@workglow/eval 0.3.38 → 0.3.40
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/commands/report.d.ts.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/evals/classify.d.ts.map +1 -1
- package/dist/evals/extract.d.ts.map +1 -1
- package/dist/evals/runner.d.ts +25 -1
- package/dist/evals/runner.d.ts.map +1 -1
- package/dist/evals/similarity.d.ts.map +1 -1
- package/dist/evals/streamSubscribe.d.ts +15 -0
- package/dist/evals/streamSubscribe.d.ts.map +1 -0
- package/dist/evals/types.d.ts +10 -2
- package/dist/evals/types.d.ts.map +1 -1
- package/dist/models.d.ts.map +1 -1
- package/dist/report/aggregate.d.ts +13 -0
- package/dist/report/aggregate.d.ts.map +1 -1
- package/dist/report/liveTally.d.ts +22 -0
- package/dist/report/liveTally.d.ts.map +1 -0
- package/dist/storage.d.ts +21 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/test/liveTally.test.d.ts +7 -0
- package/dist/test/liveTally.test.d.ts.map +1 -0
- package/dist/test/runSweep.test.d.ts +7 -0
- package/dist/test/runSweep.test.d.ts.map +1 -0
- package/dist/test/streamSubscribe.test.d.ts +7 -0
- package/dist/test/streamSubscribe.test.d.ts.map +1 -0
- package/dist/test/usageColumns.test.d.ts +7 -0
- package/dist/test/usageColumns.test.d.ts.map +1 -0
- package/dist/workglow-eval.js +322 -41
- package/package.json +15 -15
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/commands/report.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/commands/report.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,KAAK,EAAoB,UAAU,EAAE,MAAM,YAAY,CAAC;AAG/D,sEAAsE;AACtE,wBAAsB,WAAW,CAC/B,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CA0Ff;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,GACpC,IAAI,CA2CN"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA2C7C,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,EACrC,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GACnC,IAAI,CA2CN"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../../src/evals/classify.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../../src/evals/classify.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG1D,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE1E;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,UAAU,EACf,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,UAAU,EACtB,eAAe,GAAE,SAAS,MAAM,EAAO,GACtC,MAAM,CAOR;AAED,mFAAmF;AACnF,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,cAAc,GACtB,SAAS,MAAM,EAAE,CAQnB;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAOnF;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,cAAc,GACtB,WAAW,CAsCb"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/evals/extract.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/evals/extract.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAW1E;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,EAAE,CAShF;AAED,uFAAuF;AACvF,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,SAAS,YAAY,EAAE,EACrC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GACpC,MAAM,EAAE,CAaV;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,MAAM,EAAE,GACxB,MAAM,CASR;AA+BD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,cAAc,GACtB,WAAW,CAgDb"}
|
package/dist/evals/runner.d.ts
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* Copyright 2026 Steven Roussey <sroussey@gmail.com>
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
+
import type { ModelPricing } from "@workglow/ai";
|
|
7
|
+
import type { StreamEvent, Usage } from "@workglow/task-graph";
|
|
6
8
|
import type { EvalKind } from "../models";
|
|
7
9
|
import type { DatasetRowRecord, EvalStores } from "../storage";
|
|
8
10
|
import type { ColumnOptions, DatasetContext } from "./types";
|
|
@@ -13,8 +15,30 @@ export interface SweepOptions {
|
|
|
13
15
|
readonly models: readonly string[];
|
|
14
16
|
readonly columns: ColumnOptions;
|
|
15
17
|
readonly context: DatasetContext;
|
|
16
|
-
readonly onProgress?: ((done: number, total: number, model: string, ok: boolean) => void) | undefined;
|
|
18
|
+
readonly onProgress?: ((done: number, total: number, model: string, ok: boolean, usage: Usage | undefined) => void) | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Forwarded to each row's executor as its stream-chunk listener. Left
|
|
21
|
+
* undefined for an ordinary sweep, so nothing subscribes and a 500-row run
|
|
22
|
+
* pays nothing for it.
|
|
23
|
+
*/
|
|
24
|
+
readonly onStreamChunk?: ((event: StreamEvent) => void) | undefined;
|
|
17
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Map one run's token accounting onto the result row's columns.
|
|
28
|
+
*
|
|
29
|
+
* An unreported counter is stored as `null`, never `0` — the database has to
|
|
30
|
+
* keep the distinction the in-memory type protects, or a model that never
|
|
31
|
+
* mentions caching becomes indistinguishable from one that cached nothing.
|
|
32
|
+
*/
|
|
33
|
+
export declare function usageColumns(usage: Usage | undefined, pricing: ModelPricing | undefined): {
|
|
34
|
+
input_tokens: number | null;
|
|
35
|
+
output_tokens: number | null;
|
|
36
|
+
cached_tokens: number | null;
|
|
37
|
+
cache_write_tokens: number | null;
|
|
38
|
+
total_tokens: number | null;
|
|
39
|
+
cost: number | null;
|
|
40
|
+
currency: string | null;
|
|
41
|
+
};
|
|
18
42
|
/**
|
|
19
43
|
* Run every stored dataset row through the eval workflow for each model,
|
|
20
44
|
* persisting one result row per (run, model, dataset row). Failures are
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/evals/runner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/evals/runner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAe,YAAY,EAAE,MAAM,cAAc,CAAC;AAE9D,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAI/D,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAe,MAAM,SAAS,CAAC;AAE1E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,UAAU,CAAC,EAChB,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,SAAS,KAAK,IAAI,CAAC,GAC7F,SAAS,CAAC;IACd;;;;OAIG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACrE;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,KAAK,GAAG,SAAS,EACxB,OAAO,EAAE,YAAY,GAAG,SAAS,GAChC;IACD,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAWA;AAoBD;;;;;GAKG;AACH,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,SAAS,gBAAgB,EAAE,EACjC,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,MAAM,CAAC,CA6EjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"similarity.d.ts","sourceRoot":"","sources":["../../src/evals/similarity.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"similarity.d.ts","sourceRoot":"","sources":["../../src/evals/similarity.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAMhD,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE1E;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,cAAc,GACtB,WAAW,CAqCb"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Steven Roussey <sroussey@gmail.com>
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import type { StreamEvent, Workflow } from "@workglow/task-graph";
|
|
7
|
+
/**
|
|
8
|
+
* Run a workflow, forwarding its `stream_chunk` events to `onStreamChunk` for
|
|
9
|
+
* the duration of the run only.
|
|
10
|
+
*
|
|
11
|
+
* When no listener is given, nothing is subscribed at all — a 500-row sweep
|
|
12
|
+
* without `--stream` pays nothing for it.
|
|
13
|
+
*/
|
|
14
|
+
export declare function runWithStreamChunks<Output>(workflow: Workflow, onStreamChunk: ((event: StreamEvent) => void) | undefined): Promise<Output>;
|
|
15
|
+
//# sourceMappingURL=streamSubscribe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streamSubscribe.d.ts","sourceRoot":"","sources":["../../src/evals/streamSubscribe.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAc,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAE9E;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAC9C,QAAQ,EAAE,QAAQ,EAClB,aAAa,EAAE,CAAC,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC,GAAG,SAAS,GACxD,OAAO,CAAC,MAAM,CAAC,CAUjB"}
|
package/dist/evals/types.d.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Copyright 2026 Steven Roussey <sroussey@gmail.com>
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
+
import type { StreamEvent, Usage } from "@workglow/task-graph";
|
|
6
7
|
import type { DatasetRow, LabelNames } from "../hf/types";
|
|
7
8
|
/** What one workflow execution produced for one dataset row. */
|
|
8
9
|
export interface RowPrediction {
|
|
@@ -10,9 +11,16 @@ export interface RowPrediction {
|
|
|
10
11
|
readonly predicted?: string | undefined;
|
|
11
12
|
readonly expectedValue?: number | undefined;
|
|
12
13
|
readonly predictedValue?: number | undefined;
|
|
14
|
+
readonly usage?: Usage | undefined;
|
|
13
15
|
}
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Runs the eval workflow for a single dataset row against one model.
|
|
18
|
+
*
|
|
19
|
+
* `onStreamChunk`, when passed, is subscribed to the row's underlying task for
|
|
20
|
+
* the life of the call only — `--stream` is the only caller that passes it, so
|
|
21
|
+
* an ordinary sweep never pays for the subscription.
|
|
22
|
+
*/
|
|
23
|
+
export type RowExecutor = (row: DatasetRow, onStreamChunk?: (event: StreamEvent) => void) => Promise<RowPrediction>;
|
|
16
24
|
export interface ColumnOptions {
|
|
17
25
|
readonly textColumn: string;
|
|
18
26
|
/** classify: gold label column. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/evals/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1D,gEAAgE;AAChE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/evals/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1D,gEAAgE;AAChE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;CACpC;AAED;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,CACxB,GAAG,EAAE,UAAU,EACf,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,KACzC,OAAO,CAAC,aAAa,CAAC,CAAC;AAE5B,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,mCAAmC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,8EAA8E;IAC9E,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAChD,0CAA0C;IAC1C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,gDAAgD;IAChD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,oFAAoF;IACpF,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAChD,uDAAuD;IACvD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3C;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;CACjC"}
|
package/dist/models.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAgB,MAAM,cAAc,CAAC;AAM9D,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,YAAY,GAAG,SAAS,CAAC;AA8J7D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,WAAW,CA8D1E;AAED;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAkBzF;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9E;AAQD,yEAAyE;AACzE,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CASvD"}
|
|
@@ -32,4 +32,17 @@ export interface AggregateOptions {
|
|
|
32
32
|
* tie-breaker.
|
|
33
33
|
*/
|
|
34
34
|
export declare function aggregateResults(kind: EvalKind, results: readonly EvalResultRecord[], options?: AggregateOptions): ModelReport[];
|
|
35
|
+
/**
|
|
36
|
+
* Sum a model's token spend across a run's result rows.
|
|
37
|
+
*
|
|
38
|
+
* A null column means the provider reported nothing for that row, so it is
|
|
39
|
+
* skipped rather than counted as 0 — a model that never reports caching must not
|
|
40
|
+
* end up looking like one that cached nothing.
|
|
41
|
+
*/
|
|
42
|
+
export declare function sumUsageColumns(rows: readonly EvalResultRecord[]): {
|
|
43
|
+
inputTokens: number | undefined;
|
|
44
|
+
outputTokens: number | undefined;
|
|
45
|
+
cachedTokens: number | undefined;
|
|
46
|
+
cost: number | undefined;
|
|
47
|
+
};
|
|
35
48
|
//# sourceMappingURL=aggregate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aggregate.d.ts","sourceRoot":"","sources":["../../src/report/aggregate.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAK1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,uDAAuD;IACvD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,wFAAwF;IACxF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,6FAA6F;IAC7F,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,wEAAwE;AACxE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CACjD;AAWD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,SAAS,gBAAgB,EAAE,EACpC,OAAO,GAAE,gBAAqB,GAC7B,WAAW,EAAE,CAmDf"}
|
|
1
|
+
{"version":3,"file":"aggregate.d.ts","sourceRoot":"","sources":["../../src/report/aggregate.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAK1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,uDAAuD;IACvD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,wFAAwF;IACxF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,6FAA6F;IAC7F,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,wEAAwE;AACxE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CACjD;AAWD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,SAAS,gBAAgB,EAAE,EACpC,OAAO,GAAE,gBAAqB,GAC7B,WAAW,EAAE,CAmDf;AA0BD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,gBAAgB,EAAE,GAAG;IAClE,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B,CAgBA"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Steven Roussey <sroussey@gmail.com>
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import type { ModelPricing } from "@workglow/ai";
|
|
7
|
+
import type { Usage } from "@workglow/task-graph";
|
|
8
|
+
/**
|
|
9
|
+
* Running per-model totals for a sweep, rendered as a small table on stderr.
|
|
10
|
+
*
|
|
11
|
+
* Sums usage across rows because each row is a separate request — unlike a task's
|
|
12
|
+
* cumulative in-run total, these genuinely add up.
|
|
13
|
+
*/
|
|
14
|
+
export declare class LiveTally {
|
|
15
|
+
private readonly pricing;
|
|
16
|
+
private readonly byModel;
|
|
17
|
+
private readonly startedAt;
|
|
18
|
+
constructor(pricing: (model: string) => ModelPricing | undefined, now: number);
|
|
19
|
+
record(model: string, ok: boolean, usage: Usage | undefined): void;
|
|
20
|
+
render(done: number, total: number, now: number): string;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=liveTally.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"liveTally.d.ts","sourceRoot":"","sources":["../../src/report/liveTally.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AASlD;;;;;GAKG;AACH,qBAAa,SAAS;IAKlB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiC;IACzD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAEnC,YACmB,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,YAAY,GAAG,SAAS,EACrE,GAAG,EAAE,MAAM,EAGZ;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,SAAS,GAAG,IAAI,CAMjE;IAED,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAevD;CACF"}
|
package/dist/storage.d.ts
CHANGED
|
@@ -133,6 +133,27 @@ export declare const EvalResultSchema: {
|
|
|
133
133
|
readonly latency_ms: {
|
|
134
134
|
readonly type: "number";
|
|
135
135
|
};
|
|
136
|
+
readonly input_tokens: {
|
|
137
|
+
readonly type: readonly ["integer", "null"];
|
|
138
|
+
};
|
|
139
|
+
readonly output_tokens: {
|
|
140
|
+
readonly type: readonly ["integer", "null"];
|
|
141
|
+
};
|
|
142
|
+
readonly cached_tokens: {
|
|
143
|
+
readonly type: readonly ["integer", "null"];
|
|
144
|
+
};
|
|
145
|
+
readonly cache_write_tokens: {
|
|
146
|
+
readonly type: readonly ["integer", "null"];
|
|
147
|
+
};
|
|
148
|
+
readonly total_tokens: {
|
|
149
|
+
readonly type: readonly ["integer", "null"];
|
|
150
|
+
};
|
|
151
|
+
readonly cost: {
|
|
152
|
+
readonly type: readonly ["number", "null"];
|
|
153
|
+
};
|
|
154
|
+
readonly currency: {
|
|
155
|
+
readonly type: readonly ["string", "null"];
|
|
156
|
+
};
|
|
136
157
|
};
|
|
137
158
|
readonly required: readonly ["run_id", "model", "row_index", "ok", "latency_ms"];
|
|
138
159
|
readonly additionalProperties: false;
|
package/dist/storage.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,KAAK,EAAwB,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C;;;GAGG;AACH,eAAO,MAAM,iBAAiB;mBACtB,QAAQ;;iBAEZ,OAAO;qBAAI,IAAI,EAAE,QAAQ;;iBACzB,KAAK;qBAAI,IAAI,EAAE,QAAQ;;iBACvB,MAAM;qBAAI,IAAI,EAAE,QAAQ;;iBACxB,QAAQ;qBAAI,IAAI,EAAE,QAAQ;;iBAC1B,OAAO;qBAAI,IAAI,EAAE,QAAQ;;iBACzB,WAAW;qBAAI,IAAI;;iBACnB,MAAM;qBAAI,IAAI,EAAE,QAAQ;;iBACxB,UAAU;qBAAI,IAAI,EAAE,QAAQ;;;;;CAIS,CAAC;AAE1C,eAAO,MAAM,0BAA0B,YAAI,SAAS,EAAE,OAAO,CAAU,CAAC;AAExE,2EAA2E;AAC3E,eAAO,MAAM,gBAAgB;mBACrB,QAAQ;;iBAEZ,OAAO;qBAAI,IAAI,EAAE,QAAQ;;iBACzB,KAAK;qBAAI,IAAI,EAAE,QAAQ;;iBACvB,SAAS;qBAAI,IAAI,EAAE,QAAQ;;iBAC3B,IAAI;qBAAI,IAAI,EAAE,QAAQ;;;;;CAIe,CAAC;AAE1C,eAAO,MAAM,yBAAyB,YAAI,SAAS,EAAE,OAAO,EAAE,WAAW,CAAU,CAAC;AACpF,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEnE,gFAAgF;AAChF,eAAO,MAAM,aAAa;mBAClB,QAAQ;;iBAEZ,MAAM;qBAAI,IAAI,EAAE,QAAQ;qBAAE,kBAAkB;;iBAC5C,IAAI;qBAAI,IAAI,EAAE,QAAQ;;iBACtB,OAAO;qBAAI,IAAI,EAAE,QAAQ;;iBACzB,KAAK;qBAAI,IAAI,EAAE,QAAQ;;iBACvB,MAAM;qBAAI,IAAI,EAAE,QAAQ;;iBACxB,OAAO;qBAAI,IAAI,EAAE,QAAQ;;iBACzB,UAAU;qBAAI,IAAI,EAAE,QAAQ;;;;;CAIS,CAAC;AAE1C,eAAO,MAAM,sBAAsB,YAAI,QAAQ,CAAU,CAAC;AAE1D;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;mBACrB,QAAQ;;iBAEZ,MAAM;qBAAI,IAAI,EAAE,QAAQ;;iBACxB,KAAK;qBAAI,IAAI,EAAE,QAAQ;;iBACvB,SAAS;qBAAI,IAAI,EAAE,QAAQ;;iBAC3B,EAAE;qBAAI,IAAI,EAAE,QAAQ;;iBACpB,KAAK;qBAAI,IAAI;;iBACb,QAAQ;qBAAI,IAAI;;iBAChB,SAAS;qBAAI,IAAI;;iBACjB,cAAc;qBAAI,IAAI;;iBACtB,eAAe;qBAAI,IAAI;;iBACvB,UAAU;qBAAI,IAAI,EAAE,QAAQ;;;;;
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"liveTally.test.d.ts","sourceRoot":"","sources":["../../src/test/liveTally.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runSweep.test.d.ts","sourceRoot":"","sources":["../../src/test/runSweep.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streamSubscribe.test.d.ts","sourceRoot":"","sources":["../../src/test/streamSubscribe.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usageColumns.test.d.ts","sourceRoot":"","sources":["../../src/test/usageColumns.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
package/dist/workglow-eval.js
CHANGED
|
@@ -562,6 +562,24 @@ function extractionCountsFor(pairs, options) {
|
|
|
562
562
|
}
|
|
563
563
|
return counts;
|
|
564
564
|
}
|
|
565
|
+
function sumUsageColumns(rows) {
|
|
566
|
+
const sum = (pick) => {
|
|
567
|
+
let total;
|
|
568
|
+
for (const row of rows) {
|
|
569
|
+
const value = pick(row);
|
|
570
|
+
if (value === null || value === undefined)
|
|
571
|
+
continue;
|
|
572
|
+
total = (total ?? 0) + value;
|
|
573
|
+
}
|
|
574
|
+
return total;
|
|
575
|
+
};
|
|
576
|
+
return {
|
|
577
|
+
inputTokens: sum((r) => r.input_tokens),
|
|
578
|
+
outputTokens: sum((r) => r.output_tokens),
|
|
579
|
+
cachedTokens: sum((r) => r.cached_tokens),
|
|
580
|
+
cost: sum((r) => r.cost)
|
|
581
|
+
};
|
|
582
|
+
}
|
|
565
583
|
|
|
566
584
|
// src/commands/report.ts
|
|
567
585
|
async function printReport(stores, runId, format) {
|
|
@@ -589,22 +607,55 @@ async function printReport(stores, runId, format) {
|
|
|
589
607
|
}
|
|
590
608
|
console.log(`run ${run.run_id} \u2014 ${run.kind} on ${run.dataset} [${run.split}]`);
|
|
591
609
|
const REPORT_COLUMNS = {
|
|
592
|
-
classify: ["model", "rows", "ok", "accuracy", "avg_ms"],
|
|
593
|
-
similarity: [
|
|
594
|
-
|
|
610
|
+
classify: ["model", "rows", "ok", "accuracy", "avg_ms", "tokens", "cached", "cost"],
|
|
611
|
+
similarity: [
|
|
612
|
+
"model",
|
|
613
|
+
"rows",
|
|
614
|
+
"ok",
|
|
615
|
+
"pearson",
|
|
616
|
+
"spearman",
|
|
617
|
+
"avg_ms",
|
|
618
|
+
"tokens",
|
|
619
|
+
"cached",
|
|
620
|
+
"cost"
|
|
621
|
+
],
|
|
622
|
+
extract: [
|
|
623
|
+
"model",
|
|
624
|
+
"rows",
|
|
625
|
+
"ok",
|
|
626
|
+
"score",
|
|
627
|
+
"found",
|
|
628
|
+
"prec",
|
|
629
|
+
"avg_ms",
|
|
630
|
+
"tokens",
|
|
631
|
+
"cached",
|
|
632
|
+
"cost"
|
|
633
|
+
]
|
|
595
634
|
};
|
|
596
|
-
const
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
635
|
+
const resultsByModel = new Map;
|
|
636
|
+
for (const result of results) {
|
|
637
|
+
const list = resultsByModel.get(result.model) ?? [];
|
|
638
|
+
list.push(result);
|
|
639
|
+
resultsByModel.set(result.model, list);
|
|
640
|
+
}
|
|
641
|
+
const tableRows = reports.map((r) => {
|
|
642
|
+
const totals = sumUsageColumns(resultsByModel.get(r.model) ?? []);
|
|
643
|
+
return {
|
|
644
|
+
model: r.model,
|
|
645
|
+
rows: String(r.rows),
|
|
646
|
+
ok: String(r.okRows),
|
|
647
|
+
accuracy: formatMetric(r.accuracy),
|
|
648
|
+
pearson: formatMetric(r.pearson),
|
|
649
|
+
spearman: formatMetric(r.spearman),
|
|
650
|
+
score: formatMetric(r.score),
|
|
651
|
+
found: formatMetric(r.found),
|
|
652
|
+
prec: formatMetric(r.prec),
|
|
653
|
+
avg_ms: formatMetric(r.avgLatencyMs, 0),
|
|
654
|
+
tokens: `${totals.inputTokens ?? "-"}/${totals.outputTokens ?? "-"}`,
|
|
655
|
+
cached: String(totals.cachedTokens ?? "-"),
|
|
656
|
+
cost: totals.cost === undefined ? "-" : `$${totals.cost.toFixed(4)}`
|
|
657
|
+
};
|
|
658
|
+
});
|
|
608
659
|
console.log(formatTable(tableRows, REPORT_COLUMNS[kind]));
|
|
609
660
|
const failures = results.filter((r) => r.ok !== 1);
|
|
610
661
|
if (failures.length > 0) {
|
|
@@ -647,6 +698,9 @@ function registerReportCommand(program, openStores) {
|
|
|
647
698
|
});
|
|
648
699
|
}
|
|
649
700
|
|
|
701
|
+
// src/evals/runner.ts
|
|
702
|
+
import { estimateCost } from "@workglow/ai";
|
|
703
|
+
|
|
650
704
|
// src/models.ts
|
|
651
705
|
import { downloadModel } from "@workglow/ai";
|
|
652
706
|
|
|
@@ -673,6 +727,136 @@ function loadConfig() {
|
|
|
673
727
|
|
|
674
728
|
// src/models.ts
|
|
675
729
|
var GGUF_PREFIX = "gguf:";
|
|
730
|
+
var ANTHROPIC_PRICING = {
|
|
731
|
+
"claude-haiku-4-5": {
|
|
732
|
+
currency: "USD",
|
|
733
|
+
input: 1,
|
|
734
|
+
output: 5,
|
|
735
|
+
cached: 0.1,
|
|
736
|
+
cacheWrite: 1.25,
|
|
737
|
+
cacheStoragePerHour: undefined
|
|
738
|
+
},
|
|
739
|
+
"claude-sonnet-5": {
|
|
740
|
+
currency: "USD",
|
|
741
|
+
input: 2,
|
|
742
|
+
output: 10,
|
|
743
|
+
cached: 0.2,
|
|
744
|
+
cacheWrite: 2.5,
|
|
745
|
+
cacheStoragePerHour: undefined
|
|
746
|
+
},
|
|
747
|
+
"claude-opus-5": {
|
|
748
|
+
currency: "USD",
|
|
749
|
+
input: 15,
|
|
750
|
+
output: 75,
|
|
751
|
+
cached: 1.5,
|
|
752
|
+
cacheWrite: 18.75,
|
|
753
|
+
cacheStoragePerHour: undefined
|
|
754
|
+
}
|
|
755
|
+
};
|
|
756
|
+
var OPENAI_PRICING = {
|
|
757
|
+
"gpt-5.6-sol": {
|
|
758
|
+
currency: "USD",
|
|
759
|
+
input: 5,
|
|
760
|
+
output: 30,
|
|
761
|
+
cached: 0.5,
|
|
762
|
+
cacheWrite: undefined,
|
|
763
|
+
cacheStoragePerHour: undefined
|
|
764
|
+
},
|
|
765
|
+
"gpt-5.6-terra": {
|
|
766
|
+
currency: "USD",
|
|
767
|
+
input: 2,
|
|
768
|
+
output: 12,
|
|
769
|
+
cached: 0.2,
|
|
770
|
+
cacheWrite: undefined,
|
|
771
|
+
cacheStoragePerHour: undefined
|
|
772
|
+
},
|
|
773
|
+
"gpt-5.6-luna": {
|
|
774
|
+
currency: "USD",
|
|
775
|
+
input: 0.2,
|
|
776
|
+
output: 1.2,
|
|
777
|
+
cached: 0.02,
|
|
778
|
+
cacheWrite: undefined,
|
|
779
|
+
cacheStoragePerHour: undefined
|
|
780
|
+
},
|
|
781
|
+
"gpt-5.5": {
|
|
782
|
+
currency: "USD",
|
|
783
|
+
input: 5,
|
|
784
|
+
output: 15,
|
|
785
|
+
cached: 2.5,
|
|
786
|
+
cacheWrite: undefined,
|
|
787
|
+
cacheStoragePerHour: undefined
|
|
788
|
+
},
|
|
789
|
+
"gpt-5.4-mini": {
|
|
790
|
+
currency: "USD",
|
|
791
|
+
input: 0.4,
|
|
792
|
+
output: 1.6,
|
|
793
|
+
cached: 0.2,
|
|
794
|
+
cacheWrite: undefined,
|
|
795
|
+
cacheStoragePerHour: undefined
|
|
796
|
+
},
|
|
797
|
+
"text-embedding-3-small": {
|
|
798
|
+
currency: "USD",
|
|
799
|
+
input: 0.02,
|
|
800
|
+
output: undefined,
|
|
801
|
+
cached: undefined,
|
|
802
|
+
cacheWrite: undefined,
|
|
803
|
+
cacheStoragePerHour: undefined
|
|
804
|
+
}
|
|
805
|
+
};
|
|
806
|
+
var GEMINI_PRICING = {
|
|
807
|
+
"gemini-3.1-pro-preview": {
|
|
808
|
+
currency: "USD",
|
|
809
|
+
input: 2.5,
|
|
810
|
+
output: 10,
|
|
811
|
+
cached: 0.625,
|
|
812
|
+
cacheWrite: undefined,
|
|
813
|
+
cacheStoragePerHour: 4.5
|
|
814
|
+
},
|
|
815
|
+
"gemini-3-flash-preview": {
|
|
816
|
+
currency: "USD",
|
|
817
|
+
input: 0.3,
|
|
818
|
+
output: 2.5,
|
|
819
|
+
cached: 0.075,
|
|
820
|
+
cacheWrite: undefined,
|
|
821
|
+
cacheStoragePerHour: 1
|
|
822
|
+
}
|
|
823
|
+
};
|
|
824
|
+
var XAI_PRICING = {
|
|
825
|
+
"grok-4.6": {
|
|
826
|
+
currency: "USD",
|
|
827
|
+
input: 2,
|
|
828
|
+
output: 6,
|
|
829
|
+
cached: 0.5,
|
|
830
|
+
cacheWrite: undefined,
|
|
831
|
+
cacheStoragePerHour: undefined
|
|
832
|
+
}
|
|
833
|
+
};
|
|
834
|
+
var DEEPSEEK_PRICING = {
|
|
835
|
+
"deepseek-v4-flash": {
|
|
836
|
+
currency: "USD",
|
|
837
|
+
input: 0.14,
|
|
838
|
+
output: 0.28,
|
|
839
|
+
cached: 0.014,
|
|
840
|
+
cacheWrite: undefined,
|
|
841
|
+
cacheStoragePerHour: undefined
|
|
842
|
+
},
|
|
843
|
+
"deepseek-v4-pro": {
|
|
844
|
+
currency: "USD",
|
|
845
|
+
input: 0.56,
|
|
846
|
+
output: 1.68,
|
|
847
|
+
cached: 0.07,
|
|
848
|
+
cacheWrite: undefined,
|
|
849
|
+
cacheStoragePerHour: undefined
|
|
850
|
+
},
|
|
851
|
+
"deepseek-v4-pro-0813": {
|
|
852
|
+
currency: "USD",
|
|
853
|
+
input: 0.435,
|
|
854
|
+
output: 0.87,
|
|
855
|
+
cached: 0.0435,
|
|
856
|
+
cacheWrite: undefined,
|
|
857
|
+
cacheStoragePerHour: undefined
|
|
858
|
+
}
|
|
859
|
+
};
|
|
676
860
|
function resolveModelConfig(id, kind) {
|
|
677
861
|
if (id.startsWith(GGUF_PREFIX)) {
|
|
678
862
|
const ref = id.slice(GGUF_PREFIX.length);
|
|
@@ -702,19 +886,35 @@ function resolveModelConfig(id, kind) {
|
|
|
702
886
|
};
|
|
703
887
|
}
|
|
704
888
|
if (/^claude-/.test(id)) {
|
|
705
|
-
return {
|
|
889
|
+
return {
|
|
890
|
+
provider: "ANTHROPIC",
|
|
891
|
+
provider_config: { model_name: id },
|
|
892
|
+
pricing: ANTHROPIC_PRICING[id]
|
|
893
|
+
};
|
|
706
894
|
}
|
|
707
895
|
if (/^(?:gpt-|o\d|chatgpt-|text-embedding-)/.test(id)) {
|
|
708
|
-
return {
|
|
896
|
+
return {
|
|
897
|
+
provider: "OPENAI",
|
|
898
|
+
provider_config: { model_name: id },
|
|
899
|
+
pricing: OPENAI_PRICING[id]
|
|
900
|
+
};
|
|
709
901
|
}
|
|
710
902
|
if (/^gemini-/.test(id)) {
|
|
711
|
-
return {
|
|
903
|
+
return {
|
|
904
|
+
provider: "GOOGLE_GEMINI",
|
|
905
|
+
provider_config: { model_name: id },
|
|
906
|
+
pricing: GEMINI_PRICING[id]
|
|
907
|
+
};
|
|
712
908
|
}
|
|
713
909
|
if (/^grok-/.test(id)) {
|
|
714
|
-
return { provider: "XAI", provider_config: { model_name: id } };
|
|
910
|
+
return { provider: "XAI", provider_config: { model_name: id }, pricing: XAI_PRICING[id] };
|
|
715
911
|
}
|
|
716
912
|
if (/^deepseek-/.test(id)) {
|
|
717
|
-
return {
|
|
913
|
+
return {
|
|
914
|
+
provider: "DEEPSEEK",
|
|
915
|
+
provider_config: { model_name: id },
|
|
916
|
+
pricing: DEEPSEEK_PRICING[id]
|
|
917
|
+
};
|
|
718
918
|
}
|
|
719
919
|
throw new Error(`cannot infer a provider for model "${id}" \u2014 use a claude-*/gpt-*/gemini-*/grok-*/deepseek-* ` + `cloud id or an org/name HuggingFace ONNX model path`);
|
|
720
920
|
}
|
|
@@ -759,7 +959,7 @@ function parseModelList(models) {
|
|
|
759
959
|
}
|
|
760
960
|
|
|
761
961
|
// src/evals/classify.ts
|
|
762
|
-
import { Workflow } from "@workglow/task-graph";
|
|
962
|
+
import { USAGE_OUTPUT_KEY, Workflow } from "@workglow/task-graph";
|
|
763
963
|
|
|
764
964
|
// src/evals/prompt.ts
|
|
765
965
|
function fenceText(text) {
|
|
@@ -771,6 +971,19 @@ ${text}
|
|
|
771
971
|
${fence}`;
|
|
772
972
|
}
|
|
773
973
|
|
|
974
|
+
// src/evals/streamSubscribe.ts
|
|
975
|
+
async function runWithStreamChunks(workflow, onStreamChunk) {
|
|
976
|
+
const listener = onStreamChunk ? (_taskId, event) => onStreamChunk(event) : undefined;
|
|
977
|
+
if (listener)
|
|
978
|
+
workflow.on("stream_chunk", listener);
|
|
979
|
+
try {
|
|
980
|
+
return await workflow.run();
|
|
981
|
+
} finally {
|
|
982
|
+
if (listener)
|
|
983
|
+
workflow.off("stream_chunk", listener);
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
|
|
774
987
|
// src/evals/classify.ts
|
|
775
988
|
function expectedLabel(row, labelColumn, labelNames, candidateLabels = []) {
|
|
776
989
|
const raw = row[labelColumn];
|
|
@@ -810,7 +1023,7 @@ function makeClassifyExecutor(model, options, context) {
|
|
|
810
1023
|
required: ["label"],
|
|
811
1024
|
additionalProperties: false
|
|
812
1025
|
};
|
|
813
|
-
return async (row) => {
|
|
1026
|
+
return async (row, onStreamChunk) => {
|
|
814
1027
|
const text = String(row[options.textColumn] ?? "");
|
|
815
1028
|
const workflow = new Workflow;
|
|
816
1029
|
workflow.structuredGeneration({
|
|
@@ -820,16 +1033,17 @@ function makeClassifyExecutor(model, options, context) {
|
|
|
820
1033
|
temperature: 0,
|
|
821
1034
|
maxTokens: 256
|
|
822
1035
|
});
|
|
823
|
-
const
|
|
1036
|
+
const output = await runWithStreamChunks(workflow, onStreamChunk);
|
|
824
1037
|
return {
|
|
825
1038
|
expected: expectedLabel(row, options.labelColumn, context.labelNames, labels),
|
|
826
|
-
predicted: String(
|
|
1039
|
+
predicted: String(output.object?.label ?? ""),
|
|
1040
|
+
usage: output[USAGE_OUTPUT_KEY]
|
|
827
1041
|
};
|
|
828
1042
|
};
|
|
829
1043
|
}
|
|
830
1044
|
|
|
831
1045
|
// src/evals/extract.ts
|
|
832
|
-
import { Workflow as Workflow2 } from "@workglow/task-graph";
|
|
1046
|
+
import { USAGE_OUTPUT_KEY as USAGE_OUTPUT_KEY2, Workflow as Workflow2 } from "@workglow/task-graph";
|
|
833
1047
|
var DEFAULT_INSTRUCTION = "Extract every entity mentioned in the text.";
|
|
834
1048
|
var UNSAFE_FIELDS = new Set(["__proto__", "constructor", "prototype"]);
|
|
835
1049
|
function parseExpectedRows(value, column) {
|
|
@@ -896,7 +1110,7 @@ function makeExtractExecutor(model, options, context) {
|
|
|
896
1110
|
const instruction = options.instruction ?? DEFAULT_INSTRUCTION;
|
|
897
1111
|
const explicitFields = options.fields && options.fields.length > 0 ? resolveExtractionFields([], options.keyField, options.fields) : undefined;
|
|
898
1112
|
const explicitSchema = explicitFields ? buildItemsSchema(explicitFields, options.keyField) : undefined;
|
|
899
|
-
return async (row) => {
|
|
1113
|
+
return async (row, onStreamChunk) => {
|
|
900
1114
|
const text = String(row[options.textColumn] ?? "");
|
|
901
1115
|
const expectedRows = parseExpectedRows(row[options.expectedColumn], options.expectedColumn);
|
|
902
1116
|
const fields = explicitFields ?? resolveExtractionFields(expectedRows, options.keyField, undefined);
|
|
@@ -909,17 +1123,18 @@ function makeExtractExecutor(model, options, context) {
|
|
|
909
1123
|
temperature: 0,
|
|
910
1124
|
maxTokens: 2048
|
|
911
1125
|
});
|
|
912
|
-
const
|
|
913
|
-
const items = Array.isArray(
|
|
1126
|
+
const output = await runWithStreamChunks(workflow, onStreamChunk);
|
|
1127
|
+
const items = Array.isArray(output.object?.items) ? output.object.items : [];
|
|
914
1128
|
return {
|
|
915
1129
|
expected: JSON.stringify(expectedRows),
|
|
916
|
-
predicted: JSON.stringify(items)
|
|
1130
|
+
predicted: JSON.stringify(items),
|
|
1131
|
+
usage: output[USAGE_OUTPUT_KEY2]
|
|
917
1132
|
};
|
|
918
1133
|
};
|
|
919
1134
|
}
|
|
920
1135
|
|
|
921
1136
|
// src/evals/similarity.ts
|
|
922
|
-
import { Workflow as Workflow3 } from "@workglow/task-graph";
|
|
1137
|
+
import { USAGE_OUTPUT_KEY as USAGE_OUTPUT_KEY3, Workflow as Workflow3 } from "@workglow/task-graph";
|
|
923
1138
|
import { cosineSimilarity } from "@workglow/util/schema";
|
|
924
1139
|
function makeSimilarityExecutor(model, options, context) {
|
|
925
1140
|
for (const column of [options.textColumn, options.pairColumn, options.scoreColumn]) {
|
|
@@ -927,13 +1142,13 @@ function makeSimilarityExecutor(model, options, context) {
|
|
|
927
1142
|
throw new Error(`dataset has no column "${column}" (columns: ${context.columns.join(", ")}) \u2014 ` + `set --text-column/--pair-column/--score-column`);
|
|
928
1143
|
}
|
|
929
1144
|
}
|
|
930
|
-
return async (row) => {
|
|
1145
|
+
return async (row, onStreamChunk) => {
|
|
931
1146
|
const a = String(row[options.textColumn] ?? "");
|
|
932
1147
|
const b = String(row[options.pairColumn] ?? "");
|
|
933
1148
|
const workflow = new Workflow3;
|
|
934
1149
|
workflow.textEmbedding({ model, text: [a, b] });
|
|
935
|
-
const
|
|
936
|
-
const vectors = Array.isArray(
|
|
1150
|
+
const output = await runWithStreamChunks(workflow, onStreamChunk);
|
|
1151
|
+
const vectors = Array.isArray(output.vector) ? output.vector : [output.vector];
|
|
937
1152
|
if (vectors.length < 2) {
|
|
938
1153
|
throw new Error(`expected 2 embeddings, got ${vectors.length}`);
|
|
939
1154
|
}
|
|
@@ -943,12 +1158,25 @@ function makeSimilarityExecutor(model, options, context) {
|
|
|
943
1158
|
}
|
|
944
1159
|
return {
|
|
945
1160
|
expectedValue: gold,
|
|
946
|
-
predictedValue: cosineSimilarity(vectors[0], vectors[1])
|
|
1161
|
+
predictedValue: cosineSimilarity(vectors[0], vectors[1]),
|
|
1162
|
+
usage: output[USAGE_OUTPUT_KEY3]
|
|
947
1163
|
};
|
|
948
1164
|
};
|
|
949
1165
|
}
|
|
950
1166
|
|
|
951
1167
|
// src/evals/runner.ts
|
|
1168
|
+
function usageColumns(usage, pricing) {
|
|
1169
|
+
const estimate = usage ? estimateCost(usage, pricing) : undefined;
|
|
1170
|
+
return {
|
|
1171
|
+
input_tokens: usage?.input ?? null,
|
|
1172
|
+
output_tokens: usage?.output ?? null,
|
|
1173
|
+
cached_tokens: usage?.cached ?? null,
|
|
1174
|
+
cache_write_tokens: usage?.cacheWrite ?? null,
|
|
1175
|
+
total_tokens: usage?.total ?? null,
|
|
1176
|
+
cost: estimate?.amount ?? null,
|
|
1177
|
+
currency: estimate?.currency ?? null
|
|
1178
|
+
};
|
|
1179
|
+
}
|
|
952
1180
|
var EXECUTORS = {
|
|
953
1181
|
classify: makeClassifyExecutor,
|
|
954
1182
|
similarity: makeSimilarityExecutor,
|
|
@@ -979,11 +1207,13 @@ async function runSweep(stores, rows, options) {
|
|
|
979
1207
|
for (const modelId of options.models) {
|
|
980
1208
|
let executor;
|
|
981
1209
|
let setupError;
|
|
1210
|
+
let modelPricing;
|
|
982
1211
|
try {
|
|
983
1212
|
let config = resolveModelConfig(modelId, options.kind);
|
|
984
1213
|
if (options.kind === "similarity")
|
|
985
1214
|
config = await ensureEmbeddingDimensions(config);
|
|
986
1215
|
await ensureModelDownloaded(config);
|
|
1216
|
+
modelPricing = config.pricing;
|
|
987
1217
|
executor = makeExecutor(options.kind, config, options.columns, options.context);
|
|
988
1218
|
} catch (err) {
|
|
989
1219
|
setupError = err instanceof Error ? err.message : String(err);
|
|
@@ -991,13 +1221,15 @@ async function runSweep(stores, rows, options) {
|
|
|
991
1221
|
for (const { record, row, parseError } of parsedRows) {
|
|
992
1222
|
const t0 = performance.now();
|
|
993
1223
|
let outcome;
|
|
1224
|
+
let outcomeUsage;
|
|
994
1225
|
if (!executor) {
|
|
995
1226
|
outcome = failedOutcome(setupError ?? "executor unavailable");
|
|
996
1227
|
} else if (!row) {
|
|
997
1228
|
outcome = failedOutcome(parseError ?? "invalid stored row");
|
|
998
1229
|
} else {
|
|
999
1230
|
try {
|
|
1000
|
-
const prediction = await executor(row);
|
|
1231
|
+
const prediction = await executor(row, options.onStreamChunk);
|
|
1232
|
+
outcomeUsage = prediction.usage;
|
|
1001
1233
|
outcome = {
|
|
1002
1234
|
ok: 1,
|
|
1003
1235
|
error: null,
|
|
@@ -1016,10 +1248,11 @@ async function runSweep(stores, rows, options) {
|
|
|
1016
1248
|
model: modelId,
|
|
1017
1249
|
row_index: record.row_index,
|
|
1018
1250
|
latency_ms: Math.round(latency * 100) / 100,
|
|
1251
|
+
...usageColumns(outcomeUsage, modelPricing),
|
|
1019
1252
|
...outcome
|
|
1020
1253
|
});
|
|
1021
1254
|
done++;
|
|
1022
|
-
options.onProgress?.(done, total, modelId, outcome.ok === 1);
|
|
1255
|
+
options.onProgress?.(done, total, modelId, outcome.ok === 1, outcomeUsage);
|
|
1023
1256
|
}
|
|
1024
1257
|
}
|
|
1025
1258
|
return run.run_id;
|
|
@@ -1035,6 +1268,39 @@ function failedOutcome(error) {
|
|
|
1035
1268
|
};
|
|
1036
1269
|
}
|
|
1037
1270
|
|
|
1271
|
+
// src/report/liveTally.ts
|
|
1272
|
+
import { estimateCost as estimateCost2, formatCost, formatUsage } from "@workglow/ai";
|
|
1273
|
+
import { mergeUsage } from "@workglow/task-graph";
|
|
1274
|
+
|
|
1275
|
+
class LiveTally {
|
|
1276
|
+
pricing;
|
|
1277
|
+
byModel = new Map;
|
|
1278
|
+
startedAt;
|
|
1279
|
+
constructor(pricing, now) {
|
|
1280
|
+
this.pricing = pricing;
|
|
1281
|
+
this.startedAt = now;
|
|
1282
|
+
}
|
|
1283
|
+
record(model, ok, usage) {
|
|
1284
|
+
const tally = this.byModel.get(model) ?? { rows: 0, ok: 0, usage: undefined };
|
|
1285
|
+
tally.rows += 1;
|
|
1286
|
+
if (ok)
|
|
1287
|
+
tally.ok += 1;
|
|
1288
|
+
tally.usage = mergeUsage(tally.usage, usage);
|
|
1289
|
+
this.byModel.set(model, tally);
|
|
1290
|
+
}
|
|
1291
|
+
render(done, total, now) {
|
|
1292
|
+
const elapsedSec = Math.max((now - this.startedAt) / 1000, 0.001);
|
|
1293
|
+
const lines = [`[${done}/${total}]`];
|
|
1294
|
+
for (const [model, tally] of this.byModel) {
|
|
1295
|
+
const tps = tally.usage?.output === undefined ? "" : ` ${Math.round(tally.usage.output / elapsedSec)} tok/s`;
|
|
1296
|
+
const cost = tally.usage ? formatCost(estimateCost2(tally.usage, this.pricing(model))) : "";
|
|
1297
|
+
lines.push(` ${model} ${tally.ok}/${tally.rows} ok ` + `${formatUsage(tally.usage, "detailed")}${tps}${cost ? ` ${cost}` : ""}`);
|
|
1298
|
+
}
|
|
1299
|
+
return lines.join(`
|
|
1300
|
+
`);
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1038
1304
|
// src/commands/run.ts
|
|
1039
1305
|
var DEFAULT_MODELS = {
|
|
1040
1306
|
classify: "onnx-community/LFM2.5-350M-ONNX",
|
|
@@ -1053,7 +1319,7 @@ var DESCRIPTIONS = {
|
|
|
1053
1319
|
};
|
|
1054
1320
|
function registerRunCommand(program, openStores, ensureProviders) {
|
|
1055
1321
|
for (const kind of ["classify", "similarity", "extract"]) {
|
|
1056
|
-
const command = program.command(`run-${kind}`).description(DESCRIPTIONS[kind]).requiredOption("--dataset <id>", "a dataset previously stored via `dataset pull`").option("--split <split>", "dataset split", "test").option("--models <list>", `comma-separated model ids (default: ${DEFAULT_MODELS[kind]})`).option("--limit <n>", "cap the number of stored rows to run").option("--text-column <name>", `input text column (default: ${DEFAULT_TEXT_COLUMN[kind]})`).option("--format <fmt>", "report output: table or json", "table");
|
|
1322
|
+
const command = program.command(`run-${kind}`).description(DESCRIPTIONS[kind]).requiredOption("--dataset <id>", "a dataset previously stored via `dataset pull`").option("--split <split>", "dataset split", "test").option("--models <list>", `comma-separated model ids (default: ${DEFAULT_MODELS[kind]})`).option("--limit <n>", "cap the number of stored rows to run").option("--text-column <name>", `input text column (default: ${DEFAULT_TEXT_COLUMN[kind]})`).option("--format <fmt>", "report output: table or json", "table").option("--stream", "render in-flight generation text for the current row", false);
|
|
1057
1323
|
if (kind === "classify") {
|
|
1058
1324
|
command.option("--label-column <name>", "gold label column (default: label)").option("--labels <list>", "comma-separated candidate labels override");
|
|
1059
1325
|
} else if (kind === "similarity") {
|
|
@@ -1113,6 +1379,11 @@ async function runEval(kind, flags, stores) {
|
|
|
1113
1379
|
labelNames: meta.label_names ? JSON.parse(meta.label_names) : {}
|
|
1114
1380
|
};
|
|
1115
1381
|
console.error(`running ${kind} over ${limited.length} rows of ${flags.dataset} [${flags.split}] ` + `with ${models.length} model(s)`);
|
|
1382
|
+
const tally = new LiveTally((id) => resolveModelConfig(id, kind).pricing, Date.now());
|
|
1383
|
+
const onStreamChunk = flags.stream ? (event) => {
|
|
1384
|
+
if (event.type === "text-delta")
|
|
1385
|
+
process.stderr.write(event.textDelta);
|
|
1386
|
+
} : undefined;
|
|
1116
1387
|
const runId = await runSweep(stores, limited, {
|
|
1117
1388
|
kind,
|
|
1118
1389
|
dataset: flags.dataset,
|
|
@@ -1120,9 +1391,12 @@ async function runEval(kind, flags, stores) {
|
|
|
1120
1391
|
models,
|
|
1121
1392
|
columns,
|
|
1122
1393
|
context,
|
|
1123
|
-
onProgress: (done, total, model, ok) => {
|
|
1124
|
-
|
|
1125
|
-
|
|
1394
|
+
onProgress: (done, total, model, ok, usage) => {
|
|
1395
|
+
tally.record(model, ok, usage);
|
|
1396
|
+
process.stderr.write(`${tally.render(done, total, Date.now())}
|
|
1397
|
+
`);
|
|
1398
|
+
},
|
|
1399
|
+
onStreamChunk
|
|
1126
1400
|
});
|
|
1127
1401
|
console.error(`run ${runId} complete
|
|
1128
1402
|
`);
|
|
@@ -1232,7 +1506,14 @@ var EvalResultSchema = {
|
|
|
1232
1506
|
predicted: { type: ["string", "null"] },
|
|
1233
1507
|
expected_value: { type: ["number", "null"] },
|
|
1234
1508
|
predicted_value: { type: ["number", "null"] },
|
|
1235
|
-
latency_ms: { type: "number" }
|
|
1509
|
+
latency_ms: { type: "number" },
|
|
1510
|
+
input_tokens: { type: ["integer", "null"] },
|
|
1511
|
+
output_tokens: { type: ["integer", "null"] },
|
|
1512
|
+
cached_tokens: { type: ["integer", "null"] },
|
|
1513
|
+
cache_write_tokens: { type: ["integer", "null"] },
|
|
1514
|
+
total_tokens: { type: ["integer", "null"] },
|
|
1515
|
+
cost: { type: ["number", "null"] },
|
|
1516
|
+
currency: { type: ["string", "null"] }
|
|
1236
1517
|
},
|
|
1237
1518
|
required: ["run_id", "model", "row_index", "ok", "latency_ms"],
|
|
1238
1519
|
additionalProperties: false
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workglow/eval",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.40",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/workglow-dev/libs.git",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"build-js": "bun build --target=bun --packages=external --outdir ./dist ./src/workglow-eval.ts",
|
|
22
22
|
"build-js-worker-hft": "bun build --target=node --packages=external --outdir ./dist ./src/worker_hft.ts",
|
|
23
23
|
"build-types": "rm -f tsconfig.tsbuildinfo && tsgo",
|
|
24
|
-
"test": "vitest run",
|
|
24
|
+
"test": "vitest run --config ../../vitest.config.ts --project eval",
|
|
25
25
|
"test:watch": "vitest",
|
|
26
26
|
"build-js-worker-llamacpp": "bun build --target=node --packages=external --outdir ./dist ./src/worker_llamacpp.ts"
|
|
27
27
|
},
|
|
@@ -33,21 +33,21 @@
|
|
|
33
33
|
"src/**/*.md"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@workglow/ai": "0.3.
|
|
37
|
-
"@workglow/anthropic": "0.3.
|
|
38
|
-
"@workglow/deepseek": "0.3.
|
|
39
|
-
"@workglow/google-gemini": "0.3.
|
|
40
|
-
"@workglow/huggingface-transformers": "0.3.
|
|
41
|
-
"@workglow/node-llama-cpp": "0.3.
|
|
42
|
-
"@workglow/openai": "0.3.
|
|
43
|
-
"@workglow/sqlite": "0.3.
|
|
44
|
-
"@workglow/storage": "0.3.
|
|
45
|
-
"@workglow/task-graph": "0.3.
|
|
46
|
-
"@workglow/util": "0.3.
|
|
47
|
-
"@workglow/xai": "0.3.
|
|
36
|
+
"@workglow/ai": "0.3.40",
|
|
37
|
+
"@workglow/anthropic": "0.3.40",
|
|
38
|
+
"@workglow/deepseek": "0.3.40",
|
|
39
|
+
"@workglow/google-gemini": "0.3.40",
|
|
40
|
+
"@workglow/huggingface-transformers": "0.3.40",
|
|
41
|
+
"@workglow/node-llama-cpp": "0.3.40",
|
|
42
|
+
"@workglow/openai": "0.3.40",
|
|
43
|
+
"@workglow/sqlite": "0.3.40",
|
|
44
|
+
"@workglow/storage": "0.3.40",
|
|
45
|
+
"@workglow/task-graph": "0.3.40",
|
|
46
|
+
"@workglow/util": "0.3.40",
|
|
47
|
+
"@workglow/xai": "0.3.40",
|
|
48
48
|
"@huggingface/transformers": "^4.2.0",
|
|
49
49
|
"commander": "^15.0.0",
|
|
50
|
-
"hyparquet": "^1.
|
|
50
|
+
"hyparquet": "^1.28.1",
|
|
51
51
|
"hyparquet-compressors": "^1.1.1"
|
|
52
52
|
},
|
|
53
53
|
"publishConfig": {
|