arisa 4.3.5 → 5.1.2
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/AGENTS.md +21 -19
- package/README.md +30 -9
- package/package.json +6 -2
- package/pnpm-workspace.yaml +1 -0
- package/src/core/agent/agent-manager.js +288 -29
- package/src/core/agent/auth-flow.js +12 -8
- package/src/core/agent/model-selection.js +54 -14
- package/src/core/agent/model-speed.js +59 -0
- package/src/core/config/config-defaults.js +56 -4
- package/src/core/config/config-store.js +5 -1
- package/src/core/conversation/conversation-history-store.js +142 -0
- package/src/core/tasks/task-store.js +16 -0
- package/src/core/tools/daemon-health.js +11 -2
- package/src/core/tools/daemon-processes.js +92 -2
- package/src/core/tools/daemon-runtime.js +4 -2
- package/src/core/tools/ipc-client.js +15 -3
- package/src/core/tools/tool-registry.js +42 -2
- package/src/core/tools/tool-usage-store.js +59 -0
- package/src/index.js +61 -6
- package/src/runtime/arisa-capabilities.js +45 -1
- package/src/runtime/bootstrap.js +3 -2
- package/src/runtime/create-app.js +49 -11
- package/src/runtime/doctor.js +365 -0
- package/src/runtime/log-viewer.js +165 -0
- package/src/runtime/paths.js +8 -1
- package/src/runtime/report-format.js +51 -0
- package/src/runtime/service-manager.js +106 -8
- package/src/runtime/tool-process-supervisor.js +107 -10
- package/src/runtime/tool-usage-report.js +10 -0
- package/src/runtime/update-manager.js +206 -0
- package/src/transport/telegram/bot.js +633 -91
- package/src/transport/telegram/model-picker.js +28 -2
- package/test/agent-tool-policy.test.js +26 -1
- package/test/auth-flow.test.js +28 -2
- package/test/capabilities-security.test.js +37 -0
- package/test/context-and-task-bounds.test.js +280 -0
- package/test/daemon-runtime.test.js +130 -2
- package/test/dependency-warnings.test.js +17 -0
- package/test/doctor.test.js +111 -0
- package/test/log-viewer.test.js +90 -0
- package/test/model-selection.test.js +125 -2
- package/test/paths.test.js +16 -0
- package/test/pi-compaction.test.js +43 -0
- package/test/service-manager.test.js +237 -0
- package/test/task-store.test.js +31 -0
- package/test/telegram-text-artifact.test.js +36 -1
- package/test/tool-registry-run.test.js +21 -0
- package/test/tool-usage.test.js +37 -0
- package/test/update-manager.test.js +87 -0
package/AGENTS.md
CHANGED
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
## Core boundaries
|
|
4
4
|
Arisa core owns transport, sessions, artifacts, and tool orchestration:
|
|
5
5
|
- Telegram transport handles inbound and outbound messaging.
|
|
6
|
-
- Pi Agent keeps one session per authorized chat.
|
|
6
|
+
- Pi Agent keeps one session per authorized chat and is the only active harness.
|
|
7
7
|
- Incoming messages and files (text, voice, photo, document) and generated files become artifacts.
|
|
8
8
|
- The tool registry handles tool discovery, help lookup, config writes, and execution.
|
|
9
9
|
- Tools are isolated packages with their own manifest, entrypoint, and config defaults.
|
|
10
10
|
- No tools ship with the core; installed tools live under `~/.arisa/tools/<toolName>`.
|
|
11
11
|
- The Arisa install directory (your working directory) contains only the core. Never create or install tools inside it.
|
|
12
|
+
- Restart requests use `system_shell` to run `arisa restart`; do not install or create a restart tool.
|
|
12
13
|
|
|
13
14
|
New capabilities belong in tools by default. Solve requests by creating or editing a tool under `~/.arisa/tools/<toolName>`. Modifying core is the last resort: do it only after confirming the capability cannot be delivered through the tool architecture, explaining why the core change is unavoidable, and receiving explicit user approval.
|
|
14
15
|
|
|
@@ -48,9 +49,10 @@ Each tool declares in `tool.manifest.json`:
|
|
|
48
49
|
- `skillHints`: optional skills to apply when using or editing the tool
|
|
49
50
|
|
|
50
51
|
## Text encoding
|
|
51
|
-
All textual content generated or sent by Arisa or its tools must use UTF-8.
|
|
52
|
+
All textual content generated or sent by Arisa or its tools must use UTF-8.
|
|
52
53
|
|
|
53
|
-
-
|
|
54
|
+
- User-facing text documents and exports in `.txt`, `.md`, or `.csv` format must start with a UTF-8 byte-order mark (BOM).
|
|
55
|
+
- Source code, repository documentation, configuration, manifests, and structured data must use UTF-8 without BOM.
|
|
54
56
|
- Protocol payloads must declare UTF-8 through the protocol's standard mechanism and encode their bytes as UTF-8. For example, email and HTTP text content must use a `Content-Type` with `charset=UTF-8`.
|
|
55
57
|
|
|
56
58
|
## Tool-to-Arisa IPC
|
|
@@ -74,37 +76,37 @@ const result = await arisa.tools.run({
|
|
|
74
76
|
}, { timeoutMs: 120_000 });
|
|
75
77
|
```
|
|
76
78
|
|
|
77
|
-
The IPC channel is a local socket under `~/.arisa/state`. Every request must include `toolName`; chat-scoped capabilities also require `chatId`. Exposed capabilities are explicit: tools (`run`), artifacts (`createText`, `listRecent`, `get`), tasks (`add`, `list`, `cancel`), agent events (`enqueueEvent`), and runtime paths (`getChatToolStateDir`, `getToolStateDir`, `getChatToolTmpDir`, `getToolTmpDir`, `getChatArtifactsDir`). Do not expose raw `agentManager`, `taskStore`, `artifactStore`, or `toolRegistry` access.
|
|
79
|
+
The IPC channel is a local socket under `~/.arisa/state`. Every request must include `toolName`; chat-scoped capabilities also require `chatId`. Exposed capabilities are explicit: tools (`list`, `help`, `skills`, `setConfig`, `run`), artifacts (`createText`, `listRecent`, `get`, `deliver`), tasks (`add`, `list`, `cancel`, `cancelAll`), agent events (`enqueueEvent`), and runtime paths (`getChatToolStateDir`, `getToolStateDir`, `getChatToolTmpDir`, `getToolTmpDir`, `getChatArtifactsDir`). Do not expose raw `agentManager`, `taskStore`, `artifactStore`, or `toolRegistry` access.
|
|
78
80
|
|
|
79
81
|
## Conceptual pipe model
|
|
80
82
|
There are two different moments where pipes can happen:
|
|
81
83
|
|
|
82
84
|
1. **Pre-reasoning normalization pipes**
|
|
83
|
-
- These happen before
|
|
84
|
-
- Their job is to convert raw inbound media into a form
|
|
85
|
+
- These happen before the active agent runtime reasons.
|
|
86
|
+
- Their job is to convert raw inbound media into a form the agent can reason about well.
|
|
85
87
|
- Example: incoming Telegram audio must be transcribed first.
|
|
86
|
-
- In that case, the transcript becomes the effective user message content for
|
|
87
|
-
-
|
|
88
|
+
- In that case, the transcript becomes the effective user message content for the agent.
|
|
89
|
+
- The agent should reason over the transcript, not treat the raw audio as the primary message.
|
|
88
90
|
|
|
89
91
|
2. **Reasoned action pipes**
|
|
90
|
-
- These happen after
|
|
91
|
-
-
|
|
92
|
+
- These happen after the agent starts reasoning.
|
|
93
|
+
- The agent may decide to chain tools to achieve a user goal.
|
|
92
94
|
- Example: text -> TTS audio, or future multi-step workflows.
|
|
93
95
|
|
|
94
|
-
Not every pipe should be decided by
|
|
96
|
+
Not every pipe should be decided by the agent at runtime. Some pipes are part of the transport/input normalization layer and must happen before reasoning.
|
|
95
97
|
|
|
96
98
|
## Telegram inbound pipeline
|
|
97
|
-
- text -> send directly to
|
|
98
|
-
- voice -> transcribe first -> send transcript to
|
|
99
|
+
- text -> send directly to the active agent runtime
|
|
100
|
+
- voice -> transcribe first -> send transcript to the active agent runtime
|
|
99
101
|
- image/document/other media -> keep as artifacts, and add normalization pipes when needed
|
|
100
102
|
|
|
101
|
-
If inbound media was normalized before reasoning,
|
|
102
|
-
For example, if a voice note was transcribed,
|
|
103
|
+
If inbound media was normalized before reasoning, the agent should use the normalized result as the actual message content.
|
|
104
|
+
For example, if a voice note was transcribed, the agent should answer the meaning of the transcript, not simply return the raw transcript unless the user explicitly asked for transcription.
|
|
103
105
|
|
|
104
106
|
## Telegram outbound replies
|
|
105
107
|
- Short textual replies are sent inline as a normal Telegram message.
|
|
106
108
|
- When a textual reply is too large to read comfortably inline, it is delivered as a generated Markdown artifact instead of a long inline message. The transport handles this automatically in `sendTextReply`: replies over the inline length limit become a `reply-<timestamp>.md` artifact sent as a document.
|
|
107
|
-
- This is a transport-layer concern.
|
|
109
|
+
- This is a transport-layer concern. The agent should write the full answer it wants to deliver and not pre-split or truncate it to fit the chat; the transport decides between inline text and a Markdown attachment.
|
|
108
110
|
|
|
109
111
|
## How to inspect CLI tools
|
|
110
112
|
Before using a tool, inspect its help:
|
|
@@ -152,11 +154,11 @@ Example manual pipe:
|
|
|
152
154
|
Delivery is generic: any `run_tool` output that produces a file becomes an artifact, and `send_artifact(artifactId)` delivers it to the chat. The delivery method and filename are derived from the artifact (its `delivery` hint, `kind`, and stored name); internal local paths are never exposed. No caption is sent by default: the filename already appears on the attachment, so it is never duplicated into the caption text (which would let Telegram autolink a filename like `example.md` as a URL). A caption is shown only when an explicit one is passed. Tools declare their delivery intent by returning `delivery: { method }` in their output; they do not deliver to the transport themselves. As a shortcut, `run_tool` accepts `deliver: true` to generate and deliver in a single step; use it only when the user should receive the file now, not for intermediate pipe steps.
|
|
153
155
|
|
|
154
156
|
## Async event queue flow
|
|
155
|
-
Beyond time-based scheduling, tools can drive an event queue that wakes the agent only when there is something to evaluate. Everything goes through the `asyncTask` (single) or `asyncTasks` (array) field the pipeline already supports; no new
|
|
157
|
+
Beyond time-based scheduling, tools can drive an event queue that wakes the agent only when there is something to evaluate. Everything goes through the `asyncTask` (single) or `asyncTasks` (array) field the pipeline already supports; no new native agent tools are needed. The 1s poller drains tasks by `kind`:
|
|
156
158
|
|
|
157
|
-
- `agent_task`: a scheduled prompt. The poller delivers it as a prompt for
|
|
159
|
+
- `agent_task`: a scheduled prompt. The poller delivers it as a prompt for the active runtime to fulfill (time-based work).
|
|
158
160
|
- `poll_tool`: a recurring checker the poller **runs directly as a tool** (no agent turn spent). The poller materializes its output with the same logic as `run_tool`, so any `agent_event` the checker emits is enqueued for the next tick. Its `recurrence` reschedules the next poll.
|
|
159
|
-
- `agent_event`: an incoming event. The poller delivers it as a prompt so
|
|
161
|
+
- `agent_event`: an incoming event. The poller delivers it as a prompt so the active runtime evaluates it and decides the next action (it may stay silent).
|
|
160
162
|
|
|
161
163
|
Tasks without a `runAt` fire immediately, so `agent_event` and the first `poll_tool` run on the next tick.
|
|
162
164
|
|
package/README.md
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
# Arisa
|
|
2
2
|
|
|
3
|
-
[Arisa](https://arisa.sh) is a personal assistant you talk to through Telegram, powered by
|
|
3
|
+
[Arisa](https://arisa.sh) is a personal assistant you talk to through Telegram, powered by Pi Agent and isolated CLI tools.
|
|
4
4
|
|
|
5
5
|
## Origin
|
|
6
6
|
|
|
7
|
-
The initial inspiration was OpenClaw, which has interesting ideas but carries a lot of weight
|
|
7
|
+
The initial inspiration was OpenClaw, which has interesting ideas but carries a lot of weight compared with Arisa's focused core: when it generates tools they end up disorganized, and the overall framework feels overloaded.
|
|
8
8
|
|
|
9
9
|
The real heart of OpenClaw is Pi Agent: a [minimal terminal coding harness](https://www.youtube.com/watch?v=Dli5slNaJu0) that lets an AI agent reason and act with very little infrastructure. That part is genuinely good.
|
|
10
10
|
|
|
11
11
|
Telegram bots, on the other hand, work extremely well as a human interface. Simple, reliable, always in your pocket.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Arisa keeps Telegram as its interface and Pi Agent as its single reasoning harness.
|
|
14
14
|
|
|
15
15
|
It is designed around a simple idea:
|
|
16
16
|
|
|
@@ -40,7 +40,7 @@ This distinction is important. Some transformations belong to the transport/inpu
|
|
|
40
40
|
|
|
41
41
|
## Zero tools, assembled on demand
|
|
42
42
|
|
|
43
|
-
A fresh install ships with **zero tools**. The core is
|
|
43
|
+
A fresh install ships with **zero Arisa modular tools**. The core is Telegram transport, the Pi Agent reasoning loop, the artifact store, and the tool registry. Out of the box Arisa cannot transcribe audio, browse the web, or speak; it gains each capability only once a tool that provides it is installed.
|
|
44
44
|
|
|
45
45
|
Arisa assembles its own toolset from real use:
|
|
46
46
|
|
|
@@ -58,6 +58,9 @@ The result is a toolset shaped by how you actually use the assistant, not by def
|
|
|
58
58
|
- text messages go directly to Pi Agent
|
|
59
59
|
- audio/voice messages are transcribed first when a transcription tool is installed, then passed to Pi Agent as text; otherwise the agent is told transcription failed and can offer to install one
|
|
60
60
|
- media is stored as artifacts
|
|
61
|
+
- while a chat is busy, concurrent text steers Pi's active run by default
|
|
62
|
+
- set `telegram.busyMessageMode` to `"queue"` to keep concurrent text messages in order; override one chat with `telegram.chatMeta[chatId].busyMessageMode`
|
|
63
|
+
- media and normalized audio stay queued, and failed steering falls back to the ordered queue
|
|
61
64
|
|
|
62
65
|
### Tool model
|
|
63
66
|
No tools ship with the core. All installed tools live under `~/.arisa/tools/<tool-name>`, whether they come from the [official catalog](https://github.com/clasen/Arisa/tree/main/tools), from another source the user chooses, or are created by the agent itself.
|
|
@@ -86,7 +89,6 @@ All runtime state lives under `~/.arisa/`, split between global state and per-ch
|
|
|
86
89
|
|
|
87
90
|
Global:
|
|
88
91
|
- runtime config is stored in `~/.arisa/state/config.json`
|
|
89
|
-
- Pi OAuth credentials are stored in `~/.arisa/state/pi-auth.json`
|
|
90
92
|
- the scheduled-task queue is stored in `~/.arisa/state/tasks.json`
|
|
91
93
|
- installed tools live under `~/.arisa/tools/<tool>/`, each with a default `config.js` template
|
|
92
94
|
- global tool runtime state (daemons, caches, temp) lives under `~/.arisa/state/tools/<tool>/`
|
|
@@ -94,7 +96,7 @@ Global:
|
|
|
94
96
|
Per chat (`~/.arisa/chats/<chatId>/`):
|
|
95
97
|
- artifact files are stored under `artifacts/`
|
|
96
98
|
- the artifact index is stored in `state/artifacts.json`
|
|
97
|
-
-
|
|
99
|
+
- Pi sessions live under `state/pi-sessions/<revision>/`
|
|
98
100
|
- chat-scoped tool config overrides live in `config/tools/<tool>/config.js`
|
|
99
101
|
- chat-scoped daemon infrastructure lives in `state/tools/<tool>/daemon/`; persistent tool data stays beside it
|
|
100
102
|
- ephemeral scratch lives under `tmp/`
|
|
@@ -105,6 +107,22 @@ Pi authentication can use either:
|
|
|
105
107
|
- an API key entered during bootstrap
|
|
106
108
|
- or Pi's existing OAuth login when supported, such as `openai-codex`
|
|
107
109
|
|
|
110
|
+
Automatic context compaction uses Pi's native implementation and can be tuned in `~/.arisa/state/config.json`:
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"pi": {
|
|
115
|
+
"compaction": {
|
|
116
|
+
"enabled": true,
|
|
117
|
+
"reserveTokens": 120000,
|
|
118
|
+
"keepRecentTokens": 20000
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Pi compacts when the context exceeds the model's context window minus `reserveTokens`. The default keeps a large reserve so compaction occurs before Arisa Doctor's context warning on the default model. Set a smaller reserve when using models with substantially smaller context windows. Arisa does not add Telegram commands or compaction notifications.
|
|
125
|
+
|
|
108
126
|
## Install globally
|
|
109
127
|
|
|
110
128
|
```bash
|
|
@@ -123,15 +141,18 @@ Command modes:
|
|
|
123
141
|
arisa # foreground, blocking
|
|
124
142
|
arisa start # start in background
|
|
125
143
|
arisa stop # stop background service
|
|
144
|
+
arisa restart # restart background service, or start it if stopped
|
|
126
145
|
arisa status # show background service status
|
|
127
146
|
arisa flush # remove ~/.arisa
|
|
128
147
|
arisa --silent # run without verbose logs
|
|
129
148
|
```
|
|
130
149
|
|
|
150
|
+
Authorized Telegram chats can run the same safe service lifecycle with `/restart`.
|
|
151
|
+
|
|
131
152
|
Runtime model override (current process only):
|
|
132
153
|
|
|
133
154
|
```bash
|
|
134
|
-
arisa --pi.model
|
|
155
|
+
arisa --pi.model openai-codex/gpt-5.6
|
|
135
156
|
```
|
|
136
157
|
|
|
137
158
|
Notes:
|
|
@@ -201,7 +222,7 @@ No "I can't do that" when the thing is realistically buildable.
|
|
|
201
222
|
|
|
202
223
|
## Notes
|
|
203
224
|
|
|
204
|
-
- `AGENTS.md` defines the project-level behavioral rules for
|
|
225
|
+
- `AGENTS.md` defines the project-level behavioral rules for the active agent runtime
|
|
205
226
|
- `src/transport/telegram/bot.js` builds the per-message runtime prompt
|
|
206
227
|
- tool help is part of the architecture and should be consulted before use when details are unclear
|
|
207
228
|
|
|
@@ -210,7 +231,7 @@ No "I can't do that" when the thing is realistically buildable.
|
|
|
210
231
|
This is currently a functional V1. The core provides:
|
|
211
232
|
|
|
212
233
|
- Telegram transport
|
|
213
|
-
- Pi Agent integration
|
|
234
|
+
- Pi Agent session and model integration
|
|
214
235
|
- artifact-based message handling
|
|
215
236
|
- the isolated CLI tool registry (starts empty)
|
|
216
237
|
- pre-reasoning and post-reasoning pipes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arisa",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.1.2",
|
|
4
4
|
"description": "Telegram + Pi Agent modular assistant",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -28,6 +28,9 @@
|
|
|
28
28
|
],
|
|
29
29
|
"author": "Martin Clasen",
|
|
30
30
|
"license": "MIT",
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=22.8.0"
|
|
33
|
+
},
|
|
31
34
|
"repository": {
|
|
32
35
|
"type": "git",
|
|
33
36
|
"url": "git+https://github.com/clasen/Arisa.git"
|
|
@@ -39,7 +42,8 @@
|
|
|
39
42
|
"dependencies": {
|
|
40
43
|
"@earendil-works/pi-coding-agent": "0.80.6",
|
|
41
44
|
"@sinclair/typebox": "^0.34.41",
|
|
42
|
-
"grammy": "^1.42.0"
|
|
45
|
+
"grammy": "^1.42.0",
|
|
46
|
+
"typebox": "1.1.38"
|
|
43
47
|
},
|
|
44
48
|
"scripts": {
|
|
45
49
|
"start": "node src/index.js",
|