@gt-fe/eap-runtime 0.0.21 → 0.0.23
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/README.md +1 -1
- package/dist/api/handlers/invoke.handler.js +6 -3
- package/dist/api/handlers/stream.handler.js +6 -2
- package/dist/checkpoint/file-checkpoint-saver.d.ts +4 -0
- package/dist/checkpoint/file-checkpoint-saver.js +51 -22
- package/dist/checkpoint/index.d.ts +1 -1
- package/dist/checkpoint/index.js +1 -1
- package/dist/graph/adapters/langgraph-checkpointer.d.ts +11 -0
- package/dist/graph/adapters/langgraph-checkpointer.js +48 -9
- package/dist/graph/adapters/langgraph.adapter.d.ts +8 -0
- package/dist/graph/adapters/langgraph.adapter.js +58 -16
- package/dist/graph/adapters/skill-isolate.d.ts +1 -5
- package/dist/graph/adapters/skill-isolate.js +1 -12
- package/dist/graph/adapters/subgraph-compiler.js +12 -15
- package/dist/graph/contracts/executable-graph.d.ts +6 -0
- package/dist/graph/hitl/hitl-handler.d.ts +13 -4
- package/dist/graph/hitl/hitl-handler.js +78 -7
- package/dist/graph/nodes/tool-node.js +11 -6
- package/dist/providers/index.d.ts +1 -1
- package/dist/providers/index.js +1 -1
- package/dist/providers/local-llm-provider.d.ts +6 -0
- package/dist/providers/local-llm-provider.js +29 -5
- package/dist/providers/routing-llm-provider.d.ts +2 -2
- package/dist/providers/routing-llm-provider.js +5 -15
- package/dist/registry/deployment-snapshot.js +18 -4
- package/dist/registry/graph-loader.d.ts +2 -0
- package/dist/registry/graph-loader.js +99 -7
- package/dist/registry/preload-flags.d.ts +1 -1
- package/dist/registry/preload-flags.js +1 -1
- package/dist/runtime/agent-runtime.js +27 -10
- package/dist/runtime/dev-runtime.d.ts +2 -1
- package/dist/runtime/dev-runtime.js +9 -3
- package/dist/session/apply-session-compression.d.ts +4 -0
- package/dist/session/apply-session-compression.js +22 -3
- package/dist/session/index.d.ts +1 -1
- package/dist/session/index.js +1 -1
- package/dist/session/persist-turn-messages.d.ts +6 -1
- package/dist/session/persist-turn-messages.js +23 -5
- package/dist/token/record-task-token-usage.d.ts +23 -0
- package/dist/token/record-task-token-usage.js +20 -0
- package/dist/tool/http-tool-executor.js +7 -3
- package/dist/tool/index.d.ts +2 -1
- package/dist/tool/index.js +2 -1
- package/dist/tool/loaded-tool-definition.d.ts +1 -1
- package/dist/tool/local-mcp-client.d.ts +1 -1
- package/dist/tool/local-mcp-client.js +2 -39
- package/dist/tool/local-tool-executor.js +32 -5
- package/dist/tool/mcp-list.d.ts +21 -0
- package/dist/tool/mcp-list.js +49 -3
- package/dist/tool/mcp-tool-executor.d.ts +1 -1
- package/dist/tool/mcp-tool-executor.js +58 -22
- package/dist/tool/model-visible-tool-content.d.ts +16 -0
- package/dist/tool/model-visible-tool-content.js +266 -0
- package/dist/tool/timeout.d.ts +5 -12
- package/dist/tool/timeout.js +12 -34
- package/dist/tool/tool-confirmation.js +8 -5
- package/dist/tool/tool-executor.interface.d.ts +7 -1
- package/dist/tool/tool-orchestrator.js +6 -1
- package/dist/tool/tool-result-injector.js +2 -1
- package/package.json +2 -2
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* 生产(server + EAP_PREINSTALL_ROOT):以预装为准,缺失则失败(04 Req 8.1)。
|
|
5
5
|
* 开发态:Registry + 可选 ./tools 本地 manifest。
|
|
6
6
|
*/
|
|
7
|
-
import { readFile } from 'node:fs/promises';
|
|
7
|
+
import { readdir, readFile } from 'node:fs/promises';
|
|
8
8
|
import path from 'node:path';
|
|
9
9
|
import { resolveAgentModelAllowlist, resolveAgentDefaultModel } from './agent-models.js';
|
|
10
10
|
import { DEFAULT_HTTP_TOOL_TIMEOUT_SEC, DEFAULT_TOOL_TIMEOUT_SEC } from '../tool/timeout.js';
|
|
@@ -144,6 +144,26 @@ const DEFAULT_GRAPH_DSL = {
|
|
|
144
144
|
finishPoints: ['__end__'],
|
|
145
145
|
config: { timeout: 60000 },
|
|
146
146
|
};
|
|
147
|
+
/** 源图有非空字符串则保留;缺省或空数组为 `['__end__']`。预装 graph.json 与清单内嵌图同一收口。 */
|
|
148
|
+
function finishPointsFromGraphDocument(graph) {
|
|
149
|
+
const raw = graph.finishPoints;
|
|
150
|
+
if (!Array.isArray(raw))
|
|
151
|
+
return ['__end__'];
|
|
152
|
+
const ids = raw
|
|
153
|
+
.filter((id) => typeof id === 'string')
|
|
154
|
+
.map((id) => id.trim())
|
|
155
|
+
.filter((id) => id.length > 0);
|
|
156
|
+
return ids.length > 0 ? ids : ['__end__'];
|
|
157
|
+
}
|
|
158
|
+
const DEFAULT_LOADED_GRAPH_CONFIG = { timeout: 60000 };
|
|
159
|
+
/** 默认 timeout 60000;源图 `config` 覆盖。缺 `maxIterations` 时由引擎用 50。 */
|
|
160
|
+
function configFromGraphDocument(graph) {
|
|
161
|
+
const raw = graph.config;
|
|
162
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
163
|
+
return { ...DEFAULT_LOADED_GRAPH_CONFIG };
|
|
164
|
+
}
|
|
165
|
+
return { ...DEFAULT_LOADED_GRAPH_CONFIG, ...raw };
|
|
166
|
+
}
|
|
147
167
|
function yamlGraphToDsl(agentCode, graph) {
|
|
148
168
|
const nodes = graph.nodes ?? [];
|
|
149
169
|
const edges = graph.edges ?? [];
|
|
@@ -155,8 +175,8 @@ function yamlGraphToDsl(agentCode, graph) {
|
|
|
155
175
|
edges,
|
|
156
176
|
conditionalEdges: graph.conditionalEdges,
|
|
157
177
|
entryPoint: graph.entryPoint ?? nodes[0]?.id ?? 'llm',
|
|
158
|
-
finishPoints:
|
|
159
|
-
config:
|
|
178
|
+
finishPoints: finishPointsFromGraphDocument(graph),
|
|
179
|
+
config: configFromGraphDocument(graph),
|
|
160
180
|
};
|
|
161
181
|
}
|
|
162
182
|
function collectToolNames(agent, graphDsl) {
|
|
@@ -443,16 +463,71 @@ function fromInlineToolDeclaration(tool) {
|
|
|
443
463
|
inputSchema: tool.input,
|
|
444
464
|
};
|
|
445
465
|
}
|
|
466
|
+
const DEV_LOCAL_MANIFEST_FILES = [
|
|
467
|
+
'toolset.manifest.json',
|
|
468
|
+
'tool.manifest.json',
|
|
469
|
+
'manifest.json',
|
|
470
|
+
];
|
|
471
|
+
async function readJsonObject(filePath) {
|
|
472
|
+
try {
|
|
473
|
+
const raw = await readFile(filePath, 'utf-8');
|
|
474
|
+
const parsed = JSON.parse(raw);
|
|
475
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
476
|
+
return null;
|
|
477
|
+
return parsed;
|
|
478
|
+
}
|
|
479
|
+
catch {
|
|
480
|
+
return null;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
function loadedToolFromDevDir(dir, toolName, doc, toolsetOnly) {
|
|
484
|
+
const tools = doc.tools;
|
|
485
|
+
if (Array.isArray(tools) && tools.length > 0 && typeof tools[0] === 'object') {
|
|
486
|
+
const pre = {
|
|
487
|
+
toolId: String(doc.code ?? path.basename(dir)),
|
|
488
|
+
name: String(doc.name ?? path.basename(dir)),
|
|
489
|
+
version: String(doc.version ?? '0.0.0'),
|
|
490
|
+
manifest: doc,
|
|
491
|
+
bundlePath: dir,
|
|
492
|
+
};
|
|
493
|
+
const expanded = expandPreinstallToolset(pre);
|
|
494
|
+
return expanded.find((d) => d.name === toolName) ?? null;
|
|
495
|
+
}
|
|
496
|
+
if (toolsetOnly)
|
|
497
|
+
return null;
|
|
498
|
+
return fromLocalManifestFile(toolName, doc);
|
|
499
|
+
}
|
|
500
|
+
async function loadDevLocalManifestFromDir(dir, toolName, toolsetOnly) {
|
|
501
|
+
const files = toolsetOnly ? ['toolset.manifest.json'] : DEV_LOCAL_MANIFEST_FILES;
|
|
502
|
+
for (const file of files) {
|
|
503
|
+
const doc = await readJsonObject(path.join(dir, file));
|
|
504
|
+
if (!doc)
|
|
505
|
+
continue;
|
|
506
|
+
const hit = loadedToolFromDevDir(dir, toolName, doc, toolsetOnly);
|
|
507
|
+
if (hit)
|
|
508
|
+
return hit;
|
|
509
|
+
}
|
|
510
|
+
return null;
|
|
511
|
+
}
|
|
446
512
|
async function loadDevLocalManifest(toolName, toolsDir) {
|
|
447
|
-
const
|
|
513
|
+
const direct = await loadDevLocalManifestFromDir(path.join(toolsDir, toolName), toolName, false);
|
|
514
|
+
if (direct)
|
|
515
|
+
return direct;
|
|
516
|
+
let entries;
|
|
448
517
|
try {
|
|
449
|
-
|
|
450
|
-
const manifest = JSON.parse(raw);
|
|
451
|
-
return fromLocalManifestFile(toolName, manifest);
|
|
518
|
+
entries = await readdir(toolsDir, { withFileTypes: true });
|
|
452
519
|
}
|
|
453
520
|
catch {
|
|
454
521
|
return null;
|
|
455
522
|
}
|
|
523
|
+
for (const ent of entries) {
|
|
524
|
+
if (!ent.isDirectory() || ent.name === toolName)
|
|
525
|
+
continue;
|
|
526
|
+
const hit = await loadDevLocalManifestFromDir(path.join(toolsDir, ent.name), toolName, true);
|
|
527
|
+
if (hit)
|
|
528
|
+
return hit;
|
|
529
|
+
}
|
|
530
|
+
return null;
|
|
456
531
|
}
|
|
457
532
|
function fromLocalInstall(install) {
|
|
458
533
|
return {
|
|
@@ -620,6 +695,23 @@ export class GraphLoader {
|
|
|
620
695
|
}
|
|
621
696
|
return this.cloneCached(graph);
|
|
622
697
|
}
|
|
698
|
+
/** Agent `models.default`;无清单或未声明则 undefined。 */
|
|
699
|
+
async resolveDefaultModel(agentCode, version) {
|
|
700
|
+
const requested = this.resolveVersion({ agentVersion: version });
|
|
701
|
+
if (this.deploymentSnapshot) {
|
|
702
|
+
try {
|
|
703
|
+
const snap = await this.deploymentSnapshot.loadAgentSnapshot(agentCode, requested);
|
|
704
|
+
const model = resolveAgentDefaultModel((snap?.manifest ?? {}));
|
|
705
|
+
const trimmed = model?.trim();
|
|
706
|
+
if (trimmed && trimmed.toLowerCase() !== 'default')
|
|
707
|
+
return trimmed;
|
|
708
|
+
}
|
|
709
|
+
catch {
|
|
710
|
+
return undefined;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
return undefined;
|
|
714
|
+
}
|
|
623
715
|
async loadGraphFromSource(agentCode, version) {
|
|
624
716
|
if (this.deploymentSnapshot) {
|
|
625
717
|
const snap = await this.deploymentSnapshot.loadAgentSnapshot(agentCode, version);
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* |------|------|------|
|
|
6
6
|
* | EAP_PRELOAD_REQUIRE_READY | 关 | 强制校验 .ready |
|
|
7
7
|
* | EAP_PRELOAD_VALIDATE_SKILL_IO | **开** | 执行子图前校验 skill inputDef.required;`0`/`false` 关闭 |
|
|
8
|
-
* | EAP_PRELOAD_REQUIRE_CHECKSUM | 关 | snapshot 必须带 sha256 或 artifacts[]
|
|
8
|
+
* | EAP_PRELOAD_REQUIRE_CHECKSUM | 关 | snapshot 必须带 sha256 或 artifacts[]。开启时摘要不匹配抛 RUNTIME_PRELOAD_PACKAGE_CORRUPT;未开仍 warn |
|
|
9
9
|
* | EAP_PRELOAD_DEFINITION_CACHE | 有预装时开 | 进程内定义缓存;`0`/`false` 关闭 |
|
|
10
10
|
* | EAP_SKILL_HOT_RELOAD | **dev 开 / server 关** | 已装配 Skill 的目录 mtime 变化则丢缓存;未写入装配名单的目录不进清单 |
|
|
11
11
|
* | EAP_LOCAL_SKILLS_DIR | 关 | 开发态作者源 Skill 根;查找优先于 preinstall,低于 users/ |
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* |------|------|------|
|
|
6
6
|
* | EAP_PRELOAD_REQUIRE_READY | 关 | 强制校验 .ready |
|
|
7
7
|
* | EAP_PRELOAD_VALIDATE_SKILL_IO | **开** | 执行子图前校验 skill inputDef.required;`0`/`false` 关闭 |
|
|
8
|
-
* | EAP_PRELOAD_REQUIRE_CHECKSUM | 关 | snapshot 必须带 sha256 或 artifacts[]
|
|
8
|
+
* | EAP_PRELOAD_REQUIRE_CHECKSUM | 关 | snapshot 必须带 sha256 或 artifacts[]。开启时摘要不匹配抛 RUNTIME_PRELOAD_PACKAGE_CORRUPT;未开仍 warn |
|
|
9
9
|
* | EAP_PRELOAD_DEFINITION_CACHE | 有预装时开 | 进程内定义缓存;`0`/`false` 关闭 |
|
|
10
10
|
* | EAP_SKILL_HOT_RELOAD | **dev 开 / server 关** | 已装配 Skill 的目录 mtime 变化则丢缓存;未写入装配名单的目录不进清单 |
|
|
11
11
|
* | EAP_LOCAL_SKILLS_DIR | 关 | 开发态作者源 Skill 根;查找优先于 preinstall,低于 users/ |
|
|
@@ -7,20 +7,20 @@
|
|
|
7
7
|
* @see 04-runtime-core/design.md §1.5 / §1.7
|
|
8
8
|
*/
|
|
9
9
|
import { randomUUID } from 'node:crypto';
|
|
10
|
-
import { HITL_TIMEOUT_ERROR_CODE, HITL_TIMEOUT_MESSAGE, HitlAlreadyTimedOutError, HitlNotWaitingError, buildHitlWaitedPayload, isHitlDeadlinePassed, readPersistedHitlWaiting, unwrapHitlPaused, } from '../graph/hitl/hitl-handler.js';
|
|
10
|
+
import { HITL_TIMEOUT_ERROR_CODE, HITL_TIMEOUT_MESSAGE, HitlAlreadyTimedOutError, HitlNotWaitingError, buildHitlWaitedPayload, isHitlDeadlinePassed, loadHitlCheckpoint, readPersistedHitlWaiting, unwrapHitlPaused, } from '../graph/hitl/hitl-handler.js';
|
|
11
11
|
import { resolveAgentSystemPromptFromLoader } from '../registry/graph-loader.js';
|
|
12
12
|
import { toLoadedSkillMap } from '../tool/system-prompt-builder.js';
|
|
13
13
|
import { assembleLoadedTools } from '../tool/harness-primitives.js';
|
|
14
14
|
import { createFileLlmTurnLogFromEnv, } from '../debug/llm-turn-log.js';
|
|
15
15
|
import { buildHitlWaitingTaskOutput, buildTurnGraphMessages, buildTurnTranscriptFromStreamEvents, extractHitlThreadId, extractStreamReasoning, applyStreamTextDelta, createStreamAssistantBuckets, visibleStreamAssistantText, streamAssistantTexts, messageRecordsToGraphMessages, persistHitlWaitingPlaceholder, persistTurnTranscript, persistUserTurnMessage, resolveCheckpointThreadId, appendTerminalToolResult, } from '../session/persist-turn-messages.js';
|
|
16
|
-
import { iterSessionCompression, } from '../session/apply-session-compression.js';
|
|
16
|
+
import { iterSessionCompression, withCompressionSummaryModel, } from '../session/apply-session-compression.js';
|
|
17
17
|
import { applySessionMemory } from '../session/apply-session-memory.js';
|
|
18
18
|
import { resolveTokenDetail, shouldEmitTokenSse } from '../token/token-detail.js';
|
|
19
19
|
import { AppError, ErrorCodes } from '@gt-fe/eap-contracts';
|
|
20
20
|
import { resolveExecutionContext } from '../governance/governance-client.js';
|
|
21
21
|
import { resolveAgentCode } from '../common/agent-code.js';
|
|
22
22
|
import { resolveTraceId } from '../common/trace-id.js';
|
|
23
|
-
import { collectStreamNodeTokenUsage, recordTaskTokenUsages, tokenUsagesFromLlmChannel, } from '../token/record-task-token-usage.js';
|
|
23
|
+
import { collectStreamNodeTokenUsage, recordTaskTokenUsages, summarizeTokenUsages, tokenUsagesFromLlmChannel, } from '../token/record-task-token-usage.js';
|
|
24
24
|
import { resolveSkillInputFromInvokeInput } from '../registry/skill-io-guard.js';
|
|
25
25
|
const HITL_TERMINAL_STATUSES = [
|
|
26
26
|
'success',
|
|
@@ -280,15 +280,18 @@ export class AgentRuntime {
|
|
|
280
280
|
: undefined;
|
|
281
281
|
const agentSystemPrompt = await resolveAgentSystemPromptFromLoader(this.deps.graphLoader, agentCode, params.agentVersion);
|
|
282
282
|
let history = messageRecordsToGraphMessages(sessionContext.messages);
|
|
283
|
+
const compressionOptions = await withCompressionSummaryModel({
|
|
284
|
+
...this.deps.sessionCompression,
|
|
285
|
+
turnLog: this.deps.sessionCompression?.turnLog ?? this.deps.turnLog,
|
|
286
|
+
}, () => this.deps.graphLoader
|
|
287
|
+
? this.deps.graphLoader.resolveDefaultModel(agentCode, params.agentVersion)
|
|
288
|
+
: Promise.resolve(undefined));
|
|
283
289
|
for await (const step of iterSessionCompression({
|
|
284
290
|
history,
|
|
285
291
|
sessionId,
|
|
286
292
|
userId,
|
|
287
293
|
taskId: task.id,
|
|
288
|
-
options:
|
|
289
|
-
...this.deps.sessionCompression,
|
|
290
|
-
turnLog: this.deps.sessionCompression?.turnLog ?? this.deps.turnLog,
|
|
291
|
-
},
|
|
294
|
+
options: compressionOptions,
|
|
292
295
|
})) {
|
|
293
296
|
if (step.kind === 'history') {
|
|
294
297
|
history = step.messages;
|
|
@@ -367,6 +370,7 @@ export class AgentRuntime {
|
|
|
367
370
|
}
|
|
368
371
|
await recordTaskTokenUsages(this.deps.taskService, task.id, nodeTokenUsages);
|
|
369
372
|
await this.deps.taskService.updateStatus(task.id, 'success');
|
|
373
|
+
const tokenSummary = summarizeTokenUsages(nodeTokenUsages);
|
|
370
374
|
await persistTurnTranscript(this.deps.messageService, {
|
|
371
375
|
sessionId,
|
|
372
376
|
taskId: task.id,
|
|
@@ -380,7 +384,12 @@ export class AgentRuntime {
|
|
|
380
384
|
toolCallReasoningContent,
|
|
381
385
|
assistantReasoningContent,
|
|
382
386
|
}),
|
|
387
|
+
assistantTokenCount: tokenSummary.total.output,
|
|
388
|
+
assistantDurationMs: Date.now() - startTime,
|
|
383
389
|
});
|
|
390
|
+
if (shouldEmitTokenSse(tokenDetail, 'stats.token_usage')) {
|
|
391
|
+
yield this.toSSE('stats.token_usage', correlationId, task.id, tokenSummary);
|
|
392
|
+
}
|
|
384
393
|
yield this.toSSE('task.completed', correlationId, task.id, {
|
|
385
394
|
taskId: task.id,
|
|
386
395
|
duration: Date.now() - startTime,
|
|
@@ -559,6 +568,7 @@ export class AgentRuntime {
|
|
|
559
568
|
}
|
|
560
569
|
await recordTaskTokenUsages(this.deps.taskService, taskId, nodeTokenUsages);
|
|
561
570
|
await this.deps.taskService.updateStatus(taskId, 'success', visibleStreamAssistantText(assistantBuckets) || undefined);
|
|
571
|
+
const tokenSummary = summarizeTokenUsages(nodeTokenUsages);
|
|
562
572
|
if (sessionId) {
|
|
563
573
|
await persistTurnTranscript(this.deps.messageService, {
|
|
564
574
|
sessionId,
|
|
@@ -573,8 +583,13 @@ export class AgentRuntime {
|
|
|
573
583
|
toolCallReasoningContent,
|
|
574
584
|
assistantReasoningContent,
|
|
575
585
|
}),
|
|
586
|
+
assistantTokenCount: tokenSummary.total.output,
|
|
587
|
+
assistantDurationMs: Date.now() - startTime,
|
|
576
588
|
});
|
|
577
589
|
}
|
|
590
|
+
if (shouldEmitTokenSse(tokenDetail, 'stats.token_usage')) {
|
|
591
|
+
yield this.toSSE('stats.token_usage', correlationId, taskId, tokenSummary);
|
|
592
|
+
}
|
|
578
593
|
yield this.toSSE('task.completed', correlationId, taskId, {
|
|
579
594
|
taskId,
|
|
580
595
|
duration: Date.now() - startTime,
|
|
@@ -778,16 +793,18 @@ export class AgentRuntime {
|
|
|
778
793
|
const sessionId = typeof task.sessionId === 'string' && task.sessionId.trim()
|
|
779
794
|
? task.sessionId.trim()
|
|
780
795
|
: undefined;
|
|
781
|
-
const
|
|
796
|
+
const hinted = waiting?.threadId ??
|
|
782
797
|
(typeof response.threadId === 'string' && response.threadId.trim()
|
|
783
798
|
? response.threadId.trim()
|
|
784
799
|
: undefined) ??
|
|
785
800
|
extractHitlThreadId(task.output) ??
|
|
786
801
|
sessionId;
|
|
787
|
-
if (!
|
|
802
|
+
if (!hinted) {
|
|
788
803
|
throw new AppError(ErrorCodes.TASK_HITL_INVALID_STATE, `Task ${taskId} 缺少 sessionId/hitlThreadId,无法冷恢复 HITL Checkpoint`, { exposeMessage: true });
|
|
789
804
|
}
|
|
790
|
-
const
|
|
805
|
+
const resolved = await loadHitlCheckpoint(this.deps.checkpointSaver, hinted);
|
|
806
|
+
const threadId = resolved.threadId;
|
|
807
|
+
const checkpoint = resolved.checkpoint;
|
|
791
808
|
const persisted = readPersistedHitlWaiting(checkpoint?.state);
|
|
792
809
|
const behavior = persisted?.config.timeoutBehavior ?? 'error';
|
|
793
810
|
if (persisted &&
|
|
@@ -84,6 +84,7 @@ export interface DevRuntime {
|
|
|
84
84
|
* 装配本地 dev 模式所需的全部 Runtime 依赖
|
|
85
85
|
*
|
|
86
86
|
* @returns DevRuntime(含 invokeOrchestrator / streamOrchestrator / 诊断摘要)
|
|
87
|
-
* @throws EAP_LLM_MODE=local
|
|
87
|
+
* @throws `EAP_LLM_MODE=local` 且解不出密钥
|
|
88
|
+
* @throws 已配 `FOUNDATION_SERVICE_URL` 且 `EAP_LLM_CONNECTIONS` 不是合法 JSON 对象
|
|
88
89
|
*/
|
|
89
90
|
export declare function createDevRuntime(options?: CreateDevRuntimeOptions): DevRuntime;
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
*/
|
|
26
26
|
import { createDefaultLLMProvider } from '../providers/echo-llm-provider.js';
|
|
27
27
|
import { HttpLLMProvider } from '../providers/http-llm-provider.js';
|
|
28
|
-
import { createLocalLlmProvider, requireLocalLlmConnections } from '../providers/local-llm-provider.js';
|
|
28
|
+
import { createLocalLlmProvider, createOptionalLocalLlmProvider, requireLocalLlmConnections, } from '../providers/local-llm-provider.js';
|
|
29
29
|
import { RoutingLLMProvider } from '../providers/routing-llm-provider.js';
|
|
30
30
|
import { createToolExecutor } from '../tool/create-tool-executor.js';
|
|
31
31
|
import { DevToolExecutor } from '../tool/dev-tool-executor.js';
|
|
@@ -44,7 +44,8 @@ import { isRuntimeMemoryEnabled } from '../session/apply-session-memory.js';
|
|
|
44
44
|
* 装配本地 dev 模式所需的全部 Runtime 依赖
|
|
45
45
|
*
|
|
46
46
|
* @returns DevRuntime(含 invokeOrchestrator / streamOrchestrator / 诊断摘要)
|
|
47
|
-
* @throws EAP_LLM_MODE=local
|
|
47
|
+
* @throws `EAP_LLM_MODE=local` 且解不出密钥
|
|
48
|
+
* @throws 已配 `FOUNDATION_SERVICE_URL` 且 `EAP_LLM_CONNECTIONS` 不是合法 JSON 对象
|
|
48
49
|
*/
|
|
49
50
|
export function createDevRuntime(options) {
|
|
50
51
|
const foundationUrl = process.env.FOUNDATION_SERVICE_URL ?? 'http://localhost:3100';
|
|
@@ -72,7 +73,12 @@ export function createDevRuntime(options) {
|
|
|
72
73
|
llmProviderKind = 'openai-http';
|
|
73
74
|
}
|
|
74
75
|
else if (foundationConfigured) {
|
|
75
|
-
|
|
76
|
+
const fallbackProvider = createOptionalLocalLlmProvider(turnLog);
|
|
77
|
+
llmProvider = new RoutingLLMProvider({
|
|
78
|
+
foundationUrl,
|
|
79
|
+
turnLog,
|
|
80
|
+
...(fallbackProvider ? { fallbackProvider } : {}),
|
|
81
|
+
});
|
|
76
82
|
llmProviderKind = 'routing';
|
|
77
83
|
}
|
|
78
84
|
else {
|
|
@@ -23,6 +23,8 @@ export interface SessionCompressionOptions {
|
|
|
23
23
|
compressionRepository?: ICompressionRepository;
|
|
24
24
|
maxRounds?: number;
|
|
25
25
|
preserveRecentRounds?: number;
|
|
26
|
+
/** 摘要模型;与图节点同一套:Agent `models.default`。不要传字符串 `default`。 */
|
|
27
|
+
summaryModel?: string;
|
|
26
28
|
}
|
|
27
29
|
export interface RunSessionCompressionParams {
|
|
28
30
|
history: GraphMessage[];
|
|
@@ -72,6 +74,8 @@ export declare function formatCompressionCompletedMessage(input: {
|
|
|
72
74
|
error?: string;
|
|
73
75
|
}): string;
|
|
74
76
|
export declare function applySessionCompression(params: RunSessionCompressionParams): Promise<GraphMessage[]>;
|
|
77
|
+
/** 未显式 summaryModel 时写入 Agent `models.default`。压缩未开则不解析。 */
|
|
78
|
+
export declare function withCompressionSummaryModel(options: SessionCompressionOptions | undefined, resolveDefaultModel: () => Promise<string | undefined>, env?: NodeJS.ProcessEnv): Promise<SessionCompressionOptions | undefined>;
|
|
75
79
|
/**
|
|
76
80
|
* 流式入口用:先产出 started,再跑摘要,再产出 completed,最后给出本轮历史。
|
|
77
81
|
* SDK `stream` 可在 started 之后才继续 next(),HTTP SSE 可立刻 emit。
|
|
@@ -49,6 +49,19 @@ export async function applySessionCompression(params) {
|
|
|
49
49
|
const result = await runSessionCompression(params);
|
|
50
50
|
return result.messages;
|
|
51
51
|
}
|
|
52
|
+
/** 未显式 summaryModel 时写入 Agent `models.default`。压缩未开则不解析。 */
|
|
53
|
+
export async function withCompressionSummaryModel(options, resolveDefaultModel, env = process.env) {
|
|
54
|
+
if (!options)
|
|
55
|
+
return options;
|
|
56
|
+
if (!isRuntimeCompressionEnabled(options.enabled, env))
|
|
57
|
+
return options;
|
|
58
|
+
if (options.summaryModel?.trim())
|
|
59
|
+
return options;
|
|
60
|
+
const summaryModel = (await resolveDefaultModel())?.trim();
|
|
61
|
+
if (!summaryModel || summaryModel.toLowerCase() === 'default')
|
|
62
|
+
return options;
|
|
63
|
+
return { ...options, summaryModel };
|
|
64
|
+
}
|
|
52
65
|
/**
|
|
53
66
|
* 流式入口用:先产出 started,再跑摘要,再产出 completed,最后给出本轮历史。
|
|
54
67
|
* SDK `stream` 可在 started 之后才继续 next(),HTTP SSE 可立刻 emit。
|
|
@@ -151,7 +164,7 @@ async function runDecidedSessionCompression(params, decision) {
|
|
|
151
164
|
maxRounds,
|
|
152
165
|
preserveRecentRounds: options.preserveRecentRounds ?? DEFAULT_COMPRESSION_CONFIG.preserveRecentRounds,
|
|
153
166
|
...(decision.window ? { maxContextTokens: decision.window } : {}),
|
|
154
|
-
}, async (msgs) => summarizeWithProvider(provider, msgs));
|
|
167
|
+
}, async (msgs) => summarizeWithProvider(provider, msgs, options.summaryModel));
|
|
155
168
|
const compressed = await compression.compress(history);
|
|
156
169
|
if (compressed === history) {
|
|
157
170
|
return {
|
|
@@ -242,18 +255,24 @@ async function lastTurnUsage(turnLog, sessionId) {
|
|
|
242
255
|
return undefined;
|
|
243
256
|
return { used: last.used, window: last.window };
|
|
244
257
|
}
|
|
245
|
-
async function summarizeWithProvider(provider, messages) {
|
|
258
|
+
async function summarizeWithProvider(provider, messages, summaryModel) {
|
|
246
259
|
const body = messages
|
|
247
260
|
.map((m) => `${m.role}: ${m.content}`)
|
|
248
261
|
.join('\n')
|
|
249
262
|
.slice(0, 12000);
|
|
263
|
+
const raw = summaryModel?.trim();
|
|
264
|
+
const model = raw && raw.toLowerCase() !== 'default' ? raw : '';
|
|
250
265
|
const response = await provider.invoke([
|
|
251
266
|
{
|
|
252
267
|
role: 'system',
|
|
253
268
|
content: '将对话历史压成短摘要,保留用户需求、结论和未完成事项。',
|
|
254
269
|
},
|
|
255
270
|
{ role: 'user', content: body },
|
|
256
|
-
], {
|
|
271
|
+
], {
|
|
272
|
+
model,
|
|
273
|
+
temperature: 0.2,
|
|
274
|
+
maxTokens: 1024,
|
|
275
|
+
});
|
|
257
276
|
const text = response.content?.trim();
|
|
258
277
|
if (!text) {
|
|
259
278
|
throw new Error('empty compression summary');
|
package/dist/session/index.d.ts
CHANGED
|
@@ -10,6 +10,6 @@ export type { FileMessageRepositoryOptions } from './file-message.repository.js'
|
|
|
10
10
|
export { SessionContextService } from './session-context.service.js';
|
|
11
11
|
export type { ResolveSessionParams, SessionContext, } from './session-context.service.js';
|
|
12
12
|
export { CompressionMiddleware, createCompressionMiddleware } from './compression-middleware.js';
|
|
13
|
-
export { applySessionCompression, runSessionCompression, decideSessionCompression, iterSessionCompression, formatCompressionStartedMessage, formatCompressionCompletedMessage, isRuntimeCompressionEnabled, isRuntimeCompressionPersist, type SessionCompressionOptions, type RunSessionCompressionParams, type RunSessionCompressionResult, type SessionCompressionDecision, type SessionCompressionStep, } from './apply-session-compression.js';
|
|
13
|
+
export { applySessionCompression, withCompressionSummaryModel, runSessionCompression, decideSessionCompression, iterSessionCompression, formatCompressionStartedMessage, formatCompressionCompletedMessage, isRuntimeCompressionEnabled, isRuntimeCompressionPersist, type SessionCompressionOptions, type RunSessionCompressionParams, type RunSessionCompressionResult, type SessionCompressionDecision, type SessionCompressionStep, } from './apply-session-compression.js';
|
|
14
14
|
export type { CompressionMiddlewareConfig } from './compression-middleware.js';
|
|
15
15
|
export { applySessionMemory, isRuntimeMemoryEnabled, type SessionMemoryOptions, } from './apply-session-memory.js';
|
package/dist/session/index.js
CHANGED
|
@@ -10,5 +10,5 @@ export { FileMessageRepository } from './file-message.repository.js';
|
|
|
10
10
|
export { SessionContextService } from './session-context.service.js';
|
|
11
11
|
// 压缩中间件
|
|
12
12
|
export { CompressionMiddleware, createCompressionMiddleware } from './compression-middleware.js';
|
|
13
|
-
export { applySessionCompression, runSessionCompression, decideSessionCompression, iterSessionCompression, formatCompressionStartedMessage, formatCompressionCompletedMessage, isRuntimeCompressionEnabled, isRuntimeCompressionPersist, } from './apply-session-compression.js';
|
|
13
|
+
export { applySessionCompression, withCompressionSummaryModel, runSessionCompression, decideSessionCompression, iterSessionCompression, formatCompressionStartedMessage, formatCompressionCompletedMessage, isRuntimeCompressionEnabled, isRuntimeCompressionPersist, } from './apply-session-compression.js';
|
|
14
14
|
export { applySessionMemory, isRuntimeMemoryEnabled, } from './apply-session-memory.js';
|
|
@@ -21,6 +21,7 @@ export declare function persistAssistantTurnMessage(messageService: MessageServi
|
|
|
21
21
|
toolCalls?: unknown[];
|
|
22
22
|
/** DeepSeek thinking:多轮回传用 */
|
|
23
23
|
reasoningContent?: string;
|
|
24
|
+
durationMs?: number | null;
|
|
24
25
|
}): Promise<void>;
|
|
25
26
|
/**
|
|
26
27
|
* HITL 等待态占位消息:避免早退时本轮只有 user、历史偏薄
|
|
@@ -80,6 +81,7 @@ export declare function sessionVisibleAssistantTexts(texts: Array<{
|
|
|
80
81
|
* invoke 路径图增量。tool_calls / tool 行原样保留,纯文本助手收成一条放在末尾(与 stream 落库顺序一致)。
|
|
81
82
|
* GraphMessage 无 nodeId:`finishPoints` 只含一个实际节点 id 时取最后一条纯文本,不是按 id 筛选(官方 DAG 的 `merge` 在末尾)。
|
|
82
83
|
* 没有实际节点 id 或仅为 `__end__` 时把多段正文用空行拼进这一条。
|
|
84
|
+
* 无 toolCallId 的 tool 行不进 Session(code 节点结果)。
|
|
83
85
|
*/
|
|
84
86
|
export declare function sessionVisibleGraphMessages(messages: GraphMessage[], finishPoints?: string[]): GraphMessage[];
|
|
85
87
|
/**
|
|
@@ -138,8 +140,10 @@ export declare function buildHitlWaitingTaskOutput(params: {
|
|
|
138
140
|
/** 从 Task.output 解析 Checkpoint thread_id(含嵌套 hitl.threadId) */
|
|
139
141
|
export declare function extractHitlThreadId(output: unknown): string | undefined;
|
|
140
142
|
/**
|
|
141
|
-
* Checkpoint thread_id
|
|
143
|
+
* Checkpoint 父图 thread_id:HITL/多轮优先且应唯一等于 sessionId;
|
|
142
144
|
* 无 session 时退到 `task-${taskId}`。勿用 correlationId 作为 Checkpoint key。
|
|
145
|
+
* 子图槽位再经 `checkpointStorageThreadId`(`thread_id#父节点id`),
|
|
146
|
+
* 与 LangGraph put / 子图内 HITL interrupt 同一把钥匙。
|
|
143
147
|
*
|
|
144
148
|
* 注意:session 级 thread + 全量 Session 历史同时注入会导致 messages 双重 append。
|
|
145
149
|
* 组装本轮 Graph 输入请用 {@link buildTurnGraphMessages}(有 Checkpoint 历史则只追加 user)。
|
|
@@ -193,4 +197,5 @@ export declare function persistTurnTranscript(messageService: MessageService | u
|
|
|
193
197
|
/** 无 assistant 文本消息时的兜底(invoke 的 graphResult.output) */
|
|
194
198
|
fallbackAssistantContent?: string;
|
|
195
199
|
assistantTokenCount?: number;
|
|
200
|
+
assistantDurationMs?: number | null;
|
|
196
201
|
}): Promise<void>;
|
|
@@ -32,6 +32,7 @@ export async function persistAssistantTurnMessage(messageService, params) {
|
|
|
32
32
|
reasoning: params.reasoningContent
|
|
33
33
|
? { reasoningContent: params.reasoningContent }
|
|
34
34
|
: null,
|
|
35
|
+
durationMs: params.durationMs ?? null,
|
|
35
36
|
});
|
|
36
37
|
}
|
|
37
38
|
/**
|
|
@@ -163,21 +164,32 @@ function isTextAssistant(message) {
|
|
|
163
164
|
return false;
|
|
164
165
|
return Boolean(message.content?.trim());
|
|
165
166
|
}
|
|
167
|
+
/** Session 只收成对的 tool 结果;code 节点没有 toolCallId,留在 Checkpoint。 */
|
|
168
|
+
function isSessionToolMessage(message) {
|
|
169
|
+
if (message.role !== 'tool')
|
|
170
|
+
return false;
|
|
171
|
+
return Boolean(message.toolCallId?.trim());
|
|
172
|
+
}
|
|
173
|
+
function sessionGraphMessages(messages) {
|
|
174
|
+
return messages.filter((message) => message.role !== 'tool' || isSessionToolMessage(message));
|
|
175
|
+
}
|
|
166
176
|
/**
|
|
167
177
|
* invoke 路径图增量。tool_calls / tool 行原样保留,纯文本助手收成一条放在末尾(与 stream 落库顺序一致)。
|
|
168
178
|
* GraphMessage 无 nodeId:`finishPoints` 只含一个实际节点 id 时取最后一条纯文本,不是按 id 筛选(官方 DAG 的 `merge` 在末尾)。
|
|
169
179
|
* 没有实际节点 id 或仅为 `__end__` 时把多段正文用空行拼进这一条。
|
|
180
|
+
* 无 toolCallId 的 tool 行不进 Session(code 节点结果)。
|
|
170
181
|
*/
|
|
171
182
|
export function sessionVisibleGraphMessages(messages, finishPoints) {
|
|
172
|
-
const
|
|
183
|
+
const eligible = sessionGraphMessages(messages);
|
|
184
|
+
const texts = eligible.filter(isTextAssistant);
|
|
173
185
|
if (texts.length === 0)
|
|
174
|
-
return
|
|
186
|
+
return eligible;
|
|
175
187
|
const named = namedFinishPoints(finishPoints);
|
|
176
188
|
const visible = named.length === 1 ? [texts.at(-1)] : texts;
|
|
177
189
|
const keep = visible.at(-1);
|
|
178
190
|
const joined = visible.map((message) => message.content).join('\n\n');
|
|
179
191
|
const out = [];
|
|
180
|
-
for (const message of
|
|
192
|
+
for (const message of eligible) {
|
|
181
193
|
if (isTextAssistant(message))
|
|
182
194
|
continue;
|
|
183
195
|
out.push(message);
|
|
@@ -344,8 +356,10 @@ export function extractHitlThreadId(output) {
|
|
|
344
356
|
return undefined;
|
|
345
357
|
}
|
|
346
358
|
/**
|
|
347
|
-
* Checkpoint thread_id
|
|
359
|
+
* Checkpoint 父图 thread_id:HITL/多轮优先且应唯一等于 sessionId;
|
|
348
360
|
* 无 session 时退到 `task-${taskId}`。勿用 correlationId 作为 Checkpoint key。
|
|
361
|
+
* 子图槽位再经 `checkpointStorageThreadId`(`thread_id#父节点id`),
|
|
362
|
+
* 与 LangGraph put / 子图内 HITL interrupt 同一把钥匙。
|
|
349
363
|
*
|
|
350
364
|
* 注意:session 级 thread + 全量 Session 历史同时注入会导致 messages 双重 append。
|
|
351
365
|
* 组装本轮 Graph 输入请用 {@link buildTurnGraphMessages}(有 Checkpoint 历史则只追加 user)。
|
|
@@ -436,14 +450,17 @@ export async function persistTurnTranscript(messageService, params) {
|
|
|
436
450
|
toolCalls: m.toolCalls,
|
|
437
451
|
tokenCount: isToolCallOnly ? 0 : params.assistantTokenCount,
|
|
438
452
|
reasoningContent: m.reasoningContent,
|
|
453
|
+
durationMs: isToolCallOnly ? null : params.assistantDurationMs,
|
|
439
454
|
});
|
|
440
455
|
}
|
|
441
456
|
else if (m.role === 'tool') {
|
|
457
|
+
if (!m.toolCallId?.trim())
|
|
458
|
+
continue;
|
|
442
459
|
await persistToolTurnMessage(messageService, {
|
|
443
460
|
sessionId: params.sessionId,
|
|
444
461
|
taskId: params.taskId,
|
|
445
462
|
correlationId: params.correlationId,
|
|
446
|
-
toolCallId: m.toolCallId
|
|
463
|
+
toolCallId: m.toolCallId,
|
|
447
464
|
toolName: m.toolName ?? 'unknown',
|
|
448
465
|
content: m.content,
|
|
449
466
|
success: m.success !== false,
|
|
@@ -457,6 +474,7 @@ export async function persistTurnTranscript(messageService, params) {
|
|
|
457
474
|
correlationId: params.correlationId,
|
|
458
475
|
content: params.fallbackAssistantContent,
|
|
459
476
|
tokenCount: params.assistantTokenCount,
|
|
477
|
+
durationMs: params.assistantDurationMs,
|
|
460
478
|
});
|
|
461
479
|
}
|
|
462
480
|
}
|
|
@@ -14,6 +14,29 @@ export declare function tokenUsageFromNodePayload(payload: unknown): TokenUsageR
|
|
|
14
14
|
export declare function collectStreamNodeTokenUsage(event: Pick<RuntimeEvent, 'type' | 'payload'>, bucket: TokenUsageRecord[]): void;
|
|
15
15
|
/** Graph `__llmTokenUsage` channel → Task.token_usage 行(invoke / fork 抛错后从 Checkpoint 读)。 */
|
|
16
16
|
export declare function tokenUsagesFromLlmChannel(state: unknown): TokenUsageRecord[];
|
|
17
|
+
/** 本轮 LLM 用量汇总,供 stats.token_usage 与 assistantTokenCount。 */
|
|
18
|
+
export declare function summarizeTokenUsages(usages: Array<{
|
|
19
|
+
nodeId: string;
|
|
20
|
+
model: string;
|
|
21
|
+
inputTokens: number;
|
|
22
|
+
outputTokens: number;
|
|
23
|
+
costEstimate?: number;
|
|
24
|
+
}>): {
|
|
25
|
+
total: {
|
|
26
|
+
input: number;
|
|
27
|
+
output: number;
|
|
28
|
+
total: number;
|
|
29
|
+
};
|
|
30
|
+
byNode: Record<string, {
|
|
31
|
+
input: number;
|
|
32
|
+
output: number;
|
|
33
|
+
}>;
|
|
34
|
+
byModel: Record<string, {
|
|
35
|
+
input: number;
|
|
36
|
+
output: number;
|
|
37
|
+
}>;
|
|
38
|
+
costEstimate: number;
|
|
39
|
+
};
|
|
17
40
|
export declare function recordTaskTokenUsages(taskService: TaskTokenUsageWriter, taskId: string, usages: Array<{
|
|
18
41
|
nodeId: string;
|
|
19
42
|
model: string;
|
|
@@ -53,6 +53,26 @@ export function tokenUsagesFromLlmChannel(state) {
|
|
|
53
53
|
}
|
|
54
54
|
return rows;
|
|
55
55
|
}
|
|
56
|
+
/** 本轮 LLM 用量汇总,供 stats.token_usage 与 assistantTokenCount。 */
|
|
57
|
+
export function summarizeTokenUsages(usages) {
|
|
58
|
+
const byNode = {};
|
|
59
|
+
const byModel = {};
|
|
60
|
+
let input = 0;
|
|
61
|
+
let output = 0;
|
|
62
|
+
let costEstimate = 0;
|
|
63
|
+
for (const usage of usages) {
|
|
64
|
+
input += usage.inputTokens;
|
|
65
|
+
output += usage.outputTokens;
|
|
66
|
+
costEstimate += usage.costEstimate ?? 0;
|
|
67
|
+
const node = byNode[usage.nodeId] ?? (byNode[usage.nodeId] = { input: 0, output: 0 });
|
|
68
|
+
node.input += usage.inputTokens;
|
|
69
|
+
node.output += usage.outputTokens;
|
|
70
|
+
const model = byModel[usage.model] ?? (byModel[usage.model] = { input: 0, output: 0 });
|
|
71
|
+
model.input += usage.inputTokens;
|
|
72
|
+
model.output += usage.outputTokens;
|
|
73
|
+
}
|
|
74
|
+
return { total: { input, output, total: input + output }, byNode, byModel, costEstimate };
|
|
75
|
+
}
|
|
56
76
|
export async function recordTaskTokenUsages(taskService, taskId, usages) {
|
|
57
77
|
for (const usage of usages) {
|
|
58
78
|
try {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* @see docs/contracts/cross-service-api.md §4.6
|
|
6
6
|
*/
|
|
7
7
|
import { ErrorCodes } from '@gt-fe/eap-contracts';
|
|
8
|
-
import { abortOrTimeoutMessage, isAbortError } from './timeout.js';
|
|
8
|
+
import { abortOrTimeoutMessage, isAbortError, timeoutMsFromExecution } from './timeout.js';
|
|
9
9
|
function mapGatewayHttpError(status, body, statusText) {
|
|
10
10
|
const code = body?.error?.code;
|
|
11
11
|
const bodyMessage = [body?.error?.message, body?.message].find((s) => typeof s === 'string' && s.trim()) ?? '';
|
|
@@ -81,13 +81,17 @@ export class HttpToolExecutor {
|
|
|
81
81
|
Authorization: `Bearer ${request.authContext.delegationToken}`,
|
|
82
82
|
'X-Agent-Id': agentCode,
|
|
83
83
|
'X-Agent-Code': agentCode,
|
|
84
|
+
...(request.authContext.agentVersion
|
|
85
|
+
? { 'X-Agent-Version': request.authContext.agentVersion }
|
|
86
|
+
: {}),
|
|
84
87
|
'X-User-Id': request.authContext.userId,
|
|
85
88
|
userId: request.authContext.userId,
|
|
86
89
|
'X-Correlation-Id': correlationId,
|
|
87
90
|
'X-Task-Id': taskId,
|
|
88
91
|
};
|
|
89
92
|
const controller = new AbortController();
|
|
90
|
-
const
|
|
93
|
+
const timeoutMs = timeoutMsFromExecution(request.execution, this.timeout);
|
|
94
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
91
95
|
try {
|
|
92
96
|
const response = await fetch(url, {
|
|
93
97
|
method: 'POST',
|
|
@@ -137,7 +141,7 @@ export class HttpToolExecutor {
|
|
|
137
141
|
}
|
|
138
142
|
catch (error) {
|
|
139
143
|
clearTimeout(timeoutId);
|
|
140
|
-
const timeoutSec = Math.max(1, Math.round(this.timeout / 1000));
|
|
144
|
+
const timeoutSec = Math.max(1, Math.round(timeoutMsFromExecution(request.execution, this.timeout) / 1000));
|
|
141
145
|
const aborted = isAbortError(error);
|
|
142
146
|
return {
|
|
143
147
|
toolCallId: request.toolCallId,
|
package/dist/tool/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type { AuthContext, ToolCallRequest, ToolCallResult, LLMToolCall, LLMToolCallResponse, IToolExecutor, McpListedTool, } from './tool-executor.interface.js';
|
|
2
|
-
export { hydrateMcpTools, isMcpDiscoverStub, needsMcpHydration, parseListedTools, toolsetCodeFromLoaded, toolTraceIdentity, } from './mcp-list.js';
|
|
2
|
+
export { assertScopedListEcho, hydrateMcpTools, isMcpDiscoverStub, mcpToolsetCode, needsMcpHydration, parseListedTools, toolsetCodeFromLoaded, toolTraceIdentity, } from './mcp-list.js';
|
|
3
3
|
export { toLoadedToolMap, type LoadedToolDefinition, type LoadedToolMap, type LoadedToolManifestRef, } from './loaded-tool-definition.js';
|
|
4
4
|
export { ToolOrchestrator } from './tool-orchestrator.js';
|
|
5
5
|
export { isRetryableToolFailure, resolveToolRetryConfig, type ToolFailureShape, } from './tool-retry.js';
|
|
@@ -11,6 +11,7 @@ export { DevHttpExecutor, buildHttpToolUrl, resolveHttpExecutionFromRequest, typ
|
|
|
11
11
|
export { DevToolExecutor, type DevToolExecutorOptions } from './dev-tool-executor.js';
|
|
12
12
|
export { LocalMcpClient, type ILocalMcpClient, type LocalMcpInvokeContext, type LocalMcpInvokeResult, } from './local-mcp-client.js';
|
|
13
13
|
export { fileArtifactFromToolOutput, extractFileReference, resolveFileArtifact, type FileArtifact, } from './file-artifact.js';
|
|
14
|
+
export { formatMcpOutput, toModelVisibleToolContent, MAX_MODEL_RESULT_ROWS, MAX_MODEL_CONTENT_CHARS, MAX_MODEL_RESULT_CHARS, } from './model-visible-tool-content.js';
|
|
14
15
|
export { ToolExecutionRouter, type DeploymentContext, type ToolExecutionRouterOptions, } from './tool-execution-router.js';
|
|
15
16
|
export { createToolExecutor, EmptyInstallStore, type CreateToolExecutorOptions, } from './create-tool-executor.js';
|
|
16
17
|
export { assembleLoadedTools, mergeHarnessPrimitives as mergeBuiltinTools, withHarnessPrimitives as withBuiltinTools, HarnessPrimitiveExecutor as BuiltinToolExecutor, resolveUserDir, resolveJailFromState, captureOverlayJailOptions, collectToolBundlePaths, type HarnessJailOptions as BuiltinJailOptions, } from './harness-primitives.js';
|