@flue/sdk 0.3.5 → 0.3.6

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.
@@ -1,5 +1,5 @@
1
- import { S as SessionData, T as SessionStore } from "./types-T8pE1xIS.mjs";
2
- import "./mcp-BVF-sOBZ.mjs";
1
+ import { S as SessionData, T as SessionStore } from "./types-CItTrBsU.mjs";
2
+ import "./mcp-EZy-Vb5M.mjs";
3
3
  import { FlueContextConfig, FlueContextInternal, createFlueContext } from "./client.mjs";
4
4
  import { bashFactoryToSessionEnv } from "./sandbox.mjs";
5
5
  import { getModel } from "@mariozechner/pi-ai";
@@ -14,6 +14,267 @@ declare class InMemorySessionStore implements SessionStore {
14
14
  delete(id: string): Promise<void>;
15
15
  }
16
16
  //#endregion
17
+ //#region src/errors.d.ts
18
+ /**
19
+ * Concrete error classes thrown by Flue.
20
+ *
21
+ * This file is the *vocabulary* of errors in Flue. Every error the framework
22
+ * throws has a class here. The framework scaffolding (base class, renderers,
23
+ * type guards, request-parsing helpers) lives in `error-utils.ts`.
24
+ *
25
+ * ──── Why this file exists ────────────────────────────────────────────────
26
+ *
27
+ * Concentrating every error in one file is deliberate. When all errors are
28
+ * visible together, it's easy to:
29
+ *
30
+ * - Keep message tone and detail level consistent across the codebase.
31
+ * - Notice duplicates ("oh, we already have an error for this case").
32
+ * - Establish norms by example — when adding a new error, look at the
33
+ * neighbors above and copy the pattern.
34
+ *
35
+ * Application code throughout the codebase should reach for one of these
36
+ * classes rather than constructing a `FlueError` ad hoc. If no existing class
37
+ * fits, add one here. That's the entire convention.
38
+ *
39
+ * ──── Two audiences: caller vs. developer ─────────────────────────────────
40
+ *
41
+ * The reader of an error message is one of two distinct audiences:
42
+ *
43
+ * - The *caller*: an HTTP client. Possibly third-party, possibly hostile,
44
+ * possibly an end user who shouldn't even know we're built on Flue.
45
+ * Sees `message` and `details` always.
46
+ *
47
+ * - The *developer*: the human running the service (`flue dev`, `flue run`,
48
+ * local debugging). Sees `dev` in addition, but only when the server is
49
+ * running in local/dev mode (gated by `FLUE_MODE=local`).
50
+ *
51
+ * Every error class must classify its prose by audience. The required-but-
52
+ * possibly-empty shape of both `details` and `dev` is the discipline:
53
+ * forgetting either field is a TypeScript error, and writing `''` is a
54
+ * deliberate "I have nothing for that audience" decision.
55
+ *
56
+ * Concretely:
57
+ *
58
+ * - `message` One sentence. Caller-safe. Always rendered.
59
+ * - `details` Longer caller-safe prose. About the request itself, the
60
+ * contract, what the caller can do to fix it. Always
61
+ * rendered. NEVER includes:
62
+ * - sibling/neighbor enumeration (leaks namespace)
63
+ * - filesystem paths or "agents/" / "skills/" / etc.
64
+ * (leaks framework internals)
65
+ * - source-code-level fix instructions ("add ... to your
66
+ * agent definition") (caller can't act on these)
67
+ * - build-time or runtime mechanics
68
+ * - `dev` Longer dev-audience prose. Available alternatives,
69
+ * filesystem layout, framework guidance, source-code-level
70
+ * fix instructions. Rendered ONLY when FLUE_MODE=local.
71
+ *
72
+ * When in doubt, put information in `dev`. The default is conservative.
73
+ *
74
+ * ──── Conventions for new error classes ───────────────────────────────────
75
+ *
76
+ * - Class name: PascalCase, suffixed with `Error`. E.g. `AgentNotFoundError`.
77
+ * - The class owns its `type` constant (snake_case). Set once in the
78
+ * subclass constructor, never passed by callers. Renaming the wire type
79
+ * is then a one-line change.
80
+ * - Constructor takes ONLY structured input data (the values used to build
81
+ * the message). The constructor assembles `message`, `details`, and
82
+ * `dev` from that data, so call sites never reinvent phrasing.
83
+ * - `details` and `dev` are both required strings. Pass `''` only when
84
+ * there's genuinely nothing more to say for that audience.
85
+ * - For HTTP errors, the class sets its own `status` (and `headers` where
86
+ * relevant). Callers do not pick HTTP status codes ad-hoc.
87
+ *
88
+ * Worked example (matches `AgentNotFoundError` below):
89
+ *
90
+ * new AgentNotFoundError({ name, available });
91
+ * // builds:
92
+ * // message: `Agent "foo" is not registered.`
93
+ * // details: `Verify the agent name is correct.`
94
+ * // dev: `Available agents: "echo", "greeter". Agents are
95
+ * // loaded from the workspace's "agents/" directory at
96
+ * // build time. ...`
97
+ *
98
+ * The wire response in production omits `dev`; in `flue dev` / `flue run`
99
+ * it includes `dev`. That separation is what lets the dev field be richly
100
+ * helpful without leaking namespace state to public callers.
101
+ *
102
+ * Counter-example to avoid:
103
+ *
104
+ * class AgentNotFoundError extends FlueHttpError {
105
+ * constructor(message: string) { // ✗ free-form
106
+ * super({ // ✗ wrong type
107
+ * type: 'agent_error',
108
+ * message,
109
+ * details: 'Available: "x", "y", "z"', // ✗ leaks names
110
+ * dev: '', // ✗ wasted channel
111
+ * status: 500, // ✗ wrong status
112
+ * });
113
+ * }
114
+ * }
115
+ *
116
+ * The structured-constructor pattern below is what prevents that drift.
117
+ */
118
+ interface FlueErrorOptions {
119
+ /**
120
+ * Stable, machine-readable identifier (snake_case). Set once per subclass.
121
+ * Callers don't pass this — the subclass constructor does.
122
+ */
123
+ type: string;
124
+ /**
125
+ * One-sentence summary of what went wrong. Caller-safe — always rendered
126
+ * on the wire.
127
+ */
128
+ message: string;
129
+ /**
130
+ * Caller-audience longer-form explanation. Always rendered on the wire.
131
+ *
132
+ * Must be safe to expose to any HTTP client, including third-party or
133
+ * hostile callers. Do NOT include sibling enumeration, filesystem paths,
134
+ * framework-internal mechanics, or source-code fix instructions — those
135
+ * belong in `dev`.
136
+ *
137
+ * Required: pass `''` only when there's genuinely nothing more to say to
138
+ * the caller. The required-but-possibly-empty shape is intentional — it
139
+ * forces a deliberate decision rather than a thoughtless omission.
140
+ */
141
+ details: string;
142
+ /**
143
+ * Developer-audience longer-form explanation. Rendered on the wire ONLY
144
+ * when the server is running in local/dev mode (FLUE_MODE=local).
145
+ *
146
+ * Use this for everything that helps the developer running the service
147
+ * but shouldn't reach a public caller: available alternatives, filesystem
148
+ * paths, framework guidance, source-code fix instructions, configuration
149
+ * hints.
150
+ *
151
+ * Required: pass `''` only when there's genuinely nothing dev-specific
152
+ * to add (e.g. a malformed-JSON error has nothing to say to the dev that
153
+ * isn't already in `details`).
154
+ */
155
+ dev: string;
156
+ /**
157
+ * Optional structured machine-readable data. Use only when downstream
158
+ * tooling genuinely benefits — most errors should leave this unset.
159
+ */
160
+ meta?: Record<string, unknown>;
161
+ /**
162
+ * The underlying error, when wrapping. Logged server-side; never sent
163
+ * over the wire.
164
+ */
165
+ cause?: unknown;
166
+ }
167
+ /**
168
+ * Base class for every error Flue throws. Do not instantiate directly in
169
+ * application code — extend it via a subclass below. If a use case isn't
170
+ * covered, add a new subclass here rather than throwing a raw `FlueError`.
171
+ */
172
+ declare class FlueError extends Error {
173
+ readonly type: string;
174
+ readonly details: string;
175
+ readonly dev: string;
176
+ readonly meta: Record<string, unknown> | undefined;
177
+ readonly cause: unknown;
178
+ constructor(options: FlueErrorOptions);
179
+ }
180
+ interface FlueHttpErrorOptions extends FlueErrorOptions {
181
+ /** HTTP status code (4xx or 5xx). */
182
+ status: number;
183
+ /** Additional response headers (e.g. `Allow` for 405). */
184
+ headers?: Record<string, string>;
185
+ }
186
+ /**
187
+ * Base class for HTTP-layer errors. Adds `status` and optional `headers`.
188
+ * Subclasses set these in the `super({...})` call so the call site doesn't
189
+ * have to think about HTTP semantics.
190
+ */
191
+ declare class FlueHttpError extends FlueError {
192
+ readonly status: number;
193
+ readonly headers: Record<string, string> | undefined;
194
+ constructor(options: FlueHttpErrorOptions);
195
+ }
196
+ declare class MethodNotAllowedError extends FlueHttpError {
197
+ constructor({
198
+ method,
199
+ allowed
200
+ }: {
201
+ method: string;
202
+ allowed: readonly string[];
203
+ });
204
+ }
205
+ declare class AgentNotFoundError extends FlueHttpError {
206
+ constructor({
207
+ name,
208
+ available
209
+ }: {
210
+ name: string;
211
+ available: readonly string[];
212
+ });
213
+ }
214
+ declare class RouteNotFoundError extends FlueHttpError {
215
+ constructor({
216
+ method,
217
+ path
218
+ }: {
219
+ method: string;
220
+ path: string;
221
+ });
222
+ }
223
+ declare class InvalidRequestError extends FlueHttpError {
224
+ constructor({
225
+ reason
226
+ }: {
227
+ reason: string;
228
+ });
229
+ }
230
+ //#endregion
231
+ //#region src/error-utils.d.ts
232
+ /**
233
+ * Render any thrown value into a `Response` with the canonical Flue error
234
+ * envelope. Unknown / non-Flue errors are logged in full and rendered as a
235
+ * generic 500 with no message leaked.
236
+ */
237
+ declare function toHttpResponse(err: unknown): Response;
238
+ /**
239
+ * Render any thrown value into a JSON string suitable for the `data:` line of
240
+ * an SSE `error` event. Same envelope as `toHttpResponse`. Unknown / non-Flue
241
+ * errors are logged and replaced with a generic envelope.
242
+ */
243
+ declare function toSseData(err: unknown): string;
244
+ /**
245
+ * Parse a request body as JSON. Returns `{}` for genuinely empty bodies
246
+ * (Content-Length: 0 or missing) so that webhook agents which don't accept
247
+ * a payload can be invoked without one.
248
+ *
249
+ * Throws `UnsupportedMediaTypeError` if a body is present without
250
+ * `application/json` content-type, and `InvalidJsonError` if the body is
251
+ * present but unparseable.
252
+ */
253
+ declare function parseJsonBody(request: Request): Promise<unknown>;
254
+ /**
255
+ * Validate that a request targeting `/agents/<name>/<id>` is well-formed:
256
+ * method is POST, agent name is registered, and (optionally) the agent is
257
+ * webhook-accessible. Throws the appropriate FlueHttpError on any failure.
258
+ *
259
+ * Path/id validation is light: we reject empty or whitespace-only segments
260
+ * but otherwise let the URL parser's segment splitting be the source of
261
+ * truth. The Cloudflare partyserver layer additionally enforces shape via
262
+ * `routeAgentRequest`; the Node Hono layer via route patterns.
263
+ */
264
+ interface ValidateAgentRequestOptions {
265
+ method: string;
266
+ name: string;
267
+ id: string;
268
+ registeredAgents: readonly string[];
269
+ webhookAgents: readonly string[];
270
+ /**
271
+ * If true, skip the webhook-accessibility check. Used by `flue run` /
272
+ * dev local mode where trigger-less agents are also invokable.
273
+ */
274
+ allowNonWebhook?: boolean;
275
+ }
276
+ declare function validateAgentRequest(opts: ValidateAgentRequestOptions): void;
277
+ //#endregion
17
278
  //#region src/internal.d.ts
18
279
  /**
19
280
  * Resolve a `provider/model-id` string into a pi-ai `Model` object.
@@ -26,4 +287,4 @@ declare class InMemorySessionStore implements SessionStore {
26
287
  */
27
288
  declare function resolveModel(modelString: string): ReturnType<typeof getModel>;
28
289
  //#endregion
29
- export { type FlueContextConfig, type FlueContextInternal, InMemorySessionStore, bashFactoryToSessionEnv, createFlueContext, resolveModel };
290
+ export { AgentNotFoundError, type FlueContextConfig, type FlueContextInternal, InMemorySessionStore, InvalidRequestError, MethodNotAllowedError, RouteNotFoundError, bashFactoryToSessionEnv, createFlueContext, parseJsonBody, resolveModel, toHttpResponse, toSseData, validateAgentRequest };