@db-lyon/flowkit 0.10.0 → 0.11.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/README.md +37 -0
- package/dist/config/index.d.ts +2 -2
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +1 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/schema.d.ts +377 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +60 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/flow/runner.d.ts +14 -1
- package/dist/flow/runner.d.ts.map +1 -1
- package/dist/flow/runner.js +72 -2
- package/dist/flow/runner.js.map +1 -1
- package/dist/index.d.ts +10 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/task/agent-prompt-task.d.ts +26 -7
- package/dist/task/agent-prompt-task.d.ts.map +1 -1
- package/dist/task/agent-prompt-task.js +53 -19
- package/dist/task/agent-prompt-task.js.map +1 -1
- package/dist/task/agent-task.d.ts +98 -0
- package/dist/task/agent-task.d.ts.map +1 -0
- package/dist/task/agent-task.js +254 -0
- package/dist/task/agent-task.js.map +1 -0
- package/dist/task/base-task.d.ts +25 -0
- package/dist/task/base-task.d.ts.map +1 -1
- package/dist/task/base-task.js.map +1 -1
- package/dist/task/concurrency.d.ts +9 -0
- package/dist/task/concurrency.d.ts.map +1 -0
- package/dist/task/concurrency.js +24 -0
- package/dist/task/concurrency.js.map +1 -0
- package/dist/task/index.d.ts +11 -1
- package/dist/task/index.d.ts.map +1 -1
- package/dist/task/index.js +6 -0
- package/dist/task/index.js.map +1 -1
- package/dist/task/json-schema.d.ts +37 -0
- package/dist/task/json-schema.d.ts.map +1 -0
- package/dist/task/json-schema.js +223 -0
- package/dist/task/json-schema.js.map +1 -0
- package/dist/task/llm-provider.d.ts +81 -8
- package/dist/task/llm-provider.d.ts.map +1 -1
- package/dist/task/llm-provider.js +9 -3
- package/dist/task/llm-provider.js.map +1 -1
- package/dist/task/llm-runner.d.ts +72 -0
- package/dist/task/llm-runner.d.ts.map +1 -0
- package/dist/task/llm-runner.js +213 -0
- package/dist/task/llm-runner.js.map +1 -0
- package/dist/task/redact.d.ts +22 -0
- package/dist/task/redact.d.ts.map +1 -0
- package/dist/task/redact.js +47 -0
- package/dist/task/redact.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compact, dependency-free JSON Schema validator.
|
|
3
|
+
*
|
|
4
|
+
* Flowkit keeps its runtime dependencies to two (js-yaml, zod), so rather than
|
|
5
|
+
* pull in a full validator we implement the subset that LLM structured-output
|
|
6
|
+
* schemas actually use. The goal is not spec completeness — it is a precise,
|
|
7
|
+
* human-readable verdict that drives the structured-output repair loop in
|
|
8
|
+
* llm-runner (the error strings are fed back to the model).
|
|
9
|
+
*
|
|
10
|
+
* Supported keywords:
|
|
11
|
+
* type (single or array), enum, const,
|
|
12
|
+
* object: properties, required, additionalProperties (bool or schema),
|
|
13
|
+
* array: items, minItems, maxItems,
|
|
14
|
+
* string: minLength, maxLength, pattern,
|
|
15
|
+
* number: minimum, maximum, exclusiveMinimum, exclusiveMaximum,
|
|
16
|
+
* composition: anyOf, oneOf, allOf, not,
|
|
17
|
+
* nullable (OpenAPI-style — treated as "type may also be null").
|
|
18
|
+
*
|
|
19
|
+
* Anything unrecognized is ignored (treated as "no constraint"), so an
|
|
20
|
+
* over-rich schema validates leniently rather than throwing.
|
|
21
|
+
*/
|
|
22
|
+
const TYPE_OF = (v) => {
|
|
23
|
+
if (v === null)
|
|
24
|
+
return 'null';
|
|
25
|
+
if (Array.isArray(v))
|
|
26
|
+
return 'array';
|
|
27
|
+
return typeof v;
|
|
28
|
+
};
|
|
29
|
+
/** Does `value` satisfy the JSON Schema `type` token? Handles integer + null. */
|
|
30
|
+
function matchesType(value, type) {
|
|
31
|
+
switch (type) {
|
|
32
|
+
case 'integer':
|
|
33
|
+
return typeof value === 'number' && Number.isInteger(value);
|
|
34
|
+
case 'number':
|
|
35
|
+
return typeof value === 'number';
|
|
36
|
+
case 'string':
|
|
37
|
+
return typeof value === 'string';
|
|
38
|
+
case 'boolean':
|
|
39
|
+
return typeof value === 'boolean';
|
|
40
|
+
case 'object':
|
|
41
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
42
|
+
case 'array':
|
|
43
|
+
return Array.isArray(value);
|
|
44
|
+
case 'null':
|
|
45
|
+
return value === null;
|
|
46
|
+
default:
|
|
47
|
+
return true; // unknown type token — don't constrain
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function validateNode(value, schema, path, errors) {
|
|
51
|
+
// Composition keywords are evaluated independently of type.
|
|
52
|
+
if (Array.isArray(schema.allOf)) {
|
|
53
|
+
for (const sub of schema.allOf)
|
|
54
|
+
validateNode(value, sub, path, errors);
|
|
55
|
+
}
|
|
56
|
+
if (Array.isArray(schema.anyOf)) {
|
|
57
|
+
const ok = schema.anyOf.some((sub) => isolatedValid(value, sub, path));
|
|
58
|
+
if (!ok)
|
|
59
|
+
errors.push({ path, message: 'does not match any schema in anyOf' });
|
|
60
|
+
}
|
|
61
|
+
if (Array.isArray(schema.oneOf)) {
|
|
62
|
+
const matches = schema.oneOf.filter((sub) => isolatedValid(value, sub, path)).length;
|
|
63
|
+
if (matches !== 1) {
|
|
64
|
+
errors.push({ path, message: `must match exactly one schema in oneOf (matched ${matches})` });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (schema.not && typeof schema.not === 'object') {
|
|
68
|
+
if (isolatedValid(value, schema.not, path)) {
|
|
69
|
+
errors.push({ path, message: 'must not match the "not" schema' });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// const / enum
|
|
73
|
+
if ('const' in schema && !deepEqual(value, schema.const)) {
|
|
74
|
+
errors.push({ path, message: `must equal ${JSON.stringify(schema.const)}` });
|
|
75
|
+
}
|
|
76
|
+
if (Array.isArray(schema.enum) && !schema.enum.some((e) => deepEqual(e, value))) {
|
|
77
|
+
errors.push({ path, message: `must be one of ${JSON.stringify(schema.enum)}` });
|
|
78
|
+
}
|
|
79
|
+
// type (with OpenAPI-style nullable support)
|
|
80
|
+
const types = normalizeTypes(schema);
|
|
81
|
+
if (types && !(schema.nullable === true && value === null)) {
|
|
82
|
+
if (!types.some((t) => matchesType(value, t))) {
|
|
83
|
+
errors.push({
|
|
84
|
+
path,
|
|
85
|
+
message: `expected type ${types.join(' | ')} but got ${TYPE_OF(value)}`,
|
|
86
|
+
});
|
|
87
|
+
return; // further keyword checks assume the type matched
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (matchesType(value, 'object') && value !== null) {
|
|
91
|
+
validateObject(value, schema, path, errors);
|
|
92
|
+
}
|
|
93
|
+
else if (Array.isArray(value)) {
|
|
94
|
+
validateArray(value, schema, path, errors);
|
|
95
|
+
}
|
|
96
|
+
else if (typeof value === 'string') {
|
|
97
|
+
validateString(value, schema, path, errors);
|
|
98
|
+
}
|
|
99
|
+
else if (typeof value === 'number') {
|
|
100
|
+
validateNumber(value, schema, path, errors);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function validateObject(value, schema, path, errors) {
|
|
104
|
+
const properties = schema.properties ?? {};
|
|
105
|
+
if (Array.isArray(schema.required)) {
|
|
106
|
+
for (const key of schema.required) {
|
|
107
|
+
if (!(key in value))
|
|
108
|
+
errors.push({ path: join(path, key), message: 'is required' });
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
for (const [key, sub] of Object.entries(properties)) {
|
|
112
|
+
if (key in value)
|
|
113
|
+
validateNode(value[key], sub, join(path, key), errors);
|
|
114
|
+
}
|
|
115
|
+
const additional = schema.additionalProperties;
|
|
116
|
+
if (additional === false) {
|
|
117
|
+
for (const key of Object.keys(value)) {
|
|
118
|
+
if (!(key in properties)) {
|
|
119
|
+
errors.push({ path: join(path, key), message: 'is not an allowed property' });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
else if (additional && typeof additional === 'object') {
|
|
124
|
+
for (const key of Object.keys(value)) {
|
|
125
|
+
if (!(key in properties))
|
|
126
|
+
validateNode(value[key], additional, join(path, key), errors);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function validateArray(value, schema, path, errors) {
|
|
131
|
+
if (typeof schema.minItems === 'number' && value.length < schema.minItems) {
|
|
132
|
+
errors.push({ path, message: `must have at least ${schema.minItems} items` });
|
|
133
|
+
}
|
|
134
|
+
if (typeof schema.maxItems === 'number' && value.length > schema.maxItems) {
|
|
135
|
+
errors.push({ path, message: `must have at most ${schema.maxItems} items` });
|
|
136
|
+
}
|
|
137
|
+
if (schema.items && typeof schema.items === 'object' && !Array.isArray(schema.items)) {
|
|
138
|
+
value.forEach((item, i) => validateNode(item, schema.items, join(path, String(i)), errors));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function validateString(value, schema, path, errors) {
|
|
142
|
+
if (typeof schema.minLength === 'number' && value.length < schema.minLength) {
|
|
143
|
+
errors.push({ path, message: `must be at least ${schema.minLength} characters` });
|
|
144
|
+
}
|
|
145
|
+
if (typeof schema.maxLength === 'number' && value.length > schema.maxLength) {
|
|
146
|
+
errors.push({ path, message: `must be at most ${schema.maxLength} characters` });
|
|
147
|
+
}
|
|
148
|
+
if (typeof schema.pattern === 'string') {
|
|
149
|
+
let re = null;
|
|
150
|
+
try {
|
|
151
|
+
re = new RegExp(schema.pattern);
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
re = null; // invalid pattern in schema — skip rather than throw
|
|
155
|
+
}
|
|
156
|
+
if (re && !re.test(value))
|
|
157
|
+
errors.push({ path, message: `must match pattern ${schema.pattern}` });
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function validateNumber(value, schema, path, errors) {
|
|
161
|
+
if (typeof schema.minimum === 'number' && value < schema.minimum) {
|
|
162
|
+
errors.push({ path, message: `must be >= ${schema.minimum}` });
|
|
163
|
+
}
|
|
164
|
+
if (typeof schema.maximum === 'number' && value > schema.maximum) {
|
|
165
|
+
errors.push({ path, message: `must be <= ${schema.maximum}` });
|
|
166
|
+
}
|
|
167
|
+
if (typeof schema.exclusiveMinimum === 'number' && value <= schema.exclusiveMinimum) {
|
|
168
|
+
errors.push({ path, message: `must be > ${schema.exclusiveMinimum}` });
|
|
169
|
+
}
|
|
170
|
+
if (typeof schema.exclusiveMaximum === 'number' && value >= schema.exclusiveMaximum) {
|
|
171
|
+
errors.push({ path, message: `must be < ${schema.exclusiveMaximum}` });
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/** Validate against a sub-schema in isolation; used by anyOf/oneOf/not. */
|
|
175
|
+
function isolatedValid(value, schema, path) {
|
|
176
|
+
const sub = [];
|
|
177
|
+
validateNode(value, schema, path, sub);
|
|
178
|
+
return sub.length === 0;
|
|
179
|
+
}
|
|
180
|
+
function normalizeTypes(schema) {
|
|
181
|
+
const t = schema.type;
|
|
182
|
+
if (typeof t === 'string')
|
|
183
|
+
return [t];
|
|
184
|
+
if (Array.isArray(t) && t.every((x) => typeof x === 'string'))
|
|
185
|
+
return t;
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
function join(path, key) {
|
|
189
|
+
return `${path}/${key}`;
|
|
190
|
+
}
|
|
191
|
+
function deepEqual(a, b) {
|
|
192
|
+
if (a === b)
|
|
193
|
+
return true;
|
|
194
|
+
if (typeof a !== typeof b || a === null || b === null)
|
|
195
|
+
return false;
|
|
196
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
197
|
+
return a.length === b.length && a.every((v, i) => deepEqual(v, b[i]));
|
|
198
|
+
}
|
|
199
|
+
if (typeof a === 'object' && typeof b === 'object') {
|
|
200
|
+
const ka = Object.keys(a);
|
|
201
|
+
const kb = Object.keys(b);
|
|
202
|
+
if (ka.length !== kb.length)
|
|
203
|
+
return false;
|
|
204
|
+
return ka.every((k) => deepEqual(a[k], b[k]));
|
|
205
|
+
}
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
/** Validate a value against a JSON Schema. Always returns; never throws. */
|
|
209
|
+
export function validateJson(value, schema) {
|
|
210
|
+
const errors = [];
|
|
211
|
+
try {
|
|
212
|
+
validateNode(value, schema, '', errors);
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
errors.push({ path: '', message: `validator error: ${err.message}` });
|
|
216
|
+
}
|
|
217
|
+
return { valid: errors.length === 0, errors };
|
|
218
|
+
}
|
|
219
|
+
/** One-line, model-friendly summary of validation errors for the repair loop. */
|
|
220
|
+
export function formatErrors(errors) {
|
|
221
|
+
return errors.map((e) => `${e.path || '(root)'}: ${e.message}`).join('; ');
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=json-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schema.js","sourceRoot":"","sources":["../../src/task/json-schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,36 +1,109 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* LLM provider
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* LLM provider contract. Flowkit itself has no SDK dependencies — the consumer
|
|
3
|
+
* wires a concrete provider (Anthropic, OpenAI, local, a stub for tests) into
|
|
4
|
+
* the task context under the `llm` key. The provider's only job is to translate
|
|
5
|
+
* this neutral request/response shape to and from its own SDK, which keeps the
|
|
6
|
+
* engine model-agnostic.
|
|
7
|
+
*
|
|
8
|
+
* The contract is intentionally additive: a provider may ignore any field it
|
|
9
|
+
* does not support (`tools`, `schema`, `signal`, …) and a request that only
|
|
10
|
+
* sets `prompt` behaves exactly as it did before tool-calling existed.
|
|
5
11
|
*/
|
|
12
|
+
export type LLMRole = 'system' | 'user' | 'assistant' | 'tool';
|
|
13
|
+
/** A tool invocation the model asked for, surfaced on an assistant turn. */
|
|
14
|
+
export interface LLMToolCall {
|
|
15
|
+
/** Provider-assigned id, echoed back on the matching tool-result message. */
|
|
16
|
+
id: string;
|
|
17
|
+
/** Name of the tool the model wants to run. */
|
|
18
|
+
name: string;
|
|
19
|
+
/** Arguments the model produced, already parsed from JSON. */
|
|
20
|
+
arguments: Record<string, unknown>;
|
|
21
|
+
}
|
|
22
|
+
export interface LLMMessage {
|
|
23
|
+
role: LLMRole;
|
|
24
|
+
/** Text content. Empty string is valid (e.g. an assistant turn that is purely tool calls). */
|
|
25
|
+
content: string;
|
|
26
|
+
/** Present on assistant turns that request tools. */
|
|
27
|
+
toolCalls?: LLMToolCall[];
|
|
28
|
+
/** On a `tool` message: the id of the tool call this result answers. */
|
|
29
|
+
toolCallId?: string;
|
|
30
|
+
/** On a `tool` message: the tool's name (some providers key results by name). */
|
|
31
|
+
name?: string;
|
|
32
|
+
}
|
|
33
|
+
/** A tool the model is allowed to call, described to the provider. */
|
|
34
|
+
export interface LLMToolDefinition {
|
|
35
|
+
name: string;
|
|
36
|
+
description?: string;
|
|
37
|
+
/** JSON Schema for the tool's arguments. */
|
|
38
|
+
parameters: Record<string, unknown>;
|
|
39
|
+
}
|
|
40
|
+
/** How the model may use tools on a given turn. */
|
|
41
|
+
export type LLMToolChoice = 'auto' | 'none' | 'required' | {
|
|
42
|
+
name: string;
|
|
43
|
+
};
|
|
6
44
|
export interface LLMCompletionRequest {
|
|
7
45
|
/** System prompt / instructions. */
|
|
8
46
|
system?: string;
|
|
9
|
-
/**
|
|
10
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Convenience single user message. When `messages` is set it takes
|
|
49
|
+
* precedence and `prompt` is ignored.
|
|
50
|
+
*/
|
|
51
|
+
prompt?: string;
|
|
52
|
+
/** Full conversation. Overrides `prompt` when present. */
|
|
53
|
+
messages?: LLMMessage[];
|
|
11
54
|
/** Model identifier — provider-specific. */
|
|
12
55
|
model?: string;
|
|
13
56
|
/** Max output tokens. */
|
|
14
57
|
maxTokens?: number;
|
|
58
|
+
/** Sampling temperature, when the provider supports it. */
|
|
59
|
+
temperature?: number;
|
|
60
|
+
/** Stop sequences, when the provider supports them. */
|
|
61
|
+
stop?: string[];
|
|
15
62
|
/**
|
|
16
|
-
* Optional JSON Schema. When provided, the provider should attempt to
|
|
17
|
-
*
|
|
18
|
-
*
|
|
63
|
+
* Optional JSON Schema. When provided, the provider should attempt to return
|
|
64
|
+
* output that parses against the schema and populate `parsed`. Flowkit
|
|
65
|
+
* validates and repairs structured output on top of this (see llm-runner).
|
|
19
66
|
*/
|
|
20
67
|
schema?: Record<string, unknown>;
|
|
68
|
+
/** Tools the model may call this turn. */
|
|
69
|
+
tools?: LLMToolDefinition[];
|
|
70
|
+
/** Constrains tool use this turn. */
|
|
71
|
+
toolChoice?: LLMToolChoice;
|
|
72
|
+
/**
|
|
73
|
+
* Cancellation signal. Flowkit aborts this on timeout; well-behaved providers
|
|
74
|
+
* should pass it to their HTTP client so in-flight calls are cancelled.
|
|
75
|
+
*/
|
|
76
|
+
signal?: AbortSignal;
|
|
21
77
|
}
|
|
22
78
|
export interface LLMCompletionResponse {
|
|
23
79
|
/** Raw text returned by the model. */
|
|
24
80
|
text: string;
|
|
25
81
|
/** When a schema was provided and the output parsed, the structured value. */
|
|
26
82
|
parsed?: unknown;
|
|
83
|
+
/** Tool calls the model requested, if any. */
|
|
84
|
+
toolCalls?: LLMToolCall[];
|
|
85
|
+
/**
|
|
86
|
+
* Why the model stopped: `'stop'` (natural end), `'tool_use'` (wants tools),
|
|
87
|
+
* `'length'` (hit token cap), or any provider-specific string. Absent is
|
|
88
|
+
* treated as a natural stop.
|
|
89
|
+
*/
|
|
90
|
+
finishReason?: 'stop' | 'tool_use' | 'length' | (string & {});
|
|
27
91
|
/** Token usage, if the provider reports it. */
|
|
28
92
|
usage?: {
|
|
29
93
|
inputTokens?: number;
|
|
30
94
|
outputTokens?: number;
|
|
31
95
|
};
|
|
96
|
+
/** The model that actually served the request, if the provider reports it. */
|
|
97
|
+
model?: string;
|
|
32
98
|
}
|
|
33
99
|
export interface LLMProvider {
|
|
34
100
|
complete(req: LLMCompletionRequest): Promise<LLMCompletionResponse>;
|
|
35
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* A programmatic agent tool: a host-supplied function the model can call.
|
|
104
|
+
* Registered on the task context under `agentTools`, keyed by tool name, for
|
|
105
|
+
* tools that are not flowkit tasks. Receives the model's parsed arguments and
|
|
106
|
+
* returns any JSON-serializable result.
|
|
107
|
+
*/
|
|
108
|
+
export type LLMToolHandler = (args: Record<string, unknown>) => unknown | Promise<unknown>;
|
|
36
109
|
//# sourceMappingURL=llm-provider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm-provider.d.ts","sourceRoot":"","sources":["../../src/task/llm-provider.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"llm-provider.d.ts","sourceRoot":"","sources":["../../src/task/llm-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;AAE/D,4EAA4E;AAC5E,MAAM,WAAW,WAAW;IAC1B,6EAA6E;IAC7E,EAAE,EAAE,MAAM,CAAC;IACX,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,8FAA8F;IAC9F,OAAO,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC;IAC1B,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,sEAAsE;AACtE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,mDAAmD;AACnD,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5E,MAAM,WAAW,oBAAoB;IACnC,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;IACxB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,0CAA0C;IAC1C,KAAK,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC5B,qCAAqC;IACrC,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B;;;OAGG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC;IAC1B;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,QAAQ,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IAC9D,+CAA+C;IAC/C,KAAK,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACxD,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;CACrE;AAED;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,CAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC1B,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC"}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* LLM provider
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* LLM provider contract. Flowkit itself has no SDK dependencies — the consumer
|
|
3
|
+
* wires a concrete provider (Anthropic, OpenAI, local, a stub for tests) into
|
|
4
|
+
* the task context under the `llm` key. The provider's only job is to translate
|
|
5
|
+
* this neutral request/response shape to and from its own SDK, which keeps the
|
|
6
|
+
* engine model-agnostic.
|
|
7
|
+
*
|
|
8
|
+
* The contract is intentionally additive: a provider may ignore any field it
|
|
9
|
+
* does not support (`tools`, `schema`, `signal`, …) and a request that only
|
|
10
|
+
* sets `prompt` behaves exactly as it did before tool-calling existed.
|
|
5
11
|
*/
|
|
6
12
|
export {};
|
|
7
13
|
//# sourceMappingURL=llm-provider.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm-provider.js","sourceRoot":"","sources":["../../src/task/llm-provider.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"llm-provider.js","sourceRoot":"","sources":["../../src/task/llm-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single place every LLM call goes through.
|
|
3
|
+
*
|
|
4
|
+
* `runCompletion` wraps a raw provider with the cross-cutting concerns that make
|
|
5
|
+
* model calls production-safe — and does so once, so both the single-shot
|
|
6
|
+
* `AgentPromptTask` and the agentic `AgentTask` inherit identical behavior:
|
|
7
|
+
*
|
|
8
|
+
* - timeout + abort — bound every call; abort the provider's in-flight request
|
|
9
|
+
* - retry + backoff — exponential backoff on transient transport failures
|
|
10
|
+
* - structured output — validate against the requested JSON Schema and, on a
|
|
11
|
+
* mismatch, re-prompt the model with the concrete errors
|
|
12
|
+
* (the "repair loop") before giving up
|
|
13
|
+
* - output cap — bound response text so a runaway generation can't blow
|
|
14
|
+
* up memory or downstream logs
|
|
15
|
+
*/
|
|
16
|
+
import type { Logger } from '../logger.js';
|
|
17
|
+
import type { LLMProvider, LLMCompletionRequest, LLMCompletionResponse } from './llm-provider.js';
|
|
18
|
+
export interface LLMRunOptions {
|
|
19
|
+
/** Per-call timeout in ms. Default 60000. `0` disables the timeout. */
|
|
20
|
+
timeout?: number;
|
|
21
|
+
/** Transport retries (in addition to the first attempt). Default 2. */
|
|
22
|
+
retries?: number;
|
|
23
|
+
/** Base backoff in ms; doubles each retry. Default 500. */
|
|
24
|
+
retryDelay?: number;
|
|
25
|
+
/** Decide whether a given error is retryable. Default: retry everything. */
|
|
26
|
+
retryOn?: (err: Error) => boolean;
|
|
27
|
+
/** Structured-output repair re-prompts before failing. Default 1. */
|
|
28
|
+
repairAttempts?: number;
|
|
29
|
+
/** Cap on response text length. Default 0 (unlimited). */
|
|
30
|
+
maxOutputChars?: number;
|
|
31
|
+
}
|
|
32
|
+
/** Response plus runner-added metadata. */
|
|
33
|
+
export type LLMRunResult = LLMCompletionResponse & {
|
|
34
|
+
/** True when `maxOutputChars` clipped the text. */
|
|
35
|
+
truncated?: boolean;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* The subset of `LLMRunOptions` that is plain data, so it can be declared in
|
|
39
|
+
* YAML task options. `retryOn` is excluded because it is a function. Both agent
|
|
40
|
+
* tasks mix these into their option shape; `pickRunOptions` extracts them.
|
|
41
|
+
*/
|
|
42
|
+
export interface AgentRunFields {
|
|
43
|
+
timeout?: number;
|
|
44
|
+
retries?: number;
|
|
45
|
+
retryDelay?: number;
|
|
46
|
+
repairAttempts?: number;
|
|
47
|
+
maxOutputChars?: number;
|
|
48
|
+
}
|
|
49
|
+
/** Lift the run-control fields out of a task's options into `LLMRunOptions`. */
|
|
50
|
+
export declare function pickRunOptions(o: AgentRunFields): LLMRunOptions;
|
|
51
|
+
/** A provider call exceeded its timeout. */
|
|
52
|
+
export declare class LLMTimeoutError extends Error {
|
|
53
|
+
constructor(message: string);
|
|
54
|
+
}
|
|
55
|
+
/** Structured output never satisfied the schema, even after repair attempts. */
|
|
56
|
+
export declare class StructuredOutputError extends Error {
|
|
57
|
+
readonly rawText: string;
|
|
58
|
+
readonly validationErrors: string;
|
|
59
|
+
constructor(message: string, rawText: string, validationErrors: string);
|
|
60
|
+
}
|
|
61
|
+
export declare function runCompletion(provider: LLMProvider, request: LLMCompletionRequest, options?: LLMRunOptions, logger?: Logger): Promise<LLMRunResult>;
|
|
62
|
+
/**
|
|
63
|
+
* Coerce a response into a schema-conforming value: prefer the provider's
|
|
64
|
+
* `parsed`, else parse JSON out of the text. Returns `{ parsed }` when valid or
|
|
65
|
+
* `{ errors }` describing the mismatch. Exported so callers (e.g. the agent
|
|
66
|
+
* loop) can check conformance without forcing an extra model call.
|
|
67
|
+
*/
|
|
68
|
+
export declare function coerceStructured(resp: LLMCompletionResponse, schema: Record<string, unknown>): {
|
|
69
|
+
parsed?: unknown;
|
|
70
|
+
errors?: string;
|
|
71
|
+
};
|
|
72
|
+
//# sourceMappingURL=llm-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-runner.d.ts","sourceRoot":"","sources":["../../src/task/llm-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,EACV,WAAW,EACX,oBAAoB,EACpB,qBAAqB,EAEtB,MAAM,mBAAmB,CAAC;AAG3B,MAAM,WAAW,aAAa;IAC5B,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,OAAO,CAAC;IAClC,qEAAqE;IACrE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0DAA0D;IAC1D,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,2CAA2C;AAC3C,MAAM,MAAM,YAAY,GAAG,qBAAqB,GAAG;IACjD,mDAAmD;IACnD,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,CAAC,EAAE,cAAc,GAAG,aAAa,CAQ/D;AAED,4CAA4C;AAC5C,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,EAAE,MAAM;CAI5B;AAED,gFAAgF;AAChF,qBAAa,qBAAsB,SAAQ,KAAK;IAG5C,QAAQ,CAAC,OAAO,EAAE,MAAM;IACxB,QAAQ,CAAC,gBAAgB,EAAE,MAAM;gBAFjC,OAAO,EAAE,MAAM,EACN,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM;CAKpC;AAED,wBAAsB,aAAa,CACjC,QAAQ,EAAE,WAAW,EACrB,OAAO,EAAE,oBAAoB,EAC7B,OAAO,GAAE,aAAkB,EAC3B,MAAM,GAAE,MAAmB,GAC1B,OAAO,CAAC,YAAY,CAAC,CAuDvB;AA6ED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,qBAAqB,EAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAUvC"}
|