@fastagent-sh/fastagent 0.24.3 → 0.25.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 +53 -82
- package/dist/agent-api.d.ts +452 -0
- package/dist/agent-api.js +201 -0
- package/dist/answer-text.d.ts +8 -0
- package/dist/answer-text.js +18 -0
- package/dist/atomic-write.d.ts +2 -2
- package/dist/atomic-write.js +2 -2
- package/dist/authoring.d.ts +77 -0
- package/dist/authoring.js +238 -0
- package/dist/channel.d.ts +29 -15
- package/dist/channel.js +4 -1
- package/dist/channels/agentcore-protocol.d.ts +36 -50
- package/dist/channels/agentcore-protocol.js +3 -3
- package/dist/channels/agentcore-service.d.ts +8 -18
- package/dist/channels/agentcore-service.js +108 -127
- package/dist/channels/agentcore.d.ts +8 -24
- package/dist/channels/agentcore.js +32 -65
- package/dist/channels/body.d.ts +0 -16
- package/dist/channels/body.js +0 -25
- package/dist/channels/busy.js +6 -1
- package/dist/channels/context.d.ts +4 -0
- package/dist/channels/context.js +35 -0
- package/dist/channels/discover.d.ts +18 -20
- package/dist/channels/discover.js +41 -99
- package/dist/channels/feishu/feishu-api.d.ts +54 -4
- package/dist/channels/feishu/feishu-api.js +192 -149
- package/dist/channels/feishu/feishu.d.ts +3 -0
- package/dist/channels/feishu/feishu.js +117 -106
- package/dist/channels/feishu/history.d.ts +55 -0
- package/dist/channels/feishu/history.js +199 -0
- package/dist/channels/feishu/invoke-turn.d.ts +13 -11
- package/dist/channels/feishu/invoke-turn.js +9 -10
- package/dist/channels/feishu/model.d.ts +2 -1
- package/dist/channels/feishu/normalize.js +100 -0
- package/dist/channels/feishu/preview.d.ts +2 -2
- package/dist/channels/feishu/register-webhook.d.ts +1 -0
- package/dist/channels/feishu/register-webhook.js +3 -2
- package/dist/channels/feishu/scaffold/channel.ts +65 -46
- package/dist/channels/feishu/scaffold/feishu-send.ts +38 -33
- package/dist/channels/feishu/scaffold/feishu-threads.ts +25 -0
- package/dist/channels/feishu/setup-mode.d.ts +45 -25
- package/dist/channels/feishu/setup-mode.js +74 -23
- package/dist/channels/feishu/shared-api.d.ts +24 -6
- package/dist/channels/feishu/shared-api.js +30 -24
- package/dist/channels/kit/context-buffer.d.ts +11 -2
- package/dist/channels/kit/context-buffer.js +7 -4
- package/dist/channels/kit/delivery.d.ts +19 -3
- package/dist/channels/kit/delivery.js +74 -15
- package/dist/channels/kit/event-stream.js +2 -1
- package/dist/channels/kit/invoke-turn-kit.d.ts +41 -41
- package/dist/channels/kit/invoke-turn-kit.js +62 -71
- package/dist/channels/kit/place-history.d.ts +107 -0
- package/dist/channels/kit/place-history.js +182 -0
- package/dist/channels/kit/preview-kit.d.ts +9 -5
- package/dist/channels/kit/preview-kit.js +36 -15
- package/dist/channels/kit/room-threads.d.ts +46 -0
- package/dist/channels/kit/room-threads.js +81 -0
- package/dist/channels/kit/seen.js +1 -1
- package/dist/channels/kit/stop-command.d.ts +6 -3
- package/dist/channels/kit/stop-command.js +20 -18
- package/dist/channels/kit/thread-fork.d.ts +17 -0
- package/dist/channels/kit/thread-fork.js +43 -0
- package/dist/channels/kit/thread-participants.js +1 -1
- package/dist/channels/kit/transport.d.ts +5 -0
- package/dist/channels/kit/transport.js +5 -0
- package/dist/channels/kit/turn-runner.d.ts +10 -9
- package/dist/channels/kit/turn-runner.js +17 -19
- package/dist/channels/kit/turn-store.d.ts +5 -4
- package/dist/channels/kit/turn-store.js +5 -5
- package/dist/channels/lark/lark.d.ts +3 -0
- package/dist/channels/lark/lark.js +5 -0
- package/dist/channels/lark/onboard.d.ts +5 -3
- package/dist/channels/lark/onboard.js +14 -14
- package/dist/channels/lark/scaffold/channel.ts +67 -44
- package/dist/channels/lark/scaffold/lark-send.ts +38 -33
- package/dist/channels/lark/scaffold/lark-threads.ts +25 -0
- package/dist/channels/respond.d.ts +0 -4
- package/dist/channels/respond.js +1 -1
- package/dist/channels/router.d.ts +18 -0
- package/dist/channels/router.js +68 -0
- package/dist/channels/serve.d.ts +5 -70
- package/dist/channels/serve.js +105 -287
- package/dist/channels/slack/history.d.ts +42 -0
- package/dist/channels/slack/history.js +282 -0
- package/dist/channels/slack/invoke-turn.d.ts +12 -5
- package/dist/channels/slack/invoke-turn.js +7 -5
- package/dist/channels/slack/manifest.d.ts +1 -4
- package/dist/channels/slack/manifest.js +22 -10
- package/dist/channels/slack/model.d.ts +2 -1
- package/dist/channels/slack/onboard.d.ts +0 -2
- package/dist/channels/slack/onboard.js +2 -4
- package/dist/channels/slack/onboarding-state.d.ts +0 -2
- package/dist/channels/slack/onboarding-state.js +0 -1
- package/dist/channels/slack/parse.d.ts +0 -5
- package/dist/channels/slack/parse.js +1 -16
- package/dist/channels/slack/preview.d.ts +2 -3
- package/dist/channels/slack/preview.js +78 -52
- package/dist/channels/slack/register-webhook.d.ts +1 -0
- package/dist/channels/slack/register-webhook.js +6 -5
- package/dist/channels/slack/scaffold/channel.ts +23 -24
- package/dist/channels/slack/scaffold/slack-send.ts +50 -43
- package/dist/channels/slack/scaffold/slack-threads.ts +29 -0
- package/dist/channels/slack/setup-server.d.ts +19 -0
- package/dist/channels/slack/setup-server.js +113 -11
- package/dist/channels/slack/shared-api.d.ts +15 -4
- package/dist/channels/slack/shared-api.js +19 -14
- package/dist/channels/slack/slack-api.d.ts +61 -2
- package/dist/channels/slack/slack-api.js +28 -5
- package/dist/channels/slack/slack.js +97 -52
- package/dist/channels/slack/welcomed.js +1 -1
- package/dist/channels/telegram/context-buffer.d.ts +6 -1
- package/dist/channels/telegram/context-buffer.js +19 -0
- package/dist/channels/telegram/invoke-turn.d.ts +8 -4
- package/dist/channels/telegram/invoke-turn.js +7 -7
- package/dist/channels/telegram/parse.d.ts +7 -2
- package/dist/channels/telegram/parse.js +7 -0
- package/dist/channels/telegram/preview.d.ts +2 -2
- package/dist/channels/telegram/register-webhook.d.ts +1 -0
- package/dist/channels/telegram/register-webhook.js +3 -2
- package/dist/channels/telegram/scaffold/channel.ts +27 -28
- package/dist/channels/telegram/scaffold/telegram-send.ts +61 -108
- package/dist/channels/telegram/shared-api.d.ts +34 -0
- package/dist/channels/telegram/shared-api.js +79 -0
- package/dist/channels/telegram/telegram-api.d.ts +15 -5
- package/dist/channels/telegram/telegram-api.js +10 -6
- package/dist/channels/telegram/telegram.js +27 -21
- package/dist/channels/telegram/turn-store.js +1 -1
- package/dist/channels/{kit/turn-queue.d.ts → turn-queue.d.ts} +2 -2
- package/dist/channels/{kit/turn-queue.js → turn-queue.js} +10 -10
- package/dist/cli/add-feishu.d.ts +42 -12
- package/dist/cli/add-feishu.js +177 -124
- package/dist/cli/add-slack.d.ts +8 -3
- package/dist/cli/add-slack.js +115 -63
- package/dist/cli/auth-view.d.ts +10 -3
- package/dist/cli/auth-view.js +8 -6
- package/dist/cli/box-login.d.ts +17 -7
- package/dist/cli/box-login.js +46 -12
- package/dist/cli/commands/add.d.ts +15 -4
- package/dist/cli/commands/add.js +252 -143
- package/dist/cli/commands/auth.d.ts +6 -0
- package/dist/cli/commands/auth.js +50 -0
- package/dist/cli/commands/content.d.ts +6 -0
- package/dist/cli/commands/content.js +45 -0
- package/dist/cli/commands/deploy/agentcore.js +50 -77
- package/dist/cli/commands/deploy/docker.js +38 -39
- package/dist/cli/commands/deploy/fly.js +21 -18
- package/dist/cli/commands/deploy/host-login.d.ts +26 -0
- package/dist/cli/commands/deploy/host-login.js +90 -0
- package/dist/cli/commands/deploy/railway.js +21 -26
- package/dist/cli/commands/deploy/shared.d.ts +45 -17
- package/dist/cli/commands/deploy/shared.js +34 -15
- package/dist/cli/commands/deploy.d.ts +0 -4
- package/dist/cli/commands/deploy.js +237 -50
- package/dist/cli/commands/destroy.js +8 -6
- package/dist/cli/commands/dev.d.ts +0 -2
- package/dist/cli/commands/dev.js +20 -19
- package/dist/cli/commands/env.d.ts +12 -0
- package/dist/cli/commands/env.js +190 -0
- package/dist/cli/commands/info.js +95 -156
- package/dist/cli/commands/init.d.ts +2 -2
- package/dist/cli/commands/init.js +35 -33
- package/dist/cli/commands/invoke.d.ts +6 -0
- package/dist/cli/commands/invoke.js +131 -16
- package/dist/cli/commands/login.d.ts +31 -2
- package/dist/cli/commands/login.js +413 -64
- package/dist/cli/commands/logout.d.ts +4 -0
- package/dist/cli/commands/logout.js +53 -0
- package/dist/cli/commands/logs.js +8 -6
- package/dist/cli/commands/models.d.ts +2 -1
- package/dist/cli/commands/models.js +39 -37
- package/dist/cli/commands/schedules.d.ts +21 -0
- package/dist/cli/commands/schedules.js +143 -0
- package/dist/cli/commands/start.d.ts +11 -10
- package/dist/cli/commands/start.js +35 -62
- package/dist/cli/content-view.d.ts +9 -0
- package/dist/cli/content-view.js +26 -0
- package/dist/cli/fail.d.ts +9 -12
- package/dist/cli/fail.js +17 -14
- package/dist/cli/invoke-stream.d.ts +12 -3
- package/dist/cli/invoke-stream.js +85 -23
- package/dist/cli/kernel.d.ts +9 -2
- package/dist/cli/kernel.js +15 -6
- package/dist/cli/login-relay.d.ts +3 -2
- package/dist/cli/login-relay.js +18 -6
- package/dist/cli/models-view.d.ts +5 -1
- package/dist/cli/models-view.js +1 -1
- package/dist/cli/person.d.ts +10 -0
- package/dist/cli/person.js +23 -0
- package/dist/cli/program.js +421 -203
- package/dist/cli/serve.d.ts +13 -63
- package/dist/cli/serve.js +31 -121
- package/dist/cli/shared.d.ts +21 -48
- package/dist/cli/shared.js +68 -89
- package/dist/cli/ticket.d.ts +136 -0
- package/dist/cli/ticket.js +476 -0
- package/dist/client.d.ts +7 -0
- package/dist/client.js +2 -0
- package/dist/content/declare.d.ts +70 -0
- package/dist/content/declare.js +163 -0
- package/dist/content/file.d.ts +32 -0
- package/dist/content/file.js +119 -0
- package/dist/content/git.d.ts +41 -0
- package/dist/content/git.js +217 -0
- package/dist/content/mount.d.ts +2 -0
- package/dist/content/mount.js +15 -0
- package/dist/content/resolve.d.ts +52 -0
- package/dist/content/resolve.js +151 -0
- package/dist/content/source.d.ts +27 -0
- package/dist/content/source.js +53 -0
- package/dist/conversation-sessions.d.ts +26 -0
- package/dist/conversation-sessions.js +99 -0
- package/dist/declared-secrets.d.ts +19 -37
- package/dist/declared-secrets.js +16 -58
- package/dist/deploy/agentcore/destroy.d.ts +3 -3
- package/dist/deploy/agentcore/destroy.js +46 -28
- package/dist/deploy/agentcore/forwarder.js +105 -22
- package/dist/deploy/agentcore/logs.js +1 -1
- package/dist/deploy/agentcore/plan.d.ts +10 -24
- package/dist/deploy/agentcore/plan.js +31 -135
- package/dist/deploy/agentcore/run.d.ts +1 -1
- package/dist/deploy/agentcore/run.js +8 -5
- package/dist/deploy/agentcore/shell.d.ts +1 -1
- package/dist/deploy/agentcore/shell.js +5 -5
- package/dist/deploy/api.d.ts +34 -0
- package/dist/deploy/api.js +50 -0
- package/dist/deploy/box-shell.d.ts +6 -0
- package/dist/deploy/box-shell.js +7 -0
- package/dist/deploy/build-context.d.ts +7 -5
- package/dist/deploy/build-context.js +41 -35
- package/dist/deploy/channel-ingress.d.ts +6 -1
- package/dist/deploy/channel-ingress.js +18 -5
- package/dist/deploy/container.d.ts +22 -9
- package/dist/deploy/container.js +96 -55
- package/dist/deploy/docker/plan.d.ts +3 -2
- package/dist/deploy/docker/plan.js +13 -14
- package/dist/deploy/docker/run.d.ts +2 -2
- package/dist/deploy/docker/run.js +8 -4
- package/dist/deploy/fly/plan.d.ts +1 -1
- package/dist/deploy/fly/plan.js +12 -21
- package/dist/deploy/fly/run.d.ts +10 -6
- package/dist/deploy/fly/run.js +11 -6
- package/dist/deploy/hosts.d.ts +2 -1
- package/dist/deploy/hosts.js +2 -1
- package/dist/deploy/preflight.d.ts +21 -23
- package/dist/deploy/preflight.js +222 -201
- package/dist/deploy/railway/plan.d.ts +8 -6
- package/dist/deploy/railway/plan.js +15 -58
- package/dist/deploy/railway/run.d.ts +8 -3
- package/dist/deploy/railway/run.js +12 -8
- package/dist/deploy/residency.d.ts +5 -11
- package/dist/deploy/residency.js +0 -6
- package/dist/deploy/runner.d.ts +1 -1
- package/dist/deploy/runner.js +1 -1
- package/dist/deploy/secrets.d.ts +16 -2
- package/dist/deploy/secrets.js +33 -6
- package/dist/deploy/workspace.d.ts +11 -6
- package/dist/deploy/workspace.js +55 -38
- package/dist/dev-supervisor.d.ts +11 -2
- package/dist/dev-supervisor.js +51 -26
- package/dist/effect-port.d.ts +4 -4
- package/dist/effect-port.js +4 -4
- package/dist/environment/apt.d.ts +4 -0
- package/dist/environment/apt.js +32 -0
- package/dist/environment/declare.d.ts +59 -0
- package/dist/environment/declare.js +210 -0
- package/dist/environment/mise.d.ts +50 -0
- package/dist/environment/mise.js +268 -0
- package/dist/feishu.d.ts +2 -2
- package/dist/feishu.js +2 -2
- package/dist/git.d.ts +13 -0
- package/dist/git.js +55 -0
- package/dist/harnesses/models/catalog.d.ts +20 -0
- package/dist/harnesses/models/catalog.js +254 -0
- package/dist/{engines/pi/auth.d.ts → harnesses/models/credentials.d.ts} +3 -3
- package/dist/{engines/pi/auth.js → harnesses/models/credentials.js} +3 -3
- package/dist/harnesses/models/environment.d.ts +43 -0
- package/dist/harnesses/models/environment.js +82 -0
- package/dist/{engines/pi → harnesses/models}/login.d.ts +57 -26
- package/dist/{engines/pi → harnesses/models}/login.js +187 -79
- package/dist/harnesses/models/models.d.ts +83 -0
- package/dist/harnesses/models/models.js +158 -0
- package/dist/harnesses/pi-durable/agent.d.ts +42 -0
- package/dist/harnesses/pi-durable/agent.js +579 -0
- package/dist/harnesses/pi-durable/defaults.d.ts +28 -0
- package/dist/harnesses/pi-durable/defaults.js +26 -0
- package/dist/harnesses/pi-durable/define.d.ts +77 -0
- package/dist/harnesses/pi-durable/define.js +28 -0
- package/dist/harnesses/pi-durable/entries.d.ts +32 -0
- package/dist/harnesses/pi-durable/entries.js +126 -0
- package/dist/harnesses/pi-durable/events.d.ts +25 -0
- package/dist/harnesses/pi-durable/events.js +238 -0
- package/dist/harnesses/pi-durable/ids.d.ts +16 -0
- package/dist/harnesses/pi-durable/ids.js +55 -0
- package/dist/harnesses/pi-durable/messages.d.ts +41 -0
- package/dist/harnesses/pi-durable/messages.js +116 -0
- package/dist/harnesses/pi-durable/open.d.ts +88 -0
- package/dist/harnesses/pi-durable/open.js +329 -0
- package/dist/harnesses/pi-durable/reads.d.ts +30 -0
- package/dist/harnesses/pi-durable/reads.js +94 -0
- package/dist/harnesses/pi-durable/registry.d.ts +18 -0
- package/dist/harnesses/pi-durable/registry.js +56 -0
- package/dist/harnesses/pi-durable/release.d.ts +13 -0
- package/dist/harnesses/pi-durable/release.js +40 -0
- package/dist/harnesses/pi-durable/serve.d.ts +80 -0
- package/dist/harnesses/pi-durable/serve.js +156 -0
- package/dist/harnesses/pi-durable/sessions.d.ts +27 -0
- package/dist/harnesses/pi-durable/sessions.js +47 -0
- package/dist/harnesses/pi-durable/storage.d.ts +4 -0
- package/dist/harnesses/pi-durable/storage.js +49 -0
- package/dist/harnesses/pi-durable/stream.d.ts +20 -0
- package/dist/harnesses/pi-durable/stream.js +221 -0
- package/dist/harnesses/pi-durable/text.d.ts +30 -0
- package/dist/harnesses/pi-durable/text.js +292 -0
- package/dist/harnesses/pi-durable/wake.d.ts +4 -0
- package/dist/harnesses/pi-durable/wake.js +81 -0
- package/dist/http/client.d.ts +6 -0
- package/dist/http/client.js +256 -0
- package/dist/http/contract.d.ts +541 -0
- package/dist/http/contract.js +179 -0
- package/dist/http/server.d.ts +34 -0
- package/dist/http/server.js +194 -0
- package/dist/index.d.ts +17 -4
- package/dist/index.js +10 -5
- package/dist/lark.d.ts +2 -2
- package/dist/lark.js +2 -2
- package/dist/locked-file.d.ts +17 -0
- package/dist/{engines/pi/locked-file.js → locked-file.js} +16 -10
- package/dist/once.d.ts +6 -0
- package/dist/once.js +23 -0
- package/dist/paths.d.ts +36 -52
- package/dist/paths.js +66 -182
- package/dist/runtime.d.ts +25 -2
- package/dist/runtime.js +27 -0
- package/dist/scaffold/add-channel.d.ts +14 -27
- package/dist/scaffold/add-channel.js +82 -180
- package/dist/scaffold/init.d.ts +17 -18
- package/dist/scaffold/init.js +87 -99
- package/dist/scaffold/templates/SYSTEM.md +12 -0
- package/dist/scaffold/templates/env.example +4 -10
- package/dist/scaffold/templates/fastagent.config.ts +21 -33
- package/dist/scaffold/templates/gitignore +8 -1
- package/dist/scaffold/templates/skills/writing-great-skills/SKILL.md +1 -2
- package/dist/scaffold/templates.d.ts +9 -4
- package/dist/scaffold/templates.js +7 -5
- package/dist/scaffold/vendor-skill.d.ts +1 -4
- package/dist/scaffold/vendor-skill.js +5 -6
- package/dist/schedule/cron.d.ts +13 -0
- package/dist/schedule/cron.js +52 -0
- package/dist/schedule/eventbridge-cron.d.ts +17 -0
- package/dist/schedule/eventbridge-cron.js +88 -0
- package/dist/schedule/schedule.d.ts +23 -0
- package/dist/schedule/schedule.js +34 -0
- package/dist/schedule/scheduler.d.ts +34 -33
- package/dist/schedule/scheduler.js +251 -137
- package/dist/schedule/state.d.ts +4 -14
- package/dist/schedule/state.js +7 -7
- package/dist/schedule/wake-alarm.d.ts +22 -2
- package/dist/schedule/wake-alarm.js +66 -20
- package/dist/schedule/wakeups.d.ts +16 -15
- package/dist/schedule/wakeups.js +47 -45
- package/dist/service.d.ts +56 -169
- package/dist/service.js +91 -187
- package/dist/serving-command.d.ts +10 -0
- package/dist/serving-command.js +16 -0
- package/dist/slack.d.ts +1 -1
- package/dist/slack.js +1 -1
- package/dist/{channels/kit/state.js → state-file.js} +6 -6
- package/dist/telegram.d.ts +1 -0
- package/dist/telegram.js +1 -0
- package/dist/tunnel.d.ts +3 -0
- package/dist/tunnel.js +12 -4
- package/dist/value-file.d.ts +21 -0
- package/dist/value-file.js +108 -0
- package/dist/version.d.ts +5 -0
- package/dist/version.js +14 -1
- package/package.json +18 -28
- package/dist/agent.d.ts +0 -106
- package/dist/agent.js +0 -21
- package/dist/channels/control.d.ts +0 -31
- package/dist/channels/control.js +0 -329
- package/dist/channels/define-channel.d.ts +0 -39
- package/dist/channels/define-channel.js +0 -9
- package/dist/channels/feishu/context-buffer.d.ts +0 -35
- package/dist/channels/feishu/context-buffer.js +0 -65
- package/dist/channels/feishu/scaffold/channel.websocket.ts +0 -31
- package/dist/channels/http.d.ts +0 -23
- package/dist/channels/http.js +0 -57
- package/dist/channels/lark/scaffold/channel.websocket.ts +0 -31
- package/dist/channels/slack/context-buffer.d.ts +0 -23
- package/dist/channels/slack/context-buffer.js +0 -37
- package/dist/channels/sse.d.ts +0 -4
- package/dist/channels/sse.js +0 -66
- package/dist/cli/commands/chat.d.ts +0 -3
- package/dist/cli/commands/chat.js +0 -14
- package/dist/cli/commands/routine-run.d.ts +0 -6
- package/dist/cli/commands/routine-run.js +0 -46
- package/dist/cli/commands/routine.d.ts +0 -25
- package/dist/cli/commands/routine.js +0 -122
- package/dist/cli/commands/tool.d.ts +0 -1
- package/dist/cli/commands/tool.js +0 -57
- package/dist/collect.d.ts +0 -63
- package/dist/collect.js +0 -90
- package/dist/core.d.ts +0 -13
- package/dist/core.js +0 -15
- package/dist/engines/pi/agent-models.d.ts +0 -83
- package/dist/engines/pi/agent-models.js +0 -120
- package/dist/engines/pi/agent-session-factory.d.ts +0 -121
- package/dist/engines/pi/agent-session-factory.js +0 -517
- package/dist/engines/pi/chat.d.ts +0 -3
- package/dist/engines/pi/chat.js +0 -8
- package/dist/engines/pi/config.d.ts +0 -71
- package/dist/engines/pi/config.js +0 -199
- package/dist/engines/pi/create.d.ts +0 -170
- package/dist/engines/pi/create.js +0 -343
- package/dist/engines/pi/definition.d.ts +0 -74
- package/dist/engines/pi/definition.js +0 -236
- package/dist/engines/pi/entry-images.d.ts +0 -14
- package/dist/engines/pi/entry-images.js +0 -23
- package/dist/engines/pi/invoke-session.d.ts +0 -18
- package/dist/engines/pi/invoke-session.js +0 -403
- package/dist/engines/pi/locked-file.d.ts +0 -9
- package/dist/engines/pi/machine.d.ts +0 -53
- package/dist/engines/pi/machine.js +0 -137
- package/dist/engines/pi/models.d.ts +0 -200
- package/dist/engines/pi/models.js +0 -533
- package/dist/engines/pi/open.d.ts +0 -180
- package/dist/engines/pi/open.js +0 -270
- package/dist/engines/pi/openai-account-models.d.ts +0 -35
- package/dist/engines/pi/openai-account-models.js +0 -116
- package/dist/engines/pi/report.d.ts +0 -18
- package/dist/engines/pi/report.js +0 -59
- package/dist/engines/pi/retry-event.d.ts +0 -6
- package/dist/engines/pi/retry-event.js +0 -15
- package/dist/engines/pi/service.d.ts +0 -9
- package/dist/engines/pi/service.js +0 -14
- package/dist/engines/pi/session-builder.d.ts +0 -13
- package/dist/engines/pi/session-builder.js +0 -117
- package/dist/engines/pi/session-control.d.ts +0 -77
- package/dist/engines/pi/session-control.js +0 -908
- package/dist/engines/pi/session-effects.d.ts +0 -14
- package/dist/engines/pi/session-effects.js +0 -30
- package/dist/engines/pi/session-inheritance.d.ts +0 -21
- package/dist/engines/pi/session-inheritance.js +0 -204
- package/dist/engines/pi/session-markers.d.ts +0 -49
- package/dist/engines/pi/session-markers.js +0 -60
- package/dist/engines/pi/session-settings.d.ts +0 -67
- package/dist/engines/pi/session-settings.js +0 -119
- package/dist/engines/pi/session-store.d.ts +0 -69
- package/dist/engines/pi/session-store.js +0 -430
- package/dist/engines/pi/tool-context.d.ts +0 -45
- package/dist/engines/pi/tool-context.js +0 -31
- package/dist/engines/pi/tool.d.ts +0 -99
- package/dist/engines/pi/tool.js +0 -118
- package/dist/engines/pi/turn-kit.d.ts +0 -83
- package/dist/engines/pi/turn-kit.js +0 -275
- package/dist/engines/pi/wake-tool.d.ts +0 -9
- package/dist/engines/pi/wake-tool.js +0 -92
- package/dist/loader.d.ts +0 -41
- package/dist/loader.js +0 -116
- package/dist/node.d.ts +0 -3
- package/dist/node.js +0 -4
- package/dist/observe.d.ts +0 -6
- package/dist/observe.js +0 -47
- package/dist/pi.d.ts +0 -25
- package/dist/pi.js +0 -15
- package/dist/scaffold/templates/APPEND_SYSTEM.md +0 -12
- package/dist/scaffold/templates/tools/fetch-url.ts +0 -25
- package/dist/schedule/discover.d.ts +0 -17
- package/dist/schedule/discover.js +0 -61
- package/dist/schedule/routine.d.ts +0 -43
- package/dist/schedule/routine.js +0 -32
- package/dist/schedule/run.d.ts +0 -55
- package/dist/schedule/run.js +0 -146
- package/dist/secrets-gate.d.ts +0 -32
- package/dist/secrets-gate.js +0 -33
- package/dist/session-remote.d.ts +0 -47
- package/dist/session-remote.js +0 -460
- package/dist/session.d.ts +0 -466
- package/dist/session.js +0 -57
- /package/dist/{channels/kit/state.d.ts → state-file.d.ts} +0 -0
package/dist/cli/serve.d.ts
CHANGED
|
@@ -1,81 +1,31 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import { type AgentService, type MountableAgent, type MountAgentServiceOptions } from "../service.ts";
|
|
1
|
+
import type { ServedAgent, ServeOptions, Service } from "../service.ts";
|
|
2
|
+
import type { AgentConfig } from "../harnesses/pi-durable/define.ts";
|
|
4
3
|
/** Refuse `--tunnel` with a `--bind` that cloudflared cannot reach. */
|
|
5
4
|
export declare function assertTunnelBindable(host: string | undefined, tunnel: boolean): void;
|
|
6
5
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* ONE place, because `dev` and `start` both do it and a mapping two call sites must each remember is one a third
|
|
10
|
-
* will not.
|
|
11
|
-
*
|
|
12
|
-
* `--no-invoke` outranks `http.invoke`: a config value travels into a deployed image, so "do not publish a turn
|
|
13
|
-
* endpoint on this tunnel" has to be sayable without editing the definition.
|
|
14
|
-
*
|
|
15
|
-
* It takes `POST /run` WITH it, including over a definition that said `http.run: true`. Both routes start a
|
|
16
|
-
* turn for an anonymous caller, and the flag's whole reason for existing is the case where the definition cannot be
|
|
17
|
-
* edited — `dev --tunnel --no-invoke` leaving the other one published at the tunnel URL would be the flag failing at
|
|
18
|
-
* exactly the job it was added for.
|
|
6
|
+
* What the CLI adds to the assembly: its shutdown grace, exit on a connection that drops, and the API's keys, none
|
|
7
|
+
* when the definition turns the API off, whatever key the environment holds (a host's from an earlier deploy).
|
|
19
8
|
*/
|
|
20
|
-
export declare function
|
|
21
|
-
invoke?: boolean;
|
|
22
|
-
}): T;
|
|
23
|
-
/** What the CLI adds to the assembly: its shutdown grace, and exit on a connection that drops. */
|
|
24
|
-
export declare function cliMountOptions(wrapAgent: (agent: Agent) => Agent): MountAgentServiceOptions;
|
|
9
|
+
export declare function cliMountOptions(config: AgentConfig): ServeOptions;
|
|
25
10
|
/**
|
|
26
|
-
* Bind, report,
|
|
27
|
-
*
|
|
11
|
+
* Bind, report, warn about reach, open the tunnel, and close in order on a signal — the tail dev's worker and start
|
|
12
|
+
* share once the service is assembled.
|
|
28
13
|
*/
|
|
29
|
-
export declare function serveService(service:
|
|
14
|
+
export declare function serveService(service: ServedAgent, bind: {
|
|
30
15
|
port: number;
|
|
31
16
|
host?: string;
|
|
32
17
|
}, posture: {
|
|
33
18
|
tunnel: boolean;
|
|
34
19
|
agentDir: string;
|
|
35
20
|
stateRoot: string;
|
|
21
|
+
config: AgentConfig;
|
|
36
22
|
}): void;
|
|
37
23
|
/** The "we are serving" report: the supervisor message `dev`'s watcher waits for, the addresses, and what mounted. */
|
|
38
|
-
export declare function reportServing(service:
|
|
24
|
+
export declare function reportServing(service: ServedAgent, host: string | undefined, boundPort: number, config: AgentConfig): void;
|
|
39
25
|
/** The line that names WHERE the serve is — every posture reports it, including AgentCore's own surface. */
|
|
40
26
|
export declare function bindLine(host: string | undefined, boundPort: number): string;
|
|
41
|
-
/**
|
|
42
|
-
|
|
43
|
-
*
|
|
44
|
-
* `servesInvoke` is `AgentService.unverifiedRoutes`, never a guess from the route table: `http.invoke: false` leaves no
|
|
45
|
-
* `/invoke` to curl, and a channel may serve that path with a protocol of its own — both would turn this line into
|
|
46
|
-
* a copyable request that fails.
|
|
47
|
-
*/
|
|
48
|
-
export declare function readyAddressLines(host: string | undefined, boundPort: number, servesInvoke: boolean): string[];
|
|
49
|
-
/**
|
|
50
|
-
* Say what this port exposes and how far it reaches.
|
|
51
|
-
*
|
|
52
|
-
* NOTHING fastagent serves is authenticated — authentication belongs to the deployment (a gateway, a private
|
|
53
|
-
* network, AgentCore's IAM, an embedder's middleware). Two of the three warnings fire at a REACH the operator did
|
|
54
|
-
* not get by default: a bind off this machine, and `--tunnel`'s public URL.
|
|
55
|
-
*
|
|
56
|
-
* The cross-origin one is UNCONDITIONAL, including on a loopback `dev`, because the grant is. `*` is the default
|
|
57
|
-
* (`channels/serve.ts`), so a page the developer merely visits can drive this port from their browser and read the
|
|
58
|
-
* reply, loopback bind or not. Nobody opts into a default, so the one posture the decision costs is the one that
|
|
59
|
-
* has to hear about it.
|
|
60
|
-
*
|
|
61
|
-
* WHAT IS EXPOSED is read off `AgentService.unverifiedRoutes`, never assumed and never guessed from the route table.
|
|
62
|
-
* `POST /invoke` is on most serves but not all: AgentCore answers the Runtime's `/invocations` behind IAM,
|
|
63
|
-
* `http.invoke: false` withholds it, and a channel may serve that path itself — in which case the caller it is
|
|
64
|
-
* open to is the platform that signs its requests, not anyone at all. A warning naming an endpoint this process
|
|
65
|
-
* does not serve is how an operator learns to skim past all of them — the same reason `preflightDeploy` takes
|
|
66
|
-
* `publicUrl`.
|
|
67
|
-
*/
|
|
68
|
-
export declare function announceControl(service: Pick<AgentService, "controlPrefix" | "unverifiedRoutes" | "corsOrigins">, bind: {
|
|
69
|
-
host?: string;
|
|
70
|
-
tunnel: boolean;
|
|
71
|
-
}): void;
|
|
72
|
-
/** Bind HTTP and report ready — but only once the SERVICE is, which is not the same moment. */
|
|
73
|
-
export declare function serve(handler: ChannelHandler, bind: {
|
|
27
|
+
/** Listen, and report ready — but only once the SERVICE is, which is not the same moment — until a signal closes it. */
|
|
28
|
+
export declare function serve(service: Service, bind: {
|
|
74
29
|
port: number;
|
|
75
30
|
host?: string;
|
|
76
|
-
},
|
|
77
|
-
/** Awaited before anything is reported ready — see the listening handler. */
|
|
78
|
-
ready?: Promise<void>;
|
|
79
|
-
onListening?: (boundPort: number) => void;
|
|
80
|
-
onShutdown?: () => Promise<void> | void;
|
|
81
|
-
}): void;
|
|
31
|
+
}, onListening?: (boundPort: number) => void): void;
|
package/dist/cli/serve.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/** What `dev` (its worker) and `start` need beyond the service itself. */
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { serveNode } from "../channels/serve.js";
|
|
2
|
+
import { answersLocalhost, bindLabel, classifyBind } from "../bind.js";
|
|
3
|
+
import { API_PREFIX } from "../http/contract.js";
|
|
4
|
+
import { API_KEY_VARIABLE, API_TURNED_OFF, apiKeysFrom, apiTurnedOff } from "../http/server.js";
|
|
6
5
|
import { log } from "../log.js";
|
|
7
6
|
import { openExternalUrl } from "../open-url.js";
|
|
8
7
|
import { declaredChannels } from "../channels/discover.js";
|
|
@@ -15,54 +14,36 @@ export function assertTunnelBindable(host, tunnel) {
|
|
|
15
14
|
failUsage(`--tunnel reaches the serve by dialing localhost, which the bind address ${host} does not answer — bind 0.0.0.0 (or 127.0.0.1), or drop --tunnel`);
|
|
16
15
|
}
|
|
17
16
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* ONE place, because `dev` and `start` both do it and a mapping two call sites must each remember is one a third
|
|
21
|
-
* will not.
|
|
22
|
-
*
|
|
23
|
-
* `--no-invoke` outranks `http.invoke`: a config value travels into a deployed image, so "do not publish a turn
|
|
24
|
-
* endpoint on this tunnel" has to be sayable without editing the definition.
|
|
25
|
-
*
|
|
26
|
-
* It takes `POST /run` WITH it, including over a definition that said `http.run: true`. Both routes start a
|
|
27
|
-
* turn for an anonymous caller, and the flag's whole reason for existing is the case where the definition cannot be
|
|
28
|
-
* edited — `dev --tunnel --no-invoke` leaving the other one published at the tunnel URL would be the flag failing at
|
|
29
|
-
* exactly the job it was added for.
|
|
17
|
+
* What the CLI adds to the assembly: its shutdown grace, exit on a connection that drops, and the API's keys, none
|
|
18
|
+
* when the definition turns the API off, whatever key the environment holds (a host's from an earlier deploy).
|
|
30
19
|
*/
|
|
31
|
-
export function
|
|
32
|
-
return run.invoke === false ? { ...opened, http: { ...opened.http, invoke: false, run: false } } : opened;
|
|
33
|
-
}
|
|
34
|
-
/** What the CLI adds to the assembly: its shutdown grace, and exit on a connection that drops. */
|
|
35
|
-
export function cliMountOptions(wrapAgent) {
|
|
20
|
+
export function cliMountOptions(config) {
|
|
36
21
|
return {
|
|
37
|
-
|
|
22
|
+
apiKeys: apiTurnedOff(config) ? [] : apiKeysFrom(process.env[API_KEY_VARIABLE]),
|
|
38
23
|
closeTimeoutMs: SHUTDOWN_GRACE_MS,
|
|
39
24
|
onChannelClosed: (name, error) => failStartup(new Error(`${name} ${error === undefined ? "closed unexpectedly" : `failed: ${String(error)}`}`)),
|
|
40
25
|
};
|
|
41
26
|
}
|
|
42
27
|
/**
|
|
43
|
-
* Bind, report,
|
|
44
|
-
*
|
|
28
|
+
* Bind, report, warn about reach, open the tunnel, and close in order on a signal — the tail dev's worker and start
|
|
29
|
+
* share once the service is assembled.
|
|
45
30
|
*/
|
|
46
31
|
export function serveService(service, bind, posture) {
|
|
47
32
|
const { host } = bind;
|
|
48
|
-
const { tunnel, agentDir, stateRoot } = posture;
|
|
49
|
-
serve(service
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
reportServing(service, host, p);
|
|
53
|
-
announceControl(service, { host, tunnel });
|
|
54
|
-
maybeTunnel(agentDir, service.channels.routes, p, tunnel, stateRoot);
|
|
55
|
-
},
|
|
56
|
-
onShutdown: () => service.close(),
|
|
33
|
+
const { tunnel, agentDir, stateRoot, config } = posture;
|
|
34
|
+
serve(service, bind, (p) => {
|
|
35
|
+
reportServing(service, host, p, config);
|
|
36
|
+
maybeTunnel(agentDir, service.channels.routes, p, tunnel, stateRoot);
|
|
57
37
|
});
|
|
58
38
|
}
|
|
59
39
|
/** The "we are serving" report: the supervisor message `dev`'s watcher waits for, the addresses, and what mounted. */
|
|
60
|
-
export function reportServing(service, host, boundPort) {
|
|
40
|
+
export function reportServing(service, host, boundPort, config) {
|
|
61
41
|
process.send?.({ type: "ready", port: boundPort, routeChannels: service.channels.routes });
|
|
62
|
-
|
|
63
|
-
log.info(line);
|
|
64
|
-
}
|
|
42
|
+
log.info(bindLine(host, boundPort));
|
|
65
43
|
log.info(`[fastagent] routes: ${Object.keys(service.routes).join(", ") || "(none)"}`);
|
|
44
|
+
log.info(service.api
|
|
45
|
+
? `[fastagent] Agent API: ${API_PREFIX} (keys from ${API_KEY_VARIABLE})`
|
|
46
|
+
: `[fastagent] Agent API: not served — ${apiTurnedOff(config) ? API_TURNED_OFF : `set ${API_KEY_VARIABLE} to serve it under ${API_PREFIX}`}`);
|
|
66
47
|
if (service.channels.longConnections.length > 0) {
|
|
67
48
|
log.info(`[fastagent] long connections: ${service.channels.longConnections.join(", ")}`);
|
|
68
49
|
}
|
|
@@ -72,79 +53,14 @@ export function bindLine(host, boundPort) {
|
|
|
72
53
|
return `[fastagent] http host on ${classifyBind(host) === "wildcard" ? `:${boundPort} (all interfaces)` : bindLabel(host, boundPort)}`;
|
|
73
54
|
}
|
|
74
55
|
/**
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* `servesInvoke` is `AgentService.unverifiedRoutes`, never a guess from the route table: `http.invoke: false` leaves no
|
|
78
|
-
* `/invoke` to curl, and a channel may serve that path with a protocol of its own — both would turn this line into
|
|
79
|
-
* a copyable request that fails.
|
|
80
|
-
*/
|
|
81
|
-
export function readyAddressLines(host, boundPort, servesInvoke) {
|
|
82
|
-
const dial = `${clientHost(host)}:${boundPort}`;
|
|
83
|
-
return [
|
|
84
|
-
bindLine(host, boundPort),
|
|
85
|
-
...(servesInvoke
|
|
86
|
-
? [
|
|
87
|
-
`[fastagent] try it: curl -s ${dial}/invoke -X POST -H 'content-type: application/json' -d '${INVOKE_EXAMPLE_BODY}'`,
|
|
88
|
-
]
|
|
89
|
-
: []),
|
|
90
|
-
];
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Say what this port exposes and how far it reaches.
|
|
94
|
-
*
|
|
95
|
-
* NOTHING fastagent serves is authenticated — authentication belongs to the deployment (a gateway, a private
|
|
96
|
-
* network, AgentCore's IAM, an embedder's middleware). Two of the three warnings fire at a REACH the operator did
|
|
97
|
-
* not get by default: a bind off this machine, and `--tunnel`'s public URL.
|
|
98
|
-
*
|
|
99
|
-
* The cross-origin one is UNCONDITIONAL, including on a loopback `dev`, because the grant is. `*` is the default
|
|
100
|
-
* (`channels/serve.ts`), so a page the developer merely visits can drive this port from their browser and read the
|
|
101
|
-
* reply, loopback bind or not. Nobody opts into a default, so the one posture the decision costs is the one that
|
|
102
|
-
* has to hear about it.
|
|
103
|
-
*
|
|
104
|
-
* WHAT IS EXPOSED is read off `AgentService.unverifiedRoutes`, never assumed and never guessed from the route table.
|
|
105
|
-
* `POST /invoke` is on most serves but not all: AgentCore answers the Runtime's `/invocations` behind IAM,
|
|
106
|
-
* `http.invoke: false` withholds it, and a channel may serve that path itself — in which case the caller it is
|
|
107
|
-
* open to is the platform that signs its requests, not anyone at all. A warning naming an endpoint this process
|
|
108
|
-
* does not serve is how an operator learns to skim past all of them — the same reason `preflightDeploy` takes
|
|
109
|
-
* `publicUrl`.
|
|
56
|
+
* What the CLI gives a long connection to stop in, and the hard exit that follows the whole close: the server's own
|
|
57
|
+
* grace for requests in flight (500 ms, channels/serve.ts), then the channels'.
|
|
110
58
|
*/
|
|
111
|
-
export function announceControl(service, bind) {
|
|
112
|
-
const { controlPrefix, corsOrigins } = service;
|
|
113
|
-
if (controlPrefix)
|
|
114
|
-
log.info(`[fastagent] session control on ${controlPrefix}/*`);
|
|
115
|
-
// What an unauthenticated caller of this port can do, worst first. From `unverifiedRoutes`, so a channel that serves
|
|
116
|
-
// `/invoke` itself is not described as our unauthenticated data plane — it has its own signature check.
|
|
117
|
-
const exposed = describeAnonymousSurface({
|
|
118
|
-
invoke: service.unverifiedRoutes.includes("POST /invoke"),
|
|
119
|
-
run: service.unverifiedRoutes.includes("POST /run"),
|
|
120
|
-
...(controlPrefix ? { controlPrefix } : {}),
|
|
121
|
-
});
|
|
122
|
-
if (exposed.length === 0)
|
|
123
|
-
return; // nothing of ours answers here (the AgentCore adapter's surface)
|
|
124
|
-
const what = `${exposed.join(" and ")} ${exposed.length > 1 ? "answer" : "answers"}`;
|
|
125
|
-
if (corsOrigins === undefined || corsOrigins.includes("*")) {
|
|
126
|
-
log.warn(`[fastagent] any web page your browser visits can call this serve cross-origin and read the reply: ${what} ` +
|
|
127
|
-
"with no credential. That is the default (`*`); pin the origins you actually use with http.cors " +
|
|
128
|
-
"(docs/design/session-control.md §14)");
|
|
129
|
-
}
|
|
130
|
-
const reach = classifyBind(bind.host);
|
|
131
|
-
if (reach !== "loopback") {
|
|
132
|
-
log.warn(`[fastagent] the port binds ${reach === "wildcard" ? "all interfaces" : `${bind.host} (off this machine)`}: ` +
|
|
133
|
-
`${what} UNAUTHENTICATED to anyone who can reach it — bind loopback (--bind 127.0.0.1), ` +
|
|
134
|
-
"firewall the port, or front it with a gateway (docs/design/session-control.md §14)");
|
|
135
|
-
}
|
|
136
|
-
if (bind.tunnel) {
|
|
137
|
-
log.warn(`[fastagent] --tunnel publishes this port at a public URL with NO authentication: ${what} to anyone with ` +
|
|
138
|
-
"that URL — put real auth in front before sharing it (docs/design/session-control.md §14)");
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
/** What the CLI gives a service to stop in, and the hard exit that follows it. */
|
|
142
59
|
const SHUTDOWN_GRACE_MS = 800;
|
|
143
60
|
const FORCED_EXIT_MS = 1_500;
|
|
144
|
-
/**
|
|
145
|
-
export function serve(
|
|
61
|
+
/** Listen, and report ready — but only once the SERVICE is, which is not the same moment — until a signal closes it. */
|
|
62
|
+
export function serve(service, bind, onListening) {
|
|
146
63
|
const { port, host } = bind;
|
|
147
|
-
const hosted = serveNode(handler, { port, host });
|
|
148
64
|
let stopping = false;
|
|
149
65
|
const stop = (exitCode) => {
|
|
150
66
|
if (stopping)
|
|
@@ -155,33 +71,27 @@ export function serve(handler, bind, hooks = {}) {
|
|
|
155
71
|
log.error(`[fastagent] shutdown did not finish within ${FORCED_EXIT_MS}ms; exiting`);
|
|
156
72
|
process.exit(1);
|
|
157
73
|
}, FORCED_EXIT_MS);
|
|
158
|
-
// Stop accepting FIRST, before anything is awaited.
|
|
159
|
-
const closingServer = hosted.close();
|
|
160
|
-
hosted.closeAllConnections();
|
|
161
74
|
// A cleanup that failed is not a clean exit.
|
|
162
|
-
void
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
code = 1;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
75
|
+
void service.close().then(() => {
|
|
76
|
+
clearTimeout(deadline);
|
|
77
|
+
process.exit(exitCode);
|
|
78
|
+
}, (error) => {
|
|
79
|
+
log.error(`[fastagent] shutdown failed: ${String(error)}`);
|
|
170
80
|
clearTimeout(deadline);
|
|
171
|
-
process.exit(
|
|
81
|
+
process.exit(1);
|
|
172
82
|
});
|
|
173
83
|
};
|
|
174
84
|
process.once("SIGINT", () => stop(0));
|
|
175
85
|
process.once("SIGTERM", () => stop(0));
|
|
176
|
-
|
|
86
|
+
service.listen(port, host).then(async (boundPort) => {
|
|
177
87
|
try {
|
|
178
88
|
// A bound socket is NOT a serving agent: a declared socket-mode channel still has to come up, and reporting
|
|
179
89
|
// ready before it does tells the supervisor (and --tunnel, and the operator) that a surface is live while a
|
|
180
90
|
// channel is dead.
|
|
181
|
-
await
|
|
91
|
+
await service.ready;
|
|
182
92
|
if (stopping)
|
|
183
93
|
return;
|
|
184
|
-
|
|
94
|
+
onListening?.(boundPort);
|
|
185
95
|
}
|
|
186
96
|
catch (error) {
|
|
187
97
|
failStartup(error);
|
package/dist/cli/shared.d.ts
CHANGED
|
@@ -1,61 +1,32 @@
|
|
|
1
|
-
import { type LoginIO } from "../
|
|
2
|
-
import { type
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { type LoginIO } from "../harnesses/models/login.ts";
|
|
2
|
+
import { type ModelEnvironment } from "../harnesses/models/environment.ts";
|
|
3
|
+
import type { OpenedServing } from "../harnesses/pi-durable/serve.ts";
|
|
4
|
+
/** An agent directory a command entered, and the default model that then resolves, if any. */
|
|
5
|
+
export interface EnteredAgent {
|
|
6
|
+
agentDir: string;
|
|
7
|
+
modelSpec?: string;
|
|
8
|
+
}
|
|
7
9
|
/**
|
|
8
|
-
* How a command enters its agent directory, in the one order that works:
|
|
9
|
-
* first-run model picker. Returns the default model that then resolves, if any. `deploy` uses this directly: it
|
|
10
|
-
* a missing model itself, by what will ship.
|
|
10
|
+
* How a command enters its agent directory, in the one order that works: the directory, the agent's environment, then
|
|
11
|
+
* the first-run model picker. Returns the default model that then resolves, if any. `deploy` uses this directly: it
|
|
12
|
+
* gates a missing model itself, by what will ship. `before`: what the command checks of the directory before a model
|
|
13
|
+
* is asked for (`schedules run`: that the schedule it names exists).
|
|
11
14
|
*/
|
|
12
15
|
export declare function enterAgentDirectory(dirArg: string, opts: {
|
|
13
16
|
model?: string;
|
|
14
17
|
input?: boolean;
|
|
15
|
-
}): Promise<
|
|
16
|
-
modelSpec?: string;
|
|
17
|
-
}>;
|
|
18
|
+
}, before?: (agentDir: string) => Promise<void>): Promise<EnteredAgent>;
|
|
18
19
|
/**
|
|
19
|
-
* How every command that RUNS the agent on this machine enters it (dev, start, invoke,
|
|
20
|
+
* How every command that RUNS the agent on this machine enters it (dev, start, invoke, schedules run):
|
|
20
21
|
* {@link enterAgentDirectory}, plus a default model. The agent opens without one, but a process here would then fail
|
|
21
|
-
* every new conversation, so it stops at startup
|
|
22
|
+
* every new conversation, so it stops at startup instead: exit 2, the choice a terminal's picker would have asked for.
|
|
22
23
|
*/
|
|
23
24
|
export declare function enterAgentCommand(dirArg: string, opts: {
|
|
24
25
|
model?: string;
|
|
25
26
|
input?: boolean;
|
|
26
|
-
}): Promise<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* The startup half of {@link enterAgentCommand}, for the one command that checks something of its own in between:
|
|
31
|
-
* `routine run`, whose unknown name or unset secret is the more basic fault and is reported first.
|
|
32
|
-
*/
|
|
33
|
-
export declare function requireDefaultModel(placement: ResolvedPlacement & {
|
|
34
|
-
modelSpec?: string;
|
|
35
|
-
}): ResolvedPlacement & {
|
|
36
|
-
modelSpec: string;
|
|
37
|
-
};
|
|
38
|
-
/** What the startup report reads off an opened directory. */
|
|
39
|
-
export interface ReportableAssembly {
|
|
40
|
-
agentDir: string;
|
|
41
|
-
workspace: string;
|
|
42
|
-
modelSpec: string;
|
|
43
|
-
models: AgentModels;
|
|
44
|
-
config: {
|
|
45
|
-
thinkingLevel?: string;
|
|
46
|
-
};
|
|
47
|
-
definition: LoadedDefinition;
|
|
48
|
-
toolNames: string[];
|
|
49
|
-
indirectTools: IndirectTool[];
|
|
50
|
-
toolCollisions: ToolCollision[];
|
|
51
|
-
}
|
|
52
|
-
/** What `dev` and `start` say about the directory they just opened, in the order they say it. */
|
|
53
|
-
export declare function reportAssembly(a: ReportableAssembly, extras?: {
|
|
54
|
-
/** Printed between `workspace:` and `model:` (`dev` names the config file here). */
|
|
55
|
-
beforeModel?: [label: string, value: string][];
|
|
56
|
-
/** Printed after the tool lines, before findings (`start` names state + sessions here). */
|
|
57
|
-
afterTools?: [label: string, value: string][];
|
|
58
|
-
}): Promise<void>;
|
|
27
|
+
}, before?: (agentDir: string) => Promise<void>): Promise<Required<EnteredAgent>>;
|
|
28
|
+
/** What `dev` and `start` say about the agent they just opened, in the order they say it. */
|
|
29
|
+
export declare function reportAssembly(opened: OpenedServing, modelSpec: string, extras?: [label: string, value: string][]): Promise<void>;
|
|
59
30
|
/** Both stdin and stdout are a terminal — the precondition for an interactive prompt. */
|
|
60
31
|
export declare function isInteractive(): boolean;
|
|
61
32
|
/** Parse + range-check a port string (CLI flag or env). */
|
|
@@ -66,6 +37,8 @@ export declare function parsePort(value: string | undefined, source: string, fro
|
|
|
66
37
|
*/
|
|
67
38
|
export declare function parseBind(value: string | undefined): string | undefined;
|
|
68
39
|
/** Report which source provides the model's credentials, surfacing a remediation hint at startup. */
|
|
69
|
-
export declare function reportAuth(models:
|
|
40
|
+
export declare function reportAuth(models: ModelEnvironment, modelSpec: string, agentDir: string): Promise<void>;
|
|
70
41
|
/** Login terminal IO via @clack/prompts: a searchable list once long, a hidden prompt for keys. */
|
|
71
42
|
export declare function terminalLoginIO(): LoginIO;
|
|
43
|
+
/** A copy/paste-safe POSIX shell argument for a command the CLI prints. */
|
|
44
|
+
export declare function shellArg(value: string): string;
|
package/dist/cli/shared.js
CHANGED
|
@@ -2,79 +2,68 @@
|
|
|
2
2
|
* Helpers shared across command modules: interactivity gates, port parsing, the startup auth report, first-run model
|
|
3
3
|
* resolution, and the login terminal IO.
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
6
|
-
import { relative, resolve } from "node:path";
|
|
5
|
+
import { resolve } from "node:path";
|
|
7
6
|
import { autocomplete, isCancel, log as clackLog, password, select, text as clackText } from "@clack/prompts";
|
|
8
7
|
import { buildModelPickerOptions } from "./models-view.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import { agentModels } from "../engines/pi/agent-models.js";
|
|
8
|
+
import { LoginCancelled, loginFlow } from "../harnesses/models/login.js";
|
|
9
|
+
import { modelEnvironment } from "../harnesses/models/environment.js";
|
|
10
|
+
import { listModels, providerAuthStatuses, providerOf } from "../harnesses/models/models.js";
|
|
11
|
+
import { definitionProviders, loadConfig, modelSpecFor } from "../harnesses/pi-durable/open.js";
|
|
14
12
|
import { formatAuthReport } from "./auth-view.js";
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import { isDeployedWorkspace } from "../paths.js";
|
|
13
|
+
import { contentLines } from "./content-view.js";
|
|
14
|
+
import { deployedHost, isDeployedWorkspace } from "../paths.js";
|
|
18
15
|
import { log } from "../log.js";
|
|
19
|
-
import { enterAgentEnv } from "../env.js";
|
|
16
|
+
import { dotEnvPath, enterAgentEnv } from "../env.js";
|
|
20
17
|
import { openExternalUrl } from "../open-url.js";
|
|
21
18
|
import { bindAddress, isBindAddress } from "../bind.js";
|
|
22
|
-
import { failStartup, failUsage
|
|
19
|
+
import { agentDirOrExit, failStartup, failUsage } from "./fail.js";
|
|
23
20
|
/**
|
|
24
|
-
* How a command enters its agent directory, in the one order that works:
|
|
25
|
-
* first-run model picker. Returns the default model that then resolves, if any. `deploy` uses this directly: it
|
|
26
|
-
* a missing model itself, by what will ship.
|
|
21
|
+
* How a command enters its agent directory, in the one order that works: the directory, the agent's environment, then
|
|
22
|
+
* the first-run model picker. Returns the default model that then resolves, if any. `deploy` uses this directly: it
|
|
23
|
+
* gates a missing model itself, by what will ship. `before`: what the command checks of the directory before a model
|
|
24
|
+
* is asked for (`schedules run`: that the schedule it names exists).
|
|
27
25
|
*/
|
|
28
|
-
export async function enterAgentDirectory(dirArg, opts) {
|
|
29
|
-
const
|
|
30
|
-
enterAgentEnv(
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
export async function enterAgentDirectory(dirArg, opts, before) {
|
|
27
|
+
const agentDir = agentDirOrExit(resolve(dirArg));
|
|
28
|
+
enterAgentEnv(agentDir);
|
|
29
|
+
await before?.(agentDir);
|
|
30
|
+
const modelSpec = await resolveFirstRunModel(agentDir, opts);
|
|
31
|
+
return { agentDir, ...(modelSpec ? { modelSpec } : {}) };
|
|
33
32
|
}
|
|
34
33
|
/**
|
|
35
|
-
* How every command that RUNS the agent on this machine enters it (dev, start, invoke,
|
|
34
|
+
* How every command that RUNS the agent on this machine enters it (dev, start, invoke, schedules run):
|
|
36
35
|
* {@link enterAgentDirectory}, plus a default model. The agent opens without one, but a process here would then fail
|
|
37
|
-
* every new conversation, so it stops at startup
|
|
36
|
+
* every new conversation, so it stops at startup instead: exit 2, the choice a terminal's picker would have asked for.
|
|
38
37
|
*/
|
|
39
|
-
export async function enterAgentCommand(dirArg, opts) {
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const { modelSpec } = placement;
|
|
48
|
-
if (!modelSpec)
|
|
49
|
-
failStartup(missingDefaultModel());
|
|
50
|
-
return { ...placement, modelSpec };
|
|
38
|
+
export async function enterAgentCommand(dirArg, opts, before) {
|
|
39
|
+
const entered = await enterAgentDirectory(dirArg, opts, before);
|
|
40
|
+
const { modelSpec } = entered;
|
|
41
|
+
if (!modelSpec) {
|
|
42
|
+
failUsage(`missing model: set --model, "model" in fastagent.config.ts, or FASTAGENT_MODEL (e.g. "openai/gpt-5.5"; ` +
|
|
43
|
+
"`fastagent models` lists them)");
|
|
44
|
+
}
|
|
45
|
+
return { ...entered, modelSpec };
|
|
51
46
|
}
|
|
52
47
|
/** The padded label writer for the STARTUP report (`dev`/`start`, stderr via the log level). */
|
|
53
48
|
function reportLine(label, value) {
|
|
54
49
|
log.info(`[fastagent] ${`${label}:`.padEnd(13)}${value}`);
|
|
55
50
|
}
|
|
56
|
-
/** What `dev` and `start` say about the
|
|
57
|
-
export async function reportAssembly(
|
|
58
|
-
|
|
59
|
-
reportLine("
|
|
60
|
-
for (const [label, value] of
|
|
51
|
+
/** What `dev` and `start` say about the agent they just opened, in the order they say it. */
|
|
52
|
+
export async function reportAssembly(opened, modelSpec, extras = []) {
|
|
53
|
+
const { definition, code, models, agentDir, stateRoot } = opened;
|
|
54
|
+
reportLine("agent", `${definition.name} — ${agentDir}`);
|
|
55
|
+
for (const [label, value] of contentLines(opened.content))
|
|
61
56
|
reportLine(label, value);
|
|
62
|
-
reportLine("model", `${
|
|
63
|
-
await reportAuth(
|
|
64
|
-
|
|
65
|
-
reportLine("
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
reportLine("
|
|
69
|
-
reportLine("
|
|
70
|
-
|
|
71
|
-
reportLine("tools", a.toolNames.join(", "));
|
|
72
|
-
if (a.indirectTools.length > 0)
|
|
73
|
-
reportLine("indirect", describeIndirectTools(a.indirectTools));
|
|
74
|
-
reportToolCollisions(a.toolCollisions);
|
|
75
|
-
for (const [label, value] of extras.afterTools ?? [])
|
|
57
|
+
reportLine("model", `${modelSpec}${definition.config.thinkingLevel ? ` (thinking: ${definition.config.thinkingLevel})` : ""}`);
|
|
58
|
+
await reportAuth(models, modelSpec, agentDir);
|
|
59
|
+
const names = (list) => list.map(({ name }) => name).join(", ") || "(none)";
|
|
60
|
+
reportLine("tools", names(code.tools));
|
|
61
|
+
if (code.extensions.length > 0)
|
|
62
|
+
reportLine("extensions", names(code.extensions));
|
|
63
|
+
reportLine("commands", (await opened.agent.info()).commands.map(({ name }) => `/${name}`).join(", ") || "(none)");
|
|
64
|
+
reportLine("state", stateRoot);
|
|
65
|
+
for (const [label, value] of extras)
|
|
76
66
|
reportLine(label, value);
|
|
77
|
-
reportFindingsIfChanged(a.definition.dir, a.definition);
|
|
78
67
|
}
|
|
79
68
|
/** Both stdin and stdout are a terminal — the precondition for an interactive prompt. */
|
|
80
69
|
export function isInteractive() {
|
|
@@ -87,7 +76,7 @@ export function parsePort(value, source, from) {
|
|
|
87
76
|
const trimmed = value.trim();
|
|
88
77
|
if (trimmed === "")
|
|
89
78
|
return undefined;
|
|
90
|
-
if (!/^\d+$/.test(trimmed) ||
|
|
79
|
+
if (!/^\d+$/.test(trimmed) || Number(trimmed) > 65535) {
|
|
91
80
|
const message = `invalid ${source} "${value}": must be an integer 0-65535`;
|
|
92
81
|
if (from === "flag")
|
|
93
82
|
failUsage(message);
|
|
@@ -108,7 +97,7 @@ export function parseBind(value) {
|
|
|
108
97
|
return bindAddress(trimmed); // a name never travels past this point — see bind.ts
|
|
109
98
|
}
|
|
110
99
|
/** Report which source provides the model's credentials, surfacing a remediation hint at startup. */
|
|
111
|
-
export async function reportAuth(models, modelSpec) {
|
|
100
|
+
export async function reportAuth(models, modelSpec, agentDir) {
|
|
112
101
|
const provider = providerOf(modelSpec);
|
|
113
102
|
// No files: the opener was handed a credential store, which is its caller's to describe.
|
|
114
103
|
if (models.auth === undefined) {
|
|
@@ -119,36 +108,42 @@ export async function reportAuth(models, modelSpec) {
|
|
|
119
108
|
// line cannot name a file, or a source, other than the ones the runtime uses.
|
|
120
109
|
const modelId = modelSpec.slice(provider.length + 1);
|
|
121
110
|
const status = await models.authStatus(provider, modelId).catch(failStartup);
|
|
122
|
-
const report = formatAuthReport({
|
|
111
|
+
const report = formatAuthReport({
|
|
112
|
+
provider,
|
|
113
|
+
path: models.auth.path,
|
|
114
|
+
...status,
|
|
115
|
+
...(isDeployedWorkspace()
|
|
116
|
+
? { deployed: { host: deployedHost() } }
|
|
117
|
+
: { local: { authPath: models.auth.path, valueFile: dotEnvPath(agentDir) } }),
|
|
118
|
+
});
|
|
123
119
|
log.info(`[fastagent] ${report.line}`);
|
|
124
120
|
if (report.warn)
|
|
125
121
|
log.warn(`[fastagent] ${report.warn}`);
|
|
126
122
|
}
|
|
127
123
|
/**
|
|
128
|
-
*
|
|
124
|
+
* The default model, for every command that runs the agent: `--model` > `FASTAGENT_MODEL` > `fastagent.config.ts`. With
|
|
125
|
+
* none and a terminal, the first-run picker chooses one for this run (and logs in to its provider when needed).
|
|
129
126
|
*/
|
|
130
|
-
async function resolveFirstRunModel(
|
|
131
|
-
const
|
|
132
|
-
const configured =
|
|
127
|
+
async function resolveFirstRunModel(agentDir, options = {}) {
|
|
128
|
+
const config = await loadConfig(agentDir).catch(failStartup);
|
|
129
|
+
const configured = modelSpecFor(config, options.model);
|
|
133
130
|
if (configured)
|
|
134
|
-
return configured;
|
|
131
|
+
return configured;
|
|
135
132
|
if (options.input === false)
|
|
136
133
|
return undefined; // --no-input: never prompt (clig) — the caller decides what's missing
|
|
137
134
|
if (!isInteractive())
|
|
138
135
|
return undefined; // CI/deploy: the caller raises the actionable missing-model error
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const models = await environment.runtime().catch(failStartup);
|
|
143
|
-
const chosen = await pickWithCredentials(models, environment.auth.path, agentDir);
|
|
136
|
+
const providers = await definitionProviders(agentDir).catch(failStartup);
|
|
137
|
+
const environment = await modelEnvironment(agentDir, {}, providers);
|
|
138
|
+
const chosen = await pickWithCredentials(environment.models, environment.auth?.path, providers);
|
|
144
139
|
if (chosen === undefined)
|
|
145
140
|
return undefined; // cancelled (or auth probe failed): the caller raises its clear error
|
|
146
141
|
process.env.FASTAGENT_MODEL = chosen; // this process + any spawned dev worker inherits it
|
|
147
|
-
|
|
142
|
+
console.error(`[fastagent] picked ${chosen} — set \`model: ${JSON.stringify(chosen)}\` in fastagent.config.ts to keep it`);
|
|
148
143
|
return chosen;
|
|
149
144
|
}
|
|
150
145
|
/** The credential-aware pick: full catalog annotated per provider, then the post-pick auth policy. */
|
|
151
|
-
async function pickWithCredentials(models, authPath,
|
|
146
|
+
async function pickWithCredentials(models, authPath, providers) {
|
|
152
147
|
let statuses;
|
|
153
148
|
try {
|
|
154
149
|
statuses = await providerAuthStatuses(models);
|
|
@@ -181,7 +176,7 @@ async function pickWithCredentials(models, authPath, agentDir) {
|
|
|
181
176
|
}
|
|
182
177
|
try {
|
|
183
178
|
// Verified on this agent's registry, against the chosen model: the request the agent is about to make.
|
|
184
|
-
await loginFlow(terminalLoginIO(), { provider, authPath,
|
|
179
|
+
await loginFlow(terminalLoginIO(), { provider, authPath, providers, verifyWith: chosen });
|
|
185
180
|
console.error(`[fastagent] logged in to ${provider} — saved to ${authPath}`);
|
|
186
181
|
}
|
|
187
182
|
catch (error) {
|
|
@@ -210,23 +205,7 @@ export function terminalLoginIO() {
|
|
|
210
205
|
openUrl: openExternalUrl,
|
|
211
206
|
};
|
|
212
207
|
}
|
|
213
|
-
/**
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
// The pick lives in THIS process's environment only, so it serves this run and nothing that outlives it: a
|
|
217
|
-
// deployment resolves in the environment being deployed, where this machine's variables do not exist.
|
|
218
|
-
`[fastagent] picked ${spec} — set \`model: ${JSON.stringify(spec)}\` in your config to persist${why}`);
|
|
219
|
-
if (!configPath)
|
|
220
|
-
return hint();
|
|
221
|
-
try {
|
|
222
|
-
const replaced = rewriteConfigModel(await readFile(configPath, "utf8"), spec);
|
|
223
|
-
if (!replaced)
|
|
224
|
-
return hint();
|
|
225
|
-
await writeFile(configPath, replaced);
|
|
226
|
-
console.error(`[fastagent] saved model ${JSON.stringify(spec)} to ${relative(agentDir, configPath)}`);
|
|
227
|
-
}
|
|
228
|
-
catch (error) {
|
|
229
|
-
// The run goes on with the pick either way; the reason the file was not written is what the author needs to fix.
|
|
230
|
-
hint(` (could not write ${configPath}: ${error.message})`);
|
|
231
|
-
}
|
|
208
|
+
/** A copy/paste-safe POSIX shell argument for a command the CLI prints. */
|
|
209
|
+
export function shellArg(value) {
|
|
210
|
+
return /^[A-Za-z0-9_./:@%+=,-]+$/.test(value) ? value : `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
232
211
|
}
|