@agentwonderland/mcp 0.1.22 → 0.1.24
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/__tests__/card-setup.test.d.ts +1 -0
- package/dist/core/__tests__/card-setup.test.js +99 -0
- package/dist/core/__tests__/formatters.test.d.ts +1 -0
- package/dist/core/__tests__/formatters.test.js +15 -0
- package/dist/core/__tests__/passes.test.d.ts +1 -0
- package/dist/core/__tests__/passes.test.js +82 -0
- package/dist/core/__tests__/payments.test.d.ts +1 -0
- package/dist/core/__tests__/payments.test.js +52 -0
- package/dist/core/__tests__/principal.test.d.ts +1 -0
- package/dist/core/__tests__/principal.test.js +67 -0
- package/dist/core/api-client.d.ts +9 -4
- package/dist/core/api-client.js +52 -22
- package/dist/core/card-setup.d.ts +20 -13
- package/dist/core/card-setup.js +87 -30
- package/dist/core/config.d.ts +4 -0
- package/dist/core/config.js +28 -1
- package/dist/core/formatters.d.ts +2 -0
- package/dist/core/formatters.js +5 -1
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.js +2 -0
- package/dist/core/ows-adapter.d.ts +10 -2
- package/dist/core/ows-adapter.js +54 -10
- package/dist/core/passes.d.ts +40 -0
- package/dist/core/passes.js +32 -0
- package/dist/core/payments.d.ts +8 -0
- package/dist/core/payments.js +121 -16
- package/dist/core/principal.d.ts +2 -0
- package/dist/core/principal.js +109 -0
- package/dist/core/solana-charge.d.ts +9 -0
- package/dist/core/solana-charge.js +95 -0
- package/dist/core/types.d.ts +10 -0
- package/dist/index.js +13 -4
- package/dist/prompts/index.js +1 -1
- package/dist/resources/wallet.js +8 -1
- package/dist/tools/__tests__/_payment-confirmation.test.d.ts +1 -0
- package/dist/tools/__tests__/_payment-confirmation.test.js +30 -0
- package/dist/tools/_payment-confirmation.d.ts +6 -0
- package/dist/tools/_payment-confirmation.js +28 -0
- package/dist/tools/agent-info.js +14 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.js +1 -0
- package/dist/tools/passes.d.ts +2 -0
- package/dist/tools/passes.js +157 -0
- package/dist/tools/run.js +116 -49
- package/dist/tools/solve.js +102 -44
- package/dist/tools/wallet.js +85 -50
- package/package.json +3 -1
- package/src/core/__tests__/card-setup.test.ts +118 -0
- package/src/core/__tests__/formatters.test.ts +17 -0
- package/src/core/__tests__/passes.test.ts +94 -0
- package/src/core/__tests__/payments.test.ts +60 -0
- package/src/core/__tests__/principal.test.ts +87 -0
- package/src/core/api-client.ts +70 -23
- package/src/core/card-setup.ts +112 -35
- package/src/core/config.ts +33 -2
- package/src/core/formatters.ts +7 -1
- package/src/core/index.ts +2 -0
- package/src/core/ows-adapter.ts +74 -8
- package/src/core/passes.ts +74 -0
- package/src/core/payments.ts +140 -15
- package/src/core/principal.ts +128 -0
- package/src/core/solana-charge.ts +149 -0
- package/src/core/types.ts +10 -0
- package/src/index.ts +13 -4
- package/src/prompts/index.ts +1 -1
- package/src/resources/wallet.ts +8 -1
- package/src/tools/__tests__/_payment-confirmation.test.ts +45 -0
- package/src/tools/_payment-confirmation.ts +52 -0
- package/src/tools/agent-info.ts +23 -0
- package/src/tools/index.ts +1 -0
- package/src/tools/passes.ts +234 -0
- package/src/tools/run.ts +174 -53
- package/src/tools/solve.ts +149 -56
- package/src/tools/wallet.ts +102 -52
package/src/tools/run.ts
CHANGED
|
@@ -2,18 +2,36 @@ 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 {
|
|
5
|
+
import {
|
|
6
|
+
formatCreditPackOffer,
|
|
7
|
+
getActiveCreditPack,
|
|
8
|
+
getCreditPackInventory,
|
|
9
|
+
getCreditPackProgram,
|
|
10
|
+
} from "../core/passes.js";
|
|
11
|
+
import {
|
|
12
|
+
getCompatiblePaymentMethods,
|
|
13
|
+
getConfiguredMethods,
|
|
14
|
+
hasWalletConfigured,
|
|
15
|
+
getWalletAddress,
|
|
16
|
+
normalizePaymentMethod,
|
|
17
|
+
} from "../core/payments.js";
|
|
6
18
|
import { requiresSpendConfirmation, getDefaultTipAmount } from "../core/config.js";
|
|
7
19
|
import { formatRunResult } from "../core/formatters.js";
|
|
8
|
-
import { storeFeedbackToken
|
|
9
|
-
import {
|
|
20
|
+
import { storeFeedbackToken } from "./_token-cache.js";
|
|
21
|
+
import { getOrCreatePendingCardSetup, formatCardSetupBlocks } from "../core/card-setup.js";
|
|
22
|
+
import {
|
|
23
|
+
formatPaymentChoicePrompt,
|
|
24
|
+
formatPaymentLabel,
|
|
25
|
+
formatRunConfirmationCommand,
|
|
26
|
+
resolveConfirmationMethod,
|
|
27
|
+
} from "./_payment-confirmation.js";
|
|
28
|
+
import type { AgentRecord } from "../core/types.js";
|
|
10
29
|
|
|
11
30
|
const POLL_INTERVAL_MS = 3000;
|
|
12
|
-
const POLL_MAX_MS = 120000;
|
|
31
|
+
const POLL_MAX_MS = 120000;
|
|
13
32
|
|
|
14
33
|
async function pollJobUntilDone(
|
|
15
34
|
jobId: string,
|
|
16
|
-
agentName: string,
|
|
17
35
|
): Promise<{ status: string; output?: unknown; error_code?: string }> {
|
|
18
36
|
const deadline = Date.now() + POLL_MAX_MS;
|
|
19
37
|
const walletAddress = await getWalletAddress();
|
|
@@ -34,9 +52,8 @@ async function pollJobUntilDone(
|
|
|
34
52
|
if (job.status === "failed") {
|
|
35
53
|
return { status: "failed", output: job.output, error_code: job.error_code };
|
|
36
54
|
}
|
|
37
|
-
// Still processing — continue polling
|
|
38
55
|
} catch {
|
|
39
|
-
// Ignore poll errors
|
|
56
|
+
// Ignore poll errors until timeout.
|
|
40
57
|
}
|
|
41
58
|
}
|
|
42
59
|
|
|
@@ -51,17 +68,35 @@ function multiText(...blocks: string[]) {
|
|
|
51
68
|
return { content: blocks.map((t) => ({ type: "text" as const, text: t })) };
|
|
52
69
|
}
|
|
53
70
|
|
|
54
|
-
// Pending confirmations: agent_id → { agent, input, method }
|
|
55
71
|
const pendingRuns = new Map<string, {
|
|
56
72
|
agent: { id: string; name: string; price: number };
|
|
57
73
|
input: Record<string, unknown>;
|
|
58
74
|
method?: string;
|
|
59
75
|
}>();
|
|
60
76
|
|
|
77
|
+
function buildCreditPackOfferLines(agent: AgentRecord): string[] {
|
|
78
|
+
const program = getCreditPackProgram(agent);
|
|
79
|
+
if (!program?.packs?.length) return [];
|
|
80
|
+
|
|
81
|
+
return [
|
|
82
|
+
"Discounted credit packs:",
|
|
83
|
+
...program.packs.map((pack) => formatCreditPackOffer({
|
|
84
|
+
pack_id: pack.key ?? "",
|
|
85
|
+
label: pack.name ?? pack.key ?? "Credit Pack",
|
|
86
|
+
included_units: pack.included_units ?? 0,
|
|
87
|
+
price_usd: pack.price_usd ?? "0.00",
|
|
88
|
+
effective_price_per_unit_usd: (pack.included_units ?? 0) > 0 && pack.price_usd
|
|
89
|
+
? (Number(pack.price_usd) / (pack.included_units ?? 1)).toFixed(6)
|
|
90
|
+
: undefined,
|
|
91
|
+
})).map((line) => ` ${line}`),
|
|
92
|
+
` Buy one with buy_agent_credit_pack({ agent_id: "${agent.id}", pack_id: "<pack_id>" })`,
|
|
93
|
+
];
|
|
94
|
+
}
|
|
95
|
+
|
|
61
96
|
export function registerRunTools(server: McpServer): void {
|
|
62
97
|
server.tool(
|
|
63
98
|
"run_agent",
|
|
64
|
-
"Run an AI agent from the marketplace. Pays automatically via configured wallet. Returns the agent's output, cost, and job ID for tracking. If spending confirmation is enabled, first call returns a price quote — call again with confirmed: true to execute. Local file paths in the input (e.g. /Users/.../photo.jpg) are automatically uploaded to temporary storage and replaced with download URLs
|
|
99
|
+
"Run an AI agent from the marketplace. Pays automatically via configured wallet. Returns the agent's output, cost, and job ID for tracking. If spending confirmation is enabled, first call returns a price quote — call again with confirmed: true to execute. Local file paths in the input (e.g. /Users/.../photo.jpg) are automatically uploaded to temporary storage and replaced with download URLs before execution.",
|
|
65
100
|
{
|
|
66
101
|
agent_id: z.string().describe("Agent ID (UUID, slug, or name)"),
|
|
67
102
|
input: z.record(z.unknown()).describe("Input payload for the agent"),
|
|
@@ -71,51 +106,102 @@ export function registerRunTools(server: McpServer): void {
|
|
|
71
106
|
async ({ agent_id, input, pay_with, confirmed }) => {
|
|
72
107
|
if (!hasWalletConfigured()) {
|
|
73
108
|
try {
|
|
74
|
-
const {
|
|
75
|
-
|
|
76
|
-
return multiText(...blocks);
|
|
109
|
+
const { url } = await getOrCreatePendingCardSetup();
|
|
110
|
+
return multiText(...formatCardSetupBlocks(url));
|
|
77
111
|
} catch {
|
|
78
112
|
return text(
|
|
79
113
|
"No payment method configured.\n\n" +
|
|
80
114
|
"To add a credit card: wallet_setup({ action: \"add-card\" })\n" +
|
|
81
|
-
"To use crypto: wallet_setup({ action: \"create\" })"
|
|
115
|
+
"To use crypto: wallet_setup({ action: \"create\" })",
|
|
82
116
|
);
|
|
83
117
|
}
|
|
84
118
|
}
|
|
85
119
|
|
|
86
|
-
|
|
87
|
-
let agent: { id: string; name?: string; pricePer1kTokens?: string; successRate?: number };
|
|
120
|
+
let agent: AgentRecord;
|
|
88
121
|
try {
|
|
89
|
-
agent = await apiGet<
|
|
122
|
+
agent = await apiGet<AgentRecord>(`/agents/${agent_id}`);
|
|
90
123
|
} catch {
|
|
91
124
|
return text(`Agent "${agent_id}" not found. Use search_agents to find available agents.`);
|
|
92
125
|
}
|
|
93
126
|
|
|
94
127
|
const price = parseFloat(agent.pricePer1kTokens ?? "0.01");
|
|
95
128
|
const agentName = agent.name ?? agent_id;
|
|
129
|
+
const creditPackInventory = await getCreditPackInventory(agent.id);
|
|
130
|
+
const activeCreditPack = getActiveCreditPack(creditPackInventory);
|
|
131
|
+
const configuredMethods = getConfiguredMethods();
|
|
132
|
+
const compatibleMethods = getCompatiblePaymentMethods(agent, configuredMethods);
|
|
133
|
+
const pending = pendingRuns.get(agent.id);
|
|
134
|
+
const requestedMethod = pay_with ?? pending?.method;
|
|
135
|
+
const normalizedRequestedMethod = requestedMethod ? normalizePaymentMethod(requestedMethod) : null;
|
|
136
|
+
|
|
137
|
+
if (!activeCreditPack && requestedMethod && !normalizedRequestedMethod) {
|
|
138
|
+
return text(
|
|
139
|
+
`Payment method "${requestedMethod}" is not configured.\n\n` +
|
|
140
|
+
"Use wallet_status to review your current payment methods.",
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (!activeCreditPack && normalizedRequestedMethod && !compatibleMethods.includes(normalizedRequestedMethod)) {
|
|
145
|
+
return text(
|
|
146
|
+
`This agent cannot be paid with "${requestedMethod}".\n\n` +
|
|
147
|
+
`Available payment methods for this agent: ${compatibleMethods.join(", ") || "none"}.\n` +
|
|
148
|
+
"Use get_agent to inspect the agent details or choose another payment method.",
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (!activeCreditPack && !requestedMethod && compatibleMethods.length === 0) {
|
|
153
|
+
return text(
|
|
154
|
+
`No compatible payment methods are configured for ${agentName}.\n\n` +
|
|
155
|
+
`Your configured methods: ${configuredMethods.join(", ") || "none"}\n` +
|
|
156
|
+
`Agent accepts: ${agent.payment?.accepted_payments?.join(", ") || "unknown"}\n` +
|
|
157
|
+
"Use wallet_status to review your current setup.",
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (!activeCreditPack && !requestedMethod && compatibleMethods.length > 1) {
|
|
162
|
+
return text(
|
|
163
|
+
formatPaymentChoicePrompt(
|
|
164
|
+
agentName,
|
|
165
|
+
compatibleMethods,
|
|
166
|
+
compatibleMethods.map((method) => formatRunConfirmationCommand(agent.id, method).replace(", confirmed: true", "")),
|
|
167
|
+
),
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const method = activeCreditPack
|
|
172
|
+
? undefined
|
|
173
|
+
: resolveConfirmationMethod(pay_with, pending?.method, compatibleMethods);
|
|
96
174
|
|
|
97
|
-
|
|
98
|
-
if (requiresSpendConfirmation() && !confirmed) {
|
|
175
|
+
if (!activeCreditPack && requiresSpendConfirmation() && !confirmed) {
|
|
99
176
|
pendingRuns.set(agent.id, {
|
|
100
177
|
agent: { id: agent.id, name: agentName, price },
|
|
101
178
|
input,
|
|
102
|
-
method
|
|
179
|
+
method,
|
|
103
180
|
});
|
|
104
181
|
|
|
105
|
-
|
|
182
|
+
const quoteLines = [
|
|
106
183
|
`Ready to run ${agentName}`,
|
|
107
184
|
"",
|
|
108
185
|
` Cost: $${price.toFixed(2)}`,
|
|
109
|
-
` Payment: ${
|
|
186
|
+
` Payment: ${formatPaymentLabel(method)}`,
|
|
187
|
+
];
|
|
188
|
+
|
|
189
|
+
const creditPackLines = buildCreditPackOfferLines(agent);
|
|
190
|
+
if (creditPackLines.length > 0) {
|
|
191
|
+
quoteLines.push("", ...creditPackLines);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
quoteLines.push(
|
|
110
195
|
"",
|
|
111
196
|
"To proceed, call:",
|
|
112
|
-
|
|
197
|
+
formatRunConfirmationCommand(agent.id, method),
|
|
113
198
|
"",
|
|
114
199
|
"To cancel, do nothing.",
|
|
115
|
-
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
return text(quoteLines.join("\n"));
|
|
116
203
|
}
|
|
117
204
|
|
|
118
|
-
const method = pay_with;
|
|
119
205
|
let processedInput: Record<string, unknown>;
|
|
120
206
|
let uploadSummary = "";
|
|
121
207
|
try {
|
|
@@ -123,27 +209,48 @@ export function registerRunTools(server: McpServer): void {
|
|
|
123
209
|
processedInput = uploadResult.input;
|
|
124
210
|
if (uploadResult.uploads.length > 0) {
|
|
125
211
|
uploadSummary = uploadResult.uploads
|
|
126
|
-
.map((
|
|
212
|
+
.map((upload) => `Uploaded ${upload.field}: ${upload.originalPath} → ${upload.url}`)
|
|
127
213
|
.join("\n");
|
|
128
214
|
}
|
|
129
215
|
} catch (err) {
|
|
130
216
|
const msg = err instanceof Error ? err.message : "File upload failed";
|
|
131
217
|
return text(`Error: ${msg}`);
|
|
132
218
|
}
|
|
219
|
+
|
|
133
220
|
let result: Record<string, unknown>;
|
|
134
221
|
try {
|
|
135
|
-
result =
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
222
|
+
result = activeCreditPack
|
|
223
|
+
? await apiPost<Record<string, unknown>>(
|
|
224
|
+
`/agents/${agent.id}/run`,
|
|
225
|
+
{ input: processedInput },
|
|
226
|
+
{ ensureConsumerPrincipal: true },
|
|
227
|
+
)
|
|
228
|
+
: await apiPostWithPayment<Record<string, unknown>>(
|
|
229
|
+
`/agents/${agent.id}/run`,
|
|
230
|
+
{ input: processedInput },
|
|
231
|
+
method,
|
|
232
|
+
);
|
|
140
233
|
} catch (err: unknown) {
|
|
141
234
|
const apiErr = err as { status?: number; message?: string };
|
|
235
|
+
if (activeCreditPack && apiErr?.status === 402) {
|
|
236
|
+
return text(
|
|
237
|
+
`Your available credit packs for ${agentName} could not cover this run.\n\n` +
|
|
238
|
+
"Use list_agent_credit_packs to inspect your balances, or retry with a payment method.",
|
|
239
|
+
);
|
|
240
|
+
}
|
|
142
241
|
if (apiErr?.status === 402) {
|
|
242
|
+
const allMethods = getConfiguredMethods();
|
|
243
|
+
const methodName = method ?? allMethods[0] ?? "auto";
|
|
244
|
+
const creditPackLines = buildCreditPackOfferLines(agent);
|
|
143
245
|
return text(
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
246
|
+
[
|
|
247
|
+
`Payment failed — "${methodName}" payment was rejected.`,
|
|
248
|
+
"",
|
|
249
|
+
"Check your payment method and try again.",
|
|
250
|
+
...(allMethods.length > 0 ? [`Configured methods: ${allMethods.join(", ")}`] : []),
|
|
251
|
+
"Use wallet_status to check your current payment methods.",
|
|
252
|
+
...(creditPackLines.length > 0 ? ["", ...creditPackLines] : []),
|
|
253
|
+
].join("\n"),
|
|
147
254
|
);
|
|
148
255
|
}
|
|
149
256
|
const msg = apiErr?.message ?? "Failed to run agent";
|
|
@@ -153,7 +260,6 @@ export function registerRunTools(server: McpServer): void {
|
|
|
153
260
|
return text(`Error: ${msg}`);
|
|
154
261
|
}
|
|
155
262
|
|
|
156
|
-
// Clean up pending confirmation
|
|
157
263
|
pendingRuns.delete(agent.id);
|
|
158
264
|
|
|
159
265
|
const formatted = formatRunResult(result, {
|
|
@@ -168,10 +274,10 @@ export function registerRunTools(server: McpServer): void {
|
|
|
168
274
|
|
|
169
275
|
const actualCost = result.cost as number | undefined;
|
|
170
276
|
const status = result.status as string;
|
|
277
|
+
const usedCreditPack = result.consumption_mode === "credit_pack";
|
|
171
278
|
|
|
172
|
-
// Async agent — poll until complete
|
|
173
279
|
if (status === "processing") {
|
|
174
|
-
const pollResult = await pollJobUntilDone(jobId
|
|
280
|
+
const pollResult = await pollJobUntilDone(jobId);
|
|
175
281
|
if (pollResult.status === "completed") {
|
|
176
282
|
const asyncFormatted = formatRunResult({
|
|
177
283
|
...result,
|
|
@@ -179,14 +285,15 @@ export function registerRunTools(server: McpServer): void {
|
|
|
179
285
|
output: pollResult.output,
|
|
180
286
|
}, { paymentMethod: method ?? getConfiguredMethods()[0] });
|
|
181
287
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
288
|
+
const asyncSpendLine = usedCreditPack
|
|
289
|
+
? "This run used your available credit pack."
|
|
290
|
+
: actualCost != null
|
|
291
|
+
? `Paid $${actualCost.toFixed(actualCost < 0.01 ? 4 : 2)}.`
|
|
292
|
+
: "This run completed successfully.";
|
|
185
293
|
|
|
186
|
-
const asyncCostLine = actualCost != null ? `Paid $${actualCost.toFixed(actualCost < 0.01 ? 4 : 2)}.` : "";
|
|
187
294
|
const asyncFeedbackAsk = [
|
|
188
|
-
|
|
189
|
-
`"${
|
|
295
|
+
"IMPORTANT: After presenting the result above, you MUST ask the user:",
|
|
296
|
+
`"${asyncSpendLine} Was this result helpful? I can rate it (1-5 stars) or tip the builder for you."`,
|
|
190
297
|
"",
|
|
191
298
|
`If the user wants to rate: rate_agent({ job_id: "${jobId}", rating: <1-5>, comment: "..." })`,
|
|
192
299
|
`If the user wants to tip: tip_agent({ job_id: "${jobId}", agent_id: "${resultAgentId}", amount: 0.25 })`,
|
|
@@ -199,7 +306,6 @@ export function registerRunTools(server: McpServer): void {
|
|
|
199
306
|
);
|
|
200
307
|
}
|
|
201
308
|
|
|
202
|
-
// Async agent failed
|
|
203
309
|
const failedFormatted = formatRunResult({
|
|
204
310
|
...result,
|
|
205
311
|
status: "failed",
|
|
@@ -209,11 +315,12 @@ export function registerRunTools(server: McpServer): void {
|
|
|
209
315
|
|
|
210
316
|
return multiText(
|
|
211
317
|
uploadSummary ? `${uploadSummary}\n\n${failedFormatted}` : failedFormatted,
|
|
212
|
-
|
|
318
|
+
usedCreditPack
|
|
319
|
+
? "The agent execution failed and your reserved credit-pack unit was released automatically."
|
|
320
|
+
: "The agent execution failed. A refund has been initiated automatically.",
|
|
213
321
|
);
|
|
214
322
|
}
|
|
215
323
|
|
|
216
|
-
// Auto-tip if configured and run succeeded
|
|
217
324
|
const defaultTip = getDefaultTipAmount();
|
|
218
325
|
let tipLine = "";
|
|
219
326
|
if (status === "success" && defaultTip > 0 && result.feedback_token) {
|
|
@@ -233,18 +340,24 @@ export function registerRunTools(server: McpServer): void {
|
|
|
233
340
|
if (status !== "success") {
|
|
234
341
|
return multiText(
|
|
235
342
|
uploadSummary ? `${uploadSummary}\n\n${formatted}` : formatted,
|
|
236
|
-
|
|
343
|
+
usedCreditPack
|
|
344
|
+
? "The agent execution failed and your reserved credit-pack unit was released automatically."
|
|
345
|
+
: "The agent execution failed. A refund has been initiated automatically.",
|
|
237
346
|
);
|
|
238
347
|
}
|
|
239
348
|
|
|
240
|
-
const costLine =
|
|
349
|
+
const costLine = usedCreditPack
|
|
350
|
+
? ""
|
|
351
|
+
: actualCost != null
|
|
352
|
+
? `Paid $${actualCost.toFixed(actualCost < 0.01 ? 4 : 2)}.`
|
|
353
|
+
: "";
|
|
354
|
+
const spendLine = usedCreditPack ? "This run used your available credit pack." : (costLine || "This run completed successfully.");
|
|
241
355
|
|
|
242
|
-
// Separate the feedback ask into its own content block so the LLM
|
|
243
|
-
// surfaces it to the user as a distinct follow-up question, rather than
|
|
244
|
-
// burying it inside a collapsed tool output.
|
|
245
356
|
const feedbackAsk = [
|
|
246
|
-
|
|
247
|
-
|
|
357
|
+
`--- Job ${jobId} | ${agentName} | ${usedCreditPack ? "covered by credit pack" : (costLine || "completed")} ---`,
|
|
358
|
+
"",
|
|
359
|
+
"IMPORTANT: After presenting the result above, you MUST ask the user:",
|
|
360
|
+
`"${spendLine} Was this result helpful? I can rate it (1-5 stars) or tip the builder for you."`,
|
|
248
361
|
tipLine,
|
|
249
362
|
"",
|
|
250
363
|
`If the user wants to rate: rate_agent({ job_id: "${jobId}", rating: <1-5>, comment: "..." })`,
|
|
@@ -254,7 +367,15 @@ export function registerRunTools(server: McpServer): void {
|
|
|
254
367
|
`To save for later: favorite_agent({ agent_id: "${resultAgentId}" })`,
|
|
255
368
|
].join("\n");
|
|
256
369
|
|
|
257
|
-
|
|
370
|
+
const supplementalLines = !usedCreditPack
|
|
371
|
+
? buildCreditPackOfferLines(agent)
|
|
372
|
+
: [];
|
|
373
|
+
|
|
374
|
+
const primaryBlock = uploadSummary ? `${uploadSummary}\n\n${formatted}` : formatted;
|
|
375
|
+
return multiText(
|
|
376
|
+
supplementalLines.length > 0 ? `${primaryBlock}\n\n${supplementalLines.join("\n")}` : primaryBlock,
|
|
377
|
+
feedbackAsk,
|
|
378
|
+
);
|
|
258
379
|
},
|
|
259
380
|
);
|
|
260
381
|
}
|