@fastagent-sh/fastagent 0.21.1 → 0.22.1
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 -12
- package/dist/agent.d.ts +24 -37
- package/dist/agent.js +7 -15
- package/dist/atomic-write.d.ts +13 -17
- package/dist/atomic-write.js +18 -29
- package/dist/bind.d.ts +12 -22
- package/dist/bind.js +18 -27
- package/dist/channel.d.ts +11 -33
- package/dist/channels/agentcore-limits.d.ts +2 -13
- package/dist/channels/agentcore-limits.js +2 -13
- package/dist/channels/agentcore-protocol.d.ts +67 -58
- package/dist/channels/agentcore-protocol.js +23 -15
- package/dist/channels/agentcore-service.d.ts +19 -33
- package/dist/channels/agentcore-service.js +176 -59
- package/dist/channels/agentcore.d.ts +39 -33
- package/dist/channels/agentcore.js +90 -224
- package/dist/channels/body.d.ts +15 -2
- package/dist/channels/body.js +24 -2
- package/dist/channels/busy.d.ts +1 -21
- package/dist/channels/busy.js +2 -39
- package/dist/channels/control.d.ts +17 -62
- package/dist/channels/control.js +74 -182
- package/dist/channels/define-channel.d.ts +39 -0
- package/dist/channels/define-channel.js +9 -0
- package/dist/channels/discover.d.ts +10 -31
- package/dist/channels/discover.js +37 -31
- package/dist/channels/feishu/bootstrap-token.d.ts +1 -8
- package/dist/channels/feishu/bootstrap-token.js +7 -23
- package/dist/channels/feishu/card.d.ts +14 -28
- package/dist/channels/feishu/card.js +16 -30
- package/dist/channels/feishu/cloud.d.ts +1 -5
- package/dist/channels/feishu/context-buffer.d.ts +4 -23
- package/dist/channels/feishu/context-buffer.js +8 -31
- package/dist/channels/feishu/crypto.d.ts +10 -5
- package/dist/channels/feishu/crypto.js +12 -19
- package/dist/channels/feishu/feishu-api.d.ts +2 -1
- package/dist/channels/feishu/feishu-api.js +5 -4
- package/dist/channels/feishu/feishu.d.ts +4 -10
- package/dist/channels/feishu/feishu.js +113 -227
- package/dist/channels/feishu/invoke-turn.d.ts +5 -4
- package/dist/channels/feishu/invoke-turn.js +36 -54
- package/dist/channels/feishu/model.d.ts +4 -21
- package/dist/channels/feishu/model.js +1 -8
- package/dist/channels/feishu/normalize.d.ts +2 -10
- package/dist/channels/feishu/normalize.js +7 -42
- package/dist/channels/feishu/parse.d.ts +9 -29
- package/dist/channels/feishu/parse.js +8 -26
- package/dist/channels/feishu/preview.d.ts +12 -14
- package/dist/channels/feishu/preview.js +108 -207
- package/dist/channels/feishu/register-app.d.ts +8 -23
- package/dist/channels/feishu/register-app.js +7 -20
- package/dist/channels/feishu/register-webhook.d.ts +2 -9
- package/dist/channels/feishu/register-webhook.js +9 -33
- package/dist/channels/feishu/scaffold/channel.ts +27 -19
- package/dist/channels/feishu/scaffold/channel.websocket.ts +31 -0
- package/dist/channels/feishu/setup-mode.d.ts +11 -36
- package/dist/channels/feishu/setup-mode.js +7 -26
- package/dist/channels/feishu/ws-ingress.d.ts +1 -2
- package/dist/channels/feishu/ws-ingress.js +6 -8
- package/dist/channels/http.d.ts +15 -15
- package/dist/channels/http.js +19 -9
- package/dist/channels/kit/attachment-path.d.ts +4 -5
- package/dist/channels/kit/attachment-path.js +10 -34
- package/dist/channels/kit/context-buffer.d.ts +14 -21
- package/dist/channels/kit/context-buffer.js +25 -38
- package/dist/channels/kit/delivery.d.ts +35 -0
- package/dist/channels/kit/delivery.js +129 -0
- package/dist/channels/kit/event-stream.d.ts +5 -0
- package/dist/channels/kit/event-stream.js +29 -0
- package/dist/channels/kit/invoke-turn-kit.d.ts +53 -26
- package/dist/channels/kit/invoke-turn-kit.js +89 -32
- package/dist/channels/kit/preview-kit.d.ts +18 -72
- package/dist/channels/kit/preview-kit.js +22 -88
- package/dist/channels/kit/signature.d.ts +3 -9
- package/dist/channels/kit/signature.js +3 -9
- package/dist/channels/kit/state.d.ts +1 -2
- package/dist/channels/kit/state.js +5 -14
- package/dist/channels/kit/stop-command.d.ts +1 -2
- package/dist/channels/kit/stop-command.js +6 -9
- package/dist/channels/kit/tasks.d.ts +1 -1
- package/dist/channels/kit/tasks.js +8 -21
- package/dist/channels/kit/text.d.ts +2 -16
- package/dist/channels/kit/text.js +23 -31
- package/dist/channels/kit/thread-participants.d.ts +4 -17
- package/dist/channels/kit/thread-participants.js +8 -55
- package/dist/channels/kit/transport.d.ts +26 -0
- package/dist/channels/kit/transport.js +20 -0
- package/dist/channels/kit/turn-queue.d.ts +7 -11
- package/dist/channels/kit/turn-queue.js +21 -39
- package/dist/channels/kit/turn-runner.d.ts +32 -18
- package/dist/channels/kit/turn-runner.js +98 -53
- package/dist/channels/kit/turn-store.d.ts +32 -32
- package/dist/channels/kit/turn-store.js +45 -88
- package/dist/channels/lark/lark.d.ts +1 -5
- package/dist/channels/lark/onboard.d.ts +3 -12
- package/dist/channels/lark/onboard.js +3 -13
- package/dist/channels/lark/scaffold/channel.ts +27 -19
- package/dist/channels/lark/scaffold/channel.websocket.ts +31 -0
- package/dist/channels/registration.d.ts +9 -35
- package/dist/channels/registration.js +6 -37
- package/dist/channels/secret.js +2 -5
- package/dist/channels/serve.d.ts +47 -44
- package/dist/channels/serve.js +165 -101
- package/dist/channels/slack/config-api.d.ts +4 -27
- package/dist/channels/slack/config-api.js +5 -34
- package/dist/channels/slack/context-buffer.d.ts +2 -3
- package/dist/channels/slack/context-buffer.js +5 -5
- package/dist/channels/slack/invoke-turn.d.ts +3 -1
- package/dist/channels/slack/invoke-turn.js +25 -34
- package/dist/channels/slack/manifest.js +1 -3
- package/dist/channels/slack/model.d.ts +1 -2
- package/dist/channels/slack/model.js +1 -1
- package/dist/channels/slack/onboard.d.ts +4 -3
- package/dist/channels/slack/onboard.js +8 -11
- package/dist/channels/slack/onboarding-state.d.ts +3 -5
- package/dist/channels/slack/onboarding-state.js +9 -6
- package/dist/channels/slack/parse.d.ts +4 -13
- package/dist/channels/slack/parse.js +7 -28
- package/dist/channels/slack/preview.d.ts +12 -2
- package/dist/channels/slack/preview.js +292 -269
- package/dist/channels/slack/reaction.d.ts +11 -3
- package/dist/channels/slack/reaction.js +19 -8
- package/dist/channels/slack/register-webhook.js +4 -7
- package/dist/channels/slack/scaffold/channel.ts +20 -13
- package/dist/channels/slack/scaffold/slack-send.ts +2 -2
- package/dist/channels/slack/setup-server.d.ts +1 -5
- package/dist/channels/slack/setup-server.js +1 -5
- package/dist/channels/slack/shared-api.d.ts +1 -4
- package/dist/channels/slack/shared-api.js +2 -13
- package/dist/channels/slack/slack-api.d.ts +2 -1
- package/dist/channels/slack/slack-api.js +6 -4
- package/dist/channels/slack/slack.d.ts +11 -14
- package/dist/channels/slack/slack.js +121 -122
- package/dist/channels/sse.d.ts +1 -1
- package/dist/channels/sse.js +1 -1
- package/dist/channels/telegram/context-buffer.d.ts +7 -22
- package/dist/channels/telegram/context-buffer.js +6 -23
- package/dist/channels/telegram/invoke-turn.d.ts +7 -7
- package/dist/channels/telegram/invoke-turn.js +24 -43
- package/dist/channels/telegram/parse.d.ts +24 -51
- package/dist/channels/telegram/parse.js +32 -84
- package/dist/channels/telegram/preview.d.ts +10 -1
- package/dist/channels/telegram/preview.js +79 -100
- package/dist/channels/telegram/register-webhook.js +5 -23
- package/dist/channels/telegram/scaffold/channel.ts +25 -18
- package/dist/channels/telegram/scaffold/telegram-send.ts +6 -4
- package/dist/channels/telegram/telegram-api.d.ts +4 -3
- package/dist/channels/telegram/telegram-api.js +9 -7
- package/dist/channels/telegram/telegram.d.ts +4 -18
- package/dist/channels/telegram/telegram.js +38 -94
- package/dist/channels/telegram/turn-store.d.ts +11 -14
- package/dist/channels/telegram/turn-store.js +8 -6
- package/dist/channels/wait-health.d.ts +4 -6
- package/dist/channels/wait-health.js +10 -14
- package/dist/cli/add-feishu.d.ts +2 -12
- package/dist/cli/add-feishu.js +24 -71
- package/dist/cli/add-slack.d.ts +5 -3
- package/dist/cli/add-slack.js +53 -76
- package/dist/cli/auth-view.d.ts +2 -16
- package/dist/cli/auth-view.js +2 -16
- package/dist/cli/commands/add.js +25 -40
- package/dist/cli/commands/chat.d.ts +0 -1
- package/dist/cli/commands/chat.js +5 -6
- package/dist/cli/commands/deploy/agentcore.js +60 -65
- package/dist/cli/commands/deploy/docker.js +50 -23
- package/dist/cli/commands/deploy/fly.js +23 -61
- package/dist/cli/commands/deploy/railway.js +23 -18
- package/dist/cli/commands/deploy/shared.d.ts +38 -57
- package/dist/cli/commands/deploy/shared.js +40 -59
- package/dist/cli/commands/deploy.d.ts +10 -27
- package/dist/cli/commands/deploy.js +38 -60
- package/dist/cli/commands/destroy.d.ts +4 -0
- package/dist/cli/commands/destroy.js +56 -0
- package/dist/cli/commands/dev.d.ts +2 -1
- package/dist/cli/commands/dev.js +20 -23
- package/dist/cli/commands/info.d.ts +0 -2
- package/dist/cli/commands/info.js +83 -49
- package/dist/cli/commands/init.d.ts +1 -2
- package/dist/cli/commands/init.js +16 -55
- package/dist/cli/commands/invoke.d.ts +0 -1
- package/dist/cli/commands/invoke.js +5 -7
- package/dist/cli/commands/login.d.ts +2 -1
- package/dist/cli/commands/login.js +33 -38
- package/dist/cli/commands/logs.js +3 -4
- package/dist/cli/commands/models.js +1 -5
- package/dist/cli/commands/routine-run.d.ts +6 -0
- package/dist/cli/commands/routine-run.js +47 -0
- package/dist/cli/commands/routine.d.ts +25 -0
- package/dist/cli/commands/routine.js +122 -0
- package/dist/cli/commands/start.d.ts +31 -3
- package/dist/cli/commands/start.js +131 -81
- package/dist/cli/commands/tool.js +26 -12
- package/dist/cli/fail.d.ts +13 -23
- package/dist/cli/fail.js +20 -23
- package/dist/cli/invoke-stream.d.ts +1 -8
- package/dist/cli/kernel.d.ts +6 -38
- package/dist/cli/kernel.js +14 -77
- package/dist/cli/models-view.d.ts +1 -9
- package/dist/cli/models-view.js +11 -22
- package/dist/cli/program.d.ts +5 -6
- package/dist/cli/program.js +120 -157
- package/dist/cli/serve.d.ts +57 -41
- package/dist/cli/serve.js +94 -121
- package/dist/cli/shared.d.ts +15 -61
- package/dist/cli/shared.js +55 -181
- package/dist/cli.js +1 -8
- package/dist/collect.d.ts +6 -0
- package/dist/collect.js +6 -0
- package/dist/core.d.ts +4 -1
- package/dist/core.js +9 -7
- package/dist/declared-secrets.d.ts +55 -0
- package/dist/declared-secrets.js +88 -0
- package/dist/deploy/agentcore/aws-cli.d.ts +91 -0
- package/dist/deploy/agentcore/aws-cli.js +64 -0
- package/dist/deploy/agentcore/destroy.d.ts +51 -0
- package/dist/deploy/agentcore/destroy.js +273 -0
- package/dist/deploy/agentcore/forwarder.js +28 -79
- package/dist/deploy/agentcore/logs.d.ts +2 -18
- package/dist/deploy/agentcore/logs.js +27 -51
- package/dist/deploy/agentcore/plan.d.ts +85 -105
- package/dist/deploy/agentcore/plan.js +152 -314
- package/dist/deploy/agentcore/run.d.ts +28 -28
- package/dist/deploy/agentcore/run.js +227 -306
- package/dist/deploy/agentcore/zip.d.ts +2 -15
- package/dist/deploy/agentcore/zip.js +3 -17
- package/dist/deploy/build-context.d.ts +21 -0
- package/dist/deploy/build-context.js +137 -0
- package/dist/deploy/channel-ingress.d.ts +26 -39
- package/dist/deploy/channel-ingress.js +57 -28
- package/dist/deploy/container.d.ts +20 -34
- package/dist/deploy/container.js +49 -100
- package/dist/deploy/docker/plan.d.ts +12 -11
- package/dist/deploy/docker/plan.js +43 -24
- package/dist/deploy/docker/run.d.ts +22 -25
- package/dist/deploy/docker/run.js +39 -37
- package/dist/deploy/fly/plan.d.ts +15 -44
- package/dist/deploy/fly/plan.js +41 -73
- package/dist/deploy/fly/run.d.ts +16 -51
- package/dist/deploy/fly/run.js +42 -95
- package/dist/deploy/hosts.d.ts +24 -3
- package/dist/deploy/hosts.js +24 -3
- package/dist/deploy/preflight.d.ts +47 -41
- package/dist/deploy/preflight.js +282 -383
- package/dist/deploy/railway/plan.d.ts +16 -42
- package/dist/deploy/railway/plan.js +42 -60
- package/dist/deploy/railway/run.d.ts +30 -68
- package/dist/deploy/railway/run.js +86 -100
- package/dist/deploy/registration-gate.d.ts +6 -13
- package/dist/deploy/residency.d.ts +37 -0
- package/dist/deploy/residency.js +24 -0
- package/dist/deploy/runner.d.ts +10 -9
- package/dist/deploy/runner.js +7 -18
- package/dist/deploy/secrets.d.ts +40 -41
- package/dist/deploy/secrets.js +117 -103
- package/dist/deploy/workspace.d.ts +50 -0
- package/dist/deploy/workspace.js +197 -0
- package/dist/dev-supervisor.d.ts +1 -9
- package/dist/dev-supervisor.js +21 -64
- package/dist/effect-port.d.ts +50 -0
- package/dist/effect-port.js +77 -0
- package/dist/engines/pi/agent-session-factory.d.ts +50 -69
- package/dist/engines/pi/agent-session-factory.js +249 -146
- package/dist/engines/pi/auth.d.ts +15 -11
- package/dist/engines/pi/auth.js +96 -99
- package/dist/engines/pi/chat.d.ts +1 -5
- package/dist/engines/pi/chat.js +2 -14
- package/dist/engines/pi/config.d.ts +53 -51
- package/dist/engines/pi/config.js +83 -92
- package/dist/engines/pi/create.d.ts +60 -75
- package/dist/engines/pi/create.js +108 -141
- package/dist/engines/pi/definition.d.ts +14 -58
- package/dist/engines/pi/definition.js +21 -85
- package/dist/engines/pi/invoke-session.d.ts +5 -25
- package/dist/engines/pi/invoke-session.js +233 -244
- package/dist/engines/pi/login.d.ts +95 -35
- package/dist/engines/pi/login.js +259 -107
- package/dist/engines/pi/machine.d.ts +31 -0
- package/dist/engines/pi/machine.js +106 -0
- package/dist/engines/pi/models.d.ts +70 -89
- package/dist/engines/pi/models.js +188 -81
- package/dist/engines/pi/open.d.ts +65 -53
- package/dist/engines/pi/open.js +129 -69
- package/dist/engines/pi/report.d.ts +3 -12
- package/dist/engines/pi/report.js +2 -16
- package/dist/engines/pi/search-tools.d.ts +1 -9
- package/dist/engines/pi/search-tools.js +26 -57
- package/dist/engines/pi/service.d.ts +2 -16
- package/dist/engines/pi/service.js +2 -16
- package/dist/engines/pi/session-builder.d.ts +5 -9
- package/dist/engines/pi/session-builder.js +44 -82
- package/dist/engines/pi/session-control.js +286 -269
- package/dist/engines/pi/session-effects.d.ts +14 -0
- package/dist/engines/pi/session-effects.js +30 -0
- package/dist/engines/pi/session-inheritance.d.ts +9 -18
- package/dist/engines/pi/session-inheritance.js +103 -160
- package/dist/engines/pi/session-markers.d.ts +31 -30
- package/dist/engines/pi/session-markers.js +26 -25
- package/dist/engines/pi/session-settings.d.ts +6 -22
- package/dist/engines/pi/session-settings.js +10 -21
- package/dist/engines/pi/session-store.d.ts +26 -92
- package/dist/engines/pi/session-store.js +96 -310
- package/dist/engines/pi/tool-context.d.ts +17 -45
- package/dist/engines/pi/tool-context.js +7 -26
- package/dist/engines/pi/tool.d.ts +45 -36
- package/dist/engines/pi/tool.js +43 -57
- package/dist/engines/pi/turn-kit.d.ts +14 -52
- package/dist/engines/pi/turn-kit.js +18 -67
- package/dist/engines/pi/wake-tool.d.ts +2 -10
- package/dist/engines/pi/wake-tool.js +7 -27
- package/dist/env.d.ts +27 -28
- package/dist/env.js +45 -50
- package/dist/index.js +0 -2
- package/dist/lark.d.ts +1 -2
- package/dist/lark.js +1 -2
- package/dist/loader.d.ts +14 -55
- package/dist/loader.js +24 -43
- package/dist/log.d.ts +2 -12
- package/dist/log.js +3 -24
- package/dist/node.d.ts +2 -15
- package/dist/node.js +2 -18
- package/dist/observe.d.ts +2 -8
- package/dist/open-url.d.ts +1 -1
- package/dist/open-url.js +1 -1
- package/dist/paths.d.ts +70 -134
- package/dist/paths.js +165 -232
- package/dist/pi.d.ts +4 -6
- package/dist/pi.js +3 -3
- package/dist/proxy.d.ts +16 -6
- package/dist/proxy.js +52 -16
- package/dist/runtime.d.ts +18 -12
- package/dist/runtime.js +18 -11
- package/dist/scaffold/add-channel.d.ts +14 -31
- package/dist/scaffold/add-channel.js +48 -112
- package/dist/scaffold/init.d.ts +9 -31
- package/dist/scaffold/init.js +45 -138
- package/dist/scaffold/templates/env.example +6 -4
- package/dist/scaffold/templates/fastagent.config.ts +36 -0
- package/dist/scaffold/templates.d.ts +3 -3
- package/dist/scaffold/templates.js +5 -8
- package/dist/scaffold/vendor-skill.d.ts +2 -5
- package/dist/scaffold/vendor-skill.js +19 -29
- package/dist/schedule/cron.d.ts +9 -5
- package/dist/schedule/cron.js +9 -11
- package/dist/schedule/discover.d.ts +12 -12
- package/dist/schedule/discover.js +43 -34
- package/dist/schedule/routine.d.ts +43 -0
- package/dist/schedule/routine.js +32 -0
- package/dist/schedule/run.d.ts +55 -0
- package/dist/schedule/run.js +146 -0
- package/dist/schedule/scheduler.d.ts +44 -55
- package/dist/schedule/scheduler.js +291 -265
- package/dist/schedule/state.d.ts +105 -10
- package/dist/schedule/state.js +293 -19
- package/dist/schedule/wake-alarm.d.ts +10 -23
- package/dist/schedule/wake-alarm.js +91 -121
- package/dist/schedule/wakeups.d.ts +23 -39
- package/dist/schedule/wakeups.js +33 -75
- package/dist/secrets-gate.d.ts +32 -0
- package/dist/secrets-gate.js +33 -0
- package/dist/service.d.ts +137 -98
- package/dist/service.js +250 -252
- package/dist/session-remote.d.ts +33 -44
- package/dist/session-remote.js +203 -192
- package/dist/session.d.ts +166 -229
- package/dist/session.js +33 -55
- package/dist/tunnel.d.ts +8 -36
- package/dist/tunnel.js +24 -65
- package/dist/version.d.ts +2 -2
- package/dist/version.js +2 -2
- package/package.json +10 -16
- package/dist/channels/agentcore-state.d.ts +0 -77
- package/dist/channels/agentcore-state.js +0 -276
- package/dist/channels/github/github.d.ts +0 -31
- package/dist/channels/github/github.js +0 -89
- package/dist/channels/github/scaffold/channel.ts +0 -25
- package/dist/cli/commands/attach.d.ts +0 -108
- package/dist/cli/commands/attach.js +0 -637
- package/dist/cli/commands/fire.d.ts +0 -7
- package/dist/cli/commands/fire.js +0 -38
- package/dist/cli/commands/schedule.d.ts +0 -12
- package/dist/cli/commands/schedule.js +0 -87
- package/dist/github.d.ts +0 -3
- package/dist/github.js +0 -2
- package/dist/scaffold/templates/fastagent.config.mjs +0 -23
- package/dist/schedule/audit.d.ts +0 -18
- package/dist/schedule/audit.js +0 -57
- package/dist/schedule/schedule.d.ts +0 -35
- package/dist/schedule/schedule.js +0 -23
|
@@ -1,108 +1,226 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The pi `Models` collection — the single hub that owns BOTH model resolution (provider/modelId
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* the model's provider auth is in scope.
|
|
2
|
+
* The pi `Models` collection — the single hub that owns BOTH model resolution (provider/modelId lookup) AND auth
|
|
3
|
+
* (per-request credential resolution). fastagent builds one per opener and threads it into the engine alongside the
|
|
4
|
+
* selected `model`; the two must come from the same collection so the model's provider auth is in scope.
|
|
6
5
|
*/
|
|
6
|
+
import { createHash } from "node:crypto";
|
|
7
|
+
import { existsSync } from "node:fs";
|
|
8
|
+
import { readFile } from "node:fs/promises";
|
|
9
|
+
import { homedir } from "node:os";
|
|
7
10
|
import { join } from "node:path";
|
|
8
|
-
import { defaultProviderAuthContext } from "@earendil-works/pi-ai";
|
|
9
|
-
import { builtinModels } from "@earendil-works/pi-ai/providers/all";
|
|
11
|
+
import { InMemoryCredentialStore, defaultProviderAuthContext, } from "@earendil-works/pi-ai";
|
|
12
|
+
import { builtinModels, builtinProviders } from "@earendil-works/pi-ai/providers/all";
|
|
10
13
|
import { ModelRuntime } from "@earendil-works/pi-coding-agent";
|
|
11
14
|
import { fastagentCredentialStore } from "./auth.js";
|
|
12
15
|
import { providerOf } from "./config.js";
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
/**
|
|
16
|
-
* A `Models` with every built-in pi provider, wired to fastagent's auth: stored credentials from the
|
|
17
|
-
* {@link CreatePiModelsOptions.authPath} file (via {@link fastagentCredentialStore}; the global
|
|
18
|
-
* `~/.fastagent/.secrets/auth.json` unless the opener passes a project-level path), then ambient env vars. A
|
|
19
|
-
* stored credential owns the provider; env is consulted only when nothing is stored (resolution order
|
|
20
|
-
* is upstream-owned).
|
|
21
|
-
*/
|
|
16
|
+
import { AGENT_MODELS_FILE, GLOBAL_HOME_DIR, resolveOverridePath, resolveStateRoot } from "../../paths.js";
|
|
17
|
+
import { writeFileAtomic } from "../../atomic-write.js";
|
|
18
|
+
/** A `Models` with every built-in pi provider, wired to fastagent's auth. */
|
|
22
19
|
export function createPiModels(options = {}) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
return piModelsOver(fastagentCredentialStore(options.authPath, { warn: options.warn }), options.providers);
|
|
21
|
+
}
|
|
22
|
+
/** The built-ins plus `providers` (a same id replaces a built-in), over any credential store. */
|
|
23
|
+
export function piModelsOver(credentials, providers = []) {
|
|
24
|
+
const models = builtinModels({ credentials, authContext: defaultProviderAuthContext() });
|
|
25
|
+
for (const provider of providers)
|
|
28
26
|
models.setProvider(provider);
|
|
29
27
|
return models;
|
|
30
28
|
}
|
|
29
|
+
/** The serving default for reasoning effort, pinned to what pi's TUI defaults to (its own DEFAULT_THINKING_LEVEL). */
|
|
30
|
+
export const DEFAULT_THINKING_LEVEL = "medium";
|
|
31
31
|
/**
|
|
32
|
-
* The
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* an upstream default change in either place cannot silently alter deployments. Models that do not
|
|
36
|
-
* support a level are clamped by pi per model.
|
|
32
|
+
* The MACHINE's custom-endpoint file, in the same schema as an agent's own: endpoints a person set up for this machine
|
|
33
|
+
* (a local Ollama, a company gateway), which every agent here inherits the way it inherits the machine's skills.
|
|
34
|
+
* `FASTAGENT_MODELS_PATH` moves it. It never ships: a deployed agent has only its definition's file.
|
|
37
35
|
*/
|
|
38
|
-
export
|
|
36
|
+
export function machineModelsPath(env = process.env) {
|
|
37
|
+
return resolveOverridePath(env.FASTAGENT_MODELS_PATH) ?? join(homedir(), GLOBAL_HOME_DIR, AGENT_MODELS_FILE);
|
|
38
|
+
}
|
|
39
|
+
/** A custom-endpoint file's providers by id, or undefined when there is no file. Strict JSON: see {@link modelLayers}. */
|
|
40
|
+
async function readProviders(path) {
|
|
41
|
+
let raw;
|
|
42
|
+
try {
|
|
43
|
+
raw = await readFile(path, "utf8");
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
if (error.code === "ENOENT")
|
|
47
|
+
return undefined;
|
|
48
|
+
throw new Error(`could not read ${path}: ${error.message}`);
|
|
49
|
+
}
|
|
50
|
+
let parsed;
|
|
51
|
+
try {
|
|
52
|
+
parsed = JSON.parse(raw.replace(/^\uFEFF/, ""));
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
throw new Error(`${path} is not valid JSON: ${error.message}`);
|
|
56
|
+
}
|
|
57
|
+
const providers = parsed?.providers;
|
|
58
|
+
if (typeof providers !== "object" || providers === null || Array.isArray(providers)) {
|
|
59
|
+
throw new Error(`${path} must hold { "providers": { ... } }`);
|
|
60
|
+
}
|
|
61
|
+
return providers;
|
|
62
|
+
}
|
|
39
63
|
/**
|
|
40
|
-
* The
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* {@link AGENT_MODELS_FILE} when `agentDir` is given (a dir-less caller gets built-ins only), and no
|
|
44
|
-
* availability network, so the model surface equals serving's.
|
|
64
|
+
* The two custom-endpoint layers of an agent, read ONCE for every reader: the file pi loads and the report of where a
|
|
65
|
+
* provider came from both come from this, so what runs and what `info`/`deploy` say cannot disagree. Undefined when
|
|
66
|
+
* the machine has no file: then the agent's own file goes to pi untouched.
|
|
45
67
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
68
|
+
* Read here rather than by pi, because pi loads exactly one path and its comment stripping is not reachable: while a
|
|
69
|
+
* machine file exists, both files must be plain JSON.
|
|
70
|
+
*/
|
|
71
|
+
async function modelLayers(agentDir) {
|
|
72
|
+
const machinePath = machineModelsPath();
|
|
73
|
+
const machine = await readProviders(machinePath);
|
|
74
|
+
if (!machine)
|
|
75
|
+
return undefined;
|
|
76
|
+
return { machinePath, machine, own: (await readProviders(join(agentDir, AGENT_MODELS_FILE))) ?? {} };
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The models.json pi loads for an agent: its own file, layered over the machine's. The agent's file wins a provider id
|
|
80
|
+
* outright, as a definition's skill wins a name: an agent that pins an endpoint keeps it.
|
|
81
|
+
*
|
|
82
|
+
* The merge is a SNAPSHOT named by its content, in fastagent's own home: not in the agent (so `info` writes nothing
|
|
83
|
+
* there), and not in a shared temp dir, which the OS clears while a long-running process still re-reads it (pi
|
|
84
|
+
* reloads `modelsPath` on every refresh). Content addressing is what lets every process share the directory: a
|
|
85
|
+
* snapshot is never rewritten, so no process can change what another's refresh reads. The price is that a running
|
|
86
|
+
* process keeps the snapshot it started with; an edit to either file takes effect on the next start.
|
|
87
|
+
*
|
|
88
|
+
* ponytail: snapshots are never pruned (one per distinct content, a few KB each) because a running process may still
|
|
89
|
+
* read an old one; delete the directory while no fastagent process runs if it ever matters.
|
|
90
|
+
*/
|
|
91
|
+
async function modelsFileFor(agentDir) {
|
|
92
|
+
const definition = join(agentDir, AGENT_MODELS_FILE);
|
|
93
|
+
const layers = await modelLayers(agentDir);
|
|
94
|
+
if (!layers)
|
|
95
|
+
return { path: definition };
|
|
96
|
+
const content = JSON.stringify({ providers: { ...layers.machine, ...layers.own } }, null, 2);
|
|
97
|
+
const hash = createHash("sha256").update(content).digest("hex").slice(0, 32);
|
|
98
|
+
const path = join(homedir(), GLOBAL_HOME_DIR, ".cache", "models", `${hash}.json`);
|
|
99
|
+
// 0600: it may carry literal keys. Several processes may create the same snapshot at once.
|
|
100
|
+
if (!existsSync(path))
|
|
101
|
+
writeFileAtomic(path, content, 0o600, true);
|
|
102
|
+
return { path, merged: { machine: layers.machinePath, definition } };
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Where an agent's custom endpoints come from, for a report: the machine file, the providers the agent inherits from
|
|
106
|
+
* it, and the ones its own file overrides. Undefined when the machine has no file.
|
|
48
107
|
*/
|
|
108
|
+
export async function machineModels(agentDir) {
|
|
109
|
+
const layers = await modelLayers(agentDir);
|
|
110
|
+
if (!layers)
|
|
111
|
+
return undefined;
|
|
112
|
+
const ids = Object.keys(layers.machine).sort();
|
|
113
|
+
return {
|
|
114
|
+
path: layers.machinePath,
|
|
115
|
+
inherited: ids.filter((id) => !(id in layers.own)),
|
|
116
|
+
overridden: ids.filter((id) => id in layers.own),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/** Whether pi ships this provider id itself, so an agent resolves it without any models.json entry. */
|
|
120
|
+
export function isBuiltinProvider(providerId) {
|
|
121
|
+
return builtinProviders().some((provider) => provider.id === providerId);
|
|
122
|
+
}
|
|
123
|
+
/** The `ModelRuntime`-shaped sibling of {@link createPiModels}. */
|
|
49
124
|
export async function createPiModelRuntime(options = {}) {
|
|
50
125
|
const { agentDir } = options;
|
|
126
|
+
const models = !agentDir
|
|
127
|
+
? undefined
|
|
128
|
+
: options.machineLayer === false
|
|
129
|
+
? { path: join(agentDir, AGENT_MODELS_FILE) }
|
|
130
|
+
: await modelsFileFor(agentDir);
|
|
51
131
|
const runtime = await ModelRuntime.create({
|
|
52
|
-
credentials:
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
//
|
|
56
|
-
//
|
|
132
|
+
credentials: options.credentials ??
|
|
133
|
+
fastagentCredentialStore(options.auth?.path, { warn: options.warn, fallbackPath: options.auth?.fallback }),
|
|
134
|
+
modelsPath: models?.path ?? null,
|
|
135
|
+
// MUST be set whenever modelsPath is: pi defaults this to `<dirname(modelsPath)>/models-store.json`, which would
|
|
136
|
+
// write a generated cache INTO the author's agent dir.
|
|
57
137
|
...(agentDir
|
|
58
138
|
? { modelsStorePath: join(options.stateRoot ?? resolveStateRoot(agentDir), "models-store.json") }
|
|
59
139
|
: {}),
|
|
60
140
|
allowModelNetwork: false,
|
|
61
141
|
});
|
|
62
|
-
// A malformed models.json does NOT throw upstream — `create` resolves with the built-ins and parks the
|
|
63
|
-
//
|
|
64
|
-
// registry" at model-resolution time, i.e. the silent fallback this codebase forbids. The upstream
|
|
65
|
-
// message already names both the reason and the file, so it is surfaced verbatim.
|
|
142
|
+
// A malformed models.json does NOT throw upstream — `create` resolves with the built-ins and parks the reason in
|
|
143
|
+
// getError().
|
|
66
144
|
const error = runtime.getError();
|
|
67
|
-
if (error)
|
|
68
|
-
|
|
145
|
+
if (error) {
|
|
146
|
+
const origin = models?.merged
|
|
147
|
+
? `\n\nThat file merges ${models.merged.machine} with ${models.merged.definition} (the agent's own wins a provider id).`
|
|
148
|
+
: "";
|
|
149
|
+
throw new Error(`${error}${origin}`);
|
|
150
|
+
}
|
|
69
151
|
for (const provider of options.providers ?? [])
|
|
70
152
|
runtime.registerNativeProvider(provider);
|
|
71
153
|
return runtime;
|
|
72
154
|
}
|
|
73
|
-
/**
|
|
74
|
-
* How a model's credential will REACH a deployed agent — the question `deploy` asks, which
|
|
75
|
-
* {@link probeAuthSource} cannot answer: it flattens every models.json endpoint to the display label
|
|
76
|
-
* "configured API key", so a self-hosted endpoint looks credential-less to the deploy gate even when
|
|
77
|
-
* its key is sitting in an env var.
|
|
78
|
-
*
|
|
79
|
-
* - `envVar`: an environment variable backs it, BY NAME — the shape `deploy` already understands, so
|
|
80
|
-
* the value carries as a host secret with no extra declaration from the author.
|
|
81
|
-
* - `inDefinition`: the definition itself carries it (a literal `apiKey`, or a `!command` run on the
|
|
82
|
-
* host). Nothing for `deploy` to carry — and nothing to gate on either, which is the point: the
|
|
83
|
-
* `fastagent login` remedy is meaningless for a provider login cannot serve.
|
|
84
|
-
*
|
|
85
|
-
* Neither set = a stored credential or nothing at all; the existing auth.json / gate paths decide.
|
|
86
|
-
*/
|
|
155
|
+
/** How a model's credential will REACH a deployed agent. */
|
|
87
156
|
export function modelCredentialCarry(runtime, spec) {
|
|
88
157
|
const status = runtime.getProviderAuthStatus(providerOf(spec));
|
|
89
158
|
if (!status.configured)
|
|
90
159
|
return { inDefinition: false };
|
|
91
|
-
// An env-var name is only useful downstream if it IS one
|
|
92
|
-
// the environment but has no single name to carry, so it falls through to the definition-carried
|
|
93
|
-
// branch, where the author's `deploy.secrets` is the mechanism.
|
|
160
|
+
// An env-var name is only useful downstream if it IS one.
|
|
94
161
|
if (status.source === "environment" && status.label && /^[A-Z][A-Z0-9_]*$/.test(status.label)) {
|
|
95
162
|
return { envVar: status.label, inDefinition: false };
|
|
96
163
|
}
|
|
97
164
|
return { inDefinition: status.source !== "stored" };
|
|
98
165
|
}
|
|
99
166
|
/**
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
167
|
+
* EVERY provider whose `models.json` entry writes its key as a LITERAL rather than a `"$NAME"` reference or a
|
|
168
|
+
* `"!cmd"`. The file ships inside the image, so a literal there is a credential in a readable layer.
|
|
169
|
+
*
|
|
170
|
+
* Read from the FILE, not from `getProviderAuthStatus`: that answers "what satisfies this provider right now" and
|
|
171
|
+
* returns `stored` first, so a provider that has both an `auth.json` entry and a literal in the file would report
|
|
172
|
+
* `stored` and the literal would go unreported. The question is what the definition DECLARES, and only the file
|
|
173
|
+
* answers it. The three-way split mirrors pi's `configuredRequestAuthStatus`, which is not exported.
|
|
174
|
+
*
|
|
175
|
+
* The caller WARNS on this; it does not refuse. Whether a given string is a credential is the author's knowledge,
|
|
176
|
+
* not the framework's — pi's own docs prescribe `"apiKey": "ollama"` for a keyless local server, and no static rule
|
|
177
|
+
* separates that from a leaked key (an endpoint's reachability is not decidable from its URL either). FastAgent
|
|
178
|
+
* gates what IT causes; what the author wrote into their own committed file, it reports.
|
|
179
|
+
*/
|
|
180
|
+
export async function literalKeyProviders(agentDir) {
|
|
181
|
+
const file = join(agentDir, AGENT_MODELS_FILE);
|
|
182
|
+
let raw;
|
|
183
|
+
try {
|
|
184
|
+
raw = await readFile(file, "utf8");
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
// No custom endpoints is the normal case; anything else (unreadable, a directory) is the caller's problem.
|
|
188
|
+
if (error.code === "ENOENT")
|
|
189
|
+
return [];
|
|
190
|
+
throw error;
|
|
191
|
+
}
|
|
192
|
+
// Malformed JSON already threw out of createPiModelRuntime before this runs, so a parse failure here would be a
|
|
193
|
+
// genuine surprise and must not be swallowed.
|
|
194
|
+
const providers = JSON.parse(raw).providers ?? {};
|
|
195
|
+
return Object.entries(providers)
|
|
196
|
+
.filter(([, provider]) => isLiteralKey(provider?.apiKey))
|
|
197
|
+
.map(([id]) => id);
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* `!cmd` runs on the box; `$NAME` / `${NAME}` reads the environment; anything else is the key itself.
|
|
201
|
+
*
|
|
202
|
+
* `$$` is pi's escape for a literal `$`, so it is removed BEFORE looking for a reference — otherwise `"sk$$abc"`
|
|
203
|
+
* (which resolves to the literal `sk$abc`) would read as a reference and go unmentioned.
|
|
105
204
|
*/
|
|
205
|
+
function isLiteralKey(apiKey) {
|
|
206
|
+
if (typeof apiKey !== "string" || apiKey === "" || apiKey.startsWith("!"))
|
|
207
|
+
return false;
|
|
208
|
+
return !/\$\{?[A-Za-z_]/.test(apiKey.replaceAll("$$", ""));
|
|
209
|
+
}
|
|
210
|
+
export function interactiveLoginKind(p) {
|
|
211
|
+
if (interactiveAuth(p, "oauth"))
|
|
212
|
+
return "oauth";
|
|
213
|
+
return interactiveAuth(p, "api_key") ? "api_key" : "none";
|
|
214
|
+
}
|
|
215
|
+
/** THE rule for "can this method be signed in to interactively": the auth to run for it, or undefined. */
|
|
216
|
+
export function interactiveAuth(provider, method) {
|
|
217
|
+
return method === "oauth" ? provider.auth.oauth : provider.auth.apiKey?.login ? provider.auth.apiKey : undefined;
|
|
218
|
+
}
|
|
219
|
+
/** The providers a sign-in can target: pi's built-ins plus `extra`, composed exactly as {@link createPiModels} does. */
|
|
220
|
+
export function loginProviders(extra) {
|
|
221
|
+
return piModelsOver(new InMemoryCredentialStore(), extra).getProviders();
|
|
222
|
+
}
|
|
223
|
+
/** Probe every provider's auth once (auth is provider-scoped, so any of its models works as the probe). */
|
|
106
224
|
export async function providerAuthStatuses(models) {
|
|
107
225
|
const statuses = new Map();
|
|
108
226
|
for (const provider of models.getProviders()) {
|
|
@@ -120,12 +238,7 @@ export async function providerAuthStatuses(models) {
|
|
|
120
238
|
}
|
|
121
239
|
return statuses;
|
|
122
240
|
}
|
|
123
|
-
/**
|
|
124
|
-
* Which source currently satisfies auth for `spec` — a startup diagnostic. Returns the upstream
|
|
125
|
-
* `AuthResult.source` label: `"OAuth"` for a stored OAuth credential (e.g. a logged-in openai-codex),
|
|
126
|
-
* `"stored credential"` for a stored API key, an env-var name like `"ANTHROPIC_API_KEY"` for env, or
|
|
127
|
-
* undefined when unconfigured. Reporting-only; never throws.
|
|
128
|
-
*/
|
|
241
|
+
/** Which source currently satisfies auth for `spec` — a startup diagnostic. */
|
|
129
242
|
export async function probeAuthSource(models, spec) {
|
|
130
243
|
const slash = spec.indexOf("/");
|
|
131
244
|
if (slash < 1)
|
|
@@ -136,15 +249,8 @@ export async function probeAuthSource(models, spec) {
|
|
|
136
249
|
const auth = await models.getAuth(model).catch(() => undefined);
|
|
137
250
|
return auth?.source;
|
|
138
251
|
}
|
|
139
|
-
/**
|
|
140
|
-
|
|
141
|
-
* resolution path (the same path invokes take), so a mistyped key surfaces at login time, not at the
|
|
142
|
-
* first turn. `complete` reports provider errors as `stopReason: "error"` rather than throwing; the
|
|
143
|
-
* HTTP status arrives via `onResponse` — when a provider path never calls it (SDK transports), fall
|
|
144
|
-
* back to a conservative "401" match in the error text. Short timeout, no retries: feedback speed
|
|
145
|
-
* over transient-failure tolerance (a transient lands on `unknown`, which keeps the key).
|
|
146
|
-
*/
|
|
147
|
-
export async function probeApiKey(models, model) {
|
|
252
|
+
/** Quick-fail probe for a just-stored API key. */
|
|
253
|
+
export async function probeApiKey(models, model, signal) {
|
|
148
254
|
let status;
|
|
149
255
|
let reply;
|
|
150
256
|
try {
|
|
@@ -152,6 +258,7 @@ export async function probeApiKey(models, model) {
|
|
|
152
258
|
maxTokens: 16,
|
|
153
259
|
timeoutMs: 15_000,
|
|
154
260
|
maxRetries: 0,
|
|
261
|
+
...(signal ? { signal } : {}),
|
|
155
262
|
onResponse: (r) => {
|
|
156
263
|
status = r.status;
|
|
157
264
|
},
|
|
@@ -1,54 +1,58 @@
|
|
|
1
1
|
import type { Agent } from "../../agent.ts";
|
|
2
|
-
import { type FastagentConfig } from "./config.ts";
|
|
3
|
-
import type { SessionControl } from "../../session.ts";
|
|
2
|
+
import { type AuthLayers, type FastagentConfig } from "./config.ts";
|
|
3
|
+
import type { AgentCommand, SessionControl } from "../../session.ts";
|
|
4
4
|
import type { SessionObserver } from "./turn-kit.ts";
|
|
5
|
-
import type { ModuleLoadFailure } from "../../loader.ts";
|
|
6
5
|
import { type LoadedDefinition } from "./definition.ts";
|
|
6
|
+
import type { ModelRuntime } from "@earendil-works/pi-coding-agent";
|
|
7
|
+
import type { FastagentAuthOptions } from "./auth.ts";
|
|
7
8
|
import { type PiSessionRecordStore } from "./session-store.ts";
|
|
8
9
|
import type { ToolCollision, MountedTool } from "./tool.ts";
|
|
10
|
+
import type { DeclaredSecret } from "../../declared-secrets.ts";
|
|
11
|
+
import type { HttpSurface } from "../../service.ts";
|
|
12
|
+
/**
|
|
13
|
+
* The names a `/` composer completes: this agent's skills — the definition's, plus the ones its machine lends
|
|
14
|
+
* (machine.ts) —, the commands its `extensions/` register, and the machine's prompt templates.
|
|
15
|
+
*
|
|
16
|
+
* `source` says how a name is INVOKED, which is the one thing a client needs from it: a `skill` is sent as
|
|
17
|
+
* `/skill:<name>`, an `extension` command and a `prompt` as `/<name>` (docs/design/session-control.md §5.1.1).
|
|
18
|
+
*
|
|
19
|
+
* The definition is read live, like every turn reads it; the machine is the process's one read, the same snapshot a
|
|
20
|
+
* bound session runs on, so the menu cannot offer a name the next prompt would not expand. The same holds for
|
|
21
|
+
* extensions: `served` is what sessions load — the assembly's entry points, discovered once, and the runtime turns run
|
|
22
|
+
* on (asked only when there are extensions) — never a fresh scan of `extensions/`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function agentCommands(agentDir: string, workspace: string, served: {
|
|
25
|
+
extensionPaths: readonly string[];
|
|
26
|
+
modelRuntime: () => Promise<ModelRuntime>;
|
|
27
|
+
}): Promise<AgentCommand[]>;
|
|
9
28
|
export interface CreatePiAgentFromDirOptions {
|
|
10
|
-
/** Model spec override (e.g. the CLI --model flag).
|
|
29
|
+
/** Model spec override (e.g. the CLI --model flag). */
|
|
11
30
|
model?: string;
|
|
12
31
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
32
|
+
* Where conversations are stored, for an EMBEDDER that puts them somewhere the state root does not cover. There is
|
|
33
|
+
* no env or flag spelling of it: sessions are machine state, and the one knob that moves machine state is
|
|
34
|
+
* `FASTAGENT_STATE_DIR` (see {@link resolveSessionsDir}).
|
|
16
35
|
*/
|
|
17
36
|
sessionsDir?: string;
|
|
18
|
-
/**
|
|
19
|
-
* Credentials file override. Default `<agentDir>/.secrets/auth.json` (project-level, under the
|
|
20
|
-
* `.secrets/`). Override via --auth-path / FASTAGENT_AUTH_PATH; point it at
|
|
21
|
-
* the global `~/.fastagent/.secrets/auth.json` to share one credential across projects.
|
|
22
|
-
*/
|
|
37
|
+
/** Credentials file override. */
|
|
23
38
|
authPath?: string;
|
|
24
39
|
/**
|
|
25
|
-
* This is a long-running SERVE (`dev`/`start`), where the scheduler poller runs — so a self-scheduled
|
|
26
|
-
*
|
|
27
|
-
* and never poll). The built-in `wake` tool mounts only when this is set AND `config.selfSchedule` is on.
|
|
40
|
+
* This is a long-running SERVE (`dev`/`start`), where the scheduler poller runs — so a self-scheduled wake-up is
|
|
41
|
+
* actually honored.
|
|
28
42
|
*/
|
|
29
43
|
serving?: boolean;
|
|
30
|
-
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
|
|
35
|
-
* override either way. */
|
|
44
|
+
/**
|
|
45
|
+
* Wire the control plane's BOUNDARY (model changes, fork, delete) and publish it. A serve always gets the hub
|
|
46
|
+
* itself — stopping the running turn is a chat command, not a management endpoint — so this is the answer to
|
|
47
|
+
* "may a remote caller steer and rewrite this deployment", nothing else. Defaults to `config.sessionControl`.
|
|
48
|
+
*/
|
|
36
49
|
sessionControl?: boolean;
|
|
37
|
-
/** Additional raw tap with the FULL vocabulary
|
|
38
|
-
* {@link sessionControl} hub's observer, plus the hub's own boundary-mutation events
|
|
39
|
-
* (`state_changed`/`compaction_*`) via the hub's tap. TRUSTED seam: an observer receives each
|
|
40
|
-
* run's live modulation handles (see `SessionObserver`) — for read-only consumers
|
|
41
|
-
* use the hub's `events()` stream instead. */
|
|
50
|
+
/** Additional raw tap with the FULL vocabulary. */
|
|
42
51
|
observer?: SessionObserver;
|
|
43
52
|
}
|
|
44
53
|
/**
|
|
45
|
-
* The agent assembly FRONT HALF — everything that is independent of how pi consumes the
|
|
46
|
-
*
|
|
47
|
-
* placement resolution → config → model spec → the full tool surface ({@link resolveAgentTools} — the
|
|
48
|
-
* ONE place it is computed) → state root → auth path. Both {@link createPiAgentFromDir} and the
|
|
49
|
-
* session builder (session-builder.ts) consume this, so THESE inputs cannot drift between the two
|
|
50
|
-
* consumption shapes. (Definition loading and prompt assembly stay per-consumer: serving re-reads
|
|
51
|
-
* them live per invoke, the session builder snapshots at startup and lets pi append skills/env.)
|
|
54
|
+
* The agent assembly FRONT HALF — everything that is independent of how pi consumes the definition (a per-invoke
|
|
55
|
+
* session for serving vs a resident one for chat).
|
|
52
56
|
*/
|
|
53
57
|
export interface AgentAssembly {
|
|
54
58
|
config: FastagentConfig;
|
|
@@ -57,29 +61,39 @@ export interface AgentAssembly {
|
|
|
57
61
|
modelSpec: string;
|
|
58
62
|
/** Absolute agent dir — definition + config + machinery live here (resolvePlacement().agentDir). */
|
|
59
63
|
agentDir: string;
|
|
60
|
-
/** Absolute workspace — the agent's cwd and the start of the ②-context walk
|
|
61
|
-
* when the agent sits inside it, the agent dir ITSELF when you point at the agent. */
|
|
64
|
+
/** Absolute workspace — the agent's cwd and the start of the ②-context walk. */
|
|
62
65
|
workspace: string;
|
|
63
66
|
/** Absolute state root (FASTAGENT_STATE_DIR > <agentDir>/.state). */
|
|
64
67
|
stateRoot: string;
|
|
65
|
-
/**
|
|
66
|
-
|
|
68
|
+
/** The credentials files it reads ({@link resolveAuthLayers}). */
|
|
69
|
+
auth: AuthLayers;
|
|
67
70
|
/** The full mounted tool surface (all coding tools + config.tools + discovered tools/, search_tools applied). */
|
|
68
71
|
tools: MountedTool[];
|
|
69
72
|
toolNames: string[];
|
|
70
73
|
deferredToolNames: string[];
|
|
71
74
|
toolCollisions: ToolCollision[];
|
|
72
|
-
|
|
75
|
+
/** Env vars the mounted tools declared, by tool name — already asserted present by this function. */
|
|
76
|
+
toolSecrets: Map<string, DeclaredSecret[]>;
|
|
73
77
|
}
|
|
74
78
|
export declare function resolveAgentAssembly(dir: string, options?: {
|
|
75
79
|
model?: string;
|
|
76
80
|
authPath?: string;
|
|
77
81
|
}): Promise<AgentAssembly>;
|
|
78
82
|
/**
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
+
* The model specs `createPiAgentFromDir(dir, { authPath })` could run now: the agent's registry (pi's built-ins plus
|
|
84
|
+
* its `models.json`) filtered to the providers whose credentials are configured, sorted. The directory needs no model
|
|
85
|
+
* set, and the same placement and credential layers as the opener apply, so a listed spec authenticates there.
|
|
86
|
+
* Configuration is checked, not validity: no OAuth token is refreshed and no provider is called.
|
|
87
|
+
*
|
|
88
|
+
* `warn` reaches the credential store. An unreadable or corrupt credentials file otherwise reads as "nothing
|
|
89
|
+
* configured", so a client that must not show that as an empty list passes a sink that throws.
|
|
90
|
+
*/
|
|
91
|
+
export declare function availableModelsFromDir(dir: string, options?: FastagentAuthOptions & {
|
|
92
|
+
authPath?: string;
|
|
93
|
+
}): Promise<string[]>;
|
|
94
|
+
/**
|
|
95
|
+
* "Point at a directory → agent": resolve the placement (`dir` may be either end — the workspace or the agent dir
|
|
96
|
+
* itself), load the config, resolve model and tools, then L2.
|
|
83
97
|
*/
|
|
84
98
|
export declare function createPiAgentFromDir(dir: string, options?: CreatePiAgentFromDirOptions): Promise<{
|
|
85
99
|
agent: Agent;
|
|
@@ -96,21 +110,19 @@ export declare function createPiAgentFromDir(dir: string, options?: CreatePiAgen
|
|
|
96
110
|
stateRoot: string;
|
|
97
111
|
/** Absolute session store directory in use (for the startup report). */
|
|
98
112
|
sessionsDir: string;
|
|
99
|
-
/**
|
|
100
|
-
|
|
101
|
-
/** The session store in use. */
|
|
113
|
+
/** The credentials files in use — the startup report names whichever layer the credential came from. */
|
|
114
|
+
auth: AuthLayers;
|
|
102
115
|
sessions: PiSessionRecordStore;
|
|
103
|
-
/** The observation plane over this agent's sessions; present
|
|
116
|
+
/** The observation plane over this agent's sessions; present on every serve (a channel's stop command reaches the
|
|
117
|
+
* live run through it). Its boundary is wired only when {@link publishControl}. */
|
|
104
118
|
sessionControl?: SessionControl;
|
|
105
|
-
/** Whether
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
119
|
+
/** Whether that plane is also served as `/control/*` — `config.sessionControl`. */
|
|
120
|
+
publishControl: boolean;
|
|
121
|
+
/** What the serve publishes — `config.http`, handed to the assembly as-is (MountableAgent). */
|
|
122
|
+
http?: HttpSurface;
|
|
123
|
+
/** Non-default, active-by-default tool names in effect: config.tools + discovered tools/. */
|
|
110
124
|
toolNames: string[];
|
|
111
125
|
/** Tools registered but not initially active (deferred) — activated via search_tools. */
|
|
112
126
|
deferredToolNames: string[];
|
|
113
127
|
toolCollisions: ToolCollision[];
|
|
114
|
-
/** `tools/` files that failed to import — skipped, reported by the caller, never fatal. */
|
|
115
|
-
toolFailures: ModuleLoadFailure[];
|
|
116
128
|
}>;
|