funolio-agent 0.17.9 → 1.0.3
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/dist/approval.d.ts +7 -6
- package/dist/approval.d.ts.map +1 -1
- package/dist/approval.js +40 -10
- package/dist/approval.js.map +1 -1
- package/dist/backfill.js +2 -2
- package/dist/backfill.js.map +1 -1
- package/dist/clerk-model.d.ts +0 -1
- package/dist/clerk-model.d.ts.map +1 -1
- package/dist/clerk-model.js +24 -50
- package/dist/clerk-model.js.map +1 -1
- package/dist/commands/configure-provider.js +2 -2
- package/dist/commands/configure-provider.js.map +1 -1
- package/dist/commands/configure.d.ts.map +1 -1
- package/dist/commands/configure.js +10 -14
- package/dist/commands/configure.js.map +1 -1
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +17 -2
- package/dist/commands/start.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/context-window.d.ts +2 -8
- package/dist/context-window.d.ts.map +1 -1
- package/dist/context-window.js +4 -4
- package/dist/context-window.js.map +1 -1
- package/dist/eval/orchestrator-front-door-replay.js +43 -2
- package/dist/eval/orchestrator-front-door-replay.js.map +1 -1
- package/dist/eval/orchestrator-todo-dispatch-replay.d.ts +2 -0
- package/dist/eval/orchestrator-todo-dispatch-replay.d.ts.map +1 -0
- package/dist/eval/orchestrator-todo-dispatch-replay.js +253 -0
- package/dist/eval/orchestrator-todo-dispatch-replay.js.map +1 -0
- package/dist/eval/orchestrator-todo-planning-replay.d.ts +2 -0
- package/dist/eval/orchestrator-todo-planning-replay.d.ts.map +1 -0
- package/dist/eval/orchestrator-todo-planning-replay.js +247 -0
- package/dist/eval/orchestrator-todo-planning-replay.js.map +1 -0
- package/dist/eval/policy-detection-replay.d.ts +2 -0
- package/dist/eval/policy-detection-replay.d.ts.map +1 -0
- package/dist/eval/policy-detection-replay.js +122 -0
- package/dist/eval/policy-detection-replay.js.map +1 -0
- package/dist/eval/todo-worker-runtime-replay.d.ts +2 -0
- package/dist/eval/todo-worker-runtime-replay.d.ts.map +1 -0
- package/dist/eval/todo-worker-runtime-replay.js +520 -0
- package/dist/eval/todo-worker-runtime-replay.js.map +1 -0
- package/dist/integration-tokens.d.ts +6 -0
- package/dist/integration-tokens.d.ts.map +1 -1
- package/dist/integration-tokens.js +43 -0
- package/dist/integration-tokens.js.map +1 -1
- package/dist/local-data.d.ts +128 -1
- package/dist/local-data.d.ts.map +1 -1
- package/dist/local-data.js +702 -18
- package/dist/local-data.js.map +1 -1
- package/dist/local-db.d.ts.map +1 -1
- package/dist/local-db.js +216 -12
- package/dist/local-db.js.map +1 -1
- package/dist/local-funnel.d.ts.map +1 -1
- package/dist/local-funnel.js +7 -0
- package/dist/local-funnel.js.map +1 -1
- package/dist/local-server.d.ts.map +1 -1
- package/dist/local-server.js +119 -96
- package/dist/local-server.js.map +1 -1
- package/dist/mcp/bridge-server.d.ts.map +1 -1
- package/dist/mcp/bridge-server.js +8 -2
- package/dist/mcp/bridge-server.js.map +1 -1
- package/dist/mcp/manager.d.ts +5 -0
- package/dist/mcp/manager.d.ts.map +1 -1
- package/dist/mcp/manager.js +36 -0
- package/dist/mcp/manager.js.map +1 -1
- package/dist/mcp/sync-cli-config.d.ts +5 -0
- package/dist/mcp/sync-cli-config.d.ts.map +1 -1
- package/dist/mcp/sync-cli-config.js +10 -2
- package/dist/mcp/sync-cli-config.js.map +1 -1
- package/dist/message-loop.d.ts.map +1 -1
- package/dist/message-loop.js +113 -14
- package/dist/message-loop.js.map +1 -1
- package/dist/mqtt-client.d.ts +44 -0
- package/dist/mqtt-client.d.ts.map +1 -1
- package/dist/mqtt-client.js.map +1 -1
- package/dist/orchestration/front-door-policy.d.ts +26 -9
- package/dist/orchestration/front-door-policy.d.ts.map +1 -1
- package/dist/orchestration/front-door-policy.js +242 -69
- package/dist/orchestration/front-door-policy.js.map +1 -1
- package/dist/orchestration/orchestrator-blocked-prompt.d.ts +18 -0
- package/dist/orchestration/orchestrator-blocked-prompt.d.ts.map +1 -0
- package/dist/orchestration/orchestrator-blocked-prompt.js +46 -0
- package/dist/orchestration/orchestrator-blocked-prompt.js.map +1 -0
- package/dist/orchestration/orchestrator-final-response-prompt.d.ts +10 -0
- package/dist/orchestration/orchestrator-final-response-prompt.d.ts.map +1 -0
- package/dist/orchestration/orchestrator-final-response-prompt.js +39 -0
- package/dist/orchestration/orchestrator-final-response-prompt.js.map +1 -0
- package/dist/orchestration/orchestrator-operating-prompt.d.ts +11 -0
- package/dist/orchestration/orchestrator-operating-prompt.d.ts.map +1 -1
- package/dist/orchestration/orchestrator-operating-prompt.js +106 -36
- package/dist/orchestration/orchestrator-operating-prompt.js.map +1 -1
- package/dist/orchestration/policy-prompt.d.ts +6 -0
- package/dist/orchestration/policy-prompt.d.ts.map +1 -0
- package/dist/orchestration/policy-prompt.js +40 -0
- package/dist/orchestration/policy-prompt.js.map +1 -0
- package/dist/orchestration/worker-operating-prompt.d.ts +16 -0
- package/dist/orchestration/worker-operating-prompt.d.ts.map +1 -0
- package/dist/orchestration/worker-operating-prompt.js +75 -0
- package/dist/orchestration/worker-operating-prompt.js.map +1 -0
- package/dist/orchestrator.d.ts +19 -0
- package/dist/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator.js +614 -54
- package/dist/orchestrator.js.map +1 -1
- package/dist/policy-detection.d.ts +40 -0
- package/dist/policy-detection.d.ts.map +1 -0
- package/dist/policy-detection.js +298 -0
- package/dist/policy-detection.js.map +1 -0
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +28 -5
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/claude-cli.d.ts.map +1 -1
- package/dist/providers/claude-cli.js +11 -2
- package/dist/providers/claude-cli.js.map +1 -1
- package/dist/providers/codex-cli.d.ts.map +1 -1
- package/dist/providers/codex-cli.js +121 -2
- package/dist/providers/codex-cli.js.map +1 -1
- package/dist/providers/index.d.ts +4 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/summarization-pipeline.d.ts +1 -4
- package/dist/summarization-pipeline.d.ts.map +1 -1
- package/dist/summarization-pipeline.js +43 -56
- package/dist/summarization-pipeline.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/todo-tasks.d.ts +2 -0
- package/dist/tools/todo-tasks.d.ts.map +1 -1
- package/dist/tools/todo-tasks.js +203 -6
- package/dist/tools/todo-tasks.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/wizard-state.d.ts.map +1 -1
- package/dist/wizard-state.js +30 -8
- package/dist/wizard-state.js.map +1 -1
- package/dist/wizard-support.d.ts +2 -2
- package/dist/wizard-support.d.ts.map +1 -1
- package/dist/wizard-support.js +80 -93
- package/dist/wizard-support.js.map +1 -1
- package/dist/workflow-engine.d.ts +3 -0
- package/dist/workflow-engine.d.ts.map +1 -1
- package/dist/workflow-engine.js +111 -82
- package/dist/workflow-engine.js.map +1 -1
- package/package.json +5 -1
package/dist/workflow-engine.js
CHANGED
|
@@ -646,6 +646,46 @@ class WorkflowEngine extends events_1.EventEmitter {
|
|
|
646
646
|
reasonLine,
|
|
647
647
|
].join('\n');
|
|
648
648
|
}
|
|
649
|
+
buildOrchestratedTodoWorkerSystemPrompt(step, profile) {
|
|
650
|
+
const role = this.inferRoleForStep(step);
|
|
651
|
+
const roleLine = role === 'research'
|
|
652
|
+
? 'Your role is researcher. Produce the requested plan or analysis, then complete the TODO through the worker tool.'
|
|
653
|
+
: role === 'qa'
|
|
654
|
+
? 'Your role is QA. Verify the delivered work, then complete the TODO through the worker tool or create the next fix handoff.'
|
|
655
|
+
: 'Your role is implementer. Do the assigned work, then complete the TODO through the worker tool.';
|
|
656
|
+
return [
|
|
657
|
+
`You are ${profile?.name || 'a Funolio workflow worker'}.`,
|
|
658
|
+
'You are executing one orchestrated TODO task inside Funolio.',
|
|
659
|
+
roleLine,
|
|
660
|
+
'Follow the assignment in the user message exactly.',
|
|
661
|
+
'Use available tools when needed.',
|
|
662
|
+
'Do not return a plain-text final answer until you have called complete_worker_task or block_worker_task.',
|
|
663
|
+
'Do not add workflow planning, orchestration narration, or TODO-management commentary outside those tools.',
|
|
664
|
+
'If blocked after checking available context, call block_worker_task with blocker_summary, checked_context, and user_question.',
|
|
665
|
+
'If the task is complete, call complete_worker_task with output_summary and any needed handoff prompt or inserted next task.',
|
|
666
|
+
].join('\n');
|
|
667
|
+
}
|
|
668
|
+
buildOrchestratedTodoHandledResult(taskId) {
|
|
669
|
+
if (!taskId)
|
|
670
|
+
return 'TODO handled.';
|
|
671
|
+
const completed = data.getTodoTask(taskId, 'completed');
|
|
672
|
+
if (completed) {
|
|
673
|
+
return completed.output_summary?.trim()
|
|
674
|
+
|| completed.handoff_prompt?.trim()
|
|
675
|
+
|| `Completed TODO #${taskId}.`;
|
|
676
|
+
}
|
|
677
|
+
const blocked = data.getTodoTask(taskId, 'active');
|
|
678
|
+
if (blocked?.blocker_summary) {
|
|
679
|
+
return blocked.blocker_summary.trim();
|
|
680
|
+
}
|
|
681
|
+
return `Handled TODO #${taskId}.`;
|
|
682
|
+
}
|
|
683
|
+
orchestratedTodoHandled(taskId) {
|
|
684
|
+
if (!taskId)
|
|
685
|
+
return false;
|
|
686
|
+
return Boolean(data.getTodoTask(taskId, 'completed')
|
|
687
|
+
|| data.getTodoTask(taskId, 'active')?.blocker_summary);
|
|
688
|
+
}
|
|
649
689
|
buildWorkflowStepPrompt(step, pinnedContext, handoffArtifacts) {
|
|
650
690
|
const sections = [step.prompt.trim()];
|
|
651
691
|
if (pinnedContext.length > 0) {
|
|
@@ -1250,12 +1290,17 @@ class WorkflowEngine extends events_1.EventEmitter {
|
|
|
1250
1290
|
...(activeRuntime.apiStyle ? { apiStyle: activeRuntime.apiStyle } : {}),
|
|
1251
1291
|
...(activeRuntime.authMode ? { authMode: activeRuntime.authMode } : {}),
|
|
1252
1292
|
...(activeRuntime.extraHeaders ? { extraHeaders: activeRuntime.extraHeaders } : {}),
|
|
1293
|
+
...(opts?.isOrchestrated ? { preserveMcpBridge: true } : {}),
|
|
1294
|
+
...(opts?.isOrchestrated ? { toolActorId: step.agentName } : {}),
|
|
1295
|
+
...(opts?.isOrchestrated ? { toolProjectId: opts?.projectId ?? null } : {}),
|
|
1296
|
+
...(opts?.isOrchestrated ? { currentTodoTaskId: opts?.taskId } : {}),
|
|
1253
1297
|
});
|
|
1254
1298
|
const toolDefs = (0, index_2.getAllToolDefinitions)();
|
|
1255
1299
|
const workspacePath = opts?.workspacePath?.trim();
|
|
1256
1300
|
const effectiveProjectDir = workspacePath || this.projectDir;
|
|
1257
1301
|
const toolCtx = (0, index_2.createToolContext)(effectiveProjectDir, {
|
|
1258
1302
|
projectId: opts?.projectId ?? null,
|
|
1303
|
+
currentTodoTaskId: opts?.taskId,
|
|
1259
1304
|
actorType: 'llm',
|
|
1260
1305
|
actorId: step.agentName || step.agentId,
|
|
1261
1306
|
});
|
|
@@ -1266,6 +1311,9 @@ class WorkflowEngine extends events_1.EventEmitter {
|
|
|
1266
1311
|
if (opts?.systemPromptOverride?.trim()) {
|
|
1267
1312
|
systemPrompt = opts.systemPromptOverride.trim();
|
|
1268
1313
|
}
|
|
1314
|
+
else if (opts?.isOrchestrated) {
|
|
1315
|
+
systemPrompt = this.buildOrchestratedTodoWorkerSystemPrompt(step, profile);
|
|
1316
|
+
}
|
|
1269
1317
|
else if (isWorkflowWorker) {
|
|
1270
1318
|
systemPrompt = this.buildWorkflowWorkerSystemPrompt(step, profile);
|
|
1271
1319
|
}
|
|
@@ -1288,8 +1336,11 @@ class WorkflowEngine extends events_1.EventEmitter {
|
|
|
1288
1336
|
});
|
|
1289
1337
|
systemPrompt = built.systemPrompt;
|
|
1290
1338
|
}
|
|
1291
|
-
const
|
|
1292
|
-
|
|
1339
|
+
const effectivePrompt = opts?.isOrchestrated && opts?.taskId
|
|
1340
|
+
? `CURRENT TODO ID: ${opts.taskId}\nUse this TODO id when calling complete_worker_task or block_worker_task.\n\n${prompt}`
|
|
1341
|
+
: prompt;
|
|
1342
|
+
const messages = [{ role: 'user', content: effectivePrompt }];
|
|
1343
|
+
const promptChars = effectivePrompt.length;
|
|
1293
1344
|
const systemChars = systemPrompt.length;
|
|
1294
1345
|
console.info(`[workflow-engine] step runtime: agent=${step.agentName} provider=${activeRuntime.providerName} model=${activeRuntime.model} runtime=${activeRuntime.runtimeLabel || 'unknown'} promptChars=${promptChars} systemChars=${systemChars} tools=${opts?.disableTools ? 0 : toolDefs.length}`);
|
|
1295
1346
|
// Agentic loop
|
|
@@ -1303,11 +1354,14 @@ class WorkflowEngine extends events_1.EventEmitter {
|
|
|
1303
1354
|
let emittedChunkHeartbeat = false;
|
|
1304
1355
|
let chunkBuffer = '';
|
|
1305
1356
|
let lastChunkForwardAt = 0;
|
|
1306
|
-
const toolChoice =
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1357
|
+
const toolChoice = opts?.disableTools
|
|
1358
|
+
? 'auto'
|
|
1359
|
+
: opts?.isOrchestrated
|
|
1360
|
+
? 'required'
|
|
1361
|
+
: !messages.some((message) => message.role === 'tool')
|
|
1362
|
+
&& this.stepRequiresConcreteArtifact(step, prompt)
|
|
1363
|
+
? 'required'
|
|
1364
|
+
: 'auto';
|
|
1311
1365
|
let response;
|
|
1312
1366
|
try {
|
|
1313
1367
|
response = await llm.chat({
|
|
@@ -1380,6 +1434,10 @@ class WorkflowEngine extends events_1.EventEmitter {
|
|
|
1380
1434
|
...(activeRuntime.apiStyle ? { apiStyle: activeRuntime.apiStyle } : {}),
|
|
1381
1435
|
...(activeRuntime.authMode ? { authMode: activeRuntime.authMode } : {}),
|
|
1382
1436
|
...(activeRuntime.extraHeaders ? { extraHeaders: activeRuntime.extraHeaders } : {}),
|
|
1437
|
+
...(opts?.isOrchestrated ? { preserveMcpBridge: true } : {}),
|
|
1438
|
+
...(opts?.isOrchestrated ? { toolActorId: step.agentName } : {}),
|
|
1439
|
+
...(opts?.isOrchestrated ? { toolProjectId: opts?.projectId ?? null } : {}),
|
|
1440
|
+
...(opts?.isOrchestrated ? { currentTodoTaskId: opts?.taskId } : {}),
|
|
1383
1441
|
});
|
|
1384
1442
|
console.warn(`[workflow-engine] ${step.agentName} runtime failed, retrying with ${activeRuntime.providerName}`);
|
|
1385
1443
|
iteration--;
|
|
@@ -1432,12 +1490,39 @@ class WorkflowEngine extends events_1.EventEmitter {
|
|
|
1432
1490
|
});
|
|
1433
1491
|
}
|
|
1434
1492
|
}
|
|
1493
|
+
if (opts?.isOrchestrated && this.orchestratedTodoHandled(opts.taskId)) {
|
|
1494
|
+
return this.buildOrchestratedTodoHandledResult(opts.taskId);
|
|
1495
|
+
}
|
|
1435
1496
|
continue;
|
|
1436
1497
|
}
|
|
1437
1498
|
// No tool calls — final response
|
|
1438
1499
|
const content = response.content || streamedContent || '';
|
|
1439
1500
|
const usedToolsThisStep = messages.some((message) => message.role === 'tool');
|
|
1440
1501
|
const usedMutatingToolsThisStep = messages.some((message) => message.role === 'tool' && this.isMutatingToolName(message.toolName));
|
|
1502
|
+
if (opts?.isOrchestrated && !this.orchestratedTodoHandled(opts.taskId)) {
|
|
1503
|
+
const correction = [
|
|
1504
|
+
'You did not finish the orchestrated TODO correctly.',
|
|
1505
|
+
'Do not answer with plain text alone.',
|
|
1506
|
+
'You must call complete_worker_task when the task is done, or block_worker_task if you cannot proceed.',
|
|
1507
|
+
'If you already finished the work, call complete_worker_task now with output_summary and any needed handoff.',
|
|
1508
|
+
'If you are blocked, call block_worker_task now with blocker_summary, checked_context, and user_question.',
|
|
1509
|
+
].join(' ');
|
|
1510
|
+
const preview = content.replace(/\s+/g, ' ').trim().slice(0, 240);
|
|
1511
|
+
console.warn(`[workflow-engine] orchestrated TODO not completed through worker tool: agent=${step.agentName} iteration=${iteration} preview=${preview}`);
|
|
1512
|
+
if (incompleteExecutionRecoveries < 1) {
|
|
1513
|
+
incompleteExecutionRecoveries++;
|
|
1514
|
+
if (content.trim()) {
|
|
1515
|
+
messages.push({ role: 'assistant', content });
|
|
1516
|
+
}
|
|
1517
|
+
messages.push({ role: 'user', content: correction });
|
|
1518
|
+
const activeSteps = workflowContext?.workflowId
|
|
1519
|
+
? this.getActiveWorkflows().find((w) => w.id === workflowContext.workflowId)?.steps || [step]
|
|
1520
|
+
: [step];
|
|
1521
|
+
this.emitProgress(workflowContext?.workflowId || 'workflow', step, activeSteps, 'step-progress', opts?.onProgress, `${step.agentName} must finish the TODO using complete_worker_task or block_worker_task.`);
|
|
1522
|
+
continue;
|
|
1523
|
+
}
|
|
1524
|
+
throw new Error('INCOMPLETE_EXECUTION: The worker returned text without completing the TODO via complete_worker_task or block_worker_task.');
|
|
1525
|
+
}
|
|
1441
1526
|
// Parse structured footer for workflow steps
|
|
1442
1527
|
const footer = (0, status_parser_1.parseStructuredFooter)(content);
|
|
1443
1528
|
const artifactTargetsSatisfied = this.requiredArtifactTargetsSatisfied(step, prompt, effectiveProjectDir);
|
|
@@ -1478,6 +1563,10 @@ class WorkflowEngine extends events_1.EventEmitter {
|
|
|
1478
1563
|
...(activeRuntime.apiStyle ? { apiStyle: activeRuntime.apiStyle } : {}),
|
|
1479
1564
|
...(activeRuntime.authMode ? { authMode: activeRuntime.authMode } : {}),
|
|
1480
1565
|
...(activeRuntime.extraHeaders ? { extraHeaders: activeRuntime.extraHeaders } : {}),
|
|
1566
|
+
...(opts?.isOrchestrated ? { preserveMcpBridge: true } : {}),
|
|
1567
|
+
...(opts?.isOrchestrated ? { toolActorId: step.agentName } : {}),
|
|
1568
|
+
...(opts?.isOrchestrated ? { toolProjectId: opts?.projectId ?? null } : {}),
|
|
1569
|
+
...(opts?.isOrchestrated ? { currentTodoTaskId: opts?.taskId } : {}),
|
|
1481
1570
|
});
|
|
1482
1571
|
incompleteExecutionRecoveries = 0;
|
|
1483
1572
|
iteration--;
|
|
@@ -1591,8 +1680,6 @@ class WorkflowEngine extends events_1.EventEmitter {
|
|
|
1591
1680
|
const providerConnection = data.findProviderConnection(provider);
|
|
1592
1681
|
if (providerConnection?.api_key_enc)
|
|
1593
1682
|
return providerConnection.api_key_enc;
|
|
1594
|
-
if (providerConnection?.oauth_token)
|
|
1595
|
-
return providerConnection.oauth_token;
|
|
1596
1683
|
switch (provider) {
|
|
1597
1684
|
case 'anthropic': return process.env.ANTHROPIC_API_KEY;
|
|
1598
1685
|
case 'openai': return process.env.OPENAI_API_KEY;
|
|
@@ -1612,7 +1699,6 @@ class WorkflowEngine extends events_1.EventEmitter {
|
|
|
1612
1699
|
: undefined;
|
|
1613
1700
|
const resolvedKey = profile?.api_key_enc
|
|
1614
1701
|
|| profileConnection?.api_key_enc
|
|
1615
|
-
|| profileConnection?.oauth_token
|
|
1616
1702
|
|| apiKey
|
|
1617
1703
|
|| this.resolveApiKey(step.provider);
|
|
1618
1704
|
if (!resolvedKey) {
|
|
@@ -1626,9 +1712,6 @@ class WorkflowEngine extends events_1.EventEmitter {
|
|
|
1626
1712
|
};
|
|
1627
1713
|
}
|
|
1628
1714
|
async resolveClaudeWorkflowRuntime(step, profile) {
|
|
1629
|
-
const profileConnection = profile?.provider_connection_id
|
|
1630
|
-
? data.getProviderConnection(profile.provider_connection_id)
|
|
1631
|
-
: undefined;
|
|
1632
1715
|
const preferredModel = (0, subscription_runtime_1.resolveSubscriptionApiModel)(step.model || profile?.model, data.findProviderConnection('anthropic')?.default_model || data.findProviderConnection('claude-cli')?.default_model || undefined) || (step.model || profile?.model || 'default').trim() || 'default';
|
|
1633
1716
|
const apiKeyFallback = data.findProviderConnection('anthropic')?.api_key_enc || process.env.ANTHROPIC_API_KEY;
|
|
1634
1717
|
const apiFallbackConfig = apiKeyFallback
|
|
@@ -1646,63 +1729,28 @@ class WorkflowEngine extends events_1.EventEmitter {
|
|
|
1646
1729
|
runtimeLabel: 'Subscription CLI',
|
|
1647
1730
|
...(apiFallbackConfig ? { fallback: apiFallbackConfig } : {}),
|
|
1648
1731
|
};
|
|
1649
|
-
|
|
1650
|
-
const runtime = await (0, subscription_runtime_1.resolveClaudeSubscriptionRuntime)({
|
|
1651
|
-
preferredModel,
|
|
1652
|
-
inputToken: profileConnection?.access_mode === 'openclaw' ? (profileConnection.api_key_enc || null) : null,
|
|
1653
|
-
inputAccessMode: profileConnection?.access_mode || null,
|
|
1654
|
-
});
|
|
1655
|
-
if (!runtime)
|
|
1656
|
-
return cliFallbackConfig;
|
|
1657
|
-
return {
|
|
1658
|
-
providerName: runtime.providerName,
|
|
1659
|
-
apiKey: runtime.apiKey,
|
|
1660
|
-
model: runtime.model,
|
|
1661
|
-
runtimeLabel: (0, subscription_runtime_1.claudeSubscriptionRuntimeLabel)(runtime.source),
|
|
1662
|
-
requestShape: (0, subscription_runtime_1.resolveClaudeSubscriptionRequestShape)(runtime.source),
|
|
1663
|
-
baseUrl: runtime.baseUrl,
|
|
1664
|
-
apiQuery: runtime.apiQuery,
|
|
1665
|
-
authMode: runtime.authMode,
|
|
1666
|
-
extraHeaders: runtime.extraHeaders,
|
|
1667
|
-
fallback: cliFallbackConfig,
|
|
1668
|
-
};
|
|
1669
|
-
}
|
|
1670
|
-
catch (err) {
|
|
1671
|
-
console.warn(`[workflow-engine] Claude subscription auth failed: ${err?.message || err}`);
|
|
1672
|
-
return cliFallbackConfig;
|
|
1673
|
-
}
|
|
1732
|
+
return cliFallbackConfig;
|
|
1674
1733
|
}
|
|
1675
1734
|
async resolveCodexWorkflowRuntime(step, profile) {
|
|
1676
1735
|
const preferredModel = (0, subscription_runtime_1.resolveSubscriptionApiModel)(step.model || profile?.model, data.findProviderConnection('openai')?.default_model || data.findProviderConnection('codex-cli')?.default_model || undefined)
|
|
1677
1736
|
|| (step.model || profile?.model || 'default').trim()
|
|
1678
1737
|
|| 'default';
|
|
1679
|
-
|
|
1680
|
-
const runtime = await (0, subscription_runtime_1.resolveCodexSubscriptionRuntime)({ preferredModel });
|
|
1681
|
-
if (runtime) {
|
|
1682
|
-
return {
|
|
1683
|
-
providerName: runtime.providerName,
|
|
1684
|
-
apiKey: runtime.apiKey,
|
|
1685
|
-
model: runtime.model,
|
|
1686
|
-
runtimeLabel: 'Subscription API',
|
|
1687
|
-
baseUrl: runtime.baseUrl,
|
|
1688
|
-
apiStyle: runtime.apiStyle,
|
|
1689
|
-
fallback: {
|
|
1690
|
-
providerName: 'codex-cli',
|
|
1691
|
-
apiKey: 'cli-auth',
|
|
1692
|
-
model: (step.model || profile?.model || 'default').trim() || 'default',
|
|
1693
|
-
runtimeLabel: 'Subscription CLI',
|
|
1694
|
-
},
|
|
1695
|
-
};
|
|
1696
|
-
}
|
|
1697
|
-
}
|
|
1698
|
-
catch (err) {
|
|
1699
|
-
console.warn(`[workflow-engine] Codex subscription auth failed: ${err?.message || err}`);
|
|
1700
|
-
}
|
|
1738
|
+
const apiKeyFallback = data.findProviderConnection('openai')?.api_key_enc || process.env.OPENAI_API_KEY;
|
|
1701
1739
|
return {
|
|
1702
1740
|
providerName: 'codex-cli',
|
|
1703
1741
|
apiKey: 'cli-auth',
|
|
1704
1742
|
model: (step.model || profile?.model || 'default').trim() || 'default',
|
|
1705
1743
|
runtimeLabel: 'Subscription CLI',
|
|
1744
|
+
...(apiKeyFallback
|
|
1745
|
+
? {
|
|
1746
|
+
fallback: {
|
|
1747
|
+
providerName: 'openai',
|
|
1748
|
+
apiKey: apiKeyFallback,
|
|
1749
|
+
model: preferredModel,
|
|
1750
|
+
runtimeLabel: 'API Key',
|
|
1751
|
+
},
|
|
1752
|
+
}
|
|
1753
|
+
: {}),
|
|
1706
1754
|
};
|
|
1707
1755
|
}
|
|
1708
1756
|
async preflightWorkflowReadiness(steps) {
|
|
@@ -1717,28 +1765,9 @@ class WorkflowEngine extends events_1.EventEmitter {
|
|
|
1717
1765
|
failures.push({ step, reason: `Bot profile ${step.agentId} is missing.` });
|
|
1718
1766
|
continue;
|
|
1719
1767
|
}
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
}).catch(() => null);
|
|
1724
|
-
if (runtime?.apiKey)
|
|
1725
|
-
continue;
|
|
1726
|
-
failures.push({
|
|
1727
|
-
step,
|
|
1728
|
-
reason: `${profile.name} is not authenticated for Claude subscription access. Reconnect Claude login before running this workflow.`,
|
|
1729
|
-
});
|
|
1730
|
-
continue;
|
|
1731
|
-
}
|
|
1732
|
-
if (profile.provider === 'codex-cli') {
|
|
1733
|
-
const runtime = await (0, subscription_runtime_1.resolveCodexSubscriptionRuntime)({
|
|
1734
|
-
preferredModel: profile.model,
|
|
1735
|
-
}).catch(() => null);
|
|
1736
|
-
if (runtime?.apiKey)
|
|
1737
|
-
continue;
|
|
1738
|
-
failures.push({
|
|
1739
|
-
step,
|
|
1740
|
-
reason: `${profile.name} is not authenticated for Codex subscription access. Reconnect OpenAI/Codex login before running this workflow.`,
|
|
1741
|
-
});
|
|
1768
|
+
// CLI providers handle their own auth — skip subscription checks
|
|
1769
|
+
// (subscription API has been removed; CLI binary manages credentials directly)
|
|
1770
|
+
if (profile.provider === 'claude-cli' || profile.provider === 'codex-cli') {
|
|
1742
1771
|
continue;
|
|
1743
1772
|
}
|
|
1744
1773
|
const apiKey = profile.api_key_enc || this.resolveApiKey(profile.provider);
|