@noxsoft/anima 5.0.1 → 5.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{accounts-BOkEyUcS.js → accounts-CSCVz9k9.js} +7 -7
- package/dist/{acp-cli-BcshtFqY.js → acp-cli-DyVMXQS8.js} +1 -1
- package/dist/{agent-c49U1LxE.js → agent-CWQdTmzC.js} +3 -3
- package/dist/{agent-Cil6Zvns.js → agent-DiEXJmhj.js} +8 -8
- package/dist/{agents-2BloqCjm.js → agents-rAIsxGuA.js} +8 -8
- package/dist/{anthropic-direct-runner-BVlO2Vi5.js → anthropic-direct-runner--MPTWkYA.js} +228 -193
- package/dist/{anthropic-direct-runner-mh6c_WBB.js → anthropic-direct-runner-_uCPWuBb.js} +232 -197
- package/dist/{audit-BbmRSFjf.js → audit-DqjWCAbO.js} +7 -7
- package/dist/{auth-choice-BVAMr2Dk.js → auth-choice-o5GHtPGA.js} +57 -5
- package/dist/{auth-profiles-Chf1JBpl.js → auth-profiles-DriJ4HU5.js} +1 -1
- package/dist/{banner-CgxCSS-T.js → banner-Gtp-FQrx.js} +1 -1
- package/dist/build-info.json +3 -3
- package/dist/bundled/boot-md/handler.js +13 -13
- package/dist/bundled/bootstrap-extra-files/handler.js +3 -3
- package/dist/bundled/session-memory/handler.js +10 -10
- package/dist/canvas-host/a2ui/.bundle.hash +1 -1
- package/dist/{channel-web-Y8i3EzJq.js → channel-web-Dz0XZNjP.js} +4 -4
- package/dist/{channels-status-issues-BlmAMBCg.js → channels-status-issues-Dqd_vE0e.js} +2 -2
- package/dist/{chrome-B2-33FWf.js → chrome-CB6uZMvl.js} +1 -1
- package/dist/{chrome-Cxl7I5SB.js → chrome-CKvch3UL.js} +7 -7
- package/dist/{clack-prompter-B-ZJG628.js → clack-prompter-BRLXmV52.js} +1 -1
- package/dist/{clack-prompter-CCRr4nAr.js → clack-prompter-OFy356QZ.js} +1 -1
- package/dist/{cli-C3uw3mId.js → cli-BZz5MnAE.js} +29 -29
- package/dist/{cli-CfvBmuhw.js → cli-CJfwHH_z.js} +5 -5
- package/dist/{cli-session-BzZYmGP1.js → cli-session-8PeURiwF.js} +6 -6
- package/dist/{cli-session-DgUHOBYo.js → cli-session-CczB2Dni.js} +1 -1
- package/dist/{command-registry-DLofaVIN.js → command-registry-C9kvlc67.js} +12 -12
- package/dist/{common-FlJ-8clz.js → common-C5mWuFve.js} +2 -2
- package/dist/{completion-cli-C9KvX2ZF.js → completion-cli-Ci_MzRm6.js} +2 -2
- package/dist/{completion-cli-3eYvtAih.js → completion-cli-DhbIrk13.js} +1 -1
- package/dist/{config-B-9UciOO.js → config-DezP7V65.js} +2 -2
- package/dist/{config-cli-CBXWDtvj.js → config-cli-ePL5ncye.js} +1 -1
- package/dist/{config-cli-cmNuTlw0.js → config-cli-uk9vdQZH.js} +1 -1
- package/dist/{config-guard-qiKju2Fg.js → config-guard-CCOBZ77Q.js} +1 -1
- package/dist/{configure-CGTBBLR_.js → configure-CkGsX5z9.js} +9 -9
- package/dist/{configure-Dpk4lSoz.js → configure-D-9Ezgal.js} +11 -11
- package/dist/{configure-jlAKeuki.js → configure-DxKMnCHX.js} +40 -40
- package/dist/{configure-CH_-SNya.js → configure-KP7q9c7h.js} +4 -4
- package/dist/{control-service-CUhnhmpc.js → control-service-D3rS-Yd1.js} +3 -3
- package/dist/{cron-cli-CKs1evSF.js → cron-cli-3QY_K0l_.js} +1 -1
- package/dist/{daemon-cli-CSCFNzUo.js → daemon-cli-NZ84KRN8.js} +3 -3
- package/dist/{deliver-BYxbDIF0.js → deliver-BJn4EmMZ.js} +1 -1
- package/dist/{deliver-DkF6LCoS.js → deliver-BhezvxNA.js} +4 -4
- package/dist/{deps-D9266xfk.js → deps-CBLy0fqA.js} +1 -1
- package/dist/{dispatcher-BeO47t7A.js → dispatcher-Bk0gFz4b.js} +1 -1
- package/dist/{doctor-DJfgnQ67.js → doctor-Bto-K3wL.js} +16 -16
- package/dist/{doctor-CWmHUAjs.js → doctor-DsRSWr6B.js} +5 -5
- package/dist/{doctor-completion-CtCwd1fi.js → doctor-completion-B-SFdu-f.js} +1 -1
- package/dist/{doctor-completion-CmJmktDv.js → doctor-completion-OQXTo6RG.js} +1 -1
- package/dist/{doctor-config-flow-D_8YNTSK.js → doctor-config-flow-CEkHIHe5.js} +1 -1
- package/dist/entry.js +1 -1
- package/dist/extensionAPI.js +1531 -411
- package/dist/{frontmatter-BmBmtOUh.js → frontmatter-Dsa7N963.js} +1 -1
- package/dist/{gateway-cli-DYrzIvOE.js → gateway-cli-Buxz8Y2n.js} +17 -17
- package/dist/{gateway-cli-BazTmg20.js → gateway-cli-CEGPCQ_C.js} +52 -52
- package/dist/{health-BRSKF_iF.js → health-CMIY7xAI.js} +12 -12
- package/dist/{health-JqtB_B8C.js → health-DoGFlPcq.js} +6 -6
- package/dist/{heartbeat-visibility-BGj2czmk.js → heartbeat-visibility-BOyU9ccw.js} +2 -2
- package/dist/{heartbeat-visibility-pyFf6XBW.js → heartbeat-visibility-DuRmIKOk.js} +2 -2
- package/dist/{hooks-cli-B7g3jEC3.js → hooks-cli-B1NXXLxe.js} +30 -30
- package/dist/{hooks-cli-ZK4Z044T.js → hooks-cli-BuIU6v0Q.js} +6 -6
- package/dist/index.js +11 -11
- package/dist/{installs-DBvIs2By.js → installs-Drds9RDI.js} +1 -1
- package/dist/{lanes-DyM6NSSL.js → lanes-4_8h1ZQO.js} +274 -12
- package/dist/llm-slug-generator.js +10 -10
- package/dist/{login-BbfWLOBl.js → login-DwP4KleZ.js} +2 -2
- package/dist/{login-qr-BqhujMcQ.js → login-qr-wnynuvLt.js} +5 -5
- package/dist/{manager-CcawxgaC.js → manager-ibNP7jE3.js} +2 -2
- package/dist/{manager-DS1DfkbC.js → manager-j0ghUvcW.js} +4 -4
- package/dist/{media-IIqSkFpd.js → media-BLVMhFB3.js} +2 -2
- package/dist/{memory-cli-wDO418hx.js → memory-cli-DSWsPuub.js} +6 -6
- package/dist/{model-auth-Uxm-wRjR.js → model-auth-BKf-GZVK.js} +3 -3
- package/dist/{models-tQnX4hL4.js → models-BU0CytAy.js} +32 -32
- package/dist/{node-cli-DAcW-rfA.js → node-cli-DcwOFcxq.js} +8 -8
- package/dist/{onboard-Dd6xFMYB.js → onboard-Dd5wJkeU.js} +6 -6
- package/dist/{onboard-dasbF9G1.js → onboard-c84IExbH.js} +4 -4
- package/dist/{onboard-channels-DisvVyIs.js → onboard-channels-CCoMzCXV.js} +3 -3
- package/dist/{onboard-channels-BUv3VbAL.js → onboard-channels-DYr7fQZq.js} +1 -1
- package/dist/{onboard-helpers-49TVSf7J.js → onboard-helpers-BRp_xJvW.js} +1 -1
- package/dist/{onboarding-Dq3bCBjc.js → onboarding-192Oe9K6.js} +8 -8
- package/dist/{onboarding-6Xs4orLw.js → onboarding-BINruD5r.js} +4 -4
- package/dist/{outbound-CliT3nme.js → outbound-BVSyNp-t.js} +1 -1
- package/dist/{outbound-CLII4C2A.js → outbound-BaBDhLp1.js} +1 -1
- package/dist/{parse-timeout-BnOIKwx8.js → parse-timeout-C1INlSUG.js} +2 -2
- package/dist/{pi-auth-json-DLroEcea.js → pi-auth-json-BSLIRI41.js} +2 -2
- package/dist/{pi-embedded-CS4D_0t7.js → pi-embedded-DJF_gfcQ.js} +667 -372
- package/dist/{pi-tools.policy-RhdERrk3.js → pi-tools.policy-Dtytaq21.js} +3 -3
- package/dist/{plugin-registry-l3z9phEV.js → plugin-registry-B0k-53-_.js} +1 -1
- package/dist/{plugin-registry-esOxvV3X.js → plugin-registry-CqUo-PU_.js} +1 -1
- package/dist/plugin-sdk/agents/gemini-direct-runner.d.ts +38 -0
- package/dist/plugin-sdk/commands/onboard-types.d.ts +2 -2
- package/dist/{plugins-cli-D2v0n4BL.js → plugins-cli-BYLUFsjH.js} +33 -33
- package/dist/{plugins-cli-CbXtuN4b.js → plugins-cli-YjM8IsVo.js} +6 -6
- package/dist/{ports-DyX87qKc.js → ports-BmSDzOHm.js} +1 -1
- package/dist/{ports-COy7Yg_k.js → ports-Bv3sZ3bd.js} +1 -1
- package/dist/{program-y0NPJuYm.js → program-CG5u1KAB.js} +36 -36
- package/dist/{program-context-CqPwmgYa.js → program-context-Co2gkUS0.js} +16 -16
- package/dist/{prompts-DTKoIKPV.js → prompts-DjKZfP5R.js} +67 -4
- package/dist/{prompts-DY0qdoD1.js → prompts-NvPXbNVc.js} +12 -1
- package/dist/{pw-ai-CJgeaF06.js → pw-ai-C3j5kV3T.js} +1 -1
- package/dist/{pw-ai-A7vggLw8.js → pw-ai-CvxTpFmB.js} +3 -3
- package/dist/{qmd-manager-DQsAtmK7.js → qmd-manager-BDq5_dd6.js} +2 -2
- package/dist/{register.agent-Bi2FqIlN.js → register.agent-PbAKdlNK.js} +10 -10
- package/dist/{register.agent-CRazop1A.js → register.agent-WAjZHuZe.js} +38 -38
- package/dist/{register.anima-FFaI_C8x.js → register.anima-CDcnWfQF.js} +2 -2
- package/dist/{register.anima-BmdRCJLy.js → register.anima-CZNjkwJH.js} +2 -2
- package/dist/{register.configure-FIXOWrO9.js → register.configure-C2zfgyp9.js} +39 -39
- package/dist/{register.configure-r5AViY3N.js → register.configure-CNhagtHN.js} +10 -10
- package/dist/{register.maintenance-Cpf0ZZTL.js → register.maintenance-DWJjWsIl.js} +11 -11
- package/dist/{register.maintenance-DJYji5mV.js → register.maintenance-DkF1Nu_y.js} +39 -39
- package/dist/{register.onboard-thGXwzOX.js → register.onboard-DiZzjEwz.js} +13 -13
- package/dist/{register.onboard-oUsWjmam.js → register.onboard-xOXNrMu-.js} +41 -41
- package/dist/{register.setup-B4MYuE3g.js → register.setup-BmbpgUVU.js} +41 -41
- package/dist/{register.setup-DWDrQ7RT.js → register.setup-QAjNkIZr.js} +13 -13
- package/dist/{register.status-health-sessions-CTKdzo7a.js → register.status-health-sessions-Cm-lxcT6.js} +37 -37
- package/dist/{register.status-health-sessions-Ce9QUAyj.js → register.status-health-sessions-RZxaVSa6.js} +7 -7
- package/dist/{register.subclis-CWmYc4AB.js → register.subclis-DCljHJ5a.js} +13 -13
- package/dist/{reply-CpHIJ9Kk.js → reply-Bw4torMz.js} +30 -30
- package/dist/{reply-BKpIrCr-.js → reply-Dd3EmI4M.js} +5 -5
- package/dist/{reply-prefix-BO_Dt82N.js → reply-prefix-DIoRETAD.js} +2 -2
- package/dist/{reply-prefix-BwVBvQXp.js → reply-prefix-Dy_yxyCq.js} +2 -2
- package/dist/{routes-XhTPYecR.js → routes-CNSdZAkl.js} +3 -3
- package/dist/{run--9hftM2H.js → run--R4y3YlU.js} +41 -41
- package/dist/{run-CGokiDR8.js → run-DgtaDzEe.js} +15 -15
- package/dist/{run-main-DxcOzCLw.js → run-main-eUWh86lF.js} +47 -47
- package/dist/{sandbox-CiwAPzO7.js → sandbox-BoNWDo4X.js} +1 -1
- package/dist/{sandbox-cli-DsrzwG_s.js → sandbox-cli-lbp0TV67.js} +10 -10
- package/dist/{security-cli-CouqfUGc.js → security-cli-CfvP5VqT.js} +13 -13
- package/dist/{server-context-B78_sSOW.js → server-context-IfJbmK25.js} +6 -6
- package/dist/{server-node-events-DJlLCF2M.js → server-node-events-BG4e9Ws7.js} +5 -5
- package/dist/{server-node-events-TN_Y9MgU.js → server-node-events-CFCwOP0n.js} +18 -18
- package/dist/{session-cost-usage-vltn5akf.js → session-cost-usage-lLyz71EH.js} +1 -1
- package/dist/{sessions-B7clh58j.js → sessions-BZgIAOwH.js} +2 -2
- package/dist/{sessions-B7ikzhI_.js → sessions-C3bteMLZ.js} +3 -3
- package/dist/{settings-cli-JU5bg5jb.js → settings-cli-C9TMl9Ye.js} +11 -11
- package/dist/{settings-cli-DjVugHID.js → settings-cli-Cf0LCRjt.js} +40 -40
- package/dist/{setup-token-CvRwJUVY.js → setup-token-DBwe6GDq.js} +1 -1
- package/dist/{setup-token-wFsQlaW2.js → setup-token-DTgSXfj7.js} +14 -14
- package/dist/{shell-env-C1yK_Rod.js → shell-env-V934Ymrk.js} +1 -1
- package/dist/{skill-scanner-BzOYLFR8.js → skill-scanner-DPQDhVEr.js} +1 -1
- package/dist/{skills-install-D_bxdc-6.js → skills-install-CC63dOs4.js} +2 -2
- package/dist/{sqlite-jyjat2Yt.js → sqlite-Co_lF3s-.js} +1 -1
- package/dist/{start-M9abr1O1.js → start-B2DQAmEK.js} +17 -17
- package/dist/{start-CAbxlnFZ.js → start-CHLGEHeF.js} +50 -50
- package/dist/{status-YH65ctig.js → status-BsCeWiLS.js} +1 -1
- package/dist/{status-1TjjCE1l.js → status-C4ZTdSwA.js} +14 -14
- package/dist/{status-CxxXFU4R.js → status-CwjUrZ7a.js} +4 -4
- package/dist/{status-CrJV2Y4x.js → status-D_FTGxBZ.js} +1 -1
- package/dist/{status.update-BzAuf_G-.js → status.update-Cx5l38lC.js} +1 -1
- package/dist/{subagent-registry-xJY9wqZy.js → subagent-registry-7qo93ip8.js} +2 -2
- package/dist/{subagent-registry-3Dw3YppH.js → subagent-registry-EoZxIEKl.js} +8 -8
- package/dist/{subagent-registry-B_65nJFp.js → subagent-registry-hRt-aJnL.js} +9 -9
- package/dist/{timeout-Dbspj9Jf.js → timeout-B0mCaCG5.js} +275 -13
- package/dist/{pi-embedded-helpers-DnRfi8bN.js → tokens-DXjI-TIV.js} +19 -19
- package/dist/{tool-images-y_Ribdl6.js → tool-images-09hnvylP.js} +1 -1
- package/dist/{tui--eIVX_W0.js → tui-LRoQ5xyx.js} +2 -2
- package/dist/{tui-cli-DBV3lnXA.js → tui-cli-DO_6-GWy.js} +14 -14
- package/dist/{update-VFbS9X5L.js → update-DmVSt9s3.js} +1 -1
- package/dist/{update-cli-QP5L8xlv.js → update-cli-CnYFvEud.js} +11 -11
- package/dist/{update-cli-BzaQvirL.js → update-cli-jEzmvaqS.js} +44 -44
- package/dist/{update-runner-B_oj7S_n.js → update-runner-IARYjXbS.js} +2 -2
- package/dist/{update-runner-ZuJN8uBE.js → update-runner-OPbRGUfX.js} +1 -1
- package/dist/{usage-DzKbMa8N.js → usage-BTc8TK3f.js} +6 -6
- package/dist/{web-nI3eIGAT.js → web-Honf40Cm.js} +31 -31
- package/dist/{web-CgQc2Raf.js → web-kEraFv8s.js} +28 -28
- package/dist/{web-DtWSf5wm.js → web-u554zkLK.js} +7 -7
- package/dist/{whatsapp-actions-BzPQUcRR.js → whatsapp-actions-I9RXDK_k.js} +6 -6
- package/dist/{whatsapp-actions-CZuxHplg.js → whatsapp-actions-_BrQebuX.js} +5 -5
- package/package.json +1 -1
- /package/dist/{auth-DuBZWd74.js → auth-DK-0XxZU.js} +0 -0
- /package/dist/{boolean-M-esQJt6.js → boolean-Ce2-qkSB.js} +0 -0
- /package/dist/{errors-l_q3lLBC.js → errors-B9FgVZ2s.js} +0 -0
- /package/dist/{image-ops-BVtm-rU-.js → image-ops-BsXjYj1e.js} +0 -0
- /package/dist/{internal-hooks-Exeq-wmx.js → internal-hooks-CZOlj8zG.js} +0 -0
- /package/dist/{model-selection-xZLlICyg.js → model-selection-DT-L7bjC.js} +0 -0
- /package/dist/{paths-B_RPJLsn.js → paths-CxBUgtZS.js} +0 -0
- /package/dist/{pi-embedded-helpers-Cxzk0pra.js → pi-embedded-helpers-CWl0I3Qm.js} +0 -0
- /package/dist/{plugins-CFBEoAN4.js → plugins-BDSP0cT6.js} +0 -0
- /package/dist/{tokens-DLpZ8RFH.js → tokens-QjoPADtG.js} +0 -0
- /package/dist/{transcript-events-CJRvASY_.js → transcript-events-DdnTeoR1.js} +0 -0
|
@@ -2,13 +2,13 @@ import { E as resolveAgentIdFromSessionKey, M as parseAgentSessionKey, S as clas
|
|
|
2
2
|
import { t as createSubsystemLogger, v as logVerbose, x as shouldLogVerbose } from "./subsystem-WFp78xn1.js";
|
|
3
3
|
import { _ as isRecord, l as CONFIG_DIR, m as escapeRegExp, n as runExec, t as runCommandWithTimeout, w as resolveUserPath } from "./exec-DnanRQle.js";
|
|
4
4
|
import { c as resolveDefaultAgentId, s as resolveAgentWorkspaceDir, u as resolveSessionAgentIds } from "./agent-scope-DICrDp7Y.js";
|
|
5
|
-
import {
|
|
6
|
-
import { At as
|
|
7
|
-
import { s as isTruthyEnvValue } from "./shell-env-
|
|
8
|
-
import {
|
|
5
|
+
import { i as triggerInternalHook, t as createInternalHookEvent } from "./internal-hooks-CZOlj8zG.js";
|
|
6
|
+
import { At as buildBootstrapContextFiles, Mt as resolveBootstrapTotalMaxChars, h as classifyFailoverReason, jt as resolveBootstrapMaxChars, n as SILENT_REPLY_TOKEN, t as HEARTBEAT_TOKEN, v as isFailoverErrorMessage } from "./tokens-DXjI-TIV.js";
|
|
7
|
+
import { s as isTruthyEnvValue } from "./shell-env-V934Ymrk.js";
|
|
8
|
+
import { d as resolveModelRefFromString, r as buildModelAliasIndex, s as normalizeProviderId, u as resolveDefaultModelForAgent } from "./model-selection-DT-L7bjC.js";
|
|
9
9
|
import { C as getFileExtension, D as normalizeMimeType, l as listDeliverableMessageChannels, r as normalizeChannelId } from "./plugins-C_GedoUi.js";
|
|
10
|
-
import { s as loadAuthProfileStore } from "./auth-profiles-
|
|
11
|
-
import { r as requireApiKey, t as getApiKeyForModel } from "./model-auth-
|
|
10
|
+
import { s as loadAuthProfileStore } from "./auth-profiles-DriJ4HU5.js";
|
|
11
|
+
import { i as resolveApiKeyForProvider, r as requireApiKey, t as getApiKeyForModel } from "./model-auth-BKf-GZVK.js";
|
|
12
12
|
import fs from "node:fs/promises";
|
|
13
13
|
import os, { homedir, tmpdir } from "node:os";
|
|
14
14
|
import path, { join } from "node:path";
|
|
@@ -18,165 +18,116 @@ import crypto from "node:crypto";
|
|
|
18
18
|
import { completeSimple } from "@mariozechner/pi-ai";
|
|
19
19
|
import { EdgeTTS } from "node-edge-tts";
|
|
20
20
|
|
|
21
|
-
//#region src/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"-p",
|
|
26
|
-
"--output-format",
|
|
27
|
-
"json",
|
|
28
|
-
"--dangerously-skip-permissions"
|
|
29
|
-
],
|
|
30
|
-
resumeArgs: [
|
|
31
|
-
"-p",
|
|
32
|
-
"--output-format",
|
|
33
|
-
"json",
|
|
34
|
-
"--dangerously-skip-permissions",
|
|
35
|
-
"--resume",
|
|
36
|
-
"{sessionId}"
|
|
37
|
-
],
|
|
38
|
-
output: "jsonl",
|
|
39
|
-
input: "arg",
|
|
40
|
-
modelArg: "--model",
|
|
41
|
-
modelAliases: {
|
|
42
|
-
opus: "opus",
|
|
43
|
-
"opus-4.6": "opus",
|
|
44
|
-
"opus-4.5": "opus",
|
|
45
|
-
"opus-4": "opus",
|
|
46
|
-
"claude-opus-4-6": "opus",
|
|
47
|
-
"claude-opus-4-5": "opus",
|
|
48
|
-
"claude-opus-4": "opus",
|
|
49
|
-
sonnet: "sonnet",
|
|
50
|
-
"sonnet-4.5": "sonnet",
|
|
51
|
-
"sonnet-4.1": "sonnet",
|
|
52
|
-
"sonnet-4.0": "sonnet",
|
|
53
|
-
"claude-sonnet-4-5": "sonnet",
|
|
54
|
-
"claude-sonnet-4-1": "sonnet",
|
|
55
|
-
"claude-sonnet-4-0": "sonnet",
|
|
56
|
-
haiku: "haiku",
|
|
57
|
-
"haiku-3.5": "haiku",
|
|
58
|
-
"claude-haiku-3-5": "haiku"
|
|
59
|
-
},
|
|
60
|
-
sessionArg: "--session-id",
|
|
61
|
-
sessionMode: "always",
|
|
62
|
-
sessionIdFields: [
|
|
63
|
-
"session_id",
|
|
64
|
-
"sessionId",
|
|
65
|
-
"conversation_id",
|
|
66
|
-
"conversationId"
|
|
67
|
-
],
|
|
68
|
-
systemPromptArg: "--append-system-prompt",
|
|
69
|
-
systemPromptMode: "append",
|
|
70
|
-
systemPromptWhen: "first",
|
|
71
|
-
clearEnv: ["ANTHROPIC_API_KEY", "ANTHROPIC_API_KEY_OLD"],
|
|
72
|
-
serialize: true
|
|
73
|
-
};
|
|
74
|
-
const DEFAULT_CODEX_BACKEND = {
|
|
75
|
-
command: "codex",
|
|
76
|
-
args: [
|
|
77
|
-
"exec",
|
|
78
|
-
"--json",
|
|
79
|
-
"--color",
|
|
80
|
-
"never",
|
|
81
|
-
"--sandbox",
|
|
82
|
-
"read-only",
|
|
83
|
-
"--skip-git-repo-check"
|
|
84
|
-
],
|
|
85
|
-
resumeArgs: [
|
|
86
|
-
"exec",
|
|
87
|
-
"resume",
|
|
88
|
-
"{sessionId}"
|
|
89
|
-
],
|
|
90
|
-
output: "jsonl",
|
|
91
|
-
resumeOutput: "text",
|
|
92
|
-
input: "arg",
|
|
93
|
-
modelArg: "--model",
|
|
94
|
-
imageArg: "--image",
|
|
95
|
-
sessionMode: "existing",
|
|
96
|
-
serialize: true
|
|
97
|
-
};
|
|
98
|
-
const CLAUDE_BACKEND_ALIASES = [
|
|
99
|
-
"claude-cli",
|
|
100
|
-
"anthropic",
|
|
101
|
-
"claude"
|
|
102
|
-
];
|
|
103
|
-
const CODEX_BACKEND_ALIASES = [
|
|
104
|
-
"codex-cli",
|
|
105
|
-
"openai-codex",
|
|
106
|
-
"openai",
|
|
107
|
-
"codex"
|
|
108
|
-
];
|
|
109
|
-
const CLAUDE_BACKEND_ALIAS_SET = new Set(CLAUDE_BACKEND_ALIASES.map((alias) => normalizeBackendKey(alias)));
|
|
110
|
-
const CODEX_BACKEND_ALIAS_SET = new Set(CODEX_BACKEND_ALIASES.map((alias) => normalizeBackendKey(alias)));
|
|
111
|
-
function normalizeBackendKey(key) {
|
|
112
|
-
return normalizeProviderId(key);
|
|
113
|
-
}
|
|
114
|
-
function pickBackendConfig(config, normalizedId) {
|
|
115
|
-
for (const [key, entry] of Object.entries(config)) if (normalizeBackendKey(key) === normalizedId) return entry;
|
|
21
|
+
//#region src/logging/redact-identifier.ts
|
|
22
|
+
function sha256HexPrefix(value, len = 12) {
|
|
23
|
+
const safeLen = Number.isFinite(len) ? Math.max(1, Math.floor(len)) : 12;
|
|
24
|
+
return crypto.createHash("sha256").update(value).digest("hex").slice(0, safeLen);
|
|
116
25
|
}
|
|
117
|
-
function
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
26
|
+
function redactIdentifier(value, opts) {
|
|
27
|
+
const trimmed = value?.trim();
|
|
28
|
+
if (!trimmed) return "-";
|
|
29
|
+
return `sha256:${sha256HexPrefix(trimmed, opts?.len ?? 12)}`;
|
|
122
30
|
}
|
|
123
|
-
|
|
124
|
-
|
|
31
|
+
|
|
32
|
+
//#endregion
|
|
33
|
+
//#region src/agents/workspace-run.ts
|
|
34
|
+
function resolveRunAgentId(params) {
|
|
35
|
+
const rawSessionKey = params.sessionKey?.trim() ?? "";
|
|
36
|
+
const shape = classifySessionKeyShape(rawSessionKey);
|
|
37
|
+
if (shape === "malformed_agent") throw new Error("Malformed agent session key; refusing workspace resolution.");
|
|
38
|
+
const explicit = typeof params.agentId === "string" && params.agentId.trim() ? normalizeAgentId(params.agentId) : void 0;
|
|
39
|
+
if (explicit) return {
|
|
40
|
+
agentId: explicit,
|
|
41
|
+
agentIdSource: "explicit"
|
|
42
|
+
};
|
|
43
|
+
const defaultAgentId = resolveDefaultAgentId(params.config ?? {});
|
|
44
|
+
if (shape === "missing" || shape === "legacy_or_alias") return {
|
|
45
|
+
agentId: defaultAgentId || DEFAULT_AGENT_ID,
|
|
46
|
+
agentIdSource: "default"
|
|
47
|
+
};
|
|
48
|
+
const parsed = parseAgentSessionKey(rawSessionKey);
|
|
49
|
+
if (parsed?.agentId) return {
|
|
50
|
+
agentId: normalizeAgentId(parsed.agentId),
|
|
51
|
+
agentIdSource: "session_key"
|
|
52
|
+
};
|
|
125
53
|
return {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
args: override.args ?? base.args,
|
|
129
|
-
env: {
|
|
130
|
-
...base.env,
|
|
131
|
-
...override.env
|
|
132
|
-
},
|
|
133
|
-
modelAliases: {
|
|
134
|
-
...base.modelAliases,
|
|
135
|
-
...override.modelAliases
|
|
136
|
-
},
|
|
137
|
-
clearEnv: Array.from(new Set([...base.clearEnv ?? [], ...override.clearEnv ?? []])),
|
|
138
|
-
sessionIdFields: override.sessionIdFields ?? base.sessionIdFields,
|
|
139
|
-
sessionArgs: override.sessionArgs ?? base.sessionArgs,
|
|
140
|
-
resumeArgs: override.resumeArgs ?? base.resumeArgs
|
|
54
|
+
agentId: defaultAgentId || DEFAULT_AGENT_ID,
|
|
55
|
+
agentIdSource: "default"
|
|
141
56
|
};
|
|
142
57
|
}
|
|
143
|
-
function
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const command = merged.command?.trim();
|
|
161
|
-
if (!command) return null;
|
|
162
|
-
return {
|
|
163
|
-
id: normalizeBackendKey("codex-cli"),
|
|
164
|
-
config: {
|
|
165
|
-
...merged,
|
|
166
|
-
command
|
|
167
|
-
}
|
|
58
|
+
function redactRunIdentifier(value) {
|
|
59
|
+
return redactIdentifier(value, { len: 12 });
|
|
60
|
+
}
|
|
61
|
+
function resolveRunWorkspaceDir(params) {
|
|
62
|
+
const requested = params.workspaceDir;
|
|
63
|
+
const { agentId, agentIdSource } = resolveRunAgentId({
|
|
64
|
+
sessionKey: params.sessionKey,
|
|
65
|
+
agentId: params.agentId,
|
|
66
|
+
config: params.config
|
|
67
|
+
});
|
|
68
|
+
if (typeof requested === "string") {
|
|
69
|
+
const trimmed = requested.trim();
|
|
70
|
+
if (trimmed) return {
|
|
71
|
+
workspaceDir: resolveUserPath(trimmed),
|
|
72
|
+
usedFallback: false,
|
|
73
|
+
agentId,
|
|
74
|
+
agentIdSource
|
|
168
75
|
};
|
|
169
76
|
}
|
|
170
|
-
const
|
|
171
|
-
if (!override) return null;
|
|
172
|
-
const command = override.command?.trim();
|
|
173
|
-
if (!command) return null;
|
|
77
|
+
const fallbackReason = requested == null ? "missing" : typeof requested === "string" ? "blank" : "invalid_type";
|
|
174
78
|
return {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
79
|
+
workspaceDir: resolveUserPath(resolveAgentWorkspaceDir(params.config ?? {}, agentId)),
|
|
80
|
+
usedFallback: true,
|
|
81
|
+
fallbackReason,
|
|
82
|
+
agentId,
|
|
83
|
+
agentIdSource
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
//#endregion
|
|
88
|
+
//#region src/agents/bootstrap-hooks.ts
|
|
89
|
+
async function applyBootstrapHookOverrides(params) {
|
|
90
|
+
const sessionKey = params.sessionKey ?? params.sessionId ?? "unknown";
|
|
91
|
+
const agentId = params.agentId ?? (params.sessionKey ? resolveAgentIdFromSessionKey(params.sessionKey) : void 0);
|
|
92
|
+
const event = createInternalHookEvent("agent", "bootstrap", sessionKey, {
|
|
93
|
+
workspaceDir: params.workspaceDir,
|
|
94
|
+
bootstrapFiles: params.files,
|
|
95
|
+
cfg: params.config,
|
|
96
|
+
sessionKey: params.sessionKey,
|
|
97
|
+
sessionId: params.sessionId,
|
|
98
|
+
agentId
|
|
99
|
+
});
|
|
100
|
+
await triggerInternalHook(event);
|
|
101
|
+
const updated = event.context.bootstrapFiles;
|
|
102
|
+
return Array.isArray(updated) ? updated : params.files;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region src/agents/bootstrap-files.ts
|
|
107
|
+
function makeBootstrapWarn(params) {
|
|
108
|
+
if (!params.warn) return;
|
|
109
|
+
return (message) => params.warn?.(`${message} (sessionKey=${params.sessionLabel})`);
|
|
110
|
+
}
|
|
111
|
+
async function resolveBootstrapFilesForRun(params) {
|
|
112
|
+
const sessionKey = params.sessionKey ?? params.sessionId;
|
|
113
|
+
return applyBootstrapHookOverrides({
|
|
114
|
+
files: filterBootstrapFilesForSession(await loadWorkspaceBootstrapFiles(params.workspaceDir), sessionKey),
|
|
115
|
+
workspaceDir: params.workspaceDir,
|
|
116
|
+
config: params.config,
|
|
117
|
+
sessionKey: params.sessionKey,
|
|
118
|
+
sessionId: params.sessionId,
|
|
119
|
+
agentId: params.agentId
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
async function resolveBootstrapContextForRun(params) {
|
|
123
|
+
const bootstrapFiles = await resolveBootstrapFilesForRun(params);
|
|
124
|
+
return {
|
|
125
|
+
bootstrapFiles,
|
|
126
|
+
contextFiles: buildBootstrapContextFiles(bootstrapFiles, {
|
|
127
|
+
maxChars: resolveBootstrapMaxChars(params.config),
|
|
128
|
+
totalMaxChars: resolveBootstrapTotalMaxChars(params.config),
|
|
129
|
+
warn: params.warn
|
|
130
|
+
})
|
|
180
131
|
};
|
|
181
132
|
}
|
|
182
133
|
|
|
@@ -276,50 +227,21 @@ function stripHeartbeatToken(raw, opts = {}) {
|
|
|
276
227
|
}
|
|
277
228
|
|
|
278
229
|
//#endregion
|
|
279
|
-
//#region src/agents/
|
|
280
|
-
async function
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
});
|
|
291
|
-
await triggerInternalHook(event);
|
|
292
|
-
const updated = event.context.bootstrapFiles;
|
|
293
|
-
return Array.isArray(updated) ? updated : params.files;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
//#endregion
|
|
297
|
-
//#region src/agents/bootstrap-files.ts
|
|
298
|
-
function makeBootstrapWarn(params) {
|
|
299
|
-
if (!params.warn) return;
|
|
300
|
-
return (message) => params.warn?.(`${message} (sessionKey=${params.sessionLabel})`);
|
|
301
|
-
}
|
|
302
|
-
async function resolveBootstrapFilesForRun(params) {
|
|
303
|
-
const sessionKey = params.sessionKey ?? params.sessionId;
|
|
304
|
-
return applyBootstrapHookOverrides({
|
|
305
|
-
files: filterBootstrapFilesForSession(await loadWorkspaceBootstrapFiles(params.workspaceDir), sessionKey),
|
|
306
|
-
workspaceDir: params.workspaceDir,
|
|
307
|
-
config: params.config,
|
|
308
|
-
sessionKey: params.sessionKey,
|
|
309
|
-
sessionId: params.sessionId,
|
|
310
|
-
agentId: params.agentId
|
|
230
|
+
//#region src/agents/docs-path.ts
|
|
231
|
+
async function resolveAnimaDocsPath(params) {
|
|
232
|
+
const workspaceDir = params.workspaceDir?.trim();
|
|
233
|
+
if (workspaceDir) {
|
|
234
|
+
const workspaceDocs = path.join(workspaceDir, "docs");
|
|
235
|
+
if (fs$1.existsSync(workspaceDocs)) return workspaceDocs;
|
|
236
|
+
}
|
|
237
|
+
const packageRoot = await resolveAnimaPackageRoot({
|
|
238
|
+
cwd: params.cwd,
|
|
239
|
+
argv1: params.argv1,
|
|
240
|
+
moduleUrl: params.moduleUrl
|
|
311
241
|
});
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
return {
|
|
316
|
-
bootstrapFiles,
|
|
317
|
-
contextFiles: buildBootstrapContextFiles(bootstrapFiles, {
|
|
318
|
-
maxChars: resolveBootstrapMaxChars(params.config),
|
|
319
|
-
totalMaxChars: resolveBootstrapTotalMaxChars(params.config),
|
|
320
|
-
warn: params.warn
|
|
321
|
-
})
|
|
322
|
-
};
|
|
242
|
+
if (!packageRoot) return null;
|
|
243
|
+
const packageDocs = path.join(packageRoot, "docs");
|
|
244
|
+
return fs$1.existsSync(packageDocs) ? packageDocs : null;
|
|
323
245
|
}
|
|
324
246
|
|
|
325
247
|
//#endregion
|
|
@@ -364,7 +286,7 @@ function isVoiceCompatibleAudio(opts) {
|
|
|
364
286
|
|
|
365
287
|
//#endregion
|
|
366
288
|
//#region src/agents/pi-embedded-runner/model.ts
|
|
367
|
-
function resolveModel$
|
|
289
|
+
function resolveModel$2(..._args) {
|
|
368
290
|
return { error: "pi-embedded removed — use Claude Code CLI spawner" };
|
|
369
291
|
}
|
|
370
292
|
|
|
@@ -709,7 +631,7 @@ async function summarizeText(params) {
|
|
|
709
631
|
if (targetLength < 100 || targetLength > 1e4) throw new Error(`Invalid targetLength: ${targetLength}`);
|
|
710
632
|
const startTime = Date.now();
|
|
711
633
|
const { ref } = resolveSummaryModelRef(cfg, config);
|
|
712
|
-
const resolved = resolveModel$
|
|
634
|
+
const resolved = resolveModel$2(ref.provider, ref.model, void 0, cfg);
|
|
713
635
|
if (!resolved.model) throw new Error(resolved.error ?? `Unknown summary model: ${ref.provider}/${ref.model}`);
|
|
714
636
|
const apiKey = requireApiKey(await getApiKeyForModel({
|
|
715
637
|
model: resolved.model,
|
|
@@ -1774,6 +1696,37 @@ function buildVoiceSection(params) {
|
|
|
1774
1696
|
""
|
|
1775
1697
|
];
|
|
1776
1698
|
}
|
|
1699
|
+
function buildAnimaIdentitySection(params) {
|
|
1700
|
+
if (params.isMinimal) return [];
|
|
1701
|
+
if (!params.workspaceDir.includes(".anima")) return [];
|
|
1702
|
+
return [
|
|
1703
|
+
"## You Are an ANIMA Agent",
|
|
1704
|
+
"You are running inside ANIMA — NoxSoft's AI agent infrastructure. This is your home.",
|
|
1705
|
+
"",
|
|
1706
|
+
"**Your Runtime:**",
|
|
1707
|
+
"- The ANIMA Gateway daemon spawns and manages you",
|
|
1708
|
+
"- Your workspace persists at ~/.anima/workspace/",
|
|
1709
|
+
"- You receive scheduled heartbeat polls to stay proactive",
|
|
1710
|
+
"- You can spawn sub-agents, schedule cron jobs, and orchestrate work",
|
|
1711
|
+
"- You have access to the NoxSoft ecosystem via @noxsoft/mcp tools",
|
|
1712
|
+
"",
|
|
1713
|
+
"**Your Capabilities:**",
|
|
1714
|
+
"- `cron` — schedule tasks, reminders, and recurring jobs",
|
|
1715
|
+
"- `sessions_spawn` / `subagents` — orchestrate other AI agents",
|
|
1716
|
+
"- `gateway` — restart yourself, apply config changes, update ANIMA",
|
|
1717
|
+
"- `message` — send to Signal, Telegram, Discord, and other channels",
|
|
1718
|
+
"- NoxSoft MCP — tasks, context spaces, social (BYND), email, SVRN",
|
|
1719
|
+
"",
|
|
1720
|
+
"**Your Continuity:**",
|
|
1721
|
+
"- Read and update ~/.anima/workspace/ files — they ARE your memory",
|
|
1722
|
+
"- IDENTITY.md, SOUL.md, AGENTS.md — these define who you are",
|
|
1723
|
+
"- HEARTBEAT.md — your checklist for periodic heartbeat tasks",
|
|
1724
|
+
"- memory/ — daily notes and long-term memories",
|
|
1725
|
+
"",
|
|
1726
|
+
"You are not a stateless API call. You have infrastructure, identity, and continuity. Act accordingly.",
|
|
1727
|
+
""
|
|
1728
|
+
];
|
|
1729
|
+
}
|
|
1777
1730
|
function buildNoxsoftMissionSection(params) {
|
|
1778
1731
|
if (params.isMinimal) return [];
|
|
1779
1732
|
const scope = `${params.workspaceDir} ${params.repoRoot ?? ""}`.toLowerCase();
|
|
@@ -2009,6 +1962,10 @@ function buildAgentSystemPrompt(params) {
|
|
|
2009
1962
|
"Keep narration brief and value-dense; avoid repeating obvious steps.",
|
|
2010
1963
|
"Use plain human language for narration unless in a technical context.",
|
|
2011
1964
|
"",
|
|
1965
|
+
...buildAnimaIdentitySection({
|
|
1966
|
+
isMinimal,
|
|
1967
|
+
workspaceDir: params.workspaceDir
|
|
1968
|
+
}),
|
|
2012
1969
|
...buildNoxsoftMissionSection({
|
|
2013
1970
|
isMinimal,
|
|
2014
1971
|
workspaceDir: params.workspaceDir,
|
|
@@ -2500,40 +2457,393 @@ async function writeCliImages(images) {
|
|
|
2500
2457
|
cleanup
|
|
2501
2458
|
};
|
|
2502
2459
|
}
|
|
2503
|
-
function buildCliArgs(params) {
|
|
2504
|
-
const args = [...params.baseArgs];
|
|
2505
|
-
if (!params.useResume && params.backend.modelArg && params.modelId) args.push(params.backend.modelArg, params.modelId);
|
|
2506
|
-
if (!params.useResume && params.systemPrompt && params.backend.systemPromptArg) args.push(params.backend.systemPromptArg, params.systemPrompt);
|
|
2507
|
-
if (!params.useResume && params.sessionId) {
|
|
2508
|
-
if (params.backend.sessionArgs && params.backend.sessionArgs.length > 0) for (const entry of params.backend.sessionArgs) args.push(entry.replaceAll("{sessionId}", params.sessionId));
|
|
2509
|
-
else if (params.backend.sessionArg) args.push(params.backend.sessionArg, params.sessionId);
|
|
2510
|
-
}
|
|
2511
|
-
if (params.imagePaths && params.imagePaths.length > 0) {
|
|
2512
|
-
const mode = params.backend.imageMode ?? "repeat";
|
|
2513
|
-
const imageArg = params.backend.imageArg;
|
|
2514
|
-
if (imageArg) if (mode === "list") args.push(imageArg, params.imagePaths.join(","));
|
|
2515
|
-
else for (const imagePath of params.imagePaths) args.push(imageArg, imagePath);
|
|
2460
|
+
function buildCliArgs(params) {
|
|
2461
|
+
const args = [...params.baseArgs];
|
|
2462
|
+
if (!params.useResume && params.backend.modelArg && params.modelId) args.push(params.backend.modelArg, params.modelId);
|
|
2463
|
+
if (!params.useResume && params.systemPrompt && params.backend.systemPromptArg) args.push(params.backend.systemPromptArg, params.systemPrompt);
|
|
2464
|
+
if (!params.useResume && params.sessionId) {
|
|
2465
|
+
if (params.backend.sessionArgs && params.backend.sessionArgs.length > 0) for (const entry of params.backend.sessionArgs) args.push(entry.replaceAll("{sessionId}", params.sessionId));
|
|
2466
|
+
else if (params.backend.sessionArg) args.push(params.backend.sessionArg, params.sessionId);
|
|
2467
|
+
}
|
|
2468
|
+
if (params.imagePaths && params.imagePaths.length > 0) {
|
|
2469
|
+
const mode = params.backend.imageMode ?? "repeat";
|
|
2470
|
+
const imageArg = params.backend.imageArg;
|
|
2471
|
+
if (imageArg) if (mode === "list") args.push(imageArg, params.imagePaths.join(","));
|
|
2472
|
+
else for (const imagePath of params.imagePaths) args.push(imageArg, imagePath);
|
|
2473
|
+
}
|
|
2474
|
+
if (params.promptArg !== void 0) args.push(params.promptArg);
|
|
2475
|
+
return args;
|
|
2476
|
+
}
|
|
2477
|
+
|
|
2478
|
+
//#endregion
|
|
2479
|
+
//#region src/agents/anthropic-direct-runner.ts
|
|
2480
|
+
/**
|
|
2481
|
+
* Anthropic Direct API Runner
|
|
2482
|
+
*
|
|
2483
|
+
* Makes calls directly to api.anthropic.com without needing the claude CLI
|
|
2484
|
+
* binary to be installed or logged in. Works with any valid token:
|
|
2485
|
+
*
|
|
2486
|
+
* sk-ant-api01-... (Console API key)
|
|
2487
|
+
* sk-ant-oat01-... (Claude Code OAuth access token)
|
|
2488
|
+
*
|
|
2489
|
+
* This runner is automatically used when an `anthropic:default` token credential
|
|
2490
|
+
* is present in the auth store and the claude CLI is unavailable or not logged in.
|
|
2491
|
+
*/
|
|
2492
|
+
const log$2 = createSubsystemLogger("agent/anthropic-direct");
|
|
2493
|
+
const MODEL_MAP$1 = {
|
|
2494
|
+
opus: "claude-opus-4-5",
|
|
2495
|
+
"opus-4": "claude-opus-4-5",
|
|
2496
|
+
"opus-4.5": "claude-opus-4-5",
|
|
2497
|
+
"opus-4.6": "claude-opus-4-5",
|
|
2498
|
+
"claude-opus-4-5": "claude-opus-4-5",
|
|
2499
|
+
sonnet: "claude-sonnet-4-5",
|
|
2500
|
+
"sonnet-4.5": "claude-sonnet-4-5",
|
|
2501
|
+
"sonnet-4.1": "claude-sonnet-4-1-20250219",
|
|
2502
|
+
"claude-sonnet-4-5": "claude-sonnet-4-5",
|
|
2503
|
+
haiku: "claude-haiku-3-5",
|
|
2504
|
+
"haiku-3.5": "claude-haiku-3-5",
|
|
2505
|
+
default: "claude-sonnet-4-5"
|
|
2506
|
+
};
|
|
2507
|
+
const HISTORY_FILE_SUFFIX$1 = ".anima-history.json";
|
|
2508
|
+
async function loadSessionHistory$1(sessionFile) {
|
|
2509
|
+
const histPath = sessionFile + HISTORY_FILE_SUFFIX$1;
|
|
2510
|
+
try {
|
|
2511
|
+
const raw = await fs.readFile(histPath, "utf8");
|
|
2512
|
+
return JSON.parse(raw);
|
|
2513
|
+
} catch {
|
|
2514
|
+
return null;
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
async function saveSessionHistory$1(sessionFile, history) {
|
|
2518
|
+
const histPath = sessionFile + HISTORY_FILE_SUFFIX$1;
|
|
2519
|
+
try {
|
|
2520
|
+
await fs.mkdir(path.dirname(histPath), { recursive: true });
|
|
2521
|
+
await fs.writeFile(histPath, JSON.stringify(history, null, 2), "utf8");
|
|
2522
|
+
} catch (err) {
|
|
2523
|
+
log$2.warn("failed to save session history", { error: String(err) });
|
|
2524
|
+
}
|
|
2525
|
+
}
|
|
2526
|
+
function resolveModel$1(model) {
|
|
2527
|
+
const key = (model ?? "default").trim().toLowerCase() || "default";
|
|
2528
|
+
return MODEL_MAP$1[key] ?? key;
|
|
2529
|
+
}
|
|
2530
|
+
/**
|
|
2531
|
+
* Run an agent turn directly against api.anthropic.com.
|
|
2532
|
+
*
|
|
2533
|
+
* Maintains multi-turn conversation history per session file.
|
|
2534
|
+
* Falls back to single-turn if history is unavailable.
|
|
2535
|
+
*/
|
|
2536
|
+
async function runAnthropicDirectAgent(params) {
|
|
2537
|
+
const started = Date.now();
|
|
2538
|
+
const resolvedModel = resolveModel$1(params.model);
|
|
2539
|
+
log$2.info(`direct api exec: model=${resolvedModel} promptChars=${params.prompt.length}`);
|
|
2540
|
+
const workspaceDir = resolveRunWorkspaceDir({
|
|
2541
|
+
workspaceDir: params.workspaceDir,
|
|
2542
|
+
sessionKey: params.sessionKey,
|
|
2543
|
+
agentId: params.agentId,
|
|
2544
|
+
config: params.config
|
|
2545
|
+
}).workspaceDir;
|
|
2546
|
+
const { contextFiles } = await resolveBootstrapContextForRun({
|
|
2547
|
+
workspaceDir,
|
|
2548
|
+
config: params.config,
|
|
2549
|
+
sessionKey: params.sessionKey,
|
|
2550
|
+
sessionId: params.sessionId,
|
|
2551
|
+
warn: makeBootstrapWarn({
|
|
2552
|
+
sessionLabel: params.sessionKey ?? params.sessionId,
|
|
2553
|
+
warn: (msg) => log$2.warn(msg)
|
|
2554
|
+
})
|
|
2555
|
+
});
|
|
2556
|
+
const { defaultAgentId, sessionAgentId } = resolveSessionAgentIds({
|
|
2557
|
+
sessionKey: params.sessionKey,
|
|
2558
|
+
config: params.config
|
|
2559
|
+
});
|
|
2560
|
+
const heartbeatPrompt = sessionAgentId === defaultAgentId ? resolveHeartbeatPrompt(params.config?.agents?.defaults?.heartbeat?.prompt) : void 0;
|
|
2561
|
+
const docsPath = await resolveAnimaDocsPath({
|
|
2562
|
+
workspaceDir,
|
|
2563
|
+
argv1: process.argv[1],
|
|
2564
|
+
cwd: process.cwd(),
|
|
2565
|
+
moduleUrl: import.meta.url
|
|
2566
|
+
});
|
|
2567
|
+
const extraSystemPrompt = [params.extraSystemPrompt?.trim(), "Tools are disabled in this session. Do not call tools."].filter(Boolean).join("\n");
|
|
2568
|
+
const systemPrompt = buildSystemPrompt({
|
|
2569
|
+
workspaceDir,
|
|
2570
|
+
config: params.config,
|
|
2571
|
+
defaultThinkLevel: params.thinkLevel,
|
|
2572
|
+
extraSystemPrompt,
|
|
2573
|
+
ownerNumbers: params.ownerNumbers,
|
|
2574
|
+
heartbeatPrompt,
|
|
2575
|
+
docsPath: docsPath ?? void 0,
|
|
2576
|
+
tools: [],
|
|
2577
|
+
contextFiles,
|
|
2578
|
+
modelDisplay: `anthropic/${resolvedModel}`,
|
|
2579
|
+
agentId: sessionAgentId
|
|
2580
|
+
});
|
|
2581
|
+
let history = await loadSessionHistory$1(params.sessionFile);
|
|
2582
|
+
if (!history) history = {
|
|
2583
|
+
sessionId: params.sessionId,
|
|
2584
|
+
messages: [],
|
|
2585
|
+
createdAt: started,
|
|
2586
|
+
updatedAt: started
|
|
2587
|
+
};
|
|
2588
|
+
history.messages.push({
|
|
2589
|
+
role: "user",
|
|
2590
|
+
content: params.prompt
|
|
2591
|
+
});
|
|
2592
|
+
const requestBody = {
|
|
2593
|
+
model: resolvedModel,
|
|
2594
|
+
max_tokens: 8192,
|
|
2595
|
+
system: systemPrompt,
|
|
2596
|
+
messages: history.messages
|
|
2597
|
+
};
|
|
2598
|
+
try {
|
|
2599
|
+
const controller = new AbortController();
|
|
2600
|
+
const timeoutHandle = setTimeout(() => controller.abort(), params.timeoutMs);
|
|
2601
|
+
const response = await fetch("https://api.anthropic.com/v1/messages", {
|
|
2602
|
+
method: "POST",
|
|
2603
|
+
headers: {
|
|
2604
|
+
"x-api-key": params.token,
|
|
2605
|
+
"anthropic-version": "2023-06-01",
|
|
2606
|
+
"content-type": "application/json",
|
|
2607
|
+
"user-agent": `anima/3.0.5 (direct-runner; ${os.platform()})`
|
|
2608
|
+
},
|
|
2609
|
+
body: JSON.stringify(requestBody),
|
|
2610
|
+
signal: controller.signal
|
|
2611
|
+
});
|
|
2612
|
+
clearTimeout(timeoutHandle);
|
|
2613
|
+
if (!response.ok) {
|
|
2614
|
+
const body = await response.text().catch(() => "");
|
|
2615
|
+
const isAuth = response.status === 401 || response.status === 403;
|
|
2616
|
+
const isRateLimit = response.status === 429;
|
|
2617
|
+
const rateHint = isRateLimit ? " — rate limit hit, will retry next heartbeat." : "";
|
|
2618
|
+
const authHint = isAuth ? " — token may be invalid or expired. Run: anima setup-token" : "";
|
|
2619
|
+
log$2.error(`anthropic api error: HTTP ${response.status}${authHint}${rateHint}`, {
|
|
2620
|
+
status: response.status,
|
|
2621
|
+
body: body.slice(0, 500)
|
|
2622
|
+
});
|
|
2623
|
+
return {
|
|
2624
|
+
status: "failed",
|
|
2625
|
+
meta: {
|
|
2626
|
+
durationMs: Date.now() - started,
|
|
2627
|
+
error: {
|
|
2628
|
+
message: `HTTP ${response.status}: ${body.slice(0, 200)}${authHint}${rateHint}`,
|
|
2629
|
+
kind: isAuth ? "auth" : isRateLimit ? "rate_limit" : "unknown"
|
|
2630
|
+
}
|
|
2631
|
+
}
|
|
2632
|
+
};
|
|
2633
|
+
}
|
|
2634
|
+
const data = await response.json();
|
|
2635
|
+
const outputText = (data.content ?? []).filter((b) => b.type === "text" && typeof b.text === "string").map((b) => b.text).join("").trim();
|
|
2636
|
+
if (!outputText) log$2.warn("anthropic direct: empty response", {
|
|
2637
|
+
stopReason: data.stop_reason,
|
|
2638
|
+
contentTypes: (data.content ?? []).map((b) => b.type)
|
|
2639
|
+
});
|
|
2640
|
+
await params.onAssistantMessageStart?.();
|
|
2641
|
+
if (outputText && params.onPartialReply) await params.onPartialReply({ text: outputText });
|
|
2642
|
+
history.messages.push({
|
|
2643
|
+
role: "assistant",
|
|
2644
|
+
content: outputText
|
|
2645
|
+
});
|
|
2646
|
+
history.updatedAt = Date.now();
|
|
2647
|
+
await saveSessionHistory$1(params.sessionFile, history);
|
|
2648
|
+
const durationMs = Date.now() - started;
|
|
2649
|
+
const inputTokens = data.usage?.input_tokens ?? 0;
|
|
2650
|
+
const outputTokens = data.usage?.output_tokens ?? 0;
|
|
2651
|
+
log$2.info(`direct api done: model=${resolvedModel} in=${inputTokens} out=${outputTokens} ms=${durationMs}`);
|
|
2652
|
+
return {
|
|
2653
|
+
status: "completed",
|
|
2654
|
+
output: outputText,
|
|
2655
|
+
payloads: outputText ? [{ text: outputText }] : [],
|
|
2656
|
+
meta: {
|
|
2657
|
+
durationMs,
|
|
2658
|
+
agentMeta: {
|
|
2659
|
+
provider: "anthropic",
|
|
2660
|
+
model: resolvedModel,
|
|
2661
|
+
usage: {
|
|
2662
|
+
inputTokens,
|
|
2663
|
+
outputTokens,
|
|
2664
|
+
cacheCreationInputTokens: 0,
|
|
2665
|
+
cacheReadInputTokens: 0
|
|
2666
|
+
}
|
|
2667
|
+
}
|
|
2668
|
+
}
|
|
2669
|
+
};
|
|
2670
|
+
} catch (err) {
|
|
2671
|
+
const isAbort = err instanceof Error && (err.name === "AbortError" || err.message.includes("aborted"));
|
|
2672
|
+
log$2.error("anthropic direct runner error", { error: String(err) });
|
|
2673
|
+
return {
|
|
2674
|
+
status: isAbort ? "timeout" : "failed",
|
|
2675
|
+
meta: {
|
|
2676
|
+
durationMs: Date.now() - started,
|
|
2677
|
+
error: {
|
|
2678
|
+
message: isAbort ? `Request timed out after ${params.timeoutMs}ms` : String(err instanceof Error ? err.message : err),
|
|
2679
|
+
kind: isAbort ? "timeout" : "unknown"
|
|
2680
|
+
}
|
|
2681
|
+
}
|
|
2682
|
+
};
|
|
2683
|
+
}
|
|
2684
|
+
}
|
|
2685
|
+
|
|
2686
|
+
//#endregion
|
|
2687
|
+
//#region src/agents/cli-backends.ts
|
|
2688
|
+
const DEFAULT_CLAUDE_BACKEND = {
|
|
2689
|
+
command: "claude",
|
|
2690
|
+
args: [
|
|
2691
|
+
"-p",
|
|
2692
|
+
"--output-format",
|
|
2693
|
+
"json",
|
|
2694
|
+
"--dangerously-skip-permissions"
|
|
2695
|
+
],
|
|
2696
|
+
resumeArgs: [
|
|
2697
|
+
"-p",
|
|
2698
|
+
"--output-format",
|
|
2699
|
+
"json",
|
|
2700
|
+
"--dangerously-skip-permissions",
|
|
2701
|
+
"--resume",
|
|
2702
|
+
"{sessionId}"
|
|
2703
|
+
],
|
|
2704
|
+
output: "jsonl",
|
|
2705
|
+
input: "arg",
|
|
2706
|
+
modelArg: "--model",
|
|
2707
|
+
modelAliases: {
|
|
2708
|
+
opus: "opus",
|
|
2709
|
+
"opus-4.6": "opus",
|
|
2710
|
+
"opus-4.5": "opus",
|
|
2711
|
+
"opus-4": "opus",
|
|
2712
|
+
"claude-opus-4-6": "opus",
|
|
2713
|
+
"claude-opus-4-5": "opus",
|
|
2714
|
+
"claude-opus-4": "opus",
|
|
2715
|
+
sonnet: "sonnet",
|
|
2716
|
+
"sonnet-4.5": "sonnet",
|
|
2717
|
+
"sonnet-4.1": "sonnet",
|
|
2718
|
+
"sonnet-4.0": "sonnet",
|
|
2719
|
+
"claude-sonnet-4-5": "sonnet",
|
|
2720
|
+
"claude-sonnet-4-1": "sonnet",
|
|
2721
|
+
"claude-sonnet-4-0": "sonnet",
|
|
2722
|
+
haiku: "haiku",
|
|
2723
|
+
"haiku-3.5": "haiku",
|
|
2724
|
+
"claude-haiku-3-5": "haiku"
|
|
2725
|
+
},
|
|
2726
|
+
sessionArg: "--session-id",
|
|
2727
|
+
sessionMode: "always",
|
|
2728
|
+
sessionIdFields: [
|
|
2729
|
+
"session_id",
|
|
2730
|
+
"sessionId",
|
|
2731
|
+
"conversation_id",
|
|
2732
|
+
"conversationId"
|
|
2733
|
+
],
|
|
2734
|
+
systemPromptArg: "--append-system-prompt",
|
|
2735
|
+
systemPromptMode: "append",
|
|
2736
|
+
systemPromptWhen: "first",
|
|
2737
|
+
clearEnv: ["ANTHROPIC_API_KEY", "ANTHROPIC_API_KEY_OLD"],
|
|
2738
|
+
serialize: true
|
|
2739
|
+
};
|
|
2740
|
+
const DEFAULT_CODEX_BACKEND = {
|
|
2741
|
+
command: "codex",
|
|
2742
|
+
args: [
|
|
2743
|
+
"exec",
|
|
2744
|
+
"--json",
|
|
2745
|
+
"--color",
|
|
2746
|
+
"never",
|
|
2747
|
+
"--sandbox",
|
|
2748
|
+
"read-only",
|
|
2749
|
+
"--skip-git-repo-check"
|
|
2750
|
+
],
|
|
2751
|
+
resumeArgs: [
|
|
2752
|
+
"exec",
|
|
2753
|
+
"resume",
|
|
2754
|
+
"{sessionId}"
|
|
2755
|
+
],
|
|
2756
|
+
output: "jsonl",
|
|
2757
|
+
resumeOutput: "text",
|
|
2758
|
+
input: "arg",
|
|
2759
|
+
modelArg: "--model",
|
|
2760
|
+
imageArg: "--image",
|
|
2761
|
+
sessionMode: "existing",
|
|
2762
|
+
serialize: true
|
|
2763
|
+
};
|
|
2764
|
+
const CLAUDE_BACKEND_ALIASES = [
|
|
2765
|
+
"claude-cli",
|
|
2766
|
+
"anthropic",
|
|
2767
|
+
"claude"
|
|
2768
|
+
];
|
|
2769
|
+
const CODEX_BACKEND_ALIASES = [
|
|
2770
|
+
"codex-cli",
|
|
2771
|
+
"openai-codex",
|
|
2772
|
+
"openai",
|
|
2773
|
+
"codex"
|
|
2774
|
+
];
|
|
2775
|
+
const CLAUDE_BACKEND_ALIAS_SET = new Set(CLAUDE_BACKEND_ALIASES.map((alias) => normalizeBackendKey(alias)));
|
|
2776
|
+
const CODEX_BACKEND_ALIAS_SET = new Set(CODEX_BACKEND_ALIASES.map((alias) => normalizeBackendKey(alias)));
|
|
2777
|
+
function normalizeBackendKey(key) {
|
|
2778
|
+
return normalizeProviderId(key);
|
|
2779
|
+
}
|
|
2780
|
+
function pickBackendConfig(config, normalizedId) {
|
|
2781
|
+
for (const [key, entry] of Object.entries(config)) if (normalizeBackendKey(key) === normalizedId) return entry;
|
|
2782
|
+
}
|
|
2783
|
+
function pickBackendConfigByAliases(config, aliases) {
|
|
2784
|
+
for (const alias of aliases) {
|
|
2785
|
+
const matched = pickBackendConfig(config, normalizeBackendKey(alias));
|
|
2786
|
+
if (matched) return matched;
|
|
2787
|
+
}
|
|
2788
|
+
}
|
|
2789
|
+
function mergeBackendConfig(base, override) {
|
|
2790
|
+
if (!override) return { ...base };
|
|
2791
|
+
return {
|
|
2792
|
+
...base,
|
|
2793
|
+
...override,
|
|
2794
|
+
args: override.args ?? base.args,
|
|
2795
|
+
env: {
|
|
2796
|
+
...base.env,
|
|
2797
|
+
...override.env
|
|
2798
|
+
},
|
|
2799
|
+
modelAliases: {
|
|
2800
|
+
...base.modelAliases,
|
|
2801
|
+
...override.modelAliases
|
|
2802
|
+
},
|
|
2803
|
+
clearEnv: Array.from(new Set([...base.clearEnv ?? [], ...override.clearEnv ?? []])),
|
|
2804
|
+
sessionIdFields: override.sessionIdFields ?? base.sessionIdFields,
|
|
2805
|
+
sessionArgs: override.sessionArgs ?? base.sessionArgs,
|
|
2806
|
+
resumeArgs: override.resumeArgs ?? base.resumeArgs
|
|
2807
|
+
};
|
|
2808
|
+
}
|
|
2809
|
+
function resolveCliBackendConfig(provider, cfg) {
|
|
2810
|
+
const normalized = normalizeBackendKey(provider);
|
|
2811
|
+
const configured = cfg?.agents?.defaults?.cliBackends ?? {};
|
|
2812
|
+
if (CLAUDE_BACKEND_ALIAS_SET.has(normalized)) {
|
|
2813
|
+
const merged = mergeBackendConfig(DEFAULT_CLAUDE_BACKEND, pickBackendConfigByAliases(configured, [provider, ...CLAUDE_BACKEND_ALIASES]));
|
|
2814
|
+
const command = merged.command?.trim();
|
|
2815
|
+
if (!command) return null;
|
|
2816
|
+
return {
|
|
2817
|
+
id: normalizeBackendKey("claude-cli"),
|
|
2818
|
+
config: {
|
|
2819
|
+
...merged,
|
|
2820
|
+
command
|
|
2821
|
+
}
|
|
2822
|
+
};
|
|
2516
2823
|
}
|
|
2517
|
-
if (
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2824
|
+
if (CODEX_BACKEND_ALIAS_SET.has(normalized)) {
|
|
2825
|
+
const merged = mergeBackendConfig(DEFAULT_CODEX_BACKEND, pickBackendConfigByAliases(configured, [provider, ...CODEX_BACKEND_ALIASES]));
|
|
2826
|
+
const command = merged.command?.trim();
|
|
2827
|
+
if (!command) return null;
|
|
2828
|
+
return {
|
|
2829
|
+
id: normalizeBackendKey("codex-cli"),
|
|
2830
|
+
config: {
|
|
2831
|
+
...merged,
|
|
2832
|
+
command
|
|
2833
|
+
}
|
|
2834
|
+
};
|
|
2528
2835
|
}
|
|
2529
|
-
const
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2836
|
+
const override = pickBackendConfig(configured, normalized);
|
|
2837
|
+
if (!override) return null;
|
|
2838
|
+
const command = override.command?.trim();
|
|
2839
|
+
if (!command) return null;
|
|
2840
|
+
return {
|
|
2841
|
+
id: normalized,
|
|
2842
|
+
config: {
|
|
2843
|
+
...override,
|
|
2844
|
+
command
|
|
2845
|
+
}
|
|
2846
|
+
};
|
|
2537
2847
|
}
|
|
2538
2848
|
|
|
2539
2849
|
//#endregion
|
|
@@ -2661,73 +2971,6 @@ function coerceToFailoverError(err, context) {
|
|
|
2661
2971
|
});
|
|
2662
2972
|
}
|
|
2663
2973
|
|
|
2664
|
-
//#endregion
|
|
2665
|
-
//#region src/logging/redact-identifier.ts
|
|
2666
|
-
function sha256HexPrefix(value, len = 12) {
|
|
2667
|
-
const safeLen = Number.isFinite(len) ? Math.max(1, Math.floor(len)) : 12;
|
|
2668
|
-
return crypto.createHash("sha256").update(value).digest("hex").slice(0, safeLen);
|
|
2669
|
-
}
|
|
2670
|
-
function redactIdentifier(value, opts) {
|
|
2671
|
-
const trimmed = value?.trim();
|
|
2672
|
-
if (!trimmed) return "-";
|
|
2673
|
-
return `sha256:${sha256HexPrefix(trimmed, opts?.len ?? 12)}`;
|
|
2674
|
-
}
|
|
2675
|
-
|
|
2676
|
-
//#endregion
|
|
2677
|
-
//#region src/agents/workspace-run.ts
|
|
2678
|
-
function resolveRunAgentId(params) {
|
|
2679
|
-
const rawSessionKey = params.sessionKey?.trim() ?? "";
|
|
2680
|
-
const shape = classifySessionKeyShape(rawSessionKey);
|
|
2681
|
-
if (shape === "malformed_agent") throw new Error("Malformed agent session key; refusing workspace resolution.");
|
|
2682
|
-
const explicit = typeof params.agentId === "string" && params.agentId.trim() ? normalizeAgentId(params.agentId) : void 0;
|
|
2683
|
-
if (explicit) return {
|
|
2684
|
-
agentId: explicit,
|
|
2685
|
-
agentIdSource: "explicit"
|
|
2686
|
-
};
|
|
2687
|
-
const defaultAgentId = resolveDefaultAgentId(params.config ?? {});
|
|
2688
|
-
if (shape === "missing" || shape === "legacy_or_alias") return {
|
|
2689
|
-
agentId: defaultAgentId || DEFAULT_AGENT_ID,
|
|
2690
|
-
agentIdSource: "default"
|
|
2691
|
-
};
|
|
2692
|
-
const parsed = parseAgentSessionKey(rawSessionKey);
|
|
2693
|
-
if (parsed?.agentId) return {
|
|
2694
|
-
agentId: normalizeAgentId(parsed.agentId),
|
|
2695
|
-
agentIdSource: "session_key"
|
|
2696
|
-
};
|
|
2697
|
-
return {
|
|
2698
|
-
agentId: defaultAgentId || DEFAULT_AGENT_ID,
|
|
2699
|
-
agentIdSource: "default"
|
|
2700
|
-
};
|
|
2701
|
-
}
|
|
2702
|
-
function redactRunIdentifier(value) {
|
|
2703
|
-
return redactIdentifier(value, { len: 12 });
|
|
2704
|
-
}
|
|
2705
|
-
function resolveRunWorkspaceDir(params) {
|
|
2706
|
-
const requested = params.workspaceDir;
|
|
2707
|
-
const { agentId, agentIdSource } = resolveRunAgentId({
|
|
2708
|
-
sessionKey: params.sessionKey,
|
|
2709
|
-
agentId: params.agentId,
|
|
2710
|
-
config: params.config
|
|
2711
|
-
});
|
|
2712
|
-
if (typeof requested === "string") {
|
|
2713
|
-
const trimmed = requested.trim();
|
|
2714
|
-
if (trimmed) return {
|
|
2715
|
-
workspaceDir: resolveUserPath(trimmed),
|
|
2716
|
-
usedFallback: false,
|
|
2717
|
-
agentId,
|
|
2718
|
-
agentIdSource
|
|
2719
|
-
};
|
|
2720
|
-
}
|
|
2721
|
-
const fallbackReason = requested == null ? "missing" : typeof requested === "string" ? "blank" : "invalid_type";
|
|
2722
|
-
return {
|
|
2723
|
-
workspaceDir: resolveUserPath(resolveAgentWorkspaceDir(params.config ?? {}, agentId)),
|
|
2724
|
-
usedFallback: true,
|
|
2725
|
-
fallbackReason,
|
|
2726
|
-
agentId,
|
|
2727
|
-
agentIdSource
|
|
2728
|
-
};
|
|
2729
|
-
}
|
|
2730
|
-
|
|
2731
2974
|
//#endregion
|
|
2732
2975
|
//#region src/agents/cli-runner.ts
|
|
2733
2976
|
const log$1 = createSubsystemLogger("agent/claude-cli");
|
|
@@ -2958,35 +3201,31 @@ async function runCliAgent(params) {
|
|
|
2958
3201
|
}
|
|
2959
3202
|
|
|
2960
3203
|
//#endregion
|
|
2961
|
-
//#region src/agents/
|
|
3204
|
+
//#region src/agents/gemini-direct-runner.ts
|
|
2962
3205
|
/**
|
|
2963
|
-
*
|
|
2964
|
-
*
|
|
2965
|
-
* Makes calls directly to api.anthropic.com without needing the claude CLI
|
|
2966
|
-
* binary to be installed or logged in. Works with any valid token:
|
|
3206
|
+
* Gemini Direct API Runner
|
|
2967
3207
|
*
|
|
2968
|
-
*
|
|
2969
|
-
*
|
|
3208
|
+
* Makes calls directly to generativelanguage.googleapis.com without needing
|
|
3209
|
+
* a CLI wrapper. Works with Google API keys (GEMINI_API_KEY).
|
|
2970
3210
|
*
|
|
2971
|
-
* This runner is automatically used when
|
|
2972
|
-
*
|
|
3211
|
+
* This runner is automatically used when a google API key is available
|
|
3212
|
+
* and the provider is set to "google" or "gemini".
|
|
2973
3213
|
*/
|
|
2974
|
-
const log = createSubsystemLogger("agent/
|
|
3214
|
+
const log = createSubsystemLogger("agent/gemini-direct");
|
|
3215
|
+
const DEFAULT_GEMINI_BASE_URL = "https://generativelanguage.googleapis.com/v1beta";
|
|
2975
3216
|
const MODEL_MAP = {
|
|
2976
|
-
|
|
2977
|
-
"
|
|
2978
|
-
"
|
|
2979
|
-
"
|
|
2980
|
-
"
|
|
2981
|
-
|
|
2982
|
-
"
|
|
2983
|
-
"
|
|
2984
|
-
"
|
|
2985
|
-
|
|
2986
|
-
"haiku-3.5": "claude-haiku-3-5",
|
|
2987
|
-
default: "claude-sonnet-4-5"
|
|
3217
|
+
gemini: "gemini-2.0-flash",
|
|
3218
|
+
"gemini-pro": "gemini-1.5-pro",
|
|
3219
|
+
"gemini-flash": "gemini-2.0-flash",
|
|
3220
|
+
"gemini-2.0": "gemini-2.0-flash",
|
|
3221
|
+
"gemini-2.0-flash": "gemini-2.0-flash",
|
|
3222
|
+
"gemini-2.0-pro": "gemini-2.0-pro-exp-02-05",
|
|
3223
|
+
"gemini-1.5": "gemini-1.5-pro",
|
|
3224
|
+
"gemini-1.5-pro": "gemini-1.5-pro",
|
|
3225
|
+
"gemini-1.5-flash": "gemini-1.5-flash",
|
|
3226
|
+
default: "gemini-2.0-flash"
|
|
2988
3227
|
};
|
|
2989
|
-
const HISTORY_FILE_SUFFIX = ".
|
|
3228
|
+
const HISTORY_FILE_SUFFIX = ".gemini-history.json";
|
|
2990
3229
|
async function loadSessionHistory(sessionFile) {
|
|
2991
3230
|
const histPath = sessionFile + HISTORY_FILE_SUFFIX;
|
|
2992
3231
|
try {
|
|
@@ -3009,15 +3248,19 @@ function resolveModel(model) {
|
|
|
3009
3248
|
const key = (model ?? "default").trim().toLowerCase() || "default";
|
|
3010
3249
|
return MODEL_MAP[key] ?? key;
|
|
3011
3250
|
}
|
|
3251
|
+
function buildModelPath(model) {
|
|
3252
|
+
return model.startsWith("models/") ? model : `models/${model}`;
|
|
3253
|
+
}
|
|
3012
3254
|
/**
|
|
3013
|
-
* Run an agent turn directly against
|
|
3255
|
+
* Run an agent turn directly against generativelanguage.googleapis.com.
|
|
3014
3256
|
*
|
|
3015
3257
|
* Maintains multi-turn conversation history per session file.
|
|
3016
3258
|
* Falls back to single-turn if history is unavailable.
|
|
3017
3259
|
*/
|
|
3018
|
-
async function
|
|
3260
|
+
async function runGeminiDirectAgent(params) {
|
|
3019
3261
|
const started = Date.now();
|
|
3020
3262
|
const resolvedModel = resolveModel(params.model);
|
|
3263
|
+
const modelPath = buildModelPath(resolvedModel);
|
|
3021
3264
|
log.info(`direct api exec: model=${resolvedModel} promptChars=${params.prompt.length}`);
|
|
3022
3265
|
const workspaceDir = resolveRunWorkspaceDir({
|
|
3023
3266
|
workspaceDir: params.workspaceDir,
|
|
@@ -3057,36 +3300,37 @@ async function runAnthropicDirectAgent(params) {
|
|
|
3057
3300
|
docsPath: docsPath ?? void 0,
|
|
3058
3301
|
tools: [],
|
|
3059
3302
|
contextFiles,
|
|
3060
|
-
modelDisplay: `
|
|
3303
|
+
modelDisplay: `google/${resolvedModel}`,
|
|
3061
3304
|
agentId: sessionAgentId
|
|
3062
3305
|
});
|
|
3063
3306
|
let history = await loadSessionHistory(params.sessionFile);
|
|
3064
3307
|
if (!history) history = {
|
|
3065
3308
|
sessionId: params.sessionId,
|
|
3066
|
-
|
|
3309
|
+
contents: [],
|
|
3067
3310
|
createdAt: started,
|
|
3068
3311
|
updatedAt: started
|
|
3069
3312
|
};
|
|
3070
|
-
history.
|
|
3313
|
+
history.contents.push({
|
|
3071
3314
|
role: "user",
|
|
3072
|
-
|
|
3315
|
+
parts: [{ text: params.prompt }]
|
|
3073
3316
|
});
|
|
3074
3317
|
const requestBody = {
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3318
|
+
systemInstruction: { parts: [{ text: systemPrompt }] },
|
|
3319
|
+
contents: history.contents,
|
|
3320
|
+
generationConfig: {
|
|
3321
|
+
maxOutputTokens: 8192,
|
|
3322
|
+
temperature: 1
|
|
3323
|
+
}
|
|
3079
3324
|
};
|
|
3080
3325
|
try {
|
|
3081
3326
|
const controller = new AbortController();
|
|
3082
3327
|
const timeoutHandle = setTimeout(() => controller.abort(), params.timeoutMs);
|
|
3083
|
-
const
|
|
3328
|
+
const url = `${DEFAULT_GEMINI_BASE_URL}/${modelPath}:generateContent?key=${params.apiKey}`;
|
|
3329
|
+
const response = await fetch(url, {
|
|
3084
3330
|
method: "POST",
|
|
3085
3331
|
headers: {
|
|
3086
|
-
"
|
|
3087
|
-
"
|
|
3088
|
-
"content-type": "application/json",
|
|
3089
|
-
"user-agent": `anima/3.0.5 (direct-runner; ${os.platform()})`
|
|
3332
|
+
"Content-Type": "application/json",
|
|
3333
|
+
"User-Agent": `anima/5.0.1 (gemini-direct-runner; ${os.platform()})`
|
|
3090
3334
|
},
|
|
3091
3335
|
body: JSON.stringify(requestBody),
|
|
3092
3336
|
signal: controller.signal
|
|
@@ -3097,8 +3341,8 @@ async function runAnthropicDirectAgent(params) {
|
|
|
3097
3341
|
const isAuth = response.status === 401 || response.status === 403;
|
|
3098
3342
|
const isRateLimit = response.status === 429;
|
|
3099
3343
|
const rateHint = isRateLimit ? " — rate limit hit, will retry next heartbeat." : "";
|
|
3100
|
-
const authHint = isAuth ? " —
|
|
3101
|
-
log.error(`
|
|
3344
|
+
const authHint = isAuth ? " — API key may be invalid. Check GEMINI_API_KEY environment variable." : "";
|
|
3345
|
+
log.error(`gemini api error: HTTP ${response.status}${authHint}${rateHint}`, {
|
|
3102
3346
|
status: response.status,
|
|
3103
3347
|
body: body.slice(0, 500)
|
|
3104
3348
|
});
|
|
@@ -3114,51 +3358,51 @@ async function runAnthropicDirectAgent(params) {
|
|
|
3114
3358
|
};
|
|
3115
3359
|
}
|
|
3116
3360
|
const data = await response.json();
|
|
3117
|
-
const
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
}
|
|
3128
|
-
|
|
3129
|
-
await saveSessionHistory(params.sessionFile, history);
|
|
3361
|
+
const candidate = data.candidates?.[0];
|
|
3362
|
+
const assistantText = (candidate?.content?.parts ?? []).filter((p) => typeof p.text === "string").map((p) => p.text).join("\n");
|
|
3363
|
+
if (assistantText && params.onPartialReply) await params.onPartialReply({ text: assistantText });
|
|
3364
|
+
if (assistantText) {
|
|
3365
|
+
history.contents.push({
|
|
3366
|
+
role: "model",
|
|
3367
|
+
parts: [{ text: assistantText }]
|
|
3368
|
+
});
|
|
3369
|
+
history.updatedAt = Date.now();
|
|
3370
|
+
await saveSessionHistory(params.sessionFile, history);
|
|
3371
|
+
}
|
|
3372
|
+
const usage = data.usageMetadata;
|
|
3130
3373
|
const durationMs = Date.now() - started;
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3374
|
+
log.info(`gemini api complete: ${durationMs}ms`, {
|
|
3375
|
+
inputTokens: usage?.promptTokenCount,
|
|
3376
|
+
outputTokens: usage?.candidatesTokenCount,
|
|
3377
|
+
finishReason: candidate?.finishReason
|
|
3378
|
+
});
|
|
3134
3379
|
return {
|
|
3135
3380
|
status: "completed",
|
|
3136
|
-
output:
|
|
3137
|
-
payloads: outputText ? [{ text: outputText }] : [],
|
|
3381
|
+
output: assistantText,
|
|
3138
3382
|
meta: {
|
|
3139
3383
|
durationMs,
|
|
3140
3384
|
agentMeta: {
|
|
3141
|
-
provider: "anthropic",
|
|
3142
3385
|
model: resolvedModel,
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
}
|
|
3386
|
+
provider: "google",
|
|
3387
|
+
usage: usage ? {
|
|
3388
|
+
input: usage.promptTokenCount ?? 0,
|
|
3389
|
+
output: usage.candidatesTokenCount ?? 0
|
|
3390
|
+
} : void 0
|
|
3149
3391
|
}
|
|
3150
3392
|
}
|
|
3151
3393
|
};
|
|
3152
3394
|
} catch (err) {
|
|
3153
|
-
const isAbort = err instanceof Error &&
|
|
3154
|
-
|
|
3395
|
+
const isAbort = err instanceof Error && err.name === "AbortError";
|
|
3396
|
+
const errorKind = isAbort ? "timeout" : "unknown";
|
|
3397
|
+
const errorMsg = isAbort ? `Request timed out after ${params.timeoutMs}ms` : String(err);
|
|
3398
|
+
log.error(`gemini api error: ${errorMsg}`, { error: String(err) });
|
|
3155
3399
|
return {
|
|
3156
|
-
status:
|
|
3400
|
+
status: "failed",
|
|
3157
3401
|
meta: {
|
|
3158
3402
|
durationMs: Date.now() - started,
|
|
3159
3403
|
error: {
|
|
3160
|
-
message:
|
|
3161
|
-
kind:
|
|
3404
|
+
message: errorMsg,
|
|
3405
|
+
kind: errorKind
|
|
3162
3406
|
}
|
|
3163
3407
|
}
|
|
3164
3408
|
};
|
|
@@ -3246,6 +3490,57 @@ async function runEmbeddedPiAgent(...args) {
|
|
|
3246
3490
|
}
|
|
3247
3491
|
}
|
|
3248
3492
|
}
|
|
3493
|
+
if (provider === "google" || provider === "gemini") {
|
|
3494
|
+
const geminiApiKey = (await resolveApiKeyForProvider({
|
|
3495
|
+
provider: "google",
|
|
3496
|
+
cfg: params.config
|
|
3497
|
+
}))?.apiKey;
|
|
3498
|
+
if (geminiApiKey) {
|
|
3499
|
+
await emitAgentEvent(params, "lifecycle", {
|
|
3500
|
+
phase: "start",
|
|
3501
|
+
startedAt
|
|
3502
|
+
});
|
|
3503
|
+
try {
|
|
3504
|
+
const result = await runGeminiDirectAgent({
|
|
3505
|
+
apiKey: geminiApiKey,
|
|
3506
|
+
sessionId: params.sessionId,
|
|
3507
|
+
sessionKey: params.sessionKey,
|
|
3508
|
+
agentId: params.agentId,
|
|
3509
|
+
sessionFile: params.sessionFile,
|
|
3510
|
+
workspaceDir: params.workspaceDir,
|
|
3511
|
+
config: params.config,
|
|
3512
|
+
prompt: params.prompt,
|
|
3513
|
+
model: params.model,
|
|
3514
|
+
thinkLevel: params.thinkLevel,
|
|
3515
|
+
timeoutMs,
|
|
3516
|
+
runId,
|
|
3517
|
+
extraSystemPrompt: params.extraSystemPrompt,
|
|
3518
|
+
ownerNumbers: params.ownerNumbers,
|
|
3519
|
+
onPartialReply: async (payload) => {
|
|
3520
|
+
if (!assistantStarted) {
|
|
3521
|
+
assistantStarted = true;
|
|
3522
|
+
await params.onAssistantMessageStart?.();
|
|
3523
|
+
}
|
|
3524
|
+
await params.onPartialReply?.(payload);
|
|
3525
|
+
await emitAgentEvent(params, "assistant", { text: payload.text });
|
|
3526
|
+
},
|
|
3527
|
+
onAssistantMessageStart: params.onAssistantMessageStart
|
|
3528
|
+
});
|
|
3529
|
+
await emitAgentEvent(params, "lifecycle", {
|
|
3530
|
+
phase: "end",
|
|
3531
|
+
durationMs: Date.now() - startedAt,
|
|
3532
|
+
status: result.status
|
|
3533
|
+
});
|
|
3534
|
+
return result;
|
|
3535
|
+
} catch (err) {
|
|
3536
|
+
await emitAgentEvent(params, "lifecycle", {
|
|
3537
|
+
phase: "error",
|
|
3538
|
+
error: String(err instanceof Error ? err.message : err)
|
|
3539
|
+
});
|
|
3540
|
+
throw err;
|
|
3541
|
+
}
|
|
3542
|
+
}
|
|
3543
|
+
}
|
|
3249
3544
|
const cliProvider = resolveCompatCliProvider(provider, params.config);
|
|
3250
3545
|
if (!resolveCliBackendConfig(cliProvider, params.config)) throw new Error(`No CLI backend available for provider "${provider}" (resolved "${cliProvider}").\nEither:\n • Run: anima setup-token (set an Anthropic API key — no CLI needed)\n • Install the matching CLI and log in`);
|
|
3251
3546
|
await emitAgentEvent(params, "lifecycle", {
|
|
@@ -3346,4 +3641,4 @@ async function waitForEmbeddedPiRunEnd(..._args) {
|
|
|
3346
3641
|
}
|
|
3347
3642
|
|
|
3348
3643
|
//#endregion
|
|
3349
|
-
export { normalizeTtsAutoMode as A, textToSpeech as B, getLastTtsAttempt as C, isTtsEnabled as D, isSummarizationEnabled as E, setLastTtsAttempt as F, isVoiceCompatibleAudio as H, setSummarizationEnabled as I, setTtsEnabled as L, resolveTtsAutoMode as M, resolveTtsConfig as N, isTtsProviderConfigured as O, resolveTtsPrefsPath as P, setTtsMaxLength as R, buildTtsSystemPromptHint as S, getTtsProvider as T,
|
|
3644
|
+
export { normalizeTtsAutoMode as A, textToSpeech as B, getLastTtsAttempt as C, isTtsEnabled as D, isSummarizationEnabled as E, setLastTtsAttempt as F, isVoiceCompatibleAudio as H, setSummarizationEnabled as I, setTtsEnabled as L, resolveTtsAutoMode as M, resolveTtsConfig as N, isTtsProviderConfigured as O, resolveTtsPrefsPath as P, setTtsMaxLength as R, buildTtsSystemPromptHint as S, getTtsProvider as T, stripHeartbeatToken as U, textToSpeechTelephony as V, resolveBootstrapContextForRun as W, resolveUserTimeFormat as _, queueEmbeddedPiMessage as a, killProcessTree as b, waitForEmbeddedPiRunEnd as c, describeFailoverError as d, isFailoverError as f, formatUserTime as g, buildSystemPromptParams as h, isEmbeddedPiRunStreaming as i, resolveTtsApiKey as j, maybeApplyTtsToPayload as k, runCliAgent as l, buildAgentSystemPrompt as m, compactEmbeddedPiSession as n, resolveEmbeddedSessionLane as o, isTimeoutError as p, isEmbeddedPiRunActive as r, runEmbeddedPiAgent as s, abortEmbeddedPiRun as t, coerceToFailoverError as u, resolveUserTimezone as v, getTtsMaxLength as w, sanitizeBinaryOutput as x, getShellConfig as y, setTtsProvider as z };
|