negotium 0.23.1 → 0.23.2

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 (36) hide show
  1. package/dist/agent-helpers.js +136 -30
  2. package/dist/agent-helpers.js.map +12 -11
  3. package/dist/{chunk-pr8p6pap.js → chunk-6cnpkzkb.js} +7 -2
  4. package/dist/{chunk-pr8p6pap.js.map → chunk-6cnpkzkb.js.map} +3 -3
  5. package/dist/{chunk-z4r7tt2p.js → chunk-cez5m5hm.js} +1 -1
  6. package/dist/{chunk-w6xavjz2.js → chunk-s34sv3d2.js} +20 -8
  7. package/dist/chunk-s34sv3d2.js.map +12 -0
  8. package/dist/hosted-agent.js +97 -13
  9. package/dist/hosted-agent.js.map +8 -7
  10. package/dist/main.js +162 -39
  11. package/dist/main.js.map +14 -13
  12. package/dist/mcp-factories.js +136 -30
  13. package/dist/mcp-factories.js.map +12 -11
  14. package/dist/prompts.js +9 -10
  15. package/dist/prompts.js.map +3 -3
  16. package/dist/registry.js +5 -5
  17. package/dist/registry.js.map +3 -3
  18. package/dist/rollout.js +2 -2
  19. package/dist/runtime/src/agents/codex-native-multi-agent.ts +28 -6
  20. package/dist/runtime/src/agents/codex-provider.ts +14 -1
  21. package/dist/runtime/src/agents/codex-registry.ts +6 -7
  22. package/dist/runtime/src/agents/codex-tier-resolver.ts +74 -0
  23. package/dist/runtime/src/agents/explicit-agent-switch.ts +6 -1
  24. package/dist/runtime/src/agents/model-catalog.ts +34 -23
  25. package/dist/runtime/src/runtime/turn-event-stream.ts +13 -1
  26. package/dist/runtime/src/storage/token-stats.ts +2 -1
  27. package/dist/runtime/src/version.ts +1 -1
  28. package/dist/storage.js +2 -1
  29. package/dist/storage.js.map +3 -3
  30. package/dist/types/packages/core/src/agents/codex-native-multi-agent.d.ts +9 -0
  31. package/dist/types/packages/core/src/agents/codex-tier-resolver.d.ts +10 -0
  32. package/dist/types/packages/core/src/agents/model-catalog.d.ts +2 -2
  33. package/dist/types/packages/core/src/version.d.ts +1 -1
  34. package/package.json +2 -2
  35. package/dist/chunk-w6xavjz2.js.map +0 -12
  36. /package/dist/{chunk-z4r7tt2p.js.map → chunk-cez5m5hm.js.map} +0 -0
@@ -8,7 +8,7 @@ import {
8
8
  logger,
9
9
  parseJsonlText,
10
10
  writeJsonlFile
11
- } from "./chunk-pr8p6pap.js";
11
+ } from "./chunk-6cnpkzkb.js";
12
12
 
13
13
  // ../../packages/core/src/agents/rollout/claude.ts
14
14
  import { randomUUID } from "crypto";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  hostedCodexHomePath,
4
4
  latestCodexRolloutPath
5
- } from "./chunk-pr8p6pap.js";
5
+ } from "./chunk-6cnpkzkb.js";
6
6
 
7
7
  // ../../packages/core/src/agents/codex-app-server.ts
8
8
  import { spawn } from "child_process";
@@ -19,17 +19,29 @@ import {
19
19
  unlinkSync,
20
20
  writeFileSync
21
21
  } from "fs";
22
- import { createRequire } from "module";
23
22
  import { dirname, join } from "path";
23
+ import { fileURLToPath } from "url";
24
24
 
25
25
  // ../../packages/core/src/version.ts
26
- var NEGOTIUM_VERSION = "0.23.1";
26
+ var NEGOTIUM_VERSION = "0.23.2";
27
27
 
28
28
  // ../../packages/core/src/agents/codex-native-multi-agent.ts
29
- var moduleRequire = createRequire(import.meta.url);
30
- var codexSdkPackagePath = moduleRequire.resolve("@openai/codex-sdk/package.json");
31
- var codexSdkRequire = createRequire(codexSdkPackagePath);
32
- var bundledCodexPackagePath = codexSdkRequire.resolve("@openai/codex/package.json");
29
+ function findPackageJson(specifier, searchFromDir) {
30
+ let dir = searchFromDir;
31
+ for (;; ) {
32
+ const candidate = join(dir, "node_modules", specifier, "package.json");
33
+ if (existsSync(candidate))
34
+ return candidate;
35
+ const parent = dirname(dir);
36
+ if (parent === dir) {
37
+ throw new Error(`Could not locate node_modules/${specifier} starting from ${searchFromDir}`);
38
+ }
39
+ dir = parent;
40
+ }
41
+ }
42
+ var thisModuleDir = dirname(fileURLToPath(import.meta.url));
43
+ var codexSdkPackagePath = findPackageJson("@openai/codex-sdk", thisModuleDir);
44
+ var bundledCodexPackagePath = findPackageJson("@openai/codex", dirname(codexSdkPackagePath));
33
45
  function readPackageVersion(packageJsonPath) {
34
46
  const parsed = JSON.parse(readFileSync(packageJsonPath, "utf8"));
35
47
  if (typeof parsed.version !== "string" || !parsed.version.trim()) {
@@ -158,4 +170,4 @@ export {
158
170
  createCodexAppServerForker
159
171
  };
160
172
 
161
- //# debugId=1241F1827E4BFC0C64756E2164756E21
173
+ //# debugId=F52112FFE0B50C6764756E2164756E21
@@ -0,0 +1,12 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../packages/core/src/agents/codex-app-server.ts", "../../../packages/core/src/agents/codex-native-multi-agent.ts", "../../../packages/core/src/version.ts"],
4
+ "sourcesContent": [
5
+ "import { type ChildProcessWithoutNullStreams, spawn } from \"node:child_process\";\nimport { codexCliScriptPath } from \"#agents/codex-native-multi-agent\";\nimport { hostedCodexHomePath } from \"#agents/execution-host\";\nimport { latestCodexRolloutPath } from \"#agents/rollout/codex\";\nimport { NEGOTIUM_VERSION } from \"#version\";\n\ninterface CodexAppServerForkResult {\n forkId: string;\n rolloutPath: string;\n}\n\ninterface CodexAppServerForkHost {\n spawnServer(): ChildProcessWithoutNullStreams;\n findRolloutPath(threadId: string): string | undefined;\n timeoutMs: number;\n}\n\ntype JsonRpcResponse = {\n id?: number;\n result?: { thread?: { id?: unknown } };\n error?: { message?: unknown };\n};\n\nexport function createCodexAppServerForker(host: CodexAppServerForkHost) {\n return async (parentThreadId: string): Promise<CodexAppServerForkResult> => {\n const child = host.spawnServer();\n\n return await new Promise<CodexAppServerForkResult>((resolve, reject) => {\n let settled = false;\n let stdoutBuffer = \"\";\n let stderr = \"\";\n const timer = setTimeout(\n () => finish(new Error(\"Codex thread fork timed out\")),\n host.timeoutMs,\n );\n\n const finish = (error?: Error, result?: CodexAppServerForkResult) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n try {\n child.stdin.end();\n child.kill();\n } catch {\n // The app server may already have exited after stdin closed.\n }\n if (error) reject(error);\n else if (result) resolve(result);\n else reject(new Error(\"Codex thread fork returned no result\"));\n };\n\n const send = (message: Record<string, unknown>) => {\n child.stdin.write(`${JSON.stringify(message)}\\n`);\n };\n\n child.stderr.on(\"data\", (chunk) => {\n if (stderr.length < 8_192) stderr += String(chunk);\n });\n child.on(\"error\", (error) => finish(error));\n child.on(\"exit\", (code, signal) => {\n if (settled) return;\n const detail = signal ? `signal ${signal}` : `code ${code ?? 1}`;\n finish(\n new Error(\n `Codex app server exited with ${detail}${stderr.trim() ? `: ${stderr.trim()}` : \"\"}`,\n ),\n );\n });\n child.stdout.on(\"data\", (chunk) => {\n stdoutBuffer += String(chunk);\n for (;;) {\n const newline = stdoutBuffer.indexOf(\"\\n\");\n if (newline < 0) break;\n const line = stdoutBuffer.slice(0, newline);\n stdoutBuffer = stdoutBuffer.slice(newline + 1);\n let message: JsonRpcResponse;\n try {\n message = JSON.parse(line) as JsonRpcResponse;\n } catch {\n continue;\n }\n\n if (message.id === 1) {\n if (message.error) {\n finish(new Error(String(message.error.message || \"Codex initialization failed\")));\n return;\n }\n send({ method: \"initialized\" });\n send({ id: 2, method: \"thread/fork\", params: { threadId: parentThreadId } });\n continue;\n }\n if (message.id !== 2) continue;\n if (message.error) {\n finish(new Error(String(message.error.message || \"Codex thread fork failed\")));\n return;\n }\n const forkId = message.result?.thread?.id;\n if (typeof forkId !== \"string\" || !forkId) {\n finish(new Error(\"Codex thread fork returned no thread id\"));\n return;\n }\n const rolloutPath = host.findRolloutPath(forkId);\n if (!rolloutPath) {\n finish(new Error(`Codex thread fork rollout was not found for ${forkId}`));\n return;\n }\n finish(undefined, { forkId, rolloutPath });\n return;\n }\n });\n\n send({\n id: 1,\n method: \"initialize\",\n params: {\n clientInfo: { name: \"negotium\", version: NEGOTIUM_VERSION },\n },\n });\n });\n };\n}\n\nconst forkCodexThread = createCodexAppServerForker({\n spawnServer() {\n return spawn(process.execPath, [codexCliScriptPath(), \"app-server\", \"--stdio\"], {\n env: { ...process.env, CODEX_HOME: hostedCodexHomePath() },\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n // Background stdio server — no console window on Windows. Ignored on POSIX.\n windowsHide: true,\n });\n },\n findRolloutPath: latestCodexRolloutPath,\n timeoutMs: 15_000,\n});\n\nexport async function forkCodexSession(parentThreadId: string): Promise<CodexAppServerForkResult> {\n return await forkCodexThread(parentThreadId);\n}\n",
6
+ "import { type ChildProcess, spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport {\n chmodSync,\n copyFileSync,\n existsSync,\n mkdtempSync,\n readFileSync,\n renameSync,\n rmSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { NEGOTIUM_VERSION } from \"#version\";\n\ntype CodexModel = Record<string, unknown>;\ntype CodexModelCache = {\n client_version?: unknown;\n models?: unknown;\n};\n\n// Resolving these as *modules* (`require.resolve`/`import.meta.resolve`) broke\n// under a plain Node process (which is how Codex itself spawns this server —\n// Bun's resolver is lax enough that it didn't notice) once `@openai/codex-sdk`\n// 0.165.0 dropped CommonJS support (no `\"require\"` condition in its `exports`\n// map), and `@openai/codex` was never importable to begin with — it ships only\n// a CLI `bin`, no `main`/`exports` at all. Neither package needs to be\n// imported here, only located, so this reimplements Node's own node_modules\n// directory-walk (the same algorithm `require`/`import` use internally) over\n// plain filesystem checks instead, which doesn't care what either package's\n// module shape is.\nfunction findPackageJson(specifier: string, searchFromDir: string): string {\n let dir = searchFromDir;\n for (;;) {\n const candidate = join(dir, \"node_modules\", specifier, \"package.json\");\n if (existsSync(candidate)) return candidate;\n const parent = dirname(dir);\n if (parent === dir) {\n throw new Error(`Could not locate node_modules/${specifier} starting from ${searchFromDir}`);\n }\n dir = parent;\n }\n}\n\nconst thisModuleDir = dirname(fileURLToPath(import.meta.url));\nconst codexSdkPackagePath = findPackageJson(\"@openai/codex-sdk\", thisModuleDir);\nconst bundledCodexPackagePath = findPackageJson(\"@openai/codex\", dirname(codexSdkPackagePath));\n\nfunction readPackageVersion(packageJsonPath: string): string {\n const parsed = JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as { version?: unknown };\n if (typeof parsed.version !== \"string\" || !parsed.version.trim()) {\n throw new Error(`Codex package has no valid version: ${packageJsonPath}`);\n }\n return parsed.version;\n}\n\nexport const BUNDLED_CODEX_VERSION = readPackageVersion(bundledCodexPackagePath);\nconst SAFE_BUNDLED_CODEX_VERSION = BUNDLED_CODEX_VERSION.replace(/[^a-zA-Z0-9._-]/g, \"_\");\nconst NEGOTIUM_MODEL_CACHE = `negotium-models-cache-${SAFE_BUNDLED_CODEX_VERSION}.json`;\nconst NEGOTIUM_MODEL_CATALOG = `negotium-model-catalog-${SAFE_BUNDLED_CODEX_VERSION}.json`;\n\nexport function codexCliScriptPath(): string {\n return join(dirname(bundledCodexPackagePath), \"bin\", \"codex.js\");\n}\n\nfunction parseCodexModelCache(contents: string, sourcePath: string): CodexModelCache {\n let parsed: CodexModelCache;\n try {\n parsed = JSON.parse(contents) as CodexModelCache;\n } catch (error) {\n throw new Error(`Codex model cache is invalid JSON: ${sourcePath}`, { cause: error });\n }\n if (!Array.isArray(parsed.models) || parsed.models.length === 0) {\n throw new Error(`Codex model cache has no models: ${sourcePath}`);\n }\n return parsed;\n}\n\nfunction readCodexModelCache(cachePath: string): {\n contents: string;\n parsed: CodexModelCache;\n} {\n const contents = readFileSync(cachePath, \"utf8\");\n return { contents, parsed: parseCodexModelCache(contents, cachePath) };\n}\n\nexport function readCompatibleCodexModelCache(cachePath: string): {\n contents: string;\n parsed: CodexModelCache;\n} {\n const cache = readCodexModelCache(cachePath);\n if (cache.parsed.client_version !== BUNDLED_CODEX_VERSION) {\n const found =\n typeof cache.parsed.client_version === \"string\"\n ? cache.parsed.client_version\n : \"missing or invalid\";\n throw new Error(\n `Codex model cache version ${found} does not match Negotium's bundled Codex ${BUNDLED_CODEX_VERSION}: ${cachePath}`,\n );\n }\n return cache;\n}\n\nfunction writePrivateFileAtomic(path: string, contents: string): void {\n if (existsSync(path) && readFileSync(path, \"utf8\") === contents) return;\n\n const tempPath = `${path}.${process.pid}.${randomUUID()}.tmp`;\n try {\n writeFileSync(tempPath, contents, { encoding: \"utf8\", mode: 0o600 });\n renameSync(tempPath, path);\n chmodSync(path, 0o600);\n } finally {\n try {\n unlinkSync(tempPath);\n } catch {\n // renameSync normally consumed the temporary file.\n }\n }\n}\n\nexport function bundledCodexModelCachePath(authFilePath: string): string {\n return join(dirname(authFilePath), NEGOTIUM_MODEL_CACHE);\n}\n\nasync function bootstrapCodexModelCache(codexHome: string, cachePath: string): Promise<void> {\n const child = spawn(process.execPath, [codexCliScriptPath(), \"app-server\", \"--stdio\"], {\n env: { ...process.env, CODEX_HOME: codexHome },\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n // Background stdio server — no console window on Windows. Ignored on POSIX.\n windowsHide: true,\n });\n\n const refreshed = new Promise<void>((resolve, reject) => {\n let settled = false;\n let stdoutBuffer = \"\";\n let stderr = \"\";\n const timer = setTimeout(\n () => finish(new Error(\"timed out while refreshing the Codex model catalog\")),\n 15_000,\n );\n\n const finish = (error?: Error) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n try {\n child.stdin.end();\n child.kill();\n } catch {\n // The app server may already have exited after stdin closed.\n }\n if (error) reject(error);\n else if (!existsSync(cachePath)) reject(new Error(\"Codex did not create its model cache\"));\n else resolve();\n };\n\n const send = (message: Record<string, unknown>) => {\n child.stdin.write(`${JSON.stringify(message)}\\n`);\n };\n\n child.stderr.on(\"data\", (chunk) => {\n if (stderr.length < 4_096) stderr += String(chunk);\n });\n child.on(\"error\", (error) => finish(error));\n child.on(\"exit\", (code, signal) => {\n if (!settled) {\n finish(\n new Error(\n `Codex model catalog refresh exited with ${signal ? `signal ${signal}` : `code ${code ?? 1}`}${stderr.trim() ? `: ${stderr.trim()}` : \"\"}`,\n ),\n );\n }\n });\n child.stdout.on(\"data\", (chunk) => {\n stdoutBuffer += String(chunk);\n for (;;) {\n const newline = stdoutBuffer.indexOf(\"\\n\");\n if (newline < 0) break;\n const line = stdoutBuffer.slice(0, newline);\n stdoutBuffer = stdoutBuffer.slice(newline + 1);\n let message: { id?: number; error?: { message?: string } };\n try {\n message = JSON.parse(line) as typeof message;\n } catch {\n continue;\n }\n if (message.id === 1) {\n if (message.error) {\n finish(new Error(message.error.message || \"Codex initialization failed\"));\n return;\n }\n send({ method: \"initialized\" });\n send({ id: 2, method: \"model/list\", params: { includeHidden: true } });\n } else if (message.id === 2) {\n if (message.error) {\n finish(new Error(message.error.message || \"Codex model listing failed\"));\n } else {\n finish();\n }\n return;\n }\n }\n });\n\n send({\n id: 1,\n method: \"initialize\",\n params: {\n clientInfo: { name: \"negotium\", version: NEGOTIUM_VERSION },\n capabilities: { experimentalApi: true },\n },\n });\n });\n\n try {\n await refreshed;\n } finally {\n // `child.kill()` only signals. The caller deletes CODEX_HOME right after we\n // return, and Windows cannot delete a directory the child still holds open\n // (EBUSY), so wait for the process to actually exit first.\n await waitForChildExit(child, CODEX_BOOTSTRAP_EXIT_WAIT_MS);\n }\n}\n\nconst CODEX_BOOTSTRAP_EXIT_WAIT_MS = 3_000;\n\nfunction waitForChildExit(child: ChildProcess, timeoutMs: number): Promise<void> {\n if (child.exitCode !== null || child.signalCode !== null) return Promise.resolve();\n return new Promise((resolve) => {\n const timer = setTimeout(resolve, timeoutMs);\n timer.unref?.();\n child.once(\"exit\", () => {\n clearTimeout(timer);\n resolve();\n });\n });\n}\n\n/**\n * Remove the temporary CODEX_HOME. On Windows a just-exited child (or an\n * antivirus scan of the files it wrote) can keep the directory busy for a\n * moment, so retry, and never let cleanup of a throwaway directory fail a turn\n * whose result was already read. POSIX keeps the original behaviour: unlinking\n * open files works there, and a genuine failure still surfaces.\n */\nfunction removeIsolatedCodexHome(dir: string): void {\n if (process.platform !== \"win32\") {\n rmSync(dir, { recursive: true, force: true });\n return;\n }\n try {\n rmSync(dir, { recursive: true, force: true, maxRetries: 10, retryDelay: 100 });\n } catch {\n // Best effort: the OS temp cleaner will reclaim it.\n }\n}\n\nasync function bootstrapIsolatedCodexModelCache(\n authFilePath: string,\n bootstrap: (codexHome: string, cachePath: string) => Promise<void>,\n): Promise<string> {\n const sourceHome = dirname(authFilePath);\n const isolatedHome = mkdtempSync(join(tmpdir(), \"negotium-codex-models-\"));\n const isolatedCachePath = join(isolatedHome, \"models_cache.json\");\n\n try {\n const isolatedAuthPath = join(isolatedHome, \"auth.json\");\n copyFileSync(authFilePath, isolatedAuthPath);\n chmodSync(isolatedAuthPath, 0o600);\n\n // Preserve custom provider configuration while keeping the bundled CLI's\n // cache write completely outside the user's shared CODEX_HOME.\n const sourceConfigPath = join(sourceHome, \"config.toml\");\n if (existsSync(sourceConfigPath)) {\n const isolatedConfigPath = join(isolatedHome, \"config.toml\");\n copyFileSync(sourceConfigPath, isolatedConfigPath);\n chmodSync(isolatedConfigPath, 0o600);\n }\n\n await bootstrap(isolatedHome, isolatedCachePath);\n return readCompatibleCodexModelCache(isolatedCachePath).contents;\n } finally {\n removeIsolatedCodexHome(isolatedHome);\n }\n}\n\nexport async function ensureCodexModelCache(\n authFilePath: string,\n bootstrap: (codexHome: string, cachePath: string) => Promise<void> = bootstrapCodexModelCache,\n): Promise<string> {\n const codexHome = dirname(authFilePath);\n const configuredCachePath = process.env.NEGOTIUM_CODEX_MODELS_CACHE_FILE;\n if (configuredCachePath) {\n if (!existsSync(configuredCachePath)) {\n throw new Error(`Configured Codex model cache does not exist: ${configuredCachePath}`);\n }\n readCompatibleCodexModelCache(configuredCachePath);\n return configuredCachePath;\n }\n\n // The global Codex CLI owns models_cache.json and may update it to a schema\n // newer than the SDK bundled by Negotium. Snapshot a cache generated for our\n // exact bundled version so later global CLI updates cannot break turns.\n const bundledCachePath = bundledCodexModelCachePath(authFilePath);\n const sharedCachePath = join(codexHome, \"models_cache.json\");\n if (existsSync(sharedCachePath)) {\n try {\n const shared = readCompatibleCodexModelCache(sharedCachePath);\n // Keep model metadata fresh while the global CLI remains compatible.\n writePrivateFileAtomic(bundledCachePath, shared.contents);\n return bundledCachePath;\n } catch {\n // A compatible private snapshot is safer than failing because another\n // process briefly exposed an incomplete shared-cache write.\n }\n }\n\n if (existsSync(bundledCachePath)) {\n try {\n readCompatibleCodexModelCache(bundledCachePath);\n return bundledCachePath;\n } catch {\n // Re-bootstrap below instead of passing a corrupt or version-mismatched\n // private snapshot into this SDK version.\n }\n }\n\n const refreshedContents = await bootstrapIsolatedCodexModelCache(authFilePath, bootstrap);\n writePrivateFileAtomic(bundledCachePath, refreshedContents);\n return bundledCachePath;\n}\n\n/**\n * Codex can resolve model metadata before `features.multi_agent=false`, so a\n * model-advertised v1/v2 value may still register native collaboration tools.\n * Feed Codex an authoritative copy of its own catalog with only that field\n * disabled. Runtime MCP delegation remains available independently.\n */\nexport function writeCodexCatalogWithNativeMultiAgentDisabled(\n authFilePath: string,\n sourcePath: string,\n): string {\n const codexHome = dirname(authFilePath);\n const outputPath = join(codexHome, NEGOTIUM_MODEL_CATALOG);\n\n const parsed = readCodexModelCache(sourcePath).parsed;\n\n const models = (parsed.models as unknown[]).map((model, index): CodexModel => {\n if (!model || typeof model !== \"object\" || Array.isArray(model)) {\n throw new Error(`Codex model cache entry ${index} is invalid: ${sourcePath}`);\n }\n return { ...(model as CodexModel), multi_agent_version: \"disabled\" };\n });\n const contents = `${JSON.stringify({ models }, null, 2)}\\n`;\n writePrivateFileAtomic(outputPath, contents);\n return outputPath;\n}\n",
7
+ "export const NEGOTIUM_VERSION = \"0.23.2\";\n"
8
+ ],
9
+ "mappings": "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",
10
+ "debugId": "F52112FFE0B50C6764756E2164756E21",
11
+ "names": []
12
+ }
@@ -271,9 +271,14 @@ function agentAliases(agent) {
271
271
  return [
272
272
  "codex",
273
273
  "\uCF54\uB371\uC2A4",
274
+ "astra",
275
+ "sol",
276
+ "luna",
277
+ "terra",
274
278
  "gpt-6-luna",
275
279
  "gpt-6-sol",
276
280
  "gpt-5.6-luna",
281
+ "gpt-6.1-terra",
277
282
  "gpt-5.6-terra",
278
283
  "gpt-5.6-sol",
279
284
  "gpt-6-astra"
@@ -301,7 +306,7 @@ function hasExplicitAgentSwitchRequest(prompt, agent) {
301
306
  if (!prompt?.trim())
302
307
  return false;
303
308
  const text = prompt.toLowerCase().replace(/\s+/g, " ").trim();
304
- const target = `(?:${agentAliases(agent).map(escapeRegExp).join("|")})`;
309
+ const target = `(?<![A-Za-z0-9_-])(?:${agentAliases(agent).map(escapeRegExp).join("|")})(?![A-Za-z0-9_-])`;
305
310
  const switchVerb = "(?:\uBC14\uAFD4|\uBC14\uAFD4\uC918|\uBCC0\uACBD|\uBCC0\uACBD\uD574|\uC804\uD658|\uC804\uD658\uD574|\uC124\uC815|\uC124\uC815\uD574|\uC368\uC918|\uC0AC\uC6A9|\uAC00|switch|change|set|use)";
306
311
  const switchSubject = "(?:agent|runtime|model|\uC5D0\uC774\uC804\uD2B8|\uB7F0\uD0C0\uC784|\uBAA8\uB378)";
307
312
  return [
@@ -3590,18 +3595,30 @@ import {
3590
3595
  unlinkSync as unlinkSync3,
3591
3596
  writeFileSync as writeFileSync2
3592
3597
  } from "fs";
3593
- import { createRequire } from "module";
3594
3598
  import { tmpdir } from "os";
3595
3599
  import { dirname as dirname5, join as join3 } from "path";
3600
+ import { fileURLToPath } from "url";
3596
3601
 
3597
3602
  // ../../packages/core/src/version.ts
3598
- var NEGOTIUM_VERSION = "0.23.1";
3603
+ var NEGOTIUM_VERSION = "0.23.2";
3599
3604
 
3600
3605
  // ../../packages/core/src/agents/codex-native-multi-agent.ts
3601
- var moduleRequire = createRequire(import.meta.url);
3602
- var codexSdkPackagePath = moduleRequire.resolve("@openai/codex-sdk/package.json");
3603
- var codexSdkRequire = createRequire(codexSdkPackagePath);
3604
- var bundledCodexPackagePath = codexSdkRequire.resolve("@openai/codex/package.json");
3606
+ function findPackageJson(specifier, searchFromDir) {
3607
+ let dir = searchFromDir;
3608
+ for (;; ) {
3609
+ const candidate = join3(dir, "node_modules", specifier, "package.json");
3610
+ if (existsSync2(candidate))
3611
+ return candidate;
3612
+ const parent = dirname5(dir);
3613
+ if (parent === dir) {
3614
+ throw new Error(`Could not locate node_modules/${specifier} starting from ${searchFromDir}`);
3615
+ }
3616
+ dir = parent;
3617
+ }
3618
+ }
3619
+ var thisModuleDir = dirname5(fileURLToPath(import.meta.url));
3620
+ var codexSdkPackagePath = findPackageJson("@openai/codex-sdk", thisModuleDir);
3621
+ var bundledCodexPackagePath = findPackageJson("@openai/codex", dirname5(codexSdkPackagePath));
3605
3622
  function readPackageVersion(packageJsonPath) {
3606
3623
  const parsed = JSON.parse(readFileSync3(packageJsonPath, "utf8"));
3607
3624
  if (typeof parsed.version !== "string" || !parsed.version.trim()) {
@@ -3832,6 +3849,70 @@ function writeCodexCatalogWithNativeMultiAgentDisabled(authFilePath, sourcePath)
3832
3849
  return outputPath;
3833
3850
  }
3834
3851
 
3852
+ // ../../packages/core/src/agents/codex-tier-resolver.ts
3853
+ var CODEX_TIER_FALLBACKS = {
3854
+ astra: "gpt-6-astra",
3855
+ sol: "gpt-6-sol",
3856
+ luna: "gpt-6-luna",
3857
+ terra: "gpt-6.1-terra"
3858
+ };
3859
+ var warnedCachePaths = new Set;
3860
+ var warnedUnpricedSlugs = new Set;
3861
+ var pricedSlugs = new Set([
3862
+ "gpt-6-astra",
3863
+ "gpt-6-sol",
3864
+ "gpt-6-luna",
3865
+ "gpt-6.1-terra",
3866
+ "gpt-5.6-sol",
3867
+ "gpt-5.6-luna",
3868
+ "gpt-5.6-terra"
3869
+ ]);
3870
+ function codexTiersFromCache(cache) {
3871
+ const result = {};
3872
+ const priorities = {};
3873
+ if (!cache || typeof cache !== "object" || !("models" in cache))
3874
+ return result;
3875
+ const models = cache.models;
3876
+ if (!Array.isArray(models))
3877
+ return result;
3878
+ for (const model of models) {
3879
+ if (!model || typeof model !== "object")
3880
+ continue;
3881
+ const { slug, visibility, priority } = model;
3882
+ if (typeof slug !== "string" || visibility !== "list")
3883
+ continue;
3884
+ if (typeof priority !== "number" || !Number.isFinite(priority))
3885
+ continue;
3886
+ const suffix = slug.slice(slug.lastIndexOf("-") + 1);
3887
+ if (!Object.hasOwn(CODEX_TIER_FALLBACKS, suffix))
3888
+ continue;
3889
+ const tier = suffix;
3890
+ if (priorities[tier] === undefined || priority < priorities[tier]) {
3891
+ priorities[tier] = priority;
3892
+ result[tier] = slug;
3893
+ }
3894
+ }
3895
+ return result;
3896
+ }
3897
+ function resolveCodexTierModel(tier, cachePath = process.env.NEGOTIUM_CODEX_MODELS_CACHE_FILE ?? bundledCodexModelCachePath(hostedCodexAuthFilePath())) {
3898
+ try {
3899
+ const selected = codexTiersFromCache(readCompatibleCodexModelCache(cachePath).parsed)[tier];
3900
+ if (selected) {
3901
+ if (!pricedSlugs.has(selected) && !warnedUnpricedSlugs.has(selected)) {
3902
+ warnedUnpricedSlugs.add(selected);
3903
+ logger.warn({ tier, model: selected }, "Codex tier model has no token-stats price");
3904
+ }
3905
+ return selected;
3906
+ }
3907
+ } catch (error) {
3908
+ if (!warnedCachePaths.has(cachePath)) {
3909
+ warnedCachePaths.add(cachePath);
3910
+ logger.warn({ err: error, cachePath }, "Codex tier cache unavailable; using fallback ids");
3911
+ }
3912
+ }
3913
+ return CODEX_TIER_FALLBACKS[tier];
3914
+ }
3915
+
3835
3916
  // ../../packages/core/src/agents/codex-tree-kill.ts
3836
3917
  import { execFileSync as execFileSync2 } from "child_process";
3837
3918
 
@@ -4059,7 +4140,7 @@ import { chmod, copyFile, mkdtemp, rm as rm2, writeFile as writeFile2 } from "fs
4059
4140
  import { createServer } from "net";
4060
4141
  import { tmpdir as tmpdir2 } from "os";
4061
4142
  import { dirname as dirname6, join as join5, resolve as resolve5 } from "path";
4062
- import { fileURLToPath } from "url";
4143
+ import { fileURLToPath as fileURLToPath2 } from "url";
4063
4144
 
4064
4145
  // ../../packages/core/src/agents/codex-windows-wrapper.ts
4065
4146
  import { execFile } from "child_process";
@@ -4243,7 +4324,7 @@ function shellQuote(value) {
4243
4324
  return `'${value.replaceAll("'", `'"'"'`)}'`;
4244
4325
  }
4245
4326
  function hookClientPath() {
4246
- const moduleDir = dirname6(fileURLToPath(import.meta.url));
4327
+ const moduleDir = dirname6(fileURLToPath2(import.meta.url));
4247
4328
  const adjacent = resolve5(moduleDir, "codex-vault-hook.mjs");
4248
4329
  if (existsSync4(adjacent))
4249
4330
  return adjacent;
@@ -5177,6 +5258,7 @@ async function* codexProvider(opts) {
5177
5258
  ...codexEnvironment ? { env: codexEnvironment } : {},
5178
5259
  config: {
5179
5260
  agents: { enabled: false },
5261
+ tools: { update_plan: { enabled: false } },
5180
5262
  features: {
5181
5263
  hooks: true,
5182
5264
  goals: false,
@@ -5200,7 +5282,9 @@ async function* codexProvider(opts) {
5200
5282
  webSearchMode: "disabled",
5201
5283
  webSearchEnabled: false
5202
5284
  } : {},
5203
- ...opts.model ? { model: opts.model } : {},
5285
+ ...opts.model ? {
5286
+ model: Object.hasOwn(CODEX_TIER_FALLBACKS, opts.model) ? resolveCodexTierModel(opts.model) : opts.model
5287
+ } : {},
5204
5288
  ...opts.effort ? { modelReasoningEffort: mapEffort(opts.effort) } : {}
5205
5289
  };
5206
5290
  let currentSessionId = opts.sessionId;
@@ -5571,14 +5655,14 @@ function maestroProvider(opts) {
5571
5655
  }
5572
5656
  // ../../packages/core/src/agents/claude-runtime-inspection.ts
5573
5657
  import { readFileSync as readFileSync6 } from "fs";
5574
- import { createRequire as createRequire2 } from "module";
5658
+ import { createRequire } from "module";
5575
5659
  import { dirname as dirname9, join as join8 } from "path";
5576
5660
  var cached;
5577
5661
  function inspectBundledClaudeRuntime() {
5578
5662
  if (cached)
5579
5663
  return cached;
5580
5664
  try {
5581
- const require2 = createRequire2(import.meta.url);
5665
+ const require2 = createRequire(import.meta.url);
5582
5666
  const sdkDir = dirname9(require2.resolve("@anthropic-ai/claude-agent-sdk"));
5583
5667
  const sdkPackage = JSON.parse(readFileSync6(join8(sdkDir, "package.json"), "utf8"));
5584
5668
  const manifest = JSON.parse(readFileSync6(join8(sdkDir, "manifest.json"), "utf8"));
@@ -5654,4 +5738,4 @@ export {
5654
5738
  buildClaudeDisallowedTools
5655
5739
  };
5656
5740
 
5657
- //# debugId=B911FEB22E0F0C6764756E2164756E21
5741
+ //# debugId=ACCBAC7BC2F9084364756E2164756E21