agentfootprint 9.24.0 → 9.25.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 (115) hide show
  1. package/README.md +3 -1
  2. package/dist/artifacts/fileArtifacts.js +144 -17
  3. package/dist/artifacts/fileArtifacts.js.map +1 -1
  4. package/dist/artifacts/gcsArtifacts.js +398 -0
  5. package/dist/artifacts/gcsArtifacts.js.map +1 -0
  6. package/dist/artifacts/index.js +12 -1
  7. package/dist/artifacts/index.js.map +1 -1
  8. package/dist/artifacts/objectStore.js +264 -0
  9. package/dist/artifacts/objectStore.js.map +1 -0
  10. package/dist/artifacts/payload.js +41 -2
  11. package/dist/artifacts/payload.js.map +1 -1
  12. package/dist/artifacts/s3Artifacts.js +542 -0
  13. package/dist/artifacts/s3Artifacts.js.map +1 -0
  14. package/dist/artifacts/scopePath.js +87 -0
  15. package/dist/artifacts/scopePath.js.map +1 -0
  16. package/dist/artifacts/streaming.js +132 -0
  17. package/dist/artifacts/streaming.js.map +1 -0
  18. package/dist/artifacts/types.js +10 -2
  19. package/dist/artifacts/types.js.map +1 -1
  20. package/dist/core/agent/AgentBuilder.js +20 -0
  21. package/dist/core/agent/AgentBuilder.js.map +1 -1
  22. package/dist/esm/artifacts/fileArtifacts.d.ts +13 -1
  23. package/dist/esm/artifacts/fileArtifacts.js +145 -18
  24. package/dist/esm/artifacts/fileArtifacts.js.map +1 -1
  25. package/dist/esm/artifacts/gcsArtifacts.d.ts +142 -0
  26. package/dist/esm/artifacts/gcsArtifacts.js +394 -0
  27. package/dist/esm/artifacts/gcsArtifacts.js.map +1 -0
  28. package/dist/esm/artifacts/index.d.ts +4 -1
  29. package/dist/esm/artifacts/index.js +3 -0
  30. package/dist/esm/artifacts/index.js.map +1 -1
  31. package/dist/esm/artifacts/objectStore.d.ts +166 -0
  32. package/dist/esm/artifacts/objectStore.js +252 -0
  33. package/dist/esm/artifacts/objectStore.js.map +1 -0
  34. package/dist/esm/artifacts/payload.d.ts +36 -4
  35. package/dist/esm/artifacts/payload.js +38 -1
  36. package/dist/esm/artifacts/payload.js.map +1 -1
  37. package/dist/esm/artifacts/s3Artifacts.d.ts +149 -0
  38. package/dist/esm/artifacts/s3Artifacts.js +538 -0
  39. package/dist/esm/artifacts/s3Artifacts.js.map +1 -0
  40. package/dist/esm/artifacts/scopePath.d.ts +50 -0
  41. package/dist/esm/artifacts/scopePath.js +80 -0
  42. package/dist/esm/artifacts/scopePath.js.map +1 -0
  43. package/dist/esm/artifacts/streaming.d.ts +82 -0
  44. package/dist/esm/artifacts/streaming.js +123 -0
  45. package/dist/esm/artifacts/streaming.js.map +1 -0
  46. package/dist/esm/artifacts/types.d.ts +71 -5
  47. package/dist/esm/artifacts/types.js +10 -2
  48. package/dist/esm/artifacts/types.js.map +1 -1
  49. package/dist/esm/core/agent/AgentBuilder.js +20 -0
  50. package/dist/esm/core/agent/AgentBuilder.js.map +1 -1
  51. package/dist/esm/index.d.ts +2 -1
  52. package/dist/esm/index.js +6 -1
  53. package/dist/esm/index.js.map +1 -1
  54. package/dist/esm/lib/injection-engine/factories/defineSkill.d.ts +27 -0
  55. package/dist/esm/lib/injection-engine/factories/defineSkill.js +13 -0
  56. package/dist/esm/lib/injection-engine/factories/defineSkill.js.map +1 -1
  57. package/dist/esm/lib/injection-engine/index.d.ts +1 -0
  58. package/dist/esm/lib/injection-engine/index.js +7 -0
  59. package/dist/esm/lib/injection-engine/index.js.map +1 -1
  60. package/dist/esm/lib/injection-engine/skillGraph.js +9 -1
  61. package/dist/esm/lib/injection-engine/skillGraph.js.map +1 -1
  62. package/dist/esm/lib/injection-engine/skillGraphCheckup.d.ts +1 -1
  63. package/dist/esm/lib/injection-engine/skillGraphCheckup.js.map +1 -1
  64. package/dist/esm/lib/injection-engine/skillSteps.d.ts +16 -0
  65. package/dist/esm/lib/injection-engine/skillSteps.js +5 -0
  66. package/dist/esm/lib/injection-engine/skillSteps.js.map +1 -1
  67. package/dist/esm/lib/injection-engine/skillVocabulary.d.ts +83 -0
  68. package/dist/esm/lib/injection-engine/skillVocabulary.js +218 -0
  69. package/dist/esm/lib/injection-engine/skillVocabulary.js.map +1 -0
  70. package/dist/index.js +23 -13
  71. package/dist/index.js.map +1 -1
  72. package/dist/lib/injection-engine/factories/defineSkill.js +13 -0
  73. package/dist/lib/injection-engine/factories/defineSkill.js.map +1 -1
  74. package/dist/lib/injection-engine/index.js +10 -1
  75. package/dist/lib/injection-engine/index.js.map +1 -1
  76. package/dist/lib/injection-engine/skillGraph.js +9 -1
  77. package/dist/lib/injection-engine/skillGraph.js.map +1 -1
  78. package/dist/lib/injection-engine/skillGraphCheckup.js.map +1 -1
  79. package/dist/lib/injection-engine/skillSteps.js +5 -0
  80. package/dist/lib/injection-engine/skillSteps.js.map +1 -1
  81. package/dist/lib/injection-engine/skillVocabulary.js +224 -0
  82. package/dist/lib/injection-engine/skillVocabulary.js.map +1 -0
  83. package/dist/types/artifacts/fileArtifacts.d.ts +13 -1
  84. package/dist/types/artifacts/fileArtifacts.d.ts.map +1 -1
  85. package/dist/types/artifacts/gcsArtifacts.d.ts +143 -0
  86. package/dist/types/artifacts/gcsArtifacts.d.ts.map +1 -0
  87. package/dist/types/artifacts/index.d.ts +4 -1
  88. package/dist/types/artifacts/index.d.ts.map +1 -1
  89. package/dist/types/artifacts/objectStore.d.ts +167 -0
  90. package/dist/types/artifacts/objectStore.d.ts.map +1 -0
  91. package/dist/types/artifacts/payload.d.ts +36 -4
  92. package/dist/types/artifacts/payload.d.ts.map +1 -1
  93. package/dist/types/artifacts/s3Artifacts.d.ts +150 -0
  94. package/dist/types/artifacts/s3Artifacts.d.ts.map +1 -0
  95. package/dist/types/artifacts/scopePath.d.ts +51 -0
  96. package/dist/types/artifacts/scopePath.d.ts.map +1 -0
  97. package/dist/types/artifacts/streaming.d.ts +83 -0
  98. package/dist/types/artifacts/streaming.d.ts.map +1 -0
  99. package/dist/types/artifacts/types.d.ts +71 -5
  100. package/dist/types/artifacts/types.d.ts.map +1 -1
  101. package/dist/types/core/agent/AgentBuilder.d.ts.map +1 -1
  102. package/dist/types/index.d.ts +2 -1
  103. package/dist/types/index.d.ts.map +1 -1
  104. package/dist/types/lib/injection-engine/factories/defineSkill.d.ts +27 -0
  105. package/dist/types/lib/injection-engine/factories/defineSkill.d.ts.map +1 -1
  106. package/dist/types/lib/injection-engine/index.d.ts +1 -0
  107. package/dist/types/lib/injection-engine/index.d.ts.map +1 -1
  108. package/dist/types/lib/injection-engine/skillGraph.d.ts.map +1 -1
  109. package/dist/types/lib/injection-engine/skillGraphCheckup.d.ts +1 -1
  110. package/dist/types/lib/injection-engine/skillGraphCheckup.d.ts.map +1 -1
  111. package/dist/types/lib/injection-engine/skillSteps.d.ts +16 -0
  112. package/dist/types/lib/injection-engine/skillSteps.d.ts.map +1 -1
  113. package/dist/types/lib/injection-engine/skillVocabulary.d.ts +84 -0
  114. package/dist/types/lib/injection-engine/skillVocabulary.d.ts.map +1 -0
  115. package/package.json +10 -1
@@ -0,0 +1,166 @@
1
+ /**
2
+ * artifacts/objectStore — the half every REMOTE OBJECT adapter shares.
3
+ *
4
+ * Two adapters put artifacts in somebody else's bucket. They speak different
5
+ * SDKs and dispatch different operations, and that is exactly where a vendor
6
+ * belongs — but the laws they follow must not fork, so the laws live here:
7
+ *
8
+ * 1. **The payload is the object body, and it is the CANONICAL BYTES** —
9
+ * the same bytes `meta.bytes` counts and a digest covers. Not a JSON
10
+ * envelope wrapping base64: a stored report should be downloadable with
11
+ * the vendor's own console and be the report. That choice is also what
12
+ * makes `getStream` possible at all — a body you have to parse is a body
13
+ * you cannot stream.
14
+ * 2. **The meta rides as ONE object-metadata entry** ({@link ARTIFACT_META_KEY}),
15
+ * an ASCII-safe JSON envelope. One key, one truth: a "helpful" second
16
+ * copy of `kind` in a sibling field is a second thing that can disagree.
17
+ * ASCII because user metadata travels as an HTTP header on at least one
18
+ * of these services — a label with an em-dash in it must not be
19
+ * mangled at the transport — and JSON-with-escapes rather than base64
20
+ * because an operator reading the console should be able to SEE what the
21
+ * ticket says.
22
+ * 3. **The metadata budget is checked at put and REFUSED by name.** Both
23
+ * services cap user metadata (the caps differ; each adapter states its
24
+ * own). A refusal that names the field to shorten beats a vendor's
25
+ * "MetadataTooLarge" at document 400, and beats silent truncation
26
+ * always.
27
+ * 4. **Missing means null; unreadable means an error.** A 404 is the
28
+ * port's deliberate "no data" ambiguity — but only when the call ASKED
29
+ * ABOUT ONE OBJECT. A write and a listing do not ask that question, so a
30
+ * 404 from one of them is the service saying something else entirely (the
31
+ * bucket does not exist, the endpoint is wrong); nobody downstream turns
32
+ * it into `null`, so letting it past the sanitizer hands the caller the
33
+ * SDK's own text — which contains the object key. That is what
34
+ * {@link NotFoundMeaning} makes each call site declare, and why the
35
+ * default is the safe one. Anything else — denied, throttled, a network
36
+ * failure — is NOT "no data" either, and answering `null` for it would
37
+ * report an empty scope over objects that exist. Each adapter maps its
38
+ * own SDK's missing-object shape; everything else raises through
39
+ * {@link objectSdkFailure}.
40
+ * 5. **Listings order by the SERVICE's own creation time**, which comes back
41
+ * free on a listing, and page by offset over that sorted list. The port
42
+ * promises newest-first ACROSS pages; a bucket's key order is
43
+ * lexicographic, so a cursor that was the service's own continuation
44
+ * token would page in the wrong order and call it paging.
45
+ *
46
+ * Nothing in this file imports an SDK, names a vendor, or knows a wire
47
+ * format. It is the part of an object adapter that can be unit-tested with
48
+ * nothing but strings.
49
+ */
50
+ import type { PayloadShape } from './payload.js';
51
+ import { type ArtifactListOptions, type ArtifactListResult, type ArtifactMeta } from './types.js';
52
+ /** The single object-metadata key that carries the ticket. */
53
+ export declare const ARTIFACT_META_KEY = "af-artifact";
54
+ /**
55
+ * Encode a ticket for the object's metadata, refusing one that will not fit.
56
+ *
57
+ * @param meta the minted ticket.
58
+ * @param shape how the payload must be rebuilt from the body's bytes.
59
+ * @param budget the service's user-metadata cap, in bytes.
60
+ * @param adapter the factory name, for the refusal.
61
+ * @throws InvalidArtifactError when the encoded ticket exceeds the budget —
62
+ * naming the fields that are big enough to be the reason.
63
+ */
64
+ export declare function encodeArtifactMetaValue(meta: ArtifactMeta, shape: PayloadShape, budget: number, adapter: string): string;
65
+ /**
66
+ * Read a ticket back off an object's metadata.
67
+ *
68
+ * `undefined` for anything this runtime must not interpret: no entry (not
69
+ * ours — a foreign object in a shared bucket is left alone), unparseable, a
70
+ * newer envelope version, or a ref that is not a minted ref. Refusing to
71
+ * interpret is the point: a half-read ticket would be a confident description
72
+ * of the wrong thing.
73
+ */
74
+ export declare function decodeArtifactMetaValue(value: unknown): {
75
+ readonly meta: ArtifactMeta;
76
+ readonly shape: PayloadShape;
77
+ } | undefined;
78
+ /** Case-insensitive lookup in a metadata bag. At least one of these services
79
+ * lower-cases user-metadata keys in transit, so the key written and the key
80
+ * read back are not guaranteed to be the same string. */
81
+ export declare function readMetadataEntry(bag: Record<string, unknown> | undefined, key: string): unknown;
82
+ /** Has the calendar passed this ticket? The one expiry predicate both object
83
+ * adapters use, so "expired" cannot mean two things. */
84
+ export declare function isExpiredMeta(meta: ArtifactMeta, now: number): boolean;
85
+ /**
86
+ * Re-raise a failed SDK call WITHOUT its text (the `sdkFailure` law, applied
87
+ * to object storage).
88
+ *
89
+ * A cloud SDK reports transport and validation failures by echoing request
90
+ * detail into the message: the bucket, the KEY — which here contains the
91
+ * tenant, the principal and the conversation id — and sometimes a signed URL
92
+ * or a header the request carried. This library then hands that string to the
93
+ * LLM as a tool result, puts it on the commit log, and ships it to every sink
94
+ * attached. One echo and the scope tuple is in the conversation.
95
+ *
96
+ * So the text does not come through. What does is the part that is both safe
97
+ * and actionable: which operation failed, the exception's NAME, and the HTTP
98
+ * status. The original is deliberately NOT attached as `cause` — a cause
99
+ * travels into every serializer that walks own properties, which would undo
100
+ * all of this in one `JSON.stringify`.
101
+ */
102
+ export declare function objectSdkFailure(adapter: string, operation: string, err: unknown): Error;
103
+ /**
104
+ * What a "not found" from ONE call is allowed to mean.
105
+ *
106
+ * The distinction is not academic: it decides whether an SDK error object
107
+ * leaves this library intact.
108
+ *
109
+ * • `'missing-object'` — the call named one object and asked whether it is
110
+ * there. Not-found is the port's deliberate "no data", so the SDK's own
111
+ * error travels back to the CALL SITE, which immediately converts it to
112
+ * `null`/`undefined`. It never leaves the adapter, so its text never reaches
113
+ * an event, a log, or a model.
114
+ *
115
+ * • `'not-an-answer'` — the call asked no such question (it wrote, or it
116
+ * listed). A not-found here means something the caller did not ask about is
117
+ * wrong — most often that the bucket itself is not there — and NOTHING
118
+ * downstream is waiting to convert it. It goes through
119
+ * {@link objectSdkFailure} like every other failure.
120
+ *
121
+ * This is the DEFAULT for exactly that reason: a call site that says nothing
122
+ * gets the sanitizer. Leaking has to be typed out on purpose, next to the
123
+ * `catch` that proves the error is caught.
124
+ */
125
+ export type NotFoundMeaning = 'missing-object' | 'not-an-answer';
126
+ /**
127
+ * The one gate every object adapter runs its SDK failures through.
128
+ *
129
+ * Returns what to throw — the sanitized error for anything the caller is not
130
+ * standing by to interpret, the original ONLY for a genuine missing object at
131
+ * a call site that declared it asks about one, and our own refusals verbatim
132
+ * (an {@link InvalidArtifactError} is this library's sentence, already written
133
+ * for a human, and re-wrapping it would replace a teaching refusal with a
134
+ * transport complaint).
135
+ *
136
+ * Built once per adapter so the vendor's not-found detection is bound in one
137
+ * place: two call sites in the same adapter cannot end up disagreeing about
138
+ * what "missing" looks like.
139
+ *
140
+ * @param adapter the factory name, for the message.
141
+ * @param isMissingObject the adapter's own reading of its SDK's
142
+ * "no such object" — the one genuinely per-vendor part.
143
+ */
144
+ export declare function objectFailurePolicy(adapter: string, isMissingObject: (err: unknown) => boolean): (operation: string, err: unknown, meaning: NotFoundMeaning) => unknown;
145
+ /** One row of a scope listing, before the tickets are paged. */
146
+ export interface ObjectListingRow {
147
+ readonly meta: ArtifactMeta;
148
+ /** The service's own creation time for the object (ms). The sort key —
149
+ * see law 5 in the module header. */
150
+ readonly serviceCreatedAt: number;
151
+ }
152
+ /**
153
+ * The port's paging law over a scope's rows: newest first, offset cursor.
154
+ *
155
+ * Sorted by the SERVICE's creation time (falling back to the ticket's own
156
+ * `createdAt` when a listing did not carry one), ties broken by ref so two
157
+ * objects written in the same millisecond still page deterministically.
158
+ */
159
+ export declare function pageObjectListing(rows: readonly ObjectListingRow[], options: ArtifactListOptions | undefined): ArtifactListResult;
160
+ /** The offset a cursor names. Total: a cursor this store did not mint reads
161
+ * as "start at the beginning" rather than as an error — a caller cannot
162
+ * learn anything about another scope by guessing one. */
163
+ export declare function decodeOffsetCursor(cursor: string | undefined): number;
164
+ /** Validate a bucket name option at construction — the same shape of refusal
165
+ * every adapter here gives for a missing required option. */
166
+ export declare function assertBucketOption(adapter: string, option: string, value: unknown): string;
@@ -0,0 +1,252 @@
1
+ /**
2
+ * artifacts/objectStore — the half every REMOTE OBJECT adapter shares.
3
+ *
4
+ * Two adapters put artifacts in somebody else's bucket. They speak different
5
+ * SDKs and dispatch different operations, and that is exactly where a vendor
6
+ * belongs — but the laws they follow must not fork, so the laws live here:
7
+ *
8
+ * 1. **The payload is the object body, and it is the CANONICAL BYTES** —
9
+ * the same bytes `meta.bytes` counts and a digest covers. Not a JSON
10
+ * envelope wrapping base64: a stored report should be downloadable with
11
+ * the vendor's own console and be the report. That choice is also what
12
+ * makes `getStream` possible at all — a body you have to parse is a body
13
+ * you cannot stream.
14
+ * 2. **The meta rides as ONE object-metadata entry** ({@link ARTIFACT_META_KEY}),
15
+ * an ASCII-safe JSON envelope. One key, one truth: a "helpful" second
16
+ * copy of `kind` in a sibling field is a second thing that can disagree.
17
+ * ASCII because user metadata travels as an HTTP header on at least one
18
+ * of these services — a label with an em-dash in it must not be
19
+ * mangled at the transport — and JSON-with-escapes rather than base64
20
+ * because an operator reading the console should be able to SEE what the
21
+ * ticket says.
22
+ * 3. **The metadata budget is checked at put and REFUSED by name.** Both
23
+ * services cap user metadata (the caps differ; each adapter states its
24
+ * own). A refusal that names the field to shorten beats a vendor's
25
+ * "MetadataTooLarge" at document 400, and beats silent truncation
26
+ * always.
27
+ * 4. **Missing means null; unreadable means an error.** A 404 is the
28
+ * port's deliberate "no data" ambiguity — but only when the call ASKED
29
+ * ABOUT ONE OBJECT. A write and a listing do not ask that question, so a
30
+ * 404 from one of them is the service saying something else entirely (the
31
+ * bucket does not exist, the endpoint is wrong); nobody downstream turns
32
+ * it into `null`, so letting it past the sanitizer hands the caller the
33
+ * SDK's own text — which contains the object key. That is what
34
+ * {@link NotFoundMeaning} makes each call site declare, and why the
35
+ * default is the safe one. Anything else — denied, throttled, a network
36
+ * failure — is NOT "no data" either, and answering `null` for it would
37
+ * report an empty scope over objects that exist. Each adapter maps its
38
+ * own SDK's missing-object shape; everything else raises through
39
+ * {@link objectSdkFailure}.
40
+ * 5. **Listings order by the SERVICE's own creation time**, which comes back
41
+ * free on a listing, and page by offset over that sorted list. The port
42
+ * promises newest-first ACROSS pages; a bucket's key order is
43
+ * lexicographic, so a cursor that was the service's own continuation
44
+ * token would page in the wrong order and call it paging.
45
+ *
46
+ * Nothing in this file imports an SDK, names a vendor, or knows a wire
47
+ * format. It is the part of an object adapter that can be unit-tested with
48
+ * nothing but strings.
49
+ */
50
+ import { isArtifactRef } from './naming.js';
51
+ import { InvalidArtifactError, } from './types.js';
52
+ /** The single object-metadata key that carries the ticket. */
53
+ export const ARTIFACT_META_KEY = 'af-artifact';
54
+ /** Envelope version. Bumped only for a change an older reader could not
55
+ * survive; a newer number is refused, never half-read. */
56
+ const META_FORMAT = 1;
57
+ /**
58
+ * Every non-ASCII character as a `\uXXXX` escape, so the JSON is pure ASCII
59
+ * and survives a transport that only promises US-ASCII. `JSON.parse` reverses
60
+ * it exactly — the escape is part of JSON, not a private encoding.
61
+ */
62
+ function asciiJson(value) {
63
+ return JSON.stringify(value).replace(/[\u007f-\uffff]/g, (char) => {
64
+ const code = char.charCodeAt(0).toString(16).padStart(4, '0');
65
+ return `\\u${code}`;
66
+ });
67
+ }
68
+ /**
69
+ * Encode a ticket for the object's metadata, refusing one that will not fit.
70
+ *
71
+ * @param meta the minted ticket.
72
+ * @param shape how the payload must be rebuilt from the body's bytes.
73
+ * @param budget the service's user-metadata cap, in bytes.
74
+ * @param adapter the factory name, for the refusal.
75
+ * @throws InvalidArtifactError when the encoded ticket exceeds the budget —
76
+ * naming the fields that are big enough to be the reason.
77
+ */
78
+ export function encodeArtifactMetaValue(meta, shape, budget, adapter) {
79
+ const envelope = { v: META_FORMAT, shape, meta };
80
+ const value = asciiJson(envelope);
81
+ // The key travels with the value; both count against the service's cap.
82
+ const size = ARTIFACT_META_KEY.length + value.length;
83
+ if (size > budget) {
84
+ const suspects = [];
85
+ if (meta.label !== undefined && meta.label.length > 64) {
86
+ suspects.push(`label (${meta.label.length} chars)`);
87
+ }
88
+ if (meta.parentRefs !== undefined && meta.parentRefs.length > 4) {
89
+ suspects.push(`parentRefs (${meta.parentRefs.length} refs)`);
90
+ }
91
+ if (meta.kind.length > 64)
92
+ suspects.push(`kind (${meta.kind.length} chars)`);
93
+ throw new InvalidArtifactError(`${adapter}: the ticket does not fit this service's object-metadata budget ` +
94
+ `(${size} bytes encoded, budget ${budget}). The ticket travels AS object metadata, so ` +
95
+ `the payload size is irrelevant here — the description is what is too long` +
96
+ (suspects.length > 0 ? `; the length is in ${suspects.join(' and ')}` : '') +
97
+ `. Shorten the label, carry fewer parentRefs, or move the long prose into the payload ` +
98
+ `where size is what this store is for.`);
99
+ }
100
+ return value;
101
+ }
102
+ /**
103
+ * Read a ticket back off an object's metadata.
104
+ *
105
+ * `undefined` for anything this runtime must not interpret: no entry (not
106
+ * ours — a foreign object in a shared bucket is left alone), unparseable, a
107
+ * newer envelope version, or a ref that is not a minted ref. Refusing to
108
+ * interpret is the point: a half-read ticket would be a confident description
109
+ * of the wrong thing.
110
+ */
111
+ export function decodeArtifactMetaValue(value) {
112
+ if (typeof value !== 'string' || value === '')
113
+ return undefined;
114
+ let parsed;
115
+ try {
116
+ parsed = JSON.parse(value);
117
+ }
118
+ catch {
119
+ return undefined;
120
+ }
121
+ const envelope = parsed;
122
+ if (envelope === null || typeof envelope !== 'object')
123
+ return undefined;
124
+ if (typeof envelope.v !== 'number' || envelope.v > META_FORMAT)
125
+ return undefined;
126
+ const meta = envelope.meta;
127
+ if (meta === undefined || !isArtifactRef(meta.ref))
128
+ return undefined;
129
+ const shape = envelope.shape;
130
+ if (shape !== 'text' && shape !== 'binary' && shape !== 'json')
131
+ return undefined;
132
+ return { meta: meta, shape };
133
+ }
134
+ /** Case-insensitive lookup in a metadata bag. At least one of these services
135
+ * lower-cases user-metadata keys in transit, so the key written and the key
136
+ * read back are not guaranteed to be the same string. */
137
+ export function readMetadataEntry(bag, key) {
138
+ if (bag === undefined || bag === null)
139
+ return undefined;
140
+ const direct = bag[key];
141
+ if (direct !== undefined)
142
+ return direct;
143
+ const wanted = key.toLowerCase();
144
+ for (const [name, value] of Object.entries(bag)) {
145
+ if (name.toLowerCase() === wanted)
146
+ return value;
147
+ }
148
+ return undefined;
149
+ }
150
+ /** Has the calendar passed this ticket? The one expiry predicate both object
151
+ * adapters use, so "expired" cannot mean two things. */
152
+ export function isExpiredMeta(meta, now) {
153
+ return meta.expiresAt !== undefined && meta.expiresAt <= now;
154
+ }
155
+ /**
156
+ * Re-raise a failed SDK call WITHOUT its text (the `sdkFailure` law, applied
157
+ * to object storage).
158
+ *
159
+ * A cloud SDK reports transport and validation failures by echoing request
160
+ * detail into the message: the bucket, the KEY — which here contains the
161
+ * tenant, the principal and the conversation id — and sometimes a signed URL
162
+ * or a header the request carried. This library then hands that string to the
163
+ * LLM as a tool result, puts it on the commit log, and ships it to every sink
164
+ * attached. One echo and the scope tuple is in the conversation.
165
+ *
166
+ * So the text does not come through. What does is the part that is both safe
167
+ * and actionable: which operation failed, the exception's NAME, and the HTTP
168
+ * status. The original is deliberately NOT attached as `cause` — a cause
169
+ * travels into every serializer that walks own properties, which would undo
170
+ * all of this in one `JSON.stringify`.
171
+ */
172
+ export function objectSdkFailure(adapter, operation, err) {
173
+ const e = err;
174
+ const name = typeof e?.name === 'string' && e.name.length > 0 ? e.name : 'an unnamed failure';
175
+ const status = typeof e?.$metadata?.httpStatusCode === 'number'
176
+ ? e.$metadata.httpStatusCode
177
+ : typeof e?.code === 'number'
178
+ ? e.code
179
+ : undefined;
180
+ return new Error(`[artifacts] ${adapter}: ${operation} failed — ${name}` +
181
+ (status !== undefined ? ` (HTTP ${status})` : '') +
182
+ `.\n The SDK's own message is withheld: object-storage errors echo the bucket and the ` +
183
+ `object KEY, and the key carries this run's tenant/principal/conversation. Check the ` +
184
+ `service's own logs for the full exception. This is not "no data" — a missing object ` +
185
+ `answers null; this call did not get an answer at all.`);
186
+ }
187
+ /**
188
+ * The one gate every object adapter runs its SDK failures through.
189
+ *
190
+ * Returns what to throw — the sanitized error for anything the caller is not
191
+ * standing by to interpret, the original ONLY for a genuine missing object at
192
+ * a call site that declared it asks about one, and our own refusals verbatim
193
+ * (an {@link InvalidArtifactError} is this library's sentence, already written
194
+ * for a human, and re-wrapping it would replace a teaching refusal with a
195
+ * transport complaint).
196
+ *
197
+ * Built once per adapter so the vendor's not-found detection is bound in one
198
+ * place: two call sites in the same adapter cannot end up disagreeing about
199
+ * what "missing" looks like.
200
+ *
201
+ * @param adapter the factory name, for the message.
202
+ * @param isMissingObject the adapter's own reading of its SDK's
203
+ * "no such object" — the one genuinely per-vendor part.
204
+ */
205
+ export function objectFailurePolicy(adapter, isMissingObject) {
206
+ return (operation, err, meaning) => {
207
+ if (err instanceof InvalidArtifactError)
208
+ return err;
209
+ if (meaning === 'missing-object' && isMissingObject(err))
210
+ return err;
211
+ return objectSdkFailure(adapter, operation, err);
212
+ };
213
+ }
214
+ /**
215
+ * The port's paging law over a scope's rows: newest first, offset cursor.
216
+ *
217
+ * Sorted by the SERVICE's creation time (falling back to the ticket's own
218
+ * `createdAt` when a listing did not carry one), ties broken by ref so two
219
+ * objects written in the same millisecond still page deterministically.
220
+ */
221
+ export function pageObjectListing(rows, options) {
222
+ const sorted = [...rows].sort((a, b) => b.serviceCreatedAt - a.serviceCreatedAt || (a.meta.ref < b.meta.ref ? -1 : 1));
223
+ const offset = decodeOffsetCursor(options?.cursor);
224
+ const limit = Math.max(1, Math.floor(options?.limit ?? 50));
225
+ const page = sorted.slice(offset, offset + limit);
226
+ const nextOffset = offset + page.length;
227
+ return {
228
+ artifacts: page.map((row) => row.meta),
229
+ ...(nextOffset < sorted.length && { cursor: String(nextOffset) }),
230
+ };
231
+ }
232
+ /** The offset a cursor names. Total: a cursor this store did not mint reads
233
+ * as "start at the beginning" rather than as an error — a caller cannot
234
+ * learn anything about another scope by guessing one. */
235
+ export function decodeOffsetCursor(cursor) {
236
+ if (cursor === undefined)
237
+ return 0;
238
+ const parsed = Number(cursor);
239
+ return Number.isFinite(parsed) && parsed >= 0 ? Math.floor(parsed) : 0;
240
+ }
241
+ /** Validate a bucket name option at construction — the same shape of refusal
242
+ * every adapter here gives for a missing required option. */
243
+ export function assertBucketOption(adapter, option, value) {
244
+ if (typeof value !== 'string' || value.trim() === '') {
245
+ throw new TypeError(`[artifacts] ${adapter}({ ${option}: ${JSON.stringify(value)} }) names no bucket. ` +
246
+ `Give it the name of a bucket that already exists — this library never creates one: ` +
247
+ `a bucket carries region, lifecycle, encryption and access decisions that belong to ` +
248
+ `your infrastructure, not to a call in an agent.`);
249
+ }
250
+ return value;
251
+ }
252
+ //# sourceMappingURL=objectStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"objectStore.js","sourceRoot":"","sources":["../../../src/artifacts/objectStore.ts"],"names":[],"mappings":"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"}
@@ -29,15 +29,47 @@
29
29
  export declare function canonicalPayloadBytes(data: unknown): Uint8Array;
30
30
  /** Payload size in bytes — UTF-8 for text/JSON, byteLength for binary. */
31
31
  export declare function measureArtifactBytes(data: unknown): number;
32
+ /**
33
+ * Which of the three payload shapes a value is. The durable envelope carries
34
+ * it, and so does an object store's metadata — the canonical bytes alone
35
+ * cannot say whether `"7"` was the string `'7'` or the JSON number `7`, and a
36
+ * store that guessed would hand back a different value than it was given.
37
+ */
38
+ export type PayloadShape = 'text' | 'binary' | 'json';
39
+ /** The shape a payload will be stored under. Total: everything that is not a
40
+ * string or a `Uint8Array` rides as JSON (and is refused at measure/encode if
41
+ * JSON cannot carry it). */
42
+ export declare function payloadShapeOf(data: unknown): PayloadShape;
43
+ /**
44
+ * Rebuild a payload from its CANONICAL BYTES and its shape — the read half of
45
+ * `canonicalPayloadBytes`, for stores that hold the bytes themselves (an
46
+ * object body, a stream) rather than the text envelope.
47
+ *
48
+ * Round-trip law: `decodeCanonicalPayload(payloadShapeOf(x),
49
+ * canonicalPayloadBytes(x))` equals `x` for every payload this library
50
+ * accepts — which is what lets `bytes`, the digest, and the stored object all
51
+ * be the same bytes in every adapter.
52
+ */
53
+ export declare function decodeCanonicalPayload(shape: PayloadShape, bytes: Uint8Array): unknown;
32
54
  /** `sha-256:<hex>` over the canonical bytes. */
33
55
  export declare function computeArtifactDigest(data: unknown): Promise<string>;
34
- /** How a payload rides a file or a SQL TEXT column. One shape, two adapters. */
56
+ /** How a payload rides a file or a SQL TEXT column. One shape, two adapters.
57
+ *
58
+ * `'external'` (9.25.0) is the STREAMED case and exists only where a store
59
+ * can hold bytes beside the envelope: the payload is not in `value` at all —
60
+ * `value` names the sibling file that holds it, and the artifact reads back
61
+ * as binary. Only `fileArtifacts` writes it; `decodeArtifactData` refuses it
62
+ * by name, because a decoder that cannot reach the bytes must not pretend. */
35
63
  export interface EncodedPayload {
36
- readonly shape: 'text' | 'binary' | 'json';
37
- /** `text`: the string. `binary`: base64. `json`: the JSON serialization. */
64
+ readonly shape: PayloadShape | 'external';
65
+ /** `text`: the string. `binary`: base64. `json`: the JSON serialization.
66
+ * `external`: the name of the sibling file holding the raw bytes. */
38
67
  readonly value: string;
39
68
  }
40
69
  /** Encode for durable storage. Validates exactly as `measure` does. */
41
70
  export declare function encodeArtifactData(data: unknown): EncodedPayload;
42
- /** Decode what {@link encodeArtifactData} wrote. Total over its own output. */
71
+ /** Decode what {@link encodeArtifactData} wrote. Total over its own output;
72
+ * an `'external'` envelope is the one thing it refuses, by name — the bytes
73
+ * live beside the envelope and only the adapter that wrote them can reach
74
+ * them. */
43
75
  export declare function decodeArtifactData(encoded: EncodedPayload): unknown;
@@ -54,6 +54,36 @@ export function canonicalPayloadBytes(data) {
54
54
  export function measureArtifactBytes(data) {
55
55
  return canonicalPayloadBytes(data).byteLength;
56
56
  }
57
+ /** The shape a payload will be stored under. Total: everything that is not a
58
+ * string or a `Uint8Array` rides as JSON (and is refused at measure/encode if
59
+ * JSON cannot carry it). */
60
+ export function payloadShapeOf(data) {
61
+ if (data instanceof Uint8Array)
62
+ return 'binary';
63
+ if (typeof data === 'string')
64
+ return 'text';
65
+ return 'json';
66
+ }
67
+ /**
68
+ * Rebuild a payload from its CANONICAL BYTES and its shape — the read half of
69
+ * `canonicalPayloadBytes`, for stores that hold the bytes themselves (an
70
+ * object body, a stream) rather than the text envelope.
71
+ *
72
+ * Round-trip law: `decodeCanonicalPayload(payloadShapeOf(x),
73
+ * canonicalPayloadBytes(x))` equals `x` for every payload this library
74
+ * accepts — which is what lets `bytes`, the digest, and the stored object all
75
+ * be the same bytes in every adapter.
76
+ */
77
+ export function decodeCanonicalPayload(shape, bytes) {
78
+ switch (shape) {
79
+ case 'text':
80
+ return textDecoder.decode(bytes);
81
+ case 'binary':
82
+ return bytes;
83
+ case 'json':
84
+ return JSON.parse(textDecoder.decode(bytes));
85
+ }
86
+ }
57
87
  /** `sha-256:<hex>` over the canonical bytes. */
58
88
  export async function computeArtifactDigest(data) {
59
89
  const bytes = canonicalPayloadBytes(data);
@@ -75,7 +105,10 @@ export function encodeArtifactData(data) {
75
105
  // canonicalPayloadBytes carries the refusal for unserializable values.
76
106
  return { shape: 'json', value: textDecoder.decode(canonicalPayloadBytes(data)) };
77
107
  }
78
- /** Decode what {@link encodeArtifactData} wrote. Total over its own output. */
108
+ /** Decode what {@link encodeArtifactData} wrote. Total over its own output;
109
+ * an `'external'` envelope is the one thing it refuses, by name — the bytes
110
+ * live beside the envelope and only the adapter that wrote them can reach
111
+ * them. */
79
112
  export function decodeArtifactData(encoded) {
80
113
  switch (encoded.shape) {
81
114
  case 'text':
@@ -84,6 +117,10 @@ export function decodeArtifactData(encoded) {
84
117
  return fromBase64(encoded.value);
85
118
  case 'json':
86
119
  return JSON.parse(encoded.value);
120
+ case 'external':
121
+ throw new InvalidArtifactError(`the payload was streamed and lives beside the envelope ('${encoded.value}'), not in ` +
122
+ `it. Only the store that wrote it can read it back — read this artifact through ` +
123
+ `that store's get()/getStream(), never by decoding the envelope alone.`);
87
124
  }
88
125
  }
89
126
  // Buffer-free base64, so the in-file law works in a browser bundle too.
@@ -1 +1 @@
1
- {"version":3,"file":"payload.js","sourceRoot":"","sources":["../../../src/artifacts/payload.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"payload.js","sourceRoot":"","sources":["../../../src/artifacts/payload.ts"],"names":[],"mappings":"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"}