Skip to content

Commit 0ea0bc7

Browse files
Phase C: streaming/MCP/shape cleanups + disable quicktype combineClasses
Mirrors PR #1357 Phase C (TypeScript SDK API review). Changes: * `SessionConfig.streaming` and `ResumeSessionConfig.streaming` now document `Defaults to False` (matches TS PR #1357 4.2). * `ToolBinaryResult.type` tightened from `str` to `Literal["image", "resource"]` with `"image"` default (matches TS PR #1357 2.6). * `scripts/codegen/python.ts` now sets `inferenceFlags: { combineClasses: false }` when invoking quicktype. Previously quicktype's default structural-equality merging produced fuzzy synthesized names (e.g. `PermissionDecisionApproveForIonApproval` for the merge of `PermissionDecisionApproveFor{Session,Location}Approval`), which are unstable: any future divergence between the schema variants would silently change the generated class name. We rely on the schema's named definitions and resolve structural unions explicitly via `postProcessRefBasedDiscriminatedUnionsForPython`, so the merging is also redundant. Removed the `Session→Ion` / `Location→Ion` acronym hack we needed when the merging was on. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 9885b92 commit 0ea0bc7

4 files changed

Lines changed: 130 additions & 53 deletions

File tree

python/copilot/generated/rpc.py

Lines changed: 117 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

python/copilot/session.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -980,9 +980,10 @@ class SessionConfig(TypedDict, total=False):
980980
# session telemetry is always disabled regardless of this setting.
981981
# This is independent of the client OpenTelemetry configuration.
982982
enable_session_telemetry: bool
983-
# Enable streaming of assistant message and reasoning chunks
983+
# Enable streaming of assistant message and reasoning chunks.
984984
# When True, assistant.message_delta and assistant.reasoning_delta events
985-
# with delta_content are sent as the response is generated
985+
# with delta_content are sent as the response is generated.
986+
# Defaults to False.
986987
streaming: bool
987988
# Include sub-agent streaming events in the event stream. When True, streaming
988989
# delta events from sub-agents (e.g., assistant.message_delta,
@@ -1071,7 +1072,7 @@ class ResumeSessionConfig(TypedDict, total=False):
10711072
working_directory: str
10721073
# Override the default configuration directory location.
10731074
config_dir: str
1074-
# Enable streaming of assistant message chunks
1075+
# Enable streaming of assistant message chunks. Defaults to False.
10751076
streaming: bool
10761077
# Include sub-agent streaming events in the event stream. When True, streaming
10771078
# delta events from sub-agents (e.g., assistant.message_delta,

python/copilot/tools.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class ToolBinaryResult:
2424

2525
data: str = ""
2626
mime_type: str = ""
27-
type: str = ""
27+
type: Literal["image", "resource"] = "image"
2828
description: str = ""
2929

3030

scripts/codegen/python.ts

Lines changed: 8 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -359,14 +359,6 @@ function postProcessRefBasedDiscriminatedUnionsForPython(
359359
[/Id\b/g, "ID"],
360360
[/Llm/g, "LLM"],
361361
[/Cli/g, "CLI"],
362-
// quicktype merges structurally-identical unions and synthesizes a
363-
// single class name using a common substring. For our schema this
364-
// surfaces as e.g. `PermissionDecisionApproveForIonApproval` (merge
365-
// of `PermissionDecisionApproveFor{Session,Location}Approval` —
366-
// common substring is `Ion`). Try that substitution so we find
367-
// and delete the merged blob during union post-processing.
368-
[/Session/g, "Ion"],
369-
[/Location/g, "Ion"],
370362
];
371363
const results = new Set<string>([name]);
372364
for (const [pattern, replacement] of substitutions) {
@@ -459,47 +451,6 @@ function postProcessRefBasedDiscriminatedUnionsForPython(
459451
}
460452

461453
code = applyUnionRewritesToPython(code, resolved);
462-
463-
// Clean up quicktype-merged blobs that get left behind when quicktype merges
464-
// multiple structurally-identical types into one with a synthesized fuzzy
465-
// name (e.g. ``PermissionDecisionApproveForIonApproval`` for the merge of
466-
// ``PermissionDecisionApproveFor{Session,Location}Approval``). These
467-
// blobs are unused after we emit the proper per-variant + union shape.
468-
const orphanFuzzyMergedNames = ["PermissionDecisionApproveForIonApproval"];
469-
for (const orphanName of orphanFuzzyMergedNames) {
470-
const lines = code.split("\n");
471-
let classStart = -1;
472-
for (let i = 0; i < lines.length; i++) {
473-
if (lines[i] === `class ${orphanName}:` || lines[i].startsWith(`class ${orphanName}(`)) {
474-
classStart = i;
475-
break;
476-
}
477-
}
478-
if (classStart < 0) continue;
479-
let blockStart = classStart;
480-
while (
481-
blockStart > 0 &&
482-
(lines[blockStart - 1] === "@dataclass" || /^# /.test(lines[blockStart - 1]))
483-
) {
484-
blockStart--;
485-
}
486-
let blockEnd = classStart + 1;
487-
while (blockEnd < lines.length) {
488-
const ln = lines[blockEnd];
489-
if (
490-
/^class \w/.test(ln) ||
491-
/^def \w/.test(ln) ||
492-
ln === "@dataclass" ||
493-
/^# (?:Experimental|Deprecated|Internal):/.test(ln)
494-
) {
495-
break;
496-
}
497-
blockEnd++;
498-
}
499-
lines.splice(blockStart, blockEnd - blockStart);
500-
code = lines.join("\n");
501-
}
502-
503454
return { code, unions: resolved };
504455
}
505456

@@ -2789,6 +2740,14 @@ async function generateRpc(schemaPath?: string, sessionEventsSchema?: JSONSchema
27892740
inputData,
27902741
lang: "python",
27912742
rendererOptions: { "python-version": "3.7" },
2743+
// Disable quicktype's structural-equality merging of class types.
2744+
// It produces fuzzy synthesized names (e.g. ``PermissionDecisionApproveForIonApproval``
2745+
// as the merge of ``PermissionDecisionApproveFor{Session,Location}Approval``) which
2746+
// are unstable: any future divergence between the variants would silently change
2747+
// the generated class name. We rely on the schema's named definitions and resolve
2748+
// structural unions via :func:`postProcessRefBasedDiscriminatedUnionsForPython`,
2749+
// so the merging is also redundant.
2750+
inferenceFlags: { combineClasses: false },
27922751
});
27932752

27942753
let typesCode = qtResult.lines.join("\n");

0 commit comments

Comments
 (0)