From 835bd1879d561af44b9f061016fe92311ec1d503 Mon Sep 17 00:00:00 2001 From: Ali Mohammad Date: Fri, 13 Nov 2026 07:12:55 +0300 Subject: [PATCH 1/2] docs: sync Forge builder, Author and lifecycle pages Adds forge-builder, forge-author and forge-lifecycle (SDK PRs #1125/#1126) to the sync map and Ship nav, regenerates all synced pages from the SDK, and marks the three new pages pending-translation with Arabic stubs. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- agent-forge.mdx | 184 ++++++++------ approvals.mdx | 63 +++++ ar/channels.mdx | 8 +- ar/cli.mdx | 2 +- ar/comparison.mdx | 2 +- ar/durable-execution.mdx | 6 +- ar/errors.mdx | 28 +-- ar/evals.mdx | 8 +- ar/flows.mdx | 2 +- ar/forge-author.mdx | 8 + ar/forge-builder.mdx | 8 + ar/forge-lifecycle.mdx | 8 + ar/hosted-tools.mdx | 2 +- ar/mcp-integration.mdx | 4 +- ar/observability.mdx | 2 +- ar/pause-and-resume.mdx | 8 + ar/pending.json | 5 +- ar/providers.mdx | 4 +- ar/schedules.mdx | 2 +- ar/sessions.mdx | 6 +- ar/testing.mdx | 2 +- ar/triggers.mdx | 2 +- ar/troubleshooting.mdx | 12 +- ar/upgrading.mdx | 2 +- ar/workspace-tools.mdx | 2 +- changelog.mdx | 184 +++++++++++++- cli.mdx | 245 ++++++++++++++++++- comparison.mdx | 136 ++++++----- configuration.mdx | 4 +- decisions.mdx | 2 +- docs.json | 3 + durable-execution.mdx | 20 ++ errors.mdx | 201 +++++++++++++++- examples/hostinger-deploy.mdx | 2 +- flows.mdx | 49 ++++ forge-author.mdx | 161 +++++++++++++ forge-builder.mdx | 170 +++++++++++++ forge-lifecycle.mdx | 437 ++++++++++++++++++++++++++++++++++ hooks.mdx | 86 +++++++ hostinger-vps.mdx | 2 +- installation.mdx | 2 +- migrating-from-ai-sdk.mdx | 1 - observability.mdx | 142 ++++++++++- prompting-techniques.mdx | 20 +- providers.mdx | 26 ++ registry.mdx | 2 +- schedules.mdx | 15 ++ scripts/sync-sdk-docs.mjs | 3 + stream-events.mdx | 1 + triggers.mdx | 26 ++ troubleshooting.mdx | 2 +- upgrading.mdx | 1 + 52 files changed, 2122 insertions(+), 201 deletions(-) create mode 100644 ar/forge-author.mdx create mode 100644 ar/forge-builder.mdx create mode 100644 ar/forge-lifecycle.mdx create mode 100644 ar/pause-and-resume.mdx create mode 100644 forge-author.mdx create mode 100644 forge-builder.mdx create mode 100644 forge-lifecycle.mdx diff --git a/agent-forge.mdx b/agent-forge.mdx index 7e5039d..2c01740 100644 --- a/agent-forge.mdx +++ b/agent-forge.mdx @@ -19,7 +19,15 @@ This doc covers: installation, the `lousho studio` quickstart, the authoring, time travel (replaying a run from a past step), the playground endpoint, and how settings/secrets/deploy wiring works. -![The Agents screen: nav, agent rail, the fitted canvas with the Inspector folded, and the bottom drawer](/images/studio-agents.png) +Three features have their own pages: [the visual +builder](/forge-builder) — the canvas, Inspector, Configure tab, +in-place testing and Code tab — [the Agent +Author](/forge-author) — the chat that drafts agents as proposals you +review before anything is saved — and [versions, triggers and +publishing](/forge-lifecycle) — the working copy, drafts, the inbox, +the eval gate, Serve and Deploy. + +![The builder: nav, agent rail, the fitted canvas with the Inspector folded, and the bottom drawer](/images/studio-agents.png) ## Installation @@ -45,20 +53,22 @@ npx lousho studio This starts one local server and prints its URL (default `http://127.0.0.1:4750/?token=`). Open that exact URL in a browser. -It lands on the Agents screen (`#/agents`): the left navigation, the build -toolbar (the agent's name and run status, the model badge, then Debug, Stop, -Run, Import, Export and Save), the -agent rail (your saved agents plus a node/hook palette), the canvas, the -Inspector (right), and a bottom drawer with Chat, Logs, Trace, Output, -History and Settings tabs. An agent opens with nothing selected and the -whole graph fitted in view; the Inspector stays folded away until you -select a node, or press the **Inspector** button at the canvas's -top-right (its accessible name is "Show inspector"), which is remembered. The other screens are one click away in the -navigation; see [Navigation](#navigation). +It lands on the Agents list (`#/agents`): your saved agents as cards, plus +a **New agent** menu. Opening or creating one takes you to its Canvas tab +(`#/agents//canvas`) — the builder: the build toolbar (the agent's name +and run status, the model badge, then Debug, Stop, Run, Import, Export and +Save), the agent rail (your saved agents plus a node/hook palette), the +canvas, the Inspector (right), and a bottom drawer with Test, Problems, +Logs, Trace, Output, History and Settings tabs. An agent opens with +nothing selected and the whole graph fitted in view; the Inspector stays +folded away until you select a node, or press the **Inspector** button at +the canvas's top-right (its accessible name is "Show inspector"), which is +remembered. The other screens are one click away in the navigation; see +[Navigation](#navigation). Below 860px wide the navigation becomes a drawer opened from the **Navigation** (menu) button at the top; picking a screen, the scrim or Esc -closes it. On the Agents screen the agent rail and the Inspector become +closes it. On the builder the agent rail and the Inspector become slide-over panels you open from the top bar; Run (or Stop) and Save stay in the bar, and Debug, Import, Export and the model badge move into its **More actions** (`⋯`) menu. @@ -106,9 +116,11 @@ without the CLI: Agent specs and run state are stored under `.lousho/` in the directory you ran `lousho studio` from (agent YAML files under `.lousho/agents/`, checkpoints and approvals alongside them) - the same `.lousho/` layout -`lousho dev`/`lousho build` use. +`lousho dev`/`lousho build` use. Those YAML files are +[Agent spec v2](https://github.com/LinuxDevil/agent-sdk/blob/main/docs/agent-spec.md) documents, which that page explains field +by field. -The Agents screen's agent rail lists exactly the agents in that `.lousho/agents/`: a YAML +The agents list and the builder's agent rail show exactly the agents in that `.lousho/agents/`: a YAML file you add there shows up, and an agent you create in the studio is written there at once (autosave and **Save** both write the file), so it can be chatted with straight away. Another project, opened in its own @@ -142,8 +154,11 @@ The left navigation lists every screen, grouped: | Group | Item | Screen | | --- | --- | --- | -| Build | **Agents** | The builder: canvas, Inspector, bottom drawer. The build toolbar (Run, Stop, Debug, Import, Export, Save, model badge) shows only here. | +| Build | **Agents** | The agents list; an agent opens on tabs — Canvas (the builder), Overview, Configure, Code, Runs, Versions, Suggestions. The build toolbar (Run, Stop, Debug, Import, Export, Save, model badge) shows on the Canvas tab. | +| Build | **Inbox** | Pending approvals, questions, drafts, suggestions and notices, one row each with inline actions. | +| Build | **Templates** | Agent templates you can start from. | | Build | **Playground** | Try messages against a model without editing an agent. | +| Build | **Workspaces** | Workspaces in this project: their pages, problems, drafts and revisions. | | Observe | **Traces** | Every run the observe daemon holds, filtered and sorted; a row opens the trace. | | Observe | **Threads** | Sessions (conversations): one row per session, one turn per run. | | Observe | **Monitoring** | The fleet's health and charts over a time window. | @@ -152,7 +167,7 @@ The left navigation lists every screen, grouped: | Assets | **Context Hub** | Shared key-values agents publish to the daemon. | | | **Settings** | Appearance, provider keys, settings profiles, deploy, collector and shortcuts. | -Off the Agents screen a page header names the screen and keeps the live run +Off the builder a page header names the screen and keeps the live run status pill at the end of its title row, after any chips the screen adds (a prompt's labels, say). Under Settings, a small card shows the collector status (see [The collector](#the-collector-observe-daemon)). The button beside the @@ -173,7 +188,9 @@ unknown hash goes to `#/agents` (the `?token=` stays). | Route | Screen | Query keys | | --- | --- | --- | -| `#/agents`, `#/agents/` | Agents, with that agent open | | +| `#/agents` | Agents list | | +| `#/agents//canvas` | The builder for that agent | | +| `#/agents//` | One agent tab: `overview`, `configure`, `code`, `runs`, `versions`, `suggestions` | | | `#/playground` | Playground | `trace` + `fromObs`, or `prompt` (see [Playground](#playground)) | | `#/traces` | Traces list | `agent`, `status`, `model`, `project`, `q`, `prompt` (`` or `@`), `from` + `to` (ms epoch, half-open), `sort` (`duration`, `tokens`, `cost`) + `order` (`asc`, `desc`), `offset` | | `#/traces/` | One trace | `obs` (the selected step) | @@ -187,6 +204,8 @@ unknown hash goes to `#/agents` (the `?token=` stays). | `#/prompts` | Prompt registry | | | `#/prompts/`, `#/prompts/@` | One prompt (latest version by default) | `diff=,` | | `#/hub`, `#/hub/` | Context Hub | `agent` (the "Viewing as" agent), `scope` (`private`, `fleet`) | +| `#/workspaces` | Workspaces list | `q` (filters name, id, domain) | +| `#/workspaces/`, `#/workspaces//
` | One workspace; section is `overview`, `main-agent`, `pages`, `agents`, `runs`, `improve` or `revisions` | | | `#/settings` | Settings | | A time range picked from a preset other than the default is written as @@ -209,6 +228,9 @@ browser); type to filter. Paste a trace id (8 or more hex digits and dashes) and the first entry is **Open trace** for it. Arrow keys move, Enter runs. +The builder's own shortcuts — save version, undo/redo, palette search, +node delete — are listed in [the visual builder](/forge-builder#keyboard-shortcuts). + ![The command palette over the Traces screen](/images/studio-command-palette.png) In an annotation queue's review, Enter submits the scores and `S` skips @@ -251,18 +273,24 @@ The collector card at the bottom of the nav says whether the daemon answers: **Checking collector…** until the first probe, then **Collector running** or **Collector unreachable**, with the daemon URL underneath. The probe keeps polling. While the daemon is down, each daemon screen shows the command to start it instead of an error, keeps its -URL, and swaps the data back in by itself once the daemon answers. The -Agents screen and Playground runs do not need the daemon. +URL, and swaps the data back in by itself once the daemon answers. Builder +and Playground runs do not need the daemon. ## Screens ### Agents -The builder: see the [First-agent walkthrough](#first-agent-walkthrough). -`#/agents/` opens that agent; leaving the screen (or switching agents) -with unsaved changes asks first. Runs started here report to the observe -daemon, and the Run status pill's **Open trace** link opens the run on the -Trace screen. +`#/agents` is the agents list: a card per agent in `.lousho/agents/`, a +**New agent** menu (**Blank agent**, **From template**, +**Describe with AI** — see [the Agent Author](/forge-author) — or +**Import from file…**), and search and label filters. +Opening a card goes to its Canvas tab, the builder — see +[the visual builder](/forge-builder) and the +[first-agent walkthrough](#first-agent-walkthrough). `#/agents/` (the +legacy builder URL) redirects to `#/agents//canvas`. Leaving the +builder with unsaved changes asks first. Runs started there report to the +observe daemon, and the Run status pill's **Open trace** link opens the +run on the Trace screen. ### Playground @@ -299,6 +327,24 @@ says so and keeps an empty editor, and runs still work. Runs go through the [playground run endpoint](#playground-run-endpoint) and report as agent `playground`. +### Workspaces + +`#/workspaces` lists the workspaces the typed workspaces API knows: name and +domain, page count, a `Valid`/`Invalid (n)` badge from the workspace's +problems, the live revision and a last-run column (filled in by a later +ticket). `#/workspaces/` opens one workspace with a header that carries +the live revision, the problems badge, an **Draft open** badge while a draft +exists, and disabled **Run**/**Chat** actions; a left nav switches between +the `overview`, `main-agent`, `pages`, `agents`, `runs`, `improve` and +`revisions` sections, the ones not built yet naming their ticket. Every edit +is a typed authoring operation sent through `ApiClient.call('applyOps', …)` +into a draft with `expectedRevision`; the draft is applied or discarded +later. When the live revision moved under an open screen the operation gets a +409, the latest revision reloads and a toast says "This workspace changed +since you opened it." The screens call only the workspaces API +(`/api/workspaces`, mounted by a later ticket), through an injected +`ApiClient`, so they run on fixtures today and move to the Next.js app later. + ### Traces ![The Traces list](/images/studio-traces.png) @@ -511,27 +557,28 @@ and deploy cards; see [Settings, secrets and deploy wiring](#settings-secrets-an ## First-agent walkthrough -1. **Create an agent.** In the agent rail's **Agents** tab, click - **New agent**, give it a name, and pick a starting template - **Blank graph** (a single - LLM node using the built-in `mock` provider) is the fastest way to try - things out without any API keys. Agent Forge creates the agent under that - name (`.lousho/agents/.yaml`, with `name: ` in the spec) and +1. **Create an agent.** On the agents list (`#/agents`) click **New agent** + and pick **Blank agent** - it starts from an empty canvas, which is the + fastest way to try things out without any API keys (**From template** + offers ready-made starting points instead). Agent Forge creates the agent + (`.lousho/agents/.yaml`, with `name:` in the spec) and opens it on the canvas. The open agent's card has **Rename** and **Delete**. Rename moves the spec to the new name; earlier chats, traces and checkpoints stay under the old one. -2. **Look at the graph.** A blank agent is one `llm` node. Drag more nodes - in from the rail's **Nodes** tab (**Trigger**, **LLM step**, **Tool - call**, **Approval gate**, **Response / output**), or click (or press +2. **Look at the graph.** A blank agent is a single agent node. Drag more + nodes in from the rail's **Nodes** tab (a **Tool**, an **MCP server**, + a **Guardrail**, a **Chat** trigger, an **Output schema** — the full + list is in [the visual builder](/forge-builder#the-canvas)), or + click (or press Enter on) a Nodes item to add it at the centre of the canvas, and connect them by - dragging between their handles. Each node card shows its name, an LLM - node's `provider/model` chip and tool count, and the node's status in the + dragging between their handles. Each node card shows its name, an agent + node's `provider/model` chip, and the node's status in the current run (`idle` until a run reaches it). Click a node to edit its - settings (prompt, provider/model, tools, breakpoints) in the Inspector on - the right; its **Node**, **Debug** and **Hooks** sections collapse, and - each stays the way you left it. An agent whose canvas has no nodes shows - the templates on the canvas: choosing one fills the canvas (unsaved until - it autosaves, like any edit) and keeps the agent's name. + settings in the Inspector on + the right; its **Problems**, **Settings** and **Debug** sections + collapse, and + each stays the way you left it. 3. **Run it.** Click **Run** in the top bar. With the `mock` provider there's nothing to configure - it returns deterministic canned output, which is exactly the point for trying the rest of the UI without needing @@ -545,7 +592,7 @@ and deploy cards; see [Settings, secrets and deploy wiring](#settings-secrets-an twice), a daemon that is down only drops events and never fails the run, and message content is sent only to a loopback daemon (never to the trace files or the live Trace tab). Run sends a fixed - prompt, which the Chat tab shows + prompt, which the Test tab's chat shows as a **Run input** bubble instead of a message from you. If the studio server goes away, a banner says the connection was lost and the studio reconnects when it is back. @@ -584,52 +631,53 @@ and deploy cards; see [Settings, secrets and deploy wiring](#settings-secrets-an tool content. The server reads traces only from that folder (an id with a path separator is a 400) and never sends the file path to the browser. Keep `.lousho/` out of version control. -5. **Chat with it.** The **Chat** tab is a separate conversational +5. **Chat with it.** The chat in the bottom drawer's **Test** tab is a + separate conversational transport (`POST /agents/:id/message`, streamed back over the same WebSocket as everything else) - send it a message and it replies in the thread, independent of the graph "Run" button above. Each agent keeps its own chat history (`+ New chat` starts a fresh session; old ones stay browsable). -6. **Approve a paused tool call.** Add a **Tool call** node, open it in the +6. **Approve a paused tool call.** Add a **Tool** node, open it in the Inspector, and pick a tool - some tools (or an agent's own policy) can require human approval before running. When a run or chat hits one, an inline approval card appears (in the top bar for a graph run, or as a - message bubble in the Chat thread) showing the tool name and its + message bubble in the chat thread) showing the tool name and its arguments. Click **Approve** to let it proceed or **Reject** to abort that call; the run resumes automatically either way. ## Hooks Hooks are small, sandboxed functions that run immediately before or -after a tool call or an LLM `generate` - the same mechanism the SDK core +after a tool call or a model call - the same mechanism the SDK core exposes as `HookRegistry`/`AgentHook` (see -[API Overview](/api-overview)), but authored visually and attached to a -specific canvas node. - -To attach one: - -1. Select an `llm` or `tool` node on the canvas (hooks only apply to these - - they're the two points `AgentExecutor` actually calls out to). -2. Open the Inspector's **Hooks** section. Drag a **Pre-hook** or - **Post-hook** entry from the rail's **Nodes** tab onto the node (or drop - it directly in the Hooks section), or click the palette entry while the - node is selected, to attach a new one; you'll get a - choice of starter templates (`redact-pii`, `rate-limit`, `audit-log`, - `inject-context`) as an editable starting point. -3. Click the hook's chip to select it, then edit its code in the CodeMirror - editor. The code is the **body** of an async function invoked as +[API Overview](/api-overview)), authored visually as `hooks[]` entries +on the agent. + +To add one: + +1. Drag a **Hook** entry from the rail's **Nodes** tab (Safety group) onto + the canvas, or click it while the agent is open; it attaches to the + agent as a node. Each spec `hooks` entry is one node. +2. Click the hook node and edit its fields in the Inspector: an id, a + name, the **Source** (**Code here** for an inline body, or **File** for + a `.ts`/`.js` file inside the agent folder), the **Runs** point - + *Before/After each tool call* or *Before/After each model call* - the + on switch, and the code itself in a CodeMirror editor, with starter + templates (`redact-pii`, `rate-limit`, `audit-log`, `inject-context`) + filtered to the current point. +3. The code is the **body** of an async function invoked as `hook(ctx)` inside a sandboxed subprocess (`server/hookSandbox.ts`) - never in the browser or the API server process itself: - - For a tool-call hook, `ctx` is `{ toolName, args, result?, error? }`. + - For a tool-call point, `ctx` is `{ toolName, args, result?, error? }`. A pre-hook can mutate `ctx.args`; a post-hook can inspect/mutate `ctx.result`/`ctx.error`. Return `ctx`. - - For an LLM-generate hook, `ctx` is `{ messages, model }`. Mutate/push + - For a model-call point, `ctx` is `{ messages, model }`. Mutate/push onto `ctx.messages` and return `ctx`. - **Throwing aborts the step** - a rate-limit hook, for example, throws to block the tool call outright rather than letting it run. -4. Toggle the switch on a hook's chip to enable/disable it without removing - it, or use its **x** to remove it entirely. Only enabled hooks are - compiled into the run. +4. Switch a hook off without removing it, or delete its node; only enabled + hooks are compiled into the run. Example: a redact-PII pre-hook on a tool node (this is the `redact-pii` starter template) - @@ -644,7 +692,7 @@ for (const key of Object.keys(ctx.args || {})) { return ctx; ``` -Saving the agent persists these as `spec.policy.hooks` in the agent's YAML; +Saving the agent persists these as `hooks` entries in the agent's YAML; the server compiles enabled hooks into a real `HookRegistry` for the run (`server/compileHooks.ts`), routed through the same `SandboxAdapter` a sandboxed tool uses. @@ -663,7 +711,7 @@ and replay it next to the original, with ### The History tab -1. Run the agent (Topbar **Run**, or a Chat message). +1. Run the agent (Topbar **Run**, or a chat message). 2. Open the bottom drawer's **History** tab. It lists the run's steps: step number, status, the model's finish reason, the tool calls made, and the tokens and cost of the step's model call when known. @@ -805,7 +853,7 @@ automatically as long as `apps/agent-forge/dist-server` hasn't been built yet: ```bash -git clone https://github.com/LinuxDevil/agent-sdk.git +git clone https://github.com/LinuxDevil/lousho.git cd agent-sdk npm install npx lousho studio --dev # or just `npx lousho studio` before building @@ -837,7 +885,7 @@ at a server-local `demo-approval` tool (always `needsApproval: true` - see `server/buildAgent.ts`'s doc comment for why this exists, since none of the SDK's spec-resolvable built-in tools require approval), sends it a chat message that triggers the mock provider's tool-call heuristic, waits -for the run to pause on the approval gate, approves it via the Chat tab's +for the run to pause on the approval gate, approves it via the Test tab's inline approval card, and asserts the run completes. Run it with: ```bash diff --git a/approvals.mdx b/approvals.mdx index f2f45de..80bc19b 100644 --- a/approvals.mdx +++ b/approvals.mdx @@ -448,6 +448,69 @@ const trusted = createAgent({ }); ``` +### Model-decided approvals + +`createAutoApprove` wraps a cheap model as the `approve` callback: calls an +`auto` permission rule matched get a 0–1 safety score, and a score at or +above 0.8 (within 8 s) runs the tool unreviewed. Everything else — a lower +score, a timeout, a model error, arguments too long to judge — defers to a +human exactly like `'defer'`. It never denies a call on its own. + +```ts +import { ask, createAgent, createAutoApprove, modelAutoApprover } from 'lousho'; + +declare const issueTool: any; +declare const cheapProvider: import('lousho').LLMProvider; + +const agent = createAgent({ + provider, + tools: [issueTool, emailTool], + permissions: [ask(['create_issue'])], + approve: createAutoApprove({ + autoApprover: modelAutoApprover({ provider: cheapProvider }), + isAuto: (toolName) => toolName === 'create_issue', + // fallback: the agent's own approve, asked for non-auto and escalated calls + onDecision: (d) => console.log(d.toolName, d.outcome, d.cause), + }), +}); +``` + +`modelAutoApprover` asks the provider for `{"safety": <0..1>, "reason": +"..."}` at temperature 0; `createAutoApprove` clips long arguments before +they reach the model and reports every decision through `onDecision`. Pass a +`fallback` approve callback to keep a second line of defense for escalated +calls. + +An AgentSpec v2 wires the same machinery from a permission rule: `action: +'auto'` compiles to `ask`, and a host that supplies `autoApprover` (and +optionally `onAutoApproval`) gets the model-scored callback for exactly +those rules — first match still wins, so an `allow` listed before an `auto` +rule means the model is never consulted. + +```yaml +permissions: + - id: p1 + tool: github_create_issue + action: auto +``` + +```ts +import { modelAutoApprover, specV2ToAgent } from 'lousho'; + +declare const spec: import('lousho').AgentSpecV2; +declare const baseDir: string; +declare const cheapProvider: import('lousho').LLMProvider; + +const agent = await specV2ToAgent(spec, { + baseDir, + autoApprover: modelAutoApprover({ provider: cheapProvider }), + onAutoApproval: (d) => console.log(d.toolName, d.outcome, d.cause), +}); +``` + +With no `autoApprover` on the host, `action: 'auto'` behaves exactly like +`ask`. + ### Streaming the continued run `agent.approvals.streamResolve(decision, { signal })` and diff --git a/ar/channels.mdx b/ar/channels.mdx index b7af554..5e43af7 100644 --- a/ar/channels.mdx +++ b/ar/channels.mdx @@ -224,10 +224,10 @@ await channels.resolveApproval({ id: 'the-approval-id', approved: true }); | ------- | ------- | -------- | | `httpChannel({ name?, verify? })` | JSON `{ sessionKey, input }` (`input` نص أو content parts)؛ أي شيء ثاني 400. وبدون `verify`، جسم ينرسل بدون `Content-Type: application/json` ياخذ `415` (`LOUSHO_UNSUPPORTED_MEDIA_TYPE`)، فصفحة ويب ما تقدر ترسل له فورم | `200 { sessionId, text, finishReason }`؛ ولما يتوقف، `approval` كمان و`text` هو الـ prompt | | `webhookChannel({ secret?, auth?, name?, principal? })` | نص `input` في جسم JSON، أو الجسم كله؛ session لمرة وحدة إلا لو الجسم فيه `sessionKey` | `200` مع `ExecutionResult` تبع الـ turn | -| `slackChannel({ signingSecret, botToken, name?, fetch?, approvers?, onError? })` | طلبات Slack Events API والتفاعلات (راجع [Slack](#slack)) | `200` فورًا؛ الردود تُنشر في الـ thread على Slack | -| `discordChannel({ publicKey, applicationId, botToken?, name?, fetch?, approvers?, onError? })` | تفاعلات slash command والأزرار في Discord (راجع [Discord](#discord)) | ack مؤجّل فورًا؛ الرد يعدّل الرد الأصلي | -| `telegramChannel({ botToken, secretToken, botUsername?, name?, fetch?, approvers?, onError? })` | تحديثات webhook البوت في Telegram: رسائل ونقرات على inline keyboard (راجع [Telegram](#telegram)) | `200` فورًا؛ الردود تُرسل بـ `sendMessage` كنص عادي | -| `githubChannel({ webhookSecret, botName, token?, app?, name?, apiUrl?, fetch?, triggers?, approvers?, onError? })` | تعليقات GitHub على issues وpull requests والـ reviews اللي تذكر `@` (راجع [GitHub](#github)) | `200` فورًا؛ الردود تُنشر كتعليقات في نفس الـ thread | +| `slackChannel({ signingSecret, botToken, name?, fetch?, approvers?, onError? })` | طلبات Slack Events API والتفاعلات (راجع [Slack](#discord)) | `200` فورًا؛ الردود تُنشر في الـ thread على Slack | +| `discordChannel({ publicKey, applicationId, botToken?, name?, fetch?, approvers?, onError? })` | تفاعلات slash command والأزرار في Discord (راجع [Discord](#telegram)) | ack مؤجّل فورًا؛ الرد يعدّل الرد الأصلي | +| `telegramChannel({ botToken, secretToken, botUsername?, name?, fetch?, approvers?, onError? })` | تحديثات webhook البوت في Telegram: رسائل ونقرات على inline keyboard (راجع [Telegram](#github)) | `200` فورًا؛ الردود تُرسل بـ `sendMessage` كنص عادي | +| `githubChannel({ webhookSecret, botName, token?, app?, name?, apiUrl?, fetch?, triggers?, approvers?, onError? })` | تعليقات GitHub على issues وpull requests والـ reviews اللي تذكر `@` (راجع [GitHub](#microsoft-teams)) | `200` فورًا؛ الردود تُنشر كتعليقات في نفس الـ thread | | `teamsChannel({ appId, appPassword, tenantId?, name?, fetch?, approvers?, onError? })` | رسائل Microsoft Teams ونقرات أزرار Adaptive Card من Azure Bot (راجع [Microsoft Teams](#microsoft-teams)) | `200` فورًا؛ الردود تُنشر عبر Bot Framework Connector كـ Markdown | `webhookChannel({ secret })` تفحص توقيع HMAC-SHA256 للجسم الخام في diff --git a/ar/cli.mdx b/ar/cli.mdx index 7449e9d..7a17bc1 100644 --- a/ar/cli.mdx +++ b/ar/cli.mdx @@ -14,7 +14,7 @@ title: "CLI" | `lousho acp ` | يقدّم ملف spec أو مجلد agent أو agent مكتوب بـ TS لمحرر (Zed وغيره من ACP clients) عبر Agent Client Protocol على stdio. | [ACP](/ar/acp) | | `lousho add ` | يثبّت tool أو skill أو channel أو schedule أو memory slot من JSON registry داخل مجلد agent، بعد ما يعرض الـ permission manifest ويفحص الكود مقابله. | [Registry](/ar/registry) | | `lousho mcp ` | يقدّم الـ agent كسيرفر MCP (stdio، أو HTTP مع `--http`). | [MCP](/ar/mcp-integration#تشغيل-agent-كسيرفر-mcp) | -| `lousho eval [globs...]` | يشغّل ملفات `*.eval.ts` تحت vitest؛ ويطبع ملخصًا ويكتب تقارير JUnit/JSON. | [Evals](/ar/evals#lousho-eval) | +| `lousho eval [globs...]` | يشغّل ملفات `*.eval.ts` تحت vitest؛ ويطبع ملخصًا ويكتب تقارير JUnit/JSON. | [Evals](/ar/evals#حدود-الوقت) | | `lousho traces [id]` | يعرض آخر runs حفظها `fileTraceExporter()` (المدة، والـ model والـ tool calls، والـ tokens، والتكلفة)، أو يطبع run واحد كشجرة spans. | [Observability](/ar/observability#local-traces) | | `lousho build --target= --agent=` | يبني سيرفر Node أو Docker image أو Cloudflare Worker جاهزًا للنشر. | [النشر](/ar/deployment) | | `lousho studio` | يفتح Agent Forge، الـ dashboard المرئية، على port محلي واحد. | [Agent Forge](/ar/agent-forge) | diff --git a/ar/comparison.mdx b/ar/comparison.mdx index 7ac66a0..3d8553a 100644 --- a/ar/comparison.mdx +++ b/ar/comparison.mdx @@ -32,7 +32,7 @@ approvals متينة و evals و harnesses خاصة بها لـ coding agents، يشغّل كل حالة مرة واحدة على الـ provider الحقيقي ويكتب cassette، و`--replay` يشغّلها في CI بدون شبكة ولا مفتاح API، و`--drift` يعيد التسجيل في مجلد مؤقت ويوضّح كيف تغيّر مسار استدعاءات الـ tools - في كل حالة ([Evals](/ar/evals#record-replay-and-drift)، + في كل حالة ([Evals](/ar/evals#تشغيل-evals-على-deployment)، [Testing](/ar/testing#record-و-replay)). - **approvals متينة على Cloudflare Workers KV** إلى جانب الذاكرة والملفات و SQLite، بنفس كود `needsApproval` / `resumeAfterApproval()` على كل منها diff --git a/ar/durable-execution.mdx b/ar/durable-execution.mdx index d8c8cf4..d6dcbe3 100644 --- a/ar/durable-execution.mdx +++ b/ar/durable-execution.mdx @@ -348,7 +348,7 @@ if (original && replayed) { - `patch` يتطبق بهذا الترتيب: `messages(messages)` يعيد كتابة الـ transcript؛ `businessState` يستبدل القيمة المحفوظة؛ `toolResult: { toolCallId, result }` يستبدل نتيجة هالـ call في مكانها — نفس الموضع ونفس الـ call id ونفس اسم الـ tool، فيبقى الـ transcript صالح لكل provider — أو يسجلها لو الـ call ما عندها نتيجة إلى الآن؛ `appendInput` يضع رسالة user في الانتظار، تترسل بعد أي tool calls ما زالت معلقة. - الـ fork يحتفظ بعدد خطوات الـ checkpoint المصدر و`usage` حقها، فينطبق عليه اللي باقي من ميزانية `maxSteps`. نتائج الـ tools المسجلة ما تتعاد؛ والـ tool calls اللي بدون نتيجة تشتغل أول، مثل أي استئناف (يعني fork لمدخل `'awaiting-approval'` يمر على `needsApproval` من جديد؛ و`approvalId` القديم ما ينتقل). - `newSessionId` يسمي الـ fork؛ الافتراضي `.fork-`، و`n` أول رقم ما عنده checkpoint. `newSessionId` اللي عنده checkpoint أصلًا يُرفض. -- خطوة ما هي موجودة في الـ history — الـ session غير معروفة، أو الخطوة ما اشتغلت أبدًا، أو انحذفت بعد ما تجاوزت `historyLimit` — ترمي `SDKError` بكود [`LOUSHO_CHECKPOINT_NOT_FOUND`](/ar/errors#lousho_checkpoint_not_found)، ورسالته تعدّد الخطوات المحفوظة. وstore بدون `history()` ما يقدر يسوي fork (`ConfigurationError`). +- خطوة ما هي موجودة في الـ history — الـ session غير معروفة، أو الخطوة ما اشتغلت أبدًا، أو انحذفت بعد ما تجاوزت `historyLimit` — ترمي `SDKError` بكود [`LOUSHO_CHECKPOINT_NOT_FOUND`](/ar/errors#lousho_run_already_iterated)، ورسالته تعدّد الخطوات المحفوظة. وstore بدون `history()` ما يقدر يسوي fork (`ConfigurationError`). - `compareTrajectories(a, b)` تاخذ checkpointين أو transcriptين وترجع خطوات كل run — خطوة لكل turn للـ assistant: نصها وtool callsها مع نتائجها — و`divergedAt` (أول خطوة تختلف، بغض النظر عن ids الـ tool calls)، و`drift`، وهو فروق ترتيب الـ tools والـ arguments وعدد الخطوات وسبب الإنهاء، بنفس شكل `lousho eval --drift`. ## استئناف run بعد ما يتغير الـ agent @@ -360,10 +360,10 @@ if (original && replayed) { | `onAgentDrift` | لو الـ model أو الـ tools أو التعليمات اختلفت | | -------------- | ------------------------------------------- | | `'warn'` (الافتراضي) | `console.warn` يسمي اللي تغير وحدث `agent.drift` (`model`، `toolsAdded`، `toolsRemoved`، `toolsChanged`، `instructions`)؛ والـ run يكمل. | -| `'error'` | يرفض بـ[`LOUSHO_AGENT_DRIFT`](/ar/errors#lousho_agent_drift). الـ checkpoint يبقى مثل ما كان؛ والـ approval ترجع مكانها، فيقدر الـ agent الصحيح يحسمها بعدين. | +| `'error'` | يرفض بـ[`LOUSHO_AGENT_DRIFT`](/ar/errors#lousho_schedule_invalid). الـ checkpoint يبقى مثل ما كان؛ والـ approval ترجع مكانها، فيقدر الـ agent الصحيح يحسمها بعدين. | | `'ignore'` | لا شيء. | -tool call معلّقة الـ tool حقها ما عادت موجودة — آخر turn للـ model نادتها وما لها نتيجة إلى الآن، أو الإنسان وافق عليها — ترفض دائمًا بـ[`LOUSHO_RESUME_TOOL_MISSING`](/ar/errors#lousho_resume_tool_missing)، مهما كان الخيار. +tool call معلّقة الـ tool حقها ما عادت موجودة — آخر turn للـ model نادتها وما لها نتيجة إلى الآن، أو الإنسان وافق عليها — ترفض دائمًا بـ[`LOUSHO_RESUME_TOOL_MISSING`](/ar/errors#lousho_schedule_run_incomplete)، مهما كان الخيار. ```ts import { createAgent, memoryStore } from 'lousho'; diff --git a/ar/errors.mdx b/ar/errors.mdx index a6ac86d..08b283d 100644 --- a/ar/errors.mdx +++ b/ar/errors.mdx @@ -34,7 +34,7 @@ try { الاستثناءات شوية subclasses مسماة من `Error` بدون `code`، مبقاة عادية عن قصد: `PropagatingToolError` والـ subclasses تبعتها (الـ tool يرميها عشان يوقف الـ run)، و`WorkspaceError` (عملية على الـ workspace رُفضت أو فشلت — الـ model يشوفها كخطأ tool)، و`McpToolError` (أداة MCP محمّلة والسيرفر تبعها رجّع `isError`؛ برضه خطأ tool)، و`AuthError` (مدخل من `lousho/auth` يرفض الطلب بـ 401 أو 403 تبعه)، و`CronExpressionError` (`parseCronExpression()` اللي `defineSchedule()` تغلّفها كـ `LOUSHO_SCHEDULE_INVALID`)، و`DecryptionError` (`EncryptionUtils` و`DTOEncryptionFilter`). -أما `CassetteMismatchError` (replay في `recordReplay`؛ راجع [الاختبار](/ar/testing#ماذا-يفحص-الـ-replay)) فليست منها: هي `SDKError` بكود [`LOUSHO_CASSETTE_INVALID`](#lousho_cassette_invalid) وحقلين `.cassette` / `.callNumber`. +أما `CassetteMismatchError` (replay في `recordReplay`؛ راجع [الاختبار](/ar/testing#ماذا-يفحص-الـ-replay)) فليست منها: هي `SDKError` بكود [`LOUSHO_CASSETTE_INVALID`](#oauth) وحقلين `.cassette` / `.callNumber`. ```ts import { createAgent, SDKError } from 'lousho'; @@ -59,18 +59,18 @@ try { | المجال | الأكواد | متى تصادفها | | ---- | ----- | ------------------ | | [الإعدادات](#الإعدادات) | [`LOUSHO_CONFIG_INVALID`](#lousho_config_invalid)، [`LOUSHO_CONFIG_MISSING_PROVIDER`](#lousho_config_missing_provider)، [`LOUSHO_CONFIG_MISSING_AGENT`](#lousho_config_missing_agent)، [`LOUSHO_CONFIG_MISSING_INPUT`](#lousho_config_missing_input)، [`LOUSHO_CONFIG_CONFLICTING_OPTIONS`](#lousho_config_conflicting_options)، [`LOUSHO_CONFIG_MISSING_CHECKPOINT_STORE`](#lousho_config_missing_checkpoint_store)، [`LOUSHO_CONFIG_RESOLVER_FAILED`](#lousho_config_resolver_failed) | استدعاء `createAgent()` أو executor ناقصه خيارات أو يخلطها، أو config resolver فشل. | -| [الـ providers والـ peer dependencies](#الـ-providers-والـ-peer-dependencies) | [`LOUSHO_PROVIDER_SPEC_INVALID`](#lousho_provider_spec_invalid)، [`LOUSHO_PROVIDER_UNKNOWN`](#lousho_provider_unknown)، [`LOUSHO_PROVIDER_MISSING_API_KEY`](#lousho_provider_missing_api_key)، [`LOUSHO_PROVIDER_REQUEST_FAILED`](#lousho_provider_request_failed)، [`LOUSHO_PROVIDER_RATE_LIMITED`](#lousho_provider_rate_limited)، [`LOUSHO_PEER_MISSING`](#lousho_peer_missing)، [`LOUSHO_HOSTED_TOOL_UNSUPPORTED`](#lousho_hosted_tool_unsupported)، [`LOUSHO_UNSUPPORTED_CONTENT`](#lousho_unsupported_content) | حل نص model، أو API key أو حزمة peer ناقصة، أو طلب model فشل أو رجّع rate limit، أو hosted tool الـ provider ما يقدر يشغّلها، أو ملف الـ provider ما يقدر يرسله. | -| [ملفات الـ AgentSpec](#ملفات-الـ-agentspec) | [`LOUSHO_SPEC_NOT_FOUND`](#lousho_spec_not_found)، [`LOUSHO_SPEC_INVALID`](#lousho_spec_invalid)، [`LOUSHO_SPEC_UNKNOWN_FIELD`](#lousho_spec_unknown_field)، [`LOUSHO_SPEC_UNSUPPORTED_FORMAT`](#lousho_spec_unsupported_format) | تحميل ملف `AgentSpec` بـ `loadSpec()` أو `specToAgent()`. | -| [الأدوات](#الأدوات) | [`LOUSHO_TOOL_NOT_FOUND`](#lousho_tool_not_found)، [`LOUSHO_TOOL_NEEDS_CREDENTIALS`](#lousho_tool_needs_credentials)، [`LOUSHO_TOOL_EXECUTION_FAILED`](#lousho_tool_execution_failed)، [`LOUSHO_TOOL_ARGS_INVALID`](#lousho_tool_args_invalid)، [`LOUSHO_MCP_START_FAILED`](#lousho_mcp_start_failed)، [`LOUSHO_MCP_CALL_FAILED`](#lousho_mcp_call_failed) | tool ناداها الـ model ليست معروفة، أو محتاجة credentials، أو رمت، أو وصلتها arguments غير صالحة؛ أو سيرفر MCP من نوع stdio ما اشتغل أو استدعاء له فشل. | -| [الـ approvals والـ sessions](#الـ-approvals-والـ-sessions) | [`LOUSHO_APPROVAL_STORE_MISSING`](#lousho_approval_store_missing)، [`LOUSHO_APPROVAL_NOT_FOUND`](#lousho_approval_not_found)، [`LOUSHO_APPROVAL_ORPHANED`](#lousho_approval_orphaned)، [`LOUSHO_APPROVAL_CONFLICT`](#lousho_approval_conflict)، [`LOUSHO_APPROVAL_FORBIDDEN`](#lousho_approval_forbidden)، [`LOUSHO_APPROVAL_DECISION_INVALID`](#lousho_approval_decision_invalid)، [`LOUSHO_APPROVAL_KIND_MISMATCH`](#lousho_approval_kind_mismatch)، [`LOUSHO_SESSION_FORBIDDEN`](#lousho_session_forbidden)، [`LOUSHO_SESSION_AWAITING_APPROVAL`](#lousho_session_awaiting_approval)، [`LOUSHO_SESSION_ID_INVALID`](#lousho_session_id_invalid)، [`LOUSHO_SESSION_FILE_CORRUPT`](#lousho_session_file_corrupt)، [`LOUSHO_SESSION_BUSY`](#lousho_session_busy)، [`LOUSHO_SESSION_TURN_PENDING`](#lousho_session_turn_pending)، [`LOUSHO_SESSION_TURN_FAILED`](#lousho_session_turn_failed)، [`LOUSHO_SESSION_STREAM_UNSUPPORTED`](#lousho_session_stream_unsupported)، [`LOUSHO_SESSION_STEP_NOT_FOUND`](#lousho_session_step_not_found)، [`LOUSHO_SESSION_EXISTS`](#lousho_session_exists)، [`LOUSHO_SESSION_FORK_UNSUPPORTED`](#lousho_session_fork_unsupported)، [`LOUSHO_REMOTE_UNAUTHORIZED`](#lousho_remote_unauthorized)، [`LOUSHO_REMOTE_REQUEST_FAILED`](#lousho_remote_request_failed)، [`LOUSHO_SUBAGENT_TASK_NOT_FOUND`](#lousho_subagent_task_not_found)، [`LOUSHO_SUBAGENT_TASK_BUSY`](#lousho_subagent_task_busy)، [`LOUSHO_CHECKPOINT_NOT_FOUND`](#lousho_checkpoint_not_found)، [`LOUSHO_CHECKPOINT_CORRUPT`](#lousho_checkpoint_corrupt)، [`LOUSHO_AGENT_DRIFT`](#lousho_agent_drift)، [`LOUSHO_RESUME_TOOL_MISSING`](#lousho_resume_tool_missing)، [`LOUSHO_RUN_ALREADY_ITERATED`](#lousho_run_already_iterated) | approvals (موافقات) وsessions (جلسات) وcheckpoints (نقاط حفظ) والـ resume، والـ remote agents ومهام الـ sub-agents. | -| [الجداول الزمنية](#الجداول-الزمنية) | [`LOUSHO_SCHEDULE_INVALID`](#lousho_schedule_invalid)، [`LOUSHO_SCHEDULE_RUN_INCOMPLETE`](#lousho_schedule_run_incomplete) | تعريف schedule أو تحميله، أو دورة مجدولة ما خلصت. | -| [القنوات](#القنوات) | [`LOUSHO_CHANNEL_INVALID`](#lousho_channel_invalid)، [`LOUSHO_MEMORY_INVALID`](#lousho_memory_invalid) | تعريف channel أو خانة memory. | -| [السجل](#السجل) | [`LOUSHO_REGISTRY_UNREACHABLE`](#lousho_registry_unreachable)، [`LOUSHO_REGISTRY_ITEM_NOT_FOUND`](#lousho_registry_item_not_found)، [`LOUSHO_REGISTRY_INVALID`](#lousho_registry_invalid)، [`LOUSHO_REGISTRY_UNSAFE_PATH`](#lousho_registry_unsafe_path)، [`LOUSHO_REGISTRY_FILE_EXISTS`](#lousho_registry_file_exists)، [`LOUSHO_REGISTRY_MANIFEST_MISMATCH`](#lousho_registry_manifest_mismatch) | `lousho add` وهو يجلب أو ينسخ من registry. | -| [الـ sandbox](#الـ-sandbox) | [`LOUSHO_SANDBOX_EGRESS_UNSUPPORTED`](#lousho_sandbox_egress_unsupported)، [`LOUSHO_SANDBOX_PATH_DENIED`](#lousho_sandbox_path_denied) | لما تطلب من الـ sandbox شيء يعجز عنه على المنصة الحالية، أو تطلب منه يكتب برّا الـ root تبعه. | -| [مجلدات الـ agents والـ skills والـ flows](#مجلدات-الـ-agents-والـ-skills-والـ-flows) | [`LOUSHO_AGENT_DIR_INVALID`](#lousho_agent_dir_invalid)، [`LOUSHO_SKILL_INVALID`](#lousho_skill_invalid)، [`LOUSHO_FLOW_INVALID`](#lousho_flow_invalid)، [`LOUSHO_FLOW_TOOL_DENIED`](#lousho_flow_tool_denied)، [`LOUSHO_FLOW_CHANGED`](#lousho_flow_changed) | تحميل مجلد agent، أو skill، أو تعريف flow، والتحكّم باستدعاءات الـ tools في الـ flow. | -| [الـ storage والنشر والتكاملات](#الـ-storage-والنشر-والتكاملات) | [`LOUSHO_STORAGE_FAILED`](#lousho_storage_failed)، [`LOUSHO_STORAGE_BUSY`](#lousho_storage_busy)، [`LOUSHO_TRIGGER_INVALID`](#lousho_trigger_invalid)، [`LOUSHO_CHANNEL_REQUEST_FAILED`](#lousho_channel_request_failed)، [`LOUSHO_DEPLOY_FAILED`](#lousho_deploy_failed) | واجهة storage، أو trigger، أو طلب channel، أو `lousho build`. | -| [الاختبارات والـ evals](#الاختبارات-والـ-evals) | [`LOUSHO_EVALS_INVALID`](#lousho_evals_invalid)، [`LOUSHO_TEST_FAILED`](#lousho_test_failed)، [`LOUSHO_CASSETTE_INVALID`](#lousho_cassette_invalid) | `defineEval()` و`mockModel` والـ cassettes. | -| [عام](#عام) | [`LOUSHO_GENERIC_ERROR`](#lousho_generic_error)، [`LOUSHO_AGENT_EXECUTION_FAILED`](#lousho_agent_execution_failed)، [`LOUSHO_FLOW_EXECUTION_FAILED`](#lousho_flow_execution_failed)، [`LOUSHO_VALIDATION_FAILED`](#lousho_validation_failed)، [`LOUSHO_OPERATION_TIMEOUT`](#lousho_operation_timeout)، [`LOUSHO_OUTPUT_INVALID`](#lousho_output_invalid)، [`LOUSHO_BUDGET_EXCEEDED`](#lousho_budget_exceeded)، [`LOUSHO_GUARDRAIL_TRIPPED`](#lousho_guardrail_tripped) | فشل على مستوى الـ run: timeout، أو وقف بسبب budget أو guardrail، أو output غير صالح، والأكواد العامة. | +| [الـ providers والـ peer dependencies](#الـ-providers-والـ-peer-dependencies) | [`LOUSHO_PROVIDER_SPEC_INVALID`](#lousho_provider_unknown)، [`LOUSHO_PROVIDER_UNKNOWN`](#lousho_provider_missing_api_key)، [`LOUSHO_PROVIDER_MISSING_API_KEY`](#lousho_provider_request_failed)، [`LOUSHO_PROVIDER_REQUEST_FAILED`](#lousho_provider_rate_limited)، [`LOUSHO_PROVIDER_RATE_LIMITED`](#lousho_peer_missing)، [`LOUSHO_PEER_MISSING`](#lousho_hosted_tool_unsupported)، [`LOUSHO_HOSTED_TOOL_UNSUPPORTED`](#lousho_unsupported_content)، [`LOUSHO_UNSUPPORTED_CONTENT`](#ملفات-الـ-agentspec) | حل نص model، أو API key أو حزمة peer ناقصة، أو طلب model فشل أو رجّع rate limit، أو hosted tool الـ provider ما يقدر يشغّلها، أو ملف الـ provider ما يقدر يرسله. | +| [ملفات الـ AgentSpec](#ملفات-الـ-agentspec) | [`LOUSHO_SPEC_NOT_FOUND`](#lousho_spec_invalid)، [`LOUSHO_SPEC_INVALID`](#lousho_spec_unknown_field)، [`LOUSHO_SPEC_UNKNOWN_FIELD`](#lousho_spec_unsupported_format)، [`LOUSHO_SPEC_UNSUPPORTED_FORMAT`](#الأدوات) | تحميل ملف `AgentSpec` بـ `loadSpec()` أو `specToAgent()`. | +| [الأدوات](#الأدوات) | [`LOUSHO_TOOL_NOT_FOUND`](#lousho_tool_args_invalid)، [`LOUSHO_TOOL_NEEDS_CREDENTIALS`](#lousho_mcp_start_failed)، [`LOUSHO_TOOL_EXECUTION_FAILED`](#lousho_mcp_call_failed)، [`LOUSHO_TOOL_ARGS_INVALID`](#الـ-approvals-والـ-sessions)، [`LOUSHO_MCP_START_FAILED`](#lousho_approval_store_missing)، [`LOUSHO_MCP_CALL_FAILED`](#lousho_approval_not_found) | tool ناداها الـ model ليست معروفة، أو محتاجة credentials، أو رمت، أو وصلتها arguments غير صالحة؛ أو سيرفر MCP من نوع stdio ما اشتغل أو استدعاء له فشل. | +| [الـ approvals والـ sessions](#الـ-approvals-والـ-sessions) | [`LOUSHO_APPROVAL_STORE_MISSING`](#lousho_approval_conflict)، [`LOUSHO_APPROVAL_NOT_FOUND`](#lousho_approval_forbidden)، [`LOUSHO_APPROVAL_ORPHANED`](#lousho_approval_decision_invalid)، [`LOUSHO_APPROVAL_CONFLICT`](#lousho_approval_kind_mismatch)، [`LOUSHO_APPROVAL_FORBIDDEN`](#lousho_session_forbidden)، [`LOUSHO_APPROVAL_DECISION_INVALID`](#lousho_request_forbidden)، [`LOUSHO_APPROVAL_KIND_MISMATCH`](#lousho_request_invalid)، [`LOUSHO_SESSION_FORBIDDEN`](#lousho_session_awaiting_approval)، [`LOUSHO_SESSION_AWAITING_APPROVAL`](#lousho_session_turn_pending)، [`LOUSHO_SESSION_ID_INVALID`](#lousho_session_turn_failed)، [`LOUSHO_SESSION_FILE_CORRUPT`](#lousho_session_stream_unsupported)، [`LOUSHO_SESSION_BUSY`](#lousho_session_step_not_found)، [`LOUSHO_SESSION_TURN_PENDING`](#lousho_session_exists)، [`LOUSHO_SESSION_TURN_FAILED`](#lousho_session_fork_unsupported)، [`LOUSHO_SESSION_STREAM_UNSUPPORTED`](#lousho_remote_unauthorized)، [`LOUSHO_SESSION_STEP_NOT_FOUND`](#lousho_remote_request_failed)، [`LOUSHO_SESSION_EXISTS`](#lousho_subagent_task_not_found)، [`LOUSHO_SESSION_FORK_UNSUPPORTED`](#lousho_subagent_task_busy)، [`LOUSHO_REMOTE_UNAUTHORIZED`](#lousho_checkpoint_not_found)، [`LOUSHO_REMOTE_REQUEST_FAILED`](#lousho_checkpoint_corrupt)، [`LOUSHO_SUBAGENT_TASK_NOT_FOUND`](#lousho_agent_drift)، [`LOUSHO_SUBAGENT_TASK_BUSY`](#lousho_resume_tool_missing)، [`LOUSHO_CHECKPOINT_NOT_FOUND`](#lousho_run_already_iterated)، [`LOUSHO_CHECKPOINT_CORRUPT`](#الجداول-الزمنية)، [`LOUSHO_AGENT_DRIFT`](#lousho_schedule_invalid)، [`LOUSHO_RESUME_TOOL_MISSING`](#lousho_schedule_run_incomplete)، [`LOUSHO_RUN_ALREADY_ITERATED`](#القنوات) | approvals (موافقات) وsessions (جلسات) وcheckpoints (نقاط حفظ) والـ resume، والـ remote agents ومهام الـ sub-agents. | +| [الجداول الزمنية](#الجداول-الزمنية) | [`LOUSHO_SCHEDULE_INVALID`](#السجل)، [`LOUSHO_SCHEDULE_RUN_INCOMPLETE`](#lousho_registry_unreachable) | تعريف schedule أو تحميله، أو دورة مجدولة ما خلصت. | +| [القنوات](#القنوات) | [`LOUSHO_CHANNEL_INVALID`](#lousho_registry_invalid)، [`LOUSHO_MEMORY_INVALID`](#lousho_registry_unsafe_path) | تعريف channel أو خانة memory. | +| [السجل](#السجل) | [`LOUSHO_REGISTRY_UNREACHABLE`](#lousho_registry_manifest_mismatch)، [`LOUSHO_REGISTRY_ITEM_NOT_FOUND`](#الـ-sandbox)، [`LOUSHO_REGISTRY_INVALID`](#lousho_sandbox_egress_unsupported)، [`LOUSHO_REGISTRY_UNSAFE_PATH`](#lousho_sandbox_path_denied)، [`LOUSHO_REGISTRY_FILE_EXISTS`](#مجلدات-الـ-agents-والـ-skills-والـ-flows)، [`LOUSHO_REGISTRY_MANIFEST_MISMATCH`](#lousho_agent_dir_invalid) | `lousho add` وهو يجلب أو ينسخ من registry. | +| [الـ sandbox](#الـ-sandbox) | [`LOUSHO_SANDBOX_EGRESS_UNSUPPORTED`](#lousho_flow_invalid)، [`LOUSHO_SANDBOX_PATH_DENIED`](#lousho_flow_tool_denied) | لما تطلب من الـ sandbox شيء يعجز عنه على المنصة الحالية، أو تطلب منه يكتب برّا الـ root تبعه. | +| [مجلدات الـ agents والـ skills والـ flows](#مجلدات-الـ-agents-والـ-skills-والـ-flows) | [`LOUSHO_AGENT_DIR_INVALID`](#lousho_storage_failed)، [`LOUSHO_SKILL_INVALID`](#lousho_storage_busy)، [`LOUSHO_FLOW_INVALID`](#lousho_trigger_invalid)، [`LOUSHO_FLOW_TOOL_DENIED`](#lousho_channel_request_failed)، [`LOUSHO_FLOW_CHANGED`](#lousho_deploy_failed) | تحميل مجلد agent، أو skill، أو تعريف flow، والتحكّم باستدعاءات الـ tools في الـ flow. | +| [الـ storage والنشر والتكاملات](#الـ-storage-والنشر-والتكاملات) | [`LOUSHO_STORAGE_FAILED`](#lousho_evals_invalid)، [`LOUSHO_STORAGE_BUSY`](#lousho_test_failed)، [`LOUSHO_TRIGGER_INVALID`](#lousho_flow_execution_failed)، [`LOUSHO_CHANNEL_REQUEST_FAILED`](#lousho_validation_failed)، [`LOUSHO_DEPLOY_FAILED`](#lousho_operation_timeout) | واجهة storage، أو trigger، أو طلب channel، أو `lousho build`. | +| [الاختبارات والـ evals](#الاختبارات-والـ-evals) | [`LOUSHO_EVALS_INVALID`](#lousho_guardrail_tripped)، [`LOUSHO_TEST_FAILED`](#lousho_auth_config_invalid)، [`LOUSHO_CASSETTE_INVALID`](#oauth) | `defineEval()` و`mockModel` والـ cassettes. | +| [عام](#عام) | [`LOUSHO_GENERIC_ERROR`](#lousho_token_decrypt_failed)، [`LOUSHO_AGENT_EXECUTION_FAILED`](#lousho_oauth_principal_required)، [`LOUSHO_FLOW_EXECUTION_FAILED`](#lousho_oauth_app_signin_required)، [`LOUSHO_VALIDATION_FAILED`](#lousho_oauth_store_missing)، [`LOUSHO_OPERATION_TIMEOUT`](#lousho_oauth_state_invalid)، [`LOUSHO_OUTPUT_INVALID`](#lousho_signin_pending)، [`LOUSHO_BUDGET_EXCEEDED`](#lousho_oauth_token_exchange_failed)، [`LOUSHO_GUARDRAIL_TRIPPED`](#lousho_mcp_auth_required) | فشل على مستوى الـ run: timeout، أو وقف بسبب budget أو guardrail، أو output غير صالح، والأكواد العامة. | | [المصادقة](#المصادقة) | [`LOUSHO_AUTH_CONFIG_INVALID`](#lousho_auth_config_invalid) | مساعد route auth (`jwt()` أو `oidc()` أو `basic()` أو `apiToken()`) أخذ خيارات ما يقدر يتحقق فيها. | | [OAuth](#oauth) | [`LOUSHO_TOKEN_KEY_MISSING`](#lousho_token_key_missing)، [`LOUSHO_TOKEN_DECRYPT_FAILED`](#lousho_token_decrypt_failed)، [`LOUSHO_OAUTH_PRINCIPAL_REQUIRED`](#lousho_oauth_principal_required)، [`LOUSHO_OAUTH_APP_SIGNIN_REQUIRED`](#lousho_oauth_app_signin_required)، [`LOUSHO_OAUTH_STORE_MISSING`](#lousho_oauth_store_missing)، [`LOUSHO_OAUTH_STATE_INVALID`](#lousho_oauth_state_invalid)، [`LOUSHO_SIGNIN_PENDING`](#lousho_signin_pending)، [`LOUSHO_OAUTH_TOKEN_EXCHANGE_FAILED`](#lousho_oauth_token_exchange_failed)، [`LOUSHO_MCP_AUTH_REQUIRED`](#lousho_mcp_auth_required) | تخزين أو قراءة OAuth tokens في ملف أو SQLite أو KV store، والـ sign-in وتبديل الـ tokens لأدوات OAuth وسيرفرات MCP. | @@ -160,7 +160,7 @@ try { ### LOUSHO_PROVIDER_REQUEST_FAILED -**المعنى:** استدعاء model فشل (`LLMProviderError`، وكذلك `CompactedLLMProviderError` اللي `compacted.category` تبعه تشرح السبب: `timeout` أو `context-length-exceeded` أو `quota-exceeded` أو `auth-failure` أو `unknown`؛ أما فشل `rate-limit` فله كود خاص فيه، [`LOUSHO_PROVIDER_RATE_LIMITED`](#lousho_provider_rate_limited)). +**المعنى:** استدعاء model فشل (`LLMProviderError`، وكذلك `CompactedLLMProviderError` اللي `compacted.category` تبعه تشرح السبب: `timeout` أو `context-length-exceeded` أو `quota-exceeded` أو `auth-failure` أو `unknown`؛ أما فشل `rate-limit` فله كود خاص فيه، [`LOUSHO_PROVIDER_RATE_LIMITED`](#lousho_peer_missing)). الرد المتوافق مع OpenAI اللي يبلّغ عن فشل داخل 200 (`finish_reason: "error"` من OpenRouter، أو chunk فيه `error` في نص الـ stream) يفشل كـ 502 قابل لإعادة المحاولة بدل ما يرجّع النص المقطوع. تجاوز السياق يكون `context-length-exceeded` (غير قابل لإعادة المحاولة) مهما كانت الـ status، ومنه "exceeds the available context size" و"Context size has been exceeded" من llama.cpp / LM Studio، وسواء وصل من الطلب أو كخطأ في الـ stream. فشل الاتصال يكون `timeout` ويسمّي السبب، مثلاً `connection refused (ECONNREFUSED) at http://localhost:1234/v1/responses - is the server running?`. وإذا ما انقرى body الخطأ من الـ provider (والرسالة بس `Bad Request`)، ينضاف مقطع قصير من الـ body. diff --git a/ar/evals.mdx b/ar/evals.mdx index 12ec233..eadd982 100644 --- a/ar/evals.mdx +++ b/ar/evals.mdx @@ -26,7 +26,7 @@ npx lousho eval الرسائل بـ `t.send()`، وبعدها اعمل assert على الـ run. لو خلّيت `mockModel` هو الـ provider الخاص بالـ agent، يصير الـ eval deterministic: لا شبكة، لا API key، لا flakiness. **هذه هي الطريقة الافتراضية لكتابة eval**؛ استخدم model حقيقي -فقط في [judge evals](#judge-evals) بالأسفل. +فقط في [judge evals](#lousho-eval) بالأسفل. ```ts // refund.eval.ts @@ -85,7 +85,7 @@ defineEval({ | `t.maxCostUsd(n, { unknownCost? })` | gate | تكلفة الـ run المُبلَّغ عنها `n` دولار كحد أقصى. لو الـ SDK ما بلّغ عن تكلفة (الـ model ما له سعر معروف؛ شوف `registerModel`) تفشل الـ gate، لأن الميزانية ما يمكن التحقق منها؛ ومع `unknownCost: 'skip'` تتخطّاها بدل ذلك (تنحسب ناجحة، بعلامة `skipped`، مع `console.warn`) | | `t.check(name, value, check)` | gate | الـ `check` ينجح على `value` | | `t.soft(name, value, check)` | soft | ما تفشل الـ run أبدًا (إلا مع `--strict`)؛ الدرجة تتسجّل وتظهر في التقرير | -| `await t.judge(rubric)` | n/a | ترجع درجة من 0 إلى 1 من judge هو LLM (شوف [Judge evals](#judge-evals)) | +| `await t.judge(rubric)` | n/a | ترجع درجة من 0 إلى 1 من judge هو LLM (شوف [Judge evals](#lousho-eval)) | الـ checks المتاحة لـ `t.check()` و`t.soft()`: `includes(text)` و`matches(regex)` و`equals(value)` (نعم/لا، درجة 1 أو 0)، و`atLeast(n)` و`atMost(n)` @@ -260,7 +260,7 @@ lousho eval [globs...] [--tag t] [--junit path] [--json path] [--strict] [--judg | `--url base` | يشغّل كل case على الـ agent المنشور عند `base` بدل داخل العملية؛ `--token` (أو `LOUSHO_EVAL_TOKEN`) هو الـ bearer token. شوف [تشغيل evals على deployment](#تشغيل-evals-على-deployment) | | `--config path` | يستخدم vitest config الخاص بك بدل المولَّد | | `--timeout ms` | حد الوقت لكل case بالملي ثانية (`0` = بلا حد)؛ شوف [حدود الوقت](#حدود-الوقت) | -| `--record` | يشغّل على الـ provider الحقيقي ويكتب cassette (ملف تسجيل) واحد لكل case ([بالأسفل](#record-replay-and-drift)) | +| `--record` | يشغّل على الـ provider الحقيقي ويكتب cassette (ملف تسجيل) واحد لكل case ([بالأسفل](#تشغيل-evals-على-deployment)) | | `--replay` | يشغّل كل case من الـ cassette الخاص بها، بدون شبكة؛ cassette مفقودة تفشل الـ case | | `--drift` | يعيد التسجيل في مجلد مؤقت ويبلّغ كيف تغيّرت trajectory كل case (`--drift-usage` يقارن الـ tokens أيضًا) | @@ -359,7 +359,7 @@ jobs: | `LOUSHO_EVAL_DRIFT_DIR` | `--drift` | مع `record`: المكان الذي يكتب فيه run الـ drift الـ cassettes بدل جنب ملف الـ eval. | | `LOUSHO_EVAL_CONFIG` | `--config` | مسار الـ config، حتى تكرّره تلميحات إعادة التسجيل. | | `LOUSHO_EVAL_TAGS` | `--tag` | tags مفصولة بفواصل؛ ما يشتغل إلا الـ cases التي فيها واحد منها. | -| `LOUSHO_EVAL_RESULTS` | دائمًا | الملف الذي تضيف له كل case سطر نتيجتها، والذي يرجع `lousho eval` يقراه (شوف [`lousho eval`](#lousho-eval)). | +| `LOUSHO_EVAL_RESULTS` | دائمًا | الملف الذي تضيف له كل case سطر نتيجتها، والذي يرجع `lousho eval` يقراه (شوف [`lousho eval`](#حدود-الوقت)). | | `LOUSHO_EVAL_URL` | `--url` | الـ base URL للـ agent المنشور الذي تشتغل عليه الـ cases. | | `LOUSHO_EVAL_TOKEN` | `--token` | الـ bearer token لـ `--url`. | | `LOUSHO_ALLOW_LLM_JUDGE` | `--judge` | يُضبط على `1` داخل runner الـ judge. بدونه، `llmJudge()` / `llmCritique()` لو انستدعت خارج ذلك الـ runner ترمي `LOUSHO_EVALS_INVALID`، حتى judge eval في غير مكانه ما يعمل أبدًا call مدفوع لـ model في test run عادي. | diff --git a/ar/flows.mdx b/ar/flows.mdx index 882839f..31dd7ea 100644 --- a/ar/flows.mdx +++ b/ar/flows.mdx @@ -269,7 +269,7 @@ const result = await FlowExecutor.execute(flow, { agent: { name: 'report' }, pro استخدم flow إذا كان الـpipeline معروفاً مسبقاً. استخدم [sub-agents](/ar/sub-agents) لما تريد الـmodel نفسه أن يقرر ما يفوّضه، و[skills](/ar/skills) لما يحتاج نفس الـagent تعليمات إضافية لبعض المهام فقط. راجع [sub-agent أم skill أم flow؟](/ar/sub-agents#sub-agent-ولا-skill-ولا-flow؟). -الـtracing يغطي الـflows مثل أي run للـagent (راجع [Tracing والـobservability](/ar/observability#flows)). +الـtracing يغطي الـflows مثل أي run للـagent (راجع [Tracing والـobservability](/ar/observability#الأخطاء)). ## تعبيرات الـflow diff --git a/ar/forge-author.mdx b/ar/forge-author.mdx new file mode 100644 index 0000000..db7de94 --- /dev/null +++ b/ar/forge-author.mdx @@ -0,0 +1,8 @@ +--- +title: "The Agent Author" +--- + +{/* pending-translation */} + +هذه الصفحة لم تُترجَم إلى العربية بعد. اقرأ [النسخة الإنجليزية](/forge-author). + diff --git a/ar/forge-builder.mdx b/ar/forge-builder.mdx new file mode 100644 index 0000000..21124e6 --- /dev/null +++ b/ar/forge-builder.mdx @@ -0,0 +1,8 @@ +--- +title: "The visual builder" +--- + +{/* pending-translation */} + +هذه الصفحة لم تُترجَم إلى العربية بعد. اقرأ [النسخة الإنجليزية](/forge-builder). + diff --git a/ar/forge-lifecycle.mdx b/ar/forge-lifecycle.mdx new file mode 100644 index 0000000..86a874c --- /dev/null +++ b/ar/forge-lifecycle.mdx @@ -0,0 +1,8 @@ +--- +title: "Versions, triggers and publishing" +--- + +{/* pending-translation */} + +هذه الصفحة لم تُترجَم إلى العربية بعد. اقرأ [النسخة الإنجليزية](/forge-lifecycle). + diff --git a/ar/hosted-tools.mdx b/ar/hosted-tools.mdx index 97b78ce..4f6bcbb 100644 --- a/ar/hosted-tools.mdx +++ b/ar/hosted-tools.mdx @@ -56,7 +56,7 @@ console.log(result.text, result.usage.hostedToolCalls); // { web_search: 1 } في OpenRouter، `webSearch()` تضيف الـ server tool الخاصة بـ OpenRouter، وهي `openrouter:web_search`، إلى الطلب. البحث يصير على جهة OpenRouter لأي model. OpenRouter هو من يختار محرك البحث: بحث الـ model نفسه إن كان عنده، وإلا Exa. ويحاسبك على كل بحث فوق الـ tokens بالأسعار الموجودة في [صفحة أسعار OpenRouter](https://openrouter.ai/pricing). راجع [دليل web search](https://openrouter.ai/docs/guides/features/server-tools/web-search) لتفاصيل المحركات. ولأن السيرفر ينفّذ البحث داخل الطلب، الـ model لا يبلّغ عن أي tool call. بدلها يبلّغ الـ SDK عن hosted call واحدة لكل model step بحث فيها، ويقرأها من ردّ OpenRouter: `name: 'web_search'`، و`args` فارغة، والروابط المستشهد بها من `url_citation` annotations تصير `sources`، و`result: { requests }` إذا بلّغ OpenRouter عن `usage.server_tool_use.web_search_requests` (وإلا `result` تكون `{}`؛ الاختبار الحي ما استلم عددًا). الاستعلام الذي بحث عنه الـ model لا يُبلَّغ عنه. -أي توليفة غير مدعومة ترفض الـ run قبل أول model call بخطأ [`LOUSHO_HOSTED_TOOL_UNSUPPORTED`](/ar/errors#lousho_hosted_tool_unsupported) يذكر الـ provider والـ tool وما الذي سيشتغل. +أي توليفة غير مدعومة ترفض الـ run قبل أول model call بخطأ [`LOUSHO_HOSTED_TOOL_UNSUPPORTED`](/ar/errors#lousho_unsupported_content) يذكر الـ provider والـ tool وما الذي سيشتغل. الـ `LLMProvider` المخصّص يعلن عمّا يقدر يرسله عبر `supportsHostedTool(type)` — قيمة `type` هي `'web_search'` أو `'code_interpreter'` أو `'file_search'` أو `'custom'` لـ `hostedTool()` — ويستلم الـ tools في `GenerateOptions.hostedTools`. الـ provider الذي لا يملك هذه الدالة ما يدعم أي hosted tool. و`withRetry()` و`withFallback()` تسألان الـ provider المغلَّف (الأول). diff --git a/ar/mcp-integration.mdx b/ar/mcp-integration.mdx index 046f0b2..6157a94 100644 --- a/ar/mcp-integration.mdx +++ b/ar/mcp-integration.mdx @@ -49,9 +49,9 @@ await agent.close(); أي متغير آخر يحتاجه السيرفر (API key، أو `NODE_ENV`، أو إعداد proxy) لا يُورَّث إلا إذا ذكرته: `env: { GITHUB_TOKEN: process.env.GITHUB_TOKEN }`. الـ tool call الفاشل (السيرفر خرج، أو انتهت مهلته، أو ردّ بخطأ في البروتوكول) -يُرفض بـ[`LOUSHO_MCP_CALL_FAILED`](/ar/errors#lousho_mcp_call_failed) مع ذكر +يُرفض بـ[`LOUSHO_MCP_CALL_FAILED`](/ar/errors#lousho_approval_not_found) مع ذكر `__`. والسيرفر الذي لا يبدأ يفشل بـ -[`LOUSHO_MCP_START_FAILED`](/ar/errors#lousho_mcp_start_failed)، ورسالته +[`LOUSHO_MCP_START_FAILED`](/ar/errors#lousho_approval_store_missing)، ورسالته فيها exit code وآخر الأسطر التي كتبتها العملية على stderr. `stderr: 'forward'` (الافتراضي) ينسخ أيضًا stderr العملية إلى stderr العملية الحالية، و`'capture'` يحتفظ بآخر الأسطر فقط، و`'inherit'` / `'ignore'` لا يحتفظان بشيء. diff --git a/ar/observability.mdx b/ar/observability.mdx index 193b9c7..6d7be5a 100644 --- a/ar/observability.mdx +++ b/ar/observability.mdx @@ -285,7 +285,7 @@ invoke_agent weather |████████████████ `startTime` و`endTime` بالـ milliseconds منذ الـ epoch؛ `attributes` هي سمات الـ span المذكورة فوق، كاملة بدون اختصار. الـ span الذي لم ينتهِ أبدا (العملية ماتت) لا يوجد في الملف. إذا تعذّرت الكتابة في المجلد، الـ exporter يحذّر مرة واحدة والـ run يكمل. `listTraces({ dir, limit })` و`readTrace(idOrPrefix, { dir })` تقرأ الملفات من الكود. -الملفات تحمل ما تحمله الـ spans. افتراضيا هذا يعني لا محتوى رسائل ولا tools: الـ attributes الـ deprecated `input` و`prompt` و`args` و`result` تُسجَّل فقط مع `redactContent: false` (شوف [Deprecated attribute names](#deprecated-attribute-names))، و`captureContent: true` يضيف محتوى `gen_ai.*`. خلّي `.lousho/` خارج الـ version control؛ المشاريع التي ينشئها `lousho init` تتجاهله. +الملفات تحمل ما تحمله الـ spans. افتراضيا هذا يعني لا محتوى رسائل ولا tools: الـ attributes الـ deprecated `input` و`prompt` و`args` و`result` تُسجَّل فقط مع `redactContent: false` (شوف [Deprecated attribute names](#backends))، و`captureContent: true` يضيف محتوى `gen_ai.*`. خلّي `.lousho/` خارج الـ version control؛ المشاريع التي ينشئها `lousho init` تتجاهله. `lousho dev` و`lousho chat` يكتبان هذه الملفات لما تمرّر `--traces` (إلى `.lousho/traces`) أو `--traces=`، سواء لملف spec أو مجلد agent أو module. يعني agent مبني من ملف spec تقدر تتتبّعه بدون أي كود. وهي opt-in عن قصد: الملفات تحفظ توقيتات الـ spans وأعداد الـ tokens والتكاليف، ومحتوى الـ prompt والـ tools فقط إذا ضبط الـ agent `redactContent: false` أو `captureContent: true`، فلا يُكتب شيء على القرص إلا إذا طلبت. تنسيق ملف الـ spec ليس فيه إعداد للـ traces. diff --git a/ar/pause-and-resume.mdx b/ar/pause-and-resume.mdx new file mode 100644 index 0000000..261c117 --- /dev/null +++ b/ar/pause-and-resume.mdx @@ -0,0 +1,8 @@ +--- +title: "Pause, restart, resume" +--- + +{/* pending-translation */} + +هذه الصفحة لم تُترجَم إلى العربية بعد. اقرأ [النسخة الإنجليزية](/pause-and-resume). + diff --git a/ar/pending.json b/ar/pending.json index 499c6f1..0ab767b 100644 --- a/ar/pending.json +++ b/ar/pending.json @@ -1,3 +1,6 @@ [ - "pause-and-resume" + "pause-and-resume", + "forge-builder", + "forge-author", + "forge-lifecycle" ] diff --git a/ar/providers.mdx b/ar/providers.mdx index 2767b2d..fc38396 100644 --- a/ar/providers.mdx +++ b/ar/providers.mdx @@ -37,7 +37,7 @@ const custom = LLMProviderRegistry.create('openai', { ### Vendors بدون بادئة البادئة اللي الـ SDK ما يعرفها تفشل بـ -[`LOUSHO_PROVIDER_UNKNOWN`](/ar/errors#lousho_provider_unknown). الخطأ القريب +[`LOUSHO_PROVIDER_UNKNOWN`](/ar/errors#lousho_provider_missing_api_key). الخطأ القريب (`anthopic/...`) ياخذ اقتراح "did you mean"؛ وأي vendor آخر تطلع له الطرق اللي توصل له فيها مع ذلك: @@ -178,7 +178,7 @@ console.log(textOf(messages[0]), '->', result.text); | `pi` | ولا نوع (دائمًا ملاحظة نصية) | ولا نوع (دائمًا ملاحظة نصية؛ pi ما عنده file part) | أي file part آخر يرفض الـ call بـ - [`LOUSHO_UNSUPPORTED_CONTENT`](/ar/errors#lousho_unsupported_content) + [`LOUSHO_UNSUPPORTED_CONTENT`](/ar/errors#ملفات-الـ-agentspec) قبل ما يترسل أي شيء، فالـ model ما يجاوب أبدًا بدون الملف (وتحت `withFallback()` الـ call تروح للـ provider التالي). ولو تبي ملاحظة نصية مكانه بدل كذا (`[file report.pdf (application/pdf) not sent]`، مع تحذير diff --git a/ar/schedules.mdx b/ar/schedules.mdx index 0b6b827..11a652c 100644 --- a/ar/schedules.mdx +++ b/ar/schedules.mdx @@ -28,7 +28,7 @@ const running = startSchedules(agent, [morning, cleanup]); await running.stop(); ``` -- `cron`: خمسة حقول (`minute hour day-of-month month day-of-week`) أو `@hourly` أو `@daily` أو `@weekly` أو `@monthly`، ويُحسَب في `timezone` (اسم IANA، والافتراضي منطقة الجهاز الزمنية). إذا كان التعبير غير صالح، أو حدّدت `prompt` و`run` معًا، أو ما حدّدت أي واحد منهما، `defineSchedule()` يرمي `LOUSHO_SCHEDULE_INVALID` مباشرة — لا عند أول firing. راجع [الأخطاء](/ar/errors#lousho_schedule_invalid). +- `cron`: خمسة حقول (`minute hour day-of-month month day-of-week`) أو `@hourly` أو `@daily` أو `@weekly` أو `@monthly`، ويُحسَب في `timezone` (اسم IANA، والافتراضي منطقة الجهاز الزمنية). إذا كان التعبير غير صالح، أو حدّدت `prompt` و`run` معًا، أو ما حدّدت أي واحد منهما، `defineSchedule()` يرمي `LOUSHO_SCHEDULE_INVALID` مباشرة — لا عند أول firing. راجع [الأخطاء](/ar/errors#السجل). - `run` تستقبل `{ agent, firedAt, name }`. `startSchedules(agent, schedules, { now?, setTimer?, onError?, keepAlive? })` يحتفظ بمؤقّت واحد لكل schedule. أي run يرمي خطأ يروح إلى `onError` (الافتراضي: `console.error`) ولا يوقّف باقي الـ schedules أبدًا. والـ turn الخاص بـ prompt schedule إذا انتهى بأي `finishReason` غير `'stop'` يُعتبَر run فاشلًا أيضًا: `onError` يستقبل خطأ `LOUSHO_SCHEDULE_RUN_INCOMPLETE` يذكر السبب، مثلًا `'awaiting-approval'` (مع id الـ approval المعلّقة، وتبقى معلّقة إلى أن تحسمها بـ `agent.approvals.resolve()`)، أو `'output-invalid'` أو `'max-steps'`. الـ schedule لا يتداخل مع نفسه: لو الـ firing السابق ما زال شغّالًا، يُتخطّى الإطلاق التالي ويُبلَّغ به `onError`. والـ fires التي فاتت أثناء تعليق العملية تُتخطّى بدل إعادة تشغيلها. `now` و`setTimer` قابلان للحقن حتى لا تنام الاختبارات أبدًا. diff --git a/ar/sessions.mdx b/ar/sessions.mdx index 5d6bb08..3020610 100644 --- a/ar/sessions.mdx +++ b/ar/sessions.mdx @@ -441,7 +441,7 @@ store.close(); أما الـ approvals اللي لسه ما اتحسمت وOAuth tokens فبيفضلوا، وكمان الـ turn المتوقفة على approval لسه ما اتحسمت (الـ checkpoint بتاعتها وسجل محادثة الـ session)، مهما كانت قديمة. وتقرير approval الـ turn المتوقفة بتاعتها اتمسحت على أي حال - بيفشل بـ [`LOUSHO_APPROVAL_ORPHANED`](/ar/errors#lousho_approval_orphaned) + بيفشل بـ [`LOUSHO_APPROVAL_ORPHANED`](/ar/errors#lousho_approval_decision_invalid) من غير ما يشغّل الـ tool. - ملف مش database بتاع SQLite بيفشل بـ error بيذكر المسار؛ واستخدام الـ store بعد `close()` بيرمي error واضح. @@ -509,7 +509,7 @@ console.log(fork.id, reply.text); // 'trip-fork-1', 'Porto has a direct flight a - `fork({ fromStep })` بيمسك السجل لحد آخر رسالة tool في الخطوة ومعاها؛ و`fromStep: 0` ما بيمسك حاجة. وخطوة برا `0..history().length` بتترفض بـ - [`LOUSHO_SESSION_STEP_NOT_FOUND`](/ar/errors#lousho_session_step_not_found)، + [`LOUSHO_SESSION_STEP_NOT_FOUND`](/ar/errors#lousho_remote_request_failed)، ورسالته بتسرد النطاق الصحيح. - `patch: { toolResult: { toolCallId, result } }` بيبدّل نتيجة tool call واحدة في السجل المحتفَظ فيه ("ماذا لو البحث ما كان لقى ولا حاجة؟")، @@ -523,7 +523,7 @@ console.log(fork.id, reply.text); // 'trip-fork-1', 'Porto has a direct flight a طويل زيادة على اللاحقة دي، `-<8 hex of its hash>-fork-`، ويفضل في حدود 128 حرف). و`id` إله سجل محادثة أصلًا (أو نفس id الـ session) بيترفض بـ - [`LOUSHO_SESSION_EXISTS`](/ar/errors#lousho_session_exists). + [`LOUSHO_SESSION_EXISTS`](/ar/errors#lousho_subagent_task_not_found). - الـ `messages` بتاعة الـ fork بتمسك سجل محادثته أول ما `fork()` يرجع. - سجل محادثة الـ session الأصلية وcheckpoints بتاعتها ما بيتغيروا. - الـ budgets: الـ spend المسجَّل لـ `limits` بيفضل على الرسائل المحتفَظ فيها، فـ diff --git a/ar/testing.mdx b/ar/testing.mdx index 761412f..724e2dc 100644 --- a/ar/testing.mdx +++ b/ar/testing.mdx @@ -163,7 +163,7 @@ const agent = createAgent({ provider, instructions: 'You handle refund requests. ‏`mode: 'auto'` يسوّي replay إذا ملف الـ cassette موجود، ويسجّل في الحالة الثانية. -في evals معرّفة بـ `defineEval()` ما تحتاج تغلّف الـ provider بنفسك: `lousho eval --record` يكتب cassette لكل eval case، و`--replay` يشغّل منها، و`--drift` يبيّن كيف تغيّر مسار كل case. شوف [التسجيل وإعادة التشغيل والـ drift](/ar/evals#record-replay-and-drift). +في evals معرّفة بـ `defineEval()` ما تحتاج تغلّف الـ provider بنفسك: `lousho eval --record` يكتب cassette لكل eval case، و`--replay` يشغّل منها، و`--drift` يبيّن كيف تغيّر مسار كل case. شوف [التسجيل وإعادة التشغيل والـ drift](/ar/evals#تشغيل-evals-على-deployment). ### ماذا يفحص الـ replay diff --git a/ar/triggers.mdx b/ar/triggers.mdx index cfbf43a..92f2f6f 100644 --- a/ar/triggers.mdx +++ b/ar/triggers.mdx @@ -91,7 +91,7 @@ webhookChannel({ ## تواقيع طلبات Slack -`slackChannel()` يتحقق من كل طلب نيابةً عنك (راجع [Slack في Channels](/ar/channels#slack)). أما في الـhandler الخاص بك (slash commands والتفاعلات)، فتحقّق من الـbody الخام بـ`verifySlackSignature()`: HMAC-SHA256 على `v0:{X-Slack-Request-Timestamp}:{raw body}`، يُقارَن في زمن ثابت مع `X-Slack-Signature` (`v0=`). الطلبات الأقدم من خمس دقائق، أو التي تسبق الوقت المحلي بأكثر من دقيقة، تُرفَض (الـtimestamp بالثواني، كما ترسله Slack). راجع [توثيق Slack](https://docs.slack.dev/authentication/verifying-requests-from-slack). +`slackChannel()` يتحقق من كل طلب نيابةً عنك (راجع [Slack في Channels](/ar/channels#discord)). أما في الـhandler الخاص بك (slash commands والتفاعلات)، فتحقّق من الـbody الخام بـ`verifySlackSignature()`: HMAC-SHA256 على `v0:{X-Slack-Request-Timestamp}:{raw body}`، يُقارَن في زمن ثابت مع `X-Slack-Signature` (`v0=`). الطلبات الأقدم من خمس دقائق، أو التي تسبق الوقت المحلي بأكثر من دقيقة، تُرفَض (الـtimestamp بالثواني، كما ترسله Slack). راجع [توثيق Slack](https://docs.slack.dev/authentication/verifying-requests-from-slack). ```ts import { verifySlackSignature } from 'lousho/triggers'; diff --git a/ar/troubleshooting.mdx b/ar/troubleshooting.mdx index bc4bd50..72c5741 100644 --- a/ar/troubleshooting.mdx +++ b/ar/troubleshooting.mdx @@ -17,13 +17,13 @@ title: "حل المشاكل" - **السبب:** متغير مفتاح الـ provider (`OPENAI_API_KEY` أو `ANTHROPIC_API_KEY` أو `OPENROUTER_API_KEY`) غير موجود في بيئة العملية التي تشغّل الـ agent (`LOUSHO_PROVIDER_MISSING_API_KEY`). - **الحل:** اضبطه، أو مرّر instance جاهز من الـ provider. `npx lousho doctor` يطبع `set` أو `not set` لكل مفتاح، ولا يطبع القيمة أبدًا. بادئة `vendor/` في اسم الـ model هي التي تختار الـ provider؛ مع OpenRouter استخدم `openrouter//` (مثال `openrouter/openai/gpt-4o-mini`) — `model: 'openai/gpt-4o-mini'` يحتاج `OPENAI_API_KEY` حتى لو `OPENROUTER_API_KEY` هو الوحيد المضبوط. -- **للمزيد:** [الخطأ](/ar/errors#lousho_provider_missing_api_key). +- **للمزيد:** [الخطأ](/ar/errors#lousho_provider_request_failed). ### "Cannot find package `@ai-sdk/openai`" أو "install the optional peer" - **السبب:** كل provider يعتمد على حزمة اختيارية تُحمَّل عند أول استخدام، بإصدار رئيسي يقابل إصدار `ai` الرئيسي عندك (`LOUSHO_PEER_MISSING`). نفس الخطأ يغطي باقي الـ peer dependencies الاختيارية، مثل `dockerode` و`@modelcontextprotocol/sdk`. - **الحل:** نفّذ أمر `npm install` الموجود في الرسالة (موجود أيضًا في `error.installCommand`)، أو ابحث عن إصدار `ai` الرئيسي عندك في جدول الاقتران. -- **للمزيد:** [حزم الـ providers](/ar/installation#حزم-الـ-providers)، [الـ peer dependencies الاختيارية](/ar/installation#optional-peers)، [الخطأ](/ar/errors#lousho_peer_missing). +- **للمزيد:** [حزم الـ providers](/ar/installation#حزم-الـ-providers)، [الـ peer dependencies الاختيارية](/ar/installation#optional-peers)، [الخطأ](/ar/errors#lousho_hosted_tool_unsupported). ### "`ai` 5 is installed" @@ -73,7 +73,7 @@ title: "حل المشاكل" - **السبب:** الـ session الموقوفة على approval لا تقبل مدخل جديد (`LOUSHO_SESSION_AWAITING_APPROVAL`)؛ أو أن `session.compact()` أو `session.clear()` استُدعيت وفي turn شغّال أو في الطابور (`LOUSHO_SESSION_BUSY`). - **الحل:** حسم الـ approval ثم أرسل مجددًا؛ أو انتظر `send()` الخاصة بالـ turn (أو ألغِها)، ثم استدعِ من جديد. -- **للمزيد:** [بانتظار الـ approval](/ar/errors#lousho_session_awaiting_approval)، [مشغولة](/ar/errors#lousho_session_busy). +- **للمزيد:** [بانتظار الـ approval](/ar/errors#lousho_session_turn_pending)، [مشغولة](/ar/errors#lousho_session_step_not_found). ## Tools @@ -93,7 +93,7 @@ title: "حل المشاكل" - **السبب:** الـ model أرسل arguments لا تطابق الـ input schema للـ tool. داخل الـ run ترجع له الـ issues كنتيجة ويقدر يعيد المحاولة، فنادرًا ما ينتهي run بسببه. - **الحل:** إذا الـ model يغلط في نفس الحقل، خلّ نص `.describe()` أوضح. وإذا إنت استدعيت الـ tool بنفسك، صحّح الـ arguments المذكورة في الرسالة. -- **للمزيد:** [الخطأ](/ar/errors#lousho_tool_args_invalid). +- **للمزيد:** [الخطأ](/ar/errors#الـ-approvals-والـ-sessions). ## Providers و models @@ -101,7 +101,7 @@ title: "حل المشاكل" - **السبب:** الـ provider طبّق rate limit على الاستدعاء (`LOUSHO_PROVIDER_RATE_LIMITED`) أو فشل فشلًا عابرًا. - **الحل:** `createAgent()` أصلًا تعيد الاستدعاء الفاشل مرتين — لكن فقط لـ model مُمرّر كسلسلة `provider/model` أو محلول من البيئة؛ أما `provider` instance تمرّره إنت فلا تُعاد محاولاته إلا إذا ضبطت `retry`. ارفعها بـ `retry: { maxRetries: 3 }`، واضبط `fallbackModels` للانتقال إلى الـ model التالي إذا الاستدعاء ظل يفشل. -- **للمزيد:** [إعادة المحاولة و fallback models](/ar/providers#retry-ونماذج-fallback)، [الخطأ](/ar/errors#lousho_provider_rate_limited). +- **للمزيد:** [إعادة المحاولة و fallback models](/ar/providers#retry-ونماذج-fallback)، [الخطأ](/ar/errors#lousho_peer_missing). ### الـ model لا يقرأ ملفاتي @@ -121,7 +121,7 @@ title: "حل المشاكل" - **السبب:** `SubprocessSandbox` مع `network: { allow }` و`broker` يحتاج الـ broker يكون المخرج الوحيد للحاوية. Docker Desktop وrootless Docker وdaemon على جهاز آخر وEngine أقدم من 25.0.5 كلها ما تقدر تعطيك هذا، فلا تبدأ أي حاوية (`LOUSHO_SANDBOX_EGRESS_UNSUPPORTED`). الرفض مقصود، بدل فتح egress مفتوح. - **الحل:** شغّل الـ agent على Linux host عليه Docker Engine 25.0.5 أو أحدث، أو استخدم `network: 'none'`. -- **للمزيد:** [Sandboxed shell](/ar/workspace-tools#sandboxed-shell-sandboxshell)، [الخطأ](/ar/errors#lousho_sandbox_egress_unsupported). +- **للمزيد:** [Sandboxed shell](/ar/workspace-tools#sandboxed-shell-sandboxshell)، [الخطأ](/ar/errors#lousho_flow_invalid). ### أدوات سيرفر MCP ما تظهر diff --git a/ar/upgrading.mdx b/ar/upgrading.mdx index dbf16b4..3e478cb 100644 --- a/ar/upgrading.mdx +++ b/ar/upgrading.mdx @@ -126,7 +126,7 @@ const lead = createAgent({ | المحذوف | البديل | | ------- | ----------- | | `WebhookTriggerAdapter`, `WebhookTriggerAdapterOptions`, `WebhookTriggerHandle` | `webhookChannel()`، تُركَّب بـ`mountChannels()`؛ وتأخذ نفس خيار `auth`. شوف [Channels](/ar/channels) | -| `SlackTriggerAdapter`, `SlackTriggerAdapterOptions` | `slackChannel()`، تُركَّب بـ`mountChannels()` - sessions (جلسات) لكل thread، وأزرار approval (موافقة). شوف [Channels](/ar/channels#slack) | +| `SlackTriggerAdapter`, `SlackTriggerAdapterOptions` | `slackChannel()`، تُركَّب بـ`mountChannels()` - sessions (جلسات) لكل thread، وأزرار approval (موافقة). شوف [Channels](/ar/channels#discord) | | `CronTriggerAdapter`, `CronTriggerAdapterOptions`, `CronIntervalOptions`, `CronExpressionOptions` | `defineSchedule()` مع `startSchedules()`، أو `schedules/` في مجلد الـ agent، أو cron triggers في ملف spec. ما فيه `intervalMs`: اكتب تعبير الـ cron (`*/5 * * * *`). شوف [Schedules](/ar/schedules) | ## Deprecated لكنها ما زالت تشتغل في 1.x diff --git a/ar/workspace-tools.mdx b/ar/workspace-tools.mdx index 1a511ad..4099e5d 100644 --- a/ar/workspace-tools.mdx +++ b/ar/workspace-tools.mdx @@ -284,7 +284,7 @@ await broker.close(); اللي يفرضه هذا، وأين: - **Docker Engine على Linux والـagent على نفس الـhost: مفروض.** الـcontainer يقدر يوصل لعنوان الـgateway ولا شيء بعد الـbridge. في DNS: الـcontainer ما يحلّ أي أسماء خارجية بنفسه (Engine 25.0.5 وأحدث ما يمرّرون DNS من الشبكات الداخلية، CVE-2024-29018؛ والإصدارات الأقدم تُرفض)، فالأسماء تروح للـproxy اللي يحلّها على الـhost بعد فحص الـallowlist. الاتصالات المباشرة بـIP خام ما لها route. البروتوكولات غير HTTP (SSH وTCP خام وUDP) محجوبة، لأن الـproxy وحده اللي يمكن الوصول له، وأنفاق `CONNECT` تُفحص على الـallowlist مثل أي طلب. وهذا مُختبَر على daemon حقيقي: الـjob `compat` في الـCI (`npm run test:docker`) يشتغل على runner `ubuntu-latest` في GitHub (كان Docker Engine بصلاحيات root بالإصدار 28.0.4 على Ubuntu 24.04 لما أُضيف)، ويتأكد من أن الـhost المسموح يجاوب عبر الـbroker، وأن باقي الـhosts تاخذ 403، وأن تجاوز الـproxy أو الاتصال بـIP خام ما له route، وأن الـcontainer ما يحلّ أسماء خارجية، وأن الـbroker يضيف credentials ما يشوفها الـcontainer أبدًا، وأن container خارج الشبكة ما يقدر يستخدم listener الـgateway، وأن `close()` والـrun الملغي ما يتركان شبكة ولا container وراهم، وأن الشبكة المعاد استخدامها غير الداخلية تُرفض. -- **Docker Desktop (Windows وmacOS، وDesktop على Linux): مرفوض.** الـcontainers تشتغل داخل VM، فالـhost ما له عنوان على الشبكة الداخلية. و`host.docker.internal` يوصل للـhost فقط من الشبكات غير الداخلية، وهذي توصل لكل شيء ثاني كمان. `run()` يرفض بـ[`LOUSHO_SANDBOX_EGRESS_UNSUPPORTED`](/ar/errors#lousho_sandbox_egress_unsupported) وما يشغّل أي container. ونفس الشيء مع Docker rootless (الـbridge عايش في network namespace خاص فيه)، ومع daemon على جهاز ثاني (الـbroker ما يقدر يربط عنوان الـgateway)، ومع شبكة معاد استخدامها ليست داخلية، ومع Engine أقدم من 25.0.5. +- **Docker Desktop (Windows وmacOS، وDesktop على Linux): مرفوض.** الـcontainers تشتغل داخل VM، فالـhost ما له عنوان على الشبكة الداخلية. و`host.docker.internal` يوصل للـhost فقط من الشبكات غير الداخلية، وهذي توصل لكل شيء ثاني كمان. `run()` يرفض بـ[`LOUSHO_SANDBOX_EGRESS_UNSUPPORTED`](/ar/errors#lousho_flow_invalid) وما يشغّل أي container. ونفس الشيء مع Docker rootless (الـbridge عايش في network namespace خاص فيه)، ومع daemon على جهاز ثاني (الـbroker ما يقدر يربط عنوان الـgateway)، ومع شبكة معاد استخدامها ليست داخلية، ومع Engine أقدم من 25.0.5. - **خدمات ثانية على عنوان الـbridge في الـhost.** container على شبكة داخلية يقدر يوصل لأي خدمة على الـhost تستمع على عنوان الـgateway أو على كل العناوين (`0.0.0.0`). اربط خدمات الـhost بـ`127.0.0.1`، أو حط جدار ناري يقيّد subnet الـbridge لمنفذ الـbroker فقط. جدار ناري على الـhost يسقط الترافيك الجاي من الـbridge (سياسة `INPUT` صارمة) يحجب الـbroker كمان: وقتها الـruns تفشل في الاتصال، ولا تاخذ egress مفتوح. - **أوامر الـhost ما زالت بدون جدار ناري.** أمر ينفّذه `NodeWorkspace` أو `NoopSandbox` يقدر يتجاهل متغيرات الـproxy؛ راجع ملاحظات الـcredential broker أدناه. diff --git a/changelog.mdx b/changelog.mdx index dcb9cfe..64cb142 100644 --- a/changelog.mdx +++ b/changelog.mdx @@ -6,7 +6,189 @@ description: "Every notable change to lousho, newest first." ## [Unreleased] +- Model strings resolve any official AI SDK provider: `mistral/...`, `groq/...`, `xai/...`, `bedrock/...`, `vertex/...`, `azure/...` and 13 more load `@ai-sdk/` on the first call, and `ai-sdk//` loads any other `@ai-sdk/*` package. The package reads its own credentials. See [Providers](/providers#any-ai-sdk-vendor-by-name). + +## [1.0.0-alpha.117] - 2026-11-09 + +## [1.0.0-alpha.116] - 2026-11-09 + +## [1.0.0-alpha.115] - 2026-11-09 + +## [1.0.0-alpha.114] - 2026-11-09 + +## [1.0.0-alpha.113] - 2026-11-09 + +## [1.0.0-alpha.112] - 2026-11-09 + +## [1.0.0-alpha.111] - 2026-11-09 + +## [1.0.0-alpha.110] - 2026-11-09 + +## [1.0.0-alpha.109] - 2026-11-09 + +## [1.0.0-alpha.108] - 2026-11-09 + +## [1.0.0-alpha.107] - 2026-11-09 + +## [1.0.0-alpha.106] - 2026-11-09 + +## [1.0.0-alpha.105] - 2026-11-09 + +## [1.0.0-alpha.104] - 2026-11-09 + +## [1.0.0-alpha.103] - 2026-11-08 + +## [1.0.0-alpha.102] - 2026-11-08 + +## [1.0.0-alpha.101] - 2026-11-08 + +## [1.0.0-alpha.100] - 2026-11-08 + +## [1.0.0-alpha.99] - 2026-11-08 + +## [1.0.0-alpha.98] - 2026-11-08 + +## [1.0.0-alpha.97] - 2026-11-08 + +## [1.0.0-alpha.96] - 2026-11-08 + +## [1.0.0-alpha.95] - 2026-11-08 + +## [1.0.0-alpha.94] - 2026-11-08 + +## [1.0.0-alpha.93] - 2026-11-08 + +## [1.0.0-alpha.92] - 2026-11-08 + +## [1.0.0-alpha.91] - 2026-11-08 + +## [1.0.0-alpha.90] - 2026-11-08 + +## [1.0.0-alpha.89] - 2026-11-08 + +## [1.0.0-alpha.88] - 2026-11-08 + +## [1.0.0-alpha.87] - 2026-11-08 + +## [1.0.0-alpha.86] - 2026-11-08 + +## [1.0.0-alpha.85] - 2026-11-08 + +## [1.0.0-alpha.84] - 2026-11-08 + +## [1.0.0-alpha.83] - 2026-11-08 + +## [1.0.0-alpha.82] - 2026-11-08 + +## [1.0.0-alpha.81] - 2026-11-08 + +## [1.0.0-alpha.80] - 2026-11-08 + +## [1.0.0-alpha.79] - 2026-11-08 + +## [1.0.0-alpha.78] - 2026-11-08 + +## [1.0.0-alpha.77] - 2026-11-08 + +## [1.0.0-alpha.76] - 2026-11-08 + +## [1.0.0-alpha.75] - 2026-11-08 + +## [1.0.0-alpha.74] - 2026-11-08 + +## [1.0.0-alpha.73] - 2026-11-08 + +## [1.0.0-alpha.72] - 2026-11-08 + +## [1.0.0-alpha.71] - 2026-11-08 + +## [1.0.0-alpha.70] - 2026-11-08 + +## [1.0.0-alpha.69] - 2026-11-08 + +## [1.0.0-alpha.68] - 2026-11-08 + +## [1.0.0-alpha.67] - 2026-11-08 + +## [1.0.0-alpha.66] - 2026-11-08 + +## [1.0.0-alpha.65] - 2026-11-08 + +## [1.0.0-alpha.64] - 2026-11-08 + +## [1.0.0-alpha.63] - 2026-11-08 + +## [1.0.0-alpha.62] - 2026-11-08 + +## [1.0.0-alpha.61] - 2026-11-08 + +## [1.0.0-alpha.60] - 2026-11-08 + +## [1.0.0-alpha.59] - 2026-11-08 + +## [1.0.0-alpha.58] - 2026-11-08 + +## [1.0.0-alpha.57] - 2026-11-08 + +## [1.0.0-alpha.56] - 2026-11-08 + +## [1.0.0-alpha.55] - 2026-11-08 + +## [1.0.0-alpha.54] - 2026-11-08 + +## [1.0.0-alpha.53] - 2026-11-07 + +## [1.0.0-alpha.52] - 2026-11-07 + +## [1.0.0-alpha.51] - 2026-11-07 + +## [1.0.0-alpha.50] - 2026-11-07 + +## [1.0.0-alpha.49] - 2026-11-07 + +## [1.0.0-alpha.48] - 2026-11-07 + +## [1.0.0-alpha.47] - 2026-11-07 + +## [1.0.0-alpha.46] - 2026-11-07 + +## [1.0.0-alpha.45] - 2026-11-07 + +## [1.0.0-alpha.44] - 2026-11-07 + +## [1.0.0-alpha.43] - 2026-11-07 + +## [1.0.0-alpha.42] - 2026-11-07 + +## [1.0.0-alpha.41] - 2026-11-07 + +## [1.0.0-alpha.40] - 2026-11-07 + +## [1.0.0-alpha.39] - 2026-11-07 + +## [1.0.0-alpha.38] - 2026-11-07 + +## [1.0.0-alpha.37] - 2026-11-07 + +## [1.0.0-alpha.36] - 2026-11-07 + +## [1.0.0-alpha.35] - 2026-11-07 + +## [1.0.0-alpha.34] - 2026-11-07 + +## [1.0.0-alpha.33] - 2026-11-07 + +## [1.0.0-alpha.32] - 2026-11-07 + - Install docs use the public npm packages again (`npm install lousho`, `npm create lousho`). +- `lousho/improve` (experimental): `improveAgent()` proposes tested edits to an agent's instructions and skills, offline, gated against the current harness and held-out cases. It applies nothing. See [Improving an agent](https://github.com/LinuxDevil/agent-sdk/blob/main/docs/improve.md). +- `agent.recover({ retryWithDiagnosis: true })` gives a run that reached `maxAttempts` one fork told why it failed, before quarantining it. `createOutputCheck()` is a new hook that runs your check after a tool succeeds and tells the model what it found. A fork no longer inherits `lastError` and `attempts` from its source. +- **Behavior change:** `agent.recover()` no longer resumes a failing run forever. It backs off exponentially from the last failure (up to 15 minutes) and stops after `maxAttempts` failures in a row (default 10), calling the new `onQuarantined(run)` once. `agent.resume()` still runs a quarantined run. Pass a larger `maxAttempts` to keep retrying longer. +- `lousho observe failures` also lists runs whose process died and scores below `--min-score` (default 0.5). +- `agent.recover()` pauses during a provider outage instead of using up each run's attempts: after 3 provider failures in a row it stops resuming, probes with one run at growing intervals, and reports through the new `onOutage(paused)`. +- `createProgressGuard()` gains `maxSameResults` (default 5), which denies a tool that keeps returning the same result even when its arguments differ. Run spans record `lousho.run.finish_reason`, and `lousho observe failures` lists runs that ended without an answer and names rate limits. +- `lousho observe failures` lists recurring tool and model failures by agent, from the observe database or from trace files (`--traces`), each with a class and trace ids. See [Observability](/observability). +- `createProgressGuard()`: an opt-in hook that adds advice to repeated tool failures, denies calls that keep returning the same result and tools that keep failing the same way, and stops the run with `LOUSHO_RUN_NO_PROGRESS` if denials continue. Actions stream as the new `heal.action` event; tool hooks get `ctx.emit`, and tool spans record `lousho.tool.replaced_by_hook`. See [Hooks](/hooks#stop-a-run-that-makes-no-progress). ## [1.0.0-alpha.31] - 2026-11-01 @@ -109,7 +291,7 @@ opt-out. - **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'`). -- README and [Comparison](/comparison) no longer list ACP and MCP as differentiators, and describe Agent Forge as a local visual console. +- README and [Comparison](https://github.com/LinuxDevil/agent-sdk/blob/995e21b7a835a4c869c1ae0b427fc92b0ee9c000/docs/comparison.md) no longer list ACP and MCP as differentiators, and describe Agent Forge as a local visual console. - 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. diff --git a/cli.mdx b/cli.mdx index a7e268d..89db85e 100644 --- a/cli.mdx +++ b/cli.mdx @@ -21,6 +21,7 @@ Run it with `npx lousho ` inside a project that has the SDK installed. | `lousho traces [id]` | List the recent runs saved by `fileTraceExporter()` (duration, model and tool calls, tokens, cost), or print one run as a span tree. | [Observability](/observability#local-traces) | | `lousho build --target= --agent=` | Build a deployable Node server, Docker image or Cloudflare Worker. | [Deployment](/deployment) | | `lousho studio` | Launch Agent Forge, the visual dashboard, on one local port. | [Agent Forge](/agent-forge) | +| `lousho improve --check ` | Experimental. Run one self-healing cycle on an agent directory: propose edits to its instructions and skills from failed runs in your local observe database, gate them, replay them on fresh runs, and apply (auto mode, the default) or queue (manual mode) one that passes. `--watch` keeps it running; `pause`, `status`, `rollback`, `approve` and the other subcommands manage it. `--dry-run` prints the review card and applies nothing. | [Below](#lousho-improve) | Every command that takes a `` reads an agent spec file (`.yaml`, `.yml` or `.json`, see [Configuration](/configuration#agent-spec-files-agentspec)). @@ -39,8 +40,10 @@ lousho mcp [--http --port N --host H] lousho doctor [agent.yaml|json|agent-dir|agent.ts] [--json] [--ping] lousho eval [globs...] [--tag t] [--junit path] [--json path] [--strict] [--judge] [--record | --replay | --drift [--drift-usage]] [--url [--token ]] [--config vitest.config.ts] [--timeout ] lousho traces [traceId|prefix] [--dir D] [--limit N] [--json] [--content] -lousho observe [--port N] [--db path] [--host H] [--require-token] [--project X] [--webhook URL] [--retention-days N] [--session-idle-minutes N] [--older-than d] [--since d|h|m] [--agent X] [--out file] +lousho observe [--port N] [--db path] [--host H] [--require-token] [--project X] [--webhook URL] [--retention-days N] [--session-idle-minutes N] [--older-than d] [--since d|h|m] [--agent X] [--out file] lousho prompt |list|get |label