@robota-sdk/agent-session 3.0.0-beta.100

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/CHANGELOG.md ADDED
@@ -0,0 +1,1774 @@
1
+ # @robota-sdk/agent-session
2
+
3
+ ## 3.0.0-beta.100
4
+ ### Patch Changes
5
+
6
+ - @robota-sdk/agent-core@3.0.0-beta.100
7
+ - @robota-sdk/agent-file-authority@3.0.0-beta.100
8
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.100
9
+ - @robota-sdk/agent-interface-session@3.0.0-beta.100
10
+
11
+ ## 3.0.0-beta.99
12
+ ### Patch Changes
13
+
14
+ - @robota-sdk/agent-core@3.0.0-beta.99
15
+ - @robota-sdk/agent-file-authority@3.0.0-beta.99
16
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.99
17
+ - @robota-sdk/agent-interface-session@3.0.0-beta.99
18
+
19
+ ## 3.0.0-beta.98
20
+ ### Patch Changes
21
+
22
+ - @robota-sdk/agent-core@3.0.0-beta.98
23
+ - @robota-sdk/agent-file-authority@3.0.0-beta.98
24
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.98
25
+ - @robota-sdk/agent-interface-session@3.0.0-beta.98
26
+
27
+ ## 3.0.0-beta.97
28
+ ### Patch Changes
29
+
30
+ - c207a31: Keep automatic compaction aligned with the active model and pending input, preserve provider usage when estimating new context, and keep summary text out of the response stream. Display live context changes and successful automatic compaction in the shared app interface.
31
+ - 9b4f63b: Allow explicitly borrowed providers to outlive agent destruction and Session shutdown while keeping
32
+ owned providers as the default. Track replaced and removed provider cleanup, expose current provider
33
+ registrations after swapping, and hold Roundtable resource leases until runtime teardown finishes.
34
+ Borrowing does not permit concurrent provider use across leases.
35
+ Serialize manager lifecycle transitions so reinitialization cannot admit providers during pending teardown.
36
+ - 7911a7d: Preserve pending execution discovery and input admission in atomic Session conversation snapshots.
37
+ Strict synchronous checkpoints now gate waiting, settlement and abandonment acknowledgment; failed saves
38
+ require checkpoint repair without repeating execution. Restore before framework queue and autonomous
39
+ input admission, and refuse unresolved conversation copies. Read v1/v2 session envelopes and write v2;
40
+ older readers preserve v2 as unsupported, so coordinate reader versions when rolling back.
41
+ - Updated dependencies [c207a31]
42
+ - Updated dependencies [9b4f63b]
43
+ - Updated dependencies [7911a7d]
44
+ - Updated dependencies [23a30cd]
45
+ - @robota-sdk/agent-core@3.0.0-beta.97
46
+ - @robota-sdk/agent-interface-session@3.0.0-beta.97
47
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.97
48
+ - @robota-sdk/agent-file-authority@3.0.0-beta.97
49
+
50
+ ## 3.0.0-beta.96
51
+ ### Patch Changes
52
+
53
+ - @robota-sdk/agent-core@3.0.0-beta.96
54
+ - @robota-sdk/agent-file-authority@3.0.0-beta.96
55
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.96
56
+ - @robota-sdk/agent-interface-session@3.0.0-beta.96
57
+
58
+ ## 3.0.0-beta.95
59
+ ### Minor Changes
60
+
61
+ - 04719a9: **A permission request names the tool call it is about.**
62
+
63
+ `IPermissionRequestEvent` gains an optional `executionId`: the same id the call's `tool_start` and
64
+ `tool_end` carry, so a surface can hold one row from the request to the call's end. The session's
65
+ permission path carries the call's id from the tool wrapper to the prompt (`IPermissionAskContext.executionId`)
66
+ and the framework's prompt registry stamps it on the event, so it reaches every client that receives
67
+ the event, the WebSocket and HTTP `permission_request` frames included. It is present whenever the
68
+ session reports that call (its own, or an in-process background agent's) and absent for a
69
+ child-process agent's forwarded request.
70
+
71
+ The ACP agent transport keys its permission rows by that id: the request's `toolCallId` is the
72
+ call's execution id, its start and end address the same row, a denial the session decides on its
73
+ own while the editor's dialog is open closes that one row, and two same-named calls each follow
74
+ their own row whatever order the editor answers in. A request that names no call gets a row that
75
+ closes with the answer, and is closed at the end of the turn if no answer came. The name-ordered
76
+ matching is gone.
77
+ - 04a6de4: **Reasoning text a provider streams now reaches the editor as an ACP `agent_thought_chunk`, through a new `thinking_delta` session event.**
78
+
79
+ `IChatOptions.onThinkingDelta`, `IRunOptions.onThinkingDelta` and `IResumeExecutionOptions.onThinkingDelta`
80
+ (typed `TThinkingDeltaCallback`) carry reasoning text from a provider through the run, and the session
81
+ options (`ISessionOptions.onThinkingDelta`, `ICreateSessionOptions.onThinkingDelta`) hand it to the
82
+ session's owner. `InteractiveSession` emits it as `thinking_delta(delta)`, beside `text_delta`. The
83
+ text is never part of the reply: it is not appended to the conversation, not streamed through
84
+ `onTextDelta`, and the core adds no record of its own for it (no text-delta log entry, no
85
+ `provider_stream_raw_delta`); a provider's own native payload capture and response metadata keep
86
+ what the provider sent, as before. A reasoning delta counts as provider activity for the idle
87
+ timeout whether or not anyone listens to it, so a model that is only thinking is not cut off. The
88
+ existing `thinking(isThinking)` event is unchanged and remains the busy indicator. Where a provider
89
+ sends no reasoning text, nothing is emitted and nothing new is switched on.
90
+
91
+ `@robota-sdk/agent-interface-session` is a major change because a new session event name makes an
92
+ exhaustive map over the event names stop compiling until it classifies the event.
93
+
94
+ `@robota-sdk/agent-transport-acp` sends each non-empty `thinking_delta` to the editor as an
95
+ `agent_thought_chunk`, in order with the message chunks, so `robota acp` shows the model's reasoning
96
+ in the editor. A turn that streamed only thoughts still shows its result text, because only reply
97
+ text marks a turn as streamed. The WebSocket wire, the HTTP stream, headless stream-json, `query()`
98
+ and the terminal UI do not carry the new event in this change (`@robota-sdk/agent-transport` and
99
+ `@robota-sdk/agent-ui-terminal` classify it as non-surface). A forked skill and an in-process subagent
100
+ pass their reply text up but not their reasoning.
101
+
102
+ Two providers already receive reasoning text and now report it. `@robota-sdk/agent-provider-openai`
103
+ passes `response.reasoning_summary_text.delta` events of a streamed Responses call to
104
+ `onThinkingDelta`; the API sends them only when the provider profile asks for a reasoning summary, and
105
+ no request option changed; a summary streamed in several parts, and the summary of a later reasoning
106
+ item, each start on a new paragraph (`\n\n`) so the parts do not run together.
107
+ `@robota-sdk/agent-provider-openai-compatible` reports the text of Gemma's thought channel, which the
108
+ provider already removed from the reply, as it streams across chunk boundaries, with each later
109
+ channel of one reply on a new paragraph; the reply text is unchanged. No other provider reports
110
+ reasoning, and Anthropic thinking is not enabled. A model fallback chain still moves to the next model when only reasoning had streamed.
111
+
112
+ The scripted test provider (`@robota-sdk/agent-core/testing`) accepts an optional `thinking` string on
113
+ a turn and delivers it through `onThinkingDelta` before the turn's text; the scripted session harness
114
+ collects `thinking_delta` and now keeps a scripted tool-call turn's `usage`, which it used to drop.
115
+ - 0ba247b: A tool result can now carry a view its source declared (an MCP app), and a surface can invoke a
116
+ runtime tool through the session's permission gate with a prompt. This is the contract and wiring
117
+ layer: nothing produces a view yet, and the GUI does not yet host one.
118
+
119
+ - `agent-core` — `IToolResult.view` carries an `IToolAppView` (source, `ui://` resource, mime type,
120
+ HTML, structured content, callable tools, the call's input). `view` is now a typed key of
121
+ `IToolResult`, so an extension that already used a `view` key with another type must rename it.
122
+ The view is display data: it never enters model context or the size that decides a spill, and a
123
+ result replaced by its reference keeps it.
124
+ - `agent-interface-session` — `invokeRuntimeTool` takes `permissionInteraction` (`'interactive'` or
125
+ the default `'deny'`), a `driverId` (a host that attributes prompts names it as the requester) and
126
+ an `executionId` its events carry. A finished model call's `tool_end` names its view with
127
+ `IToolState.appView` (`viewId`, source, resource), and the new
128
+ `ISessionToolAppViews.readToolAppView(viewId)` reads the document. A permission handler may take
129
+ `{ signal }`, and aborting it withdraws the prompt.
130
+ - `agent-session` — a direct call asks a person only when its caller says so, and the handler is
131
+ given the call's own signal; the tool end event carries the view, never in the logged result data.
132
+ - `agent-framework` — the view of a model's call is kept under a `viewId` the session mints, in a
133
+ bounded per-session store (16 views, 4 MiB each, 16 MiB in all, measured on the whole serialized
134
+ view), and read on demand, so the document never rides `tool_end` to every surface, never enters
135
+ the recorded history, and a repeated provider tool-call id cannot overwrite another turn's view.
136
+ A malformed view is dropped. A direct call keeps and names no view, recognised by the id it was
137
+ started with. A submission or agent wakeup that arrives while a direct call holds the session is
138
+ queued behind it, as during a turn, instead of refused. A direct call acting for a driver
139
+ attributes its permission prompt and tool events to that driver, and aborting its signal withdraws
140
+ an open prompt from every surface.
141
+ - `agent-transport` — a driving connection sends `call-app-tool` (answered by `app_tool_result`) and
142
+ `read-app-view` (answered by `app_view`). A call names its view and reaches only the tools that
143
+ view's source declared; a call or read that decodes but cannot be served answers `protocol_error`
144
+ echoing the `requestId`, while an observer's attempt is refused like any non-read. A call still
145
+ waiting on its prompt is cancelled when its connection goes away (for the resume bridge, when the
146
+ bridge is disposed). `maxFrameBytes` bounds an app answer to what a carrier's channel carries;
147
+ the WebRTC carrier uses a history page's worth. `IProtocolSession` now includes the runtime-tool
148
+ and app-view roles.
149
+ - `agent-ui-web` — the two new server messages are recorded as not rendered until the app-view host
150
+ consumes them.
151
+
152
+ An implementation of `IInteractiveSession` or `IProtocolSession` outside this repository must add
153
+ `readToolAppView` (and, for `IProtocolSession`, `listRuntimeTools` and `invokeRuntimeTool`); the
154
+ members are required so a host cannot silently lack them.
155
+
156
+ ### Patch Changes
157
+
158
+ - 60f3965: **`robota mcp serve --ask-client` puts a caller's permission and ask prompts to the calling MCP client through elicitation instead of failing them.**
159
+
160
+ `@robota-sdk/agent-transport-mcp`: `createMcpTransport`, `createMcpHttpHost`,
161
+ `createMcpRemoteHttpHost` and `createAgentMcpServer` take `askClient`. Off by default, every prompt
162
+ is a tool error as before. On, and when the client declared form-mode elicitation, a permission or
163
+ ask prompt raised by that client's own call is put to it: a permission offers allow once or deny
164
+ only, never a remembered grant; an ask becomes a form (choice, multiple choice, free text); a masked
165
+ ask is never sent; deny, decline, cancel, a client error or an answer naming nothing offered keeps
166
+ today's outcome. stdio asks during the call. The HTTP hosts keep no session state, so they ask only
167
+ a client on the 2026-07-28 revision, through input-required rounds whose `requestState` is a
168
+ single-use random token naming one parked call; a 2025-era HTTP client keeps the tool error.
169
+ A call listens for prompts only while its own work drives the session, so a submission waiting
170
+ in the queue never holds another caller's prompt that it cannot answer.
171
+ Breaking for hand-written sessions: `IMcpTransportSession` now also requires `ISessionEvents`
172
+ (`on`/`off`), `ISessionPromptResolution` (`resolvePermission`/`resolveAsk`) and
173
+ `ISessionDriverAttribution` (`getActiveDriverId`), which `InteractiveSession` and the published
174
+ test double already implement.
175
+
176
+ `@robota-sdk/agent-interface-session` / `@robota-sdk/agent-session` / `@robota-sdk/agent-framework`:
177
+ `ISessionRuntimeTools.invokeRuntimeTool` (and `Session.invokeRuntimeTool`) accept
178
+ `options.permissionInteraction` and `options.driverId`. A direct call still denies a decision that
179
+ would need a person, and finds no one to ask a question, unless its caller passes
180
+ `permissionInteraction: 'interactive'`; then it asks the session's permission handler and its
181
+ tools get the session's ask port. `InteractiveSession` makes `driverId` the active driver while
182
+ the direct call runs, so a prompt the call raises carries it as `requesterDriverId`. With
183
+ `askClient` on, an MCP call runs under its own `mcp:<n>` driver id; a submission made that way is
184
+ attributed to it rather than to the owner.
185
+
186
+ `@robota-sdk/agent-transport`: exports `permissionSummaryArgument`, the argument a person recognises
187
+ a tool call by (`filePath` for the built-in file tools), for every transport that puts a permission
188
+ request to a person in its own wire form.
189
+
190
+ `@robota-sdk/agent-cli`: `mcp serve --ask-client` turns this on for whichever carrier the run serves.
191
+ - Updated dependencies [60f3965]
192
+ - Updated dependencies [115e104]
193
+ - Updated dependencies [04719a9]
194
+ - Updated dependencies [04a6de4]
195
+ - Updated dependencies [0ba247b]
196
+ - Updated dependencies [02053ec]
197
+ - @robota-sdk/agent-interface-session@3.0.0-beta.95
198
+ - @robota-sdk/agent-core@3.0.0-beta.95
199
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.95
200
+ - @robota-sdk/agent-file-authority@3.0.0-beta.95
201
+
202
+ ## 3.0.0-beta.94
203
+ ### Patch Changes
204
+
205
+ - e706b43: Live telemetry can name its spans with the OpenTelemetry GenAI semantic conventions. Set
206
+ `PRODUCT_TELEMETRY_SEMCONV` to `gen_ai` to export `invoke_agent`, `chat {model}` (client) and
207
+ `execute_tool {tool}` spans with `gen_ai.*` attributes, keeping Robota-only facts as `agent.*`; or to
208
+ `gen_ai/dup` to emit both attribute sets while dashboards move. The default, `agent`, exports exactly
209
+ the spans it did before. An unknown value, or the setting while neither traces nor metrics are exported,
210
+ refuses startup. Console traces under a GenAI mode print the same projected spans.
211
+
212
+ The live prompt trace now carries each tool body's name (the session's tool-body observation includes it
213
+ and the framework's live projection passes a label-safe name through); it reaches spans only under a
214
+ GenAI mode and is never written to session history.
215
+ - @robota-sdk/agent-interface-session@3.0.0-beta.94
216
+ - @robota-sdk/agent-core@3.0.0-beta.94
217
+ - @robota-sdk/agent-file-authority@3.0.0-beta.94
218
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.94
219
+
220
+ ## 3.0.0-beta.93
221
+ ### Patch Changes
222
+
223
+ - Updated dependencies
224
+ - @robota-sdk/agent-core@3.0.0-beta.93
225
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.93
226
+ - @robota-sdk/agent-interface-session@3.0.0-beta.93
227
+ - @robota-sdk/agent-file-authority@3.0.0-beta.93
228
+
229
+ ## 3.0.0-beta.92
230
+ ### Patch Changes
231
+
232
+ - Updated dependencies
233
+ - @robota-sdk/agent-core@3.0.0-beta.92
234
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.92
235
+ - @robota-sdk/agent-interface-session@3.0.0-beta.92
236
+ - @robota-sdk/agent-file-authority@3.0.0-beta.92
237
+
238
+ ## 3.0.0-beta.91
239
+ ### Patch Changes
240
+
241
+ - bad976f: Persist turn and tool intent before effects, restore interrupted calls with unknown outcomes, reap owned foreground shell groups after owner death, and prune proven dead peer announcements.
242
+ - @robota-sdk/agent-core@3.0.0-beta.91
243
+ - @robota-sdk/agent-file-authority@3.0.0-beta.91
244
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.91
245
+ - @robota-sdk/agent-interface-session@3.0.0-beta.91
246
+
247
+ ## 3.0.0-beta.90
248
+ ### Patch Changes
249
+
250
+ - @robota-sdk/agent-core@3.0.0-beta.90
251
+ - @robota-sdk/agent-file-authority@3.0.0-beta.90
252
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.90
253
+ - @robota-sdk/agent-interface-session@3.0.0-beta.90
254
+
255
+ ## 3.0.0-beta.89
256
+ ### Patch Changes
257
+
258
+ - @robota-sdk/agent-core@3.0.0-beta.89
259
+ - @robota-sdk/agent-file-authority@3.0.0-beta.89
260
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.89
261
+ - @robota-sdk/agent-interface-session@3.0.0-beta.89
262
+
263
+ ## 3.0.0-beta.88
264
+
265
+ ### Patch Changes
266
+
267
+ - @robota-sdk/agent-core@3.0.0-beta.88
268
+ - @robota-sdk/agent-file-authority@3.0.0-beta.88
269
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.88
270
+ - @robota-sdk/agent-interface-session@3.0.0-beta.88
271
+
272
+ ## 3.0.0-beta.87
273
+
274
+ ### Minor Changes
275
+
276
+ - 7d9cc66: Preserve an explicitly supplied host tool scheduling policy through session assembly and CLI presentation modes, retaining permission admission and conservative handling of undeclared resources.
277
+
278
+ ### Patch Changes
279
+
280
+ - Release the migrated Robota product with its public SDK namespace, robota command, compatible SDK exports, internal product configuration, and verified CLI startup and delivery corrections.
281
+ - 7d9cc66: Retain typed resource and audio observations alongside structured tool results through history, durable receipts, recovery, size admission, and session persistence. Preserve opaque resource references without fetching them, project embedded text and explicit unsupported binary/audio diagnostics into provider requests and compaction transcripts, and validate persisted observation shapes on reload.
282
+ - 7d9cc66: Retain registered tool source attribution in observations and preserve ordered outcome receipts independently of conversation summaries.
283
+ - 7d9cc66: Retain mixed tool observations alongside structured results through live session events and history
284
+ display. The shared app renderer previews inline raster images and keeps resource URIs inert, with
285
+ explicit diagnostics for unsupported media instead of silently dropping it.
286
+ - 7d9cc66: Retain registered attribution on refused and interrupted call receipts without replacing the source of actual or recovered settlements, and project undispatched registered calls into live and restored presentation history.
287
+ - Updated dependencies
288
+ - Updated dependencies [66af868]
289
+ - Updated dependencies [7d9cc66]
290
+ - Updated dependencies [7d9cc66]
291
+ - Updated dependencies [7d9cc66]
292
+ - Updated dependencies [7d9cc66]
293
+ - Updated dependencies [7d9cc66]
294
+ - Updated dependencies [7d9cc66]
295
+ - Updated dependencies [7d9cc66]
296
+ - Updated dependencies [7d9cc66]
297
+ - @robota-sdk/agent-core@3.0.0-beta.87
298
+ - @robota-sdk/agent-file-authority@3.0.0-beta.87
299
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.87
300
+ - @robota-sdk/agent-interface-session@3.0.0-beta.87
301
+
302
+ ## 3.0.0-beta.86
303
+
304
+ ### Patch Changes
305
+
306
+ - @robota-sdk/agent-core@3.0.0-beta.86
307
+ - @robota-sdk/agent-file-authority@3.0.0-beta.86
308
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.86
309
+ - @robota-sdk/agent-interface-session@3.0.0-beta.86
310
+
311
+ ## 3.0.0-beta.85
312
+
313
+ ### Minor Changes
314
+
315
+ - 94b2c87: A PreToolUse `command` hook can now steer a tool call, not only refuse it. The permission gate
316
+ applies the winning `hookSpecificOutput.permissionDecision`:
317
+
318
+ - `allow` skips the prompt a person would otherwise get. Deny rules, refusals from the mode, the
319
+ `auto` mode classifier and asks that must reach a person (an `ask` rule, a protected path, a
320
+ policy that asks about everything) still apply.
321
+ - `ask` sends the call to a person even when the mode or a remembered consent would run it. The
322
+ answer is not remembered, and with no one to ask the call is refused.
323
+ - `defer` leaves the call to the normal flow, as before.
324
+
325
+ Before this change these decisions were read and then ignored.
326
+
327
+ `updatedInput` is still not applied: the call runs the input it was made with, and an `allow` sent
328
+ with an `updatedInput` is not applied either, since it approved another input.
329
+
330
+ `runHooks` (agent-core) now reads a decision and an `updatedInput` only from `command` hooks: a
331
+ `prompt` or `agent` hook answers from a model that reads the tool input it judges, so it can only
332
+ refuse. With several hooks, `ask` now outranks `defer` (`deny` > `ask` > `defer` > `allow`), and the
333
+ reported `updatedInput` is the one sent with the winning decision.
334
+
335
+ ### Patch Changes
336
+
337
+ - 10597b2: Apply command-hook PreToolUse input rewrites only after every enforcing hook evaluates the final
338
+ input. Permission checks and tool execution share those arguments; rewrite cycles and replacements
339
+ that a delegated or already-settled action cannot apply are refused.
340
+ - Updated dependencies [41cca13]
341
+ - Updated dependencies [ada3841]
342
+ - Updated dependencies [5093a30]
343
+ - Updated dependencies [94b2c87]
344
+ - Updated dependencies [3ab2eca]
345
+ - @robota-sdk/agent-core@3.0.0-beta.85
346
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.85
347
+ - @robota-sdk/agent-interface-session@3.0.0-beta.85
348
+ - @robota-sdk/agent-file-authority@3.0.0-beta.85
349
+
350
+ ## 3.0.0-beta.84
351
+
352
+ ### Minor Changes
353
+
354
+ - 9f46375: A session can save a pending tool approval and answer it after it is reopened.
355
+ `Session.runRecoverable()` runs a prompt with a host-owned execution journal from
356
+ `@robota-sdk/agent-core`. When a tool call needs approval, it returns `waiting` with the saved
357
+ request (the exact action and its arguments) instead of asking a live approver.
358
+ `Session.resumeRecoverable()` takes the answer and continues that execution without adding another
359
+ user message; a session recreated with the same session ID, workspace, provider and model can do the
360
+ same. Ordinary `run()` keeps asking for approval live.
361
+
362
+ An approval covers only the action and arguments it was given; it never grants session-wide consent.
363
+ Current permissions, hooks and task restrictions are still checked when the tool runs, and a saved
364
+ denial holds even if the policy has since become more permissive. Reusing a response ID with
365
+ different content is refused.
366
+
367
+ While an execution waits, the session refuses new prompts. `Session.getPendingExecution()` returns
368
+ its `executionId` and saved requests, also after a cancellation that ended the turn once the wait
369
+ was saved. A resume refused before it continues, such as a stale response or a storage failure,
370
+ leaves the execution pending for another attempt; once it has continued, a later failure ends it
371
+ like an ordinary turn. `Session.abandonPendingExecution(executionId)` gives it up so the session
372
+ accepts new input: nothing runs and nothing is written to the journal, its open tool calls are
373
+ closed as failed in history, and that execution can no longer be resumed. The same journal also
374
+ records compaction's model call before history changes, and a journal write failure stays a failure
375
+ even when the turn is being cancelled.
376
+
377
+ ### Patch Changes
378
+
379
+ - Updated dependencies [9f46375]
380
+ - Updated dependencies [e8d70ac]
381
+ - Updated dependencies [9c6a8db]
382
+ - Updated dependencies [9c6a8db]
383
+ - @robota-sdk/agent-core@3.0.0-beta.84
384
+ - @robota-sdk/agent-interface-session@3.0.0-beta.84
385
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.84
386
+ - @robota-sdk/agent-file-authority@3.0.0-beta.84
387
+
388
+ ## 3.0.0-beta.83
389
+
390
+ ### Minor Changes
391
+
392
+ - e689c8e: Follow-ups to connection approval and `/handoff`.
393
+
394
+ - `agent-transport-webrtc-web` — the browser remote client says `Waiting for the host to approve this connection…`
395
+ (`awaiting-approval`) after pairing, and `Connected` only once the host's session answers. A host that closes the
396
+ channel instead is shown as `refused` and is not retried, since a retry would only ask the operator again; a
397
+ first connection lost before the host answered is `failed`. Reconnect attempts count until the host admits a
398
+ connection, so a link that keeps dropping while approval is pending gives up instead of asking again and again.
399
+ - `agent-core`, `agent-session`, `agent-framework` — a turn that did not come from the operator stores its
400
+ `turnSource` (`peer`, `external`, `agent-wakeup`) beside `driverId` on the user message and in the display
401
+ history (`IRunOptions.turnSource`), so a session handed off keeps where each turn came from.
402
+ - `agent-cli` — a `/handoff` resent after a lost confirmation reports what stays behind as it is now, not as it was
403
+ at the first attempt, and after refusing to resend a session that changed, the hand-off status shows that refusal
404
+ instead of the earlier lost confirmation.
405
+
406
+ ### Patch Changes
407
+
408
+ - be0e53c: A tool instance shared by several sessions sends each call's span to the session that made the call.
409
+
410
+ - **Before:** each session set its event service on the shared instance, so the span went to whichever session had set it last.
411
+ - **`agent-core`:** `IToolExecutionContext` gains an optional `instanceEventService`. `FunctionTool` emits its span there when a call carries one.
412
+ - **`agent-session`:** the permission wrapper keeps its session's service and passes it with every call.
413
+
414
+ - 57280bf: Every published package now declares `"engines": { "node": ">=22.12.0" }`. Before, 27 of the 38
415
+ packages declared no floor (`agent-core`, `agent-tools` and every provider among them),
416
+ `agent-session` and `agent-file-authority` declared `>=20.19.0`, and the other nine declared
417
+ `>=22.0.0`, so a consumer on Node 20 saw at most a warning from a transitive dependency.
418
+
419
+ Why 22.12: `agent-cli` and `agent-ui-terminal` need Node 22 through `ink` 7, and the CommonJS entries
420
+ of `agent-tools` and its dependents, `agent-transport`/`node` and its dependents, and
421
+ `agent-ui-terminal` `require()` ESM-only dependencies (`p-limit`, `jose`, `chalk`), which Node 22
422
+ supports unflagged only from 22.12. `engines` is advisory unless the consumer enables `engine-strict`.
423
+
424
+ No code changes: `tsdown` now reads `node22.12.0` as its build target from the field.
425
+
426
+ - 18c0d5c: Every published package now exports `./package.json`, so `require('<package>/package.json')` and
427
+ `import('<package>/package.json', { with: { type: 'json' } })` work instead of failing with
428
+ `ERR_PACKAGE_PATH_NOT_EXPORTED`, and each tarball now ships the package's `CHANGELOG.md`.
429
+ - Updated dependencies [e689c8e]
430
+ - Updated dependencies [7b72344]
431
+ - Updated dependencies [6ae3f28]
432
+ - Updated dependencies [be0e53c]
433
+ - Updated dependencies [57f57f5]
434
+ - Updated dependencies [ba822c1]
435
+ - Updated dependencies [6e6b06b]
436
+ - Updated dependencies [8bd5fac]
437
+ - Updated dependencies [57280bf]
438
+ - Updated dependencies [5033dd9]
439
+ - Updated dependencies [18c0d5c]
440
+ - Updated dependencies [dbd888d]
441
+ - Updated dependencies [1887e54]
442
+ - @robota-sdk/agent-core@3.0.0-beta.83
443
+ - @robota-sdk/agent-interface-session@3.0.0-beta.83
444
+ - @robota-sdk/agent-file-authority@3.0.0-beta.83
445
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.83
446
+
447
+ ## 3.0.0-beta.82
448
+
449
+ ### Minor Changes
450
+
451
+ - c7f9203: Connected sessions can send each other files.
452
+
453
+ - `/peers send-file <session-id> <path>` sends a copy of any file the operator can read to another
454
+ live session on this host.
455
+ - The model sends a file only through the `peer_send_file` tool. Every call asks the user, showing
456
+ the path, size, hash and destination; no permission mode, rule or remembered consent answers it.
457
+ The tool reaches only files inside the workspace whose path does not look like it holds secrets
458
+ (`.env*`, `~/.ssh`, keys and credentials), and it does not exist in a turn a peer's message started.
459
+ - The receiving operator approves every file. A received file is kept as an inert copy (mode 0600)
460
+ under `$PRODUCT_USER_STATE_DIR/peer-files/<sender>/`. It is never run and never placed in the model's context.
461
+ The conversation is told only its name, size and sha256. A name that leaves that directory is
462
+ refused, a symbolic link is never written through, and nothing is overwritten.
463
+ - Transfers travel on a channel of their own (a separate connection on this host, a separate data
464
+ channel between devices), in chunks the receiver paces, up to 32 MiB, and are kept only when the
465
+ whole content matches the offered sha256. A transfer that ends early is discarded; there is no
466
+ resume.
467
+
468
+ **API**
469
+
470
+ - `agent-interface-session-mobility`: the `file` capability, which asks the operator for every
471
+ request; `ConnectionAuthority.authorizeFile`; `IFileOffer` and `IFileFrameChannel`.
472
+ - `agent-transport/node`: `sendFileOverChannel` and `receiveFileOverChannel`, the carrier over any
473
+ `IFileFrameChannel`; `DEFAULT_MAX_FILE_BYTES`.
474
+ - `agent-transport-webrtc`: `IDeviceMeshLink.openFileChannel` and `onFileChannel`.
475
+ - `agent-remote-pairing`: `file` joins `DEVICE_CAPABILITIES`. A device certificate that names it is
476
+ refused as malformed by an earlier version.
477
+ - `agent-core`: `IToolPermissionProfile.notInPeerTurn` withholds a tool from a turn a peer's message
478
+ started.
479
+ - `agent-framework`: `ICommandLocalPeersAdapter.prepareFile`.
480
+
481
+ ### Patch Changes
482
+
483
+ - Updated dependencies [c7f9203]
484
+ - @robota-sdk/agent-core@3.0.0-beta.82
485
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.82
486
+ - @robota-sdk/agent-interface-session@3.0.0-beta.82
487
+ - @robota-sdk/agent-file-authority@3.0.0-beta.82
488
+
489
+ ## 3.0.0-beta.81
490
+
491
+ ### Minor Changes
492
+
493
+ - 3038eb7: A message from another session is instant messaging: text from an untrusted third party that
494
+ carries no authority. What the model does with it is decided by the session's ordinary permissions —
495
+ rules, permission mode and remembered consent — exactly like the session's own work. The per-origin
496
+ peer policy is gone.
497
+
498
+ **BREAKING**
499
+
500
+ - `agent-core`: `IPermissionEvaluationContext.peerTurn` is now a boolean. It decides only whether a
501
+ `repliesToPeer` tool exists; every other call in a peer turn is decided as in any turn. Removed:
502
+ `isToolAvailableInPeerTurn`, `isSecretPath`, `IPeerTurnAuthority`, `TPeerReach` (now exported by
503
+ `agent-interface-session-mobility`) and `IToolPermissionProfile.workspacePaths`.
504
+ - `agent-tools`: `Read` and `Glob` no longer declare `workspacePaths`.
505
+ - `agent-session`: `ISessionRunOptions.peerReach` is replaced by `peerTurn?: boolean`, and
506
+ `ISessionOptions.allowPeerChanges` is removed. An ask in a peer turn is answered like any other:
507
+ a consent the operator remembered answers it, and an "always allow" given there is remembered.
508
+ - `agent-interface-session`: `IPeerTurnContext` no longer has `reach`; it carries only the reply
509
+ route.
510
+ - `agent-interface-session-mobility`: `peerReachOf` is removed; `TPeerReach` moves here. A delegated
511
+ turn carries no reach.
512
+ - `agent-framework`: the `peers.allowChanges` setting is removed (an existing value is ignored). A
513
+ peer turn is offered the ordinary tools, plus `peer_reply`.
514
+
515
+ **Changes**
516
+
517
+ - `agent-framework`: the per-turn statement tells the model the message is an opinion from an
518
+ untrusted third party, not its owner's instruction, and that it decides for itself whether and how
519
+ to act. A message still expands no `@path` and attaches no context reference, and its requests
520
+ still carry no provider-hosted tool, since no permission step can decide one. The session takes
521
+ at most 6 messages a minute and 30 an hour from each sender for a turn; a message over the limit
522
+ is refused with a reason the sender receives. A prompt answer given in the name of a `peer:` or `external:`
523
+ driver is ignored. External-event turns keep their tool-less baseline.
524
+ - `agent-cli`: incoming peer turns carry only their reply route.
525
+
526
+ - 02b7452: A reply to a peer session is decided by the permission system like any call that sends something
527
+ off this machine, and it goes only to the sender that was admitted.
528
+
529
+ - `agent-core` — a tool declaring `repliesToPeer` is still refused outside a peer turn; inside one it
530
+ is decided by the ordinary steps: deny, ask and allow rules, then the mode. It declares no risk
531
+ class, so it asks by default, is refused in plan mode and proceeds under bypass. `IPeerTurnAuthority`
532
+ no longer has `toolUsed`.
533
+ - `agent-session` — an "always allow" answer to the reply is remembered and answers later replies,
534
+ as for any tool; other asks in a peer turn still need a fresh approval each time.
535
+ - `agent-framework` — `peer_reply` asks the operator by default, showing the full text and the peer
536
+ it goes to; `permissions.allow`/`deny` rules naming `peer_reply` apply. `PeerMessageIngress`
537
+ refuses a message whose origin names a sender other than the admitted one, or whose admission names
538
+ no sender, and submits the turn with the admitted identity.
539
+ - `agent-cli` — a local peer message is taken as coming from the session it names only when that
540
+ session confirms, at its own socket, that it is sending exactly that message to this receiver.
541
+ The reply target, the driver id and the operator's notices come from the confirmed sender. A
542
+ session on an earlier version cannot confirm, so its messages are refused; both sessions need this
543
+ version to message each other.
544
+
545
+ - 18b52cc: Built-in commands are offered to the model deliberately, each described for the model, and never
546
+ with a trust, credential or permission-widening action.
547
+
548
+ - `agent-interface-command` — `ICommand` gains `modelDescription?` (what the model is told, beside the
549
+ short `/help` line), and `modelInvocable` on a subcommand entry now narrows what the model may run.
550
+ - `agent-framework` — `ISystemCommand` gains `modelDescription?` and `modelRequiresPermission?`.
551
+ Once any subcommand of a model-invocable command declares `modelInvocable`, the model may run only
552
+ the bare command and the subcommands declared `true`; everything else, including an alias or an
553
+ undeclared subcommand, is refused before the command runs. The model-facing descriptor lists only
554
+ that subset. A model-requested monitor's command is now decided by the shell tool's gate (its
555
+ Bash/Shell rules, the mode and the prompt) and a refusal rejects with the new
556
+ `MonitorCommandRefusedError`. The `scriptedSession` test harness accepts `permissions` patterns.
557
+ - `agent-session` — `Session.checkToolPermission(toolName, toolArgs)` decides an action that has a
558
+ tool's effect by another route: that tool's PreToolUse hooks, then the gate's rules, mode,
559
+ remembered consent and prompt — never the command sandbox's auto-approval, since the action does
560
+ not run inside the sandbox.
561
+ - `agent-framework` also: `ICommandMCPActivationAdapter.userActionSurface?` tells `/mcp` whether the
562
+ user can type a session command, so the model's status names the terminal sign-in otherwise.
563
+ - `agent-command` — `/context` (bare and `list`), `/cost` (the report, not `budget`) and `/mcp`
564
+ (`status` only, without a prompt) are now model-invocable; `/memory approve` and `/memory reject`
565
+ are now user-only; the model's `/monitor` is decided by the shell gate rather than by consent to
566
+ the command's name. Every model-invocable command carries a model-facing description. The model's
567
+ `/mcp status` shows only safe names, states and the command to suggest, and a caller that does not
568
+ identify itself gets that view. `/context list` accounts only for turns still in context. New
569
+ `mcpUserActionNotice`, `mcpUserActionCommand` and `mcpUnavailableServersNotice` build the fixed
570
+ notices.
571
+ - `agent-command-workflows` — `/workflows` carries a model-facing description.
572
+ - `agent-mcp` — `createDiscoveredTool` accepts `authFailureNotice`: a call the server refuses for
573
+ authentication returns that host text instead of the generic failure.
574
+ - `agent-cli` — an MCP server that did not start because the user must approve it, trust the
575
+ workspace or sign in is named to the model at the start of an interactive session with the
576
+ command to suggest, and a
577
+ signed-in OAuth server that refuses a call tells the model to suggest `/mcp login <server>` — or, in print and serve runs, the terminal
578
+ `robota mcp login <server>`.
579
+
580
+ A command whose bare form is a complete action declares `runsBare`, so choosing `/cost` or `/mcp`
581
+ from the autocomplete menu still runs it even though they now declare subcommands.
582
+
583
+ - 9843fe6: Sign in to a remote MCP server from inside a session, and use its tools without restarting.
584
+
585
+ - **`/mcp login <server> [--no-browser]`** runs the same per-server OAuth sign-in as
586
+ `robota mcp login` (discovery checks, PKCE, `state`, RFC 9207 `iss`, RFC 8707 resource, the
587
+ loopback listener, the lock-guarded store). It opens the browser through the argv opener; with
588
+ `--no-browser`, or when no browser can be opened, it shows the authorization URL and asks for the
589
+ redirect URL in the session's own prompt (masked), held to the same rules as a pasted redirect in
590
+ the terminal. A failed, refused, timed-out or cancelled sign-in changes nothing and is reported by
591
+ a fixed reason only. `/mcp login <server> --client-secret` is refused: a secret is never typed into
592
+ a session, and `robota mcp login <server> --client-secret` is named instead (also after a failed
593
+ token exchange for a pre-registered client). `/mcp` stays user-only (`modelInvocable: false`).
594
+ - **Connected in the same session:** after a sign-in, a server that could not connect for want of
595
+ one goes through the normal admission (approval, fingerprint, trust) and connects, and its tools
596
+ are offered from the next message; a server that was already connected is admitted again and
597
+ reconnects, and its authenticator drops what it held and reads the new credential. A tool left out
598
+ because the session already has its name is reported, and only tools actually added get
599
+ provenance. In browser mode the authorization URL is shown in the session prompt before the
600
+ browser opens, where the user can also choose to paste the redirect instead or cancel.
601
+ - **`runMCPOAuthLogin`** takes `readRedirectWhenBrowserFails`: when `openBrowser` rejects, the
602
+ loopback listener stops and the pasted redirect is read instead, for the same redirect URI. The
603
+ loopback listener's time limit now runs from its first `wait()` — once the authorization page is
604
+ handed over — so time spent at a prompt before the browser opens does not count against it.
605
+ - **`Session.addTools`** (and `ICommandSessionTools.addTools`) offers tools that became usable
606
+ mid-session, through the same permission gate and — via `ISessionOptions.wrapAddedTools`, which
607
+ `createSession` sets — the same edit-checkpoint and reversible-execution wraps as the assembled
608
+ tools. A name the session already has is left out, never replaced. Calls are serialized, and tools
609
+ added while a turn runs are applied when the next turn starts, so a turn's rounds all see one
610
+ tool list and the prompt cache misses once, at that boundary.
611
+ - **Breaking (`agent-framework`, major):** `addTools` is a new required member of the
612
+ `ICommandSessionTools` role port (and so of `ICommandSessionRuntime`). A host that implements the
613
+ port itself must add it; one that passes an `agent-session` `Session` already has it.
614
+ - **`ICommandMCPActivationAdapter.oauthLogin`** (`ICommandMCPOAuthLoginRequest`,
615
+ `ICommandMCPOAuthLoginResult`, `ICommandMCPOAuthRedirectPrompt`) is the port behind it.
616
+ - The sign-in notice and `/mcp status` now suggest `/mcp login <server>` in a session and
617
+ `robota mcp login <server>` in a terminal; the server's name is shown only when it is safe to paste
618
+ into any shell, otherwise `<server>`.
619
+
620
+ ### Patch Changes
621
+
622
+ - Updated dependencies [3038eb7]
623
+ - Updated dependencies [02b7452]
624
+ - Updated dependencies [ec5e477]
625
+ - @robota-sdk/agent-core@3.0.0-beta.81
626
+ - @robota-sdk/agent-interface-session@3.0.0-beta.81
627
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.81
628
+ - @robota-sdk/agent-file-authority@3.0.0-beta.81
629
+
630
+ ## 3.0.0-beta.80
631
+
632
+ ### Major Changes
633
+
634
+ - 807d161: **BREAKING — ARCH-010: the execution root is a required contract field, and the containment guard now fails closed.**
635
+
636
+ The file-tool containment guard was fail-open: with no root configured it answered "allowed". A tool
637
+ built with no `cwd` therefore had no boundary — measured, a `Read` constructed that way returned the
638
+ contents of `/etc/hostname` — and the child-process subagent worker called `createDefaultTools()` with
639
+ no argument at all, so subagents got exactly that. Three independent auditors found three different
640
+ symptoms of this one missing field.
641
+
642
+ **Removed — seven context-free tool singletons.** `readTool`, `writeTool`, `editTool`, `globTool`,
643
+ `grepTool`, `shellTool`, `bashTool` are gone from `@robota-sdk/agent-tools`. A module-level instance is
644
+ bound at import time and can carry no containment root, so after the guard was inverted they could only
645
+ refuse everything.
646
+
647
+ Migrate to the factory of the same name, passing the directory the tool is allowed to work in:
648
+
649
+ ```ts
650
+ // before
651
+ import { readTool, globTool } from '@robota-sdk/agent-tools';
652
+ const tools = [readTool, globTool];
653
+
654
+ // after
655
+ import { createReadTool, createGlobTool } from '@robota-sdk/agent-tools';
656
+ const cwd = process.cwd(); // or the workspace this agent is scoped to
657
+ const tools = [createReadTool({ cwd }), createGlobTool({ cwd })];
658
+ ```
659
+
660
+ `webFetchTool`, `webSearchTool` and `askUserQuestionTool` are unchanged — they touch no filesystem, so
661
+ there is no root to contain them by.
662
+
663
+ **`cwd` is now REQUIRED** on `ISandboxToolOptions`, `IContainedBuiltinToolOptions` (and everything
664
+ extending them), `ICreateDefaultToolsOptions`, `ISessionOptions` and `ISubagentOptions`. The `= {}`
665
+ default parameter was removed from every builtin factory — that default was the mechanism by which
666
+ "forgot the root" was legal. `new Session({...})` without `cwd` no longer compiles, and also throws at
667
+ construction, because a required field is only required to a TypeScript caller.
668
+
669
+ **`Session` no longer reads `process.cwd()`.** It uses the root it was given, and `getCwd()` exposes it
670
+ so a fork or subagent asks the session instead of re-deriving a root that can disagree with it.
671
+
672
+ **Behavioural change even for callers that already passed a root**: a tool that somehow reaches the
673
+ guard with no root now REFUSES with an explicit error ("no containment root is configured … this is an
674
+ assembly bug, not a path problem") instead of allowing the access.
675
+
676
+ - 64ba748: **BREAKING — ARCH-042: project filesystem access is now an explicit, host-issued authority instead of an ambient consequence of `cwd`.**
677
+
678
+ `@robota-sdk/agent-framework` adds `WorkspaceTrustService` and the opaque
679
+ `IWorkspaceProjectAuthority`, plus bounded reader, settings-writer, state-storage, and mutation
680
+ facets. Public session, settings, context, checkpoint, memory, contribution, query, and replay
681
+ contracts consume those facets. A caller that does not supply `projectAccess` is deliberately
682
+ restricted to user-owned host state and receives no project filesystem capability.
683
+
684
+ The framework removes or renames ambient Node/project exports. Migrate `checkSettingsFile` to
685
+ `checkNodeHostSettingsFile`, `readMergedProviderSettingsFromPaths` to
686
+ `readMergedProviderSettingsFromSources`, `resolveProviderSettingsWriteTargetPath` to
687
+ `resolveProviderSettingsWriteTarget`, `FileSystemMemoryStore` / `createFileSystemMemoryStore` to
688
+ `WorkspaceMemoryStore` / `createWorkspaceMemoryStore`, and `PluginSettingsStore` to
689
+ `NodeHostPluginSettingsStore`. Host-only git helpers now carry the `FromNodeHost` suffix.
690
+ `projectPaths`, `resolveSettingsPathForScope`, and `getProviderSettingsPaths` are removed; project
691
+ consumers must use the authority facets rather than recover absolute paths.
692
+
693
+ `@robota-sdk/agent-session` renames the Node filesystem implementation `SessionStore` to
694
+ `NodeSessionStore` and adds explicit session-log/external-payload source and sink ports. Session
695
+ replay no longer resolves external payload files from an ambient directory.
696
+
697
+ `@robota-sdk/agent-interface-transport` changes `ISkillExecutionPort.loadCommands(cwd, home?)` to
698
+ the authority-bound `loadCommands()` and removes the optional absolute-path leak
699
+ `IInteractiveSessionStore.getFilePath`. `@robota-sdk/agent-command` consequently replaces the
700
+ `cwd` option of `createSkillsCommandModule` with required `contributionSources`; default command
701
+ composition accepts explicit contribution sources and discovers no project skills when none are
702
+ provided.
703
+
704
+ `@robota-sdk/agent-cli`, `@robota-sdk/agent-transport`, and
705
+ `@robota-sdk/agent-transport-tui` thread the trusted-or-restricted project decision through every
706
+ session surface. Embedded callers that need project settings, state, context, skills, checkpoints,
707
+ or mutation must mint access through `WorkspaceTrustService` and pass the returned
708
+ `projectAccess` (and a separately approved mutation/settings facet where required). Omitting it is
709
+ still type-compatible but is behaviorally breaking: the surface now fails closed instead of
710
+ reading or writing the current directory.
711
+
712
+ - 242a644: Require versioned, event-decoded session replay logs. Reject unknown, malformed, and unsupported
713
+ entries instead of dropping them or inventing message fields. Replay-only session loads and lists
714
+ report damaged logs explicitly. Legacy unversioned JSONL is not accepted; snapshot encoding remains
715
+ unchanged. Persisted logs now use schema version 1, and all replay entry points share the session-owned
716
+ decoder and preserve sidecar integrity failures.
717
+
718
+ ### Minor Changes
719
+
720
+ - 9368d00: Advisor escalation: the main model can consult a second model at the decision points it chooses.
721
+
722
+ With an advisor configured (`--advisor <profile>[:<model>]`, or the `advisorModel` setting that
723
+ `/advisor` saves; the flag wins), the session gets an `Advisor({ question? })` tool. The advisor reads
724
+ the whole conversation — system prompt, messages, tool calls and results — serialized into one prompt
725
+ and sent with `toolChoice: 'none'`, truncated from the front to fit its window with the system prompt
726
+ kept, and declines when even that does not fit. Its answer comes back framed as guidance to verify;
727
+ an empty or refusing answer reads as declined. Calls are limited to two per turn and a fixed number
728
+ per session, parallel calls in one round share those limits, and a repeated question in the same
729
+ turn returns the earlier answer. A request that was sent counts even when the provider failed (the
730
+ decline is reported by class, never by its text); only a call declined before sending gives its slot
731
+ back.
732
+
733
+ Advisor usage, including in-process subagents', is recorded where each turn's usage is recorded —
734
+ the persisted session history, under the advisor's own provider and model — so `/cost`, usage reports
735
+ and resumed sessions include it. `/cost` now totals that history and prices each part on its own
736
+ model, showing "mixed" when more than one model was priced.
737
+
738
+ `/advisor <model>` and `/advisor off` change only where calls go, never the tool list, so the main
739
+ model's prompt cache is not invalidated mid-session; the tool is added only when a session starts
740
+ with an advisor. Sending history to a destination (provider type and endpoint host) the main model
741
+ does not already use needs a one-time consent per destination, kept in the user settings file; a
742
+ refusal is remembered for the session. The organization's `allowedProviders` applies, and
743
+ `PRODUCT_DISABLE_ADVISOR=1` turns it off completely. In-process subagents inherit the advisor, bound
744
+ to their own conversation; child-process subagents do not get it.
745
+
746
+ **`@robota-sdk/agent-framework` is `major` for one reason: `ICommandHostSessionAccess` gains a
747
+ required member,** `getSessionUsage()`, the session's persisted usage records. An external
748
+ implementation of that role port stops compiling until it adds the method. The rest is additive.
749
+
750
+ - `agent-session` — `formatConversationEntries`, the one text rendering of a conversation, now used
751
+ by compaction too. It keeps tool calls and results, marks a user message a peer session sent
752
+ (`user [from "peer:<id>"]`), and JSON-encodes every message onto one line so no content can forge
753
+ another entry; compaction previously flattened all of this. `Session.getProvider()` returns the
754
+ provider the session currently uses.
755
+ - `agent-framework` — `AdvisorController`, `createAdvisorTool`, the advisor spec helpers, provider
756
+ destinations (`describeProviderDestination`, `rememberProviderDestination`), `getSessionUsage` and
757
+ `ISessionUsageRecord`, the `onUsageRecorded` session option, and the optional `advisor` command
758
+ host adapter. Session assembly binds a host-supplied Advisor tool to the session holding it.
759
+ - `agent-command` — the `/advisor` command module; `/cost` reads the session's persisted usage.
760
+ - `agent-cli` — the `--advisor` flag, `advisorModel` setting, per-destination consent store and kill
761
+ switch.
762
+ - `agent-ui-terminal` — a usage line from another source (the advisor, a background task) names that
763
+ source and leaves out the context window it does not have.
764
+ - `agent-session-analytics` — personal usage counts an advisor call's tokens and cost toward its
765
+ turn without counting it as a turn.
766
+
767
+ - 4078a72: Model fallback chain. `--fallback-model a,b` (or the `fallbackModel` settings array; the flag wins) names up to three models a turn moves to when its model is overloaded, unavailable or failing on the server. An entry is a provider profile, `profile:model`, a bare model on the primary's provider, or `default`. The move happens only before any output has streamed, lasts for the current turn, and is shown as a system note; entries that cannot be built are passed over and entries outside the organization's `allowedProviders` are dropped with a notice. `FallbackProvider` in agent-framework implements it over the session's provider; `IChatOptions` gains `executionId`, `onModelFallback` and `preserveContextWindow`, `IAIProvider` gains optional `resolveModelRoute`, and the execution loop emits a `provider_fallback` event and attributes requests, call observations, committed replies, the response cache and usage to the model that answered. A turn that ran on more than one model records per-model `modelShares` on its usage observation, which personal usage reports split by model and provider. A `/provider` switch keeps the chain, read again for the new primary.
768
+ - 196a900: Permission rules can say more than one argument per tool.
769
+
770
+ - **`Tool(name:value)` in deny and ask rules** matches a named top-level parameter, with `*` in the
771
+ value (`Bash(run_in_background:true)`, `Agent(model:opus*)`, `github__create_issue(repo:acme/*)`).
772
+ It is a parameter rule only when `name` is one of the tool's parameters, so
773
+ `WebFetch(https://…)` keeps its meaning. A parameter the call omits never matches, and a
774
+ non-scalar value is unevaluable, so the call asks. Allow rules may not use the form.
775
+ - **A rule on the primary field** (`Bash(command:rm *)`) is reported at startup and asks on every
776
+ call, instead of being silently ignored.
777
+ - **Tool-name globs.** Deny and ask rules may glob the tool name (`github__*`). Allow rules may do so
778
+ only after a literal `<server>__` prefix; an unanchored allow glob is refused at construction.
779
+ - **A bare-name deny removes the tool from the model's context.** `Tool`, `Tool(*)` or a name glob
780
+ withholds it from the offered set and the deferred-tool catalogue, live, instead of offering it
781
+ and refusing every call. `IAgentConfig.isToolVisible` is the new seam.
782
+ - **MCP canonical names keep the whole `<server>__` prefix when truncated**, so a server glob still
783
+ names every tool of that server.
784
+
785
+ - f336838: One permission evaluation order for every caller. The interactive session, background tasks and
786
+ subagents used to run two different resolvers, so the same call could be decided differently
787
+ depending on who made it. They now share `evaluatePermission`, and a background policy only adds a
788
+ ceiling, an ask-everything flag and the task's own lists to it:
789
+
790
+ deny → caller ceiling → unevaluable deny (ask) → never-auto-approve set (ask) → ask-everything →
791
+ bypassPermissions → allow → mode.
792
+
793
+ - **`ask` rules.** `permissions.ask` patterns always ask, in every mode including
794
+ `bypassPermissions`. They are matched per command like a deny rule, and are validated at
795
+ construction alongside `allow` and `deny`.
796
+ - **Never auto-approved, bypass included:** removing a critical path with `rm`/`rmdir` (the root, a
797
+ top-level directory, home, the working directory or a parent), and a modify-class write into
798
+ `.git`, `.Robota`, `.claude`, `.agents`, `.mcp.json`, `.gitconfig`, `.npmrc` or a shell rc file.
799
+ Files inside an isolated worktree (`$PRODUCT_PROJECT_STATE_DIR/worktrees/<name>/…`) are ordinary files. With no
800
+ approver attached, an ask is a denial.
801
+ - **A ceiling is checked before bypass and before any ask.** A subagent's `inherit-allowlist` ceiling
802
+ is now the parent's _effective_ rules, read live at spawn: settings, preset lists and command
803
+ auto-allows. It used to be the raw settings file. An unevaluable deny under a policy now asks,
804
+ like everywhere else, where it used to deny outright; with no approver it is still a denial.
805
+ - **Settings layers union `permissions.allow`**, as they already did `deny`. A checked-in project
806
+ file no longer silently discards the user's allow list.
807
+ - **Print mode, `createQuery()` and headless sessions default to `default` mode**, not
808
+ `bypassPermissions`. They have no approver, so a call that would ask is denied. Pass
809
+ `--permission-mode` / `permissionMode: 'bypassPermissions'` explicitly for unattended runs.
810
+
811
+ **Breaking:**
812
+ - `@robota-sdk/agent-core` removes `resolvePermissionByPolicy` and `TPermissionPolicyDecision` in
813
+ favour of `projectPermissionPolicy` plus `evaluatePermission`'s new `context` argument.
814
+ - `@robota-sdk/agent-framework` changes the settings merge rule for `permissions.allow`, and the
815
+ default permission mode of `createQuery()` and headless sessions.
816
+
817
+ - 34e50f0: A new permission mode, `auto`, lets a model classifier approve or block what would otherwise prompt.
818
+
819
+ - **What it decides:**
820
+ - Reads and in-workspace edits run as in `acceptEdits`.
821
+ - Commands and other calls the mode leaves open go to the classifier, a side call to the
822
+ session's own model. It sees the call, the working directory and the git remotes, never the
823
+ conversation.
824
+ - A block reaches the model with its reason, so it can take another route.
825
+ - **What still reaches a person, or is refused:**
826
+ - Deny rules and background ceilings apply first.
827
+ - `ask` rules, critical removals and protected paths ask a person.
828
+ - After 3 refusals in a row (blocks, or no usable verdict), or 20 blocks in the session, the
829
+ mode asks a person until one approves.
830
+ With no one to ask, the call is denied.
831
+ - **Allow rules:** in `auto` mode, allow rules that approve any command are set aside while the
832
+ mode is on. Examples are `Bash(*)`, an interpreter (`Bash(python *)`), a package runner
833
+ (`Bash(npm run *)`, `Bash(pnpm exec *)`), `Agent`, `ExecuteCommand` or `Computer`. Narrow
834
+ rules still apply.
835
+ - **Retry:** `/permissions` lists classifier blocks. `/permissions retry <n>` lets that exact call
836
+ run once, unjudged, when the model tries it again.
837
+ - **Turning it on and off:**
838
+ - `--permission-mode auto`, `/mode auto` or `/permissions auto`.
839
+ - An organization turns it off with `disableAutoMode` in the org policy.
840
+ - **New contracts:**
841
+ - `TPermissionMode` gains `'auto'`.
842
+ - `allowRulesForAutoMode` and `isBroadExecutionAllowRule`.
843
+ - `IPermissionClassifier` and `AutoModeGate`.
844
+ - The `permissionClassifier` session option.
845
+ - `Session.retryPermissionDenial`, and `retryDenial` on the permission-mode adapter.
846
+ - The `'classifier'` denial reason.
847
+ - `createModelPermissionClassifier`.
848
+ - The `disableAutoMode` option on `createSession` and `IOrgPolicy`.
849
+
850
+ - 722e88a: Shell commands can run in an OS-level sandbox: bubblewrap on Linux and WSL2, Seatbelt on macOS.
851
+
852
+ - **Confinement:** covers the command and every process it starts.
853
+ - Writes are limited to the working directory, the temporary directories and
854
+ `sandbox.filesystem.allowWrite`.
855
+ - Agent, git-hook, MCP and shell configuration inside the workspace stays read-only.
856
+ - `sandbox.filesystem.denyRead` hides paths from the command.
857
+ - The network is on or off (`sandbox.network.enabled`).
858
+ - **Modes:** `/sandbox` switches between `auto-allow`, `regular` and `off` for the next command and
859
+ saves the choice.
860
+ - In `auto-allow` (`sandbox.autoAllowBashIfSandboxed`), a confined command runs without a prompt
861
+ in `default` and `acceptEdits`.
862
+ - Deny rules, ask rules, critical removals and plan mode still apply first.
863
+ - **Exclusions:** `sandbox.excludedCommands` run unconfined, through the ordinary permission path.
864
+ - **When the sandbox cannot run:** a missing or unusable backend is reported at startup, in
865
+ `robota doctor` and in `/sandbox`, and commands then run unconfined.
866
+ `sandbox.failIfUnavailable` refuses to start instead.
867
+ - **New contracts:**
868
+ - `OsSandboxClient`, `detectOsSandbox`, `bubblewrapArguments`, `seatbeltProfile`.
869
+ - `ISandboxClient.wrapCommand` and `autoApproves`.
870
+ - `IPermissionEvaluationContext.sandboxAutoApproved`.
871
+ - The `commandSandbox` session option.
872
+ - The `sandbox` settings key and the `sandbox` command host adapter.
873
+
874
+ - a5cc36e: `/permissions` shows the rules the session enforces and the calls it refused.
875
+
876
+ - **Rules by source:** each allow, deny and ask rule the gate reads is listed under the settings file
877
+ that declares it. Rules added by a CLI flag, a preset or a command are listed under "this session".
878
+ A rule a settings file declares but the session does not enforce is not shown.
879
+ - **Recent denials:** the latest refused calls, most recent first, with the reason: a rule or the
880
+ mode, the user declining, or no one available to approve.
881
+ - New contracts: `Session.getRecentPermissionDenials()`, `PermissionEnforcer.getRecentDenials()`,
882
+ `IPermissionDenial`, the `permissionRules` host adapter (`createSettingsPermissionRulesAdapter`),
883
+ and `getPermissionRules` / `listRecentDenials` on `ICommandPermissionModeAdapter`. Settings
884
+ provenance now covers `permissions.ask`.
885
+
886
+ - d23c848: Built-in read-only shell commands run without a prompt.
887
+
888
+ A Bash call is decided like a read, and runs without a prompt in every mode (`plan` included), when
889
+ every command in it comes from the fixed read-only set (`ls`, `cat`, `grep`, `find` without actions,
890
+ `git status`/`log`/`diff`/`show` and similar) and it also:
891
+
892
+ - stays inside the workspace: every path operand resolves inside once symlinks are followed, as
893
+ `Read` requires;
894
+ - uses only printable ASCII syntax that bash, zsh, fish and PowerShell all read the same way.
895
+
896
+ Deny and ask rules still apply first. A command that writes through a redirect, expands or
897
+ substitutes anything, or runs git outside the session's repository takes the ordinary path.
898
+
899
+ New exports: `isReadOnlyCommandLine` and `TResolveInWorkspace`. `IPermissionEvaluationContext`
900
+ gains `resolveInWorkspace`, which `PermissionEnforcer` supplies.
901
+
902
+ - b078afa: Restore full-fidelity replay for session-log values externalized to content-addressed sidecar files.
903
+
904
+ `agent-session` now exports a bounded, containment- and integrity-checked recursive payload resolver,
905
+ hydrates JSONL logs at their read boundary, and rejects unresolved replay-substrate values during raw
906
+ validation. `agent-provider-replay` reuses that resolver for direct construction and file loading so
907
+ large recorded responses remain aligned with later calls.
908
+
909
+ - b078afa: Preserve complete resumable session records when the raw Session writer re-saves them.
910
+
911
+ `IInteractiveSessionStore` is now the canonical persistence port, including its optional file-backed
912
+ record-path capability. `agent-session` consumes the canonical record and store contracts directly and
913
+ keeps its former type names only as compatibility re-exports.
914
+
915
+ - 2ebff01: Complete the public session-log event vocabulary for every production writer/reader event and pass
916
+ the session-owned compaction trigger unchanged to PreCompact, PostCompact, logging, and callbacks.
917
+ - 4b76cfa: NEUT-005 (wave 2): restore an actionable context-capacity hint at the surface tier, neutrally. The zero-dependency `agent-core` layer emits a product-neutral hard-capacity notice and exposes the `IAgentConfig.contextCapacityHint` seam (wave 1). This wave wires that seam end-to-end without baking product vocabulary into a neutral library:
918
+
919
+ - `agent-session`: `ISessionOptions.contextCapacityHint` is forwarded into the agent configuration factory, making the core seam reachable from the consuming layer.
920
+ - `agent-framework`: new `deriveContextCapacityHint(commandModules)` derives the concrete remediation wording from the surface's OWN registered command set (names a registered `compact` command → `"Run /compact and retry."`; `undefined` when none, leaving the neutral core default). It is applied automatically in interactive session assembly across the TUI, print, and `--serve` surfaces.
921
+ - `agent-cli`: the default command set registers `/compact`, so end users regain the actionable hint.
922
+ - `agent-interface-transport`: reworded the `'allow-project'` permission comment so it no longer hardcodes a storage path (the location is owned by the consuming layer), matching the `agent-session` twin.
923
+
924
+ - fcb0da3: PAYLOAD-2153: make external-payload replay stable across Linux, macOS, and Windows.
925
+
926
+ - Add the domain-free `@robota-sdk/agent-file-authority` leaf with bounded, root-relative reads over retained native handles and a typed, path-safe refusal taxonomy.
927
+ - Route session replay and framework project reads through the shared authority while preserving their existing domain-specific budgets, integrity checks, and error mappings.
928
+ - Expose the canonical safe session-id predicate through the framework facade so CLI exact-session lookup stays within the SDK package boundary.
929
+ - Package the pinned native bridge in clean-installed Node CLI archives and exact-host standalone Bun binaries, refusing unsupported or mismatched targets before artifact mutation.
930
+
931
+ - 9814afc: Type-SSOT convergence (TYPE-003; re-audit CONTRACT-002/003/011/012 + RUNTIME-47 + STRUCT-04). Behavior is unchanged — this is a type-level refactor. `ITokenUsage` (agent-core) is confirmed as the usage-triple SSOT: `ISessionUsageTotals` and `IBackgroundTaskUsage` become aliases, and every inline `{ promptTokens; completionTokens; totalTokens }` copy (service/orchestration/executor/remote-client shapes) now references the SSOT (structurally identical → patch). The subagent-job contracts derive from the background-task SSOT — `TSubagentJobStatus = Exclude<TBackgroundTaskStatus, 'paused'>`, mode alias, and a `Pick`-projection `ISubagentJobState` — with a compile-enforced parity test so a drifting hand copy can no longer exist. `@robota-sdk/agent-session` is minor because the public `ISessionRecord` type is now the typed `IInteractiveSessionRecord` alias (previously a relaxed `unknown[]` mirror): runtime behavior of `SessionStore` is identical, but downstream code that assigned loose payloads to the record's fields may need explicit casts at its own trust boundary (the framework store facade's `as unknown as` cast bridge is deleted). agent-session's duplicate `@robota-sdk/agent-core` deps/devDeps declaration is also removed (STRUCT-04).
932
+
933
+ ### Patch Changes
934
+
935
+ - 5307f8a: Discriminate `IBackgroundTaskResult` by kind, the same way `TBackgroundTaskRequest` already is:
936
+ `exitCode`/`signalCode` exist only on the `process` member and `usage` only on the `agent` member,
937
+ instead of being optional-and-unreachable on every kind. `IBackgroundTaskResult<K>` narrows to the
938
+ kind-specific member; called with no type argument it is still the full union, which is what
939
+ `IBackgroundTaskState.result` continues to hold (that field stays undiscriminated — a later change).
940
+ `ISubagentJobResult` is now derived as `Omit<IBackgroundTaskResult<'agent'>, 'kind'>` rather than a
941
+ hand-maintained `Omit<IBackgroundTaskResult, 'kind' | 'exitCode' | 'signalCode'>`.
942
+
943
+ `IBackgroundTaskHandle` gains the same kind parameter as `IBackgroundTaskStart`: a runner declared
944
+ for kind `K` resolves its handle's `result` to `IBackgroundTaskResult<K>`, so a caller that starts a
945
+ known-kind runner gets a correctly-narrowed result with no cast, and reading a cross-kind field on it
946
+ is a compile error. Consumers reading `state.result` through the generic (kind-erased) manager or
947
+ task-state path are unaffected in behavior, but a `.exitCode`/`.signalCode`/`.usage` read there must
948
+ now narrow on the result's own `kind` first, since the fallback default keeps `IBackgroundTaskResult`
949
+ as the full union rather than the previously flat, always-present shape.
950
+
951
+ `agent-session`'s session-record decoder now rejects a persisted result carrying a field outside its
952
+ own kind (e.g. an `'agent'` result with `exitCode`) as corrupt, reported at that field's own path —
953
+ the same corruption-reporting style the taskId/kind identity check already uses.
954
+
955
+ **Breaking for `@robota-sdk/agent-interface-execution` and `@robota-sdk/agent-executor`**: code that
956
+ read `exitCode`/`signalCode`/`usage` off an unnarrowed `IBackgroundTaskResult`, or that implemented
957
+ `IBackgroundTaskHandle`/a custom runner without specifying its kind parameter, needs to narrow on
958
+ `result.kind` (or specify the kind parameter) before those fields are visible again.
959
+
960
+ - b462ee7: Discriminate `IBackgroundTaskState` by kind, the same way `TBackgroundTaskRequest` and (as of the
961
+ prior change) `TBackgroundTaskResult` already are. Fields only one runner ever produces now live
962
+ only on that kind's member instead of being optional-and-cross-kind-reachable on every kind:
963
+
964
+ - `agent`-only: `agentType`, `isolation`, `resumeSessionId`, `promptPreview`, and the
965
+ worktree-isolation fields (`worktreePath`, `branchName`, `worktreeStatus`, `worktreeNextAction`,
966
+ `worktreeBaseRevision`, `parentWorktreeStatus`).
967
+ - `scheduled`-only: `schedule`, `nextFireAt`.
968
+ - Every kind except `agent`: `commandPreview` (a process command, an MCP tool-invocation summary, or
969
+ a schedule's shell command / wake instruction).
970
+ - `state.result` is now `IBackgroundTaskResult<K>` — correlated with `state.kind`, not the free
971
+ full-result union.
972
+
973
+ `pid`, `logPath`, and `transcriptPath` stay on the shared base rather than becoming agent- or
974
+ process-exclusive: the runner handle SPI already reports them for whichever runner's process
975
+ happens to produce them, and a subagent run via the worktree/child-process runner carries a `pid`
976
+ exactly as a `process`-kind task does. `timeoutReason` also stays base — session restore sets
977
+ `'stale_worker'` on any non-terminal, non-rearmable task regardless of kind, not only agent ones.
978
+
979
+ `IBackgroundTaskState<K>` narrows to the kind-specific member; called with no type argument it is
980
+ still the full union. The session-record decoder (`agent-session`) now rejects a persisted task
981
+ state carrying a field outside its own kind as corrupt, reported at that field's own path, the same
982
+ way it already rejects a `state.result` whose kind disagrees with `state.kind`.
983
+
984
+ **Breaking for `@robota-sdk/agent-interface-execution` and `@robota-sdk/agent-executor`**: code that
985
+ read a kind-specific field (e.g. `state.agentType`, `state.schedule`, `state.commandPreview`) off an
986
+ unnarrowed `IBackgroundTaskState` needs to narrow on `state.kind` first, since the fallback default
987
+ no longer carries every field on every kind. `agent-session`, `agent-framework`, and `agent-command`
988
+ land the corresponding narrowing at every read site the type change touched; no runtime behavior
989
+ changes there beyond the state decoder's new corruption checks.
990
+
991
+ - 30e5e50: Reject background runner results whose task ID or kind differs from the task being completed, and report the same mismatch as corruption when decoding a persisted session record.
992
+ - 4f3c075: Assemble complete, verified package generations before switching build output; preserve the previous generation on build failure and pack only verified regular-file images. Include copied CLI web assets in affected-build ordering and artifact transfer. Preserve the CLI version in managed build paths. Public runtime contracts remain compatible (patch).
993
+ - 6085cad: CORE-031: a compaction with nothing to summarise no longer replaces the conversation
994
+
995
+ `Session.compact()` guarded on the FULL conversation and then compacted a DIFFERENT array — the same
996
+ history with system messages filtered out. So a conversation consisting only of system messages
997
+ passed the guard, reached the orchestrator empty, took its `return ''` shortcut, and came back as a
998
+ "summary" the caller wrote over the conversation: cleared, and replaced with an empty
999
+ `[Context Summary]` block.
1000
+
1001
+ The guard now tests the messages that will actually be compacted. Nothing to summarise is a no-op,
1002
+ not a failure — the conversation is left exactly as found, no hook fires, no `context_compact` event
1003
+ is written, and the provider is not called.
1004
+
1005
+ `CompactionOrchestrator.compact()` correspondingly throws `CompactionError` on an empty `history`
1006
+ rather than returning `''`, which contradicted the contract two lines above it in its own docblock
1007
+ ("always a non-empty string") and was the value that made the overwrite possible. Whether there is
1008
+ anything worth compacting is the caller's judgement, made before it commits to replacing anything.
1009
+
1010
+ Reachable from the public SDK surface: `Session.injectMessage` is what `--resume` and `--fork` drive
1011
+ on every restore.
1012
+
1013
+ - 93d061d: CORE-043: structured output now knows which transport can carry the schema before the first call
1014
+
1015
+ `run(input, { output })` asked every provider for `responseFormat: { type: 'json_schema' }`. A
1016
+ provider whose surface cannot express that accepted the option and dropped it — and the schema was
1017
+ stated in words only by the RETRY feedback turn, which runs on attempt two. So against such a
1018
+ provider, attempt one carried nothing describing the required shape and could only succeed by luck:
1019
+ the advertised three attempts were really two, and the first was spent discovering something the
1020
+ capability table already knew.
1021
+
1022
+ A `(provider, model)` pair now resolves to a mechanism (`response_schema` / `json_object` / `none`)
1023
+ and a provenance (`catalog` / `vendor-default` / `undeclared` / `unverified-endpoint`), and the
1024
+ request is shaped to match at the one seam that holds both the resolved provider and the outgoing
1025
+ messages. When the wire cannot carry the shape, the schema is stated in the prompt on the FIRST
1026
+ attempt. Each structured request emits a `structured_output_transport` event reporting what the
1027
+ request actually did.
1028
+
1029
+ - `IAIProvider.endpointIsVendorDefault?()` — a provider configured with a custom `baseURL` reports
1030
+ it, so the runtime stops claiming enforcement a gateway may not provide. Separate from
1031
+ `capabilityTable?()` on purpose: `@robota-sdk/agent-provider-openai` declares no table (nobody has
1032
+ verified one) and must still be able to answer.
1033
+ - DeepSeek's capability table declared `json_schema`; DeepSeek guarantees the response PARSES but
1034
+ takes no schema parameter. Corrected to `json_object`.
1035
+ - A provider that declares nothing is still sent the request unchanged — silence is not a denial.
1036
+
1037
+ - bed26ea: Fix: an in-flight autonomous `goal` is no longer lost on session resume. `fromSessionRecord` was a hand-enumerated field whitelist that omitted `goal` (while the write path persisted it), so the goal silently vanished on load. The read path is now a structural mirror of the write path (`{ ...session }`), so every persisted field — including `goal` — round-trips, and a future field cannot be dropped by omission (ARL-08 / DATA-006). `ISessionRecord` gains an opaque `goal?: unknown` for contract honesty.
1038
+ - 07b627f: A local peer can now be answered, and what its turn may do depends on where it runs.
1039
+
1040
+ - `agent-core`: the permission evaluator takes a peer turn's authority as one more input
1041
+ (`IPermissionEvaluationContext.peerTurn`), decided after the deny list and ceiling and before
1042
+ bypass and allow rules. A peer on another host uses no tool. A peer on the same host may use an
1043
+ inspect-class tool that declares `workspacePaths`, only when every named location resolves inside
1044
+ the workspace and is not a credential (`isSecretPath`); write and execute tools are refused unless
1045
+ enabled, and then every use asks. A tool declaring `repliesToPeer` exists only in a peer turn and
1046
+ asks once the turn used another tool. New: `isToolAvailableInPeerTurn`, `TPeerReach`,
1047
+ `IPeerTurnAuthority`. `IRunOptions.withholdHostedTools` leaves a provider's hosted tools out of a
1048
+ run's requests (`nativeWebTools` with `false` withholds a hosted tool for one call).
1049
+ - `agent-tools`: `Read` and `Glob` declare the arguments that say where they look. `Grep` does not:
1050
+ it reads files it was never named, so a peer turn does not get it.
1051
+ - `agent-session`: `ISessionRunOptions.peerReach` makes a run a peer turn for the permission policy;
1052
+ every ask in it needs a fresh approval, and its requests carry no provider-hosted tool. `ISessionOptions.allowPeerChanges` enables write and execute
1053
+ tools for same-host peer turns.
1054
+ - `agent-interface-session`: `ISubmitOptions.peer` (`IPeerTurnContext`) carries a peer turn's reach,
1055
+ the message it answers and the session a reply goes to.
1056
+ - `agent-interface-session-mobility`: `IPeerMessage.inReplyTo` threads a conversation;
1057
+ `peerReachOf(admission)` maps admission to a reach.
1058
+ - `agent-framework`: a peer turn is offered what its origin allows, and a new `peer_reply` tool
1059
+ answers the peer that sent the message, threaded to it. The setting `peers.allowChanges` enables
1060
+ write and execute tools for same-host peer turns.
1061
+ - `agent-ui-terminal`: a permission prompt in a peer turn names the requesting peer.
1062
+ - `agent-cli`: incoming peer turns carry their reach and reply route; a conversation is limited in
1063
+ depth and in how often this session answers it, and a reply over a limit is not sent and the
1064
+ operator is told.
1065
+ - `agent-provider-anthropic`, `agent-provider-openai-compatible` (Qwen): a request whose
1066
+ `nativeWebTools` sets a hosted tool to `false` is sent without it.
1067
+
1068
+ - d0de5b2: A peer session's message now reaches the model as a peer's, and a peer turn runs on the external
1069
+ baseline.
1070
+
1071
+ - `agent-core` marks every user message whose driver id starts with `peer:` as
1072
+ `<peer_message from="…">…</peer_message>` in the outgoing request — both the round and the forced
1073
+ summary — while the stored history keeps the text as sent. Wrapper-shaped text in user and tool
1074
+ messages is escaped, and an id that is not a plain identifier is printed as `peer:unverified`.
1075
+ New exports: `peerDriverOf`, `printablePeerDriver`.
1076
+ - `agent-session`'s conversation transcript (compaction, advisor) labels a peer message with the same
1077
+ printable id, so no rendering echoes a sender-chosen id that is not a plain identifier.
1078
+ - `agent-framework` runs a `peer` turn like an `external` one — no tools (`toolChoice: 'none'`), no
1079
+ `@path` expansion, no context references — and adds a per-turn system statement that the message
1080
+ came from another session and carries no authority. A `peer` turn must carry a `peer:` driver id.
1081
+
1082
+ - ebd40a0: Harden on-disk log permissions against CWE-377 (SEC-003, CodeQL `js/insecure-temporary-file`).
1083
+
1084
+ Session logs, externalized session payloads, and OpenAI request/response payload logs all carry
1085
+ conversation and prompt content, but were created with the process umask (typically `0644`) inside a
1086
+ caller-supplied directory that may be shared or world-writable. They are now created owner-only
1087
+ (`0600`), and the directories that hold them are created `0700`.
1088
+
1089
+ This is a permissions change only — file locations, names, formats, and APIs are unchanged. Anything
1090
+ that read these logs as a _different_ OS user will no longer be able to; the owning user is
1091
+ unaffected.
1092
+
1093
+ - Updated dependencies [9c19c50]
1094
+ - Updated dependencies [7b6234c]
1095
+ - Updated dependencies [5307f8a]
1096
+ - Updated dependencies [b462ee7]
1097
+ - Updated dependencies [37b4bd7]
1098
+ - Updated dependencies [4eea54b]
1099
+ - Updated dependencies [1698be4]
1100
+ - Updated dependencies [d4189b9]
1101
+ - Updated dependencies [9edae52]
1102
+ - Updated dependencies [4078a72]
1103
+ - Updated dependencies [4c73a0b]
1104
+ - Updated dependencies [196a900]
1105
+ - Updated dependencies [f336838]
1106
+ - Updated dependencies [34e50f0]
1107
+ - Updated dependencies [722e88a]
1108
+ - Updated dependencies [d23c848]
1109
+ - Updated dependencies [fec722f]
1110
+ - Updated dependencies [2d3b2c0]
1111
+ - Updated dependencies [4772067]
1112
+ - Updated dependencies [9fbab1b]
1113
+ - Updated dependencies [a009f5b]
1114
+ - Updated dependencies [4f3c075]
1115
+ - Updated dependencies [475e085]
1116
+ - Updated dependencies [e477440]
1117
+ - Updated dependencies [9dcb5da]
1118
+ - Updated dependencies [a95ca85]
1119
+ - Updated dependencies [b6d14ce]
1120
+ - Updated dependencies [0382a51]
1121
+ - Updated dependencies [93d061d]
1122
+ - Updated dependencies [39554a1]
1123
+ - Updated dependencies [d28430a]
1124
+ - Updated dependencies [fcb0da3]
1125
+ - Updated dependencies [07b627f]
1126
+ - Updated dependencies [d0de5b2]
1127
+ - Updated dependencies [d6b9404]
1128
+ - Updated dependencies [9814afc]
1129
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.80
1130
+ - @robota-sdk/agent-core@3.0.0-beta.80
1131
+ - @robota-sdk/agent-interface-session@3.0.0-beta.80
1132
+ - @robota-sdk/agent-file-authority@3.0.0-beta.80
1133
+
1134
+ ## 3.0.0-beta.79
1135
+
1136
+ ### Patch Changes
1137
+
1138
+ - @robota-sdk/agent-core@3.0.0-beta.79
1139
+ - @robota-sdk/agent-interface-transport@3.0.0-beta.79
1140
+
1141
+ ## 3.0.0-beta.78
1142
+
1143
+ ### Patch Changes
1144
+
1145
+ - Updated dependencies [6f308d1]
1146
+ - @robota-sdk/agent-core@3.0.0-beta.78
1147
+ - @robota-sdk/agent-interface-transport@3.0.0-beta.78
1148
+
1149
+ ## 3.0.0-beta.77
1150
+
1151
+ ### Patch Changes
1152
+
1153
+ - Updated dependencies
1154
+ - @robota-sdk/agent-core@3.0.0-beta.77
1155
+ - @robota-sdk/agent-interface-transport@3.0.0-beta.77
1156
+
1157
+ ## 3.0.0-beta.76
1158
+
1159
+ ### Patch Changes
1160
+
1161
+ - DQ-AUDIT-002 — consolidate duplicated domain data onto single owners: one model-pricing SSOT in agent-core (`MODEL_PRICES`/`lookupModelPrice`/`calculateModelCost`/`estimateBlendedCostPer1000`) consumed by agent-command and agent-plugin (drops two embedded/stale price tables); the `len/4` token estimator replaced by core `CONTEXT_ESTIMATE_CHARS_PER_TOKEN`; TUI `TContextState` derived from core `IContextWindowState`; dead pass-through re-exports removed from agent-session.
1162
+ - DQ-AUDIT-006 — error/observability hygiene: replace raw `throw new Error()` on core-service and provider hot paths with typed `AgentRuntimeError` subclasses (`ConfigurationError`/`ValidationError`) so error-handling can branch on category/recoverable; surface fire-and-forget hook failures via `logger.warn` instead of silent `.catch(() => {})`; wire the error-handling plugin's `totalRetries`/`successfulRecoveries` stats to real counters.
1163
+ - 576af62: Fix `ConfigurationError: Agent must be fully initialized before changing model configuration` when running `/preset` (or any live model re-apply) on a fresh interactive session before the first message. The Robota agent initialized lazily on the first `run()`, but `setModel` requires full initialization. `Session.applyModelOptions` now awaits the new idempotent `Robota.ensureReady()` before `setModel`, and the preset live-switch path (`applyPresetToSession` → `executePresetCommand`) is async end-to-end. Adds a real cold-session regression test (no mocked Robota).
1164
+ - Updated dependencies
1165
+ - Updated dependencies
1166
+ - Updated dependencies
1167
+ - Updated dependencies [576af62]
1168
+ - @robota-sdk/agent-core@3.0.0-beta.76
1169
+
1170
+ ## 3.0.0-beta.75
1171
+
1172
+ ### Patch Changes
1173
+
1174
+ - Agent preset system + live preset switching + context/history correctness fixes.
1175
+
1176
+ - **Preset system (PRESET-001~017):** new `@robota-sdk/agent-preset` package layering framework
1177
+ assembly options into named, selectable profiles (`default`, `autonomous-builder`, `careful-reviewer`,
1178
+ `neutral-executor`) plus user-authored external presets loaded from `$PRODUCT_USER_STATE_DIR/presets/*.json`.
1179
+ - **Live preset switching:** `/preset` command (list + active marker + switch) and a TUI active-preset
1180
+ display. Switching live re-applies permission posture, model/effort, persona, command-module
1181
+ selection, parallel-subagents gating, and a self-verification system-prompt section via the single
1182
+ `applyPresetToSession` engine.
1183
+ - **CTX-001:** the TUI Context display + session auto-compact now use the accurate provider-based token
1184
+ estimate (system prompt + tool schemas included) instead of a crude history-only char heuristic.
1185
+ - **HIST-001:** conversation history is now append-only — removed the silent 100-message count cap that
1186
+ could drop early context; context size is managed solely by size-based compaction.
1187
+
1188
+ - Updated dependencies
1189
+ - @robota-sdk/agent-core@3.0.0-beta.75
1190
+
1191
+ ## 3.0.0-beta.74
1192
+
1193
+ ### Patch Changes
1194
+
1195
+ - @robota-sdk/agent-core@3.0.0-beta.74
1196
+
1197
+ ## 3.0.0-beta.73
1198
+
1199
+ ### Patch Changes
1200
+
1201
+ - @robota-sdk/agent-core@3.0.0-beta.73
1202
+
1203
+ ## 3.0.0-beta.72
1204
+
1205
+ ### Patch Changes
1206
+
1207
+ - @robota-sdk/agent-core@3.0.0-beta.72
1208
+
1209
+ ## 3.0.0-beta.71
1210
+
1211
+ ### Patch Changes
1212
+
1213
+ - fix(context): unify token estimation to single SSOT — status bar and /context list now use the same serialized JSON estimate
1214
+ - Updated dependencies
1215
+ - @robota-sdk/agent-core@3.0.0-beta.71
1216
+
1217
+ ## 3.0.0-beta.70
1218
+
1219
+ ### Patch Changes
1220
+
1221
+ - @robota-sdk/agent-core@3.0.0-beta.70
1222
+
1223
+ ## 3.0.0-beta.69
1224
+
1225
+ ### Patch Changes
1226
+
1227
+ - @robota-sdk/agent-core@3.0.0-beta.69
1228
+
1229
+ ## 3.0.0-beta.68
1230
+
1231
+ ### Patch Changes
1232
+
1233
+ - @robota-sdk/agent-core@3.0.0-beta.68
1234
+
1235
+ ## 3.0.0-beta.67
1236
+
1237
+ ### Patch Changes
1238
+
1239
+ - @robota-sdk/agent-core@3.0.0-beta.67
1240
+
1241
+ ## 3.0.0-beta.66
1242
+
1243
+ ### Patch Changes
1244
+
1245
+ - @robota-sdk/agent-core@3.0.0-beta.66
1246
+
1247
+ ## 3.0.0-beta.65
1248
+
1249
+ ### Patch Changes
1250
+
1251
+ - @robota-sdk/agent-core@3.0.0-beta.65
1252
+
1253
+ ## 3.0.0-beta.64
1254
+
1255
+ ### Patch Changes
1256
+
1257
+ - @robota-sdk/agent-core@3.0.0-beta.64
1258
+
1259
+ ## 3.0.0-beta.63
1260
+
1261
+ ### Patch Changes
1262
+
1263
+ - @robota-sdk/agent-core@3.0.0-beta.63
1264
+
1265
+ ## 3.0.0-beta.62
1266
+
1267
+ ### Patch Changes
1268
+
1269
+ - Updated dependencies
1270
+ - @robota-sdk/agent-core@3.0.0-beta.62
1271
+
1272
+ ## 3.0.0-beta.61
1273
+
1274
+ ### Minor Changes
1275
+
1276
+ - 18fcc5b: Add provider-neutral sandbox snapshot hydration for interactive sessions. Snapshot-capable sandbox clients now persist `sandboxSnapshotId` on shutdown and restore it before saved message replay on non-fork resume, while the E2B structural adapter supports both `createSnapshot()`-style checkpoints and pause/resume sandbox references.
1277
+
1278
+ ### Patch Changes
1279
+
1280
+ - 1c0d44c: Align context usage estimation across session display, auto-compaction, and core hard-capacity guards so mid-window sessions do not block prematurely.
1281
+ - 36eb7a9: Add provider-owned native replay payload hooks, replay validation coverage, and a session log validation command.
1282
+ - d97bdf2: Add provider-owned model catalog metadata, route `/model` suggestions through the active provider, and make `cli:dev` resolve the CLI workspace dependency closure through source export conditions.
1283
+ - Updated dependencies [1c0d44c]
1284
+ - Updated dependencies [36eb7a9]
1285
+ - Updated dependencies [d97bdf2]
1286
+ - @robota-sdk/agent-core@3.0.0-beta.61
1287
+
1288
+ ## 3.0.0-beta.60
1289
+
1290
+ ### Minor Changes
1291
+
1292
+ - 7439391: Add provider-neutral native web search/fetch capability contracts, explicit unsupported handling for OpenAI-compatible/LM Studio profiles, and local WebFetch/WebSearch permission/documentation alignment.
1293
+
1294
+ ### Patch Changes
1295
+
1296
+ - Updated dependencies [7439391]
1297
+ - @robota-sdk/agent-core@3.0.0-beta.60
1298
+
1299
+ ## 3.0.0-beta.59
1300
+
1301
+ ### Patch Changes
1302
+
1303
+ - @robota-sdk/agent-core@3.0.0-beta.59
1304
+
1305
+ ## 3.0.0-beta.58
1306
+
1307
+ ### Patch Changes
1308
+
1309
+ - Refresh package docs and Robota.io content for the beta 57 feature set.
1310
+ - Updated dependencies
1311
+ - @robota-sdk/agent-core@3.0.0-beta.58
1312
+
1313
+ ## 3.0.0-beta.57
1314
+
1315
+ ### Minor Changes
1316
+
1317
+ - b80e51e: Add SDK-owned automatic project memory capture, approval review, bounded retrieval, and session-log provenance.
1318
+
1319
+ ### Patch Changes
1320
+
1321
+ - 16c3b6f: Persist and render provider-neutral per-turn usage summaries with pre-send context updates in CLI sessions.
1322
+ - 26a1718: Preserve and render Edit tool diff metadata in persisted CLI tool summaries.
1323
+ - Updated dependencies [16c3b6f]
1324
+ - Updated dependencies [f61e2cb]
1325
+ - @robota-sdk/agent-core@3.0.0-beta.57
1326
+
1327
+ ## 3.0.0-beta.56
1328
+
1329
+ ### Patch Changes
1330
+
1331
+ - Updated dependencies
1332
+ - @robota-sdk/agent-core@3.0.0-beta.56
1333
+
1334
+ ## 3.0.0-beta.55
1335
+
1336
+ ### Patch Changes
1337
+
1338
+ - 38a72bf: fix: resolve ESLint tsconfig parsing errors and improve pnpm CI reliability
1339
+ - Add tsconfig.eslint.json to all packages for per-package ESLint runs
1340
+ - Migrate typecheck from pnpm -r exec tsc to per-package typecheck scripts
1341
+ - Add --if-present to all recursive pnpm run scripts
1342
+ - Fix React type imports, dynamic imports in tests, Express.Multer types
1343
+
1344
+ - Updated dependencies [38a72bf]
1345
+ - @robota-sdk/agent-core@3.0.0-beta.55
1346
+
1347
+ ## 3.0.0-beta.54
1348
+
1349
+ ### Patch Changes
1350
+
1351
+ - fix: resolve all typecheck errors across packages
1352
+ - Updated dependencies
1353
+ - @robota-sdk/agent-core@3.0.0-beta.54
1354
+
1355
+ ## 3.0.0-beta.53
1356
+
1357
+ ### Patch Changes
1358
+
1359
+ - refactor: monolith decomposition — all agent-\* files under 300 lines
1360
+ - fix: PR #69 code review — session resume tool messages, type SSOT, fork isolation, settings crash, Notification removal, chat validation
1361
+ - Updated dependencies
1362
+ - Updated dependencies
1363
+ - @robota-sdk/agent-core@3.0.0-beta.53
1364
+
1365
+ ## 3.0.0-beta.52
1366
+
1367
+ ### Patch Changes
1368
+
1369
+ - @robota-sdk/agent-core@3.0.0-beta.52
1370
+
1371
+ ## 3.0.0-beta.51
1372
+
1373
+ ### Patch Changes
1374
+
1375
+ - @robota-sdk/agent-core@3.0.0-beta.51
1376
+
1377
+ ## 3.0.0-beta.50
1378
+
1379
+ ### Patch Changes
1380
+
1381
+ - @robota-sdk/agent-core@3.0.0-beta.50
1382
+
1383
+ ## 3.0.0-beta.49
1384
+
1385
+ ### Patch Changes
1386
+
1387
+ - @robota-sdk/agent-core@3.0.0-beta.49
1388
+
1389
+ ## 3.0.0-beta.48
1390
+
1391
+ ### Patch Changes
1392
+
1393
+ - @robota-sdk/agent-core@3.0.0-beta.48
1394
+
1395
+ ## 3.0.0-beta.47
1396
+
1397
+ ### Patch Changes
1398
+
1399
+ - @robota-sdk/agent-core@3.0.0-beta.47
1400
+
1401
+ ## 3.0.0-beta.46
1402
+
1403
+ ### Minor Changes
1404
+
1405
+ - feat: session continue/resume — persist, restore, and switch sessions
1406
+ - ISessionRecord.history field (required) for UI timeline restoration
1407
+ - Session.injectMessage() for AI context restoration on resume
1408
+ - InteractiveSession: sessionStore, resumeSessionId, forkSession, getName/setName
1409
+ - CLI: --continue, --resume, --fork-session, --name flags
1410
+ - TUI: /resume (session picker), /rename (session naming)
1411
+ - ListPicker generic component with viewport scrolling
1412
+ - Session name display: input border title, terminal title, StatusBar
1413
+ - Session picker: cwd filtering, date+time, response preview
1414
+ - React key remount for instant session switching
1415
+
1416
+ ### Patch Changes
1417
+
1418
+ - @robota-sdk/agent-core@3.0.0-beta.46
1419
+
1420
+ ## 3.0.0-beta.45
1421
+
1422
+ ### Patch Changes
1423
+
1424
+ - @robota-sdk/agent-core@3.0.0-beta.45
1425
+
1426
+ ## 3.0.0-beta.44
1427
+
1428
+ ### Patch Changes
1429
+
1430
+ - feat: IHistoryEntry universal history architecture + test quality cleanup
1431
+ - IHistoryEntry as universal history type across all 4 packages (core → sessions → sdk → cli)
1432
+ - Tool summary stored as event entry in history (category: 'event', type: 'tool-summary')
1433
+ - TuiStateManager pure TypeScript class for CLI rendering state
1434
+ - MessageList renders IHistoryEntry[] with Tool:/System:/You:/Robota: labels
1435
+ - Display order fixed: Tool → Robota (both streaming and abort)
1436
+ - Remove 25 tautological, duplicate, and hardcoded tests
1437
+
1438
+ - Updated dependencies
1439
+ - @robota-sdk/agent-core@3.0.0-beta.44
1440
+
1441
+ ## 2.0.9
1442
+
1443
+ ### Patch Changes
1444
+
1445
+ - Add environment-specific builds and conditional exports for optimal browser compatibility
1446
+
1447
+ This update introduces major build optimizations for better browser performance:
1448
+
1449
+ ## 🚀 Environment-Specific Builds
1450
+ - **Node.js builds**: `dist/node/` with full ESM and CJS support
1451
+ - **Browser builds**: `dist/browser/` with optimized ESM bundles
1452
+ - **Automatic selection**: Bundlers automatically choose the right build
1453
+
1454
+ ## 📦 Bundle Size Optimizations
1455
+ - **team package**: 36% smaller browser bundles (37.52KB → 24.12KB)
1456
+ - **sessions package**: 48% smaller browser bundles (10.64KB → 5.55KB)
1457
+ - **Tree-shaking**: Eliminates Node.js-specific code from browser builds
1458
+ - **Production optimizations**: Removes console logs and debug code in browser builds
1459
+
1460
+ ## 🔧 Conditional Exports
1461
+
1462
+ All packages now support conditional exports for seamless environment detection:
1463
+
1464
+ ```json
1465
+ {
1466
+ "exports": {
1467
+ "node": "./dist/node/index.js",
1468
+ "browser": "./dist/browser/index.js",
1469
+ "default": "./dist/node/index.js"
1470
+ }
1471
+ }
1472
+ ```
1473
+
1474
+ ## 🌐 Enhanced Browser Support
1475
+ - **Zero breaking changes**: Existing code continues to work unchanged
1476
+ - **Better performance**: Optimized bundles for faster loading
1477
+ - **Smaller footprint**: Reduced JavaScript bundle sizes for web applications
1478
+ - **Universal API**: Same API works across all environments
1479
+
1480
+ This update completes the browser compatibility optimization phase, making Robota SDK production-ready for web applications with optimal performance characteristics.
1481
+
1482
+ - Updated dependencies
1483
+ - @robota-sdk/agent-core@2.0.9
1484
+
1485
+ ## 2.0.8
1486
+
1487
+ ### Patch Changes
1488
+
1489
+ - # Model Configuration Refactoring
1490
+
1491
+ ## 🚀 **Breaking Changes**
1492
+
1493
+ ### **Provider Interface Simplification**
1494
+ - **OpenAI Provider**: Removed `model`, `temperature`, `maxTokens`, `topP` from provider options
1495
+ - **Anthropic Provider**: Removed `model`, `temperature`, `maxTokens` from provider options
1496
+ - **Google Provider**: Removed `model`, `temperature`, `maxTokens` from provider options
1497
+ - **All Providers**: `client` is now optional, automatically created from `apiKey`
1498
+
1499
+ ### **Centralized Model Configuration**
1500
+ - Model configuration is now exclusively handled through `defaultModel` in Robota constructor
1501
+ - Providers are simplified to handle only connection-related settings
1502
+ - Runtime model switching via `setModel()` method is now the recommended approach
1503
+
1504
+ ## ✨ **Improvements**
1505
+
1506
+ ### **Simplified Provider Creation**
1507
+
1508
+ ```typescript
1509
+ // Before
1510
+ const provider = new OpenAIProvider({
1511
+ client: openaiClient,
1512
+ model: 'gpt-3.5-turbo',
1513
+ });
1514
+
1515
+ // After
1516
+ const provider = new OpenAIProvider({
1517
+ apiKey: process.env.OPENAI_API_KEY,
1518
+ });
1519
+ ```
1520
+
1521
+ ### **Enhanced Validation**
1522
+ - Added strict validation for required model configuration
1523
+ - Removed default model fallbacks to prevent ambiguous behavior
1524
+ - Clear error messages when model is not specified
1525
+
1526
+ ### **Documentation Updates**
1527
+ - Updated all README files with new usage patterns
1528
+ - Regenerated API documentation
1529
+ - Updated all example files (11 examples)
1530
+
1531
+ ## 🔧 **Migration Guide**
1532
+ 1. **Remove model settings from Provider constructors**
1533
+ 2. **Use `apiKey` instead of `client` injection (recommended)**
1534
+ 3. **Ensure `defaultModel` is properly configured in Robota constructor**
1535
+ 4. **Update any hardcoded model references to use runtime switching**
1536
+
1537
+ ## 🎯 **Benefits**
1538
+ - **Eliminates configuration confusion** - Single source of truth for models
1539
+ - **Simplifies provider setup** - Just provide API credentials
1540
+ - **Enables better runtime control** - Centralized model management
1541
+ - **Improves consistency** - All providers follow same pattern
1542
+
1543
+ - Updated dependencies
1544
+ - @robota-sdk/agent-core@2.0.8
1545
+
1546
+ ## 2.0.7
1547
+
1548
+ ### Patch Changes
1549
+
1550
+ - Browser compatibility improvements
1551
+ - feat: Implement SimpleLogger system to replace direct console usage for better browser compatibility
1552
+ - feat: Centralize SimpleLogger in @robota-sdk/agent-core package and export for other packages
1553
+ - feat: Add support for silent and stderr-only logging modes via SilentLogger and StderrLogger
1554
+ - refactor: Update all packages (@robota-sdk/agent-provider-openai, @robota-sdk/agent-provider-anthropic, etc.) to use centralized SimpleLogger
1555
+ - chore: Add ESLint rules to prevent direct console usage while allowing legitimate cases
1556
+ - fix: Remove unused AIProvider import from examples to clean up warnings
1557
+
1558
+ These changes ensure the SDK works properly in browser environments by removing Node.js-specific console behavior while maintaining full backward compatibility.
1559
+
1560
+ - Updated dependencies
1561
+ - @robota-sdk/agent-core@2.0.7
1562
+
1563
+ ## 2.0.6
1564
+
1565
+ ### Patch Changes
1566
+
1567
+ - Add browser compatibility by removing Node.js dependencies
1568
+ - Replace NodeJS.Timeout with cross-platform TimerId type
1569
+ - Remove process.env dependency from logger configuration
1570
+ - Replace Node.js crypto module with jsSHA library for webhook signatures
1571
+ - Update OpenAI stream handlers to work in browser environments
1572
+ - Maintain 100% backward compatibility with existing Node.js applications
1573
+
1574
+ This update enables Robota SDK to run seamlessly in both Node.js and browser environments without breaking changes.
1575
+
1576
+ - Updated dependencies
1577
+ - @robota-sdk/agent-core@2.0.6
1578
+
1579
+ ## 2.0.5
1580
+
1581
+ ### Patch Changes
1582
+
1583
+ - ## 🎯 TypeScript Declaration File Optimization
1584
+ - Updated dependencies
1585
+ - @robota-sdk/agent-core@2.0.5
1586
+
1587
+ ## 2.0.4
1588
+
1589
+ ### Patch Changes
1590
+
1591
+ - 9f17ac6: Restore README.md files and prevent deletion during build process
1592
+ - Updated dependencies [9f17ac6]
1593
+ - @robota-sdk/agent-core@2.0.4
1594
+
1595
+ ## 2.1.0
1596
+
1597
+ ### Minor Changes
1598
+
1599
+ - **Production-Ready Architecture**: Complete refactoring from experimental to production-ready state
1600
+ - **Purpose Redefinition**: Focused on managing multiple independent AI agents in isolated workspaces
1601
+ - **Removed Message Editing**: Eliminated message editing/deletion functionality to focus on core purpose
1602
+ - **Simplified Architecture**: ChatInstance now wraps Robota agents with clean delegation
1603
+ - **SessionManager Implementation**: Complete multi-session management with workspace isolation
1604
+ - **Template Integration**: Integrated with agents package AgentFactory and AgentTemplates
1605
+ - **File Cleanup**: Removed duplicate implementations that existed in agents package
1606
+ - **Type System Simplification**: Streamlined interfaces and removed complex EnhancedConversationHistory
1607
+ - **Comprehensive Testing**: Added full test coverage and working examples
1608
+ - **Documentation Overhaul**: Complete README rewrite with architecture diagrams and API reference
1609
+
1610
+ ### Patch Changes
1611
+
1612
+ - Updated dependencies
1613
+ - @robota-sdk/agent-core@2.1.0
1614
+
1615
+ ## 2.0.3
1616
+
1617
+ ### Patch Changes
1618
+
1619
+ - @robota-sdk/agent-core@2.0.3
1620
+
1621
+ ## 2.0.2
1622
+
1623
+ ### Patch Changes
1624
+
1625
+ - Fix npm package documentation by ensuring README.md files are included
1626
+ - Updated dependencies
1627
+ - @robota-sdk/agent-core@2.0.2
1628
+
1629
+ ## 2.0.1
1630
+
1631
+ ### Patch Changes
1632
+
1633
+ - Remove unused dependencies from agents and sessions packages
1634
+ - Updated dependencies
1635
+ - @robota-sdk/agent-core@2.0.1
1636
+
1637
+ ## 2.0.0
1638
+
1639
+ ### Major Changes
1640
+
1641
+ - a3a464c: # Robota SDK v2.0.0-rc.1 - Unified Architecture
1642
+
1643
+ ## 🚀 Major Changes
1644
+
1645
+ ### New Unified Core
1646
+ - **@robota-sdk/agent-core**: New unified core package consolidating all functionality
1647
+ - **Zero `any` types**: Complete TypeScript type safety across all packages
1648
+ - **Provider-agnostic design**: Seamless switching between OpenAI, Anthropic, and Google
1649
+
1650
+ ### Key Features
1651
+ - **Multi-Provider Support**: Dynamic provider switching with type safety
1652
+ - **Advanced Function Calling**: Type-safe tool system with Zod validation
1653
+ - **Real-time Streaming**: Improved streaming with proper error handling
1654
+ - **Task Delegation**: Improved delegated workflow support
1655
+ - **Plugin Architecture**: Comprehensive plugin system with facade pattern
1656
+
1657
+ ### Breaking Changes
1658
+ - `@robota-sdk/core` functionality moved to `@robota-sdk/agent-core`
1659
+ - Redesigned provider interfaces with generic type parameters
1660
+ - Updated agent configuration format
1661
+
1662
+ Complete architecture overhaul focused on type safety and developer experience.
1663
+
1664
+ ### Patch Changes
1665
+
1666
+ - Updated dependencies [a3a464c]
1667
+ - @robota-sdk/agent-core@2.0.0
1668
+
1669
+ ## 1.0.5
1670
+
1671
+ ### Patch Changes
1672
+
1673
+ - Simplify team API, update docs, fix lint issues, add task coordinator template
1674
+ - Updated dependencies
1675
+ - @robota-sdk/agent-tools@1.0.5
1676
+ - @robota-sdk/core@1.0.5
1677
+
1678
+ ## 1.0.4
1679
+
1680
+ ### Patch Changes
1681
+
1682
+ - Add task delegation tooling with assignTask MCP tools
1683
+ - Updated dependencies
1684
+ - @robota-sdk/core@1.0.4
1685
+ - @robota-sdk/agent-tools@1.0.4
1686
+
1687
+ ## 1.0.3
1688
+
1689
+ ### Patch Changes
1690
+
1691
+ - Complete examples restructure and enhanced provider architecture
1692
+ - Updated dependencies
1693
+ - @robota-sdk/agent-tools@1.0.3
1694
+ - @robota-sdk/core@1.0.3
1695
+
1696
+ ## 1.0.2
1697
+
1698
+ ### Patch Changes
1699
+
1700
+ - Refactor examples and improve resource management
1701
+ - Simplified examples from 18+ files to 4 core examples (basic conversation, tool calling, multi-providers, advanced features)
1702
+ - Added proper resource cleanup with `Robota.close()` method to prevent hanging processes
1703
+ - Implemented `ToolProviderManager.close()` for proper tool provider cleanup
1704
+ - Added BaseAIProvider abstract class with common functionality for all AI providers
1705
+ - Updated package.json scripts and README documentation for better user experience
1706
+ - Removed duplicate and redundant example files
1707
+ - Added .env.example file for easier setup
1708
+
1709
+ - Updated dependencies
1710
+ - @robota-sdk/core@1.0.2
1711
+ - @robota-sdk/agent-tools@1.0.2
1712
+
1713
+ ## 1.0.1
1714
+
1715
+ ### Patch Changes
1716
+
1717
+ - Fix facade pattern tests and conversation history message limits
1718
+ - Updated dependencies
1719
+ - @robota-sdk/agent-tools@1.0.1
1720
+ - @robota-sdk/core@1.0.1
1721
+
1722
+ ## 1.0.0
1723
+
1724
+ ### Patch Changes
1725
+
1726
+ - Updated dependencies
1727
+ - @robota-sdk/agent-tools@1.0.0
1728
+ - @robota-sdk/core@1.0.0
1729
+
1730
+ ## 0.3.7
1731
+
1732
+ ### Patch Changes
1733
+
1734
+ - Major code quality improvements and architectural refactoring:
1735
+ - **Facade Pattern Implementation**: Simplified Robota class interface with manager-based architecture (ai, system, functions, analytics, tools, limits, conversation)
1736
+ - **Deprecated Methods Removal**: Removed 20+ deprecated methods, replaced with clean option-based constructor
1737
+ - **File Modularization**: Split large files into focused modules (function.ts → 4 modules, conversation-history refactoring)
1738
+ - **State Management Enhancement**: Implemented state machine pattern for sessions with improved error handling
1739
+ - **Pure Function Optimization**: Reduced complexity with pure functions and better separation of concerns
1740
+ - **TypeScript Improvements**: Fixed all compilation errors and improved type safety
1741
+ - **Example Updates**: Updated examples to use new API patterns
1742
+
1743
+ Breaking changes are minimal as the core functionality remains the same, but the internal architecture is significantly cleaner and more maintainable.
1744
+
1745
+ - Updated dependencies
1746
+ - @robota-sdk/agent-tools@0.3.7
1747
+ - @robota-sdk/core@0.3.7
1748
+
1749
+ ## 0.3.6
1750
+
1751
+ ### Patch Changes
1752
+
1753
+ - Update publishing docs with proper deployment guidelines
1754
+ - Updated dependencies
1755
+ - @robota-sdk/agent-tools@0.3.6
1756
+ - @robota-sdk/core@0.3.6
1757
+
1758
+ ## 0.3.5
1759
+
1760
+ ### Patch Changes
1761
+
1762
+ - Fix workspace dependencies & update README docs for all packages
1763
+ - Updated dependencies
1764
+ - @robota-sdk/agent-tools@0.3.5
1765
+ - @robota-sdk/core@0.3.5
1766
+
1767
+ ## 0.3.4
1768
+
1769
+ ### Patch Changes
1770
+
1771
+ - f77f18e: Add sessions package for multi-session & chat management in workspaces
1772
+ - Updated dependencies [f77f18e]
1773
+ - @robota-sdk/agent-tools@0.3.4
1774
+ - @robota-sdk/core@0.3.4