@code-yeongyu/senpi 2026.7.14-2 → 2026.7.14-3

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 (113) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/core/agent-session.js +1 -1
  3. package/dist/core/agent-session.js.map +1 -1
  4. package/dist/core/compaction/branch-summarization.d.ts +1 -1
  5. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  6. package/dist/core/compaction/branch-summarization.js.map +1 -1
  7. package/dist/core/model-registry.d.ts.map +1 -1
  8. package/dist/core/model-registry.js +17 -3
  9. package/dist/core/model-registry.js.map +1 -1
  10. package/dist/core/model-resolver.d.ts.map +1 -1
  11. package/dist/core/model-resolver.js +1 -0
  12. package/dist/core/model-resolver.js.map +1 -1
  13. package/dist/core/package-manager.d.ts.map +1 -1
  14. package/dist/core/package-manager.js +7 -2
  15. package/dist/core/package-manager.js.map +1 -1
  16. package/dist/core/provider-display-names.d.ts.map +1 -1
  17. package/dist/core/provider-display-names.js +1 -0
  18. package/dist/core/provider-display-names.js.map +1 -1
  19. package/dist/core/radius.d.ts +21 -0
  20. package/dist/core/radius.d.ts.map +1 -0
  21. package/dist/core/radius.js +30 -0
  22. package/dist/core/radius.js.map +1 -0
  23. package/dist/core/system-prompt.d.ts.map +1 -1
  24. package/dist/core/system-prompt.js +1 -11
  25. package/dist/core/system-prompt.js.map +1 -1
  26. package/dist/modes/interactive/interactive-mode.js +2 -2
  27. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  28. package/docs/custom-provider.md +2 -0
  29. package/docs/models.md +2 -0
  30. package/examples/AGENTS.md +34 -0
  31. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  32. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  33. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  34. package/examples/extensions/gondolin/package-lock.json +2 -2
  35. package/examples/extensions/gondolin/package.json +1 -1
  36. package/examples/extensions/sandbox/package-lock.json +2 -2
  37. package/examples/extensions/sandbox/package.json +1 -1
  38. package/examples/extensions/with-deps/package-lock.json +2 -2
  39. package/examples/extensions/with-deps/package.json +1 -1
  40. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +8 -0
  41. package/node_modules/@code-yeongyu/senpi-codemode/package.json +3 -3
  42. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  43. package/node_modules/@earendil-works/pi-ai/README.md +3 -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 +21 -19
  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/api/bedrock-converse-stream.d.ts.map +1 -1
  48. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js +10 -6
  49. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js.map +1 -1
  50. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts +1 -0
  51. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
  52. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +1 -1
  53. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
  54. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
  55. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +12 -3
  56. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  57. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
  58. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +23 -0
  59. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
  60. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts +1 -0
  61. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
  62. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +22 -6
  63. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  64. package/node_modules/@earendil-works/pi-ai/dist/api/pi-messages.d.ts +97 -0
  65. package/node_modules/@earendil-works/pi-ai/dist/api/pi-messages.d.ts.map +1 -0
  66. package/node_modules/@earendil-works/pi-ai/dist/api/pi-messages.js +307 -0
  67. package/node_modules/@earendil-works/pi-ai/dist/api/pi-messages.js.map +1 -0
  68. package/node_modules/@earendil-works/pi-ai/dist/api/pi-messages.lazy.d.ts +3 -0
  69. package/node_modules/@earendil-works/pi-ai/dist/api/pi-messages.lazy.d.ts.map +1 -0
  70. package/node_modules/@earendil-works/pi-ai/dist/api/pi-messages.lazy.js +3 -0
  71. package/node_modules/@earendil-works/pi-ai/dist/api/pi-messages.lazy.js.map +1 -0
  72. package/node_modules/@earendil-works/pi-ai/dist/compat.d.ts +2 -0
  73. package/node_modules/@earendil-works/pi-ai/dist/compat.d.ts.map +1 -1
  74. package/node_modules/@earendil-works/pi-ai/dist/compat.js +3 -0
  75. package/node_modules/@earendil-works/pi-ai/dist/compat.js.map +1 -1
  76. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.d.ts.map +1 -1
  77. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js +1 -0
  78. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js.map +1 -1
  79. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +1 -0
  80. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
  81. package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
  82. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +58 -6
  83. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
  84. package/node_modules/@earendil-works/pi-ai/dist/providers/all.d.ts +9 -5
  85. package/node_modules/@earendil-works/pi-ai/dist/providers/all.d.ts.map +1 -1
  86. package/node_modules/@earendil-works/pi-ai/dist/providers/all.js.map +1 -1
  87. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.d.ts +1 -6
  88. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.d.ts.map +1 -1
  89. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.js +1 -2
  90. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.js.map +1 -1
  91. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.d.ts +57 -0
  92. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.d.ts.map +1 -1
  93. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.js +19 -0
  94. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.js.map +1 -1
  95. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js +3 -3
  96. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js.map +1 -1
  97. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.js +2 -2
  98. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.js.map +1 -1
  99. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +10 -5
  100. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  101. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  102. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.d.ts +1 -0
  103. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.d.ts.map +1 -1
  104. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.js +9 -0
  105. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/index.js.map +1 -1
  106. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/radius.d.ts +39 -0
  107. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/radius.d.ts.map +1 -0
  108. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/radius.js +413 -0
  109. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/radius.js.map +1 -0
  110. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  111. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  112. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  113. package/package.json +6 -6
@@ -722,6 +722,8 @@ interface ProviderModelConfig {
722
722
  thinkingFormat?: "openai" | "openrouter" | "deepseek" | "together" | "zai" | "qwen" | "chat-template" | "qwen-chat-template" | "string-thinking" | "ant-ling";
723
723
  chatTemplateKwargs?: Record<string, string | number | boolean | null | { "$var": "thinking.enabled" | "thinking.effort"; omitWhenOff?: boolean }>;
724
724
  cacheControlFormat?: "anthropic";
725
+ sessionAffinityFormat?: "openai" | "openai-nosession" | "openrouter";
726
+ sendSessionAffinityHeaders?: boolean;
725
727
 
726
728
  // anthropic-messages
727
729
  supportsEagerToolInputStreaming?: boolean;
package/docs/models.md CHANGED
@@ -447,6 +447,8 @@ For providers with partial OpenAI compatibility, use the `compat` field.
447
447
  | `thinkingFormat` | Use `reasoning_effort`, `openrouter`, `deepseek`, `together`, `zai`, `qwen`, `chat-template`, or `qwen-chat-template` thinking parameters |
448
448
  | `chatTemplateKwargs` | `chat_template_kwargs` values for `thinkingFormat: "chat-template"`; use `{ "$var": "thinking.enabled" }` or `{ "$var": "thinking.effort" }` for pi-controlled thinking values |
449
449
  | `cacheControlFormat` | Use Anthropic-style `cache_control` markers on the system prompt, last tool definition, and last user/assistant text content. Currently only `anthropic` is supported. |
450
+ | `sendSessionAffinityHeaders` | For `openai-completions`, send session-affinity headers from the session id when caching is enabled. Default: `false`. |
451
+ | `sessionAffinityFormat` | For `openai-completions` and `openai-responses`, the session-affinity header format: `openai` sends `session_id`/`x-client-request-id` (completions also `x-session-affinity`), `openai-nosession` omits the underscore-containing `session_id` header, `openrouter` sends `x-session-id`. Does not affect the `prompt_cache_key` body param. Default: auto-detected. |
450
452
  | `supportsStrictMode` | Include the `strict` field in tool definitions |
451
453
  | `supportsLongCacheRetention` | Whether the provider accepts long cache retention when cache retention is `long`: `prompt_cache_retention: "24h"` for OpenAI prompt caching, or `cache_control.ttl: "1h"` when `cacheControlFormat` is `anthropic`. Default: `true`. |
452
454
  | `openRouterRouting` | OpenRouter provider routing preferences. This object is sent as-is in the `provider` field of the [OpenRouter API request](https://openrouter.ai/docs/guides/routing/provider-selection). |
@@ -0,0 +1,34 @@
1
+ # packages/coding-agent/examples
2
+
3
+ Runnable examples for the public Senpi SDK and extension API. Examples are documentation-quality code and must reflect shipped APIs, not private core internals. Unqualified paths below are relative to this directory; `packages/...` paths are repository-relative.
4
+
5
+ ## STRUCTURE
6
+
7
+ ```text
8
+ extensions/ Tools, commands, UI, providers, hooks, resources
9
+ extensions/*/ Multi-file examples and nested private workspaces
10
+ sdk/ Programmatic SDK usage
11
+ rpc-extension-ui.ts RPC-compatible extension UI example
12
+ ```
13
+
14
+ ## CONVENTIONS
15
+
16
+ - Import public package surfaces such as `@code-yeongyu/senpi` and `@earendil-works/pi-ai`; do not reach into `packages/coding-agent/src/core/` internals.
17
+ - Keep examples small enough to teach one pattern, while preserving real error, cleanup, cancellation, and persistence behavior where relevant.
18
+ - Extension factories have no top-level runtime side effects. Register work through the public `pi.*` API and lifecycle events.
19
+ - New interactive examples should use configurable keybindings and themed TUI helpers. Existing demos may keep fixed controls when the control scheme is part of the example. Direct terminal writes belong only in examples explicitly teaching a terminal protocol; ordinary SDK examples may use normal stdout.
20
+ - Tool string enums use the shared `StringEnum` helper for provider compatibility.
21
+ - Stateful examples persist reconstructable state in session entries or tool-result details so fork/resume behavior remains valid.
22
+ - Nested example packages are private workspaces with exact-pinned dependencies. Treat their manifests and lock impact as production dependency changes.
23
+
24
+ ## DOCUMENTATION CONTRACT
25
+
26
+ - Keep `extensions/README.md`, `packages/coding-agent/docs/extensions.md`, and `packages/coding-agent/docs/sdk.md` aligned with public API changes.
27
+ - New public extension capabilities should include a focused example when usage is not obvious from types alone.
28
+ - Do not present experimental or internal behavior as stable API.
29
+
30
+ ## VALIDATION
31
+
32
+ - Run the focused tests for the public API demonstrated by the example.
33
+ - Typecheck examples through root `npm run check`.
34
+ - Interactive examples require real CLI or visual QA when their behavior changes.
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pi-extension-custom-provider",
3
- "version": "0.80.6",
3
+ "version": "0.80.7",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pi-extension-custom-provider",
9
- "version": "0.80.6",
9
+ "version": "0.80.7",
10
10
  "dependencies": {
11
11
  "@anthropic-ai/sdk": "^0.52.0"
12
12
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-extension-custom-provider-anthropic",
3
3
  "private": true,
4
- "version": "0.80.6",
4
+ "version": "0.80.7",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-extension-custom-provider-gitlab-duo",
3
3
  "private": true,
4
- "version": "0.80.6",
4
+ "version": "0.80.7",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pi-extension-gondolin",
3
- "version": "0.80.6",
3
+ "version": "0.80.7",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pi-extension-gondolin",
9
- "version": "0.80.6",
9
+ "version": "0.80.7",
10
10
  "dependencies": {
11
11
  "@earendil-works/gondolin": "0.12.0"
12
12
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-extension-gondolin",
3
3
  "private": true,
4
- "version": "0.80.6",
4
+ "version": "0.80.7",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pi-extension-sandbox",
3
- "version": "1.10.6",
3
+ "version": "1.10.7",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pi-extension-sandbox",
9
- "version": "1.10.6",
9
+ "version": "1.10.7",
10
10
  "dependencies": {
11
11
  "@anthropic-ai/sandbox-runtime": "^0.0.26"
12
12
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-extension-sandbox",
3
3
  "private": true,
4
- "version": "1.10.6",
4
+ "version": "1.10.7",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pi-extension-with-deps",
3
- "version": "0.80.6",
3
+ "version": "0.80.7",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pi-extension-with-deps",
9
- "version": "0.80.6",
9
+ "version": "0.80.7",
10
10
  "dependencies": {
11
11
  "ms": "^2.1.3"
12
12
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-extension-with-deps",
3
3
  "private": true,
4
- "version": "0.80.6",
4
+ "version": "0.80.7",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [2026.7.14-3] - 2026-07-14
4
+
5
+ ### Added
6
+
7
+ ### Changed
8
+
9
+ ### Fixed
10
+
3
11
  ## [2026.7.14-2] - 2026-07-14
4
12
 
5
13
  ### Added
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/senpi-codemode",
3
- "version": "2026.7.14-2",
3
+ "version": "2026.7.14-3",
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": "7.29.7",
33
- "@earendil-works/pi-ai": "^2026.7.14-2",
33
+ "@earendil-works/pi-ai": "^2026.7.14-3",
34
34
  "typebox": "1.1.38"
35
35
  },
36
36
  "peerDependencies": {
37
37
  "@code-yeongyu/senpi": "*"
38
38
  },
39
39
  "devDependencies": {
40
- "@code-yeongyu/senpi": "2026.7.14-2"
40
+ "@code-yeongyu/senpi": "2026.7.14-3"
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.7.14-2",
4
+ "version": "2026.7.14-3",
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 clean && npm run build"
31
31
  },
32
32
  "dependencies": {
33
- "@earendil-works/pi-ai": "^2026.7.14-2",
33
+ "@earendil-works/pi-ai": "^2026.7.14-3",
34
34
  "ignore": "7.0.5",
35
35
  "typebox": "1.1.38",
36
36
  "yaml": "2.9.0"
@@ -1070,7 +1070,8 @@ interface OpenAICompletionsCompat {
1070
1070
  supportsReasoningEffort?: boolean; // Whether provider supports `reasoning_effort` (default: true)
1071
1071
  supportsUsageInStreaming?: boolean; // Whether provider supports `stream_options: { include_usage: true }` (default: true)
1072
1072
  supportsStrictMode?: boolean; // Whether provider supports `strict` in tool definitions (default: true)
1073
- sendSessionAffinityHeaders?: boolean; // Whether to send `session_id`, `x-client-request-id`, and `x-session-affinity` from `sessionId` when caching is enabled (default: false)
1073
+ sendSessionAffinityHeaders?: boolean; // Send session-affinity data from `sessionId` (default: false)
1074
+ sessionAffinityFormat?: 'openai' | 'openai-nosession' | 'openrouter'; // Format for session affinity: 'openai' uses `prompt_cache_key`, `session_id`, `x-client-request-id`, and `x-session-affinity`; 'openai-nosession' uses `prompt_cache_key`, `x-client-request-id`, and `x-session-affinity`; 'openrouter' uses `x-session-id` (default: auto-detected)
1074
1075
  maxTokensField?: 'max_completion_tokens' | 'max_tokens'; // Which field name to use (default: max_completion_tokens)
1075
1076
  requiresToolResultName?: boolean; // Whether tool results require the `name` field (default: false)
1076
1077
  requiresAssistantAfterToolResult?: boolean; // Whether tool results must be followed by an assistant message (default: false)
@@ -1085,7 +1086,7 @@ interface OpenAICompletionsCompat {
1085
1086
 
1086
1087
  interface OpenAIResponsesCompat {
1087
1088
  supportsDeveloperRole?: boolean; // Whether provider supports `developer` role vs `system` (default: true)
1088
- sendSessionIdHeader?: boolean; // Whether to send `session_id` from `sessionId` when caching is enabled (default: true)
1089
+ sessionAffinityFormat?: 'openai' | 'openai-nosession' | 'openrouter'; // Session-affinity header format: 'openai' sends `session_id` and `x-client-request-id`; 'openai-nosession' sends `x-client-request-id`; 'openrouter' sends `x-session-id`. Does not affect the `prompt_cache_key` body param (default: auto-detected)
1089
1090
  supportsLongCacheRetention?: boolean; // Whether provider supports `prompt_cache_retention: "24h"` (default: true)
1090
1091
  }
1091
1092
  ```
@@ -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,EAMb,MAAM,aAAa,CAAC;AAgKrB,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;AAE1E,MAAM,MAAM,wBAAwB,GAAG,YAAY,GAAG,SAAS,CAAC;AAuDhE,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;AAghBD,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,oBAAoB,EAAE,gBAAgB,CAoTzE,CAAC;AAoEF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,oBAAoB,EAAE,mBAAmB,CA2ClF,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,EAMb,MAAM,aAAa,CAAC;AAgKrB,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;AAE1E,MAAM,MAAM,wBAAwB,GAAG,YAAY,GAAG,SAAS,CAAC;AAuDhE,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;AAghBD,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,oBAAoB,EAAE,gBAAgB,CAsTzE,CAAC;AAoEF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,oBAAoB,EAAE,mBAAmB,CA2ClF,CAAC"}
@@ -819,25 +819,27 @@ export const stream = (model, context, options) => {
819
819
  }
820
820
  // Only update usage fields if present (not null).
821
821
  // Preserves input_tokens from message_start when proxies omit it in message_delta.
822
- if (event.usage.input_tokens != null) {
823
- output.usage.input = event.usage.input_tokens;
824
- }
825
- if (event.usage.output_tokens != null) {
826
- output.usage.output = event.usage.output_tokens;
827
- }
828
- if (event.usage.cache_read_input_tokens != null) {
829
- output.usage.cacheRead = event.usage.cache_read_input_tokens;
830
- }
831
- if (event.usage.cache_creation_input_tokens != null) {
832
- output.usage.cacheWrite = event.usage.cache_creation_input_tokens;
833
- }
834
- // Anthropic reports reasoning tokens in `output_tokens_details.thinking_tokens` on the
835
- // final message_delta usage (a subset of output_tokens). SDK 0.91.1 omits the field from
836
- // its Usage type, so read it through a narrow cast. Verified against the live API.
837
- const thinkingTokens = event.usage
838
- .output_tokens_details?.thinking_tokens;
839
- if (thinkingTokens != null) {
840
- output.usage.reasoning = thinkingTokens;
822
+ if (event.usage) {
823
+ if (event.usage.input_tokens != null) {
824
+ output.usage.input = event.usage.input_tokens;
825
+ }
826
+ if (event.usage.output_tokens != null) {
827
+ output.usage.output = event.usage.output_tokens;
828
+ }
829
+ if (event.usage.cache_read_input_tokens != null) {
830
+ output.usage.cacheRead = event.usage.cache_read_input_tokens;
831
+ }
832
+ if (event.usage.cache_creation_input_tokens != null) {
833
+ output.usage.cacheWrite = event.usage.cache_creation_input_tokens;
834
+ }
835
+ // Anthropic reports reasoning tokens in `output_tokens_details.thinking_tokens` on the
836
+ // final message_delta usage (a subset of output_tokens). SDK 0.91.1 omits the field from
837
+ // its Usage type, so read it through a narrow cast. Verified against the live API.
838
+ const thinkingTokens = event.usage
839
+ .output_tokens_details?.thinking_tokens;
840
+ if (thinkingTokens != null) {
841
+ output.usage.reasoning = thinkingTokens;
842
+ }
841
843
  }
842
844
  // Anthropic doesn't provide total_tokens, compute from components
843
845
  output.usage.totalTokens =