@flue/sdk 0.3.9 → 0.3.11

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 CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # Flue
6
6
 
7
- Flue is **The Agent Harness Framework.** If you know how to use Claude Code (or OpenCode, Codex, Gemini, etc)... then you already know the basics of how to build agents with Flue.
7
+ Flue is **The Agent Harness Framework.** If you know how to use Claude Code (or Codex, OpenCode, Pi, etc)... then you already know the basics of how to build agents with Flue.
8
8
 
9
9
  Flue is a TypeScript framework for building the next generation of agents, designed around a built-in **agent harness**. It's like Claude Code, but 100% headless and programmable. There's no baked-in assumption like requiring a human operator to function. No TUI. No GUI. Just TypeScript.
10
10
 
@@ -311,11 +311,11 @@ function createTaskTool(runTask, roles) {
311
311
  }
312
312
  function formatBashResult(result, command) {
313
313
  const { text: output } = truncateTail((result.stdout + (result.stderr ? "\n" + result.stderr : "")).trim(), MAX_READ_LINES, MAX_READ_BYTES);
314
- if (result.exitCode !== 0) throw new Error(`${output}\n\nCommand exited with code ${result.exitCode}`);
314
+ const exitLine = `Command exited with code ${result.exitCode}`;
315
315
  return {
316
316
  content: [{
317
317
  type: "text",
318
- text: output || "(no output)"
318
+ text: result.exitCode === 0 ? output || "(no output)" : `${output || "(no output)"}\n\n${exitLine}`
319
319
  }],
320
320
  details: {
321
321
  command,
@@ -336,8 +336,8 @@ function createGrepTool(env) {
336
336
  async execute(_toolCallId, params, signal) {
337
337
  throwIfAborted(signal);
338
338
  const searchPath = params.path || ".";
339
- let cmd = `grep -rn "${escapeShellArg(params.pattern)}" ${escapeShellArg(searchPath)}`;
340
- if (params.include) cmd = `grep -rn --include="${escapeShellArg(params.include)}" "${escapeShellArg(params.pattern)}" ${escapeShellArg(searchPath)}`;
339
+ let cmd = `grep -rn ${shellQuote(params.pattern)} ${shellQuote(searchPath)}`;
340
+ if (params.include) cmd = `grep -rn --include=${shellQuote(params.include)} ${shellQuote(params.pattern)} ${shellQuote(searchPath)}`;
341
341
  const result = await env.exec(cmd);
342
342
  if (result.exitCode === 1 && !result.stdout.trim()) return {
343
343
  content: [{
@@ -364,14 +364,14 @@ function createGlobTool(env) {
364
364
  return {
365
365
  name: "glob",
366
366
  label: "Find Files",
367
- description: "Find files by glob pattern. Returns matching file paths.",
367
+ description: "Find files by filename pattern using shell find -name semantics. Returns matching file paths.",
368
368
  parameters: Type.Object({
369
- pattern: Type.String({ description: "Glob pattern, e.g. \"**/*.ts\"" }),
369
+ pattern: Type.String({ description: "Filename pattern, e.g. \"*.ts\"" }),
370
370
  path: Type.Optional(Type.String({ description: "Directory to search in (default: .)" }))
371
371
  }),
372
372
  async execute(_toolCallId, params, signal) {
373
373
  throwIfAborted(signal);
374
- const cmd = `find ${escapeShellArg(params.path || ".")} -type f -name "${escapeShellArg(params.pattern)}" 2>/dev/null | head -${MAX_GLOB_RESULTS}`;
374
+ const cmd = `find ${shellQuote(params.path || ".")} -type f -name ${shellQuote(params.pattern)} 2>/dev/null | head -${MAX_GLOB_RESULTS}`;
375
375
  const result = await env.exec(cmd);
376
376
  if (result.exitCode !== 0 && !result.stdout.trim()) return {
377
377
  content: [{
@@ -410,8 +410,8 @@ function countOccurrences(str, substr) {
410
410
  }
411
411
  return count;
412
412
  }
413
- function escapeShellArg(arg) {
414
- return arg.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\$/g, "\\$").replace(/`/g, "\\`");
413
+ function shellQuote(arg) {
414
+ return `'${arg.replace(/'/g, `'\\''`)}'`;
415
415
  }
416
416
  function truncateHead(lines, maxLines, maxBytes) {
417
417
  let result = "";
package/dist/client.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { A as ShellResult, D as SessionOptions, E as SessionEnv, F as ToolParameters, M as SkillOptions, N as TaskOptions, O as SessionStore, P as ToolDef, S as ProvidersConfig, T as SessionData, _ as FlueSessions, a as BashLike, b as PromptResponse, d as FileStat, f as FlueAgent, g as FlueSession, h as FlueEventCallback, i as BashFactory, k as ShellOptions, l as Command, m as FlueEvent, p as FlueContext, r as AgentInit, t as AgentConfig, v as ModelConfig, w as SandboxFactory, x as ProviderSettings, y as PromptOptions } from "./types-CKcp6T-y.mjs";
2
- import { i as connectMcpServer, n as McpServerOptions, r as McpTransport, t as McpServerConnection } from "./mcp-CKMPhMDe.mjs";
1
+ import { A as ShellResult, D as SessionOptions, E as SessionEnv, F as ToolParameters, M as SkillOptions, N as TaskOptions, O as SessionStore, P as ToolDef, S as ProvidersConfig, T as SessionData, _ as FlueSessions, a as BashLike, b as PromptResponse, d as FileStat, f as FlueAgent, g as FlueSession, h as FlueEventCallback, i as BashFactory, k as ShellOptions, l as Command, m as FlueEvent, p as FlueContext, r as AgentInit, t as AgentConfig, v as ModelConfig, w as SandboxFactory, x as ProviderSettings, y as PromptOptions } from "./types-DGpyKMFm.mjs";
2
+ import { i as connectMcpServer, n as McpServerOptions, r as McpTransport, t as McpServerConnection } from "./mcp-CcRxAwXW.mjs";
3
3
  import { Type } from "@mariozechner/pi-ai";
4
4
 
5
5
  //#region src/client.d.ts
package/dist/client.mjs CHANGED
@@ -1,7 +1,7 @@
1
- import { r as discoverSessionContext } from "./agent-BTB0809P.mjs";
2
- import { a as assertRoleExists } from "./session-CNOAfV45.mjs";
1
+ import { r as discoverSessionContext } from "./agent-Cahthgu3.mjs";
2
+ import { a as assertRoleExists } from "./session-DlwIt7wq.mjs";
3
3
  import { bashFactoryToSessionEnv, createCwdSessionEnv } from "./sandbox.mjs";
4
- import { n as AgentClient, t as connectMcpServer } from "./mcp-B13ZPduG.mjs";
4
+ import { n as AgentClient, t as connectMcpServer } from "./mcp-DmDTeVXW.mjs";
5
5
  import { Type } from "@mariozechner/pi-ai";
6
6
 
7
7
  //#region src/client.ts
@@ -1,5 +1,5 @@
1
- import { E as SessionEnv, O as SessionStore, l as Command } from "../types-CKcp6T-y.mjs";
2
- import { t as CommandExecutor } from "../command-helpers-5DpOaRIB.mjs";
1
+ import { E as SessionEnv, O as SessionStore, l as Command } from "../types-DGpyKMFm.mjs";
2
+ import { t as CommandExecutor } from "../command-helpers-eVG1-Iru.mjs";
3
3
 
4
4
  //#region src/cloudflare/virtual-sandbox.d.ts
5
5
  interface VirtualSandboxOptions {
@@ -1,5 +1,5 @@
1
- import "../agent-BTB0809P.mjs";
2
- import "../session-CNOAfV45.mjs";
1
+ import "../agent-Cahthgu3.mjs";
2
+ import "../session-DlwIt7wq.mjs";
3
3
  import { createSandboxSessionEnv } from "../sandbox.mjs";
4
4
  import { t as normalizeExecutor } from "../command-helpers-hTZKWK13.mjs";
5
5
  import { Workspace, WorkspaceFileSystem } from "@cloudflare/shell";
@@ -1,4 +1,4 @@
1
- import { A as ShellResult } from "./types-CKcp6T-y.mjs";
1
+ import { A as ShellResult } from "./types-DGpyKMFm.mjs";
2
2
 
3
3
  //#region src/command-helpers.d.ts
4
4
  /**
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as ShellResult, C as Role, D as SessionOptions, E as SessionEnv, F as ToolParameters, M as SkillOptions, N as TaskOptions, O as SessionStore, P as ToolDef, T as SessionData, _ as FlueSessions, a as BashLike, b as PromptResponse, c as BuildPlugin, d as FileStat, f as FlueAgent, g as FlueSession, h as FlueEventCallback, i as BashFactory, j as Skill, k as ShellOptions, l as Command, m as FlueEvent, n as AgentInfo, o as BuildContext, p as FlueContext, r as AgentInit, s as BuildOptions, t as AgentConfig, u as CommandDef, v as ModelConfig, w as SandboxFactory, y as PromptOptions } from "./types-CKcp6T-y.mjs";
1
+ import { A as ShellResult, C as Role, D as SessionOptions, E as SessionEnv, F as ToolParameters, M as SkillOptions, N as TaskOptions, O as SessionStore, P as ToolDef, T as SessionData, _ as FlueSessions, a as BashLike, b as PromptResponse, c as BuildPlugin, d as FileStat, f as FlueAgent, g as FlueSession, h as FlueEventCallback, i as BashFactory, j as Skill, k as ShellOptions, l as Command, m as FlueEvent, n as AgentInfo, o as BuildContext, p as FlueContext, r as AgentInit, s as BuildOptions, t as AgentConfig, u as CommandDef, v as ModelConfig, w as SandboxFactory, y as PromptOptions } from "./types-DGpyKMFm.mjs";
2
2
  import { AgentTool, AgentToolResult } from "@mariozechner/pi-agent-core";
3
3
 
4
4
  //#region src/build.d.ts
package/dist/index.mjs CHANGED
@@ -1,12 +1,88 @@
1
- import { a as parseFrontmatterFile, n as createTools, t as BUILTIN_TOOL_NAMES } from "./agent-BTB0809P.mjs";
1
+ import { a as parseFrontmatterFile, n as createTools, t as BUILTIN_TOOL_NAMES } from "./agent-Cahthgu3.mjs";
2
2
  import * as esbuild from "esbuild";
3
3
  import * as fs from "node:fs";
4
4
  import * as path from "node:path";
5
5
  import { packageUpSync } from "package-up";
6
+ import * as ts from "typescript";
6
7
  import { spawn } from "node:child_process";
7
8
  import { randomUUID } from "node:crypto";
8
9
  import { parseEnv } from "node:util";
9
10
 
11
+ //#region src/agent-parser.ts
12
+ /** Extract static agent metadata at build time without evaluating the agent module. */
13
+ function parseAgentFile(filePath) {
14
+ return { triggers: parseTriggers(filePath) };
15
+ }
16
+ function parseTriggers(filePath) {
17
+ const source = fs.readFileSync(filePath, "utf-8");
18
+ const ast = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true, scriptKindForFile(filePath));
19
+ let result;
20
+ for (const statement of ast.statements) {
21
+ if (isTriggersReExport(statement)) throwUnsupportedTriggers(filePath, "re-exported triggers are not supported");
22
+ if (!ts.isVariableStatement(statement) || !hasExportModifier(statement)) continue;
23
+ for (const declaration of statement.declarationList.declarations) {
24
+ if (!ts.isIdentifier(declaration.name) || declaration.name.text !== "triggers") continue;
25
+ if (result) throwUnsupportedTriggers(filePath, "multiple triggers exports were found");
26
+ if (!declaration.initializer) throwUnsupportedTriggers(filePath, "missing initializer");
27
+ result = parseTriggersInitializer(filePath, declaration.initializer);
28
+ }
29
+ }
30
+ return result ?? {};
31
+ }
32
+ function scriptKindForFile(filePath) {
33
+ if (/\.m?js$/.test(filePath)) return ts.ScriptKind.JS;
34
+ return ts.ScriptKind.TS;
35
+ }
36
+ function hasExportModifier(statement) {
37
+ return statement.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword) ?? false;
38
+ }
39
+ function isTriggersReExport(statement) {
40
+ if (!ts.isExportDeclaration(statement) || !statement.exportClause) return false;
41
+ if (!ts.isNamedExports(statement.exportClause)) return false;
42
+ return statement.exportClause.elements.some((element) => element.name.text === "triggers");
43
+ }
44
+ function parseTriggersInitializer(filePath, initializer) {
45
+ const expr = unwrapExpression(initializer);
46
+ if (!ts.isObjectLiteralExpression(expr)) throwUnsupportedTriggers(filePath, "expected a static object literal");
47
+ const result = {};
48
+ for (const property of expr.properties) {
49
+ if (ts.isSpreadAssignment(property)) throwUnsupportedTriggers(filePath, "spread properties are not supported");
50
+ if (ts.isShorthandPropertyAssignment(property)) {
51
+ const name = property.name.text;
52
+ if (name === "webhook") throwUnsupportedTriggers(filePath, `"${name}" must use an explicit static value`);
53
+ continue;
54
+ }
55
+ if (!ts.isPropertyAssignment(property)) {
56
+ const name = propertyNameText(filePath, property.name);
57
+ if (name === "webhook") throwUnsupportedTriggers(filePath, `"${name}" must use an explicit static value`);
58
+ continue;
59
+ }
60
+ if (propertyNameText(filePath, property.name) === "webhook") {
61
+ const value = unwrapExpression(property.initializer);
62
+ if (value.kind === ts.SyntaxKind.TrueKeyword) result.webhook = true;
63
+ else if (value.kind === ts.SyntaxKind.FalseKeyword) delete result.webhook;
64
+ else throwUnsupportedTriggers(filePath, "\"webhook\" must be true or false");
65
+ }
66
+ }
67
+ return result;
68
+ }
69
+ function unwrapExpression(expr) {
70
+ while (ts.isAsExpression(expr) || ts.isSatisfiesExpression(expr) || ts.isTypeAssertionExpression(expr) || ts.isParenthesizedExpression(expr)) expr = expr.expression;
71
+ return expr;
72
+ }
73
+ function propertyNameText(filePath, name) {
74
+ if (ts.isIdentifier(name) || ts.isStringLiteral(name) || ts.isNumericLiteral(name)) return name.text;
75
+ if (ts.isComputedPropertyName(name)) {
76
+ const expression = unwrapExpression(name.expression);
77
+ if (ts.isStringLiteral(expression) || ts.isNoSubstitutionTemplateLiteral(expression)) return expression.text;
78
+ throwUnsupportedTriggers(filePath, "computed property names must be static");
79
+ }
80
+ }
81
+ function throwUnsupportedTriggers(filePath, reason) {
82
+ throw new Error(`[flue] Unsupported triggers export in ${filePath}: ${reason}. Use a static object literal, for example: export const triggers = { webhook: true }.`);
83
+ }
84
+
85
+ //#endregion
10
86
  //#region src/cloudflare-wrangler-merge.ts
11
87
  /**
12
88
  * Merge Flue's Cloudflare additions into the user's wrangler config.
@@ -377,9 +453,10 @@ var CloudflarePlugin = class {
377
453
  async generateEntryPoint(ctx) {
378
454
  const { agents, roles } = ctx;
379
455
  const rolesJson = JSON.stringify(roles);
456
+ validateCloudflareAgentNames(ctx);
380
457
  const webhookAgents = agents.filter((a) => a.triggers.webhook);
381
- const agentImports = agents.map((a) => {
382
- return `import ${agentVarName$1(a.name)} from '${a.filePath.replace(/\\/g, "/")}';`;
458
+ const agentImports = agents.map((a, index) => {
459
+ return `import ${agentVarName$1(a.name, index)} from '${a.filePath.replace(/\\/g, "/")}';`;
383
460
  }).join("\n");
384
461
  const manifest = JSON.stringify({ agents: agents.map((a) => ({
385
462
  name: a.name,
@@ -387,7 +464,7 @@ var CloudflarePlugin = class {
387
464
  })) }, null, 2);
388
465
  const agentClasses = webhookAgents.map((a) => {
389
466
  const className = agentClassName(a.name);
390
- const handlerVar = agentVarName$1(a.name);
467
+ const handlerVar = agentVarName$1(a.name, agents.indexOf(a));
391
468
  return `export class ${className} extends Agent {
392
469
  async onRequest(request) {
393
470
  return handleAgentRequest(request, this, ${JSON.stringify(a.name)}, ${handlerVar});
@@ -829,8 +906,17 @@ export default {
829
906
  return outputs;
830
907
  }
831
908
  };
832
- function agentVarName$1(name) {
833
- return "handler_" + name.replace(/[^a-zA-Z0-9]/g, "_");
909
+ function agentVarName$1(name, index) {
910
+ return `handler_${name.replace(/[^a-zA-Z0-9]/g, "_").replace(/^_+|_+$/g, "") || "agent"}_${index}`;
911
+ }
912
+ const CLOUDFLARE_AGENT_NAME_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
913
+ function validateCloudflareAgentNames(ctx) {
914
+ const invalidAgents = ctx.agents.filter((agent) => !CLOUDFLARE_AGENT_NAME_PATTERN.test(agent.name));
915
+ if (invalidAgents.length === 0) return;
916
+ const invalidList = invalidAgents.map((agent) => {
917
+ return `${path.relative(ctx.workspaceDir, agent.filePath)} (${agent.name})`;
918
+ }).join(", ");
919
+ throw new Error(`[flue] Cloudflare target requires agent filenames to use lower-kebab-case so Durable Object bindings route correctly. Invalid agent file(s): ${invalidList}. Rename them to match ${CLOUDFLARE_AGENT_NAME_PATTERN}.`);
834
920
  }
835
921
  /**
836
922
  * Convert agent name to a PascalCase DO class name.
@@ -871,8 +957,8 @@ import {
871
957
  } from '@flue/sdk/internal';
872
958
  import { randomUUID } from 'node:crypto';
873
959
 
874
- ${agents.map((a) => {
875
- return `import ${agentVarName(a.name)} from '${a.filePath.replace(/\\/g, "/")}';`;
960
+ ${agents.map((a, index) => {
961
+ return `import ${agentVarName(a.name, index)} from '${a.filePath.replace(/\\/g, "/")}';`;
876
962
  }).join("\n")}
877
963
 
878
964
  // ─── Config ─────────────────────────────────────────────────────────────────
@@ -882,7 +968,7 @@ const roles = ${rolesJson};
882
968
  const systemPrompt = '';
883
969
 
884
970
  const handlers = {
885
- ${agents.map((a) => ` ${JSON.stringify(a.name)}: ${agentVarName(a.name)},`).join("\n")}
971
+ ${agents.map((a, index) => ` ${JSON.stringify(a.name)}: ${agentVarName(a.name, index)},`).join("\n")}
886
972
  };
887
973
 
888
974
  // Set of webhook-accessible agent names. Named distinctly from the
@@ -1093,8 +1179,8 @@ process.on('SIGTERM', () => { server.close(); process.exit(0); });
1093
1179
  };
1094
1180
  }
1095
1181
  };
1096
- function agentVarName(name) {
1097
- return "handler_" + name.replace(/[^a-zA-Z0-9]/g, "_");
1182
+ function agentVarName(name, index) {
1183
+ return `handler_${name.replace(/[^a-zA-Z0-9]/g, "_").replace(/^_+|_+$/g, "") || "agent"}_${index}`;
1098
1184
  }
1099
1185
 
1100
1186
  //#endregion
@@ -1120,12 +1206,10 @@ async function build(options) {
1120
1206
  const agents = discoverAgents(workspaceDir);
1121
1207
  if (agents.length === 0) throw new Error(`[flue] No agent files found.\n\nExpected at: ${path.join(workspaceDir, "agents")}/\nAdd at least one agent file (e.g. hello.ts).`);
1122
1208
  const webhookAgents = agents.filter((a) => a.triggers.webhook);
1123
- const cronAgents = agents.filter((a) => a.triggers.cron);
1124
- const triggerlessAgents = agents.filter((a) => !a.triggers.webhook && !a.triggers.cron);
1209
+ const triggerlessAgents = agents.filter((a) => !a.triggers.webhook);
1125
1210
  console.log(`[flue] Found ${Object.keys(roles).length} role(s): ${Object.keys(roles).join(", ") || "(none)"}`);
1126
1211
  console.log(`[flue] Found ${agents.length} agent(s): ${agents.map((a) => a.name).join(", ")}`);
1127
1212
  if (webhookAgents.length > 0) console.log(`[flue] Webhook agents: ${webhookAgents.map((a) => a.name).join(", ")}`);
1128
- if (cronAgents.length > 0) console.log(`[flue] Cron agents (manifest only): ${cronAgents.map((a) => `${a.name} (${a.triggers.cron})`).join(", ")}`);
1129
1213
  if (triggerlessAgents.length > 0) console.log(`[flue] CLI-only agents (no HTTP route in deployed build): ${triggerlessAgents.map((a) => a.name).join(", ")}`);
1130
1214
  console.log(`[flue] AGENTS.md and .agents/skills/ will be discovered at runtime from session cwd`);
1131
1215
  const distDir = path.join(outputDir, "dist");
@@ -1254,7 +1338,7 @@ function discoverAgents(workspaceRoot) {
1254
1338
  if (!fs.existsSync(agentsDir)) return [];
1255
1339
  return fs.readdirSync(agentsDir).filter((f) => /\.(ts|js|mts|mjs)$/.test(f)).map((f) => {
1256
1340
  const filePath = path.join(agentsDir, f);
1257
- const triggers = parseTriggers(filePath);
1341
+ const { triggers } = parseAgentFile(filePath);
1258
1342
  return {
1259
1343
  name: f.replace(/\.(ts|js|mts|mjs)$/, ""),
1260
1344
  filePath,
@@ -1262,18 +1346,6 @@ function discoverAgents(workspaceRoot) {
1262
1346
  };
1263
1347
  });
1264
1348
  }
1265
- /** Extract trigger config via regex. Only triggers are parsed at build time (needed for routing). */
1266
- function parseTriggers(filePath) {
1267
- const source = fs.readFileSync(filePath, "utf-8");
1268
- const result = {};
1269
- const triggersExportMatch = source.match(/export\s+const\s+triggers\s*=\s*\{([^}]*)\}/);
1270
- if (!triggersExportMatch) return result;
1271
- const triggersBlock = triggersExportMatch[1] ?? "";
1272
- if (/webhook\s*:\s*true/.test(triggersBlock)) result.webhook = true;
1273
- const cronMatch = triggersBlock.match(/cron\s*:\s*['"]([^'"]+)['"]/);
1274
- if (cronMatch?.[1]) result.cron = cronMatch[1];
1275
- return result;
1276
- }
1277
1349
  /** Externalize user's direct deps (bare name + subpath wildcard). */
1278
1350
  function getUserExternals(workspaceDir) {
1279
1351
  const pkgPath = packageUpSync({ cwd: workspaceDir });
@@ -1,10 +1,7 @@
1
- import { O as SessionStore, S as ProvidersConfig, T as SessionData, v as ModelConfig } from "./types-CKcp6T-y.mjs";
2
- import "./mcp-CKMPhMDe.mjs";
1
+ import { O as SessionStore, S as ProvidersConfig, T as SessionData, v as ModelConfig } from "./types-DGpyKMFm.mjs";
3
2
  import { FlueContextConfig, FlueContextInternal, createFlueContext } from "./client.mjs";
4
3
  import { bashFactoryToSessionEnv } from "./sandbox.mjs";
5
4
  import { getModel } from "@mariozechner/pi-ai";
6
- import "valibot";
7
-
8
5
  //#region src/session.d.ts
9
6
  /** In-memory session store. Sessions persist for the lifetime of the process. */
10
7
  declare class InMemorySessionStore implements SessionStore {
package/dist/internal.mjs CHANGED
@@ -1,7 +1,7 @@
1
- import "./agent-BTB0809P.mjs";
2
- import { t as InMemorySessionStore } from "./session-CNOAfV45.mjs";
1
+ import "./agent-Cahthgu3.mjs";
2
+ import { t as InMemorySessionStore } from "./session-DlwIt7wq.mjs";
3
3
  import { bashFactoryToSessionEnv } from "./sandbox.mjs";
4
- import "./mcp-B13ZPduG.mjs";
4
+ import "./mcp-DmDTeVXW.mjs";
5
5
  import { createFlueContext } from "./client.mjs";
6
6
  import { getModel } from "@mariozechner/pi-ai";
7
7
 
@@ -1,4 +1,4 @@
1
- import { P as ToolDef } from "./types-CKcp6T-y.mjs";
1
+ import { P as ToolDef } from "./types-DGpyKMFm.mjs";
2
2
 
3
3
  //#region src/mcp.d.ts
4
4
  type McpTransport = 'streamable-http' | 'sse';
@@ -1,5 +1,5 @@
1
- import { r as discoverSessionContext } from "./agent-BTB0809P.mjs";
2
- import { a as assertRoleExists, n as Session, o as createScopedEnv, r as deleteSessionTree, s as mergeCommands } from "./session-CNOAfV45.mjs";
1
+ import { r as discoverSessionContext } from "./agent-Cahthgu3.mjs";
2
+ import { a as assertRoleExists, n as Session, o as createScopedEnv, r as deleteSessionTree, s as mergeCommands } from "./session-DlwIt7wq.mjs";
3
3
  import { createCwdSessionEnv } from "./sandbox.mjs";
4
4
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
5
5
  import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
@@ -1,5 +1,5 @@
1
- import { l as Command } from "../types-CKcp6T-y.mjs";
2
- import { t as CommandExecutor } from "../command-helpers-5DpOaRIB.mjs";
1
+ import { l as Command } from "../types-DGpyKMFm.mjs";
2
+ import { t as CommandExecutor } from "../command-helpers-eVG1-Iru.mjs";
3
3
  import { execFile } from "node:child_process";
4
4
 
5
5
  //#region src/node/define-command.d.ts
@@ -1,4 +1,4 @@
1
- import { A as ShellResult, E as SessionEnv, d as FileStat, i as BashFactory, u as CommandDef, w as SandboxFactory } from "./types-CKcp6T-y.mjs";
1
+ import { A as ShellResult, E as SessionEnv, d as FileStat, i as BashFactory, u as CommandDef, w as SandboxFactory } from "./types-DGpyKMFm.mjs";
2
2
 
3
3
  //#region src/sandbox.d.ts
4
4
  declare function createCwdSessionEnv(parentEnv: SessionEnv, cwd: string): SessionEnv;
package/dist/sandbox.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import "./agent-BTB0809P.mjs";
2
- import { i as normalizePath, o as createScopedEnv } from "./session-CNOAfV45.mjs";
1
+ import "./agent-Cahthgu3.mjs";
2
+ import { i as normalizePath, o as createScopedEnv } from "./session-DlwIt7wq.mjs";
3
3
 
4
4
  //#region src/sandbox.ts
5
5
  function createCwdSessionEnv(parentEnv, cwd) {
@@ -1,4 +1,4 @@
1
- import { i as loadSkillByPath, n as createTools, t as BUILTIN_TOOL_NAMES } from "./agent-BTB0809P.mjs";
1
+ import { i as loadSkillByPath, n as createTools, t as BUILTIN_TOOL_NAMES } from "./agent-Cahthgu3.mjs";
2
2
  import { completeSimple, isContextOverflow } from "@mariozechner/pi-ai";
3
3
  import { Agent } from "@mariozechner/pi-agent-core";
4
4
  import { toJsonSchema } from "@valibot/to-json-schema";
@@ -1158,7 +1158,11 @@ var Session = class {
1158
1158
  this.history.removeLeafMessage(lastMsg);
1159
1159
  await this.save();
1160
1160
  }
1161
- await this.runCompaction("overflow", true);
1161
+ try {
1162
+ await this.runCompaction("overflow", true);
1163
+ } finally {
1164
+ this.overflowRecoveryAttempted = false;
1165
+ }
1162
1166
  return;
1163
1167
  }
1164
1168
  if (assistantMessage.stopReason === "error") return;
@@ -436,7 +436,6 @@ interface AgentInfo {
436
436
  filePath: string;
437
437
  triggers: {
438
438
  webhook?: boolean;
439
- cron?: string;
440
439
  };
441
440
  }
442
441
  interface BuildContext {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flue/sdk",
3
- "version": "0.3.9",
3
+ "version": "0.3.11",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "exports": {
@@ -45,6 +45,7 @@
45
45
  "hono": "^4.7.0",
46
46
  "just-bash": "^2.14.2",
47
47
  "package-up": "^5.0.0",
48
+ "typescript": "^5.9.2",
48
49
  "valibot": "^1.0.0"
49
50
  },
50
51
  "devDependencies": {