codai-sdk 0.4.0 → 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/README.md +47 -2
- package/dist/index.d.ts +2473 -1560
- package/dist/index.js +197 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1219,6 +1219,173 @@ var Projects = class {
|
|
|
1219
1219
|
}
|
|
1220
1220
|
};
|
|
1221
1221
|
|
|
1222
|
+
// src/resources/resolve.ts
|
|
1223
|
+
var RESOLVE_TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
1224
|
+
"resolved",
|
|
1225
|
+
"failed",
|
|
1226
|
+
"declined",
|
|
1227
|
+
"error"
|
|
1228
|
+
]);
|
|
1229
|
+
var ResolveError = class extends CodaiError {
|
|
1230
|
+
/** The `error` field of the body: a message, or Zod `flatten()` details on a 400. */
|
|
1231
|
+
detail;
|
|
1232
|
+
constructor(message, status, body, meta = {}) {
|
|
1233
|
+
super(message, status, body, meta);
|
|
1234
|
+
this.name = "ResolveError";
|
|
1235
|
+
this.detail = extractDetail(body);
|
|
1236
|
+
}
|
|
1237
|
+
};
|
|
1238
|
+
var ResolveInsufficientFundsError = class extends ResolveError {
|
|
1239
|
+
/** Wallet balance, in `currency` units (EUR micros). */
|
|
1240
|
+
balance;
|
|
1241
|
+
/** Amount the hold needs, in `currency` units (EUR micros). */
|
|
1242
|
+
required;
|
|
1243
|
+
currency;
|
|
1244
|
+
/** pay.codai.ro checkout link for the shortfall — open it, then retry `accept()`. */
|
|
1245
|
+
topupUrl;
|
|
1246
|
+
constructor(message, body, meta = {}) {
|
|
1247
|
+
super(message, 402, body, meta);
|
|
1248
|
+
this.name = "ResolveInsufficientFundsError";
|
|
1249
|
+
this.balance = body.balance;
|
|
1250
|
+
this.required = body.required;
|
|
1251
|
+
this.currency = body.currency;
|
|
1252
|
+
this.topupUrl = body.topup_url;
|
|
1253
|
+
}
|
|
1254
|
+
};
|
|
1255
|
+
var Resolve = class {
|
|
1256
|
+
constructor(http) {
|
|
1257
|
+
this.http = http;
|
|
1258
|
+
}
|
|
1259
|
+
http;
|
|
1260
|
+
/**
|
|
1261
|
+
* `POST /v1/resolve/jobs` — submit a public GitHub repo + issue for triage.
|
|
1262
|
+
* Returns a quote (`status: 'quoted'`), a free-tier auto-accept
|
|
1263
|
+
* (`status: 'accepted'`) or a decline (`status: 'declined'`). Never retried:
|
|
1264
|
+
* a retry could create a second job.
|
|
1265
|
+
*/
|
|
1266
|
+
submit(body, opts = {}) {
|
|
1267
|
+
if (!body.issue_url && !body.issue_text)
|
|
1268
|
+
throw new TypeError("resolve.submit: one of issue_url or issue_text is required");
|
|
1269
|
+
return this.call("/v1/resolve/jobs", {
|
|
1270
|
+
method: "POST",
|
|
1271
|
+
body,
|
|
1272
|
+
noRetry: true,
|
|
1273
|
+
signal: opts.signal
|
|
1274
|
+
});
|
|
1275
|
+
}
|
|
1276
|
+
/** `GET /v1/resolve/jobs/{id}` — status, quote, reasons, cost and attestation pointer. */
|
|
1277
|
+
get(id, opts = {}) {
|
|
1278
|
+
return this.call(`/v1/resolve/jobs/${encodeURIComponent(id)}`, {
|
|
1279
|
+
signal: opts.signal
|
|
1280
|
+
});
|
|
1281
|
+
}
|
|
1282
|
+
/**
|
|
1283
|
+
* `POST /v1/resolve/jobs/{id}/accept` — accept a paid quote and start the job.
|
|
1284
|
+
* Throws `ResolveInsufficientFundsError` (402, carries `topupUrl`) when the
|
|
1285
|
+
* wallet is short, `ResolveError` 409 when the job is not `quoted`.
|
|
1286
|
+
*/
|
|
1287
|
+
accept(id, opts = {}) {
|
|
1288
|
+
return this.call(`/v1/resolve/jobs/${encodeURIComponent(id)}/accept`, {
|
|
1289
|
+
method: "POST",
|
|
1290
|
+
rawBody: "",
|
|
1291
|
+
// no body — sent with content-length: 0
|
|
1292
|
+
noRetry: true,
|
|
1293
|
+
signal: opts.signal
|
|
1294
|
+
});
|
|
1295
|
+
}
|
|
1296
|
+
/**
|
|
1297
|
+
* `GET /v1/resolve/attestations/{id}` — public execution proof (no auth needed
|
|
1298
|
+
* server-side). Accepts the attestation id or the job's `attestation_url`.
|
|
1299
|
+
*/
|
|
1300
|
+
attestation(idOrUrl, opts = {}) {
|
|
1301
|
+
const id = idOrUrl.replace(/^.*\/v1\/resolve\/attestations\//, "");
|
|
1302
|
+
return this.call(`/v1/resolve/attestations/${encodeURIComponent(id)}`, {
|
|
1303
|
+
signal: opts.signal
|
|
1304
|
+
});
|
|
1305
|
+
}
|
|
1306
|
+
/** `GET /health` — liveness of the Resolve service. */
|
|
1307
|
+
health(opts = {}) {
|
|
1308
|
+
return this.call("/health", { signal: opts.signal });
|
|
1309
|
+
}
|
|
1310
|
+
/**
|
|
1311
|
+
* Poll `get(id)` until the job reaches a terminal status (`resolved`,
|
|
1312
|
+
* `failed`, `declined`, `error`) or one of `opts.until`. A `quoted` job
|
|
1313
|
+
* does not move until you `accept()` it.
|
|
1314
|
+
*/
|
|
1315
|
+
async waitFor(id, opts = {}) {
|
|
1316
|
+
const intervalMs = opts.intervalMs ?? 5e3;
|
|
1317
|
+
const timeoutMs = opts.timeoutMs ?? 18e5;
|
|
1318
|
+
const until = new Set(opts.until ?? RESOLVE_TERMINAL_STATUSES);
|
|
1319
|
+
const deadline = Date.now() + timeoutMs;
|
|
1320
|
+
for (; ; ) {
|
|
1321
|
+
const job = await this.get(id, { signal: opts.signal });
|
|
1322
|
+
opts.onPoll?.(job);
|
|
1323
|
+
if (until.has(job.status)) return job;
|
|
1324
|
+
const left = deadline - Date.now();
|
|
1325
|
+
if (left <= 0)
|
|
1326
|
+
throw new ResolveError(
|
|
1327
|
+
`codai-resolve job ${id} still ${job.status} after ${timeoutMs} ms`,
|
|
1328
|
+
0,
|
|
1329
|
+
job
|
|
1330
|
+
);
|
|
1331
|
+
await abortableSleep(Math.min(intervalMs, left), opts.signal);
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
async call(path, init) {
|
|
1335
|
+
try {
|
|
1336
|
+
return await this.http.json(path, init);
|
|
1337
|
+
} catch (err) {
|
|
1338
|
+
throw toResolveError(path, err);
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
};
|
|
1342
|
+
function extractDetail(body) {
|
|
1343
|
+
if (body && typeof body === "object" && "error" in body) {
|
|
1344
|
+
const e = body.error;
|
|
1345
|
+
if (typeof e === "string") return e;
|
|
1346
|
+
if (e && typeof e === "object") return e;
|
|
1347
|
+
}
|
|
1348
|
+
return null;
|
|
1349
|
+
}
|
|
1350
|
+
function isInsufficientFunds(body) {
|
|
1351
|
+
return !!body && typeof body === "object" && body.error === "insufficient_funds" && typeof body.topup_url === "string";
|
|
1352
|
+
}
|
|
1353
|
+
function toResolveError(path, err) {
|
|
1354
|
+
if (!(err instanceof CodaiError) || err instanceof ResolveError) return err;
|
|
1355
|
+
if (err.status === 0) return err;
|
|
1356
|
+
const meta = { requestId: err.requestId, retryAfter: err.retryAfter };
|
|
1357
|
+
if (err.status === 402 && isInsufficientFunds(err.body)) {
|
|
1358
|
+
const b = err.body;
|
|
1359
|
+
return new ResolveInsufficientFundsError(
|
|
1360
|
+
`codai-resolve ${path} \u2192 402: insufficient funds (balance ${b.balance}, required ${b.required} ${b.currency}); top up at ${b.topup_url}`,
|
|
1361
|
+
b,
|
|
1362
|
+
meta
|
|
1363
|
+
);
|
|
1364
|
+
}
|
|
1365
|
+
const detail = extractDetail(err.body);
|
|
1366
|
+
const text = detail === null ? "" : `: ${typeof detail === "string" ? detail : JSON.stringify(detail)}`;
|
|
1367
|
+
return new ResolveError(
|
|
1368
|
+
`codai-resolve ${path} \u2192 ${err.status}${text}`,
|
|
1369
|
+
err.status,
|
|
1370
|
+
err.body,
|
|
1371
|
+
meta
|
|
1372
|
+
);
|
|
1373
|
+
}
|
|
1374
|
+
function abortableSleep(ms, signal) {
|
|
1375
|
+
return new Promise((resolve, reject) => {
|
|
1376
|
+
if (signal?.aborted) return reject(signal.reason);
|
|
1377
|
+
const onAbort = () => {
|
|
1378
|
+
clearTimeout(t);
|
|
1379
|
+
reject(signal?.reason);
|
|
1380
|
+
};
|
|
1381
|
+
const t = setTimeout(() => {
|
|
1382
|
+
signal?.removeEventListener("abort", onAbort);
|
|
1383
|
+
resolve();
|
|
1384
|
+
}, ms);
|
|
1385
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
1386
|
+
});
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1222
1389
|
// src/resources/responses.ts
|
|
1223
1390
|
var Responses = class {
|
|
1224
1391
|
constructor(http) {
|
|
@@ -1663,6 +1830,14 @@ var Notifications = class {
|
|
|
1663
1830
|
markRead(ids, opts = {}) {
|
|
1664
1831
|
return this.http.json("/v1/notifications/read", { method: "POST", body: ids ? { ids } : {}, ext: opts.ext, signal: opts.signal });
|
|
1665
1832
|
}
|
|
1833
|
+
/** `DELETE /v1/notifications/:id` — `{ deleted: 0 }` when the id is missing or not yours. */
|
|
1834
|
+
delete(id, opts = {}) {
|
|
1835
|
+
return this.http.json(`/v1/notifications/${encodeURIComponent(String(id))}`, { method: "DELETE", ext: opts.ext, signal: opts.signal });
|
|
1836
|
+
}
|
|
1837
|
+
/** `POST /v1/notifications/delete` — 1..200 ids; ids of other users are skipped. */
|
|
1838
|
+
deleteMany(ids, opts = {}) {
|
|
1839
|
+
return this.http.json("/v1/notifications/delete", { method: "POST", body: { ids }, ext: opts.ext, signal: opts.signal });
|
|
1840
|
+
}
|
|
1666
1841
|
};
|
|
1667
1842
|
|
|
1668
1843
|
// src/resources/tokens.ts
|
|
@@ -1756,6 +1931,8 @@ var OPERATION_METHODS = {
|
|
|
1756
1931
|
receiveTriggerHook: "triggers.fireHook",
|
|
1757
1932
|
listNotifications: "notifications.list",
|
|
1758
1933
|
markNotificationsRead: "notifications.markRead",
|
|
1934
|
+
deleteNotification: "notifications.delete",
|
|
1935
|
+
deleteNotifications: "notifications.deleteMany",
|
|
1759
1936
|
// Sessions
|
|
1760
1937
|
createSession: "sessions.create",
|
|
1761
1938
|
listSessions: "sessions.list",
|
|
@@ -1837,6 +2014,13 @@ var STREAMING_OPERATIONS = /* @__PURE__ */ new Set([
|
|
|
1837
2014
|
"streamSession",
|
|
1838
2015
|
"streamHost"
|
|
1839
2016
|
]);
|
|
2017
|
+
var RESOLVE_OPERATION_METHODS = {
|
|
2018
|
+
resolveHealth: "resolve.health",
|
|
2019
|
+
createResolveJob: "resolve.submit",
|
|
2020
|
+
getResolveJob: "resolve.get",
|
|
2021
|
+
acceptResolveJob: "resolve.accept",
|
|
2022
|
+
getResolveAttestation: "resolve.attestation"
|
|
2023
|
+
};
|
|
1840
2024
|
|
|
1841
2025
|
// src/index.ts
|
|
1842
2026
|
var Codai = class {
|
|
@@ -1869,6 +2053,8 @@ var Codai = class {
|
|
|
1869
2053
|
receipt;
|
|
1870
2054
|
feedback;
|
|
1871
2055
|
phoneModels;
|
|
2056
|
+
/** codai Resolve — execution-verified bug fixes (separate host, `resolveBaseUrl`). */
|
|
2057
|
+
resolve;
|
|
1872
2058
|
constructor(opts) {
|
|
1873
2059
|
if (!opts.apiKey) throw new Error("Codai: apiKey is required");
|
|
1874
2060
|
this.http = new HttpClient({
|
|
@@ -1907,6 +2093,16 @@ var Codai = class {
|
|
|
1907
2093
|
this.account = new Account(http);
|
|
1908
2094
|
this.receipt = new Receipts(http);
|
|
1909
2095
|
this.phoneModels = new PhoneModels(http);
|
|
2096
|
+
this.resolve = new Resolve(
|
|
2097
|
+
new HttpClient({
|
|
2098
|
+
apiKey: opts.apiKey,
|
|
2099
|
+
baseUrl: opts.resolveBaseUrl ?? "https://resolve.codai.ro",
|
|
2100
|
+
timeoutMs: opts.timeoutMs ?? 12e4,
|
|
2101
|
+
maxRetries: opts.maxRetries ?? 2,
|
|
2102
|
+
fetch: opts.fetch,
|
|
2103
|
+
defaults: opts.client ? { client: opts.client } : {}
|
|
2104
|
+
})
|
|
2105
|
+
);
|
|
1910
2106
|
this.chat = callable(
|
|
1911
2107
|
new Chat(http),
|
|
1912
2108
|
(o) => this.chat.completions.create(this.legacyBody(o), {
|
|
@@ -1991,6 +2187,6 @@ function allKeys(obj) {
|
|
|
1991
2187
|
}
|
|
1992
2188
|
var index_default = Codai;
|
|
1993
2189
|
|
|
1994
|
-
export { Account, AgentRuns, Agents, Audio, Chat, ChatCompletions, Codai, CodaiError, Devices, Embeddings, EnvironmentMembers, EnvironmentPorts, EnvironmentSecrets, EnvironmentTasks, Environments, Feedback, Health, Hosts, HttpClient, Messages, Models, Notifications, OPERATION_METHODS, OrgMembers, Orgs, PhoneModels, Projects, Receipts, Responses, STREAMING_OPERATIONS, SessionControls, SessionEvents, SessionLease, SessionShares, Sessions, Tasks, Tokens, Tools, Triggers, index_default as default, extensionHeaders, frameJson, mergeToolCall, readSse };
|
|
2190
|
+
export { Account, AgentRuns, Agents, Audio, Chat, ChatCompletions, Codai, CodaiError, Devices, Embeddings, EnvironmentMembers, EnvironmentPorts, EnvironmentSecrets, EnvironmentTasks, Environments, Feedback, Health, Hosts, HttpClient, Messages, Models, Notifications, OPERATION_METHODS, OrgMembers, Orgs, PhoneModels, Projects, RESOLVE_OPERATION_METHODS, RESOLVE_TERMINAL_STATUSES, Receipts, Resolve, ResolveError, ResolveInsufficientFundsError, Responses, STREAMING_OPERATIONS, SessionControls, SessionEvents, SessionLease, SessionShares, Sessions, Tasks, Tokens, Tools, Triggers, index_default as default, extensionHeaders, frameJson, mergeToolCall, readSse };
|
|
1995
2191
|
//# sourceMappingURL=index.js.map
|
|
1996
2192
|
//# sourceMappingURL=index.js.map
|