@fevex/core 0.1.0-alpha.4 → 0.1.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +240 -11
- package/dist/agents/index.d.mts +1 -1
- package/dist/artifacts/index.d.mts +2 -0
- package/dist/artifacts/index.mjs +2 -0
- package/dist/artifacts-gUzemET7.mjs +440 -0
- package/dist/channels/index.d.mts +1 -1
- package/dist/evals/index.d.mts +4 -4
- package/dist/fevex-B4QY5Z6e.d.mts +119 -0
- package/dist/http/index.d.mts +65 -5
- package/dist/http/index.mjs +238 -16
- package/dist/{index-C-IFfCNw.d.mts → index-1cHr7KB_.d.mts} +3 -3
- package/dist/{index-CqOjvtQ9.d.mts → index-5p3q2yIp.d.mts} +4 -2
- package/dist/{index-hhbgvfIt.d.mts → index-BJktlD4E.d.mts} +2 -2
- package/dist/{index-CTIwrVf9.d.mts → index-BgKFd9yw.d.mts} +1 -1
- package/dist/{index-dkFyTNh4.d.mts → index-CbACw6xZ.d.mts} +2 -2
- package/dist/index-CpLDt6Rw.d.mts +118 -0
- package/dist/{index-CknU-glw.d.mts → index-CseuTR-F.d.mts} +2 -2
- package/dist/{index-CaE864Kz.d.mts → index-CzAi2Y_Z.d.mts} +45 -6
- package/dist/{index-DyyNLuwO.d.mts → index-DVw0zOc_.d.mts} +3 -3
- package/dist/{index-CrOId2px.d.mts → index-Df84VWmN.d.mts} +1 -1
- package/dist/index.d.mts +13 -13
- package/dist/index.mjs +904 -153
- package/dist/knowledge/index.d.mts +1 -1
- package/dist/model-stream-JQdHDDcj.mjs +131 -0
- package/dist/models/index.d.mts +1 -1
- package/dist/observability/index.d.mts +2 -2
- package/dist/policies/index.d.mts +1 -1
- package/dist/{model-stream-u2xMsEaf.mjs → run-support-CmZ6Xo6H.mjs} +41 -130
- package/dist/runtime/index.d.mts +2 -2
- package/dist/runtime/index.mjs +43 -1
- package/dist/sandbox/index.d.mts +1 -1
- package/dist/sandbox/index.mjs +1 -1
- package/dist/teams/index.d.mts +1 -1
- package/dist/testing/index.d.mts +8 -7
- package/dist/testing/index.mjs +94 -2
- package/dist/tools/index.d.mts +2 -2
- package/dist/types-B8laW1hM.d.mts +561 -0
- package/dist/workflows/index.d.mts +1 -1
- package/package.json +6 -2
- package/dist/fevex-BoPbZ-Tw.d.mts +0 -60
- package/dist/index-voIZhQXB.d.mts +0 -80
- package/dist/types-CuoRx12Q.d.mts +0 -333
package/dist/http/index.mjs
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { o as ArtifactError } from "../artifacts-gUzemET7.mjs";
|
|
1
2
|
import { t as FevexRunError } from "../run-error-Cr17wPGH.mjs";
|
|
3
|
+
import { t as MAX_DEADLINE_MS } from "../run-support-CmZ6Xo6H.mjs";
|
|
2
4
|
//#region src/http/protocol.ts
|
|
3
5
|
const FEVEX_HTTP_PROTOCOL_VERSION = "3";
|
|
4
6
|
const FEVEX_HTTP_PROTOCOL_VERSION_HEADER = "Fevex-Protocol-Version";
|
|
@@ -21,6 +23,8 @@ const FEVEX_RUN_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
|
21
23
|
"CHECKPOINT_UNSUPPORTED",
|
|
22
24
|
"RUN_DEFINITION_CHANGED",
|
|
23
25
|
"POLICY_DENIED",
|
|
26
|
+
"ADMISSION_DENIED",
|
|
27
|
+
"RUNTIME_CLOSED",
|
|
24
28
|
"CREDENTIAL_NOT_FOUND",
|
|
25
29
|
"SANDBOX_REQUIRED",
|
|
26
30
|
"ELICITATION_INVALID",
|
|
@@ -32,69 +36,135 @@ const FEVEX_RUN_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
|
32
36
|
function createFevexHttpHandler(options) {
|
|
33
37
|
const pollIntervalMs = options.pollIntervalMs ?? 100;
|
|
34
38
|
const eventPageSize = options.eventPageSize ?? 100;
|
|
39
|
+
const maxConnections = options.maxConnections;
|
|
35
40
|
if (!Number.isSafeInteger(eventPageSize) || eventPageSize < 1 || eventPageSize > 1e3) throw new TypeError("eventPageSize must be an integer between 1 and 1000");
|
|
36
41
|
if (!Number.isFinite(pollIntervalMs) || pollIntervalMs < 1) throw new TypeError("pollIntervalMs must be a positive number");
|
|
42
|
+
if (maxConnections !== void 0 && (!Number.isSafeInteger(maxConnections) || maxConnections < 1)) throw new TypeError("maxConnections must be a positive safe integer");
|
|
43
|
+
let activeConnections = 0;
|
|
44
|
+
const authorize = async (access) => {
|
|
45
|
+
if (options.authorize && !await options.authorize(access)) throw new HttpProtocolError(403, "FORBIDDEN", "Forbidden");
|
|
46
|
+
};
|
|
47
|
+
const authorizeArtifact = async (access) => {
|
|
48
|
+
if (options.authorizeArtifact && !await options.authorizeArtifact(access)) throw new HttpProtocolError(403, "FORBIDDEN", "Forbidden");
|
|
49
|
+
};
|
|
37
50
|
return async (request, handlerContext = {}) => {
|
|
38
51
|
const url = new URL(request.url);
|
|
39
52
|
const path = url.pathname;
|
|
53
|
+
const commitStart = async (run) => {
|
|
54
|
+
try {
|
|
55
|
+
await options.onRunStarted?.(run, handlerContext.context);
|
|
56
|
+
} catch (error) {
|
|
57
|
+
await options.fevex.cancelRun(run.id).catch(() => {});
|
|
58
|
+
throw error;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
40
61
|
try {
|
|
41
62
|
const start = path.match(/^\/v1\/agents\/([^/]+)\/runs$/);
|
|
42
63
|
if (start && request.method === "POST") {
|
|
43
64
|
const body = await readJson(request);
|
|
44
65
|
if (!hasOwn(body, "input")) throw badRequest("input is required");
|
|
66
|
+
const name = decodeURIComponent(start[1]);
|
|
45
67
|
const sessionId = optionalId(body.sessionId, "sessionId");
|
|
46
68
|
const model = optionalId(body.model, "model");
|
|
47
69
|
const reasoning = optionalReasoning(body.reasoning);
|
|
48
|
-
|
|
70
|
+
const deadlineMs = optionalDeadline(body.deadlineMs, "deadlineMs");
|
|
71
|
+
await authorize({
|
|
72
|
+
action: "start",
|
|
73
|
+
kind: "agent",
|
|
74
|
+
name,
|
|
75
|
+
sessionId,
|
|
76
|
+
context: handlerContext.context
|
|
77
|
+
});
|
|
78
|
+
const run = await options.fevex.startAgent(name, {
|
|
49
79
|
input: body.input,
|
|
50
80
|
...model ? { model } : {},
|
|
51
81
|
...reasoning === void 0 ? {} : { reasoning },
|
|
82
|
+
...deadlineMs === void 0 ? {} : { deadlineMs },
|
|
52
83
|
...sessionId ? { sessionId } : {},
|
|
53
84
|
...handlerContext.context ? { context: handlerContext.context } : {}
|
|
54
|
-
})
|
|
85
|
+
});
|
|
86
|
+
await commitStart(run);
|
|
87
|
+
return json(run, 202);
|
|
55
88
|
}
|
|
56
89
|
const startWorkflow = path.match(/^\/v1\/workflows\/([^/]+)\/runs$/);
|
|
57
90
|
if (startWorkflow && request.method === "POST") {
|
|
58
91
|
const body = await readJson(request);
|
|
59
92
|
if (!hasOwn(body, "input")) throw badRequest("input is required");
|
|
93
|
+
const name = decodeURIComponent(startWorkflow[1]);
|
|
60
94
|
const sessionId = optionalId(body.sessionId, "sessionId");
|
|
61
95
|
const model = optionalId(body.model, "model");
|
|
62
96
|
const reasoning = optionalReasoning(body.reasoning);
|
|
63
|
-
|
|
97
|
+
const deadlineMs = optionalDeadline(body.deadlineMs, "deadlineMs");
|
|
98
|
+
await authorize({
|
|
99
|
+
action: "start",
|
|
100
|
+
kind: "workflow",
|
|
101
|
+
name,
|
|
102
|
+
sessionId,
|
|
103
|
+
context: handlerContext.context
|
|
104
|
+
});
|
|
105
|
+
const run = await options.fevex.startWorkflow(name, {
|
|
64
106
|
input: body.input,
|
|
65
107
|
...model ? { model } : {},
|
|
66
108
|
...reasoning === void 0 ? {} : { reasoning },
|
|
109
|
+
...deadlineMs === void 0 ? {} : { deadlineMs },
|
|
67
110
|
...sessionId ? { sessionId } : {},
|
|
68
111
|
...handlerContext.context ? { context: handlerContext.context } : {}
|
|
69
|
-
})
|
|
112
|
+
});
|
|
113
|
+
await commitStart(run);
|
|
114
|
+
return json(run, 202);
|
|
70
115
|
}
|
|
71
116
|
const startTeam = path.match(/^\/v1\/teams\/([^/]+)\/runs$/);
|
|
72
117
|
if (startTeam && request.method === "POST") {
|
|
73
118
|
const body = await readJson(request);
|
|
74
119
|
if (!hasOwn(body, "input")) throw badRequest("Run input is required");
|
|
120
|
+
const name = decodeURIComponent(startTeam[1]);
|
|
75
121
|
const sessionId = optionalId(body.sessionId, "sessionId");
|
|
76
122
|
const model = optionalId(body.model, "model");
|
|
77
123
|
const reasoning = optionalReasoning(body.reasoning);
|
|
78
|
-
|
|
124
|
+
const deadlineMs = optionalDeadline(body.deadlineMs, "deadlineMs");
|
|
125
|
+
await authorize({
|
|
126
|
+
action: "start",
|
|
127
|
+
kind: "team",
|
|
128
|
+
name,
|
|
129
|
+
sessionId,
|
|
130
|
+
context: handlerContext.context
|
|
131
|
+
});
|
|
132
|
+
const run = await options.fevex.startTeam(name, {
|
|
79
133
|
input: body.input,
|
|
80
134
|
...model ? { model } : {},
|
|
81
135
|
...reasoning === void 0 ? {} : { reasoning },
|
|
136
|
+
...deadlineMs === void 0 ? {} : { deadlineMs },
|
|
82
137
|
...sessionId ? { sessionId } : {},
|
|
83
138
|
...handlerContext.context ? { context: handlerContext.context } : {}
|
|
84
|
-
})
|
|
139
|
+
});
|
|
140
|
+
await commitStart(run);
|
|
141
|
+
return json(run, 202);
|
|
85
142
|
}
|
|
86
143
|
const events = path.match(/^\/v1\/runs\/([^/]+)\/events$/);
|
|
87
144
|
if (events && request.method === "GET") {
|
|
88
145
|
const runId = decodeURIComponent(events[1]);
|
|
146
|
+
await authorize({
|
|
147
|
+
action: "observe",
|
|
148
|
+
runId,
|
|
149
|
+
context: handlerContext.context
|
|
150
|
+
});
|
|
89
151
|
if (!await options.fevex.getRun(runId)) throw notFound("RUN_NOT_FOUND", "Run not found");
|
|
90
152
|
const after = request.headers.get("last-event-id")?.trim() || void 0;
|
|
91
153
|
const initial = await options.fevex.listEvents(runId, {
|
|
92
154
|
after,
|
|
93
155
|
limit: eventPageSize
|
|
94
156
|
});
|
|
157
|
+
if (maxConnections !== void 0 && activeConnections >= maxConnections) throw new HttpProtocolError(429, "CONNECTION_LIMIT", "Too many event streams");
|
|
158
|
+
activeConnections += 1;
|
|
159
|
+
let released = false;
|
|
160
|
+
const release = () => {
|
|
161
|
+
if (released) return;
|
|
162
|
+
released = true;
|
|
163
|
+
activeConnections -= 1;
|
|
164
|
+
};
|
|
95
165
|
const disconnected = new AbortController();
|
|
96
166
|
const iterator = observeEvents(options.fevex, runId, initial, after, pollIntervalMs, AbortSignal.any([request.signal, disconnected.signal]), eventPageSize);
|
|
97
|
-
return versioned(new Response(iteratorStream(iterator, () => disconnected.abort()), { headers: {
|
|
167
|
+
return versioned(new Response(iteratorStream(iterator, () => disconnected.abort(), release), { headers: {
|
|
98
168
|
"content-type": `${SSE_TYPE}; charset=utf-8`,
|
|
99
169
|
"cache-control": "no-cache, no-transform"
|
|
100
170
|
} }));
|
|
@@ -102,28 +172,99 @@ function createFevexHttpHandler(options) {
|
|
|
102
172
|
const resume = path.match(/^\/v1\/runs\/([^/]+)\/resume$/);
|
|
103
173
|
if (resume && request.method === "POST") {
|
|
104
174
|
const runId = decodeURIComponent(resume[1]);
|
|
105
|
-
if (!await options.fevex.getRun(runId)) throw notFound("RUN_NOT_FOUND", "Run not found");
|
|
106
175
|
const actor = handlerContext.context?.actor;
|
|
107
176
|
if (!actor?.id?.trim()) throw new HttpProtocolError(401, "ACTOR_REQUIRED", "Authenticated actor is required");
|
|
177
|
+
await authorize({
|
|
178
|
+
action: "resume",
|
|
179
|
+
runId,
|
|
180
|
+
context: handlerContext.context
|
|
181
|
+
});
|
|
182
|
+
if (!await options.fevex.getRun(runId)) throw notFound("RUN_NOT_FOUND", "Run not found");
|
|
108
183
|
const resolution = readResolution(await readJson(request), actor);
|
|
109
184
|
return json(await options.fevex.resumeRun(runId, resolution), 202);
|
|
110
185
|
}
|
|
111
186
|
const recover = path.match(/^\/v1\/runs\/([^/]+)\/recover$/);
|
|
112
187
|
if (recover && request.method === "POST") {
|
|
113
188
|
const runId = decodeURIComponent(recover[1]);
|
|
114
|
-
if (!await options.fevex.getRun(runId)) throw notFound("RUN_NOT_FOUND", "Run not found");
|
|
115
189
|
const actor = handlerContext.context?.actor;
|
|
116
190
|
if (!actor?.id?.trim()) throw new HttpProtocolError(401, "ACTOR_REQUIRED", "Authenticated actor is required");
|
|
191
|
+
await authorize({
|
|
192
|
+
action: "recover",
|
|
193
|
+
runId,
|
|
194
|
+
context: handlerContext.context
|
|
195
|
+
});
|
|
196
|
+
if (!await options.fevex.getRun(runId)) throw notFound("RUN_NOT_FOUND", "Run not found");
|
|
117
197
|
return json(await options.fevex.recoverRun(runId, { actor }), 202);
|
|
118
198
|
}
|
|
199
|
+
const runArtifacts = path.match(/^\/v1\/runs\/([^/]+)\/artifacts$/);
|
|
200
|
+
if (runArtifacts && request.method === "GET") {
|
|
201
|
+
const runId = decodeURIComponent(runArtifacts[1]);
|
|
202
|
+
await authorizeArtifact({
|
|
203
|
+
action: "read",
|
|
204
|
+
kind: "artifacts",
|
|
205
|
+
runId,
|
|
206
|
+
context: handlerContext.context
|
|
207
|
+
});
|
|
208
|
+
if (!options.artifactCatalog) throw new HttpProtocolError(501, "ARTIFACT_CATALOG_NOT_CONFIGURED", "Artifact catalog is not configured");
|
|
209
|
+
if (!await options.fevex.getRun(runId)) throw notFound("RUN_NOT_FOUND", "Run not found");
|
|
210
|
+
const limit = optionalLimit(url.searchParams.get("limit"));
|
|
211
|
+
return json((await options.artifactCatalog.list({
|
|
212
|
+
runId,
|
|
213
|
+
...limit === void 0 ? {} : { limit }
|
|
214
|
+
}, artifactContext(handlerContext, request))).map(({ descriptor }) => descriptor));
|
|
215
|
+
}
|
|
216
|
+
const artifactRoute = path.match(/^\/v1\/artifacts\/([^/]+)$/);
|
|
217
|
+
if (artifactRoute && (request.method === "GET" || request.method === "HEAD")) {
|
|
218
|
+
const artifactId = decodeURIComponent(artifactRoute[1]);
|
|
219
|
+
await authorizeArtifact({
|
|
220
|
+
action: "read",
|
|
221
|
+
kind: "artifact",
|
|
222
|
+
artifactId,
|
|
223
|
+
context: handlerContext.context
|
|
224
|
+
});
|
|
225
|
+
if (!options.artifacts) throw new HttpProtocolError(501, "ARTIFACTS_NOT_CONFIGURED", "Artifact store is not configured");
|
|
226
|
+
const context = artifactContext(handlerContext, request);
|
|
227
|
+
if (request.method === "HEAD" && options.artifacts.head) {
|
|
228
|
+
const descriptor = await options.artifacts.head(artifactId, context);
|
|
229
|
+
if (!descriptor) throw notFound("ARTIFACT_NOT_FOUND", "Artifact not found");
|
|
230
|
+
return artifactResponse(descriptor, null);
|
|
231
|
+
}
|
|
232
|
+
const content = await options.artifacts.get(artifactId, context);
|
|
233
|
+
if (!content) throw notFound("ARTIFACT_NOT_FOUND", "Artifact not found");
|
|
234
|
+
return artifactResponse(content.descriptor, request.method === "HEAD" ? null : content.bytes);
|
|
235
|
+
}
|
|
236
|
+
if (artifactRoute && request.method === "DELETE") {
|
|
237
|
+
const artifactId = decodeURIComponent(artifactRoute[1]);
|
|
238
|
+
await authorizeArtifact({
|
|
239
|
+
action: "delete",
|
|
240
|
+
kind: "artifact",
|
|
241
|
+
artifactId,
|
|
242
|
+
context: handlerContext.context
|
|
243
|
+
});
|
|
244
|
+
if (!options.artifacts) throw new HttpProtocolError(501, "ARTIFACTS_NOT_CONFIGURED", "Artifact store is not configured");
|
|
245
|
+
if (!options.artifacts.delete) throw new HttpProtocolError(501, "ARTIFACT_DELETE_UNSUPPORTED", "Artifact store does not support deletion");
|
|
246
|
+
if (!await options.artifacts.delete(artifactId, artifactContext(handlerContext, request))) throw notFound("ARTIFACT_NOT_FOUND", "Artifact not found");
|
|
247
|
+
return versioned(new Response(null, { status: 204 }));
|
|
248
|
+
}
|
|
119
249
|
const run = path.match(/^\/v1\/runs\/([^/]+)$/);
|
|
120
250
|
if (run && request.method === "GET") {
|
|
121
|
-
const
|
|
251
|
+
const runId = decodeURIComponent(run[1]);
|
|
252
|
+
await authorize({
|
|
253
|
+
action: "read",
|
|
254
|
+
runId,
|
|
255
|
+
context: handlerContext.context
|
|
256
|
+
});
|
|
257
|
+
const value = await options.fevex.getRun(runId);
|
|
122
258
|
if (!value) throw notFound("RUN_NOT_FOUND", "Run not found");
|
|
123
259
|
return json(value);
|
|
124
260
|
}
|
|
125
261
|
if (run && request.method === "DELETE") {
|
|
126
262
|
const runId = decodeURIComponent(run[1]);
|
|
263
|
+
await authorize({
|
|
264
|
+
action: "cancel",
|
|
265
|
+
runId,
|
|
266
|
+
context: handlerContext.context
|
|
267
|
+
});
|
|
127
268
|
const value = await options.fevex.getRun(runId);
|
|
128
269
|
if (!value) throw notFound("RUN_NOT_FOUND", "Run not found");
|
|
129
270
|
if (value.status === "running" || value.status === "paused") {
|
|
@@ -131,7 +272,7 @@ function createFevexHttpHandler(options) {
|
|
|
131
272
|
}
|
|
132
273
|
return versioned(new Response(null, { status: 204 }));
|
|
133
274
|
}
|
|
134
|
-
if (start || startWorkflow || startTeam || events || resume || recover || run) throw new HttpProtocolError(405, "METHOD_NOT_ALLOWED", "Method not allowed");
|
|
275
|
+
if (start || startWorkflow || startTeam || events || resume || recover || runArtifacts || artifactRoute || run) throw new HttpProtocolError(405, "METHOD_NOT_ALLOWED", "Method not allowed");
|
|
135
276
|
throw notFound("ROUTE_NOT_FOUND", "Route not found");
|
|
136
277
|
} catch (error) {
|
|
137
278
|
return problem(error, url.pathname, options.onError);
|
|
@@ -192,6 +333,17 @@ function createFevexHttpClient(options) {
|
|
|
192
333
|
},
|
|
193
334
|
async cancelRun(runId) {
|
|
194
335
|
await assertResponse(await fetcher(`${baseUrl}/v1/runs/${encodeURIComponent(runId)}`, { method: "DELETE" }));
|
|
336
|
+
},
|
|
337
|
+
async getArtifact(artifactId) {
|
|
338
|
+
const response = await fetcher(`${baseUrl}/v1/artifacts/${encodeURIComponent(artifactId)}`);
|
|
339
|
+
await assertResponse(response);
|
|
340
|
+
return response;
|
|
341
|
+
},
|
|
342
|
+
listArtifacts(runId) {
|
|
343
|
+
return request(`/v1/runs/${encodeURIComponent(runId)}/artifacts`);
|
|
344
|
+
},
|
|
345
|
+
async deleteArtifact(artifactId) {
|
|
346
|
+
await assertResponse(await fetcher(`${baseUrl}/v1/artifacts/${encodeURIComponent(artifactId)}`, { method: "DELETE" }));
|
|
195
347
|
}
|
|
196
348
|
};
|
|
197
349
|
}
|
|
@@ -220,18 +372,28 @@ async function* observeEvents(fevex, runId, initial, after, pollIntervalMs, sign
|
|
|
220
372
|
});
|
|
221
373
|
}
|
|
222
374
|
}
|
|
223
|
-
function iteratorStream(iterator, cancel) {
|
|
375
|
+
function iteratorStream(iterator, cancel, done) {
|
|
376
|
+
let finished = false;
|
|
377
|
+
const finish = () => {
|
|
378
|
+
if (finished) return;
|
|
379
|
+
finished = true;
|
|
380
|
+
done?.();
|
|
381
|
+
};
|
|
224
382
|
return new ReadableStream({
|
|
225
383
|
async pull(controller) {
|
|
226
384
|
try {
|
|
227
385
|
const next = await iterator.next();
|
|
228
|
-
if (next.done)
|
|
229
|
-
|
|
386
|
+
if (next.done) {
|
|
387
|
+
finish();
|
|
388
|
+
controller.close();
|
|
389
|
+
} else controller.enqueue(next.value);
|
|
230
390
|
} catch (error) {
|
|
391
|
+
finish();
|
|
231
392
|
controller.error(error);
|
|
232
393
|
}
|
|
233
394
|
},
|
|
234
395
|
async cancel() {
|
|
396
|
+
finish();
|
|
235
397
|
cancel();
|
|
236
398
|
await iterator.return(void 0);
|
|
237
399
|
}
|
|
@@ -280,6 +442,37 @@ function findBoundary(value) {
|
|
|
280
442
|
function formatEvent(event) {
|
|
281
443
|
return `id: ${event.id}\nevent: ${event.type}\ndata: ${JSON.stringify(event)}\n\n`;
|
|
282
444
|
}
|
|
445
|
+
function artifactContext(handlerContext, request) {
|
|
446
|
+
const tenantId = handlerContext.context?.attributes?.tenantId;
|
|
447
|
+
if (tenantId !== void 0 && typeof tenantId !== "string") throw badRequest("tenantId attribute must be a string");
|
|
448
|
+
const actor = handlerContext.context?.actor;
|
|
449
|
+
return {
|
|
450
|
+
...typeof tenantId === "string" ? { tenantId } : {},
|
|
451
|
+
...actor === void 0 ? {} : { actor },
|
|
452
|
+
signal: request.signal
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
function optionalLimit(value) {
|
|
456
|
+
if (value === null) return void 0;
|
|
457
|
+
const parsed = Number(value);
|
|
458
|
+
if (!Number.isSafeInteger(parsed) || parsed < 1) throw badRequest("limit must be a positive integer");
|
|
459
|
+
return parsed;
|
|
460
|
+
}
|
|
461
|
+
function artifactResponse(descriptor, bytes) {
|
|
462
|
+
return versioned(new Response(bytes === null ? null : bytes.slice().buffer, { headers: {
|
|
463
|
+
"content-type": descriptor.mimeType,
|
|
464
|
+
"content-length": String(descriptor.size),
|
|
465
|
+
"content-disposition": contentDisposition(descriptor.filename),
|
|
466
|
+
"cache-control": "private, max-age=0, must-revalidate",
|
|
467
|
+
etag: `"${descriptor.sha256}"`,
|
|
468
|
+
"x-content-type-options": "nosniff",
|
|
469
|
+
"fevex-artifact-id": descriptor.artifactId,
|
|
470
|
+
"fevex-artifact-sha256": descriptor.sha256
|
|
471
|
+
} }));
|
|
472
|
+
}
|
|
473
|
+
function contentDisposition(filename) {
|
|
474
|
+
return `attachment; filename="${filename.replace(/[^\x20-\x7e]/gu, "_").replace(/["\\]/gu, "_")}"; filename*=UTF-8''${encodeURIComponent(filename).replace(/'/gu, "%27")}`;
|
|
475
|
+
}
|
|
283
476
|
function readResolution(body, actor) {
|
|
284
477
|
if (body.type === "elicitation" && typeof body.requestId === "string" && body.requestId.trim() && hasOwn(body, "value")) return {
|
|
285
478
|
type: "elicitation",
|
|
@@ -334,6 +527,16 @@ function optionalId(value, name) {
|
|
|
334
527
|
if (typeof value !== "string" || !value.trim()) throw badRequest(`${name} must be a string`);
|
|
335
528
|
return value.trim();
|
|
336
529
|
}
|
|
530
|
+
function optionalPositiveInteger(value, name) {
|
|
531
|
+
if (value === void 0) return void 0;
|
|
532
|
+
if (!Number.isSafeInteger(value) || value < 1) throw badRequest(`${name} must be a positive integer`);
|
|
533
|
+
return value;
|
|
534
|
+
}
|
|
535
|
+
function optionalDeadline(value, name) {
|
|
536
|
+
const deadlineMs = optionalPositiveInteger(value, name);
|
|
537
|
+
if (deadlineMs !== void 0 && deadlineMs > 2147483647) throw badRequest(`${name} must be at most ${MAX_DEADLINE_MS}`);
|
|
538
|
+
return deadlineMs;
|
|
539
|
+
}
|
|
337
540
|
function optionalReasoning(value) {
|
|
338
541
|
if (value === void 0) return void 0;
|
|
339
542
|
if (typeof value !== "string" || ![
|
|
@@ -408,6 +611,11 @@ function problem(error, instance, onError) {
|
|
|
408
611
|
({status, code} = error);
|
|
409
612
|
title = error.message;
|
|
410
613
|
detail = error.message;
|
|
614
|
+
} else if (error instanceof ArtifactError) {
|
|
615
|
+
code = error.code;
|
|
616
|
+
status = statusForArtifactErrorCode(error.code);
|
|
617
|
+
title = titleForStatus(status);
|
|
618
|
+
detail = error.message;
|
|
411
619
|
} else {
|
|
412
620
|
const runError = readFevexRunError(error);
|
|
413
621
|
if (runError) {
|
|
@@ -446,13 +654,27 @@ function statusForRunErrorCode(code) {
|
|
|
446
654
|
if (code === "AGENT_NOT_FOUND" || code === "WORKFLOW_NOT_FOUND" || code === "TEAM_NOT_FOUND" || code === "SESSION_NOT_FOUND") return 404;
|
|
447
655
|
if (code === "APPROVAL_INVALID" || code === "INVALID_CURSOR") return 400;
|
|
448
656
|
if (code === "POLICY_DENIED") return 403;
|
|
657
|
+
if (code === "ADMISSION_DENIED") return 429;
|
|
658
|
+
if (code === "RUNTIME_CLOSED") return 503;
|
|
449
659
|
return 409;
|
|
450
660
|
}
|
|
661
|
+
function statusForArtifactErrorCode(code) {
|
|
662
|
+
if (code === "ARTIFACT_INVALID_ID" || code === "ARTIFACT_INVALID_INPUT" || code === "ARTIFACT_INVALID_CONTEXT") return 400;
|
|
663
|
+
if (code === "ARTIFACT_TOO_LARGE") return 413;
|
|
664
|
+
if (code === "ARTIFACT_MIME_UNSUPPORTED") return 415;
|
|
665
|
+
if (code === "ARTIFACT_CONFLICT") return 409;
|
|
666
|
+
return 500;
|
|
667
|
+
}
|
|
451
668
|
function titleForStatus(status) {
|
|
452
|
-
if (status === 404) return "Not Found";
|
|
453
669
|
if (status === 400) return "Bad Request";
|
|
454
670
|
if (status === 403) return "Forbidden";
|
|
455
|
-
return "
|
|
671
|
+
if (status === 404) return "Not Found";
|
|
672
|
+
if (status === 409) return "Conflict";
|
|
673
|
+
if (status === 413) return "Payload Too Large";
|
|
674
|
+
if (status === 415) return "Unsupported Media Type";
|
|
675
|
+
if (status === 429) return "Too Many Requests";
|
|
676
|
+
if (status === 501) return "Not Implemented";
|
|
677
|
+
return "Internal Server Error";
|
|
456
678
|
}
|
|
457
679
|
function wait(ms, signal) {
|
|
458
680
|
return new Promise((resolve) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as ExactDefinition } from "./exact-definition-NHBBFlFR.mjs";
|
|
2
|
-
import { o as ExecutionContext } from "./types-
|
|
3
|
-
import { n as AgentLimits } from "./index-
|
|
4
|
-
import { t as WorkflowAgentResult } from "./index-
|
|
2
|
+
import { o as ExecutionContext } from "./types-B8laW1hM.mjs";
|
|
3
|
+
import { n as AgentLimits } from "./index-CzAi2Y_Z.mjs";
|
|
4
|
+
import { t as WorkflowAgentResult } from "./index-CseuTR-F.mjs";
|
|
5
5
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
6
6
|
//#region src/teams/team.d.ts
|
|
7
7
|
interface TeamMember {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as ExactDefinition } from "./exact-definition-NHBBFlFR.mjs";
|
|
2
|
-
import { f as RunId, g as ToolSpec, h as ToolEventSource, l as JsonValue, o as ExecutionContext, s as JsonObject } from "./types-
|
|
3
|
-
import { i as SandboxCapabilities, r as Sandbox } from "./index-
|
|
2
|
+
import { F as ArtifactStore, f as RunId, g as ToolSpec, h as ToolEventSource, l as JsonValue, o as ExecutionContext, s as JsonObject } from "./types-B8laW1hM.mjs";
|
|
3
|
+
import { i as SandboxCapabilities, r as Sandbox } from "./index-Df84VWmN.mjs";
|
|
4
4
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
5
5
|
//#region src/tools/tool.d.ts
|
|
6
6
|
interface ToolExecutionContext {
|
|
@@ -10,6 +10,8 @@ interface ToolExecutionContext {
|
|
|
10
10
|
idempotencyKey: string;
|
|
11
11
|
getCredential(name: string): Promise<string>;
|
|
12
12
|
sandbox?: Sandbox;
|
|
13
|
+
/** Optional artifact store; writes emit `artifact.created`. */
|
|
14
|
+
artifacts?: ArtifactStore;
|
|
13
15
|
context?: ExecutionContext;
|
|
14
16
|
signal?: AbortSignal;
|
|
15
17
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { l as JsonValue, o as ExecutionContext, s as JsonObject } from "./types-
|
|
2
|
-
import {
|
|
1
|
+
import { l as JsonValue, o as ExecutionContext, s as JsonObject } from "./types-B8laW1hM.mjs";
|
|
2
|
+
import { L as SessionId } from "./index-CzAi2Y_Z.mjs";
|
|
3
3
|
//#region src/knowledge/knowledge.d.ts
|
|
4
4
|
/** Runtime context supplied to knowledge providers and memory stores. */
|
|
5
5
|
interface KnowledgeContext {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { g as ToolSpec, i as AgentMessage, l as JsonValue, m as ToolCall, s as JsonObject } from "./types-
|
|
1
|
+
import { g as ToolSpec, i as AgentMessage, l as JsonValue, m as ToolCall, s as JsonObject } from "./types-B8laW1hM.mjs";
|
|
2
2
|
//#region src/models/model.d.ts
|
|
3
3
|
/** Provider-neutral reasoning levels accepted by model gateways. */
|
|
4
4
|
type ReasoningEffort = 'provider-default' | 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { f as RunId, l as JsonValue, o as ExecutionContext } from "./types-
|
|
2
|
-
import { x as ToolRisk } from "./index-
|
|
1
|
+
import { f as RunId, l as JsonValue, o as ExecutionContext } from "./types-B8laW1hM.mjs";
|
|
2
|
+
import { x as ToolRisk } from "./index-5p3q2yIp.mjs";
|
|
3
3
|
//#region src/policies/policy.d.ts
|
|
4
4
|
/** Authorization outcome returned by a policy. */
|
|
5
5
|
type PolicyDecision = 'allow' | 'deny' | 'require_approval';
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { f as RunId, l as JsonValue, s as JsonObject } from "./types-B8laW1hM.mjs";
|
|
2
|
+
import { r as ModelMetadata, s as ModelUsage } from "./index-BgKFd9yw.mjs";
|
|
3
|
+
import { L as SessionId } from "./index-CzAi2Y_Z.mjs";
|
|
4
|
+
//#region src/observability/trace.d.ts
|
|
5
|
+
/** Final state represented by an exported run trace. */
|
|
6
|
+
type TraceStatus = 'completed' | 'failed' | 'cancelled';
|
|
7
|
+
/** Kind of run that produced a trace. Absent means `agent` for older traces. */
|
|
8
|
+
type TraceRunKind = 'agent' | 'workflow' | 'team';
|
|
9
|
+
/** Model and tool calls are agent spans; steps belong to workflow and team traces. */
|
|
10
|
+
type TraceSpanKind = 'model' | 'tool' | 'step';
|
|
11
|
+
type TraceContentKind = 'run.output' | 'model.output' | 'error.message';
|
|
12
|
+
interface TraceCost {
|
|
13
|
+
amount: number;
|
|
14
|
+
currency: string;
|
|
15
|
+
}
|
|
16
|
+
interface TraceContent {
|
|
17
|
+
kind: TraceContentKind;
|
|
18
|
+
value: JsonValue;
|
|
19
|
+
}
|
|
20
|
+
interface TraceAnnotation {
|
|
21
|
+
name: string;
|
|
22
|
+
timestamp: string;
|
|
23
|
+
attributes?: JsonObject;
|
|
24
|
+
}
|
|
25
|
+
interface TraceSpan {
|
|
26
|
+
id: string;
|
|
27
|
+
/** Run or span that contains this span. */
|
|
28
|
+
parentId: string;
|
|
29
|
+
kind: TraceSpanKind;
|
|
30
|
+
name: string;
|
|
31
|
+
startedAt: string;
|
|
32
|
+
endedAt: string;
|
|
33
|
+
durationMs: number;
|
|
34
|
+
status: TraceStatus;
|
|
35
|
+
attributes: JsonObject;
|
|
36
|
+
annotations: TraceAnnotation[];
|
|
37
|
+
usage?: ModelUsage;
|
|
38
|
+
cost?: TraceCost;
|
|
39
|
+
content?: TraceContent[];
|
|
40
|
+
}
|
|
41
|
+
interface RunTrace {
|
|
42
|
+
schemaVersion: '1';
|
|
43
|
+
/** Absent on traces produced before coordinator traces existed; treat as `agent`. */
|
|
44
|
+
kind?: TraceRunKind;
|
|
45
|
+
traceId: string;
|
|
46
|
+
runId: RunId;
|
|
47
|
+
sessionId: SessionId;
|
|
48
|
+
/** Agent, workflow or team name. */
|
|
49
|
+
agentName: string;
|
|
50
|
+
/** Run that created this one, when it belongs to a workflow or team. */
|
|
51
|
+
parentRunId?: RunId;
|
|
52
|
+
/** Top-level run in the correlation tree. Defaults to `runId`. */
|
|
53
|
+
rootRunId?: RunId;
|
|
54
|
+
/** Only present on agent traces. */
|
|
55
|
+
modelRegistryName?: string;
|
|
56
|
+
model?: ModelMetadata;
|
|
57
|
+
startedAt: string;
|
|
58
|
+
endedAt: string;
|
|
59
|
+
durationMs: number;
|
|
60
|
+
status: TraceStatus;
|
|
61
|
+
attributes: JsonObject;
|
|
62
|
+
annotations: TraceAnnotation[];
|
|
63
|
+
spans: TraceSpan[];
|
|
64
|
+
usage?: ModelUsage;
|
|
65
|
+
cost?: TraceCost;
|
|
66
|
+
content?: TraceContent[];
|
|
67
|
+
}
|
|
68
|
+
interface CostCalculatorInput {
|
|
69
|
+
modelRegistryName: string;
|
|
70
|
+
model?: ModelMetadata;
|
|
71
|
+
usage: ModelUsage;
|
|
72
|
+
}
|
|
73
|
+
type CostCalculator = (input: CostCalculatorInput) => TraceCost | undefined;
|
|
74
|
+
interface TraceRedactorInput {
|
|
75
|
+
kind: TraceContentKind;
|
|
76
|
+
value: JsonValue;
|
|
77
|
+
}
|
|
78
|
+
type TraceRedactor = (input: TraceRedactorInput) => JsonValue | undefined;
|
|
79
|
+
interface TraceContentPolicy {
|
|
80
|
+
include: readonly TraceContentKind[];
|
|
81
|
+
redact?: TraceRedactor;
|
|
82
|
+
}
|
|
83
|
+
interface TraceExporter {
|
|
84
|
+
export(trace: Readonly<RunTrace>): void | Promise<void>;
|
|
85
|
+
}
|
|
86
|
+
interface TraceExportQueueOptions {
|
|
87
|
+
/** Traces exported at once. Defaults to 4. */
|
|
88
|
+
concurrency?: number;
|
|
89
|
+
/** Traces waiting for an export slot before new traces are dropped. Defaults to 100. */
|
|
90
|
+
maxQueued?: number;
|
|
91
|
+
/** Deadline for each exporter call. Defaults to 30 seconds. */
|
|
92
|
+
timeoutMs?: number;
|
|
93
|
+
/** Failures retained for the next `flushObservability` call. Defaults to 100. */
|
|
94
|
+
maxFailures?: number;
|
|
95
|
+
}
|
|
96
|
+
/** Queue and failure counters for the runtime's trace exporters. */
|
|
97
|
+
interface ObservabilityStats {
|
|
98
|
+
/** Traces exported successfully since the runtime started. */
|
|
99
|
+
exported: number;
|
|
100
|
+
/** Failed exports and dropped traces since the runtime started. */
|
|
101
|
+
failed: number;
|
|
102
|
+
/** Traces dropped because the queue was full. */
|
|
103
|
+
dropped: number;
|
|
104
|
+
/** Traces waiting for an export slot. */
|
|
105
|
+
queued: number;
|
|
106
|
+
/** Traces currently being exported. */
|
|
107
|
+
active: number;
|
|
108
|
+
/** Failures retained for the next flush. */
|
|
109
|
+
retainedFailures: number;
|
|
110
|
+
}
|
|
111
|
+
interface ObservabilityOptions {
|
|
112
|
+
exporters: readonly TraceExporter[];
|
|
113
|
+
calculateCost?: CostCalculator;
|
|
114
|
+
content?: TraceContentPolicy;
|
|
115
|
+
exportQueue?: TraceExportQueueOptions;
|
|
116
|
+
}
|
|
117
|
+
//#endregion
|
|
118
|
+
export { TraceSpanKind as _, RunTrace as a, TraceContentKind as c, TraceExportQueueOptions as d, TraceExporter as f, TraceSpan as g, TraceRunKind as h, ObservabilityStats as i, TraceContentPolicy as l, TraceRedactorInput as m, CostCalculatorInput as n, TraceAnnotation as o, TraceRedactor as p, ObservabilityOptions as r, TraceContent as s, CostCalculator as t, TraceCost as u, TraceStatus as v };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as ExactDefinition } from "./exact-definition-NHBBFlFR.mjs";
|
|
2
|
-
import { f as RunId, l as JsonValue, o as ExecutionContext, s as JsonObject } from "./types-
|
|
3
|
-
import {
|
|
2
|
+
import { f as RunId, l as JsonValue, o as ExecutionContext, s as JsonObject } from "./types-B8laW1hM.mjs";
|
|
3
|
+
import { L as SessionId, M as RunRequest, N as RunResult, n as AgentLimits } from "./index-CzAi2Y_Z.mjs";
|
|
4
4
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
5
5
|
//#region src/workflows/workflow.d.ts
|
|
6
6
|
/** Context shared with workflow steps and compensation handlers. */
|