@sensigo/realm-cli 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/agent/providers/agent-utils.d.ts +2 -2
  2. package/dist/agent/providers/agent-utils.d.ts.map +1 -1
  3. package/dist/agent/providers/agent-utils.js +7 -4
  4. package/dist/agent/providers/agent-utils.js.map +1 -1
  5. package/dist/agent/providers/anthropic-provider.d.ts +3 -1
  6. package/dist/agent/providers/anthropic-provider.d.ts.map +1 -1
  7. package/dist/agent/providers/anthropic-provider.js +15 -4
  8. package/dist/agent/providers/anthropic-provider.js.map +1 -1
  9. package/dist/agent/providers/llm-provider.d.ts +3 -1
  10. package/dist/agent/providers/llm-provider.d.ts.map +1 -1
  11. package/dist/agent/providers/llm-provider.js.map +1 -1
  12. package/dist/agent/providers/openai-provider.d.ts +3 -1
  13. package/dist/agent/providers/openai-provider.d.ts.map +1 -1
  14. package/dist/agent/providers/openai-provider.js +18 -4
  15. package/dist/agent/providers/openai-provider.js.map +1 -1
  16. package/dist/agent/providers/openai-reasoning-provider.d.ts +1 -1
  17. package/dist/agent/providers/openai-reasoning-provider.d.ts.map +1 -1
  18. package/dist/agent/providers/openai-reasoning-provider.js +2 -2
  19. package/dist/agent/providers/openai-reasoning-provider.js.map +1 -1
  20. package/dist/agent/run-agent.d.ts.map +1 -1
  21. package/dist/agent/run-agent.js +29 -2
  22. package/dist/agent/run-agent.js.map +1 -1
  23. package/dist/index.js +1 -1
  24. package/package.json +4 -4
  25. package/dist/agent/agent-utils.d.ts +0 -27
  26. package/dist/agent/agent-utils.d.ts.map +0 -1
  27. package/dist/agent/agent-utils.js +0 -79
  28. package/dist/agent/agent-utils.js.map +0 -1
  29. package/dist/agent/anthropic-provider.d.ts +0 -23
  30. package/dist/agent/anthropic-provider.d.ts.map +0 -1
  31. package/dist/agent/anthropic-provider.js +0 -245
  32. package/dist/agent/anthropic-provider.js.map +0 -1
  33. package/dist/agent/gate-intent-interpreter.d.ts +0 -29
  34. package/dist/agent/gate-intent-interpreter.d.ts.map +0 -1
  35. package/dist/agent/gate-intent-interpreter.js +0 -33
  36. package/dist/agent/gate-intent-interpreter.js.map +0 -1
  37. package/dist/agent/llm-provider.d.ts +0 -46
  38. package/dist/agent/llm-provider.d.ts.map +0 -1
  39. package/dist/agent/llm-provider.js +0 -55
  40. package/dist/agent/llm-provider.js.map +0 -1
  41. package/dist/agent/mcp-client.d.ts +0 -18
  42. package/dist/agent/mcp-client.d.ts.map +0 -1
  43. package/dist/agent/mcp-client.js +0 -108
  44. package/dist/agent/mcp-client.js.map +0 -1
  45. package/dist/agent/mcp-types.d.ts +0 -40
  46. package/dist/agent/mcp-types.d.ts.map +0 -1
  47. package/dist/agent/mcp-types.js +0 -2
  48. package/dist/agent/mcp-types.js.map +0 -1
  49. package/dist/agent/openai-provider.d.ts +0 -30
  50. package/dist/agent/openai-provider.d.ts.map +0 -1
  51. package/dist/agent/openai-provider.js +0 -253
  52. package/dist/agent/openai-provider.js.map +0 -1
  53. package/dist/agent/openai-reasoning-provider.d.ts +0 -18
  54. package/dist/agent/openai-reasoning-provider.d.ts.map +0 -1
  55. package/dist/agent/openai-reasoning-provider.js +0 -76
  56. package/dist/agent/openai-reasoning-provider.js.map +0 -1
  57. package/dist/agent/slack-gate-notifier.d.ts +0 -80
  58. package/dist/agent/slack-gate-notifier.d.ts.map +0 -1
  59. package/dist/agent/slack-gate-notifier.js +0 -315
  60. package/dist/agent/slack-gate-notifier.js.map +0 -1
  61. package/dist/agent/slack-gate-poller.d.ts +0 -28
  62. package/dist/agent/slack-gate-poller.d.ts.map +0 -1
  63. package/dist/agent/slack-gate-poller.js +0 -66
  64. package/dist/agent/slack-gate-poller.js.map +0 -1
  65. package/dist/agent/slack-gate-server.d.ts +0 -30
  66. package/dist/agent/slack-gate-server.d.ts.map +0 -1
  67. package/dist/agent/slack-gate-server.js +0 -99
  68. package/dist/agent/slack-gate-server.js.map +0 -1
  69. package/dist/agent/slack-socket-client.d.ts +0 -20
  70. package/dist/agent/slack-socket-client.d.ts.map +0 -1
  71. package/dist/agent/slack-socket-client.js +0 -141
  72. package/dist/agent/slack-socket-client.js.map +0 -1
@@ -1,80 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,315 +0,0 @@
1
- // slack-gate-notifier.ts — Slack gate notification logic.
2
- // Owns all Slack-specific gate notification: formatting, posting, reminder timers,
3
- // and bidirectional resolution via Events API or Socket Mode.
4
- // Internal to the CLI package — not exported from the package's public index.
5
- import { submitHumanResponse, } from '@sensigo/realm';
6
- import { startSlackGateServer } from './slack-gate-server.js';
7
- import { connectSocketMode } from './slack-socket-client.js';
8
- /**
9
- * Formats a gate preview object as human-readable Slack mrkdwn text.
10
- * Uses `headline` and `message` fields when present; falls back to indented JSON.
11
- * Exported for testing.
12
- */
13
- export function formatGatePreviewForSlack(preview) {
14
- const headline = typeof preview['headline'] === 'string' ? preview['headline'] : undefined;
15
- const message = typeof preview['message'] === 'string' ? preview['message'] : undefined;
16
- if (headline !== undefined || message !== undefined) {
17
- const parts = [];
18
- if (headline !== undefined)
19
- parts.push(`*${headline}*`);
20
- if (message !== undefined)
21
- parts.push(message);
22
- return parts.join('\n\n');
23
- }
24
- if (Object.keys(preview).length === 0) {
25
- return '_(no preview)_';
26
- }
27
- return '```\n' + JSON.stringify(preview, null, 2) + '\n```';
28
- }
29
- /**
30
- * POSTs a gate-waiting notification to a Slack Incoming Webhook.
31
- * Failure is warned but does not abort the workflow run.
32
- * Exported for testing.
33
- */
34
- export async function postGateNotificationToSlack(webhookUrl, gate, runId) {
35
- const ownerLine = gate.owner !== undefined ? `\n*Owner:* ${gate.owner}` : '';
36
- const previewText = gate.resolved_message ?? formatGatePreviewForSlack(gate.preview);
37
- const gateId = gate.gate_id;
38
- const cmdLines = gate.choices
39
- .map((c) => `realm run respond ${runId} --gate ${gateId} --choice ${c}`)
40
- .join('\n');
41
- const blockText = `*Gate:* \`${gate.step_name}\`${ownerLine}\n\n${previewText}\n\n---\n` +
42
- `*Gate requires a terminal response — open a terminal and run:*\n\`\`\`${cmdLines}\`\`\``;
43
- const body = {
44
- text: '⏸ Workflow gate waiting for approval',
45
- blocks: [
46
- {
47
- type: 'section',
48
- text: {
49
- type: 'mrkdwn',
50
- text: blockText,
51
- },
52
- },
53
- ],
54
- };
55
- try {
56
- await fetch(webhookUrl, {
57
- method: 'POST',
58
- headers: { 'Content-Type': 'application/json' },
59
- body: JSON.stringify(body),
60
- });
61
- }
62
- catch (err) {
63
- console.warn(` ⚠ Slack notification failed: ${err instanceof Error ? err.message : String(err)}`);
64
- }
65
- }
66
- /**
67
- * Posts a gate notification to Slack via chat.postMessage (bot token path).
68
- * Returns the message ts for use as a thread anchor, or undefined on failure.
69
- * Exported for testing.
70
- */
71
- export async function postGateViaApi(botToken, channelId, gate, runId) {
72
- const ownerLine = gate.owner !== undefined ? `\n*Owner:* ${gate.owner}` : '';
73
- const previewText = gate.resolved_message ?? formatGatePreviewForSlack(gate.preview);
74
- const choiceList = gate.choices.map((c) => `\`${c}\``).join(' or ');
75
- const gateId = gate.gate_id;
76
- const cmdLines = gate.choices
77
- .map((c) => `realm run respond ${runId} --gate ${gateId} --choice ${c}`)
78
- .join('\n');
79
- const blockText = `*Gate:* \`${gate.step_name}\`${ownerLine}\n\n${previewText}\n\n---\n` +
80
- `*Reply in this thread with ${choiceList} to resolve, or run:*\n\`\`\`${cmdLines}\`\`\``;
81
- try {
82
- const response = await fetch('https://slack.com/api/chat.postMessage', {
83
- method: 'POST',
84
- headers: {
85
- 'Content-Type': 'application/json',
86
- Authorization: `Bearer ${botToken}`,
87
- },
88
- body: JSON.stringify({
89
- channel: channelId,
90
- text: '⏸ Workflow gate waiting for approval',
91
- blocks: [{ type: 'section', text: { type: 'mrkdwn', text: blockText } }],
92
- }),
93
- });
94
- const data = (await response.json());
95
- return data.ok ? data.ts : undefined;
96
- }
97
- catch (err) {
98
- console.warn(`Gate API notification failed: ${err instanceof Error ? err.message : String(err)}`);
99
- return undefined;
100
- }
101
- }
102
- /**
103
- * Posts a reply to an existing Slack thread via chat.postMessage.
104
- * Failures are warned but not thrown — best-effort.
105
- * Exported for testing.
106
- */
107
- export async function postSlackReply(botToken, channelId, threadTs, text) {
108
- try {
109
- await fetch('https://slack.com/api/chat.postMessage', {
110
- method: 'POST',
111
- headers: {
112
- 'Content-Type': 'application/json',
113
- Authorization: `Bearer ${botToken}`,
114
- },
115
- body: JSON.stringify({ channel: channelId, thread_ts: threadTs, text }),
116
- });
117
- }
118
- catch (err) {
119
- console.warn(`Slack reply failed: ${err instanceof Error ? err.message : String(err)}`);
120
- }
121
- }
122
- /**
123
- * Starts reminder and escalation timers for an open gate.
124
- * Returns a cleanup function that clears both timers — must be called when the gate resolves.
125
- * Exported for testing.
126
- */
127
- export function startGateReminderTimers(botToken, channelId, threadTs, gate, reminderIntervalMs, escalationThresholdMs) {
128
- const reminderTimer = setTimeout(() => {
129
- postSlackReply(botToken, channelId, threadTs, `⏰ Reminder: gate \`${gate.step_name}\` is still waiting for a response.`).catch((err) => {
130
- console.warn(`Reminder post failed: ${err instanceof Error ? err.message : String(err)}`);
131
- });
132
- }, reminderIntervalMs);
133
- const escalationTimer = setTimeout(() => {
134
- const elapsedMin = Math.round((Date.now() - new Date(gate.opened_at).getTime()) / 60_000);
135
- const mention = gate.owner !== undefined ? `${gate.owner} — ` : '';
136
- const text = `${mention}gate \`${gate.step_name}\` has been open for ${elapsedMin} minutes. Please respond.`;
137
- postSlackReply(botToken, channelId, threadTs, text).catch((err) => {
138
- console.warn(`Escalation post failed: ${err instanceof Error ? err.message : String(err)}`);
139
- });
140
- }, escalationThresholdMs);
141
- return () => {
142
- clearTimeout(reminderTimer);
143
- clearTimeout(escalationTimer);
144
- };
145
- }
146
- /**
147
- * Handles a gate using Slack bidirectional resolution:
148
- * - Events API (when signing secret is present) or Socket Mode (when app token is present)
149
- * - LLM intent interpretation of Slack replies
150
- * - Reminder and escalation timers
151
- * - Falls back to store polling for terminal-command gate resolution
152
- * Exported for testing.
153
- */
154
- export async function handleBidirectionalGate(params) {
155
- const { gate, runId, definition, store, provider: _provider, slackBotToken, slackChannelId, gateThreadTs, slackSigningSecret, slackEventsPort, slackAppToken, gateReminderIntervalMs, gateEscalationThresholdMs, pollIntervalMs, } = params;
156
- let clarificationCount = 0;
157
- const abortController = new AbortController();
158
- const processCandidate = async (text) => {
159
- if (abortController.signal.aborted)
160
- return;
161
- // Gate choices must be exact (case-insensitive). No LLM interpretation — gate responses
162
- // are irreversible writes and must reflect unambiguous intent.
163
- const normalised = text.trim().toLowerCase();
164
- const exactMatch = gate.choices.find((c) => c.toLowerCase() === normalised);
165
- if (exactMatch !== undefined) {
166
- try {
167
- await submitHumanResponse(store, definition, {
168
- runId,
169
- gateId: gate.gate_id,
170
- choice: exactMatch,
171
- });
172
- if (gateThreadTs !== undefined) {
173
- const confirmationText = gate.resolution_messages?.[exactMatch] ??
174
- `✅ Gate resolved: \`${exactMatch}\` — run continuing.`;
175
- await postSlackReply(slackBotToken, slackChannelId, gateThreadTs, confirmationText);
176
- }
177
- abortController.abort();
178
- }
179
- catch (err) {
180
- console.warn(`Gate response submission failed: ${err instanceof Error ? err.message : String(err)}`);
181
- }
182
- }
183
- else if (clarificationCount < 2 && gateThreadTs !== undefined) {
184
- clarificationCount++;
185
- await postSlackReply(slackBotToken, slackChannelId, gateThreadTs, `Please reply with one of: ${gate.choices.join(', ')}`);
186
- }
187
- };
188
- // Set up candidate intake — Socket Mode (preferred), Events API, or none.
189
- // Dedup set prevents duplicate onEvent calls. Socket Mode (preferred) and Events API both
190
- // have at-least-once delivery — the same event can arrive more than once.
191
- const seenEventIds = new Set();
192
- let serverHandle;
193
- if (slackAppToken !== undefined && gateThreadTs !== undefined) {
194
- // Mode 2 — Socket Mode (WebSocket push, no public URL required)
195
- serverHandle = connectSocketMode({
196
- appToken: slackAppToken,
197
- threadTs: gateThreadTs,
198
- onEvent: (event) => {
199
- if (seenEventIds.has(event.event_id))
200
- return;
201
- seenEventIds.add(event.event_id);
202
- processCandidate(event.text).catch((err) => {
203
- console.warn(`Candidate processing failed: ${err instanceof Error ? err.message : String(err)}`);
204
- });
205
- },
206
- signal: abortController.signal,
207
- });
208
- }
209
- else if (slackSigningSecret !== undefined && gateThreadTs !== undefined) {
210
- // Mode 3 — Events API (HTTP push, requires public URL)
211
- serverHandle = startSlackGateServer({
212
- port: slackEventsPort,
213
- signingSecret: slackSigningSecret,
214
- onEvent: (event) => {
215
- if (seenEventIds.has(event.event_id))
216
- return;
217
- seenEventIds.add(event.event_id);
218
- if (event.thread_ts !== gateThreadTs)
219
- return;
220
- processCandidate(event.text).catch((err) => {
221
- console.warn(`Candidate processing failed: ${err instanceof Error ? err.message : String(err)}`);
222
- });
223
- },
224
- });
225
- }
226
- else if (gateThreadTs !== undefined) {
227
- // Gate notification posted but no listener configured.
228
- console.log(' ℹ Gate notification posted. Set SLACK_APP_TOKEN (Socket Mode) or SLACK_SIGNING_SECRET (Events API) to resolve via Slack. Using terminal command fallback.');
229
- }
230
- // Notify when neither Events nor polling can be used — no thread anchor available.
231
- if (gateThreadTs === undefined) {
232
- console.log(' ℹ Bidirectional Slack resolution unavailable (no thread anchor). Use terminal command shown above.');
233
- }
234
- // Start reminder/escalation timers if we have a thread anchor.
235
- const clearTimers = gateThreadTs !== undefined
236
- ? startGateReminderTimers(slackBotToken, slackChannelId, gateThreadTs, gate, gateReminderIntervalMs, gateEscalationThresholdMs)
237
- : () => { };
238
- try {
239
- // Poll the store as the unified done-detector — resolves when candidate processor
240
- // calls submitHumanResponse OR when the terminal command is used.
241
- await pollUntilGateResolved(store, runId, gate.gate_id, pollIntervalMs, abortController.signal);
242
- }
243
- finally {
244
- abortController.abort();
245
- clearTimers();
246
- serverHandle?.close();
247
- }
248
- }
249
- /** Polls the store until the gate is resolved or the run reaches a terminal state. */
250
- async function pollUntilGateResolved(store, runId, gateId, intervalMs, signal) {
251
- console.log(' Waiting for approval...');
252
- for (;;) {
253
- if (signal?.aborted)
254
- break;
255
- await new Promise((resolve) => {
256
- const timer = setTimeout(resolve, intervalMs);
257
- if (signal !== undefined) {
258
- signal.addEventListener('abort', () => {
259
- clearTimeout(timer);
260
- resolve();
261
- }, { once: true });
262
- }
263
- });
264
- if (signal?.aborted)
265
- break;
266
- const run = await store.get(runId);
267
- if (run.terminal_state)
268
- break;
269
- if (run.pending_gate === undefined || run.pending_gate.gate_id !== gateId)
270
- break;
271
- }
272
- }
273
- /**
274
- * Creates a gate handler that notifies via Slack and waits for resolution.
275
- * Returns a function typed (runId, gate) => Promise<void>.
276
- */
277
- export function createSlackGateHandler(config) {
278
- return async (runId, gate) => {
279
- // Bidirectional path (bot token + channel).
280
- if (config.botToken !== undefined && config.channelId !== undefined) {
281
- const gateThreadTs = await postGateViaApi(config.botToken, config.channelId, gate, runId);
282
- await handleBidirectionalGate({
283
- gate,
284
- runId,
285
- definition: config.definition,
286
- store: config.store,
287
- provider: config.provider,
288
- slackBotToken: config.botToken,
289
- slackChannelId: config.channelId,
290
- gateThreadTs,
291
- ...(config.signingSecret !== undefined ? { slackSigningSecret: config.signingSecret } : {}),
292
- slackEventsPort: config.eventsPort ?? 3100,
293
- ...(config.appToken !== undefined ? { slackAppToken: config.appToken } : {}),
294
- gateReminderIntervalMs: config.reminderIntervalMs ?? 600_000,
295
- gateEscalationThresholdMs: config.escalationThresholdMs ?? 1_800_000,
296
- pollIntervalMs: config.pollIntervalMs ?? 3000,
297
- });
298
- }
299
- else if (config.webhookUrl !== undefined) {
300
- // One-way webhook + inline poll loop (avoids circular dependency with run-agent.ts).
301
- await postGateNotificationToSlack(config.webhookUrl, gate, runId);
302
- console.log(' Waiting for approval...');
303
- const intervalMs = config.pollIntervalMs ?? 3000;
304
- for (;;) {
305
- await new Promise((resolve) => setTimeout(resolve, intervalMs));
306
- const run = await config.store.get(runId);
307
- if (run.terminal_state)
308
- break;
309
- if (run.pending_gate === undefined || run.pending_gate.gate_id !== gate.gate_id)
310
- break;
311
- }
312
- }
313
- };
314
- }
315
- //# sourceMappingURL=slack-gate-notifier.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"slack-gate-notifier.js","sourceRoot":"","sources":["../../src/agent/slack-gate-notifier.ts"],"names":[],"mappings":"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"}
@@ -1,28 +0,0 @@
1
- export interface SlackPollConfig {
2
- /** SLACK_BOT_TOKEN — used in Authorization header. */
3
- botToken: string;
4
- /** SLACK_CHANNEL_ID — channel containing the gate notification thread. */
5
- channelId: string;
6
- /** ts of the gate notification message — anchor for conversations.replies. */
7
- threadTs: string;
8
- /** Only process messages sent after this time. Set to gate opened_at. */
9
- gateOpenedAt: Date;
10
- /** Polling interval in milliseconds. Default: 10000. */
11
- intervalMs: number;
12
- /** Called with the text of each new human message. */
13
- onCandidate: (text: string) => void;
14
- /**
15
- * Called once after the first successful poll that finds no human replies.
16
- * Use to surface a hint reminding the user to reply in the thread, not the main channel.
17
- */
18
- onHint?: (message: string) => void;
19
- /** When aborted, polling stops cleanly after the current interval. */
20
- signal?: AbortSignal;
21
- }
22
- /**
23
- * Begins polling a Slack thread for new human replies.
24
- * Filters out bot messages, messages before `gateOpenedAt`, and duplicate messages.
25
- * Calls `onCandidate` at most once per unique message ts.
26
- */
27
- export declare function pollSlackThread(config: SlackPollConfig): void;
28
- //# sourceMappingURL=slack-gate-poller.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"slack-gate-poller.d.ts","sourceRoot":"","sources":["../../src/agent/slack-gate-poller.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,eAAe;IAC9B,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,YAAY,EAAE,IAAI,CAAC;IACnB,wDAAwD;IACxD,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,sEAAsE;IACtE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAmE7D"}
@@ -1,66 +0,0 @@
1
- // slack-gate-poller.ts — Polls a Slack thread for human replies when Events API is not configured.
2
- // Used as a local CLI fallback when SLACK_BOT_TOKEN and SLACK_CHANNEL_ID are set
3
- // but no Events API endpoint (SLACK_SIGNING_SECRET) is available.
4
- /**
5
- * Begins polling a Slack thread for new human replies.
6
- * Filters out bot messages, messages before `gateOpenedAt`, and duplicate messages.
7
- * Calls `onCandidate` at most once per unique message ts.
8
- */
9
- export function pollSlackThread(config) {
10
- const { botToken, channelId, threadTs, gateOpenedAt, intervalMs, onCandidate, onHint, signal } = config;
11
- const processed = new Set();
12
- // Convert gateOpenedAt to a Slack-style float timestamp string for comparison.
13
- const gateOpenedSec = gateOpenedAt.getTime() / 1000;
14
- let hintFired = false;
15
- const poll = async () => {
16
- if (signal?.aborted)
17
- return;
18
- try {
19
- const url = `https://slack.com/api/conversations.replies` +
20
- `?channel=${encodeURIComponent(channelId)}&ts=${encodeURIComponent(threadTs)}`;
21
- const response = await fetch(url, {
22
- headers: { Authorization: `Bearer ${botToken}` },
23
- });
24
- const data = (await response.json());
25
- if (data.ok && Array.isArray(data.messages)) {
26
- let foundHumanReply = false;
27
- for (const msg of data.messages) {
28
- const msgTs = msg['ts'];
29
- if (!msgTs)
30
- continue;
31
- // Skip messages sent before or at gate opened time.
32
- if (parseFloat(msgTs) <= gateOpenedSec)
33
- continue;
34
- // Filter bot messages.
35
- if (msg['subtype'] === 'bot_message' || msg['bot_id'] !== undefined)
36
- continue;
37
- // Deduplicate by ts.
38
- if (processed.has(msgTs))
39
- continue;
40
- processed.add(msgTs);
41
- foundHumanReply = true;
42
- const text = msg['text'];
43
- if (text)
44
- onCandidate(text);
45
- }
46
- // Fire the hint once after the first successful poll with no human replies.
47
- if (!foundHumanReply && !hintFired && onHint !== undefined) {
48
- hintFired = true;
49
- onHint('Waiting for a thread reply. To resolve this gate, click \u201cReply\u201d on the gate message in Slack — do not post in the main channel.');
50
- }
51
- }
52
- }
53
- catch {
54
- // Polling failures are silent — gate remains open until a valid reply arrives.
55
- }
56
- if (!signal?.aborted) {
57
- setTimeout(() => {
58
- void poll();
59
- }, intervalMs);
60
- }
61
- };
62
- setTimeout(() => {
63
- void poll();
64
- }, intervalMs);
65
- }
66
- //# sourceMappingURL=slack-gate-poller.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"slack-gate-poller.js","sourceRoot":"","sources":["../../src/agent/slack-gate-poller.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,iFAAiF;AACjF,kEAAkE;AAwBlE;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,MAAuB;IACrD,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,GAC5F,MAAM,CAAC;IAET,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,+EAA+E;IAC/E,MAAM,aAAa,GAAG,YAAY,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;IACpD,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,MAAM,IAAI,GAAG,KAAK,IAAmB,EAAE;QACrC,IAAI,MAAM,EAAE,OAAO;YAAE,OAAO;QAE5B,IAAI,CAAC;YACH,MAAM,GAAG,GACP,6CAA6C;gBAC7C,YAAY,kBAAkB,CAAC,SAAS,CAAC,OAAO,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,QAAQ,EAAE,EAAE;aACjD,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAGlC,CAAC;YAEF,IAAI,IAAI,CAAC,EAAE,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC5C,IAAI,eAAe,GAAG,KAAK,CAAC;gBAC5B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAChC,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAuB,CAAC;oBAC9C,IAAI,CAAC,KAAK;wBAAE,SAAS;oBAErB,oDAAoD;oBACpD,IAAI,UAAU,CAAC,KAAK,CAAC,IAAI,aAAa;wBAAE,SAAS;oBAEjD,uBAAuB;oBACvB,IAAI,GAAG,CAAC,SAAS,CAAC,KAAK,aAAa,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,SAAS;wBAAE,SAAS;oBAE9E,qBAAqB;oBACrB,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;wBAAE,SAAS;oBACnC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;oBAErB,eAAe,GAAG,IAAI,CAAC;oBACvB,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAuB,CAAC;oBAC/C,IAAI,IAAI;wBAAE,WAAW,CAAC,IAAI,CAAC,CAAC;gBAC9B,CAAC;gBAED,4EAA4E;gBAC5E,IAAI,CAAC,eAAe,IAAI,CAAC,SAAS,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBAC3D,SAAS,GAAG,IAAI,CAAC;oBACjB,MAAM,CACJ,2IAA2I,CAC5I,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,+EAA+E;QACjF,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;YACrB,UAAU,CAAC,GAAG,EAAE;gBACd,KAAK,IAAI,EAAE,CAAC;YACd,CAAC,EAAE,UAAU,CAAC,CAAC;QACjB,CAAC;IACH,CAAC,CAAC;IAEF,UAAU,CAAC,GAAG,EAAE;QACd,KAAK,IAAI,EAAE,CAAC;IACd,CAAC,EAAE,UAAU,CAAC,CAAC;AACjB,CAAC"}
@@ -1,30 +0,0 @@
1
- /** A verified, filtered Slack message event from the gate thread. */
2
- export interface SlackGateEvent {
3
- /** Dedupe key from the Slack event envelope. */
4
- event_id: string;
5
- /** Thread timestamp — must match the gate notification message ts. */
6
- thread_ts: string;
7
- /** Slack user ID of the message author. */
8
- user: string;
9
- /** Raw message text to be interpreted. */
10
- text: string;
11
- /** Slack event timestamp (format: '1234567890.123456'). */
12
- ts: string;
13
- }
14
- export interface SlackGateServerOptions {
15
- /** Local port to listen on. Default: 3100. Configurable via SLACK_EVENTS_PORT. */
16
- port: number;
17
- /** Slack signing secret for HMAC-SHA256 verification. Never logged. */
18
- signingSecret: string;
19
- /** Called for each valid, non-bot message event that passes verification. */
20
- onEvent: (event: SlackGateEvent) => void;
21
- }
22
- /**
23
- * Starts a local HTTP server that receives Slack Events API callbacks.
24
- * Verifies request signatures before processing any payload.
25
- * Returns a handle to close the server.
26
- */
27
- export declare function startSlackGateServer(options: SlackGateServerOptions): {
28
- close(): void;
29
- };
30
- //# sourceMappingURL=slack-gate-server.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"slack-gate-server.d.ts","sourceRoot":"","sources":["../../src/agent/slack-gate-server.ts"],"names":[],"mappings":"AAKA,qEAAqE;AACrE,MAAM,WAAW,cAAc;IAC7B,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,SAAS,EAAE,MAAM,CAAC;IAClB,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,sBAAsB;IACrC,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,aAAa,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,OAAO,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;CAC1C;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,sBAAsB,GAAG;IAAE,KAAK,IAAI,IAAI,CAAA;CAAE,CAoGvF"}