@theokit/sdk 4.52.1 → 4.53.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 +40 -0
- package/dist/{agent-U2R2R5JP.cjs → agent-JX5SBYDE.cjs} +13 -12
- package/dist/{agent-U2R2R5JP.cjs.map → agent-JX5SBYDE.cjs.map} +1 -1
- package/dist/{agent-RDHK6MVT.js → agent-ZAGG6ZBS.js} +12 -11
- package/dist/{agent-RDHK6MVT.js.map → agent-ZAGG6ZBS.js.map} +1 -1
- package/dist/auth/index.cjs +26 -25
- package/dist/auth/index.cjs.map +1 -1
- package/dist/auth/index.js +3 -2
- package/dist/auth/index.js.map +1 -1
- package/dist/chunk-23VZBRDQ.js +147 -0
- package/dist/chunk-23VZBRDQ.js.map +1 -0
- package/dist/{chunk-CY7MIMI4.cjs → chunk-2QMK627M.cjs} +3 -3
- package/dist/{chunk-CY7MIMI4.cjs.map → chunk-2QMK627M.cjs.map} +1 -1
- package/dist/{chunk-6GS7JI64.cjs → chunk-2VFZQEDW.cjs} +56 -56
- package/dist/{chunk-6GS7JI64.cjs.map → chunk-2VFZQEDW.cjs.map} +1 -1
- package/dist/{chunk-M5EK7N6R.js → chunk-2Y5NO2SY.js} +4 -4
- package/dist/{chunk-M5EK7N6R.js.map → chunk-2Y5NO2SY.js.map} +1 -1
- package/dist/{chunk-V2EJLKGA.js → chunk-2YWWPCGX.js} +4 -3
- package/dist/chunk-2YWWPCGX.js.map +1 -0
- package/dist/chunk-33L2NVTJ.cjs +177 -0
- package/dist/chunk-33L2NVTJ.cjs.map +1 -0
- package/dist/{chunk-GNPI5IWZ.js → chunk-3SHW7XKK.js} +3 -3
- package/dist/{chunk-GNPI5IWZ.js.map → chunk-3SHW7XKK.js.map} +1 -1
- package/dist/{chunk-J4RY5DTI.js → chunk-634YVZLU.js} +3 -3
- package/dist/{chunk-J4RY5DTI.js.map → chunk-634YVZLU.js.map} +1 -1
- package/dist/{chunk-T6ZCG5AP.cjs → chunk-BC5EUG7R.cjs} +7 -6
- package/dist/chunk-BC5EUG7R.cjs.map +1 -0
- package/dist/{chunk-WLESQ3ZQ.cjs → chunk-DM6Y5B2G.cjs} +21 -21
- package/dist/{chunk-WLESQ3ZQ.cjs.map → chunk-DM6Y5B2G.cjs.map} +1 -1
- package/dist/{chunk-NACDF3PK.js → chunk-HTK54K2J.js} +3 -3
- package/dist/{chunk-SDJYLCJK.cjs.map → chunk-HTK54K2J.js.map} +1 -1
- package/dist/{chunk-42PLABFU.js → chunk-I5OTK2RP.js} +3 -3
- package/dist/{chunk-42PLABFU.js.map → chunk-I5OTK2RP.js.map} +1 -1
- package/dist/chunk-NUEL6RCZ.cjs +155 -0
- package/dist/chunk-NUEL6RCZ.cjs.map +1 -0
- package/dist/{chunk-KELIQH7K.js → chunk-NZOR3N4E.js} +11 -11
- package/dist/{chunk-KELIQH7K.js.map → chunk-NZOR3N4E.js.map} +1 -1
- package/dist/{chunk-ZNEE4WWQ.cjs → chunk-QN5N3ZVT.cjs} +5 -5
- package/dist/{chunk-ZNEE4WWQ.cjs.map → chunk-QN5N3ZVT.cjs.map} +1 -1
- package/dist/{chunk-OI6RHLGC.cjs → chunk-T5ZWI3MC.cjs} +5 -5
- package/dist/{chunk-OI6RHLGC.cjs.map → chunk-T5ZWI3MC.cjs.map} +1 -1
- package/dist/{chunk-SDJYLCJK.cjs → chunk-TR4V2LHV.cjs} +3 -3
- package/dist/chunk-TR4V2LHV.cjs.map +1 -0
- package/dist/chunk-XRI6DXPZ.js +171 -0
- package/dist/chunk-XRI6DXPZ.js.map +1 -0
- package/dist/{compact-session-FBVWO6B3.cjs → compact-session-6GKIS4SD.cjs} +15 -14
- package/dist/{compact-session-FBVWO6B3.cjs.map → compact-session-6GKIS4SD.cjs.map} +1 -1
- package/dist/{compact-session-XLXC2CZN.js → compact-session-EJ36VH5I.js} +7 -6
- package/dist/{compact-session-XLXC2CZN.js.map → compact-session-EJ36VH5I.js.map} +1 -1
- package/dist/cron.cjs +12 -11
- package/dist/cron.js +11 -10
- package/dist/eval.cjs +15 -14
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +11 -10
- package/dist/eval.js.map +1 -1
- package/dist/fs-session-store-LIKYT24K.js +10 -0
- package/dist/{fs-session-store-2TF3ZWMT.js.map → fs-session-store-LIKYT24K.js.map} +1 -1
- package/dist/{fs-session-store-TL4RJTXZ.cjs → fs-session-store-VXXDIBGM.cjs} +5 -5
- package/dist/{fs-session-store-TL4RJTXZ.cjs.map → fs-session-store-VXXDIBGM.cjs.map} +1 -1
- package/dist/index.cjs +42 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +13 -12
- package/dist/index.js.map +1 -1
- package/dist/{inject-session-UBAQ7I3G.cjs → inject-session-67SF65FC.cjs} +4 -4
- package/dist/{inject-session-UBAQ7I3G.cjs.map → inject-session-67SF65FC.cjs.map} +1 -1
- package/dist/{inject-session-UEH5MAKU.js → inject-session-HO7FYVCX.js} +3 -3
- package/dist/{inject-session-UEH5MAKU.js.map → inject-session-HO7FYVCX.js.map} +1 -1
- package/dist/internal/mcp/oauth.d.ts +1 -0
- package/dist/internal/mcp/token-storage.d.ts +1 -0
- package/dist/internal/persistence/index.cjs +6 -6
- package/dist/internal/persistence/index.js +1 -1
- package/dist/internal/persistence/transcript-ops.d.cts +6 -7
- package/dist/internal/persistence/transcript-ops.d.ts +6 -7
- package/dist/mcp-auth.cjs +299 -0
- package/dist/mcp-auth.cjs.map +1 -0
- package/dist/mcp-auth.d.cts +17 -0
- package/dist/mcp-auth.d.ts +17 -0
- package/dist/mcp-auth.js +292 -0
- package/dist/mcp-auth.js.map +1 -0
- package/dist/models.cjs +11 -10
- package/dist/models.cjs.map +1 -1
- package/dist/models.js +3 -2
- package/dist/models.js.map +1 -1
- package/dist/persistence.cjs +16 -7
- package/dist/persistence.cjs.map +1 -1
- package/dist/persistence.js +11 -2
- package/dist/persistence.js.map +1 -1
- package/package.json +11 -1
- package/dist/chunk-BKRTYDVN.js +0 -312
- package/dist/chunk-BKRTYDVN.js.map +0 -1
- package/dist/chunk-NACDF3PK.js.map +0 -1
- package/dist/chunk-T6ZCG5AP.cjs.map +0 -1
- package/dist/chunk-V2EJLKGA.js.map +0 -1
- package/dist/chunk-XK54DTRF.cjs +0 -325
- package/dist/chunk-XK54DTRF.cjs.map +0 -1
- package/dist/fs-session-store-2TF3ZWMT.js +0 -10
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/internal/auth/credential-store.ts"],"names":[],"mappings":"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","file":"chunk-23VZBRDQ.js","sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport {\n chmodSync,\n closeSync,\n fsyncSync,\n mkdirSync,\n openSync,\n readFileSync,\n renameSync,\n statSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { join } from \"node:path\";\n\nimport { z } from \"zod\";\n\nimport { AuthenticationError } from \"../../errors.js\";\n\n/**\n * M42 — the SDK credential store. Promoted DOWN from agent-builder's hardened `agents/lib/credentials.ts`\n * (M37), generalized from a closed `openrouter|anthropic|openai` union to an open `provider: string` and\n * driven by a caller-supplied {@link CredentialStoreConfig} (no hardcoded `.agent-builder`/`auth.json` /\n * `AGENT_BUILDER_HOME`). The security-critical file mechanics are ported VERBATIM (ADR D3 of the M42 plan):\n * atomic O_EXCL + rename + fsync write, 0700/0600 mode gates, `env` is always a PARAMETER (never an ambient\n * `process.env` read). Contract SHAPE adapted from OpenCode's provider `auth.loader` (MIT © 2025 opencode).\n *\n * The env-precedence + key-prefix-inference + declared-provider rungs of the agent-builder resolver are\n * APP POLICY and deliberately stay UP in the consumer; this module owns only the on-disk store + the\n * `api|oauth` discriminated union. See {@link resolveCredential} (SDK) for the store-read + refresh path.\n *\n * @internal\n */\nimport type {\n CredentialStoreConfig,\n StoredCredential,\n StoredOAuthCredential,\n} from \"./auth-types.js\";\n\n/** The store directory, honoring an optional `homeEnvVar` override. */\nexport function credentialHome(\n config: CredentialStoreConfig,\n env: Record<string, string | undefined> = {},\n): string {\n const override = config.homeEnvVar !== undefined ? env[config.homeEnvVar]?.trim() : undefined;\n return override !== undefined && override.length > 0\n ? override\n : join(config.home, config.dirName);\n}\n\n/** The credential file path inside the (possibly overridden) store directory. */\nexport function authFilePath(\n config: CredentialStoreConfig,\n env: Record<string, string | undefined> = {},\n): string {\n return join(credentialHome(config, env), config.fileName);\n}\n\n/**\n * A credential problem the caller can act on. Never carries the key value.\n *\n * M78 — this used to extend bare `Error`, which quietly disabled classification for the entire auth\n * path: `isTransientError` is `err instanceof TheokitAgentError && err.isRetryable === true`\n * (`errors.ts:443`), so a credential failure could never be judged transient OR permanent. The\n * predicate was not \"forgotten\" downstream — it was unusable there by construction.\n *\n * Extending `AuthenticationError` is ADDITIVE: the class still exists, still reports\n * `name: \"CredentialError\"`, and every existing `instanceof CredentialError` stays true. It only\n * gains ancestors. `AuthenticationError` pins `isRetryable: false`, so gaining the ability to be\n * classified does NOT turn a revoked credential into a retry loop.\n *\n * The single reference does the same thing with one root type: Codex routes every domain failure\n * through `CodexErr` with `is_retryable()` as a method (`protocol/src/error.rs:176`), rather than\n * parallel classes extending the language's `Error`.\n */\nexport class CredentialError extends AuthenticationError {\n // Field, not an assignment in the constructor: `AuthenticationError.name` is `override readonly`\n // (`errors.ts:174`), so `this.name = …` does not compile. Caught by `tsc`, not by vitest — the\n // suite was green with the broken assignment because the transpiler strips the type.\n override readonly name: string = \"CredentialError\";\n}\n\n/**\n * The on-disk store — a discriminated union on `type` (OpenCode `Info` shape). A legacy file with NO\n * `type` (or `type: 'api'`) is the API-key variant — read unchanged, no migration. The `oauth` variant\n * carries the token pair + expiry.\n */\nconst apiFileSchema = z\n .object({\n type: z.literal(\"api\").optional(),\n provider: z.string().min(1).optional(),\n api_key: z.string(),\n })\n .strict();\n\nconst oauthFileSchema = z\n .object({\n type: z.literal(\"oauth\"),\n provider: z.string().min(1),\n access: z.string().min(1),\n refresh: z.string().min(1),\n expires: z.number(),\n account_id: z.string().optional(),\n })\n .strict();\n\n// oauth first (it requires `type: 'oauth'`); a legacy `{provider?, api_key}` falls through to api.\nconst fileSchema = z.union([oauthFileSchema, apiFileSchema]);\n\n/**\n * Read the credential file. Absent ⇒ `undefined` (the normal case). Present-but-wrong is a typed error\n * naming the file: a malformed credential store must not surface as a raw parse crash. Enforces the\n * 0700 dir / 0600 file mode gates (ported verbatim — a writable dir lets an attacker swap the file for a\n * symlink to their own account).\n */\n/**\n * The 0700-dir / 0600-file mode gates (ported verbatim). The DIRECTORY matters as much as the file:\n * `mkdirSync(mode)` applies only at creation, so a pre-existing store dir keeps whatever mode it had, and a\n * writable dir lets an attacker replace the credential file with a symlink to their own 0600 file — the\n * agent then runs on THEIR account.\n */\nexport function assertSecureModes(dirPath: string, path: string): void {\n // Windows has no POSIX mode bits. `statSync().mode` there is SYNTHETIC — 0666 for any writable\n // entry, whatever the ACLs actually say — so `mode & 0o022` was non-zero for every valid store and\n // this gate refused all of them, which made the credential path unreadable on that platform\n // rather than protected. A check that cannot observe the real permission system must not report a\n // verdict about it; ACL enforcement is a separate mechanism and not one this function can fake.\n if (process.platform === \"win32\") return;\n\n const dirMode = statSync(dirPath).mode & 0o777;\n if ((dirMode & 0o022) !== 0) {\n throw new CredentialError(\n `${dirPath} is writable by other users (mode ${dirMode.toString(8)}), so the credential file ` +\n `inside it can be replaced. Fix it with: chmod 700 ${dirPath}`,\n );\n }\n const mode = statSync(path).mode & 0o777;\n if ((mode & 0o077) !== 0) {\n throw new CredentialError(\n `${path} is readable by other users (mode ${mode.toString(8)}). ` +\n `A credential file must not be. Fix it with: chmod 600 ${path}`,\n );\n }\n}\n\n/**\n * A `z.union` reports a generic \"Invalid input\" at the root, hiding WHAT is wrong. Pick the sub-schema the\n * file was CLEARLY aiming at (by its `type` discriminant) and surface that schema's specific issue.\n */\nfunction describeUnionError(parsed: unknown, err: unknown, path: string): CredentialError {\n const looksOAuth =\n typeof parsed === \"object\" &&\n parsed !== null &&\n (parsed as { type?: unknown }).type === \"oauth\";\n const specific = looksOAuth ? oauthFileSchema.safeParse(parsed) : apiFileSchema.safeParse(parsed);\n let issue: z.ZodIssue | undefined;\n if (!specific.success) {\n issue = specific.error.issues[0];\n } else if (err instanceof z.ZodError) {\n issue = err.issues[0];\n }\n return new CredentialError(\n `${path}: ${issue?.message ?? String(err)} [${issue?.path.join(\".\") || \"root\"}]`,\n );\n}\n\n/** Parse the raw file into the store union, surfacing the SPECIFIC sub-schema issue (not a generic union error). */\nfunction parseStoredFile(raw: string, path: string): StoredCredential {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n // The parser's message embeds a snippet of the INPUT — up to the raw key when a user pastes the bare\n // key instead of JSON. The position is not actionable anyway, so the expected shape is more useful.\n throw new CredentialError(\n `${path} is not valid JSON. Expected: {\"provider\": \"<name>\", \"api_key\": \"...\"}`,\n );\n }\n try {\n return fileSchema.parse(parsed);\n } catch (err) {\n throw describeUnionError(parsed, err, path);\n }\n}\n\nexport function readAuthFile(\n config: CredentialStoreConfig,\n env: Record<string, string | undefined> = {},\n): StoredCredential | undefined {\n const path = authFilePath(config, env);\n\n let raw: string;\n try {\n raw = readFileSync(path, \"utf8\");\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return undefined;\n throw new CredentialError(`cannot read ${path}: ${(err as Error).message}`);\n }\n\n assertSecureModes(credentialHome(config, env), path);\n return parseStoredFile(raw, path);\n}\n\n/**\n * Read the stored OAuth credential (with its refresh token), or `undefined` when the store is absent or\n * holds an api credential. The oauth engine needs the refresh token, which the resolved bearer does not\n * carry. Enforces the same 0600/0700 gates as every other read.\n */\nexport function readStoredOAuth(\n config: CredentialStoreConfig,\n env: Record<string, string | undefined> = {},\n): StoredOAuthCredential | undefined {\n const stored = readAuthFile(config, env);\n return stored !== undefined && stored.type === \"oauth\" ? stored : undefined;\n}\n\n/** Narrows a writable credential to the oauth variant. */\nfunction isOAuthWrite(\n c: { provider: string; apiKey: string } | StoredOAuthCredential,\n): c is StoredOAuthCredential {\n return \"type\" in c && c.type === \"oauth\";\n}\n\n/**\n * Persist a credential atomically at mode `0600`. Ported VERBATIM (ADR D3): write to a random-named temp\n * file in the same directory with `wx` (O_EXCL), fsync, close, chmod, then `rename` (atomic on POSIX) —\n * so a crash mid-write leaves whatever was there untouched, and a pre-planted symlink cannot capture the\n * key. The api variant persists the unchanged `{provider, api_key}` (back-compat, no `type` key); the\n * oauth variant persists `{type:'oauth', provider, access, refresh, expires, account_id?}`.\n */\n/** Build the on-disk JSON payload for the credential variant, validating non-empty tokens. */\nfunction buildStorePayload(\n cred: { provider: string; apiKey: string } | StoredOAuthCredential,\n): Record<string, unknown> {\n if (isOAuthWrite(cred)) {\n if (cred.access.length === 0 || cred.refresh.length === 0) {\n throw new CredentialError(\n \"refusing to write an oauth credential with an empty access/refresh token\",\n );\n }\n return {\n type: \"oauth\",\n provider: cred.provider,\n access: cred.access,\n refresh: cred.refresh,\n expires: cred.expires,\n ...(cred.account_id !== undefined ? { account_id: cred.account_id } : {}),\n };\n }\n if (typeof cred.apiKey !== \"string\" || cred.apiKey.length === 0) {\n throw new CredentialError(\"refusing to write an empty API key\");\n }\n return { provider: cred.provider, api_key: cred.apiKey };\n}\n\nexport function writeCredential(\n cred: { provider: string; apiKey: string } | StoredOAuthCredential,\n config: CredentialStoreConfig,\n env: Record<string, string | undefined> = {},\n): string {\n const payload = buildStorePayload(cred);\n\n const dir = credentialHome(config, env);\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n chmodSync(dir, 0o700); // unconditional: mkdirSync's mode applies only at creation\n\n const path = authFilePath(config, env);\n // RANDOM name + `wx` (O_EXCL): a predictable temp name with a plain write follows a pre-planted SYMLINK,\n // landing the key in an attacker's file while reporting success. O_EXCL refuses any pre-existing file or\n // link; the random suffix also removes the pid collision two containers sharing a bind-mounted home make.\n const tmp = `${path}.tmp-${randomBytes(8).toString(\"hex\")}`;\n try {\n const fd = openSync(tmp, \"wx\", 0o600);\n try {\n writeFileSync(fd, `${JSON.stringify(payload, null, 2)}\\n`);\n fsyncSync(fd);\n } finally {\n closeSync(fd);\n }\n chmodSync(tmp, 0o600); // explicit: the mode argument is subject to umask\n renameSync(tmp, path);\n } catch (err) {\n try {\n unlinkSync(tmp);\n } catch {\n // the temp file may not exist; its absence is not a failure of the write\n }\n throw new CredentialError(`cannot write ${path}: ${(err as Error).message}`);\n }\n return path;\n}\n"]}
|
|
@@ -48,7 +48,7 @@ function persistTurnToTranscript(store, loc, sessionId, turn, onCompact) {
|
|
|
48
48
|
const count = (recordCounts.get(key) ?? 0) + 1;
|
|
49
49
|
recordCounts.set(key, count);
|
|
50
50
|
if (turn.autoCompact !== void 0) {
|
|
51
|
-
const { autoCompactIfNeeded } = await import('./compact-session-
|
|
51
|
+
const { autoCompactIfNeeded } = await import('./compact-session-6GKIS4SD.cjs');
|
|
52
52
|
const fired = await autoCompactIfNeeded({
|
|
53
53
|
store,
|
|
54
54
|
loc,
|
|
@@ -114,5 +114,5 @@ exports.flushSessionWrites = flushSessionWrites;
|
|
|
114
114
|
exports.getSessionMessages = getSessionMessages;
|
|
115
115
|
exports.hydrateSession = hydrateSession;
|
|
116
116
|
exports.persistTurnToTranscript = persistTurnToTranscript;
|
|
117
|
-
//# sourceMappingURL=chunk-
|
|
118
|
-
//# sourceMappingURL=chunk-
|
|
117
|
+
//# sourceMappingURL=chunk-2QMK627M.cjs.map
|
|
118
|
+
//# sourceMappingURL=chunk-2QMK627M.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/session/agent-session.ts"],"names":["sessions","transcriptKey","hydratedKeys","persistTurn","diag","readSessionMessages"],"mappings":"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","file":"chunk-CY7MIMI4.cjs","sourcesContent":["import type { SessionStore } from \"../../types/session-store.js\";\nimport {\n type PersistTurnInput,\n persistTurn,\n readSessionMessages,\n type TranscriptLocation,\n} from \"./agent-session-store.js\";\n\n/**\n * Per-agent conversation history kept across runs (and across `Agent.resume()`\n * within the same process). Lets the fixture responder recall prior facts when\n * the user asks a follow-up question.\n *\n * SE40 — disk persistence IS the native Claude-shaped `.jsonl` transcript. The\n * in-memory cache holds the narrowed `SessionMessage[]` (user/assistant text) so\n * a send can read `priorMessages` synchronously; the whole rich turn (user +\n * assistant + tool blocks) lands on disk once per send via {@link persistTurnToTranscript}\n * (fed by `run.conversation()`). Hydration on resume reconstructs the session by\n * walking the transcript DAG (`readSessionMessages`).\n *\n * @internal\n */\n\n// `SessionMessage` lives in `./session-types.ts` (leaf types file). Re-exported\n// for back-compat with downstream importers that pulled it from here.\nexport type { SessionMessage } from \"./session-types.js\";\n\nimport type { SessionMessage } from \"./session-types.js\";\n\n// M75 — the cache lives in a leaf; see session-cache.ts for the reason (cycle broken by extraction).\nexport {\n hydratedKeys,\n invalidateSessionCache,\n sessions,\n transcriptKey,\n} from \"./session-cache.js\";\n\nimport { diag } from \"../diagnostics.js\";\nimport { hydratedKeys, sessions, transcriptKey } from \"./session-cache.js\";\n\nconst pendingWrites = new Map<string, Promise<void>>();\nconst recordCounts = new Map<string, number>();\n\n/**\n * Append a session message to the in-memory cache only. Disk persistence for the\n * whole turn happens once per send via {@link persistTurnToTranscript}; the cache\n * feeds `priorMessages` / `onBeforeSend.previousMessageCount` synchronously.\n *\n * @internal\n */\nexport function appendSessionMessage(agentId: string, message: SessionMessage): void {\n const existing = sessions.get(agentId) ?? [];\n existing.push(message);\n // `delete` + `set` reinserts at the END: a JS `Map` preserves insertion order, so the first key\n // is always the least recently touched. That is the entire LRU, with no new structure (parsimony\n // rungs 2/5 — the ordering we need is already a language guarantee).\n sessions.delete(agentId);\n sessions.set(agentId, existing);\n enforceCeiling();\n}\n\n/**\n * Ceiling on sessions kept in memory.\n *\n * The runtime only reads the **active** session; the rest is pure cache, rebuildable from the\n * on-disk transcript. 32 is deliberately generous — the primary removal path is the explicit\n * `discardSession()` at the end of the agent's life, and this ceiling is a safety net against a\n * long-lived process running hundreds of sessions (plan risk #2: a tight ceiling could evict a\n * session still referenced by an in-flight async path).\n */\nexport const MAX_CACHED_SESSIONS = 32;\n\nfunction enforceCeiling(): void {\n while (sessions.size > MAX_CACHED_SESSIONS) {\n const oldest = sessions.keys().next().value;\n if (oldest === undefined) return;\n sessions.delete(oldest);\n forgetBookkeeping(oldest);\n }\n}\n\n/**\n * Erases the bookkeeping for an `agentId` across EVERY `cwd` it appears in.\n *\n * The three maps are keyed by `transcriptKey(cwd, agentId)`; `sessions` is the only one keyed by the\n * raw `agentId`. The ceiling's first version deleted from all three using `sessions`' key — that is,\n * deleted nothing — and left `hydratedKeys` **orphaned**. Since `hydrateSession` returns early when\n * the marker is present, an evicted session came back **empty** instead of rehydrating from disk:\n * silent amnesia, and a regression new to M95, because before it nothing evicted.\n *\n * The ceiling only knows the `agentId`, not the `cwd`, so it scans by suffix — which is the format\n * `transcriptKey` produces. A scan rather than an index because these maps hold tens of entries, not\n * thousands: a reverse index here would be new structure for a problem that does not exist.\n */\nfunction forgetBookkeeping(agentId: string): void {\n const suffix = transcriptKey(\"\", agentId).slice(0 - agentId.length - 2);\n for (const k of [...hydratedKeys]) if (k.endsWith(suffix)) hydratedKeys.delete(k);\n for (const k of [...pendingWrites.keys()]) if (k.endsWith(suffix)) pendingWrites.delete(k);\n for (const k of [...recordCounts.keys()]) if (k.endsWith(suffix)) recordCounts.delete(k);\n}\n\n/**\n * Erases the agent's module bookkeeping and returns how many entries were removed.\n *\n * M95 — `invalidateSessionCache` used to clear **two** of the four maps (`sessions`, `hydratedKeys`);\n * `pendingWrites` and `recordCounts` were never touched by id, so they grew for the life of the\n * process. Neither is large per entry — the leak is in count, not volume — but a cache with no owner\n * for removal is a cache that only grows.\n *\n * Returns the count so the caller can prove the removal; a second discard returns 0, which is what\n * makes the idempotency test possible without exposing the maps.\n */\nexport function discardSession(cwd: string, agentId: string): number {\n const key = transcriptKey(cwd, agentId);\n let removed = 0;\n // `sessions` is NOT erased here — and the distinction is measured, not aesthetic. It holds the\n // readable conversation, and there is a legitimate reader AFTER dispose: the golden\n // `two-concurrent-sends-serialize` calls `getSessionMessages(agentId)` after `agent.dispose()`.\n // Erasing it here returned an empty list and broke two goldens. What bounds it is the LRU ceiling\n // above; the three below are pure bookkeeping, with no post-dispose reader.\n //\n // The key is `transcriptKey(cwd, agentId)` in ALL THREE — not the raw `agentId`. The first version\n // erased two of them by `agentId` and therefore **never erased anything**; the test did not catch\n // it because it only asserted that the SECOND call returns 0, which is true either way.\n if (hydratedKeys.delete(key)) removed++;\n if (pendingWrites.delete(key)) removed++;\n if (recordCounts.delete(key)) removed++;\n return removed;\n}\n\nexport function getSessionMessages(agentId: string): SessionMessage[] {\n return sessions.get(agentId) ?? [];\n}\n\n/**\n * Persist a full conversation turn (user + assistant + tool blocks) to the native\n * transcript. Chained per-(agent, transcript) so on-disk order matches send order,\n * and fire-and-forget so `send()` is not blocked by disk I/O. Every\n * M50 — when the caller supplies `turn.autoCompact`, size-driven auto-compaction (usage real vs\n * the model's context window) runs in this same chain, surfaced via the optional `onCompact` observer.\n *\n * @internal\n */\nexport function persistTurnToTranscript(\n store: SessionStore,\n loc: TranscriptLocation,\n sessionId: string,\n turn: PersistTurnInput,\n onCompact?: () => void,\n): void {\n const key = transcriptKey(loc.cwd, loc.agentId);\n // PRE-EXISTING debt, exposed when M75 fixed the Biome config that used to abort before\n // sweeping these files (a nested root under refactor/). It is not new code and was not touched\n // by M75; refactoring SDK internals without review would trade a visible problem for a diff\n // risky. Tracked in usetheodev/theokit-sdk#151.\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: see the reason just above\n const chained = (pendingWrites.get(key) ?? Promise.resolve()).then(async () => {\n try {\n await persistTurn(store, loc, sessionId, turn);\n const count = (recordCounts.get(key) ?? 0) + 1;\n recordCounts.set(key, count);\n // M50 — the 50-turn no-summary boundary stub is GONE (it silently amnesia'd the session).\n // Auto-compaction is now size-driven with a real summary: see `maybeAutoCompact` below,\n // invoked in this same write chain by the post-run lifecycle when usage is known.\n if (turn.autoCompact !== undefined) {\n const { autoCompactIfNeeded } = await import(\"./compact-session.js\");\n const fired = await autoCompactIfNeeded({\n store,\n loc,\n sessionId,\n usageTotal: turn.autoCompact.usageTotal,\n contextWindow: turn.autoCompact.contextWindow,\n turnCount: count,\n summarize: turn.autoCompact.summarize,\n });\n if (fired) onCompact?.();\n }\n } catch (cause) {\n const msg = cause instanceof Error ? cause.message : String(cause);\n diag(`[theokit-sdk] session transcript write failed (${loc.agentId}): ${msg}\\n`);\n }\n });\n pendingWrites.set(\n key,\n chained.then(\n () => undefined,\n () => undefined,\n ),\n );\n}\n\n/**\n * Load the persisted transcript into the in-memory cache. Idempotent per\n * (baseDir, cwd, agentId). Call once per agent lifecycle before the first read.\n *\n * @internal\n */\nexport async function hydrateSession(\n agentId: string,\n loc: { store: SessionStore; cwd: string },\n): Promise<void> {\n const key = transcriptKey(loc.cwd, agentId);\n if (hydratedKeys.has(key)) return;\n hydratedKeys.add(key);\n\n const persisted = await readSessionMessages(loc.store, agentId);\n if (persisted.length === 0) return;\n // M51 review F4 — the DISK is the source of truth at hydration time: after an invalidation\n // (compact/inject), an in-flight turn may have repopulated the cache with a SINGLE message before\n // this hydrate ran; the old \"skip when non-empty\" guard then pinned the parent to a 1-message\n // context (history + injected pair lost until restart). The persist chain serializes writes, so\n // the disk already contains that in-flight turn — replacing is always correct.\n sessions.set(agentId, persisted);\n}\n\n/**\n * Wait for all pending transcript writes to settle. Used by tests and by the\n * agent dispose path so on-disk state matches in-memory before the caller proceeds.\n *\n * @internal\n */\nexport async function flushSessionWrites(): Promise<void> {\n while (pendingWrites.size > 0) {\n const all = Array.from(pendingWrites.values());\n pendingWrites.clear();\n await Promise.all(all);\n }\n}\n\nexport function clearSession(agentId: string): void {\n sessions.delete(agentId);\n}\n\n/**\n * M50 review F1 — drop BOTH the message cache and the hydration marker so the NEXT send re-hydrates\n * from disk. Without this, a compaction only helps after a process restart: the live process keeps\n * sending the full pre-compact history (the cache is read synchronously by every send).\n */\n/**\n * M50 review F5 — run `fn` serialized on the SAME per-(cwd,agentId) write chain the per-turn\n * persistence uses, so a manual `Agent.compact` can never interleave with an in-flight turn's\n * writes (boundary landing mid-turn would orphan the turn from the replay).\n */\nexport function enqueueSessionWrite<T>(\n cwd: string,\n agentId: string,\n fn: () => Promise<T>,\n): Promise<T> {\n const key = transcriptKey(cwd, agentId);\n const prior = pendingWrites.get(key) ?? Promise.resolve();\n const result = prior.then(fn);\n pendingWrites.set(\n key,\n result.then(\n () => undefined,\n () => undefined,\n ),\n );\n return result;\n}\n\n/** Test-only: drop every cached session and hydration marker. @internal */\nexport function clearAllSessions(): void {\n sessions.clear();\n hydratedKeys.clear();\n recordCounts.clear();\n // M50 review F11 — the auto-compact attempt marks live on globalThis; tests reset them here.\n const g = globalThis as unknown as Record<symbol, Map<string, number>>;\n const sym = Symbol.for(\"theokit-sdk.session.auto-compact-attempts\");\n g[sym]?.clear();\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/session/agent-session.ts"],"names":["sessions","transcriptKey","hydratedKeys","persistTurn","diag","readSessionMessages"],"mappings":"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","file":"chunk-2QMK627M.cjs","sourcesContent":["import type { SessionStore } from \"../../types/session-store.js\";\nimport {\n type PersistTurnInput,\n persistTurn,\n readSessionMessages,\n type TranscriptLocation,\n} from \"./agent-session-store.js\";\n\n/**\n * Per-agent conversation history kept across runs (and across `Agent.resume()`\n * within the same process). Lets the fixture responder recall prior facts when\n * the user asks a follow-up question.\n *\n * SE40 — disk persistence IS the native Claude-shaped `.jsonl` transcript. The\n * in-memory cache holds the narrowed `SessionMessage[]` (user/assistant text) so\n * a send can read `priorMessages` synchronously; the whole rich turn (user +\n * assistant + tool blocks) lands on disk once per send via {@link persistTurnToTranscript}\n * (fed by `run.conversation()`). Hydration on resume reconstructs the session by\n * walking the transcript DAG (`readSessionMessages`).\n *\n * @internal\n */\n\n// `SessionMessage` lives in `./session-types.ts` (leaf types file). Re-exported\n// for back-compat with downstream importers that pulled it from here.\nexport type { SessionMessage } from \"./session-types.js\";\n\nimport type { SessionMessage } from \"./session-types.js\";\n\n// M75 — the cache lives in a leaf; see session-cache.ts for the reason (cycle broken by extraction).\nexport {\n hydratedKeys,\n invalidateSessionCache,\n sessions,\n transcriptKey,\n} from \"./session-cache.js\";\n\nimport { diag } from \"../diagnostics.js\";\nimport { hydratedKeys, sessions, transcriptKey } from \"./session-cache.js\";\n\nconst pendingWrites = new Map<string, Promise<void>>();\nconst recordCounts = new Map<string, number>();\n\n/**\n * Append a session message to the in-memory cache only. Disk persistence for the\n * whole turn happens once per send via {@link persistTurnToTranscript}; the cache\n * feeds `priorMessages` / `onBeforeSend.previousMessageCount` synchronously.\n *\n * @internal\n */\nexport function appendSessionMessage(agentId: string, message: SessionMessage): void {\n const existing = sessions.get(agentId) ?? [];\n existing.push(message);\n // `delete` + `set` reinserts at the END: a JS `Map` preserves insertion order, so the first key\n // is always the least recently touched. That is the entire LRU, with no new structure (parsimony\n // rungs 2/5 — the ordering we need is already a language guarantee).\n sessions.delete(agentId);\n sessions.set(agentId, existing);\n enforceCeiling();\n}\n\n/**\n * Ceiling on sessions kept in memory.\n *\n * The runtime only reads the **active** session; the rest is pure cache, rebuildable from the\n * on-disk transcript. 32 is deliberately generous — the primary removal path is the explicit\n * `discardSession()` at the end of the agent's life, and this ceiling is a safety net against a\n * long-lived process running hundreds of sessions (plan risk #2: a tight ceiling could evict a\n * session still referenced by an in-flight async path).\n */\nexport const MAX_CACHED_SESSIONS = 32;\n\nfunction enforceCeiling(): void {\n while (sessions.size > MAX_CACHED_SESSIONS) {\n const oldest = sessions.keys().next().value;\n if (oldest === undefined) return;\n sessions.delete(oldest);\n forgetBookkeeping(oldest);\n }\n}\n\n/**\n * Erases the bookkeeping for an `agentId` across EVERY `cwd` it appears in.\n *\n * The three maps are keyed by `transcriptKey(cwd, agentId)`; `sessions` is the only one keyed by the\n * raw `agentId`. The ceiling's first version deleted from all three using `sessions`' key — that is,\n * deleted nothing — and left `hydratedKeys` **orphaned**. Since `hydrateSession` returns early when\n * the marker is present, an evicted session came back **empty** instead of rehydrating from disk:\n * silent amnesia, and a regression new to M95, because before it nothing evicted.\n *\n * The ceiling only knows the `agentId`, not the `cwd`, so it scans by suffix — which is the format\n * `transcriptKey` produces. A scan rather than an index because these maps hold tens of entries, not\n * thousands: a reverse index here would be new structure for a problem that does not exist.\n */\nfunction forgetBookkeeping(agentId: string): void {\n const suffix = transcriptKey(\"\", agentId).slice(0 - agentId.length - 2);\n for (const k of [...hydratedKeys]) if (k.endsWith(suffix)) hydratedKeys.delete(k);\n for (const k of [...pendingWrites.keys()]) if (k.endsWith(suffix)) pendingWrites.delete(k);\n for (const k of [...recordCounts.keys()]) if (k.endsWith(suffix)) recordCounts.delete(k);\n}\n\n/**\n * Erases the agent's module bookkeeping and returns how many entries were removed.\n *\n * M95 — `invalidateSessionCache` used to clear **two** of the four maps (`sessions`, `hydratedKeys`);\n * `pendingWrites` and `recordCounts` were never touched by id, so they grew for the life of the\n * process. Neither is large per entry — the leak is in count, not volume — but a cache with no owner\n * for removal is a cache that only grows.\n *\n * Returns the count so the caller can prove the removal; a second discard returns 0, which is what\n * makes the idempotency test possible without exposing the maps.\n */\nexport function discardSession(cwd: string, agentId: string): number {\n const key = transcriptKey(cwd, agentId);\n let removed = 0;\n // `sessions` is NOT erased here — and the distinction is measured, not aesthetic. It holds the\n // readable conversation, and there is a legitimate reader AFTER dispose: the golden\n // `two-concurrent-sends-serialize` calls `getSessionMessages(agentId)` after `agent.dispose()`.\n // Erasing it here returned an empty list and broke two goldens. What bounds it is the LRU ceiling\n // above; the three below are pure bookkeeping, with no post-dispose reader.\n //\n // The key is `transcriptKey(cwd, agentId)` in ALL THREE — not the raw `agentId`. The first version\n // erased two of them by `agentId` and therefore **never erased anything**; the test did not catch\n // it because it only asserted that the SECOND call returns 0, which is true either way.\n if (hydratedKeys.delete(key)) removed++;\n if (pendingWrites.delete(key)) removed++;\n if (recordCounts.delete(key)) removed++;\n return removed;\n}\n\nexport function getSessionMessages(agentId: string): SessionMessage[] {\n return sessions.get(agentId) ?? [];\n}\n\n/**\n * Persist a full conversation turn (user + assistant + tool blocks) to the native\n * transcript. Chained per-(agent, transcript) so on-disk order matches send order,\n * and fire-and-forget so `send()` is not blocked by disk I/O. Every\n * M50 — when the caller supplies `turn.autoCompact`, size-driven auto-compaction (usage real vs\n * the model's context window) runs in this same chain, surfaced via the optional `onCompact` observer.\n *\n * @internal\n */\nexport function persistTurnToTranscript(\n store: SessionStore,\n loc: TranscriptLocation,\n sessionId: string,\n turn: PersistTurnInput,\n onCompact?: () => void,\n): void {\n const key = transcriptKey(loc.cwd, loc.agentId);\n // PRE-EXISTING debt, exposed when M75 fixed the Biome config that used to abort before\n // sweeping these files (a nested root under refactor/). It is not new code and was not touched\n // by M75; refactoring SDK internals without review would trade a visible problem for a diff\n // risky. Tracked in usetheodev/theokit-sdk#151.\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: see the reason just above\n const chained = (pendingWrites.get(key) ?? Promise.resolve()).then(async () => {\n try {\n await persistTurn(store, loc, sessionId, turn);\n const count = (recordCounts.get(key) ?? 0) + 1;\n recordCounts.set(key, count);\n // M50 — the 50-turn no-summary boundary stub is GONE (it silently amnesia'd the session).\n // Auto-compaction is now size-driven with a real summary: see `maybeAutoCompact` below,\n // invoked in this same write chain by the post-run lifecycle when usage is known.\n if (turn.autoCompact !== undefined) {\n const { autoCompactIfNeeded } = await import(\"./compact-session.js\");\n const fired = await autoCompactIfNeeded({\n store,\n loc,\n sessionId,\n usageTotal: turn.autoCompact.usageTotal,\n contextWindow: turn.autoCompact.contextWindow,\n turnCount: count,\n summarize: turn.autoCompact.summarize,\n });\n if (fired) onCompact?.();\n }\n } catch (cause) {\n const msg = cause instanceof Error ? cause.message : String(cause);\n diag(`[theokit-sdk] session transcript write failed (${loc.agentId}): ${msg}\\n`);\n }\n });\n pendingWrites.set(\n key,\n chained.then(\n () => undefined,\n () => undefined,\n ),\n );\n}\n\n/**\n * Load the persisted transcript into the in-memory cache. Idempotent per\n * (baseDir, cwd, agentId). Call once per agent lifecycle before the first read.\n *\n * @internal\n */\nexport async function hydrateSession(\n agentId: string,\n loc: { store: SessionStore; cwd: string },\n): Promise<void> {\n const key = transcriptKey(loc.cwd, agentId);\n if (hydratedKeys.has(key)) return;\n hydratedKeys.add(key);\n\n const persisted = await readSessionMessages(loc.store, agentId);\n if (persisted.length === 0) return;\n // M51 review F4 — the DISK is the source of truth at hydration time: after an invalidation\n // (compact/inject), an in-flight turn may have repopulated the cache with a SINGLE message before\n // this hydrate ran; the old \"skip when non-empty\" guard then pinned the parent to a 1-message\n // context (history + injected pair lost until restart). The persist chain serializes writes, so\n // the disk already contains that in-flight turn — replacing is always correct.\n sessions.set(agentId, persisted);\n}\n\n/**\n * Wait for all pending transcript writes to settle. Used by tests and by the\n * agent dispose path so on-disk state matches in-memory before the caller proceeds.\n *\n * @internal\n */\nexport async function flushSessionWrites(): Promise<void> {\n while (pendingWrites.size > 0) {\n const all = Array.from(pendingWrites.values());\n pendingWrites.clear();\n await Promise.all(all);\n }\n}\n\nexport function clearSession(agentId: string): void {\n sessions.delete(agentId);\n}\n\n/**\n * M50 review F1 — drop BOTH the message cache and the hydration marker so the NEXT send re-hydrates\n * from disk. Without this, a compaction only helps after a process restart: the live process keeps\n * sending the full pre-compact history (the cache is read synchronously by every send).\n */\n/**\n * M50 review F5 — run `fn` serialized on the SAME per-(cwd,agentId) write chain the per-turn\n * persistence uses, so a manual `Agent.compact` can never interleave with an in-flight turn's\n * writes (boundary landing mid-turn would orphan the turn from the replay).\n */\nexport function enqueueSessionWrite<T>(\n cwd: string,\n agentId: string,\n fn: () => Promise<T>,\n): Promise<T> {\n const key = transcriptKey(cwd, agentId);\n const prior = pendingWrites.get(key) ?? Promise.resolve();\n const result = prior.then(fn);\n pendingWrites.set(\n key,\n result.then(\n () => undefined,\n () => undefined,\n ),\n );\n return result;\n}\n\n/** Test-only: drop every cached session and hydration marker. @internal */\nexport function clearAllSessions(): void {\n sessions.clear();\n hydratedKeys.clear();\n recordCounts.clear();\n // M50 review F11 — the auto-compact attempt marks live on globalThis; tests reset them here.\n const g = globalThis as unknown as Record<symbol, Map<string, number>>;\n const sym = Symbol.for(\"theokit-sdk.session.auto-compact-attempts\");\n g[sym]?.clear();\n}\n"]}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunk2QMK627M_cjs = require('./chunk-2QMK627M.cjs');
|
|
4
|
+
var chunk3YYDHUNH_cjs = require('./chunk-3YYDHUNH.cjs');
|
|
4
5
|
var chunkBV2MWEMV_cjs = require('./chunk-BV2MWEMV.cjs');
|
|
5
6
|
var chunk6DCTL32L_cjs = require('./chunk-6DCTL32L.cjs');
|
|
6
|
-
var
|
|
7
|
-
var
|
|
7
|
+
var chunkT5ZWI3MC_cjs = require('./chunk-T5ZWI3MC.cjs');
|
|
8
|
+
var chunkDM6Y5B2G_cjs = require('./chunk-DM6Y5B2G.cjs');
|
|
8
9
|
var chunkEQMLJ52C_cjs = require('./chunk-EQMLJ52C.cjs');
|
|
9
|
-
var chunk3YYDHUNH_cjs = require('./chunk-3YYDHUNH.cjs');
|
|
10
10
|
var chunkBBZYXVLZ_cjs = require('./chunk-BBZYXVLZ.cjs');
|
|
11
11
|
var chunkOKLYRPKL_cjs = require('./chunk-OKLYRPKL.cjs');
|
|
12
12
|
var chunkCZHPR2G7_cjs = require('./chunk-CZHPR2G7.cjs');
|
|
@@ -17,14 +17,14 @@ var chunkNINIJCHU_cjs = require('./chunk-NINIJCHU.cjs');
|
|
|
17
17
|
var chunkVJ26EKGJ_cjs = require('./chunk-VJ26EKGJ.cjs');
|
|
18
18
|
var chunkKNZU4YO5_cjs = require('./chunk-KNZU4YO5.cjs');
|
|
19
19
|
var chunkECPL5RV6_cjs = require('./chunk-ECPL5RV6.cjs');
|
|
20
|
-
var
|
|
20
|
+
var chunkTR4V2LHV_cjs = require('./chunk-TR4V2LHV.cjs');
|
|
21
21
|
var chunkYLQQX5W2_cjs = require('./chunk-YLQQX5W2.cjs');
|
|
22
22
|
var chunkWJVHMTKB_cjs = require('./chunk-WJVHMTKB.cjs');
|
|
23
23
|
var chunk2CFEET3Y_cjs = require('./chunk-2CFEET3Y.cjs');
|
|
24
24
|
var chunkRTLUZKDL_cjs = require('./chunk-RTLUZKDL.cjs');
|
|
25
25
|
var chunkAMYY3JHQ_cjs = require('./chunk-AMYY3JHQ.cjs');
|
|
26
26
|
var chunkVYHJZVL5_cjs = require('./chunk-VYHJZVL5.cjs');
|
|
27
|
-
var
|
|
27
|
+
var chunkBC5EUG7R_cjs = require('./chunk-BC5EUG7R.cjs');
|
|
28
28
|
var chunkFUASIT3E_cjs = require('./chunk-FUASIT3E.cjs');
|
|
29
29
|
var chunkYTO5BRBD_cjs = require('./chunk-YTO5BRBD.cjs');
|
|
30
30
|
var chunkVKJ7V7EB_cjs = require('./chunk-VKJ7V7EB.cjs');
|
|
@@ -1617,7 +1617,7 @@ function createRealCloudRun(options) {
|
|
|
1617
1617
|
conversation: []
|
|
1618
1618
|
};
|
|
1619
1619
|
const apiKey = resolveApiKey(options.agentOptions.apiKey);
|
|
1620
|
-
const baseUrl =
|
|
1620
|
+
const baseUrl = chunkDM6Y5B2G_cjs.getConfiguredBaseUrl();
|
|
1621
1621
|
const handle = new RealCloudRun(
|
|
1622
1622
|
{
|
|
1623
1623
|
id,
|
|
@@ -1700,7 +1700,7 @@ var RealCloudRun = class extends FixtureRunBase {
|
|
|
1700
1700
|
async consumeStream(response) {
|
|
1701
1701
|
let finalStatus = "finished";
|
|
1702
1702
|
let finalText = "";
|
|
1703
|
-
for await (const record of
|
|
1703
|
+
for await (const record of chunkDM6Y5B2G_cjs.parseSseStream(response.body, this.controller.signal)) {
|
|
1704
1704
|
const parsed = safeParse(record.data);
|
|
1705
1705
|
if (parsed === void 0) continue;
|
|
1706
1706
|
const update = this.applyRecord(record.event, parsed);
|
|
@@ -1809,7 +1809,7 @@ var CloudAgent = class {
|
|
|
1809
1809
|
*/
|
|
1810
1810
|
isFixtureMode() {
|
|
1811
1811
|
const apiKey = resolveApiKey(this.options.apiKey);
|
|
1812
|
-
return
|
|
1812
|
+
return chunkDM6Y5B2G_cjs.isFixtureApiKey(apiKey) && chunkDM6Y5B2G_cjs.getConfiguredBaseUrl() === void 0;
|
|
1813
1813
|
}
|
|
1814
1814
|
// SE9 — integrated structured output; delegates to the shared helper.
|
|
1815
1815
|
generate(message, options) {
|
|
@@ -1860,7 +1860,7 @@ var CloudAgent = class {
|
|
|
1860
1860
|
const userText = typeof message === "string" ? message : message.text;
|
|
1861
1861
|
const systemPrompt = await this.resolveSystemPromptForSend(userText, options);
|
|
1862
1862
|
const apiKey = resolveApiKey(this.options.apiKey);
|
|
1863
|
-
const useRealRuntime = apiKey !== void 0 && !
|
|
1863
|
+
const useRealRuntime = apiKey !== void 0 && !chunkDM6Y5B2G_cjs.isFixtureApiKey(apiKey) && chunkDM6Y5B2G_cjs.getConfiguredBaseUrl() !== void 0;
|
|
1864
1864
|
return useRealRuntime ? createRealCloudRun({
|
|
1865
1865
|
agentId: this.agentId,
|
|
1866
1866
|
model: this.model ?? { id: DEFAULT_AGENTIC_MODEL_ID },
|
|
@@ -2175,7 +2175,7 @@ var PersonalityStore = class {
|
|
|
2175
2175
|
async #persist(agentId, slug) {
|
|
2176
2176
|
const filePath = this.#filePath();
|
|
2177
2177
|
await promises.mkdir(path.dirname(filePath), { recursive: true });
|
|
2178
|
-
await
|
|
2178
|
+
await chunkTR4V2LHV_cjs.withFileLock(filePath, async () => {
|
|
2179
2179
|
const current = await readState(filePath);
|
|
2180
2180
|
const nextAgents = { ...current.agents };
|
|
2181
2181
|
if (slug === void 0) delete nextAgents[agentId];
|
|
@@ -2654,7 +2654,7 @@ function resolveWindowForRun(model, contextWindow) {
|
|
|
2654
2654
|
const override = contextWindow !== void 0 && contextWindow > 0 ? contextWindow : void 0;
|
|
2655
2655
|
return chunkAMYY3JHQ_cjs.resolveEffectiveContextWindow({
|
|
2656
2656
|
...override !== void 0 ? { override } : {},
|
|
2657
|
-
catalog:
|
|
2657
|
+
catalog: chunkBC5EUG7R_cjs.getCatalogModelInfo(model)?.limit?.context,
|
|
2658
2658
|
margin: chunkAMYY3JHQ_cjs.CONTEXT_WINDOW_MARGIN,
|
|
2659
2659
|
floor: chunkAMYY3JHQ_cjs.CONTEXT_WINDOW_FLOOR
|
|
2660
2660
|
});
|
|
@@ -2680,7 +2680,7 @@ async function runPostRunLifecycle(inputs) {
|
|
|
2680
2680
|
try {
|
|
2681
2681
|
const partial = await safeConversation(run);
|
|
2682
2682
|
if (partial !== void 0) {
|
|
2683
|
-
|
|
2683
|
+
chunk2QMK627M_cjs.persistTurnToTranscript(sessionStore, { cwd: workspaceCwd, agentId, model }, agentId, {
|
|
2684
2684
|
userText,
|
|
2685
2685
|
conversation: partial
|
|
2686
2686
|
});
|
|
@@ -2690,11 +2690,11 @@ async function runPostRunLifecycle(inputs) {
|
|
|
2690
2690
|
chunkSXSPMRSV_cjs.diag(`[theokit-sdk] partial transcript write failed (${agentId}): ${msg}
|
|
2691
2691
|
`);
|
|
2692
2692
|
}
|
|
2693
|
-
await
|
|
2693
|
+
await chunk2QMK627M_cjs.flushSessionWrites();
|
|
2694
2694
|
return;
|
|
2695
2695
|
}
|
|
2696
2696
|
if (result.result !== void 0) {
|
|
2697
|
-
|
|
2697
|
+
chunk2QMK627M_cjs.appendSessionMessage(agentId, { role: "assistant", text: result.result });
|
|
2698
2698
|
}
|
|
2699
2699
|
const conversation = await safeConversation(run);
|
|
2700
2700
|
const resolvedWindow = resolveWindowForRun(model, contextWindow);
|
|
@@ -2705,7 +2705,7 @@ async function runPostRunLifecycle(inputs) {
|
|
|
2705
2705
|
}
|
|
2706
2706
|
const lastRequestUsage = result.usage?.requests?.at(-1)?.totalTokens;
|
|
2707
2707
|
const usageForTrigger = lastRequestUsage ?? result.usage?.totalTokens;
|
|
2708
|
-
|
|
2708
|
+
chunk2QMK627M_cjs.persistTurnToTranscript(
|
|
2709
2709
|
sessionStore,
|
|
2710
2710
|
{ cwd: workspaceCwd, agentId, model },
|
|
2711
2711
|
agentId,
|
|
@@ -2717,7 +2717,7 @@ async function runPostRunLifecycle(inputs) {
|
|
|
2717
2717
|
// The EFFECTIVE window (after override, clamp and margin) — not the declared one. Swapping for
|
|
2718
2718
|
// `contextWindow` here would budget against a number the clamp already rejected.
|
|
2719
2719
|
contextWindow: effectiveWindow,
|
|
2720
|
-
summarize:
|
|
2720
|
+
summarize: chunkDM6Y5B2G_cjs.buildDefaultSummarizer({
|
|
2721
2721
|
agentModel: model,
|
|
2722
2722
|
...inputs.apiKey !== void 0 ? { apiKey: inputs.apiKey } : {}
|
|
2723
2723
|
})
|
|
@@ -2759,7 +2759,7 @@ async function runPostRunLifecycle(inputs) {
|
|
|
2759
2759
|
agentId,
|
|
2760
2760
|
runId: result.id
|
|
2761
2761
|
});
|
|
2762
|
-
await
|
|
2762
|
+
await chunk2QMK627M_cjs.flushSessionWrites();
|
|
2763
2763
|
}
|
|
2764
2764
|
async function safeConversation(run) {
|
|
2765
2765
|
try {
|
|
@@ -3346,7 +3346,7 @@ var HISTOGRAM_NAMES = {
|
|
|
3346
3346
|
};
|
|
3347
3347
|
function safeRequire(moduleName) {
|
|
3348
3348
|
try {
|
|
3349
|
-
const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-
|
|
3349
|
+
const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-2VFZQEDW.cjs', document.baseURI).href)));
|
|
3350
3350
|
return r(moduleName);
|
|
3351
3351
|
} catch {
|
|
3352
3352
|
return void 0;
|
|
@@ -3571,7 +3571,7 @@ var cachedOtel;
|
|
|
3571
3571
|
function loadOtel() {
|
|
3572
3572
|
if (cachedOtel === void 0) {
|
|
3573
3573
|
try {
|
|
3574
|
-
const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-
|
|
3574
|
+
const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-2VFZQEDW.cjs', document.baseURI).href)));
|
|
3575
3575
|
const mod = r("@opentelemetry/api");
|
|
3576
3576
|
cachedOtel = mod;
|
|
3577
3577
|
} catch {
|
|
@@ -5770,7 +5770,7 @@ function applyToolResultGuard(parts, opts) {
|
|
|
5770
5770
|
(p) => (
|
|
5771
5771
|
// SE7 — guard the TEXT of a tool result (string or the text blocks of a
|
|
5772
5772
|
// structured content); image blocks pass through untouched.
|
|
5773
|
-
p.type === "tool_result" ? { ...p, content:
|
|
5773
|
+
p.type === "tool_result" ? { ...p, content: chunkDM6Y5B2G_cjs.renderToolResultContentText(p.content, (t) => guardText(t, opts)) } : p
|
|
5774
5774
|
)
|
|
5775
5775
|
);
|
|
5776
5776
|
}
|
|
@@ -5965,7 +5965,7 @@ function catalogCostFallback(provider, cleanedModel) {
|
|
|
5965
5965
|
const candidates = [`${provider}/${cleanedModel}`, cleanedModel];
|
|
5966
5966
|
if (stripped !== cleanedModel) candidates.push(`${provider}/${stripped}`, stripped);
|
|
5967
5967
|
for (const key of candidates) {
|
|
5968
|
-
const info =
|
|
5968
|
+
const info = chunkBC5EUG7R_cjs.getCatalogModelInfo(key);
|
|
5969
5969
|
const cost = info?.cost;
|
|
5970
5970
|
if (cost === void 0) continue;
|
|
5971
5971
|
const [prov, ...modelParts] = key.split("/");
|
|
@@ -5977,7 +5977,7 @@ function catalogCostFallback(provider, cleanedModel) {
|
|
|
5977
5977
|
...cost.cache_read !== void 0 ? { cacheReadCostPerMillion: cost.cache_read } : {},
|
|
5978
5978
|
...cost.cache_write !== void 0 ? { cacheWriteCostPerMillion: cost.cache_write } : {},
|
|
5979
5979
|
// M44 M5 fix — honest provenance: a key patched by the LIVE models-dev source is not "vendored".
|
|
5980
|
-
pricingVersion:
|
|
5980
|
+
pricingVersion: chunkBC5EUG7R_cjs.isPatchedModelKey(key) ? "catalog-models-dev" : "catalog-vendored"
|
|
5981
5981
|
};
|
|
5982
5982
|
}
|
|
5983
5983
|
return void 0;
|
|
@@ -6430,12 +6430,12 @@ var FallbackLlmClient = class {
|
|
|
6430
6430
|
let lastError;
|
|
6431
6431
|
for (const client of this.clients) {
|
|
6432
6432
|
if (signal.aborted) throw abortError(signal);
|
|
6433
|
-
const attempt = await
|
|
6433
|
+
const attempt = await chunkDM6Y5B2G_cjs.tryFirstEvent(client, request, signal, true);
|
|
6434
6434
|
if (attempt.kind === "handshake_error") {
|
|
6435
6435
|
lastError = attempt.error;
|
|
6436
6436
|
continue;
|
|
6437
6437
|
}
|
|
6438
|
-
return yield*
|
|
6438
|
+
return yield* chunkDM6Y5B2G_cjs.relayStream(attempt.generator, attempt.firstResult);
|
|
6439
6439
|
}
|
|
6440
6440
|
if (lastError !== void 0) throw lastError;
|
|
6441
6441
|
throw new chunk2YGIBOUH_cjs.NetworkError("FallbackLlmClient has no providers configured", {
|
|
@@ -6816,7 +6816,7 @@ function resolveMcpCwd(configCwd) {
|
|
|
6816
6816
|
function registerPluginProviderProfiles(entries) {
|
|
6817
6817
|
let registered2 = 0;
|
|
6818
6818
|
for (const entry of entries) {
|
|
6819
|
-
|
|
6819
|
+
chunkBC5EUG7R_cjs.registerProvider(entry.profile);
|
|
6820
6820
|
registered2 += 1;
|
|
6821
6821
|
}
|
|
6822
6822
|
return registered2;
|
|
@@ -7005,7 +7005,7 @@ function createRealLocalRun(options) {
|
|
|
7005
7005
|
}
|
|
7006
7006
|
var pluginProvidersAnnounced = false;
|
|
7007
7007
|
function resolveRunProvider(options) {
|
|
7008
|
-
|
|
7008
|
+
chunkBC5EUG7R_cjs.registerBuiltins();
|
|
7009
7009
|
const profiles = options.pluginManager?.aggregated.providerProfiles ?? [];
|
|
7010
7010
|
const registered2 = registerPluginProviderProfiles(profiles);
|
|
7011
7011
|
if (registered2 > 0 && !pluginProvidersAnnounced) {
|
|
@@ -7015,15 +7015,15 @@ function resolveRunProvider(options) {
|
|
|
7015
7015
|
`);
|
|
7016
7016
|
}
|
|
7017
7017
|
const parsedModel = chunkVYHJZVL5_cjs.parseModelId(options.model?.id);
|
|
7018
|
-
const modelInferredProvider = parsedModel.provider !== void 0 &&
|
|
7019
|
-
const keyInferredProvider =
|
|
7020
|
-
const primary = options.agentOptions.providers?.routes?.[0]?.provider ?? keyInferredProvider ?? modelInferredProvider ??
|
|
7018
|
+
const modelInferredProvider = parsedModel.provider !== void 0 && chunkBC5EUG7R_cjs.getProviderProfile(parsedModel.provider) !== void 0 ? parsedModel.provider : void 0;
|
|
7019
|
+
const keyInferredProvider = chunkDM6Y5B2G_cjs.inferProviderFromApiKey(options.agentOptions.apiKey);
|
|
7020
|
+
const primary = options.agentOptions.providers?.routes?.[0]?.provider ?? keyInferredProvider ?? modelInferredProvider ?? chunkDM6Y5B2G_cjs.detectPrimaryProvider();
|
|
7021
7021
|
const effectiveModelId = modelInferredProvider !== void 0 && modelInferredProvider === primary ? parsedModel.name : options.model?.id ?? "claude-sonnet-4-6";
|
|
7022
7022
|
return { primary, effectiveModelId };
|
|
7023
7023
|
}
|
|
7024
7024
|
function mergeExplicitApiKey(pools, primary, apiKey) {
|
|
7025
7025
|
if (apiKey === void 0 || apiKey.length === 0) return pools;
|
|
7026
|
-
if (
|
|
7026
|
+
if (chunkDM6Y5B2G_cjs.isFixtureApiKey(apiKey) || apiKey === LOCAL_RUNTIME_MOCK_KEY) return pools;
|
|
7027
7027
|
const existing = pools?.[primary];
|
|
7028
7028
|
if (existing !== void 0 && existing.length > 0) return pools;
|
|
7029
7029
|
return { ...pools ?? {}, [primary]: [apiKey] };
|
|
@@ -7046,7 +7046,7 @@ function buildLoopInputs(options, runId, userText, userImages) {
|
|
|
7046
7046
|
const credentialPoolStrategy = options.agentOptions.providers?.credentialPoolStrategy;
|
|
7047
7047
|
const extractToolCallsFromContent = options.agentOptions.providers?.routes?.[0]?.extractToolCallsFromContent;
|
|
7048
7048
|
const rateLimitSink = options.sendOptions.onRunEvent;
|
|
7049
|
-
const chain =
|
|
7049
|
+
const chain = chunkDM6Y5B2G_cjs.resolveProviderChain({
|
|
7050
7050
|
primary,
|
|
7051
7051
|
...fallback !== void 0 ? { fallback } : {},
|
|
7052
7052
|
...apiKeys !== void 0 ? { apiKeys } : {},
|
|
@@ -7328,7 +7328,7 @@ function buildRealRunOptions(args) {
|
|
|
7328
7328
|
};
|
|
7329
7329
|
}
|
|
7330
7330
|
async function createFixtureRunHelper(args) {
|
|
7331
|
-
const sessionMessages =
|
|
7331
|
+
const sessionMessages = chunk2QMK627M_cjs.getSessionMessages(args.inputs.agentId);
|
|
7332
7332
|
const projectMcpServers = args.inputs.settingSourcesIncludeProject ? await readProjectMcpServers(args.inputs.workspaceCwd) : {};
|
|
7333
7333
|
return createLocalRun({
|
|
7334
7334
|
agentId: args.inputs.agentId,
|
|
@@ -7347,7 +7347,7 @@ async function createFixtureRunHelper(args) {
|
|
|
7347
7347
|
}
|
|
7348
7348
|
async function dispatchLocalRun(args) {
|
|
7349
7349
|
const apiKey = resolveApiKey(args.inputs.options.apiKey);
|
|
7350
|
-
if (
|
|
7350
|
+
if (chunkDM6Y5B2G_cjs.shouldUseRealLocalRuntime(apiKey)) {
|
|
7351
7351
|
return createRealLocalRun(
|
|
7352
7352
|
buildRealRunOptions({
|
|
7353
7353
|
inputs: args.inputs,
|
|
@@ -7603,10 +7603,10 @@ async function disposeLocalAgentSession(agent) {
|
|
|
7603
7603
|
agent.lifecycleAbortController.abort();
|
|
7604
7604
|
await chunkYLQQX5W2_cjs.withCwdMutex(`agent-send:${agent.agentId}`, () => Promise.resolve());
|
|
7605
7605
|
disposeSessionMcpClients(agent.agentId);
|
|
7606
|
-
await
|
|
7606
|
+
await chunk2QMK627M_cjs.flushSessionWrites();
|
|
7607
7607
|
await flushRegistrySaves(agent.workspaceCwd);
|
|
7608
7608
|
await disposeSessionStore(agent.sessionStore);
|
|
7609
|
-
|
|
7609
|
+
chunk2QMK627M_cjs.discardSession(agent.workspaceCwd, agent.agentId);
|
|
7610
7610
|
}
|
|
7611
7611
|
async function reloadLocalAgent(agent) {
|
|
7612
7612
|
if (agent.context !== void 0) await agent.context.refresh();
|
|
@@ -8380,7 +8380,7 @@ var LocalAgentMemory = class {
|
|
|
8380
8380
|
async runActiveMemoryIfEnabled(userText, priorMessages, telemetry) {
|
|
8381
8381
|
const cfg = this.options.memory?.activeRecall;
|
|
8382
8382
|
if (cfg?.enabled !== true || this.index === void 0) return void 0;
|
|
8383
|
-
if (this.breaker === void 0) this.breaker = new
|
|
8383
|
+
if (this.breaker === void 0) this.breaker = new chunkDM6Y5B2G_cjs.CircuitBreaker();
|
|
8384
8384
|
if (this.cache === void 0) this.cache = new ActiveMemoryCache();
|
|
8385
8385
|
const result = await runActiveMemory({
|
|
8386
8386
|
userText,
|
|
@@ -8782,8 +8782,8 @@ async function localAgentUsePersonality(args) {
|
|
|
8782
8782
|
registry,
|
|
8783
8783
|
store: args.personalityStore,
|
|
8784
8784
|
invalidateCache: (reason) => args.invalidateCache(reason),
|
|
8785
|
-
appendSessionMessage: (msg) =>
|
|
8786
|
-
clearSession: () =>
|
|
8785
|
+
appendSessionMessage: (msg) => chunk2QMK627M_cjs.appendSessionMessage(args.agentId, msg),
|
|
8786
|
+
clearSession: () => chunk2QMK627M_cjs.clearSession(args.agentId),
|
|
8787
8787
|
opts: args.opts ?? {}
|
|
8788
8788
|
})
|
|
8789
8789
|
);
|
|
@@ -9137,7 +9137,7 @@ async function executeSendLocked(inputs, message, options) {
|
|
|
9137
9137
|
if (inputs.options.onBeforeSend !== void 0) {
|
|
9138
9138
|
await inputs.options.onBeforeSend({
|
|
9139
9139
|
conversationId: inputs.agentId,
|
|
9140
|
-
previousMessageCount:
|
|
9140
|
+
previousMessageCount: chunk2QMK627M_cjs.getSessionMessages(inputs.agentId).length
|
|
9141
9141
|
});
|
|
9142
9142
|
}
|
|
9143
9143
|
await inputs.runPreHook(userText);
|
|
@@ -9149,8 +9149,8 @@ async function executeSendLocked(inputs, message, options) {
|
|
|
9149
9149
|
userText,
|
|
9150
9150
|
sendOptions: options
|
|
9151
9151
|
});
|
|
9152
|
-
const priorMessages = [...
|
|
9153
|
-
|
|
9152
|
+
const priorMessages = [...chunk2QMK627M_cjs.getSessionMessages(inputs.agentId)];
|
|
9153
|
+
chunk2QMK627M_cjs.appendSessionMessage(inputs.agentId, { role: "user", text: userText });
|
|
9154
9154
|
await persistMemoryFactIfWritePrompt(inputs.workspaceCwd, inputs.options.memory, userText);
|
|
9155
9155
|
const memoryFacts = await readMemoryForSend(inputs.workspaceCwd, inputs.options.memory);
|
|
9156
9156
|
const portPathActive = shouldUsePortMemoryPath();
|
|
@@ -9312,7 +9312,7 @@ var LocalAgent = class {
|
|
|
9312
9312
|
this.options = options;
|
|
9313
9313
|
this.workspaceCwd = resolveCwd(options.local?.cwd);
|
|
9314
9314
|
this.transcriptBaseDir = resolveBaseDir(options.local?.baseDir);
|
|
9315
|
-
this.sessionStore = options.local?.sessionStore ?? new
|
|
9315
|
+
this.sessionStore = options.local?.sessionStore ?? new chunkT5ZWI3MC_cjs.FsSessionStore({ baseDir: this.transcriptBaseDir, cwd: this.workspaceCwd });
|
|
9316
9316
|
this.settingSourcesIncludeProject = includesSetting(options, "project");
|
|
9317
9317
|
this.settingSourcesIncludePlugins = includesSetting(options, "plugins");
|
|
9318
9318
|
const sub = bootstrapSubmanagers({
|
|
@@ -9362,7 +9362,7 @@ var LocalAgent = class {
|
|
|
9362
9362
|
);
|
|
9363
9363
|
await acquireLeaseIfPossible(this.sessionStore, this.agentId);
|
|
9364
9364
|
try {
|
|
9365
|
-
await
|
|
9365
|
+
await chunk2QMK627M_cjs.hydrateSession(this.agentId, { store: this.sessionStore, cwd: this.workspaceCwd });
|
|
9366
9366
|
await this.personalityStore.hydrate(this.agentId);
|
|
9367
9367
|
} catch (err) {
|
|
9368
9368
|
await releaseLeaseIfPossible(this.sessionStore, this.agentId);
|
|
@@ -9695,7 +9695,7 @@ async function createLocalAgent(options) {
|
|
|
9695
9695
|
if (apiKey === void 0) {
|
|
9696
9696
|
throw new chunk2YGIBOUH_cjs.AuthenticationError("Missing API key", { code: "missing_api_key" });
|
|
9697
9697
|
}
|
|
9698
|
-
const willFlowToProvider = !
|
|
9698
|
+
const willFlowToProvider = !chunkDM6Y5B2G_cjs.isFixtureApiKey(apiKey) && !chunkDM6Y5B2G_cjs.shouldUseRealLocalRuntime(apiKey);
|
|
9699
9699
|
const shape = validateApiKeyShape(apiKey, {
|
|
9700
9700
|
strict: willFlowToProvider,
|
|
9701
9701
|
// `options.model` is already normalized by `runCreateUnderSpan`; `normalizeModel`
|
|
@@ -9706,7 +9706,7 @@ async function createLocalAgent(options) {
|
|
|
9706
9706
|
if (shape.malformed) {
|
|
9707
9707
|
throw new chunk2YGIBOUH_cjs.AuthenticationError(shape.message, { code: "malformed_api_key" });
|
|
9708
9708
|
}
|
|
9709
|
-
if (!
|
|
9709
|
+
if (!chunkDM6Y5B2G_cjs.isFixtureApiKey(apiKey) && chunkDM6Y5B2G_cjs.getConfiguredBaseUrl() === void 0 && !chunkDM6Y5B2G_cjs.shouldUseRealLocalRuntime(apiKey)) {
|
|
9710
9710
|
throw new chunk2YGIBOUH_cjs.AuthenticationError("Invalid API key", {
|
|
9711
9711
|
code: "authentication_error"
|
|
9712
9712
|
});
|
|
@@ -9726,11 +9726,11 @@ async function createCloudAgent(options) {
|
|
|
9726
9726
|
if (shape.malformed) {
|
|
9727
9727
|
throw new chunk2YGIBOUH_cjs.AuthenticationError(shape.message, { code: "malformed_api_key" });
|
|
9728
9728
|
}
|
|
9729
|
-
const baseUrl =
|
|
9729
|
+
const baseUrl = chunkDM6Y5B2G_cjs.getConfiguredBaseUrl();
|
|
9730
9730
|
if (baseUrl === void 0) {
|
|
9731
9731
|
return new CloudAgent(options);
|
|
9732
9732
|
}
|
|
9733
|
-
const response = await
|
|
9733
|
+
const response = await chunkDM6Y5B2G_cjs.httpRequest("/v1/agents", {
|
|
9734
9734
|
apiKey,
|
|
9735
9735
|
method: "POST",
|
|
9736
9736
|
body: {
|
|
@@ -9755,7 +9755,7 @@ function resolveAgentPersistenceCwd(options) {
|
|
|
9755
9755
|
return process.cwd();
|
|
9756
9756
|
}
|
|
9757
9757
|
async function rehydrateExistingAgent(agentId, existing, options) {
|
|
9758
|
-
await
|
|
9758
|
+
await chunkDM6Y5B2G_cjs.discoverProviderPlugins();
|
|
9759
9759
|
await validateRehydratedAgent(agentId, existing);
|
|
9760
9760
|
const mergedLocal = options.local !== void 0 && existing.options.local !== void 0 ? { ...existing.options.local, ...options.local } : options.local ?? existing.options.local;
|
|
9761
9761
|
const mergedOptions = {
|
|
@@ -9883,7 +9883,7 @@ var Agent = class _Agent {
|
|
|
9883
9883
|
pluginCount: enabledPluginNames(options.plugins).length
|
|
9884
9884
|
});
|
|
9885
9885
|
try {
|
|
9886
|
-
await
|
|
9886
|
+
await chunkDM6Y5B2G_cjs.discoverProviderPlugins();
|
|
9887
9887
|
const agent = await runCreateUnderSpan(options, span);
|
|
9888
9888
|
return agent;
|
|
9889
9889
|
} catch (err) {
|
|
@@ -10152,9 +10152,9 @@ var Agent = class _Agent {
|
|
|
10152
10152
|
`No local agent "${agentId}" registered \u2014 compact targets local sessions.`
|
|
10153
10153
|
);
|
|
10154
10154
|
}
|
|
10155
|
-
const { compactSessionTranscript, buildDefaultSummarizer: buildDefaultSummarizer2 } = await import('./compact-session-
|
|
10155
|
+
const { compactSessionTranscript, buildDefaultSummarizer: buildDefaultSummarizer2 } = await import('./compact-session-6GKIS4SD.cjs');
|
|
10156
10156
|
const { cwd, model, store } = await openLocalStore(reg);
|
|
10157
|
-
return
|
|
10157
|
+
return chunk2QMK627M_cjs.enqueueSessionWrite(
|
|
10158
10158
|
cwd,
|
|
10159
10159
|
agentId,
|
|
10160
10160
|
() => compactSessionTranscript({
|
|
@@ -10188,7 +10188,7 @@ var Agent = class _Agent {
|
|
|
10188
10188
|
`No local agent "${agentId}" registered \u2014 injectSessionTurn targets local sessions.`
|
|
10189
10189
|
);
|
|
10190
10190
|
}
|
|
10191
|
-
const { injectSessionTurn } = await import('./inject-session-
|
|
10191
|
+
const { injectSessionTurn } = await import('./inject-session-67SF65FC.cjs');
|
|
10192
10192
|
const { cwd, model, store } = await openLocalStore(reg);
|
|
10193
10193
|
await injectSessionTurn({
|
|
10194
10194
|
store,
|
|
@@ -10315,7 +10315,7 @@ async function openLocalStore(reg) {
|
|
|
10315
10315
|
const cwd = reg.cwd ?? process.cwd();
|
|
10316
10316
|
const optModel = reg.options.model;
|
|
10317
10317
|
const model = reg.model?.id ?? (typeof optModel === "string" ? optModel : optModel?.id) ?? "unknown";
|
|
10318
|
-
const { FsSessionStore: FsSessionStore2 } = await import('./fs-session-store-
|
|
10318
|
+
const { FsSessionStore: FsSessionStore2 } = await import('./fs-session-store-VXXDIBGM.cjs');
|
|
10319
10319
|
const { defaultBaseDir: defaultBaseDir2, expandTilde: expandTilde2 } = await import('./session-transcript-TNAJ4O3M.cjs');
|
|
10320
10320
|
const baseDir = reg.options.local?.baseDir !== void 0 ? expandTilde2(reg.options.local.baseDir) : defaultBaseDir2();
|
|
10321
10321
|
return { cwd, model, store: new FsSessionStore2({ baseDir, cwd }) };
|
|
@@ -10333,5 +10333,5 @@ exports.generateCronId = generateCronId;
|
|
|
10333
10333
|
exports.getPricingEntry = getPricingEntry;
|
|
10334
10334
|
exports.openRouterMemoryEmbeddingProviderAdapter = openRouterMemoryEmbeddingProviderAdapter;
|
|
10335
10335
|
exports.resolveApiKey = resolveApiKey;
|
|
10336
|
-
//# sourceMappingURL=chunk-
|
|
10337
|
-
//# sourceMappingURL=chunk-
|
|
10336
|
+
//# sourceMappingURL=chunk-2VFZQEDW.cjs.map
|
|
10337
|
+
//# sourceMappingURL=chunk-2VFZQEDW.cjs.map
|