@nestm/storage 0.1.0-alpha.10 → 0.1.0-alpha.11

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.
Files changed (62) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +153 -0
  3. package/SECURITY.md +27 -0
  4. package/dist/ai-sdk/ai-sdk-file-workflow-tools.d.ts +37 -0
  5. package/dist/ai-sdk/ai-sdk-file-workflow-tools.d.ts.map +1 -0
  6. package/dist/ai-sdk/ai-sdk-file-workflow-tools.js +258 -0
  7. package/dist/ai-sdk/ai-sdk-file-workflow-tools.js.map +1 -0
  8. package/dist/ai-sdk/index.d.ts +1 -0
  9. package/dist/ai-sdk/index.d.ts.map +1 -1
  10. package/dist/ai-sdk/index.js +1 -0
  11. package/dist/ai-sdk/index.js.map +1 -1
  12. package/dist/bytes/index.d.ts +30 -0
  13. package/dist/bytes/index.d.ts.map +1 -0
  14. package/dist/bytes/index.js +96 -0
  15. package/dist/bytes/index.js.map +1 -0
  16. package/dist/core/index.d.ts +3 -0
  17. package/dist/core/index.d.ts.map +1 -1
  18. package/dist/core/index.js +3 -0
  19. package/dist/core/index.js.map +1 -1
  20. package/dist/core/storage-staged-content.d.ts +37 -0
  21. package/dist/core/storage-staged-content.d.ts.map +1 -0
  22. package/dist/core/storage-staged-content.js +94 -0
  23. package/dist/core/storage-staged-content.js.map +1 -0
  24. package/dist/core/storage-streams.d.ts +19 -0
  25. package/dist/core/storage-streams.d.ts.map +1 -0
  26. package/dist/core/storage-streams.js +95 -0
  27. package/dist/core/storage-streams.js.map +1 -0
  28. package/dist/core/storage-text.d.ts +33 -0
  29. package/dist/core/storage-text.d.ts.map +1 -0
  30. package/dist/core/storage-text.js +98 -0
  31. package/dist/core/storage-text.js.map +1 -0
  32. package/dist/files-sdk/memory.d.ts +7 -0
  33. package/dist/files-sdk/memory.d.ts.map +1 -0
  34. package/dist/files-sdk/memory.js +72 -0
  35. package/dist/files-sdk/memory.js.map +1 -0
  36. package/dist/files-sdk/provider/index.d.ts.map +1 -1
  37. package/dist/files-sdk/provider/index.js +4 -0
  38. package/dist/files-sdk/provider/index.js.map +1 -1
  39. package/dist/testing/index.d.ts.map +1 -1
  40. package/dist/testing/index.js +2 -1
  41. package/dist/testing/index.js.map +1 -1
  42. package/dist/workspace/index.d.ts +5 -0
  43. package/dist/workspace/index.d.ts.map +1 -1
  44. package/dist/workspace/index.js +3 -0
  45. package/dist/workspace/index.js.map +1 -1
  46. package/dist/workspace/storage-file-catalog.types.d.ts +65 -0
  47. package/dist/workspace/storage-file-catalog.types.d.ts.map +1 -0
  48. package/dist/workspace/storage-file-catalog.types.js +2 -0
  49. package/dist/workspace/storage-file-catalog.types.js.map +1 -0
  50. package/dist/workspace/storage-file-workflow.d.ts +7 -0
  51. package/dist/workspace/storage-file-workflow.d.ts.map +1 -0
  52. package/dist/workspace/storage-file-workflow.js +440 -0
  53. package/dist/workspace/storage-file-workflow.js.map +1 -0
  54. package/dist/workspace/storage-file-workflow.protection.d.ts +31 -0
  55. package/dist/workspace/storage-file-workflow.protection.d.ts.map +1 -0
  56. package/dist/workspace/storage-file-workflow.protection.js +258 -0
  57. package/dist/workspace/storage-file-workflow.protection.js.map +1 -0
  58. package/dist/workspace/storage-file-workflow.types.d.ts +128 -0
  59. package/dist/workspace/storage-file-workflow.types.d.ts.map +1 -0
  60. package/dist/workspace/storage-file-workflow.types.js +8 -0
  61. package/dist/workspace/storage-file-workflow.types.js.map +1 -0
  62. package/package.json +5 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @nestm/storage
2
2
 
3
+ ## 0.1.0-alpha.11
4
+
5
+ ### Minor Changes
6
+
7
+ - 9c5f230: Add framework-neutral durable file workflows with immutable integrity-checked
8
+ staged bodies, bounded UTF-8 reads/search, idempotent chunk appends, and explicit
9
+ host transaction ports for atomic multi-file head commits. Add protected catalog
10
+ and draft capabilities and generic tools in the existing optional AI SDK entrypoint.
11
+
12
+ Add a browser-safe bytes entrypoint for verified upload resumption and UTF-8
13
+ chunk boundaries. Preserve the default memory driver with native conditional
14
+ create/replace/read/delete, evaluated atomically after body consumption, and
15
+ canonical SHA-256 ETags. Memory remains volatile and process-local.
16
+
3
17
  ## 0.1.0-alpha.10
4
18
 
5
19
  ### Minor Changes
package/README.md CHANGED
@@ -375,6 +375,159 @@ materialize the workspace into a per-session container or VM, mount only that
375
375
  directory, run the harness there, and synchronize reviewed changes back through
376
376
  `StorageWorkspace`. A working directory alone is not a sandbox.
377
377
 
378
+ ## Durable file workflows and catalog tools
379
+
380
+ `@nestm/storage` owns byte mechanics and the draft state machine. The host owns
381
+ logical file heads, authorization, persistence and transaction atomicity. No
382
+ database, NestJS, tenant model or runtime lease is required by these contracts.
383
+
384
+ | Entry point | Exports |
385
+ | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
386
+ | `@nestm/storage/core` | `StorageStagedContentStore`, `collectStorageBytes`, `storageBytesStream`, `readStorageTextWindow`, `searchStorageText`, `applyStorageTextEdit` and their types |
387
+ | `@nestm/storage/workspace` | `StorageFileWorkflow`, draft/persistence/catalog contracts, `protectStorageFileWorkflowWorkspace`, `protectStorageFileWorkflowOperation`, `getStorageFileWorkflow`, `getStorageFileCatalog` |
388
+ | `@nestm/storage/ai-sdk` | `createAiSdkFileWorkflowTools`, `createAiSdkCatalogFileTools`, their options and tool-name constants; existing `createAiSdkWorkspaceTools` is unchanged |
389
+ | `@nestm/storage/bytes` | Browser-safe `sha256StorageBytes`, `verifyStorageChunkReceipt`, `trimStorageUtf8Chunk`, `encodeStorageBase64`, `isStorageUtf8Blob` |
390
+
391
+ ```ts
392
+ import { StorageStagedContentStore } from '@nestm/storage/core';
393
+ import {
394
+ StorageFileWorkflow,
395
+ protectStorageFileWorkflowWorkspace,
396
+ } from '@nestm/storage/workspace';
397
+ import {
398
+ createAiSdkCatalogFileTools,
399
+ createAiSdkFileWorkflowTools,
400
+ } from '@nestm/storage/ai-sdk';
401
+
402
+ // These values are supplied by the host, never by the model.
403
+ const content = new StorageStagedContentStore({
404
+ client,
405
+ key: (scope: HostScope, payloadId) => hostBodyKey(scope, payloadId),
406
+ });
407
+ const workflows = new StorageFileWorkflow({ content, persistence });
408
+ const workspace = protectStorageFileWorkflowWorkspace({
409
+ workspace: hostCatalogWorkspace,
410
+ catalog: hostCatalog,
411
+ workflows: workflows.mount(trustedScope, {
412
+ permissions: ['read', 'write', 'commit'],
413
+ signal: executionSignal,
414
+ }),
415
+ signal: executionSignal,
416
+ authorize: ({ permission, signal }) =>
417
+ authorizeCurrentHostScope(trustedScope, permission, signal),
418
+ });
419
+ const tools = {
420
+ ...createAiSdkCatalogFileTools({
421
+ catalog: workspace.catalog!,
422
+ commandId: (toolCallId) => hostCommandId(toolCallId),
423
+ }),
424
+ ...createAiSdkFileWorkflowTools({
425
+ workflow: workspace.workflows,
426
+ idempotencyKey: (toolCallId) => hostCommandId(toolCallId),
427
+ }),
428
+ };
429
+ ```
430
+
431
+ The catalog delegate implements the existing `StorageWorkspace` against the
432
+ host's logical catalog; do not pass a raw provider-prefix workspace alongside
433
+ an unrelated file service. `StorageFileCatalogCapability` adds opaque file IDs,
434
+ byte windows, literal content search and idempotent small write/edit commands.
435
+ Its `commandId` is host-scoped, stable across retries, and compared against a
436
+ canonical request fingerprint in host persistence. The host preserves its
437
+ additional policy when a generic edit targets a specialized file.
438
+
439
+ `createAiSdkCatalogFileEditSchemas(maxWriteBytes)` exposes typed append/edit
440
+ Zod objects used by the generic factory itself. A host can `.extend()` these
441
+ with an optional product-only metadata field while retaining the same UTF-8
442
+ byte rules. Delegate ordinary input to the generic tool; dispatch specialized
443
+ input through the same leased product capability and command identity. Do not
444
+ cast an opaque tool schema or rebuild the generic schema locally.
445
+
446
+ The protector retains the lease/caller signal and reauthorizes every call.
447
+ Create-only base grants cannot replace or edit a catalog file. Workflow
448
+ `restrict({ permissions, mutations, limits, signal })` intersects existing
449
+ grants/ceilings and retains parent cancellation; it never changes scope. The
450
+ protector restricts persisted draft mutations to the base create/replace grants,
451
+ including resumed sealed drafts and replay, without requiring a public read
452
+ grant to perform an otherwise authorized commit. Child mounts do
453
+ not inherit broader catalog/workflow handles. Configure both delegates with the
454
+ same scope and compatible limits; the host catalog must enforce scan budgets
455
+ inside its implementation. Structured extensions on the returned workspace
456
+ are supported: owning features can attach protected product closures while
457
+ retaining the same `.catalog` and `.workflows` members. The structural getters
458
+ are contract checks for trusted handles, not authentication of arbitrary objects.
459
+ These static file operations acquire no lease themselves.
460
+
461
+ ### Host persistence transaction
462
+
463
+ Implement `StorageFileWorkflowPersistence<Scope, Receipt>.transaction(scope,
464
+ { permission, signal }, work)`. On **every** call (including replay and body
465
+ preparation reads), reauthorize that intent and serialize the scope's draft and
466
+ idempotency records across replicas. `read` admits readers; `write` and `commit`
467
+ must enforce the host's mutation authority. The callback receives detached
468
+ records through `findDraftByKey`, `getDraft`, `saveDraft`, `listDrafts`,
469
+ `listParts`, `putPart` and `commitHeads`.
470
+
471
+ `commitHeads` receives sorted `{ draft, body }` changes. It must compare every
472
+ create/expected-ETag predicate and change all logical heads **in the same host
473
+ transaction** as the subsequent committed draft records and receipts. Return
474
+ one non-null receipt per change in the supplied order. A rejection rolls back
475
+ all callback effects. Serial object writes or independently committed database
476
+ calls do not satisfy this port. The package does not claim to implement database
477
+ atomicity. See the packed consumer fixture and filesystem e2e test for executable
478
+ minimal hosts; production hosts need their own cross-replica transaction/locking
479
+ implementation and rollback tests.
480
+
481
+ Drafts transition `open → sealed → committed` or `open/sealed → cancelled`.
482
+ Appends accept a bounded snapshot of bytes at the exact current byte offset.
483
+ Identical offset/size/SHA-256 replay succeeds; changed bytes or gaps conflict.
484
+ Text chunks must contain complete valid UTF-8. Public summaries and part receipts
485
+ omit staged body IDs and provider keys. A commit seals all requested drafts,
486
+ streams verified chunks into immutable bodies, then commits all heads and draft
487
+ receipts in one host transaction. Failed preparation or stale heads leave sealed
488
+ drafts retryable/cancellable. Mixed committed/uncommitted batches conflict;
489
+ replaying an entirely committed batch returns its stored receipts after checking
490
+ the requested size and optional digest. Cancellation cannot undo committed heads.
491
+
492
+ Check the signal before durable transaction commit. After commit, return the
493
+ receipt even if cancellation races the response. Do not automatically retry the
494
+ transaction callback. A lost response requires replay/reconciliation, not an
495
+ assumption of rollback. Provider writes happen before the metadata transaction;
496
+ failures, losing concurrent preparations, cancellations and superseded files can
497
+ leave unreferenced bodies. Retention eligibility, reference tracking and cleanup
498
+ scheduling remain host-owned. `StorageStagedContentStore.remove` performs an
499
+ ETag-conditional deletion only after the host proves eligibility; it is not a
500
+ collector and is never called automatically by the workflow.
501
+
502
+ ### Byte and provider guarantees
503
+
504
+ Staging requires native create-only writes that return an ETag and native exact
505
+ ETag reads; byte ranges additionally require `rangeRead`. Missing primitives
506
+ fail with `NOT_SUPPORTED`, without an existence-check/unconditional-write or
507
+ full-download fallback. Files SDK remains the provider, streaming, range and
508
+ conditional-policy engine. Its multipart upload controls remain distinct from
509
+ the host-persisted draft protocol; it does not provide atomic catalog commits.
510
+ The bundled filesystem and memory drivers and verified native S3 profiles
511
+ support staging. Memory stores are process-local and volatile; their conditional
512
+ comparison/publication is synchronous after asynchronous body consumption.
513
+ Memory publications use canonical SHA-256 ETags. Direct raw-map mutation remains
514
+ a trusted testing escape hatch, outside protected workspace authority.
515
+
516
+ Windows count UTF-8 bytes, use inclusive provider range ends and preserve BOMs.
517
+ Offsets splitting a character and malformed/truncated UTF-8 at EOF fail. Search
518
+ budgets include the actual requested bytes; follow `nextOffset` even on an empty
519
+ match page. `applyStorageTextEdit` works on an already buffered string, requires a
520
+ result byte ceiling and rejects non-unique replacement targets; it is not a
521
+ streaming document editor. Model text appends default to 8192 bytes per call,
522
+ clamped to the capability. Mutation tools require approval by default; hosts may
523
+ apply an existing approval policy explicitly.
524
+
525
+ The browser bytes entrypoint imports no Node, provider, NestJS or AI modules.
526
+ `verifyStorageChunkReceipt(blob, receipt, { offset, maxBytes, signal })` verifies
527
+ ordering, bounds and the actual local SHA-256 before returning the next offset.
528
+ Filename/size/mtime are insufficient proof of resumed content identity. Filename
529
+ classification, browser session storage and HTTP transport remain host policy.
530
+
378
531
  ## Configure named stores
379
532
 
380
533
  Use the package-owned S3 factory when applicable. For other providers, create a
package/SECURITY.md CHANGED
@@ -49,6 +49,33 @@ application's metadata transaction commits.
49
49
 
50
50
  ## Workspace security boundary
51
51
 
52
+ Durable file workflows use opaque host scopes and explicit persistence ports.
53
+ The host must reauthorize `transaction`'s `permission` on every call, including
54
+ idempotent replay, and serialize the scope's draft state across replicas. Head
55
+ predicates, all head changes, and committed draft receipts must share one
56
+ rollback-capable host transaction. Streamed object preparation is outside that
57
+ transaction; the package does not make object-store writes multi-file atomic.
58
+ Provider/network response loss can remain ambiguous. Reconcile by replaying the
59
+ durable request; do not infer rollback from an abort or lost response.
60
+
61
+ Construct protected catalog/workflow handles from the same trusted host scope,
62
+ bind their execution signal, and keep storage clients and persistence ports
63
+ private. The protector rechecks fresh authorization and composes caller aborts;
64
+ the host transaction independently rechecks authority at commit.
65
+ Workflow restrictions check each persisted draft's create/replace intent on
66
+ mutation and replay; they cannot widen grants, limits or detach parent abort.
67
+ The checks do not depend on a public draft-read permission. Product-only
68
+ feature closures must capture these same checks when the handle is acquired.
69
+ The structural catalog/workflow getters do not authenticate untrusted objects.
70
+
71
+ Staged bodies use native create-only writes and exact ETag reads. Integrity
72
+ receipts verify full draft chunks during assembly. Conditional body removal is
73
+ available only as a host-invoked primitive: references, eligibility and cleanup
74
+ races are host-owned. Never delete a body merely because a commit request failed
75
+ or timed out; another in-flight or committed request may reference it. The
76
+ memory adapter is volatile and its raw Map is a trusted escape hatch, not an
77
+ authorization boundary.
78
+
52
79
  `StorageWorkspace` is a narrowing capability for storage operations. Construct
53
80
  it from trusted application context, keep the underlying `StorageClient` and
54
81
  mount prefix private, and pass only the workspace or its AI tool set to
@@ -0,0 +1,37 @@
1
+ import { type ToolSet } from 'ai';
2
+ import { z } from 'zod';
3
+ import type { StorageFileCatalogCapability, StorageFileWorkflowCapability } from '../workspace/index.js';
4
+ export interface CreateAiSdkFileWorkflowToolsOptions<Receipt> {
5
+ readonly workflow: StorageFileWorkflowCapability<Receipt>;
6
+ readonly requireApproval?: boolean;
7
+ /** Host-generated token, scoped and stable across replay of this tool call. */
8
+ readonly idempotencyKey?: (toolCallId: string) => string;
9
+ readonly maxChunkBytes?: number;
10
+ }
11
+ export interface CreateAiSdkCatalogFileToolsOptions<Receipt> {
12
+ readonly catalog: StorageFileCatalogCapability<Receipt>;
13
+ readonly requireApproval?: boolean;
14
+ readonly commandId?: (toolCallId: string) => string;
15
+ readonly maxWriteBytes?: number;
16
+ }
17
+ export declare const AI_SDK_FILE_WORKFLOW_TOOL_NAMES: readonly ['workspace_begin_file_draft', 'workspace_append_file_draft', 'workspace_list_file_drafts', 'workspace_read_file_draft', 'workspace_list_file_draft_parts', 'workspace_cancel_file_draft', 'workspace_commit_files'];
18
+ export declare const AI_SDK_CATALOG_FILE_TOOL_NAMES: readonly ['workspace_list', 'workspace_stat', 'workspace_search', 'workspace_read_file', 'workspace_search_content', 'workspace_write_file', 'workspace_append_file', 'workspace_edit_file'];
19
+ /** Typed extension seam for host-only metadata; preserves generic byte validation. */
20
+ export declare function createAiSdkCatalogFileEditSchemas(maxWriteBytes?: number): {
21
+ append: z.ZodObject<{
22
+ path: z.ZodString;
23
+ expectedEtag: z.ZodString;
24
+ content: z.ZodString;
25
+ }, z.core.$strict>;
26
+ edit: z.ZodObject<{
27
+ path: z.ZodString;
28
+ expectedEtag: z.ZodString;
29
+ oldText: z.ZodString;
30
+ newText: z.ZodString;
31
+ }, z.core.$strict>;
32
+ };
33
+ /** Generic durable-file tools. Provider upload controls are a separate capability. */
34
+ export declare function createAiSdkFileWorkflowTools<Receipt>(options: CreateAiSdkFileWorkflowToolsOptions<Receipt>): ToolSet;
35
+ /** Catalog-backed alternative to the existing raw-workspace tool factory. */
36
+ export declare function createAiSdkCatalogFileTools<Receipt>(options: CreateAiSdkCatalogFileToolsOptions<Receipt>): ToolSet;
37
+ //# sourceMappingURL=ai-sdk-file-workflow-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-sdk-file-workflow-tools.d.ts","sourceRoot":"","sources":["../../src/ai-sdk/ai-sdk-file-workflow-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,OAAO,EAAE,MAAM,IAAI,CAAC;AACxC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EACV,4BAA4B,EAC5B,6BAA6B,EAC9B,MAAM,uBAAuB,CAAC;AAG/B,MAAM,WAAW,mCAAmC,CAAC,OAAO;IAC1D,QAAQ,CAAC,QAAQ,EAAE,6BAA6B,CAAC,OAAO,CAAC,CAAC;IAC1D,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,+EAA+E;IAC/E,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IACzD,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AACD,MAAM,WAAW,kCAAkC,CAAC,OAAO;IACzD,QAAQ,CAAC,OAAO,EAAE,4BAA4B,CAAC,OAAO,CAAC,CAAC;IACxD,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IACpD,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AACD,eAAO,MAAM,+BAA+B,YAC1C,4BAA4B,EAC5B,6BAA6B,EAC7B,4BAA4B,EAC5B,2BAA2B,EAC3B,iCAAiC,EACjC,6BAA6B,EAC7B,wBAAwB,CAChB,CAAC;AACX,eAAO,MAAM,8BAA8B,YACzC,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,0BAA0B,EAC1B,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,CACb,CAAC;AAuCX,sFAAsF;AACtF,wBAAgB,iCAAiC,CAAC,aAAa,SAAO;IAGlE,MAAM;;;;;IACN,IAAI;;;;;;EAOP;AAED,sFAAsF;AACtF,wBAAgB,4BAA4B,CAAC,OAAO,EAClD,OAAO,EAAE,mCAAmC,CAAC,OAAO,CAAC,GACpD,OAAO,CA6GT;AAED,6EAA6E;AAC7E,wBAAgB,2BAA2B,CAAC,OAAO,EACjD,OAAO,EAAE,kCAAkC,CAAC,OAAO,CAAC,GACnD,OAAO,CAgIT"}
@@ -0,0 +1,258 @@
1
+ import { tool } from 'ai';
2
+ import { z } from 'zod';
3
+ import { isStorageError } from '../storage.error.js';
4
+ import { AiSdkWorkspaceToolError } from './ai-sdk-workspace-tools.js';
5
+ export const AI_SDK_FILE_WORKFLOW_TOOL_NAMES = [
6
+ 'workspace_begin_file_draft',
7
+ 'workspace_append_file_draft',
8
+ 'workspace_list_file_drafts',
9
+ 'workspace_read_file_draft',
10
+ 'workspace_list_file_draft_parts',
11
+ 'workspace_cancel_file_draft',
12
+ 'workspace_commit_files',
13
+ ];
14
+ export const AI_SDK_CATALOG_FILE_TOOL_NAMES = [
15
+ 'workspace_list',
16
+ 'workspace_stat',
17
+ 'workspace_search',
18
+ 'workspace_read_file',
19
+ 'workspace_search_content',
20
+ 'workspace_write_file',
21
+ 'workspace_append_file',
22
+ 'workspace_edit_file',
23
+ ];
24
+ const offset = z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
25
+ const identity = z.string().min(1).max(256);
26
+ const etag = z.string().min(1).max(1024);
27
+ const path = z.string().min(1).max(1024);
28
+ const page = { offset: offset.default(0) };
29
+ function textSchema(maxBytes) {
30
+ if (!Number.isSafeInteger(maxBytes) || maxBytes < 1)
31
+ throw new TypeError('Text tool limit must be a positive safe integer.');
32
+ return z
33
+ .string()
34
+ .max(maxBytes)
35
+ .refine((text) => !/[\uD800-\uDFFF]/u.test(text), 'Text must be well-formed UTF-8.')
36
+ .refine((text) => new TextEncoder().encode(text).byteLength <= maxBytes, `Use at most ${maxBytes} UTF-8 bytes per call.`);
37
+ }
38
+ async function safe(work) {
39
+ try {
40
+ return await work();
41
+ }
42
+ catch (error) {
43
+ if (isStorageError(error))
44
+ throw new AiSdkWorkspaceToolError(error.code, {
45
+ applied: error.applied,
46
+ ...(error.appliedEtag === undefined
47
+ ? {}
48
+ : { appliedEtag: error.appliedEtag }),
49
+ });
50
+ if (error instanceof DOMException && error.name === 'AbortError')
51
+ throw new AiSdkWorkspaceToolError('ABORTED');
52
+ throw new AiSdkWorkspaceToolError('PROVIDER');
53
+ }
54
+ }
55
+ /** Typed extension seam for host-only metadata; preserves generic byte validation. */
56
+ export function createAiSdkCatalogFileEditSchemas(maxWriteBytes = 8192) {
57
+ const content = textSchema(maxWriteBytes);
58
+ return {
59
+ append: z.strictObject({ path, expectedEtag: etag, content }),
60
+ edit: z.strictObject({
61
+ path,
62
+ expectedEtag: etag,
63
+ oldText: content.refine((text) => text.length > 0),
64
+ newText: content,
65
+ }),
66
+ };
67
+ }
68
+ /** Generic durable-file tools. Provider upload controls are a separate capability. */
69
+ export function createAiSdkFileWorkflowTools(options) {
70
+ const { workflow } = options;
71
+ const tools = {};
72
+ const content = textSchema(Math.min(options.maxChunkBytes ?? 8192, workflow.limits.maxChunkBytes));
73
+ const approval = options.requireApproval ?? true;
74
+ if (workflow.allows('read'))
75
+ Object.assign(tools, {
76
+ workspace_list_file_drafts: tool({
77
+ description: 'List durable drafts. Resume open drafts at their current UTF-8 byte size; use nextOffset for pagination.',
78
+ inputSchema: z.strictObject(page),
79
+ execute: (input, context) => safe(() => workflow.list({ ...input, signal: context.abortSignal })),
80
+ }),
81
+ workspace_read_file_draft: tool({
82
+ description: `Read a draft window of at most ${workflow.limits.maxReadBytes} UTF-8 bytes. Continue with nextOffset, which is a byte position at a Unicode boundary.`,
83
+ inputSchema: z.strictObject({ draftId: identity, ...page }),
84
+ execute: (input, context) => safe(() => workflow.read({ ...input, signal: context.abortSignal })),
85
+ }),
86
+ workspace_list_file_draft_parts: tool({
87
+ description: 'List bounded chunk integrity receipts for resumption. Each receipt contains its byte offset, size, and SHA-256.',
88
+ inputSchema: z.strictObject({ draftId: identity, ...page }),
89
+ execute: (input, context) => safe(() => workflow.parts({ ...input, signal: context.abortSignal })),
90
+ }),
91
+ });
92
+ if (workflow.allows('write'))
93
+ Object.assign(tools, {
94
+ workspace_begin_file_draft: tool({
95
+ strict: false,
96
+ needsApproval: approval,
97
+ description: 'Begin a durable text draft without changing a visible file. Omit expectedEtag to create a new path; supply the exact current ETag to replace. Use drafts for substantial content and resume interrupted drafts.',
98
+ inputSchema: z.strictObject({ path, expectedEtag: etag.optional() }),
99
+ execute: (input, context) => safe(() => workflow.begin({
100
+ ...input,
101
+ text: true,
102
+ idempotencyKey: options.idempotencyKey?.(context.toolCallId) ??
103
+ context.toolCallId,
104
+ signal: context.abortSignal,
105
+ })),
106
+ }),
107
+ workspace_append_file_draft: tool({
108
+ needsApproval: approval,
109
+ description: 'Append a bounded UTF-8 chunk at the draft’s returned byte size. Replaying identical bytes at the same offset is safe; different bytes or a stale offset fail.',
110
+ inputSchema: z.strictObject({
111
+ draftId: identity,
112
+ offset,
113
+ content: content.refine((text) => text.length > 0),
114
+ }),
115
+ execute: (input, context) => safe(() => workflow.append({
116
+ draftId: input.draftId,
117
+ offset: input.offset,
118
+ bytes: new TextEncoder().encode(input.content),
119
+ signal: context.abortSignal,
120
+ })),
121
+ }),
122
+ workspace_cancel_file_draft: tool({
123
+ needsApproval: approval,
124
+ description: 'Cancel an unfinished draft without changing a visible file. A committed draft cannot be cancelled.',
125
+ inputSchema: z.strictObject({ draftId: identity }),
126
+ execute: (input, context) => safe(() => workflow.cancel({ ...input, signal: context.abortSignal })),
127
+ }),
128
+ });
129
+ if (workflow.allows('commit'))
130
+ tools.workspace_commit_files = tool({
131
+ strict: false,
132
+ needsApproval: approval,
133
+ description: `Atomically commit 1–${workflow.limits.maxCommitFiles} distinct completed drafts. Supply exact byte sizes. Optional SHA-256 must be known, never invented. A stale head rolls the whole batch back; replay returns stored receipts.`,
134
+ inputSchema: z.strictObject({
135
+ drafts: z
136
+ .array(z.strictObject({
137
+ draftId: identity,
138
+ size: offset,
139
+ sha256: z
140
+ .string()
141
+ .regex(/^[0-9a-f]{64}$/u)
142
+ .optional(),
143
+ }))
144
+ .min(1)
145
+ .max(workflow.limits.maxCommitFiles),
146
+ }),
147
+ execute: (input, context) => safe(async () => ({
148
+ items: await workflow.commit({
149
+ ...input,
150
+ signal: context.abortSignal,
151
+ }),
152
+ })),
153
+ });
154
+ return Object.freeze(tools);
155
+ }
156
+ /** Catalog-backed alternative to the existing raw-workspace tool factory. */
157
+ export function createAiSdkCatalogFileTools(options) {
158
+ const { catalog } = options;
159
+ const tools = {};
160
+ const content = textSchema(Math.min(options.maxWriteBytes ?? 8192, catalog.limits.maxWriteBytes));
161
+ const editSchemas = createAiSdkCatalogFileEditSchemas(Math.min(options.maxWriteBytes ?? 8192, catalog.limits.maxWriteBytes));
162
+ const approval = options.requireApproval ?? true;
163
+ const commandId = options.commandId ?? ((toolCallId) => toolCallId);
164
+ if (catalog.allows('read'))
165
+ Object.assign(tools, {
166
+ workspace_list: tool({
167
+ strict: false,
168
+ description: 'List authorized file catalog entries. Paths are mount-relative. Continue with nextOffset.',
169
+ inputSchema: z.strictObject({
170
+ directory: z.string().optional(),
171
+ ...page,
172
+ }),
173
+ execute: (input, context) => safe(() => catalog.list({ ...input, signal: context.abortSignal })),
174
+ }),
175
+ workspace_stat: tool({
176
+ description: 'Read a file identity, ETag, size and content type without loading its body.',
177
+ inputSchema: z.strictObject({ path }),
178
+ execute: (input, context) => safe(() => catalog.stat({ ...input, signal: context.abortSignal })),
179
+ }),
180
+ workspace_search: tool({
181
+ description: 'Search file paths by literal substring. Continue with nextOffset even when a page has no matches.',
182
+ inputSchema: z.strictObject({
183
+ query: z.string().min(1).max(256),
184
+ ...page,
185
+ }),
186
+ execute: (input, context) => safe(() => catalog.search({ ...input, signal: context.abortSignal })),
187
+ }),
188
+ workspace_read_file: tool({
189
+ strict: false,
190
+ description: `Read at most ${catalog.limits.maxReadBytes} UTF-8 bytes. offset/nextOffset are byte positions at Unicode boundaries. Continue with nextOffset and the same expectedEtag.`,
191
+ inputSchema: z.strictObject({
192
+ path,
193
+ expectedEtag: etag.optional(),
194
+ ...page,
195
+ }),
196
+ execute: (input, context) => safe(() => catalog.readWindow({ ...input, signal: context.abortSignal })),
197
+ }),
198
+ workspace_search_content: tool({
199
+ strict: false,
200
+ description: `Search literal text in one exact file revision. Scan at most ${catalog.limits.maxSearchScanBytes} bytes per call. Continue with nextOffset and the same expectedEtag.`,
201
+ inputSchema: z.strictObject({
202
+ path,
203
+ expectedEtag: etag,
204
+ query: z.string().min(1).max(256),
205
+ ...page,
206
+ }),
207
+ execute: (input, context) => safe(() => catalog.searchContent({ ...input, signal: context.abortSignal })),
208
+ }),
209
+ });
210
+ if (catalog.allows('write'))
211
+ Object.assign(tools, {
212
+ workspace_write_file: tool({
213
+ strict: false,
214
+ needsApproval: approval,
215
+ description: 'Create or conditionally replace a small UTF-8 file. Omit expectedEtag to create; supply the exact current ETag to replace. Use durable drafts for substantial content.',
216
+ inputSchema: z.strictObject({
217
+ path,
218
+ expectedEtag: etag.optional(),
219
+ content,
220
+ }),
221
+ execute: (input, context) => safe(() => catalog.write({
222
+ ...input,
223
+ commandId: commandId(context.toolCallId),
224
+ signal: context.abortSignal,
225
+ })),
226
+ }),
227
+ workspace_append_file: tool({
228
+ needsApproval: approval,
229
+ description: 'Append a bounded UTF-8 chunk to one exact file revision. Pass the latest ETag; retry identity prevents duplicate appends. Durable drafts support large generation.',
230
+ inputSchema: editSchemas.append,
231
+ execute: (input, context) => safe(() => catalog.edit({
232
+ path: input.path,
233
+ expectedEtag: input.expectedEtag,
234
+ change: { kind: 'append', text: input.content },
235
+ commandId: commandId(context.toolCallId),
236
+ signal: context.abortSignal,
237
+ })),
238
+ }),
239
+ workspace_edit_file: tool({
240
+ needsApproval: approval,
241
+ description: 'Replace one exact unique text span at the latest expectedEtag. oldText must match exactly once. The result carries the next revision receipt.',
242
+ inputSchema: editSchemas.edit,
243
+ execute: (input, context) => safe(() => catalog.edit({
244
+ path: input.path,
245
+ expectedEtag: input.expectedEtag,
246
+ change: {
247
+ kind: 'replace',
248
+ oldText: input.oldText,
249
+ newText: input.newText,
250
+ },
251
+ commandId: commandId(context.toolCallId),
252
+ signal: context.abortSignal,
253
+ })),
254
+ }),
255
+ });
256
+ return Object.freeze(tools);
257
+ }
258
+ //# sourceMappingURL=ai-sdk-file-workflow-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-sdk-file-workflow-tools.js","sourceRoot":"","sources":["../../src/ai-sdk/ai-sdk-file-workflow-tools.ts"],"names":[],"mappings":"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","sourcesContent":["import { tool, type ToolSet } from 'ai';\nimport { z } from 'zod';\nimport { isStorageError } from '../storage.error.js';\nimport type {\n StorageFileCatalogCapability,\n StorageFileWorkflowCapability,\n} from '../workspace/index.js';\nimport { AiSdkWorkspaceToolError } from './ai-sdk-workspace-tools.js';\n\nexport interface CreateAiSdkFileWorkflowToolsOptions<Receipt> {\n readonly workflow: StorageFileWorkflowCapability<Receipt>;\n readonly requireApproval?: boolean;\n /** Host-generated token, scoped and stable across replay of this tool call. */\n readonly idempotencyKey?: (toolCallId: string) => string;\n readonly maxChunkBytes?: number;\n}\nexport interface CreateAiSdkCatalogFileToolsOptions<Receipt> {\n readonly catalog: StorageFileCatalogCapability<Receipt>;\n readonly requireApproval?: boolean;\n readonly commandId?: (toolCallId: string) => string;\n readonly maxWriteBytes?: number;\n}\nexport const AI_SDK_FILE_WORKFLOW_TOOL_NAMES = [\n 'workspace_begin_file_draft',\n 'workspace_append_file_draft',\n 'workspace_list_file_drafts',\n 'workspace_read_file_draft',\n 'workspace_list_file_draft_parts',\n 'workspace_cancel_file_draft',\n 'workspace_commit_files',\n] as const;\nexport const AI_SDK_CATALOG_FILE_TOOL_NAMES = [\n 'workspace_list',\n 'workspace_stat',\n 'workspace_search',\n 'workspace_read_file',\n 'workspace_search_content',\n 'workspace_write_file',\n 'workspace_append_file',\n 'workspace_edit_file',\n] as const;\n\nconst offset = z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);\nconst identity = z.string().min(1).max(256);\nconst etag = z.string().min(1).max(1024);\nconst path = z.string().min(1).max(1024);\nconst page = { offset: offset.default(0) };\nfunction textSchema(maxBytes: number) {\n if (!Number.isSafeInteger(maxBytes) || maxBytes < 1)\n throw new TypeError('Text tool limit must be a positive safe integer.');\n return z\n .string()\n .max(maxBytes)\n .refine(\n (text) => !/[\\uD800-\\uDFFF]/u.test(text),\n 'Text must be well-formed UTF-8.',\n )\n .refine(\n (text) => new TextEncoder().encode(text).byteLength <= maxBytes,\n `Use at most ${maxBytes} UTF-8 bytes per call.`,\n );\n}\nasync function safe<Result>(work: () => Promise<Result>): Promise<Result> {\n try {\n return await work();\n } catch (error) {\n if (isStorageError(error))\n throw new AiSdkWorkspaceToolError(error.code, {\n applied: error.applied,\n ...(error.appliedEtag === undefined\n ? {}\n : { appliedEtag: error.appliedEtag }),\n });\n if (error instanceof DOMException && error.name === 'AbortError')\n throw new AiSdkWorkspaceToolError('ABORTED');\n throw new AiSdkWorkspaceToolError('PROVIDER');\n }\n}\n\n/** Typed extension seam for host-only metadata; preserves generic byte validation. */\nexport function createAiSdkCatalogFileEditSchemas(maxWriteBytes = 8192) {\n const content = textSchema(maxWriteBytes);\n return {\n append: z.strictObject({ path, expectedEtag: etag, content }),\n edit: z.strictObject({\n path,\n expectedEtag: etag,\n oldText: content.refine((text) => text.length > 0),\n newText: content,\n }),\n };\n}\n\n/** Generic durable-file tools. Provider upload controls are a separate capability. */\nexport function createAiSdkFileWorkflowTools<Receipt>(\n options: CreateAiSdkFileWorkflowToolsOptions<Receipt>,\n): ToolSet {\n const { workflow } = options;\n const tools: ToolSet = {};\n const content = textSchema(\n Math.min(options.maxChunkBytes ?? 8192, workflow.limits.maxChunkBytes),\n );\n const approval = options.requireApproval ?? true;\n if (workflow.allows('read'))\n Object.assign(tools, {\n workspace_list_file_drafts: tool({\n description:\n 'List durable drafts. Resume open drafts at their current UTF-8 byte size; use nextOffset for pagination.',\n inputSchema: z.strictObject(page),\n execute: (input, context) =>\n safe(() => workflow.list({ ...input, signal: context.abortSignal })),\n }),\n workspace_read_file_draft: tool({\n description: `Read a draft window of at most ${workflow.limits.maxReadBytes} UTF-8 bytes. Continue with nextOffset, which is a byte position at a Unicode boundary.`,\n inputSchema: z.strictObject({ draftId: identity, ...page }),\n execute: (input, context) =>\n safe(() => workflow.read({ ...input, signal: context.abortSignal })),\n }),\n workspace_list_file_draft_parts: tool({\n description:\n 'List bounded chunk integrity receipts for resumption. Each receipt contains its byte offset, size, and SHA-256.',\n inputSchema: z.strictObject({ draftId: identity, ...page }),\n execute: (input, context) =>\n safe(() => workflow.parts({ ...input, signal: context.abortSignal })),\n }),\n } satisfies ToolSet);\n if (workflow.allows('write'))\n Object.assign(tools, {\n workspace_begin_file_draft: tool({\n strict: false,\n needsApproval: approval,\n description:\n 'Begin a durable text draft without changing a visible file. Omit expectedEtag to create a new path; supply the exact current ETag to replace. Use drafts for substantial content and resume interrupted drafts.',\n inputSchema: z.strictObject({ path, expectedEtag: etag.optional() }),\n execute: (input, context) =>\n safe(() =>\n workflow.begin({\n ...input,\n text: true,\n idempotencyKey:\n options.idempotencyKey?.(context.toolCallId) ??\n context.toolCallId,\n signal: context.abortSignal,\n }),\n ),\n }),\n workspace_append_file_draft: tool({\n needsApproval: approval,\n description:\n 'Append a bounded UTF-8 chunk at the draft’s returned byte size. Replaying identical bytes at the same offset is safe; different bytes or a stale offset fail.',\n inputSchema: z.strictObject({\n draftId: identity,\n offset,\n content: content.refine((text) => text.length > 0),\n }),\n execute: (input, context) =>\n safe(() =>\n workflow.append({\n draftId: input.draftId,\n offset: input.offset,\n bytes: new TextEncoder().encode(input.content),\n signal: context.abortSignal,\n }),\n ),\n }),\n workspace_cancel_file_draft: tool({\n needsApproval: approval,\n description:\n 'Cancel an unfinished draft without changing a visible file. A committed draft cannot be cancelled.',\n inputSchema: z.strictObject({ draftId: identity }),\n execute: (input, context) =>\n safe(() =>\n workflow.cancel({ ...input, signal: context.abortSignal }),\n ),\n }),\n } satisfies ToolSet);\n if (workflow.allows('commit'))\n tools.workspace_commit_files = tool({\n strict: false,\n needsApproval: approval,\n description: `Atomically commit 1–${workflow.limits.maxCommitFiles} distinct completed drafts. Supply exact byte sizes. Optional SHA-256 must be known, never invented. A stale head rolls the whole batch back; replay returns stored receipts.`,\n inputSchema: z.strictObject({\n drafts: z\n .array(\n z.strictObject({\n draftId: identity,\n size: offset,\n sha256: z\n .string()\n .regex(/^[0-9a-f]{64}$/u)\n .optional(),\n }),\n )\n .min(1)\n .max(workflow.limits.maxCommitFiles),\n }),\n execute: (input, context) =>\n safe(async () => ({\n items: await workflow.commit({\n ...input,\n signal: context.abortSignal,\n }),\n })),\n });\n return Object.freeze(tools);\n}\n\n/** Catalog-backed alternative to the existing raw-workspace tool factory. */\nexport function createAiSdkCatalogFileTools<Receipt>(\n options: CreateAiSdkCatalogFileToolsOptions<Receipt>,\n): ToolSet {\n const { catalog } = options;\n const tools: ToolSet = {};\n const content = textSchema(\n Math.min(options.maxWriteBytes ?? 8192, catalog.limits.maxWriteBytes),\n );\n const editSchemas = createAiSdkCatalogFileEditSchemas(\n Math.min(options.maxWriteBytes ?? 8192, catalog.limits.maxWriteBytes),\n );\n const approval = options.requireApproval ?? true;\n const commandId = options.commandId ?? ((toolCallId: string) => toolCallId);\n if (catalog.allows('read'))\n Object.assign(tools, {\n workspace_list: tool({\n strict: false,\n description:\n 'List authorized file catalog entries. Paths are mount-relative. Continue with nextOffset.',\n inputSchema: z.strictObject({\n directory: z.string().optional(),\n ...page,\n }),\n execute: (input, context) =>\n safe(() => catalog.list({ ...input, signal: context.abortSignal })),\n }),\n workspace_stat: tool({\n description:\n 'Read a file identity, ETag, size and content type without loading its body.',\n inputSchema: z.strictObject({ path }),\n execute: (input, context) =>\n safe(() => catalog.stat({ ...input, signal: context.abortSignal })),\n }),\n workspace_search: tool({\n description:\n 'Search file paths by literal substring. Continue with nextOffset even when a page has no matches.',\n inputSchema: z.strictObject({\n query: z.string().min(1).max(256),\n ...page,\n }),\n execute: (input, context) =>\n safe(() => catalog.search({ ...input, signal: context.abortSignal })),\n }),\n workspace_read_file: tool({\n strict: false,\n description: `Read at most ${catalog.limits.maxReadBytes} UTF-8 bytes. offset/nextOffset are byte positions at Unicode boundaries. Continue with nextOffset and the same expectedEtag.`,\n inputSchema: z.strictObject({\n path,\n expectedEtag: etag.optional(),\n ...page,\n }),\n execute: (input, context) =>\n safe(() =>\n catalog.readWindow({ ...input, signal: context.abortSignal }),\n ),\n }),\n workspace_search_content: tool({\n strict: false,\n description: `Search literal text in one exact file revision. Scan at most ${catalog.limits.maxSearchScanBytes} bytes per call. Continue with nextOffset and the same expectedEtag.`,\n inputSchema: z.strictObject({\n path,\n expectedEtag: etag,\n query: z.string().min(1).max(256),\n ...page,\n }),\n execute: (input, context) =>\n safe(() =>\n catalog.searchContent({ ...input, signal: context.abortSignal }),\n ),\n }),\n } satisfies ToolSet);\n if (catalog.allows('write'))\n Object.assign(tools, {\n workspace_write_file: tool({\n strict: false,\n needsApproval: approval,\n description:\n 'Create or conditionally replace a small UTF-8 file. Omit expectedEtag to create; supply the exact current ETag to replace. Use durable drafts for substantial content.',\n inputSchema: z.strictObject({\n path,\n expectedEtag: etag.optional(),\n content,\n }),\n execute: (input, context) =>\n safe<unknown>(() =>\n catalog.write({\n ...input,\n commandId: commandId(context.toolCallId),\n signal: context.abortSignal,\n }),\n ),\n }),\n workspace_append_file: tool({\n needsApproval: approval,\n description:\n 'Append a bounded UTF-8 chunk to one exact file revision. Pass the latest ETag; retry identity prevents duplicate appends. Durable drafts support large generation.',\n inputSchema: editSchemas.append,\n execute: (input, context) =>\n safe<unknown>(() =>\n catalog.edit({\n path: input.path,\n expectedEtag: input.expectedEtag,\n change: { kind: 'append', text: input.content },\n commandId: commandId(context.toolCallId),\n signal: context.abortSignal,\n }),\n ),\n }),\n workspace_edit_file: tool({\n needsApproval: approval,\n description:\n 'Replace one exact unique text span at the latest expectedEtag. oldText must match exactly once. The result carries the next revision receipt.',\n inputSchema: editSchemas.edit,\n execute: (input, context) =>\n safe<unknown>(() =>\n catalog.edit({\n path: input.path,\n expectedEtag: input.expectedEtag,\n change: {\n kind: 'replace',\n oldText: input.oldText,\n newText: input.newText,\n },\n commandId: commandId(context.toolCallId),\n signal: context.abortSignal,\n }),\n ),\n }),\n } satisfies ToolSet);\n return Object.freeze(tools);\n}\n"]}
@@ -1,2 +1,3 @@
1
1
  export { AI_SDK_WORKSPACE_TOOL_NAMES, AiSdkWorkspaceToolError, createAiSdkWorkspaceTools, isAiSdkWorkspaceMutationToolName, type AiSdkWorkspaceApprovalConfig, type AiSdkWorkspaceCreateConflict, type AiSdkWorkspaceCreateConflictMapper, type AiSdkWorkspaceDirectoryResult, type AiSdkWorkspaceEntryResult, type AiSdkWorkspaceFileResult, type AiSdkWorkspaceMutationMode, type AiSdkWorkspaceMutationToolName, type AiSdkWorkspacePageResult, type AiSdkWorkspaceTextFileResult, type AiSdkWorkspaceToolErrorCode, type AiSdkWorkspaceToolErrorOptions, type AiSdkWorkspaceToolName, type CreateAiSdkWorkspaceToolsOptions, } from './ai-sdk-workspace-tools.js';
2
+ export { createAiSdkFileWorkflowTools, createAiSdkCatalogFileTools, createAiSdkCatalogFileEditSchemas, AI_SDK_FILE_WORKFLOW_TOOL_NAMES, AI_SDK_CATALOG_FILE_TOOL_NAMES, type CreateAiSdkFileWorkflowToolsOptions, type CreateAiSdkCatalogFileToolsOptions, } from './ai-sdk-file-workflow-tools.js';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ai-sdk/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,uBAAuB,EACvB,yBAAyB,EACzB,gCAAgC,EAChC,KAAK,4BAA4B,EACjC,KAAK,4BAA4B,EACjC,KAAK,kCAAkC,EACvC,KAAK,6BAA6B,EAClC,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,8BAA8B,EACnC,KAAK,wBAAwB,EAC7B,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EAChC,KAAK,8BAA8B,EACnC,KAAK,sBAAsB,EAC3B,KAAK,gCAAgC,GACtC,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ai-sdk/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,uBAAuB,EACvB,yBAAyB,EACzB,gCAAgC,EAChC,KAAK,4BAA4B,EACjC,KAAK,4BAA4B,EACjC,KAAK,kCAAkC,EACvC,KAAK,6BAA6B,EAClC,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,8BAA8B,EACnC,KAAK,wBAAwB,EAC7B,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EAChC,KAAK,8BAA8B,EACnC,KAAK,sBAAsB,EAC3B,KAAK,gCAAgC,GACtC,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,4BAA4B,EAC5B,2BAA2B,EAC3B,iCAAiC,EACjC,+BAA+B,EAC/B,8BAA8B,EAC9B,KAAK,mCAAmC,EACxC,KAAK,kCAAkC,GACxC,MAAM,iCAAiC,CAAC"}
@@ -1,2 +1,3 @@
1
1
  export { AI_SDK_WORKSPACE_TOOL_NAMES, AiSdkWorkspaceToolError, createAiSdkWorkspaceTools, isAiSdkWorkspaceMutationToolName, } from './ai-sdk-workspace-tools.js';
2
+ export { createAiSdkFileWorkflowTools, createAiSdkCatalogFileTools, createAiSdkCatalogFileEditSchemas, AI_SDK_FILE_WORKFLOW_TOOL_NAMES, AI_SDK_CATALOG_FILE_TOOL_NAMES, } from './ai-sdk-file-workflow-tools.js';
2
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ai-sdk/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,uBAAuB,EACvB,yBAAyB,EACzB,gCAAgC,GAejC,MAAM,6BAA6B,CAAC","sourcesContent":["export {\n AI_SDK_WORKSPACE_TOOL_NAMES,\n AiSdkWorkspaceToolError,\n createAiSdkWorkspaceTools,\n isAiSdkWorkspaceMutationToolName,\n type AiSdkWorkspaceApprovalConfig,\n type AiSdkWorkspaceCreateConflict,\n type AiSdkWorkspaceCreateConflictMapper,\n type AiSdkWorkspaceDirectoryResult,\n type AiSdkWorkspaceEntryResult,\n type AiSdkWorkspaceFileResult,\n type AiSdkWorkspaceMutationMode,\n type AiSdkWorkspaceMutationToolName,\n type AiSdkWorkspacePageResult,\n type AiSdkWorkspaceTextFileResult,\n type AiSdkWorkspaceToolErrorCode,\n type AiSdkWorkspaceToolErrorOptions,\n type AiSdkWorkspaceToolName,\n type CreateAiSdkWorkspaceToolsOptions,\n} from './ai-sdk-workspace-tools.js';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ai-sdk/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,uBAAuB,EACvB,yBAAyB,EACzB,gCAAgC,GAejC,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,4BAA4B,EAC5B,2BAA2B,EAC3B,iCAAiC,EACjC,+BAA+B,EAC/B,8BAA8B,GAG/B,MAAM,iCAAiC,CAAC","sourcesContent":["export {\n AI_SDK_WORKSPACE_TOOL_NAMES,\n AiSdkWorkspaceToolError,\n createAiSdkWorkspaceTools,\n isAiSdkWorkspaceMutationToolName,\n type AiSdkWorkspaceApprovalConfig,\n type AiSdkWorkspaceCreateConflict,\n type AiSdkWorkspaceCreateConflictMapper,\n type AiSdkWorkspaceDirectoryResult,\n type AiSdkWorkspaceEntryResult,\n type AiSdkWorkspaceFileResult,\n type AiSdkWorkspaceMutationMode,\n type AiSdkWorkspaceMutationToolName,\n type AiSdkWorkspacePageResult,\n type AiSdkWorkspaceTextFileResult,\n type AiSdkWorkspaceToolErrorCode,\n type AiSdkWorkspaceToolErrorOptions,\n type AiSdkWorkspaceToolName,\n type CreateAiSdkWorkspaceToolsOptions,\n} from './ai-sdk-workspace-tools.js';\nexport {\n createAiSdkFileWorkflowTools,\n createAiSdkCatalogFileTools,\n createAiSdkCatalogFileEditSchemas,\n AI_SDK_FILE_WORKFLOW_TOOL_NAMES,\n AI_SDK_CATALOG_FILE_TOOL_NAMES,\n type CreateAiSdkFileWorkflowToolsOptions,\n type CreateAiSdkCatalogFileToolsOptions,\n} from './ai-sdk-file-workflow-tools.js';\n"]}
@@ -0,0 +1,30 @@
1
+ /** Browser-safe bounded byte helpers. No Node, framework, provider or AI imports. */
2
+ export declare function sha256StorageBytes(bytes: Uint8Array, options: {
3
+ readonly maxBytes: number;
4
+ readonly signal?: AbortSignal | undefined;
5
+ }): Promise<string>;
6
+ /** Defers only a valid incomplete suffix (at most 3 bytes), never malformed data. */
7
+ export declare function trimStorageUtf8Chunk(bytes: Uint8Array, options: {
8
+ readonly final: boolean;
9
+ }): Uint8Array;
10
+ export declare function encodeStorageBase64(bytes: Uint8Array, options: {
11
+ readonly maxBytes: number;
12
+ }): string;
13
+ export interface StorageChunkIntegrityReceipt {
14
+ readonly offset: number;
15
+ readonly size: number;
16
+ readonly sha256: string;
17
+ }
18
+ /** Verify receipt bounds, ordering and actual local bytes before skipping a chunk. */
19
+ export declare function verifyStorageChunkReceipt(blob: Blob, receipt: StorageChunkIntegrityReceipt, options: {
20
+ readonly offset: number;
21
+ readonly maxBytes: number;
22
+ readonly signal?: AbortSignal | undefined;
23
+ }): Promise<number>;
24
+ /** Bounded UTF-8 validation; filename/MIME classification remains host policy. */
25
+ export declare function isStorageUtf8Blob(blob: Blob, options: {
26
+ readonly chunkBytes: number;
27
+ readonly rejectNul?: boolean;
28
+ readonly signal?: AbortSignal | undefined;
29
+ }): Promise<boolean>;
30
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bytes/index.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE;IACP,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CAC3C,GACA,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED,qFAAqF;AACrF,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACnC,UAAU,CA2BZ;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACrC,MAAM,CAQR;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AACD,sFAAsF;AACtF,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,4BAA4B,EACrC,OAAO,EAAE;IACP,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CAC3C,GACA,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAED,kFAAkF;AAClF,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE;IACP,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CAC3C,GACA,OAAO,CAAC,OAAO,CAAC,CAoBlB"}