@bitkyc08/opencodex 2.7.33 → 2.7.34

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 (64) hide show
  1. package/README.ja.md +1 -1
  2. package/README.ko.md +1 -1
  3. package/README.md +21 -10
  4. package/README.ru.md +1 -1
  5. package/README.zh-CN.md +1 -1
  6. package/gui/dist/assets/index-BkmJJgg6.js +52 -0
  7. package/gui/dist/assets/index-Sg-7L_oZ.css +1 -0
  8. package/gui/dist/index.html +2 -2
  9. package/package.json +1 -1
  10. package/src/adapters/anthropic.ts +13 -6
  11. package/src/adapters/cursor/discovery.ts +39 -4
  12. package/src/adapters/cursor/exec-policy.ts +11 -13
  13. package/src/adapters/cursor/live-transport.ts +22 -4
  14. package/src/adapters/cursor/protobuf-events.ts +140 -8
  15. package/src/adapters/cursor/protobuf-request.ts +15 -0
  16. package/src/adapters/cursor/request-builder.ts +10 -5
  17. package/src/adapters/cursor/transport.ts +3 -2
  18. package/src/adapters/cursor/types.ts +14 -0
  19. package/src/adapters/kiro-constants.ts +12 -0
  20. package/src/adapters/kiro-errors.ts +111 -2
  21. package/src/adapters/kiro-events.ts +154 -35
  22. package/src/adapters/kiro-retry.ts +116 -32
  23. package/src/adapters/kiro-tools.ts +30 -20
  24. package/src/adapters/kiro-wire.ts +47 -6
  25. package/src/adapters/kiro.ts +891 -228
  26. package/src/adapters/openai-chat.ts +12 -5
  27. package/src/adapters/openai-responses.ts +7 -2
  28. package/src/bridge.ts +109 -26
  29. package/src/claude/outbound.ts +27 -4
  30. package/src/cli/index.ts +1 -1
  31. package/src/codex/catalog.ts +375 -33
  32. package/src/combos/index.ts +3 -0
  33. package/src/combos/request.ts +4 -4
  34. package/src/combos/resolve.ts +2 -2
  35. package/src/combos/types.ts +104 -2
  36. package/src/config.ts +70 -1
  37. package/src/lib/eventstream-decoder.ts +9 -0
  38. package/src/oauth/index.ts +3 -1
  39. package/src/oauth/kiro-credentials.ts +48 -20
  40. package/src/oauth/login-cli.ts +2 -0
  41. package/src/providers/derive.ts +8 -0
  42. package/src/providers/kiro-models.ts +2 -2
  43. package/src/providers/openai-sidecar.ts +28 -1
  44. package/src/providers/registry.ts +39 -2
  45. package/src/responses/parser.ts +22 -10
  46. package/src/responses/schema.ts +1 -0
  47. package/src/responses/state.ts +50 -10
  48. package/src/router.ts +15 -3
  49. package/src/server/auth-cors.ts +7 -0
  50. package/src/server/claude-messages.ts +6 -0
  51. package/src/server/index.ts +6 -3
  52. package/src/server/management-api.ts +187 -43
  53. package/src/server/ports.ts +4 -2
  54. package/src/server/request-log.ts +3 -2
  55. package/src/server/responses-item-id-repair.ts +281 -0
  56. package/src/server/responses.ts +274 -73
  57. package/src/types.ts +109 -16
  58. package/src/update/job.ts +81 -1
  59. package/src/vision/describe.ts +2 -1
  60. package/src/web-search/executor.ts +2 -1
  61. package/src/web-search/loop.ts +9 -1
  62. package/src/web-search/progress-stream.ts +12 -10
  63. package/gui/dist/assets/index-D6Fcl4yM.css +0 -1
  64. package/gui/dist/assets/index-d63HMU0x.js +0 -52
@@ -1,8 +1,10 @@
1
1
  import type { OcxParsedRequest } from "../types";
2
2
  import { namespacedToolName } from "../types";
3
- import { kiroToolName } from "./kiro-wire";
3
+ import { normalizeKiroModelId } from "../providers/kiro-models";
4
+ import { createKiroToolNameRegistry, type KiroToolNameRegistry } from "./kiro-wire";
4
5
 
5
- const MAX_KIRO_TOOL_DESCRIPTION = 1024;
6
+ const MAX_KIRO_TOOL_DESCRIPTION_UNVERIFIED = 1024;
7
+ const MAX_KIRO_TOOL_DESCRIPTION_GPT_56_SOL = 9_216;
6
8
 
7
9
  // JSON Schema validation/annotation keywords that Kiro's runtimeservice tool-spec validator
8
10
  // rejects ("ValidationException: Invalid tool use format."). Codex's built-in tools omit these,
@@ -133,39 +135,47 @@ function ensureRootObjectType(schema: unknown): Record<string, unknown> {
133
135
  return merged;
134
136
  }
135
137
 
136
- export function convertKiroToolContext(parsed: OcxParsedRequest): { tools: unknown[]; systemAdditions: string[]; nameMap: Map<string, string> } {
138
+ function toolDescriptionLimit(modelId: string): number {
139
+ return normalizeKiroModelId(modelId) === "gpt-5.6-sol"
140
+ ? MAX_KIRO_TOOL_DESCRIPTION_GPT_56_SOL
141
+ : MAX_KIRO_TOOL_DESCRIPTION_UNVERIFIED;
142
+ }
143
+
144
+ function truncateDescription(description: string, limit: number): string {
145
+ if (description.length <= limit) return description;
146
+ if (limit <= 1) return description.slice(0, limit);
147
+ return `${description.slice(0, limit - 1)}…`;
148
+ }
149
+
150
+ export function convertKiroToolContext(
151
+ parsed: OcxParsedRequest,
152
+ registry: KiroToolNameRegistry = createKiroToolNameRegistry(),
153
+ ): { tools: unknown[]; systemAdditions: string[]; nameMap: Map<string, string>; registry: KiroToolNameRegistry } {
137
154
  const tools = parsed.context.tools ?? [];
138
- const systemAdditions: string[] = [];
139
- // Maps the Kiro-safe toolSpecification.name back to the original wire name so the response parser
140
- // can restore it (the bridge's toolNsMap is keyed by the original wire name). Only non-identity
141
- // entries are stored.
142
- const nameMap = new Map<string, string>();
155
+ const descriptionLimit = toolDescriptionLimit(parsed.modelId);
156
+ // Validate every listed name even when tool_choice:none emulates a tool-free turn.
157
+ for (const tool of tools) registry.alias(namespacedToolName(tool.namespace, tool.name));
158
+ const effectiveTools = parsed.options.toolChoice === "none" ? [] : tools;
143
159
  return {
144
- tools: tools.map(t => {
160
+ tools: effectiveTools.map(t => {
145
161
  const description = t.description || `Tool: ${t.name}`;
146
162
  // Send the full namespaced wire name (e.g. mcp__chrome-devtools__navigate_page) so Kiro echoes
147
163
  // it back; the bridge's toolNsMap is keyed by this name and restores the MCP namespace Codex
148
164
  // routes by. Kiro's runtimeservice rejects names with spaces or >64 chars, so normalize to a
149
165
  // safe form and remember the mapping; the response parser restores the original wire name.
150
166
  const wireName = namespacedToolName(t.namespace, t.name);
151
- const toolName = kiroToolName(wireName);
152
- if (toolName !== wireName) nameMap.set(toolName, wireName);
153
- const kiroDescription = description.length > MAX_KIRO_TOOL_DESCRIPTION
154
- ? `Tool documentation moved to the system prompt: ${toolName}.`
155
- : description;
156
- if (description.length > MAX_KIRO_TOOL_DESCRIPTION) {
157
- systemAdditions.push([`### Tool documentation: ${toolName}`, description].join("\n"));
158
- }
167
+ const toolName = registry.alias(wireName);
159
168
  return {
160
169
  toolSpecification: {
161
170
  name: toolName,
162
- description: kiroDescription,
171
+ description: truncateDescription(description, descriptionLimit),
163
172
  inputSchema: { json: ensureRootObjectType(sanitizeKiroSchema(t.parameters ?? {})) },
164
173
  },
165
174
  };
166
175
  }),
167
- systemAdditions,
168
- nameMap,
176
+ systemAdditions: [],
177
+ nameMap: registry.nameMap,
178
+ registry,
169
179
  };
170
180
  }
171
181
 
@@ -2,6 +2,7 @@ import { createHash, randomUUID } from "node:crypto";
2
2
  import { hostname, userInfo } from "node:os";
3
3
  import { normalizeKiroModelId } from "../providers/kiro-models";
4
4
  import type { OcxParsedRequest } from "../types";
5
+ import { KIRO_COMPLETION_TOOL_NAME } from "./kiro-constants";
5
6
 
6
7
  let cachedFp: string | undefined;
7
8
 
@@ -70,6 +71,36 @@ export function kiroToolName(wireName: string, used?: Set<string>): string {
70
71
  }
71
72
  }
72
73
 
74
+ export interface KiroToolNameRegistry {
75
+ alias(wireName: string): string;
76
+ restore(kiroName: string): string;
77
+ readonly nameMap: Map<string, string>;
78
+ }
79
+
80
+ /** One collision domain for advertised tools, replayed calls, and the private completion tool. */
81
+ export function createKiroToolNameRegistry(): KiroToolNameRegistry {
82
+ const used = new Set<string>([KIRO_COMPLETION_TOOL_NAME]);
83
+ const wireToKiro = new Map<string, string>();
84
+ const nameMap = new Map<string, string>();
85
+ return {
86
+ alias(wireName: string): string {
87
+ if (wireName === KIRO_COMPLETION_TOOL_NAME) {
88
+ throw new Error(`Kiro reserves the tool name ${JSON.stringify(KIRO_COMPLETION_TOOL_NAME)}`);
89
+ }
90
+ const existing = wireToKiro.get(wireName);
91
+ if (existing) return existing;
92
+ const alias = kiroToolName(wireName, used);
93
+ wireToKiro.set(wireName, alias);
94
+ if (alias !== wireName) nameMap.set(alias, wireName);
95
+ return alias;
96
+ },
97
+ restore(kiroName: string): string {
98
+ return nameMap.get(kiroName) ?? kiroName;
99
+ },
100
+ nameMap,
101
+ };
102
+ }
103
+
73
104
  export function fallbackToolUseId(): string {
74
105
  return `toolu_${randomUUID().slice(0, 8)}`;
75
106
  }
@@ -79,10 +110,20 @@ export function invocationId(): string {
79
110
  }
80
111
 
81
112
  export function stableConversationId(parsed: OcxParsedRequest): string {
82
- const msgs = parsed.context.messages;
83
- if (!msgs || msgs.length === 0) return randomUUID().slice(0, 16);
84
- const key = (msgs.length <= 3 ? msgs : [...msgs.slice(0, 3), msgs[msgs.length - 1]])
85
- .map(m => `${m.role}:${JSON.stringify((m as { content?: unknown }).content ?? "").slice(0, 100)}`)
86
- .join("|");
87
- return createHash("sha256").update(key).digest("hex").slice(0, 16);
113
+ const remembered = parsed._providerContinuation?.kiro?.conversationId;
114
+ if (isValidKiroConversationId(remembered)) return remembered;
115
+ const conversationId = randomUUID();
116
+ parsed._providerContinuation = {
117
+ ...(parsed._providerContinuation ?? {}),
118
+ kiro: { ...(parsed._providerContinuation?.kiro ?? {}), conversationId },
119
+ };
120
+ return conversationId;
121
+ }
122
+
123
+ /** Kiro metadata is untrusted; keep only bounded, printable identifiers safe to persist/replay. */
124
+ export function isValidKiroConversationId(value: unknown): value is string {
125
+ return typeof value === "string"
126
+ && value.length >= 1
127
+ && value.length <= 256
128
+ && /^[A-Za-z0-9._:-]+$/.test(value);
88
129
  }