mandala-computer-mcp 0.11.0 → 0.12.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 (65) hide show
  1. package/README.md +82 -20
  2. package/dist/api.d.ts +8 -1
  3. package/dist/api.d.ts.map +1 -1
  4. package/dist/api.js +11 -1
  5. package/dist/api.js.map +1 -1
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/cli.js +3 -1
  8. package/dist/cli.js.map +1 -1
  9. package/dist/credits.d.ts +187 -0
  10. package/dist/credits.d.ts.map +1 -0
  11. package/dist/credits.js +119 -0
  12. package/dist/credits.js.map +1 -0
  13. package/dist/errors.d.ts +31 -1
  14. package/dist/errors.d.ts.map +1 -1
  15. package/dist/errors.js +39 -1
  16. package/dist/errors.js.map +1 -1
  17. package/dist/http.d.ts.map +1 -1
  18. package/dist/http.js +82 -8
  19. package/dist/http.js.map +1 -1
  20. package/dist/limits.d.ts +2 -0
  21. package/dist/limits.d.ts.map +1 -1
  22. package/dist/limits.js +2 -0
  23. package/dist/limits.js.map +1 -1
  24. package/dist/paths.d.ts +17 -1
  25. package/dist/paths.d.ts.map +1 -1
  26. package/dist/paths.js +12 -0
  27. package/dist/paths.js.map +1 -1
  28. package/dist/poll.d.ts +1 -1
  29. package/dist/poll.js +1 -1
  30. package/dist/server.d.ts +9 -0
  31. package/dist/server.d.ts.map +1 -1
  32. package/dist/server.js +13 -2
  33. package/dist/server.js.map +1 -1
  34. package/dist/session.d.ts +20 -4
  35. package/dist/session.d.ts.map +1 -1
  36. package/dist/session.js +5 -0
  37. package/dist/session.js.map +1 -1
  38. package/dist/stdio.d.ts.map +1 -1
  39. package/dist/stdio.js +11 -1
  40. package/dist/stdio.js.map +1 -1
  41. package/dist/tool-filters.d.ts +1 -1
  42. package/dist/tool-filters.js +1 -1
  43. package/dist/tool-filters.js.map +1 -1
  44. package/dist/tools/agent.d.ts +12 -4
  45. package/dist/tools/agent.d.ts.map +1 -1
  46. package/dist/tools/agent.js +292 -132
  47. package/dist/tools/agent.js.map +1 -1
  48. package/dist/tools/chat.d.ts +11 -2
  49. package/dist/tools/chat.d.ts.map +1 -1
  50. package/dist/tools/chat.js +19 -9
  51. package/dist/tools/chat.js.map +1 -1
  52. package/dist/tools/computers.js +1 -1
  53. package/dist/tools/computers.js.map +1 -1
  54. package/dist/tools/credits.d.ts +9 -0
  55. package/dist/tools/credits.d.ts.map +1 -0
  56. package/dist/tools/credits.js +53 -0
  57. package/dist/tools/credits.js.map +1 -0
  58. package/dist/tools/guest.js +2 -2
  59. package/dist/tools/guest.js.map +1 -1
  60. package/dist/tools/input.d.ts.map +1 -1
  61. package/dist/tools/input.js +50 -18
  62. package/dist/tools/input.js.map +1 -1
  63. package/dist/version.d.ts +1 -1
  64. package/dist/version.js +1 -1
  65. package/package.json +1 -1
@@ -1,156 +1,243 @@
1
1
  import { z } from 'zod';
2
2
  import { MODEL_KEY_HEADER } from '../api.js';
3
- import { APIError, agentRunAdvice, authenticationAdvice, platformSaid } from '../errors.js';
4
- import { errorMetadata, guarded, refused, said, withErrorMetadata } from '../format.js';
3
+ import { topUpUrl } from '../credits.js';
4
+ import { APIError, agentRunAdvice, authenticationAdvice, creditsExhaustedAdvice, FUNDED_UNAVAILABLE, fundedUnavailableAdvice, platformSaid, } from '../errors.js';
5
+ import { errorMetadata, failed, guarded, refused, said, withErrorMetadata } from '../format.js';
5
6
  import * as P from '../paths.js';
6
7
  import { safeResult } from './chat.js';
8
+ /** run_agent's annotations, shared with the check that decides whether to ask about credits. */
9
+ export const RUN_AGENT_ANNOTATIONS = { openWorldHint: true };
10
+ const TITLE = 'Have the platform drive the computer';
11
+ /** What both descriptions say after their first sentence about who pays. */
12
+ const HOW = 'Use it to delegate a long stretch of pixel work; drive with the individual tools when you want to see each frame yourself. The computer must already be running. A run is MINUTES, not seconds: it reports progress on every step so a client that sends a progressToken and sets resetTimeoutOnProgress can hold the request open, and a client that cannot should lower max_steps rather than watch its own default timeout cancel a run it is already paying for.';
13
+ const TASK = 'Give the computer a task in plain language and let the platform drive it — screenshot, decide, click, type, repeat — until it is done.';
14
+ const computerId = z
15
+ .string()
16
+ .optional()
17
+ .describe('Which computer. Defaults to the one selected with use_computer.');
18
+ const prompt = z.string().describe('The task, in plain language.');
19
+ const nonblankModel = z.string().refine((v) => v.trim().length > 0, 'model must not be blank');
20
+ const STEPS_CAP = `Defaults to 20 and is capped at ${P.AGENT_MAX_STEPS} here, so a larger value is refused before the call rather than after it.`;
21
+ /** How many actions, told the way each payer needs it told. */
22
+ const maxSteps = (bill, bound) => z
23
+ .number()
24
+ .int()
25
+ .min(1)
26
+ .max(P.AGENT_MAX_STEPS)
27
+ .default(20)
28
+ .describe(`How many ACTIONS the loop may take on the desktop. Not a count of model calls and not a proxy for ${bill}: one model reply can ask for several actions and spends a step on each, a paused turn is resubmitted for tokens and no step, and a bash call or a cursor read takes no screenshot. So a run can make more model calls than steps AND more steps than screenshots — bound the work with this, and ${bound}. ${STEPS_CAP}`);
7
29
  /**
8
30
  * The platform's own agent loop, as one tool.
9
31
  *
10
- * Registered only when a model key is configured, and that is the point of the
32
+ * Registered only when something can pay for it, and that is the point of the
11
33
  * conditional: a tool a model can see is a tool it will try, and one that fails
12
34
  * on every call with "no model key" costs a turn to discover. Absent is a
13
- * clearer answer than present-and-broken.
35
+ * clearer answer than present-and-broken. Two things can pay. A configured
36
+ * model key is the caller's own, and always wins. Without one, the account's
37
+ * Mandala AI credits pay, when `GET /credits` said at the session's start that
38
+ * they could (OPL-5866); then the tool takes `max_cost_usd`, and loses `system`
39
+ * and `provider`, which a run on credits is refused.
14
40
  *
15
41
  * Worth having even though the caller is already a model with eyes. The outer
16
42
  * agent pays for every screenshot in context; this route runs the pixel-level
17
- * loop inside the platform on the caller's own Anthropic key and hands back a
18
- * sentence. Ten clicks stop being ten images.
43
+ * loop inside the platform and hands back a sentence. Ten clicks stop being ten
44
+ * images.
19
45
  */
20
46
  export const registerAgent = (server, session) => {
21
- if (!session.modelKey)
47
+ const run = (args, extra) => runAgent(server.server, session, args, extra).then((result) => safeResult(result, session.modelKey));
48
+ if (session.modelKey) {
49
+ server.registerTool('run_agent', {
50
+ title: TITLE,
51
+ description: `${TASK} Runs on the Anthropic or OpenAI key this server was configured with, and bills that key for every step. ${HOW}`,
52
+ inputSchema: {
53
+ computer_id: computerId,
54
+ prompt,
55
+ system: z.string().optional().describe('Standing instructions carried into the run.'),
56
+ provider: z
57
+ .enum(['anthropic', 'openai'])
58
+ .optional()
59
+ .describe('Inferred from model when omitted. Select openai to use gpt-6.1-sol by default. The configured MANDALA_MODEL_KEY must match the provider.'),
60
+ model: nonblankModel
61
+ .optional()
62
+ .describe('A computer-capable Anthropic or OpenAI model id to run with. Omit it for the one the platform picks. The configured key must be able to use it; a model it cannot use fails the run.'),
63
+ max_steps: maxSteps('what your key is billed', 'budget the bill on the key itself'),
64
+ },
65
+ annotations: RUN_AGENT_ANNOTATIONS,
66
+ }, run);
67
+ return;
68
+ }
69
+ if (!session.funded)
22
70
  return;
23
71
  server.registerTool('run_agent', {
24
- title: 'Have the platform drive the computer',
25
- description: 'Give the computer a task in plain language and let the platform drive it — screenshot, decide, click, type, repeat — until it is done. Runs on the Anthropic key this server was configured with, and bills that key for every step. Use it to delegate a long stretch of pixel work; drive with the individual tools when you want to see each frame yourself. The computer must already be running. A run is MINUTES, not seconds: it reports progress on every step so a client that sends a progressToken and sets resetTimeoutOnProgress can hold the request open, and a client that cannot should lower max_steps rather than watch its own default timeout cancel a run it is already paying for.',
72
+ title: TITLE,
73
+ description: `${TASK} Runs on this account's Mandala AI credits, because no model key is configured: each model call reserves $0.25 and is charged for its usage, max_cost_usd caps what one run may start, and get_credits reads the balance. ${HOW}`,
26
74
  inputSchema: {
27
- computer_id: z
28
- .string()
75
+ computer_id: computerId,
76
+ prompt,
77
+ model: nonblankModel
29
78
  .optional()
30
- .describe('Which computer. Defaults to the one selected with use_computer.'),
31
- prompt: z.string().describe('The task, in plain language.'),
32
- system: z.string().optional().describe('Standing instructions carried into the run.'),
33
- model: z
34
- .string()
35
- .refine((v) => v.trim().length > 0, 'model must not be blank')
36
- .optional()
37
- .describe('An Anthropic model id to run with. Omit it for the one the platform picks. The configured key must be able to use it; a model it cannot use fails the run.'),
38
- max_steps: z
79
+ .describe('claude-sonnet-5-5, the default, or claude-opus-5-5; credits pay for these two. Another model needs a model key.'),
80
+ max_steps: maxSteps('what a run costs', 'the spend with max_cost_usd'),
81
+ max_cost_usd: z
39
82
  .number()
40
- .int()
41
- .min(1)
42
- .max(100)
43
- .default(20)
44
- .describe('How many ACTIONS the loop may take on the desktop. Not a count of model calls and not a proxy for what your key is billed: one model reply can ask for several actions and spends a step on each, a paused turn is resubmitted for tokens and no step, and a bash call or a cursor read takes no screenshot. So a run can make more model calls than steps AND more steps than screenshots — bound the work with this, and budget the bill on the key itself. Defaults to 20 and is capped at 100 here, so a larger value is refused before the call rather than after it.'),
83
+ .min(0.25)
84
+ .max(20)
85
+ .optional()
86
+ .describe('The most this run may spend from credits, in USD, 0.25 to 20; the platform defaults to 2. No model call starts past it, but the last one can go over. A run that reaches it ends with stop max_cost.'),
45
87
  },
46
- annotations: { openWorldHint: true },
47
- }, ({ computer_id, prompt, system, model, max_steps }, extra) => guarded(async () => {
88
+ annotations: RUN_AGENT_ANNOTATIONS,
89
+ }, run);
90
+ };
91
+ /** One run, BYOK or funded: `session.modelKey` decides which. */
92
+ function runAgent(log, session, { computer_id, prompt, system, model, provider, max_steps, max_cost_usd }, extra) {
93
+ return guarded(async () => {
48
94
  const id = session.resolve(computer_id);
49
95
  const steps = [];
50
96
  let done;
97
+ // The newest balance a step reported. The `done` frame carries the run's
98
+ // cost but not this, and a model told what a run cost wants to know what
99
+ // is left as well.
100
+ let remaining;
51
101
  // The token the CLIENT sends when it wants progress, exactly as
52
102
  // watch_build reads it. Without one there is nothing to address a
53
103
  // progress notification to, and this falls back to logging alone.
54
104
  const progressToken = extra._meta?.progressToken;
55
- for await (const ev of session.api.sse('POST', P.computerAction(id, 'agent'), {
56
- body: P.agentBody({ prompt, system, model, max_steps, stream: true }),
57
- headers: { [MODEL_KEY_HEADER]: session.modelKey },
58
- signal: extra.signal,
59
- })) {
60
- if (ev.event === 'step') {
61
- if (!isRecord(ev.data))
62
- continue;
63
- const s = ev.data;
64
- steps.push(`${s.n ?? steps.length + 1}. ${s.detail ?? s.action ?? 'step'}`);
65
- // A PROGRESS notification, not only a logging one, for the reason
66
- // watch_build sends one: `_onprogress` in the SDK's
67
- // shared/protocol.js resets a pending request's timer, and
68
- // `notifications/message` — what sendLoggingMessage emits — never
69
- // touches it. This tool had only the logging half, so a run of the
70
- // default 20 steps, most of them a model call and a screenshot, sailed past
71
- // the client's 60s default and was cancelled while the platform went
72
- // on driving the desktop on the caller's own Anthropic key.
73
- //
74
- // Not sufficient on its own, and the same caveat applies here as
75
- // there: protocol.js reads `options?.resetTimeoutOnProgress ?? false`,
76
- // so a client that mints a token and leaves that option alone is
77
- // still cancelled. What this does is make the keepalive AVAILABLE.
78
- // The description says so, and max_steps is the lever for a client
79
- // that cannot opt in.
80
- if (progressToken !== undefined) {
81
- await extra
82
- .sendNotification({
83
- method: 'notifications/progress',
84
- params: {
85
- progressToken,
86
- // The step COUNT, which the SDK's ProgressSchema asks to
87
- // increase every time. `max_steps` is a real total here —
88
- // unlike a build's step count it is known before the first
89
- // step and cannot change — so the bar means something.
90
- progress: steps.length,
91
- total: max_steps,
92
- message: steps[steps.length - 1],
93
- },
94
- })
105
+ try {
106
+ for await (const ev of session.api.sse('POST', P.computerAction(id, 'agent'), {
107
+ body: P.agentBody({
108
+ prompt,
109
+ system,
110
+ model,
111
+ provider,
112
+ max_steps,
113
+ max_cost_usd,
114
+ stream: true,
115
+ }),
116
+ // No header at all on a run that credits pay for: its absence is what
117
+ // tells the platform to use them.
118
+ ...(session.modelKey ? { headers: { [MODEL_KEY_HEADER]: session.modelKey } } : {}),
119
+ signal: extra.signal,
120
+ })) {
121
+ if (ev.event === 'step') {
122
+ if (!isRecord(ev.data))
123
+ continue;
124
+ const s = ev.data;
125
+ if (finite(ev.data.credits_remaining_usd))
126
+ remaining = ev.data.credits_remaining_usd;
127
+ steps.push(`${s.n ?? steps.length + 1}. ${s.detail ?? s.action ?? 'step'}`);
128
+ // A PROGRESS notification, not only a logging one, for the reason
129
+ // watch_build sends one: `_onprogress` in the SDK's
130
+ // shared/protocol.js resets a pending request's timer, and
131
+ // `notifications/message` — what sendLoggingMessage emits — never
132
+ // touches it. This tool had only the logging half, so a run of the
133
+ // default 20 steps, most of them a model call and a screenshot, sailed past
134
+ // the client's 60s default and was cancelled while the platform went
135
+ // on driving the desktop on the caller's own model-provider key.
136
+ //
137
+ // Not sufficient on its own, and the same caveat applies here as
138
+ // there: protocol.js reads `options?.resetTimeoutOnProgress ?? false`,
139
+ // so a client that mints a token and leaves that option alone is
140
+ // still cancelled. What this does is make the keepalive AVAILABLE.
141
+ // The description says so, and max_steps is the lever for a client
142
+ // that cannot opt in.
143
+ if (progressToken !== undefined) {
144
+ await extra
145
+ .sendNotification({
146
+ method: 'notifications/progress',
147
+ params: {
148
+ progressToken,
149
+ // The step COUNT, which the SDK's ProgressSchema asks to
150
+ // increase every time. `max_steps` is a real total here —
151
+ // unlike a build's step count it is known before the first
152
+ // step and cannot change — so the bar means something.
153
+ progress: steps.length,
154
+ total: max_steps,
155
+ message: steps[steps.length - 1],
156
+ },
157
+ })
158
+ .catch(() => { });
159
+ }
160
+ // Told, not just collected. A run is minutes of clicking, and a tool
161
+ // that says nothing until it is over is one nobody watching can tell
162
+ // from a hang.
163
+ await log
164
+ .sendLoggingMessage({ level: 'info', data: steps[steps.length - 1] })
95
165
  .catch(() => { });
96
166
  }
97
- // Told, not just collected. A run is minutes of clicking, and a tool
98
- // that says nothing until it is over is one nobody watching can tell
99
- // from a hang.
100
- await server.server
101
- .sendLoggingMessage({ level: 'info', data: steps[steps.length - 1] })
102
- .catch(() => { });
103
- }
104
- else if (ev.event === 'done') {
105
- // Stop at the terminal frame rather than waiting for EOF, as
106
- // watch_build does. Waiting held a result that was already in hand
107
- // until the generator ended, so a client that aborted in that window
108
- // — or a stream the platform left open — turned a finished run into
109
- // a CancelledError and threw the answer away.
110
- //
111
- // Terminal means it SAYS SO, which is watch_build's discipline
112
- // (OPL-3835) applied to this stream's own vocabulary: `stop` is the
113
- // field the platform always sends on a result — the AgentResult type
114
- // on the platform side requires it, and every `done` it yields carries
115
- // one — and it is the field the verdict below reads. A record
116
- // without it is not a result, so it is kept, in case nothing better
117
- // arrives, but it does not end the loop and discard the frame that
118
- // would have been the real one. A `done` that is not a record at all
119
- // is skipped entirely: the null-done case the regression suite pins.
120
- if (isRecord(ev.data)) {
121
- done = ev.data;
122
- if (typeof ev.data.stop === 'string' && ev.data.stop)
123
- break;
167
+ else if (ev.event === 'done') {
168
+ // Stop at the terminal frame rather than waiting for EOF, as
169
+ // watch_build does. Waiting held a result that was already in hand
170
+ // until the generator ended, so a client that aborted in that window
171
+ // — or a stream the platform left open — turned a finished run into
172
+ // a CancelledError and threw the answer away.
173
+ //
174
+ // Terminal means it SAYS SO, which is watch_build's discipline
175
+ // (OPL-3835) applied to this stream's own vocabulary: `stop` is the
176
+ // field the platform always sends on a result — the AgentResult type
177
+ // on the platform side requires it, and every `done` it yields carries
178
+ // one — and it is the field the verdict below reads. A record
179
+ // without it is not a result, so it is kept, in case nothing better
180
+ // arrives, but it does not end the loop and discard the frame that
181
+ // would have been the real one. A `done` that is not a record at all
182
+ // is skipped entirely: the null-done case the regression suite pins.
183
+ if (isRecord(ev.data)) {
184
+ done = ev.data;
185
+ if (typeof ev.data.stop === 'string' && ev.data.stop)
186
+ break;
187
+ }
188
+ }
189
+ else if (ev.event === 'error') {
190
+ // A run that errored is a failure, and has to carry `isError` to
191
+ // say so. Prose alone leaves it indistinguishable at the protocol
192
+ // level from a run that worked — a caller checking whether the step
193
+ // succeeded would read this one as a success that happened to have
194
+ // a discouraging sentence in it.
195
+ //
196
+ // And it has to say WHY in words, because this is the one place a
197
+ // status cannot be read off the response: the platform answered 200
198
+ // before the first step, so a run stopped by the credential, the role
199
+ // or the model provider arrives as a frame in a successful stream. A model
200
+ // handed "the run failed" and a JSON blob does the natural thing,
201
+ // which is to call this tool again with the same prompt — paying for
202
+ // every completed step a second time to be refused the same way.
203
+ const frame = isRecord(ev.data) ? ev.data : {};
204
+ const diagnostic = new APIError('', typeof frame.status === 'number' ? frame.status : 0, frame);
205
+ const spent = spending(frame.cost_usd, remaining);
206
+ const topUp = topUpUrl(frame.status, frame, session.api.baseUrl);
207
+ return withErrorMetadata(refused(`The run failed after ${steps.length} step(s).${stopReason(ev.data, topUp, session.funded)}` +
208
+ (spent.line ? `\n\n${spent.line}` : '') +
209
+ (steps.length ? `\n\nWhat it did, and is billed for:\n${steps.join('\n')}` : ''), {
210
+ error: platformSaid(frame),
211
+ status: errorMetadata({ status: frame.status }).fields.status,
212
+ ...(topUp ? { code: INSUFFICIENT_CREDITS, top_up_url: topUp } : {}),
213
+ ...spent.fields,
214
+ steps: frame.steps,
215
+ usage: frame.usage,
216
+ }), {
217
+ status: frame.status,
218
+ reason: diagnostic.reason,
219
+ request_id: diagnostic.requestId,
220
+ });
124
221
  }
125
222
  }
126
- else if (ev.event === 'error') {
127
- // A run that errored is a failure, and has to carry `isError` to
128
- // say so. Prose alone leaves it indistinguishable at the protocol
129
- // level from a run that worked — a caller checking whether the step
130
- // succeeded would read this one as a success that happened to have
131
- // a discouraging sentence in it.
132
- //
133
- // And it has to say WHY in words, because this is the one place a
134
- // status cannot be read off the response: the platform answered 200
135
- // before the first step, so a run stopped by the credential, the role
136
- // or the model provider arrives as a frame in a successful stream. A model
137
- // handed "the run failed" and a JSON blob does the natural thing,
138
- // which is to call this tool again with the same prompt — paying for
139
- // every completed step a second time to be refused the same way.
140
- const frame = isRecord(ev.data) ? ev.data : {};
141
- const diagnostic = new APIError('', typeof frame.status === 'number' ? frame.status : 0, frame);
142
- return withErrorMetadata(refused(`The run failed after ${steps.length} step(s).${stopReason(ev.data)}` +
143
- (steps.length ? `\n\nWhat it did, and is billed for:\n${steps.join('\n')}` : ''), {
144
- error: platformSaid(frame),
145
- status: errorMetadata({ status: frame.status }).fields.status,
146
- steps: frame.steps,
147
- usage: frame.usage,
148
- }), {
149
- status: frame.status,
150
- reason: diagnostic.reason,
151
- request_id: diagnostic.requestId,
152
- });
223
+ }
224
+ catch (err) {
225
+ // Refused before the stream opened. Two refusals are worded here rather
226
+ // than by the shared advice: a run on credits the account cannot cover
227
+ // (a 402 naming a top-up page, which that advice would call a plan
228
+ // limit), and a run on credits the platform's AI service cannot serve
229
+ // (which it would call a change that may or may not have happened).
230
+ if (!(err instanceof APIError))
231
+ throw err;
232
+ const topUp = topUpUrl(err.status, err.body, session.api.baseUrl);
233
+ if (topUp) {
234
+ const result = failed(err, true, creditsExhaustedAdvice(topUp, 'run_agent'));
235
+ result.content.push(...said('Refusal metadata:', { code: INSUFFICIENT_CREDITS, top_up_url: topUp }).content);
236
+ return result;
153
237
  }
238
+ if (fundedOutage(session.funded, err.status, err.body))
239
+ return failed(err, true, fundedUnavailableAdvice('run_agent'));
240
+ throw err;
154
241
  }
155
242
  if (!done) {
156
243
  return refused(`The stream ended without a result after ${steps.length} step(s). What it did:\n${steps.join('\n')}`);
@@ -163,9 +250,19 @@ export const registerAgent = (server, session) => {
163
250
  ? 'finished'
164
251
  : stop === 'max_steps'
165
252
  ? `RAN OUT OF STEPS after ${done.steps ?? max_steps} — the task is probably unfinished`
166
- : stop === 'refusal'
167
- ? 'the model declined the task'
168
- : `ended: ${stop}`;
253
+ : stop === 'credits_exhausted'
254
+ ? "RAN OUT OF AI CREDITS — the task is probably unfinished. A person can top up the account's credits on its billing page, or configure a model key"
255
+ : stop === 'max_cost'
256
+ ? 'REACHED max_cost_usd: another model call would have gone past it — the task is probably unfinished'
257
+ : stop === 'refusal'
258
+ ? 'the model declined the task'
259
+ : stop === 'pause_turn'
260
+ ? 'the model kept pausing its turn — the task is probably unfinished'
261
+ : stop === 'incomplete'
262
+ ? "the model's response was incomplete — the task is probably unfinished"
263
+ : stop === 'safety_check'
264
+ ? 'STOPPED FOR A SAFETY CHECK: the model asked for approval of an action, which this tool cannot give — the task is unfinished; say so rather than running it again'
265
+ : `ended: ${stop}`;
169
266
  // Interpolated only when it IS a string, which is the same discipline
170
267
  // `stop` gets three lines up. `String()` over a shape this build does
171
268
  // not know — a content-block array is the plausible one — renders the
@@ -178,10 +275,63 @@ export const registerAgent = (server, session) => {
178
275
  : done.text === undefined || done.text === null
179
276
  ? ''
180
277
  : JSON.stringify(done.text);
181
- const result = `${verdict}\n\n${text}\n\nWhat it did:\n${steps.join('\n')}`;
182
- return stop === 'end_turn' ? said(result, done) : refused(result, done);
183
- }).then((result) => safeResult(result, session.modelKey)));
278
+ const spent = spending(done.cost_usd, remaining);
279
+ const result = `${verdict}\n\n${text}` +
280
+ (spent.line ? `\n\n${spent.line}` : '') +
281
+ `\n\nWhat it did:\n${steps.join('\n')}`;
282
+ // The cost fields as read above, not as sent: a value that is not a
283
+ // finite number (or a negative charge) is left out rather than repeated.
284
+ const { cost_usd: _cost, credits_remaining_usd: _left, ...rest } = done;
285
+ const record = { ...rest, ...spent.fields };
286
+ return stop === 'end_turn' ? said(result, record) : refused(result, record);
287
+ });
288
+ }
289
+ /**
290
+ * What a run on credits cost, and what the account has left, as a sentence and
291
+ * as fields — or nothing, on a run a model key paid for, which reports neither.
292
+ *
293
+ * `cost_usd` is the run's cumulative charge, from its last frame.
294
+ * `credits_remaining_usd` is the balance the newest step reported, and can be
295
+ * negative after a call overran what was left; the platform leaves it out when
296
+ * it could not read the balance, and so does this.
297
+ */
298
+ function spending(cost, remaining) {
299
+ const fields = {};
300
+ // A charge is never negative; a balance can be, after a call overran it.
301
+ if (finite(cost) && cost >= 0)
302
+ fields.cost_usd = cost;
303
+ if (remaining !== undefined)
304
+ fields.credits_remaining_usd = remaining;
305
+ if (fields.cost_usd === undefined && remaining === undefined)
306
+ return { fields };
307
+ const parts = [
308
+ ...(fields.cost_usd !== undefined ? [`${usd(fields.cost_usd)} of AI credits spent`] : []),
309
+ ...(remaining !== undefined ? [`${usd(remaining)} left on the account`] : []),
310
+ ];
311
+ return { line: `Cost: ${parts.join('; ')}.`, fields };
312
+ }
313
+ /** Dollars to the cent, or to a hundredth of a cent when a cent would read as nothing. */
314
+ const usd = (value) => {
315
+ const digits = value !== 0 && Math.abs(value) < 0.01 ? 4 : 2;
316
+ return `${value < 0 ? '-' : ''}$${Math.abs(value).toFixed(digits)}`;
184
317
  };
318
+ const finite = (value) => typeof value === 'number' && Number.isFinite(value);
319
+ /** The code the SDKs give a run on credits the account cannot cover. */
320
+ const INSUFFICIENT_CREDITS = 'insufficient_credits';
321
+ /**
322
+ * Whether a run on credits failed in the platform's AI service rather than in
323
+ * the way its status usually means: the platform's fixed sentence for that, at
324
+ * any status, or any other 402 — no plan limit refuses inside a run, and there
325
+ * is no key of the caller's for a provider to bill. Asked only after a 402
326
+ * naming a top-up page has been ruled out. Never on a run a model key paid
327
+ * for, whose statuses keep their own readings.
328
+ */
329
+ function fundedOutage(funded, status, body) {
330
+ if (!funded)
331
+ return false;
332
+ // A 402 whatever its body, which need not be JSON at all.
333
+ return status === 402 || (isRecord(body) && body.error === FUNDED_UNAVAILABLE);
334
+ }
185
335
  /**
186
336
  * What an `error` frame says about whether calling this tool again can work.
187
337
  *
@@ -189,9 +339,14 @@ export const registerAgent = (server, session) => {
189
339
  * answer a second run the same way after it has paid for its steps again. The
190
340
  * platform's own authority re-check is a 401 or 403 carrying `reason:
191
341
  * 'revoked'`; the 401 gets the credential sentence, and the 403 says the account
192
- * no longer permits the run. Everything else with a status here is the model
193
- * provider's, relayed for the configured model key — a 402 is its billing error,
194
- * not the Mandala plan (OPL-5437) — and {@link agentRunAdvice} words those.
342
+ * no longer permits the run. A 402 naming a top-up page is the account's AI
343
+ * credits run out (OPL-5866). On a run credits paid for, the platform reports
344
+ * its provider's failures in its own fixed words over the provider's status,
345
+ * and those are the platform's AI service failing, whatever the status (see
346
+ * {@link fundedOutage}). Everything else with a status here is the model
347
+ * provider's, relayed for the configured model key — a 402 without that page is
348
+ * its billing error, not the Mandala plan (OPL-5437) — and {@link agentRunAdvice}
349
+ * words those.
195
350
  *
196
351
  * Anything else is left as the platform's own sentence. A run can fail for
197
352
  * reasons that are worth another attempt, and inventing a verdict for a status
@@ -199,12 +354,17 @@ export const registerAgent = (server, session) => {
199
354
  * direction: the leading space is part of the returned clause so that an
200
355
  * unclassified stop reads as one sentence rather than as a missing one.
201
356
  */
202
- function stopReason(data) {
357
+ function stopReason(data, topUp, funded) {
203
358
  const frame = isRecord(data) ? data : undefined;
204
359
  const status = typeof frame?.status === 'number' ? frame.status : undefined;
205
360
  const said = platformSaid(frame);
206
361
  const why = said ? ` ${said}` : '';
207
362
  const reason = new APIError('', status ?? 0, frame).reason;
363
+ // Before either credential reading: on a run credits paid for, a 401 the
364
+ // platform reports in its own AI-service words is its provider refusing
365
+ // Mandala's key, not the caller's credential.
366
+ if (!topUp && fundedOutage(funded, status, frame))
367
+ return ` HTTP ${status}: ${fundedUnavailableAdvice('run_agent')}.${why}`;
208
368
  // 401 and 403 are split, because the recovery is not the same one. A shared
209
369
  // clause told a caller whose ROLE had been taken away to re-authenticate,
210
370
  // which restores nothing and sends it round the same refusal with another
@@ -213,7 +373,7 @@ function stopReason(data) {
213
373
  return (` HTTP ${status}: ${authenticationAdvice(reason)}.${why} Do NOT call run_agent again with the same` +
214
374
  ` prompt. Read what the steps below already did before deciding what is left to do.`);
215
375
  }
216
- const advice = agentRunAdvice(status, reason, 'run_agent');
376
+ const advice = agentRunAdvice(status, reason, 'run_agent', topUp);
217
377
  return advice ? ` HTTP ${status}: ${advice}.${why}` : why;
218
378
  }
219
379
  const isRecord = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
@@ -1 +1 @@
1
- {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/tools/agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/tools/agent.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,15 @@
1
1
  import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
2
2
  import type { Registrar } from './types.js';
3
- /** Do not let a provider echo session secrets into output, even in a known text field. */
4
- export declare function safeResult(result: CallToolResult, modelKey: string): CallToolResult;
3
+ /**
4
+ * Do not let a provider echo session secrets into output, even in a known text
5
+ * field. A run on credits has no model key to look for; splitting on an empty
6
+ * string would put the marker between every character, so it is skipped.
7
+ */
8
+ export declare function safeResult(result: CallToolResult, modelKey: string | undefined): CallToolResult;
9
+ /**
10
+ * BYOK only, and that is the platform's rule rather than this server's: the
11
+ * chat route refuses a run without a model key, so a session whose run_agent
12
+ * runs on AI credits still has no run_agent_chat.
13
+ */
5
14
  export declare const registerChat: Registrar;
6
15
  //# sourceMappingURL=chat.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/tools/chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AASzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAwK5C,0FAA0F;AAC1F,wBAAgB,UAAU,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,CAenF;AAED,eAAO,MAAM,YAAY,EAAE,SAiF1B,CAAC"}
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/tools/chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AASzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAwK5C;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,CAe/F;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,SAuF1B,CAAC"}