@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.
- package/CHANGELOG.md +80 -0
- package/dist/core/agent-session.d.ts +0 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +31 -35
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/prompt-directive-dedupe.d.ts +26 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/prompt-directive-dedupe.d.ts.map +1 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/prompt-directive-dedupe.js +98 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/prompt-directive-dedupe.js.map +1 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.d.ts +4 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.js +2 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js +11 -2
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/stream.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/stream.js +3 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/stream.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/expose/schema-compat.js +2 -0
- package/dist/core/extensions/builtin/mcp/expose/schema-compat.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/service.d.ts +4 -0
- package/dist/core/extensions/builtin/mcp/service.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/service.js +11 -0
- package/dist/core/extensions/builtin/mcp/service.js.map +1 -1
- package/dist/core/extensions/builtin/rules/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/rules/index.js +3 -2
- package/dist/core/extensions/builtin/rules/index.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-notify.js +14 -6
- package/dist/core/extensions/builtin/terminal/monitor-notify.js.map +1 -1
- package/dist/core/provider-timeout-retry.d.ts +21 -0
- package/dist/core/provider-timeout-retry.d.ts.map +1 -0
- package/dist/core/provider-timeout-retry.js +41 -0
- package/dist/core/provider-timeout-retry.js.map +1 -0
- package/dist/modes/interactive/components/continuity-notice.d.ts.map +1 -1
- package/dist/modes/interactive/components/continuity-notice.js +29 -2
- package/dist/modes/interactive/components/continuity-notice.js.map +1 -1
- package/docs/providers.md +10 -0
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +24 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +4 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/groq.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +15 -2
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/tool-schema-compat.d.ts +8 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/tool-schema-compat.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/tool-schema-compat.js +71 -17
- package/node_modules/@earendil-works/pi-ai/dist/utils/tool-schema-compat.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +1 -1
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +6 -6
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AgentContinuationOptions } from "@earendil-works/pi-agent-core";
|
|
2
|
+
import type { AssistantMessage } from "@earendil-works/pi-ai/compat";
|
|
3
|
+
export interface ProviderTimeoutRetryPlan {
|
|
4
|
+
options: AgentContinuationOptions;
|
|
5
|
+
watchdogTimeoutMs: number | undefined;
|
|
6
|
+
}
|
|
7
|
+
export interface ProviderTimeoutRetryPlanInput {
|
|
8
|
+
message: AssistantMessage;
|
|
9
|
+
streamRetryTimeoutMs: number | undefined;
|
|
10
|
+
timeoutMs: number | undefined;
|
|
11
|
+
streamStartTimeoutMs: number | undefined;
|
|
12
|
+
}
|
|
13
|
+
export interface BoundedRetryContinuation {
|
|
14
|
+
continueRun(): Promise<void>;
|
|
15
|
+
getActiveSignal(): AbortSignal | undefined;
|
|
16
|
+
abortActive(): void;
|
|
17
|
+
timeoutMs: number | undefined;
|
|
18
|
+
}
|
|
19
|
+
export declare function createProviderTimeoutRetryPlan({ message, streamRetryTimeoutMs, timeoutMs, streamStartTimeoutMs, }: ProviderTimeoutRetryPlanInput): ProviderTimeoutRetryPlan;
|
|
20
|
+
export declare function runBoundedRetryContinuation({ continueRun, getActiveSignal, abortActive, timeoutMs, }: BoundedRetryContinuation): Promise<void>;
|
|
21
|
+
//# sourceMappingURL=provider-timeout-retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-timeout-retry.d.ts","sourceRoot":"","sources":["../../src/core/provider-timeout-retry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAGrE,MAAM,WAAW,wBAAwB;IACxC,OAAO,EAAE,wBAAwB,CAAC;IAClC,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,WAAW,6BAA6B;IAC7C,OAAO,EAAE,gBAAgB,CAAC;IAC1B,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC;AAED,MAAM,WAAW,wBAAwB;IACxC,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,eAAe,IAAI,WAAW,GAAG,SAAS,CAAC;IAC3C,WAAW,IAAI,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B;AAED,wBAAgB,8BAA8B,CAAC,EAC9C,OAAO,EACP,oBAAoB,EACpB,SAAS,EACT,oBAAoB,GACpB,EAAE,6BAA6B,GAAG,wBAAwB,CAoB1D;AAED,wBAAsB,2BAA2B,CAAC,EACjD,WAAW,EACX,eAAe,EACf,WAAW,EACX,SAAS,GACT,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkB1C"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { isProviderTimeoutError } from "@earendil-works/pi-ai/compat";
|
|
2
|
+
export function createProviderTimeoutRetryPlan({ message, streamRetryTimeoutMs, timeoutMs, streamStartTimeoutMs, }) {
|
|
3
|
+
if (!isProviderTimeoutError(message)) {
|
|
4
|
+
return { options: {}, watchdogTimeoutMs: undefined };
|
|
5
|
+
}
|
|
6
|
+
const capEnabledBound = (configuredMs) => {
|
|
7
|
+
if (streamRetryTimeoutMs === undefined || configuredMs === undefined)
|
|
8
|
+
return undefined;
|
|
9
|
+
return Math.min(configuredMs, streamRetryTimeoutMs);
|
|
10
|
+
};
|
|
11
|
+
const boundedTimeoutMs = capEnabledBound(timeoutMs);
|
|
12
|
+
const boundedStreamStartTimeoutMs = capEnabledBound(streamStartTimeoutMs);
|
|
13
|
+
return {
|
|
14
|
+
options: {
|
|
15
|
+
deferQueuedMessages: true,
|
|
16
|
+
...(boundedTimeoutMs === undefined ? {} : { timeoutMs: boundedTimeoutMs }),
|
|
17
|
+
...(boundedStreamStartTimeoutMs === undefined ? {} : { streamStartTimeoutMs: boundedStreamStartTimeoutMs }),
|
|
18
|
+
},
|
|
19
|
+
watchdogTimeoutMs: boundedTimeoutMs === undefined && boundedStreamStartTimeoutMs === undefined ? streamRetryTimeoutMs : undefined,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export async function runBoundedRetryContinuation({ continueRun, getActiveSignal, abortActive, timeoutMs, }) {
|
|
23
|
+
const continuation = continueRun();
|
|
24
|
+
const ownedSignal = getActiveSignal();
|
|
25
|
+
if (timeoutMs === undefined || ownedSignal === undefined) {
|
|
26
|
+
await continuation;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const timer = setTimeout(() => {
|
|
30
|
+
if (getActiveSignal() === ownedSignal) {
|
|
31
|
+
abortActive();
|
|
32
|
+
}
|
|
33
|
+
}, timeoutMs);
|
|
34
|
+
try {
|
|
35
|
+
await continuation;
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
clearTimeout(timer);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=provider-timeout-retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-timeout-retry.js","sourceRoot":"","sources":["../../src/core/provider-timeout-retry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAqBtE,MAAM,UAAU,8BAA8B,CAAC,EAC9C,OAAO,EACP,oBAAoB,EACpB,SAAS,EACT,oBAAoB,GACW;IAC/B,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,iBAAiB,EAAE,SAAS,EAAE,CAAC;IACtD,CAAC;IAED,MAAM,eAAe,GAAG,CAAC,YAAgC,EAAsB,EAAE;QAChF,IAAI,oBAAoB,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QACvF,OAAO,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,oBAAoB,CAAC,CAAC;IACrD,CAAC,CAAC;IACF,MAAM,gBAAgB,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,2BAA2B,GAAG,eAAe,CAAC,oBAAoB,CAAC,CAAC;IAC1E,OAAO;QACN,OAAO,EAAE;YACR,mBAAmB,EAAE,IAAI;YACzB,GAAG,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAC;YAC1E,GAAG,CAAC,2BAA2B,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,CAAC;SAC3G;QACD,iBAAiB,EAChB,gBAAgB,KAAK,SAAS,IAAI,2BAA2B,KAAK,SAAS,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,SAAS;KAC/G,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,EACjD,WAAW,EACX,eAAe,EACf,WAAW,EACX,SAAS,GACiB;IAC1B,MAAM,YAAY,GAAG,WAAW,EAAE,CAAC;IACnC,MAAM,WAAW,GAAG,eAAe,EAAE,CAAC;IACtC,IAAI,SAAS,KAAK,SAAS,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC1D,MAAM,YAAY,CAAC;QACnB,OAAO;IACR,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;QAC7B,IAAI,eAAe,EAAE,KAAK,WAAW,EAAE,CAAC;YACvC,WAAW,EAAE,CAAC;QACf,CAAC;IACF,CAAC,EAAE,SAAS,CAAC,CAAC;IACd,IAAI,CAAC;QACJ,MAAM,YAAY,CAAC;IACpB,CAAC;YAAS,CAAC;QACV,YAAY,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;AACF,CAAC","sourcesContent":["import type { AgentContinuationOptions } from \"@earendil-works/pi-agent-core\";\nimport type { AssistantMessage } from \"@earendil-works/pi-ai/compat\";\nimport { isProviderTimeoutError } from \"@earendil-works/pi-ai/compat\";\n\nexport interface ProviderTimeoutRetryPlan {\n\toptions: AgentContinuationOptions;\n\twatchdogTimeoutMs: number | undefined;\n}\n\nexport interface ProviderTimeoutRetryPlanInput {\n\tmessage: AssistantMessage;\n\tstreamRetryTimeoutMs: number | undefined;\n\ttimeoutMs: number | undefined;\n\tstreamStartTimeoutMs: number | undefined;\n}\n\nexport interface BoundedRetryContinuation {\n\tcontinueRun(): Promise<void>;\n\tgetActiveSignal(): AbortSignal | undefined;\n\tabortActive(): void;\n\ttimeoutMs: number | undefined;\n}\n\nexport function createProviderTimeoutRetryPlan({\n\tmessage,\n\tstreamRetryTimeoutMs,\n\ttimeoutMs,\n\tstreamStartTimeoutMs,\n}: ProviderTimeoutRetryPlanInput): ProviderTimeoutRetryPlan {\n\tif (!isProviderTimeoutError(message)) {\n\t\treturn { options: {}, watchdogTimeoutMs: undefined };\n\t}\n\n\tconst capEnabledBound = (configuredMs: number | undefined): number | undefined => {\n\t\tif (streamRetryTimeoutMs === undefined || configuredMs === undefined) return undefined;\n\t\treturn Math.min(configuredMs, streamRetryTimeoutMs);\n\t};\n\tconst boundedTimeoutMs = capEnabledBound(timeoutMs);\n\tconst boundedStreamStartTimeoutMs = capEnabledBound(streamStartTimeoutMs);\n\treturn {\n\t\toptions: {\n\t\t\tdeferQueuedMessages: true,\n\t\t\t...(boundedTimeoutMs === undefined ? {} : { timeoutMs: boundedTimeoutMs }),\n\t\t\t...(boundedStreamStartTimeoutMs === undefined ? {} : { streamStartTimeoutMs: boundedStreamStartTimeoutMs }),\n\t\t},\n\t\twatchdogTimeoutMs:\n\t\t\tboundedTimeoutMs === undefined && boundedStreamStartTimeoutMs === undefined ? streamRetryTimeoutMs : undefined,\n\t};\n}\n\nexport async function runBoundedRetryContinuation({\n\tcontinueRun,\n\tgetActiveSignal,\n\tabortActive,\n\ttimeoutMs,\n}: BoundedRetryContinuation): Promise<void> {\n\tconst continuation = continueRun();\n\tconst ownedSignal = getActiveSignal();\n\tif (timeoutMs === undefined || ownedSignal === undefined) {\n\t\tawait continuation;\n\t\treturn;\n\t}\n\n\tconst timer = setTimeout(() => {\n\t\tif (getActiveSignal() === ownedSignal) {\n\t\t\tabortActive();\n\t\t}\n\t}, timeoutMs);\n\ttry {\n\t\tawait continuation;\n\t} finally {\n\t\tclearTimeout(timer);\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"continuity-notice.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/continuity-notice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAA8B,MAAM,uBAAuB,CAAC;AAG1F,eAAO,MAAM,0BAA0B,wCAAwC,CAAC;AAChF,eAAO,MAAM,+BAA+B,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"continuity-notice.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/continuity-notice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAA8B,MAAM,uBAAuB,CAAC;AAG1F,eAAO,MAAM,0BAA0B,wCAAwC,CAAC;AAChF,eAAO,MAAM,+BAA+B,qCAAqC,CAAC;AAoDlF;;;;GAIG;AACH,qBAAa,uBAAuB;IACnC,OAAO,CAAC,gBAAgB,CAAS;IAEjC;;;;;OAKG;IACH,KAAK,IAAI,IAAI,CAEZ;IAED,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,GAAG,SAAS,CAcvD;IAED,OAAO,CAAC,MAAM;CAGd"}
|
|
@@ -14,7 +14,33 @@ function continuityDetails(diagnostic) {
|
|
|
14
14
|
const details = diagnostic.details;
|
|
15
15
|
if (!details || typeof details.kind !== "string")
|
|
16
16
|
return undefined;
|
|
17
|
-
return {
|
|
17
|
+
return {
|
|
18
|
+
kind: details.kind,
|
|
19
|
+
...(typeof details.reason === "string" ? { reason: details.reason } : {}),
|
|
20
|
+
...(typeof details.payloadBytes === "number" ? { payloadBytes: details.payloadBytes } : {}),
|
|
21
|
+
...(typeof details.collapsedDirectives === "number" ? { collapsedDirectives: details.collapsedDirectives } : {}),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** Renders a byte count the way the transcript shows sizes: one decimal, KB/MB. */
|
|
25
|
+
function formatBytes(bytes) {
|
|
26
|
+
if (bytes < 1024)
|
|
27
|
+
return `${bytes}B`;
|
|
28
|
+
if (bytes < 1024 * 1024)
|
|
29
|
+
return `${(bytes / 1024).toFixed(1)}KB`;
|
|
30
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Appends the re-send cost to a degradation notice so the token bill is visible
|
|
34
|
+
* at the moment it is paid: how much was resent, and how many duplicate
|
|
35
|
+
* ultrawork directive blocks were collapsed out of it.
|
|
36
|
+
*/
|
|
37
|
+
function payloadSuffix(details) {
|
|
38
|
+
if (details.payloadBytes === undefined)
|
|
39
|
+
return "";
|
|
40
|
+
const collapsed = details.collapsedDirectives !== undefined && details.collapsedDirectives > 0
|
|
41
|
+
? `, ${details.collapsedDirectives} duplicate ultrawork blocks collapsed`
|
|
42
|
+
: "";
|
|
43
|
+
return ` - sent ${formatBytes(details.payloadBytes)}${collapsed}`;
|
|
18
44
|
}
|
|
19
45
|
/**
|
|
20
46
|
* Builds the muted single-line transcript notice for a completed assistant
|
|
@@ -47,7 +73,8 @@ export class ContinuityNoticeTracker {
|
|
|
47
73
|
this.renderedDisabled = true;
|
|
48
74
|
}
|
|
49
75
|
const label = KIND_LABELS[details.kind] ?? "Session continuity degraded";
|
|
50
|
-
|
|
76
|
+
const base = details.reason ? `${label} (${details.reason})` : label;
|
|
77
|
+
return this.format(`${base}${payloadSuffix(details)}`);
|
|
51
78
|
}
|
|
52
79
|
return undefined;
|
|
53
80
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"continuity-notice.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/continuity-notice.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C,MAAM,CAAC,MAAM,0BAA0B,GAAG,qCAAqC,CAAC;AAChF,MAAM,CAAC,MAAM,+BAA+B,GAAG,kCAAkC,CAAC;AAElF,8FAA8F;AAC9F,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;AAE3D,MAAM,WAAW,GAAqC;IACrD,OAAO,EAAE,wDAAwD;IACjE,QAAQ,EAAE,sFAAsF;CAChG,CAAC;AAEF,MAAM,qBAAqB,GAAG,uEAAuE,CAAC;
|
|
1
|
+
{"version":3,"file":"continuity-notice.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/continuity-notice.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AssistantMessage, AssistantMessageDiagnostic } from \"@earendil-works/pi-ai\";\nimport { theme } from \"../theme/theme.ts\";\n\nexport const CONTINUITY_DIAGNOSTIC_TYPE = \"claude_sdk_oauth_session_continuity\";\nexport const RESUME_FALLBACK_DIAGNOSTIC_TYPE = \"claude_sdk_oauth_resume_fallback\";\n\n/** Only degradation kinds reach the transcript; healthy kinds stay in session.log and RPC. */\nconst DEGRADATION_KINDS = new Set([\"flatten\", \"disabled\"]);\n\nconst KIND_LABELS: Readonly<Record<string, string>> = {\n\tflatten: \"Session continuity lost - resent the full conversation\",\n\tdisabled: \"Session continuity disabled (resumeMode: off) - resending the conversation each turn\",\n};\n\nconst RESUME_FALLBACK_LABEL = \"Session continuity lost - resume failed, resent the full conversation\";\n\ntype ContinuityDetails = {\n\tkind: string;\n\treason?: string;\n\tpayloadBytes?: number;\n\tcollapsedDirectives?: number;\n};\n\nfunction continuityDetails(diagnostic: AssistantMessageDiagnostic): ContinuityDetails | undefined {\n\tif (diagnostic.type !== CONTINUITY_DIAGNOSTIC_TYPE) return undefined;\n\tconst details = diagnostic.details;\n\tif (!details || typeof details.kind !== \"string\") return undefined;\n\treturn {\n\t\tkind: details.kind,\n\t\t...(typeof details.reason === \"string\" ? { reason: details.reason } : {}),\n\t\t...(typeof details.payloadBytes === \"number\" ? { payloadBytes: details.payloadBytes } : {}),\n\t\t...(typeof details.collapsedDirectives === \"number\" ? { collapsedDirectives: details.collapsedDirectives } : {}),\n\t};\n}\n\n/** Renders a byte count the way the transcript shows sizes: one decimal, KB/MB. */\nfunction formatBytes(bytes: number): string {\n\tif (bytes < 1024) return `${bytes}B`;\n\tif (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;\n\treturn `${(bytes / (1024 * 1024)).toFixed(1)}MB`;\n}\n\n/**\n * Appends the re-send cost to a degradation notice so the token bill is visible\n * at the moment it is paid: how much was resent, and how many duplicate\n * ultrawork directive blocks were collapsed out of it.\n */\nfunction payloadSuffix(details: ContinuityDetails): string {\n\tif (details.payloadBytes === undefined) return \"\";\n\tconst collapsed =\n\t\tdetails.collapsedDirectives !== undefined && details.collapsedDirectives > 0\n\t\t\t? `, ${details.collapsedDirectives} duplicate ultrawork blocks collapsed`\n\t\t\t: \"\";\n\treturn ` - sent ${formatBytes(details.payloadBytes)}${collapsed}`;\n}\n\n/**\n * Builds the muted single-line transcript notice for a completed assistant\n * message. `disabled` renders once per session so the escape hatch does not nag;\n * healthy kinds render nothing at all.\n */\nexport class ContinuityNoticeTracker {\n\tprivate renderedDisabled = false;\n\n\t/**\n\t * Clear the suppression state. Called when the transcript is rebuilt\n\t * (initial load, post-compaction rebuild, session switch): the rebuilt\n\t * transcript re-derives notices from persisted messages, so the first\n\t * disabled notice must be allowed to render again.\n\t */\n\treset(): void {\n\t\tthis.renderedDisabled = false;\n\t}\n\n\tnoticeFor(message: AssistantMessage): string | undefined {\n\t\tfor (const diagnostic of message.diagnostics ?? []) {\n\t\t\tif (diagnostic.type === RESUME_FALLBACK_DIAGNOSTIC_TYPE) return this.format(RESUME_FALLBACK_LABEL);\n\t\t\tconst details = continuityDetails(diagnostic);\n\t\t\tif (!details || !DEGRADATION_KINDS.has(details.kind)) continue;\n\t\t\tif (details.kind === \"disabled\") {\n\t\t\t\tif (this.renderedDisabled) continue;\n\t\t\t\tthis.renderedDisabled = true;\n\t\t\t}\n\t\t\tconst label = KIND_LABELS[details.kind] ?? \"Session continuity degraded\";\n\t\t\tconst base = details.reason ? `${label} (${details.reason})` : label;\n\t\t\treturn this.format(`${base}${payloadSuffix(details)}`);\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate format(text: string): string {\n\t\treturn theme.fg(\"muted\", text);\n\t}\n}\n"]}
|
package/docs/providers.md
CHANGED
|
@@ -81,6 +81,16 @@ To confirm from the SDK side, list the transcript files Claude Code keeps per pr
|
|
|
81
81
|
ls -lt ~/.claude/projects/*/ | head
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
+
### Diagnosing Claude OAuth token consumption
|
|
85
|
+
|
|
86
|
+
If your Claude Pro/Max subscription usage through `claude-sdk-oauth` feels unexpectedly high, check these in order:
|
|
87
|
+
|
|
88
|
+
1. **Upgrade to v2026.8.3 or later.** Resume-first session continuity (#634-637) landed on 2026-08-03. On older builds, every turn after a divergence (compaction, abort, model switch, restart, failover) re-sends the entire conversation, which is the dominant token-burn mechanism.
|
|
89
|
+
2. **Check which lane you are on.** The `ambient` lane (default) inherits the environment. `oauth-slots` and `config-dir` are managed lanes set via `SENPI_CLAUDE_SDK_OAUTH_TOKEN_INJECTION`. The `config-dir` lane keeps each account's credentials in its own `CLAUDE_CONFIG_DIR`; no official SDK API moves a transcript across roots, so account failover on that lane always flattens (re-sends the full history) — this is a declared residual, not a bug.
|
|
90
|
+
3. **Read the continuity observations.** Tail the session log and filter for `flatten` — each `flatten` line means the lane re-sent the whole conversation and lost prompt-cache hits. A healthy conversation shows one `bootstrap` followed by `delta` lines. Common flatten reasons: `transcript_missing`, `registry_miss`, `resume_initialization_failed`, `cross_root_unsupported` (config-dir only).
|
|
91
|
+
4. **Prompt-cache retention.** On the direct Anthropic API path (`anthropic` provider with an OAuth token), cache retention defaults to `long` with a 1-hour TTL on the native endpoint. Set `PI_CACHE_RETENTION=long` to ensure 1h caching. The SDK OAuth lane manages its own caching internally and senpi cannot add `cache_control` breakpoints to it.
|
|
92
|
+
5. **Directive-block deduplication.** As of v2026.8.4, the flatten serialization collapses repeated `<ultrawork-mode>` directive blocks to a single copy, preventing the issue-#494 scenario where duplicated ~17KB directive blocks consumed up to 73% of the re-sent prompt. The continuity observation reports how many were collapsed and the payload size.
|
|
93
|
+
|
|
84
94
|
### GitHub Copilot
|
|
85
95
|
|
|
86
96
|
- Press Enter for github.com, or enter your GitHub Enterprise Server domain
|
|
@@ -12,6 +12,30 @@
|
|
|
12
12
|
|
|
13
13
|
### Removed
|
|
14
14
|
|
|
15
|
+
## [2026.8.5] - 2026-08-05
|
|
16
|
+
|
|
17
|
+
### Breaking Changes
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
### Removed
|
|
26
|
+
|
|
27
|
+
## [2026.8.4-2] - 2026-08-04
|
|
28
|
+
|
|
29
|
+
### Breaking Changes
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
|
|
37
|
+
### Removed
|
|
38
|
+
|
|
15
39
|
## [2026.8.4] - 2026-08-04
|
|
16
40
|
|
|
17
41
|
### Breaking Changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-yeongyu/senpi-codemode",
|
|
3
|
-
"version": "2026.8.
|
|
3
|
+
"version": "2026.8.5",
|
|
4
4
|
"description": "Source-only senpi extension package for codemode evaluation tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -30,14 +30,14 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@babel/parser": "8.0.4",
|
|
33
|
-
"@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.8.
|
|
33
|
+
"@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.8.5",
|
|
34
34
|
"typebox": "1.3.8"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@code-yeongyu/senpi": "2026.8.
|
|
37
|
+
"@code-yeongyu/senpi": "2026.8.5"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@code-yeongyu/senpi": "2026.8.
|
|
40
|
+
"@code-yeongyu/senpi": "2026.8.5"
|
|
41
41
|
},
|
|
42
42
|
"keywords": [
|
|
43
43
|
"senpi",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@earendil-works/pi-agent-core",
|
|
3
3
|
"private": true,
|
|
4
|
-
"version": "2026.8.
|
|
4
|
+
"version": "2026.8.5",
|
|
5
5
|
"description": "General-purpose agent with transport abstraction, state management, and attachment support",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"prepublishOnly": "npm run build"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.8.
|
|
33
|
+
"@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.8.5",
|
|
34
34
|
"diff": "9.0.0",
|
|
35
35
|
"ignore": "7.0.6",
|
|
36
36
|
"typebox": "1.3.8",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic-messages.d.ts","sourceRoot":"","sources":["../../src/api/anthropic-messages.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAU1C,OAAO,KAAK,EAWX,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAOb,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"anthropic-messages.d.ts","sourceRoot":"","sources":["../../src/api/anthropic-messages.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAU1C,OAAO,KAAK,EAWX,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAOb,MAAM,aAAa,CAAC;AAkCrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AA6JlE,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;AAE1E,MAAM,MAAM,wBAAwB,GAAG,YAAY,GAAG,SAAS,CAAC;AAoEhE,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACtD;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB;;;;;;;;;;;OAWG;IACH,eAAe,CAAC,EAAE,wBAAwB,CAAC;IAC3C;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;CACnB;AA4zBD,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,oBAAoB,EAAE,gBAAgB,CA6ZzE,CAAC;AA0FF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,oBAAoB,EAAE,mBAAmB,CA2ClF,CAAC"}
|
|
@@ -14,6 +14,7 @@ import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
|
|
|
14
14
|
import { applyServerFallbackAbort, parseServerFallbackReceipt, parseStickyFallbackReceipt, } from "../utils/server-fallback-receipt.js";
|
|
15
15
|
import { normalizeToolCallId } from "../utils/tool-call-id.js";
|
|
16
16
|
import { isForcedToolChoiceUnsupportedError, omitToolChoiceParam } from "../utils/tool-choice-fallback.js";
|
|
17
|
+
import { resolveRootObjectSchema } from "../utils/tool-schema-compat.js";
|
|
17
18
|
import { demotedToolCallText, demotedToolResultText } from "../utils/unavailable-tool-text.js";
|
|
18
19
|
import { sanitizeAnthropicToolPairs } from "./anthropic-tool-pairs.js";
|
|
19
20
|
import { resolveCloudflareBaseUrl } from "./cloudflare.js";
|
|
@@ -1831,7 +1832,9 @@ function convertTools(tools, isOAuthToken, supportsEagerToolInputStreaming, supp
|
|
|
1831
1832
|
return [];
|
|
1832
1833
|
return tools.map((tool, index) => {
|
|
1833
1834
|
const strict = resolveJsonSchemaStrictSampling(tool, supportsStrictTools);
|
|
1834
|
-
|
|
1835
|
+
// A root union carries no top-level properties, so reading them directly
|
|
1836
|
+
// would advertise the tool to the model as taking no arguments at all.
|
|
1837
|
+
const schema = resolveRootObjectSchema(tool.parameters);
|
|
1835
1838
|
const legacyInputSchema = {
|
|
1836
1839
|
type: "object",
|
|
1837
1840
|
properties: schema.properties ?? {},
|