lastlight 0.15.0 → 0.16.1
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 +71 -692
- package/dist/cli-config.js.map +1 -0
- package/dist/cli-format.js.map +1 -0
- package/dist/{cli/cli-server.d.ts → cli-server.d.ts} +26 -1
- package/dist/{cli/cli-server.js → cli-server.js} +40 -5
- package/dist/cli-server.js.map +1 -0
- package/dist/cli-timeline.js.map +1 -0
- package/dist/{cli/cli.js → cli.js} +4 -3
- package/dist/cli.js.map +1 -0
- package/dist/{cli/fork-cli.d.ts → fork-cli.d.ts} +3 -3
- package/dist/{cli/fork-cli.js → fork-cli.js} +28 -27
- package/dist/fork-cli.js.map +1 -0
- package/dist/{cli/oauth-cli.js → oauth-cli.js} +1 -1
- package/dist/oauth-cli.js.map +1 -0
- package/dist/{cli/setup.js → setup.js} +10 -4
- package/dist/setup.js.map +1 -0
- package/dist/{cli/skills-install.d.ts → skills-install.d.ts} +6 -0
- package/dist/{cli/skills-install.js → skills-install.js} +6 -2
- package/dist/skills-install.js.map +1 -0
- package/package.json +20 -65
- package/plugins/lastlight/.claude-plugin/plugin.json +1 -1
- package/agent-context/rules.md +0 -80
- package/agent-context/security.md +0 -69
- package/agent-context/soul.md +0 -21
- package/config/default.yaml +0 -119
- package/deploy/.env.production.example +0 -100
- package/deploy/entrypoint.sh +0 -82
- package/deploy/native/README.md +0 -160
- package/deploy/native/install.sh +0 -110
- package/deploy/native/lastlight.env.example +0 -95
- package/deploy/native/lastlight.service +0 -50
- package/deploy/sandbox-entrypoint.sh +0 -93
- package/dist/admin/auth.d.ts +0 -51
- package/dist/admin/auth.js +0 -121
- package/dist/admin/auth.js.map +0 -1
- package/dist/admin/chat-session-reader.d.ts +0 -39
- package/dist/admin/chat-session-reader.js +0 -84
- package/dist/admin/chat-session-reader.js.map +0 -1
- package/dist/admin/docker.d.ts +0 -61
- package/dist/admin/docker.js +0 -187
- package/dist/admin/docker.js.map +0 -1
- package/dist/admin/index.d.ts +0 -9
- package/dist/admin/index.js +0 -59
- package/dist/admin/index.js.map +0 -1
- package/dist/admin/routes.d.ts +0 -81
- package/dist/admin/routes.js +0 -1381
- package/dist/admin/routes.js.map +0 -1
- package/dist/admin/sessions.d.ts +0 -89
- package/dist/admin/sessions.js +0 -204
- package/dist/admin/sessions.js.map +0 -1
- package/dist/admin/tail.d.ts +0 -12
- package/dist/admin/tail.js +0 -145
- package/dist/admin/tail.js.map +0 -1
- package/dist/admin/version.d.ts +0 -22
- package/dist/admin/version.js +0 -92
- package/dist/admin/version.js.map +0 -1
- package/dist/cli/cli-config.js.map +0 -1
- package/dist/cli/cli-format.js.map +0 -1
- package/dist/cli/cli-server.js.map +0 -1
- package/dist/cli/cli-timeline.js.map +0 -1
- package/dist/cli/cli.js.map +0 -1
- package/dist/cli/fork-cli.js.map +0 -1
- package/dist/cli/oauth-cli.js.map +0 -1
- package/dist/cli/setup.js.map +0 -1
- package/dist/cli/skills-install.js.map +0 -1
- package/dist/config/config-resolve.d.ts +0 -28
- package/dist/config/config-resolve.js +0 -47
- package/dist/config/config-resolve.js.map +0 -1
- package/dist/config/config.d.ts +0 -157
- package/dist/config/config.js +0 -581
- package/dist/config/config.js.map +0 -1
- package/dist/config/core-pin.d.ts +0 -16
- package/dist/config/core-pin.js +0 -85
- package/dist/config/core-pin.js.map +0 -1
- package/dist/config/overlay-assets.d.ts +0 -20
- package/dist/config/overlay-assets.js +0 -114
- package/dist/config/overlay-assets.js.map +0 -1
- package/dist/config/overlay-bootstrap.d.ts +0 -44
- package/dist/config/overlay-bootstrap.js +0 -304
- package/dist/config/overlay-bootstrap.js.map +0 -1
- package/dist/connectors/github-webhook.d.ts +0 -45
- package/dist/connectors/github-webhook.js +0 -321
- package/dist/connectors/github-webhook.js.map +0 -1
- package/dist/connectors/index.d.ts +0 -18
- package/dist/connectors/index.js +0 -41
- package/dist/connectors/index.js.map +0 -1
- package/dist/connectors/messaging/base.d.ts +0 -42
- package/dist/connectors/messaging/base.js +0 -139
- package/dist/connectors/messaging/base.js.map +0 -1
- package/dist/connectors/messaging/delivery.d.ts +0 -14
- package/dist/connectors/messaging/delivery.js +0 -38
- package/dist/connectors/messaging/delivery.js.map +0 -1
- package/dist/connectors/messaging/index.d.ts +0 -4
- package/dist/connectors/messaging/index.js +0 -4
- package/dist/connectors/messaging/index.js.map +0 -1
- package/dist/connectors/messaging/session-manager.d.ts +0 -53
- package/dist/connectors/messaging/session-manager.js +0 -255
- package/dist/connectors/messaging/session-manager.js.map +0 -1
- package/dist/connectors/messaging/types.d.ts +0 -58
- package/dist/connectors/messaging/types.js +0 -7
- package/dist/connectors/messaging/types.js.map +0 -1
- package/dist/connectors/slack/connector.d.ts +0 -100
- package/dist/connectors/slack/connector.js +0 -341
- package/dist/connectors/slack/connector.js.map +0 -1
- package/dist/connectors/slack/index.d.ts +0 -2
- package/dist/connectors/slack/index.js +0 -3
- package/dist/connectors/slack/index.js.map +0 -1
- package/dist/connectors/slack/mrkdwn.d.ts +0 -8
- package/dist/connectors/slack/mrkdwn.js +0 -123
- package/dist/connectors/slack/mrkdwn.js.map +0 -1
- package/dist/connectors/types.d.ts +0 -61
- package/dist/connectors/types.js +0 -2
- package/dist/connectors/types.js.map +0 -1
- package/dist/cron/fanout.d.ts +0 -33
- package/dist/cron/fanout.js +0 -55
- package/dist/cron/fanout.js.map +0 -1
- package/dist/cron/jobs.d.ts +0 -18
- package/dist/cron/jobs.js +0 -37
- package/dist/cron/jobs.js.map +0 -1
- package/dist/cron/scheduler.d.ts +0 -45
- package/dist/cron/scheduler.js +0 -105
- package/dist/cron/scheduler.js.map +0 -1
- package/dist/engine/agent-executor.d.ts +0 -34
- package/dist/engine/agent-executor.js +0 -246
- package/dist/engine/agent-executor.js.map +0 -1
- package/dist/engine/chat/chat-runner.d.ts +0 -132
- package/dist/engine/chat/chat-runner.js +0 -424
- package/dist/engine/chat/chat-runner.js.map +0 -1
- package/dist/engine/chat/chat-skills.d.ts +0 -45
- package/dist/engine/chat/chat-skills.js +0 -184
- package/dist/engine/chat/chat-skills.js.map +0 -1
- package/dist/engine/chat/chat.d.ts +0 -54
- package/dist/engine/chat/chat.js +0 -316
- package/dist/engine/chat/chat.js.map +0 -1
- package/dist/engine/chat/message-batcher.d.ts +0 -32
- package/dist/engine/chat/message-batcher.js +0 -109
- package/dist/engine/chat/message-batcher.js.map +0 -1
- package/dist/engine/dispatcher.d.ts +0 -73
- package/dist/engine/dispatcher.js +0 -663
- package/dist/engine/dispatcher.js.map +0 -1
- package/dist/engine/event-shim.d.ts +0 -117
- package/dist/engine/event-shim.js +0 -435
- package/dist/engine/event-shim.js.map +0 -1
- package/dist/engine/executors/orchestrator.d.ts +0 -81
- package/dist/engine/executors/orchestrator.js +0 -365
- package/dist/engine/executors/orchestrator.js.map +0 -1
- package/dist/engine/executors/shared.d.ts +0 -189
- package/dist/engine/executors/shared.js +0 -616
- package/dist/engine/executors/shared.js.map +0 -1
- package/dist/engine/github/git-auth.d.ts +0 -62
- package/dist/engine/github/git-auth.js +0 -161
- package/dist/engine/github/git-auth.js.map +0 -1
- package/dist/engine/github/github-app-client.d.ts +0 -23
- package/dist/engine/github/github-app-client.js +0 -33
- package/dist/engine/github/github-app-client.js.map +0 -1
- package/dist/engine/github/github-tools.d.ts +0 -18
- package/dist/engine/github/github-tools.js +0 -263
- package/dist/engine/github/github-tools.js.map +0 -1
- package/dist/engine/github/github.d.ts +0 -1193
- package/dist/engine/github/github.js +0 -357
- package/dist/engine/github/github.js.map +0 -1
- package/dist/engine/github/profiles.d.ts +0 -279
- package/dist/engine/github/profiles.js +0 -42
- package/dist/engine/github/profiles.js.map +0 -1
- package/dist/engine/github/review-poster.d.ts +0 -98
- package/dist/engine/github/review-poster.js +0 -177
- package/dist/engine/github/review-poster.js.map +0 -1
- package/dist/engine/llm.d.ts +0 -79
- package/dist/engine/llm.js +0 -269
- package/dist/engine/llm.js.map +0 -1
- package/dist/engine/oauth.d.ts +0 -43
- package/dist/engine/oauth.js +0 -103
- package/dist/engine/oauth.js.map +0 -1
- package/dist/engine/router.d.ts +0 -29
- package/dist/engine/router.js +0 -680
- package/dist/engine/router.js.map +0 -1
- package/dist/engine/screen/classifier.d.ts +0 -93
- package/dist/engine/screen/classifier.js +0 -215
- package/dist/engine/screen/classifier.js.map +0 -1
- package/dist/engine/screen/screen.d.ts +0 -41
- package/dist/engine/screen/screen.js +0 -93
- package/dist/engine/screen/screen.js.map +0 -1
- package/dist/evals-api.d.ts +0 -24
- package/dist/evals-api.js +0 -22
- package/dist/evals-api.js.map +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -923
- package/dist/index.js.map +0 -1
- package/dist/managed-repos.d.ts +0 -30
- package/dist/managed-repos.js +0 -72
- package/dist/managed-repos.js.map +0 -1
- package/dist/notify/index.d.ts +0 -15
- package/dist/notify/index.js +0 -6
- package/dist/notify/index.js.map +0 -1
- package/dist/notify/model.d.ts +0 -57
- package/dist/notify/model.js +0 -89
- package/dist/notify/model.js.map +0 -1
- package/dist/notify/notifier.d.ts +0 -17
- package/dist/notify/notifier.js +0 -87
- package/dist/notify/notifier.js.map +0 -1
- package/dist/notify/render.d.ts +0 -21
- package/dist/notify/render.js +0 -59
- package/dist/notify/render.js.map +0 -1
- package/dist/notify/transports/github.d.ts +0 -26
- package/dist/notify/transports/github.js +0 -26
- package/dist/notify/transports/github.js.map +0 -1
- package/dist/notify/transports/slack.d.ts +0 -26
- package/dist/notify/transports/slack.js +0 -28
- package/dist/notify/transports/slack.js.map +0 -1
- package/dist/notify/types.d.ts +0 -95
- package/dist/notify/types.js +0 -16
- package/dist/notify/types.js.map +0 -1
- package/dist/providers.d.ts +0 -125
- package/dist/providers.js +0 -279
- package/dist/providers.js.map +0 -1
- package/dist/sandbox/docker.d.ts +0 -180
- package/dist/sandbox/docker.js +0 -517
- package/dist/sandbox/docker.js.map +0 -1
- package/dist/sandbox/egress-allowlist.d.ts +0 -74
- package/dist/sandbox/egress-allowlist.js +0 -164
- package/dist/sandbox/egress-allowlist.js.map +0 -1
- package/dist/sandbox/egress-firewall-config.d.ts +0 -127
- package/dist/sandbox/egress-firewall-config.js +0 -434
- package/dist/sandbox/egress-firewall-config.js.map +0 -1
- package/dist/sandbox/images.d.ts +0 -23
- package/dist/sandbox/images.js +0 -55
- package/dist/sandbox/images.js.map +0 -1
- package/dist/sandbox/index.d.ts +0 -112
- package/dist/sandbox/index.js +0 -332
- package/dist/sandbox/index.js.map +0 -1
- package/dist/sandbox/sandbox.d.ts +0 -214
- package/dist/sandbox/sandbox.js +0 -453
- package/dist/sandbox/sandbox.js.map +0 -1
- package/dist/sandbox/smol.d.ts +0 -162
- package/dist/sandbox/smol.js +0 -485
- package/dist/sandbox/smol.js.map +0 -1
- package/dist/session-log.d.ts +0 -63
- package/dist/session-log.js +0 -290
- package/dist/session-log.js.map +0 -1
- package/dist/state/approval-store.d.ts +0 -88
- package/dist/state/approval-store.js +0 -149
- package/dist/state/approval-store.js.map +0 -1
- package/dist/state/build-assets.d.ts +0 -50
- package/dist/state/build-assets.js +0 -154
- package/dist/state/build-assets.js.map +0 -1
- package/dist/state/db.d.ts +0 -81
- package/dist/state/db.js +0 -155
- package/dist/state/db.js.map +0 -1
- package/dist/state/execution-store.d.ts +0 -257
- package/dist/state/execution-store.js +0 -527
- package/dist/state/execution-store.js.map +0 -1
- package/dist/state/migrate.d.ts +0 -15
- package/dist/state/migrate.js +0 -175
- package/dist/state/migrate.js.map +0 -1
- package/dist/state/workflow-run-store.d.ts +0 -216
- package/dist/state/workflow-run-store.js +0 -403
- package/dist/state/workflow-run-store.js.map +0 -1
- package/dist/telemetry/index.d.ts +0 -38
- package/dist/telemetry/index.js +0 -253
- package/dist/telemetry/index.js.map +0 -1
- package/dist/telemetry/pi-events.d.ts +0 -12
- package/dist/telemetry/pi-events.js +0 -134
- package/dist/telemetry/pi-events.js.map +0 -1
- package/dist/workflows/dag.d.ts +0 -37
- package/dist/workflows/dag.js +0 -118
- package/dist/workflows/dag.js.map +0 -1
- package/dist/workflows/loader.d.ts +0 -53
- package/dist/workflows/loader.js +0 -421
- package/dist/workflows/loader.js.map +0 -1
- package/dist/workflows/loop-eval.d.ts +0 -28
- package/dist/workflows/loop-eval.js +0 -74
- package/dist/workflows/loop-eval.js.map +0 -1
- package/dist/workflows/phase-executor.d.ts +0 -215
- package/dist/workflows/phase-executor.js +0 -1144
- package/dist/workflows/phase-executor.js.map +0 -1
- package/dist/workflows/phase-ref.d.ts +0 -50
- package/dist/workflows/phase-ref.js +0 -91
- package/dist/workflows/phase-ref.js.map +0 -1
- package/dist/workflows/resume.d.ts +0 -58
- package/dist/workflows/resume.js +0 -313
- package/dist/workflows/resume.js.map +0 -1
- package/dist/workflows/runner.d.ts +0 -63
- package/dist/workflows/runner.js +0 -364
- package/dist/workflows/runner.js.map +0 -1
- package/dist/workflows/schema.d.ts +0 -344
- package/dist/workflows/schema.js +0 -460
- package/dist/workflows/schema.js.map +0 -1
- package/dist/workflows/simple.d.ts +0 -90
- package/dist/workflows/simple.js +0 -393
- package/dist/workflows/simple.js.map +0 -1
- package/dist/workflows/target-policy.d.ts +0 -74
- package/dist/workflows/target-policy.js +0 -80
- package/dist/workflows/target-policy.js.map +0 -1
- package/dist/workflows/templates.d.ts +0 -88
- package/dist/workflows/templates.js +0 -127
- package/dist/workflows/templates.js.map +0 -1
- package/dist/workflows/triggers.d.ts +0 -21
- package/dist/workflows/triggers.js +0 -45
- package/dist/workflows/triggers.js.map +0 -1
- package/dist/workflows/verdict.d.ts +0 -19
- package/dist/workflows/verdict.js +0 -30
- package/dist/workflows/verdict.js.map +0 -1
- package/dist/worktree/manager.d.ts +0 -43
- package/dist/worktree/manager.js +0 -127
- package/dist/worktree/manager.js.map +0 -1
- package/docker-compose.yml +0 -274
- package/sandbox.Dockerfile +0 -68
- package/skills/README.md +0 -42
- package/skills/browser-qa/SKILL.md +0 -208
- package/skills/browser-qa/scripts/agent-browser.mjs +0 -531
- package/skills/building/SKILL.md +0 -95
- package/skills/chat/SKILL.md +0 -36
- package/skills/code-review/SKILL.md +0 -82
- package/skills/debug-production/SKILL.md +0 -108
- package/skills/demo/SKILL.md +0 -228
- package/skills/demo/scripts/compose-demo.sh +0 -243
- package/skills/issue-answer/SKILL.md +0 -91
- package/skills/issue-comment/SKILL.md +0 -49
- package/skills/issue-triage/SKILL.md +0 -149
- package/skills/issue-triage/references/AGENT-BRIEF.md +0 -65
- package/skills/pr-comment/SKILL.md +0 -64
- package/skills/pr-review/SKILL.md +0 -148
- package/skills/pr-review/references/findings-schema.md +0 -89
- package/skills/qa-test/SKILL.md +0 -97
- package/skills/repo-health/SKILL.md +0 -67
- package/skills/security-feedback/SKILL.md +0 -173
- package/skills/security-feedback/references/templates.md +0 -77
- package/skills/security-review/SKILL.md +0 -215
- package/skills/security-review/references/issue-format.md +0 -302
- package/skills/verify/SKILL.md +0 -118
- package/workflows/answer.yaml +0 -44
- package/workflows/build.yaml +0 -129
- package/workflows/cron-health.yaml +0 -6
- package/workflows/cron-review.yaml +0 -8
- package/workflows/cron-security.yaml +0 -6
- package/workflows/cron-triage.yaml +0 -8
- package/workflows/demo.yaml +0 -62
- package/workflows/examples/bash-smoke.yaml +0 -41
- package/workflows/examples/parallel-review.yaml +0 -36
- package/workflows/examples/tdd-loop.yaml +0 -17
- package/workflows/explore.yaml +0 -80
- package/workflows/issue-comment.yaml +0 -15
- package/workflows/issue-triage.yaml +0 -22
- package/workflows/pr-comment.yaml +0 -16
- package/workflows/pr-fix.yaml +0 -17
- package/workflows/pr-review.yaml +0 -50
- package/workflows/prompts/answer.md +0 -68
- package/workflows/prompts/architect.md +0 -44
- package/workflows/prompts/classifier.md +0 -60
- package/workflows/prompts/classify-adds-info.md +0 -17
- package/workflows/prompts/demo.md +0 -125
- package/workflows/prompts/executor.md +0 -42
- package/workflows/prompts/explore-ask.md +0 -99
- package/workflows/prompts/explore-publish.md +0 -31
- package/workflows/prompts/explore-read.md +0 -120
- package/workflows/prompts/explore-synthesize.md +0 -88
- package/workflows/prompts/fix.md +0 -18
- package/workflows/prompts/guardrails.md +0 -96
- package/workflows/prompts/pr-fix.md +0 -26
- package/workflows/prompts/pr.md +0 -39
- package/workflows/prompts/qa-browser.md +0 -95
- package/workflows/prompts/qa-synth.md +0 -44
- package/workflows/prompts/qa-test.md +0 -60
- package/workflows/prompts/re-reviewer.md +0 -33
- package/workflows/prompts/reviewer.md +0 -60
- package/workflows/prompts/verify-browser.md +0 -93
- package/workflows/prompts/verify-synth.md +0 -44
- package/workflows/prompts/verify.md +0 -63
- package/workflows/qa-test.yaml +0 -94
- package/workflows/repo-health.yaml +0 -15
- package/workflows/security-feedback.yaml +0 -25
- package/workflows/security-review.yaml +0 -37
- package/workflows/verify.yaml +0 -93
- /package/dist/{cli/cli-config.d.ts → cli-config.d.ts} +0 -0
- /package/dist/{cli/cli-config.js → cli-config.js} +0 -0
- /package/dist/{cli/cli-format.d.ts → cli-format.d.ts} +0 -0
- /package/dist/{cli/cli-format.js → cli-format.js} +0 -0
- /package/dist/{cli/cli-timeline.d.ts → cli-timeline.d.ts} +0 -0
- /package/dist/{cli/cli-timeline.js → cli-timeline.js} +0 -0
- /package/dist/{cli/cli.d.ts → cli.d.ts} +0 -0
- /package/dist/{cli/oauth-cli.d.ts → oauth-cli.d.ts} +0 -0
- /package/dist/{cli/setup.d.ts → setup.d.ts} +0 -0
package/dist/engine/llm.js
DELETED
|
@@ -1,269 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Thin one-shot LLM chat helper used by the prompt-injection screener and the
|
|
3
|
-
* intent classifier. Powered by `src/providers.ts` — that registry is the
|
|
4
|
-
* single source of truth for which providers this helper can call.
|
|
5
|
-
*
|
|
6
|
-
* The screener + classifier are deliberately small and explicit. They need a
|
|
7
|
-
* cheap/fast model on the SAME provider the user picked (or any registered
|
|
8
|
-
* provider whose key is present) so the agent's primary model and the cheap
|
|
9
|
-
* helper share one footprint. We support two request families:
|
|
10
|
-
*
|
|
11
|
-
* `openai-completions` — body `{ model, messages, <maxTokensField> }`,
|
|
12
|
-
* response `choices[0].message.content`. Covers
|
|
13
|
-
* OpenAI, OpenRouter, Groq, Cerebras, xAI,
|
|
14
|
-
* Hugging Face, Moonshot, NVIDIA, Fireworks,
|
|
15
|
-
* Together, DeepSeek, Z.AI, and Google/Mistral
|
|
16
|
-
* via their OpenAI-compatible endpoints.
|
|
17
|
-
* `anthropic-messages` — `system` field + content-block response.
|
|
18
|
-
* Covers Anthropic, Kimi for Coding, MiniMax.
|
|
19
|
-
*
|
|
20
|
-
* Scope: this helper supports the providers listed in `src/providers.ts`.
|
|
21
|
-
* Workflow phases themselves are provider-agnostic (whatever pi-ai
|
|
22
|
-
* supports); only the screener/classifier path is constrained here.
|
|
23
|
-
*/
|
|
24
|
-
import { PROVIDERS, providerByPrefix } from "../providers.js";
|
|
25
|
-
import { getRuntimeConfig } from "../config/config.js";
|
|
26
|
-
// ── Resolvers (exported for unit tests) ──────────────────────────────────────
|
|
27
|
-
/**
|
|
28
|
-
* Resolve a `provider/model` spec (or a bare model id) into a routing
|
|
29
|
-
* decision. Prefers an explicit `<prefix>/<model>` over name-inference.
|
|
30
|
-
*
|
|
31
|
-
* @throws if the prefix is present but not registered — silently
|
|
32
|
-
* mis-routing a `xai/grok-4` to OpenAI would bill the wrong account and
|
|
33
|
-
* fail at request time with a confusing error, so we surface it early.
|
|
34
|
-
*/
|
|
35
|
-
export function resolveProvider(model) {
|
|
36
|
-
const slash = model.indexOf("/");
|
|
37
|
-
if (slash > 0) {
|
|
38
|
-
const prefix = model.slice(0, slash).toLowerCase();
|
|
39
|
-
const tail = model.slice(slash + 1);
|
|
40
|
-
const spec = providerByPrefix(prefix);
|
|
41
|
-
if (spec) {
|
|
42
|
-
return {
|
|
43
|
-
provider: spec.prefix,
|
|
44
|
-
modelId: tail,
|
|
45
|
-
api: spec.api,
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
throw new Error(`llm helper: unsupported provider prefix "${prefix}" ` +
|
|
49
|
-
`(registered: ${PROVIDERS.map((p) => p.prefix).join(", ")})`);
|
|
50
|
-
}
|
|
51
|
-
// Bare model id — fall back to inference by name. OpenRouter's nested
|
|
52
|
-
// `vendor/model` ids are handled above (its prefix is "openrouter").
|
|
53
|
-
if (/^claude/i.test(model)) {
|
|
54
|
-
return { provider: "anthropic", modelId: model, api: "anthropic-messages" };
|
|
55
|
-
}
|
|
56
|
-
if (/^gpt/i.test(model) || /^o\d/.test(model)) {
|
|
57
|
-
return { provider: "openai", modelId: model, api: "openai-completions" };
|
|
58
|
-
}
|
|
59
|
-
// Anything else: assume OpenAI-completions shape against an OpenAI endpoint.
|
|
60
|
-
return { provider: "openai", modelId: model, api: "openai-completions" };
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Resolve the model id for a tiny one-shot helper call (classifier / screener).
|
|
64
|
-
* Precedence for a given `taskType`:
|
|
65
|
-
* 1. an explicit per-task entry in the config `models:` map (`models.classifier`,
|
|
66
|
-
* `models.screener`) — which already has env `OPENCODE_MODELS` /
|
|
67
|
-
* `LASTLIGHT_MODELS` layered on top at config-load, so this covers both
|
|
68
|
-
* config.yaml and the env override in one lookup;
|
|
69
|
-
* 2. the env `OPENCODE_MODELS` map read directly — a fallback for contexts
|
|
70
|
-
* where runtime config isn't loaded (some CLI / test paths);
|
|
71
|
-
* 3. the first configured provider in `PROVIDERS` order (registry order:
|
|
72
|
-
* Anthropic first, then OpenAI, OpenRouter, then the rest — `src/providers.ts`).
|
|
73
|
-
*
|
|
74
|
-
* Note: only an EXPLICIT per-task entry counts — never `models.default` — so the
|
|
75
|
-
* cheap helpers stay cheap unless a deployment deliberately pins them.
|
|
76
|
-
*/
|
|
77
|
-
export function defaultFastModel(taskType) {
|
|
78
|
-
if (taskType) {
|
|
79
|
-
const configured = getRuntimeConfig()?.models?.[taskType];
|
|
80
|
-
if (configured)
|
|
81
|
-
return configured;
|
|
82
|
-
const override = readOpencodeModelOverride(taskType);
|
|
83
|
-
if (override)
|
|
84
|
-
return override;
|
|
85
|
-
}
|
|
86
|
-
for (const spec of PROVIDERS) {
|
|
87
|
-
if (process.env[spec.envKey])
|
|
88
|
-
return `${spec.prefix}/${spec.fastModel}`;
|
|
89
|
-
}
|
|
90
|
-
// No keys set — fall back to the OpenAI default; chat() will then throw a
|
|
91
|
-
// clear "OPENAI_API_KEY not set" error at call time.
|
|
92
|
-
const openaiSpec = providerByPrefix("openai");
|
|
93
|
-
return `${openaiSpec.prefix}/${openaiSpec.fastModel}`;
|
|
94
|
-
}
|
|
95
|
-
function readOpencodeModelOverride(taskType) {
|
|
96
|
-
const raw = process.env.OPENCODE_MODELS;
|
|
97
|
-
if (!raw)
|
|
98
|
-
return undefined;
|
|
99
|
-
try {
|
|
100
|
-
const parsed = JSON.parse(raw);
|
|
101
|
-
const v = parsed?.[taskType];
|
|
102
|
-
return typeof v === "string" ? v : undefined;
|
|
103
|
-
}
|
|
104
|
-
catch {
|
|
105
|
-
return undefined;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
// ── Request builders ────────────────────────────────────────────────────────
|
|
109
|
-
function apiKeyFor(spec) {
|
|
110
|
-
const apiKey = process.env[spec.envKey];
|
|
111
|
-
if (!apiKey)
|
|
112
|
-
throw new Error(`${spec.envKey} not set`);
|
|
113
|
-
return apiKey;
|
|
114
|
-
}
|
|
115
|
-
/** Append `/messages` (Anthropic-style) taking baseUrl shape into account. */
|
|
116
|
-
function anthropicUrl(spec) {
|
|
117
|
-
return spec.baseUrl.endsWith("/v1")
|
|
118
|
-
? `${spec.baseUrl}/messages`
|
|
119
|
-
: `${spec.baseUrl}/v1/messages`;
|
|
120
|
-
}
|
|
121
|
-
/** Append `/chat/completions` (OpenAI-style). */
|
|
122
|
-
function openaiUrl(spec) {
|
|
123
|
-
return `${spec.baseUrl}/chat/completions`;
|
|
124
|
-
}
|
|
125
|
-
function buildRequest(spec, modelId, messages, opts, apiKey, signal) {
|
|
126
|
-
if (spec.api === "anthropic-messages") {
|
|
127
|
-
return buildAnthropicMessages({ spec, modelId, messages, opts, apiKey, signal });
|
|
128
|
-
}
|
|
129
|
-
return buildOpenaiCompletions({ spec, modelId, messages, opts, apiKey, signal });
|
|
130
|
-
}
|
|
131
|
-
function buildAnthropicMessages(args) {
|
|
132
|
-
const { spec, modelId, messages, opts, apiKey, signal } = args;
|
|
133
|
-
const system = messages
|
|
134
|
-
.filter((m) => m.role === "system")
|
|
135
|
-
.map((m) => m.content)
|
|
136
|
-
.join("\n");
|
|
137
|
-
return {
|
|
138
|
-
url: anthropicUrl(spec),
|
|
139
|
-
init: {
|
|
140
|
-
method: "POST",
|
|
141
|
-
signal,
|
|
142
|
-
headers: {
|
|
143
|
-
"content-type": "application/json",
|
|
144
|
-
"x-api-key": apiKey,
|
|
145
|
-
"anthropic-version": "2023-06-01",
|
|
146
|
-
},
|
|
147
|
-
body: JSON.stringify({
|
|
148
|
-
model: modelId,
|
|
149
|
-
max_tokens: opts.maxTokens ?? 256,
|
|
150
|
-
...(system ? { system } : {}),
|
|
151
|
-
messages: messages
|
|
152
|
-
.filter((m) => m.role !== "system")
|
|
153
|
-
.map((m) => ({ role: m.role, content: m.content })),
|
|
154
|
-
}),
|
|
155
|
-
},
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
function buildOpenaiCompletions(args) {
|
|
159
|
-
const { spec, modelId, messages, opts, apiKey, signal } = args;
|
|
160
|
-
// OpenAI's `max_completion_tokens` (newer family) vs. the cross-provider
|
|
161
|
-
// `max_tokens`. Almost every OpenAI-completions provider accepts `max_tokens`;
|
|
162
|
-
// OpenAI itself prefers `max_completion_tokens` so we surface that as a
|
|
163
|
-
// per-provider override in the registry.
|
|
164
|
-
const maxField = spec.maxTokensField ?? "max_tokens";
|
|
165
|
-
const headers = {
|
|
166
|
-
"content-type": "application/json",
|
|
167
|
-
authorization: `Bearer ${apiKey}`,
|
|
168
|
-
};
|
|
169
|
-
if (spec.extraHeaders) {
|
|
170
|
-
for (const [k, v] of Object.entries(spec.extraHeaders))
|
|
171
|
-
headers[k] = v;
|
|
172
|
-
}
|
|
173
|
-
return {
|
|
174
|
-
url: openaiUrl(spec),
|
|
175
|
-
init: {
|
|
176
|
-
method: "POST",
|
|
177
|
-
signal,
|
|
178
|
-
headers,
|
|
179
|
-
body: JSON.stringify({
|
|
180
|
-
model: modelId,
|
|
181
|
-
[maxField]: opts.maxTokens ?? 256,
|
|
182
|
-
messages,
|
|
183
|
-
}),
|
|
184
|
-
},
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
// ── Response extractors ─────────────────────────────────────────────────────
|
|
188
|
-
function extractAnthropicText(data) {
|
|
189
|
-
const content = data.content ?? [];
|
|
190
|
-
return content
|
|
191
|
-
.filter((block) => block.type === "text" && typeof block.text === "string")
|
|
192
|
-
.map((block) => block.text)
|
|
193
|
-
.join("");
|
|
194
|
-
}
|
|
195
|
-
function extractOpenaiText(data) {
|
|
196
|
-
return (data.choices?.[0]?.message?.content ??
|
|
197
|
-
"");
|
|
198
|
-
}
|
|
199
|
-
function extractText(spec, data) {
|
|
200
|
-
return spec.api === "anthropic-messages" ? extractAnthropicText(data) : extractOpenaiText(data);
|
|
201
|
-
}
|
|
202
|
-
// ── Public API ───────────────────────────────────────────────────────────────
|
|
203
|
-
/**
|
|
204
|
-
* Make a provider-agnostic chat call and return the final assistant text.
|
|
205
|
-
*
|
|
206
|
-
* @throws if the relevant API key isn't set or the upstream returns non-2xx
|
|
207
|
-
*/
|
|
208
|
-
export async function chat(model, messages, opts = {}) {
|
|
209
|
-
const { provider, modelId, api } = resolveProvider(model);
|
|
210
|
-
const spec = providerByPrefix(provider);
|
|
211
|
-
// For bare-id inference where the prefix isn't in the registry (the
|
|
212
|
-
// generic "assume OpenAI" fallback), synthesize a pseudo-spec so the
|
|
213
|
-
// OpenAI-completions builder still runs.
|
|
214
|
-
const resolvedSpec = spec ?? {
|
|
215
|
-
prefix: provider,
|
|
216
|
-
displayName: provider,
|
|
217
|
-
envKey: "OPENAI_API_KEY",
|
|
218
|
-
baseUrl: "https://api.openai.com/v1",
|
|
219
|
-
api,
|
|
220
|
-
host: "openai.com",
|
|
221
|
-
fastModel: modelId,
|
|
222
|
-
sampleModel: modelId,
|
|
223
|
-
};
|
|
224
|
-
return withRetry(async (signal) => {
|
|
225
|
-
const apiKey = apiKeyFor(resolvedSpec);
|
|
226
|
-
const { url, init } = buildRequest(resolvedSpec, modelId, messages, opts, apiKey, signal);
|
|
227
|
-
const res = await fetch(url, init);
|
|
228
|
-
if (!res.ok) {
|
|
229
|
-
const text = await res.text().catch(() => "");
|
|
230
|
-
throw new Error(`${resolvedSpec.prefix} api ${res.status}: ${text}`);
|
|
231
|
-
}
|
|
232
|
-
const data = await res.json();
|
|
233
|
-
return extractText(resolvedSpec, data);
|
|
234
|
-
}, opts.timeoutMs ?? 30_000);
|
|
235
|
-
}
|
|
236
|
-
/** Compatibility wrapper for older single-turn call sites. */
|
|
237
|
-
export async function callLlm(model, systemPrompt, userPrompt, opts = {}) {
|
|
238
|
-
return chat(model, [
|
|
239
|
-
{ role: "system", content: systemPrompt },
|
|
240
|
-
{ role: "user", content: userPrompt },
|
|
241
|
-
], opts);
|
|
242
|
-
}
|
|
243
|
-
/**
|
|
244
|
-
* Single retry on transient upstream failures. The screener and classifier
|
|
245
|
-
* call this inline on every incoming event, so a single 429/503 from the
|
|
246
|
-
* provider would otherwise silently drop the event and break routing.
|
|
247
|
-
*/
|
|
248
|
-
async function withRetry(call, timeoutMs) {
|
|
249
|
-
for (let attempt = 0; attempt < 2; attempt++) {
|
|
250
|
-
const ctrl = new AbortController();
|
|
251
|
-
const timer = setTimeout(() => ctrl.abort(), timeoutMs);
|
|
252
|
-
try {
|
|
253
|
-
return await call(ctrl.signal);
|
|
254
|
-
}
|
|
255
|
-
catch (err) {
|
|
256
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
257
|
-
const transient = /\b(429|5\d\d)\b/.test(msg);
|
|
258
|
-
if (attempt === 1 || !transient)
|
|
259
|
-
throw err;
|
|
260
|
-
await new Promise((r) => setTimeout(r, 750));
|
|
261
|
-
}
|
|
262
|
-
finally {
|
|
263
|
-
clearTimeout(timer);
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
// Unreachable — loop either returns or throws.
|
|
267
|
-
throw new Error("chat: retry loop fell through");
|
|
268
|
-
}
|
|
269
|
-
//# sourceMappingURL=llm.js.map
|
package/dist/engine/llm.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"llm.js","sourceRoot":"","sources":["../../src/engine/llm.ts"],"names":[],"mappings":"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"}
|
package/dist/engine/oauth.d.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { getOAuthProvider, getOAuthProviders, type OAuthCredentials } from "@earendil-works/pi-ai/oauth";
|
|
2
|
-
/** Stored form — pi-ai's CLI tags each entry with `type: "oauth"`; we match it. */
|
|
3
|
-
export type StoredCredentials = OAuthCredentials & {
|
|
4
|
-
type?: string;
|
|
5
|
-
};
|
|
6
|
-
export type AuthMap = Record<string, StoredCredentials>;
|
|
7
|
-
/** OAuth providers that CANNOT fall back to an API key — login is mandatory. */
|
|
8
|
-
export declare const OAUTH_ONLY_PROVIDERS: ReadonlySet<string>;
|
|
9
|
-
/** OAuth provider id backing a model spec, or undefined if it's API-key based. */
|
|
10
|
-
export declare function oauthProviderIdForModel(spec: string): string | undefined;
|
|
11
|
-
/**
|
|
12
|
-
* The env var pi-ai reads inside a sandbox for a provider's OAuth token, when
|
|
13
|
-
* one exists. Returns undefined for providers with no env-var route (Codex),
|
|
14
|
-
* which therefore cannot authenticate in the agentic-pi sandbox.
|
|
15
|
-
*/
|
|
16
|
-
export declare function oauthEnvVarForProvider(id: string): string | undefined;
|
|
17
|
-
/**
|
|
18
|
-
* Resolve the credential-store path. Precedence:
|
|
19
|
-
* 1. explicit argument (a caller-computed path),
|
|
20
|
-
* 2. `LASTLIGHT_AUTH_FILE` (hard override),
|
|
21
|
-
* 3. `<stateDir | $STATE_DIR | ./data>/auth.json`.
|
|
22
|
-
* The CLI writes here and the harness reads here, so both must agree; passing
|
|
23
|
-
* the harness's resolved `stateDir` keeps them aligned even if the process cwd
|
|
24
|
-
* differs.
|
|
25
|
-
*/
|
|
26
|
-
export declare function resolveAuthFile(explicit?: string, stateDir?: string): string;
|
|
27
|
-
export declare function loadAuthMap(file?: string, stateDir?: string): AuthMap;
|
|
28
|
-
export declare function saveAuthMap(map: AuthMap, file?: string, stateDir?: string): void;
|
|
29
|
-
export declare function hasOAuthCredentials(id: string, file?: string, stateDir?: string): boolean;
|
|
30
|
-
export interface OAuthKeyResult {
|
|
31
|
-
apiKey: string;
|
|
32
|
-
credentials: OAuthCredentials;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Resolve a usable API key for an OAuth provider from stored credentials,
|
|
36
|
-
* refreshing an expired token and persisting the rotated credentials back to
|
|
37
|
-
* the store. Returns null when nothing is stored for `id`. Throws only if a
|
|
38
|
-
* refresh actually fails (expired refresh token, revoked grant) — callers
|
|
39
|
-
* should surface that as "re-run login".
|
|
40
|
-
*/
|
|
41
|
-
export declare function resolveOAuthApiKey(id: string, file?: string, stateDir?: string): Promise<OAuthKeyResult | null>;
|
|
42
|
-
/** Re-exported so callers depend on this module, not pi-ai's oauth entry directly. */
|
|
43
|
-
export { getOAuthProvider, getOAuthProviders };
|
package/dist/engine/oauth.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OAuth credential management for LLM providers that authenticate with a
|
|
3
|
-
* subscription login instead of a static API key — ChatGPT Plus/Pro (Codex),
|
|
4
|
-
* Claude Pro/Max, and GitHub Copilot.
|
|
5
|
-
*
|
|
6
|
-
* pi-ai (`@earendil-works/pi-ai/oauth`) owns the actual OAuth flows, token
|
|
7
|
-
* refresh, and credential→apiKey conversion; this module is the thin Last
|
|
8
|
-
* Light layer on top:
|
|
9
|
-
* - a single on-disk credential store (`auth.json`, same JSON shape pi-ai's
|
|
10
|
-
* own CLI writes) resolved under `$STATE_DIR` so the CLI (writer) and the
|
|
11
|
-
* running harness (reader) agree on one path,
|
|
12
|
-
* - `resolveOAuthApiKey()` — refresh-if-expired + persist rotated creds +
|
|
13
|
-
* return a usable key, used by the in-process chat path,
|
|
14
|
-
* - the model-prefix → provider-id map and the sandbox env-var route so the
|
|
15
|
-
* chat and sandbox executors can both find the right credential.
|
|
16
|
-
*
|
|
17
|
-
* Two consumption seams with different reach:
|
|
18
|
-
* - **chat** (in-process pi-ai) — passes `apiKey` in the stream options, so
|
|
19
|
-
* ALL three OAuth providers work, Codex included.
|
|
20
|
-
* - **sandbox** (agentic-pi) — has no apiKey option; it reads provider creds
|
|
21
|
-
* from env only. pi-ai honours `ANTHROPIC_OAUTH_TOKEN` and
|
|
22
|
-
* `COPILOT_GITHUB_TOKEN`, but Codex (chatgpt.com backend) has no env route,
|
|
23
|
-
* so a Codex model cannot run in the sandbox. See `oauthEnvVarForProvider`.
|
|
24
|
-
*/
|
|
25
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
26
|
-
import { dirname, resolve } from "node:path";
|
|
27
|
-
import { getOAuthApiKey, getOAuthProvider, getOAuthProviders, } from "@earendil-works/pi-ai/oauth";
|
|
28
|
-
import { OAUTH_PROVIDERS, oauthProviderByModelPrefix, oauthProviderById } from "../providers.js";
|
|
29
|
-
/** OAuth providers that CANNOT fall back to an API key — login is mandatory. */
|
|
30
|
-
export const OAUTH_ONLY_PROVIDERS = new Set(OAUTH_PROVIDERS.filter((p) => p.oauthOnly).map((p) => p.id));
|
|
31
|
-
/** OAuth provider id backing a model spec, or undefined if it's API-key based. */
|
|
32
|
-
export function oauthProviderIdForModel(spec) {
|
|
33
|
-
const prefix = spec.includes("/") ? spec.slice(0, spec.indexOf("/")) : spec;
|
|
34
|
-
return oauthProviderByModelPrefix(prefix)?.id;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* The env var pi-ai reads inside a sandbox for a provider's OAuth token, when
|
|
38
|
-
* one exists. Returns undefined for providers with no env-var route (Codex),
|
|
39
|
-
* which therefore cannot authenticate in the agentic-pi sandbox.
|
|
40
|
-
*/
|
|
41
|
-
export function oauthEnvVarForProvider(id) {
|
|
42
|
-
return oauthProviderById(id)?.sandboxEnvVar ?? undefined;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Resolve the credential-store path. Precedence:
|
|
46
|
-
* 1. explicit argument (a caller-computed path),
|
|
47
|
-
* 2. `LASTLIGHT_AUTH_FILE` (hard override),
|
|
48
|
-
* 3. `<stateDir | $STATE_DIR | ./data>/auth.json`.
|
|
49
|
-
* The CLI writes here and the harness reads here, so both must agree; passing
|
|
50
|
-
* the harness's resolved `stateDir` keeps them aligned even if the process cwd
|
|
51
|
-
* differs.
|
|
52
|
-
*/
|
|
53
|
-
export function resolveAuthFile(explicit, stateDir) {
|
|
54
|
-
if (explicit)
|
|
55
|
-
return resolve(explicit);
|
|
56
|
-
if (process.env.LASTLIGHT_AUTH_FILE)
|
|
57
|
-
return resolve(process.env.LASTLIGHT_AUTH_FILE);
|
|
58
|
-
return resolve(stateDir || process.env.STATE_DIR || "data", "auth.json");
|
|
59
|
-
}
|
|
60
|
-
export function loadAuthMap(file, stateDir) {
|
|
61
|
-
const path = resolveAuthFile(file, stateDir);
|
|
62
|
-
if (!existsSync(path))
|
|
63
|
-
return {};
|
|
64
|
-
try {
|
|
65
|
-
const parsed = JSON.parse(readFileSync(path, "utf8"));
|
|
66
|
-
return parsed && typeof parsed === "object" ? parsed : {};
|
|
67
|
-
}
|
|
68
|
-
catch {
|
|
69
|
-
return {};
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
export function saveAuthMap(map, file, stateDir) {
|
|
73
|
-
const path = resolveAuthFile(file, stateDir);
|
|
74
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
75
|
-
// Mode 0600 — the file holds long-lived refresh tokens.
|
|
76
|
-
writeFileSync(path, JSON.stringify(map, null, 2), { mode: 0o600 });
|
|
77
|
-
}
|
|
78
|
-
export function hasOAuthCredentials(id, file, stateDir) {
|
|
79
|
-
return !!loadAuthMap(file, stateDir)[id];
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Resolve a usable API key for an OAuth provider from stored credentials,
|
|
83
|
-
* refreshing an expired token and persisting the rotated credentials back to
|
|
84
|
-
* the store. Returns null when nothing is stored for `id`. Throws only if a
|
|
85
|
-
* refresh actually fails (expired refresh token, revoked grant) — callers
|
|
86
|
-
* should surface that as "re-run login".
|
|
87
|
-
*/
|
|
88
|
-
export async function resolveOAuthApiKey(id, file, stateDir) {
|
|
89
|
-
const map = loadAuthMap(file, stateDir);
|
|
90
|
-
if (!map[id])
|
|
91
|
-
return null;
|
|
92
|
-
const res = await getOAuthApiKey(id, map);
|
|
93
|
-
if (!res)
|
|
94
|
-
return null;
|
|
95
|
-
// Persist the rotated credentials so the next refresh chains from the new
|
|
96
|
-
// token rather than re-using a spent one.
|
|
97
|
-
map[id] = { type: "oauth", ...res.newCredentials };
|
|
98
|
-
saveAuthMap(map, file, stateDir);
|
|
99
|
-
return { apiKey: res.apiKey, credentials: res.newCredentials };
|
|
100
|
-
}
|
|
101
|
-
/** Re-exported so callers depend on this module, not pi-ai's oauth entry directly. */
|
|
102
|
-
export { getOAuthProvider, getOAuthProviders };
|
|
103
|
-
//# sourceMappingURL=oauth.js.map
|
package/dist/engine/oauth.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/engine/oauth.ts"],"names":[],"mappings":"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"}
|
package/dist/engine/router.d.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { EventEnvelope } from "../connectors/types.js";
|
|
2
|
-
import type { StateDb } from "../state/db.js";
|
|
3
|
-
/**
|
|
4
|
-
* A routing decision — the single term for "what should process this event"
|
|
5
|
-
* is `handler`. It names either an in-process handler (chat, status-report,
|
|
6
|
-
* approval-response, …) or a workflow (issue-triage, pr-review, build, …);
|
|
7
|
-
* the dispatcher decides which. The router itself performs no side effects.
|
|
8
|
-
*/
|
|
9
|
-
export type Route = {
|
|
10
|
-
action: "handler";
|
|
11
|
-
handler: string;
|
|
12
|
-
context: Record<string, unknown>;
|
|
13
|
-
} | {
|
|
14
|
-
action: "reply";
|
|
15
|
-
message: string;
|
|
16
|
-
} | {
|
|
17
|
-
action: "ignore";
|
|
18
|
-
reason: string;
|
|
19
|
-
};
|
|
20
|
-
/** Optional dependencies the router needs to short-circuit paused runs. */
|
|
21
|
-
export interface RouterDeps {
|
|
22
|
-
db?: StateDb;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Event routing — deterministic for most events, LLM-classified for comments.
|
|
26
|
-
* Maps normalized events to the handler that should process them. Returns a
|
|
27
|
-
* decision only; the dispatcher performs the side effects.
|
|
28
|
-
*/
|
|
29
|
-
export declare function routeEvent(envelope: EventEnvelope, deps?: RouterDeps): Promise<Route>;
|