@theokit/sdk 4.16.2 → 4.16.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/eval.cjs CHANGED
@@ -1605,6 +1605,78 @@ var init_run_events = __esm({
1605
1605
  }
1606
1606
  });
1607
1607
 
1608
+ // src/internal/session/agent-session-store.ts
1609
+ function seedTranscript(prior, opts) {
1610
+ return SessionTranscript.fromRecords(prior, opts);
1611
+ }
1612
+ function mapAgentTurn(steps) {
1613
+ const assistant = {};
1614
+ const toolResults = [];
1615
+ const toolCalls = [];
1616
+ for (const step of steps) {
1617
+ if (step.type === "thinkingMessage") assistant.thinking = step.message.text;
1618
+ else if (step.type === "assistantMessage") assistant.text = step.message.text;
1619
+ else if (step.type === "toolCall")
1620
+ toolCalls.push({
1621
+ id: step.message.callId,
1622
+ name: step.message.name,
1623
+ input: step.message.args ?? {}
1624
+ });
1625
+ else
1626
+ toolResults.push({
1627
+ toolUseId: step.message.callId,
1628
+ content: step.message.result,
1629
+ isError: step.message.isError
1630
+ });
1631
+ }
1632
+ if (toolCalls.length > 0) assistant.toolCalls = toolCalls;
1633
+ return { assistant, toolResults };
1634
+ }
1635
+ function hasAssistantContent(a) {
1636
+ return a.text !== void 0 || a.thinking !== void 0 || (a.toolCalls?.length ?? 0) > 0;
1637
+ }
1638
+ function appendConversation(transcript, conversation) {
1639
+ for (const ct of conversation) {
1640
+ if (ct.type !== "agentConversationTurn") continue;
1641
+ const { assistant, toolResults } = mapAgentTurn(ct.turn.steps);
1642
+ if (hasAssistantContent(assistant)) transcript.appendAssistantTurn(assistant);
1643
+ if (toolResults.length > 0) transcript.appendToolResults(toolResults);
1644
+ }
1645
+ }
1646
+ async function readSessionMessages(store, agentId) {
1647
+ const records = await store.readRecords(agentId);
1648
+ return reconstructMessages(records).map(narrowToSessionMessage);
1649
+ }
1650
+ function partToText(p) {
1651
+ if (p.type === "text") return p.text ?? "";
1652
+ if (p.type === "tool_use") return `[tool call] ${p.name ?? ""}`;
1653
+ if (p.type === "tool_result") {
1654
+ const body = typeof p.content === "string" ? p.content : JSON.stringify(p.content);
1655
+ return `[tool result] ${body}`;
1656
+ }
1657
+ return "";
1658
+ }
1659
+ function narrowToSessionMessage(m) {
1660
+ const role = m.role === "user" ? "user" : "assistant";
1661
+ const text = m.content.map(partToText).filter((s) => s.length > 0).join("\n");
1662
+ return { role, text };
1663
+ }
1664
+ function deltaRecords(transcript, priorLength) {
1665
+ return transcript.records().slice(priorLength);
1666
+ }
1667
+ async function persistTurn(store, loc, sessionId, turn) {
1668
+ const prior = await store.readRecords(loc.agentId);
1669
+ const transcript = seedTranscript(prior, { cwd: loc.cwd, sessionId, model: loc.model });
1670
+ transcript.appendUserTurn(turn.userText);
1671
+ appendConversation(transcript, turn.conversation);
1672
+ await store.appendRecords(loc.agentId, deltaRecords(transcript, prior.length));
1673
+ }
1674
+ var init_agent_session_store = __esm({
1675
+ "src/internal/session/agent-session-store.ts"() {
1676
+ init_session_transcript();
1677
+ }
1678
+ });
1679
+
1608
1680
  // src/compaction.ts
1609
1681
  function estimateTokens(text) {
1610
1682
  return Math.ceil(text.length / 4);
@@ -1805,6 +1877,13 @@ function getProviderProfile(name) {
1805
1877
  const canonical = ALIASES.get(name) ?? name;
1806
1878
  return REGISTRY.get(canonical);
1807
1879
  }
1880
+ function listProviders() {
1881
+ return Array.from(REGISTRY.values());
1882
+ }
1883
+ function _resetProvidersForTests() {
1884
+ REGISTRY.clear();
1885
+ ALIASES.clear();
1886
+ }
1808
1887
  var REGISTRY, ALIASES;
1809
1888
  var init_registry = __esm({
1810
1889
  "src/internal/providers/registry.ts"() {
@@ -2737,6 +2816,9 @@ function registerBuiltins() {
2737
2816
  registerProvider(CEREBRAS);
2738
2817
  registerCatalogProviders();
2739
2818
  }
2819
+ function _resetBuiltinsRegistered() {
2820
+ _registeredState.done = false;
2821
+ }
2740
2822
  var _registeredState;
2741
2823
  var init_builtin = __esm({
2742
2824
  "src/internal/providers/builtin/index.ts"() {
@@ -2863,6 +2945,9 @@ async function loadOne(dir, entryName) {
2863
2945
  }
2864
2946
  }
2865
2947
  }
2948
+ function _resetDiscovery() {
2949
+ discoveryState.done = false;
2950
+ }
2866
2951
  var discoveryState;
2867
2952
  var init_discovery = __esm({
2868
2953
  "src/internal/providers/discovery.ts"() {
@@ -2874,9 +2959,25 @@ var init_discovery = __esm({
2874
2959
  });
2875
2960
 
2876
2961
  // src/internal/providers/index.ts
2962
+ var providers_exports = {};
2963
+ __export(providers_exports, {
2964
+ ANTHROPIC: () => ANTHROPIC,
2965
+ GEMINI: () => GEMINI,
2966
+ OPENAI: () => OPENAI,
2967
+ OPENROUTER: () => OPENROUTER,
2968
+ _resetBuiltinsRegistered: () => _resetBuiltinsRegistered,
2969
+ _resetDiscovery: () => _resetDiscovery,
2970
+ _resetProvidersForTests: () => _resetProvidersForTests,
2971
+ discoverProviderPlugins: () => discoverProviderPlugins,
2972
+ getProviderProfile: () => getProviderProfile,
2973
+ listProviders: () => listProviders,
2974
+ registerBuiltins: () => registerBuiltins,
2975
+ registerProvider: () => registerProvider
2976
+ });
2877
2977
  var init_providers = __esm({
2878
2978
  "src/internal/providers/index.ts"() {
2879
2979
  init_builtin();
2980
+ init_discovery();
2880
2981
  init_registry();
2881
2982
  }
2882
2983
  });
@@ -5935,7 +6036,14 @@ async function compactSessionTranscript(opts) {
5935
6036
  const m = compressible[i];
5936
6037
  if (m === void 0 || m.role !== "user" || isCompactSummary(m.content)) continue;
5937
6038
  const cost = estimateTokens(m.content);
5938
- if (budget + cost > COMPACT_USER_MESSAGE_MAX_TOKENS) break;
6039
+ if (budget + cost > COMPACT_USER_MESSAGE_MAX_TOKENS) {
6040
+ const remaining = COMPACT_USER_MESSAGE_MAX_TOKENS - budget;
6041
+ if (remaining > 50) {
6042
+ preserved.unshift(`${m.content.slice(0, remaining * 4)}
6043
+ [...truncated for compaction...]`);
6044
+ }
6045
+ break;
6046
+ }
5939
6047
  budget += cost;
5940
6048
  preserved.unshift(m.content);
5941
6049
  }
@@ -5951,6 +6059,8 @@ ${summaryBody}`;
5951
6059
  transcript.appendUserTurn(summary);
5952
6060
  const delta = transcript.records().slice(prior.length);
5953
6061
  await opts.store.appendRecords(opts.loc.agentId, delta);
6062
+ const { invalidateSessionCache: invalidateSessionCache2 } = await Promise.resolve().then(() => (init_agent_session(), agent_session_exports));
6063
+ invalidateSessionCache2(opts.loc.cwd, opts.loc.agentId);
5954
6064
  const postTokens = estimateTokens([...preserved, summary].join("\n"));
5955
6065
  return { preTokens, postTokens };
5956
6066
  }
@@ -5962,9 +6072,12 @@ function buildDefaultSummarizer(opts) {
5962
6072
  const { inferProviderFromApiKey: inferProviderFromApiKey2, detectPrimaryProvider: detectPrimaryProvider2 } = await Promise.resolve().then(() => (init_real_local_run_provider(), real_local_run_provider_exports));
5963
6073
  const keyProvider = inferProviderFromApiKey2(opts.apiKey);
5964
6074
  const modelPrefix = opts.agentModel.includes("/") ? opts.agentModel.slice(0, opts.agentModel.indexOf("/")) : void 0;
5965
- const provider = keyProvider ?? modelPrefix ?? detectPrimaryProvider2();
6075
+ const { registerBuiltins: registerBuiltins2, getProviderProfile: getProviderProfile2 } = await Promise.resolve().then(() => (init_providers(), providers_exports));
6076
+ registerBuiltins2();
6077
+ const prefixProfile = modelPrefix !== void 0 ? getProviderProfile2(modelPrefix) : void 0;
6078
+ const provider = prefixProfile !== void 0 ? modelPrefix : keyProvider ?? detectPrimaryProvider2();
5966
6079
  let model;
5967
- if (keyProvider !== void 0 && keyProvider !== modelPrefix) {
6080
+ if (provider !== modelPrefix) {
5968
6081
  model = opts.agentModel;
5969
6082
  } else {
5970
6083
  try {
@@ -6039,6 +6152,122 @@ var init_compact_session = __esm({
6039
6152
  })();
6040
6153
  }
6041
6154
  });
6155
+
6156
+ // src/internal/session/agent-session.ts
6157
+ var agent_session_exports = {};
6158
+ __export(agent_session_exports, {
6159
+ appendSessionMessage: () => appendSessionMessage,
6160
+ clearAllSessions: () => clearAllSessions,
6161
+ clearSession: () => clearSession,
6162
+ enqueueSessionWrite: () => enqueueSessionWrite,
6163
+ flushSessionWrites: () => flushSessionWrites,
6164
+ getSessionMessages: () => getSessionMessages,
6165
+ hydrateSession: () => hydrateSession,
6166
+ invalidateSessionCache: () => invalidateSessionCache,
6167
+ persistTurnToTranscript: () => persistTurnToTranscript
6168
+ });
6169
+ function transcriptKey(cwd, agentId) {
6170
+ return `${cwd}::${agentId}`;
6171
+ }
6172
+ function appendSessionMessage(agentId, message) {
6173
+ const existing = sessions.get(agentId) ?? [];
6174
+ existing.push(message);
6175
+ sessions.set(agentId, existing);
6176
+ }
6177
+ function getSessionMessages(agentId) {
6178
+ return sessions.get(agentId) ?? [];
6179
+ }
6180
+ function persistTurnToTranscript(store, loc, sessionId, turn, onCompact) {
6181
+ const key = transcriptKey(loc.cwd, loc.agentId);
6182
+ const chained = (pendingWrites.get(key) ?? Promise.resolve()).then(async () => {
6183
+ try {
6184
+ await persistTurn(store, loc, sessionId, turn);
6185
+ const count = (recordCounts.get(key) ?? 0) + 1;
6186
+ recordCounts.set(key, count);
6187
+ if (turn.autoCompact !== void 0) {
6188
+ const { autoCompactIfNeeded: autoCompactIfNeeded2 } = await Promise.resolve().then(() => (init_compact_session(), compact_session_exports));
6189
+ const fired = await autoCompactIfNeeded2({
6190
+ store,
6191
+ loc,
6192
+ sessionId,
6193
+ usageTotal: turn.autoCompact.usageTotal,
6194
+ contextWindow: turn.autoCompact.contextWindow,
6195
+ turnCount: count,
6196
+ summarize: turn.autoCompact.summarize
6197
+ });
6198
+ if (fired) onCompact?.();
6199
+ }
6200
+ } catch (cause) {
6201
+ const msg = cause instanceof Error ? cause.message : String(cause);
6202
+ process.stderr.write(
6203
+ `[theokit-sdk] session transcript write failed (${loc.agentId}): ${msg}
6204
+ `
6205
+ );
6206
+ }
6207
+ });
6208
+ pendingWrites.set(
6209
+ key,
6210
+ chained.then(
6211
+ () => void 0,
6212
+ () => void 0
6213
+ )
6214
+ );
6215
+ }
6216
+ async function hydrateSession(agentId, loc) {
6217
+ const key = transcriptKey(loc.cwd, agentId);
6218
+ if (hydratedKeys.has(key)) return;
6219
+ hydratedKeys.add(key);
6220
+ const persisted = await readSessionMessages(loc.store, agentId);
6221
+ if (persisted.length === 0) return;
6222
+ if (!sessions.has(agentId) || sessions.get(agentId)?.length === 0) {
6223
+ sessions.set(agentId, persisted);
6224
+ }
6225
+ }
6226
+ async function flushSessionWrites() {
6227
+ while (pendingWrites.size > 0) {
6228
+ const all = Array.from(pendingWrites.values());
6229
+ pendingWrites.clear();
6230
+ await Promise.all(all);
6231
+ }
6232
+ }
6233
+ function clearSession(agentId) {
6234
+ sessions.delete(agentId);
6235
+ }
6236
+ function invalidateSessionCache(cwd, agentId) {
6237
+ sessions.delete(agentId);
6238
+ hydratedKeys.delete(transcriptKey(cwd, agentId));
6239
+ }
6240
+ function enqueueSessionWrite(cwd, agentId, fn) {
6241
+ const key = transcriptKey(cwd, agentId);
6242
+ const prior = pendingWrites.get(key) ?? Promise.resolve();
6243
+ const result = prior.then(fn);
6244
+ pendingWrites.set(
6245
+ key,
6246
+ result.then(
6247
+ () => void 0,
6248
+ () => void 0
6249
+ )
6250
+ );
6251
+ return result;
6252
+ }
6253
+ function clearAllSessions() {
6254
+ sessions.clear();
6255
+ hydratedKeys.clear();
6256
+ recordCounts.clear();
6257
+ const g = globalThis;
6258
+ const sym = /* @__PURE__ */ Symbol.for("theokit-sdk.session.auto-compact-attempts");
6259
+ g[sym]?.clear();
6260
+ }
6261
+ var sessions, hydratedKeys, pendingWrites, recordCounts;
6262
+ var init_agent_session = __esm({
6263
+ "src/internal/session/agent-session.ts"() {
6264
+ init_agent_session_store();
6265
+ sessions = /* @__PURE__ */ new Map();
6266
+ hydratedKeys = /* @__PURE__ */ new Set();
6267
+ pendingWrites = /* @__PURE__ */ new Map();
6268
+ recordCounts = /* @__PURE__ */ new Map();
6269
+ }
6270
+ });
6042
6271
  async function withToolWhitelist(whitelist, fn) {
6043
6272
  return toolWhitelistStore.run(whitelist, fn);
6044
6273
  }
@@ -10414,147 +10643,6 @@ async function writeSessionSummary(input) {
10414
10643
  await replaceFileAtomic(path, body);
10415
10644
  }
10416
10645
 
10417
- // src/internal/session/agent-session-store.ts
10418
- init_session_transcript();
10419
- function seedTranscript(prior, opts) {
10420
- return SessionTranscript.fromRecords(prior, opts);
10421
- }
10422
- function mapAgentTurn(steps) {
10423
- const assistant = {};
10424
- const toolResults = [];
10425
- const toolCalls = [];
10426
- for (const step of steps) {
10427
- if (step.type === "thinkingMessage") assistant.thinking = step.message.text;
10428
- else if (step.type === "assistantMessage") assistant.text = step.message.text;
10429
- else if (step.type === "toolCall")
10430
- toolCalls.push({
10431
- id: step.message.callId,
10432
- name: step.message.name,
10433
- input: step.message.args ?? {}
10434
- });
10435
- else
10436
- toolResults.push({
10437
- toolUseId: step.message.callId,
10438
- content: step.message.result,
10439
- isError: step.message.isError
10440
- });
10441
- }
10442
- if (toolCalls.length > 0) assistant.toolCalls = toolCalls;
10443
- return { assistant, toolResults };
10444
- }
10445
- function hasAssistantContent(a) {
10446
- return a.text !== void 0 || a.thinking !== void 0 || (a.toolCalls?.length ?? 0) > 0;
10447
- }
10448
- function appendConversation(transcript, conversation) {
10449
- for (const ct of conversation) {
10450
- if (ct.type !== "agentConversationTurn") continue;
10451
- const { assistant, toolResults } = mapAgentTurn(ct.turn.steps);
10452
- if (hasAssistantContent(assistant)) transcript.appendAssistantTurn(assistant);
10453
- if (toolResults.length > 0) transcript.appendToolResults(toolResults);
10454
- }
10455
- }
10456
- async function readSessionMessages(store, agentId) {
10457
- const records = await store.readRecords(agentId);
10458
- return reconstructMessages(records).map(narrowToSessionMessage);
10459
- }
10460
- function partToText(p) {
10461
- if (p.type === "text") return p.text ?? "";
10462
- if (p.type === "tool_use") return `[tool call] ${p.name ?? ""}`;
10463
- if (p.type === "tool_result") {
10464
- const body = typeof p.content === "string" ? p.content : JSON.stringify(p.content);
10465
- return `[tool result] ${body}`;
10466
- }
10467
- return "";
10468
- }
10469
- function narrowToSessionMessage(m) {
10470
- const role = m.role === "user" ? "user" : "assistant";
10471
- const text = m.content.map(partToText).filter((s) => s.length > 0).join("\n");
10472
- return { role, text };
10473
- }
10474
- function deltaRecords(transcript, priorLength) {
10475
- return transcript.records().slice(priorLength);
10476
- }
10477
- async function persistTurn(store, loc, sessionId, turn) {
10478
- const prior = await store.readRecords(loc.agentId);
10479
- const transcript = seedTranscript(prior, { cwd: loc.cwd, sessionId, model: loc.model });
10480
- transcript.appendUserTurn(turn.userText);
10481
- appendConversation(transcript, turn.conversation);
10482
- await store.appendRecords(loc.agentId, deltaRecords(transcript, prior.length));
10483
- }
10484
-
10485
- // src/internal/session/agent-session.ts
10486
- var sessions = /* @__PURE__ */ new Map();
10487
- var hydratedKeys = /* @__PURE__ */ new Set();
10488
- var pendingWrites = /* @__PURE__ */ new Map();
10489
- var recordCounts = /* @__PURE__ */ new Map();
10490
- function transcriptKey(cwd, agentId) {
10491
- return `${cwd}::${agentId}`;
10492
- }
10493
- function appendSessionMessage(agentId, message) {
10494
- const existing = sessions.get(agentId) ?? [];
10495
- existing.push(message);
10496
- sessions.set(agentId, existing);
10497
- }
10498
- function getSessionMessages(agentId) {
10499
- return sessions.get(agentId) ?? [];
10500
- }
10501
- function persistTurnToTranscript(store, loc, sessionId, turn, onCompact) {
10502
- const key = transcriptKey(loc.cwd, loc.agentId);
10503
- const chained = (pendingWrites.get(key) ?? Promise.resolve()).then(async () => {
10504
- try {
10505
- await persistTurn(store, loc, sessionId, turn);
10506
- const count = (recordCounts.get(key) ?? 0) + 1;
10507
- recordCounts.set(key, count);
10508
- if (turn.autoCompact !== void 0) {
10509
- const { autoCompactIfNeeded: autoCompactIfNeeded2 } = await Promise.resolve().then(() => (init_compact_session(), compact_session_exports));
10510
- const fired = await autoCompactIfNeeded2({
10511
- store,
10512
- loc,
10513
- sessionId,
10514
- usageTotal: turn.autoCompact.usageTotal,
10515
- contextWindow: turn.autoCompact.contextWindow,
10516
- turnCount: count,
10517
- summarize: turn.autoCompact.summarize
10518
- });
10519
- if (fired) onCompact?.();
10520
- }
10521
- } catch (cause) {
10522
- const msg = cause instanceof Error ? cause.message : String(cause);
10523
- process.stderr.write(
10524
- `[theokit-sdk] session transcript write failed (${loc.agentId}): ${msg}
10525
- `
10526
- );
10527
- }
10528
- });
10529
- pendingWrites.set(
10530
- key,
10531
- chained.then(
10532
- () => void 0,
10533
- () => void 0
10534
- )
10535
- );
10536
- }
10537
- async function hydrateSession(agentId, loc) {
10538
- const key = transcriptKey(loc.cwd, agentId);
10539
- if (hydratedKeys.has(key)) return;
10540
- hydratedKeys.add(key);
10541
- const persisted = await readSessionMessages(loc.store, agentId);
10542
- if (persisted.length === 0) return;
10543
- if (!sessions.has(agentId) || sessions.get(agentId)?.length === 0) {
10544
- sessions.set(agentId, persisted);
10545
- }
10546
- }
10547
- async function flushSessionWrites() {
10548
- while (pendingWrites.size > 0) {
10549
- const all = Array.from(pendingWrites.values());
10550
- pendingWrites.clear();
10551
- await Promise.all(all);
10552
- }
10553
- }
10554
- function clearSession(agentId) {
10555
- sessions.delete(agentId);
10556
- }
10557
-
10558
10646
  // src/internal/runtime/memory/memory-path-selector.ts
10559
10647
  var PORT_MEMORY_PATH_ENV_VAR = "THEOKIT_PORT_MEMORY_PATH";
10560
10648
  function shouldUsePortMemoryPath() {
@@ -10605,6 +10693,20 @@ async function runPostRunLifecycle(inputs) {
10605
10693
  const { getCatalogModelInfo: getCatalogModelInfo2 } = await Promise.resolve().then(() => (init_catalog_loader(), catalog_loader_exports));
10606
10694
  const { buildDefaultSummarizer: buildDefaultSummarizer2 } = await Promise.resolve().then(() => (init_compact_session(), compact_session_exports));
10607
10695
  const contextWindow = getCatalogModelInfo2(model)?.limit?.context;
10696
+ if (contextWindow === void 0) {
10697
+ const g = globalThis;
10698
+ const sym = /* @__PURE__ */ Symbol.for("theokit-sdk.compact.no-cw-warned");
10699
+ const warned3 = g[sym] ??= /* @__PURE__ */ new Set();
10700
+ if (!warned3.has(model)) {
10701
+ warned3.add(model);
10702
+ process.stderr.write(
10703
+ `[theokit-sdk] auto-compaction disabled: model "${model}" has no context-window entry in the catalog
10704
+ `
10705
+ );
10706
+ }
10707
+ }
10708
+ const lastRequestUsage = result.usage?.requests?.at(-1)?.totalTokens;
10709
+ const usageForTrigger = lastRequestUsage ?? result.usage?.totalTokens;
10608
10710
  persistTurnToTranscript(
10609
10711
  sessionStore,
10610
10712
  { cwd: workspaceCwd, agentId, model },
@@ -10613,7 +10715,7 @@ async function runPostRunLifecycle(inputs) {
10613
10715
  userText,
10614
10716
  conversation,
10615
10717
  autoCompact: {
10616
- usageTotal: result.usage?.totalTokens,
10718
+ usageTotal: usageForTrigger,
10617
10719
  contextWindow,
10618
10720
  summarize: buildDefaultSummarizer2({
10619
10721
  agentModel: model,
@@ -19897,7 +19999,8 @@ var Agent = class _Agent {
19897
19999
  const { defaultBaseDir: defaultBaseDir2, expandTilde: expandTilde2 } = await Promise.resolve().then(() => (init_session_transcript(), session_transcript_exports));
19898
20000
  const baseDir = reg.options.local?.baseDir !== void 0 ? expandTilde2(reg.options.local.baseDir) : defaultBaseDir2();
19899
20001
  const store = new FsSessionStore2({ baseDir, cwd });
19900
- return compactSessionTranscript2({
20002
+ const { enqueueSessionWrite: enqueueSessionWrite2 } = await Promise.resolve().then(() => (init_agent_session(), agent_session_exports));
20003
+ return enqueueSessionWrite2(cwd, agentId, () => compactSessionTranscript2({
19901
20004
  store,
19902
20005
  loc: { cwd, agentId, model },
19903
20006
  sessionId: agentId,
@@ -19906,7 +20009,7 @@ var Agent = class _Agent {
19906
20009
  agentModel: model,
19907
20010
  ...reg.options.apiKey !== void 0 ? { apiKey: reg.options.apiKey } : {}
19908
20011
  })
19909
- });
20012
+ }));
19910
20013
  }
19911
20014
  /**
19912
20015
  * Permanently delete a cloud agent.