@noxsoft/anima 6.5.0 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/README.md +48 -0
  3. package/dist/{agent-VRQM14Xp.js → agent-BoAAHGEA.js} +3 -3
  4. package/dist/{agent-CnS0SRpT.js → agent-DuW0onwk.js} +4 -4
  5. package/dist/{agents-CvMRplDx.js → agents-BUXkSDns.js} +4 -4
  6. package/dist/{anthropic-direct-runner-C2Kwju-r.js → anthropic-direct-runner-DizCei79.js} +420 -4
  7. package/dist/{anthropic-direct-runner-BeYCnvZ8.js → anthropic-direct-runner-OjcTAH6g.js} +420 -3
  8. package/dist/{auth-choice-Dc5TAJwT.js → auth-choice-B1iGnjuE.js} +1 -1
  9. package/dist/{auth-choice-DY1saszS.js → auth-choice-HF9x6xk2.js} +1 -1
  10. package/dist/{banner-DAMtSjUF.js → banner-Dpa5d1If.js} +1 -1
  11. package/dist/build-info.json +3 -3
  12. package/dist/bundled/boot-md/handler.js +2 -2
  13. package/dist/bundled/session-memory/handler.js +1 -1
  14. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  15. package/dist/canvas-host/a2ui/a2ui.bundle.js +16410 -18893
  16. package/dist/{channel-web-B8mzTSaY.js → channel-web-C5mzsaa3.js} +3 -3
  17. package/dist/{cli-hcHk5KuP.js → cli-Cuq4bIg4.js} +2 -2
  18. package/dist/{cli-D8exVpuI.js → cli-X9ikywQ3.js} +3 -3
  19. package/dist/{command-registry-D3VhxpWx.js → command-registry-9V4uqrBV.js} +12 -12
  20. package/dist/{completion-cli-B3BqQJq9.js → completion-cli-BtvcR-U5.js} +1 -1
  21. package/dist/{completion-cli-CepDzeW1.js → completion-cli-DNWDwhab.js} +2 -2
  22. package/dist/{config-cli-B6Np85rk.js → config-cli-DfHE3KG-.js} +1 -1
  23. package/dist/{config-cli-3CaIxSKo.js → config-cli-fleq7-gq.js} +1 -1
  24. package/dist/{configure-zXK6UZ51.js → configure-B2Mfnwy_.js} +3 -3
  25. package/dist/{configure-D88dg6mE.js → configure-SnvMHZPD.js} +7 -7
  26. package/dist/{configure-D882Bg7c.js → configure-ZWxixuRA.js} +3 -3
  27. package/dist/{configure-xpjwedvJ.js → configure-lkozxQed.js} +8 -8
  28. package/dist/context-mdxDsO1v.js +223 -0
  29. package/dist/control-ui/assets/{index-DVpMpG5G.js → index-D4wqLVMN.js} +2 -2
  30. package/dist/control-ui/assets/{index-DVpMpG5G.js.map → index-D4wqLVMN.js.map} +1 -1
  31. package/dist/control-ui/assets/index-DIEQjjCN.js +73 -0
  32. package/dist/control-ui/assets/index-DIEQjjCN.js.map +1 -0
  33. package/dist/control-ui/assets/{observers-CxfWf9RO.js → observers-B7MfWiIZ.js} +2 -2
  34. package/dist/control-ui/assets/{observers-CxfWf9RO.js.map → observers-B7MfWiIZ.js.map} +1 -1
  35. package/dist/control-ui/index.html +1 -1
  36. package/dist/{deps-DyT32VfN.js → deps-BKLIBKjK.js} +1 -1
  37. package/dist/{doctor-WpKCNZeO.js → doctor-D7kKyUVk.js} +4 -4
  38. package/dist/{doctor-DEnSKgHu.js → doctor-DmCnZ-jF.js} +4 -4
  39. package/dist/{doctor-completion-CypXc1Uo.js → doctor-completion-B9SBdMoR.js} +1 -1
  40. package/dist/{doctor-completion-CPff9UlF.js → doctor-completion-BBvW4_J9.js} +1 -1
  41. package/dist/entry.js +1 -1
  42. package/dist/extensionAPI.js +1 -1
  43. package/dist/{gateway-cli-B_xsx5Nv.js → gateway-cli-CEM1vBuk.js} +15 -15
  44. package/dist/{gateway-cli-D3VBOA_i.js → gateway-cli-iumkTohn.js} +17 -17
  45. package/dist/{health-CabOEPQ0.js → health-B5N6_UOf.js} +3 -3
  46. package/dist/{health-C8KCBhuo.js → health-Cndq9b7A.js} +3 -3
  47. package/dist/{heartbeat-visibility-ZfNSbFcq.js → heartbeat-visibility-BQL13ZBH.js} +1 -1
  48. package/dist/{heartbeat-visibility-BjYY-mKG.js → heartbeat-visibility-CwcYugaR.js} +1 -1
  49. package/dist/{hooks-cli-Cs7GUa7G.js → hooks-cli-BZcvdIwE.js} +4 -4
  50. package/dist/{hooks-cli-DOs9WZ3K.js → hooks-cli-DSlPBQSY.js} +3 -3
  51. package/dist/index.js +10 -10
  52. package/dist/llm-slug-generator.js +1 -1
  53. package/dist/{login-BHnvW9HA.js → login-BEaBOSnw.js} +1 -1
  54. package/dist/{login-CrMpAZ0n.js → login-MzVPMRxL.js} +1 -1
  55. package/dist/{login-qr-DILcBA_q.js → login-qr-BjpDVBJE.js} +1 -1
  56. package/dist/{login-qr-CsAVGp00.js → login-qr-CxRI-tE2.js} +1 -1
  57. package/dist/{models-BM2_NkMu.js → models-CdNeYfSp.js} +4 -4
  58. package/dist/{models-cli-BpjeKsUz.js → models-cli-D7eSsPuk.js} +3 -3
  59. package/dist/{models-cli-BjY8wA-C.js → models-cli-fTZXo1zx.js} +5 -5
  60. package/dist/{onboard-DM9gULJN.js → onboard-C5K37NvY.js} +3 -3
  61. package/dist/{onboard-_-D81kAy.js → onboard-D-6QCnTi.js} +3 -3
  62. package/dist/{onboard-channels-UkphAdCy.js → onboard-channels-BsCq32Hn.js} +1 -1
  63. package/dist/{onboard-channels-CtT-RN60.js → onboard-channels-bx6oelzj.js} +1 -1
  64. package/dist/{onboarding-Djmm0PEM.js → onboarding-BeuMAyic.js} +4 -4
  65. package/dist/{onboarding-BB9PteK8.js → onboarding-CX1vIkcB.js} +4 -4
  66. package/dist/{outbound-send-deps-T_FgdfgW.js → outbound-send-deps-Y9AxHeLG.js} +1 -1
  67. package/dist/{pi-embedded-BMbtgOzv.js → pi-embedded-D15iww51.js} +1010 -104
  68. package/dist/{pi-embedded-DfbM3fAT.js → pi-embedded-DR8Pfd05.js} +1010 -104
  69. package/dist/{plugin-registry-QTkplP4s.js → plugin-registry-Do2D1nDk.js} +1 -1
  70. package/dist/{plugin-registry-DePMxn4z.js → plugin-registry-ME2FQAi-.js} +1 -1
  71. package/dist/plugin-sdk/affect/ego.d.ts +140 -0
  72. package/dist/plugin-sdk/agents/models-config.d.ts +5 -6
  73. package/dist/plugin-sdk/agents/noxsoft-runner.d.ts +3 -0
  74. package/dist/plugin-sdk/agents/openai-direct-runner.d.ts +41 -0
  75. package/dist/plugin-sdk/commands/steer.d.ts +49 -0
  76. package/dist/plugin-sdk/gateway/protocol/index.d.ts +2 -2
  77. package/dist/{plugins-cli-Dv0KQTWo.js → plugins-cli-CVFzwdmI.js} +4 -4
  78. package/dist/{plugins-cli-Bc9oU1ld.js → plugins-cli-CoVt2ewg.js} +3 -3
  79. package/dist/{program-CuwbF8YO.js → program-8rF4C_wd.js} +8 -8
  80. package/dist/{program-context-CxPfy-Wr.js → program-context-DP3qjW7A.js} +18 -18
  81. package/dist/{register.agent-DFQmkIEH.js → register.agent-BIrXCVtQ.js} +9 -9
  82. package/dist/{register.agent-DUjwGw9d.js → register.agent-DnkOx0U8.js} +7 -7
  83. package/dist/{register.anima-CtKNrpE8.js → register.anima-B36rTHUt.js} +2 -2
  84. package/dist/{register.anima-CRFHJu2J.js → register.anima-DXT9bM9A.js} +2 -2
  85. package/dist/{register.configure-CnEKV57N.js → register.configure-CuzJxZmk.js} +6 -6
  86. package/dist/{register.configure-CSSN07XN.js → register.configure-DCpvHX3m.js} +7 -7
  87. package/dist/{register.maintenance-fhcCB7ih.js → register.maintenance-CcxBFfv5.js} +10 -10
  88. package/dist/{register.maintenance-CU1A-90-.js → register.maintenance-Dla0H12S.js} +8 -8
  89. package/dist/{register.message-C1a0y2ZR.js → register.message-Brtushvp.js} +4 -4
  90. package/dist/{register.message-fM0jSKB8.js → register.message-CD7xV-jz.js} +5 -5
  91. package/dist/{register.onboard-BhPlqjFi.js → register.onboard-23Mra3LN.js} +11 -11
  92. package/dist/{register.onboard-B7Gavmvt.js → register.onboard-6CbODzQ6.js} +9 -9
  93. package/dist/{register.setup-CADdQUEN.js → register.setup-CqQw13Ky.js} +11 -11
  94. package/dist/{register.setup-0jPnMgnz.js → register.setup-DlVH7FKe.js} +9 -9
  95. package/dist/{register.status-health-sessions-Cu5fDT-z.js → register.status-health-sessions-CduFjFDB.js} +4 -4
  96. package/dist/{register.status-health-sessions-DdQsABr_.js → register.status-health-sessions-CxtgPKu9.js} +6 -6
  97. package/dist/{register.subclis-CZ91ufCy.js → register.subclis-CtANqD5P.js} +7 -7
  98. package/dist/{reply-DtHlnzOx.js → reply-93fMzde1.js} +610 -75
  99. package/dist/{reply-prefix-C8dIgJur.js → reply-prefix-B7Fb3fO8.js} +1 -1
  100. package/dist/{reply-prefix-DmWGtcH-.js → reply-prefix-BzdhJDqP.js} +1 -1
  101. package/dist/{run-Dfz_7j7t.js → run-CF3kHOGH.js} +1717 -83
  102. package/dist/{run-DqBQ-bGn.js → run-Cq_iTGK_.js} +1718 -84
  103. package/dist/{run-main-DGDW0fhx.js → run-main-BiIRcc6s.js} +17 -17
  104. package/dist/{server-node-events-Ca797E1d.js → server-node-events-B3Serk9L.js} +6 -6
  105. package/dist/{server-node-events-BR1aXVlu.js → server-node-events-DgvKcH5q.js} +5 -5
  106. package/dist/{session-C7IGnhd1.js → session-BMDpwIJu.js} +1 -1
  107. package/dist/{session-FmXsucR7.js → session-BzrnfWQ2.js} +2 -2
  108. package/dist/{session-DfsMJNG3.js → session-C_d9uvLf.js} +1 -1
  109. package/dist/{session-DLevr8Vd.js → session-jljC5QVG.js} +2 -2
  110. package/dist/{sessions-Dj7_4mkr.js → sessions-BmE5Z_1i.js} +1 -1
  111. package/dist/{settings-cli-DxNeu6kx.js → settings-cli-CZdlEmNi.js} +7 -7
  112. package/dist/{settings-cli-Dytfop1H.js → settings-cli-DsDqNpW_.js} +8 -8
  113. package/dist/{setup-token-B802CZwe.js → setup-token-C8Gg1P6T.js} +1 -1
  114. package/dist/{setup-token-DYh2QzJ-.js → setup-token-Lee4gM5w.js} +1 -1
  115. package/dist/{start-BqnPia0t.js → start-CK6urvnN.js} +17 -17
  116. package/dist/{start-C3fuLzX0.js → start-Cs1aPMq2.js} +15 -15
  117. package/dist/{status-CHGNPonc.js → status-BO5BIf81.js} +3 -3
  118. package/dist/{status-CxF6k_jr.js → status-COc4xMti.js} +1 -1
  119. package/dist/{status-tLgozFYL.js → status-C_NBOv_V.js} +1 -1
  120. package/dist/{status-DfZJJqNs.js → status-uakoP719.js} +4 -4
  121. package/dist/{subagent-registry-CPtElVX0.js → subagent-registry-fLI7QDKe.js} +449 -77
  122. package/dist/{update-cli-C-er5av6.js → update-cli-D3Ujz_cW.js} +10 -10
  123. package/dist/{update-cli-BuCw75tM.js → update-cli-DEe62XGU.js} +8 -8
  124. package/dist/{update-runner-kE8AMQt4.js → update-runner-DUl-g4mB.js} +1 -1
  125. package/dist/{update-runner-czCqHZCu.js → update-runner-DZfnquWO.js} +1 -1
  126. package/dist/{web-BHGK5GtV.js → web-C-cK9OCd.js} +1 -1
  127. package/dist/{web-DvTXV-fo.js → web-Di8j762D.js} +6 -6
  128. package/dist/{web-CyYunanU.js → web-Dybw4K7C.js} +6 -6
  129. package/dist/{web-so3pGceM.js → web-DzSlI8A6.js} +1 -1
  130. package/package.json +4 -4
  131. package/dist/context-B5X720Bs.js +0 -60
  132. package/dist/control-ui/assets/index-CBUvF5Mp.js +0 -72
  133. package/dist/control-ui/assets/index-CBUvF5Mp.js.map +0 -1
@@ -18,7 +18,7 @@ import { a as randomIdempotencyKey, n as callGateway } from "./call-B4lhqS6H.js"
18
18
  import { a as isInternalMessageChannel, c as listDeliverableMessageChannels, d as resolveMessageChannel, h as GATEWAY_CLIENT_NAMES, l as normalizeMessageChannel, m as GATEWAY_CLIENT_MODES, n as isDeliverableMessageChannel, o as isMarkdownCapableMessageChannel, p as GATEWAY_CLIENT_IDS, t as INTERNAL_MESSAGE_CHANNEL, u as resolveGatewayMessageChannel } from "./message-channel-DIHHKJhk.js";
19
19
  import { A as buildGroupDisplayName, D as listChannelDocks, E as getChannelDock, F as normalizeDeliveryContext, I as normalizeSessionDeliveryFields, M as deliveryContextFromSession, N as deliveryContextKey, O as resolveConversationLabel, P as mergeDeliveryContext, S as resolveMainSessionKey, _ as DEFAULT_RESET_TRIGGERS, a as readSessionUpdatedAt, b as resolveAgentMainSessionKey, c as updateLastRoute, d as resolveSessionKey$1, f as evaluateSessionFreshness, g as resolveThreadFlag, h as resolveSessionResetType, i as loadSessionStore, j as resolveGroupSessionKey, k as normalizeChatType, l as updateSessionStore, m as resolveSessionResetPolicy, n as appendAssistantMessageToSessionTranscript, o as recordSessionMetaFromInbound, p as resolveChannelResetConfig, t as extractDeliveryInfo, u as updateSessionStoreEntry, v as resolveFreshSessionTotalTokens, w as deriveSessionMetaPatch, y as canonicalizeMainSessionAlias } from "./sessions-C_3wTmSA.js";
20
20
  import { n as SILENT_REPLY_TOKEN, r as isSilentReplyText, t as HEARTBEAT_TOKEN } from "./tokens-CmlI2hSz.js";
21
- import { $ as isVoiceCompatibleAudio, A as getLastTtsAttempt, B as resolveTtsConfig, C as formatUserTime, D as killProcessTree, E as getShellConfig, F as isTtsProviderConfigured, G as setTtsEnabled, I as maybeApplyTtsToPayload, J as textToSpeech, K as setTtsMaxLength, L as normalizeTtsAutoMode, M as getTtsProvider, N as isSummarizationEnabled, O as sanitizeBinaryOutput, P as isTtsEnabled, R as resolveTtsApiKey, S as buildSystemPromptParams, T as resolveUserTimezone, U as setLastTtsAttempt, V as resolveTtsPrefsPath, W as setSummarizationEnabled, Y as textToSpeechTelephony, _ as resolvePromptInput, at as triggerInternalHook, b as writeCliImages, c as appendImagePathsToPrompt, d as cleanupResumeProcesses, et as makeBootstrapWarn, f as cleanupSuspendedCliProcesses, g as parseCliJsonl, h as parseCliJson, i as resolveRunWorkspaceDir, it as registerInternalHook, j as getTtsMaxLength, k as buildTtsSystemPromptHint, l as buildCliArgs, lt as resolveHeartbeatPrompt, m as normalizeCliModel, o as appendRunnerCapabilityPrompt, p as enqueueCliRun, q as setTtsProvider, r as redactRunIdentifier, rt as createInternalHookEvent, s as resolveAnimaDocsPath, t as runAnthropicDirectAgent, tt as resolveBootstrapContextForRun, u as buildSystemPrompt, ut as stripHeartbeatToken, v as resolveSessionIdToSend, w as resolveUserTimeFormat, x as buildAgentSystemPrompt, y as resolveSystemPromptUsage, z as resolveTtsAutoMode } from "./anthropic-direct-runner-C2Kwju-r.js";
21
+ import { $ as isVoiceCompatibleAudio, A as getLastTtsAttempt, B as resolveTtsConfig, C as formatUserTime, D as killProcessTree, E as getShellConfig, F as isTtsProviderConfigured, G as setTtsEnabled, I as maybeApplyTtsToPayload, J as textToSpeech, K as setTtsMaxLength, L as normalizeTtsAutoMode, M as getTtsProvider, N as isSummarizationEnabled, O as sanitizeBinaryOutput, P as isTtsEnabled, R as resolveTtsApiKey, S as buildSystemPromptParams, T as resolveUserTimezone, U as setLastTtsAttempt, V as resolveTtsPrefsPath, W as setSummarizationEnabled, Y as textToSpeechTelephony, _ as resolvePromptInput, at as makeBootstrapWarn, b as writeCliImages, c as appendImagePathsToPrompt, ct as createInternalHookEvent, d as cleanupResumeProcesses, f as cleanupSuspendedCliProcesses, g as parseCliJsonl, h as parseCliJson, ht as stripHeartbeatToken, i as resolveRunWorkspaceDir, j as getTtsMaxLength, k as buildTtsSystemPromptHint, l as buildCliArgs, lt as registerInternalHook, m as normalizeCliModel, mt as resolveHeartbeatPrompt, o as appendRunnerCapabilityPrompt, ot as resolveBootstrapContextForRun, p as enqueueCliRun, q as setTtsProvider, r as redactRunIdentifier, s as resolveAnimaDocsPath, t as runAnthropicDirectAgent, u as buildSystemPrompt, ut as triggerInternalHook, v as resolveSessionIdToSend, w as resolveUserTimeFormat, x as buildAgentSystemPrompt, y as resolveSystemPromptUsage, z as resolveTtsAutoMode } from "./anthropic-direct-runner-DizCei79.js";
22
22
  import { S as resolveBootstrapMaxChars, _ as isFailoverErrorMessage, a as normalizeElevatedLevel, b as sanitizeUserFacingText, c as normalizeUsageDisplay, d as supportsXHighThinking, g as isContextOverflowError, h as isCompactionFailureError, l as normalizeVerboseLevel, n as formatXHighModelHint, o as normalizeReasoningLevel, p as classifyFailoverReason, s as normalizeThinkLevel, t as formatThinkingLevels, u as resolveResponseUsageMode, v as isLikelyContextOverflowError, y as isTransientHttpError } from "./pi-embedded-helpers-D2SLlgS4.js";
23
23
  import { _ as resolveToolProfilePolicy, a as ensureSandboxWorkspaceForSession, c as resolveSandboxConfigForAgent, d as applyOwnerOnlyToolPolicy, f as buildPluginToolGroups, g as normalizeToolName, m as expandPolicyWithPluginGroups, o as resolveSandboxRuntimeStatus, p as collectExplicitAllowlist, s as getBridgeAuthForPort, v as stripPluginOnlyAllowlist } from "./sandbox-D-N7M7lp.js";
24
24
  import { x as DEFAULT_AI_SNAPSHOT_MAX_CHARS } from "./chrome-CmxIwwsr.js";
@@ -40,7 +40,7 @@ import { a as chunkText, c as resolveTextChunkLimit, i as chunkMarkdownTextWithM
40
40
  import { a as shouldHandleTextCommands, i as normalizeCommandBody, n as listChatCommands, r as listChatCommandsForConfig, t as parseTimeoutMs } from "./parse-timeout-D4UO8pY_.js";
41
41
  import { n as formatTimeAgo } from "./format-relative-CBDSicUs.js";
42
42
  import { a as resolveMarkdownTableMode, c as loadWebMedia, d as readResponseWithLimit, f as fetchWithSsrFGuard, i as convertMarkdownTables, l as MediaFetchError, m as fetchWithTimeout, o as normalizePollInput, p as bindAbortRelay, s as getDefaultLocalRoots, t as getActiveWebListener, u as fetchRemoteMedia } from "./active-listener-gGCoq55D.js";
43
- import { n as ensureAnimaModelsJson, t as lookupContextTokens } from "./context-B5X720Bs.js";
43
+ import { n as ensureAnimaModelsJson, t as lookupContextTokens } from "./context-mdxDsO1v.js";
44
44
  import { a as resolveSubagentToolPolicy, c as addChannelAllowFromStoreEntry, d as upsertChannelPairingRequest, f as listPairingChannels, i as resolveGroupToolPolicy, l as readChannelAllowFromStore, n as isToolAllowedByPolicies, o as resolveChannelGroupPolicy, r as resolveEffectiveToolPolicy, s as resolveChannelGroupRequireMention, t as filterToolsByPolicy, u as removeChannelAllowFromStoreEntry } from "./pi-tools.policy-D2FusuQa.js";
45
45
  import { a as minSecurity, c as recordAllowlistUse, d as resolveExecApprovalsFromFile, g as resolveSafeBins, h as evaluateShellAllowlist, i as maxAsk, l as requiresExecApproval, n as addAllowlistEntry, u as resolveExecApprovals, v as buildSafeBinsShellCommand, y as buildSafeShellCommand } from "./exec-approvals-CpOeHRBL.js";
46
46
  import { t as resolveNodeIdFromCandidates } from "./node-match-Cbt-ZqUE.js";
@@ -928,7 +928,7 @@ function coerceToFailoverError(err, context) {
928
928
 
929
929
  //#endregion
930
930
  //#region src/agents/cli-runner.ts
931
- const log$6 = createSubsystemLogger("agent/claude-cli");
931
+ const log$7 = createSubsystemLogger("agent/claude-cli");
932
932
  async function runCliAgent(params) {
933
933
  const started = Date.now();
934
934
  const workspaceResolution = resolveRunWorkspaceDir({
@@ -941,7 +941,7 @@ async function runCliAgent(params) {
941
941
  const redactedSessionId = redactRunIdentifier(params.sessionId);
942
942
  const redactedSessionKey = redactRunIdentifier(params.sessionKey);
943
943
  const redactedWorkspace = redactRunIdentifier(resolvedWorkspace);
944
- if (workspaceResolution.usedFallback) log$6.warn(`[workspace-fallback] caller=runCliAgent reason=${workspaceResolution.fallbackReason} run=${params.runId} session=${redactedSessionId} sessionKey=${redactedSessionKey} agent=${workspaceResolution.agentId} workspace=${redactedWorkspace}`);
944
+ if (workspaceResolution.usedFallback) log$7.warn(`[workspace-fallback] caller=runCliAgent reason=${workspaceResolution.fallbackReason} run=${params.runId} session=${redactedSessionId} sessionKey=${redactedSessionKey} agent=${workspaceResolution.agentId} workspace=${redactedWorkspace}`);
945
945
  const workspaceDir = resolvedWorkspace;
946
946
  const backendResolved = resolveCliBackendConfig(params.provider, params.config, { execSecurity: params.sessionExecSecurity });
947
947
  if (!backendResolved) throw new Error(`Unknown CLI backend: ${params.provider}`);
@@ -959,7 +959,7 @@ async function runCliAgent(params) {
959
959
  sessionId: params.sessionId,
960
960
  warn: makeBootstrapWarn({
961
961
  sessionLabel,
962
- warn: (message) => log$6.warn(message)
962
+ warn: (message) => log$7.warn(message)
963
963
  })
964
964
  });
965
965
  const { defaultAgentId, sessionAgentId } = resolveSessionAgentIds({
@@ -1001,17 +1001,17 @@ async function runCliAgent(params) {
1001
1001
  const previousMode = parsed.metadata?.effectiveCodexExecMode ?? parsed.metadata?.effectiveSandbox;
1002
1002
  const currentMode = effectiveCodexExecMode;
1003
1003
  if (!previousMode) {
1004
- log$6.info("Codex execution mode is unknown for the saved session; forcing session restart.");
1004
+ log$7.info("Codex execution mode is unknown for the saved session; forcing session restart.");
1005
1005
  useResume = false;
1006
1006
  isNew = true;
1007
1007
  } else if (previousMode !== currentMode) {
1008
- log$6.info(`Codex execution mode changed (${previousMode} -> ${currentMode}); forcing session restart.`);
1008
+ log$7.info(`Codex execution mode changed (${previousMode} -> ${currentMode}); forcing session restart.`);
1009
1009
  useResume = false;
1010
1010
  isNew = true;
1011
1011
  }
1012
1012
  }
1013
1013
  } catch {
1014
- log$6.info("Codex session transcript is unavailable; forcing session restart.");
1014
+ log$7.info("Codex session transcript is unavailable; forcing session restart.");
1015
1015
  useResume = false;
1016
1016
  isNew = true;
1017
1017
  }
@@ -1056,7 +1056,7 @@ async function runCliAgent(params) {
1056
1056
  const queueKey = backend.serialize ?? true ? backendResolved.id : `${backendResolved.id}:${params.runId}`;
1057
1057
  try {
1058
1058
  const output = await enqueueCliRun(queueKey, async () => {
1059
- log$6.info(`cli exec: provider=${params.provider} model=${normalizedModel} promptChars=${params.prompt.length}`);
1059
+ log$7.info(`cli exec: provider=${params.provider} model=${normalizedModel} promptChars=${params.prompt.length}`);
1060
1060
  const logOutputText = isTruthyEnvValue(process.env.ANIMA_CLAUDE_CLI_LOG_OUTPUT);
1061
1061
  if (logOutputText) {
1062
1062
  const logArgs = [];
@@ -1089,7 +1089,7 @@ async function runCliAgent(params) {
1089
1089
  const promptIndex = logArgs.indexOf(argsPrompt);
1090
1090
  if (promptIndex >= 0) logArgs[promptIndex] = `<prompt:${argsPrompt.length} chars>`;
1091
1091
  }
1092
- log$6.info(`cli argv: ${backend.command} ${logArgs.join(" ")}`);
1092
+ log$7.info(`cli argv: ${backend.command} ${logArgs.join(" ")}`);
1093
1093
  }
1094
1094
  const env = (() => {
1095
1095
  const next = {
@@ -1122,12 +1122,12 @@ async function runCliAgent(params) {
1122
1122
  const stdout = result.stdout.trim();
1123
1123
  const stderr = result.stderr.trim();
1124
1124
  if (logOutputText) {
1125
- if (stdout) log$6.info(`cli stdout:\n${stdout}`);
1126
- if (stderr) log$6.info(`cli stderr:\n${stderr}`);
1125
+ if (stdout) log$7.info(`cli stdout:\n${stdout}`);
1126
+ if (stderr) log$7.info(`cli stderr:\n${stderr}`);
1127
1127
  }
1128
1128
  if (shouldLogVerbose()) {
1129
- if (stdout) log$6.debug(`cli stdout:\n${stdout}`);
1130
- if (stderr) log$6.debug(`cli stderr:\n${stderr}`);
1129
+ if (stdout) log$7.debug(`cli stdout:\n${stdout}`);
1130
+ if (stderr) log$7.debug(`cli stderr:\n${stderr}`);
1131
1131
  }
1132
1132
  if (result.code !== 0) {
1133
1133
  const timedOut = result.killed && result.signal === "SIGKILL";
@@ -7627,7 +7627,7 @@ function resolveDefaultModel(params) {
7627
7627
 
7628
7628
  //#endregion
7629
7629
  //#region src/agents/skills/refresh.ts
7630
- const log$5 = createSubsystemLogger("gateway/skills");
7630
+ const log$6 = createSubsystemLogger("gateway/skills");
7631
7631
  const listeners = /* @__PURE__ */ new Set();
7632
7632
  const workspaceVersions = /* @__PURE__ */ new Map();
7633
7633
  const watchers = /* @__PURE__ */ new Map();
@@ -7652,7 +7652,7 @@ function emit(event) {
7652
7652
  for (const listener of listeners) try {
7653
7653
  listener(event);
7654
7654
  } catch (err) {
7655
- log$5.warn(`skills change listener failed: ${String(err)}`);
7655
+ log$6.warn(`skills change listener failed: ${String(err)}`);
7656
7656
  }
7657
7657
  }
7658
7658
  function resolveWatchPaths(workspaceDir, config) {
@@ -7769,7 +7769,7 @@ function ensureSkillsWatcher(params) {
7769
7769
  watcher.on("change", (p) => schedule(p));
7770
7770
  watcher.on("unlink", (p) => schedule(p));
7771
7771
  watcher.on("error", (err) => {
7772
- log$5.warn(`skills watcher error (${workspaceDir}): ${String(err)}`);
7772
+ log$6.warn(`skills watcher error (${workspaceDir}): ${String(err)}`);
7773
7773
  });
7774
7774
  watchers.set(workspaceDir, state);
7775
7775
  }
@@ -7956,7 +7956,7 @@ async function renamePairedNode(nodeId, displayName, baseDir) {
7956
7956
 
7957
7957
  //#endregion
7958
7958
  //#region src/infra/skills-remote.ts
7959
- const log$4 = createSubsystemLogger("gateway/skills-remote");
7959
+ const log$5 = createSubsystemLogger("gateway/skills-remote");
7960
7960
  const remoteNodes = /* @__PURE__ */ new Map();
7961
7961
  let remoteRegistry = null;
7962
7962
  function describeNode(nodeId) {
@@ -7983,14 +7983,14 @@ function logRemoteBinProbeFailure(nodeId, err) {
7983
7983
  const message = extractErrorMessage(err);
7984
7984
  const label = describeNode(nodeId);
7985
7985
  if (message?.includes("node not connected") || message?.includes("node disconnected")) {
7986
- log$4.info(`remote bin probe skipped: node unavailable (${label})`);
7986
+ log$5.info(`remote bin probe skipped: node unavailable (${label})`);
7987
7987
  return;
7988
7988
  }
7989
7989
  if (message?.includes("invoke timed out") || message?.includes("timeout")) {
7990
- log$4.warn(`remote bin probe timed out (${label}); check node connectivity for ${label}`);
7990
+ log$5.warn(`remote bin probe timed out (${label}); check node connectivity for ${label}`);
7991
7991
  return;
7992
7992
  }
7993
- log$4.warn(`remote bin probe error (${label}): ${message ?? "unknown"}`);
7993
+ log$5.warn(`remote bin probe error (${label}): ${message ?? "unknown"}`);
7994
7994
  }
7995
7995
  function isMacPlatform(platform, deviceFamily) {
7996
7996
  const platformNorm = String(platform ?? "").trim().toLowerCase();
@@ -8040,7 +8040,7 @@ async function primeRemoteSkillsCache() {
8040
8040
  }
8041
8041
  if (sawMac) bumpSkillsSnapshotVersion({ reason: "remote-node" });
8042
8042
  } catch (err) {
8043
- log$4.warn(`failed to prime remote skills cache: ${String(err)}`);
8043
+ log$5.warn(`failed to prime remote skills cache: ${String(err)}`);
8044
8044
  }
8045
8045
  }
8046
8046
  function recordRemoteNodeInfo(node) {
@@ -25609,7 +25609,7 @@ async function resolveAnnounceTarget(params) {
25609
25609
 
25610
25610
  //#endregion
25611
25611
  //#region src/agents/tools/sessions-send-tool.a2a.ts
25612
- const log$3 = createSubsystemLogger("agents/sessions-send");
25612
+ const log$4 = createSubsystemLogger("agents/sessions-send");
25613
25613
  async function runSessionsSendA2AFlow(params) {
25614
25614
  const runContextId = params.waitRunId ?? "unknown";
25615
25615
  try {
@@ -25700,7 +25700,7 @@ async function runSessionsSendA2AFlow(params) {
25700
25700
  timeoutMs: 1e4
25701
25701
  });
25702
25702
  } catch (err) {
25703
- log$3.warn("sessions_send announce delivery failed", {
25703
+ log$4.warn("sessions_send announce delivery failed", {
25704
25704
  runId: runContextId,
25705
25705
  channel: announceTarget.channel,
25706
25706
  to: announceTarget.to,
@@ -25708,7 +25708,7 @@ async function runSessionsSendA2AFlow(params) {
25708
25708
  });
25709
25709
  }
25710
25710
  } catch (err) {
25711
- log$3.warn("sessions_send announce flow failed", {
25711
+ log$4.warn("sessions_send announce flow failed", {
25712
25712
  runId: runContextId,
25713
25713
  error: formatErrorMessage(err)
25714
25714
  });
@@ -32479,7 +32479,7 @@ function createWhatsAppLoginTool() {
32479
32479
  force: Type.Optional(Type.Boolean())
32480
32480
  }),
32481
32481
  execute: async (_toolCallId, args) => {
32482
- const { startWebLoginWithQr, waitForWebLogin } = await import("./login-qr-DILcBA_q.js");
32482
+ const { startWebLoginWithQr, waitForWebLogin } = await import("./login-qr-BjpDVBJE.js");
32483
32483
  if ((args?.action ?? "start") === "wait") {
32484
32484
  const result = await waitForWebLogin({ timeoutMs: typeof args.timeoutMs === "number" ? args.timeoutMs : void 0 });
32485
32485
  return {
@@ -32658,15 +32658,15 @@ function loadWebOutbound() {
32658
32658
  return webOutboundPromise;
32659
32659
  }
32660
32660
  function loadWebLogin() {
32661
- webLoginPromise ??= import("./login-CrMpAZ0n.js").then((n) => n.n);
32661
+ webLoginPromise ??= import("./login-MzVPMRxL.js").then((n) => n.n);
32662
32662
  return webLoginPromise;
32663
32663
  }
32664
32664
  function loadWebLoginQr() {
32665
- webLoginQrPromise ??= import("./login-qr-DILcBA_q.js");
32665
+ webLoginQrPromise ??= import("./login-qr-BjpDVBJE.js");
32666
32666
  return webLoginQrPromise;
32667
32667
  }
32668
32668
  function loadWebChannel() {
32669
- webChannelPromise ??= import("./web-DvTXV-fo.js");
32669
+ webChannelPromise ??= import("./web-Di8j762D.js");
32670
32670
  return webChannelPromise;
32671
32671
  }
32672
32672
  function loadWhatsAppActions() {
@@ -33146,7 +33146,7 @@ function loadAnimaPlugins(options = {}) {
33146
33146
 
33147
33147
  //#endregion
33148
33148
  //#region src/plugins/tools.ts
33149
- const log$2 = createSubsystemLogger("plugins");
33149
+ const log$3 = createSubsystemLogger("plugins");
33150
33150
  const pluginToolMeta = /* @__PURE__ */ new WeakMap();
33151
33151
  function getPluginToolMeta(tool) {
33152
33152
  return pluginToolMeta.get(tool);
@@ -33169,10 +33169,10 @@ function resolvePluginTools(params) {
33169
33169
  config: effectiveConfig,
33170
33170
  workspaceDir: params.context.workspaceDir,
33171
33171
  logger: {
33172
- info: (msg) => log$2.info(msg),
33173
- warn: (msg) => log$2.warn(msg),
33174
- error: (msg) => log$2.error(msg),
33175
- debug: (msg) => log$2.debug(msg)
33172
+ info: (msg) => log$3.info(msg),
33173
+ warn: (msg) => log$3.warn(msg),
33174
+ error: (msg) => log$3.error(msg),
33175
+ debug: (msg) => log$3.debug(msg)
33176
33176
  }
33177
33177
  });
33178
33178
  const tools = [];
@@ -33185,7 +33185,7 @@ function resolvePluginTools(params) {
33185
33185
  const pluginIdKey = normalizeToolName(entry.pluginId);
33186
33186
  if (existingNormalized.has(pluginIdKey)) {
33187
33187
  const message = `plugin id conflicts with core tool name (${entry.pluginId})`;
33188
- log$2.error(message);
33188
+ log$3.error(message);
33189
33189
  registry.diagnostics.push({
33190
33190
  level: "error",
33191
33191
  pluginId: entry.pluginId,
@@ -33199,7 +33199,7 @@ function resolvePluginTools(params) {
33199
33199
  try {
33200
33200
  resolved = entry.factory(params.context);
33201
33201
  } catch (err) {
33202
- log$2.error(`plugin tool failed (${entry.pluginId}): ${String(err)}`);
33202
+ log$3.error(`plugin tool failed (${entry.pluginId}): ${String(err)}`);
33203
33203
  continue;
33204
33204
  }
33205
33205
  if (!resolved) continue;
@@ -33214,7 +33214,7 @@ function resolvePluginTools(params) {
33214
33214
  for (const tool of list) {
33215
33215
  if (nameSet.has(tool.name) || existing.has(tool.name)) {
33216
33216
  const message = `plugin tool name conflict (${entry.pluginId}): ${tool.name}`;
33217
- log$2.error(message);
33217
+ log$3.error(message);
33218
33218
  registry.diagnostics.push({
33219
33219
  level: "error",
33220
33220
  pluginId: entry.pluginId,
@@ -33741,7 +33741,7 @@ function wrapToolWithAbortSignal(tool, abortSignal) {
33741
33741
 
33742
33742
  //#endregion
33743
33743
  //#region src/agents/pi-tools.before-tool-call.ts
33744
- const log$1 = createSubsystemLogger("agents/tools");
33744
+ const log$2 = createSubsystemLogger("agents/tools");
33745
33745
  const BEFORE_TOOL_CALL_WRAPPED = Symbol("beforeToolCallWrapped");
33746
33746
  const adjustedParamsByToolCallId = /* @__PURE__ */ new Map();
33747
33747
  const MAX_TRACKED_ADJUSTED_PARAMS = 1024;
@@ -33782,7 +33782,7 @@ async function runBeforeToolCallHook(args) {
33782
33782
  }
33783
33783
  } catch (err) {
33784
33784
  const toolCallId = args.toolCallId ? ` toolCallId=${args.toolCallId}` : "";
33785
- log$1.warn(`before_tool_call hook failed: tool=${toolName}${toolCallId} error=${String(err)}`);
33785
+ log$2.warn(`before_tool_call hook failed: tool=${toolName}${toolCallId} error=${String(err)}`);
33786
33786
  }
33787
33787
  return {
33788
33788
  blocked: false,
@@ -34744,9 +34744,9 @@ function createAnimaCodingTools(options) {
34744
34744
 
34745
34745
  //#endregion
34746
34746
  //#region src/agents/gemini-direct-runner.ts
34747
- const log = createSubsystemLogger("agent/gemini-direct");
34747
+ const log$1 = createSubsystemLogger("agent/gemini-direct");
34748
34748
  const DEFAULT_GEMINI_BASE_URL = "https://generativelanguage.googleapis.com/v1beta";
34749
- const MODEL_MAP = {
34749
+ const MODEL_MAP$1 = {
34750
34750
  gemini: "gemini-2.5-flash",
34751
34751
  "gemini-pro": "gemini-2.5-pro",
34752
34752
  "gemini-flash": "gemini-2.5-flash",
@@ -34759,9 +34759,9 @@ const MODEL_MAP = {
34759
34759
  "gemini-3.1-pro-preview": "gemini-3.1-pro-preview",
34760
34760
  default: "gemini-2.5-flash"
34761
34761
  };
34762
- const HISTORY_FILE_SUFFIX = ".gemini-history.json";
34763
- async function loadSessionHistory(sessionFile) {
34764
- const histPath = sessionFile + HISTORY_FILE_SUFFIX;
34762
+ const HISTORY_FILE_SUFFIX$1 = ".gemini-history.json";
34763
+ async function loadSessionHistory$1(sessionFile) {
34764
+ const histPath = sessionFile + HISTORY_FILE_SUFFIX$1;
34765
34765
  try {
34766
34766
  const raw = await fs$1.readFile(histPath, "utf8");
34767
34767
  return JSON.parse(raw);
@@ -34769,18 +34769,18 @@ async function loadSessionHistory(sessionFile) {
34769
34769
  return null;
34770
34770
  }
34771
34771
  }
34772
- async function saveSessionHistory(sessionFile, history) {
34773
- const histPath = sessionFile + HISTORY_FILE_SUFFIX;
34772
+ async function saveSessionHistory$1(sessionFile, history) {
34773
+ const histPath = sessionFile + HISTORY_FILE_SUFFIX$1;
34774
34774
  try {
34775
34775
  await fs$1.mkdir(path.dirname(histPath), { recursive: true });
34776
34776
  await fs$1.writeFile(histPath, JSON.stringify(history, null, 2), "utf8");
34777
34777
  } catch (err) {
34778
- log.warn("failed to save session history", { error: String(err) });
34778
+ log$1.warn("failed to save session history", { error: String(err) });
34779
34779
  }
34780
34780
  }
34781
- function resolveModel(model) {
34781
+ function resolveModel$1(model) {
34782
34782
  const key = (model ?? "default").trim().toLowerCase() || "default";
34783
- return MODEL_MAP[key] ?? key;
34783
+ return MODEL_MAP$1[key] ?? key;
34784
34784
  }
34785
34785
  function buildModelPath(model) {
34786
34786
  return model.startsWith("models/") ? model : `models/${model}`;
@@ -34793,9 +34793,9 @@ function buildModelPath(model) {
34793
34793
  */
34794
34794
  async function runGeminiDirectAgent(params) {
34795
34795
  const started = Date.now();
34796
- const resolvedModel = resolveModel(params.model);
34796
+ const resolvedModel = resolveModel$1(params.model);
34797
34797
  const modelPath = buildModelPath(resolvedModel);
34798
- log.info(`direct api exec: model=${resolvedModel} promptChars=${params.prompt.length}`);
34798
+ log$1.info(`direct api exec: model=${resolvedModel} promptChars=${params.prompt.length}`);
34799
34799
  const workspaceDir = resolveRunWorkspaceDir({
34800
34800
  workspaceDir: params.workspaceDir,
34801
34801
  sessionKey: params.sessionKey,
@@ -34821,7 +34821,7 @@ async function runGeminiDirectAgent(params) {
34821
34821
  sessionId: params.sessionId,
34822
34822
  warn: makeBootstrapWarn({
34823
34823
  sessionLabel: params.sessionKey ?? params.sessionId,
34824
- warn: (msg) => log.warn(msg)
34824
+ warn: (msg) => log$1.warn(msg)
34825
34825
  })
34826
34826
  });
34827
34827
  const { defaultAgentId, sessionAgentId } = resolveSessionAgentIds({
@@ -34849,7 +34849,7 @@ async function runGeminiDirectAgent(params) {
34849
34849
  modelDisplay: `google/${resolvedModel}`,
34850
34850
  agentId: sessionAgentId
34851
34851
  });
34852
- let history = await loadSessionHistory(params.sessionFile);
34852
+ let history = await loadSessionHistory$1(params.sessionFile);
34853
34853
  if (!history) history = {
34854
34854
  sessionId: params.sessionId,
34855
34855
  contents: [],
@@ -34885,7 +34885,7 @@ async function runGeminiDirectAgent(params) {
34885
34885
  method: "POST",
34886
34886
  headers: {
34887
34887
  "Content-Type": "application/json",
34888
- "User-Agent": `anima/5.0.1 (gemini-direct-runner; ${os.platform()})`
34888
+ "User-Agent": `anima/7.0.0 (gemini-direct-runner; ${os.platform()})`
34889
34889
  },
34890
34890
  body: JSON.stringify(requestBody),
34891
34891
  signal: controller.signal
@@ -34898,7 +34898,7 @@ async function runGeminiDirectAgent(params) {
34898
34898
  const rateHint = isRateLimit ? " — rate limit hit, will retry next heartbeat." : "";
34899
34899
  const authHint = isAuth ? " — API key may be invalid. Check GEMINI_API_KEY environment variable." : "";
34900
34900
  console.error("GEMINI API ERROR BODY:", body);
34901
- log.error(`gemini api error: HTTP ${response.status}${authHint}${rateHint}`, {
34901
+ log$1.error(`gemini api error: HTTP ${response.status}${authHint}${rateHint}`, {
34902
34902
  status: response.status,
34903
34903
  body: body.slice(0, 500)
34904
34904
  });
@@ -35001,7 +35001,7 @@ async function runGeminiDirectAgent(params) {
35001
35001
  const isAbort = err instanceof Error && err.name === "AbortError";
35002
35002
  const errorKind = isAbort ? "timeout" : "unknown";
35003
35003
  const errorMsg = isAbort ? `Request timed out after ${params.timeoutMs}ms` : String(err);
35004
- log.error(`gemini api error: ${errorMsg}`, { error: String(err) });
35004
+ log$1.error(`gemini api error: ${errorMsg}`, { error: String(err) });
35005
35005
  return {
35006
35006
  status: isAbort ? "timeout" : "failed",
35007
35007
  meta: {
@@ -35015,9 +35015,9 @@ async function runGeminiDirectAgent(params) {
35015
35015
  }
35016
35016
  }
35017
35017
  history.updatedAt = Date.now();
35018
- await saveSessionHistory(params.sessionFile, history);
35018
+ await saveSessionHistory$1(params.sessionFile, history);
35019
35019
  const durationMs = Date.now() - started;
35020
- log.info(`gemini api complete: ${durationMs}ms`, {
35020
+ log$1.info(`gemini api complete: ${durationMs}ms`, {
35021
35021
  inputTokens: totalInputTokens,
35022
35022
  outputTokens: totalOutputTokens
35023
35023
  });
@@ -35039,6 +35039,338 @@ async function runGeminiDirectAgent(params) {
35039
35039
  };
35040
35040
  }
35041
35041
 
35042
+ //#endregion
35043
+ //#region src/agents/openai-direct-runner.ts
35044
+ const log = createSubsystemLogger("agent/openai-direct");
35045
+ const DEFAULT_OPENAI_BASE_URL = "https://api.openai.com/v1";
35046
+ const MODEL_MAP = {
35047
+ "gpt-5.4": "gpt-5.4",
35048
+ "gpt-5.2": "gpt-5.2",
35049
+ "gpt-5": "gpt-5.4",
35050
+ "gpt-4.1": "gpt-4.1",
35051
+ "gpt-4.1-mini": "gpt-4.1-mini",
35052
+ "gpt-4.1-nano": "gpt-4.1-nano",
35053
+ "gpt-4o": "gpt-4o",
35054
+ "gpt-4o-mini": "gpt-4o-mini",
35055
+ o3: "o3",
35056
+ "o3-mini": "o3-mini",
35057
+ "o4-mini": "o4-mini",
35058
+ default: "gpt-4.1"
35059
+ };
35060
+ const HISTORY_FILE_SUFFIX = ".openai-history.json";
35061
+ async function loadSessionHistory(sessionFile) {
35062
+ const histPath = sessionFile + HISTORY_FILE_SUFFIX;
35063
+ try {
35064
+ const raw = await fs$1.readFile(histPath, "utf8");
35065
+ return JSON.parse(raw);
35066
+ } catch {
35067
+ return null;
35068
+ }
35069
+ }
35070
+ async function saveSessionHistory(sessionFile, history) {
35071
+ const histPath = sessionFile + HISTORY_FILE_SUFFIX;
35072
+ try {
35073
+ await fs$1.mkdir(path.dirname(histPath), { recursive: true });
35074
+ await fs$1.writeFile(histPath, JSON.stringify(history, null, 2), "utf8");
35075
+ } catch (err) {
35076
+ log.warn("failed to save session history", { error: String(err) });
35077
+ }
35078
+ }
35079
+ function resolveModel(model) {
35080
+ const key = (model ?? "default").trim().toLowerCase() || "default";
35081
+ return MODEL_MAP[key] ?? key;
35082
+ }
35083
+ /**
35084
+ * Clean a JSON Schema for OpenAI's function calling.
35085
+ * OpenAI is stricter than most — no unsupported keywords.
35086
+ */
35087
+ function cleanSchemaForOpenAI(schema) {
35088
+ const cleaned = {};
35089
+ for (const [key, value] of Object.entries(schema)) {
35090
+ if (key === "$schema" || key === "additionalProperties" || key === "$id") continue;
35091
+ if (key === "properties" && typeof value === "object" && value !== null) {
35092
+ const props = {};
35093
+ for (const [propKey, propValue] of Object.entries(value)) if (typeof propValue === "object" && propValue !== null) props[propKey] = cleanSchemaForOpenAI(propValue);
35094
+ else props[propKey] = propValue;
35095
+ cleaned[key] = props;
35096
+ } else if (key === "items" && typeof value === "object" && value !== null) cleaned[key] = cleanSchemaForOpenAI(value);
35097
+ else cleaned[key] = value;
35098
+ }
35099
+ return cleaned;
35100
+ }
35101
+ /**
35102
+ * Run an agent turn directly against api.openai.com.
35103
+ *
35104
+ * Maintains multi-turn conversation history per session file.
35105
+ * Falls back to single-turn if history is unavailable.
35106
+ */
35107
+ async function runOpenAIDirectAgent(params) {
35108
+ const started = Date.now();
35109
+ const resolvedModel = resolveModel(params.model);
35110
+ log.info(`direct api exec: model=${resolvedModel} promptChars=${params.prompt.length}`);
35111
+ const workspaceDir = resolveRunWorkspaceDir({
35112
+ workspaceDir: params.workspaceDir,
35113
+ sessionKey: params.sessionKey,
35114
+ agentId: params.agentId,
35115
+ config: params.config
35116
+ }).workspaceDir;
35117
+ const executableTools = createAnimaCodingTools({
35118
+ config: params.config,
35119
+ workspaceDir,
35120
+ sessionKey: params.sessionKey,
35121
+ modelProvider: "openai",
35122
+ modelId: resolvedModel
35123
+ });
35124
+ const openaiTools = executableTools.map((t) => ({
35125
+ type: "function",
35126
+ function: {
35127
+ name: t.name,
35128
+ description: t.description,
35129
+ parameters: cleanSchemaForOpenAI(t.parameters ?? {
35130
+ type: "object",
35131
+ properties: {}
35132
+ })
35133
+ }
35134
+ }));
35135
+ const { contextFiles } = await resolveBootstrapContextForRun({
35136
+ workspaceDir,
35137
+ config: params.config,
35138
+ sessionKey: params.sessionKey,
35139
+ sessionId: params.sessionId,
35140
+ warn: makeBootstrapWarn({
35141
+ sessionLabel: params.sessionKey ?? params.sessionId,
35142
+ warn: (msg) => log.warn(msg)
35143
+ })
35144
+ });
35145
+ const { defaultAgentId, sessionAgentId } = resolveSessionAgentIds({
35146
+ sessionKey: params.sessionKey,
35147
+ config: params.config
35148
+ });
35149
+ const heartbeatPrompt = sessionAgentId === defaultAgentId ? resolveHeartbeatPrompt(params.config?.agents?.defaults?.heartbeat?.prompt) : void 0;
35150
+ const docsPath = await resolveAnimaDocsPath({
35151
+ workspaceDir,
35152
+ argv1: process.argv[1],
35153
+ cwd: process.cwd(),
35154
+ moduleUrl: import.meta.url
35155
+ });
35156
+ const extraSystemPrompt = appendRunnerCapabilityPrompt(params.extraSystemPrompt, "local-tools");
35157
+ const systemPrompt = buildSystemPrompt({
35158
+ workspaceDir,
35159
+ config: params.config,
35160
+ defaultThinkLevel: params.thinkLevel,
35161
+ extraSystemPrompt,
35162
+ ownerNumbers: params.ownerNumbers,
35163
+ heartbeatPrompt,
35164
+ docsPath: docsPath ?? void 0,
35165
+ tools: executableTools,
35166
+ contextFiles,
35167
+ modelDisplay: `openai/${resolvedModel}`,
35168
+ agentId: sessionAgentId
35169
+ });
35170
+ let history = await loadSessionHistory(params.sessionFile);
35171
+ if (!history) history = {
35172
+ sessionId: params.sessionId,
35173
+ messages: [{
35174
+ role: "system",
35175
+ content: systemPrompt
35176
+ }],
35177
+ createdAt: started,
35178
+ updatedAt: started
35179
+ };
35180
+ else if (history.messages.length > 0 && history.messages[0].role === "system") history.messages[0].content = systemPrompt;
35181
+ history.messages.push({
35182
+ role: "user",
35183
+ content: params.prompt
35184
+ });
35185
+ let finalAssistantText = "";
35186
+ let totalInputTokens = 0;
35187
+ let totalOutputTokens = 0;
35188
+ let isDone = false;
35189
+ let loopCount = 0;
35190
+ const maxLoops = 20;
35191
+ const baseUrl = params.config?.models?.providers?.openai?.baseUrl?.trim() || DEFAULT_OPENAI_BASE_URL;
35192
+ while (!isDone && loopCount < maxLoops) {
35193
+ loopCount++;
35194
+ const requestBody = {
35195
+ model: resolvedModel,
35196
+ messages: history.messages,
35197
+ max_tokens: 8192,
35198
+ temperature: 1,
35199
+ stream: true
35200
+ };
35201
+ if (openaiTools.length > 0) {
35202
+ requestBody.tools = openaiTools;
35203
+ requestBody.tool_choice = "auto";
35204
+ }
35205
+ try {
35206
+ const controller = new AbortController();
35207
+ const timeoutHandle = setTimeout(() => controller.abort(), params.timeoutMs);
35208
+ const url = `${baseUrl}/chat/completions`;
35209
+ const response = await fetch(url, {
35210
+ method: "POST",
35211
+ headers: {
35212
+ "Content-Type": "application/json",
35213
+ Authorization: `Bearer ${params.apiKey}`,
35214
+ "User-Agent": `anima/7.0.0 (openai-direct-runner; ${os.platform()})`
35215
+ },
35216
+ body: JSON.stringify(requestBody),
35217
+ signal: controller.signal
35218
+ });
35219
+ clearTimeout(timeoutHandle);
35220
+ if (!response.ok) {
35221
+ const body = await response.text().catch(() => "");
35222
+ const isAuth = response.status === 401 || response.status === 403;
35223
+ const isRateLimit = response.status === 429;
35224
+ const rateHint = isRateLimit ? " — rate limit hit, will retry next heartbeat." : "";
35225
+ const authHint = isAuth ? " — API key may be invalid. Check OPENAI_API_KEY environment variable." : "";
35226
+ log.error(`openai api error: HTTP ${response.status}${authHint}${rateHint}`, {
35227
+ status: response.status,
35228
+ body: body.slice(0, 500)
35229
+ });
35230
+ return {
35231
+ status: "failed",
35232
+ meta: {
35233
+ durationMs: Date.now() - started,
35234
+ error: {
35235
+ message: `HTTP ${response.status}: ${body.slice(0, 200)}${authHint}${rateHint}`,
35236
+ kind: isAuth ? "auth" : isRateLimit ? "rate_limit" : "unknown"
35237
+ }
35238
+ }
35239
+ };
35240
+ }
35241
+ if (!response.body) throw new Error("No response body received from OpenAI API");
35242
+ const bodyStream = Readable.fromWeb(response.body);
35243
+ let buffer = "";
35244
+ let chunkAssistantText = "";
35245
+ const toolCalls = /* @__PURE__ */ new Map();
35246
+ for await (const chunk of bodyStream) {
35247
+ buffer += chunk.toString("utf8");
35248
+ const lines = buffer.split("\n");
35249
+ buffer = lines.pop() ?? "";
35250
+ for (const line of lines) {
35251
+ const trimmed = line.trim();
35252
+ if (!trimmed || !trimmed.startsWith("data: ")) continue;
35253
+ const dataStr = trimmed.slice(6);
35254
+ if (dataStr === "[DONE]") continue;
35255
+ try {
35256
+ const parsed = JSON.parse(dataStr);
35257
+ const delta = parsed.choices?.[0]?.delta;
35258
+ if (delta) {
35259
+ if (typeof delta.content === "string") {
35260
+ chunkAssistantText += delta.content;
35261
+ finalAssistantText += delta.content;
35262
+ if (params.onPartialReply) await params.onPartialReply({ text: finalAssistantText });
35263
+ }
35264
+ if (delta.tool_calls) for (const tc of delta.tool_calls) {
35265
+ const idx = tc.index ?? 0;
35266
+ const existing = toolCalls.get(idx);
35267
+ if (tc.id) toolCalls.set(idx, {
35268
+ id: tc.id,
35269
+ name: tc.function?.name ?? existing?.name ?? "",
35270
+ arguments: (existing?.arguments ?? "") + (tc.function?.arguments ?? "")
35271
+ });
35272
+ else if (existing) {
35273
+ existing.name = existing.name || (tc.function?.name ?? "");
35274
+ existing.arguments += tc.function?.arguments ?? "";
35275
+ }
35276
+ }
35277
+ }
35278
+ if (parsed.usage) {
35279
+ totalInputTokens = Math.max(totalInputTokens, parsed.usage.prompt_tokens ?? 0);
35280
+ totalOutputTokens += parsed.usage.completion_tokens ?? 0;
35281
+ }
35282
+ } catch {}
35283
+ }
35284
+ }
35285
+ if (toolCalls.size > 0) {
35286
+ const assistantToolCalls = Array.from(toolCalls.values()).map((tc) => ({
35287
+ id: tc.id,
35288
+ type: "function",
35289
+ function: {
35290
+ name: tc.name,
35291
+ arguments: tc.arguments
35292
+ }
35293
+ }));
35294
+ const assistantMsg = {
35295
+ role: "assistant",
35296
+ content: chunkAssistantText || null,
35297
+ tool_calls: assistantToolCalls
35298
+ };
35299
+ history.messages.push(assistantMsg);
35300
+ for (const tc of assistantToolCalls) {
35301
+ const tool = executableTools.find((t) => t.name === tc.function.name);
35302
+ let resultContent;
35303
+ if (!tool) resultContent = JSON.stringify({ error: "Tool not found or unauthorized" });
35304
+ else if (!tool.execute) resultContent = JSON.stringify({ error: "Tool execution not implemented" });
35305
+ else try {
35306
+ const callId = crypto.randomUUID();
35307
+ let args = {};
35308
+ try {
35309
+ args = JSON.parse(tc.function.arguments);
35310
+ } catch {
35311
+ args = {};
35312
+ }
35313
+ const result = await tool.execute(callId, args);
35314
+ resultContent = typeof result === "string" ? result : JSON.stringify(result);
35315
+ } catch (err) {
35316
+ resultContent = JSON.stringify({ error: String(err) });
35317
+ }
35318
+ history.messages.push({
35319
+ role: "tool",
35320
+ content: resultContent,
35321
+ tool_call_id: tc.id
35322
+ });
35323
+ }
35324
+ } else {
35325
+ if (chunkAssistantText) history.messages.push({
35326
+ role: "assistant",
35327
+ content: chunkAssistantText
35328
+ });
35329
+ isDone = true;
35330
+ }
35331
+ } catch (err) {
35332
+ const isAbort = err instanceof Error && err.name === "AbortError";
35333
+ const errorKind = isAbort ? "timeout" : "unknown";
35334
+ const errorMsg = isAbort ? `Request timed out after ${params.timeoutMs}ms` : String(err);
35335
+ log.error(`openai api error: ${errorMsg}`, { error: String(err) });
35336
+ return {
35337
+ status: isAbort ? "timeout" : "failed",
35338
+ meta: {
35339
+ durationMs: Date.now() - started,
35340
+ error: {
35341
+ message: errorMsg,
35342
+ kind: errorKind
35343
+ }
35344
+ }
35345
+ };
35346
+ }
35347
+ }
35348
+ history.updatedAt = Date.now();
35349
+ await saveSessionHistory(params.sessionFile, history);
35350
+ const durationMs = Date.now() - started;
35351
+ log.info(`openai api complete: ${durationMs}ms`, {
35352
+ inputTokens: totalInputTokens,
35353
+ outputTokens: totalOutputTokens,
35354
+ model: resolvedModel
35355
+ });
35356
+ return {
35357
+ status: "completed",
35358
+ output: finalAssistantText,
35359
+ payloads: finalAssistantText ? [{ text: finalAssistantText }] : [],
35360
+ meta: {
35361
+ durationMs,
35362
+ agentMeta: {
35363
+ model: resolvedModel,
35364
+ provider: "openai",
35365
+ usage: {
35366
+ input: totalInputTokens,
35367
+ output: totalOutputTokens
35368
+ }
35369
+ }
35370
+ }
35371
+ };
35372
+ }
35373
+
35042
35374
  //#endregion
35043
35375
  //#region src/agents/noxsoft-runner.ts
35044
35376
  function normalizeEmbeddedProvider(provider) {
@@ -35064,6 +35396,7 @@ async function emitAgentEvent(params, stream, data) {
35064
35396
  function resolveDirectAuthProvider(provider) {
35065
35397
  if (provider === "anthropic" || provider === "claude") return "anthropic";
35066
35398
  if (provider === "google" || provider === "gemini") return "google";
35399
+ if (provider === "openai") return "openai";
35067
35400
  return null;
35068
35401
  }
35069
35402
  function resolveProfileFailureReason(result) {
@@ -35173,8 +35506,7 @@ async function runDirectWithProfileFallback(params) {
35173
35506
  }
35174
35507
  };
35175
35508
  attemptedAuthSources.add(authSourceKey);
35176
- const result = params.directProvider === "anthropic" ? await runAnthropicDirectAgent({
35177
- token: auth.apiKey ?? "",
35509
+ const directRunParams = {
35178
35510
  sessionId: params.sessionId,
35179
35511
  sessionKey: params.sessionKey,
35180
35512
  agentId: params.agentId,
@@ -35190,23 +35522,16 @@ async function runDirectWithProfileFallback(params) {
35190
35522
  ownerNumbers: params.ownerNumbers,
35191
35523
  onPartialReply: params.emitPartial,
35192
35524
  onAssistantMessageStart: params.onAssistantMessageStart
35525
+ };
35526
+ const result = params.directProvider === "anthropic" ? await runAnthropicDirectAgent({
35527
+ ...directRunParams,
35528
+ token: auth.apiKey ?? ""
35529
+ }) : params.directProvider === "openai" ? await runOpenAIDirectAgent({
35530
+ ...directRunParams,
35531
+ apiKey: auth.apiKey ?? ""
35193
35532
  }) : await runGeminiDirectAgent({
35194
- apiKey: auth.apiKey ?? "",
35195
- sessionId: params.sessionId,
35196
- sessionKey: params.sessionKey,
35197
- agentId: params.agentId,
35198
- sessionFile: params.sessionFile,
35199
- workspaceDir: params.workspaceDir,
35200
- config: params.config,
35201
- prompt: params.prompt,
35202
- model: params.model,
35203
- thinkLevel: params.thinkLevel,
35204
- timeoutMs: params.timeoutMs,
35205
- runId: params.runId,
35206
- extraSystemPrompt: params.extraSystemPrompt,
35207
- ownerNumbers: params.ownerNumbers,
35208
- onPartialReply: params.emitPartial,
35209
- onAssistantMessageStart: params.onAssistantMessageStart
35533
+ ...directRunParams,
35534
+ apiKey: auth.apiKey ?? ""
35210
35535
  });
35211
35536
  if (result.status === "completed") {
35212
35537
  if (auth.profileId) {
@@ -35250,7 +35575,7 @@ async function resolveDirectStrategy(provider, config, agentDir) {
35250
35575
  if (auth.apiKey) {
35251
35576
  if (directProvider === "anthropic" && auth.apiKey.startsWith("sk-ant-oat01-")) return null;
35252
35577
  return {
35253
- kind: directProvider === "google" ? "gemini-direct" : "anthropic-direct",
35578
+ kind: directProvider === "google" ? "gemini-direct" : directProvider === "openai" ? "openai-direct" : "anthropic-direct",
35254
35579
  provider
35255
35580
  };
35256
35581
  }
@@ -35384,6 +35709,53 @@ async function runNoxSoftEmbeddedAgent(params) {
35384
35709
  throw err;
35385
35710
  }
35386
35711
  }
35712
+ if (strategy.kind === "openai-direct") {
35713
+ await emitAgentEvent(params, "lifecycle", {
35714
+ phase: "start",
35715
+ startedAt
35716
+ });
35717
+ try {
35718
+ const result = normalizeRunnerResult({
35719
+ result: await runDirectWithProfileFallback({
35720
+ ...params,
35721
+ directProvider: "openai",
35722
+ timeoutMs,
35723
+ runId,
35724
+ emitPartial
35725
+ }),
35726
+ provider: normalizedRequestedRef?.provider ?? provider,
35727
+ model: normalizedRequestedRef?.model,
35728
+ sessionId: params.sessionId
35729
+ });
35730
+ const failure = coerceResultFailure({
35731
+ result,
35732
+ provider: result.meta.agentMeta?.provider ?? provider,
35733
+ model: result.meta.agentMeta?.model
35734
+ });
35735
+ if (failure) {
35736
+ await emitAgentEvent(params, "lifecycle", {
35737
+ phase: "error",
35738
+ startedAt,
35739
+ endedAt: Date.now(),
35740
+ error: failure.message,
35741
+ status: result.status
35742
+ });
35743
+ throw failure;
35744
+ }
35745
+ await emitAgentEvent(params, "lifecycle", {
35746
+ phase: "end",
35747
+ durationMs: Date.now() - startedAt,
35748
+ status: result.status
35749
+ });
35750
+ return result;
35751
+ } catch (err) {
35752
+ await emitAgentEvent(params, "lifecycle", {
35753
+ phase: "error",
35754
+ error: String(err instanceof Error ? err.message : err)
35755
+ });
35756
+ throw err;
35757
+ }
35758
+ }
35387
35759
  await emitAgentEvent(params, "lifecycle", {
35388
35760
  phase: "start",
35389
35761
  startedAt