negotium 0.1.12 → 0.1.13

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 (137) hide show
  1. package/dist/canonical-mcp-bridge.js +2 -3
  2. package/dist/canonical-mcp-bridge.js.map +1 -1
  3. package/dist/chunk-a9y2rwxf.js.map +1 -1
  4. package/dist/{chunk-j0kjscb7.js → chunk-s2gez3wg.js} +20 -2
  5. package/dist/{chunk-j0kjscb7.js.map → chunk-s2gez3wg.js.map} +2 -2
  6. package/dist/cron.js +49 -25
  7. package/dist/cron.js.map +15 -14
  8. package/dist/hosted-agent.js +3012 -17
  9. package/dist/hosted-agent.js.map +30 -3
  10. package/dist/main.js +31323 -36
  11. package/dist/main.js.map +198 -3
  12. package/dist/prompts.js +11 -8
  13. package/dist/prompts.js.map +4 -4
  14. package/dist/runtime/src/application/submit-user-message.ts +3 -0
  15. package/dist/runtime/src/index.ts +7 -0
  16. package/dist/runtime/src/mcp/runtime-spec.ts +3 -0
  17. package/dist/runtime/src/mcp/session-comm/server.ts +1 -1
  18. package/dist/runtime/src/platform/mcp-config.ts +13 -0
  19. package/dist/runtime/src/prompts/builders.ts +20 -6
  20. package/dist/runtime/src/query/active-rooms.ts +2 -0
  21. package/dist/runtime/src/runtime/delivery-ack.ts +112 -0
  22. package/dist/runtime/src/runtime/errors.ts +12 -12
  23. package/dist/runtime/src/runtime/turn-runner.ts +12 -0
  24. package/dist/runtime/src/storage/runtime-turn-requests.ts +1 -0
  25. package/dist/runtime/src/types/api.ts +2 -0
  26. package/dist/runtime/src/types.ts +2 -0
  27. package/dist/runtime/src/version.ts +1 -1
  28. package/dist/runtime-helpers.js.map +1 -1
  29. package/dist/storage.js.map +1 -1
  30. package/dist/types/packages/core/src/mcp/runtime-spec.d.ts +2 -0
  31. package/dist/types/packages/core/src/platform/mcp-config.d.ts +4 -0
  32. package/dist/types/packages/core/src/prompts/builders.d.ts +2 -0
  33. package/dist/types/packages/core/src/types/api.d.ts +2 -0
  34. package/dist/types/packages/core/src/types.d.ts +2 -0
  35. package/dist/types/packages/core/src/version.d.ts +1 -1
  36. package/dist/vault.js.map +1 -1
  37. package/package.json +1 -1
  38. package/dist/chunk-00q25k7p.js +0 -2387
  39. package/dist/chunk-00q25k7p.js.map +0 -26
  40. package/dist/chunk-03kv7mvj.js +0 -2152
  41. package/dist/chunk-03kv7mvj.js.map +0 -15
  42. package/dist/chunk-05pm51dh.js +0 -589
  43. package/dist/chunk-05pm51dh.js.map +0 -11
  44. package/dist/chunk-0eh16bk1.js +0 -2936
  45. package/dist/chunk-0eh16bk1.js.map +0 -20
  46. package/dist/chunk-0yfqyv88.js +0 -108
  47. package/dist/chunk-0yfqyv88.js.map +0 -10
  48. package/dist/chunk-1k7t7bnx.js +0 -97
  49. package/dist/chunk-1k7t7bnx.js.map +0 -10
  50. package/dist/chunk-3gkfr9vb.js +0 -431
  51. package/dist/chunk-3gkfr9vb.js.map +0 -11
  52. package/dist/chunk-5akd1gbj.js +0 -281
  53. package/dist/chunk-5akd1gbj.js.map +0 -10
  54. package/dist/chunk-7k19pcg8.js +0 -577
  55. package/dist/chunk-7k19pcg8.js.map +0 -14
  56. package/dist/chunk-81tbfbmt.js +0 -10
  57. package/dist/chunk-81tbfbmt.js.map +0 -10
  58. package/dist/chunk-82qhv1mq.js +0 -512
  59. package/dist/chunk-82qhv1mq.js.map +0 -13
  60. package/dist/chunk-8dy7e2a9.js +0 -103
  61. package/dist/chunk-8dy7e2a9.js.map +0 -10
  62. package/dist/chunk-8f2sqmrj.js +0 -1712
  63. package/dist/chunk-8f2sqmrj.js.map +0 -18
  64. package/dist/chunk-9hjeemfz.js +0 -372
  65. package/dist/chunk-9hjeemfz.js.map +0 -10
  66. package/dist/chunk-a4aa2ccv.js +0 -141
  67. package/dist/chunk-a4aa2ccv.js.map +0 -10
  68. package/dist/chunk-bsg215q3.js +0 -3536
  69. package/dist/chunk-bsg215q3.js.map +0 -20
  70. package/dist/chunk-bxnfsc7w.js +0 -58
  71. package/dist/chunk-bxnfsc7w.js.map +0 -10
  72. package/dist/chunk-c500xe9z.js +0 -33
  73. package/dist/chunk-c500xe9z.js.map +0 -10
  74. package/dist/chunk-cngrf7ab.js +0 -149
  75. package/dist/chunk-cngrf7ab.js.map +0 -10
  76. package/dist/chunk-d7tprf06.js +0 -53
  77. package/dist/chunk-d7tprf06.js.map +0 -10
  78. package/dist/chunk-ddnrmkrv.js +0 -61
  79. package/dist/chunk-ddnrmkrv.js.map +0 -10
  80. package/dist/chunk-edb07sjp.js +0 -567
  81. package/dist/chunk-edb07sjp.js.map +0 -14
  82. package/dist/chunk-ejcm6zx8.js +0 -591
  83. package/dist/chunk-ejcm6zx8.js.map +0 -11
  84. package/dist/chunk-ezs352qs.js +0 -237
  85. package/dist/chunk-ezs352qs.js.map +0 -11
  86. package/dist/chunk-f5xgprg1.js +0 -59
  87. package/dist/chunk-f5xgprg1.js.map +0 -10
  88. package/dist/chunk-fbtb3v0s.js +0 -1339
  89. package/dist/chunk-fbtb3v0s.js.map +0 -16
  90. package/dist/chunk-ffefbd3r.js +0 -17
  91. package/dist/chunk-ffefbd3r.js.map +0 -10
  92. package/dist/chunk-gaknyw04.js +0 -708
  93. package/dist/chunk-gaknyw04.js.map +0 -14
  94. package/dist/chunk-gxmny6tq.js +0 -1637
  95. package/dist/chunk-gxmny6tq.js.map +0 -15
  96. package/dist/chunk-h7bj5zwb.js +0 -3069
  97. package/dist/chunk-h7bj5zwb.js.map +0 -32
  98. package/dist/chunk-hp4g7wx7.js +0 -46
  99. package/dist/chunk-hp4g7wx7.js.map +0 -10
  100. package/dist/chunk-hwy3n31w.js +0 -21
  101. package/dist/chunk-hwy3n31w.js.map +0 -9
  102. package/dist/chunk-jzz91jwh.js +0 -70
  103. package/dist/chunk-jzz91jwh.js.map +0 -10
  104. package/dist/chunk-k778y16p.js +0 -153
  105. package/dist/chunk-k778y16p.js.map +0 -11
  106. package/dist/chunk-mh5mexsf.js +0 -147
  107. package/dist/chunk-mh5mexsf.js.map +0 -11
  108. package/dist/chunk-mnwaext5.js +0 -318
  109. package/dist/chunk-mnwaext5.js.map +0 -10
  110. package/dist/chunk-nkgs40ch.js +0 -23
  111. package/dist/chunk-nkgs40ch.js.map +0 -10
  112. package/dist/chunk-pz57vwsm.js +0 -250
  113. package/dist/chunk-pz57vwsm.js.map +0 -11
  114. package/dist/chunk-r6kdp7gn.js +0 -252
  115. package/dist/chunk-r6kdp7gn.js.map +0 -10
  116. package/dist/chunk-rkvrkcgx.js +0 -117
  117. package/dist/chunk-rkvrkcgx.js.map +0 -10
  118. package/dist/chunk-s74rdyqe.js +0 -117
  119. package/dist/chunk-s74rdyqe.js.map +0 -12
  120. package/dist/chunk-sa874j5c.js +0 -9
  121. package/dist/chunk-sa874j5c.js.map +0 -10
  122. package/dist/chunk-sffqdkvq.js +0 -122
  123. package/dist/chunk-sffqdkvq.js.map +0 -10
  124. package/dist/chunk-tcs9qjps.js +0 -64
  125. package/dist/chunk-tcs9qjps.js.map +0 -10
  126. package/dist/chunk-wx83ep8e.js +0 -131
  127. package/dist/chunk-wx83ep8e.js.map +0 -10
  128. package/dist/chunk-xag86ng3.js +0 -122
  129. package/dist/chunk-xag86ng3.js.map +0 -10
  130. package/dist/chunk-xfdkep71.js +0 -371
  131. package/dist/chunk-xfdkep71.js.map +0 -11
  132. package/dist/chunk-xhm1rfpt.js +0 -2907
  133. package/dist/chunk-xhm1rfpt.js.map +0 -24
  134. package/dist/chunk-xpcps28p.js +0 -2138
  135. package/dist/chunk-xpcps28p.js.map +0 -29
  136. package/dist/chunk-yb4rbev9.js +0 -214
  137. package/dist/chunk-yb4rbev9.js.map +0 -10
@@ -1,122 +0,0 @@
1
- import {
2
- Database
3
- } from "./chunk-f5xgprg1.js";
4
-
5
- // ../../packages/core/src/storage/storage-host.ts
6
- import { mkdirSync } from "fs";
7
- import { homedir } from "os";
8
- import { dirname, join, resolve } from "path";
9
- var configuredHost = {};
10
- var fallbackDatabase = null;
11
- var fallbackDatabasePath = null;
12
- var schemaInitializers = [];
13
- var initializedSchemas = new WeakMap;
14
- var initializingDatabases = new WeakSet;
15
- function envPath(name, fallback) {
16
- const value = process.env[name]?.trim();
17
- return resolve(value || fallback);
18
- }
19
- function defaultStateDir() {
20
- return envPath("NEGOTIUM_STATE_DIR", join(homedir(), ".negotium"));
21
- }
22
- function defaultDataDir() {
23
- return envPath("NEGOTIUM_DATA_DIR", join(defaultStateDir(), "data"));
24
- }
25
- function defaultLogDir() {
26
- return envPath("NEGOTIUM_LOG_DIR", join(defaultStateDir(), "logs"));
27
- }
28
- function defaultWorkspaceDir() {
29
- return envPath("NEGOTIUM_WORKSPACE_DIR", join(defaultStateDir(), "workspace"));
30
- }
31
- function defaultSessionAsksDir() {
32
- const runDir = envPath("NEGOTIUM_RUN_DIR", join(defaultStateDir(), "run"));
33
- return join(runDir, "session-asks");
34
- }
35
- function defaultSessionsDatabasePath() {
36
- return envPath("SESSIONS_DB_PATH", join(resolveStorageDataDir(), "sessions.db"));
37
- }
38
- function initializeDatabase(database) {
39
- database.exec("PRAGMA journal_mode = WAL");
40
- database.exec("PRAGMA foreign_keys = ON");
41
- database.exec("PRAGMA busy_timeout = 5000");
42
- database.exec("PRAGMA wal_autocheckpoint = 1000");
43
- try {
44
- database.exec("PRAGMA wal_checkpoint(TRUNCATE)");
45
- } catch {}
46
- }
47
- function defaultDatabase() {
48
- const path = defaultSessionsDatabasePath();
49
- if (fallbackDatabase && fallbackDatabasePath === path)
50
- return fallbackDatabase;
51
- if (fallbackDatabase)
52
- fallbackDatabase.close();
53
- mkdirSync(dirname(path), { recursive: true });
54
- fallbackDatabase = new Database(path, { create: true });
55
- fallbackDatabasePath = path;
56
- initializeDatabase(fallbackDatabase);
57
- return fallbackDatabase;
58
- }
59
- function resolveStorageDatabase() {
60
- return configuredHost.database ?? defaultDatabase();
61
- }
62
- function resolveStorageDataDir() {
63
- return configuredHost.dataDir ?? defaultDataDir();
64
- }
65
- function resolveStorageLogDir() {
66
- return configuredHost.logDir ?? defaultLogDir();
67
- }
68
- function resolveStorageSessionAsksDir() {
69
- return configuredHost.sessionAsksDir ?? defaultSessionAsksDir();
70
- }
71
- function resolveStorageWorkspaceDir() {
72
- return configuredHost.workspaceDir ?? defaultWorkspaceDir();
73
- }
74
- function resolveStorageSharedWikiDir() {
75
- return configuredHost.sharedWikiDir ?? join(resolveStorageWorkspaceDir(), "wiki");
76
- }
77
- function registerStorageSchemaInitializer(initialize, priority = 100) {
78
- schemaInitializers.push({ initialize, priority });
79
- schemaInitializers.sort((a, b) => a.priority - b.priority);
80
- }
81
- function ensureStorageSchemas(database = resolveStorageDatabase()) {
82
- if (initializingDatabases.has(database))
83
- return;
84
- let initialized = initializedSchemas.get(database);
85
- if (!initialized) {
86
- initialized = new Set;
87
- initializedSchemas.set(database, initialized);
88
- }
89
- initializingDatabases.add(database);
90
- try {
91
- for (const entry of schemaInitializers) {
92
- if (initialized.has(entry.initialize))
93
- continue;
94
- initialized.add(entry.initialize);
95
- try {
96
- entry.initialize(database);
97
- } catch (error) {
98
- initialized.delete(entry.initialize);
99
- throw error;
100
- }
101
- }
102
- } finally {
103
- initializingDatabases.delete(database);
104
- }
105
- }
106
- var internalStorageDatabase = new Proxy({}, {
107
- get(_target, property) {
108
- const database = resolveStorageDatabase();
109
- ensureStorageSchemas(database);
110
- const value = Reflect.get(database, property, database);
111
- return typeof value === "function" ? value.bind(database) : value;
112
- },
113
- set(_target, property, value) {
114
- const database = resolveStorageDatabase();
115
- ensureStorageSchemas(database);
116
- return Reflect.set(database, property, value, database);
117
- }
118
- });
119
-
120
- export { resolveStorageDataDir, resolveStorageLogDir, resolveStorageSessionAsksDir, resolveStorageWorkspaceDir, resolveStorageSharedWikiDir, registerStorageSchemaInitializer, internalStorageDatabase };
121
-
122
- //# debugId=533731B61A441E3A64756E2164756E21
@@ -1,10 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../packages/core/src/storage/storage-host.ts"],
4
- "sourcesContent": [
5
- "import { mkdirSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { Database } from \"#storage/sqlite\";\nimport type { StorageDatabase, StorageHostConfig } from \"#storage/storage-contract\";\n\nexport type {\n StorageDatabase,\n StorageDatabaseAdapter,\n StorageDatabaseInput,\n StorageHostConfig,\n StorageHostOptions,\n StorageStatement,\n StorageTransaction,\n} from \"#storage/storage-contract\";\n\nlet configuredHost: Readonly<StorageHostConfig> = {};\ntype InternalStorageDatabase = InstanceType<typeof Database>;\ntype OwnedStorageDatabase = InternalStorageDatabase & { close(): void };\nlet fallbackDatabase: OwnedStorageDatabase | null = null;\nlet fallbackDatabasePath: string | null = null;\n\ninterface StorageHostFrame {\n active: boolean;\n patch: Readonly<StorageHostConfig>;\n}\n\nconst storageHostFrames: StorageHostFrame[] = [];\n\ntype StorageSchemaInitializer = (database: InternalStorageDatabase) => void;\ninterface RegisteredSchemaInitializer {\n initialize: StorageSchemaInitializer;\n priority: number;\n}\n\nconst schemaInitializers: RegisteredSchemaInitializer[] = [];\nconst initializedSchemas = new WeakMap<InternalStorageDatabase, Set<StorageSchemaInitializer>>();\nconst initializingDatabases = new WeakSet<InternalStorageDatabase>();\n\nfunction envPath(name: string, fallback: string): string {\n const value = process.env[name]?.trim();\n return resolve(value || fallback);\n}\n\nfunction defaultStateDir(): string {\n return envPath(\"NEGOTIUM_STATE_DIR\", join(homedir(), \".negotium\"));\n}\n\nfunction defaultDataDir(): string {\n return envPath(\"NEGOTIUM_DATA_DIR\", join(defaultStateDir(), \"data\"));\n}\n\nfunction defaultLogDir(): string {\n return envPath(\"NEGOTIUM_LOG_DIR\", join(defaultStateDir(), \"logs\"));\n}\n\nfunction defaultWorkspaceDir(): string {\n return envPath(\"NEGOTIUM_WORKSPACE_DIR\", join(defaultStateDir(), \"workspace\"));\n}\n\nfunction defaultSessionAsksDir(): string {\n const runDir = envPath(\"NEGOTIUM_RUN_DIR\", join(defaultStateDir(), \"run\"));\n return join(runDir, \"session-asks\");\n}\n\nfunction defaultSessionsDatabasePath(): string {\n return envPath(\"SESSIONS_DB_PATH\", join(resolveStorageDataDir(), \"sessions.db\"));\n}\n\nfunction initializeDatabase(database: InternalStorageDatabase): void {\n database.exec(\"PRAGMA journal_mode = WAL\");\n database.exec(\"PRAGMA foreign_keys = ON\");\n database.exec(\"PRAGMA busy_timeout = 5000\");\n database.exec(\"PRAGMA wal_autocheckpoint = 1000\");\n try {\n database.exec(\"PRAGMA wal_checkpoint(TRUNCATE)\");\n } catch {\n // Non-fatal; a concurrent writer may hold the WAL briefly.\n }\n}\n\nfunction defaultDatabase(): InternalStorageDatabase {\n const path = defaultSessionsDatabasePath();\n if (fallbackDatabase && fallbackDatabasePath === path) return fallbackDatabase;\n if (fallbackDatabase) fallbackDatabase.close();\n mkdirSync(dirname(path), { recursive: true });\n fallbackDatabase = new Database(path, { create: true }) as unknown as OwnedStorageDatabase;\n fallbackDatabasePath = path;\n initializeDatabase(fallbackDatabase);\n return fallbackDatabase;\n}\n\nexport function resolveStorageDatabase(): InternalStorageDatabase {\n return (configuredHost.database ?? defaultDatabase()) as InternalStorageDatabase;\n}\n\nexport function resolveStorageDataDir(): string {\n return configuredHost.dataDir ?? defaultDataDir();\n}\n\nexport function resolveStorageLogDir(): string {\n return configuredHost.logDir ?? defaultLogDir();\n}\n\nexport function resolveStorageSessionAsksDir(): string {\n return configuredHost.sessionAsksDir ?? defaultSessionAsksDir();\n}\n\nexport function resolveStorageWorkspaceDir(): string {\n return configuredHost.workspaceDir ?? defaultWorkspaceDir();\n}\n\nexport function resolveStorageSharedWikiDir(): string {\n return configuredHost.sharedWikiDir ?? join(resolveStorageWorkspaceDir(), \"wiki\");\n}\n\nexport function resolveStorageUsersLogDir(): string {\n return configuredHost.usersLogDir ?? join(resolveStorageDataDir(), \"users\");\n}\n\nconst STORAGE_PATH_KEYS = [\n \"dataDir\",\n \"logDir\",\n \"sessionAsksDir\",\n \"workspaceDir\",\n \"sharedWikiDir\",\n \"usersLogDir\",\n] as const;\n\nfunction normalizeStorageHostPatch(options: StorageHostConfig): Readonly<StorageHostConfig> {\n const patch: StorageHostConfig = {};\n if (options.database !== undefined) patch.database = options.database;\n for (const key of STORAGE_PATH_KEYS) {\n const value = options[key];\n if (value === undefined) continue;\n if (!value.trim()) throw new TypeError(`${key} must not be empty`);\n patch[key] = resolve(value);\n }\n return Object.freeze(patch);\n}\n\nfunction refreshConfiguredHost(): void {\n configuredHost = Object.freeze(\n Object.assign(\n {},\n ...storageHostFrames.filter((frame) => frame.active).map((frame) => frame.patch),\n ),\n );\n}\n\n/**\n * Configure the process-local storage boundary for an embedding host.\n *\n * Resolution is lazy: importing `negotium/storage` never opens a database or\n * touches a filesystem path. The returned disposer restores the exact prior\n * host, which keeps tests and nested embeddings isolated.\n */\nexport function configureStorageHost(options: StorageHostConfig): () => void {\n const frame: StorageHostFrame = { active: true, patch: normalizeStorageHostPatch(options) };\n storageHostFrames.push(frame);\n refreshConfiguredHost();\n return () => {\n if (!frame.active) return;\n frame.active = false;\n const index = storageHostFrames.indexOf(frame);\n if (index >= 0) storageHostFrames.splice(index, 1);\n refreshConfiguredHost();\n };\n}\n\n/** Remove every configured host layer and restore standalone fallbacks. */\nexport function resetStorageHost(): void {\n for (const frame of storageHostFrames) frame.active = false;\n storageHostFrames.length = 0;\n refreshConfiguredHost();\n}\n\n/** Close only Negotium's fallback connection. Injected connections are borrowed. */\nexport function closeStorageDatabase(): void {\n if (!fallbackDatabase) return;\n fallbackDatabase.close();\n fallbackDatabase = null;\n fallbackDatabasePath = null;\n}\n\nexport function registerStorageSchemaInitializer(\n initialize: StorageSchemaInitializer,\n priority = 100,\n): void {\n schemaInitializers.push({ initialize, priority });\n schemaInitializers.sort((a, b) => a.priority - b.priority);\n}\n\nexport function ensureStorageSchemas(\n database: InternalStorageDatabase = resolveStorageDatabase(),\n): void {\n if (initializingDatabases.has(database)) return;\n let initialized = initializedSchemas.get(database);\n if (!initialized) {\n initialized = new Set();\n initializedSchemas.set(database, initialized);\n }\n initializingDatabases.add(database);\n try {\n for (const entry of schemaInitializers) {\n if (initialized.has(entry.initialize)) continue;\n // Mark first so a migration that calls through the public db proxy does\n // not recursively invoke itself. Remove on failure so the next call can retry.\n initialized.add(entry.initialize);\n try {\n entry.initialize(database);\n } catch (error) {\n initialized.delete(entry.initialize);\n throw error;\n }\n }\n } finally {\n initializingDatabases.delete(database);\n }\n}\n\n/** Stable proxy identity used by legacy imports and embedding hosts. */\nexport const internalStorageDatabase = new Proxy({} as InternalStorageDatabase, {\n get(_target, property) {\n const database = resolveStorageDatabase();\n ensureStorageSchemas(database);\n const value = Reflect.get(database as object, property, database);\n return typeof value === \"function\" ? value.bind(database) : value;\n },\n set(_target, property, value) {\n const database = resolveStorageDatabase();\n ensureStorageSchemas(database);\n return Reflect.set(database as object, property, value, database);\n },\n});\n\n/** Structurally typed view intended for embedding hosts. */\nexport const storageDatabase = internalStorageDatabase as unknown as StorageDatabase;\n"
6
- ],
7
- "mappings": "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",
8
- "debugId": "533731B61A441E3A64756E2164756E21",
9
- "names": []
10
- }
@@ -1,64 +0,0 @@
1
- // @bun
2
- import {
3
- codexAuthFilePath
4
- } from "./chunk-ezs352qs.js";
5
- import"./chunk-ffefbd3r.js";
6
- import"./chunk-hwy3n31w.js";
7
-
8
- // ../../packages/core/src/agents/auth-check.ts
9
- import { execFileSync } from "child_process";
10
- import { existsSync } from "fs";
11
- import { homedir, platform } from "os";
12
- import { join } from "path";
13
- function checkAgentAuth(agent) {
14
- switch (agent) {
15
- case "codex": {
16
- const path = codexAuthFilePath();
17
- if (existsSync(path))
18
- return { ok: true };
19
- return {
20
- ok: false,
21
- error: `codex is not logged in (auth file missing at ${path}). Run \`codex login\` first`
22
- };
23
- }
24
- case "claude": {
25
- if (process.env.ANTHROPIC_API_KEY)
26
- return { ok: true };
27
- if (platform() === "darwin") {
28
- try {
29
- execFileSync("security", ["find-generic-password", "-s", "Claude Code-credentials"], {
30
- stdio: "ignore"
31
- });
32
- return { ok: true };
33
- } catch {
34
- return {
35
- ok: false,
36
- error: "claude is not logged in (no macOS keychain entry 'Claude Code-credentials'). Run `claude` and complete login first"
37
- };
38
- }
39
- }
40
- const path = join(homedir(), ".claude", ".credentials.json");
41
- if (existsSync(path))
42
- return { ok: true };
43
- return {
44
- ok: false,
45
- error: `claude is not logged in (credentials missing at ${path}). Run \`claude\` and complete login first`
46
- };
47
- }
48
- case "maestro": {
49
- if (process.env.DEEPSEEK_API_KEY)
50
- return { ok: true };
51
- return {
52
- ok: false,
53
- error: "maestro is not authenticated (DEEPSEEK_API_KEY env var not set)"
54
- };
55
- }
56
- }
57
- }
58
- export {
59
- checkAgentAuth
60
- };
61
-
62
- export { checkAgentAuth };
63
-
64
- //# debugId=68DB86846946146464756E2164756E21
@@ -1,10 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../packages/core/src/agents/auth-check.ts"],
4
- "sourcesContent": [
5
- "/**\n * Cheap pre-flight auth check used to block agent switches that would\n * otherwise flip the topic to a backend the user hasn't logged into,\n * surfacing as a per-turn opaque error inside the provider. Runtime\n * failures (revoked tokens, expired sessions) still classify normally\n * via `event-processor.classifyError`.\n *\n * Each branch mirrors the auth mechanism the matching provider uses:\n * - codex: `~/.codex/auth.json` (override `NEGOTIUM_CODEX_AUTH_FILE`)\n * - claude: `ANTHROPIC_API_KEY` env, else macOS keychain entry\n * `Claude Code-credentials`, else `~/.claude/.credentials.json`\n * - maestro: `DEEPSEEK_API_KEY` env\n */\nimport { execFileSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { homedir, platform } from \"node:os\";\nimport { join } from \"node:path\";\nimport { codexAuthFilePath } from \"#platform/config\";\nimport type { AgentKind } from \"#types\";\n\nexport type AuthCheckResult = { ok: true } | { ok: false; error: string };\n\nexport function checkAgentAuth(agent: AgentKind): AuthCheckResult {\n switch (agent) {\n case \"codex\": {\n const path = codexAuthFilePath();\n if (existsSync(path)) return { ok: true };\n return {\n ok: false,\n error: `codex is not logged in (auth file missing at ${path}). Run \\`codex login\\` first`,\n };\n }\n case \"claude\": {\n if (process.env.ANTHROPIC_API_KEY) return { ok: true };\n if (platform() === \"darwin\") {\n try {\n execFileSync(\"security\", [\"find-generic-password\", \"-s\", \"Claude Code-credentials\"], {\n stdio: \"ignore\",\n });\n return { ok: true };\n } catch {\n return {\n ok: false,\n error:\n \"claude is not logged in (no macOS keychain entry 'Claude Code-credentials'). Run `claude` and complete login first\",\n };\n }\n }\n const path = join(homedir(), \".claude\", \".credentials.json\");\n if (existsSync(path)) return { ok: true };\n return {\n ok: false,\n error: `claude is not logged in (credentials missing at ${path}). Run \\`claude\\` and complete login first`,\n };\n }\n case \"maestro\": {\n if (process.env.DEEPSEEK_API_KEY) return { ok: true };\n return {\n ok: false,\n error: \"maestro is not authenticated (DEEPSEEK_API_KEY env var not set)\",\n };\n }\n }\n}\n"
6
- ],
7
- "mappings": ";;;;;;;;AAaA;AACA;AACA;AACA;AAMO,SAAS,cAAc,CAAC,OAAmC;AAAA,EAChE,QAAQ;AAAA,SACD,SAAS;AAAA,MACZ,MAAM,OAAO,kBAAkB;AAAA,MAC/B,IAAI,WAAW,IAAI;AAAA,QAAG,OAAO,EAAE,IAAI,KAAK;AAAA,MACxC,OAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAO,gDAAgD;AAAA,MACzD;AAAA,IACF;AAAA,SACK,UAAU;AAAA,MACb,IAAI,QAAQ,IAAI;AAAA,QAAmB,OAAO,EAAE,IAAI,KAAK;AAAA,MACrD,IAAI,SAAS,MAAM,UAAU;AAAA,QAC3B,IAAI;AAAA,UACF,aAAa,YAAY,CAAC,yBAAyB,MAAM,yBAAyB,GAAG;AAAA,YACnF,OAAO;AAAA,UACT,CAAC;AAAA,UACD,OAAO,EAAE,IAAI,KAAK;AAAA,UAClB,MAAM;AAAA,UACN,OAAO;AAAA,YACL,IAAI;AAAA,YACJ,OACE;AAAA,UACJ;AAAA;AAAA,MAEJ;AAAA,MACA,MAAM,OAAO,KAAK,QAAQ,GAAG,WAAW,mBAAmB;AAAA,MAC3D,IAAI,WAAW,IAAI;AAAA,QAAG,OAAO,EAAE,IAAI,KAAK;AAAA,MACxC,OAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAO,mDAAmD;AAAA,MAC5D;AAAA,IACF;AAAA,SACK,WAAW;AAAA,MACd,IAAI,QAAQ,IAAI;AAAA,QAAkB,OAAO,EAAE,IAAI,KAAK;AAAA,MACpD,OAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAO;AAAA,MACT;AAAA,IACF;AAAA;AAAA;",
8
- "debugId": "68DB86846946146464756E2164756E21",
9
- "names": []
10
- }
@@ -1,131 +0,0 @@
1
- // @bun
2
- import {
3
- db
4
- } from "./chunk-81tbfbmt.js";
5
- import {
6
- registerStorageSchemaInitializer
7
- } from "./chunk-sffqdkvq.js";
8
- import"./chunk-f5xgprg1.js";
9
- import"./chunk-hwy3n31w.js";
10
-
11
- // ../../packages/core/src/storage/api-topic-config.ts
12
- function tableColumns(table) {
13
- const rows = db.query(`PRAGMA table_info(${table})`).all();
14
- return new Set(rows.map((row) => row.name));
15
- }
16
- function createCanonicalConfigTable(name = "api_topic_config") {
17
- db.exec(`
18
- CREATE TABLE IF NOT EXISTS ${name} (
19
- topic_id TEXT PRIMARY KEY REFERENCES api_topics(id) ON DELETE CASCADE,
20
- model TEXT,
21
- effort TEXT CHECK (effort IS NULL OR effort IN ('low','medium','high','xhigh','max')),
22
- mcp TEXT,
23
- agent_locked INTEGER NOT NULL DEFAULT 0 CHECK (agent_locked IN (0,1)),
24
- model_locked INTEGER NOT NULL DEFAULT 0 CHECK (model_locked IN (0,1)),
25
- effort_locked INTEGER NOT NULL DEFAULT 0 CHECK (effort_locked IN (0,1))
26
- )
27
- `);
28
- }
29
- function initializeApiTopicConfigSchema() {
30
- const existingConfigColumns = tableColumns("api_topic_config");
31
- if (existingConfigColumns.size === 0) {
32
- createCanonicalConfigTable();
33
- } else if (existingConfigColumns.has("agent") || existingConfigColumns.has("agent_pinned") || existingConfigColumns.has("runtime_locked") || existingConfigColumns.has("model_pinned") || existingConfigColumns.has("effort_pinned") || existingConfigColumns.has("last_shown_agent")) {
34
- const topicColumns = tableColumns("api_topics");
35
- const agentColumn = topicColumns.has("agent") ? "agent" : topicColumns.has("runtime_agent") ? "runtime_agent" : null;
36
- if (agentColumn && existingConfigColumns.has("agent")) {
37
- db.exec(`UPDATE api_topics
38
- SET ${agentColumn} = (
39
- SELECT c.agent FROM api_topic_config c WHERE c.topic_id = api_topics.id
40
- )
41
- WHERE ${agentColumn} IS NULL
42
- AND EXISTS (
43
- SELECT 1 FROM api_topic_config c
44
- WHERE c.topic_id = api_topics.id AND c.agent IS NOT NULL
45
- )`);
46
- }
47
- const previousForeignKeys = db.query("PRAGMA foreign_keys").get()?.foreign_keys;
48
- db.exec("PRAGMA foreign_keys = OFF");
49
- try {
50
- const agentLockSource = existingConfigColumns.has("runtime_locked") ? "runtime_locked" : existingConfigColumns.has("agent_pinned") ? "agent_pinned" : "0";
51
- const modelLockSource = existingConfigColumns.has("model_locked") ? "model_locked" : existingConfigColumns.has("model_pinned") ? "model_pinned" : "0";
52
- const effortLockSource = existingConfigColumns.has("effort_locked") ? "effort_locked" : existingConfigColumns.has("effort_pinned") ? "effort_pinned" : "0";
53
- db.transaction(() => {
54
- createCanonicalConfigTable("api_topic_config_next");
55
- db.exec(`
56
- INSERT INTO api_topic_config_next
57
- (topic_id, model, effort, mcp, agent_locked, model_locked, effort_locked)
58
- SELECT
59
- topic_id,
60
- model,
61
- effort,
62
- mcp,
63
- COALESCE(${agentLockSource}, 0),
64
- COALESCE(${modelLockSource}, 0),
65
- COALESCE(${effortLockSource}, 0)
66
- FROM api_topic_config
67
- WHERE EXISTS (SELECT 1 FROM api_topics t WHERE t.id = api_topic_config.topic_id)
68
- `);
69
- db.exec("DROP TABLE api_topic_config");
70
- db.exec("ALTER TABLE api_topic_config_next RENAME TO api_topic_config");
71
- })();
72
- } finally {
73
- db.exec(`PRAGMA foreign_keys = ${previousForeignKeys ? "ON" : "OFF"}`);
74
- }
75
- } else {
76
- createCanonicalConfigTable();
77
- }
78
- }
79
- registerStorageSchemaInitializer(initializeApiTopicConfigSchema, 40);
80
- function rowToConfig(r) {
81
- const cfg = {};
82
- if (r.model)
83
- cfg.model = r.model;
84
- if (r.effort)
85
- cfg.effort = r.effort;
86
- if (r.mcp) {
87
- try {
88
- const parsed = JSON.parse(r.mcp);
89
- if (Array.isArray(parsed))
90
- cfg.mcp = parsed;
91
- } catch {}
92
- }
93
- if (r.agent_locked)
94
- cfg.agentLocked = true;
95
- if (r.model_locked)
96
- cfg.modelLocked = true;
97
- if (r.effort_locked)
98
- cfg.effortLocked = true;
99
- return cfg;
100
- }
101
- function getApiTopicConfig(topicId) {
102
- const row = db.query("SELECT topic_id, model, effort, mcp, agent_locked, model_locked, effort_locked FROM api_topic_config WHERE topic_id = ?").get(topicId);
103
- if (!row)
104
- return;
105
- const config = rowToConfig(row);
106
- return Object.keys(config).length > 0 ? config : undefined;
107
- }
108
- function setApiTopicConfig(topicId, config) {
109
- db.query(`INSERT INTO api_topic_config
110
- (topic_id, model, effort, mcp, agent_locked, model_locked, effort_locked)
111
- VALUES (?, ?, ?, ?, ?, ?, ?)
112
- ON CONFLICT(topic_id) DO UPDATE SET
113
- model = excluded.model,
114
- effort = excluded.effort,
115
- mcp = excluded.mcp,
116
- agent_locked = excluded.agent_locked,
117
- model_locked = excluded.model_locked,
118
- effort_locked = excluded.effort_locked`).run(topicId, config.model ?? null, config.effort ?? null, config.mcp ? JSON.stringify(config.mcp) : null, config.agentLocked ? 1 : 0, config.modelLocked ? 1 : 0, config.effortLocked ? 1 : 0);
119
- }
120
- function deleteApiTopicConfig(topicId) {
121
- db.query("DELETE FROM api_topic_config WHERE topic_id = ?").run(topicId);
122
- }
123
- export {
124
- setApiTopicConfig,
125
- getApiTopicConfig,
126
- deleteApiTopicConfig
127
- };
128
-
129
- export { getApiTopicConfig, setApiTopicConfig, deleteApiTopicConfig };
130
-
131
- //# debugId=1504C8C414D4E59064756E2164756E21
@@ -1,10 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../packages/core/src/storage/api-topic-config.ts"],
4
- "sourcesContent": [
5
- "// Persistent per-topic model/effort/MCP overrides and user locks.\n// SQLite. Mirrors api-topics.ts. This replaces the previous in-memory Map in\n// routes/topic-config.ts, which lost every override on server restart — a\n// regression now that topic config is the canonical path for model/effort\n// switching (the MCP-based direction), not just a transient convenience.\nimport { db } from \"#storage/forum-db\";\nimport { registerStorageSchemaInitializer } from \"#storage/storage-host\";\nimport type { EffortLevel } from \"#types\";\n\nfunction tableColumns(table: string): Set<string> {\n const rows = db.query(`PRAGMA table_info(${table})`).all() as Array<{ name: string }>;\n return new Set(rows.map((row) => row.name));\n}\n\nfunction createCanonicalConfigTable(name = \"api_topic_config\"): void {\n db.exec(`\n CREATE TABLE IF NOT EXISTS ${name} (\n topic_id TEXT PRIMARY KEY REFERENCES api_topics(id) ON DELETE CASCADE,\n model TEXT,\n effort TEXT CHECK (effort IS NULL OR effort IN ('low','medium','high','xhigh','max')),\n mcp TEXT,\n agent_locked INTEGER NOT NULL DEFAULT 0 CHECK (agent_locked IN (0,1)),\n model_locked INTEGER NOT NULL DEFAULT 0 CHECK (model_locked IN (0,1)),\n effort_locked INTEGER NOT NULL DEFAULT 0 CHECK (effort_locked IN (0,1))\n )\n `);\n}\n\nfunction initializeApiTopicConfigSchema(): void {\n const existingConfigColumns = tableColumns(\"api_topic_config\");\n if (existingConfigColumns.size === 0) {\n createCanonicalConfigTable();\n } else if (\n existingConfigColumns.has(\"agent\") ||\n existingConfigColumns.has(\"agent_pinned\") ||\n existingConfigColumns.has(\"runtime_locked\") ||\n existingConfigColumns.has(\"model_pinned\") ||\n existingConfigColumns.has(\"effort_pinned\") ||\n existingConfigColumns.has(\"last_shown_agent\")\n ) {\n // Complete the old agent-override migration before dropping the column. The\n // selected agent itself belongs to api_topics; only its user lock belongs here.\n const topicColumns = tableColumns(\"api_topics\");\n const agentColumn = topicColumns.has(\"agent\")\n ? \"agent\"\n : topicColumns.has(\"runtime_agent\")\n ? \"runtime_agent\"\n : null;\n if (agentColumn && existingConfigColumns.has(\"agent\")) {\n db.exec(\n `UPDATE api_topics\n SET ${agentColumn} = (\n SELECT c.agent FROM api_topic_config c WHERE c.topic_id = api_topics.id\n )\n WHERE ${agentColumn} IS NULL\n AND EXISTS (\n SELECT 1 FROM api_topic_config c\n WHERE c.topic_id = api_topics.id AND c.agent IS NOT NULL\n )`,\n );\n }\n\n const previousForeignKeys = db\n .query<{ foreign_keys: number }, []>(\"PRAGMA foreign_keys\")\n .get()?.foreign_keys;\n db.exec(\"PRAGMA foreign_keys = OFF\");\n try {\n const agentLockSource = existingConfigColumns.has(\"runtime_locked\")\n ? \"runtime_locked\"\n : existingConfigColumns.has(\"agent_pinned\")\n ? \"agent_pinned\"\n : \"0\";\n const modelLockSource = existingConfigColumns.has(\"model_locked\")\n ? \"model_locked\"\n : existingConfigColumns.has(\"model_pinned\")\n ? \"model_pinned\"\n : \"0\";\n const effortLockSource = existingConfigColumns.has(\"effort_locked\")\n ? \"effort_locked\"\n : existingConfigColumns.has(\"effort_pinned\")\n ? \"effort_pinned\"\n : \"0\";\n db.transaction(() => {\n createCanonicalConfigTable(\"api_topic_config_next\");\n db.exec(`\n INSERT INTO api_topic_config_next\n (topic_id, model, effort, mcp, agent_locked, model_locked, effort_locked)\n SELECT\n topic_id,\n model,\n effort,\n mcp,\n COALESCE(${agentLockSource}, 0),\n COALESCE(${modelLockSource}, 0),\n COALESCE(${effortLockSource}, 0)\n FROM api_topic_config\n WHERE EXISTS (SELECT 1 FROM api_topics t WHERE t.id = api_topic_config.topic_id)\n `);\n db.exec(\"DROP TABLE api_topic_config\");\n db.exec(\"ALTER TABLE api_topic_config_next RENAME TO api_topic_config\");\n })();\n } finally {\n db.exec(`PRAGMA foreign_keys = ${previousForeignKeys ? \"ON\" : \"OFF\"}`);\n }\n } else {\n createCanonicalConfigTable();\n }\n}\n\nregisterStorageSchemaInitializer(initializeApiTopicConfigSchema, 40);\n\nexport interface TopicConfig {\n model?: string;\n effort?: EffortLevel;\n mcp?: string[]; // enabled optional MCP server names\n // Per-field user locks: when true, AI self-config cannot override the field.\n agentLocked?: boolean;\n modelLocked?: boolean;\n effortLocked?: boolean;\n}\n\ninterface ConfigRow {\n topic_id: string;\n model: string | null;\n effort: string | null;\n mcp: string | null;\n agent_locked: number;\n model_locked: number;\n effort_locked: number;\n}\n\nfunction rowToConfig(r: ConfigRow): TopicConfig {\n const cfg: TopicConfig = {};\n if (r.model) cfg.model = r.model;\n if (r.effort) cfg.effort = r.effort as EffortLevel;\n if (r.mcp) {\n try {\n const parsed = JSON.parse(r.mcp);\n if (Array.isArray(parsed)) cfg.mcp = parsed as string[];\n } catch {\n // corrupt JSON — treat as no mcp override\n }\n }\n if (r.agent_locked) cfg.agentLocked = true;\n if (r.model_locked) cfg.modelLocked = true;\n if (r.effort_locked) cfg.effortLocked = true;\n return cfg;\n}\n\n/**\n * Per-topic override set via `PATCH /config` (and, going forward, the MCP\n * self-config tools). Returns `undefined` when the topic has no stored row,\n * so callers can distinguish \"no override\" from \"override with empty fields\".\n */\nexport function getApiTopicConfig(topicId: string): TopicConfig | undefined {\n const row = db\n .query(\n \"SELECT topic_id, model, effort, mcp, agent_locked, model_locked, effort_locked FROM api_topic_config WHERE topic_id = ?\",\n )\n .get(topicId) as ConfigRow | null;\n if (!row) return undefined;\n const config = rowToConfig(row);\n return Object.keys(config).length > 0 ? config : undefined;\n}\n\n/**\n * Upsert the full override for a topic. Fields set to `undefined` are cleared\n * (stored as SQL NULL), matching the previous Map semantics where the route\n * built a complete `updated` object before persisting.\n */\nexport function setApiTopicConfig(topicId: string, config: TopicConfig): void {\n db.query(\n `INSERT INTO api_topic_config\n (topic_id, model, effort, mcp, agent_locked, model_locked, effort_locked)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(topic_id) DO UPDATE SET\n model = excluded.model,\n effort = excluded.effort,\n mcp = excluded.mcp,\n agent_locked = excluded.agent_locked,\n model_locked = excluded.model_locked,\n effort_locked = excluded.effort_locked`,\n ).run(\n topicId,\n config.model ?? null,\n config.effort ?? null,\n config.mcp ? JSON.stringify(config.mcp) : null,\n config.agentLocked ? 1 : 0,\n config.modelLocked ? 1 : 0,\n config.effortLocked ? 1 : 0,\n );\n}\n\n/** Remove a topic's override row entirely (e.g. on topic hard-delete). */\nexport function deleteApiTopicConfig(topicId: string): void {\n db.query(\"DELETE FROM api_topic_config WHERE topic_id = ?\").run(topicId);\n}\n"
6
- ],
7
- "mappings": "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",
8
- "debugId": "1504C8C414D4E59064756E2164756E21",
9
- "names": []
10
- }
@@ -1,122 +0,0 @@
1
- // @bun
2
- import {
3
- resolveDefaultModel
4
- } from "./chunk-ezs352qs.js";
5
- import"./chunk-ffefbd3r.js";
6
- import"./chunk-hwy3n31w.js";
7
-
8
- // ../../packages/core/src/agents/model-catalog.ts
9
- var MODEL_OWNER = {
10
- sonnet: "claude",
11
- opus: "claude",
12
- haiku: "claude",
13
- fable: "claude",
14
- "gpt-5.6-luna": "codex",
15
- "gpt-5.6-terra": "codex",
16
- "gpt-5.6-sol": "codex",
17
- "gpt-5.5": "codex",
18
- deepseek: "maestro",
19
- "deepseek-pro": "maestro",
20
- "deepseek-flash": "maestro"
21
- };
22
- var SELECTABLE_MODELS = [
23
- {
24
- model: "gpt-5.6-sol",
25
- agent: "codex",
26
- description: "Latest frontier agentic coding model."
27
- },
28
- {
29
- model: "gpt-5.6-terra",
30
- agent: "codex",
31
- description: "Balanced agentic coding model for everyday work."
32
- },
33
- {
34
- model: "gpt-5.6-luna",
35
- agent: "codex",
36
- description: "Fast and affordable agentic coding model."
37
- },
38
- {
39
- model: "gpt-5.5",
40
- agent: "codex",
41
- description: "Frontier model for complex coding, research, and real-world work."
42
- },
43
- {
44
- model: "fable",
45
- agent: "claude",
46
- description: "Fable 5 \xB7 Most capable for your hardest and longest-running tasks \xB7 $10/$50 per Mtok"
47
- },
48
- {
49
- model: "opus",
50
- agent: "claude",
51
- description: "Opus 4.8 with 1M context \xB7 Best for everyday, complex tasks \xB7 $5/$25 per Mtok"
52
- },
53
- {
54
- model: "sonnet",
55
- agent: "claude",
56
- description: "Sonnet 5 \xB7 Efficient for routine tasks \xB7 $2/$10 per Mtok \xB7 promo through Aug 31"
57
- },
58
- {
59
- model: "deepseek-pro",
60
- agent: "maestro",
61
- description: "Sonnet-level performance at lower cost \xB7 Best for everyday tasks over coding"
62
- },
63
- {
64
- model: "deepseek-flash",
65
- agent: "maestro",
66
- description: "DeepSeek V4 Flash \xB7 Fast and low-cost for lightweight everyday tasks"
67
- }
68
- ];
69
- function selectableModel(value) {
70
- const normalized = value.trim().toLowerCase();
71
- return SELECTABLE_MODELS.find((candidate) => candidate.model === normalized);
72
- }
73
- function modelOwner(model) {
74
- if (model.startsWith("claude-"))
75
- return "claude";
76
- if (model.startsWith("deepseek-"))
77
- return "maestro";
78
- if (model.startsWith("gpt-"))
79
- return "codex";
80
- return MODEL_OWNER[model];
81
- }
82
- function resolveModelForAgent(agent, requested, registry) {
83
- const defaultModel = resolveDefaultModel(agent, registry.defaultModel);
84
- if (!requested)
85
- return defaultModel;
86
- const owner = modelOwner(requested);
87
- if (owner && owner !== agent)
88
- return defaultModel;
89
- return registry.validateModel(requested) ? requested : defaultModel;
90
- }
91
- var FALLBACK_ORDER = {
92
- claude: [
93
- { agent: "maestro", model: "deepseek-pro" },
94
- { agent: "codex", model: "gpt-5.6-luna" }
95
- ],
96
- codex: [
97
- { agent: "maestro", model: "deepseek-pro" },
98
- { agent: "claude", model: "sonnet" }
99
- ],
100
- maestro: [
101
- { agent: "codex", model: "gpt-5.6-luna" },
102
- { agent: "claude", model: "sonnet" }
103
- ]
104
- };
105
- var AGENT_DISPLAY_NAME = {
106
- claude: "Claude",
107
- codex: "Codex",
108
- maestro: "Maestro"
109
- };
110
- export {
111
- selectableModel,
112
- resolveModelForAgent,
113
- modelOwner,
114
- SELECTABLE_MODELS,
115
- MODEL_OWNER,
116
- FALLBACK_ORDER,
117
- AGENT_DISPLAY_NAME
118
- };
119
-
120
- export { MODEL_OWNER, SELECTABLE_MODELS, selectableModel, modelOwner, resolveModelForAgent, FALLBACK_ORDER, AGENT_DISPLAY_NAME };
121
-
122
- //# debugId=0800AE0F112828C564756E2164756E21
@@ -1,10 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../packages/core/src/agents/model-catalog.ts"],
4
- "sourcesContent": [
5
- "import { resolveDefaultModel } from \"#platform/config\";\nimport type { AgentKind } from \"#types\";\n\n/**\n * Models/prefixes that belong exclusively to one agent backend. When the\n * resolved agent differs from a model's owner, the model is cross-agent stale\n * and must be dropped in favor of the new agent's default — otherwise the value\n * is passed straight into a provider that can't run it and crashes the turn\n * (bug B: `/codex` leaves the topic's \"sonnet\" behind → Codex 400\n * \"The 'sonnet' model is not supported when using Codex\").\n *\n * Codex's own `validateModel` accepts ANY non-empty string (OpenAI ships new\n * IDs frequently), so it can't reject \"sonnet\" on its own — this ownership\n * owner check is the cross-agent guard the per-registry validator can't provide.\n * Unknown/new model IDs are intentionally absent here so they still pass\n * through to whichever agent is active.\n */\nexport const MODEL_OWNER: Record<string, AgentKind> = {\n // Current aliases plus retired aliases retained only for stale-model detection.\n sonnet: \"claude\",\n opus: \"claude\",\n haiku: \"claude\",\n fable: \"claude\",\n \"gpt-5.6-luna\": \"codex\",\n \"gpt-5.6-terra\": \"codex\",\n \"gpt-5.6-sol\": \"codex\",\n \"gpt-5.5\": \"codex\",\n deepseek: \"maestro\",\n \"deepseek-pro\": \"maestro\",\n \"deepseek-flash\": \"maestro\",\n};\n\nexport interface SelectableModel {\n /** Canonical token accepted by user-facing `/model` commands. */\n model: string;\n /** Runtime owner kept internal so channel UIs only need to show `model`. */\n agent: AgentKind;\n /** Short comparison copy shown alongside the model in picker UIs. */\n description: string;\n}\n\n/**\n * Canonical model picker shared by every channel. Keep this deliberately\n * finite even though the Codex backend accepts arbitrary future model ids:\n * user-facing completion should only promise models we intentionally support.\n */\nexport const SELECTABLE_MODELS: readonly SelectableModel[] = [\n {\n model: \"gpt-5.6-sol\",\n agent: \"codex\",\n description: \"Latest frontier agentic coding model.\",\n },\n {\n model: \"gpt-5.6-terra\",\n agent: \"codex\",\n description: \"Balanced agentic coding model for everyday work.\",\n },\n {\n model: \"gpt-5.6-luna\",\n agent: \"codex\",\n description: \"Fast and affordable agentic coding model.\",\n },\n {\n model: \"gpt-5.5\",\n agent: \"codex\",\n description: \"Frontier model for complex coding, research, and real-world work.\",\n },\n {\n model: \"fable\",\n agent: \"claude\",\n description:\n \"Fable 5 · Most capable for your hardest and longest-running tasks · $10/$50 per Mtok\",\n },\n {\n model: \"opus\",\n agent: \"claude\",\n description: \"Opus 4.8 with 1M context · Best for everyday, complex tasks · $5/$25 per Mtok\",\n },\n {\n model: \"sonnet\",\n agent: \"claude\",\n description: \"Sonnet 5 · Efficient for routine tasks · $2/$10 per Mtok · promo through Aug 31\",\n },\n {\n model: \"deepseek-pro\",\n agent: \"maestro\",\n description: \"Sonnet-level performance at lower cost · Best for everyday tasks over coding\",\n },\n {\n model: \"deepseek-flash\",\n agent: \"maestro\",\n description: \"DeepSeek V4 Flash · Fast and low-cost for lightweight everyday tasks\",\n },\n];\n\nexport function selectableModel(value: string): SelectableModel | undefined {\n const normalized = value.trim().toLowerCase();\n return SELECTABLE_MODELS.find((candidate) => candidate.model === normalized);\n}\n\nexport function modelOwner(model: string): AgentKind | undefined {\n if (model.startsWith(\"claude-\")) return \"claude\";\n if (model.startsWith(\"deepseek-\")) return \"maestro\";\n if (model.startsWith(\"gpt-\")) return \"codex\";\n return MODEL_OWNER[model];\n}\n\n/**\n * Resolve the model to run for `agent`, given the requested value from the\n * priority chain (per-message slash > topic-config override > topic default).\n * Drops a model owned by a different agent, then falls back to the agent's\n * registry default if the value is empty/invalid for this agent.\n */\nexport function resolveModelForAgent(\n agent: AgentKind,\n requested: string | undefined,\n registry: { validateModel(s: string): boolean; defaultModel: string },\n): string {\n const defaultModel = resolveDefaultModel(agent, registry.defaultModel);\n if (!requested) return defaultModel;\n const owner = modelOwner(requested);\n if (owner && owner !== agent) return defaultModel; // cross-agent stale\n return registry.validateModel(requested) ? requested : defaultModel;\n}\n\n/**\n * Circular fallback order per agent. Each entry lists candidates to try in\n * priority order when the current agent errors out. The actual switch is\n * guarded by `checkAgentAuth` — only candidates whose backend is reachable\n * (API key present / auth file exists) will be selected.\n */\nexport const FALLBACK_ORDER: Record<AgentKind, { agent: AgentKind; model: string }[]> = {\n claude: [\n { agent: \"maestro\", model: \"deepseek-pro\" },\n { agent: \"codex\", model: \"gpt-5.6-luna\" },\n ],\n codex: [\n { agent: \"maestro\", model: \"deepseek-pro\" },\n { agent: \"claude\", model: \"sonnet\" },\n ],\n maestro: [\n { agent: \"codex\", model: \"gpt-5.6-luna\" },\n { agent: \"claude\", model: \"sonnet\" },\n ],\n};\n\nexport const AGENT_DISPLAY_NAME: Record<AgentKind, string> = {\n claude: \"Claude\",\n codex: \"Codex\",\n maestro: \"Maestro\",\n};\n"
6
- ],
7
- "mappings": ";;;;;;;;AAiBO,IAAM,cAAyC;AAAA,EAEpD,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,WAAW;AAAA,EACX,UAAU;AAAA,EACV,gBAAgB;AAAA,EAChB,kBAAkB;AACpB;AAgBO,IAAM,oBAAgD;AAAA,EAC3D;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,aACE;AAAA,EACJ;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AACF;AAEO,SAAS,eAAe,CAAC,OAA4C;AAAA,EAC1E,MAAM,aAAa,MAAM,KAAK,EAAE,YAAY;AAAA,EAC5C,OAAO,kBAAkB,KAAK,CAAC,cAAc,UAAU,UAAU,UAAU;AAAA;AAGtE,SAAS,UAAU,CAAC,OAAsC;AAAA,EAC/D,IAAI,MAAM,WAAW,SAAS;AAAA,IAAG,OAAO;AAAA,EACxC,IAAI,MAAM,WAAW,WAAW;AAAA,IAAG,OAAO;AAAA,EAC1C,IAAI,MAAM,WAAW,MAAM;AAAA,IAAG,OAAO;AAAA,EACrC,OAAO,YAAY;AAAA;AASd,SAAS,oBAAoB,CAClC,OACA,WACA,UACQ;AAAA,EACR,MAAM,eAAe,oBAAoB,OAAO,SAAS,YAAY;AAAA,EACrE,KAAK;AAAA,IAAW,OAAO;AAAA,EACvB,MAAM,QAAQ,WAAW,SAAS;AAAA,EAClC,IAAI,SAAS,UAAU;AAAA,IAAO,OAAO;AAAA,EACrC,OAAO,SAAS,cAAc,SAAS,IAAI,YAAY;AAAA;AASlD,IAAM,iBAA2E;AAAA,EACtF,QAAQ;AAAA,IACN,EAAE,OAAO,WAAW,OAAO,eAAe;AAAA,IAC1C,EAAE,OAAO,SAAS,OAAO,eAAe;AAAA,EAC1C;AAAA,EACA,OAAO;AAAA,IACL,EAAE,OAAO,WAAW,OAAO,eAAe;AAAA,IAC1C,EAAE,OAAO,UAAU,OAAO,SAAS;AAAA,EACrC;AAAA,EACA,SAAS;AAAA,IACP,EAAE,OAAO,SAAS,OAAO,eAAe;AAAA,IACxC,EAAE,OAAO,UAAU,OAAO,SAAS;AAAA,EACrC;AACF;AAEO,IAAM,qBAAgD;AAAA,EAC3D,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AACX;",
8
- "debugId": "0800AE0F112828C564756E2164756E21",
9
- "names": []
10
- }