@code-yeongyu/senpi 2026.8.4 → 2026.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/dist/core/agent-session.d.ts +0 -1
  3. package/dist/core/agent-session.d.ts.map +1 -1
  4. package/dist/core/agent-session.js +31 -35
  5. package/dist/core/agent-session.js.map +1 -1
  6. package/dist/core/extensions/builtin/claude-sdk-oauth/prompt-directive-dedupe.d.ts +26 -0
  7. package/dist/core/extensions/builtin/claude-sdk-oauth/prompt-directive-dedupe.d.ts.map +1 -0
  8. package/dist/core/extensions/builtin/claude-sdk-oauth/prompt-directive-dedupe.js +98 -0
  9. package/dist/core/extensions/builtin/claude-sdk-oauth/prompt-directive-dedupe.js.map +1 -0
  10. package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.d.ts +4 -0
  11. package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.d.ts.map +1 -1
  12. package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.js +2 -0
  13. package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.js.map +1 -1
  14. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.d.ts.map +1 -1
  15. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js +11 -2
  16. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js.map +1 -1
  17. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.d.ts.map +1 -1
  18. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.js +3 -1
  19. package/dist/core/extensions/builtin/claude-sdk-oauth/stream.js.map +1 -1
  20. package/dist/core/extensions/builtin/mcp/expose/schema-compat.js +2 -0
  21. package/dist/core/extensions/builtin/mcp/expose/schema-compat.js.map +1 -1
  22. package/dist/core/extensions/builtin/mcp/service.d.ts +4 -0
  23. package/dist/core/extensions/builtin/mcp/service.d.ts.map +1 -1
  24. package/dist/core/extensions/builtin/mcp/service.js +11 -0
  25. package/dist/core/extensions/builtin/mcp/service.js.map +1 -1
  26. package/dist/core/extensions/builtin/rules/index.d.ts.map +1 -1
  27. package/dist/core/extensions/builtin/rules/index.js +3 -2
  28. package/dist/core/extensions/builtin/rules/index.js.map +1 -1
  29. package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts +1 -1
  30. package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts.map +1 -1
  31. package/dist/core/extensions/builtin/terminal/monitor-notify.js +14 -6
  32. package/dist/core/extensions/builtin/terminal/monitor-notify.js.map +1 -1
  33. package/dist/core/provider-timeout-retry.d.ts +21 -0
  34. package/dist/core/provider-timeout-retry.d.ts.map +1 -0
  35. package/dist/core/provider-timeout-retry.js +41 -0
  36. package/dist/core/provider-timeout-retry.js.map +1 -0
  37. package/dist/modes/interactive/components/continuity-notice.d.ts.map +1 -1
  38. package/dist/modes/interactive/components/continuity-notice.js +29 -2
  39. package/dist/modes/interactive/components/continuity-notice.js.map +1 -1
  40. package/docs/providers.md +10 -0
  41. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +24 -0
  42. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  43. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  44. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  45. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +4 -1
  46. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  47. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +1 -1
  48. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
  49. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  50. package/node_modules/@earendil-works/pi-ai/dist/providers/data/groq.json +1 -1
  51. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  52. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  53. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
  54. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +15 -2
  55. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
  56. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-schema-compat.d.ts +8 -0
  57. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-schema-compat.d.ts.map +1 -1
  58. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-schema-compat.js +71 -17
  59. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-schema-compat.js.map +1 -1
  60. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  61. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  62. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  63. package/package.json +6 -6
@@ -0,0 +1,26 @@
1
+ import type { ContentBlockParam } from "@anthropic-ai/sdk/resources/messages.js";
2
+ export interface DedupeResult {
3
+ blocks: ContentBlockParam[];
4
+ collapsedDirectives: number;
5
+ }
6
+ /**
7
+ * Total UTF-8 byte size of the serialized prompt's text blocks. Uses
8
+ * `Buffer.byteLength` rather than `String.length`, which counts UTF-16 code
9
+ * units and understates every multibyte payload (Korean, emoji, CJK) that the
10
+ * lane actually pays for on the wire.
11
+ */
12
+ export declare function serializedPayloadBytes(blocks: readonly ContentBlockParam[]): number;
13
+ /**
14
+ * Collapse repeated `<ultrawork-mode>...</ultrawork-mode>` directive spans in a
15
+ * serialized prompt to the single most recent copy; earlier spans become a
16
+ * one-line placeholder. Without this, every flatten/bootstrap re-send bills
17
+ * ~17KB per duplicate (issue #494's 875KB prompt was 73% such duplicates).
18
+ *
19
+ * Invariants (load-bearing): spans match WITHIN a single text block — a lone
20
+ * open tag in one block and a close tag in another never form a span; the LAST
21
+ * span in serialization order is kept; the input array is never mutated, so
22
+ * continuity hashes (derived from `context.messages` in `session-sync.ts`, not
23
+ * from this serialized output) are unaffected.
24
+ */
25
+ export declare function dedupeUltraworkBlocks(blocks: readonly ContentBlockParam[]): DedupeResult;
26
+ //# sourceMappingURL=prompt-directive-dedupe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-directive-dedupe.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/prompt-directive-dedupe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAuDjF,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,GAAG,MAAM,CAMnF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,GAAG,YAAY,CAyBxF"}
@@ -0,0 +1,98 @@
1
+ const ULTRAWORK_MODE_OPEN_TAG = "<ultrawork-mode>";
2
+ const ULTRAWORK_MODE_CLOSE_TAG = "</ultrawork-mode>";
3
+ const SUPERSEDED_PLACEHOLDER = "[ultrawork directive superseded; the latest ultrawork directive block below applies]";
4
+ function escapeRegExp(value) {
5
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
6
+ }
7
+ const ULTRAWORK_SPAN_PATTERN = new RegExp(`${escapeRegExp(ULTRAWORK_MODE_OPEN_TAG)}[\\s\\S]*?${escapeRegExp(ULTRAWORK_MODE_CLOSE_TAG)}`, "g");
8
+ /** Every opening and closing tag, in order, for depth tracking across blocks. */
9
+ const ULTRAWORK_TAG_PATTERN = new RegExp(`${escapeRegExp(ULTRAWORK_MODE_OPEN_TAG)}|${escapeRegExp(ULTRAWORK_MODE_CLOSE_TAG)}`, "g");
10
+ function countSpans(text) {
11
+ return (text.match(ULTRAWORK_SPAN_PATTERN) ?? []).length;
12
+ }
13
+ /**
14
+ * True when the serialized blocks contain a nested directive, tracking tag depth
15
+ * across the WHOLE block sequence rather than per block. `buildPromptBlocks`
16
+ * splits turns and content chunks into separate blocks, so a nested directive
17
+ * can straddle them (`<ultrawork-mode>outer ` | `<ultrawork-mode>inner</...>` |
18
+ * ` tail</...>`); a per-block scan misses that and the non-greedy span regex then
19
+ * pairs the outer open with the inner close, stranding tags and silently eating
20
+ * an earlier directive. Nesting is pathological rather than expected, so callers
21
+ * fail closed on it instead of emitting a corrupted prompt.
22
+ *
23
+ * Unmatched lone tags are NOT nesting: a close with no open is ignored, and a
24
+ * trailing unclosed open leaves depth high without ever exceeding one. Both are
25
+ * left byte-identical by contract.
26
+ */
27
+ function hasNestedDirective(blocks) {
28
+ let depth = 0;
29
+ for (const block of blocks) {
30
+ if (block.type !== "text")
31
+ continue;
32
+ for (const token of block.text.matchAll(ULTRAWORK_TAG_PATTERN)) {
33
+ if (token[0] === ULTRAWORK_MODE_OPEN_TAG) {
34
+ depth += 1;
35
+ if (depth > 1)
36
+ return true;
37
+ }
38
+ else if (depth > 0) {
39
+ depth -= 1;
40
+ }
41
+ }
42
+ }
43
+ return false;
44
+ }
45
+ /**
46
+ * Total UTF-8 byte size of the serialized prompt's text blocks. Uses
47
+ * `Buffer.byteLength` rather than `String.length`, which counts UTF-16 code
48
+ * units and understates every multibyte payload (Korean, emoji, CJK) that the
49
+ * lane actually pays for on the wire.
50
+ */
51
+ export function serializedPayloadBytes(blocks) {
52
+ let total = 0;
53
+ for (const block of blocks) {
54
+ if (block.type === "text")
55
+ total += Buffer.byteLength(block.text, "utf8");
56
+ }
57
+ return total;
58
+ }
59
+ /**
60
+ * Collapse repeated `<ultrawork-mode>...</ultrawork-mode>` directive spans in a
61
+ * serialized prompt to the single most recent copy; earlier spans become a
62
+ * one-line placeholder. Without this, every flatten/bootstrap re-send bills
63
+ * ~17KB per duplicate (issue #494's 875KB prompt was 73% such duplicates).
64
+ *
65
+ * Invariants (load-bearing): spans match WITHIN a single text block — a lone
66
+ * open tag in one block and a close tag in another never form a span; the LAST
67
+ * span in serialization order is kept; the input array is never mutated, so
68
+ * continuity hashes (derived from `context.messages` in `session-sync.ts`, not
69
+ * from this serialized output) are unaffected.
70
+ */
71
+ export function dedupeUltraworkBlocks(blocks) {
72
+ if (hasNestedDirective(blocks))
73
+ return { blocks: [...blocks], collapsedDirectives: 0 };
74
+ let total = 0;
75
+ for (const block of blocks) {
76
+ if (block.type === "text")
77
+ total += countSpans(block.text);
78
+ }
79
+ if (total === 0)
80
+ return { blocks: [...blocks], collapsedDirectives: 0 };
81
+ let remaining = total;
82
+ const next = [];
83
+ for (const block of blocks) {
84
+ if (block.type !== "text") {
85
+ next.push(block);
86
+ continue;
87
+ }
88
+ next.push({
89
+ type: "text",
90
+ text: block.text.replace(ULTRAWORK_SPAN_PATTERN, (match) => {
91
+ remaining -= 1;
92
+ return remaining === 0 ? match : SUPERSEDED_PLACEHOLDER;
93
+ }),
94
+ });
95
+ }
96
+ return { blocks: next, collapsedDirectives: total - 1 };
97
+ }
98
+ //# sourceMappingURL=prompt-directive-dedupe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-directive-dedupe.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/prompt-directive-dedupe.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContentBlockParam } from \"@anthropic-ai/sdk/resources/messages.js\";\n\nconst ULTRAWORK_MODE_OPEN_TAG = \"<ultrawork-mode>\";\nconst ULTRAWORK_MODE_CLOSE_TAG = \"</ultrawork-mode>\";\nconst SUPERSEDED_PLACEHOLDER = \"[ultrawork directive superseded; the latest ultrawork directive block below applies]\";\n\nfunction escapeRegExp(value: string): string {\n\treturn value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nconst ULTRAWORK_SPAN_PATTERN = new RegExp(\n\t`${escapeRegExp(ULTRAWORK_MODE_OPEN_TAG)}[\\\\s\\\\S]*?${escapeRegExp(ULTRAWORK_MODE_CLOSE_TAG)}`,\n\t\"g\",\n);\n\n/** Every opening and closing tag, in order, for depth tracking across blocks. */\nconst ULTRAWORK_TAG_PATTERN = new RegExp(\n\t`${escapeRegExp(ULTRAWORK_MODE_OPEN_TAG)}|${escapeRegExp(ULTRAWORK_MODE_CLOSE_TAG)}`,\n\t\"g\",\n);\n\nfunction countSpans(text: string): number {\n\treturn (text.match(ULTRAWORK_SPAN_PATTERN) ?? []).length;\n}\n\n/**\n * True when the serialized blocks contain a nested directive, tracking tag depth\n * across the WHOLE block sequence rather than per block. `buildPromptBlocks`\n * splits turns and content chunks into separate blocks, so a nested directive\n * can straddle them (`<ultrawork-mode>outer ` | `<ultrawork-mode>inner</...>` |\n * ` tail</...>`); a per-block scan misses that and the non-greedy span regex then\n * pairs the outer open with the inner close, stranding tags and silently eating\n * an earlier directive. Nesting is pathological rather than expected, so callers\n * fail closed on it instead of emitting a corrupted prompt.\n *\n * Unmatched lone tags are NOT nesting: a close with no open is ignored, and a\n * trailing unclosed open leaves depth high without ever exceeding one. Both are\n * left byte-identical by contract.\n */\nfunction hasNestedDirective(blocks: readonly ContentBlockParam[]): boolean {\n\tlet depth = 0;\n\tfor (const block of blocks) {\n\t\tif (block.type !== \"text\") continue;\n\t\tfor (const token of block.text.matchAll(ULTRAWORK_TAG_PATTERN)) {\n\t\t\tif (token[0] === ULTRAWORK_MODE_OPEN_TAG) {\n\t\t\t\tdepth += 1;\n\t\t\t\tif (depth > 1) return true;\n\t\t\t} else if (depth > 0) {\n\t\t\t\tdepth -= 1;\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n}\n\nexport interface DedupeResult {\n\tblocks: ContentBlockParam[];\n\tcollapsedDirectives: number;\n}\n\n/**\n * Total UTF-8 byte size of the serialized prompt's text blocks. Uses\n * `Buffer.byteLength` rather than `String.length`, which counts UTF-16 code\n * units and understates every multibyte payload (Korean, emoji, CJK) that the\n * lane actually pays for on the wire.\n */\nexport function serializedPayloadBytes(blocks: readonly ContentBlockParam[]): number {\n\tlet total = 0;\n\tfor (const block of blocks) {\n\t\tif (block.type === \"text\") total += Buffer.byteLength(block.text, \"utf8\");\n\t}\n\treturn total;\n}\n\n/**\n * Collapse repeated `<ultrawork-mode>...</ultrawork-mode>` directive spans in a\n * serialized prompt to the single most recent copy; earlier spans become a\n * one-line placeholder. Without this, every flatten/bootstrap re-send bills\n * ~17KB per duplicate (issue #494's 875KB prompt was 73% such duplicates).\n *\n * Invariants (load-bearing): spans match WITHIN a single text block — a lone\n * open tag in one block and a close tag in another never form a span; the LAST\n * span in serialization order is kept; the input array is never mutated, so\n * continuity hashes (derived from `context.messages` in `session-sync.ts`, not\n * from this serialized output) are unaffected.\n */\nexport function dedupeUltraworkBlocks(blocks: readonly ContentBlockParam[]): DedupeResult {\n\tif (hasNestedDirective(blocks)) return { blocks: [...blocks], collapsedDirectives: 0 };\n\n\tlet total = 0;\n\tfor (const block of blocks) {\n\t\tif (block.type === \"text\") total += countSpans(block.text);\n\t}\n\tif (total === 0) return { blocks: [...blocks], collapsedDirectives: 0 };\n\n\tlet remaining = total;\n\tconst next: ContentBlockParam[] = [];\n\tfor (const block of blocks) {\n\t\tif (block.type !== \"text\") {\n\t\t\tnext.push(block);\n\t\t\tcontinue;\n\t\t}\n\t\tnext.push({\n\t\t\ttype: \"text\",\n\t\t\ttext: block.text.replace(ULTRAWORK_SPAN_PATTERN, (match) => {\n\t\t\t\tremaining -= 1;\n\t\t\t\treturn remaining === 0 ? match : SUPERSEDED_PLACEHOLDER;\n\t\t\t}),\n\t\t});\n\t}\n\treturn { blocks: next, collapsedDirectives: total - 1 };\n}\n"]}
@@ -14,6 +14,8 @@ export type ContinuityObservation = {
14
14
  kind: ContinuityKind;
15
15
  reason: ContinuityReason;
16
16
  deltaMessages?: number;
17
+ payloadBytes?: number;
18
+ collapsedDirectives?: number;
17
19
  };
18
20
  export type ContinuityObservabilityBoundary = {
19
21
  emit: (observation: ContinuityObservation) => void;
@@ -45,6 +47,8 @@ export declare function observeSessionSyncDecision(input: {
45
47
  deltaMessages: number;
46
48
  firstTurn: boolean;
47
49
  senpiSessionId: string;
50
+ payloadBytes?: number;
51
+ collapsedDirectives?: number;
48
52
  }): ContinuityObservation;
49
53
  export type StagedContinuityDecision = {
50
54
  observation: ContinuityObservation;
@@ -1 +1 @@
1
- {"version":3,"file":"session-observability.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/session-observability.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;AAElG,4EAA4E;AAC5E,MAAM,MAAM,gBAAgB,GACzB,gBAAgB,GAChB,eAAe,GACf,UAAU,GACV,UAAU,GACV,gBAAgB,GAChB,yBAAyB,GACzB,8BAA8B,GAC9B,iBAAiB,GACjB,eAAe,GACf,iBAAiB,GACjB,uBAAuB,GACvB,2BAA2B,GAC3B,sBAAsB,GACtB,iBAAiB,GACjB,qBAAqB,GACrB,qBAAqB,GACrB,oBAAoB,GACpB,wBAAwB,GACxB,iBAAiB,GACjB,6BAA6B,GAC7B,eAAe,GACf,oBAAoB,GACpB,cAAc,GACd,eAAe,GACf,yCAAyC,GACzC,8BAA8B,GAC9B,+BAA+B,GAC/B,iBAAiB,GACjB,cAAc,GACd,yBAAyB,GACzB,eAAe,GACf,oBAAoB,GACpB,kBAAkB,GAClB,OAAO,CAAC;AAEX,MAAM,MAAM,qBAAqB,GAAG;IACnC,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,gBAAgB,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG;IAC7C,IAAI,EAAE,CAAC,WAAW,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACnD,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;CAC5D,CAAC;AAoDF,wBAAgB,uCAAuC,CAAC,QAAQ,EAAE,OAAO,CAAC,+BAA+B,CAAC,GAAG,IAAI,CAEhH;AAED,wBAAgB,oCAAoC,IAAI,IAAI,CAE3D;AAED,qFAAqF;AACrF,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAS/D;AAED,mFAAmF;AACnF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CASnE;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAIxE;AAaD,wBAAgB,uBAAuB,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAUrF;AAED,iFAAiF;AACjF,wBAAgB,qBAAqB,CAAC,cAAc,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAE1F;AAED,wBAAgB,wBAAwB,CAAC,cAAc,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAI7F;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IACjD,IAAI,EAAE,aAAa,GAAG,QAAQ,GAAG,WAAW,CAAC;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACvB,GAAG,qBAAqB,CAuBxB;AAED,MAAM,MAAM,wBAAwB,GAAG;IACtC,WAAW,EAAE,qBAAqB,CAAC;IACnC,IAAI,EAAE,MAAM,IAAI,CAAC;CACjB,CAAC;AAEF,oFAAoF;AACpF,wBAAgB,uBAAuB,CACtC,WAAW,EAAE,qBAAqB,EAClC,UAAU,CAAC,EAAE,CAAC,WAAW,EAAE,qBAAqB,KAAK,IAAI,EACzD,UAAU,CAAC,EAAE,MAAM,IAAI,GACrB,wBAAwB,CAW1B;AAED,wBAAgB,yBAAyB,CACxC,WAAW,EAAE,qBAAqB,EAClC,UAAU,CAAC,EAAE,CAAC,WAAW,EAAE,qBAAqB,KAAK,IAAI,GACvD,IAAI,CAQN"}
1
+ {"version":3,"file":"session-observability.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/session-observability.ts"],"names":[],"mappings":"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"}
@@ -146,6 +146,8 @@ export function observeSessionSyncDecision(input) {
146
146
  kind: input.firstTurn && reason === "registry_miss" ? "bootstrap" : "flatten",
147
147
  reason,
148
148
  deltaMessages: input.deltaMessages,
149
+ ...(input.payloadBytes !== undefined ? { payloadBytes: input.payloadBytes } : {}),
150
+ ...(input.collapsedDirectives !== undefined ? { collapsedDirectives: input.collapsedDirectives } : {}),
149
151
  };
150
152
  }
151
153
  /** Stages an attempt's decision; `emit` fires only when the attempt is retained. */
@@ -1 +1 @@
1
- {"version":3,"file":"session-observability.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/session-observability.ts"],"names":[],"mappings":"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","sourcesContent":["import { getAgentDir } from \"../../../../config.ts\";\nimport { createSessionLogger, type SessionLogger } from \"../../../session-log.ts\";\n\n/**\n * Per-turn continuity observability for the claude-sdk-oauth lane.\n *\n * Emission semantics: a decision is STAGED per attempt at its final outcome\n * point and EMITTED only when the auth-lane retain/discard wrapper retains that\n * attempt (auth-attempt.ts). A discarded attempt emits nothing, so every\n * completed turn yields exactly one observation; a turn where every attempt\n * fails yields one terminal error observation instead.\n */\nexport type ContinuityKind = \"bootstrap\" | \"delta\" | \"reattach\" | \"fork\" | \"flatten\" | \"disabled\";\n\n/** Fixed vocabulary — arbitrary error text never reaches an observation. */\nexport type ContinuityReason =\n\t| \"prefix_matched\"\n\t| \"registry_miss\"\n\t| \"idle_ttl\"\n\t| \"capacity\"\n\t| \"model_selected\"\n\t| \"thinking_level_selected\"\n\t| \"bound_account_token_expiring\"\n\t| \"account_changed\"\n\t| \"model_changed\"\n\t| \"toolset_changed\"\n\t| \"system_prompt_changed\"\n\t| \"assistant_stream_diverged\"\n\t| \"sent_stream_diverged\"\n\t| \"options_changed\"\n\t| \"history_rolled_back\"\n\t| \"assistant_rewritten\"\n\t| \"transcript_missing\"\n\t| \"cross_root_unsupported\"\n\t| \"branch_diverged\"\n\t| \"branch_boundary_unavailable\"\n\t| \"branch_resume\"\n\t| \"tainted_compaction\"\n\t| \"tainted_fork\"\n\t| \"tainted_abort\"\n\t| \"tainted_assistant_provenance_unverified\"\n\t| \"resume_initialization_failed\"\n\t| \"resume_initialization_aborted\"\n\t| \"resume_mode_off\"\n\t| \"query_failed\"\n\t| \"turn_attribution_failed\"\n\t| \"abort_timeout\"\n\t| \"extensions_removed\"\n\t| \"session_shutdown\"\n\t| \"other\";\n\nexport type ContinuityObservation = {\n\tkind: ContinuityKind;\n\treason: ContinuityReason;\n\tdeltaMessages?: number;\n};\n\nexport type ContinuityObservabilityBoundary = {\n\temit: (observation: ContinuityObservation) => void;\n\tlog: (event: string, data: Record<string, unknown>) => void;\n};\n\nconst SANITIZED_REASONS = new Set<string>([\n\t\"prefix_matched\",\n\t\"registry_miss\",\n\t\"idle_ttl\",\n\t\"capacity\",\n\t\"model_selected\",\n\t\"thinking_level_selected\",\n\t\"bound_account_token_expiring\",\n\t\"account_changed\",\n\t\"model_changed\",\n\t\"toolset_changed\",\n\t\"system_prompt_changed\",\n\t\"assistant_stream_diverged\",\n\t\"options_changed\",\n\t\"history_rolled_back\",\n\t\"assistant_rewritten\",\n\t\"transcript_missing\",\n\t\"cross_root_unsupported\",\n\t\"sent_stream_diverged\",\n\t\"branch_diverged\",\n\t\"branch_boundary_unavailable\",\n\t\"branch_resume\",\n\t\"tainted_compaction\",\n\t\"tainted_fork\",\n\t\"tainted_abort\",\n\t\"tainted_assistant_provenance_unverified\",\n\t\"resume_initialization_failed\",\n\t\"resume_initialization_aborted\",\n\t\"resume_mode_off\",\n\t\"query_failed\",\n\t\"turn_attribution_failed\",\n\t\"abort_timeout\",\n\t\"extensions_removed\",\n\t\"session_shutdown\",\n\t\"other\",\n]);\n\nlet cachedLogger: SessionLogger | undefined;\n\nfunction sessionLogger(): SessionLogger {\n\tcachedLogger ??= createSessionLogger(getAgentDir());\n\treturn cachedLogger;\n}\n\nconst defaultBoundary: ContinuityObservabilityBoundary = {\n\temit: () => {},\n\tlog: (event, data) => sessionLogger().info(event, data),\n};\nlet activeBoundary = defaultBoundary;\n\nexport function overrideContinuityObservabilityBoundary(override: Partial<ContinuityObservabilityBoundary>): void {\n\tactiveBoundary = { ...defaultBoundary, ...override };\n}\n\nexport function resetContinuityObservabilityBoundary(): void {\n\tactiveBoundary = defaultBoundary;\n}\n\n/** Maps a fixed vocabulary member through, and anything else to a bucketed cause. */\nexport function sanitizeReason(value: unknown): ContinuityReason {\n\tconst text = typeof value === \"string\" ? value : value instanceof Error ? value.message : \"\";\n\tif (SANITIZED_REASONS.has(text)) return text as ContinuityReason;\n\tconst tainted = /^tainted:(.+)$/.exec(text);\n\tif (tainted) {\n\t\tconst mapped = `tainted_${tainted[1]}`;\n\t\tif (SANITIZED_REASONS.has(mapped)) return mapped as ContinuityReason;\n\t}\n\treturn sanitizeCloseCause(value);\n}\n\n/** Buckets arbitrary close/pump failures into the fixed close-cause vocabulary. */\nexport function sanitizeCloseCause(value: unknown): ContinuityReason {\n\tconst text = typeof value === \"string\" ? value : value instanceof Error ? value.message : \"\";\n\tif (SANITIZED_REASONS.has(text)) return text as ContinuityReason;\n\tif (/did not terminate|interrupt failed/i.test(text)) return \"abort_timeout\";\n\tif (/user_message_uuid did not match|result arrived before replay claim|pre-replay buffer overflow/i.test(text)) {\n\t\treturn \"turn_attribution_failed\";\n\t}\n\tif (/query ended before|Claude SDK OAuth query|Claude Code/i.test(text)) return \"query_failed\";\n\treturn \"other\";\n}\n\n/**\n * Classifies the failure that ended a turn after every auth attempt failed.\n * Anything reaching here came out of the SDK query path, so an Error is a query\n * failure unless it matches a more specific bucket; the raw text never escapes.\n */\nexport function sanitizeTerminalFailure(value: unknown): ContinuityReason {\n\tconst cause = sanitizeCloseCause(value);\n\tif (cause !== \"other\") return cause;\n\treturn value instanceof Error ? \"query_failed\" : \"other\";\n}\n\n/**\n * One-shot pending close causes keyed by senpi session id. `closeSession`\n * records the cause here; the next admission consumes it so a first-turn\n * `registry_miss` is attributed to the real cause instead.\n */\nconst pendingCloseCauses = new Map<string, ContinuityReason>();\n// Long-running processes can stage many closes: the map is FIFO-bounded so it\n// cannot grow without limit. 256 pending causes per process is far beyond any\n// realistic session count; the oldest entry is evicted first.\nconst PENDING_CLOSE_CAUSE_LIMIT = 256;\n\nexport function recordPendingCloseCause(senpiSessionId: string, reason: unknown): void {\n\tconst cause = sanitizeReason(reason);\n\t// Delete first so a re-recorded cause moves to the newest position.\n\tpendingCloseCauses.delete(senpiSessionId);\n\tif (pendingCloseCauses.size >= PENDING_CLOSE_CAUSE_LIMIT) {\n\t\tconst oldest = pendingCloseCauses.keys().next().value;\n\t\tif (oldest !== undefined) pendingCloseCauses.delete(oldest);\n\t}\n\tpendingCloseCauses.set(senpiSessionId, cause);\n\tactiveBoundary.log(\"claude_sdk_oauth_session_close\", { reason: cause });\n}\n\n/** Read the pending close cause WITHOUT consuming it (consumed at emit time). */\nexport function peekPendingCloseCause(senpiSessionId: string): ContinuityReason | undefined {\n\treturn pendingCloseCauses.get(senpiSessionId);\n}\n\nexport function consumePendingCloseCause(senpiSessionId: string): ContinuityReason | undefined {\n\tconst cause = pendingCloseCauses.get(senpiSessionId);\n\tpendingCloseCauses.delete(senpiSessionId);\n\treturn cause;\n}\n\n/**\n * Maps the continuity decision families onto the observation vocabulary:\n * incremental→delta, resume→fork, cold-seed→flatten.\n */\nexport function observeSessionSyncDecision(input: {\n\tkind: \"incremental\" | \"resume\" | \"cold-seed\";\n\treason?: string;\n\tdeltaMessages: number;\n\tfirstTurn: boolean;\n\tsenpiSessionId: string;\n}): ContinuityObservation {\n\tif (input.kind === \"incremental\") {\n\t\treturn { kind: \"delta\", reason: \"prefix_matched\", deltaMessages: input.deltaMessages };\n\t}\n\tif (input.kind === \"resume\") {\n\t\tconst retainedCause =\n\t\t\tinput.reason === \"registry_miss\" ? consumePendingCloseCause(input.senpiSessionId) : undefined;\n\t\treturn {\n\t\t\tkind: \"fork\",\n\t\t\treason: retainedCause ?? (input.reason === undefined ? \"branch_resume\" : sanitizeReason(input.reason)),\n\t\t\tdeltaMessages: input.deltaMessages,\n\t\t};\n\t}\n\t// Peek, not consume: the staged observation is emitted only when the\n\t// auth-lane RETAINS this attempt. Consuming here would lose the cause when\n\t// the attempt is discarded; the emit path consumes it (session-stream.ts).\n\tconst retained = input.reason === \"registry_miss\" ? peekPendingCloseCause(input.senpiSessionId) : undefined;\n\tconst reason = retained ?? sanitizeReason(input.reason);\n\treturn {\n\t\tkind: input.firstTurn && reason === \"registry_miss\" ? \"bootstrap\" : \"flatten\",\n\t\treason,\n\t\tdeltaMessages: input.deltaMessages,\n\t};\n}\n\nexport type StagedContinuityDecision = {\n\tobservation: ContinuityObservation;\n\temit: () => void;\n};\n\n/** Stages an attempt's decision; `emit` fires only when the attempt is retained. */\nexport function stageContinuityDecision(\n\tobservation: ContinuityObservation,\n\tonDecision?: (observation: ContinuityObservation) => void,\n\tbeforeEmit?: () => void,\n): StagedContinuityDecision {\n\tlet emitted = false;\n\treturn {\n\t\tobservation,\n\t\temit: () => {\n\t\t\tif (emitted) return;\n\t\t\temitted = true;\n\t\t\tbeforeEmit?.();\n\t\t\temitContinuityObservation(observation, onDecision);\n\t\t},\n\t};\n}\n\nexport function emitContinuityObservation(\n\tobservation: ContinuityObservation,\n\tonDecision?: (observation: ContinuityObservation) => void,\n): void {\n\tonDecision?.(observation);\n\tactiveBoundary.emit(observation);\n\tactiveBoundary.log(\"claude_sdk_oauth_session_continuity\", {\n\t\tkind: observation.kind,\n\t\treason: observation.reason,\n\t\t...(observation.deltaMessages === undefined ? {} : { count: observation.deltaMessages }),\n\t});\n}\n"]}
1
+ {"version":3,"file":"session-observability.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/session-observability.ts"],"names":[],"mappings":"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","sourcesContent":["import { getAgentDir } from \"../../../../config.ts\";\nimport { createSessionLogger, type SessionLogger } from \"../../../session-log.ts\";\n\n/**\n * Per-turn continuity observability for the claude-sdk-oauth lane.\n *\n * Emission semantics: a decision is STAGED per attempt at its final outcome\n * point and EMITTED only when the auth-lane retain/discard wrapper retains that\n * attempt (auth-attempt.ts). A discarded attempt emits nothing, so every\n * completed turn yields exactly one observation; a turn where every attempt\n * fails yields one terminal error observation instead.\n */\nexport type ContinuityKind = \"bootstrap\" | \"delta\" | \"reattach\" | \"fork\" | \"flatten\" | \"disabled\";\n\n/** Fixed vocabulary — arbitrary error text never reaches an observation. */\nexport type ContinuityReason =\n\t| \"prefix_matched\"\n\t| \"registry_miss\"\n\t| \"idle_ttl\"\n\t| \"capacity\"\n\t| \"model_selected\"\n\t| \"thinking_level_selected\"\n\t| \"bound_account_token_expiring\"\n\t| \"account_changed\"\n\t| \"model_changed\"\n\t| \"toolset_changed\"\n\t| \"system_prompt_changed\"\n\t| \"assistant_stream_diverged\"\n\t| \"sent_stream_diverged\"\n\t| \"options_changed\"\n\t| \"history_rolled_back\"\n\t| \"assistant_rewritten\"\n\t| \"transcript_missing\"\n\t| \"cross_root_unsupported\"\n\t| \"branch_diverged\"\n\t| \"branch_boundary_unavailable\"\n\t| \"branch_resume\"\n\t| \"tainted_compaction\"\n\t| \"tainted_fork\"\n\t| \"tainted_abort\"\n\t| \"tainted_assistant_provenance_unverified\"\n\t| \"resume_initialization_failed\"\n\t| \"resume_initialization_aborted\"\n\t| \"resume_mode_off\"\n\t| \"query_failed\"\n\t| \"turn_attribution_failed\"\n\t| \"abort_timeout\"\n\t| \"extensions_removed\"\n\t| \"session_shutdown\"\n\t| \"other\";\n\nexport type ContinuityObservation = {\n\tkind: ContinuityKind;\n\treason: ContinuityReason;\n\tdeltaMessages?: number;\n\tpayloadBytes?: number;\n\tcollapsedDirectives?: number;\n};\n\nexport type ContinuityObservabilityBoundary = {\n\temit: (observation: ContinuityObservation) => void;\n\tlog: (event: string, data: Record<string, unknown>) => void;\n};\n\nconst SANITIZED_REASONS = new Set<string>([\n\t\"prefix_matched\",\n\t\"registry_miss\",\n\t\"idle_ttl\",\n\t\"capacity\",\n\t\"model_selected\",\n\t\"thinking_level_selected\",\n\t\"bound_account_token_expiring\",\n\t\"account_changed\",\n\t\"model_changed\",\n\t\"toolset_changed\",\n\t\"system_prompt_changed\",\n\t\"assistant_stream_diverged\",\n\t\"options_changed\",\n\t\"history_rolled_back\",\n\t\"assistant_rewritten\",\n\t\"transcript_missing\",\n\t\"cross_root_unsupported\",\n\t\"sent_stream_diverged\",\n\t\"branch_diverged\",\n\t\"branch_boundary_unavailable\",\n\t\"branch_resume\",\n\t\"tainted_compaction\",\n\t\"tainted_fork\",\n\t\"tainted_abort\",\n\t\"tainted_assistant_provenance_unverified\",\n\t\"resume_initialization_failed\",\n\t\"resume_initialization_aborted\",\n\t\"resume_mode_off\",\n\t\"query_failed\",\n\t\"turn_attribution_failed\",\n\t\"abort_timeout\",\n\t\"extensions_removed\",\n\t\"session_shutdown\",\n\t\"other\",\n]);\n\nlet cachedLogger: SessionLogger | undefined;\n\nfunction sessionLogger(): SessionLogger {\n\tcachedLogger ??= createSessionLogger(getAgentDir());\n\treturn cachedLogger;\n}\n\nconst defaultBoundary: ContinuityObservabilityBoundary = {\n\temit: () => {},\n\tlog: (event, data) => sessionLogger().info(event, data),\n};\nlet activeBoundary = defaultBoundary;\n\nexport function overrideContinuityObservabilityBoundary(override: Partial<ContinuityObservabilityBoundary>): void {\n\tactiveBoundary = { ...defaultBoundary, ...override };\n}\n\nexport function resetContinuityObservabilityBoundary(): void {\n\tactiveBoundary = defaultBoundary;\n}\n\n/** Maps a fixed vocabulary member through, and anything else to a bucketed cause. */\nexport function sanitizeReason(value: unknown): ContinuityReason {\n\tconst text = typeof value === \"string\" ? value : value instanceof Error ? value.message : \"\";\n\tif (SANITIZED_REASONS.has(text)) return text as ContinuityReason;\n\tconst tainted = /^tainted:(.+)$/.exec(text);\n\tif (tainted) {\n\t\tconst mapped = `tainted_${tainted[1]}`;\n\t\tif (SANITIZED_REASONS.has(mapped)) return mapped as ContinuityReason;\n\t}\n\treturn sanitizeCloseCause(value);\n}\n\n/** Buckets arbitrary close/pump failures into the fixed close-cause vocabulary. */\nexport function sanitizeCloseCause(value: unknown): ContinuityReason {\n\tconst text = typeof value === \"string\" ? value : value instanceof Error ? value.message : \"\";\n\tif (SANITIZED_REASONS.has(text)) return text as ContinuityReason;\n\tif (/did not terminate|interrupt failed/i.test(text)) return \"abort_timeout\";\n\tif (/user_message_uuid did not match|result arrived before replay claim|pre-replay buffer overflow/i.test(text)) {\n\t\treturn \"turn_attribution_failed\";\n\t}\n\tif (/query ended before|Claude SDK OAuth query|Claude Code/i.test(text)) return \"query_failed\";\n\treturn \"other\";\n}\n\n/**\n * Classifies the failure that ended a turn after every auth attempt failed.\n * Anything reaching here came out of the SDK query path, so an Error is a query\n * failure unless it matches a more specific bucket; the raw text never escapes.\n */\nexport function sanitizeTerminalFailure(value: unknown): ContinuityReason {\n\tconst cause = sanitizeCloseCause(value);\n\tif (cause !== \"other\") return cause;\n\treturn value instanceof Error ? \"query_failed\" : \"other\";\n}\n\n/**\n * One-shot pending close causes keyed by senpi session id. `closeSession`\n * records the cause here; the next admission consumes it so a first-turn\n * `registry_miss` is attributed to the real cause instead.\n */\nconst pendingCloseCauses = new Map<string, ContinuityReason>();\n// Long-running processes can stage many closes: the map is FIFO-bounded so it\n// cannot grow without limit. 256 pending causes per process is far beyond any\n// realistic session count; the oldest entry is evicted first.\nconst PENDING_CLOSE_CAUSE_LIMIT = 256;\n\nexport function recordPendingCloseCause(senpiSessionId: string, reason: unknown): void {\n\tconst cause = sanitizeReason(reason);\n\t// Delete first so a re-recorded cause moves to the newest position.\n\tpendingCloseCauses.delete(senpiSessionId);\n\tif (pendingCloseCauses.size >= PENDING_CLOSE_CAUSE_LIMIT) {\n\t\tconst oldest = pendingCloseCauses.keys().next().value;\n\t\tif (oldest !== undefined) pendingCloseCauses.delete(oldest);\n\t}\n\tpendingCloseCauses.set(senpiSessionId, cause);\n\tactiveBoundary.log(\"claude_sdk_oauth_session_close\", { reason: cause });\n}\n\n/** Read the pending close cause WITHOUT consuming it (consumed at emit time). */\nexport function peekPendingCloseCause(senpiSessionId: string): ContinuityReason | undefined {\n\treturn pendingCloseCauses.get(senpiSessionId);\n}\n\nexport function consumePendingCloseCause(senpiSessionId: string): ContinuityReason | undefined {\n\tconst cause = pendingCloseCauses.get(senpiSessionId);\n\tpendingCloseCauses.delete(senpiSessionId);\n\treturn cause;\n}\n\n/**\n * Maps the continuity decision families onto the observation vocabulary:\n * incremental→delta, resume→fork, cold-seed→flatten.\n */\nexport function observeSessionSyncDecision(input: {\n\tkind: \"incremental\" | \"resume\" | \"cold-seed\";\n\treason?: string;\n\tdeltaMessages: number;\n\tfirstTurn: boolean;\n\tsenpiSessionId: string;\n\tpayloadBytes?: number;\n\tcollapsedDirectives?: number;\n}): ContinuityObservation {\n\tif (input.kind === \"incremental\") {\n\t\treturn { kind: \"delta\", reason: \"prefix_matched\", deltaMessages: input.deltaMessages };\n\t}\n\tif (input.kind === \"resume\") {\n\t\tconst retainedCause =\n\t\t\tinput.reason === \"registry_miss\" ? consumePendingCloseCause(input.senpiSessionId) : undefined;\n\t\treturn {\n\t\t\tkind: \"fork\",\n\t\t\treason: retainedCause ?? (input.reason === undefined ? \"branch_resume\" : sanitizeReason(input.reason)),\n\t\t\tdeltaMessages: input.deltaMessages,\n\t\t};\n\t}\n\t// Peek, not consume: the staged observation is emitted only when the\n\t// auth-lane RETAINS this attempt. Consuming here would lose the cause when\n\t// the attempt is discarded; the emit path consumes it (session-stream.ts).\n\tconst retained = input.reason === \"registry_miss\" ? peekPendingCloseCause(input.senpiSessionId) : undefined;\n\tconst reason = retained ?? sanitizeReason(input.reason);\n\treturn {\n\t\tkind: input.firstTurn && reason === \"registry_miss\" ? \"bootstrap\" : \"flatten\",\n\t\treason,\n\t\tdeltaMessages: input.deltaMessages,\n\t\t...(input.payloadBytes !== undefined ? { payloadBytes: input.payloadBytes } : {}),\n\t\t...(input.collapsedDirectives !== undefined ? { collapsedDirectives: input.collapsedDirectives } : {}),\n\t};\n}\n\nexport type StagedContinuityDecision = {\n\tobservation: ContinuityObservation;\n\temit: () => void;\n};\n\n/** Stages an attempt's decision; `emit` fires only when the attempt is retained. */\nexport function stageContinuityDecision(\n\tobservation: ContinuityObservation,\n\tonDecision?: (observation: ContinuityObservation) => void,\n\tbeforeEmit?: () => void,\n): StagedContinuityDecision {\n\tlet emitted = false;\n\treturn {\n\t\tobservation,\n\t\temit: () => {\n\t\t\tif (emitted) return;\n\t\t\temitted = true;\n\t\t\tbeforeEmit?.();\n\t\t\temitContinuityObservation(observation, onDecision);\n\t\t},\n\t};\n}\n\nexport function emitContinuityObservation(\n\tobservation: ContinuityObservation,\n\tonDecision?: (observation: ContinuityObservation) => void,\n): void {\n\tonDecision?.(observation);\n\tactiveBoundary.emit(observation);\n\tactiveBoundary.log(\"claude_sdk_oauth_session_continuity\", {\n\t\tkind: observation.kind,\n\t\treason: observation.reason,\n\t\t...(observation.deltaMessages === undefined ? {} : { count: observation.deltaMessages }),\n\t});\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"session-stream.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/session-stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAAkC,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGnF,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,mBAAmB,CAAC;AAGpE,OAAO,EACN,KAAK,qBAAqB,EAM1B,MAAM,4BAA4B,CAAC;AAoBpC,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,eAAe,CAAC;AAEpE,MAAM,MAAM,0BAA0B,GAAG;IACxC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,mBAAmB,CAAC;IACnC,gBAAgB,EAAE,8BAA8B,CAAC;IACjD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;IACtE,mBAAmB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C,oBAAoB,CAAC,EAAE,CAAC,WAAW,EAAE,qBAAqB,KAAK,IAAI,CAAC;CACpE,CAAC;AAmLF,wBAAuB,uBAAuB,CAAC,KAAK,EAAE,0BAA0B,GAAG,cAAc,CAAC,UAAU,CAAC,CAW5G"}
1
+ {"version":3,"file":"session-stream.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/session-stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAAkC,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAInF,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,mBAAmB,CAAC;AAGpE,OAAO,EACN,KAAK,qBAAqB,EAM1B,MAAM,4BAA4B,CAAC;AAoBpC,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,eAAe,CAAC;AAEpE,MAAM,MAAM,0BAA0B,GAAG;IACxC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,mBAAmB,CAAC;IACnC,gBAAgB,EAAE,8BAA8B,CAAC;IACjD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;IACtE,mBAAmB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C,oBAAoB,CAAC,EAAE,CAAC,WAAW,EAAE,qBAAqB,KAAK,IAAI,CAAC;CACpE,CAAC;AA2LF,wBAAuB,uBAAuB,CAAC,KAAK,EAAE,0BAA0B,GAAG,cAAc,CAAC,UAAU,CAAC,CAW5G"}
@@ -1,6 +1,7 @@
1
1
  import { queryWithAuthLane } from "./auth-lane.js";
2
2
  import { BoundedAsyncQueue, SESSION_STREAM_QUEUE_CAPACITY } from "./bounded-queue.js";
3
3
  import { buildPromptBlocks } from "./prompt-bridge.js";
4
+ import { dedupeUltraworkBlocks, serializedPayloadBytes } from "./prompt-directive-dedupe.js";
4
5
  import { getSdkBoundary } from "./sdk-boundary.js";
5
6
  import { decideNativeContinuity } from "./session-continuity.js";
6
7
  import { consumePendingCloseCause, emitContinuityObservation, observeSessionSyncDecision, sanitizeTerminalFailure, stageContinuityDecision, } from "./session-observability.js";
@@ -152,15 +153,23 @@ async function createResidentAttempt(input, auth) {
152
153
  options: auth.options,
153
154
  });
154
155
  }
155
- const blocks = flatten
156
- ? buildPromptBlocks(input.context, input.customToolNameToSdk, input.toolWatchNote)
156
+ const flattenResult = flatten
157
+ ? dedupeUltraworkBlocks(buildPromptBlocks(input.context, input.customToolNameToSdk, input.toolWatchNote))
158
+ : undefined;
159
+ const blocks = flattenResult
160
+ ? flattenResult.blocks
157
161
  : buildDeltaPromptBlocks(messages.slice(from), input.customToolNameToSdk);
162
+ const payloadBytes = flattenResult ? serializedPayloadBytes(flattenResult.blocks) : undefined;
158
163
  const staged = stageContinuityDecision(observeSessionSyncDecision({
159
164
  kind: observedKind,
160
165
  reason: observedReason,
161
166
  deltaMessages: flatten ? hashes.length : hashes.length - from,
162
167
  firstTurn,
163
168
  senpiSessionId: sessionId,
169
+ ...(payloadBytes !== undefined ? { payloadBytes } : {}),
170
+ ...(flattenResult?.collapsedDirectives !== undefined
171
+ ? { collapsedDirectives: flattenResult.collapsedDirectives }
172
+ : {}),
164
173
  }), input.onContinuityDecision,
165
174
  // The pending close cause is consumed only when the staged observation
166
175
  // actually emits (attempt retained) — a discarded attempt leaves the
@@ -1 +1 @@
1
- {"version":3,"file":"session-stream.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/session-stream.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Api, Context, Model, SimpleStreamOptions } from \"@earendil-works/pi-ai\";\nimport { type AuthenticatedAttemptInput, queryWithAuthLane } from \"./auth-lane.ts\";\nimport { BoundedAsyncQueue, SESSION_STREAM_QUEUE_CAPACITY } from \"./bounded-queue.ts\";\nimport { buildPromptBlocks } from \"./prompt-bridge.ts\";\nimport type { SDKMessage, SDKUserMessage } from \"./sdk-boundary.ts\";\nimport { getSdkBoundary } from \"./sdk-boundary.ts\";\nimport { type ContinuityDecision, decideNativeContinuity } from \"./session-continuity.ts\";\nimport {\n\ttype ContinuityObservation,\n\tconsumePendingCloseCause,\n\temitContinuityObservation,\n\tobserveSessionSyncDecision,\n\tsanitizeTerminalFailure,\n\tstageContinuityDecision,\n} from \"./session-observability.ts\";\nimport { bindingFromEntry, getBinding, reattachSession, rememberBinding } from \"./session-reattach.ts\";\nimport {\n\ttype ClaudeSdkOauthSessionEntry,\n\tcloseSession,\n\tgetOrCreateSession,\n\tgetSession,\n\tisCurrentGeneration,\n\tisIdleExpired,\n\tsessionRegistry,\n} from \"./session-registry.ts\";\nimport { submitSessionTurn } from \"./session-registry-pump.ts\";\nimport {\n\tbuildDeltaPromptBlocks,\n\tconfigFingerprint,\n\trecordSyncedStream,\n\tsentHashesForEntry,\n\tsentMessageHashes,\n\tsentMessages,\n} from \"./session-sync.ts\";\nimport type { ClaudeSdkOauthProviderSettings } from \"./settings.ts\";\n\nexport type ResidentSessionStreamInput = {\n\tmodel: Model<Api>;\n\tcontext: Context;\n\tstreamOptions: SimpleStreamOptions;\n\tproviderSettings: ClaudeSdkOauthProviderSettings;\n\tpinnedAccount?: string;\n\tbuildOptions: Parameters<typeof queryWithAuthLane>[0][\"buildOptions\"];\n\tcustomToolNameToSdk: ReadonlyMap<string, string>;\n\ttoolWatchNote?: string;\n\tonResumeFallback: (error: unknown) => void;\n\tonContinuityDecision?: (observation: ContinuityObservation) => void;\n};\n\nfunction userMessage(content: SDKUserMessage[\"message\"][\"content\"]): SDKUserMessage[\"message\"] {\n\treturn { role: \"user\", content } as SDKUserMessage[\"message\"];\n}\n\nfunction successfulTurn(messages: readonly SDKMessage[]): boolean {\n\treturn messages.some((message) => message.type === \"result\" && message.subtype === \"success\");\n}\n\nfunction recordAssistantUuid(entry: ClaudeSdkOauthSessionEntry, sentCount: number, message: SDKMessage): void {\n\tif (message.type === \"assistant\" && message.parent_tool_use_id === null) {\n\t\tentry.assistantUuidByIndex.set(sentCount, message.uuid);\n\t}\n}\n\nfunction turnAttempt(\n\tentry: ClaudeSdkOauthSessionEntry,\n\tmessage: SDKUserMessage[\"message\"],\n\thashes: readonly string[],\n\tsignal: AbortSignal | undefined,\n\tstaged: ReturnType<typeof stageContinuityDecision>,\n) {\n\tconst generation = entry.generation;\n\treturn {\n\t\tmessages: (async function* (): AsyncGenerator<SDKMessage> {\n\t\t\tconst queue = new BoundedAsyncQueue<SDKMessage>(SESSION_STREAM_QUEUE_CAPACITY);\n\t\t\tconst completion = submitSessionTurn(sessionRegistry, entry, {\n\t\t\t\tmessage,\n\t\t\t\tsignal,\n\t\t\t\tonMessage: (sdkMessage) => {\n\t\t\t\t\trecordAssistantUuid(entry, hashes.length, sdkMessage);\n\t\t\t\t\tqueue.push(sdkMessage);\n\t\t\t\t},\n\t\t\t});\n\t\t\tvoid completion.then(\n\t\t\t\t() => queue.close(),\n\t\t\t\t(error: unknown) => queue.fail(error),\n\t\t\t);\n\t\t\ttry {\n\t\t\t\tfor await (const sdkMessage of queue) yield sdkMessage;\n\t\t\t\tconst turn = await completion;\n\t\t\t\tif (!turn.aborted && successfulTurn(turn.messages)) {\n\t\t\t\t\trecordSyncedStream(entry, hashes);\n\t\t\t\t\trememberBinding(bindingFromEntry(entry, hashes));\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\t// Every admitted turn reports exactly one decision, including one that\n\t\t\t\t// ended by abort or interrupt failure.\n\t\t\t\tstaged.emit();\n\t\t\t}\n\t\t})(),\n\t\tdiscard: (): void => {\n\t\t\tif (isCurrentGeneration(entry.senpiSessionId, generation))\n\t\t\t\tcloseSession(entry.senpiSessionId, \"attempt_discarded\");\n\t\t},\n\t};\n}\n\nconst OBSERVED_KIND: Record<ContinuityDecision[\"kind\"], \"incremental\" | \"resume\" | \"cold-seed\"> = {\n\tdelta: \"incremental\",\n\treattach: \"resume\",\n\tfork: \"resume\",\n\tflatten: \"cold-seed\",\n\tbootstrap: \"cold-seed\",\n};\n\nfunction entrySnapshot(entry: ClaudeSdkOauthSessionEntry, hashes: readonly string[]) {\n\treturn {\n\t\tsdkSessionId: entry.sdkSessionId,\n\t\taccountName: entry.accountName,\n\t\tmodelId: entry.modelId,\n\t\tsystemPromptHash: entry.systemPromptHash,\n\t\ttoolsetHash: entry.toolsetHash,\n\t\tsentCount: entry.sentCount,\n\t\tsentHashes: hashes.slice(0, entry.sentCount),\n\t\tlastAssistantUuid: entry.assistantUuidByIndex.get(entry.sentCount) ?? null,\n\t\tassistantUuidByIndex: entry.assistantUuidByIndex,\n\t\tpendingForkReason: entry.pendingForkReason,\n\t\ttaintedReason: entry.taintedReason,\n\t};\n}\n\nasync function createResidentAttempt(\n\tinput: ResidentSessionStreamInput,\n\tauth: AuthenticatedAttemptInput,\n): Promise<ReturnType<typeof turnAttempt>> {\n\tconst sessionId = input.streamOptions.sessionId!;\n\tconst messages = sentMessages(input.context);\n\tconst hashes = sentMessageHashes(messages);\n\tconst existing = getSession(sessionId);\n\tconst fingerprint = configFingerprint(auth.options, input.context, auth.authLane, auth.accountName);\n\tconst residentHashes = existing ? (sentHashesForEntry(existing) ?? hashes) : hashes;\n\tconst decision = decideNativeContinuity({\n\t\tentry: existing ? entrySnapshot(existing, residentHashes) : undefined,\n\t\tbinding: getBinding(sessionId),\n\t\tcurrentHashes: hashes,\n\t\taccountName: auth.accountName,\n\t\tmodelId: input.model.id,\n\t\tfingerprint,\n\t\ttranscriptAvailable: true,\n\t\tidleExpired: existing ? isIdleExpired(existing) : false,\n\t});\n\tconst firstTurn = existing === undefined && getBinding(sessionId) === undefined && hashes.length <= 1;\n\tlet observedReason =\n\t\t\"reason\" in decision ? decision.reason : decision.kind === \"bootstrap\" ? \"registry_miss\" : undefined;\n\tlet observedKind: \"incremental\" | \"resume\" | \"cold-seed\" = OBSERVED_KIND[decision.kind];\n\tlet entry: ClaudeSdkOauthSessionEntry;\n\tlet from = 0;\n\tlet flatten = decision.kind === \"flatten\" || decision.kind === \"bootstrap\";\n\n\tif (decision.kind === \"delta\" && existing) {\n\t\tentry = existing;\n\t\tfrom = decision.from;\n\t} else if (decision.kind === \"reattach\" || decision.kind === \"fork\") {\n\t\tconst source = getBinding(sessionId) ?? (existing ? bindingFromEntry(existing, residentHashes) : undefined);\n\t\tconst binding = source\n\t\t\t? {\n\t\t\t\t\t...source,\n\t\t\t\t\tsentCount: decision.from,\n\t\t\t\t\tsentHashes: source.sentHashes.slice(0, decision.from),\n\t\t\t\t\tassistantUuidByIndex: (source.assistantUuidByIndex ?? []).filter(([index]) => index <= decision.from),\n\t\t\t\t\t...(decision.kind === \"fork\" ? { lastAssistantUuid: decision.atUuid } : {}),\n\t\t\t\t}\n\t\t\t: undefined;\n\t\ttry {\n\t\t\tif (!binding) throw new Error(\"Claude SDK OAuth continuity binding is unavailable\");\n\t\t\tentry = await reattachSession({\n\t\t\t\tbinding,\n\t\t\t\toptions: auth.options,\n\t\t\t\t...(decision.kind === \"fork\" ? { atUuid: decision.atUuid } : {}),\n\t\t\t\t...(input.streamOptions.signal ? { signal: input.streamOptions.signal } : {}),\n\t\t\t});\n\t\t\tfrom = decision.from;\n\t\t} catch (error) {\n\t\t\tif (input.streamOptions.signal?.aborted) throw error;\n\t\t\tinput.onResumeFallback(error);\n\t\t\tobservedKind = \"cold-seed\";\n\t\t\tobservedReason = \"resume_initialization_failed\";\n\t\t\tflatten = true;\n\t\t\tentry = getOrCreateSession({\n\t\t\t\tsenpiSessionId: sessionId,\n\t\t\t\taccountName: auth.accountName,\n\t\t\t\tmodelId: input.model.id,\n\t\t\t\t...fingerprint,\n\t\t\t\toptions: auth.options,\n\t\t\t});\n\t\t}\n\t} else {\n\t\tif (existing) closeSession(sessionId, observedReason ?? \"registry_miss\");\n\t\tentry = getOrCreateSession({\n\t\t\tsenpiSessionId: sessionId,\n\t\t\taccountName: auth.accountName,\n\t\t\tmodelId: input.model.id,\n\t\t\t...fingerprint,\n\t\t\toptions: auth.options,\n\t\t});\n\t}\n\n\tconst blocks = flatten\n\t\t? buildPromptBlocks(input.context, input.customToolNameToSdk, input.toolWatchNote)\n\t\t: buildDeltaPromptBlocks(messages.slice(from), input.customToolNameToSdk);\n\tconst staged = stageContinuityDecision(\n\t\tobserveSessionSyncDecision({\n\t\t\tkind: observedKind,\n\t\t\treason: observedReason,\n\t\t\tdeltaMessages: flatten ? hashes.length : hashes.length - from,\n\t\t\tfirstTurn,\n\t\t\tsenpiSessionId: sessionId,\n\t\t}),\n\t\tinput.onContinuityDecision,\n\t\t// The pending close cause is consumed only when the staged observation\n\t\t// actually emits (attempt retained) — a discarded attempt leaves the\n\t\t// cause pending for the next admission.\n\t\t() => consumePendingCloseCause(sessionId),\n\t);\n\treturn turnAttempt(entry, userMessage(blocks), hashes, input.streamOptions.signal, staged);\n}\n\nexport async function* residentSessionMessages(input: ResidentSessionStreamInput): AsyncGenerator<SDKMessage> {\n\ttry {\n\t\tyield* residentAuthLaneMessages(input);\n\t} catch (error) {\n\t\t// Every attempt failed: the turn yields exactly one terminal observation.\n\t\temitContinuityObservation(\n\t\t\t{ kind: \"flatten\", reason: sanitizeTerminalFailure(error) },\n\t\t\tinput.onContinuityDecision,\n\t\t);\n\t\tthrow error;\n\t}\n}\n\nfunction residentAuthLaneMessages(input: ResidentSessionStreamInput): AsyncIterable<SDKMessage> {\n\treturn queryWithAuthLane({\n\t\tprompt: \"\",\n\t\tquery: getSdkBoundary().query,\n\t\tproviderSettings: input.providerSettings,\n\t\tsessionId: input.streamOptions.affinitySessionId ?? input.streamOptions.sessionId,\n\t\tpinnedAccount: input.pinnedAccount,\n\t\tbuildOptions: input.buildOptions,\n\t\tcreateAttempt: (auth) => createResidentAttempt(input, auth),\n\t});\n}\n"]}
1
+ {"version":3,"file":"session-stream.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/session-stream.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Api, Context, Model, SimpleStreamOptions } from \"@earendil-works/pi-ai\";\nimport { type AuthenticatedAttemptInput, queryWithAuthLane } from \"./auth-lane.ts\";\nimport { BoundedAsyncQueue, SESSION_STREAM_QUEUE_CAPACITY } from \"./bounded-queue.ts\";\nimport { buildPromptBlocks } from \"./prompt-bridge.ts\";\nimport { dedupeUltraworkBlocks, serializedPayloadBytes } from \"./prompt-directive-dedupe.ts\";\nimport type { SDKMessage, SDKUserMessage } from \"./sdk-boundary.ts\";\nimport { getSdkBoundary } from \"./sdk-boundary.ts\";\nimport { type ContinuityDecision, decideNativeContinuity } from \"./session-continuity.ts\";\nimport {\n\ttype ContinuityObservation,\n\tconsumePendingCloseCause,\n\temitContinuityObservation,\n\tobserveSessionSyncDecision,\n\tsanitizeTerminalFailure,\n\tstageContinuityDecision,\n} from \"./session-observability.ts\";\nimport { bindingFromEntry, getBinding, reattachSession, rememberBinding } from \"./session-reattach.ts\";\nimport {\n\ttype ClaudeSdkOauthSessionEntry,\n\tcloseSession,\n\tgetOrCreateSession,\n\tgetSession,\n\tisCurrentGeneration,\n\tisIdleExpired,\n\tsessionRegistry,\n} from \"./session-registry.ts\";\nimport { submitSessionTurn } from \"./session-registry-pump.ts\";\nimport {\n\tbuildDeltaPromptBlocks,\n\tconfigFingerprint,\n\trecordSyncedStream,\n\tsentHashesForEntry,\n\tsentMessageHashes,\n\tsentMessages,\n} from \"./session-sync.ts\";\nimport type { ClaudeSdkOauthProviderSettings } from \"./settings.ts\";\n\nexport type ResidentSessionStreamInput = {\n\tmodel: Model<Api>;\n\tcontext: Context;\n\tstreamOptions: SimpleStreamOptions;\n\tproviderSettings: ClaudeSdkOauthProviderSettings;\n\tpinnedAccount?: string;\n\tbuildOptions: Parameters<typeof queryWithAuthLane>[0][\"buildOptions\"];\n\tcustomToolNameToSdk: ReadonlyMap<string, string>;\n\ttoolWatchNote?: string;\n\tonResumeFallback: (error: unknown) => void;\n\tonContinuityDecision?: (observation: ContinuityObservation) => void;\n};\n\nfunction userMessage(content: SDKUserMessage[\"message\"][\"content\"]): SDKUserMessage[\"message\"] {\n\treturn { role: \"user\", content } as SDKUserMessage[\"message\"];\n}\n\nfunction successfulTurn(messages: readonly SDKMessage[]): boolean {\n\treturn messages.some((message) => message.type === \"result\" && message.subtype === \"success\");\n}\n\nfunction recordAssistantUuid(entry: ClaudeSdkOauthSessionEntry, sentCount: number, message: SDKMessage): void {\n\tif (message.type === \"assistant\" && message.parent_tool_use_id === null) {\n\t\tentry.assistantUuidByIndex.set(sentCount, message.uuid);\n\t}\n}\n\nfunction turnAttempt(\n\tentry: ClaudeSdkOauthSessionEntry,\n\tmessage: SDKUserMessage[\"message\"],\n\thashes: readonly string[],\n\tsignal: AbortSignal | undefined,\n\tstaged: ReturnType<typeof stageContinuityDecision>,\n) {\n\tconst generation = entry.generation;\n\treturn {\n\t\tmessages: (async function* (): AsyncGenerator<SDKMessage> {\n\t\t\tconst queue = new BoundedAsyncQueue<SDKMessage>(SESSION_STREAM_QUEUE_CAPACITY);\n\t\t\tconst completion = submitSessionTurn(sessionRegistry, entry, {\n\t\t\t\tmessage,\n\t\t\t\tsignal,\n\t\t\t\tonMessage: (sdkMessage) => {\n\t\t\t\t\trecordAssistantUuid(entry, hashes.length, sdkMessage);\n\t\t\t\t\tqueue.push(sdkMessage);\n\t\t\t\t},\n\t\t\t});\n\t\t\tvoid completion.then(\n\t\t\t\t() => queue.close(),\n\t\t\t\t(error: unknown) => queue.fail(error),\n\t\t\t);\n\t\t\ttry {\n\t\t\t\tfor await (const sdkMessage of queue) yield sdkMessage;\n\t\t\t\tconst turn = await completion;\n\t\t\t\tif (!turn.aborted && successfulTurn(turn.messages)) {\n\t\t\t\t\trecordSyncedStream(entry, hashes);\n\t\t\t\t\trememberBinding(bindingFromEntry(entry, hashes));\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\t// Every admitted turn reports exactly one decision, including one that\n\t\t\t\t// ended by abort or interrupt failure.\n\t\t\t\tstaged.emit();\n\t\t\t}\n\t\t})(),\n\t\tdiscard: (): void => {\n\t\t\tif (isCurrentGeneration(entry.senpiSessionId, generation))\n\t\t\t\tcloseSession(entry.senpiSessionId, \"attempt_discarded\");\n\t\t},\n\t};\n}\n\nconst OBSERVED_KIND: Record<ContinuityDecision[\"kind\"], \"incremental\" | \"resume\" | \"cold-seed\"> = {\n\tdelta: \"incremental\",\n\treattach: \"resume\",\n\tfork: \"resume\",\n\tflatten: \"cold-seed\",\n\tbootstrap: \"cold-seed\",\n};\n\nfunction entrySnapshot(entry: ClaudeSdkOauthSessionEntry, hashes: readonly string[]) {\n\treturn {\n\t\tsdkSessionId: entry.sdkSessionId,\n\t\taccountName: entry.accountName,\n\t\tmodelId: entry.modelId,\n\t\tsystemPromptHash: entry.systemPromptHash,\n\t\ttoolsetHash: entry.toolsetHash,\n\t\tsentCount: entry.sentCount,\n\t\tsentHashes: hashes.slice(0, entry.sentCount),\n\t\tlastAssistantUuid: entry.assistantUuidByIndex.get(entry.sentCount) ?? null,\n\t\tassistantUuidByIndex: entry.assistantUuidByIndex,\n\t\tpendingForkReason: entry.pendingForkReason,\n\t\ttaintedReason: entry.taintedReason,\n\t};\n}\n\nasync function createResidentAttempt(\n\tinput: ResidentSessionStreamInput,\n\tauth: AuthenticatedAttemptInput,\n): Promise<ReturnType<typeof turnAttempt>> {\n\tconst sessionId = input.streamOptions.sessionId!;\n\tconst messages = sentMessages(input.context);\n\tconst hashes = sentMessageHashes(messages);\n\tconst existing = getSession(sessionId);\n\tconst fingerprint = configFingerprint(auth.options, input.context, auth.authLane, auth.accountName);\n\tconst residentHashes = existing ? (sentHashesForEntry(existing) ?? hashes) : hashes;\n\tconst decision = decideNativeContinuity({\n\t\tentry: existing ? entrySnapshot(existing, residentHashes) : undefined,\n\t\tbinding: getBinding(sessionId),\n\t\tcurrentHashes: hashes,\n\t\taccountName: auth.accountName,\n\t\tmodelId: input.model.id,\n\t\tfingerprint,\n\t\ttranscriptAvailable: true,\n\t\tidleExpired: existing ? isIdleExpired(existing) : false,\n\t});\n\tconst firstTurn = existing === undefined && getBinding(sessionId) === undefined && hashes.length <= 1;\n\tlet observedReason =\n\t\t\"reason\" in decision ? decision.reason : decision.kind === \"bootstrap\" ? \"registry_miss\" : undefined;\n\tlet observedKind: \"incremental\" | \"resume\" | \"cold-seed\" = OBSERVED_KIND[decision.kind];\n\tlet entry: ClaudeSdkOauthSessionEntry;\n\tlet from = 0;\n\tlet flatten = decision.kind === \"flatten\" || decision.kind === \"bootstrap\";\n\n\tif (decision.kind === \"delta\" && existing) {\n\t\tentry = existing;\n\t\tfrom = decision.from;\n\t} else if (decision.kind === \"reattach\" || decision.kind === \"fork\") {\n\t\tconst source = getBinding(sessionId) ?? (existing ? bindingFromEntry(existing, residentHashes) : undefined);\n\t\tconst binding = source\n\t\t\t? {\n\t\t\t\t\t...source,\n\t\t\t\t\tsentCount: decision.from,\n\t\t\t\t\tsentHashes: source.sentHashes.slice(0, decision.from),\n\t\t\t\t\tassistantUuidByIndex: (source.assistantUuidByIndex ?? []).filter(([index]) => index <= decision.from),\n\t\t\t\t\t...(decision.kind === \"fork\" ? { lastAssistantUuid: decision.atUuid } : {}),\n\t\t\t\t}\n\t\t\t: undefined;\n\t\ttry {\n\t\t\tif (!binding) throw new Error(\"Claude SDK OAuth continuity binding is unavailable\");\n\t\t\tentry = await reattachSession({\n\t\t\t\tbinding,\n\t\t\t\toptions: auth.options,\n\t\t\t\t...(decision.kind === \"fork\" ? { atUuid: decision.atUuid } : {}),\n\t\t\t\t...(input.streamOptions.signal ? { signal: input.streamOptions.signal } : {}),\n\t\t\t});\n\t\t\tfrom = decision.from;\n\t\t} catch (error) {\n\t\t\tif (input.streamOptions.signal?.aborted) throw error;\n\t\t\tinput.onResumeFallback(error);\n\t\t\tobservedKind = \"cold-seed\";\n\t\t\tobservedReason = \"resume_initialization_failed\";\n\t\t\tflatten = true;\n\t\t\tentry = getOrCreateSession({\n\t\t\t\tsenpiSessionId: sessionId,\n\t\t\t\taccountName: auth.accountName,\n\t\t\t\tmodelId: input.model.id,\n\t\t\t\t...fingerprint,\n\t\t\t\toptions: auth.options,\n\t\t\t});\n\t\t}\n\t} else {\n\t\tif (existing) closeSession(sessionId, observedReason ?? \"registry_miss\");\n\t\tentry = getOrCreateSession({\n\t\t\tsenpiSessionId: sessionId,\n\t\t\taccountName: auth.accountName,\n\t\t\tmodelId: input.model.id,\n\t\t\t...fingerprint,\n\t\t\toptions: auth.options,\n\t\t});\n\t}\n\n\tconst flattenResult = flatten\n\t\t? dedupeUltraworkBlocks(buildPromptBlocks(input.context, input.customToolNameToSdk, input.toolWatchNote))\n\t\t: undefined;\n\tconst blocks = flattenResult\n\t\t? flattenResult.blocks\n\t\t: buildDeltaPromptBlocks(messages.slice(from), input.customToolNameToSdk);\n\tconst payloadBytes = flattenResult ? serializedPayloadBytes(flattenResult.blocks) : undefined;\n\tconst staged = stageContinuityDecision(\n\t\tobserveSessionSyncDecision({\n\t\t\tkind: observedKind,\n\t\t\treason: observedReason,\n\t\t\tdeltaMessages: flatten ? hashes.length : hashes.length - from,\n\t\t\tfirstTurn,\n\t\t\tsenpiSessionId: sessionId,\n\t\t\t...(payloadBytes !== undefined ? { payloadBytes } : {}),\n\t\t\t...(flattenResult?.collapsedDirectives !== undefined\n\t\t\t\t? { collapsedDirectives: flattenResult.collapsedDirectives }\n\t\t\t\t: {}),\n\t\t}),\n\t\tinput.onContinuityDecision,\n\t\t// The pending close cause is consumed only when the staged observation\n\t\t// actually emits (attempt retained) — a discarded attempt leaves the\n\t\t// cause pending for the next admission.\n\t\t() => consumePendingCloseCause(sessionId),\n\t);\n\treturn turnAttempt(entry, userMessage(blocks), hashes, input.streamOptions.signal, staged);\n}\n\nexport async function* residentSessionMessages(input: ResidentSessionStreamInput): AsyncGenerator<SDKMessage> {\n\ttry {\n\t\tyield* residentAuthLaneMessages(input);\n\t} catch (error) {\n\t\t// Every attempt failed: the turn yields exactly one terminal observation.\n\t\temitContinuityObservation(\n\t\t\t{ kind: \"flatten\", reason: sanitizeTerminalFailure(error) },\n\t\t\tinput.onContinuityDecision,\n\t\t);\n\t\tthrow error;\n\t}\n}\n\nfunction residentAuthLaneMessages(input: ResidentSessionStreamInput): AsyncIterable<SDKMessage> {\n\treturn queryWithAuthLane({\n\t\tprompt: \"\",\n\t\tquery: getSdkBoundary().query,\n\t\tproviderSettings: input.providerSettings,\n\t\tsessionId: input.streamOptions.affinitySessionId ?? input.streamOptions.sessionId,\n\t\tpinnedAccount: input.pinnedAccount,\n\t\tbuildOptions: input.buildOptions,\n\t\tcreateAttempt: (auth) => createResidentAttempt(input, auth),\n\t});\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/stream.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,GAAG,EACR,KAAK,2BAA2B,EAChC,KAAK,OAAO,EAGZ,KAAK,KAAK,EACV,KAAK,mBAAmB,EACxB,MAAM,uBAAuB,CAAC;AAiB/B,wBAAgB,oBAAoB,CACnC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,mBAAmB,GAC3B,2BAA2B,CA4L7B"}
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/stream.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,GAAG,EACR,KAAK,2BAA2B,EAChC,KAAK,OAAO,EAGZ,KAAK,KAAK,EACV,KAAK,mBAAmB,EACxB,MAAM,uBAAuB,CAAC;AAkB/B,wBAAgB,oBAAoB,CACnC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,mBAAmB,GAC3B,2BAA2B,CA6L7B"}
@@ -5,6 +5,7 @@ import { buildCustomToolServers } from "./custom-tools.js";
5
5
  import { defaultExecutableDeps, resolveClaudeCodeExecutable } from "./executable.js";
6
6
  import { buildClaudeSdkOauthQueryOptions } from "./options.js";
7
7
  import { buildPromptBlocks, buildPromptStream } from "./prompt-bridge.js";
8
+ import { dedupeUltraworkBlocks } from "./prompt-directive-dedupe.js";
8
9
  import { getSdkBoundary } from "./sdk-boundary.js";
9
10
  import { emitContinuityObservation } from "./session-observability.js";
10
11
  import { residentSessionMessages } from "./session-stream.js";
@@ -117,7 +118,8 @@ export function streamClaudeSdkOauth(model, context, options) {
117
118
  },
118
119
  })
119
120
  : queryWithAuthLane({
120
- prompt: buildPromptStream(buildPromptBlocks(context, resolvedTools.customToolNameToSdk, toolWatchNote)),
121
+ prompt: buildPromptStream(dedupeUltraworkBlocks(buildPromptBlocks(context, resolvedTools.customToolNameToSdk, toolWatchNote))
122
+ .blocks),
121
123
  query: getSdkBoundary().query,
122
124
  providerSettings,
123
125
  sessionId: affinityKey,
@@ -1 +1 @@
1
- {"version":3,"file":"stream.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/stream.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype Api,\n\ttype AssistantMessageEventStream,\n\ttype Context,\n\tcreateAssistantMessageDiagnostic,\n\tcreateAssistantMessageEventStream,\n\ttype Model,\n\ttype SimpleStreamOptions,\n} from \"@earendil-works/pi-ai\";\nimport { getSessionClaudeAccountPin } from \"./account-command.ts\";\nimport { queryWithAuthLane } from \"./auth-lane.ts\";\nimport { buildCustomToolServers } from \"./custom-tools.ts\";\nimport { defaultExecutableDeps, resolveClaudeCodeExecutable } from \"./executable.ts\";\nimport { buildClaudeSdkOauthQueryOptions } from \"./options.ts\";\nimport { buildPromptBlocks, buildPromptStream } from \"./prompt-bridge.ts\";\nimport { getSdkBoundary, type SdkQueryHandle } from \"./sdk-boundary.ts\";\nimport { type ContinuityObservation, emitContinuityObservation } from \"./session-observability.ts\";\nimport { residentSessionMessages } from \"./session-stream.ts\";\nimport { loadClaudeSdkOauthProviderSettingsFromDisk } from \"./settings.ts\";\nimport { applyStreamEvent } from \"./stream-events.ts\";\nimport { withAuthGuidance } from \"./stream-guidance.ts\";\nimport { emptyOutput, errorMessage, mapStopReason, type StreamBlock, updateUsage } from \"./stream-protocol.ts\";\nimport { toolWatch } from \"./tool-watch.ts\";\nimport { resolveSdkTools } from \"./tools.ts\";\n\nexport function streamClaudeSdkOauth(\n\tmodel: Model<Api>,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream {\n\tconst stream = createAssistantMessageEventStream();\n\tvoid (async () => {\n\t\tconst output = emptyOutput(model);\n\t\tconst blocks: StreamBlock[] = [];\n\t\tlet sdkQuery: SdkQueryHandle | undefined;\n\t\tlet closed = false;\n\t\tlet wasAborted = false;\n\t\tlet started = false;\n\t\tlet sawStreamEvent = false;\n\t\tconst closeQuery = (): void => {\n\t\t\tif (closed || !sdkQuery) return;\n\t\t\tclosed = true;\n\t\t\tsdkQuery.close();\n\t\t};\n\t\tconst requestAbort = (): void => {\n\t\t\tif (!sdkQuery) return;\n\t\t\tvoid sdkQuery\n\t\t\t\t.interrupt()\n\t\t\t\t.catch(() => {})\n\t\t\t\t.finally(closeQuery);\n\t\t};\n\t\tconst onAbort = (): void => {\n\t\t\twasAborted = true;\n\t\t\trequestAbort();\n\t\t};\n\t\tif (options?.signal?.aborted) onAbort();\n\t\telse options?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\ttry {\n\t\t\tconst resolvedTools = resolveSdkTools(context);\n\t\t\tconst affinityKey = options?.affinitySessionId ?? options?.sessionId;\n\t\t\tconst sessionKey = options?.sessionId ? toolWatch.sessionKey(options.sessionId) : undefined;\n\t\t\tif (sessionKey) toolWatch.reconcileWithContext(sessionKey, context);\n\t\t\tconst toolWatchNote = toolWatch.buildPromptNote(sessionKey, context, resolvedTools.customToolNameToSdk);\n\t\t\tconst providerSettings = loadClaudeSdkOauthProviderSettingsFromDisk(process.cwd());\n\t\t\tconst mcpServers = buildCustomToolServers(resolvedTools.customTools);\n\t\t\tconst executable = resolveClaudeCodeExecutable(defaultExecutableDeps());\n\t\t\tconst buildOptions = (authLane: Parameters<typeof buildClaudeSdkOauthQueryOptions>[0][\"authLane\"]) => {\n\t\t\t\tconst queryOptions = buildClaudeSdkOauthQueryOptions({\n\t\t\t\t\tmodel,\n\t\t\t\t\tcontext,\n\t\t\t\t\tstreamOptions: options,\n\t\t\t\t\tproviderSettings,\n\t\t\t\t\tauthLane,\n\t\t\t\t\ttools: resolvedTools.sdkTools,\n\t\t\t\t\tpathToClaudeCodeExecutable: executable,\n\t\t\t\t\tsessionId: options?.sessionId,\n\t\t\t\t\tonGuidance: (text) => {\n\t\t\t\t\t\toutput.diagnostics = [\n\t\t\t\t\t\t\t...(output.diagnostics ?? []),\n\t\t\t\t\t\t\tcreateAssistantMessageDiagnostic(\"claude_sdk_oauth_deprecation\", text),\n\t\t\t\t\t\t];\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tif (mcpServers) queryOptions.mcpServers = mcpServers;\n\t\t\t\treturn queryOptions;\n\t\t\t};\n\t\t\tconst recordContinuity = (observation: ContinuityObservation): void => {\n\t\t\t\t// Not a failure: carry the observation as details only, with no synthesized error.\n\t\t\t\toutput.diagnostics = [\n\t\t\t\t\t...(output.diagnostics ?? []),\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"claude_sdk_oauth_session_continuity\",\n\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\tdetails: { ...observation },\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\t};\n\t\t\tconst useResidentSession =\n\t\t\t\toptions?.streamKind === \"main\" && providerSettings.resumeMode !== \"off\" && options.sessionId !== undefined;\n\t\t\tif (options?.streamKind === \"main\" && !useResidentSession) {\n\t\t\t\t// The reason must reflect the ACTUAL cause: resume mode \"off\"\n\t\t\t\t// disables the lane by setting, while any other mode simply has no\n\t\t\t\t// resident session to reuse yet.\n\t\t\t\temitContinuityObservation(\n\t\t\t\t\t{\n\t\t\t\t\t\tkind: \"disabled\",\n\t\t\t\t\t\treason: providerSettings.resumeMode === \"off\" ? \"resume_mode_off\" : \"registry_miss\",\n\t\t\t\t\t},\n\t\t\t\t\trecordContinuity,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst messages = useResidentSession\n\t\t\t\t? residentSessionMessages({\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tcontext,\n\t\t\t\t\t\tstreamOptions: options,\n\t\t\t\t\t\tproviderSettings,\n\t\t\t\t\t\tpinnedAccount: getSessionClaudeAccountPin(options.sessionId),\n\t\t\t\t\t\tbuildOptions,\n\t\t\t\t\t\tcustomToolNameToSdk: resolvedTools.customToolNameToSdk,\n\t\t\t\t\t\ttoolWatchNote,\n\t\t\t\t\t\tonContinuityDecision: recordContinuity,\n\t\t\t\t\t\tonResumeFallback: (error) => {\n\t\t\t\t\t\t\toutput.diagnostics = [\n\t\t\t\t\t\t\t\t...(output.diagnostics ?? []),\n\t\t\t\t\t\t\t\tcreateAssistantMessageDiagnostic(\"claude_sdk_oauth_resume_fallback\", error),\n\t\t\t\t\t\t\t];\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t: queryWithAuthLane({\n\t\t\t\t\t\tprompt: buildPromptStream(\n\t\t\t\t\t\t\tbuildPromptBlocks(context, resolvedTools.customToolNameToSdk, toolWatchNote),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tquery: getSdkBoundary().query,\n\t\t\t\t\t\tproviderSettings,\n\t\t\t\t\t\tsessionId: affinityKey,\n\t\t\t\t\t\tpinnedAccount: getSessionClaudeAccountPin(options?.sessionId),\n\t\t\t\t\t\tonQuery: (query) => {\n\t\t\t\t\t\t\tsdkQuery = query;\n\t\t\t\t\t\t\tif (wasAborted) requestAbort();\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbuildOptions,\n\t\t\t\t\t});\n\n\t\t\tfor await (const message of messages) {\n\t\t\t\tif (!started) {\n\t\t\t\t\tstream.push({ type: \"start\", partial: output });\n\t\t\t\t\tstarted = true;\n\t\t\t\t}\n\t\t\t\tif (message.type === \"stream_event\") {\n\t\t\t\t\tsawStreamEvent = true;\n\t\t\t\t\tapplyStreamEvent(\n\t\t\t\t\t\t{ model, output, blocks, stream, customToolNameToPi: resolvedTools.customToolNameToPi },\n\t\t\t\t\t\tmessage.event,\n\t\t\t\t\t);\n\t\t\t\t} else if (message.type === \"system\" && message.subtype === \"compact_boundary\") {\n\t\t\t\t\t// Native compactions must reach the ledger: attach the boundary as a\n\t\t\t\t\t// diagnostic so the lane-policy collector can build a ledger entry\n\t\t\t\t\t// instead of the boundary being discarded in the stream.\n\t\t\t\t\toutput.diagnostics = [\n\t\t\t\t\t\t...(output.diagnostics ?? []),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"claude_sdk_oauth_compact_boundary\",\n\t\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\t\tdetails: {\n\t\t\t\t\t\t\t\tboundary: {\n\t\t\t\t\t\t\t\t\ttrigger: message.compact_metadata?.trigger ?? \"unknown\",\n\t\t\t\t\t\t\t\t\tpreTokens: message.compact_metadata?.pre_tokens ?? 0,\n\t\t\t\t\t\t\t\t\tpostTokens: message.compact_metadata?.post_tokens ?? 0,\n\t\t\t\t\t\t\t\t\tlineageId: message.session_id ?? \"\",\n\t\t\t\t\t\t\t\t\tobservedAt: Date.now(),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t];\n\t\t\t\t} else if (message.type === \"result\" && message.subtype === \"success\") {\n\t\t\t\t\t// Both fields are optional on the wire, so only adopt them when present.\n\t\t\t\t\t// A terminal result must never downgrade a toolUse turn that the stream\n\t\t\t\t\t// already established, or the agent loop would stop instead of running\n\t\t\t\t\t// the tool call sitting in `output.content`.\n\t\t\t\t\tif (message.usage) updateUsage(model, output, message.usage);\n\t\t\t\t\tif (message.stop_reason != null && output.stopReason !== \"toolUse\") {\n\t\t\t\t\t\toutput.stopReason = mapStopReason(message.stop_reason);\n\t\t\t\t\t}\n\t\t\t\t\tif (!sawStreamEvent) output.content.push({ type: \"text\", text: message.result });\n\t\t\t\t} else if (message.type === \"result\") {\n\t\t\t\t\tconst reason =\n\t\t\t\t\t\t\"errors\" in message && Array.isArray(message.errors) && message.errors.length > 0\n\t\t\t\t\t\t\t? String(message.errors[0])\n\t\t\t\t\t\t\t: `Claude Code ${message.subtype}`;\n\t\t\t\t\tthrow new Error(reason);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (wasAborted || options?.signal?.aborted) {\n\t\t\t\toutput.stopReason = \"aborted\";\n\t\t\t\toutput.errorMessage = \"Operation aborted\";\n\t\t\t\tstream.push({ type: \"error\", reason: \"aborted\", error: output });\n\t\t\t} else {\n\t\t\t\tstream.push({\n\t\t\t\t\ttype: \"done\",\n\t\t\t\t\treason: output.stopReason === \"toolUse\" ? \"toolUse\" : output.stopReason === \"length\" ? \"length\" : \"stop\",\n\t\t\t\t\tmessage: output,\n\t\t\t\t});\n\t\t\t}\n\t\t} catch (error) {\n\t\t\toutput.stopReason = options?.signal?.aborted ? \"aborted\" : \"error\";\n\t\t\toutput.errorMessage = withAuthGuidance(error, errorMessage(error));\n\t\t\tstream.push({ type: \"error\", reason: output.stopReason, error: output });\n\t\t} finally {\n\t\t\toptions?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\tcloseQuery();\n\t\t\tstream.end();\n\t\t}\n\t})();\n\treturn stream;\n}\n"]}
1
+ {"version":3,"file":"stream.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/stream.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype Api,\n\ttype AssistantMessageEventStream,\n\ttype Context,\n\tcreateAssistantMessageDiagnostic,\n\tcreateAssistantMessageEventStream,\n\ttype Model,\n\ttype SimpleStreamOptions,\n} from \"@earendil-works/pi-ai\";\nimport { getSessionClaudeAccountPin } from \"./account-command.ts\";\nimport { queryWithAuthLane } from \"./auth-lane.ts\";\nimport { buildCustomToolServers } from \"./custom-tools.ts\";\nimport { defaultExecutableDeps, resolveClaudeCodeExecutable } from \"./executable.ts\";\nimport { buildClaudeSdkOauthQueryOptions } from \"./options.ts\";\nimport { buildPromptBlocks, buildPromptStream } from \"./prompt-bridge.ts\";\nimport { dedupeUltraworkBlocks } from \"./prompt-directive-dedupe.ts\";\nimport { getSdkBoundary, type SdkQueryHandle } from \"./sdk-boundary.ts\";\nimport { type ContinuityObservation, emitContinuityObservation } from \"./session-observability.ts\";\nimport { residentSessionMessages } from \"./session-stream.ts\";\nimport { loadClaudeSdkOauthProviderSettingsFromDisk } from \"./settings.ts\";\nimport { applyStreamEvent } from \"./stream-events.ts\";\nimport { withAuthGuidance } from \"./stream-guidance.ts\";\nimport { emptyOutput, errorMessage, mapStopReason, type StreamBlock, updateUsage } from \"./stream-protocol.ts\";\nimport { toolWatch } from \"./tool-watch.ts\";\nimport { resolveSdkTools } from \"./tools.ts\";\n\nexport function streamClaudeSdkOauth(\n\tmodel: Model<Api>,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream {\n\tconst stream = createAssistantMessageEventStream();\n\tvoid (async () => {\n\t\tconst output = emptyOutput(model);\n\t\tconst blocks: StreamBlock[] = [];\n\t\tlet sdkQuery: SdkQueryHandle | undefined;\n\t\tlet closed = false;\n\t\tlet wasAborted = false;\n\t\tlet started = false;\n\t\tlet sawStreamEvent = false;\n\t\tconst closeQuery = (): void => {\n\t\t\tif (closed || !sdkQuery) return;\n\t\t\tclosed = true;\n\t\t\tsdkQuery.close();\n\t\t};\n\t\tconst requestAbort = (): void => {\n\t\t\tif (!sdkQuery) return;\n\t\t\tvoid sdkQuery\n\t\t\t\t.interrupt()\n\t\t\t\t.catch(() => {})\n\t\t\t\t.finally(closeQuery);\n\t\t};\n\t\tconst onAbort = (): void => {\n\t\t\twasAborted = true;\n\t\t\trequestAbort();\n\t\t};\n\t\tif (options?.signal?.aborted) onAbort();\n\t\telse options?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\ttry {\n\t\t\tconst resolvedTools = resolveSdkTools(context);\n\t\t\tconst affinityKey = options?.affinitySessionId ?? options?.sessionId;\n\t\t\tconst sessionKey = options?.sessionId ? toolWatch.sessionKey(options.sessionId) : undefined;\n\t\t\tif (sessionKey) toolWatch.reconcileWithContext(sessionKey, context);\n\t\t\tconst toolWatchNote = toolWatch.buildPromptNote(sessionKey, context, resolvedTools.customToolNameToSdk);\n\t\t\tconst providerSettings = loadClaudeSdkOauthProviderSettingsFromDisk(process.cwd());\n\t\t\tconst mcpServers = buildCustomToolServers(resolvedTools.customTools);\n\t\t\tconst executable = resolveClaudeCodeExecutable(defaultExecutableDeps());\n\t\t\tconst buildOptions = (authLane: Parameters<typeof buildClaudeSdkOauthQueryOptions>[0][\"authLane\"]) => {\n\t\t\t\tconst queryOptions = buildClaudeSdkOauthQueryOptions({\n\t\t\t\t\tmodel,\n\t\t\t\t\tcontext,\n\t\t\t\t\tstreamOptions: options,\n\t\t\t\t\tproviderSettings,\n\t\t\t\t\tauthLane,\n\t\t\t\t\ttools: resolvedTools.sdkTools,\n\t\t\t\t\tpathToClaudeCodeExecutable: executable,\n\t\t\t\t\tsessionId: options?.sessionId,\n\t\t\t\t\tonGuidance: (text) => {\n\t\t\t\t\t\toutput.diagnostics = [\n\t\t\t\t\t\t\t...(output.diagnostics ?? []),\n\t\t\t\t\t\t\tcreateAssistantMessageDiagnostic(\"claude_sdk_oauth_deprecation\", text),\n\t\t\t\t\t\t];\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tif (mcpServers) queryOptions.mcpServers = mcpServers;\n\t\t\t\treturn queryOptions;\n\t\t\t};\n\t\t\tconst recordContinuity = (observation: ContinuityObservation): void => {\n\t\t\t\t// Not a failure: carry the observation as details only, with no synthesized error.\n\t\t\t\toutput.diagnostics = [\n\t\t\t\t\t...(output.diagnostics ?? []),\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"claude_sdk_oauth_session_continuity\",\n\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\tdetails: { ...observation },\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\t};\n\t\t\tconst useResidentSession =\n\t\t\t\toptions?.streamKind === \"main\" && providerSettings.resumeMode !== \"off\" && options.sessionId !== undefined;\n\t\t\tif (options?.streamKind === \"main\" && !useResidentSession) {\n\t\t\t\t// The reason must reflect the ACTUAL cause: resume mode \"off\"\n\t\t\t\t// disables the lane by setting, while any other mode simply has no\n\t\t\t\t// resident session to reuse yet.\n\t\t\t\temitContinuityObservation(\n\t\t\t\t\t{\n\t\t\t\t\t\tkind: \"disabled\",\n\t\t\t\t\t\treason: providerSettings.resumeMode === \"off\" ? \"resume_mode_off\" : \"registry_miss\",\n\t\t\t\t\t},\n\t\t\t\t\trecordContinuity,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst messages = useResidentSession\n\t\t\t\t? residentSessionMessages({\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tcontext,\n\t\t\t\t\t\tstreamOptions: options,\n\t\t\t\t\t\tproviderSettings,\n\t\t\t\t\t\tpinnedAccount: getSessionClaudeAccountPin(options.sessionId),\n\t\t\t\t\t\tbuildOptions,\n\t\t\t\t\t\tcustomToolNameToSdk: resolvedTools.customToolNameToSdk,\n\t\t\t\t\t\ttoolWatchNote,\n\t\t\t\t\t\tonContinuityDecision: recordContinuity,\n\t\t\t\t\t\tonResumeFallback: (error) => {\n\t\t\t\t\t\t\toutput.diagnostics = [\n\t\t\t\t\t\t\t\t...(output.diagnostics ?? []),\n\t\t\t\t\t\t\t\tcreateAssistantMessageDiagnostic(\"claude_sdk_oauth_resume_fallback\", error),\n\t\t\t\t\t\t\t];\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t: queryWithAuthLane({\n\t\t\t\t\t\tprompt: buildPromptStream(\n\t\t\t\t\t\t\tdedupeUltraworkBlocks(buildPromptBlocks(context, resolvedTools.customToolNameToSdk, toolWatchNote))\n\t\t\t\t\t\t\t\t.blocks,\n\t\t\t\t\t\t),\n\t\t\t\t\t\tquery: getSdkBoundary().query,\n\t\t\t\t\t\tproviderSettings,\n\t\t\t\t\t\tsessionId: affinityKey,\n\t\t\t\t\t\tpinnedAccount: getSessionClaudeAccountPin(options?.sessionId),\n\t\t\t\t\t\tonQuery: (query) => {\n\t\t\t\t\t\t\tsdkQuery = query;\n\t\t\t\t\t\t\tif (wasAborted) requestAbort();\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbuildOptions,\n\t\t\t\t\t});\n\n\t\t\tfor await (const message of messages) {\n\t\t\t\tif (!started) {\n\t\t\t\t\tstream.push({ type: \"start\", partial: output });\n\t\t\t\t\tstarted = true;\n\t\t\t\t}\n\t\t\t\tif (message.type === \"stream_event\") {\n\t\t\t\t\tsawStreamEvent = true;\n\t\t\t\t\tapplyStreamEvent(\n\t\t\t\t\t\t{ model, output, blocks, stream, customToolNameToPi: resolvedTools.customToolNameToPi },\n\t\t\t\t\t\tmessage.event,\n\t\t\t\t\t);\n\t\t\t\t} else if (message.type === \"system\" && message.subtype === \"compact_boundary\") {\n\t\t\t\t\t// Native compactions must reach the ledger: attach the boundary as a\n\t\t\t\t\t// diagnostic so the lane-policy collector can build a ledger entry\n\t\t\t\t\t// instead of the boundary being discarded in the stream.\n\t\t\t\t\toutput.diagnostics = [\n\t\t\t\t\t\t...(output.diagnostics ?? []),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"claude_sdk_oauth_compact_boundary\",\n\t\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\t\tdetails: {\n\t\t\t\t\t\t\t\tboundary: {\n\t\t\t\t\t\t\t\t\ttrigger: message.compact_metadata?.trigger ?? \"unknown\",\n\t\t\t\t\t\t\t\t\tpreTokens: message.compact_metadata?.pre_tokens ?? 0,\n\t\t\t\t\t\t\t\t\tpostTokens: message.compact_metadata?.post_tokens ?? 0,\n\t\t\t\t\t\t\t\t\tlineageId: message.session_id ?? \"\",\n\t\t\t\t\t\t\t\t\tobservedAt: Date.now(),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t];\n\t\t\t\t} else if (message.type === \"result\" && message.subtype === \"success\") {\n\t\t\t\t\t// Both fields are optional on the wire, so only adopt them when present.\n\t\t\t\t\t// A terminal result must never downgrade a toolUse turn that the stream\n\t\t\t\t\t// already established, or the agent loop would stop instead of running\n\t\t\t\t\t// the tool call sitting in `output.content`.\n\t\t\t\t\tif (message.usage) updateUsage(model, output, message.usage);\n\t\t\t\t\tif (message.stop_reason != null && output.stopReason !== \"toolUse\") {\n\t\t\t\t\t\toutput.stopReason = mapStopReason(message.stop_reason);\n\t\t\t\t\t}\n\t\t\t\t\tif (!sawStreamEvent) output.content.push({ type: \"text\", text: message.result });\n\t\t\t\t} else if (message.type === \"result\") {\n\t\t\t\t\tconst reason =\n\t\t\t\t\t\t\"errors\" in message && Array.isArray(message.errors) && message.errors.length > 0\n\t\t\t\t\t\t\t? String(message.errors[0])\n\t\t\t\t\t\t\t: `Claude Code ${message.subtype}`;\n\t\t\t\t\tthrow new Error(reason);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (wasAborted || options?.signal?.aborted) {\n\t\t\t\toutput.stopReason = \"aborted\";\n\t\t\t\toutput.errorMessage = \"Operation aborted\";\n\t\t\t\tstream.push({ type: \"error\", reason: \"aborted\", error: output });\n\t\t\t} else {\n\t\t\t\tstream.push({\n\t\t\t\t\ttype: \"done\",\n\t\t\t\t\treason: output.stopReason === \"toolUse\" ? \"toolUse\" : output.stopReason === \"length\" ? \"length\" : \"stop\",\n\t\t\t\t\tmessage: output,\n\t\t\t\t});\n\t\t\t}\n\t\t} catch (error) {\n\t\t\toutput.stopReason = options?.signal?.aborted ? \"aborted\" : \"error\";\n\t\t\toutput.errorMessage = withAuthGuidance(error, errorMessage(error));\n\t\t\tstream.push({ type: \"error\", reason: output.stopReason, error: output });\n\t\t} finally {\n\t\t\toptions?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\tcloseQuery();\n\t\t\tstream.end();\n\t\t}\n\t})();\n\treturn stream;\n}\n"]}
@@ -105,6 +105,8 @@ function resolveRefs(value, root, seenRefs, warnings) {
105
105
  }
106
106
  const result = {};
107
107
  for (const [key, child] of Object.entries(value)) {
108
+ if (key === "type" && child === null)
109
+ continue;
108
110
  result[key] = resolveRefs(child, root, seenRefs, warnings);
109
111
  }
110
112
  return result;
@@ -1 +1 @@
1
- {"version":3,"file":"schema-compat.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/mcp/expose/schema-compat.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ImageContent, TextContent } from \"@earendil-works/pi-ai\";\nimport { type TSchema, Type } from \"typebox\";\nimport { buildMcpToolName, buildMcpToolNames, type McpToolNameEntry } from \"./naming.ts\";\nimport { collectAllPages, type McpListPage, type McpPaginationResult } from \"./pagination.ts\";\n\nexport type { McpListPage, McpPaginationResult, McpToolNameEntry };\nexport { buildMcpToolName, buildMcpToolNames, collectAllPages };\n\ninterface SchemaConversionResult {\n\tschema: TSchema;\n\twarnings: string[];\n}\n\ninterface OutputSchemaRetryResult {\n\tschema: Record<string, unknown>;\n\twarnings: string[];\n}\n\nexport type McpContentBlock =\n\t| { type: \"text\"; text?: unknown }\n\t| { type: \"image\"; data?: unknown; mimeType?: unknown }\n\t| { type: \"audio\"; data?: unknown; mimeType?: unknown }\n\t| { type: \"resource\"; resource?: unknown }\n\t| { type: \"resource_link\"; uri?: unknown; name?: unknown; description?: unknown; mimeType?: unknown }\n\t| Record<string, unknown>;\n\nexport type McpMappedContentBlock =\n\t| TextContent\n\t| ImageContent\n\t| { type: \"audio\"; data: string; mimeType: string }\n\t| { type: \"resource\"; resource: unknown }\n\t| { type: \"resource_link\"; uri: string; name?: string; description?: string; mimeType?: string };\n\nexport interface McpToolResultLike {\n\tcontent?: McpContentBlock[];\n\tstructuredContent?: unknown;\n\tisError?: boolean;\n}\n\nexport type McpMappedToolResult =\n\t| { ok: true; content: McpMappedContentBlock[] }\n\t| { ok: false; error: { message: string; content: McpMappedContentBlock[] } };\n\nconst PERMISSIVE_OBJECT_SCHEMA = { type: \"object\", properties: {} } as const;\n\nexport function convertJsonSchemaToTypeBox(schema: unknown): SchemaConversionResult {\n\tconst warnings: string[] = [];\n\tconst resolved = resolveRefs(stripTopLevelSchemaKeys(schema), schema, new Set<string>(), warnings);\n\tif (warnings.length > 0) {\n\t\treturn { schema: Type.Unsafe<unknown>({ ...PERMISSIVE_OBJECT_SCHEMA }), warnings };\n\t}\n\tif (!isRecord(resolved)) {\n\t\treturn {\n\t\t\tschema: Type.Unsafe<unknown>({ ...PERMISSIVE_OBJECT_SCHEMA }),\n\t\t\twarnings: [\"MCP schema is not an object; using permissive object schema.\"],\n\t\t};\n\t}\n\treturn { schema: Type.Unsafe<unknown>(resolved), warnings };\n}\n\nexport function prepareOutputSchemaRetry(schema: unknown): OutputSchemaRetryResult {\n\tconst warnings: string[] = [];\n\tconst record: Record<string, unknown> = isRecord(schema) ? { ...schema } : { ...PERMISSIVE_OBJECT_SCHEMA };\n\tif (hasOwn(record, \"$schema\")) {\n\t\tdelete record.$schema;\n\t\twarnings.push(\"Stripped top-level $schema from MCP outputSchema retry.\");\n\t}\n\tif (hasOwn(record, \"additionalProperties\")) {\n\t\tdelete record.additionalProperties;\n\t\twarnings.push(\"Stripped top-level additionalProperties from MCP outputSchema retry.\");\n\t}\n\treturn { schema: record, warnings };\n}\n\nexport function mapMcpToolResult(result: McpToolResultLike): McpMappedToolResult {\n\tconst content = mapMcpContent(result);\n\tif (result.isError === true) {\n\t\treturn { ok: false, error: { message: contentToErrorMessage(content), content } };\n\t}\n\treturn { ok: true, content };\n}\n\nfunction mapMcpContent(result: McpToolResultLike): McpMappedContentBlock[] {\n\tconst content: McpMappedContentBlock[] = [];\n\tfor (const block of result.content ?? []) {\n\t\tcontent.push(mapContentBlock(block));\n\t}\n\tif (result.structuredContent !== undefined) {\n\t\tcontent.push({ type: \"text\", text: stringifyJson(result.structuredContent) });\n\t}\n\tif (content.length === 0) {\n\t\tcontent.push({ type: \"text\", text: \"(empty result)\" });\n\t}\n\treturn content;\n}\n\nfunction mapContentBlock(block: McpContentBlock): McpMappedContentBlock {\n\tif (block.type === \"text\") {\n\t\treturn { type: \"text\", text: typeof block.text === \"string\" ? block.text : stringifyJson(block.text) };\n\t}\n\tif (block.type === \"image\" && typeof block.data === \"string\" && typeof block.mimeType === \"string\") {\n\t\treturn { type: \"image\", data: block.data, mimeType: block.mimeType };\n\t}\n\tif (block.type === \"audio\" && typeof block.data === \"string\" && typeof block.mimeType === \"string\") {\n\t\treturn { type: \"audio\", data: block.data, mimeType: block.mimeType };\n\t}\n\tif (block.type === \"resource\" && hasOwn(block, \"resource\")) {\n\t\treturn { type: \"resource\", resource: block.resource };\n\t}\n\tif (block.type === \"resource_link\" && typeof block.uri === \"string\") {\n\t\treturn {\n\t\t\ttype: \"resource_link\",\n\t\t\turi: block.uri,\n\t\t\t...(typeof block.name === \"string\" ? { name: block.name } : {}),\n\t\t\t...(typeof block.description === \"string\" ? { description: block.description } : {}),\n\t\t\t...(typeof block.mimeType === \"string\" ? { mimeType: block.mimeType } : {}),\n\t\t};\n\t}\n\treturn { type: \"text\", text: stringifyJson(block) };\n}\n\nfunction contentToErrorMessage(content: readonly McpMappedContentBlock[]): string {\n\tconst firstText = content.find((block): block is TextContent => block.type === \"text\");\n\treturn firstText?.text.trim() || \"MCP tool returned an error result.\";\n}\n\nfunction stripTopLevelSchemaKeys(schema: unknown): unknown {\n\tif (!isRecord(schema)) return schema;\n\tconst result = { ...schema };\n\tdelete result.$schema;\n\tdelete result.additionalProperties;\n\treturn result;\n}\n\nfunction resolveRefs(value: unknown, root: unknown, seenRefs: Set<string>, warnings: string[]): unknown {\n\tif (Array.isArray(value)) {\n\t\treturn value.map((entry) => resolveRefs(entry, root, seenRefs, warnings));\n\t}\n\tif (!isRecord(value)) return value;\n\n\tif (typeof value.$ref === \"string\") {\n\t\tconst ref = value.$ref;\n\t\tconst resolved = resolveLocalRef(root, ref);\n\t\tif (resolved === undefined || seenRefs.has(ref)) {\n\t\t\twarnings.push(`MCP schema contains unresolvable $ref '${ref}'; using permissive object schema.`);\n\t\t\treturn { ...PERMISSIVE_OBJECT_SCHEMA };\n\t\t}\n\t\tconst nextSeenRefs = new Set(seenRefs);\n\t\tnextSeenRefs.add(ref);\n\t\treturn resolveRefs(resolved, root, nextSeenRefs, warnings);\n\t}\n\n\tconst result: Record<string, unknown> = {};\n\tfor (const [key, child] of Object.entries(value)) {\n\t\tresult[key] = resolveRefs(child, root, seenRefs, warnings);\n\t}\n\treturn result;\n}\n\nfunction resolveLocalRef(root: unknown, ref: string): unknown {\n\tif (!ref.startsWith(\"#/\")) return undefined;\n\tlet current: unknown = root;\n\tfor (const part of ref\n\t\t.slice(2)\n\t\t.split(\"/\")\n\t\t.map((segment) => segment.replace(/~1/g, \"/\").replace(/~0/g, \"~\"))) {\n\t\tif (!isRecord(current) || !(part in current)) return undefined;\n\t\tcurrent = current[part];\n\t}\n\treturn current;\n}\n\nfunction stringifyJson(value: unknown): string {\n\tconst text = JSON.stringify(value);\n\treturn text ?? String(value);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasOwn(value: Record<string, unknown>, key: string): boolean {\n\treturn Object.getOwnPropertyDescriptor(value, key) !== undefined;\n}\n"]}
1
+ {"version":3,"file":"schema-compat.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/mcp/expose/schema-compat.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ImageContent, TextContent } from \"@earendil-works/pi-ai\";\nimport { type TSchema, Type } from \"typebox\";\nimport { buildMcpToolName, buildMcpToolNames, type McpToolNameEntry } from \"./naming.ts\";\nimport { collectAllPages, type McpListPage, type McpPaginationResult } from \"./pagination.ts\";\n\nexport type { McpListPage, McpPaginationResult, McpToolNameEntry };\nexport { buildMcpToolName, buildMcpToolNames, collectAllPages };\n\ninterface SchemaConversionResult {\n\tschema: TSchema;\n\twarnings: string[];\n}\n\ninterface OutputSchemaRetryResult {\n\tschema: Record<string, unknown>;\n\twarnings: string[];\n}\n\nexport type McpContentBlock =\n\t| { type: \"text\"; text?: unknown }\n\t| { type: \"image\"; data?: unknown; mimeType?: unknown }\n\t| { type: \"audio\"; data?: unknown; mimeType?: unknown }\n\t| { type: \"resource\"; resource?: unknown }\n\t| { type: \"resource_link\"; uri?: unknown; name?: unknown; description?: unknown; mimeType?: unknown }\n\t| Record<string, unknown>;\n\nexport type McpMappedContentBlock =\n\t| TextContent\n\t| ImageContent\n\t| { type: \"audio\"; data: string; mimeType: string }\n\t| { type: \"resource\"; resource: unknown }\n\t| { type: \"resource_link\"; uri: string; name?: string; description?: string; mimeType?: string };\n\nexport interface McpToolResultLike {\n\tcontent?: McpContentBlock[];\n\tstructuredContent?: unknown;\n\tisError?: boolean;\n}\n\nexport type McpMappedToolResult =\n\t| { ok: true; content: McpMappedContentBlock[] }\n\t| { ok: false; error: { message: string; content: McpMappedContentBlock[] } };\n\nconst PERMISSIVE_OBJECT_SCHEMA = { type: \"object\", properties: {} } as const;\n\nexport function convertJsonSchemaToTypeBox(schema: unknown): SchemaConversionResult {\n\tconst warnings: string[] = [];\n\tconst resolved = resolveRefs(stripTopLevelSchemaKeys(schema), schema, new Set<string>(), warnings);\n\tif (warnings.length > 0) {\n\t\treturn { schema: Type.Unsafe<unknown>({ ...PERMISSIVE_OBJECT_SCHEMA }), warnings };\n\t}\n\tif (!isRecord(resolved)) {\n\t\treturn {\n\t\t\tschema: Type.Unsafe<unknown>({ ...PERMISSIVE_OBJECT_SCHEMA }),\n\t\t\twarnings: [\"MCP schema is not an object; using permissive object schema.\"],\n\t\t};\n\t}\n\treturn { schema: Type.Unsafe<unknown>(resolved), warnings };\n}\n\nexport function prepareOutputSchemaRetry(schema: unknown): OutputSchemaRetryResult {\n\tconst warnings: string[] = [];\n\tconst record: Record<string, unknown> = isRecord(schema) ? { ...schema } : { ...PERMISSIVE_OBJECT_SCHEMA };\n\tif (hasOwn(record, \"$schema\")) {\n\t\tdelete record.$schema;\n\t\twarnings.push(\"Stripped top-level $schema from MCP outputSchema retry.\");\n\t}\n\tif (hasOwn(record, \"additionalProperties\")) {\n\t\tdelete record.additionalProperties;\n\t\twarnings.push(\"Stripped top-level additionalProperties from MCP outputSchema retry.\");\n\t}\n\treturn { schema: record, warnings };\n}\n\nexport function mapMcpToolResult(result: McpToolResultLike): McpMappedToolResult {\n\tconst content = mapMcpContent(result);\n\tif (result.isError === true) {\n\t\treturn { ok: false, error: { message: contentToErrorMessage(content), content } };\n\t}\n\treturn { ok: true, content };\n}\n\nfunction mapMcpContent(result: McpToolResultLike): McpMappedContentBlock[] {\n\tconst content: McpMappedContentBlock[] = [];\n\tfor (const block of result.content ?? []) {\n\t\tcontent.push(mapContentBlock(block));\n\t}\n\tif (result.structuredContent !== undefined) {\n\t\tcontent.push({ type: \"text\", text: stringifyJson(result.structuredContent) });\n\t}\n\tif (content.length === 0) {\n\t\tcontent.push({ type: \"text\", text: \"(empty result)\" });\n\t}\n\treturn content;\n}\n\nfunction mapContentBlock(block: McpContentBlock): McpMappedContentBlock {\n\tif (block.type === \"text\") {\n\t\treturn { type: \"text\", text: typeof block.text === \"string\" ? block.text : stringifyJson(block.text) };\n\t}\n\tif (block.type === \"image\" && typeof block.data === \"string\" && typeof block.mimeType === \"string\") {\n\t\treturn { type: \"image\", data: block.data, mimeType: block.mimeType };\n\t}\n\tif (block.type === \"audio\" && typeof block.data === \"string\" && typeof block.mimeType === \"string\") {\n\t\treturn { type: \"audio\", data: block.data, mimeType: block.mimeType };\n\t}\n\tif (block.type === \"resource\" && hasOwn(block, \"resource\")) {\n\t\treturn { type: \"resource\", resource: block.resource };\n\t}\n\tif (block.type === \"resource_link\" && typeof block.uri === \"string\") {\n\t\treturn {\n\t\t\ttype: \"resource_link\",\n\t\t\turi: block.uri,\n\t\t\t...(typeof block.name === \"string\" ? { name: block.name } : {}),\n\t\t\t...(typeof block.description === \"string\" ? { description: block.description } : {}),\n\t\t\t...(typeof block.mimeType === \"string\" ? { mimeType: block.mimeType } : {}),\n\t\t};\n\t}\n\treturn { type: \"text\", text: stringifyJson(block) };\n}\n\nfunction contentToErrorMessage(content: readonly McpMappedContentBlock[]): string {\n\tconst firstText = content.find((block): block is TextContent => block.type === \"text\");\n\treturn firstText?.text.trim() || \"MCP tool returned an error result.\";\n}\n\nfunction stripTopLevelSchemaKeys(schema: unknown): unknown {\n\tif (!isRecord(schema)) return schema;\n\tconst result = { ...schema };\n\tdelete result.$schema;\n\tdelete result.additionalProperties;\n\treturn result;\n}\n\nfunction resolveRefs(value: unknown, root: unknown, seenRefs: Set<string>, warnings: string[]): unknown {\n\tif (Array.isArray(value)) {\n\t\treturn value.map((entry) => resolveRefs(entry, root, seenRefs, warnings));\n\t}\n\tif (!isRecord(value)) return value;\n\n\tif (typeof value.$ref === \"string\") {\n\t\tconst ref = value.$ref;\n\t\tconst resolved = resolveLocalRef(root, ref);\n\t\tif (resolved === undefined || seenRefs.has(ref)) {\n\t\t\twarnings.push(`MCP schema contains unresolvable $ref '${ref}'; using permissive object schema.`);\n\t\t\treturn { ...PERMISSIVE_OBJECT_SCHEMA };\n\t\t}\n\t\tconst nextSeenRefs = new Set(seenRefs);\n\t\tnextSeenRefs.add(ref);\n\t\treturn resolveRefs(resolved, root, nextSeenRefs, warnings);\n\t}\n\n\tconst result: Record<string, unknown> = {};\n\tfor (const [key, child] of Object.entries(value)) {\n\t\tif (key === \"type\" && child === null) continue;\n\t\tresult[key] = resolveRefs(child, root, seenRefs, warnings);\n\t}\n\treturn result;\n}\n\nfunction resolveLocalRef(root: unknown, ref: string): unknown {\n\tif (!ref.startsWith(\"#/\")) return undefined;\n\tlet current: unknown = root;\n\tfor (const part of ref\n\t\t.slice(2)\n\t\t.split(\"/\")\n\t\t.map((segment) => segment.replace(/~1/g, \"/\").replace(/~0/g, \"~\"))) {\n\t\tif (!isRecord(current) || !(part in current)) return undefined;\n\t\tcurrent = current[part];\n\t}\n\treturn current;\n}\n\nfunction stringifyJson(value: unknown): string {\n\tconst text = JSON.stringify(value);\n\treturn text ?? String(value);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasOwn(value: Record<string, unknown>, key: string): boolean {\n\treturn Object.getOwnPropertyDescriptor(value, key) !== undefined;\n}\n"]}
@@ -33,6 +33,10 @@ export declare class McpService {
33
33
  getMcpPromptServers(): readonly import("./prompts.ts").McpPromptServer[];
34
34
  /** Connected servers that list resources (todo 39), for mention expansion. */
35
35
  getMcpResourceServers(): readonly McpResourceServer[];
36
+ /** Subscribe to completed catalog registrations. Consumers must inspect the
37
+ * resulting snapshot because tool, resource, and prompt catalogs can become
38
+ * available in different startup-race generations. */
39
+ onMcpRegistrationChanged(listener: () => void): () => void;
36
40
  /** Reveal skill-owned tools (todo 37): activation is effective the next
37
41
  * turn, exactly like an tool_search promotion. Unknown names are ignored. */
38
42
  activateSkillMcpTools(names: readonly string[]): void;