@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
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/** Feishu/Lark's half of the shared context buffer (mechanics + consume protocol: ../kit/context-buffer.ts). */
|
|
2
|
-
import { type ContextBuffer } from "../kit/context-buffer.ts";
|
|
3
|
-
import type { NormalizedFeishuMessage } from "./model.ts";
|
|
4
|
-
export interface FeishuBufferedResource {
|
|
5
|
-
messageId: string;
|
|
6
|
-
key: string;
|
|
7
|
-
name?: string;
|
|
8
|
-
}
|
|
9
|
-
export interface FeishuBufferEntry {
|
|
10
|
-
sender: string;
|
|
11
|
-
body: string;
|
|
12
|
-
messageId: string;
|
|
13
|
-
replyTo?: string;
|
|
14
|
-
files?: FeishuBufferedResource[];
|
|
15
|
-
images?: FeishuBufferedResource[];
|
|
16
|
-
}
|
|
17
|
-
/** A background resource carried into a later turn, with attribution for its prompt manifest. */
|
|
18
|
-
export interface FeishuBufferedRef extends FeishuBufferedResource {
|
|
19
|
-
from: string;
|
|
20
|
-
}
|
|
21
|
-
/** The place a message belongs to: the main chat, or a thread within it. */
|
|
22
|
-
export declare function feishuBufferPlaceKey(conversation: Pick<NormalizedFeishuMessage["conversation"], "chatId" | "threadId">): string;
|
|
23
|
-
/** One-line, bounded background text. */
|
|
24
|
-
export declare function feishuBufferText(text: string): string;
|
|
25
|
-
/** Select the most recent background resources, excluding resources already primary on this turn. */
|
|
26
|
-
export declare function collectFeishuBufferedAttachments(consumed: FeishuBufferEntry[], primary: {
|
|
27
|
-
files: FeishuBufferedResource[];
|
|
28
|
-
images: FeishuBufferedResource[];
|
|
29
|
-
}): {
|
|
30
|
-
files: FeishuBufferedRef[];
|
|
31
|
-
images: FeishuBufferedRef[];
|
|
32
|
-
skipped: number;
|
|
33
|
-
};
|
|
34
|
-
export type FeishuContextBuffer = ContextBuffer<FeishuBufferEntry>;
|
|
35
|
-
export declare function createFeishuContextBuffer(path: string, label: string): FeishuContextBuffer;
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/** Feishu/Lark's half of the shared context buffer (mechanics + consume protocol: ../kit/context-buffer.ts). */
|
|
2
|
-
import { capBufferedRefs, BUFFER_LINE_MAX_CHARS, createContextBuffer as createGenericContextBuffer, } from "../kit/context-buffer.js";
|
|
3
|
-
import { truncateCodePointPrefix } from "../kit/text.js";
|
|
4
|
-
function bufferLine(entry) {
|
|
5
|
-
const meta = [`msg ${entry.messageId}`, entry.replyTo ? `reply to msg ${entry.replyTo}` : undefined]
|
|
6
|
-
.filter(Boolean)
|
|
7
|
-
.join(", ");
|
|
8
|
-
return `${entry.sender} (${meta}): ${entry.body}`;
|
|
9
|
-
}
|
|
10
|
-
/** The place a message belongs to: the main chat, or a thread within it. */
|
|
11
|
-
export function feishuBufferPlaceKey(conversation) {
|
|
12
|
-
return conversation.threadId ? `${conversation.chatId}:thread:${conversation.threadId}` : conversation.chatId;
|
|
13
|
-
}
|
|
14
|
-
/** One-line, bounded background text. */
|
|
15
|
-
export function feishuBufferText(text) {
|
|
16
|
-
return truncateCodePointPrefix(text.replace(/\s+/g, " ").trim(), BUFFER_LINE_MAX_CHARS);
|
|
17
|
-
}
|
|
18
|
-
function resourceIdentity(resource) {
|
|
19
|
-
return `${resource.messageId}\u0000${resource.key}`;
|
|
20
|
-
}
|
|
21
|
-
/** Select the most recent background resources, excluding resources already primary on this turn. */
|
|
22
|
-
export function collectFeishuBufferedAttachments(consumed, primary) {
|
|
23
|
-
const refs = (pick, primaryRefs) => {
|
|
24
|
-
const excluded = new Set(primaryRefs.map(resourceIdentity));
|
|
25
|
-
const seen = new Set();
|
|
26
|
-
const out = [];
|
|
27
|
-
for (const entry of consumed) {
|
|
28
|
-
for (const resource of pick(entry) ?? []) {
|
|
29
|
-
const identity = resourceIdentity(resource);
|
|
30
|
-
if (excluded.has(identity) || seen.has(identity))
|
|
31
|
-
continue;
|
|
32
|
-
seen.add(identity);
|
|
33
|
-
out.push({ ...resource, from: entry.sender });
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return out;
|
|
37
|
-
};
|
|
38
|
-
const files = capBufferedRefs(refs((entry) => entry.files, primary.files));
|
|
39
|
-
const images = capBufferedRefs(refs((entry) => entry.images, primary.images));
|
|
40
|
-
return { files: files.kept, images: images.kept, skipped: files.skipped + images.skipped };
|
|
41
|
-
}
|
|
42
|
-
function isResource(value) {
|
|
43
|
-
const resource = value;
|
|
44
|
-
return (typeof resource?.messageId === "string" &&
|
|
45
|
-
typeof resource.key === "string" &&
|
|
46
|
-
(resource.name === undefined || typeof resource.name === "string"));
|
|
47
|
-
}
|
|
48
|
-
function isEntry(value) {
|
|
49
|
-
const entry = value;
|
|
50
|
-
const resources = (candidate) => candidate === undefined || (Array.isArray(candidate) && candidate.every(isResource));
|
|
51
|
-
return (typeof entry?.sender === "string" &&
|
|
52
|
-
typeof entry.body === "string" &&
|
|
53
|
-
typeof entry.messageId === "string" &&
|
|
54
|
-
(entry.replyTo === undefined || typeof entry.replyTo === "string") &&
|
|
55
|
-
resources(entry.files) &&
|
|
56
|
-
resources(entry.images));
|
|
57
|
-
}
|
|
58
|
-
export function createFeishuContextBuffer(path, label) {
|
|
59
|
-
return createGenericContextBuffer({
|
|
60
|
-
path,
|
|
61
|
-
label,
|
|
62
|
-
isEntry,
|
|
63
|
-
line: bufferLine,
|
|
64
|
-
});
|
|
65
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { feishuWebSocketChannel } from "@fastagent-sh/fastagent/feishu";
|
|
2
|
-
import { defineChannel } from "@fastagent-sh/fastagent";
|
|
3
|
-
|
|
4
|
-
// Feishu WebSocket long connection: the process connects OUT to the platform, so no public URL,
|
|
5
|
-
// Verification Token, Encrypt Key, or --tunnel is needed. In Events & Callbacks choose long
|
|
6
|
-
// connection, subscribe im.message.receive_v1, then publish the app version. Keep one process
|
|
7
|
-
// running in production: scale-to-zero/App Sleeping would disconnect ingress.
|
|
8
|
-
export default defineChannel({
|
|
9
|
-
// The env vars this channel needs. fastagent carries them to a deployed box and refuses to serve
|
|
10
|
-
// while one is unset — a bare process.env read gets neither guarantee.
|
|
11
|
-
secrets: ["FEISHU_APP_ID", "FEISHU_APP_SECRET"],
|
|
12
|
-
channel: (secrets) =>
|
|
13
|
-
feishuWebSocketChannel({
|
|
14
|
-
appId: secrets.FEISHU_APP_ID,
|
|
15
|
-
appSecret: secrets.FEISHU_APP_SECRET,
|
|
16
|
-
// No session modes: a chat is one session and a thread is another, and where the answer goes follows
|
|
17
|
-
// from that (docs/design/participant-model.md).
|
|
18
|
-
// Dev/personal bot: surface raw errors to the chat so you (and your AI agent) can act on them. The
|
|
19
|
-
// chat is customer-facing by default — for a public bot, drop this or return a neutral string;
|
|
20
|
-
// full details always go to the server log regardless.
|
|
21
|
-
onError: (failed) => `⚠️ ${failed.details}`,
|
|
22
|
-
// The channel owns transport + format (markdown card) + attachments (image→vision, file→disk) +
|
|
23
|
-
// the live streaming preview. `route` (POLICY) is OPTIONAL — omitted, it uses defaultFeishuRoute:
|
|
24
|
-
// p2p chats always answer; groups answer on @this-bot, plus bare messages in a thread where the
|
|
25
|
-
// Agent takes part and exactly ONE human does. Other human group/thread discussion buffers until
|
|
26
|
-
// that place's next answered turn; @other-only messages buffer rather than triggering the Agent.
|
|
27
|
-
// Override to customise explicit routing, reusing the export:
|
|
28
|
-
// route: (e) => defaultFeishuRoute(e, { botOpenId: "ou_xxx" }) && { session: `user:${e.sender?.sender_id?.open_id}` },
|
|
29
|
-
// route: (e) => defaultFeishuRoute(e, { botOpenId: "ou_xxx" }) && { text: `${feishuEnvelope(e)}\n[extra]` },
|
|
30
|
-
}),
|
|
31
|
-
});
|
package/dist/channels/http.d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HTTP/SSE channel: fan one invoke stream out to Server-Sent Events. The web stream primitives supply cancellation
|
|
3
|
-
* natively (consumer disconnect → `cancel()` → `iterator.return()` → invoke cancellation, SPEC MUST 3), backpressure,
|
|
4
|
-
* and the body cap.
|
|
5
|
-
*/
|
|
6
|
-
import type { Agent } from "../agent.ts";
|
|
7
|
-
/**
|
|
8
|
-
* Request body cap (1 MiB) — shared by every Prompt-bearing wire surface (the control plane's dispatch imports it), so
|
|
9
|
-
* the two caps cannot drift apart.
|
|
10
|
-
*/
|
|
11
|
-
export declare const MAX_BODY_BYTES: number;
|
|
12
|
-
/**
|
|
13
|
-
* A valid example request body for the invoke handler — lives HERE, next to the shape check it must satisfy, so the
|
|
14
|
-
* CLI's "try it" hint can't drift from the protocol.
|
|
15
|
-
*/
|
|
16
|
-
export declare const INVOKE_EXAMPLE_BODY = "{\"session\":\"dev\",\"text\":\"hello\"}";
|
|
17
|
-
/**
|
|
18
|
-
* Fetch-shaped invoke handler.
|
|
19
|
-
*
|
|
20
|
-
* No CORS here: who may call this from a browser is decided once, before dispatch, in `channels/serve.ts`'s router
|
|
21
|
-
* — which is also the only layer that can answer the `OPTIONS` preflight, since this route registers only `POST`.
|
|
22
|
-
*/
|
|
23
|
-
export declare function createInvokeHandler(agent: Agent): (req: Request) => Promise<Response>;
|
package/dist/channels/http.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { readBodyCapped, refuseNonJsonBody } from "./body.js";
|
|
2
|
-
import { text } from "./respond.js";
|
|
3
|
-
import { sseResponse } from "./sse.js";
|
|
4
|
-
/**
|
|
5
|
-
* Request body cap (1 MiB) — shared by every Prompt-bearing wire surface (the control plane's dispatch imports it), so
|
|
6
|
-
* the two caps cannot drift apart.
|
|
7
|
-
*/
|
|
8
|
-
export const MAX_BODY_BYTES = 1 << 20;
|
|
9
|
-
/**
|
|
10
|
-
* A valid example request body for the invoke handler — lives HERE, next to the shape check it must satisfy, so the
|
|
11
|
-
* CLI's "try it" hint can't drift from the protocol.
|
|
12
|
-
*/
|
|
13
|
-
export const INVOKE_EXAMPLE_BODY = '{"session":"dev","text":"hello"}';
|
|
14
|
-
/**
|
|
15
|
-
* Fetch-shaped invoke handler.
|
|
16
|
-
*
|
|
17
|
-
* No CORS here: who may call this from a browser is decided once, before dispatch, in `channels/serve.ts`'s router
|
|
18
|
-
* — which is also the only layer that can answer the `OPTIONS` preflight, since this route registers only `POST`.
|
|
19
|
-
*/
|
|
20
|
-
export function createInvokeHandler(agent) {
|
|
21
|
-
return async (req) => {
|
|
22
|
-
if (req.method !== "POST")
|
|
23
|
-
return text("POST only\n", 405);
|
|
24
|
-
// Also applied by the host router over every unguarded route — kept HERE too because this handler is a
|
|
25
|
-
// PUBLIC standalone artifact (docs/overview.md mounts it as a Next.js route), and a handler you can mount
|
|
26
|
-
// anywhere has to be safe anywhere. The router's copy is what stops a route added later from forgetting.
|
|
27
|
-
const wrongType = refuseNonJsonBody(req);
|
|
28
|
-
if (wrongType)
|
|
29
|
-
return wrongType;
|
|
30
|
-
const body = await readBodyCapped(req, MAX_BODY_BYTES);
|
|
31
|
-
if ("tooLarge" in body)
|
|
32
|
-
return text("body too large\n", 413);
|
|
33
|
-
let payload;
|
|
34
|
-
try {
|
|
35
|
-
payload = JSON.parse(body.text);
|
|
36
|
-
}
|
|
37
|
-
catch {
|
|
38
|
-
return text("invalid json\n", 400);
|
|
39
|
-
}
|
|
40
|
-
const { session, text: promptText, parentSession, branchHints, } = (payload ?? {});
|
|
41
|
-
if (typeof session !== "string" || typeof promptText !== "string") {
|
|
42
|
-
return text('need { "session": string, "text": string }\n', 400);
|
|
43
|
-
}
|
|
44
|
-
// INVOKE_EXAMPLE_BODY must keep satisfying this request shape.
|
|
45
|
-
if (parentSession !== undefined && typeof parentSession !== "string") {
|
|
46
|
-
return text('"parentSession" must be a string\n', 400);
|
|
47
|
-
}
|
|
48
|
-
if (branchHints !== undefined && !(Array.isArray(branchHints) && branchHints.every((h) => typeof h === "string"))) {
|
|
49
|
-
return text('"branchHints" must be an array of strings\n', 400);
|
|
50
|
-
}
|
|
51
|
-
return sseResponse(agent.invoke({
|
|
52
|
-
session,
|
|
53
|
-
...(parentSession !== undefined ? { parentSession } : {}),
|
|
54
|
-
...(branchHints !== undefined ? { branchHints } : {}),
|
|
55
|
-
}, { text: promptText }));
|
|
56
|
-
};
|
|
57
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { larkWebSocketChannel } from "@fastagent-sh/fastagent/lark";
|
|
2
|
-
import { defineChannel } from "@fastagent-sh/fastagent";
|
|
3
|
-
|
|
4
|
-
// Lark WebSocket long connection: the process connects OUT to the platform, so no public URL,
|
|
5
|
-
// Verification Token, Encrypt Key, or --tunnel is needed. In Events & Callbacks choose long
|
|
6
|
-
// connection, subscribe im.message.receive_v1, then publish the app version. Keep one process
|
|
7
|
-
// running in production: scale-to-zero/App Sleeping would disconnect ingress.
|
|
8
|
-
export default defineChannel({
|
|
9
|
-
// The env vars this channel needs. fastagent carries them to a deployed box and refuses to serve
|
|
10
|
-
// while one is unset — a bare process.env read gets neither guarantee.
|
|
11
|
-
secrets: ["LARK_APP_ID", "LARK_APP_SECRET"],
|
|
12
|
-
channel: (secrets) =>
|
|
13
|
-
larkWebSocketChannel({
|
|
14
|
-
appId: secrets.LARK_APP_ID,
|
|
15
|
-
appSecret: secrets.LARK_APP_SECRET,
|
|
16
|
-
// No session modes: a chat is one session and a thread is another, and where the answer goes follows
|
|
17
|
-
// from that (docs/design/participant-model.md).
|
|
18
|
-
// Dev/personal bot: surface raw errors to the chat so you (and your AI agent) can act on them. The
|
|
19
|
-
// chat is customer-facing by default — for a public bot, drop this or return a neutral string;
|
|
20
|
-
// full details always go to the server log regardless.
|
|
21
|
-
onError: (failed) => `⚠️ ${failed.details}`,
|
|
22
|
-
// The channel owns transport + format (markdown card) + attachments (image→vision, file→disk) +
|
|
23
|
-
// the live streaming preview. `route` (POLICY) is OPTIONAL — omitted, it uses defaultLarkRoute:
|
|
24
|
-
// p2p chats always answer; groups answer on @this-bot, plus bare messages in a thread where the
|
|
25
|
-
// Agent takes part and exactly ONE human does. Other human group/thread discussion buffers until
|
|
26
|
-
// that place's next answered turn; @other-only messages buffer rather than triggering the Agent.
|
|
27
|
-
// Override to customise explicit routing, reusing the export:
|
|
28
|
-
// route: (e) => defaultLarkRoute(e, { botOpenId: "ou_xxx" }) && { session: `user:${e.sender?.sender_id?.open_id}` },
|
|
29
|
-
// route: (e) => defaultLarkRoute(e, { botOpenId: "ou_xxx" }) && { text: `${larkEnvelope(e)}\n[extra]` },
|
|
30
|
-
}),
|
|
31
|
-
});
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Slack's half of the shared context buffer (mechanics + consume protocol: ../kit/context-buffer.ts): the entry shape,
|
|
3
|
-
* its fold-line rendering, and buffered-file selection.
|
|
4
|
-
*/
|
|
5
|
-
import { type ContextBuffer } from "../kit/context-buffer.ts";
|
|
6
|
-
export interface SlackBufferEntry {
|
|
7
|
-
sender: string;
|
|
8
|
-
body: string;
|
|
9
|
-
messageId: string;
|
|
10
|
-
replyTo?: string;
|
|
11
|
-
fileIds?: string[];
|
|
12
|
-
}
|
|
13
|
-
export interface SlackBufferedFileRef {
|
|
14
|
-
id: string;
|
|
15
|
-
from: string;
|
|
16
|
-
messageId: string;
|
|
17
|
-
}
|
|
18
|
-
export declare function collectSlackBufferedFiles(consumed: SlackBufferEntry[], primaryIds: Set<string>): {
|
|
19
|
-
files: SlackBufferedFileRef[];
|
|
20
|
-
skipped: number;
|
|
21
|
-
};
|
|
22
|
-
export type SlackContextBuffer = ContextBuffer<SlackBufferEntry>;
|
|
23
|
-
export declare function createSlackContextBuffer(path: string, label: string): SlackContextBuffer;
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Slack's half of the shared context buffer (mechanics + consume protocol: ../kit/context-buffer.ts): the entry shape,
|
|
3
|
-
* its fold-line rendering, and buffered-file selection.
|
|
4
|
-
*/
|
|
5
|
-
import { capBufferedRefs, createContextBuffer as createGenericContextBuffer, } from "../kit/context-buffer.js";
|
|
6
|
-
function bufferLine(entry) {
|
|
7
|
-
const meta = [`msg ${entry.messageId}`, entry.replyTo ? `thread root ${entry.replyTo}` : undefined]
|
|
8
|
-
.filter(Boolean)
|
|
9
|
-
.join(", ");
|
|
10
|
-
return `${entry.sender} (${meta}): ${entry.body}`;
|
|
11
|
-
}
|
|
12
|
-
export function collectSlackBufferedFiles(consumed, primaryIds) {
|
|
13
|
-
const seen = new Set();
|
|
14
|
-
const files = [];
|
|
15
|
-
for (const entry of consumed) {
|
|
16
|
-
for (const id of entry.fileIds ?? []) {
|
|
17
|
-
if (primaryIds.has(id) || seen.has(id))
|
|
18
|
-
continue;
|
|
19
|
-
seen.add(id);
|
|
20
|
-
files.push({ id, from: entry.sender, messageId: entry.messageId });
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
const capped = capBufferedRefs(files);
|
|
24
|
-
return { files: capped.kept, skipped: capped.skipped };
|
|
25
|
-
}
|
|
26
|
-
function isEntry(value) {
|
|
27
|
-
const entry = value;
|
|
28
|
-
return (typeof entry?.sender === "string" &&
|
|
29
|
-
typeof entry.body === "string" &&
|
|
30
|
-
typeof entry.messageId === "string" &&
|
|
31
|
-
(entry.replyTo === undefined || typeof entry.replyTo === "string") &&
|
|
32
|
-
(entry.fileIds === undefined ||
|
|
33
|
-
(Array.isArray(entry.fileIds) && entry.fileIds.every((id) => typeof id === "string"))));
|
|
34
|
-
}
|
|
35
|
-
export function createSlackContextBuffer(path, label) {
|
|
36
|
-
return createGenericContextBuffer({ path, label, isEntry, line: bufferLine });
|
|
37
|
-
}
|
package/dist/channels/sse.d.ts
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
/** Shared SSE response lifecycle for invoke and session observation. */
|
|
2
|
-
/** The remote client's idle watchdog allows three missed heartbeats. */
|
|
3
|
-
export declare const SSE_HEARTBEAT_MS = 30000;
|
|
4
|
-
export declare function sseResponse<T>(events: AsyncIterable<T>, project?: (event: T) => unknown): Response;
|
package/dist/channels/sse.js
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/** Shared SSE response lifecycle for invoke and session observation. */
|
|
2
|
-
/** The remote client's idle watchdog allows three missed heartbeats. */
|
|
3
|
-
export const SSE_HEARTBEAT_MS = 30_000;
|
|
4
|
-
const encoder = new TextEncoder();
|
|
5
|
-
const heartbeat = encoder.encode(": ping\n\n");
|
|
6
|
-
export function sseResponse(events, project = (event) => event) {
|
|
7
|
-
const iterator = events[Symbol.asyncIterator]();
|
|
8
|
-
// Subscribe before headers; synchronous startup errors belong to the HTTP error boundary.
|
|
9
|
-
let pending = Promise.resolve(iterator.next());
|
|
10
|
-
// pull() surfaces asynchronous failures. Observe rejection even if the caller cancels before that pull.
|
|
11
|
-
pending.catch(() => { });
|
|
12
|
-
let closed = false;
|
|
13
|
-
let timer;
|
|
14
|
-
const stop = () => {
|
|
15
|
-
closed = true;
|
|
16
|
-
clearInterval(timer);
|
|
17
|
-
};
|
|
18
|
-
const cancel = async () => {
|
|
19
|
-
if (closed)
|
|
20
|
-
return;
|
|
21
|
-
stop();
|
|
22
|
-
await iterator.return?.();
|
|
23
|
-
};
|
|
24
|
-
const stream = new ReadableStream({
|
|
25
|
-
start(controller) {
|
|
26
|
-
timer = setInterval(() => controller.enqueue(heartbeat), SSE_HEARTBEAT_MS);
|
|
27
|
-
},
|
|
28
|
-
async pull(controller) {
|
|
29
|
-
try {
|
|
30
|
-
const next = await (pending ?? iterator.next());
|
|
31
|
-
pending = undefined;
|
|
32
|
-
// Cancellation can settle a pending next(); its value no longer has a reader.
|
|
33
|
-
if (closed)
|
|
34
|
-
return;
|
|
35
|
-
if (next.done) {
|
|
36
|
-
stop();
|
|
37
|
-
controller.close();
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
controller.enqueue(encoder.encode(`data: ${JSON.stringify(project(next.value))}\n\n`));
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
catch (error) {
|
|
44
|
-
if (closed)
|
|
45
|
-
return;
|
|
46
|
-
// Errored streams never call cancel(), so iterator and timer cleanup belongs here too.
|
|
47
|
-
try {
|
|
48
|
-
await cancel();
|
|
49
|
-
}
|
|
50
|
-
catch (cleanupError) {
|
|
51
|
-
controller.error(new AggregateError([error, cleanupError], "SSE source and cleanup failed", { cause: error }));
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
controller.error(error);
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
cancel,
|
|
58
|
-
});
|
|
59
|
-
return new Response(stream, {
|
|
60
|
-
headers: {
|
|
61
|
-
"content-type": "text/event-stream",
|
|
62
|
-
"cache-control": "no-cache",
|
|
63
|
-
connection: "keep-alive",
|
|
64
|
-
},
|
|
65
|
-
});
|
|
66
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/** `fastagent chat [dir]`: open the SAME assembled agent in pi's interactive TUI. */
|
|
2
|
-
import { failStartup } from "../fail.js";
|
|
3
|
-
import { enterAgentCommand } from "../shared.js";
|
|
4
|
-
export async function runChat(dirArg, opts) {
|
|
5
|
-
// Chat authenticates through fastagent's credential store like every other command (the shared session builder
|
|
6
|
-
// injects it — see engines/pi/session-builder.ts), so the first-run picker and its inline login apply here too.
|
|
7
|
-
const placement = await enterAgentCommand(dirArg, opts);
|
|
8
|
-
// Run the chat process AT the workspace: pi resolves a session's cwd as `header.cwd ?? process.cwd()`, so aligning
|
|
9
|
-
// process.cwd() with the workspace keeps a cwd-less session on it.
|
|
10
|
-
process.chdir(placement.workspace);
|
|
11
|
-
// Lazy-import: chat pulls pi's interactive TUI module graph; headless start/dev never need it.
|
|
12
|
-
const { runPiChat } = await import("../../engines/pi/chat.js");
|
|
13
|
-
await runPiChat(placement.agentDir, { model: placement.modelSpec }).catch(failStartup);
|
|
14
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `fastagent routine run <name> [dir]`: run ONE routine's turn immediately — the authoring loop for routines (like
|
|
3
|
-
* `invoke` is for a prompt). Cron or not: a routine that declares none has no other local entry.
|
|
4
|
-
*/
|
|
5
|
-
import { join } from "node:path";
|
|
6
|
-
import { displayPath } from "../../paths.js";
|
|
7
|
-
import { reportModuleLoadFailures } from "../../loader.js";
|
|
8
|
-
import { createPiAgentFromDir } from "../../engines/pi/open.js";
|
|
9
|
-
import { runInvokeStream } from "../invoke-stream.js";
|
|
10
|
-
import { loadRoutines } from "../../schedule/discover.js";
|
|
11
|
-
import { routineSession } from "../../schedule/routine.js";
|
|
12
|
-
import { failStartup, gateSecretsOrExit } from "../fail.js";
|
|
13
|
-
import { enterAgentDirectory, reportAuth, requireDefaultModel } from "../shared.js";
|
|
14
|
-
export async function runRoutine(name, dirArg, opts) {
|
|
15
|
-
const placement = await enterAgentDirectory(dirArg, opts);
|
|
16
|
-
// Routines are agent surface — discovered where dev/start/`routine list` do (the agent dir), so this command
|
|
17
|
-
// sees the same set the clock serves.
|
|
18
|
-
const { routines, secrets, failures } = await loadRoutines(placement.agentDir).catch(failStartup);
|
|
19
|
-
// Reported BEFORE the name is looked up: a routine file that failed to import is missing from
|
|
20
|
-
// `routines`, so "unknown routine" is the case where the author most needs to hear about it.
|
|
21
|
-
reportModuleLoadFailures(failures);
|
|
22
|
-
const routine = routines.find((r) => r.name === name);
|
|
23
|
-
if (!routine) {
|
|
24
|
-
// Name the discovery path: a schedule misplaced in the workspace (outside the agent dir) should read as "wrong
|
|
25
|
-
// place", not "broken file".
|
|
26
|
-
failStartup(new Error(`unknown routine "${name}" (looked in ${displayPath(process.cwd(), join(placement.agentDir, "routines")) ?? "routines"}). ` +
|
|
27
|
-
`available: ${routines.map((r) => r.name).join(", ") || "(none)"}`));
|
|
28
|
-
}
|
|
29
|
-
// This RUNS the routine, so it takes the serving path's guarantee: a prompt built from an
|
|
30
|
-
// unset declared value is the degraded turn this feature exists to prevent (`Post the digest to `
|
|
31
|
-
// — sent and executed), and the loader resolved it into a string before anything could notice.
|
|
32
|
-
// THIS schedule only (`owner`): running one routine must not fail because a SIBLING ROUTINE needs a
|
|
33
|
-
// credential this machine has no reason to hold. The agent assembled below is a different question
|
|
34
|
-
// and gates every mounted tool — a run's turn can call any of them — so this command is not free of a
|
|
35
|
-
// tool's declaration, only of another routine's. The failures go to the gate too, even though they
|
|
36
|
-
// were printed above: its guarantee must not depend on this call site remembering (a repeated line
|
|
37
|
-
// on the refusal path is the cheaper failure).
|
|
38
|
-
gateSecretsOrExit({ declared: secrets, failures, owner: name });
|
|
39
|
-
const { modelSpec } = requireDefaultModel(placement);
|
|
40
|
-
const { agent, models } = await createPiAgentFromDir(placement.agentDir, { model: modelSpec }).catch(failStartup);
|
|
41
|
-
console.error(`[fastagent] routine run: ${name} (${modelSpec})`);
|
|
42
|
-
await reportAuth(models, modelSpec);
|
|
43
|
-
const exitCode = await runInvokeStream(agent.invoke({ session: routineSession(name) }, { text: routine.prompt }), (text) => process.stdout.write(text), (line) => console.error(line));
|
|
44
|
-
process.stdout.write("\n");
|
|
45
|
-
process.exit(exitCode);
|
|
46
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `fastagent routine history <name> [dir]`: print this routine's fired slots — when each fired, how it ended, how
|
|
3
|
-
* long it took.
|
|
4
|
-
*
|
|
5
|
-
* The history IS the claims (`schedule/claims/<name>/`), so it is bounded by construction and carries no turn text:
|
|
6
|
-
* what the run SAID is in its session (`routine:<name>`), stored once, like any other turn's, under the state
|
|
7
|
-
* root's `sessions/` — which is where this command points rather than copying any of it here.
|
|
8
|
-
*
|
|
9
|
-
* This command does NOT try to say which turn belongs to which fire. Nothing links them: a routine's fires share
|
|
10
|
-
* ONE continuing conversation, so the session id is the same for all of them, and the turn-level identifier would
|
|
11
|
-
* have to cross the engine-neutral contract (no `AgentEvent` carries an entry id) or cost the shared conversation.
|
|
12
|
-
* A claim's timestamp against a time-ordered journal is what an operator reads anyway — matching them HERE only
|
|
13
|
-
* moves a human's judgement into a heuristic that cannot be right about a session other writers also append to.
|
|
14
|
-
*/
|
|
15
|
-
export declare function runRoutineHistory(name: string, dirArg: string, json: boolean): void;
|
|
16
|
-
/**
|
|
17
|
-
* `fastagent routine list [dir]`: every declared routine, and when (or whether) a clock fires it.
|
|
18
|
-
*
|
|
19
|
-
* IT ALSO READS the agent's pending wake-ups. They are a different owner (the state, not the definition) but the
|
|
20
|
-
* same question when an operator is asking it: "what is going to wake this agent up?". Deleting the command that
|
|
21
|
-
* CANCELLED one was right — `unwake({ id })` covers it, and a serve that can receive the alarm can also be spoken
|
|
22
|
-
* to — but that argument is about WRITING. Without a read, the only way to learn why an agent wakes at 3am is to
|
|
23
|
-
* open `<stateRoot>/schedule/wakeups.json` by hand.
|
|
24
|
-
*/
|
|
25
|
-
export declare function runRoutineList(dirArg: string, json: boolean): Promise<void>;
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `fastagent routine history|list` — the routines this DEFINITION declares.
|
|
3
|
-
*
|
|
4
|
-
* The agent's own pending wake-ups are not here and have no command: they live in the state, not the definition,
|
|
5
|
-
* and `unwake({ id })` is what cancels one (schedule/wakeups.ts says why).
|
|
6
|
-
*/
|
|
7
|
-
import { resolve } from "node:path";
|
|
8
|
-
import { enterAgentEnv } from "../../env.js";
|
|
9
|
-
import { resolveSessionsDir, resolveStateRoot } from "../../paths.js";
|
|
10
|
-
import { reportModuleLoadFailures } from "../../loader.js";
|
|
11
|
-
import { nextRun } from "../../schedule/cron.js";
|
|
12
|
-
import { loadRoutines } from "../../schedule/discover.js";
|
|
13
|
-
import { routineSession } from "../../schedule/routine.js";
|
|
14
|
-
import { isSafeScheduleName, readFires } from "../../schedule/state.js";
|
|
15
|
-
import { listWakeups } from "../../schedule/wakeups.js";
|
|
16
|
-
import { failStartup, placementOrExit } from "../fail.js";
|
|
17
|
-
/**
|
|
18
|
-
* `fastagent routine history <name> [dir]`: print this routine's fired slots — when each fired, how it ended, how
|
|
19
|
-
* long it took.
|
|
20
|
-
*
|
|
21
|
-
* The history IS the claims (`schedule/claims/<name>/`), so it is bounded by construction and carries no turn text:
|
|
22
|
-
* what the run SAID is in its session (`routine:<name>`), stored once, like any other turn's, under the state
|
|
23
|
-
* root's `sessions/` — which is where this command points rather than copying any of it here.
|
|
24
|
-
*
|
|
25
|
-
* This command does NOT try to say which turn belongs to which fire. Nothing links them: a routine's fires share
|
|
26
|
-
* ONE continuing conversation, so the session id is the same for all of them, and the turn-level identifier would
|
|
27
|
-
* have to cross the engine-neutral contract (no `AgentEvent` carries an entry id) or cost the shared conversation.
|
|
28
|
-
* A claim's timestamp against a time-ordered journal is what an operator reads anyway — matching them HERE only
|
|
29
|
-
* moves a human's judgement into a heuristic that cannot be right about a session other writers also append to.
|
|
30
|
-
*/
|
|
31
|
-
export function runRoutineHistory(name, dirArg, json) {
|
|
32
|
-
const { agentDir: target } = placementOrExit(resolve(dirArg));
|
|
33
|
-
enterAgentEnv(target); // FASTAGENT_STATE_DIR may live in .env — read the SAME state root the scheduler wrote
|
|
34
|
-
const stateRoot = resolveStateRoot(target);
|
|
35
|
-
// A name that cannot be a routine is a MISTYPED ARGUMENT, and it must not look like an empty history: exit 1 the
|
|
36
|
-
// way every other user-input refusal does, so `--json` printing nothing is never read as "the command succeeded".
|
|
37
|
-
if (!isSafeScheduleName(name)) {
|
|
38
|
-
failStartup(new Error(`"${name}" cannot be a routine name (no path separators, "." or "..")`));
|
|
39
|
-
}
|
|
40
|
-
// `readFires` throws a raw fs error on unreadable state, because its other caller is the serving boot, which must
|
|
41
|
-
// fail rather than arm a schedule it cannot read. This caller is a read-only CLI command: the same fact is an
|
|
42
|
-
// operator's to fix, so it exits the way every other refusal in this file does instead of printing a Node stack.
|
|
43
|
-
let fires;
|
|
44
|
-
try {
|
|
45
|
-
fires = readFires(stateRoot, name);
|
|
46
|
-
}
|
|
47
|
-
catch (e) {
|
|
48
|
-
failStartup(new Error(`the fired-slot claims for "${name}" are unreadable (state: ${stateRoot}): ${String(e)}`));
|
|
49
|
-
}
|
|
50
|
-
if (json) {
|
|
51
|
-
console.log(JSON.stringify(fires, null, 2));
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
if (fires.length === 0) {
|
|
55
|
-
// No special case for "wake": it is an ordinary schedule name now (`discover.ts` stopped reserving it).
|
|
56
|
-
console.error(`no recorded fires for "${name}" (state: ${stateRoot})`);
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
// The question is "did LAST NIGHT's run fail?", so text mode tails the most recent fires; --json above is the
|
|
60
|
-
// whole retained window.
|
|
61
|
-
const TAIL = 20;
|
|
62
|
-
const shown = fires.slice(-TAIL);
|
|
63
|
-
for (const f of shown) {
|
|
64
|
-
// An unreported fire has no duration to print, and `0ms` would be a value a fast turn really produces — the
|
|
65
|
-
// column stays empty rather than claiming the turn took no time.
|
|
66
|
-
const took = f.ms === undefined ? "" : `${f.ms}ms`;
|
|
67
|
-
console.log(`${f.firedAt} ${(f.outcome ?? "unreported").padEnd(11)} ${took.padStart(8)}`);
|
|
68
|
-
}
|
|
69
|
-
if (fires.length > shown.length) {
|
|
70
|
-
console.error(`(the last ${shown.length} of ${fires.length} fires — --json for all)`);
|
|
71
|
-
}
|
|
72
|
-
// The other half of the answer, and where it lives: these rows say a fire happened, not what it produced. The
|
|
73
|
-
// session id comes from the ONE place that spells it and the directory from the ONE place that resolves it. The
|
|
74
|
-
// record is one level further down and under a name pi accepts (`piSessionId` escapes the `:`), so the pointer
|
|
75
|
-
// says how to recognise the file rather than claiming a path the reader can paste.
|
|
76
|
-
console.error(`(what these runs said: session ${routineSession(name)} — a JSON-lines journal under ${resolveSessionsDir(target)}, ` +
|
|
77
|
-
`in the file whose name carries "${name}")`);
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* `fastagent routine list [dir]`: every declared routine, and when (or whether) a clock fires it.
|
|
81
|
-
*
|
|
82
|
-
* IT ALSO READS the agent's pending wake-ups. They are a different owner (the state, not the definition) but the
|
|
83
|
-
* same question when an operator is asking it: "what is going to wake this agent up?". Deleting the command that
|
|
84
|
-
* CANCELLED one was right — `unwake({ id })` covers it, and a serve that can receive the alarm can also be spoken
|
|
85
|
-
* to — but that argument is about WRITING. Without a read, the only way to learn why an agent wakes at 3am is to
|
|
86
|
-
* open `<stateRoot>/schedule/wakeups.json` by hand.
|
|
87
|
-
*/
|
|
88
|
-
export async function runRoutineList(dirArg, json) {
|
|
89
|
-
const { agentDir: target } = placementOrExit(resolve(dirArg));
|
|
90
|
-
enterAgentEnv(target);
|
|
91
|
-
const { routines, failures } = await loadRoutines(target).catch(failStartup);
|
|
92
|
-
reportModuleLoadFailures(failures);
|
|
93
|
-
const wakeups = listWakeups(resolveStateRoot(target));
|
|
94
|
-
if (json) {
|
|
95
|
-
console.log(JSON.stringify({
|
|
96
|
-
routines: routines.map((r) => ({
|
|
97
|
-
...r,
|
|
98
|
-
next: r.cron === undefined ? null : (nextRun(r.cron, r.tz, new Date())?.toISOString() ?? null),
|
|
99
|
-
})),
|
|
100
|
-
wakeups,
|
|
101
|
-
}, null, 2));
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
if (routines.length === 0 && wakeups.length === 0) {
|
|
105
|
-
console.error(`nothing declared or pending — no routines/ files, no wake-ups (agent: ${target})`);
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
for (const r of routines) {
|
|
109
|
-
// A routine with no cron is not broken and not idle: it is reached by NAME (`routine run`, `POST /run`), and
|
|
110
|
-
// saying "on demand" is the difference between that and a cron that will never fire again.
|
|
111
|
-
const when = r.cron === undefined
|
|
112
|
-
? "on demand".padEnd(26)
|
|
113
|
-
: `${(nextRun(r.cron, r.tz, new Date())?.toISOString() ?? "(never)").padEnd(26)}cron ${r.cron}${r.tz ? ` ${r.tz}` : ""}`;
|
|
114
|
-
console.log(`${r.name.padEnd(20)} ${when}`);
|
|
115
|
-
}
|
|
116
|
-
// Labelled, because these two are NOT the same kind of thing: a routine is the author's, a wake-up is the
|
|
117
|
-
// agent's own and is cancelled with `unwake` rather than a command here.
|
|
118
|
-
for (const w of wakeups) {
|
|
119
|
-
const kind = w.cron ? `cron ${w.cron}${w.tz ? ` ${w.tz}` : ""}` : "one-shot";
|
|
120
|
-
console.log(`wake ${w.id} ${w.fireAt} ${kind} session=${w.session} ${w.prompt.slice(0, 60)}`);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function runTool(name: string, argsJson: string, dirArg: string): Promise<void>;
|