@fastagent-sh/fastagent 0.24.4 → 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 -535
- 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 -92
- package/dist/engines/pi/turn-kit.js +0 -288
- 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
|
@@ -1,44 +1,46 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `fastagent models [search]`: print every "provider/modelId" the agent here
|
|
3
|
-
*
|
|
4
|
-
* `
|
|
2
|
+
* `fastagent models [search]`: print every "provider/modelId" the agent here can name (pi-ai's built-ins with their
|
|
3
|
+
* published catalogs, and the providers its definition declares), or, outside an agent, the built-ins; `[search]`
|
|
4
|
+
* filters by substring. `--refresh` asks the network for the lists even when the kept ones are fresh.
|
|
5
5
|
*/
|
|
6
|
-
import { join } from "node:path";
|
|
7
6
|
import { InMemoryCredentialStore } from "@earendil-works/pi-ai";
|
|
8
|
-
import {
|
|
9
|
-
import { listModels } from "../../
|
|
10
|
-
import {
|
|
11
|
-
import { refreshMachineModelCatalog, refreshModelCatalog } from "../../engines/pi/open.js";
|
|
12
|
-
import { AGENT_MODEL_CATALOG_FILE, findAgentDir, globalHome, placementDeadEnd } from "../../paths.js";
|
|
7
|
+
import { modelEnvironment } from "../../harnesses/models/environment.js";
|
|
8
|
+
import { listModels, providerOf } from "../../harnesses/models/models.js";
|
|
9
|
+
import { definitionProviders } from "../../harnesses/pi-durable/open.js";
|
|
13
10
|
import { enterAgentEnv } from "../../env.js";
|
|
14
|
-
import {
|
|
11
|
+
import { installProxyFetch } from "../../proxy.js";
|
|
12
|
+
import { formatModelsCommand } from "../models-view.js";
|
|
13
|
+
import { failStartup, optionalAgentDirOrExit } from "../fail.js";
|
|
15
14
|
export async function runModels(search, opts = {}) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
15
|
+
// "Outside an agent" must mean exactly that, as for `login`: refused inside an agent's subdirectory (findAgentDir);
|
|
16
|
+
// `-g` asks for pi-ai's built-ins alone.
|
|
17
|
+
const agentDir = opts.global ? undefined : optionalAgentDirOrExit(process.cwd());
|
|
18
|
+
let providers = [];
|
|
19
|
+
if (agentDir) {
|
|
20
|
+
enterAgentEnv(agentDir); // a provider in code may read its secrets when it is built
|
|
21
|
+
providers = await definitionProviders(agentDir).catch(failStartup);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
installProxyFetch();
|
|
25
|
+
}
|
|
26
|
+
// Outside an agent, no credentials file is read: the built-ins' lists need none.
|
|
27
|
+
const environment = await modelEnvironment(agentDir, agentDir ? {} : { credentialStore: new InMemoryCredentialStore() }, providers, { force: opts.refresh === true });
|
|
28
|
+
const { lines, error } = formatModelsCommand(listModels(environment.models), search);
|
|
29
|
+
if (opts.json) {
|
|
30
|
+
const models = lines.map((spec) => {
|
|
31
|
+
const provider = providerOf(spec);
|
|
32
|
+
const id = spec.slice(provider.length + 1);
|
|
33
|
+
return { spec, provider, id, name: environment.models.getModel(provider, id)?.name ?? id };
|
|
34
|
+
});
|
|
35
|
+
console.log(JSON.stringify(models, null, 2));
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
for (const spec of lines)
|
|
39
|
+
console.log(spec);
|
|
40
|
+
if (error)
|
|
41
|
+
console.error(error);
|
|
35
42
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const { lines, error } = formatModelsCommand(listModels(models), search);
|
|
40
|
-
for (const spec of lines)
|
|
41
|
-
console.log(spec);
|
|
42
|
-
if (error)
|
|
43
|
-
console.error(error);
|
|
43
|
+
// The list printed is the one kept; the warning above it said why it is not newer.
|
|
44
|
+
if (opts.refresh && environment.catalogProblem !== undefined)
|
|
45
|
+
process.exitCode = 1;
|
|
44
46
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text mode answers "when does each run next, and did the last run work?" from the newest claim alone, so an old file
|
|
3
|
+
* in the retained window cannot fail it; `--json` adds each schedule's whole retained fire history (the claims under
|
|
4
|
+
* `schedule/claims/<name>/`). What a run SAID is in its session, once it has fired.
|
|
5
|
+
*/
|
|
6
|
+
export declare function runSchedulesList(dirArg: string, json: boolean): Promise<void>;
|
|
7
|
+
/**
|
|
8
|
+
* Fire the schedule `name` now, as its clock would: in its session, with its claim and its outcome recorded. It opens
|
|
9
|
+
* the instance's storage, so a serve of it refuses this, and the other way round. The answer goes to stdout; exit 0
|
|
10
|
+
* only when its message completed, as `invoke`'s.
|
|
11
|
+
*/
|
|
12
|
+
export declare function runScheduleNow(name: string, dirArg: string, opts: {
|
|
13
|
+
model?: string;
|
|
14
|
+
input?: boolean;
|
|
15
|
+
}): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Cancel the pending wake-up `id`, whatever session set it: the one way out of a wake-up set where nobody can message
|
|
18
|
+
* the agent (a schedule's own session). It holds the instance's storage while it writes, so it is refused while a serve
|
|
19
|
+
* of the instance runs, whose poll writes the same store.
|
|
20
|
+
*/
|
|
21
|
+
export declare function runUnwake(id: string, dirArg: string): Promise<void>;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `fastagent schedules` — what is going to wake this agent up: the schedules its definition declares, and the wake-ups
|
|
3
|
+
* it set for itself. `list` shows both, `run` fires a schedule now, `unwake` cancels a wake-up.
|
|
4
|
+
*
|
|
5
|
+
* The two have different owners (a schedule is the definition's, a wake-up the state's) but answer the same operator
|
|
6
|
+
* question, so one command lists both, labelled apart.
|
|
7
|
+
*/
|
|
8
|
+
import { resolve } from "node:path";
|
|
9
|
+
import * as Effect from "effect/Effect";
|
|
10
|
+
import { AgentError, hasEnded } from "../../agent-api.js";
|
|
11
|
+
import { enterAgentEnv } from "../../env.js";
|
|
12
|
+
import { buildDefinitionShape, prepareDefinition } from "../../harnesses/pi-durable/open.js";
|
|
13
|
+
import { holdingInstance, openServing } from "../../harnesses/pi-durable/serve.js";
|
|
14
|
+
import { resolveStateRoot } from "../../paths.js";
|
|
15
|
+
import { nextRun } from "../../schedule/cron.js";
|
|
16
|
+
import { fireScheduleNow, scheduleSessions } from "../../schedule/scheduler.js";
|
|
17
|
+
import { latestFire, readFires } from "../../schedule/state.js";
|
|
18
|
+
import { listWakeups, removeAnyWakeup } from "../../schedule/wakeups.js";
|
|
19
|
+
import { agentDirOrExit, failStartup, failUsage } from "../fail.js";
|
|
20
|
+
import { exitCodeOf } from "../invoke-stream.js";
|
|
21
|
+
import { enterAgentCommand, reportAuth } from "../shared.js";
|
|
22
|
+
/**
|
|
23
|
+
* Text mode answers "when does each run next, and did the last run work?" from the newest claim alone, so an old file
|
|
24
|
+
* in the retained window cannot fail it; `--json` adds each schedule's whole retained fire history (the claims under
|
|
25
|
+
* `schedule/claims/<name>/`). What a run SAID is in its session, once it has fired.
|
|
26
|
+
*/
|
|
27
|
+
export async function runSchedulesList(dirArg, json) {
|
|
28
|
+
const target = agentDirOrExit(resolve(dirArg));
|
|
29
|
+
enterAgentEnv(target); // FASTAGENT_STATE_DIR may live in .env — read the SAME state root the scheduler wrote
|
|
30
|
+
const stateRoot = resolveStateRoot(target);
|
|
31
|
+
// Its shape only: listing what will fire needs none of the values the code reads.
|
|
32
|
+
const { schedules } = await prepareDefinition(target)
|
|
33
|
+
.then((definition) => buildDefinitionShape(definition, process.env))
|
|
34
|
+
.catch(failStartup);
|
|
35
|
+
const sessions = scheduleSessions(stateRoot);
|
|
36
|
+
const now = new Date();
|
|
37
|
+
// A claim state this command cannot read is the operator's to fix: one line, never a Node stack.
|
|
38
|
+
const read = (name, what, fn) => {
|
|
39
|
+
try {
|
|
40
|
+
return fn();
|
|
41
|
+
}
|
|
42
|
+
catch (e) {
|
|
43
|
+
failStartup(new Error(`the ${what} of "${name}" is unreadable (state: ${stateRoot}): ${String(e)}`));
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
const rows = schedules.map(({ name, cron, tz, prompt }) => ({
|
|
47
|
+
name,
|
|
48
|
+
cron,
|
|
49
|
+
...(tz === undefined ? {} : { tz }),
|
|
50
|
+
...(typeof prompt === "string" ? { prompt } : {}),
|
|
51
|
+
next: nextRun(cron, tz, now)?.toISOString() ?? null,
|
|
52
|
+
session: sessions.get(name) ?? null,
|
|
53
|
+
}));
|
|
54
|
+
const wakeups = listWakeups(stateRoot);
|
|
55
|
+
if (json) {
|
|
56
|
+
const withFires = rows.map((r) => ({
|
|
57
|
+
...r,
|
|
58
|
+
fires: read(r.name, "fire history", () => readFires(stateRoot, r.name)),
|
|
59
|
+
}));
|
|
60
|
+
console.log(JSON.stringify({ schedules: withFires, wakeups }, null, 2));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (rows.length === 0 && wakeups.length === 0) {
|
|
64
|
+
console.error(`nothing scheduled — no src/schedules/, no wake-ups (agent: ${target})`);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
for (const r of rows) {
|
|
68
|
+
const last = read(r.name, "last fire", () => latestFire(stateRoot, r.name));
|
|
69
|
+
const lastRun = last ? `last ${last.firedAt} ${last.outcome ?? "unreported"}` : "never run";
|
|
70
|
+
console.log(`${r.name.padEnd(20)} next ${(r.next ?? "(never)").padEnd(26)}cron ${r.cron}${r.tz ? ` ${r.tz}` : ""} ${lastRun} session=${r.session ?? "(none yet)"}`);
|
|
71
|
+
}
|
|
72
|
+
for (const w of wakeups) {
|
|
73
|
+
const kind = w.cron ? `cron ${w.cron}${w.tz ? ` ${w.tz}` : ""}` : "one-shot";
|
|
74
|
+
console.log(`wake ${w.id} ${w.fireAt} ${kind} session=${w.session} ${w.prompt.slice(0, 60)}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Fire the schedule `name` now, as its clock would: in its session, with its claim and its outcome recorded. It opens
|
|
79
|
+
* the instance's storage, so a serve of it refuses this, and the other way round. The answer goes to stdout; exit 0
|
|
80
|
+
* only when its message completed, as `invoke`'s.
|
|
81
|
+
*/
|
|
82
|
+
export async function runScheduleNow(name, dirArg, opts) {
|
|
83
|
+
// The name before the model, from the definition's shape: a script told its schedule does not exist need not set up
|
|
84
|
+
// a model first.
|
|
85
|
+
const { agentDir, modelSpec } = await enterAgentCommand(dirArg, opts, async (target) => {
|
|
86
|
+
const declared = await prepareDefinition(target)
|
|
87
|
+
.then((definition) => buildDefinitionShape(definition, process.env).schedules.map((s) => s.name))
|
|
88
|
+
.catch(failStartup);
|
|
89
|
+
if (!declared.includes(name)) {
|
|
90
|
+
failUsage(`no schedule "${name}" in ${target}/src/schedules/ (declared: ${declared.join(", ") || "none"})`);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
// Refused while the instance holds work a stopped serve left: this process would run it, and cut it off at its exit.
|
|
94
|
+
const { agent, models, schedules, stateRoot } = await openServing(agentDir, {
|
|
95
|
+
model: modelSpec,
|
|
96
|
+
unfinished: "refuse",
|
|
97
|
+
}).catch(failStartup);
|
|
98
|
+
const schedule = schedules.find((s) => s.name === name);
|
|
99
|
+
if (schedule === undefined) {
|
|
100
|
+
// Checked above: only an edit of src/schedules/ while this ran gets here.
|
|
101
|
+
await agent.close();
|
|
102
|
+
failStartup(new Error(`src/schedules/ changed while this ran: "${name}" is gone from it — run it again`));
|
|
103
|
+
}
|
|
104
|
+
await reportAuth(models, modelSpec, agentDir);
|
|
105
|
+
const fired = await Effect.runPromise(fireScheduleNow({ agent, stateRoot, schedule })).catch(failStartup);
|
|
106
|
+
const sessionId = scheduleSessions(stateRoot).get(name);
|
|
107
|
+
const message = fired.fired && sessionId !== undefined
|
|
108
|
+
? await agent.messages
|
|
109
|
+
.get({ sessionId, idempotencyKey: fired.slot.toISOString() })
|
|
110
|
+
.catch((error) => {
|
|
111
|
+
// A fire refused before it sent its message (a busy session) has none.
|
|
112
|
+
if (error instanceof AgentError && error.code === "not_found")
|
|
113
|
+
return undefined;
|
|
114
|
+
throw error;
|
|
115
|
+
})
|
|
116
|
+
.catch(failStartup)
|
|
117
|
+
: undefined;
|
|
118
|
+
const ended = message !== undefined && hasEnded(message) ? message : undefined;
|
|
119
|
+
if (ended?.answer !== undefined)
|
|
120
|
+
process.stdout.write(`${ended.answer.text}\n`);
|
|
121
|
+
await agent.close();
|
|
122
|
+
if (!fired.fired)
|
|
123
|
+
console.error(`[fastagent] ${name} did not fire: ${fired.skippedReason}`);
|
|
124
|
+
// The claim counts a cut-off answer as completed; the exit code does not.
|
|
125
|
+
else if (ended?.status === "incomplete")
|
|
126
|
+
console.error(`[fastagent] ${name}: its answer was cut off (incomplete)`);
|
|
127
|
+
process.exit(ended === undefined ? 1 : exitCodeOf(ended));
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Cancel the pending wake-up `id`, whatever session set it: the one way out of a wake-up set where nobody can message
|
|
131
|
+
* the agent (a schedule's own session). It holds the instance's storage while it writes, so it is refused while a serve
|
|
132
|
+
* of the instance runs, whose poll writes the same store.
|
|
133
|
+
*/
|
|
134
|
+
export async function runUnwake(id, dirArg) {
|
|
135
|
+
const target = agentDirOrExit(resolve(dirArg));
|
|
136
|
+
enterAgentEnv(target);
|
|
137
|
+
const stateRoot = resolveStateRoot(target);
|
|
138
|
+
const removed = await holdingInstance(stateRoot, () => removeAnyWakeup(stateRoot, id)).catch(failStartup);
|
|
139
|
+
if (removed === undefined) {
|
|
140
|
+
failStartup(new Error(`no pending wake-up ${id} (state: ${stateRoot}); \`fastagent schedules list\` shows them`));
|
|
141
|
+
}
|
|
142
|
+
console.log(`removed wake ${removed.id} ${removed.fireAt} session=${removed.session} ${removed.prompt.slice(0, 60)}`);
|
|
143
|
+
}
|
|
@@ -1,34 +1,35 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Agent } from "../../agent-api.ts";
|
|
2
|
+
import type { AgentConfig } from "../../harnesses/pi-durable/define.ts";
|
|
3
|
+
import { type ServedAgent } from "../../service.ts";
|
|
2
4
|
export interface StartOptions {
|
|
3
5
|
port?: string;
|
|
4
6
|
bind?: string;
|
|
5
7
|
model?: string;
|
|
6
8
|
tunnel?: boolean;
|
|
7
|
-
/** false ⇔ `--no-invoke`: withhold `POST /invoke` for THIS run (`http.invoke` is the persistent form). */
|
|
8
|
-
invoke?: boolean;
|
|
9
9
|
input?: boolean;
|
|
10
10
|
}
|
|
11
|
-
|
|
11
|
+
/** What `start` opened and serves: the agent too, for a deployment's own check of what it runs. */
|
|
12
|
+
type StartedService = ServedAgent & {
|
|
13
|
+
agent: Agent;
|
|
12
14
|
stateRoot: string;
|
|
13
15
|
port: number;
|
|
16
|
+
config: AgentConfig;
|
|
14
17
|
};
|
|
15
18
|
export declare function runStart(dirArg: string, opts: StartOptions): Promise<void>;
|
|
16
19
|
/** What the storage stage hands the opening stage. */
|
|
17
20
|
export interface PreparedWorkspace {
|
|
18
|
-
/** The
|
|
21
|
+
/** The agent directory to open — the storage's deployed definition when a release manifest selected one. */
|
|
19
22
|
dir: string;
|
|
20
|
-
/**
|
|
23
|
+
/** The storage root, set when this process took a deployment's storage. */
|
|
21
24
|
deployed?: {
|
|
22
25
|
root: string;
|
|
23
|
-
agent: string;
|
|
24
26
|
};
|
|
25
27
|
}
|
|
26
28
|
/**
|
|
27
|
-
* Stage one — TAKE the
|
|
28
|
-
* volume.
|
|
29
|
+
* Stage one — TAKE the storage: verify it is mounted, apply the release, and point the machinery at the volume.
|
|
29
30
|
*/
|
|
30
31
|
export declare function prepareStartWorkspace(dirArg: string): Promise<PreparedWorkspace>;
|
|
31
32
|
export declare function openStartService(dirArg: string, opts: StartOptions): Promise<StartedService>;
|
|
32
|
-
/** Internal entry loaded from the
|
|
33
|
+
/** Internal entry loaded from the agent's installed package after storage initialization. */
|
|
33
34
|
export declare function openPreparedStartService(dirArg: string, opts: StartOptions): Promise<StartedService>;
|
|
34
35
|
export {};
|
|
@@ -11,19 +11,16 @@ import { join, resolve } from "node:path";
|
|
|
11
11
|
import { pathToFileURL } from "node:url";
|
|
12
12
|
import { createRequire } from "node:module";
|
|
13
13
|
import { readFile } from "node:fs/promises";
|
|
14
|
-
import * as Effect from "effect/Effect";
|
|
15
14
|
import { applyCarriedEnv } from "../../deploy/secrets.js";
|
|
16
15
|
import { applyReleaseEnv, installAgentDependencies, parseDeploymentRelease, prepareDeployment, } from "../../deploy/workspace.js";
|
|
17
|
-
import { resolveSecretsDir, isAgentcoreRuntime, isUnderDir, exists } from "../../paths.js";
|
|
16
|
+
import { selectAgentEnvironment, resolveSecretsDir, isAgentcoreRuntime, isUnderDir, exists } from "../../paths.js";
|
|
18
17
|
import { log, setLogLevel } from "../../log.js";
|
|
19
|
-
import {
|
|
20
|
-
import { DEFAULT_HTTP_PORT,
|
|
21
|
-
import { logAgentLoop } from "../../observe.js";
|
|
18
|
+
import { openServing } from "../../harnesses/pi-durable/serve.js";
|
|
19
|
+
import { DEFAULT_HTTP_PORT, serveAgent } from "../../service.js";
|
|
22
20
|
import { mountAgentcoreService, deferAgentcoreService } from "../../channels/agentcore-service.js";
|
|
23
|
-
import { createWakeAlarmSink } from "../../schedule/wake-alarm.js";
|
|
24
|
-
import { setWakeupsSink } from "../../schedule/wakeups.js";
|
|
25
21
|
import { failStartup } from "../fail.js";
|
|
26
|
-
import {
|
|
22
|
+
import { unmarkDevServe } from "../../serving-command.js";
|
|
23
|
+
import { assertTunnelBindable, bindLine, cliMountOptions, serveService, serve } from "../serve.js";
|
|
27
24
|
import { enterAgentCommand, parseBind, parsePort, reportAssembly } from "../shared.js";
|
|
28
25
|
export async function runStart(dirArg, opts) {
|
|
29
26
|
const portFlag = parsePort(opts.port, "--port", "flag");
|
|
@@ -36,6 +33,8 @@ export async function runStart(dirArg, opts) {
|
|
|
36
33
|
failStartup(error);
|
|
37
34
|
}
|
|
38
35
|
setLogLevel("info");
|
|
36
|
+
selectAgentEnvironment("production");
|
|
37
|
+
unmarkDevServe();
|
|
39
38
|
if (isAgentcoreRuntime()) {
|
|
40
39
|
// The generated Runtime resource sets PORT; 8080 is the platform's contract when nothing does.
|
|
41
40
|
const port = portFlag ?? parsePort(process.env.PORT, "PORT env", "env") ?? 8080;
|
|
@@ -44,19 +43,13 @@ export async function runStart(dirArg, opts) {
|
|
|
44
43
|
assemble: async (prepared) => {
|
|
45
44
|
const service = await openPreparedWorkspace(prepared, opts);
|
|
46
45
|
await service.ready;
|
|
47
|
-
announceControl(service, { host: bindFlag, tunnel: false });
|
|
48
46
|
return service;
|
|
49
47
|
},
|
|
50
48
|
});
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
// NOT `readyAddressLines`: this posture serves the Runtime's `/invocations` contract, not our `/invoke`.
|
|
56
|
-
log.info(bindLine(bindFlag, port));
|
|
57
|
-
log.info("[fastagent] agentcore: the definition opens on the first invocation");
|
|
58
|
-
},
|
|
59
|
-
onShutdown: () => deferred.close(),
|
|
49
|
+
// The assembly report waits for the first envelope, so this line is the only sign of life a booted container gives.
|
|
50
|
+
serve(deferred, { port, host: bindFlag }, (port) => {
|
|
51
|
+
log.info(bindLine(bindFlag, port));
|
|
52
|
+
log.info("[fastagent] agentcore: the definition opens on the first invocation");
|
|
60
53
|
});
|
|
61
54
|
return;
|
|
62
55
|
}
|
|
@@ -66,11 +59,10 @@ export async function runStart(dirArg, opts) {
|
|
|
66
59
|
const tunnel = opts.tunnel ?? false;
|
|
67
60
|
// An unset bind stays the wildcard: this is the container posture, and a published port needs it.
|
|
68
61
|
assertTunnelBindable(bindFlag, tunnel);
|
|
69
|
-
serveService(service, { port: portFlag ?? parsePort(process.env.PORT, "PORT env", "env") ?? service.port, host: bindFlag }, { tunnel, agentDir: service.agentDir, stateRoot: service.stateRoot });
|
|
62
|
+
serveService(service, { port: portFlag ?? parsePort(process.env.PORT, "PORT env", "env") ?? service.port, host: bindFlag }, { tunnel, agentDir: service.agentDir, stateRoot: service.stateRoot, config: service.config });
|
|
70
63
|
}
|
|
71
64
|
/**
|
|
72
|
-
* Stage one — TAKE the
|
|
73
|
-
* volume.
|
|
65
|
+
* Stage one — TAKE the storage: verify it is mounted, apply the release, and point the machinery at the volume.
|
|
74
66
|
*/
|
|
75
67
|
export async function prepareStartWorkspace(dirArg) {
|
|
76
68
|
const manifestPath = process.env.FASTAGENT_RELEASE_FILE;
|
|
@@ -78,7 +70,7 @@ export async function prepareStartWorkspace(dirArg) {
|
|
|
78
70
|
return { dir: dirArg };
|
|
79
71
|
const storage = process.env.FASTAGENT_STORAGE_DIR;
|
|
80
72
|
if (!storage)
|
|
81
|
-
throw new Error("FASTAGENT_STORAGE_DIR is required for a
|
|
73
|
+
throw new Error("FASTAGENT_STORAGE_DIR is required for a deployment");
|
|
82
74
|
const root = resolve(storage);
|
|
83
75
|
const manifest = parseDeploymentRelease(await readFile(manifestPath, "utf8"));
|
|
84
76
|
const dir = await prepareDeployment(resolve(dirArg), root, manifest);
|
|
@@ -86,26 +78,27 @@ export async function prepareStartWorkspace(dirArg) {
|
|
|
86
78
|
// their state is the one failure they could not diagnose from the logs.
|
|
87
79
|
process.env.FASTAGENT_STATE_DIR ||= join(root, ".state");
|
|
88
80
|
process.env.FASTAGENT_SECRETS_DIR ||= join(root, ".secrets");
|
|
89
|
-
|
|
81
|
+
// mise's data directory, on the storage rather than the container's disk. The image's packages are in mise's system
|
|
82
|
+
// directory, which mise reads as well, so a start installs nothing there.
|
|
83
|
+
process.env.MISE_DATA_DIR ||= join(process.env.FASTAGENT_STATE_DIR, "mise");
|
|
90
84
|
// The release's own declarations, projected into the environment it was resolved FOR. This must stay BEFORE
|
|
91
|
-
// `enterAgentEnv` reads the
|
|
85
|
+
// `enterAgentEnv` reads the agent's `.env`, which is what makes either source outrank a value edited on the
|
|
92
86
|
// box (applyReleaseEnv's own tests pin the precedence).
|
|
93
87
|
applyReleaseEnv(manifest);
|
|
94
88
|
process.chdir(dir);
|
|
95
|
-
return { dir, deployed: { root
|
|
89
|
+
return { dir, deployed: { root } };
|
|
96
90
|
}
|
|
97
91
|
/**
|
|
98
|
-
* Stage two — RUN
|
|
99
|
-
* FastAgent install.
|
|
92
|
+
* Stage two — RUN the prepared agent directory: install its dependencies, then open through its own FastAgent install.
|
|
100
93
|
*/
|
|
101
94
|
async function openPreparedWorkspace(prepared, opts) {
|
|
102
95
|
let open = openPreparedStartService;
|
|
103
96
|
if (prepared.deployed) {
|
|
104
|
-
const { root
|
|
105
|
-
const agentDir =
|
|
97
|
+
const { root } = prepared.deployed;
|
|
98
|
+
const agentDir = prepared.dir;
|
|
106
99
|
if (await exists(join(agentDir, "package.json"))) {
|
|
107
100
|
await installAgentDependencies(root, agentDir);
|
|
108
|
-
// Tools and their session context must share the
|
|
101
|
+
// Tools and their session context must share the agent's runtime module instance.
|
|
109
102
|
const entry = createRequire(join(agentDir, "package.json")).resolve("@fastagent-sh/fastagent");
|
|
110
103
|
const local = (await import(__rewriteRelativeImportExtension(new URL("./cli/commands/start.js", pathToFileURL(entry)).href)));
|
|
111
104
|
// A version-skewed dependency resolves and imports fine, then fails as "open is not a function" with nothing
|
|
@@ -121,45 +114,25 @@ async function openPreparedWorkspace(prepared, opts) {
|
|
|
121
114
|
export async function openStartService(dirArg, opts) {
|
|
122
115
|
return openPreparedWorkspace(await prepareStartWorkspace(dirArg), opts);
|
|
123
116
|
}
|
|
124
|
-
/** Internal entry loaded from the
|
|
117
|
+
/** Internal entry loaded from the agent's installed package after storage initialization. */
|
|
125
118
|
export async function openPreparedStartService(dirArg, opts) {
|
|
126
|
-
const
|
|
127
|
-
const opened = await
|
|
128
|
-
model:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const { agent, agentDir, config, stateRoot, sessionsDir } = opened;
|
|
132
|
-
await reportAssembly({ ...opened, modelSpec: placement.modelSpec }, {
|
|
133
|
-
afterTools: [
|
|
134
|
-
["state", stateRoot],
|
|
135
|
-
["sessions", sessionsDir],
|
|
136
|
-
],
|
|
119
|
+
const { agentDir, modelSpec } = await enterAgentCommand(dirArg, opts);
|
|
120
|
+
const opened = await openServing(agentDir, {
|
|
121
|
+
model: modelSpec,
|
|
122
|
+
// AgentCore's session storage refuses SQLite's own locks; the deployment's lease makes the dotfile lock safe.
|
|
123
|
+
storage: { instance: isAgentcoreRuntime() ? "leased-dotfile" : "posix" },
|
|
137
124
|
});
|
|
125
|
+
const { stateRoot } = opened;
|
|
126
|
+
await reportAssembly(opened, modelSpec);
|
|
138
127
|
if (isUnderDir(stateRoot, agentDir)) {
|
|
139
128
|
log.info("[fastagent] note: state lives under the definition; use FASTAGENT_STATE_DIR on persistent storage for deployment.");
|
|
140
129
|
}
|
|
141
130
|
if (isUnderDir(resolveSecretsDir(agentDir), agentDir)) {
|
|
142
131
|
log.info("[fastagent] note: credentials live under the definition; use FASTAGENT_SECRETS_DIR on persistent storage for deployment.");
|
|
143
132
|
}
|
|
144
|
-
const
|
|
145
|
-
const onStateReady = isAgentcoreRuntime() ? armWakeAlarms(stateRoot) : undefined;
|
|
146
|
-
const mountable = withRunOverrides(opened, opts);
|
|
133
|
+
const { config } = opened.definition;
|
|
147
134
|
const service = await (isAgentcoreRuntime()
|
|
148
|
-
? mountAgentcoreService(
|
|
149
|
-
:
|
|
150
|
-
return { ...service, stateRoot, port: config.http?.port ?? DEFAULT_HTTP_PORT };
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Install the wake-ALARM sink before the scheduler starts: the first wake poll may advance a recurring entry, and that
|
|
154
|
-
* save must already re-arm its alarm.
|
|
155
|
-
*/
|
|
156
|
-
function armWakeAlarms(stateRoot) {
|
|
157
|
-
const secret = process.env.FASTAGENT_WAKE_SECRET;
|
|
158
|
-
if (!secret) {
|
|
159
|
-
log.warn("[fastagent] FASTAGENT_WAKE_SECRET is missing; external wake alarms cannot be registered");
|
|
160
|
-
return undefined;
|
|
161
|
-
}
|
|
162
|
-
const sink = Effect.runSync(createWakeAlarmSink({ secret }));
|
|
163
|
-
setWakeupsSink(sink);
|
|
164
|
-
return () => sink(stateRoot);
|
|
135
|
+
? mountAgentcoreService(opened)
|
|
136
|
+
: serveAgent(opened, cliMountOptions(config)));
|
|
137
|
+
return { ...service, agent: opened.agent, stateRoot, port: config.http?.port ?? DEFAULT_HTTP_PORT, config };
|
|
165
138
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** How the CLI writes an agent's content. */
|
|
2
|
+
import type { BoundContent } from "../content/declare.ts";
|
|
3
|
+
import { type ResolvedContent } from "../content/resolve.ts";
|
|
4
|
+
/**
|
|
5
|
+
* The report lines for an agent's content — `works on` / `knows`, one per entry, then a `notice` line for each
|
|
6
|
+
* thing its resolution has to say, then one for each directory this machine binds that is not here — shared by the
|
|
7
|
+
* startup report, `info` and `content list`, so the three say the same thing.
|
|
8
|
+
*/
|
|
9
|
+
export declare function contentLines(content: readonly ResolvedContent[], absent?: readonly BoundContent[]): [label: string, value: string][];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { LOCAL_CONTEXT_FILE } from "../paths.js";
|
|
2
|
+
import { absentNotice } from "../content/resolve.js";
|
|
3
|
+
/** What a content entry is, in the words the reports use. */
|
|
4
|
+
function contentKind(c) {
|
|
5
|
+
if (c.kind !== "github")
|
|
6
|
+
return `this machine only, bound in ${LOCAL_CONTEXT_FILE}`;
|
|
7
|
+
const github = `github ${c.repo}${c.ref ? `@${c.ref}` : ""}`;
|
|
8
|
+
return c.clone ? `${github}, a clone brought up to date at each start` : `${github}, your checkout bound here`;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The report lines for an agent's content — `works on` / `knows`, one per entry, then a `notice` line for each
|
|
12
|
+
* thing its resolution has to say, then one for each directory this machine binds that is not here — shared by the
|
|
13
|
+
* startup report, `info` and `content list`, so the three say the same thing.
|
|
14
|
+
*/
|
|
15
|
+
export function contentLines(content, absent = []) {
|
|
16
|
+
const lines = content.flatMap((c) => [
|
|
17
|
+
[c.readonly ? "knows" : "works on", `${c.name.padEnd(width(content))} ${c.location} (${contentKind(c)})`],
|
|
18
|
+
...c.notices.map((notice) => ["notice", `${c.name}: ${notice}`]),
|
|
19
|
+
]);
|
|
20
|
+
for (const binding of absent)
|
|
21
|
+
lines.push(["notice", absentNotice(binding)]);
|
|
22
|
+
return lines.length === 0 ? [["content", "(none)"]] : lines;
|
|
23
|
+
}
|
|
24
|
+
function width(content) {
|
|
25
|
+
return Math.max(0, ...content.map((c) => c.name.length));
|
|
26
|
+
}
|
package/dist/cli/fail.d.ts
CHANGED
|
@@ -1,22 +1,19 @@
|
|
|
1
|
-
import { type ResolvedPlacement } from "../paths.ts";
|
|
2
|
-
import { gateSecrets } from "../secrets-gate.ts";
|
|
3
1
|
/** The ONE error prefix every error message carries — bold red when stderr renders color, plain otherwise. */
|
|
4
2
|
export declare function errorPrefix(colors?: boolean): string;
|
|
3
|
+
/**
|
|
4
|
+
* A ticket's process (ticket.ts): a failure that ends the process is the ticket's failure too, recorded before the
|
|
5
|
+
* process exits, wherever in a long command it happens.
|
|
6
|
+
*/
|
|
7
|
+
export declare function recordFailures(record: ((message: string) => void) | undefined): void;
|
|
5
8
|
/**
|
|
6
9
|
* User-fixable startup problems (missing model / bad config / broken definition) are thrown as plain `Error` — print
|
|
7
10
|
* just the message. Anything else (a TypeError, a non-Error throw) is a bug: keep the stack.
|
|
8
11
|
*/
|
|
9
12
|
export declare function failStartup(error: unknown): never;
|
|
10
|
-
/**
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
* buries the one line naming the file. The catch translates that expected failure into the CLI's
|
|
15
|
-
* single-line refusal and exits 1; nothing is recovered.
|
|
16
|
-
*/
|
|
17
|
-
export declare function gateSecretsOrExit(input: Parameters<typeof gateSecrets>[0]): void;
|
|
18
|
-
/** THE placement entry point for commands: resolve `dir`, or exit 1 with the one-line refusal. */
|
|
19
|
-
export declare function placementOrExit(dir: string): ResolvedPlacement;
|
|
13
|
+
/** THE addressing entry point for commands: the agent directory `dir` names, or exit 1 with the one-line refusal. */
|
|
14
|
+
export declare function agentDirOrExit(dir: string): string;
|
|
15
|
+
/** {@link findAgentDir} for a command that also works without an agent: undefined when there is none, exit 1 inside one. */
|
|
16
|
+
export declare function optionalAgentDirOrExit(dir: string): string | undefined;
|
|
20
17
|
/**
|
|
21
18
|
* A usage error the parser could not catch (a bad value shape, an invalid flag/argument combination discovered in a
|
|
22
19
|
* command body): print the message and exit 2.
|
package/dist/cli/fail.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { gateSecrets } from "../secrets-gate.js";
|
|
1
|
+
import { findAgentDir, resolveAgentDir } from "../paths.js";
|
|
3
2
|
/** stderr renders color: a color TTY, with Node's `hasColors()` carrying the NO_COLOR/TERM=dumb veto. */
|
|
4
3
|
function stderrHasColors() {
|
|
5
4
|
return process.stderr.isTTY === true && (process.stderr.hasColors?.() ?? false);
|
|
@@ -8,36 +7,39 @@ function stderrHasColors() {
|
|
|
8
7
|
export function errorPrefix(colors = stderrHasColors()) {
|
|
9
8
|
return colors ? "\x1b[1;31mError:\x1b[0m" : "Error:";
|
|
10
9
|
}
|
|
10
|
+
let failureRecorder;
|
|
11
|
+
/**
|
|
12
|
+
* A ticket's process (ticket.ts): a failure that ends the process is the ticket's failure too, recorded before the
|
|
13
|
+
* process exits, wherever in a long command it happens.
|
|
14
|
+
*/
|
|
15
|
+
export function recordFailures(record) {
|
|
16
|
+
failureRecorder = record;
|
|
17
|
+
}
|
|
11
18
|
/**
|
|
12
19
|
* User-fixable startup problems (missing model / bad config / broken definition) are thrown as plain `Error` — print
|
|
13
20
|
* just the message. Anything else (a TypeError, a non-Error throw) is a bug: keep the stack.
|
|
14
21
|
*/
|
|
15
22
|
export function failStartup(error) {
|
|
23
|
+
failureRecorder?.(error instanceof Error ? error.message : String(error));
|
|
16
24
|
if (error instanceof Error && error.constructor === Error)
|
|
17
25
|
console.error(`${errorPrefix()} ${error.message}`);
|
|
18
26
|
else
|
|
19
27
|
console.error(errorPrefix(), error);
|
|
20
28
|
process.exit(1);
|
|
21
29
|
}
|
|
22
|
-
/**
|
|
23
|
-
|
|
24
|
-
* tool`, `fastagent routine run`). The gate throws SYNCHRONOUSLY, so there is no promise to hang the usual
|
|
25
|
-
* `.catch(failStartup)` on, and a raw throw reaches `cli.ts`'s top-level await as a Node stack that
|
|
26
|
-
* buries the one line naming the file. The catch translates that expected failure into the CLI's
|
|
27
|
-
* single-line refusal and exits 1; nothing is recovered.
|
|
28
|
-
*/
|
|
29
|
-
export function gateSecretsOrExit(input) {
|
|
30
|
+
/** THE addressing entry point for commands: the agent directory `dir` names, or exit 1 with the one-line refusal. */
|
|
31
|
+
export function agentDirOrExit(dir) {
|
|
30
32
|
try {
|
|
31
|
-
|
|
33
|
+
return resolveAgentDir(dir);
|
|
32
34
|
}
|
|
33
35
|
catch (error) {
|
|
34
36
|
failStartup(error);
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
|
-
/**
|
|
38
|
-
export function
|
|
39
|
+
/** {@link findAgentDir} for a command that also works without an agent: undefined when there is none, exit 1 inside one. */
|
|
40
|
+
export function optionalAgentDirOrExit(dir) {
|
|
39
41
|
try {
|
|
40
|
-
return
|
|
42
|
+
return findAgentDir(dir);
|
|
41
43
|
}
|
|
42
44
|
catch (error) {
|
|
43
45
|
failStartup(error);
|
|
@@ -48,6 +50,7 @@ export function placementOrExit(dir) {
|
|
|
48
50
|
* command body): print the message and exit 2.
|
|
49
51
|
*/
|
|
50
52
|
export function failUsage(message) {
|
|
53
|
+
failureRecorder?.(message);
|
|
51
54
|
console.error(`${errorPrefix()} ${message}`);
|
|
52
55
|
process.exit(2);
|
|
53
56
|
}
|