assistme 0.2.8 → 0.2.9
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/chunk-TTEGHE2E.js +47 -0
- package/dist/chunk-UWE5WVQI.js +289 -0
- package/dist/config-PUIS2TQL.js +12 -0
- package/dist/index.js +434 -672
- package/dist/job-runner-N4XAAWLJ.js +7 -0
- package/package.json +1 -2
- package/src/agent/job-runner.ts +33 -71
- package/src/agent/mcp-servers.ts +26 -149
- package/src/agent/memory.test.ts +41 -65
- package/src/agent/memory.ts +33 -134
- package/src/agent/processor.ts +0 -3
- package/src/agent/scheduler.ts +47 -93
- package/src/agent/session.test.ts +8 -12
- package/src/agent/session.ts +10 -53
- package/src/agent/skills.ts +89 -488
- package/src/commands/job.ts +6 -6
- package/src/commands/status.ts +3 -10
- package/src/db/api-client.ts +68 -0
- package/src/db/supabase.test.ts +71 -184
- package/src/db/supabase.ts +140 -243
- package/dist/chunk-XY3LGAOY.js +0 -580
- package/dist/job-runner-XTGLMPZ3.js +0 -6
package/src/db/supabase.ts
CHANGED
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
import { createClient, SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
-
import { createHash } from "crypto";
|
|
3
|
-
import { getConfig } from "../utils/config.js";
|
|
4
|
-
import { log } from "../utils/logger.js";
|
|
5
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
6
2
|
import { join } from "path";
|
|
7
3
|
import { homedir } from "os";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export const CLI_AGENT_ID = "00000000-0000-0000-0000-000000000001";
|
|
12
|
-
export const DAYBOX_AGENT_ID = "00000000-0000-0000-0000-000000000002";
|
|
4
|
+
import { callMcpHandler } from "./api-client.js";
|
|
5
|
+
import { log } from "../utils/logger.js";
|
|
13
6
|
|
|
14
7
|
// ── Auth Store (persists am_ token to disk) ──────────────────────────
|
|
15
8
|
|
|
@@ -38,46 +31,11 @@ function writeAuthStore(data: Record<string, string>) {
|
|
|
38
31
|
writeFileSync(AUTH_FILE, JSON.stringify(data, null, 2), { mode: 0o600 });
|
|
39
32
|
}
|
|
40
33
|
|
|
41
|
-
// ── Supabase Client (anon key only, no auth session) ────────────────
|
|
42
|
-
|
|
43
|
-
let supabase: SupabaseClient | null = null;
|
|
44
|
-
|
|
45
|
-
export function getSupabase(): SupabaseClient {
|
|
46
|
-
if (!supabase) {
|
|
47
|
-
const config = getConfig();
|
|
48
|
-
if (!config.supabaseUrl || !config.supabaseAnonKey) {
|
|
49
|
-
throw new Error(
|
|
50
|
-
"Supabase not configured. Run `assistme config set supabaseUrl <url>` first."
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
supabase = createClient(config.supabaseUrl, config.supabaseAnonKey, {
|
|
54
|
-
auth: { persistSession: false },
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
return supabase;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// ── Token Hash ──────────────────────────────────────────────────────
|
|
61
|
-
|
|
62
|
-
function hashToken(token: string): string {
|
|
63
|
-
return createHash("sha256").update(token).digest("hex");
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/** Get stored token hash (computed from persisted am_ token). */
|
|
67
|
-
function getTokenHash(): string {
|
|
68
|
-
const store = readAuthStore();
|
|
69
|
-
const token = store["mcp_token"];
|
|
70
|
-
if (!token || !token.startsWith("am_")) {
|
|
71
|
-
throw new Error("Not authenticated. Run `assistme login`.");
|
|
72
|
-
}
|
|
73
|
-
return hashToken(token);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
34
|
// ── Auth ─────────────────────────────────────────────────────────────
|
|
77
35
|
|
|
78
36
|
/**
|
|
79
37
|
* Login using an am_ MCP token.
|
|
80
|
-
* Validates against DB via
|
|
38
|
+
* Validates against DB via edge function, stores locally.
|
|
81
39
|
*/
|
|
82
40
|
export async function loginWithToken(mcpToken: string): Promise<string> {
|
|
83
41
|
if (!mcpToken.startsWith("am_")) {
|
|
@@ -86,34 +44,25 @@ export async function loginWithToken(mcpToken: string): Promise<string> {
|
|
|
86
44
|
);
|
|
87
45
|
}
|
|
88
46
|
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
if (error) throw new Error(`Token validation failed: ${error.message}`);
|
|
97
|
-
if (!data || data.length === 0) throw new Error("Invalid or expired token");
|
|
47
|
+
const result = await callMcpHandler<{ user_id: string; email: string | null }>(
|
|
48
|
+
"auth.validate_token",
|
|
49
|
+
{},
|
|
50
|
+
mcpToken,
|
|
51
|
+
);
|
|
98
52
|
|
|
99
53
|
// Persist token
|
|
100
54
|
const store = readAuthStore();
|
|
101
55
|
store["mcp_token"] = mcpToken;
|
|
102
56
|
writeAuthStore(store);
|
|
103
57
|
|
|
104
|
-
return
|
|
58
|
+
return result.user_id;
|
|
105
59
|
}
|
|
106
60
|
|
|
107
61
|
export async function getCurrentUserId(): Promise<string> {
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
});
|
|
113
|
-
if (error || !data || data.length === 0) {
|
|
114
|
-
throw new Error("Token expired or revoked. Run `assistme login`.");
|
|
115
|
-
}
|
|
116
|
-
return data[0].out_user_id;
|
|
62
|
+
const result = await callMcpHandler<{ user_id: string }>(
|
|
63
|
+
"auth.validate_token",
|
|
64
|
+
);
|
|
65
|
+
return result.user_id;
|
|
117
66
|
}
|
|
118
67
|
|
|
119
68
|
export async function logout(): Promise<void> {
|
|
@@ -145,61 +94,71 @@ export async function createSession(
|
|
|
145
94
|
workspacePath: string,
|
|
146
95
|
version: string
|
|
147
96
|
): Promise<AgentSession> {
|
|
148
|
-
const
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
p_model: getConfig().model || null,
|
|
97
|
+
const { getConfig } = await import("../utils/config.js");
|
|
98
|
+
const data = await callMcpHandler<AgentSession>("session.create", {
|
|
99
|
+
session_name: sessionName,
|
|
100
|
+
workspace_path: workspacePath,
|
|
101
|
+
version,
|
|
102
|
+
model: getConfig().model || null,
|
|
155
103
|
});
|
|
156
|
-
|
|
157
|
-
if (error) throw new Error(`Failed to create session: ${error.message}`);
|
|
158
|
-
return data as AgentSession;
|
|
104
|
+
return data;
|
|
159
105
|
}
|
|
160
106
|
|
|
161
107
|
export async function updateHeartbeat(sessionId: string): Promise<void> {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
if (error) log.warn(`Heartbeat update failed: ${error.message}`);
|
|
108
|
+
try {
|
|
109
|
+
await callMcpHandler("session.heartbeat", { session_id: sessionId });
|
|
110
|
+
} catch (err) {
|
|
111
|
+
log.warn(`Heartbeat update failed: ${err instanceof Error ? err.message : err}`);
|
|
112
|
+
}
|
|
168
113
|
}
|
|
169
114
|
|
|
170
115
|
export async function endSession(sessionId: string): Promise<void> {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
if (error) log.error(`Failed to end session: ${error.message}`);
|
|
116
|
+
try {
|
|
117
|
+
await callMcpHandler("session.end", { session_id: sessionId });
|
|
118
|
+
} catch (err) {
|
|
119
|
+
log.error(`Failed to end session: ${err instanceof Error ? err.message : err}`);
|
|
120
|
+
}
|
|
177
121
|
}
|
|
178
122
|
|
|
179
123
|
export async function setSessionBusy(
|
|
180
124
|
sessionId: string,
|
|
181
125
|
busy: boolean
|
|
182
126
|
): Promise<void> {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
p_session_id: sessionId,
|
|
187
|
-
p_busy: busy,
|
|
127
|
+
await callMcpHandler("session.set_busy", {
|
|
128
|
+
session_id: sessionId,
|
|
129
|
+
busy,
|
|
188
130
|
});
|
|
189
131
|
}
|
|
190
132
|
|
|
133
|
+
export async function cleanupStaleSessions(
|
|
134
|
+
currentSessionId: string,
|
|
135
|
+
thresholdMs = 120_000
|
|
136
|
+
): Promise<number> {
|
|
137
|
+
try {
|
|
138
|
+
const result = await callMcpHandler<{ cleaned: number }>(
|
|
139
|
+
"session.cleanup_stale",
|
|
140
|
+
{ current_session_id: currentSessionId, threshold_ms: thresholdMs },
|
|
141
|
+
);
|
|
142
|
+
return result.cleaned;
|
|
143
|
+
} catch {
|
|
144
|
+
return 0;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export async function getActiveSessions(
|
|
149
|
+
limit = 5
|
|
150
|
+
): Promise<AgentSession[]> {
|
|
151
|
+
return callMcpHandler<AgentSession[]>("session.get_active", { limit });
|
|
152
|
+
}
|
|
153
|
+
|
|
191
154
|
// ── Conversation Management ─────────────────────────────────────────
|
|
192
155
|
|
|
193
156
|
export async function getOrCreateCliConversation(
|
|
194
157
|
_userId: string,
|
|
195
158
|
_sessionId: string
|
|
196
159
|
): Promise<string> {
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
p_token_hash: getTokenHash(),
|
|
200
|
-
});
|
|
201
|
-
if (error) throw new Error(`Failed to get conversation: ${error.message}`);
|
|
202
|
-
return data as string;
|
|
160
|
+
const data = await callMcpHandler<string>("conversation.get_or_create");
|
|
161
|
+
return data;
|
|
203
162
|
}
|
|
204
163
|
|
|
205
164
|
// ── Message / Task Management ────────────────────────────────────────
|
|
@@ -228,77 +187,46 @@ export async function createTask(
|
|
|
228
187
|
sessionId: string,
|
|
229
188
|
prompt: string
|
|
230
189
|
): Promise<ConversationMessage> {
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
p_session_id: sessionId,
|
|
236
|
-
p_prompt: prompt,
|
|
190
|
+
const data = await callMcpHandler<Record<string, unknown>>("task.create", {
|
|
191
|
+
conversation_id: conversationId,
|
|
192
|
+
session_id: sessionId,
|
|
193
|
+
prompt,
|
|
237
194
|
});
|
|
238
|
-
|
|
239
|
-
if (error) throw new Error(`Failed to create task: ${error.message}`);
|
|
240
195
|
return { ...data, prompt } as ConversationMessage;
|
|
241
196
|
}
|
|
242
197
|
|
|
243
|
-
export async function pollPendingTasks(
|
|
244
|
-
sessionId: string
|
|
245
|
-
): Promise<ConversationMessage[]> {
|
|
246
|
-
const sb = getSupabase();
|
|
247
|
-
const { data, error } = await sb.rpc("mcp_poll_tasks", {
|
|
248
|
-
p_token_hash: getTokenHash(),
|
|
249
|
-
p_session_id: sessionId,
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
if (error) {
|
|
253
|
-
log.warn(`Task poll failed: ${error.message}`);
|
|
254
|
-
return [];
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
const rows = (data || []) as Record<string, unknown>[];
|
|
258
|
-
return rows.map((row) => ({
|
|
259
|
-
...row,
|
|
260
|
-
prompt:
|
|
261
|
-
(row.metadata as Record<string, unknown>)?.prompt || row.content || "",
|
|
262
|
-
})) as ConversationMessage[];
|
|
263
|
-
}
|
|
264
|
-
|
|
265
198
|
/**
|
|
266
|
-
* Atomically poll ONE pending task and claim it in a single
|
|
199
|
+
* Atomically poll ONE pending task and claim it in a single call.
|
|
267
200
|
* Uses FOR UPDATE SKIP LOCKED — concurrent CLIs will never grab the same task.
|
|
268
201
|
* Returns null if no pending task exists.
|
|
269
202
|
*/
|
|
270
203
|
export async function pollAndClaimTask(
|
|
271
204
|
sessionId: string
|
|
272
205
|
): Promise<ConversationMessage | null> {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
206
|
+
try {
|
|
207
|
+
const data = await callMcpHandler<Record<string, unknown> | null>(
|
|
208
|
+
"task.poll_and_claim",
|
|
209
|
+
{ session_id: sessionId },
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
if (!data) return null;
|
|
278
213
|
|
|
279
|
-
|
|
280
|
-
|
|
214
|
+
return {
|
|
215
|
+
...data,
|
|
216
|
+
prompt:
|
|
217
|
+
(data.metadata as Record<string, unknown>)?.prompt || data.content || "",
|
|
218
|
+
} as ConversationMessage;
|
|
219
|
+
} catch (err) {
|
|
220
|
+
log.warn(`Poll-and-claim failed: ${err instanceof Error ? err.message : err}`);
|
|
281
221
|
return null;
|
|
282
222
|
}
|
|
283
|
-
|
|
284
|
-
if (!data) return null;
|
|
285
|
-
|
|
286
|
-
const row = data as Record<string, unknown>;
|
|
287
|
-
return {
|
|
288
|
-
...row,
|
|
289
|
-
prompt:
|
|
290
|
-
(row.metadata as Record<string, unknown>)?.prompt || row.content || "",
|
|
291
|
-
} as ConversationMessage;
|
|
292
223
|
}
|
|
293
224
|
|
|
294
225
|
export async function claimTask(messageId: string): Promise<boolean> {
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
p_token_hash: getTokenHash(),
|
|
298
|
-
p_message_id: messageId,
|
|
226
|
+
const data = await callMcpHandler<boolean>("task.claim", {
|
|
227
|
+
message_id: messageId,
|
|
299
228
|
});
|
|
300
|
-
|
|
301
|
-
return data as boolean;
|
|
229
|
+
return data;
|
|
302
230
|
}
|
|
303
231
|
|
|
304
232
|
export async function completeTask(
|
|
@@ -306,27 +234,25 @@ export async function completeTask(
|
|
|
306
234
|
resultSummary: string,
|
|
307
235
|
tokenUsage?: Record<string, number>
|
|
308
236
|
): Promise<void> {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
p_result: resultSummary,
|
|
314
|
-
p_token_usage: tokenUsage || null,
|
|
237
|
+
await callMcpHandler("task.complete", {
|
|
238
|
+
message_id: messageId,
|
|
239
|
+
result: resultSummary,
|
|
240
|
+
token_usage: tokenUsage || null,
|
|
315
241
|
});
|
|
316
|
-
if (error) throw new Error(`Failed to complete task: ${error.message}`);
|
|
317
242
|
}
|
|
318
243
|
|
|
319
244
|
export async function failTask(
|
|
320
245
|
messageId: string,
|
|
321
246
|
errorMessage: string
|
|
322
247
|
): Promise<void> {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
})
|
|
329
|
-
|
|
248
|
+
try {
|
|
249
|
+
await callMcpHandler("task.fail", {
|
|
250
|
+
message_id: messageId,
|
|
251
|
+
error: errorMessage,
|
|
252
|
+
});
|
|
253
|
+
} catch (err) {
|
|
254
|
+
log.error(`Failed to update task status: ${err instanceof Error ? err.message : err}`);
|
|
255
|
+
}
|
|
330
256
|
}
|
|
331
257
|
|
|
332
258
|
// ── Job Run Polling ─────────────────────────────────────────────────
|
|
@@ -344,20 +270,17 @@ export interface PendingJobRun {
|
|
|
344
270
|
* Returns null if no pending job run exists.
|
|
345
271
|
*/
|
|
346
272
|
export async function pollAndClaimJobRun(
|
|
347
|
-
|
|
273
|
+
_userId: string
|
|
348
274
|
): Promise<PendingJobRun | null> {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
log.debug(`Job run poll failed: ${
|
|
275
|
+
try {
|
|
276
|
+
const data = await callMcpHandler<PendingJobRun | null>(
|
|
277
|
+
"job.claim_pending_run",
|
|
278
|
+
);
|
|
279
|
+
return data;
|
|
280
|
+
} catch (err) {
|
|
281
|
+
log.debug(`Job run poll failed: ${err instanceof Error ? err.message : err}`);
|
|
356
282
|
return null;
|
|
357
283
|
}
|
|
358
|
-
|
|
359
|
-
if (!data) return null;
|
|
360
|
-
return data as PendingJobRun;
|
|
361
284
|
}
|
|
362
285
|
|
|
363
286
|
// ── Conversation History ─────────────────────────────────────────────
|
|
@@ -376,37 +299,33 @@ export async function getConversationHistory(
|
|
|
376
299
|
excludeMessageId: string,
|
|
377
300
|
limit: number = 20
|
|
378
301
|
): Promise<HistoryEntry[]> {
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
302
|
+
try {
|
|
303
|
+
const rows = await callMcpHandler<Array<Record<string, unknown>>>(
|
|
304
|
+
"conversation.get_history",
|
|
305
|
+
{
|
|
306
|
+
conversation_id: conversationId,
|
|
307
|
+
exclude_message_id: excludeMessageId,
|
|
308
|
+
limit,
|
|
309
|
+
},
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
return (rows || [])
|
|
313
|
+
.reverse() // chronological order (oldest first)
|
|
314
|
+
.map((row) => {
|
|
315
|
+
const prompt =
|
|
316
|
+
((row.metadata as Record<string, unknown>)?.prompt as string) || "";
|
|
317
|
+
const content = (row.content as string) || "";
|
|
318
|
+
const response =
|
|
319
|
+
row.status === "failed"
|
|
320
|
+
? `[Task failed] ${content}`
|
|
321
|
+
: content;
|
|
322
|
+
return { prompt, response };
|
|
323
|
+
})
|
|
324
|
+
.filter((entry) => entry.prompt && entry.response);
|
|
325
|
+
} catch (err) {
|
|
326
|
+
log.debug(`Failed to fetch conversation history: ${err instanceof Error ? err.message : err}`);
|
|
392
327
|
return [];
|
|
393
328
|
}
|
|
394
|
-
|
|
395
|
-
const rows = (data || []) as Array<Record<string, unknown>>;
|
|
396
|
-
|
|
397
|
-
return rows
|
|
398
|
-
.reverse() // chronological order (oldest first)
|
|
399
|
-
.map((row) => {
|
|
400
|
-
const prompt =
|
|
401
|
-
((row.metadata as Record<string, unknown>)?.prompt as string) || "";
|
|
402
|
-
const content = (row.content as string) || "";
|
|
403
|
-
const response =
|
|
404
|
-
row.status === "failed"
|
|
405
|
-
? `[Task failed] ${content}`
|
|
406
|
-
: content;
|
|
407
|
-
return { prompt, response };
|
|
408
|
-
})
|
|
409
|
-
.filter((entry) => entry.prompt && entry.response);
|
|
410
329
|
}
|
|
411
330
|
|
|
412
331
|
// ── Event Streaming ─────────────────────────────────────────────────
|
|
@@ -432,33 +351,17 @@ export async function emitEvent(
|
|
|
432
351
|
eventType: EventType,
|
|
433
352
|
eventData: Record<string, unknown>
|
|
434
353
|
): Promise<void> {
|
|
435
|
-
const sb = getSupabase();
|
|
436
354
|
eventSequence++;
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
export async function emitEvents(
|
|
448
|
-
messageId: string,
|
|
449
|
-
events: Array<{ type: EventType; data: Record<string, unknown> }>
|
|
450
|
-
): Promise<void> {
|
|
451
|
-
const sb = getSupabase();
|
|
452
|
-
const eventsJson = events.map((e) => {
|
|
453
|
-
eventSequence++;
|
|
454
|
-
return { type: e.type, data: e.data, seq: eventSequence };
|
|
455
|
-
});
|
|
456
|
-
const { error } = await sb.rpc("mcp_emit_events", {
|
|
457
|
-
p_token_hash: getTokenHash(),
|
|
458
|
-
p_message_id: messageId,
|
|
459
|
-
p_events: eventsJson,
|
|
460
|
-
});
|
|
461
|
-
if (error) log.warn(`Failed to emit events batch: ${error.message}`);
|
|
355
|
+
try {
|
|
356
|
+
await callMcpHandler("event.emit", {
|
|
357
|
+
message_id: messageId,
|
|
358
|
+
event_type: eventType,
|
|
359
|
+
event_data: eventData,
|
|
360
|
+
seq: eventSequence,
|
|
361
|
+
});
|
|
362
|
+
} catch (err) {
|
|
363
|
+
log.warn(`Failed to emit event: ${err instanceof Error ? err.message : err}`);
|
|
364
|
+
}
|
|
462
365
|
}
|
|
463
366
|
|
|
464
367
|
// ── Action Request Helpers ──────────────────────────────────────────
|
|
@@ -467,23 +370,17 @@ export async function setActionRequest(
|
|
|
467
370
|
messageId: string,
|
|
468
371
|
actionData: Record<string, unknown>
|
|
469
372
|
): Promise<void> {
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
p_message_id: messageId,
|
|
474
|
-
p_action_data: actionData,
|
|
373
|
+
await callMcpHandler("action.set_request", {
|
|
374
|
+
message_id: messageId,
|
|
375
|
+
action_data: actionData,
|
|
475
376
|
});
|
|
476
|
-
if (error) throw new Error(`Failed to set action request: ${error.message}`);
|
|
477
377
|
}
|
|
478
378
|
|
|
479
379
|
export async function pollActionResponse(
|
|
480
380
|
messageId: string
|
|
481
381
|
): Promise<Record<string, unknown> | null> {
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
});
|
|
487
|
-
if (error) throw new Error(`Failed to poll action response: ${error.message}`);
|
|
488
|
-
return data as Record<string, unknown> | null;
|
|
382
|
+
return callMcpHandler<Record<string, unknown> | null>(
|
|
383
|
+
"action.poll_response",
|
|
384
|
+
{ message_id: messageId },
|
|
385
|
+
);
|
|
489
386
|
}
|