@fevex/core 0.1.0-alpha.3 → 0.1.0-alpha.5

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 (41) hide show
  1. package/README.md +183 -2
  2. package/dist/agents/index.d.mts +1 -1
  3. package/dist/artifacts/index.d.mts +2 -0
  4. package/dist/artifacts/index.mjs +2 -0
  5. package/dist/artifacts-gUzemET7.mjs +440 -0
  6. package/dist/channels/index.d.mts +2 -2
  7. package/dist/channels/index.mjs +70 -28
  8. package/dist/evals/index.d.mts +4 -4
  9. package/dist/{fevex-Ddyi6z6L.d.mts → fevex-B5NxFKcV.d.mts} +41 -11
  10. package/dist/http/index.d.mts +65 -5
  11. package/dist/http/index.mjs +236 -16
  12. package/dist/{index-Bgcxgy66.d.mts → index--_LdSEuF.d.mts} +31 -10
  13. package/dist/{index-CrOId2px.d.mts → index-BFnWUu7j.d.mts} +1 -1
  14. package/dist/{index-CTIwrVf9.d.mts → index-BPwkgdo3.d.mts} +1 -1
  15. package/dist/{index-DviHtsLo.d.mts → index-Br-zPxZH.d.mts} +2 -2
  16. package/dist/{index-Dx_LotWZ.d.mts → index-CGmHXV31.d.mts} +38 -3
  17. package/dist/{index-CqOjvtQ9.d.mts → index-CKQCNvJz.d.mts} +4 -2
  18. package/dist/{index-dkFyTNh4.d.mts → index-Cb3AB98n.d.mts} +2 -2
  19. package/dist/{index-B4PIkqOU.d.mts → index-D6lnI92z.d.mts} +3 -3
  20. package/dist/{index-Bg9rr8Qe.d.mts → index-Dsulk-n6.d.mts} +3 -3
  21. package/dist/{index-DeXUtyd9.d.mts → index-aayvtf0J.d.mts} +2 -2
  22. package/dist/index.d.mts +13 -13
  23. package/dist/index.mjs +464 -103
  24. package/dist/knowledge/index.d.mts +1 -1
  25. package/dist/model-stream-JQdHDDcj.mjs +131 -0
  26. package/dist/models/index.d.mts +1 -1
  27. package/dist/observability/index.d.mts +1 -1
  28. package/dist/policies/index.d.mts +1 -1
  29. package/dist/{model-stream-u2xMsEaf.mjs → run-support-CmZ6Xo6H.mjs} +41 -130
  30. package/dist/runtime/index.d.mts +2 -2
  31. package/dist/runtime/index.mjs +43 -1
  32. package/dist/sandbox/index.d.mts +1 -1
  33. package/dist/sandbox/index.mjs +42 -17
  34. package/dist/teams/index.d.mts +1 -1
  35. package/dist/testing/index.d.mts +13 -7
  36. package/dist/testing/index.mjs +98 -2
  37. package/dist/tools/index.d.mts +2 -2
  38. package/dist/types-BDVUoAU6.d.mts +559 -0
  39. package/dist/workflows/index.d.mts +1 -1
  40. package/package.json +6 -2
  41. package/dist/types-CuoRx12Q.d.mts +0 -333
@@ -1,17 +1,20 @@
1
+ import { n as RunPausedError } from "../run-error-Cr17wPGH.mjs";
1
2
  //#region src/channels/channel.ts
2
3
  var ChannelError = class extends Error {
3
4
  code;
4
5
  safeMessage;
5
6
  name = "ChannelError";
7
+ runId;
6
8
  constructor(code, safeMessage, options) {
7
9
  super(safeMessage, options);
8
10
  this.code = code;
9
11
  this.safeMessage = safeMessage;
12
+ this.runId = options?.runId;
10
13
  }
11
14
  };
12
15
  //#endregion
13
16
  //#region src/channels/handle-channel-input.ts
14
- /** Parses one channel input, runs the configured agent, and delivers its output. */
17
+ /** Parses one channel input, runs the configured agent, and delivers its result or elicitation. */
15
18
  async function handleChannelInput(input, options) {
16
19
  const channelEvents = [];
17
20
  const emit = (event) => {
@@ -32,57 +35,92 @@ async function handleChannelInput(input, options) {
32
35
  };
33
36
  const message = parsed;
34
37
  emit(received(options.adapter.name, message));
35
- let result;
38
+ let runId;
36
39
  try {
37
40
  const sessionId = await options.resolveSessionId?.(message);
38
- result = await options.fevex.runAgent(options.agentName, {
41
+ runId = (await options.fevex.runAgent(options.agentName, {
39
42
  input: message.content,
40
43
  ...sessionId ? { sessionId } : {},
41
44
  context: channelContext(options.adapter.name, message),
42
45
  signal: options.signal
43
- });
46
+ })).runId;
44
47
  } catch (cause) {
45
- const error = channelError("CHANNEL_RUN_FAILED", "Channel run failed", cause);
46
- emit(failed(options.adapter.name, "run", error, message));
47
- throw error;
48
+ if (cause instanceof RunPausedError && cause.pause.type === "elicitation") runId = cause.runId;
49
+ else {
50
+ const error = channelError("CHANNEL_RUN_FAILED", "Channel run failed", cause);
51
+ emit(failed(options.adapter.name, "run", error, message));
52
+ throw error;
53
+ }
48
54
  }
49
- const run = await options.fevex.getRun(result.runId);
50
- if (!run || run.kind === "workflow" || run.kind === "team") {
51
- const error = channelError("CHANNEL_RUN_FAILED", "Channel run was not found after completion");
52
- emit(failed(options.adapter.name, "run", error, message));
55
+ const delivered = await deliverChannelRun(runId, message, options);
56
+ return {
57
+ ...delivered,
58
+ events: [channelEvents[0], ...delivered.events]
59
+ };
60
+ }
61
+ /** Delivers a stored agent result or elicitation without executing the agent again. */
62
+ async function deliverChannelRun(runId, message, options) {
63
+ options.signal?.throwIfAborted();
64
+ const run = await options.fevex.getRun(runId);
65
+ const elicitation = run?.status === "paused" && run.pause?.type === "elicitation" ? run.pause.request : void 0;
66
+ if (!run || run.kind === "workflow" || run.kind === "team" || run.status !== "completed" && !elicitation) {
67
+ const error = channelError("CHANNEL_RUN_FAILED", "Channel run is not ready for delivery", void 0, runId);
68
+ options.onEvent?.(failed(options.adapter.name, "run", error, message));
53
69
  throw error;
54
70
  }
55
71
  const output = {
56
- deliveryId: message.deliveryId,
72
+ deliveryId: elicitation ? `elicitation:${runId}:${elicitation.id}` : message.deliveryId,
57
73
  conversationId: message.conversationId,
58
74
  ...message.threadId ? { threadId: message.threadId } : {},
59
- content: stringifyOutput(result.output),
75
+ content: elicitation ? elicitation.prompt : stringifyOutput(run.output ?? null),
60
76
  metadata: {
61
- runId: result.runId,
62
- sessionId: result.sessionId
77
+ runId,
78
+ sessionId: run.sessionId,
79
+ ...elicitation ? { requestId: elicitation.id } : {}
63
80
  }
64
81
  };
65
82
  let delivery;
66
83
  try {
67
- delivery = await options.adapter.deliver(output, { signal: options.signal });
84
+ if (elicitation) {
85
+ if (!options.adapter.deliverElicitation) throw channelError("CHANNEL_ELICITATION_UNSUPPORTED", "Channel does not support elicitation delivery", void 0, runId);
86
+ if (elicitation.expiresAt && Date.now() > Date.parse(elicitation.expiresAt)) throw channelError("CHANNEL_ELICITATION_EXPIRED", "Channel elicitation has expired", void 0, runId);
87
+ delivery = await options.adapter.deliverElicitation(elicitation, {
88
+ signal: options.signal,
89
+ deliveryId: output.deliveryId,
90
+ runId,
91
+ sessionId: run.sessionId,
92
+ conversationId: message.conversationId,
93
+ ...message.threadId ? { threadId: message.threadId } : {}
94
+ });
95
+ } else delivery = await options.adapter.deliver(output, { signal: options.signal });
68
96
  } catch (cause) {
69
- const error = channelError("CHANNEL_DELIVERY_FAILED", "Channel delivery failed", cause);
70
- emit(failed(options.adapter.name, "deliver", error, message));
97
+ const error = cause instanceof ChannelError ? channelError(cause.code, cause.safeMessage, cause, runId) : channelError("CHANNEL_DELIVERY_FAILED", "Channel delivery failed", cause, runId);
98
+ options.onEvent?.({
99
+ ...failed(options.adapter.name, "deliver", error, {
100
+ ...message,
101
+ deliveryId: output.deliveryId
102
+ }),
103
+ ...elicitation ? { requestId: elicitation.id } : {}
104
+ });
71
105
  throw error;
72
106
  }
73
- const deliveredEvent = delivered(options.adapter.name, message);
74
- emit(deliveredEvent);
107
+ const deliveredEvent = {
108
+ ...delivered(options.adapter.name, {
109
+ ...message,
110
+ deliveryId: output.deliveryId
111
+ }),
112
+ runId,
113
+ ...elicitation ? { requestId: elicitation.id } : {}
114
+ };
115
+ options.onEvent?.(deliveredEvent);
75
116
  return {
76
117
  ignored: false,
77
118
  message,
78
119
  run,
79
120
  output,
80
121
  delivery,
81
- events: [
82
- channelEvents[0],
83
- ...result.events ?? [],
84
- deliveredEvent
85
- ]
122
+ ...elicitation ? { elicitation } : {},
123
+ events: [...await options.fevex.listEvents(runId), deliveredEvent]
86
124
  };
87
125
  }
88
126
  function channelContext(adapter, message) {
@@ -132,6 +170,7 @@ function failed(adapter, phase, error, message) {
132
170
  adapter,
133
171
  phase,
134
172
  error: error.safeMessage,
173
+ ...error.runId ? { runId: error.runId } : {},
135
174
  ...message ? {
136
175
  messageId: message.id,
137
176
  deliveryId: message.deliveryId,
@@ -140,11 +179,14 @@ function failed(adapter, phase, error, message) {
140
179
  } : {}
141
180
  };
142
181
  }
143
- function channelError(code, safeMessage, cause) {
144
- return new ChannelError(code, safeMessage, cause === void 0 ? void 0 : { cause });
182
+ function channelError(code, safeMessage, cause, runId) {
183
+ return new ChannelError(code, safeMessage, {
184
+ ...cause === void 0 ? {} : { cause },
185
+ ...runId ? { runId } : {}
186
+ });
145
187
  }
146
188
  function stringifyOutput(value) {
147
189
  return typeof value === "string" ? value : JSON.stringify(value);
148
190
  }
149
191
  //#endregion
150
- export { ChannelError, handleChannelInput };
192
+ export { ChannelError, deliverChannelRun, handleChannelInput };
@@ -1,7 +1,7 @@
1
- import { l as JsonValue, o as ExecutionContext, t as AgentEvent } from "../types-CuoRx12Q.mjs";
2
- import { r as ModelMetadata, s as ModelUsage } from "../index-CTIwrVf9.mjs";
3
- import { l as TraceCost, t as CostCalculator } from "../index-B4PIkqOU.mjs";
4
- import { t as Fevex } from "../fevex-Ddyi6z6L.mjs";
1
+ import { l as JsonValue, o as ExecutionContext, t as AgentEvent } from "../types-BDVUoAU6.mjs";
2
+ import { r as ModelMetadata, s as ModelUsage } from "../index-BPwkgdo3.mjs";
3
+ import { l as TraceCost, t as CostCalculator } from "../index-D6lnI92z.mjs";
4
+ import { t as Fevex } from "../fevex-B5NxFKcV.mjs";
5
5
  //#region src/evals/canonical-json.d.ts
6
6
  /** Serializes JSON-like data with stable object-key ordering. */
7
7
  declare function serializeCanonical(value: unknown): string;
@@ -1,14 +1,39 @@
1
- import { f as RunId, t as AgentEvent } from "./types-CuoRx12Q.mjs";
2
- import { t as ModelGateway } from "./index-CTIwrVf9.mjs";
3
- import { A as RunStore, D as RunRequest, E as RunRecord, F as TeamRun, M as SessionId, O as RunResult, S as ResumeRunResolution, U as WorkflowRun, a as AgentRun, b as ListEventsOptions, f as CredentialStore, j as Session, t as AgentDefinition } from "./index-Dx_LotWZ.mjs";
4
- import { r as ContextProvider, s as MemoryStore } from "./index-DeXUtyd9.mjs";
5
- import { r as ObservabilityOptions } from "./index-B4PIkqOU.mjs";
6
- import { r as Sandbox } from "./index-CrOId2px.mjs";
7
- import { g as ToolDefinition, s as ConnectionDefinition } from "./index-CqOjvtQ9.mjs";
8
- import { r as PolicyDefinition } from "./index-dkFyTNh4.mjs";
9
- import { n as WorkflowDefinition } from "./index-DviHtsLo.mjs";
10
- import { t as TeamDefinition } from "./index-Bg9rr8Qe.mjs";
1
+ import { F as ArtifactStore, f as RunId, o as ExecutionContext, t as AgentEvent } from "./types-BDVUoAU6.mjs";
2
+ import { t as ModelGateway } from "./index-BPwkgdo3.mjs";
3
+ import { A as RunRecord, C as PurgeRunsResult, F as Session, I as SessionId, M as RunResult, P as RunStore, S as PurgeRunsOptions, a as AgentRun, b as ListEventsOptions, f as CredentialStore, j as RunRequest, q as WorkflowRun, t as AgentDefinition, w as ResumeRunResolution, z as TeamRun } from "./index-CGmHXV31.mjs";
4
+ import { r as ContextProvider, s as MemoryStore } from "./index-aayvtf0J.mjs";
5
+ import { r as ObservabilityOptions } from "./index-D6lnI92z.mjs";
6
+ import { r as Sandbox } from "./index-BFnWUu7j.mjs";
7
+ import { g as ToolDefinition, s as ConnectionDefinition } from "./index-CKQCNvJz.mjs";
8
+ import { r as PolicyDefinition } from "./index-Cb3AB98n.mjs";
9
+ import { n as WorkflowDefinition } from "./index-Br-zPxZH.mjs";
10
+ import { t as TeamDefinition } from "./index-Dsulk-n6.mjs";
11
11
  //#region src/fevex.d.ts
12
+ interface FevexAdmissionRequest {
13
+ kind: 'agent' | 'workflow' | 'team';
14
+ name: string;
15
+ request: RunRequest;
16
+ activeRuns: number;
17
+ activeTenantRuns: number;
18
+ }
19
+ /** Optional host-level admission controls applied before a top-level run starts. */
20
+ interface FevexAdmission {
21
+ /** Maximum concurrent top-level runs in this runtime. */
22
+ maxActiveRuns?: number;
23
+ /** Maximum concurrent top-level runs for one tenant. */
24
+ maxActiveRunsPerTenant?: number;
25
+ /** Defaults to a non-empty `context.attributes.tenantId` string. */
26
+ tenantKey?: (context?: ExecutionContext) => string | undefined;
27
+ /** Custom admission check, called after the built-in limits. */
28
+ authorize?: (request: FevexAdmissionRequest) => boolean | Promise<boolean>;
29
+ }
30
+ interface FevexLimits {
31
+ /**
32
+ * Maximum non-control events persisted for one run. Control events such as
33
+ * pause, resume, approval and terminal transitions are always persisted.
34
+ */
35
+ maxEventsPerRun?: number;
36
+ }
12
37
  /** Provider-neutral definitions and adapters used to create one Fevex runtime. */
13
38
  interface FevexConfig {
14
39
  models: Record<string, ModelGateway>;
@@ -22,9 +47,13 @@ interface FevexConfig {
22
47
  runStore?: RunStore;
23
48
  credentialStore?: CredentialStore;
24
49
  sandbox?: Sandbox;
50
+ /** Optional artifact store exposed to tools as `context.artifacts`. */
51
+ artifacts?: ArtifactStore;
25
52
  policies?: PolicyDefinition[];
26
53
  onEvent?: (event: AgentEvent) => void;
27
54
  observability?: ObservabilityOptions;
55
+ admission?: FevexAdmission;
56
+ limits?: FevexLimits;
28
57
  }
29
58
  interface Fevex {
30
59
  startAgent<TInput = unknown, TOutput = unknown>(name: string, request: RunRequest<TInput, TOutput>): Promise<AgentRun<TOutput>>;
@@ -46,6 +75,7 @@ interface Fevex {
46
75
  type?: string;
47
76
  };
48
77
  }): Promise<RunRecord<TOutput>>;
78
+ purgeRuns(options?: PurgeRunsOptions): Promise<PurgeRunsResult>;
49
79
  compactSession(sessionId: SessionId, summary: string): Promise<Session>;
50
80
  flushObservability(): Promise<void>;
51
81
  }
@@ -57,4 +87,4 @@ interface Fevex {
57
87
  */
58
88
  declare function createFevex(config: FevexConfig): Fevex;
59
89
  //#endregion
60
- export { FevexConfig as n, createFevex as r, Fevex as t };
90
+ export { FevexLimits as a, FevexConfig as i, FevexAdmission as n, createFevex as o, FevexAdmissionRequest as r, Fevex as t };
@@ -1,7 +1,7 @@
1
- import { l as JsonValue, o as ExecutionContext, t as AgentEvent } from "../types-CuoRx12Q.mjs";
2
- import { c as ReasoningEffort } from "../index-CTIwrVf9.mjs";
3
- import { E as RunRecord, F as TeamRun, M as SessionId, U as WorkflowRun, a as AgentRun } from "../index-Dx_LotWZ.mjs";
4
- import { t as Fevex } from "../fevex-Ddyi6z6L.mjs";
1
+ import { D as ArtifactCatalog, F as ArtifactStore, f as RunId, k as ArtifactDescriptor, l as JsonValue, o as ExecutionContext, t as AgentEvent } from "../types-BDVUoAU6.mjs";
2
+ import { c as ReasoningEffort } from "../index-BPwkgdo3.mjs";
3
+ import { A as RunRecord, I as SessionId, a as AgentRun, q as WorkflowRun, z as TeamRun } from "../index-CGmHXV31.mjs";
4
+ import { t as Fevex } from "../fevex-B5NxFKcV.mjs";
5
5
  //#region src/http/protocol.d.ts
6
6
  declare const FEVEX_HTTP_PROTOCOL_VERSION = "3";
7
7
  declare const FEVEX_HTTP_PROTOCOL_VERSION_HEADER = "Fevex-Protocol-Version";
@@ -10,6 +10,8 @@ interface StartRunHttpRequest<TInput extends JsonValue = JsonValue> {
10
10
  model?: string;
11
11
  reasoning?: ReasoningEffort;
12
12
  sessionId?: SessionId;
13
+ /** Maximum wall-clock time for the run, including time spent paused. */
14
+ deadlineMs?: number;
13
15
  }
14
16
  type ResumeRunHttpRequest = {
15
17
  type: 'elicitation';
@@ -47,11 +49,66 @@ interface FevexProblemDetails {
47
49
  interface FevexHttpHandlerContext {
48
50
  context?: ExecutionContext;
49
51
  }
52
+ /** Host-facing resource access check. */
53
+ type FevexHttpAccess = {
54
+ action: 'start';
55
+ kind: 'agent' | 'workflow' | 'team';
56
+ name: string;
57
+ sessionId?: SessionId;
58
+ context?: ExecutionContext;
59
+ } | {
60
+ action: 'read' | 'observe' | 'cancel' | 'resume' | 'recover';
61
+ runId: RunId;
62
+ context?: ExecutionContext;
63
+ };
64
+ /** Host-facing artifact access check. */
65
+ type FevexArtifactAccess = {
66
+ action: 'read' | 'delete';
67
+ kind: 'artifact';
68
+ artifactId: string;
69
+ context?: ExecutionContext;
70
+ } | {
71
+ action: 'read';
72
+ kind: 'artifacts';
73
+ runId: RunId;
74
+ context?: ExecutionContext;
75
+ };
50
76
  interface FevexHttpHandlerOptions {
51
77
  fevex: Fevex;
52
78
  pollIntervalMs?: number;
53
79
  /** Events per SSE read (default 100, maximum 1000). */
54
80
  eventPageSize?: number;
81
+ /** Maximum concurrent SSE streams (default unlimited). */
82
+ maxConnections?: number;
83
+ /**
84
+ * Authorizes a resource operation before the handler reads or mutates a run,
85
+ * or starts a run (new or existing session). Return false for a 403 response.
86
+ * Omit to preserve the host's existing trusted-network behavior.
87
+ */
88
+ authorize?: (access: FevexHttpAccess) => boolean | Promise<boolean>;
89
+ /**
90
+ * Byte store used by the artifact routes. When omitted, artifact routes
91
+ * return 501.
92
+ */
93
+ artifacts?: ArtifactStore;
94
+ /**
95
+ * Metadata catalog used to list artifacts for a run. When omitted, the
96
+ * run-artifact listing route returns 501.
97
+ */
98
+ artifactCatalog?: ArtifactCatalog;
99
+ /**
100
+ * Authorizes artifact reads, listings and deletions. Omit to preserve the
101
+ * host's existing trusted-network behavior.
102
+ */
103
+ authorizeArtifact?: (access: FevexArtifactAccess) => boolean | Promise<boolean>;
104
+ /**
105
+ * Called after a run starts so the host can persist run and session ownership.
106
+ * If it throws, the handler cancels the new run and returns 500. A process
107
+ * crash between start and this callback leaves the run unowned; hosts must
108
+ * treat unowned runs as inaccessible. Runs created outside the HTTP handler
109
+ * are not reported.
110
+ */
111
+ onRunStarted?: (run: RunRecord, context?: ExecutionContext) => void | Promise<void>;
55
112
  onError?: (error: unknown, problem: FevexProblemDetails) => void;
56
113
  }
57
114
  type FevexHttpHandler = (request: Request, context?: FevexHttpHandlerContext) => Promise<Response>;
@@ -73,6 +130,9 @@ interface FevexHttpClient {
73
130
  resumeRun<TOutput = JsonValue>(runId: string, request: ResumeRunHttpRequest): Promise<RunRecord<TOutput>>;
74
131
  recoverRun<TOutput = JsonValue>(runId: string): Promise<RunRecord<TOutput>>;
75
132
  cancelRun(runId: string): Promise<void>;
133
+ getArtifact(artifactId: string): Promise<Response>;
134
+ listArtifacts(runId: string): Promise<ArtifactDescriptor[]>;
135
+ deleteArtifact(artifactId: string): Promise<void>;
76
136
  }
77
137
  //#endregion
78
138
  //#region src/http/transport.d.ts
@@ -87,4 +147,4 @@ declare class FevexHttpError extends Error {
87
147
  }
88
148
  declare function createFevexHttpClient(options: FevexHttpClientOptions): FevexHttpClient;
89
149
  //#endregion
90
- export { FEVEX_HTTP_PROTOCOL_VERSION, FEVEX_HTTP_PROTOCOL_VERSION_HEADER, FevexHttpClient, FevexHttpClientOptions, FevexHttpError, FevexHttpFetch, FevexHttpHandler, FevexHttpHandlerContext, FevexHttpHandlerOptions, FevexProblemDetails, ObserveRunOptions, ResumeRunHttpRequest, StartRunHttpRequest, createFevexHttpClient, createFevexHttpHandler };
150
+ export { FEVEX_HTTP_PROTOCOL_VERSION, FEVEX_HTTP_PROTOCOL_VERSION_HEADER, FevexArtifactAccess, FevexHttpAccess, FevexHttpClient, FevexHttpClientOptions, FevexHttpError, FevexHttpFetch, FevexHttpHandler, FevexHttpHandlerContext, FevexHttpHandlerOptions, FevexProblemDetails, ObserveRunOptions, ResumeRunHttpRequest, StartRunHttpRequest, createFevexHttpClient, createFevexHttpHandler };