Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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#<code>` 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/<name>` 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'`).
Expand All @@ -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).
Expand Down
4 changes: 4 additions & 0 deletions docs/upgrading.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/<name>` 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

Expand Down Expand Up @@ -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 |
Expand Down
4 changes: 4 additions & 0 deletions llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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/<name>` 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

Expand Down Expand Up @@ -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 |
Expand Down
Loading