@flue/sdk 0.3.11 → 0.4.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 +14 -23
- package/dist/abort-Bg3qsAkU.mjs +43 -0
- package/dist/app.d.mts +106 -0
- package/dist/app.mjs +4 -0
- package/dist/client.d.mts +9 -3
- package/dist/client.mjs +10 -24
- package/dist/cloudflare/index.d.mts +10 -6
- package/dist/cloudflare/index.mjs +388 -26
- package/dist/cloudflare-model-BeiZ1pLz.d.mts +6 -0
- package/dist/config.d.mts +133 -0
- package/dist/config.mjs +195 -0
- package/dist/flue-app-CG8i4wNG.d.mts +184 -0
- package/dist/flue-app-DeTOZjPs.mjs +730 -0
- package/dist/index.d.mts +41 -19
- package/dist/index.mjs +434 -594
- package/dist/internal.d.mts +9 -272
- package/dist/internal.mjs +16 -430
- package/dist/{mcp-DmDTeVXW.mjs → mcp-2SW_tpox.mjs} +19 -33
- package/dist/{mcp-CcRxAwXW.d.mts → mcp-C3UBXVkR.d.mts} +1 -1
- package/dist/node/index.d.mts +8 -12
- package/dist/node/index.mjs +94 -64
- package/dist/providers-DeFRIwp0.mjs +158 -0
- package/dist/result-K1IRhWKM.mjs +685 -0
- package/dist/sandbox.d.mts +25 -4
- package/dist/sandbox.mjs +44 -62
- package/dist/{session-DlwIt7wq.mjs → session-CO_uGVOk.mjs} +485 -263
- package/dist/types-BAmV4f3Q.d.mts +727 -0
- package/package.json +12 -1
- package/dist/agent-Cahthgu3.mjs +0 -453
- package/dist/command-helpers-eVG1-Iru.d.mts +0 -21
- package/dist/command-helpers-hTZKWK13.mjs +0 -37
- package/dist/types-DGpyKMFm.d.mts +0 -508
|
@@ -0,0 +1,727 @@
|
|
|
1
|
+
import { ImageContent, Model, TSchema } from "@mariozechner/pi-ai";
|
|
2
|
+
import * as v from "valibot";
|
|
3
|
+
import { AgentMessage, ThinkingLevel } from "@mariozechner/pi-agent-core";
|
|
4
|
+
|
|
5
|
+
//#region src/types.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Inline image content attached to a `prompt()`, `skill()`, or `task()` call.
|
|
8
|
+
* Re-exports pi-ai's `ImageContent` shape: `{ type: 'image', data: base64, mimeType }`.
|
|
9
|
+
* The selected model must support vision input.
|
|
10
|
+
*/
|
|
11
|
+
type PromptImage = ImageContent;
|
|
12
|
+
/**
|
|
13
|
+
* A skill registered with the session. The body of the skill (everything
|
|
14
|
+
* below the frontmatter in `SKILL.md`) is intentionally NOT cached in
|
|
15
|
+
* memory — at call time, the model reads the file from disk via its
|
|
16
|
+
* filesystem tools. That keeps relative references inside the skill
|
|
17
|
+
* resolvable from where they live, and lets users edit skill files
|
|
18
|
+
* mid-session without re-initialising the agent.
|
|
19
|
+
*/
|
|
20
|
+
interface Skill {
|
|
21
|
+
name: string;
|
|
22
|
+
description: string;
|
|
23
|
+
}
|
|
24
|
+
interface Role {
|
|
25
|
+
name: string;
|
|
26
|
+
description: string;
|
|
27
|
+
/** Markdown body of the role file (below the frontmatter). */
|
|
28
|
+
instructions: string;
|
|
29
|
+
model?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Reasoning effort to apply to model calls performed under this role. Forwarded
|
|
32
|
+
* to pi-ai's `SimpleStreamOptions.reasoning`. Models without reasoning support
|
|
33
|
+
* silently ignore it. Pi-ai clamps the requested level against
|
|
34
|
+
* `Model.thinkingLevelMap` per provider. Use `"off"` to explicitly disable.
|
|
35
|
+
*/
|
|
36
|
+
thinkingLevel?: ThinkingLevel;
|
|
37
|
+
}
|
|
38
|
+
type ToolParameters = TSchema | Record<string, unknown>;
|
|
39
|
+
/**
|
|
40
|
+
* Custom tool passed to init(), prompt(), skill(), or task(). init() tools are
|
|
41
|
+
* available to every session call; prompt/skill/task tools are scoped to that call.
|
|
42
|
+
* Parameters are JSON Schema-compatible. Use `Type` from `@flue/sdk/client` for
|
|
43
|
+
* hand-written tools, or pass schemas discovered from adapters such as MCP.
|
|
44
|
+
*/
|
|
45
|
+
interface ToolDef<TParams extends ToolParameters = ToolParameters> {
|
|
46
|
+
/** Must be unique across built-in and custom tools. */
|
|
47
|
+
name: string;
|
|
48
|
+
/** Tells the LLM when and how to use this tool. */
|
|
49
|
+
description: string;
|
|
50
|
+
/** JSON Schema-compatible parameter schema. */
|
|
51
|
+
parameters: TParams;
|
|
52
|
+
/** Returns a string result sent back to the LLM. Thrown errors become tool errors. */
|
|
53
|
+
execute: (args: Record<string, any>, signal?: AbortSignal) => Promise<string>;
|
|
54
|
+
}
|
|
55
|
+
interface FileStat {
|
|
56
|
+
isFile: boolean;
|
|
57
|
+
isDirectory: boolean;
|
|
58
|
+
isSymbolicLink: boolean;
|
|
59
|
+
size: number;
|
|
60
|
+
mtime: Date;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Universal session environment interface. All sandbox modes (isolate, local, remote)
|
|
64
|
+
* implement this — no mode-specific branching needed in core logic.
|
|
65
|
+
*
|
|
66
|
+
* File methods accept both absolute and relative paths (resolved against `cwd`).
|
|
67
|
+
*/
|
|
68
|
+
interface SessionEnv {
|
|
69
|
+
exec(command: string, options?: {
|
|
70
|
+
cwd?: string;
|
|
71
|
+
env?: Record<string, string>;
|
|
72
|
+
/**
|
|
73
|
+
* Wall-clock deadline hint in seconds. Forwarded to the underlying
|
|
74
|
+
* sandbox connector's native timeout option (E2B `timeoutMs`,
|
|
75
|
+
* Daytona `timeout`, etc.) so signal-blind providers still observe
|
|
76
|
+
* the deadline with full fidelity.
|
|
77
|
+
*
|
|
78
|
+
* Independent of `signal`. Callers that have a deadline AND want
|
|
79
|
+
* mid-flight cancellation should pass both: `timeout` for
|
|
80
|
+
* provider-native enforcement, `signal` for ad-hoc abort. The
|
|
81
|
+
* bash tool does this when the model emits a `timeout` parameter.
|
|
82
|
+
*/
|
|
83
|
+
timeout?: number;
|
|
84
|
+
/**
|
|
85
|
+
* Cancel the in-flight command. Aborting rejects with an
|
|
86
|
+
* `AbortError`. Connectors that wrap a signal-aware SDK observe
|
|
87
|
+
* this mid-flight; others see it only before/after the remote
|
|
88
|
+
* call returns. Use `timeout` for guaranteed deadline enforcement
|
|
89
|
+
* on signal-blind connectors.
|
|
90
|
+
*/
|
|
91
|
+
signal?: AbortSignal;
|
|
92
|
+
}): Promise<ShellResult>;
|
|
93
|
+
readFile(path: string): Promise<string>;
|
|
94
|
+
readFileBuffer(path: string): Promise<Uint8Array>;
|
|
95
|
+
writeFile(path: string, content: string | Uint8Array): Promise<void>;
|
|
96
|
+
stat(path: string): Promise<FileStat>;
|
|
97
|
+
readdir(path: string): Promise<string[]>;
|
|
98
|
+
exists(path: string): Promise<boolean>;
|
|
99
|
+
mkdir(path: string, options?: {
|
|
100
|
+
recursive?: boolean;
|
|
101
|
+
}): Promise<void>;
|
|
102
|
+
rm(path: string, options?: {
|
|
103
|
+
recursive?: boolean;
|
|
104
|
+
force?: boolean;
|
|
105
|
+
}): Promise<void>;
|
|
106
|
+
cwd: string;
|
|
107
|
+
/**
|
|
108
|
+
* Resolve a relative path against cwd. Absolute paths pass through.
|
|
109
|
+
* File methods resolve internally — only needed when you need the absolute path
|
|
110
|
+
* for your own logic (e.g., extracting the parent directory).
|
|
111
|
+
*/
|
|
112
|
+
resolvePath(p: string): string;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Filesystem surface for the agent sandbox, exposed on `FlueAgent.fs` and
|
|
116
|
+
* `FlueSession.fs`. Reads and writes happen inside whatever the sandbox
|
|
117
|
+
* connector points at (a remote container, microVM, in-process FS, etc.).
|
|
118
|
+
*
|
|
119
|
+
* Operations are out-of-band — they don't appear in the conversation
|
|
120
|
+
* transcript. The model has its own `read`/`write`/`edit` tools for
|
|
121
|
+
* filesystem work it should reason about. Use `fs` for plumbing (staging
|
|
122
|
+
* files, capturing artifacts, managing scratch space) the model shouldn't
|
|
123
|
+
* see. If a write should feed into the model's next turn, prompt the model
|
|
124
|
+
* to read the file itself.
|
|
125
|
+
*
|
|
126
|
+
* Paths can be absolute or relative. Relative paths are resolved against
|
|
127
|
+
* the agent's cwd, which comes from `init({ cwd })` if set, otherwise from
|
|
128
|
+
* the sandbox connector's default (varies by provider). Use absolute paths
|
|
129
|
+
* for portability across connectors.
|
|
130
|
+
*/
|
|
131
|
+
interface FlueFs {
|
|
132
|
+
/** Read a UTF-8 file. Throws if the path doesn't exist or isn't a file. */
|
|
133
|
+
readFile(path: string): Promise<string>;
|
|
134
|
+
/** Read a file as raw bytes. Use this for binary content. */
|
|
135
|
+
readFileBuffer(path: string): Promise<Uint8Array>;
|
|
136
|
+
/**
|
|
137
|
+
* Write content to a file. Creates the file if it doesn't exist; replaces
|
|
138
|
+
* it if it does. Accepts both UTF-8 strings and raw bytes.
|
|
139
|
+
*/
|
|
140
|
+
writeFile(path: string, content: string | Uint8Array): Promise<void>;
|
|
141
|
+
/** Get file metadata (size, mtime, type). Throws if the path doesn't exist. */
|
|
142
|
+
stat(path: string): Promise<FileStat>;
|
|
143
|
+
/** List directory entries (names only, no paths). Throws if not a directory. */
|
|
144
|
+
readdir(path: string): Promise<string[]>;
|
|
145
|
+
/** True if a file or directory exists at `path`. Never throws. */
|
|
146
|
+
exists(path: string): Promise<boolean>;
|
|
147
|
+
/**
|
|
148
|
+
* Create a directory. Pass `{ recursive: true }` to create parent
|
|
149
|
+
* directories as needed (mkdir -p semantics).
|
|
150
|
+
*/
|
|
151
|
+
mkdir(path: string, options?: {
|
|
152
|
+
recursive?: boolean;
|
|
153
|
+
}): Promise<void>;
|
|
154
|
+
/**
|
|
155
|
+
* Remove a file or directory. Pass `{ recursive: true }` to remove
|
|
156
|
+
* directory trees, `{ force: true }` to suppress missing-path errors.
|
|
157
|
+
*/
|
|
158
|
+
rm(path: string, options?: {
|
|
159
|
+
recursive?: boolean;
|
|
160
|
+
force?: boolean;
|
|
161
|
+
}): Promise<void>;
|
|
162
|
+
}
|
|
163
|
+
interface CompactionConfig {
|
|
164
|
+
enabled?: boolean;
|
|
165
|
+
/** Token buffer to keep free in the context window. Default: 16384 */
|
|
166
|
+
reserveTokens?: number;
|
|
167
|
+
/** Recent tokens to preserve (not summarized). Default: 20000 */
|
|
168
|
+
keepRecentTokens?: number;
|
|
169
|
+
}
|
|
170
|
+
/** Per-provider transport settings configured from `@flue/sdk/app`. */
|
|
171
|
+
interface ProviderSettings {
|
|
172
|
+
/** Provider endpoint used by built-in models or registered providers. */
|
|
173
|
+
baseUrl?: string;
|
|
174
|
+
/** Headers merged into the resolved model's provider-level headers. */
|
|
175
|
+
headers?: Record<string, string>;
|
|
176
|
+
/** API key returned to the underlying agent runtime for this provider. */
|
|
177
|
+
apiKey?: string;
|
|
178
|
+
/**
|
|
179
|
+
* Sends `store: true` for OpenAI Responses API providers. Only enable when
|
|
180
|
+
* you need OpenAI-hosted item persistence and accept its retention policy.
|
|
181
|
+
*/
|
|
182
|
+
storeResponses?: boolean;
|
|
183
|
+
}
|
|
184
|
+
interface AgentConfig {
|
|
185
|
+
/** Discovered at runtime from AGENTS.md + .agents/skills/ in the session's cwd. */
|
|
186
|
+
systemPrompt: string;
|
|
187
|
+
/** Discovered at runtime from .agents/skills/ in the session's cwd. */
|
|
188
|
+
skills: Record<string, Skill>;
|
|
189
|
+
roles: Record<string, Role>;
|
|
190
|
+
/**
|
|
191
|
+
* Agent-wide default model. Undefined when the user explicitly passes
|
|
192
|
+
* `init({ model: false })`, so each model-using call must resolve one from a
|
|
193
|
+
* role or call-site override.
|
|
194
|
+
*/
|
|
195
|
+
model: Model<any> | undefined;
|
|
196
|
+
/** Agent-wide default role. Per-session and per-call roles override this. */
|
|
197
|
+
role?: string;
|
|
198
|
+
/** Resolve model config to a Model instance. Throws on invalid model strings. */
|
|
199
|
+
resolveModel: (model: ModelConfig | undefined) => Model<any> | undefined;
|
|
200
|
+
/**
|
|
201
|
+
* Agent-wide default reasoning effort. Per-call and role-level values
|
|
202
|
+
* override this. The harness substitutes `"medium"` when unset; see
|
|
203
|
+
* `AgentInit.thinkingLevel` for the full precedence rules.
|
|
204
|
+
*/
|
|
205
|
+
thinkingLevel?: ThinkingLevel;
|
|
206
|
+
compaction?: CompactionConfig;
|
|
207
|
+
}
|
|
208
|
+
type ModelConfig = string | false;
|
|
209
|
+
/**
|
|
210
|
+
* Request context passed to agent handler functions. Pass type parameters
|
|
211
|
+
* to type `payload` and `env` (e.g. the `Env` interface generated by
|
|
212
|
+
* `wrangler types`). Compile-time only — no runtime validation of `payload`.
|
|
213
|
+
*/
|
|
214
|
+
interface FlueContext<TPayload = any, TEnv = Record<string, any>> {
|
|
215
|
+
readonly id: string;
|
|
216
|
+
readonly payload: TPayload;
|
|
217
|
+
/** Platform env bindings (process.env on Node, Worker env on Cloudflare). */
|
|
218
|
+
readonly env: TEnv;
|
|
219
|
+
/**
|
|
220
|
+
* The standard Fetch `Request` for the current invocation. Use it to read
|
|
221
|
+
* headers (`req.headers.get('authorization')`), method, URL, and the
|
|
222
|
+
* raw body (`req.text()` / `req.json()` / `req.arrayBuffer()` /
|
|
223
|
+
* `req.formData()`) — useful for things like HMAC signature verification
|
|
224
|
+
* over the request bytes.
|
|
225
|
+
*
|
|
226
|
+
* Body access is single-use, like any standard `Request`: once you call a
|
|
227
|
+
* body-reading method, calling another will throw. Use `req.clone()` if
|
|
228
|
+
* you need to read it more than once.
|
|
229
|
+
*
|
|
230
|
+
* Undefined when the agent is invoked outside an HTTP context (e.g. future
|
|
231
|
+
* cron / queue triggers). Today every trigger is HTTP, so in practice this
|
|
232
|
+
* is always defined — the optional type lets the contract hold when other
|
|
233
|
+
* trigger types ship.
|
|
234
|
+
*
|
|
235
|
+
* For client IP, parse the platform header yourself, e.g.
|
|
236
|
+
* `req.headers.get('cf-connecting-ip')` on Cloudflare, or
|
|
237
|
+
* `req.headers.get('x-forwarded-for')?.split(',')[0]?.trim()` behind a
|
|
238
|
+
* trusted proxy on Node. Don't trust headers you don't control.
|
|
239
|
+
*/
|
|
240
|
+
readonly req: Request | undefined;
|
|
241
|
+
/** Initialize an agent runtime with sandbox + persistence. */
|
|
242
|
+
init(options: AgentInit): Promise<FlueAgent>;
|
|
243
|
+
}
|
|
244
|
+
/** Agent runtime options. A default model is required unless explicitly disabled with `model: false`. */
|
|
245
|
+
interface AgentInit {
|
|
246
|
+
/** Agent/sandbox scope id. Defaults to the route/context id. */
|
|
247
|
+
id?: string;
|
|
248
|
+
/** Working directory for context discovery, tools, and shell calls. Defaults to the sandbox cwd. */
|
|
249
|
+
cwd?: string;
|
|
250
|
+
/**
|
|
251
|
+
* - `'empty'` (default): In-memory sandbox, no files, no host access.
|
|
252
|
+
* - `'local'`: No sandbox — direct access to the host filesystem and shell.
|
|
253
|
+
* `cwd` defaults to `process.cwd()`. Node target only; throws on Cloudflare.
|
|
254
|
+
* Use this when flue itself is running inside an external sandbox / container
|
|
255
|
+
* / CI runner that already provides the isolation boundary.
|
|
256
|
+
* - `BashFactory`: User-configured just-bash factory. Called once to construct the runtime.
|
|
257
|
+
* - `SandboxFactory`: Connector-wrapped external sandbox (Daytona, CF Containers, etc.).
|
|
258
|
+
*/
|
|
259
|
+
sandbox?: 'empty' | 'local' | SandboxFactory | BashFactory;
|
|
260
|
+
/** Defaults to platform store (in-memory on Node, DO SQLite on Cloudflare). */
|
|
261
|
+
persist?: SessionStore;
|
|
262
|
+
/**
|
|
263
|
+
* Default model for this agent. Applies to all prompt(), skill(), and task()
|
|
264
|
+
* calls unless overridden by a role or at the call site. Pass `false` to require every
|
|
265
|
+
* model-using call to resolve a model from a role or call-site override.
|
|
266
|
+
*
|
|
267
|
+
* Format: `'provider/modelId'` (e.g. `'anthropic/claude-opus-4-20250514'`).
|
|
268
|
+
*
|
|
269
|
+
* Precedence (highest wins): per-call `model` > role `model` > agent `model`.
|
|
270
|
+
*/
|
|
271
|
+
model: ModelConfig;
|
|
272
|
+
/** Agent-wide default role. Overridden by session-level or per-call roles. */
|
|
273
|
+
role?: string;
|
|
274
|
+
/**
|
|
275
|
+
* Default reasoning effort for every prompt(), skill(), and task() call.
|
|
276
|
+
* Forwarded to pi-ai's `SimpleStreamOptions.reasoning`. Pi-ai clamps the
|
|
277
|
+
* requested level against the model's `thinkingLevelMap`; non-reasoning
|
|
278
|
+
* models effectively run with reasoning off after clamping.
|
|
279
|
+
*
|
|
280
|
+
* Precedence (highest wins): per-call `thinkingLevel` > role
|
|
281
|
+
* `thinkingLevel` > agent `thinkingLevel`. When nothing is set, the harness
|
|
282
|
+
* defaults to `"medium"`. Use `"off"` to explicitly disable reasoning on
|
|
283
|
+
* models that support it.
|
|
284
|
+
*/
|
|
285
|
+
thinkingLevel?: ThinkingLevel;
|
|
286
|
+
/**
|
|
287
|
+
* Agent-wide tools. Every prompt(), skill(), and task() call can use these.
|
|
288
|
+
* Per-call tools are added on top and must not reuse the same names.
|
|
289
|
+
*/
|
|
290
|
+
tools?: ToolDef[];
|
|
291
|
+
}
|
|
292
|
+
interface FlueAgent {
|
|
293
|
+
readonly id: string;
|
|
294
|
+
/** Get or create a session in this agent. Defaults to the "default" session. */
|
|
295
|
+
session(id?: string, options?: SessionOptions): Promise<FlueSession>;
|
|
296
|
+
/** Explicit session management helpers. */
|
|
297
|
+
readonly sessions: FlueSessions;
|
|
298
|
+
/** Run a shell command in the agent sandbox without recording it in a conversation. */
|
|
299
|
+
shell(command: string, options?: ShellOptions): CallHandle<ShellResult>;
|
|
300
|
+
/**
|
|
301
|
+
* Read and write files in the agent sandbox without recording in a
|
|
302
|
+
* conversation. See {@link FlueFs}.
|
|
303
|
+
*/
|
|
304
|
+
readonly fs: FlueFs;
|
|
305
|
+
}
|
|
306
|
+
interface FlueSessions {
|
|
307
|
+
/** Load an existing session. Throws if it does not exist. */
|
|
308
|
+
get(id?: string, options?: SessionOptions): Promise<FlueSession>;
|
|
309
|
+
/** Create a new session. Throws if it already exists. */
|
|
310
|
+
create(id?: string, options?: SessionOptions): Promise<FlueSession>;
|
|
311
|
+
/** Delete a session's stored conversation state. No-op when missing. */
|
|
312
|
+
delete(id?: string): Promise<void>;
|
|
313
|
+
}
|
|
314
|
+
interface SessionOptions {
|
|
315
|
+
/** Session-wide default role. Per-call roles override this. */
|
|
316
|
+
role?: string;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Awaitable handle returned by `prompt()`, `skill()`, `task()`, and `shell()`.
|
|
320
|
+
* Aborting rejects the awaited value with an `AbortError` (a `DOMException`)
|
|
321
|
+
* whose `cause` is the signal's `reason`. Pass `options.signal` to merge an
|
|
322
|
+
* external `AbortSignal` (e.g. `AbortSignal.timeout(ms)`) with the handle's.
|
|
323
|
+
*/
|
|
324
|
+
interface CallHandle<T> extends PromiseLike<T> {
|
|
325
|
+
/** Fires when the call is aborted, whether via `abort()` or `options.signal`. */
|
|
326
|
+
readonly signal: AbortSignal;
|
|
327
|
+
/** Cancel the in-flight call. */
|
|
328
|
+
abort(reason?: unknown): void;
|
|
329
|
+
}
|
|
330
|
+
interface FlueSession {
|
|
331
|
+
readonly id: string;
|
|
332
|
+
prompt<S extends v.GenericSchema>(text: string, options: PromptOptions<S> & {
|
|
333
|
+
schema: S;
|
|
334
|
+
}): CallHandle<PromptResultResponse<v.InferOutput<S>>>;
|
|
335
|
+
prompt(text: string, options?: PromptOptions): CallHandle<PromptResponse>;
|
|
336
|
+
shell(command: string, options?: ShellOptions): CallHandle<ShellResult>;
|
|
337
|
+
/**
|
|
338
|
+
* Read and write files in the session's sandbox. See {@link FlueFs}.
|
|
339
|
+
* Unlike {@link FlueSession.shell}, fs operations are not recorded in
|
|
340
|
+
* the conversation transcript.
|
|
341
|
+
*/
|
|
342
|
+
readonly fs: FlueFs;
|
|
343
|
+
skill<S extends v.GenericSchema>(name: string, options: SkillOptions<S> & {
|
|
344
|
+
schema: S;
|
|
345
|
+
}): CallHandle<PromptResultResponse<v.InferOutput<S>>>;
|
|
346
|
+
skill(name: string, options?: SkillOptions): CallHandle<PromptResponse>;
|
|
347
|
+
task<S extends v.GenericSchema>(text: string, options: TaskOptions<S> & {
|
|
348
|
+
schema: S;
|
|
349
|
+
}): CallHandle<PromptResultResponse<v.InferOutput<S>>>;
|
|
350
|
+
task(text: string, options?: TaskOptions): CallHandle<PromptResponse>;
|
|
351
|
+
delete(): Promise<void>;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Token + cost usage aggregated across every LLM call dispatched by a
|
|
355
|
+
* single prompt(), skill(), or task() invocation, including:
|
|
356
|
+
* - every assistant turn produced by the call,
|
|
357
|
+
* - any result-extraction retry triggered by `schema:` callers,
|
|
358
|
+
* - any compaction summarization (1–2 internal calls) triggered when
|
|
359
|
+
* context approached the model's window during the call,
|
|
360
|
+
* - the post-compaction retry assistant turn for overflow recovery.
|
|
361
|
+
*
|
|
362
|
+
* `cost` is computed by pi-ai as `(model.cost.X / 1_000_000) * usage.X`,
|
|
363
|
+
* where `model.cost.X` is the per-million-token rate from the model's
|
|
364
|
+
* cost table. The currency of `cost` therefore matches whatever unit that
|
|
365
|
+
* rate is denominated in. For pi-ai's built-in model registry the rates
|
|
366
|
+
* mirror each provider's published pricing (USD for the major commercial
|
|
367
|
+
* providers); custom-registered models or proxied endpoints may use other
|
|
368
|
+
* units. When in doubt, consult the active model's cost table.
|
|
369
|
+
*/
|
|
370
|
+
interface PromptUsage {
|
|
371
|
+
input: number;
|
|
372
|
+
output: number;
|
|
373
|
+
cacheRead: number;
|
|
374
|
+
cacheWrite: number;
|
|
375
|
+
totalTokens: number;
|
|
376
|
+
cost: {
|
|
377
|
+
input: number;
|
|
378
|
+
output: number;
|
|
379
|
+
cacheRead: number;
|
|
380
|
+
cacheWrite: number;
|
|
381
|
+
total: number;
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Identifies the model that Flue selected for the call (after applying the
|
|
386
|
+
* call > role > agent precedence). When more than one model runs during the
|
|
387
|
+
* call (rare; e.g. cross-model flows), this reflects the model in effect for
|
|
388
|
+
* the call's primary turn.
|
|
389
|
+
*/
|
|
390
|
+
interface PromptModel {
|
|
391
|
+
id: string;
|
|
392
|
+
}
|
|
393
|
+
interface PromptResponse {
|
|
394
|
+
text: string;
|
|
395
|
+
usage: PromptUsage;
|
|
396
|
+
model: PromptModel;
|
|
397
|
+
}
|
|
398
|
+
interface PromptResultResponse<T> {
|
|
399
|
+
data: T;
|
|
400
|
+
/**
|
|
401
|
+
* @deprecated Renamed to `data`; will be removed in a future release.
|
|
402
|
+
* The runtime still populates this field, but it is typed as `never` so
|
|
403
|
+
* TypeScript flags any usage. Migrate destructures from
|
|
404
|
+
* `{ result }` to `{ data }`.
|
|
405
|
+
*/
|
|
406
|
+
result?: never;
|
|
407
|
+
usage: PromptUsage;
|
|
408
|
+
model: PromptModel;
|
|
409
|
+
}
|
|
410
|
+
interface SessionData {
|
|
411
|
+
version: 2;
|
|
412
|
+
entries: SessionEntry[];
|
|
413
|
+
leafId: string | null;
|
|
414
|
+
metadata: Record<string, any>;
|
|
415
|
+
createdAt: string;
|
|
416
|
+
updatedAt: string;
|
|
417
|
+
}
|
|
418
|
+
type SessionEntry = MessageEntry | CompactionEntry | BranchSummaryEntry;
|
|
419
|
+
interface SessionEntryBase {
|
|
420
|
+
type: string;
|
|
421
|
+
id: string;
|
|
422
|
+
parentId: string | null;
|
|
423
|
+
timestamp: string;
|
|
424
|
+
}
|
|
425
|
+
interface MessageEntry extends SessionEntryBase {
|
|
426
|
+
type: 'message';
|
|
427
|
+
message: AgentMessage;
|
|
428
|
+
source?: 'prompt' | 'skill' | 'shell' | 'task' | 'retry';
|
|
429
|
+
}
|
|
430
|
+
interface CompactionEntry extends SessionEntryBase {
|
|
431
|
+
type: 'compaction';
|
|
432
|
+
summary: string;
|
|
433
|
+
firstKeptEntryId: string;
|
|
434
|
+
tokensBefore: number;
|
|
435
|
+
details?: {
|
|
436
|
+
readFiles: string[];
|
|
437
|
+
modifiedFiles: string[];
|
|
438
|
+
};
|
|
439
|
+
/**
|
|
440
|
+
* Token usage consumed by the summarization call(s) that produced this
|
|
441
|
+
* compaction. Aggregated across the 1–2 internal LLM calls that
|
|
442
|
+
* `compact()` dispatched. Undefined for compactions persisted before
|
|
443
|
+
* this field was introduced (treated as zero by aggregators).
|
|
444
|
+
*/
|
|
445
|
+
usage?: PromptUsage;
|
|
446
|
+
}
|
|
447
|
+
interface BranchSummaryEntry extends SessionEntryBase {
|
|
448
|
+
type: 'branch_summary';
|
|
449
|
+
fromId: string;
|
|
450
|
+
summary: string;
|
|
451
|
+
details?: unknown;
|
|
452
|
+
}
|
|
453
|
+
interface SessionStore {
|
|
454
|
+
save(id: string, data: SessionData): Promise<void>;
|
|
455
|
+
load(id: string): Promise<SessionData | null>;
|
|
456
|
+
delete(id: string): Promise<void>;
|
|
457
|
+
}
|
|
458
|
+
/** All option fields are scoped to the duration of the call. */
|
|
459
|
+
interface PromptOptions<S extends v.GenericSchema | undefined = undefined> {
|
|
460
|
+
schema?: S;
|
|
461
|
+
/**
|
|
462
|
+
* @deprecated Renamed to `schema`; will be removed in a future release.
|
|
463
|
+
* The runtime still accepts this field, but it is typed as `never` so
|
|
464
|
+
* TypeScript flags any usage. Migrate `result: <schema>` to
|
|
465
|
+
* `schema: <schema>`.
|
|
466
|
+
*/
|
|
467
|
+
result?: never;
|
|
468
|
+
tools?: ToolDef[];
|
|
469
|
+
role?: string;
|
|
470
|
+
/** e.g., 'anthropic/claude-sonnet-4-20250514' */
|
|
471
|
+
model?: string;
|
|
472
|
+
/** Override reasoning effort for this call. See `AgentInit.thinkingLevel`. */
|
|
473
|
+
thinkingLevel?: ThinkingLevel;
|
|
474
|
+
/** Cancel this call. See `CallHandle`. */
|
|
475
|
+
signal?: AbortSignal;
|
|
476
|
+
/** Images attached to this user message. Requires a vision-capable model. */
|
|
477
|
+
images?: PromptImage[];
|
|
478
|
+
}
|
|
479
|
+
interface SkillOptions<S extends v.GenericSchema | undefined = undefined> {
|
|
480
|
+
args?: Record<string, unknown>;
|
|
481
|
+
schema?: S;
|
|
482
|
+
/**
|
|
483
|
+
* @deprecated Renamed to `schema`; will be removed in a future release.
|
|
484
|
+
* The runtime still accepts this field, but it is typed as `never` so
|
|
485
|
+
* TypeScript flags any usage. Migrate `result: <schema>` to
|
|
486
|
+
* `schema: <schema>`.
|
|
487
|
+
*/
|
|
488
|
+
result?: never;
|
|
489
|
+
tools?: ToolDef[];
|
|
490
|
+
role?: string;
|
|
491
|
+
model?: string;
|
|
492
|
+
/** Override reasoning effort for this call. See `AgentInit.thinkingLevel`. */
|
|
493
|
+
thinkingLevel?: ThinkingLevel;
|
|
494
|
+
/** Cancel this call. See `CallHandle`. */
|
|
495
|
+
signal?: AbortSignal;
|
|
496
|
+
/** Images attached to the skill's user message. Requires a vision-capable model. */
|
|
497
|
+
images?: PromptImage[];
|
|
498
|
+
}
|
|
499
|
+
interface TaskOptions<S extends v.GenericSchema | undefined = undefined> {
|
|
500
|
+
schema?: S;
|
|
501
|
+
/**
|
|
502
|
+
* @deprecated Renamed to `schema`; will be removed in a future release.
|
|
503
|
+
* The runtime still accepts this field, but it is typed as `never` so
|
|
504
|
+
* TypeScript flags any usage. Migrate `result: <schema>` to
|
|
505
|
+
* `schema: <schema>`.
|
|
506
|
+
*/
|
|
507
|
+
result?: never;
|
|
508
|
+
tools?: ToolDef[];
|
|
509
|
+
role?: string;
|
|
510
|
+
model?: string;
|
|
511
|
+
/** Override reasoning effort for this call. See `AgentInit.thinkingLevel`. */
|
|
512
|
+
thinkingLevel?: ThinkingLevel;
|
|
513
|
+
/** Working directory for the detached task session. Defaults to the parent session cwd. */
|
|
514
|
+
cwd?: string;
|
|
515
|
+
/** Cancel this task. See `CallHandle`. */
|
|
516
|
+
signal?: AbortSignal;
|
|
517
|
+
/** Images attached to the task's initial user message. Requires a vision-capable model. */
|
|
518
|
+
images?: PromptImage[];
|
|
519
|
+
}
|
|
520
|
+
interface ShellOptions {
|
|
521
|
+
env?: Record<string, string>;
|
|
522
|
+
cwd?: string;
|
|
523
|
+
/** Cancel this call. See `CallHandle`. */
|
|
524
|
+
signal?: AbortSignal;
|
|
525
|
+
}
|
|
526
|
+
interface ShellResult {
|
|
527
|
+
stdout: string;
|
|
528
|
+
stderr: string;
|
|
529
|
+
exitCode: number;
|
|
530
|
+
}
|
|
531
|
+
/** Wraps external sandboxes (Daytona, CF Containers, etc.) into Flue's SessionEnv. */
|
|
532
|
+
interface SandboxFactory {
|
|
533
|
+
createSessionEnv(options: {
|
|
534
|
+
id: string;
|
|
535
|
+
cwd?: string;
|
|
536
|
+
}): Promise<SessionEnv>;
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Structural type for duck-type detection of just-bash `Bash` instances in init().
|
|
540
|
+
* Purely structural — no just-bash import, so client.ts stays platform-agnostic.
|
|
541
|
+
*/
|
|
542
|
+
interface BashLike {
|
|
543
|
+
exec(command: string, options?: {
|
|
544
|
+
cwd?: string;
|
|
545
|
+
env?: Record<string, string>;
|
|
546
|
+
signal?: AbortSignal;
|
|
547
|
+
}): Promise<ShellResult>;
|
|
548
|
+
getCwd(): string;
|
|
549
|
+
fs: {
|
|
550
|
+
readFile(path: string, options?: any): Promise<string>;
|
|
551
|
+
readFileBuffer(path: string): Promise<Uint8Array>;
|
|
552
|
+
writeFile(path: string, content: string | Uint8Array, options?: any): Promise<void>;
|
|
553
|
+
stat(path: string): Promise<any>;
|
|
554
|
+
readdir(path: string): Promise<string[]>;
|
|
555
|
+
exists(path: string): Promise<boolean>;
|
|
556
|
+
mkdir(path: string, options?: {
|
|
557
|
+
recursive?: boolean;
|
|
558
|
+
}): Promise<void>;
|
|
559
|
+
rm(path: string, options?: {
|
|
560
|
+
recursive?: boolean;
|
|
561
|
+
force?: boolean;
|
|
562
|
+
}): Promise<void>;
|
|
563
|
+
resolvePath(base: string, path: string): string;
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
/** Factory that constructs the agent's Bash-like runtime. Called once at init. */
|
|
567
|
+
type BashFactory = () => BashLike | Promise<BashLike>;
|
|
568
|
+
type FlueEvent = ({
|
|
569
|
+
type: 'agent_start';
|
|
570
|
+
} | {
|
|
571
|
+
type: 'text_delta';
|
|
572
|
+
text: string;
|
|
573
|
+
} | {
|
|
574
|
+
type: 'thinking_start';
|
|
575
|
+
} | {
|
|
576
|
+
type: 'thinking_delta';
|
|
577
|
+
delta: string;
|
|
578
|
+
} | {
|
|
579
|
+
type: 'thinking_end';
|
|
580
|
+
content: string;
|
|
581
|
+
} | {
|
|
582
|
+
type: 'tool_start';
|
|
583
|
+
toolName: string;
|
|
584
|
+
toolCallId: string;
|
|
585
|
+
args?: any;
|
|
586
|
+
} | {
|
|
587
|
+
type: 'tool_end';
|
|
588
|
+
toolName: string;
|
|
589
|
+
toolCallId: string;
|
|
590
|
+
isError: boolean;
|
|
591
|
+
result?: any;
|
|
592
|
+
} | {
|
|
593
|
+
type: 'turn_end';
|
|
594
|
+
} | {
|
|
595
|
+
type: 'task_start';
|
|
596
|
+
taskId: string;
|
|
597
|
+
prompt: string;
|
|
598
|
+
role?: string;
|
|
599
|
+
cwd?: string;
|
|
600
|
+
} | {
|
|
601
|
+
type: 'task_end';
|
|
602
|
+
taskId: string;
|
|
603
|
+
isError: boolean;
|
|
604
|
+
result?: any;
|
|
605
|
+
} | {
|
|
606
|
+
type: 'compaction_start';
|
|
607
|
+
reason: 'threshold' | 'overflow';
|
|
608
|
+
estimatedTokens: number;
|
|
609
|
+
} | {
|
|
610
|
+
type: 'compaction_end';
|
|
611
|
+
messagesBefore: number;
|
|
612
|
+
messagesAfter: number;
|
|
613
|
+
} | {
|
|
614
|
+
type: 'idle';
|
|
615
|
+
}) & {
|
|
616
|
+
sessionId?: string;
|
|
617
|
+
parentSessionId?: string;
|
|
618
|
+
taskId?: string;
|
|
619
|
+
};
|
|
620
|
+
type FlueEventCallback = (event: FlueEvent) => void;
|
|
621
|
+
interface AgentInfo {
|
|
622
|
+
name: string;
|
|
623
|
+
filePath: string;
|
|
624
|
+
triggers: {
|
|
625
|
+
webhook?: boolean;
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
interface BuildContext {
|
|
629
|
+
agents: AgentInfo[];
|
|
630
|
+
roles: Record<string, Role>;
|
|
631
|
+
/**
|
|
632
|
+
* The project root — typically the user's cwd. Source files
|
|
633
|
+
* (agents/, roles/) live here directly, or under `<root>/.flue/`
|
|
634
|
+
* if that directory exists (the `.flue/`-as-src layout).
|
|
635
|
+
*/
|
|
636
|
+
root: string;
|
|
637
|
+
/**
|
|
638
|
+
* Absolute path to the directory the build writes its artifacts into.
|
|
639
|
+
* Defaults to `<root>/dist`; users can override with `--output`
|
|
640
|
+
* (CLI) or `output` (programmatic) to redirect the build elsewhere.
|
|
641
|
+
*
|
|
642
|
+
* Note that this is the literal output directory — `server.mjs`,
|
|
643
|
+
* `wrangler.jsonc`, etc. are written directly inside it. The user's
|
|
644
|
+
* `wrangler.jsonc` and the wrangler deploy-redirect file still anchor
|
|
645
|
+
* on `root`, regardless of this value.
|
|
646
|
+
*/
|
|
647
|
+
output: string;
|
|
648
|
+
/**
|
|
649
|
+
* Absolute path to the user's `app.{ts,js,mts,mjs}` entry, if one
|
|
650
|
+
* exists in the source root. When set, the generated server entry
|
|
651
|
+
* imports the user's app and dispatches all requests through its
|
|
652
|
+
* `fetch` method instead of constructing a default Hono app. When
|
|
653
|
+
* undefined, the generated entry falls back to a default Hono app
|
|
654
|
+
* with Flue's built-in routes mounted via `flue()`.
|
|
655
|
+
*
|
|
656
|
+
* Discovery follows the same extension priority as agents:
|
|
657
|
+
* `app.ts` > `app.mts` > `app.js` > `app.mjs`.
|
|
658
|
+
*/
|
|
659
|
+
appEntry?: string;
|
|
660
|
+
options: BuildOptions;
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Controls the build output format for a target platform.
|
|
664
|
+
*
|
|
665
|
+
* A plugin can either ship a fully-bundled JavaScript artifact (Node target)
|
|
666
|
+
* or hand over a TypeScript/ESM entry source that some downstream tool will
|
|
667
|
+
* bundle (Cloudflare target — wrangler does the bundling). Pre-bundling on
|
|
668
|
+
* top of a tool that bundles for itself causes subtle resolution conflicts
|
|
669
|
+
* (we hit this with `tar`/`fs`/etc. via `nodejs_compat`), so the Cloudflare
|
|
670
|
+
* path explicitly opts out.
|
|
671
|
+
*/
|
|
672
|
+
interface BuildPlugin {
|
|
673
|
+
name: string;
|
|
674
|
+
/**
|
|
675
|
+
* The source of the entry point (TS or JS). May be async — the Cloudflare
|
|
676
|
+
* plugin reads the user's wrangler config (via wrangler's reader) which is
|
|
677
|
+
* a sync call but lives behind a lazy `await import('wrangler')`.
|
|
678
|
+
*/
|
|
679
|
+
generateEntryPoint(ctx: BuildContext): string | Promise<string>;
|
|
680
|
+
/**
|
|
681
|
+
* Bundling strategy:
|
|
682
|
+
* - `'esbuild'` (default): run the SDK's esbuild pass to produce a
|
|
683
|
+
* bundled `dist/server.mjs`. Use when the deploy target is "just run
|
|
684
|
+
* this file" with no further bundling step.
|
|
685
|
+
* - `'none'`: skip esbuild. The entry is written as-is to `dist/` and
|
|
686
|
+
* becomes the input for whatever tool will deploy it (e.g. wrangler).
|
|
687
|
+
* The plugin must also implement `entryFilename` to set the file name.
|
|
688
|
+
*/
|
|
689
|
+
bundle?: 'esbuild' | 'none';
|
|
690
|
+
/**
|
|
691
|
+
* The filename to use for the entry, written under `dist/`. Required when
|
|
692
|
+
* `bundle === 'none'`. For `bundle === 'esbuild'` the output is always
|
|
693
|
+
* `server.mjs` and this field is ignored.
|
|
694
|
+
*/
|
|
695
|
+
entryFilename?: string;
|
|
696
|
+
/** esbuild options. Only consulted when `bundle === 'esbuild'`. */
|
|
697
|
+
esbuildOptions?(ctx: BuildContext): Record<string, any>;
|
|
698
|
+
/**
|
|
699
|
+
* Additional files to write to the output directory (`ctx.output`).
|
|
700
|
+
* Keys are filenames relative to `output` (e.g. `wrangler.jsonc`,
|
|
701
|
+
* `Dockerfile`). Values are file contents. May be async.
|
|
702
|
+
*/
|
|
703
|
+
additionalOutputs?(ctx: BuildContext): Record<string, string> | Promise<Record<string, string>>;
|
|
704
|
+
}
|
|
705
|
+
interface BuildOptions {
|
|
706
|
+
/**
|
|
707
|
+
* The project root — typically the cwd of the `flue` invocation.
|
|
708
|
+
*
|
|
709
|
+
* Source files (agents, roles) are discovered from `<root>/.flue/`
|
|
710
|
+
* if that directory exists, otherwise from `<root>/` directly.
|
|
711
|
+
* The two layouts never mix — `.flue/` wins unconditionally if present.
|
|
712
|
+
*/
|
|
713
|
+
root: string;
|
|
714
|
+
/**
|
|
715
|
+
* Where the build artifacts are written. Defaults to `<root>/dist`.
|
|
716
|
+
* Pass an absolute or root-relative path to redirect the build
|
|
717
|
+
* somewhere else (e.g. when integrating with another build system that
|
|
718
|
+
* expects a specific directory). Resolved relative to the cwd at call
|
|
719
|
+
* time, not `root`.
|
|
720
|
+
*/
|
|
721
|
+
output?: string;
|
|
722
|
+
target?: 'node' | 'cloudflare';
|
|
723
|
+
/** Overrides `target` when provided. */
|
|
724
|
+
plugin?: BuildPlugin;
|
|
725
|
+
}
|
|
726
|
+
//#endregion
|
|
727
|
+
export { SessionStore as A, PromptUsage as C, SessionData as D, SandboxFactory as E, TaskOptions as F, ThinkingLevel as I, ToolDef as L, ShellResult as M, Skill as N, SessionEnv as O, SkillOptions as P, ToolParameters as R, PromptResultResponse as S, Role as T, FlueSessions as _, BashLike as a, PromptOptions as b, BuildPlugin as c, FlueAgent as d, FlueContext as f, FlueSession as g, FlueFs as h, BashFactory as i, ShellOptions as j, SessionOptions as k, CallHandle as l, FlueEventCallback as m, AgentInfo as n, BuildContext as o, FlueEvent as p, AgentInit as r, BuildOptions as s, AgentConfig as t, FileStat as u, ModelConfig as v, ProviderSettings as w, PromptResponse as x, PromptModel as y };
|