@ouispec/agent-worker 0.7.0 → 0.8.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.
Files changed (65) hide show
  1. package/README.md +31 -1
  2. package/dist/approvals/preview.d.ts +2 -2
  3. package/dist/approvals/preview.d.ts.map +1 -1
  4. package/dist/approvals/preview.js +20 -3
  5. package/dist/approvals/preview.js.map +1 -1
  6. package/dist/attachments/content.d.ts +68 -0
  7. package/dist/attachments/content.d.ts.map +1 -0
  8. package/dist/attachments/content.js +318 -0
  9. package/dist/attachments/content.js.map +1 -0
  10. package/dist/attachments/guard.d.ts +69 -0
  11. package/dist/attachments/guard.d.ts.map +1 -0
  12. package/dist/attachments/guard.js +86 -0
  13. package/dist/attachments/guard.js.map +1 -0
  14. package/dist/attachments/limits.d.ts +46 -0
  15. package/dist/attachments/limits.d.ts.map +1 -0
  16. package/dist/attachments/limits.js +64 -0
  17. package/dist/attachments/limits.js.map +1 -0
  18. package/dist/attachments/store.d.ts +85 -0
  19. package/dist/attachments/store.d.ts.map +1 -0
  20. package/dist/attachments/store.js +2 -0
  21. package/dist/attachments/store.js.map +1 -0
  22. package/dist/attachments/tools.d.ts +12 -0
  23. package/dist/attachments/tools.d.ts.map +1 -0
  24. package/dist/attachments/tools.js +216 -0
  25. package/dist/attachments/tools.js.map +1 -0
  26. package/dist/authz/tool-policy.d.ts +6 -0
  27. package/dist/authz/tool-policy.d.ts.map +1 -1
  28. package/dist/authz/tool-policy.js.map +1 -1
  29. package/dist/index.d.ts +7 -2
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +5 -1
  32. package/dist/index.js.map +1 -1
  33. package/dist/orchestrator.d.ts.map +1 -1
  34. package/dist/orchestrator.js +202 -26
  35. package/dist/orchestrator.js.map +1 -1
  36. package/dist/prompt/clock.d.ts +0 -17
  37. package/dist/prompt/clock.d.ts.map +1 -1
  38. package/dist/prompt/clock.js +19 -2
  39. package/dist/prompt/clock.js.map +1 -1
  40. package/dist/prompt/user-text.d.ts +19 -0
  41. package/dist/prompt/user-text.d.ts.map +1 -0
  42. package/dist/prompt/user-text.js +20 -0
  43. package/dist/prompt/user-text.js.map +1 -0
  44. package/dist/runtime/turn-runner.d.ts +10 -2
  45. package/dist/runtime/turn-runner.d.ts.map +1 -1
  46. package/dist/runtime/turn-runner.js +41 -1
  47. package/dist/runtime/turn-runner.js.map +1 -1
  48. package/dist/runtime/types.d.ts +23 -2
  49. package/dist/runtime/types.d.ts.map +1 -1
  50. package/dist/stop/turn-stop.d.ts +6 -6
  51. package/dist/stop/turn-stop.d.ts.map +1 -1
  52. package/dist/stop/turn-stop.js +6 -2
  53. package/dist/stop/turn-stop.js.map +1 -1
  54. package/dist/tools/input-validation.d.ts.map +1 -1
  55. package/dist/tools/input-validation.js +3 -0
  56. package/dist/tools/input-validation.js.map +1 -1
  57. package/dist/tools/types.d.ts +12 -0
  58. package/dist/tools/types.d.ts.map +1 -1
  59. package/dist/tools/types.js.map +1 -1
  60. package/dist/turn-policy.d.ts +14 -0
  61. package/dist/turn-policy.d.ts.map +1 -1
  62. package/dist/turn-policy.js.map +1 -1
  63. package/dist/types.d.ts +26 -2
  64. package/dist/types.d.ts.map +1 -1
  65. package/package.json +6 -6
@@ -0,0 +1,86 @@
1
+ /**
2
+ * The attachment cost guard (ADR-0252 §2.11).
3
+ *
4
+ * A file given to the model is resent with every model step of the turn, so
5
+ * what a turn costs is what it gives each step times the steps it takes.
6
+ * Before each step the guard adds up what that step would carry; when the
7
+ * turn's cap or the conversation's would be passed, the costliest files are
8
+ * given as their reference line from that step on, and the model is told they
9
+ * were left out. A file left out is still in the conversation and still
10
+ * usable by actions.
11
+ */
12
+ import { DEFAULT_CONVERSATION_ATTACHMENT_TOKENS, DEFAULT_TURN_ATTACHMENT_TOKENS } from './limits.js';
13
+ export class AttachmentGuard {
14
+ turnCap;
15
+ conversationCap;
16
+ active = new Map();
17
+ given = new Map();
18
+ leftOut = new Set();
19
+ spent = 0;
20
+ constructor(options = {}) {
21
+ this.turnCap = options.turnTokens ?? DEFAULT_TURN_ATTACHMENT_TOKENS;
22
+ // The conversation's cap, less what its earlier turns gave: what this turn may still give.
23
+ this.conversationCap = Math.max(0, (options.conversationTokens ?? DEFAULT_CONVERSATION_ATTACHMENT_TOKENS) - (options.conversationUsed ?? 0));
24
+ }
25
+ get cap() {
26
+ return Math.min(this.turnCap, this.conversationCap);
27
+ }
28
+ activeTokens() {
29
+ let sum = 0;
30
+ for (const part of this.active.values())
31
+ sum += part.tokens;
32
+ return sum;
33
+ }
34
+ /** Whether a part of `tokens` fits in the next step as well as what is already given. */
35
+ admits(tokens) {
36
+ return this.spent + this.activeTokens() + tokens <= this.cap;
37
+ }
38
+ /** The cap a part of `tokens` would pass, or null when it fits: what the model is told when it is not given. */
39
+ passes(tokens) {
40
+ const need = this.spent + this.activeTokens() + tokens;
41
+ if (need <= this.cap)
42
+ return null;
43
+ return need > this.conversationCap ? 'conversation' : 'turn';
44
+ }
45
+ /** Give a part from the next step on. */
46
+ add(part) {
47
+ this.active.set(part.key, part);
48
+ this.given.set(part.key, part);
49
+ }
50
+ /** Record a part that was not given at all: over the cap before its first step. */
51
+ refuse(part) {
52
+ this.given.set(part.key, { ...part, where: { message: true }, leftOutLine: '' });
53
+ this.leftOut.add(part.key);
54
+ }
55
+ /**
56
+ * Before a step: leave out the costliest parts until the step fits, then
57
+ * count the step. Returns the parts left out at this step.
58
+ */
59
+ beforeStep() {
60
+ const dropped = [];
61
+ while (this.active.size > 0 && this.spent + this.activeTokens() > this.cap) {
62
+ const costliest = [...this.active.values()].reduce((a, b) => (b.tokens > a.tokens ? b : a));
63
+ this.active.delete(costliest.key);
64
+ this.leftOut.add(costliest.key);
65
+ dropped.push(costliest);
66
+ }
67
+ this.spent += this.activeTokens();
68
+ return dropped;
69
+ }
70
+ /** Every part left out so far, with what replaces it. */
71
+ leftOutParts() {
72
+ return [...this.leftOut].map((key) => this.given.get(key)).filter((p) => p.leftOutLine);
73
+ }
74
+ usage() {
75
+ const parts = [...this.given.values()];
76
+ return {
77
+ count: new Set(parts.map((p) => p.attachmentId)).size,
78
+ images: parts.filter((p) => p.kind === 'image' && !this.leftOut.has(p.key)).length,
79
+ textChars: parts.filter((p) => !this.leftOut.has(p.key)).reduce((sum, p) => sum + (p.textChars ?? 0), 0),
80
+ pdfPages: parts.filter((p) => !this.leftOut.has(p.key)).reduce((sum, p) => sum + (p.pdfPages ?? 0), 0),
81
+ estimatedTokens: this.spent,
82
+ leftOut: this.leftOut.size,
83
+ };
84
+ }
85
+ }
86
+ //# sourceMappingURL=guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guard.js","sourceRoot":"","sources":["../../src/attachments/guard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * What the model is given of a file, in one place (ADR-0252 §2.11).
3
+ *
4
+ * Ours, and the tighter of ours and the provider's. Claude on Amazon Bedrock
5
+ * through the Converse API (checked 2026-10-06, "Message", Bedrock API
6
+ * reference) takes on one message at most 20 images, each at most 3.75 MB and
7
+ * 8,000 × 8,000 px, and at most 5 documents, each at most 4.5 MB, with a text
8
+ * block beside them; images and documents only on a user message.
9
+ */
10
+ /** A picture's longest edge as the model is given it: the platform makes this rendition at commit. */
11
+ export declare const MODEL_IMAGE_MAX_EDGE = 1568;
12
+ /** A picture's bytes as the model is given it (well under the provider's 3.75 MB). */
13
+ export declare const MODEL_IMAGE_MAX_BYTES: number;
14
+ /** The picture types a model is given; the platform re-encodes others. */
15
+ export declare const MODEL_IMAGE_MEDIA_TYPES: readonly ["image/png", "image/jpeg", "image/webp"];
16
+ /**
17
+ * Why a picture the store gave cannot go to the model, or null when it can:
18
+ * a type the model does not take, or more bytes than the rendition may have.
19
+ * The provider refuses a whole request over its own limit, and a picture in a
20
+ * tool result is resent on every later step, so it is checked before it goes.
21
+ */
22
+ export declare function modelImageRefusal(mediaType: string, bytes: number): string | null;
23
+ /** The provider's limit on images in one message. */
24
+ export declare const PROVIDER_MAX_IMAGES = 20;
25
+ /** A text file's characters given with the message it is attached to. */
26
+ export declare const TEXT_CHARS_PER_FILE = 20000;
27
+ /** All text files' characters given with one message. */
28
+ export declare const TEXT_CHARS_PER_TURN = 40000;
29
+ /** The most `attachment_read` returns in one call. */
30
+ export declare const READ_CHARS_PER_CALL = 20000;
31
+ /** A PDF given as a document part has at most this many pages; a longer one goes as its text. */
32
+ export declare const PDF_DOCUMENT_MAX_PAGES = 20;
33
+ /** The provider's document size limit. */
34
+ export declare const PDF_DOCUMENT_MAX_BYTES: number;
35
+ /** The provider's limit on documents in one message. */
36
+ export declare const PROVIDER_MAX_DOCUMENTS = 5;
37
+ /** The cost guard's caps on attachment input, in estimated tokens (ADR-0252 §6.3). */
38
+ export declare const DEFAULT_TURN_ATTACHMENT_TOKENS = 30000;
39
+ export declare const DEFAULT_CONVERSATION_ATTACHMENT_TOKENS = 300000;
40
+ /** An image's tokens as Claude counts them: about one per 750 pixels, at the size it is given. */
41
+ export declare function imageTokens(width: number | undefined, height: number | undefined): number;
42
+ /** Text's tokens: about one per four characters. */
43
+ export declare function textTokens(chars: number): number;
44
+ /** A PDF document part's tokens: its text and an image of each page, about 2,300 a page. */
45
+ export declare function pdfDocumentTokens(pages: number | undefined): number;
46
+ //# sourceMappingURL=limits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/attachments/limits.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,sGAAsG;AACtG,eAAO,MAAM,oBAAoB,OAAO,CAAC;AACzC,sFAAsF;AACtF,eAAO,MAAM,qBAAqB,QAAc,CAAC;AACjD,0EAA0E;AAC1E,eAAO,MAAM,uBAAuB,oDAAqD,CAAC;AAC1F;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASjF;AAED,qDAAqD;AACrD,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,yEAAyE;AACzE,eAAO,MAAM,mBAAmB,QAAS,CAAC;AAC1C,yDAAyD;AACzD,eAAO,MAAM,mBAAmB,QAAS,CAAC;AAC1C,sDAAsD;AACtD,eAAO,MAAM,mBAAmB,QAAS,CAAC;AAE1C,iGAAiG;AACjG,eAAO,MAAM,sBAAsB,KAAK,CAAC;AACzC,0CAA0C;AAC1C,eAAO,MAAM,sBAAsB,QAAoB,CAAC;AACxD,wDAAwD;AACxD,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,sFAAsF;AACtF,eAAO,MAAM,8BAA8B,QAAS,CAAC;AACrD,eAAO,MAAM,sCAAsC,SAAU,CAAC;AAE9D,kGAAkG;AAClG,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAIzF;AAED,oDAAoD;AACpD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,4FAA4F;AAC5F,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAEnE"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * What the model is given of a file, in one place (ADR-0252 §2.11).
3
+ *
4
+ * Ours, and the tighter of ours and the provider's. Claude on Amazon Bedrock
5
+ * through the Converse API (checked 2026-10-06, "Message", Bedrock API
6
+ * reference) takes on one message at most 20 images, each at most 3.75 MB and
7
+ * 8,000 × 8,000 px, and at most 5 documents, each at most 4.5 MB, with a text
8
+ * block beside them; images and documents only on a user message.
9
+ */
10
+ /** A picture's longest edge as the model is given it: the platform makes this rendition at commit. */
11
+ export const MODEL_IMAGE_MAX_EDGE = 1568;
12
+ /** A picture's bytes as the model is given it (well under the provider's 3.75 MB). */
13
+ export const MODEL_IMAGE_MAX_BYTES = 1024 * 1024;
14
+ /** The picture types a model is given; the platform re-encodes others. */
15
+ export const MODEL_IMAGE_MEDIA_TYPES = ['image/png', 'image/jpeg', 'image/webp'];
16
+ /**
17
+ * Why a picture the store gave cannot go to the model, or null when it can:
18
+ * a type the model does not take, or more bytes than the rendition may have.
19
+ * The provider refuses a whole request over its own limit, and a picture in a
20
+ * tool result is resent on every later step, so it is checked before it goes.
21
+ */
22
+ export function modelImageRefusal(mediaType, bytes) {
23
+ const type = String(mediaType ?? '').split(';')[0].trim().toLowerCase();
24
+ if (!MODEL_IMAGE_MEDIA_TYPES.includes(type)) {
25
+ return `its picture is ${type || 'of no type'}, and a model is given only ${MODEL_IMAGE_MEDIA_TYPES.join(', ')}`;
26
+ }
27
+ if (bytes > MODEL_IMAGE_MAX_BYTES) {
28
+ return `its picture is ${(bytes / (1024 * 1024)).toFixed(1)} MB, over the ${MODEL_IMAGE_MAX_BYTES / (1024 * 1024)} MB a model is given`;
29
+ }
30
+ return null;
31
+ }
32
+ /** The provider's limit on images in one message. */
33
+ export const PROVIDER_MAX_IMAGES = 20;
34
+ /** A text file's characters given with the message it is attached to. */
35
+ export const TEXT_CHARS_PER_FILE = 20_000;
36
+ /** All text files' characters given with one message. */
37
+ export const TEXT_CHARS_PER_TURN = 40_000;
38
+ /** The most `attachment_read` returns in one call. */
39
+ export const READ_CHARS_PER_CALL = 20_000;
40
+ /** A PDF given as a document part has at most this many pages; a longer one goes as its text. */
41
+ export const PDF_DOCUMENT_MAX_PAGES = 20;
42
+ /** The provider's document size limit. */
43
+ export const PDF_DOCUMENT_MAX_BYTES = 4.5 * 1024 * 1024;
44
+ /** The provider's limit on documents in one message. */
45
+ export const PROVIDER_MAX_DOCUMENTS = 5;
46
+ /** The cost guard's caps on attachment input, in estimated tokens (ADR-0252 §6.3). */
47
+ export const DEFAULT_TURN_ATTACHMENT_TOKENS = 30_000;
48
+ export const DEFAULT_CONVERSATION_ATTACHMENT_TOKENS = 300_000;
49
+ /** An image's tokens as Claude counts them: about one per 750 pixels, at the size it is given. */
50
+ export function imageTokens(width, height) {
51
+ if (!width || !height)
52
+ return Math.ceil((MODEL_IMAGE_MAX_EDGE * MODEL_IMAGE_MAX_EDGE) / 750);
53
+ const scale = Math.min(1, MODEL_IMAGE_MAX_EDGE / Math.max(width, height));
54
+ return Math.ceil((Math.round(width * scale) * Math.round(height * scale)) / 750);
55
+ }
56
+ /** Text's tokens: about one per four characters. */
57
+ export function textTokens(chars) {
58
+ return Math.ceil(chars / 4);
59
+ }
60
+ /** A PDF document part's tokens: its text and an image of each page, about 2,300 a page. */
61
+ export function pdfDocumentTokens(pages) {
62
+ return (pages ?? PDF_DOCUMENT_MAX_PAGES) * 2_300;
63
+ }
64
+ //# sourceMappingURL=limits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limits.js","sourceRoot":"","sources":["../../src/attachments/limits.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,sGAAsG;AACtG,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAC;AACzC,sFAAsF;AACtF,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,GAAG,IAAI,CAAC;AACjD,0EAA0E;AAC1E,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,WAAW,EAAE,YAAY,EAAE,YAAY,CAAU,CAAC;AAC1F;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,SAAiB,EAAE,KAAa;IAChE,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACxE,IAAI,CAAE,uBAA6C,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnE,OAAO,kBAAkB,IAAI,IAAI,YAAY,+BAA+B,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IACnH,CAAC;IACD,IAAI,KAAK,GAAG,qBAAqB,EAAE,CAAC;QAClC,OAAO,kBAAkB,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAiB,qBAAqB,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,sBAAsB,CAAC;IAC1I,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,qDAAqD;AACrD,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAEtC,yEAAyE;AACzE,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAC1C,yDAAyD;AACzD,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAC1C,sDAAsD;AACtD,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAE1C,iGAAiG;AACjG,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AACzC,0CAA0C;AAC1C,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AACxD,wDAAwD;AACxD,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAExC,sFAAsF;AACtF,MAAM,CAAC,MAAM,8BAA8B,GAAG,MAAM,CAAC;AACrD,MAAM,CAAC,MAAM,sCAAsC,GAAG,OAAO,CAAC;AAE9D,kGAAkG;AAClG,MAAM,UAAU,WAAW,CAAC,KAAyB,EAAE,MAA0B;IAC/E,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,oBAAoB,GAAG,oBAAoB,CAAC,GAAG,GAAG,CAAC,CAAC;IAC7F,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAC1E,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;AACnF,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,iBAAiB,CAAC,KAAyB;IACzD,OAAO,CAAC,KAAK,IAAI,sBAAsB,CAAC,GAAG,KAAK,CAAC;AACnD,CAAC"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * The host's file area, as the worker reads it (ADR-0252 §3). The worker never
3
+ * holds a URL or a key: it asks the host for a file by id, for the turn's own
4
+ * conversation and user, and the host checks the file is theirs on every call.
5
+ */
6
+ import type { AttachmentRef } from '@ouispec/agent-core';
7
+ /** Whose file: the turn's user, account and conversation. A file of another conversation is never resolved. */
8
+ export interface AttachmentOwner {
9
+ userId: string;
10
+ accountId: string;
11
+ conversationId: string;
12
+ }
13
+ /**
14
+ * What the model is given of a file:
15
+ * - `image`: the model's rendition (at most 1,568 px on its longest edge and 1 MB);
16
+ * - `text`: the file's text, or a PDF's extracted text, from `offset`, at most `limit` characters;
17
+ * - `document`: a PDF's bytes, for a document part.
18
+ */
19
+ export type AttachmentLoadAs = 'image' | 'text' | 'document';
20
+ export type AttachmentContent = {
21
+ ok: true;
22
+ mediaType: string;
23
+ bytes: Uint8Array;
24
+ } | {
25
+ ok: true;
26
+ text: string;
27
+ /** The file's whole text length, so the model is told how much it was not given. */
28
+ totalChars: number;
29
+ } | {
30
+ ok: false;
31
+ /**
32
+ * - `gone`: removed, or no longer stored.
33
+ * - `pending`: still being checked (its malware scan): it can be read once that passes.
34
+ * - `refused`: not this turn's to read, or the check refused it.
35
+ * - `unsupported`: nothing of that form exists for it.
36
+ */
37
+ reason: 'gone' | 'pending' | 'refused' | 'unsupported';
38
+ message?: string;
39
+ };
40
+ /** What every call to the store may be given: the turn's signal, aborted when the turn is stopped or runs out of time. */
41
+ export interface AttachmentStoreCallOptions {
42
+ signal?: AbortSignal;
43
+ }
44
+ export interface AttachmentStore {
45
+ /**
46
+ * The references of these files, if they are the owner's; ids that are not
47
+ * are left out. A file still being checked is described with `pending`.
48
+ */
49
+ describe(ids: readonly string[], owner: AttachmentOwner, options?: AttachmentStoreCallOptions): Promise<AttachmentRef[]>;
50
+ /**
51
+ * A file's content in the form asked for. An image is the model's rendition:
52
+ * PNG, JPEG or WebP, at most 1 MB (`MODEL_IMAGE_MEDIA_TYPES`,
53
+ * `MODEL_IMAGE_MAX_BYTES`); anything else is not given to the model.
54
+ */
55
+ load(id: string, owner: AttachmentOwner, as: AttachmentLoadAs, options?: AttachmentStoreCallOptions & {
56
+ range?: {
57
+ offset: number;
58
+ limit: number;
59
+ };
60
+ }): Promise<AttachmentContent>;
61
+ /** Every file of the conversation, newest last, removed ones marked, ones still being checked `pending`. */
62
+ list(owner: AttachmentOwner, options?: AttachmentStoreCallOptions): Promise<AttachmentRef[]>;
63
+ /**
64
+ * The estimated attachment tokens the conversation's earlier turns were
65
+ * given, for the conversation's cap. Without it only the turn's cap applies.
66
+ */
67
+ conversationUsage?(owner: AttachmentOwner, options?: AttachmentStoreCallOptions): Promise<number>;
68
+ }
69
+ /** How the worker gives a turn's files to the model (`AgentWorkerConfig.attachments`). */
70
+ export interface AttachmentWorkerConfig {
71
+ store: AttachmentStore;
72
+ /** Estimated tokens of attachment input one turn may give the model. Default 30,000. */
73
+ turnTokens?: number;
74
+ /** Estimated tokens of attachment input one conversation may give the model. Default 300,000. */
75
+ conversationTokens?: number;
76
+ /** Files one message gives the model; any more are named as not given. Default 5 (ADR-0252 §6.3). */
77
+ perMessage?: number;
78
+ /**
79
+ * Give a short PDF to the model as a document part. Off until a live eval
80
+ * of the provider's document part passes (ADR-0252 §2.11): a PDF then goes
81
+ * as its extracted text, which is complete without it.
82
+ */
83
+ pdfAsDocument?: boolean;
84
+ }
85
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/attachments/store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,+GAA+G;AAC/G,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,CAAC;AAE7D,MAAM,MAAM,iBAAiB,GACzB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GAClD;IACE,EAAE,EAAE,IAAI,CAAC;IACT,IAAI,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,UAAU,EAAE,MAAM,CAAC;CACpB,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV;;;;;OAKG;IACH,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAC;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEN,0HAA0H;AAC1H,MAAM,WAAW,0BAA0B;IACzC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,0BAA0B,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACzH;;;;OAIG;IACH,IAAI,CACF,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,eAAe,EACtB,EAAE,EAAE,gBAAgB,EACpB,OAAO,CAAC,EAAE,0BAA0B,GAAG;QAAE,KAAK,CAAC,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,GACnF,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC9B,4GAA4G;IAC5G,IAAI,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,0BAA0B,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IAC7F;;;OAGG;IACH,iBAAiB,CAAC,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,0BAA0B,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACnG;AAED,0FAA0F;AAC1F,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,eAAe,CAAC;IACvB,wFAAwF;IACxF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iGAAiG;IACjG,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qGAAqG;IACrG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/attachments/store.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ import type { RegisteredTool } from '../tools/types.js';
2
+ import type { AttachmentGuard } from './guard.js';
3
+ import type { AttachmentOwner, AttachmentStore } from './store.js';
4
+ /** The tool class of the attachment tools, as a host's tool policy sees it. */
5
+ export declare const ATTACHMENT_TOOL_CLASS = "attachment";
6
+ export declare const ATTACHMENT_TOOLS: readonly ["attachment_list", "attachment_view", "attachment_read"];
7
+ export declare function attachmentTools(context: {
8
+ store: AttachmentStore;
9
+ owner: AttachmentOwner;
10
+ guard: AttachmentGuard;
11
+ }): RegisteredTool[];
12
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/attachments/tools.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAA6C,MAAM,mBAAmB,CAAC;AACnG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAqB,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAItF,+EAA+E;AAC/E,eAAO,MAAM,qBAAqB,eAAe,CAAC;AAElD,eAAO,MAAM,gBAAgB,oEAA6C,CAAC;AAiB3E,wBAAgB,eAAe,CAAC,OAAO,EAAE;IAAE,KAAK,EAAE,eAAe,CAAC;IAAC,KAAK,EAAE,eAAe,CAAC;IAAC,KAAK,EAAE,eAAe,CAAA;CAAE,GAAG,cAAc,EAAE,CA8KrI"}
@@ -0,0 +1,216 @@
1
+ /**
2
+ * The attachment tools (ADR-0252 §2.12): how the assistant comes back to a
3
+ * file after the message it came with, by its id.
4
+ *
5
+ * - `attachment_list`: the conversation's files, so "the logo I sent earlier"
6
+ * is answerable after its message has left the history.
7
+ * - `attachment_view`: a picture, given to the model as the result's picture.
8
+ * - `attachment_read`: a page of a file's text, or a PDF's.
9
+ *
10
+ * SDK-owned backend tools of the class `attachment`: not UI tools, so not
11
+ * subject to the page's sight rule and holding no place in the UI sequence.
12
+ * Each reads through the host's store, which checks on every call that the
13
+ * file is the turn's conversation's, and each counts against the cost guard.
14
+ */
15
+ import { attachmentReferenceLine, isAttachmentId } from '@ouispec/agent-core';
16
+ import { imageTokens, modelImageRefusal, READ_CHARS_PER_CALL, textTokens } from './limits.js';
17
+ import { capReachedReason, LIST_TOOL, READ_TOOL, textBlock, VIEW_TOOL } from './content.js';
18
+ /** The tool class of the attachment tools, as a host's tool policy sees it. */
19
+ export const ATTACHMENT_TOOL_CLASS = 'attachment';
20
+ export const ATTACHMENT_TOOLS = [LIST_TOOL, VIEW_TOOL, READ_TOOL];
21
+ const fail = (error) => ({ success: false, error });
22
+ function base64Of(bytes) {
23
+ return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString('base64');
24
+ }
25
+ /** A store failure, said without its details: they are the host's, and the turn goes on. */
26
+ function failedLine(ref, err) {
27
+ const what = ref ? attachmentReferenceLine(ref) : 'The file';
28
+ const aborted = err instanceof Error && (err.name === 'AbortError' || err.name === 'TimeoutError');
29
+ return aborted ? `${what} was not loaded: the turn stopped.` : `${what} could not be loaded. Try again, or go on without it.`;
30
+ }
31
+ const STILL_CHECKED = 'is still being checked; it can be used once that is done. Try again shortly.';
32
+ export function attachmentTools(context) {
33
+ const { store, owner, guard } = context;
34
+ const one = async (id, ctx) => {
35
+ if (!isAttachmentId(id))
36
+ return { error: 'Give the attachment’s id, as its reference line shows it ("att_…").' };
37
+ let ref;
38
+ try {
39
+ [ref] = await store.describe([id], owner, { signal: ctx.abortSignal });
40
+ }
41
+ catch (err) {
42
+ return { error: failedLine(null, err) };
43
+ }
44
+ if (!ref)
45
+ return { error: `No attachment ${id} in this conversation.` };
46
+ if (ref.removed)
47
+ return { error: `${attachmentReferenceLine(ref)} It was removed; it cannot be read.` };
48
+ if (ref.pending)
49
+ return { error: `${attachmentReferenceLine(ref)} ${STILL_CHECKED}` };
50
+ return { ref };
51
+ };
52
+ const load = async (ref, ctx, ...rest) => {
53
+ try {
54
+ return await store.load(ref.id, owner, rest[0], { ...rest[1], signal: ctx.abortSignal });
55
+ }
56
+ catch (err) {
57
+ return { failed: failedLine(ref, err) };
58
+ }
59
+ };
60
+ const unavailable = (ref, content, doing) => content.reason === 'pending'
61
+ ? `${attachmentReferenceLine(ref)} ${STILL_CHECKED}`
62
+ : (content.message ?? `${attachmentReferenceLine(ref)} cannot be ${doing}: it is ${content.reason}.`);
63
+ const list = {
64
+ name: LIST_TOOL,
65
+ toolClass: ATTACHMENT_TOOL_CLASS,
66
+ kind: 'backend',
67
+ effect: 'view',
68
+ description: 'Lists the files the person attached in this conversation, oldest first: each one’s id, name, type, size, and a picture’s size; a file still being checked says so. ' +
69
+ `Use it to find a file attached earlier ("the logo I sent"), then ${VIEW_TOOL} or ${READ_TOOL} with its id, or pass the id to an action that takes a file.`,
70
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false, sideEffects: false },
71
+ execute: async (_input, ctx) => {
72
+ let files;
73
+ try {
74
+ files = await store.list(owner, { signal: ctx.abortSignal });
75
+ }
76
+ catch (err) {
77
+ return fail(failedLine(null, err).replace('The file', 'The conversation’s files'));
78
+ }
79
+ // What each file is, by its line: the name the model reads is the cleaned one.
80
+ return {
81
+ success: true,
82
+ data: {
83
+ files: files.map((ref) => ({
84
+ id: ref.id,
85
+ kind: ref.kind,
86
+ line: attachmentReferenceLine(ref),
87
+ ...(ref.removed ? { removed: true } : {}),
88
+ ...(ref.pending ? { pending: true } : {}),
89
+ })),
90
+ count: files.length,
91
+ },
92
+ };
93
+ },
94
+ };
95
+ const view = {
96
+ name: VIEW_TOOL,
97
+ toolClass: ATTACHMENT_TOOL_CLASS,
98
+ kind: 'backend',
99
+ effect: 'view',
100
+ description: 'Looks at a picture the person attached in this conversation, by its id: the picture comes with the result. Pictures are not repeated in later turns, so look again when you need to.',
101
+ inputSchema: {
102
+ type: 'object',
103
+ properties: { id: { type: 'string', description: 'The attachment’s id, from its reference line or attachment_list.' } },
104
+ required: ['id'],
105
+ additionalProperties: false,
106
+ sideEffects: false,
107
+ },
108
+ execute: async (input, ctx) => {
109
+ const found = await one(input.id, ctx);
110
+ if ('error' in found)
111
+ return fail(found.error);
112
+ const { ref } = found;
113
+ if (ref.kind !== 'image')
114
+ return fail(`${attachmentReferenceLine(ref)} is not a picture: read it with ${READ_TOOL}.`);
115
+ const tokens = imageTokens(ref.width, ref.height);
116
+ const over = guard.passes(tokens);
117
+ if (over) {
118
+ guard.refuse({ key: `tool:${ctx.toolCallId ?? ref.id}`, attachmentId: ref.id, kind: 'image', tokens });
119
+ return fail(`Not shown: ${capReachedReason(over, VIEW_TOOL)}`);
120
+ }
121
+ const content = await load(ref, ctx, 'image');
122
+ if ('failed' in content)
123
+ return fail(content.failed);
124
+ if (!content.ok)
125
+ return fail(unavailable(ref, content, 'shown'));
126
+ if (!('bytes' in content))
127
+ return fail(`${attachmentReferenceLine(ref)} has no picture to show.`);
128
+ const refusal = modelImageRefusal(content.mediaType, content.bytes.byteLength);
129
+ if (refusal)
130
+ return fail(`${attachmentReferenceLine(ref)} cannot be shown: ${refusal}.`);
131
+ guard.add({
132
+ key: `tool:${ctx.toolCallId ?? ref.id}`,
133
+ attachmentId: ref.id,
134
+ kind: 'image',
135
+ tokens,
136
+ where: { toolCallId: ctx.toolCallId ?? '' },
137
+ leftOutLine: `${attachmentReferenceLine(ref)} Its picture is not repeated from here on, to keep within the allowance for files.`,
138
+ });
139
+ return {
140
+ success: true,
141
+ data: { attachment: attachmentReferenceLine(ref), shown: 'The picture is attached to this result: look at it.' },
142
+ image: { mediaType: content.mediaType, base64: base64Of(content.bytes) },
143
+ };
144
+ },
145
+ };
146
+ const read = {
147
+ name: READ_TOOL,
148
+ toolClass: ATTACHMENT_TOOL_CLASS,
149
+ kind: 'backend',
150
+ effect: 'view',
151
+ description: 'Reads a file the person attached in this conversation, by its id: a page of its text (a PDF’s text too), from `offset`, at most `limit` characters. ' +
152
+ 'The result says how many characters the file has, so read on from where a page ended. The text is given with this result only: read it again in a later turn when you need it.',
153
+ inputSchema: {
154
+ type: 'object',
155
+ properties: {
156
+ id: { type: 'string', description: 'The attachment’s id, from its reference line or attachment_list.' },
157
+ offset: { type: 'integer', minimum: 0, description: 'The first character to read. Default 0.' },
158
+ limit: { type: 'integer', minimum: 1, maximum: READ_CHARS_PER_CALL, description: `How many characters, at most ${READ_CHARS_PER_CALL}. Default ${READ_CHARS_PER_CALL}.` },
159
+ },
160
+ required: ['id'],
161
+ additionalProperties: false,
162
+ sideEffects: false,
163
+ },
164
+ execute: async (input, ctx) => {
165
+ const found = await one(input.id, ctx);
166
+ if ('error' in found)
167
+ return fail(found.error);
168
+ const { ref } = found;
169
+ if (ref.kind === 'image')
170
+ return fail(`${attachmentReferenceLine(ref)} is a picture: look at it with ${VIEW_TOOL}.`);
171
+ if (ref.kind === 'other')
172
+ return fail(`${attachmentReferenceLine(ref)} has no text to read. An action that takes a file can use it by its id.`);
173
+ const offset = typeof input.offset === 'number' ? Math.max(0, Math.floor(input.offset)) : 0;
174
+ const limit = Math.min(typeof input.limit === 'number' ? Math.max(1, Math.floor(input.limit)) : READ_CHARS_PER_CALL, READ_CHARS_PER_CALL);
175
+ const content = await load(ref, ctx, 'text', { range: { offset, limit } });
176
+ if ('failed' in content)
177
+ return fail(content.failed);
178
+ if (!content.ok)
179
+ return fail(unavailable(ref, content, 'read'));
180
+ if (!('text' in content))
181
+ return fail(`${attachmentReferenceLine(ref)} has no text to read.`);
182
+ const text = content.text.slice(0, limit);
183
+ const tokens = textTokens(text.length);
184
+ const over = guard.passes(tokens);
185
+ if (over) {
186
+ guard.refuse({ key: `tool:${ctx.toolCallId ?? ref.id}`, attachmentId: ref.id, kind: 'text', tokens, textChars: text.length });
187
+ return fail(`Not read: ${capReachedReason(over, READ_TOOL)} A smaller page may fit.`);
188
+ }
189
+ guard.add({
190
+ key: `tool:${ctx.toolCallId ?? ref.id}`,
191
+ attachmentId: ref.id,
192
+ kind: ref.kind === 'pdf' ? 'pdf' : 'text',
193
+ tokens,
194
+ textChars: text.length,
195
+ where: { toolCallId: ctx.toolCallId ?? '' },
196
+ leftOutLine: `${attachmentReferenceLine(ref)} The text read from it is not repeated from here on, to keep within the allowance for files. Read it again if needed.`,
197
+ });
198
+ const end = offset + text.length;
199
+ // The text is the model's, with this result, and nothing else's (ADR-0252 §2.15): what is
200
+ // emitted, recorded and stored says which characters were read, never what they say.
201
+ return {
202
+ success: true,
203
+ data: {
204
+ attachment: attachmentReferenceLine(ref),
205
+ offset,
206
+ chars: text.length,
207
+ totalChars: content.totalChars,
208
+ ...(end < content.totalChars ? { next: end } : { end: true }),
209
+ },
210
+ modelText: textBlock(ref, text, text.length),
211
+ };
212
+ },
213
+ };
214
+ return [list, view, read];
215
+ }
216
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/attachments/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAsB,MAAM,qBAAqB,CAAC;AAIlG,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9F,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE5F,+EAA+E;AAC/E,MAAM,CAAC,MAAM,qBAAqB,GAAG,YAAY,CAAC;AAElD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAU,CAAC;AAE3E,MAAM,IAAI,GAAG,CAAC,KAAa,EAAuB,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;AAEjF,SAAS,QAAQ,CAAC,KAAiB;IACjC,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC1F,CAAC;AAED,4FAA4F;AAC5F,SAAS,UAAU,CAAC,GAAyB,EAAE,GAAY;IACzD,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IAC7D,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC;IACnG,OAAO,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,oCAAoC,CAAC,CAAC,CAAC,GAAG,IAAI,uDAAuD,CAAC;AAChI,CAAC;AAED,MAAM,aAAa,GAAG,8EAA8E,CAAC;AAErG,MAAM,UAAU,eAAe,CAAC,OAAmF;IACjH,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAExC,MAAM,GAAG,GAAG,KAAK,EAAE,EAAW,EAAE,GAAyB,EAAuD,EAAE;QAChH,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;YAAE,OAAO,EAAE,KAAK,EAAE,qEAAqE,EAAE,CAAC;QACjH,IAAI,GAA8B,CAAC;QACnC,IAAI,CAAC;YACH,CAAC,GAAG,CAAC,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QACzE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;QAC1C,CAAC;QACD,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,CAAC;QACxE,IAAI,GAAG,CAAC,OAAO;YAAE,OAAO,EAAE,KAAK,EAAE,GAAG,uBAAuB,CAAC,GAAG,CAAC,qCAAqC,EAAE,CAAC;QACxG,IAAI,GAAG,CAAC,OAAO;YAAE,OAAO,EAAE,KAAK,EAAE,GAAG,uBAAuB,CAAC,GAAG,CAAC,IAAI,aAAa,EAAE,EAAE,CAAC;QACtF,OAAO,EAAE,GAAG,EAAE,CAAC;IACjB,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,KAAK,EAAE,GAAkB,EAAE,GAAyB,EAAE,GAAG,IAAuF,EAAE,EAAE;QAC/J,IAAI,CAAC;YACH,OAAO,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QAC3F,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;QAC1C,CAAC;IACH,CAAC,CAAC;IACF,MAAM,WAAW,GAAG,CAAC,GAAkB,EAAE,OAAkD,EAAE,KAAa,EAAE,EAAE,CAC5G,OAAO,CAAC,MAAM,KAAK,SAAS;QAC1B,CAAC,CAAC,GAAG,uBAAuB,CAAC,GAAG,CAAC,IAAI,aAAa,EAAE;QACpD,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,IAAI,GAAG,uBAAuB,CAAC,GAAG,CAAC,cAAc,KAAK,WAAW,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;IAE1G,MAAM,IAAI,GAAmB;QAC3B,IAAI,EAAE,SAAS;QACf,SAAS,EAAE,qBAAqB;QAChC,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,MAAM;QACd,WAAW,EACT,qKAAqK;YACrK,oEAAoE,SAAS,OAAO,SAAS,8DAA8D;QAC7J,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,oBAAoB,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE;QAChG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;YAC7B,IAAI,KAAsB,CAAC;YAC3B,IAAI,CAAC;gBACH,KAAK,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;YAC/D,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,0BAA0B,CAAC,CAAC,CAAC;YACrF,CAAC;YACD,+EAA+E;YAC/E,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE;oBACJ,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;wBACzB,EAAE,EAAE,GAAG,CAAC,EAAE;wBACV,IAAI,EAAE,GAAG,CAAC,IAAI;wBACd,IAAI,EAAE,uBAAuB,CAAC,GAAG,CAAC;wBAClC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBACzC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qBAC1C,CAAC,CAAC;oBACH,KAAK,EAAE,KAAK,CAAC,MAAM;iBACpB;aACF,CAAC;QACJ,CAAC;KACF,CAAC;IAEF,MAAM,IAAI,GAAmB;QAC3B,IAAI,EAAE,SAAS;QACf,SAAS,EAAE,qBAAqB;QAChC,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,MAAM;QACd,WAAW,EACT,sLAAsL;QACxL,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kEAAkE,EAAE,EAAE;YACvH,QAAQ,EAAE,CAAC,IAAI,CAAC;YAChB,oBAAoB,EAAE,KAAK;YAC3B,WAAW,EAAE,KAAK;SACnB;QACD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YAC5B,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;YACvC,IAAI,OAAO,IAAI,KAAK;gBAAE,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC/C,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;YACtB,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;gBAAE,OAAO,IAAI,CAAC,GAAG,uBAAuB,CAAC,GAAG,CAAC,mCAAmC,SAAS,GAAG,CAAC,CAAC;YACtH,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;YAClD,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAClC,IAAI,IAAI,EAAE,CAAC;gBACT,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,QAAQ,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,EAAE,EAAE,EAAE,YAAY,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;gBACvG,OAAO,IAAI,CAAC,cAAc,gBAAgB,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC;YACjE,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;YAC9C,IAAI,QAAQ,IAAI,OAAO;gBAAE,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YACrD,IAAI,CAAC,OAAO,CAAC,EAAE;gBAAE,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;YACjE,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC;gBAAE,OAAO,IAAI,CAAC,GAAG,uBAAuB,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;YAClG,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAC/E,IAAI,OAAO;gBAAE,OAAO,IAAI,CAAC,GAAG,uBAAuB,CAAC,GAAG,CAAC,qBAAqB,OAAO,GAAG,CAAC,CAAC;YACzF,KAAK,CAAC,GAAG,CAAC;gBACR,GAAG,EAAE,QAAQ,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,EAAE,EAAE;gBACvC,YAAY,EAAE,GAAG,CAAC,EAAE;gBACpB,IAAI,EAAE,OAAO;gBACb,MAAM;gBACN,KAAK,EAAE,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,IAAI,EAAE,EAAE;gBAC3C,WAAW,EAAE,GAAG,uBAAuB,CAAC,GAAG,CAAC,oFAAoF;aACjI,CAAC,CAAC;YACH,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE,EAAE,UAAU,EAAE,uBAAuB,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,qDAAqD,EAAE;gBAChH,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;aACzE,CAAC;QACJ,CAAC;KACF,CAAC;IAEF,MAAM,IAAI,GAAmB;QAC3B,IAAI,EAAE,SAAS;QACf,SAAS,EAAE,qBAAqB;QAChC,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,MAAM;QACd,WAAW,EACT,sJAAsJ;YACtJ,gLAAgL;QAClL,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kEAAkE,EAAE;gBACvG,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,yCAAyC,EAAE;gBAC/F,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,gCAAgC,mBAAmB,aAAa,mBAAmB,GAAG,EAAE;aAC1K;YACD,QAAQ,EAAE,CAAC,IAAI,CAAC;YAChB,oBAAoB,EAAE,KAAK;YAC3B,WAAW,EAAE,KAAK;SACnB;QACD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YAC5B,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;YACvC,IAAI,OAAO,IAAI,KAAK;gBAAE,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC/C,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;YACtB,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;gBAAE,OAAO,IAAI,CAAC,GAAG,uBAAuB,CAAC,GAAG,CAAC,kCAAkC,SAAS,GAAG,CAAC,CAAC;YACrH,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;gBAAE,OAAO,IAAI,CAAC,GAAG,uBAAuB,CAAC,GAAG,CAAC,yEAAyE,CAAC,CAAC;YAChJ,MAAM,MAAM,GAAG,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5F,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,EAAE,mBAAmB,CAAC,CAAC;YAC1I,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;YAC3E,IAAI,QAAQ,IAAI,OAAO;gBAAE,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YACrD,IAAI,CAAC,OAAO,CAAC,EAAE;gBAAE,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;YAChE,IAAI,CAAC,CAAC,MAAM,IAAI,OAAO,CAAC;gBAAE,OAAO,IAAI,CAAC,GAAG,uBAAuB,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;YAC9F,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YAC1C,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACvC,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAClC,IAAI,IAAI,EAAE,CAAC;gBACT,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,QAAQ,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,EAAE,EAAE,EAAE,YAAY,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;gBAC9H,OAAO,IAAI,CAAC,aAAa,gBAAgB,CAAC,IAAI,EAAE,SAAS,CAAC,0BAA0B,CAAC,CAAC;YACxF,CAAC;YACD,KAAK,CAAC,GAAG,CAAC;gBACR,GAAG,EAAE,QAAQ,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,EAAE,EAAE;gBACvC,YAAY,EAAE,GAAG,CAAC,EAAE;gBACpB,IAAI,EAAE,GAAG,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM;gBACzC,MAAM;gBACN,SAAS,EAAE,IAAI,CAAC,MAAM;gBACtB,KAAK,EAAE,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,IAAI,EAAE,EAAE;gBAC3C,WAAW,EAAE,GAAG,uBAAuB,CAAC,GAAG,CAAC,uHAAuH;aACpK,CAAC,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;YACjC,0FAA0F;YAC1F,qFAAqF;YACrF,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE;oBACJ,UAAU,EAAE,uBAAuB,CAAC,GAAG,CAAC;oBACxC,MAAM;oBACN,KAAK,EAAE,IAAI,CAAC,MAAM;oBAClB,UAAU,EAAE,OAAO,CAAC,UAAU;oBAC9B,GAAG,CAAC,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;iBAC9D;gBACD,SAAS,EAAE,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;aAC7C,CAAC;QACJ,CAAC;KACF,CAAC;IAEF,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC5B,CAAC"}
@@ -29,6 +29,12 @@ export interface ToolPolicyContext {
29
29
  * Decide by this, not by the name: a UI action id can equal a host tool's.
30
30
  */
31
31
  toolKind: 'ui' | 'backend';
32
+ /**
33
+ * The SDK's class for a tool it owns: `attachment` for the attachment tools
34
+ * (ADR-0252 §2.12). A policy that admits by name should admit the class too,
35
+ * so a tool the SDK adds to it later needs no change.
36
+ */
37
+ toolClass?: 'attachment';
32
38
  /** What the tool declares it does (ADR-0226 §2.6); undefined when it declares nothing, which counts as a write. */
33
39
  effect: ToolEffect | undefined;
34
40
  /** Whether the tool declares it removes or replaces something the person made. */
@@ -1 +1 @@
1
- {"version":3,"file":"tool-policy.d.ts","sourceRoot":"","sources":["../../src/authz/tool-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;;;;;;GAOG;AAEH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAC/D;AAED,MAAM,WAAW,iBAAiB;IAChC,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,cAAc,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,QAAQ,EAAE,IAAI,GAAG,SAAS,CAAC;IAC3B,mHAAmH;IACnH,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;IAC/B,kFAAkF;IAClF,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,GAC1B;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GACnB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,MAAM,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnD;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,UAE/B,CAAC;AAEF;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,kBAAkB,CAAC,CAU7B"}
1
+ {"version":3,"file":"tool-policy.d.ts","sourceRoot":"","sources":["../../src/authz/tool-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;;;;;;GAOG;AAEH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAC/D;AAED,MAAM,WAAW,iBAAiB;IAChC,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,cAAc,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,QAAQ,EAAE,IAAI,GAAG,SAAS,CAAC;IAC3B;;;;OAIG;IACH,SAAS,CAAC,EAAE,YAAY,CAAC;IACzB,mHAAmH;IACnH,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;IAC/B,kFAAkF;IAClF,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,GAC1B;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GACnB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,MAAM,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnD;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,UAE/B,CAAC;AAEF;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,kBAAkB,CAAC,CAU7B"}
@@ -1 +1 @@
1
- {"version":3,"file":"tool-policy.js","sourceRoot":"","sources":["../../src/authz/tool-policy.ts"],"names":[],"mappings":"AAqDA;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAe;IAC3C,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,OAAgB,EAAE,CAAC;CACrD,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,MAAkB,EAClB,GAAsB;IAEtB,IAAI,CAAC;QACH,OAAO,MAAM,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC;QAChF,OAAO;YACL,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,2CAA2C,OAAO,EAAE;SAC7D,CAAC;IACJ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"tool-policy.js","sourceRoot":"","sources":["../../src/authz/tool-policy.ts"],"names":[],"mappings":"AA2DA;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAe;IAC3C,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,OAAgB,EAAE,CAAC;CACrD,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,MAAkB,EAClB,GAAsB;IAEtB,IAAI,CAAC;QACH,OAAO,MAAM,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC;QAChF,OAAO;YACL,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,2CAA2C,OAAO,EAAE;SAC7D,CAAC;IACJ,CAAC;AACH,CAAC"}
package/dist/index.d.ts CHANGED
@@ -34,6 +34,11 @@ export { buildApprovalPreview } from './approvals/preview.js';
34
34
  export { createHttpTurnStopClient, watchTurnStop, stopOf, TurnStopped, DEFAULT_STOP_GRACE_MS } from './stop/turn-stop.js';
35
35
  export type { TurnStopClient, HttpTurnStopClientConfig, TurnStopWatch, TurnStopState } from './stop/turn-stop.js';
36
36
  export { stoppedTurnMessages } from './stop/partial.js';
37
+ export type { AttachmentStore, AttachmentStoreCallOptions, AttachmentOwner, AttachmentLoadAs, AttachmentContent, AttachmentWorkerConfig } from './attachments/store.js';
38
+ export { AttachmentGuard, type AttachmentUsage, type GuardedPart, type AttachmentCap } from './attachments/guard.js';
39
+ export { attachmentTools, ATTACHMENT_TOOLS, ATTACHMENT_TOOL_CLASS } from './attachments/tools.js';
40
+ export { VIEW_TOOL as ATTACHMENT_VIEW_TOOL, READ_TOOL as ATTACHMENT_READ_TOOL, LIST_TOOL as ATTACHMENT_LIST_TOOL, ATTACHMENT_DATA_NOTE, escapeAttachmentText, } from './attachments/content.js';
41
+ export * as attachmentLimits from './attachments/limits.js';
37
42
  export type { RecordedStep, RecordedCall } from './stop/partial.js';
38
43
  export type { UIActionChannel, HttpUIActionChannelConfig } from './ui/channel.js';
39
44
  export { createHttpUIActionChannel } from './ui/channel.js';
@@ -50,11 +55,11 @@ export type { AgentApiSurface, EntityInstance, EntityFilter, EntityMutation, Int
50
55
  export { runAgentTurn } from './orchestrator.js';
51
56
  export { PROMPT_CACHE_BREAKPOINTS, describeModel } from './model.js';
52
57
  export type { LanguageModel, ProviderOptions } from './model.js';
53
- export type { TurnPolicy } from './turn-policy.js';
58
+ export type { TurnPolicy, StepTool } from './turn-policy.js';
54
59
  export { defaultTurnPolicy } from './turn-policy.js';
55
60
  export { createHttpEmitAdapter } from './emit/http-adapter.js';
56
61
  export type { HttpEmitAdapterConfig } from './emit/http-adapter.js';
57
- export { createAgentTurnRunner, categorizeError, payloadRefusal } from './runtime/turn-runner.js';
62
+ export { createAgentTurnRunner, categorizeError, payloadRefusal, TURN_DEADLINE_EXCEEDED } from './runtime/turn-runner.js';
58
63
  export type { AgentTurnRunner, TurnOutcome, CategorizedError } from './runtime/turn-runner.js';
59
64
  export { assertAgentRuntimeConfig } from './runtime/config.js';
60
65
  export type { AgentRuntimeConfig, LambdaAgentConfig, AgentTurnPayload, HistoryRequest } from './runtime/types.js';