@tuttiai/cli 0.9.0 → 0.11.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 +134 -0
- package/dist/index.js +400 -93
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -29,6 +29,8 @@ Load a score file and open an interactive REPL:
|
|
|
29
29
|
```bash
|
|
30
30
|
tutti-ai run # defaults to ./tutti.score.ts
|
|
31
31
|
tutti-ai run ./custom-score.ts # specify a score file
|
|
32
|
+
tutti-ai run --watch # hot-reload the score on file changes
|
|
33
|
+
tutti-ai run -w ./score.ts # short alias
|
|
32
34
|
```
|
|
33
35
|
|
|
34
36
|
Features:
|
|
@@ -36,6 +38,138 @@ Features:
|
|
|
36
38
|
- Colored tool execution trace
|
|
37
39
|
- Session continuity across messages
|
|
38
40
|
- Graceful Ctrl+C handling
|
|
41
|
+
- Hot reload with `--watch` / `-w` (see below)
|
|
42
|
+
|
|
43
|
+
#### Watch mode
|
|
44
|
+
|
|
45
|
+
`--watch` reloads the score (and any file in the score's directory tree,
|
|
46
|
+
excluding `node_modules`, `dist`, and dotfiles) whenever it changes on
|
|
47
|
+
disk. Changes are debounced 200ms so editor saves that touch the file
|
|
48
|
+
multiple times collapse into a single reload.
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
> research quantum computing
|
|
52
|
+
[tutti] Score changed, reloading...
|
|
53
|
+
[tutti] Score reloaded. Changes applied.
|
|
54
|
+
> what did you learn last turn?
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Semantics:
|
|
58
|
+
|
|
59
|
+
- **Changes take effect at turn boundaries**, never mid-tool-call. The
|
|
60
|
+
current turn always completes with the config it started with; the
|
|
61
|
+
next turn reads the new config.
|
|
62
|
+
- **Session history is preserved** across reloads — the REPL's
|
|
63
|
+
`session_id` carries over, so the conversation continues.
|
|
64
|
+
- **Syntax errors are recovered** — if the reload fails to parse or
|
|
65
|
+
validate, the error is printed and the REPL keeps using the previous
|
|
66
|
+
config. Fix the file and save again.
|
|
67
|
+
- **Trade-off**: runtime internals (tool cache, semantic memory) reset
|
|
68
|
+
on reload. Conversation history survives because the REPL owns the
|
|
69
|
+
session store and reuses it across runtime swaps.
|
|
70
|
+
|
|
71
|
+
Deferred (known gaps):
|
|
72
|
+
- The watcher uses a directory-tree watch, not a resolved import graph —
|
|
73
|
+
unrelated file edits in the project tree will also trigger reloads.
|
|
74
|
+
A future revision may use `madge` or the TS compiler API for
|
|
75
|
+
precision.
|
|
76
|
+
- Voice-level partial reload isn't implemented; the whole runtime is
|
|
77
|
+
rebuilt on every change. Fast enough in practice (typically <50ms)
|
|
78
|
+
but means runtime-internal caches reset.
|
|
79
|
+
|
|
80
|
+
### `tutti-ai serve [score]`
|
|
81
|
+
|
|
82
|
+
Start the Tutti HTTP server — exposes your score as a REST API:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
tutti-ai serve # defaults to ./tutti.score.ts
|
|
86
|
+
tutti-ai serve ./custom-score.ts # specify a score file
|
|
87
|
+
tutti-ai serve --port 8080 # custom port (default: 3847)
|
|
88
|
+
tutti-ai serve --watch # hot-reload score on file changes
|
|
89
|
+
tutti-ai serve -a researcher # expose a specific agent
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Options:
|
|
93
|
+
|
|
94
|
+
| Flag | Default | What it does |
|
|
95
|
+
|---|---|---|
|
|
96
|
+
| `-p, --port <number>` | `3847` | Port to listen on. |
|
|
97
|
+
| `-H, --host <address>` | `0.0.0.0` | Interface to bind to. |
|
|
98
|
+
| `-k, --api-key <key>` | `TUTTI_API_KEY` env | Bearer token clients must send for auth. |
|
|
99
|
+
| `-a, --agent <name>` | score entry or first agent | Which agent to expose via the API. |
|
|
100
|
+
| `-w, --watch` | off | Reload the score and restart the server on file changes. |
|
|
101
|
+
|
|
102
|
+
Startup output:
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
Tutti Server v0.1.0
|
|
106
|
+
http://localhost:3847
|
|
107
|
+
|
|
108
|
+
Score: my-project
|
|
109
|
+
Agent: assistant
|
|
110
|
+
Agents: assistant, researcher
|
|
111
|
+
Watch: enabled
|
|
112
|
+
|
|
113
|
+
Endpoints:
|
|
114
|
+
POST http://localhost:3847/run
|
|
115
|
+
POST http://localhost:3847/run/stream
|
|
116
|
+
GET http://localhost:3847/sessions/:id
|
|
117
|
+
GET http://localhost:3847/health
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
#### Environment variables
|
|
121
|
+
|
|
122
|
+
| Variable | Required | Description |
|
|
123
|
+
|---|---|---|
|
|
124
|
+
| `TUTTI_API_KEY` | Yes | Bearer token for authenticating requests. |
|
|
125
|
+
| `ANTHROPIC_API_KEY` | If using Anthropic | Anthropic API key. |
|
|
126
|
+
| `OPENAI_API_KEY` | If using OpenAI | OpenAI API key. |
|
|
127
|
+
| `GOOGLE_API_KEY` | If using Gemini | Google AI API key. |
|
|
128
|
+
| `TUTTI_ALLOWED_ORIGINS` | No | Comma-separated CORS origins (default: `*`). |
|
|
129
|
+
| `DATABASE_URL` | No | PostgreSQL URL for session persistence. |
|
|
130
|
+
| `TUTTI_REDIS_URL` | No | Redis URL for durable checkpoints. |
|
|
131
|
+
|
|
132
|
+
#### Example curl commands
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
# Health check
|
|
136
|
+
curl http://localhost:3847/health
|
|
137
|
+
|
|
138
|
+
# Run an agent (non-streaming)
|
|
139
|
+
curl -X POST http://localhost:3847/run \
|
|
140
|
+
-H "Authorization: Bearer $TUTTI_API_KEY" \
|
|
141
|
+
-H "Content-Type: application/json" \
|
|
142
|
+
-d '{"input": "Summarize the latest AI news"}'
|
|
143
|
+
|
|
144
|
+
# Run an agent (streaming via SSE)
|
|
145
|
+
curl -N -X POST http://localhost:3847/run/stream \
|
|
146
|
+
-H "Authorization: Bearer $TUTTI_API_KEY" \
|
|
147
|
+
-H "Content-Type: application/json" \
|
|
148
|
+
-d '{"input": "Write a short poem about TypeScript"}'
|
|
149
|
+
|
|
150
|
+
# Continue a conversation
|
|
151
|
+
curl -X POST http://localhost:3847/run \
|
|
152
|
+
-H "Authorization: Bearer $TUTTI_API_KEY" \
|
|
153
|
+
-H "Content-Type: application/json" \
|
|
154
|
+
-d '{"input": "Tell me more", "session_id": "<session_id from previous response>"}'
|
|
155
|
+
|
|
156
|
+
# Retrieve session history
|
|
157
|
+
curl http://localhost:3847/sessions/<session_id> \
|
|
158
|
+
-H "Authorization: Bearer $TUTTI_API_KEY"
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
#### Graceful shutdown
|
|
162
|
+
|
|
163
|
+
`SIGINT` (Ctrl+C) and `SIGTERM` close the server after in-flight requests
|
|
164
|
+
complete. Fastify's built-in connection draining ensures no request is
|
|
165
|
+
dropped mid-response.
|
|
166
|
+
|
|
167
|
+
#### Watch mode
|
|
168
|
+
|
|
169
|
+
`--watch` reloads the score on any file change in the score's directory
|
|
170
|
+
tree (debounced 200ms). On reload the server is closed and restarted
|
|
171
|
+
with the new config. In-flight sessions survive because the session
|
|
172
|
+
store is shared across restarts.
|
|
39
173
|
|
|
40
174
|
### `tutti-ai resume <session-id>`
|
|
41
175
|
|