agentfootprint 9.25.0 → 9.26.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.
- package/AGENTS.md +1 -1
- package/CLAUDE.md +7 -1
- package/ai-instructions/claude-code/SKILL.md +1 -1
- package/dist/adapters/code/local.js +102 -2
- package/dist/adapters/code/local.js.map +1 -1
- package/dist/adapters/hosting/agentcore.js +11 -0
- package/dist/adapters/hosting/agentcore.js.map +1 -1
- package/dist/adapters/identity/jwks.js +277 -0
- package/dist/adapters/identity/jwks.js.map +1 -0
- package/dist/adapters/types.js +18 -1
- package/dist/adapters/types.js.map +1 -1
- package/dist/artifacts/index.js +6 -1
- package/dist/artifacts/index.js.map +1 -1
- package/dist/artifacts/recordingArtifact.js +88 -0
- package/dist/artifacts/recordingArtifact.js.map +1 -0
- package/dist/core/Agent.js +176 -0
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/agent/repeatedCall.js +190 -0
- package/dist/core/agent/repeatedCall.js.map +1 -0
- package/dist/core/agent/stages/toolCalls.js +50 -0
- package/dist/core/agent/stages/toolCalls.js.map +1 -1
- package/dist/core/codeRunnerTool.js +149 -12
- package/dist/core/codeRunnerTool.js.map +1 -1
- package/dist/esm/adapters/code/local.d.ts +16 -0
- package/dist/esm/adapters/code/local.js +102 -2
- package/dist/esm/adapters/code/local.js.map +1 -1
- package/dist/esm/adapters/hosting/agentcore.js +11 -0
- package/dist/esm/adapters/hosting/agentcore.js.map +1 -1
- package/dist/esm/adapters/identity/jwks.d.ts +124 -0
- package/dist/esm/adapters/identity/jwks.js +249 -0
- package/dist/esm/adapters/identity/jwks.js.map +1 -0
- package/dist/esm/adapters/types.d.ts +86 -0
- package/dist/esm/adapters/types.js +16 -0
- package/dist/esm/adapters/types.js.map +1 -1
- package/dist/esm/artifacts/index.d.ts +1 -0
- package/dist/esm/artifacts/index.js +1 -0
- package/dist/esm/artifacts/index.js.map +1 -1
- package/dist/esm/artifacts/recordingArtifact.d.ts +76 -0
- package/dist/esm/artifacts/recordingArtifact.js +83 -0
- package/dist/esm/artifacts/recordingArtifact.js.map +1 -0
- package/dist/esm/core/Agent.d.ts +66 -2
- package/dist/esm/core/Agent.js +176 -0
- package/dist/esm/core/Agent.js.map +1 -1
- package/dist/esm/core/agent/repeatedCall.d.ts +150 -0
- package/dist/esm/core/agent/repeatedCall.js +184 -0
- package/dist/esm/core/agent/repeatedCall.js.map +1 -0
- package/dist/esm/core/agent/stages/toolCalls.d.ts +12 -0
- package/dist/esm/core/agent/stages/toolCalls.js +50 -0
- package/dist/esm/core/agent/stages/toolCalls.js.map +1 -1
- package/dist/esm/core/agent/types.d.ts +82 -0
- package/dist/esm/core/codeRunnerTool.d.ts +31 -0
- package/dist/esm/core/codeRunnerTool.js +149 -12
- package/dist/esm/core/codeRunnerTool.js.map +1 -1
- package/dist/esm/events/payloads.d.ts +22 -0
- package/dist/esm/events/registry.d.ts +3 -1
- package/dist/esm/events/registry.js +2 -0
- package/dist/esm/events/registry.js.map +1 -1
- package/dist/esm/hosting/admission.d.ts +180 -0
- package/dist/esm/hosting/admission.js +188 -0
- package/dist/esm/hosting/admission.js.map +1 -0
- package/dist/esm/hosting/artifactWire.d.ts +8 -5
- package/dist/esm/hosting/artifactWire.js +14 -9
- package/dist/esm/hosting/artifactWire.js.map +1 -1
- package/dist/esm/hosting/envelope.d.ts +34 -0
- package/dist/esm/hosting/envelope.js +81 -0
- package/dist/esm/hosting/envelope.js.map +1 -1
- package/dist/esm/hosting/errors.d.ts +131 -0
- package/dist/esm/hosting/errors.js +195 -0
- package/dist/esm/hosting/errors.js.map +1 -1
- package/dist/esm/hosting/httpHost.d.ts +21 -0
- package/dist/esm/hosting/httpHost.js +44 -2
- package/dist/esm/hosting/httpHost.js.map +1 -1
- package/dist/esm/hosting/identityVerification.d.ts +154 -0
- package/dist/esm/hosting/identityVerification.js +135 -0
- package/dist/esm/hosting/identityVerification.js.map +1 -0
- package/dist/esm/hosting/index.d.ts +12 -3
- package/dist/esm/hosting/index.js +16 -2
- package/dist/esm/hosting/index.js.map +1 -1
- package/dist/esm/hosting/memorySessions.d.ts +9 -0
- package/dist/esm/hosting/memorySessions.js +86 -0
- package/dist/esm/hosting/memorySessions.js.map +1 -1
- package/dist/esm/hosting/nodeHost.js +8 -0
- package/dist/esm/hosting/nodeHost.js.map +1 -1
- package/dist/esm/hosting/sessionWire.d.ts +126 -0
- package/dist/esm/hosting/sessionWire.js +95 -0
- package/dist/esm/hosting/sessionWire.js.map +1 -0
- package/dist/esm/hosting/sqliteSessions.js +122 -5
- package/dist/esm/hosting/sqliteSessions.js.map +1 -1
- package/dist/esm/hosting/standingAgent.js +299 -8
- package/dist/esm/hosting/standingAgent.js.map +1 -1
- package/dist/esm/hosting/types.d.ts +166 -6
- package/dist/esm/hosting/types.js.map +1 -1
- package/dist/esm/hosting/wireOps.d.ts +52 -0
- package/dist/esm/hosting/wireOps.js +60 -0
- package/dist/esm/hosting/wireOps.js.map +1 -0
- package/dist/esm/identity.d.ts +1 -0
- package/dist/esm/identity.js +6 -0
- package/dist/esm/identity.js.map +1 -1
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +5 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/events/registry.js +2 -0
- package/dist/events/registry.js.map +1 -1
- package/dist/hosting/admission.js +194 -0
- package/dist/hosting/admission.js.map +1 -0
- package/dist/hosting/artifactWire.js +14 -9
- package/dist/hosting/artifactWire.js.map +1 -1
- package/dist/hosting/envelope.js +84 -1
- package/dist/hosting/envelope.js.map +1 -1
- package/dist/hosting/errors.js +203 -1
- package/dist/hosting/errors.js.map +1 -1
- package/dist/hosting/httpHost.js +43 -1
- package/dist/hosting/httpHost.js.map +1 -1
- package/dist/hosting/identityVerification.js +140 -0
- package/dist/hosting/identityVerification.js.map +1 -0
- package/dist/hosting/index.js +38 -1
- package/dist/hosting/index.js.map +1 -1
- package/dist/hosting/memorySessions.js +86 -0
- package/dist/hosting/memorySessions.js.map +1 -1
- package/dist/hosting/nodeHost.js +8 -0
- package/dist/hosting/nodeHost.js.map +1 -1
- package/dist/hosting/sessionWire.js +100 -0
- package/dist/hosting/sessionWire.js.map +1 -0
- package/dist/hosting/sqliteSessions.js +121 -4
- package/dist/hosting/sqliteSessions.js.map +1 -1
- package/dist/hosting/standingAgent.js +297 -6
- package/dist/hosting/standingAgent.js.map +1 -1
- package/dist/hosting/types.js.map +1 -1
- package/dist/hosting/wireOps.js +65 -0
- package/dist/hosting/wireOps.js.map +1 -0
- package/dist/identity.js +9 -1
- package/dist/identity.js.map +1 -1
- package/dist/index.js +9 -2
- package/dist/index.js.map +1 -1
- package/dist/types/adapters/code/local.d.ts +16 -0
- package/dist/types/adapters/code/local.d.ts.map +1 -1
- package/dist/types/adapters/hosting/agentcore.d.ts.map +1 -1
- package/dist/types/adapters/identity/jwks.d.ts +125 -0
- package/dist/types/adapters/identity/jwks.d.ts.map +1 -0
- package/dist/types/adapters/types.d.ts +86 -0
- package/dist/types/adapters/types.d.ts.map +1 -1
- package/dist/types/artifacts/index.d.ts +1 -0
- package/dist/types/artifacts/index.d.ts.map +1 -1
- package/dist/types/artifacts/recordingArtifact.d.ts +77 -0
- package/dist/types/artifacts/recordingArtifact.d.ts.map +1 -0
- package/dist/types/core/Agent.d.ts +66 -2
- package/dist/types/core/Agent.d.ts.map +1 -1
- package/dist/types/core/agent/repeatedCall.d.ts +151 -0
- package/dist/types/core/agent/repeatedCall.d.ts.map +1 -0
- package/dist/types/core/agent/stages/toolCalls.d.ts +12 -0
- package/dist/types/core/agent/stages/toolCalls.d.ts.map +1 -1
- package/dist/types/core/agent/types.d.ts +82 -0
- package/dist/types/core/agent/types.d.ts.map +1 -1
- package/dist/types/core/codeRunnerTool.d.ts +31 -0
- package/dist/types/core/codeRunnerTool.d.ts.map +1 -1
- package/dist/types/events/payloads.d.ts +22 -0
- package/dist/types/events/payloads.d.ts.map +1 -1
- package/dist/types/events/registry.d.ts +3 -1
- package/dist/types/events/registry.d.ts.map +1 -1
- package/dist/types/hosting/admission.d.ts +181 -0
- package/dist/types/hosting/admission.d.ts.map +1 -0
- package/dist/types/hosting/artifactWire.d.ts +8 -5
- package/dist/types/hosting/artifactWire.d.ts.map +1 -1
- package/dist/types/hosting/envelope.d.ts +34 -0
- package/dist/types/hosting/envelope.d.ts.map +1 -1
- package/dist/types/hosting/errors.d.ts +131 -0
- package/dist/types/hosting/errors.d.ts.map +1 -1
- package/dist/types/hosting/httpHost.d.ts +21 -0
- package/dist/types/hosting/httpHost.d.ts.map +1 -1
- package/dist/types/hosting/identityVerification.d.ts +155 -0
- package/dist/types/hosting/identityVerification.d.ts.map +1 -0
- package/dist/types/hosting/index.d.ts +12 -3
- package/dist/types/hosting/index.d.ts.map +1 -1
- package/dist/types/hosting/memorySessions.d.ts +9 -0
- package/dist/types/hosting/memorySessions.d.ts.map +1 -1
- package/dist/types/hosting/nodeHost.d.ts.map +1 -1
- package/dist/types/hosting/sessionWire.d.ts +127 -0
- package/dist/types/hosting/sessionWire.d.ts.map +1 -0
- package/dist/types/hosting/sqliteSessions.d.ts.map +1 -1
- package/dist/types/hosting/standingAgent.d.ts.map +1 -1
- package/dist/types/hosting/types.d.ts +166 -6
- package/dist/types/hosting/types.d.ts.map +1 -1
- package/dist/types/hosting/wireOps.d.ts +53 -0
- package/dist/types/hosting/wireOps.d.ts.map +1 -0
- package/dist/types/identity.d.ts +1 -0
- package/dist/types/identity.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +6 -1
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* jwksIdentity — verify the caller's bearer token against a published key set.
|
|
3
|
+
*
|
|
4
|
+
* Pattern: Adapter (GoF) over `jose`, behind the vendor-neutral
|
|
5
|
+
* {@link IdentityVerifier} port.
|
|
6
|
+
* Role: the ONE identity verifier this release ships. It covers cloud IdPs
|
|
7
|
+
* and on-prem ones with the same code, because JWKS is the same
|
|
8
|
+
* protocol in both: a URL that publishes signing keys, and tokens
|
|
9
|
+
* signed by one of them.
|
|
10
|
+
* Emits: nothing. The door that called it reports the refusal — by CLASS.
|
|
11
|
+
*
|
|
12
|
+
* ── What it checks, and what it refuses to pretend to check ─────────────────
|
|
13
|
+
* Signature (against the key the token's `kid` names, fetched and cached from
|
|
14
|
+
* `jwksUrl`), `iss`, `aud`, `exp` and `nbf`. That is the whole list, and it is
|
|
15
|
+
* the whole list on purpose:
|
|
16
|
+
*
|
|
17
|
+
* • **It is not an authorization decision.** A verified token proves WHO, not
|
|
18
|
+
* WHAT-THEY-MAY-DO. Roles and claims come back on the result so your own
|
|
19
|
+
* policy can decide; this adapter never reads them.
|
|
20
|
+
* • **It does not check revocation.** A JWT is valid until it expires, and no
|
|
21
|
+
* amount of key fetching changes that. Short lifetimes are the answer; an
|
|
22
|
+
* adapter that implied otherwise would be selling a guarantee the protocol
|
|
23
|
+
* does not make.
|
|
24
|
+
* • **`alg: none` cannot get through**, because a JWKS resolver has no key for
|
|
25
|
+
* it — verified against the real library rather than assumed (see the pin
|
|
26
|
+
* test). Neither can a token signed with an algorithm outside `algorithms`.
|
|
27
|
+
*
|
|
28
|
+
* ── The token never comes back out ──────────────────────────────────────────
|
|
29
|
+
* Every failure is re-raised as {@link IdentityNotVerifiedError} carrying only
|
|
30
|
+
* the CLASS — `expired`, `wrong-audience`, `wrong-issuer`, `not-yet-valid`,
|
|
31
|
+
* `unverifiable`. The library's own message is dropped, and the original is
|
|
32
|
+
* deliberately NOT attached as `cause`: a cause travels into every serializer
|
|
33
|
+
* that walks own properties, and one `JSON.stringify` would undo all of this.
|
|
34
|
+
* (The `sdkFailure` law, applied to a credential rather than to a cloud SDK.)
|
|
35
|
+
*
|
|
36
|
+
* A key set this adapter could not FETCH is a different fact and gets a
|
|
37
|
+
* different class: {@link VerifierUnavailableError}, which the host answers 503
|
|
38
|
+
* rather than 401. Your IdP being down is not the caller presenting a bad
|
|
39
|
+
* token, and telling every client to re-authenticate against an unreachable
|
|
40
|
+
* provider is the wrong instruction at the worst moment.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* const host = await standingAgent({
|
|
44
|
+
* agent, sessions, host: nodeHost({ port: 8080 }),
|
|
45
|
+
* identity: { verify: jwksIdentity({
|
|
46
|
+
* jwksUrl: 'https://idp.example.com/.well-known/jwks.json',
|
|
47
|
+
* issuer: 'https://idp.example.com/',
|
|
48
|
+
* audience: 'my-api',
|
|
49
|
+
* }).verify },
|
|
50
|
+
* });
|
|
51
|
+
*/
|
|
52
|
+
import { IdentityNotVerifiedError, VerifierUnavailableError } from '../../hosting/errors.js';
|
|
53
|
+
import { lazyRequire } from '../../lib/lazyRequire.js';
|
|
54
|
+
/** Raised when a token must be verified and `jose` is not installed. */
|
|
55
|
+
export class MissingJwksSupportError extends Error {
|
|
56
|
+
code = 'ERR_MISSING_JWKS_SUPPORT';
|
|
57
|
+
constructor() {
|
|
58
|
+
super('jwksIdentity requires the `jose` peer dependency.\n' +
|
|
59
|
+
' Install: npm install jose\n' +
|
|
60
|
+
' Or pass `backend` to jwksIdentity() if your bundler resolves it statically.');
|
|
61
|
+
this.name = 'MissingJwksSupportError';
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** The asymmetric families. See {@link JwksIdentityOptions.algorithms}. */
|
|
65
|
+
const DEFAULT_ALGORITHMS = [
|
|
66
|
+
'RS256',
|
|
67
|
+
'RS384',
|
|
68
|
+
'RS512',
|
|
69
|
+
'PS256',
|
|
70
|
+
'PS384',
|
|
71
|
+
'PS512',
|
|
72
|
+
'ES256',
|
|
73
|
+
'ES384',
|
|
74
|
+
'ES512',
|
|
75
|
+
];
|
|
76
|
+
/**
|
|
77
|
+
* `jose`'s stable error codes → this library's failure vocabulary.
|
|
78
|
+
*
|
|
79
|
+
* Mapped by CODE STRING rather than by `instanceof`, and that is the load-
|
|
80
|
+
* bearing choice: the error classes are not on `jose`'s main entry point (they
|
|
81
|
+
* live under `jose/errors`), the codes are documented as stable, and a string
|
|
82
|
+
* comparison survives a duplicated copy of the library in a `node_modules` tree
|
|
83
|
+
* — which `instanceof` famously does not.
|
|
84
|
+
*
|
|
85
|
+
* Every code is one this adapter has SEEN the installed library produce; the
|
|
86
|
+
* pin test reproduces each one against the real package.
|
|
87
|
+
*/
|
|
88
|
+
function classOf(err) {
|
|
89
|
+
const e = err;
|
|
90
|
+
const code = typeof e?.code === 'string' ? e.code : undefined;
|
|
91
|
+
switch (code) {
|
|
92
|
+
case 'ERR_JWT_EXPIRED':
|
|
93
|
+
return 'expired';
|
|
94
|
+
case 'ERR_JWT_CLAIM_VALIDATION_FAILED': {
|
|
95
|
+
const claim = typeof e?.claim === 'string' ? e.claim : undefined;
|
|
96
|
+
if (claim === 'aud')
|
|
97
|
+
return 'wrong-audience';
|
|
98
|
+
if (claim === 'iss')
|
|
99
|
+
return 'wrong-issuer';
|
|
100
|
+
if (claim === 'nbf')
|
|
101
|
+
return 'not-yet-valid';
|
|
102
|
+
return 'unverifiable';
|
|
103
|
+
}
|
|
104
|
+
case 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED':
|
|
105
|
+
case 'ERR_JWKS_NO_MATCHING_KEY':
|
|
106
|
+
case 'ERR_JWKS_MULTIPLE_MATCHING_KEYS':
|
|
107
|
+
case 'ERR_JWS_INVALID':
|
|
108
|
+
case 'ERR_JWT_INVALID':
|
|
109
|
+
case 'ERR_JWK_INVALID':
|
|
110
|
+
case 'ERR_JWKS_INVALID':
|
|
111
|
+
case 'ERR_JOSE_ALG_NOT_ALLOWED':
|
|
112
|
+
case 'ERR_JOSE_NOT_SUPPORTED':
|
|
113
|
+
return 'unverifiable';
|
|
114
|
+
case 'ERR_JWKS_TIMEOUT':
|
|
115
|
+
return 'keys-unavailable';
|
|
116
|
+
default:
|
|
117
|
+
// No JOSE code at all. A key-set fetch that failed surfaces here as the
|
|
118
|
+
// runtime's own `TypeError: fetch failed` — an outage on THIS side, and
|
|
119
|
+
// answering it 401 would send every client to re-authenticate against a
|
|
120
|
+
// provider that is already down.
|
|
121
|
+
return code === undefined ? 'keys-unavailable' : 'unverifiable';
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/** Roles out of a claim, read leniently and never invented. */
|
|
125
|
+
function rolesOf(value) {
|
|
126
|
+
if (Array.isArray(value)) {
|
|
127
|
+
const roles = value.filter((v) => typeof v === 'string' && v.length > 0);
|
|
128
|
+
return roles.length > 0 ? roles : undefined;
|
|
129
|
+
}
|
|
130
|
+
if (typeof value === 'string' && value.trim().length > 0) {
|
|
131
|
+
// The `scope` convention: one space-delimited string.
|
|
132
|
+
const roles = value.trim().split(/\s+/);
|
|
133
|
+
return roles.length > 0 ? roles : undefined;
|
|
134
|
+
}
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
export function jwksIdentity(options) {
|
|
138
|
+
const { jwksUrl } = options;
|
|
139
|
+
if (typeof jwksUrl !== 'string' || jwksUrl.trim().length === 0) {
|
|
140
|
+
throw new TypeError(`[identity] jwksIdentity({ jwksUrl: ${JSON.stringify(jwksUrl)} }) needs the URL your ` +
|
|
141
|
+
`identity provider publishes its signing keys at — usually ` +
|
|
142
|
+
`'<issuer>/.well-known/jwks.json'.`);
|
|
143
|
+
}
|
|
144
|
+
let url;
|
|
145
|
+
try {
|
|
146
|
+
url = new URL(jwksUrl);
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
throw new TypeError(`[identity] jwksIdentity({ jwksUrl: '${jwksUrl}' }) is not an absolute URL. Key sets are ` +
|
|
150
|
+
`fetched over the network, so a relative path has nothing to resolve against.`);
|
|
151
|
+
}
|
|
152
|
+
if (emptyName(options.issuer)) {
|
|
153
|
+
throw new TypeError(`[identity] jwksIdentity needs an \`issuer\`. A verifier that accepted any issuer would ` +
|
|
154
|
+
`accept a token minted by anybody who publishes a key set — which is not verification, ` +
|
|
155
|
+
`it is a signature check with no opinion about who signed.`);
|
|
156
|
+
}
|
|
157
|
+
if (emptyName(options.audience)) {
|
|
158
|
+
throw new TypeError(`[identity] jwksIdentity needs an \`audience\` — this API's name at your identity ` +
|
|
159
|
+
`provider. Without it a token minted for a DIFFERENT service verifies here, which is ` +
|
|
160
|
+
`the confused-deputy shape: a valid credential, honoured by the wrong door.`);
|
|
161
|
+
}
|
|
162
|
+
const userIdClaim = options.userIdClaim ?? 'sub';
|
|
163
|
+
const rolesClaim = options.rolesClaim ?? 'roles';
|
|
164
|
+
const algorithms = options.algorithms ?? DEFAULT_ALGORITHMS;
|
|
165
|
+
/** The key-set resolver, built once and reused — `jose` caches inside it. */
|
|
166
|
+
let resolver;
|
|
167
|
+
const getResolver = () => (resolver ??= (async () => {
|
|
168
|
+
const jose = options.backend ?? (await loadJose());
|
|
169
|
+
const keys = jose.createRemoteJWKSet(url, {
|
|
170
|
+
...(options.cacheMaxAgeMs !== undefined && { cacheMaxAge: options.cacheMaxAgeMs }),
|
|
171
|
+
...(options.fetchTimeoutMs !== undefined && { timeoutDuration: options.fetchTimeoutMs }),
|
|
172
|
+
});
|
|
173
|
+
return { jose, keys };
|
|
174
|
+
})().catch((err) => {
|
|
175
|
+
// A failed BUILD is not cached — a bundler hiccup or a transient import
|
|
176
|
+
// failure must not permanently poison the verifier.
|
|
177
|
+
resolver = undefined;
|
|
178
|
+
throw err;
|
|
179
|
+
}));
|
|
180
|
+
return {
|
|
181
|
+
async verify(token) {
|
|
182
|
+
const { jose, keys } = await getResolver();
|
|
183
|
+
let payload;
|
|
184
|
+
try {
|
|
185
|
+
const verified = await jose.jwtVerify(token, keys, {
|
|
186
|
+
issuer: options.issuer,
|
|
187
|
+
audience: options.audience,
|
|
188
|
+
algorithms: algorithms,
|
|
189
|
+
...(options.clockToleranceSeconds !== undefined && {
|
|
190
|
+
clockTolerance: options.clockToleranceSeconds,
|
|
191
|
+
}),
|
|
192
|
+
});
|
|
193
|
+
payload = verified.payload;
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
const failure = classOf(err);
|
|
197
|
+
// The one place the two shapes diverge: an unreachable key set is this
|
|
198
|
+
// deployment's outage (503), everything else is the caller's token
|
|
199
|
+
// (401). Neither carries the token, the claims, or the library's text.
|
|
200
|
+
if (failure === 'keys-unavailable') {
|
|
201
|
+
throw new VerifierUnavailableError('jwksIdentity', 'its key set could not be fetched');
|
|
202
|
+
}
|
|
203
|
+
throw new IdentityNotVerifiedError(failure, false);
|
|
204
|
+
}
|
|
205
|
+
const userId = payload[userIdClaim];
|
|
206
|
+
if (typeof userId !== 'string' || userId.length === 0) {
|
|
207
|
+
// A perfectly valid token that does not say who it is about. Refused
|
|
208
|
+
// rather than served anonymously: "verified, subject unknown" is a
|
|
209
|
+
// state nothing downstream could act on honestly.
|
|
210
|
+
throw new IdentityNotVerifiedError('unverifiable', false);
|
|
211
|
+
}
|
|
212
|
+
const roles = rolesOf(payload[rolesClaim]);
|
|
213
|
+
return {
|
|
214
|
+
userId,
|
|
215
|
+
...(roles !== undefined && { roles }),
|
|
216
|
+
claims: payload,
|
|
217
|
+
};
|
|
218
|
+
},
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
function emptyName(value) {
|
|
222
|
+
if (typeof value === 'string')
|
|
223
|
+
return value.trim().length === 0;
|
|
224
|
+
if (Array.isArray(value))
|
|
225
|
+
return value.length === 0 || value.some((v) => typeof v !== 'string');
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Load `jose`, or refuse by name.
|
|
230
|
+
*
|
|
231
|
+
* `jose` v6 is ESM-only, so a dynamic import is tried first and the CJS require
|
|
232
|
+
* is the fallback — one of the two works on every runtime this package
|
|
233
|
+
* supports. (The `unpdf` loader's shape, for the same reason.)
|
|
234
|
+
*/
|
|
235
|
+
async function loadJose() {
|
|
236
|
+
try {
|
|
237
|
+
const spec = 'jose';
|
|
238
|
+
return (await import(spec));
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
try {
|
|
242
|
+
return lazyRequire('jose');
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
throw new MissingJwksSupportError();
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=jwks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwks.js","sourceRoot":"","sources":["../../../../src/adapters/identity/jwks.ts"],"names":[],"mappings":"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"}
|
|
@@ -712,6 +712,60 @@ export interface CodeRunner {
|
|
|
712
712
|
readonly signal?: AbortSignal;
|
|
713
713
|
}): Promise<CodeSession>;
|
|
714
714
|
}
|
|
715
|
+
/**
|
|
716
|
+
* The environment variable an executing snippet reads its staged inputs from —
|
|
717
|
+
* a JSON object mapping each input's NAME to the path it landed at.
|
|
718
|
+
*
|
|
719
|
+
* Part of {@link CodeSession.stageInputs}'s contract rather than one adapter's
|
|
720
|
+
* convention, and named here so an adapter uses the constant instead of
|
|
721
|
+
* retyping the string. It is what makes model-written code portable across
|
|
722
|
+
* backends: the code reads one variable, and every adapter that stages inputs
|
|
723
|
+
* fills it the same way.
|
|
724
|
+
*/
|
|
725
|
+
export declare const STAGED_INPUTS_ENV = "AF_STAGED_INPUTS";
|
|
726
|
+
/**
|
|
727
|
+
* One payload staged INTO a code session before code runs (9.26.0).
|
|
728
|
+
*
|
|
729
|
+
* `name` is the file name the caller wants it under — the tool derives it from
|
|
730
|
+
* the declared argument (`dataset` → `dataset.json`), so the model can be told
|
|
731
|
+
* the name in a static description. An adapter may sanitize it (a name is
|
|
732
|
+
* caller data landing in a filesystem) but must not rename it beyond
|
|
733
|
+
* recognition, because the manifest is keyed by what it was ASKED for.
|
|
734
|
+
*/
|
|
735
|
+
export interface CodeInput {
|
|
736
|
+
/**
|
|
737
|
+
* The MANIFEST KEY — what the executing code looks this input up by. The
|
|
738
|
+
* tool uses the declared argument name (`dataset`), so a static description
|
|
739
|
+
* can tell the model exactly what to look up before any session exists.
|
|
740
|
+
*/
|
|
741
|
+
readonly name: string;
|
|
742
|
+
/**
|
|
743
|
+
* The file name to write it under, when it should differ from `name` — the
|
|
744
|
+
* tool derives one from the artifact's media type (`dataset` +
|
|
745
|
+
* `application/json` → `dataset.json`) so an interpreter's own loader sees a
|
|
746
|
+
* familiar extension. Defaults to `name`.
|
|
747
|
+
*
|
|
748
|
+
* A separate field precisely so the manifest KEY and the on-disk NAME cannot
|
|
749
|
+
* drift: the code looks up what it was told to look up, whatever the file
|
|
750
|
+
* ended up being called.
|
|
751
|
+
*/
|
|
752
|
+
readonly fileName?: string;
|
|
753
|
+
/** The bytes. A string is written as UTF-8 text; a `Uint8Array` verbatim. */
|
|
754
|
+
readonly data: string | Uint8Array;
|
|
755
|
+
/** The producer's own statement about the payload, when it has one. */
|
|
756
|
+
readonly mediaType?: string;
|
|
757
|
+
}
|
|
758
|
+
/** Where one staged input actually landed. */
|
|
759
|
+
export interface StagedCodeInput {
|
|
760
|
+
/** The name it was asked for — the manifest key the code looks up. */
|
|
761
|
+
readonly name: string;
|
|
762
|
+
/** The path the executing code opens. Absolute, or relative to the session's
|
|
763
|
+
* working directory: whichever it is, it is what the manifest carries and
|
|
764
|
+
* what the code should use verbatim. */
|
|
765
|
+
readonly path: string;
|
|
766
|
+
/** How many bytes landed. */
|
|
767
|
+
readonly bytes: number;
|
|
768
|
+
}
|
|
715
769
|
/** One live session. `stop()` is idempotent and tolerates "already gone". */
|
|
716
770
|
export interface CodeSession {
|
|
717
771
|
/** The backend's own id for this session, when it has one. */
|
|
@@ -722,6 +776,35 @@ export interface CodeSession {
|
|
|
722
776
|
readonly timeoutMs?: number;
|
|
723
777
|
readonly signal?: AbortSignal;
|
|
724
778
|
}): Promise<CodeResult>;
|
|
779
|
+
/**
|
|
780
|
+
* OPTIONAL (9.26.0) — put payloads INTO the session, so code can read data
|
|
781
|
+
* that never travelled through the context window.
|
|
782
|
+
*
|
|
783
|
+
* ── Why it is a new member rather than an argument to `execute` ──────────
|
|
784
|
+
* The port's only input was the code STRING, and 9.22.0 stated the honest
|
|
785
|
+
* consequence rather than working around it: pushing a resolved artifact
|
|
786
|
+
* through that door would mean inlining megabytes into an argv, in
|
|
787
|
+
* language-specific quoting, past operating-system argument limits. This is
|
|
788
|
+
* the session file-write verb that note said it was waiting for.
|
|
789
|
+
*
|
|
790
|
+
* ── The contract, which is two promises not one ─────────────────────────
|
|
791
|
+
* 1. The payloads are written where the session's code can read them, and
|
|
792
|
+
* the returned {@link StagedCodeInput.path} is what the code opens.
|
|
793
|
+
* 2. Every later `execute` on this session exposes the manifest as the
|
|
794
|
+
* {@link STAGED_INPUTS_ENV} environment variable — a JSON object of
|
|
795
|
+
* `name → path`. That second promise is what makes the model's code
|
|
796
|
+
* portable: it reads one variable, on every backend that stages.
|
|
797
|
+
*
|
|
798
|
+
* Staged inputs live as long as the SESSION and are released by `stop()`.
|
|
799
|
+
*
|
|
800
|
+
* ── Absent, never faked ─────────────────────────────────────────────────
|
|
801
|
+
* A backend that cannot write into its own session LEAVES THIS ABSENT.
|
|
802
|
+
* Feature-detect with `canStageCodeInputs(session)`; `codeRunnerTool`
|
|
803
|
+
* refuses by name when a tool declares artifact inputs and the runner cannot
|
|
804
|
+
* carry them, because running the code without the data it declared would be
|
|
805
|
+
* the accepted-and-silently-wrong failure.
|
|
806
|
+
*/
|
|
807
|
+
stageInputs?(inputs: readonly CodeInput[]): Promise<readonly StagedCodeInput[]>;
|
|
725
808
|
/**
|
|
726
809
|
* Release the session.
|
|
727
810
|
*
|
|
@@ -731,6 +814,9 @@ export interface CodeSession {
|
|
|
731
814
|
*/
|
|
732
815
|
stop(): Promise<void>;
|
|
733
816
|
}
|
|
817
|
+
/** Can this session accept staged inputs? The feature-detection law: read the
|
|
818
|
+
* member, never assume it from the adapter's name. */
|
|
819
|
+
export declare function canStageCodeInputs(session: CodeSession): session is CodeSession & Required<Pick<CodeSession, 'stageInputs'>>;
|
|
734
820
|
/** What one execution produced. */
|
|
735
821
|
export interface CodeResult {
|
|
736
822
|
/** Did the code run to completion without an error exit? */
|
|
@@ -35,4 +35,20 @@ export function checkerGoverns(checker, capability) {
|
|
|
35
35
|
return true;
|
|
36
36
|
return checker.governs?.includes(capability) === true;
|
|
37
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* The environment variable an executing snippet reads its staged inputs from —
|
|
40
|
+
* a JSON object mapping each input's NAME to the path it landed at.
|
|
41
|
+
*
|
|
42
|
+
* Part of {@link CodeSession.stageInputs}'s contract rather than one adapter's
|
|
43
|
+
* convention, and named here so an adapter uses the constant instead of
|
|
44
|
+
* retyping the string. It is what makes model-written code portable across
|
|
45
|
+
* backends: the code reads one variable, and every adapter that stages inputs
|
|
46
|
+
* fills it the same way.
|
|
47
|
+
*/
|
|
48
|
+
export const STAGED_INPUTS_ENV = 'AF_STAGED_INPUTS';
|
|
49
|
+
/** Can this session accept staged inputs? The feature-detection law: read the
|
|
50
|
+
* member, never assume it from the adapter's name. */
|
|
51
|
+
export function canStageCodeInputs(session) {
|
|
52
|
+
return typeof session.stageInputs === 'function';
|
|
53
|
+
}
|
|
38
54
|
//# sourceMappingURL=types.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/adapters/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA+GH;;;;GAIG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAwB,MAAM,CAAC,MAAM,CAAC;IAC5E,MAAM;IACN,WAAW;CACZ,CAAC,CAAC;AAikBH;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAsC,EACtC,UAAgC;IAEhC,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3B,IAAI,UAAU,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAC5C,OAAO,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;AACxD,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/adapters/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA+GH;;;;GAIG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAwB,MAAM,CAAC,MAAM,CAAC;IAC5E,MAAM;IACN,WAAW;CACZ,CAAC,CAAC;AAikBH;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAsC,EACtC,UAAgC;IAEhC,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3B,IAAI,UAAU,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAC5C,OAAO,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;AACxD,CAAC;AAqDD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,kBAAkB,CAAC;AAgGpD;uDACuD;AACvD,MAAM,UAAU,kBAAkB,CAChC,OAAoB;IAEpB,OAAO,OAAO,OAAO,CAAC,WAAW,KAAK,UAAU,CAAC;AACnD,CAAC"}
|
|
@@ -21,4 +21,5 @@ export { assertStreamBytes, bytesAsStream, canGetArtifactStream, canPutArtifactS
|
|
|
21
21
|
export { bindArtifacts, unconfiguredArtifacts, type ArtifactEventFact, type ArtifactEventSink, type ArtifactOp, type ArtifactRefusalReason, type BindArtifactsOptions, type ToolArtifactPutInput, type ToolArtifacts, } from './capability.js';
|
|
22
22
|
export { assertToolWants, resolveToolWants, wantsNeedsStoreRefusal, type ToolWants, type WantsRefusal, type WantsResolution, } from './wants.js';
|
|
23
23
|
export { PRESENT_TOOL_NAME, presentArtifact, type PresentOutcome, type PresentSnapshot, type PresentedResult, } from './present.js';
|
|
24
|
+
export { recordingPutInput, RECORDING_ARTIFACT_KIND, RECORDING_MEDIA_TYPE, UnserializableRecordingError, type RecordingMintFacts, } from './recordingArtifact.js';
|
|
24
25
|
export { assertArtifactPlacement, isPlacedToolResult, placedResultKind, placedToolResult, type ArtifactPlacement, type PlacedToolResult, } from './placement.js';
|
|
@@ -20,5 +20,6 @@ export { assertStreamBytes, bytesAsStream, canGetArtifactStream, canPutArtifactS
|
|
|
20
20
|
export { bindArtifacts, unconfiguredArtifacts, } from './capability.js';
|
|
21
21
|
export { assertToolWants, resolveToolWants, wantsNeedsStoreRefusal, } from './wants.js';
|
|
22
22
|
export { PRESENT_TOOL_NAME, presentArtifact, } from './present.js';
|
|
23
|
+
export { recordingPutInput, RECORDING_ARTIFACT_KIND, RECORDING_MEDIA_TYPE, UnserializableRecordingError, } from './recordingArtifact.js';
|
|
23
24
|
export { assertArtifactPlacement, isPlacedToolResult, placedResultKind, placedToolResult, } from './placement.js';
|
|
24
25
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/artifacts/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,GAetB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAElF,OAAO,EACL,iBAAiB,EACjB,oCAAoC,GAGrC,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,aAAa,EACb,2BAA2B,GAE5B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,eAAe,EACf,4BAA4B,GAG7B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,WAAW,EAA2B,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,YAAY,EAA4B,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,GAId,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,aAAa,EACb,qBAAqB,GAQtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,sBAAsB,GAIvB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,eAAe,GAIhB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,GAGjB,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/artifacts/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,GAetB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAElF,OAAO,EACL,iBAAiB,EACjB,oCAAoC,GAGrC,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,aAAa,EACb,2BAA2B,GAE5B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,eAAe,EACf,4BAA4B,GAG7B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,WAAW,EAA2B,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,YAAY,EAA4B,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,GAId,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,aAAa,EACb,qBAAqB,GAQtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,sBAAsB,GAIvB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,eAAe,GAIhB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,oBAAoB,EACpB,4BAA4B,GAE7B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,GAGjB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* artifacts/recordingArtifact — a finished run, checked into the store like any
|
|
3
|
+
* other payload.
|
|
4
|
+
*
|
|
5
|
+
* `recordRun` has produced `{ snapshot, events, structure }` since 8.x and the
|
|
6
|
+
* lens family has consumed exactly that shape since. What nobody shipped was
|
|
7
|
+
* the boring half in between: WHERE a completed run's recording goes so a
|
|
8
|
+
* screen can ask for it later. Every deployment that wanted the Lens over the
|
|
9
|
+
* wire wrote the same twenty lines — record the run, serialize it, put it
|
|
10
|
+
* somewhere with a key, hand the key to the frontend — and each one wrote a
|
|
11
|
+
* slightly different, slightly wrong version of retention and scoping.
|
|
12
|
+
*
|
|
13
|
+
* All four of those problems already have an answer in this package: the
|
|
14
|
+
* artifact store IS a keyed payload store with scope isolation, retention and
|
|
15
|
+
* a read-only wire. So a recording is simply an artifact of kind
|
|
16
|
+
* `'recording/run'`, and the wire ops that already redeem claim tickets serve
|
|
17
|
+
* it with **zero new operations** — `{ op: 'artifact-get', ref }` returns the
|
|
18
|
+
* recording, and the frontend does what it always did with the bytes.
|
|
19
|
+
*
|
|
20
|
+
* ── Why the payload is TEXT and not an object ───────────────────────────────
|
|
21
|
+
* The recording is minted as its JSON text — the same bytes
|
|
22
|
+
* `JSON.stringify(recorder.toRecording())` produces, which is precisely what
|
|
23
|
+
* `observeRecording(JSON.parse(text))` consumes on the viewer side. Two
|
|
24
|
+
* reasons, and both are about not lying:
|
|
25
|
+
*
|
|
26
|
+
* • `recordRun` states that `snapshot` and `structure` are the runner's OWN
|
|
27
|
+
* objects, held by reference. An in-process store handed those would keep
|
|
28
|
+
* a live view into a finished run's state — the artifact would silently
|
|
29
|
+
* change if anything touched it. Serializing detaches it, once, here.
|
|
30
|
+
* • A recording that cannot be serialized cannot be delivered over any wire
|
|
31
|
+
* either, so failing at the mint is failing at the honest moment rather
|
|
32
|
+
* than at whatever reads it next.
|
|
33
|
+
*/
|
|
34
|
+
import type { PutArtifactInput } from './types.js';
|
|
35
|
+
/** The consumer vocabulary a run recording is stored under. One kind, exact
|
|
36
|
+
* match — the same rule every `wants` declaration is judged by. */
|
|
37
|
+
export declare const RECORDING_ARTIFACT_KIND = "recording/run";
|
|
38
|
+
/** The media type a recording is minted with. */
|
|
39
|
+
export declare const RECORDING_MEDIA_TYPE = "application/json";
|
|
40
|
+
/** What a recording mint needs to know beyond the recording itself. */
|
|
41
|
+
export interface RecordingMintFacts {
|
|
42
|
+
/** The run this recording is OF — stamped on `origin.runId`, which is the
|
|
43
|
+
* join back to the trace. */
|
|
44
|
+
readonly runId?: string;
|
|
45
|
+
/**
|
|
46
|
+
* The operator's label, when they set one.
|
|
47
|
+
*
|
|
48
|
+
* Used VERBATIM when present: an operator who named their recordings meant
|
|
49
|
+
* that name, and a library that decorated it would be overruling them. The
|
|
50
|
+
* consequence is worth stating — a static label repeats on every run, and
|
|
51
|
+
* what distinguishes two recordings is the ref and `origin.runId`, never the
|
|
52
|
+
* label. With no label the composed one names the run, which is the most
|
|
53
|
+
* useful honest sentence available at mint time.
|
|
54
|
+
*/
|
|
55
|
+
readonly label?: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Raised when a recording could not be turned into bytes.
|
|
59
|
+
*
|
|
60
|
+
* Its own class because the CALLER's answer differs from every other mint
|
|
61
|
+
* failure: a full store is retryable and a cyclic snapshot is not.
|
|
62
|
+
*/
|
|
63
|
+
export declare class UnserializableRecordingError extends Error {
|
|
64
|
+
readonly code: "ERR_UNSERIALIZABLE_RECORDING";
|
|
65
|
+
constructor(detail: string);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Turn one finished recording into the `put` input that stores it.
|
|
69
|
+
*
|
|
70
|
+
* Pure: no store, no events, no agent. The caller owns WHEN this happens (after
|
|
71
|
+
* the answer is composed) and what to do when it fails.
|
|
72
|
+
*
|
|
73
|
+
* @throws UnserializableRecordingError when the recording cannot be
|
|
74
|
+
* JSON-serialized — a cyclic object in a snapshot, most likely.
|
|
75
|
+
*/
|
|
76
|
+
export declare function recordingPutInput(recording: unknown, facts?: RecordingMintFacts): PutArtifactInput;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* artifacts/recordingArtifact — a finished run, checked into the store like any
|
|
3
|
+
* other payload.
|
|
4
|
+
*
|
|
5
|
+
* `recordRun` has produced `{ snapshot, events, structure }` since 8.x and the
|
|
6
|
+
* lens family has consumed exactly that shape since. What nobody shipped was
|
|
7
|
+
* the boring half in between: WHERE a completed run's recording goes so a
|
|
8
|
+
* screen can ask for it later. Every deployment that wanted the Lens over the
|
|
9
|
+
* wire wrote the same twenty lines — record the run, serialize it, put it
|
|
10
|
+
* somewhere with a key, hand the key to the frontend — and each one wrote a
|
|
11
|
+
* slightly different, slightly wrong version of retention and scoping.
|
|
12
|
+
*
|
|
13
|
+
* All four of those problems already have an answer in this package: the
|
|
14
|
+
* artifact store IS a keyed payload store with scope isolation, retention and
|
|
15
|
+
* a read-only wire. So a recording is simply an artifact of kind
|
|
16
|
+
* `'recording/run'`, and the wire ops that already redeem claim tickets serve
|
|
17
|
+
* it with **zero new operations** — `{ op: 'artifact-get', ref }` returns the
|
|
18
|
+
* recording, and the frontend does what it always did with the bytes.
|
|
19
|
+
*
|
|
20
|
+
* ── Why the payload is TEXT and not an object ───────────────────────────────
|
|
21
|
+
* The recording is minted as its JSON text — the same bytes
|
|
22
|
+
* `JSON.stringify(recorder.toRecording())` produces, which is precisely what
|
|
23
|
+
* `observeRecording(JSON.parse(text))` consumes on the viewer side. Two
|
|
24
|
+
* reasons, and both are about not lying:
|
|
25
|
+
*
|
|
26
|
+
* • `recordRun` states that `snapshot` and `structure` are the runner's OWN
|
|
27
|
+
* objects, held by reference. An in-process store handed those would keep
|
|
28
|
+
* a live view into a finished run's state — the artifact would silently
|
|
29
|
+
* change if anything touched it. Serializing detaches it, once, here.
|
|
30
|
+
* • A recording that cannot be serialized cannot be delivered over any wire
|
|
31
|
+
* either, so failing at the mint is failing at the honest moment rather
|
|
32
|
+
* than at whatever reads it next.
|
|
33
|
+
*/
|
|
34
|
+
/** The consumer vocabulary a run recording is stored under. One kind, exact
|
|
35
|
+
* match — the same rule every `wants` declaration is judged by. */
|
|
36
|
+
export const RECORDING_ARTIFACT_KIND = 'recording/run';
|
|
37
|
+
/** The media type a recording is minted with. */
|
|
38
|
+
export const RECORDING_MEDIA_TYPE = 'application/json';
|
|
39
|
+
/**
|
|
40
|
+
* Raised when a recording could not be turned into bytes.
|
|
41
|
+
*
|
|
42
|
+
* Its own class because the CALLER's answer differs from every other mint
|
|
43
|
+
* failure: a full store is retryable and a cyclic snapshot is not.
|
|
44
|
+
*/
|
|
45
|
+
export class UnserializableRecordingError extends Error {
|
|
46
|
+
code = 'ERR_UNSERIALIZABLE_RECORDING';
|
|
47
|
+
constructor(detail) {
|
|
48
|
+
super(`[artifacts] the run recording could not be serialized (${detail}), so it was not ` +
|
|
49
|
+
`stored. A recording that JSON cannot carry could not be delivered over any wire ` +
|
|
50
|
+
`either — this fails at the mint rather than at whatever tried to read it. The run ` +
|
|
51
|
+
`itself is unaffected: its answer was already composed before this was attempted.`);
|
|
52
|
+
this.name = 'UnserializableRecordingError';
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Turn one finished recording into the `put` input that stores it.
|
|
57
|
+
*
|
|
58
|
+
* Pure: no store, no events, no agent. The caller owns WHEN this happens (after
|
|
59
|
+
* the answer is composed) and what to do when it fails.
|
|
60
|
+
*
|
|
61
|
+
* @throws UnserializableRecordingError when the recording cannot be
|
|
62
|
+
* JSON-serialized — a cyclic object in a snapshot, most likely.
|
|
63
|
+
*/
|
|
64
|
+
export function recordingPutInput(recording, facts = {}) {
|
|
65
|
+
let text;
|
|
66
|
+
try {
|
|
67
|
+
text = JSON.stringify(recording) ?? '';
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
throw new UnserializableRecordingError(err instanceof Error ? err.message : String(err));
|
|
71
|
+
}
|
|
72
|
+
if (text === '') {
|
|
73
|
+
throw new UnserializableRecordingError('it serializes to nothing');
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
kind: RECORDING_ARTIFACT_KIND,
|
|
77
|
+
mediaType: RECORDING_MEDIA_TYPE,
|
|
78
|
+
data: text,
|
|
79
|
+
label: facts.label ?? (facts.runId !== undefined ? `run ${facts.runId}` : 'run recording'),
|
|
80
|
+
...(facts.runId !== undefined && { origin: { runId: facts.runId } }),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=recordingArtifact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recordingArtifact.js","sourceRoot":"","sources":["../../../src/artifacts/recordingArtifact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAIH;oEACoE;AACpE,MAAM,CAAC,MAAM,uBAAuB,GAAG,eAAe,CAAC;AAEvD,iDAAiD;AACjD,MAAM,CAAC,MAAM,oBAAoB,GAAG,kBAAkB,CAAC;AAoBvD;;;;;GAKG;AACH,MAAM,OAAO,4BAA6B,SAAQ,KAAK;IAC5C,IAAI,GAAG,8BAAuC,CAAC;IAExD,YAAY,MAAc;QACxB,KAAK,CACH,0DAA0D,MAAM,mBAAmB;YACjF,kFAAkF;YAClF,oFAAoF;YACpF,kFAAkF,CACrF,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,8BAA8B,CAAC;IAC7C,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAC/B,SAAkB,EAClB,QAA4B,EAAE;IAE9B,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IACzC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,4BAA4B,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3F,CAAC;IACD,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;QAChB,MAAM,IAAI,4BAA4B,CAAC,0BAA0B,CAAC,CAAC;IACrE,CAAC;IACD,OAAO;QACL,IAAI,EAAE,uBAAuB;QAC7B,SAAS,EAAE,oBAAoB;QAC/B,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC;QAC1F,GAAG,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;KACrE,CAAC;AACJ,CAAC"}
|