@desplega.ai/agent-swarm 1.152.2 → 1.153.0
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.
- package/README.md +1 -1
- package/dist/{acp-adapter-pfeje2v5.js → acp-adapter-ahmjxhek.js} +4 -4
- package/dist/{actions-0sttc7f5.js → actions-jzrfpkmn.js} +30 -26
- package/dist/{anthropic-messages-2y8nktar.js → anthropic-messages-9vqsbznt.js} +112 -84
- package/dist/{app-p8teva95.js → app-03na2vwb.js} +9 -6
- package/dist/{assistant-r45jnsrt.js → assistant-hfkxvhgt.js} +31 -27
- package/dist/{azure-openai-responses-f38x2avq.js → azure-openai-responses-04qwdwfq.js} +27 -13
- package/dist/{boot-reembed-je26h5y7.js → boot-reembed-c98xrad3.js} +8 -6
- package/dist/{boot-reembed-1qmybsd4.js → boot-reembed-zt3qm9xn.js} +9 -7
- package/dist/{boot-scrub-logs-gte3h1mm.js → boot-scrub-logs-jcqd8ksj.js} +6 -4
- package/dist/{claude-adapter-csc1mzka.js → claude-adapter-mgryg8g3.js} +17 -15
- package/dist/{claude-managed-adapter-dsmkcrjy.js → claude-managed-adapter-ea2aga6w.js} +3 -3
- package/dist/{claude-sdk-session-fcd6f078.js → claude-sdk-session-jjf4zss1.js} +17 -15
- package/dist/{cli-r2fpe7cx.js → cli-00w2c66p.js} +61 -55
- package/dist/{cli-fm4ytsdk.js → cli-0d9nbqxf.js} +1 -1
- package/dist/cli-0x5qzvkg.js +4279 -0
- package/dist/{cli-d3p82erb.js → cli-18amys3y.js} +9 -9
- package/dist/{cli-wbyk465z.js → cli-1hwnb4hc.js} +1 -1
- package/dist/{cli-xw7vak96.js → cli-3bcmp015.js} +5 -5
- package/dist/cli-3er6gcsn.js +1849 -0
- package/dist/{cli-c4eeb5q2.js → cli-5b6b62tz.js} +1 -1
- package/dist/{cli-4ahpr4sw.js → cli-5mbmvxnn.js} +5 -5
- package/dist/{cli-xy1cchaf.js → cli-5taqtpze.js} +235 -8
- package/dist/{cli-fmy65jdn.js → cli-6ks9xf1n.js} +7 -5
- package/dist/cli-7g9s78jf.js +2827 -0
- package/dist/{cli-jew3jda5.js → cli-7pnz2v6s.js} +2 -2
- package/dist/{cli-r84ctdxn.js → cli-83wkg402.js} +2 -2
- package/dist/{cli-jvy9qgjs.js → cli-a9scg8sv.js} +4 -4
- package/dist/{cli-4yc5d8fk.js → cli-avkd6mqv.js} +50 -0
- package/dist/{cli-ht5rs63n.js → cli-b2g6mzjc.js} +15 -6
- package/dist/{cli-jbmc0r7r.js → cli-bw0dfwkr.js} +1 -1
- package/dist/{cli-8wrympd7.js → cli-bzr0ftht.js} +26 -7
- package/dist/{cli-wpv5rgg2.js → cli-cdq08v3r.js} +2 -2
- package/dist/cli-cgj4hc12.js +18902 -0
- package/dist/cli-d6hk10xx.js +14075 -0
- package/dist/{cli-zvgj5zg8.js → cli-djvxhnc4.js} +31 -3324
- package/dist/{cli-s25avqg9.js → cli-e781c6f9.js} +1 -0
- package/dist/{cli-3bpzj8me.js → cli-eazstkad.js} +2 -2
- package/dist/{cli-s2qjdd6z.js → cli-eetrvv91.js} +1 -1
- package/dist/cli-h38x0qhg.js +6912 -0
- package/dist/{cli-9xvdm3bx.js → cli-h60qfasa.js} +742 -278
- package/dist/{pi-mono-adapter-jcqt71cg.js → cli-ja7mrygn.js} +67343 -101083
- package/dist/{cli-j8dggbcr.js → cli-k0g1sjzm.js} +23 -31
- package/dist/{cli-gphgnvpf.js → cli-m04pt18h.js} +2 -2
- package/dist/{cli-rgvp6r2x.js → cli-mcnhgnn1.js} +193 -4
- package/dist/{cli-j4nv2wqy.js → cli-mzgyhxbe.js} +10 -4
- package/dist/{cli-qn042eh7.js → cli-n0q9b7j4.js} +46 -1870
- package/dist/cli-n7h1kqpf.js +29 -0
- package/dist/{cli-ckz5t2hb.js → cli-nq0kgyxe.js} +5 -5
- package/dist/{cli-z3wkng35.js → cli-qrqhc31j.js} +151 -125
- package/dist/{cli-56h18ng2.js → cli-r8tdds6s.js} +1 -1
- package/dist/{cli-ch38q5z4.js → cli-rj7de4b2.js} +6788 -2541
- package/dist/{cli-qd65dvr6.js → cli-s5s1f2yn.js} +56 -40
- package/dist/{cli-kj76p1ez.js → cli-scwq51gn.js} +13 -7
- package/dist/{cli-2nnd56zt.js → cli-tdh4hjr2.js} +3 -2
- package/dist/{cli-c2mk1kgf.js → cli-v4en75c5.js} +8 -1
- package/dist/{cli-b9dd0h3k.js → cli-vw03hg5t.js} +3 -2
- package/dist/{cli-zvkq5csn.js → cli-ybpp1srm.js} +6 -6
- package/dist/cli-yn0a417a.js +4069 -0
- package/dist/{cli-gpqcs935.js → cli-ysc1kbet.js} +2 -2
- package/dist/{cli-zfzznn7c.js → cli-ytxs7mn1.js} +26 -2
- package/dist/cli-zcsyfw2z.js +3335 -0
- package/dist/{cli-4j8k1m4w.js → cli-zt1227k1.js} +1162 -192
- package/dist/cli-zy5w9gpt.js +230 -0
- package/dist/cli.js +26 -34
- package/dist/{codex-adapter-fxmpsabw.js → codex-adapter-8548daap.js} +12 -11
- package/dist/{codex-session-runner-rr1e47ea.js → codex-session-runner-2dad8p4x.js} +12 -11
- package/dist/{commands-0f5rxz51.js → commands-355dbpa8.js} +6 -4
- package/dist/{db-r3jxf3wy.js → db-4jjvwz1s.js} +6 -4
- package/dist/{dispatcher-06vph6q4.js → dispatcher-ca590nkz.js} +29 -25
- package/dist/dsh-adapter-rgvj6ykp.js +19 -0
- package/dist/{e2b-413b8t4v.js → e2b-93x1k0j5.js} +6 -7
- package/dist/{google-generative-ai-ndjmj5fa.js → google-generative-ai-xtw7tggr.js} +33 -73
- package/dist/{google-vertex-fr665tqs.js → google-vertex-zdqpms6n.js} +38 -68
- package/dist/{handlers-0hgtc910.js → handlers-2y6dqpvf.js} +32 -28
- package/dist/{hook-9kvrv1er.js → hook-0s8knepr.js} +11 -9
- package/dist/{hook-fbfhkat3.js → hook-k0gec254.js} +12 -10
- package/dist/{http-xbyx8k5j.js → http-jp2nb4zw.js} +300 -237
- package/dist/{index-tfsdxyv6.js → index-0wzg3sp3.js} +39 -24
- package/dist/{index-rnyahfn5.js → index-3mq6ce93.js} +29 -25
- package/dist/{index-jsw3aynb.js → index-42s7eezq.js} +29 -25
- package/dist/{cli-pdz9qde4.js → index-9ch1n761.js} +10 -11
- package/dist/{index-gpfn1741.js → index-b56xkbc7.js} +8 -6
- package/dist/{index-66xz5e9j.js → index-h5gs261z.js} +521 -9
- package/dist/{index-2sp0384z.js → index-kkeftv5h.js} +738 -21
- package/dist/{index-sgk50mbg.js → index-s37dbevy.js} +30 -26
- package/dist/index-w097eg0x.js +5 -0
- package/dist/jiti-loader-b4837mtm.js +34 -0
- package/dist/jiti-static-loader-q2g5ds0y.js +31267 -0
- package/dist/{keepalive-s3xpr7sw.js → keepalive-9pfw7t02.js} +8 -6
- package/dist/{lead-rq4n5r16.js → lead-7vcmcdq4.js} +44 -39
- package/dist/{maintenance-f0atj1ab.js → maintenance-x277jbpd.js} +9 -7
- package/dist/{mistral-conversations-qhr84ph3.js → mistral-conversations-zx0kn554.js} +24 -18
- package/dist/{node-x1g4v0pq.js → node-5qtycf6a.js} +16 -11
- package/dist/{oauth-refresh-sweep-q0t3bxre.js → oauth-refresh-sweep-5fwa7th2.js} +7 -5
- package/dist/{onboard-br5j1kch.js → onboard-17sv0f51.js} +103 -35
- package/dist/{openai-codex-responses-wy6a43wd.js → openai-codex-responses-4vjqzvjp.js} +33 -27
- package/dist/{openai-completions-32rdwmze.js → openai-completions-pxsmym7g.js} +52 -64
- package/dist/{openai-responses-6xwf7bzg.js → openai-responses-tmn0rqp0.js} +23 -24
- package/dist/{opencode-adapter-28axqa09.js → opencode-adapter-qbmv4tpy.js} +6 -6
- package/dist/{otel-impl-vdqge2nt.js → otel-impl-srjy4be4.js} +4 -4
- package/dist/{pi-messages-b1mbr6gp.js → pi-messages-txpjj39q.js} +3 -3
- package/dist/pi-mono-adapter-946a0sdd.js +1316 -0
- package/dist/{pricing-refresh-hb3691fd.js → pricing-refresh-vetcm563.js} +8 -6
- package/dist/{rbac-roles-jh280k9g.js → rbac-roles-cfzgr6r1.js} +8 -6
- package/dist/{rbac-roles-t78xt39b.js → rbac-roles-cmxaddmy.js} +7 -5
- package/dist/{render-v2-7p8r2ymg.js → render-v2-f9hzff72.js} +9 -6
- package/dist/{seed-pricing-hf889enh.js → seed-pricing-jggk6rsy.js} +7 -5
- package/dist/{setup-w6mb03jv.js → setup-8mfceb9t.js} +4 -5
- package/dist/virtual-modules-ax661xp0.js +54 -0
- package/dist/{work-objects-nt8gy1kj.js → work-objects-vdsdcczj.js} +32 -28
- package/dist/{worker-dwy617t0.js → worker-cd0nhyv1.js} +44 -39
- package/openapi.json +36 -14
- package/package.json +6 -6
- package/src/be/automation-preflight.ts +6 -4
- package/src/be/extensions/db.ts +35 -4
- package/src/be/models-catalog.ts +2 -0
- package/src/be/modelsdev-cache.json +213 -0
- package/src/be/rbac-audit.ts +2 -0
- package/src/be/seed-pricing.ts +3 -1
- package/src/be/swarm-config-guard.ts +1 -0
- package/src/commands/onboard/compose-generator.ts +6 -1
- package/src/commands/onboard/env-generator.ts +6 -1
- package/src/commands/onboard/manifest.ts +1 -0
- package/src/commands/onboard/steps/integration-slack.tsx +56 -16
- package/src/commands/onboard/steps/review.tsx +5 -0
- package/src/commands/onboard/types.ts +6 -0
- package/src/commands/onboard.tsx +5 -1
- package/src/commands/provider-credentials.ts +14 -2
- package/src/extensions/lifecycle.ts +15 -21
- package/src/http/agents.ts +2 -2
- package/src/http/config.ts +1 -1
- package/src/http/core.ts +5 -3
- package/src/http/extensions.ts +108 -34
- package/src/http/status.ts +22 -10
- package/src/prompts/base-prompt.ts +15 -7
- package/src/providers/claude-managed-models.ts +8 -0
- package/src/providers/codex-models.ts +15 -1
- package/src/providers/dsh-adapter.ts +248 -0
- package/src/providers/index.ts +5 -1
- package/src/providers/modelsdev-reasoning.json +50 -0
- package/src/rbac/legacy-policy.ts +15 -1
- package/src/rbac/types.ts +2 -0
- package/src/server.ts +7 -1
- package/src/slack/app.ts +32 -10
- package/src/slack/config.ts +29 -0
- package/src/telemetry.ts +2 -3
- package/src/tests/agents-harness-provider.test.ts +19 -0
- package/src/tests/agents-list-model-display.test.ts +60 -1
- package/src/tests/base-prompt.test.ts +25 -0
- package/src/tests/claude-managed-adapter.test.ts +6 -0
- package/src/tests/codex-gpt6-release.test.ts +97 -0
- package/src/tests/config-api-only-keys.test.ts +9 -0
- package/src/tests/context-window.test.ts +1 -0
- package/src/tests/dsh-adapter.test.ts +276 -0
- package/src/tests/e2e-nightly-report.test.ts +3 -3
- package/src/tests/e2e-redact.test.ts +2 -0
- package/src/tests/env-flag.test.ts +6 -0
- package/src/tests/extensions-db.test.ts +41 -0
- package/src/tests/extensions-http.test.ts +148 -4
- package/src/tests/extensions-lifecycle.test.ts +18 -0
- package/src/tests/extensions-mcp-tools.test.ts +9 -5
- package/src/tests/internal-ai/complete-structured.test.ts +32 -9
- package/src/tests/internal-ai/credentials.test.ts +4 -4
- package/src/tests/internal-ai/models.test.ts +20 -0
- package/src/tests/migration-046-budgets.test.ts +2 -0
- package/src/tests/model-control.test.ts +2 -2
- package/src/tests/onboard-compose.test.ts +14 -0
- package/src/tests/onboard-env.test.ts +17 -0
- package/src/tests/onboard-manifest.test.ts +12 -0
- package/src/tests/opus-5-5-registry.test.ts +48 -0
- package/src/tests/pricing-refresh.test.ts +1 -1
- package/src/tests/pricing-routes.test.ts +15 -3
- package/src/tests/provider-registration.test.ts +5 -2
- package/src/tests/rbac-admission-e2e.test.ts +54 -0
- package/src/tests/rbac-e2e-helpers.ts +2 -0
- package/src/tests/rbac-engine.test.ts +32 -0
- package/src/tests/rbac-wire-e2e.test.ts +33 -0
- package/src/tests/reasoning-effort.test.ts +8 -0
- package/src/tests/reload-config.test.ts +33 -0
- package/src/tests/session-costs-model-key-normalize.test.ts +1 -0
- package/src/tests/slack-config.test.ts +136 -0
- package/src/tests/slack-mode-lifecycle.test.ts +69 -0
- package/src/tests/status.test.ts +22 -2
- package/src/tests/task-tool-preload-mcp.test.ts +3 -1
- package/src/tests/telemetry-init.test.ts +18 -0
- package/src/tests/workflow-llm.test.ts +3 -3
- package/src/tools/extension-common.ts +4 -0
- package/src/tools/extension-install.ts +1 -1
- package/src/tools/extension-list.ts +4 -3
- package/src/types.ts +17 -8
- package/src/utils/context-window.ts +1 -0
- package/src/utils/credentials.ts +8 -0
- package/src/utils/internal-ai/complete-structured.ts +8 -0
- package/src/utils/internal-ai/models.ts +5 -5
- package/templates/schedules/daily-status-report/content.md +25 -12
- package/templates/schedules/daily-workflow-health-audit/content.md +1 -1
- package/templates/skills/swarm-extensions/content.md +9 -5
- package/dist/cli-4wppfkcm.js +0 -16384
- package/dist/cli-55qrx3q8.js +0 -6041
- package/dist/cli-cg4vnyh4.js +0 -305
- package/dist/cli-jyetr64j.js +0 -52
- package/dist/cli-pp9ax9pa.js +0 -520
- package/dist/cli-qa66qaf0.js +0 -6076
- package/dist/cli-qghpvca2.js +0 -590
- package/dist/cli-rembwgt8.js +0 -861
- package/dist/cli-tcvj7j2r.js +0 -1971
- package/dist/cli-vfcth11k.js +0 -36
- package/dist/cli-w1d1bgkk.js +0 -1422
- package/dist/cli-y6x0gqtg.js +0 -5977
- package/dist/es5-tj3tn4jj.js +0 -844
- package/dist/index-1kq5hw2p.js +0 -467
- package/dist/index-1p8wdstt.js +0 -7
- package/dist/index-8fdjzb2f.js +0 -100
- package/dist/index-bxmwzbgw.js +0 -365
- package/dist/index-nzerxd5z.js +0 -7
- package/dist/index-pyymnzat.js +0 -1168
- package/dist/index-qv6atbab.js +0 -619
- package/dist/index-rja32qa7.js +0 -801
- package/dist/index-tzg5srfp.js +0 -211
- package/dist/index-vhncw983.js +0 -90
- package/dist/index-xk036zsk.js +0 -859
- package/dist/index-zyazbzcb.js +0 -6
- package/dist/{claude-managed-setup-48dwg9bv.js → claude-managed-setup-f5pmsyrp.js} +3 -3
|
@@ -22,6 +22,7 @@ import { checkClaudeCredentials } from "../providers/claude-adapter";
|
|
|
22
22
|
import { checkClaudeManagedCredentials } from "../providers/claude-managed-adapter";
|
|
23
23
|
import { checkCodexCredentials } from "../providers/codex-adapter";
|
|
24
24
|
import { checkDevinCredentials } from "../providers/devin-adapter";
|
|
25
|
+
import { checkDshCredentials } from "../providers/dsh-adapter";
|
|
25
26
|
import { checkOpencodeCredentials } from "../providers/opencode-adapter";
|
|
26
27
|
import type { CredCheckOptions, CredStatus } from "../providers/types";
|
|
27
28
|
import type {
|
|
@@ -41,7 +42,8 @@ export type SupportedProvider =
|
|
|
41
42
|
| "devin"
|
|
42
43
|
| "opencode"
|
|
43
44
|
| "pi"
|
|
44
|
-
| "acp"
|
|
45
|
+
| "acp"
|
|
46
|
+
| "dsh";
|
|
45
47
|
|
|
46
48
|
/**
|
|
47
49
|
* True when the pi harness authenticates against Bedrock rather than a provider
|
|
@@ -105,6 +107,7 @@ export const REQUIRED_CRED_VARS_BY_PROVIDER: Record<SupportedProvider, readonly
|
|
|
105
107
|
pi: ["ANTHROPIC_API_KEY", "OPENROUTER_API_KEY", "OPENAI_API_KEY"],
|
|
106
108
|
// The ACP target process owns its own auth, so the swarm requires nothing.
|
|
107
109
|
acp: [],
|
|
110
|
+
dsh: ["DEEPSEEK_API_KEY", "OPENROUTER_API_KEY"],
|
|
108
111
|
};
|
|
109
112
|
|
|
110
113
|
type CredentialChecker = (
|
|
@@ -114,6 +117,7 @@ type CredentialChecker = (
|
|
|
114
117
|
|
|
115
118
|
/** The handlers used by the credential-readiness dispatcher. */
|
|
116
119
|
export const CREDENTIAL_PROVIDER_CHECKERS: Record<SupportedProvider, CredentialChecker> = {
|
|
120
|
+
dsh: (env) => checkDshCredentials(env),
|
|
117
121
|
claude: (env) => checkClaudeCredentials(env),
|
|
118
122
|
"claude-managed": (env) => checkClaudeManagedCredentials(env),
|
|
119
123
|
codex: (env, opts) => checkCodexCredentials(env, opts),
|
|
@@ -416,12 +420,20 @@ export async function validateProviderCredentials(provider: string): Promise<Liv
|
|
|
416
420
|
latency_ms: r.latency_ms,
|
|
417
421
|
};
|
|
418
422
|
}
|
|
423
|
+
case "dsh":
|
|
424
|
+
return checkDshCredentials(env).ready
|
|
425
|
+
? presenceCheckOk()
|
|
426
|
+
: {
|
|
427
|
+
ok: false,
|
|
428
|
+
error: "Set DEEPSEEK_API_KEY or OPENROUTER_API_KEY for dsh.",
|
|
429
|
+
latency_ms: Date.now() - startedAt,
|
|
430
|
+
};
|
|
419
431
|
case "acp":
|
|
420
432
|
return presenceCheckOk();
|
|
421
433
|
default:
|
|
422
434
|
return {
|
|
423
435
|
ok: false,
|
|
424
|
-
error: `Unknown provider "${provider}". Supported: claude, claude-managed, codex, devin, opencode, pi, acp.`,
|
|
436
|
+
error: `Unknown provider "${provider}". Supported: claude, claude-managed, codex, devin, opencode, pi, acp, dsh.`,
|
|
425
437
|
latency_ms: Date.now() - startedAt,
|
|
426
438
|
};
|
|
427
439
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
activateExtensionVersionSnapshot,
|
|
3
3
|
getExtensionById,
|
|
4
|
-
getExtensionFiles,
|
|
5
4
|
getExtensionVersion,
|
|
6
5
|
insertExtensionRun,
|
|
7
6
|
listExtensions,
|
|
@@ -66,28 +65,23 @@ function maxUpdatedAt(extensions: Extension[]): string {
|
|
|
66
65
|
}
|
|
67
66
|
|
|
68
67
|
async function loadableExtension(record: Extension): Promise<LoadableExtension> {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
return {
|
|
78
|
-
record: {
|
|
79
|
-
...record,
|
|
80
|
-
manifestJson: version.manifestJson,
|
|
81
|
-
contentHash: version.contentHash,
|
|
82
|
-
},
|
|
83
|
-
manifest: ExtensionManifestSchema.parse(JSON.parse(version.manifestJson)),
|
|
84
|
-
files: JSON.parse(version.filesJson) as Record<string, string>,
|
|
85
|
-
};
|
|
68
|
+
// Always load the immutable selected version. The mutable current-file projection
|
|
69
|
+
// can advance while an agent stages a draft after we read the extension row.
|
|
70
|
+
const version = await getExtensionVersion(record.id, record.activeVersion);
|
|
71
|
+
if (!version) {
|
|
72
|
+
throw new ExtensionLifecycleError(
|
|
73
|
+
`Extension version ${record.activeVersion} was not found`,
|
|
74
|
+
404,
|
|
75
|
+
);
|
|
86
76
|
}
|
|
87
77
|
return {
|
|
88
|
-
record
|
|
89
|
-
|
|
90
|
-
|
|
78
|
+
record: {
|
|
79
|
+
...record,
|
|
80
|
+
manifestJson: version.manifestJson,
|
|
81
|
+
contentHash: version.contentHash,
|
|
82
|
+
},
|
|
83
|
+
manifest: ExtensionManifestSchema.parse(JSON.parse(version.manifestJson)),
|
|
84
|
+
files: JSON.parse(version.filesJson) as Record<string, string>,
|
|
91
85
|
};
|
|
92
86
|
}
|
|
93
87
|
|
package/src/http/agents.ts
CHANGED
|
@@ -181,7 +181,7 @@ const setAgentHarnessProviderRoute = route({
|
|
|
181
181
|
},
|
|
182
182
|
});
|
|
183
183
|
|
|
184
|
-
const LocalHarnessProviderSchema = z.enum(["claude", "codex", "pi", "opencode", "acp"]);
|
|
184
|
+
const LocalHarnessProviderSchema = z.enum(["claude", "codex", "pi", "opencode", "acp", "dsh"]);
|
|
185
185
|
const AcpRuntimeConfigSchema = z
|
|
186
186
|
.object({
|
|
187
187
|
target: z.enum(ACP_TARGET_IDS),
|
|
@@ -1046,7 +1046,7 @@ export async function handleAgentsRest(
|
|
|
1046
1046
|
})
|
|
1047
1047
|
)[0]?.value ?? "");
|
|
1048
1048
|
const allowedLevels =
|
|
1049
|
-
harness_provider === "acp"
|
|
1049
|
+
harness_provider === "acp" || harness_provider === "dsh"
|
|
1050
1050
|
? []
|
|
1051
1051
|
: reasoningCapability(harness_provider, modelForValidation ?? "").levels;
|
|
1052
1052
|
if (!allowedLevels.includes(reasoning_effort)) {
|
package/src/http/config.ts
CHANGED
|
@@ -37,7 +37,7 @@ const SECRETS_FORCE_MASK_NOTE =
|
|
|
37
37
|
// bootstrap admin key would let a compromised worker administer the shared org.
|
|
38
38
|
// The API materializes these into its own process.env at boot via
|
|
39
39
|
// getInjectableGlobalConfigs, so no HTTP consumer legitimately needs them.
|
|
40
|
-
const API_ONLY_CONFIG_KEYS = new Set(["API_AGENT_FS_API_KEY"]);
|
|
40
|
+
const API_ONLY_CONFIG_KEYS = new Set(["API_AGENT_FS_API_KEY", "SLACK_SIGNING_SECRET"]);
|
|
41
41
|
|
|
42
42
|
function stripApiOnlyKeys<T extends { key: string }>(configs: T[]): T[] {
|
|
43
43
|
return configs.filter((config) => !API_ONLY_CONFIG_KEYS.has(config.key));
|
package/src/http/core.ts
CHANGED
|
@@ -150,6 +150,10 @@ async function reloadGlobalConfigsAndIntegrationsInner(): Promise<ReloadConfigRe
|
|
|
150
150
|
|
|
151
151
|
const updated = await loadGlobalConfigsIntoEnv(true);
|
|
152
152
|
|
|
153
|
+
// Retire the old transport before any other integration can fail during
|
|
154
|
+
// reload. HTTP/invalid selection must never leave the previous socket live.
|
|
155
|
+
await stopSlackApp();
|
|
156
|
+
|
|
153
157
|
// File-storage provider selection reads process.env once and memoizes; the
|
|
154
158
|
// env we just (re)hydrated may flip it (local-fs → agent-fs after late
|
|
155
159
|
// provisioning, or a rotated bootstrap key). Reset so the next fs request
|
|
@@ -206,9 +210,7 @@ async function reloadGlobalConfigsAndIntegrationsInner(): Promise<ReloadConfigRe
|
|
|
206
210
|
resetJira();
|
|
207
211
|
if (await initJira()) integrations.push("jira");
|
|
208
212
|
|
|
209
|
-
await
|
|
210
|
-
await startSlackApp();
|
|
211
|
-
integrations.push("slack");
|
|
213
|
+
if (await startSlackApp()) integrations.push("slack");
|
|
212
214
|
|
|
213
215
|
return {
|
|
214
216
|
configsLoaded: updated.length,
|
package/src/http/extensions.ts
CHANGED
|
@@ -4,9 +4,11 @@ import { resolveHttpAuditUserId } from "../be/audit-user";
|
|
|
4
4
|
import { getAgentById } from "../be/db";
|
|
5
5
|
import {
|
|
6
6
|
deleteExtension,
|
|
7
|
+
ExtensionOwnershipError,
|
|
7
8
|
getExtensionById,
|
|
8
9
|
getExtensionByName,
|
|
9
10
|
getExtensionFiles,
|
|
11
|
+
type InstallExtensionResult,
|
|
10
12
|
installExtension,
|
|
11
13
|
listExtensionRuns,
|
|
12
14
|
listExtensions,
|
|
@@ -23,8 +25,15 @@ import {
|
|
|
23
25
|
reloadExtension,
|
|
24
26
|
} from "../extensions/lifecycle";
|
|
25
27
|
import { ExtensionConfigError } from "../extensions/loader";
|
|
26
|
-
import { can, type PermissionVerb, type RbacPrincipal } from "../rbac";
|
|
27
28
|
import {
|
|
29
|
+
can,
|
|
30
|
+
LEGACY_RULES,
|
|
31
|
+
type PermissionVerb,
|
|
32
|
+
type RbacPrincipal,
|
|
33
|
+
type RbacResource,
|
|
34
|
+
} from "../rbac";
|
|
35
|
+
import {
|
|
36
|
+
type Extension,
|
|
28
37
|
ExtensionInstallBodySchema,
|
|
29
38
|
ExtensionManifestSchema,
|
|
30
39
|
ExtensionRunSchema,
|
|
@@ -44,6 +53,8 @@ const installRoute = route({
|
|
|
44
53
|
pattern: ["api", "extensions", "install"],
|
|
45
54
|
operationId: "extensions_install",
|
|
46
55
|
summary: "Validate and install an extension bundle",
|
|
56
|
+
description:
|
|
57
|
+
"Any authenticated agent can install a disabled draft owned by its agent ID. Workers can update only their own bundles; activation remains lead/operator-only.",
|
|
47
58
|
tags: ["Extensions"],
|
|
48
59
|
body: ExtensionInstallBodySchema,
|
|
49
60
|
responses: {
|
|
@@ -153,6 +164,8 @@ const patchRoute = route({
|
|
|
153
164
|
pattern: ["api", "extensions", null],
|
|
154
165
|
operationId: "extensions_update",
|
|
155
166
|
summary: "Update extension priority, config, or description",
|
|
167
|
+
description:
|
|
168
|
+
"Workers may edit their own disabled extensions. Leads, operators, and dashboard users retain access to all extensions.",
|
|
156
169
|
tags: ["Extensions"],
|
|
157
170
|
params: idParamsSchema,
|
|
158
171
|
body: z
|
|
@@ -177,6 +190,8 @@ const deleteRoute = route({
|
|
|
177
190
|
pattern: ["api", "extensions", null],
|
|
178
191
|
operationId: "extensions_delete",
|
|
179
192
|
summary: "Uninstall a disabled extension",
|
|
193
|
+
description:
|
|
194
|
+
"Workers may uninstall their own disabled extensions. Leads, operators, and dashboard users retain access to all extensions.",
|
|
180
195
|
tags: ["Extensions"],
|
|
181
196
|
params: idParamsSchema,
|
|
182
197
|
responses: {
|
|
@@ -316,14 +331,23 @@ async function extensionPrincipal(
|
|
|
316
331
|
return { kind: "agent", agentId: "", isLead: false };
|
|
317
332
|
}
|
|
318
333
|
|
|
334
|
+
/** Restrict ordinary agents; retain the existing blanket access for elevated writers. */
|
|
335
|
+
function ownerOnlyAgentId(principal: RbacPrincipal): string | undefined {
|
|
336
|
+
return principal.kind === "agent" &&
|
|
337
|
+
!LEGACY_RULES["lead-or-operator-or-user"].evaluate(principal, undefined)
|
|
338
|
+
? principal.agentId
|
|
339
|
+
: undefined;
|
|
340
|
+
}
|
|
341
|
+
|
|
319
342
|
async function requirePermission(
|
|
320
343
|
req: IncomingMessage,
|
|
321
344
|
res: ServerResponse,
|
|
322
345
|
callerAgentId: string | undefined,
|
|
323
346
|
verb: Extract<PermissionVerb, "extension.write" | "extension.activate">,
|
|
347
|
+
resource: RbacResource = { kind: "none" },
|
|
324
348
|
): Promise<RbacPrincipal | null> {
|
|
325
349
|
const principal = await extensionPrincipal(req, callerAgentId);
|
|
326
|
-
const decision = can({ principal, verb, resource
|
|
350
|
+
const decision = can({ principal, verb, resource, source: "http" });
|
|
327
351
|
if (decision.allow) return principal;
|
|
328
352
|
jsonError(res, `Forbidden: ${decision.reason}`, 403);
|
|
329
353
|
return null;
|
|
@@ -331,11 +355,13 @@ async function requirePermission(
|
|
|
331
355
|
|
|
332
356
|
function respondLifecycleError(res: ServerResponse, error: unknown): void {
|
|
333
357
|
const status =
|
|
334
|
-
error instanceof
|
|
335
|
-
?
|
|
336
|
-
: error instanceof
|
|
337
|
-
?
|
|
338
|
-
:
|
|
358
|
+
error instanceof ExtensionOwnershipError
|
|
359
|
+
? 403
|
|
360
|
+
: error instanceof ExtensionConfigError
|
|
361
|
+
? 400
|
|
362
|
+
: error instanceof ExtensionLifecycleError
|
|
363
|
+
? error.status
|
|
364
|
+
: 500;
|
|
339
365
|
jsonError(res, scrubSecrets(error instanceof Error ? error.message : String(error)), status);
|
|
340
366
|
}
|
|
341
367
|
|
|
@@ -349,26 +375,41 @@ export async function handleExtensions(
|
|
|
349
375
|
if (installRoute.match(req.method, pathSegments)) {
|
|
350
376
|
const parsed = await installRoute.parse(req, res, pathSegments, queryParams);
|
|
351
377
|
if (!parsed) return true;
|
|
352
|
-
const
|
|
378
|
+
const existing = await getExtensionByName(parsed.body.manifest.name);
|
|
379
|
+
const principal = await requirePermission(req, res, agentId, "extension.write", {
|
|
380
|
+
kind: "extension",
|
|
381
|
+
extensionId: existing?.id,
|
|
382
|
+
createdByAgentId: existing?.createdByAgentId,
|
|
383
|
+
});
|
|
353
384
|
if (!principal) return true;
|
|
354
385
|
const validation = await validateBundle(parsed.body);
|
|
355
386
|
if (!validation.ok) {
|
|
356
387
|
json(res, { error: "extension_validation_failed", diagnostics: validation.diagnostics }, 400);
|
|
357
388
|
return true;
|
|
358
389
|
}
|
|
359
|
-
const existing = await getExtensionByName(validation.manifest.name);
|
|
360
390
|
const writerAgentId = principal.kind === "agent" ? principal.agentId : undefined;
|
|
361
391
|
const updatedBy = await resolveHttpAuditUserId(req, writerAgentId);
|
|
362
392
|
const shouldActivate = principal.kind !== "agent" && existing?.enabled === true;
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
393
|
+
// Enforce ownership again inside the upsert transaction: validation can yield
|
|
394
|
+
// while another agent installs the same name.
|
|
395
|
+
const ownerOnly = ownerOnlyAgentId(principal);
|
|
396
|
+
let result: InstallExtensionResult;
|
|
397
|
+
try {
|
|
398
|
+
result = await installExtension({
|
|
399
|
+
manifest: validation.manifest,
|
|
400
|
+
files: parsed.body.files,
|
|
401
|
+
priority: parsed.body.priority,
|
|
402
|
+
config: parsed.body.config,
|
|
403
|
+
agentId: writerAgentId,
|
|
404
|
+
createdBy: updatedBy,
|
|
405
|
+
activate: shouldActivate,
|
|
406
|
+
ownerOnly,
|
|
407
|
+
});
|
|
408
|
+
} catch (error) {
|
|
409
|
+
if (!(error instanceof ExtensionOwnershipError)) throw error;
|
|
410
|
+
jsonError(res, error.message, 403);
|
|
411
|
+
return true;
|
|
412
|
+
}
|
|
372
413
|
let extension = result.extension;
|
|
373
414
|
if (shouldActivate) {
|
|
374
415
|
try {
|
|
@@ -446,19 +487,42 @@ export async function handleExtensions(
|
|
|
446
487
|
if (patchRoute.match(req.method, pathSegments)) {
|
|
447
488
|
const parsed = await patchRoute.parse(req, res, pathSegments, queryParams);
|
|
448
489
|
if (!parsed) return true;
|
|
449
|
-
const
|
|
490
|
+
const stored = await getExtensionById(parsed.params.id);
|
|
491
|
+
if (!stored) {
|
|
492
|
+
jsonError(res, "Extension not found", 404);
|
|
493
|
+
return true;
|
|
494
|
+
}
|
|
495
|
+
const principal = await requirePermission(req, res, agentId, "extension.write", {
|
|
496
|
+
kind: "extension",
|
|
497
|
+
extensionId: stored.id,
|
|
498
|
+
createdByAgentId: stored.createdByAgentId,
|
|
499
|
+
});
|
|
450
500
|
if (!principal) return true;
|
|
451
501
|
const writerAgentId = principal.kind === "agent" ? principal.agentId : undefined;
|
|
452
|
-
const
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
502
|
+
const ownerOnly = ownerOnlyAgentId(principal);
|
|
503
|
+
// PATCH reloads live code; ordinary owners may edit only disabled drafts.
|
|
504
|
+
if (
|
|
505
|
+
stored.enabled &&
|
|
506
|
+
ownerOnly &&
|
|
507
|
+
!(await requirePermission(req, res, agentId, "extension.activate"))
|
|
508
|
+
) {
|
|
509
|
+
return true;
|
|
510
|
+
}
|
|
511
|
+
const config = parsed.body.config
|
|
512
|
+
? preserveRedactedConfigValues(parsed.body.config, stored.configJson)
|
|
513
|
+
: parsed.body.config;
|
|
514
|
+
let extension: Extension | null;
|
|
515
|
+
try {
|
|
516
|
+
extension = await updateExtensionMeta(parsed.params.id, {
|
|
517
|
+
...parsed.body,
|
|
518
|
+
...(config === undefined ? {} : { config }),
|
|
519
|
+
updatedBy: await resolveHttpAuditUserId(req, writerAgentId),
|
|
520
|
+
ownerOnly,
|
|
521
|
+
});
|
|
522
|
+
} catch (error) {
|
|
523
|
+
respondLifecycleError(res, error);
|
|
524
|
+
return true;
|
|
525
|
+
}
|
|
462
526
|
if (!extension) {
|
|
463
527
|
jsonError(res, "Extension not found", 404);
|
|
464
528
|
return true;
|
|
@@ -478,18 +542,28 @@ export async function handleExtensions(
|
|
|
478
542
|
if (deleteRoute.match(req.method, pathSegments)) {
|
|
479
543
|
const parsed = await deleteRoute.parse(req, res, pathSegments, queryParams);
|
|
480
544
|
if (!parsed) return true;
|
|
481
|
-
const
|
|
482
|
-
if (!
|
|
483
|
-
const extension = await getExtensionById(parsed.params.id);
|
|
484
|
-
if (!extension) {
|
|
545
|
+
const stored = await getExtensionById(parsed.params.id);
|
|
546
|
+
if (!stored) {
|
|
485
547
|
jsonError(res, "Extension not found", 404);
|
|
486
548
|
return true;
|
|
487
549
|
}
|
|
550
|
+
const principal = await requirePermission(req, res, agentId, "extension.write", {
|
|
551
|
+
kind: "extension",
|
|
552
|
+
extensionId: stored.id,
|
|
553
|
+
createdByAgentId: stored.createdByAgentId,
|
|
554
|
+
});
|
|
555
|
+
if (!principal) return true;
|
|
556
|
+
const extension = stored;
|
|
488
557
|
if (extension.enabled) {
|
|
489
558
|
jsonError(res, "Disable the extension before uninstalling it", 409);
|
|
490
559
|
return true;
|
|
491
560
|
}
|
|
492
|
-
|
|
561
|
+
try {
|
|
562
|
+
await deleteExtension(extension.id, ownerOnlyAgentId(principal));
|
|
563
|
+
} catch (error) {
|
|
564
|
+
respondLifecycleError(res, error);
|
|
565
|
+
return true;
|
|
566
|
+
}
|
|
493
567
|
deleteRoute.respond(res, 200, { deleted: true });
|
|
494
568
|
return true;
|
|
495
569
|
}
|
package/src/http/status.ts
CHANGED
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
} from "../be/db";
|
|
35
35
|
import { getEmbeddingProvider } from "../be/memory";
|
|
36
36
|
import { getFileStorageProvider } from "../fs/registry";
|
|
37
|
+
import { getSlackConfiguration } from "../slack/config";
|
|
37
38
|
import { type AgentCredStatus, AutomationIntegrationIdSchema, ProviderNameSchema } from "../types";
|
|
38
39
|
import { route } from "./route-def";
|
|
39
40
|
import { json, jsonError } from "./utils";
|
|
@@ -407,26 +408,37 @@ function embeddingsMilestone(): SetupMilestone {
|
|
|
407
408
|
}
|
|
408
409
|
|
|
409
410
|
function slackMilestone(state: AutomationSetupStates["slack"]): SetupMilestone {
|
|
410
|
-
const
|
|
411
|
-
const disabled = disable === "true" || disable === "1";
|
|
411
|
+
const config = getSlackConfiguration();
|
|
412
412
|
|
|
413
413
|
if (state === "unverified") {
|
|
414
|
+
let hint: string;
|
|
415
|
+
if (config.disabled) {
|
|
416
|
+
hint = "Slack is explicitly disabled (SLACK_DISABLE=true).";
|
|
417
|
+
} else if (!config.mode) {
|
|
418
|
+
hint = "Invalid SLACK_MODE. Use socket or http.";
|
|
419
|
+
} else if (config.mode === "http" && config.missingCredentials.length === 0) {
|
|
420
|
+
hint =
|
|
421
|
+
"HTTP credentials are configured, but HTTP ingress is unavailable until the receiver is installed.";
|
|
422
|
+
} else {
|
|
423
|
+
hint = `Set ${config.missingCredentials.join(" + ")} for Slack ${config.mode} mode.`;
|
|
424
|
+
}
|
|
414
425
|
return {
|
|
415
426
|
id: "slack",
|
|
416
|
-
label: "Slack
|
|
427
|
+
label: "Slack configured",
|
|
417
428
|
state: "unverified",
|
|
418
|
-
hint
|
|
419
|
-
? "Slack is explicitly disabled (SLACK_DISABLE=true)."
|
|
420
|
-
: "Set SLACK_BOT_TOKEN + SLACK_APP_TOKEN to connect Slack.",
|
|
429
|
+
hint,
|
|
421
430
|
action_url: automationIntegrationFixUrl("slack"),
|
|
422
431
|
};
|
|
423
432
|
}
|
|
424
|
-
|
|
425
|
-
// For now treat env-present as `verified` so the UX matches the brainstorm.
|
|
433
|
+
|
|
426
434
|
return {
|
|
427
435
|
id: "slack",
|
|
428
|
-
label: "Slack
|
|
429
|
-
state: "
|
|
436
|
+
label: "Slack configured",
|
|
437
|
+
state: "configured",
|
|
438
|
+
hint:
|
|
439
|
+
config.mode === "http"
|
|
440
|
+
? "HTTP credentials are configured, but HTTP ingress is unavailable until the receiver is installed."
|
|
441
|
+
: "Socket Mode credentials are configured; a live connection has not been verified.",
|
|
430
442
|
action_url: automationIntegrationFixUrl("slack"),
|
|
431
443
|
};
|
|
432
444
|
}
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import type { ProviderTraits } from "../providers/types";
|
|
19
|
+
import { getSlackConfiguration } from "../slack/config";
|
|
19
20
|
import type { ProviderName } from "../types";
|
|
20
21
|
import { isSteeringEnabled } from "../utils/steering-enabled";
|
|
21
22
|
import { matchesDefaultClaudeMd, matchesDefaultIdentityMd } from "./defaults";
|
|
@@ -54,11 +55,18 @@ const CLAUDE_MD_INJECT_PROVIDERS: ReadonlySet<string> = new Set(["codex", "openc
|
|
|
54
55
|
/** Providers that get the repo CLAUDE.md inlined until native loading is verified. */
|
|
55
56
|
const REPO_CLAUDE_MD_INLINE_PROVIDERS: ReadonlySet<string> = new Set(["opencode"]);
|
|
56
57
|
|
|
57
|
-
export function areSlackPromptToolsEnabled(
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
export function areSlackPromptToolsEnabled(
|
|
59
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
60
|
+
serverCapabilities?: string[],
|
|
61
|
+
): boolean {
|
|
62
|
+
const config = getSlackConfiguration(env);
|
|
63
|
+
if (config.disabled || !config.mode) return false;
|
|
64
|
+
|
|
65
|
+
// Preserve the socket credential gate. For the HTTP contract, workers use
|
|
66
|
+
// the server tool capability without needing the API-owned signing secret.
|
|
67
|
+
if (serverCapabilities && !serverCapabilities.includes("slack")) return false;
|
|
68
|
+
if (config.mode === "http" && serverCapabilities) return true;
|
|
69
|
+
return config.missingCredentials.length === 0;
|
|
62
70
|
}
|
|
63
71
|
|
|
64
72
|
export type BasePromptArgs = {
|
|
@@ -185,8 +193,8 @@ export const getBasePrompt = async (args: BasePromptArgs): Promise<string> => {
|
|
|
185
193
|
|
|
186
194
|
// H. Slack. One block for both roles; the scripts-only variant covers Slack
|
|
187
195
|
// via ctx.swarm.slack_* for Slack-originated tasks.
|
|
188
|
-
const slackPromptToolsEnabled = areSlackPromptToolsEnabled();
|
|
189
|
-
if (hasMcp && slackPromptToolsEnabled && !scriptsOnlyMode
|
|
196
|
+
const slackPromptToolsEnabled = areSlackPromptToolsEnabled(process.env, args.serverCapabilities);
|
|
197
|
+
if (hasMcp && slackPromptToolsEnabled && !scriptsOnlyMode) {
|
|
190
198
|
const slackResult = await resolveTemplateAsync("system.agent.slack", {});
|
|
191
199
|
prompt += slackResult.text;
|
|
192
200
|
}
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
export const CLAUDE_MANAGED_MODELS = [
|
|
28
28
|
"claude-fable-5-1",
|
|
29
29
|
"claude-mythos-5-1",
|
|
30
|
+
"claude-opus-5-5",
|
|
30
31
|
"claude-opus-5",
|
|
31
32
|
"claude-fable-5",
|
|
32
33
|
"claude-mythos-5",
|
|
@@ -69,6 +70,7 @@ export interface ClaudeManagedModelPricing extends ClaudeManagedTokenPricing {
|
|
|
69
70
|
* - claude-mythos-5-1: $10 / $50 / $0.25 / $12.50 (invite only, verified 2026-09-02)
|
|
70
71
|
* - claude-fable-5: $10 / $50 / $1.00 / $12.50 (verified 2026-06-10)
|
|
71
72
|
* - claude-mythos-5: $10 / $50 / $1.00 / $12.50 (limited availability, verified 2026-06-10)
|
|
73
|
+
* - claude-opus-5-5: $4 / $20 / $0.20 / $5.00 (verified 2026-09-22)
|
|
72
74
|
* - claude-opus-5: $5 / $25 / $0.50 / $6.25 (verified 2026-07-25)
|
|
73
75
|
* - claude-sonnet-5: $2 / $10 / $0.20 / $2.50 (standard rate, verified 2026-08-29)
|
|
74
76
|
* - claude-sonnet-4-6: $3 / $15 / $0.30 / $3.75 (in / out / cache-read / cache-write)
|
|
@@ -90,6 +92,12 @@ export const CLAUDE_MANAGED_MODEL_PRICING: Record<ClaudeManagedModel, ClaudeMana
|
|
|
90
92
|
cacheReadPerMillion: 0.25,
|
|
91
93
|
cacheWritePerMillion: 12.5,
|
|
92
94
|
},
|
|
95
|
+
"claude-opus-5-5": {
|
|
96
|
+
inputPerMillion: 4.0,
|
|
97
|
+
outputPerMillion: 20.0,
|
|
98
|
+
cacheReadPerMillion: 0.2,
|
|
99
|
+
cacheWritePerMillion: 5.0,
|
|
100
|
+
},
|
|
93
101
|
"claude-opus-5": {
|
|
94
102
|
inputPerMillion: 5.0,
|
|
95
103
|
outputPerMillion: 25.0,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Codex API-addressable models, verified from https://developers.openai.com/api/docs/models
|
|
3
|
-
* and https://developers.openai.com/api/docs/deprecations as of 2026-09-
|
|
3
|
+
* and https://developers.openai.com/api/docs/deprecations as of 2026-09-23.
|
|
4
4
|
*
|
|
5
5
|
* NOTE: `gpt-5.3-codex-spark` is intentionally excluded. It is a ChatGPT Pro
|
|
6
6
|
* research preview and is NOT API-addressable via the Codex SDK at launch.
|
|
@@ -20,6 +20,8 @@ import modelsDevCache from "../be/modelsdev-cache.json";
|
|
|
20
20
|
*/
|
|
21
21
|
export const CODEX_MODELS = [
|
|
22
22
|
"gpt-6-astra", // most capable model for complex reasoning, coding, and agentic work
|
|
23
|
+
"gpt-6-sol", // complex coding and agentic workflows
|
|
24
|
+
"gpt-6-luna", // focused, high-volume tasks
|
|
23
25
|
"gpt-5.6-sol", // frontier GPT-5.6 tier for complex reasoning/coding
|
|
24
26
|
"gpt-5.6-terra", // balanced GPT-5.6 tier
|
|
25
27
|
"gpt-5.6-luna", // fast/cheap GPT-5.6 tier for high-volume workloads
|
|
@@ -83,6 +85,8 @@ const MODELSDEV_OPENAI_MODELS =
|
|
|
83
85
|
|
|
84
86
|
const FALLBACK_CODEX_MODEL_CONTEXT_WINDOWS: Record<CodexModel, number> = {
|
|
85
87
|
"gpt-6-astra": 1_050_000,
|
|
88
|
+
"gpt-6-sol": 1_050_000,
|
|
89
|
+
"gpt-6-luna": 1_050_000,
|
|
86
90
|
"gpt-5.6-sol": 1_050_000,
|
|
87
91
|
"gpt-5.6-terra": 1_050_000,
|
|
88
92
|
"gpt-5.6-luna": 1_050_000,
|
|
@@ -153,6 +157,16 @@ export const FALLBACK_CODEX_MODEL_PRICING: Record<CodexModel, CodexModelPricing>
|
|
|
153
157
|
cachedInputPerMillion: 1.0,
|
|
154
158
|
outputPerMillion: 50.0,
|
|
155
159
|
},
|
|
160
|
+
"gpt-6-sol": {
|
|
161
|
+
inputPerMillion: 2.0,
|
|
162
|
+
cachedInputPerMillion: 0.2,
|
|
163
|
+
outputPerMillion: 10.0,
|
|
164
|
+
},
|
|
165
|
+
"gpt-6-luna": {
|
|
166
|
+
inputPerMillion: 0.1,
|
|
167
|
+
cachedInputPerMillion: 0.01,
|
|
168
|
+
outputPerMillion: 0.5,
|
|
169
|
+
},
|
|
156
170
|
"gpt-5.6-sol": {
|
|
157
171
|
inputPerMillion: 4.0,
|
|
158
172
|
cachedInputPerMillion: 0.4,
|