@gt-fe/eap-runtime 0.0.10 → 0.0.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 +3 -3
- package/dist/api/handlers/invoke.handler.js +4 -0
- package/dist/api/handlers/stream.handler.js +4 -0
- package/dist/contracts/trace-collector.d.ts +1 -1
- package/dist/governance/governance-client.js +40 -16
- package/dist/governance/index.d.ts +1 -1
- package/dist/governance/index.js +1 -1
- package/dist/governance/permission-guard.d.ts +1 -0
- package/dist/governance/permission-guard.js +13 -4
- package/dist/graph/adapters/langgraph.adapter.js +11 -6
- package/dist/graph/contracts/executable-graph.d.ts +2 -0
- package/dist/graph/hitl/hitl-handler.d.ts +3 -0
- package/dist/graph/hitl/hitl-handler.js +4 -1
- package/dist/graph/nodes/tool-node.js +27 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/providers/echo-llm-provider.js +2 -2
- package/dist/registry/deployment-snapshot.d.ts +14 -2
- package/dist/registry/deployment-snapshot.js +56 -30
- package/dist/registry/graph-loader.js +4 -4
- package/dist/registry/index.d.ts +1 -1
- package/dist/registry/index.js +1 -1
- package/dist/runtime/agent-runtime.js +18 -4
- package/dist/runtime/dev-runtime.d.ts +1 -1
- package/dist/runtime/dev-runtime.js +6 -10
- package/dist/tool/dev-http-executor.js +9 -6
- package/dist/tool/dev-mcp-executor.js +5 -3
- package/dist/tool/dev-tool-executor.d.ts +1 -1
- package/dist/tool/dev-tool-executor.js +2 -2
- package/dist/tool/harness-command.d.ts +32 -0
- package/dist/tool/harness-command.js +276 -0
- package/dist/tool/harness-primitives.d.ts +25 -3
- package/dist/tool/harness-primitives.js +156 -49
- package/dist/tool/http-tool-executor.js +15 -20
- package/dist/tool/index.d.ts +3 -2
- package/dist/tool/index.js +3 -2
- package/dist/tool/local-mcp-client.js +54 -23
- package/dist/tool/local-tool-executor.js +13 -9
- package/dist/tool/mcp-tool-executor.js +14 -6
- package/dist/tool/skill-script-refs.d.ts +20 -0
- package/dist/tool/skill-script-refs.js +62 -0
- package/dist/tool/system-prompt-builder.d.ts +2 -2
- package/dist/tool/system-prompt-builder.js +7 -4
- package/dist/tool/timeout.d.ts +14 -0
- package/dist/tool/timeout.js +36 -0
- package/dist/tool/tool-confirmation.js +2 -1
- package/dist/tool/tool-executor.interface.d.ts +13 -3
- package/dist/tool/tool-orchestrator.d.ts +1 -1
- package/dist/tool/tool-orchestrator.js +6 -3
- package/package.json +3 -3
- package/dist/common/concurrency.d.ts +0 -79
- package/dist/common/concurrency.js +0 -121
- package/dist/common/queue-consumer.d.ts +0 -125
- package/dist/common/queue-consumer.js +0 -159
- package/dist/tool/mock-tool-executor.d.ts +0 -28
- package/dist/tool/mock-tool-executor.js +0 -65
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RabbitMQ 队列消费者
|
|
3
|
-
*
|
|
4
|
-
* 从 RabbitMQ 队列中消费任务消息,分发给 Graph 引擎处理。
|
|
5
|
-
* 通过 channel.prefetch(n) 控制并发:
|
|
6
|
-
* - 最多同时处理 n 条未 ack 的消息
|
|
7
|
-
* - 超出 prefetch 限制的消息留在 RabbitMQ Queue 中排队等待
|
|
8
|
-
* - 不丢弃任何请求
|
|
9
|
-
*
|
|
10
|
-
* 整体 QPS = Pod 数 × prefetch
|
|
11
|
-
*
|
|
12
|
-
* @see Requirement 14 AC2: 系统通过消息消费者 prefetch 参数控制单 Agent 实例的并发上限
|
|
13
|
-
* @see Requirement 14 AC3: 并发请求数超过 prefetch 限制时,系统将超出请求放入 Queue 排队等待,不丢弃请求
|
|
14
|
-
*/
|
|
15
|
-
import type { Connection } from 'amqplib';
|
|
16
|
-
/**
|
|
17
|
-
* 任务消息体 — 从 RabbitMQ 队列中消费到的任务负载
|
|
18
|
-
*/
|
|
19
|
-
export interface TaskMessage {
|
|
20
|
-
/** 任务唯一标识 */
|
|
21
|
-
taskId: string;
|
|
22
|
-
/** 目标 Agent(值为 agentCode;字段名保留 agentId 兼容存量消息) */
|
|
23
|
-
agentId: string;
|
|
24
|
-
/** 会话 ID */
|
|
25
|
-
sessionId: string;
|
|
26
|
-
/** 发起请求的用户 ID */
|
|
27
|
-
userId: string;
|
|
28
|
-
/** 用户输入内容 */
|
|
29
|
-
input: string;
|
|
30
|
-
/** 可选的执行配置 */
|
|
31
|
-
config?: Record<string, unknown>;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* 任务处理器 — 接收解析后的 TaskMessage,分发给 Graph 引擎执行
|
|
35
|
-
*
|
|
36
|
-
* 处理成功则 resolve,失败则 reject(消费者据此决定 ack/nack)。
|
|
37
|
-
*/
|
|
38
|
-
export type TaskHandler = (message: TaskMessage) => Promise<void>;
|
|
39
|
-
/**
|
|
40
|
-
* QueueConsumer 配置选项
|
|
41
|
-
*/
|
|
42
|
-
export interface QueueConsumerOptions {
|
|
43
|
-
/** 队列名称 */
|
|
44
|
-
queueName: string;
|
|
45
|
-
/** prefetch 数量 — 单实例最大并发消息处理数,默认 5 */
|
|
46
|
-
prefetch?: number;
|
|
47
|
-
/** 队列是否持久化,默认 true */
|
|
48
|
-
durable?: boolean;
|
|
49
|
-
/** 是否自动确认(不推荐生产使用),默认 false */
|
|
50
|
-
noAck?: boolean;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* RabbitMQ 队列消费者
|
|
54
|
-
*
|
|
55
|
-
* 核心设计:利用 RabbitMQ channel.prefetch 机制实现队列式溢出控制。
|
|
56
|
-
* - consumer.prefetch(5) → 该 Channel 上最多持有 5 条未 ack 消息
|
|
57
|
-
* - 第 6 条及后续消息自动留在 RabbitMQ Queue 中排队
|
|
58
|
-
* - 只有当某条消息被 ack/nack 后,RabbitMQ 才推送下一条
|
|
59
|
-
* - 保证不丢弃任何请求(queue-based overflow)
|
|
60
|
-
*
|
|
61
|
-
* 使用方式:
|
|
62
|
-
* ```ts
|
|
63
|
-
* const consumer = new QueueConsumer(connection, {
|
|
64
|
-
* queueName: 'agent.tasks.ai-bi',
|
|
65
|
-
* prefetch: 5,
|
|
66
|
-
* }, async (msg) => {
|
|
67
|
-
* await graphEngine.execute(msg);
|
|
68
|
-
* });
|
|
69
|
-
*
|
|
70
|
-
* await consumer.start();
|
|
71
|
-
* // ... 优雅关闭
|
|
72
|
-
* await consumer.stop();
|
|
73
|
-
* ```
|
|
74
|
-
*/
|
|
75
|
-
export declare class QueueConsumer {
|
|
76
|
-
private readonly connection;
|
|
77
|
-
private readonly options;
|
|
78
|
-
private readonly taskHandler;
|
|
79
|
-
private channel;
|
|
80
|
-
private consumerTag;
|
|
81
|
-
private started;
|
|
82
|
-
/**
|
|
83
|
-
* @param connection amqplib Connection 实例
|
|
84
|
-
* @param options 消费者配置
|
|
85
|
-
* @param taskHandler 任务处理函数 — 接收解析后的消息,分发给 Graph 引擎
|
|
86
|
-
*/
|
|
87
|
-
constructor(connection: Connection, options: QueueConsumerOptions, taskHandler: TaskHandler);
|
|
88
|
-
/**
|
|
89
|
-
* 启动消费者
|
|
90
|
-
*
|
|
91
|
-
* 1. 创建 Channel
|
|
92
|
-
* 2. 设置 prefetch(限制并发)
|
|
93
|
-
* 3. 声明队列(确保队列存在)
|
|
94
|
-
* 4. 开始消费消息
|
|
95
|
-
*
|
|
96
|
-
* prefetch 机制保证:超出限制的消息留在 RabbitMQ Queue 排队,不丢弃。
|
|
97
|
-
*/
|
|
98
|
-
start(): Promise<void>;
|
|
99
|
-
/**
|
|
100
|
-
* 停止消费者并优雅关闭 Channel
|
|
101
|
-
*
|
|
102
|
-
* 1. 取消消费(不再接收新消息)
|
|
103
|
-
* 2. 关闭 Channel
|
|
104
|
-
*
|
|
105
|
-
* 已在处理中的消息不受影响,会正常完成后 ack/nack。
|
|
106
|
-
*/
|
|
107
|
-
stop(): Promise<void>;
|
|
108
|
-
/**
|
|
109
|
-
* 是否正在运行
|
|
110
|
-
*/
|
|
111
|
-
get isRunning(): boolean;
|
|
112
|
-
/**
|
|
113
|
-
* 获取配置的 prefetch 值
|
|
114
|
-
*/
|
|
115
|
-
get prefetch(): number;
|
|
116
|
-
/**
|
|
117
|
-
* 处理单条消息
|
|
118
|
-
*
|
|
119
|
-
* - 解析消息体为 TaskMessage
|
|
120
|
-
* - 调用 taskHandler 执行任务
|
|
121
|
-
* - 成功 → ack(释放 prefetch 槽位,RabbitMQ 推送下一条)
|
|
122
|
-
* - 失败 → nack + requeue(消息重新入队,稍后重试)
|
|
123
|
-
*/
|
|
124
|
-
private handleMessage;
|
|
125
|
-
}
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RabbitMQ 队列消费者
|
|
3
|
-
*
|
|
4
|
-
* 从 RabbitMQ 队列中消费任务消息,分发给 Graph 引擎处理。
|
|
5
|
-
* 通过 channel.prefetch(n) 控制并发:
|
|
6
|
-
* - 最多同时处理 n 条未 ack 的消息
|
|
7
|
-
* - 超出 prefetch 限制的消息留在 RabbitMQ Queue 中排队等待
|
|
8
|
-
* - 不丢弃任何请求
|
|
9
|
-
*
|
|
10
|
-
* 整体 QPS = Pod 数 × prefetch
|
|
11
|
-
*
|
|
12
|
-
* @see Requirement 14 AC2: 系统通过消息消费者 prefetch 参数控制单 Agent 实例的并发上限
|
|
13
|
-
* @see Requirement 14 AC3: 并发请求数超过 prefetch 限制时,系统将超出请求放入 Queue 排队等待,不丢弃请求
|
|
14
|
-
*/
|
|
15
|
-
// ─────────────────────────────────────────────
|
|
16
|
-
// QueueConsumer
|
|
17
|
-
// ─────────────────────────────────────────────
|
|
18
|
-
/** 默认 prefetch 值 */
|
|
19
|
-
const DEFAULT_PREFETCH = 5;
|
|
20
|
-
/**
|
|
21
|
-
* RabbitMQ 队列消费者
|
|
22
|
-
*
|
|
23
|
-
* 核心设计:利用 RabbitMQ channel.prefetch 机制实现队列式溢出控制。
|
|
24
|
-
* - consumer.prefetch(5) → 该 Channel 上最多持有 5 条未 ack 消息
|
|
25
|
-
* - 第 6 条及后续消息自动留在 RabbitMQ Queue 中排队
|
|
26
|
-
* - 只有当某条消息被 ack/nack 后,RabbitMQ 才推送下一条
|
|
27
|
-
* - 保证不丢弃任何请求(queue-based overflow)
|
|
28
|
-
*
|
|
29
|
-
* 使用方式:
|
|
30
|
-
* ```ts
|
|
31
|
-
* const consumer = new QueueConsumer(connection, {
|
|
32
|
-
* queueName: 'agent.tasks.ai-bi',
|
|
33
|
-
* prefetch: 5,
|
|
34
|
-
* }, async (msg) => {
|
|
35
|
-
* await graphEngine.execute(msg);
|
|
36
|
-
* });
|
|
37
|
-
*
|
|
38
|
-
* await consumer.start();
|
|
39
|
-
* // ... 优雅关闭
|
|
40
|
-
* await consumer.stop();
|
|
41
|
-
* ```
|
|
42
|
-
*/
|
|
43
|
-
export class QueueConsumer {
|
|
44
|
-
connection;
|
|
45
|
-
options;
|
|
46
|
-
taskHandler;
|
|
47
|
-
channel = null;
|
|
48
|
-
consumerTag = null;
|
|
49
|
-
started = false;
|
|
50
|
-
/**
|
|
51
|
-
* @param connection amqplib Connection 实例
|
|
52
|
-
* @param options 消费者配置
|
|
53
|
-
* @param taskHandler 任务处理函数 — 接收解析后的消息,分发给 Graph 引擎
|
|
54
|
-
*/
|
|
55
|
-
constructor(connection, options, taskHandler) {
|
|
56
|
-
this.connection = connection;
|
|
57
|
-
this.options = {
|
|
58
|
-
queueName: options.queueName,
|
|
59
|
-
prefetch: options.prefetch ?? DEFAULT_PREFETCH,
|
|
60
|
-
durable: options.durable ?? true,
|
|
61
|
-
noAck: options.noAck ?? false,
|
|
62
|
-
};
|
|
63
|
-
this.taskHandler = taskHandler;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* 启动消费者
|
|
67
|
-
*
|
|
68
|
-
* 1. 创建 Channel
|
|
69
|
-
* 2. 设置 prefetch(限制并发)
|
|
70
|
-
* 3. 声明队列(确保队列存在)
|
|
71
|
-
* 4. 开始消费消息
|
|
72
|
-
*
|
|
73
|
-
* prefetch 机制保证:超出限制的消息留在 RabbitMQ Queue 排队,不丢弃。
|
|
74
|
-
*/
|
|
75
|
-
async start() {
|
|
76
|
-
if (this.started) {
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
// 1. 创建 Channel
|
|
80
|
-
this.channel = await this.connection.createChannel();
|
|
81
|
-
// 2. 设置 prefetch — 核心并发控制
|
|
82
|
-
// 超出 prefetch 的消息留在 Queue 中排队等待(queue-based overflow)
|
|
83
|
-
await this.channel.prefetch(this.options.prefetch);
|
|
84
|
-
// 3. 声明队列(幂等操作,队列已存在则不做修改)
|
|
85
|
-
await this.channel.assertQueue(this.options.queueName, {
|
|
86
|
-
durable: this.options.durable,
|
|
87
|
-
});
|
|
88
|
-
// 4. 开始消费
|
|
89
|
-
const { consumerTag } = await this.channel.consume(this.options.queueName, (msg) => this.handleMessage(msg), { noAck: this.options.noAck });
|
|
90
|
-
this.consumerTag = consumerTag;
|
|
91
|
-
this.started = true;
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* 停止消费者并优雅关闭 Channel
|
|
95
|
-
*
|
|
96
|
-
* 1. 取消消费(不再接收新消息)
|
|
97
|
-
* 2. 关闭 Channel
|
|
98
|
-
*
|
|
99
|
-
* 已在处理中的消息不受影响,会正常完成后 ack/nack。
|
|
100
|
-
*/
|
|
101
|
-
async stop() {
|
|
102
|
-
if (!this.started || !this.channel) {
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
// 取消消费者
|
|
106
|
-
if (this.consumerTag) {
|
|
107
|
-
await this.channel.cancel(this.consumerTag);
|
|
108
|
-
this.consumerTag = null;
|
|
109
|
-
}
|
|
110
|
-
// 关闭 Channel
|
|
111
|
-
await this.channel.close();
|
|
112
|
-
this.channel = null;
|
|
113
|
-
this.started = false;
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* 是否正在运行
|
|
117
|
-
*/
|
|
118
|
-
get isRunning() {
|
|
119
|
-
return this.started;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* 获取配置的 prefetch 值
|
|
123
|
-
*/
|
|
124
|
-
get prefetch() {
|
|
125
|
-
return this.options.prefetch;
|
|
126
|
-
}
|
|
127
|
-
// ─── 内部方法 ───────────────────────────────
|
|
128
|
-
/**
|
|
129
|
-
* 处理单条消息
|
|
130
|
-
*
|
|
131
|
-
* - 解析消息体为 TaskMessage
|
|
132
|
-
* - 调用 taskHandler 执行任务
|
|
133
|
-
* - 成功 → ack(释放 prefetch 槽位,RabbitMQ 推送下一条)
|
|
134
|
-
* - 失败 → nack + requeue(消息重新入队,稍后重试)
|
|
135
|
-
*/
|
|
136
|
-
async handleMessage(msg) {
|
|
137
|
-
// RabbitMQ 在 Channel 关闭时会发送 null
|
|
138
|
-
if (!msg || !this.channel) {
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
try {
|
|
142
|
-
// 解析消息体
|
|
143
|
-
const body = msg.content.toString('utf-8');
|
|
144
|
-
const taskMessage = JSON.parse(body);
|
|
145
|
-
// 分发给 Graph 引擎处理
|
|
146
|
-
await this.taskHandler(taskMessage);
|
|
147
|
-
// 处理成功 → ack,释放 prefetch 槽位
|
|
148
|
-
if (!this.options.noAck) {
|
|
149
|
-
this.channel.ack(msg);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
catch {
|
|
153
|
-
// 处理失败 → nack,requeue=true 让消息重新排队
|
|
154
|
-
if (!this.options.noAck && this.channel) {
|
|
155
|
-
this.channel.nack(msg, false, true);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MockToolExecutor — 本地开发模式的模拟 Tool 执行器
|
|
3
|
-
*
|
|
4
|
-
* 定位:`eap dev --tool-mode mock` 场景下替代真实 Gateway/Local 执行器,
|
|
5
|
-
* 让 Agent 开发者在无 foundation-service、无真实 Tool 依赖的前提下跑通 Graph。
|
|
6
|
-
*
|
|
7
|
-
* 响应查找顺序:
|
|
8
|
-
* 1. `${toolsDir}/<toolName>/mock.json`(用户自定义 Mock 响应)
|
|
9
|
-
* 2. `${toolsDir}/<toolName>/tool.manifest.json` 内嵌 `mockResponse` 字段
|
|
10
|
-
* 3. 兜底 echo:`{ toolName, arguments, note: "mock" }`
|
|
11
|
-
*
|
|
12
|
-
* 使用示例:
|
|
13
|
-
* const executor = new MockToolExecutor({ toolsDir: './tools' });
|
|
14
|
-
*/
|
|
15
|
-
import type { IToolExecutor, ToolCallRequest, ToolCallResult } from './tool-executor.interface.js';
|
|
16
|
-
export interface MockToolExecutorOptions {
|
|
17
|
-
/** 本地 tools 根目录,默认 `./tools` 或读 `EAP_LOCAL_TOOLS_DIR` */
|
|
18
|
-
toolsDir?: string;
|
|
19
|
-
/** Mock 响应可自定义 delay,用于验证 SSE/流式表现 */
|
|
20
|
-
delayMs?: number;
|
|
21
|
-
}
|
|
22
|
-
export declare class MockToolExecutor implements IToolExecutor {
|
|
23
|
-
private readonly toolsDir;
|
|
24
|
-
private readonly delayMs;
|
|
25
|
-
constructor(options?: MockToolExecutorOptions);
|
|
26
|
-
execute(request: ToolCallRequest): Promise<ToolCallResult>;
|
|
27
|
-
private resolveMockResponse;
|
|
28
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MockToolExecutor — 本地开发模式的模拟 Tool 执行器
|
|
3
|
-
*
|
|
4
|
-
* 定位:`eap dev --tool-mode mock` 场景下替代真实 Gateway/Local 执行器,
|
|
5
|
-
* 让 Agent 开发者在无 foundation-service、无真实 Tool 依赖的前提下跑通 Graph。
|
|
6
|
-
*
|
|
7
|
-
* 响应查找顺序:
|
|
8
|
-
* 1. `${toolsDir}/<toolName>/mock.json`(用户自定义 Mock 响应)
|
|
9
|
-
* 2. `${toolsDir}/<toolName>/tool.manifest.json` 内嵌 `mockResponse` 字段
|
|
10
|
-
* 3. 兜底 echo:`{ toolName, arguments, note: "mock" }`
|
|
11
|
-
*
|
|
12
|
-
* 使用示例:
|
|
13
|
-
* const executor = new MockToolExecutor({ toolsDir: './tools' });
|
|
14
|
-
*/
|
|
15
|
-
import { readFile } from 'node:fs/promises';
|
|
16
|
-
import path from 'node:path';
|
|
17
|
-
async function readJsonFile(filePath) {
|
|
18
|
-
try {
|
|
19
|
-
const raw = await readFile(filePath, 'utf-8');
|
|
20
|
-
return JSON.parse(raw);
|
|
21
|
-
}
|
|
22
|
-
catch {
|
|
23
|
-
return undefined;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
export class MockToolExecutor {
|
|
27
|
-
toolsDir;
|
|
28
|
-
delayMs;
|
|
29
|
-
constructor(options = {}) {
|
|
30
|
-
this.toolsDir =
|
|
31
|
-
options.toolsDir ?? process.env.EAP_LOCAL_TOOLS_DIR ?? './tools';
|
|
32
|
-
this.delayMs = options.delayMs ?? 0;
|
|
33
|
-
}
|
|
34
|
-
async execute(request) {
|
|
35
|
-
if (this.delayMs > 0) {
|
|
36
|
-
await new Promise((r) => setTimeout(r, this.delayMs));
|
|
37
|
-
}
|
|
38
|
-
const mockResponse = await this.resolveMockResponse(request.toolName);
|
|
39
|
-
const payload = mockResponse ?? {
|
|
40
|
-
toolName: request.toolName,
|
|
41
|
-
arguments: request.arguments,
|
|
42
|
-
note: 'mock: no explicit mockResponse found, echoing arguments',
|
|
43
|
-
};
|
|
44
|
-
return {
|
|
45
|
-
toolCallId: request.toolCallId,
|
|
46
|
-
toolName: request.toolName,
|
|
47
|
-
content: typeof payload === 'string' ? payload : JSON.stringify(payload),
|
|
48
|
-
success: true,
|
|
49
|
-
runtime: 'mock',
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
async resolveMockResponse(toolName) {
|
|
53
|
-
const toolDir = path.join(this.toolsDir, toolName);
|
|
54
|
-
// 优先级 1:独立 mock.json
|
|
55
|
-
const explicit = await readJsonFile(path.join(toolDir, 'mock.json'));
|
|
56
|
-
if (explicit !== undefined)
|
|
57
|
-
return explicit;
|
|
58
|
-
// 优先级 2:manifest 内嵌 mockResponse
|
|
59
|
-
const manifest = (await readJsonFile(path.join(toolDir, 'tool.manifest.json')));
|
|
60
|
-
if (manifest && manifest.mockResponse !== undefined) {
|
|
61
|
-
return manifest.mockResponse;
|
|
62
|
-
}
|
|
63
|
-
return undefined;
|
|
64
|
-
}
|
|
65
|
-
}
|