@fastagent-sh/fastagent 0.29.0 → 0.30.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 +9 -4
- package/dist/atomic-write.d.ts +4 -5
- package/dist/atomic-write.js +4 -5
- package/dist/authoring.d.ts +32 -15
- package/dist/authoring.js +147 -127
- package/dist/channels/agentcore-protocol.d.ts +8 -3
- package/dist/channels/agentcore-protocol.js +3 -1
- package/dist/channels/agentcore-service.d.ts +1 -0
- package/dist/channels/agentcore-service.js +14 -4
- package/dist/channels/agentcore.d.ts +9 -0
- package/dist/channels/agentcore.js +29 -4
- package/dist/channels/context.d.ts +2 -0
- package/dist/channels/context.js +5 -1
- package/dist/channels/feishu/feishu-api.d.ts +2 -1
- package/dist/channels/feishu/feishu.d.ts +0 -3
- package/dist/channels/feishu/feishu.js +10 -10
- package/dist/channels/feishu/register-app.js +3 -5
- package/dist/channels/feishu/scaffold/channel.ts +32 -34
- package/dist/channels/feishu/scaffold/feishu-send.ts +5 -5
- package/dist/channels/feishu/scaffold/feishu-threads.ts +3 -3
- package/dist/channels/feishu/setup-mode.d.ts +2 -12
- package/dist/channels/feishu/setup-mode.js +2 -22
- package/dist/channels/feishu/setup.d.ts +12 -0
- package/dist/channels/feishu/setup.js +197 -0
- package/dist/channels/kit/abortable.d.ts +8 -0
- package/dist/channels/kit/abortable.js +22 -0
- package/dist/channels/lark/lark.d.ts +0 -3
- package/dist/channels/lark/lark.js +0 -5
- package/dist/channels/lark/scaffold/channel.ts +33 -35
- package/dist/channels/lark/scaffold/lark-send.ts +5 -5
- package/dist/channels/lark/scaffold/lark-threads.ts +3 -3
- package/dist/channels/lark/setup.d.ts +9 -0
- package/dist/channels/lark/setup.js +57 -0
- package/dist/channels/setup.d.ts +112 -0
- package/dist/channels/setup.js +31 -0
- package/dist/channels/slack/history.js +1 -1
- package/dist/channels/slack/manifest.d.ts +17 -7
- package/dist/channels/slack/manifest.js +12 -16
- package/dist/channels/slack/scaffold/channel.ts +44 -30
- package/dist/channels/slack/scaffold/slack-send.ts +8 -8
- package/dist/channels/slack/scaffold/slack-threads.ts +4 -4
- package/dist/channels/slack/setup.d.ts +7 -0
- package/dist/channels/slack/setup.js +119 -0
- package/dist/channels/slack/slack-api.d.ts +2 -0
- package/dist/channels/slack/slack-api.js +4 -0
- package/dist/channels/slack/slack.d.ts +21 -2
- package/dist/channels/slack/slack.js +398 -338
- package/dist/channels/slack/socket.d.ts +57 -0
- package/dist/channels/slack/socket.js +305 -0
- package/dist/channels/telegram/polling.d.ts +27 -0
- package/dist/channels/telegram/polling.js +105 -0
- package/dist/channels/telegram/scaffold/channel.ts +52 -32
- package/dist/channels/telegram/scaffold/telegram-send.ts +9 -9
- package/dist/channels/telegram/setup.d.ts +2 -0
- package/dist/channels/telegram/setup.js +42 -0
- package/dist/channels/telegram/telegram-api.d.ts +27 -1
- package/dist/channels/telegram/telegram-api.js +7 -6
- package/dist/channels/telegram/telegram.d.ts +11 -3
- package/dist/channels/telegram/telegram.js +184 -157
- package/dist/channels/webhook-evidence.d.ts +11 -0
- package/dist/channels/webhook-evidence.js +71 -0
- package/dist/channels/webhooks.d.ts +37 -0
- package/dist/channels/webhooks.js +70 -0
- package/dist/child-env.d.ts +16 -0
- package/dist/child-env.js +30 -0
- package/dist/cli/box-login.js +4 -1
- package/dist/cli/channel-app.d.ts +3 -0
- package/dist/cli/channel-app.js +35 -0
- package/dist/cli/channel-setup.d.ts +38 -0
- package/dist/cli/channel-setup.js +195 -0
- package/dist/cli/commands/add.d.ts +6 -14
- package/dist/cli/commands/add.js +45 -303
- package/dist/cli/commands/auth.js +8 -2
- package/dist/cli/commands/build.d.ts +5 -0
- package/dist/cli/commands/build.js +16 -0
- package/dist/cli/commands/channels.d.ts +19 -0
- package/dist/cli/commands/channels.js +230 -0
- package/dist/cli/commands/content.d.ts +7 -3
- package/dist/cli/commands/content.js +16 -10
- package/dist/cli/commands/deploy/agentcore.js +55 -23
- package/dist/cli/commands/deploy/channel-apps.d.ts +17 -0
- package/dist/cli/commands/deploy/channel-apps.js +30 -0
- package/dist/cli/commands/deploy/docker.js +32 -65
- package/dist/cli/commands/deploy/fly.js +28 -12
- package/dist/cli/commands/deploy/railway.js +38 -13
- package/dist/cli/commands/deploy/secrets-step.d.ts +19 -0
- package/dist/cli/commands/deploy/secrets-step.js +66 -0
- package/dist/cli/commands/deploy/shared.d.ts +16 -5
- package/dist/cli/commands/deploy/shared.js +25 -8
- package/dist/cli/commands/deploy.js +53 -60
- package/dist/cli/commands/dev.d.ts +2 -0
- package/dist/cli/commands/dev.js +15 -3
- package/dist/cli/commands/env.js +1 -1
- package/dist/cli/commands/info.d.ts +2 -0
- package/dist/cli/commands/info.js +60 -25
- package/dist/cli/commands/init.js +3 -1
- package/dist/cli/commands/invoke.d.ts +2 -0
- package/dist/cli/commands/invoke.js +20 -7
- package/dist/cli/commands/login.d.ts +0 -7
- package/dist/cli/commands/login.js +22 -10
- package/dist/cli/commands/logout.js +1 -1
- package/dist/cli/commands/mcp.js +14 -6
- package/dist/cli/commands/models.js +3 -2
- package/dist/cli/commands/schedules.d.ts +4 -2
- package/dist/cli/commands/schedules.js +14 -10
- package/dist/cli/commands/secrets.d.ts +14 -0
- package/dist/cli/commands/secrets.js +213 -0
- package/dist/cli/commands/start.d.ts +14 -14
- package/dist/cli/commands/start.js +46 -60
- package/dist/cli/content-view.d.ts +4 -6
- package/dist/cli/content-view.js +5 -11
- package/dist/cli/first-run-channels.d.ts +3 -0
- package/dist/cli/first-run-channels.js +63 -0
- package/dist/cli/instance.d.ts +41 -0
- package/dist/cli/instance.js +155 -0
- package/dist/cli/invoke-stream.d.ts +5 -2
- package/dist/cli/invoke-stream.js +7 -2
- package/dist/cli/program.js +282 -110
- package/dist/cli/serve.d.ts +4 -5
- package/dist/cli/serve.js +4 -7
- package/dist/cli/shared.d.ts +11 -2
- package/dist/cli/shared.js +32 -19
- package/dist/cli/ticket.js +50 -6
- package/dist/content/declare.d.ts +31 -37
- package/dist/content/declare.js +59 -60
- package/dist/content/file.d.ts +23 -12
- package/dist/content/file.js +48 -35
- package/dist/content/git.d.ts +0 -10
- package/dist/content/git.js +5 -39
- package/dist/content/resolve.d.ts +18 -22
- package/dist/content/resolve.js +32 -66
- package/dist/content/source.d.ts +7 -8
- package/dist/content/source.js +10 -28
- package/dist/credentials-page.d.ts +26 -0
- package/dist/credentials-page.js +185 -0
- package/dist/declared-secrets.d.ts +10 -3
- package/dist/declared-secrets.js +8 -4
- package/dist/deploy/agentcore/destroy.d.ts +4 -1
- package/dist/deploy/agentcore/destroy.js +25 -1
- package/dist/deploy/agentcore/forwarder.js +1 -1
- package/dist/deploy/agentcore/plan.d.ts +7 -21
- package/dist/deploy/agentcore/plan.js +47 -49
- package/dist/deploy/agentcore/run.d.ts +18 -10
- package/dist/deploy/agentcore/run.js +93 -70
- package/dist/deploy/agentcore/runtime-secrets.d.ts +7 -0
- package/dist/deploy/agentcore/runtime-secrets.js +108 -0
- package/dist/deploy/agentcore/shell.js +12 -19
- package/dist/deploy/agentcore/sigv4.d.ts +7 -0
- package/dist/deploy/agentcore/sigv4.js +15 -0
- package/dist/deploy/agentcore/slr.d.ts +18 -0
- package/dist/deploy/agentcore/slr.js +27 -0
- package/dist/deploy/agentcore/store.d.ts +7 -0
- package/dist/deploy/agentcore/store.js +115 -0
- package/dist/deploy/api.d.ts +14 -14
- package/dist/deploy/api.js +26 -24
- package/dist/deploy/box-shell.d.ts +3 -1
- package/dist/deploy/build-context.d.ts +4 -4
- package/dist/deploy/build-context.js +11 -15
- package/dist/deploy/channel-ingress.d.ts +35 -9
- package/dist/deploy/channel-ingress.js +119 -22
- package/dist/deploy/container.d.ts +35 -10
- package/dist/deploy/container.js +79 -37
- package/dist/deploy/delivered-text.d.ts +13 -0
- package/dist/deploy/delivered-text.js +86 -0
- package/dist/deploy/docker/plan.d.ts +7 -8
- package/dist/deploy/docker/plan.js +31 -52
- package/dist/deploy/docker/run.d.ts +5 -43
- package/dist/deploy/docker/run.js +9 -84
- package/dist/deploy/file-store.d.ts +2 -0
- package/dist/deploy/file-store.js +17 -0
- package/dist/deploy/fly/plan.d.ts +3 -2
- package/dist/deploy/fly/plan.js +20 -9
- package/dist/deploy/fly/run.d.ts +18 -8
- package/dist/deploy/fly/run.js +24 -42
- package/dist/deploy/fly/store.d.ts +12 -0
- package/dist/deploy/fly/store.js +83 -0
- package/dist/deploy/hosts.d.ts +1 -2
- package/dist/deploy/hosts.js +1 -2
- package/dist/deploy/preflight.d.ts +18 -5
- package/dist/deploy/preflight.js +135 -63
- package/dist/deploy/railway/ignore.d.ts +8 -0
- package/dist/deploy/railway/ignore.js +57 -0
- package/dist/deploy/railway/plan.d.ts +1 -2
- package/dist/deploy/railway/plan.js +8 -6
- package/dist/deploy/railway/run.d.ts +21 -15
- package/dist/deploy/railway/run.js +32 -78
- package/dist/deploy/railway/store.d.ts +29 -0
- package/dist/deploy/railway/store.js +143 -0
- package/dist/deploy/runner.d.ts +5 -2
- package/dist/deploy/runner.js +4 -3
- package/dist/deploy/secret-store.d.ts +63 -0
- package/dist/deploy/secret-store.js +98 -0
- package/dist/deploy/secrets.d.ts +29 -46
- package/dist/deploy/secrets.js +49 -122
- package/dist/deploy/workspace.d.ts +6 -12
- package/dist/deploy/workspace.js +18 -94
- package/dist/dev-supervisor.js +6 -8
- package/dist/environment/declare.js +3 -2
- package/dist/environment/mise.d.ts +3 -1
- package/dist/environment/mise.js +4 -2
- package/dist/feishu.d.ts +1 -1
- package/dist/feishu.js +1 -1
- package/dist/harnesses/models/catalog.d.ts +1 -0
- package/dist/harnesses/models/catalog.js +1 -2
- package/dist/harnesses/models/environment.d.ts +7 -2
- package/dist/harnesses/models/environment.js +9 -5
- package/dist/harnesses/models/host.d.ts +0 -7
- package/dist/harnesses/models/host.js +10 -1
- package/dist/harnesses/models/login.d.ts +0 -8
- package/dist/harnesses/models/login.js +5 -4
- package/dist/harnesses/models/models.d.ts +7 -2
- package/dist/harnesses/models/models.js +28 -4
- package/dist/harnesses/pi-durable/agent.js +59 -38
- package/dist/harnesses/pi-durable/build.d.ts +12 -0
- package/dist/harnesses/pi-durable/build.js +270 -0
- package/dist/harnesses/pi-durable/built.d.ts +24 -0
- package/dist/harnesses/pi-durable/built.js +136 -0
- package/dist/harnesses/pi-durable/config.d.ts +81 -0
- package/dist/harnesses/pi-durable/config.js +266 -0
- package/dist/harnesses/pi-durable/define.d.ts +63 -13
- package/dist/harnesses/pi-durable/define.js +23 -2
- package/dist/harnesses/pi-durable/definition.d.ts +72 -0
- package/dist/harnesses/pi-durable/definition.js +143 -0
- package/dist/harnesses/pi-durable/events.d.ts +4 -3
- package/dist/harnesses/pi-durable/events.js +179 -136
- package/dist/harnesses/pi-durable/execution-env.d.ts +17 -0
- package/dist/harnesses/pi-durable/execution-env.js +11 -0
- package/dist/harnesses/pi-durable/mcp.js +1 -3
- package/dist/harnesses/pi-durable/open.d.ts +35 -37
- package/dist/harnesses/pi-durable/open.js +91 -153
- package/dist/harnesses/pi-durable/reads.d.ts +0 -1
- package/dist/harnesses/pi-durable/reads.js +1 -3
- package/dist/harnesses/pi-durable/registry.d.ts +4 -6
- package/dist/harnesses/pi-durable/registry.js +29 -26
- package/dist/harnesses/pi-durable/release.d.ts +2 -2
- package/dist/harnesses/pi-durable/release.js +10 -7
- package/dist/harnesses/pi-durable/serve.d.ts +91 -15
- package/dist/harnesses/pi-durable/serve.js +109 -47
- package/dist/harnesses/pi-durable/sessions.js +15 -12
- package/dist/harnesses/pi-durable/text-sources.d.ts +30 -0
- package/dist/harnesses/pi-durable/text-sources.js +55 -0
- package/dist/harnesses/pi-durable/text.d.ts +16 -4
- package/dist/harnesses/pi-durable/text.js +115 -59
- package/dist/harnesses/pi-durable/wake.js +8 -8
- package/dist/http/client.js +9 -3
- package/dist/http/contract.d.ts +3 -3
- package/dist/http/server.d.ts +1 -1
- package/dist/http/server.js +1 -1
- package/dist/index.d.ts +8 -5
- package/dist/index.js +4 -1
- package/dist/instance-name.d.ts +7 -0
- package/dist/instance-name.js +26 -0
- package/dist/lark.d.ts +1 -1
- package/dist/lark.js +1 -1
- package/dist/mcp/client.js +11 -2
- package/dist/mcp/config.d.ts +70 -18
- package/dist/mcp/config.js +136 -53
- package/dist/mcp/host.d.ts +5 -2
- package/dist/mcp/host.js +14 -6
- package/dist/mcp/sign-in.js +2 -2
- package/dist/mcp-api.d.ts +14 -0
- package/dist/paths.d.ts +22 -8
- package/dist/paths.js +44 -11
- package/dist/runtime-websocket.d.ts +14 -0
- package/dist/runtime-websocket.js +39 -0
- package/dist/scaffold/add-channel.d.ts +9 -16
- package/dist/scaffold/add-channel.js +13 -83
- package/dist/scaffold/templates/env.example +4 -5
- package/dist/scaffold/templates/fastagent.config.ts +20 -14
- package/dist/scaffold/templates/gitignore +9 -6
- package/dist/scaffold/templates.d.ts +6 -2
- package/dist/scaffold/templates.js +7 -2
- package/dist/scaffold/vendor-skill.js +4 -2
- package/dist/service.d.ts +44 -6
- package/dist/service.js +110 -10
- package/dist/serving-command.d.ts +10 -0
- package/dist/serving-command.js +1 -0
- package/dist/slack.d.ts +1 -1
- package/dist/slack.js +1 -1
- package/dist/strip-edges.d.ts +10 -0
- package/dist/strip-edges.js +22 -0
- package/dist/telegram.d.ts +1 -1
- package/dist/telegram.js +1 -1
- package/dist/tunnel.d.ts +0 -1
- package/dist/tunnel.js +2 -8
- package/dist/value-file.d.ts +11 -6
- package/dist/value-file.js +21 -9
- package/dist/version.d.ts +7 -1
- package/dist/version.js +9 -3
- package/package.json +6 -5
- package/dist/channels/lark/credentials-page.d.ts +0 -25
- package/dist/channels/lark/credentials-page.js +0 -206
- package/dist/channels/lark/onboard.d.ts +0 -52
- package/dist/channels/lark/onboard.js +0 -86
- package/dist/channels/slack/config-api.d.ts +0 -69
- package/dist/channels/slack/config-api.js +0 -162
- package/dist/channels/slack/onboard.d.ts +0 -40
- package/dist/channels/slack/onboard.js +0 -136
- package/dist/channels/slack/onboarding-state.d.ts +0 -31
- package/dist/channels/slack/onboarding-state.js +0 -64
- package/dist/channels/slack/register-webhook.d.ts +0 -12
- package/dist/channels/slack/register-webhook.js +0 -67
- package/dist/channels/slack/setup-server.d.ts +0 -32
- package/dist/channels/slack/setup-server.js +0 -246
- package/dist/cli/add-feishu.d.ts +0 -41
- package/dist/cli/add-feishu.js +0 -391
- package/dist/cli/add-slack.d.ts +0 -18
- package/dist/cli/add-slack.js +0 -216
- package/dist/harnesses/pi-durable/parked.d.ts +0 -18
- package/dist/harnesses/pi-durable/parked.js +0 -27
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `fastagent build` (agent-artifact.md §3.4): a source project compiled into `dist/`, a package that holds everything
|
|
3
|
+
* an open reads and nothing of the machine that built it. The project's own TypeScript compiles it, per file and
|
|
4
|
+
* unbundled, with the options FastAgent sets; the text and resources are copied; the entry is generated, the
|
|
5
|
+
* definition's modules as static imports.
|
|
6
|
+
*/
|
|
7
|
+
import { spawn } from "node:child_process";
|
|
8
|
+
import { mkdir, rename, rm, writeFile } from "node:fs/promises";
|
|
9
|
+
import { createRequire } from "node:module";
|
|
10
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
11
|
+
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
12
|
+
import { instanceConfigSchema } from "./config.js";
|
|
13
|
+
import { BUILD_FILE, DIST_DIR, buildRecord, copyFiles, copyPlan } from "./built.js";
|
|
14
|
+
import { declareMcp, literalCredentialAdvice, literalCredentials, relativeCommands } from "../../mcp/config.js";
|
|
15
|
+
import { AGENT_CONFIG_FILE, exists, isUnderDir } from "../../paths.js";
|
|
16
|
+
import { readPackageJson } from "../../runtime.js";
|
|
17
|
+
import { HARNESS_PACKAGES } from "../../version.js";
|
|
18
|
+
import { DEFINITION_FORMAT } from "./definition.js";
|
|
19
|
+
import { loadSourceDefinition } from "./open.js";
|
|
20
|
+
import { REGISTRY_KINDS } from "./registry.js";
|
|
21
|
+
const STAGING_DIR = join(".fastagent", "build");
|
|
22
|
+
/** The JSON Schema of an instance's `fastagent.json` for this program: an editor's `$schema`, and the package's own. */
|
|
23
|
+
const SCHEMA_FILE = "fastagent.schema.json";
|
|
24
|
+
const FASTAGENT_PACKAGE = "@fastagent-sh/fastagent";
|
|
25
|
+
/** A declaration file: types only, so the compiler emits nothing for it, wherever it is (a workspace package's). */
|
|
26
|
+
const DECLARATION = /\.d\.[cm]?ts$/;
|
|
27
|
+
const MIN_TYPESCRIPT = 7;
|
|
28
|
+
export async function buildProject(directory, options = {}) {
|
|
29
|
+
// The same refusals `dev` makes, before anything is written: a build of a definition that does not open is no build.
|
|
30
|
+
const definition = await loadSourceDefinition(directory);
|
|
31
|
+
const { dir } = definition;
|
|
32
|
+
await requireModulePackage(dir);
|
|
33
|
+
const dist = join(dir, DIST_DIR);
|
|
34
|
+
// Built apart and moved into place whole: a build that fails leaves the `dist/` before it as it was.
|
|
35
|
+
const staging = join(dir, STAGING_DIR);
|
|
36
|
+
await rm(staging, { recursive: true, force: true });
|
|
37
|
+
try {
|
|
38
|
+
await mkdir(staging, { recursive: true });
|
|
39
|
+
const code = await compile(dir, staging, definition, options.check !== false);
|
|
40
|
+
await copyFiles(dir, staging, await copyPlan(dir, code));
|
|
41
|
+
requireShippedCommands(dir, staging);
|
|
42
|
+
await writeEntry(staging, definition);
|
|
43
|
+
await writeFile(join(staging, "package.json"), await distPackageJson(dir, definition));
|
|
44
|
+
await writeFile(join(staging, SCHEMA_FILE), `${JSON.stringify(instanceConfigSchema(definition.config.settings), null, 2)}\n`);
|
|
45
|
+
await writeFile(join(staging, BUILD_FILE), await buildRecord(dir, code));
|
|
46
|
+
await rm(dist, { recursive: true, force: true });
|
|
47
|
+
await rename(staging, dist);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
await rm(staging, { recursive: true, force: true });
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
return { dist, definition, warnings: literalMcpCredentials(dir) };
|
|
54
|
+
}
|
|
55
|
+
/** The compiler reads a `.ts` file as CommonJS without a package that says otherwise, and refuses its `import`s. */
|
|
56
|
+
async function requireModulePackage(dir) {
|
|
57
|
+
if (!(await exists(join(dir, "package.json")))) {
|
|
58
|
+
throw new Error(`fastagent build needs ${join(dir, "package.json")}, with "type": "module"`);
|
|
59
|
+
}
|
|
60
|
+
if ((await readPackageJson(dir)).type !== "module") {
|
|
61
|
+
throw new Error(`fastagent build compiles ES modules: set "type": "module" in ${join(dir, "package.json")}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** The project's `tsc`, by the package's own `bin`: FastAgent does not carry a compiler, as Next.js does not. */
|
|
65
|
+
function projectTsc(dir) {
|
|
66
|
+
try {
|
|
67
|
+
const manifest = createRequire(join(dir, "package.json")).resolve("typescript/package.json");
|
|
68
|
+
const { bin, version } = JSON.parse(readFileSync(manifest, "utf8"));
|
|
69
|
+
if (bin?.tsc === undefined)
|
|
70
|
+
throw new Error(`${manifest} has no tsc`);
|
|
71
|
+
// The options the build sets (--ignoreConfig, --erasableSyntaxOnly, --rewriteRelativeImportExtensions) are 7's.
|
|
72
|
+
if (!(Number.parseInt(version ?? "", 10) >= MIN_TYPESCRIPT)) {
|
|
73
|
+
throw new Error(`fastagent build needs TypeScript ${MIN_TYPESCRIPT} or newer; ${dir} has ${version ?? "an unknown version"}`);
|
|
74
|
+
}
|
|
75
|
+
return join(dirname(manifest), bin.tsc);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
if (error.code !== "MODULE_NOT_FOUND")
|
|
79
|
+
throw error;
|
|
80
|
+
throw new Error(`fastagent build compiles with the project's TypeScript, and ${dir} has none: npm install --save-dev typescript`, { cause: error });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/** What the compiler is run with: FastAgent sets it, and the author's `tsconfig.json` is the editor's. */
|
|
84
|
+
function tscArguments(dir, outDir, roots, more) {
|
|
85
|
+
return [
|
|
86
|
+
projectTsc(dir),
|
|
87
|
+
"--ignoreConfig",
|
|
88
|
+
"--pretty",
|
|
89
|
+
"false",
|
|
90
|
+
"--target",
|
|
91
|
+
"es2022",
|
|
92
|
+
"--module",
|
|
93
|
+
"nodenext",
|
|
94
|
+
"--moduleResolution",
|
|
95
|
+
"nodenext",
|
|
96
|
+
"--strict",
|
|
97
|
+
"--skipLibCheck",
|
|
98
|
+
"--verbatimModuleSyntax",
|
|
99
|
+
// What `dev` runs is Node's type stripping: the build compiles only what it would run.
|
|
100
|
+
"--erasableSyntaxOnly",
|
|
101
|
+
"--allowImportingTsExtensions",
|
|
102
|
+
"--rewriteRelativeImportExtensions",
|
|
103
|
+
"--resolveJsonModule",
|
|
104
|
+
"--allowJs",
|
|
105
|
+
"--rootDir",
|
|
106
|
+
dir,
|
|
107
|
+
"--outDir",
|
|
108
|
+
outDir,
|
|
109
|
+
...more,
|
|
110
|
+
...roots.map((file) => join(dir, file)),
|
|
111
|
+
];
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* The source files the compiler reads, split into the project's (relative, what the build records) and those outside
|
|
115
|
+
* it, which `dist/` cannot hold: `tsc` reports one (TS6059) yet writes its output beside it, and with `--noCheck`
|
|
116
|
+
* reports nothing and succeeds, so the files are listed first and the build refuses before anything is emitted.
|
|
117
|
+
* Dependencies (`node_modules`, the compiler's own libraries) and declaration files, which emit nothing, are neither.
|
|
118
|
+
*/
|
|
119
|
+
async function programFiles(dir, roots) {
|
|
120
|
+
const { output } = await run(process.execPath, tscArguments(dir, dir, roots, ["--listFilesOnly"]), dir);
|
|
121
|
+
const inside = [];
|
|
122
|
+
const outside = [];
|
|
123
|
+
for (const file of output.split("\n").map((line) => line.trim())) {
|
|
124
|
+
if (!isAbsolute(file) || file.split(sep).includes("node_modules"))
|
|
125
|
+
continue;
|
|
126
|
+
const rel = relative(dir, file);
|
|
127
|
+
if (rel.startsWith("..")) {
|
|
128
|
+
if (!DECLARATION.test(file))
|
|
129
|
+
outside.push(file);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
inside.push(rel.split(sep).join("/"));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return { inside, outside };
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* The configuration and every registered module, compiled with what they import; a type error fails the build.
|
|
139
|
+
* Answers the project's source files the compiler read.
|
|
140
|
+
*/
|
|
141
|
+
async function compile(dir, outDir, definition, check) {
|
|
142
|
+
const roots = [
|
|
143
|
+
...((await exists(join(dir, AGENT_CONFIG_FILE))) ? [AGENT_CONFIG_FILE] : []),
|
|
144
|
+
...REGISTRY_KINDS.flatMap((kind) => definition.registry[kind].map(({ file }) => file)),
|
|
145
|
+
];
|
|
146
|
+
if (roots.length === 0)
|
|
147
|
+
return [];
|
|
148
|
+
const { inside, outside } = await programFiles(dir, roots);
|
|
149
|
+
if (outside.length > 0) {
|
|
150
|
+
throw new Error(`the project imports source from outside ${dir}, which ${DIST_DIR}/ cannot hold: ${outside.join(", ")}`);
|
|
151
|
+
}
|
|
152
|
+
const { code, output } = await run(process.execPath, tscArguments(dir, outDir, roots, check ? [] : ["--noCheck"]), dir);
|
|
153
|
+
if (code !== 0)
|
|
154
|
+
throw new Error(`tsc refused the project (exit ${code}):\n${output.trim()}`);
|
|
155
|
+
// The configuration's declaration alone: it types the package's entry by the program's settings.
|
|
156
|
+
if (roots.includes(AGENT_CONFIG_FILE)) {
|
|
157
|
+
const declared = await run(process.execPath, tscArguments(dir, outDir, [AGENT_CONFIG_FILE], ["--declaration", "--emitDeclarationOnly", "--noCheck"]), dir);
|
|
158
|
+
if (declared.code !== 0) {
|
|
159
|
+
throw new Error(`tsc could not write the declaration of ${AGENT_CONFIG_FILE}:\n${declared.output.trim()}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return inside;
|
|
163
|
+
}
|
|
164
|
+
function run(command, args, cwd) {
|
|
165
|
+
return new Promise((resolve, reject) => {
|
|
166
|
+
const child = spawn(command, args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
167
|
+
let output = "";
|
|
168
|
+
child.stdout.on("data", (chunk) => (output += chunk.toString()));
|
|
169
|
+
child.stderr.on("data", (chunk) => (output += chunk.toString()));
|
|
170
|
+
child.on("error", reject);
|
|
171
|
+
child.on("close", (code) => resolve({ code, output }));
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
/** `index.js`, the package's default export: the definition, its modules imported statically. */
|
|
175
|
+
async function writeEntry(dist, definition) {
|
|
176
|
+
const emitted = (file) => `./${file.replace(/\.(ts|mts)$/, (ext) => (ext === ".mts" ? ".mjs" : ".js"))}`;
|
|
177
|
+
const lines = [
|
|
178
|
+
"// Generated by fastagent build: do not edit.",
|
|
179
|
+
'import { dirname } from "node:path";',
|
|
180
|
+
'import { fileURLToPath } from "node:url";',
|
|
181
|
+
`import { defineDefinition } from ${JSON.stringify(FASTAGENT_PACKAGE)};`,
|
|
182
|
+
];
|
|
183
|
+
const hasConfig = await exists(join(dist, "fastagent.config.js"));
|
|
184
|
+
if (hasConfig)
|
|
185
|
+
lines.push('import config from "./fastagent.config.js";');
|
|
186
|
+
let index = 0;
|
|
187
|
+
const kinds = REGISTRY_KINDS.map((kind) => {
|
|
188
|
+
const entries = definition.registry[kind].map(({ file, name }) => {
|
|
189
|
+
const local = `m${index++}`;
|
|
190
|
+
lines.push(`import ${local} from ${JSON.stringify(emitted(file))};`);
|
|
191
|
+
return ` { file: ${JSON.stringify(file)}, name: ${JSON.stringify(name)}, value: ${local} },`;
|
|
192
|
+
});
|
|
193
|
+
return ` ${kind}: [\n${entries.map((entry) => ` ${entry}`).join("\n")}${entries.length > 0 ? "\n" : ""} ],`;
|
|
194
|
+
});
|
|
195
|
+
const source = `${lines.join("\n")}
|
|
196
|
+
|
|
197
|
+
export default defineDefinition({
|
|
198
|
+
format: ${DEFINITION_FORMAT},
|
|
199
|
+
builtWith: ${JSON.stringify(definition.builtWith)},
|
|
200
|
+
name: ${JSON.stringify(definition.name)},
|
|
201
|
+
version: ${JSON.stringify(definition.version)},
|
|
202
|
+
dir: dirname(fileURLToPath(import.meta.url)),
|
|
203
|
+
config: ${hasConfig ? "config ?? {}" : "{}"},
|
|
204
|
+
registry: {
|
|
205
|
+
${kinds.map((kind) => ` ${kind}`).join("\n")}
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
`;
|
|
209
|
+
await writeFile(join(dist, "index.js"), source);
|
|
210
|
+
const typed = await exists(join(dist, "fastagent.config.d.ts"));
|
|
211
|
+
const fastagent = JSON.stringify(FASTAGENT_PACKAGE);
|
|
212
|
+
await writeFile(join(dist, "index.d.ts"), typed
|
|
213
|
+
? `import type { AgentDefinition, SettingsOf } from ${fastagent};\nimport type config from "./fastagent.config.js";\n` +
|
|
214
|
+
`declare const definition: AgentDefinition<SettingsOf<typeof config>>;\nexport default definition;\n`
|
|
215
|
+
: `import type { AgentDefinition } from ${fastagent};\ndeclare const definition: AgentDefinition;\nexport default definition;\n`);
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* The package `dist/` is: the project's name, version and own dependencies, with FastAgent and the pi packages its
|
|
219
|
+
* code imports as peers, so an app that installs several agents holds one copy of each (§3.5).
|
|
220
|
+
*/
|
|
221
|
+
async function distPackageJson(dir, definition) {
|
|
222
|
+
const pkg = (await readPackageJson(dir));
|
|
223
|
+
const peers = new Set([FASTAGENT_PACKAGE, ...HARNESS_PACKAGES]);
|
|
224
|
+
const dependencies = {};
|
|
225
|
+
const peerDependencies = {};
|
|
226
|
+
for (const [name, range] of Object.entries(pkg.dependencies ?? {})) {
|
|
227
|
+
(peers.has(name) ? peerDependencies : dependencies)[name] = range;
|
|
228
|
+
}
|
|
229
|
+
const out = {
|
|
230
|
+
name: pkg.name ?? basename(dir),
|
|
231
|
+
version: definition.version,
|
|
232
|
+
...(pkg.description === undefined ? {} : { description: pkg.description }),
|
|
233
|
+
...(pkg.license === undefined ? {} : { license: pkg.license }),
|
|
234
|
+
type: "module",
|
|
235
|
+
exports: {
|
|
236
|
+
".": { types: "./index.d.ts", default: "./index.js" },
|
|
237
|
+
[`./${SCHEMA_FILE}`]: `./${SCHEMA_FILE}`,
|
|
238
|
+
},
|
|
239
|
+
...(Object.keys(dependencies).length > 0 ? { dependencies } : {}),
|
|
240
|
+
...(Object.keys(peerDependencies).length > 0 ? { peerDependencies } : {}),
|
|
241
|
+
};
|
|
242
|
+
return `${JSON.stringify(out, null, 2)}\n`;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* A program's stdio command with a path is relative to its package, which in `dev` is the project and after a build is
|
|
246
|
+
* `dist/`, holding only what the build copied. One the build did not copy works in `dev` and is not there on a box, so
|
|
247
|
+
* it is refused here, against what was actually written to `staging`, rather than found when the box starts.
|
|
248
|
+
*/
|
|
249
|
+
function requireShippedCommands(dir, staging) {
|
|
250
|
+
for (const { name, file, command } of relativeCommands(declareMcp(dir))) {
|
|
251
|
+
const inProject = resolve(dir, command);
|
|
252
|
+
const shipped = join(staging, relative(dir, inProject));
|
|
253
|
+
if (isUnderDir(inProject, dir) && existsSync(shipped))
|
|
254
|
+
continue;
|
|
255
|
+
const dependency = isUnderDir(inProject, dir) && relative(dir, inProject).split(sep)[0] === "node_modules";
|
|
256
|
+
throw new Error(`${file} mcpServers.${name}: the command "${command}" ` +
|
|
257
|
+
(dependency
|
|
258
|
+
? `is in node_modules, which the box installs for itself and ${DIST_DIR}/ does not hold: run the package by ` +
|
|
259
|
+
`name (\`npx <package>\`) or give the absolute path it has there`
|
|
260
|
+
: existsSync(inProject)
|
|
261
|
+
? `is not in ${DIST_DIR}/, which holds only what the build copies (assets/, skills/, prompts/ and the ` +
|
|
262
|
+
`resources beside code): move it under assets/`
|
|
263
|
+
: `does not exist in the project`));
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
/** What a build says of a literal credential in the program's `mcpServers`, which the package publishes. */
|
|
267
|
+
function literalMcpCredentials(dir) {
|
|
268
|
+
return literalCredentials(declareMcp(dir)).map((literal) => `${literal.file} mcpServers.${literal.server}.${literal.field}.${literal.key} is a literal value, and ` +
|
|
269
|
+
`${DIST_DIR}/ is published: ${literalCredentialAdvice(literal)} and give the value as a secret`);
|
|
270
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type AgentDefinition } from "./definition.ts";
|
|
2
|
+
export declare const DIST_DIR = "dist";
|
|
3
|
+
/** Beside the package's entry: the format and fingerprint of the build, and the code files it read. */
|
|
4
|
+
export declare const BUILD_FILE = "build.json";
|
|
5
|
+
/**
|
|
6
|
+
* The files the build copies into `dist/` beside what it compiled, as project-relative `[from, to]`: the text and data
|
|
7
|
+
* of the root, `skills/`, `prompts/` and `assets/` whole, and in each directory the code lives in, every file that is
|
|
8
|
+
* not code or a test (a module's resource is relative to the module, so it lands beside it). A link is followed to
|
|
9
|
+
* what it names, and one back into a directory being listed is refused.
|
|
10
|
+
*/
|
|
11
|
+
export declare function copyPlan(dir: string, code: readonly string[]): Promise<string[]>;
|
|
12
|
+
/** Copy each of `files`, project-relative, from `dir` to `to`. */
|
|
13
|
+
export declare function copyFiles(dir: string, to: string, files: readonly string[]): Promise<void>;
|
|
14
|
+
export declare function buildRecord(dir: string, code: readonly string[]): Promise<string>;
|
|
15
|
+
/**
|
|
16
|
+
* The definition of the project's `dist/`: refused, naming `fastagent build`, when there is none or, with
|
|
17
|
+
* `checkSources`, when the project has moved on from it. A deployed box's project is the release's copy, which the
|
|
18
|
+
* agent works in and edits, so only a local `start` asks whether the author forgot to build.
|
|
19
|
+
*/
|
|
20
|
+
export declare function loadProjectBuild(directory: string, { checkSources }: {
|
|
21
|
+
checkSources: boolean;
|
|
22
|
+
}): Promise<AgentDefinition>;
|
|
23
|
+
/** The definition a built package (`dist/`, or one installed under `node_modules`) exports. */
|
|
24
|
+
export declare function loadBuiltDefinition(dist: string): Promise<AgentDefinition>;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* What `dist/` is, as a project and an opener both see it (agent-artifact.md §3.4): which of the project's files go
|
|
11
|
+
* into it, the fingerprint the build records of what it read, and the opener that refuses a `dist/` the project has
|
|
12
|
+
* moved on from.
|
|
13
|
+
*/
|
|
14
|
+
import { createHash } from "node:crypto";
|
|
15
|
+
import { copyFile, mkdir, readFile, readdir, realpath, stat } from "node:fs/promises";
|
|
16
|
+
import { dirname, join } from "node:path";
|
|
17
|
+
import { pathToFileURL } from "node:url";
|
|
18
|
+
import { CONTEXT_FILE, exists } from "../../paths.js";
|
|
19
|
+
import { assertDefinition } from "./definition.js";
|
|
20
|
+
import { registryFiles } from "./registry.js";
|
|
21
|
+
export const DIST_DIR = "dist";
|
|
22
|
+
/** Beside the package's entry: the format and fingerprint of the build, and the code files it read. */
|
|
23
|
+
export const BUILD_FILE = "build.json";
|
|
24
|
+
const CODE = /\.(ts|mts|cts|tsx|js|mjs|cjs|jsx)$/;
|
|
25
|
+
const TEST = /\.(test|spec)\.[a-z]+$/;
|
|
26
|
+
/** What never leaves the project, wherever it is: secrets, dependencies, history, the build's own output. */
|
|
27
|
+
const NEVER_COPIED = /^(\.env(\..*)?|\.secrets|node_modules|\.git|\.DS_Store)$/;
|
|
28
|
+
/** The program's text and data at the project root (§3.4). */
|
|
29
|
+
const ROOT_FILES = ["SYSTEM.md", "AGENTS.md", CONTEXT_FILE, "README.md"];
|
|
30
|
+
const ROOT_DIRS = ["skills", "prompts", "assets"];
|
|
31
|
+
const LICENSE = /^LICEN[CS]E(\..*)?$/i;
|
|
32
|
+
/**
|
|
33
|
+
* The files the build copies into `dist/` beside what it compiled, as project-relative `[from, to]`: the text and data
|
|
34
|
+
* of the root, `skills/`, `prompts/` and `assets/` whole, and in each directory the code lives in, every file that is
|
|
35
|
+
* not code or a test (a module's resource is relative to the module, so it lands beside it). A link is followed to
|
|
36
|
+
* what it names, and one back into a directory being listed is refused.
|
|
37
|
+
*/
|
|
38
|
+
export async function copyPlan(dir, code) {
|
|
39
|
+
const files = [];
|
|
40
|
+
for (const name of await readdir(dir)) {
|
|
41
|
+
if (ROOT_FILES.includes(name) || LICENSE.test(name))
|
|
42
|
+
files.push(name);
|
|
43
|
+
}
|
|
44
|
+
for (const name of ROOT_DIRS) {
|
|
45
|
+
if (await exists(join(dir, name)))
|
|
46
|
+
files.push(...(await filesIn(dir, name, () => true)));
|
|
47
|
+
}
|
|
48
|
+
const compiledIn = new Set(code.filter((file) => file.includes("/")).map((file) => file.split("/")[0]));
|
|
49
|
+
for (const name of [...compiledIn].filter((name) => !ROOT_DIRS.includes(name))) {
|
|
50
|
+
files.push(...(await filesIn(dir, name, (file) => !CODE.test(file) && !TEST.test(file))));
|
|
51
|
+
}
|
|
52
|
+
return [...new Set(files)].sort();
|
|
53
|
+
}
|
|
54
|
+
async function filesIn(dir, rel, include, within = []) {
|
|
55
|
+
const here = await realpath(join(dir, rel));
|
|
56
|
+
if (within.includes(here))
|
|
57
|
+
throw new Error(`${rel} links back to ${here}, a directory this build is copying`);
|
|
58
|
+
const files = [];
|
|
59
|
+
for (const entry of await readdir(join(dir, rel), { withFileTypes: true })) {
|
|
60
|
+
if (NEVER_COPIED.test(entry.name))
|
|
61
|
+
continue;
|
|
62
|
+
const path = `${rel}/${entry.name}`;
|
|
63
|
+
const target = await stat(join(dir, path));
|
|
64
|
+
if (target.isDirectory())
|
|
65
|
+
files.push(...(await filesIn(dir, path, include, [...within, here])));
|
|
66
|
+
else if (target.isFile() && include(entry.name))
|
|
67
|
+
files.push(path);
|
|
68
|
+
}
|
|
69
|
+
return files;
|
|
70
|
+
}
|
|
71
|
+
/** Copy each of `files`, project-relative, from `dir` to `to`. */
|
|
72
|
+
export async function copyFiles(dir, to, files) {
|
|
73
|
+
for (const file of files) {
|
|
74
|
+
await mkdir(dirname(join(to, file)), { recursive: true });
|
|
75
|
+
await copyFile(join(dir, file), join(to, file));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async function digest(path) {
|
|
79
|
+
try {
|
|
80
|
+
return createHash("sha256")
|
|
81
|
+
.update(await readFile(path))
|
|
82
|
+
.digest("hex");
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
if (error.code === "ENOENT")
|
|
86
|
+
return "missing";
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Everything the build reads from the project, as one hash: the code the compiler read, the modules the registry lists
|
|
92
|
+
* now, the files it would copy, and `package.json`. Runtime writes (state, secrets, an agent's own output) are none of
|
|
93
|
+
* these, so running an agent never makes its build stale.
|
|
94
|
+
*/
|
|
95
|
+
async function fingerprintOf(dir, code) {
|
|
96
|
+
const files = new Set([...code, ...(await registryFiles(dir)), ...(await copyPlan(dir, code)), "package.json"]);
|
|
97
|
+
const hash = createHash("sha256");
|
|
98
|
+
for (const file of [...files].sort())
|
|
99
|
+
hash.update(`${file}\0${await digest(join(dir, file))}\n`);
|
|
100
|
+
return hash.digest("hex");
|
|
101
|
+
}
|
|
102
|
+
export async function buildRecord(dir, code) {
|
|
103
|
+
const record = { code: [...code].sort(), fingerprint: await fingerprintOf(dir, code) };
|
|
104
|
+
return `${JSON.stringify(record, null, 2)}\n`;
|
|
105
|
+
}
|
|
106
|
+
/** Why `dist/` of the project in `dir` cannot be opened, or nothing when it is the build of the project as it is. */
|
|
107
|
+
async function builtProblem(dir, checkSources) {
|
|
108
|
+
const rebuild = "run `fastagent build`";
|
|
109
|
+
const dist = join(dir, DIST_DIR);
|
|
110
|
+
if (!(await exists(join(dist, BUILD_FILE))))
|
|
111
|
+
return `${dist} holds no build: ${rebuild}`;
|
|
112
|
+
if (!checkSources)
|
|
113
|
+
return undefined;
|
|
114
|
+
const record = JSON.parse(await readFile(join(dist, BUILD_FILE), "utf8"));
|
|
115
|
+
return (await fingerprintOf(dir, record.code)) === record.fingerprint
|
|
116
|
+
? undefined
|
|
117
|
+
: `${dist} was built from other sources than ${dir} holds now: ${rebuild}`;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* The definition of the project's `dist/`: refused, naming `fastagent build`, when there is none or, with
|
|
121
|
+
* `checkSources`, when the project has moved on from it. A deployed box's project is the release's copy, which the
|
|
122
|
+
* agent works in and edits, so only a local `start` asks whether the author forgot to build.
|
|
123
|
+
*/
|
|
124
|
+
export async function loadProjectBuild(directory, { checkSources }) {
|
|
125
|
+
const problem = await builtProblem(directory, checkSources);
|
|
126
|
+
if (problem !== undefined)
|
|
127
|
+
throw new Error(problem);
|
|
128
|
+
return loadBuiltDefinition(join(directory, DIST_DIR));
|
|
129
|
+
}
|
|
130
|
+
/** The definition a built package (`dist/`, or one installed under `node_modules`) exports. */
|
|
131
|
+
export async function loadBuiltDefinition(dist) {
|
|
132
|
+
const entry = join(dist, "index.js");
|
|
133
|
+
if (!(await exists(entry)))
|
|
134
|
+
throw new Error(`${dist} has no index.js: it is not a built agent package`);
|
|
135
|
+
return assertDefinition((await import(__rewriteRelativeImportExtension(pathToFileURL(entry).href))).default);
|
|
136
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { ModelThinkingLevel } from "@earendil-works/pi-ai";
|
|
2
|
+
import { type Schema } from "@earendil-works/pi-schema";
|
|
3
|
+
import type { ContentEntry } from "../../content/declare.ts";
|
|
4
|
+
import { type McpServerDeclaration } from "../../mcp/config.ts";
|
|
5
|
+
import type { AgentConfig, AgentDefaults, Ingress } from "./define.ts";
|
|
6
|
+
import type { AgentDefinition } from "./definition.ts";
|
|
7
|
+
/**
|
|
8
|
+
* What an instance may set over the program's defaults: `fastagent.json`, or the same shape as an object. Beside the
|
|
9
|
+
* defaults, what only an instance adds: content, and instructions, skills and prompt templates (relative paths are the
|
|
10
|
+
* file's directory's).
|
|
11
|
+
*/
|
|
12
|
+
export type InstanceConfig<Settings = unknown> = AgentDefaults<Settings> & {
|
|
13
|
+
/** The instance's name, one path segment. Default: the program's name made one. */
|
|
14
|
+
name?: string;
|
|
15
|
+
content?: Record<string, ContentEntry>;
|
|
16
|
+
/** MCP servers the instance adds to the program's: a name both declare refuses the open. */
|
|
17
|
+
mcpServers?: Record<string, McpServerDeclaration>;
|
|
18
|
+
instructions?: string[];
|
|
19
|
+
skills?: string[];
|
|
20
|
+
prompts?: string[];
|
|
21
|
+
};
|
|
22
|
+
/** An instance configuration and where it is from, said in a refusal and as a value's source. */
|
|
23
|
+
export interface InstanceConfigSource {
|
|
24
|
+
values: unknown;
|
|
25
|
+
label: string;
|
|
26
|
+
/** The configuration file's directory, which its relative paths are relative to. None for an object. */
|
|
27
|
+
directory?: string;
|
|
28
|
+
}
|
|
29
|
+
/** The JSON Schema of an instance's `fastagent.json` for a program with `settings`: what `fastagent build` publishes. */
|
|
30
|
+
export declare function instanceConfigSchema(settings: Schema | undefined): Schema;
|
|
31
|
+
/**
|
|
32
|
+
* The program's `fastagent.config.ts` default export, checked: the constants it may hold, its `settings` schema, and
|
|
33
|
+
* its defaults in the shape an instance's configuration has. Without one, no constants and no defaults.
|
|
34
|
+
*/
|
|
35
|
+
export declare function checkProgramConfig(config: unknown, file: string): AgentConfig;
|
|
36
|
+
/** A `fastagent.json` read: refused when it cannot be read or is not JSON, naming the file. */
|
|
37
|
+
export declare function readInstanceConfigFile(path: string): Promise<InstanceConfigSource>;
|
|
38
|
+
/** The configuration `FASTAGENT_CONFIG` names, when it names one. */
|
|
39
|
+
export declare function namedInstanceConfig(env?: NodeJS.ProcessEnv): Promise<InstanceConfigSource | undefined>;
|
|
40
|
+
/** The instance configuration `dev` runs a project with: the one named by `--config` or `FASTAGENT_CONFIG`, else the project's own. */
|
|
41
|
+
export declare function devInstanceConfig(dir: string): Promise<InstanceConfigSource | undefined>;
|
|
42
|
+
/** The `fastagent.json` a development project holds at its root, when it holds one. */
|
|
43
|
+
export declare function projectInstanceConfig(dir: string): Promise<InstanceConfigSource | undefined>;
|
|
44
|
+
/** A channel's platform app, for one whose URL only a person sets (SPEC.md §8, `channels.<name>.app`). */
|
|
45
|
+
interface ChannelApp {
|
|
46
|
+
id: string;
|
|
47
|
+
team?: string;
|
|
48
|
+
url?: string;
|
|
49
|
+
}
|
|
50
|
+
/** What an open reads of the configuration: the program's defaults with an instance's over them. */
|
|
51
|
+
export interface EffectiveConfig {
|
|
52
|
+
/** The instance's name as its configuration gives it; none when it gives none (`instanceName` defaults it). */
|
|
53
|
+
name?: string;
|
|
54
|
+
model?: string;
|
|
55
|
+
thinkingLevel?: ModelThinkingLevel;
|
|
56
|
+
http?: {
|
|
57
|
+
port?: number;
|
|
58
|
+
api?: boolean;
|
|
59
|
+
publicUrl?: string;
|
|
60
|
+
};
|
|
61
|
+
deploy?: {
|
|
62
|
+
agentcore?: {
|
|
63
|
+
idleTimeoutSeconds?: number;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
channels?: Readonly<Record<string, {
|
|
67
|
+
ingress?: Ingress;
|
|
68
|
+
app?: ChannelApp;
|
|
69
|
+
}>>;
|
|
70
|
+
settings: Readonly<Record<string, unknown>>;
|
|
71
|
+
/** Where each value is from, by its path (`http.port`, `settings.repo`): "program default", or the instance's label. */
|
|
72
|
+
sources: Readonly<Record<string, string>>;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The configuration an instance of `definition` opens with: the program's defaults, the instance's over them, the
|
|
76
|
+
* merged settings checked against the program's `settings` schema (a required one no one gave refuses, naming it).
|
|
77
|
+
*/
|
|
78
|
+
export declare function resolveConfig(definition: AgentDefinition, instance?: InstanceConfigSource): EffectiveConfig;
|
|
79
|
+
/** The value at a dotted `path` of `config`. */
|
|
80
|
+
export declare function configValue(config: EffectiveConfig, path: string): unknown;
|
|
81
|
+
export {};
|