@sensigo/realm-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +109 -0
- package/dist/agent/agent-utils.d.ts +27 -0
- package/dist/agent/agent-utils.d.ts.map +1 -0
- package/dist/agent/agent-utils.js +79 -0
- package/dist/agent/agent-utils.js.map +1 -0
- package/dist/agent/anthropic-provider.d.ts +23 -0
- package/dist/agent/anthropic-provider.d.ts.map +1 -0
- package/dist/agent/anthropic-provider.js +245 -0
- package/dist/agent/anthropic-provider.js.map +1 -0
- package/dist/agent/gate/slack-gate-notifier.d.ts +80 -0
- package/dist/agent/gate/slack-gate-notifier.d.ts.map +1 -0
- package/dist/agent/gate/slack-gate-notifier.js +315 -0
- package/dist/agent/gate/slack-gate-notifier.js.map +1 -0
- package/dist/agent/gate/slack-gate-server.d.ts +30 -0
- package/dist/agent/gate/slack-gate-server.d.ts.map +1 -0
- package/dist/agent/gate/slack-gate-server.js +99 -0
- package/dist/agent/gate/slack-gate-server.js.map +1 -0
- package/dist/agent/gate/slack-socket-client.d.ts +20 -0
- package/dist/agent/gate/slack-socket-client.d.ts.map +1 -0
- package/dist/agent/gate/slack-socket-client.js +141 -0
- package/dist/agent/gate/slack-socket-client.js.map +1 -0
- package/dist/agent/gate-intent-interpreter.d.ts +29 -0
- package/dist/agent/gate-intent-interpreter.d.ts.map +1 -0
- package/dist/agent/gate-intent-interpreter.js +33 -0
- package/dist/agent/gate-intent-interpreter.js.map +1 -0
- package/dist/agent/index.d.ts +4 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +4 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/llm-provider.d.ts +46 -0
- package/dist/agent/llm-provider.d.ts.map +1 -0
- package/dist/agent/llm-provider.js +55 -0
- package/dist/agent/llm-provider.js.map +1 -0
- package/dist/agent/mcp/mcp-client.d.ts +18 -0
- package/dist/agent/mcp/mcp-client.d.ts.map +1 -0
- package/dist/agent/mcp/mcp-client.js +108 -0
- package/dist/agent/mcp/mcp-client.js.map +1 -0
- package/dist/agent/mcp/mcp-extensions.d.ts +40 -0
- package/dist/agent/mcp/mcp-extensions.d.ts.map +1 -0
- package/dist/agent/mcp/mcp-extensions.js +2 -0
- package/dist/agent/mcp/mcp-extensions.js.map +1 -0
- package/dist/agent/mcp-client.d.ts +18 -0
- package/dist/agent/mcp-client.d.ts.map +1 -0
- package/dist/agent/mcp-client.js +108 -0
- package/dist/agent/mcp-client.js.map +1 -0
- package/dist/agent/mcp-types.d.ts +40 -0
- package/dist/agent/mcp-types.d.ts.map +1 -0
- package/dist/agent/mcp-types.js +2 -0
- package/dist/agent/mcp-types.js.map +1 -0
- package/dist/agent/openai-provider.d.ts +30 -0
- package/dist/agent/openai-provider.d.ts.map +1 -0
- package/dist/agent/openai-provider.js +253 -0
- package/dist/agent/openai-provider.js.map +1 -0
- package/dist/agent/openai-reasoning-provider.d.ts +18 -0
- package/dist/agent/openai-reasoning-provider.d.ts.map +1 -0
- package/dist/agent/openai-reasoning-provider.js +76 -0
- package/dist/agent/openai-reasoning-provider.js.map +1 -0
- package/dist/agent/preflight.d.ts +36 -0
- package/dist/agent/preflight.d.ts.map +1 -0
- package/dist/agent/preflight.js +81 -0
- package/dist/agent/preflight.js.map +1 -0
- package/dist/agent/providers/agent-utils.d.ts +27 -0
- package/dist/agent/providers/agent-utils.d.ts.map +1 -0
- package/dist/agent/providers/agent-utils.js +79 -0
- package/dist/agent/providers/agent-utils.js.map +1 -0
- package/dist/agent/providers/anthropic-provider.d.ts +23 -0
- package/dist/agent/providers/anthropic-provider.d.ts.map +1 -0
- package/dist/agent/providers/anthropic-provider.js +257 -0
- package/dist/agent/providers/anthropic-provider.js.map +1 -0
- package/dist/agent/providers/llm-provider.d.ts +46 -0
- package/dist/agent/providers/llm-provider.d.ts.map +1 -0
- package/dist/agent/providers/llm-provider.js +56 -0
- package/dist/agent/providers/llm-provider.js.map +1 -0
- package/dist/agent/providers/openai-provider.d.ts +30 -0
- package/dist/agent/providers/openai-provider.d.ts.map +1 -0
- package/dist/agent/providers/openai-provider.js +253 -0
- package/dist/agent/providers/openai-provider.js.map +1 -0
- package/dist/agent/providers/openai-reasoning-provider.d.ts +19 -0
- package/dist/agent/providers/openai-reasoning-provider.d.ts.map +1 -0
- package/dist/agent/providers/openai-reasoning-provider.js +89 -0
- package/dist/agent/providers/openai-reasoning-provider.js.map +1 -0
- package/dist/agent/run-agent.d.ts +50 -0
- package/dist/agent/run-agent.d.ts.map +1 -0
- package/dist/agent/run-agent.js +327 -0
- package/dist/agent/run-agent.js.map +1 -0
- package/dist/agent/slack-gate-notifier.d.ts +80 -0
- package/dist/agent/slack-gate-notifier.d.ts.map +1 -0
- package/dist/agent/slack-gate-notifier.js +315 -0
- package/dist/agent/slack-gate-notifier.js.map +1 -0
- package/dist/agent/slack-gate-poller.d.ts +28 -0
- package/dist/agent/slack-gate-poller.d.ts.map +1 -0
- package/dist/agent/slack-gate-poller.js +66 -0
- package/dist/agent/slack-gate-poller.js.map +1 -0
- package/dist/agent/slack-gate-server.d.ts +30 -0
- package/dist/agent/slack-gate-server.d.ts.map +1 -0
- package/dist/agent/slack-gate-server.js +99 -0
- package/dist/agent/slack-gate-server.js.map +1 -0
- package/dist/agent/slack-socket-client.d.ts +20 -0
- package/dist/agent/slack-socket-client.d.ts.map +1 -0
- package/dist/agent/slack-socket-client.js +141 -0
- package/dist/agent/slack-socket-client.js.map +1 -0
- package/dist/commands/agent.d.ts +3 -0
- package/dist/commands/agent.d.ts.map +1 -0
- package/dist/commands/agent.js +183 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/cleanup.d.ts +16 -0
- package/dist/commands/cleanup.d.ts.map +1 -0
- package/dist/commands/cleanup.js +79 -0
- package/dist/commands/cleanup.js.map +1 -0
- package/dist/commands/diff.d.ts +41 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +203 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/init.d.ts +10 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +97 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/inspect.d.ts +14 -0
- package/dist/commands/inspect.d.ts.map +1 -0
- package/dist/commands/inspect.js +224 -0
- package/dist/commands/inspect.js.map +1 -0
- package/dist/commands/list.d.ts +18 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +88 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/mcp.d.ts +8 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +22 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/migrate.d.ts +3 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +42 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/register.d.ts +6 -0
- package/dist/commands/register.d.ts.map +1 -0
- package/dist/commands/register.js +51 -0
- package/dist/commands/register.js.map +1 -0
- package/dist/commands/replay-format.d.ts +3 -0
- package/dist/commands/replay-format.d.ts.map +1 -0
- package/dist/commands/replay-format.js +10 -0
- package/dist/commands/replay-format.js.map +1 -0
- package/dist/commands/replay.d.ts +38 -0
- package/dist/commands/replay.d.ts.map +1 -0
- package/dist/commands/replay.js +173 -0
- package/dist/commands/replay.js.map +1 -0
- package/dist/commands/respond.d.ts +20 -0
- package/dist/commands/respond.d.ts.map +1 -0
- package/dist/commands/respond.js +49 -0
- package/dist/commands/respond.js.map +1 -0
- package/dist/commands/resume.d.ts +15 -0
- package/dist/commands/resume.d.ts.map +1 -0
- package/dist/commands/resume.js +63 -0
- package/dist/commands/resume.js.map +1 -0
- package/dist/commands/run.d.ts +3 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +127 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/serve.d.ts +33 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +144 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/commands/test.d.ts +12 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +58 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/validate.d.ts +3 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +35 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/commands/watch.d.ts +18 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +112 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/commands/webhook.d.ts +51 -0
- package/dist/commands/webhook.d.ts.map +1 -0
- package/dist/commands/webhook.js +227 -0
- package/dist/commands/webhook.js.map +1 -0
- package/dist/commands-registry.d.ts +7 -0
- package/dist/commands-registry.d.ts.map +1 -0
- package/dist/commands-registry.js +44 -0
- package/dist/commands-registry.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/store/replay-store.d.ts +29 -0
- package/dist/store/replay-store.d.ts.map +1 -0
- package/dist/store/replay-store.js +31 -0
- package/dist/store/replay-store.js.map +1 -0
- package/package.json +83 -0
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
// run-agent.ts — Core agent loop logic, decoupled from the Commander handler for testability.
|
|
2
|
+
// Exports runAgent(), AgentDeps, AgentRunOptions, and AgentRunResult.
|
|
3
|
+
// All Slack-specific gate notification logic lives in slack-gate-notifier.ts.
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { loadWorkflowFromFile, findEligibleSteps, executeChain, buildNextActions, WorkflowError, } from '@sensigo/realm';
|
|
6
|
+
import { isToolCapable } from './providers/llm-provider.js';
|
|
7
|
+
import { McpClient as McpClientImpl } from './mcp/mcp-client.js';
|
|
8
|
+
/**
|
|
9
|
+
* Renders a display template against a flat vars object.
|
|
10
|
+
* Syntax: {{ field }} or {{ nested.field }} — plain dot-path interpolation, no filters.
|
|
11
|
+
* Missing paths render as empty string.
|
|
12
|
+
*/
|
|
13
|
+
function renderDisplay(template, vars) {
|
|
14
|
+
return template.replace(/\{\{\s*([^}]+?)\s*\}\}/g, (_, expr) => {
|
|
15
|
+
const parts = expr.trim().split('.');
|
|
16
|
+
let val = vars;
|
|
17
|
+
for (const part of parts) {
|
|
18
|
+
if (typeof val !== 'object' || val === null) {
|
|
19
|
+
val = undefined;
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
val = val[part];
|
|
23
|
+
}
|
|
24
|
+
return val === undefined ? '' : typeof val === 'string' ? val : JSON.stringify(val);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Formats a step output object as human-readable plain text for the terminal.
|
|
29
|
+
* Renders `headline` and `message` string fields directly; falls back to JSON.
|
|
30
|
+
*/
|
|
31
|
+
function formatOutputForTerminal(output) {
|
|
32
|
+
const headline = typeof output['headline'] === 'string' ? output['headline'] : undefined;
|
|
33
|
+
const message = typeof output['message'] === 'string' ? output['message'] : undefined;
|
|
34
|
+
if (headline !== undefined || message !== undefined) {
|
|
35
|
+
const parts = [];
|
|
36
|
+
if (headline !== undefined)
|
|
37
|
+
parts.push(headline);
|
|
38
|
+
if (message !== undefined)
|
|
39
|
+
parts.push(message);
|
|
40
|
+
return parts.join('\n\n');
|
|
41
|
+
}
|
|
42
|
+
if (Object.keys(output).length === 0) {
|
|
43
|
+
return '(no output)';
|
|
44
|
+
}
|
|
45
|
+
return JSON.stringify(output, null, 2);
|
|
46
|
+
}
|
|
47
|
+
async function pollUntilGateResolved(store, runId, gateId, intervalMs, signal) {
|
|
48
|
+
console.log(' Waiting for approval...');
|
|
49
|
+
for (;;) {
|
|
50
|
+
if (signal?.aborted)
|
|
51
|
+
break;
|
|
52
|
+
await new Promise((resolve) => {
|
|
53
|
+
const timer = setTimeout(resolve, intervalMs);
|
|
54
|
+
if (signal !== undefined) {
|
|
55
|
+
signal.addEventListener('abort', () => {
|
|
56
|
+
clearTimeout(timer);
|
|
57
|
+
resolve();
|
|
58
|
+
}, { once: true });
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
if (signal?.aborted)
|
|
62
|
+
break;
|
|
63
|
+
const run = await store.get(runId);
|
|
64
|
+
if (run.terminal_state)
|
|
65
|
+
break;
|
|
66
|
+
if (run.pending_gate === undefined || run.pending_gate.gate_id !== gateId)
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Runs a workflow to completion using the provided dependencies.
|
|
72
|
+
* Returns 'completed' when the run finishes normally; 'failed' otherwise.
|
|
73
|
+
* Throws on setup failures (e.g. workflow file not found, provider error).
|
|
74
|
+
*/
|
|
75
|
+
export async function runAgent(deps, options) {
|
|
76
|
+
if (options.existingRunId !== undefined && options.workflowPath !== undefined) {
|
|
77
|
+
throw new Error('existingRunId and workflowPath are mutually exclusive');
|
|
78
|
+
}
|
|
79
|
+
// Load or use provided definition.
|
|
80
|
+
const definition = options.definition !== undefined
|
|
81
|
+
? options.definition
|
|
82
|
+
: loadWorkflowFromFile(options.workflowPath.endsWith('.yaml') || options.workflowPath.endsWith('.yml')
|
|
83
|
+
? options.workflowPath
|
|
84
|
+
: join(options.workflowPath, 'workflow.yaml'));
|
|
85
|
+
// Register only when explicitly requested (--register flag).
|
|
86
|
+
// By default realm agent does not write to ~/.realm/workflows/ as a side effect.
|
|
87
|
+
if (options.register === true) {
|
|
88
|
+
await deps.workflowStore.register(definition);
|
|
89
|
+
}
|
|
90
|
+
let runId;
|
|
91
|
+
let currentRun;
|
|
92
|
+
if (options.existingRunId !== undefined) {
|
|
93
|
+
// --run-id path: attach to existing run
|
|
94
|
+
currentRun = await deps.store.get(options.existingRunId);
|
|
95
|
+
if (currentRun.terminal_state) {
|
|
96
|
+
throw new Error(`Run ${options.existingRunId} is already in terminal state: ${currentRun.terminal_reason ?? currentRun.run_phase}`);
|
|
97
|
+
}
|
|
98
|
+
runId = options.existingRunId;
|
|
99
|
+
// in_progress_steps on attach: handled by engine's existing eligibility logic — no restart needed
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
// Normal path: create new run
|
|
103
|
+
const initialRecord = await deps.store.create({
|
|
104
|
+
workflowId: definition.id,
|
|
105
|
+
workflowVersion: definition.version,
|
|
106
|
+
params: options.params,
|
|
107
|
+
});
|
|
108
|
+
runId = initialRecord.id;
|
|
109
|
+
currentRun = await deps.store.get(runId);
|
|
110
|
+
}
|
|
111
|
+
console.log(`\nRealm Agent — ${definition.name} v${definition.version}`);
|
|
112
|
+
console.log(`Run ID: ${runId}\n`);
|
|
113
|
+
// Initialise MCP client if any steps declare tools.
|
|
114
|
+
let mcpClient;
|
|
115
|
+
if (definition.mcp_servers !== undefined && definition.mcp_servers.length > 0) {
|
|
116
|
+
const serverIds = new Set(definition.mcp_servers.map((s) => s.id));
|
|
117
|
+
for (const step of Object.values(definition.steps)) {
|
|
118
|
+
for (const toolEntry of step.tools ?? []) {
|
|
119
|
+
const serverId = toolEntry.split(':')[0] ?? '';
|
|
120
|
+
if (!serverIds.has(serverId)) {
|
|
121
|
+
throw new Error(`Step tool '${toolEntry}' references unknown MCP server '${serverId}'`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
mcpClient = (deps.mcpClientFactory ?? ((s, sig) => new McpClientImpl(s, sig)))(definition.mcp_servers, undefined);
|
|
126
|
+
if (!isToolCapable(deps.provider)) {
|
|
127
|
+
throw new Error('This workflow uses MCP tool-enabled steps, but the configured LLM provider does not support tool calling. ' +
|
|
128
|
+
'Reasoning models (o1-series) and custom non-tool providers cannot run tool-enabled steps. ' +
|
|
129
|
+
'Use --provider openai with a standard chat model (e.g. gpt-4o), or --provider anthropic.');
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
try {
|
|
133
|
+
while (!currentRun.terminal_state) {
|
|
134
|
+
// --- Gate handling ---
|
|
135
|
+
if (currentRun.pending_gate !== undefined) {
|
|
136
|
+
const gate = currentRun.pending_gate;
|
|
137
|
+
console.log(`\n⏸ Gate: ${gate.step_name} | ID: ${gate.gate_id}`);
|
|
138
|
+
const gateStepDef = definition.steps[gate.step_name];
|
|
139
|
+
const gateText = gate.resolved_message ??
|
|
140
|
+
(gateStepDef?.display !== undefined
|
|
141
|
+
? renderDisplay(gateStepDef.display, gate.preview)
|
|
142
|
+
: formatOutputForTerminal(gate.preview));
|
|
143
|
+
const indented = gateText
|
|
144
|
+
.trimEnd()
|
|
145
|
+
.split('\n')
|
|
146
|
+
.map((l) => ` ${l}`)
|
|
147
|
+
.join('\n');
|
|
148
|
+
console.log('\n' + indented + '\n');
|
|
149
|
+
if (deps.gateHandler !== undefined) {
|
|
150
|
+
await deps.gateHandler(runId, gate);
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
// Terminal fallback: print each choice as a command and poll.
|
|
154
|
+
for (const choice of gate.choices) {
|
|
155
|
+
const label = choice.charAt(0).toUpperCase() + choice.slice(1);
|
|
156
|
+
console.log(` ${label}: realm run respond ${runId} --gate ${gate.gate_id} --choice ${choice}`);
|
|
157
|
+
}
|
|
158
|
+
await pollUntilGateResolved(deps.store, runId, gate.gate_id, options.pollIntervalMs ?? 3000);
|
|
159
|
+
}
|
|
160
|
+
currentRun = await deps.store.get(runId);
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
// --- Step execution ---
|
|
164
|
+
const eligible = findEligibleSteps(definition, currentRun);
|
|
165
|
+
if (eligible.length === 0)
|
|
166
|
+
break;
|
|
167
|
+
const stepName = eligible[0];
|
|
168
|
+
const stepDef = definition.steps[stepName];
|
|
169
|
+
let stepInput;
|
|
170
|
+
let toolCallsForMeta;
|
|
171
|
+
if (stepDef.execution === 'agent') {
|
|
172
|
+
// Resolve template-expanded prompt via buildNextActions so {{ context.resources.* }}
|
|
173
|
+
// references are substituted before the LLM call.
|
|
174
|
+
const nextActions = buildNextActions(definition, currentRun);
|
|
175
|
+
const nextAction = nextActions.find((a) => a.instruction !== null &&
|
|
176
|
+
a.instruction.call_with['command'] === stepName) ?? nextActions[0];
|
|
177
|
+
const prompt = nextAction?.prompt ?? stepDef.description;
|
|
178
|
+
const inputSchema = nextAction?.input_schema ??
|
|
179
|
+
stepDef.input_schema;
|
|
180
|
+
const descPreview = stepDef.description.slice(0, 80);
|
|
181
|
+
console.log(`\n→ [agent] ${stepName}`);
|
|
182
|
+
console.log(` ${descPreview}${stepDef.description.length > 80 ? '…' : ''}`);
|
|
183
|
+
if (stepDef.tools && stepDef.tools.length > 0 && mcpClient) {
|
|
184
|
+
// Tools path: build tool definitions, call callStepWithTools.
|
|
185
|
+
const byServer = new Map();
|
|
186
|
+
for (const entry of stepDef.tools) {
|
|
187
|
+
const [serverId, toolName] = entry.split(':');
|
|
188
|
+
if (!byServer.has(serverId))
|
|
189
|
+
byServer.set(serverId, []);
|
|
190
|
+
byServer.get(serverId).push(toolName);
|
|
191
|
+
}
|
|
192
|
+
let toolsResult;
|
|
193
|
+
try {
|
|
194
|
+
const toolDefs = [];
|
|
195
|
+
const barenameOwner = new Map(); // bareName → serverId of first registration
|
|
196
|
+
for (const [serverId, allowList] of byServer) {
|
|
197
|
+
const mcpTools = await mcpClient.getTools(serverId, allowList);
|
|
198
|
+
const returnedNames = new Set(mcpTools.map((t) => t.name));
|
|
199
|
+
for (const name of allowList) {
|
|
200
|
+
if (!returnedNames.has(name)) {
|
|
201
|
+
throw new WorkflowError(`Step '${stepName}' declares tool '${serverId}:${name}' which is not exposed by MCP server '${serverId}'. ` +
|
|
202
|
+
`Check the tool name against the server's published tool list.`, {
|
|
203
|
+
code: 'MCP_TOOL_NOT_FOUND',
|
|
204
|
+
category: 'ENGINE',
|
|
205
|
+
agentAction: 'stop',
|
|
206
|
+
retryable: false,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
for (const mcpTool of mcpTools) {
|
|
211
|
+
const firstOwner = barenameOwner.get(mcpTool.name);
|
|
212
|
+
if (firstOwner !== undefined) {
|
|
213
|
+
throw new WorkflowError(`Tool name collision in step '${stepName}': '${mcpTool.name}' is exposed by both '${firstOwner}' and '${serverId}'. ` +
|
|
214
|
+
`Tool names must be unique across all connected servers within a step.`, {
|
|
215
|
+
code: 'MCP_TOOL_NAME_COLLISION',
|
|
216
|
+
category: 'ENGINE',
|
|
217
|
+
agentAction: 'stop',
|
|
218
|
+
retryable: false,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
barenameOwner.set(mcpTool.name, serverId);
|
|
222
|
+
toolDefs.push({
|
|
223
|
+
id: `${serverId}:${mcpTool.name}`,
|
|
224
|
+
serverId,
|
|
225
|
+
name: mcpTool.name,
|
|
226
|
+
description: mcpTool.description,
|
|
227
|
+
inputSchema: mcpTool.inputSchema,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
const executor = async (namespacedName, args) => {
|
|
232
|
+
const [serverId, toolName] = namespacedName.split(':');
|
|
233
|
+
return mcpClient.call(serverId, toolName, args);
|
|
234
|
+
};
|
|
235
|
+
if (!isToolCapable(deps.provider)) {
|
|
236
|
+
throw new Error('invariant: provider lost tool capability between startup and step execution');
|
|
237
|
+
}
|
|
238
|
+
toolsResult = await deps.provider.callStepWithTools(prompt, toolDefs, executor, {
|
|
239
|
+
...(stepDef.input_schema !== undefined
|
|
240
|
+
? { inputSchema: stepDef.input_schema }
|
|
241
|
+
: {}),
|
|
242
|
+
maxToolCalls: stepDef.max_tool_calls ?? 20,
|
|
243
|
+
toolTimeoutMs: (stepDef.tool_timeout ?? 30) * 1000,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
catch (err) {
|
|
247
|
+
console.error(`\n✗ Step '${stepName}' (tools) failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
248
|
+
return 'failed';
|
|
249
|
+
}
|
|
250
|
+
stepInput = toolsResult.output;
|
|
251
|
+
toolCallsForMeta = toolsResult.toolCalls;
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
// Retry the LLM call once on failure before giving up.
|
|
255
|
+
let callError;
|
|
256
|
+
stepInput = {};
|
|
257
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
258
|
+
try {
|
|
259
|
+
stepInput = await deps.provider.callStep(prompt, inputSchema);
|
|
260
|
+
callError = undefined;
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
catch (err) {
|
|
264
|
+
callError = err;
|
|
265
|
+
console.warn(` ⚠ LLM call attempt ${attempt + 1} failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (callError !== undefined) {
|
|
269
|
+
console.error(`\n✗ Step '${stepName}' LLM call failed after 2 attempts`);
|
|
270
|
+
return 'failed';
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
// Auto step — the engine dispatches to the service adapter directly.
|
|
276
|
+
console.log(`→ [auto] ${stepName}`);
|
|
277
|
+
stepInput = {};
|
|
278
|
+
}
|
|
279
|
+
const result = await executeChain(deps.store, definition, {
|
|
280
|
+
runId,
|
|
281
|
+
command: stepName,
|
|
282
|
+
input: stepInput,
|
|
283
|
+
dispatcher: async () => stepInput,
|
|
284
|
+
registry: deps.registry,
|
|
285
|
+
...(toolCallsForMeta !== undefined ? { stepMeta: { toolCalls: toolCallsForMeta } } : {}),
|
|
286
|
+
});
|
|
287
|
+
if (result.status === 'error') {
|
|
288
|
+
console.error(`\n✗ Step '${stepName}' failed: ${result.errors.join(', ')}`);
|
|
289
|
+
return 'failed';
|
|
290
|
+
}
|
|
291
|
+
if (result.status === 'confirm_required') {
|
|
292
|
+
// Gate will be handled at the top of the next iteration.
|
|
293
|
+
currentRun = await deps.store.get(runId);
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
currentRun = await deps.store.get(runId);
|
|
297
|
+
console.log(` ✓ → ${currentRun.run_phase}`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
finally {
|
|
301
|
+
if (mcpClient) {
|
|
302
|
+
await mcpClient.disconnect();
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
if (currentRun.run_phase === 'completed') {
|
|
306
|
+
console.log(`\nRun complete: ${runId}`);
|
|
307
|
+
// Print the last agent step's output so the result is visible without
|
|
308
|
+
// a separate `realm run inspect` call.
|
|
309
|
+
const lastAgentEvidence = [...currentRun.evidence]
|
|
310
|
+
.reverse()
|
|
311
|
+
.find((snapshot) => snapshot.status === 'success' &&
|
|
312
|
+
snapshot.kind !== 'gate_response' &&
|
|
313
|
+
definition.steps[snapshot.step_id]?.execution === 'agent');
|
|
314
|
+
if (lastAgentEvidence !== undefined) {
|
|
315
|
+
console.log(`\nResult (${lastAgentEvidence.step_id}):`);
|
|
316
|
+
const stepDef = definition.steps[lastAgentEvidence.step_id];
|
|
317
|
+
const formatted = stepDef?.display !== undefined
|
|
318
|
+
? renderDisplay(stepDef.display, lastAgentEvidence.output_summary)
|
|
319
|
+
: formatOutputForTerminal(lastAgentEvidence.output_summary);
|
|
320
|
+
console.log(formatted);
|
|
321
|
+
}
|
|
322
|
+
return 'completed';
|
|
323
|
+
}
|
|
324
|
+
console.error(`\nRun ended in phase: ${currentRun.run_phase}`);
|
|
325
|
+
return 'failed';
|
|
326
|
+
}
|
|
327
|
+
//# sourceMappingURL=run-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-agent.js","sourceRoot":"","sources":["../../src/agent/run-agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { type RunStore, type WorkflowDefinition, type PendingGate } from '@sensigo/realm';
|
|
2
|
+
import type { LlmProvider } from './llm-provider.js';
|
|
3
|
+
/**
|
|
4
|
+
* Formats a gate preview object as human-readable Slack mrkdwn text.
|
|
5
|
+
* Uses `headline` and `message` fields when present; falls back to indented JSON.
|
|
6
|
+
* Exported for testing.
|
|
7
|
+
*/
|
|
8
|
+
export declare function formatGatePreviewForSlack(preview: Record<string, unknown>): string;
|
|
9
|
+
/**
|
|
10
|
+
* POSTs a gate-waiting notification to a Slack Incoming Webhook.
|
|
11
|
+
* Failure is warned but does not abort the workflow run.
|
|
12
|
+
* Exported for testing.
|
|
13
|
+
*/
|
|
14
|
+
export declare function postGateNotificationToSlack(webhookUrl: string, gate: PendingGate, runId: string): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Posts a gate notification to Slack via chat.postMessage (bot token path).
|
|
17
|
+
* Returns the message ts for use as a thread anchor, or undefined on failure.
|
|
18
|
+
* Exported for testing.
|
|
19
|
+
*/
|
|
20
|
+
export declare function postGateViaApi(botToken: string, channelId: string, gate: PendingGate, runId: string): Promise<string | undefined>;
|
|
21
|
+
/**
|
|
22
|
+
* Posts a reply to an existing Slack thread via chat.postMessage.
|
|
23
|
+
* Failures are warned but not thrown — best-effort.
|
|
24
|
+
* Exported for testing.
|
|
25
|
+
*/
|
|
26
|
+
export declare function postSlackReply(botToken: string, channelId: string, threadTs: string, text: string): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Starts reminder and escalation timers for an open gate.
|
|
29
|
+
* Returns a cleanup function that clears both timers — must be called when the gate resolves.
|
|
30
|
+
* Exported for testing.
|
|
31
|
+
*/
|
|
32
|
+
export declare function startGateReminderTimers(botToken: string, channelId: string, threadTs: string, gate: PendingGate, reminderIntervalMs: number, escalationThresholdMs: number): () => void;
|
|
33
|
+
/** Parameters for the bidirectional gate handler. Exported for testing. */
|
|
34
|
+
export interface BidirectionalGateParams {
|
|
35
|
+
gate: PendingGate;
|
|
36
|
+
runId: string;
|
|
37
|
+
definition: WorkflowDefinition;
|
|
38
|
+
store: RunStore;
|
|
39
|
+
provider: LlmProvider;
|
|
40
|
+
slackBotToken: string;
|
|
41
|
+
slackChannelId: string;
|
|
42
|
+
gateThreadTs: string | undefined;
|
|
43
|
+
slackSigningSecret?: string;
|
|
44
|
+
slackEventsPort: number;
|
|
45
|
+
/** SLACK_APP_TOKEN — enables Socket Mode when set. */
|
|
46
|
+
slackAppToken?: string;
|
|
47
|
+
gateReminderIntervalMs: number;
|
|
48
|
+
gateEscalationThresholdMs: number;
|
|
49
|
+
pollIntervalMs: number;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Handles a gate using Slack bidirectional resolution:
|
|
53
|
+
* - Events API (when signing secret is present) or Socket Mode (when app token is present)
|
|
54
|
+
* - LLM intent interpretation of Slack replies
|
|
55
|
+
* - Reminder and escalation timers
|
|
56
|
+
* - Falls back to store polling for terminal-command gate resolution
|
|
57
|
+
* Exported for testing.
|
|
58
|
+
*/
|
|
59
|
+
export declare function handleBidirectionalGate(params: BidirectionalGateParams): Promise<void>;
|
|
60
|
+
export interface SlackGateHandlerConfig {
|
|
61
|
+
store: RunStore;
|
|
62
|
+
definition: WorkflowDefinition;
|
|
63
|
+
/** Required by handleBidirectionalGate for LLM intent parsing. */
|
|
64
|
+
provider: LlmProvider;
|
|
65
|
+
webhookUrl?: string;
|
|
66
|
+
botToken?: string;
|
|
67
|
+
channelId?: string;
|
|
68
|
+
signingSecret?: string;
|
|
69
|
+
eventsPort?: number;
|
|
70
|
+
appToken?: string;
|
|
71
|
+
reminderIntervalMs?: number;
|
|
72
|
+
escalationThresholdMs?: number;
|
|
73
|
+
pollIntervalMs?: number;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Creates a gate handler that notifies via Slack and waits for resolution.
|
|
77
|
+
* Returns a function typed (runId, gate) => Promise<void>.
|
|
78
|
+
*/
|
|
79
|
+
export declare function createSlackGateHandler(config: SlackGateHandlerConfig): (runId: string, gate: PendingGate) => Promise<void>;
|
|
80
|
+
//# sourceMappingURL=slack-gate-notifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack-gate-notifier.d.ts","sourceRoot":"","sources":["../../src/agent/slack-gate-notifier.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,kBAAkB,EACvB,KAAK,WAAW,EACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAgBlF;AAED;;;;GAIG;AACH,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAiCf;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAgC7B;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAaf;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,WAAW,EACjB,kBAAkB,EAAE,MAAM,EAC1B,qBAAqB,EAAE,MAAM,GAC5B,MAAM,IAAI,CAyBZ;AAED,2EAA2E;AAC3E,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,kBAAkB,CAAC;IAC/B,KAAK,EAAE,QAAQ,CAAC;IAChB,QAAQ,EAAE,WAAW,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,yBAAyB,EAAE,MAAM,CAAC;IAClC,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoI5F;AAiCD,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,QAAQ,CAAC;IAChB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,kEAAkE;IAClE,QAAQ,EAAE,WAAW,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,sBAAsB,GAC7B,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAkCrD"}
|