@fastagent-sh/fastagent 0.24.4 → 0.26.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 +54 -82
- package/dist/agent-api.d.ts +460 -0
- package/dist/agent-api.js +209 -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 +81 -0
- package/dist/authoring.js +245 -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 +116 -64
- package/dist/cli/auth-view.d.ts +10 -3
- package/dist/cli/auth-view.js +8 -6
- package/dist/cli/box-login.d.ts +18 -7
- package/dist/cli/box-login.js +46 -12
- package/dist/cli/commands/add.d.ts +15 -4
- package/dist/cli/commands/add.js +253 -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 +191 -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 +132 -16
- package/dist/cli/commands/login.d.ts +31 -2
- package/dist/cli/commands/login.js +416 -65
- 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 +6 -4
- package/dist/cli/login-relay.js +19 -7
- 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 +70 -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 +220 -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 +223 -202
- 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 +52 -27
- package/dist/effect-port.d.ts +4 -4
- package/dist/effect-port.js +4 -4
- package/dist/env.d.ts +0 -13
- package/dist/env.js +1 -44
- 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 +51 -0
- package/dist/environment/mise.js +272 -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 +48 -0
- package/dist/harnesses/models/environment.js +88 -0
- package/dist/harnesses/models/host.d.ts +30 -0
- package/dist/harnesses/models/host.js +97 -0
- package/dist/{engines/pi → harnesses/models}/login.d.ts +66 -70
- package/dist/harnesses/models/login.js +439 -0
- package/dist/harnesses/models/models.d.ts +84 -0
- package/dist/harnesses/models/models.js +197 -0
- package/dist/harnesses/pi-durable/agent.d.ts +42 -0
- package/dist/harnesses/pi-durable/agent.js +581 -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 +95 -0
- package/dist/harnesses/pi-durable/open.js +330 -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 +90 -0
- package/dist/harnesses/pi-durable/serve.js +186 -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 +11 -0
- package/dist/harnesses/pi-durable/wake.js +90 -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 +19 -4
- package/dist/index.js +13 -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/sign-in-api.d.ts +147 -0
- package/dist/sign-in-api.js +9 -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 +14 -5
- package/dist/value-file.d.ts +40 -0
- package/dist/value-file.js +164 -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/login.js +0 -331
- 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,23 +0,0 @@
|
|
|
1
|
-
/** A user prompt's and a tool result's images; no other message publishes any, so no ref can reach them. */
|
|
2
|
-
function publishedImages(message) {
|
|
3
|
-
if (message.role !== "user" && message.role !== "toolResult")
|
|
4
|
-
return [];
|
|
5
|
-
const content = message.content;
|
|
6
|
-
return Array.isArray(content) ? content.filter((b) => b.type === "image") : [];
|
|
7
|
-
}
|
|
8
|
-
/** `data.images` of the entry `entryId` holding `message`, absent when it has none. */
|
|
9
|
-
export function entryImages(entryId, message) {
|
|
10
|
-
const images = publishedImages(message).map((b, i) => ({ ref: `${entryId}:${i}`, mimeType: b.mimeType }));
|
|
11
|
-
return images.length > 0 ? { images } : {};
|
|
12
|
-
}
|
|
13
|
-
/** The image `ref` names in `record`, or undefined when it names none there. The inverse of `entryImages`. */
|
|
14
|
-
export function imageAt(record, ref) {
|
|
15
|
-
const at = ref.lastIndexOf(":");
|
|
16
|
-
const index = ref.slice(at + 1);
|
|
17
|
-
// Canonical digits only, so one image has one ref (`:00` is not `:0`).
|
|
18
|
-
if (at <= 0 || !/^(0|[1-9]\d*)$/.test(index))
|
|
19
|
-
return undefined;
|
|
20
|
-
const entry = record.getEntry(ref.slice(0, at));
|
|
21
|
-
const image = entry?.type === "message" ? publishedImages(entry.message)[Number(index)] : undefined;
|
|
22
|
-
return image ? { data: image.data, mimeType: image.mimeType } : undefined;
|
|
23
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/** Pi's per-invoke binding over a durable session record. */
|
|
2
|
-
import type { AgentSession, AgentSessionEvent } from "@earendil-works/pi-coding-agent";
|
|
3
|
-
import { type Agent } from "../../agent.ts";
|
|
4
|
-
import type { SessionEvent } from "../../session.ts";
|
|
5
|
-
import type { SessionInheritance } from "./session-inheritance.ts";
|
|
6
|
-
import { type Lease, type SessionObserver } from "./turn-kit.ts";
|
|
7
|
-
/** Open or create a record and bind a session. */
|
|
8
|
-
export type PiAgentSessionFactory = (sessionId: string, inherit?: SessionInheritance) => Promise<AgentSession>;
|
|
9
|
-
export interface CreatePiAgentFromSessionOptions {
|
|
10
|
-
sessionFactory: PiAgentSessionFactory;
|
|
11
|
-
/** Shared with control-plane writes; admission is synchronous and fail-fast. */
|
|
12
|
-
lease?: Lease;
|
|
13
|
-
/** Trusted observation tap; controls arrive with run_started, before session binding. */
|
|
14
|
-
observer?: SessionObserver;
|
|
15
|
-
}
|
|
16
|
-
/** pi's session event as the observation plane's, or null for one it does not publish. Exported for tests only. */
|
|
17
|
-
export declare function toSessionEvent(event: AgentSessionEvent, runId: string): SessionEvent | null;
|
|
18
|
-
export declare function createPiAgentFromSession(options: CreatePiAgentFromSessionOptions): Agent;
|
|
@@ -1,403 +0,0 @@
|
|
|
1
|
-
import { contentText } from "@earendil-works/pi-ai";
|
|
2
|
-
import * as Deferred from "effect/Deferred";
|
|
3
|
-
import * as Effect from "effect/Effect";
|
|
4
|
-
import * as Fiber from "effect/Fiber";
|
|
5
|
-
import * as Queue from "effect/Queue";
|
|
6
|
-
import { ABORTED_CODE, MISSING_MODEL_CODE, SESSION_BUSY_CODE, } from "../../agent.js";
|
|
7
|
-
import { entryImages } from "./entry-images.js";
|
|
8
|
-
import { cancellableStream } from "../../collect.js";
|
|
9
|
-
import { log } from "../../log.js";
|
|
10
|
-
import { toRetryScheduledEvent } from "./retry-event.js";
|
|
11
|
-
import { PortFailure, port, portAbort, portCleanup, portError } from "../../effect-port.js";
|
|
12
|
-
import { SessionBusy, acquireSession, acquireSessionLease } from "./session-effects.js";
|
|
13
|
-
import { MissingModel } from "./session-settings.js";
|
|
14
|
-
import { errorToTerminal, inProcessLease, agentEventProjection, answerOutcome, streamsThinkingDelta, asksToEndRun, toPiPromptOptions, toTerminal, } from "./turn-kit.js";
|
|
15
|
-
// Structured output is for scripts. Observation publishes Pi's display result, including bounded nested traces.
|
|
16
|
-
function displayToolResult(result) {
|
|
17
|
-
const { structuredContent: _internal, ...display } = result;
|
|
18
|
-
return display;
|
|
19
|
-
}
|
|
20
|
-
/** pi's session event as the observation plane's, or null for one it does not publish. Exported for tests only. */
|
|
21
|
-
export function toSessionEvent(event, runId) {
|
|
22
|
-
const at = Date.now();
|
|
23
|
-
switch (event.type) {
|
|
24
|
-
case "message_start":
|
|
25
|
-
if (event.message.role !== "assistant")
|
|
26
|
-
return null;
|
|
27
|
-
return { type: "message_started", timestamp: at, runId, data: {} };
|
|
28
|
-
case "message_update": {
|
|
29
|
-
const ev = event.assistantMessageEvent;
|
|
30
|
-
if (ev.type === "text_delta" || ev.type === "thinking_delta") {
|
|
31
|
-
// Empty deltas must not spend the silent window in which a provider retry is safe. A redacted block's
|
|
32
|
-
// placeholder is not reasoning, and its entry will not carry it either (turn-kit.ts answerThinking).
|
|
33
|
-
return ev.delta === "" || (ev.type === "thinking_delta" && !streamsThinkingDelta(ev))
|
|
34
|
-
? null
|
|
35
|
-
: {
|
|
36
|
-
type: "message_delta",
|
|
37
|
-
timestamp: at,
|
|
38
|
-
runId,
|
|
39
|
-
data: { channel: ev.type === "text_delta" ? "text" : "thinking", delta: ev.delta },
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
case "message_end": {
|
|
45
|
-
if (event.message.role !== "assistant")
|
|
46
|
-
return null;
|
|
47
|
-
const outcome = answerOutcome(event.message);
|
|
48
|
-
return { type: "message_finished", timestamp: at, runId, data: outcome ? { outcome } : {} };
|
|
49
|
-
}
|
|
50
|
-
case "tool_execution_start":
|
|
51
|
-
return {
|
|
52
|
-
type: "tool_started",
|
|
53
|
-
timestamp: at,
|
|
54
|
-
runId,
|
|
55
|
-
data: {
|
|
56
|
-
id: event.toolCallId,
|
|
57
|
-
name: event.toolName,
|
|
58
|
-
args: event.args,
|
|
59
|
-
...(event.parentToolCallId ? { parentToolCallId: event.parentToolCallId } : {}),
|
|
60
|
-
},
|
|
61
|
-
};
|
|
62
|
-
case "tool_execution_update":
|
|
63
|
-
return {
|
|
64
|
-
type: "tool_progress",
|
|
65
|
-
timestamp: at,
|
|
66
|
-
runId,
|
|
67
|
-
data: {
|
|
68
|
-
id: event.toolCallId,
|
|
69
|
-
name: event.toolName,
|
|
70
|
-
partialResult: displayToolResult(event.partialResult),
|
|
71
|
-
...(event.parentToolCallId ? { parentToolCallId: event.parentToolCallId } : {}),
|
|
72
|
-
},
|
|
73
|
-
};
|
|
74
|
-
case "tool_execution_end":
|
|
75
|
-
return {
|
|
76
|
-
type: "tool_finished",
|
|
77
|
-
timestamp: at,
|
|
78
|
-
runId,
|
|
79
|
-
data: {
|
|
80
|
-
id: event.toolCallId,
|
|
81
|
-
isError: event.isError,
|
|
82
|
-
content: displayToolResult(event.result),
|
|
83
|
-
...(event.parentToolCallId ? { parentToolCallId: event.parentToolCallId } : {}),
|
|
84
|
-
...(asksToEndRun(event) ? { terminate: true } : {}),
|
|
85
|
-
},
|
|
86
|
-
};
|
|
87
|
-
case "queue_update":
|
|
88
|
-
return {
|
|
89
|
-
type: "queue_changed",
|
|
90
|
-
timestamp: at,
|
|
91
|
-
runId,
|
|
92
|
-
data: { steering: [...event.steering], followUp: [...event.followUp] },
|
|
93
|
-
};
|
|
94
|
-
case "auto_retry_start":
|
|
95
|
-
case "summarization_retry_scheduled":
|
|
96
|
-
return toRetryScheduledEvent(event, runId);
|
|
97
|
-
default:
|
|
98
|
-
return null;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
/** pi's error-channel events for work an invoke owes its caller: the command it ran, and the turns it started. */
|
|
102
|
-
const OWED_BY_THE_RUN = new Set(["command", "send_user_message", "send_message"]);
|
|
103
|
-
/**
|
|
104
|
-
* The turns extensions start on this session and have not finished. `pi.sendUserMessage` and `pi.sendMessage` reach
|
|
105
|
-
* these two session methods, and pi discards the promise; wrapping the methods keeps it. The session is this run's
|
|
106
|
-
* alone, so the wrap never outlives the run.
|
|
107
|
-
*/
|
|
108
|
-
function trackExtensionTurns(session) {
|
|
109
|
-
const pending = new Set();
|
|
110
|
-
const track = (sent) => {
|
|
111
|
-
pending.add(sent);
|
|
112
|
-
const done = () => void pending.delete(sent);
|
|
113
|
-
sent.then(done, done); // pi's own `.catch` on `sent` reports the failure
|
|
114
|
-
return sent;
|
|
115
|
-
};
|
|
116
|
-
const sendUserMessage = session.sendUserMessage.bind(session);
|
|
117
|
-
const sendCustomMessage = session.sendCustomMessage.bind(session);
|
|
118
|
-
session.sendUserMessage = (...args) => track(sendUserMessage(...args));
|
|
119
|
-
session.sendCustomMessage = (...args) => track(sendCustomMessage(...args));
|
|
120
|
-
return pending;
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Report each user message when it is WRITTEN, which is later than pi announces it: pi awaits extension `message_end`
|
|
124
|
-
* handlers before it appends. Emitting from the write is what makes `user_message.entryId` readable through
|
|
125
|
-
* `entries()` by the time the event arrives, so a reconnecting client's backfill cannot miss a message whose event
|
|
126
|
-
* fired before it subscribed. pi's agent awaits each listener before the next event, so the message still reports
|
|
127
|
-
* before the answer to it. The in-memory store reuses one record across runs, so the release restores the method.
|
|
128
|
-
*/
|
|
129
|
-
function reportUserMessages(session, report) {
|
|
130
|
-
const record = session.sessionManager;
|
|
131
|
-
const append = record.appendMessage;
|
|
132
|
-
return Effect.acquireRelease(Effect.sync(() => {
|
|
133
|
-
record.appendMessage = (message) => {
|
|
134
|
-
const entryId = append.call(record, message);
|
|
135
|
-
// The same text and images `entries()` publishes for this entry (session-control.ts toSessionEntry).
|
|
136
|
-
if (message.role === "user") {
|
|
137
|
-
report({ entryId, text: contentText(message.content, ""), ...entryImages(entryId, message) });
|
|
138
|
-
}
|
|
139
|
-
return entryId;
|
|
140
|
-
};
|
|
141
|
-
}), () => Effect.sync(() => {
|
|
142
|
-
record.appendMessage = append;
|
|
143
|
-
}));
|
|
144
|
-
}
|
|
145
|
-
export function createPiAgentFromSession(options) {
|
|
146
|
-
const { sessionFactory, lease = inProcessLease(), observer } = options;
|
|
147
|
-
async function* turn(scope, prompt, { onCancelReady, wasCancelled }) {
|
|
148
|
-
const queue = Effect.runSync(Queue.unbounded());
|
|
149
|
-
const consumed = Deferred.makeUnsafe();
|
|
150
|
-
const bound = Deferred.makeUnsafe();
|
|
151
|
-
const abort = new AbortController();
|
|
152
|
-
onCancelReady(() => abort.abort());
|
|
153
|
-
const runId = crypto.randomUUID();
|
|
154
|
-
const project = agentEventProjection();
|
|
155
|
-
/**
|
|
156
|
-
* Each call's `tool_progress` still waiting in the queue. A newer status replaces its text instead of queuing
|
|
157
|
-
* behind it, so the queue holds at most one per running call, and a consumer that falls behind (a slow `/invoke`
|
|
158
|
-
* client) gets the latest status, not every snapshot in between: pi's bash reports every 100 ms, and a single
|
|
159
|
-
* growing line is up to 50 KB each time. The replaced event keeps its place, which moves a status earlier, never
|
|
160
|
-
* past its own call's `tool_ended`: pi takes no progress from a call once it has returned.
|
|
161
|
-
*/
|
|
162
|
-
const unreadProgress = new Map();
|
|
163
|
-
let settled = false;
|
|
164
|
-
let outcome;
|
|
165
|
-
let abortsInFlight = 0;
|
|
166
|
-
let abortSucceeded = false;
|
|
167
|
-
/**
|
|
168
|
-
* An abort is owed to every model request this invoke makes, including one not yet started. pi's `abort()` stops
|
|
169
|
-
* only an agent run or a compaction already in flight: one that lands while `prompt()` prepares (input handlers,
|
|
170
|
-
* the auth check, `before_agent_start`) finds nothing to stop, and `_runAgentPrompt` then clears pi's own flag.
|
|
171
|
-
* So the run remembers it and aborts each agent run and automatic compaction as it starts (`agent_start`,
|
|
172
|
-
* `compaction_start`: both emitted once pi's controller for it exists).
|
|
173
|
-
*/
|
|
174
|
-
let abortRequested = false;
|
|
175
|
-
const observe = (event, run) => {
|
|
176
|
-
if (!event || !observer)
|
|
177
|
-
return;
|
|
178
|
-
try {
|
|
179
|
-
observer(scope.session, event, run);
|
|
180
|
-
}
|
|
181
|
-
catch (error) {
|
|
182
|
-
log.warn(`[fastagent] session observer threw (event ${event.type}): ${String(error)}`);
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
const ready = Deferred.await(bound);
|
|
186
|
-
/**
|
|
187
|
-
* Every control command obeys one admission rule: wait for this run's binding, then refuse once it has settled.
|
|
188
|
-
* Kept in one place so a fourth command cannot arrive with a fifth spelling of it.
|
|
189
|
-
*/
|
|
190
|
-
const alreadySettled = () => new PortFailure(new Error("run already settled; the command cannot take effect"));
|
|
191
|
-
const command = (run) => Effect.runPromise(Effect.gen(function* () {
|
|
192
|
-
const session = yield* ready;
|
|
193
|
-
if (settled)
|
|
194
|
-
return yield* Effect.fail(alreadySettled());
|
|
195
|
-
return yield* run(session);
|
|
196
|
-
}));
|
|
197
|
-
// Prompt preparation stays OUTSIDE admission: pi accepts a message for a finished run without complaint
|
|
198
|
-
// (`_steeringMessages.push`), so a run that ends between the settled check and the enqueue drops the command while
|
|
199
|
-
// it reports success. Image resizing would be such a gap, hundreds of milliseconds of dynamic import and Photon
|
|
200
|
-
// work, and doing it here also keeps it overlapping session acquisition. pi has a gap of its own: it awaits the
|
|
201
|
-
// definition's `input` handlers before it queues, so a `queued` answer is checked against settlement once more.
|
|
202
|
-
// A `handled` one stands either way: the handler took the prompt whatever became of the run.
|
|
203
|
-
const enqueue = async (p, kind) => {
|
|
204
|
-
const opts = await toPiPromptOptions(p, "queued");
|
|
205
|
-
return command((session) => Effect.gen(function* () {
|
|
206
|
-
const disposition = yield* port(() => session[kind](p.text, opts?.images));
|
|
207
|
-
if (disposition === "queued" && settled) {
|
|
208
|
-
// pi has queued it, and announced it (`queue_update`), on a run that takes nothing in any more. Emptying
|
|
209
|
-
// the queue tells the observation plane so, which would otherwise report the refused prompt pending.
|
|
210
|
-
session.clearQueue();
|
|
211
|
-
return yield* Effect.fail(alreadySettled());
|
|
212
|
-
}
|
|
213
|
-
return disposition;
|
|
214
|
-
}));
|
|
215
|
-
};
|
|
216
|
-
const controls = {
|
|
217
|
-
steer: (p) => enqueue(p, "steer"),
|
|
218
|
-
followUp: (p) => enqueue(p, "followUp"),
|
|
219
|
-
abort: () => command((session) => Effect.gen(function* () {
|
|
220
|
-
abortsInFlight++;
|
|
221
|
-
abortRequested = true;
|
|
222
|
-
yield* port(() => session.abort()).pipe(Effect.tap(() => Effect.sync(() => {
|
|
223
|
-
abortSucceeded = true;
|
|
224
|
-
})), Effect.ensuring(Effect.sync(() => {
|
|
225
|
-
abortsInFlight--;
|
|
226
|
-
})));
|
|
227
|
-
})),
|
|
228
|
-
};
|
|
229
|
-
const execute = Effect.gen(function* () {
|
|
230
|
-
yield* acquireSessionLease(lease, scope.session);
|
|
231
|
-
yield* Effect.addFinalizer(() => Effect.sync(() => {
|
|
232
|
-
settled = true;
|
|
233
|
-
observe({ type: "run_settled", timestamp: Date.now(), runId, data: outcome ?? { status: "aborted" } });
|
|
234
|
-
}));
|
|
235
|
-
// Admission precedes binding so a racing control command waits on this run's readiness gate.
|
|
236
|
-
observe({ type: "run_started", timestamp: Date.now(), runId, data: {} }, controls);
|
|
237
|
-
const session = yield* acquireSession(sessionFactory, scope.session, scope.parentSession === undefined
|
|
238
|
-
? undefined
|
|
239
|
-
: {
|
|
240
|
-
parentSession: scope.parentSession,
|
|
241
|
-
...(scope.branchHints !== undefined ? { branchHints: scope.branchHints } : {}),
|
|
242
|
-
});
|
|
243
|
-
let finalAssistant;
|
|
244
|
-
let runStarted = false;
|
|
245
|
-
let extensionFailure;
|
|
246
|
-
let streamedAnswer = false;
|
|
247
|
-
let retriedAfterAnswer;
|
|
248
|
-
let eventFailure;
|
|
249
|
-
const abortWith = (operation) => {
|
|
250
|
-
void Effect.runPromise(portCleanup(operation, () => session.abort()));
|
|
251
|
-
};
|
|
252
|
-
const stop = () => abortWith("event-fault abort");
|
|
253
|
-
yield* Effect.acquireRelease(Effect.try({
|
|
254
|
-
try: () => session.subscribe((event) => {
|
|
255
|
-
if (retriedAfterAnswer !== undefined || eventFailure)
|
|
256
|
-
return;
|
|
257
|
-
try {
|
|
258
|
-
if (event.type === "agent_start")
|
|
259
|
-
runStarted = true;
|
|
260
|
-
if ((event.type === "agent_start" || event.type === "compaction_start") && abortRequested)
|
|
261
|
-
abortWith("requested abort");
|
|
262
|
-
// Compaction rewrites session history; the event's assistant message is the turn's fact.
|
|
263
|
-
if (event.type === "message_end" && event.message.role === "assistant") {
|
|
264
|
-
finalAssistant = event.message;
|
|
265
|
-
for (const diagnostic of finalAssistant.diagnostics ?? []) {
|
|
266
|
-
log.warn(`[fastagent] provider diagnostic ${diagnostic.type} (${finalAssistant.provider}/${finalAssistant.model}, session ${scope.session}, run ${runId})`);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
if (event.type === "compaction_end" && event.reason !== "manual") {
|
|
270
|
-
const status = event.aborted ? "aborted" : event.errorMessage ? "failed" : "completed";
|
|
271
|
-
const emit = event.errorMessage && !event.aborted ? log.warn : log.debug;
|
|
272
|
-
emit(`[fastagent] automatic compaction ${event.reason} (session ${scope.session}, run ${runId}): ${status}`);
|
|
273
|
-
}
|
|
274
|
-
if (event.type === "auto_retry_start" && streamedAnswer) {
|
|
275
|
-
retriedAfterAnswer = event.errorMessage;
|
|
276
|
-
// Pi installs the retry controller after emitting this event.
|
|
277
|
-
queueMicrotask(stop);
|
|
278
|
-
return;
|
|
279
|
-
}
|
|
280
|
-
const rich = toSessionEvent(event, runId);
|
|
281
|
-
observe(rich);
|
|
282
|
-
if (!rich)
|
|
283
|
-
return;
|
|
284
|
-
const projected = project(rich);
|
|
285
|
-
if (!projected)
|
|
286
|
-
return;
|
|
287
|
-
if (projected.type === "text" || projected.type === "thinking")
|
|
288
|
-
streamedAnswer = true;
|
|
289
|
-
if (projected.type === "tool_progress") {
|
|
290
|
-
const unread = unreadProgress.get(projected.id);
|
|
291
|
-
if (unread) {
|
|
292
|
-
unread.text = projected.text;
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
295
|
-
unreadProgress.set(projected.id, projected);
|
|
296
|
-
}
|
|
297
|
-
Queue.offerUnsafe(queue, projected);
|
|
298
|
-
}
|
|
299
|
-
catch (error) {
|
|
300
|
-
eventFailure = new PortFailure(error);
|
|
301
|
-
queueMicrotask(stop);
|
|
302
|
-
}
|
|
303
|
-
}),
|
|
304
|
-
catch: (error) => new PortFailure(error),
|
|
305
|
-
}), (unsubscribe) => portCleanup("unsubscribe", unsubscribe));
|
|
306
|
-
// pi swallows a failing extension command, and a turn an extension failed to start, into its error channel;
|
|
307
|
-
// both are work this run owes its caller, so the run reports them.
|
|
308
|
-
yield* Effect.acquireRelease(Effect.sync(() => session.extensionRunner.onError((error) => {
|
|
309
|
-
if (OWED_BY_THE_RUN.has(error.event))
|
|
310
|
-
extensionFailure ??= `${error.event} failed (${error.extensionPath}): ${error.error}`;
|
|
311
|
-
})), (unsubscribe) => Effect.sync(unsubscribe));
|
|
312
|
-
yield* reportUserMessages(session, (data) => observe({ type: "user_message", timestamp: Date.now(), runId, data }));
|
|
313
|
-
const extensionTurns = trackExtensionTurns(session);
|
|
314
|
-
// Completing the gate can run waiting controls synchronously; their queue events must be observed.
|
|
315
|
-
yield* Deferred.succeed(bound, session);
|
|
316
|
-
const promptOptions = yield* port(() => toPiPromptOptions(prompt, "prompt"));
|
|
317
|
-
if (eventFailure)
|
|
318
|
-
return yield* Effect.fail(eventFailure);
|
|
319
|
-
// Whether an extension could take this input instead of the model (a command, or an `input` handler): only
|
|
320
|
-
// then may a prompt settle with no model run and still have done its job.
|
|
321
|
-
const extensionMayTakeInput = session.extensionRunner.getRegisteredCommands().length > 0 || session.extensionRunner.hasHandlers("input");
|
|
322
|
-
yield* portAbort("prompt", async () => {
|
|
323
|
-
await session.prompt(prompt.text, promptOptions);
|
|
324
|
-
// An extension command returns from `prompt()` as soon as its handler does, and a turn it started may not
|
|
325
|
-
// have begun yet, so idleness alone proves nothing. This run owns those turns until they settle, and any
|
|
326
|
-
// turn they start in turn.
|
|
327
|
-
do {
|
|
328
|
-
await Promise.allSettled([...extensionTurns]);
|
|
329
|
-
await session.waitForIdle();
|
|
330
|
-
} while (extensionTurns.size > 0);
|
|
331
|
-
}, () => session.abort());
|
|
332
|
-
if (eventFailure)
|
|
333
|
-
return yield* Effect.fail(eventFailure);
|
|
334
|
-
if (extensionFailure !== undefined)
|
|
335
|
-
return { type: "failed", details: extensionFailure, retryable: false };
|
|
336
|
-
if (retriedAfterAnswer !== undefined)
|
|
337
|
-
return { type: "failed", details: retriedAfterAnswer, retryable: true };
|
|
338
|
-
if (finalAssistant)
|
|
339
|
-
return toTerminal(finalAssistant);
|
|
340
|
-
// No model run at all: an extension took the input (a command, or an `input` handler) and did its work.
|
|
341
|
-
if (!runStarted && extensionMayTakeInput)
|
|
342
|
-
return { type: "completed" };
|
|
343
|
-
return {
|
|
344
|
-
type: "failed",
|
|
345
|
-
details: "the engine settled the run without ending an assistant message",
|
|
346
|
-
retryable: false,
|
|
347
|
-
};
|
|
348
|
-
}).pipe(Effect.onError((cause) => Deferred.failCause(bound, cause)));
|
|
349
|
-
const work = Effect.runFork(Effect.scoped(Effect.gen(function* () {
|
|
350
|
-
const terminal = yield* execute.pipe(Effect.catchCause((cause) => {
|
|
351
|
-
const error = portError(cause);
|
|
352
|
-
return Effect.succeed(error instanceof SessionBusy
|
|
353
|
-
? {
|
|
354
|
-
type: "failed",
|
|
355
|
-
details: "session busy: a turn is already in flight for this session",
|
|
356
|
-
retryable: true,
|
|
357
|
-
code: SESSION_BUSY_CODE,
|
|
358
|
-
}
|
|
359
|
-
: error instanceof MissingModel
|
|
360
|
-
? { type: "failed", details: error.message, retryable: false, code: MISSING_MODEL_CODE }
|
|
361
|
-
: errorToTerminal(error));
|
|
362
|
-
}));
|
|
363
|
-
settled = true;
|
|
364
|
-
Queue.offerUnsafe(queue, terminal.type === "failed" && (abortSucceeded || abortsInFlight > 0)
|
|
365
|
-
? { ...terminal, retryable: false, code: ABORTED_CODE }
|
|
366
|
-
: terminal);
|
|
367
|
-
Queue.endUnsafe(queue);
|
|
368
|
-
// Producer completion is earlier than consumer completion.
|
|
369
|
-
yield* Deferred.await(consumed);
|
|
370
|
-
})).pipe(Effect.ensuring(Effect.sync(() => {
|
|
371
|
-
Queue.endUnsafe(queue);
|
|
372
|
-
}))), { signal: abort.signal });
|
|
373
|
-
const read = Queue.takeAll(queue).pipe(Effect.catchTag("Done", () => Effect.succeed([])));
|
|
374
|
-
try {
|
|
375
|
-
for (;;) {
|
|
376
|
-
const events = await Effect.runPromise(read);
|
|
377
|
-
if (events.length === 0)
|
|
378
|
-
return;
|
|
379
|
-
for (const event of events) {
|
|
380
|
-
if (wasCancelled())
|
|
381
|
-
return;
|
|
382
|
-
if (event.type === "failed") {
|
|
383
|
-
outcome =
|
|
384
|
-
event.code === ABORTED_CODE
|
|
385
|
-
? { status: "aborted", error: { message: event.details, retryable: false } }
|
|
386
|
-
: { status: "failed", error: { code: event.code, message: event.details, retryable: event.retryable } };
|
|
387
|
-
}
|
|
388
|
-
else if (event.type === "completed")
|
|
389
|
-
outcome = { status: "completed" };
|
|
390
|
-
// Handed over: the consumer owns it now, and the next status queues afresh.
|
|
391
|
-
if (event.type === "tool_progress")
|
|
392
|
-
unreadProgress.delete(event.id);
|
|
393
|
-
yield event;
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
finally {
|
|
398
|
-
Deferred.doneUnsafe(consumed, Effect.void);
|
|
399
|
-
await Effect.runPromise(Fiber.await(work));
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
return { invoke: (scope, prompt) => cancellableStream((hooks) => turn(scope, prompt, hooks)) };
|
|
403
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export interface LockResult<T> {
|
|
2
|
-
result: T;
|
|
3
|
-
/** New file content to persist under the lock; undefined = no write. */
|
|
4
|
-
next?: string;
|
|
5
|
-
}
|
|
6
|
-
/** Serialized cross-process read-modify-write of one file, replaced whole so its readers need no lock. */
|
|
7
|
-
export declare function withLockedFile<T>(path: string, fn: (current: string | undefined) => Promise<LockResult<T>>, options?: {
|
|
8
|
-
signal?: AbortSignal;
|
|
9
|
-
}): Promise<T>;
|