@graphorin/core 0.6.0 → 0.7.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/CHANGELOG.md +88 -0
- package/README.md +14 -8
- package/dist/channels/channels.d.ts.map +1 -1
- package/dist/channels/index.d.ts +2 -2
- package/dist/channels/index.js +2 -2
- package/dist/channels/pause.d.ts +47 -2
- package/dist/channels/pause.d.ts.map +1 -1
- package/dist/channels/pause.js +62 -2
- package/dist/channels/pause.js.map +1 -1
- package/dist/contracts/checkpoint-store.d.ts +97 -1
- package/dist/contracts/checkpoint-store.d.ts.map +1 -1
- package/dist/contracts/checkpoint-store.js.map +1 -1
- package/dist/contracts/index.d.ts +5 -5
- package/dist/contracts/index.js +2 -1
- package/dist/contracts/memory-store.d.ts +59 -2
- package/dist/contracts/memory-store.d.ts.map +1 -1
- package/dist/contracts/provider.d.ts +20 -6
- package/dist/contracts/provider.d.ts.map +1 -1
- package/dist/contracts/session-store.d.ts +10 -2
- package/dist/contracts/session-store.d.ts.map +1 -1
- package/dist/contracts/tool.d.ts +75 -1
- package/dist/contracts/tool.d.ts.map +1 -1
- package/dist/contracts/tool.js +57 -0
- package/dist/contracts/tool.js.map +1 -0
- package/dist/contracts/tracer.d.ts +53 -5
- package/dist/contracts/tracer.d.ts.map +1 -1
- package/dist/contracts/tracer.js.map +1 -1
- package/dist/index.d.ts +14 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -7
- package/dist/index.js.map +1 -1
- package/dist/package.js +6 -0
- package/dist/package.js.map +1 -0
- package/dist/types/agent-event-wire.d.ts +74 -0
- package/dist/types/agent-event-wire.d.ts.map +1 -0
- package/dist/types/agent-event-wire.js +130 -0
- package/dist/types/agent-event-wire.js.map +1 -0
- package/dist/types/agent-event.d.ts +48 -6
- package/dist/types/agent-event.d.ts.map +1 -1
- package/dist/types/index.d.ts +3 -2
- package/dist/types/index.js +2 -1
- package/dist/types/memory.d.ts +11 -0
- package/dist/types/memory.d.ts.map +1 -1
- package/dist/types/run.d.ts +86 -4
- package/dist/types/run.d.ts.map +1 -1
- package/dist/types/run.js.map +1 -1
- package/dist/types/tool.d.ts +10 -0
- package/dist/types/tool.d.ts.map +1 -1
- package/dist/types/usage.d.ts +11 -1
- package/dist/types/usage.d.ts.map +1 -1
- package/dist/types/usage.js.map +1 -1
- package/dist/utils/binary-json.d.ts +165 -0
- package/dist/utils/binary-json.d.ts.map +1 -0
- package/dist/utils/binary-json.js +240 -0
- package/dist/utils/binary-json.js.map +1 -0
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/index.js +2 -1
- package/dist/utils/validation.d.ts +10 -1
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +1 -1
- package/dist/utils/validation.js.map +1 -1
- package/package.json +9 -7
- package/src/channels/channels.ts +206 -0
- package/src/channels/directive.ts +41 -0
- package/src/channels/dispatch.ts +37 -0
- package/src/channels/durable.ts +151 -0
- package/src/channels/index.ts +62 -0
- package/src/channels/pause.ts +216 -0
- package/src/contracts/auth-token-store.ts +42 -0
- package/src/contracts/checkpoint-store.ts +256 -0
- package/src/contracts/embedder.ts +42 -0
- package/src/contracts/eval-scorer.ts +44 -0
- package/src/contracts/index.ts +112 -0
- package/src/contracts/local-provider-trust.ts +33 -0
- package/src/contracts/logger.ts +61 -0
- package/src/contracts/memory-store.ts +187 -0
- package/src/contracts/oauth-server-store.ts +78 -0
- package/src/contracts/preferred-model.ts +56 -0
- package/src/contracts/provider.ts +316 -0
- package/src/contracts/reasoning-retention.ts +52 -0
- package/src/contracts/redaction-validator.ts +56 -0
- package/src/contracts/sandbox.ts +70 -0
- package/src/contracts/secret-ref.ts +22 -0
- package/src/contracts/secret-value.ts +117 -0
- package/src/contracts/secrets-store.ts +90 -0
- package/src/contracts/session-store.ts +163 -0
- package/src/contracts/token-counter.ts +23 -0
- package/src/contracts/tool.ts +397 -0
- package/src/contracts/tracer.ts +219 -0
- package/src/contracts/trigger-store.ts +40 -0
- package/src/index.ts +23 -0
- package/src/types/agent-event-wire.ts +193 -0
- package/src/types/agent-event.ts +579 -0
- package/src/types/handoff.ts +111 -0
- package/src/types/index.ts +148 -0
- package/src/types/memory.ts +427 -0
- package/src/types/message.ts +174 -0
- package/src/types/run.ts +312 -0
- package/src/types/sensitivity.ts +35 -0
- package/src/types/session-scope.ts +18 -0
- package/src/types/stop-condition.ts +108 -0
- package/src/types/tool-call.ts +24 -0
- package/src/types/tool.ts +324 -0
- package/src/types/usage.ts +120 -0
- package/src/types/workflow-event.ts +132 -0
- package/src/utils/assert-never.ts +24 -0
- package/src/utils/async-context.ts +55 -0
- package/src/utils/binary-json.ts +425 -0
- package/src/utils/hash.ts +122 -0
- package/src/utils/index.ts +57 -0
- package/src/utils/streams.ts +233 -0
- package/src/utils/validation.ts +82 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stream / async-iterable helpers. All helpers honor `AbortSignal`
|
|
3
|
+
* propagation: when the supplied signal aborts, the underlying
|
|
4
|
+
* iterator's `return()` method is invoked so that resources held by the
|
|
5
|
+
* upstream generator are released cleanly.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Internal helper: detect whether `it` already has its own
|
|
12
|
+
* `AsyncIterator.return` so we know whether to forward cancellations.
|
|
13
|
+
*/
|
|
14
|
+
function hasReturn<T>(
|
|
15
|
+
iter: AsyncIterator<T>,
|
|
16
|
+
): iter is AsyncIterator<T> & { return: NonNullable<AsyncIterator<T>['return']> } {
|
|
17
|
+
return typeof iter.return === 'function';
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Drain an `AsyncIterable` into an array.
|
|
22
|
+
*
|
|
23
|
+
* @stable
|
|
24
|
+
*/
|
|
25
|
+
export async function collect<T>(source: AsyncIterable<T>, signal?: AbortSignal): Promise<T[]> {
|
|
26
|
+
const out: T[] = [];
|
|
27
|
+
for await (const item of withSignal(source, signal)) {
|
|
28
|
+
out.push(item);
|
|
29
|
+
}
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Map every value of an async iterable. The mapper may be async.
|
|
35
|
+
* Cancellation via `signal` is honored.
|
|
36
|
+
*
|
|
37
|
+
* @stable
|
|
38
|
+
*/
|
|
39
|
+
export async function* mapStream<T, U>(
|
|
40
|
+
source: AsyncIterable<T>,
|
|
41
|
+
fn: (value: T, index: number) => U | Promise<U>,
|
|
42
|
+
signal?: AbortSignal,
|
|
43
|
+
): AsyncIterable<U> {
|
|
44
|
+
let index = 0;
|
|
45
|
+
for await (const item of withSignal(source, signal)) {
|
|
46
|
+
yield await fn(item, index++);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Filter values produced by `source`. The predicate may be async.
|
|
52
|
+
*
|
|
53
|
+
* @stable
|
|
54
|
+
*/
|
|
55
|
+
export async function* filter<T>(
|
|
56
|
+
source: AsyncIterable<T>,
|
|
57
|
+
pred: (value: T, index: number) => boolean | Promise<boolean>,
|
|
58
|
+
signal?: AbortSignal,
|
|
59
|
+
): AsyncIterable<T> {
|
|
60
|
+
let index = 0;
|
|
61
|
+
for await (const item of withSignal(source, signal)) {
|
|
62
|
+
if (await pred(item, index++)) yield item;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Take the first `n` items.
|
|
68
|
+
*
|
|
69
|
+
* @stable
|
|
70
|
+
*/
|
|
71
|
+
export async function* take<T>(
|
|
72
|
+
source: AsyncIterable<T>,
|
|
73
|
+
n: number,
|
|
74
|
+
signal?: AbortSignal,
|
|
75
|
+
): AsyncIterable<T> {
|
|
76
|
+
if (n <= 0) return;
|
|
77
|
+
let i = 0;
|
|
78
|
+
for await (const item of withSignal(source, signal)) {
|
|
79
|
+
yield item;
|
|
80
|
+
if (++i >= n) return;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Take items as long as `pred` returns truthy. The first item for which
|
|
86
|
+
* `pred` returns falsy ends the stream.
|
|
87
|
+
*
|
|
88
|
+
* @stable
|
|
89
|
+
*/
|
|
90
|
+
export async function* takeWhile<T>(
|
|
91
|
+
source: AsyncIterable<T>,
|
|
92
|
+
pred: (value: T, index: number) => boolean | Promise<boolean>,
|
|
93
|
+
signal?: AbortSignal,
|
|
94
|
+
): AsyncIterable<T> {
|
|
95
|
+
let index = 0;
|
|
96
|
+
for await (const item of withSignal(source, signal)) {
|
|
97
|
+
if (!(await pred(item, index++))) return;
|
|
98
|
+
yield item;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Merge multiple async iterables into a single output iterable. Items
|
|
104
|
+
* are yielded in the order they arrive (interleaved), not in source
|
|
105
|
+
* order. Cancellation propagates to every upstream iterator.
|
|
106
|
+
*
|
|
107
|
+
* @stable
|
|
108
|
+
*/
|
|
109
|
+
export async function* merge<T>(
|
|
110
|
+
sources: ReadonlyArray<AsyncIterable<T>>,
|
|
111
|
+
signal?: AbortSignal,
|
|
112
|
+
): AsyncIterable<T> {
|
|
113
|
+
if (sources.length === 0) return;
|
|
114
|
+
|
|
115
|
+
const iterators = sources.map((s) => s[Symbol.asyncIterator]());
|
|
116
|
+
type Pending = { iter: AsyncIterator<T>; index: number; promise: Promise<IteratorResult<T>> };
|
|
117
|
+
const pending: Array<Pending | null> = iterators.map((iter, index) => ({
|
|
118
|
+
iter,
|
|
119
|
+
index,
|
|
120
|
+
promise: iter.next(),
|
|
121
|
+
}));
|
|
122
|
+
|
|
123
|
+
const onAbort = async (): Promise<void> => {
|
|
124
|
+
await Promise.all(
|
|
125
|
+
pending.map(async (p) => {
|
|
126
|
+
if (p && hasReturn(p.iter)) {
|
|
127
|
+
try {
|
|
128
|
+
await p.iter.return(undefined);
|
|
129
|
+
} catch {
|
|
130
|
+
// Suppress: we are cancelling regardless.
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}),
|
|
134
|
+
);
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
if (signal?.aborted) {
|
|
138
|
+
await onAbort();
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const abortListener = (): void => {
|
|
143
|
+
void onAbort();
|
|
144
|
+
};
|
|
145
|
+
signal?.addEventListener('abort', abortListener, { once: true });
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
while (pending.some((p) => p !== null)) {
|
|
149
|
+
if (signal?.aborted) return;
|
|
150
|
+
|
|
151
|
+
// Race only the still-active iterators.
|
|
152
|
+
const live = pending.filter((p): p is Pending => p !== null);
|
|
153
|
+
const winner = await Promise.race(live.map(async (p) => ({ p, result: await p.promise })));
|
|
154
|
+
|
|
155
|
+
if (winner.result.done) {
|
|
156
|
+
pending[winner.p.index] = null;
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
yield winner.result.value;
|
|
161
|
+
|
|
162
|
+
// Re-prime the winning iterator.
|
|
163
|
+
pending[winner.p.index] = {
|
|
164
|
+
...winner.p,
|
|
165
|
+
promise: winner.p.iter.next(),
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
} finally {
|
|
169
|
+
signal?.removeEventListener('abort', abortListener);
|
|
170
|
+
// Flush any remaining iterators.
|
|
171
|
+
await Promise.all(
|
|
172
|
+
pending.map(async (p) => {
|
|
173
|
+
if (p && hasReturn(p.iter)) {
|
|
174
|
+
try {
|
|
175
|
+
await p.iter.return(undefined);
|
|
176
|
+
} catch {
|
|
177
|
+
// Suppress.
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}),
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Wrap `source` with abort-signal propagation: when `signal` aborts the
|
|
187
|
+
* underlying iterator's `return()` is called and the loop exits cleanly.
|
|
188
|
+
*
|
|
189
|
+
* @stable
|
|
190
|
+
*/
|
|
191
|
+
export async function* withSignal<T>(
|
|
192
|
+
source: AsyncIterable<T>,
|
|
193
|
+
signal?: AbortSignal,
|
|
194
|
+
): AsyncIterable<T> {
|
|
195
|
+
if (!signal) {
|
|
196
|
+
yield* source;
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
if (signal.aborted) return;
|
|
200
|
+
|
|
201
|
+
const iter = source[Symbol.asyncIterator]();
|
|
202
|
+
let abortListener: (() => void) | null = null;
|
|
203
|
+
|
|
204
|
+
const abortPromise = new Promise<{ aborted: true }>((resolve) => {
|
|
205
|
+
abortListener = (): void => resolve({ aborted: true });
|
|
206
|
+
signal.addEventListener('abort', abortListener, { once: true });
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
try {
|
|
210
|
+
while (true) {
|
|
211
|
+
const next = iter.next();
|
|
212
|
+
const winner = await Promise.race([
|
|
213
|
+
next.then((r) => ({ aborted: false as const, result: r })),
|
|
214
|
+
abortPromise,
|
|
215
|
+
]);
|
|
216
|
+
|
|
217
|
+
if (winner.aborted) {
|
|
218
|
+
if (hasReturn(iter)) {
|
|
219
|
+
try {
|
|
220
|
+
await iter.return(undefined);
|
|
221
|
+
} catch {
|
|
222
|
+
// Suppress.
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
if (winner.result.done) return;
|
|
228
|
+
yield winner.result.value;
|
|
229
|
+
}
|
|
230
|
+
} finally {
|
|
231
|
+
if (abortListener) signal.removeEventListener('abort', abortListener);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type-only Zod compatibility shim. We declare a structural type for the
|
|
3
|
+
* subset of `zod` we depend on so that `@graphorin/core` can be type-
|
|
4
|
+
* checked without importing zod directly. Consumers that do `import {
|
|
5
|
+
* z } from 'zod'` get the real types via the user's `zod` install (the
|
|
6
|
+
* peer dependency).
|
|
7
|
+
*
|
|
8
|
+
* @stable
|
|
9
|
+
*/
|
|
10
|
+
export interface ZodLikeSchema<TOutput = unknown, TInput = unknown> {
|
|
11
|
+
parse(data: unknown): TOutput;
|
|
12
|
+
safeParse(data: unknown): ZodLikeSafeParseResult<TOutput, TInput>;
|
|
13
|
+
/** Internal phantom used by Zod for inference. We don't dereference it. */
|
|
14
|
+
readonly _output?: TOutput;
|
|
15
|
+
readonly _input?: TInput;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** @stable */
|
|
19
|
+
export type ZodLikeSafeParseResult<TOutput, TInput> =
|
|
20
|
+
| { readonly success: true; readonly data: TOutput }
|
|
21
|
+
| { readonly success: false; readonly error: ZodLikeError<TInput> };
|
|
22
|
+
|
|
23
|
+
/** @stable */
|
|
24
|
+
export interface ZodLikeError<_TInput = unknown> {
|
|
25
|
+
readonly name: string;
|
|
26
|
+
readonly message: string;
|
|
27
|
+
readonly issues: ReadonlyArray<{
|
|
28
|
+
/**
|
|
29
|
+
* W-013: `PropertyKey`, not `string | number` - zod 4 bases
|
|
30
|
+
* `$ZodIssue.path` on `PropertyKey`, and this shim must be a
|
|
31
|
+
* SUPERSET of both supported peer majors or the canonical
|
|
32
|
+
* `tool({ inputSchema: z.object({...}) })` fails to typecheck for
|
|
33
|
+
* every zod@4 consumer. Type-level widening of a produced position
|
|
34
|
+
* (breaking for downstream code assigning elements to
|
|
35
|
+
* `string | number`).
|
|
36
|
+
*/
|
|
37
|
+
readonly path: ReadonlyArray<PropertyKey>;
|
|
38
|
+
readonly message: string;
|
|
39
|
+
}>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Validate `data` against `schema` and return a `Result` instead of
|
|
44
|
+
* throwing. Use this in code paths where you want explicit
|
|
45
|
+
* pattern-matching over success / failure.
|
|
46
|
+
*
|
|
47
|
+
* @stable
|
|
48
|
+
*/
|
|
49
|
+
export type ValidationResult<T> =
|
|
50
|
+
| { readonly ok: true; readonly value: T }
|
|
51
|
+
| { readonly ok: false; readonly error: ZodLikeError };
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Synchronous validation wrapper. Does **not** swallow errors thrown by
|
|
55
|
+
* the schema's transformations - only normalizes the success / failure
|
|
56
|
+
* signal.
|
|
57
|
+
*
|
|
58
|
+
* @stable
|
|
59
|
+
*/
|
|
60
|
+
export function validate<T>(schema: ZodLikeSchema<T>, data: unknown): ValidationResult<T> {
|
|
61
|
+
const result = schema.safeParse(data);
|
|
62
|
+
if (result.success) return { ok: true, value: result.data };
|
|
63
|
+
return { ok: false, error: result.error };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Throwing variant of `validate(...)` that surfaces a `TypeError` carrying
|
|
68
|
+
* a stable, parser-style message. Useful at module-boundary entry points
|
|
69
|
+
* where a thrown error is the natural failure mode.
|
|
70
|
+
*
|
|
71
|
+
* @stable
|
|
72
|
+
*/
|
|
73
|
+
export function validateOrThrow<T>(schema: ZodLikeSchema<T>, data: unknown, what?: string): T {
|
|
74
|
+
const r = validate(schema, data);
|
|
75
|
+
if (r.ok) return r.value;
|
|
76
|
+
// W-013: `Array.prototype.join` THROWS on symbol elements - map to
|
|
77
|
+
// String first (zod 4 paths are PropertyKey-based).
|
|
78
|
+
const summary = r.error.issues
|
|
79
|
+
.map((i) => `${i.path.map(String).join('.') || '.'}: ${i.message}`)
|
|
80
|
+
.join('; ');
|
|
81
|
+
throw new TypeError(`graphorin: validation failed${what ? ` for ${what}` : ''}: ${summary}`);
|
|
82
|
+
}
|