@fastagent-sh/fastagent 0.15.0 → 0.16.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 +13 -3
- package/dist/channels/agentcore-limits.d.ts +7 -0
- package/dist/channels/agentcore-limits.js +9 -0
- package/dist/channels/agentcore-state.d.ts +83 -0
- package/dist/channels/agentcore-state.js +258 -0
- package/dist/channels/agentcore.d.ts +98 -0
- package/dist/channels/agentcore.js +260 -0
- package/dist/channels/busy.d.ts +23 -0
- package/dist/channels/busy.js +53 -0
- package/dist/channels/context-buffer.d.ts +5 -0
- package/dist/channels/context-buffer.js +5 -0
- package/dist/channels/feishu/context-buffer.d.ts +13 -8
- package/dist/channels/feishu/context-buffer.js +60 -6
- package/dist/channels/feishu/feishu-api.js +4 -1
- package/dist/channels/feishu/feishu.d.ts +0 -12
- package/dist/channels/feishu/feishu.js +143 -54
- package/dist/channels/feishu/invoke-turn.js +35 -18
- package/dist/channels/feishu/model.d.ts +0 -1
- package/dist/channels/feishu/normalize.js +0 -1
- package/dist/channels/feishu/parse.d.ts +21 -7
- package/dist/channels/feishu/parse.js +24 -7
- package/dist/channels/feishu/preview.js +3 -2
- package/dist/channels/feishu/scaffold/channel.ts +9 -8
- package/dist/channels/feishu/scaffold/feishu-send.ts +6 -4
- package/dist/channels/feishu/setup-mode.d.ts +30 -1
- package/dist/channels/feishu/setup-mode.js +27 -1
- package/dist/channels/github/github.js +8 -1
- package/dist/channels/http.js +1 -1
- package/dist/channels/lark/scaffold/channel.ts +9 -8
- package/dist/channels/lark/scaffold/lark-send.ts +6 -4
- package/dist/channels/preview-kit.d.ts +7 -1
- package/dist/channels/preview-kit.js +3 -2
- package/dist/channels/slack/parse.d.ts +16 -1
- package/dist/channels/slack/parse.js +46 -3
- package/dist/channels/slack/preview.d.ts +1 -2
- package/dist/channels/slack/preview.js +68 -24
- package/dist/channels/slack/scaffold/channel.ts +5 -5
- package/dist/channels/slack/slack-api.d.ts +3 -23
- package/dist/channels/slack/slack-api.js +6 -22
- package/dist/channels/slack/slack.d.ts +13 -20
- package/dist/channels/slack/slack.js +95 -50
- package/dist/channels/state.d.ts +11 -4
- package/dist/channels/state.js +19 -12
- package/dist/channels/tasks.d.ts +0 -6
- package/dist/channels/tasks.js +16 -1
- package/dist/channels/telegram/parse.d.ts +0 -7
- package/dist/channels/telegram/parse.js +4 -2
- package/dist/channels/telegram/scaffold/telegram-send.ts +6 -3
- package/dist/channels/telegram/telegram.js +1 -1
- package/dist/channels/text.d.ts +14 -0
- package/dist/channels/text.js +14 -0
- package/dist/channels/thread-participants.d.ts +21 -0
- package/dist/channels/thread-participants.js +132 -0
- package/dist/channels/turn-queue.js +7 -0
- package/dist/cli/add-feishu.d.ts +7 -4
- package/dist/cli/add-feishu.js +57 -37
- package/dist/cli/add-slack.d.ts +2 -1
- package/dist/cli/add-slack.js +6 -11
- package/dist/cli/commands/add.js +50 -51
- package/dist/cli/commands/attach.js +8 -4
- package/dist/cli/commands/chat.js +8 -8
- package/dist/cli/commands/deploy.d.ts +1 -1
- package/dist/cli/commands/deploy.js +323 -77
- package/dist/cli/commands/dev.js +24 -22
- package/dist/cli/commands/fire.js +15 -16
- package/dist/cli/commands/info.js +36 -29
- package/dist/cli/commands/init.d.ts +1 -1
- package/dist/cli/commands/init.js +65 -53
- package/dist/cli/commands/invoke.js +9 -6
- package/dist/cli/commands/login.js +35 -21
- package/dist/cli/commands/schedule.js +6 -8
- package/dist/cli/commands/start.js +93 -37
- package/dist/cli/commands/tool.js +22 -18
- package/dist/cli/fail.d.ts +17 -0
- package/dist/cli/fail.js +24 -0
- package/dist/cli/program.js +57 -36
- package/dist/cli/serve.d.ts +26 -6
- package/dist/cli/serve.js +62 -15
- package/dist/cli/shared.d.ts +15 -2
- package/dist/cli/shared.js +30 -18
- package/dist/deploy/agentcore/plan.d.ts +117 -0
- package/dist/deploy/agentcore/plan.js +721 -0
- package/dist/deploy/agentcore/run.d.ts +73 -0
- package/dist/deploy/agentcore/run.js +412 -0
- package/dist/deploy/agentcore/zip.d.ts +17 -0
- package/dist/deploy/agentcore/zip.js +68 -0
- package/dist/deploy/container.d.ts +26 -25
- package/dist/deploy/container.js +93 -89
- package/dist/deploy/docker/plan.d.ts +1 -1
- package/dist/deploy/docker/plan.js +12 -17
- package/dist/deploy/fly/plan.d.ts +2 -0
- package/dist/deploy/fly/plan.js +27 -19
- package/dist/deploy/fly/run.d.ts +12 -1
- package/dist/deploy/fly/run.js +36 -2
- package/dist/deploy/preflight.d.ts +11 -5
- package/dist/deploy/preflight.js +217 -65
- package/dist/deploy/railway/plan.d.ts +7 -0
- package/dist/deploy/railway/plan.js +41 -16
- package/dist/deploy/railway/run.d.ts +8 -1
- package/dist/deploy/railway/run.js +7 -2
- package/dist/deploy/runner.d.ts +5 -2
- package/dist/deploy/runner.js +9 -3
- package/dist/dev-supervisor.d.ts +11 -8
- package/dist/dev-supervisor.js +53 -51
- package/dist/engines/pi/auth.d.ts +8 -7
- package/dist/engines/pi/auth.js +12 -10
- package/dist/engines/pi/channel.d.ts +1 -1
- package/dist/engines/pi/channel.js +5 -5
- package/dist/engines/pi/chat.js +2 -2
- package/dist/engines/pi/config.d.ts +6 -46
- package/dist/engines/pi/config.js +21 -108
- package/dist/engines/pi/create.d.ts +8 -8
- package/dist/engines/pi/create.js +13 -12
- package/dist/engines/pi/definition.d.ts +7 -26
- package/dist/engines/pi/definition.js +8 -54
- package/dist/engines/pi/login.d.ts +1 -1
- package/dist/engines/pi/models.d.ts +3 -3
- package/dist/engines/pi/models.js +1 -1
- package/dist/engines/pi/{workspace.d.ts → open.d.ts} +29 -23
- package/dist/engines/pi/{workspace.js → open.js} +27 -29
- package/dist/engines/pi/session-builder.d.ts +2 -2
- package/dist/engines/pi/session-builder.js +11 -11
- package/dist/engines/pi/tool.js +4 -0
- package/dist/env.d.ts +16 -4
- package/dist/env.js +43 -5
- package/dist/host/node.d.ts +2 -2
- package/dist/loader.d.ts +2 -2
- package/dist/loader.js +3 -3
- package/dist/log.d.ts +1 -1
- package/dist/log.js +1 -1
- package/dist/paths.d.ts +138 -0
- package/dist/paths.js +326 -0
- package/dist/pi.d.ts +1 -1
- package/dist/pi.js +2 -2
- package/dist/runtime.d.ts +7 -5
- package/dist/runtime.js +2 -2
- package/dist/scaffold/add-channel.d.ts +7 -3
- package/dist/scaffold/add-channel.js +55 -29
- package/dist/scaffold/init.d.ts +32 -41
- package/dist/scaffold/init.js +161 -185
- package/dist/scaffold/templates/env.example +15 -6
- package/dist/scaffold/templates/fastagent.config.mjs +1 -1
- package/dist/scaffold/templates/gitignore +14 -6
- package/dist/scaffold/templates/persona.md +4 -2
- package/dist/scaffold/templates/secrets.gitignore +5 -0
- package/dist/scaffold/templates.d.ts +1 -7
- package/dist/scaffold/templates.js +3 -25
- package/dist/scaffold/vendor-skill.d.ts +2 -2
- package/dist/scaffold/vendor-skill.js +13 -13
- package/dist/schedule/discover.js +4 -4
- package/dist/schedule/scheduler.d.ts +40 -1
- package/dist/schedule/scheduler.js +89 -56
- package/dist/schedule/state.js +1 -1
- package/dist/schedule/wake-alarm.d.ts +47 -0
- package/dist/schedule/wake-alarm.js +136 -0
- package/dist/schedule/wakeups.d.ts +1 -0
- package/dist/schedule/wakeups.js +18 -0
- package/dist/tunnel.d.ts +3 -3
- package/dist/tunnel.js +7 -7
- package/package.json +4 -1
- package/dist/channels/feishu/owned-threads.d.ts +0 -7
- package/dist/channels/feishu/owned-threads.js +0 -47
- package/dist/channels/slack/owned-threads.d.ts +0 -6
- package/dist/channels/slack/owned-threads.js +0 -43
- package/dist/scaffold/templates/gitignore.agentdir-root +0 -5
- package/dist/scaffold/templates/gitignore.kit +0 -2
- package/dist/workspace.d.ts +0 -9
- package/dist/workspace.js +0 -45
|
@@ -13,11 +13,11 @@ export declare function piDefaultTools(cwd: string): AgentTool[];
|
|
|
13
13
|
/** `config.tools` semantics: extra tools APPENDED after pi's defaults, never replacing them. */
|
|
14
14
|
export declare function resolveTools(config: FastagentConfig, cwd: string): AgentTool[];
|
|
15
15
|
/**
|
|
16
|
-
* The full tool set
|
|
16
|
+
* The full tool set an agent mounts: pi defaults + `config.tools` + discovered `tools/` (deduped,
|
|
17
17
|
* existing win), plus the non-default tool names and collisions to report. One source for the
|
|
18
18
|
* dev/start openers AND `fastagent tool`, so they all mount exactly the same set.
|
|
19
19
|
*/
|
|
20
|
-
export declare function
|
|
20
|
+
export declare function resolveAgentTools(config: FastagentConfig, agentDir: string, cwd?: string): Promise<{
|
|
21
21
|
tools: AgentTool[];
|
|
22
22
|
toolNames: string[];
|
|
23
23
|
/** Tools registered but not initially active (defineTool `deferred: true`) — discovered/activated
|
|
@@ -86,8 +86,8 @@ export interface CreatePiAgentOptions {
|
|
|
86
86
|
*/
|
|
87
87
|
providers?: Provider[];
|
|
88
88
|
/**
|
|
89
|
-
* Credentials file for stored OAuth/API-key auth. Defaults to `~/.fastagent/auth.json`; the
|
|
90
|
-
* directory opener passes the project-level `<
|
|
89
|
+
* Credentials file for stored OAuth/API-key auth. Defaults to `~/.fastagent/.secrets/auth.json`; the
|
|
90
|
+
* directory opener passes the project-level `<root>/.secrets/auth.json` instead. Env vars are still
|
|
91
91
|
* consulted when a provider is absent from the file (resolution order is upstream-owned).
|
|
92
92
|
*/
|
|
93
93
|
authPath?: string;
|
|
@@ -121,16 +121,16 @@ export interface CreatePiAgentFromDefinitionOptions {
|
|
|
121
121
|
tools?: FastagentTool[];
|
|
122
122
|
/**
|
|
123
123
|
* The agent's working directory: where the default tools operate AND whose ancestors are walked for
|
|
124
|
-
* ② project context (AGENTS.md). Defaults to `dir
|
|
125
|
-
*
|
|
126
|
-
*
|
|
124
|
+
* ② project context (AGENTS.md). Defaults to `dir`. Set it to the enclosing repo so a coding agent
|
|
125
|
+
* whose definition lives in `dir` operates on — and reads the AGENTS.md of — that repo (core.md
|
|
126
|
+
* scenario grid); that is what the CLI's opener does with the workspace.
|
|
127
127
|
*/
|
|
128
128
|
cwd?: string;
|
|
129
129
|
/** Extra providers registered on top of the built-ins (your own gateway / self-hosted endpoint). */
|
|
130
130
|
providers?: Provider[];
|
|
131
131
|
/**
|
|
132
132
|
* Credentials file (see {@link CreatePiAgentOptions.authPath}). Being dir-aware, this rung defaults
|
|
133
|
-
* to the PROJECT-level `<dir>/.
|
|
133
|
+
* to the PROJECT-level `<dir>/.secrets/auth.json` (matching `fastagent dev`/`start` on the same
|
|
134
134
|
* dir) — unlike the dir-less {@link createPiAgent}/{@link createPiModels}, which default global.
|
|
135
135
|
*/
|
|
136
136
|
authPath?: string;
|
|
@@ -6,14 +6,15 @@
|
|
|
6
6
|
* L1 createPiAgent(options) — assemble from typed parts (the canonical ctor).
|
|
7
7
|
* L0 createPiAgentFromHarness({ harnessFactory }) — in invoke.ts (its body is the turn mechanism).
|
|
8
8
|
*
|
|
9
|
-
* Above L2 sits the
|
|
9
|
+
* Above L2 sits the agent opener createPiAgentFromDir (open.ts), which both `dev` and
|
|
10
10
|
* `start` drive. Each rung calls the one below; options narrow as you go up (L2 owns systemPrompt/skills —
|
|
11
11
|
* they come from the definition; the openers own model/tools — from config resolution).
|
|
12
12
|
*/
|
|
13
13
|
import { formatSkillsForSystemPrompt } from "@earendil-works/pi-agent-core";
|
|
14
14
|
import { NodeExecutionEnv } from "@earendil-works/pi-agent-core/node";
|
|
15
15
|
import { createCodingTools } from "@earendil-works/pi-coding-agent";
|
|
16
|
-
import { defaultAuthPath, resolveModel
|
|
16
|
+
import { defaultAuthPath, resolveModel } from "./config.js";
|
|
17
|
+
import { resolveSecretsDir } from "../../paths.js";
|
|
17
18
|
import { loadAgentDefinition } from "./definition.js";
|
|
18
19
|
import { piHarnessFactory } from "./harness.js";
|
|
19
20
|
import { createPiModels } from "./models.js";
|
|
@@ -37,18 +38,18 @@ export function resolveTools(config, cwd) {
|
|
|
37
38
|
return config.tools ? [...defaults, ...config.tools] : defaults;
|
|
38
39
|
}
|
|
39
40
|
/**
|
|
40
|
-
* The full tool set
|
|
41
|
+
* The full tool set an agent mounts: pi defaults + `config.tools` + discovered `tools/` (deduped,
|
|
41
42
|
* existing win), plus the non-default tool names and collisions to report. One source for the
|
|
42
43
|
* dev/start openers AND `fastagent tool`, so they all mount exactly the same set.
|
|
43
44
|
*/
|
|
44
|
-
export async function
|
|
45
|
-
// Default coding tools (read/bash/edit/write) are rooted at `cwd` (the
|
|
46
|
-
// discovered `tools/` come from `agentDir` (the agent's own surface).
|
|
45
|
+
export async function resolveAgentTools(config, agentDir, cwd = agentDir) {
|
|
46
|
+
// Default coding tools (read/bash/edit/write) are rooted at `cwd` (the workspace the agent operates
|
|
47
|
+
// on); discovered `tools/` come from `agentDir` (the agent's own surface).
|
|
47
48
|
const discovered = await loadTools(agentDir);
|
|
48
49
|
const merged = mergeDiscoveredTools(resolveTools(config, cwd), discovered.tools);
|
|
49
|
-
// The built-in `search_tools` loader mounts here — the one place the
|
|
50
|
-
// computed — so `dev`/`start`/`info`/`fastagent tool` all see the same surface (idempotent;
|
|
51
|
-
//
|
|
50
|
+
// The built-in `search_tools` loader mounts here — the one place the agent's full tool set is
|
|
51
|
+
// computed — so `dev`/`start`/`info`/`fastagent tool` all see the same surface (idempotent; an
|
|
52
|
+
// agent-defined search_tools wins).
|
|
52
53
|
const tools = withSearchTool(merged.tools);
|
|
53
54
|
// Builtin = a search_tools that was ABSENT before withSearchTool (a reference compare would misfire
|
|
54
55
|
// on the deferred-authored-loader case, where withSearchTool returns a new array without adding one).
|
|
@@ -98,7 +99,7 @@ export function piBasePrompt(options = {}) {
|
|
|
98
99
|
const deferredCount = mounted.length - tools.length;
|
|
99
100
|
const toolsList = tools.length > 0 ? tools.map((t) => `- ${t.name}: ${(t.description ?? "").split("\n")[0]}`).join("\n") : "(none)";
|
|
100
101
|
// Segment ① identity: an authored persona (persona.md) replaces the default engine identity line
|
|
101
|
-
// (
|
|
102
|
+
// (core.md §11), keeping the tools list + guidelines below.
|
|
102
103
|
const identity = options.persona?.trim() ||
|
|
103
104
|
"You are an expert coding assistant operating inside pi, a coding agent harness. You help users by reading files, executing commands, editing code, and writing new files.";
|
|
104
105
|
const deferredNote = deferredCount > 0
|
|
@@ -220,9 +221,9 @@ export async function createPiAgentFromDefinition(dir, options) {
|
|
|
220
221
|
model: options.model,
|
|
221
222
|
thinkingLevel: options.thinkingLevel,
|
|
222
223
|
providers: options.providers,
|
|
223
|
-
// Dir-aware default: the same
|
|
224
|
+
// Dir-aware default: the same secrets-dir-derived file the opener uses for this dir (the opener
|
|
224
225
|
// passes an explicit authPath, so this only affects direct L2 callers).
|
|
225
|
-
authPath: options.authPath ?? defaultAuthPath(
|
|
226
|
+
authPath: options.authPath ?? defaultAuthPath(resolveSecretsDir(dir)),
|
|
226
227
|
// The directory is the agent, LIVE: re-read the definition on every invoke, so AGENTS.md/skills
|
|
227
228
|
// edits (the author's, or the agent's own self-modification) take effect on the next turn with
|
|
228
229
|
// no process restart — restarts are reserved for code (tools/channels/config, module cache).
|
|
@@ -32,9 +32,9 @@ export interface LoadedDefinition {
|
|
|
32
32
|
}
|
|
33
33
|
export interface LoadAgentDefinitionOptions {
|
|
34
34
|
/**
|
|
35
|
-
* Working directory whose ancestors are walked for context files (segment ②). Default = `agentDir
|
|
36
|
-
*
|
|
37
|
-
*
|
|
35
|
+
* Working directory whose ancestors are walked for context files (segment ②). Default = `agentDir`.
|
|
36
|
+
* The opener passes the workspace instead, so an agent that lives in `agentDir` picks up the
|
|
37
|
+
* project's AGENTS.md up the tree (core.md scenario grid).
|
|
38
38
|
*/
|
|
39
39
|
cwd?: string;
|
|
40
40
|
env?: ExecutionEnv;
|
|
@@ -42,31 +42,12 @@ export interface LoadAgentDefinitionOptions {
|
|
|
42
42
|
/** Read an agent definition. persona.md/skills come from `agentDir`; ② context = pi's loadProjectContextFiles({ cwd, agentDir }). */
|
|
43
43
|
export declare function loadAgentDefinition(agentDir: string, options?: LoadAgentDefinitionOptions): Promise<LoadedDefinition>;
|
|
44
44
|
/**
|
|
45
|
-
* Whether `targetPath` lives inside `baseDir` (same path counts).
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* the tree). Whether a relative override lands in-tree is a cwd question — see `resolveStateRoot`.
|
|
45
|
+
* Whether `targetPath` lives inside `baseDir` (same path counts). Used to ask "did an override move
|
|
46
|
+
* this OUT of the agent?" — the startup report's redeploy notes, `add`'s printed `.env` label, and the
|
|
47
|
+
* dev watcher's "your .env is not watched" warning all turn on that fact. Reporting only: fastagent
|
|
48
|
+
* does not act on where a user's paths point.
|
|
50
49
|
*/
|
|
51
50
|
export declare function isUnderDir(targetPath: string, baseDir: string): boolean;
|
|
52
|
-
/**
|
|
53
|
-
* The single owner of the self-ignore MECHANISM: iff the resolved state ROOT lands inside the workspace
|
|
54
|
-
* tree, write `<stateRoot>/.gitignore="*"` — which then covers EVERYTHING under it (sessions, auth.json,
|
|
55
|
-
* every channel's `channels/<kind>` home). `ensureStateDirSelfIgnored` is private, so a caller cannot
|
|
56
|
-
* write a `.gitignore` bypassing this.
|
|
57
|
-
*
|
|
58
|
-
* ROOT-based, not path-based: everything derives from the state root (config.ts), so protecting the
|
|
59
|
-
* root protects all of it — INCLUDING a custom in-tree root (a `FASTAGENT_STATE_DIR` inside the agent
|
|
60
|
-
* dir), the case a path-based (`.fastagent`-only) guard would leak. A per-path override
|
|
61
|
-
* (`--sessions-dir`/`--auth-path`) is operator-owned: pointed at an external volume it is out-of-tree
|
|
62
|
-
* (correctly not ours to ignore); pointed at a custom in-tree dir WE DON'T OWN, we do not write a
|
|
63
|
-
* `.gitignore` into it (it may be a directory the operator deliberately tracks).
|
|
64
|
-
*
|
|
65
|
-
* Excludes the user's HOME-global `~/.fastagent` (e.g. `login`/`dev` run from `$HOME`): self-ignore is
|
|
66
|
-
* for protecting state inside an agent PROJECT tree, not for writing a `.gitignore` into the user's
|
|
67
|
-
* home, which a dotfiles repo may track. The global credential file there was never self-ignored.
|
|
68
|
-
*/
|
|
69
|
-
export declare function ensureStateRootSelfIgnored(dir: string, stateRoot: string): Promise<void>;
|
|
70
51
|
/** Resolve to a canonical (symlink-free) absolute path so comparisons match `process.cwd()`'s realpath.
|
|
71
52
|
* A non-existent path can't be realpath'd, so it stays as the plain absolute resolve. */
|
|
72
53
|
export declare function canonicalPath(p: string): string;
|
|
@@ -14,12 +14,11 @@
|
|
|
14
14
|
* (bad skill files, name collisions) are returned as data. An unreadable ② context file only warns (pi).
|
|
15
15
|
*/
|
|
16
16
|
import { realpathSync } from "node:fs";
|
|
17
|
-
import { mkdir, writeFile } from "node:fs/promises";
|
|
18
|
-
import { homedir } from "node:os";
|
|
19
17
|
import { isAbsolute, join, relative, resolve } from "node:path";
|
|
20
18
|
import { loadSkills } from "@earendil-works/pi-agent-core";
|
|
21
19
|
import { NodeExecutionEnv } from "@earendil-works/pi-agent-core/node";
|
|
22
20
|
import { loadProjectContextFiles } from "@earendil-works/pi-coding-agent";
|
|
21
|
+
import { assertInsideAgentDir } from "../../paths.js";
|
|
23
22
|
/** Read an agent definition. persona.md/skills come from `agentDir`; ② context = pi's loadProjectContextFiles({ cwd, agentDir }). */
|
|
24
23
|
export async function loadAgentDefinition(agentDir, options = {}) {
|
|
25
24
|
// One resolved default for the working directory (env cwd AND the context-walk start), so they can
|
|
@@ -44,7 +43,9 @@ export async function loadAgentDefinition(agentDir, options = {}) {
|
|
|
44
43
|
}
|
|
45
44
|
const persona = personaRead.ok ? personaRead.value : undefined;
|
|
46
45
|
// Skills come ONLY from the definition's own skills/ (no external/global mount), so the same
|
|
47
|
-
// definition loads the same skills on every machine
|
|
46
|
+
// definition loads the same skills on every machine — and, like tools/channels/schedules, a symlink
|
|
47
|
+
// that escapes the agent dir is refused rather than followed (the fourth of four surfaces).
|
|
48
|
+
await assertInsideAgentDir(root, "skills");
|
|
48
49
|
const { skills: raw, diagnostics } = await loadSkills(e, [join(root, "skills")]);
|
|
49
50
|
const byName = new Map();
|
|
50
51
|
const collisions = [];
|
|
@@ -60,62 +61,15 @@ export async function loadAgentDefinition(agentDir, options = {}) {
|
|
|
60
61
|
return { contextFiles, persona, skills: [...byName.values()], diagnostics, collisions, dir: root };
|
|
61
62
|
}
|
|
62
63
|
/**
|
|
63
|
-
* Whether `targetPath` lives inside `baseDir` (same path counts).
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
* the tree). Whether a relative override lands in-tree is a cwd question — see `resolveStateRoot`.
|
|
64
|
+
* Whether `targetPath` lives inside `baseDir` (same path counts). Used to ask "did an override move
|
|
65
|
+
* this OUT of the agent?" — the startup report's redeploy notes, `add`'s printed `.env` label, and the
|
|
66
|
+
* dev watcher's "your .env is not watched" warning all turn on that fact. Reporting only: fastagent
|
|
67
|
+
* does not act on where a user's paths point.
|
|
68
68
|
*/
|
|
69
69
|
export function isUnderDir(targetPath, baseDir) {
|
|
70
70
|
const rel = relative(baseDir, targetPath);
|
|
71
71
|
return rel === "" || (!rel.startsWith("..") && !isAbsolute(rel));
|
|
72
72
|
}
|
|
73
|
-
/**
|
|
74
|
-
* Self-ignore a state dir: create it if missing, then write `<stateDir>/.gitignore` = "*" (idempotent
|
|
75
|
-
* — an existing one is kept), so a workspace that runs dev/start never shows machine state as
|
|
76
|
-
* untracked. Creates the dir because a caller may self-ignore it before anything else populates it
|
|
77
|
-
* (e.g. `login` writing auth.json into a not-yet-created root).
|
|
78
|
-
*
|
|
79
|
-
* Module-PRIVATE on purpose: the only entry to the leak guard is {@link ensureStateRootSelfIgnored}
|
|
80
|
-
* (home exclusion + containment). Keeping this unexported makes that single-owner claim hold at the
|
|
81
|
-
* type level — a sibling command can't bypass those checks by writing a `.gitignore` directly.
|
|
82
|
-
*/
|
|
83
|
-
async function ensureStateDirSelfIgnored(stateDir) {
|
|
84
|
-
await mkdir(stateDir, { recursive: true });
|
|
85
|
-
await writeFile(join(stateDir, ".gitignore"), "*\n", { flag: "wx" }).catch((e) => {
|
|
86
|
-
if (e.code !== "EEXIST")
|
|
87
|
-
throw e;
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* The single owner of the self-ignore MECHANISM: iff the resolved state ROOT lands inside the workspace
|
|
92
|
-
* tree, write `<stateRoot>/.gitignore="*"` — which then covers EVERYTHING under it (sessions, auth.json,
|
|
93
|
-
* every channel's `channels/<kind>` home). `ensureStateDirSelfIgnored` is private, so a caller cannot
|
|
94
|
-
* write a `.gitignore` bypassing this.
|
|
95
|
-
*
|
|
96
|
-
* ROOT-based, not path-based: everything derives from the state root (config.ts), so protecting the
|
|
97
|
-
* root protects all of it — INCLUDING a custom in-tree root (a `FASTAGENT_STATE_DIR` inside the agent
|
|
98
|
-
* dir), the case a path-based (`.fastagent`-only) guard would leak. A per-path override
|
|
99
|
-
* (`--sessions-dir`/`--auth-path`) is operator-owned: pointed at an external volume it is out-of-tree
|
|
100
|
-
* (correctly not ours to ignore); pointed at a custom in-tree dir WE DON'T OWN, we do not write a
|
|
101
|
-
* `.gitignore` into it (it may be a directory the operator deliberately tracks).
|
|
102
|
-
*
|
|
103
|
-
* Excludes the user's HOME-global `~/.fastagent` (e.g. `login`/`dev` run from `$HOME`): self-ignore is
|
|
104
|
-
* for protecting state inside an agent PROJECT tree, not for writing a `.gitignore` into the user's
|
|
105
|
-
* home, which a dotfiles repo may track. The global credential file there was never self-ignored.
|
|
106
|
-
*/
|
|
107
|
-
export async function ensureStateRootSelfIgnored(dir, stateRoot) {
|
|
108
|
-
// Compare CANONICAL paths for the home check: `dir` arrives realpath-resolved (it is `process.cwd()`
|
|
109
|
-
// or `resolve(".")`) but `homedir()` returns the raw `$HOME`, so a symlinked home would slip past raw
|
|
110
|
-
// equality and we'd write a `.gitignore` into the real `~/.fastagent` — the very thing the doc forbids
|
|
111
|
-
// (chat.ts canonicalizes for the same reason).
|
|
112
|
-
if (canonicalPath(dir) === canonicalPath(homedir()))
|
|
113
|
-
return;
|
|
114
|
-
// Containment on RAW paths: stateRoot is resolve()'d (config.ts) and `dir` is absolute, so it is exact
|
|
115
|
-
// by construction. An external-volume root resolves outside the tree → skip (not ours to ignore).
|
|
116
|
-
if (isUnderDir(stateRoot, dir))
|
|
117
|
-
await ensureStateDirSelfIgnored(stateRoot);
|
|
118
|
-
}
|
|
119
73
|
/** Resolve to a canonical (symlink-free) absolute path so comparisons match `process.cwd()`'s realpath.
|
|
120
74
|
* A non-existent path can't be realpath'd, so it stays as the plain absolute resolve. */
|
|
121
75
|
export function canonicalPath(p) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `fastagent login`: authenticate a MODEL PROVIDER into the resolved auth file (project-level
|
|
3
|
-
* `<
|
|
3
|
+
* `<root>/.secrets/auth.json` by default, or `--auth-path`/`FASTAGENT_AUTH_PATH`) via the same
|
|
4
4
|
* {@link fastagentCredentialStore} the runtime uses (one writer, one lock/corruption semantics).
|
|
5
5
|
*
|
|
6
6
|
* Flow (pi-ai's unified `ProviderAuth` API): pick a method (OAuth or API key), then a provider that
|
|
@@ -9,8 +9,8 @@ import { ModelRuntime } from "@earendil-works/pi-coding-agent";
|
|
|
9
9
|
import { type FastagentAuthOptions } from "./auth.ts";
|
|
10
10
|
import { type InteractiveLoginKind } from "./login.ts";
|
|
11
11
|
export interface CreatePiModelsOptions extends FastagentAuthOptions {
|
|
12
|
-
/** Credentials file path. Defaults to the global `~/.fastagent/auth.json`; the directory opener passes
|
|
13
|
-
* the project-level `<
|
|
12
|
+
/** Credentials file path. Defaults to the global `~/.fastagent/.secrets/auth.json`; the directory opener passes
|
|
13
|
+
* the project-level `<root>/.secrets/auth.json`. */
|
|
14
14
|
authPath?: string;
|
|
15
15
|
/** Extra providers registered on top of the built-ins (same id overrides a built-in). */
|
|
16
16
|
providers?: Provider[];
|
|
@@ -18,7 +18,7 @@ export interface CreatePiModelsOptions extends FastagentAuthOptions {
|
|
|
18
18
|
/**
|
|
19
19
|
* A `Models` with every built-in pi provider, wired to fastagent's auth: stored credentials from the
|
|
20
20
|
* {@link CreatePiModelsOptions.authPath} file (via {@link fastagentCredentialStore}; the global
|
|
21
|
-
* `~/.fastagent/auth.json` unless the opener passes a project-level path), then ambient env vars. A
|
|
21
|
+
* `~/.fastagent/.secrets/auth.json` unless the opener passes a project-level path), then ambient env vars. A
|
|
22
22
|
* stored credential owns the provider; env is consulted only when nothing is stored (resolution order
|
|
23
23
|
* is upstream-owned).
|
|
24
24
|
*/
|
|
@@ -12,7 +12,7 @@ import { interactiveLoginKind } from "./login.js";
|
|
|
12
12
|
/**
|
|
13
13
|
* A `Models` with every built-in pi provider, wired to fastagent's auth: stored credentials from the
|
|
14
14
|
* {@link CreatePiModelsOptions.authPath} file (via {@link fastagentCredentialStore}; the global
|
|
15
|
-
* `~/.fastagent/auth.json` unless the opener passes a project-level path), then ambient env vars. A
|
|
15
|
+
* `~/.fastagent/.secrets/auth.json` unless the opener passes a project-level path), then ambient env vars. A
|
|
16
16
|
* stored credential owns the provider; env is consulted only when nothing is stored (resolution order
|
|
17
17
|
* is upstream-owned).
|
|
18
18
|
*/
|
|
@@ -5,21 +5,21 @@ import type { SessionControl } from "../../session.ts";
|
|
|
5
5
|
import type { SessionObserver } from "./invoke.ts";
|
|
6
6
|
import type { PiSessionReader, PiSessionStore } from "./sessions.ts";
|
|
7
7
|
import type { ModuleLoadFailure } from "../../loader.ts";
|
|
8
|
-
import {
|
|
8
|
+
import type { LoadedDefinition } from "./definition.ts";
|
|
9
9
|
import type { ToolCollision } from "./tool.ts";
|
|
10
|
-
export interface
|
|
10
|
+
export interface CreatePiAgentFromDirOptions {
|
|
11
11
|
/** Model spec override (e.g. the CLI --model flag). Precedence: this > FASTAGENT_MODEL > config.model. */
|
|
12
12
|
model?: string;
|
|
13
13
|
/**
|
|
14
|
-
* Session store directory. Default `<
|
|
14
|
+
* Session store directory. Default `<agentDir>/.state/sessions` (machine state). `start`
|
|
15
15
|
* overrides it (--sessions-dir / FASTAGENT_SESSIONS_DIR / a mounted volume) so production continuity
|
|
16
16
|
* survives redeploys.
|
|
17
17
|
*/
|
|
18
18
|
sessionsDir?: string;
|
|
19
19
|
/**
|
|
20
|
-
* Credentials file override. Default `<
|
|
21
|
-
*
|
|
22
|
-
* `~/.fastagent/auth.json` to share one credential across projects.
|
|
20
|
+
* Credentials file override. Default `<agentDir>/.secrets/auth.json` (project-level, under the
|
|
21
|
+
* `.secrets/`). Override via --auth-path / FASTAGENT_AUTH_PATH; point it at
|
|
22
|
+
* the global `~/.fastagent/.secrets/auth.json` to share one credential across projects.
|
|
23
23
|
*/
|
|
24
24
|
authPath?: string;
|
|
25
25
|
/**
|
|
@@ -28,7 +28,7 @@ export interface CreatePiAgentFromWorkspaceOptions {
|
|
|
28
28
|
* and never poll). The built-in `wake` tool mounts only when this is set AND `config.selfSchedule` is on.
|
|
29
29
|
*/
|
|
30
30
|
serving?: boolean;
|
|
31
|
-
/** Assemble the session control plane over this
|
|
31
|
+
/** Assemble the session control plane over this agent's session store and return it as
|
|
32
32
|
* {@link sessionControl} — the store is created inside this opener, so the hub must be wired
|
|
33
33
|
* here too (an external `createPiSessionControl` cannot exist before the store does).
|
|
34
34
|
* Default: `config.sessionControl` AND {@link serving} — the config key means "serve the control
|
|
@@ -43,24 +43,27 @@ export interface CreatePiAgentFromWorkspaceOptions {
|
|
|
43
43
|
observer?: SessionObserver;
|
|
44
44
|
}
|
|
45
45
|
/**
|
|
46
|
-
* The
|
|
46
|
+
* The agent assembly FRONT HALF — everything that is independent of how pi consumes the
|
|
47
47
|
* definition (transient harness for serving vs resident AgentSession for chat / session control):
|
|
48
|
-
* config → model spec →
|
|
49
|
-
* place it is computed) → state root → auth path. Both {@link
|
|
48
|
+
* placement resolution → config → model spec → the full tool surface ({@link resolveAgentTools} — the
|
|
49
|
+
* ONE place it is computed) → state root → auth path. Both {@link createPiAgentFromDir} and the
|
|
50
50
|
* session builder (session-builder.ts) consume this, so THESE inputs cannot drift between the two
|
|
51
51
|
* consumption shapes. (Definition loading and prompt assembly stay per-consumer: serving re-reads
|
|
52
52
|
* them live per invoke, the session builder snapshots at startup and lets pi append skills/env.)
|
|
53
53
|
*/
|
|
54
|
-
export interface
|
|
54
|
+
export interface AgentAssembly {
|
|
55
55
|
config: FastagentConfig;
|
|
56
56
|
configPath?: string;
|
|
57
57
|
/** The resolved "provider/modelId" spec in use. */
|
|
58
58
|
modelSpec: string;
|
|
59
|
-
/** Absolute agent
|
|
59
|
+
/** Absolute agent dir — definition + config + machinery live here (resolvePlacement().agentDir). */
|
|
60
60
|
agentDir: string;
|
|
61
|
-
/** Absolute
|
|
61
|
+
/** Absolute workspace — the agent's cwd and the start of the ②-context walk: the agent dir's parent
|
|
62
|
+
* when the agent sits inside it, the agent dir ITSELF when you point at the agent. */
|
|
63
|
+
workspace: string;
|
|
64
|
+
/** Absolute state root (FASTAGENT_STATE_DIR > <agentDir>/.state). */
|
|
62
65
|
stateRoot: string;
|
|
63
|
-
/** Absolute credentials file (--auth-path/authPath option > FASTAGENT_AUTH_PATH > <
|
|
66
|
+
/** Absolute credentials file (--auth-path/authPath option > FASTAGENT_AUTH_PATH > <agentDir>/.secrets/auth.json). */
|
|
64
67
|
authPath: string;
|
|
65
68
|
/** The full mounted tool surface (config.tools + discovered tools/, search_tools applied). */
|
|
66
69
|
tools: AgentTool[];
|
|
@@ -69,25 +72,28 @@ export interface WorkspaceAssembly {
|
|
|
69
72
|
toolCollisions: ToolCollision[];
|
|
70
73
|
toolFailures: ModuleLoadFailure[];
|
|
71
74
|
}
|
|
72
|
-
export declare function
|
|
75
|
+
export declare function resolveAgentAssembly(dir: string, options?: {
|
|
73
76
|
model?: string;
|
|
74
77
|
authPath?: string;
|
|
75
|
-
}): Promise<
|
|
78
|
+
}): Promise<AgentAssembly>;
|
|
76
79
|
/**
|
|
77
|
-
* "Point at a
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
+
* "Point at a directory → agent": resolve the placement (`dir` may be either end — the workspace or
|
|
81
|
+
* the agent dir itself), load the config, resolve model and tools, then L2. Throws a clear error when
|
|
82
|
+
* no model source is set (fail visibly at startup). Returns everything an entry point needs to report
|
|
83
|
+
* what it assembled.
|
|
80
84
|
*/
|
|
81
|
-
export declare function
|
|
85
|
+
export declare function createPiAgentFromDir(dir: string, options?: CreatePiAgentFromDirOptions): Promise<{
|
|
82
86
|
agent: Agent;
|
|
83
87
|
definition: LoadedDefinition;
|
|
84
88
|
config: FastagentConfig;
|
|
85
89
|
configPath?: string;
|
|
86
90
|
/** The resolved "provider/modelId" spec actually in use. */
|
|
87
91
|
modelSpec: string;
|
|
88
|
-
/** Absolute agent
|
|
92
|
+
/** Absolute agent dir in use — channels/tools/persona come from here. */
|
|
89
93
|
agentDir: string;
|
|
90
|
-
/** Absolute
|
|
94
|
+
/** Absolute workspace in use — the agent's cwd: ALWAYS the directory that was pointed at. */
|
|
95
|
+
workspace: string;
|
|
96
|
+
/** Absolute state root in use (FASTAGENT_STATE_DIR > <agentDir>/.state) — the ChannelContext's stateRoot. */
|
|
91
97
|
stateRoot: string;
|
|
92
98
|
/** Absolute session store directory in use (for the startup report). */
|
|
93
99
|
sessionsDir: string;
|
|
@@ -95,7 +101,7 @@ export declare function createPiAgentFromWorkspace(dir: string, options?: Create
|
|
|
95
101
|
authPath: string;
|
|
96
102
|
/** The session store in use — also a {@link PiSessionReader}. */
|
|
97
103
|
sessions: PiSessionStore & PiSessionReader;
|
|
98
|
-
/** The observation plane over this
|
|
104
|
+
/** The observation plane over this agent's sessions; present iff `options.sessionControl`. */
|
|
99
105
|
sessionControl?: SessionControl;
|
|
100
106
|
/** Non-default, active-by-default tool names in effect: config.tools + discovered tools/. Each name
|
|
101
107
|
* lives in exactly one report slot — deferred names are in {@link deferredToolNames} instead. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Open a definition directory into an agent — the single
|
|
2
|
+
* Open a definition directory into an agent — the single agent opener BOTH `fastagent dev` and
|
|
3
3
|
* `fastagent start` drive.
|
|
4
4
|
*
|
|
5
5
|
* A thin command-posture composition over L2 `createPiAgentFromDefinition`: open the directory →
|
|
@@ -9,39 +9,35 @@
|
|
|
9
9
|
* watch and can point sessions at a mounted volume.
|
|
10
10
|
*/
|
|
11
11
|
import { mkdir } from "node:fs/promises";
|
|
12
|
-
import { defaultSessionsDir, loadConfig,
|
|
13
|
-
import {
|
|
12
|
+
import { defaultSessionsDir, loadConfig, resolveAuthPath, resolveModelSpec, } from "./config.js";
|
|
13
|
+
import { resolveStateRoot, resolvePlacement } from "../../paths.js";
|
|
14
|
+
import { createPiAgentFromDefinition, resolveAgentTools } from "./create.js";
|
|
14
15
|
import { createPiSessionControl } from "./session-control.js";
|
|
15
16
|
import { withWakeTool } from "./wake-tool.js";
|
|
16
|
-
import { ensureStateRootSelfIgnored } from "./definition.js";
|
|
17
17
|
import { jsonlSessionStore } from "./sessions.js";
|
|
18
|
-
export async function
|
|
19
|
-
|
|
18
|
+
export async function resolveAgentAssembly(dir, options = {}) {
|
|
19
|
+
// Placement is structural (resolvePlacement): the AGENT DIR carries definition + config + machinery;
|
|
20
|
+
// its parent — the WORKSPACE — is what the agent works on: its cwd and the start of the ②-context
|
|
21
|
+
// walk (that is where it reads the project's AGENTS.md from).
|
|
22
|
+
const { agentDir, workspace } = resolvePlacement(dir);
|
|
23
|
+
const { config, path: configPath } = await loadConfig(agentDir);
|
|
20
24
|
const modelSpec = resolveModelSpec(options.model, config);
|
|
21
25
|
if (!modelSpec) {
|
|
22
26
|
throw new Error(`missing model: set --model, "model" in fastagent.config.ts, or FASTAGENT_MODEL (e.g. "openai-codex/gpt-5.5")`);
|
|
23
27
|
}
|
|
24
|
-
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
// The
|
|
29
|
-
// whole machine-state home in one knob (a container mounts one volume); the finer overrides below
|
|
30
|
-
// still win for their specific path.
|
|
31
|
-
const stateRoot = resolveStateRoot(dir);
|
|
32
|
-
// The credentials file: project-level by default (under the state root); only resolved here, never
|
|
28
|
+
const { tools, toolNames, deferredToolNames, toolCollisions, toolFailures } = await resolveAgentTools(config, agentDir, workspace);
|
|
29
|
+
// The state root: sessions/channel state/schedule state derive from it (FASTAGENT_STATE_DIR moves it
|
|
30
|
+
// in one knob — a container points it at its volume); the finer overrides below still win.
|
|
31
|
+
const stateRoot = resolveStateRoot(agentDir);
|
|
32
|
+
// The credentials file: project-level by default (under `<agentDir>/.secrets`); only resolved here, never
|
|
33
33
|
// created (a missing file reads as not-configured — `fastagent login` creates it).
|
|
34
|
-
const authPath = resolveAuthPath(
|
|
35
|
-
// Self-ignore the state root iff it lands in-tree — which covers everything under it (sessions, auth,
|
|
36
|
-
// every channel's `channels/<kind>` home). HERE, not in the serving opener: every consumer of this
|
|
37
|
-
// assembly can WRITE under the state root (serving: sessions/channels; the session builder: pi's
|
|
38
|
-
// `/login` writing auth.json), so resolving a workspace's state root must make it leak-safe.
|
|
39
|
-
await ensureStateRootSelfIgnored(dir, stateRoot);
|
|
34
|
+
const authPath = resolveAuthPath(agentDir, options.authPath);
|
|
40
35
|
return {
|
|
41
36
|
config,
|
|
42
37
|
configPath,
|
|
43
38
|
modelSpec,
|
|
44
39
|
agentDir,
|
|
40
|
+
workspace,
|
|
45
41
|
stateRoot,
|
|
46
42
|
authPath,
|
|
47
43
|
tools,
|
|
@@ -52,18 +48,19 @@ export async function resolveWorkspaceAssembly(dir, options = {}) {
|
|
|
52
48
|
};
|
|
53
49
|
}
|
|
54
50
|
/**
|
|
55
|
-
* "Point at a
|
|
56
|
-
*
|
|
57
|
-
*
|
|
51
|
+
* "Point at a directory → agent": resolve the placement (`dir` may be either end — the workspace or
|
|
52
|
+
* the agent dir itself), load the config, resolve model and tools, then L2. Throws a clear error when
|
|
53
|
+
* no model source is set (fail visibly at startup). Returns everything an entry point needs to report
|
|
54
|
+
* what it assembled.
|
|
58
55
|
*/
|
|
59
|
-
export async function
|
|
60
|
-
const { config, configPath, modelSpec, agentDir, stateRoot, authPath, tools, toolNames, deferredToolNames, toolCollisions, toolFailures, } = await
|
|
56
|
+
export async function createPiAgentFromDir(dir, options = {}) {
|
|
57
|
+
const { config, configPath, modelSpec, agentDir, workspace, stateRoot, authPath, tools, toolNames, deferredToolNames, toolCollisions, toolFailures, } = await resolveAgentAssembly(dir, options);
|
|
61
58
|
// Mount the built-in `wake` tool only when BOTH: this is a long-running serve (the poller honors it) AND
|
|
62
|
-
// the author opted into self-scheduling (config.selfSchedule). The
|
|
59
|
+
// the author opted into self-scheduling (config.selfSchedule). The agent's own `wake` wins if defined.
|
|
63
60
|
const mountedTools = withWakeTool(tools, stateRoot, !!options.serving && !!config.selfSchedule);
|
|
64
61
|
const sessionsDir = options.sessionsDir ?? defaultSessionsDir(stateRoot);
|
|
65
62
|
await mkdir(sessionsDir, { recursive: true });
|
|
66
|
-
const sessions = jsonlSessionStore({ dir: sessionsDir, cwd:
|
|
63
|
+
const sessions = jsonlSessionStore({ dir: sessionsDir, cwd: workspace });
|
|
67
64
|
// The hub is wired HERE because the store is created here: chicken-and-egg otherwise (the hub
|
|
68
65
|
// needs the store; the agent needs the hub's observer). Boundary parts (models/factory/lease)
|
|
69
66
|
// only exist after the assembly below — the hub takes them as a lazy thunk, filled by the
|
|
@@ -93,7 +90,7 @@ export async function createPiAgentFromWorkspace(dir, options = {}) {
|
|
|
93
90
|
const { agent, definition } = await createPiAgentFromDefinition(agentDir, {
|
|
94
91
|
model: modelSpec,
|
|
95
92
|
thinkingLevel: config.thinkingLevel,
|
|
96
|
-
cwd:
|
|
93
|
+
cwd: workspace,
|
|
97
94
|
tools: mountedTools,
|
|
98
95
|
authPath,
|
|
99
96
|
// Skills are definition-only (the agent is its directory), so dev mirrors deployment exactly.
|
|
@@ -115,6 +112,7 @@ export async function createPiAgentFromWorkspace(dir, options = {}) {
|
|
|
115
112
|
sessions,
|
|
116
113
|
sessionControl: hub?.control,
|
|
117
114
|
agentDir,
|
|
115
|
+
workspace,
|
|
118
116
|
config,
|
|
119
117
|
configPath,
|
|
120
118
|
modelSpec,
|
|
@@ -3,7 +3,7 @@ export interface BuildSessionRuntimeOptions {
|
|
|
3
3
|
/** Model spec override (the CLI --model flag). Precedence: this > FASTAGENT_MODEL > config.model. */
|
|
4
4
|
model?: string;
|
|
5
5
|
/** Credentials file override (the CLI --auth-path flag). Precedence: this > FASTAGENT_AUTH_PATH >
|
|
6
|
-
* the
|
|
6
|
+
* the agent's default `<agentDir>/.secrets/auth.json`. */
|
|
7
7
|
authPath?: string;
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
@@ -11,6 +11,6 @@ export interface BuildSessionRuntimeOptions {
|
|
|
11
11
|
* skills, and auth resolved exactly as the serving opener does). Split from the TUI launcher so the
|
|
12
12
|
* assembly — the fidelity-critical part — is inspectable and reusable without launching a TUI.
|
|
13
13
|
*/
|
|
14
|
-
export declare function
|
|
14
|
+
export declare function buildAgentSessionRuntime(dir: string, options?: BuildSessionRuntimeOptions,
|
|
15
15
|
/** Session backend. Defaults to pi's project-scoped store; tests inject SessionManager.inMemory(). */
|
|
16
16
|
sessionManager?: SessionManager): Promise<AgentSessionRuntime>;
|