@theokit/sdk 4.22.0 → 4.23.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/dist/compaction.cjs +31 -0
- package/dist/compaction.cjs.map +1 -1
- package/dist/compaction.d.cts +79 -0
- package/dist/compaction.d.ts +79 -0
- package/dist/compaction.js +28 -1
- package/dist/compaction.js.map +1 -1
- package/dist/{cron-Bhdyjl0B.d.ts → cron-B_NkE_VM.d.ts} +15 -1
- package/dist/{cron-M2Xz7lq2.d.cts → cron-x3muPNgg.d.cts} +15 -1
- package/dist/cron.cjs +461 -332
- package/dist/cron.cjs.map +1 -1
- package/dist/cron.d.cts +2 -2
- package/dist/cron.d.ts +2 -2
- package/dist/cron.js +461 -332
- package/dist/cron.js.map +1 -1
- package/dist/{errors-gE8612p9.d.cts → errors-BdL-buYn.d.cts} +1 -1
- package/dist/{errors-CG2RpeW-.d.ts → errors-DHZtSNnj.d.ts} +1 -1
- package/dist/errors.d.cts +2 -2
- package/dist/eval.cjs +461 -332
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +461 -332
- package/dist/eval.js.map +1 -1
- package/dist/index.cjs +634 -503
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -12
- package/dist/index.d.ts +21 -12
- package/dist/index.js +634 -503
- package/dist/index.js.map +1 -1
- package/dist/internal/global-singleton.d.ts +13 -0
- package/dist/internal/llm/openai-messages.d.ts +2 -0
- package/dist/internal/local-agent/mcp-pool.d.ts +41 -0
- package/dist/internal/local-agent/real-local-run.d.ts +2 -0
- package/dist/internal/persistence/index.cjs +3 -1
- package/dist/internal/persistence/index.cjs.map +1 -1
- package/dist/internal/persistence/index.js +3 -1
- package/dist/internal/persistence/index.js.map +1 -1
- package/dist/internal/providers/registry.d.ts +1 -0
- package/dist/internal/runtime/lifecycle/context-budget-event.d.ts +25 -0
- package/dist/internal/runtime/lifecycle/goal-marker.d.ts +13 -0
- package/dist/internal/runtime/lifecycle/run-until.d.ts +0 -1
- package/dist/internal/session/agent-session.d.ts +1 -1
- package/dist/internal/session/session-cache.d.ts +20 -0
- package/dist/models.cjs +11 -15
- package/dist/models.cjs.map +1 -1
- package/dist/models.js +11 -15
- package/dist/models.js.map +1 -1
- package/dist/persistence.cjs +3 -1
- package/dist/persistence.cjs.map +1 -1
- package/dist/persistence.js +3 -1
- package/dist/persistence.js.map +1 -1
- package/dist/provider-catalog.json +144 -469
- package/dist/{run-DFM1H2jW.d.cts → run-OJbGyweZ.d.cts} +20 -1
- package/dist/{run-DFM1H2jW.d.ts → run-OJbGyweZ.d.ts} +20 -1
- package/dist/types/agent.d.ts +14 -0
- package/dist/types/run-events.d.ts +20 -1
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.js.map +1 -1
- package/package.json +2 -2
- package/dist/goal-loop.d.ts +0 -35
package/dist/eval.js
CHANGED
|
@@ -1594,6 +1594,44 @@ var init_plugin_guards = __esm({
|
|
|
1594
1594
|
}
|
|
1595
1595
|
});
|
|
1596
1596
|
|
|
1597
|
+
// src/compaction.ts
|
|
1598
|
+
function resolveEffectiveContextWindow(input) {
|
|
1599
|
+
if (!(input.margin > 0) || input.margin > 1) {
|
|
1600
|
+
throw new ContextWindowMarginError(input.margin);
|
|
1601
|
+
}
|
|
1602
|
+
const withMargin = (raw) => Math.floor(raw * input.margin);
|
|
1603
|
+
if (input.override !== void 0) {
|
|
1604
|
+
const clamped = input.catalog !== void 0 && input.override > input.catalog;
|
|
1605
|
+
const raw = clamped ? input.catalog : input.override;
|
|
1606
|
+
return { window: withMargin(raw), source: "override", clamped };
|
|
1607
|
+
}
|
|
1608
|
+
if (input.catalog !== void 0) {
|
|
1609
|
+
return { window: withMargin(input.catalog), source: "catalog", clamped: false };
|
|
1610
|
+
}
|
|
1611
|
+
return { window: withMargin(input.floor ?? 0), source: "fallback", clamped: false };
|
|
1612
|
+
}
|
|
1613
|
+
function estimateTokens(text) {
|
|
1614
|
+
return Math.ceil(text.length / 4);
|
|
1615
|
+
}
|
|
1616
|
+
var ContextWindowMarginError, CONTEXT_WINDOW_MARGIN, CONTEXT_WINDOW_FLOOR;
|
|
1617
|
+
var init_compaction = __esm({
|
|
1618
|
+
"src/compaction.ts"() {
|
|
1619
|
+
init_errors();
|
|
1620
|
+
ContextWindowMarginError = class extends TheokitAgentError {
|
|
1621
|
+
constructor(margin) {
|
|
1622
|
+
super(
|
|
1623
|
+
`context-window margin must be in (0, 1], got ${String(margin)}. A margin above 1 grows the assumed window and delays compaction past the real limit.`,
|
|
1624
|
+
{ code: "invalid_context_window_margin" }
|
|
1625
|
+
);
|
|
1626
|
+
this.margin = margin;
|
|
1627
|
+
}
|
|
1628
|
+
margin;
|
|
1629
|
+
};
|
|
1630
|
+
CONTEXT_WINDOW_MARGIN = 0.95;
|
|
1631
|
+
CONTEXT_WINDOW_FLOOR = 128e3;
|
|
1632
|
+
}
|
|
1633
|
+
});
|
|
1634
|
+
|
|
1597
1635
|
// src/types/run-events.ts
|
|
1598
1636
|
function emitRunEvent(sink, event) {
|
|
1599
1637
|
if (sink === void 0) return;
|
|
@@ -1606,6 +1644,18 @@ var init_run_events = __esm({
|
|
|
1606
1644
|
"src/types/run-events.ts"() {
|
|
1607
1645
|
}
|
|
1608
1646
|
});
|
|
1647
|
+
|
|
1648
|
+
// src/internal/global-singleton.ts
|
|
1649
|
+
function globalSingleton(key, create) {
|
|
1650
|
+
const g = globalThis;
|
|
1651
|
+
const sym = Symbol.for(key);
|
|
1652
|
+
if (g[sym] === void 0) g[sym] = create();
|
|
1653
|
+
return g[sym];
|
|
1654
|
+
}
|
|
1655
|
+
var init_global_singleton = __esm({
|
|
1656
|
+
"src/internal/global-singleton.ts"() {
|
|
1657
|
+
}
|
|
1658
|
+
});
|
|
1609
1659
|
var MODALITIES, costSchema, limitSchema, modalitiesSchema, catalogModelSchema;
|
|
1610
1660
|
var init_catalog_schema = __esm({
|
|
1611
1661
|
"src/internal/providers/catalog-schema.ts"() {
|
|
@@ -1646,12 +1696,6 @@ var init_catalog_schema = __esm({
|
|
|
1646
1696
|
});
|
|
1647
1697
|
|
|
1648
1698
|
// src/internal/providers/registry.ts
|
|
1649
|
-
function globalSingleton(key, create) {
|
|
1650
|
-
const g = globalThis;
|
|
1651
|
-
const sym = Symbol.for(key);
|
|
1652
|
-
if (g[sym] === void 0) g[sym] = create();
|
|
1653
|
-
return g[sym];
|
|
1654
|
-
}
|
|
1655
1699
|
function registerProvider(profile) {
|
|
1656
1700
|
if (REGISTRY.has(profile.name)) {
|
|
1657
1701
|
process.stderr.write(`[theokit-sdk] Provider "${profile.name}" overridden by user plugin.
|
|
@@ -1676,6 +1720,7 @@ function getProviderProfile(name) {
|
|
|
1676
1720
|
var REGISTRY, ALIASES;
|
|
1677
1721
|
var init_registry = __esm({
|
|
1678
1722
|
"src/internal/providers/registry.ts"() {
|
|
1723
|
+
init_global_singleton();
|
|
1679
1724
|
REGISTRY = globalSingleton(
|
|
1680
1725
|
"theokit-sdk.providers.registry",
|
|
1681
1726
|
() => /* @__PURE__ */ new Map()
|
|
@@ -1683,12 +1728,6 @@ var init_registry = __esm({
|
|
|
1683
1728
|
ALIASES = globalSingleton("theokit-sdk.providers.aliases", () => /* @__PURE__ */ new Map());
|
|
1684
1729
|
}
|
|
1685
1730
|
});
|
|
1686
|
-
function globalSingleton2(key, create) {
|
|
1687
|
-
const g = globalThis;
|
|
1688
|
-
const sym = Symbol.for(key);
|
|
1689
|
-
if (g[sym] === void 0) g[sym] = create();
|
|
1690
|
-
return g[sym];
|
|
1691
|
-
}
|
|
1692
1731
|
function getCatalogModelInfo(key) {
|
|
1693
1732
|
ensureModelIndexLoaded();
|
|
1694
1733
|
return modelInfoIndex.get(key);
|
|
@@ -1777,32 +1816,24 @@ function registerCatalogProviders(opts) {
|
|
|
1777
1816
|
var __dirname_resolved, modelInfoIndex, patchedModelKeys, indexState;
|
|
1778
1817
|
var init_catalog_loader = __esm({
|
|
1779
1818
|
"src/internal/providers/catalog-loader.ts"() {
|
|
1819
|
+
init_global_singleton();
|
|
1780
1820
|
init_catalog_schema();
|
|
1781
1821
|
init_registry();
|
|
1782
1822
|
__dirname_resolved = dirname(fileURLToPath(import.meta.url));
|
|
1783
|
-
modelInfoIndex =
|
|
1823
|
+
modelInfoIndex = globalSingleton(
|
|
1784
1824
|
"theokit-sdk.providers.model-info-index",
|
|
1785
1825
|
() => /* @__PURE__ */ new Map()
|
|
1786
1826
|
);
|
|
1787
|
-
patchedModelKeys =
|
|
1827
|
+
patchedModelKeys = globalSingleton(
|
|
1788
1828
|
"theokit-sdk.providers.model-info-patched",
|
|
1789
1829
|
() => /* @__PURE__ */ new Set()
|
|
1790
1830
|
);
|
|
1791
|
-
indexState =
|
|
1831
|
+
indexState = globalSingleton("theokit-sdk.providers.model-info-loaded", () => ({
|
|
1792
1832
|
loaded: false
|
|
1793
1833
|
}));
|
|
1794
1834
|
}
|
|
1795
1835
|
});
|
|
1796
1836
|
|
|
1797
|
-
// src/compaction.ts
|
|
1798
|
-
function estimateTokens(text) {
|
|
1799
|
-
return Math.ceil(text.length / 4);
|
|
1800
|
-
}
|
|
1801
|
-
var init_compaction = __esm({
|
|
1802
|
-
"src/compaction.ts"() {
|
|
1803
|
-
}
|
|
1804
|
-
});
|
|
1805
|
-
|
|
1806
1837
|
// src/internal/providers/builtin/anthropic.ts
|
|
1807
1838
|
var ANTHROPIC;
|
|
1808
1839
|
var init_anthropic = __esm({
|
|
@@ -2598,12 +2629,6 @@ var init_builtin = __esm({
|
|
|
2598
2629
|
})();
|
|
2599
2630
|
}
|
|
2600
2631
|
});
|
|
2601
|
-
function globalSingleton3(key, create) {
|
|
2602
|
-
const g = globalThis;
|
|
2603
|
-
const sym = Symbol.for(key);
|
|
2604
|
-
if (g[sym] === void 0) g[sym] = create();
|
|
2605
|
-
return g[sym];
|
|
2606
|
-
}
|
|
2607
2632
|
function pluginsRoot() {
|
|
2608
2633
|
return join(homedir(), ".theokit", "plugins", "model-providers");
|
|
2609
2634
|
}
|
|
@@ -2695,8 +2720,9 @@ async function loadOne(dir, entryName) {
|
|
|
2695
2720
|
var discoveryState;
|
|
2696
2721
|
var init_discovery = __esm({
|
|
2697
2722
|
"src/internal/providers/discovery.ts"() {
|
|
2723
|
+
init_global_singleton();
|
|
2698
2724
|
init_registry();
|
|
2699
|
-
discoveryState =
|
|
2725
|
+
discoveryState = globalSingleton("theokit-sdk.providers.discovered", () => ({
|
|
2700
2726
|
done: false
|
|
2701
2727
|
}));
|
|
2702
2728
|
}
|
|
@@ -4372,6 +4398,68 @@ var init_hermes_tool_extract = __esm({
|
|
|
4372
4398
|
}
|
|
4373
4399
|
});
|
|
4374
4400
|
|
|
4401
|
+
// src/internal/llm/openai-messages.ts
|
|
4402
|
+
function toOpenAIMessages(message) {
|
|
4403
|
+
if (message.role === "system") return [systemMessage(message)];
|
|
4404
|
+
if (message.role === "user") return userOrToolMessages(message);
|
|
4405
|
+
return [assistantMessage(message)];
|
|
4406
|
+
}
|
|
4407
|
+
function systemMessage(message) {
|
|
4408
|
+
return { role: "system", content: joinTextParts2(message) };
|
|
4409
|
+
}
|
|
4410
|
+
function joinTextParts2(message) {
|
|
4411
|
+
return message.content.filter((part) => part.type === "text").map((part) => part.text).join("\n");
|
|
4412
|
+
}
|
|
4413
|
+
function userOrToolMessages(message) {
|
|
4414
|
+
const out = [];
|
|
4415
|
+
for (const part of message.content) {
|
|
4416
|
+
if (part.type === "tool_result") {
|
|
4417
|
+
out.push({
|
|
4418
|
+
role: "tool",
|
|
4419
|
+
tool_call_id: part.toolUseId,
|
|
4420
|
+
// SE7 — this wire's tool role is string-only: text blocks flatten; an
|
|
4421
|
+
// image block fails fast (ConfigurationError).
|
|
4422
|
+
content: toStringToolResultContent(part.content, "openai")
|
|
4423
|
+
});
|
|
4424
|
+
}
|
|
4425
|
+
}
|
|
4426
|
+
const userText = joinTextParts2(message);
|
|
4427
|
+
const imageParts = message.content.filter(
|
|
4428
|
+
(p) => p.type === "image"
|
|
4429
|
+
);
|
|
4430
|
+
if (imageParts.length > 0) {
|
|
4431
|
+
const content = [];
|
|
4432
|
+
if (userText.length > 0) content.push({ type: "text", text: userText });
|
|
4433
|
+
for (const img of imageParts) {
|
|
4434
|
+
const url = img.source.type === "base64" ? `data:${img.source.media_type};base64,${img.source.data}` : img.source.url;
|
|
4435
|
+
content.push({ type: "image_url", image_url: { url } });
|
|
4436
|
+
}
|
|
4437
|
+
out.push({ role: "user", content });
|
|
4438
|
+
} else if (userText.length > 0) {
|
|
4439
|
+
out.push({ role: "user", content: userText });
|
|
4440
|
+
}
|
|
4441
|
+
return out;
|
|
4442
|
+
}
|
|
4443
|
+
function assistantMessage(message) {
|
|
4444
|
+
const text = joinTextParts2(message);
|
|
4445
|
+
const toolCalls = message.content.filter((part) => part.type === "tool_use").map((part) => {
|
|
4446
|
+
const tc = part;
|
|
4447
|
+
return {
|
|
4448
|
+
id: tc.id,
|
|
4449
|
+
type: "function",
|
|
4450
|
+
function: { name: tc.name, arguments: JSON.stringify(tc.input) }
|
|
4451
|
+
};
|
|
4452
|
+
});
|
|
4453
|
+
const result = { role: "assistant", content: text };
|
|
4454
|
+
if (toolCalls.length > 0) result.tool_calls = toolCalls;
|
|
4455
|
+
return result;
|
|
4456
|
+
}
|
|
4457
|
+
var init_openai_messages = __esm({
|
|
4458
|
+
"src/internal/llm/openai-messages.ts"() {
|
|
4459
|
+
init_tool_result_content();
|
|
4460
|
+
}
|
|
4461
|
+
});
|
|
4462
|
+
|
|
4375
4463
|
// src/internal/llm/openai.ts
|
|
4376
4464
|
function deriveChatPath(baseUrl) {
|
|
4377
4465
|
try {
|
|
@@ -4433,61 +4521,6 @@ function encodeOpenAIResponseFormat(rf) {
|
|
|
4433
4521
|
}
|
|
4434
4522
|
};
|
|
4435
4523
|
}
|
|
4436
|
-
function toOpenAIMessages(message) {
|
|
4437
|
-
if (message.role === "system") return [systemMessage(message)];
|
|
4438
|
-
if (message.role === "user") return userOrToolMessages(message);
|
|
4439
|
-
return [assistantMessage(message)];
|
|
4440
|
-
}
|
|
4441
|
-
function systemMessage(message) {
|
|
4442
|
-
return { role: "system", content: joinTextParts2(message) };
|
|
4443
|
-
}
|
|
4444
|
-
function joinTextParts2(message) {
|
|
4445
|
-
return message.content.filter((part) => part.type === "text").map((part) => part.text).join("\n");
|
|
4446
|
-
}
|
|
4447
|
-
function userOrToolMessages(message) {
|
|
4448
|
-
const out = [];
|
|
4449
|
-
for (const part of message.content) {
|
|
4450
|
-
if (part.type === "tool_result") {
|
|
4451
|
-
out.push({
|
|
4452
|
-
role: "tool",
|
|
4453
|
-
tool_call_id: part.toolUseId,
|
|
4454
|
-
// SE7 — this wire's tool role is string-only: text blocks flatten; an
|
|
4455
|
-
// image block fails fast (ConfigurationError).
|
|
4456
|
-
content: toStringToolResultContent(part.content, "openai")
|
|
4457
|
-
});
|
|
4458
|
-
}
|
|
4459
|
-
}
|
|
4460
|
-
const userText = joinTextParts2(message);
|
|
4461
|
-
const imageParts = message.content.filter(
|
|
4462
|
-
(p) => p.type === "image"
|
|
4463
|
-
);
|
|
4464
|
-
if (imageParts.length > 0) {
|
|
4465
|
-
const content = [];
|
|
4466
|
-
if (userText.length > 0) content.push({ type: "text", text: userText });
|
|
4467
|
-
for (const img of imageParts) {
|
|
4468
|
-
const url = img.source.type === "base64" ? `data:${img.source.media_type};base64,${img.source.data}` : img.source.url;
|
|
4469
|
-
content.push({ type: "image_url", image_url: { url } });
|
|
4470
|
-
}
|
|
4471
|
-
out.push({ role: "user", content });
|
|
4472
|
-
} else if (userText.length > 0) {
|
|
4473
|
-
out.push({ role: "user", content: userText });
|
|
4474
|
-
}
|
|
4475
|
-
return out;
|
|
4476
|
-
}
|
|
4477
|
-
function assistantMessage(message) {
|
|
4478
|
-
const text = joinTextParts2(message);
|
|
4479
|
-
const toolCalls = message.content.filter((part) => part.type === "tool_use").map((part) => {
|
|
4480
|
-
const tc = part;
|
|
4481
|
-
return {
|
|
4482
|
-
id: tc.id,
|
|
4483
|
-
type: "function",
|
|
4484
|
-
function: { name: tc.name, arguments: JSON.stringify(tc.input) }
|
|
4485
|
-
};
|
|
4486
|
-
});
|
|
4487
|
-
const result = { role: "assistant", content: text };
|
|
4488
|
-
if (toolCalls.length > 0) result.tool_calls = toolCalls;
|
|
4489
|
-
return result;
|
|
4490
|
-
}
|
|
4491
4524
|
var OpenAIClient, OpenAIStreamAccumulator, openAISystemText;
|
|
4492
4525
|
var init_openai2 = __esm({
|
|
4493
4526
|
"src/internal/llm/openai.ts"() {
|
|
@@ -4496,8 +4529,8 @@ var init_openai2 = __esm({
|
|
|
4496
4529
|
init_openai_compatible2();
|
|
4497
4530
|
init_finish();
|
|
4498
4531
|
init_hermes_tool_extract();
|
|
4532
|
+
init_openai_messages();
|
|
4499
4533
|
init_sse();
|
|
4500
|
-
init_tool_result_content();
|
|
4501
4534
|
OpenAIClient = class {
|
|
4502
4535
|
constructor(options) {
|
|
4503
4536
|
this.options = options;
|
|
@@ -5586,6 +5619,14 @@ function selectTransport(profile, apiKey) {
|
|
|
5586
5619
|
const ctx = { apiKey };
|
|
5587
5620
|
return { fetch: profile.transform.fetch?.(ctx), headers: profile.transform.headers?.(ctx) };
|
|
5588
5621
|
};
|
|
5622
|
+
const comTransform = (opts, criar) => {
|
|
5623
|
+
const t = applyTransform();
|
|
5624
|
+
assertOAuthResolved(t);
|
|
5625
|
+
if (t.fetch !== void 0) opts.fetch = t.fetch;
|
|
5626
|
+
const merged = profile.extraHeaders !== void 0 || t.headers !== void 0 ? { ...profile.extraHeaders, ...t.headers } : void 0;
|
|
5627
|
+
if (merged !== void 0) opts.extraHeaders = merged;
|
|
5628
|
+
return criar(opts);
|
|
5629
|
+
};
|
|
5589
5630
|
const assertOAuthResolved = (t) => {
|
|
5590
5631
|
if (apiKey !== "__oauth_lazy_token__") return;
|
|
5591
5632
|
const auth = t.headers?.authorization ?? t.headers?.Authorization;
|
|
@@ -5614,12 +5655,7 @@ function selectTransport(profile, apiKey) {
|
|
|
5614
5655
|
}
|
|
5615
5656
|
const envOverride = resolveBaseUrlEnvOverride(profile.name);
|
|
5616
5657
|
if (envOverride !== void 0) opts.baseUrl = envOverride;
|
|
5617
|
-
|
|
5618
|
-
assertOAuthResolved(t);
|
|
5619
|
-
if (t.fetch !== void 0) opts.fetch = t.fetch;
|
|
5620
|
-
const merged = profile.extraHeaders !== void 0 || t.headers !== void 0 ? { ...profile.extraHeaders, ...t.headers } : void 0;
|
|
5621
|
-
if (merged !== void 0) opts.extraHeaders = merged;
|
|
5622
|
-
return new OpenAIClient(opts);
|
|
5658
|
+
return comTransform(opts, (o) => new OpenAIClient(o));
|
|
5623
5659
|
}
|
|
5624
5660
|
if (profile.apiMode === "anthropic_messages") {
|
|
5625
5661
|
if (profile.name === "vertex") {
|
|
@@ -5628,12 +5664,7 @@ function selectTransport(profile, apiKey) {
|
|
|
5628
5664
|
}
|
|
5629
5665
|
const opts = { apiKey };
|
|
5630
5666
|
opts.baseUrl = process.env.ANTHROPIC_API_BASE_URL ?? profile.baseUrl;
|
|
5631
|
-
|
|
5632
|
-
assertOAuthResolved(t);
|
|
5633
|
-
if (t.fetch !== void 0) opts.fetch = t.fetch;
|
|
5634
|
-
const merged = profile.extraHeaders !== void 0 || t.headers !== void 0 ? { ...profile.extraHeaders, ...t.headers } : void 0;
|
|
5635
|
-
if (merged !== void 0) opts.extraHeaders = merged;
|
|
5636
|
-
return new AnthropicClient(opts);
|
|
5667
|
+
return comTransform(opts, (o) => new AnthropicClient(o));
|
|
5637
5668
|
}
|
|
5638
5669
|
if (profile.apiMode === "bedrock_anthropic") {
|
|
5639
5670
|
const realKey = apiKey === "__bedrock_lazy_token__" ? void 0 : apiKey;
|
|
@@ -5790,202 +5821,52 @@ function buildCompressionPrompt(messages) {
|
|
|
5790
5821
|
|
|
5791
5822
|
--- CONVERSATION TO SUMMARIZE ---
|
|
5792
5823
|
${formatted}
|
|
5793
|
-
--- END ---`;
|
|
5794
|
-
}
|
|
5795
|
-
async function compressConversationWindow(opts) {
|
|
5796
|
-
const userPrompt = buildCompressionPrompt(opts.messages);
|
|
5797
|
-
let summary;
|
|
5798
|
-
try {
|
|
5799
|
-
summary = await opts.callLlm(opts.model, COMPRESSION_SYSTEM, userPrompt);
|
|
5800
|
-
} catch (cause) {
|
|
5801
|
-
throw new CompressionFailedError(
|
|
5802
|
-
`Compression LLM call failed: ${cause instanceof Error ? cause.message : String(cause)}`,
|
|
5803
|
-
{ cause: cause instanceof Error ? cause : void 0 }
|
|
5804
|
-
);
|
|
5805
|
-
}
|
|
5806
|
-
if (!summary || summary.trim().length === 0) {
|
|
5807
|
-
throw new CompressionFailedError(
|
|
5808
|
-
"Compression LLM returned empty summary \u2014 reduction ineffective."
|
|
5809
|
-
);
|
|
5810
|
-
}
|
|
5811
|
-
return {
|
|
5812
|
-
role: "system",
|
|
5813
|
-
content: `[Compressed conversation summary]: ${summary.trim()}`
|
|
5814
|
-
};
|
|
5815
|
-
}
|
|
5816
|
-
var CompressionFailedError, COMPRESSION_SYSTEM;
|
|
5817
|
-
var init_compression_summarizer = __esm({
|
|
5818
|
-
"src/internal/runtime/compression/compression-summarizer.ts"() {
|
|
5819
|
-
CompressionFailedError = class extends Error {
|
|
5820
|
-
name = "CompressionFailedError";
|
|
5821
|
-
};
|
|
5822
|
-
COMPRESSION_SYSTEM = "You are a conversation summarizer. Produce a concise factual summary. Preserve all decisions, preferences, code snippets, and action items. Do not add commentary or opinions. Output ONLY the summary text.";
|
|
5823
|
-
}
|
|
5824
|
-
});
|
|
5825
|
-
|
|
5826
|
-
// src/internal/session/agent-session-store.ts
|
|
5827
|
-
function seedTranscript(prior, opts) {
|
|
5828
|
-
return SessionTranscript.fromRecords(prior, opts);
|
|
5829
|
-
}
|
|
5830
|
-
function mapAgentTurn(steps) {
|
|
5831
|
-
const assistant = {};
|
|
5832
|
-
const toolResults = [];
|
|
5833
|
-
const toolCalls = [];
|
|
5834
|
-
for (const step of steps) {
|
|
5835
|
-
if (step.type === "thinkingMessage") assistant.thinking = step.message.text;
|
|
5836
|
-
else if (step.type === "assistantMessage") assistant.text = step.message.text;
|
|
5837
|
-
else if (step.type === "toolCall")
|
|
5838
|
-
toolCalls.push({
|
|
5839
|
-
id: step.message.callId,
|
|
5840
|
-
name: step.message.name,
|
|
5841
|
-
input: step.message.args ?? {}
|
|
5842
|
-
});
|
|
5843
|
-
else
|
|
5844
|
-
toolResults.push({
|
|
5845
|
-
toolUseId: step.message.callId,
|
|
5846
|
-
content: step.message.result,
|
|
5847
|
-
isError: step.message.isError
|
|
5848
|
-
});
|
|
5849
|
-
}
|
|
5850
|
-
if (toolCalls.length > 0) assistant.toolCalls = toolCalls;
|
|
5851
|
-
return { assistant, toolResults };
|
|
5852
|
-
}
|
|
5853
|
-
function hasAssistantContent(a) {
|
|
5854
|
-
return a.text !== void 0 || a.thinking !== void 0 || (a.toolCalls?.length ?? 0) > 0;
|
|
5855
|
-
}
|
|
5856
|
-
function appendConversation(transcript, conversation) {
|
|
5857
|
-
for (const ct of conversation) {
|
|
5858
|
-
if (ct.type !== "agentConversationTurn") continue;
|
|
5859
|
-
const { assistant, toolResults } = mapAgentTurn(ct.turn.steps);
|
|
5860
|
-
if (hasAssistantContent(assistant)) transcript.appendAssistantTurn(assistant);
|
|
5861
|
-
if (toolResults.length > 0) transcript.appendToolResults(toolResults);
|
|
5862
|
-
}
|
|
5863
|
-
}
|
|
5864
|
-
async function readSessionMessages(store, agentId) {
|
|
5865
|
-
const records = await store.readRecords(agentId);
|
|
5866
|
-
return reconstructMessages(records).map(narrowToSessionMessage);
|
|
5867
|
-
}
|
|
5868
|
-
function partToText(p) {
|
|
5869
|
-
if (p.type === "text") return p.text ?? "";
|
|
5870
|
-
if (p.type === "tool_use") return `[tool call] ${p.name ?? ""}`;
|
|
5871
|
-
if (p.type === "tool_result") {
|
|
5872
|
-
const body = typeof p.content === "string" ? p.content : JSON.stringify(p.content);
|
|
5873
|
-
return `[tool result] ${body}`;
|
|
5874
|
-
}
|
|
5875
|
-
return "";
|
|
5876
|
-
}
|
|
5877
|
-
function narrowToSessionMessage(m) {
|
|
5878
|
-
const role = m.role === "user" ? "user" : "assistant";
|
|
5879
|
-
const text = m.content.map(partToText).filter((s) => s.length > 0).join("\n");
|
|
5880
|
-
return { role, text };
|
|
5881
|
-
}
|
|
5882
|
-
function deltaRecords(transcript, priorLength) {
|
|
5883
|
-
return transcript.records().slice(priorLength);
|
|
5884
|
-
}
|
|
5885
|
-
async function persistTurn(store, loc, sessionId, turn) {
|
|
5886
|
-
const prior = await store.readRecords(loc.agentId);
|
|
5887
|
-
const transcript = seedTranscript(prior, { cwd: loc.cwd, sessionId, model: loc.model });
|
|
5888
|
-
transcript.appendUserTurn(turn.userText);
|
|
5889
|
-
appendConversation(transcript, turn.conversation);
|
|
5890
|
-
await store.appendRecords(loc.agentId, deltaRecords(transcript, prior.length));
|
|
5891
|
-
}
|
|
5892
|
-
var init_agent_session_store = __esm({
|
|
5893
|
-
"src/internal/session/agent-session-store.ts"() {
|
|
5894
|
-
init_session_transcript();
|
|
5895
|
-
}
|
|
5896
|
-
});
|
|
5897
|
-
|
|
5898
|
-
// src/internal/session/agent-session.ts
|
|
5899
|
-
function transcriptKey(cwd, agentId) {
|
|
5900
|
-
return `${cwd}::${agentId}`;
|
|
5901
|
-
}
|
|
5902
|
-
function appendSessionMessage(agentId, message) {
|
|
5903
|
-
const existing = sessions.get(agentId) ?? [];
|
|
5904
|
-
existing.push(message);
|
|
5905
|
-
sessions.set(agentId, existing);
|
|
5906
|
-
}
|
|
5907
|
-
function getSessionMessages(agentId) {
|
|
5908
|
-
return sessions.get(agentId) ?? [];
|
|
5909
|
-
}
|
|
5910
|
-
function persistTurnToTranscript(store, loc, sessionId, turn, onCompact) {
|
|
5911
|
-
const key = transcriptKey(loc.cwd, loc.agentId);
|
|
5912
|
-
const chained = (pendingWrites.get(key) ?? Promise.resolve()).then(async () => {
|
|
5913
|
-
try {
|
|
5914
|
-
await persistTurn(store, loc, sessionId, turn);
|
|
5915
|
-
const count = (recordCounts.get(key) ?? 0) + 1;
|
|
5916
|
-
recordCounts.set(key, count);
|
|
5917
|
-
if (turn.autoCompact !== void 0) {
|
|
5918
|
-
const { autoCompactIfNeeded: autoCompactIfNeeded2 } = await Promise.resolve().then(() => (init_compact_session(), compact_session_exports));
|
|
5919
|
-
const fired = await autoCompactIfNeeded2({
|
|
5920
|
-
store,
|
|
5921
|
-
loc,
|
|
5922
|
-
sessionId,
|
|
5923
|
-
usageTotal: turn.autoCompact.usageTotal,
|
|
5924
|
-
contextWindow: turn.autoCompact.contextWindow,
|
|
5925
|
-
turnCount: count,
|
|
5926
|
-
summarize: turn.autoCompact.summarize
|
|
5927
|
-
});
|
|
5928
|
-
if (fired) onCompact?.();
|
|
5929
|
-
}
|
|
5930
|
-
} catch (cause) {
|
|
5931
|
-
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
5932
|
-
process.stderr.write(
|
|
5933
|
-
`[theokit-sdk] session transcript write failed (${loc.agentId}): ${msg}
|
|
5934
|
-
`
|
|
5935
|
-
);
|
|
5936
|
-
}
|
|
5937
|
-
});
|
|
5938
|
-
pendingWrites.set(
|
|
5939
|
-
key,
|
|
5940
|
-
chained.then(
|
|
5941
|
-
() => void 0,
|
|
5942
|
-
() => void 0
|
|
5943
|
-
)
|
|
5944
|
-
);
|
|
5945
|
-
}
|
|
5946
|
-
async function hydrateSession(agentId, loc) {
|
|
5947
|
-
const key = transcriptKey(loc.cwd, agentId);
|
|
5948
|
-
if (hydratedKeys.has(key)) return;
|
|
5949
|
-
hydratedKeys.add(key);
|
|
5950
|
-
const persisted = await readSessionMessages(loc.store, agentId);
|
|
5951
|
-
if (persisted.length === 0) return;
|
|
5952
|
-
sessions.set(agentId, persisted);
|
|
5953
|
-
}
|
|
5954
|
-
async function flushSessionWrites() {
|
|
5955
|
-
while (pendingWrites.size > 0) {
|
|
5956
|
-
const all = Array.from(pendingWrites.values());
|
|
5957
|
-
pendingWrites.clear();
|
|
5958
|
-
await Promise.all(all);
|
|
5824
|
+
--- END ---`;
|
|
5825
|
+
}
|
|
5826
|
+
async function compressConversationWindow(opts) {
|
|
5827
|
+
const userPrompt = buildCompressionPrompt(opts.messages);
|
|
5828
|
+
let summary;
|
|
5829
|
+
try {
|
|
5830
|
+
summary = await opts.callLlm(opts.model, COMPRESSION_SYSTEM, userPrompt);
|
|
5831
|
+
} catch (cause) {
|
|
5832
|
+
throw new CompressionFailedError(
|
|
5833
|
+
`Compression LLM call failed: ${cause instanceof Error ? cause.message : String(cause)}`,
|
|
5834
|
+
{ cause: cause instanceof Error ? cause : void 0 }
|
|
5835
|
+
);
|
|
5836
|
+
}
|
|
5837
|
+
if (!summary || summary.trim().length === 0) {
|
|
5838
|
+
throw new CompressionFailedError(
|
|
5839
|
+
"Compression LLM returned empty summary \u2014 reduction ineffective."
|
|
5840
|
+
);
|
|
5959
5841
|
}
|
|
5842
|
+
return {
|
|
5843
|
+
role: "system",
|
|
5844
|
+
content: `[Compressed conversation summary]: ${summary.trim()}`
|
|
5845
|
+
};
|
|
5960
5846
|
}
|
|
5961
|
-
|
|
5962
|
-
|
|
5847
|
+
var CompressionFailedError, COMPRESSION_SYSTEM;
|
|
5848
|
+
var init_compression_summarizer = __esm({
|
|
5849
|
+
"src/internal/runtime/compression/compression-summarizer.ts"() {
|
|
5850
|
+
CompressionFailedError = class extends Error {
|
|
5851
|
+
name = "CompressionFailedError";
|
|
5852
|
+
};
|
|
5853
|
+
COMPRESSION_SYSTEM = "You are a conversation summarizer. Produce a concise factual summary. Preserve all decisions, preferences, code snippets, and action items. Do not add commentary or opinions. Output ONLY the summary text.";
|
|
5854
|
+
}
|
|
5855
|
+
});
|
|
5856
|
+
|
|
5857
|
+
// src/internal/session/session-cache.ts
|
|
5858
|
+
function transcriptKey(cwd, agentId) {
|
|
5859
|
+
return `${cwd}::${agentId}`;
|
|
5963
5860
|
}
|
|
5964
5861
|
function invalidateSessionCache(cwd, agentId) {
|
|
5965
5862
|
sessions.delete(agentId);
|
|
5966
5863
|
hydratedKeys.delete(transcriptKey(cwd, agentId));
|
|
5967
5864
|
}
|
|
5968
|
-
|
|
5969
|
-
|
|
5970
|
-
|
|
5971
|
-
const result = prior.then(fn);
|
|
5972
|
-
pendingWrites.set(
|
|
5973
|
-
key,
|
|
5974
|
-
result.then(
|
|
5975
|
-
() => void 0,
|
|
5976
|
-
() => void 0
|
|
5977
|
-
)
|
|
5978
|
-
);
|
|
5979
|
-
return result;
|
|
5980
|
-
}
|
|
5981
|
-
var sessions, hydratedKeys, pendingWrites, recordCounts;
|
|
5982
|
-
var init_agent_session = __esm({
|
|
5983
|
-
"src/internal/session/agent-session.ts"() {
|
|
5984
|
-
init_agent_session_store();
|
|
5865
|
+
var sessions, hydratedKeys;
|
|
5866
|
+
var init_session_cache = __esm({
|
|
5867
|
+
"src/internal/session/session-cache.ts"() {
|
|
5985
5868
|
sessions = /* @__PURE__ */ new Map();
|
|
5986
5869
|
hydratedKeys = /* @__PURE__ */ new Set();
|
|
5987
|
-
pendingWrites = /* @__PURE__ */ new Map();
|
|
5988
|
-
recordCounts = /* @__PURE__ */ new Map();
|
|
5989
5870
|
}
|
|
5990
5871
|
});
|
|
5991
5872
|
|
|
@@ -6147,7 +6028,7 @@ var init_compact_session = __esm({
|
|
|
6147
6028
|
init_providers();
|
|
6148
6029
|
init_compression_model_registry();
|
|
6149
6030
|
init_compression_summarizer();
|
|
6150
|
-
|
|
6031
|
+
init_session_cache();
|
|
6151
6032
|
COMPACT_SUMMARY_MARKER = "[[theokit:compact-summary]]";
|
|
6152
6033
|
COMPACT_USER_MESSAGE_MAX_TOKENS = 2e4;
|
|
6153
6034
|
autoCompactAttempts = (() => {
|
|
@@ -6158,6 +6039,165 @@ var init_compact_session = __esm({
|
|
|
6158
6039
|
})();
|
|
6159
6040
|
}
|
|
6160
6041
|
});
|
|
6042
|
+
|
|
6043
|
+
// src/internal/session/agent-session-store.ts
|
|
6044
|
+
function seedTranscript(prior, opts) {
|
|
6045
|
+
return SessionTranscript.fromRecords(prior, opts);
|
|
6046
|
+
}
|
|
6047
|
+
function mapAgentTurn(steps) {
|
|
6048
|
+
const assistant = {};
|
|
6049
|
+
const toolResults = [];
|
|
6050
|
+
const toolCalls = [];
|
|
6051
|
+
for (const step of steps) {
|
|
6052
|
+
if (step.type === "thinkingMessage") assistant.thinking = step.message.text;
|
|
6053
|
+
else if (step.type === "assistantMessage") assistant.text = step.message.text;
|
|
6054
|
+
else if (step.type === "toolCall")
|
|
6055
|
+
toolCalls.push({
|
|
6056
|
+
id: step.message.callId,
|
|
6057
|
+
name: step.message.name,
|
|
6058
|
+
input: step.message.args ?? {}
|
|
6059
|
+
});
|
|
6060
|
+
else
|
|
6061
|
+
toolResults.push({
|
|
6062
|
+
toolUseId: step.message.callId,
|
|
6063
|
+
content: step.message.result,
|
|
6064
|
+
isError: step.message.isError
|
|
6065
|
+
});
|
|
6066
|
+
}
|
|
6067
|
+
if (toolCalls.length > 0) assistant.toolCalls = toolCalls;
|
|
6068
|
+
return { assistant, toolResults };
|
|
6069
|
+
}
|
|
6070
|
+
function hasAssistantContent(a) {
|
|
6071
|
+
return a.text !== void 0 || a.thinking !== void 0 || (a.toolCalls?.length ?? 0) > 0;
|
|
6072
|
+
}
|
|
6073
|
+
function appendConversation(transcript, conversation) {
|
|
6074
|
+
for (const ct of conversation) {
|
|
6075
|
+
if (ct.type !== "agentConversationTurn") continue;
|
|
6076
|
+
const { assistant, toolResults } = mapAgentTurn(ct.turn.steps);
|
|
6077
|
+
if (hasAssistantContent(assistant)) transcript.appendAssistantTurn(assistant);
|
|
6078
|
+
if (toolResults.length > 0) transcript.appendToolResults(toolResults);
|
|
6079
|
+
}
|
|
6080
|
+
}
|
|
6081
|
+
async function readSessionMessages(store, agentId) {
|
|
6082
|
+
const records = await store.readRecords(agentId);
|
|
6083
|
+
return reconstructMessages(records).map(narrowToSessionMessage);
|
|
6084
|
+
}
|
|
6085
|
+
function partToText(p) {
|
|
6086
|
+
if (p.type === "text") return p.text ?? "";
|
|
6087
|
+
if (p.type === "tool_use") return `[tool call] ${p.name ?? ""}`;
|
|
6088
|
+
if (p.type === "tool_result") {
|
|
6089
|
+
const body = typeof p.content === "string" ? p.content : JSON.stringify(p.content);
|
|
6090
|
+
return `[tool result] ${body}`;
|
|
6091
|
+
}
|
|
6092
|
+
return "";
|
|
6093
|
+
}
|
|
6094
|
+
function narrowToSessionMessage(m) {
|
|
6095
|
+
const role = m.role === "user" ? "user" : "assistant";
|
|
6096
|
+
const text = m.content.map(partToText).filter((s) => s.length > 0).join("\n");
|
|
6097
|
+
return { role, text };
|
|
6098
|
+
}
|
|
6099
|
+
function deltaRecords(transcript, priorLength) {
|
|
6100
|
+
return transcript.records().slice(priorLength);
|
|
6101
|
+
}
|
|
6102
|
+
async function persistTurn(store, loc, sessionId, turn) {
|
|
6103
|
+
const prior = await store.readRecords(loc.agentId);
|
|
6104
|
+
const transcript = seedTranscript(prior, { cwd: loc.cwd, sessionId, model: loc.model });
|
|
6105
|
+
transcript.appendUserTurn(turn.userText);
|
|
6106
|
+
appendConversation(transcript, turn.conversation);
|
|
6107
|
+
await store.appendRecords(loc.agentId, deltaRecords(transcript, prior.length));
|
|
6108
|
+
}
|
|
6109
|
+
var init_agent_session_store = __esm({
|
|
6110
|
+
"src/internal/session/agent-session-store.ts"() {
|
|
6111
|
+
init_session_transcript();
|
|
6112
|
+
}
|
|
6113
|
+
});
|
|
6114
|
+
|
|
6115
|
+
// src/internal/session/agent-session.ts
|
|
6116
|
+
function appendSessionMessage(agentId, message) {
|
|
6117
|
+
const existing = sessions.get(agentId) ?? [];
|
|
6118
|
+
existing.push(message);
|
|
6119
|
+
sessions.set(agentId, existing);
|
|
6120
|
+
}
|
|
6121
|
+
function getSessionMessages(agentId) {
|
|
6122
|
+
return sessions.get(agentId) ?? [];
|
|
6123
|
+
}
|
|
6124
|
+
function persistTurnToTranscript(store, loc, sessionId, turn, onCompact) {
|
|
6125
|
+
const key = transcriptKey(loc.cwd, loc.agentId);
|
|
6126
|
+
const chained = (pendingWrites.get(key) ?? Promise.resolve()).then(async () => {
|
|
6127
|
+
try {
|
|
6128
|
+
await persistTurn(store, loc, sessionId, turn);
|
|
6129
|
+
const count = (recordCounts.get(key) ?? 0) + 1;
|
|
6130
|
+
recordCounts.set(key, count);
|
|
6131
|
+
if (turn.autoCompact !== void 0) {
|
|
6132
|
+
const { autoCompactIfNeeded: autoCompactIfNeeded2 } = await Promise.resolve().then(() => (init_compact_session(), compact_session_exports));
|
|
6133
|
+
const fired = await autoCompactIfNeeded2({
|
|
6134
|
+
store,
|
|
6135
|
+
loc,
|
|
6136
|
+
sessionId,
|
|
6137
|
+
usageTotal: turn.autoCompact.usageTotal,
|
|
6138
|
+
contextWindow: turn.autoCompact.contextWindow,
|
|
6139
|
+
turnCount: count,
|
|
6140
|
+
summarize: turn.autoCompact.summarize
|
|
6141
|
+
});
|
|
6142
|
+
if (fired) onCompact?.();
|
|
6143
|
+
}
|
|
6144
|
+
} catch (cause) {
|
|
6145
|
+
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
6146
|
+
process.stderr.write(
|
|
6147
|
+
`[theokit-sdk] session transcript write failed (${loc.agentId}): ${msg}
|
|
6148
|
+
`
|
|
6149
|
+
);
|
|
6150
|
+
}
|
|
6151
|
+
});
|
|
6152
|
+
pendingWrites.set(
|
|
6153
|
+
key,
|
|
6154
|
+
chained.then(
|
|
6155
|
+
() => void 0,
|
|
6156
|
+
() => void 0
|
|
6157
|
+
)
|
|
6158
|
+
);
|
|
6159
|
+
}
|
|
6160
|
+
async function hydrateSession(agentId, loc) {
|
|
6161
|
+
const key = transcriptKey(loc.cwd, agentId);
|
|
6162
|
+
if (hydratedKeys.has(key)) return;
|
|
6163
|
+
hydratedKeys.add(key);
|
|
6164
|
+
const persisted = await readSessionMessages(loc.store, agentId);
|
|
6165
|
+
if (persisted.length === 0) return;
|
|
6166
|
+
sessions.set(agentId, persisted);
|
|
6167
|
+
}
|
|
6168
|
+
async function flushSessionWrites() {
|
|
6169
|
+
while (pendingWrites.size > 0) {
|
|
6170
|
+
const all = Array.from(pendingWrites.values());
|
|
6171
|
+
pendingWrites.clear();
|
|
6172
|
+
await Promise.all(all);
|
|
6173
|
+
}
|
|
6174
|
+
}
|
|
6175
|
+
function clearSession(agentId) {
|
|
6176
|
+
sessions.delete(agentId);
|
|
6177
|
+
}
|
|
6178
|
+
function enqueueSessionWrite(cwd, agentId, fn) {
|
|
6179
|
+
const key = transcriptKey(cwd, agentId);
|
|
6180
|
+
const prior = pendingWrites.get(key) ?? Promise.resolve();
|
|
6181
|
+
const result = prior.then(fn);
|
|
6182
|
+
pendingWrites.set(
|
|
6183
|
+
key,
|
|
6184
|
+
result.then(
|
|
6185
|
+
() => void 0,
|
|
6186
|
+
() => void 0
|
|
6187
|
+
)
|
|
6188
|
+
);
|
|
6189
|
+
return result;
|
|
6190
|
+
}
|
|
6191
|
+
var pendingWrites, recordCounts;
|
|
6192
|
+
var init_agent_session = __esm({
|
|
6193
|
+
"src/internal/session/agent-session.ts"() {
|
|
6194
|
+
init_agent_session_store();
|
|
6195
|
+
init_session_cache();
|
|
6196
|
+
init_session_cache();
|
|
6197
|
+
pendingWrites = /* @__PURE__ */ new Map();
|
|
6198
|
+
recordCounts = /* @__PURE__ */ new Map();
|
|
6199
|
+
}
|
|
6200
|
+
});
|
|
6161
6201
|
async function withToolWhitelist(whitelist, fn) {
|
|
6162
6202
|
return toolWhitelistStore.run(whitelist, fn);
|
|
6163
6203
|
}
|
|
@@ -6252,10 +6292,10 @@ var init_context = __esm({
|
|
|
6252
6292
|
}
|
|
6253
6293
|
});
|
|
6254
6294
|
|
|
6255
|
-
// src/goal-
|
|
6295
|
+
// src/internal/runtime/lifecycle/goal-marker.ts
|
|
6256
6296
|
var GOAL_CONTINUATION_MARKER;
|
|
6257
|
-
var
|
|
6258
|
-
"src/goal-
|
|
6297
|
+
var init_goal_marker = __esm({
|
|
6298
|
+
"src/internal/runtime/lifecycle/goal-marker.ts"() {
|
|
6259
6299
|
GOAL_CONTINUATION_MARKER = "[[theokit:goal-continuation]]";
|
|
6260
6300
|
}
|
|
6261
6301
|
});
|
|
@@ -6429,7 +6469,7 @@ ${lastResponse.slice(-1e3)}`
|
|
|
6429
6469
|
}
|
|
6430
6470
|
var init_run_until = __esm({
|
|
6431
6471
|
"src/internal/runtime/lifecycle/run-until.ts"() {
|
|
6432
|
-
|
|
6472
|
+
init_goal_marker();
|
|
6433
6473
|
}
|
|
6434
6474
|
});
|
|
6435
6475
|
|
|
@@ -10600,6 +10640,7 @@ function parseDecisionFromStdout(stdout) {
|
|
|
10600
10640
|
}
|
|
10601
10641
|
|
|
10602
10642
|
// src/internal/runtime/lifecycle/post-run-lifecycle.ts
|
|
10643
|
+
init_compaction();
|
|
10603
10644
|
init_run_events();
|
|
10604
10645
|
|
|
10605
10646
|
// src/internal/memory/storage/session-summary-writer.ts
|
|
@@ -10669,6 +10710,12 @@ function resolveActiveMemorySummaryForSend(legacySummary, portPathEnabled) {
|
|
|
10669
10710
|
return legacySummary;
|
|
10670
10711
|
}
|
|
10671
10712
|
|
|
10713
|
+
// src/internal/runtime/lifecycle/context-budget-event.ts
|
|
10714
|
+
function buildContextBudgetEvent(model, resolved) {
|
|
10715
|
+
if (resolved.source !== "fallback") return void 0;
|
|
10716
|
+
return { type: "compaction_fallback", model, window: resolved.window };
|
|
10717
|
+
}
|
|
10718
|
+
|
|
10672
10719
|
// src/internal/runtime/lifecycle/post-run-lifecycle.ts
|
|
10673
10720
|
async function runPostRunLifecycle(inputs) {
|
|
10674
10721
|
const {
|
|
@@ -10694,18 +10741,15 @@ async function runPostRunLifecycle(inputs) {
|
|
|
10694
10741
|
appendSessionMessage(agentId, { role: "assistant", text: result.result });
|
|
10695
10742
|
}
|
|
10696
10743
|
const conversation = await safeConversation(run);
|
|
10697
|
-
const
|
|
10698
|
-
|
|
10699
|
-
|
|
10700
|
-
|
|
10701
|
-
|
|
10702
|
-
|
|
10703
|
-
|
|
10704
|
-
|
|
10705
|
-
|
|
10706
|
-
`
|
|
10707
|
-
);
|
|
10708
|
-
}
|
|
10744
|
+
const resolvedWindow = resolveEffectiveContextWindow({
|
|
10745
|
+
catalog: getCatalogModelInfo(model)?.limit?.context,
|
|
10746
|
+
margin: CONTEXT_WINDOW_MARGIN,
|
|
10747
|
+
floor: CONTEXT_WINDOW_FLOOR
|
|
10748
|
+
});
|
|
10749
|
+
const contextWindow = resolvedWindow.window;
|
|
10750
|
+
const budgetEvent = buildContextBudgetEvent(model, resolvedWindow);
|
|
10751
|
+
if (budgetEvent !== void 0 && onRunEvent !== void 0) {
|
|
10752
|
+
emitRunEvent(onRunEvent, budgetEvent);
|
|
10709
10753
|
}
|
|
10710
10754
|
const lastRequestUsage = result.usage?.requests?.at(-1)?.totalTokens;
|
|
10711
10755
|
const usageForTrigger = lastRequestUsage ?? result.usage?.totalTokens;
|
|
@@ -15677,6 +15721,71 @@ function registerPluginProviderProfiles(entries) {
|
|
|
15677
15721
|
|
|
15678
15722
|
// src/internal/local-agent/real-local-run.ts
|
|
15679
15723
|
init_async_local_storage();
|
|
15724
|
+
|
|
15725
|
+
// src/internal/local-agent/mcp-pool.ts
|
|
15726
|
+
var DEFAULT_IDLE_TTL_MS = 6e5;
|
|
15727
|
+
function configKey(config) {
|
|
15728
|
+
return JSON.stringify(
|
|
15729
|
+
config,
|
|
15730
|
+
(_k, v) => v !== null && typeof v === "object" && !Array.isArray(v) ? Object.fromEntries(
|
|
15731
|
+
Object.entries(v).sort(([a], [b]) => a < b ? -1 : 1)
|
|
15732
|
+
) : v
|
|
15733
|
+
);
|
|
15734
|
+
}
|
|
15735
|
+
var McpClientPool = class {
|
|
15736
|
+
entries = /* @__PURE__ */ new Map();
|
|
15737
|
+
idleTtlMs;
|
|
15738
|
+
now;
|
|
15739
|
+
constructor(options = {}) {
|
|
15740
|
+
this.idleTtlMs = options.idleTtlMs ?? DEFAULT_IDLE_TTL_MS;
|
|
15741
|
+
this.now = options.now ?? Date.now;
|
|
15742
|
+
}
|
|
15743
|
+
/**
|
|
15744
|
+
* Return the pooled client for `(sessionId, serverName, config)`, creating it via `factory` on
|
|
15745
|
+
* first use. Every call refreshes idleness — the TTL measures time SINCE LAST USE, not age.
|
|
15746
|
+
*
|
|
15747
|
+
* Synchronous by design: `createMcpClient` is itself synchronous (the handshake happens later, on
|
|
15748
|
+
* `initialize`), so there is no `await` between the lookup and the insert and two concurrent runs
|
|
15749
|
+
* in the same session cannot both miss the cache.
|
|
15750
|
+
*/
|
|
15751
|
+
acquire(sessionId, serverName, config, factory) {
|
|
15752
|
+
const key = `${sessionId}\0${serverName}\0${configKey(config)}`;
|
|
15753
|
+
const existing = this.entries.get(key);
|
|
15754
|
+
if (existing !== void 0) {
|
|
15755
|
+
existing.lastUsedAt = this.now();
|
|
15756
|
+
return existing.client;
|
|
15757
|
+
}
|
|
15758
|
+
const client = factory();
|
|
15759
|
+
this.entries.set(key, { client, sessionId, lastUsedAt: this.now() });
|
|
15760
|
+
return client;
|
|
15761
|
+
}
|
|
15762
|
+
/**
|
|
15763
|
+
* Close and forget every client of ONE session. Scoped deliberately: clearing the whole map would
|
|
15764
|
+
* tear down the servers of every concurrent conversation.
|
|
15765
|
+
*/
|
|
15766
|
+
disposeSession(sessionId, close) {
|
|
15767
|
+
for (const [key, entry] of this.entries) {
|
|
15768
|
+
if (entry.sessionId !== sessionId) continue;
|
|
15769
|
+
close(entry.client);
|
|
15770
|
+
this.entries.delete(key);
|
|
15771
|
+
}
|
|
15772
|
+
}
|
|
15773
|
+
/** Close and forget every client idle for longer than the TTL. */
|
|
15774
|
+
reapIdle(close) {
|
|
15775
|
+
const cutoff = this.now() - this.idleTtlMs;
|
|
15776
|
+
for (const [key, entry] of this.entries) {
|
|
15777
|
+
if (entry.lastUsedAt > cutoff) continue;
|
|
15778
|
+
close(entry.client);
|
|
15779
|
+
this.entries.delete(key);
|
|
15780
|
+
}
|
|
15781
|
+
}
|
|
15782
|
+
/** Live pooled-client count — for observability and tests. */
|
|
15783
|
+
size() {
|
|
15784
|
+
return this.entries.size;
|
|
15785
|
+
}
|
|
15786
|
+
};
|
|
15787
|
+
|
|
15788
|
+
// src/internal/local-agent/real-local-run.ts
|
|
15680
15789
|
init_real_local_run_provider();
|
|
15681
15790
|
|
|
15682
15791
|
// src/a2a/subagent.ts
|
|
@@ -16095,12 +16204,23 @@ function buildLoopInputs(options, runId, userText, userImages) {
|
|
|
16095
16204
|
...options.agentOptions.memoryProvider !== void 0 ? { memoryProvider: options.agentOptions.memoryProvider } : {}
|
|
16096
16205
|
};
|
|
16097
16206
|
}
|
|
16207
|
+
var sessionMcpPool = new McpClientPool();
|
|
16208
|
+
function disposeSessionMcpClients(agentId) {
|
|
16209
|
+
sessionMcpPool.disposeSession(agentId, (client) => {
|
|
16210
|
+
void client.close();
|
|
16211
|
+
});
|
|
16212
|
+
}
|
|
16098
16213
|
function buildMcpMap(options) {
|
|
16099
16214
|
const map = /* @__PURE__ */ new Map();
|
|
16100
16215
|
const inline = options.sendOptions.mcpServers ?? options.agentOptions.mcpServers;
|
|
16101
16216
|
if (inline === void 0) return map;
|
|
16217
|
+
const pooled = options.agentOptions.mcpLifecycle === "session";
|
|
16218
|
+
if (pooled) sessionMcpPool.reapIdle((c) => void c.close());
|
|
16102
16219
|
for (const [name, config] of Object.entries(inline)) {
|
|
16103
|
-
map.set(
|
|
16220
|
+
map.set(
|
|
16221
|
+
name,
|
|
16222
|
+
pooled ? sessionMcpPool.acquire(options.agentId, name, config, () => createMcpClient(name, config)) : createMcpClient(name, config)
|
|
16223
|
+
);
|
|
16104
16224
|
}
|
|
16105
16225
|
return map;
|
|
16106
16226
|
}
|
|
@@ -17165,7 +17285,9 @@ async function loadDriver(filePath) {
|
|
|
17165
17285
|
}
|
|
17166
17286
|
try {
|
|
17167
17287
|
const mod = await (driverLoaderOverrides?.nodeSqlite?.() ?? Promise.resolve(
|
|
17168
|
-
process.getBuiltinModule?.(
|
|
17288
|
+
process.getBuiltinModule?.(
|
|
17289
|
+
"node:sqlite"
|
|
17290
|
+
) ?? (() => {
|
|
17169
17291
|
throw new Error("node:sqlite built-in unavailable (Node < 22.3)");
|
|
17170
17292
|
})()
|
|
17171
17293
|
));
|
|
@@ -18215,7 +18337,8 @@ var LocalAgentMemory = class {
|
|
|
18215
18337
|
const message = cause instanceof Error ? cause.message : String(cause);
|
|
18216
18338
|
const g = globalThis;
|
|
18217
18339
|
const sym = /* @__PURE__ */ Symbol.for("theokit-sdk.memory.warned");
|
|
18218
|
-
|
|
18340
|
+
g[sym] ??= /* @__PURE__ */ new Set();
|
|
18341
|
+
const warned3 = g[sym];
|
|
18219
18342
|
if (!warned3.has(message)) {
|
|
18220
18343
|
warned3.add(message);
|
|
18221
18344
|
process.stderr.write(`[theokit-sdk] memory tools unavailable: ${message}
|
|
@@ -19399,6 +19522,7 @@ var LocalAgent = class {
|
|
|
19399
19522
|
liveAgentRegistry.forget(this.agentId);
|
|
19400
19523
|
this.lifecycleAbortController.abort();
|
|
19401
19524
|
await withCwdMutex(`agent-send:${this.agentId}`, () => Promise.resolve());
|
|
19525
|
+
disposeSessionMcpClients(this.agentId);
|
|
19402
19526
|
await flushSessionWrites();
|
|
19403
19527
|
await flushRegistrySaves(this.workspaceCwd);
|
|
19404
19528
|
}
|
|
@@ -19699,8 +19823,8 @@ async function getRegisteredAgentOrThrow(agentId) {
|
|
|
19699
19823
|
// src/agent.ts
|
|
19700
19824
|
init_errors();
|
|
19701
19825
|
init_discovery();
|
|
19702
|
-
init_agent_session();
|
|
19703
19826
|
init_agent_factory_registry();
|
|
19827
|
+
init_agent_session();
|
|
19704
19828
|
var streamObjectImport;
|
|
19705
19829
|
var Agent = class _Agent {
|
|
19706
19830
|
constructor() {
|
|
@@ -19992,26 +20116,26 @@ var Agent = class _Agent {
|
|
|
19992
20116
|
reg = getRegisteredAgent(agentId);
|
|
19993
20117
|
}
|
|
19994
20118
|
if (reg === void 0 || reg.runtime !== "local") {
|
|
19995
|
-
throw new UnknownAgentError(
|
|
20119
|
+
throw new UnknownAgentError(
|
|
20120
|
+
`No local agent "${agentId}" registered \u2014 compact targets local sessions.`
|
|
20121
|
+
);
|
|
19996
20122
|
}
|
|
19997
|
-
const cwd = reg.cwd ?? process.cwd();
|
|
19998
|
-
const optModel = reg.options.model;
|
|
19999
|
-
const model = reg.model?.id ?? (typeof optModel === "string" ? optModel : optModel?.id) ?? "unknown";
|
|
20000
20123
|
const { compactSessionTranscript: compactSessionTranscript2, buildDefaultSummarizer: buildDefaultSummarizer2 } = await Promise.resolve().then(() => (init_compact_session(), compact_session_exports));
|
|
20001
|
-
const {
|
|
20002
|
-
|
|
20003
|
-
|
|
20004
|
-
|
|
20005
|
-
|
|
20006
|
-
|
|
20007
|
-
|
|
20008
|
-
|
|
20009
|
-
|
|
20010
|
-
|
|
20011
|
-
|
|
20012
|
-
|
|
20124
|
+
const { cwd, model, store } = await abrirStoreLocal(reg);
|
|
20125
|
+
return enqueueSessionWrite(
|
|
20126
|
+
cwd,
|
|
20127
|
+
agentId,
|
|
20128
|
+
() => compactSessionTranscript2({
|
|
20129
|
+
store,
|
|
20130
|
+
loc: { cwd, agentId, model },
|
|
20131
|
+
sessionId: agentId,
|
|
20132
|
+
trigger: options.trigger ?? "manual",
|
|
20133
|
+
summarize: options.summarize ?? buildDefaultSummarizer2({
|
|
20134
|
+
agentModel: model,
|
|
20135
|
+
...reg.options.apiKey !== void 0 ? { apiKey: reg.options.apiKey } : {}
|
|
20136
|
+
})
|
|
20013
20137
|
})
|
|
20014
|
-
|
|
20138
|
+
);
|
|
20015
20139
|
}
|
|
20016
20140
|
/**
|
|
20017
20141
|
* M51 — inject a SYNTHETIC user+assistant pair into a LOCAL session's persisted transcript WITHOUT
|
|
@@ -20028,16 +20152,12 @@ var Agent = class _Agent {
|
|
|
20028
20152
|
reg = getRegisteredAgent(agentId);
|
|
20029
20153
|
}
|
|
20030
20154
|
if (reg === void 0 || reg.runtime !== "local") {
|
|
20031
|
-
throw new UnknownAgentError(
|
|
20155
|
+
throw new UnknownAgentError(
|
|
20156
|
+
`No local agent "${agentId}" registered \u2014 injectSessionTurn targets local sessions.`
|
|
20157
|
+
);
|
|
20032
20158
|
}
|
|
20033
|
-
const cwd = reg.cwd ?? process.cwd();
|
|
20034
|
-
const optModel = reg.options.model;
|
|
20035
|
-
const model = reg.model?.id ?? (typeof optModel === "string" ? optModel : optModel?.id) ?? "unknown";
|
|
20036
20159
|
const { injectSessionTurn: injectSessionTurn2 } = await Promise.resolve().then(() => (init_inject_session(), inject_session_exports));
|
|
20037
|
-
const {
|
|
20038
|
-
const { defaultBaseDir: defaultBaseDir2, expandTilde: expandTilde2 } = await Promise.resolve().then(() => (init_session_transcript(), session_transcript_exports));
|
|
20039
|
-
const baseDir = reg.options.local?.baseDir !== void 0 ? expandTilde2(reg.options.local.baseDir) : defaultBaseDir2();
|
|
20040
|
-
const store = new FsSessionStore2({ baseDir, cwd });
|
|
20160
|
+
const { cwd, model, store } = await abrirStoreLocal(reg);
|
|
20041
20161
|
await injectSessionTurn2({
|
|
20042
20162
|
store,
|
|
20043
20163
|
loc: { cwd, agentId, model },
|
|
@@ -20079,6 +20199,15 @@ setAgentFacade({
|
|
|
20079
20199
|
resume: (agentId, options) => Agent.resume(agentId, options),
|
|
20080
20200
|
batch: (prompts, options) => Agent.batch(prompts, options)
|
|
20081
20201
|
});
|
|
20202
|
+
async function abrirStoreLocal(reg) {
|
|
20203
|
+
const cwd = reg.cwd ?? process.cwd();
|
|
20204
|
+
const optModel = reg.options.model;
|
|
20205
|
+
const model = reg.model?.id ?? (typeof optModel === "string" ? optModel : optModel?.id) ?? "unknown";
|
|
20206
|
+
const { FsSessionStore: FsSessionStore2 } = await Promise.resolve().then(() => (init_fs_session_store(), fs_session_store_exports));
|
|
20207
|
+
const { defaultBaseDir: defaultBaseDir2, expandTilde: expandTilde2 } = await Promise.resolve().then(() => (init_session_transcript(), session_transcript_exports));
|
|
20208
|
+
const baseDir = reg.options.local?.baseDir !== void 0 ? expandTilde2(reg.options.local.baseDir) : defaultBaseDir2();
|
|
20209
|
+
return { cwd, model, store: new FsSessionStore2({ baseDir, cwd }) };
|
|
20210
|
+
}
|
|
20082
20211
|
var JsonlParseError = class extends Error {
|
|
20083
20212
|
constructor(message, line) {
|
|
20084
20213
|
super(message);
|