@flue/sdk 0.1.2 → 0.1.3
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 +4 -9
- package/dist/client.d.mts +2 -7
- package/dist/client.mjs +3 -9
- package/dist/cloudflare/index.d.mts +6 -2
- package/dist/cloudflare/index.mjs +25 -2
- package/dist/command-helpers-BPcSV93o.d.mts +21 -0
- package/dist/command-helpers-CxRhK1my.mjs +37 -0
- package/dist/index.d.mts +1 -1
- package/dist/internal.d.mts +1 -1
- package/dist/internal.mjs +1 -1
- package/dist/node/index.d.mts +14 -0
- package/dist/node/index.mjs +75 -0
- package/dist/sandbox.d.mts +1 -1
- package/dist/sandbox.mjs +1 -1
- package/dist/{session-BRLCNVG1.mjs → session-CiAMTsLZ.mjs} +25 -7
- package/dist/{types-C8tsaK1j.d.mts → types-BZPltYah.d.mts} +7 -0
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -94,9 +94,8 @@ A triage agent that runs in CI whenever an issue is opened on GitHub. The `"loca
|
|
|
94
94
|
|
|
95
95
|
```ts
|
|
96
96
|
// .flue/agents/triage.ts
|
|
97
|
-
import {
|
|
98
|
-
import {
|
|
99
|
-
import { promisify } from 'node:util';
|
|
97
|
+
import { type FlueContext } from '@flue/sdk/client';
|
|
98
|
+
import { defineCommand } from '@flue/sdk/node';
|
|
100
99
|
import * as v from 'valibot';
|
|
101
100
|
|
|
102
101
|
// Because we are running this in CI, we don't need to expose this as an HTTP endpoint.
|
|
@@ -106,12 +105,8 @@ export const triggers = {};
|
|
|
106
105
|
// Connect privileged CLIs to your agent without leaking sensitive keys and secrets.
|
|
107
106
|
// Secrets are hooked up inside the command definition here, so your agent never sees them.
|
|
108
107
|
// Commands are controlled per-prompt, so you can be as granular with access as you need.
|
|
109
|
-
const npm = defineCommand('npm'
|
|
110
|
-
const gh = defineCommand('gh',
|
|
111
|
-
promisify(execFile)('gh', args, {
|
|
112
|
-
env: { GH_TOKEN: process.env.GH_TOKEN },
|
|
113
|
-
}),
|
|
114
|
-
);
|
|
108
|
+
const npm = defineCommand('npm');
|
|
109
|
+
const gh = defineCommand('gh', { env: { GH_TOKEN: process.env.GH_TOKEN } });
|
|
115
110
|
|
|
116
111
|
export default async function ({ init, payload }: FlueContext) {
|
|
117
112
|
// 'local' mounts the host filesystem at /workspace — ideal for CI
|
package/dist/client.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as ShellOptions, D as TaskOptions, E as SkillOptions, O as ToolDef, S as SessionStore, b as SessionEnv, d as FlueContext, f as FlueEvent, g as PromptResponse, h as PromptOptions, l as CommandSupport, m as FlueSession, p as FlueEventCallback, r as BashLike, s as Command, t as AgentConfig, u as FileStat, v as SandboxFactory, w as ShellResult, x as SessionInit, y as SessionData } from "./types-
|
|
1
|
+
import { C as ShellOptions, D as TaskOptions, E as SkillOptions, O as ToolDef, S as SessionStore, b as SessionEnv, d as FlueContext, f as FlueEvent, g as PromptResponse, h as PromptOptions, l as CommandSupport, m as FlueSession, p as FlueEventCallback, r as BashLike, s as Command, t as AgentConfig, u as FileStat, v as SandboxFactory, w as ShellResult, x as SessionInit, y as SessionData } from "./types-BZPltYah.mjs";
|
|
2
2
|
import { Type } from "@mariozechner/pi-ai";
|
|
3
3
|
|
|
4
4
|
//#region src/client.d.ts
|
|
@@ -21,10 +21,5 @@ interface FlueContextInternal extends FlueContext {
|
|
|
21
21
|
setEventCallback(callback: FlueEventCallback | undefined): void;
|
|
22
22
|
}
|
|
23
23
|
declare function createFlueContext(config: FlueContextConfig): FlueContextInternal;
|
|
24
|
-
declare function defineCommand(name: string, execute: (args: string[]) => Promise<{
|
|
25
|
-
stdout: string;
|
|
26
|
-
stderr: string;
|
|
27
|
-
exitCode: number;
|
|
28
|
-
}>): Command;
|
|
29
24
|
//#endregion
|
|
30
|
-
export { type BashLike, type Command, type CommandSupport, type FileStat, type FlueContext, FlueContextConfig, FlueContextInternal, type FlueEvent, type FlueEventCallback, type FlueSession, type PromptOptions, type PromptResponse, type SandboxFactory, type SessionData, type SessionEnv, type SessionInit, type SessionStore, type ShellOptions, type ShellResult, type SkillOptions, type TaskOptions, type ToolDef, Type, createFlueContext
|
|
25
|
+
export { type BashLike, type Command, type CommandSupport, type FileStat, type FlueContext, FlueContextConfig, FlueContextInternal, type FlueEvent, type FlueEventCallback, type FlueSession, type PromptOptions, type PromptResponse, type SandboxFactory, type SessionData, type SessionEnv, type SessionInit, type SessionStore, type ShellOptions, type ShellResult, type SkillOptions, type TaskOptions, type ToolDef, Type, createFlueContext };
|
package/dist/client.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as discoverSessionContext } from "./agent-BYG0nVbQ.mjs";
|
|
2
|
-
import { n as Session } from "./session-
|
|
2
|
+
import { n as Session } from "./session-CiAMTsLZ.mjs";
|
|
3
3
|
import { bashToSessionEnv } from "./sandbox.mjs";
|
|
4
4
|
import { Type } from "@mariozechner/pi-ai";
|
|
5
5
|
|
|
@@ -32,7 +32,7 @@ function createFlueContext(config) {
|
|
|
32
32
|
skills: localContext.skills,
|
|
33
33
|
model: sessionModel
|
|
34
34
|
};
|
|
35
|
-
return new Session(config.sessionId, sessionConfig, env, store, savedData, currentEventCallback);
|
|
35
|
+
return new Session(config.sessionId, sessionConfig, env, store, savedData, currentEventCallback, options?.commands);
|
|
36
36
|
},
|
|
37
37
|
setEventCallback(callback) {
|
|
38
38
|
currentEventCallback = callback;
|
|
@@ -54,12 +54,6 @@ async function resolveSessionEnv(sessionId, sandbox, config) {
|
|
|
54
54
|
}
|
|
55
55
|
return sandbox.createSessionEnv({ sessionId });
|
|
56
56
|
}
|
|
57
|
-
function defineCommand(name, execute) {
|
|
58
|
-
return {
|
|
59
|
-
name,
|
|
60
|
-
execute
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
57
|
|
|
64
58
|
//#endregion
|
|
65
|
-
export { Type, createFlueContext
|
|
59
|
+
export { Type, createFlueContext };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { S as SessionStore, b as SessionEnv } from "../types-
|
|
1
|
+
import { S as SessionStore, b as SessionEnv, s as Command } from "../types-BZPltYah.mjs";
|
|
2
|
+
import { t as CommandExecutor } from "../command-helpers-BPcSV93o.mjs";
|
|
2
3
|
|
|
3
4
|
//#region src/cloudflare/virtual-sandbox.d.ts
|
|
4
5
|
interface VirtualSandboxOptions {
|
|
@@ -8,6 +9,9 @@ interface VirtualSandboxOptions {
|
|
|
8
9
|
declare function getVirtualSandbox(): Promise<any>;
|
|
9
10
|
declare function getVirtualSandbox(bucket: unknown, options?: VirtualSandboxOptions): Promise<any>;
|
|
10
11
|
//#endregion
|
|
12
|
+
//#region src/cloudflare/define-command.d.ts
|
|
13
|
+
declare function defineCommand(name: string, execute: CommandExecutor): Command;
|
|
14
|
+
//#endregion
|
|
11
15
|
//#region src/cloudflare/cf-sandbox.d.ts
|
|
12
16
|
declare function cfSandboxToSessionEnv(sandbox: any, cwd?: string): Promise<SessionEnv>;
|
|
13
17
|
//#endregion
|
|
@@ -33,4 +37,4 @@ declare function setCloudflareContext(ctx: CloudflareContext): void;
|
|
|
33
37
|
declare function getCloudflareContext(): CloudflareContext;
|
|
34
38
|
declare function clearCloudflareContext(): void;
|
|
35
39
|
//#endregion
|
|
36
|
-
export { type CloudflareContext, type VirtualSandboxOptions, cfSandboxToSessionEnv, clearCloudflareContext, getCloudflareContext, getVirtualSandbox, setCloudflareContext, store };
|
|
40
|
+
export { type CloudflareContext, type VirtualSandboxOptions, cfSandboxToSessionEnv, clearCloudflareContext, defineCommand, getCloudflareContext, getVirtualSandbox, setCloudflareContext, store };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import "../agent-BYG0nVbQ.mjs";
|
|
2
|
-
import "../session-
|
|
2
|
+
import "../session-CiAMTsLZ.mjs";
|
|
3
3
|
import { createSandboxSessionEnv } from "../sandbox.mjs";
|
|
4
|
+
import { t as normalizeExecutor } from "../command-helpers-CxRhK1my.mjs";
|
|
4
5
|
import { Workspace, WorkspaceFileSystem } from "@cloudflare/shell";
|
|
5
6
|
|
|
6
7
|
//#region src/cloudflare/context.ts
|
|
@@ -105,6 +106,28 @@ async function getVirtualSandbox(bucket, options) {
|
|
|
105
106
|
});
|
|
106
107
|
}
|
|
107
108
|
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region src/cloudflare/define-command.ts
|
|
111
|
+
/**
|
|
112
|
+
* Cloudflare-specific `defineCommand`. Function form only — Workers cannot
|
|
113
|
+
* spawn host processes, so there is no pass-through sugar. The user supplies
|
|
114
|
+
* an executor (typically `fetch`-based or SDK-based) and benefits from
|
|
115
|
+
* return-shape normalization plus automatic throw-catching.
|
|
116
|
+
*
|
|
117
|
+
* ```ts
|
|
118
|
+
* const issues = defineCommand('issues', async (args) => {
|
|
119
|
+
* const res = await fetch(`https://api.github.com/...`);
|
|
120
|
+
* return { stdout: await res.text() };
|
|
121
|
+
* });
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
function defineCommand(name, execute) {
|
|
125
|
+
return {
|
|
126
|
+
name,
|
|
127
|
+
execute: normalizeExecutor(execute)
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
108
131
|
//#endregion
|
|
109
132
|
//#region src/cloudflare/cf-sandbox.ts
|
|
110
133
|
/** Wraps a @cloudflare/sandbox instance (from getSandbox()) into SessionEnv. */
|
|
@@ -204,4 +227,4 @@ function store() {
|
|
|
204
227
|
}
|
|
205
228
|
|
|
206
229
|
//#endregion
|
|
207
|
-
export { cfSandboxToSessionEnv, clearCloudflareContext, getCloudflareContext, getVirtualSandbox, setCloudflareContext, store };
|
|
230
|
+
export { cfSandboxToSessionEnv, clearCloudflareContext, defineCommand, getCloudflareContext, getVirtualSandbox, setCloudflareContext, store };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { w as ShellResult } from "./types-BZPltYah.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/command-helpers.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Loose return shape accepted from user-supplied command executors. All forms
|
|
6
|
+
* are normalized to a full `ShellResult` by `normalizeExecutor()`.
|
|
7
|
+
*/
|
|
8
|
+
type CommandExecutorResult = ShellResult | {
|
|
9
|
+
stdout?: string;
|
|
10
|
+
stderr?: string;
|
|
11
|
+
exitCode?: number;
|
|
12
|
+
} | string | void;
|
|
13
|
+
/**
|
|
14
|
+
* User-supplied command executor. Can return a full `ShellResult`, a partial
|
|
15
|
+
* `{ stdout?, stderr?, exitCode? }` object, a bare string (treated as stdout),
|
|
16
|
+
* or void (empty success). Thrown errors are caught and converted to an
|
|
17
|
+
* `exitCode`-bearing `ShellResult` — no `try`/`catch` needed at the call site.
|
|
18
|
+
*/
|
|
19
|
+
type CommandExecutor = (args: string[]) => Promise<CommandExecutorResult>;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { CommandExecutor as t };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//#region src/command-helpers.ts
|
|
2
|
+
/**
|
|
3
|
+
* Wrap a user-supplied `CommandExecutor` to always resolve with a full
|
|
4
|
+
* `ShellResult`. Applies loose-return normalization and catches throws.
|
|
5
|
+
*/
|
|
6
|
+
function normalizeExecutor(executor) {
|
|
7
|
+
return async (args) => {
|
|
8
|
+
try {
|
|
9
|
+
const raw = await executor(args);
|
|
10
|
+
if (raw === void 0 || raw === null) return {
|
|
11
|
+
stdout: "",
|
|
12
|
+
stderr: "",
|
|
13
|
+
exitCode: 0
|
|
14
|
+
};
|
|
15
|
+
if (typeof raw === "string") return {
|
|
16
|
+
stdout: raw,
|
|
17
|
+
stderr: "",
|
|
18
|
+
exitCode: 0
|
|
19
|
+
};
|
|
20
|
+
return {
|
|
21
|
+
stdout: raw.stdout ?? "",
|
|
22
|
+
stderr: raw.stderr ?? "",
|
|
23
|
+
exitCode: raw.exitCode ?? 0
|
|
24
|
+
};
|
|
25
|
+
} catch (err) {
|
|
26
|
+
const e = err ?? {};
|
|
27
|
+
return {
|
|
28
|
+
stdout: typeof e.stdout === "string" ? e.stdout : "",
|
|
29
|
+
stderr: typeof e.stderr === "string" ? e.stderr : String(err),
|
|
30
|
+
exitCode: typeof e.code === "number" ? e.code : 1
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
//#endregion
|
|
37
|
+
export { normalizeExecutor as t };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as ShellOptions, D as TaskOptions, E as SkillOptions, O as ToolDef, S as SessionStore, T as Skill, _ as Role, a as BuildOptions, b as SessionEnv, c as CommandDef, d as FlueContext, f as FlueEvent, g as PromptResponse, h as PromptOptions, i as BuildContext, l as CommandSupport, m as FlueSession, n as AgentInfo, o as BuildPlugin, p as FlueEventCallback, r as BashLike, s as Command, t as AgentConfig, u as FileStat, v as SandboxFactory, w as ShellResult, x as SessionInit, y as SessionData } from "./types-
|
|
1
|
+
import { C as ShellOptions, D as TaskOptions, E as SkillOptions, O as ToolDef, S as SessionStore, T as Skill, _ as Role, a as BuildOptions, b as SessionEnv, c as CommandDef, d as FlueContext, f as FlueEvent, g as PromptResponse, h as PromptOptions, i as BuildContext, l as CommandSupport, m as FlueSession, n as AgentInfo, o as BuildPlugin, p as FlueEventCallback, r as BashLike, s as Command, t as AgentConfig, u as FileStat, v as SandboxFactory, w as ShellResult, x as SessionInit, y as SessionData } from "./types-BZPltYah.mjs";
|
|
2
2
|
import { AgentTool } from "@mariozechner/pi-agent-core";
|
|
3
3
|
|
|
4
4
|
//#region src/build.d.ts
|
package/dist/internal.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as SessionStore, y as SessionData } from "./types-
|
|
1
|
+
import { S as SessionStore, y as SessionData } from "./types-BZPltYah.mjs";
|
|
2
2
|
import { FlueContextConfig, FlueContextInternal, createFlueContext } from "./client.mjs";
|
|
3
3
|
import { bashToSessionEnv } from "./sandbox.mjs";
|
|
4
4
|
import "valibot";
|
package/dist/internal.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./agent-BYG0nVbQ.mjs";
|
|
2
|
-
import { t as InMemorySessionStore } from "./session-
|
|
2
|
+
import { t as InMemorySessionStore } from "./session-CiAMTsLZ.mjs";
|
|
3
3
|
import { bashToSessionEnv } from "./sandbox.mjs";
|
|
4
4
|
import { createFlueContext } from "./client.mjs";
|
|
5
5
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { s as Command } from "../types-BZPltYah.mjs";
|
|
2
|
+
import { t as CommandExecutor } from "../command-helpers-BPcSV93o.mjs";
|
|
3
|
+
import { execFile } from "node:child_process";
|
|
4
|
+
|
|
5
|
+
//#region src/node/define-command.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Options forwarded directly to Node's `child_process.execFile`. Full pass-through.
|
|
8
|
+
*/
|
|
9
|
+
type CommandOptions = NonNullable<Parameters<typeof execFile>[2]>;
|
|
10
|
+
declare function defineCommand(name: string): Command;
|
|
11
|
+
declare function defineCommand(name: string, options: CommandOptions): Command;
|
|
12
|
+
declare function defineCommand(name: string, execute: CommandExecutor): Command;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { type CommandOptions, defineCommand };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { t as normalizeExecutor } from "../command-helpers-CxRhK1my.mjs";
|
|
2
|
+
import { execFile } from "node:child_process";
|
|
3
|
+
import { promisify } from "node:util";
|
|
4
|
+
|
|
5
|
+
//#region src/node/define-command.ts
|
|
6
|
+
/**
|
|
7
|
+
* Node-specific `defineCommand`. Supports three forms:
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* defineCommand('agent-browser');
|
|
11
|
+
* defineCommand('gh', { env: { GH_TOKEN: process.env.GH_TOKEN } });
|
|
12
|
+
* defineCommand('gh', async (args) => ({ stdout: '...' }));
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* Forms A and B shell out via `child_process.execFile`. Form C lets the user
|
|
16
|
+
* implement the command however they like. All three forms benefit from
|
|
17
|
+
* return-shape normalization and throw-catching — no `try`/`catch` or
|
|
18
|
+
* `return { stdout, stderr, exitCode: 0 }` boilerplate required.
|
|
19
|
+
*/
|
|
20
|
+
const execFileAsync = promisify(execFile);
|
|
21
|
+
/**
|
|
22
|
+
* Essential, non-sensitive environment variables automatically forwarded to
|
|
23
|
+
* pass-through commands (forms A and B). Users can override any of these —
|
|
24
|
+
* or add their own (e.g. `GH_TOKEN`) — via `options.env`. Anything not listed
|
|
25
|
+
* here (API keys, tokens, secrets, etc.) stays on the host and is NEVER
|
|
26
|
+
* exposed to the spawned process unless the caller opts in explicitly.
|
|
27
|
+
*
|
|
28
|
+
* If you need full control over the env, use the function form:
|
|
29
|
+
* `defineCommand('gh', async (args) => { ... })`.
|
|
30
|
+
*/
|
|
31
|
+
const DEFAULT_ENV = {
|
|
32
|
+
PATH: process.env.PATH,
|
|
33
|
+
HOME: process.env.HOME,
|
|
34
|
+
USER: process.env.USER,
|
|
35
|
+
LOGNAME: process.env.LOGNAME,
|
|
36
|
+
HOSTNAME: process.env.HOSTNAME,
|
|
37
|
+
SHELL: process.env.SHELL,
|
|
38
|
+
LANG: process.env.LANG,
|
|
39
|
+
LC_ALL: process.env.LC_ALL,
|
|
40
|
+
LC_CTYPE: process.env.LC_CTYPE,
|
|
41
|
+
TZ: process.env.TZ,
|
|
42
|
+
TERM: process.env.TERM,
|
|
43
|
+
TMPDIR: process.env.TMPDIR,
|
|
44
|
+
TMP: process.env.TMP,
|
|
45
|
+
TEMP: process.env.TEMP
|
|
46
|
+
};
|
|
47
|
+
function defineCommand(name, arg) {
|
|
48
|
+
if (typeof arg === "function") return {
|
|
49
|
+
name,
|
|
50
|
+
execute: normalizeExecutor(arg)
|
|
51
|
+
};
|
|
52
|
+
const userOpts = arg ?? {};
|
|
53
|
+
const mergedOpts = {
|
|
54
|
+
maxBuffer: 50 * 1024 * 1024,
|
|
55
|
+
...userOpts,
|
|
56
|
+
env: {
|
|
57
|
+
...DEFAULT_ENV,
|
|
58
|
+
...userOpts.env ?? {}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const executor = async (args) => {
|
|
62
|
+
const { stdout, stderr } = await execFileAsync(name, args, mergedOpts);
|
|
63
|
+
return {
|
|
64
|
+
stdout: String(stdout ?? ""),
|
|
65
|
+
stderr: String(stderr ?? "")
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
return {
|
|
69
|
+
name,
|
|
70
|
+
execute: normalizeExecutor(executor)
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
//#endregion
|
|
75
|
+
export { defineCommand };
|
package/dist/sandbox.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as SessionEnv, c as CommandDef, r as BashLike, u as FileStat, v as SandboxFactory, w as ShellResult } from "./types-
|
|
1
|
+
import { b as SessionEnv, c as CommandDef, r as BashLike, u as FileStat, v as SandboxFactory, w as ShellResult } from "./types-BZPltYah.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/sandbox.d.ts
|
|
4
4
|
declare function bashToSessionEnv(bash: BashLike): SessionEnv;
|
package/dist/sandbox.mjs
CHANGED
|
@@ -508,11 +508,13 @@ var Session = class Session {
|
|
|
508
508
|
compactionAbortController;
|
|
509
509
|
eventCallback;
|
|
510
510
|
builtinTools;
|
|
511
|
-
|
|
511
|
+
sessionCommands;
|
|
512
|
+
constructor(id, config, env, store, existingData, onAgentEvent, sessionCommands) {
|
|
512
513
|
this.id = id;
|
|
513
514
|
this.config = config;
|
|
514
515
|
this.env = env;
|
|
515
516
|
this.store = store;
|
|
517
|
+
this.sessionCommands = sessionCommands ?? [];
|
|
516
518
|
this.metadata = existingData?.metadata ?? {};
|
|
517
519
|
this.createdAt = existingData?.createdAt;
|
|
518
520
|
this.lastCompaction = existingData?.lastCompaction;
|
|
@@ -586,8 +588,9 @@ var Session = class Session {
|
|
|
586
588
|
const promptWithRole = this.injectRoleInstructions(text, options?.role);
|
|
587
589
|
const schema = options?.result;
|
|
588
590
|
const fullPrompt = buildPromptText(promptWithRole, schema);
|
|
589
|
-
|
|
590
|
-
|
|
591
|
+
const effectiveCommands = this.mergeCommands(options?.commands);
|
|
592
|
+
if (effectiveCommands.length > 0) this.assertCommandSupport(effectiveCommands);
|
|
593
|
+
const registeredCommandNames = this.registerCommands(effectiveCommands);
|
|
591
594
|
const registeredToolNames = options?.tools ? this.registerCustomTools(options.tools) : [];
|
|
592
595
|
try {
|
|
593
596
|
await this.agent.prompt(fullPrompt);
|
|
@@ -616,8 +619,9 @@ var Session = class Session {
|
|
|
616
619
|
const schema = options?.result;
|
|
617
620
|
const skillPrompt = buildSkillPrompt(registeredSkill.instructions, options?.args, schema);
|
|
618
621
|
const promptWithRole = this.injectRoleInstructions(skillPrompt, options?.role);
|
|
619
|
-
|
|
620
|
-
|
|
622
|
+
const effectiveCommands = this.mergeCommands(options?.commands);
|
|
623
|
+
if (effectiveCommands.length > 0) this.assertCommandSupport(effectiveCommands);
|
|
624
|
+
const registeredCommandNames = this.registerCommands(effectiveCommands);
|
|
621
625
|
const registeredToolNames = options?.tools ? this.registerCustomTools(options.tools) : [];
|
|
622
626
|
try {
|
|
623
627
|
await this.agent.prompt(promptWithRole);
|
|
@@ -632,8 +636,9 @@ var Session = class Session {
|
|
|
632
636
|
}
|
|
633
637
|
}
|
|
634
638
|
async shell(command, options) {
|
|
635
|
-
|
|
636
|
-
|
|
639
|
+
const effectiveCommands = this.mergeCommands(options?.commands);
|
|
640
|
+
if (effectiveCommands.length > 0) this.assertCommandSupport(effectiveCommands);
|
|
641
|
+
const registeredNames = this.registerCommands(effectiveCommands);
|
|
637
642
|
try {
|
|
638
643
|
const result = await this.env.exec(command, {
|
|
639
644
|
env: options?.env,
|
|
@@ -750,6 +755,19 @@ var Session = class Session {
|
|
|
750
755
|
if (commands.length === 0) return;
|
|
751
756
|
if (!this.env.commandSupport) throw new Error("[flue] Cannot use commands: this environment does not support command registration. Commands are only available in isolate sandbox mode. Remote sandboxes handle command execution at the platform level.");
|
|
752
757
|
}
|
|
758
|
+
/**
|
|
759
|
+
* Merge session-wide `commands` (from init()) with per-call commands. When
|
|
760
|
+
* both define a command with the same name, the per-call entry wins for
|
|
761
|
+
* that call.
|
|
762
|
+
*/
|
|
763
|
+
mergeCommands(perCall) {
|
|
764
|
+
if (!perCall || perCall.length === 0) return this.sessionCommands;
|
|
765
|
+
if (this.sessionCommands.length === 0) return perCall;
|
|
766
|
+
const byName = /* @__PURE__ */ new Map();
|
|
767
|
+
for (const cmd of this.sessionCommands) byName.set(cmd.name, cmd);
|
|
768
|
+
for (const cmd of perCall) byName.set(cmd.name, cmd);
|
|
769
|
+
return Array.from(byName.values());
|
|
770
|
+
}
|
|
753
771
|
registerCommands(commands) {
|
|
754
772
|
if (!this.env.commandSupport || commands.length === 0) return [];
|
|
755
773
|
const names = [];
|
|
@@ -146,6 +146,13 @@ interface SessionInit {
|
|
|
146
146
|
* Precedence (highest wins): per-call `model` > role `model` > session `model` > build-time default.
|
|
147
147
|
*/
|
|
148
148
|
model?: string;
|
|
149
|
+
/**
|
|
150
|
+
* Session-wide commands. Every prompt(), skill(), and shell() call inherits
|
|
151
|
+
* this list. Per-call `commands` are merged on top — if a per-call command
|
|
152
|
+
* shares a name with a session command, the per-call version wins for that
|
|
153
|
+
* call.
|
|
154
|
+
*/
|
|
155
|
+
commands?: Command[];
|
|
149
156
|
}
|
|
150
157
|
interface FlueSession {
|
|
151
158
|
prompt<S extends v.GenericSchema>(text: string, options: PromptOptions<S> & {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flue/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"exports": {
|
|
@@ -23,6 +23,10 @@
|
|
|
23
23
|
"./cloudflare": {
|
|
24
24
|
"types": "./dist/cloudflare/index.d.mts",
|
|
25
25
|
"import": "./dist/cloudflare/index.mjs"
|
|
26
|
+
},
|
|
27
|
+
"./node": {
|
|
28
|
+
"types": "./dist/node/index.d.mts",
|
|
29
|
+
"import": "./dist/node/index.mjs"
|
|
26
30
|
}
|
|
27
31
|
},
|
|
28
32
|
"main": "./dist/index.mjs",
|