@theokit/sdk 5.14.0 → 5.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/dist/{agent-Dfw3VsIX.d.ts → agent-B6C9i_qu.d.ts} +23 -213
- package/dist/{agent-DExqjqYy.d.cts → agent-B6FQad6P.d.cts} +23 -213
- package/dist/{agent-T34LCGQM.js → agent-DRDGUU6T.js} +18 -17
- package/dist/{agent-T34LCGQM.js.map → agent-DRDGUU6T.js.map} +1 -1
- package/dist/{agent-TL4K7BTG.cjs → agent-VI2HITPT.cjs} +19 -18
- package/dist/{agent-TL4K7BTG.cjs.map → agent-VI2HITPT.cjs.map} +1 -1
- package/dist/agent.d.ts +2 -3
- package/dist/{batch-EP3FCL6D.js → batch-N2XDYZED.js} +4 -4
- package/dist/{batch-EP3FCL6D.js.map → batch-N2XDYZED.js.map} +1 -1
- package/dist/{batch-IZ5EDKJ5.cjs → batch-VFR2MAUE.cjs} +7 -7
- package/dist/{batch-IZ5EDKJ5.cjs.map → batch-VFR2MAUE.cjs.map} +1 -1
- package/dist/{chunk-3ONIVO2I.js → chunk-23SS4ID4.js} +3 -3
- package/dist/{chunk-3ONIVO2I.js.map → chunk-23SS4ID4.js.map} +1 -1
- package/dist/{chunk-2C24NSNV.js → chunk-3BBTHFGJ.js} +3 -3
- package/dist/{chunk-2C24NSNV.js.map → chunk-3BBTHFGJ.js.map} +1 -1
- package/dist/{chunk-NP362THY.cjs → chunk-3F53FLQ7.cjs} +5 -7
- package/dist/chunk-3F53FLQ7.cjs.map +1 -0
- package/dist/{chunk-SXH37C7X.cjs → chunk-55LLQFHW.cjs} +6 -6
- package/dist/{chunk-SXH37C7X.cjs.map → chunk-55LLQFHW.cjs.map} +1 -1
- package/dist/{chunk-GARVAUCU.js → chunk-5M5GQYBM.js} +534 -236
- package/dist/chunk-5M5GQYBM.js.map +1 -0
- package/dist/{chunk-2WY2OFSC.cjs → chunk-64ECM3XM.cjs} +616 -318
- package/dist/chunk-64ECM3XM.cjs.map +1 -0
- package/dist/{chunk-ZJAYFSVI.js → chunk-7ACS6P5Z.js} +5 -7
- package/dist/chunk-7ACS6P5Z.js.map +1 -0
- package/dist/{chunk-NAVUTK6X.js → chunk-ARC2V7NY.js} +3 -3
- package/dist/{chunk-NAVUTK6X.js.map → chunk-ARC2V7NY.js.map} +1 -1
- package/dist/{chunk-WDVG5R2Q.cjs → chunk-AUH2EVWY.cjs} +4 -3
- package/dist/chunk-AUH2EVWY.cjs.map +1 -0
- package/dist/chunk-BNEUB52I.cjs +55 -0
- package/dist/chunk-BNEUB52I.cjs.map +1 -0
- package/dist/chunk-BPL5CVZ5.js +53 -0
- package/dist/chunk-BPL5CVZ5.js.map +1 -0
- package/dist/{chunk-NVQSBRG6.js → chunk-CBBT42VX.js} +3 -3
- package/dist/{chunk-NVQSBRG6.js.map → chunk-CBBT42VX.js.map} +1 -1
- package/dist/chunk-CHKV2L2Y.cjs +416 -0
- package/dist/chunk-CHKV2L2Y.cjs.map +1 -0
- package/dist/{chunk-SNVYOX46.cjs → chunk-DJKGDLYZ.cjs} +91 -61
- package/dist/chunk-DJKGDLYZ.cjs.map +1 -0
- package/dist/{chunk-354F3OF5.js → chunk-FGGVSHDW.js} +3 -3
- package/dist/{chunk-354F3OF5.js.map → chunk-FGGVSHDW.js.map} +1 -1
- package/dist/{chunk-6OCJWGVD.cjs → chunk-FTXY4D44.cjs} +4 -4
- package/dist/{chunk-6OCJWGVD.cjs.map → chunk-FTXY4D44.cjs.map} +1 -1
- package/dist/chunk-INVEGVGO.js +405 -0
- package/dist/chunk-INVEGVGO.js.map +1 -0
- package/dist/{chunk-ZOL3L4EH.js → chunk-IOBHFP2E.js} +49 -19
- package/dist/chunk-IOBHFP2E.js.map +1 -0
- package/dist/{chunk-BZK5QL3N.cjs → chunk-KMFBNKCT.cjs} +4 -4
- package/dist/{chunk-BZK5QL3N.cjs.map → chunk-KMFBNKCT.cjs.map} +1 -1
- package/dist/{chunk-DF77RBF4.js → chunk-LCCT5ZXJ.js} +6 -6
- package/dist/{chunk-DF77RBF4.js.map → chunk-LCCT5ZXJ.js.map} +1 -1
- package/dist/{chunk-G7XBVM3T.cjs → chunk-MHUOVS5I.cjs} +5 -5
- package/dist/{chunk-G7XBVM3T.cjs.map → chunk-MHUOVS5I.cjs.map} +1 -1
- package/dist/{chunk-CWQPQTUZ.cjs → chunk-NEH3BPFD.cjs} +15 -15
- package/dist/{chunk-CWQPQTUZ.cjs.map → chunk-NEH3BPFD.cjs.map} +1 -1
- package/dist/{chunk-5AR6O7GW.js → chunk-NK5EOTDY.js} +3 -3
- package/dist/{chunk-5AR6O7GW.js.map → chunk-NK5EOTDY.js.map} +1 -1
- package/dist/{chunk-4TEGFMSP.cjs → chunk-P7QYG4RZ.cjs} +23 -15
- package/dist/chunk-P7QYG4RZ.cjs.map +1 -0
- package/dist/chunk-PPU2D4FZ.js +19 -0
- package/dist/chunk-PPU2D4FZ.js.map +1 -0
- package/dist/{chunk-AB4OPJLD.js → chunk-RGVMJU57.js} +3 -3
- package/dist/{chunk-AB4OPJLD.js.map → chunk-RGVMJU57.js.map} +1 -1
- package/dist/{chunk-4KBI37F3.cjs → chunk-RTDVSHJR.cjs} +5 -5
- package/dist/{chunk-4KBI37F3.cjs.map → chunk-RTDVSHJR.cjs.map} +1 -1
- package/dist/{chunk-CJN5CEI3.js → chunk-RZL2W4C3.js} +23 -15
- package/dist/chunk-RZL2W4C3.js.map +1 -0
- package/dist/chunk-SPEN7RJU.cjs +18 -0
- package/dist/{chunk-R5UQL2R5.cjs.map → chunk-SPEN7RJU.cjs.map} +1 -1
- package/dist/{chunk-ZF2LDKQQ.cjs → chunk-U3DW3WDE.cjs} +9 -8
- package/dist/chunk-U3DW3WDE.cjs.map +1 -0
- package/dist/{chunk-LXG6VL6R.cjs → chunk-U7PRI3XM.cjs} +3 -3
- package/dist/{chunk-LXG6VL6R.cjs.map → chunk-U7PRI3XM.cjs.map} +1 -1
- package/dist/{chunk-H7G65PNI.js → chunk-VCQ37TC5.js} +3 -3
- package/dist/{chunk-H7G65PNI.js.map → chunk-VCQ37TC5.js.map} +1 -1
- package/dist/{chunk-SDZ4XDWS.cjs → chunk-VWYFGE27.cjs} +9 -9
- package/dist/{chunk-SDZ4XDWS.cjs.map → chunk-VWYFGE27.cjs.map} +1 -1
- package/dist/{chunk-RN3XDZGS.js → chunk-WM646HEN.js} +4 -3
- package/dist/chunk-WM646HEN.js.map +1 -0
- package/dist/chunk-X7CE7Y5W.js +305 -0
- package/dist/chunk-X7CE7Y5W.js.map +1 -0
- package/dist/{chunk-CGH4BCIY.cjs → chunk-XE3CAY6Z.cjs} +5 -5
- package/dist/{chunk-CGH4BCIY.cjs.map → chunk-XE3CAY6Z.cjs.map} +1 -1
- package/dist/chunk-XOU3CL7S.cjs +312 -0
- package/dist/chunk-XOU3CL7S.cjs.map +1 -0
- package/dist/{chunk-ULEK4OM4.js → chunk-YKNBTHMD.js} +3 -3
- package/dist/{chunk-ULEK4OM4.js.map → chunk-YKNBTHMD.js.map} +1 -1
- package/dist/{compact-session-D2MQDB6G.cjs → compact-session-NX7HUNTB.cjs} +16 -16
- package/dist/{compact-session-D2MQDB6G.cjs.map → compact-session-NX7HUNTB.cjs.map} +1 -1
- package/dist/{compact-session-N2PPHQO6.js → compact-session-Q5IGNFPW.js} +7 -7
- package/dist/{compact-session-N2PPHQO6.js.map → compact-session-Q5IGNFPW.js.map} +1 -1
- package/dist/{cron-CK2v0VWA.d.cts → cron-Bh3aWgQ2.d.cts} +2 -2
- package/dist/{cron-BubDpFJG.d.ts → cron-CCDxeeFZ.d.ts} +2 -2
- package/dist/cron.cjs +18 -17
- package/dist/cron.d.cts +4 -3
- package/dist/cron.d.ts +4 -3
- package/dist/cron.js +17 -16
- package/dist/eval.cjs +17 -16
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +16 -15
- package/dist/eval.js.map +1 -1
- package/dist/fs-session-store-CYNTEPJZ.cjs +20 -0
- package/dist/{fs-session-store-S2AXVJIX.cjs.map → fs-session-store-CYNTEPJZ.cjs.map} +1 -1
- package/dist/fs-session-store-MYQEVUFL.js +11 -0
- package/dist/{fs-session-store-6ZCCJX3K.js.map → fs-session-store-MYQEVUFL.js.map} +1 -1
- package/dist/{index-manager-HO456AVW.cjs → index-manager-2KH75BRW.cjs} +7 -7
- package/dist/{index-manager-HO456AVW.cjs.map → index-manager-2KH75BRW.cjs.map} +1 -1
- package/dist/{index-manager-QDH56FER.js → index-manager-NF2WRLOU.js} +6 -6
- package/dist/{index-manager-QDH56FER.js.map → index-manager-NF2WRLOU.js.map} +1 -1
- package/dist/index.cjs +66 -262
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -46
- package/dist/index.d.ts +10 -46
- package/dist/index.js +27 -227
- package/dist/index.js.map +1 -1
- package/dist/{inject-session-J26SHHIO.js → inject-session-4ROYLZHY.js} +3 -3
- package/dist/{inject-session-J26SHHIO.js.map → inject-session-4ROYLZHY.js.map} +1 -1
- package/dist/{inject-session-3ICZIJ2N.cjs → inject-session-AWKDCGHV.cjs} +4 -4
- package/dist/{inject-session-3ICZIJ2N.cjs.map → inject-session-AWKDCGHV.cjs.map} +1 -1
- package/dist/internal/agent-loop/doom-loop-tracker.d.ts +3 -0
- package/dist/internal/agent-loop/types.d.ts +6 -0
- package/dist/internal/error-mappers/anthropic.d.ts +3 -0
- package/dist/internal/error-mappers/openai-compatible.d.ts +2 -3
- package/dist/internal/local-agent/local-agent-dispatch.d.ts +3 -1
- package/dist/internal/local-agent/send-queue.d.ts +31 -0
- package/dist/internal/mcp/client.d.ts +2 -0
- package/dist/internal/mcp/oauth-bearer.d.ts +2 -0
- package/dist/internal/memory/adapters/index.cjs +3 -3
- package/dist/internal/memory/adapters/index.js +2 -2
- package/dist/internal/memory/dreaming/phases.d.ts +15 -0
- package/dist/internal/memory/dreaming/run.d.ts +29 -0
- package/dist/internal/memory/sdk-memory-peer-loader.d.ts +2 -0
- package/dist/internal/memory/storage/index.cjs +51 -35
- package/dist/internal/memory/storage/index.d.cts +2 -0
- package/dist/internal/memory/storage/index.d.ts +2 -0
- package/dist/internal/memory/storage/index.js +4 -4
- package/dist/internal/persistence/cwd-mutex.d.cts +4 -2
- package/dist/internal/persistence/cwd-mutex.d.ts +4 -2
- package/dist/internal/persistence/index.cjs +4 -4
- package/dist/internal/persistence/index.js +2 -2
- package/dist/internal/persistence/sqlite-session-store.d.cts +25 -0
- package/dist/internal/persistence/sqlite-session-store.d.ts +25 -0
- package/dist/internal/providers/registry.d.ts +5 -1
- package/dist/mcp-auth.cjs +25 -307
- package/dist/mcp-auth.cjs.map +1 -1
- package/dist/mcp-auth.js +5 -305
- package/dist/mcp-auth.js.map +1 -1
- package/dist/models.cjs +9 -9
- package/dist/models.js +2 -2
- package/dist/persistence.cjs +9 -4
- package/dist/persistence.cjs.map +1 -1
- package/dist/persistence.d.cts +744 -40
- package/dist/persistence.d.ts +744 -40
- package/dist/persistence.js +3 -2
- package/dist/persistence.js.map +1 -1
- package/dist/providers.cjs +4 -4
- package/dist/providers.js +2 -2
- package/dist/sandbox/docker-sandbox.d.cts +58 -0
- package/dist/sandbox/docker-sandbox.d.ts +58 -0
- package/dist/sandbox/index.cjs +129 -1
- package/dist/sandbox/index.cjs.map +1 -1
- package/dist/sandbox/index.d.cts +1 -0
- package/dist/sandbox/index.d.ts +1 -0
- package/dist/sandbox/index.js +132 -5
- package/dist/sandbox/index.js.map +1 -1
- package/dist/{sdk-agent-DwzHcuxy.d.cts → sdk-agent-BA_6_wtc.d.cts} +30 -2
- package/dist/{sdk-agent-a3fW1xUK.d.ts → sdk-agent-CnwPODYH.d.ts} +30 -2
- package/dist/session-store-Dh07jr9N.d.cts +209 -0
- package/dist/session-store-Dh07jr9N.d.ts +209 -0
- package/dist/sqlite-session-store-BbcpKY1L.d.ts +64 -0
- package/dist/sqlite-session-store-TKXtT4ON.d.cts +64 -0
- package/dist/subagents-loader-KLWF4QPD.cjs +16 -0
- package/dist/{subagents-loader-TXOA5EJJ.cjs.map → subagents-loader-KLWF4QPD.cjs.map} +1 -1
- package/dist/subagents-loader-SXETS2F2.js +7 -0
- package/dist/{subagents-loader-Z744TAKD.js.map → subagents-loader-SXETS2F2.js.map} +1 -1
- package/dist/subagents-loader.cjs +2 -2
- package/dist/subagents-loader.d.cts +3 -2
- package/dist/subagents-loader.d.ts +3 -2
- package/dist/subagents-loader.js +1 -1
- package/dist/types/agent.d.ts +14 -1
- package/dist/types/budget-tracker.d.ts +6 -2
- package/dist/types/mcp.d.ts +14 -0
- package/dist/types/run.d.ts +15 -1
- package/dist/workflow.d.cts +1 -1
- package/dist/workflow.d.ts +1 -1
- package/docs/adr/mutation-testing-scope.md +12 -2
- package/docs/error-codes.md +41 -40
- package/docs/harness-capability-map.md +32 -6
- package/package.json +1 -1
- package/dist/chunk-2WY2OFSC.cjs.map +0 -1
- package/dist/chunk-4TEGFMSP.cjs.map +0 -1
- package/dist/chunk-6CXRYPG7.cjs +0 -211
- package/dist/chunk-6CXRYPG7.cjs.map +0 -1
- package/dist/chunk-CJN5CEI3.js.map +0 -1
- package/dist/chunk-GARVAUCU.js.map +0 -1
- package/dist/chunk-MSEL5E5P.js +0 -204
- package/dist/chunk-MSEL5E5P.js.map +0 -1
- package/dist/chunk-NP362THY.cjs.map +0 -1
- package/dist/chunk-Q5EWJPRY.js +0 -18
- package/dist/chunk-Q5EWJPRY.js.map +0 -1
- package/dist/chunk-R5UQL2R5.cjs +0 -18
- package/dist/chunk-RN3XDZGS.js.map +0 -1
- package/dist/chunk-SNVYOX46.cjs.map +0 -1
- package/dist/chunk-WDVG5R2Q.cjs.map +0 -1
- package/dist/chunk-ZF2LDKQQ.cjs.map +0 -1
- package/dist/chunk-ZJAYFSVI.js.map +0 -1
- package/dist/chunk-ZOL3L4EH.js.map +0 -1
- package/dist/fs-session-store-6ZCCJX3K.js +0 -11
- package/dist/fs-session-store-S2AXVJIX.cjs +0 -20
- package/dist/subagents-loader-TXOA5EJJ.cjs +0 -16
- package/dist/subagents-loader-Z744TAKD.js +0 -7
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { submit, emitRunEvent } from './chunk-HWMGR3HA.js';
|
|
2
|
-
import { enqueueSessionWrite, hydrateSession, persistTurnToTranscript, flushSessionWrites, appendSessionMessage, getSessionMessages, discardSession, clearSession } from './chunk-
|
|
3
|
-
import { IndexManager } from './chunk-
|
|
2
|
+
import { enqueueSessionWrite, hydrateSession, persistTurnToTranscript, flushSessionWrites, appendSessionMessage, getSessionMessages, discardSession, clearSession } from './chunk-23SS4ID4.js';
|
|
3
|
+
import { IndexManager } from './chunk-3BBTHFGJ.js';
|
|
4
4
|
import { currentPersonalityContext, warnPersonalitySwitchInsideFork } from './chunk-HJ2LV464.js';
|
|
5
5
|
import { extractCodePlugins, isCodePlugin } from './chunk-2SFBB54R.js';
|
|
6
|
-
import { createOpenAiCompatibleRuntime } from './chunk-
|
|
6
|
+
import { createOpenAiCompatibleRuntime } from './chunk-VCQ37TC5.js';
|
|
7
7
|
import { persistActiveMemoryTranscript } from './chunk-QK2ERTO3.js';
|
|
8
|
-
import { resolveMaxFacts, writeSessionSummary, resolveMemoryRoot, MEMORY_KINDS, appendFact, readFacts, legacyMemoryJsonPath, memoryMdPath, appendFactToMarkdown } from './chunk-
|
|
9
|
-
import { FsSessionStore } from './chunk-
|
|
10
|
-
import { discoverProviderPlugins, validateApiKeyShape, getConfiguredBaseUrl, httpRequest, isFixtureApiKey, presentProviderCredentialEnvVars, readTrustArray, buildDefaultSummarizer, shouldUseRealLocalRuntime, parseSseStream, CircuitBreaker, trustFilePath, resolveRunProvider, mergeExplicitApiKey, resolveProviderChain, abortError, tryFirstEvent, relayStream, renderToolResultContentText } from './chunk-
|
|
8
|
+
import { resolveMaxFacts, writeSessionSummary, resolveMemoryRoot, MEMORY_KINDS, appendFact, readFacts, legacyMemoryJsonPath, memoryMdPath, appendFactToMarkdown } from './chunk-LCCT5ZXJ.js';
|
|
9
|
+
import { FsSessionStore } from './chunk-RGVMJU57.js';
|
|
10
|
+
import { discoverProviderPlugins, validateApiKeyShape, getConfiguredBaseUrl, httpRequest, isFixtureApiKey, presentProviderCredentialEnvVars, readTrustArray, buildDefaultSummarizer, shouldUseRealLocalRuntime, parseSseStream, CircuitBreaker, trustFilePath, resolveRunProvider, mergeExplicitApiKey, resolveProviderChain, abortError, tryFirstEvent, relayStream, renderToolResultContentText } from './chunk-IOBHFP2E.js';
|
|
11
11
|
import { resolveChildEnv } from './chunk-HKCKOAIO.js';
|
|
12
12
|
import { DEFAULT_MAX_BYTES_PER_FILE, runDiscovery, truncateWithMarker } from './chunk-KCM3RMKR.js';
|
|
13
13
|
import { warnFailureOnce, loadHookConfig, warnOnce } from './chunk-XJ3WU5CZ.js';
|
|
14
|
+
import { getTokens, lockedRefresh, refreshAccessToken, runPkceFlow, setTokens } from './chunk-X7CE7Y5W.js';
|
|
14
15
|
import { readVersionedJson, writeVersionedJson } from './chunk-OLJOI4LK.js';
|
|
15
16
|
import { toJsonSchema } from './chunk-7I5Z3UBJ.js';
|
|
16
17
|
import { sanitizeToolInput } from './chunk-FJWQP6EE.js';
|
|
@@ -22,21 +23,21 @@ import { validateArtifactPath, PathTraversalError, safePathJoin } from './chunk-
|
|
|
22
23
|
import { insideRoot, atOrInsideRoot } from './chunk-UKMBRMGT.js';
|
|
23
24
|
import { mapWithConcurrency } from './chunk-ORLTGPOS.js';
|
|
24
25
|
import { expandTilde, defaultBaseDir } from './chunk-XESYJ4JC.js';
|
|
25
|
-
import { withFileLock } from './chunk-
|
|
26
|
-
import { withCwdMutex } from './chunk-
|
|
26
|
+
import { withFileLock } from './chunk-FGGVSHDW.js';
|
|
27
|
+
import { withCwdMutex } from './chunk-PPU2D4FZ.js';
|
|
27
28
|
import { sweepStaleAtomicTemps, atomicWriteJson } from './chunk-M4U24U6G.js';
|
|
28
|
-
import { loadSubagents, pluginBundleDirs } from './chunk-
|
|
29
|
+
import { loadSubagents, pluginBundleDirs } from './chunk-WM646HEN.js';
|
|
29
30
|
import { reportUndeclaredSources, theokitConfigRoot, undefinedVariablesIn, getTheokitHome, adapterForConfigPath, adaptersForSurface, projectConfigRoots, pluginBundleRoots } from './chunk-YMVTUV5K.js';
|
|
30
31
|
import { readWorkspaceDir, parseSimpleYaml } from './chunk-Q7UG242V.js';
|
|
31
32
|
import { resolveEffectiveContextWindow, CONTEXT_WINDOW_FLOOR, CONTEXT_WINDOW_MARGIN } from './chunk-SZQFCHU6.js';
|
|
32
|
-
import { isAnthropicFamilyModel } from './chunk-
|
|
33
|
+
import { isAnthropicFamilyModel } from './chunk-CBBT42VX.js';
|
|
33
34
|
import { parseModelId } from './chunk-R7WIIPUR.js';
|
|
34
|
-
import { getProviderProfile } from './chunk-
|
|
35
|
-
import { getCatalogModelInfo, isPatchedModelKey } from './chunk-
|
|
35
|
+
import { getProviderProfile } from './chunk-YKNBTHMD.js';
|
|
36
|
+
import { getCatalogModelInfo, isPatchedModelKey } from './chunk-RZL2W4C3.js';
|
|
36
37
|
import { globalSingleton } from './chunk-AGACYRJ2.js';
|
|
37
38
|
import { boundFetch } from './chunk-Q7GYMXVC.js';
|
|
38
|
-
import { AgentRunError, coerceToKnownAgentRunErrorCode, UnknownAgentError, ConfigurationError, AuthenticationError, AgentDisposedError, UnsupportedRunOperationError,
|
|
39
|
-
import { diag, resolveApiKey, API_KEY_ENV_VAR, redactSecrets
|
|
39
|
+
import { AgentRunError, coerceToKnownAgentRunErrorCode, UnknownAgentError, ConfigurationError, AuthenticationError, AgentDisposedError, UnsupportedRunOperationError, TheokitAgentError, NetworkError } from './chunk-TNFOU6SB.js';
|
|
40
|
+
import { diag, resolveApiKey, diagFailure, API_KEY_ENV_VAR, redactSecrets } from './chunk-3OY6H3I7.js';
|
|
40
41
|
import { stat, mkdir, readFile, readdir, access, unlink } from 'fs/promises';
|
|
41
42
|
import { randomUUID, createHash } from 'crypto';
|
|
42
43
|
import { join, dirname, isAbsolute, delimiter, resolve, relative } from 'path';
|
|
@@ -1673,7 +1674,10 @@ var RealCloudRun = class extends FixtureRunBase {
|
|
|
1673
1674
|
await this.consumeStream(response);
|
|
1674
1675
|
} catch (cause) {
|
|
1675
1676
|
if (this.terminated) return;
|
|
1676
|
-
this.fail(
|
|
1677
|
+
this.fail(
|
|
1678
|
+
cause instanceof Error ? cause.message : String(cause),
|
|
1679
|
+
cause instanceof TheokitAgentError ? cause : void 0
|
|
1680
|
+
);
|
|
1677
1681
|
}
|
|
1678
1682
|
}
|
|
1679
1683
|
async postRun(apiKey, baseUrl) {
|
|
@@ -1751,13 +1755,17 @@ var RealCloudRun = class extends FixtureRunBase {
|
|
|
1751
1755
|
message: { role: "assistant", content: [{ type: "text", text }] }
|
|
1752
1756
|
};
|
|
1753
1757
|
}
|
|
1754
|
-
fail(message,
|
|
1758
|
+
fail(message, cause) {
|
|
1755
1759
|
const event = this.buildAssistantEvent(message);
|
|
1756
1760
|
this.script.events.push(event);
|
|
1757
1761
|
this.notifyNewEvents();
|
|
1758
1762
|
this.script.result = message;
|
|
1759
1763
|
if (this.script.errorDetail === void 0) {
|
|
1760
|
-
this.script.errorDetail = {
|
|
1764
|
+
this.script.errorDetail = {
|
|
1765
|
+
message,
|
|
1766
|
+
...cause?.code !== void 0 ? { code: cause.code } : {},
|
|
1767
|
+
...cause !== void 0 ? { cause } : {}
|
|
1768
|
+
};
|
|
1761
1769
|
}
|
|
1762
1770
|
this.transitionTo("error");
|
|
1763
1771
|
}
|
|
@@ -3163,6 +3171,177 @@ async function importEntry(candidate) {
|
|
|
3163
3171
|
function isGeneralPlugin(value) {
|
|
3164
3172
|
return isCodePlugin(value) && value.kind === "general" && typeof value.name === "string";
|
|
3165
3173
|
}
|
|
3174
|
+
|
|
3175
|
+
// src/internal/runtime/registry/live-agent-registry.ts
|
|
3176
|
+
var DEFAULT_MAX_AGENTS = 100;
|
|
3177
|
+
var DEFAULT_IDLE_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
3178
|
+
var DEFAULT_SWEEP_INTERVAL_MS = 6e4;
|
|
3179
|
+
var LiveAgentRegistry = class {
|
|
3180
|
+
#agents = /* @__PURE__ */ new Map();
|
|
3181
|
+
#maxAgents = DEFAULT_MAX_AGENTS;
|
|
3182
|
+
#idleTimeoutMs = DEFAULT_IDLE_TIMEOUT_MS;
|
|
3183
|
+
#sweepIntervalMs = DEFAULT_SWEEP_INTERVAL_MS;
|
|
3184
|
+
#onEvict;
|
|
3185
|
+
#sweepTimer;
|
|
3186
|
+
/**
|
|
3187
|
+
* Reconfigure registry behavior. Process-wide singleton (D310) — last
|
|
3188
|
+
* configure call wins for all subsequent operations.
|
|
3189
|
+
*/
|
|
3190
|
+
configure(opts) {
|
|
3191
|
+
if (opts.maxAgents !== void 0) this.#maxAgents = Math.max(0, opts.maxAgents);
|
|
3192
|
+
if (opts.idleTimeoutMs !== void 0) this.#idleTimeoutMs = Math.max(0, opts.idleTimeoutMs);
|
|
3193
|
+
if (opts.sweepIntervalMs !== void 0)
|
|
3194
|
+
this.#sweepIntervalMs = Math.max(1e3, opts.sweepIntervalMs);
|
|
3195
|
+
this.#onEvict = opts.onEvict;
|
|
3196
|
+
this.#stopSweep();
|
|
3197
|
+
if (this.#idleTimeoutMs > 0) this.#startSweep();
|
|
3198
|
+
}
|
|
3199
|
+
/**
|
|
3200
|
+
* Lookup a cached agent. `get` is a use — refreshes `lastUsedAt` so the
|
|
3201
|
+
* entry survives LRU eviction.
|
|
3202
|
+
*/
|
|
3203
|
+
get(id) {
|
|
3204
|
+
const entry = this.#agents.get(id);
|
|
3205
|
+
if (entry === void 0) return void 0;
|
|
3206
|
+
entry.lastUsedAt = Date.now();
|
|
3207
|
+
return entry.agent;
|
|
3208
|
+
}
|
|
3209
|
+
/**
|
|
3210
|
+
* Insert or overwrite an agent in the cache. Triggers fire-and-forget LRU
|
|
3211
|
+
* eviction when `size > maxAgents`.
|
|
3212
|
+
*
|
|
3213
|
+
* EC-4: when `id` already maps to a DIFFERENT agent instance, dispose the
|
|
3214
|
+
* old one before overwriting (race protection against two `getOrCreate`
|
|
3215
|
+
* calls creating two agents but only the second being cached — the first
|
|
3216
|
+
* would leak file handles + lifecycle controllers).
|
|
3217
|
+
*/
|
|
3218
|
+
set(id, agent) {
|
|
3219
|
+
if (this.#maxAgents === 0) return;
|
|
3220
|
+
const existing = this.#agents.get(id);
|
|
3221
|
+
if (existing !== void 0 && existing.agent !== agent) {
|
|
3222
|
+
void existing.agent.dispose().catch(() => {
|
|
3223
|
+
diag(`[theokit-sdk] dispose during overwrite failed (${id})
|
|
3224
|
+
`);
|
|
3225
|
+
});
|
|
3226
|
+
}
|
|
3227
|
+
this.#agents.set(id, { agent, lastUsedAt: Date.now() });
|
|
3228
|
+
if (this.#agents.size > this.#maxAgents) void this.#evictLRU();
|
|
3229
|
+
}
|
|
3230
|
+
/**
|
|
3231
|
+
* Remove the entry from the cache WITHOUT calling `dispose()` or
|
|
3232
|
+
* `onEvict`. Used by `LocalAgent.dispose()` itself so the disposed
|
|
3233
|
+
* instance can never be returned by a subsequent `get(id)` (dispose-cache
|
|
3234
|
+
* race fix). Idempotent — calling on an unknown id is a no-op.
|
|
3235
|
+
*
|
|
3236
|
+
* @internal
|
|
3237
|
+
*/
|
|
3238
|
+
forget(id) {
|
|
3239
|
+
this.#agents.delete(id);
|
|
3240
|
+
}
|
|
3241
|
+
/**
|
|
3242
|
+
* Explicitly evict an agent by id. Returns `true` when the entry was
|
|
3243
|
+
* present (false = already gone). Calls `agent.dispose()` + `onEvict`
|
|
3244
|
+
* with reason `"explicit"`.
|
|
3245
|
+
*/
|
|
3246
|
+
async evict(id) {
|
|
3247
|
+
const entry = this.#agents.get(id);
|
|
3248
|
+
if (entry === void 0) return false;
|
|
3249
|
+
this.#agents.delete(id);
|
|
3250
|
+
await this.#disposeAndNotify(id, entry.agent, "explicit");
|
|
3251
|
+
return true;
|
|
3252
|
+
}
|
|
3253
|
+
/**
|
|
3254
|
+
* Evict every cached agent. Used by graceful shutdown (`process.on('SIGTERM')`)
|
|
3255
|
+
* or end-of-test cleanup.
|
|
3256
|
+
*/
|
|
3257
|
+
async evictAll() {
|
|
3258
|
+
const entries = Array.from(this.#agents.entries());
|
|
3259
|
+
this.#agents.clear();
|
|
3260
|
+
this.#stopSweep();
|
|
3261
|
+
for (const [id, entry] of entries) {
|
|
3262
|
+
await this.#disposeAndNotify(id, entry.agent, "explicit");
|
|
3263
|
+
}
|
|
3264
|
+
}
|
|
3265
|
+
/** Number of currently cached agents. */
|
|
3266
|
+
size() {
|
|
3267
|
+
return this.#agents.size;
|
|
3268
|
+
}
|
|
3269
|
+
/** Ids of cached agents, newest first (by lastUsedAt). */
|
|
3270
|
+
ids() {
|
|
3271
|
+
return Array.from(this.#agents.entries()).sort((a, b) => b[1].lastUsedAt - a[1].lastUsedAt).map(([id]) => id);
|
|
3272
|
+
}
|
|
3273
|
+
/**
|
|
3274
|
+
* LRU eviction: drop the entry with the smallest `lastUsedAt`. Runs only
|
|
3275
|
+
* when `size > maxAgents`. Asynchronous because `dispose()` is a Promise;
|
|
3276
|
+
* the hot-path caller (`set`) does not await.
|
|
3277
|
+
*
|
|
3278
|
+
* @internal
|
|
3279
|
+
*/
|
|
3280
|
+
async #evictLRU() {
|
|
3281
|
+
if (this.#agents.size <= this.#maxAgents) return;
|
|
3282
|
+
let oldestId;
|
|
3283
|
+
let oldestAt = Infinity;
|
|
3284
|
+
for (const [id, entry2] of this.#agents) {
|
|
3285
|
+
if (entry2.lastUsedAt < oldestAt) {
|
|
3286
|
+
oldestAt = entry2.lastUsedAt;
|
|
3287
|
+
oldestId = id;
|
|
3288
|
+
}
|
|
3289
|
+
}
|
|
3290
|
+
if (oldestId === void 0) return;
|
|
3291
|
+
const entry = this.#agents.get(oldestId);
|
|
3292
|
+
if (entry === void 0) return;
|
|
3293
|
+
this.#agents.delete(oldestId);
|
|
3294
|
+
await this.#disposeAndNotify(oldestId, entry.agent, "lru");
|
|
3295
|
+
}
|
|
3296
|
+
/** Background sweep — drops entries whose `lastUsedAt < now - idleTimeoutMs`. */
|
|
3297
|
+
async #sweepIdle() {
|
|
3298
|
+
if (this.#idleTimeoutMs === 0) return;
|
|
3299
|
+
const threshold = Date.now() - this.#idleTimeoutMs;
|
|
3300
|
+
const toEvict = [];
|
|
3301
|
+
for (const [id, entry] of this.#agents) {
|
|
3302
|
+
if (entry.lastUsedAt < threshold) toEvict.push([id, entry]);
|
|
3303
|
+
}
|
|
3304
|
+
for (const [id, entry] of toEvict) {
|
|
3305
|
+
const current = this.#agents.get(id);
|
|
3306
|
+
if (current === void 0 || current.agent !== entry.agent) continue;
|
|
3307
|
+
this.#agents.delete(id);
|
|
3308
|
+
await this.#disposeAndNotify(id, entry.agent, "idle");
|
|
3309
|
+
}
|
|
3310
|
+
}
|
|
3311
|
+
#startSweep() {
|
|
3312
|
+
this.#sweepTimer = setInterval(() => void this.#sweepIdle(), this.#sweepIntervalMs);
|
|
3313
|
+
this.#sweepTimer.unref?.();
|
|
3314
|
+
}
|
|
3315
|
+
#stopSweep() {
|
|
3316
|
+
if (this.#sweepTimer !== void 0) {
|
|
3317
|
+
clearInterval(this.#sweepTimer);
|
|
3318
|
+
this.#sweepTimer = void 0;
|
|
3319
|
+
}
|
|
3320
|
+
}
|
|
3321
|
+
/** Dispose + notify with errors swallowed (D309). Single chokepoint. */
|
|
3322
|
+
async #disposeAndNotify(id, agent, reason) {
|
|
3323
|
+
try {
|
|
3324
|
+
await agent.dispose();
|
|
3325
|
+
} catch (cause) {
|
|
3326
|
+
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
3327
|
+
diag(`[theokit-sdk] dispose during eviction failed (${id}): ${msg}
|
|
3328
|
+
`);
|
|
3329
|
+
}
|
|
3330
|
+
if (this.#onEvict !== void 0) {
|
|
3331
|
+
try {
|
|
3332
|
+
this.#onEvict(id, reason);
|
|
3333
|
+
} catch (cause) {
|
|
3334
|
+
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
3335
|
+
diag(`[theokit-sdk] onEvict listener threw (${id}): ${msg}
|
|
3336
|
+
`);
|
|
3337
|
+
}
|
|
3338
|
+
}
|
|
3339
|
+
}
|
|
3340
|
+
};
|
|
3341
|
+
var liveAgentRegistry = globalSingleton(
|
|
3342
|
+
"theokit-sdk.runtime.live-agents",
|
|
3343
|
+
() => new LiveAgentRegistry()
|
|
3344
|
+
);
|
|
3166
3345
|
function executableExtensions() {
|
|
3167
3346
|
return process.platform === "win32" ? ["", ...(process.env.PATHEXT ?? ".EXE;.CMD").split(";")] : [""];
|
|
3168
3347
|
}
|
|
@@ -3182,8 +3361,9 @@ function binaryOnPath(bin) {
|
|
|
3182
3361
|
);
|
|
3183
3362
|
}
|
|
3184
3363
|
var SkillsManager = class {
|
|
3185
|
-
constructor(cwd,
|
|
3364
|
+
constructor(cwd, enabled, settingSourcesIncludeProject, skillsDir, inline, compatSources = [], bundledDirs = []) {
|
|
3186
3365
|
this.cwd = cwd;
|
|
3366
|
+
this.enabled = enabled;
|
|
3187
3367
|
this.settingSourcesIncludeProject = settingSourcesIncludeProject;
|
|
3188
3368
|
this.skillsDir = skillsDir;
|
|
3189
3369
|
this.inline = inline;
|
|
@@ -3191,6 +3371,7 @@ var SkillsManager = class {
|
|
|
3191
3371
|
this.bundledDirs = bundledDirs;
|
|
3192
3372
|
}
|
|
3193
3373
|
cwd;
|
|
3374
|
+
enabled;
|
|
3194
3375
|
settingSourcesIncludeProject;
|
|
3195
3376
|
skillsDir;
|
|
3196
3377
|
inline;
|
|
@@ -3236,8 +3417,12 @@ var SkillsManager = class {
|
|
|
3236
3417
|
const inlineNames = new Set(this.inline.map((s) => s.name));
|
|
3237
3418
|
return [...discovered.filter((s) => !inlineNames.has(s.name)), ...this.inline];
|
|
3238
3419
|
}
|
|
3420
|
+
visible() {
|
|
3421
|
+
const allowed = this.enabled;
|
|
3422
|
+
return allowed === void 0 ? this.skills : this.skills.filter((s) => allowed.includes(s.name));
|
|
3423
|
+
}
|
|
3239
3424
|
list() {
|
|
3240
|
-
return Promise.resolve(this.
|
|
3425
|
+
return Promise.resolve(this.visible());
|
|
3241
3426
|
}
|
|
3242
3427
|
/**
|
|
3243
3428
|
* SE20 — resolve a skill by name INCLUDING its body. Inline (`createSkill`)
|
|
@@ -3246,7 +3431,7 @@ var SkillsManager = class {
|
|
|
3246
3431
|
* enabled skill matches (malformed skills were already excluded at discovery).
|
|
3247
3432
|
*/
|
|
3248
3433
|
async get(name) {
|
|
3249
|
-
const skill = this.
|
|
3434
|
+
const skill = this.visible().find((s) => s.name === name);
|
|
3250
3435
|
if (skill === void 0) return void 0;
|
|
3251
3436
|
const instructions = typeof skill.instructions === "string" ? skill.instructions : stripSkillFrontmatter(await readFile(skill.source, "utf8"));
|
|
3252
3437
|
const references = skill.references;
|
|
@@ -3674,6 +3859,23 @@ function validateMcpServers(options) {
|
|
|
3674
3859
|
{ code: "cloud_stdio_cwd_rejected" }
|
|
3675
3860
|
);
|
|
3676
3861
|
}
|
|
3862
|
+
rejectUnhonourableAuth(name, config, options.cloud !== void 0);
|
|
3863
|
+
}
|
|
3864
|
+
}
|
|
3865
|
+
function rejectUnhonourableAuth(name, config, cloud) {
|
|
3866
|
+
const auth = config.auth;
|
|
3867
|
+
if (auth === void 0) return;
|
|
3868
|
+
if (auth.oauth === void 0) {
|
|
3869
|
+
throw new ConfigurationError(
|
|
3870
|
+
`MCP server "${name}" declares auth without auth.oauth, which the SDK cannot honour; use auth.oauth or set an Authorization header`,
|
|
3871
|
+
{ code: "mcp_auth_unsupported" }
|
|
3872
|
+
);
|
|
3873
|
+
}
|
|
3874
|
+
if (cloud) {
|
|
3875
|
+
throw new ConfigurationError(
|
|
3876
|
+
`MCP server "${name}" declares auth.oauth, which the SDK cannot run for a cloud agent`,
|
|
3877
|
+
{ code: "mcp_auth_unsupported" }
|
|
3878
|
+
);
|
|
3677
3879
|
}
|
|
3678
3880
|
}
|
|
3679
3881
|
function isStdioWithCwd(config) {
|
|
@@ -4190,8 +4392,13 @@ function wrapSpan(span, openSpans) {
|
|
|
4190
4392
|
setAttribute: (k, v) => safe(() => span.setAttribute(k, redactAttrValue(v)), void 0),
|
|
4191
4393
|
setAttributes: (attrs) => safe(() => span.setAttributes(redactAttrs(attrs)), void 0),
|
|
4192
4394
|
addEvent: (name, attrs) => safe(() => span.addEvent(name, attrs ? redactAttrs(attrs) : void 0), void 0),
|
|
4193
|
-
setStatus: (status) => safe(
|
|
4194
|
-
|
|
4395
|
+
setStatus: (status) => safe(
|
|
4396
|
+
() => span.setStatus(
|
|
4397
|
+
status.message === void 0 ? status : { ...status, message: redactSecrets(status.message) }
|
|
4398
|
+
),
|
|
4399
|
+
void 0
|
|
4400
|
+
),
|
|
4401
|
+
recordException: (err) => safe(() => span.recordException(redactException(err)), void 0),
|
|
4195
4402
|
end: (endTime) => {
|
|
4196
4403
|
safe(() => span.end(endTime), void 0);
|
|
4197
4404
|
openSpans.delete(span);
|
|
@@ -4200,6 +4407,18 @@ function wrapSpan(span, openSpans) {
|
|
|
4200
4407
|
isRecording: () => safe(() => span.isRecording(), false)
|
|
4201
4408
|
};
|
|
4202
4409
|
}
|
|
4410
|
+
function redactException(err) {
|
|
4411
|
+
if (typeof err === "string") return redactSecrets(err);
|
|
4412
|
+
if (typeof err !== "object" || err === null) return err;
|
|
4413
|
+
const src = err;
|
|
4414
|
+
const out = {};
|
|
4415
|
+
for (const k of ["name", "code", "message", "stack"]) {
|
|
4416
|
+
const v = src[k];
|
|
4417
|
+
if (typeof v === "string") out[k] = redactSecrets(v);
|
|
4418
|
+
else if (typeof v === "number") out[k] = v;
|
|
4419
|
+
}
|
|
4420
|
+
return out;
|
|
4421
|
+
}
|
|
4203
4422
|
function redactAttrValue(value) {
|
|
4204
4423
|
if (typeof value !== "string") return value;
|
|
4205
4424
|
return redactSecrets(value);
|
|
@@ -5164,7 +5383,9 @@ function evaluateBudgetGate(tracker) {
|
|
|
5164
5383
|
return {
|
|
5165
5384
|
allowed: false,
|
|
5166
5385
|
reason: "custom",
|
|
5167
|
-
detail: `budget_tracker_check_threw: ${message}
|
|
5386
|
+
detail: `budget_tracker_check_threw: ${message}`,
|
|
5387
|
+
// Keep the thrown value so the run's error can carry it as its cause.
|
|
5388
|
+
cause: error
|
|
5168
5389
|
};
|
|
5169
5390
|
}
|
|
5170
5391
|
}
|
|
@@ -5174,11 +5395,12 @@ function createDoomLoopTracker(option) {
|
|
|
5174
5395
|
if (option === false) return void 0;
|
|
5175
5396
|
return new DoomLoopTracker(option);
|
|
5176
5397
|
}
|
|
5177
|
-
var DEFAULT_CONFIG = { softThreshold: 3, hardThreshold: 5 };
|
|
5178
|
-
function assertValidThresholds(soft, hard) {
|
|
5398
|
+
var DEFAULT_CONFIG = { softThreshold: 3, hardThreshold: 5, churnThreshold: 6 };
|
|
5399
|
+
function assertValidThresholds(soft, hard, churn) {
|
|
5179
5400
|
for (const [label, value] of [
|
|
5180
5401
|
["softThreshold", soft],
|
|
5181
|
-
["hardThreshold", hard]
|
|
5402
|
+
["hardThreshold", hard],
|
|
5403
|
+
["churnThreshold", churn]
|
|
5182
5404
|
]) {
|
|
5183
5405
|
if (!Number.isInteger(value) || value < 1) {
|
|
5184
5406
|
throw new ConfigurationError(
|
|
@@ -5215,17 +5437,40 @@ var DoomLoopTracker = class {
|
|
|
5215
5437
|
#config;
|
|
5216
5438
|
#lastSignature = "";
|
|
5217
5439
|
#count = 0;
|
|
5440
|
+
#lastName = "";
|
|
5441
|
+
#lastResult;
|
|
5442
|
+
#churn = 0;
|
|
5218
5443
|
constructor(config) {
|
|
5219
5444
|
const softThreshold = config?.softThreshold ?? DEFAULT_CONFIG.softThreshold;
|
|
5220
5445
|
const hardThreshold = config?.hardThreshold ?? DEFAULT_CONFIG.hardThreshold;
|
|
5221
|
-
|
|
5222
|
-
|
|
5446
|
+
const churnThreshold = config?.churnThreshold ?? DEFAULT_CONFIG.churnThreshold;
|
|
5447
|
+
assertValidThresholds(softThreshold, hardThreshold, churnThreshold);
|
|
5448
|
+
this.#config = { softThreshold, hardThreshold, churnThreshold };
|
|
5223
5449
|
}
|
|
5224
5450
|
inspect(call) {
|
|
5225
5451
|
const signature = signatureOf(call);
|
|
5226
|
-
|
|
5452
|
+
const identical = signature === this.#lastSignature;
|
|
5453
|
+
const churning = !identical && call.name === this.#lastName && call.result !== void 0 && call.result === this.#lastResult;
|
|
5454
|
+
this.#churn = churning ? this.#churn + 1 : 1;
|
|
5455
|
+
this.#lastName = call.name;
|
|
5456
|
+
this.#lastResult = call.result;
|
|
5457
|
+
this.#count = identical ? this.#count + 1 : 1;
|
|
5227
5458
|
this.#lastSignature = signature;
|
|
5228
5459
|
const count = this.#count;
|
|
5460
|
+
const churn = this.#churn;
|
|
5461
|
+
const churnHard = this.#config.churnThreshold;
|
|
5462
|
+
if (churn >= churnHard) {
|
|
5463
|
+
return {
|
|
5464
|
+
kind: "hard",
|
|
5465
|
+
message: `Detected argument churn: ${churn} consecutive calls to \`${call.name}\` with different arguments and no change in the result; stopping to avoid a loop.`
|
|
5466
|
+
};
|
|
5467
|
+
}
|
|
5468
|
+
if (churn > 1 && churn === Math.max(2, churnHard - 2)) {
|
|
5469
|
+
return {
|
|
5470
|
+
kind: "soft",
|
|
5471
|
+
message: `Detected argument churn: ${churn} consecutive calls to \`${call.name}\` with different arguments and no change in the result; try a different approach.`
|
|
5472
|
+
};
|
|
5473
|
+
}
|
|
5229
5474
|
if (count >= this.#config.hardThreshold) {
|
|
5230
5475
|
return {
|
|
5231
5476
|
kind: "hard",
|
|
@@ -5243,6 +5488,9 @@ var DoomLoopTracker = class {
|
|
|
5243
5488
|
reset() {
|
|
5244
5489
|
this.#lastSignature = "";
|
|
5245
5490
|
this.#count = 0;
|
|
5491
|
+
this.#lastName = "";
|
|
5492
|
+
this.#lastResult = void 0;
|
|
5493
|
+
this.#churn = 0;
|
|
5246
5494
|
}
|
|
5247
5495
|
};
|
|
5248
5496
|
function firstDoomLoopVerdict(tracker, calls) {
|
|
@@ -5487,7 +5735,16 @@ async function initLoopContext(inputs) {
|
|
|
5487
5735
|
),
|
|
5488
5736
|
buildUserEvent(inputs)
|
|
5489
5737
|
]);
|
|
5490
|
-
if (inputs.onLoopEvent !== void 0)
|
|
5738
|
+
if (inputs.onLoopEvent !== void 0) {
|
|
5739
|
+
const sink = inputs.onLoopEvent;
|
|
5740
|
+
for (const seeded of events) {
|
|
5741
|
+
try {
|
|
5742
|
+
sink(seeded);
|
|
5743
|
+
} catch {
|
|
5744
|
+
}
|
|
5745
|
+
}
|
|
5746
|
+
events.subscribe(sink);
|
|
5747
|
+
}
|
|
5491
5748
|
const priorMessages = replayMessages(inputs.priorMessages ?? []);
|
|
5492
5749
|
let memorySystemPromptAdditions;
|
|
5493
5750
|
if (inputs.memoryProvider !== void 0 && memoryProviderHandle !== void 0) {
|
|
@@ -5576,7 +5833,8 @@ async function collectTools(mcp, withheld, sink) {
|
|
|
5576
5833
|
inputSchema: tool.inputSchema,
|
|
5577
5834
|
origin: "mcp",
|
|
5578
5835
|
mcpServerName: serverName,
|
|
5579
|
-
mcpToolName: tool.name
|
|
5836
|
+
mcpToolName: tool.name,
|
|
5837
|
+
...client.sequential === true ? { mcpSequential: true } : {}
|
|
5580
5838
|
});
|
|
5581
5839
|
}
|
|
5582
5840
|
}
|
|
@@ -6563,11 +6821,35 @@ function raceToolExecution(exec, opts) {
|
|
|
6563
6821
|
// src/internal/agent-loop/tool-dispatch.ts
|
|
6564
6822
|
async function dispatchTools(inputs, tools, toolCalls, events, parentSpan) {
|
|
6565
6823
|
const maxConcurrent = inputs.maxConcurrentTools ?? 4;
|
|
6566
|
-
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
(
|
|
6570
|
-
|
|
6824
|
+
const units = [];
|
|
6825
|
+
const bySequentialServer = /* @__PURE__ */ new Map();
|
|
6826
|
+
toolCalls.forEach((call, index) => {
|
|
6827
|
+
const tool = tools.find((t) => t.name === call.name);
|
|
6828
|
+
if (tool?.mcpSequential === true && tool.mcpServerName !== void 0) {
|
|
6829
|
+
let unit = bySequentialServer.get(tool.mcpServerName);
|
|
6830
|
+
if (unit === void 0) {
|
|
6831
|
+
unit = { indexes: [] };
|
|
6832
|
+
bySequentialServer.set(tool.mcpServerName, unit);
|
|
6833
|
+
units.push(unit);
|
|
6834
|
+
}
|
|
6835
|
+
unit.indexes.push(index);
|
|
6836
|
+
} else {
|
|
6837
|
+
units.push({ indexes: [index] });
|
|
6838
|
+
}
|
|
6839
|
+
});
|
|
6840
|
+
const results = new Array(toolCalls.length);
|
|
6841
|
+
await mapWithConcurrency(units, maxConcurrent, async (unit) => {
|
|
6842
|
+
for (const index of unit.indexes) {
|
|
6843
|
+
results[index] = await dispatchSingleCall(
|
|
6844
|
+
inputs,
|
|
6845
|
+
tools,
|
|
6846
|
+
toolCalls[index],
|
|
6847
|
+
events,
|
|
6848
|
+
parentSpan
|
|
6849
|
+
);
|
|
6850
|
+
}
|
|
6851
|
+
});
|
|
6852
|
+
return results;
|
|
6571
6853
|
}
|
|
6572
6854
|
async function dispatchSingleCall(inputs, tools, call, events, parentSpan) {
|
|
6573
6855
|
const { call: workingCall, repairs } = applyRepairAndExtractCall(tools, call);
|
|
@@ -6944,12 +7226,17 @@ async function runAgentLoop(inputs) {
|
|
|
6944
7226
|
const budget = inputs.budget ?? new IterationBudget({ maxIterations: inputs.maxIterations ?? 8 });
|
|
6945
7227
|
let lastTurnDecision;
|
|
6946
7228
|
while (budget.shouldContinue()) {
|
|
7229
|
+
injectSteered(ctx, inputs.steerQueue?.drain());
|
|
6947
7230
|
if (inputs.budgetTracker !== void 0) {
|
|
6948
7231
|
const decision2 = evaluateBudgetGate(inputs.budgetTracker);
|
|
6949
7232
|
if (decision2.allowed === false) {
|
|
6950
7233
|
ctx.finalStatus = "error";
|
|
6951
7234
|
if (decision2.detail !== void 0) {
|
|
6952
|
-
ctx.error = {
|
|
7235
|
+
ctx.error = {
|
|
7236
|
+
message: decision2.detail,
|
|
7237
|
+
code: decision2.reason ?? "budget",
|
|
7238
|
+
...decision2.cause !== void 0 ? { cause: decision2.cause } : {}
|
|
7239
|
+
};
|
|
6953
7240
|
}
|
|
6954
7241
|
if (decision2.reason === "iteration_limit") {
|
|
6955
7242
|
ctx.stoppedAtIterationLimit = true;
|
|
@@ -6961,7 +7248,13 @@ async function runAgentLoop(inputs) {
|
|
|
6961
7248
|
if (usingGrace) budget.useGraceCall();
|
|
6962
7249
|
const decision = await runIteration(inputs, ctx);
|
|
6963
7250
|
lastTurnDecision = decision;
|
|
6964
|
-
if (decision === "done")
|
|
7251
|
+
if (decision === "done") {
|
|
7252
|
+
const late = inputs.steerQueue?.drainOrClose() ?? [];
|
|
7253
|
+
if (late.length === 0) break;
|
|
7254
|
+
injectSteered(ctx, late);
|
|
7255
|
+
budget.consume();
|
|
7256
|
+
continue;
|
|
7257
|
+
}
|
|
6965
7258
|
if (decision === "error") {
|
|
6966
7259
|
ctx.finalStatus = "error";
|
|
6967
7260
|
break;
|
|
@@ -7089,6 +7382,10 @@ async function finishOrReflect(inputs, ctx, llmOutput) {
|
|
|
7089
7382
|
ctx.finalStatus = "finished";
|
|
7090
7383
|
return "done";
|
|
7091
7384
|
}
|
|
7385
|
+
function injectSteered(ctx, texts) {
|
|
7386
|
+
if (texts === void 0) return;
|
|
7387
|
+
for (const text of texts) ctx.messages.push({ role: "user", content: [{ type: "text", text }] });
|
|
7388
|
+
}
|
|
7092
7389
|
async function runIteration(inputs, ctx) {
|
|
7093
7390
|
const hookCtx = { agentId: inputs.agentId, runId: inputs.runId };
|
|
7094
7391
|
await inputs.pluginManager?.runPreLlmCallHooks(hookCtx);
|
|
@@ -7102,12 +7399,11 @@ function trackTurnUsage(inputs, llmOutput) {
|
|
|
7102
7399
|
const tracker = inputs.budgetTracker;
|
|
7103
7400
|
if (tracker === void 0) return;
|
|
7104
7401
|
const model = inputs.model.id ?? "auto";
|
|
7105
|
-
trackEvent(tracker, { tokens:
|
|
7402
|
+
trackEvent(tracker, { tokens: llmOutput.inputTokens ?? 0, model, type: "input" });
|
|
7403
|
+
trackEvent(tracker, { tokens: llmOutput.cacheReadTokens ?? 0, model, type: "cache_read" });
|
|
7404
|
+
trackEvent(tracker, { tokens: llmOutput.cacheWriteTokens ?? 0, model, type: "cache_write" });
|
|
7106
7405
|
trackEvent(tracker, { tokens: llmOutput.outputTokens ?? 0, model, type: "output" });
|
|
7107
7406
|
}
|
|
7108
|
-
function promptTokens(llmOutput) {
|
|
7109
|
-
return (llmOutput.inputTokens ?? 0) + (llmOutput.cacheReadTokens ?? 0) + (llmOutput.cacheWriteTokens ?? 0);
|
|
7110
|
-
}
|
|
7111
7407
|
function trackEvent(tracker, event) {
|
|
7112
7408
|
if (event.tokens <= 0) return;
|
|
7113
7409
|
try {
|
|
@@ -7166,12 +7462,22 @@ async function continueOrTerminate(inputs, ctx, llmOutput) {
|
|
|
7166
7462
|
}
|
|
7167
7463
|
}
|
|
7168
7464
|
pushToolConversationSteps(ctx, llmOutput.toolCalls, toolResults);
|
|
7169
|
-
if (await inspectDoomLoop(inputs, ctx, llmOutput.toolCalls) === "stop")
|
|
7465
|
+
if (await inspectDoomLoop(inputs, ctx, llmOutput.toolCalls, toolResults) === "stop")
|
|
7466
|
+
return "done";
|
|
7170
7467
|
return handleToolErrorContinuation(inputs, ctx, toolResults);
|
|
7171
7468
|
}
|
|
7172
|
-
async function inspectDoomLoop(inputs, ctx, toolCalls) {
|
|
7469
|
+
async function inspectDoomLoop(inputs, ctx, toolCalls, toolResults) {
|
|
7173
7470
|
if (ctx.doomLoop === void 0) return "continue";
|
|
7174
|
-
const
|
|
7471
|
+
const resultById = /* @__PURE__ */ new Map();
|
|
7472
|
+
for (const part of toolResults) {
|
|
7473
|
+
if (part.type === "tool_result") {
|
|
7474
|
+
resultById.set(part.toolUseId, JSON.stringify([part.content, part.isError === true]));
|
|
7475
|
+
}
|
|
7476
|
+
}
|
|
7477
|
+
const verdict = firstDoomLoopVerdict(
|
|
7478
|
+
ctx.doomLoop,
|
|
7479
|
+
toolCalls.map((c) => ({ name: c.name, input: c.input, result: resultById.get(c.id) }))
|
|
7480
|
+
);
|
|
7175
7481
|
if (verdict.kind === "hard") {
|
|
7176
7482
|
ctx.stoppedByDoomLoop = true;
|
|
7177
7483
|
await emitAssistantTextStep(
|
|
@@ -7248,6 +7554,34 @@ function handshakeAwareTimeout(input) {
|
|
|
7248
7554
|
return isReconnectHandshake ? Math.max(input.requestTimeoutMs, HANDSHAKE_FLOOR_MS) : input.requestTimeoutMs;
|
|
7249
7555
|
}
|
|
7250
7556
|
|
|
7557
|
+
// src/internal/mcp/oauth-bearer.ts
|
|
7558
|
+
var EXPIRY_SKEW_MS = 3e4;
|
|
7559
|
+
async function obtain(serverName, clientId, scopes, oauth) {
|
|
7560
|
+
const stored = await getTokens(serverName);
|
|
7561
|
+
if (stored?.accessToken !== void 0 && stored.expiresAt - EXPIRY_SKEW_MS > Date.now()) {
|
|
7562
|
+
return stored;
|
|
7563
|
+
}
|
|
7564
|
+
const refreshToken = stored?.refreshToken;
|
|
7565
|
+
if (refreshToken !== void 0) {
|
|
7566
|
+
try {
|
|
7567
|
+
return await lockedRefresh(
|
|
7568
|
+
serverName,
|
|
7569
|
+
() => refreshAccessToken(serverName, clientId, refreshToken, oauth)
|
|
7570
|
+
);
|
|
7571
|
+
} catch {
|
|
7572
|
+
}
|
|
7573
|
+
}
|
|
7574
|
+
const fresh = await runPkceFlow(serverName, clientId, scopes, oauth);
|
|
7575
|
+
await setTokens(serverName, fresh);
|
|
7576
|
+
return fresh;
|
|
7577
|
+
}
|
|
7578
|
+
async function resolveBearer(serverName, auth) {
|
|
7579
|
+
if (auth.oauth === void 0)
|
|
7580
|
+
throw new Error(`MCP server "${serverName}" declares no auth.oauth`);
|
|
7581
|
+
const tokens = await obtain(serverName, auth.CLIENT_ID, auth.scopes, auth.oauth);
|
|
7582
|
+
return `Bearer ${tokens.accessToken}`;
|
|
7583
|
+
}
|
|
7584
|
+
|
|
7251
7585
|
// src/internal/mcp/client.ts
|
|
7252
7586
|
function createMcpClient(name, config, fetchImpl = fetch) {
|
|
7253
7587
|
if (isStdio(config)) return new StdioMcpClient(name, config);
|
|
@@ -7328,6 +7662,9 @@ var StdioMcpClient = class extends BaseMcpClient {
|
|
|
7328
7662
|
reconnectPromise;
|
|
7329
7663
|
/** True only while `reconnect()`'s handshake is in flight — see `timeoutFor`. */
|
|
7330
7664
|
reconnecting = false;
|
|
7665
|
+
get sequential() {
|
|
7666
|
+
return this.config.sequential === true;
|
|
7667
|
+
}
|
|
7331
7668
|
get timeoutMs() {
|
|
7332
7669
|
return this.config.requestTimeoutMs ?? DEFAULT_MCP_TIMEOUT_MS;
|
|
7333
7670
|
}
|
|
@@ -7534,6 +7871,9 @@ var HttpMcpClient = class extends BaseMcpClient {
|
|
|
7534
7871
|
*/
|
|
7535
7872
|
sessionId;
|
|
7536
7873
|
fetchImpl;
|
|
7874
|
+
get sequential() {
|
|
7875
|
+
return this.config.sequential === true;
|
|
7876
|
+
}
|
|
7537
7877
|
close() {
|
|
7538
7878
|
return Promise.resolve();
|
|
7539
7879
|
}
|
|
@@ -7546,7 +7886,9 @@ var HttpMcpClient = class extends BaseMcpClient {
|
|
|
7546
7886
|
* override contract predates this change and is the only escape a user has while a server
|
|
7547
7887
|
* misbehaves.
|
|
7548
7888
|
*/
|
|
7549
|
-
buildHeaders() {
|
|
7889
|
+
async buildHeaders() {
|
|
7890
|
+
const auth = this.config.auth;
|
|
7891
|
+
const bearer = auth?.oauth !== void 0 ? await resolveBearer(this.name, auth) : void 0;
|
|
7550
7892
|
return {
|
|
7551
7893
|
"content-type": "application/json",
|
|
7552
7894
|
// Streamable HTTP asks for BOTH media types. Declaring only `application/json` makes a
|
|
@@ -7555,6 +7897,7 @@ var HttpMcpClient = class extends BaseMcpClient {
|
|
|
7555
7897
|
// Present only for a STATEFUL server. For a stateless one nothing is sent — inventing a
|
|
7556
7898
|
// header would trade one broken transport for another.
|
|
7557
7899
|
...this.sessionId !== void 0 ? { "mcp-session-id": this.sessionId } : {},
|
|
7900
|
+
...bearer !== void 0 ? { authorization: bearer } : {},
|
|
7558
7901
|
...this.config.headers ?? {}
|
|
7559
7902
|
};
|
|
7560
7903
|
}
|
|
@@ -7597,7 +7940,7 @@ var HttpMcpClient = class extends BaseMcpClient {
|
|
|
7597
7940
|
async request(method, params) {
|
|
7598
7941
|
const id = this.nextId++;
|
|
7599
7942
|
const payload = { jsonrpc: "2.0", id, method, params };
|
|
7600
|
-
const headers = this.buildHeaders();
|
|
7943
|
+
const headers = await this.buildHeaders();
|
|
7601
7944
|
const timeoutMs = this.config.requestTimeoutMs ?? DEFAULT_MCP_TIMEOUT_MS;
|
|
7602
7945
|
let response;
|
|
7603
7946
|
try {
|
|
@@ -7944,6 +8287,7 @@ function buildLoopInputs(options, runId, userText, userImages) {
|
|
|
7944
8287
|
...options.sendOptions.context !== void 0 ? { context: options.sendOptions.context } : {},
|
|
7945
8288
|
// SE2 — forward the opt-in typed runtime-event sink to the loop.
|
|
7946
8289
|
...options.sendOptions.onRunEvent !== void 0 ? { runEventSink: options.sendOptions.onRunEvent } : {},
|
|
8290
|
+
...options.steerQueue !== void 0 ? { steerQueue: options.steerQueue } : {},
|
|
7947
8291
|
...toolResultPolicyInputs(options.sendOptions),
|
|
7948
8292
|
// M1-2: per-send iteration ceiling (validated above). The loop reads
|
|
7949
8293
|
// inputs.maxIterations (default 8 when unset).
|
|
@@ -8165,7 +8509,8 @@ function buildRealRunOptions(args) {
|
|
|
8165
8509
|
...args.priorMessages.length > 0 ? { priorMessages: args.priorMessages } : {},
|
|
8166
8510
|
...args.memoryTools !== void 0 && args.memoryTools.length > 0 ? { memoryTools: args.memoryTools } : {},
|
|
8167
8511
|
...args.personalityToolWhitelist !== void 0 ? { personalityToolWhitelist: args.personalityToolWhitelist } : {},
|
|
8168
|
-
...args.personalityName !== void 0 ? { personalityName: args.personalityName } : {}
|
|
8512
|
+
...args.personalityName !== void 0 ? { personalityName: args.personalityName } : {},
|
|
8513
|
+
...args.steerQueue !== void 0 ? { steerQueue: args.steerQueue } : {}
|
|
8169
8514
|
};
|
|
8170
8515
|
}
|
|
8171
8516
|
async function createFixtureRunHelper(args) {
|
|
@@ -8197,6 +8542,7 @@ async function dispatchLocalRun(args) {
|
|
|
8197
8542
|
systemPrompt: args.systemPrompt,
|
|
8198
8543
|
priorMessages: args.priorMessages,
|
|
8199
8544
|
memoryTools: args.memoryTools,
|
|
8545
|
+
...args.steerQueue !== void 0 ? { steerQueue: args.steerQueue } : {},
|
|
8200
8546
|
...args.activePreset?.tools !== void 0 ? { personalityToolWhitelist: args.activePreset.tools } : {},
|
|
8201
8547
|
...args.activePreset !== void 0 ? { personalityName: args.activePreset.name } : {}
|
|
8202
8548
|
})
|
|
@@ -8249,177 +8595,6 @@ async function consumePending(agentId, pending, clear, refresh) {
|
|
|
8249
8595
|
await applyDeferredInvalidation(agentId, pending, refresh);
|
|
8250
8596
|
}
|
|
8251
8597
|
|
|
8252
|
-
// src/internal/runtime/registry/live-agent-registry.ts
|
|
8253
|
-
var DEFAULT_MAX_AGENTS = 100;
|
|
8254
|
-
var DEFAULT_IDLE_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
8255
|
-
var DEFAULT_SWEEP_INTERVAL_MS = 6e4;
|
|
8256
|
-
var LiveAgentRegistry = class {
|
|
8257
|
-
#agents = /* @__PURE__ */ new Map();
|
|
8258
|
-
#maxAgents = DEFAULT_MAX_AGENTS;
|
|
8259
|
-
#idleTimeoutMs = DEFAULT_IDLE_TIMEOUT_MS;
|
|
8260
|
-
#sweepIntervalMs = DEFAULT_SWEEP_INTERVAL_MS;
|
|
8261
|
-
#onEvict;
|
|
8262
|
-
#sweepTimer;
|
|
8263
|
-
/**
|
|
8264
|
-
* Reconfigure registry behavior. Process-wide singleton (D310) — last
|
|
8265
|
-
* configure call wins for all subsequent operations.
|
|
8266
|
-
*/
|
|
8267
|
-
configure(opts) {
|
|
8268
|
-
if (opts.maxAgents !== void 0) this.#maxAgents = Math.max(0, opts.maxAgents);
|
|
8269
|
-
if (opts.idleTimeoutMs !== void 0) this.#idleTimeoutMs = Math.max(0, opts.idleTimeoutMs);
|
|
8270
|
-
if (opts.sweepIntervalMs !== void 0)
|
|
8271
|
-
this.#sweepIntervalMs = Math.max(1e3, opts.sweepIntervalMs);
|
|
8272
|
-
this.#onEvict = opts.onEvict;
|
|
8273
|
-
this.#stopSweep();
|
|
8274
|
-
if (this.#idleTimeoutMs > 0) this.#startSweep();
|
|
8275
|
-
}
|
|
8276
|
-
/**
|
|
8277
|
-
* Lookup a cached agent. `get` is a use — refreshes `lastUsedAt` so the
|
|
8278
|
-
* entry survives LRU eviction.
|
|
8279
|
-
*/
|
|
8280
|
-
get(id) {
|
|
8281
|
-
const entry = this.#agents.get(id);
|
|
8282
|
-
if (entry === void 0) return void 0;
|
|
8283
|
-
entry.lastUsedAt = Date.now();
|
|
8284
|
-
return entry.agent;
|
|
8285
|
-
}
|
|
8286
|
-
/**
|
|
8287
|
-
* Insert or overwrite an agent in the cache. Triggers fire-and-forget LRU
|
|
8288
|
-
* eviction when `size > maxAgents`.
|
|
8289
|
-
*
|
|
8290
|
-
* EC-4: when `id` already maps to a DIFFERENT agent instance, dispose the
|
|
8291
|
-
* old one before overwriting (race protection against two `getOrCreate`
|
|
8292
|
-
* calls creating two agents but only the second being cached — the first
|
|
8293
|
-
* would leak file handles + lifecycle controllers).
|
|
8294
|
-
*/
|
|
8295
|
-
set(id, agent) {
|
|
8296
|
-
if (this.#maxAgents === 0) return;
|
|
8297
|
-
const existing = this.#agents.get(id);
|
|
8298
|
-
if (existing !== void 0 && existing.agent !== agent) {
|
|
8299
|
-
void existing.agent.dispose().catch(() => {
|
|
8300
|
-
diag(`[theokit-sdk] dispose during overwrite failed (${id})
|
|
8301
|
-
`);
|
|
8302
|
-
});
|
|
8303
|
-
}
|
|
8304
|
-
this.#agents.set(id, { agent, lastUsedAt: Date.now() });
|
|
8305
|
-
if (this.#agents.size > this.#maxAgents) void this.#evictLRU();
|
|
8306
|
-
}
|
|
8307
|
-
/**
|
|
8308
|
-
* Remove the entry from the cache WITHOUT calling `dispose()` or
|
|
8309
|
-
* `onEvict`. Used by `LocalAgent.dispose()` itself so the disposed
|
|
8310
|
-
* instance can never be returned by a subsequent `get(id)` (dispose-cache
|
|
8311
|
-
* race fix). Idempotent — calling on an unknown id is a no-op.
|
|
8312
|
-
*
|
|
8313
|
-
* @internal
|
|
8314
|
-
*/
|
|
8315
|
-
forget(id) {
|
|
8316
|
-
this.#agents.delete(id);
|
|
8317
|
-
}
|
|
8318
|
-
/**
|
|
8319
|
-
* Explicitly evict an agent by id. Returns `true` when the entry was
|
|
8320
|
-
* present (false = already gone). Calls `agent.dispose()` + `onEvict`
|
|
8321
|
-
* with reason `"explicit"`.
|
|
8322
|
-
*/
|
|
8323
|
-
async evict(id) {
|
|
8324
|
-
const entry = this.#agents.get(id);
|
|
8325
|
-
if (entry === void 0) return false;
|
|
8326
|
-
this.#agents.delete(id);
|
|
8327
|
-
await this.#disposeAndNotify(id, entry.agent, "explicit");
|
|
8328
|
-
return true;
|
|
8329
|
-
}
|
|
8330
|
-
/**
|
|
8331
|
-
* Evict every cached agent. Used by graceful shutdown (`process.on('SIGTERM')`)
|
|
8332
|
-
* or end-of-test cleanup.
|
|
8333
|
-
*/
|
|
8334
|
-
async evictAll() {
|
|
8335
|
-
const entries = Array.from(this.#agents.entries());
|
|
8336
|
-
this.#agents.clear();
|
|
8337
|
-
this.#stopSweep();
|
|
8338
|
-
for (const [id, entry] of entries) {
|
|
8339
|
-
await this.#disposeAndNotify(id, entry.agent, "explicit");
|
|
8340
|
-
}
|
|
8341
|
-
}
|
|
8342
|
-
/** Number of currently cached agents. */
|
|
8343
|
-
size() {
|
|
8344
|
-
return this.#agents.size;
|
|
8345
|
-
}
|
|
8346
|
-
/** Ids of cached agents, newest first (by lastUsedAt). */
|
|
8347
|
-
ids() {
|
|
8348
|
-
return Array.from(this.#agents.entries()).sort((a, b) => b[1].lastUsedAt - a[1].lastUsedAt).map(([id]) => id);
|
|
8349
|
-
}
|
|
8350
|
-
/**
|
|
8351
|
-
* LRU eviction: drop the entry with the smallest `lastUsedAt`. Runs only
|
|
8352
|
-
* when `size > maxAgents`. Asynchronous because `dispose()` is a Promise;
|
|
8353
|
-
* the hot-path caller (`set`) does not await.
|
|
8354
|
-
*
|
|
8355
|
-
* @internal
|
|
8356
|
-
*/
|
|
8357
|
-
async #evictLRU() {
|
|
8358
|
-
if (this.#agents.size <= this.#maxAgents) return;
|
|
8359
|
-
let oldestId;
|
|
8360
|
-
let oldestAt = Infinity;
|
|
8361
|
-
for (const [id, entry2] of this.#agents) {
|
|
8362
|
-
if (entry2.lastUsedAt < oldestAt) {
|
|
8363
|
-
oldestAt = entry2.lastUsedAt;
|
|
8364
|
-
oldestId = id;
|
|
8365
|
-
}
|
|
8366
|
-
}
|
|
8367
|
-
if (oldestId === void 0) return;
|
|
8368
|
-
const entry = this.#agents.get(oldestId);
|
|
8369
|
-
if (entry === void 0) return;
|
|
8370
|
-
this.#agents.delete(oldestId);
|
|
8371
|
-
await this.#disposeAndNotify(oldestId, entry.agent, "lru");
|
|
8372
|
-
}
|
|
8373
|
-
/** Background sweep — drops entries whose `lastUsedAt < now - idleTimeoutMs`. */
|
|
8374
|
-
async #sweepIdle() {
|
|
8375
|
-
if (this.#idleTimeoutMs === 0) return;
|
|
8376
|
-
const threshold = Date.now() - this.#idleTimeoutMs;
|
|
8377
|
-
const toEvict = [];
|
|
8378
|
-
for (const [id, entry] of this.#agents) {
|
|
8379
|
-
if (entry.lastUsedAt < threshold) toEvict.push([id, entry]);
|
|
8380
|
-
}
|
|
8381
|
-
for (const [id, entry] of toEvict) {
|
|
8382
|
-
const current = this.#agents.get(id);
|
|
8383
|
-
if (current === void 0 || current.agent !== entry.agent) continue;
|
|
8384
|
-
this.#agents.delete(id);
|
|
8385
|
-
await this.#disposeAndNotify(id, entry.agent, "idle");
|
|
8386
|
-
}
|
|
8387
|
-
}
|
|
8388
|
-
#startSweep() {
|
|
8389
|
-
this.#sweepTimer = setInterval(() => void this.#sweepIdle(), this.#sweepIntervalMs);
|
|
8390
|
-
this.#sweepTimer.unref?.();
|
|
8391
|
-
}
|
|
8392
|
-
#stopSweep() {
|
|
8393
|
-
if (this.#sweepTimer !== void 0) {
|
|
8394
|
-
clearInterval(this.#sweepTimer);
|
|
8395
|
-
this.#sweepTimer = void 0;
|
|
8396
|
-
}
|
|
8397
|
-
}
|
|
8398
|
-
/** Dispose + notify with errors swallowed (D309). Single chokepoint. */
|
|
8399
|
-
async #disposeAndNotify(id, agent, reason) {
|
|
8400
|
-
try {
|
|
8401
|
-
await agent.dispose();
|
|
8402
|
-
} catch (cause) {
|
|
8403
|
-
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
8404
|
-
diag(`[theokit-sdk] dispose during eviction failed (${id}): ${msg}
|
|
8405
|
-
`);
|
|
8406
|
-
}
|
|
8407
|
-
if (this.#onEvict !== void 0) {
|
|
8408
|
-
try {
|
|
8409
|
-
this.#onEvict(id, reason);
|
|
8410
|
-
} catch (cause) {
|
|
8411
|
-
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
8412
|
-
diag(`[theokit-sdk] onEvict listener threw (${id}): ${msg}
|
|
8413
|
-
`);
|
|
8414
|
-
}
|
|
8415
|
-
}
|
|
8416
|
-
}
|
|
8417
|
-
};
|
|
8418
|
-
var liveAgentRegistry = globalSingleton(
|
|
8419
|
-
"theokit-sdk.runtime.live-agents",
|
|
8420
|
-
() => new LiveAgentRegistry()
|
|
8421
|
-
);
|
|
8422
|
-
|
|
8423
8598
|
// src/internal/local-agent/local-agent-lifecycle.ts
|
|
8424
8599
|
async function acquireLeaseIfPossible(store, agentId) {
|
|
8425
8600
|
if (typeof store.acquire !== "function") return;
|
|
@@ -10138,6 +10313,14 @@ async function applyInputProcessors(inputs, message, rawUserText, options, sendM
|
|
|
10138
10313
|
const effectiveMessage = typeof message === "string" ? res.value : { ...message, text: res.value };
|
|
10139
10314
|
return { userText: res.value, effectiveMessage };
|
|
10140
10315
|
}
|
|
10316
|
+
var lastSendAt = /* @__PURE__ */ new Map();
|
|
10317
|
+
function applyIdleReset(agentId, minutes) {
|
|
10318
|
+
const now = Date.now();
|
|
10319
|
+
const previous = lastSendAt.get(agentId);
|
|
10320
|
+
lastSendAt.set(agentId, now);
|
|
10321
|
+
if (minutes === void 0 || !Number.isFinite(minutes) || minutes <= 0) return;
|
|
10322
|
+
if (previous !== void 0 && now - previous > minutes * 6e4) clearSession(agentId);
|
|
10323
|
+
}
|
|
10141
10324
|
async function executeSendLocked(inputs, message, options) {
|
|
10142
10325
|
if (inputs.disposed) throw new AgentDisposedError(inputs.agentId);
|
|
10143
10326
|
await consumePending(
|
|
@@ -10152,6 +10335,7 @@ async function executeSendLocked(inputs, message, options) {
|
|
|
10152
10335
|
const gated = await applyInputProcessors(inputs, message, rawUserText, options, sendModel);
|
|
10153
10336
|
if ("tripwireRun" in gated) return gated.tripwireRun;
|
|
10154
10337
|
const { userText, effectiveMessage } = gated;
|
|
10338
|
+
applyIdleReset(inputs.agentId, inputs.options.sessionIdleResetMinutes);
|
|
10155
10339
|
if (inputs.options.onBeforeSend !== void 0) {
|
|
10156
10340
|
await inputs.options.onBeforeSend({
|
|
10157
10341
|
conversationId: inputs.agentId,
|
|
@@ -10337,6 +10521,43 @@ function reportUnknownLocalOptions(local) {
|
|
|
10337
10521
|
}
|
|
10338
10522
|
}
|
|
10339
10523
|
|
|
10524
|
+
// src/internal/local-agent/send-queue.ts
|
|
10525
|
+
var TurnSteerQueue = class {
|
|
10526
|
+
pending = [];
|
|
10527
|
+
closed = false;
|
|
10528
|
+
/** @returns false when the turn can no longer pick the message up. */
|
|
10529
|
+
push(text) {
|
|
10530
|
+
if (this.closed) return false;
|
|
10531
|
+
this.pending.push(text);
|
|
10532
|
+
return true;
|
|
10533
|
+
}
|
|
10534
|
+
drain() {
|
|
10535
|
+
const taken = this.pending;
|
|
10536
|
+
this.pending = [];
|
|
10537
|
+
return taken;
|
|
10538
|
+
}
|
|
10539
|
+
drainOrClose() {
|
|
10540
|
+
const taken = this.drain();
|
|
10541
|
+
if (taken.length === 0) this.closed = true;
|
|
10542
|
+
return taken;
|
|
10543
|
+
}
|
|
10544
|
+
/** Stop accepting and hand back what no loop iteration picked up. */
|
|
10545
|
+
closeAndTake() {
|
|
10546
|
+
this.closed = true;
|
|
10547
|
+
return this.drain();
|
|
10548
|
+
}
|
|
10549
|
+
};
|
|
10550
|
+
function joinCollected(messages) {
|
|
10551
|
+
if (messages.length === 1) return messages[0];
|
|
10552
|
+
const texts = messages.map((m) => typeof m === "string" ? m : m.text);
|
|
10553
|
+
const images = messages.flatMap((m) => typeof m === "string" ? [] : m.images ?? []);
|
|
10554
|
+
const text = texts.join("\n\n");
|
|
10555
|
+
return images.length > 0 ? { text, images } : text;
|
|
10556
|
+
}
|
|
10557
|
+
function hasImages(message) {
|
|
10558
|
+
return typeof message !== "string" && (message.images?.length ?? 0) > 0;
|
|
10559
|
+
}
|
|
10560
|
+
|
|
10340
10561
|
// src/internal/local-agent/local-agent.ts
|
|
10341
10562
|
var LocalAgent = class {
|
|
10342
10563
|
/**
|
|
@@ -10385,6 +10606,9 @@ var LocalAgent = class {
|
|
|
10385
10606
|
settingSourcesIncludePlugins;
|
|
10386
10607
|
resolvedSubagents = {};
|
|
10387
10608
|
disposed = false;
|
|
10609
|
+
activeTurn;
|
|
10610
|
+
inflight = 0;
|
|
10611
|
+
collectBatch;
|
|
10388
10612
|
invalidationPending;
|
|
10389
10613
|
skillsManager;
|
|
10390
10614
|
pluginsManager;
|
|
@@ -10509,10 +10733,48 @@ var LocalAgent = class {
|
|
|
10509
10733
|
agentId: this.agentId,
|
|
10510
10734
|
...this.model?.id !== void 0 ? { model: this.model.id } : {}
|
|
10511
10735
|
});
|
|
10736
|
+
return this.enqueueSend(message, options, sendSpan);
|
|
10737
|
+
}
|
|
10738
|
+
/** Queue one send behind the lock, or fold it into the running turn / pending batch. */
|
|
10739
|
+
enqueueSend(message, options, sendSpan) {
|
|
10740
|
+
const mode = options.queueMode ?? "followup";
|
|
10741
|
+
const text = typeof message === "string" ? message : message.text;
|
|
10742
|
+
const active = this.activeTurn;
|
|
10743
|
+
if (mode === "steer" && active !== void 0 && !hasImages(message) && active.steer.push(text)) {
|
|
10744
|
+
sendSpan.end();
|
|
10745
|
+
return active.run;
|
|
10746
|
+
}
|
|
10747
|
+
if (mode === "collect" && this.collectBatch !== void 0) {
|
|
10748
|
+
this.collectBatch.messages.push(message);
|
|
10749
|
+
sendSpan.end();
|
|
10750
|
+
return this.collectBatch.run;
|
|
10751
|
+
}
|
|
10752
|
+
const key = `agent-send:${this.agentId}`;
|
|
10753
|
+
this.inflight += 1;
|
|
10754
|
+
const release = () => {
|
|
10755
|
+
this.inflight -= 1;
|
|
10756
|
+
};
|
|
10757
|
+
if (mode === "collect" && this.inflight > 1) {
|
|
10758
|
+
const messages = [message];
|
|
10759
|
+
const run = new Promise((resolve, reject) => {
|
|
10760
|
+
void withCwdMutex(key, () => {
|
|
10761
|
+
this.collectBatch = void 0;
|
|
10762
|
+
return this.runLockedSendCycle(
|
|
10763
|
+
joinCollected(messages),
|
|
10764
|
+
options,
|
|
10765
|
+
sendSpan,
|
|
10766
|
+
resolve,
|
|
10767
|
+
reject
|
|
10768
|
+
).finally(release);
|
|
10769
|
+
});
|
|
10770
|
+
});
|
|
10771
|
+
this.collectBatch = { messages, run };
|
|
10772
|
+
return run;
|
|
10773
|
+
}
|
|
10512
10774
|
return new Promise((resolve, reject) => {
|
|
10513
10775
|
void withCwdMutex(
|
|
10514
|
-
|
|
10515
|
-
() => this.runLockedSendCycle(message, options, sendSpan, resolve, reject)
|
|
10776
|
+
key,
|
|
10777
|
+
() => this.runLockedSendCycle(message, options, sendSpan, resolve, reject).finally(release)
|
|
10516
10778
|
);
|
|
10517
10779
|
});
|
|
10518
10780
|
}
|
|
@@ -10528,20 +10790,40 @@ var LocalAgent = class {
|
|
|
10528
10790
|
const declared = this.model?.contextWindow;
|
|
10529
10791
|
return declared !== void 0 ? { contextWindow: declared } : {};
|
|
10530
10792
|
}
|
|
10793
|
+
/** A steered message the loop never picked up (run errored, was cancelled) still gets answered. */
|
|
10794
|
+
followUpUnsteered(leftover) {
|
|
10795
|
+
if (leftover.length === 0) return;
|
|
10796
|
+
this.send(leftover.join("\n\n")).catch(
|
|
10797
|
+
(err) => diagFailure(`[theokit-sdk] steered message followup failed: ${String(err)}`)
|
|
10798
|
+
);
|
|
10799
|
+
}
|
|
10531
10800
|
async runLockedSendCycle(message, options, sendSpan, resolve, reject) {
|
|
10532
10801
|
const userText = typeof message === "string" ? message : message.text;
|
|
10533
10802
|
let run;
|
|
10803
|
+
const steer = new TurnSteerQueue();
|
|
10804
|
+
let res = () => void 0;
|
|
10805
|
+
let rej = () => void 0;
|
|
10806
|
+
const turnRun = new Promise((a, b) => {
|
|
10807
|
+
res = a;
|
|
10808
|
+
rej = b;
|
|
10809
|
+
});
|
|
10810
|
+
turnRun.catch(() => void 0);
|
|
10811
|
+
this.activeTurn = { steer, run: turnRun };
|
|
10534
10812
|
try {
|
|
10535
10813
|
run = await this.sendLocked(message, options);
|
|
10536
10814
|
} catch (err) {
|
|
10537
10815
|
sendSpan.recordException(err);
|
|
10538
10816
|
sendSpan.setStatus({ code: 2, message: err instanceof Error ? err.message : String(err) });
|
|
10539
10817
|
sendSpan.end();
|
|
10818
|
+
this.activeTurn = void 0;
|
|
10819
|
+
rej(err);
|
|
10540
10820
|
reject(err);
|
|
10541
10821
|
return;
|
|
10542
10822
|
}
|
|
10543
10823
|
if (options.task !== void 0) registerRunAsTask(run, this.agentId, options.task, userText);
|
|
10544
|
-
|
|
10824
|
+
const view = callerView(run, this.options.throwOnError);
|
|
10825
|
+
res(view);
|
|
10826
|
+
resolve(view);
|
|
10545
10827
|
try {
|
|
10546
10828
|
await runPostRunLifecycle({
|
|
10547
10829
|
run,
|
|
@@ -10565,6 +10847,8 @@ var LocalAgent = class {
|
|
|
10565
10847
|
});
|
|
10566
10848
|
} finally {
|
|
10567
10849
|
sendSpan.end();
|
|
10850
|
+
this.activeTurn = void 0;
|
|
10851
|
+
this.followUpUnsteered(steer.closeAndTake());
|
|
10568
10852
|
}
|
|
10569
10853
|
}
|
|
10570
10854
|
async sendLocked(message, options) {
|
|
@@ -10672,11 +10956,13 @@ var LocalAgent = class {
|
|
|
10672
10956
|
memoryFacts,
|
|
10673
10957
|
priorMessages,
|
|
10674
10958
|
memoryTools,
|
|
10675
|
-
activePreset: this.activePreset()
|
|
10959
|
+
activePreset: this.activePreset(),
|
|
10960
|
+
...this.activeTurn !== void 0 ? { steerQueue: this.activeTurn.steer } : {}
|
|
10676
10961
|
});
|
|
10677
10962
|
}
|
|
10678
10963
|
close() {
|
|
10679
10964
|
this.disposed = true;
|
|
10965
|
+
liveAgentRegistry.forget(this.agentId);
|
|
10680
10966
|
}
|
|
10681
10967
|
async reload() {
|
|
10682
10968
|
this.resolvedSubagents = await reloadLocalAgent(this);
|
|
@@ -11027,6 +11313,7 @@ function paginateByKey(all, keyOf, limit, cursor, sortByKey) {
|
|
|
11027
11313
|
|
|
11028
11314
|
// src/agent.ts
|
|
11029
11315
|
var streamObjectImport;
|
|
11316
|
+
var getOrCreateInFlight = /* @__PURE__ */ new Map();
|
|
11030
11317
|
var Agent = class _Agent {
|
|
11031
11318
|
constructor() {
|
|
11032
11319
|
}
|
|
@@ -11211,7 +11498,7 @@ var Agent = class _Agent {
|
|
|
11211
11498
|
* @public
|
|
11212
11499
|
*/
|
|
11213
11500
|
static async batch(prompts, options) {
|
|
11214
|
-
const { batchImpl } = await import('./batch-
|
|
11501
|
+
const { batchImpl } = await import('./batch-N2XDYZED.js');
|
|
11215
11502
|
return batchImpl(prompts, options, { create: (opts) => _Agent.create(opts) });
|
|
11216
11503
|
}
|
|
11217
11504
|
/**
|
|
@@ -11241,18 +11528,27 @@ var Agent = class _Agent {
|
|
|
11241
11528
|
* The agent-builder's M85 interrupt rotates the session id to work around a
|
|
11242
11529
|
* constraint that does not exist.
|
|
11243
11530
|
*
|
|
11244
|
-
* - `close()` marks the handle disposed
|
|
11245
|
-
*
|
|
11246
|
-
* for that path.
|
|
11531
|
+
* - `close()` marks the handle disposed AND drops its cache entry, so the next call
|
|
11532
|
+
* builds a fresh handle.
|
|
11247
11533
|
*
|
|
11248
11534
|
* @public
|
|
11249
11535
|
*/
|
|
11250
11536
|
static async getOrCreate(agentId, options) {
|
|
11251
11537
|
const cached = _Agent.registry.get(agentId);
|
|
11252
11538
|
if (cached !== void 0) return cached;
|
|
11253
|
-
const
|
|
11254
|
-
|
|
11255
|
-
|
|
11539
|
+
const inFlight = getOrCreateInFlight.get(agentId);
|
|
11540
|
+
if (inFlight !== void 0) return inFlight;
|
|
11541
|
+
const build = (async () => {
|
|
11542
|
+
const fresh = await getOrCreateUncached(agentId, options);
|
|
11543
|
+
_Agent.registry.set(agentId, fresh);
|
|
11544
|
+
return fresh;
|
|
11545
|
+
})();
|
|
11546
|
+
getOrCreateInFlight.set(agentId, build);
|
|
11547
|
+
try {
|
|
11548
|
+
return await build;
|
|
11549
|
+
} finally {
|
|
11550
|
+
if (getOrCreateInFlight.get(agentId) === build) getOrCreateInFlight.delete(agentId);
|
|
11551
|
+
}
|
|
11256
11552
|
}
|
|
11257
11553
|
/**
|
|
11258
11554
|
* List agents (local or cloud). M107 — `cwd` is READ, not ignored. B-115 (2026-08-19) —
|
|
@@ -11363,7 +11659,7 @@ var Agent = class _Agent {
|
|
|
11363
11659
|
*/
|
|
11364
11660
|
static async compact(agentId, options = {}) {
|
|
11365
11661
|
const reg = await requireLocalAgent(agentId, "compact");
|
|
11366
|
-
const { compactSessionTranscript, buildDefaultSummarizer: buildDefaultSummarizer2 } = await import('./compact-session-
|
|
11662
|
+
const { compactSessionTranscript, buildDefaultSummarizer: buildDefaultSummarizer2 } = await import('./compact-session-Q5IGNFPW.js');
|
|
11367
11663
|
const { cwd, model, store } = await openLocalStore(reg);
|
|
11368
11664
|
return enqueueSessionWrite(
|
|
11369
11665
|
cwd,
|
|
@@ -11393,7 +11689,7 @@ var Agent = class _Agent {
|
|
|
11393
11689
|
*/
|
|
11394
11690
|
static async injectSessionTurn(agentId, turn) {
|
|
11395
11691
|
const reg = await requireLocalAgent(agentId, "injectSessionTurn");
|
|
11396
|
-
const { injectSessionTurn } = await import('./inject-session-
|
|
11692
|
+
const { injectSessionTurn } = await import('./inject-session-4ROYLZHY.js');
|
|
11397
11693
|
const { cwd, model, store } = await openLocalStore(reg);
|
|
11398
11694
|
await injectSessionTurn({
|
|
11399
11695
|
store,
|
|
@@ -11444,7 +11740,7 @@ var Agent = class _Agent {
|
|
|
11444
11740
|
*/
|
|
11445
11741
|
static async describe(agentId) {
|
|
11446
11742
|
const agent = await getRegisteredAgentOrThrow(agentId);
|
|
11447
|
-
const { loadSubagents: loadSubagents2 } = await import('./subagents-loader-
|
|
11743
|
+
const { loadSubagents: loadSubagents2 } = await import('./subagents-loader-SXETS2F2.js');
|
|
11448
11744
|
const settingSources = agent.options.local?.settingSources;
|
|
11449
11745
|
const subagents = await loadSubagents2(
|
|
11450
11746
|
agent.cwd ?? process.cwd(),
|
|
@@ -11543,7 +11839,9 @@ async function openLocalStore(reg) {
|
|
|
11543
11839
|
const cwd = reg.cwd ?? process.cwd();
|
|
11544
11840
|
const optModel = reg.options.model;
|
|
11545
11841
|
const model = reg.model?.id ?? (typeof optModel === "string" ? optModel : optModel?.id) ?? "unknown";
|
|
11546
|
-
const
|
|
11842
|
+
const injected = reg.options.local?.sessionStore;
|
|
11843
|
+
if (injected !== void 0) return { cwd, model, store: injected };
|
|
11844
|
+
const { FsSessionStore: FsSessionStore2 } = await import('./fs-session-store-MYQEVUFL.js');
|
|
11547
11845
|
const { defaultBaseDir: defaultBaseDir2, expandTilde: expandTilde2 } = await import('./session-transcript-BSHZYYY6.js');
|
|
11548
11846
|
const configuredSessionDir = reg.options.local?.sessionDir ?? reg.options.local?.baseDir;
|
|
11549
11847
|
const baseDir = configuredSessionDir !== void 0 ? expandTilde2(configuredSessionDir) : defaultBaseDir2();
|
|
@@ -11551,5 +11849,5 @@ async function openLocalStore(reg) {
|
|
|
11551
11849
|
}
|
|
11552
11850
|
|
|
11553
11851
|
export { Agent, AgentBuilder, DEFAULT_AGENTIC_MODEL_ID, MEMORY_EMBEDDING_ADAPTERS, Tool, ToolError, UsageAccumulator, computeCost, generateCronId, getPricingEntry, managedSettingsPathFor, openRouterMemoryEmbeddingProviderAdapter, readManagedSettings, resolveSessionDir };
|
|
11554
|
-
//# sourceMappingURL=chunk-
|
|
11555
|
-
//# sourceMappingURL=chunk-
|
|
11852
|
+
//# sourceMappingURL=chunk-5M5GQYBM.js.map
|
|
11853
|
+
//# sourceMappingURL=chunk-5M5GQYBM.js.map
|