triflux 10.2.0 → 10.3.0
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 +236 -156
- package/hub/bridge.mjs +638 -290
- package/hub/codex-compat.mjs +1 -1
- package/hub/fullcycle.mjs +1 -1
- package/hub/intent.mjs +1 -0
- package/hub/lib/mcp-response-cache.mjs +205 -0
- package/hub/pipe.mjs +228 -119
- package/hub/reflexion.mjs +87 -13
- package/hub/research.mjs +1 -0
- package/hub/server.mjs +997 -611
- package/hub/team/ansi.mjs +1 -1
- package/hub/team/conductor-registry.mjs +121 -0
- package/hub/team/conductor.mjs +256 -125
- package/hub/team/execution-mode.mjs +105 -0
- package/hub/team/headless.mjs +686 -252
- package/hub/team/lead-control.mjs +91 -4
- package/hub/team/mcp-selector.mjs +145 -0
- package/hub/team/session-sync.mjs +153 -6
- package/hub/team/swarm-hypervisor.mjs +208 -86
- package/hub/team/tui-lite.mjs +18 -2
- package/hub/token-mode.mjs +1 -0
- package/hub/tools.mjs +474 -252
- package/package.json +5 -5
- package/scripts/codex-gateway-preflight.mjs +133 -0
- package/scripts/codex-mcp-gateway-sync.mjs +199 -0
- package/skills/star-prompt/SKILL.md +169 -69
- package/skills/tfx-setup/SKILL.md +124 -0
- package/skills/tfx-swarm/SKILL.md +124 -72
package/hub/tools.mjs
CHANGED
|
@@ -2,22 +2,20 @@
|
|
|
2
2
|
// register/status/publish/ask/poll/handoff/HITL + team proxy
|
|
3
3
|
// 모든 도구 응답: { ok: boolean, error?: { code, message }, data?: ... }
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { createPipeline, ensurePipelineTable } from "./pipeline/index.mjs";
|
|
6
6
|
import {
|
|
7
|
-
ensurePipelineTable,
|
|
8
|
-
createPipeline,
|
|
9
|
-
} from './pipeline/index.mjs';
|
|
10
|
-
import {
|
|
11
|
-
readPipelineState,
|
|
12
7
|
initPipelineState,
|
|
13
8
|
listPipelineStates,
|
|
14
|
-
|
|
9
|
+
readPipelineState,
|
|
10
|
+
} from "./pipeline/state.mjs";
|
|
11
|
+
import { sendInputToConductorSession } from "./team/conductor-registry.mjs";
|
|
12
|
+
import { getTeamBridge } from "./team-bridge.mjs";
|
|
15
13
|
|
|
16
|
-
const TEAM_BRIDGE_NOT_REGISTERED =
|
|
14
|
+
const TEAM_BRIDGE_NOT_REGISTERED = "bridge_not_registered";
|
|
17
15
|
|
|
18
16
|
function getTeamBridgeMethod(methodName) {
|
|
19
17
|
const method = getTeamBridge()?.[methodName];
|
|
20
|
-
return typeof method ===
|
|
18
|
+
return typeof method === "function" ? method : null;
|
|
21
19
|
}
|
|
22
20
|
|
|
23
21
|
function teamInfoFallback(args = {}) {
|
|
@@ -86,7 +84,7 @@ function teamSendMessageFallback(args = {}) {
|
|
|
86
84
|
ok: true,
|
|
87
85
|
data: {
|
|
88
86
|
message_id: null,
|
|
89
|
-
recipient: args.to ??
|
|
87
|
+
recipient: args.to ?? "team-lead",
|
|
90
88
|
inbox_file: null,
|
|
91
89
|
queued_at: null,
|
|
92
90
|
unread_count: 0,
|
|
@@ -110,10 +108,13 @@ export function createTools(store, router, hitl, pipe = null) {
|
|
|
110
108
|
return async (args) => {
|
|
111
109
|
try {
|
|
112
110
|
const result = await fn(args);
|
|
113
|
-
return { content: [{ type:
|
|
111
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
114
112
|
} catch (e) {
|
|
115
113
|
const err = { ok: false, error: { code, message: e.message } };
|
|
116
|
-
return {
|
|
114
|
+
return {
|
|
115
|
+
content: [{ type: "text", text: JSON.stringify(err) }],
|
|
116
|
+
isError: true,
|
|
117
|
+
};
|
|
117
118
|
}
|
|
118
119
|
};
|
|
119
120
|
}
|
|
@@ -121,22 +122,37 @@ export function createTools(store, router, hitl, pipe = null) {
|
|
|
121
122
|
return [
|
|
122
123
|
// ── 1. register ──
|
|
123
124
|
{
|
|
124
|
-
name:
|
|
125
|
-
description:
|
|
125
|
+
name: "register",
|
|
126
|
+
description: "에이전트를 허브에 등록하고 lease를 발급받습니다",
|
|
126
127
|
inputSchema: {
|
|
127
|
-
type:
|
|
128
|
-
required: [
|
|
128
|
+
type: "object",
|
|
129
|
+
required: [
|
|
130
|
+
"agent_id",
|
|
131
|
+
"cli",
|
|
132
|
+
"capabilities",
|
|
133
|
+
"topics",
|
|
134
|
+
"heartbeat_ttl_ms",
|
|
135
|
+
],
|
|
129
136
|
properties: {
|
|
130
|
-
agent_id:
|
|
131
|
-
cli:
|
|
132
|
-
pid:
|
|
133
|
-
capabilities:
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
+
agent_id: { type: "string", pattern: "^[a-zA-Z0-9._:-]{3,64}$" },
|
|
138
|
+
cli: { type: "string", enum: ["codex", "gemini", "claude", "other"] },
|
|
139
|
+
pid: { type: "integer", minimum: 1 },
|
|
140
|
+
capabilities: {
|
|
141
|
+
type: "array",
|
|
142
|
+
items: { type: "string" },
|
|
143
|
+
minItems: 1,
|
|
144
|
+
maxItems: 64,
|
|
145
|
+
},
|
|
146
|
+
topics: { type: "array", items: { type: "string" }, maxItems: 64 },
|
|
147
|
+
metadata: { type: "object" },
|
|
148
|
+
heartbeat_ttl_ms: {
|
|
149
|
+
type: "integer",
|
|
150
|
+
minimum: 10000,
|
|
151
|
+
maximum: 7200000,
|
|
152
|
+
},
|
|
137
153
|
},
|
|
138
154
|
},
|
|
139
|
-
handler: wrap(
|
|
155
|
+
handler: wrap("REGISTER_FAILED", (args) => {
|
|
140
156
|
const data = router.registerAgent(args);
|
|
141
157
|
return { ok: true, data };
|
|
142
158
|
}),
|
|
@@ -144,88 +160,128 @@ export function createTools(store, router, hitl, pipe = null) {
|
|
|
144
160
|
|
|
145
161
|
// ── 2. status ──
|
|
146
162
|
{
|
|
147
|
-
name:
|
|
148
|
-
description:
|
|
163
|
+
name: "status",
|
|
164
|
+
description: "허브, 에이전트, 큐, 트레이스 상태를 조회합니다",
|
|
149
165
|
inputSchema: {
|
|
150
|
-
type:
|
|
166
|
+
type: "object",
|
|
151
167
|
properties: {
|
|
152
|
-
scope:
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
168
|
+
scope: {
|
|
169
|
+
type: "string",
|
|
170
|
+
enum: ["hub", "agent", "queue", "trace"],
|
|
171
|
+
default: "hub",
|
|
172
|
+
},
|
|
173
|
+
agent_id: { type: "string" },
|
|
174
|
+
trace_id: { type: "string" },
|
|
175
|
+
include_metrics: { type: "boolean", default: true },
|
|
156
176
|
},
|
|
157
177
|
},
|
|
158
|
-
handler: wrap(
|
|
159
|
-
return router.getStatus(args.scope ||
|
|
178
|
+
handler: wrap("STATUS_FAILED", (args) => {
|
|
179
|
+
return router.getStatus(args.scope || "hub", args);
|
|
160
180
|
}),
|
|
161
181
|
},
|
|
162
182
|
|
|
163
183
|
// ── 3. publish ──
|
|
164
184
|
{
|
|
165
|
-
name:
|
|
166
|
-
description:
|
|
185
|
+
name: "publish",
|
|
186
|
+
description:
|
|
187
|
+
'이벤트 또는 응답 메시지를 발행합니다. to에 "topic:XXX" 지정 시 구독자 전체 fanout',
|
|
167
188
|
inputSchema: {
|
|
168
|
-
type:
|
|
169
|
-
required: [
|
|
189
|
+
type: "object",
|
|
190
|
+
required: ["from", "to", "topic", "payload"],
|
|
170
191
|
properties: {
|
|
171
|
-
from:
|
|
172
|
-
to:
|
|
173
|
-
topic:
|
|
174
|
-
priority:
|
|
175
|
-
ttl_ms:
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
192
|
+
from: { type: "string", pattern: "^[a-zA-Z0-9._:-]{3,64}$" },
|
|
193
|
+
to: { type: "string" },
|
|
194
|
+
topic: { type: "string", pattern: "^[a-zA-Z0-9._:-]+$" },
|
|
195
|
+
priority: { type: "integer", minimum: 1, maximum: 9, default: 5 },
|
|
196
|
+
ttl_ms: {
|
|
197
|
+
type: "integer",
|
|
198
|
+
minimum: 1000,
|
|
199
|
+
maximum: 86400000,
|
|
200
|
+
default: 300000,
|
|
201
|
+
},
|
|
202
|
+
payload: { type: "object" },
|
|
203
|
+
trace_id: { type: "string" },
|
|
204
|
+
correlation_id: { type: "string" },
|
|
179
205
|
},
|
|
180
206
|
},
|
|
181
|
-
handler: wrap(
|
|
207
|
+
handler: wrap("PUBLISH_FAILED", (args) => {
|
|
182
208
|
return router.handlePublish(args);
|
|
183
209
|
}),
|
|
184
210
|
},
|
|
185
211
|
|
|
186
212
|
// ── 4. ask ──
|
|
187
213
|
{
|
|
188
|
-
name:
|
|
189
|
-
description:
|
|
214
|
+
name: "ask",
|
|
215
|
+
description:
|
|
216
|
+
"다른 에이전트에게 질문합니다. await_response_ms > 0이면 짧은 폴링으로 응답 대기",
|
|
190
217
|
inputSchema: {
|
|
191
|
-
type:
|
|
192
|
-
required: [
|
|
218
|
+
type: "object",
|
|
219
|
+
required: ["from", "to", "topic", "question"],
|
|
193
220
|
properties: {
|
|
194
|
-
from:
|
|
195
|
-
to:
|
|
196
|
-
topic:
|
|
197
|
-
question:
|
|
198
|
-
context_refs:
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
221
|
+
from: { type: "string", pattern: "^[a-zA-Z0-9._:-]{3,64}$" },
|
|
222
|
+
to: { type: "string" },
|
|
223
|
+
topic: { type: "string", pattern: "^[a-zA-Z0-9._:-]+$" },
|
|
224
|
+
question: { type: "string", minLength: 1, maxLength: 20000 },
|
|
225
|
+
context_refs: {
|
|
226
|
+
type: "array",
|
|
227
|
+
items: { type: "string" },
|
|
228
|
+
maxItems: 32,
|
|
229
|
+
},
|
|
230
|
+
payload: { type: "object" },
|
|
231
|
+
priority: { type: "integer", minimum: 1, maximum: 9, default: 5 },
|
|
232
|
+
ttl_ms: {
|
|
233
|
+
type: "integer",
|
|
234
|
+
minimum: 1000,
|
|
235
|
+
maximum: 86400000,
|
|
236
|
+
default: 300000,
|
|
237
|
+
},
|
|
238
|
+
await_response_ms: {
|
|
239
|
+
type: "integer",
|
|
240
|
+
minimum: 0,
|
|
241
|
+
maximum: 30000,
|
|
242
|
+
default: 0,
|
|
243
|
+
},
|
|
244
|
+
trace_id: { type: "string" },
|
|
245
|
+
correlation_id: { type: "string" },
|
|
205
246
|
},
|
|
206
247
|
},
|
|
207
|
-
handler: wrap(
|
|
248
|
+
handler: wrap("ASK_FAILED", async (args) => {
|
|
208
249
|
return await router.handleAsk(args);
|
|
209
250
|
}),
|
|
210
251
|
},
|
|
211
252
|
|
|
212
253
|
// ── 5. poll_messages ──
|
|
213
254
|
{
|
|
214
|
-
name:
|
|
215
|
-
description:
|
|
255
|
+
name: "poll_messages",
|
|
256
|
+
description:
|
|
257
|
+
"Deprecated. poll_messages 대신 Named Pipe subscribe/publish 채널을 사용합니다",
|
|
216
258
|
inputSchema: {
|
|
217
|
-
type:
|
|
218
|
-
required: [
|
|
259
|
+
type: "object",
|
|
260
|
+
required: ["agent_id"],
|
|
219
261
|
properties: {
|
|
220
|
-
agent_id:
|
|
221
|
-
wait_ms:
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
262
|
+
agent_id: { type: "string", pattern: "^[a-zA-Z0-9._:-]{3,64}$" },
|
|
263
|
+
wait_ms: {
|
|
264
|
+
type: "integer",
|
|
265
|
+
minimum: 0,
|
|
266
|
+
maximum: 30000,
|
|
267
|
+
default: 1000,
|
|
268
|
+
},
|
|
269
|
+
max_messages: {
|
|
270
|
+
type: "integer",
|
|
271
|
+
minimum: 1,
|
|
272
|
+
maximum: 100,
|
|
273
|
+
default: 20,
|
|
274
|
+
},
|
|
275
|
+
include_topics: {
|
|
276
|
+
type: "array",
|
|
277
|
+
items: { type: "string" },
|
|
278
|
+
maxItems: 64,
|
|
279
|
+
},
|
|
280
|
+
ack_ids: { type: "array", items: { type: "string" }, maxItems: 100 },
|
|
281
|
+
auto_ack: { type: "boolean", default: false },
|
|
226
282
|
},
|
|
227
283
|
},
|
|
228
|
-
handler: wrap(
|
|
284
|
+
handler: wrap("POLL_DEPRECATED", async (args) => {
|
|
229
285
|
const replay = router.drainAgent(args.agent_id, {
|
|
230
286
|
max_messages: args.max_messages,
|
|
231
287
|
include_topics: args.include_topics,
|
|
@@ -237,13 +293,14 @@ export function createTools(store, router, hitl, pipe = null) {
|
|
|
237
293
|
return {
|
|
238
294
|
ok: false,
|
|
239
295
|
error: {
|
|
240
|
-
code:
|
|
241
|
-
message:
|
|
296
|
+
code: "POLL_DEPRECATED",
|
|
297
|
+
message:
|
|
298
|
+
"poll_messages는 deprecated 되었습니다. pipe subscribe/publish 채널을 사용하세요.",
|
|
242
299
|
},
|
|
243
300
|
data: {
|
|
244
301
|
pipe_path: pipe?.path || null,
|
|
245
|
-
delivery_mode:
|
|
246
|
-
protocol:
|
|
302
|
+
delivery_mode: "pipe_push",
|
|
303
|
+
protocol: "ndjson",
|
|
247
304
|
replay: {
|
|
248
305
|
messages: replay,
|
|
249
306
|
count: replay.length,
|
|
@@ -256,275 +313,394 @@ export function createTools(store, router, hitl, pipe = null) {
|
|
|
256
313
|
|
|
257
314
|
// ── 6. handoff ──
|
|
258
315
|
{
|
|
259
|
-
name:
|
|
260
|
-
description:
|
|
316
|
+
name: "handoff",
|
|
317
|
+
description:
|
|
318
|
+
"다른 에이전트에게 작업을 인계합니다. acceptance_criteria로 완료 기준 지정 가능",
|
|
261
319
|
inputSchema: {
|
|
262
|
-
type:
|
|
263
|
-
required: [
|
|
320
|
+
type: "object",
|
|
321
|
+
required: ["from", "to", "topic", "task"],
|
|
264
322
|
properties: {
|
|
265
|
-
from:
|
|
266
|
-
to:
|
|
267
|
-
topic:
|
|
268
|
-
task:
|
|
269
|
-
acceptance_criteria: {
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
323
|
+
from: { type: "string", pattern: "^[a-zA-Z0-9._:-]{3,64}$" },
|
|
324
|
+
to: { type: "string" },
|
|
325
|
+
topic: { type: "string", pattern: "^[a-zA-Z0-9._:-]+$" },
|
|
326
|
+
task: { type: "string", minLength: 1, maxLength: 20000 },
|
|
327
|
+
acceptance_criteria: {
|
|
328
|
+
type: "array",
|
|
329
|
+
items: { type: "string" },
|
|
330
|
+
maxItems: 32,
|
|
331
|
+
},
|
|
332
|
+
context_refs: {
|
|
333
|
+
type: "array",
|
|
334
|
+
items: { type: "string" },
|
|
335
|
+
maxItems: 32,
|
|
336
|
+
},
|
|
337
|
+
priority: { type: "integer", minimum: 1, maximum: 9, default: 5 },
|
|
338
|
+
ttl_ms: {
|
|
339
|
+
type: "integer",
|
|
340
|
+
minimum: 1000,
|
|
341
|
+
maximum: 86400000,
|
|
342
|
+
default: 600000,
|
|
343
|
+
},
|
|
344
|
+
trace_id: { type: "string" },
|
|
345
|
+
correlation_id: { type: "string" },
|
|
275
346
|
},
|
|
276
347
|
},
|
|
277
|
-
handler: wrap(
|
|
348
|
+
handler: wrap("HANDOFF_FAILED", (args) => {
|
|
278
349
|
return router.handleHandoff(args);
|
|
279
350
|
}),
|
|
280
351
|
},
|
|
281
352
|
|
|
282
353
|
// ── 7. assign_async ──
|
|
283
354
|
{
|
|
284
|
-
name:
|
|
285
|
-
description:
|
|
355
|
+
name: "assign_async",
|
|
356
|
+
description:
|
|
357
|
+
"AWS CAO 스타일 비차단 assign job을 생성하고 워커에게 실시간 전달합니다",
|
|
286
358
|
inputSchema: {
|
|
287
|
-
type:
|
|
288
|
-
required: [
|
|
359
|
+
type: "object",
|
|
360
|
+
required: ["supervisor_agent", "worker_agent", "task"],
|
|
289
361
|
properties: {
|
|
290
|
-
supervisor_agent: {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
362
|
+
supervisor_agent: {
|
|
363
|
+
type: "string",
|
|
364
|
+
pattern: "^[a-zA-Z0-9._:-]{3,64}$",
|
|
365
|
+
},
|
|
366
|
+
worker_agent: { type: "string", pattern: "^[a-zA-Z0-9._:-]{3,64}$" },
|
|
367
|
+
topic: {
|
|
368
|
+
type: "string",
|
|
369
|
+
pattern: "^[a-zA-Z0-9._:-]+$",
|
|
370
|
+
default: "assign.job",
|
|
371
|
+
},
|
|
372
|
+
task: { type: "string", minLength: 1, maxLength: 20000 },
|
|
373
|
+
payload: { type: "object" },
|
|
374
|
+
priority: { type: "integer", minimum: 1, maximum: 9, default: 5 },
|
|
375
|
+
ttl_ms: {
|
|
376
|
+
type: "integer",
|
|
377
|
+
minimum: 1000,
|
|
378
|
+
maximum: 86400000,
|
|
379
|
+
default: 600000,
|
|
380
|
+
},
|
|
381
|
+
timeout_ms: {
|
|
382
|
+
type: "integer",
|
|
383
|
+
minimum: 1000,
|
|
384
|
+
maximum: 86400000,
|
|
385
|
+
default: 600000,
|
|
386
|
+
},
|
|
387
|
+
max_retries: { type: "integer", minimum: 0, maximum: 20, default: 0 },
|
|
388
|
+
trace_id: { type: "string" },
|
|
389
|
+
correlation_id: { type: "string" },
|
|
301
390
|
},
|
|
302
391
|
},
|
|
303
|
-
handler: wrap(
|
|
392
|
+
handler: wrap("ASSIGN_ASYNC_FAILED", (args) => {
|
|
304
393
|
return router.assignAsync(args);
|
|
305
394
|
}),
|
|
306
395
|
},
|
|
307
396
|
|
|
308
397
|
// ── 8. assign_result ──
|
|
309
398
|
{
|
|
310
|
-
name:
|
|
311
|
-
description:
|
|
399
|
+
name: "assign_result",
|
|
400
|
+
description:
|
|
401
|
+
"assign job의 진행/완료 결과를 보고합니다. completed + metadata.result 관례를 지원합니다",
|
|
312
402
|
inputSchema: {
|
|
313
|
-
type:
|
|
314
|
-
required: [
|
|
403
|
+
type: "object",
|
|
404
|
+
required: ["job_id", "status"],
|
|
315
405
|
properties: {
|
|
316
|
-
job_id: { type:
|
|
317
|
-
worker_agent: { type:
|
|
318
|
-
status: {
|
|
319
|
-
|
|
406
|
+
job_id: { type: "string", minLength: 1, maxLength: 128 },
|
|
407
|
+
worker_agent: { type: "string", pattern: "^[a-zA-Z0-9._:-]{3,64}$" },
|
|
408
|
+
status: {
|
|
409
|
+
type: "string",
|
|
410
|
+
enum: [
|
|
411
|
+
"queued",
|
|
412
|
+
"running",
|
|
413
|
+
"in_progress",
|
|
414
|
+
"completed",
|
|
415
|
+
"succeeded",
|
|
416
|
+
"success",
|
|
417
|
+
"failed",
|
|
418
|
+
"error",
|
|
419
|
+
"timed_out",
|
|
420
|
+
"timeout",
|
|
421
|
+
],
|
|
422
|
+
},
|
|
423
|
+
attempt: { type: "integer", minimum: 1 },
|
|
320
424
|
result: {},
|
|
321
425
|
error: {},
|
|
322
|
-
metadata: { type:
|
|
323
|
-
payload: { type:
|
|
426
|
+
metadata: { type: "object" },
|
|
427
|
+
payload: { type: "object" },
|
|
324
428
|
},
|
|
325
429
|
},
|
|
326
|
-
handler: wrap(
|
|
430
|
+
handler: wrap("ASSIGN_RESULT_FAILED", (args) => {
|
|
327
431
|
return router.reportAssignResult(args);
|
|
328
432
|
}),
|
|
329
433
|
},
|
|
330
434
|
|
|
331
435
|
// ── 9. assign_status ──
|
|
332
436
|
{
|
|
333
|
-
name:
|
|
334
|
-
description:
|
|
437
|
+
name: "assign_status",
|
|
438
|
+
description:
|
|
439
|
+
"assign job 단건 상태 또는 supervisor/worker/status 기준 목록을 조회합니다",
|
|
335
440
|
inputSchema: {
|
|
336
|
-
type:
|
|
441
|
+
type: "object",
|
|
337
442
|
properties: {
|
|
338
|
-
job_id: { type:
|
|
339
|
-
supervisor_agent: {
|
|
340
|
-
|
|
341
|
-
|
|
443
|
+
job_id: { type: "string", minLength: 1, maxLength: 128 },
|
|
444
|
+
supervisor_agent: {
|
|
445
|
+
type: "string",
|
|
446
|
+
pattern: "^[a-zA-Z0-9._:-]{3,64}$",
|
|
447
|
+
},
|
|
448
|
+
worker_agent: { type: "string", pattern: "^[a-zA-Z0-9._:-]{3,64}$" },
|
|
449
|
+
status: {
|
|
450
|
+
type: "string",
|
|
451
|
+
enum: ["queued", "running", "succeeded", "failed", "timed_out"],
|
|
452
|
+
},
|
|
342
453
|
statuses: {
|
|
343
|
-
type:
|
|
344
|
-
items: {
|
|
454
|
+
type: "array",
|
|
455
|
+
items: {
|
|
456
|
+
type: "string",
|
|
457
|
+
enum: ["queued", "running", "succeeded", "failed", "timed_out"],
|
|
458
|
+
},
|
|
345
459
|
maxItems: 8,
|
|
346
460
|
},
|
|
347
|
-
trace_id: { type:
|
|
348
|
-
correlation_id: { type:
|
|
349
|
-
limit: { type:
|
|
461
|
+
trace_id: { type: "string" },
|
|
462
|
+
correlation_id: { type: "string" },
|
|
463
|
+
limit: { type: "integer", minimum: 1, maximum: 100, default: 50 },
|
|
350
464
|
},
|
|
351
465
|
},
|
|
352
|
-
handler: wrap(
|
|
466
|
+
handler: wrap("ASSIGN_STATUS_FAILED", (args) => {
|
|
353
467
|
return router.getAssignStatus(args);
|
|
354
468
|
}),
|
|
355
469
|
},
|
|
356
470
|
|
|
357
471
|
// ── 10. request_human_input ──
|
|
358
472
|
{
|
|
359
|
-
name:
|
|
360
|
-
description:
|
|
473
|
+
name: "request_human_input",
|
|
474
|
+
description:
|
|
475
|
+
"사용자에게 입력을 요청합니다 (CAPTCHA, 승인, 자격증명, 선택, 텍스트)",
|
|
361
476
|
inputSchema: {
|
|
362
|
-
type:
|
|
363
|
-
required: [
|
|
477
|
+
type: "object",
|
|
478
|
+
required: [
|
|
479
|
+
"requester_agent",
|
|
480
|
+
"kind",
|
|
481
|
+
"prompt",
|
|
482
|
+
"requested_schema",
|
|
483
|
+
"deadline_ms",
|
|
484
|
+
"default_action",
|
|
485
|
+
],
|
|
364
486
|
properties: {
|
|
365
|
-
requester_agent:
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
487
|
+
requester_agent: {
|
|
488
|
+
type: "string",
|
|
489
|
+
pattern: "^[a-zA-Z0-9._:-]{3,64}$",
|
|
490
|
+
},
|
|
491
|
+
kind: {
|
|
492
|
+
type: "string",
|
|
493
|
+
enum: ["captcha", "approval", "credential", "choice", "text"],
|
|
494
|
+
},
|
|
495
|
+
prompt: { type: "string", minLength: 1, maxLength: 20000 },
|
|
496
|
+
requested_schema: { type: "object" },
|
|
497
|
+
deadline_ms: { type: "integer", minimum: 1000 },
|
|
498
|
+
default_action: {
|
|
499
|
+
type: "string",
|
|
500
|
+
enum: ["decline", "cancel", "timeout_continue"],
|
|
501
|
+
},
|
|
502
|
+
channel_preference: {
|
|
503
|
+
type: "string",
|
|
504
|
+
enum: ["terminal", "pipe", "file_polling"],
|
|
505
|
+
default: "terminal",
|
|
506
|
+
},
|
|
507
|
+
trace_id: { type: "string" },
|
|
508
|
+
correlation_id: { type: "string" },
|
|
374
509
|
},
|
|
375
510
|
},
|
|
376
|
-
handler: wrap(
|
|
511
|
+
handler: wrap("HITL_REQUEST_FAILED", (args) => {
|
|
377
512
|
return hitl.requestHumanInput(args);
|
|
378
513
|
}),
|
|
379
514
|
},
|
|
380
515
|
|
|
381
516
|
// ── 11. submit_human_input ──
|
|
382
517
|
{
|
|
383
|
-
name:
|
|
384
|
-
description:
|
|
518
|
+
name: "submit_human_input",
|
|
519
|
+
description: "사용자 입력 요청에 응답합니다 (accept, decline, cancel)",
|
|
385
520
|
inputSchema: {
|
|
386
|
-
type:
|
|
387
|
-
required: [
|
|
521
|
+
type: "object",
|
|
522
|
+
required: ["request_id", "action"],
|
|
388
523
|
properties: {
|
|
389
|
-
request_id:
|
|
390
|
-
action:
|
|
391
|
-
content:
|
|
392
|
-
submitted_by: { type:
|
|
524
|
+
request_id: { type: "string" },
|
|
525
|
+
action: { type: "string", enum: ["accept", "decline", "cancel"] },
|
|
526
|
+
content: { type: "object" },
|
|
527
|
+
submitted_by: { type: "string", default: "human" },
|
|
393
528
|
},
|
|
394
529
|
},
|
|
395
|
-
handler: wrap(
|
|
530
|
+
handler: wrap("HITL_SUBMIT_FAILED", (args) => {
|
|
396
531
|
return hitl.submitHumanInput(args);
|
|
397
532
|
}),
|
|
398
533
|
},
|
|
399
534
|
|
|
400
535
|
// ── 12. team_info ──
|
|
401
536
|
{
|
|
402
|
-
name:
|
|
403
|
-
description:
|
|
537
|
+
name: "team_info",
|
|
538
|
+
description: "Claude Native Teams 메타/멤버/경로 정보를 조회합니다",
|
|
404
539
|
inputSchema: {
|
|
405
|
-
type:
|
|
406
|
-
required: [
|
|
540
|
+
type: "object",
|
|
541
|
+
required: ["team_name"],
|
|
407
542
|
properties: {
|
|
408
|
-
team_name: {
|
|
409
|
-
|
|
410
|
-
|
|
543
|
+
team_name: {
|
|
544
|
+
type: "string",
|
|
545
|
+
minLength: 1,
|
|
546
|
+
maxLength: 128,
|
|
547
|
+
pattern: "^[a-z0-9][a-z0-9-]*$",
|
|
548
|
+
},
|
|
549
|
+
include_members: { type: "boolean", default: true },
|
|
550
|
+
include_paths: { type: "boolean", default: true },
|
|
411
551
|
},
|
|
412
552
|
},
|
|
413
|
-
handler: wrap(
|
|
414
|
-
const teamInfo = getTeamBridgeMethod(
|
|
553
|
+
handler: wrap("TEAM_INFO_FAILED", (args) => {
|
|
554
|
+
const teamInfo = getTeamBridgeMethod("teamInfo");
|
|
415
555
|
return teamInfo ? teamInfo(args) : teamInfoFallback(args);
|
|
416
556
|
}),
|
|
417
557
|
},
|
|
418
558
|
|
|
419
559
|
// ── 13. team_task_list ──
|
|
420
560
|
{
|
|
421
|
-
name:
|
|
422
|
-
description:
|
|
561
|
+
name: "team_task_list",
|
|
562
|
+
description:
|
|
563
|
+
"Claude Native Teams task 목록을 owner/status 조건으로 조회합니다. 실패 판정은 completed + metadata.result도 함께 확인해야 합니다",
|
|
423
564
|
inputSchema: {
|
|
424
|
-
type:
|
|
425
|
-
required: [
|
|
565
|
+
type: "object",
|
|
566
|
+
required: ["team_name"],
|
|
426
567
|
properties: {
|
|
427
|
-
team_name: { type:
|
|
428
|
-
owner: { type:
|
|
568
|
+
team_name: { type: "string", pattern: "^[a-z0-9][a-z0-9-]*$" },
|
|
569
|
+
owner: { type: "string" },
|
|
429
570
|
statuses: {
|
|
430
|
-
type:
|
|
431
|
-
items: {
|
|
571
|
+
type: "array",
|
|
572
|
+
items: {
|
|
573
|
+
type: "string",
|
|
574
|
+
enum: [
|
|
575
|
+
"pending",
|
|
576
|
+
"in_progress",
|
|
577
|
+
"completed",
|
|
578
|
+
"failed",
|
|
579
|
+
"deleted",
|
|
580
|
+
],
|
|
581
|
+
},
|
|
432
582
|
maxItems: 8,
|
|
433
583
|
},
|
|
434
|
-
include_internal: { type:
|
|
435
|
-
limit: { type:
|
|
584
|
+
include_internal: { type: "boolean", default: false },
|
|
585
|
+
limit: { type: "integer", minimum: 1, maximum: 1000, default: 200 },
|
|
436
586
|
},
|
|
437
587
|
},
|
|
438
|
-
handler: wrap(
|
|
439
|
-
const teamTaskList = getTeamBridgeMethod(
|
|
588
|
+
handler: wrap("TEAM_TASK_LIST_FAILED", (args) => {
|
|
589
|
+
const teamTaskList = getTeamBridgeMethod("teamTaskList");
|
|
440
590
|
return teamTaskList ? teamTaskList(args) : teamTaskListFallback(args);
|
|
441
591
|
}),
|
|
442
592
|
},
|
|
443
593
|
|
|
444
594
|
// ── 14. team_task_update ──
|
|
445
595
|
{
|
|
446
|
-
name:
|
|
447
|
-
description:
|
|
596
|
+
name: "team_task_update",
|
|
597
|
+
description:
|
|
598
|
+
'Claude Native Teams task를 claim/update 합니다. status: "failed" 입력은 completed + metadata.result="failed"로 정규화됩니다',
|
|
448
599
|
inputSchema: {
|
|
449
|
-
type:
|
|
450
|
-
required: [
|
|
600
|
+
type: "object",
|
|
601
|
+
required: ["team_name", "task_id"],
|
|
451
602
|
properties: {
|
|
452
|
-
team_name: { type:
|
|
453
|
-
task_id: { type:
|
|
454
|
-
claim: { type:
|
|
455
|
-
owner: { type:
|
|
456
|
-
status: {
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
603
|
+
team_name: { type: "string", pattern: "^[a-z0-9][a-z0-9-]*$" },
|
|
604
|
+
task_id: { type: "string", minLength: 1, maxLength: 64 },
|
|
605
|
+
claim: { type: "boolean", default: false },
|
|
606
|
+
owner: { type: "string" },
|
|
607
|
+
status: {
|
|
608
|
+
type: "string",
|
|
609
|
+
enum: ["pending", "in_progress", "completed", "failed", "deleted"],
|
|
610
|
+
},
|
|
611
|
+
subject: { type: "string" },
|
|
612
|
+
description: { type: "string" },
|
|
613
|
+
activeForm: { type: "string" },
|
|
614
|
+
add_blocks: { type: "array", items: { type: "string" } },
|
|
615
|
+
add_blocked_by: { type: "array", items: { type: "string" } },
|
|
616
|
+
metadata_patch: { type: "object" },
|
|
617
|
+
if_match_mtime_ms: { type: "number" },
|
|
618
|
+
actor: { type: "string" },
|
|
465
619
|
},
|
|
466
620
|
},
|
|
467
|
-
handler: wrap(
|
|
468
|
-
const teamTaskUpdate = getTeamBridgeMethod(
|
|
469
|
-
return teamTaskUpdate
|
|
621
|
+
handler: wrap("TEAM_TASK_UPDATE_FAILED", (args) => {
|
|
622
|
+
const teamTaskUpdate = getTeamBridgeMethod("teamTaskUpdate");
|
|
623
|
+
return teamTaskUpdate
|
|
624
|
+
? teamTaskUpdate(args)
|
|
625
|
+
: teamTaskUpdateFallback(args);
|
|
470
626
|
}),
|
|
471
627
|
},
|
|
472
628
|
|
|
473
629
|
// ── 15. team_send_message ──
|
|
474
630
|
{
|
|
475
|
-
name:
|
|
476
|
-
description:
|
|
631
|
+
name: "team_send_message",
|
|
632
|
+
description: "Claude Native Teams inbox에 메시지를 append 합니다",
|
|
477
633
|
inputSchema: {
|
|
478
|
-
type:
|
|
479
|
-
required: [
|
|
634
|
+
type: "object",
|
|
635
|
+
required: ["team_name", "from", "text"],
|
|
480
636
|
properties: {
|
|
481
|
-
team_name: { type:
|
|
482
|
-
from: { type:
|
|
483
|
-
to: { type:
|
|
484
|
-
text: { type:
|
|
485
|
-
summary: { type:
|
|
486
|
-
color: { type:
|
|
637
|
+
team_name: { type: "string", pattern: "^[a-z0-9][a-z0-9-]*$" },
|
|
638
|
+
from: { type: "string", minLength: 1, maxLength: 128 },
|
|
639
|
+
to: { type: "string", default: "team-lead" },
|
|
640
|
+
text: { type: "string", minLength: 1, maxLength: 200000 },
|
|
641
|
+
summary: { type: "string", maxLength: 1000 },
|
|
642
|
+
color: { type: "string", default: "blue" },
|
|
487
643
|
},
|
|
488
644
|
},
|
|
489
|
-
handler: wrap(
|
|
490
|
-
const teamSendMessage = getTeamBridgeMethod(
|
|
491
|
-
return teamSendMessage
|
|
645
|
+
handler: wrap("TEAM_SEND_MESSAGE_FAILED", (args) => {
|
|
646
|
+
const teamSendMessage = getTeamBridgeMethod("teamSendMessage");
|
|
647
|
+
return teamSendMessage
|
|
648
|
+
? teamSendMessage(args)
|
|
649
|
+
: teamSendMessageFallback(args);
|
|
492
650
|
}),
|
|
493
651
|
},
|
|
494
652
|
|
|
495
653
|
// ── 16. pipeline_state ──
|
|
496
654
|
{
|
|
497
|
-
name:
|
|
498
|
-
description:
|
|
655
|
+
name: "pipeline_state",
|
|
656
|
+
description: "파이프라인 상태를 조회합니다 (--thorough 모드)",
|
|
499
657
|
inputSchema: {
|
|
500
|
-
type:
|
|
501
|
-
required: [
|
|
658
|
+
type: "object",
|
|
659
|
+
required: ["team_name"],
|
|
502
660
|
properties: {
|
|
503
|
-
team_name: { type:
|
|
661
|
+
team_name: { type: "string", pattern: "^[a-z0-9][a-z0-9-]*$" },
|
|
504
662
|
},
|
|
505
663
|
},
|
|
506
|
-
handler: wrap(
|
|
664
|
+
handler: wrap("PIPELINE_STATE_FAILED", (args) => {
|
|
507
665
|
ensurePipelineTable(store.db);
|
|
508
666
|
const state = readPipelineState(store.db, args.team_name);
|
|
509
667
|
return state
|
|
510
668
|
? { ok: true, data: state }
|
|
511
|
-
: {
|
|
669
|
+
: {
|
|
670
|
+
ok: false,
|
|
671
|
+
error: {
|
|
672
|
+
code: "PIPELINE_NOT_FOUND",
|
|
673
|
+
message: `파이프라인 없음: ${args.team_name}`,
|
|
674
|
+
},
|
|
675
|
+
};
|
|
512
676
|
}),
|
|
513
677
|
},
|
|
514
678
|
|
|
515
679
|
// ── 17. pipeline_advance ──
|
|
516
680
|
{
|
|
517
|
-
name:
|
|
518
|
-
description:
|
|
681
|
+
name: "pipeline_advance",
|
|
682
|
+
description:
|
|
683
|
+
"파이프라인을 다음 단계로 전이합니다 (전이 규칙 + fix loop 바운딩 적용)",
|
|
519
684
|
inputSchema: {
|
|
520
|
-
type:
|
|
521
|
-
required: [
|
|
685
|
+
type: "object",
|
|
686
|
+
required: ["team_name", "phase"],
|
|
522
687
|
properties: {
|
|
523
|
-
team_name: { type:
|
|
524
|
-
phase: {
|
|
688
|
+
team_name: { type: "string", pattern: "^[a-z0-9][a-z0-9-]*$" },
|
|
689
|
+
phase: {
|
|
690
|
+
type: "string",
|
|
691
|
+
enum: [
|
|
692
|
+
"plan",
|
|
693
|
+
"prd",
|
|
694
|
+
"exec",
|
|
695
|
+
"verify",
|
|
696
|
+
"fix",
|
|
697
|
+
"complete",
|
|
698
|
+
"failed",
|
|
699
|
+
],
|
|
700
|
+
},
|
|
525
701
|
},
|
|
526
702
|
},
|
|
527
|
-
handler: wrap(
|
|
703
|
+
handler: wrap("PIPELINE_ADVANCE_FAILED", (args) => {
|
|
528
704
|
ensurePipelineTable(store.db);
|
|
529
705
|
const pipeline = createPipeline(store.db, args.team_name);
|
|
530
706
|
return pipeline.advance(args.phase);
|
|
@@ -533,18 +709,18 @@ export function createTools(store, router, hitl, pipe = null) {
|
|
|
533
709
|
|
|
534
710
|
// ── 18. pipeline_init ──
|
|
535
711
|
{
|
|
536
|
-
name:
|
|
537
|
-
description:
|
|
712
|
+
name: "pipeline_init",
|
|
713
|
+
description: "새 파이프라인을 초기화합니다 (기존 상태 덮어쓰기)",
|
|
538
714
|
inputSchema: {
|
|
539
|
-
type:
|
|
540
|
-
required: [
|
|
715
|
+
type: "object",
|
|
716
|
+
required: ["team_name"],
|
|
541
717
|
properties: {
|
|
542
|
-
team_name: { type:
|
|
543
|
-
fix_max: { type:
|
|
544
|
-
ralph_max: { type:
|
|
718
|
+
team_name: { type: "string", pattern: "^[a-z0-9][a-z0-9-]*$" },
|
|
719
|
+
fix_max: { type: "integer", minimum: 1, maximum: 20, default: 3 },
|
|
720
|
+
ralph_max: { type: "integer", minimum: 1, maximum: 100, default: 10 },
|
|
545
721
|
},
|
|
546
722
|
},
|
|
547
|
-
handler: wrap(
|
|
723
|
+
handler: wrap("PIPELINE_INIT_FAILED", (args) => {
|
|
548
724
|
ensurePipelineTable(store.db);
|
|
549
725
|
const state = initPipelineState(store.db, args.team_name, {
|
|
550
726
|
fix_max: args.fix_max,
|
|
@@ -556,21 +732,48 @@ export function createTools(store, router, hitl, pipe = null) {
|
|
|
556
732
|
|
|
557
733
|
// ── 19. pipeline_advance_gated (HITL 승인 게이트) ──
|
|
558
734
|
{
|
|
559
|
-
name:
|
|
560
|
-
description:
|
|
735
|
+
name: "pipeline_advance_gated",
|
|
736
|
+
description:
|
|
737
|
+
"HITL 승인 게이트가 포함된 파이프라인 전이. 지정 단계로의 전이 전 사용자 승인을 요청하고, 승인 후 전이를 실행합니다. deadline 초과 시 default_action에 따라 자동 처리됩니다.",
|
|
561
738
|
inputSchema: {
|
|
562
|
-
type:
|
|
563
|
-
required: [
|
|
739
|
+
type: "object",
|
|
740
|
+
required: ["team_name", "phase"],
|
|
564
741
|
properties: {
|
|
565
|
-
team_name: { type:
|
|
566
|
-
phase: {
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
742
|
+
team_name: { type: "string", pattern: "^[a-z0-9][a-z0-9-]*$" },
|
|
743
|
+
phase: {
|
|
744
|
+
type: "string",
|
|
745
|
+
enum: [
|
|
746
|
+
"plan",
|
|
747
|
+
"prd",
|
|
748
|
+
"exec",
|
|
749
|
+
"verify",
|
|
750
|
+
"fix",
|
|
751
|
+
"complete",
|
|
752
|
+
"failed",
|
|
753
|
+
],
|
|
754
|
+
},
|
|
755
|
+
prompt: {
|
|
756
|
+
type: "string",
|
|
757
|
+
description: "사용자에게 표시할 승인 요청 메시지",
|
|
758
|
+
},
|
|
759
|
+
deadline_ms: {
|
|
760
|
+
type: "integer",
|
|
761
|
+
minimum: 5000,
|
|
762
|
+
maximum: 600000,
|
|
763
|
+
default: 120000,
|
|
764
|
+
},
|
|
765
|
+
default_action: {
|
|
766
|
+
type: "string",
|
|
767
|
+
enum: ["timeout_continue", "timeout_abort"],
|
|
768
|
+
default: "timeout_continue",
|
|
769
|
+
},
|
|
770
|
+
requester_agent: {
|
|
771
|
+
type: "string",
|
|
772
|
+
description: "요청자 에이전트 이름",
|
|
773
|
+
},
|
|
571
774
|
},
|
|
572
775
|
},
|
|
573
|
-
handler: wrap(
|
|
776
|
+
handler: wrap("PIPELINE_ADVANCE_GATED_FAILED", (args) => {
|
|
574
777
|
ensurePipelineTable(store.db);
|
|
575
778
|
const pipeline = createPipeline(store.db, args.team_name);
|
|
576
779
|
|
|
@@ -580,23 +783,25 @@ export function createTools(store, router, hitl, pipe = null) {
|
|
|
580
783
|
return {
|
|
581
784
|
ok: false,
|
|
582
785
|
error: {
|
|
583
|
-
code:
|
|
786
|
+
code: "TRANSITION_BLOCKED",
|
|
584
787
|
message: `전이 불가: ${current.phase} → ${args.phase}`,
|
|
585
788
|
},
|
|
586
789
|
};
|
|
587
790
|
}
|
|
588
791
|
|
|
589
792
|
// HITL 승인 요청 생성
|
|
590
|
-
const approvalPrompt =
|
|
793
|
+
const approvalPrompt =
|
|
794
|
+
args.prompt ||
|
|
795
|
+
`파이프라인 ${args.team_name}: ${pipeline.getState().phase} → ${args.phase} 전이를 승인하시겠습니까?`;
|
|
591
796
|
const deadlineMs = args.deadline_ms || 120000;
|
|
592
797
|
const now = Date.now();
|
|
593
798
|
|
|
594
799
|
const hitlResult = hitl.requestHumanInput({
|
|
595
800
|
requester_agent: args.requester_agent || `pipeline:${args.team_name}`,
|
|
596
|
-
kind:
|
|
801
|
+
kind: "approval",
|
|
597
802
|
prompt: approvalPrompt,
|
|
598
803
|
deadline_ms: now + deadlineMs,
|
|
599
|
-
default_action: args.default_action ||
|
|
804
|
+
default_action: args.default_action || "timeout_continue",
|
|
600
805
|
});
|
|
601
806
|
|
|
602
807
|
if (!hitlResult.ok) {
|
|
@@ -612,8 +817,8 @@ export function createTools(store, router, hitl, pipe = null) {
|
|
|
612
817
|
target_phase: args.phase,
|
|
613
818
|
current_phase: pipeline.getState().phase,
|
|
614
819
|
deadline_ms: now + deadlineMs,
|
|
615
|
-
default_action: args.default_action ||
|
|
616
|
-
message: `승인 대기 중. ID: ${hitlResult.data.request_id}. ${Math.round(deadlineMs / 1000)}초 후 ${args.default_action ||
|
|
820
|
+
default_action: args.default_action || "timeout_continue",
|
|
821
|
+
message: `승인 대기 중. ID: ${hitlResult.data.request_id}. ${Math.round(deadlineMs / 1000)}초 후 ${args.default_action || "timeout_continue"} 자동 실행.`,
|
|
617
822
|
},
|
|
618
823
|
};
|
|
619
824
|
}),
|
|
@@ -621,16 +826,33 @@ export function createTools(store, router, hitl, pipe = null) {
|
|
|
621
826
|
|
|
622
827
|
// ── 20. pipeline_list ──
|
|
623
828
|
{
|
|
624
|
-
name:
|
|
625
|
-
description:
|
|
829
|
+
name: "pipeline_list",
|
|
830
|
+
description: "활성 파이프라인 목록을 조회합니다",
|
|
626
831
|
inputSchema: {
|
|
627
|
-
type:
|
|
832
|
+
type: "object",
|
|
628
833
|
properties: {},
|
|
629
834
|
},
|
|
630
|
-
handler: wrap(
|
|
835
|
+
handler: wrap("PIPELINE_LIST_FAILED", () => {
|
|
631
836
|
ensurePipelineTable(store.db);
|
|
632
837
|
return { ok: true, data: listPipelineStates(store.db) };
|
|
633
838
|
}),
|
|
634
839
|
},
|
|
840
|
+
|
|
841
|
+
// ── 21. send_input ──
|
|
842
|
+
{
|
|
843
|
+
name: "send_input",
|
|
844
|
+
description: "Send input text to a worker in INPUT_WAIT state",
|
|
845
|
+
inputSchema: {
|
|
846
|
+
type: "object",
|
|
847
|
+
properties: {
|
|
848
|
+
session_id: { type: "string", description: "Conductor session ID" },
|
|
849
|
+
text: { type: "string", description: "Input text to send" },
|
|
850
|
+
},
|
|
851
|
+
required: ["session_id", "text"],
|
|
852
|
+
},
|
|
853
|
+
handler: wrap("SEND_INPUT_FAILED", (args) => {
|
|
854
|
+
return sendInputToConductorSession(args.session_id, args.text);
|
|
855
|
+
}),
|
|
856
|
+
},
|
|
635
857
|
];
|
|
636
858
|
}
|