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