@granular-software/sdk 0.4.20 → 0.4.21
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 +34 -4
- package/dist/agent-evals.d.mts +1 -1
- package/dist/agent-evals.d.ts +1 -1
- package/dist/agent-evals.js +53 -19
- package/dist/agent-evals.js.map +1 -1
- package/dist/agent-evals.mjs +53 -19
- package/dist/agent-evals.mjs.map +1 -1
- package/dist/agent-harness.js +5 -2
- package/dist/agent-harness.js.map +1 -1
- package/dist/agent-harness.mjs +5 -2
- package/dist/agent-harness.mjs.map +1 -1
- package/dist/cli/index.js +48 -17
- package/dist/{client-DWYdWpS-.d.mts → client-DLGC0mJk.d.mts} +7 -2
- package/dist/{client-DWYdWpS-.d.ts → client-DLGC0mJk.d.ts} +7 -2
- package/dist/index.d.mts +18 -3
- package/dist/index.d.ts +18 -3
- package/dist/index.js +56 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +54 -20
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/agent-evals.mjs
CHANGED
|
@@ -4662,10 +4662,15 @@ var Session = class {
|
|
|
4662
4662
|
* ```typescript
|
|
4663
4663
|
* import { Author, Book, global_search } from './sandbox-tools';
|
|
4664
4664
|
*
|
|
4665
|
-
* const
|
|
4665
|
+
* const totalAuthors = await Author.count();
|
|
4666
|
+
* const firstAuthorsPage = await Author.page({ page: 1, perPage: 10, saveAs: 'recent_authors' });
|
|
4667
|
+
* const authors = firstAuthorsPage.items;
|
|
4666
4668
|
* const tolkien = await Author.get({ path: 'author_tolkien' });
|
|
4667
4669
|
* const bio = await tolkien.get_bio({ detailed: true });
|
|
4668
4670
|
* const books = await tolkien.get_books();
|
|
4671
|
+
* for await (const author of Author.iterate({ perPage: 100, maxItems: 500 })) {
|
|
4672
|
+
* console.log(author.id);
|
|
4673
|
+
* }
|
|
4669
4674
|
* ```
|
|
4670
4675
|
*
|
|
4671
4676
|
* Effect calls (instance methods, static methods, global functions) trigger
|
|
@@ -11223,9 +11228,9 @@ var STANDARD_MODULES_OPERATIONS = [
|
|
|
11223
11228
|
{ create: "class", extends: "entity", has: {} },
|
|
11224
11229
|
{ create: "user", extends: "entity", has: { email: { value: void 0 }, firstName: { value: void 0 }, lastName: { value: void 0 } } },
|
|
11225
11230
|
{ create: "company", extends: "entity", has: { name: { value: void 0 }, website: { value: void 0 } } },
|
|
11226
|
-
{ create: "string", has: {
|
|
11227
|
-
{ create: "number", has: {
|
|
11228
|
-
{ create: "boolean", has: {
|
|
11231
|
+
{ create: "string", has: {} },
|
|
11232
|
+
{ create: "number", has: {} },
|
|
11233
|
+
{ create: "boolean", has: {} },
|
|
11229
11234
|
{ create: "tool_parameter", has: { name: { value: void 0 }, type: { value: "string" }, description: { value: void 0 }, required: { value: false } } }
|
|
11230
11235
|
];
|
|
11231
11236
|
var BUILTIN_MODULES = {
|
|
@@ -11235,6 +11240,8 @@ var DEFAULT_DIRECT_RECORD_OBJECTS_REQUEST_BATCH_SIZE = 100;
|
|
|
11235
11240
|
var MAX_RECORD_OBJECTS_CONCURRENCY = 16;
|
|
11236
11241
|
var DEFAULT_DIRECT_RECORD_OBJECTS_RETRY_COUNT = 3;
|
|
11237
11242
|
var DEFAULT_DIRECT_RECORD_OBJECTS_RETRY_DELAY_MS = 1e3;
|
|
11243
|
+
var LOCAL_CONTROL_REQUEST_RETRY_COUNT = 4;
|
|
11244
|
+
var LOCAL_CONTROL_REQUEST_RETRY_DELAY_MS = 500;
|
|
11238
11245
|
function planRecordObjectsChunks(records, batchSize) {
|
|
11239
11246
|
const total = records.length;
|
|
11240
11247
|
const size = Math.max(1, Math.min(batchSize, total));
|
|
@@ -11249,6 +11256,17 @@ function planRecordObjectsChunks(records, batchSize) {
|
|
|
11249
11256
|
function sleep(ms) {
|
|
11250
11257
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
11251
11258
|
}
|
|
11259
|
+
function isLocalControlUrl(url) {
|
|
11260
|
+
try {
|
|
11261
|
+
const parsed = new URL(url);
|
|
11262
|
+
return parsed.hostname === "127.0.0.1" || parsed.hostname === "localhost" || parsed.hostname === "::1";
|
|
11263
|
+
} catch {
|
|
11264
|
+
return false;
|
|
11265
|
+
}
|
|
11266
|
+
}
|
|
11267
|
+
function isRetryableLocalWorkerRestart(status, body, url) {
|
|
11268
|
+
return isLocalControlUrl(url) && (status === 503 && body.includes("Your worker restarted mid-request") || status === 500 && body.includes("Network connection lost"));
|
|
11269
|
+
}
|
|
11252
11270
|
function isRetryableRecordObjectsError(error) {
|
|
11253
11271
|
const message = error instanceof Error ? error.message : String(error);
|
|
11254
11272
|
return /worker restarted mid-request|econnreset|network|socket connection was closed unexpectedly|timed out/i.test(message);
|
|
@@ -13272,23 +13290,36 @@ var Granular = class _Granular {
|
|
|
13272
13290
|
if (this.debugHttp) {
|
|
13273
13291
|
console.log(`[SDK] Requesting: ${url}`);
|
|
13274
13292
|
}
|
|
13275
|
-
|
|
13276
|
-
|
|
13277
|
-
|
|
13278
|
-
|
|
13279
|
-
|
|
13280
|
-
|
|
13281
|
-
|
|
13293
|
+
for (let attempt = 1; attempt <= LOCAL_CONTROL_REQUEST_RETRY_COUNT; attempt += 1) {
|
|
13294
|
+
const response = await fetch(url, {
|
|
13295
|
+
...options,
|
|
13296
|
+
headers: {
|
|
13297
|
+
"Authorization": `Bearer ${this.apiKey}`,
|
|
13298
|
+
"Content-Type": "application/json",
|
|
13299
|
+
"Connection": "close",
|
|
13300
|
+
...options.headers
|
|
13301
|
+
}
|
|
13302
|
+
});
|
|
13303
|
+
if (response.ok) {
|
|
13304
|
+
if (response.status === 204) {
|
|
13305
|
+
return { deleted: true };
|
|
13306
|
+
}
|
|
13307
|
+
return response.json();
|
|
13282
13308
|
}
|
|
13283
|
-
});
|
|
13284
|
-
if (!response.ok) {
|
|
13285
13309
|
const errorText = await response.text();
|
|
13310
|
+
const retryable = isRetryableLocalWorkerRestart(response.status, errorText, url);
|
|
13311
|
+
if (retryable && attempt < LOCAL_CONTROL_REQUEST_RETRY_COUNT) {
|
|
13312
|
+
if (this.debugHttp) {
|
|
13313
|
+
console.warn(
|
|
13314
|
+
`[SDK] Retrying local control request after worker restart (${attempt}/${LOCAL_CONTROL_REQUEST_RETRY_COUNT - 1} retries used): ${url}`
|
|
13315
|
+
);
|
|
13316
|
+
}
|
|
13317
|
+
await sleep(LOCAL_CONTROL_REQUEST_RETRY_DELAY_MS * attempt);
|
|
13318
|
+
continue;
|
|
13319
|
+
}
|
|
13286
13320
|
throw new Error(`Granular API Error (${response.status}): ${errorText}`);
|
|
13287
13321
|
}
|
|
13288
|
-
|
|
13289
|
-
return { deleted: true };
|
|
13290
|
-
}
|
|
13291
|
-
return response.json();
|
|
13322
|
+
throw new Error(`Granular API Error: exhausted retries for ${url}`);
|
|
13292
13323
|
}
|
|
13293
13324
|
};
|
|
13294
13325
|
|
|
@@ -14209,7 +14240,10 @@ ${loopBlock}
|
|
|
14209
14240
|
- Only use classes, methods, and parameter shapes that are explicitly declared in those typedefs.
|
|
14210
14241
|
- Never invent helper methods such as \`find(...)\` or unsupported parameters such as \`id\` when the typedefs require \`path\`.
|
|
14211
14242
|
- Use \`ClassName.get({ path })\` only when you already know an object's graph path.
|
|
14212
|
-
- Use \`ClassName.
|
|
14243
|
+
- Use \`ClassName.count()\` when you only need a total.
|
|
14244
|
+
- Use \`ClassName.page({ page, perPage, saveAs })\` when you need both records and pagination metadata like \`totalCount\` or \`hasMore\`.
|
|
14245
|
+
- Use \`ClassName.list({ page, perPage, saveAs })\` to load one typed page of records. \`limit\` is only a legacy alias for \`perPage\`.
|
|
14246
|
+
- Use \`for await (const item of ClassName.iterate({ perPage, maxItems }))\` for large batch jobs so you do not materialize the whole result set at once.
|
|
14213
14247
|
- Instance methods: \`await instance.method_name(params)\`.
|
|
14214
14248
|
- Static methods: \`await ClassName.static_method(params)\`.
|
|
14215
14249
|
- Global effects: \`await effect_name(params)\`.
|
|
@@ -14221,7 +14255,7 @@ ${loopBlock}
|
|
|
14221
14255
|
- Status fields are free-form operational strings, not strict enums. Normalize spelling mentally and do not rely on brittle hard-coded sets that miss variants like \`in-progress\`, \`in_progress\`, \`awaiting-part\`, or \`approval-submitted\`.
|
|
14222
14256
|
- Do not discard a case, work order, part request, or shipment only because its status string does not match your preferred "open" spelling. If the record is otherwise the clear match, inspect it.
|
|
14223
14257
|
- Reuse \`heap.getVar(name)\`, \`heap.setVar(name, value)\`, and \`heap.deleteVar(name)\` only when it clearly helps the next step. Do not mirror data into the heap just for completeness.
|
|
14224
|
-
- Prefer \`heap.setVar(name, value)\` for scalars or one selected instance. Prefer \`ClassName.list({ saveAs })\` for
|
|
14258
|
+
- Prefer \`heap.setVar(name, value)\` for scalars or one selected instance. Prefer \`ClassName.list({ page, perPage, saveAs })\` for reusable list pages instead of \`heap.setVar(name, array)\`.
|
|
14225
14259
|
- Never write an empty array into the heap. If a filtered list is empty, keep it local or clear the previous heap value with \`heap.deleteVar(name)\`.
|
|
14226
14260
|
- Prefer heap-backed state that represents the current choice or recommendation. Avoid storing extra scalar bookkeeping unless it is needed for the next concrete step.
|
|
14227
14261
|
- Only store true sandbox instances, typed lists of sandbox instances, or scalars in the heap. Results returned by static effects like availability/search helpers are often plain JSON, not sandbox instances.
|