@asermax/tachikoma 2.0.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 +64 -0
- package/dist/agent/adapter.d.ts +8 -0
- package/dist/agent/adapter.js +86 -0
- package/dist/agent/adapter.js.map +1 -0
- package/dist/agent/manager.d.ts +35 -0
- package/dist/agent/manager.js +76 -0
- package/dist/agent/manager.js.map +1 -0
- package/dist/agent/models.d.ts +46 -0
- package/dist/agent/models.js +96 -0
- package/dist/agent/models.js.map +1 -0
- package/dist/agent/side-run.d.ts +42 -0
- package/dist/agent/side-run.js +83 -0
- package/dist/agent/side-run.js.map +1 -0
- package/dist/app.d.ts +5 -0
- package/dist/app.js +79 -0
- package/dist/app.js.map +1 -0
- package/dist/channels/types.d.ts +37 -0
- package/dist/channels/types.js +5 -0
- package/dist/channels/types.js.map +1 -0
- package/dist/config/default-template.d.ts +1 -0
- package/dist/config/default-template.js +49 -0
- package/dist/config/default-template.js.map +1 -0
- package/dist/config/load.d.ts +8 -0
- package/dist/config/load.js +28 -0
- package/dist/config/load.js.map +1 -0
- package/dist/config/parse.d.ts +5 -0
- package/dist/config/parse.js +18 -0
- package/dist/config/parse.js.map +1 -0
- package/dist/config/schema.d.ts +29 -0
- package/dist/config/schema.js +35 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/coordinator.d.ts +54 -0
- package/dist/coordinator.js +344 -0
- package/dist/coordinator.js.map +1 -0
- package/dist/db/core-schema.d.ts +250 -0
- package/dist/db/core-schema.js +19 -0
- package/dist/db/core-schema.js.map +1 -0
- package/dist/db/index.d.ts +8 -0
- package/dist/db/index.js +16 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/schema.d.ts +4 -0
- package/dist/db/schema.js +7 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/db/state.d.ts +10 -0
- package/dist/db/state.js +36 -0
- package/dist/db/state.js.map +1 -0
- package/dist/domain/agent-events.d.ts +26 -0
- package/dist/domain/agent-events.js +2 -0
- package/dist/domain/agent-events.js.map +1 -0
- package/dist/domain/message.d.ts +25 -0
- package/dist/domain/message.js +17 -0
- package/dist/domain/message.js.map +1 -0
- package/dist/events.d.ts +9 -0
- package/dist/events.js +27 -0
- package/dist/events.js.map +1 -0
- package/dist/extensions/api.d.ts +118 -0
- package/dist/extensions/api.js +7 -0
- package/dist/extensions/api.js.map +1 -0
- package/dist/extensions/boundary/detector.d.ts +20 -0
- package/dist/extensions/boundary/detector.js +57 -0
- package/dist/extensions/boundary/detector.js.map +1 -0
- package/dist/extensions/boundary/idle.d.ts +10 -0
- package/dist/extensions/boundary/idle.js +28 -0
- package/dist/extensions/boundary/idle.js.map +1 -0
- package/dist/extensions/boundary/index.d.ts +12 -0
- package/dist/extensions/boundary/index.js +65 -0
- package/dist/extensions/boundary/index.js.map +1 -0
- package/dist/extensions/boundary/summary.d.ts +5 -0
- package/dist/extensions/boundary/summary.js +33 -0
- package/dist/extensions/boundary/summary.js.map +1 -0
- package/dist/extensions/commands/index.d.ts +7 -0
- package/dist/extensions/commands/index.js +21 -0
- package/dist/extensions/commands/index.js.map +1 -0
- package/dist/extensions/context/index.d.ts +7 -0
- package/dist/extensions/context/index.js +65 -0
- package/dist/extensions/context/index.js.map +1 -0
- package/dist/extensions/context/processor.d.ts +27 -0
- package/dist/extensions/context/processor.js +228 -0
- package/dist/extensions/context/processor.js.map +1 -0
- package/dist/extensions/detached-processes/index.d.ts +12 -0
- package/dist/extensions/detached-processes/index.js +51 -0
- package/dist/extensions/detached-processes/index.js.map +1 -0
- package/dist/extensions/detached-processes/limits.d.ts +27 -0
- package/dist/extensions/detached-processes/limits.js +55 -0
- package/dist/extensions/detached-processes/limits.js.map +1 -0
- package/dist/extensions/detached-processes/output.d.ts +2 -0
- package/dist/extensions/detached-processes/output.js +26 -0
- package/dist/extensions/detached-processes/output.js.map +1 -0
- package/dist/extensions/detached-processes/reconcile.d.ts +31 -0
- package/dist/extensions/detached-processes/reconcile.js +71 -0
- package/dist/extensions/detached-processes/reconcile.js.map +1 -0
- package/dist/extensions/detached-processes/repository.d.ts +33 -0
- package/dist/extensions/detached-processes/repository.js +62 -0
- package/dist/extensions/detached-processes/repository.js.map +1 -0
- package/dist/extensions/detached-processes/schema.d.ts +252 -0
- package/dist/extensions/detached-processes/schema.js +23 -0
- package/dist/extensions/detached-processes/schema.js.map +1 -0
- package/dist/extensions/detached-processes/spawn.d.ts +40 -0
- package/dist/extensions/detached-processes/spawn.js +137 -0
- package/dist/extensions/detached-processes/spawn.js.map +1 -0
- package/dist/extensions/detached-processes/tools.d.ts +41 -0
- package/dist/extensions/detached-processes/tools.js +243 -0
- package/dist/extensions/detached-processes/tools.js.map +1 -0
- package/dist/extensions/detached-processes/watcher.d.ts +7 -0
- package/dist/extensions/detached-processes/watcher.js +19 -0
- package/dist/extensions/detached-processes/watcher.js.map +1 -0
- package/dist/extensions/external/index.d.ts +11 -0
- package/dist/extensions/external/index.js +40 -0
- package/dist/extensions/external/index.js.map +1 -0
- package/dist/extensions/external/installs.d.ts +39 -0
- package/dist/extensions/external/installs.js +98 -0
- package/dist/extensions/external/installs.js.map +1 -0
- package/dist/extensions/external/loader.d.ts +19 -0
- package/dist/extensions/external/loader.js +70 -0
- package/dist/extensions/external/loader.js.map +1 -0
- package/dist/extensions/external/tools.d.ts +17 -0
- package/dist/extensions/external/tools.js +112 -0
- package/dist/extensions/external/tools.js.map +1 -0
- package/dist/extensions/git/commit.d.ts +19 -0
- package/dist/extensions/git/commit.js +44 -0
- package/dist/extensions/git/commit.js.map +1 -0
- package/dist/extensions/git/git.d.ts +11 -0
- package/dist/extensions/git/git.js +29 -0
- package/dist/extensions/git/git.js.map +1 -0
- package/dist/extensions/git/hooks.d.ts +10 -0
- package/dist/extensions/git/hooks.js +88 -0
- package/dist/extensions/git/hooks.js.map +1 -0
- package/dist/extensions/git/index.d.ts +11 -0
- package/dist/extensions/git/index.js +28 -0
- package/dist/extensions/git/index.js.map +1 -0
- package/dist/extensions/git/processor.d.ts +13 -0
- package/dist/extensions/git/processor.js +52 -0
- package/dist/extensions/git/processor.js.map +1 -0
- package/dist/extensions/git/sync.d.ts +44 -0
- package/dist/extensions/git/sync.js +189 -0
- package/dist/extensions/git/sync.js.map +1 -0
- package/dist/extensions/git/tools.d.ts +21 -0
- package/dist/extensions/git/tools.js +101 -0
- package/dist/extensions/git/tools.js.map +1 -0
- package/dist/extensions/host.d.ts +31 -0
- package/dist/extensions/host.js +75 -0
- package/dist/extensions/host.js.map +1 -0
- package/dist/extensions/index.d.ts +3 -0
- package/dist/extensions/index.js +32 -0
- package/dist/extensions/index.js.map +1 -0
- package/dist/extensions/memory/archive.d.ts +8 -0
- package/dist/extensions/memory/archive.js +46 -0
- package/dist/extensions/memory/archive.js.map +1 -0
- package/dist/extensions/memory/dates.d.ts +2 -0
- package/dist/extensions/memory/dates.js +7 -0
- package/dist/extensions/memory/dates.js.map +1 -0
- package/dist/extensions/memory/extraction.d.ts +17 -0
- package/dist/extensions/memory/extraction.js +218 -0
- package/dist/extensions/memory/extraction.js.map +1 -0
- package/dist/extensions/memory/index.d.ts +20 -0
- package/dist/extensions/memory/index.js +67 -0
- package/dist/extensions/memory/index.js.map +1 -0
- package/dist/extensions/memory/indexes.d.ts +14 -0
- package/dist/extensions/memory/indexes.js +64 -0
- package/dist/extensions/memory/indexes.js.map +1 -0
- package/dist/extensions/memory/layout.d.ts +20 -0
- package/dist/extensions/memory/layout.js +79 -0
- package/dist/extensions/memory/layout.js.map +1 -0
- package/dist/extensions/memory/maintenance.d.ts +21 -0
- package/dist/extensions/memory/maintenance.js +357 -0
- package/dist/extensions/memory/maintenance.js.map +1 -0
- package/dist/extensions/memory/prompts.d.ts +8 -0
- package/dist/extensions/memory/prompts.js +125 -0
- package/dist/extensions/memory/prompts.js.map +1 -0
- package/dist/extensions/memory/transcript.d.ts +18 -0
- package/dist/extensions/memory/transcript.js +79 -0
- package/dist/extensions/memory/transcript.js.map +1 -0
- package/dist/extensions/notifications/format.d.ts +5 -0
- package/dist/extensions/notifications/format.js +17 -0
- package/dist/extensions/notifications/format.js.map +1 -0
- package/dist/extensions/notifications/index.d.ts +13 -0
- package/dist/extensions/notifications/index.js +29 -0
- package/dist/extensions/notifications/index.js.map +1 -0
- package/dist/extensions/notifications/payload.d.ts +22 -0
- package/dist/extensions/notifications/payload.js +29 -0
- package/dist/extensions/notifications/payload.js.map +1 -0
- package/dist/extensions/notifications/router.d.ts +29 -0
- package/dist/extensions/notifications/router.js +55 -0
- package/dist/extensions/notifications/router.js.map +1 -0
- package/dist/extensions/notifications/tools.d.ts +12 -0
- package/dist/extensions/notifications/tools.js +41 -0
- package/dist/extensions/notifications/tools.js.map +1 -0
- package/dist/extensions/projects/context-provider.d.ts +9 -0
- package/dist/extensions/projects/context-provider.js +37 -0
- package/dist/extensions/projects/context-provider.js.map +1 -0
- package/dist/extensions/projects/git.d.ts +28 -0
- package/dist/extensions/projects/git.js +91 -0
- package/dist/extensions/projects/git.js.map +1 -0
- package/dist/extensions/projects/hooks.d.ts +7 -0
- package/dist/extensions/projects/hooks.js +42 -0
- package/dist/extensions/projects/hooks.js.map +1 -0
- package/dist/extensions/projects/index.d.ts +11 -0
- package/dist/extensions/projects/index.js +30 -0
- package/dist/extensions/projects/index.js.map +1 -0
- package/dist/extensions/projects/processor.d.ts +13 -0
- package/dist/extensions/projects/processor.js +63 -0
- package/dist/extensions/projects/processor.js.map +1 -0
- package/dist/extensions/projects/tools.d.ts +21 -0
- package/dist/extensions/projects/tools.js +118 -0
- package/dist/extensions/projects/tools.js.map +1 -0
- package/dist/extensions/registrations.d.ts +21 -0
- package/dist/extensions/registrations.js +12 -0
- package/dist/extensions/registrations.js.map +1 -0
- package/dist/extensions/repl/index.d.ts +2 -0
- package/dist/extensions/repl/index.js +85 -0
- package/dist/extensions/repl/index.js.map +1 -0
- package/dist/extensions/skills/agents.d.ts +17 -0
- package/dist/extensions/skills/agents.js +77 -0
- package/dist/extensions/skills/agents.js.map +1 -0
- package/dist/extensions/skills/delegate.d.ts +22 -0
- package/dist/extensions/skills/delegate.js +54 -0
- package/dist/extensions/skills/delegate.js.map +1 -0
- package/dist/extensions/skills/index.d.ts +11 -0
- package/dist/extensions/skills/index.js +43 -0
- package/dist/extensions/skills/index.js.map +1 -0
- package/dist/extensions/skills/reload.d.ts +8 -0
- package/dist/extensions/skills/reload.js +38 -0
- package/dist/extensions/skills/reload.js.map +1 -0
- package/dist/extensions/tasks/executor.d.ts +43 -0
- package/dist/extensions/tasks/executor.js +179 -0
- package/dist/extensions/tasks/executor.js.map +1 -0
- package/dist/extensions/tasks/expiration.d.ts +12 -0
- package/dist/extensions/tasks/expiration.js +17 -0
- package/dist/extensions/tasks/expiration.js.map +1 -0
- package/dist/extensions/tasks/generation.d.ts +14 -0
- package/dist/extensions/tasks/generation.js +70 -0
- package/dist/extensions/tasks/generation.js.map +1 -0
- package/dist/extensions/tasks/index.d.ts +14 -0
- package/dist/extensions/tasks/index.js +75 -0
- package/dist/extensions/tasks/index.js.map +1 -0
- package/dist/extensions/tasks/repository.d.ts +53 -0
- package/dist/extensions/tasks/repository.js +147 -0
- package/dist/extensions/tasks/repository.js.map +1 -0
- package/dist/extensions/tasks/schedule.d.ts +13 -0
- package/dist/extensions/tasks/schedule.js +32 -0
- package/dist/extensions/tasks/schedule.js.map +1 -0
- package/dist/extensions/tasks/schema.d.ts +423 -0
- package/dist/extensions/tasks/schema.js +45 -0
- package/dist/extensions/tasks/schema.js.map +1 -0
- package/dist/extensions/tasks/session-delivery.d.ts +18 -0
- package/dist/extensions/tasks/session-delivery.js +39 -0
- package/dist/extensions/tasks/session-delivery.js.map +1 -0
- package/dist/extensions/tasks/tools.d.ts +38 -0
- package/dist/extensions/tasks/tools.js +181 -0
- package/dist/extensions/tasks/tools.js.map +1 -0
- package/dist/extensions/telegram/buttons.d.ts +14 -0
- package/dist/extensions/telegram/buttons.js +49 -0
- package/dist/extensions/telegram/buttons.js.map +1 -0
- package/dist/extensions/telegram/channel.d.ts +39 -0
- package/dist/extensions/telegram/channel.js +201 -0
- package/dist/extensions/telegram/channel.js.map +1 -0
- package/dist/extensions/telegram/chunking.d.ts +7 -0
- package/dist/extensions/telegram/chunking.js +67 -0
- package/dist/extensions/telegram/chunking.js.map +1 -0
- package/dist/extensions/telegram/inbound.d.ts +7 -0
- package/dist/extensions/telegram/inbound.js +29 -0
- package/dist/extensions/telegram/inbound.js.map +1 -0
- package/dist/extensions/telegram/index.d.ts +13 -0
- package/dist/extensions/telegram/index.js +67 -0
- package/dist/extensions/telegram/index.js.map +1 -0
- package/dist/extensions/telegram/media.d.ts +39 -0
- package/dist/extensions/telegram/media.js +223 -0
- package/dist/extensions/telegram/media.js.map +1 -0
- package/dist/extensions/telegram/mutex.d.ts +9 -0
- package/dist/extensions/telegram/mutex.js +14 -0
- package/dist/extensions/telegram/mutex.js.map +1 -0
- package/dist/extensions/telegram/sending.d.ts +48 -0
- package/dist/extensions/telegram/sending.js +119 -0
- package/dist/extensions/telegram/sending.js.map +1 -0
- package/dist/extensions/telegram/streaming.d.ts +46 -0
- package/dist/extensions/telegram/streaming.js +140 -0
- package/dist/extensions/telegram/streaming.js.map +1 -0
- package/dist/extensions/telegram/tools.d.ts +80 -0
- package/dist/extensions/telegram/tools.js +232 -0
- package/dist/extensions/telegram/tools.js.map +1 -0
- package/dist/extensions/workflows/cleanup.d.ts +10 -0
- package/dist/extensions/workflows/cleanup.js +38 -0
- package/dist/extensions/workflows/cleanup.js.map +1 -0
- package/dist/extensions/workflows/index.d.ts +11 -0
- package/dist/extensions/workflows/index.js +42 -0
- package/dist/extensions/workflows/index.js.map +1 -0
- package/dist/extensions/workflows/loader.d.ts +27 -0
- package/dist/extensions/workflows/loader.js +90 -0
- package/dist/extensions/workflows/loader.js.map +1 -0
- package/dist/extensions/workflows/model.d.ts +19 -0
- package/dist/extensions/workflows/model.js +7 -0
- package/dist/extensions/workflows/model.js.map +1 -0
- package/dist/extensions/workflows/repository.d.ts +24 -0
- package/dist/extensions/workflows/repository.js +61 -0
- package/dist/extensions/workflows/repository.js.map +1 -0
- package/dist/extensions/workflows/schema.d.ts +193 -0
- package/dist/extensions/workflows/schema.js +20 -0
- package/dist/extensions/workflows/schema.js.map +1 -0
- package/dist/extensions/workflows/tools.d.ts +27 -0
- package/dist/extensions/workflows/tools.js +285 -0
- package/dist/extensions/workflows/tools.js.map +1 -0
- package/dist/log.d.ts +8 -0
- package/dist/log.js +15 -0
- package/dist/log.js.map +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +27 -0
- package/dist/main.js.map +1 -0
- package/dist/migration/ask.d.ts +8 -0
- package/dist/migration/ask.js +24 -0
- package/dist/migration/ask.js.map +1 -0
- package/dist/migration/config.d.ts +10 -0
- package/dist/migration/config.js +122 -0
- package/dist/migration/config.js.map +1 -0
- package/dist/migration/context.d.ts +3 -0
- package/dist/migration/context.js +24 -0
- package/dist/migration/context.js.map +1 -0
- package/dist/migration/database.d.ts +8 -0
- package/dist/migration/database.js +51 -0
- package/dist/migration/database.js.map +1 -0
- package/dist/migration/fs.d.ts +1 -0
- package/dist/migration/fs.js +11 -0
- package/dist/migration/fs.js.map +1 -0
- package/dist/migration/index.d.ts +11 -0
- package/dist/migration/index.js +28 -0
- package/dist/migration/index.js.map +1 -0
- package/dist/migration/skills.d.ts +19 -0
- package/dist/migration/skills.js +77 -0
- package/dist/migration/skills.js.map +1 -0
- package/dist/scheduler.d.ts +17 -0
- package/dist/scheduler.js +53 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/sessions/registry.d.ts +15 -0
- package/dist/sessions/registry.js +42 -0
- package/dist/sessions/registry.js.map +1 -0
- package/dist/workspace.d.ts +13 -0
- package/dist/workspace.js +32 -0
- package/dist/workspace.js.map +1 -0
- package/drizzle/0000_init.sql +19 -0
- package/drizzle/0001_extensions.sql +63 -0
- package/drizzle/meta/0000_snapshot.json +134 -0
- package/drizzle/meta/0001_snapshot.json +526 -0
- package/drizzle/meta/_journal.json +20 -0
- package/package.json +63 -0
- package/skills/skill-authoring/SKILL.md +168 -0
- package/skills/workflow-authoring/SKILL.md +251 -0
package/README.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Tachikoma
|
|
2
|
+
|
|
3
|
+
Tachikoma is a proactive personal assistant built on the [pi agent SDK](https://github.com/earendil-works/pi). It maintains persistent memory across conversations, extracts learnings automatically, handles background tasks during idle time, and is reachable through Telegram or a local REPL.
|
|
4
|
+
|
|
5
|
+
The core is deliberately thin — config, database, scheduler, channels, session orchestration, and an extension host — and **every feature is an extension**: memory, conversation boundary detection, skills, workflows, scheduled tasks, project tracking, git-versioned workspace, Telegram, detached process supervision, notifications, and external extension loading (out-of-tree extensions on the same contract, installable from git).
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm i -g @asermax/tachikoma
|
|
11
|
+
tachikoma # start the agent (REPL channel)
|
|
12
|
+
tachikoma -c telegram
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Releases are published automatically: `just release` bumps the version and tags via commit-and-tag-version, then `git push --follow-tags` triggers the publish workflow. Maintainers must configure an `NPM_TOKEN` repository secret with publish access to the `@asermax` scope.
|
|
16
|
+
|
|
17
|
+
## Requirements
|
|
18
|
+
|
|
19
|
+
- Node.js >= 22.19 (the project runs TypeScript sources directly via native type stripping)
|
|
20
|
+
- pnpm
|
|
21
|
+
- LLM provider credentials: an existing [pi](https://pi.dev) login (`~/.pi/agent/auth.json`) is picked up automatically, or set a provider key like `ANTHROPIC_API_KEY` in the environment
|
|
22
|
+
|
|
23
|
+
## Quick start
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
just install # pnpm install
|
|
27
|
+
just run # start the agent (REPL channel)
|
|
28
|
+
just run -c telegram # start with the Telegram channel
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
On first run a commented config file is generated at `~/.config/tachikoma/config.toml` and the workspace at `~/tachikoma` is initialized (SOUL.md, USER.md, memory layout, git repo).
|
|
32
|
+
|
|
33
|
+
## Configuration
|
|
34
|
+
|
|
35
|
+
TOML at `~/.config/tachikoma/config.toml`. Core sections: `[workspace]`, `[agent]` (optional per-role models as `provider/model-id[:thinkingLevel]` — anything unset defers to pi), `[logging]`, `[channels]`, `[sessions]`, `[scheduler]`. pi-level knobs (default model, thinking budgets, compaction, retry, custom providers) live in pi's own `settings.json`/`models.json` under `{workspace}/.tachikoma/pi/`. Each extension reads its own `[extensions.<name>]` section — see the generated file and the feature specs in `docs/feature-specs/`.
|
|
36
|
+
|
|
37
|
+
## Development
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
just check # lint + typecheck + tests (run before considering anything done)
|
|
41
|
+
just test # vitest
|
|
42
|
+
just lint # biome check
|
|
43
|
+
just fmt # biome check --write
|
|
44
|
+
just typecheck # tsc --noEmit
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Database migrations: schema lives in `src/db/schema.ts` (aggregating per-extension `schema.ts` modules); generate migrations with `pnpm drizzle-kit generate` — they apply automatically at startup.
|
|
48
|
+
|
|
49
|
+
## Architecture
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
Channel (telegram/repl extension)
|
|
53
|
+
→ Coordinator (core): inbound middleware → session ensure/resume
|
|
54
|
+
→ context providers (parallel) → pi AgentSession prompt
|
|
55
|
+
→ AgentEvents streamed back to the channel
|
|
56
|
+
→ exchange processors (rolling summary, …)
|
|
57
|
+
→ on idle close: post-processing phases (memory extraction, git commit, …)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
- **Extensions** implement features through one contract (`defineExtension`) with app-level hooks (scheduler, db, sessions, channels) and pi-native session hooks (`app.agent.use((pi) => …)`). Start at `docs/design/DES-001-unified-extension-api.md` and `DES-002-extension-authoring.md`.
|
|
61
|
+
- **pi SDK ground truth** for this codebase: `docs/reference/pi-sdk-notes.md`.
|
|
62
|
+
- **Planning docs**: `docs/planning/VISION.md`, `docs/planning/DELTAS.md`; decisions in `docs/architecture/ADR-*`; feature documentation under `docs/feature-specs/` and `docs/feature-designs/`.
|
|
63
|
+
|
|
64
|
+
The agent's pi state (sessions, settings) lives isolated under `{workspace}/.tachikoma/pi`, so it never interferes with a personal pi installation; provider credentials are shared from the machine-level pi login when present.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AgentSession } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import type { AgentEvent } from "../domain/agent-events.ts";
|
|
3
|
+
/**
|
|
4
|
+
* Run one prompt against a pi session, exposing the stream as domain AgentEvents.
|
|
5
|
+
* The iterator completes only after pi's prompt() promise settles, so consumers
|
|
6
|
+
* can treat iteration end as exchange end.
|
|
7
|
+
*/
|
|
8
|
+
export declare const streamPrompt: (session: AgentSession, text: string) => AsyncIterable<AgentEvent>;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
const mapSessionEvent = (event) => {
|
|
2
|
+
switch (event.type) {
|
|
3
|
+
case "message_update": {
|
|
4
|
+
const update = event.assistantMessageEvent;
|
|
5
|
+
if (update.type === "text_delta")
|
|
6
|
+
return { kind: "text", text: update.delta };
|
|
7
|
+
if (update.type === "thinking_delta")
|
|
8
|
+
return { kind: "thinking", text: update.delta };
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
case "tool_execution_start":
|
|
12
|
+
return {
|
|
13
|
+
kind: "tool-start",
|
|
14
|
+
toolCallId: event.toolCallId,
|
|
15
|
+
toolName: event.toolName,
|
|
16
|
+
args: (event.args ?? {}),
|
|
17
|
+
};
|
|
18
|
+
case "tool_execution_end":
|
|
19
|
+
return {
|
|
20
|
+
kind: "tool-end",
|
|
21
|
+
toolCallId: event.toolCallId,
|
|
22
|
+
toolName: event.toolName,
|
|
23
|
+
isError: event.isError,
|
|
24
|
+
};
|
|
25
|
+
case "compaction_start":
|
|
26
|
+
return { kind: "status", text: "Compacting conversation…" };
|
|
27
|
+
case "auto_retry_start":
|
|
28
|
+
return { kind: "status", text: "Provider hiccup — retrying…" };
|
|
29
|
+
default:
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Run one prompt against a pi session, exposing the stream as domain AgentEvents.
|
|
35
|
+
* The iterator completes only after pi's prompt() promise settles, so consumers
|
|
36
|
+
* can treat iteration end as exchange end.
|
|
37
|
+
*/
|
|
38
|
+
export const streamPrompt = (session, text) => {
|
|
39
|
+
const queue = [];
|
|
40
|
+
let wake = null;
|
|
41
|
+
let finished = false;
|
|
42
|
+
let failure = null;
|
|
43
|
+
const push = (event) => {
|
|
44
|
+
if (event != null)
|
|
45
|
+
queue.push(event);
|
|
46
|
+
wake?.();
|
|
47
|
+
wake = null;
|
|
48
|
+
};
|
|
49
|
+
const unsubscribe = session.subscribe((event) => push(mapSessionEvent(event)));
|
|
50
|
+
const run = session
|
|
51
|
+
.prompt(text)
|
|
52
|
+
.catch((error) => {
|
|
53
|
+
failure = error;
|
|
54
|
+
})
|
|
55
|
+
.finally(() => {
|
|
56
|
+
finished = true;
|
|
57
|
+
push(null);
|
|
58
|
+
});
|
|
59
|
+
return (async function* () {
|
|
60
|
+
try {
|
|
61
|
+
while (true) {
|
|
62
|
+
while (queue.length > 0)
|
|
63
|
+
yield queue.shift();
|
|
64
|
+
if (finished)
|
|
65
|
+
break;
|
|
66
|
+
await new Promise((resolve) => {
|
|
67
|
+
wake = resolve;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
if (failure != null) {
|
|
71
|
+
yield {
|
|
72
|
+
kind: "error",
|
|
73
|
+
message: failure instanceof Error ? failure.message : String(failure),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
yield { kind: "result", stopReason: "done" };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
unsubscribe();
|
|
82
|
+
await run;
|
|
83
|
+
}
|
|
84
|
+
})();
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/agent/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type AgentSession, AuthStorage, type ExtensionFactory, ModelRegistry, SettingsManager, type ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import type { Config } from "../config/schema.ts";
|
|
3
|
+
import type { Logger } from "../log.ts";
|
|
4
|
+
import type { Workspace } from "../workspace.ts";
|
|
5
|
+
import { type ModelTier, ModelTiers } from "./models.ts";
|
|
6
|
+
export interface AgentSessionSources {
|
|
7
|
+
piFactories: ExtensionFactory[];
|
|
8
|
+
systemPromptBuilders: (() => string)[];
|
|
9
|
+
}
|
|
10
|
+
export interface OpenSessionOptions {
|
|
11
|
+
/** Resume from an existing pi session file instead of starting fresh. */
|
|
12
|
+
sessionFile?: string | null;
|
|
13
|
+
/** Ephemeral side session: nothing persisted to disk. */
|
|
14
|
+
inMemory?: boolean;
|
|
15
|
+
/** Skip registered extension factories and system prompt builders (headless side work). */
|
|
16
|
+
bare?: boolean;
|
|
17
|
+
tools?: string[];
|
|
18
|
+
customTools?: ToolDefinition[];
|
|
19
|
+
systemPrompt?: string;
|
|
20
|
+
tier?: ModelTier;
|
|
21
|
+
}
|
|
22
|
+
export declare class AgentManager {
|
|
23
|
+
readonly authStorage: AuthStorage;
|
|
24
|
+
readonly modelRegistry: ModelRegistry;
|
|
25
|
+
readonly settingsManager: SettingsManager;
|
|
26
|
+
readonly tiers: ModelTiers;
|
|
27
|
+
private readonly workspace;
|
|
28
|
+
private readonly sources;
|
|
29
|
+
private readonly log;
|
|
30
|
+
constructor(workspace: Workspace, config: Config, sources: AgentSessionSources, log: Logger);
|
|
31
|
+
apiKeyFor(provider: string): Promise<string | undefined>;
|
|
32
|
+
/** Open the main conversational session, with all registered extensions bound. */
|
|
33
|
+
open(options?: OpenSessionOptions): Promise<AgentSession>;
|
|
34
|
+
private composeSystemPrompt;
|
|
35
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { existsSync, statSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { AuthStorage, createAgentSession, DefaultResourceLoader, ModelRegistry, SessionManager, SettingsManager, } from "@earendil-works/pi-coding-agent";
|
|
4
|
+
import { ModelTiers } from "./models.js";
|
|
5
|
+
export class AgentManager {
|
|
6
|
+
authStorage;
|
|
7
|
+
modelRegistry;
|
|
8
|
+
settingsManager;
|
|
9
|
+
tiers;
|
|
10
|
+
workspace;
|
|
11
|
+
sources;
|
|
12
|
+
log;
|
|
13
|
+
constructor(workspace, config, sources, log) {
|
|
14
|
+
this.workspace = workspace;
|
|
15
|
+
this.sources = sources;
|
|
16
|
+
this.log = log;
|
|
17
|
+
// Credentials are machine-level: prefer a workspace-local auth.json when it has
|
|
18
|
+
// actual content, otherwise share the user's existing pi login (~/.pi/agent/auth.json).
|
|
19
|
+
const localAuth = join(workspace.piDir, "auth.json");
|
|
20
|
+
const hasLocalAuth = existsSync(localAuth) && statSync(localAuth).size > 2;
|
|
21
|
+
this.authStorage = hasLocalAuth ? AuthStorage.create(localAuth) : AuthStorage.create();
|
|
22
|
+
this.modelRegistry = ModelRegistry.create(this.authStorage, join(workspace.piDir, "models.json"));
|
|
23
|
+
this.settingsManager = SettingsManager.create(workspace.root, workspace.piDir);
|
|
24
|
+
this.tiers = new ModelTiers(config.agent, this.modelRegistry, this.settingsManager);
|
|
25
|
+
}
|
|
26
|
+
async apiKeyFor(provider) {
|
|
27
|
+
return (await this.authStorage.getApiKey(provider)) ?? undefined;
|
|
28
|
+
}
|
|
29
|
+
/** Open the main conversational session, with all registered extensions bound. */
|
|
30
|
+
async open(options = {}) {
|
|
31
|
+
const workspace = this.workspace;
|
|
32
|
+
const bare = options.bare === true;
|
|
33
|
+
const systemPromptOverride = options.systemPrompt ??
|
|
34
|
+
(!bare && this.sources.systemPromptBuilders.length > 0
|
|
35
|
+
? this.composeSystemPrompt()
|
|
36
|
+
: undefined);
|
|
37
|
+
const loader = new DefaultResourceLoader({
|
|
38
|
+
cwd: workspace.root,
|
|
39
|
+
agentDir: workspace.piDir,
|
|
40
|
+
extensionFactories: bare ? [] : [...this.sources.piFactories],
|
|
41
|
+
...(systemPromptOverride != null ? { systemPromptOverride: () => systemPromptOverride } : {}),
|
|
42
|
+
});
|
|
43
|
+
await loader.reload();
|
|
44
|
+
const sessionManager = options.inMemory === true
|
|
45
|
+
? SessionManager.inMemory(workspace.root)
|
|
46
|
+
: options.sessionFile != null
|
|
47
|
+
? SessionManager.open(options.sessionFile, workspace.sessionsDir)
|
|
48
|
+
: SessionManager.create(workspace.root, workspace.sessionsDir);
|
|
49
|
+
// A configured role pins the model (and optional thinking suffix); an unset
|
|
50
|
+
// chain omits both so pi's full resolution applies — session restore first,
|
|
51
|
+
// then settings defaults, then the first credentialed model.
|
|
52
|
+
const tier = options.tier ?? "main";
|
|
53
|
+
const configured = this.tiers.configuredRef(tier) != null ? this.tiers.resolve(tier) : null;
|
|
54
|
+
const { session, modelFallbackMessage } = await createAgentSession({
|
|
55
|
+
cwd: workspace.root,
|
|
56
|
+
agentDir: workspace.piDir,
|
|
57
|
+
...(configured != null ? { model: configured.model } : {}),
|
|
58
|
+
...(configured?.thinkingLevel != null ? { thinkingLevel: configured.thinkingLevel } : {}),
|
|
59
|
+
...(options.tools != null ? { tools: options.tools } : {}),
|
|
60
|
+
...(options.customTools != null ? { customTools: options.customTools } : {}),
|
|
61
|
+
resourceLoader: loader,
|
|
62
|
+
sessionManager,
|
|
63
|
+
settingsManager: this.settingsManager,
|
|
64
|
+
authStorage: this.authStorage,
|
|
65
|
+
modelRegistry: this.modelRegistry,
|
|
66
|
+
});
|
|
67
|
+
if (modelFallbackMessage != null) {
|
|
68
|
+
this.log.warn({ modelFallbackMessage }, "model fallback on session open");
|
|
69
|
+
}
|
|
70
|
+
return session;
|
|
71
|
+
}
|
|
72
|
+
composeSystemPrompt() {
|
|
73
|
+
return this.sources.systemPromptBuilders.map((build) => build()).join("\n\n");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/agent/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ModelRegistry, SettingsManager } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import type { Config, ThinkingLevel } from "../config/schema.ts";
|
|
3
|
+
export declare const MODEL_TIERS: {
|
|
4
|
+
/** Main conversational agent. */
|
|
5
|
+
readonly main: "main";
|
|
6
|
+
/** Retrieval and routing work. */
|
|
7
|
+
readonly searcher: "searcher";
|
|
8
|
+
/** Extraction and mechanical transformation. */
|
|
9
|
+
readonly processor: "processor";
|
|
10
|
+
/** Discrete classification with structured output. */
|
|
11
|
+
readonly classifier: "classifier";
|
|
12
|
+
};
|
|
13
|
+
export type ModelTier = keyof typeof MODEL_TIERS;
|
|
14
|
+
export interface ModelRef {
|
|
15
|
+
provider: string;
|
|
16
|
+
id: string;
|
|
17
|
+
thinkingLevel?: ThinkingLevel;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Parse "provider/model-id[:thinkingLevel]". The suffix is only treated as a
|
|
21
|
+
* thinking level when it names one — model ids may legitimately contain colons
|
|
22
|
+
* (e.g. ollama's "llama3:8b").
|
|
23
|
+
*/
|
|
24
|
+
export declare const parseModelRef: (ref: string) => ModelRef;
|
|
25
|
+
export interface ResolvedTier {
|
|
26
|
+
model: NonNullable<ReturnType<ModelRegistry["find"]>>;
|
|
27
|
+
thinkingLevel?: ThinkingLevel;
|
|
28
|
+
/** True when nothing was configured and pi's own default resolution applied. */
|
|
29
|
+
fromPiDefaults: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Per-role model selection. Roles left unset in `[agent]` fall back along
|
|
33
|
+
* classifier → processor → main (searcher → main); a fully unset chain defers
|
|
34
|
+
* to pi's own resolution: settings defaultProvider/defaultModel, else the
|
|
35
|
+
* first credentialed model.
|
|
36
|
+
*/
|
|
37
|
+
export declare class ModelTiers {
|
|
38
|
+
private readonly agentConfig;
|
|
39
|
+
private readonly registry;
|
|
40
|
+
private readonly settings;
|
|
41
|
+
constructor(agentConfig: Config["agent"], registry: ModelRegistry, settings: SettingsManager);
|
|
42
|
+
/** The configured reference for a tier after applying the fallback chain, if any. */
|
|
43
|
+
configuredRef(tier: ModelTier): ModelRef | null;
|
|
44
|
+
resolve(tier: ModelTier): ResolvedTier;
|
|
45
|
+
private resolvePiDefault;
|
|
46
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
export const MODEL_TIERS = {
|
|
2
|
+
/** Main conversational agent. */
|
|
3
|
+
main: "main",
|
|
4
|
+
/** Retrieval and routing work. */
|
|
5
|
+
searcher: "searcher",
|
|
6
|
+
/** Extraction and mechanical transformation. */
|
|
7
|
+
processor: "processor",
|
|
8
|
+
/** Discrete classification with structured output. */
|
|
9
|
+
classifier: "classifier",
|
|
10
|
+
};
|
|
11
|
+
const THINKING_LEVELS = new Set(["off", "minimal", "low", "medium", "high", "xhigh"]);
|
|
12
|
+
/**
|
|
13
|
+
* Parse "provider/model-id[:thinkingLevel]". The suffix is only treated as a
|
|
14
|
+
* thinking level when it names one — model ids may legitimately contain colons
|
|
15
|
+
* (e.g. ollama's "llama3:8b").
|
|
16
|
+
*/
|
|
17
|
+
export const parseModelRef = (ref) => {
|
|
18
|
+
const slash = ref.indexOf("/");
|
|
19
|
+
if (slash <= 0 || slash === ref.length - 1) {
|
|
20
|
+
throw new Error(`Invalid model reference "${ref}" — expected "provider/model-id[:thinkingLevel]"`);
|
|
21
|
+
}
|
|
22
|
+
const provider = ref.slice(0, slash);
|
|
23
|
+
let id = ref.slice(slash + 1);
|
|
24
|
+
let thinkingLevel;
|
|
25
|
+
const colon = id.lastIndexOf(":");
|
|
26
|
+
if (colon > 0 && THINKING_LEVELS.has(id.slice(colon + 1))) {
|
|
27
|
+
thinkingLevel = id.slice(colon + 1);
|
|
28
|
+
id = id.slice(0, colon);
|
|
29
|
+
}
|
|
30
|
+
return { provider, id, ...(thinkingLevel != null ? { thinkingLevel } : {}) };
|
|
31
|
+
};
|
|
32
|
+
const FALLBACK_CHAIN = {
|
|
33
|
+
main: ["main"],
|
|
34
|
+
searcher: ["searcher", "main"],
|
|
35
|
+
processor: ["processor", "main"],
|
|
36
|
+
classifier: ["classifier", "processor", "main"],
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Per-role model selection. Roles left unset in `[agent]` fall back along
|
|
40
|
+
* classifier → processor → main (searcher → main); a fully unset chain defers
|
|
41
|
+
* to pi's own resolution: settings defaultProvider/defaultModel, else the
|
|
42
|
+
* first credentialed model.
|
|
43
|
+
*/
|
|
44
|
+
export class ModelTiers {
|
|
45
|
+
agentConfig;
|
|
46
|
+
registry;
|
|
47
|
+
settings;
|
|
48
|
+
constructor(agentConfig, registry, settings) {
|
|
49
|
+
this.agentConfig = agentConfig;
|
|
50
|
+
this.registry = registry;
|
|
51
|
+
this.settings = settings;
|
|
52
|
+
}
|
|
53
|
+
/** The configured reference for a tier after applying the fallback chain, if any. */
|
|
54
|
+
configuredRef(tier) {
|
|
55
|
+
for (const candidate of FALLBACK_CHAIN[tier]) {
|
|
56
|
+
const raw = this.agentConfig[candidate];
|
|
57
|
+
if (raw != null)
|
|
58
|
+
return parseModelRef(raw);
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
resolve(tier) {
|
|
63
|
+
const ref = this.configuredRef(tier);
|
|
64
|
+
if (ref != null) {
|
|
65
|
+
const model = this.registry.find(ref.provider, ref.id);
|
|
66
|
+
if (model == null) {
|
|
67
|
+
throw new Error(`Model "${ref.provider}/${ref.id}" (${tier} tier) not found in pi's model registry`);
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
model,
|
|
71
|
+
...(ref.thinkingLevel != null ? { thinkingLevel: ref.thinkingLevel } : {}),
|
|
72
|
+
fromPiDefaults: false,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return { ...this.resolvePiDefault(tier), fromPiDefaults: true };
|
|
76
|
+
}
|
|
77
|
+
resolvePiDefault(tier) {
|
|
78
|
+
const provider = this.settings.getDefaultProvider();
|
|
79
|
+
const id = this.settings.getDefaultModel();
|
|
80
|
+
const thinkingLevel = this.settings.getDefaultThinkingLevel();
|
|
81
|
+
if (provider != null && id != null) {
|
|
82
|
+
const model = this.registry.find(provider, id);
|
|
83
|
+
if (model != null) {
|
|
84
|
+
return { model, ...(thinkingLevel != null ? { thinkingLevel } : {}) };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const available = this.registry.getAvailable();
|
|
88
|
+
const first = available[0];
|
|
89
|
+
if (first == null) {
|
|
90
|
+
throw new Error(`No model available for the ${tier} tier: set [agent].${tier} in config.toml, ` +
|
|
91
|
+
"a default model in pi's settings.json, or provider credentials");
|
|
92
|
+
}
|
|
93
|
+
return { model: first, ...(thinkingLevel != null ? { thinkingLevel } : {}) };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/agent/models.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import type { Static, TSchema } from "typebox";
|
|
3
|
+
import type { Logger } from "../log.ts";
|
|
4
|
+
import type { AgentManager } from "./manager.ts";
|
|
5
|
+
import type { ModelTier } from "./models.ts";
|
|
6
|
+
export interface ClassifyOptions<S extends TSchema> {
|
|
7
|
+
system: string;
|
|
8
|
+
user: string;
|
|
9
|
+
schema: S;
|
|
10
|
+
tier?: ModelTier;
|
|
11
|
+
}
|
|
12
|
+
export interface CompleteOptions {
|
|
13
|
+
system?: string;
|
|
14
|
+
user: string;
|
|
15
|
+
tier?: ModelTier;
|
|
16
|
+
}
|
|
17
|
+
export interface HeadlessRunOptions {
|
|
18
|
+
prompt: string;
|
|
19
|
+
system?: string;
|
|
20
|
+
/** pi built-in tool names the run may use (e.g. ["read", "grep"]). Default: none. */
|
|
21
|
+
tools?: string[];
|
|
22
|
+
/** Extra in-process tools for this run (their names are enabled automatically). */
|
|
23
|
+
customTools?: ToolDefinition[];
|
|
24
|
+
tier?: ModelTier;
|
|
25
|
+
}
|
|
26
|
+
export interface HeadlessRunResult {
|
|
27
|
+
text: string;
|
|
28
|
+
}
|
|
29
|
+
/** Side-channel LLM work outside the conversational session: classification and one-shot completions. */
|
|
30
|
+
export declare class SideRunner {
|
|
31
|
+
private readonly manager;
|
|
32
|
+
private readonly log;
|
|
33
|
+
constructor(manager: AgentManager, log: Logger);
|
|
34
|
+
complete({ system, user, tier }: CompleteOptions): Promise<string>;
|
|
35
|
+
/**
|
|
36
|
+
* Headless agent run in an ephemeral pi session: tool use allowed, nothing persisted,
|
|
37
|
+
* no Tachikoma extensions bound. Returns the final assistant text.
|
|
38
|
+
*/
|
|
39
|
+
run({ prompt, system, tools, customTools, tier, }: HeadlessRunOptions): Promise<HeadlessRunResult>;
|
|
40
|
+
/** Structured classification: instructs JSON output matching the schema, parses, retries once. */
|
|
41
|
+
classify<S extends TSchema>({ system, user, schema, tier, }: ClassifyOptions<S>): Promise<Static<S>>;
|
|
42
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { completeSimple } from "@earendil-works/pi-ai";
|
|
2
|
+
import { parseWithSchema } from "../config/parse.js";
|
|
3
|
+
const textOf = (message) => message.content
|
|
4
|
+
.filter((block) => block.type === "text")
|
|
5
|
+
.map((block) => block.text)
|
|
6
|
+
.join("");
|
|
7
|
+
const extractJson = (text) => {
|
|
8
|
+
const fenced = text.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
9
|
+
if (fenced?.[1] != null)
|
|
10
|
+
return fenced[1].trim();
|
|
11
|
+
const start = text.indexOf("{");
|
|
12
|
+
const end = text.lastIndexOf("}");
|
|
13
|
+
if (start >= 0 && end > start)
|
|
14
|
+
return text.slice(start, end + 1);
|
|
15
|
+
return text.trim();
|
|
16
|
+
};
|
|
17
|
+
/** Side-channel LLM work outside the conversational session: classification and one-shot completions. */
|
|
18
|
+
export class SideRunner {
|
|
19
|
+
manager;
|
|
20
|
+
log;
|
|
21
|
+
constructor(manager, log) {
|
|
22
|
+
this.manager = manager;
|
|
23
|
+
this.log = log;
|
|
24
|
+
}
|
|
25
|
+
async complete({ system, user, tier = "processor" }) {
|
|
26
|
+
const { model, fromPiDefaults } = this.manager.tiers.resolve(tier);
|
|
27
|
+
if (fromPiDefaults) {
|
|
28
|
+
this.log.debug({ tier, model: `${model.provider}/${model.id}` }, "tier unset — using pi default model");
|
|
29
|
+
}
|
|
30
|
+
const apiKey = await this.manager.apiKeyFor(model.provider);
|
|
31
|
+
const messages = [
|
|
32
|
+
{ role: "user", content: [{ type: "text", text: user }], timestamp: Date.now() },
|
|
33
|
+
];
|
|
34
|
+
const result = await completeSimple(model, { ...(system != null ? { systemPrompt: system } : {}), messages }, apiKey != null ? { apiKey } : undefined);
|
|
35
|
+
if (result.stopReason === "error" || result.stopReason === "aborted") {
|
|
36
|
+
throw new Error(`side completion failed: ${result.errorMessage ?? result.stopReason}`);
|
|
37
|
+
}
|
|
38
|
+
return textOf(result);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Headless agent run in an ephemeral pi session: tool use allowed, nothing persisted,
|
|
42
|
+
* no Tachikoma extensions bound. Returns the final assistant text.
|
|
43
|
+
*/
|
|
44
|
+
async run({ prompt, system, tools = [], customTools, tier = "processor", }) {
|
|
45
|
+
const session = await this.manager.open({
|
|
46
|
+
inMemory: true,
|
|
47
|
+
bare: true,
|
|
48
|
+
tier,
|
|
49
|
+
tools: [...tools, ...(customTools ?? []).map((tool) => tool.name)],
|
|
50
|
+
...(customTools != null ? { customTools } : {}),
|
|
51
|
+
...(system != null ? { systemPrompt: system } : {}),
|
|
52
|
+
});
|
|
53
|
+
try {
|
|
54
|
+
await session.prompt(prompt);
|
|
55
|
+
for (let index = session.messages.length - 1; index >= 0; index -= 1) {
|
|
56
|
+
const message = session.messages[index];
|
|
57
|
+
if (message == null || message.role !== "assistant")
|
|
58
|
+
continue;
|
|
59
|
+
return { text: textOf(message) };
|
|
60
|
+
}
|
|
61
|
+
return { text: "" };
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
session.dispose();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/** Structured classification: instructs JSON output matching the schema, parses, retries once. */
|
|
68
|
+
async classify({ system, user, schema, tier = "classifier", }) {
|
|
69
|
+
const instruction = `${system}\n\nRespond with a single JSON object matching this JSON Schema — no prose:\n${JSON.stringify(schema)}`;
|
|
70
|
+
const attempt = async (extra) => {
|
|
71
|
+
const text = await this.complete({ system: instruction, user: `${user}${extra}`, tier });
|
|
72
|
+
return parseWithSchema(schema, JSON.parse(extractJson(text)), "classification output");
|
|
73
|
+
};
|
|
74
|
+
try {
|
|
75
|
+
return await attempt("");
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
this.log.debug({ err: error }, "classification parse failed — retrying once");
|
|
79
|
+
return attempt("\n\n(Reminder: output ONLY the JSON object, nothing else.)");
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=side-run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"side-run.js","sourceRoot":"","sources":["../../src/agent/side-run.ts"],"names":[],"mappings":"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"}
|