@triflux/remote 10.25.1 → 10.27.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/hub/server.mjs +21 -8
- package/hub/team/agent-map.json +3 -3
- package/hub/team/backend.mjs +3 -9
- package/hub/team/build-worker-prompt.mjs +33 -2
- package/hub/team/claude-daemon-control.mjs +911 -0
- package/hub/team/claude-native-bridge.mjs +244 -11
- package/hub/team/claude-session-projection.mjs +10 -1
- package/hub/team/cli/commands/start/index.mjs +3 -6
- package/hub/team/cli/commands/start/parse-args.mjs +10 -3
- package/hub/team/cli/commands/start/start-headless.mjs +50 -20
- package/hub/team/cli/help.mjs +1 -1
- package/hub/team/cli/services/runtime-mode.mjs +6 -3
- package/hub/team/execution-mode.mjs +27 -12
- package/hub/team/headless.mjs +191 -43
- package/hub/team/interactive-native-launcher.mjs +106 -0
- package/hub/team/interactive-native-worker.mjs +80 -0
- package/hub/team/interactive-tui-transport.mjs +465 -0
- package/hub/team/launcher-template.mjs +28 -6
- package/hub/team/native.mjs +46 -7
- package/hub/team/pane.mjs +0 -5
- package/hub/team/psmux.mjs +3 -3
- package/hub/team/retry-state-machine.mjs +83 -14
- package/hub/team/session.mjs +5 -36
- package/hub/team/swarm-hypervisor.mjs +63 -14
- package/hub/team/swarm-preflight.mjs +3 -1
- package/hub/team/terminal-opener.mjs +1 -1
- package/hub/team/tui-core.mjs +4 -0
- package/hub/team/tui-lite.mjs +3 -2
- package/hub/team/tui-viewer.mjs +4 -4
- package/hub/team/tui.mjs +4 -2
- package/hub/team/worker-sandbox.mjs +4 -0
- package/hub/tools.mjs +4 -1
- package/hub/workers/antigravity-route-worker.mjs +169 -0
- package/hub/workers/delegator-mcp.mjs +58 -314
- package/hub/workers/factory.mjs +7 -4
- package/hub/workers/gemini-worker.mjs +55 -306
- package/hub/workers/interface.mjs +2 -1
- package/hub/workers/worker-utils.mjs +1 -1
- package/package.json +1 -1
- package/scripts/lib/cli-codex.mjs +3 -3
- package/scripts/lib/cli-gemini.mjs +20 -50
- package/scripts/lib/keyword-rules.mjs +1 -1
- package/scripts/lib/mcp-gateway-health-check.mjs +159 -0
- package/scripts/lib/mcp-gateway-wrapper-check.mjs +35 -0
- package/scripts/lib/psmux-info.mjs +50 -5
|
@@ -12,11 +12,9 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
12
12
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
13
13
|
import * as z from "zod";
|
|
14
14
|
import { resolveBashExecutable } from "@triflux/core/hub/lib/bash-path.mjs";
|
|
15
|
-
import { whichCommand } from "@triflux/core/hub/platform.mjs";
|
|
16
15
|
import { runHeadlessWithCleanup } from "../team/headless.mjs";
|
|
17
16
|
import { buildWorkerSandboxEnv } from "../team/worker-sandbox.mjs";
|
|
18
17
|
import { CodexMcpWorker } from "./codex-mcp.mjs";
|
|
19
|
-
import { GeminiWorker } from "./gemini-worker.mjs";
|
|
20
18
|
|
|
21
19
|
const SCRIPT_DIR = dirname(fileURLToPath(import.meta.url));
|
|
22
20
|
|
|
@@ -34,7 +32,6 @@ if (!mcpFilterPath) {
|
|
|
34
32
|
const {
|
|
35
33
|
buildPromptHint,
|
|
36
34
|
getCodexMcpConfig,
|
|
37
|
-
getGeminiAllowedServers,
|
|
38
35
|
SUPPORTED_MCP_PROFILES,
|
|
39
36
|
} = await import(pathToFileURL(mcpFilterPath).href);
|
|
40
37
|
const SERVER_INFO = { name: "triflux-delegator", version: "1.0.0" };
|
|
@@ -70,30 +67,24 @@ const AGENT_TIMEOUT_SEC = Object.freeze({
|
|
|
70
67
|
});
|
|
71
68
|
|
|
72
69
|
const CODEX_PROFILE_BY_AGENT = Object.freeze({
|
|
73
|
-
executor: "
|
|
74
|
-
"build-fixer": "
|
|
75
|
-
debugger: "
|
|
76
|
-
"deep-executor": "
|
|
77
|
-
architect: "
|
|
78
|
-
planner: "
|
|
79
|
-
critic: "
|
|
80
|
-
analyst: "
|
|
81
|
-
"code-reviewer": "
|
|
82
|
-
"security-reviewer": "
|
|
83
|
-
"quality-reviewer": "
|
|
84
|
-
scientist: "
|
|
85
|
-
"scientist-deep": "
|
|
86
|
-
"document-specialist": "
|
|
87
|
-
verifier: "
|
|
88
|
-
designer: "
|
|
89
|
-
writer: "
|
|
90
|
-
spark: "
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
const GEMINI_MODEL_BY_AGENT = Object.freeze({
|
|
94
|
-
"build-fixer": "gemini-3-flash-preview",
|
|
95
|
-
writer: "gemini-3-flash-preview",
|
|
96
|
-
spark: "gemini-3-flash-preview",
|
|
70
|
+
executor: "gpt55_high",
|
|
71
|
+
"build-fixer": "gpt55_low",
|
|
72
|
+
debugger: "gpt55_xhigh",
|
|
73
|
+
"deep-executor": "gpt55_xhigh",
|
|
74
|
+
architect: "gpt55_xhigh",
|
|
75
|
+
planner: "gpt55_xhigh",
|
|
76
|
+
critic: "gpt55_xhigh",
|
|
77
|
+
analyst: "gpt55_xhigh",
|
|
78
|
+
"code-reviewer": "gpt55_high",
|
|
79
|
+
"security-reviewer": "gpt55_xhigh",
|
|
80
|
+
"quality-reviewer": "gpt55_high",
|
|
81
|
+
scientist: "gpt55_high",
|
|
82
|
+
"scientist-deep": "gpt55_xhigh",
|
|
83
|
+
"document-specialist": "gpt55_high",
|
|
84
|
+
verifier: "gpt55_high",
|
|
85
|
+
designer: "gpt55_xhigh",
|
|
86
|
+
writer: "gpt55_low",
|
|
87
|
+
spark: "gpt55_low",
|
|
97
88
|
});
|
|
98
89
|
|
|
99
90
|
const REVIEW_INSTRUCTION_BY_AGENT = Object.freeze({
|
|
@@ -152,8 +143,13 @@ function resolveCodexProfile(agentType) {
|
|
|
152
143
|
return CODEX_PROFILE_BY_AGENT[agentType] || "high";
|
|
153
144
|
}
|
|
154
145
|
|
|
155
|
-
function
|
|
156
|
-
|
|
146
|
+
function normalizeProvider(provider = "auto") {
|
|
147
|
+
const value = provider || "auto";
|
|
148
|
+
return value === "gemini" ? "antigravity" : value;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function normalizeDelegateArgs(args = {}) {
|
|
152
|
+
return { ...args, provider: normalizeProvider(args.provider) };
|
|
157
153
|
}
|
|
158
154
|
|
|
159
155
|
function resolveTimeoutMs(agentType, timeoutMs) {
|
|
@@ -187,21 +183,6 @@ function withContext(prompt, contextFile) {
|
|
|
187
183
|
return `${prompt}\n\n<prior_context>\n${context}\n</prior_context>`;
|
|
188
184
|
}
|
|
189
185
|
|
|
190
|
-
function withPromptHint(prompt, args) {
|
|
191
|
-
const promptWithContext = withContext(prompt, args.contextFile);
|
|
192
|
-
const hint = buildPromptHint({
|
|
193
|
-
agentType: args.agentType,
|
|
194
|
-
requestedProfile: args.mcpProfile,
|
|
195
|
-
searchTool: args.searchTool,
|
|
196
|
-
workerIndex: Number.isInteger(args.workerIndex)
|
|
197
|
-
? args.workerIndex
|
|
198
|
-
: undefined,
|
|
199
|
-
taskText: promptWithContext,
|
|
200
|
-
});
|
|
201
|
-
if (!hint) return promptWithContext;
|
|
202
|
-
return `${promptWithContext}. ${hint}`;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
186
|
function joinInstructions(...values) {
|
|
206
187
|
return values
|
|
207
188
|
.filter((value) => typeof value === "string" && value.trim())
|
|
@@ -231,7 +212,7 @@ function parseRouteType(stderr = "") {
|
|
|
231
212
|
const match = stderr.match(/type=([a-z-]+)/);
|
|
232
213
|
if (!match) return null;
|
|
233
214
|
if (match[1] === "codex") return "codex";
|
|
234
|
-
if (match[1] === "gemini") return "
|
|
215
|
+
if (match[1] === "gemini") return "antigravity";
|
|
235
216
|
return match[1];
|
|
236
217
|
}
|
|
237
218
|
|
|
@@ -265,7 +246,7 @@ function createErrorPayload(message, extras = {}) {
|
|
|
265
246
|
const DelegateInputSchema = z.object({
|
|
266
247
|
prompt: z.string().min(1).describe("위임할 프롬프트"),
|
|
267
248
|
provider: z
|
|
268
|
-
.enum(["auto", "codex", "gemini"])
|
|
249
|
+
.enum(["auto", "codex", "antigravity", "gemini"])
|
|
269
250
|
.default("auto")
|
|
270
251
|
.describe("사용할 provider"),
|
|
271
252
|
mode: z
|
|
@@ -327,7 +308,9 @@ const DelegateInputSchema = z.object({
|
|
|
327
308
|
workers: z
|
|
328
309
|
.array(
|
|
329
310
|
z.object({
|
|
330
|
-
provider: z
|
|
311
|
+
provider: z
|
|
312
|
+
.enum(["codex", "antigravity", "gemini"])
|
|
313
|
+
.describe("워커 provider"),
|
|
331
314
|
agentType: z.string().default("executor").describe("역할명"),
|
|
332
315
|
prompt: z.string().describe("워커별 프롬프트"),
|
|
333
316
|
mcpProfile: z.string().default("auto").describe("MCP 프로필"),
|
|
@@ -399,12 +382,13 @@ function isTeamRouteRequested(args) {
|
|
|
399
382
|
}
|
|
400
383
|
|
|
401
384
|
function pickRouteMode(provider) {
|
|
402
|
-
|
|
385
|
+
const normalized = normalizeProvider(provider);
|
|
386
|
+
return normalized === "auto" ? "auto" : normalized;
|
|
403
387
|
}
|
|
404
388
|
|
|
405
389
|
function sanitizeDelegateArgs(args = {}) {
|
|
406
390
|
return {
|
|
407
|
-
provider: args.provider
|
|
391
|
+
provider: normalizeProvider(args.provider),
|
|
408
392
|
agentType: args.agentType || "executor",
|
|
409
393
|
cwd: args.cwd || null,
|
|
410
394
|
timeoutMs: Number.isFinite(Number(args.timeoutMs))
|
|
@@ -433,18 +417,6 @@ function sanitizeDelegateArgs(args = {}) {
|
|
|
433
417
|
};
|
|
434
418
|
}
|
|
435
419
|
|
|
436
|
-
function formatConversationTranscript(turns = []) {
|
|
437
|
-
return turns
|
|
438
|
-
.map((turn, index) => {
|
|
439
|
-
const parts = [`Turn ${index + 1} user:\n${turn.user}`];
|
|
440
|
-
if (typeof turn.assistant === "string" && turn.assistant.trim()) {
|
|
441
|
-
parts.push(`Turn ${index + 1} assistant:\n${turn.assistant}`);
|
|
442
|
-
}
|
|
443
|
-
return parts.join("\n\n");
|
|
444
|
-
})
|
|
445
|
-
.join("\n\n");
|
|
446
|
-
}
|
|
447
|
-
|
|
448
420
|
async function emitProgress(extra, progress, total, message) {
|
|
449
421
|
if (extra?._meta?.progressToken === undefined) return;
|
|
450
422
|
await extra.sendNotification({
|
|
@@ -486,17 +458,9 @@ export class DelegatorMcpWorker {
|
|
|
486
458
|
clientInfo: { name: SERVER_INFO.name, version: SERVER_INFO.version },
|
|
487
459
|
});
|
|
488
460
|
|
|
489
|
-
this.geminiCommand =
|
|
490
|
-
options.geminiCommand || this.env.GEMINI_BIN || "gemini";
|
|
491
|
-
this.geminiCommandArgs =
|
|
492
|
-
Array.isArray(options.geminiArgs) && options.geminiArgs.length
|
|
493
|
-
? [...options.geminiArgs]
|
|
494
|
-
: parseJsonArray(this.env.GEMINI_BIN_ARGS_JSON, []);
|
|
495
|
-
|
|
496
461
|
this.server = null;
|
|
497
462
|
this.transport = null;
|
|
498
463
|
this.jobs = new Map();
|
|
499
|
-
this.geminiConversations = new Map();
|
|
500
464
|
this.routeChildren = new Set();
|
|
501
465
|
this.ready = false;
|
|
502
466
|
}
|
|
@@ -519,7 +483,7 @@ export class DelegatorMcpWorker {
|
|
|
519
483
|
"triflux-delegate",
|
|
520
484
|
{
|
|
521
485
|
description:
|
|
522
|
-
"새 위임을 실행합니다. codex
|
|
486
|
+
"새 위임을 실행합니다. codex direct 경로와 antigravity/tfx-route 기반 auto 라우팅을 지원합니다.",
|
|
523
487
|
inputSchema: DelegateInputSchema,
|
|
524
488
|
outputSchema: DelegateOutputSchema,
|
|
525
489
|
},
|
|
@@ -548,7 +512,7 @@ export class DelegatorMcpWorker {
|
|
|
548
512
|
"triflux-delegate-reply",
|
|
549
513
|
{
|
|
550
514
|
description:
|
|
551
|
-
"기존 delegate job에 후속 응답을
|
|
515
|
+
"기존 delegate job에 후속 응답을 보냅니다. 현재 route 기반 Antigravity job은 후속 응답을 지원하지 않습니다.",
|
|
552
516
|
inputSchema: DelegateReplyInputSchema,
|
|
553
517
|
outputSchema: DelegateOutputSchema,
|
|
554
518
|
},
|
|
@@ -581,15 +545,6 @@ export class DelegatorMcpWorker {
|
|
|
581
545
|
this.routeChildren.clear();
|
|
582
546
|
|
|
583
547
|
await this.codexWorker.stop().catch(() => {});
|
|
584
|
-
|
|
585
|
-
for (const job of this.jobs.values()) {
|
|
586
|
-
if (job.worker) {
|
|
587
|
-
await job.worker.stop().catch(() => {});
|
|
588
|
-
job.worker = null;
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
this.geminiConversations.clear();
|
|
592
|
-
|
|
593
548
|
if (this.server) {
|
|
594
549
|
await this.server.close().catch(() => {});
|
|
595
550
|
}
|
|
@@ -599,11 +554,13 @@ export class DelegatorMcpWorker {
|
|
|
599
554
|
}
|
|
600
555
|
|
|
601
556
|
async run(prompt, options = {}) {
|
|
602
|
-
return this._executeDirect({ prompt, ...options });
|
|
557
|
+
return this._executeDirect(normalizeDelegateArgs({ prompt, ...options }));
|
|
603
558
|
}
|
|
604
559
|
|
|
605
560
|
async execute(prompt, options = {}) {
|
|
606
|
-
const result = await this._executeDirect(
|
|
561
|
+
const result = await this._executeDirect(
|
|
562
|
+
normalizeDelegateArgs({ prompt, ...options }),
|
|
563
|
+
);
|
|
607
564
|
return {
|
|
608
565
|
output: result.output || result.error || "",
|
|
609
566
|
exitCode: result.exitCode ?? (result.ok ? 0 : 1),
|
|
@@ -614,10 +571,11 @@ export class DelegatorMcpWorker {
|
|
|
614
571
|
}
|
|
615
572
|
|
|
616
573
|
async delegate(args, extra) {
|
|
617
|
-
|
|
618
|
-
|
|
574
|
+
const normalizedArgs = normalizeDelegateArgs(args);
|
|
575
|
+
if (normalizedArgs.mode === "async") {
|
|
576
|
+
return this._startAsyncJob(normalizedArgs, extra);
|
|
619
577
|
}
|
|
620
|
-
return this._runSyncJob(
|
|
578
|
+
return this._runSyncJob(normalizedArgs, extra);
|
|
621
579
|
}
|
|
622
580
|
|
|
623
581
|
async getJobStatus(jobId, extra) {
|
|
@@ -637,7 +595,7 @@ export class DelegatorMcpWorker {
|
|
|
637
595
|
return payload;
|
|
638
596
|
}
|
|
639
597
|
|
|
640
|
-
async reply({ job_id
|
|
598
|
+
async reply({ job_id }, extra) {
|
|
641
599
|
const job = this.jobs.get(job_id);
|
|
642
600
|
if (!job) {
|
|
643
601
|
return createErrorPayload(`알 수 없는 jobId: ${job_id}`, {
|
|
@@ -651,145 +609,20 @@ export class DelegatorMcpWorker {
|
|
|
651
609
|
job_id,
|
|
652
610
|
});
|
|
653
611
|
}
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
job
|
|
657
|
-
|
|
658
|
-
return createErrorPayload(
|
|
659
|
-
"delegate-reply는 현재 direct Gemini job에만 지원됩니다.",
|
|
660
|
-
{
|
|
661
|
-
jobId: job_id,
|
|
662
|
-
job_id,
|
|
663
|
-
},
|
|
664
|
-
);
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
const conversation = this.geminiConversations.get(job_id);
|
|
668
|
-
if (!conversation) {
|
|
669
|
-
return createErrorPayload(`Gemini 대화 컨텍스트가 없습니다: ${job_id}`, {
|
|
670
|
-
jobId: job_id,
|
|
671
|
-
job_id,
|
|
672
|
-
});
|
|
673
|
-
}
|
|
674
|
-
if (conversation.closed) {
|
|
675
|
-
return createErrorPayload(`이미 종료된 대화입니다: ${job_id}`, {
|
|
612
|
+
void extra;
|
|
613
|
+
return createErrorPayload(
|
|
614
|
+
"delegate-reply는 route 기반 Antigravity job에 지원되지 않습니다.",
|
|
615
|
+
{
|
|
676
616
|
jobId: job_id,
|
|
677
617
|
job_id,
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
await emitProgress(
|
|
682
|
-
extra,
|
|
683
|
-
DIRECT_PROGRESS_START,
|
|
684
|
-
100,
|
|
685
|
-
`job ${job_id} 후속 응답을 시작합니다.`,
|
|
618
|
+
},
|
|
686
619
|
);
|
|
687
|
-
job.status = "running";
|
|
688
|
-
job.updatedAt = new Date().toISOString();
|
|
689
|
-
|
|
690
|
-
const worker = this._createGeminiWorker();
|
|
691
|
-
job.worker = worker;
|
|
692
|
-
const prompt = this._buildGeminiReplyPrompt(conversation, reply);
|
|
693
|
-
|
|
694
|
-
try {
|
|
695
|
-
const result = await worker.execute(prompt, {
|
|
696
|
-
cwd: job.requestArgs.cwd || this.cwd,
|
|
697
|
-
timeoutMs: resolveTimeoutMs(job.agentType, job.requestArgs.timeoutMs),
|
|
698
|
-
model: job.requestArgs.model || resolveGeminiModel(job.agentType),
|
|
699
|
-
approvalMode: "yolo",
|
|
700
|
-
allowedMcpServerNames: getGeminiAllowedServers(
|
|
701
|
-
this._getMcpPolicyOptions(job.requestArgs),
|
|
702
|
-
),
|
|
703
|
-
});
|
|
704
|
-
|
|
705
|
-
conversation.turns.push({
|
|
706
|
-
user: reply,
|
|
707
|
-
assistant: result.output,
|
|
708
|
-
});
|
|
709
|
-
conversation.updatedAt = new Date().toISOString();
|
|
710
|
-
conversation.closed = Boolean(done);
|
|
711
|
-
if (done) {
|
|
712
|
-
this.geminiConversations.delete(job_id);
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
this._applyJobResult(job, {
|
|
716
|
-
ok: result.exitCode === 0,
|
|
717
|
-
status: result.exitCode === 0 ? "completed" : "failed",
|
|
718
|
-
providerRequested: "gemini",
|
|
719
|
-
providerResolved: "gemini",
|
|
720
|
-
agentType: job.agentType,
|
|
721
|
-
transport: "gemini-worker",
|
|
722
|
-
exitCode: result.exitCode,
|
|
723
|
-
output: result.output,
|
|
724
|
-
sessionKey: result.sessionKey || job.sessionKey || null,
|
|
725
|
-
});
|
|
726
|
-
await emitProgress(
|
|
727
|
-
extra,
|
|
728
|
-
DIRECT_PROGRESS_DONE,
|
|
729
|
-
100,
|
|
730
|
-
`job ${job_id} 후속 응답이 완료되었습니다.`,
|
|
731
|
-
);
|
|
732
|
-
return this._serializeJob(job);
|
|
733
|
-
} catch (error) {
|
|
734
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
735
|
-
this._applyJobResult(
|
|
736
|
-
job,
|
|
737
|
-
createErrorPayload(message, {
|
|
738
|
-
mode: job.mode,
|
|
739
|
-
providerRequested: "gemini",
|
|
740
|
-
providerResolved: "gemini",
|
|
741
|
-
agentType: job.agentType,
|
|
742
|
-
transport: "gemini-worker",
|
|
743
|
-
}),
|
|
744
|
-
);
|
|
745
|
-
return this._serializeJob(job);
|
|
746
|
-
} finally {
|
|
747
|
-
await worker.stop().catch(() => {});
|
|
748
|
-
job.worker = null;
|
|
749
|
-
}
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
_createGeminiWorker() {
|
|
753
|
-
const resolved = whichCommand(this.geminiCommand) || this.geminiCommand;
|
|
754
|
-
return new GeminiWorker({
|
|
755
|
-
command: resolved,
|
|
756
|
-
commandArgs: this.geminiCommandArgs,
|
|
757
|
-
cwd: this.cwd,
|
|
758
|
-
env: this.env,
|
|
759
|
-
});
|
|
760
620
|
}
|
|
761
621
|
|
|
762
622
|
_buildDirectPrompt(args) {
|
|
763
623
|
return withContext(String(args.prompt ?? ""), args.contextFile);
|
|
764
624
|
}
|
|
765
625
|
|
|
766
|
-
_buildDirectPromptWithHint(args) {
|
|
767
|
-
return withPromptHint(String(args.prompt ?? ""), {
|
|
768
|
-
agentType: args.agentType || "executor",
|
|
769
|
-
mcpProfile: args.mcpProfile || "auto",
|
|
770
|
-
searchTool: args.searchTool,
|
|
771
|
-
workerIndex: Number.isInteger(args.workerIndex)
|
|
772
|
-
? args.workerIndex
|
|
773
|
-
: undefined,
|
|
774
|
-
contextFile: args.contextFile,
|
|
775
|
-
});
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
_buildGeminiReplyPrompt(conversation, reply) {
|
|
779
|
-
const transcript = formatConversationTranscript(conversation.turns);
|
|
780
|
-
return [
|
|
781
|
-
"Continue the conversation using the prior transcript below.",
|
|
782
|
-
"",
|
|
783
|
-
"<conversation_history>",
|
|
784
|
-
transcript,
|
|
785
|
-
"</conversation_history>",
|
|
786
|
-
"",
|
|
787
|
-
"<latest_user_reply>",
|
|
788
|
-
reply,
|
|
789
|
-
"</latest_user_reply>",
|
|
790
|
-
].join("\n");
|
|
791
|
-
}
|
|
792
|
-
|
|
793
626
|
_getMcpPolicyOptions(args) {
|
|
794
627
|
return {
|
|
795
628
|
agentType: args.agentType || "executor",
|
|
@@ -810,7 +643,12 @@ export class DelegatorMcpWorker {
|
|
|
810
643
|
}
|
|
811
644
|
|
|
812
645
|
_shouldUseRoute(args) {
|
|
813
|
-
return
|
|
646
|
+
return (
|
|
647
|
+
args.provider === "auto" ||
|
|
648
|
+
args.provider === "antigravity" ||
|
|
649
|
+
args.provider === "gemini" ||
|
|
650
|
+
isTeamRouteRequested(args)
|
|
651
|
+
);
|
|
814
652
|
}
|
|
815
653
|
|
|
816
654
|
async _executeDirect(args, extra = null) {
|
|
@@ -878,8 +716,8 @@ export class DelegatorMcpWorker {
|
|
|
878
716
|
|
|
879
717
|
// workers 배열을 headless assignments 형식으로 변환
|
|
880
718
|
const assignments = args.workers.map((w) => {
|
|
881
|
-
// provider를 CLI 이름으로
|
|
882
|
-
const cli = w.provider;
|
|
719
|
+
// provider를 CLI 이름으로 매핑. gemini는 deprecated alias로 antigravity에 합류한다.
|
|
720
|
+
const cli = normalizeProvider(w.provider);
|
|
883
721
|
const role = w.agentType || "executor";
|
|
884
722
|
// buildDirectPrompt와 동일한 context 처리
|
|
885
723
|
const prompt = withContext(String(w.prompt || ""), args.contextFile);
|
|
@@ -1003,38 +841,6 @@ export class DelegatorMcpWorker {
|
|
|
1003
841
|
};
|
|
1004
842
|
}
|
|
1005
843
|
|
|
1006
|
-
if (args.provider === "gemini") {
|
|
1007
|
-
const worker = this._createGeminiWorker();
|
|
1008
|
-
const prompt = this._buildDirectPromptWithHint(args);
|
|
1009
|
-
try {
|
|
1010
|
-
const result = await worker.execute(prompt, {
|
|
1011
|
-
cwd: args.cwd || this.cwd,
|
|
1012
|
-
timeoutMs: resolveTimeoutMs(args.agentType, args.timeoutMs),
|
|
1013
|
-
model: args.model || resolveGeminiModel(args.agentType),
|
|
1014
|
-
approvalMode: "yolo",
|
|
1015
|
-
allowedMcpServerNames: getGeminiAllowedServers(
|
|
1016
|
-
this._getMcpPolicyOptions(args),
|
|
1017
|
-
),
|
|
1018
|
-
});
|
|
1019
|
-
|
|
1020
|
-
return {
|
|
1021
|
-
ok: result.exitCode === 0,
|
|
1022
|
-
mode: "sync",
|
|
1023
|
-
status: result.exitCode === 0 ? "completed" : "failed",
|
|
1024
|
-
providerRequested: "gemini",
|
|
1025
|
-
providerResolved: "gemini",
|
|
1026
|
-
agentType: args.agentType,
|
|
1027
|
-
transport: "gemini-worker",
|
|
1028
|
-
exitCode: result.exitCode,
|
|
1029
|
-
output: result.output,
|
|
1030
|
-
sessionKey: result.sessionKey,
|
|
1031
|
-
_geminiPrompt: prompt,
|
|
1032
|
-
};
|
|
1033
|
-
} finally {
|
|
1034
|
-
await worker.stop().catch(() => {});
|
|
1035
|
-
}
|
|
1036
|
-
}
|
|
1037
|
-
|
|
1038
844
|
return createErrorPayload(
|
|
1039
845
|
`지원하지 않는 direct provider: ${args.provider}`,
|
|
1040
846
|
{
|
|
@@ -1155,30 +961,6 @@ export class DelegatorMcpWorker {
|
|
|
1155
961
|
};
|
|
1156
962
|
}
|
|
1157
963
|
|
|
1158
|
-
if (args.provider === "gemini") {
|
|
1159
|
-
const worker = this._createGeminiWorker();
|
|
1160
|
-
job.worker = worker;
|
|
1161
|
-
const prompt = this._buildDirectPromptWithHint(args);
|
|
1162
|
-
const result = await worker.execute(prompt, {
|
|
1163
|
-
cwd: args.cwd || this.cwd,
|
|
1164
|
-
timeoutMs: resolveTimeoutMs(args.agentType, args.timeoutMs),
|
|
1165
|
-
model: args.model || resolveGeminiModel(args.agentType),
|
|
1166
|
-
approvalMode: "yolo",
|
|
1167
|
-
allowedMcpServerNames: getGeminiAllowedServers(
|
|
1168
|
-
this._getMcpPolicyOptions(args),
|
|
1169
|
-
),
|
|
1170
|
-
});
|
|
1171
|
-
|
|
1172
|
-
return {
|
|
1173
|
-
ok: result.exitCode === 0,
|
|
1174
|
-
providerResolved: "gemini",
|
|
1175
|
-
output: result.output,
|
|
1176
|
-
exitCode: result.exitCode,
|
|
1177
|
-
sessionKey: result.sessionKey,
|
|
1178
|
-
_geminiPrompt: prompt,
|
|
1179
|
-
};
|
|
1180
|
-
}
|
|
1181
|
-
|
|
1182
964
|
throw new Error(`지원하지 않는 async provider: ${args.provider}`);
|
|
1183
965
|
}
|
|
1184
966
|
|
|
@@ -1287,7 +1069,7 @@ export class DelegatorMcpWorker {
|
|
|
1287
1069
|
error: "",
|
|
1288
1070
|
thread_id: job.threadId,
|
|
1289
1071
|
session_key: job.sessionKey,
|
|
1290
|
-
conversation_open:
|
|
1072
|
+
conversation_open: false,
|
|
1291
1073
|
};
|
|
1292
1074
|
}
|
|
1293
1075
|
|
|
@@ -1332,44 +1114,6 @@ export class DelegatorMcpWorker {
|
|
|
1332
1114
|
job.sessionKey = result.sessionKey || job.sessionKey || null;
|
|
1333
1115
|
job.completedAt = new Date().toISOString();
|
|
1334
1116
|
job.updatedAt = job.completedAt;
|
|
1335
|
-
|
|
1336
|
-
if (
|
|
1337
|
-
job.providerRequested === "gemini" &&
|
|
1338
|
-
job.transport === "gemini-worker" &&
|
|
1339
|
-
typeof result._geminiPrompt === "string"
|
|
1340
|
-
) {
|
|
1341
|
-
this._storeGeminiConversation(
|
|
1342
|
-
job,
|
|
1343
|
-
result._geminiPrompt,
|
|
1344
|
-
result.output || "",
|
|
1345
|
-
);
|
|
1346
|
-
}
|
|
1347
|
-
}
|
|
1348
|
-
|
|
1349
|
-
_storeGeminiConversation(job, userPrompt, assistantReply) {
|
|
1350
|
-
const existing = this.geminiConversations.get(job.jobId);
|
|
1351
|
-
if (existing) {
|
|
1352
|
-
if (typeof assistantReply === "string") {
|
|
1353
|
-
const lastTurn = existing.turns.at(-1);
|
|
1354
|
-
if (lastTurn && lastTurn.assistant !== assistantReply) {
|
|
1355
|
-
lastTurn.assistant = assistantReply;
|
|
1356
|
-
}
|
|
1357
|
-
}
|
|
1358
|
-
existing.updatedAt = new Date().toISOString();
|
|
1359
|
-
return;
|
|
1360
|
-
}
|
|
1361
|
-
|
|
1362
|
-
this.geminiConversations.set(job.jobId, {
|
|
1363
|
-
jobId: job.jobId,
|
|
1364
|
-
closed: false,
|
|
1365
|
-
updatedAt: new Date().toISOString(),
|
|
1366
|
-
turns: [
|
|
1367
|
-
{
|
|
1368
|
-
user: userPrompt,
|
|
1369
|
-
assistant: assistantReply,
|
|
1370
|
-
},
|
|
1371
|
-
],
|
|
1372
|
-
});
|
|
1373
1117
|
}
|
|
1374
1118
|
|
|
1375
1119
|
async _runSyncJob(args, extra) {
|
package/hub/workers/factory.mjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// hub/workers/factory.mjs — Worker 생성 팩토리
|
|
2
2
|
//
|
|
3
3
|
// Supported worker types:
|
|
4
|
-
// - 'gemini' →
|
|
4
|
+
// - 'gemini' → AntigravityRouteWorker (deprecated alias)
|
|
5
|
+
// - 'antigravity' → AntigravityRouteWorker
|
|
5
6
|
// - 'claude' → ClaudeWorker
|
|
6
7
|
// - 'codex' → CodexMcpWorker (default) or CodexAppServerWorker when
|
|
7
8
|
// opts.transport === 'app-server'
|
|
@@ -14,8 +15,8 @@
|
|
|
14
15
|
// `publishCallback` or swap the transport with `requestJsonFn`.
|
|
15
16
|
|
|
16
17
|
import { ClaudeWorker } from "./claude-worker.mjs";
|
|
18
|
+
import { AntigravityRouteWorker } from "./antigravity-route-worker.mjs";
|
|
17
19
|
import { CodexAppServerWorker } from "./codex-app-server-worker.mjs";
|
|
18
|
-
import { GeminiWorker } from "./gemini-worker.mjs";
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* Build a best-effort publishCallback that posts the envelope to
|
|
@@ -76,14 +77,16 @@ async function createCodexWorker(opts = {}) {
|
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
/**
|
|
79
|
-
* @param {'gemini'|'claude'|'codex'|'codex-app-server'|'delegator'} type
|
|
80
|
+
* @param {'gemini'|'antigravity'|'agy'|'claude'|'codex'|'codex-app-server'|'delegator'} type
|
|
80
81
|
* @param {object} [opts]
|
|
81
82
|
* @returns {Promise<import('./interface.mjs').IWorker>}
|
|
82
83
|
*/
|
|
83
84
|
export async function createWorker(type, opts = {}) {
|
|
84
85
|
switch (type) {
|
|
85
86
|
case "gemini":
|
|
86
|
-
|
|
87
|
+
case "antigravity":
|
|
88
|
+
case "agy":
|
|
89
|
+
return new AntigravityRouteWorker(opts);
|
|
87
90
|
case "claude":
|
|
88
91
|
return new ClaudeWorker(opts);
|
|
89
92
|
case "codex":
|