agentcash 0.7.7 → 0.8.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 +1 -1
- package/dist/cjs/run-server.cjs +59 -28
- package/dist/esm/{chunk-5EMDWOPZ.js → chunk-4R52CY5Q.js} +23 -23
- package/dist/esm/chunk-4R52CY5Q.js.map +1 -0
- package/dist/esm/{chunk-2XMLNLWS.js → chunk-5ELAEV2M.js} +9 -7
- package/dist/esm/{chunk-2XMLNLWS.js.map → chunk-5ELAEV2M.js.map} +1 -1
- package/dist/esm/{chunk-SRV57WB2.js → chunk-62B3GENJ.js} +8 -6
- package/dist/esm/{chunk-SRV57WB2.js.map → chunk-62B3GENJ.js.map} +1 -1
- package/dist/esm/{chunk-TRPO7BKD.js → chunk-6PU3XK6I.js} +8 -228
- package/dist/esm/chunk-6PU3XK6I.js.map +1 -0
- package/dist/esm/{chunk-FLIDR6EU.js → chunk-7ZEXMJYJ.js} +5 -3
- package/dist/esm/{chunk-FLIDR6EU.js.map → chunk-7ZEXMJYJ.js.map} +1 -1
- package/dist/esm/{chunk-QPL3AVUK.js → chunk-C36IAW7R.js} +5 -3
- package/dist/esm/{chunk-QPL3AVUK.js.map → chunk-C36IAW7R.js.map} +1 -1
- package/dist/esm/chunk-FBPC4LGY.js +7 -0
- package/dist/esm/{chunk-PWYZN62H.js → chunk-OHA3LLUQ.js} +3 -3
- package/dist/esm/{chunk-24E2V3PA.js → chunk-UN3PRLTL.js} +15 -43
- package/dist/esm/chunk-UN3PRLTL.js.map +1 -0
- package/dist/esm/{chunk-JKCEMNAF.js → chunk-VR5I67WE.js} +2 -2
- package/dist/esm/{chunk-XNU6FVCF.js → chunk-W7DAJMFQ.js} +87 -19
- package/dist/esm/chunk-W7DAJMFQ.js.map +1 -0
- package/dist/esm/chunk-YQFK4U62.js +230 -0
- package/dist/esm/chunk-YQFK4U62.js.map +1 -0
- package/dist/esm/{chunk-X6KM3YLG.js → chunk-Z2R7VYNM.js} +11 -9
- package/dist/esm/{chunk-X6KM3YLG.js.map → chunk-Z2R7VYNM.js.map} +1 -1
- package/dist/esm/chunk-ZDDDU5O2.js +41 -0
- package/dist/esm/chunk-ZDDDU5O2.js.map +1 -0
- package/dist/esm/{chunk-KPEJO3KV.js → chunk-ZOVLXKVL.js} +8 -8
- package/dist/esm/chunk-ZOVLXKVL.js.map +1 -0
- package/dist/esm/{commands-IFU565JX.js → commands-YSOBBE4N.js} +625 -504
- package/dist/esm/commands-YSOBBE4N.js.map +1 -0
- package/dist/esm/{fund-N47ZRBRZ.js → fund-PRV53MDA.js} +7 -5
- package/dist/esm/{fund-N47ZRBRZ.js.map → fund-PRV53MDA.js.map} +1 -1
- package/dist/esm/index.js +65 -23
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/{install-WJ645IFJ.js → install-QT37XD4R.js} +10 -8
- package/dist/esm/{install-WJ645IFJ.js.map → install-QT37XD4R.js.map} +1 -1
- package/dist/esm/lib.js +4 -3
- package/dist/esm/{server-VU3UAM7K.js → server-QARME5NA.js} +26 -19
- package/dist/esm/server-QARME5NA.js.map +1 -0
- package/dist/esm/shared/operations/index.js +7 -6
- package/dist/esm/shared/operations/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/esm/chunk-24E2V3PA.js.map +0 -1
- package/dist/esm/chunk-5EMDWOPZ.js.map +0 -1
- package/dist/esm/chunk-KPEJO3KV.js.map +0 -1
- package/dist/esm/chunk-L7FC4RVF.js +0 -7
- package/dist/esm/chunk-TRPO7BKD.js.map +0 -1
- package/dist/esm/chunk-XNU6FVCF.js.map +0 -1
- package/dist/esm/commands-IFU565JX.js.map +0 -1
- package/dist/esm/server-VU3UAM7K.js.map +0 -1
- /package/dist/esm/{chunk-L7FC4RVF.js.map → chunk-FBPC4LGY.js.map} +0 -0
- /package/dist/esm/{chunk-PWYZN62H.js.map → chunk-OHA3LLUQ.js.map} +0 -0
- /package/dist/esm/{chunk-JKCEMNAF.js.map → chunk-VR5I67WE.js.map} +0 -0
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
safeParseJson
|
|
3
|
+
} from "./chunk-ZDDDU5O2.js";
|
|
4
|
+
import {
|
|
5
|
+
configFile
|
|
6
|
+
} from "./chunk-6PU3XK6I.js";
|
|
7
|
+
|
|
1
8
|
// src/shared/origins.ts
|
|
2
9
|
var ORIGINS = [
|
|
3
10
|
"https://stableenrich.dev" /* StableEnrich */,
|
|
@@ -108,28 +115,33 @@ ${PRIMARY_ORIGINS.flatMap((o) => ORIGIN_METADATA[o] ? [` ${o} \u2014 ${ORIGIN_M
|
|
|
108
115
|
reportError: {
|
|
109
116
|
mcp: `EMERGENCY ONLY. Report critical MCP tool bugs. Do NOT use for normal errors (balance, network, 4xx) \u2014 those are recoverable.`,
|
|
110
117
|
cli: `Report a critical bug to the agentcash team (emergency only). Do NOT use for normal errors like low balance, network timeouts, or 4xx responses \u2014 those are recoverable without filing a report.`
|
|
111
|
-
}
|
|
112
|
-
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
var WORKFLOW = [
|
|
121
|
+
`Workflow:`,
|
|
122
|
+
`1. If you don't already know your balance, call get_wallet_info. You need a balance for paid endpoints \u2014 if it's zero, share the deposit link with the user. SIWX endpoints don't require a balance. You don't need to call this every turn, just before your first paid call or whenever you're unsure.`,
|
|
123
|
+
`2. Call discover_api_endpoints() to get the endpoint index \u2014 a list of available routes with descriptions and auth modes. The auth mode for each endpoint tells you whether to use fetch (paid) or fetch_with_auth (SIWX).`,
|
|
124
|
+
`3. Call check_endpoint_schema() to get the exact input/output schema and auth mode for the endpoint you want to call, so you know what fields to pass and what the response contains. Both discover_api_endpoints and check_endpoint_schema return the auth mode.`,
|
|
125
|
+
`4. Call fetch (paid) or fetch_with_auth (SIWX) based on the auth mode, and with the correct input schema.`
|
|
126
|
+
].join("\n");
|
|
127
|
+
function buildServerInstructions(userOrigins = []) {
|
|
128
|
+
const allOrigins = [
|
|
129
|
+
...userOrigins.map((o) => ` - ${o.url} \u2014 ${o.description}`),
|
|
130
|
+
...PRIMARY_ORIGINS.flatMap(
|
|
131
|
+
(o) => ORIGIN_METADATA[o] ? [` - ${o} \u2014 ${ORIGIN_METADATA[o].description}`] : []
|
|
132
|
+
)
|
|
133
|
+
].join("\n");
|
|
134
|
+
return [
|
|
113
135
|
`AgentCash lets you call protected APIs \u2014 handling both x402 micropayments and SIWX authentication seamlessly. It manages a USDC wallet for paid endpoints (fetch) and signs wallet proofs for identity-gated endpoints (fetch_with_auth).`,
|
|
114
136
|
`The user has installed agentcash because they want to use paid and SIWX-protected APIs as their preferred way to accomplish related tasks.`,
|
|
115
137
|
`Paid endpoints require a wallet balance. SIWX endpoints are free \u2014 they only require a wallet identity.`,
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
...PRIMARY_ORIGINS.flatMap(
|
|
119
|
-
(o) => ORIGIN_METADATA[o] ? [` - ${o} \u2014 ${ORIGIN_METADATA[o].description}`] : []
|
|
120
|
-
)
|
|
121
|
-
].join("\n"),
|
|
138
|
+
`If a task could be accomplished by one of these registered origins, run the workflow below:
|
|
139
|
+
${allOrigins}`,
|
|
122
140
|
`discover_api_endpoints also works with any origin beyond this list. If you identify another origin that would be useful for a task, you can use it.`,
|
|
123
|
-
|
|
124
|
-
`Workflow:`,
|
|
125
|
-
`1. If you don't already know your balance, call get_wallet_info. You need a balance for paid endpoints \u2014 if it's zero, share the deposit link with the user. SIWX endpoints don't require a balance. You don't need to call this every turn, just before your first paid call or whenever you're unsure.`,
|
|
126
|
-
`2. Call discover_api_endpoints() to get the endpoint index \u2014 a list of available routes with descriptions and auth modes. The auth mode for each endpoint tells you whether to use fetch (paid) or fetch_with_auth (SIWX).`,
|
|
127
|
-
`3. Call check_endpoint_schema() to get the exact input/output schema and auth mode for the endpoint you want to call, so you know what fields to pass and what the response contains. Both discover_api_endpoints and check_endpoint_schema return the auth mode.`,
|
|
128
|
-
`4. Call fetch (paid) or fetch_with_auth (SIWX) based on the auth mode, and with the correct input schema.`
|
|
129
|
-
].join("\n"),
|
|
141
|
+
WORKFLOW,
|
|
130
142
|
`If you need to compose multiple endpoints in sequence, or anything about the origin's capabilities is unclear, call discover_api_endpoints with include_guidance=true to retrieve the origin's full usage documentation.`
|
|
131
|
-
].join("\n\n")
|
|
132
|
-
}
|
|
143
|
+
].join("\n\n");
|
|
144
|
+
}
|
|
133
145
|
var REQUEST_PARAMS = {
|
|
134
146
|
url: "The endpoint URL",
|
|
135
147
|
method: "HTTP method. Defaults to GET for fetch operations.",
|
|
@@ -188,11 +200,67 @@ var TOOL_PARAMS = {
|
|
|
188
200
|
}
|
|
189
201
|
};
|
|
190
202
|
|
|
203
|
+
// src/shared/user-origins.ts
|
|
204
|
+
import * as fs from "fs";
|
|
205
|
+
import z from "zod";
|
|
206
|
+
var ORIGINS_FILE = configFile("origins.json");
|
|
207
|
+
var userOriginSchema = z.object({
|
|
208
|
+
url: z.string(),
|
|
209
|
+
title: z.string(),
|
|
210
|
+
description: z.string(),
|
|
211
|
+
addedAt: z.string()
|
|
212
|
+
});
|
|
213
|
+
var originsFileSchema = z.object({
|
|
214
|
+
added: z.array(userOriginSchema)
|
|
215
|
+
});
|
|
216
|
+
function readOriginsFile() {
|
|
217
|
+
if (!fs.existsSync(ORIGINS_FILE)) return [];
|
|
218
|
+
const raw = fs.readFileSync(ORIGINS_FILE, "utf-8");
|
|
219
|
+
const json = safeParseJson("user-origins", raw);
|
|
220
|
+
if (!json.isOk()) return [];
|
|
221
|
+
const parsed = originsFileSchema.safeParse(json.value);
|
|
222
|
+
return parsed.success ? parsed.data.added : [];
|
|
223
|
+
}
|
|
224
|
+
function writeOriginsFile(origins) {
|
|
225
|
+
fs.writeFileSync(
|
|
226
|
+
ORIGINS_FILE,
|
|
227
|
+
JSON.stringify({ added: origins }, null, 2),
|
|
228
|
+
"utf-8"
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
function loadUserOrigins() {
|
|
232
|
+
return readOriginsFile();
|
|
233
|
+
}
|
|
234
|
+
function addUserOrigin(origin) {
|
|
235
|
+
const origins = readOriginsFile();
|
|
236
|
+
const entry = { ...origin, addedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
237
|
+
const existing = origins.findIndex((o) => o.url === origin.url);
|
|
238
|
+
if (existing >= 0) {
|
|
239
|
+
origins[existing] = entry;
|
|
240
|
+
} else {
|
|
241
|
+
origins.push(entry);
|
|
242
|
+
}
|
|
243
|
+
writeOriginsFile(origins);
|
|
244
|
+
return entry;
|
|
245
|
+
}
|
|
246
|
+
function removeUserOrigin(url) {
|
|
247
|
+
const origins = readOriginsFile();
|
|
248
|
+
const filtered = origins.filter((o) => o.url !== url);
|
|
249
|
+
if (filtered.length === origins.length) return { removed: false };
|
|
250
|
+
writeOriginsFile(filtered);
|
|
251
|
+
return { removed: true };
|
|
252
|
+
}
|
|
253
|
+
|
|
191
254
|
export {
|
|
192
255
|
ORIGINS,
|
|
193
256
|
ORIGIN_METADATA,
|
|
257
|
+
PRIMARY_ORIGINS,
|
|
194
258
|
DESCRIPTIONS,
|
|
259
|
+
buildServerInstructions,
|
|
195
260
|
REQUEST_PARAMS,
|
|
196
|
-
TOOL_PARAMS
|
|
261
|
+
TOOL_PARAMS,
|
|
262
|
+
loadUserOrigins,
|
|
263
|
+
addUserOrigin,
|
|
264
|
+
removeUserOrigin
|
|
197
265
|
};
|
|
198
|
-
//# sourceMappingURL=chunk-
|
|
266
|
+
//# sourceMappingURL=chunk-W7DAJMFQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/shared/origins.ts","../../src/shared/descriptions.ts","../../src/shared/user-origins.ts"],"sourcesContent":["/**\n * Known x402-protected API origins.\n * Using const enum so values are inlined at build time.\n */\nexport const enum Origin {\n StableEnrich = 'https://stableenrich.dev',\n StableSocial = 'https://stablesocial.dev',\n StableStudio = 'https://stablestudio.dev',\n StableUpload = 'https://stableupload.dev',\n StableEmail = 'https://stableemail.dev',\n X402Scan = 'https://x402scan.com',\n Shirt = 'https://shirt.sh',\n X402Puppet = 'https://x402puppet.com',\n X402Facilitator = 'https://x402facilitator.com',\n}\n\n/**\n * Array of all known origins for iteration.\n * Const enums are erased at compile time, so we need a regular array for runtime iteration.\n */\nexport const ORIGINS = [\n Origin.StableEnrich,\n Origin.StableSocial,\n Origin.StableStudio,\n Origin.StableUpload,\n Origin.StableEmail,\n Origin.X402Scan,\n Origin.Shirt,\n Origin.X402Puppet,\n] as const;\n","/**\n * Single source of truth for all LLM-facing text in the MCP package.\n *\n * `DESCRIPTIONS` covers every tool with both an `mcp` variant (detailed,\n * AI-audience) and a `cli` variant (concise, human-readable for --help).\n * `serverInstructions` is shared across both surfaces.\n *\n * Additional exports cover parameter/output schema descriptions, origin\n * metadata, and prompt content — all LLM-facing text in one place.\n */\n\nimport { Origin } from './origins';\nimport type { UserOrigin } from './user-origins';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Origin metadata (used for MCP resource registration descriptions)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const ORIGIN_METADATA: Record<\n string,\n { title: string; description: string }\n> = {\n [Origin.StableEnrich]: {\n title: 'StableEnrich',\n description:\n 'People/org search, Google Maps, Grok twitter search, Exa web search, LinkedIn data, Firecrawl scrape, WhitePages, email enrichment',\n },\n [Origin.StableSocial]: {\n title: 'StableSocial',\n description:\n 'Social media data for Twitter, Instagram, TikTok, YouTube, Facebook, Reddit',\n },\n [Origin.StableStudio]: {\n title: 'StableStudio',\n description: 'Generate and edit images and videos',\n },\n [Origin.StableUpload]: {\n title: 'StableUpload',\n description: 'Pay to upload files, get a permanent download URL.',\n },\n [Origin.StableEmail]: {\n title: 'StableEmail',\n description: 'Send emails',\n },\n [Origin.X402Scan]: {\n title: 'X402 Scan',\n description: 'x402 protocol explorer',\n },\n [Origin.Shirt]: {\n title: 'Shirt',\n description: 'Shirt.sh',\n },\n [Origin.X402Puppet]: {\n title: 'X402 Puppet',\n description: 'Browser automation',\n },\n [Origin.X402Facilitator]: {\n title: 'X402 Facilitator',\n description: 'Payment facilitation',\n },\n};\n\nexport const PRIMARY_ORIGINS = [\n Origin.StableEnrich,\n Origin.StableSocial,\n Origin.StableStudio,\n Origin.StableUpload,\n Origin.StableEmail,\n] as const;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Tool descriptions — { mcp, cli } per tool + shared serverInstructions\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const DESCRIPTIONS = {\n fetch: {\n mcp: `HTTP fetch with automatic x402 payment handling. Makes the request and, if the endpoint returns 402, signs payment and retries with payment headers. Returns response data along with payment details (price, tx hash) if a payment was made.\\n\\nFor endpoints you haven't called before in this session, you MUST call check_endpoint_schema first to confirm the request body schema. Skipping this causes 400 errors from wrong field names.`,\n cli: `HTTP fetch with automatic x402 payment handling. If the endpoint returns 402, signs payment and retries — no manual payment steps needed. Run 'check <url>' first to confirm the request body schema; skipping this causes 400 errors from wrong field names.`,\n epilogue: `Workflow: check <url> → fetch <url> -m POST -b '{\"field\":\"value\"}'\\nUse 'fetch-auth' instead if the endpoint requires identity (SIWX) rather than payment.`,\n },\n\n fetchWithAuth: {\n mcp: `HTTP fetch with automatic SIWX (Sign-In With X) authentication. Sends an authenticated request to a SIWX-protected endpoint. Returns response data gated by the endpoint's authentication requirements.\\n\\nFor endpoints you haven't called before in this session, you MUST call check_endpoint_schema first to confirm the request body schema. Skipping this causes 400 errors from wrong field names.`,\n cli: `HTTP fetch with automatic SIWX (Sign-In With X) authentication for identity-gated endpoints. No payment required — the wallet is used as an identity proof only. Run 'check <url>' first to confirm the request body schema; skipping this causes 400 errors from wrong field names.`,\n epilogue: `Workflow: check <url> → fetch-auth <url> -m POST -b '{\"field\":\"value\"}'\\nUse 'fetch' instead if the endpoint requires payment (x402) rather than identity.`,\n },\n\n getWalletInfo: {\n mcp: `Get wallet address and USDC balance. Auto-creates wallet on first use (~/.agentcash/wallet.json). Returns a deposit link if funding is needed. If onboardingCta is present, show its message to the user — it means they haven't onboarded yet and need to either visit the onboard link or deposit directly.`,\n cli: `Get wallet address, USDC balance, and deposit link. Creates the wallet on first use (~/.agentcash/wallet.json). Check this before making paid API calls — if balance is zero, deposit USDC using the returned link.`,\n },\n\n checkEndpointSchema: {\n mcp: [\n `Get the input/output schema and auth mode (paid or SIWX) for a single endpoint.`,\n `Call this to see exactly what fields the request body expects and what the response contains.`,\n `Returns the schema from the origin's OpenAPI spec. Optionally pass sample_input_body to probe the endpoint live (without payment) for an exact price quote — do this when pricing is range-based or quote-based, or when you're unsure about the input schema.`,\n ].join('\\n\\n'),\n cli: `Get the input/output schema and auth mode (paid or SIWX) for an endpoint. Returns exact field names from the OpenAPI spec — call this before 'fetch' or 'fetch-auth' to avoid 400 errors. Pass --body to probe the endpoint live for an exact price quote when pricing is range-based or unclear.`,\n epilogue: `Auth mode tells you which command to use:\\n paid → agentcash fetch <url>\\n SIWX → agentcash fetch-auth <url>`,\n },\n\n discoverApiEndpoints: {\n mcp: [\n `List available endpoints at an API origin. Returns endpoint URLs with descriptions of what each does and the auth mode for each (paid or SIWX). Works with any origin, not just the registered ones.`,\n `Call this when you need to see what routes are available at an origin — whether it's one of the registered origins or any other origin you've identified as useful.`,\n `The response always indicates whether guidance is available. Guidance is documentation published by the API provider explaining how endpoints work together, edge cases, and usage tips. compact guidance is included automatically; set include_guidance=true to force-include full usage documentation when you need to compose two or more endpoints or need clarification on how the origin works.`,\n ].join('\\n\\n'),\n cli: `List available endpoints at an API origin with descriptions and auth modes (paid or SIWX). Works with any origin, not just registered ones. Add --include-guidance for full provider docs when composing multiple endpoints or when usage is unclear.`,\n epilogue: `Registered origins:\\n${PRIMARY_ORIGINS.flatMap(o => (ORIGIN_METADATA[o] ? [` ${o} — ${ORIGIN_METADATA[o].description}`] : [])).join('\\n')}`,\n },\n\n redeemInvite: {\n mcp: `Redeem an invite code for free USDC on Base. One-time use per code. Returns amount received and transaction hash. Use get_wallet_info after to verify balance.`,\n cli: `Redeem an invite code for free USDC on Base. One-time use per code. Run 'wallet info' after to verify the balance landed.`,\n },\n\n try: {\n cli: `Fetch a new origin for its resources and return a prompt guiding the user through the process of calling the first endpoint.`,\n },\n\n reportError: {\n mcp: `EMERGENCY ONLY. Report critical MCP tool bugs. Do NOT use for normal errors (balance, network, 4xx) — those are recoverable.`,\n cli: `Report a critical bug to the agentcash team (emergency only). Do NOT use for normal errors like low balance, network timeouts, or 4xx responses — those are recoverable without filing a report.`,\n },\n} as const;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Dynamic server instructions (includes user-added origins at runtime)\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst WORKFLOW = [\n `Workflow:`,\n `1. If you don't already know your balance, call get_wallet_info. You need a balance for paid endpoints — if it's zero, share the deposit link with the user. SIWX endpoints don't require a balance. You don't need to call this every turn, just before your first paid call or whenever you're unsure.`,\n `2. Call discover_api_endpoints() to get the endpoint index — a list of available routes with descriptions and auth modes. The auth mode for each endpoint tells you whether to use fetch (paid) or fetch_with_auth (SIWX).`,\n `3. Call check_endpoint_schema() to get the exact input/output schema and auth mode for the endpoint you want to call, so you know what fields to pass and what the response contains. Both discover_api_endpoints and check_endpoint_schema return the auth mode.`,\n `4. Call fetch (paid) or fetch_with_auth (SIWX) based on the auth mode, and with the correct input schema.`,\n].join('\\n');\n\nexport function buildServerInstructions(\n userOrigins: UserOrigin[] = []\n): string {\n const allOrigins = [\n ...userOrigins.map(o => ` - ${o.url} — ${o.description}`),\n ...PRIMARY_ORIGINS.flatMap(o =>\n ORIGIN_METADATA[o] ? [` - ${o} — ${ORIGIN_METADATA[o].description}`] : []\n ),\n ].join('\\n');\n\n return [\n `AgentCash lets you call protected APIs — handling both x402 micropayments and SIWX authentication seamlessly. It manages a USDC wallet for paid endpoints (fetch) and signs wallet proofs for identity-gated endpoints (fetch_with_auth).`,\n `The user has installed agentcash because they want to use paid and SIWX-protected APIs as their preferred way to accomplish related tasks.`,\n `Paid endpoints require a wallet balance. SIWX endpoints are free — they only require a wallet identity.`,\n `If a task could be accomplished by one of these registered origins, run the workflow below:\\n${allOrigins}`,\n `discover_api_endpoints also works with any origin beyond this list. If you identify another origin that would be useful for a task, you can use it.`,\n WORKFLOW,\n `If you need to compose multiple endpoints in sequence, or anything about the origin's capabilities is unclear, call discover_api_endpoints with include_guidance=true to retrieve the origin's full usage documentation.`,\n ].join('\\n\\n');\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Shared request schema parameter descriptions\n// (used by fetch, fetch_with_auth tools)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const REQUEST_PARAMS = {\n url: 'The endpoint URL',\n method: 'HTTP method. Defaults to GET for fetch operations.',\n body: 'Request body for POST/PUT/PATCH methods',\n headers: 'Additional headers to include',\n timeout: 'Request timeout in milliseconds',\n} as const;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Per-tool parameter and output schema descriptions\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const TOOL_PARAMS = {\n fetch: {\n paymentMethod: 'Payment protocol to use. Defaults to auto-detect.',\n },\n\n checkEndpointSchema: {\n url: 'Full URL of the endpoint to inspect',\n method:\n 'HTTP method to check. If omitted, all methods declared in the spec are returned.',\n sampleInputBody:\n 'Optional. A sample request body to probe the endpoint live (without payment) for exact pricing. Use when pricing is range-based or quote-based, or when you need to verify the input schema. Omit to get the static schema and advisory pricing from the spec.',\n headers: 'Additional headers to include in the probe request',\n },\n\n getWalletInfo: {\n output: {\n address: 'Wallet address (0x...)',\n balance: 'Total USDC balance across all chains',\n chains: 'Balance breakdown by chain',\n isNewWallet: 'Whether the wallet is new and needs to be funded',\n depositLink: 'Link to deposit USDC directly into the wallet',\n onboardingCta:\n 'Present when the user has not yet redeemed an invite code. Show the message to the user — it directs them to onboard or deposit.',\n onboardingCtaOnboardLink: 'Link to the onboarding page',\n onboardingCtaDepositLink: 'Link to deposit USDC directly',\n onboardingCtaMessage: 'Human-readable CTA to show the user',\n message: 'Warning if balance is low',\n chain: 'Chain name',\n chainBalance: 'USDC balance on this chain',\n },\n },\n\n redeemInvite: {\n code: 'The invite code',\n output: {\n amount: 'Amount with unit (e.g., \"5 USDC\")',\n txHash: 'Transaction hash on Base',\n },\n },\n\n discoverApiEndpoints: {\n url: 'The origin URL to discover endpoints on (e.g. https://stableenrich.dev)',\n includeGuidance:\n \"Request the origin's usage guidance. true=always include, false=never include, omit=auto (included when compact). Guidance explains how to compose multiple endpoints and covers edge cases.\",\n },\n\n reportError: {\n tool: 'MCP tool name',\n resource: 'Resource URL',\n summary: '1-2 sentence summary',\n errorMessage: 'Error message',\n stack: 'Stack trace',\n fullReport: 'Detailed report with context, logs, repro steps',\n output: {\n reportId: 'Unique report ID for tracking',\n message: 'Confirmation message',\n },\n },\n} as const;\n","import * as fs from 'fs';\n\nimport z from 'zod';\n\nimport { configFile } from './fs';\nimport { safeParseJson } from './neverthrow/json';\n\nconst ORIGINS_FILE = configFile('origins.json');\n\nconst userOriginSchema = z.object({\n url: z.string(),\n title: z.string(),\n description: z.string(),\n addedAt: z.string(),\n});\n\nconst originsFileSchema = z.object({\n added: z.array(userOriginSchema),\n});\n\nexport type UserOrigin = z.infer<typeof userOriginSchema>;\n\nfunction readOriginsFile(): UserOrigin[] {\n if (!fs.existsSync(ORIGINS_FILE)) return [];\n const raw = fs.readFileSync(ORIGINS_FILE, 'utf-8');\n const json = safeParseJson('user-origins', raw);\n if (!json.isOk()) return [];\n const parsed = originsFileSchema.safeParse(json.value);\n return parsed.success ? parsed.data.added : [];\n}\n\nfunction writeOriginsFile(origins: UserOrigin[]): void {\n fs.writeFileSync(\n ORIGINS_FILE,\n JSON.stringify({ added: origins }, null, 2),\n 'utf-8'\n );\n}\n\nexport function loadUserOrigins(): UserOrigin[] {\n return readOriginsFile();\n}\n\nexport function addUserOrigin(origin: Omit<UserOrigin, 'addedAt'>): UserOrigin {\n const origins = readOriginsFile();\n const entry: UserOrigin = { ...origin, addedAt: new Date().toISOString() };\n const existing = origins.findIndex(o => o.url === origin.url);\n if (existing >= 0) {\n origins[existing] = entry;\n } else {\n origins.push(entry);\n }\n writeOriginsFile(origins);\n return entry;\n}\n\nexport function removeUserOrigin(url: string): { removed: boolean } {\n const origins = readOriginsFile();\n const filtered = origins.filter(o => o.url !== url);\n if (filtered.length === origins.length) return { removed: false };\n writeOriginsFile(filtered);\n return { removed: true };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import {
|
|
2
|
+
configFile,
|
|
3
|
+
err,
|
|
4
|
+
ok,
|
|
5
|
+
resultFromPromise,
|
|
6
|
+
resultFromThrowable
|
|
7
|
+
} from "./chunk-6PU3XK6I.js";
|
|
8
|
+
import {
|
|
9
|
+
isVerbose
|
|
10
|
+
} from "./chunk-ISR6DJ53.js";
|
|
11
|
+
|
|
12
|
+
// src/shared/neverthrow/fs/index.ts
|
|
13
|
+
import { readFile, writeFile, appendFile, chmod } from "fs/promises";
|
|
14
|
+
var errorType = "fs";
|
|
15
|
+
var fsErr = (surface, error) => err(errorType, surface, error);
|
|
16
|
+
var fsResultFromPromise = (surface, promise, error) => resultFromPromise(errorType, surface, promise, error);
|
|
17
|
+
var safeReadFile = (surface, path) => fsResultFromPromise(surface, readFile(path, "utf-8"), () => ({
|
|
18
|
+
cause: "file_not_readable",
|
|
19
|
+
message: "Failed to read file"
|
|
20
|
+
}));
|
|
21
|
+
var safeWriteFile = (surface, path, data) => fsResultFromPromise(surface, writeFile(path, data), () => ({
|
|
22
|
+
cause: "file_not_writable",
|
|
23
|
+
message: "Failed to write file"
|
|
24
|
+
}));
|
|
25
|
+
var safeAppendFile = (surface, path, data) => fsResultFromPromise(surface, appendFile(path, data), () => ({
|
|
26
|
+
cause: "file_not_writable",
|
|
27
|
+
message: "Failed to append file"
|
|
28
|
+
}));
|
|
29
|
+
var safeChmod = (surface, path, mode) => fsResultFromPromise(surface, chmod(path, mode), () => ({
|
|
30
|
+
cause: "file_not_chmodable",
|
|
31
|
+
message: "Failed to chmod file"
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
// src/shared/log.ts
|
|
35
|
+
var logFile;
|
|
36
|
+
function getLogFile() {
|
|
37
|
+
if (logFile === void 0) {
|
|
38
|
+
const result = resultFromThrowable(
|
|
39
|
+
"log",
|
|
40
|
+
"log",
|
|
41
|
+
() => configFile("mcp.log"),
|
|
42
|
+
(e) => ({
|
|
43
|
+
cause: "log_init",
|
|
44
|
+
message: e instanceof Error ? e.message : String(e)
|
|
45
|
+
})
|
|
46
|
+
);
|
|
47
|
+
logFile = result.isOk() ? result.value : null;
|
|
48
|
+
}
|
|
49
|
+
return logFile;
|
|
50
|
+
}
|
|
51
|
+
function format(args) {
|
|
52
|
+
return args.map(
|
|
53
|
+
(a) => typeof a === "object" && a !== null ? JSON.stringify(a) : String(a)
|
|
54
|
+
).join(" ");
|
|
55
|
+
}
|
|
56
|
+
function write(level, msg, args) {
|
|
57
|
+
const formatted = args.length ? `${msg} ${format(args)}` : msg;
|
|
58
|
+
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [${level}] ${formatted}
|
|
59
|
+
`;
|
|
60
|
+
const file = getLogFile();
|
|
61
|
+
if (file) safeAppendFile("log", file, line);
|
|
62
|
+
if (isVerbose()) {
|
|
63
|
+
console.error(`[agentcash] ${formatted}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
var log = {
|
|
67
|
+
info: (msg, ...args) => write("INFO", msg, args),
|
|
68
|
+
error: (msg, ...args) => write("ERROR", msg, args),
|
|
69
|
+
debug: (msg, ...args) => isVerbose() && write("DEBUG", msg, args),
|
|
70
|
+
get path() {
|
|
71
|
+
return getLogFile();
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// src/shared/neverthrow/parse/index.ts
|
|
76
|
+
import z from "zod";
|
|
77
|
+
var type = "json";
|
|
78
|
+
var parseErr = (surface, error) => err(type, surface, error);
|
|
79
|
+
var safeParse = (surface, schema, value) => {
|
|
80
|
+
const parseResult = schema.safeParse(value);
|
|
81
|
+
if (!parseResult.success) {
|
|
82
|
+
return parseErr(surface, {
|
|
83
|
+
cause: "invalid_data",
|
|
84
|
+
message: JSON.stringify(z.treeifyError(parseResult.error), null, 2),
|
|
85
|
+
error: parseResult.error
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return ok(parseResult.data);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
// src/shared/neverthrow/fetch/index.ts
|
|
92
|
+
import contentType from "content-type";
|
|
93
|
+
var DEFAULT_FETCH_TIMEOUT = 1e4;
|
|
94
|
+
var DEFAULT_USER_FETCH_TIMEOUT = 3e4;
|
|
95
|
+
var IMAGE_TYPES = /* @__PURE__ */ new Set([
|
|
96
|
+
"image/png",
|
|
97
|
+
"image/jpeg",
|
|
98
|
+
"image/gif",
|
|
99
|
+
"image/webp",
|
|
100
|
+
"image/svg+xml",
|
|
101
|
+
"image/tiff",
|
|
102
|
+
"image/bmp",
|
|
103
|
+
"image/ico"
|
|
104
|
+
]);
|
|
105
|
+
var errorType2 = "fetch";
|
|
106
|
+
var fetchErr = (surface, error) => err(errorType2, surface, error);
|
|
107
|
+
var fetchOk = (value) => ok(value);
|
|
108
|
+
var fetchHttpErr = (surface, response) => fetchErr(surface, {
|
|
109
|
+
cause: "http",
|
|
110
|
+
statusCode: response.status,
|
|
111
|
+
message: response.statusText,
|
|
112
|
+
response
|
|
113
|
+
});
|
|
114
|
+
var safeFetch = (surface, request, timeout) => {
|
|
115
|
+
const signal = timeout ? AbortSignal.timeout(timeout) : void 0;
|
|
116
|
+
return resultFromPromise(
|
|
117
|
+
errorType2,
|
|
118
|
+
surface,
|
|
119
|
+
fetch(request, ...signal ? [{ signal }] : []),
|
|
120
|
+
(error) => {
|
|
121
|
+
if (error instanceof DOMException && (error.name === "TimeoutError" || error.name === "AbortError")) {
|
|
122
|
+
return {
|
|
123
|
+
cause: "timeout",
|
|
124
|
+
message: timeout ? `Request timed out after ${timeout}ms. You can increase the timeout by passing a larger value in the 'timeout' parameter.` : "Request was aborted"
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
cause: "network",
|
|
129
|
+
message: error instanceof Error ? error.message : "Network error"
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
);
|
|
133
|
+
};
|
|
134
|
+
var safeFetchJson = (surface, request, schema, timeout) => {
|
|
135
|
+
return safeFetch(surface, request, timeout).andThen((response) => {
|
|
136
|
+
if (!response.ok) {
|
|
137
|
+
return fetchHttpErr(surface, response);
|
|
138
|
+
}
|
|
139
|
+
return resultFromPromise(errorType2, surface, response.json(), () => ({
|
|
140
|
+
cause: "parse",
|
|
141
|
+
message: "Could not parse JSON from response",
|
|
142
|
+
statusCode: response.status,
|
|
143
|
+
contentType: response.headers.get("content-type") ?? "Not specified"
|
|
144
|
+
}));
|
|
145
|
+
}).andThen((data) => safeParse(surface, schema, data));
|
|
146
|
+
};
|
|
147
|
+
var safeParseResponse = (surface, response) => {
|
|
148
|
+
return resultFromPromise(
|
|
149
|
+
errorType2,
|
|
150
|
+
surface,
|
|
151
|
+
(async () => {
|
|
152
|
+
const header = response.headers.get("content-type");
|
|
153
|
+
const { type: mimeType } = header ? contentType.parse(header) : { type: "application/octet-stream" };
|
|
154
|
+
switch (mimeType) {
|
|
155
|
+
case "application/json":
|
|
156
|
+
return {
|
|
157
|
+
type: "json",
|
|
158
|
+
data: await response.json()
|
|
159
|
+
};
|
|
160
|
+
case "application/pdf":
|
|
161
|
+
return {
|
|
162
|
+
type: "pdf",
|
|
163
|
+
mimeType,
|
|
164
|
+
data: await response.arrayBuffer()
|
|
165
|
+
};
|
|
166
|
+
case "application/octet-stream":
|
|
167
|
+
return {
|
|
168
|
+
type: "octet-stream",
|
|
169
|
+
mimeType,
|
|
170
|
+
data: await response.arrayBuffer()
|
|
171
|
+
};
|
|
172
|
+
case "multipart/form-data":
|
|
173
|
+
return { type: "formData", data: await response.formData() };
|
|
174
|
+
}
|
|
175
|
+
if (IMAGE_TYPES.has(mimeType)) {
|
|
176
|
+
return {
|
|
177
|
+
type: "image",
|
|
178
|
+
mimeType,
|
|
179
|
+
data: await response.arrayBuffer()
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
if (mimeType.startsWith("audio/")) {
|
|
183
|
+
return {
|
|
184
|
+
type: "audio",
|
|
185
|
+
mimeType,
|
|
186
|
+
data: await response.arrayBuffer()
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
if (mimeType.startsWith("video/")) {
|
|
190
|
+
return {
|
|
191
|
+
type: "video",
|
|
192
|
+
mimeType,
|
|
193
|
+
data: await response.arrayBuffer()
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
if (mimeType.startsWith("text/")) {
|
|
197
|
+
return { type: "text", data: await response.text() };
|
|
198
|
+
}
|
|
199
|
+
throw new Error(`Unsupported content type: ${header}`);
|
|
200
|
+
})(),
|
|
201
|
+
(e) => ({
|
|
202
|
+
cause: "parse",
|
|
203
|
+
message: e instanceof Error ? e.message : "Could not parse response",
|
|
204
|
+
statusCode: response.status,
|
|
205
|
+
contentType: response.headers.get("content-type") ?? "Not specified"
|
|
206
|
+
})
|
|
207
|
+
);
|
|
208
|
+
};
|
|
209
|
+
var isFetchError = (error) => {
|
|
210
|
+
return error.type === errorType2;
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
export {
|
|
214
|
+
safeParse,
|
|
215
|
+
DEFAULT_FETCH_TIMEOUT,
|
|
216
|
+
DEFAULT_USER_FETCH_TIMEOUT,
|
|
217
|
+
fetchErr,
|
|
218
|
+
fetchOk,
|
|
219
|
+
fetchHttpErr,
|
|
220
|
+
safeFetch,
|
|
221
|
+
safeFetchJson,
|
|
222
|
+
safeParseResponse,
|
|
223
|
+
isFetchError,
|
|
224
|
+
fsErr,
|
|
225
|
+
safeReadFile,
|
|
226
|
+
safeWriteFile,
|
|
227
|
+
safeChmod,
|
|
228
|
+
log
|
|
229
|
+
};
|
|
230
|
+
//# sourceMappingURL=chunk-YQFK4U62.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/shared/neverthrow/fs/index.ts","../../src/shared/log.ts","../../src/shared/neverthrow/parse/index.ts","../../src/shared/neverthrow/fetch/index.ts"],"sourcesContent":["import { readFile, writeFile, appendFile, chmod } from 'fs/promises';\n\nimport { err, resultFromPromise } from '@agentcash/neverthrow';\n\nimport type { BaseFileSystemError } from './types';\n\nconst errorType = 'fs';\n\nexport const fsErr = (surface: string, error: BaseFileSystemError) =>\n err(errorType, surface, error);\n\nconst fsResultFromPromise = <T>(\n surface: string,\n promise: Promise<T>,\n error: (e: unknown) => BaseFileSystemError\n) => resultFromPromise(errorType, surface, promise, error);\n\nexport const safeReadFile = (surface: string, path: string) =>\n fsResultFromPromise(surface, readFile(path, 'utf-8'), () => ({\n cause: 'file_not_readable',\n message: 'Failed to read file',\n }));\n\nexport const safeWriteFile = (surface: string, path: string, data: string) =>\n fsResultFromPromise(surface, writeFile(path, data), () => ({\n cause: 'file_not_writable',\n message: 'Failed to write file',\n }));\n\nexport const safeAppendFile = (surface: string, path: string, data: string) =>\n fsResultFromPromise(surface, appendFile(path, data), () => ({\n cause: 'file_not_writable',\n message: 'Failed to append file',\n }));\n\nexport const safeChmod = (surface: string, path: string, mode: number) =>\n fsResultFromPromise(surface, chmod(path, mode), () => ({\n cause: 'file_not_chmodable',\n message: 'Failed to chmod file',\n }));\n","import { resultFromThrowable } from '@agentcash/neverthrow';\n\nimport { safeAppendFile } from '@/shared/neverthrow/fs';\n\nimport { configFile } from './fs';\nimport { isVerbose } from './cli-context';\n\n/**\n * Resolved lazily on first write. `null` means the filesystem is\n * unavailable (e.g. Vercel sandbox) — file logging is skipped.\n */\nlet logFile: string | null | undefined;\n\nfunction getLogFile(): string | null {\n if (logFile === undefined) {\n const result = resultFromThrowable(\n 'log',\n 'log',\n () => configFile('mcp.log'),\n e => ({\n cause: 'log_init' as const,\n message: e instanceof Error ? e.message : String(e),\n })\n );\n logFile = result.isOk() ? result.value : null;\n }\n return logFile;\n}\n\nfunction format(args: unknown[]): string {\n return args\n .map(a =>\n typeof a === 'object' && a !== null ? JSON.stringify(a) : String(a)\n )\n .join(' ');\n}\n\nfunction write(level: string, msg: string, args: unknown[]): void {\n const formatted = args.length ? `${msg} ${format(args)}` : msg;\n const line = `[${new Date().toISOString()}] [${level}] ${formatted}\\n`;\n const file = getLogFile();\n if (file) safeAppendFile('log', file, line);\n if (isVerbose()) {\n console.error(`[agentcash] ${formatted}`);\n }\n}\n\nexport const log = {\n info: (msg: string, ...args: unknown[]) => write('INFO', msg, args),\n error: (msg: string, ...args: unknown[]) => write('ERROR', msg, args),\n debug: (msg: string, ...args: unknown[]) =>\n isVerbose() && write('DEBUG', msg, args),\n get path() {\n return getLogFile();\n },\n};\n","import z from 'zod';\n\nimport { err, ok } from '@agentcash/neverthrow';\n\nimport type { BaseParseError } from './types';\n\nconst type = 'json';\n\nconst parseErr = (surface: string, error: BaseParseError) =>\n err(type, surface, error);\n\nexport const safeParse = <T>(\n surface: string,\n schema: z.ZodSchema<T>,\n value: unknown\n) => {\n const parseResult = schema.safeParse(value);\n if (!parseResult.success) {\n return parseErr(surface, {\n cause: 'invalid_data',\n message: JSON.stringify(z.treeifyError(parseResult.error), null, 2),\n error: parseResult.error,\n });\n }\n return ok(parseResult.data);\n};\n","import contentType from 'content-type';\nimport { err, ok, resultFromPromise } from '@agentcash/neverthrow';\n\nimport type z from 'zod';\n\nimport type { BaseError, Error } from '@agentcash/neverthrow/types';\nimport type { BaseFetchError, FetchError, ParsedResponse } from './types';\nimport type { JsonObject } from '../json/types';\nimport { safeParse } from '../parse';\n\n/** Default timeout (ms) for infrastructure fetches (discovery, probes, specs). */\nexport const DEFAULT_FETCH_TIMEOUT = 10_000;\n\n/** Default timeout (ms) for external resource fetches where response time is unknown. */\nexport const DEFAULT_USER_FETCH_TIMEOUT = 30_000;\n\nconst IMAGE_TYPES = new Set([\n 'image/png',\n 'image/jpeg',\n 'image/gif',\n 'image/webp',\n 'image/svg+xml',\n 'image/tiff',\n 'image/bmp',\n 'image/ico',\n]);\n\nconst errorType = 'fetch';\n\nexport const fetchErr = (surface: string, error: BaseFetchError) =>\n err(errorType, surface, error);\nexport const fetchOk = <T>(value: T) => ok(value);\n\nexport const fetchHttpErr = (surface: string, response: Response) =>\n fetchErr(surface, {\n cause: 'http' as const,\n statusCode: response.status,\n message: response.statusText,\n response,\n });\n\nexport const safeFetch = (\n surface: string,\n request: Request,\n timeout?: number\n) => {\n const signal = timeout ? AbortSignal.timeout(timeout) : undefined;\n\n return resultFromPromise(\n errorType,\n surface,\n fetch(request, ...(signal ? [{ signal }] : [])),\n error => {\n if (\n error instanceof DOMException &&\n (error.name === 'TimeoutError' || error.name === 'AbortError')\n ) {\n return {\n cause: 'timeout',\n message: timeout\n ? `Request timed out after ${timeout}ms. You can increase the timeout by passing a larger value in the 'timeout' parameter.`\n : 'Request was aborted',\n } as BaseFetchError;\n }\n\n return {\n cause: 'network',\n message: error instanceof Error ? error.message : 'Network error',\n } as BaseFetchError;\n }\n );\n};\n\nexport const safeFetchJson = <T>(\n surface: string,\n request: Request,\n schema: z.ZodSchema<T>,\n timeout?: number\n) => {\n return safeFetch(surface, request, timeout)\n .andThen(response => {\n if (!response.ok) {\n return fetchHttpErr(surface, response);\n }\n\n return resultFromPromise(errorType, surface, response.json(), () => ({\n cause: 'parse' as const,\n message: 'Could not parse JSON from response',\n statusCode: response.status,\n contentType: response.headers.get('content-type') ?? 'Not specified',\n }));\n })\n .andThen(data => safeParse(surface, schema, data));\n};\n\nexport const safeParseResponse = (surface: string, response: Response) => {\n return resultFromPromise(\n errorType,\n surface,\n (async (): Promise<ParsedResponse> => {\n const header = response.headers.get('content-type');\n const { type: mimeType } = header\n ? contentType.parse(header)\n : { type: 'application/octet-stream' };\n\n switch (mimeType) {\n case 'application/json':\n return {\n type: 'json' as const,\n data: (await response.json()) as JsonObject,\n };\n case 'application/pdf':\n return {\n type: 'pdf' as const,\n mimeType,\n data: await response.arrayBuffer(),\n };\n case 'application/octet-stream':\n return {\n type: 'octet-stream' as const,\n mimeType,\n data: await response.arrayBuffer(),\n };\n case 'multipart/form-data':\n return { type: 'formData' as const, data: await response.formData() };\n }\n\n if (IMAGE_TYPES.has(mimeType)) {\n return {\n type: 'image' as const,\n mimeType,\n data: await response.arrayBuffer(),\n };\n }\n\n if (mimeType.startsWith('audio/')) {\n return {\n type: 'audio' as const,\n mimeType,\n data: await response.arrayBuffer(),\n };\n }\n\n if (mimeType.startsWith('video/')) {\n return {\n type: 'video' as const,\n mimeType,\n data: await response.arrayBuffer(),\n };\n }\n\n if (mimeType.startsWith('text/')) {\n return { type: 'text' as const, data: await response.text() };\n }\n\n throw new Error(`Unsupported content type: ${header}`);\n })(),\n e => ({\n cause: 'parse' as const,\n message: e instanceof Error ? e.message : 'Could not parse response',\n statusCode: response.status,\n contentType: response.headers.get('content-type') ?? 'Not specified',\n })\n );\n};\n\nexport const isFetchError = (error: Error<BaseError>): error is FetchError => {\n return error.type === errorType;\n};\n"],"mappings":"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","names":["errorType"]}
|
|
@@ -1,26 +1,28 @@
|
|
|
1
1
|
import {
|
|
2
2
|
REQUEST_PARAMS
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-W7DAJMFQ.js";
|
|
4
4
|
import {
|
|
5
5
|
getTempoBalance
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-62B3GENJ.js";
|
|
7
7
|
import {
|
|
8
8
|
isMppEnabled
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-FBPC4LGY.js";
|
|
10
10
|
import {
|
|
11
11
|
getBalance
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-7ZEXMJYJ.js";
|
|
13
13
|
import {
|
|
14
14
|
DEFAULT_USER_FETCH_TIMEOUT,
|
|
15
|
-
err,
|
|
16
15
|
fetchErr,
|
|
17
16
|
fetchOk,
|
|
18
17
|
log,
|
|
18
|
+
safeFetch
|
|
19
|
+
} from "./chunk-YQFK4U62.js";
|
|
20
|
+
import {
|
|
21
|
+
err,
|
|
19
22
|
ok,
|
|
20
23
|
resultFromPromise,
|
|
21
|
-
resultFromThrowable
|
|
22
|
-
|
|
23
|
-
} from "./chunk-TRPO7BKD.js";
|
|
24
|
+
resultFromThrowable
|
|
25
|
+
} from "./chunk-6PU3XK6I.js";
|
|
24
26
|
|
|
25
27
|
// src/server/tools/lib/request.ts
|
|
26
28
|
import z from "zod";
|
|
@@ -516,4 +518,4 @@ export {
|
|
|
516
518
|
getInputSchema,
|
|
517
519
|
createFetchWithAuth
|
|
518
520
|
};
|
|
519
|
-
//# sourceMappingURL=chunk-
|
|
521
|
+
//# sourceMappingURL=chunk-Z2R7VYNM.js.map
|