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