@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.
Files changed (112) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/README.md +14 -8
  3. package/dist/channels/channels.d.ts.map +1 -1
  4. package/dist/channels/index.d.ts +2 -2
  5. package/dist/channels/index.js +2 -2
  6. package/dist/channels/pause.d.ts +47 -2
  7. package/dist/channels/pause.d.ts.map +1 -1
  8. package/dist/channels/pause.js +62 -2
  9. package/dist/channels/pause.js.map +1 -1
  10. package/dist/contracts/checkpoint-store.d.ts +97 -1
  11. package/dist/contracts/checkpoint-store.d.ts.map +1 -1
  12. package/dist/contracts/checkpoint-store.js.map +1 -1
  13. package/dist/contracts/index.d.ts +5 -5
  14. package/dist/contracts/index.js +2 -1
  15. package/dist/contracts/memory-store.d.ts +59 -2
  16. package/dist/contracts/memory-store.d.ts.map +1 -1
  17. package/dist/contracts/provider.d.ts +20 -6
  18. package/dist/contracts/provider.d.ts.map +1 -1
  19. package/dist/contracts/session-store.d.ts +10 -2
  20. package/dist/contracts/session-store.d.ts.map +1 -1
  21. package/dist/contracts/tool.d.ts +75 -1
  22. package/dist/contracts/tool.d.ts.map +1 -1
  23. package/dist/contracts/tool.js +57 -0
  24. package/dist/contracts/tool.js.map +1 -0
  25. package/dist/contracts/tracer.d.ts +53 -5
  26. package/dist/contracts/tracer.d.ts.map +1 -1
  27. package/dist/contracts/tracer.js.map +1 -1
  28. package/dist/index.d.ts +14 -9
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +11 -7
  31. package/dist/index.js.map +1 -1
  32. package/dist/package.js +6 -0
  33. package/dist/package.js.map +1 -0
  34. package/dist/types/agent-event-wire.d.ts +74 -0
  35. package/dist/types/agent-event-wire.d.ts.map +1 -0
  36. package/dist/types/agent-event-wire.js +130 -0
  37. package/dist/types/agent-event-wire.js.map +1 -0
  38. package/dist/types/agent-event.d.ts +48 -6
  39. package/dist/types/agent-event.d.ts.map +1 -1
  40. package/dist/types/index.d.ts +3 -2
  41. package/dist/types/index.js +2 -1
  42. package/dist/types/memory.d.ts +11 -0
  43. package/dist/types/memory.d.ts.map +1 -1
  44. package/dist/types/run.d.ts +86 -4
  45. package/dist/types/run.d.ts.map +1 -1
  46. package/dist/types/run.js.map +1 -1
  47. package/dist/types/tool.d.ts +10 -0
  48. package/dist/types/tool.d.ts.map +1 -1
  49. package/dist/types/usage.d.ts +11 -1
  50. package/dist/types/usage.d.ts.map +1 -1
  51. package/dist/types/usage.js.map +1 -1
  52. package/dist/utils/binary-json.d.ts +165 -0
  53. package/dist/utils/binary-json.d.ts.map +1 -0
  54. package/dist/utils/binary-json.js +240 -0
  55. package/dist/utils/binary-json.js.map +1 -0
  56. package/dist/utils/index.d.ts +2 -1
  57. package/dist/utils/index.js +2 -1
  58. package/dist/utils/validation.d.ts +10 -1
  59. package/dist/utils/validation.d.ts.map +1 -1
  60. package/dist/utils/validation.js +1 -1
  61. package/dist/utils/validation.js.map +1 -1
  62. package/package.json +9 -7
  63. package/src/channels/channels.ts +206 -0
  64. package/src/channels/directive.ts +41 -0
  65. package/src/channels/dispatch.ts +37 -0
  66. package/src/channels/durable.ts +151 -0
  67. package/src/channels/index.ts +62 -0
  68. package/src/channels/pause.ts +216 -0
  69. package/src/contracts/auth-token-store.ts +42 -0
  70. package/src/contracts/checkpoint-store.ts +256 -0
  71. package/src/contracts/embedder.ts +42 -0
  72. package/src/contracts/eval-scorer.ts +44 -0
  73. package/src/contracts/index.ts +112 -0
  74. package/src/contracts/local-provider-trust.ts +33 -0
  75. package/src/contracts/logger.ts +61 -0
  76. package/src/contracts/memory-store.ts +187 -0
  77. package/src/contracts/oauth-server-store.ts +78 -0
  78. package/src/contracts/preferred-model.ts +56 -0
  79. package/src/contracts/provider.ts +316 -0
  80. package/src/contracts/reasoning-retention.ts +52 -0
  81. package/src/contracts/redaction-validator.ts +56 -0
  82. package/src/contracts/sandbox.ts +70 -0
  83. package/src/contracts/secret-ref.ts +22 -0
  84. package/src/contracts/secret-value.ts +117 -0
  85. package/src/contracts/secrets-store.ts +90 -0
  86. package/src/contracts/session-store.ts +163 -0
  87. package/src/contracts/token-counter.ts +23 -0
  88. package/src/contracts/tool.ts +397 -0
  89. package/src/contracts/tracer.ts +219 -0
  90. package/src/contracts/trigger-store.ts +40 -0
  91. package/src/index.ts +23 -0
  92. package/src/types/agent-event-wire.ts +193 -0
  93. package/src/types/agent-event.ts +579 -0
  94. package/src/types/handoff.ts +111 -0
  95. package/src/types/index.ts +148 -0
  96. package/src/types/memory.ts +427 -0
  97. package/src/types/message.ts +174 -0
  98. package/src/types/run.ts +312 -0
  99. package/src/types/sensitivity.ts +35 -0
  100. package/src/types/session-scope.ts +18 -0
  101. package/src/types/stop-condition.ts +108 -0
  102. package/src/types/tool-call.ts +24 -0
  103. package/src/types/tool.ts +324 -0
  104. package/src/types/usage.ts +120 -0
  105. package/src/types/workflow-event.ts +132 -0
  106. package/src/utils/assert-never.ts +24 -0
  107. package/src/utils/async-context.ts +55 -0
  108. package/src/utils/binary-json.ts +425 -0
  109. package/src/utils/hash.ts +122 -0
  110. package/src/utils/index.ts +57 -0
  111. package/src/utils/streams.ts +233 -0
  112. 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
+ }