@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/README.md
CHANGED
|
@@ -28,18 +28,26 @@ adapters, validation and tests without adopting a heavy runtime.
|
|
|
28
28
|
npm install @fevex/core
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
The npm release pipeline publishes exactly three official packages:
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
34
|
npm install @fevex/core @fevex/openai
|
|
35
35
|
npm install @fevex/core @fevex/deepseek
|
|
36
|
-
npm install @fevex/core @fevex/mcp
|
|
37
|
-
npm install @fevex/core @fevex/openapi
|
|
38
|
-
npm install @fevex/core @fevex/sqlite
|
|
39
|
-
npm install @fevex/core @fevex/postgres
|
|
40
|
-
npm install @fevex/core @fevex/opentelemetry @opentelemetry/api
|
|
41
36
|
```
|
|
42
37
|
|
|
38
|
+
CI builds, typechecks, tests and tarball-smokes all nine packages. The
|
|
39
|
+
repository-only integrations below are **not published to npm** by the release
|
|
40
|
+
pipeline; use them from this repository until they are published:
|
|
41
|
+
|
|
42
|
+
| Package | Purpose |
|
|
43
|
+
| --- | --- |
|
|
44
|
+
| `@fevex/mcp` | Model Context Protocol tools and connections |
|
|
45
|
+
| `@fevex/openapi` | Tools generated from an OpenAPI document |
|
|
46
|
+
| `@fevex/sqlite` | SQLite run and session store |
|
|
47
|
+
| `@fevex/postgres` | PostgreSQL run and session store |
|
|
48
|
+
| `@fevex/opentelemetry` | OpenTelemetry trace and metric export |
|
|
49
|
+
| `@fevex/browser` | Browser automation tools |
|
|
50
|
+
|
|
43
51
|
Schemas are optional. The examples use Zod 4, but any Standard
|
|
44
52
|
Schema-compatible validator can be used:
|
|
45
53
|
|
|
@@ -47,6 +55,20 @@ Schema-compatible validator can be used:
|
|
|
47
55
|
npm install zod
|
|
48
56
|
```
|
|
49
57
|
|
|
58
|
+
## Compatibility & releases
|
|
59
|
+
|
|
60
|
+
FEVEX is pre-1.0. Documented imports from official packages are the public API;
|
|
61
|
+
`src/internal`, undocumented paths and checkpoint shapes are not. While in alpha,
|
|
62
|
+
`minor` releases may contain breaking changes with migration notes; `patch`
|
|
63
|
+
releases stay compatible. Store migrations are forward-only, checkpoints are
|
|
64
|
+
versioned and private, and downgrades are not supported.
|
|
65
|
+
|
|
66
|
+
Only the latest alpha is supported; pin exact versions in production. Releases
|
|
67
|
+
come from reviewed changesets, publish only the three official packages, and
|
|
68
|
+
place alpha versions on the npm `latest` tag. Read the full
|
|
69
|
+
[compatibility and release policy](https://fevex.dev/docs/compatibility/) before
|
|
70
|
+
upgrading a durable deployment.
|
|
71
|
+
|
|
50
72
|
## Quickstart
|
|
51
73
|
|
|
52
74
|
This example executes a complete model-tool-model cycle without network access:
|
|
@@ -568,6 +590,31 @@ Hosts pass authenticated `ExecutionContext` separately to `handler(request,
|
|
|
568
590
|
SSE response never cancels its run. Cancellation is explicit through
|
|
569
591
|
`client.cancelRun(run.id)`.
|
|
570
592
|
|
|
593
|
+
Artifacts use the same handler:
|
|
594
|
+
|
|
595
|
+
```ts
|
|
596
|
+
const handler = createFevexHttpHandler({
|
|
597
|
+
fevex: app,
|
|
598
|
+
artifacts: artifactStore, // FileSystemArtifactStore or S3ArtifactStore
|
|
599
|
+
artifactCatalog: artifactCatalog, // optional; enables listing by run
|
|
600
|
+
authorizeArtifact(access) {
|
|
601
|
+
return access.context?.actor?.id === 'alice';
|
|
602
|
+
},
|
|
603
|
+
});
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
Routes:
|
|
607
|
+
|
|
608
|
+
- `GET /v1/artifacts/:id` streams the bytes with `content-type`,
|
|
609
|
+
`content-length`, `content-disposition`, `etag` and artifact headers.
|
|
610
|
+
- `HEAD /v1/artifacts/:id` returns the same metadata without a body.
|
|
611
|
+
- `DELETE /v1/artifacts/:id` deletes bytes and catalog metadata.
|
|
612
|
+
- `GET /v1/runs/:runId/artifacts?limit=100` lists descriptors for a run.
|
|
613
|
+
|
|
614
|
+
The client exposes `getArtifact`, `listArtifacts` and `deleteArtifact`. Keep the
|
|
615
|
+
bucket private; the handler authorizes the request and streams the bytes, or a
|
|
616
|
+
host can use the descriptor to mint a short-lived signed URL.
|
|
617
|
+
|
|
571
618
|
## Approvals and durable runs
|
|
572
619
|
|
|
573
620
|
Tools can declare risk, approval, idempotency, retries and credential names.
|
|
@@ -652,6 +699,28 @@ underlying work. External systems must enforce the supplied idempotency key to
|
|
|
652
699
|
make keyed retries safe. Repeated tool call IDs are rejected within a run before
|
|
653
700
|
Fevex repeats an effect.
|
|
654
701
|
|
|
702
|
+
### Deadlines, admission and retention
|
|
703
|
+
|
|
704
|
+
Set `deadlineMs` on a run request to cap wall-clock time. An expired deadline
|
|
705
|
+
cancels the run with `run.cancelled` reason `timeout`; resuming or recovering
|
|
706
|
+
after the absolute deadline persists that cancellation instead of continuing.
|
|
707
|
+
|
|
708
|
+
`createFevex({ admission })` limits concurrent top-level runs globally or per
|
|
709
|
+
tenant. The default tenant key is a non-empty `context.attributes.tenantId`;
|
|
710
|
+
`tenantKey` and `authorize` support host-specific quotas. Counts are local to
|
|
711
|
+
one runtime process.
|
|
712
|
+
|
|
713
|
+
`createFevex({ limits: { maxEventsPerRun } })` caps non-control events per run.
|
|
714
|
+
Pause, resume, approval, elicitation, wait and terminal events are always
|
|
715
|
+
persisted so a run can always reach a durable state; use retention for a total
|
|
716
|
+
storage cap.
|
|
717
|
+
|
|
718
|
+
Terminal runs can be purged with `app.purgeRuns({ before, statuses, limit })`.
|
|
719
|
+
SQLite and PostgreSQL implement the retention capability; custom stores can add
|
|
720
|
+
`purgeRuns` to opt in. The API deletes only terminal runs and sessions left
|
|
721
|
+
without runs; active work is untouched. Artifact retention and per-event payload
|
|
722
|
+
byte limits remain host policies.
|
|
723
|
+
|
|
655
724
|
## Observability
|
|
656
725
|
|
|
657
726
|
Add trace exporters to the application configuration; agent definitions stay
|
|
@@ -683,8 +752,50 @@ Traces contain only metadata by default. Output and safe error capture require
|
|
|
683
752
|
an explicit `content.include` policy; sensitive object keys are redacted before
|
|
684
753
|
an optional application redactor runs. Exporters run outside the run path: their
|
|
685
754
|
errors never change the run result, and `flushObservability()` reports pending
|
|
686
|
-
export failures.
|
|
687
|
-
|
|
755
|
+
export failures. Export work is bounded and deduplicated:
|
|
756
|
+
|
|
757
|
+
```ts
|
|
758
|
+
const app = createFevex({
|
|
759
|
+
models,
|
|
760
|
+
agents,
|
|
761
|
+
observability: {
|
|
762
|
+
exporters: [createOpenTelemetryExporter()],
|
|
763
|
+
exportQueue: {
|
|
764
|
+
concurrency: 4,
|
|
765
|
+
maxQueued: 100,
|
|
766
|
+
timeoutMs: 30_000,
|
|
767
|
+
maxFailures: 100,
|
|
768
|
+
},
|
|
769
|
+
},
|
|
770
|
+
});
|
|
771
|
+
|
|
772
|
+
await app.flushObservability({ timeoutMs: 5_000 });
|
|
773
|
+
console.log(app.getObservabilityStats());
|
|
774
|
+
```
|
|
775
|
+
|
|
776
|
+
Workflow and team traces carry `kind` and a span per step. Agent steps expose
|
|
777
|
+
`childRunId`; child agent traces carry `parentRunId` and `rootRunId`, and tool
|
|
778
|
+
spans are nested under the model call that requested them. A dropped trace or a
|
|
779
|
+
failed export is counted in `getObservabilityStats()`, and the next
|
|
780
|
+
`flushObservability()` rejects with the failures accumulated since the previous
|
|
781
|
+
flush. OpenTelemetry SDK setup, OTLP export and shutdown remain application
|
|
782
|
+
responsibilities.
|
|
783
|
+
|
|
784
|
+
## Graceful shutdown
|
|
785
|
+
|
|
786
|
+
`shutdown` stops admission, drains active runs, cancels what remains at the
|
|
787
|
+
deadline and flushes trace exports:
|
|
788
|
+
|
|
789
|
+
```ts
|
|
790
|
+
const result = await app.shutdown({ timeoutMs: 30_000 });
|
|
791
|
+
console.log(result.timedOut, result.cancelledRunIds, result.observability);
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
New starts, resumes and recoveries fail with `RUNTIME_CLOSED` (HTTP `503`) once
|
|
795
|
+
shutdown begins. The host closes its HTTP server, stores and external adapters
|
|
796
|
+
after `shutdown` returns. See
|
|
797
|
+
[Operations & soak tests](https://fevex.dev/docs/operations/) for crash recovery
|
|
798
|
+
and the 1–8 hour load harness.
|
|
688
799
|
|
|
689
800
|
## Evaluations
|
|
690
801
|
|
|
@@ -871,12 +982,128 @@ Context providers are lazy per run. Memory is a replaceable store; the built-in
|
|
|
871
982
|
store is in-memory substring search, not embeddings, vector search or durable
|
|
872
983
|
storage.
|
|
873
984
|
|
|
985
|
+
## Artifacts
|
|
986
|
+
|
|
987
|
+
`@fevex/core/artifacts` stores large or binary outputs as references. Runs,
|
|
988
|
+
events and prompts carry an `ArtifactDescriptor`; bytes stay in an
|
|
989
|
+
`ArtifactStore`.
|
|
990
|
+
|
|
991
|
+
```ts
|
|
992
|
+
import {
|
|
993
|
+
FileSystemArtifactStore,
|
|
994
|
+
InMemoryArtifactStore,
|
|
995
|
+
S3ArtifactStore,
|
|
996
|
+
type S3ObjectClient,
|
|
997
|
+
} from '@fevex/core/artifacts';
|
|
998
|
+
|
|
999
|
+
const artifacts = new FileSystemArtifactStore({
|
|
1000
|
+
rootDir: '.fevex/artifacts',
|
|
1001
|
+
maxBytes: 10 * 1024 * 1024,
|
|
1002
|
+
});
|
|
1003
|
+
|
|
1004
|
+
const descriptor = await artifacts.put(
|
|
1005
|
+
{
|
|
1006
|
+
filename: 'report.pdf',
|
|
1007
|
+
mimeType: 'application/pdf',
|
|
1008
|
+
bytes,
|
|
1009
|
+
},
|
|
1010
|
+
{ tenantId: 'acme', runId: 'run-1' },
|
|
1011
|
+
);
|
|
1012
|
+
|
|
1013
|
+
const stored = await artifacts.get(descriptor.artifactId, { tenantId: 'acme' });
|
|
1014
|
+
```
|
|
1015
|
+
|
|
1016
|
+
Use `InMemoryArtifactStore` for tests. For S3, R2, MinIO or another
|
|
1017
|
+
S3-compatible service, wrap its SDK with the small `S3ObjectClient` interface;
|
|
1018
|
+
Fevex does not ship an object-storage SDK:
|
|
1019
|
+
|
|
1020
|
+
```ts
|
|
1021
|
+
const client: S3ObjectClient = {
|
|
1022
|
+
async putObject({ key, body, contentType }) {
|
|
1023
|
+
await s3.send(new PutObjectCommand({
|
|
1024
|
+
Bucket,
|
|
1025
|
+
Key: key,
|
|
1026
|
+
Body: body,
|
|
1027
|
+
ContentType: contentType,
|
|
1028
|
+
}));
|
|
1029
|
+
},
|
|
1030
|
+
async getObject({ key }) {
|
|
1031
|
+
try {
|
|
1032
|
+
const result = await s3.send(new GetObjectCommand({ Bucket, Key: key }));
|
|
1033
|
+
return new Uint8Array(await result.Body!.transformToByteArray());
|
|
1034
|
+
} catch (error) {
|
|
1035
|
+
if ((error as { name?: string }).name === 'NoSuchKey') return null;
|
|
1036
|
+
throw error;
|
|
1037
|
+
}
|
|
1038
|
+
},
|
|
1039
|
+
async deleteObject({ key }) {
|
|
1040
|
+
await s3.send(new DeleteObjectCommand({ Bucket, Key: key }));
|
|
1041
|
+
},
|
|
1042
|
+
};
|
|
1043
|
+
|
|
1044
|
+
const artifacts = new S3ArtifactStore({ client, prefix: 'fevex' });
|
|
1045
|
+
```
|
|
1046
|
+
|
|
1047
|
+
The bucket should stay private. The host authorizes the actor and serves a
|
|
1048
|
+
short-lived signed URL or streams the bytes; do not expose bucket URLs to the
|
|
1049
|
+
model. This subpath is local-first: use the filesystem store for development and
|
|
1050
|
+
single-node deployments, and the S3-compatible store for multi-instance
|
|
1051
|
+
production.
|
|
1052
|
+
|
|
1053
|
+
For a queryable metadata index, compose the byte store with a catalog:
|
|
1054
|
+
|
|
1055
|
+
```ts
|
|
1056
|
+
import { CatalogedArtifactStore, FileSystemArtifactStore } from '@fevex/core/artifacts';
|
|
1057
|
+
import { createSQLiteArtifactCatalog } from '@fevex/sqlite';
|
|
1058
|
+
|
|
1059
|
+
const catalog = createSQLiteArtifactCatalog({ filename: '.fevex/artifacts.db' });
|
|
1060
|
+
const artifacts = new CatalogedArtifactStore({
|
|
1061
|
+
store: new FileSystemArtifactStore({ rootDir: '.fevex/artifacts' }),
|
|
1062
|
+
catalog,
|
|
1063
|
+
});
|
|
1064
|
+
|
|
1065
|
+
const records = await artifacts.list({ runId: 'run-1' }, { tenantId: 'acme' });
|
|
1066
|
+
await artifacts.deleteByRun('run-1', { tenantId: 'acme' });
|
|
1067
|
+
```
|
|
1068
|
+
|
|
1069
|
+
`@fevex/postgres` exposes the same catalog contract with
|
|
1070
|
+
`createPostgresArtifactCatalog`. The catalog stores only metadata; bytes stay in
|
|
1071
|
+
the filesystem or object storage.
|
|
1072
|
+
|
|
1073
|
+
Pass the store to `createFevex` to expose it to tools as `context.artifacts`:
|
|
1074
|
+
|
|
1075
|
+
```ts
|
|
1076
|
+
const save = defineTool({
|
|
1077
|
+
name: 'save_report',
|
|
1078
|
+
async execute(_input, context) {
|
|
1079
|
+
return context.artifacts!.put({
|
|
1080
|
+
filename: 'report.txt',
|
|
1081
|
+
mimeType: 'text/plain',
|
|
1082
|
+
bytes: new TextEncoder().encode('report'),
|
|
1083
|
+
});
|
|
1084
|
+
},
|
|
1085
|
+
});
|
|
1086
|
+
|
|
1087
|
+
createFevex({
|
|
1088
|
+
models,
|
|
1089
|
+
agents,
|
|
1090
|
+
tools: [save],
|
|
1091
|
+
artifacts,
|
|
1092
|
+
});
|
|
1093
|
+
```
|
|
1094
|
+
|
|
1095
|
+
The runtime injects `runId`, `sessionId`, tenant and actor into every artifact
|
|
1096
|
+
call. Each successful `put` emits `artifact.created` with the descriptor before
|
|
1097
|
+
`tool.completed`; a tool that writes and then fails still leaves the event and
|
|
1098
|
+
the artifact available.
|
|
1099
|
+
|
|
874
1100
|
## Public Exports
|
|
875
1101
|
|
|
876
1102
|
| Import | Purpose |
|
|
877
1103
|
| --- | --- |
|
|
878
1104
|
| `@fevex/core` | Common runtime, definitions and contracts |
|
|
879
1105
|
| `@fevex/core/agents` | Agent definitions |
|
|
1106
|
+
| `@fevex/core/artifacts` | Artifact descriptors, local stores and S3-compatible adapter |
|
|
880
1107
|
| `@fevex/core/channels` | Channel adapters and message handling |
|
|
881
1108
|
| `@fevex/core/knowledge` | Context providers, skills and memory contracts |
|
|
882
1109
|
| `@fevex/core/models` | Provider-neutral model contracts |
|
|
@@ -886,7 +1113,7 @@ storage.
|
|
|
886
1113
|
| `@fevex/core/runtime` | Runs, sessions and store contracts |
|
|
887
1114
|
| `@fevex/core/sandbox` | Sandbox contract and local development sandbox |
|
|
888
1115
|
| `@fevex/core/policies` | Authorization policy contracts |
|
|
889
|
-
| `@fevex/core/observability` | Trace, redaction and cost contracts |
|
|
1116
|
+
| `@fevex/core/observability` | Trace, bounded export queue, redaction and cost contracts |
|
|
890
1117
|
| `@fevex/core/evals` | Datasets, scorers, reporters and regressions |
|
|
891
1118
|
| `@fevex/core/testing` | Deterministic testing helpers |
|
|
892
1119
|
|
|
@@ -959,8 +1186,10 @@ limit for the initial SSE read and every subsequent read. Full pages drain
|
|
|
959
1186
|
without the polling delay; short pages wait for `pollIntervalMs`. Stream demand
|
|
960
1187
|
controls progress, so a slow consumer retains at most one page plus the stream's
|
|
961
1188
|
single queued frame, rather than buffering the run's entire history. Disconnecting
|
|
962
|
-
cancels polling.
|
|
963
|
-
per-event payload limits
|
|
1189
|
+
cancels polling. `maxConnections` caps concurrent SSE streams. This bounds event
|
|
1190
|
+
counts, not the byte size of an individual event; per-event payload limits remain
|
|
1191
|
+
host responsibilities. Use `purgeRuns` for configurable retention of terminal
|
|
1192
|
+
runs.
|
|
964
1193
|
|
|
965
1194
|
### Run model identity
|
|
966
1195
|
|
package/dist/agents/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as AgentLimits, r as defineAgent, t as AgentDefinition } from "../index-
|
|
1
|
+
import { n as AgentLimits, r as defineAgent, t as AgentDefinition } from "../index-CzAi2Y_Z.mjs";
|
|
2
2
|
export { AgentDefinition, AgentLimits, defineAgent };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { A as ArtifactError, C as FileSystemArtifactStore, D as ArtifactCatalog, E as CatalogedArtifactStoreOptions, F as ArtifactStore, I as ArtifactStoreContext, L as ArtifactWrite, M as ArtifactId, N as ArtifactQuery, O as ArtifactContent, P as ArtifactRecord, R as artifactTenantId, S as InMemoryArtifactCatalog, T as CatalogedArtifactStore, _ as S3ArtifactStore, b as InMemoryArtifactStore, j as ArtifactErrorCode, k as ArtifactDescriptor, v as S3ArtifactStoreOptions, w as FileSystemArtifactStoreOptions, x as InMemoryArtifactStoreOptions, y as S3ObjectClient, z as assertArtifactId } from "../types-B8laW1hM.mjs";
|
|
2
|
+
export { ArtifactCatalog, ArtifactContent, ArtifactDescriptor, ArtifactError, ArtifactErrorCode, ArtifactId, ArtifactQuery, ArtifactRecord, ArtifactStore, ArtifactStoreContext, ArtifactWrite, CatalogedArtifactStore, CatalogedArtifactStoreOptions, FileSystemArtifactStore, FileSystemArtifactStoreOptions, InMemoryArtifactCatalog, InMemoryArtifactStore, InMemoryArtifactStoreOptions, S3ArtifactStore, S3ArtifactStoreOptions, S3ObjectClient, artifactTenantId, assertArtifactId };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as CatalogedArtifactStore, c as assertArtifactId, i as FileSystemArtifactStore, n as InMemoryArtifactStore, o as ArtifactError, r as InMemoryArtifactCatalog, s as artifactTenantId, t as S3ArtifactStore } from "../artifacts-gUzemET7.mjs";
|
|
2
|
+
export { ArtifactError, CatalogedArtifactStore, FileSystemArtifactStore, InMemoryArtifactCatalog, InMemoryArtifactStore, S3ArtifactStore, artifactTenantId, assertArtifactId };
|