funolio-agent 1.0.53 → 1.1.65
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 +1 -6
- package/dist/approval.d.ts.map +1 -1
- package/dist/approval.js +2 -7
- package/dist/approval.js.map +1 -1
- package/dist/auth/credential-reader.d.ts.map +1 -1
- package/dist/auth/credential-reader.js +4 -3
- package/dist/auth/credential-reader.js.map +1 -1
- package/dist/auth/token-refresh.d.ts +8 -0
- package/dist/auth/token-refresh.d.ts.map +1 -1
- package/dist/auth/token-refresh.js +82 -52
- package/dist/auth/token-refresh.js.map +1 -1
- package/dist/auto-organizer.d.ts.map +1 -1
- package/dist/auto-organizer.js +6 -7
- package/dist/auto-organizer.js.map +1 -1
- package/dist/bench-prefix.d.ts +16 -0
- package/dist/bench-prefix.d.ts.map +1 -0
- package/dist/bench-prefix.js +25 -0
- package/dist/bench-prefix.js.map +1 -0
- package/dist/bot-manager.d.ts +5 -1
- package/dist/bot-manager.d.ts.map +1 -1
- package/dist/bot-manager.js +46 -27
- package/dist/bot-manager.js.map +1 -1
- package/dist/chat-sync.d.ts +42 -0
- package/dist/chat-sync.d.ts.map +1 -0
- package/dist/chat-sync.js +95 -0
- package/dist/chat-sync.js.map +1 -0
- package/dist/clerk-model.d.ts +7 -0
- package/dist/clerk-model.d.ts.map +1 -1
- package/dist/clerk-model.js +42 -8
- package/dist/clerk-model.js.map +1 -1
- package/dist/cli-bootstrap-history.d.ts +10 -0
- package/dist/cli-bootstrap-history.d.ts.map +1 -0
- package/dist/cli-bootstrap-history.js +112 -0
- package/dist/cli-bootstrap-history.js.map +1 -0
- package/dist/cli-models.d.ts +8 -0
- package/dist/cli-models.d.ts.map +1 -0
- package/dist/cli-models.js +91 -0
- package/dist/cli-models.js.map +1 -0
- package/dist/cli-session-epoch.d.ts +13 -3
- package/dist/cli-session-epoch.d.ts.map +1 -1
- package/dist/cli-session-epoch.js +53 -4
- package/dist/cli-session-epoch.js.map +1 -1
- package/dist/cli-session-registry.d.ts +35 -0
- package/dist/cli-session-registry.d.ts.map +1 -0
- package/dist/cli-session-registry.js +177 -0
- package/dist/cli-session-registry.js.map +1 -0
- package/dist/cli.js +62 -0
- package/dist/cli.js.map +1 -1
- package/dist/codex-app-server-manager.d.ts +189 -0
- package/dist/codex-app-server-manager.d.ts.map +1 -0
- package/dist/codex-app-server-manager.js +1468 -0
- package/dist/codex-app-server-manager.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +8 -30
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/pool.d.ts +32 -0
- package/dist/commands/pool.d.ts.map +1 -1
- package/dist/commands/pool.js +145 -66
- package/dist/commands/pool.js.map +1 -1
- package/dist/commands/setup.d.ts +4 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +9 -25
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/start.d.ts +21 -0
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +559 -63
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +5 -2
- package/dist/commands/status.js.map +1 -1
- package/dist/completion-marker.d.ts +7 -0
- package/dist/completion-marker.d.ts.map +1 -0
- package/dist/completion-marker.js +28 -0
- package/dist/completion-marker.js.map +1 -0
- package/dist/config.d.ts +7 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +184 -60
- package/dist/config.js.map +1 -1
- package/dist/context-window.d.ts +37 -1
- package/dist/context-window.d.ts.map +1 -1
- package/dist/context-window.js +210 -17
- package/dist/context-window.js.map +1 -1
- package/dist/live-activity.d.ts +31 -0
- package/dist/live-activity.d.ts.map +1 -0
- package/dist/live-activity.js +36 -0
- package/dist/live-activity.js.map +1 -0
- package/dist/local-chat-execution.d.ts +114 -0
- package/dist/local-chat-execution.d.ts.map +1 -0
- package/dist/local-chat-execution.js +349 -0
- package/dist/local-chat-execution.js.map +1 -0
- package/dist/local-cli-pty-manager.d.ts +186 -0
- package/dist/local-cli-pty-manager.d.ts.map +1 -1
- package/dist/local-cli-pty-manager.js +2581 -164
- package/dist/local-cli-pty-manager.js.map +1 -1
- package/dist/local-conversation-gateway.d.ts +110 -0
- package/dist/local-conversation-gateway.d.ts.map +1 -0
- package/dist/local-conversation-gateway.js +175 -0
- package/dist/local-conversation-gateway.js.map +1 -0
- package/dist/local-data.d.ts +276 -5
- package/dist/local-data.d.ts.map +1 -1
- package/dist/local-data.js +1201 -86
- package/dist/local-data.js.map +1 -1
- package/dist/local-db.d.ts +6 -0
- package/dist/local-db.d.ts.map +1 -1
- package/dist/local-db.js +428 -2
- package/dist/local-db.js.map +1 -1
- package/dist/local-funnel.d.ts.map +1 -1
- package/dist/local-funnel.js +6 -5
- package/dist/local-funnel.js.map +1 -1
- package/dist/local-server.d.ts +55 -0
- package/dist/local-server.d.ts.map +1 -1
- package/dist/local-server.js +3281 -441
- package/dist/local-server.js.map +1 -1
- package/dist/managed-process-registry.d.ts +59 -0
- package/dist/managed-process-registry.d.ts.map +1 -0
- package/dist/managed-process-registry.js +390 -0
- package/dist/managed-process-registry.js.map +1 -0
- package/dist/mcp/claude-config-writer.d.ts +5 -5
- package/dist/mcp/claude-config-writer.d.ts.map +1 -1
- package/dist/mcp/claude-config-writer.js +19 -11
- package/dist/mcp/claude-config-writer.js.map +1 -1
- package/dist/mcp/index.d.ts +4 -2
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/sync-cli-config.d.ts +42 -4
- package/dist/mcp/sync-cli-config.d.ts.map +1 -1
- package/dist/mcp/sync-cli-config.js +497 -17
- package/dist/mcp/sync-cli-config.js.map +1 -1
- package/dist/message-loop.d.ts +6 -0
- package/dist/message-loop.d.ts.map +1 -1
- package/dist/message-loop.js +281 -89
- package/dist/message-loop.js.map +1 -1
- package/dist/mqtt-client.d.ts +44 -1
- package/dist/mqtt-client.d.ts.map +1 -1
- package/dist/mqtt-client.js +284 -46
- package/dist/mqtt-client.js.map +1 -1
- package/dist/mqtt-data-relay.d.ts +44 -0
- package/dist/mqtt-data-relay.d.ts.map +1 -0
- package/dist/mqtt-data-relay.js +106 -0
- package/dist/mqtt-data-relay.js.map +1 -0
- package/dist/oauth.d.ts.map +1 -1
- package/dist/oauth.js +69 -29
- package/dist/oauth.js.map +1 -1
- package/dist/orchestration/capabilities.d.ts +13 -0
- package/dist/orchestration/capabilities.d.ts.map +1 -0
- package/dist/orchestration/capabilities.js +152 -0
- package/dist/orchestration/capabilities.js.map +1 -0
- package/dist/orchestration/dispatch-executor.d.ts +83 -0
- package/dist/orchestration/dispatch-executor.d.ts.map +1 -0
- package/dist/orchestration/dispatch-executor.js +266 -0
- package/dist/orchestration/dispatch-executor.js.map +1 -0
- package/dist/orchestration/dispatch-hint.d.ts +134 -0
- package/dist/orchestration/dispatch-hint.d.ts.map +1 -0
- package/dist/orchestration/dispatch-hint.js +247 -0
- package/dist/orchestration/dispatch-hint.js.map +1 -0
- package/dist/orchestration/dispatch-runner.d.ts +106 -0
- package/dist/orchestration/dispatch-runner.d.ts.map +1 -0
- package/dist/orchestration/dispatch-runner.js +604 -0
- package/dist/orchestration/dispatch-runner.js.map +1 -0
- package/dist/orchestration/dispatch-tools.d.ts +167 -0
- package/dist/orchestration/dispatch-tools.d.ts.map +1 -0
- package/dist/orchestration/dispatch-tools.js +328 -0
- package/dist/orchestration/dispatch-tools.js.map +1 -0
- package/dist/orchestration/front-door-policy.d.ts +35 -10
- package/dist/orchestration/front-door-policy.d.ts.map +1 -1
- package/dist/orchestration/front-door-policy.js +30 -267
- package/dist/orchestration/front-door-policy.js.map +1 -1
- package/dist/orchestration/orchestrator-dispatch-prompt.d.ts +43 -0
- package/dist/orchestration/orchestrator-dispatch-prompt.d.ts.map +1 -0
- package/dist/orchestration/orchestrator-dispatch-prompt.js +267 -0
- package/dist/orchestration/orchestrator-dispatch-prompt.js.map +1 -0
- package/dist/orchestration/orchestrator-operating-prompt.d.ts +15 -0
- package/dist/orchestration/orchestrator-operating-prompt.d.ts.map +1 -1
- package/dist/orchestration/orchestrator-operating-prompt.js +206 -20
- package/dist/orchestration/orchestrator-operating-prompt.js.map +1 -1
- package/dist/orchestration/plan-import.d.ts +39 -0
- package/dist/orchestration/plan-import.d.ts.map +1 -0
- package/dist/orchestration/plan-import.js +547 -0
- package/dist/orchestration/plan-import.js.map +1 -0
- package/dist/orchestration/validation.d.ts +40 -0
- package/dist/orchestration/validation.d.ts.map +1 -0
- package/dist/orchestration/validation.js +203 -0
- package/dist/orchestration/validation.js.map +1 -0
- package/dist/orchestration/worker-operating-prompt.d.ts +2 -0
- package/dist/orchestration/worker-operating-prompt.d.ts.map +1 -1
- package/dist/orchestration/worker-operating-prompt.js +36 -46
- package/dist/orchestration/worker-operating-prompt.js.map +1 -1
- package/dist/orchestrator.d.ts +214 -33
- package/dist/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator.js +2200 -1100
- package/dist/orchestrator.js.map +1 -1
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +8 -4
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/claude-cli-prompt.d.ts.map +1 -1
- package/dist/providers/claude-cli-prompt.js +49 -5
- package/dist/providers/claude-cli-prompt.js.map +1 -1
- package/dist/providers/claude-cli.d.ts.map +1 -1
- package/dist/providers/claude-cli.js +81 -5
- package/dist/providers/claude-cli.js.map +1 -1
- package/dist/providers/codex-cli.d.ts +10 -6
- package/dist/providers/codex-cli.d.ts.map +1 -1
- package/dist/providers/codex-cli.js +204 -26
- package/dist/providers/codex-cli.js.map +1 -1
- package/dist/providers/google.d.ts.map +1 -1
- package/dist/providers/google.js +15 -5
- package/dist/providers/google.js.map +1 -1
- package/dist/providers/index.d.ts +15 -1
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/openai.d.ts +1 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +13 -5
- package/dist/providers/openai.js.map +1 -1
- package/dist/response-guard.js +1 -1
- package/dist/response-guard.js.map +1 -1
- package/dist/server-adapter.d.ts +8 -0
- package/dist/server-adapter.d.ts.map +1 -1
- package/dist/server-adapter.js +7 -0
- package/dist/server-adapter.js.map +1 -1
- package/dist/service-mode.d.ts +1 -1
- package/dist/service-mode.d.ts.map +1 -1
- package/dist/service-mode.js +64 -1
- package/dist/service-mode.js.map +1 -1
- package/dist/service-setup-only.d.ts +8 -0
- package/dist/service-setup-only.d.ts.map +1 -0
- package/dist/service-setup-only.js +37 -0
- package/dist/service-setup-only.js.map +1 -0
- package/dist/slash-commands.d.ts +21 -0
- package/dist/slash-commands.d.ts.map +1 -0
- package/dist/slash-commands.js +99 -0
- package/dist/slash-commands.js.map +1 -0
- package/dist/subagent/index.d.ts +4 -2
- package/dist/subagent/index.d.ts.map +1 -1
- package/dist/subagent/index.js.map +1 -1
- package/dist/summarization-pipeline.d.ts.map +1 -1
- package/dist/summarization-pipeline.js +1 -9
- package/dist/summarization-pipeline.js.map +1 -1
- package/dist/token-counter.d.ts.map +1 -1
- package/dist/token-counter.js +11 -4
- package/dist/token-counter.js.map +1 -1
- package/dist/tool-filter.d.ts.map +1 -1
- package/dist/tool-filter.js +10 -6
- package/dist/tool-filter.js.map +1 -1
- package/dist/tools/admin-tools.d.ts.map +1 -1
- package/dist/tools/admin-tools.js +20 -5
- package/dist/tools/admin-tools.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/run-command.d.ts.map +1 -1
- package/dist/tools/run-command.js +5 -1
- package/dist/tools/run-command.js.map +1 -1
- package/dist/tools/search-conversation-history.d.ts +16 -0
- package/dist/tools/search-conversation-history.d.ts.map +1 -0
- package/dist/tools/search-conversation-history.js +334 -0
- package/dist/tools/search-conversation-history.js.map +1 -0
- package/dist/tools/todo-tasks.d.ts.map +1 -1
- package/dist/tools/todo-tasks.js +77 -5
- package/dist/tools/todo-tasks.js.map +1 -1
- package/dist/usage-log.d.ts +62 -0
- package/dist/usage-log.d.ts.map +1 -0
- package/dist/usage-log.js +98 -0
- package/dist/usage-log.js.map +1 -0
- package/dist/wizard-state.d.ts +20 -0
- package/dist/wizard-state.d.ts.map +1 -1
- package/dist/wizard-state.js +90 -3
- package/dist/wizard-state.js.map +1 -1
- package/dist/wizard-support.d.ts.map +1 -1
- package/dist/wizard-support.js +27 -1
- package/dist/wizard-support.js.map +1 -1
- package/dist/workflow-engine.d.ts +44 -2
- package/dist/workflow-engine.d.ts.map +1 -1
- package/dist/workflow-engine.js +932 -111
- package/dist/workflow-engine.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.executeReplyDirectly = executeReplyDirectly;
|
|
37
|
+
exports.executeDelegateSingle = executeDelegateSingle;
|
|
38
|
+
exports.executeCreateWorkflow = executeCreateWorkflow;
|
|
39
|
+
/**
|
|
40
|
+
* Orchestration dispatch executor (Phase A — dead code).
|
|
41
|
+
*
|
|
42
|
+
* Takes validated dispatch tool-call arguments (see dispatch-tools.ts) and
|
|
43
|
+
* performs the side effects: creating TODOs in the local DB, or returning
|
|
44
|
+
* the reply_directly text to the caller.
|
|
45
|
+
*
|
|
46
|
+
* Not yet wired to the live orchestrator turn loop — that's the Step-5
|
|
47
|
+
* wire-up work gated behind the feature flag from Decision 6.
|
|
48
|
+
*
|
|
49
|
+
* KEY BEHAVIORS (per orchestration-plan.txt):
|
|
50
|
+
* - reply_directly: no side effects, just returns the text.
|
|
51
|
+
* - delegate_single: creates exactly one TODO owned by the target bot.
|
|
52
|
+
* * bot_name wins over role when both provided.
|
|
53
|
+
* * role is stored on the TODO as informational metadata.
|
|
54
|
+
* * When only role is given, resolveBotForRole() picks the bot.
|
|
55
|
+
* - create_workflow: creates N TODOs in order, linking each to the next
|
|
56
|
+
* via next_worker_bot_id / next_worker_name / next_worker_role so
|
|
57
|
+
* the existing workflow-engine plumbing picks up the chain.
|
|
58
|
+
* * handoff_to_next is appended to the NEXT step's task prompt as
|
|
59
|
+
* the "[PREVIOUS WORKER HANDOFF]" section the worker-operating-
|
|
60
|
+
* prompt already supports.
|
|
61
|
+
*
|
|
62
|
+
* All executor functions return a structured result describing what was
|
|
63
|
+
* created. Callers (the orchestrator turn loop, once wired) use the result
|
|
64
|
+
* to surface TODO IDs back to the user and to start workflow execution.
|
|
65
|
+
*/
|
|
66
|
+
const data = __importStar(require("../local-data"));
|
|
67
|
+
const dispatch_tools_1 = require("./dispatch-tools");
|
|
68
|
+
const capabilities_1 = require("./capabilities");
|
|
69
|
+
/**
|
|
70
|
+
* Compose a worker task prompt from the orchestrator's task_instructions
|
|
71
|
+
* and the original user prompt, following the same position-aware rule
|
|
72
|
+
* enforced by the legacy path's shouldIncludeOriginalPromptForWorker:
|
|
73
|
+
* - If the worker is first in the chain: always include.
|
|
74
|
+
* - Otherwise: include only if the worker's
|
|
75
|
+
* orchestration_include_user_prompt flag is set.
|
|
76
|
+
* The appended block uses the same "Original user request (reference
|
|
77
|
+
* only):" header the legacy path uses, so worker prompts look the
|
|
78
|
+
* same regardless of which dispatch path created them.
|
|
79
|
+
*/
|
|
80
|
+
function composeTaskPrompt(instructions, userPrompt, worker, isFirstInChain, recentContext, nextWorker) {
|
|
81
|
+
const shouldAppend = isFirstInChain || Number(worker.orchestration_include_user_prompt) === 1;
|
|
82
|
+
const parts = [['YOUR TASK', instructions.trim()].filter(Boolean).join('\n')];
|
|
83
|
+
if (nextWorker?.name) {
|
|
84
|
+
const roleLabel = nextWorker.role ? ` (${nextWorker.role})` : '';
|
|
85
|
+
parts.push([
|
|
86
|
+
'NEXT WORKER',
|
|
87
|
+
`After you complete this task, ${nextWorker.name}${roleLabel} receives your handoff.`,
|
|
88
|
+
].join('\n'));
|
|
89
|
+
parts.push([
|
|
90
|
+
'HANDOFF REQUIREMENTS',
|
|
91
|
+
'When calling complete_worker_task, write handoff_prompt as the next worker prompt. Include the goal, artifact/path, current issue or result, exact scope, constraints, and acceptance checks. Do not create a new TODO unless the orchestrator explicitly asked you to.',
|
|
92
|
+
].join('\n'));
|
|
93
|
+
}
|
|
94
|
+
if (isFirstInChain && recentContext?.trim()) {
|
|
95
|
+
parts.push(`Recent conversation context:\n${recentContext.trim()}`);
|
|
96
|
+
}
|
|
97
|
+
if (shouldAppend && userPrompt.trim()) {
|
|
98
|
+
parts.push(`Original user request:\n${userPrompt}`);
|
|
99
|
+
}
|
|
100
|
+
return parts.filter(Boolean).join('\n\n');
|
|
101
|
+
}
|
|
102
|
+
// -----------------------------------------------------------------------------
|
|
103
|
+
// Bot lookup helpers
|
|
104
|
+
// -----------------------------------------------------------------------------
|
|
105
|
+
function findBotByName(name, bots) {
|
|
106
|
+
const needle = name.trim().toLowerCase();
|
|
107
|
+
if (!needle)
|
|
108
|
+
return null;
|
|
109
|
+
for (const bot of bots) {
|
|
110
|
+
if (bot.name.trim().toLowerCase() === needle)
|
|
111
|
+
return bot;
|
|
112
|
+
}
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
function resolveStepBot(args, ctx) {
|
|
116
|
+
const hasBot = typeof args.bot_name === 'string' && args.bot_name.trim().length > 0;
|
|
117
|
+
const hasRole = typeof args.role === 'string' && args.role.trim().length > 0;
|
|
118
|
+
if (hasBot) {
|
|
119
|
+
const bot = findBotByName(args.bot_name, ctx.resolution.activeBots);
|
|
120
|
+
if (!bot)
|
|
121
|
+
return { ok: false, error: `bot_name "${args.bot_name}" not found in conversation roster.` };
|
|
122
|
+
return { ok: true, bot };
|
|
123
|
+
}
|
|
124
|
+
if (hasRole) {
|
|
125
|
+
const bot = (0, dispatch_tools_1.resolveBotForRole)(args.role, ctx.resolution);
|
|
126
|
+
if (!bot)
|
|
127
|
+
return { ok: false, error: `no active bot has role "${args.role}" in its priority list.` };
|
|
128
|
+
return { ok: true, bot };
|
|
129
|
+
}
|
|
130
|
+
return { ok: false, error: 'neither bot_name nor role provided (this should have been caught by validation).' };
|
|
131
|
+
}
|
|
132
|
+
// -----------------------------------------------------------------------------
|
|
133
|
+
// Executors
|
|
134
|
+
// -----------------------------------------------------------------------------
|
|
135
|
+
function executeReplyDirectly(args) {
|
|
136
|
+
return { kind: 'reply_directly', text: args.text };
|
|
137
|
+
}
|
|
138
|
+
function executeDelegateSingle(args, ctx) {
|
|
139
|
+
const resolved = resolveStepBot(args, ctx);
|
|
140
|
+
if (!resolved.ok)
|
|
141
|
+
return { kind: 'error', error: resolved.error };
|
|
142
|
+
const bot = resolved.bot;
|
|
143
|
+
// A single delegate has no predecessor, so the worker is first in
|
|
144
|
+
// chain and always receives the original user prompt per the policy.
|
|
145
|
+
const composedPrompt = composeTaskPrompt(args.task_instructions, ctx.userPrompt, bot, true, ctx.recentContext);
|
|
146
|
+
const task = data.addTodoTask({
|
|
147
|
+
projectId: ctx.projectId,
|
|
148
|
+
conversationId: ctx.conversationId,
|
|
149
|
+
title: buildTaskTitle(bot.name, args.role, args.task_instructions, args.title),
|
|
150
|
+
details: `Task dispatched by orchestrator ${ctx.orchestratorActor.name}.`,
|
|
151
|
+
participants: [bot.name],
|
|
152
|
+
successCriteria: args.success_criteria || deriveDefaultSuccessCriteria(args.task_instructions),
|
|
153
|
+
ownerBotId: bot.id,
|
|
154
|
+
ownerName: bot.name,
|
|
155
|
+
taskType: inferTaskType(args.role, bot),
|
|
156
|
+
profileName: bot.name,
|
|
157
|
+
taskPrompt: composedPrompt,
|
|
158
|
+
actor: { actorType: 'orchestrator', actorId: ctx.orchestratorActor.actorId },
|
|
159
|
+
});
|
|
160
|
+
return { kind: 'delegate_single', task, assignedBot: bot };
|
|
161
|
+
}
|
|
162
|
+
function executeCreateWorkflow(args, ctx) {
|
|
163
|
+
// Resolve every step's bot up front. If any fail to resolve, reject the whole
|
|
164
|
+
// workflow before creating any TODOs. Avoids partial state.
|
|
165
|
+
const resolvedBots = [];
|
|
166
|
+
for (let i = 0; i < args.steps.length; i += 1) {
|
|
167
|
+
const step = args.steps[i];
|
|
168
|
+
const r = resolveStepBot(step, ctx);
|
|
169
|
+
if (!r.ok)
|
|
170
|
+
return { kind: 'error', error: `Step ${i + 1}: ${r.error}` };
|
|
171
|
+
resolvedBots.push(r.bot);
|
|
172
|
+
}
|
|
173
|
+
const tasks = [];
|
|
174
|
+
for (let i = 0; i < args.steps.length; i += 1) {
|
|
175
|
+
const step = args.steps[i];
|
|
176
|
+
const owner = resolvedBots[i];
|
|
177
|
+
const next = resolvedBots[i + 1] || null;
|
|
178
|
+
const nextStep = args.steps[i + 1] || null;
|
|
179
|
+
let taskPrompt = step.task_instructions;
|
|
180
|
+
// Weave prior step's handoff_to_next into THIS step's task prompt so the
|
|
181
|
+
// worker sees it. Uses the "[PREVIOUS WORKER HANDOFF]" header that
|
|
182
|
+
// worker-operating-prompt.ts already recognizes.
|
|
183
|
+
const priorStep = args.steps[i - 1];
|
|
184
|
+
if (priorStep?.handoff_to_next && priorStep.handoff_to_next.trim()) {
|
|
185
|
+
taskPrompt = `[PREVIOUS WORKER HANDOFF]\n${priorStep.handoff_to_next.trim()}\n\n${taskPrompt}`;
|
|
186
|
+
}
|
|
187
|
+
// Position-aware include_user_prompt policy, same as the legacy
|
|
188
|
+
// workflow-template path: step 0 is first in chain → always gets
|
|
189
|
+
// the user prompt; steps 1..N-1 honor the per-bot flag.
|
|
190
|
+
const isFirstInChain = i === 0;
|
|
191
|
+
taskPrompt = composeTaskPrompt(taskPrompt, ctx.userPrompt, owner, isFirstInChain, ctx.recentContext, next ? { name: next.name, role: nextStep?.role || data.getAgentOrchestrationRoleLabel(next) } : null);
|
|
192
|
+
const task = data.addTodoTask({
|
|
193
|
+
projectId: ctx.projectId,
|
|
194
|
+
conversationId: ctx.conversationId,
|
|
195
|
+
title: buildTaskTitle(owner.name, step.role, step.task_instructions, step.title),
|
|
196
|
+
details: ctx.workflowSourceLabel
|
|
197
|
+
? `${ctx.workflowSourceLabel} step ${i + 1} of ${args.steps.length} prepared by ${ctx.orchestratorActor.name}.`
|
|
198
|
+
: `Workflow step ${i + 1} of ${args.steps.length} dispatched by orchestrator ${ctx.orchestratorActor.name}.`,
|
|
199
|
+
participants: [owner.name],
|
|
200
|
+
successCriteria: step.success_criteria || deriveDefaultSuccessCriteria(step.task_instructions),
|
|
201
|
+
ownerBotId: owner.id,
|
|
202
|
+
ownerName: owner.name,
|
|
203
|
+
taskType: inferTaskType(step.role, owner),
|
|
204
|
+
profileName: owner.name,
|
|
205
|
+
nextWorkerBotId: next?.id || null,
|
|
206
|
+
nextWorkerName: next?.name || null,
|
|
207
|
+
nextWorkerRole: next ? (nextStep?.role || data.getAgentOrchestrationRoleLabel(next)) : null,
|
|
208
|
+
taskPrompt,
|
|
209
|
+
actor: { actorType: 'orchestrator', actorId: ctx.orchestratorActor.actorId },
|
|
210
|
+
});
|
|
211
|
+
tasks.push(task);
|
|
212
|
+
}
|
|
213
|
+
return { kind: 'create_workflow', tasks, assignedBots: resolvedBots };
|
|
214
|
+
}
|
|
215
|
+
// -----------------------------------------------------------------------------
|
|
216
|
+
// Small helpers
|
|
217
|
+
// -----------------------------------------------------------------------------
|
|
218
|
+
function buildTaskTitle(botName, role, taskInstructions, explicitTitle) {
|
|
219
|
+
const rawTitle = String(explicitTitle || '').trim();
|
|
220
|
+
const summary = (rawTitle || taskInstructions).trim().replace(/\s+/g, ' ').slice(0, 96);
|
|
221
|
+
const title = summary || 'Assigned task';
|
|
222
|
+
if (title.toLowerCase().startsWith(`${botName.toLowerCase()}:`))
|
|
223
|
+
return title;
|
|
224
|
+
const roleLabel = !rawTitle && role && role.trim() ? ` (${role.trim()})` : '';
|
|
225
|
+
return `${botName}${roleLabel}: ${title}`;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Derive a default success criteria when the LLM doesn't provide one.
|
|
229
|
+
* The DB's orchestrator path requires a non-empty successCriteria, so we
|
|
230
|
+
* synthesize a short version from the task instructions rather than
|
|
231
|
+
* forcing the orchestrator LLM to articulate criteria for trivial tasks.
|
|
232
|
+
*/
|
|
233
|
+
function deriveDefaultSuccessCriteria(taskInstructions) {
|
|
234
|
+
const trimmed = taskInstructions.trim().replace(/\s+/g, ' ');
|
|
235
|
+
const brief = trimmed.length > 200 ? `${trimmed.slice(0, 197)}...` : trimmed;
|
|
236
|
+
return `Task completed as specified: ${brief}`;
|
|
237
|
+
}
|
|
238
|
+
function inferTaskType(role, bot) {
|
|
239
|
+
const inferred = (0, capabilities_1.inferTaskTypeFromCapabilities)(role, data.getAgentRolePriorities(bot), 'coding');
|
|
240
|
+
if (inferred !== 'coding' || !role)
|
|
241
|
+
return inferred;
|
|
242
|
+
const fromRole = (role || '').trim().toLowerCase();
|
|
243
|
+
if (fromRole === 'qa' || fromRole === 'review')
|
|
244
|
+
return 'qa';
|
|
245
|
+
if (fromRole === 'research' || fromRole === 'brainstorm' || fromRole === 'planning')
|
|
246
|
+
return 'research';
|
|
247
|
+
if (fromRole === 'verify' || fromRole === 'verification')
|
|
248
|
+
return 'verify';
|
|
249
|
+
if (fromRole === 'deploy' || fromRole === 'deployment')
|
|
250
|
+
return 'deploy';
|
|
251
|
+
if (fromRole === 'coding' || fromRole === 'code')
|
|
252
|
+
return 'coding';
|
|
253
|
+
// Fall back to the bot's first priority role (normalized), else 'coding' as neutral default.
|
|
254
|
+
const primaries = data.getAgentRolePriorities(bot);
|
|
255
|
+
const primary = (primaries[0] || '').trim().toLowerCase();
|
|
256
|
+
if (primary === 'qa' || primary === 'review' || primary === 'quality assurance')
|
|
257
|
+
return 'qa';
|
|
258
|
+
if (primary === 'research' || primary === 'brainstorm' || primary === 'planning')
|
|
259
|
+
return 'research';
|
|
260
|
+
if (primary === 'verify' || primary === 'verification')
|
|
261
|
+
return 'verify';
|
|
262
|
+
if (primary === 'deploy' || primary === 'deployment')
|
|
263
|
+
return 'deploy';
|
|
264
|
+
return 'coding';
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=dispatch-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch-executor.js","sourceRoot":"","sources":["../../src/orchestration/dispatch-executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestration dispatch hint builder (Phase A — dead code).
|
|
3
|
+
*
|
|
4
|
+
* Per orchestration-plan.txt Decision 5, the orchestrator LLM receives a
|
|
5
|
+
* structured JSON context block every turn. This module is a PURE function
|
|
6
|
+
* that produces that block from conversation + bot + project state.
|
|
7
|
+
*
|
|
8
|
+
* Two tiers:
|
|
9
|
+
* - Tier 1 (essential facts): user_prompt, conversation, available_bots,
|
|
10
|
+
* existing_todos, effective_policy
|
|
11
|
+
* - Tier 2 (advisory hints): candidate_roles_detected, candidate_bots,
|
|
12
|
+
* suggested_mode, reasoning
|
|
13
|
+
*
|
|
14
|
+
* Tier 2 replaces what the regex dispatchers used to do AUTHORITATIVELY.
|
|
15
|
+
* Now it is ADVISORY — the LLM can accept, override, or ignore it.
|
|
16
|
+
*
|
|
17
|
+
* Implementation guardrails (Codex 2026-04-18 review):
|
|
18
|
+
* - Hint size is bounded (Guardrail #5). TODO count caps, per-field char
|
|
19
|
+
* caps, recent_summary + effective_policy length caps.
|
|
20
|
+
* - Advisory helpers are PURE — they accept inputs and return data; no
|
|
21
|
+
* side effects, no class dependencies. Easy to unit-test in isolation.
|
|
22
|
+
* - `project_folder` is INCLUDED by design (Decision 5); callers running
|
|
23
|
+
* through an API provider should treat this as documented behavior.
|
|
24
|
+
*/
|
|
25
|
+
import * as data from '../local-data';
|
|
26
|
+
export declare const HINT_BUDGETS: {
|
|
27
|
+
readonly MAX_TODOS: 30;
|
|
28
|
+
readonly MAX_TODO_TITLE_CHARS: 200;
|
|
29
|
+
readonly MAX_TODO_DETAILS_CHARS: 200;
|
|
30
|
+
readonly MAX_RECENT_SUMMARY_CHARS: 2000;
|
|
31
|
+
readonly MAX_RECENT_TURNS_CHARS: 6000;
|
|
32
|
+
readonly MAX_EFFECTIVE_POLICY_CHARS: 1000;
|
|
33
|
+
};
|
|
34
|
+
export interface HintBotEntry {
|
|
35
|
+
name: string;
|
|
36
|
+
provider: string;
|
|
37
|
+
model: string | null;
|
|
38
|
+
role_priorities: string[];
|
|
39
|
+
is_active: boolean;
|
|
40
|
+
}
|
|
41
|
+
export interface HintTodoEntry {
|
|
42
|
+
id: string;
|
|
43
|
+
owner: string | null;
|
|
44
|
+
title: string;
|
|
45
|
+
status: string | null;
|
|
46
|
+
}
|
|
47
|
+
export interface HintSelectedWorkflowTemplate {
|
|
48
|
+
id: string;
|
|
49
|
+
name: string;
|
|
50
|
+
description: string | null;
|
|
51
|
+
steps: Array<{
|
|
52
|
+
index: number;
|
|
53
|
+
bot_name: string;
|
|
54
|
+
role_priorities: string[];
|
|
55
|
+
saved_instruction: string | null;
|
|
56
|
+
is_checkpoint: boolean;
|
|
57
|
+
}>;
|
|
58
|
+
}
|
|
59
|
+
export interface HintCandidateWorkflowPlan {
|
|
60
|
+
source: 'selected_workflow_template' | 'named_workflow_template' | 'explicit_bot_sequence';
|
|
61
|
+
reason: string;
|
|
62
|
+
steps: Array<{
|
|
63
|
+
index: number;
|
|
64
|
+
bot_name: string;
|
|
65
|
+
role_priorities: string[];
|
|
66
|
+
suggested_role: string | null;
|
|
67
|
+
confidence?: 'low' | 'medium' | 'high';
|
|
68
|
+
reason?: string;
|
|
69
|
+
}>;
|
|
70
|
+
}
|
|
71
|
+
export interface HintConversation {
|
|
72
|
+
id: string;
|
|
73
|
+
title: string | null;
|
|
74
|
+
topic_id: string | null;
|
|
75
|
+
project_name: string | null;
|
|
76
|
+
project_folder: string | null;
|
|
77
|
+
turn_count: number;
|
|
78
|
+
recent_summary: string | null;
|
|
79
|
+
recent_turns: string | null;
|
|
80
|
+
bootstrap_history_file: string | null;
|
|
81
|
+
}
|
|
82
|
+
export interface AdvisoryBlock {
|
|
83
|
+
candidate_roles_detected: string[];
|
|
84
|
+
candidate_bots_mentioned_by_name: string[];
|
|
85
|
+
suggested_mode: 'reply_directly' | 'delegate_single' | 'create_workflow';
|
|
86
|
+
reasoning: string;
|
|
87
|
+
}
|
|
88
|
+
export interface PlanExecutionIntent {
|
|
89
|
+
mode: 'none' | 'per_step_todos' | 'per_step_workflow';
|
|
90
|
+
requires_file_read_before_dispatch: boolean;
|
|
91
|
+
mentioned_bots: string[];
|
|
92
|
+
candidate_roles: string[];
|
|
93
|
+
reasoning: string;
|
|
94
|
+
}
|
|
95
|
+
export interface DispatchHint {
|
|
96
|
+
user_prompt: string;
|
|
97
|
+
conversation: HintConversation;
|
|
98
|
+
available_bots: HintBotEntry[];
|
|
99
|
+
selected_workflow_template: HintSelectedWorkflowTemplate | null;
|
|
100
|
+
candidate_workflow_plan: HintCandidateWorkflowPlan | null;
|
|
101
|
+
plan_execution_intent: PlanExecutionIntent;
|
|
102
|
+
existing_todos: HintTodoEntry[];
|
|
103
|
+
todos_truncated: boolean;
|
|
104
|
+
effective_policy: string | null;
|
|
105
|
+
advisory: AdvisoryBlock;
|
|
106
|
+
}
|
|
107
|
+
export interface BuildHintInput {
|
|
108
|
+
userPrompt: string;
|
|
109
|
+
conversation: {
|
|
110
|
+
id: string;
|
|
111
|
+
title: string | null;
|
|
112
|
+
topic_id?: string | null;
|
|
113
|
+
project_name: string | null;
|
|
114
|
+
project_folder: string | null;
|
|
115
|
+
turn_count: number;
|
|
116
|
+
recent_summary: string | null;
|
|
117
|
+
recent_turns?: string | null;
|
|
118
|
+
bootstrap_history_file?: string | null;
|
|
119
|
+
};
|
|
120
|
+
activeBots: data.AgentProfileRow[];
|
|
121
|
+
selectedWorkflowTemplate?: HintSelectedWorkflowTemplate | null;
|
|
122
|
+
candidateWorkflowPlan?: HintCandidateWorkflowPlan | null;
|
|
123
|
+
existingTodos: Array<{
|
|
124
|
+
id: string | number;
|
|
125
|
+
owner_name: string | null;
|
|
126
|
+
title: string;
|
|
127
|
+
status: string | null;
|
|
128
|
+
}>;
|
|
129
|
+
effectivePolicyText: string | null;
|
|
130
|
+
}
|
|
131
|
+
export declare function buildDispatchHint(input: BuildHintInput): DispatchHint;
|
|
132
|
+
export declare function computePlanExecutionIntent(userPrompt: string, bots: HintBotEntry[]): PlanExecutionIntent;
|
|
133
|
+
export declare function computeAdvisory(userPrompt: string, bots: HintBotEntry[], precomputedPlanIntent?: PlanExecutionIntent): AdvisoryBlock;
|
|
134
|
+
//# sourceMappingURL=dispatch-hint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch-hint.d.ts","sourceRoot":"","sources":["../../src/orchestration/dispatch-hint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,IAAI,MAAM,eAAe,CAAC;AAOtC,eAAO,MAAM,YAAY;;;;;;;CAOf,CAAC;AAMX,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,4BAA4B;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,KAAK,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;QACjC,aAAa,EAAE,OAAO,CAAC;KACxB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,4BAA4B,GAAG,yBAAyB,GAAG,uBAAuB,CAAC;IAC3F,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,UAAU,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;QACvC,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,aAAa;IAC5B,wBAAwB,EAAE,MAAM,EAAE,CAAC;IACnC,gCAAgC,EAAE,MAAM,EAAE,CAAC;IAC3C,cAAc,EAAE,gBAAgB,GAAG,iBAAiB,GAAG,iBAAiB,CAAC;IACzE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,mBAAmB,CAAC;IACtD,kCAAkC,EAAE,OAAO,CAAC;IAC5C,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,gBAAgB,CAAC;IAC/B,cAAc,EAAE,YAAY,EAAE,CAAC;IAC/B,0BAA0B,EAAE,4BAA4B,GAAG,IAAI,CAAC;IAChE,uBAAuB,EAAE,yBAAyB,GAAG,IAAI,CAAC;IAC1D,qBAAqB,EAAE,mBAAmB,CAAC;IAC3C,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,EAAE,aAAa,CAAC;CACzB;AAMD,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE;QACZ,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACxC,CAAC;IACF,UAAU,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC;IACnC,wBAAwB,CAAC,EAAE,4BAA4B,GAAG,IAAI,CAAC;IAC/D,qBAAqB,CAAC,EAAE,yBAAyB,GAAG,IAAI,CAAC;IACzD,aAAa,EAAE,KAAK,CAAC;QACnB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;KACvB,CAAC,CAAC;IACH,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AA4BD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG,YAAY,CA4BrE;AA0ED,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,mBAAmB,CAoDxG;AAwDD,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,YAAY,EAAE,EACpB,qBAAqB,CAAC,EAAE,mBAAmB,GAC1C,aAAa,CAWf"}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HINT_BUDGETS = void 0;
|
|
4
|
+
exports.buildDispatchHint = buildDispatchHint;
|
|
5
|
+
exports.computePlanExecutionIntent = computePlanExecutionIntent;
|
|
6
|
+
exports.computeAdvisory = computeAdvisory;
|
|
7
|
+
const local_data_1 = require("../local-data");
|
|
8
|
+
// -----------------------------------------------------------------------------
|
|
9
|
+
// Budgets (per Guardrail #5)
|
|
10
|
+
// -----------------------------------------------------------------------------
|
|
11
|
+
exports.HINT_BUDGETS = {
|
|
12
|
+
MAX_TODOS: 30,
|
|
13
|
+
MAX_TODO_TITLE_CHARS: 200,
|
|
14
|
+
MAX_TODO_DETAILS_CHARS: 200,
|
|
15
|
+
MAX_RECENT_SUMMARY_CHARS: 2000,
|
|
16
|
+
MAX_RECENT_TURNS_CHARS: 6000,
|
|
17
|
+
MAX_EFFECTIVE_POLICY_CHARS: 1000,
|
|
18
|
+
};
|
|
19
|
+
function truncate(text, max) {
|
|
20
|
+
if (text == null)
|
|
21
|
+
return null;
|
|
22
|
+
const s = String(text);
|
|
23
|
+
if (s.length <= max)
|
|
24
|
+
return s;
|
|
25
|
+
return s.slice(0, Math.max(0, max - 1)).trimEnd() + '…';
|
|
26
|
+
}
|
|
27
|
+
function toHintBot(bot) {
|
|
28
|
+
return {
|
|
29
|
+
name: bot.name,
|
|
30
|
+
provider: bot.provider,
|
|
31
|
+
model: bot.model || null,
|
|
32
|
+
role_priorities: (0, local_data_1.getAgentRolePriorities)(bot),
|
|
33
|
+
is_active: bot.is_active === 1,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function toHintTodo(t) {
|
|
37
|
+
return {
|
|
38
|
+
id: String(t.id),
|
|
39
|
+
owner: t.owner_name || null,
|
|
40
|
+
title: truncate(t.title, exports.HINT_BUDGETS.MAX_TODO_TITLE_CHARS) || '',
|
|
41
|
+
status: t.status || null,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function buildDispatchHint(input) {
|
|
45
|
+
const todosCapped = input.existingTodos.slice(0, exports.HINT_BUDGETS.MAX_TODOS);
|
|
46
|
+
const todosTruncated = input.existingTodos.length > exports.HINT_BUDGETS.MAX_TODOS;
|
|
47
|
+
const availableBots = input.activeBots.filter((b) => b.is_active === 1).map(toHintBot);
|
|
48
|
+
const planExecutionIntent = computePlanExecutionIntent(input.userPrompt, availableBots);
|
|
49
|
+
const advisory = computeAdvisory(input.userPrompt, availableBots, planExecutionIntent);
|
|
50
|
+
return {
|
|
51
|
+
user_prompt: input.userPrompt,
|
|
52
|
+
conversation: {
|
|
53
|
+
id: input.conversation.id,
|
|
54
|
+
title: input.conversation.title,
|
|
55
|
+
topic_id: input.conversation.topic_id ?? null,
|
|
56
|
+
project_name: input.conversation.project_name,
|
|
57
|
+
project_folder: input.conversation.project_folder,
|
|
58
|
+
turn_count: input.conversation.turn_count,
|
|
59
|
+
recent_summary: truncate(input.conversation.recent_summary, exports.HINT_BUDGETS.MAX_RECENT_SUMMARY_CHARS),
|
|
60
|
+
recent_turns: truncate(input.conversation.recent_turns, exports.HINT_BUDGETS.MAX_RECENT_TURNS_CHARS),
|
|
61
|
+
bootstrap_history_file: input.conversation.bootstrap_history_file || null,
|
|
62
|
+
},
|
|
63
|
+
available_bots: availableBots,
|
|
64
|
+
selected_workflow_template: input.selectedWorkflowTemplate || null,
|
|
65
|
+
candidate_workflow_plan: input.candidateWorkflowPlan || null,
|
|
66
|
+
plan_execution_intent: planExecutionIntent,
|
|
67
|
+
existing_todos: todosCapped.map(toHintTodo),
|
|
68
|
+
todos_truncated: todosTruncated,
|
|
69
|
+
effective_policy: truncate(input.effectivePolicyText, exports.HINT_BUDGETS.MAX_EFFECTIVE_POLICY_CHARS),
|
|
70
|
+
advisory,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
// -----------------------------------------------------------------------------
|
|
74
|
+
// Advisory computation (replaces the OLD dispatchers as a hint, not a decision)
|
|
75
|
+
// -----------------------------------------------------------------------------
|
|
76
|
+
/**
|
|
77
|
+
* Detects likely roles in a user prompt using simple keyword patterns.
|
|
78
|
+
* The set of candidates is derived from the actual roles configured on the
|
|
79
|
+
* current bot roster — so this adapts to any domain (software, legal,
|
|
80
|
+
* medical, etc.) without a hardcoded list.
|
|
81
|
+
*/
|
|
82
|
+
function detectCandidateRoles(userPrompt, bots) {
|
|
83
|
+
const normalizedPrompt = userPrompt.toLowerCase();
|
|
84
|
+
const seen = new Set();
|
|
85
|
+
const result = [];
|
|
86
|
+
for (const bot of bots) {
|
|
87
|
+
for (const role of bot.role_priorities) {
|
|
88
|
+
const key = role.trim().toLowerCase();
|
|
89
|
+
if (!key || seen.has(key))
|
|
90
|
+
continue;
|
|
91
|
+
// Match if the role word (or its first meaningful token) appears in the prompt.
|
|
92
|
+
// Uses word-boundary regex with case-insensitive match to avoid sub-word hits.
|
|
93
|
+
const rolePattern = new RegExp(`\\b${key.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\$&')}\\b`, 'i');
|
|
94
|
+
if (rolePattern.test(userPrompt) || rolePattern.test(normalizedPrompt)) {
|
|
95
|
+
seen.add(key);
|
|
96
|
+
result.push(role);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// Also detect common role keywords the user might mention even if no bot has
|
|
101
|
+
// them listed — the LLM can still use these as hints.
|
|
102
|
+
// verify/validate kept DISTINCT from qa (Codex QA 2026-04-18, finding #5).
|
|
103
|
+
// Collapsing them was the original bug the refactor was supposed to fix.
|
|
104
|
+
const commonKeywords = [
|
|
105
|
+
{ word: /\b(prompt builder|prompt building|user prompt|rewrite prompt|better prompt)\b/i, label: 'Prompt Building' },
|
|
106
|
+
{ word: /\b(code|coding|build|implement|create|write|develop)\b/i, label: 'coding' },
|
|
107
|
+
{ word: /\b(qa|review|test|testing|audit)\b/i, label: 'qa' },
|
|
108
|
+
{ word: /\b(verify|verification|validate|validation)\b/i, label: 'verify' },
|
|
109
|
+
{ word: /\b(research|investigate|analy[sz]e|analysis|brainstorm)\b/i, label: 'research' },
|
|
110
|
+
{ word: /\b(design|ui\/?ux|layout|visual)\b/i, label: 'Design' },
|
|
111
|
+
{ word: /\b(debug|debugging|troubleshoot|root cause)\b/i, label: 'Debugging' },
|
|
112
|
+
{ word: /\b(database|db|sqlite|schema|migration)\b/i, label: 'Data' },
|
|
113
|
+
{ word: /\b(documentation|docs|readme|release notes)\b/i, label: 'Documentation' },
|
|
114
|
+
{ word: /\b(deploy|deployment|release|ship)\b/i, label: 'deploy' },
|
|
115
|
+
];
|
|
116
|
+
for (const { word, label } of commonKeywords) {
|
|
117
|
+
if (!seen.has(label) && word.test(userPrompt)) {
|
|
118
|
+
seen.add(label);
|
|
119
|
+
result.push(label);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return result;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Finds bot names mentioned verbatim (case-insensitive) in the user prompt.
|
|
126
|
+
* Returns only bot names that exist in the roster — prevents false positives
|
|
127
|
+
* on common words that happen to match a bot name elsewhere.
|
|
128
|
+
*/
|
|
129
|
+
function detectMentionedBotNames(userPrompt, bots) {
|
|
130
|
+
const result = [];
|
|
131
|
+
for (const bot of bots) {
|
|
132
|
+
const nameEscaped = bot.name.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\$&');
|
|
133
|
+
const pattern = new RegExp(`\\b${nameEscaped}\\b`, 'i');
|
|
134
|
+
if (pattern.test(userPrompt)) {
|
|
135
|
+
result.push(bot.name);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return result;
|
|
139
|
+
}
|
|
140
|
+
function computePlanExecutionIntent(userPrompt, bots) {
|
|
141
|
+
const candidateRoles = detectCandidateRoles(userPrompt, bots);
|
|
142
|
+
const mentionedBots = detectMentionedBotNames(userPrompt, bots);
|
|
143
|
+
const text = String(userPrompt || '').trim();
|
|
144
|
+
if (!text) {
|
|
145
|
+
return {
|
|
146
|
+
mode: 'none',
|
|
147
|
+
requires_file_read_before_dispatch: false,
|
|
148
|
+
mentioned_bots: [],
|
|
149
|
+
candidate_roles: [],
|
|
150
|
+
reasoning: 'No user prompt text.',
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
const referencesFileOrPlan = /\b(read|open|inspect|use|apply|take)\b[\s\S]{0,80}\b(file|plan|document|txt|text file|markdown|md)\b/i.test(text)
|
|
154
|
+
|| /\bsteps?\s+(?:presented|listed|defined)\s+in\s+(?:this|the)\s+file\b/i.test(text)
|
|
155
|
+
|| /\bfrom\s+(?:this|the)\s+file\b/i.test(text);
|
|
156
|
+
const perStepSignal = /\b(each|every|individual)\s+step\b/i.test(text)
|
|
157
|
+
|| /\bone\s+(?:todo|task|workflow\s+step)\s+per\s+step\b/i.test(text);
|
|
158
|
+
const todoSignal = /\b(todo|to-do|task)\b/i.test(text);
|
|
159
|
+
const normalWorkflowSignal = /\b(?:use|run|apply)\b[\s\S]{0,40}\b(?:my|our|the|selected|normal|default|project team)\s+workflow\b/i.test(text)
|
|
160
|
+
|| /\buse\b[\s\S]{0,20}\bworkflow\b[\s\S]{0,40}\b(?:each|every|individual)\s+step\b/i.test(text);
|
|
161
|
+
if (referencesFileOrPlan && perStepSignal && normalWorkflowSignal) {
|
|
162
|
+
return {
|
|
163
|
+
mode: 'per_step_workflow',
|
|
164
|
+
requires_file_read_before_dispatch: true,
|
|
165
|
+
mentioned_bots: mentionedBots,
|
|
166
|
+
candidate_roles: candidateRoles,
|
|
167
|
+
reasoning: 'User explicitly asked to apply a saved/normal workflow to each structured step in a file or plan.',
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
if (referencesFileOrPlan && perStepSignal && todoSignal && (mentionedBots.length > 0 || candidateRoles.length > 0)) {
|
|
171
|
+
return {
|
|
172
|
+
mode: 'per_step_todos',
|
|
173
|
+
requires_file_read_before_dispatch: true,
|
|
174
|
+
mentioned_bots: mentionedBots,
|
|
175
|
+
candidate_roles: candidateRoles,
|
|
176
|
+
reasoning: 'User explicitly asked to turn each structured step in a file or plan into sequential worker TODOs.',
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
mode: 'none',
|
|
181
|
+
requires_file_read_before_dispatch: false,
|
|
182
|
+
mentioned_bots: mentionedBots,
|
|
183
|
+
candidate_roles: candidateRoles,
|
|
184
|
+
reasoning: referencesFileOrPlan
|
|
185
|
+
? 'Prompt references a file or plan, but does not explicitly request per-step TODO/workflow expansion.'
|
|
186
|
+
: 'No explicit plan-file execution request detected.',
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Suggests a dispatch mode based on the prompt shape.
|
|
191
|
+
* Purely advisory — the orchestrator LLM is free to override.
|
|
192
|
+
*/
|
|
193
|
+
function suggestMode(userPrompt, candidateRoles, mentionedBots, planIntent) {
|
|
194
|
+
const text = userPrompt.trim();
|
|
195
|
+
if (!text)
|
|
196
|
+
return 'reply_directly';
|
|
197
|
+
if (planIntent.mode !== 'none')
|
|
198
|
+
return 'create_workflow';
|
|
199
|
+
const hasQuestionMark = text.includes('?');
|
|
200
|
+
const workflowSignals = /\b(first\b.*\bthen\b|after\s+(that|you|qa|coding)|handoff|multi[- ]step)\b/i.test(text)
|
|
201
|
+
|| candidateRoles.length >= 2
|
|
202
|
+
|| mentionedBots.length >= 2;
|
|
203
|
+
if (workflowSignals)
|
|
204
|
+
return 'create_workflow';
|
|
205
|
+
if (candidateRoles.length === 1 || mentionedBots.length === 1)
|
|
206
|
+
return 'delegate_single';
|
|
207
|
+
// Pure question with no role or bot hint — probably a direct reply.
|
|
208
|
+
if (hasQuestionMark && candidateRoles.length === 0 && mentionedBots.length === 0) {
|
|
209
|
+
return 'reply_directly';
|
|
210
|
+
}
|
|
211
|
+
// Default conservative: delegate_single when the prompt looks task-shaped.
|
|
212
|
+
if (/\b(do|make|build|write|fix|finish|create|implement)\b/i.test(text)) {
|
|
213
|
+
return 'delegate_single';
|
|
214
|
+
}
|
|
215
|
+
return 'reply_directly';
|
|
216
|
+
}
|
|
217
|
+
function buildAdvisoryReasoning(mode, candidateRoles, mentionedBots) {
|
|
218
|
+
const parts = [];
|
|
219
|
+
if (mentionedBots.length > 0) {
|
|
220
|
+
parts.push(`prompt mentions bot${mentionedBots.length > 1 ? 's' : ''} by name (${mentionedBots.join(', ')})`);
|
|
221
|
+
}
|
|
222
|
+
if (candidateRoles.length > 0) {
|
|
223
|
+
parts.push(`detected role keyword${candidateRoles.length > 1 ? 's' : ''}: ${candidateRoles.join(', ')}`);
|
|
224
|
+
}
|
|
225
|
+
if (parts.length === 0) {
|
|
226
|
+
parts.push('no role or bot-name signals detected');
|
|
227
|
+
}
|
|
228
|
+
const modeLabel = mode === 'reply_directly'
|
|
229
|
+
? 'direct reply'
|
|
230
|
+
: mode === 'delegate_single'
|
|
231
|
+
? 'single delegation'
|
|
232
|
+
: 'multi-step workflow';
|
|
233
|
+
return `Suggesting ${modeLabel}: ${parts.join('; ')}.`;
|
|
234
|
+
}
|
|
235
|
+
function computeAdvisory(userPrompt, bots, precomputedPlanIntent) {
|
|
236
|
+
const candidateRoles = detectCandidateRoles(userPrompt, bots);
|
|
237
|
+
const mentionedBots = detectMentionedBotNames(userPrompt, bots);
|
|
238
|
+
const planIntent = precomputedPlanIntent || computePlanExecutionIntent(userPrompt, bots);
|
|
239
|
+
const suggested_mode = suggestMode(userPrompt, candidateRoles, mentionedBots, planIntent);
|
|
240
|
+
return {
|
|
241
|
+
candidate_roles_detected: candidateRoles,
|
|
242
|
+
candidate_bots_mentioned_by_name: mentionedBots,
|
|
243
|
+
suggested_mode,
|
|
244
|
+
reasoning: buildAdvisoryReasoning(suggested_mode, candidateRoles, mentionedBots),
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=dispatch-hint.js.map
|