@flue/sdk 0.3.10 → 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 +1 -1
- package/dist/{agent-BTB0809P.mjs → agent-Cahthgu3.mjs} +9 -9
- package/dist/client.d.mts +2 -2
- package/dist/client.mjs +3 -3
- package/dist/cloudflare/index.d.mts +2 -2
- package/dist/cloudflare/index.mjs +2 -2
- package/dist/{command-helpers-5DpOaRIB.d.mts → command-helpers-eVG1-Iru.d.mts} +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +99 -27
- package/dist/internal.d.mts +1 -4
- package/dist/internal.mjs +3 -3
- package/dist/{mcp-CKMPhMDe.d.mts → mcp-CcRxAwXW.d.mts} +1 -1
- package/dist/{mcp-B13ZPduG.mjs → mcp-DmDTeVXW.mjs} +2 -2
- package/dist/node/index.d.mts +2 -2
- package/dist/sandbox.d.mts +1 -1
- package/dist/sandbox.mjs +2 -2
- package/dist/{session-CNOAfV45.mjs → session-DlwIt7wq.mjs} +6 -2
- package/dist/{types-CKcp6T-y.d.mts → types-DGpyKMFm.d.mts} +0 -1
- package/package.json +2 -1
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
|
|
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
|
-
|
|
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
|
|
340
|
-
if (params.include) cmd = `grep -rn --include
|
|
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
|
|
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: "
|
|
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 ${
|
|
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
|
|
414
|
-
return arg.replace(
|
|
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-
|
|
2
|
-
import { i as connectMcpServer, n as McpServerOptions, r as McpTransport, t as McpServerConnection } from "./mcp-
|
|
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-
|
|
2
|
-
import { a as assertRoleExists } from "./session-
|
|
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-
|
|
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-
|
|
2
|
-
import { t as CommandExecutor } from "../command-helpers-
|
|
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-
|
|
2
|
-
import "../session-
|
|
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";
|
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-
|
|
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-
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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 });
|
package/dist/internal.d.mts
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import { O as SessionStore, S as ProvidersConfig, T as SessionData, v as ModelConfig } from "./types-
|
|
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-
|
|
2
|
-
import { t as InMemorySessionStore } from "./session-
|
|
1
|
+
import "./agent-Cahthgu3.mjs";
|
|
2
|
+
import { t as InMemorySessionStore } from "./session-DlwIt7wq.mjs";
|
|
3
3
|
import { bashFactoryToSessionEnv } from "./sandbox.mjs";
|
|
4
|
-
import "./mcp-
|
|
4
|
+
import "./mcp-DmDTeVXW.mjs";
|
|
5
5
|
import { createFlueContext } from "./client.mjs";
|
|
6
6
|
import { getModel } from "@mariozechner/pi-ai";
|
|
7
7
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as discoverSessionContext } from "./agent-
|
|
2
|
-
import { a as assertRoleExists, n as Session, o as createScopedEnv, r as deleteSessionTree, s as mergeCommands } from "./session-
|
|
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";
|
package/dist/node/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { l as Command } from "../types-
|
|
2
|
-
import { t as CommandExecutor } from "../command-helpers-
|
|
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
|
package/dist/sandbox.d.mts
CHANGED
|
@@ -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-
|
|
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-
|
|
2
|
-
import { i as normalizePath, o as createScopedEnv } from "./session-
|
|
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-
|
|
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
|
-
|
|
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;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flue/sdk",
|
|
3
|
-
"version": "0.3.
|
|
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": {
|