@gt-fe/eap-cli 0.2.11 → 0.2.13

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.
Files changed (75) hide show
  1. package/README.md +304 -304
  2. package/dist/static/playground/index.html +131 -131
  3. package/dist/static/playground/playground.css +209 -209
  4. package/dist/static/playground/playground.js +151 -151
  5. package/dist/static/playground-app/index.html +11 -11
  6. package/dist/templates/README.md +51 -51
  7. package/dist/templates/agent-api-orchestration/.env +16 -16
  8. package/dist/templates/agent-api-orchestration/README.md +326 -326
  9. package/dist/templates/agent-api-orchestration/agent.manifest.json +19 -19
  10. package/dist/templates/agent-api-orchestration/eap.config.json +1 -1
  11. package/dist/templates/agent-api-orchestration/eap.lock.yaml +5 -5
  12. package/dist/templates/agent-api-orchestration/gitignore +3 -3
  13. package/dist/templates/agent-api-orchestration/graph.json +35 -35
  14. package/dist/templates/agent-api-orchestration/package.json +2 -2
  15. package/dist/templates/agent-api-orchestration/scripts/api-test.mjs +443 -443
  16. package/dist/templates/agent-api-orchestration/scripts/build-runtime.mjs +26 -26
  17. package/dist/templates/agent-api-orchestration/scripts/validate.mjs +12 -12
  18. package/dist/templates/agent-api-orchestration/src/embedded-agent.ts +91 -91
  19. package/dist/templates/agent-api-orchestration/src/http/app.ts +58 -58
  20. package/dist/templates/agent-api-orchestration/src/http/config.ts +34 -34
  21. package/dist/templates/agent-api-orchestration/src/http/errors.ts +63 -63
  22. package/dist/templates/agent-api-orchestration/src/http/index.ts +4 -4
  23. package/dist/templates/agent-api-orchestration/src/http/middleware/cors.ts +17 -17
  24. package/dist/templates/agent-api-orchestration/src/http/routes/agent.ts +33 -33
  25. package/dist/templates/agent-api-orchestration/src/http/routes/health.ts +15 -15
  26. package/dist/templates/agent-api-orchestration/src/http/routes/invocations.ts +29 -29
  27. package/dist/templates/agent-api-orchestration/src/http/routes/sessions.ts +70 -70
  28. package/dist/templates/agent-api-orchestration/src/http/services/agent-service.ts +60 -60
  29. package/dist/templates/agent-api-orchestration/src/http/services/resource-service.ts +95 -95
  30. package/dist/templates/agent-api-orchestration/src/http/shared/request.ts +82 -82
  31. package/dist/templates/agent-api-orchestration/src/http/shared/sse.ts +32 -32
  32. package/dist/templates/agent-api-orchestration/src/http/types.ts +39 -39
  33. package/dist/templates/agent-api-orchestration/src/index.ts +91 -91
  34. package/dist/templates/agent-api-orchestration/src/platform-user.ts +36 -36
  35. package/dist/templates/agent-api-orchestration/src/project-config.ts +45 -45
  36. package/dist/templates/agent-api-orchestration/tsconfig.json +15 -15
  37. package/dist/templates/dag-workflow/README.md +102 -102
  38. package/dist/templates/dag-workflow/agent.manifest.json +19 -19
  39. package/dist/templates/dag-workflow/eap.config.json +1 -1
  40. package/dist/templates/dag-workflow/eap.lock.yaml +5 -5
  41. package/dist/templates/dag-workflow/gitignore +51 -51
  42. package/dist/templates/dag-workflow/graph.json +51 -51
  43. package/dist/templates/dag-workflow/package.json +10 -10
  44. package/dist/templates/dag-workflow/skills/README.md +116 -116
  45. package/dist/templates/plan-and-execute/README.md +109 -109
  46. package/dist/templates/plan-and-execute/agent.manifest.json +19 -19
  47. package/dist/templates/plan-and-execute/eap.config.json +1 -1
  48. package/dist/templates/plan-and-execute/eap.lock.yaml +5 -5
  49. package/dist/templates/plan-and-execute/gitignore +51 -51
  50. package/dist/templates/plan-and-execute/graph.json +49 -49
  51. package/dist/templates/plan-and-execute/package.json +10 -10
  52. package/dist/templates/plan-and-execute/skills/README.md +120 -120
  53. package/dist/templates/plan-and-execute/tools/echo-tool/src/index.js +17 -17
  54. package/dist/templates/plan-and-execute/tools/echo-tool/toolset.manifest.json +55 -55
  55. package/dist/templates/simple-flow/README.md +87 -87
  56. package/dist/templates/simple-flow/agent.manifest.json +19 -19
  57. package/dist/templates/simple-flow/eap.config.json +1 -1
  58. package/dist/templates/simple-flow/eap.lock.yaml +5 -5
  59. package/dist/templates/simple-flow/gitignore +51 -51
  60. package/dist/templates/simple-flow/graph.json +32 -32
  61. package/dist/templates/simple-flow/package.json +10 -10
  62. package/dist/templates/simple-flow/skills/README.md +113 -113
  63. package/dist/templates/single-agent-with-tools/README.md +138 -138
  64. package/dist/templates/single-agent-with-tools/agent.manifest.json +19 -19
  65. package/dist/templates/single-agent-with-tools/eap.config.json +1 -1
  66. package/dist/templates/single-agent-with-tools/eap.lock.yaml +5 -5
  67. package/dist/templates/single-agent-with-tools/gitignore +51 -51
  68. package/dist/templates/single-agent-with-tools/graph.json +41 -41
  69. package/dist/templates/single-agent-with-tools/package.json +10 -10
  70. package/dist/templates/single-agent-with-tools/skills/README.md +119 -119
  71. package/dist/templates/single-agent-with-tools/tools/echo-tool/src/index.js +17 -17
  72. package/dist/templates/single-agent-with-tools/tools/echo-tool/toolset.manifest.json +55 -55
  73. package/dist/templates/single-agent-with-tools/tools/http-weather/toolset.manifest.json +73 -73
  74. package/dist/templates/single-agent-with-tools/tools/web-search/toolset.manifest.json +41 -41
  75. package/package.json +3 -3
@@ -1,33 +1,33 @@
1
- import { Router } from 'express';
2
- import type { Agent } from '@gt-fe/eap-sdk';
3
- import { notFound } from '../errors.js';
4
- import { buildCapabilities } from '../services/agent-service.js';
5
- import { createInvocationRouter } from './invocations.js';
6
- import { createSessionRouter } from './sessions.js';
7
-
8
- export function createAgentRouter(agent: Agent): Router {
9
- const router = Router({ mergeParams: true });
10
-
11
- // 所有子路由共享同一个 Agent code 校验,避免错误 code 误调用当前 Agent。
12
- router.use((request, _response, next) => {
13
- if (request.params.agentCode !== agent.target.agentCode) return next(notFound('Agent not found'));
14
- next();
15
- });
16
-
17
- // 能力描述是前端页面的入口:页面可先发现版本、模型、工具和接口地址。
18
- router.get('/', (_request, response) => {
19
- response.json(buildCapabilities(agent));
20
- });
21
-
22
- // 这里故意不放鉴权中间件。调用方可以在挂载本 Router 前注入自己的鉴权、租户和审计逻辑。
23
- router.use(createInvocationRouter(agent));
24
- router.use('/sessions', createSessionRouter(agent));
25
- return router;
26
- }
27
-
28
- export function createAgentApiRouter(agent: Agent): Router {
29
- const router = Router();
30
- router.use('/:agentCode', createAgentRouter(agent));
31
- router.use((_request, _response, next) => next(notFound()));
32
- return router;
33
- }
1
+ import { Router } from 'express';
2
+ import type { Agent } from '@gt-fe/eap-sdk';
3
+ import { notFound } from '../errors.js';
4
+ import { buildCapabilities } from '../services/agent-service.js';
5
+ import { createInvocationRouter } from './invocations.js';
6
+ import { createSessionRouter } from './sessions.js';
7
+
8
+ export function createAgentRouter(agent: Agent): Router {
9
+ const router = Router({ mergeParams: true });
10
+
11
+ // 所有子路由共享同一个 Agent code 校验,避免错误 code 误调用当前 Agent。
12
+ router.use((request, _response, next) => {
13
+ if (request.params.agentCode !== agent.target.agentCode) return next(notFound('Agent not found'));
14
+ next();
15
+ });
16
+
17
+ // 能力描述是前端页面的入口:页面可先发现版本、模型、工具和接口地址。
18
+ router.get('/', (_request, response) => {
19
+ response.json(buildCapabilities(agent));
20
+ });
21
+
22
+ // 这里故意不放鉴权中间件。调用方可以在挂载本 Router 前注入自己的鉴权、租户和审计逻辑。
23
+ router.use(createInvocationRouter(agent));
24
+ router.use('/sessions', createSessionRouter(agent));
25
+ return router;
26
+ }
27
+
28
+ export function createAgentApiRouter(agent: Agent): Router {
29
+ const router = Router();
30
+ router.use('/:agentCode', createAgentRouter(agent));
31
+ router.use((_request, _response, next) => next(notFound()));
32
+ return router;
33
+ }
@@ -1,15 +1,15 @@
1
- import { Router } from 'express';
2
- import type { Agent } from '@gt-fe/eap-sdk';
3
-
4
- export function createHealthRouter(agent: Agent): Router {
5
- const router = Router();
6
- // 健康检查只报告进程和已加载 Agent 版本,不触发模型调用。
7
- router.get('/', (_request, response) => {
8
- response.json({
9
- status: 'ok',
10
- agentCode: agent.target.agentCode,
11
- version: agent.target.version,
12
- });
13
- });
14
- return router;
15
- }
1
+ import { Router } from 'express';
2
+ import type { Agent } from '@gt-fe/eap-sdk';
3
+
4
+ export function createHealthRouter(agent: Agent): Router {
5
+ const router = Router();
6
+ // 健康检查只报告进程和已加载 Agent 版本,不触发模型调用。
7
+ router.get('/', (_request, response) => {
8
+ response.json({
9
+ status: 'ok',
10
+ agentCode: agent.target.agentCode,
11
+ version: agent.target.version,
12
+ });
13
+ });
14
+ return router;
15
+ }
@@ -1,29 +1,29 @@
1
- import { Router } from 'express';
2
- import type { Agent } from '@gt-fe/eap-sdk';
3
- import { asyncRoute } from '../errors.js';
4
- import { messageInput } from '../services/agent-service.js';
5
- import { buildAgentRequest, requestBody, resolveSessionId, text } from '../shared/request.js';
6
- import { beginSse, pipeSse } from '../shared/sse.js';
7
-
8
- export function createInvocationRouter(agent: Agent): Router {
9
- const router = Router({ mergeParams: true });
10
-
11
- // 同步接口适合一次性拿完整结果;sessionId 可选,传入后由 Runtime 继续已有会话。
12
- router.post('/invoke', asyncRoute(async (request, response) => {
13
- const body = requestBody(request);
14
- const sessionId = resolveSessionId(undefined, text(body.sessionId));
15
- const input = messageInput(body as Record<string, unknown>);
16
- response.json(await agent.invoke(input, buildAgentRequest(request, body, sessionId)));
17
- }));
18
-
19
- // 流式接口原样转发 Runtime SSEEvent,前端可以逐帧渲染模型和工具事件。
20
- router.post('/stream', asyncRoute(async (request, response) => {
21
- const body = requestBody(request);
22
- const sessionId = resolveSessionId(undefined, text(body.sessionId));
23
- const input = messageInput(body as Record<string, unknown>);
24
- beginSse(response);
25
- await pipeSse(response, agent.stream(input, buildAgentRequest(request, body, sessionId)));
26
- }));
27
-
28
- return router;
29
- }
1
+ import { Router } from 'express';
2
+ import type { Agent } from '@gt-fe/eap-sdk';
3
+ import { asyncRoute } from '../errors.js';
4
+ import { messageInput } from '../services/agent-service.js';
5
+ import { buildAgentRequest, requestBody, resolveSessionId, text } from '../shared/request.js';
6
+ import { beginSse, pipeSse } from '../shared/sse.js';
7
+
8
+ export function createInvocationRouter(agent: Agent): Router {
9
+ const router = Router({ mergeParams: true });
10
+
11
+ // 同步接口适合一次性拿完整结果;sessionId 可选,传入后由 Runtime 继续已有会话。
12
+ router.post('/invoke', asyncRoute(async (request, response) => {
13
+ const body = requestBody(request);
14
+ const sessionId = resolveSessionId(undefined, text(body.sessionId));
15
+ const input = messageInput(body as Record<string, unknown>);
16
+ response.json(await agent.invoke(input, buildAgentRequest(request, body, sessionId)));
17
+ }));
18
+
19
+ // 流式接口原样转发 Runtime SSEEvent,前端可以逐帧渲染模型和工具事件。
20
+ router.post('/stream', asyncRoute(async (request, response) => {
21
+ const body = requestBody(request);
22
+ const sessionId = resolveSessionId(undefined, text(body.sessionId));
23
+ const input = messageInput(body as Record<string, unknown>);
24
+ beginSse(response);
25
+ await pipeSse(response, agent.stream(input, buildAgentRequest(request, body, sessionId)));
26
+ }));
27
+
28
+ return router;
29
+ }
@@ -1,70 +1,70 @@
1
- import { Router } from 'express';
2
- import type { Agent } from '@gt-fe/eap-sdk';
3
- import { asyncRoute } from '../errors.js';
4
- import { getSessionOrThrow, messageInput } from '../services/agent-service.js';
5
- import { beginSse, pipeSse } from '../shared/sse.js';
6
- import { buildAgentRequest, isRecord, pagination, requestBody, resolveSessionId, text } from '../shared/request.js';
7
-
8
- export function createSessionRouter(agent: Agent): Router {
9
- const router = Router({ mergeParams: true });
10
-
11
- // userId 只是会话记录上的业务字段,宿主可在自己的鉴权层决定它的取值。
12
- router.get('/', asyncRoute(async (request, response) => {
13
- const queryUserId = text(request.query.userId);
14
- response.json(await agent.sessions.list({
15
- ...(queryUserId ? { userId: queryUserId } : {}),
16
- ...pagination(request),
17
- }));
18
- }));
19
-
20
- // 创建会话不绑定登录态,方便模板直接连接前端页面或由宿主传入用户 ID。
21
- router.post('/', asyncRoute(async (request, response) => {
22
- const body = requestBody(request);
23
- const bodyUserId = text(body.userId);
24
- response.status(201).json(await agent.sessions.create({
25
- ...(text(body.id) ? { id: text(body.id) } : {}),
26
- ...(bodyUserId ? { userId: bodyUserId } : {}),
27
- ...(body.title !== undefined ? { title: text(body.title) ?? '' } : {}),
28
- ...(isRecord(body.metadata) ? { metadata: body.metadata } : {}),
29
- }));
30
- }));
31
-
32
- // 以下接口只负责会话和消息生命周期,不承担用户归属校验。
33
- router.get('/:sessionId', asyncRoute(async (request, response) => {
34
- response.json(await getSessionOrThrow(agent, request.params.sessionId));
35
- }));
36
-
37
- router.post('/:sessionId/archive', asyncRoute(async (request, response) => {
38
- await getSessionOrThrow(agent, request.params.sessionId);
39
- response.json(await agent.sessions.archive(request.params.sessionId));
40
- }));
41
-
42
- router.post('/:sessionId/restore', asyncRoute(async (request, response) => {
43
- await getSessionOrThrow(agent, request.params.sessionId);
44
- response.json(await agent.sessions.restore(request.params.sessionId));
45
- }));
46
-
47
- router.get('/:sessionId/messages', asyncRoute(async (request, response) => {
48
- await getSessionOrThrow(agent, request.params.sessionId);
49
- response.json(await agent.messages.list(request.params.sessionId, pagination(request)));
50
- }));
51
-
52
- router.post('/:sessionId/messages', asyncRoute(async (request, response) => {
53
- const sessionId = request.params.sessionId;
54
- await getSessionOrThrow(agent, sessionId);
55
- const body = requestBody(request);
56
- const input = messageInput(body as Record<string, unknown>);
57
- response.json(await agent.invoke(input, buildAgentRequest(request, body, resolveSessionId(sessionId, text(body.sessionId)))));
58
- }));
59
-
60
- router.post('/:sessionId/stream', asyncRoute(async (request, response) => {
61
- const sessionId = request.params.sessionId;
62
- await getSessionOrThrow(agent, sessionId);
63
- const body = requestBody(request);
64
- const input = messageInput(body as Record<string, unknown>);
65
- beginSse(response);
66
- await pipeSse(response, agent.stream(input, buildAgentRequest(request, body, resolveSessionId(sessionId, text(body.sessionId)))));
67
- }));
68
-
69
- return router;
70
- }
1
+ import { Router } from 'express';
2
+ import type { Agent } from '@gt-fe/eap-sdk';
3
+ import { asyncRoute } from '../errors.js';
4
+ import { getSessionOrThrow, messageInput } from '../services/agent-service.js';
5
+ import { beginSse, pipeSse } from '../shared/sse.js';
6
+ import { buildAgentRequest, isRecord, pagination, requestBody, resolveSessionId, text } from '../shared/request.js';
7
+
8
+ export function createSessionRouter(agent: Agent): Router {
9
+ const router = Router({ mergeParams: true });
10
+
11
+ // userId 只是会话记录上的业务字段,宿主可在自己的鉴权层决定它的取值。
12
+ router.get('/', asyncRoute(async (request, response) => {
13
+ const queryUserId = text(request.query.userId);
14
+ response.json(await agent.sessions.list({
15
+ ...(queryUserId ? { userId: queryUserId } : {}),
16
+ ...pagination(request),
17
+ }));
18
+ }));
19
+
20
+ // 创建会话不绑定登录态,方便模板直接连接前端页面或由宿主传入用户 ID。
21
+ router.post('/', asyncRoute(async (request, response) => {
22
+ const body = requestBody(request);
23
+ const bodyUserId = text(body.userId);
24
+ response.status(201).json(await agent.sessions.create({
25
+ ...(text(body.id) ? { id: text(body.id) } : {}),
26
+ ...(bodyUserId ? { userId: bodyUserId } : {}),
27
+ ...(body.title !== undefined ? { title: text(body.title) ?? '' } : {}),
28
+ ...(isRecord(body.metadata) ? { metadata: body.metadata } : {}),
29
+ }));
30
+ }));
31
+
32
+ // 以下接口只负责会话和消息生命周期,不承担用户归属校验。
33
+ router.get('/:sessionId', asyncRoute(async (request, response) => {
34
+ response.json(await getSessionOrThrow(agent, request.params.sessionId));
35
+ }));
36
+
37
+ router.post('/:sessionId/archive', asyncRoute(async (request, response) => {
38
+ await getSessionOrThrow(agent, request.params.sessionId);
39
+ response.json(await agent.sessions.archive(request.params.sessionId));
40
+ }));
41
+
42
+ router.post('/:sessionId/restore', asyncRoute(async (request, response) => {
43
+ await getSessionOrThrow(agent, request.params.sessionId);
44
+ response.json(await agent.sessions.restore(request.params.sessionId));
45
+ }));
46
+
47
+ router.get('/:sessionId/messages', asyncRoute(async (request, response) => {
48
+ await getSessionOrThrow(agent, request.params.sessionId);
49
+ response.json(await agent.messages.list(request.params.sessionId, pagination(request)));
50
+ }));
51
+
52
+ router.post('/:sessionId/messages', asyncRoute(async (request, response) => {
53
+ const sessionId = request.params.sessionId;
54
+ await getSessionOrThrow(agent, sessionId);
55
+ const body = requestBody(request);
56
+ const input = messageInput(body as Record<string, unknown>);
57
+ response.json(await agent.invoke(input, buildAgentRequest(request, body, resolveSessionId(sessionId, text(body.sessionId)))));
58
+ }));
59
+
60
+ router.post('/:sessionId/stream', asyncRoute(async (request, response) => {
61
+ const sessionId = request.params.sessionId;
62
+ await getSessionOrThrow(agent, sessionId);
63
+ const body = requestBody(request);
64
+ const input = messageInput(body as Record<string, unknown>);
65
+ beginSse(response);
66
+ await pipeSse(response, agent.stream(input, buildAgentRequest(request, body, resolveSessionId(sessionId, text(body.sessionId)))));
67
+ }));
68
+
69
+ return router;
70
+ }
@@ -1,60 +1,60 @@
1
- import { readFileSync } from 'node:fs';
2
- import type { Agent } from '@gt-fe/eap-sdk';
3
- import { badRequest, notFound } from '../errors.js';
4
- import { isRecord, text } from '../shared/request.js';
5
-
6
- export function buildCapabilities(agent: Agent): Record<string, unknown> {
7
- // 能力描述从物化后的 manifest/graph 读取,避免前端重复维护 Agent 配置。
8
- const manifest = readJsonFile(agent.target.manifestPath);
9
- const graph = readJsonFile(agent.target.graphPath);
10
- const manifestRecord = isRecord(manifest) ? manifest : {};
11
- const graphRecord = isRecord(graph) ? graph : {};
12
- const nodes = Array.isArray(graphRecord.nodes)
13
- ? graphRecord.nodes.filter(isRecord).map((node) => ({ id: node.id, type: node.type }))
14
- : [];
15
- const agentCode = encodeURIComponent(agent.target.agentCode);
16
- return {
17
- agent: {
18
- code: agent.target.agentCode,
19
- version: agent.target.version,
20
- name: text(manifestRecord.name) ?? agent.target.agentCode,
21
- description: text(manifestRecord.description) ?? '',
22
- models: manifestRecord.models ?? {},
23
- tools: Array.isArray(manifestRecord.toolRefs) ? manifestRecord.toolRefs : [],
24
- skills: Array.isArray(manifestRecord.skillRefs) ? manifestRecord.skillRefs : [],
25
- },
26
- capabilities: {
27
- invoke: true,
28
- stream: true,
29
- sessions: { create: true, list: true, get: true, archive: true, restore: false },
30
- messages: { list: true, send: true },
31
- },
32
- endpoints: {
33
- invoke: `/api/v1/agents/${agentCode}/invoke`,
34
- stream: `/api/v1/agents/${agentCode}/stream`,
35
- sessions: `/api/v1/agents/${agentCode}/sessions`,
36
- messages: `/api/v1/agents/${agentCode}/sessions/{sessionId}/messages`,
37
- },
38
- graph: { nodes },
39
- };
40
- }
41
-
42
- export async function getSessionOrThrow(agent: Agent, sessionId: string) {
43
- const session = await agent.sessions.get(sessionId);
44
- if (!session) throw notFound('Session not found');
45
- return session;
46
- }
47
-
48
- export function messageInput(body: Record<string, unknown>): string {
49
- const input = text(body.input) ?? text(body.content);
50
- if (!input) throw badRequest('Request body requires a non-empty input or content string');
51
- return input;
52
- }
53
-
54
- function readJsonFile(path: string): unknown {
55
- try {
56
- return JSON.parse(readFileSync(path, 'utf8'));
57
- } catch {
58
- return {};
59
- }
60
- }
1
+ import { readFileSync } from 'node:fs';
2
+ import type { Agent } from '@gt-fe/eap-sdk';
3
+ import { badRequest, notFound } from '../errors.js';
4
+ import { isRecord, text } from '../shared/request.js';
5
+
6
+ export function buildCapabilities(agent: Agent): Record<string, unknown> {
7
+ // 能力描述从物化后的 manifest/graph 读取,避免前端重复维护 Agent 配置。
8
+ const manifest = readJsonFile(agent.target.manifestPath);
9
+ const graph = readJsonFile(agent.target.graphPath);
10
+ const manifestRecord = isRecord(manifest) ? manifest : {};
11
+ const graphRecord = isRecord(graph) ? graph : {};
12
+ const nodes = Array.isArray(graphRecord.nodes)
13
+ ? graphRecord.nodes.filter(isRecord).map((node) => ({ id: node.id, type: node.type }))
14
+ : [];
15
+ const agentCode = encodeURIComponent(agent.target.agentCode);
16
+ return {
17
+ agent: {
18
+ code: agent.target.agentCode,
19
+ version: agent.target.version,
20
+ name: text(manifestRecord.name) ?? agent.target.agentCode,
21
+ description: text(manifestRecord.description) ?? '',
22
+ models: manifestRecord.models ?? {},
23
+ tools: Array.isArray(manifestRecord.toolRefs) ? manifestRecord.toolRefs : [],
24
+ skills: Array.isArray(manifestRecord.skillRefs) ? manifestRecord.skillRefs : [],
25
+ },
26
+ capabilities: {
27
+ invoke: true,
28
+ stream: true,
29
+ sessions: { create: true, list: true, get: true, archive: true, restore: false },
30
+ messages: { list: true, send: true },
31
+ },
32
+ endpoints: {
33
+ invoke: `/api/v1/agents/${agentCode}/invoke`,
34
+ stream: `/api/v1/agents/${agentCode}/stream`,
35
+ sessions: `/api/v1/agents/${agentCode}/sessions`,
36
+ messages: `/api/v1/agents/${agentCode}/sessions/{sessionId}/messages`,
37
+ },
38
+ graph: { nodes },
39
+ };
40
+ }
41
+
42
+ export async function getSessionOrThrow(agent: Agent, sessionId: string) {
43
+ const session = await agent.sessions.get(sessionId);
44
+ if (!session) throw notFound('Session not found');
45
+ return session;
46
+ }
47
+
48
+ export function messageInput(body: Record<string, unknown>): string {
49
+ const input = text(body.input) ?? text(body.content);
50
+ if (!input) throw badRequest('Request body requires a non-empty input or content string');
51
+ return input;
52
+ }
53
+
54
+ function readJsonFile(path: string): unknown {
55
+ try {
56
+ return JSON.parse(readFileSync(path, 'utf8'));
57
+ } catch {
58
+ return {};
59
+ }
60
+ }
@@ -1,95 +1,95 @@
1
- import type {
2
- Agent,
3
- AgentResourceManager,
4
- ResourceCatalogItem,
5
- AgentResourceState,
6
- ResourceActivationOptions,
7
- InstallResourceRequest,
8
- RefreshResourceRequest,
9
- ReloadResult,
10
- ResourceApplyOptions,
11
- ResourceChangeResult,
12
- ResourceMutationOptions,
13
- ResourceQuery,
14
- ResourceRef,
15
- } from '@gt-fe/eap-sdk';
16
-
17
- export interface ResourceApplyAndReloadResult {
18
- change: ResourceChangeResult;
19
- reload?: ReloadResult;
20
- }
21
-
22
- /**
23
- * Host-facing resource workflow. The SDK supplies the interface; the host
24
- * supplies the manager and decides when an effective Runtime may be replaced.
25
- */
26
- export class AgentResourceService {
27
- constructor(private readonly agent: Agent) {}
28
-
29
- get manager(): AgentResourceManager {
30
- return this.agent.resources;
31
- }
32
-
33
- listMarket(query?: ResourceQuery): Promise<ResourceCatalogItem[]> {
34
- return this.manager.listMarket(query);
35
- }
36
-
37
- listInstalled(query?: ResourceQuery): Promise<AgentResourceState[]> {
38
- return this.manager.listInstalled(query);
39
- }
40
-
41
- get(ref: ResourceRef): Promise<AgentResourceState | null> {
42
- return this.manager.get(ref);
43
- }
44
-
45
- install(request: InstallResourceRequest): Promise<ResourceChangeResult> {
46
- return this.manager.install(request);
47
- }
48
-
49
- update(request?: RefreshResourceRequest): Promise<ResourceChangeResult[]> {
50
- return this.manager.refresh(request);
51
- }
52
-
53
- uninstall(ref: ResourceRef, options?: ResourceMutationOptions): Promise<ResourceChangeResult> {
54
- return this.manager.uninstall(ref, options);
55
- }
56
-
57
- enable(ref: ResourceRef, options?: ResourceActivationOptions): Promise<ResourceChangeResult> {
58
- return this.manager.enable(ref, options);
59
- }
60
-
61
- disable(ref: ResourceRef, options?: ResourceActivationOptions): Promise<ResourceChangeResult> {
62
- return this.manager.disable(ref, options);
63
- }
64
-
65
- apply(options?: ResourceApplyOptions): Promise<ResourceChangeResult> {
66
- return this.manager.apply(options);
67
- }
68
-
69
- reload(): Promise<ReloadResult> {
70
- return this.agent.reload();
71
- }
72
-
73
- invalidate(ref?: ResourceRef): Promise<void> {
74
- return this.manager.invalidate(ref);
75
- }
76
-
77
- /**
78
- * Materializes the desired resource set without an implicit reload, then
79
- * explicitly switches the Agent when the manager reports that it is needed.
80
- */
81
- async applyAndReload(resources?: ResourceRef[]): Promise<ResourceApplyAndReloadResult> {
82
- const change = await this.manager.apply({
83
- ...(resources ? { resources } : {}),
84
- reload: false,
85
- });
86
- if (change.status === 'failed' || !change.requiresReload) return { change };
87
-
88
- const reload = await this.agent.reload();
89
- return { change, reload };
90
- }
91
- }
92
-
93
- export function createAgentResourceService(agent: Agent): AgentResourceService {
94
- return new AgentResourceService(agent);
95
- }
1
+ import type {
2
+ Agent,
3
+ AgentResourceManager,
4
+ ResourceCatalogItem,
5
+ AgentResourceState,
6
+ ResourceActivationOptions,
7
+ InstallResourceRequest,
8
+ RefreshResourceRequest,
9
+ ReloadResult,
10
+ ResourceApplyOptions,
11
+ ResourceChangeResult,
12
+ ResourceMutationOptions,
13
+ ResourceQuery,
14
+ ResourceRef,
15
+ } from '@gt-fe/eap-sdk';
16
+
17
+ export interface ResourceApplyAndReloadResult {
18
+ change: ResourceChangeResult;
19
+ reload?: ReloadResult;
20
+ }
21
+
22
+ /**
23
+ * Host-facing resource workflow. The SDK supplies the interface; the host
24
+ * supplies the manager and decides when an effective Runtime may be replaced.
25
+ */
26
+ export class AgentResourceService {
27
+ constructor(private readonly agent: Agent) {}
28
+
29
+ get manager(): AgentResourceManager {
30
+ return this.agent.resources;
31
+ }
32
+
33
+ listMarket(query?: ResourceQuery): Promise<ResourceCatalogItem[]> {
34
+ return this.manager.listMarket(query);
35
+ }
36
+
37
+ listInstalled(query?: ResourceQuery): Promise<AgentResourceState[]> {
38
+ return this.manager.listInstalled(query);
39
+ }
40
+
41
+ get(ref: ResourceRef): Promise<AgentResourceState | null> {
42
+ return this.manager.get(ref);
43
+ }
44
+
45
+ install(request: InstallResourceRequest): Promise<ResourceChangeResult> {
46
+ return this.manager.install(request);
47
+ }
48
+
49
+ update(request?: RefreshResourceRequest): Promise<ResourceChangeResult[]> {
50
+ return this.manager.refresh(request);
51
+ }
52
+
53
+ uninstall(ref: ResourceRef, options?: ResourceMutationOptions): Promise<ResourceChangeResult> {
54
+ return this.manager.uninstall(ref, options);
55
+ }
56
+
57
+ enable(ref: ResourceRef, options?: ResourceActivationOptions): Promise<ResourceChangeResult> {
58
+ return this.manager.enable(ref, options);
59
+ }
60
+
61
+ disable(ref: ResourceRef, options?: ResourceActivationOptions): Promise<ResourceChangeResult> {
62
+ return this.manager.disable(ref, options);
63
+ }
64
+
65
+ apply(options?: ResourceApplyOptions): Promise<ResourceChangeResult> {
66
+ return this.manager.apply(options);
67
+ }
68
+
69
+ reload(): Promise<ReloadResult> {
70
+ return this.agent.reload();
71
+ }
72
+
73
+ invalidate(ref?: ResourceRef): Promise<void> {
74
+ return this.manager.invalidate(ref);
75
+ }
76
+
77
+ /**
78
+ * Materializes the desired resource set without an implicit reload, then
79
+ * explicitly switches the Agent when the manager reports that it is needed.
80
+ */
81
+ async applyAndReload(resources?: ResourceRef[]): Promise<ResourceApplyAndReloadResult> {
82
+ const change = await this.manager.apply({
83
+ ...(resources ? { resources } : {}),
84
+ reload: false,
85
+ });
86
+ if (change.status === 'failed' || !change.requiresReload) return { change };
87
+
88
+ const reload = await this.agent.reload();
89
+ return { change, reload };
90
+ }
91
+ }
92
+
93
+ export function createAgentResourceService(agent: Agent): AgentResourceService {
94
+ return new AgentResourceService(agent);
95
+ }