@gt-fe/eap-runtime 0.0.23 → 0.0.25
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 -0
- package/dist/api/handlers/invoke.handler.d.ts +4 -0
- package/dist/api/handlers/invoke.handler.js +69 -37
- package/dist/api/handlers/stream.handler.d.ts +4 -0
- package/dist/api/handlers/stream.handler.js +40 -21
- package/dist/api/routes/agent.routes.js +6 -5
- package/dist/checkpoint/checkpoint-ref-notify.js +1 -1
- package/dist/common/types.d.ts +6 -2
- package/dist/common/types.js +3 -1
- package/dist/graph/adapters/langgraph.adapter.d.ts +6 -4
- package/dist/graph/adapters/langgraph.adapter.js +103 -18
- package/dist/graph/contracts/executable-graph.d.ts +11 -2
- package/dist/graph/execution-trace-context.d.ts +4 -0
- package/dist/graph/execution-trace-context.js +3 -1
- package/dist/graph/nodes/rag/types.d.ts +4 -1
- package/dist/providers/http-llm-provider.js +25 -0
- package/dist/registry/graph-loader.js +5 -4
- package/dist/runtime/agent-runtime.d.ts +4 -1
- package/dist/runtime/agent-runtime.js +110 -20
- package/dist/runtime/dev-runtime.d.ts +1 -0
- package/dist/runtime/dev-runtime.js +9 -2
- package/dist/runtime/types.d.ts +1 -1
- package/dist/session/apply-session-compression.d.ts +6 -4
- package/dist/session/apply-session-compression.js +24 -11
- package/dist/session/index.d.ts +1 -1
- package/dist/session/index.js +1 -1
- package/dist/session/persist-turn-messages.d.ts +50 -9
- package/dist/session/persist-turn-messages.js +133 -15
- package/dist/sse/events/response-events.d.ts +2 -2
- package/dist/sse/events/response-events.js +1 -1
- package/dist/task/contracts/task-manager.contract.d.ts +2 -0
- package/dist/task/index.d.ts +1 -0
- package/dist/task/index.js +1 -0
- package/dist/task/resolve-task-timeout.d.ts +6 -0
- package/dist/task/resolve-task-timeout.js +16 -0
- package/dist/task/task-timeout.d.ts +1 -1
- package/dist/task/task-timeout.js +3 -2
- package/dist/task/task.service.js +1 -0
- package/package.json +2 -2
|
@@ -305,31 +305,149 @@ function extractReasoningContent(reasoning) {
|
|
|
305
305
|
* - Session 级 Checkpoint 持有图内 messages(含 reasoning)
|
|
306
306
|
* - 当 Checkpoint 已有历史时,只追加本轮 user,避免双重 append
|
|
307
307
|
* - Checkpoint 缺失/无 messages 时,回退 Session 全量历史
|
|
308
|
+
* - 压缩针对 Checkpoint(无则 Session)中的模型上下文;压成功且来自 Checkpoint 时由调用方设 `replaceCheckpointMessages`
|
|
308
309
|
*/
|
|
309
310
|
export async function buildTurnGraphMessages(params) {
|
|
310
|
-
const
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
311
|
+
const facing = await loadModelFacingHistory({
|
|
312
|
+
sessionHistory: params.history,
|
|
313
|
+
checkpointSaver: params.checkpointSaver,
|
|
314
|
+
threadId: params.threadId,
|
|
315
|
+
});
|
|
316
|
+
return turnGraphMessagesAfterCompression({
|
|
317
|
+
history: facing.messages,
|
|
318
|
+
input: params.input,
|
|
319
|
+
fromCheckpoint: facing.fromCheckpoint,
|
|
320
|
+
compressed: false,
|
|
321
|
+
}).messages;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* 模型上下文:Checkpoint 已有 messages 用它,否则用 Session 历史。
|
|
325
|
+
* 压缩必须压这份列表,不能只压 Session 再在有 Checkpoint 时丢掉。
|
|
326
|
+
*/
|
|
327
|
+
export async function loadModelFacingHistory(params) {
|
|
328
|
+
const sessionHistory = params.sessionHistory ?? [];
|
|
329
|
+
if (!params.checkpointSaver || !params.threadId) {
|
|
330
|
+
return { messages: sessionHistory, fromCheckpoint: false };
|
|
314
331
|
}
|
|
315
332
|
const cp = await params.checkpointSaver.load(params.threadId);
|
|
316
|
-
|
|
317
|
-
|
|
333
|
+
const checkpointMessages = graphMessagesFromCheckpoint(cp);
|
|
334
|
+
if (checkpointMessages.length > 0) {
|
|
335
|
+
return { messages: checkpointMessages, fromCheckpoint: true };
|
|
318
336
|
}
|
|
319
|
-
return
|
|
337
|
+
return { messages: sessionHistory, fromCheckpoint: false };
|
|
320
338
|
}
|
|
321
|
-
|
|
339
|
+
/**
|
|
340
|
+
* 压缩后的入图列表。来自 Checkpoint 且本轮压成功:整表 `__set` 覆盖,写入最新 Checkpoint。
|
|
341
|
+
* 未压且来自 Checkpoint:只追加本轮 user。无 Checkpoint:历史 + 本轮 user。
|
|
342
|
+
*/
|
|
343
|
+
export function turnGraphMessagesAfterCompression(params) {
|
|
344
|
+
const newUser = { role: 'user', content: params.input };
|
|
345
|
+
if (params.fromCheckpoint && params.compressed) {
|
|
346
|
+
return {
|
|
347
|
+
messages: [...params.history, newUser],
|
|
348
|
+
replaceCheckpointMessages: true,
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
if (params.fromCheckpoint) {
|
|
352
|
+
return { messages: [newUser], replaceCheckpointMessages: false };
|
|
353
|
+
}
|
|
354
|
+
return {
|
|
355
|
+
messages: [...params.history, newUser],
|
|
356
|
+
replaceCheckpointMessages: false,
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* invoke 从 Graph 最终 messages 切本轮增量的起点。
|
|
361
|
+
* 覆盖(`__set`)或无 Checkpoint:入图数组长度(已含本轮 user)。
|
|
362
|
+
* 追加到已有 Checkpoint:模型上下文条数 + 入图条数(通常 1 条 user)。
|
|
363
|
+
*/
|
|
364
|
+
export function persistGraphMessageBaseline(params) {
|
|
365
|
+
if (params.replaceCheckpointMessages || !params.fromCheckpoint) {
|
|
366
|
+
return params.graphInputCount;
|
|
367
|
+
}
|
|
368
|
+
return params.modelFacingCount + params.graphInputCount;
|
|
369
|
+
}
|
|
370
|
+
export function graphMessagesFromCheckpoint(cp) {
|
|
322
371
|
if (!cp)
|
|
323
|
-
return
|
|
324
|
-
if (Array.isArray(cp.state?.messages) && cp.state.messages.length > 0)
|
|
325
|
-
return true;
|
|
372
|
+
return [];
|
|
326
373
|
const channelValues = cp.engineSnapshot?.['channel_values'];
|
|
327
374
|
if (channelValues && typeof channelValues === 'object') {
|
|
328
375
|
const messages = channelValues['messages'];
|
|
329
|
-
if (Array.isArray(messages) && messages.length > 0)
|
|
330
|
-
return
|
|
376
|
+
if (Array.isArray(messages) && messages.length > 0) {
|
|
377
|
+
return unknownListToGraphMessages(messages);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
if (Array.isArray(cp.state?.messages) && cp.state.messages.length > 0) {
|
|
381
|
+
return unknownListToGraphMessages(cp.state.messages);
|
|
382
|
+
}
|
|
383
|
+
return [];
|
|
384
|
+
}
|
|
385
|
+
function unknownListToGraphMessages(raw) {
|
|
386
|
+
return raw.map((msg) => unknownToGraphMessage(msg));
|
|
387
|
+
}
|
|
388
|
+
function unknownToGraphMessage(msg) {
|
|
389
|
+
if (typeof msg !== 'object' || msg === null) {
|
|
390
|
+
return { role: 'user', content: String(msg) };
|
|
331
391
|
}
|
|
332
|
-
|
|
392
|
+
const m = msg;
|
|
393
|
+
const nested = m.kwargs && typeof m.kwargs === 'object' ? m.kwargs : undefined;
|
|
394
|
+
const lcName = Array.isArray(m.id) ? m.id[m.id.length - 1] : undefined;
|
|
395
|
+
const typeHint = m.type === 'constructor' ? undefined : m.type;
|
|
396
|
+
const role = graphRoleFromUnknown(m.role ?? nested?.role ?? nested?.type ?? typeHint ?? lcName);
|
|
397
|
+
const content = messageContentToString(m.content ?? nested?.content);
|
|
398
|
+
const toolCalls = (m.toolCalls ?? m.tool_calls ?? nested?.tool_calls);
|
|
399
|
+
const toolCallId = (typeof m.toolCallId === 'string' && m.toolCallId) ||
|
|
400
|
+
(typeof m.tool_call_id === 'string' && m.tool_call_id) ||
|
|
401
|
+
(typeof nested?.tool_call_id === 'string' && nested.tool_call_id) ||
|
|
402
|
+
undefined;
|
|
403
|
+
const toolName = (typeof m.toolName === 'string' && m.toolName) ||
|
|
404
|
+
(typeof nested?.name === 'string' && nested.name) ||
|
|
405
|
+
undefined;
|
|
406
|
+
const success = typeof m.success === 'boolean' ? m.success : undefined;
|
|
407
|
+
const reasoningContent = (typeof m.reasoningContent === 'string' && m.reasoningContent) ||
|
|
408
|
+
(typeof m.reasoning_content === 'string' && m.reasoning_content) ||
|
|
409
|
+
undefined;
|
|
410
|
+
return {
|
|
411
|
+
role,
|
|
412
|
+
content,
|
|
413
|
+
...(toolCalls ? { toolCalls } : {}),
|
|
414
|
+
...(toolCallId ? { toolCallId } : {}),
|
|
415
|
+
...(toolName ? { toolName } : {}),
|
|
416
|
+
...(success !== undefined ? { success } : {}),
|
|
417
|
+
...(reasoningContent ? { reasoningContent } : {}),
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
function graphRoleFromUnknown(raw) {
|
|
421
|
+
if (raw === 'user' || raw === 'assistant' || raw === 'system' || raw === 'tool')
|
|
422
|
+
return raw;
|
|
423
|
+
if (raw === 'human' || raw === 'HumanMessage')
|
|
424
|
+
return 'user';
|
|
425
|
+
if (raw === 'ai' || raw === 'AIMessage')
|
|
426
|
+
return 'assistant';
|
|
427
|
+
if (raw === 'system' || raw === 'SystemMessage')
|
|
428
|
+
return 'system';
|
|
429
|
+
if (raw === 'tool' || raw === 'ToolMessage')
|
|
430
|
+
return 'tool';
|
|
431
|
+
return 'user';
|
|
432
|
+
}
|
|
433
|
+
function messageContentToString(content) {
|
|
434
|
+
if (typeof content === 'string')
|
|
435
|
+
return content;
|
|
436
|
+
if (Array.isArray(content)) {
|
|
437
|
+
return content
|
|
438
|
+
.map((part) => {
|
|
439
|
+
if (typeof part === 'string')
|
|
440
|
+
return part;
|
|
441
|
+
if (part && typeof part === 'object' && typeof part.text === 'string') {
|
|
442
|
+
return part.text;
|
|
443
|
+
}
|
|
444
|
+
return '';
|
|
445
|
+
})
|
|
446
|
+
.join('');
|
|
447
|
+
}
|
|
448
|
+
if (content == null)
|
|
449
|
+
return '';
|
|
450
|
+
return String(content);
|
|
333
451
|
}
|
|
334
452
|
export function buildHitlWaitingTaskOutput(params) {
|
|
335
453
|
return {
|
|
@@ -362,7 +480,7 @@ export function extractHitlThreadId(output) {
|
|
|
362
480
|
* 与 LangGraph put / 子图内 HITL interrupt 同一把钥匙。
|
|
363
481
|
*
|
|
364
482
|
* 注意:session 级 thread + 全量 Session 历史同时注入会导致 messages 双重 append。
|
|
365
|
-
* 组装本轮 Graph 输入请用 {@link
|
|
483
|
+
* 组装本轮 Graph 输入请用 {@link loadModelFacingHistory} 与 {@link turnGraphMessagesAfterCompression}。
|
|
366
484
|
*/
|
|
367
485
|
export function resolveCheckpointThreadId(params) {
|
|
368
486
|
if (params.sessionId)
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* - response.final
|
|
6
6
|
*
|
|
7
7
|
* 可选事件:
|
|
8
|
-
* - response.max_iterations_reached
|
|
8
|
+
* - response.max_iterations_reached(契约保留;调度步上限走 task.error / runtime.graph.max_iterations,不发本事件)
|
|
9
9
|
*
|
|
10
10
|
* @see design.md §1.6 SSE事件协议定义
|
|
11
11
|
*/
|
|
@@ -16,7 +16,7 @@ export interface ResponseFinalPayload {
|
|
|
16
16
|
/** 回复格式(如 text, markdown, json) */
|
|
17
17
|
format: string;
|
|
18
18
|
}
|
|
19
|
-
/**
|
|
19
|
+
/** 契约保留。整图调度步上限不发此事件。 */
|
|
20
20
|
export interface ResponseMaxIterationsReachedPayload {
|
|
21
21
|
/** 最大迭代次数 */
|
|
22
22
|
maxIterations: number;
|
package/dist/task/index.d.ts
CHANGED
|
@@ -3,5 +3,6 @@ export { TaskService, InMemoryTaskRepository } from './task.service.js';
|
|
|
3
3
|
export type { ITaskRepository } from './task.service.js';
|
|
4
4
|
export { TaskTimeoutManager } from './task-timeout.js';
|
|
5
5
|
export type { TaskTimeoutManagerOptions } from './task-timeout.js';
|
|
6
|
+
export { resolveTaskTimeoutMs } from './resolve-task-timeout.js';
|
|
6
7
|
export { TaskProgressTracker } from './task-progress-tracker.js';
|
|
7
8
|
export type { TaskProgressInfo } from './task-progress-tracker.js';
|
package/dist/task/index.js
CHANGED
|
@@ -2,4 +2,5 @@
|
|
|
2
2
|
export * from './contracts/index.js';
|
|
3
3
|
export { TaskService, InMemoryTaskRepository } from './task.service.js';
|
|
4
4
|
export { TaskTimeoutManager } from './task-timeout.js';
|
|
5
|
+
export { resolveTaskTimeoutMs } from './resolve-task-timeout.js';
|
|
5
6
|
export { TaskProgressTracker } from './task-progress-tracker.js';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 整图超时:请求 config.timeout,否则图 config.timeout,否则平台缺省 1200000 毫秒(20 分钟)。
|
|
3
|
+
* 官方模板图上不写 timeout,用平台缺省。LLM HTTP 超时、HITL 等待另算。
|
|
4
|
+
*/
|
|
5
|
+
/** 请求显式值优先,否则图配置,否则 {@link DEFAULT_GRAPH_TIMEOUT_MS}。 */
|
|
6
|
+
export declare function resolveTaskTimeoutMs(requestTimeout?: number, graphTimeout?: number): number;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 整图超时:请求 config.timeout,否则图 config.timeout,否则平台缺省 1200000 毫秒(20 分钟)。
|
|
3
|
+
* 官方模板图上不写 timeout,用平台缺省。LLM HTTP 超时、HITL 等待另算。
|
|
4
|
+
*/
|
|
5
|
+
import { DEFAULT_GRAPH_TIMEOUT_MS } from '../common/types.js';
|
|
6
|
+
function positiveMs(value) {
|
|
7
|
+
if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0)
|
|
8
|
+
return undefined;
|
|
9
|
+
return Math.trunc(value);
|
|
10
|
+
}
|
|
11
|
+
/** 请求显式值优先,否则图配置,否则 {@link DEFAULT_GRAPH_TIMEOUT_MS}。 */
|
|
12
|
+
export function resolveTaskTimeoutMs(requestTimeout, graphTimeout) {
|
|
13
|
+
return (positiveMs(requestTimeout) ??
|
|
14
|
+
positiveMs(graphTimeout) ??
|
|
15
|
+
DEFAULT_GRAPH_TIMEOUT_MS);
|
|
16
|
+
}
|
|
@@ -9,11 +9,12 @@
|
|
|
9
9
|
* @see design.md §1.1 任务管理 — Task级超时
|
|
10
10
|
* @see requirements.md Requirement 7 AC4
|
|
11
11
|
*/
|
|
12
|
+
import { DEFAULT_GRAPH_TIMEOUT_MS } from '../common/types.js';
|
|
12
13
|
// ─────────────────────────────────────────────
|
|
13
14
|
// Default Constants
|
|
14
15
|
// ─────────────────────────────────────────────
|
|
15
|
-
/**
|
|
16
|
-
const DEFAULT_TIMEOUT_MS =
|
|
16
|
+
/** 默认超时:与图/请求缺省同一常数 */
|
|
17
|
+
const DEFAULT_TIMEOUT_MS = DEFAULT_GRAPH_TIMEOUT_MS;
|
|
17
18
|
/** 最大允许超时:3600 秒(1 小时) */
|
|
18
19
|
const MAX_TIMEOUT_MS = 3_600_000;
|
|
19
20
|
// ─────────────────────────────────────────────
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gt-fe/eap-runtime",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.25",
|
|
4
4
|
"description": "Enterprise Agent Platform — Runtime核心:Graph执行引擎、Task生命周期、Session管理、Checkpoint持久化",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"ioredis": "^5.4.0",
|
|
21
21
|
"pg": "^8.13.0",
|
|
22
22
|
"yaml": "^2.6.1",
|
|
23
|
-
"@gt-fe/eap-contracts": "0.0.
|
|
23
|
+
"@gt-fe/eap-contracts": "0.0.14"
|
|
24
24
|
},
|
|
25
25
|
"publishConfig": {
|
|
26
26
|
"registry": "https://registry.npmjs.org/",
|