@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 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