@qoniai/qoni 0.4.3 → 0.5.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/CHANGELOG.md +19 -0
- package/README.md +26 -0
- package/README.zh-CN.md +25 -0
- package/dist/index.cjs +82 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +32 -1
- package/dist/index.d.ts +32 -1
- package/dist/index.js +82 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.0 - 2026-09-17
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Let Do Anything callers select a server-managed Browserbase proxy by ID, choose
|
|
8
|
+
`off`, `all`, or `scoped` routing, and select a supported Browserbase compute
|
|
9
|
+
region with `browserProxy`.
|
|
10
|
+
|
|
11
|
+
### Security
|
|
12
|
+
|
|
13
|
+
- Reject proxy URLs, usernames, passwords, and any unknown proxy option locally.
|
|
14
|
+
Proxy credentials remain in the backend's private registry and never cross the
|
|
15
|
+
public SDK API.
|
|
16
|
+
|
|
17
|
+
## 0.4.4
|
|
18
|
+
|
|
19
|
+
- Populate Do Anything `result.artifacts` from durable run files, including attached runs.
|
|
20
|
+
- Expose signed download URLs, per-file link refresh, and explicit file listing.
|
|
21
|
+
|
|
3
22
|
All notable changes to `@qoniai/qoni` are documented in this file.
|
|
4
23
|
|
|
5
24
|
This project follows semantic versioning. Before `1.0.0`, minor versions may
|
package/README.md
CHANGED
|
@@ -391,12 +391,22 @@ const context = await qoni.gumem.recall({
|
|
|
391
391
|
const run = await qoni.doAnything.run({
|
|
392
392
|
token,
|
|
393
393
|
prompt: "Open https://en.wikipedia.org/wiki/Solid-state_battery and summarize its key advantages over lithium-ion.",
|
|
394
|
+
browserProxy: {
|
|
395
|
+
proxyId: "sg-static", // server-side registry id; never pass credentials here
|
|
396
|
+
mode: "scoped", // off | all | scoped
|
|
397
|
+
region: "ap-southeast-1",
|
|
398
|
+
},
|
|
394
399
|
});
|
|
395
400
|
|
|
396
401
|
const status = await run.status(); // refresh the run's current state
|
|
397
402
|
await run.cancel("User stopped the task"); // idempotent
|
|
398
403
|
```
|
|
399
404
|
|
|
405
|
+
`browserProxy` affects only newly created Browserbase sessions. `region` selects
|
|
406
|
+
Browserbase compute, while the registered proxy controls network egress. The SDK
|
|
407
|
+
accepts only a proxy ID, mode, and region; operators manage proxy credentials in
|
|
408
|
+
OpsConsole.
|
|
409
|
+
|
|
400
410
|
### Web Search
|
|
401
411
|
|
|
402
412
|
```ts
|
|
@@ -785,3 +795,19 @@ Common first-run errors:
|
|
|
785
795
|
## License
|
|
786
796
|
|
|
787
797
|
MIT
|
|
798
|
+
|
|
799
|
+
## Do Anything file artifacts
|
|
800
|
+
|
|
801
|
+
After `wait()`, `result.artifacts` contains this run's persisted files, including when using `attach()` after reconnecting. Screenshots and recordings remain on their dedicated APIs. Temporary S3 URLs expire 900 seconds after signing; do not put them in public logs. Refreshing a link requires a valid delegation token with `webagent.do_anything:read`. Stored files remain subject to project retention.
|
|
802
|
+
|
|
803
|
+
```ts
|
|
804
|
+
const result = await run.wait();
|
|
805
|
+
for (const artifact of result.artifacts) {
|
|
806
|
+
let url = artifact.downloadUrl;
|
|
807
|
+
url = await artifact.refreshDownloadUrl?.();
|
|
808
|
+
const data = await artifact.content(); // Uint8Array, authenticated download
|
|
809
|
+
}
|
|
810
|
+
const artifacts = await client.doAnything.artifacts({ token, runId: run.id });
|
|
811
|
+
```
|
|
812
|
+
|
|
813
|
+
Wire methods: `client.doAnything.api.listArtifacts(...)` and `artifactDownloadUrl(...)`.
|
package/README.zh-CN.md
CHANGED
|
@@ -362,12 +362,21 @@ const context = await qoni.gumem.recall({
|
|
|
362
362
|
const run = await qoni.doAnything.run({
|
|
363
363
|
token,
|
|
364
364
|
prompt: "打开 https://en.wikipedia.org/wiki/Solid-state_battery ,总结它相对锂离子电池的主要优势。",
|
|
365
|
+
browserProxy: {
|
|
366
|
+
proxyId: "sg-static", // 服务端代理注册表 ID;这里绝不传凭据
|
|
367
|
+
mode: "scoped", // off | all | scoped
|
|
368
|
+
region: "ap-southeast-1",
|
|
369
|
+
},
|
|
365
370
|
});
|
|
366
371
|
|
|
367
372
|
const status = await run.status(); // 刷新并返回当前状态
|
|
368
373
|
await run.cancel("用户停止任务"); // 幂等
|
|
369
374
|
```
|
|
370
375
|
|
|
376
|
+
`browserProxy` 只影响新建的 Browserbase 会话。`region` 选择 Browserbase
|
|
377
|
+
计算区域,注册代理决定网络出口。SDK 只接受代理 ID、模式和区域;代理账号密码由
|
|
378
|
+
运维人员在 OpsConsole 管理。
|
|
379
|
+
|
|
371
380
|
### Web Search
|
|
372
381
|
|
|
373
382
|
```ts
|
|
@@ -715,3 +724,19 @@ try {
|
|
|
715
724
|
## License
|
|
716
725
|
|
|
717
726
|
MIT
|
|
727
|
+
|
|
728
|
+
## Do Anything file artifacts
|
|
729
|
+
|
|
730
|
+
After `wait()`, `result.artifacts` contains this run's persisted files, including when using `attach()` after reconnecting. Screenshots and recordings remain on their dedicated APIs. Temporary S3 URLs expire 900 seconds after signing; do not put them in public logs. Refreshing a link requires a valid delegation token with `webagent.do_anything:read`. Stored files remain subject to project retention.
|
|
731
|
+
|
|
732
|
+
```ts
|
|
733
|
+
const result = await run.wait();
|
|
734
|
+
for (const artifact of result.artifacts) {
|
|
735
|
+
let url = artifact.downloadUrl;
|
|
736
|
+
url = await artifact.refreshDownloadUrl?.();
|
|
737
|
+
const data = await artifact.content(); // Uint8Array, authenticated download
|
|
738
|
+
}
|
|
739
|
+
const artifacts = await client.doAnything.artifacts({ token, runId: run.id });
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
Wire methods: `client.doAnything.api.listArtifacts(...)` and `artifactDownloadUrl(...)`.
|
package/dist/index.cjs
CHANGED
|
@@ -1194,6 +1194,34 @@ var PLATFORM_DECIDED_RUN_OPTIONS = [
|
|
|
1194
1194
|
"outputSchema",
|
|
1195
1195
|
"cacheScript"
|
|
1196
1196
|
];
|
|
1197
|
+
var BROWSERBASE_REGIONS = /* @__PURE__ */ new Set([
|
|
1198
|
+
"us-west-2",
|
|
1199
|
+
"us-east-1",
|
|
1200
|
+
"eu-central-1",
|
|
1201
|
+
"ap-southeast-1"
|
|
1202
|
+
]);
|
|
1203
|
+
function validateBrowserProxyOptions(value) {
|
|
1204
|
+
if (value === void 0) return;
|
|
1205
|
+
if (!isJsonObject(value)) {
|
|
1206
|
+
throw new QoniValidationError("browserProxy must be an object");
|
|
1207
|
+
}
|
|
1208
|
+
const allowed = /* @__PURE__ */ new Set(["proxyId", "mode", "region"]);
|
|
1209
|
+
const extras = Object.keys(value).filter((key) => !allowed.has(key));
|
|
1210
|
+
if (extras.length > 0) {
|
|
1211
|
+
throw new QoniValidationError(
|
|
1212
|
+
`browserProxy does not accept ${extras.join(", ")} \u2014 credentials stay server-side`
|
|
1213
|
+
);
|
|
1214
|
+
}
|
|
1215
|
+
if (value.proxyId !== void 0 && (typeof value.proxyId !== "string" || !/^[a-z0-9][a-z0-9._-]{0,63}$/.test(value.proxyId))) {
|
|
1216
|
+
throw new QoniValidationError("browserProxy.proxyId is invalid");
|
|
1217
|
+
}
|
|
1218
|
+
if (value.mode !== void 0 && !["off", "all", "scoped"].includes(String(value.mode))) {
|
|
1219
|
+
throw new QoniValidationError("browserProxy.mode must be off, all, or scoped");
|
|
1220
|
+
}
|
|
1221
|
+
if (value.region !== void 0 && (typeof value.region !== "string" || !BROWSERBASE_REGIONS.has(value.region))) {
|
|
1222
|
+
throw new QoniValidationError("browserProxy.region is not supported");
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1197
1225
|
function createDoAnythingNamespace(transport) {
|
|
1198
1226
|
const api = {
|
|
1199
1227
|
createSession: (input) => transport.webAgentJson("POST", "/do_anything/sessions", input.token, {
|
|
@@ -1262,6 +1290,18 @@ function createDoAnythingNamespace(transport) {
|
|
|
1262
1290
|
requiredScopes: ["webagent.do_anything:read"]
|
|
1263
1291
|
}
|
|
1264
1292
|
),
|
|
1293
|
+
listArtifacts: (input) => transport.webAgentJson(
|
|
1294
|
+
"GET",
|
|
1295
|
+
`/do_anything/runs/${encodeURIComponent(input.runId)}/artifacts`,
|
|
1296
|
+
input.token,
|
|
1297
|
+
{ signal: input.signal, requiredScopes: ["webagent.do_anything:read"] }
|
|
1298
|
+
),
|
|
1299
|
+
artifactDownloadUrl: (input) => transport.webAgentJson(
|
|
1300
|
+
"GET",
|
|
1301
|
+
`/do_anything/artifacts/${encodeURIComponent(input.artifactId)}/download-url`,
|
|
1302
|
+
input.token,
|
|
1303
|
+
{ requiredScopes: ["webagent.do_anything:read"] }
|
|
1304
|
+
),
|
|
1265
1305
|
readRecording: (input) => transport.webAgentJson(
|
|
1266
1306
|
"GET",
|
|
1267
1307
|
`/do_anything/sessions/${encodeURIComponent(input.sessionId)}/recording`,
|
|
@@ -1271,8 +1311,42 @@ function createDoAnythingNamespace(transport) {
|
|
|
1271
1311
|
}
|
|
1272
1312
|
)
|
|
1273
1313
|
};
|
|
1314
|
+
async function artifacts(input) {
|
|
1315
|
+
const { data } = await api.listArtifacts(input);
|
|
1316
|
+
if (!isJsonObject(data) || !Array.isArray(data.items)) {
|
|
1317
|
+
throw new QoniValidationError("artifact list response requires items");
|
|
1318
|
+
}
|
|
1319
|
+
return data.items.map((item) => {
|
|
1320
|
+
if (!isJsonObject(item) || typeof item.id !== "string" || !item.id) {
|
|
1321
|
+
throw new QoniValidationError("artifact requires a nonempty id");
|
|
1322
|
+
}
|
|
1323
|
+
const id = item.id;
|
|
1324
|
+
const artifact = {
|
|
1325
|
+
id,
|
|
1326
|
+
name: typeof item.name === "string" ? item.name : void 0,
|
|
1327
|
+
mime: typeof item.mime_type === "string" ? item.mime_type : void 0,
|
|
1328
|
+
sizeBytes: typeof item.size_bytes === "number" ? item.size_bytes : void 0,
|
|
1329
|
+
createdAt: typeof item.created_at === "string" ? item.created_at : void 0,
|
|
1330
|
+
downloadUrl: typeof item.download_url === "string" ? item.download_url : void 0,
|
|
1331
|
+
expiresIn: typeof item.expires_in === "number" ? item.expires_in : void 0,
|
|
1332
|
+
content: async () => (await transport.webAgentBytes(
|
|
1333
|
+
`/do_anything/artifacts/${encodeURIComponent(id)}/blob`,
|
|
1334
|
+
input.token,
|
|
1335
|
+
{ requiredScopes: ["webagent.do_anything:read"] }
|
|
1336
|
+
)).bytes,
|
|
1337
|
+
refreshDownloadUrl: async () => {
|
|
1338
|
+
const { data: link } = await api.artifactDownloadUrl({ token: input.token, artifactId: id });
|
|
1339
|
+
artifact.downloadUrl = link.download_url;
|
|
1340
|
+
artifact.expiresIn = link.expires_in;
|
|
1341
|
+
return link.download_url;
|
|
1342
|
+
}
|
|
1343
|
+
};
|
|
1344
|
+
return artifact;
|
|
1345
|
+
});
|
|
1346
|
+
}
|
|
1274
1347
|
function buildOps(token, runId, capture) {
|
|
1275
1348
|
return {
|
|
1349
|
+
listArtifacts: (signal) => artifacts({ token, runId, signal }),
|
|
1276
1350
|
getDetail: async (signal) => asRecord2((await api.getRun({ token, runId, signal })).data),
|
|
1277
1351
|
streamEvents: (opts) => api.events({
|
|
1278
1352
|
token,
|
|
@@ -1310,6 +1384,7 @@ function createDoAnythingNamespace(transport) {
|
|
|
1310
1384
|
if (!prompt || typeof prompt !== "string") {
|
|
1311
1385
|
throw new QoniValidationError("doAnything.run requires a prompt string");
|
|
1312
1386
|
}
|
|
1387
|
+
validateBrowserProxyOptions(rest.browserProxy);
|
|
1313
1388
|
const unsupported = PLATFORM_DECIDED_RUN_OPTIONS.filter(
|
|
1314
1389
|
(key) => rest[key] !== void 0
|
|
1315
1390
|
);
|
|
@@ -1351,6 +1426,7 @@ function createDoAnythingNamespace(transport) {
|
|
|
1351
1426
|
await handle.status();
|
|
1352
1427
|
return handle;
|
|
1353
1428
|
},
|
|
1429
|
+
artifacts,
|
|
1354
1430
|
api
|
|
1355
1431
|
};
|
|
1356
1432
|
}
|
|
@@ -1360,8 +1436,13 @@ function normalizeDoAnythingRunInput(input) {
|
|
|
1360
1436
|
profileId: "profile_id",
|
|
1361
1437
|
keepAlive: "keep_alive",
|
|
1362
1438
|
allowedActions: "allowed_actions",
|
|
1363
|
-
maxDurationMinutes: "max_duration_minutes"
|
|
1439
|
+
maxDurationMinutes: "max_duration_minutes",
|
|
1440
|
+
browserProxy: "browser_proxy"
|
|
1364
1441
|
});
|
|
1442
|
+
const browserProxy = body.browser_proxy;
|
|
1443
|
+
if (isJsonObject(browserProxy)) {
|
|
1444
|
+
body.browser_proxy = renameKeys2(browserProxy, { proxyId: "proxy_id" });
|
|
1445
|
+
}
|
|
1365
1446
|
return body;
|
|
1366
1447
|
}
|
|
1367
1448
|
function normalizeDoAnythingInterveneInput(input) {
|