@bitkyc08/opencodex 2.52.0 → 2.53.0-preview.20260913

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 (236) hide show
  1. package/gui/dist/assets/index-BBOZWGB6.css +1 -0
  2. package/gui/dist/assets/index-D7ynYo2K.js +128 -0
  3. package/gui/dist/index.html +2 -2
  4. package/native/remote-workspace-helper/Cargo.lock +130 -0
  5. package/native/remote-workspace-helper/Cargo.toml +24 -0
  6. package/native/remote-workspace-helper/src/main.rs +49 -0
  7. package/native/remote-workspace-helper/src/protocol.rs +246 -0
  8. package/native/remote-workspace-helper/src/sandbox/macos.rs +19 -0
  9. package/native/remote-workspace-helper/src/sandbox/mod.rs +77 -0
  10. package/native/remote-workspace-helper/src/sandbox/windows.rs +15 -0
  11. package/package.json +6 -1
  12. package/src/adapters/anthropic-image-normalize.ts +30 -2
  13. package/src/adapters/anthropic.ts +1 -1
  14. package/src/adapters/base.ts +8 -2
  15. package/src/adapters/cursor/cursor-errors.ts +12 -0
  16. package/src/adapters/cursor/thread-continuity.ts +93 -0
  17. package/src/adapters/cursor.ts +104 -73
  18. package/src/adapters/devin/cloud-direct/chat.ts +312 -23
  19. package/src/adapters/devin/cloud-direct/metadata.ts +31 -2
  20. package/src/adapters/devin/live-models.ts +70 -3
  21. package/src/adapters/devin.ts +281 -21
  22. package/src/adapters/google-wire-compiler.ts +14 -6
  23. package/src/adapters/google.ts +22 -8
  24. package/src/adapters/kiro/adapter.ts +316 -0
  25. package/src/adapters/kiro/conversation.ts +136 -0
  26. package/src/adapters/kiro/payload.ts +432 -0
  27. package/src/adapters/kiro/reasoning.ts +56 -0
  28. package/src/adapters/kiro/stream.ts +1153 -0
  29. package/src/adapters/kiro/usage.ts +223 -0
  30. package/src/adapters/kiro/wire.ts +76 -0
  31. package/src/adapters/kiro.ts +8 -2319
  32. package/src/adapters/mimo-free.ts +1 -1
  33. package/src/adapters/openai-chat-images.ts +101 -0
  34. package/src/adapters/openai-chat.ts +201 -181
  35. package/src/adapters/openai-responses.ts +92 -224
  36. package/src/adapters/registry.ts +0 -7
  37. package/src/adapters/run-turn-queue.ts +13 -6
  38. package/src/bridge.ts +14 -15
  39. package/src/chat/inbound.ts +29 -4
  40. package/src/chat/outbound.ts +145 -107
  41. package/src/claude/desktop-profile.ts +4 -6
  42. package/src/cli/account-api.ts +14 -0
  43. package/src/cli/account-extended.ts +1 -1
  44. package/src/cli/account-history.ts +60 -0
  45. package/src/cli/account-main.ts +80 -0
  46. package/src/cli/account.ts +11 -3
  47. package/src/cli/capabilities.ts +113 -0
  48. package/src/cli/catalog.ts +109 -0
  49. package/src/cli/dispatch.ts +9 -0
  50. package/src/cli/help.ts +2 -0
  51. package/src/cli/index.ts +2 -2
  52. package/src/cli/observe.ts +28 -1
  53. package/src/cli/opencode.ts +42 -8
  54. package/src/cli/provider-runtime.ts +11 -1
  55. package/src/cli/provider.ts +22 -2
  56. package/src/cli/registry.ts +21 -0
  57. package/src/cli/remote-workspace.ts +154 -0
  58. package/src/cli/status.ts +39 -7
  59. package/src/cli/usage-report.ts +14 -2
  60. package/src/client/hub-client.ts +34 -0
  61. package/src/client/hub-state.ts +9 -1
  62. package/src/codex/account-store.ts +78 -0
  63. package/src/codex/auth-api.ts +81 -54
  64. package/src/codex/auth-context.ts +45 -16
  65. package/src/codex/catalog/effort.ts +1 -1
  66. package/src/codex/catalog/metadata.ts +3 -6
  67. package/src/codex/catalog/native-models.ts +4 -4
  68. package/src/codex/catalog/parsing.ts +2 -20
  69. package/src/codex/catalog/provider-fetch.ts +10 -1
  70. package/src/codex/catalog/remote.ts +233 -0
  71. package/src/codex/catalog/sync.ts +403 -35
  72. package/src/codex/convergence.ts +1 -1
  73. package/src/codex/history-manifest.ts +36 -0
  74. package/src/codex/history-provider.ts +32 -5
  75. package/src/codex/inject.ts +9 -0
  76. package/src/codex/main-account.ts +113 -0
  77. package/src/codex/main-device-reauth-api.ts +89 -0
  78. package/src/codex/main-device-reauth.ts +217 -0
  79. package/src/codex/native-residue.ts +9 -2
  80. package/src/codex/quota-auto-refresh.ts +3 -2
  81. package/src/codex/quota-capacity.ts +98 -0
  82. package/src/codex/quota-history.ts +160 -0
  83. package/src/codex/quota-types.ts +8 -0
  84. package/src/codex/quota.ts +118 -91
  85. package/src/codex/refresh.ts +2 -1
  86. package/src/codex/routing.ts +90 -17
  87. package/src/codex/sync.ts +33 -4
  88. package/src/combos/request.ts +19 -1
  89. package/src/config/multi-agent-surface.ts +61 -0
  90. package/src/config/provider-validation.ts +176 -0
  91. package/src/config.ts +213 -11
  92. package/src/generated/compatibility-version.json +436 -168
  93. package/src/images/loop.ts +119 -36
  94. package/src/lib/admission.ts +12 -6
  95. package/src/lib/redact.ts +7 -0
  96. package/src/lib/translator-budget.ts +4 -3
  97. package/src/lib/windows-atomic-replace.ts +1 -0
  98. package/src/lib/windows-elevation.ts +1 -1
  99. package/src/oauth/chatgpt-device.ts +62 -5
  100. package/src/oauth/devin/cli-import.ts +130 -0
  101. package/src/oauth/devin.ts +63 -8
  102. package/src/oauth/index.ts +29 -14
  103. package/src/oauth/kiro.ts +18 -6
  104. package/src/oauth/login-cli.ts +9 -1
  105. package/src/oauth/meta-muse-device.ts +464 -0
  106. package/src/oauth/meta-muse.ts +123 -32
  107. package/src/oauth/pool-kernel.ts +9 -0
  108. package/src/oauth/pool-settings-capability.ts +2 -2
  109. package/src/oauth/store.ts +57 -0
  110. package/src/oauth/types.ts +31 -0
  111. package/src/providers/derive.ts +13 -3
  112. package/src/providers/devin-cli-authmode-migration.ts +57 -35
  113. package/src/providers/devin-provider-merge-migration.ts +240 -0
  114. package/src/providers/muse-key-quota.ts +117 -0
  115. package/src/providers/muse-subscription-usage.ts +14 -2
  116. package/src/providers/openai-sidecar.ts +25 -3
  117. package/src/providers/opencode-zen-rate-limit.ts +58 -0
  118. package/src/providers/provider-id-rewrite.ts +20 -5
  119. package/src/providers/quota-types.ts +12 -0
  120. package/src/providers/quota.ts +143 -102
  121. package/src/providers/reasoning-metadata.ts +543 -0
  122. package/src/providers/registry.ts +80 -49
  123. package/src/reasoning-effort.ts +26 -2
  124. package/src/remote/hub-usage.ts +32 -0
  125. package/src/remote-control/index.ts +192 -41
  126. package/src/remote-control/workspace-activation.ts +9 -0
  127. package/src/remote-control/workspace-agent-connection.ts +366 -0
  128. package/src/remote-control/workspace-claude-runtime.ts +243 -0
  129. package/src/remote-control/workspace-codex-runtime.ts +531 -0
  130. package/src/remote-control/workspace-codex-sandbox.ts +115 -0
  131. package/src/remote-control/workspace-command-runner.ts +748 -0
  132. package/src/remote-control/workspace-coordinator.ts +231 -0
  133. package/src/remote-control/workspace-device.ts +585 -0
  134. package/src/remote-control/workspace-executable.ts +43 -0
  135. package/src/remote-control/workspace-executor.ts +397 -0
  136. package/src/remote-control/workspace-hub.ts +519 -0
  137. package/src/remote-control/workspace-pi-runtime.ts +382 -0
  138. package/src/remote-control/workspace-process.ts +129 -0
  139. package/src/remote-control/workspace-rpc.ts +304 -0
  140. package/src/remote-control/workspace-runtime.ts +60 -0
  141. package/src/remote-control/workspace-secret-store.ts +39 -0
  142. package/src/remote-control/workspace-sessions.ts +799 -0
  143. package/src/remote-control/workspace-tool-bridge.ts +192 -0
  144. package/src/responses/code-mode-helper-compat.ts +22 -3
  145. package/src/responses/hosted-tool-policy.ts +0 -1
  146. package/src/responses/muse-tool-name-alias.ts +379 -0
  147. package/src/responses/plaintext-v2-agent-messages.ts +902 -0
  148. package/src/router.ts +7 -0
  149. package/src/routing/compatibility/behavior.ts +0 -1
  150. package/src/server/audio-client.ts +64 -0
  151. package/src/server/audio-dictation.ts +91 -0
  152. package/src/server/audio-live.ts +185 -0
  153. package/src/server/audio-transcriptions.ts +183 -0
  154. package/src/server/audio-upstream.ts +153 -0
  155. package/src/server/auth-cors.ts +61 -2
  156. package/src/server/chat-completions.ts +1 -1
  157. package/src/server/chat-native-sse.ts +92 -48
  158. package/src/server/chat-native.ts +37 -15
  159. package/src/server/hub-usage.ts +57 -0
  160. package/src/server/images.ts +4 -0
  161. package/src/server/index.ts +722 -57
  162. package/src/server/lifecycle.ts +5 -6
  163. package/src/server/live-call-bindings.ts +60 -0
  164. package/src/server/live.ts +12 -1
  165. package/src/server/management/agent-settings-routes.ts +25 -4
  166. package/src/server/management/api-access.ts +37 -0
  167. package/src/server/management/api-key-usage.ts +7 -2
  168. package/src/server/management/config-routes.ts +1 -18
  169. package/src/server/management/context.ts +15 -0
  170. package/src/server/management/logs-usage-routes.ts +2 -0
  171. package/src/server/management/oauth-account-routes.ts +39 -12
  172. package/src/server/management/provider-routes.ts +125 -2
  173. package/src/server/management/remote-workspace-routes.ts +140 -0
  174. package/src/server/management/route-registry.ts +15 -0
  175. package/src/server/management/usage-aggregate-cache.ts +14 -15
  176. package/src/server/management/usage-summary-cache.ts +2 -0
  177. package/src/server/management-api.ts +23 -0
  178. package/src/server/ports.ts +17 -0
  179. package/src/server/relay-eager.ts +4 -1
  180. package/src/server/relay.ts +70 -10
  181. package/src/server/request-decompress.ts +6 -3
  182. package/src/server/responses/agent-task-recovery.ts +25 -32
  183. package/src/server/responses/codex-auth-error.ts +11 -0
  184. package/src/server/responses/codex-ws-exchange.ts +52 -3
  185. package/src/server/responses/codex-ws-wire.ts +55 -0
  186. package/src/server/responses/compact.ts +9 -1
  187. package/src/server/responses/core.ts +337 -73
  188. package/src/server/responses/encrypted-payload.ts +45 -2
  189. package/src/server/responses/ws-upstream.ts +4 -1
  190. package/src/server/responses-self-named-namespace-scrub.ts +1 -3
  191. package/src/server/responses-undeclared-tool-guard.ts +1 -1
  192. package/src/server/search.ts +3 -0
  193. package/src/server/sse-payload-rewrite.ts +136 -51
  194. package/src/server/ws-bridge.ts +35 -1
  195. package/src/service/cli.ts +372 -0
  196. package/src/service/diagnostics.ts +340 -0
  197. package/src/service/guards.ts +303 -0
  198. package/src/service/health.ts +222 -0
  199. package/src/service/launchd.ts +853 -0
  200. package/src/service/orchestration.ts +617 -0
  201. package/src/service/repair.ts +334 -0
  202. package/src/service/state.ts +363 -0
  203. package/src/service/systemd.ts +229 -0
  204. package/src/service/windows-ops.ts +690 -0
  205. package/src/service/windows-scheduler.ts +769 -0
  206. package/src/service/windows-taskxml.ts +613 -0
  207. package/src/service.ts +22 -5550
  208. package/src/storage/cleanup/db.ts +258 -0
  209. package/src/storage/cleanup/execute.ts +358 -0
  210. package/src/storage/cleanup/paths.ts +189 -0
  211. package/src/storage/cleanup/pending.ts +140 -0
  212. package/src/storage/cleanup/preview.ts +292 -0
  213. package/src/storage/cleanup/reconcile.ts +347 -0
  214. package/src/storage/cleanup/restore.ts +932 -0
  215. package/src/storage/cleanup/satellite.ts +474 -0
  216. package/src/storage/cleanup/staging.ts +129 -0
  217. package/src/storage/cleanup/types.ts +98 -0
  218. package/src/storage/cleanup.ts +49 -3127
  219. package/src/types/accounts.ts +2 -0
  220. package/src/types/config.ts +13 -12
  221. package/src/types/provider.ts +37 -0
  222. package/src/types/request.ts +2 -0
  223. package/src/types/tools.ts +17 -5
  224. package/src/types.ts +1 -0
  225. package/src/usage/expected-prices.ts +127 -0
  226. package/src/usage/log.ts +58 -1
  227. package/src/vision/eligibility.ts +13 -2
  228. package/src/web-search/loop.ts +56 -3
  229. package/gui/dist/assets/index-CWXut3rG.js +0 -115
  230. package/gui/dist/assets/index-EdoPnm9_.css +0 -1
  231. package/src/adapters/devin-cli/acp.ts +0 -204
  232. package/src/adapters/devin-cli/adapter.ts +0 -345
  233. package/src/adapters/devin-cli/binary.ts +0 -69
  234. package/src/adapters/devin-cli/models.ts +0 -57
  235. package/src/oauth/devin-cli.ts +0 -149
  236. package/src/server/responses-reasoning-summary-rewrite.ts +0 -178
@@ -0,0 +1,223 @@
1
+ import { estimateTokens } from "../../lib/token-estimate";
2
+ import { KIRO_MODEL_CONTEXT_WINDOWS, normalizeKiroModelId } from "../../providers/kiro-models";
3
+ import { modelRecordValue } from "../../reasoning-effort";
4
+ import { sniffImageDimensions } from "../anthropic-image-guard";
5
+ import type { KiroImage } from "../kiro-images";
6
+ import type {
7
+ OcxContentPart,
8
+ OcxMessage,
9
+ OcxParsedRequest,
10
+ } from "../../types";
11
+ import type { KiroHistoryEntry } from "./wire";
12
+
13
+ export function userContentText(content: string | OcxContentPart[]): string {
14
+ if (typeof content === "string") return content;
15
+ return content.map(p => (p.type === "text" ? p.text : "")).filter(Boolean).join("\n");
16
+ }
17
+
18
+ export function usageContentText(content: string | OcxContentPart[]): string {
19
+ if (typeof content === "string") return content;
20
+ return content
21
+ .map(p => {
22
+ if (p.type === "text") return p.text;
23
+ if (p.type === "image") return `[image:${p.detail ?? "auto"}]`;
24
+ return "";
25
+ })
26
+ .filter(Boolean)
27
+ .join("\n");
28
+ }
29
+ export function serializeForUsage(value: unknown): string {
30
+ try { return JSON.stringify(value); } catch { return String(value); }
31
+ }
32
+ export function currentTurnUsageMessages(messages: OcxMessage[]): OcxMessage[] {
33
+ return messages.slice(messages.map(m => m.role).lastIndexOf("assistant") + 1).filter(m => m.role !== "assistant");
34
+ }
35
+ export function kiroPayloadMessages(parsed: OcxParsedRequest): OcxMessage[] {
36
+ return parsed.context.messages;
37
+ }
38
+
39
+ export function messageUsageText(msg: OcxMessage): string {
40
+ switch (msg.role) {
41
+ case "user":
42
+ case "developer":
43
+ return usageContentText(msg.content);
44
+ case "toolResult":
45
+ return [
46
+ msg.toolName,
47
+ msg.toolCallId,
48
+ msg.isError ? "error" : "success",
49
+ usageContentText(msg.content),
50
+ ].filter(Boolean).join("\n");
51
+ case "assistant":
52
+ return "";
53
+ }
54
+ }
55
+
56
+ export function messageLogText(msg: OcxMessage): string {
57
+ if (msg.role !== "assistant") return messageUsageText(msg);
58
+ return msg.content.map(part => {
59
+ if (part.type === "text") return part.text;
60
+ if (part.type === "toolCall") return [part.name, part.id, serializeForUsage(part.arguments)].join("\n");
61
+ return part.thinking;
62
+ }).filter(Boolean).join("\n");
63
+ }
64
+
65
+ export function estimateKiroImageTokens(image: KiroImage): number {
66
+ const dimensions = sniffImageDimensions(image.source.bytes);
67
+ if (dimensions) {
68
+ return Math.max(256, Math.ceil(dimensions.width * dimensions.height / 750));
69
+ }
70
+ const decodedBytes = Math.floor(image.source.bytes.length * 3 / 4);
71
+ return Math.max(256, Math.ceil(decodedBytes / 512));
72
+ }
73
+
74
+ export function estimateKiroTokens(text: string, modelId?: string): number {
75
+ return estimateTokens(text, modelId ? `kiro/${modelId}` : "kiro");
76
+ }
77
+
78
+ /** Hangul/Han/kana ranges, matching the shared estimator's own CJK classification. */
79
+ export function kiroCjkCount(text: string): number {
80
+ let cjk = 0;
81
+ for (let i = 0; i < text.length; i++) {
82
+ const c = text.charCodeAt(i);
83
+ if (
84
+ (c >= 0xac00 && c <= 0xd7a3) || (c >= 0x1100 && c <= 0x11ff) || (c >= 0x3130 && c <= 0x318f)
85
+ || (c >= 0x4e00 && c <= 0x9fff) || (c >= 0x3400 && c <= 0x4dbf) || (c >= 0x3040 && c <= 0x30ff)
86
+ ) cjk++;
87
+ }
88
+ return cjk;
89
+ }
90
+
91
+ /**
92
+ * Token estimate for walked payload text, with the wire expansion applied to the Latin portion
93
+ * only. Splitting here rather than inside the shared estimator keeps that module pure and
94
+ * provider-neutral: the expansion is a fact about Kiro's wire, not about tokenization.
95
+ */
96
+ export function estimateKiroWireTokens(text: string, modelId: string): number {
97
+ if (!text) return 0;
98
+ const cjk = kiroCjkCount(text);
99
+ if (cjk === 0) return Math.ceil(estimateKiroTokens(text, modelId) * KIRO_LATIN_WIRE_EXPANSION);
100
+ const latinTokens = estimateKiroTokens("x".repeat(text.length - cjk), modelId);
101
+ const cjkTokens = estimateKiroTokens("\uac00".repeat(cjk), modelId);
102
+ return Math.ceil(latinTokens * KIRO_LATIN_WIRE_EXPANSION + cjkTokens);
103
+ }
104
+
105
+ /**
106
+ * Structural cost of one conversation entry, in tokens.
107
+ *
108
+ * The walker below concatenates message TEXT, but the wire carries JSON: per-entry keys
109
+ * (`userInputMessage`, `content`, `modelId`, `origin`) and role framing. That is charged
110
+ * upstream and is invisible to a text-only count, so without it a long conversation drifts
111
+ * further below the real charge with every turn added — an error proportional to entry COUNT,
112
+ * which no per-character ratio can recover.
113
+ *
114
+ * Regressing serialized bodies against what the walker counts, over eleven payload sizes from
115
+ * 3 to 701 entries:
116
+ *
117
+ * bodyBytes = 1.0422 * walkedChars + 66.7 * entries + 68
118
+ *
119
+ * 66.7 bytes at the measured 2.433 bytes per charged token is 27.4 tokens per entry. The
120
+ * earlier value of 12 was a conservative hand-fit taken before that regression existed, and
121
+ * being less than half the real cost is precisely why the estimate decayed with conversation
122
+ * length: an under-charge of ~15 tokens per entry is invisible across four messages and
123
+ * dominant across seven hundred.
124
+ *
125
+ * Cross-checked against 4,090 recorded requests, where real traffic averages 1,310 bytes per
126
+ * message: 66.7 bytes is 5% of that, so this term charges framing and is not quietly absorbing
127
+ * message content.
128
+ */
129
+ export const KIRO_ENTRY_FRAMING_TOKENS = 27;
130
+
131
+ /**
132
+ * Multiplier reconciling the LATIN text estimate with what the wire charges for that same text.
133
+ *
134
+ * The shared estimator counts Latin text at 2.8 chars/token, while the wire charges 2.433 bytes
135
+ * per token at 1.0422 bytes per walked character — an effective 2.334 chars/token, and
136
+ * 2.8 / 2.334 = 1.199.
137
+ *
138
+ * The evidence that the split between this term and `KIRO_ENTRY_FRAMING_TOKENS` is right is its
139
+ * stability: holding framing at 27, the multiplier the charge implies stays within 1.189-1.209
140
+ * across a 230x range of conversation sizes. A mis-specified split drifts with size, and the
141
+ * earlier 1.12/12 pair did — its accuracy fell from 0.92 at four messages to 0.87 at seven
142
+ * hundred.
143
+ *
144
+ * LATIN ONLY, deliberately. 2.433 bytes/token is a property of this traffic mix, which is Latin
145
+ * and code. A Hangul character is three UTF-8 bytes but roughly one token, so its bytes-per-token
146
+ * is entirely different and a Latin-derived byte rate says nothing about it. Scaling CJK by this
147
+ * factor bills Hangul at 1.25 chars/token, against recorded ground truth that already places the
148
+ * shared 1.5 ratio at 0.90 of the authoritative count — an over-charge that would compact Korean
149
+ * threads early.
150
+ *
151
+ * This is NOT JSON escaping, despite what an earlier version of this comment claimed. Measured
152
+ * directly, `JSON.stringify` expands prose by 1.012 (Latin) to 1.019 (Korean), nowhere near 1.2.
153
+ * Escaping is real but small, and is already inside the byte measurement this factor comes from.
154
+ */
155
+ export const KIRO_LATIN_WIRE_EXPANSION = 1.2;
156
+
157
+ export function estimateKiroPayloadInputTokens(payload: Record<string, unknown>, modelId: string): number {
158
+ const conversationState = (payload as {
159
+ conversationState?: {
160
+ history?: KiroHistoryEntry[];
161
+ currentMessage?: KiroHistoryEntry;
162
+ };
163
+ }).conversationState;
164
+ if (!conversationState) return 0;
165
+
166
+ const parts: string[] = [];
167
+ let imageTokens = 0;
168
+ const entries = [
169
+ ...(conversationState.history ?? []),
170
+ ...(conversationState.currentMessage ? [conversationState.currentMessage] : []),
171
+ ];
172
+ for (const entry of entries) {
173
+ const user = entry.userInputMessage;
174
+ if (user) {
175
+ if (user.content) parts.push(user.content);
176
+ for (const image of user.images ?? []) imageTokens += estimateKiroImageTokens(image);
177
+ const context = user.userInputMessageContext;
178
+ if (context?.tools?.length) parts.push(serializeForUsage(context.tools));
179
+ if (context?.toolResults?.length) parts.push(serializeForUsage(context.toolResults));
180
+ }
181
+ const assistant = entry.assistantResponseMessage;
182
+ if (assistant) {
183
+ if (assistant.content) parts.push(assistant.content);
184
+ if (assistant.toolUses?.length) parts.push(serializeForUsage(assistant.toolUses));
185
+ }
186
+ }
187
+ return estimateKiroWireTokens(parts.join("\n"), modelId)
188
+ + imageTokens
189
+ + entries.length * KIRO_ENTRY_FRAMING_TOKENS;
190
+ }
191
+
192
+ export function shouldCountStablePromptOverhead(parsed: OcxParsedRequest): boolean {
193
+ return !parsed.previousResponseId && !parsed.context.messages.some(m => m.role === "assistant");
194
+ }
195
+
196
+ export function estimateKiroInputTokens(parsed: OcxParsedRequest): number {
197
+ const parts = currentTurnUsageMessages(parsed.context.messages)
198
+ .map(messageUsageText)
199
+ .filter(Boolean);
200
+
201
+ if (shouldCountStablePromptOverhead(parsed)) {
202
+ if (parsed.context.systemPrompt?.length) parts.push(...parsed.context.systemPrompt);
203
+ if (parsed.context.tools?.length) parts.push(serializeForUsage(parsed.context.tools));
204
+ }
205
+
206
+ return estimateKiroTokens(parts.join("\n"), parsed.modelId);
207
+ }
208
+
209
+ export function estimateKiroLogInputTokens(parsed: OcxParsedRequest): number {
210
+ const parts = parsed.context.messages.map(messageLogText).filter(Boolean);
211
+ if (parsed.context.systemPrompt?.length) parts.push(...parsed.context.systemPrompt);
212
+ if (parsed.context.tools?.length) parts.push(serializeForUsage(parsed.context.tools));
213
+ return Math.max(estimateKiroInputTokens(parsed), estimateKiroTokens(parts.join("\n"), parsed.modelId));
214
+ }
215
+
216
+ export function kiroUpstreamContextWindow(modelId: string | undefined): number | undefined {
217
+ if (!modelId) return undefined;
218
+ const normalizedModelId = normalizeKiroModelId(modelId);
219
+ if (normalizedModelId === "auto") return undefined;
220
+ const window = modelRecordValue(KIRO_MODEL_CONTEXT_WINDOWS, modelId)
221
+ ?? modelRecordValue(KIRO_MODEL_CONTEXT_WINDOWS, normalizedModelId);
222
+ return typeof window === "number" && Number.isFinite(window) && window > 0 ? window : undefined;
223
+ }
@@ -0,0 +1,76 @@
1
+ import type { OcxProviderConfig } from "../../types";
2
+ import type { KiroImage } from "../kiro-images";
3
+
4
+ export const AMZ_TARGET = "AmazonCodeWhispererStreamingService.GenerateAssistantResponse";
5
+ export const SDK_VERSION = "1.0.27";
6
+ export const NODE_VERSION = "22.21.1";
7
+ export const KIRO_IDE_VERSION = "1.0.0";
8
+ export const KIRO_FALLBACK_SERIALIZATION_ENVELOPE_BYTES = 64 * 1024;
9
+ export type KiroWireClient = "ide" | "cli";
10
+
11
+ export function kiroCliPlatform(): "linux" | "macos" | "windows" {
12
+ return process.platform === "win32" ? "windows" : process.platform === "darwin" ? "macos" : "linux";
13
+ }
14
+
15
+ export function kiroCliUserAgent(includeAppVersion: boolean): string {
16
+ return [
17
+ "aws-sdk-rust/1.3.15",
18
+ "ua/2.1",
19
+ "api/codewhispererstreaming/0.1.17975",
20
+ `os/${kiroCliPlatform()}`,
21
+ "lang/rust/1.92.0",
22
+ ...(includeAppVersion ? ["md/appVersion-2.14.2"] : []),
23
+ "m/F",
24
+ "app/AmazonQ-For-CLI",
25
+ ].join(" ");
26
+ }
27
+
28
+ // Payload construction (conversationState)
29
+ export interface KiroToolUse {
30
+ name: string;
31
+ input: Record<string, unknown>; // OBJECT, not stringified
32
+ toolUseId: string;
33
+ }
34
+ export interface KiroToolResult {
35
+ content: Array<{ text: string }>;
36
+ status: string;
37
+ toolUseId: string;
38
+ }
39
+ export interface KiroUserInputMessage {
40
+ content: string;
41
+ modelId?: string;
42
+ origin?: string;
43
+ userInputMessageContext?: {
44
+ tools?: unknown[];
45
+ toolResults?: KiroToolResult[];
46
+ };
47
+ images?: KiroImage[];
48
+ }
49
+ export interface KiroHistoryEntry {
50
+ userInputMessage?: KiroUserInputMessage;
51
+ assistantResponseMessage?: {
52
+ content: string;
53
+ toolUses?: KiroToolUse[];
54
+ reasoningContent?: { redactedContent: string };
55
+ };
56
+ }
57
+
58
+ export function kiroToolWireNames(tools: readonly unknown[]): string[] {
59
+ return tools
60
+ .map(tool => {
61
+ const spec = (tool as { toolSpecification?: { name?: unknown } }).toolSpecification;
62
+ return typeof spec?.name === "string" ? spec.name : undefined;
63
+ })
64
+ .filter((name): name is string => typeof name === "string");
65
+ }
66
+
67
+ export function kiroRuntimeEndpoint(provider: OcxProviderConfig, region: string): string {
68
+ const configured = new URL(provider.baseUrl);
69
+ if (
70
+ /^runtime\.[a-z]{2}(?:-[a-z]+)+-\d\.kiro\.dev$/i.test(configured.hostname)
71
+ && configured.pathname === "/"
72
+ ) {
73
+ return `https://runtime.${region}.kiro.dev/`;
74
+ }
75
+ return configured.toString();
76
+ }