@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
package/dist/engines/pi/login.js
DELETED
|
@@ -1,331 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Signing in to a MODEL PROVIDER, for any front end: {@link login} runs one provider's flow over pi-ai's own
|
|
3
|
-
* `AuthInteraction` and persists the credential through the same {@link fastagentCredentialStore} the runtime reads
|
|
4
|
-
* (one writer, one lock/corruption semantics); {@link loginOptions} is the list a picker offers. `fastagent login` is
|
|
5
|
-
* one front end ({@link loginFlow}: terminal menus, then {@link login}); a GUI client is another.
|
|
6
|
-
*/
|
|
7
|
-
import { InMemoryCredentialStore, } from "@earendil-works/pi-ai";
|
|
8
|
-
import { dirname } from "node:path";
|
|
9
|
-
import { SettingsManager } from "@earendil-works/pi-coding-agent";
|
|
10
|
-
import { fastagentCredentialStore } from "./auth.js";
|
|
11
|
-
import { createPiModelRuntime, interactiveAuth, loginProviders, piModelsOver, probeApiKey } from "./models.js";
|
|
12
|
-
import { agentModels } from "./agent-models.js";
|
|
13
|
-
/** The user backed out of a prompt/menu, or the flow was aborted — a decision, not a failure. */
|
|
14
|
-
export class LoginCancelled extends Error {
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Every interactive sign-in of pi's built-in providers, with what `credentials` (a credentials file, or the caller's
|
|
18
|
-
* own store) already holds for each. A provider whose key can only come from its env var offers none and is left out.
|
|
19
|
-
*/
|
|
20
|
-
export function loginOptions(credentials) {
|
|
21
|
-
return loginOptionsOver(credentials);
|
|
22
|
-
}
|
|
23
|
-
/** A credentials file path names fastagent's store over it; a store is used as given. */
|
|
24
|
-
const storeOf = (credentials) => typeof credentials === "string" ? fastagentCredentialStore(credentials) : credentials;
|
|
25
|
-
/** {@link loginOptions} over pi's built-ins plus `providers` (a same id replaces one). Not public: a test seam. */
|
|
26
|
-
export async function loginOptionsOver(credentials, providers) {
|
|
27
|
-
// ONE read of the store: `list` is metadata only, and reading per provider would repeat a corrupt file's warning for
|
|
28
|
-
// every provider.
|
|
29
|
-
const held = new Map((await storeOf(credentials).list()).map((info) => [info.providerId, info.type]));
|
|
30
|
-
const offered = [];
|
|
31
|
-
for (const provider of loginProviders(providers)) {
|
|
32
|
-
const methods = ["oauth", "api_key"].filter((method) => interactiveAuth(provider, method));
|
|
33
|
-
if (methods.length === 0)
|
|
34
|
-
continue;
|
|
35
|
-
const stored = held.get(provider.id);
|
|
36
|
-
for (const method of methods) {
|
|
37
|
-
offered.push({
|
|
38
|
-
provider: provider.id,
|
|
39
|
-
method,
|
|
40
|
-
label: interactiveAuth(provider, method)?.name ?? provider.name,
|
|
41
|
-
subscription: method === "oauth" && provider.auth.oauth?.isSubscription === true,
|
|
42
|
-
...(stored ? { stored } : {}),
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return offered;
|
|
47
|
-
}
|
|
48
|
-
/** Combine present abort signals into one (no-op when none/one). */
|
|
49
|
-
function anySignal(...signals) {
|
|
50
|
-
const present = signals.filter((s) => s !== undefined);
|
|
51
|
-
return present.length === 0 ? undefined : present.length === 1 ? present[0] : AbortSignal.any(present);
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Sign in to one of pi's built-in providers and persist the credential to `authPath`, or to the caller's
|
|
55
|
-
* `credentialStore`.
|
|
56
|
-
*
|
|
57
|
-
* The store is checked FIRST (a no-op write runs the file store's refuse-corrupt and writability checks, or whatever
|
|
58
|
-
* the caller's store does on a write), so a flow never runs toward a credential that could not be saved. An entered API key is verified with one minimal request to pi's
|
|
59
|
-
* default model for the provider (its first model when pi names none), at pi's built-in endpoint, BEFORE it is
|
|
60
|
-
* written. Credentials are provider-scoped, so any of the provider's models answers the question the check asks (does
|
|
61
|
-
* the provider refuse the key, HTTP 401); a key the provider rejects is never stored, and the provider's key flow runs
|
|
62
|
-
* again (the provider and method were not the mistake). Progress and outcome go out through `interaction.notify`.
|
|
63
|
-
* A provider an agent's models.json points elsewhere is not this call's: store that key with `fastagentCredentialStore`.
|
|
64
|
-
*
|
|
65
|
-
* Aborting `interaction.signal` at any point, the verification included, rejects with {@link LoginCancelled} and
|
|
66
|
-
* writes no credential (an OAuth device ID, the installation's identity, is kept once created). Every prompt carries a signal that aborts on it, on the prompt's own signal (a callback server
|
|
67
|
-
* beating a `manual_code` prompt), and when the flow settles with a prompt still pending.
|
|
68
|
-
*/
|
|
69
|
-
export function login(request) {
|
|
70
|
-
return loginOver(request);
|
|
71
|
-
}
|
|
72
|
-
/** {@link login}, plus {@link LoginInternals}. */
|
|
73
|
-
export async function loginOver(request, internals = {}) {
|
|
74
|
-
const { providers, verifyWith, agentDir } = internals;
|
|
75
|
-
const { method, interaction } = request;
|
|
76
|
-
if (request.credentialStore === undefined && typeof request.authPath !== "string") {
|
|
77
|
-
throw new Error("login needs authPath or credentialStore: where the sign-in is written");
|
|
78
|
-
}
|
|
79
|
-
const provider = loginProviders(providers).find((p) => p.id === request.provider);
|
|
80
|
-
if (!provider)
|
|
81
|
-
throw new Error(`unknown provider "${request.provider}"`);
|
|
82
|
-
const auth = interactiveAuth(provider, method);
|
|
83
|
-
if (!auth?.login)
|
|
84
|
-
throw new Error(`provider "${provider.id}" has no interactive ${method} login`);
|
|
85
|
-
const flow = auth.login.bind(auth);
|
|
86
|
-
// The key under test lives here, not in the file, until it passes.
|
|
87
|
-
const trial = new InMemoryCredentialStore();
|
|
88
|
-
// Only a key needs the registry, and building an agent's fails on a broken models.json: an OAuth sign-in must not.
|
|
89
|
-
// For a key it is built BEFORE the flow, so that failure comes before the person types anything.
|
|
90
|
-
const models = method !== "api_key"
|
|
91
|
-
? undefined
|
|
92
|
-
: agentDir
|
|
93
|
-
? await createPiModelRuntime({
|
|
94
|
-
agentDir,
|
|
95
|
-
credentials: trial,
|
|
96
|
-
...(providers ? { providers: [...providers] } : {}),
|
|
97
|
-
})
|
|
98
|
-
: piModelsOver(trial, providers);
|
|
99
|
-
const store = agentModels(undefined, request).credentials;
|
|
100
|
-
await store.modify(provider.id, async () => undefined);
|
|
101
|
-
const signal = interaction.signal ?? new AbortController().signal;
|
|
102
|
-
const notify = (event) => interaction.notify(event);
|
|
103
|
-
let getDeviceId = request.getDeviceId;
|
|
104
|
-
if (method === "oauth" && !getDeviceId && request.authPath !== undefined) {
|
|
105
|
-
// Only the settings file beside the credentials: no project's `.pi/settings.json` has a say in this write.
|
|
106
|
-
const settings = SettingsManager.create(dirname(request.authPath), dirname(request.authPath), {
|
|
107
|
-
projectTrusted: false,
|
|
108
|
-
});
|
|
109
|
-
const deviceId = settings.getOrCreateDeviceId();
|
|
110
|
-
await settings.flush();
|
|
111
|
-
const errors = settings.drainErrors();
|
|
112
|
-
if (errors.length)
|
|
113
|
-
throw new Error(`could not persist login device ID: ${errors.map(({ error }) => error.message).join("; ")}`);
|
|
114
|
-
getDeviceId = () => deviceId;
|
|
115
|
-
}
|
|
116
|
-
for (;;) {
|
|
117
|
-
const credential = await runFlow((io) => flow(io, { getDeviceId }), interaction, signal);
|
|
118
|
-
let verified = "n/a";
|
|
119
|
-
if (models) {
|
|
120
|
-
await trial.modify(provider.id, async () => credential);
|
|
121
|
-
const verdict = await verifyApiKey(models, provider.id, verifyWith, notify, signal);
|
|
122
|
-
if (signal.aborted)
|
|
123
|
-
throw new LoginCancelled("cancelled");
|
|
124
|
-
if (verdict === "rejected")
|
|
125
|
-
continue;
|
|
126
|
-
verified = verdict;
|
|
127
|
-
}
|
|
128
|
-
await store.modify(provider.id, async () => credential);
|
|
129
|
-
return { provider: provider.id, method, verified };
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
async function runFlow(flow, interaction, signal) {
|
|
133
|
-
if (signal.aborted)
|
|
134
|
-
throw new LoginCancelled("cancelled");
|
|
135
|
-
const done = new AbortController();
|
|
136
|
-
let credential;
|
|
137
|
-
try {
|
|
138
|
-
credential = await flow({
|
|
139
|
-
signal,
|
|
140
|
-
prompt: (prompt) => interaction.prompt({ ...prompt, signal: anySignal(prompt.signal, signal, done.signal) }),
|
|
141
|
-
notify: (event) => interaction.notify(event),
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
catch (error) {
|
|
145
|
-
// Whatever the provider made of the abort (its own error, a rejected prompt), it was the caller's decision.
|
|
146
|
-
if (signal.aborted)
|
|
147
|
-
throw new LoginCancelled("cancelled");
|
|
148
|
-
throw error;
|
|
149
|
-
}
|
|
150
|
-
finally {
|
|
151
|
-
done.abort();
|
|
152
|
-
}
|
|
153
|
-
// A provider that ignored the abort and finished anyway: the caller still cancelled.
|
|
154
|
-
if (signal.aborted)
|
|
155
|
-
throw new LoginCancelled("cancelled");
|
|
156
|
-
return credential;
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* pi's default model per provider (`defaultModelPerProvider` in pi-coding-agent's model-resolver): the general-purpose
|
|
160
|
-
* model pi itself starts on, so the likeliest to answer a minimal request. COPIED, because pi does not export it;
|
|
161
|
-
* `test/login.test.ts` compares this against pi's own table, so a pi release that changes a default fails there.
|
|
162
|
-
*/
|
|
163
|
-
export const PI_DEFAULT_MODELS = {
|
|
164
|
-
"amazon-bedrock": "us.anthropic.claude-opus-4-6-v1",
|
|
165
|
-
"ant-ling": "Ring-2.6-1T",
|
|
166
|
-
anthropic: "claude-opus-4-8",
|
|
167
|
-
openai: "gpt-5.5",
|
|
168
|
-
"azure-openai-responses": "gpt-5.4",
|
|
169
|
-
"openai-codex": "gpt-6.1-sol",
|
|
170
|
-
radius: "balanced",
|
|
171
|
-
nvidia: "nvidia/nemotron-3-super-120b-a12b",
|
|
172
|
-
deepseek: "deepseek-v4-pro",
|
|
173
|
-
google: "gemini-3.1-pro-preview",
|
|
174
|
-
"google-vertex": "gemini-3.1-pro-preview",
|
|
175
|
-
"github-copilot": "gpt-5.4",
|
|
176
|
-
openrouter: "moonshotai/kimi-k2.6",
|
|
177
|
-
"vercel-ai-gateway": "zai/glm-5.1",
|
|
178
|
-
xai: "grok-4.7",
|
|
179
|
-
groq: "openai/gpt-oss-120b",
|
|
180
|
-
cerebras: "gpt-oss-120b",
|
|
181
|
-
zai: "glm-5.3",
|
|
182
|
-
"zai-coding-cn": "glm-5.3",
|
|
183
|
-
mistral: "devstral-medium-latest",
|
|
184
|
-
minimax: "MiniMax-M2.7",
|
|
185
|
-
"minimax-cn": "MiniMax-M2.7",
|
|
186
|
-
moonshotai: "kimi-k2.6",
|
|
187
|
-
"moonshotai-cn": "kimi-k2.6",
|
|
188
|
-
huggingface: "moonshotai/Kimi-K2.6",
|
|
189
|
-
fireworks: "accounts/fireworks/models/kimi-k3",
|
|
190
|
-
together: "moonshotai/Kimi-K3",
|
|
191
|
-
baseten: "zai-org/GLM-5.2",
|
|
192
|
-
opencode: "kimi-k2.6",
|
|
193
|
-
"opencode-go": "kimi-k3",
|
|
194
|
-
"kimi-coding": "kimi-for-coding",
|
|
195
|
-
meta: "muse-spark-1.3",
|
|
196
|
-
"cloudflare-workers-ai": "@cf/moonshotai/kimi-k2.6",
|
|
197
|
-
"cloudflare-ai-gateway": "workers-ai/@cf/moonshotai/kimi-k2.6",
|
|
198
|
-
"qwen-token-plan": "qwen3.7-max",
|
|
199
|
-
"qwen-token-plan-cn": "qwen3.7-max",
|
|
200
|
-
"qwen-token-plan-individual": "qwen3.8-max",
|
|
201
|
-
xiaomi: "mimo-v2.5-pro",
|
|
202
|
-
"xiaomi-token-plan-cn": "mimo-v2.5-pro",
|
|
203
|
-
"xiaomi-token-plan-ams": "mimo-v2.5-pro",
|
|
204
|
-
"xiaomi-token-plan-sgp": "mimo-v2.5-pro",
|
|
205
|
-
};
|
|
206
|
-
/** One minimal request with the key under test. */
|
|
207
|
-
async function verifyApiKey(models, providerId, verifyWith, notify, signal) {
|
|
208
|
-
const chosen = verifyWith?.startsWith(`${providerId}/`)
|
|
209
|
-
? models.getModel(providerId, verifyWith.slice(providerId.length + 1))
|
|
210
|
-
: undefined;
|
|
211
|
-
const piDefault = PI_DEFAULT_MODELS[providerId];
|
|
212
|
-
// The provider's first model is the last resort only: catalogs are alphabetical, and a first model can be a
|
|
213
|
-
// special-purpose one that rejects a minimal request (which still answers the 401 question).
|
|
214
|
-
const model = chosen ??
|
|
215
|
-
(piDefault ? models.getModel(providerId, piDefault) : undefined) ??
|
|
216
|
-
models.getProvider(providerId)?.getModels()[0];
|
|
217
|
-
if (!model) {
|
|
218
|
-
notify({
|
|
219
|
-
type: "info",
|
|
220
|
-
message: `cannot verify the key: provider "${providerId}" lists no models — kept as entered`,
|
|
221
|
-
});
|
|
222
|
-
return "unknown";
|
|
223
|
-
}
|
|
224
|
-
const label = `${model.provider}/${model.id}`;
|
|
225
|
-
notify({ type: "progress", message: `verifying the key with ${label}…` });
|
|
226
|
-
const probe = await probeApiKey(models, model, signal);
|
|
227
|
-
if (signal.aborted)
|
|
228
|
-
return "unknown"; // the caller reports the cancel, not a verdict on the key
|
|
229
|
-
if (probe.state === "ok") {
|
|
230
|
-
notify({ type: "info", message: `key verified — ${label} responded` });
|
|
231
|
-
}
|
|
232
|
-
else if (probe.state === "rejected") {
|
|
233
|
-
notify({
|
|
234
|
-
type: "info",
|
|
235
|
-
message: `${providerId} rejected the API key (HTTP 401): ${probe.message} — enter it again (or cancel)`,
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
else {
|
|
239
|
-
notify({
|
|
240
|
-
type: "info",
|
|
241
|
-
message: `could not verify the key with ${label}: ${probe.message} — kept; invokes surface the provider's error`,
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
return probe.state;
|
|
245
|
-
}
|
|
246
|
-
/** {@link LoginIO} as pi-ai's `AuthInteraction`: what {@link login} drives for the terminal. */
|
|
247
|
-
function terminalInteraction(io, signal) {
|
|
248
|
-
return {
|
|
249
|
-
...(signal ? { signal } : {}),
|
|
250
|
-
prompt: async (p) => {
|
|
251
|
-
// A select is UNCANCELLABLE here: `LoginIO.select` takes no signal.
|
|
252
|
-
const v = p.type === "select"
|
|
253
|
-
? await io.select(p.message, p.options.map((o) => ({
|
|
254
|
-
value: o.id,
|
|
255
|
-
label: o.label,
|
|
256
|
-
...(o.description ? { hint: o.description } : {}),
|
|
257
|
-
})))
|
|
258
|
-
: await io.prompt(p.message, { hidden: p.type === "secret", ...(p.signal ? { signal: p.signal } : {}) });
|
|
259
|
-
if (v === undefined)
|
|
260
|
-
throw new LoginCancelled("cancelled");
|
|
261
|
-
return v;
|
|
262
|
-
},
|
|
263
|
-
notify: (e) => {
|
|
264
|
-
if (e.type === "auth_url") {
|
|
265
|
-
io.note(`Open this URL to authorize:\n ${e.url}`);
|
|
266
|
-
if (e.instructions)
|
|
267
|
-
io.note(e.instructions);
|
|
268
|
-
io.openUrl(e.url);
|
|
269
|
-
}
|
|
270
|
-
else if (e.type === "device_code") {
|
|
271
|
-
io.note(`Go to ${e.verificationUri} and enter the code: ${e.userCode}`);
|
|
272
|
-
io.openUrl(e.verificationUri);
|
|
273
|
-
}
|
|
274
|
-
else {
|
|
275
|
-
io.note(e.message);
|
|
276
|
-
}
|
|
277
|
-
},
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
async function selectMethod(io) {
|
|
281
|
-
const v = await io.select("Authentication method", [
|
|
282
|
-
{ value: "oauth", label: "Use a subscription (OAuth)" },
|
|
283
|
-
{ value: "api_key", label: "Use an API key" },
|
|
284
|
-
]);
|
|
285
|
-
if (v !== "oauth" && v !== "api_key")
|
|
286
|
-
throw new LoginCancelled("no authentication method selected");
|
|
287
|
-
return v;
|
|
288
|
-
}
|
|
289
|
-
/**
|
|
290
|
-
* `fastagent login`: ask only what was not given (method, then provider, from {@link loginOptions} with each one's
|
|
291
|
-
* stored credential), then {@link login}.
|
|
292
|
-
*/
|
|
293
|
-
export async function loginFlow(io, options) {
|
|
294
|
-
const offered = await loginOptionsOver(options.authPath, options.providers);
|
|
295
|
-
let provider = options.provider;
|
|
296
|
-
let method = options.method;
|
|
297
|
-
if (provider) {
|
|
298
|
-
const methods = offered.filter((o) => o.provider === provider).map((o) => o.method);
|
|
299
|
-
if (methods.length === 0) {
|
|
300
|
-
const known = loginProviders(options.providers).some((p) => p.id === provider);
|
|
301
|
-
throw new Error(known
|
|
302
|
-
? `provider "${provider}" has no interactive login — set its API key via the provider's env var`
|
|
303
|
-
: `unknown provider "${provider}"`);
|
|
304
|
-
}
|
|
305
|
-
method ??= methods.length > 1 ? await selectMethod(io) : methods[0];
|
|
306
|
-
}
|
|
307
|
-
else {
|
|
308
|
-
const chosenMethod = method ?? (await selectMethod(io));
|
|
309
|
-
method = chosenMethod;
|
|
310
|
-
const candidates = offered.filter((o) => o.method === chosenMethod);
|
|
311
|
-
if (candidates.length === 0)
|
|
312
|
-
throw new Error(`no provider supports ${chosenMethod} login`);
|
|
313
|
-
provider = await io.select("Select a provider", candidates.map((o) => ({
|
|
314
|
-
value: o.provider,
|
|
315
|
-
label: o.label,
|
|
316
|
-
...(o.stored ? { hint: `configured (${o.stored})` } : {}),
|
|
317
|
-
})));
|
|
318
|
-
if (!candidates.some((o) => o.provider === provider))
|
|
319
|
-
throw new LoginCancelled("no provider selected");
|
|
320
|
-
}
|
|
321
|
-
return loginOver({
|
|
322
|
-
provider: provider,
|
|
323
|
-
method: method,
|
|
324
|
-
authPath: options.authPath,
|
|
325
|
-
interaction: terminalInteraction(io, options.signal),
|
|
326
|
-
}, {
|
|
327
|
-
...(options.providers ? { providers: options.providers } : {}),
|
|
328
|
-
...(options.verifyWith ? { verifyWith: options.verifyWith } : {}),
|
|
329
|
-
...(options.agentDir ? { agentDir: options.agentDir } : {}),
|
|
330
|
-
});
|
|
331
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* THE MACHINE an agent runs on, as fastagent inherits it: the skills and prompt templates this box provides — found
|
|
3
|
-
* by pi's own Agent Skills discovery, installed pi packages included — and pi's engine settings.
|
|
4
|
-
*
|
|
5
|
-
* An agent inherits its machine the way it already inherits the `PATH`: `bash` runs whatever is installed, and a
|
|
6
|
-
* skill in `~/.pi/agent/skills` is available the same way. Deploying ships the project scope — the workspace — and
|
|
7
|
-
* nothing here is compared against a deployment, the same way nobody is told their local `ffmpeg` is not in the image.
|
|
8
|
-
*
|
|
9
|
-
* READ ONCE per process, like the environment it is. The definition is what stays live (`dev` re-reads it per turn,
|
|
10
|
-
* because it is what an author edits); a skill installed after boot arrives on the next start.
|
|
11
|
-
*/
|
|
12
|
-
import { DefaultResourceLoader, SettingsManager } from "@earendil-works/pi-coding-agent";
|
|
13
|
-
/** pi's own shapes, taken from its loader rather than re-declared. */
|
|
14
|
-
export type MachineSkill = ReturnType<DefaultResourceLoader["getSkills"]>["skills"][number];
|
|
15
|
-
export type MachinePrompt = ReturnType<DefaultResourceLoader["getPrompts"]>["prompts"][number];
|
|
16
|
-
/** The Pi built-in extensions a definition loads, each unless the machine's settings disable it. */
|
|
17
|
-
export declare const BUILTIN_EXTENSIONS: readonly ["codemode", "tool-search"];
|
|
18
|
-
/**
|
|
19
|
-
* The way in for an authored tool the model is not given up front, by its exposure: the built-in extension that
|
|
20
|
-
* provides it and the tool that extension registers. A `codemode` tool is called from codemode scripts, a `deferred`
|
|
21
|
-
* one is loaded by tool_search — the rule Pi's MCP extension applies to its own tools (`ensureDiscoveryActive`).
|
|
22
|
-
* Without that extension the tool has no way in at all.
|
|
23
|
-
*/
|
|
24
|
-
export declare const DISCOVERY: {
|
|
25
|
-
readonly codemode: {
|
|
26
|
-
readonly extension: "codemode";
|
|
27
|
-
readonly tool: "codemode";
|
|
28
|
-
};
|
|
29
|
-
readonly deferred: {
|
|
30
|
-
readonly extension: "tool-search";
|
|
31
|
-
readonly tool: "tool_search";
|
|
32
|
-
};
|
|
33
|
-
};
|
|
34
|
-
/** What this box lends an agent. */
|
|
35
|
-
export interface Machine {
|
|
36
|
-
skills: MachineSkill[];
|
|
37
|
-
prompts: MachinePrompt[];
|
|
38
|
-
/**
|
|
39
|
-
* The {@link BUILTIN_EXTENSIONS} left enabled, by Pi's own rule: `"extensions": ["-builtin:codemode"]` in the user
|
|
40
|
-
* settings disables one, and the workspace's `.pi/settings.json` overrides that either way.
|
|
41
|
-
*/
|
|
42
|
-
builtinExtensions: string[];
|
|
43
|
-
/** pi's engine settings (retry, compaction, cache warming, …) as read at boot — a fresh manager per caller. */
|
|
44
|
-
settingsManager(): SettingsManager;
|
|
45
|
-
}
|
|
46
|
-
/** This process's one read of the machine, shared by the run plane and `commands()` so the two cannot disagree. */
|
|
47
|
-
export declare function readMachine(workspace: string): Promise<Machine>;
|
|
48
|
-
/** The definition's names win: vendoring a skill into `skills/` is how an author overrides the machine's. */
|
|
49
|
-
export declare function withMachine<Own extends {
|
|
50
|
-
name: string;
|
|
51
|
-
}, Lent extends {
|
|
52
|
-
name: string;
|
|
53
|
-
}>(own: readonly Own[], lent: readonly Lent[]): (Own | Lent)[];
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* THE MACHINE an agent runs on, as fastagent inherits it: the skills and prompt templates this box provides — found
|
|
3
|
-
* by pi's own Agent Skills discovery, installed pi packages included — and pi's engine settings.
|
|
4
|
-
*
|
|
5
|
-
* An agent inherits its machine the way it already inherits the `PATH`: `bash` runs whatever is installed, and a
|
|
6
|
-
* skill in `~/.pi/agent/skills` is available the same way. Deploying ships the project scope — the workspace — and
|
|
7
|
-
* nothing here is compared against a deployment, the same way nobody is told their local `ffmpeg` is not in the image.
|
|
8
|
-
*
|
|
9
|
-
* READ ONCE per process, like the environment it is. The definition is what stays live (`dev` re-reads it per turn,
|
|
10
|
-
* because it is what an author edits); a skill installed after boot arrives on the next start.
|
|
11
|
-
*/
|
|
12
|
-
import { DefaultPackageManager, DefaultResourceLoader, SettingsManager, getAgentDir, } from "@earendil-works/pi-coding-agent";
|
|
13
|
-
import { log } from "../../log.js";
|
|
14
|
-
/** The Pi built-in extensions a definition loads, each unless the machine's settings disable it. */
|
|
15
|
-
// Not `mcp`: its server connections live as long as a session, and a served session lives one turn, so every turn
|
|
16
|
-
// would start every configured server.
|
|
17
|
-
export const BUILTIN_EXTENSIONS = ["codemode", "tool-search"];
|
|
18
|
-
/**
|
|
19
|
-
* The way in for an authored tool the model is not given up front, by its exposure: the built-in extension that
|
|
20
|
-
* provides it and the tool that extension registers. A `codemode` tool is called from codemode scripts, a `deferred`
|
|
21
|
-
* one is loaded by tool_search — the rule Pi's MCP extension applies to its own tools (`ensureDiscoveryActive`).
|
|
22
|
-
* Without that extension the tool has no way in at all.
|
|
23
|
-
*/
|
|
24
|
-
export const DISCOVERY = {
|
|
25
|
-
codemode: { extension: "codemode", tool: "codemode" },
|
|
26
|
-
deferred: { extension: "tool-search", tool: "tool_search" },
|
|
27
|
-
};
|
|
28
|
-
/** Keyed by the two places it reads: the workspace (project scope) and pi's own directory (user scope). */
|
|
29
|
-
const reads = new Map();
|
|
30
|
-
/** This process's one read of the machine, shared by the run plane and `commands()` so the two cannot disagree. */
|
|
31
|
-
export function readMachine(workspace) {
|
|
32
|
-
// pi's own answer for where its user-level resources live — asked, not spelled, since `PI_CODING_AGENT_DIR` moves it.
|
|
33
|
-
const agentDir = getAgentDir();
|
|
34
|
-
const key = `${workspace}\u0000${agentDir}`;
|
|
35
|
-
const cached = reads.get(key);
|
|
36
|
-
if (cached)
|
|
37
|
-
return cached;
|
|
38
|
-
const reading = read(workspace, agentDir);
|
|
39
|
-
reads.set(key, reading);
|
|
40
|
-
return reading;
|
|
41
|
-
}
|
|
42
|
-
async function read(workspace, agentDir) {
|
|
43
|
-
const files = SettingsManager.create(workspace, agentDir);
|
|
44
|
-
// pi reads an unparseable or locked settings file as `{}` and keeps the error for whoever asks. Nobody did, so a
|
|
45
|
-
// trailing comma in `~/.pi/agent/settings.json` — or pi's own TUI holding the lock at that moment — left this whole
|
|
46
|
-
// process on pi's defaults, silently: the read happens once.
|
|
47
|
-
for (const { scope, path, error } of files.drainErrors()) {
|
|
48
|
-
log.warn(`[fastagent] pi ${scope} settings${path ? ` (${path})` : ""} could not be read, so pi's defaults apply: ${error.message}`);
|
|
49
|
-
}
|
|
50
|
-
// INSTALLED PACKAGES, NEVER AN INSTALL. pi's loader resolves `packages` itself and installs a missing one
|
|
51
|
-
// (`npm install`, `git clone`), throwing out of `reload()` when that fails — measured. So fastagent resolves them
|
|
52
|
-
// here, telling pi to skip what is absent, and hands the loader a packageless copy of the settings so its own
|
|
53
|
-
// resolve has nothing to do.
|
|
54
|
-
const manager = new DefaultPackageManager({
|
|
55
|
-
cwd: workspace,
|
|
56
|
-
agentDir,
|
|
57
|
-
settingsManager: files,
|
|
58
|
-
builtinExtensions: [...BUILTIN_EXTENSIONS],
|
|
59
|
-
});
|
|
60
|
-
const packages = await manager.resolve(async () => "skip");
|
|
61
|
-
// A package skipped is said, once: its skills would otherwise just not be there. Asked of the configured list, not
|
|
62
|
-
// of `onMissing` — pi never calls that under `PI_OFFLINE`, so the warning would vanish exactly when offline.
|
|
63
|
-
for (const { source } of manager.listConfiguredPackages().filter((configured) => !configured.installedPath)) {
|
|
64
|
-
log.warn(`[fastagent] pi package ${source} is not installed, so its skills and prompts are not loaded`);
|
|
65
|
-
}
|
|
66
|
-
const settings = {
|
|
67
|
-
global: withoutPackages(files.getGlobalSettings()),
|
|
68
|
-
project: withoutPackages(files.getProjectSettings()),
|
|
69
|
-
};
|
|
70
|
-
const loader = new DefaultResourceLoader({
|
|
71
|
-
cwd: workspace,
|
|
72
|
-
agentDir,
|
|
73
|
-
settingsManager: scopedSettings(settings),
|
|
74
|
-
additionalSkillPaths: fromPackages(packages.skills),
|
|
75
|
-
additionalPromptTemplatePaths: fromPackages(packages.prompts),
|
|
76
|
-
// The machine's extensions are its owner's setup, not this agent's (agent-session-factory.ts loads only the
|
|
77
|
-
// definition's own); context files are fastagent's own (segment ②).
|
|
78
|
-
noExtensions: true,
|
|
79
|
-
noContextFiles: true,
|
|
80
|
-
});
|
|
81
|
-
await loader.reload();
|
|
82
|
-
const { skills, diagnostics: skillDiagnostics } = loader.getSkills();
|
|
83
|
-
const { prompts, diagnostics: promptDiagnostics } = loader.getPrompts();
|
|
84
|
-
// Said once — this is the process's only read. A `SKILL.md` with no description, or a prompt template whose
|
|
85
|
-
// frontmatter does not parse, is otherwise simply absent.
|
|
86
|
-
for (const [kind, diagnostics] of [
|
|
87
|
-
["skill", skillDiagnostics],
|
|
88
|
-
["prompt template", promptDiagnostics],
|
|
89
|
-
]) {
|
|
90
|
-
for (const diagnostic of diagnostics) {
|
|
91
|
-
log.warn(`[fastagent] ${kind} ${diagnostic.type}: ${diagnostic.message}${diagnostic.path ? ` (${diagnostic.path})` : ""}`);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
// A `/` in a skill's name names the context it comes from (definition.ts), and pi only warns about one. The
|
|
95
|
-
// machine's own skill spelled that way is left out rather than let collide with a context's.
|
|
96
|
-
const lent = skills.filter((skill) => {
|
|
97
|
-
if (!skill.name.includes("/"))
|
|
98
|
-
return true;
|
|
99
|
-
log.warn(`[fastagent] machine skill "${skill.name}" (${skill.filePath}) is not loaded: a skill's name may not contain "/", ` +
|
|
100
|
-
`which names the context a skill comes from`);
|
|
101
|
-
return false;
|
|
102
|
-
});
|
|
103
|
-
const builtinExtensions = packages.extensions
|
|
104
|
-
.filter((resource) => resource.enabled && resource.metadata.source === "builtin")
|
|
105
|
-
.map((resource) => resource.path.slice("builtin:".length));
|
|
106
|
-
return { skills: lent, prompts, builtinExtensions, settingsManager: () => scopedSettings(settings) };
|
|
107
|
-
}
|
|
108
|
-
/** A package's enabled resources; the loader discovers the top-level ones itself. */
|
|
109
|
-
function fromPackages(resources) {
|
|
110
|
-
return resources.filter((r) => r.enabled && r.metadata.origin === "package").map((r) => r.path);
|
|
111
|
-
}
|
|
112
|
-
function withoutPackages({ packages: _, ...rest }) {
|
|
113
|
-
return rest;
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* A SettingsManager over the boot snapshot. TWO scopes, not `SettingsManager.inMemory`'s one: pi deep-merges the
|
|
117
|
-
* project file over the global one (a project `retry.enabled` keeps the global `retry.maxRetries`), and flattening
|
|
118
|
-
* them first would change that. A write stays in memory — a served turn never edits the operator's files.
|
|
119
|
-
*/
|
|
120
|
-
function scopedSettings(snapshot) {
|
|
121
|
-
const stored = {
|
|
122
|
-
global: JSON.stringify(snapshot.global),
|
|
123
|
-
project: JSON.stringify(snapshot.project),
|
|
124
|
-
};
|
|
125
|
-
return SettingsManager.fromStorage({
|
|
126
|
-
withLock(scope, fn) {
|
|
127
|
-
const next = fn(stored[scope]);
|
|
128
|
-
if (next !== undefined)
|
|
129
|
-
stored[scope] = next;
|
|
130
|
-
},
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
/** The definition's names win: vendoring a skill into `skills/` is how an author overrides the machine's. */
|
|
134
|
-
export function withMachine(own, lent) {
|
|
135
|
-
const names = new Set(own.map((item) => item.name));
|
|
136
|
-
return [...own, ...lent.filter((item) => !names.has(item.name))];
|
|
137
|
-
}
|