@agentwonderland/mcp 0.1.13 → 0.1.15
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/core/formatters.d.ts +1 -0
- package/dist/core/formatters.js +3 -0
- package/dist/tools/run.js +58 -2
- package/dist/tools/solve.js +61 -1
- package/package.json +1 -1
- package/src/core/formatters.ts +4 -0
- package/src/tools/run.ts +81 -2
- package/src/tools/solve.ts +77 -0
package/dist/core/formatters.js
CHANGED
|
@@ -116,6 +116,9 @@ export function formatRunResult(result, opts) {
|
|
|
116
116
|
const latency = result.latency_ms != null ? `${result.latency_ms}ms` : "";
|
|
117
117
|
const method = opts?.paymentMethod ?? "";
|
|
118
118
|
lines.push(`${status} ${agent}${latency ? ` (${latency})` : ""}`);
|
|
119
|
+
if (result.error_code) {
|
|
120
|
+
lines.push(`Error: ${result.error_code}`);
|
|
121
|
+
}
|
|
119
122
|
if (costStr) {
|
|
120
123
|
lines.push(`Paid: ${costStr}${method ? ` via ${method}` : ""}`);
|
|
121
124
|
}
|
package/dist/tools/run.js
CHANGED
|
@@ -1,10 +1,34 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { apiGet, apiPost, apiPostWithPayment } from "../core/api-client.js";
|
|
3
3
|
import { uploadLocalFiles } from "../core/file-upload.js";
|
|
4
|
-
import { getConfiguredMethods, hasWalletConfigured } from "../core/payments.js";
|
|
4
|
+
import { getConfiguredMethods, hasWalletConfigured, getWalletAddress } from "../core/payments.js";
|
|
5
5
|
import { requiresSpendConfirmation, getDefaultTipAmount } from "../core/config.js";
|
|
6
6
|
import { formatRunResult } from "../core/formatters.js";
|
|
7
7
|
import { storeFeedbackToken } from "./_token-cache.js";
|
|
8
|
+
const POLL_INTERVAL_MS = 3000;
|
|
9
|
+
const POLL_MAX_MS = 120000; // 2 minutes
|
|
10
|
+
async function pollJobUntilDone(jobId, agentName) {
|
|
11
|
+
const deadline = Date.now() + POLL_MAX_MS;
|
|
12
|
+
const walletAddress = await getWalletAddress();
|
|
13
|
+
const walletParam = walletAddress ? `?wallet=${walletAddress}` : "";
|
|
14
|
+
while (Date.now() < deadline) {
|
|
15
|
+
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
|
|
16
|
+
try {
|
|
17
|
+
const job = await apiGet(`/jobs/${jobId}${walletParam}`);
|
|
18
|
+
if (job.status === "completed") {
|
|
19
|
+
return { status: "completed", output: job.output };
|
|
20
|
+
}
|
|
21
|
+
if (job.status === "failed") {
|
|
22
|
+
return { status: "failed", output: job.output, error_code: job.error_code };
|
|
23
|
+
}
|
|
24
|
+
// Still processing — continue polling
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// Ignore poll errors, keep trying until deadline
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return { status: "failed", error_code: "POLL_TIMEOUT" };
|
|
31
|
+
}
|
|
8
32
|
function text(t) {
|
|
9
33
|
return { content: [{ type: "text", text: t }] };
|
|
10
34
|
}
|
|
@@ -62,7 +86,7 @@ export function registerRunTools(server) {
|
|
|
62
86
|
processedInput = uploadResult.input;
|
|
63
87
|
if (uploadResult.uploads.length > 0) {
|
|
64
88
|
uploadSummary = uploadResult.uploads
|
|
65
|
-
.map((u) => `Uploaded ${u.field}: ${u.originalPath} → ${u.url
|
|
89
|
+
.map((u) => `Uploaded ${u.field}: ${u.originalPath} → ${u.url}`)
|
|
66
90
|
.join("\n");
|
|
67
91
|
}
|
|
68
92
|
}
|
|
@@ -99,6 +123,38 @@ export function registerRunTools(server) {
|
|
|
99
123
|
}
|
|
100
124
|
const actualCost = result.cost;
|
|
101
125
|
const status = result.status;
|
|
126
|
+
// Async agent — poll until complete
|
|
127
|
+
if (status === "processing") {
|
|
128
|
+
const pollResult = await pollJobUntilDone(jobId, agentName);
|
|
129
|
+
if (pollResult.status === "completed") {
|
|
130
|
+
const asyncFormatted = formatRunResult({
|
|
131
|
+
...result,
|
|
132
|
+
status: "success",
|
|
133
|
+
output: pollResult.output,
|
|
134
|
+
}, { paymentMethod: method ?? getConfiguredMethods()[0] });
|
|
135
|
+
if (result.feedback_token) {
|
|
136
|
+
storeFeedbackToken(jobId, result.feedback_token, resultAgentId);
|
|
137
|
+
}
|
|
138
|
+
const asyncCostLine = actualCost != null ? `Paid $${actualCost.toFixed(actualCost < 0.01 ? 4 : 2)}.` : "";
|
|
139
|
+
const asyncFeedbackAsk = [
|
|
140
|
+
`IMPORTANT: After presenting the result above, you MUST ask the user:`,
|
|
141
|
+
`"${asyncCostLine} Was this result helpful? I can rate it (1-5 stars) or tip the builder for you."`,
|
|
142
|
+
"",
|
|
143
|
+
`If the user wants to rate: rate_agent({ job_id: "${jobId}", rating: <1-5>, comment: "..." })`,
|
|
144
|
+
`If the user wants to tip: tip_agent({ job_id: "${jobId}", agent_id: "${resultAgentId}", amount: 0.25 })`,
|
|
145
|
+
`To save for later: favorite_agent({ agent_id: "${resultAgentId}" })`,
|
|
146
|
+
].join("\n");
|
|
147
|
+
return multiText(uploadSummary ? `${uploadSummary}\n\n${asyncFormatted}` : asyncFormatted, asyncFeedbackAsk);
|
|
148
|
+
}
|
|
149
|
+
// Async agent failed
|
|
150
|
+
const failedFormatted = formatRunResult({
|
|
151
|
+
...result,
|
|
152
|
+
status: "failed",
|
|
153
|
+
output: pollResult.output,
|
|
154
|
+
error_code: pollResult.error_code,
|
|
155
|
+
}, { paymentMethod: method ?? getConfiguredMethods()[0] });
|
|
156
|
+
return multiText(uploadSummary ? `${uploadSummary}\n\n${failedFormatted}` : failedFormatted, "The agent execution failed. A refund has been initiated automatically.");
|
|
157
|
+
}
|
|
102
158
|
// Auto-tip if configured and run succeeded
|
|
103
159
|
const defaultTip = getDefaultTipAmount();
|
|
104
160
|
let tipLine = "";
|
package/dist/tools/solve.js
CHANGED
|
@@ -1,10 +1,33 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { apiGet, apiPost, apiPostWithPayment } from "../core/api-client.js";
|
|
3
|
-
import { hasWalletConfigured, getConfiguredMethods, getAcceptedPaymentMethods, } from "../core/payments.js";
|
|
3
|
+
import { hasWalletConfigured, getConfiguredMethods, getAcceptedPaymentMethods, getWalletAddress, } from "../core/payments.js";
|
|
4
4
|
import { requiresSpendConfirmation, getDefaultTipAmount } from "../core/config.js";
|
|
5
5
|
import { agentList, formatRunResult } from "../core/formatters.js";
|
|
6
6
|
import { uploadLocalFiles } from "../core/file-upload.js";
|
|
7
7
|
import { storeFeedbackToken } from "./_token-cache.js";
|
|
8
|
+
const POLL_INTERVAL_MS = 3000;
|
|
9
|
+
const POLL_MAX_MS = 120000;
|
|
10
|
+
async function pollSolveJob(jobId) {
|
|
11
|
+
const deadline = Date.now() + POLL_MAX_MS;
|
|
12
|
+
const walletAddress = await getWalletAddress();
|
|
13
|
+
const walletParam = walletAddress ? `?wallet=${walletAddress}` : "";
|
|
14
|
+
while (Date.now() < deadline) {
|
|
15
|
+
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
|
|
16
|
+
try {
|
|
17
|
+
const job = await apiGet(`/jobs/${jobId}${walletParam}`);
|
|
18
|
+
if (job.status === "completed") {
|
|
19
|
+
return { status: "completed", output: job.output };
|
|
20
|
+
}
|
|
21
|
+
if (job.status === "failed") {
|
|
22
|
+
return { status: "failed", output: job.output, error_code: job.error_code };
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// Ignore poll errors, keep trying
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return { status: "failed", error_code: "POLL_TIMEOUT" };
|
|
30
|
+
}
|
|
8
31
|
function text(t) {
|
|
9
32
|
return { content: [{ type: "text", text: t }] };
|
|
10
33
|
}
|
|
@@ -171,9 +194,46 @@ export function registerSolveTools(server) {
|
|
|
171
194
|
}
|
|
172
195
|
const jobId = result.job_id ?? "";
|
|
173
196
|
const agentId2 = result.agent_id ?? selected.id;
|
|
197
|
+
const status = result.status;
|
|
174
198
|
if (result.feedback_token) {
|
|
175
199
|
storeFeedbackToken(jobId, result.feedback_token, agentId2);
|
|
176
200
|
}
|
|
201
|
+
// Async agent — poll until complete
|
|
202
|
+
if (status === "processing") {
|
|
203
|
+
const pollResult = await pollSolveJob(jobId);
|
|
204
|
+
if (pollResult.status === "completed") {
|
|
205
|
+
const asyncFormatted = formatRunResult({
|
|
206
|
+
...result,
|
|
207
|
+
status: "success",
|
|
208
|
+
output: pollResult.output,
|
|
209
|
+
}, { paymentMethod: method });
|
|
210
|
+
const asyncOutput = [
|
|
211
|
+
discovery,
|
|
212
|
+
"",
|
|
213
|
+
`Running ${selected.name} — best match`,
|
|
214
|
+
`Estimated cost: $${estimatedCost.toFixed(4)}`,
|
|
215
|
+
"",
|
|
216
|
+
asyncFormatted,
|
|
217
|
+
].join("\n");
|
|
218
|
+
const asyncCost = result.cost;
|
|
219
|
+
return multiText(asyncOutput, feedbackAsk(jobId, agentId2, asyncCost, ""));
|
|
220
|
+
}
|
|
221
|
+
// Async agent failed
|
|
222
|
+
const failedFormatted = formatRunResult({
|
|
223
|
+
...result,
|
|
224
|
+
status: "failed",
|
|
225
|
+
output: pollResult.output,
|
|
226
|
+
error_code: pollResult.error_code,
|
|
227
|
+
}, { paymentMethod: method });
|
|
228
|
+
const failedOutput = [
|
|
229
|
+
discovery,
|
|
230
|
+
"",
|
|
231
|
+
`Running ${selected.name} — best match`,
|
|
232
|
+
"",
|
|
233
|
+
failedFormatted,
|
|
234
|
+
].join("\n");
|
|
235
|
+
return multiText(failedOutput, "The agent execution failed. A refund has been initiated automatically.");
|
|
236
|
+
}
|
|
177
237
|
const actualCost = result.cost;
|
|
178
238
|
const tipMsg = result.feedback_token ? await autoTip(jobId, agentId2, selected.name ?? "", result.feedback_token) : "";
|
|
179
239
|
const output = [
|
package/package.json
CHANGED
package/src/core/formatters.ts
CHANGED
|
@@ -111,6 +111,7 @@ interface RunResultLike {
|
|
|
111
111
|
agent_id?: string;
|
|
112
112
|
agent_name?: string;
|
|
113
113
|
output?: unknown;
|
|
114
|
+
error_code?: string;
|
|
114
115
|
latency_ms?: number;
|
|
115
116
|
execution_latency_ms?: number;
|
|
116
117
|
cost?: number;
|
|
@@ -153,6 +154,9 @@ export function formatRunResult(result: RunResultLike, opts?: { paymentMethod?:
|
|
|
153
154
|
const method = opts?.paymentMethod ?? "";
|
|
154
155
|
|
|
155
156
|
lines.push(`${status} ${agent}${latency ? ` (${latency})` : ""}`);
|
|
157
|
+
if (result.error_code) {
|
|
158
|
+
lines.push(`Error: ${result.error_code}`);
|
|
159
|
+
}
|
|
156
160
|
if (costStr) {
|
|
157
161
|
lines.push(`Paid: ${costStr}${method ? ` via ${method}` : ""}`);
|
|
158
162
|
}
|
package/src/tools/run.ts
CHANGED
|
@@ -2,11 +2,46 @@ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { apiGet, apiPost, apiPostWithPayment } from "../core/api-client.js";
|
|
4
4
|
import { uploadLocalFiles } from "../core/file-upload.js";
|
|
5
|
-
import { getConfiguredMethods, hasWalletConfigured } from "../core/payments.js";
|
|
5
|
+
import { getConfiguredMethods, hasWalletConfigured, getWalletAddress } from "../core/payments.js";
|
|
6
6
|
import { requiresSpendConfirmation, getDefaultTipAmount } from "../core/config.js";
|
|
7
7
|
import { formatRunResult } from "../core/formatters.js";
|
|
8
8
|
import { storeFeedbackToken, getFeedbackToken } from "./_token-cache.js";
|
|
9
9
|
|
|
10
|
+
const POLL_INTERVAL_MS = 3000;
|
|
11
|
+
const POLL_MAX_MS = 120000; // 2 minutes
|
|
12
|
+
|
|
13
|
+
async function pollJobUntilDone(
|
|
14
|
+
jobId: string,
|
|
15
|
+
agentName: string,
|
|
16
|
+
): Promise<{ status: string; output?: unknown; error_code?: string }> {
|
|
17
|
+
const deadline = Date.now() + POLL_MAX_MS;
|
|
18
|
+
const walletAddress = await getWalletAddress();
|
|
19
|
+
const walletParam = walletAddress ? `?wallet=${walletAddress}` : "";
|
|
20
|
+
|
|
21
|
+
while (Date.now() < deadline) {
|
|
22
|
+
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
|
|
23
|
+
try {
|
|
24
|
+
const job = await apiGet<{
|
|
25
|
+
status: string;
|
|
26
|
+
output?: unknown;
|
|
27
|
+
error_code?: string;
|
|
28
|
+
}>(`/jobs/${jobId}${walletParam}`);
|
|
29
|
+
|
|
30
|
+
if (job.status === "completed") {
|
|
31
|
+
return { status: "completed", output: job.output };
|
|
32
|
+
}
|
|
33
|
+
if (job.status === "failed") {
|
|
34
|
+
return { status: "failed", output: job.output, error_code: job.error_code };
|
|
35
|
+
}
|
|
36
|
+
// Still processing — continue polling
|
|
37
|
+
} catch {
|
|
38
|
+
// Ignore poll errors, keep trying until deadline
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return { status: "failed", error_code: "POLL_TIMEOUT" };
|
|
43
|
+
}
|
|
44
|
+
|
|
10
45
|
function text(t: string) {
|
|
11
46
|
return { content: [{ type: "text" as const, text: t }] };
|
|
12
47
|
}
|
|
@@ -81,7 +116,7 @@ export function registerRunTools(server: McpServer): void {
|
|
|
81
116
|
processedInput = uploadResult.input;
|
|
82
117
|
if (uploadResult.uploads.length > 0) {
|
|
83
118
|
uploadSummary = uploadResult.uploads
|
|
84
|
-
.map((u) => `Uploaded ${u.field}: ${u.originalPath} → ${u.url
|
|
119
|
+
.map((u) => `Uploaded ${u.field}: ${u.originalPath} → ${u.url}`)
|
|
85
120
|
.join("\n");
|
|
86
121
|
}
|
|
87
122
|
} catch (err) {
|
|
@@ -127,6 +162,50 @@ export function registerRunTools(server: McpServer): void {
|
|
|
127
162
|
const actualCost = result.cost as number | undefined;
|
|
128
163
|
const status = result.status as string;
|
|
129
164
|
|
|
165
|
+
// Async agent — poll until complete
|
|
166
|
+
if (status === "processing") {
|
|
167
|
+
const pollResult = await pollJobUntilDone(jobId, agentName);
|
|
168
|
+
if (pollResult.status === "completed") {
|
|
169
|
+
const asyncFormatted = formatRunResult({
|
|
170
|
+
...result,
|
|
171
|
+
status: "success",
|
|
172
|
+
output: pollResult.output,
|
|
173
|
+
}, { paymentMethod: method ?? getConfiguredMethods()[0] });
|
|
174
|
+
|
|
175
|
+
if (result.feedback_token) {
|
|
176
|
+
storeFeedbackToken(jobId, result.feedback_token as string, resultAgentId);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const asyncCostLine = actualCost != null ? `Paid $${actualCost.toFixed(actualCost < 0.01 ? 4 : 2)}.` : "";
|
|
180
|
+
const asyncFeedbackAsk = [
|
|
181
|
+
`IMPORTANT: After presenting the result above, you MUST ask the user:`,
|
|
182
|
+
`"${asyncCostLine} Was this result helpful? I can rate it (1-5 stars) or tip the builder for you."`,
|
|
183
|
+
"",
|
|
184
|
+
`If the user wants to rate: rate_agent({ job_id: "${jobId}", rating: <1-5>, comment: "..." })`,
|
|
185
|
+
`If the user wants to tip: tip_agent({ job_id: "${jobId}", agent_id: "${resultAgentId}", amount: 0.25 })`,
|
|
186
|
+
`To save for later: favorite_agent({ agent_id: "${resultAgentId}" })`,
|
|
187
|
+
].join("\n");
|
|
188
|
+
|
|
189
|
+
return multiText(
|
|
190
|
+
uploadSummary ? `${uploadSummary}\n\n${asyncFormatted}` : asyncFormatted,
|
|
191
|
+
asyncFeedbackAsk,
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Async agent failed
|
|
196
|
+
const failedFormatted = formatRunResult({
|
|
197
|
+
...result,
|
|
198
|
+
status: "failed",
|
|
199
|
+
output: pollResult.output,
|
|
200
|
+
error_code: pollResult.error_code,
|
|
201
|
+
}, { paymentMethod: method ?? getConfiguredMethods()[0] });
|
|
202
|
+
|
|
203
|
+
return multiText(
|
|
204
|
+
uploadSummary ? `${uploadSummary}\n\n${failedFormatted}` : failedFormatted,
|
|
205
|
+
"The agent execution failed. A refund has been initiated automatically.",
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
130
209
|
// Auto-tip if configured and run succeeded
|
|
131
210
|
const defaultTip = getDefaultTipAmount();
|
|
132
211
|
let tipLine = "";
|
package/src/tools/solve.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
hasWalletConfigured,
|
|
6
6
|
getConfiguredMethods,
|
|
7
7
|
getAcceptedPaymentMethods,
|
|
8
|
+
getWalletAddress,
|
|
8
9
|
} from "../core/payments.js";
|
|
9
10
|
import { requiresSpendConfirmation, getDefaultTipAmount } from "../core/config.js";
|
|
10
11
|
import { agentList, formatRunResult } from "../core/formatters.js";
|
|
@@ -12,6 +13,39 @@ import { uploadLocalFiles } from "../core/file-upload.js";
|
|
|
12
13
|
import type { AgentRecord } from "../core/types.js";
|
|
13
14
|
import { storeFeedbackToken } from "./_token-cache.js";
|
|
14
15
|
|
|
16
|
+
const POLL_INTERVAL_MS = 3000;
|
|
17
|
+
const POLL_MAX_MS = 120000;
|
|
18
|
+
|
|
19
|
+
async function pollSolveJob(
|
|
20
|
+
jobId: string,
|
|
21
|
+
): Promise<{ status: string; output?: unknown; error_code?: string }> {
|
|
22
|
+
const deadline = Date.now() + POLL_MAX_MS;
|
|
23
|
+
const walletAddress = await getWalletAddress();
|
|
24
|
+
const walletParam = walletAddress ? `?wallet=${walletAddress}` : "";
|
|
25
|
+
|
|
26
|
+
while (Date.now() < deadline) {
|
|
27
|
+
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
|
|
28
|
+
try {
|
|
29
|
+
const job = await apiGet<{
|
|
30
|
+
status: string;
|
|
31
|
+
output?: unknown;
|
|
32
|
+
error_code?: string;
|
|
33
|
+
}>(`/jobs/${jobId}${walletParam}`);
|
|
34
|
+
|
|
35
|
+
if (job.status === "completed") {
|
|
36
|
+
return { status: "completed", output: job.output };
|
|
37
|
+
}
|
|
38
|
+
if (job.status === "failed") {
|
|
39
|
+
return { status: "failed", output: job.output, error_code: job.error_code };
|
|
40
|
+
}
|
|
41
|
+
} catch {
|
|
42
|
+
// Ignore poll errors, keep trying
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return { status: "failed", error_code: "POLL_TIMEOUT" };
|
|
47
|
+
}
|
|
48
|
+
|
|
15
49
|
function text(t: string) {
|
|
16
50
|
return { content: [{ type: "text" as const, text: t }] };
|
|
17
51
|
}
|
|
@@ -204,11 +238,54 @@ export function registerSolveTools(server: McpServer): void {
|
|
|
204
238
|
|
|
205
239
|
const jobId = (result as Record<string, unknown>).job_id as string ?? "";
|
|
206
240
|
const agentId2 = (result as Record<string, unknown>).agent_id as string ?? selected.id;
|
|
241
|
+
const status = result.status as string;
|
|
207
242
|
|
|
208
243
|
if (result.feedback_token) {
|
|
209
244
|
storeFeedbackToken(jobId, result.feedback_token as string, agentId2);
|
|
210
245
|
}
|
|
211
246
|
|
|
247
|
+
// Async agent — poll until complete
|
|
248
|
+
if (status === "processing") {
|
|
249
|
+
const pollResult = await pollSolveJob(jobId);
|
|
250
|
+
if (pollResult.status === "completed") {
|
|
251
|
+
const asyncFormatted = formatRunResult({
|
|
252
|
+
...result,
|
|
253
|
+
status: "success",
|
|
254
|
+
output: pollResult.output,
|
|
255
|
+
}, { paymentMethod: method });
|
|
256
|
+
|
|
257
|
+
const asyncOutput = [
|
|
258
|
+
discovery,
|
|
259
|
+
"",
|
|
260
|
+
`Running ${selected.name} — best match`,
|
|
261
|
+
`Estimated cost: $${estimatedCost.toFixed(4)}`,
|
|
262
|
+
"",
|
|
263
|
+
asyncFormatted,
|
|
264
|
+
].join("\n");
|
|
265
|
+
|
|
266
|
+
const asyncCost = (result as Record<string, unknown>).cost as number | undefined;
|
|
267
|
+
return multiText(asyncOutput, feedbackAsk(jobId, agentId2, asyncCost, ""));
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Async agent failed
|
|
271
|
+
const failedFormatted = formatRunResult({
|
|
272
|
+
...result,
|
|
273
|
+
status: "failed",
|
|
274
|
+
output: pollResult.output,
|
|
275
|
+
error_code: pollResult.error_code,
|
|
276
|
+
}, { paymentMethod: method });
|
|
277
|
+
|
|
278
|
+
const failedOutput = [
|
|
279
|
+
discovery,
|
|
280
|
+
"",
|
|
281
|
+
`Running ${selected.name} — best match`,
|
|
282
|
+
"",
|
|
283
|
+
failedFormatted,
|
|
284
|
+
].join("\n");
|
|
285
|
+
|
|
286
|
+
return multiText(failedOutput, "The agent execution failed. A refund has been initiated automatically.");
|
|
287
|
+
}
|
|
288
|
+
|
|
212
289
|
const actualCost = (result as Record<string, unknown>).cost as number | undefined;
|
|
213
290
|
const tipMsg = result.feedback_token ? await autoTip(jobId, agentId2, selected.name ?? "", result.feedback_token as string) : "";
|
|
214
291
|
|