@zhanla/sdk-ts 0.2.0 → 0.3.1
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/bin/discover.js +37 -17
- package/bin/env.js +72 -0
- package/bin/run.js +2 -0
- package/dist/executor.d.ts +3 -3
- package/dist/executor.js +80 -12
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/manifest.d.ts +3 -3
- package/dist/types.d.ts +26 -21
- package/dist/types.js +37 -13
- package/package.json +7 -2
package/bin/discover.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
import { pathToFileURL } from "url";
|
|
13
13
|
import { resolve } from "path";
|
|
14
|
+
import { loadDotenvLocal, splitFileSpec } from "./env.js";
|
|
14
15
|
|
|
15
16
|
function isComponentLike(value) {
|
|
16
17
|
return (
|
|
@@ -77,8 +78,34 @@ function stableSerialize(value) {
|
|
|
77
78
|
return JSON.stringify(value);
|
|
78
79
|
}
|
|
79
80
|
|
|
80
|
-
function
|
|
81
|
-
return
|
|
81
|
+
function projectRefForHash(ref) {
|
|
82
|
+
return { key: ref.key, component_type: ref.component_type };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function sortAndProjectRefs(refs) {
|
|
86
|
+
return [...refs].map(projectRefForHash).sort((a, b) => a.key.localeCompare(b.key));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function normalizeStepForHash(step) {
|
|
90
|
+
if (step.is_conditional) return step;
|
|
91
|
+
const ref = step.component_ref;
|
|
92
|
+
if (ref == null) return step;
|
|
93
|
+
return { ...step, component_ref: projectRefForHash(ref) };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function normalizeEvalNodeForHash(node) {
|
|
97
|
+
if (node == null || typeof node !== "object") return node;
|
|
98
|
+
const result = { ...node };
|
|
99
|
+
if (result.eval_ref != null) result.eval_ref = projectRefForHash(result.eval_ref);
|
|
100
|
+
for (const branch of ["if_pass", "if_fail"]) {
|
|
101
|
+
if (Array.isArray(result[branch])) {
|
|
102
|
+
result[branch] = result[branch].map((edge) => {
|
|
103
|
+
if (edge == null || typeof edge !== "object" || edge.node == null) return edge;
|
|
104
|
+
return { ...edge, node: normalizeEvalNodeForHash(edge.node) };
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return result;
|
|
82
109
|
}
|
|
83
110
|
|
|
84
111
|
function behaviorFields(manifest) {
|
|
@@ -91,13 +118,13 @@ function behaviorFields(manifest) {
|
|
|
91
118
|
if (manifest.model != null) fields.model = manifest.model;
|
|
92
119
|
if (manifest.temperature != null) fields.temperature = manifest.temperature;
|
|
93
120
|
if (manifest.output_schema != null) fields.output_schema = manifest.output_schema;
|
|
94
|
-
if (manifest.tool_refs != null) fields.tool_refs =
|
|
95
|
-
if (manifest.skill_refs != null) fields.skill_refs =
|
|
96
|
-
if (manifest.agent_refs != null) fields.agent_refs =
|
|
97
|
-
if (manifest.steps != null) fields.steps = manifest.steps;
|
|
98
|
-
if (manifest.eval_refs != null) fields.eval_refs =
|
|
121
|
+
if (manifest.tool_refs != null) fields.tool_refs = sortAndProjectRefs(manifest.tool_refs);
|
|
122
|
+
if (manifest.skill_refs != null) fields.skill_refs = sortAndProjectRefs(manifest.skill_refs);
|
|
123
|
+
if (manifest.agent_refs != null) fields.agent_refs = sortAndProjectRefs(manifest.agent_refs);
|
|
124
|
+
if (manifest.steps != null) fields.steps = manifest.steps.map(normalizeStepForHash);
|
|
125
|
+
if (manifest.eval_refs != null) fields.eval_refs = sortAndProjectRefs(manifest.eval_refs);
|
|
99
126
|
if (manifest.weights != null) fields.weights = manifest.weights;
|
|
100
|
-
if (manifest.root != null) fields.root = manifest.root;
|
|
127
|
+
if (manifest.root != null) fields.root = normalizeEvalNodeForHash(manifest.root);
|
|
101
128
|
if (manifest.source_code != null) fields.source_code = manifest.source_code;
|
|
102
129
|
if (manifest.model_response_format != null) {
|
|
103
130
|
fields.model_response_format = manifest.model_response_format;
|
|
@@ -186,17 +213,10 @@ export function buildDiscoveredManifests({
|
|
|
186
213
|
}
|
|
187
214
|
|
|
188
215
|
export async function runDiscover(fileSpec) {
|
|
189
|
-
|
|
190
|
-
let symbolName = null;
|
|
191
|
-
|
|
192
|
-
const colonIndex = fileSpec.lastIndexOf(":");
|
|
193
|
-
// Handle Windows drive letters (e.g. C:\...) — only split if colon is not at position 1
|
|
194
|
-
if (colonIndex > 1) {
|
|
195
|
-
filePath = fileSpec.slice(0, colonIndex);
|
|
196
|
-
symbolName = fileSpec.slice(colonIndex + 1) || null;
|
|
197
|
-
}
|
|
216
|
+
const { filePath, symbolName } = splitFileSpec(fileSpec);
|
|
198
217
|
|
|
199
218
|
const absolutePath = resolve(filePath);
|
|
219
|
+
loadDotenvLocal(absolutePath);
|
|
200
220
|
const fileUrl = pathToFileURL(absolutePath).href;
|
|
201
221
|
|
|
202
222
|
let moduleExports;
|
package/bin/env.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { existsSync, readFileSync, statSync } from "fs";
|
|
4
|
+
import { dirname, join, resolve } from "path";
|
|
5
|
+
|
|
6
|
+
function isDirectory(path) {
|
|
7
|
+
try {
|
|
8
|
+
return statSync(path).isDirectory();
|
|
9
|
+
} catch {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function splitFileSpec(fileSpec) {
|
|
15
|
+
const colonIndex = fileSpec.lastIndexOf(":");
|
|
16
|
+
// Preserve Windows drive letters (e.g. C:\...) by only splitting on later colons.
|
|
17
|
+
if (colonIndex > 1) {
|
|
18
|
+
return {
|
|
19
|
+
filePath: fileSpec.slice(0, colonIndex),
|
|
20
|
+
symbolName: fileSpec.slice(colonIndex + 1) || null,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return { filePath: fileSpec, symbolName: null };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function findDotenvLocal(startPath) {
|
|
27
|
+
let current = resolve(startPath);
|
|
28
|
+
if (!isDirectory(current)) {
|
|
29
|
+
current = dirname(current);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
while (true) {
|
|
33
|
+
const candidate = join(current, ".env.local");
|
|
34
|
+
if (existsSync(candidate)) {
|
|
35
|
+
return candidate;
|
|
36
|
+
}
|
|
37
|
+
const parent = dirname(current);
|
|
38
|
+
if (parent === current) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
current = parent;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function loadDotenvLocal(startPath) {
|
|
46
|
+
const envPath = findDotenvLocal(startPath);
|
|
47
|
+
if (!envPath) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const source = readFileSync(envPath, "utf8");
|
|
52
|
+
for (const line of source.split(/\r?\n/)) {
|
|
53
|
+
const trimmed = line.trim();
|
|
54
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
55
|
+
const equalsIndex = trimmed.indexOf("=");
|
|
56
|
+
if (equalsIndex === -1) continue;
|
|
57
|
+
|
|
58
|
+
const key = trimmed.slice(0, equalsIndex).trim();
|
|
59
|
+
let value = trimmed.slice(equalsIndex + 1).trim();
|
|
60
|
+
if (
|
|
61
|
+
(value.startsWith('"') && value.endsWith('"'))
|
|
62
|
+
|| (value.startsWith("'") && value.endsWith("'"))
|
|
63
|
+
) {
|
|
64
|
+
value = value.slice(1, -1);
|
|
65
|
+
}
|
|
66
|
+
if (key && process.env[key] === undefined) {
|
|
67
|
+
process.env[key] = value;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return envPath;
|
|
72
|
+
}
|
package/bin/run.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import { pathToFileURL } from "url";
|
|
12
12
|
import { resolve } from "path";
|
|
13
13
|
import readline from "readline";
|
|
14
|
+
import { loadDotenvLocal } from "./env.js";
|
|
14
15
|
|
|
15
16
|
function redirectConsoleToStderr() {
|
|
16
17
|
const stringifyArg = (arg) => {
|
|
@@ -54,6 +55,7 @@ async function loadTargetComponent(target, collectExportedComponents) {
|
|
|
54
55
|
const { filePath, symbolName } = parseTarget(target);
|
|
55
56
|
|
|
56
57
|
const absolutePath = resolve(filePath);
|
|
58
|
+
loadDotenvLocal(absolutePath);
|
|
57
59
|
const fileUrl = pathToFileURL(absolutePath).href;
|
|
58
60
|
|
|
59
61
|
let moduleExports;
|
package/dist/executor.d.ts
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
* Local execution engine for TypeScript SDK components.
|
|
3
3
|
* Mirrors the Python CLI executor's component-type dispatch semantics.
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
5
|
+
import { ZhanlaComponent } from "./types.js";
|
|
6
6
|
export interface RowResult {
|
|
7
7
|
status: "ok" | "error";
|
|
8
8
|
output?: Record<string, unknown>;
|
|
9
9
|
error?: string;
|
|
10
10
|
pathTaken?: Record<string, unknown>;
|
|
11
11
|
}
|
|
12
|
-
export declare function executeComponent(comp:
|
|
13
|
-
export declare function executeRow(component:
|
|
12
|
+
export declare function executeComponent(comp: ZhanlaComponent, kwargs: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
13
|
+
export declare function executeRow(component: ZhanlaComponent, evalComponent: ZhanlaComponent | null, row: Record<string, unknown>): Promise<RowResult>;
|
package/dist/executor.js
CHANGED
|
@@ -13,6 +13,17 @@ const JSON_OUTPUT_ERROR_MARKERS = [
|
|
|
13
13
|
"extra data",
|
|
14
14
|
"unexpected token",
|
|
15
15
|
];
|
|
16
|
+
const EXECUTION_MODES = {
|
|
17
|
+
tool: "code",
|
|
18
|
+
code_eval: "code",
|
|
19
|
+
skill: "prompt",
|
|
20
|
+
agent: "prompt",
|
|
21
|
+
llm_processor: "prompt",
|
|
22
|
+
llm_eval: "prompt",
|
|
23
|
+
orchestration: "dag",
|
|
24
|
+
checklist: "composite",
|
|
25
|
+
eval_tree: "composite",
|
|
26
|
+
};
|
|
16
27
|
function buildComponentFailureOutput(error) {
|
|
17
28
|
return { [COMPONENT_ERROR_KEY]: error };
|
|
18
29
|
}
|
|
@@ -58,12 +69,6 @@ function stringifyValue(value) {
|
|
|
58
69
|
return String(value);
|
|
59
70
|
}
|
|
60
71
|
}
|
|
61
|
-
function deriveModelInput(row) {
|
|
62
|
-
if ("input" in row) {
|
|
63
|
-
return stringifyValue(row["input"]);
|
|
64
|
-
}
|
|
65
|
-
return stringifyValue(row);
|
|
66
|
-
}
|
|
67
72
|
function deriveExpectedOutput(row) {
|
|
68
73
|
if ("expected_output" in row) {
|
|
69
74
|
return stringifyValue(row["expected_output"]);
|
|
@@ -151,7 +156,14 @@ async function runTool(comp, kwargs) {
|
|
|
151
156
|
return { result };
|
|
152
157
|
}
|
|
153
158
|
async function runCodeEval(comp, kwargs) {
|
|
154
|
-
const
|
|
159
|
+
const modelResponse = kwargs["model_response"];
|
|
160
|
+
const expectedResponse = kwargs["expected_response"] ?? null;
|
|
161
|
+
const { value: result, logs } = await captureConsoleLogs(async () => {
|
|
162
|
+
if (comp.isAsync) {
|
|
163
|
+
return await comp.fn(modelResponse, expectedResponse);
|
|
164
|
+
}
|
|
165
|
+
return comp.fn(modelResponse, expectedResponse);
|
|
166
|
+
});
|
|
155
167
|
if (result !== null && typeof result === "object" && !Array.isArray(result)) {
|
|
156
168
|
return logs.length > 0
|
|
157
169
|
? { ...result, logs }
|
|
@@ -289,6 +301,32 @@ async function runLLMProcessor(comp, kwargs) {
|
|
|
289
301
|
async function runLLMEval(comp, kwargs) {
|
|
290
302
|
return runRunnerComponent(comp, kwargs);
|
|
291
303
|
}
|
|
304
|
+
function componentExecutionMode(component) {
|
|
305
|
+
return EXECUTION_MODES[component.componentType];
|
|
306
|
+
}
|
|
307
|
+
function componentSourceLanguage(component) {
|
|
308
|
+
switch (component.componentType) {
|
|
309
|
+
case "tool":
|
|
310
|
+
case "agent":
|
|
311
|
+
case "llm_processor":
|
|
312
|
+
case "llm_eval":
|
|
313
|
+
return "typescript";
|
|
314
|
+
default:
|
|
315
|
+
return undefined;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
function componentPrompt(component) {
|
|
319
|
+
if ("instructions" in component && typeof component.instructions === "string" && component.instructions !== "") {
|
|
320
|
+
return component.instructions;
|
|
321
|
+
}
|
|
322
|
+
return undefined;
|
|
323
|
+
}
|
|
324
|
+
function componentSourceCode(component) {
|
|
325
|
+
if ("fn" in component && typeof component.fn === "function") {
|
|
326
|
+
return component.fn.toString();
|
|
327
|
+
}
|
|
328
|
+
return undefined;
|
|
329
|
+
}
|
|
292
330
|
async function runOrchestration(comp, inputData, executedSteps) {
|
|
293
331
|
// Flatten input into accumulated so steps can access row fields directly.
|
|
294
332
|
// Each step's output is also merged at the top level AND stored at step.name.
|
|
@@ -331,14 +369,45 @@ async function runOrchestration(comp, inputData, executedSteps) {
|
|
|
331
369
|
continue;
|
|
332
370
|
}
|
|
333
371
|
const stepInput = { ...accumulated };
|
|
334
|
-
|
|
372
|
+
let stepOutput;
|
|
373
|
+
let nestedTrace;
|
|
374
|
+
if (component.componentType === "orchestration") {
|
|
375
|
+
const nestedSteps = [];
|
|
376
|
+
stepOutput = await runOrchestration(component, accumulated, nestedSteps);
|
|
377
|
+
nestedTrace = { kind: "orchestration", steps: nestedSteps };
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
stepOutput = await executeComponent(component, accumulated);
|
|
381
|
+
}
|
|
335
382
|
if (executedSteps) {
|
|
336
|
-
|
|
383
|
+
const stepRecord = {
|
|
337
384
|
name: step.name,
|
|
338
385
|
type: component.componentType,
|
|
386
|
+
component_type: component.componentType,
|
|
387
|
+
component_key: component.key,
|
|
339
388
|
input: stepInput,
|
|
340
389
|
output: stepOutput,
|
|
341
|
-
}
|
|
390
|
+
};
|
|
391
|
+
const executionMode = componentExecutionMode(component);
|
|
392
|
+
if (executionMode !== undefined) {
|
|
393
|
+
stepRecord.execution_mode = executionMode;
|
|
394
|
+
}
|
|
395
|
+
const sourceLanguage = componentSourceLanguage(component);
|
|
396
|
+
if (sourceLanguage !== undefined) {
|
|
397
|
+
stepRecord.source_language = sourceLanguage;
|
|
398
|
+
}
|
|
399
|
+
const prompt = componentPrompt(component);
|
|
400
|
+
if (prompt !== undefined) {
|
|
401
|
+
stepRecord.prompt = prompt;
|
|
402
|
+
}
|
|
403
|
+
const sourceCode = componentSourceCode(component);
|
|
404
|
+
if (sourceCode !== undefined) {
|
|
405
|
+
stepRecord.source_code = sourceCode;
|
|
406
|
+
}
|
|
407
|
+
if (nestedTrace !== undefined) {
|
|
408
|
+
stepRecord.trace = nestedTrace;
|
|
409
|
+
}
|
|
410
|
+
executedSteps.push(stepRecord);
|
|
342
411
|
}
|
|
343
412
|
// Merge step output at top level for convenient access in downstream steps
|
|
344
413
|
Object.assign(accumulated, stepOutput);
|
|
@@ -490,9 +559,8 @@ export async function executeRow(component, evalComponent, row) {
|
|
|
490
559
|
};
|
|
491
560
|
}
|
|
492
561
|
const evalKwargs = {
|
|
493
|
-
model_input: deriveModelInput(row),
|
|
494
562
|
model_response: deriveModelResponse(output),
|
|
495
|
-
|
|
563
|
+
expected_response: deriveExpectedOutput(row) || null,
|
|
496
564
|
};
|
|
497
565
|
try {
|
|
498
566
|
const evalOutput = await executeComponent(evalComponent, evalKwargs);
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* zhanla-sdk-ts public API.
|
|
3
3
|
* Import component classes to define zhanla components in TypeScript.
|
|
4
4
|
*/
|
|
5
|
-
export { Tool, CodeEval, Skill, Agent, LLMProcessor, LLMEval, Runner, Conditional, Step, Orchestration, Leaf, Edge, Branch, Checklist, EvalTree,
|
|
6
|
-
export type { ToolOptions, CodeEvalOptions, SkillOptions, AgentOptions, LLMProcessorOptions, LLMEvalOptions, OrchestrationOptions, ChecklistOptions, EvalTreeOptions, StepOptions, ComponentType, JsonSchema, JsonSchemaObject, JsonSchemaArray, JsonSchemaScalar, ToolCall, LLMResponse, RunnerOptions, RunnerCallOptions, RunnerMessage, } from "./types.js";
|
|
5
|
+
export { Tool, CodeEval, Skill, Agent, LLMProcessor, LLMEval, Runner, Conditional, Step, Orchestration, Leaf, Edge, Branch, Checklist, EvalTree, ZhanlaComponent, RUNNABLE_TYPES, EVAL_TYPES, } from "./types.js";
|
|
6
|
+
export type { ComponentValue, ToolOptions, CodeEvalOptions, SkillOptions, AgentOptions, LLMProcessorOptions, LLMEvalOptions, OrchestrationOptions, ChecklistOptions, EvalTreeOptions, StepOptions, ComponentType, JsonSchema, JsonSchemaObject, JsonSchemaArray, JsonSchemaScalar, ToolCall, LLMResponse, RunnerOptions, RunnerCallOptions, RunnerMessage, } from "./types.js";
|
|
7
7
|
export { toManifest, collectExportedComponents } from "./manifest.js";
|
|
8
8
|
export type { ComponentManifest, StepManifest, BranchManifest, EdgeManifest, LeafManifest } from "./manifest.js";
|
|
9
9
|
export { executeComponent, executeRow } from "./executor.js";
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* zhanla-sdk-ts public API.
|
|
3
3
|
* Import component classes to define zhanla components in TypeScript.
|
|
4
4
|
*/
|
|
5
|
-
export { Tool, CodeEval, Skill, Agent, LLMProcessor, LLMEval, Runner, Conditional, Step, Orchestration, Leaf, Edge, Branch, Checklist, EvalTree,
|
|
5
|
+
export { Tool, CodeEval, Skill, Agent, LLMProcessor, LLMEval, Runner, Conditional, Step, Orchestration, Leaf, Edge, Branch, Checklist, EvalTree, ZhanlaComponent, RUNNABLE_TYPES, EVAL_TYPES, } from "./types.js";
|
|
6
6
|
export { toManifest, collectExportedComponents } from "./manifest.js";
|
|
7
7
|
export { executeComponent, executeRow } from "./executor.js";
|
|
8
8
|
export { wrap } from "./wrap.js";
|
package/dist/manifest.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Manifest emission — serialize SDK component instances into ComponentManifest objects.
|
|
3
3
|
* The manifest shape mirrors the Python CLI's ComponentManifest dataclass.
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
5
|
+
import { ZhanlaComponent, ComponentRef, JsonSchema } from "./types.js";
|
|
6
6
|
export interface StepManifest {
|
|
7
7
|
name: string;
|
|
8
8
|
component_ref?: ComponentRef;
|
|
@@ -62,8 +62,8 @@ export interface ComponentManifest {
|
|
|
62
62
|
source_format?: string;
|
|
63
63
|
model_response_format?: string;
|
|
64
64
|
}
|
|
65
|
-
export declare function toManifest(component:
|
|
65
|
+
export declare function toManifest(component: ZhanlaComponent, opts?: {
|
|
66
66
|
filePath?: string;
|
|
67
67
|
symbolName?: string;
|
|
68
68
|
}): ComponentManifest;
|
|
69
|
-
export declare function collectExportedComponents(moduleExports: Record<string, unknown>):
|
|
69
|
+
export declare function collectExportedComponents(moduleExports: Record<string, unknown>): ZhanlaComponent[];
|
package/dist/types.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export type JsonSchemaArray = {
|
|
|
16
16
|
items: JsonSchema;
|
|
17
17
|
};
|
|
18
18
|
export type JsonSchema = JsonSchemaScalar | JsonSchemaObject | JsonSchemaArray | Record<string, unknown>;
|
|
19
|
+
export type ComponentValue = string | number | Record<string, unknown> | unknown[];
|
|
19
20
|
export type ComponentType = "tool" | "code_eval" | "skill" | "agent" | "llm_processor" | "llm_eval" | "orchestration" | "checklist" | "eval_tree";
|
|
20
21
|
export interface ComponentRef {
|
|
21
22
|
key: string;
|
|
@@ -60,7 +61,7 @@ export interface RunnerOptions {
|
|
|
60
61
|
export declare class Runner {
|
|
61
62
|
readonly client: unknown;
|
|
62
63
|
constructor(opts: RunnerOptions);
|
|
63
|
-
buildMessages(component: Pick<
|
|
64
|
+
buildMessages(component: Pick<ZhanlaComponent, "description"> & {
|
|
64
65
|
instructions?: string;
|
|
65
66
|
}, row: Record<string, unknown>): RunnerMessage[];
|
|
66
67
|
private providerName;
|
|
@@ -72,9 +73,10 @@ export declare class Runner {
|
|
|
72
73
|
jsonRepair?: boolean;
|
|
73
74
|
text: string;
|
|
74
75
|
}): Promise<string>;
|
|
76
|
+
private warnModelProviderMismatch;
|
|
75
77
|
callLlm(opts: RunnerCallOptions): Promise<LLMResponse>;
|
|
76
78
|
}
|
|
77
|
-
export declare abstract class
|
|
79
|
+
export declare abstract class ZhanlaComponent {
|
|
78
80
|
abstract readonly componentType: ComponentType;
|
|
79
81
|
abstract readonly name: string;
|
|
80
82
|
abstract readonly description: string;
|
|
@@ -90,7 +92,7 @@ export interface ToolOptions {
|
|
|
90
92
|
outputSchema?: JsonSchema;
|
|
91
93
|
key: string;
|
|
92
94
|
}
|
|
93
|
-
export declare class Tool extends
|
|
95
|
+
export declare class Tool extends ZhanlaComponent {
|
|
94
96
|
readonly componentType: "tool";
|
|
95
97
|
readonly name: string;
|
|
96
98
|
readonly description: string;
|
|
@@ -104,15 +106,15 @@ export declare class Tool extends BaseComponent {
|
|
|
104
106
|
export interface CodeEvalOptions {
|
|
105
107
|
name: string;
|
|
106
108
|
description: string;
|
|
107
|
-
fn: (
|
|
109
|
+
fn: (modelResponse: ComponentValue, expectedResponse: ComponentValue | null) => unknown;
|
|
108
110
|
modelResponseFormat?: "JSON" | "TEXT" | "YAML";
|
|
109
111
|
key: string;
|
|
110
112
|
}
|
|
111
|
-
export declare class CodeEval extends
|
|
113
|
+
export declare class CodeEval extends ZhanlaComponent {
|
|
112
114
|
readonly componentType: "code_eval";
|
|
113
115
|
readonly name: string;
|
|
114
116
|
readonly description: string;
|
|
115
|
-
readonly fn: (
|
|
117
|
+
readonly fn: (modelResponse: ComponentValue, expectedResponse: ComponentValue | null) => unknown;
|
|
116
118
|
readonly isAsync: boolean;
|
|
117
119
|
readonly modelResponseFormat: "JSON" | "TEXT" | "YAML";
|
|
118
120
|
readonly key: string;
|
|
@@ -127,7 +129,7 @@ export interface SkillOptions {
|
|
|
127
129
|
outputSchema?: JsonSchema;
|
|
128
130
|
key: string;
|
|
129
131
|
}
|
|
130
|
-
export declare class Skill extends
|
|
132
|
+
export declare class Skill extends ZhanlaComponent {
|
|
131
133
|
readonly componentType: "skill";
|
|
132
134
|
readonly name: string;
|
|
133
135
|
readonly description: string;
|
|
@@ -144,6 +146,7 @@ export interface AgentOptions {
|
|
|
144
146
|
description: string;
|
|
145
147
|
instructions: string;
|
|
146
148
|
model: string;
|
|
149
|
+
client?: unknown;
|
|
147
150
|
runner?: Runner;
|
|
148
151
|
tools?: Tool[];
|
|
149
152
|
skills?: Skill[];
|
|
@@ -154,7 +157,7 @@ export interface AgentOptions {
|
|
|
154
157
|
topK?: number;
|
|
155
158
|
key: string;
|
|
156
159
|
}
|
|
157
|
-
export declare class Agent extends
|
|
160
|
+
export declare class Agent extends ZhanlaComponent {
|
|
158
161
|
readonly componentType: "agent";
|
|
159
162
|
readonly name: string;
|
|
160
163
|
readonly description: string;
|
|
@@ -176,6 +179,7 @@ export interface LLMProcessorOptions {
|
|
|
176
179
|
description: string;
|
|
177
180
|
instructions: string;
|
|
178
181
|
model: string;
|
|
182
|
+
client?: unknown;
|
|
179
183
|
runner?: Runner;
|
|
180
184
|
outputSchema?: JsonSchema;
|
|
181
185
|
jsonRepair?: boolean;
|
|
@@ -183,7 +187,7 @@ export interface LLMProcessorOptions {
|
|
|
183
187
|
topK?: number;
|
|
184
188
|
key: string;
|
|
185
189
|
}
|
|
186
|
-
export declare class LLMProcessor extends
|
|
190
|
+
export declare class LLMProcessor extends ZhanlaComponent {
|
|
187
191
|
readonly componentType: "llm_processor";
|
|
188
192
|
readonly name: string;
|
|
189
193
|
readonly description: string;
|
|
@@ -202,6 +206,7 @@ export interface LLMEvalOptions {
|
|
|
202
206
|
description: string;
|
|
203
207
|
instructions: string;
|
|
204
208
|
model: string;
|
|
209
|
+
client?: unknown;
|
|
205
210
|
runner?: Runner;
|
|
206
211
|
outputSchema?: JsonSchema;
|
|
207
212
|
jsonRepair?: boolean;
|
|
@@ -209,7 +214,7 @@ export interface LLMEvalOptions {
|
|
|
209
214
|
topK?: number;
|
|
210
215
|
key: string;
|
|
211
216
|
}
|
|
212
|
-
export declare class LLMEval extends
|
|
217
|
+
export declare class LLMEval extends ZhanlaComponent {
|
|
213
218
|
readonly componentType: "llm_eval";
|
|
214
219
|
readonly name: string;
|
|
215
220
|
readonly description: string;
|
|
@@ -236,12 +241,12 @@ export declare class Conditional {
|
|
|
236
241
|
}
|
|
237
242
|
export interface StepOptions {
|
|
238
243
|
name: string;
|
|
239
|
-
component:
|
|
244
|
+
component: ZhanlaComponent | Conditional;
|
|
240
245
|
next?: string[];
|
|
241
246
|
}
|
|
242
247
|
export declare class Step {
|
|
243
248
|
readonly name: string;
|
|
244
|
-
readonly component:
|
|
249
|
+
readonly component: ZhanlaComponent | Conditional;
|
|
245
250
|
readonly next: string[];
|
|
246
251
|
constructor(opts: StepOptions);
|
|
247
252
|
}
|
|
@@ -251,7 +256,7 @@ export interface OrchestrationOptions {
|
|
|
251
256
|
steps: Step[];
|
|
252
257
|
key: string;
|
|
253
258
|
}
|
|
254
|
-
export declare class Orchestration extends
|
|
259
|
+
export declare class Orchestration extends ZhanlaComponent {
|
|
255
260
|
readonly componentType: "orchestration";
|
|
256
261
|
readonly name: string;
|
|
257
262
|
readonly description: string;
|
|
@@ -260,9 +265,9 @@ export declare class Orchestration extends BaseComponent {
|
|
|
260
265
|
constructor(opts: OrchestrationOptions);
|
|
261
266
|
}
|
|
262
267
|
export declare class Leaf {
|
|
263
|
-
readonly eval:
|
|
268
|
+
readonly eval: ZhanlaComponent;
|
|
264
269
|
constructor(opts: {
|
|
265
|
-
eval:
|
|
270
|
+
eval: ZhanlaComponent;
|
|
266
271
|
});
|
|
267
272
|
}
|
|
268
273
|
export declare class Edge {
|
|
@@ -274,12 +279,12 @@ export declare class Edge {
|
|
|
274
279
|
});
|
|
275
280
|
}
|
|
276
281
|
export declare class Branch {
|
|
277
|
-
readonly eval:
|
|
282
|
+
readonly eval: ZhanlaComponent;
|
|
278
283
|
readonly threshold: number;
|
|
279
284
|
readonly ifPass: Edge[];
|
|
280
285
|
readonly ifFail: Edge[];
|
|
281
286
|
constructor(opts: {
|
|
282
|
-
eval:
|
|
287
|
+
eval: ZhanlaComponent;
|
|
283
288
|
threshold: number;
|
|
284
289
|
ifPass: Edge[];
|
|
285
290
|
ifFail: Edge[];
|
|
@@ -288,15 +293,15 @@ export declare class Branch {
|
|
|
288
293
|
export interface ChecklistOptions {
|
|
289
294
|
name: string;
|
|
290
295
|
description: string;
|
|
291
|
-
evals:
|
|
296
|
+
evals: ZhanlaComponent[];
|
|
292
297
|
weights?: number[];
|
|
293
298
|
key: string;
|
|
294
299
|
}
|
|
295
|
-
export declare class Checklist extends
|
|
300
|
+
export declare class Checklist extends ZhanlaComponent {
|
|
296
301
|
readonly componentType: "checklist";
|
|
297
302
|
readonly name: string;
|
|
298
303
|
readonly description: string;
|
|
299
|
-
readonly evals:
|
|
304
|
+
readonly evals: ZhanlaComponent[];
|
|
300
305
|
readonly weights?: number[];
|
|
301
306
|
readonly key: string;
|
|
302
307
|
constructor(opts: ChecklistOptions);
|
|
@@ -307,7 +312,7 @@ export interface EvalTreeOptions {
|
|
|
307
312
|
root: Branch;
|
|
308
313
|
key: string;
|
|
309
314
|
}
|
|
310
|
-
export declare class EvalTree extends
|
|
315
|
+
export declare class EvalTree extends ZhanlaComponent {
|
|
311
316
|
readonly componentType: "eval_tree";
|
|
312
317
|
readonly name: string;
|
|
313
318
|
readonly description: string;
|
package/dist/types.js
CHANGED
|
@@ -263,7 +263,22 @@ export class Runner {
|
|
|
263
263
|
}
|
|
264
264
|
}
|
|
265
265
|
}
|
|
266
|
+
warnModelProviderMismatch(model) {
|
|
267
|
+
const provider = this.providerName();
|
|
268
|
+
let expected;
|
|
269
|
+
if (model.startsWith("claude-"))
|
|
270
|
+
expected = "anthropic";
|
|
271
|
+
else if (model.startsWith("gemini-"))
|
|
272
|
+
expected = "gemini";
|
|
273
|
+
else if (/^(gpt-|o1-|o3-|o4-)/.test(model))
|
|
274
|
+
expected = "openai";
|
|
275
|
+
if (expected !== undefined && provider !== expected) {
|
|
276
|
+
console.warn(`[zhanla] Model '${model}' looks like an ${expected} model but the runner client is ${provider}. ` +
|
|
277
|
+
"Check that your client matches your model.");
|
|
278
|
+
}
|
|
279
|
+
}
|
|
266
280
|
async callLlm(opts) {
|
|
281
|
+
this.warnModelProviderMismatch(opts.model);
|
|
267
282
|
if (isAnthropicClient(this.client)) {
|
|
268
283
|
const systemMessage = opts.messages.find((message) => message.role === "system")?.content ?? "";
|
|
269
284
|
const chatMessages = opts.messages
|
|
@@ -426,7 +441,7 @@ export class Runner {
|
|
|
426
441
|
// ---------------------------------------------------------------------------
|
|
427
442
|
// Base component class
|
|
428
443
|
// ---------------------------------------------------------------------------
|
|
429
|
-
export class
|
|
444
|
+
export class ZhanlaComponent {
|
|
430
445
|
get isRunnable() {
|
|
431
446
|
return RUNNABLE_TYPES.has(this.componentType);
|
|
432
447
|
}
|
|
@@ -434,7 +449,7 @@ export class BaseComponent {
|
|
|
434
449
|
return EVAL_TYPES.has(this.componentType);
|
|
435
450
|
}
|
|
436
451
|
}
|
|
437
|
-
export class Tool extends
|
|
452
|
+
export class Tool extends ZhanlaComponent {
|
|
438
453
|
componentType = "tool";
|
|
439
454
|
name;
|
|
440
455
|
description;
|
|
@@ -455,7 +470,7 @@ export class Tool extends BaseComponent {
|
|
|
455
470
|
this.key = opts.key;
|
|
456
471
|
}
|
|
457
472
|
}
|
|
458
|
-
export class CodeEval extends
|
|
473
|
+
export class CodeEval extends ZhanlaComponent {
|
|
459
474
|
componentType = "code_eval";
|
|
460
475
|
name;
|
|
461
476
|
description;
|
|
@@ -474,7 +489,7 @@ export class CodeEval extends BaseComponent {
|
|
|
474
489
|
this.key = opts.key;
|
|
475
490
|
}
|
|
476
491
|
}
|
|
477
|
-
export class Skill extends
|
|
492
|
+
export class Skill extends ZhanlaComponent {
|
|
478
493
|
componentType = "skill";
|
|
479
494
|
name;
|
|
480
495
|
description;
|
|
@@ -497,7 +512,7 @@ export class Skill extends BaseComponent {
|
|
|
497
512
|
this.key = opts.key;
|
|
498
513
|
}
|
|
499
514
|
}
|
|
500
|
-
export class Agent extends
|
|
515
|
+
export class Agent extends ZhanlaComponent {
|
|
501
516
|
componentType = "agent";
|
|
502
517
|
name;
|
|
503
518
|
description;
|
|
@@ -514,11 +529,14 @@ export class Agent extends BaseComponent {
|
|
|
514
529
|
key;
|
|
515
530
|
constructor(opts) {
|
|
516
531
|
super();
|
|
532
|
+
if (opts.client !== undefined && opts.runner !== undefined) {
|
|
533
|
+
throw new Error("Specify client or runner, not both.");
|
|
534
|
+
}
|
|
517
535
|
this.name = opts.name;
|
|
518
536
|
this.description = opts.description;
|
|
519
537
|
this.instructions = opts.instructions;
|
|
520
538
|
this.model = opts.model;
|
|
521
|
-
this.runner = opts.runner;
|
|
539
|
+
this.runner = opts.client !== undefined ? new Runner({ client: opts.client }) : opts.runner;
|
|
522
540
|
this.tools = opts.tools ?? [];
|
|
523
541
|
this.skills = opts.skills ?? [];
|
|
524
542
|
this.agents = opts.agents ?? [];
|
|
@@ -530,7 +548,7 @@ export class Agent extends BaseComponent {
|
|
|
530
548
|
this.key = opts.key;
|
|
531
549
|
}
|
|
532
550
|
}
|
|
533
|
-
export class LLMProcessor extends
|
|
551
|
+
export class LLMProcessor extends ZhanlaComponent {
|
|
534
552
|
componentType = "llm_processor";
|
|
535
553
|
name;
|
|
536
554
|
description;
|
|
@@ -544,11 +562,14 @@ export class LLMProcessor extends BaseComponent {
|
|
|
544
562
|
key;
|
|
545
563
|
constructor(opts) {
|
|
546
564
|
super();
|
|
565
|
+
if (opts.client !== undefined && opts.runner !== undefined) {
|
|
566
|
+
throw new Error("Specify client or runner, not both.");
|
|
567
|
+
}
|
|
547
568
|
this.name = opts.name;
|
|
548
569
|
this.description = opts.description;
|
|
549
570
|
this.instructions = opts.instructions;
|
|
550
571
|
this.model = opts.model;
|
|
551
|
-
this.runner = opts.runner;
|
|
572
|
+
this.runner = opts.client !== undefined ? new Runner({ client: opts.client }) : opts.runner;
|
|
552
573
|
this.outputSchema = opts.outputSchema;
|
|
553
574
|
this.jsonRepair = opts.jsonRepair ?? false;
|
|
554
575
|
this.temperature = opts.temperature;
|
|
@@ -557,7 +578,7 @@ export class LLMProcessor extends BaseComponent {
|
|
|
557
578
|
this.key = opts.key;
|
|
558
579
|
}
|
|
559
580
|
}
|
|
560
|
-
export class LLMEval extends
|
|
581
|
+
export class LLMEval extends ZhanlaComponent {
|
|
561
582
|
componentType = "llm_eval";
|
|
562
583
|
name;
|
|
563
584
|
description;
|
|
@@ -571,11 +592,14 @@ export class LLMEval extends BaseComponent {
|
|
|
571
592
|
key;
|
|
572
593
|
constructor(opts) {
|
|
573
594
|
super();
|
|
595
|
+
if (opts.client !== undefined && opts.runner !== undefined) {
|
|
596
|
+
throw new Error("Specify client or runner, not both.");
|
|
597
|
+
}
|
|
574
598
|
this.name = opts.name;
|
|
575
599
|
this.description = opts.description;
|
|
576
600
|
this.instructions = opts.instructions;
|
|
577
601
|
this.model = opts.model;
|
|
578
|
-
this.runner = opts.runner;
|
|
602
|
+
this.runner = opts.client !== undefined ? new Runner({ client: opts.client }) : opts.runner;
|
|
579
603
|
this.outputSchema = opts.outputSchema;
|
|
580
604
|
this.jsonRepair = opts.jsonRepair ?? false;
|
|
581
605
|
this.temperature = opts.temperature;
|
|
@@ -604,7 +628,7 @@ export class Step {
|
|
|
604
628
|
this.next = opts.next ?? [];
|
|
605
629
|
}
|
|
606
630
|
}
|
|
607
|
-
export class Orchestration extends
|
|
631
|
+
export class Orchestration extends ZhanlaComponent {
|
|
608
632
|
componentType = "orchestration";
|
|
609
633
|
name;
|
|
610
634
|
description;
|
|
@@ -648,7 +672,7 @@ export class Branch {
|
|
|
648
672
|
this.ifFail = opts.ifFail;
|
|
649
673
|
}
|
|
650
674
|
}
|
|
651
|
-
export class Checklist extends
|
|
675
|
+
export class Checklist extends ZhanlaComponent {
|
|
652
676
|
componentType = "checklist";
|
|
653
677
|
name;
|
|
654
678
|
description;
|
|
@@ -665,7 +689,7 @@ export class Checklist extends BaseComponent {
|
|
|
665
689
|
this.key = opts.key;
|
|
666
690
|
}
|
|
667
691
|
}
|
|
668
|
-
export class EvalTree extends
|
|
692
|
+
export class EvalTree extends ZhanlaComponent {
|
|
669
693
|
componentType = "eval_tree";
|
|
670
694
|
name;
|
|
671
695
|
description;
|
package/package.json
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhanla/sdk-ts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "TypeScript SDK for the zhanla CLI — define and run AI components locally",
|
|
5
|
+
"homepage": "https://benchmark-black.vercel.app/",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/zhanla-ai"
|
|
9
|
+
},
|
|
5
10
|
"main": "dist/index.js",
|
|
6
11
|
"types": "dist/index.d.ts",
|
|
7
12
|
"type": "module",
|
|
8
13
|
"bin": {
|
|
9
|
-
"zhanla-sdk-ts": "
|
|
14
|
+
"zhanla-sdk-ts": "bin/cli.js"
|
|
10
15
|
},
|
|
11
16
|
"scripts": {
|
|
12
17
|
"build": "tsc",
|