@theokit/sdk 4.16.3 → 4.16.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/cron.cjs +363 -383
- package/dist/cron.cjs.map +1 -1
- package/dist/cron.js +364 -384
- package/dist/cron.js.map +1 -1
- package/dist/eval.cjs +363 -383
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +364 -384
- package/dist/eval.js.map +1 -1
- package/dist/index.cjs +361 -369
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +362 -370
- package/dist/index.js.map +1 -1
- package/dist/internal/session/agent-session.d.ts +12 -0
- package/dist/provider-catalog.json +493 -144
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1760,140 +1760,6 @@ var init_session_summary_writer = __esm({
|
|
|
1760
1760
|
MAX_TURN_CHARS = 2e3;
|
|
1761
1761
|
}
|
|
1762
1762
|
});
|
|
1763
|
-
|
|
1764
|
-
// src/compaction.ts
|
|
1765
|
-
function estimateTokens(text) {
|
|
1766
|
-
return Math.ceil(text.length / 4);
|
|
1767
|
-
}
|
|
1768
|
-
var init_compaction = __esm({
|
|
1769
|
-
"src/compaction.ts"() {
|
|
1770
|
-
}
|
|
1771
|
-
});
|
|
1772
|
-
|
|
1773
|
-
// src/internal/runtime/compression/compression-summarizer.ts
|
|
1774
|
-
var compression_summarizer_exports = {};
|
|
1775
|
-
__export(compression_summarizer_exports, {
|
|
1776
|
-
CompressionFailedError: () => CompressionFailedError,
|
|
1777
|
-
buildCompressionPrompt: () => buildCompressionPrompt,
|
|
1778
|
-
compressConversationWindow: () => compressConversationWindow
|
|
1779
|
-
});
|
|
1780
|
-
function buildCompressionPrompt(messages) {
|
|
1781
|
-
const formatted = messages.map((m) => `[${m.role}]: ${m.content}`).join("\n\n");
|
|
1782
|
-
return `Summarize the following ${messages.length} conversation messages into a concise summary that preserves ALL facts, decisions, user preferences, and context needed for the conversation to continue naturally. The summary will replace these messages in the context window. Be thorough but concise.
|
|
1783
|
-
|
|
1784
|
-
--- CONVERSATION TO SUMMARIZE ---
|
|
1785
|
-
${formatted}
|
|
1786
|
-
--- END ---`;
|
|
1787
|
-
}
|
|
1788
|
-
async function compressConversationWindow(opts) {
|
|
1789
|
-
const userPrompt = buildCompressionPrompt(opts.messages);
|
|
1790
|
-
let summary;
|
|
1791
|
-
try {
|
|
1792
|
-
summary = await opts.callLlm(opts.model, COMPRESSION_SYSTEM, userPrompt);
|
|
1793
|
-
} catch (cause) {
|
|
1794
|
-
throw new CompressionFailedError(
|
|
1795
|
-
`Compression LLM call failed: ${cause instanceof Error ? cause.message : String(cause)}`,
|
|
1796
|
-
{ cause: cause instanceof Error ? cause : void 0 }
|
|
1797
|
-
);
|
|
1798
|
-
}
|
|
1799
|
-
if (!summary || summary.trim().length === 0) {
|
|
1800
|
-
throw new CompressionFailedError(
|
|
1801
|
-
"Compression LLM returned empty summary \u2014 reduction ineffective."
|
|
1802
|
-
);
|
|
1803
|
-
}
|
|
1804
|
-
return {
|
|
1805
|
-
role: "system",
|
|
1806
|
-
content: `[Compressed conversation summary]: ${summary.trim()}`
|
|
1807
|
-
};
|
|
1808
|
-
}
|
|
1809
|
-
var CompressionFailedError, COMPRESSION_SYSTEM;
|
|
1810
|
-
var init_compression_summarizer = __esm({
|
|
1811
|
-
"src/internal/runtime/compression/compression-summarizer.ts"() {
|
|
1812
|
-
CompressionFailedError = class extends Error {
|
|
1813
|
-
name = "CompressionFailedError";
|
|
1814
|
-
};
|
|
1815
|
-
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.";
|
|
1816
|
-
}
|
|
1817
|
-
});
|
|
1818
|
-
|
|
1819
|
-
// src/internal/runtime/compression/compression-model-registry.ts
|
|
1820
|
-
var compression_model_registry_exports = {};
|
|
1821
|
-
__export(compression_model_registry_exports, {
|
|
1822
|
-
CompressionModelUnresolvedError: () => CompressionModelUnresolvedError,
|
|
1823
|
-
resolveCompressionModel: () => resolveCompressionModel
|
|
1824
|
-
});
|
|
1825
|
-
function resolveCompressionModel(agentModel) {
|
|
1826
|
-
const exact = EXACT_REGISTRY.get(agentModel);
|
|
1827
|
-
if (exact !== void 0) return exact;
|
|
1828
|
-
const wildcard = matchWildcard(agentModel);
|
|
1829
|
-
if (wildcard !== null) return wildcard;
|
|
1830
|
-
if (isNoAuthProvider(agentModel)) return agentModel;
|
|
1831
|
-
throw new CompressionModelUnresolvedError(agentModel);
|
|
1832
|
-
}
|
|
1833
|
-
function matchWildcard(agentModel) {
|
|
1834
|
-
for (const [pattern, replacement] of WILDCARD_REGISTRY) {
|
|
1835
|
-
const prefix = pattern.endsWith("*") ? pattern.slice(0, -1) : pattern;
|
|
1836
|
-
if (!agentModel.startsWith(prefix)) continue;
|
|
1837
|
-
const suffix = agentModel.slice(prefix.length);
|
|
1838
|
-
const replPrefix = replacement.endsWith("*") ? replacement.slice(0, -1) : replacement;
|
|
1839
|
-
return `${replPrefix}${suffix}`;
|
|
1840
|
-
}
|
|
1841
|
-
return null;
|
|
1842
|
-
}
|
|
1843
|
-
function isNoAuthProvider(agentModel) {
|
|
1844
|
-
const slashIdx = agentModel.indexOf("/");
|
|
1845
|
-
if (slashIdx <= 0) return false;
|
|
1846
|
-
return NO_AUTH_PROVIDERS.has(agentModel.slice(0, slashIdx));
|
|
1847
|
-
}
|
|
1848
|
-
var EXACT_REGISTRY, WILDCARD_REGISTRY, NO_AUTH_PROVIDERS, CompressionModelUnresolvedError;
|
|
1849
|
-
var init_compression_model_registry = __esm({
|
|
1850
|
-
"src/internal/runtime/compression/compression-model-registry.ts"() {
|
|
1851
|
-
EXACT_REGISTRY = /* @__PURE__ */ new Map([
|
|
1852
|
-
// OpenAI family
|
|
1853
|
-
["openai/gpt-4o", "openai/gpt-4o-mini"],
|
|
1854
|
-
["openai/gpt-4-turbo", "openai/gpt-4o-mini"],
|
|
1855
|
-
["openai/gpt-4", "openai/gpt-4o-mini"],
|
|
1856
|
-
["openai/o1-preview", "openai/gpt-4o-mini"],
|
|
1857
|
-
["openai/o1", "openai/gpt-4o-mini"],
|
|
1858
|
-
["openai/o3", "openai/gpt-4o-mini"],
|
|
1859
|
-
["openai/o3-mini", "openai/gpt-4o-mini"],
|
|
1860
|
-
// Anthropic family
|
|
1861
|
-
["anthropic/claude-opus-4", "anthropic/claude-3-5-haiku-latest"],
|
|
1862
|
-
["anthropic/claude-sonnet-4", "anthropic/claude-3-5-haiku-latest"],
|
|
1863
|
-
["anthropic/claude-3-5-sonnet", "anthropic/claude-3-5-haiku-latest"],
|
|
1864
|
-
["anthropic/claude-3-5-sonnet-latest", "anthropic/claude-3-5-haiku-latest"],
|
|
1865
|
-
["anthropic/claude-3-opus", "anthropic/claude-3-haiku"],
|
|
1866
|
-
["anthropic/claude-3-sonnet", "anthropic/claude-3-haiku"],
|
|
1867
|
-
// Vertex (Gemini + Anthropic-on-Vertex)
|
|
1868
|
-
["vertex/gemini-1.5-pro", "vertex/gemini-1.5-flash"],
|
|
1869
|
-
["vertex/gemini-2.0-pro", "vertex/gemini-1.5-flash"],
|
|
1870
|
-
["vertex/claude-3-5-sonnet", "vertex/claude-3-5-haiku"],
|
|
1871
|
-
["vertex/claude-3-opus", "vertex/claude-3-haiku"],
|
|
1872
|
-
// OpenRouter (preserve openrouter prefix, swap tier within same vendor)
|
|
1873
|
-
["openrouter/openai/gpt-4o", "openrouter/openai/gpt-4o-mini"],
|
|
1874
|
-
["openrouter/openai/gpt-4-turbo", "openrouter/openai/gpt-4o-mini"],
|
|
1875
|
-
["openrouter/anthropic/claude-3-5-sonnet", "openrouter/anthropic/claude-3-5-haiku"],
|
|
1876
|
-
["openrouter/anthropic/claude-opus-4", "openrouter/anthropic/claude-3-5-haiku"]
|
|
1877
|
-
]);
|
|
1878
|
-
WILDCARD_REGISTRY = [
|
|
1879
|
-
// Bedrock Anthropic: us.anthropic.claude-sonnet-* → us.anthropic.claude-3-haiku-*
|
|
1880
|
-
["bedrock/anthropic.claude-sonnet*", "bedrock/anthropic.claude-3-haiku*"],
|
|
1881
|
-
["bedrock/anthropic.claude-opus*", "bedrock/anthropic.claude-3-haiku*"],
|
|
1882
|
-
["bedrock/anthropic.claude-3-5-sonnet*", "bedrock/anthropic.claude-3-5-haiku*"]
|
|
1883
|
-
];
|
|
1884
|
-
NO_AUTH_PROVIDERS = /* @__PURE__ */ new Set(["ollama", "lmstudio", "llamacpp"]);
|
|
1885
|
-
CompressionModelUnresolvedError = class extends Error {
|
|
1886
|
-
name = "CompressionModelUnresolvedError";
|
|
1887
|
-
agentModel;
|
|
1888
|
-
constructor(agentModel) {
|
|
1889
|
-
super(
|
|
1890
|
-
`Could not resolve a same-family-cheaper-tier compression model for "${agentModel}". Provide Agent.create({compression: {model: "<your-cheaper-model>"}}) OR add "${agentModel}" to the compression-model-registry (see ADR D440).`
|
|
1891
|
-
);
|
|
1892
|
-
this.agentModel = agentModel;
|
|
1893
|
-
}
|
|
1894
|
-
};
|
|
1895
|
-
}
|
|
1896
|
-
});
|
|
1897
1763
|
var MODALITIES, costSchema, limitSchema, modalitiesSchema, catalogModelSchema;
|
|
1898
1764
|
var init_catalog_schema = __esm({
|
|
1899
1765
|
"src/internal/providers/catalog-schema.ts"() {
|
|
@@ -1974,19 +1840,6 @@ var init_registry = __esm({
|
|
|
1974
1840
|
ALIASES = globalSingleton("theokit-sdk.providers.aliases", () => /* @__PURE__ */ new Map());
|
|
1975
1841
|
}
|
|
1976
1842
|
});
|
|
1977
|
-
|
|
1978
|
-
// src/internal/providers/catalog-loader.ts
|
|
1979
|
-
var catalog_loader_exports = {};
|
|
1980
|
-
__export(catalog_loader_exports, {
|
|
1981
|
-
_resetModelInfoIndexForTests: () => _resetModelInfoIndexForTests,
|
|
1982
|
-
getCatalogCapabilities: () => getCatalogCapabilities,
|
|
1983
|
-
getCatalogModelInfo: () => getCatalogModelInfo,
|
|
1984
|
-
isPatchedModelKey: () => isPatchedModelKey,
|
|
1985
|
-
listModelInfoKeys: () => listModelInfoKeys,
|
|
1986
|
-
loadProviderCatalog: () => loadProviderCatalog,
|
|
1987
|
-
patchModelInfo: () => patchModelInfo,
|
|
1988
|
-
registerCatalogProviders: () => registerCatalogProviders
|
|
1989
|
-
});
|
|
1990
1843
|
function globalSingleton2(key2, create) {
|
|
1991
1844
|
const g = globalThis;
|
|
1992
1845
|
const sym = Symbol.for(key2);
|
|
@@ -2000,16 +1853,6 @@ function getCatalogModelInfo(key2) {
|
|
|
2000
1853
|
function isPatchedModelKey(key2) {
|
|
2001
1854
|
return patchedModelKeys.has(key2);
|
|
2002
1855
|
}
|
|
2003
|
-
function patchModelInfo(key2, model) {
|
|
2004
|
-
ensureModelIndexLoaded();
|
|
2005
|
-
const existing = modelInfoIndex.get(key2);
|
|
2006
|
-
modelInfoIndex.set(key2, existing === void 0 ? model : { ...existing, ...model });
|
|
2007
|
-
patchedModelKeys.add(key2);
|
|
2008
|
-
}
|
|
2009
|
-
function listModelInfoKeys() {
|
|
2010
|
-
ensureModelIndexLoaded();
|
|
2011
|
-
return [...modelInfoIndex.keys()];
|
|
2012
|
-
}
|
|
2013
1856
|
function ensureModelIndexLoaded() {
|
|
2014
1857
|
if (indexState.loaded) return;
|
|
2015
1858
|
indexState.loaded = true;
|
|
@@ -2043,11 +1886,6 @@ function indexEntryModels(entry) {
|
|
|
2043
1886
|
}
|
|
2044
1887
|
}
|
|
2045
1888
|
}
|
|
2046
|
-
function _resetModelInfoIndexForTests() {
|
|
2047
|
-
modelInfoIndex.clear();
|
|
2048
|
-
patchedModelKeys.clear();
|
|
2049
|
-
indexState.loaded = false;
|
|
2050
|
-
}
|
|
2051
1889
|
function validateEntry(raw) {
|
|
2052
1890
|
if (typeof raw.id !== "string" || typeof raw.displayName !== "string" || typeof raw.apiMode !== "string" || typeof raw.authType !== "string" || typeof raw.baseUrl !== "string" || !Array.isArray(raw.envVars) || !Array.isArray(raw.fallbackModels) || raw.capabilities == null || typeof raw.capabilities !== "object") {
|
|
2053
1891
|
return null;
|
|
@@ -2058,12 +1896,6 @@ function loadProviderCatalog(opts) {
|
|
|
2058
1896
|
const catalogPath = path.join(__dirname_resolved, "provider-catalog.json");
|
|
2059
1897
|
const rawText = fs.readFileSync(catalogPath, "utf-8");
|
|
2060
1898
|
let entries = JSON.parse(rawText);
|
|
2061
|
-
if (opts?._testInjectMalformed) {
|
|
2062
|
-
entries = [
|
|
2063
|
-
...entries,
|
|
2064
|
-
{ id: "malformed-provider", displayName: "Bad" }
|
|
2065
|
-
];
|
|
2066
|
-
}
|
|
2067
1899
|
const result = {};
|
|
2068
1900
|
for (const raw of entries) {
|
|
2069
1901
|
const validated = validateEntry(raw);
|
|
@@ -2092,7 +1924,7 @@ function getCatalogCapabilities(providerId) {
|
|
|
2092
1924
|
return _capabilitiesCache[providerId];
|
|
2093
1925
|
}
|
|
2094
1926
|
function registerCatalogProviders(opts) {
|
|
2095
|
-
const catalog = loadProviderCatalog(
|
|
1927
|
+
const catalog = loadProviderCatalog();
|
|
2096
1928
|
for (const entry of Object.values(catalog)) {
|
|
2097
1929
|
if (getProviderProfile(entry.id) !== void 0) continue;
|
|
2098
1930
|
if (entry.aliases?.some((a) => getProviderProfile(a) !== void 0)) continue;
|
|
@@ -2133,6 +1965,15 @@ var init_catalog_loader = __esm({
|
|
|
2133
1965
|
}
|
|
2134
1966
|
});
|
|
2135
1967
|
|
|
1968
|
+
// src/compaction.ts
|
|
1969
|
+
function estimateTokens(text) {
|
|
1970
|
+
return Math.ceil(text.length / 4);
|
|
1971
|
+
}
|
|
1972
|
+
var init_compaction = __esm({
|
|
1973
|
+
"src/compaction.ts"() {
|
|
1974
|
+
}
|
|
1975
|
+
});
|
|
1976
|
+
|
|
2136
1977
|
// src/internal/providers/builtin/anthropic.ts
|
|
2137
1978
|
var ANTHROPIC;
|
|
2138
1979
|
var init_anthropic = __esm({
|
|
@@ -5777,12 +5618,6 @@ var init_vertex_router = __esm({
|
|
|
5777
5618
|
});
|
|
5778
5619
|
|
|
5779
5620
|
// src/internal/llm/router.ts
|
|
5780
|
-
var router_exports = {};
|
|
5781
|
-
__export(router_exports, {
|
|
5782
|
-
_resetCredentialPoolWarnings: () => _resetCredentialPoolWarnings,
|
|
5783
|
-
_resetNoAuthApiKeyWarnings: () => _resetNoAuthApiKeyWarnings,
|
|
5784
|
-
resolveProviderChain: () => resolveProviderChain
|
|
5785
|
-
});
|
|
5786
5621
|
function resolveProviderChain(options) {
|
|
5787
5622
|
registerBuiltins();
|
|
5788
5623
|
return buildChain(options);
|
|
@@ -5880,9 +5715,6 @@ function warnNoAuthApiKeysIgnoredOnce(provider) {
|
|
|
5880
5715
|
`
|
|
5881
5716
|
);
|
|
5882
5717
|
}
|
|
5883
|
-
function _resetNoAuthApiKeyWarnings() {
|
|
5884
|
-
warnedNoAuthApiKeys.clear();
|
|
5885
|
-
}
|
|
5886
5718
|
function sentinelForNoAuth(profile) {
|
|
5887
5719
|
return profile.authType === "none" ? profile.name : void 0;
|
|
5888
5720
|
}
|
|
@@ -5913,9 +5745,6 @@ function warnUnknownProvidersInApiKeys(apiKeys) {
|
|
|
5913
5745
|
}
|
|
5914
5746
|
}
|
|
5915
5747
|
}
|
|
5916
|
-
function _resetCredentialPoolWarnings() {
|
|
5917
|
-
warnedProviders.clear();
|
|
5918
|
-
}
|
|
5919
5748
|
function resolveApiKey2(envVars) {
|
|
5920
5749
|
for (const v of envVars) {
|
|
5921
5750
|
const value = process.env[v];
|
|
@@ -6019,41 +5848,318 @@ var init_router = __esm({
|
|
|
6019
5848
|
}
|
|
6020
5849
|
});
|
|
6021
5850
|
|
|
6022
|
-
// src/internal/local-agent/real-local-run-provider.ts
|
|
6023
|
-
|
|
6024
|
-
|
|
6025
|
-
|
|
6026
|
-
|
|
6027
|
-
}
|
|
6028
|
-
|
|
6029
|
-
|
|
6030
|
-
const byPrefix
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
|
|
5851
|
+
// src/internal/local-agent/real-local-run-provider.ts
|
|
5852
|
+
function inferProviderFromApiKey(apiKey) {
|
|
5853
|
+
if (apiKey === void 0 || apiKey.length === 0) return void 0;
|
|
5854
|
+
const byPrefix = [
|
|
5855
|
+
{ provider: "openrouter", prefix: "sk-or-" },
|
|
5856
|
+
{ provider: "anthropic", prefix: "sk-ant-" },
|
|
5857
|
+
{ provider: "openai", prefix: "sk-" }
|
|
5858
|
+
];
|
|
5859
|
+
for (const { provider, prefix } of byPrefix) {
|
|
5860
|
+
if (apiKey.startsWith(prefix) && getProviderProfile(provider) !== void 0) {
|
|
5861
|
+
return provider;
|
|
5862
|
+
}
|
|
5863
|
+
}
|
|
5864
|
+
return void 0;
|
|
5865
|
+
}
|
|
5866
|
+
function detectPrimaryProvider() {
|
|
5867
|
+
if (process.env.ANTHROPIC_API_KEY !== void 0 && process.env.ANTHROPIC_API_KEY.length > 0) {
|
|
5868
|
+
return "anthropic";
|
|
5869
|
+
}
|
|
5870
|
+
if (process.env.OPENAI_API_KEY !== void 0 && process.env.OPENAI_API_KEY.length > 0) {
|
|
5871
|
+
return "openai";
|
|
5872
|
+
}
|
|
5873
|
+
if (process.env.OPENROUTER_API_KEY !== void 0 && process.env.OPENROUTER_API_KEY.length > 0) {
|
|
5874
|
+
return "openrouter";
|
|
5875
|
+
}
|
|
5876
|
+
return "openai";
|
|
5877
|
+
}
|
|
5878
|
+
var init_real_local_run_provider = __esm({
|
|
5879
|
+
"src/internal/local-agent/real-local-run-provider.ts"() {
|
|
5880
|
+
init_providers();
|
|
5881
|
+
}
|
|
5882
|
+
});
|
|
5883
|
+
|
|
5884
|
+
// src/internal/runtime/compression/compression-model-registry.ts
|
|
5885
|
+
function resolveCompressionModel(agentModel) {
|
|
5886
|
+
const exact = EXACT_REGISTRY.get(agentModel);
|
|
5887
|
+
if (exact !== void 0) return exact;
|
|
5888
|
+
const wildcard = matchWildcard(agentModel);
|
|
5889
|
+
if (wildcard !== null) return wildcard;
|
|
5890
|
+
if (isNoAuthProvider(agentModel)) return agentModel;
|
|
5891
|
+
throw new CompressionModelUnresolvedError(agentModel);
|
|
5892
|
+
}
|
|
5893
|
+
function matchWildcard(agentModel) {
|
|
5894
|
+
for (const [pattern, replacement] of WILDCARD_REGISTRY) {
|
|
5895
|
+
const prefix = pattern.endsWith("*") ? pattern.slice(0, -1) : pattern;
|
|
5896
|
+
if (!agentModel.startsWith(prefix)) continue;
|
|
5897
|
+
const suffix = agentModel.slice(prefix.length);
|
|
5898
|
+
const replPrefix = replacement.endsWith("*") ? replacement.slice(0, -1) : replacement;
|
|
5899
|
+
return `${replPrefix}${suffix}`;
|
|
5900
|
+
}
|
|
5901
|
+
return null;
|
|
5902
|
+
}
|
|
5903
|
+
function isNoAuthProvider(agentModel) {
|
|
5904
|
+
const slashIdx = agentModel.indexOf("/");
|
|
5905
|
+
if (slashIdx <= 0) return false;
|
|
5906
|
+
return NO_AUTH_PROVIDERS.has(agentModel.slice(0, slashIdx));
|
|
5907
|
+
}
|
|
5908
|
+
var EXACT_REGISTRY, WILDCARD_REGISTRY, NO_AUTH_PROVIDERS, CompressionModelUnresolvedError;
|
|
5909
|
+
var init_compression_model_registry = __esm({
|
|
5910
|
+
"src/internal/runtime/compression/compression-model-registry.ts"() {
|
|
5911
|
+
EXACT_REGISTRY = /* @__PURE__ */ new Map([
|
|
5912
|
+
// OpenAI family
|
|
5913
|
+
["openai/gpt-4o", "openai/gpt-4o-mini"],
|
|
5914
|
+
["openai/gpt-4-turbo", "openai/gpt-4o-mini"],
|
|
5915
|
+
["openai/gpt-4", "openai/gpt-4o-mini"],
|
|
5916
|
+
["openai/o1-preview", "openai/gpt-4o-mini"],
|
|
5917
|
+
["openai/o1", "openai/gpt-4o-mini"],
|
|
5918
|
+
["openai/o3", "openai/gpt-4o-mini"],
|
|
5919
|
+
["openai/o3-mini", "openai/gpt-4o-mini"],
|
|
5920
|
+
// Anthropic family
|
|
5921
|
+
["anthropic/claude-opus-4", "anthropic/claude-3-5-haiku-latest"],
|
|
5922
|
+
["anthropic/claude-sonnet-4", "anthropic/claude-3-5-haiku-latest"],
|
|
5923
|
+
["anthropic/claude-3-5-sonnet", "anthropic/claude-3-5-haiku-latest"],
|
|
5924
|
+
["anthropic/claude-3-5-sonnet-latest", "anthropic/claude-3-5-haiku-latest"],
|
|
5925
|
+
["anthropic/claude-3-opus", "anthropic/claude-3-haiku"],
|
|
5926
|
+
["anthropic/claude-3-sonnet", "anthropic/claude-3-haiku"],
|
|
5927
|
+
// Vertex (Gemini + Anthropic-on-Vertex)
|
|
5928
|
+
["vertex/gemini-1.5-pro", "vertex/gemini-1.5-flash"],
|
|
5929
|
+
["vertex/gemini-2.0-pro", "vertex/gemini-1.5-flash"],
|
|
5930
|
+
["vertex/claude-3-5-sonnet", "vertex/claude-3-5-haiku"],
|
|
5931
|
+
["vertex/claude-3-opus", "vertex/claude-3-haiku"],
|
|
5932
|
+
// OpenRouter (preserve openrouter prefix, swap tier within same vendor)
|
|
5933
|
+
["openrouter/openai/gpt-4o", "openrouter/openai/gpt-4o-mini"],
|
|
5934
|
+
["openrouter/openai/gpt-4-turbo", "openrouter/openai/gpt-4o-mini"],
|
|
5935
|
+
["openrouter/anthropic/claude-3-5-sonnet", "openrouter/anthropic/claude-3-5-haiku"],
|
|
5936
|
+
["openrouter/anthropic/claude-opus-4", "openrouter/anthropic/claude-3-5-haiku"]
|
|
5937
|
+
]);
|
|
5938
|
+
WILDCARD_REGISTRY = [
|
|
5939
|
+
// Bedrock Anthropic: us.anthropic.claude-sonnet-* → us.anthropic.claude-3-haiku-*
|
|
5940
|
+
["bedrock/anthropic.claude-sonnet*", "bedrock/anthropic.claude-3-haiku*"],
|
|
5941
|
+
["bedrock/anthropic.claude-opus*", "bedrock/anthropic.claude-3-haiku*"],
|
|
5942
|
+
["bedrock/anthropic.claude-3-5-sonnet*", "bedrock/anthropic.claude-3-5-haiku*"]
|
|
5943
|
+
];
|
|
5944
|
+
NO_AUTH_PROVIDERS = /* @__PURE__ */ new Set(["ollama", "lmstudio", "llamacpp"]);
|
|
5945
|
+
CompressionModelUnresolvedError = class extends Error {
|
|
5946
|
+
name = "CompressionModelUnresolvedError";
|
|
5947
|
+
agentModel;
|
|
5948
|
+
constructor(agentModel) {
|
|
5949
|
+
super(
|
|
5950
|
+
`Could not resolve a same-family-cheaper-tier compression model for "${agentModel}". Provide Agent.create({compression: {model: "<your-cheaper-model>"}}) OR add "${agentModel}" to the compression-model-registry (see ADR D440).`
|
|
5951
|
+
);
|
|
5952
|
+
this.agentModel = agentModel;
|
|
5953
|
+
}
|
|
5954
|
+
};
|
|
5955
|
+
}
|
|
5956
|
+
});
|
|
5957
|
+
|
|
5958
|
+
// src/internal/runtime/compression/compression-summarizer.ts
|
|
5959
|
+
function buildCompressionPrompt(messages) {
|
|
5960
|
+
const formatted = messages.map((m) => `[${m.role}]: ${m.content}`).join("\n\n");
|
|
5961
|
+
return `Summarize the following ${messages.length} conversation messages into a concise summary that preserves ALL facts, decisions, user preferences, and context needed for the conversation to continue naturally. The summary will replace these messages in the context window. Be thorough but concise.
|
|
5962
|
+
|
|
5963
|
+
--- CONVERSATION TO SUMMARIZE ---
|
|
5964
|
+
${formatted}
|
|
5965
|
+
--- END ---`;
|
|
5966
|
+
}
|
|
5967
|
+
async function compressConversationWindow(opts) {
|
|
5968
|
+
const userPrompt = buildCompressionPrompt(opts.messages);
|
|
5969
|
+
let summary;
|
|
5970
|
+
try {
|
|
5971
|
+
summary = await opts.callLlm(opts.model, COMPRESSION_SYSTEM, userPrompt);
|
|
5972
|
+
} catch (cause) {
|
|
5973
|
+
throw new CompressionFailedError(
|
|
5974
|
+
`Compression LLM call failed: ${cause instanceof Error ? cause.message : String(cause)}`,
|
|
5975
|
+
{ cause: cause instanceof Error ? cause : void 0 }
|
|
5976
|
+
);
|
|
5977
|
+
}
|
|
5978
|
+
if (!summary || summary.trim().length === 0) {
|
|
5979
|
+
throw new CompressionFailedError(
|
|
5980
|
+
"Compression LLM returned empty summary \u2014 reduction ineffective."
|
|
5981
|
+
);
|
|
5982
|
+
}
|
|
5983
|
+
return {
|
|
5984
|
+
role: "system",
|
|
5985
|
+
content: `[Compressed conversation summary]: ${summary.trim()}`
|
|
5986
|
+
};
|
|
5987
|
+
}
|
|
5988
|
+
var CompressionFailedError, COMPRESSION_SYSTEM;
|
|
5989
|
+
var init_compression_summarizer = __esm({
|
|
5990
|
+
"src/internal/runtime/compression/compression-summarizer.ts"() {
|
|
5991
|
+
CompressionFailedError = class extends Error {
|
|
5992
|
+
name = "CompressionFailedError";
|
|
5993
|
+
};
|
|
5994
|
+
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.";
|
|
5995
|
+
}
|
|
5996
|
+
});
|
|
5997
|
+
|
|
5998
|
+
// src/internal/session/agent-session-store.ts
|
|
5999
|
+
function seedTranscript(prior, opts) {
|
|
6000
|
+
return SessionTranscript.fromRecords(prior, opts);
|
|
6001
|
+
}
|
|
6002
|
+
function mapAgentTurn(steps) {
|
|
6003
|
+
const assistant = {};
|
|
6004
|
+
const toolResults = [];
|
|
6005
|
+
const toolCalls = [];
|
|
6006
|
+
for (const step of steps) {
|
|
6007
|
+
if (step.type === "thinkingMessage") assistant.thinking = step.message.text;
|
|
6008
|
+
else if (step.type === "assistantMessage") assistant.text = step.message.text;
|
|
6009
|
+
else if (step.type === "toolCall")
|
|
6010
|
+
toolCalls.push({
|
|
6011
|
+
id: step.message.callId,
|
|
6012
|
+
name: step.message.name,
|
|
6013
|
+
input: step.message.args ?? {}
|
|
6014
|
+
});
|
|
6015
|
+
else
|
|
6016
|
+
toolResults.push({
|
|
6017
|
+
toolUseId: step.message.callId,
|
|
6018
|
+
content: step.message.result,
|
|
6019
|
+
isError: step.message.isError
|
|
6020
|
+
});
|
|
6021
|
+
}
|
|
6022
|
+
if (toolCalls.length > 0) assistant.toolCalls = toolCalls;
|
|
6023
|
+
return { assistant, toolResults };
|
|
6024
|
+
}
|
|
6025
|
+
function hasAssistantContent(a) {
|
|
6026
|
+
return a.text !== void 0 || a.thinking !== void 0 || (a.toolCalls?.length ?? 0) > 0;
|
|
6027
|
+
}
|
|
6028
|
+
function appendConversation(transcript, conversation) {
|
|
6029
|
+
for (const ct of conversation) {
|
|
6030
|
+
if (ct.type !== "agentConversationTurn") continue;
|
|
6031
|
+
const { assistant, toolResults } = mapAgentTurn(ct.turn.steps);
|
|
6032
|
+
if (hasAssistantContent(assistant)) transcript.appendAssistantTurn(assistant);
|
|
6033
|
+
if (toolResults.length > 0) transcript.appendToolResults(toolResults);
|
|
6034
|
+
}
|
|
6035
|
+
}
|
|
6036
|
+
async function readSessionMessages(store, agentId) {
|
|
6037
|
+
const records = await store.readRecords(agentId);
|
|
6038
|
+
return reconstructMessages(records).map(narrowToSessionMessage);
|
|
6039
|
+
}
|
|
6040
|
+
function partToText(p) {
|
|
6041
|
+
if (p.type === "text") return p.text ?? "";
|
|
6042
|
+
if (p.type === "tool_use") return `[tool call] ${p.name ?? ""}`;
|
|
6043
|
+
if (p.type === "tool_result") {
|
|
6044
|
+
const body = typeof p.content === "string" ? p.content : JSON.stringify(p.content);
|
|
6045
|
+
return `[tool result] ${body}`;
|
|
6046
|
+
}
|
|
6047
|
+
return "";
|
|
6048
|
+
}
|
|
6049
|
+
function narrowToSessionMessage(m) {
|
|
6050
|
+
const role = m.role === "user" ? "user" : "assistant";
|
|
6051
|
+
const text = m.content.map(partToText).filter((s) => s.length > 0).join("\n");
|
|
6052
|
+
return { role, text };
|
|
6053
|
+
}
|
|
6054
|
+
function deltaRecords(transcript, priorLength) {
|
|
6055
|
+
return transcript.records().slice(priorLength);
|
|
6056
|
+
}
|
|
6057
|
+
async function persistTurn(store, loc, sessionId, turn) {
|
|
6058
|
+
const prior = await store.readRecords(loc.agentId);
|
|
6059
|
+
const transcript = seedTranscript(prior, { cwd: loc.cwd, sessionId, model: loc.model });
|
|
6060
|
+
transcript.appendUserTurn(turn.userText);
|
|
6061
|
+
appendConversation(transcript, turn.conversation);
|
|
6062
|
+
await store.appendRecords(loc.agentId, deltaRecords(transcript, prior.length));
|
|
6063
|
+
}
|
|
6064
|
+
var init_agent_session_store = __esm({
|
|
6065
|
+
"src/internal/session/agent-session-store.ts"() {
|
|
6066
|
+
init_session_transcript();
|
|
6067
|
+
}
|
|
6068
|
+
});
|
|
6069
|
+
|
|
6070
|
+
// src/internal/session/agent-session.ts
|
|
6071
|
+
function transcriptKey(cwd, agentId) {
|
|
6072
|
+
return `${cwd}::${agentId}`;
|
|
6073
|
+
}
|
|
6074
|
+
function appendSessionMessage(agentId, message) {
|
|
6075
|
+
const existing = sessions.get(agentId) ?? [];
|
|
6076
|
+
existing.push(message);
|
|
6077
|
+
sessions.set(agentId, existing);
|
|
6078
|
+
}
|
|
6079
|
+
function getSessionMessages(agentId) {
|
|
6080
|
+
return sessions.get(agentId) ?? [];
|
|
6081
|
+
}
|
|
6082
|
+
function persistTurnToTranscript(store, loc, sessionId, turn, onCompact) {
|
|
6083
|
+
const key2 = transcriptKey(loc.cwd, loc.agentId);
|
|
6084
|
+
const chained = (pendingWrites.get(key2) ?? Promise.resolve()).then(async () => {
|
|
6085
|
+
try {
|
|
6086
|
+
await persistTurn(store, loc, sessionId, turn);
|
|
6087
|
+
const count = (recordCounts.get(key2) ?? 0) + 1;
|
|
6088
|
+
recordCounts.set(key2, count);
|
|
6089
|
+
if (turn.autoCompact !== void 0) {
|
|
6090
|
+
const { autoCompactIfNeeded: autoCompactIfNeeded2 } = await Promise.resolve().then(() => (init_compact_session(), compact_session_exports));
|
|
6091
|
+
const fired = await autoCompactIfNeeded2({
|
|
6092
|
+
store,
|
|
6093
|
+
loc,
|
|
6094
|
+
sessionId,
|
|
6095
|
+
usageTotal: turn.autoCompact.usageTotal,
|
|
6096
|
+
contextWindow: turn.autoCompact.contextWindow,
|
|
6097
|
+
turnCount: count,
|
|
6098
|
+
summarize: turn.autoCompact.summarize
|
|
6099
|
+
});
|
|
6100
|
+
if (fired) onCompact?.();
|
|
6101
|
+
}
|
|
6102
|
+
} catch (cause) {
|
|
6103
|
+
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
6104
|
+
process.stderr.write(
|
|
6105
|
+
`[theokit-sdk] session transcript write failed (${loc.agentId}): ${msg}
|
|
6106
|
+
`
|
|
6107
|
+
);
|
|
6038
6108
|
}
|
|
6039
|
-
}
|
|
6040
|
-
|
|
6109
|
+
});
|
|
6110
|
+
pendingWrites.set(
|
|
6111
|
+
key2,
|
|
6112
|
+
chained.then(
|
|
6113
|
+
() => void 0,
|
|
6114
|
+
() => void 0
|
|
6115
|
+
)
|
|
6116
|
+
);
|
|
6041
6117
|
}
|
|
6042
|
-
function
|
|
6043
|
-
|
|
6044
|
-
|
|
6045
|
-
|
|
6046
|
-
|
|
6047
|
-
|
|
6118
|
+
async function hydrateSession(agentId, loc) {
|
|
6119
|
+
const key2 = transcriptKey(loc.cwd, agentId);
|
|
6120
|
+
if (hydratedKeys.has(key2)) return;
|
|
6121
|
+
hydratedKeys.add(key2);
|
|
6122
|
+
const persisted = await readSessionMessages(loc.store, agentId);
|
|
6123
|
+
if (persisted.length === 0) return;
|
|
6124
|
+
if (!sessions.has(agentId) || sessions.get(agentId)?.length === 0) {
|
|
6125
|
+
sessions.set(agentId, persisted);
|
|
6048
6126
|
}
|
|
6049
|
-
|
|
6050
|
-
|
|
6127
|
+
}
|
|
6128
|
+
async function flushSessionWrites() {
|
|
6129
|
+
while (pendingWrites.size > 0) {
|
|
6130
|
+
const all = Array.from(pendingWrites.values());
|
|
6131
|
+
pendingWrites.clear();
|
|
6132
|
+
await Promise.all(all);
|
|
6051
6133
|
}
|
|
6052
|
-
return "openai";
|
|
6053
6134
|
}
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
|
|
6135
|
+
function clearSession(agentId) {
|
|
6136
|
+
sessions.delete(agentId);
|
|
6137
|
+
}
|
|
6138
|
+
function invalidateSessionCache(cwd, agentId) {
|
|
6139
|
+
sessions.delete(agentId);
|
|
6140
|
+
hydratedKeys.delete(transcriptKey(cwd, agentId));
|
|
6141
|
+
}
|
|
6142
|
+
function enqueueSessionWrite(cwd, agentId, fn) {
|
|
6143
|
+
const key2 = transcriptKey(cwd, agentId);
|
|
6144
|
+
const prior = pendingWrites.get(key2) ?? Promise.resolve();
|
|
6145
|
+
const result = prior.then(fn);
|
|
6146
|
+
pendingWrites.set(
|
|
6147
|
+
key2,
|
|
6148
|
+
result.then(
|
|
6149
|
+
() => void 0,
|
|
6150
|
+
() => void 0
|
|
6151
|
+
)
|
|
6152
|
+
);
|
|
6153
|
+
return result;
|
|
6154
|
+
}
|
|
6155
|
+
var sessions, hydratedKeys, pendingWrites, recordCounts;
|
|
6156
|
+
var init_agent_session = __esm({
|
|
6157
|
+
"src/internal/session/agent-session.ts"() {
|
|
6158
|
+
init_agent_session_store();
|
|
6159
|
+
sessions = /* @__PURE__ */ new Map();
|
|
6160
|
+
hydratedKeys = /* @__PURE__ */ new Set();
|
|
6161
|
+
pendingWrites = /* @__PURE__ */ new Map();
|
|
6162
|
+
recordCounts = /* @__PURE__ */ new Map();
|
|
6057
6163
|
}
|
|
6058
6164
|
});
|
|
6059
6165
|
|
|
@@ -6095,7 +6201,14 @@ async function compactSessionTranscript(opts) {
|
|
|
6095
6201
|
const m = compressible[i];
|
|
6096
6202
|
if (m === void 0 || m.role !== "user" || isCompactSummary(m.content)) continue;
|
|
6097
6203
|
const cost = estimateTokens(m.content);
|
|
6098
|
-
if (budget + cost > COMPACT_USER_MESSAGE_MAX_TOKENS)
|
|
6204
|
+
if (budget + cost > COMPACT_USER_MESSAGE_MAX_TOKENS) {
|
|
6205
|
+
const remaining = COMPACT_USER_MESSAGE_MAX_TOKENS - budget;
|
|
6206
|
+
if (remaining > 50) {
|
|
6207
|
+
preserved.unshift(`${m.content.slice(0, remaining * 4)}
|
|
6208
|
+
[...truncated for compaction...]`);
|
|
6209
|
+
}
|
|
6210
|
+
break;
|
|
6211
|
+
}
|
|
6099
6212
|
budget += cost;
|
|
6100
6213
|
preserved.unshift(m.content);
|
|
6101
6214
|
}
|
|
@@ -6111,30 +6224,29 @@ ${summaryBody}`;
|
|
|
6111
6224
|
transcript.appendUserTurn(summary);
|
|
6112
6225
|
const delta = transcript.records().slice(prior.length);
|
|
6113
6226
|
await opts.store.appendRecords(opts.loc.agentId, delta);
|
|
6227
|
+
invalidateSessionCache(opts.loc.cwd, opts.loc.agentId);
|
|
6114
6228
|
const postTokens = estimateTokens([...preserved, summary].join("\n"));
|
|
6115
6229
|
return { preTokens, postTokens };
|
|
6116
6230
|
}
|
|
6117
6231
|
function buildDefaultSummarizer(opts) {
|
|
6118
6232
|
return async (messages) => {
|
|
6119
|
-
const
|
|
6120
|
-
const { resolveCompressionModel: resolveCompressionModel2 } = await Promise.resolve().then(() => (init_compression_model_registry(), compression_model_registry_exports));
|
|
6121
|
-
const { resolveProviderChain: resolveProviderChain2 } = await Promise.resolve().then(() => (init_router(), router_exports));
|
|
6122
|
-
const { inferProviderFromApiKey: inferProviderFromApiKey2, detectPrimaryProvider: detectPrimaryProvider2 } = await Promise.resolve().then(() => (init_real_local_run_provider(), real_local_run_provider_exports));
|
|
6123
|
-
const keyProvider = inferProviderFromApiKey2(opts.apiKey);
|
|
6233
|
+
const keyProvider = inferProviderFromApiKey(opts.apiKey);
|
|
6124
6234
|
const modelPrefix = opts.agentModel.includes("/") ? opts.agentModel.slice(0, opts.agentModel.indexOf("/")) : void 0;
|
|
6125
|
-
|
|
6235
|
+
registerBuiltins();
|
|
6236
|
+
const prefixProfile = modelPrefix !== void 0 ? getProviderProfile(modelPrefix) : void 0;
|
|
6237
|
+
const provider = prefixProfile !== void 0 ? modelPrefix : keyProvider ?? detectPrimaryProvider();
|
|
6126
6238
|
let model;
|
|
6127
6239
|
if (provider !== modelPrefix) {
|
|
6128
6240
|
model = opts.agentModel;
|
|
6129
6241
|
} else {
|
|
6130
6242
|
try {
|
|
6131
|
-
model =
|
|
6243
|
+
model = resolveCompressionModel(opts.agentModel);
|
|
6132
6244
|
} catch {
|
|
6133
6245
|
model = opts.agentModel;
|
|
6134
6246
|
}
|
|
6135
6247
|
}
|
|
6136
6248
|
const callLlm = async (m, system, user) => {
|
|
6137
|
-
const chain =
|
|
6249
|
+
const chain = resolveProviderChain({
|
|
6138
6250
|
primary: provider,
|
|
6139
6251
|
...opts.apiKey !== void 0 ? { apiKeys: { [provider]: [opts.apiKey] } } : {}
|
|
6140
6252
|
});
|
|
@@ -6154,7 +6266,7 @@ function buildDefaultSummarizer(opts) {
|
|
|
6154
6266
|
}
|
|
6155
6267
|
return text;
|
|
6156
6268
|
};
|
|
6157
|
-
const summary = await
|
|
6269
|
+
const summary = await compressConversationWindow({ messages: [...messages], model, callLlm });
|
|
6158
6270
|
return summary.content;
|
|
6159
6271
|
};
|
|
6160
6272
|
}
|
|
@@ -6188,6 +6300,12 @@ var COMPACT_SUMMARY_MARKER, COMPACT_USER_MESSAGE_MAX_TOKENS, autoCompactAttempts
|
|
|
6188
6300
|
var init_compact_session = __esm({
|
|
6189
6301
|
"src/internal/session/compact-session.ts"() {
|
|
6190
6302
|
init_compaction();
|
|
6303
|
+
init_router();
|
|
6304
|
+
init_real_local_run_provider();
|
|
6305
|
+
init_providers();
|
|
6306
|
+
init_compression_model_registry();
|
|
6307
|
+
init_compression_summarizer();
|
|
6308
|
+
init_agent_session();
|
|
6191
6309
|
init_session_transcript();
|
|
6192
6310
|
COMPACT_SUMMARY_MARKER = "[[theokit:compact-summary]]";
|
|
6193
6311
|
COMPACT_USER_MESSAGE_MAX_TOKENS = 2e4;
|
|
@@ -13018,147 +13136,8 @@ function parseDecisionFromStdout(stdout) {
|
|
|
13018
13136
|
// src/internal/runtime/lifecycle/post-run-lifecycle.ts
|
|
13019
13137
|
init_run_events();
|
|
13020
13138
|
init_session_summary_writer();
|
|
13021
|
-
|
|
13022
|
-
|
|
13023
|
-
init_session_transcript();
|
|
13024
|
-
function seedTranscript(prior, opts) {
|
|
13025
|
-
return SessionTranscript.fromRecords(prior, opts);
|
|
13026
|
-
}
|
|
13027
|
-
function mapAgentTurn(steps) {
|
|
13028
|
-
const assistant = {};
|
|
13029
|
-
const toolResults = [];
|
|
13030
|
-
const toolCalls = [];
|
|
13031
|
-
for (const step of steps) {
|
|
13032
|
-
if (step.type === "thinkingMessage") assistant.thinking = step.message.text;
|
|
13033
|
-
else if (step.type === "assistantMessage") assistant.text = step.message.text;
|
|
13034
|
-
else if (step.type === "toolCall")
|
|
13035
|
-
toolCalls.push({
|
|
13036
|
-
id: step.message.callId,
|
|
13037
|
-
name: step.message.name,
|
|
13038
|
-
input: step.message.args ?? {}
|
|
13039
|
-
});
|
|
13040
|
-
else
|
|
13041
|
-
toolResults.push({
|
|
13042
|
-
toolUseId: step.message.callId,
|
|
13043
|
-
content: step.message.result,
|
|
13044
|
-
isError: step.message.isError
|
|
13045
|
-
});
|
|
13046
|
-
}
|
|
13047
|
-
if (toolCalls.length > 0) assistant.toolCalls = toolCalls;
|
|
13048
|
-
return { assistant, toolResults };
|
|
13049
|
-
}
|
|
13050
|
-
function hasAssistantContent(a) {
|
|
13051
|
-
return a.text !== void 0 || a.thinking !== void 0 || (a.toolCalls?.length ?? 0) > 0;
|
|
13052
|
-
}
|
|
13053
|
-
function appendConversation(transcript, conversation) {
|
|
13054
|
-
for (const ct of conversation) {
|
|
13055
|
-
if (ct.type !== "agentConversationTurn") continue;
|
|
13056
|
-
const { assistant, toolResults } = mapAgentTurn(ct.turn.steps);
|
|
13057
|
-
if (hasAssistantContent(assistant)) transcript.appendAssistantTurn(assistant);
|
|
13058
|
-
if (toolResults.length > 0) transcript.appendToolResults(toolResults);
|
|
13059
|
-
}
|
|
13060
|
-
}
|
|
13061
|
-
async function readSessionMessages(store, agentId) {
|
|
13062
|
-
const records = await store.readRecords(agentId);
|
|
13063
|
-
return reconstructMessages(records).map(narrowToSessionMessage);
|
|
13064
|
-
}
|
|
13065
|
-
function partToText(p) {
|
|
13066
|
-
if (p.type === "text") return p.text ?? "";
|
|
13067
|
-
if (p.type === "tool_use") return `[tool call] ${p.name ?? ""}`;
|
|
13068
|
-
if (p.type === "tool_result") {
|
|
13069
|
-
const body = typeof p.content === "string" ? p.content : JSON.stringify(p.content);
|
|
13070
|
-
return `[tool result] ${body}`;
|
|
13071
|
-
}
|
|
13072
|
-
return "";
|
|
13073
|
-
}
|
|
13074
|
-
function narrowToSessionMessage(m) {
|
|
13075
|
-
const role = m.role === "user" ? "user" : "assistant";
|
|
13076
|
-
const text = m.content.map(partToText).filter((s) => s.length > 0).join("\n");
|
|
13077
|
-
return { role, text };
|
|
13078
|
-
}
|
|
13079
|
-
function deltaRecords(transcript, priorLength) {
|
|
13080
|
-
return transcript.records().slice(priorLength);
|
|
13081
|
-
}
|
|
13082
|
-
async function persistTurn(store, loc, sessionId, turn) {
|
|
13083
|
-
const prior = await store.readRecords(loc.agentId);
|
|
13084
|
-
const transcript = seedTranscript(prior, { cwd: loc.cwd, sessionId, model: loc.model });
|
|
13085
|
-
transcript.appendUserTurn(turn.userText);
|
|
13086
|
-
appendConversation(transcript, turn.conversation);
|
|
13087
|
-
await store.appendRecords(loc.agentId, deltaRecords(transcript, prior.length));
|
|
13088
|
-
}
|
|
13089
|
-
|
|
13090
|
-
// src/internal/session/agent-session.ts
|
|
13091
|
-
var sessions = /* @__PURE__ */ new Map();
|
|
13092
|
-
var hydratedKeys = /* @__PURE__ */ new Set();
|
|
13093
|
-
var pendingWrites = /* @__PURE__ */ new Map();
|
|
13094
|
-
var recordCounts = /* @__PURE__ */ new Map();
|
|
13095
|
-
function transcriptKey(cwd, agentId) {
|
|
13096
|
-
return `${cwd}::${agentId}`;
|
|
13097
|
-
}
|
|
13098
|
-
function appendSessionMessage(agentId, message) {
|
|
13099
|
-
const existing = sessions.get(agentId) ?? [];
|
|
13100
|
-
existing.push(message);
|
|
13101
|
-
sessions.set(agentId, existing);
|
|
13102
|
-
}
|
|
13103
|
-
function getSessionMessages(agentId) {
|
|
13104
|
-
return sessions.get(agentId) ?? [];
|
|
13105
|
-
}
|
|
13106
|
-
function persistTurnToTranscript(store, loc, sessionId, turn, onCompact) {
|
|
13107
|
-
const key2 = transcriptKey(loc.cwd, loc.agentId);
|
|
13108
|
-
const chained = (pendingWrites.get(key2) ?? Promise.resolve()).then(async () => {
|
|
13109
|
-
try {
|
|
13110
|
-
await persistTurn(store, loc, sessionId, turn);
|
|
13111
|
-
const count = (recordCounts.get(key2) ?? 0) + 1;
|
|
13112
|
-
recordCounts.set(key2, count);
|
|
13113
|
-
if (turn.autoCompact !== void 0) {
|
|
13114
|
-
const { autoCompactIfNeeded: autoCompactIfNeeded2 } = await Promise.resolve().then(() => (init_compact_session(), compact_session_exports));
|
|
13115
|
-
const fired = await autoCompactIfNeeded2({
|
|
13116
|
-
store,
|
|
13117
|
-
loc,
|
|
13118
|
-
sessionId,
|
|
13119
|
-
usageTotal: turn.autoCompact.usageTotal,
|
|
13120
|
-
contextWindow: turn.autoCompact.contextWindow,
|
|
13121
|
-
turnCount: count,
|
|
13122
|
-
summarize: turn.autoCompact.summarize
|
|
13123
|
-
});
|
|
13124
|
-
if (fired) onCompact?.();
|
|
13125
|
-
}
|
|
13126
|
-
} catch (cause) {
|
|
13127
|
-
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
13128
|
-
process.stderr.write(
|
|
13129
|
-
`[theokit-sdk] session transcript write failed (${loc.agentId}): ${msg}
|
|
13130
|
-
`
|
|
13131
|
-
);
|
|
13132
|
-
}
|
|
13133
|
-
});
|
|
13134
|
-
pendingWrites.set(
|
|
13135
|
-
key2,
|
|
13136
|
-
chained.then(
|
|
13137
|
-
() => void 0,
|
|
13138
|
-
() => void 0
|
|
13139
|
-
)
|
|
13140
|
-
);
|
|
13141
|
-
}
|
|
13142
|
-
async function hydrateSession(agentId, loc) {
|
|
13143
|
-
const key2 = transcriptKey(loc.cwd, agentId);
|
|
13144
|
-
if (hydratedKeys.has(key2)) return;
|
|
13145
|
-
hydratedKeys.add(key2);
|
|
13146
|
-
const persisted = await readSessionMessages(loc.store, agentId);
|
|
13147
|
-
if (persisted.length === 0) return;
|
|
13148
|
-
if (!sessions.has(agentId) || sessions.get(agentId)?.length === 0) {
|
|
13149
|
-
sessions.set(agentId, persisted);
|
|
13150
|
-
}
|
|
13151
|
-
}
|
|
13152
|
-
async function flushSessionWrites() {
|
|
13153
|
-
while (pendingWrites.size > 0) {
|
|
13154
|
-
const all = Array.from(pendingWrites.values());
|
|
13155
|
-
pendingWrites.clear();
|
|
13156
|
-
await Promise.all(all);
|
|
13157
|
-
}
|
|
13158
|
-
}
|
|
13159
|
-
function clearSession(agentId) {
|
|
13160
|
-
sessions.delete(agentId);
|
|
13161
|
-
}
|
|
13139
|
+
init_catalog_loader();
|
|
13140
|
+
init_compact_session();
|
|
13162
13141
|
|
|
13163
13142
|
// src/internal/runtime/memory/memory-path-selector.ts
|
|
13164
13143
|
var PORT_MEMORY_PATH_ENV_VAR = "THEOKIT_PORT_MEMORY_PATH";
|
|
@@ -13207,9 +13186,21 @@ async function runPostRunLifecycle(inputs) {
|
|
|
13207
13186
|
appendSessionMessage(agentId, { role: "assistant", text: result.result });
|
|
13208
13187
|
}
|
|
13209
13188
|
const conversation = await safeConversation(run);
|
|
13210
|
-
const
|
|
13211
|
-
|
|
13212
|
-
|
|
13189
|
+
const contextWindow = getCatalogModelInfo(model)?.limit?.context;
|
|
13190
|
+
if (contextWindow === void 0) {
|
|
13191
|
+
const g = globalThis;
|
|
13192
|
+
const sym = /* @__PURE__ */ Symbol.for("theokit-sdk.compact.no-cw-warned");
|
|
13193
|
+
const warned3 = g[sym] ??= /* @__PURE__ */ new Set();
|
|
13194
|
+
if (!warned3.has(model)) {
|
|
13195
|
+
warned3.add(model);
|
|
13196
|
+
process.stderr.write(
|
|
13197
|
+
`[theokit-sdk] auto-compaction disabled: model "${model}" has no context-window entry in the catalog
|
|
13198
|
+
`
|
|
13199
|
+
);
|
|
13200
|
+
}
|
|
13201
|
+
}
|
|
13202
|
+
const lastRequestUsage = result.usage?.requests?.at(-1)?.totalTokens;
|
|
13203
|
+
const usageForTrigger = lastRequestUsage ?? result.usage?.totalTokens;
|
|
13213
13204
|
persistTurnToTranscript(
|
|
13214
13205
|
sessionStore,
|
|
13215
13206
|
{ cwd: workspaceCwd, agentId, model },
|
|
@@ -13218,9 +13209,9 @@ async function runPostRunLifecycle(inputs) {
|
|
|
13218
13209
|
userText,
|
|
13219
13210
|
conversation,
|
|
13220
13211
|
autoCompact: {
|
|
13221
|
-
usageTotal:
|
|
13212
|
+
usageTotal: usageForTrigger,
|
|
13222
13213
|
contextWindow,
|
|
13223
|
-
summarize:
|
|
13214
|
+
summarize: buildDefaultSummarizer({
|
|
13224
13215
|
agentModel: model,
|
|
13225
13216
|
...inputs.apiKey !== void 0 ? { apiKey: inputs.apiKey } : {}
|
|
13226
13217
|
})
|
|
@@ -21215,6 +21206,7 @@ async function getRegisteredAgentOrThrow(agentId) {
|
|
|
21215
21206
|
// src/agent.ts
|
|
21216
21207
|
init_errors();
|
|
21217
21208
|
init_discovery();
|
|
21209
|
+
init_agent_session();
|
|
21218
21210
|
init_agent_factory_registry();
|
|
21219
21211
|
var streamObjectImport;
|
|
21220
21212
|
var Agent = class _Agent {
|
|
@@ -21517,7 +21509,7 @@ var Agent = class _Agent {
|
|
|
21517
21509
|
const { defaultBaseDir: defaultBaseDir2, expandTilde: expandTilde2 } = await Promise.resolve().then(() => (init_session_transcript(), session_transcript_exports));
|
|
21518
21510
|
const baseDir = reg.options.local?.baseDir !== void 0 ? expandTilde2(reg.options.local.baseDir) : defaultBaseDir2();
|
|
21519
21511
|
const store = new FsSessionStore2({ baseDir, cwd });
|
|
21520
|
-
return compactSessionTranscript2({
|
|
21512
|
+
return enqueueSessionWrite(cwd, agentId, () => compactSessionTranscript2({
|
|
21521
21513
|
store,
|
|
21522
21514
|
loc: { cwd, agentId, model },
|
|
21523
21515
|
sessionId: agentId,
|
|
@@ -21526,7 +21518,7 @@ var Agent = class _Agent {
|
|
|
21526
21518
|
agentModel: model,
|
|
21527
21519
|
...reg.options.apiKey !== void 0 ? { apiKey: reg.options.apiKey } : {}
|
|
21528
21520
|
})
|
|
21529
|
-
});
|
|
21521
|
+
}));
|
|
21530
21522
|
}
|
|
21531
21523
|
/**
|
|
21532
21524
|
* Permanently delete a cloud agent.
|