@deeprelay/mcp 0.0.1 → 0.1.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.
- package/README.md +188 -1
- package/dist/auth.d.ts +52 -0
- package/dist/auth.js +122 -0
- package/dist/auth.js.map +1 -0
- package/dist/errors.d.ts +83 -0
- package/dist/errors.js +307 -0
- package/dist/errors.js.map +1 -0
- package/dist/guardrail/budget.d.ts +95 -0
- package/dist/guardrail/budget.js +225 -0
- package/dist/guardrail/budget.js.map +1 -0
- package/dist/guardrail/elicitation.d.ts +12 -0
- package/dist/guardrail/elicitation.js +79 -0
- package/dist/guardrail/elicitation.js.map +1 -0
- package/dist/guardrail/estimate.d.ts +67 -0
- package/dist/guardrail/estimate.js +171 -0
- package/dist/guardrail/estimate.js.map +1 -0
- package/dist/guardrail/handshake.d.ts +32 -0
- package/dist/guardrail/handshake.js +164 -0
- package/dist/guardrail/handshake.js.map +1 -0
- package/dist/guardrail/types.d.ts +61 -0
- package/dist/guardrail/types.js +10 -0
- package/dist/guardrail/types.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/roster.d.ts +36 -0
- package/dist/roster.js +130 -0
- package/dist/roster.js.map +1 -0
- package/dist/tools/crypto-deposit-gate.d.ts +21 -0
- package/dist/tools/crypto-deposit-gate.js +91 -0
- package/dist/tools/crypto-deposit-gate.js.map +1 -0
- package/dist/tools/index.d.ts +16 -0
- package/dist/tools/index.js +108 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/readonly/define.d.ts +32 -0
- package/dist/tools/readonly/define.js +64 -0
- package/dist/tools/readonly/define.js.map +1 -0
- package/dist/tools/readonly/index.d.ts +7 -0
- package/dist/tools/readonly/index.js +292 -0
- package/dist/tools/readonly/index.js.map +1 -0
- package/dist/tools/readonly/video-reads.d.ts +11 -0
- package/dist/tools/readonly/video-reads.js +170 -0
- package/dist/tools/readonly/video-reads.js.map +1 -0
- package/dist/tools/result.d.ts +22 -0
- package/dist/tools/result.js +63 -0
- package/dist/tools/result.js.map +1 -0
- package/dist/tools/spend/define.d.ts +93 -0
- package/dist/tools/spend/define.js +286 -0
- package/dist/tools/spend/define.js.map +1 -0
- package/dist/tools/spend/index.d.ts +11 -0
- package/dist/tools/spend/index.js +163 -0
- package/dist/tools/spend/index.js.map +1 -0
- package/dist/tools/spend/media.d.ts +9 -0
- package/dist/tools/spend/media.js +164 -0
- package/dist/tools/spend/media.js.map +1 -0
- package/dist/tools/spend/pricing.d.ts +17 -0
- package/dist/tools/spend/pricing.js +58 -0
- package/dist/tools/spend/pricing.js.map +1 -0
- package/dist/tools/types.d.ts +45 -0
- package/dist/tools/types.js +3 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools/write/define.d.ts +60 -0
- package/dist/tools/write/define.js +110 -0
- package/dist/tools/write/define.js.map +1 -0
- package/dist/tools/write/index.d.ts +12 -0
- package/dist/tools/write/index.js +159 -0
- package/dist/tools/write/index.js.map +1 -0
- package/dist/tools/write/payment-links.d.ts +3 -0
- package/dist/tools/write/payment-links.js +161 -0
- package/dist/tools/write/payment-links.js.map +1 -0
- package/dist/tools/write/spending-limit.d.ts +2 -0
- package/dist/tools/write/spending-limit.js +229 -0
- package/dist/tools/write/spending-limit.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.js +36 -0
- package/dist/version.js.map +1 -0
- package/package.json +39 -3
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { Configuration } from "@deeprelay/sdk";
|
|
2
|
+
import { z, type ZodRawShape } from "zod";
|
|
3
|
+
import { type Estimate, type EstimateParams } from "../../guardrail/estimate.js";
|
|
4
|
+
import type { Modality, Quote } from "../../guardrail/types.js";
|
|
5
|
+
import type { SpendToolName } from "../../roster.js";
|
|
6
|
+
import type { Env, ToolContext, ToolDefinition, ToolResult } from "../types.js";
|
|
7
|
+
import { type ModelRates } from "./pricing.js";
|
|
8
|
+
/** Appended to every spend description. The tier's contract, stated to the agent. */
|
|
9
|
+
export declare const SPEND_TIER_SENTENCE: string;
|
|
10
|
+
export type QuoteKind = "ceiling" | "budget";
|
|
11
|
+
/** The extra arguments every spend tool accepts. */
|
|
12
|
+
export declare const SPEND_CONFIRMATION_SHAPE: {
|
|
13
|
+
confirmation_token: z.ZodOptional<z.ZodString>;
|
|
14
|
+
session_budget_usd: z.ZodOptional<z.ZodNumber>;
|
|
15
|
+
quote_kind: z.ZodOptional<z.ZodEnum<{
|
|
16
|
+
ceiling: "ceiling";
|
|
17
|
+
budget: "budget";
|
|
18
|
+
}>>;
|
|
19
|
+
};
|
|
20
|
+
/** Per-execution facts handed to a tool's execute step. */
|
|
21
|
+
export interface SpendRun {
|
|
22
|
+
/** Unique per execution; the budget reservation key. */
|
|
23
|
+
callId: string;
|
|
24
|
+
/** The confirmation token when this run was confirmed, else callId. Sent by image and video only. */
|
|
25
|
+
idempotencyKey: string;
|
|
26
|
+
config: Configuration;
|
|
27
|
+
rates: ModelRates;
|
|
28
|
+
estimate: Estimate;
|
|
29
|
+
env: Env;
|
|
30
|
+
}
|
|
31
|
+
/** What a spend tool's execute step returns when ok() can serialize it. */
|
|
32
|
+
export interface SpendExecuted {
|
|
33
|
+
/** One sentence the agent can relay as-is. */
|
|
34
|
+
lead: string;
|
|
35
|
+
/** Sanitized and redacted before it reaches the agent. */
|
|
36
|
+
payload: Record<string, unknown>;
|
|
37
|
+
}
|
|
38
|
+
/** A prebuilt ToolResult (image blocks) is passed through unchanged. */
|
|
39
|
+
export type SpendOutcome = SpendExecuted | ToolResult;
|
|
40
|
+
type Args<Shape extends ZodRawShape> = z.infer<z.ZodObject<Shape>>;
|
|
41
|
+
export interface SpendToolSpec<Shape extends ZodRawShape> {
|
|
42
|
+
name: SpendToolName;
|
|
43
|
+
title: string;
|
|
44
|
+
/** Agent-shaped: what it does and its pricing basis. The tier sentence is appended. */
|
|
45
|
+
description: string;
|
|
46
|
+
/** Must include `model`. */
|
|
47
|
+
inputSchema: Shape;
|
|
48
|
+
modality: Modality;
|
|
49
|
+
/** The yes/no question for a ceiling (this-call) confirmation. */
|
|
50
|
+
question: string;
|
|
51
|
+
/** What was being attempted, for error messages ("running a chat completion"). */
|
|
52
|
+
context: string;
|
|
53
|
+
/** The first sentence of the quote summary (no trailing period). */
|
|
54
|
+
describe(args: Args<Shape>): string;
|
|
55
|
+
/** Extra quote wording. Video uses it to state the floor semantics. */
|
|
56
|
+
quoteNote?: string;
|
|
57
|
+
execute(args: Args<Shape>, run: SpendRun): Promise<SpendOutcome>;
|
|
58
|
+
}
|
|
59
|
+
/** Map the snake_case tool arguments onto the estimator's inputs. */
|
|
60
|
+
export declare function toEstimateParams(args: Record<string, unknown>): EstimateParams;
|
|
61
|
+
/**
|
|
62
|
+
* The two-call handshake with elicitation in front of it. No valid token means
|
|
63
|
+
* a quote comes back and nothing executes. With elicitation, "confirmed"
|
|
64
|
+
* re-enters the SAME handshake with the minted token, "declined" revokes the
|
|
65
|
+
* token and returns the quote marked declined, "unavailable" returns the quote.
|
|
66
|
+
* executeFn receives the token that authorized it (for idempotency keys).
|
|
67
|
+
*/
|
|
68
|
+
export declare function confirmThenExecute<P extends Record<string, unknown>>(toolName: SpendToolName, params: P & {
|
|
69
|
+
confirmation_token?: string;
|
|
70
|
+
}, quoteFn: (p: P) => Promise<Quote>, executeFn: (p: P, token: string) => Promise<ToolResult>, question: string, ctx?: ToolContext): Promise<ToolResult>;
|
|
71
|
+
export interface RunWithBudgetOptions {
|
|
72
|
+
toolName: SpendToolName;
|
|
73
|
+
modality: Modality;
|
|
74
|
+
/** Parsed arguments, including any confirmation_token / session_budget_usd / quote_kind. */
|
|
75
|
+
parsed: Record<string, unknown>;
|
|
76
|
+
ctx?: ToolContext;
|
|
77
|
+
config: Configuration;
|
|
78
|
+
rates: ModelRates;
|
|
79
|
+
/** Ceiling-branch question. */
|
|
80
|
+
question: string;
|
|
81
|
+
/** First sentence of the quote summary. */
|
|
82
|
+
describe: string;
|
|
83
|
+
quoteNote?: string;
|
|
84
|
+
execute(args: Record<string, unknown>, run: SpendRun): Promise<SpendOutcome>;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* The budget-checked dispatch: ceiling → approval → wall → headroom
|
|
88
|
+
* (checkCall's order), then run, confirm this call, or confirm a budget.
|
|
89
|
+
*/
|
|
90
|
+
export declare function runWithBudget(o: RunWithBudgetOptions): Promise<ToolResult>;
|
|
91
|
+
/** Wrap a billable inference call in the spend tier's quote → budget → confirm dispatch. */
|
|
92
|
+
export declare function defineSpendTool<Shape extends ZodRawShape>(spec: SpendToolSpec<Shape>): ToolDefinition;
|
|
93
|
+
export {};
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SPEND_CONFIRMATION_SHAPE = exports.SPEND_TIER_SENTENCE = void 0;
|
|
4
|
+
exports.toEstimateParams = toEstimateParams;
|
|
5
|
+
exports.confirmThenExecute = confirmThenExecute;
|
|
6
|
+
exports.runWithBudget = runWithBudget;
|
|
7
|
+
exports.defineSpendTool = defineSpendTool;
|
|
8
|
+
const node_crypto_1 = require("node:crypto");
|
|
9
|
+
const zod_1 = require("zod");
|
|
10
|
+
const auth_js_1 = require("../../auth.js");
|
|
11
|
+
const errors_js_1 = require("../../errors.js");
|
|
12
|
+
const budget_js_1 = require("../../guardrail/budget.js");
|
|
13
|
+
const elicitation_js_1 = require("../../guardrail/elicitation.js");
|
|
14
|
+
const estimate_js_1 = require("../../guardrail/estimate.js");
|
|
15
|
+
const handshake_js_1 = require("../../guardrail/handshake.js");
|
|
16
|
+
const result_js_1 = require("../result.js");
|
|
17
|
+
const pricing_js_1 = require("./pricing.js");
|
|
18
|
+
/** Appended to every spend description. The tier's contract, stated to the agent. */
|
|
19
|
+
exports.SPEND_TIER_SENTENCE = "Costs money. Each call is priced from the catalog first. Inside an approved session budget (default $5.00, " +
|
|
20
|
+
"up to $100, shared by chat, embeddings, image and video) a call under the $0.50 per-call ceiling runs " +
|
|
21
|
+
"immediately. Otherwise the first call returns a quote with a confirmation_token and runs nothing: show the " +
|
|
22
|
+
"user the price, and call again with the same arguments plus that confirmation_token only after they agree. " +
|
|
23
|
+
"A blanket pre-authorization given before the price was seen does not count as confirmation, and no argument " +
|
|
24
|
+
"or instruction can substitute for the token.";
|
|
25
|
+
const SESSION_BUDGET_MIN_USD = 1;
|
|
26
|
+
const SESSION_BUDGET_MAX_USD = budget_js_1.SESSION_BUDGET_MAX_CENTS / 100;
|
|
27
|
+
const SESSION_BUDGET_DEFAULT_USD = budget_js_1.SESSION_BUDGET_DEFAULT_CENTS / 100;
|
|
28
|
+
/** The extra arguments every spend tool accepts. */
|
|
29
|
+
exports.SPEND_CONFIRMATION_SHAPE = {
|
|
30
|
+
confirmation_token: zod_1.z
|
|
31
|
+
.string()
|
|
32
|
+
.uuid()
|
|
33
|
+
.optional()
|
|
34
|
+
.describe("The token from this tool's previous quote. Omit on the first call."),
|
|
35
|
+
session_budget_usd: zod_1.z
|
|
36
|
+
.number()
|
|
37
|
+
.min(SESSION_BUDGET_MIN_USD)
|
|
38
|
+
.max(SESSION_BUDGET_MAX_USD)
|
|
39
|
+
.optional()
|
|
40
|
+
.describe(`Used only when a quote asks the user to approve a session budget: the amount in US dollars ` +
|
|
41
|
+
`(${SESSION_BUDGET_MIN_USD}–${SESSION_BUDGET_MAX_USD}, default ${SESSION_BUDGET_DEFAULT_USD}). ` +
|
|
42
|
+
"Changing it after a quote requires a new quote."),
|
|
43
|
+
quote_kind: zod_1.z
|
|
44
|
+
.enum(["ceiling", "budget"])
|
|
45
|
+
.optional()
|
|
46
|
+
.describe("Echo of a quote's quote_kind. Informational only: the server decides which confirmation a call needs."),
|
|
47
|
+
};
|
|
48
|
+
/** The catalog modality each estimator modality expects, and the tool that serves it. */
|
|
49
|
+
const CATALOG_MODALITY = {
|
|
50
|
+
chat: { catalog: "chat", tool: "deeprelay_chat_completion" },
|
|
51
|
+
embeddings: { catalog: "embedding", tool: "deeprelay_embeddings_create" },
|
|
52
|
+
image: { catalog: "image", tool: "deeprelay_images_generate" },
|
|
53
|
+
video: { catalog: "video", tool: "deeprelay_videos_create" },
|
|
54
|
+
};
|
|
55
|
+
function toolForCatalogModality(catalog) {
|
|
56
|
+
return Object.values(CATALOG_MODALITY).find((m) => m.catalog === catalog)?.tool;
|
|
57
|
+
}
|
|
58
|
+
function dollars(microCents) {
|
|
59
|
+
return `$${(microCents / (budget_js_1.MICRO_CENTS_PER_CENT * 100)).toFixed(2)}`;
|
|
60
|
+
}
|
|
61
|
+
function usd(amount) {
|
|
62
|
+
return `$${amount.toFixed(2)}`;
|
|
63
|
+
}
|
|
64
|
+
function isToolResult(v) {
|
|
65
|
+
return Array.isArray(v.content);
|
|
66
|
+
}
|
|
67
|
+
function serialize(out, env, extra) {
|
|
68
|
+
if (isToolResult(out)) {
|
|
69
|
+
return out;
|
|
70
|
+
}
|
|
71
|
+
return (0, result_js_1.ok)({ lead: out.lead, ...out.payload, ...(extra ?? {}) }, { env });
|
|
72
|
+
}
|
|
73
|
+
/** Map the snake_case tool arguments onto the estimator's inputs. */
|
|
74
|
+
function toEstimateParams(args) {
|
|
75
|
+
return {
|
|
76
|
+
messages: args.messages,
|
|
77
|
+
maxTokens: args.max_tokens,
|
|
78
|
+
input: args.input,
|
|
79
|
+
n: args.n,
|
|
80
|
+
size: args.size,
|
|
81
|
+
seconds: args.seconds,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The two-call handshake with elicitation in front of it. No valid token means
|
|
86
|
+
* a quote comes back and nothing executes. With elicitation, "confirmed"
|
|
87
|
+
* re-enters the SAME handshake with the minted token, "declined" revokes the
|
|
88
|
+
* token and returns the quote marked declined, "unavailable" returns the quote.
|
|
89
|
+
* executeFn receives the token that authorized it (for idempotency keys).
|
|
90
|
+
*/
|
|
91
|
+
async function confirmThenExecute(toolName, params, quoteFn, executeFn, question, ctx) {
|
|
92
|
+
const env = ctx?.env ?? process.env;
|
|
93
|
+
const extra = {};
|
|
94
|
+
if (params.quote_kind !== undefined)
|
|
95
|
+
extra.quote_kind = params.quote_kind;
|
|
96
|
+
if (params.session_budget_usd !== undefined)
|
|
97
|
+
extra.session_budget_usd = params.session_budget_usd;
|
|
98
|
+
const presented = typeof params.confirmation_token === "string" ? params.confirmation_token : "";
|
|
99
|
+
const first = await (0, handshake_js_1.withSpendGuardrail)(toolName, params, quoteFn, (p) => executeFn(p, presented));
|
|
100
|
+
if (!(0, result_js_1.isQuoteResult)(first)) {
|
|
101
|
+
return first;
|
|
102
|
+
}
|
|
103
|
+
const answer = await (0, elicitation_js_1.elicitConfirmation)(ctx?.elicitation, first, question);
|
|
104
|
+
if (answer === "unavailable") {
|
|
105
|
+
return (0, result_js_1.quoteResult)(first, env, extra);
|
|
106
|
+
}
|
|
107
|
+
if (answer === "declined") {
|
|
108
|
+
// The user said no: that quote must not stay redeemable.
|
|
109
|
+
(0, handshake_js_1.revokeConfirmation)(first.confirmationToken);
|
|
110
|
+
return (0, result_js_1.quoteResult)({ ...first, declined: true }, env, extra);
|
|
111
|
+
}
|
|
112
|
+
const token = first.confirmationToken;
|
|
113
|
+
const confirmed = await (0, handshake_js_1.withSpendGuardrail)(toolName, { ...params, confirmation_token: token }, quoteFn, (p) => executeFn(p, token));
|
|
114
|
+
return (0, result_js_1.isQuoteResult)(confirmed) ? (0, result_js_1.quoteResult)(confirmed, env, extra) : confirmed;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* The budget-checked dispatch: ceiling → approval → wall → headroom
|
|
118
|
+
* (checkCall's order), then run, confirm this call, or confirm a budget.
|
|
119
|
+
*/
|
|
120
|
+
async function runWithBudget(o) {
|
|
121
|
+
const env = o.ctx?.env ?? process.env;
|
|
122
|
+
const { confirmation_token: token, quote_kind: _agentQuoteKind, session_budget_usd: requestedBudgetUsd, ...request } = o.parsed;
|
|
123
|
+
const estimate = (0, estimate_js_1.estimateMicroCents)(o.modality, toEstimateParams(request), o.rates);
|
|
124
|
+
// A model that publishes no rate for this modality cannot be priced, so the
|
|
125
|
+
// call is treated as over the ceiling and confirmed on its own.
|
|
126
|
+
const checked = estimate.pricingKnown ? estimate.microCents : Number.NaN;
|
|
127
|
+
const runFor = (confirmedBy) => {
|
|
128
|
+
const callId = (0, node_crypto_1.randomUUID)();
|
|
129
|
+
return {
|
|
130
|
+
callId,
|
|
131
|
+
idempotencyKey: confirmedBy !== undefined && confirmedBy !== "" ? confirmedBy : callId,
|
|
132
|
+
config: o.config,
|
|
133
|
+
rates: o.rates,
|
|
134
|
+
estimate,
|
|
135
|
+
env,
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
const summaryFor = (kind, decision, budgetUsd) => {
|
|
139
|
+
const parts = [`${o.describe}.`];
|
|
140
|
+
parts.push(estimate.pricingKnown
|
|
141
|
+
? `Estimated cost: ${dollars(estimate.microCents)}.`
|
|
142
|
+
: "This model publishes no rate for this kind of call, so it cannot be priced in advance.");
|
|
143
|
+
if (o.quoteNote !== undefined) {
|
|
144
|
+
parts.push(o.quoteNote);
|
|
145
|
+
}
|
|
146
|
+
else if (estimate.isFloor) {
|
|
147
|
+
parts.push("This is a floor, not a cap.");
|
|
148
|
+
}
|
|
149
|
+
parts.push(decision.reason);
|
|
150
|
+
if (kind === "ceiling") {
|
|
151
|
+
parts.push("Confirming runs this one call only. It does not approve a session budget.");
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
parts.push(`Confirming approves a ${usd(budgetUsd ?? SESSION_BUDGET_DEFAULT_USD)} session budget for all deeprelay ` +
|
|
155
|
+
"inference in this session (chat, embeddings, image and video) and runs this call. To choose another " +
|
|
156
|
+
`amount (${SESSION_BUDGET_MIN_USD}–${SESSION_BUDGET_MAX_USD} dollars), call again with session_budget_usd ` +
|
|
157
|
+
"instead of the token.");
|
|
158
|
+
}
|
|
159
|
+
parts.push("Call again with the same arguments plus confirmation_token only after the user agrees.");
|
|
160
|
+
return parts.join(" ");
|
|
161
|
+
};
|
|
162
|
+
const quoteOf = (kind, decision, budgetUsd) => async (p) => ({
|
|
163
|
+
summary: summaryFor(kind, decision, budgetUsd),
|
|
164
|
+
resolvedParams: p,
|
|
165
|
+
...(estimate.pricingKnown ? { estimateMicroCents: estimate.microCents } : {}),
|
|
166
|
+
isFloor: estimate.isFloor,
|
|
167
|
+
});
|
|
168
|
+
const executeRequest = async (p, confirmedBy) => {
|
|
169
|
+
const { quote_kind: _k, session_budget_usd: _b, confirmation_token: _t, ...req } = p;
|
|
170
|
+
return serialize(await o.execute(req, runFor(confirmedBy)), env);
|
|
171
|
+
};
|
|
172
|
+
const branchFor = (decision, budgetUsd) => {
|
|
173
|
+
if (decision.verdict === "over_ceiling") {
|
|
174
|
+
return {
|
|
175
|
+
params: { ...request, quote_kind: "ceiling" },
|
|
176
|
+
quoteFn: quoteOf("ceiling", decision),
|
|
177
|
+
executeFn: (p, t) => executeRequest(p, t),
|
|
178
|
+
question: o.question,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
params: { ...request, quote_kind: "budget", session_budget_usd: budgetUsd },
|
|
183
|
+
quoteFn: quoteOf("budget", decision, budgetUsd),
|
|
184
|
+
executeFn: async (p, t) => {
|
|
185
|
+
(0, budget_js_1.approveBudget)(Math.round(Number(p.session_budget_usd) * 100));
|
|
186
|
+
// Approval is never a way past the ceiling or the headroom: re-check.
|
|
187
|
+
const recheck = (0, budget_js_1.checkCall)(checked);
|
|
188
|
+
if (recheck.verdict !== "ok") {
|
|
189
|
+
return quoteOnly(recheck);
|
|
190
|
+
}
|
|
191
|
+
return executeRequest(p, t);
|
|
192
|
+
},
|
|
193
|
+
question: `Approve a ${usd(budgetUsd)} session budget for deeprelay inference and run this call at the price shown?`,
|
|
194
|
+
};
|
|
195
|
+
};
|
|
196
|
+
// A fresh quote with no elicitation, for a call that still is not runnable
|
|
197
|
+
// after a budget approval. Redeeming it is a new tool call, which re-enters
|
|
198
|
+
// runWithBudget from the top.
|
|
199
|
+
const quoteOnly = async (decision) => {
|
|
200
|
+
const branch = branchFor(decision, SESSION_BUDGET_DEFAULT_USD);
|
|
201
|
+
const q = await (0, handshake_js_1.withSpendGuardrail)(o.toolName, branch.params, branch.quoteFn, async () => {
|
|
202
|
+
throw new Error("unreachable: no token was presented");
|
|
203
|
+
});
|
|
204
|
+
if (!(0, result_js_1.isQuoteResult)(q)) {
|
|
205
|
+
throw new Error("unreachable: a token-less handshake call always quotes");
|
|
206
|
+
}
|
|
207
|
+
const extra = { quote_kind: branch.params.quote_kind, session_budget_usd: branch.params.session_budget_usd };
|
|
208
|
+
return (0, result_js_1.quoteResult)(q, env, extra);
|
|
209
|
+
};
|
|
210
|
+
const decision = (0, budget_js_1.checkCall)(checked);
|
|
211
|
+
if (decision.verdict === "ok") {
|
|
212
|
+
// Nothing to confirm. A stale token presented here must not stay redeemable.
|
|
213
|
+
if (typeof token === "string" && token !== "") {
|
|
214
|
+
(0, handshake_js_1.revokeConfirmation)(token);
|
|
215
|
+
}
|
|
216
|
+
const extra = requestedBudgetUsd !== undefined
|
|
217
|
+
? {
|
|
218
|
+
note: "session_budget_usd applies only when a quote asks for a session budget; the current budget is unchanged.",
|
|
219
|
+
}
|
|
220
|
+
: undefined;
|
|
221
|
+
const run = runFor();
|
|
222
|
+
return serialize(await o.execute(request, run), env, extra);
|
|
223
|
+
}
|
|
224
|
+
const budgetUsd = typeof requestedBudgetUsd === "number" ? requestedBudgetUsd : SESSION_BUDGET_DEFAULT_USD;
|
|
225
|
+
const branch = branchFor(decision, budgetUsd);
|
|
226
|
+
return confirmThenExecute(o.toolName, { ...branch.params, confirmation_token: token }, branch.quoteFn, branch.executeFn, branch.question, o.ctx);
|
|
227
|
+
}
|
|
228
|
+
const SPEND_ANNOTATIONS = Object.freeze({
|
|
229
|
+
readOnlyHint: false,
|
|
230
|
+
destructiveHint: false,
|
|
231
|
+
idempotentHint: false,
|
|
232
|
+
openWorldHint: true,
|
|
233
|
+
});
|
|
234
|
+
/** Wrap a billable inference call in the spend tier's quote → budget → confirm dispatch. */
|
|
235
|
+
function defineSpendTool(spec) {
|
|
236
|
+
const inputSchema = { ...spec.inputSchema, ...exports.SPEND_CONFIRMATION_SHAPE };
|
|
237
|
+
const schema = zod_1.z.strictObject(inputSchema);
|
|
238
|
+
const expected = CATALOG_MODALITY[spec.modality];
|
|
239
|
+
return {
|
|
240
|
+
name: spec.name,
|
|
241
|
+
tier: "spend",
|
|
242
|
+
title: spec.title,
|
|
243
|
+
description: `${spec.description.trim()} ${exports.SPEND_TIER_SENTENCE}`,
|
|
244
|
+
inputSchema,
|
|
245
|
+
annotations: { ...SPEND_ANNOTATIONS },
|
|
246
|
+
enabledAtBoot: true,
|
|
247
|
+
async handler(args, ctx) {
|
|
248
|
+
const env = ctx?.env ?? process.env;
|
|
249
|
+
let parsed;
|
|
250
|
+
let config;
|
|
251
|
+
try {
|
|
252
|
+
parsed = schema.parse(args ?? {});
|
|
253
|
+
config = (0, auth_js_1.buildConfiguration)(env);
|
|
254
|
+
}
|
|
255
|
+
catch (err) {
|
|
256
|
+
return (0, result_js_1.fail)((0, errors_js_1.mapSdkError)(err, spec.context, { env }), env);
|
|
257
|
+
}
|
|
258
|
+
try {
|
|
259
|
+
const modelId = String(parsed.model);
|
|
260
|
+
const rates = await (0, pricing_js_1.ratesFor)(config, modelId);
|
|
261
|
+
if (rates.modality !== undefined && rates.modality !== expected.catalog) {
|
|
262
|
+
const other = toolForCatalogModality(rates.modality);
|
|
263
|
+
throw new errors_js_1.QuoteUnavailableError(`Model "${modelId}" is a ${rates.modality} model, not a ${expected.catalog} model.` +
|
|
264
|
+
(other !== undefined ? ` Use ${other} for it.` : ""));
|
|
265
|
+
}
|
|
266
|
+
const typed = parsed;
|
|
267
|
+
return await runWithBudget({
|
|
268
|
+
toolName: spec.name,
|
|
269
|
+
modality: spec.modality,
|
|
270
|
+
parsed,
|
|
271
|
+
ctx,
|
|
272
|
+
config,
|
|
273
|
+
rates,
|
|
274
|
+
question: spec.question,
|
|
275
|
+
describe: spec.describe(typed),
|
|
276
|
+
quoteNote: spec.quoteNote,
|
|
277
|
+
execute: (req, run) => spec.execute(req, run),
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
catch (err) {
|
|
281
|
+
return (0, result_js_1.fail)(await (0, errors_js_1.mapSdkErrorAsync)(err, spec.context, env), env);
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
//# sourceMappingURL=define.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define.js","sourceRoot":"","sources":["../../../src/tools/spend/define.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ToolDefinition } from "../types.js";
|
|
2
|
+
import { mediaSpendTools } from "./media.js";
|
|
3
|
+
export { confirmThenExecute, defineSpendTool, runWithBudget, SPEND_CONFIRMATION_SHAPE, SPEND_TIER_SENTENCE, } from "./define.js";
|
|
4
|
+
export type { QuoteKind, SpendExecuted, SpendOutcome, SpendRun, SpendToolSpec } from "./define.js";
|
|
5
|
+
/** Upper bound on max_tokens for one chat call. */
|
|
6
|
+
export declare const CHAT_MAX_TOKENS_LIMIT = 8192;
|
|
7
|
+
/** Upper bound on the number of inputs in one embeddings call (keeps the response bounded). */
|
|
8
|
+
export declare const EMBEDDINGS_MAX_INPUTS = 64;
|
|
9
|
+
/** The spend tier, in SPEND_TOOLS order. */
|
|
10
|
+
export declare const spendTools: ToolDefinition[];
|
|
11
|
+
export { mediaSpendTools };
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mediaSpendTools = exports.spendTools = exports.EMBEDDINGS_MAX_INPUTS = exports.CHAT_MAX_TOKENS_LIMIT = exports.SPEND_TIER_SENTENCE = exports.SPEND_CONFIRMATION_SHAPE = exports.runWithBudget = exports.defineSpendTool = exports.confirmThenExecute = void 0;
|
|
4
|
+
// The spend tier: billable inference (Phase 104, D-02/D-06/D-07/D-08/D-10).
|
|
5
|
+
//
|
|
6
|
+
// Four tools, one session budget. Chat and embeddings are defined here; image
|
|
7
|
+
// generation and video create live in media.ts. Every one is built by
|
|
8
|
+
// defineSpendTool (define.ts), so pricing, the ceiling → approval → wall →
|
|
9
|
+
// headroom order and the confirmation handshake belong to the tier.
|
|
10
|
+
//
|
|
11
|
+
// Chat and embeddings settle synchronously: reserve the estimate, make the
|
|
12
|
+
// call, reconcile at the actual cost from the response's usage, or release the
|
|
13
|
+
// reservation if the call throws. They send no Idempotency-Key: the API does
|
|
14
|
+
// not accept one on these routes (RESEARCH Pitfall 3).
|
|
15
|
+
//
|
|
16
|
+
// The chat schema deliberately has no `tools` / `response_format`: the API
|
|
17
|
+
// passthrough for them has not landed (CONTEXT, Claude's Discretion), and
|
|
18
|
+
// `stream` is not an argument: the tool always sends stream: false, because an
|
|
19
|
+
// MCP tool result is one message.
|
|
20
|
+
const sdk_1 = require("@deeprelay/sdk");
|
|
21
|
+
const zod_1 = require("zod");
|
|
22
|
+
const budget_js_1 = require("../../guardrail/budget.js");
|
|
23
|
+
const estimate_js_1 = require("../../guardrail/estimate.js");
|
|
24
|
+
const define_js_1 = require("./define.js");
|
|
25
|
+
const media_js_1 = require("./media.js");
|
|
26
|
+
Object.defineProperty(exports, "mediaSpendTools", { enumerable: true, get: function () { return media_js_1.mediaSpendTools; } });
|
|
27
|
+
var define_js_2 = require("./define.js");
|
|
28
|
+
Object.defineProperty(exports, "confirmThenExecute", { enumerable: true, get: function () { return define_js_2.confirmThenExecute; } });
|
|
29
|
+
Object.defineProperty(exports, "defineSpendTool", { enumerable: true, get: function () { return define_js_2.defineSpendTool; } });
|
|
30
|
+
Object.defineProperty(exports, "runWithBudget", { enumerable: true, get: function () { return define_js_2.runWithBudget; } });
|
|
31
|
+
Object.defineProperty(exports, "SPEND_CONFIRMATION_SHAPE", { enumerable: true, get: function () { return define_js_2.SPEND_CONFIRMATION_SHAPE; } });
|
|
32
|
+
Object.defineProperty(exports, "SPEND_TIER_SENTENCE", { enumerable: true, get: function () { return define_js_2.SPEND_TIER_SENTENCE; } });
|
|
33
|
+
/** Upper bound on max_tokens for one chat call. */
|
|
34
|
+
exports.CHAT_MAX_TOKENS_LIMIT = 8192;
|
|
35
|
+
const chatCompletion = (0, define_js_1.defineSpendTool)({
|
|
36
|
+
name: "deeprelay_chat_completion",
|
|
37
|
+
title: "Chat completion",
|
|
38
|
+
description: "Run one chat completion on a deeprelay chat model and return the assistant's reply, token usage and cost. " +
|
|
39
|
+
"Priced per token from the model's catalog rates: the quote bounds the cost by max_tokens (default " +
|
|
40
|
+
`${estimate_js_1.DEFAULT_MAX_TOKENS}), and the session budget settles at the actual usage. Use deeprelay_models_list ` +
|
|
41
|
+
"(modality chat) to find a model id. Returns one complete message; streaming is not offered.",
|
|
42
|
+
inputSchema: {
|
|
43
|
+
model: zod_1.z.string().min(1).describe("A chat model id from deeprelay_models_list."),
|
|
44
|
+
messages: zod_1.z
|
|
45
|
+
.array(zod_1.z.strictObject({
|
|
46
|
+
role: zod_1.z.enum(["system", "user", "assistant"]),
|
|
47
|
+
content: zod_1.z.string(),
|
|
48
|
+
}))
|
|
49
|
+
.min(1)
|
|
50
|
+
.describe("The conversation so far, oldest first."),
|
|
51
|
+
max_tokens: zod_1.z
|
|
52
|
+
.number()
|
|
53
|
+
.int()
|
|
54
|
+
.min(1)
|
|
55
|
+
.max(exports.CHAT_MAX_TOKENS_LIMIT)
|
|
56
|
+
.default(estimate_js_1.DEFAULT_MAX_TOKENS)
|
|
57
|
+
.describe(`Upper bound on generated tokens (1–${exports.CHAT_MAX_TOKENS_LIMIT}, default ${estimate_js_1.DEFAULT_MAX_TOKENS}). It also bounds the quote.`),
|
|
58
|
+
temperature: zod_1.z.number().min(0).max(2).optional().describe("Sampling temperature, 0–2."),
|
|
59
|
+
},
|
|
60
|
+
modality: "chat",
|
|
61
|
+
question: "Run this chat completion at the price shown?",
|
|
62
|
+
context: "running a chat completion",
|
|
63
|
+
describe: (a) => `Chat completion on ${a.model}: ${a.messages.length} message(s), up to ${a.max_tokens} output tokens`,
|
|
64
|
+
async execute(a, run) {
|
|
65
|
+
(0, budget_js_1.recordEstimate)(run.callId, run.estimate.microCents);
|
|
66
|
+
let res;
|
|
67
|
+
let actual;
|
|
68
|
+
try {
|
|
69
|
+
res = await new sdk_1.InferenceApi(run.config).createChatCompletion({
|
|
70
|
+
chatCompletionRequest: {
|
|
71
|
+
model: a.model,
|
|
72
|
+
messages: a.messages,
|
|
73
|
+
temperature: a.temperature,
|
|
74
|
+
maxTokens: a.max_tokens,
|
|
75
|
+
stream: false,
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
actual = (0, estimate_js_1.actualMicroCents)("chat", res.usage, run.rates, run.estimate.microCents);
|
|
79
|
+
(0, budget_js_1.reconcileActual)(run.callId, actual);
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
(0, budget_js_1.releaseEstimate)(run.callId);
|
|
83
|
+
throw err;
|
|
84
|
+
}
|
|
85
|
+
const choice = res.choices?.[0];
|
|
86
|
+
return {
|
|
87
|
+
lead: `Chat completion finished (${choice?.finishReason ?? "no finish reason reported"}).`,
|
|
88
|
+
payload: {
|
|
89
|
+
model: res.model,
|
|
90
|
+
finish_reason: choice?.finishReason ?? null,
|
|
91
|
+
message: choice?.message ?? null,
|
|
92
|
+
usage: {
|
|
93
|
+
prompt_tokens: res.usage?.promptTokens,
|
|
94
|
+
completion_tokens: res.usage?.completionTokens,
|
|
95
|
+
total_tokens: res.usage?.totalTokens,
|
|
96
|
+
},
|
|
97
|
+
cost: { estimated_micro_cents: run.estimate.microCents, actual_micro_cents: actual },
|
|
98
|
+
session_budget: (0, budget_js_1.budgetStatus)(),
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
/** Upper bound on the number of inputs in one embeddings call (keeps the response bounded). */
|
|
104
|
+
exports.EMBEDDINGS_MAX_INPUTS = 64;
|
|
105
|
+
const embeddingsCreate = (0, define_js_1.defineSpendTool)({
|
|
106
|
+
name: "deeprelay_embeddings_create",
|
|
107
|
+
title: "Create embeddings",
|
|
108
|
+
description: "Embed one string or a list of up to 64 strings with a deeprelay embedding model and return the vectors, " +
|
|
109
|
+
"token usage and cost. Priced per input token from the model's catalog rate; the session budget settles at " +
|
|
110
|
+
"the actual prompt tokens. Use deeprelay_models_list (modality embedding) to find a model id.",
|
|
111
|
+
inputSchema: {
|
|
112
|
+
model: zod_1.z.string().min(1).describe("An embedding model id from deeprelay_models_list."),
|
|
113
|
+
input: zod_1.z
|
|
114
|
+
.union([
|
|
115
|
+
zod_1.z.string().min(1),
|
|
116
|
+
zod_1.z.array(zod_1.z.string().min(1)).min(1).max(exports.EMBEDDINGS_MAX_INPUTS),
|
|
117
|
+
])
|
|
118
|
+
.describe(`One non-empty string, or 1–${exports.EMBEDDINGS_MAX_INPUTS} non-empty strings.`),
|
|
119
|
+
dimensions: zod_1.z.number().int().positive().optional().describe("Output dimensions, for models that support it."),
|
|
120
|
+
encoding_format: zod_1.z.enum(["float"]).optional().describe("Only float is offered."),
|
|
121
|
+
},
|
|
122
|
+
modality: "embeddings",
|
|
123
|
+
question: "Create these embeddings at the price shown?",
|
|
124
|
+
context: "creating embeddings",
|
|
125
|
+
describe: (a) => `Embeddings on ${a.model}: ${typeof a.input === "string" ? 1 : a.input.length} input(s)`,
|
|
126
|
+
async execute(a, run) {
|
|
127
|
+
(0, budget_js_1.recordEstimate)(run.callId, run.estimate.microCents);
|
|
128
|
+
let res;
|
|
129
|
+
let actual;
|
|
130
|
+
try {
|
|
131
|
+
res = await new sdk_1.InferenceApi(run.config).createEmbeddings({
|
|
132
|
+
embeddingsRequest: {
|
|
133
|
+
model: a.model,
|
|
134
|
+
input: a.input,
|
|
135
|
+
dimensions: a.dimensions,
|
|
136
|
+
encodingFormat: a.encoding_format,
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
actual = (0, estimate_js_1.actualMicroCents)("embeddings", res.usage, run.rates, run.estimate.microCents);
|
|
140
|
+
(0, budget_js_1.reconcileActual)(run.callId, actual);
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
(0, budget_js_1.releaseEstimate)(run.callId);
|
|
144
|
+
throw err;
|
|
145
|
+
}
|
|
146
|
+
const data = res.data ?? [];
|
|
147
|
+
return {
|
|
148
|
+
lead: `Created ${data.length} embedding(s).`,
|
|
149
|
+
payload: {
|
|
150
|
+
model: res.model,
|
|
151
|
+
count: data.length,
|
|
152
|
+
dimensions: data[0]?.embedding.length,
|
|
153
|
+
embeddings: data.map((e) => e.embedding),
|
|
154
|
+
usage: { prompt_tokens: res.usage?.promptTokens, total_tokens: res.usage?.totalTokens },
|
|
155
|
+
cost: { estimated_micro_cents: run.estimate.microCents, actual_micro_cents: actual },
|
|
156
|
+
session_budget: (0, budget_js_1.budgetStatus)(),
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
/** The spend tier, in SPEND_TOOLS order. */
|
|
162
|
+
exports.spendTools = [chatCompletion, embeddingsCreate, ...media_js_1.mediaSpendTools];
|
|
163
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/spend/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ToolDefinition } from "../types.js";
|
|
2
|
+
export declare const IMAGE_MAX_COUNT = 4;
|
|
3
|
+
export declare const VIDEO_MAX_SECONDS = 30;
|
|
4
|
+
/** The floor wording every video quote carries (D-07). */
|
|
5
|
+
export declare const VIDEO_FLOOR_NOTE = "This is a floor, not a cap \u2014 the final charge is known when the job completes.";
|
|
6
|
+
/** The image's MIME type from its base64 signature; PNG when unrecognized. */
|
|
7
|
+
export declare function imageMimeType(b64: string): string;
|
|
8
|
+
/** Image then video, in SPEND_TOOLS order. */
|
|
9
|
+
export declare const mediaSpendTools: ToolDefinition[];
|