@oddington/sdk 0.1.40 → 0.1.42

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 CHANGED
@@ -86,6 +86,11 @@ declared `review` handler crosses the Inbox publication seam as `review`; Inbox
86
86
  retains the canonical `invoice-import` routine identity separately, without
87
87
  deploying or executing that handler.
88
88
 
89
+ Long customer computation inside a remote step can report advancing work with
90
+ `await os.run.progress({ completed, total })`. Report progress after meaningful
91
+ batches of work rather than after every individual item. OS capability calls and
92
+ step transitions already count as activity automatically.
93
+
89
94
  Microsoft Connection configuration has a separate, optional `access` description.
90
95
  It preserves supplied strings, including existing `read` and `read-write` labels,
91
96
  and does not grant or restrict Microsoft permissions. Management results omit
@@ -98,6 +103,13 @@ With `access: { ai: true }`, `os.ai.generateText` returns non-empty `{ text }`.
98
103
  with code `invalid_output`, a clear bounded `detail`, and the original final
99
104
  answer as optional `text` for routine-owned recovery. The text is bounded at
100
105
  256 KiB and excluded from the error message and ordinary JSON serialization.
106
+ AI failures have plain-language messages and keep their structured `code`.
107
+ Optional `detail` explains a known runner limit, exit, response failure or request
108
+ validation rule. Use these facts rather than parsing messages. A code-only legacy
109
+ failure does not establish a more specific cause or justify a retry. Local Run
110
+ activity and AI inspection preserve these diagnostics even when the routine
111
+ catches the error and continues; no provider logs or private answer text are
112
+ included in the ordinary activity summary.
101
113
  The routine can inspect it explicitly, apply its own recovery rules, report
102
114
  an item failure and continue; it must not cast a rejected answer to the promised
103
115
  type. OS does not coerce, drop fields, repair or retry automatically.
@@ -107,6 +119,29 @@ type. OS does not coerce, drop fields, repair or retry automatically.
107
119
  extract JSON from explanatory prose or repair the answer. `RoutineAIError`
108
120
  remains a compatibility alias of `AIError`, so existing `instanceof` checks work.
109
121
 
122
+ For a File that needs local tool-assisted inspection, explicitly enable tools
123
+ on that call:
124
+
125
+ ```ts
126
+ const { object } = await os.ai.generateObject({
127
+ input: document,
128
+ instructions: 'Read this document and report only grounded facts.',
129
+ schema: documentFacts,
130
+ tools: true,
131
+ });
132
+ ```
133
+
134
+ Omitting `tools` or setting it to `false` keeps the existing tool-free behavior.
135
+ OS supplies and sandboxes the tools; routines do not choose CLI flags or shell
136
+ commands. This first version requires a File input and local macOS execution
137
+ with Claude Code 2.1.285 or newer. Unsupported hosts reject with
138
+ `AIError('capability_unavailable')` rather than silently ignoring the option.
139
+ The original stays read-only, temporary processing is disposable, and tool
140
+ network access is blocked. A tool-assisted answer still has to satisfy the
141
+ requested schema and the routine's own completeness checks.
142
+ Tool-enabled object generation uses the runner's structured final submission;
143
+ OS validates that value without extracting JSON from surrounding commentary.
144
+
110
145
  Preserve safe AI error facts when reporting a per-document failure. Keep the
111
146
  original answer (`error.text`) out of step data, business records and logs:
112
147
 
@@ -244,7 +279,7 @@ os.init({ auth }); // OS-owned startup, once before app modules run.
244
279
  // App code uses the installed capabilities directly.
245
280
  const general = data.repository('general');
246
281
  try {
247
- const selected = await general.records.select({ invoices: { $: { limit: 20 } } });
282
+ const selected = await general.records.query({ invoices: { $: { limit: 20 } } });
248
283
  const found = await general.records.search('acme overdue', {
249
284
  collections: ['invoices'], limit: 20,
250
285
  });
@@ -473,7 +508,10 @@ and numeric byte counts; its message explains the rejected field or expected
473
508
  versus received size. Streaming rejection marks partial received counts with
474
509
  `receivedAtLeast: true`. These facts survive local Run summaries and saved
475
510
  failure evidence without raw names, keys, file content or provider text. Older
476
- errors without `detail` remain valid. Reads return the successful Web
511
+ errors without `detail` remain valid. Messages use the known reason in plain
512
+ language; use `code`, `status`, `retryable` and `detail` for programmatic decisions
513
+ rather than parsing the message. Replacement errors explain that `replace`
514
+ expects the current enrichment's SHA-256 value. Reads return the successful Web
477
515
  Response without consuming its body. Local transfer is bounded and buffered
478
516
  before constructing that Response. Current workspace members can use every File in that workspace. A
479
517
  routine's `files: "read"` permits get/read; `files: "read-write"` also permits
@@ -581,12 +619,12 @@ import { data, DataOperationError } from '@oddington/sdk';
581
619
  const general = data.repository('general');
582
620
  const collections = await general.collections.list();
583
621
  const schema = await general.collections.schema('invoices');
584
- const first = await general.records.select({
622
+ const first = await general.records.query({
585
623
  invoices: { $: { limit: 50 }, supplier: { $: { fields: ['name'] } } },
586
624
  suppliers: {},
587
625
  });
588
626
  const next = first.$meta.collections.invoices.next;
589
- if (next) await general.records.select({
627
+ if (next) await general.records.query({
590
628
  invoices: { $: { limit: 50, after: next }, supplier: { $: { fields: ['name'] } } },
591
629
  });
592
630
  ```
@@ -623,7 +661,7 @@ unedited first-release generated output and preserves every other alias; edited
623
661
  or malformed generated files remain protected.
624
662
 
625
663
  Known repository literals then constrain collection/field/link names and query
626
- operands and infer projected `select`, `pages` and `all` values from normalized
664
+ operands and infer projected `query`, `pages` and `all` values from normalized
627
665
  schemas. Multiple aliases share the root declaration. Refresh explicitly with
628
666
  the same CLI command after publishing schema changes; app builds and launches
629
667
  never refresh it. Missing metadata and dynamic repository strings retain generic
@@ -651,7 +689,7 @@ Both helpers preserve literal collection arrays and selected-link inference.
651
689
  prefetches after a consumer stops. Independent collection cursors pin the first
652
690
  snapshot. Completed collections yield empty arrays on later pages and retain
653
691
  requested counts. Empty matches yield one versioned page. Helpers own continuation;
654
- use `select` for a manual `after` cursor or explicit historical selection.
692
+ use `query` for a manual `after` cursor or explicit historical query.
655
693
 
656
694
  `all` consumes the same iterator and returns only after successful exhaustion.
657
695
  Its required positive safe-integer `maxRecords` caps top-level Record occurrences
@@ -661,7 +699,7 @@ or increase `maxRecords`, and rejects with nonretryable `capacity` without a
661
699
  partial or truncated result.
662
700
  Invalid helper arguments use `invalid_query`; malformed pages, cursor cycles,
663
701
  snapshot changes or inconsistent requested counts use nonretryable `unavailable`.
664
- Selection and authority failures propagate unchanged, with no retry or restart.
702
+ Query and authority failures propagate unchanged, with no retry or restart.
665
703
 
666
704
  Read known stable refs directly, including refs from different collections:
667
705
 
@@ -674,7 +712,7 @@ const batch = await general.records.read(['invoices/one', 'suppliers/acme']);
674
712
 
675
713
  An array accepts 1–100 distinct valid refs; a one-element array keeps the batch
676
714
  shape, and all-missing batches still carry their version. Both forms send one
677
- bounded operation through the same app/routine authority and snapshot as `select`.
715
+ bounded operation through the same app/routine authority and snapshot as `query`.
678
716
  Records include `$ref`, `$version` and all canonical structured fields; links
679
717
  remain refs, omitted and null fields stay distinct, and Markdown bodies and
680
718
  `$filing` are excluded. Invalid refs, exceeded bounds, denied access and service
@@ -743,7 +781,7 @@ and `$in`, declared one-valued `integer`, `number` and `date` fields accept
743
781
  `$gt`, `$gte`, `$lt` and `$lte`:
744
782
 
745
783
  ```ts
746
- await general.records.select({ invoices: { $: { where: {
784
+ await general.records.query({ invoices: { $: { where: {
747
785
  amount: { $gte: 10, $lte: 20 },
748
786
  date: { $gte: '2026-10-01', $lt: '2026-11-01' },
749
787
  month: { $gte: '2026-10', $lte: '2026-10' },