flowneer 0.2.0 → 0.3.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/dist/plugins/index.d.ts
CHANGED
|
@@ -3,5 +3,5 @@ export { CircuitBreakerOptions, withCircuitBreaker, withCycles, withFallback, wi
|
|
|
3
3
|
export { AuditEntry, AuditLogStore, CheckpointStore, VersionedCheckpointEntry, VersionedCheckpointStore, withAuditLog, withCheckpoint, withReplay, withVersionedCheckpoint } from './persistence/index.js';
|
|
4
4
|
export { RateLimitOptions, withCostTracker, withRateLimit, withTokenBudget } from './llm/index.js';
|
|
5
5
|
export { withAtomicUpdates, withDryRun, withMocks, withStepLimit } from './dev/index.js';
|
|
6
|
-
export { peekChannel, receiveFrom, sendTo, withChannels } from './messaging/index.js';
|
|
6
|
+
export { StreamSubscriber, emit, peekChannel, receiveFrom, sendTo, withChannels, withStream } from './messaging/index.js';
|
|
7
7
|
import '../index.js';
|
package/dist/plugins/index.js
CHANGED
|
@@ -77,10 +77,16 @@ var withInterrupts = {
|
|
|
77
77
|
var withFallback = {
|
|
78
78
|
withFallback(fn) {
|
|
79
79
|
this._setHooks({
|
|
80
|
-
wrapStep: async (
|
|
80
|
+
wrapStep: async (meta, next, shared, params) => {
|
|
81
81
|
try {
|
|
82
82
|
await next();
|
|
83
|
-
} catch {
|
|
83
|
+
} catch (e) {
|
|
84
|
+
shared.__fallbackError = {
|
|
85
|
+
stepIndex: meta.index,
|
|
86
|
+
stepType: meta.type,
|
|
87
|
+
message: e instanceof Error ? e.message : String(e),
|
|
88
|
+
stack: e instanceof Error ? e.stack : void 0
|
|
89
|
+
};
|
|
84
90
|
await fn(shared, params);
|
|
85
91
|
}
|
|
86
92
|
}
|
|
@@ -126,15 +132,20 @@ var withCircuitBreaker = {
|
|
|
126
132
|
var withTimeout = {
|
|
127
133
|
withTimeout(ms) {
|
|
128
134
|
this._setHooks({
|
|
129
|
-
wrapStep: (meta, next) =>
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
+
wrapStep: (meta, next) => {
|
|
136
|
+
let handle;
|
|
137
|
+
return Promise.race([
|
|
138
|
+
next().finally(() => clearTimeout(handle)),
|
|
139
|
+
new Promise(
|
|
140
|
+
(_, reject) => handle = setTimeout(
|
|
141
|
+
() => reject(
|
|
142
|
+
new Error(`step ${meta.index} timed out after ${ms}ms`)
|
|
143
|
+
),
|
|
144
|
+
ms
|
|
145
|
+
)
|
|
135
146
|
)
|
|
136
|
-
)
|
|
137
|
-
|
|
147
|
+
]);
|
|
148
|
+
}
|
|
138
149
|
});
|
|
139
150
|
return this;
|
|
140
151
|
}
|
|
@@ -415,7 +426,23 @@ var withChannels = {
|
|
|
415
426
|
return this;
|
|
416
427
|
}
|
|
417
428
|
};
|
|
429
|
+
|
|
430
|
+
// plugins/messaging/withStream.ts
|
|
431
|
+
var withStream = {
|
|
432
|
+
withStream(subscriber) {
|
|
433
|
+
this._setHooks({
|
|
434
|
+
beforeFlow: (shared) => {
|
|
435
|
+
shared.__stream = subscriber;
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
return this;
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
function emit(shared, chunk) {
|
|
442
|
+
shared.__stream?.(chunk);
|
|
443
|
+
}
|
|
418
444
|
export {
|
|
445
|
+
emit,
|
|
419
446
|
peekChannel,
|
|
420
447
|
receiveFrom,
|
|
421
448
|
sendTo,
|
|
@@ -434,6 +461,7 @@ export {
|
|
|
434
461
|
withRateLimit,
|
|
435
462
|
withReplay,
|
|
436
463
|
withStepLimit,
|
|
464
|
+
withStream,
|
|
437
465
|
withTimeout,
|
|
438
466
|
withTiming,
|
|
439
467
|
withTokenBudget,
|
|
@@ -17,4 +17,40 @@ declare module "../../Flowneer" {
|
|
|
17
17
|
}
|
|
18
18
|
declare const withChannels: FlowneerPlugin;
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
/** Callback invoked each time a step calls `emit()`. */
|
|
21
|
+
type StreamSubscriber<T = unknown> = (chunk: T) => void;
|
|
22
|
+
declare module "../../Flowneer" {
|
|
23
|
+
interface FlowBuilder<S, P> {
|
|
24
|
+
/**
|
|
25
|
+
* Registers a streaming subscriber for this flow.
|
|
26
|
+
* Steps call `emit(shared, chunk)` to push data to the subscriber in real-time.
|
|
27
|
+
* The subscriber is stored on `shared.__stream` before the first step runs
|
|
28
|
+
* so it is automatically inherited by sub-flows (loop, batch, etc.).
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* const flow = new FlowBuilder<MyState>()
|
|
32
|
+
* .withStream((chunk) => console.log("[stream]", chunk))
|
|
33
|
+
* // ...
|
|
34
|
+
*
|
|
35
|
+
* // Inside a step:
|
|
36
|
+
* emit(s, { type: "draft", content: s.draft });
|
|
37
|
+
*/
|
|
38
|
+
withStream<T = unknown>(subscriber: StreamSubscriber<T>): this;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
declare const withStream: FlowneerPlugin;
|
|
42
|
+
/**
|
|
43
|
+
* Push a chunk to the subscriber registered via `.withStream()`.
|
|
44
|
+
* Safe to call unconditionally — silently no-ops when no subscriber is registered.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* async function refineDraft(s: MyState) {
|
|
48
|
+
* // ... produce s.draft ...
|
|
49
|
+
* emit(s, { type: "draft", round: s.round, content: s.draft });
|
|
50
|
+
* }
|
|
51
|
+
*/
|
|
52
|
+
declare function emit<T = unknown>(shared: {
|
|
53
|
+
__stream?: StreamSubscriber<T>;
|
|
54
|
+
}, chunk: T): void;
|
|
55
|
+
|
|
56
|
+
export { type StreamSubscriber, emit, peekChannel, receiveFrom, sendTo, withChannels, withStream };
|
|
@@ -32,9 +32,26 @@ var withChannels = {
|
|
|
32
32
|
return this;
|
|
33
33
|
}
|
|
34
34
|
};
|
|
35
|
+
|
|
36
|
+
// plugins/messaging/withStream.ts
|
|
37
|
+
var withStream = {
|
|
38
|
+
withStream(subscriber) {
|
|
39
|
+
this._setHooks({
|
|
40
|
+
beforeFlow: (shared) => {
|
|
41
|
+
shared.__stream = subscriber;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
return this;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
function emit(shared, chunk) {
|
|
48
|
+
shared.__stream?.(chunk);
|
|
49
|
+
}
|
|
35
50
|
export {
|
|
51
|
+
emit,
|
|
36
52
|
peekChannel,
|
|
37
53
|
receiveFrom,
|
|
38
54
|
sendTo,
|
|
39
|
-
withChannels
|
|
55
|
+
withChannels,
|
|
56
|
+
withStream
|
|
40
57
|
};
|
|
@@ -2,10 +2,16 @@
|
|
|
2
2
|
var withFallback = {
|
|
3
3
|
withFallback(fn) {
|
|
4
4
|
this._setHooks({
|
|
5
|
-
wrapStep: async (
|
|
5
|
+
wrapStep: async (meta, next, shared, params) => {
|
|
6
6
|
try {
|
|
7
7
|
await next();
|
|
8
|
-
} catch {
|
|
8
|
+
} catch (e) {
|
|
9
|
+
shared.__fallbackError = {
|
|
10
|
+
stepIndex: meta.index,
|
|
11
|
+
stepType: meta.type,
|
|
12
|
+
message: e instanceof Error ? e.message : String(e),
|
|
13
|
+
stack: e instanceof Error ? e.stack : void 0
|
|
14
|
+
};
|
|
9
15
|
await fn(shared, params);
|
|
10
16
|
}
|
|
11
17
|
}
|
|
@@ -51,15 +57,20 @@ var withCircuitBreaker = {
|
|
|
51
57
|
var withTimeout = {
|
|
52
58
|
withTimeout(ms) {
|
|
53
59
|
this._setHooks({
|
|
54
|
-
wrapStep: (meta, next) =>
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
(
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
wrapStep: (meta, next) => {
|
|
61
|
+
let handle;
|
|
62
|
+
return Promise.race([
|
|
63
|
+
next().finally(() => clearTimeout(handle)),
|
|
64
|
+
new Promise(
|
|
65
|
+
(_, reject) => handle = setTimeout(
|
|
66
|
+
() => reject(
|
|
67
|
+
new Error(`step ${meta.index} timed out after ${ms}ms`)
|
|
68
|
+
),
|
|
69
|
+
ms
|
|
70
|
+
)
|
|
60
71
|
)
|
|
61
|
-
)
|
|
62
|
-
|
|
72
|
+
]);
|
|
73
|
+
}
|
|
63
74
|
});
|
|
64
75
|
return this;
|
|
65
76
|
}
|