Skip to content

Commit 0b80129

Browse files
stephentoubCopilot
andcommitted
Align Python generator formats
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 9ec4e23 commit 0b80129

File tree

4 files changed

+216
-12
lines changed

4 files changed

+216
-12
lines changed

nodejs/test/python-codegen.test.ts

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import type { JSONSchema7 } from "json-schema";
2+
import { describe, expect, it } from "vitest";
3+
4+
import { generatePythonSessionEventsCode } from "../../scripts/codegen/python.ts";
5+
6+
describe("python session event codegen", () => {
7+
it("maps special schema formats to the expected Python types", () => {
8+
const schema: JSONSchema7 = {
9+
definitions: {
10+
SessionEvent: {
11+
anyOf: [
12+
{
13+
type: "object",
14+
required: ["type", "data"],
15+
properties: {
16+
type: { const: "session.synthetic" },
17+
data: {
18+
type: "object",
19+
required: [
20+
"at",
21+
"identifier",
22+
"duration",
23+
"integerDuration",
24+
"uri",
25+
"pattern",
26+
"payload",
27+
"encoded",
28+
"count",
29+
],
30+
properties: {
31+
at: { type: "string", format: "date-time" },
32+
identifier: { type: "string", format: "uuid" },
33+
duration: { type: "number", format: "duration" },
34+
integerDuration: { type: "integer", format: "duration" },
35+
optionalDuration: {
36+
type: ["number", "null"],
37+
format: "duration",
38+
},
39+
action: {
40+
type: "string",
41+
enum: ["store", "vote"],
42+
default: "store",
43+
},
44+
summary: { type: "string", default: "" },
45+
uri: { type: "string", format: "uri" },
46+
pattern: { type: "string", format: "regex" },
47+
payload: { type: "string", format: "byte" },
48+
encoded: { type: "string", contentEncoding: "base64" },
49+
count: { type: "integer" },
50+
},
51+
},
52+
},
53+
},
54+
],
55+
},
56+
},
57+
};
58+
59+
const code = generatePythonSessionEventsCode(schema);
60+
61+
expect(code).toContain("from datetime import datetime, timedelta");
62+
expect(code).toContain("at: datetime");
63+
expect(code).toContain("identifier: UUID");
64+
expect(code).toContain("duration: timedelta");
65+
expect(code).toContain("integer_duration: timedelta");
66+
expect(code).toContain("optional_duration: timedelta | None = None");
67+
expect(code).toContain('duration = from_timedelta(obj.get("duration"))');
68+
expect(code).toContain('result["duration"] = to_timedelta(self.duration)');
69+
expect(code).toContain('result["integerDuration"] = to_timedelta_int(self.integer_duration)');
70+
expect(code).toContain("def to_timedelta_int(x: timedelta) -> int:");
71+
expect(code).toContain('action = from_union([from_none, lambda x: parse_enum(SessionSyntheticDataAction, x)], obj.get("action", "store"))');
72+
expect(code).toContain('summary = from_union([from_none, lambda x: from_str(x)], obj.get("summary", ""))');
73+
expect(code).toContain("uri: str");
74+
expect(code).toContain("pattern: str");
75+
expect(code).toContain("payload: str");
76+
expect(code).toContain("encoded: str");
77+
expect(code).toContain("count: int");
78+
});
79+
});

python/copilot/generated/session_events.py

Lines changed: 28 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

python/test_event_forward_compatibility.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@
1818
ContentElement,
1919
Data,
2020
Mode,
21+
PermissionRequestedDataPermissionRequest,
22+
PermissionRequestedDataPermissionRequestAction,
2123
ReferenceType,
2224
RequestedSchema,
2325
RequestedSchemaType,
2426
Resource,
2527
Result,
2628
ResultKind,
29+
SessionTaskCompleteData,
2730
SessionEventType,
2831
session_event_from_dict,
2932
)
@@ -130,3 +133,11 @@ def test_data_shim_preserves_raw_mapping_values(self):
130133

131134
constructed = Data(arguments={"tool_call_id": "call-1"})
132135
assert constructed.to_dict() == {"arguments": {"tool_call_id": "call-1"}}
136+
137+
def test_schema_defaults_are_applied_for_missing_optional_fields(self):
138+
"""Generated event models should honor primitive schema defaults during parsing."""
139+
request = PermissionRequestedDataPermissionRequest.from_dict({"kind": "memory", "fact": "remember this"})
140+
assert request.action == PermissionRequestedDataPermissionRequestAction.STORE
141+
142+
task_complete = SessionTaskCompleteData.from_dict({"success": True})
143+
assert task_complete.summary == ""

0 commit comments

Comments
 (0)