stratagate-dsh 0.3.14 → 0.3.15
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 +671 -665
- package/LICENSE +21 -21
- package/dist/client.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/plugin.js +56 -26
- package/dist/plugin.js.map +1 -1
- package/docs/DSH.md +268 -268
- package/docs/DSH.zh-CN.md +245 -245
- package/docs/benchmarks/issue-128-windows-review.json +104 -104
- package/docs/benchmarks/issue-128-windows.json +103 -103
- package/docs/dreaming-agent.md +45 -45
- package/docs/issue-128-lease-cache-review-followup.md +55 -55
- package/docs/issue-128-review-followup.md +58 -58
- package/docs/npm-release.md +52 -52
- package/docs/validation/issue119.md +41 -41
- package/package.json +246 -246
- package/screenshots.json +8 -8
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dsh-host-resolution.ts","../src/bootstrap.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs'\r\nimport { createRequire, registerHooks } from 'node:module'\r\nimport { dirname, isAbsolute, join, relative } from 'node:path'\r\nimport { fileURLToPath, pathToFileURL } from 'node:url'\r\n\r\nconst HOST_PACKAGES = [\r\n '@deepseek-ai/cordis',\r\n '@deepseek-ai/dsh-agent-default-model',\r\n '@deepseek-ai/dsh-client-ui-conversation',\r\n '@deepseek-ai/dsh-llm',\r\n '@deepseek-ai/dsh-native-command',\r\n '@deepseek-ai/dsh-session',\r\n '@deepseek-ai/dsh-session-format',\r\n '@deepseek-ai/dsh-session-format-catalog',\r\n '@deepseek-ai/dsh-session-format-v0-to-v1',\r\n '@deepseek-ai/dsh-settings',\r\n '@deepseek-ai/dsh-system-prompt',\r\n '@deepseek-ai/dsh-tools',\r\n '@deepseek-ai/schemastery',\r\n] as const\r\n\r\nconst installedHooks = Symbol.for('stratagate.dsh-host-resolution.v1')\r\n\r\nfunction isWithin(path: string, root: string): boolean {\r\n const child = relative(root, path)\r\n return child === '' || (!child.startsWith('..') && !isAbsolute(child))\r\n}\r\n\r\nfunction profileDirectory(start: string): string | undefined {\r\n let directory = start\r\n for (;;) {\r\n const manifestPath = join(directory, 'package.json')\r\n if (existsSync(manifestPath)) {\r\n try {\r\n const manifest = JSON.parse(readFileSync(manifestPath, 'utf8')) as { dsh?: { profile?: unknown } }\r\n if (manifest.dsh?.profile && typeof manifest.dsh.profile === 'object') return directory\r\n } catch {}\r\n }\r\n const parent = dirname(directory)\r\n if (parent === directory) return undefined\r\n directory = parent\r\n }\r\n}\r\n\r\nfunction hostPackage(specifier: string): boolean {\r\n return HOST_PACKAGES.some((name) => specifier === name || specifier.startsWith(`${name}/`))\r\n}\r\n\r\n/**\r\n * Force only StrataGate's DSH imports through the installation-owned fallback\r\n * created by DSH. The hook neither deletes nor rewrites the profile's package\r\n * tree, and imports belonging to the host or other plugins are untouched.\r\n */\r\nexport function installDshHostResolution(moduleUrl: string): boolean {\r\n const packageDirectory = dirname(dirname(fileURLToPath(moduleUrl)))\r\n const profile = profileDirectory(packageDirectory)\r\n if (!profile) return false\r\n\r\n const globalState = globalThis as typeof globalThis & { [installedHooks]?: Set<string> }\r\n const installed = globalState[installedHooks] ??= new Set<string>()\r\n const key = `${profile}\\u0000${packageDirectory}`\r\n if (installed.has(key)) return true\r\n\r\n const fallbackModules = join(dirname(profile), 'node_modules')\r\n const hostRequire = createRequire(join(fallbackModules, '.stratagate-host-resolution.cjs'))\r\n registerHooks({\r\n resolve(specifier, context, nextResolve) {\r\n const parent = context.parentURL?.startsWith('file:') ? fileURLToPath(context.parentURL) : undefined\r\n if (!hostPackage(specifier) || !parent || !isWithin(parent, packageDirectory)) {\r\n return nextResolve(specifier, context)\r\n }\r\n try {\r\n return { url: pathToFileURL(hostRequire.resolve(specifier)).href, shortCircuit: true }\r\n } catch (cause) {\r\n if (specifier === '@deepseek-ai/dsh-session-format-v0-to-v1'\r\n || specifier === '@deepseek-ai/dsh-session-format-catalog') {\r\n return nextResolve(specifier, context)\r\n }\r\n throw new Error(\r\n `StrataGate cannot resolve host-provided DSH package ${JSON.stringify(specifier)} from ${fallbackModules}. `\r\n + 'Start StrataGate through the DSH profile launcher so the host can prepare its module fallback.',\r\n { cause },\r\n )\r\n }\r\n },\r\n })\r\n installed.add(key)\r\n return true\r\n}\r\n","import { installDshHostResolution } from './dsh-host-resolution.js'\
|
|
1
|
+
{"version":3,"sources":["../src/dsh-host-resolution.ts","../src/bootstrap.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs'\r\nimport { createRequire, registerHooks } from 'node:module'\r\nimport { dirname, isAbsolute, join, relative } from 'node:path'\r\nimport { fileURLToPath, pathToFileURL } from 'node:url'\r\n\r\nconst HOST_PACKAGES = [\r\n '@deepseek-ai/cordis',\r\n '@deepseek-ai/dsh-agent-default-model',\r\n '@deepseek-ai/dsh-client-ui-conversation',\r\n '@deepseek-ai/dsh-llm',\r\n '@deepseek-ai/dsh-native-command',\r\n '@deepseek-ai/dsh-session',\r\n '@deepseek-ai/dsh-session-format',\r\n '@deepseek-ai/dsh-session-format-catalog',\r\n '@deepseek-ai/dsh-session-format-v0-to-v1',\r\n '@deepseek-ai/dsh-settings',\r\n '@deepseek-ai/dsh-system-prompt',\r\n '@deepseek-ai/dsh-tools',\r\n '@deepseek-ai/schemastery',\r\n] as const\r\n\r\nconst installedHooks = Symbol.for('stratagate.dsh-host-resolution.v1')\r\n\r\nfunction isWithin(path: string, root: string): boolean {\r\n const child = relative(root, path)\r\n return child === '' || (!child.startsWith('..') && !isAbsolute(child))\r\n}\r\n\r\nfunction profileDirectory(start: string): string | undefined {\r\n let directory = start\r\n for (;;) {\r\n const manifestPath = join(directory, 'package.json')\r\n if (existsSync(manifestPath)) {\r\n try {\r\n const manifest = JSON.parse(readFileSync(manifestPath, 'utf8')) as { dsh?: { profile?: unknown } }\r\n if (manifest.dsh?.profile && typeof manifest.dsh.profile === 'object') return directory\r\n } catch {}\r\n }\r\n const parent = dirname(directory)\r\n if (parent === directory) return undefined\r\n directory = parent\r\n }\r\n}\r\n\r\nfunction hostPackage(specifier: string): boolean {\r\n return HOST_PACKAGES.some((name) => specifier === name || specifier.startsWith(`${name}/`))\r\n}\r\n\r\n/**\r\n * Force only StrataGate's DSH imports through the installation-owned fallback\r\n * created by DSH. The hook neither deletes nor rewrites the profile's package\r\n * tree, and imports belonging to the host or other plugins are untouched.\r\n */\r\nexport function installDshHostResolution(moduleUrl: string): boolean {\r\n const packageDirectory = dirname(dirname(fileURLToPath(moduleUrl)))\r\n const profile = profileDirectory(packageDirectory)\r\n if (!profile) return false\r\n\r\n const globalState = globalThis as typeof globalThis & { [installedHooks]?: Set<string> }\r\n const installed = globalState[installedHooks] ??= new Set<string>()\r\n const key = `${profile}\\u0000${packageDirectory}`\r\n if (installed.has(key)) return true\r\n\r\n const fallbackModules = join(dirname(profile), 'node_modules')\r\n const hostRequire = createRequire(join(fallbackModules, '.stratagate-host-resolution.cjs'))\r\n registerHooks({\r\n resolve(specifier, context, nextResolve) {\r\n const parent = context.parentURL?.startsWith('file:') ? fileURLToPath(context.parentURL) : undefined\r\n if (!hostPackage(specifier) || !parent || !isWithin(parent, packageDirectory)) {\r\n return nextResolve(specifier, context)\r\n }\r\n try {\r\n return { url: pathToFileURL(hostRequire.resolve(specifier)).href, shortCircuit: true }\r\n } catch (cause) {\r\n if (specifier === '@deepseek-ai/dsh-session-format-v0-to-v1'\r\n || specifier === '@deepseek-ai/dsh-session-format-catalog') {\r\n return nextResolve(specifier, context)\r\n }\r\n throw new Error(\r\n `StrataGate cannot resolve host-provided DSH package ${JSON.stringify(specifier)} from ${fallbackModules}. `\r\n + 'Start StrataGate through the DSH profile launcher so the host can prepare its module fallback.',\r\n { cause },\r\n )\r\n }\r\n },\r\n })\r\n installed.add(key)\r\n return true\r\n}\r\n","import { installDshHostResolution } from './dsh-host-resolution.js'\n\n// DSH prepares its installation-owned module fallback before it imports a\n// profile bundle. Install the narrowly-scoped resolver first, then load the\n// implementation so stale profile-local peers cannot win ESM resolution.\ninstallDshHostResolution(import.meta.url)\n\n// This file and src/index.ts are separate tsup entries. The runtime path is\n// intentionally external so the implementation is instantiated only after\n// the resolver above is active.\n// @ts-expect-error dist/plugin.js is emitted from src/index.ts during build.\nconst plugin = await import('./plugin.js') as typeof import('./index.js')\n\nexport const name = plugin.name\nexport const inject = plugin.inject\nexport const STRATAGATE_SETTINGS_NAMESPACE = plugin.STRATAGATE_SETTINGS_NAMESPACE\nexport const Config = plugin.Config\nexport const apply = plugin.apply\nexport type PluginConfig = import('./index.js').PluginConfig\n"],"mappings":";AAAA,SAAS,YAAY,oBAAoB;AACzC,SAAS,eAAe,qBAAqB;AAC7C,SAAS,SAAS,YAAY,MAAM,gBAAgB;AACpD,SAAS,eAAe,qBAAqB;AAE7C,IAAM,gBAAgB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,iBAAiB,uBAAO,IAAI,mCAAmC;AAErE,SAAS,SAAS,MAAc,MAAuB;AACrD,QAAM,QAAQ,SAAS,MAAM,IAAI;AACjC,SAAO,UAAU,MAAO,CAAC,MAAM,WAAW,IAAI,KAAK,CAAC,WAAW,KAAK;AACtE;AAEA,SAAS,iBAAiB,OAAmC;AAC3D,MAAI,YAAY;AAChB,aAAS;AACP,UAAM,eAAe,KAAK,WAAW,cAAc;AACnD,QAAI,WAAW,YAAY,GAAG;AAC5B,UAAI;AACF,cAAM,WAAW,KAAK,MAAM,aAAa,cAAc,MAAM,CAAC;AAC9D,YAAI,SAAS,KAAK,WAAW,OAAO,SAAS,IAAI,YAAY,SAAU,QAAO;AAAA,MAChF,QAAQ;AAAA,MAAC;AAAA,IACX;AACA,UAAM,SAAS,QAAQ,SAAS;AAChC,QAAI,WAAW,UAAW,QAAO;AACjC,gBAAY;AAAA,EACd;AACF;AAEA,SAAS,YAAY,WAA4B;AAC/C,SAAO,cAAc,KAAK,CAACA,UAAS,cAAcA,SAAQ,UAAU,WAAW,GAAGA,KAAI,GAAG,CAAC;AAC5F;AAOO,SAAS,yBAAyB,WAA4B;AACnE,QAAM,mBAAmB,QAAQ,QAAQ,cAAc,SAAS,CAAC,CAAC;AAClE,QAAM,UAAU,iBAAiB,gBAAgB;AACjD,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,cAAc;AACpB,QAAM,YAAY,YAAY,cAAc,MAAM,oBAAI,IAAY;AAClE,QAAM,MAAM,GAAG,OAAO,KAAS,gBAAgB;AAC/C,MAAI,UAAU,IAAI,GAAG,EAAG,QAAO;AAE/B,QAAM,kBAAkB,KAAK,QAAQ,OAAO,GAAG,cAAc;AAC7D,QAAM,cAAc,cAAc,KAAK,iBAAiB,iCAAiC,CAAC;AAC1F,gBAAc;AAAA,IACZ,QAAQ,WAAW,SAAS,aAAa;AACvC,YAAM,SAAS,QAAQ,WAAW,WAAW,OAAO,IAAI,cAAc,QAAQ,SAAS,IAAI;AAC3F,UAAI,CAAC,YAAY,SAAS,KAAK,CAAC,UAAU,CAAC,SAAS,QAAQ,gBAAgB,GAAG;AAC7E,eAAO,YAAY,WAAW,OAAO;AAAA,MACvC;AACA,UAAI;AACF,eAAO,EAAE,KAAK,cAAc,YAAY,QAAQ,SAAS,CAAC,EAAE,MAAM,cAAc,KAAK;AAAA,MACvF,SAAS,OAAO;AACd,YAAI,cAAc,8CACb,cAAc,2CAA2C;AAC5D,iBAAO,YAAY,WAAW,OAAO;AAAA,QACvC;AACA,cAAM,IAAI;AAAA,UACR,uDAAuD,KAAK,UAAU,SAAS,CAAC,SAAS,eAAe;AAAA,UAExG,EAAE,MAAM;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACD,YAAU,IAAI,GAAG;AACjB,SAAO;AACT;;;ACnFA,yBAAyB,YAAY,GAAG;AAMxC,IAAM,SAAS,MAAM,OAAO,aAAa;AAElC,IAAM,OAAO,OAAO;AACpB,IAAM,SAAS,OAAO;AACtB,IAAM,gCAAgC,OAAO;AAC7C,IAAM,SAAS,OAAO;AACtB,IAAM,QAAQ,OAAO;","names":["name"]}
|
package/dist/plugin.js
CHANGED
|
@@ -5501,6 +5501,7 @@ function agentEventCandidate(content, category, now, threadId) {
|
|
|
5501
5501
|
};
|
|
5502
5502
|
}
|
|
5503
5503
|
var DERIVATION_BACKOFF_MS = 1e3;
|
|
5504
|
+
var GRAPH_PROJECTION_BATCH_SIZE = 8;
|
|
5504
5505
|
function restrictExtractionRelations(temporal, allowedIds) {
|
|
5505
5506
|
const result = { ...temporal };
|
|
5506
5507
|
if (typeof result.sameEventId !== "string" || !allowedIds.has(result.sameEventId)) {
|
|
@@ -6669,6 +6670,18 @@ var StrataGate = class _StrataGate {
|
|
|
6669
6670
|
return this.commitMutation(() => {
|
|
6670
6671
|
const job = [...this.graphProjectionJobs.values()].filter(eligible).sort((left, right) => Number(left.status !== "pending") - Number(right.status !== "pending") || right.priority - left.priority || left.createdAt.localeCompare(right.createdAt))[0];
|
|
6671
6672
|
if (!job) return null;
|
|
6673
|
+
const sourceEventIds = job.sourceEventIds;
|
|
6674
|
+
for (let index = GRAPH_PROJECTION_BATCH_SIZE; index < sourceEventIds.length; index += GRAPH_PROJECTION_BATCH_SIZE) {
|
|
6675
|
+
const id = this.graphIdFactory("gproj");
|
|
6676
|
+
this.graphProjectionJobs.set(id, {
|
|
6677
|
+
...job,
|
|
6678
|
+
id,
|
|
6679
|
+
sourceEventIds: sourceEventIds.slice(index, index + GRAPH_PROJECTION_BATCH_SIZE),
|
|
6680
|
+
nodeIds: [],
|
|
6681
|
+
edgeIds: []
|
|
6682
|
+
});
|
|
6683
|
+
}
|
|
6684
|
+
job.sourceEventIds = sourceEventIds.slice(0, GRAPH_PROJECTION_BATCH_SIZE);
|
|
6672
6685
|
const events = job.sourceEventIds.flatMap((id) => {
|
|
6673
6686
|
const event = this.findEvent(id);
|
|
6674
6687
|
return event ? [event] : [];
|
|
@@ -7554,30 +7567,30 @@ var StrataGate = class _StrataGate {
|
|
|
7554
7567
|
return job;
|
|
7555
7568
|
}
|
|
7556
7569
|
queueGraphProjection(sourceEventIds, priority) {
|
|
7557
|
-
if (!this.graphProjector) return
|
|
7558
|
-
const completed = new Set([...this.graphProjectionJobs.values()].filter((
|
|
7559
|
-
const queued = new Set([...this.graphProjectionJobs.values()].filter((
|
|
7570
|
+
if (!this.graphProjector) return;
|
|
7571
|
+
const completed = new Set([...this.graphProjectionJobs.values()].filter((job) => job.projectorVersion === KNOWLEDGE_GRAPH_PROJECTOR_VERSION && job.status === "completed").flatMap((job) => job.sourceEventIds));
|
|
7572
|
+
const queued = new Set([...this.graphProjectionJobs.values()].filter((job) => job.projectorVersion === KNOWLEDGE_GRAPH_PROJECTOR_VERSION && job.status !== "completed").flatMap((job) => job.sourceEventIds));
|
|
7560
7573
|
const ids2 = [...new Set(sourceEventIds.filter((id) => this.findEvent(id) && !completed.has(id) && !queued.has(id)))];
|
|
7561
|
-
if (ids2.length === 0) return null;
|
|
7562
7574
|
const now = toUtc8Iso(this.now());
|
|
7563
|
-
|
|
7564
|
-
|
|
7565
|
-
|
|
7566
|
-
|
|
7567
|
-
|
|
7568
|
-
|
|
7569
|
-
|
|
7570
|
-
|
|
7571
|
-
|
|
7572
|
-
|
|
7573
|
-
|
|
7574
|
-
|
|
7575
|
-
|
|
7576
|
-
|
|
7577
|
-
|
|
7578
|
-
|
|
7579
|
-
|
|
7580
|
-
|
|
7575
|
+
for (let index = 0; index < ids2.length; index += GRAPH_PROJECTION_BATCH_SIZE) {
|
|
7576
|
+
const job = {
|
|
7577
|
+
id: this.graphIdFactory("gproj"),
|
|
7578
|
+
sourceEventIds: ids2.slice(index, index + GRAPH_PROJECTION_BATCH_SIZE),
|
|
7579
|
+
projectorVersion: KNOWLEDGE_GRAPH_PROJECTOR_VERSION,
|
|
7580
|
+
status: "pending",
|
|
7581
|
+
attempts: 0,
|
|
7582
|
+
priority,
|
|
7583
|
+
nodeIds: [],
|
|
7584
|
+
edgeIds: [],
|
|
7585
|
+
nameProvenanceRecoveryVersion: 1,
|
|
7586
|
+
reason: null,
|
|
7587
|
+
lastError: null,
|
|
7588
|
+
nextRetryAt: null,
|
|
7589
|
+
createdAt: now,
|
|
7590
|
+
updatedAt: now
|
|
7591
|
+
};
|
|
7592
|
+
this.graphProjectionJobs.set(job.id, job);
|
|
7593
|
+
}
|
|
7581
7594
|
}
|
|
7582
7595
|
recoverGraphNameProvenanceFailures() {
|
|
7583
7596
|
for (const job of this.graphProjectionJobs.values()) {
|
|
@@ -7595,8 +7608,8 @@ var StrataGate = class _StrataGate {
|
|
|
7595
7608
|
const score = (event) => (event.status === "active" ? 1e4 : 0) + event.weight.mentionCount * 100 + (event.scope === "project" ? 500 : 0) + (Date.parse(event.temporal.happenedStart ?? event.temporal.mentionedAt ?? event.updatedAt) || 0) / 1e12;
|
|
7596
7609
|
return score(right) - score(left);
|
|
7597
7610
|
});
|
|
7598
|
-
for (let index = 0; index < candidates.length; index +=
|
|
7599
|
-
this.queueGraphProjection(candidates.slice(index, index +
|
|
7611
|
+
for (let index = 0; index < candidates.length; index += GRAPH_PROJECTION_BATCH_SIZE) {
|
|
7612
|
+
this.queueGraphProjection(candidates.slice(index, index + GRAPH_PROJECTION_BATCH_SIZE).map(({ id }) => id), candidates.length - index);
|
|
7600
7613
|
}
|
|
7601
7614
|
}
|
|
7602
7615
|
queueElementProjection(sourceEventIds) {
|
|
@@ -9056,6 +9069,7 @@ function parseTopicProjection(value, context) {
|
|
|
9056
9069
|
return { topics };
|
|
9057
9070
|
}
|
|
9058
9071
|
var TOPIC_OUTPUT_TOKEN_BUDGET = 32768;
|
|
9072
|
+
var GRAPH_OUTPUT_TOKEN_BUDGET = 32768;
|
|
9059
9073
|
var DshModelBridge = class {
|
|
9060
9074
|
constructor(ctx, config, liveStructuredReasoningEffort) {
|
|
9061
9075
|
this.ctx = ctx;
|
|
@@ -9391,6 +9405,7 @@ Use project scope for repository decisions, user scope for stable preferences/id
|
|
|
9391
9405
|
const routeKey = `${baseRoute.provider}\0${baseRoute.model}`;
|
|
9392
9406
|
let useOff = await this.shouldUseOff(baseRoute);
|
|
9393
9407
|
const isTopic = kind === "topicProjector";
|
|
9408
|
+
const isGraph = kind === "graphProjector";
|
|
9394
9409
|
const topicDiagnostics = {
|
|
9395
9410
|
...topicMetadata,
|
|
9396
9411
|
requestedOutputTokens: TOPIC_OUTPUT_TOKEN_BUDGET,
|
|
@@ -9417,7 +9432,7 @@ Use project scope for repository decisions, user scope for stable preferences/id
|
|
|
9417
9432
|
}
|
|
9418
9433
|
}
|
|
9419
9434
|
const message = createUserMessage({
|
|
9420
|
-
content: [{ type: "text", text: JSON.stringify(payload) }],
|
|
9435
|
+
content: [{ type: "text", text: JSON.stringify(isGraph ? { ...object(payload), outputTokenBudget: GRAPH_OUTPUT_TOKEN_BUDGET } : payload) }],
|
|
9421
9436
|
source: dshMessageSource()
|
|
9422
9437
|
});
|
|
9423
9438
|
const assembler = new BlockAssembler();
|
|
@@ -9437,7 +9452,7 @@ ${JSON_RETRY_INSTRUCTION}${graphRetryFeedback}${topicRetryFeedback}`,
|
|
|
9437
9452
|
type: "function",
|
|
9438
9453
|
function: { name: STRUCTURED_TOOLS[kind].name }
|
|
9439
9454
|
},
|
|
9440
|
-
maxTokens: kind === "dreamingStep" ? TOPIC_OUTPUT_TOKEN_BUDGET : kind === "profileMaintenance" ? Math.max(this.config.maxOutputTokens, Math.min(12e3, 512 + 2 * Array.from(JSON.stringify(payload)).length)) : isTopic ? TOPIC_OUTPUT_TOKEN_BUDGET : this.config.maxOutputTokens,
|
|
9455
|
+
maxTokens: kind === "dreamingStep" ? TOPIC_OUTPUT_TOKEN_BUDGET : kind === "profileMaintenance" ? Math.max(this.config.maxOutputTokens, Math.min(12e3, 512 + 2 * Array.from(JSON.stringify(payload)).length)) : isTopic ? TOPIC_OUTPUT_TOKEN_BUDGET : isGraph ? GRAPH_OUTPUT_TOKEN_BUDGET : this.config.maxOutputTokens,
|
|
9441
9456
|
sessionId: execution.sessionId,
|
|
9442
9457
|
purpose: "compaction"
|
|
9443
9458
|
};
|
|
@@ -9449,6 +9464,18 @@ ${JSON_RETRY_INSTRUCTION}${graphRetryFeedback}${topicRetryFeedback}`,
|
|
|
9449
9464
|
request.maxTokens = Math.min(TOPIC_OUTPUT_TOKEN_BUDGET, Math.floor(window - input - 1024));
|
|
9450
9465
|
}
|
|
9451
9466
|
}
|
|
9467
|
+
if (isGraph) {
|
|
9468
|
+
const input = estimateTokens(JSON.stringify({ system: request.system, tools: request.tools, messages: request.messages }));
|
|
9469
|
+
const window = this.contextWindows.get(routeKey);
|
|
9470
|
+
if (window !== void 0) {
|
|
9471
|
+
if (window - input - 1024 < 256) throw new Error("Graph input exceeds model context capacity; reduce the source batch");
|
|
9472
|
+
request.maxTokens = Math.min(GRAPH_OUTPUT_TOKEN_BUDGET, Math.floor(window - input - 1024));
|
|
9473
|
+
}
|
|
9474
|
+
request.messages = [{ ...message, content: [{ type: "text", text: JSON.stringify({
|
|
9475
|
+
...object(payload),
|
|
9476
|
+
outputTokenBudget: request.maxTokens
|
|
9477
|
+
}) }] }];
|
|
9478
|
+
}
|
|
9452
9479
|
if (isTopic) {
|
|
9453
9480
|
const estimateInput = () => estimateTokens(JSON.stringify({ system: request.system, tools: request.tools, messages: request.messages }));
|
|
9454
9481
|
let inputTokens = estimateInput();
|
|
@@ -9526,6 +9553,9 @@ ${JSON_RETRY_INSTRUCTION}${graphRetryFeedback}${topicRetryFeedback}`,
|
|
|
9526
9553
|
[finish=${finish.kind}; toolCalls=${calls.length}]`;
|
|
9527
9554
|
lastResponse = responseForError;
|
|
9528
9555
|
try {
|
|
9556
|
+
if (isGraph && finish.kind === "max-tokens") {
|
|
9557
|
+
throw new ModelJsonResponseError("StrataGate Graph output token limit reached", { response: responseForError });
|
|
9558
|
+
}
|
|
9529
9559
|
const expectedTool = STRUCTURED_TOOLS[kind].name;
|
|
9530
9560
|
let parsed;
|
|
9531
9561
|
if (calls.length !== 1 || calls[0]?.name !== expectedTool) {
|