From 08386dc31b1e9831ccf5a949b17b95c5b68a3699 Mon Sep 17 00:00:00 2001 From: Ali Mohammad Date: Tue, 20 Oct 2026 05:30:23 +0300 Subject: [PATCH] docs(changelog): wave 2 entries for recovery, busy /chat, option keys, .env deny, scaffold cap Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 12 ++++++++++++ docs/upgrading.md | 4 ++++ llms-full.txt | 4 ++++ 3 files changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fbe151ef..e2f7e433 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,15 @@ opt-out. ### Changed +- **Behavior change:** the built node-server and Docker image resume runs a crash left in progress when they start (`agent.recover()`), and check again every 30 seconds until shutdown. Runs paused on an approval or a question are left alone, and a run another replica holds is skipped. `LOUSHO_RECOVER_ON_START=0` turns it off. See [Crash recovery](docs/deployment.md#crash-recovery). +- **Behavior change:** `createAgent()` and `defineTool()` reject an option key they don't know with `LOUSHO_CONFIG_INVALID` and a suggestion (`requireApproval` → `needsApproval`, `maxOutputTokens` → `modelSettings.maxTokens`) instead of ignoring it. A mistyped `needsApproval` used to run the tool unapproved. Keys set to `undefined` are ignored. +- **Behavior change:** the workspace file tools deny `.env` and `.env.*` by default as well as `.git`. `.env.example`, `.env.sample` and `.env.template` stay readable. A `deny` list you pass still replaces the defaults. +- `POST /chat` answers `409` with `Retry-After: 2` and `code: LOUSHO_SESSION_BUSY` when another process or replica is running the session, instead of a `200` stream holding only the error. An `Idempotency-Key` resend that hits a running turn gets the same `409`. +- Scaffolded agents (`lousho init`, `create-lousho-agent`) set `modelSettings: { maxTokens: 4096 }`, so a first run on a low-credit OpenRouter key no longer fails with "requires more credits, or fewer max_tokens". The generated README explains the error. +- Error `docs` links point to `https://lousho.com/errors#` instead of the GitHub file on `main`. +- The Docker image creates `/app/data` owned by `node` and declares it a `VOLUME`, so a fresh named volume works with `LOUSHO_STORE=sqlite:/app/data/lousho.db`. +- The [Authentication](docs/auth.md) examples read secrets from the environment and fail at startup when they are missing, instead of falling back to a literal secret. + - **Behavior change:** the built node-server (and the Docker image) now guards `POST /channels/` and its approvals route for a channel without `verify` with `LOUSHO_API_TOKEN` / `auth.ts`, the same as `/chat`. Before, such a channel answered anyone even with a token set. Channels that verify their own requests (Slack, Discord, Telegram, GitHub, Teams, `webhookChannel` with a secret, any channel with `verify`) are unchanged, and the start-up log lists each channel route's guard (`self-verified`, `server-auth` or `open`). - **Behavior change:** `webhookChannel` replies with `{ sessionId, text, finishReason, approval? }` (plus `approvalPrompt` on a pause), as `httpChannel` does, instead of the full `ExecutionResult`. The full result echoed the system prompt and the whole transcript to the caller. `fullResult: true` restores the old body. - Channels answer a turn on a session that another process or replica is running (`LOUSHO_SESSION_BUSY`) with `409` and `Retry-After: 2` instead of a `500`, and report a turn that fails before the request is acknowledged to `onError` with stage `'turn'` (it said `'parse'`). @@ -21,6 +30,9 @@ opt-out. - CI is one workflow with two jobs: `ci` (type checks, lint, build, tests with coverage, docs, API and fallow gates, pack-smoke, size check, and a zod 4 type check) and `compat` (the newest peers, `ai` 7 with zod 4, plus the real-Docker sandbox tests). The separate Docker Engine, Agent Forge E2E and weekly registry-smoke workflows and the `ai` 6 / zod 3 matrix entries are gone; `npm run registry-smoke` and `npm run test:e2e:studio` still run locally. When the fallow gate fails, CI now prints its full health and duplication reports. ### Added +- `lousho add` falls back to the registry bundled in the npm package (`registry/dist`) when `registry.lousho.com` and its GitHub fallbacks are unreachable, with a notice that the bundled copy may be older. +- [Pause, restart and resume](docs/pause-and-resume.md): one tutorial for an approval that waits across a restart, crash recovery, and resending over HTTP. +- `SECURITY.md`: supported versions, private reporting through GitHub, and the disclosure policy. - `httpChannel()` created without `verify` logs one warning that the channel is unauthenticated and its `sessionKey` values are guessable. [Channels](docs/channels.md) shows `verify` in the quick start, and [Deployment](docs/deployment.md) says which routes `LOUSHO_API_TOKEN` guards. - `POST /chat` accepts an `Idempotency-Key` header: a resend with the same key replays the finished turn's reply (`Idempotent-Replayed: true`, nothing runs), resumes a turn a crash interrupted instead of appending the message again, and is a `409` (`LOUSHO_SESSION_BUSY`) while that turn still runs. The key is stored on the turn's user message (`metadata.idempotencyKey`), so it survives restarts; `session.pending()` reports it as `idempotencyKey`. See [Resending a turn](docs/deployment.md#resending-a-turn). - `fromAiSdkTools(record)` converts Vercel AI SDK tools (`tool({ ... })` or plain `{ description, inputSchema | parameters, execute, needsApproval? }` objects) into Lousho tools, keyed by name: zod and Standard Schemas are kept, `jsonSchema()` wrappers and plain JSON Schemas are converted (their own `validate` still runs), `needsApproval` (boolean or function) pauses the run for approval, and `execute` gets the call id and the run's abort signal. It imports nothing from `ai`, so tools built on `ai` 4 to 7 work with any installed version. New guide: [Migrating from the AI SDK](docs/migrating-from-ai-sdk.md). diff --git a/docs/upgrading.md b/docs/upgrading.md index 7df47e8d..b900c950 100644 --- a/docs/upgrading.md +++ b/docs/upgrading.md @@ -223,6 +223,8 @@ there is one. A change marked "no opt-out" closed a security or data-loss bug. | The built node-server (and Docker image) requires `LOUSHO_API_TOKEN` / `auth.ts` on `/channels/` for a channel without `verify` when a token or `auth.ts` is set; self-verifying channels are unchanged. | give the channel a `verify` | | `webhookChannel` replies `{ sessionId, text, finishReason, approval? }` instead of the full `ExecutionResult`. | `webhookChannel({ fullResult: true })` | | A channel turn on a session another process is running answers `409` (`LOUSHO_SESSION_BUSY`, `Retry-After: 2`) instead of `500`. | no opt-out (retry after the delay) | +| `POST /chat` on a session another process is running answers `409` (`LOUSHO_SESSION_BUSY`, `Retry-After: 2`) instead of a `200` stream holding only the error. | no opt-out (retry after the delay) | +| The built server resumes runs a crash left in progress when it starts, and every 30 seconds. | `LOUSHO_RECOVER_ON_START=0` | ### Sessions, approvals and durability @@ -269,6 +271,8 @@ there is one. A change marked "no opt-out" closed a security or data-loss bug. | ------ | ------- | | MCP tools ask for approval by default (`approval: 'always'`); an MCP tool whose name equals a local tool's is refused. See [Approval for MCP tools](./mcp.md#approval-for-mcp-tools). | `approval: 'annotations'` on servers you trust | | Tool results are capped at 50,000 characters (head and tail kept). | `maxToolResultChars: Infinity` | +| `createAgent()` and `defineTool()` throw `LOUSHO_CONFIG_INVALID` for an option key they don't know, with a suggestion. | no opt-out (remove or rename the key) | +| The workspace file tools deny `.env` and `.env.*` by default (not `.env.example`, `.env.sample`, `.env.template`). | pass your own `deny` list (it replaces the defaults) | | `defineTool()` throws `LOUSHO_CONFIG_INVALID` for a non-object `input` root or a `z.date()` / `z.bigint()` field; tool-call arguments that are not valid JSON reach the model as `LOUSHO_TOOL_ARGS_INVALID` instead of running the tool with `{}`. | no opt-out | | A flow `toolCall` step passes the agent's gate (`permissions`, `permissionMode`, approval) and validates its arguments; a call that needs approval fails with `LOUSHO_FLOW_TOOL_DENIED` without `approve`. See [Flows](./flows.md#tool-calls). | pass `approve` in the flow context | | `createShellTool` `allow` string patterns refuse arguments that leave the workspace (`..`, `~`, absolute paths), also through quotes. | an `allow` `CommandRule` with an `args` check | diff --git a/llms-full.txt b/llms-full.txt index 79fccb74..9725ff68 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -20147,6 +20147,8 @@ there is one. A change marked "no opt-out" closed a security or data-loss bug. | The built node-server (and Docker image) requires `LOUSHO_API_TOKEN` / `auth.ts` on `/channels/` for a channel without `verify` when a token or `auth.ts` is set; self-verifying channels are unchanged. | give the channel a `verify` | | `webhookChannel` replies `{ sessionId, text, finishReason, approval? }` instead of the full `ExecutionResult`. | `webhookChannel({ fullResult: true })` | | A channel turn on a session another process is running answers `409` (`LOUSHO_SESSION_BUSY`, `Retry-After: 2`) instead of `500`. | no opt-out (retry after the delay) | +| `POST /chat` on a session another process is running answers `409` (`LOUSHO_SESSION_BUSY`, `Retry-After: 2`) instead of a `200` stream holding only the error. | no opt-out (retry after the delay) | +| The built server resumes runs a crash left in progress when it starts, and every 30 seconds. | `LOUSHO_RECOVER_ON_START=0` | ### Sessions, approvals and durability @@ -20193,6 +20195,8 @@ there is one. A change marked "no opt-out" closed a security or data-loss bug. | ------ | ------- | | MCP tools ask for approval by default (`approval: 'always'`); an MCP tool whose name equals a local tool's is refused. See [Approval for MCP tools](https://github.com/LinuxDevil/agent-sdk/blob/main/docs/mcp.md#approval-for-mcp-tools). | `approval: 'annotations'` on servers you trust | | Tool results are capped at 50,000 characters (head and tail kept). | `maxToolResultChars: Infinity` | +| `createAgent()` and `defineTool()` throw `LOUSHO_CONFIG_INVALID` for an option key they don't know, with a suggestion. | no opt-out (remove or rename the key) | +| The workspace file tools deny `.env` and `.env.*` by default (not `.env.example`, `.env.sample`, `.env.template`). | pass your own `deny` list (it replaces the defaults) | | `defineTool()` throws `LOUSHO_CONFIG_INVALID` for a non-object `input` root or a `z.date()` / `z.bigint()` field; tool-call arguments that are not valid JSON reach the model as `LOUSHO_TOOL_ARGS_INVALID` instead of running the tool with `{}`. | no opt-out | | A flow `toolCall` step passes the agent's gate (`permissions`, `permissionMode`, approval) and validates its arguments; a call that needs approval fails with `LOUSHO_FLOW_TOOL_DENIED` without `approve`. See [Flows](https://github.com/LinuxDevil/agent-sdk/blob/main/docs/flows.md#tool-calls). | pass `approve` in the flow context | | `createShellTool` `allow` string patterns refuse arguments that leave the workspace (`..`, `~`, absolute paths), also through quotes. | an `allow` `CommandRule` with an `args` check |