@arizeai/phoenix-client 5.2.1 → 5.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/esm/__generated__/api/v1.d.ts +321 -9
- package/dist/esm/__generated__/api/v1.d.ts.map +1 -1
- package/dist/esm/experiments/createExperiment.d.ts +39 -0
- package/dist/esm/experiments/createExperiment.d.ts.map +1 -0
- package/dist/esm/experiments/createExperiment.js +43 -0
- package/dist/esm/experiments/createExperiment.js.map +1 -0
- package/dist/esm/experiments/deleteExperiment.d.ts +36 -0
- package/dist/esm/experiments/deleteExperiment.d.ts.map +1 -0
- package/dist/esm/experiments/deleteExperiment.js +49 -0
- package/dist/esm/experiments/deleteExperiment.js.map +1 -0
- package/dist/esm/experiments/getExperimentInfo.d.ts.map +1 -1
- package/dist/esm/experiments/getExperimentInfo.js +9 -2
- package/dist/esm/experiments/getExperimentInfo.js.map +1 -1
- package/dist/esm/experiments/index.d.ts +5 -0
- package/dist/esm/experiments/index.d.ts.map +1 -1
- package/dist/esm/experiments/index.js +5 -0
- package/dist/esm/experiments/index.js.map +1 -1
- package/dist/esm/experiments/listExperiments.d.ts +29 -0
- package/dist/esm/experiments/listExperiments.d.ts.map +1 -0
- package/dist/esm/experiments/listExperiments.js +59 -0
- package/dist/esm/experiments/listExperiments.js.map +1 -0
- package/dist/esm/experiments/resumeEvaluation.d.ts +105 -0
- package/dist/esm/experiments/resumeEvaluation.d.ts.map +1 -0
- package/dist/esm/experiments/resumeEvaluation.js +558 -0
- package/dist/esm/experiments/resumeEvaluation.js.map +1 -0
- package/dist/esm/experiments/resumeExperiment.d.ts +102 -0
- package/dist/esm/experiments/resumeExperiment.d.ts.map +1 -0
- package/dist/esm/experiments/resumeExperiment.js +517 -0
- package/dist/esm/experiments/resumeExperiment.js.map +1 -0
- package/dist/esm/experiments/runExperiment.d.ts.map +1 -1
- package/dist/esm/experiments/runExperiment.js +28 -2
- package/dist/esm/experiments/runExperiment.js.map +1 -1
- package/dist/esm/prompts/createPrompt.d.ts +19 -1
- package/dist/esm/prompts/createPrompt.d.ts.map +1 -1
- package/dist/esm/prompts/createPrompt.js +14 -1
- package/dist/esm/prompts/createPrompt.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/types/experiments.d.ts +60 -3
- package/dist/esm/types/experiments.d.ts.map +1 -1
- package/dist/esm/utils/channel.d.ts +229 -0
- package/dist/esm/utils/channel.d.ts.map +1 -0
- package/dist/esm/utils/channel.js +352 -0
- package/dist/esm/utils/channel.js.map +1 -0
- package/dist/esm/utils/formatPromptMessages.d.ts.map +1 -1
- package/dist/esm/utils/getPromptBySelector.d.ts.map +1 -1
- package/dist/esm/utils/isHttpError.d.ts +21 -0
- package/dist/esm/utils/isHttpError.d.ts.map +1 -0
- package/dist/esm/utils/isHttpError.js +33 -0
- package/dist/esm/utils/isHttpError.js.map +1 -0
- package/dist/src/__generated__/api/v1.d.ts +321 -9
- package/dist/src/__generated__/api/v1.d.ts.map +1 -1
- package/dist/src/experiments/createExperiment.d.ts +39 -0
- package/dist/src/experiments/createExperiment.d.ts.map +1 -0
- package/dist/src/experiments/createExperiment.js +43 -0
- package/dist/src/experiments/createExperiment.js.map +1 -0
- package/dist/src/experiments/deleteExperiment.d.ts +36 -0
- package/dist/src/experiments/deleteExperiment.d.ts.map +1 -0
- package/dist/src/experiments/deleteExperiment.js +52 -0
- package/dist/src/experiments/deleteExperiment.js.map +1 -0
- package/dist/src/experiments/getExperimentInfo.d.ts.map +1 -1
- package/dist/src/experiments/getExperimentInfo.js +9 -2
- package/dist/src/experiments/getExperimentInfo.js.map +1 -1
- package/dist/src/experiments/index.d.ts +5 -0
- package/dist/src/experiments/index.d.ts.map +1 -1
- package/dist/src/experiments/index.js +5 -0
- package/dist/src/experiments/index.js.map +1 -1
- package/dist/src/experiments/listExperiments.d.ts +29 -0
- package/dist/src/experiments/listExperiments.d.ts.map +1 -0
- package/dist/src/experiments/listExperiments.js +66 -0
- package/dist/src/experiments/listExperiments.js.map +1 -0
- package/dist/src/experiments/resumeEvaluation.d.ts +105 -0
- package/dist/src/experiments/resumeEvaluation.d.ts.map +1 -0
- package/dist/src/experiments/resumeEvaluation.js +584 -0
- package/dist/src/experiments/resumeEvaluation.js.map +1 -0
- package/dist/src/experiments/resumeExperiment.d.ts +102 -0
- package/dist/src/experiments/resumeExperiment.d.ts.map +1 -0
- package/dist/src/experiments/resumeExperiment.js +540 -0
- package/dist/src/experiments/resumeExperiment.js.map +1 -0
- package/dist/src/experiments/runExperiment.d.ts.map +1 -1
- package/dist/src/experiments/runExperiment.js +28 -2
- package/dist/src/experiments/runExperiment.js.map +1 -1
- package/dist/src/prompts/createPrompt.d.ts +19 -1
- package/dist/src/prompts/createPrompt.d.ts.map +1 -1
- package/dist/src/prompts/createPrompt.js +14 -1
- package/dist/src/prompts/createPrompt.js.map +1 -1
- package/dist/src/types/experiments.d.ts +60 -3
- package/dist/src/types/experiments.d.ts.map +1 -1
- package/dist/src/utils/channel.d.ts +229 -0
- package/dist/src/utils/channel.d.ts.map +1 -0
- package/dist/src/utils/channel.js +385 -0
- package/dist/src/utils/channel.js.map +1 -0
- package/dist/src/utils/formatPromptMessages.d.ts.map +1 -1
- package/dist/src/utils/getPromptBySelector.d.ts.map +1 -1
- package/dist/src/utils/isHttpError.d.ts +21 -0
- package/dist/src/utils/isHttpError.d.ts.map +1 -0
- package/dist/src/utils/isHttpError.js +37 -0
- package/dist/src/utils/isHttpError.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/__generated__/api/v1.ts +321 -9
- package/src/experiments/createExperiment.ts +90 -0
- package/src/experiments/deleteExperiment.ts +67 -0
- package/src/experiments/getExperimentInfo.ts +9 -2
- package/src/experiments/index.ts +5 -0
- package/src/experiments/listExperiments.ts +83 -0
- package/src/experiments/resumeEvaluation.ts +799 -0
- package/src/experiments/resumeExperiment.ts +742 -0
- package/src/experiments/runExperiment.ts +30 -2
- package/src/prompts/createPrompt.ts +19 -1
- package/src/types/experiments.ts +62 -3
- package/src/utils/channel.ts +397 -0
- package/src/utils/isHttpError.ts +45 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AnnotatorKind } from "./annotations.js";
|
|
2
2
|
import { Node } from "./core.js";
|
|
3
|
-
import { Example } from "./datasets.js";
|
|
3
|
+
import { Example, ExampleWithId } from "./datasets.js";
|
|
4
4
|
/**
|
|
5
5
|
* An experiment is a set of task runs on a dataset version
|
|
6
6
|
*/
|
|
@@ -9,16 +9,73 @@ export interface ExperimentInfo extends Node {
|
|
|
9
9
|
datasetVersionId: string;
|
|
10
10
|
datasetSplits?: string[];
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* Number of times the experiment is repeated
|
|
13
13
|
*/
|
|
14
|
-
|
|
14
|
+
repetitions: number;
|
|
15
15
|
/**
|
|
16
16
|
* Metadata about the experiment as an object of key values
|
|
17
17
|
* e.x. model name
|
|
18
18
|
*/
|
|
19
19
|
metadata: Record<string, unknown>;
|
|
20
|
+
/**
|
|
21
|
+
* The project under which the experiment task traces are recorded
|
|
22
|
+
* Note: This can be null when no project is associated with the experiment
|
|
23
|
+
*/
|
|
24
|
+
projectName: string | null;
|
|
25
|
+
/**
|
|
26
|
+
* The creation timestamp of the experiment
|
|
27
|
+
*/
|
|
28
|
+
createdAt: string;
|
|
29
|
+
/**
|
|
30
|
+
* The last update timestamp of the experiment
|
|
31
|
+
*/
|
|
32
|
+
updatedAt: string;
|
|
33
|
+
/**
|
|
34
|
+
* Number of examples in the experiment
|
|
35
|
+
*/
|
|
36
|
+
exampleCount: number;
|
|
37
|
+
/**
|
|
38
|
+
* Number of successful runs in the experiment
|
|
39
|
+
*/
|
|
40
|
+
successfulRunCount: number;
|
|
41
|
+
/**
|
|
42
|
+
* Number of failed runs in the experiment
|
|
43
|
+
*/
|
|
44
|
+
failedRunCount: number;
|
|
45
|
+
/**
|
|
46
|
+
* Number of missing (not yet executed) runs in the experiment
|
|
47
|
+
*/
|
|
48
|
+
missingRunCount: number;
|
|
20
49
|
}
|
|
21
50
|
export type ExperimentRunID = string;
|
|
51
|
+
/**
|
|
52
|
+
* Represents incomplete experiment runs for a dataset example
|
|
53
|
+
* Groups all incomplete repetitions for a single example
|
|
54
|
+
*/
|
|
55
|
+
export interface IncompleteRun {
|
|
56
|
+
/**
|
|
57
|
+
* The dataset example that has incomplete runs
|
|
58
|
+
*/
|
|
59
|
+
datasetExample: Example;
|
|
60
|
+
/**
|
|
61
|
+
* List of repetition numbers that need to be run for this example
|
|
62
|
+
*/
|
|
63
|
+
repetitionNumbers: number[];
|
|
64
|
+
}
|
|
65
|
+
export interface IncompleteEvaluation {
|
|
66
|
+
/**
|
|
67
|
+
* The experiment run with incomplete evaluations
|
|
68
|
+
*/
|
|
69
|
+
experimentRun: ExperimentRun;
|
|
70
|
+
/**
|
|
71
|
+
* The dataset example for this run
|
|
72
|
+
*/
|
|
73
|
+
datasetExample: ExampleWithId;
|
|
74
|
+
/**
|
|
75
|
+
* List of evaluation names that are incomplete (either missing or failed)
|
|
76
|
+
*/
|
|
77
|
+
evaluationNames: string[];
|
|
78
|
+
}
|
|
22
79
|
/**
|
|
23
80
|
* A map of an experiment runId to the run
|
|
24
81
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"experiments.d.ts","sourceRoot":"","sources":["../../../src/types/experiments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"experiments.d.ts","sourceRoot":"","sources":["../../../src/types/experiments.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A bounded, buffered CSP channel implementation for TypeScript.
|
|
3
|
+
*
|
|
4
|
+
* Implements the Producer-Consumer pattern with automatic backpressure via
|
|
5
|
+
* blocking send/receive semantics. Based on Communicating Sequential Processes (Hoare, 1978).
|
|
6
|
+
*
|
|
7
|
+
* Properties:
|
|
8
|
+
* - Bounded buffer: O(capacity) memory usage
|
|
9
|
+
* - Blocking send: Blocks when buffer is full
|
|
10
|
+
* - Blocking receive: Blocks when buffer is empty
|
|
11
|
+
* - Graceful shutdown: Close drains buffer before terminating
|
|
12
|
+
*
|
|
13
|
+
* Performance Characteristics:
|
|
14
|
+
* - send(): O(R) where R = pending receivers (typically 0-10)
|
|
15
|
+
* - receive(): O(B + S) where B = buffer size, S = pending senders
|
|
16
|
+
* - Uses Array.shift() which is O(n) but acceptable for small queues
|
|
17
|
+
* - Same complexity trade-off as async.queue, p-limit, and similar libraries
|
|
18
|
+
* - For typical usage (buffer < 100, queues < 10), overhead is negligible (<10ms per 5000 operations)
|
|
19
|
+
*
|
|
20
|
+
* Note: Could be optimized to O(1) with linked list or circular buffer, but current
|
|
21
|
+
* implementation prioritizes simplicity and is comparable to standard JS libraries.
|
|
22
|
+
*
|
|
23
|
+
* Deadlock Prevention:
|
|
24
|
+
* JavaScript channels use cooperative blocking via Promises, not true thread blocking.
|
|
25
|
+
* Deadlocks are rare but possible in certain patterns:
|
|
26
|
+
*
|
|
27
|
+
* ❌ AVOID: Sequential operations on unbuffered channels
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const ch = new Channel<number>(0);
|
|
30
|
+
* await ch.send(1); // Blocks forever - no receiver started
|
|
31
|
+
* await ch.receive(); // Never reached
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* ❌ AVOID: Circular dependencies between channels
|
|
35
|
+
* ```typescript
|
|
36
|
+
* const ch1 = new Channel(0);
|
|
37
|
+
* const ch2 = new Channel(0);
|
|
38
|
+
* // Task 1: await ch1.send() → await ch2.receive()
|
|
39
|
+
* // Task 2: await ch2.send() → await ch1.receive()
|
|
40
|
+
* // Both block on send, never reach receive
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* ✅ SAFE: Concurrent start with buffered channels (recommended pattern)
|
|
44
|
+
* ```typescript
|
|
45
|
+
* const ch = new Channel<number>(); // Default (10) is safe
|
|
46
|
+
*
|
|
47
|
+
* // Start producer immediately
|
|
48
|
+
* const producer = (async () => {
|
|
49
|
+
* for (let i = 0; i < 100; i++) {
|
|
50
|
+
* await ch.send(i);
|
|
51
|
+
* }
|
|
52
|
+
* ch.close(); // Always close in finally block
|
|
53
|
+
* })();
|
|
54
|
+
*
|
|
55
|
+
* // Start consumers immediately
|
|
56
|
+
* const consumers = Array.from({ length: 5 }, async () => {
|
|
57
|
+
* for await (const value of ch) {
|
|
58
|
+
* await processValue(value);
|
|
59
|
+
* }
|
|
60
|
+
* });
|
|
61
|
+
*
|
|
62
|
+
* // Wait for all to complete
|
|
63
|
+
* await Promise.all([producer, ...consumers]);
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* Best Practices:
|
|
67
|
+
* 1. Use default capacity or higher (10+) for production - provides safety and throughput
|
|
68
|
+
* 2. Always close() channels in a finally block to prevent hanging operations
|
|
69
|
+
* 3. Start producers and consumers concurrently, not sequentially
|
|
70
|
+
* 4. Use for-await loops for automatic cleanup on close
|
|
71
|
+
* 5. Avoid circular dependencies between channels
|
|
72
|
+
* 6. Handle errors in workers so they don't crash and leave channel blocked
|
|
73
|
+
* 7. Only use unbuffered (capacity=0) when you need strict happens-before guarantees
|
|
74
|
+
*
|
|
75
|
+
* @see https://en.wikipedia.org/wiki/Communicating_sequential_processes
|
|
76
|
+
*
|
|
77
|
+
* @template T The type of values sent through the channel
|
|
78
|
+
*
|
|
79
|
+
* @example Safe Producer-Consumer Pattern
|
|
80
|
+
* ```typescript
|
|
81
|
+
* // Default capacity (10) is safe for most cases
|
|
82
|
+
* const ch = new Channel<number>(); // or explicit: new Channel<number>(50)
|
|
83
|
+
*
|
|
84
|
+
* // Producer with proper cleanup
|
|
85
|
+
* const producer = (async () => {
|
|
86
|
+
* try {
|
|
87
|
+
* for (let i = 0; i < 100; i++) {
|
|
88
|
+
* await ch.send(i); // Blocks if buffer full (backpressure)
|
|
89
|
+
* }
|
|
90
|
+
* } finally {
|
|
91
|
+
* ch.close(); // Guaranteed cleanup
|
|
92
|
+
* }
|
|
93
|
+
* })();
|
|
94
|
+
*
|
|
95
|
+
* // Multiple consumers
|
|
96
|
+
* const consumers = Array.from({ length: 3 }, async () => {
|
|
97
|
+
* for await (const value of ch) {
|
|
98
|
+
* console.log(value);
|
|
99
|
+
* }
|
|
100
|
+
* });
|
|
101
|
+
*
|
|
102
|
+
* await Promise.all([producer, ...consumers]);
|
|
103
|
+
* ```
|
|
104
|
+
*
|
|
105
|
+
* @example Unbuffered Channel (Rendezvous)
|
|
106
|
+
* ```typescript
|
|
107
|
+
* const ch = new Channel<number>(0); // Unbuffered - use with care!
|
|
108
|
+
*
|
|
109
|
+
* // Must start both operations before awaiting
|
|
110
|
+
* const sendPromise = ch.send(42); // Starts but doesn't block caller yet
|
|
111
|
+
* const value = await ch.receive(); // Unblocks the sender
|
|
112
|
+
* await sendPromise; // Now safe to await
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
/**
|
|
116
|
+
* Custom error class for channel operations
|
|
117
|
+
*/
|
|
118
|
+
export declare class ChannelError extends Error {
|
|
119
|
+
constructor(message: string, options?: ErrorOptions);
|
|
120
|
+
}
|
|
121
|
+
export declare class Channel<T> {
|
|
122
|
+
#private;
|
|
123
|
+
/**
|
|
124
|
+
* Create a new channel with the specified buffer capacity.
|
|
125
|
+
*
|
|
126
|
+
* @param capacity - Buffer size (default: 10)
|
|
127
|
+
* - 0: Unbuffered/rendezvous channel - strict synchronization, higher deadlock risk.
|
|
128
|
+
* Use only when you need guaranteed happens-before ordering.
|
|
129
|
+
* - 1-100: Buffered channel - recommended for production use.
|
|
130
|
+
* - Higher values: Better throughput but more memory usage.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```typescript
|
|
134
|
+
* // Default buffered (safe for most cases)
|
|
135
|
+
* const ch1 = new Channel<number>();
|
|
136
|
+
*
|
|
137
|
+
* // Explicit buffer size (production pattern)
|
|
138
|
+
* const ch2 = new Channel<number>(50);
|
|
139
|
+
*
|
|
140
|
+
* // Unbuffered (advanced - strict synchronization)
|
|
141
|
+
* const ch3 = new Channel<number>(0);
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
constructor(capacity?: number);
|
|
145
|
+
/**
|
|
146
|
+
* Send a value to the channel
|
|
147
|
+
* Blocks if the buffer is full until space is available
|
|
148
|
+
*
|
|
149
|
+
* @param value - The value to send
|
|
150
|
+
* @throws {ChannelError} If channel is closed
|
|
151
|
+
*/
|
|
152
|
+
send(value: T): Promise<void>;
|
|
153
|
+
/**
|
|
154
|
+
* Receive a value from the channel
|
|
155
|
+
* Blocks if no value is available until one arrives
|
|
156
|
+
*
|
|
157
|
+
* @returns The received value, or CLOSED symbol if channel is closed and empty
|
|
158
|
+
*/
|
|
159
|
+
receive(): Promise<T | typeof CLOSED>;
|
|
160
|
+
/**
|
|
161
|
+
* Try to receive a value without blocking
|
|
162
|
+
* Returns immediately with value or undefined if channel is empty
|
|
163
|
+
*
|
|
164
|
+
* @returns The received value, CLOSED if channel is closed, or undefined if empty
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ```typescript
|
|
168
|
+
* const ch = new Channel<number>(10);
|
|
169
|
+
* await ch.send(42);
|
|
170
|
+
*
|
|
171
|
+
* const value = ch.tryReceive();
|
|
172
|
+
* if (value !== undefined && value !== CLOSED) {
|
|
173
|
+
* console.log("Got:", value);
|
|
174
|
+
* }
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
tryReceive(): T | typeof CLOSED | undefined;
|
|
178
|
+
/**
|
|
179
|
+
* Close the channel
|
|
180
|
+
* No more sends allowed, but remaining values can be received
|
|
181
|
+
*/
|
|
182
|
+
close(): void;
|
|
183
|
+
/**
|
|
184
|
+
* Check if channel is closed
|
|
185
|
+
*/
|
|
186
|
+
get isClosed(): boolean;
|
|
187
|
+
/**
|
|
188
|
+
* Get current buffer length
|
|
189
|
+
*/
|
|
190
|
+
get length(): number;
|
|
191
|
+
/**
|
|
192
|
+
* Get the channel's capacity
|
|
193
|
+
*/
|
|
194
|
+
get capacity(): number;
|
|
195
|
+
/**
|
|
196
|
+
* Get the number of blocked senders waiting
|
|
197
|
+
*/
|
|
198
|
+
get pendingSends(): number;
|
|
199
|
+
/**
|
|
200
|
+
* Get the number of blocked receivers waiting
|
|
201
|
+
*/
|
|
202
|
+
get pendingReceives(): number;
|
|
203
|
+
/**
|
|
204
|
+
* Async iterator support for for-await-of loops
|
|
205
|
+
*/
|
|
206
|
+
[Symbol.asyncIterator](): AsyncIterableIterator<T>;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Special symbol to indicate channel is closed
|
|
210
|
+
*/
|
|
211
|
+
export declare const CLOSED: unique symbol;
|
|
212
|
+
/**
|
|
213
|
+
* Type guard to check if a value is the CLOSED symbol
|
|
214
|
+
*
|
|
215
|
+
* @param value - Value to check
|
|
216
|
+
* @returns true if value is CLOSED symbol
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```typescript
|
|
220
|
+
* const value = await ch.receive();
|
|
221
|
+
* if (isClosed(value)) {
|
|
222
|
+
* console.log("Channel is closed");
|
|
223
|
+
* } else {
|
|
224
|
+
* console.log("Got value:", value);
|
|
225
|
+
* }
|
|
226
|
+
* ```
|
|
227
|
+
*/
|
|
228
|
+
export declare function isClosed<T>(value: T | typeof CLOSED): value is typeof CLOSED;
|
|
229
|
+
//# sourceMappingURL=channel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../../src/utils/channel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiHG;AAmBH;;GAEG;AACH,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAIpD;AAWD,qBAAa,OAAO,CAAC,CAAC;;IAOpB;;;;;;;;;;;;;;;;;;;;OAoBG;gBACS,QAAQ,GAAE,MAAW;IAOjC;;;;;;OAMG;IACG,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBnC;;;;;OAKG;IACG,OAAO,IAAI,OAAO,CAAC,CAAC,GAAG,OAAO,MAAM,CAAC;IAiC3C;;;;;;;;;;;;;;;;OAgBG;IACH,UAAU,IAAI,CAAC,GAAG,OAAO,MAAM,GAAG,SAAS;IA+B3C;;;OAGG;IACH,KAAK,IAAI,IAAI;IAkBb;;OAEG;IACH,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;OAEG;IACH,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED;;OAEG;IACH,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED;;OAEG;IACH,IAAI,eAAe,IAAI,MAAM,CAE5B;IAED;;OAEG;IACI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,qBAAqB,CAAC,CAAC,CAAC;CAO1D;AAED;;GAEG;AACH,eAAO,MAAM,MAAM,eAAmB,CAAC;AAEvC;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,MAAM,GAAG,KAAK,IAAI,OAAO,MAAM,CAE5E"}
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A bounded, buffered CSP channel implementation for TypeScript.
|
|
3
|
+
*
|
|
4
|
+
* Implements the Producer-Consumer pattern with automatic backpressure via
|
|
5
|
+
* blocking send/receive semantics. Based on Communicating Sequential Processes (Hoare, 1978).
|
|
6
|
+
*
|
|
7
|
+
* Properties:
|
|
8
|
+
* - Bounded buffer: O(capacity) memory usage
|
|
9
|
+
* - Blocking send: Blocks when buffer is full
|
|
10
|
+
* - Blocking receive: Blocks when buffer is empty
|
|
11
|
+
* - Graceful shutdown: Close drains buffer before terminating
|
|
12
|
+
*
|
|
13
|
+
* Performance Characteristics:
|
|
14
|
+
* - send(): O(R) where R = pending receivers (typically 0-10)
|
|
15
|
+
* - receive(): O(B + S) where B = buffer size, S = pending senders
|
|
16
|
+
* - Uses Array.shift() which is O(n) but acceptable for small queues
|
|
17
|
+
* - Same complexity trade-off as async.queue, p-limit, and similar libraries
|
|
18
|
+
* - For typical usage (buffer < 100, queues < 10), overhead is negligible (<10ms per 5000 operations)
|
|
19
|
+
*
|
|
20
|
+
* Note: Could be optimized to O(1) with linked list or circular buffer, but current
|
|
21
|
+
* implementation prioritizes simplicity and is comparable to standard JS libraries.
|
|
22
|
+
*
|
|
23
|
+
* Deadlock Prevention:
|
|
24
|
+
* JavaScript channels use cooperative blocking via Promises, not true thread blocking.
|
|
25
|
+
* Deadlocks are rare but possible in certain patterns:
|
|
26
|
+
*
|
|
27
|
+
* ❌ AVOID: Sequential operations on unbuffered channels
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const ch = new Channel<number>(0);
|
|
30
|
+
* await ch.send(1); // Blocks forever - no receiver started
|
|
31
|
+
* await ch.receive(); // Never reached
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* ❌ AVOID: Circular dependencies between channels
|
|
35
|
+
* ```typescript
|
|
36
|
+
* const ch1 = new Channel(0);
|
|
37
|
+
* const ch2 = new Channel(0);
|
|
38
|
+
* // Task 1: await ch1.send() → await ch2.receive()
|
|
39
|
+
* // Task 2: await ch2.send() → await ch1.receive()
|
|
40
|
+
* // Both block on send, never reach receive
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* ✅ SAFE: Concurrent start with buffered channels (recommended pattern)
|
|
44
|
+
* ```typescript
|
|
45
|
+
* const ch = new Channel<number>(); // Default (10) is safe
|
|
46
|
+
*
|
|
47
|
+
* // Start producer immediately
|
|
48
|
+
* const producer = (async () => {
|
|
49
|
+
* for (let i = 0; i < 100; i++) {
|
|
50
|
+
* await ch.send(i);
|
|
51
|
+
* }
|
|
52
|
+
* ch.close(); // Always close in finally block
|
|
53
|
+
* })();
|
|
54
|
+
*
|
|
55
|
+
* // Start consumers immediately
|
|
56
|
+
* const consumers = Array.from({ length: 5 }, async () => {
|
|
57
|
+
* for await (const value of ch) {
|
|
58
|
+
* await processValue(value);
|
|
59
|
+
* }
|
|
60
|
+
* });
|
|
61
|
+
*
|
|
62
|
+
* // Wait for all to complete
|
|
63
|
+
* await Promise.all([producer, ...consumers]);
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* Best Practices:
|
|
67
|
+
* 1. Use default capacity or higher (10+) for production - provides safety and throughput
|
|
68
|
+
* 2. Always close() channels in a finally block to prevent hanging operations
|
|
69
|
+
* 3. Start producers and consumers concurrently, not sequentially
|
|
70
|
+
* 4. Use for-await loops for automatic cleanup on close
|
|
71
|
+
* 5. Avoid circular dependencies between channels
|
|
72
|
+
* 6. Handle errors in workers so they don't crash and leave channel blocked
|
|
73
|
+
* 7. Only use unbuffered (capacity=0) when you need strict happens-before guarantees
|
|
74
|
+
*
|
|
75
|
+
* @see https://en.wikipedia.org/wiki/Communicating_sequential_processes
|
|
76
|
+
*
|
|
77
|
+
* @template T The type of values sent through the channel
|
|
78
|
+
*
|
|
79
|
+
* @example Safe Producer-Consumer Pattern
|
|
80
|
+
* ```typescript
|
|
81
|
+
* // Default capacity (10) is safe for most cases
|
|
82
|
+
* const ch = new Channel<number>(); // or explicit: new Channel<number>(50)
|
|
83
|
+
*
|
|
84
|
+
* // Producer with proper cleanup
|
|
85
|
+
* const producer = (async () => {
|
|
86
|
+
* try {
|
|
87
|
+
* for (let i = 0; i < 100; i++) {
|
|
88
|
+
* await ch.send(i); // Blocks if buffer full (backpressure)
|
|
89
|
+
* }
|
|
90
|
+
* } finally {
|
|
91
|
+
* ch.close(); // Guaranteed cleanup
|
|
92
|
+
* }
|
|
93
|
+
* })();
|
|
94
|
+
*
|
|
95
|
+
* // Multiple consumers
|
|
96
|
+
* const consumers = Array.from({ length: 3 }, async () => {
|
|
97
|
+
* for await (const value of ch) {
|
|
98
|
+
* console.log(value);
|
|
99
|
+
* }
|
|
100
|
+
* });
|
|
101
|
+
*
|
|
102
|
+
* await Promise.all([producer, ...consumers]);
|
|
103
|
+
* ```
|
|
104
|
+
*
|
|
105
|
+
* @example Unbuffered Channel (Rendezvous)
|
|
106
|
+
* ```typescript
|
|
107
|
+
* const ch = new Channel<number>(0); // Unbuffered - use with care!
|
|
108
|
+
*
|
|
109
|
+
* // Must start both operations before awaiting
|
|
110
|
+
* const sendPromise = ch.send(42); // Starts but doesn't block caller yet
|
|
111
|
+
* const value = await ch.receive(); // Unblocks the sender
|
|
112
|
+
* await sendPromise; // Now safe to await
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
/**
|
|
116
|
+
* Custom error class for channel operations
|
|
117
|
+
*/
|
|
118
|
+
export class ChannelError extends Error {
|
|
119
|
+
constructor(message, options) {
|
|
120
|
+
super(message, options);
|
|
121
|
+
this.name = "ChannelError";
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Error messages for channel operations
|
|
126
|
+
*/
|
|
127
|
+
const ERRORS = {
|
|
128
|
+
SEND_TO_CLOSED: "Cannot send to closed channel",
|
|
129
|
+
CLOSED_WHILE_BLOCKED: "Channel closed while send was blocked",
|
|
130
|
+
NEGATIVE_CAPACITY: "Channel capacity must be non-negative",
|
|
131
|
+
};
|
|
132
|
+
export class Channel {
|
|
133
|
+
#buffer = [];
|
|
134
|
+
#sendQueue = [];
|
|
135
|
+
#receiveQueue = [];
|
|
136
|
+
#closed = false;
|
|
137
|
+
#capacity;
|
|
138
|
+
/**
|
|
139
|
+
* Create a new channel with the specified buffer capacity.
|
|
140
|
+
*
|
|
141
|
+
* @param capacity - Buffer size (default: 10)
|
|
142
|
+
* - 0: Unbuffered/rendezvous channel - strict synchronization, higher deadlock risk.
|
|
143
|
+
* Use only when you need guaranteed happens-before ordering.
|
|
144
|
+
* - 1-100: Buffered channel - recommended for production use.
|
|
145
|
+
* - Higher values: Better throughput but more memory usage.
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```typescript
|
|
149
|
+
* // Default buffered (safe for most cases)
|
|
150
|
+
* const ch1 = new Channel<number>();
|
|
151
|
+
*
|
|
152
|
+
* // Explicit buffer size (production pattern)
|
|
153
|
+
* const ch2 = new Channel<number>(50);
|
|
154
|
+
*
|
|
155
|
+
* // Unbuffered (advanced - strict synchronization)
|
|
156
|
+
* const ch3 = new Channel<number>(0);
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
constructor(capacity = 10) {
|
|
160
|
+
if (capacity < 0) {
|
|
161
|
+
throw new ChannelError(ERRORS.NEGATIVE_CAPACITY);
|
|
162
|
+
}
|
|
163
|
+
this.#capacity = capacity;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Send a value to the channel
|
|
167
|
+
* Blocks if the buffer is full until space is available
|
|
168
|
+
*
|
|
169
|
+
* @param value - The value to send
|
|
170
|
+
* @throws {ChannelError} If channel is closed
|
|
171
|
+
*/
|
|
172
|
+
async send(value) {
|
|
173
|
+
if (this.#closed) {
|
|
174
|
+
throw new ChannelError(ERRORS.SEND_TO_CLOSED);
|
|
175
|
+
}
|
|
176
|
+
// Direct delivery to waiting receiver
|
|
177
|
+
const receiver = this.#receiveQueue.shift();
|
|
178
|
+
if (receiver) {
|
|
179
|
+
receiver.resolve(value);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
// Add to buffer if space available
|
|
183
|
+
if (this.#buffer.length < this.#capacity) {
|
|
184
|
+
this.#buffer.push(value);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
// Block until space available
|
|
188
|
+
return new Promise((resolve, reject) => {
|
|
189
|
+
this.#sendQueue.push({ value, resolve, reject });
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Receive a value from the channel
|
|
194
|
+
* Blocks if no value is available until one arrives
|
|
195
|
+
*
|
|
196
|
+
* @returns The received value, or CLOSED symbol if channel is closed and empty
|
|
197
|
+
*/
|
|
198
|
+
async receive() {
|
|
199
|
+
// Drain buffer first
|
|
200
|
+
if (this.#buffer.length > 0) {
|
|
201
|
+
const value = this.#buffer.shift();
|
|
202
|
+
// Unblock a waiting sender
|
|
203
|
+
const sender = this.#sendQueue.shift();
|
|
204
|
+
if (sender) {
|
|
205
|
+
this.#buffer.push(sender.value);
|
|
206
|
+
sender.resolve();
|
|
207
|
+
}
|
|
208
|
+
return value;
|
|
209
|
+
}
|
|
210
|
+
// Direct handoff from waiting sender (critical for unbuffered channels)
|
|
211
|
+
const sender = this.#sendQueue.shift();
|
|
212
|
+
if (sender) {
|
|
213
|
+
sender.resolve();
|
|
214
|
+
return sender.value;
|
|
215
|
+
}
|
|
216
|
+
// Channel closed and empty
|
|
217
|
+
if (this.#closed) {
|
|
218
|
+
return CLOSED;
|
|
219
|
+
}
|
|
220
|
+
// Block until value available
|
|
221
|
+
return new Promise((resolve, reject) => {
|
|
222
|
+
this.#receiveQueue.push({ resolve, reject });
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Try to receive a value without blocking
|
|
227
|
+
* Returns immediately with value or undefined if channel is empty
|
|
228
|
+
*
|
|
229
|
+
* @returns The received value, CLOSED if channel is closed, or undefined if empty
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* ```typescript
|
|
233
|
+
* const ch = new Channel<number>(10);
|
|
234
|
+
* await ch.send(42);
|
|
235
|
+
*
|
|
236
|
+
* const value = ch.tryReceive();
|
|
237
|
+
* if (value !== undefined && value !== CLOSED) {
|
|
238
|
+
* console.log("Got:", value);
|
|
239
|
+
* }
|
|
240
|
+
* ```
|
|
241
|
+
*/
|
|
242
|
+
tryReceive() {
|
|
243
|
+
// Drain buffer first
|
|
244
|
+
if (this.#buffer.length > 0) {
|
|
245
|
+
const value = this.#buffer.shift();
|
|
246
|
+
// Unblock a waiting sender
|
|
247
|
+
const sender = this.#sendQueue.shift();
|
|
248
|
+
if (sender) {
|
|
249
|
+
this.#buffer.push(sender.value);
|
|
250
|
+
sender.resolve();
|
|
251
|
+
}
|
|
252
|
+
return value;
|
|
253
|
+
}
|
|
254
|
+
// Direct handoff from waiting sender
|
|
255
|
+
const sender = this.#sendQueue.shift();
|
|
256
|
+
if (sender) {
|
|
257
|
+
sender.resolve();
|
|
258
|
+
return sender.value;
|
|
259
|
+
}
|
|
260
|
+
// Channel closed and empty
|
|
261
|
+
if (this.#closed) {
|
|
262
|
+
return CLOSED;
|
|
263
|
+
}
|
|
264
|
+
// Channel empty but not closed
|
|
265
|
+
return undefined;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Close the channel
|
|
269
|
+
* No more sends allowed, but remaining values can be received
|
|
270
|
+
*/
|
|
271
|
+
close() {
|
|
272
|
+
if (this.#closed)
|
|
273
|
+
return;
|
|
274
|
+
this.#closed = true;
|
|
275
|
+
// Resolve all blocked receivers
|
|
276
|
+
for (const receiver of this.#receiveQueue) {
|
|
277
|
+
receiver.resolve(CLOSED);
|
|
278
|
+
}
|
|
279
|
+
this.#receiveQueue = [];
|
|
280
|
+
// Reject all blocked senders
|
|
281
|
+
const error = new ChannelError(ERRORS.CLOSED_WHILE_BLOCKED);
|
|
282
|
+
for (const sender of this.#sendQueue) {
|
|
283
|
+
sender.reject(error);
|
|
284
|
+
}
|
|
285
|
+
this.#sendQueue = [];
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Check if channel is closed
|
|
289
|
+
*/
|
|
290
|
+
get isClosed() {
|
|
291
|
+
return this.#closed;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Get current buffer length
|
|
295
|
+
*/
|
|
296
|
+
get length() {
|
|
297
|
+
return this.#buffer.length;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Get the channel's capacity
|
|
301
|
+
*/
|
|
302
|
+
get capacity() {
|
|
303
|
+
return this.#capacity;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Get the number of blocked senders waiting
|
|
307
|
+
*/
|
|
308
|
+
get pendingSends() {
|
|
309
|
+
return this.#sendQueue.length;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Get the number of blocked receivers waiting
|
|
313
|
+
*/
|
|
314
|
+
get pendingReceives() {
|
|
315
|
+
return this.#receiveQueue.length;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Async iterator support for for-await-of loops
|
|
319
|
+
*/
|
|
320
|
+
async *[Symbol.asyncIterator]() {
|
|
321
|
+
while (true) {
|
|
322
|
+
const value = await this.receive();
|
|
323
|
+
if (value === CLOSED)
|
|
324
|
+
return;
|
|
325
|
+
yield value;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Special symbol to indicate channel is closed
|
|
331
|
+
*/
|
|
332
|
+
export const CLOSED = Symbol("CLOSED");
|
|
333
|
+
/**
|
|
334
|
+
* Type guard to check if a value is the CLOSED symbol
|
|
335
|
+
*
|
|
336
|
+
* @param value - Value to check
|
|
337
|
+
* @returns true if value is CLOSED symbol
|
|
338
|
+
*
|
|
339
|
+
* @example
|
|
340
|
+
* ```typescript
|
|
341
|
+
* const value = await ch.receive();
|
|
342
|
+
* if (isClosed(value)) {
|
|
343
|
+
* console.log("Channel is closed");
|
|
344
|
+
* } else {
|
|
345
|
+
* console.log("Got value:", value);
|
|
346
|
+
* }
|
|
347
|
+
* ```
|
|
348
|
+
*/
|
|
349
|
+
export function isClosed(value) {
|
|
350
|
+
return value === CLOSED;
|
|
351
|
+
}
|
|
352
|
+
//# sourceMappingURL=channel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channel.js","sourceRoot":"","sources":["../../../src/utils/channel.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatPromptMessages.d.ts","sourceRoot":"","sources":["../../../src/utils/formatPromptMessages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAKlD,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAI3E;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,oBAAoB,EAC5B,cAAc,EAAE,iBAAiB,EAAE,EACnC,SAAS,GAAE,SAAc;;;;;;;
|
|
1
|
+
{"version":3,"file":"formatPromptMessages.d.ts","sourceRoot":"","sources":["../../../src/utils/formatPromptMessages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAKlD,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAI3E;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,oBAAoB,EAC5B,cAAc,EAAE,iBAAiB,EAAE,EACnC,SAAS,GAAE,SAAc;;;;;;;mBA4DinyF,uDAAsB;;;;;;;;;IAlBjqyF"}
|