zidane 5.5.2 → 5.5.4
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/dist/{agent-CvImMxMQ.d.ts → agent-CMAklak7.d.ts} +98 -3
- package/dist/agent-CMAklak7.d.ts.map +1 -0
- package/dist/chat.d.ts +5 -5
- package/dist/chat.js +3 -3
- package/dist/{index-B0uc2C5x.d.ts → index-CF5QwBiz.d.ts} +2 -2
- package/dist/{index-B0uc2C5x.d.ts.map → index-CF5QwBiz.d.ts.map} +1 -1
- package/dist/{index-CtXksgqb.d.ts → index-kroGomhj.d.ts} +2 -2
- package/dist/index-kroGomhj.d.ts.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +5 -5
- package/dist/{login-DthdFNzR.js → login-B_kfoGMP.js} +4 -4
- package/dist/{login-DthdFNzR.js.map → login-B_kfoGMP.js.map} +1 -1
- package/dist/{mcp-C8XUNC_R.js → mcp-BE43Viwi.js} +2 -2
- package/dist/{mcp-C8XUNC_R.js.map → mcp-BE43Viwi.js.map} +1 -1
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.js +1 -1
- package/dist/{presets-C5E9hokO.js → presets-BDvBZuYI.js} +2 -2
- package/dist/{presets-C5E9hokO.js.map → presets-BDvBZuYI.js.map} +1 -1
- package/dist/presets.d.ts +2 -2
- package/dist/presets.js +1 -1
- package/dist/providers.d.ts +1 -1
- package/dist/restate.d.ts +148 -0
- package/dist/restate.d.ts.map +1 -0
- package/dist/restate.js +152 -0
- package/dist/restate.js.map +1 -0
- package/dist/session/sqlite.d.ts +1 -1
- package/dist/session.d.ts +1 -1
- package/dist/skills.d.ts +2 -2
- package/dist/{tools-BavL6n7q.js → tools-Bbd0Ivwn.js} +131 -68
- package/dist/tools-Bbd0Ivwn.js.map +1 -0
- package/dist/tools.d.ts +2 -2
- package/dist/tools.js +1 -1
- package/dist/{transcript-anchors-BMZRmrYk.d.ts → transcript-anchors-C79AszkC.d.ts} +23 -4
- package/dist/transcript-anchors-C79AszkC.d.ts.map +1 -0
- package/dist/tui.d.ts +2 -2
- package/dist/tui.js +16 -8
- package/dist/tui.js.map +1 -1
- package/dist/{turn-operations-DtMApNGT.js → turn-operations-CGf7wWF0.js} +35 -8
- package/dist/turn-operations-CGf7wWF0.js.map +1 -0
- package/dist/{types-C-9h2drI.js → types-oKPBdCmL.js} +7 -2
- package/dist/types-oKPBdCmL.js.map +1 -0
- package/dist/types.d.ts +3 -3
- package/dist/types.js +2 -2
- package/package.json +10 -1
- package/dist/agent-CvImMxMQ.d.ts.map +0 -1
- package/dist/index-CtXksgqb.d.ts.map +0 -1
- package/dist/tools-BavL6n7q.js.map +0 -1
- package/dist/transcript-anchors-BMZRmrYk.d.ts.map +0 -1
- package/dist/turn-operations-DtMApNGT.js.map +0 -1
- package/dist/types-C-9h2drI.js.map +0 -1
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { I as SessionStore, Pt as AgentClock, lt as StreamOptions, ot as Provider, y as ToolDef } from "./agent-CMAklak7.js";
|
|
2
|
+
|
|
3
|
+
//#region src/restate/types.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Minimal structural types mirroring the subset of `@restatedev/restate-sdk`
|
|
6
|
+
* the adapter touches. Kept in-house so:
|
|
7
|
+
*
|
|
8
|
+
* 1. `zidane/restate` typechecks **without** the SDK installed — useful in
|
|
9
|
+
* monorepos that vend `zidane` upstream of Restate.
|
|
10
|
+
* 2. The contract is explicit at the seam: a handful of methods, not the
|
|
11
|
+
* full SDK surface. Drift between SDK versions surfaces as a single
|
|
12
|
+
* type error here instead of cascading through wrapper internals.
|
|
13
|
+
*
|
|
14
|
+
* Consumers wiring the real SDK pass `restate.Context` / `restate.ObjectContext`
|
|
15
|
+
* directly — they're structurally assignable to the shapes below.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Subset of `restate.Context.run` used by the adapter.
|
|
19
|
+
* The SDK's full signature accepts a richer options bag; this captures
|
|
20
|
+
* what the adapter exercises.
|
|
21
|
+
*/
|
|
22
|
+
interface RestateRunOptions {
|
|
23
|
+
/** Max retry attempts before surfacing a terminal error. */
|
|
24
|
+
maxRetryAttempts?: number;
|
|
25
|
+
/** Retry policy passthrough. SDK-shaped object; opaque to the adapter. */
|
|
26
|
+
retryPolicy?: unknown;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Structural subset of `restate.Context` covering everything the
|
|
30
|
+
* adapter's pure wrappers need.
|
|
31
|
+
*
|
|
32
|
+
* `run` journals one side effect; on replay the journaled value returns
|
|
33
|
+
* without re-executing `fn`. `date.now()` is async because the SDK
|
|
34
|
+
* routes it through `ctx.run` internally — replay returns the journaled
|
|
35
|
+
* timestamp. `rand.uuidv4()` is sync because the SDK seeds an in-memory
|
|
36
|
+
* RNG from the invocation id, which is itself replay-stable.
|
|
37
|
+
*/
|
|
38
|
+
interface RestateContextLike {
|
|
39
|
+
run: <T>(name: string, fn: () => Promise<T> | T, options?: RestateRunOptions) => Promise<T>;
|
|
40
|
+
date: {
|
|
41
|
+
now: () => Promise<number>;
|
|
42
|
+
};
|
|
43
|
+
rand: {
|
|
44
|
+
uuidv4: () => string;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Structural subset of `restate.ObjectContext` — adds keyed K/V state
|
|
49
|
+
* scoped to the virtual-object instance the handler is bound to.
|
|
50
|
+
*
|
|
51
|
+
* `get` returns `null` for missing keys (SDK contract). `set` returns
|
|
52
|
+
* void; the SDK journals the mutation transparently.
|
|
53
|
+
*/
|
|
54
|
+
interface RestateObjectContextLike extends RestateContextLike {
|
|
55
|
+
key: string;
|
|
56
|
+
get: <T>(name: string) => Promise<T | null>;
|
|
57
|
+
set: <T>(name: string, value: T) => void;
|
|
58
|
+
clear: (name: string) => void;
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/restate/clock.d.ts
|
|
62
|
+
/**
|
|
63
|
+
* Wrap a Restate context's `date.now()` + `rand.uuidv4()` into the
|
|
64
|
+
* {@link AgentClock} shape Zidane consumes for journaled metadata.
|
|
65
|
+
*
|
|
66
|
+
* The returned clock is a thin live view onto `ctx` — each call hits
|
|
67
|
+
* the SDK afresh. No caching, no closure-captured values. Restate's
|
|
68
|
+
* journal handles determinism on its end.
|
|
69
|
+
*/
|
|
70
|
+
declare function restateClock(ctx: RestateContextLike): AgentClock;
|
|
71
|
+
//#endregion
|
|
72
|
+
//#region src/restate/provider.d.ts
|
|
73
|
+
interface RestateProviderOptions {
|
|
74
|
+
/**
|
|
75
|
+
* `ctx.run` options forwarded on every wrapped stream call. Defaults
|
|
76
|
+
* to `{ maxRetryAttempts: 3 }` — provider transients (rate limits,
|
|
77
|
+
* 5xx, connection resets) get retried inside the journal entry. Once
|
|
78
|
+
* the cap is reached the failure becomes terminal and surfaces
|
|
79
|
+
* through the loop's normal `AgentProviderError` path.
|
|
80
|
+
*/
|
|
81
|
+
runOptions?: RestateRunOptions;
|
|
82
|
+
/**
|
|
83
|
+
* Override the journal-entry name. Receives the 1-indexed sequence
|
|
84
|
+
* number for this wrapper instance and the `StreamOptions` of the
|
|
85
|
+
* call. Default: `llm-call-<n>`. Override to inject extra structure
|
|
86
|
+
* (e.g. `${agentName}/llm-call-${n}`) when multiple agents share a
|
|
87
|
+
* service.
|
|
88
|
+
*/
|
|
89
|
+
entryName?: (seq: number, opts: StreamOptions) => string;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Wrap a Zidane `Provider` so its `stream()` method journals each turn's
|
|
93
|
+
* response inside `ctx.run`. All other Provider methods (`formatTools`,
|
|
94
|
+
* `userMessage`, `toolResultsMessage`, `classifyError`, …) pass through
|
|
95
|
+
* unchanged — they're pure functions over already-deterministic inputs.
|
|
96
|
+
*/
|
|
97
|
+
declare function restateProvider(inner: Provider, ctx: RestateContextLike, options?: RestateProviderOptions): Provider;
|
|
98
|
+
//#endregion
|
|
99
|
+
//#region src/restate/session.d.ts
|
|
100
|
+
/**
|
|
101
|
+
* Construct a `SessionStore` backed by the bound virtual-object's K/V
|
|
102
|
+
* state. The store is single-tenant — every method ignores the
|
|
103
|
+
* `sessionId` argument because the virtual object is already keyed by
|
|
104
|
+
* `ctx.key`. Calling `appendTurns('other-id', …)` writes to the
|
|
105
|
+
* CURRENT object's state, not the one named in the argument. Bind one
|
|
106
|
+
* virtual-object key per session and the contract holds.
|
|
107
|
+
*/
|
|
108
|
+
declare function restateSessionStore(ctx: RestateObjectContextLike): SessionStore;
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region src/restate/tool.d.ts
|
|
111
|
+
interface RestateToolOptions {
|
|
112
|
+
/**
|
|
113
|
+
* `ctx.run` options forwarded on every wrapped tool call. Defaults to
|
|
114
|
+
* `{ maxRetryAttempts: 1 }` — tool errors are typically deterministic
|
|
115
|
+
* (validation failures, missing files) so blind retries waste budget.
|
|
116
|
+
* Override per-tool for network-heavy custom tools that benefit from
|
|
117
|
+
* SDK-level retries.
|
|
118
|
+
*/
|
|
119
|
+
runOptions?: RestateRunOptions;
|
|
120
|
+
/**
|
|
121
|
+
* Override the journal-entry name. Receives the canonical tool name
|
|
122
|
+
* and the call's input. Default: `tool-<name>-<seq>` where `<seq>` is
|
|
123
|
+
* a per-wrapper monotonic counter. Override to inject the model's
|
|
124
|
+
* `callId` (read it off `ToolContext.callId` inside `execute` if you
|
|
125
|
+
* need an LLM-visible key — but the default counter is sufficient
|
|
126
|
+
* for journal correctness).
|
|
127
|
+
*/
|
|
128
|
+
entryName?: (seq: number, name: string, input: Record<string, unknown>) => string;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Wrap a single `ToolDef` so its `execute` runs inside `ctx.run`. The
|
|
132
|
+
* tool's `spec` and `isConcurrencySafe` pass through unchanged.
|
|
133
|
+
*/
|
|
134
|
+
declare function restateTool(inner: ToolDef, ctx: RestateContextLike, options?: RestateToolOptions): ToolDef;
|
|
135
|
+
/**
|
|
136
|
+
* Wrap an entire tool map at once — convenience for the common case of
|
|
137
|
+
* "journal every tool the agent has". Pass-through for tools whose
|
|
138
|
+
* names are listed in `opts.exclude` (e.g. fully-deterministic local
|
|
139
|
+
* helpers where journaling is pure overhead).
|
|
140
|
+
*
|
|
141
|
+
* The returned map is a fresh object; the input is untouched.
|
|
142
|
+
*/
|
|
143
|
+
declare function wrapAgentTools(tools: Record<string, ToolDef>, ctx: RestateContextLike, opts?: RestateToolOptions & {
|
|
144
|
+
exclude?: readonly string[];
|
|
145
|
+
}): Record<string, ToolDef>;
|
|
146
|
+
//#endregion
|
|
147
|
+
export { type RestateContextLike, type RestateObjectContextLike, type RestateProviderOptions, type RestateRunOptions, type RestateToolOptions, restateClock, restateProvider, restateSessionStore, restateTool, wrapAgentTools };
|
|
148
|
+
//# sourceMappingURL=restate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restate.d.ts","names":[],"sources":["../src/restate/types.ts","../src/restate/clock.ts","../src/restate/provider.ts","../src/restate/session.ts","../src/restate/tool.ts"],"mappings":";;;;;;AAmBA;;;;;AAiBA;;;;;;;;;;UAjBiB,iBAAA;EAuBW;EArB1B,gBAAA;EAgBM;EAdN,WAAA;AAAA;;;;;;;;;;;UAae,kBAAA;EACf,GAAA,MACE,IAAA,UACA,EAAA,QAAU,OAAA,CAAQ,CAAA,IAAK,CAAA,EACvB,OAAA,GAAU,iBAAA,KACP,OAAA,CAAQ,CAAA;EACb,IAAA;IAAQ,GAAA,QAAW,OAAA;EAAA;EACnB,IAAA;IAAQ,MAAA;EAAA;AAAA;;;;;;;;UAUO,wBAAA,SAAiC,kBAAA;EAChD,GAAA;EACA,GAAA,MAAS,IAAA,aAAiB,OAAA,CAAQ,CAAA;EAClC,GAAA,MAAS,IAAA,UAAc,KAAA,EAAO,CAAA;EAC9B,KAAA,GAAQ,IAAA;AAAA;;;;;;;;;;;iBCnCM,YAAA,CAAa,GAAA,EAAK,kBAAA,GAAqB,UAAA;;;UCGtC,sBAAA;EFcK;;;;;;;EENpB,UAAA,GAAa,iBAAA;EFSL;;;;;;AAWV;EEZE,SAAA,IAAa,GAAA,UAAa,IAAA,EAAM,aAAA;AAAA;;;;;;;iBASlB,eAAA,CACd,KAAA,EAAO,QAAA,EACP,GAAA,EAAK,kBAAA,EACL,OAAA,GAAS,sBAAA,GACR,QAAA;;;;;;;;;;;iBCKa,mBAAA,CAAoB,GAAA,EAAK,wBAAA,GAA2B,YAAA;;;UC/BnD,kBAAA;EJYH;;;;;;;EIJZ,UAAA,GAAa,iBAAA;EJOL;;;AAUV;;;;;EIRE,SAAA,IAAa,GAAA,UAAa,IAAA,UAAc,KAAA,EAAO,MAAA;AAAA;;;;;iBAOjC,WAAA,CACd,KAAA,EAAO,OAAA,EACP,GAAA,EAAK,kBAAA,EACL,OAAA,GAAS,kBAAA,GACR,OAAA;;;;;;;;;iBA2Ba,cAAA,CACd,KAAA,EAAO,MAAA,SAAe,OAAA,GACtB,GAAA,EAAK,kBAAA,EACL,IAAA,GAAM,kBAAA;EAAuB,OAAA;AAAA,IAC5B,MAAA,SAAe,OAAA"}
|
package/dist/restate.js
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
//#region src/restate/clock.ts
|
|
2
|
+
/**
|
|
3
|
+
* Wrap a Restate context's `date.now()` + `rand.uuidv4()` into the
|
|
4
|
+
* {@link AgentClock} shape Zidane consumes for journaled metadata.
|
|
5
|
+
*
|
|
6
|
+
* The returned clock is a thin live view onto `ctx` — each call hits
|
|
7
|
+
* the SDK afresh. No caching, no closure-captured values. Restate's
|
|
8
|
+
* journal handles determinism on its end.
|
|
9
|
+
*/
|
|
10
|
+
function restateClock(ctx) {
|
|
11
|
+
return {
|
|
12
|
+
now: () => ctx.date.now(),
|
|
13
|
+
randomUUID: () => ctx.rand.uuidv4()
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/restate/provider.ts
|
|
18
|
+
/**
|
|
19
|
+
* Wrap a Zidane `Provider` so its `stream()` method journals each turn's
|
|
20
|
+
* response inside `ctx.run`. All other Provider methods (`formatTools`,
|
|
21
|
+
* `userMessage`, `toolResultsMessage`, `classifyError`, …) pass through
|
|
22
|
+
* unchanged — they're pure functions over already-deterministic inputs.
|
|
23
|
+
*/
|
|
24
|
+
function restateProvider(inner, ctx, options = {}) {
|
|
25
|
+
const runOpts = options.runOptions ?? { maxRetryAttempts: 3 };
|
|
26
|
+
const nameFor = options.entryName ?? ((seq) => `llm-call-${seq}`);
|
|
27
|
+
let seq = 0;
|
|
28
|
+
return {
|
|
29
|
+
...inner,
|
|
30
|
+
stream(streamOpts, callbacks) {
|
|
31
|
+
seq += 1;
|
|
32
|
+
return ctx.run(nameFor(seq, streamOpts), () => inner.stream(streamOpts, callbacks), runOpts);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region src/restate/session.ts
|
|
38
|
+
const KEY_DATA = "session-data";
|
|
39
|
+
const KEY_TURNS = "session-turns";
|
|
40
|
+
const KEY_RUNS = "session-runs";
|
|
41
|
+
/**
|
|
42
|
+
* Construct a `SessionStore` backed by the bound virtual-object's K/V
|
|
43
|
+
* state. The store is single-tenant — every method ignores the
|
|
44
|
+
* `sessionId` argument because the virtual object is already keyed by
|
|
45
|
+
* `ctx.key`. Calling `appendTurns('other-id', …)` writes to the
|
|
46
|
+
* CURRENT object's state, not the one named in the argument. Bind one
|
|
47
|
+
* virtual-object key per session and the contract holds.
|
|
48
|
+
*/
|
|
49
|
+
function restateSessionStore(ctx) {
|
|
50
|
+
return {
|
|
51
|
+
/**
|
|
52
|
+
* Turn-id mint backed by Restate's seeded RNG. Critical: without
|
|
53
|
+
* this, `Session.generateTurnId` falls through to
|
|
54
|
+
* `crypto.randomUUID()` (see `src/session/index.ts`), so every
|
|
55
|
+
* assistant / tool-results turn id drifts across replays even
|
|
56
|
+
* though `AgentClock.randomUUID` is wired correctly — the loop
|
|
57
|
+
* calls `session?.generateTurnId() ?? clock.randomUUID()`, and a
|
|
58
|
+
* session that always returns a value short-circuits the fallback.
|
|
59
|
+
*/
|
|
60
|
+
generateTurnId: () => ctx.rand.uuidv4(),
|
|
61
|
+
async load(_sessionId) {
|
|
62
|
+
const header = await ctx.get(KEY_DATA);
|
|
63
|
+
if (!header) return null;
|
|
64
|
+
const turns = await ctx.get(KEY_TURNS) ?? [];
|
|
65
|
+
const runs = await ctx.get(KEY_RUNS) ?? [];
|
|
66
|
+
return {
|
|
67
|
+
...header,
|
|
68
|
+
turns,
|
|
69
|
+
runs
|
|
70
|
+
};
|
|
71
|
+
},
|
|
72
|
+
async save(session) {
|
|
73
|
+
const { turns, runs, ...header } = session;
|
|
74
|
+
ctx.set(KEY_DATA, header);
|
|
75
|
+
ctx.set(KEY_TURNS, turns);
|
|
76
|
+
ctx.set(KEY_RUNS, runs);
|
|
77
|
+
},
|
|
78
|
+
async delete(_sessionId) {
|
|
79
|
+
ctx.clear(KEY_DATA);
|
|
80
|
+
ctx.clear(KEY_TURNS);
|
|
81
|
+
ctx.clear(KEY_RUNS);
|
|
82
|
+
},
|
|
83
|
+
/**
|
|
84
|
+
* Always empty — virtual objects don't support cross-key
|
|
85
|
+
* enumeration. Maintain a separate index handler if discovery
|
|
86
|
+
* matters.
|
|
87
|
+
*/
|
|
88
|
+
async list() {
|
|
89
|
+
return [];
|
|
90
|
+
},
|
|
91
|
+
async appendTurns(_sessionId, turns) {
|
|
92
|
+
const existing = await ctx.get(KEY_TURNS) ?? [];
|
|
93
|
+
ctx.set(KEY_TURNS, [...existing, ...turns]);
|
|
94
|
+
},
|
|
95
|
+
async getTurns(_sessionId, from = 0, limit) {
|
|
96
|
+
return (await ctx.get(KEY_TURNS) ?? []).slice(from, limit !== void 0 ? from + limit : void 0);
|
|
97
|
+
},
|
|
98
|
+
async updateRun(_sessionId, run) {
|
|
99
|
+
const runs = await ctx.get(KEY_RUNS) ?? [];
|
|
100
|
+
const idx = runs.findIndex((r) => r.id === run.id);
|
|
101
|
+
const next = [...runs];
|
|
102
|
+
if (idx >= 0) next[idx] = run;
|
|
103
|
+
else next.push(run);
|
|
104
|
+
ctx.set(KEY_RUNS, next);
|
|
105
|
+
},
|
|
106
|
+
async updateStatus(_sessionId, status) {
|
|
107
|
+
const header = await ctx.get(KEY_DATA);
|
|
108
|
+
if (header) ctx.set(KEY_DATA, {
|
|
109
|
+
...header,
|
|
110
|
+
status,
|
|
111
|
+
updatedAt: await ctx.date.now()
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
//#endregion
|
|
117
|
+
//#region src/restate/tool.ts
|
|
118
|
+
/**
|
|
119
|
+
* Wrap a single `ToolDef` so its `execute` runs inside `ctx.run`. The
|
|
120
|
+
* tool's `spec` and `isConcurrencySafe` pass through unchanged.
|
|
121
|
+
*/
|
|
122
|
+
function restateTool(inner, ctx, options = {}) {
|
|
123
|
+
const runOpts = options.runOptions ?? { maxRetryAttempts: 1 };
|
|
124
|
+
const nameFor = options.entryName ?? ((seq, name) => `tool-${name}-${seq}`);
|
|
125
|
+
const canonicalName = inner.spec.name;
|
|
126
|
+
let seq = 0;
|
|
127
|
+
return {
|
|
128
|
+
...inner,
|
|
129
|
+
execute: (input, toolCtx) => {
|
|
130
|
+
seq += 1;
|
|
131
|
+
return ctx.run(nameFor(seq, canonicalName, input), () => inner.execute(input, toolCtx), runOpts);
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Wrap an entire tool map at once — convenience for the common case of
|
|
137
|
+
* "journal every tool the agent has". Pass-through for tools whose
|
|
138
|
+
* names are listed in `opts.exclude` (e.g. fully-deterministic local
|
|
139
|
+
* helpers where journaling is pure overhead).
|
|
140
|
+
*
|
|
141
|
+
* The returned map is a fresh object; the input is untouched.
|
|
142
|
+
*/
|
|
143
|
+
function wrapAgentTools(tools, ctx, opts = {}) {
|
|
144
|
+
const excludeSet = new Set(opts.exclude ?? []);
|
|
145
|
+
const wrapped = {};
|
|
146
|
+
for (const [name, def] of Object.entries(tools)) wrapped[name] = excludeSet.has(name) ? def : restateTool(def, ctx, opts);
|
|
147
|
+
return wrapped;
|
|
148
|
+
}
|
|
149
|
+
//#endregion
|
|
150
|
+
export { restateClock, restateProvider, restateSessionStore, restateTool, wrapAgentTools };
|
|
151
|
+
|
|
152
|
+
//# sourceMappingURL=restate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restate.js","names":[],"sources":["../src/restate/clock.ts","../src/restate/provider.ts","../src/restate/session.ts","../src/restate/tool.ts"],"sourcesContent":["/**\n * Restate-backed {@link AgentClock} — journals `now()` + `randomUUID()` so\n * every `SessionTurn.id` / `SessionTurn.createdAt` / `runId` / synthetic\n * turn id stays byte-identical across replays of the same invocation.\n *\n * Pass to `agent.run({ clock: restateClock(ctx) })` or bake it into\n * `createAgent({ clock: restateClock(ctx) })` for the duration of a\n * handler invocation. The clock holds a reference to `ctx`; do not reuse\n * a clock instance across invocations.\n */\n\nimport type { AgentClock } from '../types'\nimport type { RestateContextLike } from './types'\n\n/**\n * Wrap a Restate context's `date.now()` + `rand.uuidv4()` into the\n * {@link AgentClock} shape Zidane consumes for journaled metadata.\n *\n * The returned clock is a thin live view onto `ctx` — each call hits\n * the SDK afresh. No caching, no closure-captured values. Restate's\n * journal handles determinism on its end.\n */\nexport function restateClock(ctx: RestateContextLike): AgentClock {\n return {\n now: () => ctx.date.now(),\n randomUUID: () => ctx.rand.uuidv4(),\n }\n}\n","/**\n * Restate-backed Provider wrapper.\n *\n * Wraps `Provider.stream` so every assistant turn (the LLM call as a\n * whole) is journaled. The model is invoked once per turn — the live\n * stream still fires `onText` / `onThinking` callbacks for UX during the\n * original execution. On replay, `ctx.run` returns the journaled\n * `TurnResult` immediately and the inner provider is NEVER re-invoked →\n * no duplicate billed tokens, no duplicate stream chunks.\n *\n * Replay caveat: stream callbacks don't re-fire on replay. Consumers\n * that paint live UI from `stream:text` should reconstruct transcripts\n * from `session.turns` via `eventsFromTurns` (zidane/chat) instead of\n * relying on hook re-emission. The chat layer already does this.\n *\n * Journal-entry naming: a monotonic per-wrapper counter (`llm-call-1`,\n * `llm-call-2`, …). One wrapper instance per Restate handler invocation\n * resets the counter; Restate's journal is invocation-scoped so names\n * don't need to be globally unique. The counter ticks the same way on\n * replay because the wrapper is constructed fresh each attempt.\n */\n\nimport type { Provider, StreamCallbacks, StreamOptions, TurnResult } from '../providers'\nimport type { RestateContextLike, RestateRunOptions } from './types'\n\nexport interface RestateProviderOptions {\n /**\n * `ctx.run` options forwarded on every wrapped stream call. Defaults\n * to `{ maxRetryAttempts: 3 }` — provider transients (rate limits,\n * 5xx, connection resets) get retried inside the journal entry. Once\n * the cap is reached the failure becomes terminal and surfaces\n * through the loop's normal `AgentProviderError` path.\n */\n runOptions?: RestateRunOptions\n /**\n * Override the journal-entry name. Receives the 1-indexed sequence\n * number for this wrapper instance and the `StreamOptions` of the\n * call. Default: `llm-call-<n>`. Override to inject extra structure\n * (e.g. `${agentName}/llm-call-${n}`) when multiple agents share a\n * service.\n */\n entryName?: (seq: number, opts: StreamOptions) => string\n}\n\n/**\n * Wrap a Zidane `Provider` so its `stream()` method journals each turn's\n * response inside `ctx.run`. All other Provider methods (`formatTools`,\n * `userMessage`, `toolResultsMessage`, `classifyError`, …) pass through\n * unchanged — they're pure functions over already-deterministic inputs.\n */\nexport function restateProvider(\n inner: Provider,\n ctx: RestateContextLike,\n options: RestateProviderOptions = {},\n): Provider {\n const runOpts: RestateRunOptions = options.runOptions ?? { maxRetryAttempts: 3 }\n const nameFor = options.entryName ?? ((seq: number) => `llm-call-${seq}`)\n let seq = 0\n\n return {\n ...inner,\n stream(streamOpts: StreamOptions, callbacks: StreamCallbacks): Promise<TurnResult> {\n seq += 1\n return ctx.run<TurnResult>(\n nameFor(seq, streamOpts),\n () => inner.stream(streamOpts, callbacks),\n runOpts,\n )\n },\n }\n}\n","/**\n * Restate-backed `SessionStore` — turn / run state lives in the bound\n * virtual object's K/V state instead of SQLite / file / remote HTTP.\n *\n * Trade-offs vs. journal-only replay\n * ----------------------------------\n * If you only care about durable execution within ONE invocation,\n * skip this — the journaled `ctx.run` entries (LLM calls, tool\n * executions) are enough to replay the loop to byte-identical state\n * after a crash. The in-memory `createMemoryStore()` is the right\n * choice; turns rematerialize from the journal each replay.\n *\n * Pick this store when EXTERNAL consumers (TUI, web GUI, support\n * tooling) need to read a session's history WITHOUT re-entering the\n * agent handler. Virtual-object state is exposed via the SDK's read\n * APIs (`ctx.get` from another handler, `restate-cli`, the Restate\n * web UI) — same data, different access path. The journal is\n * invocation-local; this state is the externally-visible projection\n * of it.\n *\n * Storage layout\n * --------------\n * One virtual-object key per session, three K/V slots:\n *\n * `data` → `SessionData` minus the `turns` array (small header)\n * `turns` → `SessionTurn[]` (the conversation history)\n * `runs` → `SessionRun[]` (run lifecycle records)\n *\n * Splitting `turns` / `runs` out keeps the header light for `load()` —\n * a handler that only needs metadata doesn't pull the full history.\n *\n * Listing / discovery\n * -------------------\n * `list()` returns `[]` and `delete()` no-ops — virtual objects don't\n * expose cross-key enumeration. Use a separate index handler if you\n * need it (one virtual object per `projectRoot` that maintains an\n * indexed list of session ids; this store doesn't own that concern).\n * `generateSessionId` is omitted so the agent falls back to its\n * default UUID generator — for a session bound 1:1 to a virtual-\n * object key, pass `id: ctx.key` to `createSession()` instead and\n * skip ID generation entirely.\n */\n\nimport type { SessionData, SessionRun, SessionStore } from '../session'\nimport type { SessionTurn } from '../types'\nimport type { RestateObjectContextLike } from './types'\n\nconst KEY_DATA = 'session-data'\nconst KEY_TURNS = 'session-turns'\nconst KEY_RUNS = 'session-runs'\n\n/**\n * Construct a `SessionStore` backed by the bound virtual-object's K/V\n * state. The store is single-tenant — every method ignores the\n * `sessionId` argument because the virtual object is already keyed by\n * `ctx.key`. Calling `appendTurns('other-id', …)` writes to the\n * CURRENT object's state, not the one named in the argument. Bind one\n * virtual-object key per session and the contract holds.\n */\nexport function restateSessionStore(ctx: RestateObjectContextLike): SessionStore {\n return {\n /**\n * Turn-id mint backed by Restate's seeded RNG. Critical: without\n * this, `Session.generateTurnId` falls through to\n * `crypto.randomUUID()` (see `src/session/index.ts`), so every\n * assistant / tool-results turn id drifts across replays even\n * though `AgentClock.randomUUID` is wired correctly — the loop\n * calls `session?.generateTurnId() ?? clock.randomUUID()`, and a\n * session that always returns a value short-circuits the fallback.\n */\n generateTurnId: () => ctx.rand.uuidv4(),\n\n async load(_sessionId: string): Promise<SessionData | null> {\n const header = await ctx.get<Omit<SessionData, 'turns' | 'runs'>>(KEY_DATA)\n if (!header)\n return null\n const turns = (await ctx.get<SessionTurn[]>(KEY_TURNS)) ?? []\n const runs = (await ctx.get<SessionRun[]>(KEY_RUNS)) ?? []\n return { ...header, turns, runs }\n },\n\n async save(session: SessionData): Promise<void> {\n const { turns, runs, ...header } = session\n ctx.set(KEY_DATA, header)\n ctx.set(KEY_TURNS, turns)\n ctx.set(KEY_RUNS, runs)\n },\n\n async delete(_sessionId: string): Promise<void> {\n ctx.clear(KEY_DATA)\n ctx.clear(KEY_TURNS)\n ctx.clear(KEY_RUNS)\n },\n\n /**\n * Always empty — virtual objects don't support cross-key\n * enumeration. Maintain a separate index handler if discovery\n * matters.\n */\n async list(): Promise<string[]> {\n return []\n },\n\n async appendTurns(_sessionId: string, turns: SessionTurn[]): Promise<void> {\n const existing = (await ctx.get<SessionTurn[]>(KEY_TURNS)) ?? []\n ctx.set(KEY_TURNS, [...existing, ...turns])\n },\n\n async getTurns(_sessionId: string, from = 0, limit?: number): Promise<SessionTurn[]> {\n const turns = (await ctx.get<SessionTurn[]>(KEY_TURNS)) ?? []\n return turns.slice(from, limit !== undefined ? from + limit : undefined)\n },\n\n async updateRun(_sessionId: string, run: SessionRun): Promise<void> {\n const runs = (await ctx.get<SessionRun[]>(KEY_RUNS)) ?? []\n const idx = runs.findIndex(r => r.id === run.id)\n const next = [...runs]\n if (idx >= 0)\n next[idx] = run\n else\n next.push(run)\n ctx.set(KEY_RUNS, next)\n },\n\n async updateStatus(_sessionId: string, status: SessionData['status']): Promise<void> {\n const header = await ctx.get<Omit<SessionData, 'turns' | 'runs'>>(KEY_DATA)\n if (header) {\n ctx.set(KEY_DATA, { ...header, status, updatedAt: await ctx.date.now() })\n }\n },\n }\n}\n","/**\n * Restate-backed tool wrappers.\n *\n * Wraps `ToolDef.execute` so every tool invocation is journaled. The\n * tool body runs once on the original execution; on replay `ctx.run`\n * returns the journaled result without re-executing. Side effects\n * (`write_file` to disk, network POSTs in custom tools) happen\n * **exactly once** across crashes + retries — the entire reason for\n * pairing Zidane with Restate.\n *\n * `tool:gate`, `tool:transform`, `tool:after` hooks fire OUTSIDE the\n * journaled boundary, so they re-execute on replay. Built-in handlers\n * are deterministic given the journaled input + output (truncation,\n * image-stripping, `<edit-outcomes>` merge — all pure). Consumer hooks\n * that hit external services should themselves wrap side effects in\n * `ctx.run` so the substitution / annotation is replay-stable.\n *\n * `isConcurrencySafe` is preserved — Restate's per-key serialization\n * doesn't preclude in-handler parallelism. The loop's scheduler still\n * fans out safe tools up to `behavior.maxConcurrentTools`, each call\n * lands in its own journal entry. Order-of-journal-completion does NOT\n * affect replay correctness: Restate journals by call-site name, not\n * by completion order.\n */\n\nimport type { ToolDef } from '../tools/types'\nimport type { RestateContextLike, RestateRunOptions } from './types'\n\nexport interface RestateToolOptions {\n /**\n * `ctx.run` options forwarded on every wrapped tool call. Defaults to\n * `{ maxRetryAttempts: 1 }` — tool errors are typically deterministic\n * (validation failures, missing files) so blind retries waste budget.\n * Override per-tool for network-heavy custom tools that benefit from\n * SDK-level retries.\n */\n runOptions?: RestateRunOptions\n /**\n * Override the journal-entry name. Receives the canonical tool name\n * and the call's input. Default: `tool-<name>-<seq>` where `<seq>` is\n * a per-wrapper monotonic counter. Override to inject the model's\n * `callId` (read it off `ToolContext.callId` inside `execute` if you\n * need an LLM-visible key — but the default counter is sufficient\n * for journal correctness).\n */\n entryName?: (seq: number, name: string, input: Record<string, unknown>) => string\n}\n\n/**\n * Wrap a single `ToolDef` so its `execute` runs inside `ctx.run`. The\n * tool's `spec` and `isConcurrencySafe` pass through unchanged.\n */\nexport function restateTool(\n inner: ToolDef,\n ctx: RestateContextLike,\n options: RestateToolOptions = {},\n): ToolDef {\n const runOpts: RestateRunOptions = options.runOptions ?? { maxRetryAttempts: 1 }\n const nameFor = options.entryName ?? ((seq: number, name: string) => `tool-${name}-${seq}`)\n const canonicalName = inner.spec.name\n let seq = 0\n\n return {\n ...inner,\n execute: (input, toolCtx) => {\n seq += 1\n return ctx.run(\n nameFor(seq, canonicalName, input),\n () => inner.execute(input, toolCtx),\n runOpts,\n )\n },\n }\n}\n\n/**\n * Wrap an entire tool map at once — convenience for the common case of\n * \"journal every tool the agent has\". Pass-through for tools whose\n * names are listed in `opts.exclude` (e.g. fully-deterministic local\n * helpers where journaling is pure overhead).\n *\n * The returned map is a fresh object; the input is untouched.\n */\nexport function wrapAgentTools(\n tools: Record<string, ToolDef>,\n ctx: RestateContextLike,\n opts: RestateToolOptions & { exclude?: readonly string[] } = {},\n): Record<string, ToolDef> {\n const excludeSet = new Set(opts.exclude ?? [])\n const wrapped: Record<string, ToolDef> = {}\n for (const [name, def] of Object.entries(tools)) {\n wrapped[name] = excludeSet.has(name) ? def : restateTool(def, ctx, opts)\n }\n return wrapped\n}\n"],"mappings":"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"}
|
package/dist/session/sqlite.d.ts
CHANGED
package/dist/session.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $ as fromOpenAI, B as createRemoteStore, F as SessionRun, I as SessionStore, J as autoDetectAndConvert,
|
|
1
|
+
import { $ as fromOpenAI, B as createRemoteStore, F as SessionRun, I as SessionStore, J as autoDetectAndConvert, Jt as SessionContentBlock, L as createSession, M as CreateSessionOptions, N as Session, P as SessionData, Q as fromAnthropic, Qt as SessionTurn, R as loadSession, Zt as SessionMessage, at as createFileMapStore, et as toAnthropic, it as FileMapStoreOptions, nt as createMemoryStore, rt as FileMapAdapter, tt as toOpenAI, z as RemoteStoreOptions } from "./agent-CMAklak7.js";
|
|
2
2
|
export { CreateSessionOptions, FileMapAdapter, FileMapStoreOptions, RemoteStoreOptions, Session, SessionContentBlock, SessionData, SessionMessage, SessionRun, SessionStore, SessionTurn, autoDetectAndConvert, createFileMapStore, createMemoryStore, createRemoteStore, createSession, fromAnthropic, fromOpenAI, loadSession, toAnthropic, toOpenAI };
|
package/dist/skills.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { A as SkillSource, D as SkillConfig, O as SkillDiagnostic, c as DeactivationReason, d as createSkillActivationState, j as SkillsConfig, k as SkillResource, l as SkillActivationState, o as ActivationVia, s as ActiveSkill, u as SkillActivationStateOptions } from "./agent-
|
|
2
|
-
import { S as installAllowedToolsGate, _ as inferSource, a as SkillValidationResult, b as buildCatalog, c as parseAllowedToolPattern, d as validateSkillName, f as resolveSkills, g as getDefaultScanPaths, h as discoverSkills, i as SkillValidationIssue, l as validateResourcePath, m as SourcedScanPath, n as writeSkillToDisk, o as isToolAllowedByUnion, p as interpolateShellCommands, r as writeSkillsToDisk, s as matchesAllowedTool, t as defineSkill, u as validateSkillForWrite, v as parseFrontmatter, x as IMPLICITLY_ALLOWED_SKILL_TOOLS, y as parseSkillFile } from "./index-
|
|
1
|
+
import { A as SkillSource, D as SkillConfig, O as SkillDiagnostic, c as DeactivationReason, d as createSkillActivationState, j as SkillsConfig, k as SkillResource, l as SkillActivationState, o as ActivationVia, s as ActiveSkill, u as SkillActivationStateOptions } from "./agent-CMAklak7.js";
|
|
2
|
+
import { S as installAllowedToolsGate, _ as inferSource, a as SkillValidationResult, b as buildCatalog, c as parseAllowedToolPattern, d as validateSkillName, f as resolveSkills, g as getDefaultScanPaths, h as discoverSkills, i as SkillValidationIssue, l as validateResourcePath, m as SourcedScanPath, n as writeSkillToDisk, o as isToolAllowedByUnion, p as interpolateShellCommands, r as writeSkillsToDisk, s as matchesAllowedTool, t as defineSkill, u as validateSkillForWrite, v as parseFrontmatter, x as IMPLICITLY_ALLOWED_SKILL_TOOLS, y as parseSkillFile } from "./index-CF5QwBiz.js";
|
|
3
3
|
export { ActivationVia, ActiveSkill, DeactivationReason, IMPLICITLY_ALLOWED_SKILL_TOOLS, SkillActivationState, SkillActivationStateOptions, SkillConfig, SkillDiagnostic, SkillResource, SkillSource, SkillValidationIssue, SkillValidationResult, SkillsConfig, SourcedScanPath, buildCatalog, createSkillActivationState, defineSkill, discoverSkills, getDefaultScanPaths, inferSource, installAllowedToolsGate, interpolateShellCommands, isToolAllowedByUnion, matchesAllowedTool, parseAllowedToolPattern, parseFrontmatter, parseSkillFile, resolveSkills, validateResourcePath, validateSkillForWrite, validateSkillName, writeSkillToDisk, writeSkillsToDisk };
|