@ferricstore/ferricstore 0.11.11 → 0.12.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/README.md +16 -1
- package/dist/durability-DlDCsdlo.d.cts +16 -0
- package/dist/durability-DplL0SbW.d.ts +16 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -162
- package/dist/index.d.ts +5 -162
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal-lEEDZpPH.d.cts +4 -0
- package/dist/internal-lEEDZpPH.d.ts +4 -0
- package/dist/langgraph.cjs +1278 -0
- package/dist/langgraph.cjs.map +1 -0
- package/dist/langgraph.d.cts +148 -0
- package/dist/langgraph.d.ts +148 -0
- package/dist/langgraph.js +1252 -0
- package/dist/langgraph.js.map +1 -0
- package/dist/openai-agents.cjs +580 -0
- package/dist/openai-agents.cjs.map +1 -0
- package/dist/openai-agents.d.cts +44 -0
- package/dist/openai-agents.d.ts +44 -0
- package/dist/openai-agents.js +555 -0
- package/dist/openai-agents.js.map +1 -0
- package/dist/outcomes-BbFDp3AH.d.ts +160 -0
- package/dist/outcomes-DmBwnq0Y.d.cts +160 -0
- package/docs/agent-frameworks.md +159 -0
- package/docs/api/assets/highlight.css +12 -12
- package/docs/api/classes/ClaimHydrationError.html +2 -2
- package/docs/api/classes/ConnectionClosedError.html +2 -2
- package/docs/api/classes/FerricStoreError.html +2 -2
- package/docs/api/classes/FlowAlreadyExistsError.html +2 -2
- package/docs/api/classes/FlowBatchError.html +2 -2
- package/docs/api/classes/FlowNotFoundError.html +2 -2
- package/docs/api/classes/FlowQueryError.html +2 -2
- package/docs/api/classes/FlowWrongStateError.html +2 -2
- package/docs/api/classes/HTTPTransportError.html +2 -2
- package/docs/api/classes/InvalidCommandError.html +2 -2
- package/docs/api/classes/LeaseRenewalError.html +2 -2
- package/docs/api/classes/LockHeldError.html +2 -2
- package/docs/api/classes/LockNotOwnedError.html +2 -2
- package/docs/api/classes/OverloadedError.html +2 -2
- package/docs/api/classes/QueueCompletionError.html +2 -2
- package/docs/api/classes/RequestTimeoutError.html +2 -2
- package/docs/api/classes/RerouteError.html +2 -2
- package/docs/api/classes/StaleLeaseError.html +2 -2
- package/docs/api/classes/StalePolicyGenerationError.html +2 -2
- package/docs/api/index.html +34 -24
- package/docs/api/media/agent-frameworks.md +159 -0
- package/docs/api/media/langgraph.ts +23 -0
- package/docs/api/media/openai-agents-session.ts +13 -0
- package/docs/api/variables/FERRICSTORE_SDK_VERSION.html +1 -1
- package/package.json +41 -2
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Agent framework persistence
|
|
2
|
+
|
|
3
|
+
FerricStore's TypeScript package has optional adapters for LangGraph.js and the
|
|
4
|
+
OpenAI Agents SDK. They live in separate package entry points, so the base SDK
|
|
5
|
+
does not load either framework.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
For LangGraph.js:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @ferricstore/ferricstore @langchain/langgraph @langchain/core
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
For the OpenAI Agents SDK:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @ferricstore/ferricstore @openai/agents
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Both adapters accept the normal `FerricStoreClient`. Their serialization is
|
|
22
|
+
independent of the client's configured codec.
|
|
23
|
+
|
|
24
|
+
## LangGraph.js checkpoints
|
|
25
|
+
|
|
26
|
+
`FerricStoreSaver` implements LangGraph's `BaseCheckpointSaver` contract:
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { Annotation, END, START, StateGraph } from "@langchain/langgraph";
|
|
30
|
+
import { FerricStoreClient } from "@ferricstore/ferricstore";
|
|
31
|
+
import { FerricStoreSaver } from "@ferricstore/ferricstore/langgraph";
|
|
32
|
+
|
|
33
|
+
const client = await FerricStoreClient.fromUrl("ferric://127.0.0.1:6388");
|
|
34
|
+
const saver = new FerricStoreSaver(client);
|
|
35
|
+
|
|
36
|
+
const State = Annotation.Root({ count: Annotation<number>() });
|
|
37
|
+
const graph = new StateGraph(State)
|
|
38
|
+
.addNode("increment", ({ count }) => ({ count: count + 1 }))
|
|
39
|
+
.addEdge(START, "increment")
|
|
40
|
+
.addEdge("increment", END)
|
|
41
|
+
.compile({ checkpointer: saver });
|
|
42
|
+
|
|
43
|
+
await graph.invoke(
|
|
44
|
+
{ count: 0 },
|
|
45
|
+
{ configurable: { thread_id: "agent-42" } }
|
|
46
|
+
);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The saver supports named checkpoint namespaces, latest and exact reads,
|
|
50
|
+
ordered and filtered listing, parent chains, pending writes, retry-safe write
|
|
51
|
+
indexes, global listing, and complete thread deletion. It uses LangGraph's
|
|
52
|
+
serializer, so framework-specific values round-trip correctly.
|
|
53
|
+
|
|
54
|
+
Checkpoint mutations are serialized per thread with renewable,
|
|
55
|
+
ownership-checked locks. Indexes are published before the final checkpoint
|
|
56
|
+
record; readers validate each record and skip incomplete entries. This makes a
|
|
57
|
+
process failure during publication invisible and a retry safe.
|
|
58
|
+
|
|
59
|
+
## LangGraph.js long-term memory
|
|
60
|
+
|
|
61
|
+
`FerricStoreStore` implements `BaseStore`:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
import { FerricStoreStore } from "@ferricstore/ferricstore/langgraph";
|
|
65
|
+
|
|
66
|
+
const store = new FerricStoreStore(client);
|
|
67
|
+
|
|
68
|
+
await store.put(["users", "u-42"], "preferences", {
|
|
69
|
+
language: "en",
|
|
70
|
+
notifications: true
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const memories = await store.search(["users", "u-42"], {
|
|
74
|
+
filter: { notifications: true }
|
|
75
|
+
});
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
It supports hierarchical namespaces, atomic per-item mutation ordering,
|
|
79
|
+
batched operations, exact and comparison filters (`$eq`, `$ne`, `$gt`, `$gte`,
|
|
80
|
+
`$lt`, `$lte`, `$in`, `$nin`), ordered pagination, namespace listing, updates,
|
|
81
|
+
and deletion.
|
|
82
|
+
Semantic `query` search currently throws a clear error because no vector index
|
|
83
|
+
is configured; it never silently returns unranked data.
|
|
84
|
+
|
|
85
|
+
## Run LangGraph inside FerricFlow
|
|
86
|
+
|
|
87
|
+
The checkpointer makes graph steps resumable. `LangGraphFlow` adds the durable
|
|
88
|
+
outer lifecycle: leases and fencing, retries, scheduled work, signals,
|
|
89
|
+
approvals, workflow history, and terminal state.
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
import { LangGraphFlow } from "@ferricstore/ferricstore/langgraph";
|
|
93
|
+
|
|
94
|
+
const agentFlow = new LangGraphFlow(graph, {
|
|
95
|
+
interruptState: "waiting_for_approval"
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
workflow.state("running", agentFlow.handler.bind(agentFlow));
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
By default, the bridge derives a stable LangGraph `thread_id` from the Flow
|
|
102
|
+
type, partition, and ID. It sends the Flow payload on the first invocation and
|
|
103
|
+
uses `null` input when a checkpoint already exists. LangGraph runtime context
|
|
104
|
+
includes the active `WorkflowContext`. Completed graphs become `complete()`
|
|
105
|
+
outcomes; interrupts can transition to a chosen Flow state or use a custom
|
|
106
|
+
outcome mapper. Call `resume(flowContext, value)` from a handler to send a
|
|
107
|
+
LangGraph `Command({ resume: value })`.
|
|
108
|
+
|
|
109
|
+
The graph checkpointer and FerricFlow solve different layers and are intended
|
|
110
|
+
to be used together:
|
|
111
|
+
|
|
112
|
+
```text
|
|
113
|
+
FerricFlow durable run lifecycle
|
|
114
|
+
↓
|
|
115
|
+
LangGraphFlow invocation bridge
|
|
116
|
+
↓
|
|
117
|
+
LangGraph graph + FerricStoreSaver
|
|
118
|
+
↓
|
|
119
|
+
FerricStore
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## OpenAI Agents SDK Session
|
|
123
|
+
|
|
124
|
+
`FerricStoreSession` implements the base `Session` contract plus the optional
|
|
125
|
+
history rewrite and atomic transaction capabilities used by the current
|
|
126
|
+
OpenAI Agents SDK:
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
import { Agent, run } from "@openai/agents";
|
|
130
|
+
import { FerricStoreSession } from "@ferricstore/ferricstore/openai-agents";
|
|
131
|
+
|
|
132
|
+
const session = new FerricStoreSession(client, {
|
|
133
|
+
sessionId: "customer-42"
|
|
134
|
+
});
|
|
135
|
+
const agent = new Agent({ name: "Support", instructions: "Be helpful." });
|
|
136
|
+
|
|
137
|
+
await run(agent, "Where is my order?", { session });
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The adapter provides chronological reads with tail limits, append, pop,
|
|
141
|
+
clear, compaction replacement, function-call history rewrites, and atomic
|
|
142
|
+
`append_items` / `replace_suffix` transactions. A transaction stores its
|
|
143
|
+
operation ID and history mutation in one atomic record. Repeating the same
|
|
144
|
+
operation is a no-op; reusing its ID for different content or replacing a
|
|
145
|
+
non-matching suffix fails without changing history.
|
|
146
|
+
|
|
147
|
+
All session mutations use a renewable FerricStore lock. Reads see either the
|
|
148
|
+
old or new complete session record, never a partial history. `clearSession()`
|
|
149
|
+
also clears transaction receipts. Session persistence stores conversation
|
|
150
|
+
history; put the overall agent run in FerricFlow when it also needs durable
|
|
151
|
+
leases, retries, timers, signals, or multi-step business state.
|
|
152
|
+
|
|
153
|
+
## Operational options
|
|
154
|
+
|
|
155
|
+
All three adapters accept `keyPrefix`, `lockTtlMs`, `lockWaitMs`, and
|
|
156
|
+
`lockRetryMs`. The saver and store also accept `scanCount`; the saver accepts a
|
|
157
|
+
custom LangGraph serializer. Defaults are suitable for ordinary use. Give
|
|
158
|
+
different applications or environments different prefixes when they share a
|
|
159
|
+
FerricStore deployment.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Annotation, END, START, StateGraph } from "@langchain/langgraph";
|
|
2
|
+
import { FerricStoreClient } from "@ferricstore/ferricstore";
|
|
3
|
+
import { FerricStoreSaver, FerricStoreStore } from "@ferricstore/ferricstore/langgraph";
|
|
4
|
+
|
|
5
|
+
const client = await FerricStoreClient.fromUrl(
|
|
6
|
+
process.env.FERRICSTORE_URL ?? "ferric://127.0.0.1:6388"
|
|
7
|
+
);
|
|
8
|
+
const checkpointer = new FerricStoreSaver(client);
|
|
9
|
+
const store = new FerricStoreStore(client);
|
|
10
|
+
|
|
11
|
+
const State = Annotation.Root({ count: Annotation<number>() });
|
|
12
|
+
const graph = new StateGraph(State)
|
|
13
|
+
.addNode("increment", ({ count }) => ({ count: count + 1 }))
|
|
14
|
+
.addEdge(START, "increment")
|
|
15
|
+
.addEdge("increment", END)
|
|
16
|
+
.compile({ checkpointer, store });
|
|
17
|
+
|
|
18
|
+
const result = await graph.invoke(
|
|
19
|
+
{ count: 0 },
|
|
20
|
+
{ configurable: { thread_id: "example-agent" } }
|
|
21
|
+
);
|
|
22
|
+
console.log(result);
|
|
23
|
+
await client.close();
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Agent, run } from "@openai/agents";
|
|
2
|
+
import { FerricStoreClient } from "@ferricstore/ferricstore";
|
|
3
|
+
import { FerricStoreSession } from "@ferricstore/ferricstore/openai-agents";
|
|
4
|
+
|
|
5
|
+
const client = await FerricStoreClient.fromUrl(
|
|
6
|
+
process.env.FERRICSTORE_URL ?? "ferric://127.0.0.1:6388"
|
|
7
|
+
);
|
|
8
|
+
const session = new FerricStoreSession(client, { sessionId: "example-conversation" });
|
|
9
|
+
const agent = new Agent({ name: "Assistant", instructions: "Be concise and helpful." });
|
|
10
|
+
|
|
11
|
+
const result = await run(agent, "Remember that my preferred language is TypeScript.", { session });
|
|
12
|
+
console.log(result.finalOutput);
|
|
13
|
+
await client.close();
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<ul class="tsd-breadcrumb" aria-label="Breadcrumb">
|
|
11
11
|
<li><a href="" aria-current="page">FERRICSTORE_SDK_VERSION</a></li></ul>
|
|
12
12
|
<h1>Variable FERRICSTORE_SDK_VERSION<code class="tsd-tag">Const</code></h1></div>
|
|
13
|
-
<div class="tsd-signature"><span class="tsd-kind-variable">FERRICSTORE_SDK_VERSION</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">"0.
|
|
13
|
+
<div class="tsd-signature"><span class="tsd-kind-variable">FERRICSTORE_SDK_VERSION</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">"0.12.0"</span></div>
|
|
14
14
|
<div class="tsd-comment tsd-typography"><p>TypeScript SDK package version.</p>
|
|
15
15
|
</div><aside class="tsd-sources">
|
|
16
16
|
<ul>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ferricstore/ferricstore",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "TypeScript SDK for FerricStore and FerricFlow",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -52,6 +52,26 @@
|
|
|
52
52
|
"default": "./dist/index.cjs"
|
|
53
53
|
}
|
|
54
54
|
},
|
|
55
|
+
"./langgraph": {
|
|
56
|
+
"import": {
|
|
57
|
+
"types": "./dist/langgraph.d.ts",
|
|
58
|
+
"default": "./dist/langgraph.js"
|
|
59
|
+
},
|
|
60
|
+
"require": {
|
|
61
|
+
"types": "./dist/langgraph.d.cts",
|
|
62
|
+
"default": "./dist/langgraph.cjs"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"./openai-agents": {
|
|
66
|
+
"import": {
|
|
67
|
+
"types": "./dist/openai-agents.d.ts",
|
|
68
|
+
"default": "./dist/openai-agents.js"
|
|
69
|
+
},
|
|
70
|
+
"require": {
|
|
71
|
+
"types": "./dist/openai-agents.d.cts",
|
|
72
|
+
"default": "./dist/openai-agents.cjs"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
55
75
|
"./package.json": "./package.json"
|
|
56
76
|
},
|
|
57
77
|
"files": [
|
|
@@ -61,7 +81,7 @@
|
|
|
61
81
|
"LICENSE"
|
|
62
82
|
],
|
|
63
83
|
"scripts": {
|
|
64
|
-
"build": "tsup src/index.ts --format esm,cjs --dts --sourcemap --clean",
|
|
84
|
+
"build": "tsup src/index.ts src/langgraph.ts src/openai-agents.ts --format esm,cjs --dts --sourcemap --clean --splitting false",
|
|
65
85
|
"check": "npm run typecheck && npm run lint && npm run test && npm run build && npm run test:exports && npm run docs:check",
|
|
66
86
|
"docs": "typedoc",
|
|
67
87
|
"docs:check": "typedoc --logLevel Warn && node scripts/check-generated-docs.mjs",
|
|
@@ -84,6 +104,9 @@
|
|
|
84
104
|
"@emnapi/core": "^1.11.3",
|
|
85
105
|
"@emnapi/runtime": "^1.11.3",
|
|
86
106
|
"@eslint/js": "^10.0.1",
|
|
107
|
+
"@langchain/core": "^1.2.9",
|
|
108
|
+
"@langchain/langgraph": "^1.4.12",
|
|
109
|
+
"@openai/agents": "^0.17.0",
|
|
87
110
|
"@types/node": "^22.20.1",
|
|
88
111
|
"eslint": "^10.9.0",
|
|
89
112
|
"tsup": "^8.5.1",
|
|
@@ -91,5 +114,21 @@
|
|
|
91
114
|
"typescript": "^6.0.3",
|
|
92
115
|
"typescript-eslint": "^8.67.0",
|
|
93
116
|
"vitest": "^4.1.11"
|
|
117
|
+
},
|
|
118
|
+
"peerDependencies": {
|
|
119
|
+
"@langchain/core": ">=1.1.48 <2",
|
|
120
|
+
"@langchain/langgraph": ">=1.4.12 <2",
|
|
121
|
+
"@openai/agents": ">=0.17.0 <1"
|
|
122
|
+
},
|
|
123
|
+
"peerDependenciesMeta": {
|
|
124
|
+
"@langchain/core": {
|
|
125
|
+
"optional": true
|
|
126
|
+
},
|
|
127
|
+
"@langchain/langgraph": {
|
|
128
|
+
"optional": true
|
|
129
|
+
},
|
|
130
|
+
"@openai/agents": {
|
|
131
|
+
"optional": true
|
|
132
|
+
}
|
|
94
133
|
}
|
|
95
134
|
}
|