@desplega.ai/agent-swarm 2.7.4 → 2.7.5
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-g3ads55s.js +15 -0
- package/dist/{actions-gfrr9vb7.js → actions-zwfykqqk.js} +18 -18
- package/dist/{amp-adapter-0s58gm46.js → amp-adapter-z3s0ssdt.js} +3 -3
- package/dist/{app-stvq692g.js → app-vmp4fgep.js} +3 -3
- package/dist/{assistant-5s37fr9n.js → assistant-vwde653f.js} +28 -21
- package/dist/{boot-reembed-yzy1841n.js → boot-reembed-375t7tbk.js} +1 -1
- package/dist/{boot-reembed-cv82gz7y.js → boot-reembed-gq9rcpnj.js} +1 -1
- package/dist/{boot-scrub-sweep-8k4q95ap.js → boot-scrub-sweep-nd938kyf.js} +4 -4
- package/dist/{boot-seeds-ftt9htah.js → boot-seeds-aykx51v3.js} +4 -4
- package/dist/{boxd-515v1t8z.js → boxd-k1j26g3h.js} +1 -1
- package/dist/{claude-adapter-t00wrzeh.js → claude-adapter-8j4hm099.js} +7 -7
- package/dist/{claude-managed-adapter-g6vmjccb.js → claude-managed-adapter-dvs2xw5n.js} +2 -2
- package/dist/{claude-managed-setup-afpa82f7.js → claude-managed-setup-0wyynpn1.js} +3 -3
- package/dist/{claude-sdk-session-vj0c2azx.js → claude-sdk-session-q6wj5hmy.js} +9 -9
- package/dist/{cli-wndv9p7g.js → cli-0731hvbw.js} +6 -6
- package/dist/{cli-d2pzqej1.js → cli-0bxqnvq9.js} +719 -7
- package/dist/{cli-jkt52mgt.js → cli-0gey5fzy.js} +2 -2
- package/dist/{cli-1yekbyqm.js → cli-1338796d.js} +205 -48
- package/dist/{cli-1s1dqn1j.js → cli-1ayk1eas.js} +171 -123
- package/dist/{cli-a4btqqft.js → cli-1b7btd38.js} +1 -1
- package/dist/{cli-a2jw6ee5.js → cli-1p89xny0.js} +1 -1
- package/dist/{cli-v726afdm.js → cli-2pnswgh8.js} +1 -1
- package/dist/{cli-kvtc7aez.js → cli-3h4nhjn8.js} +42 -14
- package/dist/{cli-655xm9ms.js → cli-583frbyr.js} +1 -1
- package/dist/{cli-4r12t6w6.js → cli-5c4hjzne.js} +101 -4
- package/dist/{cli-az0bpf8p.js → cli-5pag6rmn.js} +3 -3
- package/dist/{cli-36g23z21.js → cli-6s7vdcta.js} +4 -4
- package/dist/{cli-rtk9g7av.js → cli-73jzwksr.js} +6 -2
- package/dist/{cli-jg0nfda6.js → cli-75gkpjvw.js} +52 -21
- package/dist/{cli-a81qevyg.js → cli-7a42nfy0.js} +20 -36
- package/dist/{cli-0sbkss7h.js → cli-7wcyk2s5.js} +2 -2
- package/dist/{cli-41z8xwj0.js → cli-7wspm5gm.js} +14 -4
- package/dist/{cli-byqfbnjw.js → cli-82ae98pz.js} +9 -9
- package/dist/{cli-bq2pcphn.js → cli-8hs41zy2.js} +1 -1
- package/dist/{cli-vqgnyh76.js → cli-98rw5dt5.js} +15 -3
- package/dist/{cli-9cctx1tn.js → cli-a22h291q.js} +1 -1
- package/dist/{cli-j4kt1mpb.js → cli-a47xy8eq.js} +3 -3
- package/dist/{cli-ycm6180s.js → cli-a7v854rf.js} +5 -3
- package/dist/{cli-98pke4vk.js → cli-ae7mrdf9.js} +2 -2
- package/dist/{cli-ahd90bwt.js → cli-afrrppsw.js} +6 -6
- package/dist/{cli-8yy525ad.js → cli-bhjt02p8.js} +2 -2
- package/dist/{cli-v1yw3wha.js → cli-bnz7a7qf.js} +4 -4
- package/dist/{cli-j4kw3rsx.js → cli-cm5yqn35.js} +18 -0
- package/dist/{cli-h55y2bjc.js → cli-dhar9qay.js} +2 -2
- package/dist/{cli-5gr1g711.js → cli-fqzx7gwa.js} +2 -2
- package/dist/{cli-tzrpv5sc.js → cli-ftyxyspd.js} +1 -1
- package/dist/cli-fw2w0kva.js +47 -0
- package/dist/{cli-2dfbv8qr.js → cli-fy6x31ps.js} +1 -0
- package/dist/{cli-mvckssyq.js → cli-g61qxmge.js} +5 -5
- package/dist/{cli-aq58fk5m.js → cli-g83s9ewh.js} +7 -1
- package/dist/{cli-224epwwf.js → cli-hn9hxmz9.js} +3 -3
- package/dist/{cli-5hjced2v.js → cli-j3jvnpe8.js} +6 -6
- package/dist/{cli-dae4sbgy.js → cli-jm2vfpfd.js} +2 -2
- package/dist/{cli-zn15c46z.js → cli-mjzynrse.js} +1 -1
- package/dist/{cli-a1fhj4n9.js → cli-mmwm7zbf.js} +2 -2
- package/dist/{cli-cq1pf336.js → cli-mry0qzym.js} +5 -5
- package/dist/{cli-bwty35gx.js → cli-mthwvjre.js} +1 -1
- package/dist/{cli-s0exq74r.js → cli-nmbmy64z.js} +3 -3
- package/dist/{cli-wcmnan2g.js → cli-nn4d8dne.js} +5 -5
- package/dist/{cli-jg4p5t36.js → cli-nzxr556s.js} +121 -51
- package/dist/{cli-bcz074zx.js → cli-p599f1qm.js} +1 -1
- package/dist/{cli-k76tgq03.js → cli-pywf3eh5.js} +2 -2
- package/dist/{cli-wk9md5px.js → cli-qxnf8z2z.js} +2 -2
- package/dist/{cli-je8yeyc5.js → cli-rhw40jgb.js} +5 -5
- package/dist/{cli-avgcz4ra.js → cli-rm6hqj3z.js} +406 -35
- package/dist/{cli-0fgr1w9b.js → cli-rpm2sgv0.js} +2 -2
- package/dist/{cli-t282jgab.js → cli-rqkxrmgw.js} +12 -12
- package/dist/{cli-2qpvmmkw.js → cli-s0qnd4wv.js} +1 -1
- package/dist/{cli-pwyevs29.js → cli-spknvxbq.js} +22 -21
- package/dist/{cli-9y354g3j.js → cli-srye3vdt.js} +1 -1
- package/dist/{cli-pe09p6dv.js → cli-tqgg40ek.js} +1 -1
- package/dist/{cli-f255yaqn.js → cli-vbyfwh92.js} +3 -3
- package/dist/{cli-gcbdjt47.js → cli-vfym7wmz.js} +6 -6
- package/dist/{cli-edmm9d9y.js → cli-vqypxzh4.js} +7 -7
- package/dist/{cli-1gm8jcyr.js → cli-wvaawacd.js} +13 -13
- package/dist/{cli-eny54typ.js → cli-wx3rhnm0.js} +1 -1
- package/dist/{cli-b1afgtj3.js → cli-xbkdm710.js} +3 -3
- package/dist/{cli-mc97xy2s.js → cli-xtjhfmpc.js} +16 -4
- package/dist/{cli-eqx6k993.js → cli-y24sc29k.js} +25 -13
- package/dist/{cli-ktmvb20s.js → cli-z6jkx23q.js} +12 -12
- package/dist/{cli-7n5sbw0z.js → cli-z8eh3ex8.js} +5 -5
- package/dist/cli-zh3fp8v2.js +151 -0
- package/dist/{cli-13jvmew3.js → cli-zppwg9p9.js} +7 -7
- package/dist/cli.js +18 -18
- package/dist/{codex-adapter-g0gctw29.js → codex-adapter-q6k3gnyg.js} +5 -5
- package/dist/{codex-hook-vrzz2xhr.js → codex-hook-9efm2x1m.js} +1 -1
- package/dist/{codex-login-0gg46ygn.js → codex-login-y0pmff1c.js} +1 -1
- package/dist/{codex-session-runner-dr2cxe1c.js → codex-session-runner-3mwmk3d9.js} +6 -6
- package/dist/{commands-1p07cvff.js → commands-evrenjn9.js} +2 -2
- package/dist/{controller-z0s7sv6r.js → controller-xjp8vswh.js} +4 -4
- package/dist/{controllers-connect-x9kvvhyk.js → controllers-connect-pp5jnxvc.js} +20 -20
- package/dist/{cursor-adapter-m5b98pvk.js → cursor-adapter-yf47w4t0.js} +2 -2
- package/dist/{db-rsh04kh3.js → db-rgfsh91f.js} +2 -2
- package/dist/{db-capk2raj.js → db-zxpw6aht.js} +3 -3
- package/dist/{devin-adapter-yxm87fe9.js → devin-adapter-r9phbnc9.js} +1 -1
- package/dist/{dispatcher-304q6fwa.js → dispatcher-smasgws7.js} +17 -17
- package/dist/{docker-7rxt0rry.js → docker-rrjhaqt9.js} +2 -2
- package/dist/{dsh-adapter-btewem0y.js → dsh-adapter-ftyy8dnp.js} +2 -2
- package/dist/{e2b-renc0k8q.js → e2b-qcaj675y.js} +2 -2
- package/dist/{e2b-7fc9b9bd.js → e2b-w1p0bnpm.js} +2 -2
- package/dist/{easter-egg-3d-fm1p3n4d.js → easter-egg-3d-yyts7p16.js} +1 -1
- package/dist/{embedding-space-s68v49ct.js → embedding-space-1z0mbg95.js} +6 -6
- package/dist/{embeddings-4ms3604w.js → embeddings-ygeg7tm7.js} +1 -1
- package/dist/{event-bus-dfjx2qdh.js → event-bus-g0ka3pbw.js} +1 -1
- package/dist/{execute-mcdgccjs.js → execute-14qhqp4d.js} +1 -1
- package/dist/{external-channel-9dxwfztn.js → external-channel-ttgrs3sx.js} +2 -2
- package/dist/fx-adapter-gt6pncj2.js +18 -0
- package/dist/{grok-adapter-05ecv4h0.js → grok-adapter-sm4m5k4g.js} +8 -8
- package/dist/handlers-vwmba1m2.js +31 -0
- package/dist/{heartbeat-3n94heh3.js → heartbeat-qahz4p62.js} +20 -20
- package/dist/{hook-zxwje86c.js → hook-4fd5wq5w.js} +4 -4
- package/dist/{hook-aadrn69x.js → hook-kj3d398m.js} +6 -6
- package/dist/{http-xzxk9mst.js → http-1ted0j1k.js} +100 -64
- package/dist/index-5r71rf98.js +32 -0
- package/dist/{index-d34f6r87.js → index-6rq3r5zb.js} +1 -1
- package/dist/{index-9j4zwcht.js → index-7v51awbn.js} +158 -672
- package/dist/index-anmwxs87.js +29 -0
- package/dist/{index-qeb82z37.js → index-q4b917zs.js} +1 -1
- package/dist/index-spp0ra5c.js +36 -0
- package/dist/{keepalive-w4aakbyk.js → keepalive-6cf311t5.js} +4 -4
- package/dist/lead-fjy418cw.js +69 -0
- package/dist/{maintenance-hbptpk6p.js → maintenance-a4bm1bmt.js} +1 -1
- package/dist/{oauth-refresh-sweep-217semrv.js → oauth-refresh-sweep-3h0dfw1k.js} +3 -3
- package/dist/{onboard-vz2s5df3.js → onboard-myn5hraa.js} +3 -3
- package/dist/{opencode-adapter-gtfd7d7v.js → opencode-adapter-p2nkb5am.js} +5 -5
- package/dist/{otel-impl-aefave37.js → otel-impl-a1a0ef6b.js} +2 -2
- package/dist/{pi-mono-adapter-f8h5yseh.js → pi-mono-adapter-rzmpb72a.js} +117 -23
- package/dist/{pricing-refresh-m1yhh9ya.js → pricing-refresh-83drrnxj.js} +3 -3
- package/dist/{rbac-roles-svj72cdf.js → rbac-roles-0fb6e7pj.js} +2 -2
- package/dist/{rbac-roles-rrw8twdz.js → rbac-roles-s8y6ecb5.js} +1 -1
- package/dist/{render-v2-amwbnfxh.js → render-v2-twmbgrz4.js} +3 -3
- package/dist/{resume-9cd6wf6z.js → resume-zfqc36xj.js} +7 -7
- package/dist/{runtime-fp4vrx7m.js → runtime-qwggdpqr.js} +1 -1
- package/dist/{session-access-21t6yjyg.js → session-access-sc9pn9da.js} +4 -4
- package/dist/{session-source-backfill-pxbzcsc6.js → session-source-backfill-qh07xr8g.js} +3 -3
- package/dist/{setup-4592tqz4.js → setup-4fr0m7a1.js} +1 -1
- package/dist/{virtual-modules-gzfnpmnz.js → virtual-modules-fh4ha15b.js} +2 -2
- package/dist/{work-objects-t9tcf174.js → work-objects-0wr8zxct.js} +20 -20
- package/dist/worker-0c5tyzqe.js +69 -0
- package/dist/{worker-follow-up-q32jh4yk.js → worker-follow-up-ktyyazyp.js} +17 -17
- package/dist/{x-b6wxntdt.js → x-vmmye1kb.js} +2 -2
- package/openapi.json +97 -32
- package/package.json +1 -1
- package/src/be/db/session-summaries.ts +8 -2
- package/src/be/db/session-tree.ts +174 -61
- package/src/be/db/session-visibility.ts +5 -4
- package/src/be/db.ts +8 -4
- package/src/be/migrations/259_session_summaries_open_tasks.sql +111 -0
- package/src/be/model-validation.ts +5 -1
- package/src/be/pricing-normalize.ts +7 -2
- package/src/be/scripts/typecheck.ts +1 -0
- package/src/be/seed/schedules-seeder.ts +135 -9
- package/src/be/seed/workflows-seeder.ts +65 -1
- package/src/be/seed-pricing.ts +23 -0
- package/src/be/steering.ts +50 -3
- package/src/be/swarm-config-guard.ts +1 -0
- package/src/commands/provider-credentials.ts +29 -2
- package/src/commands/runner.ts +86 -5
- package/src/extensions/contract-types.generated.ts +1 -1
- package/src/extensions/contract.ts +27 -1
- package/src/extensions/dispatcher.ts +4 -0
- package/src/http/agents.ts +1 -0
- package/src/http/mcp-bridge.ts +4 -0
- package/src/integrations/chat-sdk/inbound.ts +15 -5
- package/src/integrations/chat-sdk/steering.ts +3 -1
- package/src/kv-reserved-namespaces.ts +2 -0
- package/src/prompts/base-prompt.ts +4 -1
- package/src/prompts/session-templates.ts +26 -0
- package/src/providers/acp-adapter.ts +190 -26
- package/src/providers/acp-targets.ts +306 -6
- package/src/providers/amp-adapter.ts +1 -1
- package/src/providers/codex-adapter.ts +9 -44
- package/src/providers/codex-oauth/flow.ts +24 -3
- package/src/providers/codex-oauth/storage.ts +56 -17
- package/src/providers/codex-oauth/subscription.ts +67 -0
- package/src/providers/fx-adapter.ts +211 -0
- package/src/providers/index.ts +5 -1
- package/src/providers/mcp-loopback-proxy.ts +94 -0
- package/src/providers/pi-mono-adapter.ts +98 -13
- package/src/providers/pricing-sources.md +8 -0
- package/src/providers/reasoning-effort.ts +17 -1
- package/src/providers/types.ts +2 -1
- package/src/scheduler/scheduler.ts +36 -3
- package/src/scripts-runtime/sdk-allowlist.ts +1 -0
- package/src/scripts-runtime/types/stdlib.d.ts +5 -0
- package/src/scripts-runtime/types/swarm-extension.d.ts +33 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +5 -0
- package/src/server.ts +7 -0
- package/src/slack/assistant.ts +17 -1
- package/src/slack/handlers.ts +18 -5
- package/src/slack/left-threads.ts +65 -0
- package/src/slack/steering.ts +3 -0
- package/src/slack/thread-buffer.ts +40 -16
- package/src/tests/acp-adapter.test.ts +79 -0
- package/src/tests/base-prompt.test.ts +12 -0
- package/src/tests/chat-sdk-inbound.test.ts +30 -0
- package/src/tests/chatgpt-subscription-model-groups.test.ts +62 -0
- package/src/tests/chatgpt-subscription-pi.test.ts +170 -0
- package/src/tests/chatgpt-subscription-session-bench.test.ts +198 -0
- package/src/tests/codex-oauth-credential-info.test.ts +40 -0
- package/src/tests/codex-oauth-refresh-egress.test.ts +194 -0
- package/src/tests/context-window.test.ts +7 -0
- package/src/tests/explicit-model-validation.test.ts +99 -0
- package/src/tests/extensions-run-context.test.ts +11 -0
- package/src/tests/extensions-steering.test.ts +353 -0
- package/src/tests/extensions-validate.test.ts +5 -0
- package/src/tests/fixtures/extensions/steering-policy/hooks.ts +39 -0
- package/src/tests/fixtures/extensions/steering-policy/manifest.json +7 -0
- package/src/tests/fixtures/fake-fx.ts +167 -0
- package/src/tests/fixtures/fx/acp-responses-recorded.json +157 -0
- package/src/tests/fixtures/fx/acp-updates-recorded.jsonl +15 -0
- package/src/tests/fx-adapter.test.ts +771 -0
- package/src/tests/grok-adapter.test.ts +36 -0
- package/src/tests/mcp-loopback-proxy.test.ts +193 -0
- package/src/tests/model-tier-resolution.test.ts +3 -3
- package/src/tests/pricing-refresh.test.ts +5 -5
- package/src/tests/prompt-template-session.test.ts +5 -3
- package/src/tests/provider-registration.test.ts +2 -1
- package/src/tests/query-audit-plans.test.ts +3 -2
- package/src/tests/script-connections.test.ts +2 -0
- package/src/tests/seed-model-profiles.test.ts +2 -2
- package/src/tests/seed-schedules.test.ts +138 -0
- package/src/tests/session-cost-recompute-unit.test.ts +39 -0
- package/src/tests/session-costs-golden.test.ts +26 -0
- package/src/tests/session-summaries-plans.test.ts +120 -0
- package/src/tests/session-summaries.test.ts +72 -12
- package/src/tests/sessions-tree.test.ts +11 -3
- package/src/tests/slack-leave-thread.test.ts +431 -0
- package/src/tests/tool-annotations.test.ts +2 -1
- package/src/tests/workflow-engine-v2.test.ts +42 -0
- package/src/tests/workflow-script-principal.test.ts +207 -7
- package/src/tools/slack-leave-thread.ts +104 -0
- package/src/tools/steer-task.ts +3 -2
- package/src/tools/tool-config.ts +2 -1
- package/src/types.ts +19 -0
- package/src/utils/codex-auth-failure.ts +30 -0
- package/src/utils/context-window.ts +4 -1
- package/src/utils/credentials.ts +7 -0
- package/src/utils/fx-models.ts +43 -0
- package/src/workflows/cooldown.ts +3 -2
- package/src/workflows/engine.ts +24 -9
- package/templates/schedules/dreaming-daily/config.json +1 -1
- package/templates/schedules/dreaming-daily/content.md +6 -14
- package/templates/skills/swarm-docs/content.md +1 -0
- package/templates/workflows/dreaming/content.md +5 -1
- package/dist/acp-adapter-96dc64m2.js +0 -15
- package/dist/handlers-jg7v74ty.js +0 -31
- package/dist/index-8c1zbz59.js +0 -29
- package/dist/index-8k8tmfxd.js +0 -32
- package/dist/index-hq617xdj.js +0 -36
- package/dist/lead-567kw7x3.js +0 -68
- package/dist/worker-fjdqra6q.js +0 -68
|
@@ -6,11 +6,12 @@ import {
|
|
|
6
6
|
getLatestActiveTaskInThread2,
|
|
7
7
|
getLatestLeadTaskInThread2,
|
|
8
8
|
getMostRecentTaskInThread2,
|
|
9
|
+
SteeringBlockedError,
|
|
9
10
|
requestSteering,
|
|
10
11
|
init_steering2,
|
|
11
12
|
createLogEntry2,
|
|
12
13
|
init_db4
|
|
13
|
-
} from "./cli-
|
|
14
|
+
} from "./cli-1ayk1eas.js";
|
|
14
15
|
import {
|
|
15
16
|
ackSlackMessage,
|
|
16
17
|
init_ack,
|
|
@@ -26,7 +27,7 @@ import {
|
|
|
26
27
|
init_watcher,
|
|
27
28
|
getSlackApp2,
|
|
28
29
|
init_app3
|
|
29
|
-
} from "./cli-
|
|
30
|
+
} from "./cli-wvaawacd.js";
|
|
30
31
|
import {
|
|
31
32
|
TaskCreationBlockedError,
|
|
32
33
|
init_errors2,
|
|
@@ -36,20 +37,22 @@ import {
|
|
|
36
37
|
createSlackTaskWithFiles,
|
|
37
38
|
notifySlackFileFailures,
|
|
38
39
|
init_inbound_files,
|
|
40
|
+
isSlackThreadLeft,
|
|
41
|
+
init_left_threads,
|
|
39
42
|
extractSlackMessageText,
|
|
40
43
|
init_message_text,
|
|
41
44
|
createAdditiveBuffer,
|
|
42
45
|
init_additive_buffer
|
|
43
|
-
} from "./cli-
|
|
46
|
+
} from "./cli-1338796d.js";
|
|
44
47
|
import {
|
|
45
48
|
resolveSlackUserId,
|
|
46
49
|
rewriteSlackMentions,
|
|
47
50
|
init_enrich
|
|
48
|
-
} from "./cli-
|
|
51
|
+
} from "./cli-nmbmy64z.js";
|
|
49
52
|
import {
|
|
50
53
|
findUserByExternalId,
|
|
51
54
|
init_users
|
|
52
|
-
} from "./cli-
|
|
55
|
+
} from "./cli-bhjt02p8.js";
|
|
53
56
|
import {
|
|
54
57
|
isSteeringEnabled2,
|
|
55
58
|
init_steering_enabled
|
|
@@ -57,7 +60,7 @@ import {
|
|
|
57
60
|
import {
|
|
58
61
|
scrubSecrets,
|
|
59
62
|
init_secret_scrubber
|
|
60
|
-
} from "./cli-
|
|
63
|
+
} from "./cli-1b7btd38.js";
|
|
61
64
|
import {
|
|
62
65
|
__esm,
|
|
63
66
|
__using,
|
|
@@ -135,7 +138,9 @@ async function requestSlackThreadSteering(args) {
|
|
|
135
138
|
onUnsupported: "degrade",
|
|
136
139
|
source: "slack",
|
|
137
140
|
createdByKind: "user",
|
|
138
|
-
createdByUserId: args.requestedByUserId
|
|
141
|
+
createdByUserId: args.requestedByUserId,
|
|
142
|
+
messageTimestamps: args.messageTimestamps,
|
|
143
|
+
slack: { channelId: args.channelId, threadTs: args.threadTs, userId: args.slackUserId }
|
|
139
144
|
});
|
|
140
145
|
for (const messageTs of args.messageTimestamps ?? []) {
|
|
141
146
|
await createLogEntry2({
|
|
@@ -230,6 +235,10 @@ async function slackFlush(items, key, immediate) {
|
|
|
230
235
|
return;
|
|
231
236
|
}
|
|
232
237
|
const { channelId, threadTs } = split;
|
|
238
|
+
if (await isSlackThreadLeft(channelId, threadTs)) {
|
|
239
|
+
console.log(`[Slack] Buffer flush: dropping ${items.length} message(s) in left thread ${key}`);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
233
242
|
const originalRequesterId = items[0].userId;
|
|
234
243
|
const botUserId = items.find((item) => item.botUserId)?.botUserId;
|
|
235
244
|
console.log(`[Slack] Flushing buffer: ${key} (${items.length} messages, immediate=${immediate})`);
|
|
@@ -258,15 +267,32 @@ ${combinedText}`;
|
|
|
258
267
|
}) : (await findUserByExternalId("slack", originalRequesterId))?.id;
|
|
259
268
|
const nextSenderIndex = items.findIndex((item) => item.userId !== originalRequesterId);
|
|
260
269
|
const steeringItems = nextSenderIndex === -1 ? items : items.slice(0, nextSenderIndex);
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
270
|
+
let steering;
|
|
271
|
+
try {
|
|
272
|
+
steering = files.length === 0 ? await requestSlackThreadSteering({
|
|
273
|
+
channelId,
|
|
274
|
+
threadTs,
|
|
275
|
+
message: nextSenderIndex === -1 ? combinedText : await rewriteSlackMentions(steeringItems.map((item) => item.text).join(`
|
|
265
276
|
---
|
|
266
277
|
`), botUserId),
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
278
|
+
messageTimestamps: steeringItems.map((item) => item.ts),
|
|
279
|
+
requestedByUserId,
|
|
280
|
+
slackUserId: originalRequesterId
|
|
281
|
+
}) : null;
|
|
282
|
+
} catch (error) {
|
|
283
|
+
if (!(error instanceof SteeringBlockedError))
|
|
284
|
+
throw error;
|
|
285
|
+
console.info("[Slack] pre.task.steer blocked:", error.extension.name, error.reason);
|
|
286
|
+
if (app) {
|
|
287
|
+
for (const item of steeringItems) {
|
|
288
|
+
await ackSlackMessage(app.client, channelId, item.ts, "no_entry");
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
if (nextSenderIndex !== -1) {
|
|
292
|
+
await slackFlush(items.slice(nextSenderIndex), key, immediate);
|
|
293
|
+
}
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
270
296
|
if (steering) {
|
|
271
297
|
console.log(`[Slack] Buffer flushed → steering ${steering.result.outcome} for task ${steering.task.id}`);
|
|
272
298
|
const agent = steering.task.agentId ? await getAgentById2(steering.task.agentId) : undefined;
|
|
@@ -373,6 +399,7 @@ ${description}` : description;
|
|
|
373
399
|
var BUFFER_TIMEOUT_MS, slackBuffer;
|
|
374
400
|
var init_thread_buffer = __esm(() => {
|
|
375
401
|
init_db4();
|
|
402
|
+
init_steering2();
|
|
376
403
|
init_users();
|
|
377
404
|
init_additive_buffer();
|
|
378
405
|
init_context_key();
|
|
@@ -383,6 +410,7 @@ var init_thread_buffer = __esm(() => {
|
|
|
383
410
|
init_blocks();
|
|
384
411
|
init_enrich();
|
|
385
412
|
init_inbound_files();
|
|
413
|
+
init_left_threads();
|
|
386
414
|
init_message_text();
|
|
387
415
|
init_render_v2();
|
|
388
416
|
init_responses();
|
|
@@ -2,6 +2,23 @@ import {
|
|
|
2
2
|
__esm
|
|
3
3
|
} from "./cli-242037k3.js";
|
|
4
4
|
|
|
5
|
+
// packages/model-catalog/src/chatgpt-subscription.ts
|
|
6
|
+
function chatgptSubscriptionModelId(model) {
|
|
7
|
+
const trimmed = model?.trim() ?? "";
|
|
8
|
+
const prefix = `${CHATGPT_SUBSCRIPTION_PROVIDER}/`;
|
|
9
|
+
if (!trimmed.toLowerCase().startsWith(prefix))
|
|
10
|
+
return null;
|
|
11
|
+
const id = trimmed.slice(prefix.length);
|
|
12
|
+
return id && !id.includes("/") ? id : null;
|
|
13
|
+
}
|
|
14
|
+
function isChatgptSubscriptionModel(model) {
|
|
15
|
+
return chatgptSubscriptionModelId(model) !== null;
|
|
16
|
+
}
|
|
17
|
+
var CHATGPT_SUBSCRIPTION_PROVIDER = "openai-codex", CHATGPT_SUBSCRIPTION_HARNESSES;
|
|
18
|
+
var init_chatgpt_subscription = __esm(() => {
|
|
19
|
+
CHATGPT_SUBSCRIPTION_HARNESSES = ["pi"];
|
|
20
|
+
});
|
|
21
|
+
|
|
5
22
|
// packages/model-catalog/src/display.ts
|
|
6
23
|
var init_display = () => {};
|
|
7
24
|
|
|
@@ -153,7 +170,27 @@ function harnessCatalogSection(harness) {
|
|
|
153
170
|
return HARNESS_CATALOG_SECTION[harness] ?? null;
|
|
154
171
|
}
|
|
155
172
|
function isHarnessModelJudged(harness) {
|
|
156
|
-
return !!harness && (harnessCatalogSection(harness) !== null || harness === "grok");
|
|
173
|
+
return !!harness && (harnessCatalogSection(harness) !== null || harness === "grok" || harness === "fx");
|
|
174
|
+
}
|
|
175
|
+
function fxModelRoute(model) {
|
|
176
|
+
const id = model.trim();
|
|
177
|
+
if (!id)
|
|
178
|
+
return { error: `An empty model has no fx route. ${FX_ROUTES_HINT}` };
|
|
179
|
+
const slash = id.indexOf("/");
|
|
180
|
+
if (slash < 0)
|
|
181
|
+
return { fxProvider: "openai", fxModel: id, keyVar: "OPENAI_API_KEY" };
|
|
182
|
+
const namespace = id.slice(0, slash).toLowerCase();
|
|
183
|
+
const rest = id.slice(slash + 1).trim();
|
|
184
|
+
if (namespace === "openrouter" && rest) {
|
|
185
|
+
return { fxProvider: "openrouter", fxModel: rest, keyVar: "OPENROUTER_API_KEY" };
|
|
186
|
+
}
|
|
187
|
+
if (namespace === "vercel" && rest) {
|
|
188
|
+
return { fxProvider: "gateway", fxModel: rest, keyVar: "AI_GATEWAY_API_KEY" };
|
|
189
|
+
}
|
|
190
|
+
const reason = FX_REJECTED_NAMESPACES[namespace];
|
|
191
|
+
return {
|
|
192
|
+
error: `Model "${id}" has no fx route${reason ? `: ${reason}` : ""}. ${FX_ROUTES_HINT}`
|
|
193
|
+
};
|
|
157
194
|
}
|
|
158
195
|
function normalizeGrokModel(model) {
|
|
159
196
|
return model.trim().replace(XAI_PREFIX_RE, "");
|
|
@@ -228,8 +265,14 @@ function buildClaudeShortnameMap(models) {
|
|
|
228
265
|
return out;
|
|
229
266
|
}
|
|
230
267
|
function harnessModelMismatch(model, harness, sections, context = {}) {
|
|
268
|
+
const subscriptionId = chatgptSubscriptionModelId(model);
|
|
269
|
+
if (harness && subscriptionId && !CHATGPT_SUBSCRIPTION_HARNESSES.includes(harness)) {
|
|
270
|
+
return subscriptionMismatchMessage(model.trim(), subscriptionId, harness, context);
|
|
271
|
+
}
|
|
231
272
|
if (harness === "grok")
|
|
232
273
|
return grokModelMismatch(model, sections, context);
|
|
274
|
+
if (harness === "fx")
|
|
275
|
+
return fxModelMismatch(model, sections, context);
|
|
233
276
|
const section = harness ? harnessCatalogSection(harness) : null;
|
|
234
277
|
if (!harness || !section)
|
|
235
278
|
return null;
|
|
@@ -291,6 +334,37 @@ function grokModelMismatch(model, sections, context) {
|
|
|
291
334
|
}
|
|
292
335
|
return null;
|
|
293
336
|
}
|
|
337
|
+
function fxModelMismatch(model, sections, context) {
|
|
338
|
+
const id = model.trim();
|
|
339
|
+
if (!id)
|
|
340
|
+
return null;
|
|
341
|
+
const agent = context.agentId ? ` of agent "${context.agentName ?? context.agentId}" (${context.agentId})` : "";
|
|
342
|
+
const fail = (reason) => `Model "${id}" does not run on the fx harness${agent}. ${reason} Use modelTier (smol, regular, smart, ultra) for portable intent, or omit model and let the assignee resolve it.`;
|
|
343
|
+
if (isAlias(id)) {
|
|
344
|
+
const parsed = parseAlias(id);
|
|
345
|
+
if (!parsed)
|
|
346
|
+
return null;
|
|
347
|
+
return parsed.kind === "openrouter" || parsed.kind === "openai" ? null : fail(`A latest:${parsed.kind} alias resolves to an id fx cannot route. ${FX_ROUTES_HINT}`);
|
|
348
|
+
}
|
|
349
|
+
const route = fxModelRoute(id);
|
|
350
|
+
if ("error" in route)
|
|
351
|
+
return fail(route.error);
|
|
352
|
+
if (route.fxProvider !== "openai")
|
|
353
|
+
return null;
|
|
354
|
+
if (Object.hasOwn(sections.openai?.models ?? {}, id))
|
|
355
|
+
return null;
|
|
356
|
+
for (const [name, other] of Object.entries(sections)) {
|
|
357
|
+
if (name === "openai" || !other?.models)
|
|
358
|
+
continue;
|
|
359
|
+
if (Object.hasOwn(other.models, id) || name === "anthropic" && isClaudeShortname(id, other)) {
|
|
360
|
+
return fail(`A bare id runs on OpenAI (OPENAI_API_KEY), and "${id}" is in the ${name} catalog, not openai. ${FX_ROUTES_HINT}`);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
return null;
|
|
364
|
+
}
|
|
365
|
+
function isClaudeShortname(id, section) {
|
|
366
|
+
return Object.hasOwn(buildClaudeShortnameMap(section.models), id);
|
|
367
|
+
}
|
|
294
368
|
function grokMismatchMessage(model, sections, context) {
|
|
295
369
|
const agent = context.agentId ? ` of agent "${context.agentName ?? context.agentId}" (${context.agentId})` : "";
|
|
296
370
|
const pool = sections.xai?.models ? [sections.xai.models] : Object.values(sections).map((section) => section?.models ?? {});
|
|
@@ -307,6 +381,11 @@ function grokMismatchMessage(model, sections, context) {
|
|
|
307
381
|
const examples = ids.length ? ` (for example: ${ids.slice(0, MAX_EXAMPLE_IDS).join(", ")}${extra > 0 ? ` and ${extra} more` : ""})` : "";
|
|
308
382
|
return `Model "${model}" does not run on the grok harness${agent}. The grok harness accepts xai catalog models${examples} and openrouter/<vendor>/<id>. Use modelTier (smol, regular, smart, ultra) for portable intent, or omit model and let the assignee resolve it.`;
|
|
309
383
|
}
|
|
384
|
+
function subscriptionMismatchMessage(model, bareId, harness, context) {
|
|
385
|
+
const agent = context.agentId ? ` of agent "${context.agentName ?? context.agentId}" (${context.agentId})` : "";
|
|
386
|
+
const codexHint = harness === "codex" ? ` On codex, use "${bareId}": codex runs it on the pool directly.` : "";
|
|
387
|
+
return `Model "${model}" does not run on the ${harness} harness${agent}. The ChatGPT subscription prefix (openai-codex/) is for the ${CHATGPT_SUBSCRIPTION_HARNESSES.join(" and ")} harness.${codexHint}`;
|
|
388
|
+
}
|
|
310
389
|
function harnessMismatchMessage(model, harness, section, own, context) {
|
|
311
390
|
const agent = context.agentId ? ` of agent "${context.agentName ?? context.agentId}" (${context.agentId})` : "";
|
|
312
391
|
const ids = harnessModelIds(harness, own);
|
|
@@ -314,14 +393,20 @@ function harnessMismatchMessage(model, harness, section, own, context) {
|
|
|
314
393
|
const examples = ids.slice(0, MAX_EXAMPLE_IDS).join(", ") + (extra > 0 ? ` and ${extra} more` : "");
|
|
315
394
|
return `Model "${model}" does not run on the ${harness} harness${agent}. The ${harness} harness accepts ${section} catalog models, for example: ${examples}. Use modelTier (smol, regular, smart, ultra) for portable intent, or omit model and let the assignee resolve it.`;
|
|
316
395
|
}
|
|
317
|
-
var HARNESS_CATALOG_SECTION, XAI_PREFIX_RE, GROK_ID_RE, DATED_ID_RE3, ISO_DATED_ID_RE, CODEX_EXCLUDED_TOKENS, CODEX_MIN_GPT_MAJOR = 5, CONTEXT_SUFFIX_RE, MAX_EXAMPLE_IDS = 8;
|
|
396
|
+
var HARNESS_CATALOG_SECTION, FX_REJECTED_NAMESPACES, FX_ROUTES_HINT = "The fx harness runs openrouter/<vendor>/<id> (OPENROUTER_API_KEY), vercel/<vendor>/<id> (AI_GATEWAY_API_KEY) or a bare OpenAI id (OPENAI_API_KEY).", XAI_PREFIX_RE, GROK_ID_RE, DATED_ID_RE3, ISO_DATED_ID_RE, CODEX_EXCLUDED_TOKENS, CODEX_MIN_GPT_MAJOR = 5, CONTEXT_SUFFIX_RE, MAX_EXAMPLE_IDS = 8;
|
|
318
397
|
var init_harness_models = __esm(() => {
|
|
398
|
+
init_chatgpt_subscription();
|
|
319
399
|
init_resolve_alias();
|
|
320
400
|
HARNESS_CATALOG_SECTION = {
|
|
321
401
|
claude: "anthropic",
|
|
322
402
|
"claude-managed": "anthropic",
|
|
323
403
|
codex: "openai"
|
|
324
404
|
};
|
|
405
|
+
FX_REJECTED_NAMESPACES = {
|
|
406
|
+
nan: "fx rejects NaN's streams (InconsistentFinishReason on its trailing usage chunk, fx 0.0.15)",
|
|
407
|
+
helmcode: "Helmcode is not verified on fx yet",
|
|
408
|
+
anthropic: "fx cannot speak the Anthropic Messages API; use openrouter/anthropic/<id> or vercel/anthropic/<id>"
|
|
409
|
+
};
|
|
325
410
|
XAI_PREFIX_RE = /^xai\//i;
|
|
326
411
|
GROK_ID_RE = /^grok-[^/]+$/i;
|
|
327
412
|
DATED_ID_RE3 = /-\d{8}$/;
|
|
@@ -671,6 +756,12 @@ function grokCatalogRef(model) {
|
|
|
671
756
|
}
|
|
672
757
|
return { providerId: "xai", modelId: id };
|
|
673
758
|
}
|
|
759
|
+
function fxCatalogRef(model) {
|
|
760
|
+
const route = fxModelRoute(model);
|
|
761
|
+
if ("error" in route || route.fxProvider !== "gateway")
|
|
762
|
+
return null;
|
|
763
|
+
return { providerId: "vercel", modelId: route.fxModel };
|
|
764
|
+
}
|
|
674
765
|
function cursorCatalogRef(model) {
|
|
675
766
|
const id = model.trim().toLowerCase();
|
|
676
767
|
if (/^(gpt-|o\d)/.test(id))
|
|
@@ -713,6 +804,9 @@ function applyHarnessOverrides(harness, modelId, facts, levels) {
|
|
|
713
804
|
} else if (harness !== "codex" && harness !== "cursor" && harness !== "opencode" && harness !== "pi") {
|
|
714
805
|
result = result.filter((l) => l !== "max");
|
|
715
806
|
}
|
|
807
|
+
if (harness === "fx") {
|
|
808
|
+
result = result.filter((l) => l !== "off");
|
|
809
|
+
}
|
|
716
810
|
if (harness === "codex") {
|
|
717
811
|
const isCodexMax = /-codex-max$/.test(modelId);
|
|
718
812
|
const isCodexNonMax = /-codex$/.test(modelId) && !isCodexMax;
|
|
@@ -738,6 +832,7 @@ function claudeCatalogModelId(modelId, models) {
|
|
|
738
832
|
}
|
|
739
833
|
var REASONING_EFFORT_LEVELS, REASONING_HARNESSES, FALLBACK_LEVELS, EFFORT_VALUE_MAP;
|
|
740
834
|
var init_reasoning = __esm(() => {
|
|
835
|
+
init_chatgpt_subscription();
|
|
741
836
|
init_harness_models();
|
|
742
837
|
REASONING_EFFORT_LEVELS = ["off", "low", "medium", "high", "xhigh", "max"];
|
|
743
838
|
REASONING_HARNESSES = [
|
|
@@ -748,7 +843,8 @@ var init_reasoning = __esm(() => {
|
|
|
748
843
|
"dsh",
|
|
749
844
|
"cursor",
|
|
750
845
|
"amp",
|
|
751
|
-
"grok"
|
|
846
|
+
"grok",
|
|
847
|
+
"fx"
|
|
752
848
|
];
|
|
753
849
|
FALLBACK_LEVELS = ["low", "medium", "high"];
|
|
754
850
|
EFFORT_VALUE_MAP = {
|
|
@@ -763,6 +859,7 @@ var init_reasoning = __esm(() => {
|
|
|
763
859
|
|
|
764
860
|
// packages/model-catalog/src/index.ts
|
|
765
861
|
var init_src2 = __esm(() => {
|
|
862
|
+
init_chatgpt_subscription();
|
|
766
863
|
init_display();
|
|
767
864
|
init_harness_models();
|
|
768
865
|
init_merge();
|
|
@@ -773,4 +870,4 @@ var init_src2 = __esm(() => {
|
|
|
773
870
|
init_resolve_alias();
|
|
774
871
|
});
|
|
775
872
|
|
|
776
|
-
export { isAlias, parseAlias, resolveAlias, harnessCatalogSection, isHarnessModelJudged, normalizeGrokModel, harnessModelIds, modelFamilyKey, buildClaudeShortnameMap, harnessModelMismatch, openAICompatibleProviders, openAICompatibleProviderIds, providerKeyVars, openAICompatibleKeyVars, baseUrlEnvVar, openAICompatibleBaseUrlVars, baseUrlOverride, ignoredBaseUrlVar, providerBaseUrl, openAICompatibleProvider, providerForModel, providerForKeyVar, providerKeyFromEnv, providerHarnessModels, withAgentChatRegistrySections, registryCatalogSections, withRegistryCatalogSections, dshCatalogRef, grokCatalogRef, cursorCatalogRef, reasoningLevelsFor, claudeCatalogModelId, init_src2 };
|
|
873
|
+
export { CHATGPT_SUBSCRIPTION_PROVIDER, chatgptSubscriptionModelId, isChatgptSubscriptionModel, isAlias, parseAlias, resolveAlias, harnessCatalogSection, isHarnessModelJudged, fxModelRoute, normalizeGrokModel, harnessModelIds, modelFamilyKey, buildClaudeShortnameMap, harnessModelMismatch, openAICompatibleProviders, openAICompatibleProviderIds, providerKeyVars, openAICompatibleKeyVars, baseUrlEnvVar, openAICompatibleBaseUrlVars, baseUrlOverride, ignoredBaseUrlVar, providerBaseUrl, openAICompatibleProvider, providerForModel, providerForKeyVar, providerKeyFromEnv, providerHarnessModels, withAgentChatRegistrySections, registryCatalogSections, withRegistryCatalogSections, dshCatalogRef, grokCatalogRef, fxCatalogRef, cursorCatalogRef, reasoningLevelsFor, claudeCatalogModelId, init_src2 };
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
isGrokOpenRouterModel,
|
|
3
3
|
grokTargetProfile,
|
|
4
4
|
ACPAdapter2
|
|
5
|
-
} from "./cli-
|
|
5
|
+
} from "./cli-rm6hqj3z.js";
|
|
6
6
|
import {
|
|
7
7
|
getOpenRouterBaseUrl,
|
|
8
8
|
getOpenRouterAttributionHeaders,
|
|
@@ -11,11 +11,11 @@ import {
|
|
|
11
11
|
import {
|
|
12
12
|
registerVolatileSecret,
|
|
13
13
|
init_secret_scrubber
|
|
14
|
-
} from "./cli-
|
|
14
|
+
} from "./cli-1b7btd38.js";
|
|
15
15
|
import {
|
|
16
16
|
normalizeGrokModel,
|
|
17
17
|
init_src2
|
|
18
|
-
} from "./cli-
|
|
18
|
+
} from "./cli-5c4hjzne.js";
|
|
19
19
|
|
|
20
20
|
// src/providers/grok-adapter.ts
|
|
21
21
|
init_src2();
|
|
@@ -7,21 +7,21 @@ import {
|
|
|
7
7
|
tierConfigKey,
|
|
8
8
|
init_model_tier_keys,
|
|
9
9
|
init_db4
|
|
10
|
-
} from "./cli-
|
|
10
|
+
} from "./cli-1ayk1eas.js";
|
|
11
11
|
import {
|
|
12
12
|
ensureRbacSeedsSynced2,
|
|
13
13
|
init_rbac_roles
|
|
14
|
-
} from "./cli-
|
|
14
|
+
} from "./cli-8hs41zy2.js";
|
|
15
15
|
import {
|
|
16
16
|
seedPricingFromModelsDev,
|
|
17
17
|
init_seed_pricing
|
|
18
|
-
} from "./cli-
|
|
18
|
+
} from "./cli-xtjhfmpc.js";
|
|
19
19
|
import {
|
|
20
20
|
MODEL_TIERS,
|
|
21
21
|
DEFAULT_MODEL_TIER_MAP,
|
|
22
22
|
ProviderNameSchema,
|
|
23
23
|
init_types4
|
|
24
|
-
} from "./cli-
|
|
24
|
+
} from "./cli-7wspm5gm.js";
|
|
25
25
|
import {
|
|
26
26
|
__esm
|
|
27
27
|
} from "./cli-242037k3.js";
|
|
@@ -2,11 +2,12 @@ import {
|
|
|
2
2
|
runtimeCatalogSection,
|
|
3
3
|
runtimeCatalogModel,
|
|
4
4
|
init_runtime_model_catalog
|
|
5
|
-
} from "./cli-
|
|
5
|
+
} from "./cli-1p89xny0.js";
|
|
6
6
|
import {
|
|
7
|
+
chatgptSubscriptionModelId,
|
|
7
8
|
buildClaudeShortnameMap,
|
|
8
9
|
init_src2
|
|
9
|
-
} from "./cli-
|
|
10
|
+
} from "./cli-5c4hjzne.js";
|
|
10
11
|
import {
|
|
11
12
|
__esm
|
|
12
13
|
} from "./cli-242037k3.js";
|
|
@@ -32,6 +33,9 @@ function getContextWindowSize(model) {
|
|
|
32
33
|
function getKnownContextWindowSize(model) {
|
|
33
34
|
if (!model)
|
|
34
35
|
return;
|
|
36
|
+
const subscriptionId = chatgptSubscriptionModelId(model);
|
|
37
|
+
if (subscriptionId)
|
|
38
|
+
return catalogContext("openai", subscriptionId);
|
|
35
39
|
const slash = model.indexOf("/");
|
|
36
40
|
if (slash > 0) {
|
|
37
41
|
const scoped = catalogContext(model.slice(0, slash), model.slice(slash + 1));
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
scrubSecrets,
|
|
7
7
|
init_secret_scrubber
|
|
8
|
-
} from "./cli-
|
|
8
|
+
} from "./cli-1b7btd38.js";
|
|
9
9
|
import {
|
|
10
10
|
__esm
|
|
11
11
|
} from "./cli-242037k3.js";
|
|
@@ -116,13 +116,13 @@ async function refreshAccessToken(refreshToken) {
|
|
|
116
116
|
})
|
|
117
117
|
});
|
|
118
118
|
if (!response.ok) {
|
|
119
|
-
const text = await response.text().catch(() => "");
|
|
119
|
+
const text = redactTokens(await response.text().catch(() => ""), [refreshToken]);
|
|
120
120
|
console.error("[codex-oauth] Token refresh failed:", response.status, text);
|
|
121
121
|
return { type: "failed", status: response.status, error: text.slice(0, 300) };
|
|
122
122
|
}
|
|
123
123
|
const json = await response.json();
|
|
124
124
|
if (!json.access_token || !json.refresh_token || typeof json.expires_in !== "number") {
|
|
125
|
-
console.error("[codex-oauth] Token refresh response missing fields:", json);
|
|
125
|
+
console.error("[codex-oauth] Token refresh response missing fields; got keys:", Object.keys(json).join(", "));
|
|
126
126
|
return { type: "failed" };
|
|
127
127
|
}
|
|
128
128
|
return {
|
|
@@ -132,10 +132,22 @@ async function refreshAccessToken(refreshToken) {
|
|
|
132
132
|
expires: Date.now() + json.expires_in * 1000
|
|
133
133
|
};
|
|
134
134
|
} catch (error) {
|
|
135
|
-
|
|
135
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
136
|
+
console.error("[codex-oauth] Token refresh error:", redactTokens(message, [refreshToken]));
|
|
136
137
|
return { type: "failed" };
|
|
137
138
|
}
|
|
138
139
|
}
|
|
140
|
+
function redactTokens(text, tokens) {
|
|
141
|
+
let out = text;
|
|
142
|
+
for (const token of tokens) {
|
|
143
|
+
if (!token)
|
|
144
|
+
continue;
|
|
145
|
+
const forms = new Set([token, encodeURIComponent(token), JSON.stringify(token).slice(1, -1)]);
|
|
146
|
+
for (const form of forms)
|
|
147
|
+
out = out.split(form).join("[REDACTED:codex_oauth_token]");
|
|
148
|
+
}
|
|
149
|
+
return scrubSecrets(out);
|
|
150
|
+
}
|
|
139
151
|
function getAccountId(accessToken) {
|
|
140
152
|
const payload = decodeJwt(accessToken);
|
|
141
153
|
const auth = payload?.[JWT_CLAIM_PATH];
|
|
@@ -384,6 +396,16 @@ function isStaleByAge(expires, maxAgeMs) {
|
|
|
384
396
|
const issuedAt = expires - ACCESS_TOKEN_TTL_MS;
|
|
385
397
|
return Date.now() - issuedAt > maxAgeMs;
|
|
386
398
|
}
|
|
399
|
+
function buildPoolRevalidationFailureReason(err, slot) {
|
|
400
|
+
if (err instanceof CodexOAuthRefreshError) {
|
|
401
|
+
if (err.reason === "lock_timeout") {
|
|
402
|
+
return `[auth-error] Codex pool slot ${slot} [...${err.keySuffix}] revalidation failed: timed out waiting for the refresh lock — transient, will retry on next task.`;
|
|
403
|
+
}
|
|
404
|
+
return `[auth-error] Codex pool slot ${slot} [...${err.keySuffix}] revalidation failed: refresh rejected (${err.status ?? "unknown status"} ${scrubSecrets(err.body ?? "")}) — credential likely revoked; re-run codex-login for this slot.`;
|
|
405
|
+
}
|
|
406
|
+
const message = scrubSecrets(err instanceof Error ? err.message : String(err));
|
|
407
|
+
return `[auth-error] Codex pool slot ${slot} revalidation failed (not a confirmed auth rejection, transient): ${message}`;
|
|
408
|
+
}
|
|
387
409
|
async function acquireCodexRefreshLock(apiUrl, apiKey, slot) {
|
|
388
410
|
const key = codexOAuthKeyForSlot(slot);
|
|
389
411
|
const res = await fetch(`${apiUrl}/api/oauth/refresh-locks/${encodeURIComponent(key)}`, {
|
|
@@ -465,22 +487,29 @@ async function loadAllCodexOAuthSlots(apiUrl, apiKey, options = {}) {
|
|
|
465
487
|
}
|
|
466
488
|
async function storeCodexOAuth(apiUrl, apiKey, creds, slot = 0) {
|
|
467
489
|
const key = codexOAuthKeyForSlot(slot);
|
|
468
|
-
const
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
490
|
+
const redact = (text) => redactTokens(text, [creds.access, creds.refresh]);
|
|
491
|
+
let res;
|
|
492
|
+
try {
|
|
493
|
+
res = await fetch(`${apiUrl}/api/config`, {
|
|
494
|
+
method: "PUT",
|
|
495
|
+
headers: {
|
|
496
|
+
"Content-Type": "application/json",
|
|
497
|
+
Authorization: `Bearer ${apiKey}`
|
|
498
|
+
},
|
|
499
|
+
body: JSON.stringify({
|
|
500
|
+
scope: "global",
|
|
501
|
+
key,
|
|
502
|
+
value: JSON.stringify(creds),
|
|
503
|
+
isSecret: true,
|
|
504
|
+
description: `Codex ChatGPT OAuth credentials slot ${slot} (stored by codex-login)`
|
|
505
|
+
})
|
|
506
|
+
});
|
|
507
|
+
} catch (error) {
|
|
508
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
509
|
+
throw new Error(`Failed to store ${key} config: ${redact(message)}`);
|
|
510
|
+
}
|
|
482
511
|
if (!res.ok) {
|
|
483
|
-
const text = await res.text().catch(() => "");
|
|
512
|
+
const text = redact(await res.text().catch(() => ""));
|
|
484
513
|
throw new Error(`Failed to store ${key} config: HTTP ${res.status} ${text}`);
|
|
485
514
|
}
|
|
486
515
|
}
|
|
@@ -531,7 +560,8 @@ async function persistCodexOAuth(apiUrl, apiKey, creds, slot = 0) {
|
|
|
531
560
|
try {
|
|
532
561
|
await storeCodexOAuth(apiUrl, apiKey, creds, slot);
|
|
533
562
|
} catch (err) {
|
|
534
|
-
|
|
563
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
564
|
+
console.error("[codex-oauth] persistCodexOAuth failed (non-fatal):", redactTokens(message, [creds.access, creds.refresh]));
|
|
535
565
|
}
|
|
536
566
|
}
|
|
537
567
|
async function getValidCodexOAuth(apiUrl, apiKey, slot = 0, opts) {
|
|
@@ -591,6 +621,7 @@ async function getValidCodexOAuth(apiUrl, apiKey, slot = 0, opts) {
|
|
|
591
621
|
}
|
|
592
622
|
var CODEX_OAUTH_KEY_LEGACY = "codex_oauth", MAX_CODEX_OAUTH_SLOT = 100, REFRESH_LOCK_TTL_MS, REFRESH_LOCK_WAIT_MS, REFRESH_LOCK_POLL_MS = 250, REFRESH_SKEW_MS, ACCESS_TOKEN_TTL_MS, CodexOAuthRefreshError;
|
|
593
623
|
var init_storage = __esm(() => {
|
|
624
|
+
init_secret_scrubber();
|
|
594
625
|
init_auth_json();
|
|
595
626
|
init_flow();
|
|
596
627
|
REFRESH_LOCK_TTL_MS = 2 * 60 * 1000;
|
|
@@ -615,4 +646,4 @@ var init_storage = __esm(() => {
|
|
|
615
646
|
};
|
|
616
647
|
});
|
|
617
648
|
|
|
618
|
-
export { _fetchHolder, CLIENT_ID, decodeJwt, exchangeAuthorizationCode2, getAccountId, extractChatgptPlanType, extractChatgptUserId, loginCodexOAuth, init_flow, deriveCodexKeySuffix, authJsonToCredentialSelection, credentialsToAuthJson, init_auth_json, MAX_CODEX_OAUTH_SLOT,
|
|
649
|
+
export { _fetchHolder, CLIENT_ID, decodeJwt, exchangeAuthorizationCode2, getAccountId, extractChatgptPlanType, extractChatgptUserId, loginCodexOAuth, init_flow, deriveCodexKeySuffix, authJsonToCredentialSelection, credentialsToAuthJson, init_auth_json, MAX_CODEX_OAUTH_SLOT, buildPoolRevalidationFailureReason, codexOAuthKeyForSlot, loadAllCodexOAuthSlots, storeCodexOAuth, persistCodexOAuth, getValidCodexOAuth, init_storage };
|