@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/index.js CHANGED
@@ -1758,6 +1758,78 @@ var init_session_summary_writer = __esm({
1758
1758
  }
1759
1759
  });
1760
1760
 
1761
+ // src/internal/session/agent-session-store.ts
1762
+ function seedTranscript(prior, opts) {
1763
+ return SessionTranscript.fromRecords(prior, opts);
1764
+ }
1765
+ function mapAgentTurn(steps) {
1766
+ const assistant = {};
1767
+ const toolResults = [];
1768
+ const toolCalls = [];
1769
+ for (const step of steps) {
1770
+ if (step.type === "thinkingMessage") assistant.thinking = step.message.text;
1771
+ else if (step.type === "assistantMessage") assistant.text = step.message.text;
1772
+ else if (step.type === "toolCall")
1773
+ toolCalls.push({
1774
+ id: step.message.callId,
1775
+ name: step.message.name,
1776
+ input: step.message.args ?? {}
1777
+ });
1778
+ else
1779
+ toolResults.push({
1780
+ toolUseId: step.message.callId,
1781
+ content: step.message.result,
1782
+ isError: step.message.isError
1783
+ });
1784
+ }
1785
+ if (toolCalls.length > 0) assistant.toolCalls = toolCalls;
1786
+ return { assistant, toolResults };
1787
+ }
1788
+ function hasAssistantContent(a) {
1789
+ return a.text !== void 0 || a.thinking !== void 0 || (a.toolCalls?.length ?? 0) > 0;
1790
+ }
1791
+ function appendConversation(transcript, conversation) {
1792
+ for (const ct of conversation) {
1793
+ if (ct.type !== "agentConversationTurn") continue;
1794
+ const { assistant, toolResults } = mapAgentTurn(ct.turn.steps);
1795
+ if (hasAssistantContent(assistant)) transcript.appendAssistantTurn(assistant);
1796
+ if (toolResults.length > 0) transcript.appendToolResults(toolResults);
1797
+ }
1798
+ }
1799
+ async function readSessionMessages(store, agentId) {
1800
+ const records = await store.readRecords(agentId);
1801
+ return reconstructMessages(records).map(narrowToSessionMessage);
1802
+ }
1803
+ function partToText(p) {
1804
+ if (p.type === "text") return p.text ?? "";
1805
+ if (p.type === "tool_use") return `[tool call] ${p.name ?? ""}`;
1806
+ if (p.type === "tool_result") {
1807
+ const body = typeof p.content === "string" ? p.content : JSON.stringify(p.content);
1808
+ return `[tool result] ${body}`;
1809
+ }
1810
+ return "";
1811
+ }
1812
+ function narrowToSessionMessage(m) {
1813
+ const role = m.role === "user" ? "user" : "assistant";
1814
+ const text = m.content.map(partToText).filter((s) => s.length > 0).join("\n");
1815
+ return { role, text };
1816
+ }
1817
+ function deltaRecords(transcript, priorLength) {
1818
+ return transcript.records().slice(priorLength);
1819
+ }
1820
+ async function persistTurn(store, loc, sessionId, turn) {
1821
+ const prior = await store.readRecords(loc.agentId);
1822
+ const transcript = seedTranscript(prior, { cwd: loc.cwd, sessionId, model: loc.model });
1823
+ transcript.appendUserTurn(turn.userText);
1824
+ appendConversation(transcript, turn.conversation);
1825
+ await store.appendRecords(loc.agentId, deltaRecords(transcript, prior.length));
1826
+ }
1827
+ var init_agent_session_store = __esm({
1828
+ "src/internal/session/agent-session-store.ts"() {
1829
+ init_session_transcript();
1830
+ }
1831
+ });
1832
+
1761
1833
  // src/compaction.ts
1762
1834
  function estimateTokens(text) {
1763
1835
  return Math.ceil(text.length / 4);
@@ -1961,6 +2033,10 @@ function getProviderProfile(name) {
1961
2033
  function listProviders() {
1962
2034
  return Array.from(REGISTRY.values());
1963
2035
  }
2036
+ function _resetProvidersForTests() {
2037
+ REGISTRY.clear();
2038
+ ALIASES.clear();
2039
+ }
1964
2040
  var REGISTRY, ALIASES;
1965
2041
  var init_registry = __esm({
1966
2042
  "src/internal/providers/registry.ts"() {
@@ -2893,6 +2969,9 @@ function registerBuiltins() {
2893
2969
  registerProvider(CEREBRAS);
2894
2970
  registerCatalogProviders();
2895
2971
  }
2972
+ function _resetBuiltinsRegistered() {
2973
+ _registeredState.done = false;
2974
+ }
2896
2975
  var _registeredState;
2897
2976
  var init_builtin = __esm({
2898
2977
  "src/internal/providers/builtin/index.ts"() {
@@ -3019,6 +3098,9 @@ async function loadOne(dir, entryName) {
3019
3098
  }
3020
3099
  }
3021
3100
  }
3101
+ function _resetDiscovery() {
3102
+ discoveryState.done = false;
3103
+ }
3022
3104
  var discoveryState;
3023
3105
  var init_discovery = __esm({
3024
3106
  "src/internal/providers/discovery.ts"() {
@@ -3030,6 +3112,21 @@ var init_discovery = __esm({
3030
3112
  });
3031
3113
 
3032
3114
  // src/internal/providers/index.ts
3115
+ var providers_exports = {};
3116
+ __export(providers_exports, {
3117
+ ANTHROPIC: () => ANTHROPIC,
3118
+ GEMINI: () => GEMINI,
3119
+ OPENAI: () => OPENAI,
3120
+ OPENROUTER: () => OPENROUTER,
3121
+ _resetBuiltinsRegistered: () => _resetBuiltinsRegistered,
3122
+ _resetDiscovery: () => _resetDiscovery,
3123
+ _resetProvidersForTests: () => _resetProvidersForTests,
3124
+ discoverProviderPlugins: () => discoverProviderPlugins,
3125
+ getProviderProfile: () => getProviderProfile,
3126
+ listProviders: () => listProviders,
3127
+ registerBuiltins: () => registerBuiltins,
3128
+ registerProvider: () => registerProvider
3129
+ });
3033
3130
  var init_providers = __esm({
3034
3131
  "src/internal/providers/index.ts"() {
3035
3132
  init_builtin();
@@ -6092,7 +6189,14 @@ async function compactSessionTranscript(opts) {
6092
6189
  const m = compressible[i];
6093
6190
  if (m === void 0 || m.role !== "user" || isCompactSummary(m.content)) continue;
6094
6191
  const cost = estimateTokens(m.content);
6095
- if (budget + cost > COMPACT_USER_MESSAGE_MAX_TOKENS) break;
6192
+ if (budget + cost > COMPACT_USER_MESSAGE_MAX_TOKENS) {
6193
+ const remaining = COMPACT_USER_MESSAGE_MAX_TOKENS - budget;
6194
+ if (remaining > 50) {
6195
+ preserved.unshift(`${m.content.slice(0, remaining * 4)}
6196
+ [...truncated for compaction...]`);
6197
+ }
6198
+ break;
6199
+ }
6096
6200
  budget += cost;
6097
6201
  preserved.unshift(m.content);
6098
6202
  }
@@ -6108,6 +6212,8 @@ ${summaryBody}`;
6108
6212
  transcript.appendUserTurn(summary);
6109
6213
  const delta = transcript.records().slice(prior.length);
6110
6214
  await opts.store.appendRecords(opts.loc.agentId, delta);
6215
+ const { invalidateSessionCache: invalidateSessionCache2 } = await Promise.resolve().then(() => (init_agent_session(), agent_session_exports));
6216
+ invalidateSessionCache2(opts.loc.cwd, opts.loc.agentId);
6111
6217
  const postTokens = estimateTokens([...preserved, summary].join("\n"));
6112
6218
  return { preTokens, postTokens };
6113
6219
  }
@@ -6119,9 +6225,12 @@ function buildDefaultSummarizer(opts) {
6119
6225
  const { inferProviderFromApiKey: inferProviderFromApiKey2, detectPrimaryProvider: detectPrimaryProvider2 } = await Promise.resolve().then(() => (init_real_local_run_provider(), real_local_run_provider_exports));
6120
6226
  const keyProvider = inferProviderFromApiKey2(opts.apiKey);
6121
6227
  const modelPrefix = opts.agentModel.includes("/") ? opts.agentModel.slice(0, opts.agentModel.indexOf("/")) : void 0;
6122
- const provider = keyProvider ?? modelPrefix ?? detectPrimaryProvider2();
6228
+ const { registerBuiltins: registerBuiltins2, getProviderProfile: getProviderProfile2 } = await Promise.resolve().then(() => (init_providers(), providers_exports));
6229
+ registerBuiltins2();
6230
+ const prefixProfile = modelPrefix !== void 0 ? getProviderProfile2(modelPrefix) : void 0;
6231
+ const provider = prefixProfile !== void 0 ? modelPrefix : keyProvider ?? detectPrimaryProvider2();
6123
6232
  let model;
6124
- if (keyProvider !== void 0 && keyProvider !== modelPrefix) {
6233
+ if (provider !== modelPrefix) {
6125
6234
  model = opts.agentModel;
6126
6235
  } else {
6127
6236
  try {
@@ -6196,6 +6305,122 @@ var init_compact_session = __esm({
6196
6305
  })();
6197
6306
  }
6198
6307
  });
6308
+
6309
+ // src/internal/session/agent-session.ts
6310
+ var agent_session_exports = {};
6311
+ __export(agent_session_exports, {
6312
+ appendSessionMessage: () => appendSessionMessage,
6313
+ clearAllSessions: () => clearAllSessions,
6314
+ clearSession: () => clearSession,
6315
+ enqueueSessionWrite: () => enqueueSessionWrite,
6316
+ flushSessionWrites: () => flushSessionWrites,
6317
+ getSessionMessages: () => getSessionMessages,
6318
+ hydrateSession: () => hydrateSession,
6319
+ invalidateSessionCache: () => invalidateSessionCache,
6320
+ persistTurnToTranscript: () => persistTurnToTranscript
6321
+ });
6322
+ function transcriptKey(cwd, agentId) {
6323
+ return `${cwd}::${agentId}`;
6324
+ }
6325
+ function appendSessionMessage(agentId, message) {
6326
+ const existing = sessions.get(agentId) ?? [];
6327
+ existing.push(message);
6328
+ sessions.set(agentId, existing);
6329
+ }
6330
+ function getSessionMessages(agentId) {
6331
+ return sessions.get(agentId) ?? [];
6332
+ }
6333
+ function persistTurnToTranscript(store, loc, sessionId, turn, onCompact) {
6334
+ const key2 = transcriptKey(loc.cwd, loc.agentId);
6335
+ const chained = (pendingWrites.get(key2) ?? Promise.resolve()).then(async () => {
6336
+ try {
6337
+ await persistTurn(store, loc, sessionId, turn);
6338
+ const count = (recordCounts.get(key2) ?? 0) + 1;
6339
+ recordCounts.set(key2, count);
6340
+ if (turn.autoCompact !== void 0) {
6341
+ const { autoCompactIfNeeded: autoCompactIfNeeded2 } = await Promise.resolve().then(() => (init_compact_session(), compact_session_exports));
6342
+ const fired = await autoCompactIfNeeded2({
6343
+ store,
6344
+ loc,
6345
+ sessionId,
6346
+ usageTotal: turn.autoCompact.usageTotal,
6347
+ contextWindow: turn.autoCompact.contextWindow,
6348
+ turnCount: count,
6349
+ summarize: turn.autoCompact.summarize
6350
+ });
6351
+ if (fired) onCompact?.();
6352
+ }
6353
+ } catch (cause) {
6354
+ const msg = cause instanceof Error ? cause.message : String(cause);
6355
+ process.stderr.write(
6356
+ `[theokit-sdk] session transcript write failed (${loc.agentId}): ${msg}
6357
+ `
6358
+ );
6359
+ }
6360
+ });
6361
+ pendingWrites.set(
6362
+ key2,
6363
+ chained.then(
6364
+ () => void 0,
6365
+ () => void 0
6366
+ )
6367
+ );
6368
+ }
6369
+ async function hydrateSession(agentId, loc) {
6370
+ const key2 = transcriptKey(loc.cwd, agentId);
6371
+ if (hydratedKeys.has(key2)) return;
6372
+ hydratedKeys.add(key2);
6373
+ const persisted = await readSessionMessages(loc.store, agentId);
6374
+ if (persisted.length === 0) return;
6375
+ if (!sessions.has(agentId) || sessions.get(agentId)?.length === 0) {
6376
+ sessions.set(agentId, persisted);
6377
+ }
6378
+ }
6379
+ async function flushSessionWrites() {
6380
+ while (pendingWrites.size > 0) {
6381
+ const all = Array.from(pendingWrites.values());
6382
+ pendingWrites.clear();
6383
+ await Promise.all(all);
6384
+ }
6385
+ }
6386
+ function clearSession(agentId) {
6387
+ sessions.delete(agentId);
6388
+ }
6389
+ function invalidateSessionCache(cwd, agentId) {
6390
+ sessions.delete(agentId);
6391
+ hydratedKeys.delete(transcriptKey(cwd, agentId));
6392
+ }
6393
+ function enqueueSessionWrite(cwd, agentId, fn) {
6394
+ const key2 = transcriptKey(cwd, agentId);
6395
+ const prior = pendingWrites.get(key2) ?? Promise.resolve();
6396
+ const result = prior.then(fn);
6397
+ pendingWrites.set(
6398
+ key2,
6399
+ result.then(
6400
+ () => void 0,
6401
+ () => void 0
6402
+ )
6403
+ );
6404
+ return result;
6405
+ }
6406
+ function clearAllSessions() {
6407
+ sessions.clear();
6408
+ hydratedKeys.clear();
6409
+ recordCounts.clear();
6410
+ const g = globalThis;
6411
+ const sym = /* @__PURE__ */ Symbol.for("theokit-sdk.session.auto-compact-attempts");
6412
+ g[sym]?.clear();
6413
+ }
6414
+ var sessions, hydratedKeys, pendingWrites, recordCounts;
6415
+ var init_agent_session = __esm({
6416
+ "src/internal/session/agent-session.ts"() {
6417
+ init_agent_session_store();
6418
+ sessions = /* @__PURE__ */ new Map();
6419
+ hydratedKeys = /* @__PURE__ */ new Set();
6420
+ pendingWrites = /* @__PURE__ */ new Map();
6421
+ recordCounts = /* @__PURE__ */ new Map();
6422
+ }
6423
+ });
6199
6424
  async function withToolWhitelist(whitelist, fn) {
6200
6425
  return toolWhitelistStore.run(whitelist, fn);
6201
6426
  }
@@ -13016,147 +13241,6 @@ function parseDecisionFromStdout(stdout) {
13016
13241
  init_run_events();
13017
13242
  init_session_summary_writer();
13018
13243
 
13019
- // src/internal/session/agent-session-store.ts
13020
- init_session_transcript();
13021
- function seedTranscript(prior, opts) {
13022
- return SessionTranscript.fromRecords(prior, opts);
13023
- }
13024
- function mapAgentTurn(steps) {
13025
- const assistant = {};
13026
- const toolResults = [];
13027
- const toolCalls = [];
13028
- for (const step of steps) {
13029
- if (step.type === "thinkingMessage") assistant.thinking = step.message.text;
13030
- else if (step.type === "assistantMessage") assistant.text = step.message.text;
13031
- else if (step.type === "toolCall")
13032
- toolCalls.push({
13033
- id: step.message.callId,
13034
- name: step.message.name,
13035
- input: step.message.args ?? {}
13036
- });
13037
- else
13038
- toolResults.push({
13039
- toolUseId: step.message.callId,
13040
- content: step.message.result,
13041
- isError: step.message.isError
13042
- });
13043
- }
13044
- if (toolCalls.length > 0) assistant.toolCalls = toolCalls;
13045
- return { assistant, toolResults };
13046
- }
13047
- function hasAssistantContent(a) {
13048
- return a.text !== void 0 || a.thinking !== void 0 || (a.toolCalls?.length ?? 0) > 0;
13049
- }
13050
- function appendConversation(transcript, conversation) {
13051
- for (const ct of conversation) {
13052
- if (ct.type !== "agentConversationTurn") continue;
13053
- const { assistant, toolResults } = mapAgentTurn(ct.turn.steps);
13054
- if (hasAssistantContent(assistant)) transcript.appendAssistantTurn(assistant);
13055
- if (toolResults.length > 0) transcript.appendToolResults(toolResults);
13056
- }
13057
- }
13058
- async function readSessionMessages(store, agentId) {
13059
- const records = await store.readRecords(agentId);
13060
- return reconstructMessages(records).map(narrowToSessionMessage);
13061
- }
13062
- function partToText(p) {
13063
- if (p.type === "text") return p.text ?? "";
13064
- if (p.type === "tool_use") return `[tool call] ${p.name ?? ""}`;
13065
- if (p.type === "tool_result") {
13066
- const body = typeof p.content === "string" ? p.content : JSON.stringify(p.content);
13067
- return `[tool result] ${body}`;
13068
- }
13069
- return "";
13070
- }
13071
- function narrowToSessionMessage(m) {
13072
- const role = m.role === "user" ? "user" : "assistant";
13073
- const text = m.content.map(partToText).filter((s) => s.length > 0).join("\n");
13074
- return { role, text };
13075
- }
13076
- function deltaRecords(transcript, priorLength) {
13077
- return transcript.records().slice(priorLength);
13078
- }
13079
- async function persistTurn(store, loc, sessionId, turn) {
13080
- const prior = await store.readRecords(loc.agentId);
13081
- const transcript = seedTranscript(prior, { cwd: loc.cwd, sessionId, model: loc.model });
13082
- transcript.appendUserTurn(turn.userText);
13083
- appendConversation(transcript, turn.conversation);
13084
- await store.appendRecords(loc.agentId, deltaRecords(transcript, prior.length));
13085
- }
13086
-
13087
- // src/internal/session/agent-session.ts
13088
- var sessions = /* @__PURE__ */ new Map();
13089
- var hydratedKeys = /* @__PURE__ */ new Set();
13090
- var pendingWrites = /* @__PURE__ */ new Map();
13091
- var recordCounts = /* @__PURE__ */ new Map();
13092
- function transcriptKey(cwd, agentId) {
13093
- return `${cwd}::${agentId}`;
13094
- }
13095
- function appendSessionMessage(agentId, message) {
13096
- const existing = sessions.get(agentId) ?? [];
13097
- existing.push(message);
13098
- sessions.set(agentId, existing);
13099
- }
13100
- function getSessionMessages(agentId) {
13101
- return sessions.get(agentId) ?? [];
13102
- }
13103
- function persistTurnToTranscript(store, loc, sessionId, turn, onCompact) {
13104
- const key2 = transcriptKey(loc.cwd, loc.agentId);
13105
- const chained = (pendingWrites.get(key2) ?? Promise.resolve()).then(async () => {
13106
- try {
13107
- await persistTurn(store, loc, sessionId, turn);
13108
- const count = (recordCounts.get(key2) ?? 0) + 1;
13109
- recordCounts.set(key2, count);
13110
- if (turn.autoCompact !== void 0) {
13111
- const { autoCompactIfNeeded: autoCompactIfNeeded2 } = await Promise.resolve().then(() => (init_compact_session(), compact_session_exports));
13112
- const fired = await autoCompactIfNeeded2({
13113
- store,
13114
- loc,
13115
- sessionId,
13116
- usageTotal: turn.autoCompact.usageTotal,
13117
- contextWindow: turn.autoCompact.contextWindow,
13118
- turnCount: count,
13119
- summarize: turn.autoCompact.summarize
13120
- });
13121
- if (fired) onCompact?.();
13122
- }
13123
- } catch (cause) {
13124
- const msg = cause instanceof Error ? cause.message : String(cause);
13125
- process.stderr.write(
13126
- `[theokit-sdk] session transcript write failed (${loc.agentId}): ${msg}
13127
- `
13128
- );
13129
- }
13130
- });
13131
- pendingWrites.set(
13132
- key2,
13133
- chained.then(
13134
- () => void 0,
13135
- () => void 0
13136
- )
13137
- );
13138
- }
13139
- async function hydrateSession(agentId, loc) {
13140
- const key2 = transcriptKey(loc.cwd, agentId);
13141
- if (hydratedKeys.has(key2)) return;
13142
- hydratedKeys.add(key2);
13143
- const persisted = await readSessionMessages(loc.store, agentId);
13144
- if (persisted.length === 0) return;
13145
- if (!sessions.has(agentId) || sessions.get(agentId)?.length === 0) {
13146
- sessions.set(agentId, persisted);
13147
- }
13148
- }
13149
- async function flushSessionWrites() {
13150
- while (pendingWrites.size > 0) {
13151
- const all = Array.from(pendingWrites.values());
13152
- pendingWrites.clear();
13153
- await Promise.all(all);
13154
- }
13155
- }
13156
- function clearSession(agentId) {
13157
- sessions.delete(agentId);
13158
- }
13159
-
13160
13244
  // src/internal/runtime/memory/memory-path-selector.ts
13161
13245
  var PORT_MEMORY_PATH_ENV_VAR = "THEOKIT_PORT_MEMORY_PATH";
13162
13246
  function shouldUsePortMemoryPath() {
@@ -13207,6 +13291,20 @@ async function runPostRunLifecycle(inputs) {
13207
13291
  const { getCatalogModelInfo: getCatalogModelInfo2 } = await Promise.resolve().then(() => (init_catalog_loader(), catalog_loader_exports));
13208
13292
  const { buildDefaultSummarizer: buildDefaultSummarizer2 } = await Promise.resolve().then(() => (init_compact_session(), compact_session_exports));
13209
13293
  const contextWindow = getCatalogModelInfo2(model)?.limit?.context;
13294
+ if (contextWindow === void 0) {
13295
+ const g = globalThis;
13296
+ const sym = /* @__PURE__ */ Symbol.for("theokit-sdk.compact.no-cw-warned");
13297
+ const warned3 = g[sym] ??= /* @__PURE__ */ new Set();
13298
+ if (!warned3.has(model)) {
13299
+ warned3.add(model);
13300
+ process.stderr.write(
13301
+ `[theokit-sdk] auto-compaction disabled: model "${model}" has no context-window entry in the catalog
13302
+ `
13303
+ );
13304
+ }
13305
+ }
13306
+ const lastRequestUsage = result.usage?.requests?.at(-1)?.totalTokens;
13307
+ const usageForTrigger = lastRequestUsage ?? result.usage?.totalTokens;
13210
13308
  persistTurnToTranscript(
13211
13309
  sessionStore,
13212
13310
  { cwd: workspaceCwd, agentId, model },
@@ -13215,7 +13313,7 @@ async function runPostRunLifecycle(inputs) {
13215
13313
  userText,
13216
13314
  conversation,
13217
13315
  autoCompact: {
13218
- usageTotal: result.usage?.totalTokens,
13316
+ usageTotal: usageForTrigger,
13219
13317
  contextWindow,
13220
13318
  summarize: buildDefaultSummarizer2({
13221
13319
  agentModel: model,
@@ -21514,7 +21612,8 @@ var Agent = class _Agent {
21514
21612
  const { defaultBaseDir: defaultBaseDir2, expandTilde: expandTilde2 } = await Promise.resolve().then(() => (init_session_transcript(), session_transcript_exports));
21515
21613
  const baseDir = reg.options.local?.baseDir !== void 0 ? expandTilde2(reg.options.local.baseDir) : defaultBaseDir2();
21516
21614
  const store = new FsSessionStore2({ baseDir, cwd });
21517
- return compactSessionTranscript2({
21615
+ const { enqueueSessionWrite: enqueueSessionWrite2 } = await Promise.resolve().then(() => (init_agent_session(), agent_session_exports));
21616
+ return enqueueSessionWrite2(cwd, agentId, () => compactSessionTranscript2({
21518
21617
  store,
21519
21618
  loc: { cwd, agentId, model },
21520
21619
  sessionId: agentId,
@@ -21523,7 +21622,7 @@ var Agent = class _Agent {
21523
21622
  agentModel: model,
21524
21623
  ...reg.options.apiKey !== void 0 ? { apiKey: reg.options.apiKey } : {}
21525
21624
  })
21526
- });
21625
+ }));
21527
21626
  }
21528
21627
  /**
21529
21628
  * Permanently delete a cloud agent.