@gt-fe/eap-cli 0.2.11 → 0.2.12
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 +304 -304
- package/dist/static/playground/index.html +131 -131
- package/dist/static/playground/playground.css +209 -209
- package/dist/static/playground/playground.js +151 -151
- package/dist/static/playground-app/index.html +11 -11
- package/dist/templates/README.md +51 -51
- package/dist/templates/agent-api-orchestration/.env +16 -16
- package/dist/templates/agent-api-orchestration/README.md +326 -326
- package/dist/templates/agent-api-orchestration/agent.manifest.json +19 -19
- package/dist/templates/agent-api-orchestration/eap.config.json +1 -1
- package/dist/templates/agent-api-orchestration/eap.lock.yaml +5 -5
- package/dist/templates/agent-api-orchestration/gitignore +3 -3
- package/dist/templates/agent-api-orchestration/graph.json +35 -35
- package/dist/templates/agent-api-orchestration/package.json +1 -1
- package/dist/templates/agent-api-orchestration/scripts/api-test.mjs +443 -443
- package/dist/templates/agent-api-orchestration/scripts/build-runtime.mjs +26 -26
- package/dist/templates/agent-api-orchestration/scripts/validate.mjs +12 -12
- package/dist/templates/agent-api-orchestration/src/embedded-agent.ts +91 -91
- package/dist/templates/agent-api-orchestration/src/http/app.ts +58 -58
- package/dist/templates/agent-api-orchestration/src/http/config.ts +34 -34
- package/dist/templates/agent-api-orchestration/src/http/errors.ts +63 -63
- package/dist/templates/agent-api-orchestration/src/http/index.ts +4 -4
- package/dist/templates/agent-api-orchestration/src/http/middleware/cors.ts +17 -17
- package/dist/templates/agent-api-orchestration/src/http/routes/agent.ts +33 -33
- package/dist/templates/agent-api-orchestration/src/http/routes/health.ts +15 -15
- package/dist/templates/agent-api-orchestration/src/http/routes/invocations.ts +29 -29
- package/dist/templates/agent-api-orchestration/src/http/routes/sessions.ts +70 -70
- package/dist/templates/agent-api-orchestration/src/http/services/agent-service.ts +60 -60
- package/dist/templates/agent-api-orchestration/src/http/services/resource-service.ts +95 -95
- package/dist/templates/agent-api-orchestration/src/http/shared/request.ts +82 -82
- package/dist/templates/agent-api-orchestration/src/http/shared/sse.ts +32 -32
- package/dist/templates/agent-api-orchestration/src/http/types.ts +39 -39
- package/dist/templates/agent-api-orchestration/src/index.ts +91 -91
- package/dist/templates/agent-api-orchestration/src/platform-user.ts +36 -36
- package/dist/templates/agent-api-orchestration/src/project-config.ts +45 -45
- package/dist/templates/agent-api-orchestration/tsconfig.json +15 -15
- package/dist/templates/dag-workflow/README.md +102 -102
- package/dist/templates/dag-workflow/agent.manifest.json +19 -19
- package/dist/templates/dag-workflow/eap.config.json +1 -1
- package/dist/templates/dag-workflow/eap.lock.yaml +5 -5
- package/dist/templates/dag-workflow/gitignore +51 -51
- package/dist/templates/dag-workflow/graph.json +51 -51
- package/dist/templates/dag-workflow/package.json +10 -10
- package/dist/templates/dag-workflow/skills/README.md +116 -116
- package/dist/templates/plan-and-execute/README.md +109 -109
- package/dist/templates/plan-and-execute/agent.manifest.json +19 -19
- package/dist/templates/plan-and-execute/eap.config.json +1 -1
- package/dist/templates/plan-and-execute/eap.lock.yaml +5 -5
- package/dist/templates/plan-and-execute/gitignore +51 -51
- package/dist/templates/plan-and-execute/graph.json +49 -49
- package/dist/templates/plan-and-execute/package.json +10 -10
- package/dist/templates/plan-and-execute/skills/README.md +120 -120
- package/dist/templates/plan-and-execute/tools/echo-tool/src/index.js +17 -17
- package/dist/templates/plan-and-execute/tools/echo-tool/toolset.manifest.json +55 -55
- package/dist/templates/simple-flow/README.md +87 -87
- package/dist/templates/simple-flow/agent.manifest.json +19 -19
- package/dist/templates/simple-flow/eap.config.json +1 -1
- package/dist/templates/simple-flow/eap.lock.yaml +5 -5
- package/dist/templates/simple-flow/gitignore +51 -51
- package/dist/templates/simple-flow/graph.json +32 -32
- package/dist/templates/simple-flow/package.json +10 -10
- package/dist/templates/simple-flow/skills/README.md +113 -113
- package/dist/templates/single-agent-with-tools/README.md +138 -138
- package/dist/templates/single-agent-with-tools/agent.manifest.json +19 -19
- package/dist/templates/single-agent-with-tools/eap.config.json +1 -1
- package/dist/templates/single-agent-with-tools/eap.lock.yaml +5 -5
- package/dist/templates/single-agent-with-tools/gitignore +51 -51
- package/dist/templates/single-agent-with-tools/graph.json +41 -41
- package/dist/templates/single-agent-with-tools/package.json +10 -10
- package/dist/templates/single-agent-with-tools/skills/README.md +119 -119
- package/dist/templates/single-agent-with-tools/tools/echo-tool/src/index.js +17 -17
- package/dist/templates/single-agent-with-tools/tools/echo-tool/toolset.manifest.json +55 -55
- package/dist/templates/single-agent-with-tools/tools/http-weather/toolset.manifest.json +73 -73
- package/dist/templates/single-agent-with-tools/tools/web-search/toolset.manifest.json +41 -41
- package/package.json +3 -3
|
@@ -1,82 +1,82 @@
|
|
|
1
|
-
import type { Request } from 'express';
|
|
2
|
-
import { randomUUID } from 'node:crypto';
|
|
3
|
-
import type { AgentRequest } from '@gt-fe/eap-sdk';
|
|
4
|
-
import type { AgentRequestBody } from '../types.js';
|
|
5
|
-
import { badRequest } from '../errors.js';
|
|
6
|
-
|
|
7
|
-
export function text(value: unknown): string | undefined {
|
|
8
|
-
return typeof value === 'string' && value.trim() ? value.trim() : undefined;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function isRecord(value: unknown): value is Record<string, unknown> {
|
|
12
|
-
return Boolean(value && typeof value === 'object' && !Array.isArray(value));
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function requestBody(request: Request): AgentRequestBody {
|
|
16
|
-
// 非 JSON 对象统一按空对象处理,具体字段校验由路由服务函数完成。
|
|
17
|
-
return isRecord(request.body) ? request.body as AgentRequestBody : {};
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function resolveSessionId(routeSessionId: string | undefined, bodySessionId: string | undefined): string | undefined {
|
|
21
|
-
if (routeSessionId && bodySessionId && routeSessionId !== bodySessionId) {
|
|
22
|
-
throw badRequest('Path sessionId and body sessionId must match');
|
|
23
|
-
}
|
|
24
|
-
return routeSessionId ?? bodySessionId;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function buildAgentRequest(
|
|
28
|
-
request: Request,
|
|
29
|
-
body: AgentRequestBody,
|
|
30
|
-
sessionId?: string,
|
|
31
|
-
): AgentRequest {
|
|
32
|
-
// 只组装 SDK AgentRequest,不解析 Authorization,也不构造用户身份上下文。
|
|
33
|
-
const correlationId = request.header('x-correlation-id')?.trim() || randomUUID();
|
|
34
|
-
const ragSources = stringArray(body.ragSources, 'ragSources');
|
|
35
|
-
const ragScope = parseRagScope(body.ragScope);
|
|
36
|
-
return {
|
|
37
|
-
...(sessionId ? { sessionId } : {}),
|
|
38
|
-
...(text(body.taskId) ? { taskId: text(body.taskId) } : {}),
|
|
39
|
-
...(text(body.agentVersion) ? { agentVersion: text(body.agentVersion) } : {}),
|
|
40
|
-
// 服务层不伪造用户身份;关联 ID 仍然透传,方便宿主接入自己的日志和链路追踪。
|
|
41
|
-
traceId: text(body.traceId) ?? correlationId,
|
|
42
|
-
...(isRecord(body.config) ? { config: body.config as AgentRequest['config'] } : {}),
|
|
43
|
-
...(ragSources ? { ragSources } : {}),
|
|
44
|
-
...(ragScope ? { ragScope } : {}),
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function pagination(request: Request): { limit?: number; offset?: number } {
|
|
49
|
-
const limit = queryInteger(request.query.limit, 'limit');
|
|
50
|
-
const offset = queryInteger(request.query.offset, 'offset');
|
|
51
|
-
if (limit !== undefined && (limit < 1 || limit > 500)) throw badRequest('limit must be an integer between 1 and 500');
|
|
52
|
-
return {
|
|
53
|
-
...(limit !== undefined ? { limit } : {}),
|
|
54
|
-
...(offset !== undefined ? { offset } : {}),
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function queryInteger(value: unknown, name: string): number | undefined {
|
|
59
|
-
if (value === undefined || value === '') return undefined;
|
|
60
|
-
if (typeof value !== 'string' || !/^\d+$/.test(value)) throw badRequest(`${name} must be a non-negative integer`);
|
|
61
|
-
return Number(value);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function stringArray(value: unknown, name = 'value'): string[] | undefined {
|
|
65
|
-
if (value === undefined) return undefined;
|
|
66
|
-
if (!Array.isArray(value) || !value.every((item) => typeof item === 'string')) {
|
|
67
|
-
throw badRequest(`${name} must be an array of strings`);
|
|
68
|
-
}
|
|
69
|
-
return value as string[];
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function parseRagScope(value: unknown): AgentRequest['ragScope'] {
|
|
73
|
-
if (value === undefined) return undefined;
|
|
74
|
-
if (!isRecord(value)) throw badRequest('ragScope must be an object');
|
|
75
|
-
const fileIds = stringArray(value.fileIds, 'ragScope.fileIds');
|
|
76
|
-
const dirPaths = stringArray(value.dirPaths, 'ragScope.dirPaths');
|
|
77
|
-
if (fileIds === undefined && dirPaths === undefined) return undefined;
|
|
78
|
-
return {
|
|
79
|
-
...(fileIds ? { fileIds } : {}),
|
|
80
|
-
...(dirPaths ? { dirPaths } : {}),
|
|
81
|
-
};
|
|
82
|
-
}
|
|
1
|
+
import type { Request } from 'express';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import type { AgentRequest } from '@gt-fe/eap-sdk';
|
|
4
|
+
import type { AgentRequestBody } from '../types.js';
|
|
5
|
+
import { badRequest } from '../errors.js';
|
|
6
|
+
|
|
7
|
+
export function text(value: unknown): string | undefined {
|
|
8
|
+
return typeof value === 'string' && value.trim() ? value.trim() : undefined;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function isRecord(value: unknown): value is Record<string, unknown> {
|
|
12
|
+
return Boolean(value && typeof value === 'object' && !Array.isArray(value));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function requestBody(request: Request): AgentRequestBody {
|
|
16
|
+
// 非 JSON 对象统一按空对象处理,具体字段校验由路由服务函数完成。
|
|
17
|
+
return isRecord(request.body) ? request.body as AgentRequestBody : {};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function resolveSessionId(routeSessionId: string | undefined, bodySessionId: string | undefined): string | undefined {
|
|
21
|
+
if (routeSessionId && bodySessionId && routeSessionId !== bodySessionId) {
|
|
22
|
+
throw badRequest('Path sessionId and body sessionId must match');
|
|
23
|
+
}
|
|
24
|
+
return routeSessionId ?? bodySessionId;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function buildAgentRequest(
|
|
28
|
+
request: Request,
|
|
29
|
+
body: AgentRequestBody,
|
|
30
|
+
sessionId?: string,
|
|
31
|
+
): AgentRequest {
|
|
32
|
+
// 只组装 SDK AgentRequest,不解析 Authorization,也不构造用户身份上下文。
|
|
33
|
+
const correlationId = request.header('x-correlation-id')?.trim() || randomUUID();
|
|
34
|
+
const ragSources = stringArray(body.ragSources, 'ragSources');
|
|
35
|
+
const ragScope = parseRagScope(body.ragScope);
|
|
36
|
+
return {
|
|
37
|
+
...(sessionId ? { sessionId } : {}),
|
|
38
|
+
...(text(body.taskId) ? { taskId: text(body.taskId) } : {}),
|
|
39
|
+
...(text(body.agentVersion) ? { agentVersion: text(body.agentVersion) } : {}),
|
|
40
|
+
// 服务层不伪造用户身份;关联 ID 仍然透传,方便宿主接入自己的日志和链路追踪。
|
|
41
|
+
traceId: text(body.traceId) ?? correlationId,
|
|
42
|
+
...(isRecord(body.config) ? { config: body.config as AgentRequest['config'] } : {}),
|
|
43
|
+
...(ragSources ? { ragSources } : {}),
|
|
44
|
+
...(ragScope ? { ragScope } : {}),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function pagination(request: Request): { limit?: number; offset?: number } {
|
|
49
|
+
const limit = queryInteger(request.query.limit, 'limit');
|
|
50
|
+
const offset = queryInteger(request.query.offset, 'offset');
|
|
51
|
+
if (limit !== undefined && (limit < 1 || limit > 500)) throw badRequest('limit must be an integer between 1 and 500');
|
|
52
|
+
return {
|
|
53
|
+
...(limit !== undefined ? { limit } : {}),
|
|
54
|
+
...(offset !== undefined ? { offset } : {}),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function queryInteger(value: unknown, name: string): number | undefined {
|
|
59
|
+
if (value === undefined || value === '') return undefined;
|
|
60
|
+
if (typeof value !== 'string' || !/^\d+$/.test(value)) throw badRequest(`${name} must be a non-negative integer`);
|
|
61
|
+
return Number(value);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function stringArray(value: unknown, name = 'value'): string[] | undefined {
|
|
65
|
+
if (value === undefined) return undefined;
|
|
66
|
+
if (!Array.isArray(value) || !value.every((item) => typeof item === 'string')) {
|
|
67
|
+
throw badRequest(`${name} must be an array of strings`);
|
|
68
|
+
}
|
|
69
|
+
return value as string[];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function parseRagScope(value: unknown): AgentRequest['ragScope'] {
|
|
73
|
+
if (value === undefined) return undefined;
|
|
74
|
+
if (!isRecord(value)) throw badRequest('ragScope must be an object');
|
|
75
|
+
const fileIds = stringArray(value.fileIds, 'ragScope.fileIds');
|
|
76
|
+
const dirPaths = stringArray(value.dirPaths, 'ragScope.dirPaths');
|
|
77
|
+
if (fileIds === undefined && dirPaths === undefined) return undefined;
|
|
78
|
+
return {
|
|
79
|
+
...(fileIds ? { fileIds } : {}),
|
|
80
|
+
...(dirPaths ? { dirPaths } : {}),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import type { Response } from 'express';
|
|
2
|
-
import type { SSEEvent } from '@gt-fe/eap-sdk';
|
|
3
|
-
import { sendSseError } from '../errors.js';
|
|
4
|
-
|
|
5
|
-
export function beginSse(response: Response): void {
|
|
6
|
-
// 关闭代理缓存和响应缓冲,确保前端能实时收到每一帧 Runtime 事件。
|
|
7
|
-
response.status(200).set({
|
|
8
|
-
'Content-Type': 'text/event-stream; charset=utf-8',
|
|
9
|
-
'Cache-Control': 'no-cache, no-transform',
|
|
10
|
-
Connection: 'keep-alive',
|
|
11
|
-
'X-Accel-Buffering': 'no',
|
|
12
|
-
}).flushHeaders();
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function writeSseEvent(response: Response, event: SSEEvent): void {
|
|
16
|
-
// 保留 Runtime 原始事件类型,只补充前端调试所需的公共追踪字段。
|
|
17
|
-
if (response.destroyed) return;
|
|
18
|
-
response.write(`event: ${event.type}\ndata: ${JSON.stringify({ ...event.data, correlationId: event.correlationId, taskId: event.taskId, timestamp: event.timestamp })}\n\n`);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export async function pipeSse(response: Response, events: AsyncIterable<SSEEvent>): Promise<void> {
|
|
22
|
-
// 客户端断开时停止消费 Runtime 流,避免继续向已关闭的连接写数据。
|
|
23
|
-
try {
|
|
24
|
-
for await (const event of events) {
|
|
25
|
-
if (response.destroyed) break;
|
|
26
|
-
writeSseEvent(response, event);
|
|
27
|
-
}
|
|
28
|
-
if (!response.destroyed) response.end();
|
|
29
|
-
} catch (error) {
|
|
30
|
-
sendSseError(response, error);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
1
|
+
import type { Response } from 'express';
|
|
2
|
+
import type { SSEEvent } from '@gt-fe/eap-sdk';
|
|
3
|
+
import { sendSseError } from '../errors.js';
|
|
4
|
+
|
|
5
|
+
export function beginSse(response: Response): void {
|
|
6
|
+
// 关闭代理缓存和响应缓冲,确保前端能实时收到每一帧 Runtime 事件。
|
|
7
|
+
response.status(200).set({
|
|
8
|
+
'Content-Type': 'text/event-stream; charset=utf-8',
|
|
9
|
+
'Cache-Control': 'no-cache, no-transform',
|
|
10
|
+
Connection: 'keep-alive',
|
|
11
|
+
'X-Accel-Buffering': 'no',
|
|
12
|
+
}).flushHeaders();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function writeSseEvent(response: Response, event: SSEEvent): void {
|
|
16
|
+
// 保留 Runtime 原始事件类型,只补充前端调试所需的公共追踪字段。
|
|
17
|
+
if (response.destroyed) return;
|
|
18
|
+
response.write(`event: ${event.type}\ndata: ${JSON.stringify({ ...event.data, correlationId: event.correlationId, taskId: event.taskId, timestamp: event.timestamp })}\n\n`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export async function pipeSse(response: Response, events: AsyncIterable<SSEEvent>): Promise<void> {
|
|
22
|
+
// 客户端断开时停止消费 Runtime 流,避免继续向已关闭的连接写数据。
|
|
23
|
+
try {
|
|
24
|
+
for await (const event of events) {
|
|
25
|
+
if (response.destroyed) break;
|
|
26
|
+
writeSseEvent(response, event);
|
|
27
|
+
}
|
|
28
|
+
if (!response.destroyed) response.end();
|
|
29
|
+
} catch (error) {
|
|
30
|
+
sendSseError(response, error);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
export interface AgentRequestBody {
|
|
2
|
-
// HTTP 层只做宽松的 unknown 接收,字段转换集中在 shared/request.ts。
|
|
3
|
-
input?: unknown;
|
|
4
|
-
content?: unknown;
|
|
5
|
-
id?: unknown;
|
|
6
|
-
userId?: unknown;
|
|
7
|
-
title?: unknown;
|
|
8
|
-
metadata?: unknown;
|
|
9
|
-
sessionId?: unknown;
|
|
10
|
-
taskId?: unknown;
|
|
11
|
-
agentVersion?: unknown;
|
|
12
|
-
traceId?: unknown;
|
|
13
|
-
config?: unknown;
|
|
14
|
-
/** RAG 会话勾选的数据源 id 列表(透传给 AgentRequest.ragSources)。 */
|
|
15
|
-
ragSources?: unknown;
|
|
16
|
-
/** RAG 本地检索范围(透传给 AgentRequest.ragScope)。 */
|
|
17
|
-
ragScope?: unknown;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface AgentHttpStartOptions {
|
|
21
|
-
host?: string;
|
|
22
|
-
port?: number;
|
|
23
|
-
corsOrigin?: string;
|
|
24
|
-
maxBodyBytes?: number;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface ResolvedAgentHttpOptions {
|
|
28
|
-
host: string;
|
|
29
|
-
port: number;
|
|
30
|
-
corsOrigin: string;
|
|
31
|
-
maxBodyBytes: number;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export interface AgentHttpService {
|
|
35
|
-
app: import('express').Express;
|
|
36
|
-
server: import('node:http').Server;
|
|
37
|
-
address: string;
|
|
38
|
-
stop(): Promise<void>;
|
|
39
|
-
}
|
|
1
|
+
export interface AgentRequestBody {
|
|
2
|
+
// HTTP 层只做宽松的 unknown 接收,字段转换集中在 shared/request.ts。
|
|
3
|
+
input?: unknown;
|
|
4
|
+
content?: unknown;
|
|
5
|
+
id?: unknown;
|
|
6
|
+
userId?: unknown;
|
|
7
|
+
title?: unknown;
|
|
8
|
+
metadata?: unknown;
|
|
9
|
+
sessionId?: unknown;
|
|
10
|
+
taskId?: unknown;
|
|
11
|
+
agentVersion?: unknown;
|
|
12
|
+
traceId?: unknown;
|
|
13
|
+
config?: unknown;
|
|
14
|
+
/** RAG 会话勾选的数据源 id 列表(透传给 AgentRequest.ragSources)。 */
|
|
15
|
+
ragSources?: unknown;
|
|
16
|
+
/** RAG 本地检索范围(透传给 AgentRequest.ragScope)。 */
|
|
17
|
+
ragScope?: unknown;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface AgentHttpStartOptions {
|
|
21
|
+
host?: string;
|
|
22
|
+
port?: number;
|
|
23
|
+
corsOrigin?: string;
|
|
24
|
+
maxBodyBytes?: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface ResolvedAgentHttpOptions {
|
|
28
|
+
host: string;
|
|
29
|
+
port: number;
|
|
30
|
+
corsOrigin: string;
|
|
31
|
+
maxBodyBytes: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface AgentHttpService {
|
|
35
|
+
app: import('express').Express;
|
|
36
|
+
server: import('node:http').Server;
|
|
37
|
+
address: string;
|
|
38
|
+
stop(): Promise<void>;
|
|
39
|
+
}
|
|
@@ -1,91 +1,91 @@
|
|
|
1
|
-
import { config } from 'dotenv';
|
|
2
|
-
import { dirname, resolve } from 'node:path';
|
|
3
|
-
import { fileURLToPath } from 'node:url';
|
|
4
|
-
|
|
5
|
-
import { createEmbeddedAgent } from './embedded-agent.js';
|
|
6
|
-
import { startAgentHttpServer, type AgentHttpStartOptions } from './http/index.js';
|
|
7
|
-
import { createAgentResourceService, type AgentResourceService } from './http/services/resource-service.js';
|
|
8
|
-
export { createAgentApp, createAgentHttpServer, resolveAgentHttpStartOptions, startAgentHttpServer } from './http/index.js';
|
|
9
|
-
export type { AgentHttpStartOptions } from './http/index.js';
|
|
10
|
-
export { createEmbeddedAgent, createSdkTokenProvider } from './embedded-agent.js';
|
|
11
|
-
export type { EmbeddedAgentOptions } from './embedded-agent.js';
|
|
12
|
-
export { AgentResourceService, createAgentResourceService } from './http/services/resource-service.js';
|
|
13
|
-
export type { ResourceApplyAndReloadResult } from './http/services/resource-service.js';
|
|
14
|
-
|
|
15
|
-
// 入口文件的位置决定 Runtime 的相对路径,不依赖启动命令所在的当前目录。
|
|
16
|
-
const entryDirectory = dirname(fileURLToPath(import.meta.url));
|
|
17
|
-
const projectRoot = resolve(entryDirectory, '..');
|
|
18
|
-
// 统一读取项目根 .env。
|
|
19
|
-
config({ path: resolve(projectRoot, '.env') });
|
|
20
|
-
|
|
21
|
-
// 默认导出实例用于模板开发演示(npm run dev);生产宿主应调用
|
|
22
|
-
// createEmbeddedAgent({ credentialProvider }),显式注入凭证。
|
|
23
|
-
export const agent = await createEmbeddedAgent();
|
|
24
|
-
|
|
25
|
-
// 资源服务只负责编排 SDK manager;生产宿主通过 createEmbeddedAgent({ resourceManager }) 注入。
|
|
26
|
-
export const resourceService: AgentResourceService = createAgentResourceService(agent);
|
|
27
|
-
|
|
28
|
-
// Agent 事件是 Runtime 的权威 SSEEvent;这里仅做实时观测,不持久化 Trace。
|
|
29
|
-
const unsubscribe = agent.events.subscribe(undefined, (event) => {
|
|
30
|
-
console.log('[Agent 事件]', event.type, event.taskId, event.correlationId);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
console.log(`Agent API 已加载:${agent.target.agentCode}@${agent.target.version}`);
|
|
34
|
-
|
|
35
|
-
export function invoke(input: string, sessionId?: string) {
|
|
36
|
-
return agent.invoke(input, { sessionId });
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function stream(input: string, sessionId?: string) {
|
|
40
|
-
return agent.stream(input, {
|
|
41
|
-
sessionId,
|
|
42
|
-
onEvent(event) {
|
|
43
|
-
console.log('[流式事件]', event.type, event.taskId, event.correlationId);
|
|
44
|
-
},
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// 会话和消息 API 同时以进程内函数导出;默认启动时由 Express 路由映射为 HTTP 接口。
|
|
49
|
-
export function createSession(userId: string, title?: string) {
|
|
50
|
-
return agent.sessions.create({ userId, title });
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export function listSessions(userId: string, limit = 20, offset = 0) {
|
|
54
|
-
return agent.sessions.list({ userId, limit, offset });
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function archiveSession(sessionId: string) {
|
|
58
|
-
return agent.sessions.archive(sessionId);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export function restoreSession(sessionId: string) {
|
|
62
|
-
return agent.sessions.restore(sessionId);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export function listMessages(sessionId: string, limit = 100, offset = 0) {
|
|
66
|
-
return agent.messages.list(sessionId, { limit, offset });
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/** 启动面向前端智能体页面的 HTTP 服务;宿主也可以只 import Agent 自行挂载路由。 */
|
|
70
|
-
export async function startAgentService(options: AgentHttpStartOptions = {}) {
|
|
71
|
-
return startAgentHttpServer(agent, options);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (isDirectEntryPoint()) {
|
|
75
|
-
const service = await startAgentService();
|
|
76
|
-
console.log(`Agent 服务已启动:${service.address}`);
|
|
77
|
-
console.log(`能力描述:${service.address}/api/v1/agents/${agent.target.agentCode}`);
|
|
78
|
-
|
|
79
|
-
const shutdown = async () => {
|
|
80
|
-
unsubscribe();
|
|
81
|
-
await service.stop();
|
|
82
|
-
agent.dispose();
|
|
83
|
-
};
|
|
84
|
-
process.once('SIGINT', () => void shutdown());
|
|
85
|
-
process.once('SIGTERM', () => void shutdown());
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function isDirectEntryPoint(): boolean {
|
|
89
|
-
const entry = process.argv[1];
|
|
90
|
-
return Boolean(entry && resolve(entry) === resolve(fileURLToPath(import.meta.url)));
|
|
91
|
-
}
|
|
1
|
+
import { config } from 'dotenv';
|
|
2
|
+
import { dirname, resolve } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
|
|
5
|
+
import { createEmbeddedAgent } from './embedded-agent.js';
|
|
6
|
+
import { startAgentHttpServer, type AgentHttpStartOptions } from './http/index.js';
|
|
7
|
+
import { createAgentResourceService, type AgentResourceService } from './http/services/resource-service.js';
|
|
8
|
+
export { createAgentApp, createAgentHttpServer, resolveAgentHttpStartOptions, startAgentHttpServer } from './http/index.js';
|
|
9
|
+
export type { AgentHttpStartOptions } from './http/index.js';
|
|
10
|
+
export { createEmbeddedAgent, createSdkTokenProvider } from './embedded-agent.js';
|
|
11
|
+
export type { EmbeddedAgentOptions } from './embedded-agent.js';
|
|
12
|
+
export { AgentResourceService, createAgentResourceService } from './http/services/resource-service.js';
|
|
13
|
+
export type { ResourceApplyAndReloadResult } from './http/services/resource-service.js';
|
|
14
|
+
|
|
15
|
+
// 入口文件的位置决定 Runtime 的相对路径,不依赖启动命令所在的当前目录。
|
|
16
|
+
const entryDirectory = dirname(fileURLToPath(import.meta.url));
|
|
17
|
+
const projectRoot = resolve(entryDirectory, '..');
|
|
18
|
+
// 统一读取项目根 .env。
|
|
19
|
+
config({ path: resolve(projectRoot, '.env') });
|
|
20
|
+
|
|
21
|
+
// 默认导出实例用于模板开发演示(npm run dev);生产宿主应调用
|
|
22
|
+
// createEmbeddedAgent({ credentialProvider }),显式注入凭证。
|
|
23
|
+
export const agent = await createEmbeddedAgent();
|
|
24
|
+
|
|
25
|
+
// 资源服务只负责编排 SDK manager;生产宿主通过 createEmbeddedAgent({ resourceManager }) 注入。
|
|
26
|
+
export const resourceService: AgentResourceService = createAgentResourceService(agent);
|
|
27
|
+
|
|
28
|
+
// Agent 事件是 Runtime 的权威 SSEEvent;这里仅做实时观测,不持久化 Trace。
|
|
29
|
+
const unsubscribe = agent.events.subscribe(undefined, (event) => {
|
|
30
|
+
console.log('[Agent 事件]', event.type, event.taskId, event.correlationId);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
console.log(`Agent API 已加载:${agent.target.agentCode}@${agent.target.version}`);
|
|
34
|
+
|
|
35
|
+
export function invoke(input: string, sessionId?: string) {
|
|
36
|
+
return agent.invoke(input, { sessionId });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function stream(input: string, sessionId?: string) {
|
|
40
|
+
return agent.stream(input, {
|
|
41
|
+
sessionId,
|
|
42
|
+
onEvent(event) {
|
|
43
|
+
console.log('[流式事件]', event.type, event.taskId, event.correlationId);
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// 会话和消息 API 同时以进程内函数导出;默认启动时由 Express 路由映射为 HTTP 接口。
|
|
49
|
+
export function createSession(userId: string, title?: string) {
|
|
50
|
+
return agent.sessions.create({ userId, title });
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function listSessions(userId: string, limit = 20, offset = 0) {
|
|
54
|
+
return agent.sessions.list({ userId, limit, offset });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function archiveSession(sessionId: string) {
|
|
58
|
+
return agent.sessions.archive(sessionId);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function restoreSession(sessionId: string) {
|
|
62
|
+
return agent.sessions.restore(sessionId);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function listMessages(sessionId: string, limit = 100, offset = 0) {
|
|
66
|
+
return agent.messages.list(sessionId, { limit, offset });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** 启动面向前端智能体页面的 HTTP 服务;宿主也可以只 import Agent 自行挂载路由。 */
|
|
70
|
+
export async function startAgentService(options: AgentHttpStartOptions = {}) {
|
|
71
|
+
return startAgentHttpServer(agent, options);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (isDirectEntryPoint()) {
|
|
75
|
+
const service = await startAgentService();
|
|
76
|
+
console.log(`Agent 服务已启动:${service.address}`);
|
|
77
|
+
console.log(`能力描述:${service.address}/api/v1/agents/${agent.target.agentCode}`);
|
|
78
|
+
|
|
79
|
+
const shutdown = async () => {
|
|
80
|
+
unsubscribe();
|
|
81
|
+
await service.stop();
|
|
82
|
+
agent.dispose();
|
|
83
|
+
};
|
|
84
|
+
process.once('SIGINT', () => void shutdown());
|
|
85
|
+
process.once('SIGTERM', () => void shutdown());
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function isDirectEntryPoint(): boolean {
|
|
89
|
+
const entry = process.argv[1];
|
|
90
|
+
return Boolean(entry && resolve(entry) === resolve(fileURLToPath(import.meta.url)));
|
|
91
|
+
}
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createPlatformClient,
|
|
3
|
-
type PlatformIdentity,
|
|
4
|
-
} from '@gt-fe/eap-sdk';
|
|
5
|
-
import { dirname } from 'node:path';
|
|
6
|
-
import { fileURLToPath } from 'node:url';
|
|
7
|
-
|
|
8
|
-
import { loadTemplatePlatformConfig } from './project-config.js';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* 演示宿主已经拿到前端用户 Token 时,如何通过 SDK 查询用户信息。
|
|
12
|
-
*
|
|
13
|
-
* 这个函数只做平台信息查询,不是 Express 中间件,也不会替宿主做登录、
|
|
14
|
-
* 401 返回、租户绑定或业务权限判断。宿主可以在自己的路由层按需调用它。
|
|
15
|
-
*/
|
|
16
|
-
export async function resolveTokenUser(token: string): Promise<PlatformIdentity> {
|
|
17
|
-
const requestToken = token.trim();
|
|
18
|
-
if (!requestToken) throw new Error('token 不能为空');
|
|
19
|
-
|
|
20
|
-
const { portalEndpoint, foundationEndpoint } = loadTemplatePlatformConfig(
|
|
21
|
-
dirname(fileURLToPath(import.meta.url)),
|
|
22
|
-
);
|
|
23
|
-
if (!foundationEndpoint) {
|
|
24
|
-
throw new Error('请在 eap.config.json 的 platform.foundationServiceUrl 中配置 Foundation 地址后再查询 Token 用户信息');
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// PlatformClient 的 portalEndpoint 是必填配置;查询用户实际走 foundation。
|
|
28
|
-
const client = createPlatformClient({
|
|
29
|
-
portalEndpoint,
|
|
30
|
-
foundationEndpoint,
|
|
31
|
-
token: requestToken,
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
// SDK 会校验 Token 有效性、调用方类型,并返回 userId / roles / permissions。
|
|
35
|
-
return client.resolveTokenUser(requestToken);
|
|
36
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
createPlatformClient,
|
|
3
|
+
type PlatformIdentity,
|
|
4
|
+
} from '@gt-fe/eap-sdk';
|
|
5
|
+
import { dirname } from 'node:path';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
|
|
8
|
+
import { loadTemplatePlatformConfig } from './project-config.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 演示宿主已经拿到前端用户 Token 时,如何通过 SDK 查询用户信息。
|
|
12
|
+
*
|
|
13
|
+
* 这个函数只做平台信息查询,不是 Express 中间件,也不会替宿主做登录、
|
|
14
|
+
* 401 返回、租户绑定或业务权限判断。宿主可以在自己的路由层按需调用它。
|
|
15
|
+
*/
|
|
16
|
+
export async function resolveTokenUser(token: string): Promise<PlatformIdentity> {
|
|
17
|
+
const requestToken = token.trim();
|
|
18
|
+
if (!requestToken) throw new Error('token 不能为空');
|
|
19
|
+
|
|
20
|
+
const { portalEndpoint, foundationEndpoint } = loadTemplatePlatformConfig(
|
|
21
|
+
dirname(fileURLToPath(import.meta.url)),
|
|
22
|
+
);
|
|
23
|
+
if (!foundationEndpoint) {
|
|
24
|
+
throw new Error('请在 eap.config.json 的 platform.foundationServiceUrl 中配置 Foundation 地址后再查询 Token 用户信息');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// PlatformClient 的 portalEndpoint 是必填配置;查询用户实际走 foundation。
|
|
28
|
+
const client = createPlatformClient({
|
|
29
|
+
portalEndpoint,
|
|
30
|
+
foundationEndpoint,
|
|
31
|
+
token: requestToken,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// SDK 会校验 Token 有效性、调用方类型,并返回 userId / roles / permissions。
|
|
35
|
+
return client.resolveTokenUser(requestToken);
|
|
36
|
+
}
|
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
import {
|
|
2
|
-
loadAgentRuntime,
|
|
3
|
-
type LoadedAgentRuntime,
|
|
4
|
-
} from '@gt-fe/eap-sdk';
|
|
5
|
-
import { resolve } from 'node:path';
|
|
6
|
-
|
|
7
|
-
export interface TemplatePlatformConfig {
|
|
8
|
-
portalEndpoint: string;
|
|
9
|
-
foundationEndpoint?: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Runtime preparation puts config and lock files beside the materialized
|
|
14
|
-
* Agent manifest. Development and production therefore load the same tree.
|
|
15
|
-
*/
|
|
16
|
-
export function loadTemplateRuntime(
|
|
17
|
-
moduleDirectory: string,
|
|
18
|
-
runtimeRoot?: string,
|
|
19
|
-
): LoadedAgentRuntime {
|
|
20
|
-
return loadAgentRuntime({
|
|
21
|
-
runtimeRoot: runtimeRoot ?? resolveTemplateRuntimeRoot(moduleDirectory),
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function resolveTemplateRuntimeRoot(moduleDirectory: string): string {
|
|
26
|
-
const isDev = process.argv.includes('--dev');
|
|
27
|
-
const deploymentRoot = isDev ? resolve(moduleDirectory, '..') : moduleDirectory;
|
|
28
|
-
return resolve(
|
|
29
|
-
deploymentRoot,
|
|
30
|
-
process.env.EAP_RUNTIME_ROOT?.trim() || './.eap/runtime',
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function loadTemplatePlatformConfig(
|
|
35
|
-
moduleDirectory: string,
|
|
36
|
-
runtimeRoot?: string,
|
|
37
|
-
): TemplatePlatformConfig {
|
|
38
|
-
const { config } = loadTemplateRuntime(moduleDirectory, runtimeRoot);
|
|
39
|
-
const portalEndpoint = config.platform.portalUrl.trim();
|
|
40
|
-
const foundationEndpoint = config.platform.foundationServiceUrl?.trim() || undefined;
|
|
41
|
-
return {
|
|
42
|
-
portalEndpoint,
|
|
43
|
-
...(foundationEndpoint ? { foundationEndpoint } : {}),
|
|
44
|
-
};
|
|
45
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
loadAgentRuntime,
|
|
3
|
+
type LoadedAgentRuntime,
|
|
4
|
+
} from '@gt-fe/eap-sdk';
|
|
5
|
+
import { resolve } from 'node:path';
|
|
6
|
+
|
|
7
|
+
export interface TemplatePlatformConfig {
|
|
8
|
+
portalEndpoint: string;
|
|
9
|
+
foundationEndpoint?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Runtime preparation puts config and lock files beside the materialized
|
|
14
|
+
* Agent manifest. Development and production therefore load the same tree.
|
|
15
|
+
*/
|
|
16
|
+
export function loadTemplateRuntime(
|
|
17
|
+
moduleDirectory: string,
|
|
18
|
+
runtimeRoot?: string,
|
|
19
|
+
): LoadedAgentRuntime {
|
|
20
|
+
return loadAgentRuntime({
|
|
21
|
+
runtimeRoot: runtimeRoot ?? resolveTemplateRuntimeRoot(moduleDirectory),
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function resolveTemplateRuntimeRoot(moduleDirectory: string): string {
|
|
26
|
+
const isDev = process.argv.includes('--dev');
|
|
27
|
+
const deploymentRoot = isDev ? resolve(moduleDirectory, '..') : moduleDirectory;
|
|
28
|
+
return resolve(
|
|
29
|
+
deploymentRoot,
|
|
30
|
+
process.env.EAP_RUNTIME_ROOT?.trim() || './.eap/runtime',
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function loadTemplatePlatformConfig(
|
|
35
|
+
moduleDirectory: string,
|
|
36
|
+
runtimeRoot?: string,
|
|
37
|
+
): TemplatePlatformConfig {
|
|
38
|
+
const { config } = loadTemplateRuntime(moduleDirectory, runtimeRoot);
|
|
39
|
+
const portalEndpoint = config.platform.portalUrl.trim();
|
|
40
|
+
const foundationEndpoint = config.platform.foundationServiceUrl?.trim() || undefined;
|
|
41
|
+
return {
|
|
42
|
+
portalEndpoint,
|
|
43
|
+
...(foundationEndpoint ? { foundationEndpoint } : {}),
|
|
44
|
+
};
|
|
45
|
+
}
|