@vm0/cli 9.278.0 → 9.278.1
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/{agent-HUDTEGLK.js → agent-4F3XAJWN.js} +12 -6
- package/agent-4F3XAJWN.js.map +1 -0
- package/{banking-BMZONEXP.js → banking-CWQFQKZB.js} +61 -7
- package/banking-CWQFQKZB.js.map +1 -0
- package/{browser-LQP445CU.js → browser-BI6UFWPH.js} +4 -5
- package/browser-BI6UFWPH.js.map +1 -0
- package/{chat-UF7QAWUT.js → chat-MKIW4FPP.js} +24 -16
- package/chat-MKIW4FPP.js.map +1 -0
- package/chunk-2SJTFDC2.js +189 -0
- package/chunk-2SJTFDC2.js.map +1 -0
- package/chunk-4FTIKZKP.js +64 -0
- package/chunk-4FTIKZKP.js.map +1 -0
- package/chunk-7UZXNER2.js +568 -0
- package/chunk-7UZXNER2.js.map +1 -0
- package/chunk-A6ZRMNM3.js +102 -0
- package/chunk-A6ZRMNM3.js.map +1 -0
- package/{chunk-QC63TUJC.js → chunk-C62A6LD6.js} +2 -2
- package/chunk-CCTF3YVW.js +52 -0
- package/chunk-CCTF3YVW.js.map +1 -0
- package/chunk-CD2BLKGC.js +188 -0
- package/chunk-CD2BLKGC.js.map +1 -0
- package/chunk-CEJGHPF3.js +55 -0
- package/chunk-CEJGHPF3.js.map +1 -0
- package/chunk-DUA6CF7E.js +2053 -0
- package/chunk-DUA6CF7E.js.map +1 -0
- package/chunk-E2TQAKNL.js +1300 -0
- package/chunk-E2TQAKNL.js.map +1 -0
- package/{chunk-5ZZI2LSO.js → chunk-GHKWW4NC.js} +5 -5
- package/chunk-GV3PG6CZ.js +114 -0
- package/chunk-GV3PG6CZ.js.map +1 -0
- package/chunk-GY7D76EZ.js +81 -0
- package/chunk-GY7D76EZ.js.map +1 -0
- package/chunk-HHHHZMTA.js +434 -0
- package/chunk-HHHHZMTA.js.map +1 -0
- package/chunk-HZYOJTEE.js +1275 -0
- package/chunk-HZYOJTEE.js.map +1 -0
- package/chunk-J3ZRXVI6.js +740 -0
- package/chunk-J3ZRXVI6.js.map +1 -0
- package/chunk-JJWFO27K.js +31 -0
- package/chunk-JJWFO27K.js.map +1 -0
- package/chunk-JV6LM2YC.js +39 -0
- package/chunk-JV6LM2YC.js.map +1 -0
- package/chunk-KER77KJB.js +105 -0
- package/chunk-KER77KJB.js.map +1 -0
- package/{chunk-V5ZVB7RJ.js → chunk-KKO2XGLQ.js} +1 -6
- package/chunk-KKO2XGLQ.js.map +1 -0
- package/chunk-LIYPTQAO.js +198 -0
- package/chunk-LIYPTQAO.js.map +1 -0
- package/chunk-LYLDVUHT.js +131 -0
- package/chunk-LYLDVUHT.js.map +1 -0
- package/chunk-PFWBO2VK.js +801 -0
- package/chunk-PFWBO2VK.js.map +1 -0
- package/chunk-RTCRU35A.js +194 -0
- package/chunk-RTCRU35A.js.map +1 -0
- package/{chunk-F2AM4RWA.js → chunk-RTEEWZUT.js} +2 -2
- package/{chunk-F2AM4RWA.js.map → chunk-RTEEWZUT.js.map} +1 -1
- package/{chunk-BRV4D3P2.js → chunk-RUKMHBNQ.js} +2 -2
- package/chunk-SA4DYSBR.js +31 -0
- package/chunk-SA4DYSBR.js.map +1 -0
- package/chunk-SJPOFQJU.js +792 -0
- package/chunk-SJPOFQJU.js.map +1 -0
- package/{chunk-V7A6ZFHR.js → chunk-SMPSKBAP.js} +25 -774
- package/chunk-SMPSKBAP.js.map +1 -0
- package/{chunk-E53W6UVQ.js → chunk-T2X2EGV2.js} +4 -4
- package/chunk-T2X2EGV2.js.map +1 -0
- package/chunk-U2GQH6AD.js +309 -0
- package/chunk-U2GQH6AD.js.map +1 -0
- package/chunk-U6A2RPHO.js +66 -0
- package/chunk-U6A2RPHO.js.map +1 -0
- package/chunk-UIXUGVZB.js +362 -0
- package/chunk-UIXUGVZB.js.map +1 -0
- package/chunk-XRZKJACM.js +49 -0
- package/chunk-XRZKJACM.js.map +1 -0
- package/chunk-YDS3X7KB.js +202 -0
- package/chunk-YDS3X7KB.js.map +1 -0
- package/{chunk-A6TMOGPR.js → chunk-ZKNJW4K6.js} +1412 -334
- package/chunk-ZKNJW4K6.js.map +1 -0
- package/chunk-ZXSCBS77.js +90 -0
- package/chunk-ZXSCBS77.js.map +1 -0
- package/{computer-use-RRD7BCCK.js → computer-use-6AEVW47F.js} +9 -7
- package/computer-use-6AEVW47F.js.map +1 -0
- package/{connector-XX7UU6XE.js → connector-XDQ6JEBU.js} +25 -13
- package/connector-XDQ6JEBU.js.map +1 -0
- package/{credit-GDNNAQRO.js → credit-JPQA5XPA.js} +8 -10
- package/credit-JPQA5XPA.js.map +1 -0
- package/{developer-support-IISP5UBI.js → developer-support-V7NZOU2P.js} +27 -7
- package/developer-support-V7NZOU2P.js.map +1 -0
- package/{doctor-IZM2TJOH.js → doctor-FJO24TG3.js} +13 -11
- package/doctor-FJO24TG3.js.map +1 -0
- package/{feishu-XB7SQBSI.js → feishu-PNOAM33Q.js} +99 -9
- package/feishu-PNOAM33Q.js.map +1 -0
- package/{finance-OGWHKQLU.js → finance-55OJ6GYP.js} +49 -9
- package/finance-55OJ6GYP.js.map +1 -0
- package/{generate-AA2PVOYQ.js → generate-XUKBK523.js} +26 -21
- package/generate-XUKBK523.js.map +1 -0
- package/{github-VJVIBTVF.js → github-V4MD2PMM.js} +83 -8
- package/github-V4MD2PMM.js.map +1 -0
- package/{goal-7SYVHDTK.js → goal-FS5FJKVU.js} +69 -13
- package/goal-FS5FJKVU.js.map +1 -0
- package/{host-UVQMIOBA.js → host-GITTJ6PR.js} +124 -10
- package/host-GITTJ6PR.js.map +1 -0
- package/{logs-PIS4X24E.js → logs-EEUIGYUD.js} +51 -11
- package/logs-EEUIGYUD.js.map +1 -0
- package/{mail-L33OSQ2R.js → mail-G4SAJSBD.js} +39 -8
- package/mail-G4SAJSBD.js.map +1 -0
- package/{maps-D5XTXU5U.js → maps-7ANNU3BX.js} +65 -11
- package/maps-7ANNU3BX.js.map +1 -0
- package/{model-ZFMRECDM.js → model-DSPDCJLB.js} +6 -6
- package/model-DSPDCJLB.js.map +1 -0
- package/{model-provider-EZZ2DRYZ.js → model-provider-RZQ45PNG.js} +6 -6
- package/model-provider-RZQ45PNG.js.map +1 -0
- package/package.json +1 -1
- package/{people-search-PFTIO2QS.js → people-search-I7PUMF5M.js} +22 -6
- package/people-search-I7PUMF5M.js.map +1 -0
- package/{phone-6SG5ZUNL.js → phone-SSAPGMTW.js} +90 -9
- package/phone-SSAPGMTW.js.map +1 -0
- package/{recognize-LLU6J3SW.js → recognize-D7VORZBN.js} +27 -9
- package/recognize-D7VORZBN.js.map +1 -0
- package/{resource-FGUSXS4G.js → resource-76IV3TMW.js} +21 -7
- package/resource-76IV3TMW.js.map +1 -0
- package/{scrape-BAUZ2YFD.js → scrape-JBDLNTLB.js} +22 -6
- package/scrape-JBDLNTLB.js.map +1 -0
- package/{search-DLO5RXRM.js → search-UNZNUTZX.js} +29 -9
- package/search-UNZNUTZX.js.map +1 -0
- package/{slack-CVATPKP3.js → slack-AAH6GG2W.js} +103 -11
- package/slack-AAH6GG2W.js.map +1 -0
- package/{teams-ZZYO6YIK.js → teams-6OPXE4TX.js} +90 -9
- package/teams-6OPXE4TX.js.map +1 -0
- package/{telegram-VY7T4YAR.js → telegram-RRZG73RT.js} +101 -10
- package/telegram-RRZG73RT.js.map +1 -0
- package/{upgrade-GFA4ZUU4.js → upgrade-I5IL4UQL.js} +3 -4
- package/upgrade-I5IL4UQL.js.map +1 -0
- package/{video-STFG7BET.js → video-HV44W4X7.js} +5 -4
- package/video-HV44W4X7.js.map +1 -0
- package/{weather-ISJEHJWR.js → weather-EQ7CSADB.js} +70 -16
- package/weather-EQ7CSADB.js.map +1 -0
- package/{web-YN4CVHK7.js → web-6LIMWEOZ.js} +5 -5
- package/web-6LIMWEOZ.js.map +1 -0
- package/{web-search-PC7IECND.js → web-search-AT7WONZN.js} +22 -6
- package/web-search-AT7WONZN.js.map +1 -0
- package/{whoami-KXFXZGM6.js → whoami-RKTLLSI4.js} +16 -7
- package/whoami-RKTLLSI4.js.map +1 -0
- package/{workflow-O7YZHB7A.js → workflow-ZH32P622.js} +135 -39
- package/workflow-ZH32P622.js.map +1 -0
- package/zero.js +40 -40
- package/agent-HUDTEGLK.js.map +0 -1
- package/banking-BMZONEXP.js.map +0 -1
- package/browser-LQP445CU.js.map +0 -1
- package/chat-UF7QAWUT.js.map +0 -1
- package/chunk-2W73DZDW.js +0 -32
- package/chunk-2W73DZDW.js.map +0 -1
- package/chunk-6PN6QGIM.js +0 -11405
- package/chunk-6PN6QGIM.js.map +0 -1
- package/chunk-A6TMOGPR.js.map +0 -1
- package/chunk-ANOLYIPL.js +0 -10
- package/chunk-ANOLYIPL.js.map +0 -1
- package/chunk-E53W6UVQ.js.map +0 -1
- package/chunk-V5ZVB7RJ.js.map +0 -1
- package/chunk-V7A6ZFHR.js.map +0 -1
- package/computer-use-RRD7BCCK.js.map +0 -1
- package/connector-XX7UU6XE.js.map +0 -1
- package/credit-GDNNAQRO.js.map +0 -1
- package/developer-support-IISP5UBI.js.map +0 -1
- package/doctor-IZM2TJOH.js.map +0 -1
- package/feishu-XB7SQBSI.js.map +0 -1
- package/finance-OGWHKQLU.js.map +0 -1
- package/generate-AA2PVOYQ.js.map +0 -1
- package/github-VJVIBTVF.js.map +0 -1
- package/goal-7SYVHDTK.js.map +0 -1
- package/host-UVQMIOBA.js.map +0 -1
- package/logs-PIS4X24E.js.map +0 -1
- package/mail-L33OSQ2R.js.map +0 -1
- package/maps-D5XTXU5U.js.map +0 -1
- package/model-ZFMRECDM.js.map +0 -1
- package/model-provider-EZZ2DRYZ.js.map +0 -1
- package/people-search-PFTIO2QS.js.map +0 -1
- package/phone-6SG5ZUNL.js.map +0 -1
- package/recognize-LLU6J3SW.js.map +0 -1
- package/resource-FGUSXS4G.js.map +0 -1
- package/scrape-BAUZ2YFD.js.map +0 -1
- package/search-DLO5RXRM.js.map +0 -1
- package/slack-CVATPKP3.js.map +0 -1
- package/teams-ZZYO6YIK.js.map +0 -1
- package/telegram-VY7T4YAR.js.map +0 -1
- package/upgrade-GFA4ZUU4.js.map +0 -1
- package/video-STFG7BET.js.map +0 -1
- package/weather-ISJEHJWR.js.map +0 -1
- package/web-YN4CVHK7.js.map +0 -1
- package/web-search-PC7IECND.js.map +0 -1
- package/whoami-KXFXZGM6.js.map +0 -1
- package/workflow-O7YZHB7A.js.map +0 -1
- /package/{chunk-QC63TUJC.js.map → chunk-C62A6LD6.js.map} +0 -0
- /package/{chunk-5ZZI2LSO.js.map → chunk-GHKWW4NC.js.map} +0 -0
- /package/{chunk-BRV4D3P2.js.map → chunk-RUKMHBNQ.js.map} +0 -0
|
@@ -2,17 +2,22 @@
|
|
|
2
2
|
import { createRequire as __createRequire } from "node:module";
|
|
3
3
|
const require = __createRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
import "./chunk-V7A6ZFHR.js";
|
|
11
|
-
import "./chunk-ANOLYIPL.js";
|
|
5
|
+
integrationsPhoneMessageContract,
|
|
6
|
+
integrationsPhoneUploadCompleteContract,
|
|
7
|
+
integrationsPhoneUploadInitContract
|
|
8
|
+
} from "./chunk-PFWBO2VK.js";
|
|
9
|
+
import "./chunk-JV6LM2YC.js";
|
|
12
10
|
import {
|
|
11
|
+
ApiRequestError,
|
|
12
|
+
getActiveToken,
|
|
13
|
+
getBaseUrl,
|
|
14
|
+
getClientConfig,
|
|
15
|
+
handleError,
|
|
16
|
+
headersWithCliClientHeaders,
|
|
17
|
+
initClient,
|
|
13
18
|
source_default,
|
|
14
19
|
withErrorHandler
|
|
15
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-GHKWW4NC.js";
|
|
16
21
|
import "./chunk-32FE3MDA.js";
|
|
17
22
|
import {
|
|
18
23
|
Command
|
|
@@ -28,6 +33,82 @@ init_esm_shims();
|
|
|
28
33
|
init_esm_shims();
|
|
29
34
|
import { basename, join } from "path";
|
|
30
35
|
import { tmpdir } from "os";
|
|
36
|
+
|
|
37
|
+
// src/lib/api/domains/integrations-phone.ts
|
|
38
|
+
init_esm_shims();
|
|
39
|
+
import { createWriteStream } from "fs";
|
|
40
|
+
import { Readable } from "stream";
|
|
41
|
+
import { pipeline } from "stream/promises";
|
|
42
|
+
async function sendPhoneMessage(body) {
|
|
43
|
+
const config = await getClientConfig();
|
|
44
|
+
const client = initClient(integrationsPhoneMessageContract, config);
|
|
45
|
+
const result = await client.sendMessage({ body, headers: {} });
|
|
46
|
+
if (result.status === 200) {
|
|
47
|
+
return result.body;
|
|
48
|
+
}
|
|
49
|
+
handleError(result, "Failed to send AgentPhone message");
|
|
50
|
+
}
|
|
51
|
+
async function initPhoneFileUpload(body) {
|
|
52
|
+
const config = await getClientConfig();
|
|
53
|
+
const client = initClient(integrationsPhoneUploadInitContract, config);
|
|
54
|
+
const result = await client.init({ body, headers: {} });
|
|
55
|
+
if (result.status === 200) {
|
|
56
|
+
return result.body;
|
|
57
|
+
}
|
|
58
|
+
handleError(result, "Failed to initialize AgentPhone file upload");
|
|
59
|
+
}
|
|
60
|
+
async function completePhoneFileUpload(body) {
|
|
61
|
+
const config = await getClientConfig();
|
|
62
|
+
const client = initClient(integrationsPhoneUploadCompleteContract, config);
|
|
63
|
+
const result = await client.complete({ body, headers: {} });
|
|
64
|
+
if (result.status === 200) {
|
|
65
|
+
return result.body;
|
|
66
|
+
}
|
|
67
|
+
handleError(result, "Failed to complete AgentPhone file upload");
|
|
68
|
+
}
|
|
69
|
+
async function downloadPhoneFile(fileId, outPath) {
|
|
70
|
+
const baseUrl = await getBaseUrl();
|
|
71
|
+
const token = await getActiveToken();
|
|
72
|
+
if (!token) {
|
|
73
|
+
throw new ApiRequestError("Not authenticated", "UNAUTHORIZED", 401);
|
|
74
|
+
}
|
|
75
|
+
const url = new URL("/api/zero/integrations/phone/download-file", baseUrl);
|
|
76
|
+
url.searchParams.set("file_id", fileId);
|
|
77
|
+
const headers = {
|
|
78
|
+
Authorization: `Bearer ${token}`
|
|
79
|
+
};
|
|
80
|
+
const response = await fetch(url, {
|
|
81
|
+
headers: headersWithCliClientHeaders(headers)
|
|
82
|
+
});
|
|
83
|
+
if (!response.ok) {
|
|
84
|
+
let message = `Failed to download AgentPhone file (HTTP ${response.status})`;
|
|
85
|
+
let code = "UNKNOWN";
|
|
86
|
+
try {
|
|
87
|
+
const body = await response.json();
|
|
88
|
+
if (body.error?.message) message = body.error.message;
|
|
89
|
+
if (body.error?.code) code = body.error.code;
|
|
90
|
+
} catch {
|
|
91
|
+
}
|
|
92
|
+
throw new ApiRequestError(message, code, response.status);
|
|
93
|
+
}
|
|
94
|
+
if (!response.body) {
|
|
95
|
+
throw new ApiRequestError(
|
|
96
|
+
"AgentPhone download response has no body",
|
|
97
|
+
"EMPTY_BODY",
|
|
98
|
+
502
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
const mimetype = response.headers.get("x-file-mimetype") ?? response.headers.get("content-type") ?? "application/octet-stream";
|
|
102
|
+
await pipeline(
|
|
103
|
+
Readable.fromWeb(response.body),
|
|
104
|
+
createWriteStream(outPath)
|
|
105
|
+
);
|
|
106
|
+
const contentLengthHeader = response.headers.get("content-length");
|
|
107
|
+
const size = contentLengthHeader ? Number(contentLengthHeader) : 0;
|
|
108
|
+
return { path: outPath, mimetype, size };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// src/commands/zero/phone/download-file.ts
|
|
31
112
|
function defaultOutPath(fileId) {
|
|
32
113
|
return join(tmpdir(), `phone-${basename(fileId)}`);
|
|
33
114
|
}
|
|
@@ -204,4 +285,4 @@ Examples:
|
|
|
204
285
|
export {
|
|
205
286
|
zeroPhoneCommand
|
|
206
287
|
};
|
|
207
|
-
//# sourceMappingURL=phone-
|
|
288
|
+
//# sourceMappingURL=phone-SSAPGMTW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/zero/phone/index.ts","../src/commands/zero/phone/download-file.ts","../src/lib/api/domains/integrations-phone.ts","../src/commands/zero/phone/message.ts","../src/commands/zero/phone/upload-file.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { downloadFileCommand } from \"./download-file\";\nimport { messageCommand } from \"./message\";\nimport { uploadFileCommand } from \"./upload-file\";\n\nexport const zeroPhoneCommand = new Command()\n .name(\"phone\")\n .description(\"Send AgentPhone messages, upload files, and download media\")\n .addCommand(messageCommand)\n .addCommand(downloadFileCommand)\n .addCommand(uploadFileCommand)\n .addHelpText(\n \"after\",\n `\nExamples:\n Send a message: zero phone message --to +15551234567 -t \"Hello!\"\n Upload a file: zero phone upload-file -f /tmp/report.pdf --to +15551234567\n Download a file: zero phone download-file <file-id> -o /tmp/out.jpg`,\n );\n","import { basename, join } from \"path\";\nimport { tmpdir } from \"os\";\nimport { Command } from \"commander\";\nimport { downloadPhoneFile } from \"../../../lib/api/domains/integrations-phone\";\nimport { withErrorHandler } from \"../../../lib/command/with-error-handler\";\n\nfunction defaultOutPath(fileId: string): string {\n return join(tmpdir(), `phone-${basename(fileId)}`);\n}\n\nexport const downloadFileCommand = new Command()\n .name(\"download-file\")\n .description(\"Download an AgentPhone media file by id\")\n .argument(\n \"<file-id>\",\n \"AgentPhone message id from an [AgentPhone file] block\",\n )\n .option(\n \"-o, --out <path>\",\n \"Output path for the downloaded file (default: /tmp/phone-<file-id>)\",\n )\n .addHelpText(\n \"after\",\n `\nExamples:\n Download to default temp path: zero phone download-file msg_123\n Download to explicit path: zero phone download-file msg_123 -o /tmp/photo.jpg\n\nOutput:\n Prints a JSON object to stdout on success:\n {\"path\":\"/tmp/phone-msg_123\",\"mimetype\":\"image/jpeg\",\"size\":12345}\n\nHow to read the downloaded file:\n - Images (png/jpg/gif/webp/svg): open the file path with your image viewing tool\n - Videos (mp4/mov/webm): transcribe audio first with\n zero video transcribe --url <download-url>\n or extract frames with\n ffmpeg -i <path> -vf \"fps=1\" -q:v 2 /tmp/<file-id>_frame_%03d.jpg\n - PDF/text/csv/json/markdown: read the file directly`,\n )\n .action(\n withErrorHandler(async (fileId: string, options: { out?: string }) => {\n const outPath = options.out ?? defaultOutPath(fileId);\n const result = await downloadPhoneFile(fileId, outPath);\n console.log(JSON.stringify(result));\n }),\n );\n","import { createWriteStream } from \"node:fs\";\nimport { Readable } from \"node:stream\";\nimport { pipeline } from \"node:stream/promises\";\nimport { initClient } from \"@vm0/api-contracts/contracts/trpc-contract\";\nimport {\n integrationsPhoneMessageContract,\n integrationsPhoneUploadCompleteContract,\n integrationsPhoneUploadInitContract,\n type PhoneUploadCompleteBody,\n type PhoneUploadCompleteResponse,\n type PhoneUploadInitBody,\n type PhoneUploadInitResponse,\n type SendPhoneMessageBody,\n type SendPhoneMessageResponse,\n} from \"@vm0/api-contracts/contracts/integrations\";\nimport {\n ApiRequestError,\n getBaseUrl,\n getClientConfig,\n handleError,\n} from \"../core/client-factory\";\nimport { getActiveToken } from \"../config\";\nimport { headersWithCliClientHeaders } from \"../client-headers\";\n\ninterface DownloadPhoneFileResult {\n path: string;\n mimetype: string;\n size: number;\n}\n\nexport async function sendPhoneMessage(\n body: SendPhoneMessageBody,\n): Promise<SendPhoneMessageResponse> {\n const config = await getClientConfig();\n const client = initClient(integrationsPhoneMessageContract, config);\n\n const result = await client.sendMessage({ body, headers: {} });\n\n if (result.status === 200) {\n return result.body;\n }\n\n handleError(result, \"Failed to send AgentPhone message\");\n}\n\nexport async function initPhoneFileUpload(\n body: PhoneUploadInitBody,\n): Promise<PhoneUploadInitResponse> {\n const config = await getClientConfig();\n const client = initClient(integrationsPhoneUploadInitContract, config);\n\n const result = await client.init({ body, headers: {} });\n\n if (result.status === 200) {\n return result.body;\n }\n\n handleError(result, \"Failed to initialize AgentPhone file upload\");\n}\n\nexport async function completePhoneFileUpload(\n body: PhoneUploadCompleteBody,\n): Promise<PhoneUploadCompleteResponse> {\n const config = await getClientConfig();\n const client = initClient(integrationsPhoneUploadCompleteContract, config);\n\n const result = await client.complete({ body, headers: {} });\n\n if (result.status === 200) {\n return result.body;\n }\n\n handleError(result, \"Failed to complete AgentPhone file upload\");\n}\n\n/**\n * Download an AgentPhone media attachment to a local path.\n */\nexport async function downloadPhoneFile(\n fileId: string,\n outPath: string,\n): Promise<DownloadPhoneFileResult> {\n const baseUrl = await getBaseUrl();\n const token = await getActiveToken();\n if (!token) {\n throw new ApiRequestError(\"Not authenticated\", \"UNAUTHORIZED\", 401);\n }\n\n const url = new URL(\"/api/zero/integrations/phone/download-file\", baseUrl);\n url.searchParams.set(\"file_id\", fileId);\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n };\n\n const response = await fetch(url, {\n headers: headersWithCliClientHeaders(headers),\n });\n\n if (!response.ok) {\n let message = `Failed to download AgentPhone file (HTTP ${response.status})`;\n let code = \"UNKNOWN\";\n try {\n const body = (await response.json()) as {\n error?: { message?: string; code?: string };\n };\n if (body.error?.message) message = body.error.message;\n if (body.error?.code) code = body.error.code;\n } catch {\n // keep generic message when the body is not JSON\n }\n throw new ApiRequestError(message, code, response.status);\n }\n\n if (!response.body) {\n throw new ApiRequestError(\n \"AgentPhone download response has no body\",\n \"EMPTY_BODY\",\n 502,\n );\n }\n\n const mimetype =\n response.headers.get(\"x-file-mimetype\") ??\n response.headers.get(\"content-type\") ??\n \"application/octet-stream\";\n\n await pipeline(\n Readable.fromWeb(response.body as never),\n createWriteStream(outPath),\n );\n\n const contentLengthHeader = response.headers.get(\"content-length\");\n const size = contentLengthHeader ? Number(contentLengthHeader) : 0;\n\n return { path: outPath, mimetype, size };\n}\n","import { readFileSync } from \"fs\";\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { sendPhoneMessage } from \"../../../lib/api/domains/integrations-phone\";\nimport { withErrorHandler } from \"../../../lib/command/with-error-handler\";\n\nexport const messageCommand = new Command()\n .name(\"message\")\n .description(\"Send an AgentPhone text message\")\n .requiredOption(\"--to <phone>\", \"Connected phone handle to message\")\n .option(\"--agent-id <id>\", \"AgentPhone agent ID (inferred when omitted)\")\n .option(\"-t, --text <message>\", \"Message text\")\n .addHelpText(\n \"after\",\n `\nExamples:\n Send a message: zero phone message --to +15551234567 -t \"Hello!\"\n From stdin: printf \"Hello!\" | zero phone message --to +15551234567\n\nNotes:\n - The phone handle must already be connected to the authenticated VM0 user\n - AgentPhone agent ID is inferred from the conversation when omitted`,\n )\n .action(\n withErrorHandler(\n async (options: { to: string; agentId?: string; text?: string }) => {\n let text = options.text;\n if (!text && !process.stdin.isTTY) {\n try {\n text = readFileSync(\"/dev/stdin\", \"utf8\").trim();\n } catch {\n // stdin not readable (e.g. test runner with no piped input);\n // fall through to the missing-text validation below.\n }\n }\n\n if (!text) {\n throw new Error(\"Either --text or piped stdin must be provided\", {\n cause: new Error(\n 'Usage: zero phone message --to +15551234567 -t \"your message\"',\n ),\n });\n }\n\n const result = await sendPhoneMessage({\n toNumber: options.to,\n text,\n agentphoneAgentId: options.agentId,\n });\n\n console.log(\n chalk.green(`✓ Message sent (message_id: ${result.messageId})`),\n );\n },\n ),\n );\n","import { readFileSync, statSync } from \"fs\";\nimport { basename, extname } from \"path\";\nimport { Command } from \"commander\";\nimport {\n completePhoneFileUpload,\n initPhoneFileUpload,\n} from \"../../../lib/api/domains/integrations-phone\";\nimport { withErrorHandler } from \"../../../lib/command/with-error-handler\";\n\nconst MIME_BY_EXTENSION: Record<string, string> = {\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\",\n \".mp4\": \"video/mp4\",\n \".webm\": \"video/webm\",\n \".mov\": \"video/quicktime\",\n \".pdf\": \"application/pdf\",\n \".txt\": \"text/plain\",\n \".csv\": \"text/csv\",\n \".md\": \"text/markdown\",\n \".json\": \"application/json\",\n};\n\nfunction inferContentType(localPath: string): string {\n const ext = extname(localPath).toLowerCase();\n return MIME_BY_EXTENSION[ext] ?? \"application/octet-stream\";\n}\n\nexport const uploadFileCommand = new Command()\n .name(\"upload-file\")\n .description(\"Upload a local file to an AgentPhone conversation\")\n .requiredOption(\"-f, --file <path>\", \"Local file path to upload\")\n .requiredOption(\"--to <phone>\", \"Connected phone handle to message\")\n .option(\"--agent-id <id>\", \"AgentPhone agent ID (inferred when omitted)\")\n .option(\"--caption <text>\", \"Caption to accompany the file\")\n .option(\"--content-type <mime>\", \"Override inferred content type\")\n .addHelpText(\n \"after\",\n `\nExamples:\n Upload a file: zero phone upload-file -f /tmp/report.pdf --to +15551234567\n With a caption: zero phone upload-file -f /tmp/photo.jpg --to +15551234567 --caption \"Here it is\"\n\nOutput:\n Prints a JSON object to stdout on success:\n {\"messageId\":\"msg_123\",\"toNumber\":\"+15551234567\",\"filename\":\"report.pdf\",\"mimetype\":\"application/pdf\",\"size\":12345,\"url\":\"https://...\"}`,\n )\n .action(\n withErrorHandler(\n async (options: {\n file: string;\n to: string;\n agentId?: string;\n caption?: string;\n contentType?: string;\n }) => {\n let fileSize: number;\n try {\n const stat = statSync(options.file);\n if (!stat.isFile()) {\n throw new Error(`Not a regular file: ${options.file}`);\n }\n fileSize = stat.size;\n } catch (error) {\n if (error instanceof Error && error.message.startsWith(\"Not \")) {\n throw error;\n }\n throw new Error(`File not found: ${options.file}`);\n }\n\n if (fileSize === 0) {\n throw new Error(\"File is empty\");\n }\n\n const filename = basename(options.file);\n const contentType =\n options.contentType ?? inferContentType(options.file);\n\n const prepared = await initPhoneFileUpload({\n filename,\n contentType,\n length: fileSize,\n supportsUploadHeaders: true,\n });\n\n const fileContent = readFileSync(options.file);\n const uploadResponse = await fetch(prepared.uploadUrl, {\n method: \"PUT\",\n headers: {\n \"Content-Type\": prepared.contentType,\n ...prepared.uploadHeaders,\n },\n body: new Uint8Array(fileContent),\n });\n\n if (!uploadResponse.ok) {\n throw new Error(\n `File upload failed: ${uploadResponse.status} ${uploadResponse.statusText}`,\n );\n }\n\n const result = await completePhoneFileUpload({\n uploadId: prepared.uploadId,\n toNumber: options.to,\n agentphoneAgentId: options.agentId,\n contentType: prepared.contentType,\n caption: options.caption,\n });\n\n console.log(JSON.stringify(result));\n },\n ),\n );\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;ACAA;AAAA,SAAS,UAAU,YAAY;AAC/B,SAAS,cAAc;;;ACDvB;AAAA,SAAS,yBAAyB;AAClC,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AA4BzB,eAAsB,iBACpB,MACmC;AACnC,QAAM,SAAS,MAAM,gBAAgB;AACrC,QAAM,SAAS,WAAW,kCAAkC,MAAM;AAElE,QAAM,SAAS,MAAM,OAAO,YAAY,EAAE,MAAM,SAAS,CAAC,EAAE,CAAC;AAE7D,MAAI,OAAO,WAAW,KAAK;AACzB,WAAO,OAAO;AAAA,EAChB;AAEA,cAAY,QAAQ,mCAAmC;AACzD;AAEA,eAAsB,oBACpB,MACkC;AAClC,QAAM,SAAS,MAAM,gBAAgB;AACrC,QAAM,SAAS,WAAW,qCAAqC,MAAM;AAErE,QAAM,SAAS,MAAM,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC,EAAE,CAAC;AAEtD,MAAI,OAAO,WAAW,KAAK;AACzB,WAAO,OAAO;AAAA,EAChB;AAEA,cAAY,QAAQ,6CAA6C;AACnE;AAEA,eAAsB,wBACpB,MACsC;AACtC,QAAM,SAAS,MAAM,gBAAgB;AACrC,QAAM,SAAS,WAAW,yCAAyC,MAAM;AAEzE,QAAM,SAAS,MAAM,OAAO,SAAS,EAAE,MAAM,SAAS,CAAC,EAAE,CAAC;AAE1D,MAAI,OAAO,WAAW,KAAK;AACzB,WAAO,OAAO;AAAA,EAChB;AAEA,cAAY,QAAQ,2CAA2C;AACjE;AAKA,eAAsB,kBACpB,QACA,SACkC;AAClC,QAAM,UAAU,MAAM,WAAW;AACjC,QAAM,QAAQ,MAAM,eAAe;AACnC,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,gBAAgB,qBAAqB,gBAAgB,GAAG;AAAA,EACpE;AAEA,QAAM,MAAM,IAAI,IAAI,8CAA8C,OAAO;AACzE,MAAI,aAAa,IAAI,WAAW,MAAM;AAEtC,QAAM,UAAkC;AAAA,IACtC,eAAe,UAAU,KAAK;AAAA,EAChC;AAEA,QAAM,WAAW,MAAM,MAAM,KAAK;AAAA,IAChC,SAAS,4BAA4B,OAAO;AAAA,EAC9C,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,QAAI,UAAU,4CAA4C,SAAS,MAAM;AACzE,QAAI,OAAO;AACX,QAAI;AACF,YAAM,OAAQ,MAAM,SAAS,KAAK;AAGlC,UAAI,KAAK,OAAO,QAAS,WAAU,KAAK,MAAM;AAC9C,UAAI,KAAK,OAAO,KAAM,QAAO,KAAK,MAAM;AAAA,IAC1C,QAAQ;AAAA,IAER;AACA,UAAM,IAAI,gBAAgB,SAAS,MAAM,SAAS,MAAM;AAAA,EAC1D;AAEA,MAAI,CAAC,SAAS,MAAM;AAClB,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,WACJ,SAAS,QAAQ,IAAI,iBAAiB,KACtC,SAAS,QAAQ,IAAI,cAAc,KACnC;AAEF,QAAM;AAAA,IACJ,SAAS,QAAQ,SAAS,IAAa;AAAA,IACvC,kBAAkB,OAAO;AAAA,EAC3B;AAEA,QAAM,sBAAsB,SAAS,QAAQ,IAAI,gBAAgB;AACjE,QAAM,OAAO,sBAAsB,OAAO,mBAAmB,IAAI;AAEjE,SAAO,EAAE,MAAM,SAAS,UAAU,KAAK;AACzC;;;ADlIA,SAAS,eAAe,QAAwB;AAC9C,SAAO,KAAK,OAAO,GAAG,SAAS,SAAS,MAAM,CAAC,EAAE;AACnD;AAEO,IAAM,sBAAsB,IAAI,QAAQ,EAC5C,KAAK,eAAe,EACpB,YAAY,yCAAyC,EACrD;AAAA,EACC;AAAA,EACA;AACF,EACC;AAAA,EACC;AAAA,EACA;AACF,EACC;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBF,EACC;AAAA,EACC,iBAAiB,OAAO,QAAgB,YAA8B;AACpE,UAAM,UAAU,QAAQ,OAAO,eAAe,MAAM;AACpD,UAAM,SAAS,MAAM,kBAAkB,QAAQ,OAAO;AACtD,YAAQ,IAAI,KAAK,UAAU,MAAM,CAAC;AAAA,EACpC,CAAC;AACH;;;AE9CF;AAAA,SAAS,oBAAoB;AAMtB,IAAM,iBAAiB,IAAI,QAAQ,EACvC,KAAK,SAAS,EACd,YAAY,iCAAiC,EAC7C,eAAe,gBAAgB,mCAAmC,EAClE,OAAO,mBAAmB,6CAA6C,EACvE,OAAO,wBAAwB,cAAc,EAC7C;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQF,EACC;AAAA,EACC;AAAA,IACE,OAAO,YAA6D;AAClE,UAAI,OAAO,QAAQ;AACnB,UAAI,CAAC,QAAQ,CAAC,QAAQ,MAAM,OAAO;AACjC,YAAI;AACF,iBAAO,aAAa,cAAc,MAAM,EAAE,KAAK;AAAA,QACjD,QAAQ;AAAA,QAGR;AAAA,MACF;AAEA,UAAI,CAAC,MAAM;AACT,cAAM,IAAI,MAAM,iDAAiD;AAAA,UAC/D,OAAO,IAAI;AAAA,YACT;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAEA,YAAM,SAAS,MAAM,iBAAiB;AAAA,QACpC,UAAU,QAAQ;AAAA,QAClB;AAAA,QACA,mBAAmB,QAAQ;AAAA,MAC7B,CAAC;AAED,cAAQ;AAAA,QACN,eAAM,MAAM,oCAA+B,OAAO,SAAS,GAAG;AAAA,MAChE;AAAA,IACF;AAAA,EACF;AACF;;;ACvDF;AAAA,SAAS,gBAAAA,eAAc,gBAAgB;AACvC,SAAS,YAAAC,WAAU,eAAe;AAQlC,IAAM,oBAA4C;AAAA,EAChD,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AACX;AAEA,SAAS,iBAAiB,WAA2B;AACnD,QAAM,MAAM,QAAQ,SAAS,EAAE,YAAY;AAC3C,SAAO,kBAAkB,GAAG,KAAK;AACnC;AAEO,IAAM,oBAAoB,IAAI,QAAQ,EAC1C,KAAK,aAAa,EAClB,YAAY,mDAAmD,EAC/D,eAAe,qBAAqB,2BAA2B,EAC/D,eAAe,gBAAgB,mCAAmC,EAClE,OAAO,mBAAmB,6CAA6C,EACvE,OAAO,oBAAoB,+BAA+B,EAC1D,OAAO,yBAAyB,gCAAgC,EAChE;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQF,EACC;AAAA,EACC;AAAA,IACE,OAAO,YAMD;AACJ,UAAI;AACJ,UAAI;AACF,cAAM,OAAO,SAAS,QAAQ,IAAI;AAClC,YAAI,CAAC,KAAK,OAAO,GAAG;AAClB,gBAAM,IAAI,MAAM,uBAAuB,QAAQ,IAAI,EAAE;AAAA,QACvD;AACA,mBAAW,KAAK;AAAA,MAClB,SAAS,OAAO;AACd,YAAI,iBAAiB,SAAS,MAAM,QAAQ,WAAW,MAAM,GAAG;AAC9D,gBAAM;AAAA,QACR;AACA,cAAM,IAAI,MAAM,mBAAmB,QAAQ,IAAI,EAAE;AAAA,MACnD;AAEA,UAAI,aAAa,GAAG;AAClB,cAAM,IAAI,MAAM,eAAe;AAAA,MACjC;AAEA,YAAM,WAAWC,UAAS,QAAQ,IAAI;AACtC,YAAM,cACJ,QAAQ,eAAe,iBAAiB,QAAQ,IAAI;AAEtD,YAAM,WAAW,MAAM,oBAAoB;AAAA,QACzC;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR,uBAAuB;AAAA,MACzB,CAAC;AAED,YAAM,cAAcC,cAAa,QAAQ,IAAI;AAC7C,YAAM,iBAAiB,MAAM,MAAM,SAAS,WAAW;AAAA,QACrD,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB,SAAS;AAAA,UACzB,GAAG,SAAS;AAAA,QACd;AAAA,QACA,MAAM,IAAI,WAAW,WAAW;AAAA,MAClC,CAAC;AAED,UAAI,CAAC,eAAe,IAAI;AACtB,cAAM,IAAI;AAAA,UACR,uBAAuB,eAAe,MAAM,IAAI,eAAe,UAAU;AAAA,QAC3E;AAAA,MACF;AAEA,YAAM,SAAS,MAAM,wBAAwB;AAAA,QAC3C,UAAU,SAAS;AAAA,QACnB,UAAU,QAAQ;AAAA,QAClB,mBAAmB,QAAQ;AAAA,QAC3B,aAAa,SAAS;AAAA,QACtB,SAAS,QAAQ;AAAA,MACnB,CAAC;AAED,cAAQ,IAAI,KAAK,UAAU,MAAM,CAAC;AAAA,IACpC;AAAA,EACF;AACF;;;AJ9GK,IAAM,mBAAmB,IAAI,QAAQ,EACzC,KAAK,OAAO,EACZ,YAAY,4DAA4D,EACxE,WAAW,cAAc,EACzB,WAAW,mBAAmB,EAC9B,WAAW,iBAAiB,EAC5B;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAKF;","names":["readFileSync","basename","basename","readFileSync"]}
|
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire as __createRequire } from "node:module";
|
|
3
3
|
const require = __createRequire(import.meta.url);
|
|
4
|
+
import {
|
|
5
|
+
inferWebUploadContentType,
|
|
6
|
+
uploadWebFile
|
|
7
|
+
} from "./chunk-J3ZRXVI6.js";
|
|
4
8
|
import {
|
|
5
9
|
ZERO_RECOGNITION_MAX_FILE_BYTES,
|
|
6
10
|
ZERO_RECOGNITION_MAX_PROMPT_CHARS,
|
|
7
|
-
|
|
11
|
+
zeroRecognitionContract,
|
|
8
12
|
zeroRecognitionImageMimeTypeSchema
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
uploadWebFile
|
|
13
|
-
} from "./chunk-V7A6ZFHR.js";
|
|
14
|
-
import "./chunk-ANOLYIPL.js";
|
|
13
|
+
} from "./chunk-U6A2RPHO.js";
|
|
14
|
+
import "./chunk-SMPSKBAP.js";
|
|
15
|
+
import "./chunk-JV6LM2YC.js";
|
|
15
16
|
import {
|
|
16
17
|
ApiRequestError,
|
|
18
|
+
getClientConfig,
|
|
19
|
+
handleError,
|
|
20
|
+
initClient,
|
|
17
21
|
withErrorHandler
|
|
18
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-GHKWW4NC.js";
|
|
19
23
|
import "./chunk-32FE3MDA.js";
|
|
20
24
|
import {
|
|
21
25
|
Command
|
|
@@ -27,6 +31,20 @@ import {
|
|
|
27
31
|
// src/commands/zero/recognize/index.ts
|
|
28
32
|
init_esm_shims();
|
|
29
33
|
import { statSync } from "fs";
|
|
34
|
+
|
|
35
|
+
// src/lib/api/domains/zero-recognition.ts
|
|
36
|
+
init_esm_shims();
|
|
37
|
+
async function callZeroRecognition(body) {
|
|
38
|
+
const config = await getClientConfig();
|
|
39
|
+
const client = initClient(zeroRecognitionContract, config);
|
|
40
|
+
const result = await client.recognize({ headers: {}, body });
|
|
41
|
+
if (result.status === 200) {
|
|
42
|
+
return result.body;
|
|
43
|
+
}
|
|
44
|
+
handleError(result, "Failed to recognize image");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// src/commands/zero/recognize/index.ts
|
|
30
48
|
function validatePrompt(prompt) {
|
|
31
49
|
const trimmed = prompt.trim();
|
|
32
50
|
if (!trimmed) {
|
|
@@ -104,4 +122,4 @@ Notes:
|
|
|
104
122
|
export {
|
|
105
123
|
zeroRecognizeCommand
|
|
106
124
|
};
|
|
107
|
-
//# sourceMappingURL=recognize-
|
|
125
|
+
//# sourceMappingURL=recognize-D7VORZBN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/zero/recognize/index.ts","../src/lib/api/domains/zero-recognition.ts"],"sourcesContent":["import { statSync } from \"node:fs\";\n\nimport {\n ZERO_RECOGNITION_MAX_FILE_BYTES,\n ZERO_RECOGNITION_MAX_PROMPT_CHARS,\n zeroRecognitionImageMimeTypeSchema,\n type ZeroRecognitionImageMimeType,\n} from \"@vm0/api-contracts/contracts/zero-recognition\";\nimport { Command } from \"commander\";\n\nimport { ApiRequestError } from \"../../../lib/api/core/client-factory\";\nimport { callZeroRecognition } from \"../../../lib/api/domains/zero-recognition\";\nimport {\n inferWebUploadContentType,\n uploadWebFile,\n} from \"../../../lib/api/domains/web\";\nimport { withErrorHandler } from \"../../../lib/command/with-error-handler\";\n\ninterface RecognizeOptions {\n readonly file: string;\n readonly prompt: string;\n}\n\nfunction validatePrompt(prompt: string): string {\n const trimmed = prompt.trim();\n if (!trimmed) {\n throw new ApiRequestError(\n \"Recognition prompt must not be empty\",\n \"BAD_REQUEST\",\n 400,\n );\n }\n if (trimmed.length > ZERO_RECOGNITION_MAX_PROMPT_CHARS) {\n throw new ApiRequestError(\n `Recognition prompt must be ${ZERO_RECOGNITION_MAX_PROMPT_CHARS} characters or fewer`,\n \"BAD_REQUEST\",\n 400,\n );\n }\n return trimmed;\n}\n\nfunction validateImageFile(file: string): ZeroRecognitionImageMimeType {\n const stats = statSync(file);\n if (!stats.isFile()) {\n throw new ApiRequestError(\n `Not a regular file: ${file}`,\n \"BAD_REQUEST\",\n 400,\n );\n }\n if (stats.size === 0) {\n throw new ApiRequestError(\n \"Image file must not be empty\",\n \"BAD_REQUEST\",\n 400,\n );\n }\n if (stats.size > ZERO_RECOGNITION_MAX_FILE_BYTES) {\n throw new ApiRequestError(\n \"Image file must be 20 MB or smaller\",\n \"PAYLOAD_TOO_LARGE\",\n 413,\n );\n }\n\n const contentType = inferWebUploadContentType(file);\n const parsed = zeroRecognitionImageMimeTypeSchema.safeParse(contentType);\n if (!parsed.success) {\n throw new ApiRequestError(\n \"Image must be a PNG, JPEG, or WebP file\",\n \"BAD_REQUEST\",\n 400,\n );\n }\n return parsed.data;\n}\n\nexport const zeroRecognizeCommand = new Command()\n .name(\"recognize\")\n .description(\"Recognize one image through a managed multimodal model\")\n .requiredOption(\"-f, --file <path>\", \"Local PNG, JPEG, or WebP image\")\n .requiredOption(\"-p, --prompt <instruction>\", \"Recognition instruction\")\n .action(\n withErrorHandler(async (options: RecognizeOptions) => {\n const prompt = validatePrompt(options.prompt);\n const contentType = validateImageFile(options.file);\n const uploaded = await uploadWebFile(options.file, { contentType });\n const response = await callZeroRecognition({\n fileId: uploaded.id,\n prompt,\n });\n console.log(response.text);\n }),\n )\n .addHelpText(\n \"after\",\n `\nExample:\n zero recognize --file ./screenshot.png --prompt \"Describe the error shown\"\n\nNotes:\n - Available only in runs whose selected model does not support image input\n - Accepts one PNG, JPEG, or WebP image up to 20 MB\n - Uses a fixed vm0-managed recognition model and prints only recognized text`,\n );\n","import {\n zeroRecognitionContract,\n type ZeroRecognitionRequest,\n type ZeroRecognitionResponse,\n} from \"@vm0/api-contracts/contracts/zero-recognition\";\nimport { initClient } from \"@vm0/api-contracts/contracts/trpc-contract\";\n\nimport { getClientConfig, handleError } from \"../core/client-factory\";\n\nexport async function callZeroRecognition(\n body: ZeroRecognitionRequest,\n): Promise<ZeroRecognitionResponse> {\n const config = await getClientConfig();\n const client = initClient(zeroRecognitionContract, config);\n const result = await client.recognize({ headers: {}, body });\n if (result.status === 200) {\n return result.body;\n }\n handleError(result, \"Failed to recognize image\");\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,SAAS,gBAAgB;;;ACAzB;AASA,eAAsB,oBACpB,MACkC;AAClC,QAAM,SAAS,MAAM,gBAAgB;AACrC,QAAM,SAAS,WAAW,yBAAyB,MAAM;AACzD,QAAM,SAAS,MAAM,OAAO,UAAU,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC;AAC3D,MAAI,OAAO,WAAW,KAAK;AACzB,WAAO,OAAO;AAAA,EAChB;AACA,cAAY,QAAQ,2BAA2B;AACjD;;;ADIA,SAAS,eAAe,QAAwB;AAC9C,QAAM,UAAU,OAAO,KAAK;AAC5B,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI,QAAQ,SAAS,mCAAmC;AACtD,UAAM,IAAI;AAAA,MACR,8BAA8B,iCAAiC;AAAA,MAC/D;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,MAA4C;AACrE,QAAM,QAAQ,SAAS,IAAI;AAC3B,MAAI,CAAC,MAAM,OAAO,GAAG;AACnB,UAAM,IAAI;AAAA,MACR,uBAAuB,IAAI;AAAA,MAC3B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI,MAAM,SAAS,GAAG;AACpB,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI,MAAM,OAAO,iCAAiC;AAChD,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,cAAc,0BAA0B,IAAI;AAClD,QAAM,SAAS,mCAAmC,UAAU,WAAW;AACvE,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAO,OAAO;AAChB;AAEO,IAAM,uBAAuB,IAAI,QAAQ,EAC7C,KAAK,WAAW,EAChB,YAAY,wDAAwD,EACpE,eAAe,qBAAqB,gCAAgC,EACpE,eAAe,8BAA8B,yBAAyB,EACtE;AAAA,EACC,iBAAiB,OAAO,YAA8B;AACpD,UAAM,SAAS,eAAe,QAAQ,MAAM;AAC5C,UAAM,cAAc,kBAAkB,QAAQ,IAAI;AAClD,UAAM,WAAW,MAAM,cAAc,QAAQ,MAAM,EAAE,YAAY,CAAC;AAClE,UAAM,WAAW,MAAM,oBAAoB;AAAA,MACzC,QAAQ,SAAS;AAAA,MACjB;AAAA,IACF,CAAC;AACD,YAAQ,IAAI,SAAS,IAAI;AAAA,EAC3B,CAAC;AACH,EACC;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQF;","names":[]}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire as __createRequire } from "node:module";
|
|
3
3
|
const require = __createRequire(import.meta.url);
|
|
4
|
+
import {
|
|
5
|
+
registryResourceDownloadContract
|
|
6
|
+
} from "./chunk-CCTF3YVW.js";
|
|
4
7
|
import {
|
|
5
8
|
findColorSystem,
|
|
6
9
|
findDesignSystem,
|
|
@@ -11,15 +14,14 @@ import {
|
|
|
11
14
|
findVideoTemplate,
|
|
12
15
|
findWebsiteTemplateResource
|
|
13
16
|
} from "./chunk-NKYACNWA.js";
|
|
17
|
+
import "./chunk-JV6LM2YC.js";
|
|
14
18
|
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
import "./chunk-ANOLYIPL.js";
|
|
19
|
-
import {
|
|
19
|
+
getClientConfig,
|
|
20
|
+
handleError,
|
|
21
|
+
initClient,
|
|
20
22
|
source_default,
|
|
21
23
|
withErrorHandler
|
|
22
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-GHKWW4NC.js";
|
|
23
25
|
import "./chunk-32FE3MDA.js";
|
|
24
26
|
import {
|
|
25
27
|
Command
|
|
@@ -3005,6 +3007,18 @@ var To = (s3) => {
|
|
|
3005
3007
|
s3.mtimeCache || (s3.mtimeCache = /* @__PURE__ */ new Map()), s3.filter = t ? (e, i) => t(e, i) && !((s3.mtimeCache?.get(e) ?? i.mtime ?? 0) > (i.mtime ?? 0)) : (e, i) => !((s3.mtimeCache?.get(e) ?? i.mtime ?? 0) > (i.mtime ?? 0));
|
|
3006
3008
|
};
|
|
3007
3009
|
|
|
3010
|
+
// src/lib/api/domains/registry-resources.ts
|
|
3011
|
+
init_esm_shims();
|
|
3012
|
+
async function getRegistryResourceDownload(query) {
|
|
3013
|
+
const config = await getClientConfig();
|
|
3014
|
+
const client = initClient(registryResourceDownloadContract, config);
|
|
3015
|
+
const result = await client.download({ query });
|
|
3016
|
+
if (result.status === 200) {
|
|
3017
|
+
return result.body;
|
|
3018
|
+
}
|
|
3019
|
+
handleError(result, `Registry resource "${query.id}" not found`);
|
|
3020
|
+
}
|
|
3021
|
+
|
|
3008
3022
|
// src/commands/zero/resource/index.ts
|
|
3009
3023
|
function candidateIds(id) {
|
|
3010
3024
|
if (id.includes(":")) {
|
|
@@ -3110,4 +3124,4 @@ export {
|
|
|
3110
3124
|
findRegistryResourceForPull,
|
|
3111
3125
|
zeroResourceCommand
|
|
3112
3126
|
};
|
|
3113
|
-
//# sourceMappingURL=resource-
|
|
3127
|
+
//# sourceMappingURL=resource-76IV3TMW.js.map
|