# Billing Source: https://tale.dev/docs/cloud/billing Billing on Cloud is metered, not seat-based. You pay for tokens consumed by chats and agents, voice minutes, image generations, and storage; the platform itself comes with the org. This page walks one invoice line, lists the metered components, and points at the budget controls that prevent surprises. The invoice arrives monthly via email and is also visible inside the product under **Settings > Billing**. Cloud bills in your org's billing currency, which defaults to USD on sign-up and can be changed before the first invoice cuts. ## A worked invoice line A line on the invoice reads `Models — Anthropic Claude Sonnet — 1.2M tokens — $4.32`. Tale assembled it from the per-message usage ledger: every chat reply records the model used, the token count, and the cost at the rate active when the call completed. Lines aggregate by provider and model per billing period. The detail is downloadable as CSV from the same screen. ## Plan tiers Tale ships two tiers — **Community** and **Enterprise**. Community is the self-hosted open-source edition; you run it on your own infrastructure and the billing concept on this page does not apply. **Enterprise** is the managed tier (Cloud or self-hosted) with a support SLA, audit-log retention controls, SSO, the DPA, and access to regions beyond the default. The tier affects fixed monthly fees and feature gates, not per-call costs; the metered pricing for tokens, voice, and storage below applies to Enterprise on Cloud. ## Metered components | Component | Unit | Counted as | Where to view | | ----------- | ----------------- | --------------------------------------------------------- | ------------------------------------------------------------- | | Models | Tokens (in + out) | Per provider call; markup applied on top of provider rate | [Usage analytics](/platform/admin/governance/usage-analytics) | | Voice (TTS) | Characters spoken | Per agent reply rendered as audio | Usage analytics | | Voice (STT) | Audio seconds | Per user message recorded | Usage analytics | | Images | Generations | Per image returned by the model | Usage analytics | | Storage | GB-month | Object store usage averaged over the period | Billing page | ## Budgets and overages Set budgets under [Policies and limits](/platform/admin/governance/policies-and-limits). A **Budget rule** caps monthly spend per user, per team, per role, or per org. Hitting a budget reads as a clear toast — **Usage limit reached** — and pauses the affected scope until the budget is raised or the period rolls over. The default precedence is `user > team > role > default` — the most specific rule wins. A **Warning threshold (%)** on the same rule emits a notification when usage crosses the threshold without blocking. Reach for the warning when you want to know but not interrupt; reach for hard limits when overruns are an emergency. ## Where to find usage The richest view is [Usage analytics](/platform/admin/governance/usage-analytics) under Governance — it breaks usage down by **Top Assistants**, **Top Models**, **Top Voice Models**, and **Per-User Usage**, all filterable by date range. The Billing page in Settings shows the invoice-level view; Usage analytics shows the operational view. ## Where this fits Billing is the operator's headline page; [Usage analytics](/platform/admin/governance/usage-analytics) is the everyday one. If your org's cost is mostly tokens, the page worth bookmarking is the Top Models table — it surfaces which models the team has settled on and tells you whether a switch to a cheaper alternative would matter. For self-hosted users, the billing concept does not apply (you pay your provider directly); the cost-visibility page does. # Data residency Source: https://tale.dev/docs/cloud/data-residency Data residency on Cloud answers two questions every audit eventually asks: which region holds your data at rest, and which external systems touch it in flight. This page traces a single chat round-trip end to end, lists the data classes, and names every sub-processor your messages pass through. The default region for new Cloud orgs is Switzerland. Switching region after sign-up is a migration, not a setting flip — re-creating an org in the EU region is faster than moving an existing one. Pick once; pick deliberately. ## A worked example — one chat round-trip The user in Zürich opens Chat and sends "summarise the latest customer call". The request hits Tale's edge in the chosen region, lands on `tale-platform`, which calls into `tale-convex` (the backend), reads knowledge from the corpus database when the agent's knowledge tool asks for it, and emits an outbound call to the provider behind the model the sender picked. Knowledge retrieval runs inside the Convex backend — it queries the corpus database directly, with no separate retrieval service in the path. The model provider returns tokens; Tale streams them back across the same path. The reply and citations land in the operational database, the corpus stays in the knowledge database, and both are replicated within the region. Two arrows cross the regional boundary in this trip: the call to the model provider (always external) and any sub-processor the agent's tools triggered (web fetch, OneDrive read, MCP server in another region). Everything else stays in region. ## Primary regions | Region | Postgres | Object store | DR replica | | -------------- | --------- | ------------ | ---------- | | Switzerland | Zürich | Zürich | Geneva | | European Union | Frankfurt | Frankfurt | Dublin | The DR replica is for disaster recovery, not active traffic. A region's data never flows to the other region's primary or replica. ## What stays in region, what leaves | Data type | Region-locked | Crosses | Notes | | ---------------------------------- | ------------- | ------- | ------------------------------------------------------------------------------ | | Chats and messages | ✓ | | | | Documents and knowledge embeddings | ✓ | | | | Org configuration and roles | ✓ | | | | Audit logs | ✓ | | | | Model provider requests | | ✓ | Goes to the provider you configured; pick a regional endpoint when one exists. | | OneDrive sync | | ✓ | Microsoft's storage region applies. | | Web tool fetches | | ✓ | Wherever the URL resolves. | ## Backups and DR Tale snapshots both Postgres databases — the operational store and the knowledge corpus — daily, and the object store hourly. Snapshots are encrypted at rest with keys held by Tale; the DR replica receives a copy within the region. Restores from snapshot are a customer-initiated operation routed through support; the SLA covers restore time. ## Changing region A region change is implemented as an export from the current region, an import into the new region, and a DNS cutover. The procedure is the same as [Migrate to self-hosted](/cloud/migrate-to-self-hosted) except both sides are Cloud regions; expect downtime in the minutes range and a planned window. There is no in-place region toggle. ## Where this fits Data residency is the first page every compliance review reads. Pair it with [Trust and compliance](/cloud/trust-and-compliance) (which framework covers what) and [Subprocessors](/legal/subprocessors) (the list of every external system named above). If your org is considering self-hosted because of a residency requirement, [Self-hosted overview](/self-hosted/overview) is the next read — running the stack on your hardware moves every arrow on this page inside your own boundary. # Cloud Source: https://tale.dev/docs/cloud Tale Cloud is the managed edition. Tale operates the infrastructure, your data is pinned to Switzerland or the EU, and your team's only operational concern is using the product. The codebase is identical to self-hosted; the difference is who keeps it running. This section covers the concerns specific to running on Cloud — onboarding, regions and data residency, billing, the trust posture you can hand an auditor, and how to migrate to self-hosted if your needs change. Every other feature reference lives one tab over under Platform, identical regardless of edition. ## Pages in this section Request your instance, create the org, configure the first model provider, publish your first agent. About an hour for an Editor. Where your data lives, which sub-processors touch it, and what changes when you switch region. Plans, seats, metered components, budgets, and where to find the invoice. The certifications Tale ships with, the shared-responsibility split, and what evidence you can hand an auditor. Export from Cloud, stand up a self-hosted instance, import. ## Where this fits Cloud is the convenient front door; Platform is where the real work lives. Once your org is signed in and the first agent is running, your team spends nearly all their time in Platform pages, not here. The one page worth re-reading whenever your operational posture changes is [Data residency](/cloud/data-residency) — it surfaces every external system your data crosses. # Migrate to self-hosted Source: https://tale.dev/docs/cloud/migrate-to-self-hosted Migration from Cloud to self-hosted is a real procedure, not a setting flip. The data exports, the new instance imports, DNS cuts over to the new host, and your team signs in to the same org they had — same agents, same chats, same audit history. This tutorial walks the procedure and points at where it goes wrong. Reach for it when self-hosting genuinely fits better: data residency requires hardware you control, costs at scale make on-premise cheaper than per-token, or the org has decided to run the stack themselves. For most teams Cloud stays the right call — re-read [Cloud onboarding](/cloud/onboarding) if you are still deciding. ## Before you begin Have these in place before exporting anything: - A target host that meets the self-hosted prerequisites — see [Quickstart](/self-hosted/install/quickstart) for the spec. - DNS control over the domain your org currently uses; you will swing it during the cutover. - A maintenance window of at least an hour. The import itself is faster than that, but DNS propagation and validation add time. - A recent backup confirmation in your Cloud org's audit log. Nothing gets deleted in the source during a migration, but the export bundle is your evidence that the source state was consistent. ## What moves and what does not Moves: chats, threads, messages, attachments, documents, knowledge embeddings, agents, agent versions, workflows, executions, audit logs, members, roles, teams, branding, API keys, connectors metadata. Does not move: external connectors have to be re-authenticated against the new instance (the credentials live in the provider, not in the export bundle); active running workflows pause and resume on the new instance after the cutover; voice audio retained past the org's retention window stays in the Cloud object store until purged. ## Step 1 — Export Open **Settings > Organization** on Cloud and click **Export**. The dialog runs the export in the background and emails a download link when complete. The export is a single encrypted bundle; the email contains the decryption key. Download the bundle and store the key separately. ## Step 2 — Stand up the target instance On the target host, follow [Quickstart](/self-hosted/install/quickstart) through the first-admin step. Do not invite users yet — the import overwrites the member list. Confirm the new instance boots and you can sign in as Owner. ## Step 3 — Import On the target instance, sign in as Owner and visit `/_internal/import` (linked from the Settings page after a fresh install). Upload the bundle, paste the decryption key, and click **Import**. The import is a long-running operation; the page shows progress per data class. When the page resolves to **Import complete**, the new instance carries the source org's full state. ## Step 4 — Cut DNS Update the DNS record for the org's domain to point at the new instance. Once propagation lands and the new instance's TLS is healthy, users signing in arrive at the self-hosted instance with their existing credentials. The Cloud org becomes read-only at this point — to avoid drift, archive it in **Settings > Organization** on Cloud after a few days of confidence. ## Troubleshooting - **Export hangs at "preparing".** Very large orgs (>100 GB) take longer than the email window assumes. Open a support ticket; the export runs to completion in the background. - **Import fails on schema mismatch.** Your target instance is running an older Tale version than the Cloud export expects. Upgrade the target before retrying — the bundle is forward-compatible, not backward-compatible. - **Members cannot sign in after cutover.** Session cookies are scoped to the old host. Members re-authenticate once; SSO and 2FA settings carry across. - **Workflows show "paused" after import.** Expected — the import preserves state but does not auto-resume running executions. Open each workflow and click **Resume** after confirming the target instance is reachable from any external triggers. ## Where this gets used Migration is a one-direction operation in practice — once you self-host, you stay self-hosted unless something changes structurally. The reverse migration (self-hosted to Cloud) follows the same shape with the same tooling and is supported but rare. If you are still on Cloud and reading this for context, the page worth following up with is [Self-hosted overview](/self-hosted/overview); it names what you are taking on. # Cloud onboarding Source: https://tale.dev/docs/cloud/onboarding This journey walks from demo request to a production-ready Cloud org with one working agent. The result is an org where your team can sign in, pick a working agent, and ask it something useful — nothing fancy yet, just the foundation everything else builds on. You need a working email address and the ability to verify it. The walk assumes no prior Tale knowledge; if anything below references a concept you have not met, the linked page introduces it. Once your instance is ready, the hands-on part takes under an hour — about half of it in the provider step, the rest mostly clicks. ## Before you begin Pin down three things: - An email address for the first Owner of the org. This account will hold the highest role; pick someone who will not leave the team next week. - API credentials for at least one model provider (OpenAI, Anthropic, Azure, or a compatible local). The provider's portal shows where these live. - The region you want your data pinned to. Cloud offers Switzerland and the EU; the choice is part of the instance setup, and switching later is a real migration. ## From demo request to a working agent Tale Cloud is not self-serve — every Cloud org runs on its own instance, set up for you by the Tale team. Fill in the demo request form at [tale.dev/request-demo](https://tale.dev/request-demo); name and email are enough, though your company and a line on what your agents should do help the team tailor the setup. The team then sets up your own demo instance — a dedicated environment, not a shared trial — and gets back to you when it is ready. Open your instance and sign up. The form asks for your name, email, and a password; verify the email link when it arrives. The next screen asks for the **Organization name** — the display name your team will see in the corner of every page. Pick something that survives a rebrand. ![The create-organization wizard on its workspace step, with Northlight Labs typed into the Organization name field and the Next button enabled.](/images/get-started/org-create-wizard.webp) The first user becomes the org's **Owner** automatically. You can see your role in the **Members** section under **Settings > Organization** later if you forget. Open **Settings > Organization**, scroll to the **Members** section, and click **Add member**. Enter the admin's name and email, assign the **Admin** role, and set a password — Tale creates the account directly and shows the sign-in credentials once, so save them and relay them to the new admin out of band (there is no invite email). They land in the org with the role you assigned. The "at least 2 Admins" safety rule means an org cannot accidentally lock itself out by removing its only Admin — add a second admin before doing anything that requires it. For the role matrix (who can do what), see [Members and roles](/platform/admin/members-and-roles). Open **Settings > AI providers**, find the connector you hold a key for, and click **Add credential**. Name the credential so a later reader knows which key it is, pick **API key** as the authentication method, and paste the key. The credential is stored encrypted and becomes the connector's default when it is the first one; a second credential on the same connector is fine, and you choose which is the default. The most common reason a key is rejected is whitespace around it. ![The AI providers settings page listing one connected provider, OpenRouter, with its base URL and a count of 52 models.](/images/get-started/settings-providers.webp) This step is where most onboarding sessions stall — the provider portal is usually a different login, and the team has to dig for the key. If validation hangs for more than a minute, refresh the page; the key is saved as soon as **Save** confirms — the row sometimes needs a reload to show it. Open **Agents** and click **Create agent**. Pick the model you just added. Write a one-paragraph instructions block — the voice the agent should answer in, the domain it knows, the cases it refuses. Save. Flip **Visible in chat** on. The agent is now reachable from any chat in the org. For a deeper walk on what makes an agent good, see [Create an agent](/platform/agents/create). Click **New chat** in the sidebar. Pick the agent from the picker, type a question the agent's domain covers, send. The reply streams back — if it lands the way you wrote the instructions to land, the org is done with onboarding. Three follow-ups worth doing now while everything is fresh: - Open **Settings > Branding** and upload the org logo. - Set the org's default language under **Settings > Organization**. - Skim [Trust and compliance](/cloud/trust-and-compliance) so you know what to show an auditor before one asks. ## Troubleshooting - **Invite email never arrives.** Check the invitee's spam folder. Tale sends from `noreply@tale.dev`; some corporate filters quarantine it. - **Provider validation fails with "invalid key".** Re-copy the key from the provider portal — copying often grabs a leading or trailing space. - **Agent does not show in the chat picker.** Confirm **Visible in chat** is on for the agent. ## Where this gets used You now have an org with one working agent and one admin besides yourself. The natural next walk is [Build your first agent end to end](/tutorials/editor/first-agent-end-to-end) — same shape, but builds an agent that does real domain work with knowledge bindings. If you came here to evaluate Cloud against self-hosted, [Migrate to self-hosted](/cloud/migrate-to-self-hosted) is the reverse walk. # Trust and compliance Source: https://tale.dev/docs/cloud/trust-and-compliance Trust and compliance on Cloud is the page an auditor wants. It names the frameworks the platform is certified against, splits responsibilities between Tale and your org cleanly, lists the data-protection controls available to you, and tells you who to call when something goes wrong. The content here is descriptive — what is shipped today, what evidence Tale can hand over on request. The legal documents themselves (DPA, terms, privacy) live under [Legal](/legal/privacy); this page is the operator's quick reference. ## A worked control — audit logs end to end The org's compliance officer needs to demonstrate that "every change to access control is logged with the actor, the target, and the timestamp". Tale's [Audit logs](/platform/admin/governance/audit-logs) record every member invite, role change, removal, and 2FA reset with the actor's user ID, the affected member's ID, and an ISO timestamp. Logs are immutable — restoring a snapshot does not modify them — and retained per the org's configured floor. The officer exports a date range as CSV, hands it to the auditor, and the worked example clears the control. ## Certifications and frameworks Tale Cloud is currently audited or attested against the following frameworks; the certification reports are available under NDA via support: - SOC 2 Type II (annual) - ISO/IEC 27001 - GDPR-aligned controls (EDPB guidance applied) - FADP-aligned controls for the Switzerland region (revDSG) Pending or planned: HIPAA BAA (US enterprise customers), additional regional attestations as the region list grows. ## Shared-responsibility split | Control | Tale | You | Evidence | | ----------------------------- | ----------------- | ---------------------- | -------------------------------------------------------- | | Infrastructure availability | ✓ | | Status page, SOC 2 SLA report | | Data encryption at rest | ✓ | | Architecture description | | Encryption in transit | ✓ | | TLS termination by Tale's edge | | Member identity and roles | | ✓ | [Members and roles](/platform/admin/members-and-roles) | | API key issuance and rotation | | ✓ | [API keys](/platform/admin/api-keys) | | Content filtering and DLP | Provides hooks | Configures rules | [Guardrails](/platform/admin/governance/guardrails) | | Audit-log retention | Provides storage | Sets retention | [Retention](/self-hosted/configuration/retention) | | Data-subject requests | Provides workflow | Initiates and approves | [DSRs](/platform/admin/governance/data-subject-requests) | | Provider credentials | | ✓ | [Providers](/platform/admin/providers) | ## Data protection controls Inside the product, three control surfaces matter for compliance: - **Audit logs** — immutable record of who did what; retention configurable. - **Legal hold** — exempts a record set from retention until lifted; covered in [Legal hold](/platform/admin/governance/legal-hold). - **Data subject requests** — the request → claim → erasure → audit workflow; covered in [DSRs](/platform/admin/governance/data-subject-requests). ## Reporting incidents Tale's security incident contact is `security@tale.dev`. Suspected vulnerability disclosure follows the responsible-disclosure policy on the same email. Customer-facing security advisories are published on the status page and emailed to the org's Owner. ## Where this fits Trust and compliance is the audit-time page; [Data residency](/cloud/data-residency) is the architecture-time page; [Subprocessors](/legal/subprocessors) is the list-of-vendors page. An auditor usually wants all three at once — bookmark them together. If you operate self-hosted, the controls are the same; what changes is who runs the infrastructure beneath them — see [Self-hosted overview](/self-hosted/overview). # AI-assisted development Source: https://tale.dev/docs/develop/ai-assisted-development Tale projects are JSON — agents, workflows, connectors, branding — and JSON edits well in AI editors when the editor knows the schema. The CLI emits two things for that: a rules file each editor reads at the project root (`CLAUDE.md` for Claude Code, `.cursor/rules/tale.mdc` for Cursor, `.github/copilot-instructions.md` for Copilot, `.windsurfrules` for Windsurf), and a read-only schema mirror under `.tale/reference/` the rules file points the editor at. Read this when you want to edit a Tale project in an AI editor without hand-typing JSON. Come back when the editor invents fields or wires the wrong agent shape — the answer is almost always that the schema under `.tale/reference/` is stale. ## A worked setup Initialise a project — the CLI writes the rules file and the schema mirror in the same step: ```bash tale init my-org cd my-org ls -a # .cursor/ .github/ .tale/ .windsurfrules # CLAUDE.md agents/ workflows/ connectors/ branding/ ``` `CLAUDE.md` (also installed as the Cursor `.mdc`, the Copilot `.md`, and the Windsurf rules file) tells the editor where to look before editing a config: > Before creating or editing any config, read the relevant schemas and implementation code in `.tale/reference/` to understand the valid structure, fields, and constraints. Use existing config files in the project as examples. The directive matters because every editor under load skips schema reads unless told otherwise. The rules file is the contract; the schema mirror is the ground truth. ## What lives where | Path | What it is | | -------------------------------- | ----------------------------------------------------------------------- | | `agents/` | One JSON file per agent — instructions, knowledge, tools, model. | | `workflows/` | Workflow JSON configs, grouped by category subdirectory. | | `connectors//config.json` | Connector manifest — operations, auth method, allowed hosts. | | `connectors//connector.ts` | Optional TypeScript connector for REST shapes the manifest can't cover. | | `branding/branding.json` | Org branding — colours, logos, email senders. | | `.tale/reference/` | Read-only schema mirror; regenerated by `tale init` and `tale update`. | The reference tree is bytes-identical to the schemas the platform validates against at deploy time. Treat it as canonical: when a field name in a hand-written config disagrees with the reference, the reference wins. ## Working with the editor The rules file names three rules each editor enforces while editing: - **Agents bind, delegate, attach.** An agent can simultaneously bind connectors (`connectorBindings`), delegate to other agents (`delegates`), and attach workflows (`workflows`). Read existing configs before introducing a new binding. - **Workflows use connector operations.** A workflow step references connector operations declared in `connectors//config.json`. Editing a step against an operation that does not exist will fail validation. - **Naming is enforced.** Agent filenames match `[a-z0-9][a-z0-9_-]*\.json`. Workflow step slugs match `[a-z0-9][a-z0-9_-]*`. Connector directories are lowercase alphanumeric with hyphens or underscores. When the editor proposes a change, ask it to cite the file in `.tale/reference/` it relied on. If it cannot, regenerate the mirror with `tale update` and try again. ## Cursor: config plane vs runtime plane Cursor shows up in Tale in two separate places — do not conflate them. | Plane | What it does | Where it lives | | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | | **Config** | Helps Cursor (or any AI editor) edit Tale project JSON on your machine | `.cursor/rules/tale.mdc`, `CLAUDE.md`, `.tale/reference/` — everything `tale init` writes | | **Runtime** | Runs the Cursor Agent CLI headlessly inside an isolated sandbox when a project agent or automation agent node uses the **Cursor** harness | Project agent / automation agent node with **Harness** = Cursor | The rules file and schema mirror on this page are the **config plane**: they steer a local editor while you change agents, workflows, and connectors. The **runtime plane** is a managed harness turn — `agent -p --output-format stream-json` with your `CURSOR_API_KEY`, normalized progress in chat, and session resume across follow-ups. Credentials, models, and billing for runtime turns are covered in [Harnesses](/platform/agents/harnesses), not here. ## Where this fits AI-assisted development is the editing path; deployment is the publishing path. Once a config passes editor validation, [`tale deploy`](/self-hosted/install/cli-install) reconciles it against the platform — the same schema check, this time as a gate. For features the editor cannot reach (the in-product builder, the visual workflow editor), the [Platform tab](/platform) is the canonical surface; the AI-editor path here is for projects that prefer config-as-code. # API reference Source: https://tale.dev/docs/develop/api-reference The Tale API is the surface integrators use when they are outside the product and want to script it: knowledge resources, automations and their runs, chat threads, agents, and skills, all as JSON over HTTPS with an API key in a header. The same key also opens the [MCP endpoint](/develop/mcp-endpoint) — this page covers the REST half. This page is the canonical inventory of the surface, the auth model, and the error shape. Field-level request and response schemas live in the OpenAPI document your instance serves at `/docs` — load it there when you need every property; read this page to understand how the API behaves. ## A worked request The shortest useful request — list the organization's automations — is one curl: ```bash curl -sS "https://your-host.example.com/api/v1/automations" \ -H "Authorization: Bearer $TALE_API_KEY" ``` A successful response is a page: `{ "page": [ { "name": "billing/dunning", "latest": 3, "deployedVersion": 2 } ], "isDone": true, "continueCursor": null }`. Every list endpoint answers this same envelope — pass `continueCursor` back as `?cursor=` to fetch the next page, and cap page size with `?limit=`. ## Authentication API keys are minted in the product by anyone with Admin or Developer permissions — [API keys](/platform/admin/api-keys) covers the panel. A key is shown once at creation and never again; it belongs to the user who minted it and to that user's organization. Pass the key as a bearer token: `Authorization: Bearer `. The organization context comes from the key — a key cannot be used outside its issuing organization, and everything the key touches is scoped there. What the key may _do_ follows the key holder's role: reads and mock runs need membership, while starting live work and editing what is deployed needs the developer capability. Where that matters, the endpoint notes below say so. ## Endpoint groups | Group | Path | What it covers | | ----------------- | --------------------------------------- | ------------------------------------------------------------------------------------ | | Automations | `/api/v1/automations/...` | List, read versions, start runs, read run history, bind and unbind triggers. | | Runs | `/api/v1/runs/{runId}` | One durable run in full — status, output, trace, effects — and `POST .../cancel`. | | Threads | `/api/v1/threads/...` | The key holder's chat threads: create, read messages, send a message, poll the turn. | | Agents | `/api/v1/agents/...` | List, read, create or replace, delete the organization's agents. | | Skills | `/api/v1/skills/...` | Same shape as agents, for skills. | | Knowledge entries | `/api/v1/knowledge-entries/...` | Topic-keyed facts: list, create, supersede, delete. | | Knowledge search | `POST /api/v1/knowledge/search` | Semantic retrieval over the organization's indexed knowledge. | | Documents | `/api/v1/documents/...` | Knowledge-base documents: CRUD plus `POST .../retry-indexing`. | | Websites | `/api/v1/websites/...` | Crawled sources: CRUD plus `.../pages`, `.../sync`, `.../search`. | | Products | `/api/v1/products/...` | Product catalog entries: CRUD. | | Contacts | `/api/v1/contacts/...` | Contact records: CRUD plus `POST /api/v1/contacts/bulk`. | | MCP | `POST /api/v1/mcp` | The [MCP endpoint](/develop/mcp-endpoint) — same key, JSON-RPC instead of REST. | | Webhook trigger | `POST /api/automations/webhook/` | Start a deployed automation from outside; the [Webhooks page](/develop/webhooks). | ## Automation names in URLs An automation's name is a `/`-separated path — `billing/dunning` — and a path cannot travel inside one URL segment. In every `/api/v1/automations/{name}/...` URL, write the name with `__` in place of each `/`: ```bash curl -sS "https://your-host.example.com/api/v1/automations/billing__dunning/runs" \ -H "Authorization: Bearer $TALE_API_KEY" ``` Responses always carry the real name (`"name": "billing/dunning"`); the `__` form exists only in URLs. Agent and skill slugs are flat and need no encoding. ## Start a run, then poll it A run is durable and may take minutes, so starting one answers **202** with the run's identity, not its result: ```bash curl -sS -X POST "https://your-host.example.com/api/v1/automations/billing__dunning/runs" \ -H "Authorization: Bearer $TALE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": { "customerId": "cus_123" } }' # → 202 { "runId": "...", "version": 2, "name": "billing/dunning", "mode": "live" } ``` Poll `GET /api/v1/runs/{runId}` until `status` leaves `queued`/`running`/`waiting`; the finished run carries `output`, the per-node `trace`, and the `effects` it produced. `POST /api/v1/runs/{runId}/cancel` stops a run at its next node boundary — work a node already completed is not undone. `mode` defaults to `live`. A live run acts on the organization's behalf, so it needs a key whose holder has the developer capability; `{"mode": "mock"}` runs against deterministic mocks and needs only membership. Starting a run needs no trigger — the API key is the entitlement. An automation with no deployed version answers **409**; deploy a version whose tests pass and the same call goes through. `projectId` names the project the run operates in — the project its task and document tools act on. Omit it and the run is organization-wide, except that an automation bound to a single project runs in that one automatically; an automation bound to several accepts only a `projectId` among them, and refuses any other. ## Send a message, then poll the turn Chat is the same 202-then-poll shape. Create a thread, post a message, poll the generation, then read the messages: ```bash # 1. A thread of your own curl -sS -X POST "https://your-host.example.com/api/v1/threads" \ -H "Authorization: Bearer $TALE_API_KEY" \ -H "Content-Type: application/json" -d '{}' # → 201 { "id": "" } # 2. Send a message — on this API the model is always explicit, never auto-selected curl -sS -X POST "https://your-host.example.com/api/v1/threads//messages" \ -H "Authorization: Bearer $TALE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "content": "Summarise this quarter for me.", "model": "" }' # → 202 { "threadId": "...", "status": "accepted", "model": "...", "poll": "/api/v1/threads//generation" } # 3. Poll until idle, then read curl -sS "https://your-host.example.com/api/v1/threads//generation" \ -H "Authorization: Bearer $TALE_API_KEY" # → 200 { "status": "streaming" } … then { "status": "idle" } ``` `{"status": "idle"}` means no turn is running — read `GET /api/v1/threads/{id}/messages` for the reply. A turn that fails before producing output still surfaces: the failure lands as an assistant message carrying the error, never silently. Threads listed and read over the API are the key holder's own; a second user's threads are invisible to your key even inside the same organization. ## Error model Every non-2xx response carries one flat envelope: ```json { "error": "Automation not found" } ``` Branch on the HTTP status; the message is for humans: - **400** — malformed request: a missing required field, a wrong type, an unparseable body. - **401** — missing or invalid API key. - **403** — the key is valid but its holder's role lacks the capability (live runs, trigger writes, cancels). - **404** — the resource does not exist in your organization, or belongs to someone else's thread. - **409** — the state refuses the action: no deployed version, a duplicate topic or email, a turn already running. - **413** — the body is too large (the webhook trigger caps at 256 KB). - **429** — rate limit exceeded; see [Rate limits](/develop/rate-limits). - **500** — internal error. Two deletion semantics exist, on purpose. Unbinding an automation's trigger (`DELETE .../triggers`) answers **204** whether or not a trigger existed — it is an idempotent "make it so". Deleting a resource (`DELETE /api/v1/agents/{slug}`) answers **404** when nothing existed — you asked to remove a thing that is not there. ## Versioning The API is versioned by URL prefix — today `/api/v1/` — and evolves additively inside it: new endpoints and new optional fields appear, existing shapes stay. A breaking change would ship under a new prefix. The OpenAPI document at `/docs` always describes the running instance. ## Where this fits This page is the REST half of the outside surface. The [MCP endpoint](/develop/mcp-endpoint) exposes the same platform to MCP clients — automation authoring lives there, not in REST. The [Webhooks page](/develop/webhooks) covers the inbound trigger that starts runs without a key. If you are building inside the product — agents, automations, custom tools — the [Platform tab](/platform) is your day-to-day; this page is for outside. # Connectors Source: https://tale.dev/docs/develop/connectors Connectors are the vendor-specific half of how Tale reaches other systems, and they are part of the platform rather than something an organisation assembles. Each one is a YAML file in the source tree that declares who it talks to, how it authenticates, and every action it can perform — which is why the catalog is identical in every deployment and why an upgrade is all it takes to move it forward. Read this when you want to know what a connector actually promises a caller, or when you are deciding between contributing one and hosting an MCP server. The organisation-facing side — adding credentials, defaults, reconnecting a lapsed grant — is [Connector credentials](/platform/admin/connectors), and the catalog itself is [Connectors](/platform/connectors/overview). ## How a connector is declared Every connector is one directory under `configs/platform/system/connectors/`, named for its slug, holding a `connector.yml` and the icon the settings page renders. The slug is the directory name, the connector's declared `name`, and the first half of the node type an automation uses to place one of its actions — `.`. Thirteen of these directories ship today. The file opens with the connector's identity and its authentication contract, then lists the actions: ```yaml name: tavily displayName: Tavily description: Real-time web search and page extraction for AI research. tags: - Search allowedHosts: - api.tavily.com auth: - method: api-key actions: - name: search description: >- Search the open web via Tavily. Returns top results with title, URL, content snippet, and score. effects: read input: type: object required: [query] properties: query: { type: string, description: 'Natural-language search query.' } max_results: { type: number, description: 'Max results (1-10).' } output: '{ answer?: string, results: Array<{ title: string, url: string, content: string, score: number }> }' ``` `allowedHosts` is the egress boundary — an action body that reaches anywhere else is refused rather than proxied. A connector whose API lives at a customer address instead of a vendor one adds `endpointMode: per-credential`, and each credential then carries the origin its calls are built from; Confluence and Shopify are the two shipped cases. Connectors are read from the platform's own tree, not from an organisation's configuration, and there is no upload path that adds one at runtime. Adding a connector is a source contribution — see [Contributor setup](/develop/contributor-setup). Hosting your own bridge without touching the source is what MCP is for. ## What an action declares An action is a contract, and every field of it is visible to the caller before the call happens: - **Name and description.** The name completes the node type; the description is what an agent reads when it decides whether this action is the right one. - **Input.** A JSON Schema — object type, required fields, and a description per property. Automations validate a node's configuration against it, and agents fill it from the same schema. - **Output.** A signature describing the shape that comes back, so a workflow author knows what the next step can reference. - **Effects.** Either `read` or `write`. Write actions gate behind the organisation's approval policy, and a call that cannot reach an approval decision is refused rather than performed ungated. Actions resolve their credential at call time: the one the caller names, or the connector's default when the caller names none. That is the seam that lets the same automation run against a different account by pointing it at a different credential name. Mail sync and inbox triage are different on purpose — `conversation.sync_mailbox` and `conversation.list_mailbox_messages` walk every active credential on the connector so every connected mailbox is covered without naming each one. ## The authentication methods A connector declares the methods it accepts, and a credential is stored against exactly one of them. The four are fixed, because each one describes a different way a secret reaches the vendor. | Method | UI label | What the credential holds | | --------- | ------------------- | ------------------------------------------------------------------------------------------------ | | `api-key` | API key | A single secret the action body places itself — a vendor header, a query param, or a body field. | | `bearer` | Token | A token sent as the Authorization header, under the scheme the connector names. | | `basic` | Username & password | A username and password sent as HTTP Basic, which is also the shape a mailbox login takes. | | `oauth2` | OAuth | An authorization-code grant: access token, refresh token, expiry, and the granted scopes. | Secrets are encrypted at rest in a single envelope and never travel back out to a caller. A listing shows a masked preview computed when the credential was written, so reading the credential list never touches ciphertext. ## Registering an OAuth app An `oauth2` connector declares the vendor's authorize and token URLs plus the scopes it requests, and the deployment supplies the app those URLs authenticate against. Register this exact callback as an allowed redirect URI on the vendor side, built from the deployment's `SITE_URL` and any `BASE_PATH` prefix: ```text ${SITE_URL}${BASE_PATH}/api/connectors/oauth2/callback ``` The client ID and secret for each connector come from the deployment environment, named per connector as `CONNECTOR_OAUTH__CLIENT_ID` and `CONNECTOR_OAUTH__CLIENT_SECRET`, with the slug upper-cased and its dashes turned into underscores. When `SITE_URL` is unset the consent flow refuses to start rather than guessing an origin from the request. The redirect URI has to match byte for byte — scheme, host, path, and no trailing slash. A mismatch fails at the vendor's consent screen with a `redirect_uri` error before Tale ever sees the callback, which is the single most common reason a fresh OAuth connector will not connect. ## Choosing a surface Two surfaces reach systems outside Tale, and the choice is about who owns and runs the bridge. | Surface | Reach for it when | | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | Shipped connector | A connector already exists for the target system. Your work is a credential, and the vendor contract is maintained for you. | | MCP server | Nothing shipped covers the system — an internal API, a homegrown tool, a host only your network can reach. You write and run the process. | An MCP server is registered under **Settings > API > MCP**, and every tool it exposes joins the agent toolbelt beside connector actions, each with its own approval flag. The reference is [MCP servers](/platform/connectors/mcp-servers); the end-to-end build is [MCP server from scratch](/tutorials/developer/mcp-server-from-scratch). ## Where this fits A connector is a declared contract — hosts, authentication, and a typed action list — that ships with the platform and is fed by credentials the organisation owns. Read [Connectors](/platform/connectors/overview) for what is in the catalog, [Connector credentials](/platform/admin/connectors) for how those credentials are managed day to day, and [MCP servers](/platform/connectors/mcp-servers) when the bridge you need has to be your own code. # Contributor setup Source: https://tale.dev/docs/develop/contributor-setup This page is for contributors who want to run Tale from source and ship a change back. It covers the prerequisites, the one-time setup, the pre-flight check that catches a broken machine before a long boot, and what to expect from `bun run dev`. It is not the operator path — if you want to run Tale to use it, not change it, the [self-hosted quickstart](/self-hosted/install/quickstart) installs the packaged stack with the CLI instead. The source is one Bun workspace, end to end — the whole stack is TypeScript, with no Python and no second package manager to install. A single `bun install` wires up every service, and `bun run dev` boots the platform with a local Convex backend, generated dev secrets, and Vite — no cloud account, no hand-edited `.env`. Knowledge work that used to live in standalone services (RAG search, document ingestion, web crawling, document generation) now runs inside the Convex backend, so there is nothing extra to start for it. ## A working setup, start to finish The shortest path from a fresh clone to a running app is four commands. The pre-flight check between install and dev is the one that saves you a confusing failure ten layers deep: ```bash bun install # wire up every workspace bun run setup:check # validate Bun, the dev ports, and the Convex CLI bun run dev # boot Convex + Vite (watch for the READY banner) ``` If `setup:check` prints all green and `bun run dev` reaches its `READY` banner, your environment is sound. The rest of this page explains each piece and what to do when one of them complains. ## Prerequisites Only one tool has to be on your `PATH` before anything else, because the whole stack is TypeScript on a single runtime: - **Bun 1.3 or higher** — the workspace runtime and package manager. Install it from [bun.sh](https://bun.sh/docs/installation), then confirm with `bun --version`. Everything else the source needs (the Convex CLI, every service dependency) is resolved by `bun install`. You do not need Docker for local development with `bun run dev` — it spawns Convex directly on your machine. Docker only enters the picture for the containerised hybrid mode below and for the operator install. ## Install and pre-flight A single install covers every workspace, because the repo is one Bun workspace graph: ```bash bun install ``` Before the first `bun run dev`, run the pre-flight check. It validates your Bun version, that ports 3000 and 3210 are free, and that the Convex CLI is reachable — and prints the exact fix for anything missing, so you do not discover a wrong Bun version halfway through a cold boot: ```bash bun run setup:check ``` Each failing line carries its remediation: a `bun upgrade` for an old Bun, an `lsof`/`kill` pair for a busy port. A clean run exits zero and tells you to go ahead with `bun run dev`. ## What `bun run dev` does `bun run dev` is the development orchestrator. It loads your `.env` files, generates insecure local defaults for any secret you have not set, spawns a local Convex backend in anonymous mode, syncs the environment into it, runs Convex codegen, waits for the auth routes to answer, then starts Vite. The platform is the slowest server to come up because it waits on Convex, so a cold start takes 30 to 90 seconds. Until the orchestrator prints its `READY` banner, the app refusing connections on `http://localhost:3000` is expected, not a failure — Vite has not bound the port yet. When you see the banner, the app is reachable and auth is healthy. Stop the whole stack with `Ctrl-C`; it shuts down both Convex and Vite cleanly. The dev orchestrator generates everything it needs, so a local `.env.example` copy is optional for local development — the insecure defaults (`INSTANCE_SECRET`, `BETTER_AUTH_SECRET`, the WebDAV HMAC key) are filled in at boot and printed as warnings. Set real values in `services/platform/.env.local` only when you need production-shaped behaviour or want to override a default. ## When a port is busy `bun run dev` binds two ports: 3000 for the Vite app and 3210 for the local Convex backend. It fails fast with an actionable message when either is taken, because a silent fallback to another port would break the Convex proxy and every `localhost:3000` link. The usual culprit is a previous `bun run dev` or `tale dev` that did not fully exit. Free the port and re-run. The command that finds and stops the holder is the same one `setup:check` and the orchestrator suggest: ```bash lsof -nP -iTCP:3000 -sTCP:LISTEN # show the PID holding the app port kill # stop it ``` To run the app on a different port instead, set `PORT`: `PORT=3005 bun run dev`. If the Convex deployment itself gets into a bad state after automatic maintenance — a stale schema after an aborted migration, a corrupt local SQLite file — see [Resetting local Convex dev data](#resetting-local-convex-dev-data) below; do not delete `.convex/local/` casually. ## Convex local storage maintenance Every `convex dev` push stores a new function-bundle blob under `services/platform/.convex/local/default/convex_local_storage/modules/`. The Convex CLI never garbage-collects old blobs locally, so months of daily dev can accumulate tens of thousands of files (10+ GB) and make cold starts fail inside the CLI's 30-second backend-ready window. `bun run dev` runs maintenance automatically before it spawns Convex: - **Prune** when module storage exceeds 1,500 blobs or 2 GB — deletes only unreferenced historical function-bundle blobs under `convex_local_storage/modules/`, keeping every blob the current deployment still loads (module source packages and their node `externalPackageId` deps parents, plus up to 1,000 newest unreferenced leftovers). Your SQLite database, uploaded files, and org config are untouched. If the deployment's live references can't be read, or look empty while blobs remain on disk, prune is skipped rather than guessing. - **Integrity gate** — if a live module blob is already missing on disk, `bun run dev` stops with a clear error pointing at `setup:clean`. Continuing would boot into a half-dead backend (chat and crons fail with opaque server errors). - **Clear snapshot export artifacts** when the cached Convex backend binary no longer matches the one recorded in your local deployment — removes `export.zip` and related import/export debris that can trigger a failed re-import on cold start, without wiping dev data. Set `TALE_DEV_SKIP_CONVEX_MAINTENANCE=1` to opt out of prune/snapshot cleanup (the integrity gate still runs). `bun run setup:check` warns (non-blocking) when module storage is already over the prune threshold. ## Resetting local Convex dev data Last resort only — `bun run setup:clean` wipes **all** local Convex dev data: every table in the local SQLite file, every upload in `convex_local_storage/files/`, and every function bundle. Org config on disk and `.env.local` are untouched. **Crossing the 0.4 baseline:** local dev data and per-org config trees created by pre-0.4 checkouts have no migration path — the 0.4 baseline reset emptied the migration history, and the export/import round trip below cannot bridge it either (the old export does not match the new schema). Moving a dev machine across the baseline means resetting local Convex data and recreating your dev orgs; treat pre-0.4 `$TALE_CONFIG_DIR` org directories the same way. **Keep your data across the reset.** Even when the integrity gate fires (a live module bundle is missing), the backend itself still starts — so you can export your data first and restore it afterwards, and the reset then loses nothing: ```bash # 1. Start the backend (this bypasses the `bun run dev` integrity gate), then # export in a second terminal: bun run --filter @tale/platform convex:dev cd services/platform && npx convex export --path convex-backup.zip # 2. Reset (guarded — see below), bootstrap a fresh deployment, then restore: bun run setup:clean # type: delete local convex bun run dev # wait for the READY banner cd services/platform && npx convex import --replace-all convex-backup.zip ``` `bun run setup:clean` is guarded on purpose (coding agents must not run it unless you explicitly asked): 1. Run it yourself in a terminal — not through an agent. 2. When prompted, type the exact phrase `delete local convex` (a bare `y` is rejected). 3. Non-interactive runs (CI) require `TALE_CONFIRM_DESTROY_LOCAL_CONVEX=delete-local-convex` — never set that in agent shells. Try automatic maintenance and a normal `bun run dev` first. If you must reset, **export first** (above) to keep your data — only skip the export when you truly don't need the local conversations, uploads, and other anonymous-deployment state. ## Hybrid mode against a containerised Convex `bun run dev` spawns an ephemeral Convex backend by default, which is the right thing for most work. When you want fast Vite reloads against a stable Convex that mirrors production, run the dedicated `convex` container and point Vite at it instead: ```bash docker compose up convex # one terminal: the stable backend CONVEX_EXTERNAL=true bun run dev # another: Vite against the container ``` Set `CONVEX_URL` if your container exposes Convex on a non-default host or port. This is the only local-dev path that needs Docker, and it is optional — the default ephemeral backend needs nothing beyond the three prerequisites. ## Before you open a PR Every PR runs through one gate: `bun run check`, which is format, lint, typecheck, and the full test suite across every touched workspace. A green run is the merge signal; a red one blocks. The pre-PR checklist in [`AGENTS.md`](https://github.com/tale-project/tale/blob/main/AGENTS.md) lists the rest — docs and translations ship in the same PR as the code that changed them. If your change touches `services/docs/`, also run the docs gate (`bun run --filter @tale/docs test`) so structural parity, terminology, and prose checks pass before review. Anything a user can see, configure, or call needs its docs updated in all three base locales in the same commit. ## Where this fits Contributor setup is the floor every other developer task stands on: get the prerequisites in place, let `setup:check` confirm the machine, and `bun run dev` gives you the whole platform with a local backend in under two minutes once the images are warm. The pre-flight check and the port remediation exist because the most common first-run failures are a wrong tool version or a leftover process holding a port — both are five-second fixes once you can see them. Once the stack runs, the [Develop overview](/develop/overview) frames the external surface you build against, and [AI-assisted development](/develop/ai-assisted-development) covers using Tale's own agents to author Tale configs. If you are contributing a container change rather than a source change, [Contributing](/self-hosted/contributing-docker) under the Self-hosted tab is the build-and-test walk for that path. # MCP endpoint Source: https://tale.dev/docs/develop/mcp-endpoint Tale is itself an MCP server. Point any MCP client — an agent harness, an IDE, your own SDK loop — at one endpoint and it can author and operate automations, search what the organization can do, invoke a capability, and retrieve knowledge, with the same API key the REST surface takes. Where REST is the connector seam for your code, the MCP endpoint is the seam for _models_: every tool answers text a model can read and act on. Read this to connect a client and understand the tool inventory. The grammar for authoring automations is deliberately not duplicated here — the endpoint teaches it itself through `get_docs`. ## Connect a client The endpoint speaks MCP protocol `2025-03-26` as JSON-RPC over HTTPS — plain JSON responses, no SSE stream, one message per request (a batch answers error `-32600`). Authenticate with an organization API key ([API keys](/platform/admin/api-keys) covers minting one): ```json // POST https://your-host.example.com/api/v1/mcp // Authorization: Bearer tale_... { "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {} } ``` The server identifies as `tale-platform`. In a client that takes a config block, that is all you need: ```json { "mcpServers": { "tale": { "url": "https://your-host.example.com/api/v1/mcp", "headers": { "Authorization": "Bearer tale_..." } } } } ``` `tools/list` returns the full inventory; `GET` on the endpoint answers **405** — there is no event stream to subscribe to. ## The tools Twenty-two tools, in three groups. The authoring tools take whole automation documents and validate everything themselves — their schemas are open on the wire, and `get_docs` is the reference a model reads first. The management and capability tools take simple arguments and declare real JSON schemas. ### Authoring | Tool | What it does | | --------------------- | ---------------------------------------------------------- | | `get_docs` | The automation grammar and authoring guide, as text. | | `get_catalog` | Every node type this deployment can execute. | | `search_catalog` | Search the node-type catalog by keyword. | | `validate_automation` | Validate an automation document without saving it. | | `run_automation` | Run an automation document directly (mock or live mode). | | `test_automation` | Run an automation's own acceptance tests. | | `save_automation` | Save an automation document as a new immutable version. | | `get_automation` | Read one saved version (the latest when unversioned). | | `list_automations` | The organization's automations with their latest versions. | | `deploy_automation` | Promote one saved version to be the live version. | ### Run & trigger management | Tool | What it does | | ---------------- | -------------------------------------------------------------------------------------------------------------- | | `run_deployed` | Run the deployed version and WAIT for the finished result — output, trace and effects in one answer. | | `start_run` | Start the deployed version in the background and return a run handle immediately; poll get_run for the result. | | `list_runs` | Recent runs, newest first — of one automation or of the whole organization. | | `get_run` | One run in full: status, output, trace and effects. | | `cancel_run` | Stop a run at its next node boundary. | | `list_versions` | One automation's immutable version history. | | `list_triggers` | What starts the automations (never the webhook secret). | | `delete_trigger` | Unbind an automation's trigger; its versions and run history stay. | | `set_trigger` | Bind what starts the automation (schedule/webhook/event). | Pick `run_deployed` when the automation is quick and you want one call with the answer in it. Pick `start_run` when the run may take minutes — it returns a `runId` immediately, and `get_run` polls it. Both run live. `start_run` also takes an optional `projectId` — the project the run operates in, so its task and document tools act there. Omit it for an organization-wide run, or, when the automation is bound to a single project, that one. A bound automation accepts only a project it is bound to. ### Capabilities & knowledge | Tool | What it does | | --------------------- | ------------------------------------------------------------------------------------------------------------------- | | `search_capabilities` | Search everything this organization can do — its automations, connector actions, skills and tools. | | `invoke_capability` | Invoke one capability by id. An action the organization gates returns a pending-approval result instead of running. | | `get_knowledge` | Retrieve passages from the organization's knowledge — its documents and its crawled web pages. | This is the same registry a chat turn sees: one namespace over builtins, connector actions, skills, automations, and connected MCP tools. A capability the organization gates behind approval does not silently run — `invoke_capability` answers a pending-approval result the model can relay. ## What the key may do The key proves who is calling; the key holder's role decides what the call may do, exactly as in the product: - **Any member key** — every read tool, `run_automation` in mock mode, `search_capabilities`, `get_knowledge`. - **Developer capability required** — `save_automation`, `deploy_automation`, `set_trigger`, `delete_trigger`, `cancel_run`, and live execution (`run_deployed`, `start_run`, `run_automation` in live mode). A refused call is not a protocol error: the tool answers a readable refusal — `{"error": "...", "hint": "..."}` — so the calling model can adjust instead of crashing. That convention holds everywhere: validation problems, missing deployments, and role refusals all come back as data; `isError` is reserved for a call that actually threw. ## Where this fits The MCP endpoint and the [REST API](/develop/api-reference) are one surface with two dialects — same key, same organization scoping, same run objects (`start_run` here and `POST .../runs` there produce the same durable run). Building an MCP server of your own that Tale consumes is the opposite direction — that is [MCP servers](/platform/connectors/mcp-servers) under connectors. # Develop Source: https://tale.dev/docs/develop/overview Develop is the section for integrators and contributors — anyone wiring Tale into another system, building on top of the API, or shipping a change to the source. The pages here describe the external surface (REST, webhooks, OpenAI-compatible endpoints) and the contributor workflow. If you are inside the product as a Developer-role user (building agents, workflows, custom tools), the Platform tab covers your day to day; Develop is for when you are outside the product, talking to it across the wire. Prefer to watch first? The bonus episode walks the developer surface — keys, APIs, webhooks, harnesses — in two minutes. ## Pages in this section Endpoints, authentication, OpenAI-compatible endpoints, error model, versioning. Outbound (Tale → you) and inbound (you → Tale), signing, idempotency, retries. Using Tale agents to author Tale workflows, the `.agents/` skill files. Third-party connectors from a developer perspective. Cloud incident reporting, self-hosted metrics pointers. Per-key, per-IP, per-org limits and how to interpret 429s. ## Where this fits Develop is the smallest section because most users never need it; the audience is concentrated in two roles (in-product Developer, out-of-product contributor) but it is load-bearing for both. If you are wiring something external to Tale, [API reference](/develop/api-reference) is the first read; if you are contributing to the source, [Contributing](/self-hosted/contributing-docker) — under the Self-hosted tab — is. # Rate limits Source: https://tale.dev/docs/develop/rate-limits The API is rate-limited per key with token buckets: bursts pass, sustained hammering answers **429**. The budgets are sized so a normal connector never sees them — when a previously healthy client starts hitting 429, the answer is almost always a missing backoff or a hot loop, not missing capacity. Read this when you are wiring a client that calls the API on a schedule or under load. ## The buckets | Surface | Budget | Burst | | ----------------------------------------------------------------------------------------------- | ------------------ | ----- | | Reads and CRUD — every `/api/v1` endpoint not listed below, including `POST /api/v1/mcp` | 120 requests / min | 200 | | Starting work — `POST /api/v1/automations/{name}/runs` and `POST /api/v1/threads/{id}/messages` | 20 requests / min | 40 | The second bucket is deliberately small: each of those requests costs a whole durable run or a model turn, not a database read. A token bucket refills continuously — the burst capacity absorbs a batch, then the sustained rate applies. ## The 429 An overrun answers the API's ordinary error envelope, with nothing to parse beyond the status: ```json { "error": "Rate limit exceeded" } ``` There are no rate-limit headers — no `Retry-After`, no remaining-budget counters. Back off blind: start at one second, double per consecutive 429, cap at sixty, and add jitter so concurrent workers do not retry in lock-step. Because starting a run answers **202** before the work happens, a lost response is cheap to detect — list the automation's recent runs before firing again rather than retrying writes on suspicion. ## Where this fits The [API reference](/develop/api-reference) names the 429 in the error model and points here. If your workload genuinely needs more than the budgets allow, batch on your side — `POST /api/v1/contacts/bulk` exists for exactly that — or spread the schedule; the buckets are per key, so two keys do not share a budget. # Status page Source: https://tale.dev/docs/develop/status-page The status page is the canonical record of Tale Cloud availability. Each rotatable service has its own status row, incident history is kept for the audit trail, and the page is the channel Tale uses during an incident — before email goes out, before support tickets are answered, the page is updated. Read this when something is misbehaving and you want to know whether it is just you. Subscribe to the feed when you are responsible for the connector on your side — the page tells you which service degraded so you can route the alert to the right team without waking the wrong on-call. ## A worked subscription The status page is at `https://status.tale.dev`. Subscribing takes one URL: ```bash curl -sS https://status.tale.dev/history.rss ``` The RSS feed carries every state change — open, update, resolved — for every service. Email subscription is the same one-click form on the page; the email channel ships the same events with a five-minute debounce. ## Scope per service | Service | What it covers | When it goes red | | ---------- | ---------------------------------------------------------------------------------- | ------------------------------------------------ | | `platform` | The TanStack Start + Convex application — agents, workflows, connectors, UI. | UI unreachable; API returns 5xx; auth broken. | | `rag` | The Python FastAPI document-processing service — indexing, retrieval. | Document uploads stall; retrieval is empty. | | `crawler` | The Crawl4AI web-extraction service — used by document ingest and Tavily fallback. | Web-pulled documents fail; deep research stalls. | | `proxy` | The Caddy edge — TLS termination, HTTP routing. | All Tale Cloud traffic affected. | | `db` | TimescaleDB — durable state for the Convex layer and platform metadata. | Writes refused; the platform row also goes red. | Each row carries the last 90 days of uptime as a sparkline. An incident reads as a coloured band on the row; clicking the band opens the timeline — first update, follow-ups, resolution, post-mortem when one is owed. ## Incident history History is kept indefinitely. Each incident records the affected services, the customer impact statement, the timeline, and the post-mortem when the incident crosses the severity threshold that obliges one. The threshold is published on the page itself; the rule of thumb is anything with cross-org customer impact and a duration above 30 minutes. The page is owned by the on-call rotation. Updates are pushed by the engineer holding the page, not by an automated system — the choice is deliberate, because the page is also the document that goes to customers and auditors after the fact. ## Self-hosted: what changes Self-hosted instances do not appear on `status.tale.dev` — that page covers Tale Cloud. Each deployment ships its own status page instead, served by the platform and reachable without signing in at `https:///status`. It renders a server-side health summary — operational, degraded, or outage — from a liveness probe against the Convex backend, so an operator (or an end user checking whether it is just them) can read availability without a login. The machine-readable form is `https:///status.json`, which returns the same result as JSON for an uptime monitor to poll. That page reports the availability of the deployment itself. For deeper operational signal — container health from `tale status`, request metrics from the Caddy logs, and control-plane events in the in-product audit log — the [observability troubleshooting page](/self-hosted/operate/observability/troubleshooting) maps symptoms to logs. ## Where this fits The status page is the operational channel; [Trust and compliance](/cloud/trust-and-compliance) is the audit channel and lists the page as evidence for the infrastructure-availability control. If you are wiring Tale into a pipeline and need the connector to react to a Tale outage, the RSS feed is the input; if you are reading this because something in your connector is failing right now, [API reference](/develop/api-reference) lists the error codes you should branch on. # WebDAV API Source: https://tale.dev/docs/develop/webdav-api Tale exposes the document store under `/dav//` as a read-write WebDAV Class 2 endpoint (RFC 4918). This page is the protocol reference — the wire-level surface a client implementer or a third-party tool needs to integrate. For the end-user setup guide and per-client instructions, see [Platform > Connectors > WebDAV](/platform/connectors/webdav). ## URL scheme ```text /dav//documents/ R/W active documents tree /dav//.trash/ R/O trashed documents (soft-delete view) /dav// R/O collection containing the two above ``` Segments are URL-encoded. The server rejects segments containing `/`, `\`, NUL, or the relative names `.` and `..`. Each segment must be 1–255 bytes. The `orgSlug` matches `[a-zA-Z0-9_-]{1,64}`. Trailing-slash policy follows WebDAV convention: collections (folders) are referenced with a trailing slash, resources (files) without. Many clients normalise on the fly; the server accepts both forms on lookup and emits the canonical form in PROPFIND responses. ## Authentication HTTP Basic only. The username field can be any non-empty value — the app-password itself is the actual credential, and the server does not match the username against your account record. Using your Tale account email is the convention for audit clarity, and clients that prefill from the keychain expect an email-shaped string, but the auth decision is made on the password alone. The password is an **app-password** generated under Settings > WebDAV. The user's main account password is not accepted on this endpoint. ```http Authorization: Basic ``` App-passwords are hashed with HMAC-SHA256 keyed by the server's `WEBDAV_APP_PASSWORD_HMAC_KEY` deployment secret. The key is derived deterministically from `INSTANCE_SECRET` by the platform entrypoint (prod) and `server.ts` (dev), so operators do not mint it manually; setting it explicitly in `.env` overrides the derived value. Lookup narrows by the password's first four characters (stored alongside the hash for indexed lookup) and verifies with a constant-time HMAC comparison. Every authenticated request also verifies the requesting user is an active member of the organisation in the URL — a stale row (membership removed after app-password issue) is rejected with `403`. `OPTIONS` is the only method allowed without authentication; clients use it to probe DAV capability before signing in. ## Methods | Method | Behaviour | Auth | | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | | OPTIONS | Advertise capabilities. Returns `DAV: 1, 2`, `Allow: …`, and `Microsoft-Server-WebDAV-Extensions: 1` for Windows compatibility. | Anonymous OK | | PROPFIND | List a resource (Depth 0) or a collection's immediate children (Depth 1). The property list emitted is documented below. **Depth: infinity is rejected with 403** to prevent unbounded responses. | Required | | PROPPATCH | Returns 207 success per-property without storing values. Dead properties are not persisted in v1; PROPPATCH succeeds optimistically for client compatibility. | Required | | GET / HEAD | Stream the document blob. Sets `Content-Type`, `Content-Length`, `ETag`, and `Last-Modified`. GET on a collection returns 405. | Required | | PUT | Create or replace a document. New blob is stored in Convex storage with content-hash dedup; the document row picks up `sourceProvider: "webdav"`. Returns 201 on create, 204 on overwrite. | Required | | DELETE | Soft-delete a document (sets `lifecycleStatus: "trashed"`) or a folder (cascades trash on contained documents, hard-deletes the folder rows). Returns 204. | Required | | MKCOL | Create a folder under an existing parent. Empty body only. Returns 201, 405 if the target exists, or 409 if the parent does not. | Required | | MOVE | Rename or relocate. Atomic for documents. For folders, updates the `parentId` of the moved folder. Honours `Overwrite: T/F` and `If` headers. Returns 201 (new destination) or 204 (overwrite). | Required | | COPY | Server-side copy. Document copies reuse the same Convex storage id (dedup). Folder copies recurse. Honours `Overwrite` and `If`. | Required | | LOCK | Class 2 exclusive or shared write-lock. Timeout from `Timeout: Second-N` header, capped at 3600. Refresh by re-sending LOCK with `If: ()` and an empty body. | Required | | UNLOCK | Release a lock by its token. Only the lock owner can release. Returns 204. | Required | `HEAD` shares its handler with `GET` minus the body. ## Properties PROPFIND returns these live properties for every resource: - `resourcetype` — `` on folders, empty on documents. - `displayname` — the folder name or document title. - `getlastmodified` — RFC 1123 timestamp. Documents use `sourceModifiedAt` if set, otherwise the document row creation time. - `creationdate` — ISO 8601 of the row creation time. - `getcontenttype` — documents only; the MIME type the document was uploaded with. - `getcontentlength` — documents only; bytes. - `getetag` — documents only; the content hash if known, otherwise the document id. - `supportedlock` — advertises exclusive write-lock support. - `lockdiscovery` — present on resources with active locks. Dead properties are not stored. PROPPATCH echoes 200 for a dead property set on its own, but setting a live/protected property returns a per-property 403 (`cannot-modify-protected-property`), and any dead properties in the same request are then reported as 424 Failed Dependency (RFC 4918 §9.2 atomicity). No value is ever persisted. ## Lock semantics Locks live in their own Convex table, keyed by `(organizationId, resourcePath)`. Wire form is `opaquelocktoken:`. The server: - Caps timeout at 3600 seconds. Requests for longer windows are clamped silently. - Treats `LOCK` with an `If: ()` header and an empty body as a refresh — the existing lock's expiry is bumped. - Returns `412 Precondition Failed` on a refresh when the supplied token is unknown. - Returns `423 Locked` on `PUT / DELETE / MOVE / COPY / MKCOL / PROPPATCH` against a locked path when the request lacks a matching `If` header. - Returns `412 Precondition Failed` when the supplied `If` token does not match the live lock. - Expires locks lazily — the lookup query returns null for expired rows and schedules a fire-and-forget delete. - Hard-deletes every lock owned by an app-password when that app-password is revoked. `UNLOCK` requires both a valid `Lock-Token` header and the requesting user to be the lock owner. ## Status codes - `200` — OPTIONS, GET, HEAD, LOCK, LOCK refresh, PROPPATCH (per-property) - `201` — PUT create, MKCOL, MOVE/COPY to a new destination - `204` — DELETE, UNLOCK, PUT overwrite, MOVE/COPY overwrite - `207` — PROPFIND, PROPPATCH (multi-status envelope) - `400` — malformed `Destination` / `If` / `Lock-Token` / `Timeout` header - `401` — missing or invalid Basic auth - `403` — Depth: infinity rejected; .trash write attempt; root delete/move; wrong app-password owner on UNLOCK; user not a member of the org; MOVE/COPY onto itself or into its own subtree; cross-org `Destination` - `404` — resource not found - `405` — GET on a collection; PUT to a collection path; MKCOL on existing path; root MKCOL - `409` — MKCOL, MOVE, or COPY when the destination parent does not exist - `412` — `If` token mismatch; `If-Match` / `If-None-Match` precondition failed; MOVE/COPY with `Overwrite: F` onto an existing destination - `413` — PUT body over the size cap, or an XML request body (PROPFIND / PROPPATCH / MKCOL / LOCK) over 64 KB - `415` — MKCOL with non-empty XML body (extended MKCOL not implemented) - `423` — write attempted on a locked path without matching `If` - `502` — cross-host `Destination`; storage proxy fetch failed - `503` — LOCK count cap exceeded for the app-password (with `Retry-After`) - `507` — folder subtree too large to delete, move, or copy in a single request ## Compliance - DAV Class **1** (basic): full. - DAV Class **2** (locking): full, with the lazy-expiry behaviour described above. - DAV Class **3** (calendaring, contacts, search, ACL): not implemented. The server advertises `DAV: 1, 2` in the OPTIONS response. ## Limits - `Depth: infinity` on PROPFIND is rejected with `403`. - `Timeout: Second-N` on LOCK is clamped to `[1, 3600]`. - PUT body size is capped at **5 GB** by default (`413` once exceeded), enforced both at the reverse proxy and in the platform server. Operators can raise or lower it with the `WEBDAV_MAX_PUT_BYTES` environment variable. The body is streamed to a Convex presigned URL with backpressure, so a large upload does not buffer in platform memory. - XML request bodies (PROPFIND / PROPPATCH / MKCOL / LOCK) are capped at **64 KB** (`413` once exceeded) — these envelopes are tiny by design. - App-passwords are hashed with HMAC-SHA256; the secret never appears in any response after the create call. - `lastUsedAt` is patched at most once per minute per app-password to avoid write storms on busy mounts. ## Network requirements The WebDAV endpoint runs inside the platform Hono server (`platform:3000` in compose). Caddy routes `/dav/*` to it via the default fallback — no extra configuration is required. The path requires the platform server to have `ADMIN_KEY` set in its environment so it can call internal Convex queries with admin auth. For dev (`bun dev`), the same dispatch is mounted as a Vite middleware (`vite-plugins/serve-webdav.ts`) — `curl` and clients can hit `http://localhost:3000/dav//...` against a running dev server without rebuilding. ## Security WebDAV ships the app-password on every request as an HTTP Basic header — there is no session, no token refresh, just the raw credential replayed on every PROPFIND, PUT, LOCK, and so on. Only mount the endpoint over HTTPS; running it over plain HTTP leaks the password to anyone on the wire, and revoking the row is the only way to recover. Never put the app-password into the URL itself (the `https://user:pass@host/...` shorthand) — most clients log URLs in shell history, crash reports, and proxy access logs, where the credential would survive long after the mount was unmounted. Let the WebDAV client store the password in the OS keychain (macOS Keychain, Windows Credential Manager, GNOME Keyring) and surface it through the standard credential prompt instead. The server enforces TLS at the reverse proxy layer in production deploys; dev mode over plain HTTP is only intended for `localhost` testing. Audit logs record every authenticated request with the prefix of the password used, so a leaked credential can be traced and revoked without rotating the rest of the device fleet. ## Where this fits WebDAV is the mount-protocol surface of the same document store the [REST API reference](/develop/api-reference) drives for bulk import and search — both routes write into the table the [Document Hub](/platform/knowledge/documents) reads from, so a file created through Finder appears in the web UI without any sync step. The protocol is the right pick when a user wants their documents to feel like a local folder; the REST API is the right pick when a script or agent wants byte-level control over what gets written and when. RFC 4918 is the wire-level authority for everything on this page. # Webhooks Source: https://tale.dev/docs/develop/webhooks A webhook trigger turns a POST from your system into a run of a deployed automation — no API key, no SDK, just a URL that Tale mints when you bind the trigger. It is the right seam when the caller is a third-party product (a payment provider, a form tool, a CI job) that can only fire an HTTP request at a URL you give it. Read this when you are wiring an external system to start automations. For calls where you want a value back or you hold an API key, the [API reference](/develop/api-reference) is the synchronous half. ## A worked trigger Bind a webhook trigger to an automation — in the automation's editor, or with `PUT /api/v1/automations/{name}/triggers` and `{"kind": "webhook"}` — and Tale answers with the trigger URL's token, once. Then any system can start a run: ```bash curl -sS -X POST "https://your-host.example.com/api/automations/webhook/" \ -H "Content-Type: application/json" \ -d '{ "orderId": "12345", "amount": 199.0 }' # → 202 { "runId": "..." } ``` The body becomes the run's input. A body that is not JSON is handed through as text rather than refused — some vendors send plain text — and anything over 256 KB is rejected with **413**. Poll the run like any other via `GET /api/v1/runs/{runId}` with an API key, or watch it in the product. The full response vocabulary: - **202** `{ "runId": "..." }` — the run started. - **404** — unknown, disabled, or mistyped token. The response never distinguishes the cases, so a guesser learns nothing. - **409** `{ "error": "automation has no deployed version" }` — deploy a version whose tests pass and the same call runs. - **413** — the body exceeds 256 KB. ## The token is the credential There is no signature and no Authorization header: the token in the URL is the whole credential, so treat the URL like a password. Tale stores only a hash and compares in constant time; the plaintext exists exactly once, in the response that minted it. Lost or leaked the URL? Rotate it — `PUT /api/v1/automations/{name}/triggers` with `{"kind": "webhook", "rotateToken": true}` mints a fresh token and answers it once; the old URL dies immediately. Unbinding the trigger (`DELETE .../triggers`, or in the editor) revokes it entirely; the automation's versions and run history stay. ## Idempotency and retries The trigger endpoint does not de-duplicate: a retried POST starts a second run. What makes retries safe is the run itself — a live run checkpoints every completed node, so a run that resumes after an interruption never repeats a side effect it already produced. Where a _duplicate run_ would still be wrong, carry your own de-duplication key in the payload and branch on it in the automation's first node. Retrying is the caller's responsibility: the response tells you whether the run _started_, not whether it succeeded. A sensible caller retries non-2xx responses with backoff and treats 202 as done. ## Where this fits The webhook is the credential-less way in; everything else goes through an API key. The [Triggers page](/platform/automations/triggers) covers the product side — schedules, events, and webhooks as the automation editor presents them. The [API reference](/develop/api-reference) covers starting runs with a key (`POST /api/v1/automations/{name}/runs`), which is the better seam when the caller is your own code. # Your first day running a workspace Source: https://tale.dev/docs/get-started/admins This journey is for the person accountable for the workspace. In fifteen minutes you create the organization, connect the provider that makes chat answer, bring in your first teammates, and learn where the governance controls live before you need them. You need an account on a running instance ([quickstart](/get-started/quickstart)); on a brand-new instance the first account is automatically the **Owner**, which carries every permission below. If you arrived via the quickstart, your organization already exists — skip to connecting a provider. A fresh sign-in without one lands on the creation wizard: the **Organization name** is the display name your team sees in the corner of every page — pick something that survives a rebrand. The wizard then offers to connect an AI provider and finishes on the dashboard. ![The create-organization wizard on its workspace step, with Northlight Labs typed into the Organization name field and the Next button enabled.](/images/get-started/org-create-wizard.webp) Nothing answers until a provider is connected. If you skipped the wizard's provider step, open **Settings > AI providers** and click **Add credential** on a connector — an [OpenRouter](https://openrouter.ai) key reaches the widest model catalog, and every direct vendor ships its own connector beside it. A credential is usable the moment it is saved; from then on every agent in the workspace can answer with any model that connector exposes. ![The AI providers settings page listing one connected provider, OpenRouter, with its base URL and a count of 52 models.](/images/get-started/settings-providers.webp) To add people, open **Settings > Organization**, scroll to the **Members** section, and click **Add member**. Each person lands with a role that bounds what they can do: **Member** reads and chats, **Editor** builds agents and knowledge, **Developer** wires up workflows, automations, and API access, **Admin** runs the workspace. Start people low — raising a role later is one click, and un-leaking access is not. ![The Organization settings page with its Members section listing the workspace owner Alex Rivera and an Add member button.](/images/get-started/settings-organization-members.webp) A teammate who signs in and gets an answer in chat proves the whole chain — account, role, provider — without you standing next to them. You will not need policies on day one, but you should know the door: **Settings > Governance** holds audit logs, usage analytics, content policies, guardrails, and retention. The one habit worth starting today is skimming [audit logs](/platform/admin/governance/audit-logs) after the first week — it shows you what your workspace actually does. ## Where you are now The workspace stands: a provider answers, the team is in with bounded roles, and you know where the controls live. The full permission matrix is [Members and roles](/platform/admin/members-and-roles); [Admin overview](/platform/admin/overview) maps every pane you now own; and when compliance asks, [governance](/platform/admin/governance/audit-logs) is the section you show them. # Your first day integrating with Tale Source: https://tale.dev/docs/get-started/developers This journey is for the person wiring Tale into other systems. In ten minutes you mint an API key, make your first authenticated request, and know which door to knock on for chat, workflows, and documents. You need the **Developer** role or higher (the API settings are hidden below it) on a running instance — [quickstart](/get-started/quickstart) if you have none. Replace `your-host.example.com` below with your instance's host. To get a credential your scripts can hold, open **Settings > API > REST** and click **Create API key**. Name it for the system that will use it — keys are listed by name, and a year from now "zapier-bridge" beats "test". The key value shows once, on creation; store it in your secret manager, not in code. ![The REST API keys settings page listing two keys — Production ingest and CI pipeline — each showing only its key prefix, the date it was added, and a Never used marker, beside a Create API key button.](/images/get-started/settings-api-keys.webp) The shortest useful call lists the agents your key can see. The key rides as a bearer token; the workspace context is inferred from the key itself: ```bash curl -sS https://your-host.example.com/api/v1/agents \ -H "Authorization: Bearer $TALE_API_KEY" ``` A JSON array of agents — including the built-in Assistant — proves the key, the header, and the route. A `401` means the token header is malformed or the key was revoked. ## The rest of the surface Everything else is variations on that request. Automations run by name over `POST /api/v1/automations//runs` with the same Bearer key — answered 202, polled via `/api/v1/runs/` — or fire from outside over webhook URLs of the form `/api/automations/webhook/`, where the token in the URL is the credential. Chat is a thread, a posted message, and a poll; documents upload over `/api/v1/documents`; and the same key opens the [MCP endpoint](/develop/mcp-endpoint) for model-driven clients. The [API reference](/develop/api-reference) is the complete inventory with auth, shapes, and limits. ## Where you are now You hold a working credential and have seen the request shape every endpoint shares. From here, [call Tale from a script](/tutorials/developer/call-tale-from-a-script) turns the curl into a real connector, [trigger an automation via webhook](/tutorials/developer/trigger-automation-via-webhook) covers the push direction, and the [MCP endpoint](/develop/mcp-endpoint) is the same platform for MCP clients. # Your first day building agents Source: https://tale.dev/docs/get-started/editors This journey is for the person who turns "the team keeps asking the same questions" into an agent that answers them. In fifteen minutes you create an agent, shape how it behaves, and watch it do real work on a task — the loop every later agent refines. You need the **Editor** role or higher (the Agents section is hidden from members) on a workspace where chat already answers — that is the [quickstart](/get-started/quickstart). To start an agent teammates can put to work, open **Agents** in the sidebar and click **Create agent**. Name it for the job, not the technology — "Support Triage" beats "GPT Helper" — because the name is what teammates assign tasks to later. The editor opens on the **General** tab: the display name teammates see and a one-line description. The setting that matters on day one is the visibility — it decides who in the organisation may put the agent to work. Open **Instructions** — the knob that matters most. Write one paragraph as if briefing a new colleague: the voice to answer in, the domain it owns, and the cases it should refuse. Concrete beats complete — you will refine after seeing real replies. Click **Save**; the agent is reachable from the next request, with no separate publish step. Agents do their work on tasks — chat runs the built-in assistant only. Open a project, add your agent under its **Agents** tab, then create a task that states the work in one sentence and assign it to the agent. Start the run and watch its timeline; the result comes back for your review, and only you can mark it done. A result that follows the voice and scope you wrote means the instructions bind — the agent is real. ## Where you are now You have shipped the smallest real agent: instructions and a place in the org's roster. The full model behind what you touched is [Agent concepts](/platform/agents/concepts) — instructions, knowledge, tools, and skills. The natural next build is [your first agent end to end](/tutorials/editor/first-agent-end-to-end), which adds knowledge bindings and a real domain; after that, [agents with knowledge](/tutorials/editor/agent-with-knowledge) and [delegation between agents](/tutorials/editor/delegate-between-agents) take the same loop further. # Your first day using Tale Source: https://tale.dev/docs/get-started/members This journey is for everyone who uses Tale rather than configures it. In fifteen minutes you chat with an agent, add a document the whole workspace can draw on, and learn where shared work lives — the three moves that cover most days. You need a signed-in account on a workspace where chat already answers — that is the [quickstart](/get-started/quickstart). Chatting and browsing work with the **Member** role; the two write moves below (uploading a document, moving a task) need **Editor** or higher — if a button is missing for you, that is the role boundary, not a broken workspace. You already sent a first message in the quickstart — this time watch what the agent does with it. Click **New chat**, ask something from your actual work, and expand the collapsible tool-call boxes above the reply: they show what the agent read or ran before answering. When the answer should come from a document, upload it under **Knowledge** first — the assistant searches the organisation's documents and cites what it used. The next step covers that upload. Knowledge persists across every chat and cites itself in the answers. To make a document available to every agent and teammate, open **Knowledge > Documents** and click **Upload documents**, then **From your device**, pick the file, and click **Upload**. The document appears in the table and is indexed in the background — once indexed, agents cite it in their answers. The upload menu appears for Editors and up; with the Member role you read and search the library, and hand the file to an Editor to add. ![The Knowledge Documents table listing three uploaded text files with their indexing status.](/images/get-started/documents-list.webp) Ask a new chat a question only your document can answer. A reply citing the document proves the index works end to end. Open **Projects** in the sidebar. A project bundles everything about one effort — tasks on a board, shared files, project chats, and its own agents. Open a project and switch between **Board** and **List** on the Tasks tab; with edit access (Editor and up) you drag a task between columns to update its status, and the card staying in its new column after a reload means the change persisted for everyone. ![A project task board titled Website relaunch with seven task cards spread one or two per column across Backlog, To do, In progress, In review, Done, and Cancelled.](/images/platform/projects-task-board.webp) Chats never disappear silently. Click **Show chats** above the chat to open the history sidebar — every chat you can resume in this workspace, newest first. Renaming a chat gives it a title that survives; deleting one moves it to the workspace trash rather than destroying it. ## Where you are now You can chat, feed the workspace knowledge, and navigate shared work — the member's daily loop. The natural next reads are [Chat basics](/platform/chat/basics) for the mental model behind the chat, and [Use projects](/tutorials/member/use-projects) for a deeper project walkthrough. When you are ready to build an agent of your own, switch to the [editor journey](/get-started/editors). # Quickstart Source: https://tale.dev/docs/get-started/quickstart This is the shortest path to a working chat with an agent: get an instance, sign in, send a message, watch the reply stream. It takes about five minutes on a ready instance and fifteen if you stand one up on your own machine, and it ends with the screen below — a real answer from an agent over your workspace. ![A chat thread showing a user question about onboarding feedback and an assistant reply containing a markdown table of three themes.](/images/platform/chat-thread-reply.webp) Prefer the tour as a video? Episode 1 walks the same ground in three minutes — captions included. ## Get an instance The two editions run the same product — pick by who should operate the stack. With [Docker](https://www.docker.com/products/docker-desktop) running, three commands stand up the whole stack on your machine: ```bash curl -fsSL https://raw.githubusercontent.com/tale-project/tale/main/scripts/install-cli.sh | bash tale init my-project && cd my-project tale dev ``` The first run pulls images — expect five to ten minutes. When the browser opens, sign up: the first account claims the **Owner** role and creates your organization. The [self-hosted quickstart](/self-hosted/install/quickstart) covers every step in depth, including Windows and troubleshooting. Cloud instances are set up for you: fill in the [demo request form](https://tale.dev/request-demo) and the Tale team provisions your own instance. Once it is ready, open it and sign up — the form asks for your name, email, and a password; verify the email link when it arrives, name your organization, and you land in the dashboard. The setup wizard offers to connect an AI provider right away — paste an [OpenRouter](https://openrouter.ai) key there and chat works immediately. The [admin journey](/get-started/admins) walks the same wizard with screenshots when you want more than the happy path. ## Send your first message Click **New chat** in the sidebar. The composer at the bottom of the screen is where everything starts: the message field, and one picker naming the model the reply will come from. A model already showing on the picker means you are ready to send — the assistant itself is built in, so there is nothing else to choose. Pick any chat model from the picker — every reply comes from the model you named, so nothing is chosen for you behind the scenes. Type a question and send it. The reply streams in token by token; when the agent reasons before answering, a collapsible thinking line appears above the reply. A streamed reply that answers your question means the whole chain works — provider credential, model, and assistant. You have a working workspace. ## Where you are now You have a running instance and an agent that answers. The next fifteen minutes depend on your role: the [member journey](/get-started/members) covers documents and projects, the [editor journey](/get-started/editors) publishes your first specialist agent, the [admin journey](/get-started/admins) sets up the team and providers, and the [developer journey](/get-started/developers) gets you an API key and your first request. # Tale documentation Source: https://tale.dev/docs/ You chat with models over your own documents, build agents that handle a job end to end, run automations in the background, and manage contact conversations from one inbox — with your choice of AI providers and your data pinned to a region you control. Every feature, API, and role is identical across the two editions; the only difference is who runs the stack. Start with the quickstart, then follow the journey that matches your role. From a running instance to a working chat reply, on Cloud or your own machine. ## Pick your journey Four day-one journeys, one per role. Each takes about 15 minutes and ends with something working. Your first chat, your first document, your first project — the member's first day. Publish a minimal agent and watch it answer in chat — the editor's first day. Mint an API key and make your first authenticated request — the developer's first day. Set up the workspace, invite the team, connect a provider — the admin's first day. ## Pick your edition Tale operates the stack — pick this when running infrastructure is not where the team should spend its hours. Install Tale on your own VPC, on-premises hardware, or in an air-gapped environment. ## Go deeper The canonical feature reference, identical for Cloud and self-hosted. Role-indexed walks from "I want to do X" to a working result. REST API, webhooks, connector SDK, contributor workflows. ## Where this fits Once you have walked a get-started journey, the rest of the docs sit one click away: [Platform](/platform) is the canonical reference for every user-visible feature, and [Tutorials](/tutorials/overview) go deeper on complete tasks. Source, issues, and release announcements live at [GitHub](https://github.com/tale-project/tale). # Agents (admin view) Source: https://tale.dev/docs/platform/admin/agents The Admin agents view is the org-wide directory of every agent that exists in Tale, regardless of who built it. Editors and Developers see the agents they have access to in their own area; Admins and Owners see all of them, plus the per-agent governance levers and the per-agent audit trail. This page covers that supervisory surface — what the table shows, what an Admin can change, and what stays under the agent owner's control. This page does not teach you how to build an agent. That is the Editor view under [Agent concepts](/platform/agents/concepts). What follows is the other side: how to find an agent, how to step in when one needs attention, and how the role boundaries hold when you do. ## What the table shows Open **Settings > Agents** to land on the org-wide list. Each row names an agent and shows who owns it, whether it is shared with the organization or kept private, and when it was last edited. The list is searchable by name, and the default sort is most-recently-edited first — useful when you want to see what has changed since you last looked. Clicking a row opens the same agent editor an Editor or Developer would see, but with the Admin lens on: every tab is visible, every binding is editable, and the history shows the full edit trail with the actor and the diff for each save. ## What an Admin can do that an Editor cannot Admins inherit every permission Editors and Developers carry on the agent surface. Beyond those, the Admin view adds three governance moves. - **Narrow an agent's reach.** Flipping a shared agent back to private takes it out of every member's picker without deleting anything — its conversations and its history stay intact, and sharing it again restores the previous behaviour. Reach for this when an agent is misbehaving and you need it to stop being used while you work out why. - **Reassign ownership.** An agent's owner is the member responsible for it, and a private agent must always have one. Reassigning hands the agent to somebody else; the previous owner keeps whatever access their role gives them and nothing more. Reach for it when an owner changes teams or leaves. - **Apply a governance policy.** Admins can attach a policy to an agent — required approvals on writes, which tool families are permitted, which connectors may be reached. The policy wins over the agent's own configuration wherever the two disagree, and the agent's owner sees it as a read-only badge in the editor. ## What stays with the agent owner Most everyday editing stays with whoever built the agent: renaming it, rewriting its instructions, adjusting its knowledge scope, granting or revoking tools, binding and unbinding skills, and saving new versions. The Admin view is for stepping in, not for taking over. If you find yourself editing other people's agents routinely, the right answer is usually a governance policy that scopes the behaviour for a class of agents rather than a manual edit to one of them. One thing sits outside both roles: nobody pins a model to an agent. The model is chosen per turn by whoever sends the message, so governing which models may be used is a [Providers](/platform/admin/providers) question and a [Policies and limits](/platform/admin/governance/policies-and-limits) question, never an agent-by-agent one. ## Audit and history Every save on an agent lands in the audit log with the actor, the timestamp, and the field that changed. The Admin view exposes the per-agent slice of that log through the agent editor's history; the same data is reachable org-wide under **Settings > Governance**. Bindings are worth reading with that in mind — an agent's configuration can sit unchanged while a skill bundle it binds is replaced underneath it, and the bundle's own audit trail is where that shows up. ## Where this fits The Admin agents view is the supervisory complement to the Editor's build view — the same agents, a different lens. Most of the time you should reach for it only when something needs attention; the day-to-day work happens in the agent editor under [Agent concepts](/platform/agents/concepts). When the right answer is to scope behaviour for a class of agents rather than one of them, the next read is [Members and roles](/platform/admin/members-and-roles) for how policies attach to roles. # API keys Source: https://tale.dev/docs/platform/admin/api-keys API keys are the org-wide credentials Tale issues so external code can call its REST API without a human in the loop. A key authenticates the caller as the organisation, scoped by the role you pick when you mint it. Admins and Developers manage keys; other roles cannot see the page. This is the reference for what a key is, how to create one, how to scope it, and how to retire it without breaking anything that depends on it. The keys listed here are different from the per-user session tokens Tale issues when someone signs in. Those are short-lived and tied to a person; API keys are long-lived and tied to the organisation. Reach for an API key when you wire a script, a cron job, an internal service, or a third-party connector to Tale; reach for the in-product UI when a person is at the keyboard. ![The REST API keys settings page listing two keys, each showing only its prefix, the date it was added, and a Never used marker, beside a Create API key button.](/images/get-started/settings-api-keys.webp) ## Creating a key Open **Settings > API keys** and click **Create API key**. Give the key a name that says who or what will use it (`Billing sync`, `Slack relay`, `ops-cron`), pick the role it should carry, and pick the expiry. Tale shows the secret exactly once on creation — copy it into your password manager or your deployment system before you close the dialog. After that, only the key's prefix is visible from the table. The role you pick scopes everything the key can do. A key carrying the Developer role can read every resource and write to most; a key carrying the Member role can read the knowledge base and start chats but not configure anything. Pick the smallest role that does the job — keys are exactly as dangerous as the role they carry. ## What the table shows The API keys table lists each key by name, prefix, role, creator, last-used timestamp, and expiry. The prefix is the first eight characters of the secret — enough to identify the key in logs without exposing it. The last-used timestamp updates on every successful request the key makes; a key that has not been used for weeks is usually safe to retire. The filter row lets you narrow by role, by creator, and by expiry window. The default sort is most-recently-created first; the secondary sort is most-recently-used. ## Rotating a key To rotate, create the new key first, deploy it to the system that uses the old one, verify the new key works (the last-used timestamp updates), and only then revoke the old one. Tale does not auto-rotate keys; the discipline of overlap is yours to keep. Rotation is the right move whenever a key is suspected of having leaked, whenever someone with access to the key leaves the organisation, or on whatever cadence your security policy mandates. ## Revoking a key Click the row, then **Revoke**. A revoked key stops authenticating immediately — any in-flight request completes, but the next one fails with `401`. Revoked keys stay in the table for the audit trail; the row badges them as revoked and shows who revoked them and when. There is no undo for revocation; if you revoke the wrong key, mint a new one. ## Scopes and limits Each key carries the permissions of its role at the time of every request, not the time of creation. If you change a role's permissions through a governance policy, every key that carries that role inherits the change on the next request. The org's rate limits apply per key, not per organisation; a noisy key does not throttle a quiet one. A key can be restricted further by IP allowlist on creation. The allowlist takes a comma-separated list of CIDR blocks; requests from outside the list fail with `403`. Reach for the IP allowlist when the calling system has a stable egress and you want defence in depth. ## Where this fits API keys are the bridge between Tale and external code; they sit beside [Connectors](/platform/admin/connectors) (third-party systems Tale calls out to) and [Automation webhook triggers](/platform/automations/triggers) (systems that call into Tale on events). The natural next read is the REST API itself — see the API reference in the Develop tab for the surface a key authenticates against, and see [Members and roles](/platform/admin/members-and-roles) for the role-to-permission map every key inherits. # Branding Source: https://tale.dev/docs/platform/admin/branding Branding is the surface that swaps Tale's default chrome for your organisation's own. The page covers the assets the platform skins — logo, favicon, and the accent colour the palette derives from — and explains where each one shows up so you can preview before you save. The product name itself follows your organisation's name automatically, so there is no separate field to fill. Admins reach for branding when a self-hosted instance ships to an external audience or when an internal rollout needs to feel native to the company. Only Admins and Owners can edit branding. Everyone else sees the result; the form itself is hidden from Editors, Developers, and Members. ![The Branding settings page with logo and favicon uploads, an accent colour field, and a live preview pane on the right.](/images/platform/settings-branding.webp) ## Where branding lives Open **Settings > Branding**. The form has three sections (logo upload, favicon upload, accent colour) and a live preview that mirrors the sidebar with the values you are editing. Save commits the change for every member of _that_ organisation on their next page load — there is no per-user override. Branding is scoped to one organisation. Each organisation keeps its own logo, favicon, and accent colour, so switching organisations swaps the chrome to that organisation's branding rather than carrying the previous one's over. Editing here changes only the organisation you are currently in. ## The product name There is no "app name" or "text logo" field. The wordmark in the sidebar header and the name in the browser tab title are your organisation's own name, which you set on the **Settings > Organization** page. Rename the organisation and the chrome follows on the next page load. Upload a logo image (below) and it takes the wordmark's place; with no logo, the organisation name is rendered as the text wordmark. ## The assets **Logo** is an image — PNG, SVG, or JPG. The platform renders it at sidebar height; aim for a transparent background and a wordmark that reads at roughly 32 pixels tall. The logo is a single upload used on both themes, so pick a mark that reads on light and dark backgrounds. With no logo, the chrome falls back to your organisation's name as a text wordmark. **Favicon** is the tab icon. Upload a light and a dark variant so the icon stays legible whichever theme the operating system has chosen — or leave it blank and Tale derives one from your logo the moment you upload it, so a single upload skins both the sidebar and the browser tab. An explicit favicon always wins over the auto-derived one. **Accent colour** is the single colour the branded palette derives from — buttons, focus rings, selection states, and the sidebar's active row all take their tone from it. It accepts any hex value, picked once for both light and dark mode; Tale derives a legible palette per theme, so a colour that would be hard to read against one theme's background is nudged into contrast for that theme only while the other stays untouched — the same brand reads cleanly on both. The preview reflects the derived palette for the theme you are currently viewing. ## A worked rebrand To rebrand an instance for `Acme Corp`, first set the organisation's name to `Acme Corp` on the **Settings > Organization** page — that name becomes the sidebar wordmark and the browser tab title. Then open **Settings > Branding**, upload the company wordmark as the logo, and paste the brand hex (`#3B82F6` for the example) into the accent colour field. Leave the favicon blank and Tale generates one from the logo. The preview pane on the right updates as you type. Save commits the change; the sidebar, the browser tab, and the favicon reflect the new branding immediately. ## The custom login screen The sign-in, sign-up, and password-reset screens render before you have picked an organisation, so there is no organisation in scope to brand them with. They show the platform's default branding rather than any single organisation's; per-organisation branding takes over the moment you land inside that organisation's workspace. Sign out and reload the login URL to verify which assets the pre-auth screens use. ## Where this fits Branding is the visual layer that sits above every other admin surface; SSO, email, and audit logs all carry the branded chrome to your members. Because the product name is the organisation's own name, keep it sharp on the [organization](/platform/admin/members-and-roles) settings. Pair branding with [providers](/platform/admin/providers) so the model names that show in the chat header match the chrome around them, and with [members and roles](/platform/admin/members-and-roles) so the people who can edit branding are the same people who own the rest of the org's chrome. # Changelog Source: https://tale.dev/docs/platform/admin/changelog The changelog is the in-product viewer that surfaces release notes for the Tale platform itself — not for content your members produce. After a self-hosted upgrade or a managed-cloud rollout, the viewer lists what changed between the previous version and the one running now. Admins read it after an upgrade to brief the team and to flag anything that affects how members work. The viewer reads release notes from the Tale repository on GitHub and caches them inside your instance so the page loads even when GitHub is unreachable. ## Where the changelog lives The changelog has two surfaces. The **What's new** page under **Help** lists every recent release with its full notes. The **upgrade toast** fires once per major-version bump and links straight to the page — the toast shows `Upgraded to v` and stays until dismissed so a member who was away does not miss the heads-up. Open the page from the help menu in the top bar, or from the upgrade toast when it appears. The page caches up to roughly thirty recent releases; older ones link out to the GitHub release history. ## What each entry shows Each release entry carries four fields: the version tag, the publish date, the release name (often a short headline), and the release body in Markdown. Tale renders the body the way GitHub does — headings, lists, links, and code fences all survive. Releases that GitHub has not yet published surface a short explainer card with a link to the public release history. ## Scope The changelog is the platform's changelog — what changed in Tale itself. It does not show changes to your agents, your workflows, or your knowledge base; those have their own per-resource history. If you are looking for the version history of an agent or a workflow, open the resource and switch to the **History** tab. The viewer is read-only and visible to every signed-in member. There is no Admin-only flag — anyone with an account can open the page. The data the viewer fetches is public release information from the Tale GitHub repository, so there is nothing org-scoped to hide. ## A worked upgrade After a self-hosted upgrade from `v0.42` to `v0.45`, sign in and look for the upgrade toast in the top right. Click **View** to open the changelog page. The page shows three release entries (`v0.43`, `v0.44`, `v0.45`) newest first, each with the engineer-written notes from the GitHub release. Skim the highlights, share the link with the team if anything needs a wider audience, and the toast clears the next time you reload. When the upgrade spans more than the cached window, the page shows the most recent entries with a banner that links to GitHub for the earlier notes. The cache stays warm for the next reader on your instance. ## Where this fits The changelog is the operator's read-out of what Tale itself just did; it sits next to the audit log (which records what your members did) and the providers page (which tracks which model versions are wired). Pair it with [self-hosted upgrade](/self-hosted/operate/upgrades) when you operate the instance — the upgrade guide walks the version bump, and the changelog reads out the result on the other side. # Connector credentials Source: https://tale.dev/docs/platform/admin/connectors Every connector ships with the platform, so the administrator's job is never installation — it is deciding which accounts Tale may act as, and keeping those credentials healthy. A connector holds as many credentials as you need, one per workspace, store, mailbox, or bot, and one of them answers for any caller that names none. This page is the operations side of that: what the page shows, how each authentication method is filled in, and what happens when you promote, disable, delete, or reconnect a row. The catalog itself — the thirteen connectors, what each one buys you, and how their actions reach automations and chat — is on [Connectors](/platform/connectors/overview). Reading time here is best spent on the credential lifecycle, because that is the part that differs per organisation and the part that breaks. ## What the page shows Open **Settings > Connectors**. The page is gated on Admin or Developer permissions and is a table of the credentials your organisation holds — one row per credential, not one per shipped connector. A row shows its name, the connector it authenticates, its authentication method, and its coordinates: a masked preview of the stored secret, plus the instance URL where the connector needs one. A **Default** badge marks the one an action falls back to, a **Disabled** badge any that is switched off. Search covers both the name you gave a credential and the connector behind it; the filter button narrows to one connector. A `?connector=` link narrows the table the same way, which is where the OAuth round trip returns you. Two warnings appear here, and they mean different things. _No default credential for {connector}_ means every row works but nothing answers for a caller that names none. **Reconnect needed** on a row means an OAuth grant stopped refreshing and needs consent again — the credential itself is fine. ## Adding a credential **Add credential** opens the shipped catalog. Connectors you already hold a credential for come first, under **In use**; everything else follows below it, alphabetically, each with its category tags and how many actions it exposes. Search narrows the list; picking one moves you to the setup step, and **Back to the catalog** returns. Setup asks for a **Name** first, and the field's help text is the reason it matters: the name an action uses to pick this credential. Choose something an automation author will recognise months later, such as `Support inbox` or `EU store`. What follows the name depends on the **Authentication method** the connector accepts. One field, **API key**. The connector's own action bodies decide where the key travels — a header the vendor defines, or the request body where the vendor requires it. Shopify and Tavily are the shipped cases. One field, **Token**, sent as the Authorization header on every request. GitHub takes a personal access token this way; Discord takes a bot token, which the platform sends under Discord's own scheme rather than the standard one. Two fields, **Username** and **Password**, sent as HTTP Basic. The pair is not always a login in the everyday sense: Confluence takes the account email with an API token, Twilio takes the Account SID with the Auth Token, and the WebDAV connector takes a WebDAV app password. IMAP / SMTP takes the mailbox login itself. No secret to type, so the setup step is the hand-off alone: **Connect** takes you to the vendor's consent screen, and Tale stores what comes back — access token, refresh token, expiry, and the granted scopes — as a new credential row. Gmail, Google Drive, Outlook, Teams, and Slack all connect this way. A connector that accepts both a grant and a token offers both, with **Connect** first. Adding a second credential to a connector that already has one is the same flow again — it simply appears under **In use** in the catalog. There is no limit to work around and nothing to disconnect first. Confluence and Shopify also ask for an **Instance URL**, because neither has a single vendor host. Confluence wants your Atlassian site origin — the address you open Confluence at. Shopify wants your store's `myshopify.com` origin, which is the admin address rather than the storefront domain. The value is stored in the clear on purpose, so the table can show which instance each row points at. ## Choosing the default One credential per connector can be the **Default**, and **Make default** on any row moves it. The default is what resolution falls back to when an automation node or a chat action names no credential. Mail sync is the exception that proves the rule the other way: `conversation.sync_mailbox` walks every _active_ credential on the connector so adding a second IMAP mailbox (or a second Gmail account) does not leave it unsynced until you promote it. Inbox triage does the same fan-out through `conversation.list_mailbox_messages`. A connector with several credentials and no default is a working configuration with a gap in it. Callers that name a row keep running; callers that do not cannot pick one and fail. Promote a row and the gap closes immediately. ## Replacing a secret Rotating a key is an edit on the credential, not a separate operation. Open the row and choose **Replace API key**, **Replace token**, or **Replace username & password**, depending on the method. The stored secret is never shown back to you, and entering a new one replaces it everywhere that credential is used — every automation node and every chat action pointed at that row picks up the new secret without being touched. The credential keeps its name, its default flag, and its instance URL through a replacement, so nothing downstream has to be repointed. **Edit name & instance** covers the other direction: renaming a row, or moving it to a different instance origin. ## Disabling and deleting **Disable** takes a credential out of service while keeping the row and everything configured on it. The credential shows as **Disabled** and nothing resolves to it; **Enable** puts it back. Reach for this when an account is suspected rather than finished, or when you want a configuration parked without losing it. **Delete** is immediate and final. Automations and chat actions using that credential lose access to this connector at once — there is no grace period. Deleting the default leaves the connector without one until another row is promoted, and the confirmation says so before you commit. ## Reconnecting a broken authorization An OAuth credential whose stored authorization expired or was revoked shows **Reconnect needed** with the reason attached. This is the platform's own finding, not an operator's decision, which is why it reads differently from a credential someone disabled by hand: nothing about the row is wrong, the vendor stopped honouring the grant. **Reconnect** re-runs the vendor's consent flow and restores access on the same row, keeping its name, its default flag, and every reference pointed at it. A credential you disabled yourself is not repaired this way — **Enable** is the fix for that one, and reconnecting it would be answering the wrong question. ## Connectors and MCP servers Both surfaces let an agent reach past Tale, and the difference is who owns the bridge. A connector is vendor-specific, ships with the platform, and is maintained for you; your side of it is the credential. An MCP server is a process you host and register under **Settings > API > MCP**, exposing whatever tools you write. Reach for the connector when one exists for the target system, and for [MCP servers](/platform/connectors/mcp-servers) when none does. ## Where this fits Credential management is the whole of connector administration now that nothing is installed: add the accounts, name them well, keep one default per connector, and reconnect the OAuth rows that lapse. [Connectors](/platform/connectors/overview) is the catalog those credentials attach to, [Agent tools](/platform/agents/tools) shows how the resulting actions arrive in an agent's toolbelt, and [Configure approvals](/platform/approvals/configure) is where the write actions are held for a person to release. # Enterprise SSO and provisioning Source: https://tale.dev/docs/platform/admin/enterprise-sso Enterprise SSO lets your members sign in with your identity provider (IdP) instead of a Tale password, and SCIM lets the IdP provision, update, and deactivate members and groups automatically — no manual invites. One connection per organisation carries the sign-in protocol, the provisioning policy, and the SCIM token together. Everything lives on one page: **Settings > Enterprise SSO** (admins only). Tale speaks four protocols: **OIDC**, plain **OAuth2**, **SAML 2.0** for sign-in, and **SCIM 2.0** for provisioning. You can enable sign-in, provisioning, or both. ![The Enterprise SSO settings page with the Protocol dropdown set to Microsoft Entra ID and a matching display name, and a sign-in section carrying the redirect URL to register, an issuer URL and client ID filled in from the app registration, an empty client secret, and the requested scopes.](/images/platform/settings-enterprise-sso.webp) ## Choosing a protocol Open **Settings > Enterprise SSO**, pick a **Protocol**, and fill in only that protocol's fields — the rest stay hidden. A **Setup guide** on the same page lists the exact steps and shows the URLs you paste into your IdP. Use **Test connection** before saving to validate the configuration, and **Save** to enable sign-in. - **Microsoft Entra ID** — Microsoft's OIDC, with group-to-team sync over Microsoft Graph. - **Generic OIDC** — any OpenID Connect provider (Google, Okta, Auth0, Keycloak, …). Endpoints are discovered from the issuer. - **OAuth2** — providers without OIDC discovery; you configure the authorization, token, and userinfo endpoints by hand. - **SAML 2.0** — XML-based SSO; you exchange metadata with the IdP. ## Microsoft Entra ID 1. Sign in to the [Microsoft Entra admin center](https://entra.microsoft.com) as at least an Application Developer. 2. Go to **Entra ID > App registrations > New registration**, name it, and choose **Single tenant**. 3. Under **Redirect URI**, select the **Web** platform and paste the **Redirect URL** shown on the Tale settings page, then **Register**. 4. On the app's **Overview**, copy the **Application (client) ID** and **Directory (tenant) ID**. Your issuer URL is `https://login.microsoftonline.com/{tenant-id}/v2.0`. 5. Open **Certificates & secrets > New client secret** and copy the secret **Value** (not the Secret ID). 6. In Tale, choose **Microsoft Entra ID**, and enter the client ID, client secret, and issuer URL. 7. For group-to-team sync, add the Microsoft Graph **GroupMember.Read.All** permission under **API permissions** and grant admin consent. 8. For OneDrive and SharePoint document sync, add the Microsoft Graph **Files.Read** and **Sites.Read.All** permissions under **API permissions** and grant admin consent. A new connection requests both by default — the SSO token doubles as the Graph token, so members can import files right after signing in. If the organisation should only sign in, remove the two scopes from the **Scopes** field; the Microsoft 365 entry then stays hidden on the documents page. ## Google Google is configured as a generic OIDC provider. 1. In the [Google Cloud Console](https://console.cloud.google.com), open **APIs & Services > Credentials > Create credentials > OAuth client ID**. 2. Choose the application type **Web application**. 3. Under **Authorized redirect URIs**, add the **Redirect URL** shown on the Tale settings page, and save. 4. Copy the **Client ID** and **Client secret** from the top of the client page. 5. In Tale, choose **Generic OIDC**, enter the client ID and secret, and set the issuer URL to `https://accounts.google.com`. Endpoints are discovered automatically. Google's standard OIDC does **not** return group memberships, so group-to-team sync is unavailable with Google alone — it needs the Admin SDK / Cloud Identity API with a Workspace admin. Sign-in and role-by-claim mapping work normally. ## Generic OIDC and OAuth2 For any other OIDC provider (Okta, Auth0, Keycloak), choose **Generic OIDC**, paste the **issuer URL** and the client ID/secret — Tale reads the authorization, token, and userinfo endpoints from the issuer's `.well-known/openid-configuration`. If a provider exposes OAuth2 but no discovery document, choose **OAuth2** and enter the **authorization**, **token**, and **userinfo** endpoint URLs by hand. When the provider uses non-standard claim names, map **email**, **name**, and **groups** under the connection's advanced fields (dot-paths are supported, e.g. `realm_access.roles`). ## SAML 2.0 1. In Tale, choose **SAML 2.0**. The page shows your **SP metadata URL** and **ACS (reply) URL** — copy them. 2. In your IdP, create a new SAML 2.0 application. Set its **ACS URL** and **Entity ID / Audience** to the SP values shown (or upload the SP metadata URL), and set the **Name ID** format to email address. 3. Under **Import IdP metadata**, paste the IdP's federation-metadata URL and click **Import** — or click **Upload XML** if your IdP only offers a downloadable file. Tale parses the metadata and fills the entity ID, sign-on URL, and signing certificate fields below, so there's nothing to retype by hand. All three stay editable, so review the imported values (or fill them in yourself, if your IdP publishes no metadata document) before saving. 4. Map the **email**, **name**, and **group** attributes in your IdP; if their names differ from the defaults, set the matching attribute names in Tale's advanced fields. Tale supports both IdP-initiated SAML (the IdP posts an assertion to the ACS URL) and SP-initiated SAML (a member clicks **Sign in with SSO** and Tale redirects to the IdP). Signed assertions are required; encrypted assertions are supported when you supply an SP keypair. ## Several organizations on one deployment A deployment can host more than one organization, each with its own connection. Click **Continue with SSO** on the login page, then pick your organization from the list — each entry shows the connection's **Display name**. That name is visible to anyone on the login page, so set a clear display name per connection in **Settings > Enterprise SSO**. ## Provisioning: roles and teams Every protocol shares one provisioning policy: - **Default role** — the role a newly provisioned member receives (Member by default). - **Auto-assign roles** — when on, role-mapping rules map a job title, app role, group, or claim to a platform role; the default role applies when nothing matches. - **Sync groups to teams** — when on, each of the user's IdP groups becomes (or joins) a team of the same name on sign-in; **Exclude groups** skips noisy groups (comma-separated). ## SCIM provisioning (users and groups) SCIM lets your IdP push changes without anyone signing in. In the **SCIM provisioning** section, click **Generate token** — copy it once (it is never shown again) — and paste it, along with the **SCIM base URL** shown, into your IdP's provisioning settings. The IdP authenticates with the token as a bearer credential; Tale resolves the organisation from the token, so it is the tenant boundary. Tale implements SCIM 2.0 **Users** and **Groups**: create, read, list (with `userName`/`displayName` filters), replace, patch, and delete. Provisioned users map to organisation members; groups map to teams. **Deactivation is soft** — when the IdP sets a user inactive (`active: false`), the member's role is set to `disabled` (which removes their access), and re-activation restores their prior role. A SCIM **delete** removes the membership from the organisation; the user account itself is kept, and re-provisioning attaches it again at the connection's default role. The organisation owner can never be de-provisioned via SCIM. ## Verifying Use **Test connection** for OIDC/OAuth2 to confirm discovery and credentials before saving. For SAML, download the SP metadata into your IdP and run a test login. For SCIM, most IdPs offer a "test" or "provision now" action that creates a sample user — confirm it appears under **Settings > Members**. End-to-end SSO sign-in is best verified against your real IdP in a staging organisation. # Audit logs Source: https://tale.dev/docs/platform/admin/governance/audit-logs The audit log is the immutable record of every consequential action inside your organisation. Every sign-in, role change, provider edit, agent save, workflow run, and sandbox invocation lands here with the actor, the resource, the before/after state, and the timestamp. Admins and Owners read this when an audit asks who touched a resource and when, when a compliance officer needs an export, or when something goes sideways and the question is _who changed what at 03:14_. This page is the reference for the columns, the filters, the categories, and the export formats. The retention window for audit rows is set on the same Governance area under retention policy — keep it long enough to satisfy your compliance requirements before rows roll off. ## A worked filter To find the moment a member's role was changed, open **Settings > Governance > Logs**, set the **Category** filter to **Member**, and search for the actor or the target by name. Each row expands to the full payload — previous state, new state, the IP if the request was over the wire, the actor type (user, system, API, workflow). Export the filtered set as CSV or JSON from the toolbar above the table. ## The columns | Name | Type | Required | Description | | -------------- | -------- | -------- | ----------------------------------------------------------------------------------------- | | Timestamp | ISO 8601 | yes | Server time the action committed. | | Action | string | yes | The semantic action — `update_member_role`, `provider_created`, `agent_saved`. | | User | string | yes | Display name of the actor; `System`, `API`, or `Workflow` when the actor is not a person. | | Resource | string | yes | The resource the action touched — `agent`, `provider`, `member`, `workflow`. | | Category | enum | yes | Auth, Member, Data, Connector, Workflow, Security, Admin, AI, Skill, Agent. | | Status | enum | yes | Success, Failure, Denied. | | Changed fields | JSON | no | The diff between previous and new state for update actions. | ## Filters Filter by date range, category, status, actor, resource, or free-text search across action names. Combine filters — a date range plus the **Security** category plus **Denied** status surfaces the failed sign-in attempts in a window. Filter state is reflected in the URL, so a saved link reopens the same view. ## Exporting Two export formats ship: CSV for spreadsheets and JSON for downstream systems. Both honour the active filters — what you export is what you see. Set the filters you want (the worked filter above is the pattern), then choose CSV or JSON from the toolbar above the table. Large exports stream as a download; the toolbar reports progress and completes with the file size and row count. The CSV arrives as `audit-logs-.csv`, one row per action, with a flat column per field; timestamps are ISO 8601 in UTC and any value containing a comma is quoted: ```csv timestamp,action,category,actorEmail,actorId,actorType,actorRole,resourceType,resourceId,resourceName,status,errorMessage 2026-01-14T03:14:07.000Z,member.role_changed,Member,admin@acme.example,usr_8f3a,user,owner,member,usr_2b91,jordan@acme.example,success, 2026-01-14T03:15:22.000Z,provider.updated,Provider,admin@acme.example,usr_8f3a,user,owner,provider,prov_openai,OpenAI,success, ``` The JSON export (`audit-logs-.json`) carries the same rows as full objects plus the fields CSV flattens away — the `previousState`/`newState` diff and the per-row `integrityHash`. Reach for JSON when a downstream system needs the before/after payload or has to re-verify each row against the SHA-256 chain (see [Retention and integrity](#retention-and-integrity)); reach for CSV when a person opens it in a spreadsheet. ## Retention and integrity Audit rows are immutable: edits and deletes are themselves audited, and the row schema carries an integrity hash you can verify against the export. A scheduled daily check re-verifies the hash chain server-side and records a `security` audit entry if verification fails, so tampering or an out-of-band deletion surfaces even when no admin runs the manual check. A failed check also raises a critical in-app notification to the organisation's admins and fans out to Slack when a Slack notification channel is configured. Admins can verify the chain on demand from the **Chain integrity** panel at the top of this page — it shows the current status, the last automated check time, and a **Verify now** button — and a failed check's notification deep-links to the flagged row so an admin lands on the break instead of the top of the log. Retention defaults to 90 days and is configurable on the retention policy page (30 to 365 days). Rows that age out are removed by the next cleanup pass — there is no soft-delete window for audit data. ## Where this fits The audit log is the read side of every other governance feature: legal hold names the holds it placed, data subject requests log every cascade step, the run-code policy logs the URLs each sandbox tried to reach. When a question starts with _who, when, what_, the audit log is the answer. The companion page is the [retention policy](/platform/admin/governance/policies-and-limits) — it controls how long these rows stay before cleanup removes them. # Content and models Source: https://tale.dev/docs/platform/admin/governance/content-models Content and models is the surface where you decide which LLMs the people in your organisation can reach and which one each group lands on by default. It pairs an allowlist or blocklist per scope (org, team, role, user) with a default-model rule the resolver applies when no agent or conversation has overridden the choice. Admins and Owners read this page when a compliance rule pins a workload to an approved model, when a team should default to a cheaper model than the rest of the org, or when a new model from an existing provider needs to be made reachable. ![The Content and Models governance page showing the mandatory system-prompt prefix and suffix fields filled with the org's house rules, above a default-models table carrying three rules: a default for all users, and role rules for Developer and Member, each pinned to an OpenRouter model.](/images/platform/governance-content-models.webp) ## A worked default To set the default model for the Editor role, open **Settings > Governance > Default Models** and click **Add rule**. Pick **Role** as the scope, **Editor** as the target, then pick the provider and model. Save and the next request from any Editor without an explicit per-agent or per-conversation model lands on the rule's model. More specific scopes win — a user rule beats a team rule beats a role rule beats the org default. ## The two layers **Model access** is the allowlist or blocklist that gates which models a scope can use at all. A model not on the allowlist is invisible to that scope — the picker hides it and the resolver refuses to bind to it, even if an agent has it pinned. Reach for the allowlist when a regulator names the approved models; reach for the blocklist when a single model should be off-limits everywhere else. **Default models** is the resolver rule that picks the model when nothing else has — no per-agent override, no per-conversation override. The default applies the moment the user starts a fresh chat and applies as the fallback when an agent's pinned model is unreachable. ## Scopes and precedence Both layers carry a scope: org, team, role, or user. The resolver evaluates from narrowest to widest — user wins over team wins over role wins over org default. The model access layer composes with the default-model layer; the default the resolver picks must also pass the access check for the same scope, otherwise the resolver falls back to the nearest permitted model. ## Allowlist and blocklist warnings The default-models editor surfaces a warning when a rule names a model the allowlist for the same scope does not permit, or when the blocklist for the same scope blocks it. The warning does not block saving — the resolver will fall back at request time — but it flags the mismatch so you can fix one or the other. ## The model that reads images Not every model can see. When a text-only model runs an agent that opens a screenshot, a scanned invoice, or a rendered slide, Tale hands that image to a second model and gives the agent the transcription back. That happens through the gateway, so no provider key ever reaches the sandbox, and a model that already reads images skips the detour entirely. **Vision model** decides which model does that reading. Leave it on **Automatic** and Tale picks for you, preferring a recommended vision model and falling back to the cheapest one your credentials reach. The line under the picker always names the model currently doing the job and why it was chosen, so the answer to "which model is reading our images" is never a guess. Pin a model when you want that choice to stop moving. Automatic reads a live provider catalog, so the cheapest reachable model changes as providers publish new listings — a pin holds the lane on the model you tested. Only models that can actually transcribe are offered: media generators and free-tier lanes are filtered out, because both accept an image and then refuse the request. If a pinned model later stops being reachable — the credential rotated, the allowlist narrowed, the provider dropped it — Tale logs that and falls back to Automatic rather than leaving your agents unable to read at all. ## Where this fits Content and models is the gate every chat and every agent passes through at request time. Pairing model access with default models lets you ship a tight compliance posture without forcing every agent author to remember which model is approved this quarter. The companion is the [policies and limits](/platform/admin/governance/policies-and-limits) page — it covers the cost and request caps that apply on top of the model choices made here. # Data subject requests Source: https://tale.dev/docs/platform/admin/governance/data-subject-requests Data subject requests is the workflow Tale ships for honouring GDPR Article 17 (right to erasure) and the equivalent CCPA right under California law. Each request becomes a receipt: it names the subject, the reason code, the SLA deadline, and the cascade of rows the system erased across threads, documents, workflow executions, and personal prompt templates. Admins and Owners read this page when a subject files a request, when a deadline is closing in, or when an audit asks for the receipt of a past erasure. ![The Data subject requests governance page showing the cooling-off window, dual-approval toggle, and daily-limit fields above an erasure-requests table with one pending request — subject Jordan Blake, reason code consent withdrawn, 24 hours until execution and 29 days left on its SLA — beside a File request button.](/images/platform/governance-data-subject-requests.webp) ## A worked filing To file a request, open **Settings > Governance > Data subject requests** and click **File request**. Pick the subject, choose a reason code (consent withdrawn, no longer necessary, unlawful processing, legal obligation, objection, child subject, or contract termination), and add a free-text narrative. The request enters a cooling-off window before the cascade runs — any Admin can cancel during the window. After the window elapses, the cascade erases the subject's threads, documents, workflow executions, RAG embeddings, and personal prompts, and the receipt records counts for each category. ## Status lifecycle | Name | Default | Description | | ----------------- | ------------- | ----------------------------------------------------------------------------------------- | | Pending | initial state | The request is filed and waiting for the cooling-off window or the second admin approval. | | Awaiting approval | dual-control | A second Admin must approve before the cascade runs. | | Running | mid-cascade | The cascade is in flight; partial counters update as each category completes. | | Completed | terminal | Every category erased without error. | | Partial | terminal | Some rows were skipped — usually a legal hold blocked them. | | Failed | terminal | The cascade hit an error; the receipt names the failed category. | | Blocked | terminal | An active legal hold blocks every cascade step. | | Cancelled | terminal | An Admin cancelled before the cooling-off window elapsed. | ## SLA tracking Every request carries a service-level deadline — by default, 30 days from filing. The Requests list shows days-left or an overdue badge per row. Article 12(3) of GDPR permits a single extension for complex cases; the **Extend deadline** action records the extension on the receipt with the requesting admin's name and a narrative. ## Legal hold interaction A subject's data is _not_ erased while it is on legal hold. Rows under hold show as **Skipped by hold** in the receipt's per-category counters; releasing the hold and retrying the request finishes the erasure. The Blocked status fires when a hold covers every category from the start — the cascade does not run, and the receipt reflects the block. ## The cascade categories The receipt breaks the erased rows down by category — threads, documents, workflow executions, prompt templates, RAG documents removed from the vector store. Read the drawer to see counts and the audit timeline; the audit log on the same Governance area carries the full event chain (`gdpr_erasure_requested`, `gdpr_erasure_executed`, `gdpr_erasure_extended`, `gdpr_erasure_cancelled`). ## Where this fits Data subject requests is the compliance face of retention — the audited, dual-controlled path that erases a specific subject on demand instead of the timed sweep retention runs across everyone. The companion page is [legal hold](/platform/admin/governance/legal-hold) — it covers how to pause retention and DSAR cascades for litigation before they run. # Feedback analytics Source: https://tale.dev/docs/platform/admin/governance/feedback-analytics Feedback analytics is the dashboard that turns the per-message thumbs and the per-chat ratings into trend lines. Members leave the feedback inline in chat; this page aggregates it by agent, by model, and over time so the regression in last week's voice change is visible as a number, not a hunch. Admins and Owners read this page when a model swap looks like a downgrade, when one agent is underperforming the others, or when leadership wants the rough quality posture of every agent in the org. ## A worked drill-down Open **Settings > Governance > Feedback** and the default view is the org-wide ratio across the last 30 days. Switch the breakdown to **By agent** to see the ratio per agent — sort by feedback volume to find the agents members are actually using, then click into one to see its model history alongside the same ratio over time. The split-by-model view is the same data sliced on the model that produced each rated reply. ## The two signals **Thumbs feedback** is the per-message signal — a thumb up or thumb down on any agent reply. The thumb carries an optional free-text comment; the comment is per row and never aggregated into the ratio. Members can leave both, edit either, or withdraw entirely; the timeline reflects the latest state. **Chat ratings** is the per-conversation signal — the one-to-five star rating that surfaces at the end of a conversation. Ratings carry an optional comment too. Chat ratings are coarser than thumbs and useful for tracking the agent-level vibe over many turns where individual thumbs would be noisy. ## Breakdowns The dashboard slices by three dimensions: - **Agent** — every agent in the org gets its own row with ratio, volume, and trend. - **Model** — every model that produced a rated reply contributes; useful when you compare a primary against its fallback. - **Time** — the trend is daily for the last 30 days and weekly for longer windows. ## Free-text comments Comments are surfaced under the aggregated numbers as a list. Sort by recency or by sentiment; click through to the conversation in context to see what the rated reply was responding to. Comments are subject to the same retention policy as the conversations they belong to; if a thread is purged or trashed, its comments go with it. ## Where this fits Feedback analytics is the pulse on every agent in the org — the place a regression in voice or model behaviour shows up before someone reports it. The companion is [usage analytics](/platform/admin/governance/usage-analytics) — the same agents and models, sliced by spend and token volume instead of quality. # Guardrails Source: https://tale.dev/docs/platform/admin/governance/guardrails Guardrails is the surface where you configure the three filter layers Tale runs on every chat message in your organisation. Each message passes through content safety (word lists and admin regex), then PII detection (built-in patterns plus custom), then an optional external moderation provider — in that fixed order, on the way in and on the way out. Admins and Owners read this page when a regulator names a content rule, when a leak warrants a tighter policy, or when an agent's replies need to be sanitised before they leave the model. ![The Guardrails governance page showing three status cards — content safety applied to input and output across two categories, PII detection running in mask mode over four built-in patterns, and a moderation provider marked Disabled with no external API configured — above a recent-events feed reporting no events yet.](/images/platform/governance-guardrails.webp) ## A worked layering To configure the layers, open **Settings > Governance > Guardrails**. The overview shows three status cards, one per layer — content safety, PII detection, moderation. Each card links to its own configuration page where you pick whether the layer runs on input, on output, or both, and what it does on a match (block the message, mask the match, or flag and pass). The recent-events table at the bottom of the overview shows the last 50 detections, blocks, and provider errors with their layer, direction, and match category. ## Content safety Content safety is the layer you own. Define one or more categories — hate speech, profanity, a custom regex for an internal codename — and pick a mode per category: **block** refuses the message, **mask** replaces matches with a placeholder, **flag** records the detection without changing the message. Block wins over mask wins over flag when more than one category matches. The layer's word lists and patterns never leave the deployment. Matched text is not stored — only the category, the direction (input or output), and the count of matches end up in the audit event. ## PII detection PII detection ships with patterns for emails, phones, government IDs, payment numbers, and a long tail of regional formats. Add custom patterns if your regulator names a format the built-ins miss. Pick a mode — block, mask with a placeholder, or flag — and an apply direction. Mask is the typical choice for output filtering when the model has been given access to records that include PII it should not echo back. ## Moderation provider The moderation layer is an external classifier — OpenAI Moderation, Azure Content Safety, Perspective API, or a custom HTTP endpoint. Configure the provider's endpoint, an API key, and the category-to-action mapping (each provider returns its own taxonomy; the mapping decides which categories block, mask, or flag). The layer is optional — leave it disabled and only the first two layers run. The provider sits on the network egress path. Failures are configurable per direction: fail-open lets the message through, fail-closed refuses it. The recent-events view shows provider errors, HTTP statuses, and circuit-open events when the layer is rate-limited. ## Recent events Every detection, block, and provider error lands in the recent-events table for 30 days. Filter by layer or by kind; click a row to see the matched categories, the actor, the message id, and the timestamp. Raw matched text is never stored — the events are a tuning surface, not a content archive. ## Where this fits Guardrails is the runtime filter between the user and the model in both directions. Pair it with [content and models](/platform/admin/governance/content-models) so an approved model is also subject to the approved content rules. The companion is the [audit log](/platform/admin/governance/audit-logs) — every block and every mask the guardrail layers apply lands there as a permanent record. # Legal hold Source: https://tale.dev/docs/platform/admin/governance/legal-hold Legal hold is the mechanism Tale ships for preserving evidence under litigation hold. A hold pins a target — a user, a document, a thread, a workflow execution, or the whole organisation — out of reach of the retention sweep and the data-subject erasure cascade. Admins and Owners read this page when counsel asks them to preserve a custodian's data, when a release request needs the dual-control sign-off, or when an audit reconciles which holds were in force on a given date. ![The Legal hold governance page showing one active hold — a User hold on marta.vogel, placed by Alex Rivera under the Northstar contract matter — beside a Place legal hold button, above the Pending approval and Approved release-request queues, both reading No release requests.](/images/platform/governance-legal-hold.webp) ## A worked placement To place a hold on a user, open **Settings > Governance > Legal hold** and click **Place legal hold**. Pick the target type — user, thread, document, execution, or organisation — pick the specific target, add a reason, and link the hold to a matter if one is open. The hold takes effect immediately; retention sweeps skip the target's rows, the erasure cascade reports them as **Skipped by hold**, and the target row carries the **On legal hold** badge in every list where it appears. ## The four sections **Active holds** is the working list of every hold currently in force. Each row carries the type, the target, the reason, the matter, who placed it, and when. Filter by type or by matter to scope the view. **Release requests** is the dual-control queue. Releasing a hold requires a different Admin to approve the request; approved requests still wait out a cooldown before they take effect. The section splits into _pending approval_ and _approved, awaiting cooldown_ so the queue and the timer are both visible. **Matters** groups holds by case. Each matter carries a name, a case number, and the list of linked holds. Closing a matter files release requests for every linked hold — still subject to the dual-control approval per request. **Release history** is the read-only audit of effected and rejected releases. Use it to reconcile against an opposing counsel's preservation letter or to feed an audit report. ## Hold-and-cascade interaction A hold blocks every retention pass and every erasure step for the target. The trash page shows the **Delete is blocked by an active legal hold** banner when an Admin tries to purge a row under hold. A data subject request whose subject is covered by a hold lands in the **Blocked** status until the hold is released; partial coverage (some threads under hold, some not) lands in **Partial** with per-category counters in the receipt. ## Dual-control Place and release are not symmetric. Place is a single-Admin action — the speed matters when litigation arrives. Release is dual-control: the requesting Admin files, a different Admin approves, and a cooldown window applies between approval and effect so a hasty release can still be cancelled. Both halves of the workflow are audited end to end. ## Where this fits Legal hold is the freeze button on retention. It is the only mechanism that beats the timed retention sweep and the data-subject erasure cascade — both of which respect holds by design. The companion pages are [data subject requests](/platform/admin/governance/data-subject-requests) for the cascade side and [policies and limits](/platform/admin/governance/policies-and-limits) for the retention windows the hold overrides. # Policies and limits Source: https://tale.dev/docs/platform/admin/governance/policies-and-limits Policies and limits is the surface where you cap what your members and agents can consume. Budgets cap tokens, cost, and requests per billing period; feature controls toggle web search, code execution, and file upload by scope; upload policy gates the file types and sizes a member can attach; retention policy decides how long each data type lives before cleanup. Admins and Owners read this page when a workload is over budget, when a feature should be off for a subset of users, or when a regulator names a retention window that differs from the default. ![The Policies and Limits governance page showing three monthly budget rules — one for the entire organization, one default for all users, and one for the developer role, each capping tokens, cost, and requests — above the upload-policy fields for allowed file types, sizes, and volume.](/images/platform/governance-policies-limits.webp) ## A worked budget To cap an Editor's monthly spend, open **Settings > Governance > Budgets** and click **Add rule**. Pick **Role** as the scope, **Editor** as the target, set the period to **Monthly**, and fill in a max-cost in USD. Save and the next month-period request that would push an Editor over the cap is refused with a budget-exceeded error. A warning threshold below the cap fires an alert before the cap hits. Narrower scopes override broader ones — a user rule beats a team rule beats a role rule — and org-wide limits always apply on top as an additional cap. ## The four policy layers **Budgets** are token, cost, and request caps per scope and period. Scopes are org, role, team, user, or API key. Each rule carries a token cap, a cost cap in USD, an optional request cap, and a warning threshold expressed as a percentage of the cap. An API-key rule targets one issued key (pick **API key** as the scope, then the key from **Settings > API**) and caps only the traffic authenticated with that key — the REST and OpenAI-compatible API — so you can meter a single connector without touching in-app usage. Image generation is metered by cost and request count, not tokens — an image request reports no tokens, so cap image spend with the cost or request limit, not the token limit. **Feature controls** toggle web search, code execution, and file upload per scope, and cap the max context tokens for AI replies. A feature off for a scope hides the toggle in chat and refuses the request server-side. **Upload policy** gates the file extensions, MIME types, and sizes a member can attach. It also caps the total volume per user — useful when storage is metered. Toggle the policy off for a permissive default; toggle it on to enforce the lists. **Retention policy** decides how long each data type (chat history, documents, prompts, audit logs, usage ledger, workflow runs, and more) stays before the cleanup pass removes it. The page shows the operator-imposed bounds, the per-org override within those bounds, and a grace window before hard delete. ## Precedence All four layers share the same scope ladder: user > team > role > org > default. The narrowest rule wins. Where a layer carries an org-wide cap (budgets), the cap applies as an additional ceiling on top of any narrower rule. An API-key budget sits outside the ladder as its own independent bucket: it binds the key's own requests regardless of the owner's user, team, or org caps, so a single credential can be held to a tighter allotment than the person who issued it. ## Retention bounds and approvals Retention policy sits inside operator-imposed bounds — the self-hosted operator sets a floor and a ceiling per category, and the org's value clamps to that range. When the operator proposes a tighter floor or a lower ceiling, the change surfaces as a proposal Admins can apply or reject. Reductions to the policy land with a pending-change banner and a grace window before they take effect — the same grace gives Admins a chance to cancel. ## Session idle timeout Session idle timeout signs members out after a period of inactivity — the session-bound control compliance frameworks ask for (SOC 2 CC6.1). Open **Settings > Governance > Security & Monitoring**, switch on **Enable session idle timeout**, and set **Idle timeout (minutes)** (1–1440, default 30). Members see a warning shortly before the cut-off; after it, the active tab signs out and the login page explains the sign-out instead of presenting a bare form. The window can only tighten the deployment-wide limit, never loosen it. Self-hosted operators set that hard cap with an environment variable (see the [environment reference](/self-hosted/configuration/environment-reference)); the org policy applies on top, and the stricter of the two windows wins. A member of several organisations gets the strictest window across all of them. Enforcement has two halves. The watchdog in the browser ends open, visible sessions on the minute. Closed tabs and abandoned devices are caught server-side by a revocation sweep that runs about every five minutes — a session can therefore outlive the window by a few minutes; when you state the control to an auditor, count the window plus roughly half an hour in the worst case. Every server-side revocation lands in the [audit log](/platform/admin/governance/audit-logs) as `session.idle_revoked`. One caveat for trusted-headers deployments: the reverse proxy owns authentication there, so a revoked session is re-established as soon as the member confirms the sign-in notice — pair the policy with an idle timeout on the proxy or IdP side for a real lockout. ## Conversation routing Inbound mail lands unassigned unless a routing rule claims it. Under **Settings > Governance > Policies & limits**, open **Conversation routing** and add a rule mapping a recipient address to a team, a person, or both: the next conversation that arrives at that address is assigned the moment it is created, before anyone opens the inbox. A rule matches the address the sender wrote to — the conversation's `To` — case-insensitively; an address with no rule stays unassigned. Visibility is built in: a conversation assigned to a team is visible only to that team's members, and one assigned to a person only to that person (the union when both are set). True unassigned conversations — no person and no team — are visible only to admins and owners, who triage them. Members and Editors only see work routed or assigned into their person or team queue. Pair routing with the header **Assignee** control so inbound land in the right queue on arrival. Routing only ever assigns; it never reassigns a conversation that already has an owner or team, so a reply threading into an existing thread is left alone. A rule pointing at a since-deleted team or person is skipped — the conversation still arrives, just unassigned for admin triage. ## Where this fits Policies and limits is the budget and gate layer that protects the org from runaway spend and unintended access. Pair it with [content and models](/platform/admin/governance/content-models) so the model the budget caps is also the one the access list permits, and with [retention policy on the same page](#retention-bounds-and-approvals) so the data the org keeps is bounded too. The companion is [audit logs](/platform/admin/governance/audit-logs) — every policy change here lands there as a permanent record. # Run-code policy Source: https://tale.dev/docs/platform/admin/governance/run-code-policy Run-code policy is the surface where you decide which Python and Node packages the sandbox can install at execution time. Skills with scripts and the Run code tool both run in the same sandbox; this policy is the single seam where you tighten or loosen what they can install. Admins and Owners read this page when an agent needs a new library, or when an audit asks why a package was blocked at a given time. ![The Run-code policy governance page with Allowlist picked in the default-mode radiogroup, above a Python allow list holding pandas, numpy, scipy, and scikit-learn, a Python deny list holding paramiko, fabric, pexpect, and scapy, and a Node allow list holding axios, date-fns, dayjs, and lodash.](/images/platform/governance-run-code-policy.webp) ## A worked switch The default mode is **Denylist** with an empty list, which means every package is installable. To switch to a curated set, open **Settings > Governance > Run-code packages**, change the mode to **Allowlist**, and enumerate the packages you trust under **Python allow list** and **Node allow list**. Save and the next sandbox run that requests a package outside the list fails with the **not on the allow list** reason in the audit event. ## The two modes | Name | Default | Description | | --------- | ------- | ----------------------------------------------------------------------------------------------------------------- | | Allowlist | off | Only the listed packages install; everything else is rejected. Use when a regulator names the approved libraries. | | Denylist | on | Every package installs except the listed ones. Use when a small set is known-bad and the rest is trusted. | ## The four lists Each mode reads from two lists — Python and Node. One package per line, or comma-separated. Version constraints are stripped automatically (`pandas==2.1` matches `pandas`), so the policy is name-based and survives library upgrades. Scoped Node packages (`@scope/pkg`) are supported. The lists are independent per language: a Python allowlist plus a Node denylist is a valid combination, and means Python is strict and Node is permissive on the same sandbox. ## The tester The Test panel on the same page lets you paste pip or npm specs and see whether each one would pass under the current draft. It uses your unsaved edits, so you can iterate before clicking Save. Each spec is parsed, stripped of its version constraint, and matched against the lists; the panel reports **Allowed** or **Denied** with the reason — matches-the-allow-list, not-on-the-allow-list, matches-the-deny-list, not-on-the-deny-list. ## Network egress and skills The package policy gates _what_ runs in the sandbox. The same sandbox runs skill scripts — see the [Skills concept](/platform/agents/skills) page. Outbound network from sandbox code is open by default, with cloud-metadata and private-range targets always blocked; on self-hosted deployments the operator can restrict it to a hostname allowlist at the deployment level — the walk lives in [Hardening](/self-hosted/operate/security/hardening). Treat publishing a skill with a script as widening the trust surface for every agent that picks it up; the package policy and the deployment's egress policy together decide what the script can do. ## Where this fits Run-code policy is the gate on the sandbox that backs both the Run code tool and skill scripts. The companion concept is [Agent skills](/platform/agents/skills) — it covers when to publish a script as a skill, and why the package policy is the load-bearing gate. The companion governance page is [audit logs](/platform/admin/governance/audit-logs) — every denied package install lands there with the spec and the reason. # Trash Source: https://tale.dev/docs/platform/admin/governance/trash Trash is the recovery surface for the rows retention has soft-deleted but not yet hard-deleted. When a chat thread, a document, a prompt template, or a workflow run exceeds its retention window, it moves here for the configured grace window before the next cleanup pass removes it for good. Admins and Owners read this page when a member asks for a deleted artefact back, when a workflow deleted the wrong thing, or when an audit needs to know whether a row is still recoverable. ## A worked restore To restore a chat history thread, open **Settings > Governance > Trash** and switch the **Category** filter to **Chat history**. Each row carries the type, the name, the owner, the status, and when it was trashed. Click **Restore** on the row, confirm in the dialog, and the row returns to its source list — chat threads reappear in the conversation inbox and documents in the knowledge base. Restoring a retention-expired row requires typing `restore` to confirm and is audited as an override of the retention policy. ## The two statuses **Trashed** is the normal soft-delete state. The row's retention window elapsed, it moved to trash, and the grace window is still ticking. Restore returns the row to its source list with no policy override. **Expired** is the second state — the grace window ran out and the row is queued for permanent deletion at the next cleanup. Restore is still possible but is an override: the dialog asks you to type `restore` and the audit log records the override with your name. ## The categories Trash holds rows from many categories. The category filter switches the view per tab: - Chat history (threads) - Documents - Temporary files - Prompt templates - Message feedback - Contacts - Vendors - External conversations - Message metadata - Workflow runs - Workflow trigger logs - Usage ledger - Audit logs - Chat filter events - Memory audit Each category honours its own retention window and its own grace window — set on the retention policy in [policies and limits](/platform/admin/governance/policies-and-limits). ## Legal hold interaction Rows under legal hold do not appear in trash — the hold pins them out of reach of every retention step. When you try to delete a held row from its source list, Tale refuses with the **Delete is blocked by an active legal hold** message. Release the hold to let retention sweep the row through the trash window the way other categories flow. ## The grace window The grace window is configurable per category on the retention policy. A grace of zero skips trash entirely — the cleanup pass hard-deletes the row immediately when retention triggers. A grace above zero keeps the row in trash for that many days and surfaces it here for the Admin window where restore is still cheap. ## Where this fits Trash is the second chance retention gives every category before the cleanup pass removes a row for good. It pairs with [policies and limits](/platform/admin/governance/policies-and-limits) — the retention page sets the windows; this page is the recovery view those windows feed. The companion is [legal hold](/platform/admin/governance/legal-hold), which is the only mechanism that beats retention before a row ever lands in trash. # Usage analytics Source: https://tale.dev/docs/platform/admin/governance/usage-analytics Usage analytics is the dashboard that aggregates every billable AI call into a single view of tokens, cost, and request volume. It slices by user, team, role, model, agent, and time so the unexpected line on the bill is traceable to the workload that drove it. Admins and Owners read this page when a bill is unexpected, when leadership wants the rough shape of AI spend, or when a budget alert fires and the next question is _who and what_. ## A worked drill-down Open **Settings > Governance > Usage**. The default view is the last 30 days, org-wide, with the three headline counters — total tokens, total cost in USD, total requests. Switch the breakdown to **By user** to find the heaviest consumers, **By model** to compare an expensive primary against a cheaper fallback, or **By agent** to find the agent driving the load. Each row clicks through to a per-row time series; the chart axis follows the chosen period. ## The dimensions - **User** — every member who has triggered a billable call. Pair with the team or role filter to scope the view. - **Team** — aggregated across team members; useful when budgets are team-scoped. - **Role** — Owner, Admin, Developer, Editor, Member. - **Model** — every model that produced a reply, grouped by provider. - **Agent** — every named agent (the leaderboard sorts by token volume, cost, or request count). - **Time** — daily trend for short windows, weekly for longer windows. ## The cost model Cost is an estimate. Each request lands in the usage ledger with input tokens, output tokens, the model's published price per million tokens, and the wall-clock duration. The dashboard multiplies tokens by price; image generation calls land with a per-image cost the provider returns. The ledger row is the source of truth, and the [audit log](/platform/admin/governance/audit-logs) carries the row's actor and timestamp for cross-reference. ## Budget overlays When [policies and limits](/platform/admin/governance/policies-and-limits) has a budget for a scope, the usage chart overlays the cap as a horizontal line. Hovering a point shows the percentage of the cap consumed and the projected month-end based on the current trend. Crossing the warning threshold paints the chart's series amber; crossing the cap paints it red and surfaces the budget-exceeded events as markers on the time axis. ## Retention of usage rows The usage ledger has its own retention window in [policies and limits](/platform/admin/governance/policies-and-limits). Default is 365 days; shorten it and the historical chart truncates accordingly. The dashboard reflects whatever the ledger holds — there is no archive layer underneath. ## Where this fits Usage analytics is the spend and volume side of the same workload [feedback analytics](/platform/admin/governance/feedback-analytics) reads for quality. Together they answer _is this agent worth its cost_. The companion is [policies and limits](/platform/admin/governance/policies-and-limits) — the page where the budgets this dashboard overlays are configured. # Members and roles Source: https://tale.dev/docs/platform/admin/members-and-roles Members are the people in your organisation who can sign in to Tale. Roles control what each member can do — read, write, configure, govern. This page is the canonical reference for the six roles and the resource-level permissions each role carries. Six roles cover almost every team Tale ships to. Admins and Owners read this page when they are setting up a team for the first time, when an audit asks who has access to what, or when they need to know whether to give a new hire Editor or Developer. Prefer to watch first? Episode 8 walks the roster, the role ladder, and the team walls in two minutes — captions included. ![The Organization settings page with its Members section listing the workspace owner and an Add member button.](/images/get-started/settings-organization-members.webp) ## Adding a member To add a person to your organisation, open **Settings > Organization**, scroll to the **Members** section, and click **Add member**. Fill in their **Name**, **Email**, and **Role**, and set a **Password** — Tale does not send an email invite, so a password is required to create a new account. (If the email already belongs to a Tale account, no password is asked: the person signs in with their existing credentials and is simply added to this organisation.) On **Add member**, Tale shows the new sign-in credentials **once**, with the reminder to save them now because they won't be shown again. Relay them to the new member out of band — there is no reset email. Anyone who later forgets their password contacts an admin, who can set a new one from the same Members section. Pick the role on the form before you submit; promoting or changing it later is a one-click change in the same Members section. ## The six roles **Owner** has every permission Admin has, plus the one Admin lacks: transferring ownership and deleting the organisation. Most teams have exactly one Owner; some keep two for continuity. **Admin** governs the organisation: members, providers, branding, governance policies, connectors, the audit log. Admins do everything Editor does and everything Developer does, plus the configuration surface. They cannot transfer ownership. **Developer** builds: agents, workflows, connectors, API keys, MCP servers. Developers can read every resource and write to most of them, including governance policies (read-only). Reach for Developer when someone needs the API plane and the connector tooling. **Editor** curates and operates: agents, the knowledge base (documents, contacts, products, vendors, websites), the conversation inbox, approvals, the skill library. Editors can read workflows but not modify them; they can read connectors but not configure them. Reach for Editor when someone runs the day-to-day product work without touching the API or connector plane. **Member** runs: chat, browse the knowledge base, and read conversations and approvals. Conversation read is assignment-scoped: Members see threads assigned to them or queued to their teams; true unassigned mail is admin triage only — use [Conversation routing](/platform/admin/governance/policies-and-limits#conversation-routing) so inbound lands in a team queue on arrival. Members write only to message feedback (thumbs up / down). Reach for Member as the default — most users in most organisations are Members. **Disabled** has no permissions. Use it to revoke access without deleting the account; transcripts and audit history stay intact, and re-enabling restores the previous role. ## The permission matrix | Resource | Owner | Admin | Developer | Editor | Member | Disabled | | --------------------- | ----- | ----- | --------- | ------ | ------ | -------- | | Agents | R / W | R / W | R / W | R / W | R | — | | Documents | R / W | R / W | R / W | R / W | R | — | | Products | R / W | R / W | R / W | R / W | R | — | | Contacts | R / W | R / W | R / W | R / W | R | — | | Vendors | R / W | R / W | R / W | R / W | R | — | | Projects | R / W | R / W | R / W | R / W | R | — | | Websites | R / W | R / W | R / W | R / W | R | — | | Conversations | R / W | R / W | R / W | R / W | R | — | | Conversation messages | R / W | R / W | R / W | R / W | R | — | | Approvals | R / W | R / W | R / W | R / W | R | — | | Workflow executions | R / W | R / W | R / W | R | R | — | | Workflow processing | R / W | R / W | R / W | R | R | — | | Connectors | R / W | R / W | R / W | R | R | — | | OneDrive sync configs | R / W | R / W | R / W | R | R | — | | Prompt templates | R / W | R / W | R / W | R / W | R | — | | Audit logs | R / W | R / W | R / W | R / W | R | — | | Governance policies | R / W | R / W | R | R | R | — | | Message feedback | R / W | R / W | R / W | R / W | R / W | — | | MCP servers | R / W | R / W | R / W | R | R | — | R = read, W = write, — = no access. The matrix is the authoritative description of what each role can do across the resources Tale tracks; the rows are the same set the in-product permission system uses at request time. ## The Settings surface and the menu Members, Editors, and Disabled users do not see the configuration surface — only their own personal settings. Developers see the organization settings but not the governance sub-tree (except read views). Admins and Owners see everything. The settings menu is grouped into **Personal** (Account, Preferences, Environment — every role), **Organization** (Teams, the Members section, AI providers, Branding, Governance, and the rest — Admin-and-Owner, with Developers seeing a subset), and **Development** (the API and data-residency surface). Governance is an item inside the Organization group, not a group of its own, and it needs Admin access. ## Edge cases **Transferring ownership** requires an existing Owner to nominate a current Admin or Owner; the new Owner role takes effect immediately. The previous Owner becomes Admin unless explicitly downgraded. **Last Admin warning.** The Members section warns when removing or downgrading the last Admin or Owner. The action is allowed — Tale does not lock you out — but you should keep at least two Admin-or-Owner accounts for continuity. **Resetting 2FA** is on the member's row in the Members section. Resetting clears the second factor; the next sign-in re-enrolls. ## Where this fits Roles are the access surface every other admin page touches: SSO authenticates them, API keys belong to them, audit logs name them, governance policies scope behaviour by role. The next page worth reading depends on what you are doing next. If you are wiring sign-in to your identity provider, [authentication](/self-hosted/configuration/authentication) covers the four sign-in modes. If you are scoping access by team rather than by role alone, [Teams](/platform/admin/teams) covers the per-team scoping layer. # Admin Source: https://tale.dev/docs/platform/admin/overview Admin is the configuration plane of Tale. It covers the people who can sign in, the teams that group them, the AI providers behind every reply, the API keys that let external code talk to the org, the third-party connectors agents reach through, and the branding the rest of the org sees. Only Admins and Owners see the full Admin menu; Developers see a subset, and other roles do not see it at all. These pages describe what each setting does and what it changes about the running product. Most are read once during setup and revisited when something changes — a new hire, a rotated key, a new provider. The role-and-permission story behind the whole menu lives in [Members and roles](/platform/admin/members-and-roles); start there, because every other Admin page references the role names it defines. Prefer to watch first? Episode 9 tours the whole control room — providers, guardrails, audit, cost — in three minutes, captions included. ## Configuration areas The six roles and the resource-level matrix that says who can read, write, configure, and govern. Group members into teams that share agents, skills, and connectors. Every agent the org has, and where an Admin steps in when one needs governance. Store the credentials behind every reply and pick which models the org may call. Store and replace the credentials behind Slack, Gmail, Outlook, Google Drive, GitHub, Shopify, and more. Wire sign-in to your identity provider with SAML or OIDC. Mint and scope the keys external code uses to reach Tale's REST API. The name, logo, and colors the rest of the org sees. Require a second factor for sign-in and manage enrolment across the org. The in-product record of what shipped and when. Audit logs, policies and limits, guardrails, analytics, retention, and legal hold. ## Where this fits Admin is the surface every other tab assumes. Chat resolves a model through the providers configured here; agents call tools through the connectors configured here; the skill library and the inbox respect the team boundaries configured here. The natural first read is [Members and roles](/platform/admin/members-and-roles) — every other Admin page references the role names it defines. # AI providers Source: https://tale.dev/docs/platform/admin/providers Nothing in Tale answers a prompt until your organisation holds a working credential for at least one AI provider. **Settings > AI providers** is where those credentials live, and it is the only place they can be created. Admins and Developers can open the page; everyone else meets its result later, as the list of models they can choose in chat, on an agent, or on a workflow step. ## Connectors and credentials Two different things meet on this page, and telling them apart makes the rest of it obvious. A **connector** is Tale's built-in knowledge of one provider: which wire dialect it speaks, which endpoint it answers on, where its model list comes from, and which kinds of authentication it accepts. Connectors ship with the platform. You cannot add, edit, or remove one from the UI, and a platform upgrade can bring more. A **credential** is your organisation's half — the part that actually authorises a call. You store as many as you need against a connector: a production key beside a staging key, one key per department, an ops-managed variable next to one you rotate by hand. Each credential carries a name, an authentication method, an optional model allowlist, and an enable state, and one of them is the default. These are the connectors that ship today: | Connector | Wire format | Model catalog | | -------------------- | ---------------------- | ------------------------ | | OpenRouter | OpenAI-compatible API | OpenRouter catalog | | OpenAI | OpenAI-compatible API | Built-in catalog | | Anthropic | Anthropic Messages API | Built-in catalog | | Gemini | OpenAI-compatible API | Built-in catalog | | Azure OpenAI | OpenAI-compatible API | No catalog | | DeepSeek | OpenAI-compatible API | Built-in catalog | | Moonshot AI (Kimi) | OpenAI-compatible API | Built-in catalog | | Qwen (Alibaba) | OpenAI-compatible API | Built-in catalog | | SpaceXAI | OpenAI-compatible API | Built-in catalog | | Z.ai (GLM) | OpenAI-compatible API | Built-in catalog | | Vercel AI Gateway | OpenAI-compatible API | Provider models endpoint | | Nous Portal (Hermes) | OpenAI-compatible API | No catalog | ## What the page shows **Credentials** is a table of what your organisation actually holds — one row per stored credential, not one per shipped provider. A row shows its name, the provider it authenticates, its authentication method, and its coordinates: a masked preview of the stored key or the name of the environment variable behind it, plus the credential's own endpoint URL where the provider needs one and how many models its allowlist permits. A **Default** badge marks the one requests fall back to, a **Disabled** badge any that is switched off. The row's actions menu holds everything else. Two warnings surface here rather than inside a dialog. A provider whose model catalog could not be fetched says so on every row that depends on it — a working key is still useless when Tale cannot tell which models the provider serves. And a provider with credentials but no default is named above the table: requests cannot pick one automatically until you promote one. Below the table, **Harnesses** reports how each coding harness resolves for your organisation. It is read-only; the credentials above are what change it. ## Adding a credential **Add credential** opens the shipped catalog. Providers you already hold a credential for come first, under **In use**; everything else follows below it, alphabetically. Each entry names its wire facts — the API format and endpoint host, as in `OpenAI-compatible API · openrouter.ai`, or `endpoint set per credential` — and how many models its catalog holds. Search narrows the list; picking one moves you to the form, and **Back to the catalog** returns. Because the form belongs to the provider you picked, it only offers what that provider accepts — you are never asked for a base URL the platform already knows. The method switches the rest of the form: a secret field for **API key** and **Subscription key**, a variable name for **Environment variable**, the full broker form for **Subscription broker**. **Name** is what every later screen shows instead of the secret. Name it for its purpose — `Production key`, `Finance team`, `Ops-managed` — because that is the label someone will pick from months later. **Model allowlist** is optional. Leave it empty and the credential may use everything in the connector's catalog; set it and the credential is confined to what you picked. ### API key Paste the secret into **API key**. Tale stores it encrypted and never shows it again — the row displays a masked preview, not the key. To rotate, open the row's menu and choose **Replace API key**; the replacement takes effect everywhere that credential is used, at once. ### Environment variable Here the key never enters Tale. It lives on the deployment, and the credential records only the name of the variable that holds it. Type the suffix; the reserved prefix `TALE_PROVIDER_KEY_` is fixed and cannot be edited away. Any name outside that prefix is rejected, so the field can never be pointed at an unrelated deployment secret. Names are capped at 40 characters. The variable itself is provisioned by whoever runs the deployment — the operator side is documented in [Providers](/self-hosted/configuration/providers). ### Vendor subscriptions and brokers Two methods cover subscriptions rather than metered API keys. **Subscription key** stores a vendor's subscription secret directly; a Nous Portal subscription is one shipped case. **Subscription broker** points at an endpoint that hands out a pool of rotating OAuth tokens — the shape a Claude subscription uses. The broker form asks for the **Broker endpoint** and its **HTTP method**, then how Tale authenticates to the broker under **Broker authentication**: None, Bearer token, or Custom header, with a **Header name** and the **Broker secret**, or **Secret from environment variable** when your operations team holds it. The rest describes the response — the **Token array path**, the **Token field**, the **Target environment variable** the chosen token is injected into, and a **Token selection** strategy of Random, First usable, or Round-robin. **Advanced** carries the tuning: **Status field**, **Active status value**, **Expiry field**, **Request timeout (ms)**, **Max response size (bytes)**, and **Expiry safety margin (ms)**. Both kinds are consumed inside the vendor's own tooling rather than over a plain API call, so the dialog says so: **Runs sandboxed on its provider's harness.** An Anthropic subscription broker runs on the `claude-code` harness, a Nous Portal subscription key on `hermes`. Direct API calls are never offered for these credentials. ## Connectors that set the endpoint per credential Azure OpenAI has no fixed endpoint because every Azure resource serves its own, in the form `https://.openai.azure.com/openai/v1`. Its section header says the endpoint is set per credential, and its dialog adds an **Endpoint URL** field so each credential carries the resource it belongs to. Azure also ships no model catalog, and the reason is worth knowing before you fill the form: on Azure the model id in a request is the deployment name you chose inside the resource, which Tale cannot know in advance. Type those names into the credential's **Model allowlist** as a comma-separated list. Without them, the credential makes no model available at all. ## Choosing the default credential A request that names no credential uses the connector's default. That covers most traffic, so the default is the credential you want ordinary work to land on — the shared production key rather than the experiment. Open a row's menu and choose **Make default**. One credential per connector holds it, and promoting a different one moves it. A disabled credential cannot become the default. Leave a connector without a default and the platform will not choose for you: it says so on the page, and requests that do not name a credential have nothing to resolve to. ## Narrowing what a credential may call **Model allowlist** limits one credential to a subset of its connector's models. With a catalog behind it the field is a searchable multi-select; without one it is a free-text list of ids. Leave it empty and the credential may use the whole catalog. Set it and the row shows the count, and anything outside the list stops resolving through that credential. An allowlist narrows one credential. To narrow what a person, team, or role may pick across every provider at once, use the model-access rules under [Content and models](/platform/admin/governance/content-models). The two compose: a model has to clear both before it appears in a picker. ## Keeping the model catalogs current **Refresh catalogs** sits in the page header. It re-fetches every live catalog and reports one line per connector — the number of models it found, or the error it hit, so a provider that is down is named rather than silently skipped. Catalogs that ship with the platform need nothing: when every connector has one, the report says there is nothing to refresh. Live catalogs are cached between refreshes and there is no background sync, so a model published this morning appears once somebody presses the button. ## Disabling and deleting credentials **Disable** switches a credential off while keeping its configuration and its allowlist. Reach for it when a key is suspected, a quota is exhausted, or a department is paused — re-enabling is one click and nothing has to be re-entered. Deleting is immediate and total. Agents and requests using that credential lose access to the provider straight away, so re-point anything that depends on it first. Deleting the default leaves the connector without one until you promote another, which the confirmation tells you before you commit. ## Where this fits This page is the floor everything else stands on: an agent, a chat reply, a workflow step, a knowledge-base embedding all resolve to a model, and a model is only reachable when a credential on this page can call it. Which models that leaves you is covered in [Model catalog](/platform/models), the governance layer that narrows them further in [Content and models](/platform/admin/governance/content-models), and the deployment-side variables an operator provisions in [Providers](/self-hosted/configuration/providers). # Teams Source: https://tale.dev/docs/platform/admin/teams A team is a named group of members that shares access to agents, prompts, projects, connectors, and conversations. Where roles define what a person _can_ do, teams define which slice of the org's data that person works in. Most orgs end up with a handful of teams — support, sales, ops — and most of the day-to-day permission decisions land on the team boundary, not the role boundary. Admins manage teams under **Settings > Teams**. This page is the reference for what a team owns, how membership works, and how the team boundary interacts with the role-based permissions documented under [Members and roles](/platform/admin/members-and-roles). Read it once when you stand up the org's teams; come back when you reorganise. ![The Teams settings page listing three teams — Growth, Platform engineering, and Customer success — each with one member and the date it was added, beside a Create team button.](/images/platform/settings-teams.webp) ## What a team owns A team holds membership and a set of resources scoped to it. The resources are: - **Agents** — agents created with a team scope are visible and editable only by members of that team. Org-wide agents stay visible to everyone with the right role. - **Prompts** — saved prompts with `Team` visibility appear only to that team's members. Personal prompts stay private to their owner; Global prompts are visible org-wide. - **Projects** — projects can be assigned to a team; the team's members inherit project access without being added one by one. - **Connectors** — connectors restricted to certain teams (under the **Allowed teams** lever on **Settings > Connectors**) only appear in pickers for those teams. - **Conversations** — a conversation can be assigned to a team as well as to an individual, from the assignee picker in its header. Visibility follows that assignment: a team queue is visible to that team's members, a person assignment to that person, and admins and owners see everything. True unassigned conversations (no person, no team) stay with admins for triage — pair with [Conversation routing](/platform/admin/governance/policies-and-limits#conversation-routing) so inbound lands in a team on arrival. A resource without a team scope stays visible to everyone whose role allows it. Teams are an _additive_ scoping layer — they narrow visibility, never widen it. ## Creating a team Open **Settings > Teams** and click **Create team**. Give the team a name (`Support`, `Sales`, `Operations`) and an optional description; the name appears everywhere the team shows up — pickers, badges, team-scoped document access, and the project assignment field. Saving creates an empty team you can fill with members from the team's row. The team's row carries three sub-views: **Members** (who is in the team), **Resources** (what the team owns), and **Settings** (the team's name, description, and lifecycle). The Resources view is the easiest way to see what a team can reach into; it doubles as the audit surface when someone asks why a team can see a particular agent. ## Adding and removing members Open the team's row and click **Add members**. The picker lists the org's members; checking one adds them to the team. A member can belong to multiple teams; their access is the union of every team they are in plus their role's org-wide reach. Removing a member from a team strips the team-scoped visibility on the next request; in-flight chats finish, but the next thread does not see the team's resources. ## Team versus role The role decides what a person can do; the team decides what they can do it to. A Member-role user in the Support team can read the support team's agents but cannot edit them; a Developer-role user in the Support team can read and write the support team's agents but cannot see Sales's. Teams never grant capabilities the role lacks; roles never widen visibility past the team scope. When you need a permission decision the existing roles and teams cannot express, the next lever is a governance policy — see [Members and roles](/platform/admin/members-and-roles) for how policies attach to roles, and the governance section for the policy fields themselves. ## Deleting a team Click the team's row, then **Delete team**. Deletion is hard-stop — the team is gone, every team-scoped resource it owned moves to org-wide visibility, and members lose the team-scoped slice of their access. There is no undo; orphaned resources stay reachable by everyone whose role allows them, which is rarely the right outcome. Reach for delete when a team is genuinely retired, not when it is reorganising. ## Where this fits Teams are the scoping layer right below roles — roles say _what_, teams say _where_. The natural next read depends on the resource you are scoping: [Skill library](/platform/workspace/skills) for how a shared instruction reaches everyone, [Connectors (admin view)](/platform/admin/connectors) for the credentials a team's automations call, and [Projects](/platform/projects/overview) for project-to-team assignment. # Two-factor authentication Source: https://tale.dev/docs/platform/admin/two-factor-authentication Two-factor authentication adds a second proof of identity on top of the password — a six-digit code from an authenticator app, or a WebAuthn passkey. Tale ships TOTP (time-based one-time passwords) compatible with Google Authenticator, 1Password, Authy, and any other app that follows the standard, plus passkeys for a phishing-resistant alternative. The page covers per-user enrolment, passkeys, the backup codes that recover an account when the phone is gone, the org-wide enforce policy, and the admin reset for a locked-out member. Two-factor is optional by default. Admins can require it for the whole organisation with a grace window so members have time to enrol. ## Per-user enrolment To turn 2FA on for your own account, open **Account > Security**. Click **Enable two-factor**, confirm your password, and scan the QR code with an authenticator app. Enter the six-digit code the app shows to verify the secret was captured, then save the backup codes the next screen presents. The codes show once — download or copy them before clicking **Done**. The same screen carries **Disable** and **Regenerate backup codes**. Disabling clears the second factor; regenerating invalidates every previous backup code. Both actions require the account password as a confirmation. ## Backup codes Backup codes are single-use strings the platform mints when 2FA is enabled or regenerated. Each one substitutes for the authenticator code on a single sign-in — useful when the phone is lost, the authenticator is uninstalled, or you are stuck somewhere without the device. The platform watches the remaining count and surfaces a low-balance banner when only a few codes remain; the banner links straight to the regenerate flow. Treat backup codes like passwords. Store them in a password manager or print them and lock them away. Anyone who has both your password and a backup code can sign in as you. ## Passkeys A passkey is a WebAuthn credential — Face ID, Touch ID, Windows Hello, or a hardware security key — that signs a per-login challenge instead of producing a typed code. The credential is bound to the site's origin, so a look-alike phishing domain gets nothing to replay; that makes a passkey phishing-resistant in a way TOTP is not, and it satisfies an enforced two-factor policy exactly like TOTP does. To register one, open **Account > Security** and click **Add a passkey**. Give the credential a name you will recognise later, then pick the **Authenticator type**: **Any (recommended)** lets the browser offer everything available, **This device (Face ID, Touch ID, Windows Hello)** narrows the ceremony to the built-in authenticator, and **Security key or phone** narrows it to a roaming one. The browser runs the registration ceremony from there. Each entry in the same list carries a **Remove** icon button for revoking your own credentials; it asks you to confirm before the passkey is removed. A registered passkey works at three doors. On the login screen, **Sign in with a passkey** signs you in without typing the password — the credential is itself strong proof. On the verification screen after a password login, **Use a passkey instead** replaces the six-digit code. And on the enrolment screen an enforced policy routes unenrolled members to, **Register a passkey instead** sits next to the TOTP setup — a member who registers only a passkey, never TOTP, passes the policy. When a member loses a device with a passkey on it, an Admin revokes the credential: open **Settings > Organization**, click **Edit member** on the member, and remove the credential from the **Passkeys** section of the dialog. Tale deletes the credential and ends every active session of that member, so a lost or stolen authenticator can't keep a session alive. Registration, self-removal, admin revocation, and every passkey sign-in land in the audit log (`passkey_added`, `passkey_removed`, `passkey_revoked_by_admin`, `passkey_sign_in`). ## The enforce-for-org policy Admins can require two-factor for every password-authenticated member of the organisation. Open **Settings > Governance > Security & Monitoring** and, under **Two-factor authentication**, toggle **Require two-factor authentication**. The policy carries a grace period (in days) that gives each member time to enrol from their first sign-in under the policy; set it to zero for immediate enforcement. ![The Security and Monitoring governance page showing login-attempt limit fields and the password-policy character-class requirements; the two-factor policy is further down the same page.](/images/platform/governance-security-monitoring.webp) | Field | Type | Required | Description | | --------------------------------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------- | | Require two-factor authentication | Toggle | yes | Off keeps 2FA optional for every member; on turns the policy on. | | Grace period (days) | Integer | yes | Days from a member's first signed-in moment under the policy before enrolment is required. Zero means immediate. | | Exempt SSO-only users | Toggle | no | When on, members whose only account is a federated identity rely on the upstream IdP for MFA. | A member inside the grace window sees a count-down banner in the app pointing them at the enrolment flow. Once grace expires, the next sign-in routes through the enrolment screen and the member cannot continue until they have enrolled. ## Admin reset for a locked-out member When a member loses their phone and their backup codes, an Admin clears the second factor on their account. Open **Settings > Organization**, click **Edit member** on the member, and click **Reset two-factor** in the dialog. Tale disables 2FA for the account and ends every active session, so the member re-enrols on their next sign-in. The reset is recorded in the audit log under `2fa_reset_by_admin`. Reach for it as a recovery action — the member should re-enrol immediately once they are back in. ## Where this fits Two-factor sits one layer above the password — same login screen, second step. Pair it with [members and roles](/platform/admin/members-and-roles) (the admin who resets the second factor is the same admin who manages the account), with [policies and limits](/platform/admin/governance/policies-and-limits) (the enforce policy lives in the governance surface), and with [audit logs](/platform/admin/governance/audit-logs) (every enrolment, disablement, and admin reset lands there). # Agent concepts Source: https://tale.dev/docs/platform/agents/concepts An agent is the unit Tale reaches for when the same question keeps coming back. It is a **persona** rather than a runtime: it says who is answering — a name, instructions, what it may reach for, and who in the organization may use it — and nothing about how a turn executes. Editors and Developers build them; every member runs them. This page hands you the mental model the rest of the section assumes. Read it once before you build your first agent, and come back to it when you cannot remember whether the behaviour you want to change lives in the instructions, the tools, the skills, or the knowledge scope. Prefer to watch first? Episode 4 builds an agent end to end in under three minutes, captions included. ## What an agent carries **Identity.** The slug the agent is filed under, the display name people meet it by, a short description of what it is for, and optional per-locale versions of those strings so a German or French reader gets the agent in their own language. The slug is fixed once the agent exists; the display name is yours to change whenever the job shifts. **Instructions.** The prose prepended to every turn the agent answers. Keep it short, opinionated, and concrete — long instructions get diluted in long conversations. Name the voice, the constraints, and the cases where the agent should decline. **Tools and skills.** Two allowlists. Tools name the capabilities the agent may call, and platform tools, connected connectors, and the organization's automations all appear as capabilities in that one list. Skills name the knowledge bundles it may expand, up to ten of them. Both follow the same rule: leave a list untouched and the agent is not narrowed, state a list and it is limited to exactly what you named. **Knowledge scoping.** One setting deciding which corpus the agent's retrieval may read — the organization's own documents, the pages fetched on its behalf, both together, or nothing at all. Retrieval runs only when the agent calls for it, so nothing lands in a reply that the agent did not go looking for. **Visibility.** `private`, so only its owner reaches it, or `org`, so every member does. A private agent names an owner, because an ownerless private agent would be reachable by nobody. ```mermaid flowchart LR I[Instructions] --> A((Agent)) T[Tools] --> A S[Skills] --> A K[Knowledge scope] --> A A --> R[Reply with citations] ``` ## What the agent does not decide The model is not part of the agent. Whoever composes the turn owns that choice — the composer's picker is models only, opening on **Auto** (Tale picks a model per message, and the reply records which one ran) with every directly-served model there to pin instead. An agent that pinned a model would quietly override the choice the person in front of the screen just made, so it holds none. The same reasoning retires several settings you might go looking for. A chat agent has no type and no harness picker: whether work runs on a coding [harness](/platform/agents/harnesses) is decided when you create a **project agent** (its dialog calls the field **Agent type**) or an automation **agent** node (there it is labeled **Harness**), and some provider credentials force one. It carries no execution deadline, because a ceiling belongs to the host running the turn rather than to a persona. It holds no environment variables and no credentials of its own — those live on the organization's provider records, where they can be rotated and audited in one place. And it ships no canned openers, because the composer is the entry point. ## Putting it together — a support-triage agent A first useful agent is the support-triage one: it reads the inbound question, answers what it can, and hands the rest on. The decisions: - Instructions: a one-paragraph voice, plus three explicit cases where it declines. - Tools: web search and the conversation tools. No code execution. - Skills: the house reply-tone bundle, so the wording matches everywhere it is used. - Knowledge: scoped to the organization's documents, with the crawled web left out. - Visibility: `org`, so the whole support team can pick it in the composer. The conversation then flows: your message arrives, the instructions frame the reply, retrieval finds the passages that support it, the granted tools fill the gaps, and the answer lands with citations. Escalation to a specialist is not a tool you toggle — it follows the worker relationships between agents, covered in [Agent workers](/platform/agents/delegation). ## When to reach for it A single agent is the right shape when the conversation stays in one domain and one voice. Reach for an [automation](/platform/automations/concepts) when the work has fixed stages and you want approvals or scheduling between them; reach for a plain chat with no agent when you are exploring an answer yourself and the model's own defaults are fine. | Use … when | Agent | Plain chat | Automation | | ---------------------------------------------- | ----- | ---------- | ---------- | | The same question recurs | ✓ | | | | The voice or the constraints matter | ✓ | | | | You need approvals or scheduling between steps | | | ✓ | | You are exploring an answer one time | | ✓ | | ## Build one An agent is identity, instructions, two allowlists, a knowledge scope, and a visibility setting — change one of them and you have changed how it behaves, change three and you have a different product. Everything about how a turn actually runs stays outside the persona, decided per conversation. The natural next read is [Create an agent](/platform/agents/create), which walks that editor tab by tab on a fresh instance. # Create an agent Source: https://tale.dev/docs/platform/agents/create This walkthrough goes from an empty create dialog to an agent your teammates can pick. The result is a persona that knows its domain, holds the tools it needs to act on what it reads, and is reachable from any chat in your organization. Budget about fifteen minutes. The running example is a support-triage agent — the same one [Agent concepts](/platform/agents/concepts) introduces. Substitute your own domain freely; none of the steps depend on the example. ## Before you begin Two things should be in place: - Your organization has at least one provider credential under **Settings > Providers**. The agent itself names no model — whoever sends a message picks one in the composer — but the composer has nothing to offer until a credential exists. Cloud users get one by default; self-hosted operators follow [Configuration → providers](/self-hosted/configuration/providers). - You hold the Editor role or higher here. Check [Members and roles](/platform/admin/members-and-roles) if you are not sure what you hold. ## Step 1 — Name it and decide who sees it Open **Agents** in the sidebar and create a new one. The dialog asks for a **Name** — the unique id used in links and the API, which you cannot change afterwards, so keep it descriptive and lowercase, `support-triage` rather than `agent2` — plus a **Display name** teammates meet it by and a short **Description**. Confirm and the editor opens on **General**. **General** is where identity lives: the display name, the description, an icon, and the agent's **visibility**. Keep an agent private while you are still shaping it and only you reach it; share it with the organization and every member can pick it in the composer. A private agent records an owner, which is you — an agent nobody owns and nobody can see would be reachable by nobody at all. ## Step 2 — Write the instructions Open **Instructions**. The field is plain markdown, capped at 20,000 characters, and it is prepended to every turn the agent answers. Three pieces of advice from the field: - **Open with the voice.** One paragraph naming who the agent is, who it answers to, and what tone it strikes. The model treats this as the strongest signal in the whole file. - **Name the refusal cases explicitly.** Three or four sentences saying what the agent declines to do, and what it says when it declines. - **Resist specifying every behaviour.** Long instructions get diluted in long conversations. If a behaviour belongs in code, lean on a tool; if it belongs in documents, lean on the knowledge scope; if it repeats across agents, lean on a skill. Instructions can be translated per locale alongside the display name and description, so a French reader gets an agent briefed in French rather than an English brief answering in French. ## Step 3 — Grant tools and skills Switch to **Tools**. Tools are individual switches grouped into category cards — contacts, products, files, knowledge, automations, and more — and each one you grant widens what the agent may read or change on your behalf. Grant the smallest set that does the job and leave the rest off. Connected connectors and the organization's automations appear in the same list, so binding one is the same move as granting a platform tool. ![The agent editor's Tools tab scrolled to the category cards, with Knowledge at three of four tools checked and Files at seven of seven, while Conversations, Discussions, Analytics, and Tasks & projects have none granted.](/images/platform/agent-editor-tools.webp) **Run code** executes scripts in a sandbox and is governed by the organization's [run-code policy](/platform/admin/governance/run-code-policy) — the switch grants the tool, the policy decides what a run may actually do. Then open **Skills** and bind the bundles this agent should be able to expand, up to ten. A skill is a knowledge pack from the organization's [skill library](/platform/workspace/skills): bind the house reply-tone bundle here and the triage agent phrases its answers the way every other agent does. Leave the list empty and the agent expands nothing. ## Step 4 — Scope its knowledge Switch to **Knowledge**. One setting decides which corpus the agent's retrieval may read: the organization's own uploaded **documents**, the **web** pages fetched on its behalf, **all** of it fused together, or **none**, which offers the agent no retrieval at all. Retrieval runs only when the agent decides it needs it — nothing is injected into a reply it did not ask for. Narrow the scope when you can. Everything in scope competes for relevance on every question, so an agent pointed at the documents that matter answers better than one pointed at everything the organization owns. ## Step 5 — Save it and try it Click **Save**. Open a new chat, pick the agent, pick a model in the composer's picker, and send a message that exercises the knowledge and the tools you granted. The model is your choice on every turn, so the same agent can answer a cheap question on a small model and a hard one on a large model without any edit. If the agent answers the way you wrote it, you are done. If it does not, the **History** button at the top right of the editor holds every saved version and lets you compare or restore — see [Agent versions](/platform/agents/versions). ## Troubleshooting - **The agent does not appear in the chat picker.** Its visibility is still private, so only you see it. Share it with the organization on the **General** tab. - **Replies ignore the knowledge.** The knowledge scope may be set to none, or the document may not be indexed yet — open it from [Documents](/platform/knowledge/documents) to check its state. - **A bound skill never gets used.** A model reaches for a skill by its description, so a vague description gets skipped; say what the skill does and when it applies. A bundle marked `disable-model-invocation` deliberately waits to be named. - **A tool call is refused at runtime.** A governance policy is gating the tool: the agent is allowed to call it, and the runtime declines. Check [Policies and limits](/platform/admin/governance/policies-and-limits). ## Where this gets used Creating one agent is the point where the rest of the platform starts to feel like Tale rather than a generic chat window. You have written a persona, drawn its boundaries with two allowlists and a knowledge scope, and left every question about how a turn runs to the conversation itself. The natural next walk is [Agent with knowledge](/tutorials/editor/agent-with-knowledge) — the same shape, but it binds a folder of documents and exercises the citation pipeline end to end. To see an agent hand a sub-task to a spawned worker, walk [Hand work to a worker](/tutorials/editor/delegate-between-agents). # Agent workers Source: https://tale.dev/docs/platform/agents/delegation Spawning is the move you make when one task deserves its own focused context: open-ended research, bulk extraction, drafting a long document. The agent you chat with composes a **worker** on demand — a name, task instructions, an optional operating method, and a tool grant — runs it, and folds the result back into its reply. Workers are ephemeral: they exist for one job, and their run is recorded as a **job card** in the chat. This page hands you the mental model for when a worker is the right shape and how the platform keeps it bounded. The end-to-end walk lives in [Hand work to a worker](/tutorials/editor/delegate-between-agents). ## How a job runs When the agent calls **spawn_agent**, Tale resolves the worker's capabilities, starts a fresh child conversation, and runs the worker non-interactively: it sees only the task input the agent sent (not the whole chat history), tracks its progress on a live checklist, and its final message comes back to the agent as the result. The chat shows a job card with the worker's name, live progress, terminal status, and an expandable transcript of everything it did. Workers cannot talk to the user. If a worker needs input only a human can give, it says so in its result and the agent asks you — questions always come from the agent you actually talk to. ## Capabilities are a subset, always A worker can hold at most what its spawning agent holds. Three layers decide the effective grant: - **Org configuration** — the agent's own tools, skills, and connectors, as configured by your admins. Nothing new to manage per worker. - **The per-job grant** — the agent picks the smallest set from its own capabilities for this task (fewer tools = a more focused worker). - **Platform exceptions** — a few tools never transfer, most importantly the ask-the-user tool: a worker's questions must flow through the agent, so answering never dead-ends. Workers also cannot spawn workers. One exception runs the other way: every worker can always list and read the thread's files (uploads, generated outputs) — writing files or running code stays an explicit grant. Anything requested outside those bounds is silently skipped and reported — the job card shows what was narrowed away, and the agent adapts (for example, telling you an connector needs connecting). ## Operating methods For open-ended work, the agent can grant a **methodology skill** as the worker's operating method — `web-research` ships built-in: live planning on the checklist, per-question search budgets, and a cited deliverable. Methodologies are skills, so admins govern them the same way as every other skill. ## Limits and spend A worker runs inside the turn that spawned it and cannot outlive it; when the ceiling is reached the job ends with its partial progress still visible on the card. That ceiling belongs to whatever host is running the turn rather than to the agent, which carries no deadline of its own. Token spend rolls up to the spawning agent, and spend limits are enforced for the organization as a whole rather than per agent, so a job's cost lands with the rest of the organization's usage. Admins cap how many jobs may run at once under **Governance → agent_jobs** (default 10). ## When to reach for it | Use … when | Worker | Single agent | Workflow | | ------------------------------------------------------- | ------ | ------------ | -------- | | One sub-task benefits from an isolated, focused context | ✓ | | | | The agent can answer well inline | | ✓ | | | Work has explicit stages with approvals between them | | | ✓ | The cost of a worker is one extra run; the benefit is a clean context with exactly the right capabilities for the sub-task, and a job card that shows the user what happened. When the stages are fixed and you want approvals or scheduling between them, a workflow is the right shape instead. # Harnesses Source: https://tale.dev/docs/platform/agents/harnesses A **Harness** is a shipped coding CLI — Claude Code, Codex, Cursor, and peers — that runs your chosen model inside an isolated container instead of the ordinary chat loop. The harness plans, writes files, runs commands, installs packages, and reports back. You never pick a harness from the chat composer: chat selects a **model** only. The harness is chosen when you create a **project agent** — its dialog calls the field **Agent type** — or an automation **agent** node, where it is labeled **Harness**. This page covers which harnesses ship with Tale, where you bind one, where the credential comes from, and what the container can and cannot reach. The credentials themselves are an organization-level surface — see [Providers](/platform/admin/providers). **Settings > Providers** also has a **Harnesses** tab that shows how each harness would resolve for the organization. ## Where you pick a harness Open a project's **Agents** tab and create or edit an agent. The dialog asks for an **Agent type** — the harness, the coding CLI that agent will run on — alongside its model, equipment, and instructions. Assign a board task to that agent and it works in a sandbox on that harness. In an automation, an **agent** node carries the same **Harness** field. When the workflow reaches that node, the turn runs on the chosen harness. Chat never lists harnesses. The composer's picker is models only; harness work arrives through a project agent or an automation agent node, not through a composer group. ## What a harness turn is Describe a task in plain language — "write a small Python CLI and test it", "clone this repository and fix the bug in issue 42". The message goes to the harness rather than to the model directly. The harness drives the model in a loop inside the container, deciding for itself when to read a file, run a command, or try again, and the reply lands when its turn finishes. Two things follow from that. The work is real rather than described: files exist, commands actually ran, and their output is what the model reasoned over. And the shape of the turn belongs to the harness, not to Tale — a harness with a plan mode ends its turn with a proposal you can review, and one built for single shots simply runs to completion. ## The harnesses that ship Nine harnesses ship with the platform. They differ in how they take a prompt, whether they can be steered mid-turn, and whether they can reach MCP servers. | Harness | Credentials it accepts | Worth knowing | | ----------- | ---------------------- | -------------------------------------------------------------------------------------------------------------- | | Claude Code | Managed or your own | The most capable: steerable mid-turn, and a plan mode that ends in a reviewable proposal. Reaches MCP servers. | | Codex | Managed or your own | One-shot turns. Reaches MCP servers. | | Cursor | Your own only | One-shot turns. Its CLI cannot route through the platform gateway, so a managed credential is refused. | | Gemini CLI | Managed or your own | One-shot turns. Reaches MCP servers. | | Hermes | Managed or your own | One-shot turns, with no MCP channel. | | OpenClaw | Managed or your own | One-shot turns. Reaches MCP servers. | | OpenCode | Managed only | One-shot turns. Reaches MCP servers. Runs through the gateway, so your own key is refused. | | Pi | Managed or your own | One-shot turns, with no MCP channel. | | Qwen Code | Managed or your own | One-shot turns. Reaches MCP servers. | Steering is what the difference buys you in practice. With Claude Code, a correction you send while the turn is running reaches the agent at its next tool boundary — "use pnpm, not npm" lands while the work is still going. Every other harness picks a queued message up at the turn boundary instead. ## Where the credential comes from The credential is the organization's, not the agent's. An agent holds no keys of its own, and there is no per-agent credential tab; what a turn authenticates with follows from the provider credential behind the model you picked, configured under [Providers](/platform/admin/providers). Which of two postures a turn runs in follows from the kind of credential that is. **A stored API key, or one read from a deployment environment variable**, stays with the platform. Tale mints a session-scoped gateway key for the turn, and the harness authenticates with that rather than with the real secret, so the container never holds a credential that outlives the session. This is the managed posture, and the only harness that refuses it is Cursor. **A vendor subscription** — a coding-plan key, a portal key, an OAuth blob, or a pool of rotating tokens fetched from a broker — works differently, because vendors sanction those credentials for their own agent tooling and nothing else. A subscription credential therefore forces the turn onto one specific harness: asking for a plain chat turn is refused with a reason naming that harness, and asking for a different harness is refused too. The secret is injected into the session environment, which is bring-your-own posture, so the forced harness has to accept it — OpenCode, being gateway-only, refuses. A harness turn always names a concrete harness. Nothing guesses one for you: the only case where a harness arrives on its own is the subscription credential that carries its forced choice with it. ## What the sandbox can reach The container starts from an empty working directory and is locked down by default. Files and folders you pin with `@` ride along into the session under `/user/uploads/`, so the agent opens the real bytes rather than a retrieval snippet, and what it writes under `/user/output/` comes back into the chat as a file. Outbound network is denied apart from a narrow allowlist — package registries and GitHub — so the agent can install what it needs and clone a public repository without being able to reach arbitrary hosts. Connected connectors reach the agent through a broker rather than through the box. When the agent calls one, the request goes back to Tale, which runs it with the stored credential and hands back only the result, so a compromised container cannot read your keys. A write surfaces as an approval card in the chat and proceeds once you approve it. GitHub is the deliberate exception: `git` and the `gh` CLI need a token locally, so a turn runs with a scoped one while the conversation has the GitHub connector equipped — injected per turn, gone when the turn ends. Skills bound to the agent are staged into the session as files rather than fetched through a tool, and a skill the checked-out repository ships wins over the copy Tale would stage — [Agent skills](/platform/agents/skills) covers that precedence rule. Your own [environment variables and secrets](/platform/member/environment) are set in the container too, which is how a personal token or endpoint reaches the work without anyone else's session seeing it. ## Cost and metering A harness turn can be long and call the model many times, so it costs more than a single chat reply. Managed turns run through the gateway, which is what makes them meterable: they land in [Usage analytics](/platform/admin/governance/usage-analytics) alongside every other turn, and the organization's [Policies and limits](/platform/admin/governance/policies-and-limits) cap what they may spend. Turns on a subscription credential bypass the gateway by design, since the secret goes into the container and the vendor's own tooling talks to the vendor directly. Those turns are not metered and the organization's spend caps do not reach them — the accounting lives with whoever owns the subscription. ## Where this fits A harness turns a project agent or an automation agent node into a live session with a coding tool in an isolated container: you drive it in plain language, it works on real files, and the harness decides the rhythm of the turn. Chat stays model-only; the **Harness** field lives on the agent or the automation node. The axis that decides how much of it stays under the organization's control is the credential — a stored key keeps the turn on the gateway, under the caps and in the metering, while a vendor subscription pushes it into the box and onto that vendor's own account. Pair this page with [Providers](/platform/admin/providers) for the credential side and [Connectors](/platform/connectors/overview) for what the agent can reach once it is running. # Image generation Source: https://tale.dev/docs/platform/agents/image-generation Image generation in Tale is a tool, not a kind of agent. Any agent granted `generate_image` can produce a picture inline: ask it to create, draw, or design something, the model calls the tool, and the image renders in the reply the way an attachment does. There is no mode to switch into first and no specialised persona to pick. This page covers that tool — what it does, how you grant or withhold it, how the result lands in the conversation, and what it costs. The mechanics underneath belong to the provider: quality, price, and speed vary widely between image models. ## The generate_image tool `generate_image` takes one thing — a prompt describing the picture to make. That prompt is self-contained, because the image model never sees the conversation: the agent folds everything you said about style, mood, composition, and colour into the single description it sends. The result comes back as a file, renders inline, and the agent's text wraps around it. Being an ordinary tool means everything true of the rest of the tool surface is true here. The model decides when to call it from the list its agent was granted, the call and its result appear in the conversation like any other tool call, and an agent that was never granted it cannot reach it at all. ## Grant it or withhold it Open the agent's **Tools** tab and grant `generate_image` where the job involves pictures; leave it off for an agent that should only ever answer in text. There is nothing else to configure — no per-agent image setting, no image-only persona, and no type to switch an agent into. The model behind the picture comes from the same place as every other model: whoever sends the message picks it in the composer, rather than the agent pinning one. An organization whose providers offer nothing image-capable gets a clear refusal instead of a guess, which is the cue for an admin to add one under [Providers](/platform/admin/providers). ## How the image lands in the reply The generated image renders inline next to the agent's text and opens full size when you click it. The file is stored alongside the conversation's attachments and inherits the same retention rules, so a generated picture is exactly as durable — and as deletable — as anything you uploaded to that chat yourself. Because the image arrives through a tool call, it is auditable like one: the prompt the model actually sent is visible in the call, which is usually the fastest way to work out why a picture came back different from what you pictured. ## Cost and budget Image models cost more per call than text models, sometimes by an order of magnitude. The organization's [Policies and limits](/platform/admin/governance/policies-and-limits) cap spend per user, per team, and per agent, and hitting a cap surfaces in the chat instead of rendering a picture. Spend shows up in [Usage analytics](/platform/admin/governance/usage-analytics) in the same tables as text usage. ## Where this fits Image generation is one entry on one list, and that is the whole point: an agent that should draw gets `generate_image`, an agent that should not does not, and no part of the persona has to be reshaped around pictures. The drift candidates here are provider and model names — pair this page with the running list in [Providers](/platform/admin/providers) rather than memorising model strings, and with [Agent tools](/platform/agents/tools) for the rest of the catalog. # Agent knowledge Source: https://tale.dev/docs/platform/agents/knowledge Knowledge is what an agent can retrieve and cite at reply time. Without it the agent is generic; with it the agent answers from your organization's material and shows where the answer came from. The agent's **Knowledge** tab holds a single decision: which corpus this agent's retrieval is allowed to read. That decision is smaller than it used to need to be, because retrieval itself is no longer a mode you configure. An agent searches when it judges that it needs to, and nothing is injected into a reply the agent did not go looking for. ## Pick a scope Four values, one setting: - **Documents** — the organization's own uploads, and nothing else. - **Web** — the pages fetched on the organization's behalf, and nothing else. - **All** — both corpora, fused into one ranked result. This is what an agent gets when nobody narrows it. - **None** — the agent is offered no retrieval at all. Reach for it when the agent's job is reasoning or drafting and citations would only be noise. Every corpus belongs to your organization, so widening the scope never crosses into another tenant's material. It only decides how much of your own the agent is pointed at. ## Narrow it on purpose Everything in scope competes for relevance on every question, which is why a narrower scope usually answers better than a wider one. An agent pointed at the documents your team actually maintains finds the right passage; the same agent pointed at every crawled page as well has to beat the noise first. Set **Documents** when the truth lives in files you control and a stale web page would be a liability. Set **Web** when the agent's job is about what is published rather than what is filed. Set **All** when both genuinely matter and you would rather have the recall. The material itself — what is uploaded, what is crawled, and what is indexed — is managed under [Documents](/platform/knowledge/documents) and [Websites](/platform/knowledge/crawling), not here; this tab only points the agent at it. ## How retrieval lands in the reply When the agent retrieves, citations attach to the sentences they support — hovering shows the source, clicking opens it. A document that has not finished indexing is not retrievable yet, so an agent that seems to be ignoring an obvious source is often waiting on the index rather than misconfigured. ## When to reach for it Structured records and live systems are tools, not knowledge. The boundaries: | Use… | When the agent needs… | | --------------------------------------------------- | ------------------------------------------------------ | | Knowledge (this tab) | To search and cite the organization's material | | [Tools](/platform/agents/tools) | Contacts, products, vendors, websites, or live systems | | [Project agents](/platform/projects/project-agents) | Knowledge scoped to one Project | ## Where this fits Agent knowledge answers one question — should this agent read the organization's documents, its crawled web, both, or neither. The wider [Knowledge](/platform/knowledge/overview) section is where those sources live and get indexed; this tab wires one agent into a slice of them. For the end-to-end build — upload, scope, ask, verify the citations — walk [Agent with knowledge](/tutorials/editor/agent-with-knowledge). # Skills on agents Source: https://tale.dev/docs/platform/agents/skills An agent reaches a skill only when it is equipped, and equipping is a pick from the organization's [skill library](/platform/workspace/skills). This page is about the surfaces that pick — a project's agents and an automation's agent nodes. One rule decides what they may pick: **the project's own visibility counts, never the configuring member's.** ## What equipping decides An equipped skill is offered to the model by its description. When the model judges that description relevant to what you asked, it reads the `SKILL.md` body, then opens individual bundle files where the body points at them. Nothing is executed and nothing is pasted in up front, so a skill costs context only on the turns where the model actually reaches for it. A bundle whose frontmatter carries `disable-model-invocation: true` behaves differently. It stays equipped and stays readable, but the model must not reach for it unprompted; it waits for a turn where somebody names it. ## Equip a project's agents A [project agent](/platform/agents/create) carries its own equipment, picked in the capability menu on the agent's dialog. The list there follows the **project's** visibility, not yours: organization-wide skills, plus team skills shared with any of the project's teams. An org-wide project sees organization skills only, and nobody's legacy private skills ever appear — a project agent runs for every member of the project, so its equipment must never smuggle in something only its author could see. The same scope holds at run time. A task run stages the agent's skills as the project; an org-level automation stages as the organization. A skill that stops being visible to that scope fails the run by name rather than quietly running without it — deliberate equipment silently missing is worse than a failed run. ## Skills in a sandbox session When a turn runs in a sandbox, equipped bundles do not arrive through a tool call. They are staged into the session as files, in the layout the runtime already knows how to discover, so the harness finds them the way it would find a skill on any machine it works on. One rule governs collisions: the repository wins. If the checked-out repository ships a skill under the same slug as one Tale would stage, Tale withholds its copy and the repository's version stands. A repository can always override what the platform would otherwise teach the agent, and the session never holds two bundles claiming the same name. ## Skill or instructions | Use … when | Skill | Agent instructions | | ------------------------------------------------------- | ----- | ------------------ | | The pattern repeats across several agents | ✓ | | | The behaviour needs reference files alongside the prose | ✓ | | | The behaviour is this one agent's voice | | ✓ | | One edit should reach everyone who uses the behaviour | ✓ | | | The agent's instructions still fit on one screen | | ✓ | Instructions are the right shape for one agent's own character. A skill is the right shape as soon as the same behaviour turns up in a second and third agent and keeping their instructions in step starts to cost you. ## Where this fits Equipping is the narrow half of skills: the library decides what exists and who may see it; a project's agent dialog and an automation's agent nodes decide where it gets used — always through the project's or the organization's own visibility. Keep equipment lists short, prefer replacing a bundle over cloning it, and let a repository override what the platform stages when an agent works inside one. The other half of the story — writing a `SKILL.md`, uploading a folder, and sharing a bundle — is the [skill library](/platform/workspace/skills). # Agent tools Source: https://tale.dev/docs/platform/agents/tools Tools are what an agent can do beyond producing text. The model decides which tool to call from the list the agent's author has granted; Tale runs the tool, hands the result back, and the model continues. The agent's **Tools** tab is that list — a searchable catalog of per-tool switches, grouped into category cards. ![The agent editor's Tools tab scrolled to the category cards, with Knowledge at three of four tools checked and Files at seven of seven, while Conversations, Discussions, Analytics, and Tasks & projects have none granted.](/images/platform/agent-editor-tools.webp) ## Granting tools one by one Check a tool and the agent can call it from the next request; uncheck it and the agent forgets it exists. **Search tools…** filters the catalog by name or category, each tool row carries a one-line description of what it grants, and a category's header checkbox enables the whole group at once — the count beside it shows how many of the group's tools are on. The categories map to the platform's surfaces: **Contacts**, **Products**, **Vendors**, and **Websites** expose read and update tools over structured records; **Conversations** lets the agent read and reply; **Knowledge** covers document search and writing; **Tasks & projects** includes the agent's own to-do list; **Automations** lets it create and run the organization's automations; **Web** holds search over the sites your organization has added; **Files** covers the agent's file operations; **System** holds **Run code**, **Ask a human**, and the other runtime tools. Grant the smallest set that does the job — every enabled tool widens what the agent can read or change on your behalf. **Run code**, in the **System** group, is the widest of these: it runs Python, Node, or bash in the chat's own sandbox, over the files the chat already holds rather than a blank box. A call runs a snippet directly, runs a script the agent staged under `/user/code/`, or installs packages only — declared packages install first and persist for the rest of the turn, and whatever the run writes under `/user/output/` comes back as a file in the chat. Files and folders you pin with `@` arrive in that sandbox under `/user/uploads/`, so the code opens the real bytes, not a retrieval snippet. An agent spawns a focused **worker** for a sub-task on its own — it is not a tool you toggle here. See [Agent workers](/platform/agents/delegation) for when that is the right move and how a worker inherits a bounded subset of the agent's own capabilities. ## Web access is a tool, not a mode Web search sits in the catalog like everything else. Grant it and the agent can search when it judges that it should; leave it off and it cannot search at all. There is no separate mode to configure and no automatic injection of results into a reply — the agent reaches for search the way it reaches for any other tool. What it searches is the material your organization has added rather than an open crawl, so manage the sources under [Websites](/platform/knowledge/crawling). ## Connectors and automations are capabilities too A connected connector and a published automation reach the agent through this same list. There is no second binding surface underneath it: name the capability in the agent's allowlist and the agent can call it without having to quote the connector or the automation id itself. Connected [MCP servers](/platform/connectors/mcp-servers) arrive the same way, through the organization's connectors. An automation that only an event can start is listed but not callable. The agent sees that it exists and is told plainly that it runs when its event fires rather than on request — an agent that cannot see the organization's automations invents workarounds instead of pointing at the one that already does the job. ## How tool calls render Tool calls appear in the chat as collapsed cards between the user's message and the reply. Expanding a card reveals the tool name, the inputs the model emitted, and the result Tale returned. A failed tool call shows the error; the model usually retries with a different shape on the next turn. ## When to reach for it | Use Tools when… | Use Knowledge when… | | ---------------------------------------------- | ------------------------------------------ | | The agent must act — query, update, run, reply | The agent must cite documents it retrieved | | The data is structured records or live systems | The data is uploaded or crawled content | ## Where this fits Tools widen what an agent can do; they also widen the trust boundary, since the agent can now read, write, or call things on the user's behalf. Pair this page with [Run-code policy](/platform/admin/governance/run-code-policy) if the agent will execute code. The agent's instructions stay the place where the **policy** lives; the **Tools** tab is the place where the **surface** lives. # Agent versions Source: https://tale.dev/docs/platform/agents/versions Every save of an agent creates a snapshot. The **History** button at the top right of the agent editor opens those snapshots in reverse chronological order; comparing shows what changed, and restoring replaces the current state with a past version. There is no manual-save versus auto-save distinction — every persisted change is a version. The mechanic is small but load-bearing. Most teams adjust an agent's instructions weekly; without the history, the team would never trust the edits. ## Reviewing a change Open the agent and click **History**. The list shows **Current version** at the top and every prior **Snapshot version** below, with the author and timestamp on each row. Pick a snapshot and **Compare changes** reviews the differences between it and the current version — the changed fields highlight — before you decide to restore. ## Restoring a version From a snapshot, click **Restore this version**. The agent's current state is replaced with the snapshot — a toast confirms **Agent restored from history** — and the restore lands on the timeline as its own entry, so restores are additive, not destructive. Chats already running against the previous version continue on it until they end; the restored version applies from the next chat. ## What gets versioned Versioning covers everything the agent itself carries: its display strings and description, its instructions, the tool and skill allowlists, the knowledge scope, its visibility, and its metadata. It does not reach the things an agent only points at. Replacing a document the agent retrieves from changes what it answers without bumping the agent's version, and so does replacing a skill bundle it binds — the binding names a slug, so the agent's own configuration is unchanged while its behaviour is not. To audit either, see [Audit logs](/platform/admin/governance/audit-logs). ## Where this fits Versions are the agent's safety net for the same reason git is the codebase's: anything saved is recoverable. The companion page is [Audit logs](/platform/admin/governance/audit-logs) — it covers the org-wide who-did-what trail; History covers the per-agent what-was-it trail. # Approval concepts Source: https://tale.dev/docs/platform/approvals/concepts An approval is the seam between an agent's initiative and your judgement: a card that appears in the chat where the action was attempted, holding that action until a person decides. Agents propose — a document write, an outbound API call, a workflow run — and nothing executes while the card is pending. The chat says so explicitly: **Respond to the pending request above to continue**. This page is the mental model — what fires an approval, what the card offers, and what a decision leaves behind. The workflow-specific gates live on [Approvals in workflows](/platform/automations/approvals-in-workflows); where the requirements are declared lives on [Configure approvals](/platform/approvals/configure). ## What fires an approval Every card comes from an agent trying to act on something that outlives the conversation: - **Plans** — an agent proposes a multi-step plan as a **Proposed plan** card; **Approve & execute** starts it. - **Document writes** — a **Save to documents** card holds files an agent wants to store; nothing lands in the document hub until approved. - **Knowledge writes** — a **Save to knowledge base** card holds a fact an agent wants to remember org-wide. - **Connector calls** — an operation flagged as requiring approval (outbound writes, typically) holds with the exact parameters shown. - **MCP tools** — a tool the server marks **Requires approval** asks before it runs. - **Workflow creation, updates, and runs** — the workflow-side gates, covered in [Approvals in workflows](/platform/automations/approvals-in-workflows). ## The decisions on a card Every card carries the action's exact payload — the file, the fact, the parameters — and two decisions: approve (the button names the action, such as **Run workflow** or **Approve & execute**) or reject. Connector cards add a third path, **Suggest changes**: describe what is wrong in free text and the agent revises the call instead of abandoning it. Approvals are decided in the conversation they interrupt — by whoever holds that chat. There is no separate approval inbox or routing to an approver pool; the person the agent works for is the person who decides. ## States and the trail A card moves through **Pending** to **Executing** to **Completed** — or **Rejected** — and keeps its resolved state in the transcript, so a chat rereads as a record of what was allowed. Each decision also lands in the [audit log](/platform/admin/governance/audit-logs) with the actor, the action, and the timestamp. Resolved cards cannot be re-opened; a retry means a fresh proposal and a fresh card. ## Where this fits Approvals are what let you hand agents real capabilities — files, APIs, workflows — without handing over the record of who allowed what. Read [Configure approvals](/platform/approvals/configure) next to see where a requirement is switched on, and [Approvals in workflows](/platform/automations/approvals-in-workflows) for the gates around workflows. # Configure approvals Source: https://tale.dev/docs/platform/approvals/configure Approval requirements in Tale are declarative: each capability carries its own flag saying whether an agent must ask first, and the flag travels with the connector or server that provides the capability. Nothing has to be configured for the defaults to be right — this page shows where each flag lives, which writes ask by default, and how to change that for your organization. The model of what an approval card is and who decides it lives on [Approval concepts](/platform/approvals/concepts). What follows is the configuration surface, capability by capability. ## Connector operations Every connector declares its operations, and each operation carries its own approval flag. Open **Settings > Connectors**, click an connector, and its operations list badges the ones marked **Requires approval** — for the shipped connectors, that is the write side: sending mail, posting messages, creating issues. Reads run without a card; flagged writes hold in chat with their exact parameters until someone approves. The flag is not a separate setting an admin toggles. Every action a connector declares carries an effect — `read` or `write` — and the write side is what the approval policy gates. That keeps the two honest with each other: an action cannot quietly change from a read to a write without also changing what it has to ask for. ## Which writes ask A card is worth someone's attention when the write **leaves your tenant**. That is the default line: - **Writes to outside systems ask** — sending mail, posting to Slack, opening a GitHub issue, writing to a WebDAV share. These connectors hold your vendor credentials and act on systems Tale does not own. - **Writes on Tale's own surface do not** — moving a task, commenting on it, saving a document into the project, running a script in your own sandbox. These are already bound by the permissions of whoever (or whatever) performed them, an automation that performs them passed its deploy gate, and every one of them is recorded in the run's own trace and the audit log. Without that line a single automation run could stack up half a dozen cards for its own bookkeeping — "move this card to In progress" — and bury the one card that actually needed a person. ## Changing the line for your organization Both directions are configurable per organization, in `governance/approval-policy.yml` under your configuration directory. Each rule names **one** target — a whole connector, or a single action as `.` — and the more specific rule wins: ```yaml rules: # This team reviews every task the desk touches. - connector: task decision: require_approval # Their nightly report mail is trusted; other mail actions still ask. - action: imap-smtp.send decision: auto_approve ``` An operation that is already waiting on a card keeps its card even if the policy is loosened afterwards — a decision belongs to the operation it was asked about, so a parked run is never stranded by a policy edit. ## MCP tools An MCP server's manifest marks which of its tools need sign-off. Open **Settings > API > MCP**, expand a server, and its **Discovered Tools** list badges each flagged tool with **Requires approval** — those ask in chat every time an agent calls them. The flag comes from the server's author; connecting a server is how you accept its tool contract, so review the list before activating one. [MCP servers](/platform/connectors/mcp-servers) covers registration. ## Built-in write gates Some gates ship on and are not configurable, because the action is consequential by nature: - **Document writes** — an agent saving files to the document hub always asks (**Save to documents**). - **Knowledge writes** — an agent storing an org-wide fact always asks (**Save to knowledge base**). - **Workflow creation, updates, and runs** — an agent building, editing, or starting a workflow always asks; see [Approvals in workflows](/platform/automations/approvals-in-workflows). The lever for these is not the approval flag but the capability itself: an agent without the document tools or workflow tools never produces the card. Trim the agent's [tool set](/platform/agents/tools) to remove the capability entirely. ## Verifying what will ask Before putting an agent in front of real systems, read its capabilities the way an approver would: the connector's operations list for flagged writes, the MCP server's **Discovered Tools** for flagged tools, and the agent's tool tab for whether it holds write tools at all. The [audit log](/platform/admin/governance/audit-logs) then records every decision the setup produces. ## Where this fits Configuration here is distribution — flags live with the connectors and servers that own the capabilities. Read [Approval concepts](/platform/approvals/concepts) for the card lifecycle those flags produce, and [Agent tools](/platform/agents/tools) for the capability side of the same boundary. # Approvals in workflows Source: https://tale.dev/docs/platform/automations/approvals-in-workflows Workflows run without you, but they change and start only with you. Three human gates surround every workflow: the AI editor's changes to a definition apply only after you approve them, an agent that wants to run a workflow needs your sign-off first, and a run that hits a question pauses until someone answers. This page covers the three gates; the org-wide story of what an approval card is lives on [Approval concepts](/platform/approvals/concepts). ![The workflow canvas of an automation showing a graph of nodes, with a panel open beside it.](/images/platform/automation-editor-canvas.webp) ## Approving changes to a definition Ask the assistant to build or rework an automation and its proposal lands as a card rather than as a change. The card names what it would do — create a new automation, patch a single node, or replace the whole document — and holds until you decide. Approve it and the result is saved as a new version exactly like a manual save, so the document you were looking at is untouched and the version that is live stays live until you deploy. Cancel discards the proposal, and nothing reaches the document while the card is pending. ## Approving a run An agent in chat that holds the automation tools can ask to start one. The request arrives as a card naming the automation, and you can expand it to inspect the exact input it would run with before deciding. After approval the same card follows the live run — which node it is on, how long it has been going, and how it ended — and lets you stop it mid-flight or open the run itself for the full per-node detail. The chat holds while a request is pending, and it tells you so. Decide the card before sending the next message. ## Answering a paused run A run that needs a human answer takes the **Waiting** status in the [run list](/platform/automations/execution-logs) and parks there. The question arrives as a form card — fill it in and submit it, or push back in free text when the form is not asking the right thing. Answering does not restart anything: the run re-enters at the node it stopped on, carries your answer forward as that node's input, and finishes the rest of the graph. Every node it had already completed stays completed, so nothing it did before the pause happens twice. ## What each decision leaves behind Every gate moves through the same handful of states on the card itself — pending, then being carried out, then finished or rejected — and the decision lands in the [audit log](/platform/admin/governance/audit-logs) with the actor and the timestamp. A resolved card cannot be reopened; to retry a rejected run, ask again and decide the fresh card. An approval that started a run leaves the run behind as its own record, so what the decision actually caused stays readable in the [run list](/platform/automations/execution-logs) long after the card is gone. ## Where this fits These gates are the workflow-side face of one product-wide pattern: an agent proposes, a human disposes. [Approval concepts](/platform/approvals/concepts) names every card type beyond workflows — document writes, knowledge writes, connector calls — and [Configure approvals](/platform/approvals/configure) shows where the requirements are declared. # Automation assistant Source: https://tale.dev/docs/platform/automations/assistant The **Automation assistant** is the chat agent scoped to one automation, answering with that automation's document, its agents, its skills and its connectors already in context. Admins and Developers use it to understand an automation they did not build, extend one instead of duplicating it, or get help authoring the pieces the automation's own page does not edit. Ask it what something does before you touch it by hand, because it reads the whole document at once rather than one node at a time. ## What it edits directly The automation's own document is the one piece the assistant has full tool access to: it reads the current version, edits nodes, validates the result, saves a new version, and runs it against mocks — the same acts you would perform by hand, in the same order. It works within the same rules you do, so a save appends a version rather than editing one, and the version that is live stays live until somebody deploys. Agents are one step behind: it reads the roster and can install, enable, or disable one, but instructions, model, and the rest of an agent's configuration stay yours to edit in the agent editor, with the assistant drafting the exact JSON for you to paste in. ## What it drafts instead Skills, connectors, and builtin views have no editing tool at all: the assistant writes the definition per the matching authoring skill and tells you exactly where to apply it — Settings > Connectors for a credential, the automation's own page for a view. Install and setup work the same way: it walks the readiness checklist, naming what still needs connecting and what still needs enabling, rather than doing the connecting itself. The same boundary applies to triggers. The assistant can tell you which schedule, webhook, or event trigger an automation carries and what each one would send into a run, and it can spell out the trigger you want — but the decision to expose an automation to the outside world stays a human one. [Automation triggers](/platform/automations/triggers) covers what each kind does. ## Finding what already exists Before building anything, the assistant searches for an automation or bundle to extend rather than duplicate — the same reuse-first rule every write-\* skill enforces. Its search reaches automations the catalog itself hides: a bundle's hidden members (see [Automation concepts](/platform/automations/concepts)) are still visible to the assistant, so it can point you at, say, the PR Creator agent buried inside Resolve GitHub issues instead of proposing a new one. ## Where this fits The Automation assistant is the fastest way into an automation you didn't build — ask it what something does before you touch it by hand. [Automation concepts](/platform/automations/concepts) is the vocabulary it assumes; [Browse and install](/platform/automations/catalog) is where you'd act on what it tells you if the automation isn't installed yet. # Built-in automations Source: https://tale.dev/docs/platform/automations/builtin Tale ships automations out of the box: three that turn a mailbox into a shared inbox, one bundle that resolves GitHub issues end to end, a set of sync and upkeep templates you install when you need them, and the pre-installed packs that run task boards and mentions for every organization. Editors and Members use whatever an installed automation adds — an Inbox tab, a Backlog entry — without installing anything themselves; installing is an Owner/Admin/Developer action covered on [Browse and install](/platform/automations/catalog). This page names what each one does and the connector it needs connected first. ![The Automations catalog on the All automations tab, showing cards for the email automations and the Resolve GitHub issues bundle, each with its icon and description.](/images/platform/automations-catalog.webp) ## Sync Gmail, Outlook, and email over IMAP **Sync Gmail emails**, **Sync Outlook emails**, and **Sync emails via SMTP/IMAP** are the same automation three times over, one per mailbox kind: each requires exactly the connector its name says, each installs the same channel-agnostic **Inbox** builtin view, and each carries the mail-sync workflow that pulls the mailbox into conversations on a schedule, every five minutes out of the box (change the [schedule trigger](/platform/automations/triggers) to pull less often). An organization that receives mail on more than one kind of mailbox installs more than one of these; each Inbox only shows its own mailbox's traffic. When a connector has several credentials — two IMAP mailboxes, two Gmail accounts — one sync pass covers every active credential, and each mailbox keeps its own position in its own mail, so adding a second mailbox later does not skip everything older than what the first one already pulled. A mailbox that cannot be reached is skipped for that pass and retried on the next one, without holding up the others. The matching **Triage … inbox** automations do the same fan-out before writing one digest across every connected mailbox. | Automation | Requires | Mailbox | | ------------------------- | --------- | -------------------------------------- | | Sync Gmail emails | Gmail | A Gmail mailbox | | Sync Outlook emails | Outlook | A Microsoft Outlook mailbox | | Sync emails via SMTP/IMAP | IMAP/SMTP | Any private mailbox over IMAP and SMTP | ## The Inbox tab Every one of the three opens on its **Inbox** tab: four sub-tabs — **Open**, **Closed**, **Spam**, **Archived** — each a split view with the conversation list on the left and the selected thread on the right. Opening a conversation fills the right pane with its full message history; until you pick one, the pane reads **Select a conversation to view details**. The message field sits under the thread on **Open** — replies belong to active conversations, so the other three tabs are read-only. Write in **Type a message** and click **Send**; the reply goes out through the mailbox the conversation arrived on, with the recipient and subject line derived from the thread — there's nothing to address by hand. The thread header shows the real **From** for that conversation — the address the contact wrote to, or the sender you pick when composing — so what you see matches what a reply actually sends as. On a Gmail or Outlook connection the compose **From** is the connected account's address; on IMAP/SMTP you edit only the local part of **From**, and the verified domain stays fixed as a badge so you never leave it. **Improve** rewrites your draft with AI before you send it. On the IMAP automation, replies sent from the mailbox itself — from any mail client — sync into the conversation too, ordered with the rest of the thread. The thread header carries the status verbs for whichever conversation is selected — **Close conversation** and **Mark as spam** on an open thread, **Reopen conversation** on a closed or archived one, **Not spam** and the destructive **Delete** on spam. Selecting several rows in the list surfaces the same verbs as bulk actions. Admins and Owners also use the header **Assignee** control to queue work. Open it and pick from **People** and **Team** — the two are independent, so a conversation can sit in a team's queue and still be assigned to one person. Changing the person notifies them in-app and by email; queuing to a team notifies that team's members (the actor is skipped either way). Self-assignment, clearing the person (**Unassign**), and removing the team (**Remove team**) notify no one. Non-admins see the current assignment as read-only. Visibility follows assignment: Members see only their own and their teams' queues; true unassigned mail is admin triage. Pair assignment with [Conversation routing](/platform/admin/governance/policies-and-limits#conversation-routing) when inbound addresses should land in a queue automatically. ## Resolve GitHub issues **Resolve GitHub issues** is a bundle, not a single automation: installing it runs one aggregated wizard that installs four hidden automations at once, bound to the project you choose, and requires the GitHub connector. Each member does one stage of the loop. **Triage GitHub issues** scores a repository's open issues on a schedule and proposes the actionable ones onto the project's [Backlog](/platform/projects/backlog) — titled `# `, labelled to match GitHub, and left for a human to review. **Sync GitHub issues** closes a task the moment its GitHub issue closes, whether the resolve chain merged the fix or a human closed the issue directly on GitHub — it only closes, never creates or reopens a task. **Create GitHub pull requests** ships the PR Creator agent: once a human Starts a proposed task, it clones the repository, opens or adopts the pull request for the issue, implements the fix, verifies it against the project's own tests, and waits for CI to go green. **Review GitHub pull requests** ships the PR Reviewer agent: it re-tests the PR Creator's branch, confirms CI, and a toolless judge decides mergeability — approved parks the task at **In review** for a human to merge on GitHub; not approved sends it back to the PR Creator with feedback, up to a small rework cap. A human stays in the loop at two points: starting a proposed task off the Backlog, and merging the pull request on GitHub itself — nothing in the bundle merges on your behalf. ## Sync and upkeep templates Eight more automations sit in the catalog for the moments you need them. Each is a single workflow you install and then point at your data — the sync ones ask for their source on the schedule they create, and every one is editable afterwards on the automation's own page, where an edit becomes a new version you deploy when you are ready. | Automation | Requires | What it does | | ---------------------------------- | ------------ | ----------------------------------------------------------------------------- | | Sync Confluence pages | Confluence | Imports a Confluence space's pages into the knowledge library on a schedule | | Sync Google Drive files | Google Drive | Imports a Drive folder's documents into the knowledge library | | Sync Shopify customers | Shopify | Imports the shop's customers into the organization's contact records | | Sync Shopify products | Shopify | Imports the shop's product catalog into the organization's product records | | Analyze product relationships | — | Scans the product catalog and records accessories, variants, and complements | | Index documents for retrieval | — | Indexes newly uploaded documents so agents can search and cite them | | Archive idle conversations | — | Closes out conversations that sat quiet past their idle window | | Notify members on inbound messages | — | Alerts members the moment a new inbound message lands in an open conversation | ## The pre-installed packs The plumbing that runs every organization's boards ships as automations too — installed automatically at creation, hidden from the catalog, and visible on the **Installed** tab like anything else. The **task pack** runs an assigned agent the moment a task lands on it, triages unassigned work, reacts to @-mentions, routes finished work through review, sweeps stale runs, enforces SLAs, and keeps dependent tasks, subtasks, and archives moving; its sibling keeps OneDrive files synced. Each is a normal automation — open one to read its document on the canvas, follow what it did in its [run list](/platform/automations/execution-logs), or switch off a [trigger](/platform/automations/triggers) to stop it firing; an uninstall sticks and is never re-installed behind your back. ## Where this fits The inbox automations, the Resolve GitHub issues bundle, and the sync templates are what ships today; a private automation your organization builds or uploads shows up in the same catalog next to them. [Browse and install](/platform/automations/catalog) covers the catalog mechanics; [Project Backlog](/platform/projects/backlog) is the next read for what happens to a task after Triage proposes it. # Add automations to your organization Source: https://tale.dev/docs/platform/automations/catalog The **Automations** page in the sidebar lists every automation the organization owns and is the door new ones come through. An organization starts with the shipped packs already in place, you can author a new automation from scratch on its canvas, and **Upload package** takes a pack you built elsewhere — as plain files, or as one zip that also installs the skill bundles the pack ships with. Managing the page takes Owner, Admin, or Developer permissions; everything an upload creates stays a draft until you deploy it, so nothing running changes because a file landed. This page covers where automations come from and what an uploaded package may contain. Operating one — the canvas, versions, test runs, deploying — is [The workflow editor](/platform/automations/editor); the model underneath is [Automation concepts](/platform/automations/concepts); what the shipped packs do is [Built-in automations](/platform/automations/builtin). <Frame caption="The Automations page — every row is one automation with its version count and the version that is live, or Not deployed."> ![The Automations page listing the shipped email and GitHub automations, each row showing its version count and deployment state.](/images/platform/automations-catalog.webp) </Frame> ## What the list shows Each row is one automation: its name, how many versions it has, and either the live version or **Not deployed**. The org page lists organization-level automations; an automation that belongs to a project lives on that project's **Automations** tab instead — where an automation appears is decided once, by its first save, and never moves. Click a row to land on the automation's page and work with it as [The workflow editor](/platform/automations/editor) describes. **New automation** offers two ways to start from scratch: **From a goal** hands your description to the builder, which authors the nodes for you; **Blank (trigger + agent)** scaffolds a one-agent automation you wire yourself — name it, pick the agent's model, and the rest (the prompt, the granted tools and secrets, the trigger) is yours to set on the canvas. The shipped packs need no install step at all: every organization is seeded with them at creation, ready to deploy. ## Upload a package A pack is a directory: `workflow.yml` (the automation document — required), `automation.yml` (the manifest — optional), and, when the pack ships its own knowledge, one folder per skill under `skills/`. ```text review-invoices/ ├── workflow.yml ├── automation.yml └── skills/ └── invoice-rules/ ├── SKILL.md └── references/ └── checklist-rules.md ``` To upload one, open **Automations**, pick **Upload package** from the **New automation** menu, and choose either form of the same pack: - **The files** — `workflow.yml`, plus `automation.yml` when the pack ships one. Right for a pack that is only its document. - **One `.zip` of the pack directory** — required when the pack carries skills, since only the zip can hold their folders. Markdown notes outside `skills/` — a README, a design record — are ignored, as are dotfiles and build leftovers (`__pycache__/`, `node_modules/`), so zip the directory as it is, straight after a test run; the zip stays under 20 MiB. Pick where the automation installs — the organization, or one project — before you submit. A pack whose manifest declares `scope: project` only installs into a project; an organization-wide upload of one is refused. The choice is not final: installing into a project binds the automation to it, and the **Projects** panel on the automation's page manages the whole set afterwards — bind more projects, or none to serve the whole organization. <Frame caption="Upload package — the files or one zip, and where the automation installs."> ![The upload package dialog with its file drop zone and the Install into picker set to Organization.](/images/platform/automations-upload-dialog.webp) </Frame> The server validates before anything is stored. The document runs through the same engine validation the editor uses — an upload that would not run is refused with the engine's own issues, not saved broken — and the manifest's `subjects` and `settings` blocks become the automation's task contract and [settings forms](#settings-the-pack-declares), exactly as a save from the canvas would set them. What lands is a **draft version** behind the normal deploy gate — nothing triggers run until a version is deployed. The dialog offers the deploy the moment the upload succeeds: make the new version live right there, or pick **Later** and deploy from the automation's page when you're ready. Uploading an existing automation's pack again appends the next version — the store never overwrites history, so every earlier version stays exactly where it was. Choosing a project as the target also binds the existing automation to that project, on top of whatever projects it already serves. ## Skills the package carries A zip may ship the skills its document leans on — the bundles an agent node loads or a script step runs from. The manifest must name them, and the declaration is checked in both directions: a `skills/` folder the manifest doesn't declare refuses the upload, and so does a declared slug the zip doesn't carry. ```yaml # automation.yml name: Review invoices skills: - invoice-rules subjects: task: # …the task contract, unchanged ``` Each carried bundle is validated as a real skill — frontmatter parsed, `name` equal to its folder — and installed into the organization's [skill library](/platform/workspace/skills) the moment the upload is accepted, so the draft's test runs already find them. What happens per slug depends on what the library already holds: - **New slug** — the bundle is installed. - **Identical bundle** — nothing is written; the upload reports it unchanged. - **Different content** — the upload stops and lists the colliding slugs. Confirm to replace them with the package's versions; the superseded `SKILL.md` stays in each skill's history. Nothing — not the automation, not any skill — is written until you confirm. A document that references a skill the package doesn't carry and the library doesn't hold still uploads — the missing reference comes back as a warning, so a pack can name a skill you install later. ## Settings the pack declares An automation whose runs read operator-owned configuration — a case profile, a validation policy — can declare it as **settings forms** in the manifest. The platform renders them in the task board's create dialog and saves each form as a flat YAML file in a project folder, so nobody hand-edits a file to configure the automation, and every project keeps its own values. ```yaml # automation.yml settings: folder: Setup forms: - file: validation-policy.yaml title: Validation policy required: true fields: - key: method label: Validation profile type: select default: strict_rules options: - value: strict_rules label: Strict checklist (standard) ``` A form owns its file: saving rewrites `Setup/validation-policy.yaml` from the form's values, and the form pre-fills from whatever the file holds — whether the form wrote it or someone uploaded it by hand. Fields are `text`, `number`, `boolean`, or `select`; every value lands as a string, a `text` field may pin a `pattern`, and titles, labels, help lines, and option labels localize through per-entry `i18n` blocks. Anything richer than a flat key–value file — nested blocks, lists — belongs in a separate hand-authored file the workflow reads alongside. Mark a form `required: true` and the create dialog enforces it per project: the first time someone picks the automation's task template in a project that hasn't been set up, the forms appear before the task's own field, and creating continues only once they're saved. From then on a **Settings** button in the same dialog reopens the forms for editing — each with its own **Save**, active only when something changed. ## Deliverables the pack declares A pack whose runs file documents back into a task's folder can name which of them are the **deliverables** — what a reviewer opens the task for. The task's Outcome zone lists exactly these, always open and in the declared order, while everything else in the folder — the uploads, the run's working files — folds away under **Files**. ```yaml # automation.yml subjects: task: outcome: files: - return.xml - report.md - journal.csv ``` Only the pack knows which of its written files are the point, so nothing is guessed platform-side: a name that no run has filed yet still shows as a promised row marked _Not ready yet_, so the task names what it will produce before it produces it. `*` and `?` wildcards are honoured (`return-*.xml`) for a name a run derives. Declare nothing and the Outcome zone falls back to every file the runs filed, newest first. ## Where this fits Automations arrive three ways — seeded with the organization, authored on the canvas, or uploaded as a pack — and every route ends in the same place: a draft version on the automation's page, deployed on your say-so. A zip-packed upload also stocks the [skill library](/platform/workspace/skills) with the bundles the automation needs, with a confirmation in front of any skill it would replace. [The workflow editor](/platform/automations/editor) is the next read for taking that draft live. # Automation concepts Source: https://tale.dev/docs/platform/automations/concepts An automation is one saved workflow document under a name, plus everything the platform keeps around it: the history of that document's versions, the single version that is live, the triggers allowed to start it, and the record of every run. Open **Automations** in the sidebar and each row is one of those names, with the version that is live beside it. Three ideas on this page decide how the rest of the surface behaves — versions never change, deploying is a separate act, and a trigger binds to the name rather than to a version — so read them before you build anything. Prefer to watch first? Episode 5 opens the triage automation end to end and decides a real approval card on camera, captions included. <Video src="/videos/en/tutorials/ep5-automations/ep5-automations.en.mp4" poster="/videos/en/tutorials/ep5-automations/ep5-automations.en.webp" captions="/videos/en/tutorials/ep5-automations/ep5-automations.en.vtt" lang="en" title="Episode 5 — Automations & approvals" caption="Episode 5 — Automations & approvals (2:42)"> </Video> ## The workflow document Everything an automation does is declared in one document. Its `name` is also its identity — lowercase slug segments, dash-separated, with `/` grouping related automations into folders, as in `billing/dunning-reminder`. Around the name sit a `description`, an `inputs` JSON Schema describing the runtime input, the `nodes` that do the work, an `output` that is the automation's return value, and the `tests` that decide whether a version may be deployed. ```yaml name: billing/dunning-reminder description: Remind a customer about an overdue invoice. inputs: type: object properties: invoiceId: { type: string } required: [invoiceId] nodes: - id: invoice type: transform input: id: '{{ input.invoiceId }}' code: 'return { id: input.id, daysLate: 14 };' - id: message type: llm model: openai/gpt-4o-mini prompt: 'Write a polite reminder for invoice {{ nodes.invoice.output.id }}.' output: text: '{{ nodes.message.output.text }}' tests: - name: builds a reminder input: { invoiceId: 'inv-1' } ``` Canvas positions ride along in a `ui` block the engine ignores, so dragging a box around never changes behaviour. ### Edges are derived, not declared There is no edge list. One node reads another by referencing it — `{{ nodes.invoice.output.id }}` — and that reference _is_ the edge the canvas draws. Execution order is a topological sort over those derived edges, which is why deleting a reference also removes an arrow, and why two nodes that read each other are refused as a cycle. Templates use a single `{{ }}` JavaScript-expression grammar over `input`, `nodes.<id>.output`, and, inside an iterating node, `item` and `index`. ### Control flow rides on the node Branching and looping are fields on a node rather than separate step types, so the canvas shows them as badges on the box they affect. | Field | What it does | | ---------------------------- | ------------------------------------------------------------------------ | | `when` | Run the node only when the expression is truthy; dependents skip with it | | `elseOf` | Run exactly when the named node was skipped by its own `when` | | `forEach` | Run once per item of a collection, with `item` and `index` in scope | | `repeatUntil` / `maxRepeats` | Re-run until the expression is truthy, capped (default 5, maximum 20) | | `onError` | `fail` halts the run; `continue` records the error and skips dependents | ### Node types Three types are built in, and every connector action and platform native — knowledge search, document operations — joins the same table alongside them. **`transform`** runs pure JavaScript to reshape data. It has no network and no imports: the body reads the node's resolved `input` and must return a value. **`llm`** calls a language model with a templated prompt. `model` is required and always explicit — an automation never picks one on your behalf (the chat composer's Auto is a chat-only affordance). The output is `{text}`, or the schema-shaped object when the node declares an `outputSchema`. **`subworkflow`** runs another saved automation as a single node, referenced as `"name"` or `"name@version"`. Without a version it uses the deployed one, and nesting is capped at three levels. ### Structured and unstructured output Every node type's output is one of two kinds, and this is the rule authors hit most. A **structured** output is a typed shape you may path into with `nodes.<id>.output.<field>`. An **unstructured** output is free text: only `nodes.<id>.output.text` exists, and only in string context. A tool that declares no output schema is unstructured by definition, and the one sanctioned bridge from text to structured data is an `llm` node with an `outputSchema`. Validation refuses the mistake instead of letting it surface at run time, and every error carries a machine-readable code plus a hint naming what is actually available. Reading that hint is how you discover the shape you meant to reference. ## Versions never change Saving appends a new version; it never edits an existing one. Versions are numbered from 1 and stay contiguous per automation, and each carries the message its author wrote about what changed. Version 3 of an automation is therefore the same document forever. Two things follow. Editing an automation cannot disturb what is already running, because the running version is a different row. And a run that failed last month can be read against the exact document that produced it, because that document still exists untouched. ## Deploying is a separate act One version per automation is the deployed one, and that is the version triggers run. Promoting a version, or rolling back to an earlier one, is a single act that overwrites no history — the version list stays exactly as it was and only the pointer moves. An automation may also have no deployment at all and live purely as drafts. A version becomes deployable only once its own tests pass. Tests are stored with the document: each has a name, an input, and expectations about the output and about the effects the run should produce. Whether a version's tests passed is recorded when it is saved, so promoting reads that recorded fact instead of re-running the suite. <Note> An automation with no deployed version cannot be started at all — not by a trigger, not by hand. Save a version, then deploy it. </Note> ## What starts a run A trigger says what is allowed to start an automation, and there are exactly three kinds: a **schedule** (a cron expression read in a named IANA timezone), a **webhook** (an inbound URL guarded by a token), and an **event** (a platform event name). A trigger binds to the automation's **name**, never to a version. Deploying a new version therefore never invalidates a webhook URL an external system depends on, and never drops a schedule someone is relying on. Each trigger can be switched off and back on without being lost, and each records when the scheduler last acted on it. [Workflow triggers](/platform/automations/triggers) covers what each kind carries into the run. ## What a run records A run is a durable object, not a log line. It holds its status — `queued`, `running`, `waiting`, `success`, `failed`, or `cancelled` — its mode, what started it, the input it received, the output it produced, and a **checkpoint for every completed node**. Those checkpoints are the point. A live run steps node by node, and when it reaches the platform's action time window it hands itself back and resumes from the last completed node instead of repeating side effects already performed. A run also keeps the engine's full trace and the ordered list of effects it produced, which is what lets the canvas replay it and what keeps every outside change auditable afterwards. Runs come in two modes. **Mock** never touches the outside world and is the fast feedback loop while you author. **Live** may, which is why starting one is a developer-level action. [Execution logs](/platform/automations/execution-logs) reads a run end to end. ## Where a human decides A run that needs an approval does not fail and does not restart. It pauses in `waiting`, and when the approval is answered it re-enters at the node it stopped on, carrying the answer forward. A run waiting on human input behaves the same way. [Approvals in workflows](/platform/automations/approvals-in-workflows) covers the gates and what each decision leaves behind. ## Choosing the right unit | Reach for … | Automation | Agent | Agent webhook | | ------------------------------------------------------------------ | ---------- | ----- | ------------- | | Work with several steps, branches, schedules, or approvals between | ✓ | | | | Something that must run on a clock or answer a webhook | ✓ | | | | A recurring question in chat, with no external system involved | | ✓ | | | One agent reply per incoming POST | | | ✓ | Check the catalog before building — the automation you need may already ship. A [webhook trigger](/platform/automations/triggers) is the inbound seam; reach for it when an external payload should start a run. ## Putting the model to work An automation is one document, kept as an unbroken chain of versions, with exactly one of them deployed and a set of triggers bound to its name rather than to any version — which is what makes editing safe, rollback cheap, and a failed run reproducible. [The workflow editor](/platform/automations/editor) is the hands-on manual for saving, testing, deploying, and rolling back; [Browse and install automations](/platform/automations/catalog) is the route to the ones that already ship. # The workflow editor Source: https://tale.dev/docs/platform/automations/editor This page is the hands-on half of automations: what you click, in what order, to take a change from an idea to the version that triggers run. The model underneath — one document, immutable versions, one deployment, triggers bound to the name — lives on [Automation concepts](/platform/automations/concepts), and this page assumes it. Saving, testing, and deploying are three separate acts here, and keeping them separate is what lets you edit an automation that is live without disturbing a single running job. ## Where an automation lives Open **Automations** in the sidebar. The list shows every automation in the organization with how many versions it has and either the version that is live or **Not deployed** when it has none yet. Click one and you land on its page. That page is a single scrolling surface rather than a set of tabs. At the top sit the automation's name, the version you are looking at, the live version, and the run control. Below that is the canvas with a node panel beside it, then the save bar, the **Trigger** panel, and the **Projects** panel — which projects' task boards see the automation; none means the whole organization — and at the bottom the **Versions** and **Runs** lists side by side. ## Read the canvas The canvas draws the version on screen. Each box is one node, labelled with its id and its type, and boxes that read another node's output say so — a **Reads** line names the nodes it depends on. The arrows between boxes are not something you draw: an arrow exists because one node's field references another node's output, so the graph always matches the document. Control flow appears as badges on the box it applies to, in the same vocabulary the document uses — `when …`, `else of …`, `for each …`, `repeat until …` (with the cap shown when there is one), and `continue on error`. Nothing about the shape of the graph is hidden in a separate settings screen. Two states are worth recognising. A version with no nodes says so and tells you to add one to the document. A version whose nodes reference each other in a circle warns you that the order shown is the order they are written in, not an order the engine could run, and asks you to remove one of the references to break the cycle. <Note> The canvas is for reading and selecting. You wire nodes together by referencing them, not by dragging a connection between two boxes. </Note> ## Edit a node Click a box and the node panel beside the canvas fills with that node's fields. Which fields appear depends on the node's type: **Code** for a `transform`, **Prompt**, **System prompt**, **Model** and **Output schema** for an `llm`, **Workflow** for a `subworkflow`, and **Input** for anything that takes one. **Input** is a JSON object, and it is where references live. A string value may reference another node's output, and that reference is exactly what draws an arrow on the canvas. While the JSON is incomplete the panel tells you it is not valid yet and leaves the node unchanged, so a half-typed edit can never be saved by accident. Below the type-specific fields sits a **Control flow** group with **When**, **Else of**, **For each**, and **Repeat until**. These are the same fields the badges on the canvas reflect, so setting one here changes the badge immediately. ## Save, run, deploy The three acts are deliberately separate. Run through them in order the first time and the separation stops feeling like extra work. <Steps> <Step title="Save a version"> Edits show an **Unsaved changes** marker until you save. Write a **Version message** saying what changed — that message is the only thing distinguishing two versions in the list later — then click **Save version**. The save appends a new version and leaves every earlier one exactly as it was. With nothing changed, the button tells you there is nothing to save rather than minting an identical version. </Step> <Step title="Run it against mocks"> **Test run** starts a run in mock mode: connectors return their deterministic stand-ins and nothing outside the platform is touched. It is safe to press repeatedly, which is what makes it the loop to work in while you are still shaping a node. When the automation is bound to more than one project, a **project scope** selector sits beside the run controls. It defaults to organization-wide; pick one of the bound projects to make the run — and the task and document tools its agents use — act in just that project. </Step> <Step title="Deploy the version you want live"> In the **Versions** list, click **Deploy** on the version you want triggers to run. The live one carries a **Live** badge, and deploying a different one moves that badge without touching any version's contents. </Step> </Steps> <Note> The run control on this page always runs against mocks. A run that may reach the outside world is started by a trigger or by a programmatic call, and starting one is a developer-level action. </Note> ## Tests and the deploy gate Tests are part of the document, not a separate panel. Each test carries a name, an input, and expectations about the output and about the effects the run should produce, and they travel with the version like any other field. ```yaml tests: - name: reminds a late payer input: { invoiceId: 'inv-1' } expect: effects: - connector: email.send ``` Whether a version's tests passed is recorded at save time, and the **Versions** list shows the result as a **Tests passed** or **Tests failed** badge. Deploying reads that record: a version saved with failing tests is refused, and the list says the version was not deployed rather than silently doing nothing. Fix the cause and save a new version — a recorded result is a fact about that version and never changes. ## Roll back Rolling back is deploying an earlier version. Find the version in the list, read its message to confirm it is the one you want, and click **Deploy**. The badge moves, the newer versions stay in the list untouched, and no document is rewritten. This is why version messages matter more than they look. Six versions in, the message is what tells you which one was the last good state, so write it for the person who will be reading it during an incident. ## Read the last run on the canvas Once an automation has run, **Show last run** overlays that run onto the canvas. Every box picks up the status the run gave it — it **Ran**, was **Skipped**, **Failed**, was **Never reached**, or has **Not reached yet** while the run is still going — so a failure is visible as a position in the graph rather than as a line in a log. Select a node with the overlay on and the panel adds an **In this run** section: the **Resolved input** the node actually received after every template was evaluated, its **Output**, and the effects it produced, or a note that it changed nothing outside the platform. Resolved input is usually the fastest answer to "why did this node do that" — it shows the value a reference produced, not the reference you wrote. **Open the last run** goes to the full run page, where the same canvas sits alongside the run's input, its output, and the complete list of effects. [Execution logs](/platform/automations/execution-logs) reads that page end to end. ## Where this fits The loop is short once the three acts are clear: edit a node, save a version with a message worth reading, run it against mocks until it does what you meant, then deploy it — and deploy an older version when you need to undo. [Automation concepts](/platform/automations/concepts) is the model this page operates; [Workflow triggers](/platform/automations/triggers) is what starts the deployed version once you are happy with it. # Execution logs Source: https://tale.dev/docs/platform/automations/execution-logs Every start of an automation opens a run, and the run keeps writing to itself until it finishes. It records what started it, which version it used, what it received, what each node produced, and everything it changed outside the platform. This is the surface every other automations page points at when something did not happen the way you expected, so it is worth knowing how to read one before you need to. ## The run list An automation's page ends with a **Runs** list, newest first. Each row carries the run's status, whether it was a test or a live run, the version it ran, when it started, and what started it. A run that failed or is waiting shows the reason on the row itself instead of the starter, so the list often answers the question without being opened. An automation that has never run says so rather than showing an empty table. ## What each status means | Status | What it tells you | | ------------- | ----------------------------------------------------------------- | | **Queued** | The run exists and is waiting for the engine to pick it up | | **Running** | The engine is working through the nodes | | **Waiting** | The run is parked on a human decision or an answer it needs | | **Succeeded** | Every node the graph reached finished and the output was produced | | **Failed** | A node errored and nothing was configured to carry on past it | | **Stopped** | Somebody cancelled the run; work already performed is not undone | **Waiting** is the one people misread. It is not a stall and not a failure — the run is holding its place and will carry on from the node it stopped at as soon as the decision it needs is made. [Approvals in workflows](/platform/automations/approvals-in-workflows) covers what it is waiting for. ## Test runs and live runs Every run is marked as one or the other, and the difference is whether the outside world was touched. A **test** run uses each connector's deterministic stand-in: no mail leaves, no record is written, nothing is charged. A **live** run may do all three, which is why starting one is a developer-level action and why every effect it produces is recorded. Reading a test run tells you whether the graph and the data flow are right. Only a live run tells you whether the outside systems behaved. ## Reading one run Open a run and you get the automation's canvas with that run painted onto it, plus the run's own facts around it: the version, the mode, when it started, and when it finished. ### Per-node results Every box on the canvas carries the status the run gave it — it **Ran**, was **Skipped**, **Failed**, was **Never reached**, or has **Not reached yet** while the run is still going. A failure is therefore a position in the graph rather than a line to search for, and the nodes downstream of it show plainly as never reached. Select a node and the panel shows what happened to it: the **Resolved input** it actually received once every template had been evaluated, and its **Output**. Resolved input is the single most useful field on this page. It shows the value a reference produced rather than the reference you wrote, which is how a template that quietly resolved to nothing gets caught. Skipped nodes are worth reading rather than glossing over, because the reason differs: a node can be skipped by its own condition, by a node it depends on having been skipped, because it is the else-branch of a node that ran, or because it failed under a setting that lets the run continue. ### Effects A run also keeps the ordered list of everything it changed outside the platform — each entry naming which node caused it, which connector was called, and the input it was called with. A run that changed nothing outside the platform says so explicitly, which is a real answer rather than an empty section. The effects list is what makes a run auditable after the fact. When someone asks whether a message actually went out, this is the list that answers, and it stays with the run permanently. ## Why a long run does not repeat itself A live run does not execute in one go. It steps node by node, and every completed node is checkpointed before the next one starts, so when a run reaches the platform's time window it hands itself back and resumes from the last completed node. A node that already ran is never reached a second time, which is what stops an interrupted run from sending the same message twice. The same checkpoints cover a run whose continuation was lost. A run left in a non-terminal state past a grace period is picked back up automatically and continues from where its checkpoints say it got to, rather than restarting or sitting unfinished forever. ## A worked debugging session The daily reminder did not go out. Open the automation and look at the **Runs** list: this morning's run is there and it is **Failed**, with its reason on the row. Open it. The canvas shows the first three nodes as having run, the fourth as failed, and everything after it as never reached — so the question is already narrowed to one box. Select the failed node and read its **Resolved input**: the customer name is present, the invoice id is an empty string. That points one node upstream. Select that upstream node and read its output. It returned a record with no `id` field, because the field it was reading had been renamed. The template referencing it resolved to nothing, and the node downstream failed on the empty value rather than on anything wrong with itself. <Tip> Read the effects list before you fix anything. It tells you whether the run got far enough to touch the outside world, which decides whether re-running is harmless or needs cleaning up first. </Tip> Fix the reference in the node panel, save a version with a message naming the renamed field, and press **Test run**. The mock run walks the same graph and this time every box shows as having run. Deploy that version, and tomorrow's schedule picks it up. ## Stopping a run While a run is unfinished you can stop it, and a stopped run is terminal — the engine checks at every node boundary and stops scheduling the next one. Work already performed is not rolled back, because it cannot be: a message that was sent is sent. Read the effects list to see exactly how far it got before deciding what to do next. ## Where this fits A run is the receipt an automation leaves behind: its status says what happened, its per-node results say where, its resolved inputs say why, and its effects say what it changed outside the platform. Pair this page with [Workflow triggers](/platform/automations/triggers) for the kinds of start that open these records, and with [audit logs](/platform/admin/governance/audit-logs) for the organization-wide trail of who changed what. # Automation triggers Source: https://tale.dev/docs/platform/automations/triggers A trigger is what starts an automation when nobody is clicking anything. There are exactly three kinds, the set is closed, and an automation may carry several of them at once. The single most useful thing to know about a trigger is that it binds to the automation's **name** and not to a version, which is why deploying a new version never invalidates a webhook URL an external system depends on and never drops a schedule. Every trigger fires against the automation's deployed version and runs in live mode, so an automation with no deployment cannot be started by one. Each trigger carries an on-off switch and records when the scheduler last acted on it. ## The three kinds | Kind | Starts the automation when … | | ---------- | ---------------------------------------------------- | | `schedule` | A cron expression comes due in a named IANA timezone | | `webhook` | An external system posts to a token-guarded URL | | `event` | A named platform event happens | A programmatic start needs no trigger at all: an API client with an organization key calls `POST /api/v1/automations/{name}/runs` (or the MCP `start_run` tool) and the key itself is the entitlement — see the [API reference](/develop/api-reference). ## Schedules A schedule carries a five-field cron expression and the IANA timezone it is read in. The fields are minute, hour, day of month, month, and day of week, and each accepts a `*`, a number, a range, a step, or a comma-separated list of those. ```text */15 * * * * every fifteen minutes 0 9 * * 1-5 09:00 on weekdays 0 6 1 * * 06:00 on the first of the month 30 8 1 * 1 08:30 on the 1st and on every Monday ``` Day of week runs 0 to 7 with both 0 and 7 meaning Sunday. When you restrict both day of month **and** day of week, a day matching either one fires — the same rule crontab uses, which is what makes the last example read the way it behaves. The timezone is resolved as wall-clock time, so a schedule written for 09:00 in `Europe/Zurich` stays at 09:00 across a daylight-saving change instead of drifting an hour twice a year. A schedule that names no timezone is read in UTC. Resolution is one minute, and a schedule is a heartbeat rather than a queue: after an outage the automation resumes at its next occurrence instead of replaying the ones it missed. A schedule whose cron expression cannot be parsed is skipped rather than stopping the platform's other schedules, and its last-fired time stops advancing — which is the signal to go and read it. ## Webhooks A webhook is an inbound URL guarded by a token. Creating one mints the token and shows it once; only its hash is stored, so the platform can verify a caller without ever being able to reproduce the URL. Any system that posts to it starts a run, and the request body becomes the run's payload. ```bash curl -X POST https://<your-tale-host>/api/automations/webhook/<token> \ -H 'Content-Type: application/json' \ -d '{"invoiceId": "inv-1"}' ``` A successful call is accepted immediately and answers with the id of the run it started, so the caller never waits for the automation to finish. A body that is not JSON is handed through as text rather than refused, because some vendors post form or plain-text payloads. Bodies are capped at 256 KB — a webhook takes a payload, not an upload. You can scope the run to a project by adding `?projectId=<id>` to the URL — the project you bake into the URL you give the vendor. Leave it off and the run uses the automation's own binding: an automation bound to a single project runs there, one bound to several or to none runs organization-wide. The project is validated against those bindings, so a public URL can never widen the run past what the automation is bound to; a project outside the set answers with a 400. Two refusals are worth recognising. An unknown token and a token belonging to a switched-off trigger both answer the same way, deliberately, so that nobody can probe the platform for which tokens exist. An automation with no deployed version answers with a conflict instead, which tells you the URL is fine and the deployment is missing. <Warning> The token in the URL is the credential. Anyone holding the URL can start the automation, so store it the way you store a password, hand it out over a secure channel, and delete the trigger to revoke it — there is no way to recover the token afterwards. </Warning> ## Events An event trigger names a platform event and fires whenever that event happens in the organization. The event's payload becomes the run's input, which makes this the kind to reach for when the automation's job is to react to something the platform itself just did. <Note> An event raised by an automation's own run never fires triggers. An automation that writes a record, which raises an event, which starts the same automation, is an unbounded loop that no per-run limit can stop, so the platform refuses at the point of dispatch instead. </Note> ## What each kind carries into the run The input an automation receives says which kind started it, so a single document can serve more than one trigger and branch on the difference. | Kind | The run's input | | ---------- | --------------------------------------------------------- | | `schedule` | The trigger kind and the occurrence time it fired for | | `webhook` | The trigger kind and the posted body as the payload | | `event` | The trigger kind, the event name, and the event's payload | An API-started run carries exactly the `input` the caller sent. Declare the shape you expect in the document's `inputs` schema and the reference to it validates before the automation ever runs. ## Deploying does not disturb them Because a trigger names the automation rather than a version, the whole set survives every deploy and every rollback. Publish a webhook URL to a partner, deploy eleven more versions, roll back twice, and that URL keeps working and keeps hitting whatever is live at the time. The same holds in the other direction: adding, editing, or removing a trigger changes nothing about the document or its versions. Triggers and versions are two independent things about the same automation. ## Turning one off without losing it Every trigger has an enabled flag, and switching it off is the way to stop an automation firing without giving anything up. A disabled schedule stops coming due, a disabled webhook URL stops being honoured, and a disabled event trigger stops matching — while the row, its configuration, and the automation's whole run history stay exactly where they were. Switch it back on and it resumes. Deleting a trigger is the permanent version of the same thing, and for a webhook it is also how you revoke the URL. Reach for the switch when you want a pause and for deletion when you want the credential gone. ## Where this fits Three kinds, one behaviour: each starts the deployed version in live mode, each records when it last fired, and each can be paused without being lost — and none of them care how many times you have deployed since. [Automation concepts](/platform/automations/concepts) explains why binding to the name is what makes that true; [Execution logs](/platform/automations/execution-logs) shows the runs your triggers produced and which one started each. # Arena Mode Source: https://tale.dev/docs/platform/chat/arena-mode Arena Mode runs the same prompt against two models at once and asks you which reply is better. The verdict feeds the org's feedback analytics; over time, the data tells which model the team actually prefers for which kind of question, separate from anyone's gut feel. Reach for Arena when picking a model has been a debate rather than a decision — comparing replies side by side breaks the deadlock with evidence rather than opinions. For ordinary work the regular model picker is enough; Arena's value is the verdicts it produces, not the comparison view itself. ## How Arena renders Open the chat's plus menu and pick **Arena Mode** — the chat sprouts two model pickers labelled **Model A** and **Model B**. Sending a message runs both models in parallel; the screen splits and each reply streams into its own column. Once both finish, a verdict row appears under the columns with four buttons: **A is better**, **B is better**, **Tie**, **Both bad**. <Frame caption="The same prompt answered by two models, with the verdict row beneath."> ![Arena Mode with one launch-checklist prompt answered in two columns — Claude Haiku 4.5 on the left returning a numbered five-step list, Claude Sonnet 4.6 on the right grouping the same work under headings and adding the risks worth flagging — above the A is better, B is better, Tie, and Both bad verdict buttons.](/images/platform/chat-arena-split.webp) </Frame> <Note> Both columns run the same agent — pick the agent you care about before you enable Arena, because the comparison is only meaningful when the instructions, tools, and knowledge on each side are identical. </Note> ## Picking the contenders The two pickers are independent — any model the agent's policy allows is fair game on each side. Picking the same model on both sides is allowed (useful for testing temperature differences if the agent exposes that), but most comparisons span vendors or sizes. The agent's instructions, knowledge, and tools apply to both columns; only the underlying model differs. ## Casting a verdict The verdict is single-click. **A is better** and **B is better** are self-explanatory; **Tie** is for when both replies are roughly equally good; **Both bad** is for when neither is acceptable. The button you click records the verdict and resolves the chat to the winning column — the next message you send goes to that model only. Picking **Tie** or **Both bad** leaves both columns active for one more round. ## Where verdicts surface Verdicts roll up into [Feedback analytics](/platform/admin/governance/feedback-analytics) under **Arena verdicts**, alongside a **Top Model Matchups** table that ranks pairings by win rate. The data is org-scoped rather than per-user, so a handful of deliberate verdicts can outweigh a much larger pile of habit when someone reads the table to decide which model the team should reach for. ## When to reach for it | Use … when | Arena Mode | Regular model picker | | ---------------------------------------------------------- | ---------- | -------------------- | | You are deciding which model to default to | ✓ | | | You suspect a model regression after an upgrade | ✓ | | | You already know which model you want and need a reply now | | ✓ | | The query is short and ordinary | | ✓ | ## Where this fits Arena is the lightweight feedback loop on top of model choice. The heavier surface is [Feedback analytics](/platform/admin/governance/feedback-analytics) — that is where the verdicts you cast become a chart someone uses to argue about defaults. If you are the one who will read the chart later, run a handful of Arena rounds before reading the chart; the verdicts you cast yourself will tell you whether the table's framing matches your experience. # Chat basics Source: https://tale.dev/docs/platform/chat/basics This page is the mental model for everything in the Chat tab. It names the parts of the composer, traces a message from key-press to streamed reply, says exactly what the model is handed and what it may call along the way, and shows how to read what came back. Read it once and the rest of the chat pages are variations on the same flow. <Frame caption="The Chat tab with a streamed reply above the composer."> ![A chat thread showing a user question about onboarding feedback and an assistant reply containing a markdown table of three themes.](/images/platform/chat-thread-reply.webp) </Frame> ## The composer The composer is the input strip at the bottom of the screen. The message field sends on **Enter** and breaks the line on **Shift+Enter**. One picker beside the `+` menu holds the model choice — **Auto**, the default, lets Tale pick a model per message, or you name one — and, for a named model that exposes it, the reasoning effort. That is the whole set of choices, by design: there is no agent picker, no skill picker, and no control over where the turn runs. The `+` menu holds **Add photos & files** and, on chats that can host one, **Arena Mode** ([Arena Mode](/platform/chat/arena-mode)); **Read replies aloud** ([Voice mode](/platform/chat/voice-mode)) is the speaker toggle beside the microphone, and the microphone dictates into the field. While a reply streams, the send button becomes stop. Stopping keeps everything that already streamed — the reply settles as it is, mid-sentence if that is where it was. ### Attachments Drag files from your desktop anywhere onto the composer — an overlay says **Drop files here to upload** while you hover — paste a screenshot straight into the message field, or pick files through the `+` menu's **Add photos & files**. Chat takes images, documents (PDF, Office, OpenDocument, CSV), text-based files, and audio/video. Each image stages as a small thumbnail above the field: click it to zoom, and its ✕ removes it. Everything else stages as a named chip that tracks its processing: the organisation's transcription model turns audio and video into text, and documents are indexed for retrieval. Sending never waits on a progress bar — a message sent while files still process parks above the composer and goes out by itself the moment everything is ready; its ✕ abandons the queued send and puts the text back. Up to ten files ride one message. Paste a video link (YouTube, Vimeo, Bilibili and friends) and it becomes a chip too: Tale fetches the captions — or extracts and transcribes the audio when there are none — in the background, and the transcript rides your message exactly like an uploaded recording. Only a failed video chip holds the send, because waiting on it would never end: retry it or remove it, everything else queues. A model that can see images receives the pixels themselves, inline with your words; for one that cannot, the composer says so while the images are staged — that model would only see the file names. Audio never reaches the chat model as bytes: the model receives the transcript as text while your bubble keeps the words you typed (and the audio chip). A document's content reaches the assistant through its knowledge tools — the turn tells it which files are attached and it reads them with `rag_fetch`, so expect a retrieval step before the answer. A format with no text extractor (legacy Office files like `.doc`) still attaches, but the assistant only sees its name and will say so rather than guess. Documents dropped here stay private to this conversation — they never join the organisation's [Knowledge](/platform/knowledge/overview) library, and no other chat or teammate can retrieve them. Staged files belong to the conversation they were staged in (switching chats clears them), and regenerating a reply re-sends the same attachments — transcripts and document access are rebuilt for the model from the stored files. Work that produces files belongs to a task. Speaking into the microphone is a separate path — see [Voice mode](/platform/chat/voice-mode). <Frame caption="The composer: message field, the model-and-effort picker, dictation, send."> ![The chat composer with its plus menu, model picker showing Auto, microphone button, and send button.](/images/platform/chat-composer.webp) </Frame> ## Picking a model The picker opens on **Auto**: for every message, Tale reads what you wrote — length, code, subject matter — and picks a model for it from the same list the picker shows, favouring a light model for a quick question and a strong one for hard or sensitive ground. A document attachment raises the floor: a message that carries a file to read never goes to the lightest model, however short the question. No second AI decides this (it is a plain heuristic on the message), and there is no silent failover: the model that starts your reply is the one that answers it, and the message details name it. Once a message carries images, only models that can see them are considered; if none can, the send says so instead of guessing. Prefer to decide yourself? Pick any model from the list — the picker lists the models the organisation holds an active, directly-usable credential for; a model that could only run inside a vendor's own tooling is not offered here. A named pick is yours until you hand it back to Auto, and either choice sticks as the default for your next chats. Auto appears only when there is a real choice to make — with a single usable model the picker simply names it. For models with controllable reasoning depth, the picker's second section sets the effort. The pick rides the conversation — every following turn runs at the level you set, and models without the knob ignore it. Left on **Default**, a model that can answer without extended reasoning does exactly that — pick a level when you want it to think longer. On Auto the effort section stays out of the menu: how hard a model thinks is paired with _which_ model, so pin one to set it. ## What the model is given The prompt is assembled in one fixed order, and the list is short by design: the organisation's mandatory instructions, the assistant's built-in guide, the rules for handling untrusted content, one short line of documentation per tool, then the current timestamp with the response-language directive, then the full message history — including every tool call and result, exactly as they happened. Nothing else is added. There is no personalisation blob, no memories slipped in behind your back, no automatic knowledge retrieval, and no automatic web context. Everything the model learns beyond its instructions, it learns by calling a tool — which means it shows up in the transcript, attributable and refusable. <Info> When the conversation outgrows the model's context window, the oldest messages are dropped and a visible notice takes their place. They are not summarised: a summary is a second model call that can invent the history it was meant to preserve, and dropping messages is lossy in a way you can see. </Info> ## The three tools The assistant carries exactly three tools, all read-only retrieval — this is the boundary that keeps chat a conversation rather than a workbench. | Tool | What it reaches | | ------------ | -------------------------------------------------------------------------------------------------------------------------------- | | `rag_search` | The organisation's knowledge: documents, knowledge entries, crawled website pages, products, and contacts | | `rag_fetch` | The full text behind a ref — an attached or found document by its file id, or a crawled page by its URL | | `web_fetch` | A public web page, fetched live — the step beyond the organisation's knowledge; content already crawled is served by `rag_fetch` | A search is honest about what it covered: the result names every source it searched and says which were unavailable — an organisation without an embedding model configured, for example, gets "documents and crawled pages can't be searched yet" rather than a silent empty list, and the assistant relays that instead of guessing around it. There is deliberately nothing else — no code execution, no file writing, no connectors, no sub-agents. Those capabilities live on tasks and inside automations, where there is an owner, a review step, and an audit trail sized for them. ## Asking for a deliverable Ask the assistant for a presentation, a translated document, or any other artifact and it will not half-build one inline: it gives you the short version if one is useful, then tells you to create a task and assign it to an agent. A task has an owner, produces a reviewable result, and only a person marks it done — none of which a chat reply can offer. Translating a sentence you pasted is chat work; translating a file is task work. ## Reading the reply The reply streams in as it is generated. Above it, the thought timeline records what the assistant did, in order: - A collapsible **"Thought for _n_ s"** line carries the model's reasoning — click to expand the prose. - Each tool call is a step row — _Searching knowledge base for "…"_, _Reading example.com_ — with a spinner while it runs and a warning with the reason when it fails. The steps stay visible when the reasoning is collapsed; they are the record of what the assistant reached for. Below the answer, **Sources** lists the pages and documents the assistant actually loaded — derived from the tool results, not from the prose, so a source card never claims reading that did not happen. Web sources open in a new tab. The toolbar under a settled reply copies the text, shows token counts and timings (**Send → first words** from Send; **Start → done** and **Start → first token** from when the server begins the reply), records a thumbs rating, and forks the chat — a visible copy of the conversation up to that point, continued as a new chat of its own. ## Conversations versus chats Within Chat, the unit is a **chat** — that is the word every button and toast uses. The data model behind it is called `threads` and the URL carries `threads/$threadId`; the docs follow the UI and say "chat" in body prose. The contact-channel inbox an installed email automation adds is a different surface: a conversation there is a contact thread, not a chat — see [Built-in automations](/platform/automations/builtin) for that sense of the word. ## History and search The chat history sidebar lists every chat you can resume in this org, newest first, with your pinned chats floating on top and project-filed chats under their folders; selecting one opens the full transcript. Searching there filters by title, and full-text search across message bodies is a per-chat operation rather than an org-wide one. Renaming a chat sets a custom title that overrides the generated one. Deleting a chat moves it into [Trash](/platform/admin/governance/trash), where retention sweeps it after the grace window. ## Where this fits Chat basics is the page the rest of this section refines: [Arena Mode](/platform/chat/arena-mode) runs one prompt through two models side by side, [Voice mode](/platform/chat/voice-mode) covers speaking instead of typing, and [Shared chats](/platform/chat/shared-threads) covers publishing a transcript to the org. If your question turned into work — something with a deliverable at the end — [Agent concepts](/platform/agents/concepts) is the next read: agents do on tasks everything chat deliberately leaves out. # Chat Source: https://tale.dev/docs/platform/chat/overview Chat is the everyday entry point to Tale. You ask, the assistant searches the organisation's knowledge or fetches a page when the question needs it, and the reply streams back with every step and source on display. Chat deliberately does one job — questions and retrieval. Work that needs an owner and a reviewable result — a presentation, a translated document, a data export — lives on a task; a fixed process lives in an automation. The assistant knows that boundary and points you to a task the moment a request crosses it, so nothing heavy ever gets half-built inside a chat. <Frame caption="A chat with a streamed reply — the question, the assistant's steps, and the answer."> ![A chat thread showing a user question about onboarding feedback and an assistant reply containing a markdown table of three themes.](/images/platform/chat-thread-reply.webp) </Frame> ## The parts of the screen The sidebar lists every chat you can resume, filed under your project folders, pinned favourites first, with search and an archive below. The conversation column carries the exchange: above each reply, a collapsible thinking line records what the assistant did — the reasoning and each knowledge search or page fetch, in order — and below the answer, **Sources** lists what it actually read. The composer at the bottom is the message field plus one picker for the model — **Auto** by default, any listed model to pin, and the reasoning effort for a pinned model that has one; the `+` menu holds read-aloud and Arena Mode, and the microphone dictates. While a reply streams, send becomes stop. A fresh chat opens with four starter prompts. Click one and it becomes your first message — the fastest way to see the whole loop run once. <Frame caption="A new chat: the welcome heading, four starters, and the composer."> ![The empty new-chat screen showing the welcome heading, four conversation starter buttons, and the composer below.](/images/platform/chat-starters-empty.webp) </Frame> ## Chat, task, or automation? Match the work to the surface — each kind has exactly one home. | Kind of work | Where it lives | Why | | --------------------------------------------------------------- | -------------- | ---------------------------------------------------------------------- | | Ask about knowledge, documents, or a public web page | Chat | Conversation with visible steps and sources; nothing to sign off | | Produce a deliverable — a presentation, a translation, a report | Task | Needs an owner and review; an agent does the work, a person marks Done | | A fixed process with validation gates and human steps | Automation | The process is the product; people and agents act inside it | The assistant enforces the first row itself: ask it for a 2000-word essay and it gives you a brief sketch, then tells you to create a task and assign it to an agent. That is by design — a deliverable produced inline in chat would have no review step and no owner. ## Pages in this section <CardGroup cols="2"> <Card title="Chat basics" icon="message-circle" href="/platform/chat/basics"> What happens between hitting send and the reply landing — the composer, the three retrieval tools, the thought timeline, and sources. </Card> <Card title="Arena Mode" icon="swords" href="/platform/chat/arena-mode"> Side-by-side model comparison, and how verdicts roll into feedback analytics. </Card> <Card title="Voice mode" icon="mic" href="/platform/chat/voice-mode"> Speaking instead of typing — the STT and TTS handoffs and the privacy boundary. </Card> <Card title="Shared chats" icon="share-2" href="/platform/chat/shared-threads"> Sharing a read-only snapshot of a chat with the rest of the org, and stopping the share later. </Card> </CardGroup> ## Where this fits Chat is the asking surface; the rest of the platform is what it asks. Knowledge feeds its searches, and [projects](/platform/projects/overview) file its history and carry the tasks that pick up everything chat deliberately refuses to build inline. The page worth bookmarking first is [Chat basics](/platform/chat/basics) — once you understand the send-to-reply path, every other chat page reads as a variation on it. # Shared chats Source: https://tale.dev/docs/platform/chat/shared-threads Sharing a chat publishes a read-only snapshot of it at a link anyone in your organization can open. It is one gesture: **Share** copies the link to your clipboard, and you paste it wherever your team talks. The mechanic is light enough to use casually — share a question and its answer the way you would share a document. ## Sharing a chat Open the chat and click the **⋯** menu in the header, then **Share**. The link lands on your clipboard immediately — a **Link copied** toast confirms it. The same entry lives on each chat's row menu in the sidebar. Two things worth knowing about the link: - **It is org-scoped.** Only signed-in members of your organization can open it; it is not a public URL. - **It is a snapshot.** The recipient sees the conversation as it stood when you shared it. If the chat moves on and you want to share the newer state, click **Share** again — the link stays the same and the snapshot refreshes. <Frame caption="What the recipient opens: the shared, read-only snapshot with its byline."> ![A shared chat viewed read-only, showing the conversation transcript under a Shared chat heading with a byline naming who shared it and when.](/images/platform/chat-shared-view.webp) </Frame> ## What the viewer sees The link opens a read-only **Shared chat** view: the transcript, with a byline naming who shared it and when. There is no composer — a shared chat is something to read, not a place to reply. A viewer who wants to take the topic further starts their own chat — or a task in a [project](/platform/projects/overview), if what they want is a deliverable. ## Stopping sharing The chat's row menu offers **Stop sharing** once a chat is shared. The link stops working immediately; visitors land on a "no longer available" page. Deleting the chat has the same effect on the link. Sharing again later publishes a fresh snapshot. ## Where this fits Shared chats are the lightweight way to hand a conversation to a teammate without leaving the product. The heavier-weight alternative is bringing the teammate into a [Project](/platform/projects/overview) where chats, files, and agents are shared by default. Sharing is for one-off handoffs; a Project is for ongoing collaboration on the same work. # Voice mode Source: https://tale.dev/docs/platform/chat/voice-mode Voice mode turns the composer into a microphone. You speak, the recording is transcribed into your next message, the agent answers in text, and the answer can be read back out loud. The loop is hands-free, which is worth a lot when you are walking, cooking, or tired of typing — and it crosses two speech providers, which is worth knowing before your organisation's data goes through it. This page covers both halves of the round-trip and the boundary the audio crosses. The chat itself does not change: voice is a wrapper around the same message flow described in [Chat basics](/platform/chat/basics). ## Speech to text Start recording from the composer's microphone control and speak; stop it the same way. The recording is uploaded, a speech-to-text model transcribes it, and the transcript becomes the next message in the chat — exactly as if you had typed it. You can read the transcript before it goes, which matters because a transcription error is indistinguishable from a badly phrased question once the agent has answered it. Transcription runs once per spoken message. What the agent receives is text; no audio reaches the chat model. ## Text to speech Reading a reply aloud is a choice you make in the composer, for the turn you are about to send. Switch voice output on and the reply that comes back is sent to a text-to-speech model and played as it arrives; leave it off and the reply lands as text like any other. Playback can be stopped early, and the last reply can be played again without re-asking the question. <Note> Voice output is a composer control, not a saved preference. There is no per-agent voice pinned to an agent and no organisation-wide default that decides for you — the turn you are sending is the scope of the choice, which keeps a hands-free session from following you into a shared office. </Note> ## Which provider holds which piece Two model picks matter here, and neither is the model in the model picker. Speech-to-text runs before the agent turn, on the audio. Text-to-speech runs after it, on the finished reply. The agent between them is unchanged — the same instructions, the same tools, the same context contract. Both are configured by whoever administers the organisation's providers. If no speech provider is configured, the composer's voice controls have nothing to call, and the answer is to connect one rather than to change anything in the chat. ## Privacy boundary The recording leaves your device. It is uploaded to Tale's storage, sent to the speech-to-text provider the organisation configured, and the resulting transcript is kept in the chat history alongside the typed messages — searchable, exportable, and subject to the same retention rules as everything else in the chat. The audio itself is retained under the org's retention policy. Replies go out to the text-to-speech provider as plain text, and the returned audio streams to your device rather than being stored. <Warning> Organisations with strict data-residency rules should pick speech providers in the same region as the rest of the stack — the audio and the transcript are subject to the same rules as any other message content. See [Data residency](/cloud/data-residency). </Warning> ## When voice beats text Voice is faster than typing for short, conversational questions and considerably slower for anything you would copy out afterwards. A spoken answer is heard once; a written one can be skimmed, quoted, and pasted. | Use … when | Voice | Text | | ------------------------------------------------- | ----- | ---- | | You are hands-busy and want a quick fact | ✓ | | | The reply will be a long list or a code block | | ✓ | | The agent's reply will feed a later written task | | ✓ | | You are practising a language and want to hear it | ✓ | | ## Where this fits Voice is the second input shape on the same composer, beside typing. The privacy story carries the most weight here because two extra providers touch the data, so the page worth reading next depends on your edition — [Data residency](/cloud/data-residency) on Cloud, or [Providers](/self-hosted/configuration/providers) if you run Tale yourself and choose the speech providers as well as the chat ones. # MCP servers Source: https://tale.dev/docs/platform/connectors/mcp-servers An MCP server is an external process that exposes tools to Tale's agents over the Model Context Protocol. Where an [connector](/platform/connectors/overview) is a vendor-specific connector Tale ships, an MCP server is a generic bridge anyone can host — an internal API, a vendor without a connector, a script that computes something Tale's built-in tools cannot. You host the server; Tale only talks to it. <Frame caption="The Add MCP server form — a connection and an authentication method are the whole registration."> ![The Add MCP server dialog under Settings API MCP, filled in for a support-tickets server — display name Support Tickets, a one-line description, Streamable HTTP as the transport type, the server URL, and an authentication method of None — over the MCP page, where an Internal Wiki server is already registered.](/images/platform/settings-mcp-add-dialog.webp) </Frame> ## Registering a server Open **Settings > API > MCP** and click **Add MCP server**. The form takes: - **Name** and **Display name** — the identifier, and the label agents and approval cards show. - **Transport type** — **Streamable HTTP**, **SSE**, or **stdio**. The HTTP transports take a **URL** — the form flags a malformed one inline before you can save; stdio takes the command Tale spawns. - **Authentication** — **None**, **API Key**, or **OAuth 2.0** (token URL, client ID and secret, scopes). - **Allowed agents** — which agents may bind to this server. The default is no agents; reach for **All agents** only when the server is generic enough that every agent benefits. **Save server**, then use **Test connection** on the row to verify the handshake — the row's status shows **Connected**, **Disconnected**, or **Error** with the upstream message. ## The discovered tools Once connected, Tale fetches the server's manifest and lists it as **Discovered Tools** — each tool's name, description, and whether the server flags it **Requires approval**. Flagged tools ask in chat every time an agent calls them, with the exact arguments shown on the card; unflagged tools run like any built-in tool. <Warning> Every MCP tool widens what your agents can reach, and the approval flags come from the server's author — connecting a server means accepting its tool contract. Read the discovered list before pointing agents at a server you did not write. </Warning> ## Using it from agents A registered, active server's tools join the toolbelt agents can call; the request travels through Tale to your server and the reply comes back into the conversation. The server can also expose resources and prompts where its author implements them — tools are the common surface. ## Deactivating and removing Each server row can be deactivated — its tools drop out of agent toolbelts until you activate it again, with the registration kept. Deleting the server removes the registration entirely after a confirmation; re-adding it later is a fresh registration with a fresh manifest fetch. ## MCP server or connector Both let an agent reach beyond Tale; the difference is who owns the connector. Connectors are vendor-specific, shipped, and maintained in the catalog; MCP servers are generic and yours to run. Reach for the connector when one exists for the target system; reach for MCP when you need the bridge to be your own code. ## Where this fits MCP is the open-ended extension surface of the agent toolbelt. The natural next reads are [Agent tools](/platform/agents/tools) for how tools surface on an agent, [Configure approvals](/platform/approvals/configure) for the flags that hold risky calls, and the [MCP server from scratch](/tutorials/developer/mcp-server-from-scratch) tutorial for building one end to end. # Connectors Source: https://tale.dev/docs/platform/connectors/overview An connector is two things at once: a **connector** that ships with the platform, and the **credentials** your organisation stores against that connector. The connector carries the vendor knowledge — which actions exist, what each one takes and returns, how signing in works — and is identical in every organisation. The credentials are yours, and a connector holds as many as you need: one per workspace, store, mailbox, or bot. Thirteen connectors ship today, and each one is already listed under **Settings > Connectors**, waiting for its first credential. Prefer to watch first? Episode 7 walks the doors to the outside world — connectors, MCP, and the boundaries — in two and a half minutes, captions included. <Video src="/videos/en/tutorials/ep7-connectors/ep7-connectors.en.mp4" poster="/videos/en/tutorials/ep7-connectors/ep7-connectors.en.webp" captions="/videos/en/tutorials/ep7-connectors/ep7-connectors.en.vtt" lang="en" title="Episode 7 — Connectors & the outside world" caption="Episode 7 — Connectors & the outside world (2:30)"> </Video> ## What a connector is There is nothing to install. Every connector arrives with the platform, which is why the catalog looks the same in every organisation and why an upgrade keeps it current without anyone maintaining it. A connector is a definition: a display name and a one-line description, the category tags it belongs to, the authentication methods it accepts, and the list of actions it can perform against the vendor. Because the definition is shared, the only thing your organisation decides is which accounts Tale may act as. That decision is a credential, and it is the whole of setup. ## The connectors that ship Thirteen connectors ship, each tagged with the category it belongs to — Knowledge, Messaging, Email, Developer, Commerce, Search, or Files. **Sign-in** is the authentication method the connector accepts, which decides what the credential form asks for; **Actions** is how many operations it exposes, the same count the connector's section shows on the settings page. | Connector | What connecting it buys you | Sign-in | Actions | | ----------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------- | ------- | | **Confluence** | Import Confluence Cloud pages into Tale's knowledge base. | Username & password | 2 | | **Discord** | Post messages and manage channels in your Discord server. | Token | 8 | | **GitHub** | Manage repositories, issues, and pull requests on GitHub. | Token | 19 | | **Gmail** | Read, send, and organize email in Gmail. | OAuth | 9 | | **Google Drive** | Import files from Google Drive into Tale's knowledge base. | OAuth | 2 | | **IMAP / SMTP Mailbox** | Connect a private IMAP + SMTP mail server to Conversations — no Gmail or Outlook account required. | Username & password | 2 | | **Microsoft Outlook** | Manage Outlook mail, calendar, and contacts. | OAuth | 10 | | **Shopify** | Sync products, customers, and orders from your Shopify store. | API key | 9 | | **Slack** | Send messages and interact with channels in Slack. | OAuth | 7 | | **Tavily** | Real-time web search and page extraction for AI research. | API key | 2 | | **Microsoft Teams** | Send messages and manage channels in Microsoft Teams. | OAuth | 9 | | **Twilio** | Send SMS and make voice calls with Twilio. | Username & password | 7 | | **WebDAV Files** | Read, write, and list files in the organisation's WebDAV store — the same files the `/dav` endpoint serves. | Username & password | 4 | Pages and files pulled in through Confluence or Google Drive run through the same indexing pipeline as a direct upload, and answers cite them back to the source — see [Documents](/platform/knowledge/documents). The WebDAV connector is the write side of the same store your devices mount as a network drive, covered in [WebDAV](/platform/connectors/webdav). ## Credentials on a connector A connector holds as many credentials as your organisation needs. One Slack workspace per business unit, one Shopify store per market, one mailbox per support queue — each is a separate row under the connector, with its own secret and its own state. That is what lets a single automation library serve several teams without any of them borrowing another's account. Each credential carries four things: - **Name** — the name an action uses to pick this credential. Write it for whoever reads the automation months from now: `Support inbox`, `EU store`, `Release bot`. - **Authentication method** — **API key**, **Token**, **Username & password**, or **OAuth**, chosen from what the connector accepts. - **Default** — one credential per connector can hold this. An automation node or chat action that names no credential uses the default. - **State** — a credential is either in use or **Disabled**. Disabling keeps the row and its configuration but stops anything calling through it. Leave a connector without a default and it still works for callers that name a credential outright, but a caller that names none has nothing to fall back on. The connector's section says as much, and the fix is to promote one of the existing credentials. <Note> Confluence and Shopify have no single vendor host — the API lives at your own Atlassian site or your own `myshopify.com` store. Both therefore ask each credential for an **Instance URL**, and their section carries the line _Each credential names its own instance_. Point Confluence at the address you open Confluence at, and Shopify at the store's admin origin rather than its storefront domain. </Note> ## Connecting one Where you start depends on what the connector accepts. Token-shaped connectors open a form and take the secret directly; OAuth connectors send you to the vendor's consent screen and return with the credential already filled in. Both paths end in the same place — a named row under the connector. <Steps> <Step title="Open Settings > Connectors"> Every connector has a section, headed by its icon, description, category tags, and action count. Nothing is hidden behind a catalog dialog. </Step> <Step title="Add the credential"> **Add credential** opens the form for connectors that take a key, a token, or a username and password. **Connect** runs the vendor's consent flow for OAuth connectors, then binds the result to a new row. </Step> <Step title="Name it, and make it the default"> Give the credential a name your automations can point at, and promote it if it should be the one used when nobody names a credential. The connector's actions become available to automations and chat as soon as the row exists. </Step> </Steps> The per-method detail — what each form asks for, how to replace a secret, what happens when an authorization expires — lives on [Connector credentials](/platform/admin/connectors). ## Actions in automations and chat Every action a connector declares has a name, a description, an input schema, an output signature, and a declared effect of `read` or `write`. Automations place an action as a node in the workflow editor; chat reaches the same actions as agent tools. Either way the call resolves a credential first — the one the caller names, or the connector's default — and fails clearly when neither exists. <Warning> Write actions change something in the other system: a message posted, an issue opened, an SMS sent. They gate behind your organisation's approval policy, so the agent proposes the call and a person releases it. Read [Configure approvals](/platform/approvals/configure) before pointing an agent at one. </Warning> ## When no connector fits Thirteen connectors cover the systems most teams reach for, and they cannot cover an internal API, a homegrown tool, or a vendor nobody has written a connector for. That is what MCP is for: you host a server, Tale registers it, and its tools join the agent toolbelt alongside connector actions. The bridge is your code rather than a shipped definition, which is exactly the trade — more freedom, more to maintain. Register one under **Settings > API > MCP**, as described in [MCP servers](/platform/connectors/mcp-servers). ## Where this fits Connectors are how Tale reaches the systems your work already lives in, and credentials are how you decide which accounts it may act as. From here, [Connector credentials](/platform/admin/connectors) is the operations side — adding, replacing, disabling, and reconnecting the rows under each connector. [Agent tools](/platform/agents/tools) shows how a connector's actions arrive in an agent's toolbelt, [Configure approvals](/platform/approvals/configure) holds the write ones, and [MCP servers](/platform/connectors/mcp-servers) covers the ground the catalog does not. </content> </invoke> # WebDAV Source: https://tale.dev/docs/platform/connectors/webdav WebDAV turns Tale's document store into a remote folder you mount like any shared network drive. The backing store is the same one the Document Hub shows — what you drop into the mounted folder appears in the UI, and vice versa. Everything you need is on one panel: **Settings > API > WebDAV** carries the connection details and the app-password generator. <Frame caption="Settings > API > WebDAV — the pre-filled connection details on top, the app-password generator below."> ![The WebDAV settings page showing a connection URL, a username field with the account email, an explanation that the password is a generated app-password, and an app-passwords table holding two entries — Design workstation and MacBook Pro, each with only its prefix and creation date — beside a Generate button.](/images/platform/settings-webdav.webp) </Frame> ## Generate an app-password The endpoint authenticates with app-passwords — short secrets you mint per device — because every WebDAV client stores its credential in the system keychain, and a scoped, revocable secret belongs there rather than your account password. Your account password does not work on this endpoint. Click **Generate**, label the password after the device (`MacBook Finder`, `ops-laptop rclone`), and copy it — use one per device; the full password is only shown once. Afterwards the table keeps only the label and a short prefix, enough to recognise the row when you revoke it. Generating requires the same capability that gates API keys; plain members ask an admin. For the username, use your Tale account email. Only the password is actually verified, but the email keeps audit rows readable and matches what client dialogs expect. ## Connect from your device The address is the URL from the panel — `https://<your-site>/dav/<orgSlug>/documents/`. <Tabs> <Tab title="macOS Finder"> Press **⌘K** (Connect to Server), paste the URL, and sign in with your email and the app-password. The share mounts in the sidebar; drag files in to upload, out to download, and rename or delete in place. The first listing of a large tree can take a few seconds. </Tab> <Tab title="Windows"> In **This PC**, choose **Map network drive**, paste the URL as the folder, and pick **Connect using different credentials**. Windows caps WebDAV transfers at 50 MB per file by default — raise `FileSizeLimitInBytes` under the `WebClient\Parameters` registry key and restart the WebClient service. On a non-standard HTTPS port, set `BasicAuthLevel` to `2` under the same key. </Tab> <Tab title="iOS Files"> Tap the three-dot menu, choose **Connect to Server**, and enter the same URL and credentials. Files supports browsing and downloading; in-place editing works for formats with an iOS app. </Tab> <Tab title="rclone"> ```bash rclone config create tale webdav \ url=https://<your-site>/dav/<orgSlug>/documents/ \ vendor=other \ user=<your-email> \ pass=$(rclone obscure '<app-password>') rclone copy ./local-folder tale: --progress ``` `vendor=other` is correct — Tale's server is generic, not a named flavour rclone recognises. </Tab> </Tabs> ## What the mount can do Reads and writes mirror your Document Hub permissions, files you upload index and search like direct uploads, and their source field is set to `webdav` for filtering in audit views. Project files are the exception: a project's **Knowledge** tab is scoped to that one project and never appears over WebDAV, so the mount shows only the org-wide Document Hub. The `.trash/` namespace lists soft-deleted documents read-only — download for recovery, restore through the UI. Editors that take WebDAV locks (Office, LibreOffice) get them; a competing write during an edit returns `423 Locked`. ## Revoking Revoke a password with the trash icon on its row — the next request with it is rejected, other devices are untouched, and any locks it held are released. There is no undo; mint a new password if you revoke the wrong row. <Warning> Basic auth sends the app-password on every request. Mount only over HTTPS, keep the password in the OS keychain, and never paste it into a `https://user:pass@host/` URL — shell history and proxy logs outlive the mount. Revoke immediately on any suspected leak. </Warning> ## Where this fits WebDAV is the per-user, device-facing door to the same data as the [Document Hub](/platform/knowledge/documents); the wire protocol lives under [WebDAV API](/develop/webdav-api). For machine-to-machine imports, [API keys](/platform/admin/api-keys) plus the REST API are usually the better fit. # Developer Source: https://tale.dev/docs/platform/developer/overview Developer is the in-app surface for the people who wire Tale to the rest of their stack. It groups the four levers that let external code talk to Tale and Tale talk to external code: API keys for the REST surface, custom tools that extend an agent's reach, agent webhooks for inbound triggers, and MCP servers for the external-process bridge. People with the Developer role see this menu; Members and Editors do not. This overview names what each page covers and points to the deeper reference. Developer-role users typically land here on their first day, set up the credentials and tools they need, and come back when they extend the stack — adding a new MCP server, rotating a key, registering a new webhook. ## What Developer covers The Developer surface sits beside the rest of the org's settings but with a narrower audience. It assumes you know what a REST API is, what a webhook looks like, and what an MCP server does — the pages do not re-explain the underlying concepts; they explain how Tale exposes them. The same surface in the Cloud and self-hosted tabs differs only in deployment shape; the UI here is identical. The configuration-file equivalents of some of these features (env vars, JSON configs for custom tools) live one tab over in the self-hosted documentation. ## Pages in this section <CardGroup cols="2"> <Card title="API keys" icon="key" href="/platform/admin/api-keys"> Wire a script, a cron job, or an internal service to Tale's REST API. Shared with Admin under Settings > API keys. </Card> <Card title="MCP servers" icon="server" href="/platform/connectors/mcp-servers"> Register an external MCP-protocol process and pick which of its tools the org's agents may call. </Card> <Card title="Agent tools" icon="wrench" href="/platform/agents/tools"> Extend an agent's toolbelt with a custom tool the org's agents can call. </Card> </CardGroup> ## Where this fits Developer is the bridge between Tale and the rest of the codebase the org runs. The natural first read depends on what you came to wire — for outbound (something inside Tale calls outside) [Agent tools](/platform/agents/tools) and [MCP servers](/platform/connectors/mcp-servers); for inbound (something outside calls into Tale) [API keys](/platform/admin/api-keys). # Editor Source: https://tale.dev/docs/platform/editor/overview Editor is the build surface of Tale. Where Member is the role that runs the product and Admin is the role that governs it, Editor is the role that creates the things everyone else uses — agents, projects, automations, the documents and structured data the knowledge base holds, the prompts saved for the team. People with the Editor role see the full set of build tabs without the admin governance surface and without the developer-only levers. This overview names what an Editor does, where they do it, and which pages cover each piece. Editors typically land here on their first day, build out the org's first useful agent and project, and come back to this tab whenever the next thing needs to be built. The role-and-permission story behind the tabs lives on [Members and roles](/platform/admin/members-and-roles). ## What Editor covers The work an Editor does falls into four buckets: building **agents** (instructions, knowledge bindings, tools, models), curating the **knowledge base** (uploading documents, maintaining contacts, products, vendors, websites), authoring **automations** (workflows with triggers, steps, and approval gates), and bundling **projects** (file sets, scoped agents, project instructions). Each bucket has its own section in Platform; the Editor tab is the index across them. Editors share the build surface with Developers — Developers also see all four buckets and can do everything an Editor can, plus the API and connector plane. Reach for an Editor when the day-to-day work is content and configuration; reach for a Developer when the work crosses into code or external systems. ## Pages in this section The Editor surface is the same surface the per-area sections of Platform document. What follows is the index across them. <CardGroup cols="2"> <Card title="Agents" icon="bot" href="/platform/agents/concepts"> The four-knob mental model an Editor builds every agent from. </Card> <Card title="Automations" icon="workflow" href="/platform/automations/concepts"> Workflows, triggers, steps, executions. </Card> <Card title="Knowledge" icon="library" href="/platform/knowledge/overview"> The documents and structured-data area an Editor curates. </Card> <Card title="Projects" icon="folder-open" href="/platform/projects/overview"> The shared workspace an Editor bundles around a contact or a launch. </Card> <Card title="Skill library" icon="list-plus" href="/platform/workspace/skills"> The bundle library an Editor uses to keep a recurring instruction reusable across chats and agents. </Card> </CardGroup> ## Where this fits Editor is the role most teams have several of — the people who do the build work other roles consume. The natural first read on day one is [Agent concepts](/platform/agents/concepts), because the four-knob model is what every other build page assumes. The natural second is [Build your first agent](/tutorials/editor/first-agent-end-to-end) — it walks the four knobs end to end on a fresh instance. # Platform Source: https://tale.dev/docs/platform Platform is the canonical product reference: every user-visible feature in Tale, identical for Cloud and self-hosted. The pages here describe the UI someone clicks, the concept behind the UI, and the trade-offs between features that look similar. The section is organised by area, then by feature within an area. Most readers do not read it front to back — they land here from a search result or a link from a tutorial, and the page they landed on should answer the question they brought. ## Feature areas <CardGroup cols="2"> <Card title="Chat" icon="message-circle" href="/platform/chat/overview"> The everyday entry point — threads, agents in chat, attachments, arena mode, voice mode, the Canvas pane, sharing. </Card> <Card title="Projects" icon="folder-open" href="/platform/projects/overview"> Shared workspaces that bundle files, instructions, threads, and project-scoped agents. </Card> <Card title="Agents" icon="bot" href="/platform/agents/concepts"> Instructions, knowledge, tools, model — plus skills, workers, versioning, and webhook triggers. </Card> <Card title="Automations" icon="layout-grid" href="/platform/automations/concepts"> Installable bundles of connectors, agents, skills, and a workflow — the catalog, the install wizard, the editor and triggers behind each one, and the run history it leaves. </Card> <Card title="Knowledge" icon="library" href="/platform/knowledge/overview"> Documents, contacts, products, vendors, websites — the structured-data model agents cite. </Card> <Card title="Approvals" icon="check-check" href="/platform/approvals/concepts"> Inline cards, workflow gates, and the approver pool that keeps humans in the loop. </Card> <Card title="Skill library" icon="list-plus" href="/platform/workspace/skills"> Reusable instruction bundles you keep private or share with the whole organisation. </Card> <Card title="Models" icon="cpu" href="/platform/models"> The model catalog behind every picker — capability tags, defaults, and the shipped list. </Card> <Card title="Connectors" icon="plug" href="/platform/connectors/overview"> Third-party SaaS pairings and MCP servers. </Card> </CardGroup> ## Set up your first day Four role-indexed entries map the same features from the reader's side of the desk — what a Member, an Editor, a Developer, or an Admin actually touches on day one. <CardGroup cols="2"> <Card title="Member" icon="user" href="/platform/member/overview"> Chat, knowledge, personal preferences — the surface most people in most orgs use. </Card> <Card title="Editor" icon="pencil-ruler" href="/platform/editor/overview"> The build surface — agents, knowledge curation, automations, projects. </Card> <Card title="Developer" icon="terminal" href="/platform/developer/overview"> API keys, custom tools, webhooks, MCP servers — wiring Tale to external code. </Card> <Card title="Admin" icon="shield" href="/platform/admin/overview"> Organization settings, providers, branding, connectors, and the governance sub-tree. </Card> </CardGroup> ## Where this fits Platform is the gravity well — Cloud and self-hosted both link into it for feature documentation, and every tutorial cites pages here for the underlying concepts. The page worth bookmarking on your first day is [Agents → concepts](/platform/agents/concepts) — almost every other product page assumes the four-knob mental model that page builds. # Crawling Source: https://tale.dev/docs/platform/knowledge/crawling A Website is the knowledge base's shape for "a public site the agent should know about". You hand Tale a domain and a scan interval; the crawler discovers URLs, fetches pages, extracts the main content, chunks and embeds the text, and serves the chunks back at reply time the same way it does for Documents. When you need specific pages rather than a whole site, hand it a URL list instead — the same pipeline runs on exactly the pages you name. This page walks what you see between adding a domain and agents citing its pages. <Frame caption="Adding a website — in Whole website mode, domain plus scan interval is the whole form."> ![The Add website dialog on the Websites tab, asking for a domain and a scan interval that defaults to every six hours.](/images/platform/websites-add-dialog.webp) </Frame> ## Adding a website Open **Knowledge > Websites** and click **Add website**. **Source type** decides what the source covers: **Whole website** — the default — crawls everything it can discover on the domain, **URL list** indexes exactly the pages you paste (the next section). In Whole website mode the dialog has two fields: **Domain** (for example `example.com`) and **Scan interval** — every 1 hour, 6 hours (the default), 12 hours, 1 day, 5 days, 7 days, or 30 days. Tale normalises the domain — `https://`, `www.`, and trailing slashes are tolerated — and rejects anything that does not parse as a hostname. Click **Save**; the scheduler picks new websites up on its next tick, so the first scan starts within seconds. <Note> There is no auth field and no include/exclude path list — the crawler sees exactly what an anonymous visitor sees. Anything behind a login belongs in [Documents](/platform/knowledge/documents) or an [connector](/platform/connectors/overview) instead. </Note> ## Adding a URL list Switch **Source type** to **URL list** when you want specific pages, not a whole site — a report here, a pricing page there, a handful of PDFs. Paste one URL per line into **URLs**; only those pages are fetched and indexed, and the crawler follows no links beyond them. The lines may span several websites: the dialog groups them into one source per website, so a paste covering three domains creates three rows. Pasting another list for a website that already has one adds the new URLs to the existing source — nothing is dropped, and the scan interval moves to whatever you picked. Lists re-scan on the same cadence as whole websites; their rows carry a **URL list** badge in the table. ## How URLs are discovered The crawler tries the cooperative path first. It resolves the homepage and walks every sitemap the site publishes — `sitemap.xml`, sitemap indexes, gzipped and robots-declared sitemaps — collecting the URL list the site itself maintains. Sites with a healthy sitemap get complete coverage with no guessing. When the sitemap is missing, broken, or empty, the crawler falls back to a breadth-first link walk from the homepage: in-domain links only, external and social links dropped, navigation and footer chrome stripped before extraction. The fallback covers sitemap-less sites, but it cannot match a well-maintained sitemap for completeness. Pages are not the only content that counts. Linked documents — PDF and Office files (`docx`, `xlsx`, `pptx`, `odt`) — are fetched and indexed like pages, whether the crawler finds them linked on a website or you list them directly in a URL list. Images and scanned documents without embedded text are skipped: the scan remembers it looked and stores nothing. ## The scan schedule The interval decides how often URLs are re-discovered and pages re-fetched. Each scan is incremental: unchanged pages are skipped, changed pages are re-extracted and re-embedded, new pages are added, removed pages are dropped from the index. URL lists follow the same cadence with a fixed set — the listed pages are re-fetched on schedule, nothing new is discovered. Agents pointed at the website see the new content on the next retrieval — there is no separate publish step. ## Reading the table Each row shows the domain (URL-list sources carry a **URL list** badge beside it), its **Status** — **Idle** between scans, **Scanning** in flight, **Active** after a successful scan, **Error** when the last scan failed, **Deleting** during removal — the **Indexed** percentage (hover for crawled-of-total page counts), the last **Scanned** time, and the **Interval**. Open a row for the site's discovered title and description; click **View pages** for the page list — every indexed URL with its word count, chunk count, and last-crawled time, plus a search box that runs over the indexed chunks, which is the quickest way to check what an agent would actually retrieve. ## Where this fits Crawling is the cheap way to bring a public site into agent context: a domain — or a hand-picked URL list — a cadence, and the rest is the crawler's problem. The trade-off is the anonymous-visitor boundary — private content needs [Documents](/platform/knowledge/documents) or an connector. For how the Website rows sit beside Contacts, Products, and Vendors, read [Structured data](/platform/knowledge/structured-data). # Documents Source: https://tale.dev/docs/platform/knowledge/documents The Documents tab is the knowledge base's file surface. Editors upload files, Tale runs each one through the indexing pipeline — extract the text, chunk it, embed the chunks, store them — and agents whose knowledge scope covers the document retrieve relevant passages at reply time and cite them. This page covers the operator side: uploading, the status column, team scoping, folders, and the document lifecycle. <Frame caption="The Documents table — size, source, RAG status, and team scope per file."> ![The Knowledge area's Documents tab listing three uploaded text files with size, source, RAG status, and team columns.](/images/get-started/documents-list.webp) </Frame> ## Uploading Open **Knowledge > Documents** and click **Upload documents** — the menu offers **From your device** and **From Microsoft 365**. The upload gate accepts the formats that cover the bulk of org knowledge: PDF, Word (`.doc`, `.docx`), OpenDocument text (`.odt`), PowerPoint (`.ppt`, `.pptx`), Excel (`.xls`, `.xlsx`), CSV, plain text, and images (JPG, PNG, GIF, WEBP). Anything else is refused at upload. Uploading and indexing are separate facts, and the **RAG status** column tracks the second one: **Indexing** while the pipeline runs, **Indexed** when agents can retrieve the content, **Failed** when the pipeline errored, and **Needs reindex** when the stored chunks are stale. Modern formats index; the legacy Office trio (`.doc`, `.xls`, `.ppt`) uploads and stays downloadable but shows **Not indexed** — agents cannot retrieve its content until you re-save it in the modern format. ## Revising a controlled document Use a controlled document when approval must stay tied to the exact file that a reviewer saw. Replacing its draft updates the existing record; uploading another file with the same name still creates a separate document. <Steps> <Step title="Choose the controlled record"> For a regular upload, open the row menu and click **Mark as controlled**. It becomes `v1 · Draft`. An approved record offers both **Replace file** and **New revision**: use **New revision** only when you need the next draft without replacing its file. </Step> <Step title="Replace the current file"> Open the draft or approved record's row menu and click **Replace file**, then choose one file in the same format. A draft keeps its current revision. For an approved record, the dialog preserves approved vN and opens draft vN+1 only after the replacement succeeds; cancelling or a failed upload leaves vN approved. A legal hold blocks either path. <Frame caption="The replacement dialog accepts one file in the record's existing format."> ![The Replace file dialog for a controlled text document, with a same-format file picker and a note that approved versions remain in history.](/images/platform/controlled-document-replace-file.webp) </Frame> </Step> <Step title="Check and submit the revision"> Open the document preview and confirm that it shows the replacement. Then open the row menu and click **Submit for review**. The picker offers only members who can actually open the document — a project file needs project edit access. The draft freezes while the reviewer decides on that exact file; the reviewer is notified in the bell and by email, and the decision comes back to you the same way — a request for changes carries the reviewer's feedback, which the submit dialog also shows before your next attempt. </Step> </Steps> ## Importing from Microsoft 365 **From Microsoft 365** imports from OneDrive or SharePoint instead of disk: pick files or folders, then choose the import mode. **One-time import** brings the files in once — they behave like uploads from disk. **Sync import** keeps the selection synchronized: new files in the OneDrive folder appear on a later sync pass, changed files re-index, and files deleted at the source leave the workspace. Both modes preserve the folder structure of your selection. Sync covers personal OneDrive folders — a SharePoint selection always imports once. To stop syncing — a whole synced folder or a single synced file — open the row's menu and click **Stop syncing**; the imported documents stay in the workspace and stop updating. Deleting a synced folder or file also stops its sync. In every case the originals in OneDrive are untouched. ## Scoping, folders, sources Each row carries a **Teams** cell — **Organization-wide** by default, or the teams you pick via **Assign team** in the row menu. A team-scoped document is invisible to members and agents outside the team; this is the knowledge base's access lever. Project files are outside this model entirely: a project's **Knowledge** tab holds files scoped to that one project, and they never appear in this library or in its team scoping — see [Manage files](/platform/projects/manage-files). **New folder** keeps large libraries navigable, and connectors bring their own structure: documents synced from OneDrive or SharePoint land under sync folders and show their origin in the **Source** column, which keeps citations traceable to the upstream system. <Warning> Deleting a folder permanently deletes every file and subfolder inside it. Deleting a OneDrive sync folder also removes its auto-sync configuration and history — though never the files in OneDrive itself. </Warning> ## Reindex and delete **Reindex** (row menu) re-runs the pipeline on the stored file — the right move after an indexing failure or when a document shows **Needs reindex**. **Delete** removes the document and its indexed chunks; the confirmation says it plainly — the action cannot be undone. Re-uploading the same file brings the content back as a fresh document. A controlled record stops being deletable the moment any of its versions is approved — in review, approved, or drafting the next revision, the menu entry reads **Protected controlled record** instead, and a folder holding such a record refuses folder deletion the same way. The approved snapshot is a retained record; that is the point of the lifecycle. Each document shows a status: **Queued** (waiting its turn — a busy organization indexes a few files at a time and the rest queue), **Indexing**, **Indexed**, **Failed**, or **Unsupported** (a legacy format such as `.doc`/`.ppt`/`.xls` that stores and downloads fine but has no text extractor, so it is never indexed for search). An indexing job interrupted by a timeout or a backend restart recovers on its own within a few minutes — it is retried or marked **Failed** with a retry option, never left stuck. If your organization enforces a per-user storage quota, failed and unsupported files still count against it until deleted, so freeing space means removing files you no longer need. Clicking a document opens the preview, with a sidebar showing size, source, RAG status, teams, uploader, and modification date — the fastest way to check what a citation actually points at. ## Documents versus structured data Documents are the unstructured half of the knowledge base. When the content is a list of things with the same fields — contacts, products, suppliers — a typed record serves agents better than a spreadsheet upload: exact values instead of retrieved passages. The decision rules live in [Structured data](/platform/knowledge/structured-data). ## Where this fits Documents are the most-used corner of the knowledge base — most citations in most replies point here. The retrieval side — how an agent's knowledge scope decides what it searches — is [Agent knowledge](/platform/agents/knowledge); the fact-sized sibling surface is [Knowledge entries](/platform/knowledge/knowledge-entries), which rides this same pipeline one document at a time. # Knowledge entries Source: https://tale.dev/docs/platform/knowledge/knowledge-entries Knowledge entries are the knowledge base's fact surface. Where a document carries a whole file, an entry carries one small, durable fact — "the store opens at 9", "the return window is 3 days" — keyed by a topic name. Entries ride the same indexing pipeline as documents, so every agent whose scope covers them retrieves and cites them like any other source; what makes them special is how they get in and how corrections replace what they correct. <Frame caption="The Knowledge entries tab — topic, content, source, and indexing status per fact."> ![The Knowledge entries tab listing three manually added facts, each showing a Manual source tag and an Indexed status badge.](/images/platform/knowledge-entries-list.webp) </Frame> ## Where entries come from **From chat, with your approval.** Agents with the knowledge-write tool enabled can propose saving a fact you stated or corrected during a chat. The proposal appears as a card in the chat — **Save to knowledge base**, with the topic and the full content; when the topic already exists the card becomes **Update knowledge base** and warns that approving will replace the existing entry. Nothing lands until you click **Approve**; **Reject** discards it. <Note> The tool is off by default — enable it per agent in the agent's tool settings. An agent can never write into the org's shared knowledge without a human signing off on the exact text. </Note> **Manually.** Click **Add entry** on **Knowledge > Knowledge entries**. Give it a **Topic** (up to 120 characters — short and stable, like a heading) and the **Content** as markdown (up to 8000 characters), written so it makes sense without any surrounding conversation. The **Source** column keeps the two origins apart: **Chat** or **Manual**. ## One live version per topic Topics are the dedup key: an approved chat proposal for an existing topic, or an edit, replaces the live version rather than adding a second one — the knowledge base never serves two versions of the same fact. Adding a new entry under an existing topic is refused with a duplicate-topic error; edit the existing entry instead. Replaced versions are not lost. Open an entry to see its details — indexing status, last update, and the **Version history** with every superseded version and when it was replaced. Only the live version is indexed for retrieval; the history exists for audit and reference. ## Editing, indexing, deleting Editing creates a new live version and re-indexes in the background — the **Status** badge dips to indexing and returns to **Indexed** when search picks up the new text. Deleting removes the whole entry: the confirmation warns that it also disappears from the knowledge base, so agents can no longer find it, and that the action cannot be undone. If the fact was right, add it again. ## Where this fits Knowledge entries close the loop between conversations and the knowledge base: a correction made once in chat becomes a fact every agent retrieves, with a human approving the exact wording and one live version per topic guaranteeing the old fact disappears when the new one lands. For the file-shaped half read [Documents](/platform/knowledge/documents); for how agents bind and retrieve, read [Agent knowledge](/platform/agents/knowledge). # Knowledge Source: https://tale.dev/docs/platform/knowledge/overview Knowledge is the area where the org's data lives so agents can read and cite it. Editors curate it once; agents retrieve over it at reply time, which is why an agent in Tale can answer with your reality instead of the model's training data. The area opens on six tabs: **Documents**, **Knowledge entries**, **Websites**, **Products**, **Contacts**, and **Vendors**. Prefer to watch first? Episode 3 walks the whole library in three minutes — indexing, entries, records, the crawler, and scopes, captions included. <Video src="/videos/en/tutorials/ep3-knowledge/ep3-knowledge.en.mp4" poster="/videos/en/tutorials/ep3-knowledge/ep3-knowledge.en.webp" captions="/videos/en/tutorials/ep3-knowledge/ep3-knowledge.en.vtt" lang="en" title="Episode 3 — Knowledge" caption="Episode 3 — Knowledge (3:03)"> </Video> <Frame caption="The Documents tab — the most-used corner of the knowledge base."> ![The Knowledge area's Documents tab listing three uploaded text files with size, source, RAG status, and team columns.](/images/get-started/documents-list.webp) </Frame> ## The two shapes Everything in the area is one of two shapes. **Indexed content** — the files in Documents, the facts in Knowledge entries, the pages a website crawl brings in — runs through the indexing pipeline (extract, chunk, embed, store) so agents retrieve relevant passages and cite them. **Typed records** — Products, Contacts, Vendors — are rows with named fields that agents read as data, not prose: exact values, no retrieval guesswork. The shape you pick decides how an agent can use the content, which is why [Structured data](/platform/knowledge/structured-data) is a decision page, not just a reference. ## Where the index lives Indexed content is embedded into Tale's built-in vector database — a **PostgreSQL** store (ParadeDB) that combines `pgvector` embeddings with keyword (BM25) search and fuses the two, so retrieval catches both semantic matches and exact terms. It ships with the platform, so there's nothing extra to license or operate, and retrieval, citations, per-team permissions, and GDPR erasure all act on one store. Embeddings come from the org's configured **embedding model** — an org admin picks the provider, model, and vector width in **Settings > Data residency**, and knowledge search refuses with an actionable error until one is configured, rather than guessing a model. **Bring your own vector database — it's Postgres.** Because the vector store is PostgreSQL, you can point Tale's knowledge database at any managed PostgreSQL you run (with the `pgvector` and `pg_search`/ParadeDB extensions) instead of the bundled one — your data, your infrastructure, your region. An org admin sets the connection in **Settings > Data residency** — enter the host, database, and credentials for your Postgres, the same way on a self-hosted deployment and on a dedicated cloud instance. Tale verifies the connection and that the required extensions are present before you cut over. See [Data residency](/self-hosted/configuration/data-residency) for the connection details and the extension prerequisites. ## How agents reach in An agent does not see the whole library by default. The agent's **Knowledge** tab controls its retrieval scope — which parts of the library it searches at reply time — and team-scoped items stay invisible to agents and members outside the team. Retrieval is driven by the agent's RAG-tagged tools, and every retrieved passage carries its source, so citations point back at the file, entry, or page it came from. The agent-side mechanics live in [Agent knowledge](/platform/agents/knowledge). ## Pages in this section <CardGroup cols="2"> <Card title="Documents" icon="file-text" href="/platform/knowledge/documents"> Uploading files, the indexing pipeline, supported formats, and the per-document lifecycle. </Card> <Card title="Knowledge entries" icon="book-open" href="/platform/knowledge/knowledge-entries"> Small, topic-keyed facts — captured from chat with approval or added by hand. </Card> <Card title="Crawling" icon="globe" href="/platform/knowledge/crawling"> Turning a public website into knowledge — domain, scan interval, and the indexed-pages view. </Card> <Card title="Structured data" icon="table" href="/platform/knowledge/structured-data"> Contacts, Products, Vendors, Websites — when a typed record beats a document. </Card> </CardGroup> ## Where this fits Knowledge is the data layer every grounded reply stands on; without it, agents only know what the model already knows. Bring content in through the tab that matches its shape, then wire agents to it — the natural next read is [Documents](/platform/knowledge/documents) for files, [Structured data](/platform/knowledge/structured-data) for records, and [Agent knowledge](/platform/agents/knowledge) for the retrieval side. # Structured data Source: https://tale.dev/docs/platform/knowledge/structured-data Tale's knowledge base ships two shapes side by side. Documents are text the agent retrieves chunks from; structured records are typed rows the agent reads fields from. The shape you pick is the most important decision in how an agent will use your knowledge — get it wrong and the agent either dilutes a clear answer or guesses at a value you have on file. This page hands you the mental model for when each shape is the right one. Read it before you load a folder of files; come back to it when you are tempted to upload a spreadsheet as a PDF. ## Documents versus structured records A document is free-form: the indexing pipeline extracts text, chunks it, embeds the chunks, and serves passages via retrieval at reply time. The agent sees passages and cites them by source. This is the right shape when the content is prose — contracts, manuals, knowledge-base articles, meeting notes. A structured record is typed: the entity has known fields (a contact has a name, an email, an industry; a product has a SKU, a price, stock). The agent reads the fields directly, joins across entities, and answers with the value. This is the right shape when the source is a database row — accounts, orders, parts, supplier records. ## The four built-in entities Four structured tabs sit beside **Documents** and **Knowledge entries** in the Knowledge area: - **Contacts** — the people and organisations you do business with. - **Products** — the things you sell. - **Vendors** — the suppliers you buy from. - **Websites** — public sites a crawler fetches on a schedule; the record holds the domain and scan settings, the indexed pages hold the content ([Crawling](/platform/knowledge/crawling)). Structured records share the knowledge base's team-scoping levers: a team-scoped record is invisible outside the team the same way a team-scoped document is. ## Content models for custom shapes When the four built-ins do not fit, content models let you define a custom structured record type: name the entity, declare its fields, set field-level access, and the new type appears alongside the built-ins. The definitions live under [governance content models](/platform/admin/governance/content-models). <Note> Content models cost governance attention — every field's access and retention policy is yours to set. Reach for them when the data is genuinely a new shape, not a slight variation on one of the four built-ins. </Note> ## Putting it together — a CRM agent A CRM agent that answers "where are we with Acme?" uses both shapes. The Contacts entity holds the canonical record — name, primary contact, industry, status. Documents hold the call notes and contracts. The agent reads the contact's fields directly, retrieves passages from the documents, and answers with both: the structured status from Contacts, the latest context from the most recent call note. Without structured records, the agent has to find Acme by name across PDFs and risks confusing two contacts with similar names. Without documents, the agent knows Acme's status but cannot tell you what happened on Tuesday's call. ## When to reach for it | Use … when | Documents | Structured record | | ---------------------------------------------------------- | --------- | ----------------- | | The source is free prose | ✓ | | | The source has typed fields and you want exact values back | | ✓ | | You need to join across many records | | ✓ | | The agent should cite passages by location | ✓ | | ## Where this fits Structured data is the seam between your operational data and the agent surface. Use the four built-ins for what they cover; reach for [content models](/platform/admin/governance/content-models) when a fifth shape appears. The next read worth queuing is [Documents](/platform/knowledge/documents) — the indexing pipeline that serves the unstructured half. # Environment variables & secrets Source: https://tale.dev/docs/platform/member/environment Environment variables & secrets is your personal store of variables that Tale injects into every sandbox you run in this organisation. When a [project agent or automation agent node](/platform/agents/harnesses) starts a harness turn, each entry you have saved here is set in the environment before the agent runs, so a command the agent issues — or the agent itself — can read it. Reach for it when the work needs something of yours that nobody else should hold: a personal API token for a service the organization has not connected, an endpoint that differs for you, a key tied to your own account. It is a member-level page every role can open, and the entries are scoped to you and to the current organisation, so they never leak to teammates and never follow you into another org. This page covers the two kinds of entry, how secrets are protected, the rules a name and value have to satisfy, and where the values end up. <Frame caption="Settings > Environment — the saved entries, each with the Secret switch that decides whether its value can be read back."> ![The Environment settings page listing three saved entries — ANALYTICS_ORG and CRM_BASE_URL with their values in plain sight, and CRM_API_TOKEN masked as dots with its Secret box ticked — above an Add variable action.](/images/platform/settings-environment.webp) </Frame> ## Variables and secrets Open **Settings > Environment**. **Add variable** opens a dialog for a new entry, with the list of what you have saved below. Each entry is a **Name** and a **Value**, plus a **Secret** switch that decides how the value is stored and shown. A plain variable is stored as-is and shown back in full in the list — use it for non-sensitive configuration the agent expects, a region name or an endpoint. A **secret** is encrypted the moment you save it and is write-only from then on: the list shows `••••••••` in place of the value, and there is no way to read it back. Turn the switch on for anything sensitive — an API key, an OAuth token, a password. The trade-off is that you cannot review a secret's value later, so if you are unsure it is right, delete it and add it again rather than hunting for a reveal button that does not exist. Each row carries the name, the value or its mask, and when it was last updated. The trash icon asks for confirmation before it removes the entry, because deleting one takes it out of every sandbox of yours on the next run. ## Names, values, and limits A **name** must start with a letter or underscore and contain only letters, numbers, and underscores — the shape of an ordinary environment variable, `MY_API_KEY` rather than `my-api.key`. Names are capped at 128 characters and values at 8,192, which is room for a long token or a multi-line key but not a file. You can keep up to 100 entries. Tale trims spaces from the start and end of a value when you save it, because a stray newline from a copy-paste is the most common reason a token silently fails. It does not trim spaces or line breaks _inside_ the value, but it warns you when it finds them: a credential normally has none, so interior whitespace usually means a token wrapped across lines in your terminal when you pasted it. The warning does not block the save — a genuinely multi-line secret such as a PEM private key keeps its line breaks — so read it and decide. ## How the values reach the sandbox A secret never travels in the clear except into your own sandbox. At rest it is encrypted in Tale's backend under a key the platform holds, and the list query returns only the mask, never the plaintext. When a turn starts, the platform decrypts your secrets and sets them, alongside your plain variables, in the environment of your sandbox for that run. Whenever a secret is injected for a turn, that access is recorded in the audit log. That last step is the boundary worth understanding: the values land inside your sandbox container, so the isolation of the sandbox — not the secret store — is what stands between your credentials and anything else that runs there. This matches how the in-sandbox GitHub token works, and it is why these entries are scoped to you alone rather than shared with the org. What does not come from here is the credential a turn uses to reach its model. That belongs to the organization's provider records under [Providers](/platform/admin/providers), where it can be rotated and audited in one place — an agent holds no keys of its own, and neither does this page on its behalf. Keep these entries for the things your own work needs and let the model credential stay where the organization can govern it. ## Where this fits Environment variables & secrets is the one member-level page that reaches into the sandbox rather than the chat — it is how your own keys and configuration get to the work you run, without an Editor or Admin setting them for you. Read it alongside [Harnesses](/platform/agents/harnesses), which covers what else the container holds and what it is allowed to reach. For the rest of your personal settings — display name, password, custom instructions — see [Preferences](/platform/member/preferences). # Install as app Source: https://tale.dev/docs/platform/member/install-as-app Tale ships as a Progressive Web App. Installing it puts an icon on your dock or home screen, runs Tale in its own window without browser chrome, and keeps the same session you had in the browser. There is no separate native build to download and no extension to install — the same URL you sign in with is the same app, in a standalone shell. This page covers the three places you trigger the install: the **Get app** row in your profile menu on Chromium browsers, the share-sheet step on iOS Safari, and the install banner Android Chrome surfaces on its own. Once installed, Tale behaves identically; the install only changes the chrome around it. ## The profile-menu shortcut On Chrome, Edge, Brave, Arc, and the other Chromium browsers, Tale's profile dropdown carries a **Get app** row when the browser is willing to install. Open the menu from your avatar in the top-right, scroll past the theme switcher and the language switcher, and click **Get app**. The browser opens its native install confirmation; accept it, and Tale lands in your dock (macOS), your taskbar (Windows), or your apps list (ChromeOS) within a second or two. The row is only there when the browser fired its `beforeinstallprompt` event and the app is not already installed. Browsers that do not fire that event — Firefox, Safari, anything in a private window — do not show the row, so the menu stays one item shorter rather than asking for something it cannot deliver. ## iOS and iPadOS iOS Safari does not fire `beforeinstallprompt`, so the **Get app** row does not appear in the menu. The install path lives in Safari's share sheet instead. Open Tale in Safari, tap the share icon in the toolbar, scroll down to **Add to Home Screen**, and confirm. Tale appears on your home screen with the same icon as the browser favicon. Tap it, and Tale opens in its own window — no Safari address bar, no tab strip, no back button beyond what Tale itself surfaces. Notifications work the same way they do in the browser tab; the install is the only difference. Other iOS browsers — Chrome, Edge, Firefox on iOS — are Safari under the hood. They do not have an Add-to-Home-Screen entry of their own. The Safari path is the only iOS install path that produces a real standalone app. ## Android Android Chrome handles installation in two places. The first is the same **Get app** row in Tale's profile menu, identical to the desktop flow. The second is Chrome's own install banner — a one-line bar that slides up from the bottom of the page on sites it considers installable. Tap **Install** on the banner, confirm in the system sheet, and Tale lands on your home screen. If you dismissed the banner once, it usually does not come back for a while. The profile-menu shortcut keeps working whether or not the banner has been shown. Other Android browsers — Firefox, Samsung Internet, Brave — each have their own install path under their browser menu, typically labelled **Install app** or **Add to Home Screen**. ## After installing Tale running in a PWA window is the same Tale running in a browser tab. The session, the chats, the knowledge base, the agents — all of it is the same surface. The differences are cosmetic and small: no browser chrome around the app window, an icon in your launcher, and on most platforms the window remembers its size and position between launches. Uninstalling follows the platform convention. On macOS, drag the icon out of the dock; on Windows, right-click and uninstall; on iOS and Android, long-press the icon and remove. Uninstalling clears the PWA shell but not the session — sign back in through the browser, and your data is where you left it. ## When to reach for it The install is worth it once you find yourself opening Tale every day and want it to feel like one of your apps rather than one of your tabs. It is also the right move when you want the chat window pinned to a virtual desktop or a stage-manager slot that browser tabs would not respect. Skip the install if you sign in from many machines and prefer the browser tab — Tale works the same way either way. The neighbouring read is [Member overview](/platform/member/overview) — it is the map of what the rest of the Member surface covers once Tale is sitting in your dock. # Member Source: https://tale.dev/docs/platform/member/overview Member is the default role most people in most orgs carry. It is the end-user surface of Tale — chat with agents, browse the knowledge base, reply to contact email in an installed automation's Inbox, act on the approvals others have routed to you, and leave feedback on replies. Members do not build agents, do not configure providers, do not install automations. They use the product the Editors and Developers built for them. This overview names what a Member can do and points at the per-feature pages. Members typically land on Chat first; the rest of this page is what to read once chat alone is not enough — when you want to know where a citation came from, what an approval card is, or what a project bundles. ## What Member covers The Member surface is intentionally narrow. The four buckets are: - **Chat** — pick an agent (or none), send a message, read the reply. The chat surfaces the skill library, attachments, voice mode, arena mode for side-by-side comparison, and the Canvas pane when a reply produces more than the chat can hold inline. - **Knowledge** — browse documents, contacts, products, vendors, websites the org has loaded. Read-only for Members; the curating happens on the Editor side. - **Inbox** — reply in the **Inbox** tab an installed email automation adds. Members answer when an agent hands a conversation back; installing the automation itself is an admin action. - **Approvals** — read the approval cards routed to you. Click Approve, Reject, or Request changes; leave a comment if the rule asks for one. The org configuration settings — providers, connectors, agents, governance — are hidden for Members; the work surface is the bulk of what is left. The exception is a small personal settings group every role carries: Account, Personalization, and [Environment variables & secrets](/platform/member/environment), the keys and variables injected into the sandboxes you run. ## Pages in this section This section is short — the Member surface is the cross-section of pages that Editors build for and that everyone uses. The deeper reading lives in the per-feature areas. <CardGroup cols="2"> <Card title="Chat" icon="message-circle" href="/platform/chat/overview"> The everyday entry point — chat, agents, attachments, citations. </Card> <Card title="Knowledge" icon="library" href="/platform/knowledge/overview"> The read-only window into what the org has loaded. </Card> <Card title="Built-in automations" icon="inbox" href="/platform/automations/builtin"> The email automations that add an Inbox tab — and what each one does. </Card> <Card title="Approvals" icon="check-check" href="/platform/approvals/concepts"> What an approval card is and what each button does. </Card> </CardGroup> ## Where this fits Member is the role that consumes what the Editor builds and the Admin governs. The natural first read is [Chat](/platform/chat/overview) — it is where every Member spends most of their time, and most of the other Member surfaces fan out from a chat that wanted to do something more. # Preferences Source: https://tale.dev/docs/platform/member/preferences Preferences are the dials that belong to you rather than to the org. Your name is what agents and teammates see in chats and approvals. Your locale and theme follow you between devices. Your memories are facts an agent has proposed about you and you have approved, kept separately from anything an Admin or Editor has set at the org level. This page maps where each lever lives and what it changes. The shape is intentionally two-layered: the profile menu (everywhere, one click from the avatar) carries the quick toggles; **Settings > Account** and **Settings > Preferences** carry the deeper account fields. Everything here is yours — none of it leaks to other members or other orgs. ## The profile menu Click your avatar in the top-right. The dropdown opens with your name, your email, and the current build version. Below the header sit four quick controls every member sees regardless of role: the **theme** switcher (System / Light / Dark), the **language** sub-menu (English, Deutsch, Français), the **Get app** row when the browser can install Tale as a PWA, and **Log out**. Theme and language take effect immediately and persist per-device. The menu also carries an organisation switcher when you belong to more than one org and a team filter when your current org has teams. Those are not preferences — they change what Tale shows you, not how Tale behaves. Below the team filter, **User settings** opens **Settings > Account**, the page covered next. ## Account — name, email, password, two-factor Open **Settings > Account**. Three sections sit on the page: **Profile**, **Security**, and **Two-factor authentication**. The Profile section shows your **email** first, then your **name** — the email implies the name Tale suggests, which you can edit freely. The name is editable inline; the change saves and propagates to every chat and approval the next time they render. Email is read-only — it is what you signed in with, and changing it goes through support. There is no avatar field on the page; Tale derives an avatar from your name's initials. The Security section holds a single button: **Change password** if you signed up with email and password, **Set password** if your account is federated through SSO and you want to add a password as a fallback. Both flows enforce the org's password policy and surface the rules live as you type, and a wrong current password is flagged inline on the field rather than as a transient error. Changing your password signs you out of every device — the dialog warns you before you confirm, and you'll sign back in with the new password. The Two-factor section pairs the account with a TOTP app or a hardware key and shows the backup codes once at enrolment. ## Memories, and the approval gate on them A memory is a short fact about you that an agent suggested and you kept — a preference you stated, a constraint you keep repeating, a context worth carrying between chats. Memories are the one part of your account an agent can write to, which is why the write goes through you first. Proposing one is something the model does by calling a tool, not a background process reading your conversations. The call writes the entry as **pending** and records an audit line at the same time, because proposing durable state about a person is worth logging even before anyone agrees to it. A pending entry does nothing on its own: it waits as a suggestion in **Settings > Preferences** until you save it or discard it, and only a saved memory can ever be read back. <Info> Nothing is added to a prompt on your behalf. A saved memory reaches a reply only when the model searches for it and the search returns it — a model cannot give itself durable knowledge about you by writing it down, and it cannot quietly consult a suggestion you declined. </Info> Saved memories are listed on the same page with a control to delete each one. Deleting a memory takes it out of what a search can return, which is the whole of its effect — no second copy is riding along in some other prompt. ## Signing out The **Log out** row at the bottom of the profile menu confirms with a dialog before clearing the session. After confirming, Tale does a full page reload to the sign-in page so no stale state lingers in the tab. Sign-out is per-device — signing out on your laptop does not log you out on your phone, and vice versa. ## Where this fits Preferences are the line between you and the rest of the org. The org Admin sets the defaults — the password policy, which models are allowed, what governance applies to a chat — and your preferences override them where Tale lets them. One personal page sits apart from this set: [Environment variables & secrets](/platform/member/environment) holds variables and credentials scoped to you within a single organisation rather than following you across them — the place to keep the provider key a bring-your-own agent uses. The next read worth queuing is [Member overview](/platform/member/overview) for the map of the rest of the Member surface, or [Install as app](/platform/member/install-as-app) if you want Tale to live in your dock rather than your browser tabs. # Model catalog Source: https://tale.dev/docs/platform/models Every model picker in Tale offers the same thing — the models your organisation can actually reach right now. That set is assembled per provider, from the connector's own model list and the credentials you hold against it, then narrowed by your governance rules. This page explains where each piece comes from, so "why is that model missing" has an answer you can act on rather than guess at. ## The catalog is per provider There is no single global model list. Each provider connector declares where its models come from, and the badge on that connector's section under **Settings > AI providers** names the source: - **Built-in catalog** — the list ships with the platform and is upgraded with it. OpenAI, Anthropic, Gemini, DeepSeek, Moonshot AI (Kimi), Qwen (Alibaba), SpaceXAI, and Z.ai (GLM) work this way. - **OpenRouter catalog** — fetched from OpenRouter's own catalog and normalised on arrival. OpenRouter works this way, which is why its list is by far the longest. - **Provider models endpoint** — fetched from the provider's own models listing. Vercel AI Gateway works this way. - **No catalog** — the provider publishes nothing worth shipping, so the models come from each credential instead. Azure OpenAI and Nous Portal (Hermes) work this way. The count beside the badge is that connector's current list. It says nothing about what your organisation may call, only about what the provider offers. ## What decides availability A model reaches a picker after clearing two gates in order. The first is credentials. A connector with no credential is a provider you cannot call, catalog or not. A credential with an empty **Model allowlist** offers its connector's whole catalog; one with an allowlist offers only the models on it. The union across every enabled credential is what your organisation can technically reach. The second is governance. The model-access rules under [Content and models](/platform/admin/governance/content-models) allow or block models per organisation, team, role, or user, and they apply on top of the first gate. A model that clears the credentials but not the policy stays invisible to that scope, and the resolver refuses to bind to it even when an agent has it pinned. <Note> When a model you expected is absent, walk the two gates in that order. Confirm a credential for its provider exists and is enabled, check whether that credential's allowlist excludes it, then check the model-access rules for the scope you are looking from. Almost every "missing model" is one of those three. </Note> ## Providers that ship no catalog Some providers cannot publish a list Tale could ship. For those connectors the credential's **Model allowlist** stops being a filter and becomes the availability set itself: it is a free-text field, you type model ids into it separated by commas, and those ids are the only models that credential can reach. <Info> On Azure OpenAI the ids are the deployment names you chose inside your Azure resource, not the vendor's public model names. A credential with an empty allowlist there makes no model available at all, which is the usual cause of an Azure connector that looks configured but offers nothing. </Info> ## Refreshing a live catalog Catalogs fetched from a provider are cached, and they refresh only when somebody asks. The **Model catalogs** card at the top of **Settings > AI providers** carries a **Refresh catalogs** button that re-fetches every live source and reports one line per connector: the number of models found, or the error that stopped it. There is no background sync and no scheduled job, so a model released this morning appears after the next refresh and not before. When every connector on your instance ships a built-in catalog, there is nothing to fetch and the card says so. ## Choosing a model Chat opens on **Auto**: Tale reads each message and picks a model for it — a light heuristic over length, code, subject matter, and attached documents, never another AI call — then runs exactly that model and records it on the reply, where the message details name it. Pick a model from the menu instead and the choice is yours until you hand it back to Auto; pinning a model is the fix for a pick that is slow, expensive, or wrong for the job. Everywhere else the model is always named explicitly: on an agent, on any workflow step that calls a model, and on every API request. Nothing there routes on your behalf — no selection by task complexity, no quality tiers. And in no lane — chat included — is there silent failover: the model that starts a reply is the model that answers it, or you see the error. A run stays reproducible and a bill stays attributable, because the model that ran is recorded, never guessed. <Tip> When more than one model could plausibly do the job, [Arena Mode](/platform/chat/arena-mode) runs the same prompt against several of them side by side, which turns the choice into a comparison instead of a hunch. </Tip> ## Where this fits The catalog is the visible half of provider configuration: what an Admin connects under [AI providers](/platform/admin/providers) is what everyone else sees in a picker here. Widening the set means adding a credential or relaxing an allowlist; narrowing it means an allowlist or a model-access rule under [Content and models](/platform/admin/governance/content-models). For how a model fits alongside instructions, knowledge, and tools when you build an agent, read [Agent concepts](/platform/agents/concepts). # Project Backlog Source: https://tale.dev/docs/platform/projects/backlog A task at **`backlog` status** is proposed work nobody has committed to yet — most often synced in by an automation like [Triage GitHub issues](/platform/automations/builtin). It lives in the **leftmost lane** on the Board and the **top section** on the List, using the same card, detail sheet, status picker, and assignee picker as every other status. [Task automation](/platform/projects/task-automation) covers what happens once a task reaches **To do** and enters the assignment loop. ## A synced task Triage GitHub issues proposes one task per actionable open issue, keyed to the issue so a later sync never double-creates it: the title is `#<number> <title>` — for example `#482 Login button misaligned on Safari` — the description opens with the issue's own GitHub URL, and its labels mirror the issue's GitHub labels. A task you create from the board with the default status starts at **To do**; set **Backlog** in the create form when you want to file a proposal yourself. ## Moving work forward There are no backlog-only buttons. Drag a card to another lane, open the detail sheet and pick a new status, or assign an owner — the same paths you use for **To do** or **In progress**. Agent auto-assignment and assignment suggestions run only when a task is at **To do**, not while it sits in **Backlog**. If you move a proposal straight to **In progress** or assign it by hand, you are taking ownership yourself. Dismiss a proposal the same way you close any task: set status to **Cancelled** in the picker. A human cancellation sticks — a later GitHub sync does not resurrect a proposal you rejected while the issue stays open on GitHub. When an issue was **Done** on the board and someone reopens it on GitHub, sync moves the task back to **Backlog**. ## Where this fits Backlog is the intake column between an automation proposing work and your team committing to it. The natural next read is [Task automation](/platform/projects/task-automation) for what happens at **To do**, or [Built-in automations](/platform/automations/builtin) for what proposes tasks in the first place. # Project concepts Source: https://tale.dev/docs/platform/projects/concepts A project is the unit Tale reaches for when a body of work needs the same files, the same instructions, and the same working surfaces across many chats and many people. This page hands you the mental model — read it before you create your first project, and come back when you are deciding whether a growing chat should be promoted into one. <Frame caption="The General tab — identity, sharing, and the stats strip are the project's front door."> ![The General tab of the Website relaunch project showing the name and description fields, the sharing section with an Org-wide owning team, and a stats strip reading two files, no chats, and Org-wide.](/images/platform/project-general-tab.webp) </Frame> ## What a project owns **Chats** started inside the project carry its context automatically. They stay yours until you flip **Share with project** on a chat — the Chats tab splits into **Your chats** and **Shared with project** accordingly. Sharing a chat hides your personal memories and instructions from the responses other members see. **Instructions** are context that applies to every chat in the project — the framing, constraints, and vocabulary of the work — so nobody re-pastes them per chat. **Files** on the **Knowledge** tab are reference material every chat in the project can draw on, held in a folder tree you upload into once rather than re-attaching per chat. They stay scoped to this project — they never surface in the org-wide library or in `@` pickers outside it — see [Manage files](/platform/projects/manage-files). **Tasks** make the project a place to run work, not just talk about it: a board with statuses and [automation](/platform/projects/task-automation), with comment threads on every task for the decisions around it. **Agents** is the project's crew: named agents, each with a harness, a model on a provider you pick, equipment, and standing instructions, ready to take tasks off the board ([Project agents](/platform/projects/project-agents)). ## Creating and identity **Create project** asks for a name and a **Project key** — the prefix for task IDs like `WR-1`. The key is fixed; it cannot be changed after the project is created. Description, owning team, icon, and color are editable later on the **General** tab, where the unified **Save** and **Discard** buttons sit in the tab strip. ## Sharing model Sharing is by team, not by individual invitation. A project defaults to **Org-wide**; picking an owning team scopes it to that team, and additional teams can be added on the General tab. Org admins always have access. Renaming, archiving, and deleting live in the row menu on the projects list — deleting asks what happens to the content: detach the files and chats (they become library documents and personal chats) or delete them too. ## When to reach for it | Use … when | Project | Stand-alone chat | | --------------------------------------------- | ------- | ---------------- | | The same files apply across many chats | ✓ | | | The same instructions apply across many chats | ✓ | | | Multiple people work the same body of work | ✓ | | | The work has tasks, owners, and decisions | ✓ | | | The question is one-shot | | ✓ | A stand-alone chat is the right shape for exploring an answer once. The moment the context should outlive the chat, move it — the chat's **Move to project…** action carries an existing chat into a project. ## Where this fits Projects are the seam where chats, knowledge, and task automation meet. The natural next read is [Use projects](/tutorials/member/use-projects), which walks a fresh project end to end; the per-tab pages in this section go deeper on [files](/platform/projects/manage-files) and [agents and models](/platform/projects/project-agents). # Manage project files Source: https://tale.dev/docs/platform/projects/manage-files A project's **Knowledge** tab is the shared file area every chat inside the project can reach. Upload a file once and every chat in the project — and every agent that runs inside it — can read it without re-uploading. This page covers the folder tree, the upload mechanic, pinning, and the limits. The Knowledge tab is not the org-wide knowledge base in the [Documents](/platform/knowledge/documents) sense. Its files are scoped to one project and never appear in the org-wide library, in `@` pickers outside the project, or over WebDAV; deleting the project deletes the files. For org-wide reference material, use [Documents](/platform/knowledge/documents) and bind it to agents. <Frame caption="The Knowledge tab — the project's file tree, every file scoped to this project and indexed for retrieval."> ![The Knowledge tab of the Website relaunch project showing two indexed files in the file tree, a New folder button, and the Add file dropzone.](/images/platform/project-knowledge-files.webp) </Frame> ## Folders Project files live in a folder tree. **New folder** creates a folder at the root; the folder-with-plus icon on a folder row creates a subfolder inside it. Click a folder to select it — the drop area switches to _Add file to "…"_ and uploads land inside. Deleting a folder deletes everything in it, including the files' entries in the retrieval index; the confirmation says so before anything happens. Folders here are project-scoped: a same-named folder in the org-wide library is a different folder. ## A worked upload Open the project, click **Knowledge**, select the target folder (or none for the root), and drag files onto the drop area. The row appears in the tree and resolves to **Indexed** once retrieval has picked it up. The same upload is now reachable from any chat the project owns: send a message that references the topic and the agent retrieves it, or type `@` in the chat and pin the file — or a whole folder — to the turn. ## Replacing and deleting Replacing a file uploads a new copy under the same name; the earlier version moves to the project's version history. Citations from earlier chats keep pointing at the version that was active when the chat referenced it. Deleting a file removes it from the picker immediately; existing chats keep their citations, but the underlying file moves to [Trash](/platform/admin/governance/trash) with the rest of the project's retention cohort. ## Locking a file behind review When an approval must stay tied to the exact file a reviewer saw — an SOP, a validation plan — open the file row's menu and click **Mark as controlled**. The row gains a `v1 · Draft` badge and walks the same lifecycle as a controlled document in the org-wide library: **Submit for review** freezes the file for a named reviewer, approving locks the version immutably, and **New revision** opens the next draft. The full lifecycle, including replacing a draft's file, is on [Documents](/platform/knowledge/documents#revising-a-controlled-document). Scope does not change — a controlled project file is still a project file, visible only inside the project. ## Size limits Per-file and per-project limits are set by the org under [Policies and limits](/platform/admin/governance/policies-and-limits). Hitting a per-file limit fails the upload with a toast; hitting a per-project limit fails it with a different toast that names the policy. Members hitting a limit cannot raise it themselves — an Admin adjusts the policy, or the project owner deletes older files. ## Surfacing in chats A chat started inside a project automatically has access to every file in the project's Knowledge tab. The agent's retrieval tool sees project files alongside any agent-bound Knowledge sources. Citations from project files are scoped to the chat that produced them — sharing that chat outside the project preserves the citations, but the viewer cannot click through to the source unless they are also in the project. Pinning with `@` narrows a single turn: `@file` pins one file, `@folder` pins a folder and everything under it (the picker offers the project's folders inside project chats, and org-wide folders everywhere). Pinned files are also delivered to the agent's sandbox under `/user/uploads`, so a project agent on a coding harness — Claude Code and the other harnesses included — can open the actual bytes, not just quote retrieval snippets. ## Where this fits Manage files is the operational page for the Knowledge tab — the conceptual framing is on [Project concepts](/platform/projects/concepts), and the agent-bound equivalent across the whole org is [Documents](/platform/knowledge/documents). If you find yourself re-uploading the same files into many projects, that is the signal to move them to Documents and bind an agent to them instead. # Projects Source: https://tale.dev/docs/platform/projects/overview A project is a shared workspace that bundles everything one piece of work needs — the chats, the reference files, the instructions, and the task board — so the context follows the work instead of being re-pasted into every chat. Where a single chat answers one question, a project is where a team keeps a contact, a launch, or a long-running investigation moving. Prefer to watch first? Episode 6 walks a live project in two and a half minutes — including a task an agent picks up on camera. <Video src="/videos/en/tutorials/ep6-projects/ep6-projects.en.mp4" poster="/videos/en/tutorials/ep6-projects/ep6-projects.en.webp" captions="/videos/en/tutorials/ep6-projects/ep6-projects.en.vtt" lang="en" title="Episode 6 — Projects with AI" caption="Episode 6 — Projects with AI (2:21)"> </Video> <Frame caption="A project's task board — one of the eight tabs every project carries."> ![A kanban task board inside the Website relaunch project, with seven task cards spread across the Backlog, To do, In progress, In review, Done, and Cancelled columns.](/images/platform/projects-task-board.webp) </Frame> ## The parts of a project Every project opens on the same tab strip: **General** (name, description, sharing, and recent chats), **Chats** (your chats in the project plus the ones shared with it), **Tasks** (the board), **Knowledge** (the project's files, in a folder tree), and **Agents** (the project's own task agents) — plus **Automations** once one is bound to the project, and **Environment** for project administrators. Apps installed into the project add their own tabs after these. ## Pages in this section <CardGroup cols="2"> <Card title="Project concepts" icon="compass" href="/platform/projects/concepts"> The mental model — what a project owns, when it beats a stand-alone chat, and how sharing works. </Card> <Card title="Manage files" icon="folder-open" href="/platform/projects/manage-files"> The Knowledge tab — uploading files into folders, index status, and how project files stay scoped to the project. </Card> <Card title="Project agents" icon="bot" href="/platform/projects/project-agents"> The project's own agents — harness, model and serving provider, equipment, standing instructions — and how tasks put them to work. </Card> <Card title="Task automation" icon="workflow" href="/platform/projects/task-automation"> Assigning board tasks to agents — the execution loop, the review gate, and the guardrails. </Card> <Card title="Backlog" icon="gauge" href="/platform/projects/backlog"> Proposed tasks an automation or teammate synced in — Start onto the board or Close them off. </Card> </CardGroup> ## Where this fits Projects sit beside Chat in the sidebar, and the handover is natural: a question starts in Chat, turns out to be bigger than one chat, and moves into a project — the chat's **Move to project…** action carries an existing chat across. If you are new to projects, start with [Project concepts](/platform/projects/concepts) for the model, then walk [Use projects](/tutorials/member/use-projects) end to end on a fresh one. # Project agents Source: https://tale.dev/docs/platform/projects/project-agents A project's **Agents** tab is its crew: named agents you configure once and then assign work to, each combining a coding [harness](/platform/agents/harnesses), a model, skills and connectors, and standing instructions. Chat keeps running the built-in assistant — these agents exist for the board: assign one a task and it works in an isolated sandbox, then reports back for your review. Anyone with project edit access can manage them; a project holds up to 50. <Frame caption="The Agents tab — the project's own agents, each row naming its harness, serving provider, and model."> ![The Agents tab of a project listing named agents, each with a harness label, the serving provider, the model id, and an equipped count.](/images/platform/project-agents-models.webp) </Frame> ## Create an agent <Steps> <Step title="Open the tab and start one"> Open the project's **Agents** tab and click **New agent**. Give it a **Name** your team will recognize on task cards, and pick the **Agent type** — the coding harness the agent runs on. </Step> <Step title="Pick the model — and with it, the provider"> The **Model** list is searchable, and a model served by more than one provider appears once per provider, with the serving provider named under each entry. The pick is exact: the agent's runs call that model through that provider — and the spend lands on that provider's credential. When the picked provider can no longer serve the model, the run fails with the reason instead of quietly switching to another provider's bill. Subscription-served entries — a Claude subscription, say — appear only while the **Agent type** is the harness that subscription drives, and a run on one authenticates with the vendor subscription instead of an organization API key. </Step> <Step title="Equip it and set its instructions"> **Skills, connectors & tools** decide what the agent can reach beyond its workspace; the list follows the project's team access, not your personal visibility. Skills stage reference bundles into the sandbox; connectors broker a connected service; **platform tools** let the agent read and write your organization's own data — find and read tasks, contacts, products, documents, and knowledge, and (when you grant a write tool) create tasks, comment, move them between columns, sync an external item to a task, or save a document. A write tool is marked _Writes data_: granting it is the authorization, so an agent equipped with `Create tasks` files real tasks with no further approval. Reads and writes both stay scoped to the project — an agent never sees another project's board. **Secrets** hand the agent an API key as an environment variable — the escape hatch for a service that has no connector. Add one (a name like `GLITCHTIP_TOKEN` and the token), and the agent receives it in its shell and calls that service's API directly, reading the vendor's own docs. The value is stored encrypted and never shown again; store only low-privilege, rotatable tokens, because the running agent can read them. Secrets are owned by the organization, so the same one is reused across agents and rotated in one place. **Instructions** ride along on every run as a standing instruction — what this agent owns, how it should work, and the boundaries it must respect. </Step> </Steps> Click **Create agent**. The row lists the harness, the serving provider, the model, and the equipped count — the same summary teammates see when they assign it work. ## Put it to work Assign a board task to the agent and click **Start agent** on the task. The run works in an isolated sandbox with a standing workspace that persists across the agent's tasks, posts its report back as a task comment, attaches produced files as deliverables, and parks the task **In review** — agents never complete work; a person does. Comment on the task and @mention the agent to steer a live run, or to kick a fresh one that reads your comment first. [Task automation](/platform/projects/task-automation) covers the board loop end to end. ## Change or remove one Edits apply from the next run — a live run keeps the configuration it started with, so a mid-run edit never swaps the engine underneath it. Deleting an agent keeps every task's history; only the assignee slot empties. ## Chat assistant or project agent? | Use… | when the work is… | | --------------- | --------------------------------------------------------------------------------- | | Chat | a conversation — questions, drafts, retrieval; the built-in assistant handles it. | | A project agent | a task — repo or file work on a harness, done by a standing, configured crew. | ## Where this fits The agent is the project-side package of choices other pages explain: the harness catalog and its capabilities live in [Harnesses](/platform/agents/harnesses), and which providers and credentials serve the models — stored keys on the metered gateway, or vendor subscriptions on the vendor's own account — is the [Providers](/platform/admin/providers) surface. # Task automation Source: https://tale.dev/docs/platform/projects/task-automation Assigning a board task to an AI agent puts it to work. The task's **assignee is its driver** — a person, a project agent, or an automation — and drives the board choreography; the **Reviewer** is the named human the finished work waits on. A task an automation proposes sits in [Backlog](/platform/projects/backlog) until a human starts it — from that moment on it's a board task like any other and enters the loop below. <Frame caption="The project task board — assigning a card to an agent is what starts the loop below."> ![A kanban task board inside the Website relaunch project, showing seven task cards spread across its status columns, from Backlog and To do through In review to Done and Cancelled.](/images/platform/projects-task-board.webp) </Frame> ## The execution loop 1. **Assign** a task to an agent. The card moves to _In progress_ and the agent works in its own sandbox session, with the task's description, comments, and input files as context. 2. The agent **reports back**: its result lands as a task comment (deliverables in the task's Output zone), and the task parks at **_In review_** — agents can never set _Done_; that rule is enforced server-side. 3. The park **requests a review**: the task's **Reviewer** gets an inbox bell and an email, and the task sheet shows the review card — _Waiting on {name}_. Without a designated reviewer the request lands with the task's creator (or the project's), so a finish is never silent. 4. A human **decides from the review card**: **Approve** completes the task — _Done_ is recorded as that person's decision, never the agent's. **Request changes** posts the feedback as a task comment and hands it straight back to the agent, which starts a rework run and parks the result at _In review_ again. A failed run leaves the task where it was and explains itself on the task sheet; start the run again once the cause is fixed. A parent task with open subtasks refuses to close until the last subtask is done. ## Driver and Reviewer The two roles are deliberately separate fields: | Role | Who | What it does | | ------------ | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | **Assignee** | person, agent, or automation | Drives the work and the board status — the polymorphic single assignee | | **Reviewer** | a project member who can edit | The named "waiting on" human: gets the review request, populates the **Needs my review** filter, decides the review card | Pick the reviewer in the task sheet's **Reviewer** field. The designation is deliberately **soft**: it routes notifications and the queue, but any project editor can still respond to a review — and unlike reassigning the driver, you can set or change the reviewer while a run is live. Reviewing this way never requires taking the task over: the agent or automation stays the assignee, so the choreography keeps working after the decision. The board names the gate: cards waiting at _In review_ carry a **Waiting on {name}** chip (or _Waiting on you_), and the board's **Review** filter reduces the board to the tasks waiting on you — your personal review queue inside the project. ## Mentions **@-mention an agent** in a task comment and it reads the mentioning text and acts. Typing `@` opens an autocomplete over members and the project's agents; the composer previews whether each mentioned agent will actually respond (automation off, breaker paused, not mentionable in this project). A mention of the task's **assignee** is treated as feedback on its assigned work: a running agent picks the comment up mid-run, an idle one starts a rework run carrying the comment verbatim. ## Guardrails Every agent run — assignment, mention, review rework — passes the same admission gate: - **One engine per task**: a task with a live run refuses a second one, and reassigning mid-run is refused outright (cancel first — the picker offers cancel-then-reassign). - **Concurrency**: agent sessions draw from per-organization capacity; excess runs queue and start when a slot frees. - **Per-task circuit breaker**: too many automated runs within an hour on one task pauses automation on that task until a human changes its status. ## Choosing an assignee Not every task belongs on a coding harness. Use this rule of thumb: | Task shape | Assign | | --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | | Research, writing, summaries, personal deliverables | A **person** | | Board work driven by a deployed automation | An **Automation** — its desk then drives the board's status verbs, and review happens on the task's subject panel | | Repository work — bugs, features, refactors, PRs | An **Agent** on a coding [**Harness**](/platform/agents/harnesses) — create it on the project's Agents tab with the harness that fits the work | The assignee picker groups **Agents** and **Automations**. Each agent runs in a sandbox on the **Harness** chosen when it was created, pre-equipped with its skills, connectors, and instructions. ## The kill switch The `task_automation` governance policy carries the master switch: switching it off stops the run path — in-flight work finishes, nothing new starts. It is admin-only and audited; on a self-hosted instance the policy is one of the org's governance config files, alongside the limits covered on [Policies and limits](/platform/admin/governance/policies-and-limits). ## Where this fits Task automation is what turns the project board from a to-do list into a delegation surface: a human assigns, a named human reviews, the agent runs everything in between — and _Done_ stays a human decision. The natural next read is [Backlog](/platform/projects/backlog) for how proposed work enters the loop. # Skill library Source: https://tale.dev/docs/platform/workspace/skills A skill is an instruction you write once and let every agent read. It lives in your organization's own file tree as a small bundle — a `SKILL.md` carrying the instruction in its body, plus any reference material that instruction leans on — and **Settings > Skills** is where you create, upload, and maintain those bundles. Every member can create skills; what you may edit is decided per bundle. This page covers what a skill is, the file it is made of, who gets to see it, and how you add and retire one. Read the agent side on [Skills on agents](/platform/agents/skills) once you want a particular agent to reach for a particular bundle. ## What a skill is, and what it is not A skill is a **knowledge pack**. Its body is instruction a model reads when the work calls for it: a house writing voice, a checklist your team follows, the way your organization phrases a refusal. A model finds the bundle by its description, reads the body when that description matches the task at hand, and opens individual bundle files when the body points at them. A skill is never something the platform executes. There is no entry point, no command, and no runtime in a bundle — a file under `scripts/` is material a model may read and adapt, not a program Tale runs on your behalf. That boundary is what makes a bundle safe to accept from outside: importing someone else's skill hands your organization prose and reference files, and nothing that can act on its own. ## The SKILL.md file Every bundle has exactly one `SKILL.md` at its root — a YAML frontmatter block, then the instruction body in markdown. ```markdown --- name: release-notes description: Turn a list of merged changes into release notes in our house voice. Use when someone asks for a changelog, release notes, or a summary of what shipped. visibility: team teams: - jx7d… license: CC-BY-4.0 --- Write release notes as three sections — Added, Changed, Fixed — and lead each line with the verb... ``` The keys follow the agentskills.io convention in kebab-case, and any key Tale does not recognise is kept verbatim, so a bundle authored for another tool survives an edit and a save unchanged. | Key | What it carries | | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `name` | The slug, which must equal the bundle's folder name — lowercase letters, digits, and single hyphens, 64 characters at most. `anthropic` and `claude` are reserved. | | `description` | Up to 1024 characters, and the field that decides whether a model reaches for the skill at all. Say what it does and when it applies. | | `visibility` | `team` or `org`. Absent counts as `org`. `private` is retired — a pre-existing private bundle still parses, but no new skill may take it. | | `teams` | The team ids a `team` skill is shared with — required there, rejected elsewhere. The library's sharing picker fills it for you. | | `owner` | The member the bundle belongs to — attribution on a shared skill, required on a legacy `private` one. | | `license` | Free text, for a bundle you imported or intend to pass on. | | `recommended-packages` | Python or Node package specs the author suggests. Advisory only — Tale never installs them on a skill's behalf. | | `disable-model-invocation` | Set it to `true` and a model must not reach for the skill on its own. It stays available for an explicit recall. | | `icon` and `labels` | An Iconify id and up to eight chips, for the skill's card in the library. | Two ceilings apply: the frontmatter block may run to 16 KB, and the whole `SKILL.md` to 512 KB. Bundle assets sit outside that budget. ## Who can see it Sharing is one field rather than a table of permissions. `visibility: team` shares the bundle with the teams listed under `teams` — pick them in the library's **Visibility** section. `visibility: org` means every member sees it, and any project's agents can equip it. Any member may share a skill team- or organization-wide; editing or deleting someone else's shared skill takes an org admin. A bundle carrying no `visibility` at all — including one you upload — counts as an organization skill, and the upload preview says so before you confirm. <Note> `visibility: private` is retired. Agents are the only surface that equips skills, and a project's agents never see one member's private bundle — so a private skill would be visible to you alone and usable nowhere. A bundle that already carries it keeps working for its owner (even an admin cannot read it), and its owner can widen the sharing at any time; new skills and uploads that declare `private` are refused. </Note> Narrowing a skill's sharing — org to team, or dropping a team — asks for confirmation first: whoever loses sight of the skill also loses it in every agent that equipped it through them. ## Add a skill Open **Settings > Skills**. The page is a table of every skill you may see — its name, description, visibility, and labels — with search over all three of name, description and labels, and filters for visibility and label. Clicking a row opens the bundle. **Add skill** offers three starting points. <Steps> <Step title="Start blank"> **Blank skill** asks for a name — the slug, in lowercase letters, numbers, and single hyphens — plus the description, the sharing, and an instruction body you can write on the spot. New skills start shared with the organization; narrow the sharing to teams where the knowledge is theirs. </Step> <Step title="Or upload a bundle"> **Upload zip** takes a `.zip` with `SKILL.md` at its root, alongside any `scripts/`, `references/`, or `assets/` folders; **Upload folder** takes the folder itself and zips it for you. Either way Tale reads the frontmatter before writing anything and shows you what it found — the description, the sharing it will land with, the license, and a full file list with sizes — so you approve a bundle you have actually read. A bundle whose slug already exists asks first whether to replace it. </Step> <Step title="Write the body"> Open the skill and write the instruction under **Instructions (body)**. This is the text a model reads, so write it the way you would brief a colleague: what the skill is for, when it applies, and what good output looks like. </Step> </Steps> ## What sits in the bundle A skill's detail view shows **Bundle** — the file tree as it exists on disk — with a viewer for any file you click. The smallest useful skill is a single file, and most grow one folder at a time. ```text release-notes/ ├── SKILL.md ├── references/ │ └── voice-and-tone.md └── scripts/ └── group-changes.py ``` Keep the assets small and readable. Text a model can open cheaply gets used; a large binary sits there unread, and the viewer says outright that it cannot preview it. ## Retire a skill **Delete skill** on the detail view removes the bundle from disk; every agent equipped with it loses access, with nothing to fall back on. There is no version pinning — a skill is always read exactly as it stands right now, which is also what makes it worth extracting: one edit reaches everyone who holds it. ## Where this fits The skill library is the lightest reuse Tale offers: one file, one field for sharing, and nothing to keep in sync across the people who need it. It is where a phrasing you keep retyping stops being something you retype. Once a bundle is in the library, the remaining decision is which agents get it — that is [Skills on agents](/platform/agents/skills), which covers equipping a project's agents and how a bundle reaches a sandbox. # Authentication Source: https://tale.dev/docs/self-hosted/configuration/authentication Tale ships four sign-in modes that an operator picks per instance. The default is local password, with one user per email; Microsoft Entra and generic OIDC delegate identity to an external provider; trusted headers hands the responsibility to a reverse proxy already terminating SSO upstream. The decision is permanent in the sense that it shapes how users are provisioned — switching modes after rollout is possible, but every existing user has to be re-mapped to the new identity source. Local password and trusted headers are switched by env vars ([Environment reference](/self-hosted/configuration/environment-reference)); Microsoft Entra and generic OIDC are configured per organisation inside the running app. This page is the mode-by-mode walkthrough — when to choose each, what it changes for the user, what breaks when it is misconfigured. ## Local password (default) Local password is the mode you get if you set nothing. The platform stores a bcrypt hash in Postgres, signs the session with `BETTER_AUTH_SECRET`, and the user signs in with an email and password the admin invites them with. No external identity provider is involved. Reach for it on small instances and air-gapped deployments where adding an IdP is more friction than it solves. The cost: password reset goes through the admin (or through email if `SMTP_*` is configured), and there is no SSO story. ```bash # .env — no flags needed for local password HOST=localhost SITE_URL=https://localhost BETTER_AUTH_SECRET=... ``` ## Microsoft Entra The Microsoft Entra mode adds a **Continue with SSO** button to the sign-in screen and accepts users from a tenant you control. There is no env-var switch: the connection is configured per organisation under **Settings > Enterprise SSO** once the platform is up — pick the **Microsoft Entra ID** protocol and enter the client ID, client secret, and issuer URL from your app registration. The full walkthrough, including role mapping and group-to-team sync, is [Enterprise SSO and provisioning](/platform/admin/enterprise-sso). Two deployment values must be right before the flow can work: `SITE_URL`, because the sign-in redirect URL is derived from it, and `BETTER_AUTH_SECRET`, which signs the OAuth state. The redirect URI to register in Entra is `${SITE_URL}${BASE_PATH}/http_api/api/sso/callback` — the settings page shows the exact URL to copy, and it must match byte-for-byte or Entra rejects the sign-in with `AADSTS50011`. The tenant ID in the Entra app registration narrows who can sign in; a multi-tenant registration accepts anyone with a Microsoft account, which is rarely what you want. ## Generic OIDC Generic OIDC accepts any spec-compliant identity provider — Keycloak, Authentik, Okta, Google Workspace. Configuration lives on the **Single Sign-On** card under **Settings > Connectors**: pick the **Generic OIDC** provider type, enter the issuer URL, client ID, and client secret, and Tale reads the authorization, token, and userinfo endpoints from the issuer's `.well-known/openid-configuration` document. The flow uses the standard Authorization Code grant with PKCE (S256). Tale stores no secret on disk for OIDC; the client ID and client secret live in the encrypted credential store. The redirect URI to register with your provider is `${SITE_URL}/http_api/api/sso/callback`. Identity providers disagree on where claims live, so the card lets you point Tale at yours. The **Email claim**, **Name claim**, and **Groups claim** fields take a claim name or a dot path into the userinfo response — Keycloak's realm roles, for example, sit at `realm_access.roles`. Role mapping rules assign platform roles at sign-in: a **Group** rule matches the user's groups against a wildcard pattern (`platform-admin*` → Admin), a **Claim** rule matches any claim resolved by dot path. **Auto-provision teams** mirrors the groups your provider returns as Tale teams on every sign-in, minus the groups you exclude. A worked Keycloak example: create a confidential client `tale-platform` with the redirect URI above, add a Group Membership mapper so the client emits `groups` in userinfo, then in Tale set the issuer to `https://keycloak.example.com/realms/<realm>`, add a group rule `platform-admin*` → Admin, and click **Test connection** — it validates discovery before anything is saved. This is the mode for teams that already run an IdP and want their existing identity surface in Tale. ## Trusted headers Trusted headers is the mode for sites that terminate SSO at an upstream reverse proxy — oauth2-proxy, Pomerium, Authelia. The proxy authenticates the user and forwards identifying headers (`X-Auth-Request-Email`, `X-Auth-Request-Preferred-Username`); Tale trusts those headers and creates or updates the user record on the fly. ```bash # .env TRUSTED_HEADERS_ENABLED=true ``` The threat model is delicate. Anything that can reach the platform container with those headers becomes the user named in them. Restrict the platform port so only the proxy can speak to it (a Docker network or a host firewall rule), and never expose the platform container directly to the internet when this mode is on. ## Where this fits The four modes are mutually exclusive in spirit but technically additive — Microsoft Entra and trusted headers can coexist on the same instance if your IdP story is mid-migration. The full per-mode trade-off table lives in [Members and roles](/platform/admin/members-and-roles) on the user side; this page covers the operator's switch. The next configuration page worth reading is [Providers](/self-hosted/configuration/providers) — once users can sign in, you still need at least one model provider wired up before they can do anything. # Data residency Source: https://tale.dev/docs/self-hosted/configuration/data-residency A self-hosted Tale deployment runs on infrastructure you already control, so its data lives on your hosts by default. **Data residency** is for the case where you want individual data stores pointed at your own managed Postgres or object storage instead of the bundled containers — for example to keep document text in a database your team operates, or uploaded files in your own S3 bucket. The knowledge corpus runs as its own container (`knowledge-db`) precisely so it can be relocated or replaced independently of the operational database — it is the store most residency requirements care about. Administrators configure this in **Settings > Data residency**; the change is written to a single deployment-level config file and **takes effect when the affected containers restart**. This page covers what can be relocated, the one prerequisite that bites (ParadeDB), how the configuration is stored and applied, and how to restart safely. ## Enabling editing **Settings > Data residency** is one page with two kinds of section: the deployment-wide stores every organization shares, and the stores a single organization brings for itself. Each section renders read-only or editable depending on what the reader may change, and the page says which state you are in. Viewing is open to any organization owner or admin; **editing the deployment-wide stores** — repointing a data store, saving secrets, running a connection test, or applying a restart — is restricted to a named allowlist of operators. List their sign-in emails (comma-separated) in `.env` and restart: ```bash TALE_DEPLOYMENT_CONFIG_ADMINS=alice@example.com,bob@example.com ``` With the allowlist empty or unset, the deployment sections still show the current configuration to administrators, but read-only — the **Save deployment** and **Apply & restart** header actions appear only for allowlisted operators. Only a signed-in admin whose email is on the list gets those sections editable; the page tells you which email to add. The entrypoints always consume the config file regardless of the allowlist, so an operator who prefers to hand-edit the file on disk can do so without naming any UI editors. ## What you can relocate Three stores, each independent and optional. An absent setting means "use the bundled default" — so a fresh deployment with no config is unchanged. - **Knowledge database** — the knowledge corpus: document metadata, the extracted chunk text, embeddings, the BM25 index, the semantic cache, and the crawled web pages. It ships as the bundled `knowledge-db` container (`tale_knowledge`, with the `private_knowledge` and `public_web` schemas) and is the store most residency requirements care about, because it holds your document content. Point it at your own managed Postgres to keep the corpus on infrastructure your team operates. - **File storage** — where uploaded files (the original blobs) live. By default they sit on the local Convex volume; you can point them at an external S3-compatible bucket. - **Application database** (advanced) — the operational Convex database (the bundled `db` container). The Convex backend derives this database's name from `INSTANCE_NAME` (`tale_platform`) and connects on host:port only, so the external Postgres must contain a database named exactly `tale_platform`. Its TLS mode is fixed by the Convex driver and is not configurable. > Note: the knowledge database and the application database are two separate Postgres instances — moving one does not touch the other. Relocating the knowledge database moves the extracted text and embeddings; the original uploaded files move only when you also relocate **File storage** to S3. ## The ParadeDB prerequisite The knowledge database uses two Postgres extensions: `vector` (pgvector) for embeddings and `pg_search` (ParadeDB) for full-text/BM25 hybrid search. An external knowledge Postgres **must run ParadeDB** (which bundles both) for full search quality. If you point it at a plain Postgres that has only `pgvector`, indexing and vector search still work, but hybrid search degrades to **vector-only** — the BM25 leg is silently skipped. The **Test connection** button reports both `pgvector` and `pg_search` availability so you can see this before you commit. The external knowledge database must already exist (it can have any name you enter — `tale_knowledge` by convention) with the `private_knowledge` and `public_web` schemas; the baseline schema migrations live in [`services/db/migrations/`](https://github.com/tale-project/tale/tree/main/services/db/migrations) and are applied via dbmate when the database comes up. ## Per-organization knowledge databases The stores above are deployment-wide — every organization shares them. A single organization can instead point **its own** knowledge corpus at a Postgres you provision for it, while every other org keeps using the bundled `knowledge-db`. Reach for this when one tenant's document and crawled-web content must sit on infrastructure isolated from the rest — a stricter residency requirement than the deployment default satisfies. The org's **entire** knowledge corpus moves — both schemas: `private_knowledge` (document metadata, chunk text, embeddings, and the semantic cache) and `public_web` (the crawler's website pages, their chunk text, and embeddings). Nothing in an organization's knowledge database is shared with any other organization. The connection lives under the organization's own config directory, not the deployment file: - `$TALE_CONFIG_DIR/<orgSlug>/knowledge/connection.json` — host, port, database, user, and sslmode. - `$TALE_CONFIG_DIR/<orgSlug>/knowledge/connection.secrets.json` — the password, SOPS-encrypted when a SOPS age key is configured (see [Secrets with SOPS](/self-hosted/configuration/secrets-with-sops)). - `$TALE_CONFIG_DIR/<orgSlug>/knowledge/embedding.json` — the organization's embedding model: provider, optional stored credential, model tag, vector width, and an optional OpenAI-compatible base URL. The same ParadeDB requirement applies. The org validates its candidate database with an org-scoped connection test that reports `pgvector` and `pg_search` availability before switching, and a plain-pgvector target degrades that org's search to vector-only. The database can start empty — Tale creates the `private_knowledge` and `public_web` schemas on first use, so you never apply the baseline migrations by hand. This path is fallback-safe. An organization with no `connection.json` keeps using the deployment-default `knowledge-db` exactly as before, so the feature changes nothing for orgs that don't opt in. Two organizations pointed at the same database share one connection pool, and — unlike the deployment-wide stores — a per-org change needs no container restart: the next request for that org routes to its own database. An organization owner or admin can also manage this connection from the UI: the per-organization sections of **Settings > Data residency** read and write exactly these files, with the same connection test before switching. Those sections stay editable for an org owner or admin whether or not the operator allowlist names them, because the files they touch belong to the organization rather than the deployment. The JSON files on disk stay the source of truth — an operator who prefers to edit them by hand needs no UI step. ### The organization's embedding model Knowledge search needs one more per-organization setting before it can run at all: the **embedding model** — which provider and model turn documents and queries into vectors, and at exactly what vector width. Without it, indexing and search refuse with an actionable error rather than guessing a model. Set it in the **Embedding model** section of **Settings > Data residency** (or write `embedding.json` by hand): pick a provider you hold a credential for, name the model tag as the provider spells it, and state the width the model produces — the width is never inferred from the model name, because a wrong guess writes vectors that search silently can't use. The width is pinned **per database** when the first vector is written. On the shared deployment `knowledge-db`, that means every organization must agree on one width; an organization that wants a different embedding model at a different width is exactly the case for giving it its own knowledge database above. ## Per-organization object storage The same per-organization pattern covers uploaded files. A single organization can point **its own** file blobs — Knowledge Hub documents, chat attachments, audio, and generated media — at an S3-compatible bucket you provision for it (AWS S3, MinIO, Cloudflare R2, …), while every other org keeps using the deployment default. The bucket is dedicated to that organization; nothing in it is shared across organizations. The connection lives next to the knowledge one, under the organization's config directory: - `$TALE_CONFIG_DIR/<orgSlug>/object-storage/connection.json` — region, optional endpoint (for MinIO/R2), path-style flag, bucket, and an optional key prefix. - `$TALE_CONFIG_DIR/<orgSlug>/object-storage/connection.secrets.json` — the access key pair, SOPS-encrypted when a SOPS age key is configured (see [Secrets with SOPS](/self-hosted/configuration/secrets-with-sops)). Unlike the deployment-wide S3 switch above, this path is **not** greenfield-only: from the moment the config exists, new uploads go to the org's bucket, while files stored earlier stay readable where they are in Convex storage — mixed references are supported, so you can switch at any time and relocate the older files afterward with the blob backfill below. Removing the config sends new uploads back to the deployment default; files already written to the bucket stay there, but Tale can't read them until the connection is added again. No restart is needed in either direction. Org admins can manage this connection from the same per-organization sections of **Settings > Data residency**; its connection test performs a real upload/read/delete round-trip against the bucket before you commit. As with the knowledge connection, the JSON files remain the source of truth. > **Allow the app's origin in the bucket's CORS policy.** Uploads and downloads run directly between the browser and the bucket via presigned URLs, so the bucket must accept cross-origin requests from your deployment's URL — allow that origin with the methods `GET`, `PUT`, and `HEAD` and all request headers (Cloudflare R2: the bucket's **Settings > CORS Policy**; AWS S3 and MinIO: the bucket's CORS configuration). The in-app connection test runs from the server, not the browser, so a missing CORS policy surfaces only later, as a failed upload. ### Moving pre-existing files into the bucket Connecting the bucket only reroutes **new** uploads; the blobs written before you connected it stay in Convex's `_storage` and keep working through the mixed references above. To bring that history onto your own infrastructure as well — the whole point of data residency — run the **blob backfill**: it copies each pre-existing blob into the org's bucket, verifies it round-trips byte-for-byte, rewrites every row that references it, and deletes the Convex copy. An org admin runs it from the UI: with the bucket connection saved, the Object storage section of **Settings > Data residency** shows **Move existing files** — confirm, and the move runs in the background while uploads keep working; a status line on the same section reports progress and the outcome of the latest run. An operator with Convex CLI access can run the same engine from a shell instead, passing the organization's id. Dry-run first to see what would move, then run it for real: ```bash # Dry run — counts and samples what would move, writes nothing: bunx convex run object_storage/backfill_actions:migrateOrgBlobsToObjectStorage '{"organizationId":"<organizationId>","dryRun":true}' # The real move — drop dryRun once the counts look right: bunx convex run object_storage/backfill_actions:migrateOrgBlobsToObjectStorage '{"organizationId":"<organizationId>"}' ``` The backfill is **idempotent** and **org-scoped**: it moves only that organization's blobs, skips anything already in the bucket, and leaves each Convex source in place until its copy is verified — so a re-run after an interruption resumes safely. A real run needs the bucket connection configured first; a dry run does not. This is deliberately **not** a versioned framework migration — it runs on demand, per organization, when you choose to relocate a tenant's history, not at a release boundary. ## File storage on S3 External file storage is all-or-nothing across Convex's storage use-cases, so you provide **five buckets** — files, exports, snapshot-imports, modules, and search — plus a region and credentials. For S3-compatible services (MinIO, Cloudflare R2) set the endpoint and enable path-style addressing. > **Greenfield only.** Switching file storage from local to S3 does **not** migrate the blobs already on the local volume — Convex will look for them in the bucket and not find them. Set S3 at initial deployment, or copy the existing local storage into the bucket out of band before switching. ## How the configuration is stored Saving writes two files at the config root (not under an org directory): - `deployment.json` — the non-secret config (hosts, ports, buckets, modes). - `deployment.secrets.json` — the database passwords and S3 keys, SOPS-encrypted (see [Secrets with SOPS](/self-hosted/configuration/secrets-with-sops)). At boot the `convex` entrypoint reads these and derives its connections before starting. Knowledge ingestion and retrieval run inside the Convex backend, so it is the only container that opens the knowledge-database connection — there is no separate retrieval service to configure. The contract is **fail-closed**: a present-but-unparseable `deployment.json`, an undecryptable secret, or a config missing required fields **aborts startup** rather than silently falling back to the bundled database — mis-routing regulated data is worse than not starting. An absent file is the normal default path. ## Applying a change: restart The config is read at boot, so a save does not take effect until the **`convex`** container restarts (the platform itself does not need restarting). Two ways: - **Manual** — `docker compose restart convex`, or `tale deploy --services convex` for a zero-downtime blue-green roll. - **One-click** — enable the opt-in `controller` service (`docker compose --profile controller up -d`). It is a small internal-only sidecar that restarts the allowlisted `convex` service on an HMAC-signed request from the app, so the browser-facing platform never needs Docker-socket access. With it running, the **Apply & restart** button does the bounce for you; set `CONTROLLER_TOKEN` (shared with the platform) and `CONTROLLER_URL` in `.env`. Without it, the button shows the manual command. The relevant environment variables are `TALE_DEPLOYMENT_CONFIG_ADMINS` (the comma-separated email allowlist of operators allowed to edit), and — only when running the one-click `controller` — `CONTROLLER_TOKEN` (the shared HMAC secret) and `CONTROLLER_URL` (e.g. `http://controller:8004`). Set them in `.env`. See also [Environment reference](/self-hosted/configuration/environment-reference) and [Secrets with SOPS](/self-hosted/configuration/secrets-with-sops). # Environment reference Source: https://tale.dev/docs/self-hosted/configuration/environment-reference Tale reads its configuration from a single `.env` file at the repo root. About a dozen variables are mandatory at first boot; the rest tune behaviour. This page lists every variable the [`.env.example`](https://github.com/tale-project/tale/blob/main/.env.example) ships with, what it defaults to, and which surface in the product consumes it. Groups are ordered by when you first need them: domain identity, TLS, secrets, database, instance, observability, provider encryption. If a variable changes value, restart the platform container (`docker compose restart tale-platform tale-convex`) for it to take effect. ## How to read this page Each group is a `Name | Default | Description` table. Variables marked **Required** must be set before `docker compose up` succeeds. Variables marked **Optional** can be left unset; the column's description names what disabling the feature does. The `.env.example` file ships with inline comments that explain each variable in context; this page is the structured, grouped reference for the same set. ## Domain identity (required at first boot) | Name | Default | Description | | ----------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------- | | `HOST` | `localhost` | **Required.** Hostname without protocol. Used for Docker networking and outbound email. | | `SITE_URL` | `https://localhost` | **Required.** Full canonical URL including scheme and any non-standard port. Auth callbacks and external links use this. | | `BASE_PATH` | unset | **Optional.** Path prefix for subpath deployments behind a reverse proxy (e.g. `/app`). Leave unset for root deployments. | The `SITE_URL` must match what the user types in the browser exactly. A trailing slash, a missing port, or `http` instead of `https` will break the auth callback and produce sign-in loops. ## TLS | Name | Default | Description | | ----------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------- | | `TLS_MODE` | `selfsigned` | One of `selfsigned`, `letsencrypt`, `external`. See [TLS and domains](/self-hosted/configuration/tls-and-domains) for trade-offs. | | `TLS_EMAIL` | unset | Contact email for Let's Encrypt notifications. Optional but recommended in production. | `selfsigned` runs Caddy with a generated cert — the browser warns, fine for development. `letsencrypt` requires a real domain and ports 80/443 reachable from the public Internet. `external` makes Caddy serve plain HTTP; an upstream reverse proxy terminates TLS. ## Security secrets (required) | Name | Default | Description | | ----------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `BETTER_AUTH_SECRET` | example value in shipped file | **Required.** Base64 secret for the Better Auth session signer. Generate with `openssl rand -base64 32`. Rotating invalidates every session. | | `ENCRYPTION_SECRET_HEX` | example value in shipped file | **Required.** 32-byte hex key. AES-256 key for OAuth and connector credentials and HKDF input for the guardrails secret box. Generate with `openssl rand -hex 32`. Rotating invalidates every DB-stored ciphertext; operators must re-enter affected secrets. | | `INSTANCE_SECRET` | example value in shipped file | **Required.** Used to derive the Convex admin key for `tale deploy`. Deploy fails if unset. | Replace the values that ship in `.env.example` before exposing the instance — they are intentionally insecure placeholders. ## Database Tale runs two Postgres databases: the operational store (`db`, port 5432) behind the Convex backend, and the knowledge corpus (`knowledge-db`, port 5433) that holds document chunks, embeddings, and crawled pages. Both are ParadeDB and share `DB_PASSWORD`, but they are independent — point either at external infrastructure on its own. | Name | Default | Description | | ------------------------ | ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `DB_PASSWORD` | `tale_password_change_me` | **Required.** Password for the self-hosted Postgres user. Change before production. Used by both database containers. | | `POSTGRES_URL` | constructed from `DB_PASSWORD` | **Optional.** Override the auto-constructed operational-database URL. Use when pointing at an external Postgres or a non-standard host/port. | | `KNOWLEDGE_DATABASE_URL` | `postgresql://tale:${DB_PASSWORD}@knowledge-db:5432/tale_knowledge` | **Optional.** Connection URL the Convex backend uses for the knowledge corpus. Override to relocate the corpus to your own managed ParadeDB — the data-residency-sensitive store moves independently. | | `KNOWLEDGE_DB_NAME` | `tale_knowledge` | **Optional.** Name of the knowledge database. The bundled `knowledge-db` container creates this database on first boot. | The auto-constructed operational form is `postgresql://tale:${DB_PASSWORD}@db:5432`. Convex expects this URL without a database name; the name is derived from the instance configuration. The knowledge corpus lives in `tale_knowledge` with the `private_knowledge` and `public_web` schemas; the **Settings > Data residency** UI writes a richer per-store config than these raw variables, covered in [Data residency](/self-hosted/configuration/data-residency). ## Observability | Name | Default | Description | | --------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------- | | `SENTRY_DSN` | unset | Sentry DSN for error tracking. Leave unset to disable. Compatible with self-hosted GlitchTip and Bugsink. | | `SENTRY_TRACES_SAMPLE_RATE` | unset | Optional sample rate for performance traces (`0.0`–`1.0`). Default behaviour depends on the deployment. | | `METRICS_BEARER_TOKEN` | unset | Bearer token required to access the Prometheus `/metrics/*` endpoints. Leave unset to keep metrics endpoints unreachable from outside. | Setting `METRICS_BEARER_TOKEN` exposes two endpoints behind the token: `/metrics/platform` and `/metrics/convex` (Convex's 261 built-in metrics, which now carry the RAG and crawl timings as well). See [Observability config](/self-hosted/configuration/observability-config) for the scrape config. ## Provider secrets encryption | Name | Default | Description | | ------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | `SOPS_AGE_KEY` | unset | Inline age secret key. Encrypts `providers/*.secrets.json`. Default mode after `tale init`. Multiple keys are not supported inline. | | `SOPS_AGE_KEY_FILE` | unset | Path to a file with one or more age keys (one per line; `#` comments allowed). Required for key rotation. Mutually exclusive with the inline form. | When both age vars are unset, Tale stores `providers/*.secrets.json` as plaintext JSON at mode 0600. Reach this mode only when the host disk is encrypted at rest or the files are produced by external tooling (a Kubernetes Secret mount, a Vault template). Rotating an age key is appending the new key, re-saving each provider in the UI, then dropping the old key. See [Secrets with SOPS](/self-hosted/configuration/secrets-with-sops) for the full rotation walk. The env-var key source needs no environment-level switch: a provider credential can hold the _name_ of an environment variable instead of a stored key, as long as that name carries the reserved `TALE_PROVIDER_KEY_` prefix. The gate is fail-closed — any other name is rejected, so the field can never point at an unrelated deployment secret — and names are capped at 40 characters. Define the variable here or in your secret manager so both the platform and the Convex backend can read it; the full mechanism is documented in [Providers](/self-hosted/configuration/providers). A subscription-broker credential has a second, separate namespace for the secret Tale presents **to the broker**: that field takes an environment-variable name under the reserved `TALE_TOKEN_SOURCE_` prefix, capped at 60 characters. The two prefixes stay distinct on purpose — a broker secret is not a provider API key, and neither field can name a variable outside its own namespace. ## Feature flags Optional toggles for features not enabled by default. Each flag turns one feature on or off at boot; toggling requires a restart of the platform container. | Name | Default | Description | | ------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------- | | `TRUSTED_HEADERS_ENABLED` | `false` | Enables the trusted-headers auth mode (identity supplied by the reverse proxy). | | `FILE_EVENTS_ENABLED` | `false` | Enables file-watching events for the OneDrive-sync connector. | | `TALE_DEPLOYMENT_CONFIG_ADMINS` | unset | Comma-separated email allowlist of operators allowed to edit deployment data residency. Empty/unset = read-only for all admins. | ## Restart controller The opt-in `controller` sidecar powers the one-click **Apply & restart** button on the [Data residency](/self-hosted/configuration/data-residency) page: it bounces the `convex` container after a config change so the browser-facing platform never needs Docker-socket access. Enable it with `docker compose --profile controller up -d`, then set both variables below. Leave them unset to keep restarting `convex` by hand. | Name | Default | Description | | ------------------ | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `CONTROLLER_TOKEN` | unset | Shared HMAC secret for **Apply & restart**. The `controller` refuses to start without it, and the platform signs every restart request with it — the two values must match. Generate with `openssl rand -hex 32`. | | `CONTROLLER_URL` | unset | Base URL the platform uses to reach the `controller` sidecar (e.g. `http://controller:8004` on the internal network). With either this or `CONTROLLER_TOKEN` unset, **Apply & restart** shows the manual command. | ## RAG retrieval tuning Optional knobs for knowledge-base search. The in-process RAG path (Convex node-actions) re-scores results with a cross-encoder when re-ranking is on. All carry the `RAG_` prefix and are read by the `platform` and `convex` containers at boot; after changing one, run `docker compose restart platform convex` for it to take effect. | Name | Default | Description | | ---------------------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `RAG_RERANKING_ENABLED` | `false` | Re-scores the merged BM25 + vector candidates with a cross-encoder before results are returned. Improves precision at the cost of per-query latency. | | `RAG_RERANKING_MODEL` | `cross-encoder/ms-marco-MiniLM-L-6-v2` | Cross-encoder model identifier passed to the rerank provider. | | `RAG_RERANKING_PROVIDER` | `local` | Must be set to `api` to enable re-ranking — it posts the candidates to an external `/rerank` endpoint (Cohere/Jina-compatible). `local` is no longer supported and fails fast. | | `RAG_RERANKING_TOP_K` | `10` | Maximum number of results the reranker returns. The response never exceeds the request's own `top_k`. | | `RAG_RERANKING_CANDIDATES` | `30` | Size of the candidate pool fed to the reranker. A wider pool improves re-scoring quality and costs proportionally more time per query. | | `RAG_RERANKING_API_BASE_URL` | unset | Base URL for the rerank provider; the platform calls `{base_url}/rerank`. Required when re-ranking is enabled. | | `RAG_RERANKING_API_KEY` | unset | Bearer token sent to the external rerank endpoint. Leave unset for unauthenticated endpoints. | Re-ranking ships disabled because it adds per-query latency and depends on an external endpoint. Enable it — by setting `RAG_RERANKING_PROVIDER=api` and pointing `RAG_RERANKING_API_BASE_URL` at a hosted rerank service — when retrieval precision matters more than response time. There is no in-process model to download or cache; with re-ranking off, search returns the plain merged BM25 + vector ranking. ## Sessions | Name | Default | Description | | ------------------------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `SESSION_IDLE_TIMEOUT_MINUTES` | unset | **Optional.** Sign a session out after this many minutes of inactivity (`1`–`1440`). The window slides on activity and is enforced server-side across email/password, SSO, and trusted-headers sessions. | Leave it unset to keep the default session lifetime. When set, an idle session expires server-side once the window elapses, while an active one keeps sliding forward on each request. Org admins can tighten the effective window per organisation — never loosen it past this cap — via the [session idle timeout governance policy](/platform/admin/governance/policies-and-limits); idle sessions under that policy are revoked by a sweep that runs about every five minutes. ## Video-link ingestion (yt-dlp) When Tale ingests a video link, it fetches the transcript for the agent. YouTube blocks automated access from datacenter/server IPs, so this can fail on a cloud deployment. The deployment ships a PO-token provider wired up by default (see [Video ingestion](/self-hosted/configuration/video-ingestion) for the full picture); the options below are optional overrides and escalations. None guarantees a bypass — a clean egress IP is the single biggest lever. Read by the `convex` container and re-read on each ingestion, so a change takes effect without a restart. | Name | Default | Description | | -------------------------------- | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `VIDEO_INGEST_PROXY_URL` | unset | Route yt-dlp egress through a proxy (a residential/ISP IP works best; datacenter proxies are usually flagged too). Schemes: `http`, `https`, `socks4`, `socks4a`, `socks5`, `socks5h` — prefer `socks5h://` so DNS resolves at the proxy. | | `VIDEO_INGEST_POT_PROVIDER_URL` | `http://bgutil-provider:4416` (baked) | Base URL of the PO-token provider supplying the GVS tokens that dissolve YouTube's bot wall. Defaults to the `bgutil-provider` compose sidecar when the baked plugin is present — set only to point at a provider on another host. | | `VIDEO_INGEST_FETCH_POT` | `always` when a provider is wired | When yt-dlp requests PO tokens from the provider (`never`/`auto`/`always`). yt-dlp's own `auto` never fetches a token for the player request — exactly where the bot wall hits — so Tale defaults to `always` alongside a provider. `never` bypasses a misbehaving provider. | | `VIDEO_INGEST_YTDLP_PLUGIN_DIRS` | `/opt/yt-dlp/plugins` (baked) | Directory yt-dlp loads plugins from — each plugin nested one level down (`<dir>/<name>/yt_dlp_plugins/…`). Defaults to the baked-in bgutil plugin dir when present; override only to add your own plugins. | | `VIDEO_INGEST_COOKIES_FILE` | unset | Path to a Netscape cookie jar. Guest cookies from an incognito session raise the rate limit with no ban risk; account cookies unlock gated content but risk the account. | | `VIDEO_INGEST_PLAYER_CLIENT` | `default,tv_simply` | Comma-separated YouTube player-client fallback list. When a PO-token provider is wired the default widens to `default,mweb,tv_simply` (mweb needs a GVS token); set explicitly to force a list. | | `VIDEO_INGEST_PO_TOKEN` | unset | Manually pinned PO token (`CLIENT.CONTEXT+TOKEN`). Mainly for testing — tokens are video-ID-bound and short-lived; prefer the provider. | | `VIDEO_INGEST_IMPERSONATE` | unset | Browser TLS/JA3 impersonation target (e.g. `safari`). Requires `curl_cffi` in the image; leave unset unless you know it's available. | | `VIDEO_INGEST_BIN_DIR` | unset | Directory prepended to the yt-dlp/ffmpeg child's `PATH` so a self-provisioned `yt-dlp` (and its Deno runtime) installed outside the image's pinned bin dirs is found first. The `convex` image bakes yt-dlp into `PATH`, so leave it unset there; set it on a host or dev box running its own toolchain. | | `VIDEO_INGEST_FFMPEG_LOCATION` | `/usr/bin/ffmpeg` | Absolute path to the ffmpeg yt-dlp uses for post-processing (subtitle conversion, audio extraction). Override when ffmpeg lives elsewhere — e.g. Homebrew's `/opt/homebrew/bin/ffmpeg` on a macOS dev box. | None of these guarantees success against YouTube's adversarial detection. Ordinary public videos, less aggressive platforms, or a residential-IP/self-hosted deployment typically work without any of them. ## Where this fits The variables here are the operator's contact surface; the UI surface that consumes most of them lives under [Platform admin](/platform/admin/overview). Provider keys are the one half-and-half: the keys themselves live in `providers/*.secrets.json`, but the UI under **Settings > AI providers** is how you add and rotate them in practice. The next read worth queuing is [Providers](/self-hosted/configuration/providers) — it covers the shipped connector files and the reserved variables that hold provider keys. # Observability config Source: https://tale.dev/docs/self-hosted/configuration/observability-config Tale ships three observability seams: stdout logs from every container, Prometheus-format metrics behind a bearer token, and optional Sentry error reporting. The defaults are loud enough to spot a crash and quiet enough to fit in a single host's journald; the production knobs below add the structured paths your existing monitoring stack can scrape. None of the three send anything off-host unless you configure them to. This page covers the server-side switches. The operator-facing alert playbook lives in [Operations](/self-hosted/operate/observability/operations), and the symptom-first lookup in [Troubleshooting](/self-hosted/operate/observability/troubleshooting). ## Logs Every container writes structured JSON or console logs to stdout, captured by Docker's default `json-file` driver with a 10 MB-per-file, 3-file rotation. The log destination is a function of how you deploy: - Single host with journald — `journalctl -u docker` carries the lot. - Single host without journald — `docker compose logs -f <service>` for live tailing. - Aggregator (Loki, Vector, Fluent Bit) — point the Docker logging driver at it via `daemon.json`. Tale does not ship a log shipper. The driver swap is the supported connector point. ## Metrics The Caddy proxy exposes three metrics paths gated by a single bearer token: | Path | Source | What's inside | | -------------------- | --------------- | ----------------------------------------------------------------------------------- | | `/metrics/platform` | `tale-platform` | HTTP latency, route counters, Node process metrics, response-time SLA target gauges | | `/metrics/convex` | `tale-convex` | 261 built-in Convex metrics, plus the RAG and crawl timings | | `/metrics/sla-rules` | `tale-platform` | Generated Prometheus recording + alerting rules for the response-time SLAs | Knowledge work (RAG search, document ingestion, web crawling) runs inside the Convex backend now, so its timings ride the `/metrics/convex` series rather than a separate endpoint. Set `METRICS_BEARER_TOKEN` in `.env` to enable these endpoints; leave it unset to keep them returning 401 to every request. The `/metrics/sla-rules` path is a read-only YAML rules file you load into Prometheus, not a scrape target — the thresholds it carries are documented in [Operations](/self-hosted/operate/observability/operations). Anything other than the listed paths returns 401 too, so a misrouted scraper does not accidentally see the platform's internal health endpoints. A working Prometheus scrape stanza: ```yaml scrape_configs: - job_name: tale-platform scheme: https metrics_path: /metrics/platform authorization: credentials: <METRICS_BEARER_TOKEN> static_configs: - targets: ['tale.example.com'] ``` Duplicate the stanza per path, or use a single job with `relabel_configs` if you prefer. ## Error tracking with Sentry Sentry is opt-in via `SENTRY_DSN`. Self-hosted GlitchTip and Bugsink work too, since they speak the same DSN format. The platform and the convex containers both read the DSN and tag events with the container name. ```bash # .env SENTRY_DSN=https://your-key@your-sentry-host/project-id SENTRY_TRACES_SAMPLE_RATE=0.1 ``` The sample rate caps performance traces; leave it unset for the default 1.0 in development and tighten it (0.05–0.2) in production. Stack frames are sent unredacted, so point the DSN at infrastructure you control if your error payloads are sensitive. ## What does not ship yet OpenTelemetry traces are not built into the containers. The data is reachable indirectly — Convex action durations and HTTP route timings come through the Prometheus metrics — but there is no OTLP exporter on the box today. If you need full trace export, run an OpenTelemetry Collector alongside Tale and scrape the Prometheus endpoints from it. ## Where this fits The three seams above are the contact points with the rest of your monitoring stack; the alert thresholds and the oncall checklist live in [Operations](/self-hosted/operate/observability/operations). If something is on fire right now and you need the symptom-first index, jump to [Troubleshooting](/self-hosted/operate/observability/troubleshooting). # Providers Source: https://tale.dev/docs/self-hosted/configuration/providers An AI provider in Tale is two halves that live in two different places. The **connector** — the wire format, the endpoint, the model catalog source, the authentication methods a provider accepts — ships with the platform as a file you read but do not edit. The **credentials** are organisation data, created and rotated in the app under **Settings > AI providers**. This page is the operator's half: what the shipped files contain, and the one lever a deployment genuinely owns, which is holding provider API keys in environment variables. ## Where the connectors live Connector definitions are YAML files under `configs/platform/system/providers/`, one per provider, named for the provider's slug — `openrouter.yml`, `openai.yml`, `anthropic.yml`, `azure.yml`, and so on. They are part of the platform image and are upgraded with it. The matching built-in model catalogs sit beside them under `configs/platform/system/models/<slug>.yml`. <Warning> These files are read-only inputs, not deployment configuration. Editing one inside a running container is overwritten by the next upgrade, and there is no organisation-level override for them. When a provider you need is not in the shipped set, that is a platform change rather than a config change. </Warning> ## What a connector declares A connector is short by design. It names the provider, the wire dialect its API speaks, the endpoint it answers on, where its model list comes from, and which authentication methods it accepts — nothing organisation-specific and no secrets. <CodeGroup> ```yaml anthropic.yml name: anthropic displayName: Anthropic apiFormat: anthropic baseUrl: https://api.anthropic.com catalog: source: static auth: - method: api-key - method: env - method: subscription-broker constraints: execution: sandbox harness: claude-code ``` ```yaml openrouter.yml name: openrouter displayName: OpenRouter apiFormat: openai baseUrl: https://openrouter.ai/api/v1 catalog: source: openrouter-api auth: - method: api-key - method: env ``` </CodeGroup> `apiFormat` is the wire dialect — `openai` or `anthropic`. An `openai`-format connector may additionally declare `wireDialect: openai-modern`, as the shipped OpenAI and Azure connectors do: the platform then spells the output cap `max_completion_tokens` and holds a custom temperature back from reasoning models, because the current api.openai.com surface rejects `max_tokens` and non-default temperatures on those models — while third-party OpenAI-compatible endpoints keep the classic fields. `baseUrl` is the fixed endpoint; a connector that omits it declares `endpointMode: per-credential` instead, which is how Azure OpenAI works, since every Azure resource serves its own endpoint and each credential therefore carries its own URL. `catalog.source` is one of `static` (a shipped file under `configs/platform/system/models/`), `openrouter-api`, `models-endpoint`, or `none`. Each entry under `auth` is a method the provider's credentials may use, and a method may carry `constraints` that pin it to sandboxed execution on a named harness. ## Environment-variable key source If your API keys already live in Kubernetes Secrets, Vault, or a cloud secret manager, a credential does not have to hold the secret. The **Environment variable** authentication method stores only the _name_ of a deployment variable, and the platform reads the value from the process environment at call time. This is the ops-managed path: the key never enters the application database, and rotating it is a deployment concern rather than an admin task. The variable name is prefix-gated. It must begin with `TALE_PROVIDER_KEY_`, and the app fixes that prefix in the form so only the suffix is typed: ```bash TALE_PROVIDER_KEY_OPENROUTER=sk-or-... TALE_PROVIDER_KEY_OPENAI_PROD=sk-... ``` <Note> The gate is fail-closed: any name outside the reserved prefix is rejected, which is what stops a credential from naming an unrelated deployment secret such as `SOPS_AGE_KEY` or `BETTER_AUTH_SECRET` and having it sent as a bearer token to a provider endpoint. Names are capped at 40 characters, the limit of the platform-to-Convex environment sync — a longer name would silently never reach the backend runtime. </Note> Define the variable so that both the platform container and the Convex backend can read it. The platform syncs its environment to Convex at boot, so the in-process actions resolve the same value; a variable added or changed after boot needs a restart of the platform container before it is visible. Values are trimmed, which spares you the trailing newline a mounted secret file often carries and the `401` it produces. ## Broker secrets from the environment A **Subscription broker** credential authenticates to the broker before it can fetch a token pool, and that broker secret can come from the deployment too. Its variables carry their own reserved prefix, `TALE_TOKEN_SOURCE_`, kept separate from provider keys so the two namespaces cannot be confused for one another. The same fail-closed rule applies: a name outside the prefix is rejected. In the credential form the field is **Secret from environment variable**, and leaving it empty means the broker secret is stored encrypted with the credential instead. ## What is organisation data, not deployment config Credentials, their names, their model allowlists, which one is the default, and which are enabled are all organisation data. They are created in the app, they are scoped to one organisation, and there is no file on disk you edit to add one — including on a self-hosted instance. <Tip> That split is the quickest way to place a task. Anything about _which provider exists and what it can do_ is a shipped connector; anything about _who may call it and with what key_ is a credential in the app. The only overlap is the environment-variable key path, where the deployment holds the secret and the credential holds its name. </Tip> ## Where this fits An operator's whole surface here is provisioning environment variables and knowing which connectors the platform ships; everything else about providers happens in the app. The UI walkthrough — adding credentials, picking a default, narrowing an allowlist, refreshing catalogs — is [AI providers](/platform/admin/providers), what your users end up seeing is [Model catalog](/platform/models), and the variables themselves are listed alongside the rest of the deployment's configuration in the [environment reference](/self-hosted/configuration/environment-reference). # Retention Source: https://tale.dev/docs/self-hosted/configuration/retention Retention in Tale is the policy that deletes old data on a schedule — chats, documents, audit logs, workflow executions, token-usage ledger rows. The operator sets bounds (minimums and maximums) per category; each org's admin picks the actual retention window inside those bounds via **Settings > Governance > Retention policy**. The split exists so a hosting team can enforce compliance floors without micromanaging every tenant. This page covers the operator surface. The admin-facing controls and the per-category descriptions live in [Governance > Retention policy](/platform/admin/governance/policies-and-limits). ## How the bounds work Each retention category — chat threads, documents, contacts, vendors, prompt templates, ledger rows, audit logs, workflow executions, workflow trigger logs, login attempts — has a `min` and a `max`. An org admin sets a value inside that window. Tightening the floor across an existing instance is a multi-step flow: operator proposes the new bound, every affected admin sees a banner, the change applies once accepted. | Category | Typical floor | Why | | ----------------------- | ------------- | ---------------------------------------------- | | Chat history | 30 d | Most users want recent context, not forever | | Documents | 1 y | Knowledge tends to age out slowly | | Audit logs | 1 y minimum | Compliance frameworks expect a year | | Token-usage ledger | 90 d | Analytics and budget reports rely on rows | | Workflow execution logs | 30 d | Debugging rarely reaches further back | | Login attempts | 30 d | Brute-force investigation needs the audit tail | The shipped defaults are loose; tighten per your compliance posture. ## Where you set bounds Under the org-first layout, retention bounds are **per-org**: edit `retention.json` directly inside an org's subtree under `TALE_CONFIG_DIR` (defaults to `/app/data/` inside the platform container, so the file lives at `/app/data/<org>/retention.json`, e.g. `/app/data/default/retention.json`). Each org has its own file; the `default` org's file is the template a fresh deployment picks up on first boot. ```json { "chatHistory": { "min": 30, "max": 730, "unit": "days" }, "documents": { "min": 1, "max": 3650, "unit": "days" }, "auditLog": { "min": 365, "max": 3650, "unit": "days" }, "tokenLedger": { "min": 90, "max": 1095, "unit": "days" } } ``` The platform container watches the file; changes propose a bounds update for every existing org. Admins see the proposal in their **Retention policy** screen and apply it themselves. The propose-then-apply step is deliberate: tightening a floor shortens history, which is a destructive action no operator should land silently on every tenant. The admin-chosen retention windows live in a separate file, `retention-policy.json`, alongside the bounds in the same `governance/` folder. It holds flat `<category>Enabled` / `<category>RetentionDays` fields (e.g. `"auditLogEnabled": true, "auditLogRetentionDays": 730`), not the `min`/`max` bounds. That file is written by **Settings > Governance > Retention policy** in the app, so admins normally never edit it by hand — keep it distinct from the operator-owned bounds file. ## The retention sweep A scheduled cron inside `tale-convex` runs the actual deletion. Each category is swept independently — a slow run on one does not block the others. Deletions are audited (every category has its own `*.retention_deleted` event), and restoring an entity inside its grace window is possible from **Trash** before the final sweep. Audit log entries are themselves subject to retention, but their floor is enforced per-deployment, not per-org: the strictest (shortest) audit-log retention across all orgs is what actually runs. A stricter tenant pulls everyone tighter — keep this in mind on multi-tenant instances. ## Legal hold A legal hold freezes retention for a specific scope: a single thread, a contact record, or an entire organization. Held entities skip the sweep until the hold is released. The hold itself is audited; org-wide holds are loud enough that the UI surfaces a confirmation before they apply. ## Where this fits The bounds file is the operator's lever; the per-category windows the admin sees are documented in [Retention policy](/platform/admin/governance/policies-and-limits). If you are setting bounds against a compliance framework (GDPR, HIPAA, SOC 2), the audit-log floor is usually what auditors check first. # Secrets with SOPS Source: https://tale.dev/docs/self-hosted/configuration/secrets-with-sops Tale stores provider API keys in `providers/*.secrets.json` files on disk. The default mode after `tale init` encrypts these files with SOPS using an age key; an alternative mode reads multiple keys from a file (the rotation path); a third mode keeps the files in plaintext at file mode 0600 for environments where the disk is encrypted at rest and rotation is handled externally. This page is the operator's walkthrough of the three modes and the safe rotation path. The env vars that drive the modes are `SOPS_AGE_KEY` and `SOPS_AGE_KEY_FILE` — their reference rows live in [Environment reference](/self-hosted/configuration/environment-reference#provider-secrets-encryption). This page is the longer story. ## The three modes | Mode | Env vars | When to use | | ----------------- | ---------------------------------- | ------------------------------------------------------------- | | Inline age key | `SOPS_AGE_KEY=AGE-SECRET-KEY-1...` | Default after `tale init`. Single host, single key. | | Key file | `SOPS_AGE_KEY_FILE=/path/to/keys` | Required for rotation. One age key per line, `#` comments. | | Plaintext at 0600 | Both unset | Disk encrypted at rest, or external tooling writes the files. | The platform container picks the mode at boot. The inline form is the simplest; the file form is the only one that supports multiple readers (which is what makes rotation possible without downtime); the plaintext form skips SOPS entirely and trusts the filesystem. ## First-boot encrypted mode `tale init` generates an age keypair and writes the private half into `SOPS_AGE_KEY` in your `.env`. Provider secret files written through **Settings > Providers** are encrypted on save: ```bash # Inspect — the file is SOPS-encrypted JSON, not the cleartext API key cat providers/openai.secrets.json # { # "apiKey": "ENC[AES256_GCM,data:...,iv:...,tag:...]", # "sops": { ... } # } ``` Decryption happens in-process when the platform container reads the file. The age key never leaves the platform container's memory. ## Rotating the age key Rotation is the one path the inline form does not cover — only `SOPS_AGE_KEY_FILE` lets you accept ciphertext readable by both the old and the new key during the cutover. The walk: ```bash # 1. Generate a new age key age-keygen -o /etc/tale/age-keys.txt # 2. Append the new key as a second line in the file echo "AGE-SECRET-KEY-1NEW..." >> /etc/tale/age-keys.txt # 3. Point .env at the file and restart the platform container sed -i 's|^SOPS_AGE_KEY=.*|# SOPS_AGE_KEY=|' .env sed -i 's|^# SOPS_AGE_KEY_FILE=.*|SOPS_AGE_KEY_FILE=/etc/tale/age-keys.txt|' .env docker compose restart tale-platform tale-convex ``` Now both old and new keys can decrypt existing files. Re-save each provider's API key under **Settings > Providers** — each save produces ciphertext readable by both keys. Once every provider has been re-saved (the **Last rotated** column in the providers table tells you which still hold old ciphertext), remove the old key from the file: ```bash # 4. Drop the old key line and restart again sed -i '/^AGE-SECRET-KEY-1OLD/d' /etc/tale/age-keys.txt docker compose restart tale-platform tale-convex ``` The order is load-bearing: never remove the old key before every file is re-encrypted, or the platform container will fail to read the still-old files at the next decryption. ## Switching to plaintext When the host disk is encrypted at rest (LUKS, AWS EBS encryption, GCP CSEK) and you do not want a second layer of key management, the plaintext mode is the supported option. Comment out both `SOPS_AGE_KEY` and `SOPS_AGE_KEY_FILE`, restart, and re-save each provider — the files are now JSON at mode 0600. The risk model shifts: a leaked filesystem dump is now a leaked credential dump. Pick this mode only when the disk encryption is real (not a tickbox), and audit the host's backup story to confirm no plaintext snapshot escapes. ## External secret stores When your keys already live in Vault, a cloud secret manager, or Kubernetes Secrets, the first-class pattern is the env-var key source: point each provider at an **environment variable** with `secretsEnv` and let your secret store populate that variable. No cleartext file touches the disk, and the reserved-prefix gate keeps a config-write actor from reading an unrelated deployment secret. The full mechanism — the `TALE_PROVIDER_KEY_` prefix gate, resolution order, and the restart-on-change behaviour — lives in [Providers](/self-hosted/configuration/providers#environment-variable-key-source). The file-mount approach is the legacy alternative: write the cleartext `*.secrets.json` files from the external store and run Tale in plaintext mode. It still works, but it puts the cleartext key on disk and breaks if you save a provider through the UI — the UI overwrites the mount. Prefer the env-var source unless a constraint forces the file form. ## Where this fits This page is the operator's full guide to the SOPS layer; the env-var reference rows are in [Environment reference](/self-hosted/configuration/environment-reference#provider-secrets-encryption), and the provider file format itself in [Providers](/self-hosted/configuration/providers). If a key is leaked, rotation is the same walk above run urgently. # TLS and domains Source: https://tale.dev/docs/self-hosted/configuration/tls-and-domains The `tale-proxy` container is Caddy. It owns TLS termination, host routing, and the metrics auth gate; every browser-facing request lands here first. The three modes — self-signed, Let's Encrypt, external — cover the three deployment shapes most operators reach for, and the variable that switches between them is `TLS_MODE` in your `.env`. The env-var reference rows live in [Environment reference](/self-hosted/configuration/environment-reference#tls). This page is the per-mode walkthrough and the recipes for custom domains and bring-your-own certificates. ## Self-signed (default) `TLS_MODE=selfsigned` runs Caddy with a certificate it generates from its internal CA. The browser warns the first time, and the host needs to trust the cert to suppress the warning — that is intended for local development: ```bash docker exec tale-proxy caddy trust ``` The trust command imports Caddy's CA into the system trust store on the host running the docker daemon. Other machines on the network still see the warning unless they import the CA too. Production never uses this mode. ## Let's Encrypt `TLS_MODE=letsencrypt` lets Caddy issue and renew a real public certificate. Three prerequisites must hold or the issuance loop fails: - The hostname in `HOST` and `SITE_URL` resolves to the host's public IP from the public Internet. - Ports 80 and 443 are reachable from the public Internet (port 80 carries the ACME HTTP-01 challenge). - `TLS_EMAIL` is set to a mailbox you read — Let's Encrypt warns there before expiry. ```bash # .env TLS_MODE=letsencrypt TLS_EMAIL=ops@yourdomain.com ``` The first boot blocks for about a minute while the ACME challenge runs. After that, renewals are automatic 30 days before expiry; failures land in `docker compose logs proxy`. ## External proxy `TLS_MODE=external` makes Caddy serve plain HTTP on the inside, and you front it with your own reverse proxy that terminates TLS upstream. Pick this when: - You already run a CDN or load balancer that handles certificates. - You want to terminate TLS once at the edge of your VPC and run everything internal as plaintext. - Your compliance posture requires a specific certificate authority that Caddy does not support. ```bash # .env TLS_MODE=external SITE_URL=https://tale.yourdomain.com # the URL your users hit ``` The upstream proxy needs `X-Forwarded-Proto: https` set on every request so Tale generates correct redirects and absolute URLs. Without it, sign-in links land on `http://` and the auth cookie's `Secure` flag rejects them. ## Custom domain The domain itself is just `HOST` and `SITE_URL`. The same Caddyfile inside `tale-proxy` reads both at boot. Change them, recreate the proxy container (`docker compose up -d --force-recreate tale-proxy`), and the new domain is live within seconds. Let's Encrypt re-issues for the new name on the next request that hits the new hostname. ```bash # .env HOST=tale.example.com SITE_URL=https://tale.example.com ``` Subpath deployments — Tale behind `https://example.com/app/` — set `BASE_PATH=/app` in addition. The reverse proxy upstream of Caddy strips nothing; Tale handles the prefix itself. ## Bring-your-own certificate For an internal CA or a wildcard cert you already own, mount the cert and key into `tale-proxy` and add a `tls` directive to the Caddyfile: ```yaml # compose.yml override services: proxy: volumes: - ./certs/fullchain.pem:/etc/tale/cert.pem:ro - ./certs/privkey.pem:/etc/tale/key.pem:ro environment: TLS_MODE: external # bypasses Caddy's auto-issuance ``` Then either pre-build a `tale-proxy` image with the custom Caddyfile, or front Tale with your own reverse proxy and stick with `TLS_MODE=external` — both paths are supported and the second is simpler. ## Where this fits The three modes cover the three deployment shapes most teams hit; the env-var rows live in [Environment reference](/self-hosted/configuration/environment-reference#tls). If you are setting up a fresh production host right now, [Production Linux server install](/self-hosted/install/linux-server) walks Let's Encrypt end-to-end with the firewall and DNS steps in order. # Video ingestion Source: https://tale.dev/docs/self-hosted/configuration/video-ingestion When Tale ingests a video link, it fetches the video's transcript with `yt-dlp`. Video platforms — YouTube most aggressively — challenge requests from datacenter and server IPs with a "confirm you're not a bot" wall, so a fresh self-hosted deployment on a cloud VM can see ingestion fail where a laptop on a home connection would succeed. This page covers the three layers Tale ships to get past that, from the one that needs no configuration to the one that needs the most. <Info> Managed **Cloud** deployments run these measures for you — this page is for operators running Tale on their own infrastructure. </Info> ## Layer 1 — the PO-token provider (default, no config) The single most effective measure is a **proof-of-origin (PO) token**: a signed value that makes a request look like it came from a real browser session. Tale ships a token provider wired up out of the box — the `yt-dlp` plugin is baked into the image and a `bgutil-provider` sidecar serves the tokens over the internal network. No environment variable is required; a fresh `docker compose up` or `tale deploy` has it running. You can point `yt-dlp` at a provider on a different host with `VIDEO_INGEST_POT_PROVIDER_URL`, or supply a manually-minted token with `VIDEO_INGEST_PO_TOKEN` — both are documented in the [environment reference](/self-hosted/configuration/environment-reference). The sidecar being down never breaks the stack: ingestion simply falls back to no token, exactly as if the layer were absent. ## Layer 2 — an egress proxy When the token alone is not enough — some IP ranges are flagged regardless — route the fetch through an **egress proxy** on an IP the platform trusts. Residential and ISP-hosted proxies work best; datacenter and commercial proxies are often flagged just like the server itself. Set `VIDEO_INGEST_PROXY_URL` to the proxy URL. A `socks5h://` scheme resolves DNS at the proxy (the safest choice); `http`, `https`, `socks4`, `socks4a`, `socks5`, and `socks5h` are all accepted. The value can carry credentials — Tale scrubs them from every log line. ```bash .env VIDEO_INGEST_PROXY_URL=socks5h://user:pass@residential.example:1080 ``` The proxy applies to every phase of a fetch — metadata, captions, and audio — so the whole ingest shares one trusted egress path. ## Layer 3 — the pre-warmed browser-session pool The strongest measure is to present cookies from a **real browser session that has already cleared the bot check**. Tale keeps a pool of these sessions, keyed by domain, and hands one to each fetch so the platform sees a returning visitor rather than a first-touch server. Sessions are stored encrypted at rest (the cookie jar is sealed with the deployment's `ENCRYPTION_SECRET_HEX`) and are never exposed to agent-executed code — they live only in the server-side fetch layer. A session that starts getting blocked is cooled and then retired automatically, and expired sessions are swept on a schedule. Populating the pool is an advanced, hands-on step: capture a Netscape cookie jar from a browser that has solved the challenge for the target platform, then import it through the `importBrowserSession` internal action. The same pool also backs the agent's web-fetch tool and crawler, so a session warmed for a domain benefits every server-side reach-out to it. <Warning> Account cookies unlock gated content but put the account at risk if the platform flags automated use. Prefer cookies from a throwaway or purpose-made account, and never commit a cookie jar to source control. </Warning> ## Which layer do I need? <CardGroup cols="2"> <Card title="Just deployed, some videos fail" icon="circle-play"> Layer 1 is already on. Retry — many blocks are transient. Move to Layer 2 only if failures persist. </Card> <Card title="Most videos fail on this host" icon="globe"> The deployment's IP is likely flagged. Add an egress proxy (Layer 2) on a residential IP. </Card> <Card title="A specific platform still blocks you" icon="key-round"> Warm a browser session for that platform (Layer 3) so the fetch presents cleared cookies. </Card> <Card title="Full variable reference" icon="settings"> Every `VIDEO_INGEST_*` knob, with defaults, lives in the [environment reference](/self-hosted/configuration/environment-reference). </Card> </CardGroup> ## An honest expectation None of these layers can guarantee ingestion against a platform actively working to block automated access from arbitrary IPs. Together they make ingestion succeed wherever your egress is trusted, and every deployment has a supported path to escalate. If a platform hard-blocks your server, the transcript can still be brought in by hand — paste it into a [Knowledge](/platform/knowledge/documents) document. # Contributing to Docker images Source: https://tale.dev/docs/self-hosted/contributing-docker Every container Tale ships has its Dockerfile in the public source repo. Forks, air-gapped distributions, and one-off patches all start from the same files; this page is the operator's walk through building the images yourself, where the customisation seams live, and how to keep a fork in sync with upstream without diverging on the boring parts. The container architecture lives at [Container architecture](/self-hosted/operate/container-architecture); this page is what you read when the published images do not fit and you need to build your own. ## What the images are The stack is entirely TypeScript — no Python image. Each image has one Dockerfile under `services/<name>/`: | Image | Source path | Base | | ------------------------ | ----------------------------- | ---------------------------- | | `tale-proxy` | `services/proxy/` | Caddy | | `tale-platform` | `services/platform/` | Bun + Debian slim | | `tale-convex` | `services/convex/` | Convex local-backend | | `tale-db` | `services/db/` | ParadeDB (Postgres) | | `tale-sandbox` | `services/sandbox/` | Bun + Docker CLI | | `tale-sandbox-egress` | `services/sandbox-egress/` | Alpine + tinyproxy | | `tale-sandbox-runtime` | `services/sandbox-runtime/` | Bun + Chromium + Playwright | | `tale-sandbox-buildkitd` | `services/sandbox-buildkitd/` | Debian + BuildKit + redsocks | | `tale-controller` | `services/controller/` | Bun + Docker CLI | Both database containers — `db` and `knowledge-db` — build from the same `tale-db` ParadeDB image; the difference is the database each one serves. The LLM gateway, `tale-sandbox-llm-gateway`, is a pinned upstream image (`maximhq/bifrost`), so it has no Dockerfile in the repo. The compose files at the repo root (`compose.yml` for development, the CLI-generated production compose) reference these by `ghcr.io/tale-project/tale/<image>:<tag>`. A local build replaces the registry pull with a `build:` block in compose. ## Building locally A first build of every image takes about 15 minutes on a recent laptop; subsequent builds hit Docker's layer cache and finish in under a minute for the image you changed. ```bash # Build every image in compose.yml docker compose build # Build one image docker compose build platform ``` Set `PULL_POLICY=build` in your environment (or in `.env`) to force compose to build rather than pull the published image. The shipped `compose.yml` defaults to `build`, so a local clone with no overrides already builds; production compose files generated by `tale deploy` default to `always` and pull from the registry. ## The customisation seams The supported extension points for forks are at the Dockerfile level. The image's entrypoint and the configuration files inside it are stable — patch them, build the image, and the rest of the system does not need to know. - **Caddyfile** — `services/proxy/Caddyfile` controls routing and TLS termination. Custom headers, custom subdomains, and custom rate limits land here. - **Platform plop templates** — `services/platform/Dockerfile` runs a build step that bakes in the messages, the schema, and the static assets. A fork that ships custom UI strings or extra routes builds the platform image. - **Sandbox runtime image** — `services/sandbox-runtime/Dockerfile` is the execution environment for `Run code`, web rendering, and document generation; it already carries Chromium and Playwright. A fork that needs an extra system package or a different browser build patches here. - **Sandbox egress proxy** — `services/sandbox-egress/tinyproxy.conf.template` is the proxy config the entrypoint renders at startup: open egress by default, or a default-deny hostname filter when `SANDBOX_EGRESS_ALLOWLIST` is set. A fork that needs different proxy behaviour patches here. What is not a supported seam: the convex backend's application code, including document extraction and the RAG and crawler logic that now live in-process (`services/platform/convex/`), and the platform container's runtime code (`services/platform/app/`). Those files are application code, not configuration — adding a document-format extractor or changing retrieval behaviour is a real fork and rides the upgrade tax. ## Tagging and pushing your own registry For air-gapped or vendored distributions, the path is "build, tag, push to your registry, change the compose `image:` lines." ```bash # Build, tag, push export REGISTRY=registry.internal.example.com/tale docker compose build docker tag ghcr.io/tale-project/tale/tale-platform:latest \ $REGISTRY/tale-platform:vendored-1.0 docker push $REGISTRY/tale-platform:vendored-1.0 ``` The CLI's deploy generates a compose file with the registry path; either patch the generated file post-generation, or skip the CLI and run `docker compose` directly against a compose file you maintain yourself. ## Staying in sync with upstream The cheap path is a fork on GitHub that periodically merges from `tale-project/tale@main`. Conflicts land in the files you patched; the rest carries through clean. The two anti-patterns: - **Patching application code instead of contributing it back.** If the change is broadly useful, upstream a PR — every release tax goes down. - **Pinning to an old base image.** The Caddy, Bun, and Postgres bases pick up security patches on rebuild; pinning the base for "stability" is borrowing trouble. ## Where this fits This page is the contributor-facing seam of the operator story. The architecture overview lives in [Container architecture](/self-hosted/operate/container-architecture); the upgrade workflow that runs the published images is in [Upgrades](/self-hosted/operate/upgrades). If your fork is non-trivial, the conversation worth starting before you write code is the one on the project's Discord or GitHub Discussions — many forks end up being features waiting to land upstream. # Self-hosted Source: https://tale.dev/docs/self-hosted Self-hosted Tale runs on your own infrastructure — on-premises, in your VPC, or air-gapped. Seven containers, your data on your disk, no per-seat billing, and no traffic that crosses to Tale's servers unless you point a provider at one. This section is for operators: the people who decide where Tale runs, install it, configure it, keep it patched, and pick up the pager when something goes wrong. End users of self-hosted instances mostly read the Platform tab — the product surface is identical between editions. ## Pages in this section **[Architecture overview](/self-hosted/overview)** — what each container does, where data lives on disk, what talks to what. **[Install](/self-hosted/install/quickstart)** — quickstart on a laptop, production install on a Linux host, the docker compose reference, first admin setup, the CLI installer. **[Configuration](/self-hosted/configuration/environment-reference)** — every environment variable, provider files, authentication modes, TLS, storage, retention, SOPS-encrypted secrets, observability. **[Operate](/self-hosted/operate/container-architecture)** — upgrades, backups and restore, observability and troubleshooting, security advisories, hardening, release notes format. **[Contributing](/self-hosted/contributing-docker)** — how to build and test a local container change. ## Where this fits Self-hosted is the edition where the operator owns more of the stack. If your team is small and the operational overhead would crowd out product work, [Cloud](/cloud) is the other shape of the same product. If you're standing up a fresh instance right now, [Quickstart](/self-hosted/install/quickstart) is the right next read. # Install the tale CLI Source: https://tale.dev/docs/self-hosted/install/cli-install The `tale` CLI is the recommended way to run and operate Tale. The [quickstart](/self-hosted/install/quickstart) already uses it to stand an instance up locally with `tale init` and `tale dev`; this page is the other half — installing the CLI on a workstation so it can drive a _remote_ instance: deploying new versions, running migrations, and capturing diagnostics without you remembering every `docker compose` invocation. Everything the CLI does can also be done with `docker compose` and `ssh` directly, so a team already deep in its own automation can stay on compose. For everyone else the CLI is the shorter path, and the rest of the self-hosted docs assume it is installed. ## Before you begin You need: - A workstation running macOS, Linux, or Windows 10+. - SSH access to the host your Tale instance runs on, with the operator user able to run `docker compose`. The installer downloads a release binary from GitHub. Corporate networks that block raw-content downloads need to allow `raw.githubusercontent.com` and `github.com`. ## Step 1 — Run install-cli.sh or install-cli.ps1 On macOS or Linux: ```bash curl -fsSL https://raw.githubusercontent.com/tale-project/tale/main/scripts/install-cli.sh | bash ``` On Windows PowerShell: ```powershell irm https://raw.githubusercontent.com/tale-project/tale/main/scripts/install-cli.ps1 | iex ``` Both installers detect the OS and CPU architecture, pull the matching release binary from the latest GitHub release, and drop it on the `PATH` (`/usr/local/bin/tale` or `%LOCALAPPDATA%\Programs\tale\tale.exe`) — asking for `sudo` when the install directory is not writable. Release binaries ship for macOS on Apple Silicon and Intel, and for Linux on x86_64 and arm64; Windows-on-ARM machines run the x64 binary through the built-in emulation. On an architecture without a released binary, the installer exits with a clear message and points you at building from source. To pin a version, set the `VERSION` environment variable before piping into the installer; to pick the install directory yourself, set `INSTALL_DIR`. | OS | Installer script | | ------- | ------------------------- | | macOS | `scripts/install-cli.sh` | | Linux | `scripts/install-cli.sh` | | Windows | `scripts/install-cli.ps1` | ## Step 2 — Verify ```bash tale --version ``` The CLI prints its version. If the command is not found, the installer dropped the binary outside the `PATH` — the installer output names the destination directory. ## Step 3 — Confirm configuration There is no `tale config set` — everything the CLI needs lives in the project that `tale init` created. Run any `tale` command from inside that directory (the CLI walks up the tree to find `tale.json`), and confirm it resolves: ```bash tale config show ``` The host the proxy answers on, TLS settings, and every secret live in the project's `.env`. To change the host, edit `HOST` there or pass `--host` to `tale dev` / `tale deploy`. To operate a remote host, point your shell's Docker context (or `DOCKER_HOST`) at it — the CLI talks to the same Docker endpoint every `docker` command does. The Convex dashboard admin key is separate from CLI configuration — it never gates sign-up, and it is deterministic (derived from `INSTANCE_NAME` and `INSTANCE_SECRET`, so it stays the same across restarts). Generate it with `tale convex admin` when you want to inspect the backend (see [First admin](/self-hosted/install/first-admin)). ## Step 4 — Run tale deploy ```bash tale deploy ``` `tale deploy` always ships the CLI's own version: it pulls that version's images, restarts the affected containers in the right order, and runs schema migrations — `tale update` is how you move to a different version first. It is the supported replacement for the longer `docker compose pull && docker compose up -d` dance. If you prefer compose directly, the same effect lives in [Upgrades](/self-hosted/operate/upgrades). ## Command reference The CLI groups its commands by what you are doing, the same way `tale --help` does. Each command and its arguments are listed below. How to read the notation: - A positional argument in `[square brackets]` is **optional**; one in `<angle brackets>` is **required**. - Every flag is **optional** — omit it to get the default behaviour. - A flag written `--flag <value>` **requires a value** when you use it (e.g. `--port 8443`); a bare flag like `--detach` is a boolean switch. - **Defaults** are shown in parentheses after the description. No default means the flag is off, or the command resolves the value from `.env` / context. Run `tale <command> --help` for the authoritative list at your installed version. **Global flags** work on every command: - `--verbose` — verbose output: debug logs and the raw subprocess stream (long form only; there is no `-v`). - `-q, --quiet` — only warnings and errors. - `-y, --yes` — assume "yes" for all prompts (non-interactive). - `--no-color` — disable ANSI colour (also honours `NO_COLOR` / `FORCE_COLOR`). - `--json` — machine-readable JSON on stdout, human messages on stderr; supported by `status`, `config show`, and `migrate status`. - `--ci` — force non-interactive, append-only output (no cursor control). Commands exit `0` on success, `2` on a usage error, `3` on an unmet precondition (no project, Docker not running, port in use), `4` on a user abort (Ctrl-C, or a required prompt with no terminal), and `5` on an external-dependency failure — so scripts can branch on the cause. ### Setup `tale init [directory]` — create a project: it scaffolds the example configs, `AGENTS.md` + a `CLAUDE.md` pointer, and a local-default `.env` (localhost, self-signed certificate, generated secrets). No Docker is needed, and the production domain and TLS are chosen later, at `tale deploy`. In a terminal it asks for a project name when `directory` is omitted, confirms before overwriting an existing project, and asks once whether agents may run `docker` inside sandboxes (default: no — enabling it runs a privileged inner Docker); non-interactive runs skip all prompts. `directory` is optional (default: the current directory). - `-f, --force` — overwrite an existing `tale.json` instead of aborting. - `--no-env` — scaffold the project but skip `.env` generation. `tale dev` — launch all services locally with a self-signed certificate. - `-d, --detach` — run in the background instead of streaming logs. - `-p, --port <port>` — HTTPS port to expose (default `443`). - `--host <hostname>` — host alias for the proxy (default `localhost`). - `-y, --yes` — non-interactive: auto-accept prompts (e.g. installing or starting Docker). `tale deploy` — blue-green, zero-downtime deploy of the current CLI version. On the first deploy it prompts for your production domain and Let's Encrypt email (or pass `--host`). - `--stop` — also update the stop-gated tier (`db`, `proxy`) — recreates those containers, so accept a brief downtime; without it, running `db`/`proxy` are left untouched. - `-s, --services <list>` — update only these comma-separated services (default: all rotatable services). - `--host <hostname>` — host alias for the proxy (default: the `HOST` value from `.env`). - `--override` — overwrite container config from the host workspace (encrypted `*.secrets.json` and `.history/` are always preserved). - `--override-all` — factory-reseed the builtin catalog into every org server-side; implies `--stop`. - `-q, --quiet` — suppress container logs during the deploy. - `-y, --yes` — auto-accept destructive confirmation prompts (e.g. `--override-all`). - `--skip-backup` — skip the automatic pre-deploy volume snapshot. - `--dry-run` — preview what would change without touching anything. ### Operate `tale status` — show the current deployment status. No arguments. `tale logs <service>` — stream a service's logs (`service` is one of the running services; on a dev-only stack with no deployment, it falls back to the dev container). - `-f, --follow` — follow log output as it is written. - `-n, --tail <lines>` — show only the last N lines. - `--since <duration>` — show logs since a relative time (e.g. `1h`, `30m`). - `-c, --color <color>` — target a specific deployment colour (`blue` or `green`). - `--raw` — stream raw, unfiltered log output (no classification). `tale backup` — snapshot all data volumes into the project backups volume. No arguments. `tale restore [snapshot-id]` — restore a snapshot; omit the id to list available snapshots. - `--stop` — stop running project containers before restoring. - `-y, --yes` — skip the confirmation prompt. `tale rollback` — roll back to the previous patch version (patch-level only). Prompts for confirmation before it touches anything. - `-y, --yes` — skip the confirmation prompt (required when running non-interactively). ### Maintain `tale update` — move this Tale instance to a new version: update the CLI binary, then sync project files to that version's templates. Run `tale deploy` afterwards to roll the containers. The CLI also self-aligns to the instance version on every command, so this is only needed to deliberately change versions. - `-v, --version <version>` — update to this exact version (e.g. `0.9.0`) instead of the latest; allows downgrades. - `-f, --force` — force re-sync and overwrite locally modified project files. - `--dry-run` — show what would change without modifying anything. `tale migrate` — re-provision the built-in defaults and apply the safe pending data migrations against the running deployment — the same idempotent steps every deploy runs, on demand. The subcommands give granular, reversible control: `migrate status` shows applied and pending migrations, `migrate up [--to <version>]` applies pending ones (destructive steps need `-y, --yes` or `--step`), and `migrate down --to <version>` rolls back. `tale cleanup` — remove inactive (non-current colour) containers. No arguments. `tale reset` — remove all blue-green containers. - `-f, --force` — skip the confirmation prompt. - `-a, --all` — also remove the stateful infrastructure containers. - `--dry-run` — preview the reset without making changes. `tale uninstall` — remove the `tale` CLI binary from this system. It prompts before deleting anything and _offers_ to also remove the per-user config (`~/.tale-daemon`) and tear down a project's Docker resources and files. Without `--purge`, a project and its containers are left intact — run `tale reset --all` inside one to remove those. - `-f, --force` — skip the confirmation prompt (removes the binary only; the optional cleanups still need `--purge`). - `--purge` — also remove `~/.tale-daemon` and, for a project found from the current directory, tear down its Docker resources and delete its files. Irreversible. - `--dry-run` — show what would be removed without removing anything. `tale config` — manage CLI configuration. Use the `show` subcommand to print the resolved config. ### Advanced `tale auth reset-owner` — reset the owner account credentials. - `-e, --email <email>` — set a new owner email address. - `-p, --password <password>` — set a new owner password. `tale convex admin` — generate a Convex dashboard admin key. No arguments. ## Troubleshooting - **`tale deploy` targets the wrong machine.** The CLI uses your shell's Docker context / `DOCKER_HOST`. Switch with `docker context use …` (or set `DOCKER_HOST`) so it points at the intended host, then re-run. - **`tale deploy` uses the wrong host alias.** The host the proxy answers on comes from `HOST` in the project's `.env`, not a separate CLI store. Edit `.env` or pass `--host` to override it for one run. - **The Convex dashboard rejects the admin key.** Sign-up never asks for the key — only the dashboard does. The key is deterministic (derived from `INSTANCE_NAME` and `INSTANCE_SECRET`), so a rejection usually means those values differ between the platform and Convex services, or the deployment URL is wrong — use `SITE_URL`. Regenerate with `tale convex admin` to be sure you copied the current value. - **Installer fails on macOS because the binary cannot execute.** When the freshly installed binary refuses to run (e.g. Gatekeeper kills it), the installer fails with recovery hints instead of reporting success — follow them, then re-run the installer. - **`tale` not found after install on Linux.** The installer drops the binary in `/usr/local/bin`; verify the directory is on the user's `PATH` (`echo $PATH`). ## Where this gets used Once the CLI is wired up, the operator's daily surface shrinks to a handful of subcommands. The pages worth reading next depend on what you came to do — [Upgrades](/self-hosted/operate/upgrades) for version bumps, [Backups and restore](/self-hosted/operate/backups-and-restore) for snapshot drills, [Container architecture](/self-hosted/operate/container-architecture) for what the CLI restarts when it deploys. # Docker Compose reference Source: https://tale.dev/docs/self-hosted/install/docker-compose-reference Tale ships a handful of Docker Compose files. The base is `compose.yml`; the rest are overlays that add or replace services for specific scenarios — development, docs, test. This page names each file, says when to pick it, and gives the layering rule everything else follows. The shape is conservative on purpose. The base file alone runs production; every overlay is opt-in via `-f` and adds only what it needs to. Memorise the base and a single overlay, not the whole grid. ## A worked compose-up A production single-host instance runs from the base alone: ```bash docker compose up -d ``` A developer hacking on platform and docs at the same time layers two overlays: ```bash docker compose -f compose.yml -f compose.dev.yml -f compose.docs.yml up -d ``` The leftmost file is the base; each subsequent file merges its keys on top. Conflicts (same service, same key) resolve last-file-wins. The merged graph is what Docker brings up. ## The compose files | File | Use case | Notable overrides | | ----------------------- | ---------------------------------------------- | --------------------------------------------------------------------- | | `compose.yml` | Production single-host | The base — every service, healthchecks, restart policy | | `compose.dev.yml` | Local development with hot-reload | Mounts source into containers, swaps to dev images, exposes dev ports | | `compose.docs.yml` | Adds the docs site service | Brings up `tale-docs` and routes `/docs` through the proxy | | `compose.web.yml` | Adds the marketing site service | Brings up `tale-web` and routes `/` (root) through the proxy | | `compose.test.yml` | Runs the platform test suite against the stack | Replaces the platform image with the test-shaped variant | | `compose.web.test.yml` | Runs web tests | Like `web.yml` but the test-shaped variant | | `compose.docs.test.yml` | Runs docs tests | Like `docs.yml` but the test-shaped variant | | `compose.test.mock.yml` | Mock-backed integration tests | Swaps providers for mock implementations | ## Services and their roles The base graph brings up eight containers: - `tale-proxy` — Caddy. TLS, reverse proxy, 301s. - `tale-platform` — the TanStack Start app. The user-facing UI and API. - `tale-convex` — the Convex backend. WebSocket, queries, mutations, actions — and the in-process RAG search, document ingestion, web crawling, and document generation that used to be separate services. - `tale-db` — operational Postgres (ParadeDB). The Convex backend's persistent store. - `tale-knowledge-db` — knowledge corpus Postgres (ParadeDB). The `tale_knowledge` database holding document chunks, embeddings, and crawled pages, on port 5433 so it never clashes with `tale-db` on 5432. - `tale-sandbox-llm-gateway` — the LLM gateway for harness turns (pinned external image). - `tale-sandbox-egress` and `tale-sandbox` — the sandbox plane. Run-code containers behind an egress proxy (open by default; lock down with `SANDBOX_EGRESS_ALLOWLIST`), also the headless-browser runtime the convex backend calls for web rendering and document generation. The stack is now entirely TypeScript — there is no Python service in the graph. [Container architecture](/self-hosted/operate/container-architecture) goes deeper on what owns what. ## Overriding Operator customisations belong in an extra overlay, not in edits to the shipped files. Create `compose.local.yml` with the overrides you need: ```yaml services: platform: environment: - LOG_LEVEL=debug ``` Bring the stack up with the local overlay layered last: ```bash docker compose -f compose.yml -f compose.local.yml up -d ``` This pattern keeps `git pull` clean — no merge conflicts on the shipped files. The same pattern works for any custom volume mount, custom port, or environment override. ## Profiles One service in the base file uses a Docker Compose profile. Profiles let a service exist in the graph but not start unless its profile is activated. The profile in use is `controller` — the opt-in `tale-controller` sidecar that restarts the convex container on a signed request so a data-residency change applies without giving the platform Docker-socket access. Activate it with: ```bash docker compose --profile controller up -d ``` ## Where this fits The compose reference is the operator's grid for the source tree. For the inside of each container, the [container architecture](/self-hosted/operate/container-architecture) page covers responsibilities; for the variables the containers read at boot, the [environment reference](/self-hosted/configuration/environment-reference) is the source of truth. # Create the first admin Source: https://tale.dev/docs/self-hosted/install/first-admin A brand-new Tale instance has no users. The first person to open it runs a one-time setup wizard that creates their account, signs them in, makes them the **Owner**, and names the first organization — no bootstrap key, no manual promotion. This walk covers that first run, how teammates join afterward, and where to get the Convex dashboard admin key if you ever need to inspect the backend directly. The one thing to unlearn from older instructions: the first sign-up no longer asks for an admin key. Tale is invite-only after the first account, so there is no open sign-up page to lock down either. ## Before you begin Have the instance running and reachable on `SITE_URL`. Verify with: ```bash docker compose ps ``` Every service should show `running` or `healthy`. If any is unhealthy, [troubleshooting](/self-hosted/operate/observability/troubleshooting) names the four common causes. ## Run the setup wizard Open `SITE_URL`. With no users yet, Tale sends you straight to the setup wizard — there is no separate sign-up page to hunt for, because the log-in screen redirects an empty instance into setup automatically. The wizard creates your account and signs you in mid-flow, then names your first organization. The provider step is optional: skip it and add a key later under **Settings > AI providers**, or connect OpenRouter now to start chatting immediately. Get a key at [openrouter.ai/keys](https://openrouter.ai/keys). The finish step drops you in the dashboard. ## Confirm you're the Owner The first account on a fresh instance is the **Owner** automatically — there is no key to paste and no promotion step. Confirm under **Settings > People** that your row carries the Owner badge. ## How new people join There is no self-service sign-up. Once an Owner exists, `SITE_URL/sign-up` redirects visitors to the log-in page, so nobody can create an account on their own. Add teammates by invite under **Settings > People**; each invite carries the role the new member lands with. The full role model is in [Members and roles](/platform/admin/members-and-roles). ## Get the Convex dashboard admin key The admin key plays no part in the steps above — it only unlocks the **Convex dashboard**, the low-level view of the backend database. The key is deterministic: it is derived from `INSTANCE_SECRET`, so it stays the same across restarts rather than rotating. Get it whichever way fits how you installed: - With the CLI: `tale convex admin` finds the platform container and prints the key. `tale dev` also prints it once services are healthy. - From a git clone: `./scripts/get-admin-key.sh` from the repo root. Open `SITE_URL/convex-dashboard`, enter `SITE_URL` as the deployment URL, and paste the key when prompted. ## Troubleshooting - **The wizard didn't appear — you landed on the log-in page.** Users already exist on this instance; the wizard only runs on a truly empty one. Sign in instead, or have an existing Owner invite you under **Settings > People**. - **A service is unhealthy.** The platform container is not fully up. `docker compose ps` says which service is failing; `docker compose logs platform` shows why. - **The dashboard rejects the admin key.** The key is deterministic from `INSTANCE_SECRET`, so a rejection usually means `INSTANCE_NAME` and `INSTANCE_SECRET` differ between the platform and Convex services, or the deployment URL is wrong — use `SITE_URL`. Regenerate with `tale convex admin` to be sure you copied the current value. ## Where this gets used You now have an Owner and an org, and you know the admin key is a backend-inspection tool, not part of sign-in. The first run is keyless by design: open the URL, the wizard makes you the Owner, and everyone else joins by invite. The next steps that belong on the calendar are inviting the rest of the admins (under **Settings > People**), adding a model provider, and publishing the first agent — the [Cloud onboarding](/cloud/onboarding) walk is identical from this point on except for the URL. # Install Source: https://tale.dev/docs/self-hosted/install Installing Tale has three shapes, and the right one depends on what you are doing with the result. This page routes you to the path that fits — a quick local trial, a production install behind TLS, or the raw Compose reference when you want to own every knob — so you do not start down a hardening walk when you only wanted to click around. All three paths land on the same product; the difference is how much of the stack you operate and how durable the result needs to be. The CLI wraps Docker Compose for the first two so there is nothing to hand-edit, while the reference path is for teams who run Compose themselves. ## Trying Tale on a laptop If you want a running instance to click through — on your own machine, with no domain and no hardening — the [Quickstart](/self-hosted/install/quickstart) is the path. Install the CLI, run `tale init` then `tale dev`, and you are signed into your own org in minutes. The CLI provisions Docker if it is missing, generates every secret, and bind-mounts your config so edits reload live. This is the right path for an evaluation, a demo, or local development against a real stack. When you outgrow the laptop and want the same project on a real host, the trial project carries over — `tale deploy` takes it to a domain without re-initialising. ## Running Tale in production When real traffic will land on the instance, the [Linux server](/self-hosted/install/linux-server) walk is the path. It covers TLS, a firewall, a non-root user, the reverse proxy, and the operational hooks you want before you point a domain at it. The CLI still does the heavy lifting — `tale deploy` runs a blue-green, zero-downtime rollout with health checks and rollback — but this walk adds the host-level setup that a trial skips. After the first deploy, [First admin](/self-hosted/install/first-admin) explains the one-time setup wizard that makes the first account the **Owner** — everyone after that joins by invite, so there is no open sign-up to close — and [CLI install](/self-hosted/install/cli-install) sets up the CLI on a workstation to deploy and upgrade a remote instance. ## Owning the Compose layer If you would rather run the stack from a clone of the repository and manage Compose yourself — for transparency, air-gapped builds, or your own automation — the [Docker Compose reference](/self-hosted/install/docker-compose-reference) is the path. It documents the base file and the overlays the CLI generates under the hood, so you can reproduce or extend them by hand. This is the most control and the most work; most teams are better served by the CLI paths above. This path pairs with the [Linux server](/self-hosted/install/linux-server) walk for the host-level pieces (TLS, firewall, user) that Compose alone does not cover. ## Where this fits The three install paths trade convenience for control: the [Quickstart](/self-hosted/install/quickstart) is the fastest way to a running instance, the [Linux server](/self-hosted/install/linux-server) walk hardens it for real traffic, and the [Docker Compose reference](/self-hosted/install/docker-compose-reference) hands you every knob when the CLI's defaults are not enough. Pick by durability: a trial you will throw away wants the quickstart; an instance your team depends on wants the production walk. Once installed, the [Configuration](/self-hosted/configuration/environment-reference) pages are the source of truth for every environment variable and provider file, and the [Operate](/self-hosted/operate/container-architecture) section covers upgrades, backups, and observability for the running stack. # Production Linux server install Source: https://tale.dev/docs/self-hosted/install/linux-server This walk takes the [quickstart](/self-hosted/install/quickstart) shape and hardens it for production traffic. The result is a single Linux host running Tale behind real TLS, with a firewall, a non-root operator user, and the operational defaults the team should hit before pointing users at the URL. The walk targets a recent Ubuntu LTS or Debian; commands translate one-for-one to RHEL-family distros with `dnf` substituted for `apt`. Skip nothing — the order matters, and each step assumes the previous one landed cleanly. ## Before you begin You need: - A VM or bare-metal host with at least 8 GB RAM, 4 vCPU, and 100 GB disk. Storage grows with attachments and knowledge. - A DNS A record pointing at the host's public IP. Without DNS, Let's Encrypt cannot issue a cert. - Ports 80, 443 reachable from the public internet for TLS issuance; SSH on whatever port your operator policy says. - Sudo on the host. ## Step 1 — Provision the box Update and install the basics: ```bash sudo apt update && sudo apt upgrade -y sudo apt install -y curl git ufw ``` Create a non-root operator user named `tale`: ```bash sudo adduser tale sudo usermod -aG sudo,docker tale ``` Switch to that user (`sudo su - tale`) for the rest of the walk. Operating Tale as root pulls a higher blast radius for no benefit; the rest of the steps assume the `tale` user. ## Step 2 — Install Docker ```bash curl -fsSL https://get.docker.com | sudo sh sudo systemctl enable --now docker ``` Verify with `docker run hello-world`. If the user cannot run docker without sudo, log out and back in to pick up the `docker` group membership. ## Step 3 — Configure firewall and reverse path Allow only what Tale needs: ```bash sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow OpenSSH sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable ``` If you front Tale with an existing reverse proxy on the same host (rare on a single-host install), set `TLS_MODE=external` in `.env` and adjust the firewall accordingly. The Caddy container inside Tale terminates TLS by default. ## Step 4 — Pull Tale ```bash git clone https://github.com/tale-project/tale.git cd tale cp .env.example .env ``` Set `HOST`, `SITE_URL`, and generate the four secrets as in the [quickstart](/self-hosted/install/quickstart). The production diff versus quickstart lives in step 5 (TLS) and the operational hooks at the end of this walk. ## Step 5 — TLS via Let's Encrypt Open `.env` and set: | Variable | Value | | ----------- | ----------------------- | | `TLS_MODE` | `letsencrypt` | | `TLS_EMAIL` | An ops mailbox you read | Caddy issues and renews the cert automatically using the DNS record from the prerequisites. The first boot waits for the cert; expect a one-minute delay on the first `docker compose up -d` while the ACME challenge runs. ## Step 6 — First boot ```bash docker compose up -d docker compose ps ``` Every service should be `running` or `healthy`. Walk through **Step 4 — Create the first admin** from the [quickstart](/self-hosted/install/quickstart) to land in the dashboard. Open `SITE_URL` over `https://` — the browser should not warn about the cert. ## Step 7 — Operational hooks Before pointing users at the URL, three hooks make life easier later: - **Backups.** Point your existing snapshot tooling at `db-data` and the object store volume — see [Backups and restore](/self-hosted/operate/backups-and-restore). - **Logs.** Tale logs to stdout. If the host has journald, `journalctl -u docker` carries everything; otherwise pipe to your aggregator. - **Metrics.** Set `METRICS_BEARER_TOKEN` in `.env` and scrape `/metrics` from your Prometheus — see [Observability config](/self-hosted/configuration/observability-config). ## Port table | Port | Direction | Purpose | Required | | ---- | --------- | ------------------------------------ | --------------- | | 22 | inbound | SSH | yes, restricted | | 80 | inbound | HTTP, used for ACME and 301 to HTTPS | yes | | 443 | inbound | HTTPS, primary traffic | yes | | 53 | outbound | DNS | yes | | 443 | outbound | model providers, image pulls | yes | ## Troubleshooting - **Let's Encrypt issuance fails.** DNS must resolve to this host's public IP from the public internet, and port 80 must be reachable from the public internet. Run `curl -I http://$HOST` from another machine; if it hits the Caddy challenge, the path works. - **Containers cannot reach model providers.** The host's outbound firewall might block; verify with `docker compose exec platform curl -I https://api.openai.com`. - **TLS cert renews fail later.** Caddy renews 30 days before expiry; failures show in `docker compose logs proxy`. The two common causes are an expired `TLS_EMAIL` mailbox and a DNS change that broke the record. ## Where this gets used You now have a production-shaped install on one host. Two follow-ups belong on the calendar — [Backups and restore](/self-hosted/operate/backups-and-restore) and [Hardening](/self-hosted/operate/security/hardening). If your scale outgrows one host (the rule of thumb is roughly a hundred concurrent users on the recommended spec), the multi-host architecture lives at [Container architecture](/self-hosted/operate/container-architecture). # Self-hosted quickstart Source: https://tale.dev/docs/self-hosted/install/quickstart This is the fastest way to a running Tale: install the `tale` CLI, then two commands. The result is your own org running on your own machine, reachable in the browser. It is meant for a laptop or a single host you want to try Tale on; when you are ready to run it for real, the [Linux server](/self-hosted/install/linux-server) walk covers a hardened production install. ## Before you begin You need nothing to start, and one thing before an agent can answer: - **Docker** — but the CLI provisions it for you: when Docker is missing, `tale dev` offers to install or start it before anything else. If you already run [Docker Desktop](https://www.docker.com/products/docker-desktop) (v24+), or Docker Engine plus the Compose plugin on Linux, the CLI uses that. - An **[OpenRouter API key](https://openrouter.ai)** (or any OpenAI-compatible provider) so agents have a model to talk to. You do not need it for `tale init` — you add it in the app after sign-up, in the setup wizard or under **Settings > AI providers**, and you can swap in any provider later. ## From zero to signed in <Steps> <Step title="Install the CLI"> The installer detects your OS, drops the `tale` binary on your `PATH`, and is the only step that touches your system — it asks for `sudo` when the install directory (default `/usr/local/bin`) is not writable. <Tabs> <Tab title="macOS / Linux"> ```bash curl -fsSL https://raw.githubusercontent.com/tale-project/tale/main/scripts/install-cli.sh | bash ``` </Tab> <Tab title="Windows (PowerShell)"> ```powershell irm https://raw.githubusercontent.com/tale-project/tale/main/scripts/install-cli.ps1 | iex ``` </Tab> </Tabs> <Check> `tale --version` printing a version number confirms the binary landed on your `PATH`. </Check> </Step> <Step title="Create a project"> ```bash tale init my-project cd my-project ``` `tale init` scaffolds a project directory, generates every security secret, and writes the `.env`, so there is nothing to hand-edit. The defaults are localhost and a self-signed certificate; the production domain is chosen later, at `tale deploy`. The one question it asks is whether agents may run `docker` / `docker compose` inside their sandboxes — the default is No, because enabling it runs a privileged inner Docker; a single-user install can say yes, while multi-tenant operators should install Sysbox instead. It does not ask for an API key; that is collected in the app once you sign in. It also drops example agents, workflows, connectors, providers, skills, and branding under `default/`, and writes `AGENTS.md` (plus a `CLAUDE.md` pointer) so an AI editor can build configs with full schema awareness. Most of that tree is a catalog rather than live configuration — only entries marked `autoInstall` are active on a new organization, and the generated `default/README.md` explains the split. </Step> <Step title="Start Tale"> ```bash tale dev ``` If Docker is missing, `tale dev` offers to install or start it first. The first run then pulls several gigabytes of images and builds the container graph — the CLI prints per-image pull progress and keeps waiting, so on a slow network this can take tens of minutes. Once the stack reports ready (`Tale is running — open https://localhost`), `tale dev` opens your browser automatically. If it cannot, it prints the URL to visit. <Note> Your browser shows a certificate warning for the local self-signed certificate. That is expected — accept it to continue. </Note> Your config under `default/` is bind-mounted into the running instance, so edits to agents, workflows, and connectors reload live. Stop the stack with `Ctrl-C` (or `tale dev --detach` to run it in the background). </Step> <Step title="Create your account"> On an empty instance there is no sign-up page to hunt for: the first visit lands in the one-time setup wizard, which creates your account, signs you in, makes you the **Owner**, and names your **Organization**. You land in the dashboard — no admin key involved, and nothing to lock down afterward, because everyone after you joins by invite. <Note> [First admin](/self-hosted/install/first-admin) covers the wizard in detail, how teammates join, and the Convex dashboard admin key — a backend-inspection tool that plays no part in sign-in. </Note> </Step> <Step title="Add a model and publish an agent"> You now have an empty org. Two moves get you to something useful: add your OpenRouter key — the setup wizard prompts for it right after you create the owner account, and **Settings > AI providers** takes it any time later — then publish your first agent with [Create an agent](/platform/agents/create). A confirmation on the provider row means the key works. <Check> A new chat answering a message is the end-to-end proof: provider, model, and agent all work. From here the [Platform](/platform) docs are the canonical reference for every feature, identical to Cloud. </Check> </Step> </Steps> ## Prefer raw Docker Compose? The CLI wraps `docker compose` so you do not have to. If you would rather run the stack from a clone of the repository and manage compose yourself — for transparency, air-gapped builds, or your own automation — clone the repo, copy `.env.example` to `.env`, set `HOST` and `SITE_URL`, generate the secrets, and `docker compose up -d`. The [Linux server](/self-hosted/install/linux-server) walk and the [Docker Compose reference](/self-hosted/install/docker-compose-reference) cover that path end to end. ## Troubleshooting - **`tale` not found after install.** The installer names the destination directory in its output; make sure that directory is on your `PATH` (on Linux it is usually `/usr/local/bin`). - **`tale dev` exits with a port conflict.** Read the compose error to see which port is taken. If it is 443, another service binds HTTPS on the host — free it, or remap with `tale dev --port 8443` (the flag remaps only the HTTPS port). The sandbox spawner always binds `127.0.0.1:8003` and cannot be remapped, so two Tale dev projects cannot run on one machine at the same time. - **Docker is not running.** `tale dev` offers to start (or install) it — accept the prompt, or start Docker Desktop yourself (`sudo systemctl start docker` on Linux) and retry. - **A container crash-loops on first boot.** Almost always a missing secret — re-run `tale dev`, which re-runs environment setup, or inspect logs with `tale logs platform`. ## Where this gets used You now have a working Tale instance on your machine. To run it for real, the [Linux server](/self-hosted/install/linux-server) walk covers TLS, firewall, a non-root user, and the operational hooks you want before real traffic lands; [CLI install](/self-hosted/install/cli-install) sets the CLI up to deploy and upgrade a remote instance from your workstation. # Backups and restore Source: https://tale.dev/docs/self-hosted/operate/backups-and-restore Tale's backup unit is the volume snapshot: a paused, checksummed tar of every data volume in the instance, written into a dedicated `backups` volume that lives next to the data it protects. The CLI takes one automatically before any deploy step that can migrate data, and `tale backup` takes one on demand. Recovery is `tale restore <snapshot-id>` plus a redeploy of the matching version — that pair is the answer to a failed upgrade, and the reason `tale rollback` can afford to refuse anything beyond a patch step. The architecture context lives in [Container architecture](/self-hosted/operate/container-architecture); this page covers what a snapshot contains, when one is taken, how the copy gets off the host, and the restore walk. ## What a snapshot contains | Volume | Holds | | ---------------------------- | ----------------------------------------------- | | `db-data` | Postgres — agents, runs, the audit log | | `convex-data` | Org config, provider secrets, uploaded branding | | `rag-data` | The vector index built from your documents | | `crawler-data` | Crawled website knowledge | | `caddy-data`, `caddy-config` | TLS certificates and proxy state | Each snapshot is a directory named like `20260611-142530-deploy` inside the project's `backups` volume: one `.tar.gz` per volume, a `.sha256` sidecar each, and a `manifest.json` written last. A directory without a manifest is an incomplete snapshot — it never shows up in listings and can never be restored. Two things live outside the volumes and need separate capture: the project workspace (the directory holding `tale.json`) and `.env`. ## When snapshots are taken `tale deploy` snapshots before its first mutating step whenever the deploy can change data: the target version differs from the running one, or a host-config push (`--override` / `--override-all`) is requested. While each volume is tarred, the containers using it are paused for a few seconds so the archive is crash-consistent — a live copy of a running Postgres directory is not restorable. A failed snapshot aborts the deploy. `--skip-backup` overrides that on `tale deploy`, which leaves your own external backups as the only recovery path — the flag logs a loud warning for exactly that reason. ```bash # Take a snapshot right now tale backup ``` ## Retention Rotation keeps the newest five snapshots and everything from the last 14 days — whichever is more generous. A snapshot is deleted only when it is both beyond the count window and older than the age window, so a quiet instance keeps its last snapshots indefinitely. Override the windows with `BACKUP_KEEP_COUNT` and `BACKUP_KEEP_DAYS` in `.env`. ## Off-host copy The snapshots live on the same host as the data they protect — a dead disk takes both. Point your existing backup tooling (Restic, Borg, Velero, cloud-provider snapshots) at the `backups` volume, and capture the project workspace and `.env` in the same job. Tale does not ship an upload step — keeping the off-host copy under your existing backup contract is deliberate. ```bash # crontab on the host — hourly Restic copy of the backups volume to S3 0 * * * * restic -r s3:s3.amazonaws.com/bucket/tale backup \ /var/lib/docker/volumes/<project-id>_backups/_data ``` Find the volume's host path with `docker volume inspect <project-id>_backups`; the project id lives in `tale.json`. ## Restoring a snapshot `tale restore` without arguments lists what is available; with an id it verifies the checksums, wipes the data volumes, and extracts the snapshot. It refuses while any project container runs — pass `--stop` to stop them — and asks for confirmation before touching anything. ```bash # See what's available tale restore # Stop the stack and restore tale restore 20260611-142530-deploy --stop # Bring the stack back on the version that matches the data tale update --version 0.9.6 tale deploy --stop ``` The redeploy of the matching version is part of the restore, not an optional extra: the snapshot captured the data exactly as that platform version left it, and a newer binary would immediately re-run its migrations against it. The restore output prints the exact version recorded in the snapshot's manifest. ## Restore drill Run the drill quarterly on a non-production host. The drill is not "does a snapshot exist" — it is "can a fresh host be rebuilt from the off-host copy of the `backups` volume, the project workspace, and `.env` in under an hour." The failure modes the drill catches: an off-host job that never captured the workspace, and a stale `.env` that no longer matches the current binary's requirements. ## Where this fits Snapshots are the cheap part; the restore drill is what proves they work, and the redeploy-the-matching-version rule is the one thing to remember — recovery is never "roll the binary back," it is "restore the data and deploy the version it belongs to." The upgrade flow these snapshots protect lives in [Upgrades](/self-hosted/operate/upgrades); the hardening checklist that names backups as a row is in [Hardening](/self-hosted/operate/security/hardening). # Container architecture Source: https://tale.dev/docs/self-hosted/operate/container-architecture A Tale instance is eight containers wired by docker compose. The architecture page covered what each container is for; this page is the operator's version — which container owns which job, how a chat message flows through them, and what the failure mode looks like when one of them dies. Read this when you are on call. Come back when you are deciding which container to roll first during an upgrade. ## The eight containers, with their jobs | Container | Job | Crashes affect | | -------------------------- | ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------- | | `tale-proxy` | TLS termination + edge routing | All ingress — no client can reach the UI | | `tale-platform` | UI server, static asset delivery | Browser sees 502; the API is still reachable | | `tale-convex` | Backend actions/queries/mutations + WebSocket, plus in-process RAG, crawling, and document gen | UI loads, but no data; in-flight chats stall; ingestion stalls | | `tale-db` | Operational Postgres for Convex | Convex falls back to read-only; writes block | | `tale-knowledge-db` | Knowledge corpus Postgres (document chunks, embeddings, crawled pages) | Knowledge search returns empty; ingestion fails | | `tale-sandbox-llm-gateway` | LLM gateway for harness turns | Harness turns can't reach a model; chat is unaffected | | `tale-sandbox-egress` | Network egress for sandboxed code | `Run code` tool errors with "egress denied"; web render fails | | `tale-sandbox` | Sandbox runtime + headless browser for web render and document generation | `Run code`, web crawl render, and document generation all fail | One container is exposed to the public network (`tale-proxy` for HTTPS, and optionally `tale-sandbox-egress` outbound for the sandbox); the rest are internal-only. The opt-in `tale-controller` sidecar (the `controller` profile) is off by default; when enabled it restarts `tale-convex` on a signed request so a data-residency change can apply without handing the platform Docker access. ## The request path A chat message takes one round trip through the containers: 1. Browser → `tale-proxy` (TLS terminated). 2. `tale-proxy` → `tale-platform` for HTML/JS, → `tale-convex` for API + WebSocket. 3. `tale-convex` reads the org's provider config, picks the model, opens a stream to the upstream provider. 4. If the agent retrieves knowledge: `tale-convex` runs the RAG search in-process, querying `tale-knowledge-db` directly — no separate retrieval service in the path. 5. If the agent runs code: `tale-convex` → `tale-sandbox` → `tale-sandbox-egress` for any outbound network. 6. The provider stream tokens back through `tale-convex` to the browser over the WebSocket. The hot path is short. If chat latency feels wrong, the container to blame is almost always the upstream provider, not Tale; the metrics endpoints on `tale-convex` (which now carries the RAG and crawl timings as well) surface the time spent in each hop. ## The sandbox plane Sandboxed code execution runs in `tale-sandbox` with `tale-sandbox-egress` as the only network seam. The two-container split is deliberate: `tale-sandbox` itself has no outbound network; every request the sandboxed code makes goes through `tale-sandbox-egress`, which blocks cloud-metadata and private-range targets at the IP layer and — when the operator sets `SANDBOX_EGRESS_ALLOWLIST` — enforces a default-deny hostname allowlist on top. If the egress container is down, sandboxed code that needs the network fails closed with "egress denied" — not a silent timeout. The sandbox runtime carries Chromium and Playwright, so the convex backend reuses it for the headless work it cannot do in-process: rendering a JavaScript page during a web crawl, and turning generated HTML into a PDF or image. Those jobs run as ephemeral sandbox executions rather than user code, but they ride the same egress and isolation seam. The sandbox is the only container that runs untrusted-ish code (user-supplied skill scripts, agent `Run code` invocations); the rest of the stack runs the platform's own code. ## Failure modes — what each container's outage looks like **`tale-proxy` down.** TLS handshake fails; every client sees a connection error. Inside the host, the platform and convex containers are still up — restart proxy first. **`tale-platform` down.** Browser gets 502 from proxy; the API keeps working. Existing browser tabs with cached assets continue to talk to convex over the WebSocket and may not notice until they reload. **`tale-convex` down.** Browser loads the UI shell but nothing populates. WebSocket reconnects loop. Restarting convex is safe — sessions are server-side; clients re-subscribe on reconnect. **`tale-db` down.** Convex enters its degraded mode: reads from cache, writes are queued. Long outages eventually surface as "saving failed" toasts. **`tale-knowledge-db` down.** Document ingestion fails and knowledge search returns empty — agents that retrieve knowledge get an empty result set and a warning in the execution log. The rest of the app keeps working; chats without knowledge are unaffected. Restarting the container clears it, and in-flight uploads retry on the next pass. **`tale-sandbox` / `tale-sandbox-egress` down.** `Run code` tool calls return an error and skill scripts fail. Because the convex backend renders web pages and generates documents through the sandbox runtime, a web crawl that needs JavaScript rendering and document generation also fail closed while the sandbox is down. Agents that use none of these keep working. **`tale-sandbox-llm-gateway` down.** Harness turns lose their path to a model provider. Regular chat — which calls providers directly from convex, not through the LLM gateway — is unaffected. ## Where this fits This page is the operator's map; the [Architecture overview](/self-hosted/overview) is the introduction to the same picture, the [Troubleshooting](/self-hosted/operate/observability/troubleshooting) page is the symptom-first index when something has gone wrong. If you are setting alert thresholds, [Operations](/self-hosted/operate/observability/operations) names the signals worth wiring. # Operations Source: https://tale.dev/docs/self-hosted/operate/observability/operations The operations page is the alert playbook — which signals are worth waking someone for, which can ride out a coffee, and what the first five minutes of an incident look like. Tale's metrics surface lives behind `METRICS_BEARER_TOKEN`; this page assumes you have wired up Prometheus and Grafana per [Observability config](/self-hosted/configuration/observability-config) and now need to know which numbers to watch. The symptom-first index is at [Troubleshooting](/self-hosted/operate/observability/troubleshooting). This page is the proactive side — signals first, oncall checklist second. ## Signals worth alerting on | Signal | Severity | Why it matters | | ------------------------------------------- | -------- | --------------------------------------------------- | | `tale-proxy` health probe failing > 1 min | page | Every user sees a connection error | | `tale-platform` HTTP 5xx rate > 5 % | page | The UI is broken for a meaningful share of requests | | `tale-convex` WebSocket reconnect storm | page | UI loads but no data flows | | Postgres connections > 80 % of pool | warn | The next spike will start blocking | | `db-data` volume > 80 % full | warn | The operational Postgres goes read-only at full | | `knowledge-db-data` volume > 80 % full | warn | Ingestion fails when the corpus database is full | | `tale-knowledge-db` unreachable from convex | warn | Knowledge search returns empty; ingestion stalls | | Provider request error rate > 20 % | warn | The upstream LLM provider is having a bad day | | Daily backup did not write | page | Restore drill will fail at the worst moment | | TLS cert renewal failed | warn | Renews 30 d before expiry — you have time | The first two pages are the actually-customer-impacting ones. The warns are catching trends before they tip into page territory. ## Log signals to grep for Logs come through stdout per container, captured by Docker's `json-file` driver. The four phrases that consistently mean trouble: - `panic` or `unexpected error` in `tale-convex` logs — Convex action crash. - `decryption failed` in `tale-platform` logs — SOPS age key mismatch with the file on disk. - `429 Too Many Requests` repeated from a provider — rate limit hit, agents will start failing. - `connection refused` or `ECONNREFUSED` to `knowledge-db` in `tale-convex` logs — the backend cannot reach the corpus database; ingestion and knowledge search fail. Pipe these to your aggregator as derived alerts; the metrics endpoints do not surface them as gauges. ## Oncall checklist When a page lands, the first five minutes follow the same shape every time. 1. **Confirm the alert is real.** Open `$SITE_URL` in a browser. If the UI loads and chat works, you are looking at a metrics or scraper issue, not a customer-impacting one. 2. **Identify the container.** `docker compose ps` shows which is unhealthy; `docker compose logs --tail=200 <service>` shows the last error. 3. **Restart the most-likely culprit.** `docker compose restart <service>` resolves a surprising fraction of incidents — process crashes, file watchers gone stale, exhausted connection pools. The architecture is built to survive a single container restart cleanly. 4. **Check upstream providers.** `https://status.openai.com`, `https://status.anthropic.com`, etc. If the provider is on fire, agents fail; Tale is not the cause. 5. **Page the on-call engineer if the user-visible symptom persists after a restart.** No need to escalate sooner — most incidents resolve in the first three steps. ## What does not need oncall A `tale-knowledge-db` outage is a warn, not a page. The web-crawl schedule absorbs hours of downtime without user impact, and document ingestion retries rather than dropping work — uploads sit in "indexing" until the corpus database is back. Knowledge search returns empty in the meantime, but chats that do not retrieve knowledge keep working. Catch this in the warn band and fix it in business hours. ## Response-time SLAs Two response-time budgets are tracked as first-class signals: interactive dialog input and long-running operations such as evaluations. Both are verified as a **mean** over a rolling window — the contractual figure is an average, not a per-request ceiling — and both are wired so Prometheus alerts the moment the average drifts past budget. | Budget | Statistic | Target | Window | Underlying series | | -------------- | --------- | ------ | ------ | ----------------------------- | | Dialog input | mean | ~1 s | 30 m | `tale_dialog_ttft_seconds` | | Long operation | mean | ~40 s | 6 h | `tale_long_operation_seconds` | Each target also rides the platform metrics endpoint as `tale_sla_target_seconds{sla,statistic}`, so a Grafana panel draws the budget line straight from Prometheus instead of hard-coding it. The underlying latency series are the Convex function-execution histograms on `/metrics/convex`; relabel or record them to the names above so the rules resolve. The platform serves the ready-made recording and alerting rules at `/metrics/sla-rules` (behind the same bearer token as the other metrics paths) — fetch it once and reference the file under `rule_files:`, or paste the equivalent: ```yaml groups: - name: tale-sla-recording rules: - record: tale_sla_dialog_ttft:mean30m expr: rate(tale_dialog_ttft_seconds_sum[30m]) / rate(tale_dialog_ttft_seconds_count[30m]) labels: sla: dialog_ttft - record: tale_sla_long_operation:mean6h expr: rate(tale_long_operation_seconds_sum[6h]) / rate(tale_long_operation_seconds_count[6h]) labels: sla: long_operation - name: tale-sla-alerts rules: - alert: TaleSlaDialogTtftBreached expr: tale_sla_dialog_ttft:mean30m > 1 for: 15m labels: severity: warn sla: dialog_ttft annotations: summary: 'Dialog input response time: mean response time over 30m exceeds the 1s SLA' description: Mean time-to-first-token for an interactive chat / dialog turn. - alert: TaleSlaLongOperationBreached expr: tale_sla_long_operation:mean6h > 40 for: 30m labels: severity: warn sla: long_operation annotations: summary: 'Long operation response time: mean response time over 6h exceeds the 40s SLA' description: Mean end-to-end time for long-running operations such as evaluations. ``` A breach here is a **warn**, not a page: a drifting average is a degradation to chase in business hours, and the `for:` windows deliberately wait out a short spike before firing. The ~1 s dialog budget reconciles with the looser ~3 s warm time-to-first-token in the manual performance plan — that ~3 s is a per-request ceiling for a single cold, Auto-routed first token (the first provider SSE text delta) including model and network time, whereas the ~1 s here is the steady-state mean across dialog turns, so occasional first tokens reaching the ceiling are consistent with a sub-second mean. Holding the 1 s mean on live providers may still need the backend-overhead optimization tracked on the feature issue; this alert is what confirms whether the target is met. ## Where this fits The signals above are the proactive side of operating a Tale instance; the reactive side is [Troubleshooting](/self-hosted/operate/observability/troubleshooting), and the configuration that gets the metrics into Prometheus is [Observability config](/self-hosted/configuration/observability-config). If you have not yet set `METRICS_BEARER_TOKEN`, every threshold above is unmonitored — start there. # Prometheus and Grafana Source: https://tale.dev/docs/self-hosted/operate/observability/prometheus-grafana This is the worked example behind [Observability config](/self-hosted/configuration/observability-config): a Prometheus and Grafana pair you can drop next to Tale, pointed at the two bearer-token metrics endpoints, with a starter dashboard and one alert rule to build on. It's for self-hosted operators who have already set `METRICS_BEARER_TOKEN` and now want live graphs instead of a `curl` against `/metrics`. The config-reference page lists the endpoints and the single scrape stanza; this page stands the whole stack up end to end. Everything here runs on the same host as Tale, so no metric leaves the box. ## Before you start Set `METRICS_BEARER_TOKEN` in your `.env` and restart the proxy — without it the two endpoints return 401 to every request, and Prometheus will show each target as down. The endpoints, and what each one carries, are the table in [Observability config](/self-hosted/configuration/observability-config#metrics): `/metrics/platform` and `/metrics/convex` (the latter now carries the in-process RAG and crawl timings), both served by `tale-proxy` over the same hostname as the app. ## Add Prometheus and Grafana to your stack Drop these two services into a compose override next to Tale. Prometheus scrapes on an interval and stores a local TSDB; Grafana reads Prometheus and renders the dashboards. Both bind to localhost only — reach Grafana through an SSH tunnel or put it behind the same proxy with auth, never expose it raw. ```yaml # docker-compose.metrics.yml — start with: docker compose -f docker-compose.yml -f docker-compose.metrics.yml up -d services: prometheus: image: prom/prometheus:v3.1.0 volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro - prometheus-data:/prometheus ports: - '127.0.0.1:9090:9090' restart: unless-stopped grafana: image: grafana/grafana:11.4.0 environment: GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD:?set a strong password} GF_USERS_ALLOW_SIGN_UP: 'false' volumes: - grafana-data:/var/lib/grafana ports: - '127.0.0.1:3001:3000' restart: unless-stopped volumes: prometheus-data: grafana-data: ``` ## Scrape configuration Tale's two endpoints share one bearer token, so the scrape config is the published stanza repeated once per path. Save this as `prometheus.yml` next to the override above and substitute your host and token — Prometheus reads the token from the file, so keep it `chmod 600` and out of version control. ```yaml global: scrape_interval: 30s scrape_configs: - job_name: tale-platform scheme: https metrics_path: /metrics/platform authorization: { credentials: '${METRICS_BEARER_TOKEN}' } static_configs: - targets: ['tale.example.com'] - job_name: tale-convex scheme: https metrics_path: /metrics/convex authorization: { credentials: '${METRICS_BEARER_TOKEN}' } static_configs: - targets: ['tale.example.com'] ``` Open `http://127.0.0.1:9090/targets` after start — both jobs should read **UP**. A target stuck **DOWN** with a 401 means the token in `prometheus.yml` does not match `METRICS_BEARER_TOKEN`; a connection error means the hostname or scheme is wrong. ## A starter dashboard Point Grafana at Prometheus first — add a Prometheus data source at `http://prometheus:9090` (Grafana reaches it by the compose service name). Then build a dashboard from these panels; the first three use metrics that are always present, and the rest map to the signals in [Operations](/self-hosted/operate/observability/operations). | Panel | Query | Reads as | | --------------- | ---------------------------------------------------- | ------------------------------------------------- | | Targets up | `up{job=~"tale-.*"}` | `1` per healthy endpoint, `0` when scraping fails | | Platform memory | `process_resident_memory_bytes{job="tale-platform"}` | Resident memory of the platform container | | Event-loop lag | `nodejs_eventloop_lag_seconds{job="tale-platform"}` | Spikes when the platform is saturated | | Convex up | `up{job="tale-convex"}` | Backend reachability — `0` is a page | The platform endpoint carries Node's default process metrics (CPU, memory, event-loop lag, GC), which is why the concrete queries above target it. The Convex endpoint exposes its own richer series, including the in-process RAG and crawl timings — open it once (`curl -H "Authorization: Bearer $TOKEN" https://tale.example.com/metrics/convex`) to read the exact metric names your version exposes, then add panels for knowledge-ingestion throughput and provider error rate called out in Operations. ## A first alert rule Start with the one signal that is unambiguous — a metrics target that stops responding. Add this rule file to Prometheus (mount it and reference it under `rule_files:` in `prometheus.yml`), then wire Alertmanager or Grafana alerting to your pager. ```yaml groups: - name: tale rules: - alert: TaleTargetDown expr: up{job=~"tale-.*"} == 0 for: 2m labels: { severity: page } annotations: summary: 'Tale metrics target {{ $labels.job }} is down' ``` The full list of what's worth paging on versus what can wait — platform 5xx rate, Postgres pool saturation, knowledge-database reachability, daily-backup-did-not-write — is the signal table in [Operations](/self-hosted/operate/observability/operations); translate each row into a rule once the matching series is on your dashboard. ## Where this fits This page turns the two documented metrics endpoints into a running Prometheus and Grafana stack: a compose override, a two-job scrape config, a starter dashboard, and a target-down alert you extend with the Operations thresholds. Keep both services bound to localhost and the bearer token off disk-in-the-clear, and the whole monitoring surface stays on the host with Tale. The endpoints and the token that gate them are owned by [Observability config](/self-hosted/configuration/observability-config); the thresholds and the oncall checklist are [Operations](/self-hosted/operate/observability/operations). When a panel goes red, the symptom-to-fix lookup is [Troubleshooting](/self-hosted/operate/observability/troubleshooting). # Troubleshooting Source: https://tale.dev/docs/self-hosted/operate/observability/troubleshooting This page is the symptom-first lookup when something is wrong right now. Each section starts with what the user actually reports — what the browser shows, what the agent fails on, what the upload screen says — and walks back to the cause and the fix. Anything not listed here is a candidate for a new section once it has shown up twice. The proactive side — signals worth alerting on, what to wire into Prometheus — lives in [Operations](/self-hosted/operate/observability/operations). This page is for the moment after the page fired. ## Browser sees 502 or "Bad Gateway" The `tale-proxy` container reached the platform, but the platform did not reply. Either `tale-platform` is down or its health endpoint is unreachable. Check container state first: ```bash docker compose ps tale-platform docker compose logs --tail=200 tale-platform ``` If the container is restarting, the logs at the bottom show the crash reason — usually a misconfigured env var (`SITE_URL` mismatch, missing `BETTER_AUTH_SECRET`) or a Postgres connection failure. Fix the env, restart, retry. If the container is healthy but the browser still sees 502, the proxy is the suspect — `docker compose restart tale-proxy` clears most of these. ## Browser sees a TLS warning `TLS_MODE=selfsigned` is the most common cause — the browser does not trust Caddy's internal CA on first visit. Either trust the CA on the host (`docker exec tale-proxy caddy trust`) or switch to `TLS_MODE=letsencrypt` for a real certificate. The full mode walk lives in [TLS and domains](/self-hosted/configuration/tls-and-domains). If the mode is already `letsencrypt`, check the proxy logs for ACME failures — DNS not resolving to this host's public IP and port 80 unreachable from the public Internet are the two common causes. ## UI loads but no data appears The UI shell is static assets served by `tale-platform`; everything else flows through `tale-convex` over a WebSocket. When the WebSocket cannot connect, the shell loads and stays empty. Symptoms: spinners that never resolve, "reconnecting" toasts, the chat input that never accepts a message. ```bash docker compose logs --tail=200 tale-convex ``` The convex container is probably restarting (look for `panic` in the logs) or unreachable from the proxy. Restart with `docker compose restart tale-convex` — sessions are server-side and clients re-subscribe on reconnect, so the restart is safe. ## Uploads stuck in "indexing" Document ingestion runs inside the Convex backend and writes the extracted chunks and embeddings to the knowledge corpus database. A long "indexing" state means either the backend cannot reach `tale-knowledge-db` or the file itself failed to extract. Check the convex logs and the corpus database first: ```bash docker compose logs --tail=200 tale-convex | grep -iE "knowledge|ingest|embed" docker compose ps tale-knowledge-db ``` If the logs show connection errors to `knowledge-db`, restart the corpus database (`docker compose restart tale-knowledge-db`); ingestion retries on the next pass, so uploads do not have to be re-submitted. If the database is healthy but a specific upload is stuck, the file itself is the suspect — corrupt PDFs and password-protected documents land in a failure state and require deletion and re-upload. ## Chat replies stop mid-stream The token stream from the upstream provider dropped — either the provider rate-limited, the connection timed out, or the provider's service is degraded. Check the provider's status page first; then look in the platform logs: ```bash docker compose logs --tail=200 tale-platform | grep -E "429|503|stream" ``` A `429` is the common case. Either the org's budget is hitting the provider's rate limit, or the provider key itself is throttled. Switching the org's default model to a less-loaded provider clears the symptom while the upstream cools off. ## Saving fails with "saving failed" toast The convex container could not write to Postgres. Either `tale-db` is down or its disk is full: ```bash docker compose ps tale-db docker compose exec db df -h /var/lib/postgresql/data ``` A disk at 100 % is the failure that produces the most surprised faces. Free space, restart `tale-db`, and the queued writes flush. If the disk has room, the suspect is connection-pool exhaustion or a lock — restart `tale-convex` to clear the pool. ## "Run code" tool errors with "egress denied" The `tale-sandbox-egress` container is the only outbound network path for sandboxed code; if it is down or misconfigured, every outbound request from the sandbox fails closed. Check the egress container first: ```bash docker compose ps tale-sandbox-egress docker compose logs --tail=100 tale-sandbox-egress ``` If the container is healthy and you have set `SANDBOX_EGRESS_ALLOWLIST`, the request hit the allowlist — extend the variable in `.env` and recreate `tale-sandbox-egress`. Without an allowlist the proxy is open at the hostname layer, so check the target instead: only port 443 is tunnelled for HTTPS, and cloud-metadata and private-range addresses are always blocked at the IP layer. ## Sign-in loops back to the sign-in screen `SITE_URL` does not match what the browser actually requested. Auth cookies are scoped to the URL the request landed on; a mismatch (trailing slash, missing port, `http` vs `https`, base-path prefix) means the cookie set on the callback does not get sent on the next request. Fix `.env`: ```bash SITE_URL=https://tale.example.com # exactly what the user types ``` Recreate the platform container (`docker compose up -d --force-recreate tale-platform`) for the change to land in the rendered HTML. ## Where to get help Self-hosted instances do not phone home, so support starts with you. The two channels: - **GitHub Issues** — bugs and reproducible problems. The [tale-project/tale](https://github.com/tale-project/tale/issues) tracker has a template that asks for the diagnostics bundle `tale diagnostics` produces. - **Discord** — questions, configuration debates, "is this a bug" triage. The invite lives in the repo README. Reproducible diagnostics make every channel faster. `tale diagnostics` collects sanitised logs, env vars (secrets redacted), and container health into a single archive worth attaching. # How to read release notes Source: https://tale.dev/docs/self-hosted/operate/release-notes/format Tale ships a release per minor version and patches as bug-fix tags between them. The release notes for every tag follow the same shape so you can scan one in a minute and know whether the upgrade is a five-minute bump or a maintenance window. This page covers the format: the semver promise, what each section guarantees, and where to read deeper when a row points at a migration. The notes themselves live on the GitHub release page for each tag. The CLI also surfaces them — `tale update --notes` prints the notes for the version it is about to install. ## The semver promise Tale versions are semver, and the version number is the headline fact about an upgrade. - **Patch (`0.9.0 → 0.9.1`)** — bug fixes only. No schema migrations, no config changes, no behaviour changes other than the fix itself. Safe to upgrade without reading past the security section. - **Minor (`0.9.x → 0.10.x`)** — new features, possibly forward-only migrations. Backwards-compatible by default; deprecations are announced one minor in advance. The one standing exception is 0.4.0: a breaking minor that requires a fresh deployment (see [Upgrades → 0.3 → 0.4](/self-hosted/operate/upgrades)). - **Major (`0.x → 1.x`)** — breaking changes are allowed. Always carries a migration-notes link at the top of the release; read it end-to-end before starting. The version line at the top of every release page names the bump kind in plain English so you do not have to do the arithmetic yourself. ## The sections every release has Each release page is the same ordered list of sections. Empty sections are omitted, not left blank — if you do not see a section, there is nothing to report there. - **Highlights** — one or two paragraphs naming what the release is for. Read this first. - **Breaking changes** — every change that requires the operator to do something before or after the upgrade. Each row names the symptom you would hit if you skipped, and the action that avoids it. - **Deprecations** — features still working in this release but flagged for removal. Each row names the removal version so you can plan the cutover. - **Security** — CVE-format entries for fixes that close a vulnerability. The full feed lives under [Security advisories](/self-hosted/operate/security/advisories); the release notes carry the one-line summary plus the advisory link. - **Features and fixes** — the long list. Grouped by area (Platform, CLI, Docs); each row reads as one sentence. - **Migration notes** _(major versions and some minors)_ — the linked walk through schema migrations, config-file changes, or operator-facing renames. Always read for majors. ## How to scan a release Read the version line, the highlights, and the breaking-changes section. If breaking changes is empty and the security section does not name a fix that touches your install, the upgrade is the `tale update` + `tale deploy` sequence from [Upgrades](/self-hosted/operate/upgrades). If either section has rows, walk them before running `tale deploy`. ```text 0.12.0 (minor) — 2026-05-14 Highlights Streaming tool calls now stream into the chat as they emit. Breaking changes (none) Deprecations AGENTS_LEGACY_PROMPT env var — removed in 0.14. Security CVE-2026-XXXX — patched bypass in the run-code sandbox. See: advisory TAL-2026-007. ``` The shape above is what `tale update --notes` prints. The web version of the same release adds links on every advisory and migration row. ## Where this fits The release-notes format is the contract between the project and the operator — the same shape every release so the upgrade decision is a scan, not a deep read. The natural next steps are [Upgrades](/self-hosted/operate/upgrades) for the deploy mechanics and [Security advisories](/self-hosted/operate/security/advisories) for the long-form vulnerability feed the security section links into. # Security advisories Source: https://tale.dev/docs/self-hosted/operate/security/advisories Tale publishes a security advisory for every vulnerability that closes through a patched release. The feed lives on GitHub Security Advisories under the `tale-project/tale` repository and mirrors to an RSS endpoint operators can wire into their alerting. This page covers the format every advisory follows, the severity scale Tale uses, the disclosure timeline maintainers commit to, and the three subscription paths. The advisories are the long-form record. The one-line summary plus a link appears in the **Security** section of each [release note](/self-hosted/operate/release-notes/format). ## The advisory format Every advisory is a GitHub Security Advisory with a stable identifier of the form `TAL-YYYY-NNN` (Tale's internal id) plus the upstream `CVE-YYYY-NNNNN` if one was assigned. The body is the same ordered set of sections so an operator can scan the load-bearing facts without reading the prose. - **Summary** — one sentence naming what an attacker could do and what the fix changes. - **Affected versions** — the version range that contains the vulnerability, in semver form (`>=0.8.0, <0.12.3`). - **Patched versions** — the first release that contains the fix. Upgrading to or past this version closes the vulnerability. - **Severity** — one of the four tiers below, plus the CVSS 3.1 vector for operators who score against their own threat model. - **Workarounds** — what to set, disable, or block to mitigate the vulnerability when an immediate upgrade is not possible. Empty when no workaround exists. - **Credits** — the reporter, when they have asked to be named. The patched-version row is the one most operators land on first; the upgrade itself is the two-command sequence from [Upgrades](/self-hosted/operate/upgrades). ## The severity scale Tale uses four tiers. The tier is set from the CVSS score and the reachability of the vulnerable surface on a default install. | Tier | CVSS | What it means | | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------- | | Critical | 9.0+ | Pre-authenticated remote code execution or unauthenticated data exfiltration. Patch within 24 hours. | | High | 7.0–8.9 | Authenticated escalation, sandbox escape, or cross-tenant data leak. Patch within a week. | | Moderate | 4.0–6.9 | Information disclosure, denial of service, or escalation requiring rare preconditions. Patch on the next maintenance window. | | Low | 0.1–3.9 | Defence-in-depth fixes and hardening without a known exploit path. Patch when convenient. | The CVSS vector lets you re-score against your own deployment — an advisory rated High against a public install may be Low against an air-gapped one. ## The disclosure timeline Maintainers commit to the following timeline from the moment a report lands at `security@tale.dev`: - **Within 72 hours** — acknowledgement, a triage call, and a TAL identifier assigned. - **Within 14 days** — a fix or a workaround published privately to the reporter, and the patched version planned. - **At fix release** — the advisory publishes on GitHub, the CVE assignment is requested, and the security section of the release notes carries the summary. - **30 days after release** — the technical detail in the advisory expands with the reproducer (when reproducing in public no longer puts unpatched installs at risk). Reporters can request a delay if they need more time to disclose; maintainers accept up to 90 days before publishing the summary anyway. On the engineering side, dependency fixes move on a fast track so the patched release lands quickly: Renovate opens a security update PR within 24 hours of an upstream advisory — bypassing the normal release-age delay that applies to routine updates — and CI blocks any merge that introduces a known high or critical advisory. A disclosed dependency CVE therefore turns into a patched Tale release in days, not on the next routine cadence. ## Subscribing Three paths to the same feed: ```text GitHub watch — github.com/tale-project/tale → Watch → Custom → Security alerts RSS — https://github.com/tale-project/tale/security/advisories.atom Email digest — security-announce@tale.dev (one mail per advisory, no traffic between) ``` The RSS feed is what most operators wire into Slack or PagerDuty; the email digest is for one-person teams that do not run an alerting pipeline. ## Where this fits The advisory feed is one of the two contracts that make Tale safe to self-host — release notes name what changes, advisories name what was wrong. The natural next reads are [How to read release notes](/self-hosted/operate/release-notes/format) for the matching change-log format and [Hardening](/self-hosted/operate/security/hardening) for the checklist that limits exposure before an advisory ever fires. # Audit-log integrity alerts Source: https://tale.dev/docs/self-hosted/operate/security/audit-log-integrity Tale verifies every organisation's audit-log hash chain on a schedule and raises an alert the moment a verification fails. This page is the runbook for the operator or admin who received that alert: how to read the finding, how to separate a genuine tamper signal from an ordinary retention or configuration artifact, and what to preserve before you touch anything. The alert is deliberately loud because a real break is rare and serious — but most breaks that fire in practice have an everyday explanation, so the work is to rule those out methodically rather than to panic. ## What triggers it A daily cron walks every organisation's append-only audit chain along with its retention and scrub checkpoints. When a chain fails to verify, the run does two things. It writes an in-band `security` audit row — on every failing run, so the durable record is always complete — and it raises an out-of-band notification to the organisation's admins, in the notification bell and in your Slack channel when one is connected. The out-of-band alert is deduplicated. You get one notification when a break is first detected, and one more only if it changes — a different broken row, or a different failing checkpoint — not a fresh alarm each day for the same break. A subsequent clean run clears the alert on its own; a later, different break raises a new one. ## Tampering or a configuration gap The alert arrives in two shapes, and the title tells you which. **Audit log integrity check failed** is the critical one: the hash chain itself does not verify, or a signed checkpoint's signature does not match the configured key. Treat this as a possible tamper signal until you have explained it. **Audit log signatures can't be verified** is a calm warning, not a breach: a checkpoint is signed, but the deployment has no `TALE_AUDIT_SIGNING_KEY` configured to check that signature against. Nothing was forged — Tale cannot prove the checkpoint is authentic until you restore the key. The in-product panel mirrors the split: a healthy chain shows a green **Verified** badge, an active incident shows a red **Integrity alert active** badge, and an organisation the cron has not reached yet shows **Not yet checked**. ## Open the integrity panel An organisation's admins inspect the chain from **Settings > Governance > Logs**. The **Chain integrity** panel at the top of the page shows the status badge, the time of the last automated check, and a **Verify now** button that re-runs the same verification on demand. If you arrived from the notification, clicking the alert deep-links you straight to the flagged row in the audit table instead of the top of the log. Run **Verify now** to see the structured finding. For a hash-chain break, the panel shows **Chain integrity broken** with the **Entry ID** of the first row that fails, when it **Occurred**, the **Expected hash**, and the **Stored hash** that did not match — plus an **Open this entry** button that reveals the row in the table. For a checkpoint problem, it shows **Checkpoint verification failed** with the **Checkpoint ID** and a **Reason**. Record these details before you change anything: they are the evidence. ## Rule out the benign causes A hash break is a tamper signal only when nothing legitimate explains it, and the verifier already accounts for the three ordinary events that cause almost every alert — so confirming one of them is your first move. **A retention cut.** When retention hard-deletes old rows, the surviving chain head points at a row that no longer exists. The verifier re-anchors across the cut using a signed retention checkpoint, so a clean cut verifies normally. If instead you see **Audit log signatures can't be verified**, the cut itself is fine — the deployment is missing the `TALE_AUDIT_SIGNING_KEY` that authenticates the checkpoint. That is a configuration gap, not tampering. **A GDPR scrub.** Erasing a data subject blanks their fields in place, which would change those rows' hashes — so a scrub writes a signed scrub checkpoint covering the affected rows, and the verifier trusts them on that basis. A scrub should never surface as a break on a deployment that has a signing key. **Legacy pre-chain rows.** Rows written before audit hash-chaining existed carry no integrity hash. The verifier skips them automatically; they are not a break. A genuine tamper signal is a hash mismatch with none of these explanations: no retention cut at that point, no scrub covering the row, and the signing key present and correct. ## Respond to a real break If the finding survives that triage — a hash mismatch you cannot account for — treat it as a security incident and preserve evidence first. Audit rows are append-only by design; do not delete or edit any row, including the flagged one, because that destroys the record an investigation depends on. 1. Record the finding verbatim — the **Entry ID**, **Occurred** time, **Expected hash**, and **Stored hash** (or the **Checkpoint ID** and **Reason**) shown in the panel. Copy or screenshot them rather than relying on the alert alone. 2. Confirm whether the signing key is configured on the host, so you can tell a real mismatch from an unverifiable checkpoint. This reports presence without printing the secret: ```bash grep -q '^TALE_AUDIT_SIGNING_KEY=' .env && echo configured || echo missing ``` 3. Correlate the break's timestamp with recent activity — a retention sweep, a data-subject scrub, a deploy, a database restore, or direct database access. A break that lines up with a maintenance action usually has an ordinary cause you can now name. 4. If nothing explains it, escalate through your security incident policy and treat the database as potentially compromised until proven otherwise. Keep a backup snapshot from before and after the detected break for forensics. ## Clear the alert The alert is incident-based, not a recurring event. Once the break is resolved or explained — the key restored, the retention artifact understood, a tampered database rebuilt from a clean backup — the next daily run verifies cleanly and clears the alert on its own, and the **Chain integrity** badge returns to **Verified**. There is no acknowledge or dismiss step to remember. If a different break appears later, the check raises a fresh alert for that one, so muting is never necessary. ## Where this fits An integrity alert is a prompt to investigate, not a verdict — the daily check runs loud so a rare real break cannot hide among the logs, and this runbook is how you separate that rare case from the retention and scrub artifacts behind most alerts. The mechanism the verifier checks — the SHA-256 hash chain and the HMAC-signed checkpoints — is documented in [Cryptography](/self-hosted/operate/security/cryptography), and the retention cuts that legitimately re-anchor it are in [Retention](/self-hosted/configuration/retention). The panel, columns, and export you use to read a flagged row live on the [Audit logs](/platform/admin/governance/audit-logs) reference; the [Hardening](/self-hosted/operate/security/hardening) checklist is where this monitoring gets switched on in the first place. # Cryptography Source: https://tale.dev/docs/self-hosted/operate/security/cryptography This page is the inventory of every cryptographic primitive Tale relies on: what protects secrets on disk, what protects traffic on the wire, how passwords are hashed, and how the audit log proves it has not been tampered with. It is written for operators and compliance reviewers who need to answer "which algorithms, which key lengths, where are the keys" against a standard such as BSI TR-02102-1 — Tale already uses compliant primitives, and this page is where they are written down. The claims here are verified against the source; where a primitive is configurable, the environment variable that controls it is named so you can audit your own deployment. None of this is a substitute for encrypting the host disk — see [Hardening](/self-hosted/operate/security/hardening) for the layer below the application. ## Data at rest Tale encrypts two classes of secret at rest, with two different mechanisms. **Provider API keys** live in `providers/*.secrets.json` and are encrypted with [SOPS](/self-hosted/configuration/secrets-with-sops) using an **age** key. SOPS encrypts each value with **AES-256-GCM** and wraps the data key to the age recipient, whose key agreement is **X25519**. An encrypted value reads `ENC[AES256_GCM,data:…,iv:…,tag:…]` on disk; decryption happens in-process and the age private key never leaves the platform container's memory. **Application-encrypted fields** — OAuth connector tokens and similar credentials stored in the database — are encrypted with **AES-256-GCM** through a compact JWE (`alg: dir`, `enc: A256GCM`). The 32-byte key comes from `ENCRYPTION_SECRET` (base64) or `ENCRYPTION_SECRET_HEX` (hex); the platform refuses to start the encryption path with a key that is not exactly 32 bytes. The Convex data store and Postgres volumes are protected by the host: run them on an encrypted filesystem (LUKS, or your cloud provider's volume encryption). Tale does not store credentials in plaintext — a provider key or OAuth token is either SOPS-encrypted on disk or AES-256-GCM-encrypted in the database, never written in the clear. **Customer PII and application records** — names, email and postal addresses, conversation content — are protected at rest by the same layers that protect the database as a whole: Convex's at-rest encryption, TLS 1.3 in transit, and row-level security that scopes every read to the caller's organisation. Application-level field encryption is purpose-built for secrets — provider keys and OAuth tokens, written once and read by a single code path. PII is different: it is filtered, sorted, and looked up by exact value, and the customer table is indexed by organisation and email. Encrypting those columns at the field level would break equality lookups and indexed search — unless paired with a searchable-hash scheme that leaks the very equality it is meant to hide — while adding a key-rotation cost and no protection the encrypted host disk beneath the application doesn't already provide against a stolen volume. If your compliance regime calls for field-level PII encryption on top of these layers, that is a deliberate application change rather than a default Tale ships. ## Data in transit All browser and API traffic terminates TLS at the reverse proxy (Caddy), which negotiates TLS 1.3 (with TLS 1.2 as the floor) and obtains certificates automatically. The cipher suites are the proxy's modern defaults — AES-256-GCM and ChaCha20-Poly1305 with ECDHE key exchange. Configure the domain and certificate source in [TLS and domains](/self-hosted/configuration/tls-and-domains); traffic between containers stays on the host's internal Docker network. ## Password hashing Local-password accounts are hashed with **bcrypt** (via Better Auth), so a stolen database row does not reveal the password and a verification deliberately costs ~100 ms — which is also why the login path's timing is fuzzed (see [Authentication](/self-hosted/configuration/authentication)). Sessions are signed with `BETTER_AUTH_SECRET` (HMAC); rotating that secret invalidates every existing session. ## Audit-log integrity The audit log is tamper-evident through a **SHA-256 hash chain**: each entry stores `SHA-256(previousHash + canonicalized record)`, so altering or deleting any historical entry breaks the chain at that point and every entry after it. Entries additionally carry an **HMAC-SHA-256** signature. The admin integrity-check verifies both; see [Audit logs](/platform/admin/governance/audit-logs). ## Mapping to BSI TR-02102-1 Every primitive below is in the recommended set of BSI TR-02102-1. Tale does not ship any deprecated algorithm (no MD5, SHA-1, DES, or RSA < 3072 on a key it generates). | Use | Algorithm | Key / output size | Controlled by | | ----------------------- | --------------------------------- | ----------------- | --------------------------------------------- | | Provider secrets (disk) | AES-256-GCM + age (X25519) | 256-bit | `SOPS_AGE_KEY` / `SOPS_AGE_KEY_FILE` | | App fields (database) | AES-256-GCM (JWE `dir`/`A256GCM`) | 256-bit | `ENCRYPTION_SECRET` / `ENCRYPTION_SECRET_HEX` | | Transport | TLS 1.3 (AES-256-GCM, ECDHE) | 256-bit | Reverse proxy / `tls-and-domains` | | Password hashing | bcrypt | per-hash salt | Better Auth (built in) | | Session signing | HMAC-SHA-256 | 256-bit | `BETTER_AUTH_SECRET` | | Audit integrity | SHA-256 chain + HMAC-SHA-256 | 256-bit | built in | ## Key storage and rotation Three secrets are load-bearing, and each has a rotation path. The **age private key** (`SOPS_AGE_KEY`) decrypts provider secrets; rotate it by adding a new recipient and re-encrypting, following the walk in [Secrets with SOPS](/self-hosted/configuration/secrets-with-sops). The **field-encryption key** (`ENCRYPTION_SECRET`) decrypts database credentials; rotating it requires re-encrypting the affected rows, so plan it as a maintenance step rather than a hot swap. The **auth secret** (`BETTER_AUTH_SECRET`) signs sessions; rotating it logs everyone out on their next request. All three live only in the platform container's environment — never commit them, and store them in your secret manager of record. ## Where this fits Cryptography in Tale is layered: SOPS+age and AES-256-GCM protect secrets at rest, TLS 1.3 protects them in transit, bcrypt protects passwords, and a SHA-256 chain proves the audit log is intact — all primitives that sit inside BSI TR-02102-1's recommended set, with the controlling environment variables named above so you can verify your own instance. The layer beneath the application is the host itself: [Hardening](/self-hosted/operate/security/hardening) covers the egress allowlist, container isolation, and disk-encryption expectations that this page assumes, and [Secrets with SOPS](/self-hosted/configuration/secrets-with-sops) is the operational walk-through for the age key these algorithms depend on. # Hardening Source: https://tale.dev/docs/self-hosted/operate/security/hardening The defaults Tale ships with are safe for development and reasonable for a small production install. Going from "reasonable" to "ready for the regulator" is a checklist, not a configuration flag — every row below tightens one specific attack surface. Walk the list once before opening the URL to real users, and run it again after every major upgrade. The reference detail for each row lives elsewhere — TLS in [TLS and domains](/self-hosted/configuration/tls-and-domains), backups in [Backups and restore](/self-hosted/operate/backups-and-restore), retention in [Retention](/self-hosted/configuration/retention). This page is the index that names what to harden and points at the page that walks it. ## Host | Item | Why it matters | | ------------------------------ | ------------------------------------------------------- | | Non-root operator user | Limits blast radius if the platform user is compromised | | SSH key auth only | Password auth is the open door bots scan for | | Unattended security updates | Patches the OS without waiting for a maintenance window | | Host firewall (ufw / nftables) | Closes everything that is not 22, 80, 443 | | Disk encryption at rest | Required if you run SOPS in plaintext mode | The non-root user is the one most teams skip. Tale's containers run their own non-root processes inside, but the docker daemon itself runs as root — operating that daemon as the operator user (member of the `docker` group, not as root) is the cheapest tightening on this page. The full walk lives in [Production Linux server install](/self-hosted/install/linux-server). ## Network The proxy is the only inbound surface. Block everything else. ```bash sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow OpenSSH sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable ``` If you run trusted-headers auth, the platform port must not be reachable directly from anywhere except the upstream proxy — anything that can hit it with the right headers becomes that user. A Docker network or a host firewall rule both work; pick one and verify it from outside the host. ## TLS `TLS_MODE=selfsigned` is for development. Production runs `letsencrypt` (or `external` if you front Tale with your own TLS-terminating proxy). The renewal cron is automatic; the alert that fires when renewal fails is what saves you 90 days later. See [TLS and domains](/self-hosted/configuration/tls-and-domains). ## Secrets Every secret in `.env` is sensitive — the auth signing secret, the encryption key, the database password, the age key, the metrics bearer token. The minimum bar: - `.env` is mode 0600 and owned by the operator user. - `BETTER_AUTH_SECRET`, `ENCRYPTION_SECRET_HEX`, `INSTANCE_SECRET` are rotated off the example values that ship in `.env.example`. - `DB_PASSWORD` is changed from the default placeholder. - `SOPS_AGE_KEY` or `SOPS_AGE_KEY_FILE` is set — leaving both unset is supported but reserved for disk-encrypted hosts with external secret management. The full SOPS walk and rotation procedure lives in [Secrets with SOPS](/self-hosted/configuration/secrets-with-sops). ## Audit logs Audit logs are immutable and retention-bound. Compliance frameworks expect at least a year; the bound is enforced per-deployment, so the strictest org's setting is what actually runs. Set the floor in your operator config to match the loosest framework you support, and make sure backups capture audit-log rows along with the rest of the database. The retention reference lives in [Retention](/self-hosted/configuration/retention). ## Backups A backup that has not been restored is a hope, not a backup. The minimum: daily Postgres dumps written by the `tale-db` cron, copied off-host within the hour, and a quarterly restore drill that rebuilds a working instance from the snapshot. The full procedure is in [Backups and restore](/self-hosted/operate/backups-and-restore). ## Sandbox isolation Run-code is the riskiest surface in the product — the only place where user-supplied input becomes executed code. `tale-sandbox` runs with no privileged caps, its network is internal-only, and `tale-sandbox-egress` is its only outbound path. At the hostname layer that path is open by default: sandboxed code reaches any public host over HTTPS, while cloud-metadata endpoints and private address ranges are always blocked at the IP layer — that floor holds in every configuration. The hardening lever is `SANDBOX_EGRESS_ALLOWLIST`. Set it in `.env` to a pipe-separated list of hostname regexes and recreate `tale-sandbox-egress`, and the proxy flips to default-deny — only matching hosts are reachable. A registry-only lockdown that keeps pip, npm, uv, and git-over-HTTPS working: ```bash SANDBOX_EGRESS_ALLOWLIST=^pypi\.org$|^files\.pythonhosted\.org$|^registry\.npmjs\.org$|^objects\.githubusercontent\.com$|^codeload\.github\.com$|^github\.com$|^api\.github\.com$ ``` Keep the list short and prefer specific hosts over wildcards. Package installs are gated separately, through the [run-code policy](/platform/admin/governance/run-code-policy) screen. ## Monitoring `METRICS_BEARER_TOKEN` is unset in `.env.example` — that is intentional, so a fresh install does not leak metrics. Set the token, scrape from your Prometheus, and the alert thresholds in [Operations](/self-hosted/operate/observability/operations) cover the customer-impacting signals. The audit-log hash chain is verified automatically every night by a scheduled integrity check. A genuine break raises a critical security alert to the organisation's admins — in the notification bell, and in your Slack channel when one is connected — so tampering surfaces even when nobody is watching the logs; a signed checkpoint that can't be verified because `TALE_AUDIT_SIGNING_KEY` is unset alerts more calmly, as the configuration gap it is. The alert fires once when a break is first detected or when it changes, not every day for the same break. Admins re-run the verification on demand from the **Chain integrity** panel on **Settings > Governance > Logs** — a status badge, the last-check time, and a **Verify now** button. When one fires, work the [audit-log integrity runbook](/self-hosted/operate/security/audit-log-integrity) to tell a real break from a benign retention or configuration artifact. ## HTTP security headers Every HTML response carries a strict set of security headers, and the set is locked by tests so an upgrade cannot silently drop one. The platform web client (`services/platform`) sends a nonce-based Content-Security-Policy with no `unsafe-inline` scripts, HSTS on HTTPS, `X-Content-Type-Options: nosniff`, `X-Frame-Options: DENY` alongside CSP `frame-ancestors 'none'`, `Referrer-Policy: strict-origin-when-cross-origin`, a restrictive `Permissions-Policy`, and `X-Permitted-Cross-Domain-Policies: none`. It scores A+ on the MDN HTTP Observatory, and that grade is asserted by the CI test suite — the scoring is re-implemented in tests that fail the build on any regression. The marketing site and the docs site ship the same header family, adding `Cross-Origin-Opener-Policy` and `Cross-Origin-Resource-Policy` set to `same-origin`. Verify it against your own deployment: - `curl -sI https://<your-host>/ | grep -iE 'content-security|strict-transport|x-frame|x-content-type|referrer-policy|permissions-policy|cross-origin'` - Scan the host on [securityheaders.com](https://securityheaders.com) or the [MDN HTTP Observatory](https://developer.mozilla.org/en-US/observatory). <!-- The MDN Observatory UI is only localized in some languages. When adding a new docs language, check whether developer.mozilla.org/<lang>/observatory exists and fall back to the en-US analyze links if it does not. --> The public demo is the live reference for what a correct deployment reports: the [Observatory scan of demo.tale.dev](https://developer.mozilla.org/en-US/observatory/analyze?host=demo.tale.dev) came back A+ on 15 July 2026 — score 115/100, all ten tests passed. The one header the report lists as not implemented, `Cross-Origin-Resource-Policy`, costs no points; it is the deliberate exception described below. Cross-origin isolation (COOP/CORP) is deliberately left off on the platform app: `Cross-Origin-Opener-Policy: same-origin` would sever the live window handle an OAuth sign-in popup uses to hand the finished sign-in back to the app, and `Cross-Origin-Resource-Policy` would block branding assets loaded from a second host. The content sites, which do neither, enable both. HSTS is emitted only when `SITE_URL` is `https://`. ## Where this fits Hardening is not a one-pass task — the list above is what to walk before launch, and re-walk after every upgrade or after every change to the network shape. The next thing worth reading after this is whichever row above you have not done yet. # Upgrades Source: https://tale.dev/docs/self-hosted/operate/upgrades Upgrades on a self-hosted Tale instance run through two commands: `tale update` moves the CLI binary to the new version and syncs your project files to match, then `tale deploy` rolls the platform containers. The deploy uses a blue-green pattern — the new colour starts alongside the old, healthchecks pass, traffic flips, the old colour drains. Zero downtime is the default; if a patch release misbehaves, `tale rollback` returns to the previous patch in one command, and anything bigger recovers from the pre-upgrade snapshot. **One hard exception:** there is no upgrade path from 0.3.x to 0.4. 0.4 is a breaking cutover that requires a fresh deployment — see [0.3 → 0.4: breaking cutover](#03--04-breaking-cutover) before anything else if your instance is on 0.3.x. What you no longer do is keep the CLI in sync by hand: the CLI aligns itself to the instance automatically (see below), so the only deliberate step is choosing when to move versions with `tale update`. The CLI install lives in [Install the tale CLI](/self-hosted/install/cli-install). This page covers what each command does and how the version model works. ## The CLI tracks the instance automatically The CLI binary is always the same version as the instance it manages. The workspace records that version in `tale.json`; on every command the CLI compares its own version against it and, if they differ, self-updates the binary to match (up or down) before running. When they already match — the overwhelmingly common case — this is a no-op with no network call, so you never notice it. That means you rarely run `tale update` except when you deliberately want to move to a new version. A teammate who installed a newer CLI than your instance, or restored an older snapshot, gets the right CLI version automatically on their next command. There is no flag to turn this off — keeping the tool and the instance in lockstep is what makes deploys safe. ## Before you upgrade Two things are worth confirming first: - Your off-host copy of the `backups` volume is current — see [Backups and restore](/self-hosted/operate/backups-and-restore). `tale update` snapshots the data volumes automatically before any step that can migrate data, but the snapshot lives on the same host; the off-host copy is what survives a dead disk. - The release notes for the target version do not name a breaking change. The notes are linked from the GitHub release page; breaking changes are flagged as such at the top. If the upgrade crosses a major version (1.x → 2.x), read the migration notes end-to-end before starting. Major versions are where schema migrations and config-file format changes land. ## The two commands `tale update` updates the CLI binary and then syncs your project files to that version's templates. It does **not** touch the running containers — that is `tale deploy`'s job. If the file sync fails, the CLI rolls its own binary back to the version your workspace was on, so the binary and `tale.json` never drift apart. Run bare, the command targets the newest release **in your current x.y release line** — a 0.3.x instance moves to the newest 0.3.x. Releases on a newer line can be breaking, so `tale update` never crosses that boundary on its own: when a newer line exists it says so and stays put. Moving lines is a deliberate step — read the release notes for the new line first, then pin it with `--version`. ```bash # Move the CLI + project files to the newest release in the current x.y line tale update # Pin a specific version — the only way to change lines; allows downgrades (see Rolling back) tale update --version 0.10.2 # Preview the version change and file sync without touching anything tale update --dry-run ``` `tale deploy` does the actual rolling restart, and it always deploys the CLI's own version — which, thanks to alignment, is the version your workspace records. It sorts the services into three tiers: - **App tier** — `platform` — rolls on **every** deploy with zero downtime (blue-green: the new colour starts alongside the old, healthchecks pass, traffic flips, the old colour drains). - **Backend & compute** — `convex`, `sandbox`, `sandbox-egress` — roll on every deploy too, so they never version-skew from `platform`. Each is a single container that recreates **in place** when its image actually changed; the deploy first drains its in-flight work (chat generations for `convex`, agent runs for `sandbox`) so the brief restart doesn't cut a live request. - **Stop-gated tier** — `db`, `proxy` — left **running and untouched** by default (recreating Postgres or the proxy is a brief outage you don't want on a routine roll). Pass `--stop` to update them; the deploy warns and names them when it skips. ```bash # After tale update, roll the containers to match (app tier + convex) tale deploy # Also update db/proxy (brief downtime while they recreate) tale deploy --stop # Roll only specific services tale deploy --services platform # Preview without changes tale deploy --dry-run ``` `--dry-run` is worth running before every production upgrade — it surfaces missing images, missing migrations, and dependency mismatches without touching the running containers. ## The blue-green pattern A running instance is one of the two colours (blue or green) at any given time. The deploy phase brings up the other colour, waits for it to pass healthchecks, then flips Caddy's upstream to the new colour. The old colour drains its in-flight requests (default 30 s), then exits. Three guarantees the pattern gives you: - **No window where both colours serve traffic.** A database constraint enforces single-active — Caddy routes to the healthy one. - **Patch rollback is one command.** `tale rollback` redeploys the previous patch release on the idle colour and flips traffic back. It refuses minor and major downgrades — those can leave the database ahead of the binary, and their recovery path is a snapshot restore. - **Failed healthchecks block the flip.** If the new colour does not pass within the timeout, the deploy aborts and the old colour continues serving. The full deploy procedure including the cleanup phase lives in `tale --help`; the operator-facing recipe is `tale update && tale deploy && tale status` and visual confirmation in the browser. ## Working with data migrations The migration chain starts at the **0.4.0 baseline**: releases from 0.4.0 on carry versioned migrations for the changes they ship, and nothing older — pre-0.4 history is not in the binary (that is what makes the 0.3 → 0.4 cutover breaking). Within the 0.4.x line, every deploy applies pending data migrations automatically — but only the non-destructive ones. Migrations that remove or overwrite data (a table drop, a column removal) are never run unattended: the deploy skips them, prints which ones are waiting, and leaves the decision to you. ```bash # What is applied, what is pending, what failed tale migrate status # Apply pending migrations, reviewing each destructive step tale migrate up --step # Apply everything without prompting (CI / after reviewing the plan) tale migrate up --yes # Roll data back to an earlier version (0.4.0 or later) tale migrate down --to 0.4.0 ``` Destructive migrations snapshot the affected rows or config files before touching them, so `tale migrate down` can rebuild what they removed. Both directions are resumable: progress is tracked per migration (and per organization for config-file migrations), so a crash or timeout picks up where it stopped instead of starting over. If a migration fails during a deploy, the platform still boots on its current schema — the boot log prints a prominent error and `tale migrate status` shows the failed migration with the recorded error. Fix the cause, then re-run `tale migrate up`; already-completed work is skipped. ## Rolling back ```bash # Back to the previous patch version (prompts for confirmation) tale rollback # Skip the prompt when running non-interactively tale rollback --yes ``` `tale rollback` is gated to patch-level steps: it only targets the recorded previous version, and refuses unless that version shares `major.minor` with the running platform. Patch releases never carry migrations, so redeploying the previous patch is always safe. Anything bigger may have migrated data forward — redeploying an older binary on top of migrated data corrupts the instance instead of recovering it. For those, the recovery path is restoring the pre-upgrade snapshot and moving back to the version that matches it with `tale update --version <version>` followed by `tale deploy --stop` (so `db`/`proxy` roll back too); the refusal message prints the exact commands, and the full walk lives in [Backups and restore](/self-hosted/operate/backups-and-restore). Because the rollback tears down the running containers, the command warns what it is about to do and asks for confirmation before it pulls a single image; pass `--yes` to skip that prompt in scripts or CI. ## Version compatibility Tale versions are semver. The compatibility rules: - Patch (`0.9.0 → 0.9.1`) — no migrations, no config changes, `tale rollback` is always safe. - Minor (`0.9.x → 0.10.x`) — may include forward-only migrations; `tale rollback` refuses, recovery is restore-snapshot-and-redeploy. - Major (`0.x → 1.x`) — read the migration notes, schedule the maintenance window, expect surprises. - **The 0.4.0 baseline** — versions below 0.4.0 and versions from 0.4.0 on are separate worlds: no upgrade in either direction, see the cutover section below. Skipping minor versions (going from 0.9 to 0.11) is supported as long as the intermediate migrations are still in the binary; the release notes call it out when this is not the case. The 0.4.0 baseline is the standing instance of that exception: pre-0.4 migrations are not in any 0.4+ binary. To move _down_ a version deliberately — say a minor release misbehaves and you have already reversed its migrations — pin the target with `tale update --version <version>`. The command warns when the target is older than the running version and reminds you to reverse data migrations first. A downgrade below 0.4.0 crosses the cutover backwards and is not supported: a 0.3.x release cannot read data created by 0.4+ — restore a pre-0.4 snapshot or deploy 0.3.x fresh instead. ## 0.3 → 0.4: breaking cutover 0.4 rebuilt the platform's AI backend, and with it the data model, from a clean baseline. The versioned-migration history was reset at 0.4.0: no 0.4+ release carries the pre-0.4 migrations, so **a 0.3.x instance cannot be upgraded in place — 0.4 requires a fresh deployment.** **What this means in practice:** - `tale deploy` with a 0.4+ CLI **refuses** to touch an instance whose running version is below 0.4.0, before pulling an image or writing anything. The container has the same guard at boot (log marker `[migrations][breaking-cutover]`) for stacks managed outside the CLI. - Nothing from a 0.3 instance is carried over: chats, automations and their run history, knowledge entries, task history, users and sign-ins. Files in a BYO-S3 bucket physically remain in the bucket, but the new instance has no references to them. - The 0.3.x line stays maintained for security and critical fixes on the `release/0.3` branch — staying on 0.3.x for a while is a supported choice, moving to 0.4 is a re-onboarding, not an upgrade. **Moving to 0.4:** ```bash # 1. Leave the 0.3 instance untouched (it keeps serving). # 2. Create a NEW project directory with a 0.4 CLI: mkdir tale-04 && cd tale-04 tale init tale deploy # 3. Re-onboard: organizations, users (invite / SSO), configuration, # documents and knowledge re-upload. # 4. Decommission the 0.3 instance once the new one is accepted. ``` The expert override — `tale deploy --accept-data-loss`, or `TALE_ACCEPT_DATA_LOSS=1` on the container — exists for the rare case where you deliberately reuse a host whose old volumes you have already dealt with. It does exactly what its name says: pre-0.4 data on that instance becomes permanently unreadable. ## Where this fits The upgrade flow ties together every other operate page — backups are what makes a failed upgrade recoverable, observability is what tells you the new colour is healthy, hardening is what you re-walk after a major version. If you are setting up the CLI for the first time, [Install the tale CLI](/self-hosted/install/cli-install) covers the workstation-side setup; if you are picking up the pager mid-rollout, [Troubleshooting](/self-hosted/operate/observability/troubleshooting) names the symptoms. # Self-hosted architecture Source: https://tale.dev/docs/self-hosted/overview A Tale instance is eight containers behind a Caddy proxy, talking to two Postgres databases — one operational, one for the knowledge corpus; two of them are sandbox containers off to the side for code execution. The compose file is the contract — what runs, what is exposed, what is mounted. This page hands you the mental model so the install, configure, and operate pages do not have to re-explain it. Read this before you `docker compose up`. Come back when you are debugging an outage and need to know which container's logs to open first. ## The eight containers **tale-proxy** is Caddy at the edge. It terminates TLS, routes everything under `/` to the platform container, and forwards everything under `/api/` and the Convex paths to the convex container. Healthchecks live here. **tale-platform** is the React + TanStack Start server. It renders the UI, serves static assets, and is the only container exposed to the browser. It does not hold business state — everything that needs to persist talks to convex. **tale-convex** is the backend: the actions, queries, mutations, and the WebSocket layer the UI subscribes to. Provider keys, agent definitions, workflow runs, audit logs all live here. It also runs the knowledge work in-process — document ingestion, web crawling, RAG search, and document generation are Convex node-actions, not separate services. The headless work those jobs need (rendering a web page, turning HTML into a PDF or image) is delegated to the sandbox runtime, which already ships Chromium and Playwright. **tale-db** is the operational Postgres (ParadeDB). It holds the Convex backend data — agents, runs, the audit log — and is one of the two stateful containers that matter for backups. **tale-knowledge-db** is the knowledge corpus Postgres (ParadeDB), the `tale_knowledge` database with two schemas: `private_knowledge` (uploaded-document chunks, embeddings, the BM25 index, the semantic cache) and `public_web` (crawled web pages). It is split from `tale-db` so the corpus — the data-residency-sensitive store — can be relocated or replaced on its own. The Convex backend connects to it directly; nothing else does. **tale-sandbox-llm-gateway** is the LLM gateway for harness turns. It is the only path from a sandboxed harness to a model provider; the platform provisions it and mints per-session keys. **tale-sandbox** and **tale-sandbox-egress** run sandboxed code on behalf of the `Run code` tool and skill scripts, and serve as the headless-browser runtime the convex backend calls for web rendering and document generation. The egress container is the only path the sandbox has to the network. Egress is open by default — sandboxed code reaches any public host over HTTPS while cloud-metadata and private-range targets stay blocked at the IP layer; lock it down to a hostname allowlist with `SANDBOX_EGRESS_ALLOWLIST`, described in [Hardening](/self-hosted/operate/security/hardening). One more service ships but stays off by default: **tale-controller** is an opt-in sidecar (the `controller` compose profile) that restarts the convex container on a signed request from the app, so a data-residency change can apply without giving the browser-facing platform Docker-socket access. ## Data on disk Four volumes survive a `docker compose down`: - `db-data` — the operational Postgres data directory: the database behind agents, runs, and the audit log. - `knowledge-db-data` — the knowledge corpus Postgres data directory: document chunks, embeddings, the search indexes, and crawled web pages. Backs up separately from `db-data` because it is a separate database. - `backups` — checksummed volume snapshots written by `tale backup` and automatically before migrating deploys; [Backups and restore](/self-hosted/operate/backups-and-restore) is the drill. - The convex object-store mount — uploaded files, generated documents, exported bundles. Everything else is ephemeral. Containers can be replaced without data loss as long as the volumes survive. ## Provider secrets and the SOPS layer Provider keys (OpenAI, Anthropic, Azure, Ollama, etc.) live on disk in a `providers/` directory mounted into the platform container. Each provider has a `<name>.json` and a `<name>.secrets.json`; the secrets file is encrypted with SOPS and the [`SOPS_AGE_KEY`](/self-hosted/configuration/environment-reference) variable. This split exists for two reasons. Rotating a provider key is editing one file, not re-running the platform; backing up the encrypted file is safe to commit alongside infrastructure. The plaintext mode (no SOPS, secrets in cleartext) is supported for tightly controlled environments where the disk itself is encrypted at rest. ## Auth and sessions Sign-in is Better Auth running inside the convex container. Four sign-in modes ship: local password, Microsoft Entra (OAuth/OIDC), generic OIDC, and trusted headers (the reverse proxy provides the identity). The platform container reads the cookie, hands it to convex, and convex decides what the session can do based on the user's role and the per-resource permission matrix documented in [Members and roles](/platform/admin/members-and-roles). The [authentication reference](/self-hosted/configuration/authentication) covers the env vars and the per-mode trade-offs. ## When you outgrow single-host The default compose file runs all eight containers on one host. The architecture is single-tenant: nothing in the design splits work across hosts. The first thing you can move off the box without re-architecting is the knowledge corpus — `tale-knowledge-db` is a standalone Postgres, so pointing it at managed infrastructure (for capacity or for a residency requirement) is a connection-string change, covered in [Data residency](/self-hosted/configuration/data-residency). The Convex layer is still single-instance; horizontal scaling of the backend is not a v1 feature. ## Where this fits This architecture page is the map every other self-hosted page assumes. The natural next read is [Quickstart](/self-hosted/install/quickstart) if you are setting up a fresh instance, or [Container architecture](/self-hosted/operate/container-architecture) if you are operating one and need the same picture with the failure modes overlaid. # Connect a local LLM provider Source: https://tale.dev/docs/tutorials/admin/connect-local-provider A local provider is the path to running models inside your own perimeter — no outbound API calls, no per-token bill, no third-party transcript. This walk takes a self-hosted Tale instance from "I have an Ollama, LM Studio, or vLLM endpoint" to "a chat in the org calls a local model and the reply streams back." The walk is for an Admin on a self-hosted install; Cloud orgs do not reach onto your network and skip this page. You need the Admin role in Tale, a local inference server reachable from the `tale-platform` container over TLS, and a model already pulled or loaded on that server. The connector format and the credential model are documented in [Providers](/self-hosted/configuration/providers); this page walks one end-to-end path and verifies the result. ## Before you begin Confirm four things. Your role is Admin or Owner — **Settings > AI providers** is hidden below that. Your local inference server answers `GET /v1/models` (or the Ollama equivalent `GET /api/tags`) from inside the Tale Docker network. At least one model is loaded — Ollama users have run `ollama pull llama3.1:8b` or similar, LM Studio users have a model loaded in the server tab, vLLM users have started the server with `--model` pointed at a checkpoint. And the server is reachable over `https://`: a connector's base URL must be an HTTPS URL, so terminate TLS in front of the inference server — a reverse proxy with an internal certificate is the usual answer — rather than exposing it in the clear. ## Step 1 — Make the inference server reachable from Tale The first move is confirming that `tale-platform` can reach the inference server by hostname over TLS. Without that, every model call surfaces a connection error and no model is callable. When the inference server runs behind a proxy in the same Docker network, the reachable hostname is that proxy's service name. Run a one-shot curl from the `tale-platform` container to verify before you write any configuration: ```bash docker compose exec platform curl -sf https://ollama.internal/api/tags ``` A JSON list of pulled models is the success signal. A connection error means the hostname is wrong, the certificate is not trusted, or the inference server is not listening on the interface the container can reach. ## Step 2 — Declare the connector Shipped connectors cover the public vendors; a machine on your own network is an org-defined connector — one YAML file in the organisation's config tree. The file tells Tale where to send requests, which wire dialect the endpoint speaks, and where its model list comes from. Write `$TALE_CONFIG_DIR/<orgSlug>/providers/local-ollama.yml`. The `name` must match the filename stem, and it must not collide with a shipped connector's name: ```yaml name: local-ollama displayName: Local Ollama apiFormat: openai baseUrl: https://ollama.internal/v1 catalog: source: models-endpoint auth: - method: api-key - method: env ``` `apiFormat: openai` is right for Ollama, LM Studio, and vLLM — all three expose the OpenAI Chat Completions shape. `catalog.source: models-endpoint` tells Tale to list models from `GET {baseUrl}/models` instead of shipping a static list, which is what you want when the loaded models change. A file that fails to validate is skipped and the reason is logged, so read the platform log if the connector does not appear. ## Step 3 — Store the credential A connector on its own calls nothing. What authorises a request is a credential stored against that connector, and a connector holds as many as you need. Open **Settings > AI providers**. The new connector sits beside the shipped ones; click **Add credential** on it. Pick **API key** and paste whatever token your server expects — LM Studio ignores the value, vLLM wants the token you passed to `--api-key`. Name the credential for the machine it reaches (`GPU box, rack 2`), and leave the **Model allowlist** empty to expose everything the server lists, or pick the subset the org may call. The first credential on a connector becomes its default. Prefer the key to live on the deployment instead? Pick **Environment variable** and name a deployment variable under the reserved `TALE_PROVIDER_KEY_` prefix. The secret then never enters Tale's own store, and your operations team owns rotation. ## Step 4 — Verify with a chat The proof the wiring works is one chat reply streaming from the local server. Without this step you only know the configuration parses. Open a new chat, open the model picker, and pick one of the local models by name — do not leave the picker on **Auto**, which may route this message to another provider; this step needs the reply to come from the machine you are watching. Send a short prompt (`Reply with the single word "ready"`). The reply streams in within a few seconds. Tail the inference server log on the host while you send the prompt — Ollama logs the request line, LM Studio prints a request summary, vLLM prints the generation latency. Seeing the request hit the local server is the verification that traffic is staying inside your network, not bouncing through an external API. ## Troubleshooting - **Symptom:** the connector never appears under **Settings > AI providers**. **Cause:** the YAML failed to validate, or its `name` does not match the filename stem. **Fix:** read the platform log — a rejected connector is logged with the file and the reason — and correct the file. - **Symptom:** the connector appears but its model list is empty. **Cause:** the inference server is reachable but has no models loaded, or its `/models` endpoint answered an error. **Fix:** load a model, then click **Refresh catalogs** on the providers page. Catalogs update only when you refresh them. - **Symptom:** the file is rejected because the base URL is not HTTPS, or points at `localhost`, `127.0.0.1`, or a private IP. **Cause:** connector base URLs are HTTPS-only, and the host policy blocks loopback and private addresses. **Fix:** put a TLS-terminating reverse proxy in front of the inference server and use its in-network hostname. - **Symptom:** the chat reply is an error naming the model. **Cause:** the model id does not match the upstream one. **Fix:** re-pick from the model picker — Ollama tags like `:latest` matter to the upstream and must match exactly. ## Where this fits A local provider is the seam between Tale and your own GPUs — the same connector-and-credential shape as a public vendor, but no traffic leaves your network. The natural next reads are [Providers](/self-hosted/configuration/providers) for the connector format in full and the environment-variable credential path, and [Hardening](/self-hosted/operate/security/hardening) for the egress guarantees that keep an agent from reaching a cloud model you did not intend. # Pipe meeting transcripts into the Knowledge Base Source: https://tale.dev/docs/tutorials/admin/meeting-transcription A meeting transcript is one of the highest-value documents a project can keep — names, decisions, follow-ups, all in one searchable place. This walk integrates Meetily, a local meeting-transcription tool, with a Tale project so every transcript Meetily produces lands in the project's Knowledge Base as a document on its own. The walk is for an Admin on a self-hosted Tale instance pairing it with a Meetily install on the same network. You need an Admin role in Tale, a Meetily install reachable from the `tale-platform` container, and one project in Tale with a Knowledge Base you want the transcripts routed into. The Knowledge Base concept lives in [Knowledge Base](/platform/knowledge/overview); this page is the connector walk, not the concept page. ## Before you begin Confirm four things. Your role is Admin or Owner in Tale — the **Connectors** panel is hidden below that. Meetily is running and producing transcripts in a format Tale accepts (Markdown, plain text, or VTT). The Meetily host is reachable from `tale-platform` on its webhook or shared-folder path. And the target project already exists in Tale with a Knowledge Base attached — the connector writes _into_ a Knowledge Base, it does not create one. ## Step 1 — Pick a delivery path Meetily can hand transcripts to Tale in two shapes, and they have different operational properties. The pick locks in how the rest of the walk reads. The **webhook** path has Meetily POST each finished transcript to a Tale ingestion endpoint as soon as the meeting ends; the transcript is in the Knowledge Base within seconds of the meeting closing. The **shared folder** path has Meetily write transcripts as files into a directory the Tale platform polls every minute; latency is up to a minute but the path needs no public URL and survives Meetily restarts without retry logic. Pick webhook when both services run in the same network and you want fast indexing; pick shared folder when Meetily runs on a workstation that wakes irregularly or when the operations team prefers a file-based audit trail. ## Step 2 — Create the ingestion endpoint or folder in Tale Tale needs to know where transcripts will land and which project they belong to. Without this binding, transcripts arrive but no Knowledge Base claims them. Open **Settings > Connectors**, click **Add connector**, and pick **Meeting transcripts**. Pick the project from the dropdown — the Knowledge Base the project uses is the destination. Pick the delivery path you chose in Step 1. If you picked webhook, Tale generates a URL of the shape `https://<your-host>/connectors/transcripts/<token>` and shows it once. Copy the URL; it doubles as the bearer credential, so treat it like a secret. If you picked shared folder, Tale prompts for the path on disk that `tale-platform` should watch (typically `/data/transcripts/<project-slug>`). Create the directory on the host, give it group ownership matching the `tale-platform` container user, and confirm. ## Step 3 — Point Meetily at Tale Meetily now needs to know where to deliver each transcript. The settings live in Meetily's own config. For the webhook path, open Meetily's settings and add a webhook destination with the URL from Step 2. Pick the transcript format — Markdown is what reads best inside a Tale document preview, but VTT and plain text both index correctly. For the shared-folder path, set Meetily's transcript-output directory to the path you created in Step 2. Make sure Meetily writes one file per meeting, named with the meeting title and timestamp. End a short test meeting in Meetily and watch the Tale Connectors panel. The connector row shows a **Last delivery** timestamp that updates within a minute (folder mode) or a few seconds (webhook mode). ## Step 4 — Verify the document lands and indexes The proof the wiring works is one transcript visible in the Knowledge Base as a searchable document. Without this step you do not know whether Tale received the file _and_ indexed it. Open the target project, navigate to its Knowledge Base, and look for the new transcript at the top of the document list. Click into the preview — the transcript renders as a document with the meeting title as the document name and the meeting date as the document's created-at. Wait for the indexing badge to clear (a few seconds for a short transcript, up to a minute for a long one), then run a search for a name or a phrase you remember from the test meeting. The transcript should be the first result with the phrase highlighted. If the document is there but the indexing badge stays orange, indexing is behind — the [Troubleshooting](/self-hosted/operate/observability/troubleshooting) page names the symptoms. ## Privacy notes The connector crosses one network in each direction and the data shape matters. - **Meetily → Tale.** The transcript body crosses, plus the meeting title, the timestamp, and any speaker labels Meetily attached. Audio does not cross — Meetily transcribes locally and only the text is delivered. The webhook path uses HTTPS with the bearer token in the URL; the folder path uses a filesystem path with no network at all. - **Tale → Meetily.** Nothing. The connector is one-way; Tale never calls back into Meetily. - **Tale → external services.** The transcript text crosses to whichever embedding provider is bound to the Knowledge Base. If the embedding provider is a local one (Ollama, LM Studio, vLLM via [Connect a local LLM provider](/tutorials/admin/connect-local-provider)), no transcript text leaves the host. If the embedding provider is OpenAI, Anthropic, or another hosted endpoint, the transcript text is sent to that endpoint for vectorisation per the provider's data-handling policy. When transcripts contain content the org cannot send to a cloud provider, the supported pattern is to bind the project's Knowledge Base to a local embedding model. The provider-bind happens in the Knowledge Base settings, not in this connector. ## Where this fits The meeting-transcription connector is the cleanest example of "Tale indexes what your other tools already produce" — no copy-paste, no manual upload, no extra step in the meeting workflow. The natural next reads are [Knowledge Base](/platform/knowledge/overview) for what the indexed transcript can then be used for inside an agent, and [Connect a local LLM provider](/tutorials/admin/connect-local-provider) when the privacy section above pushes you toward keeping the embedding step on-host. # Install the Outlook add-in Source: https://tale.dev/docs/tutorials/admin/office-add-in The Outlook add-in surfaces a Tale sidebar inside Outlook on the web, desktop, and mobile. From the sidebar a member picks an agent, drops the open mail thread in as context, and gets a draft reply back without switching apps. This walk is for an Admin rolling the add-in out across an org; it covers the manifest deploy, the sign-in, and the verification. You need an Admin role in Tale, a Microsoft 365 tenant where you can manage Integrated Apps, and a Tale instance reachable from the Microsoft 365 cloud. Cloud orgs are reachable by default; self-hosted instances need a public HTTPS URL. ## Before you begin Confirm three things on the Microsoft side: you are a Global Administrator (or have the Exchange Admin role with Integrated Apps), centralised deployment is enabled for your tenant, and the mailbox you will test with has not blocked add-ins via mailbox policy. On the Tale side, open **Settings > Connectors** and check that **Microsoft 365** is listed — that is where the add-in publishes the manifest URL. ## Step 1 — Get the manifest URL from Tale The add-in talks to Tale through a manifest XML the Microsoft 365 admin centre hosts. Tale generates the manifest per instance so the sidebar points at your URL, not at a shared multi-tenant endpoint. Open **Settings > Connectors > Microsoft 365** and copy the **Add-in manifest URL** the panel shows. You should see a URL ending in `/connectors/office/manifest.xml`. Open it in a new tab to confirm it returns XML and not an HTML error page — if it errors, your instance is not reachable from outside or the connector is disabled. ## Step 2 — Deploy through the Microsoft 365 admin centre The manifest is what tells Microsoft 365 which mailboxes can see the sidebar and what URL to load it from. Centralised deployment is the supported path; user-by-user side-loading works but does not survive a mailbox migration. Open the Microsoft 365 admin centre, navigate to **Settings > Integrated apps > Upload custom apps**, choose **Office Add-in** and **Provide link to manifest file**, and paste the URL from Step 1. Pick the rollout audience — the whole tenant, a security group, or a specific list of users. Submit. Microsoft confirms the deployment with a green banner; the rollout typically reaches mailboxes within an hour, sometimes a few hours on a large tenant. ## Step 3 — Sign in from the sidebar Open Outlook as a user in the rollout audience, click any mail message, and look for the Tale icon in the message ribbon. Clicking it opens the sidebar; on first open it asks the user to sign in with their Tale account. The sign-in is OAuth through the Tale instance — same identity provider as the web app. After sign-in the sidebar lists the user's available agents. Picking one and clicking **Draft reply** pulls the open mail thread in as context and streams a reply into the sidebar. The user reviews, edits, and clicks **Insert** to drop it into the Outlook compose pane. ## Where this fits The add-in is the lightest path to "Tale where your members already work" — no portal switch, no copy-paste. The sidebar is a thin shell around the same agents you publish in [Create an agent](/platform/agents/create); changes to the agent's instructions, knowledge, or tools land in the sidebar on the next request. For the broader connector story — Slack, Gmail, custom MCP servers — see [Connectors overview](/platform/connectors/overview). If you operate a self-hosted instance and the manifest URL is unreachable from Microsoft 365, the [Linux server](/self-hosted/install/linux-server) page covers the public-HTTPS prerequisite. # Build a custom tool Source: https://tale.dev/docs/tutorials/developer/build-a-custom-tool A custom tool is a function you write that an agent's model can call by name. You declare the input schema and the return shape; Tale handles serialisation, the tool-call card in the chat, and the result hand-back to the model. This walk takes a fresh custom tool from "I have a function in mind" to "the agent calls it from a chat" on a single instance. You need a Developer role in the org and access to the **Settings > Custom tools** panel; everything else is in the UI. The underlying concept lives in [Agent tools](/platform/agents/tools); the developer-facing surface — schemas, transport, errors — is the focus here. ## Before you begin Confirm two things. First, your role is at least Developer — the panel is hidden below that. Second, you have an agent you can edit; if not, create one through [Create an agent](/platform/agents/create) before continuing. The walk uses a single-input, single-output tool called `lookup_order` that takes an order ID and returns a status string — the smallest shape that exercises the schema, the call, and the result rendering. ## Step 1 — Define the tool in Custom tools The first move is registering the tool name and its JSON Schema. The schema is what the model sees; without a schema the model has no idea what arguments to emit, and the call never happens. Open **Settings > Custom tools** and click **New tool**. Give it a name (`lookup_order`), a one-sentence description (`Look up the status of an order by ID`), and a JSON Schema for the input: ```json { "type": "object", "properties": { "orderId": { "type": "string", "description": "The order ID, e.g. ORD-12345" } }, "required": ["orderId"] } ``` Save. The tool is now registered in the org's custom-tool registry; no agent uses it yet. ## Step 2 — Wire the implementation A registered tool with no implementation returns an error to the model. Tale exposes two implementation modes: an inline sandbox script (Python or JavaScript, run inside Tale's sandbox), and an outbound HTTPS call (Tale POSTs the arguments to your endpoint, you return JSON). Pick the HTTPS mode for this walk — it is the shape you reach for in production. In the tool's detail panel, set: - **Endpoint URL** — `https://your-api.example.com/lookup-order` - **Method** — `POST` - **Auth header** — a bearer token from your secrets manager Tale POSTs `{ "orderId": "..." }` to your endpoint; your endpoint returns `{ "status": "shipped", "carrier": "DHL", "eta": "2026-06-01" }`. Save. The custom tool is wired. ## Step 3 — Attach the tool to an agent A wired tool is invisible to agents until one of them is given permission to call it. Open the agent you want to extend, click **Tools**, scroll to **Custom tools**, and toggle `lookup_order` on. Save the agent. Open a chat with the agent and ask "what is the status of order ORD-12345". The chat shows a collapsed `lookup_order` tool-call card between your message and the reply; expanding it shows the arguments the model emitted (`{ "orderId": "ORD-12345" }`) and the JSON your endpoint returned. The model then writes the reply using the tool result. ## Where this fits A custom tool is the seam between an agent and your domain — order lookup, internal search, calculator, anything an off-the-shelf connector does not cover. The schema is what the model uses to decide whether to call, so spend the time to write a tight description and only the fields you need. For tools you want to share across orgs, see [MCP servers from scratch](/tutorials/developer/mcp-server-from-scratch) — MCP is the protocol for "one tool, many Tale instances". For the conceptual side of what tools do inside an agent, see [Agent tools](/platform/agents/tools). # Call Tale from a script Source: https://tale.dev/docs/tutorials/developer/call-tale-from-a-script Calling Tale from a script is the path you reach for when you want a value back from the platform without opening the UI. The Tale API speaks JSON over HTTPS and accepts a bearer token in the `Authorization` header; from there, every endpoint group is a normal REST call. This walk takes you from "I want to script Tale" to an assistant reply printed in your terminal in one sitting. You need a Developer role (to mint API keys), the URL of your Tale instance, and a shell with `curl` and Python. The full API surface lives in the [API reference](/develop/api-reference); this page is the smallest end-to-end walk through it. ## Before you begin Confirm three things. Your instance is reachable on HTTPS — open `https://your-host.example.com` and check the dashboard loads. Your role is at least Developer — [API keys](/platform/admin/api-keys) are managed by Admin and Developer roles. You know a model your organization has configured — the API never auto-selects one, so every chat call names its model explicitly. ## Step 1 — Mint an API key The first move is creating an API key. The key is what every script call carries; without it the API returns 401, and you cannot read the key back after creation. Create a key in the [API keys](/platform/admin/api-keys) panel and copy what it shows — Tale displays it once and never again. Store it as an environment variable for the rest of this walk: ```bash export TALE_API_KEY="tale_..." export TALE_BASE_URL="https://your-host.example.com" ``` The key belongs to you and to your organization; what it may do follows your role. Treat it like a password. ## Step 2 — Smoke-test with curl The smallest end-to-end check is listing the organization's automations. If this works, auth, networking, and the API are all good; if it fails, the failure mode tells you which one is broken. ```bash curl -sS "$TALE_BASE_URL/api/v1/automations" \ -H "Authorization: Bearer $TALE_API_KEY" | jq ``` A 200 with a `{ "page": [...], "isDone": true, ... }` body confirms the round-trip — every list endpoint answers this same paginated envelope. A 401 means the key is wrong; anything else means the instance is unreachable or the path is mistyped. ## Step 3 — Ask a model and read the reply Chat over the API is asynchronous: you post a message, the turn runs in the background, and you poll until it is done. Three calls, one loop: ```python import os, time, requests base = os.environ["TALE_BASE_URL"] auth = {"Authorization": f"Bearer {os.environ['TALE_API_KEY']}"} # 1. A thread of your own thread = requests.post(f"{base}/api/v1/threads", headers=auth, json={}).json() # 2. Send a message — name a model your org has configured requests.post( f"{base}/api/v1/threads/{thread['id']}/messages", headers=auth, json={"content": "In one sentence: what is Tale?", "model": "<your-model>"}, ).raise_for_status() # 3. Poll until idle, then read the last message while True: status = requests.get( f"{base}/api/v1/threads/{thread['id']}/generation", headers=auth ).json()["status"] if status == "idle": break time.sleep(1) messages = requests.get( f"{base}/api/v1/threads/{thread['id']}/messages", headers=auth ).json()["page"] print(messages[-1]["content"]) ``` `{"status": "idle"}` means the turn finished — including a failed one, which lands as an assistant message carrying the error rather than vanishing. The send call answers **202** immediately; the reply exists only after the poll loop leaves `queued`/`streaming`. ## Step 4 — Start an automation run The same 202-then-poll shape starts real work. Automation names are `/`-paths written with `__` in URLs — `billing/dunning` travels as `billing__dunning`: ```bash RUN=$(curl -sS -X POST "$TALE_BASE_URL/api/v1/automations/billing__dunning/runs" \ -H "Authorization: Bearer $TALE_API_KEY" \ -H "Content-Type: application/json" -d '{ "input": {} }' | jq -r .runId) curl -sS "$TALE_BASE_URL/api/v1/runs/$RUN" \ -H "Authorization: Bearer $TALE_API_KEY" | jq .status ``` A live run needs your Developer role; pass `{"mode": "mock"}` to rehearse against deterministic mocks with any member key. A 409 means the automation has no deployed version yet. ## Where this fits A script is the path you take when the data plane is JSON, not a screen — cron jobs, CI checks, internal portals. The API key carries your role, every list endpoint answers the same paginated envelope, and anything that starts real work answers 202 and hands you something to poll. For inbound triggers — a third-party system POSTing into a Tale automation — see [Trigger an automation via webhook](/tutorials/developer/trigger-automation-via-webhook). For a model-driven client instead of a script, the [MCP endpoint](/develop/mcp-endpoint) exposes the same platform as tools. For the full endpoint inventory and error model, the [API reference](/develop/api-reference) is the single source of truth. # Stand up an MCP server from scratch Source: https://tale.dev/docs/tutorials/developer/mcp-server-from-scratch A Model Context Protocol (MCP) server is a process that exposes a list of tools over a small JSON-RPC protocol. Tale registers an MCP server once at the org level; from then on, every agent whose tools tab includes that server can call its tools. This walk takes a brand-new MCP server from "empty repo" to "called by an agent in a chat" on one Tale instance. You need a Developer role, a host that can run the MCP server (your laptop is fine for the walk; a managed service or container for production), and an HTTPS URL Tale can reach. Cloud orgs reach public URLs by default; self-hosted instances need network access to wherever the MCP server runs. ## Before you begin Confirm two things. You have Node 20 or Python 3.11 installed — the official MCP SDKs target those runtimes. The Tale instance can reach your MCP server's URL — for local development, an `ngrok` tunnel or equivalent works; for production, host the server somewhere with a stable HTTPS endpoint. The conceptual side of MCP in Tale lives in [Agent tools](/platform/agents/tools); this walk is the wiring. ## Step 1 — Scaffold the server The first move is generating the minimum MCP server — one tool, one handler. The official SDK does the protocol plumbing so you only write the tool. ```bash npm create mcp-server@latest hello-tale cd hello-tale ``` Open `src/index.ts` and replace the example tool with one that returns the current time in a named timezone: ```ts server.tool( 'current_time', 'Return the current time in a given timezone', { timezone: z.string() }, async ({ timezone }) => { const now = new Date().toLocaleString('en-US', { timeZone: timezone }); return { content: [{ type: 'text', text: now }] }; }, ); ``` Run the server locally: ```bash npm run start ``` The server listens on `http://localhost:3000/mcp` by default. The scaffold is in place; nothing in Tale knows about it yet. ## Step 2 — Expose it on HTTPS MCP servers Tale can call need an HTTPS URL with a valid certificate. For local development, point an `ngrok` tunnel at port 3000 and copy the public URL the tunnel prints. For production, host the server behind your normal ingress — Caddy, Nginx, a managed function, anything that terminates TLS. Verify the public URL responds to a health check: ```bash curl -sS "https://abcd.ngrok.app/mcp/health" ``` A 200 confirms reachability. A 502 or timeout means the tunnel is not forwarding; restart it or check the firewall. ## Step 3 — Register the server in Tale A reachable MCP server is invisible to Tale until you register it. Open **Settings > Connectors > MCP servers** and click **New server**. Fill in: - **Name** — `Hello Tale time` - **URL** — the public HTTPS URL from Step 2 (e.g. `https://abcd.ngrok.app/mcp`) - **Auth** — bearer token if your server requires it, none for the walk Click **Save**. Tale calls the server's `list_tools` method to discover the tool inventory; the panel shows `current_time` with its description. The server is now registered org-wide. ## Step 4 — Attach the server to an agent and call the tool A registered server is reachable only by agents that opt in. Open any agent, click **Tools > MCP**, toggle **Hello Tale time** on, and save. Open a chat with the agent and ask "what time is it in Tokyo right now". The chat renders a `current_time` tool-call card; expanding it shows `{ "timezone": "Asia/Tokyo" }` and the timestamp your server returned, and the agent's reply uses the timestamp. ## Where this fits An MCP server is the right shape when a tool needs to live outside Tale — code your team owns, a service in another network, a third-party API you wrap. Custom tools in [Build a custom tool](/tutorials/developer/build-a-custom-tool) are the right shape when the tool is one-off and lives inside one org's settings. For the bigger picture of how tools widen what an agent can do, see [Agent tools](/platform/agents/tools). For wiring an connector that wraps a third-party API instead of your own code, [Connectors overview](/platform/connectors/overview) is the next read. # Trigger an automation via webhook Source: https://tale.dev/docs/tutorials/developer/trigger-automation-via-webhook A webhook trigger turns an automation into something an external system can fire by POSTing JSON. Tale matches the token in the URL against the trigger, and the run it starts belongs to the automation's deployed version — never to a draft someone is still editing. This walk takes an automation from "I want to fire it from outside" to "an order event posts and the run appears" on a single instance. You need a Developer role in the org, an automation with a deployed version, and a shell with `curl`. The full inbound contract — status codes, body handling, size limits — lives in [Webhooks](/develop/webhooks); this walk is the smallest end-to-end use of it. ## Before you begin Confirm two things. The automation you will trigger has a **deployed** version — saving a version is not enough, and a version is only deployable once its own tests pass, so run them first. Your role is at least Developer; adding triggers is gated to Developer and above. If you have no automation yet, the canonical small one is "record the payload and stop" — build it through [Build a workflow with an approval](/tutorials/editor/workflow-with-approvals) and drop the approval node for this walk. ## Step 1 — Add a webhook trigger The first move is binding a webhook trigger to the automation. Without one, the automation runs only from the UI or a schedule; with one, it gets a URL any system can POST to. Open the automation's **Triggers** tab and add a webhook. Tale mints a URL with the credential embedded as a token in the path — there is no separate key and no Authorization header. The plaintext token is shown once and never stored, so copy it now; only its hash is kept, which is why nobody can recover the URL for you later. The trigger binds to the automation's **name**, not to the version you deployed. Deploy a new version tomorrow and this URL keeps working — that is the whole point of separating the two. ```bash export TALE_TRIGGER_URL="https://your-host.example.com/api/automations/webhook/<token>" ``` ## Step 2 — POST a payload from curl The webhook URL is an ordinary POST endpoint, and the body becomes the run's input. A body that is not JSON is handed through as text rather than refused, so a vendor that posts form-encoded data still reaches your first node. ```bash curl -sS "$TALE_TRIGGER_URL" \ -H "Content-Type: application/json" \ -d '{ "orderId": "12345", "amount": 199.0 }' ``` An accepted call answers **202** with `{ "runId": "..." }`. The run is now executing asynchronously; open the automation's run list and you will see it with your payload as the input. ## Step 3 — Read the failure cases Four responses cover everything the endpoint can say, and each one points at a different fix. **404** means the token matches no enabled trigger — it is wrong, it was deleted, or the trigger is disabled. The response deliberately never says which, so a caller guessing tokens learns nothing from the difference. **409** with `{ "error": "automation has no deployed version" }` means the automation exists but nothing is live: deploy a version whose tests pass and the same call runs. **413** means the body is over 256 KB; post a reference instead of the payload. **202** is the only success. Retries deserve one sentence of their own: the endpoint does not de-duplicate, so a retried POST starts a second run. What keeps that safe is the run itself — every completed node is checkpointed, so a run that resumes after an interruption never repeats the side effects it already produced. Where a _duplicate_ run would still be wrong, carry your own event id in the payload and branch on it in the first node. ## Where this fits Webhook triggers are the inbound seam of the automation engine — what your CRM, your order system, or your monitoring tool POSTs into. Reach for one when the sentence is "this happened in our world, please run something about it"; reach for the [API reference](/develop/api-reference) when you want a synchronous answer instead. The trigger-side configuration, and the other three kinds that can start the same automation, live on [Workflow triggers](/platform/automations/triggers). # Build an agent with knowledge Source: https://tale.dev/docs/tutorials/editor/agent-with-knowledge An agent with knowledge is the shape you reach for when the model needs to answer from specific documents — your product manual, your policies, last quarter's call notes — not from whatever it learned during training. The agent retrieves chunks from the bound sources at reply time and cites them. This walk takes a fresh agent from "I want it to know my docs" to "the reply cites the right document" on one instance. You need an Editor role, the ability to upload documents to the knowledge base, and roughly three documents to bind. The conceptual side lives in [Agent knowledge](/platform/agents/knowledge); this walk is the end-to-end mechanic. ## Before you begin Confirm three things. Your role is at least Editor — agent editing is gated to Editor and above. You have at least three documents on hand to upload (PDFs, DOCX, Markdown — anything the knowledge base accepts). You have a provider configured so the agent can run — without one, the test reply at the end fails on the model call. ## Step 1 — Upload documents to the knowledge base The first move is putting the documents inside Tale's knowledge base. Documents that are not in the knowledge base cannot be bound; the agent only sees sources it can name. Open **Knowledge > Documents** and click **Upload**. Drag the three documents in, give them sensible titles, and wait for the status column to show **Ready** for each. The status walks through `uploaded → processing → ready`; processing chunks the document and computes embeddings. A typical PDF reaches **Ready** in a minute or two. If a document sticks on `processing` for more than five minutes, open its row to see the error — the most common cause is an unsupported format (image-only PDFs, password-protected files) or a file larger than the org's upload limit. ## Step 2 — Create the agent A bound document goes on an agent, so the agent has to exist first. Open **Agents > New agent** and fill in the four knobs as a baseline: - **Name** — `Docs Q&A` - **Instructions** — `You answer questions strictly from the bound documents. If you cannot find the answer in the documents, say so explicitly. Cite the document title for every claim.` - **Tools** — toggle **RAG** on; everything else off - **Model** — pick whatever default the org uses Save and publish. The agent now exists but has no knowledge — it will refuse every question because it cannot find any source. ## Step 3 — Bind the documents The binding is the seam that gives the agent retrieval access to a subset of the knowledge base. Open the agent's **Knowledge** tab and click **Agent knowledge**. Pick the three documents from Step 1 and save. The Knowledge tab now lists three bound sources. The agent's RAG tool will retrieve only from those three; nothing else in the knowledge base is reachable from this agent, even other documents in the same library. ## Step 4 — Ask a question and check the citation Open a chat with `Docs Q&A` and ask a question one of the documents answers. The reply streams in with citations inline — hovering shows the document title, clicking opens the document at the cited chunk. Ask a question none of the documents covers; the agent should refuse explicitly per the instruction, not invent an answer. If the agent invents an answer anyway, the instructions are not strict enough — add an explicit refusal case ("If you cannot find the answer in the bound documents, respond with exactly: 'I could not find this in the bound documents.'") and republish. ## Where this fits The four moves above are the canonical "agent that answers from your docs" build: upload, create the agent with RAG on, bind, verify with a citation. The same shape scales — bind ten documents instead of three, add a website or a contact record, swap the model. The bindings, not the model, are what makes the agent yours. For the conceptual side of how retrieval composes with the agent's other knobs, see [Agent concepts](/platform/agents/concepts). For the wider knowledge-base story — Contacts, Products, Vendors, Websites — see [Knowledge overview](/platform/knowledge/overview). # Hand work to a worker Source: https://tale.dev/docs/tutorials/editor/delegate-between-agents When a request deserves its own focused context — cited research, bulk extraction, a long draft — the assistant spawns a **worker**: an ephemeral agent composed for exactly that task, with exactly the capabilities the assistant grants it from its own set. There is nothing to configure; this walk runs one research job end to end and shows you how to read the job card. The conceptual side (capability subsets, budgets, methodologies) lives in [Agent workers](/platform/agents/delegation). ## Before you begin You need a chat-capable agent (the built-in Assistant works as-is) on a model with tool-calling support. For live web sources, connect a search connector such as Tavily under **Settings > Connectors** — without it the worker falls back to plain web fetching and says so in its result. ## Step 1 — Ask for something worth a worker Open a chat with `Assistant` and ask for open-ended, citable work, for example: `Research the current state of solid-state batteries — market, key players, cited sources.` A quick factual question won't (and shouldn't) spawn anything; workers are for tasks that benefit from isolation. ## Step 2 — Watch the job card The assistant calls `spawn_agent` and a **job card** appears under its turn: the worker's name, a live status, and the worker's own progress checklist filling in as it plans and works through sub-questions. The card never blocks the chat — you can keep typing while the worker runs. If the card shows a "skipped" note, the assistant requested something outside its own grants (say, an unconnected connector); the run continues with what remains, and the note tells you what to connect for next time. ## Step 3 — Read the result and the transcript When the job finishes, the assistant folds the worker's deliverable into its reply — for research, a conclusion, key points with inline citations, and sources. On the card, expand **worker activity** to see the full transcript: every search, every tool call, and the worker's reasoning. That transcript is the audit trail you point at when someone asks what the agent actually did. ## Step 4 — When something goes wrong A worker that runs out of time or hits an error ends with a visible status on the card — `timed out` or `failed` — with its partial progress intact. The assistant reports what it got and continues itself where it can. Nothing fails silently: if the worker needed input only you can give, the assistant asks you directly. ## Where this fits One request, one worker, one card is the smallest useful shape. The same mechanics scale to several workers in a turn — each gets its own card, its own progress, and its own transcript. For fixed stages with approvals or scheduling between them, reach for a [workflow](/platform/automations/concepts) instead. # Build your first agent Source: https://tale.dev/docs/tutorials/editor/first-agent-end-to-end A first agent is the smallest useful thing in Tale: instructions plus a model, sometimes with one tool or one document bound. This walk turns the four knobs in order — instructions, knowledge, tools, model — and leaves you with a published agent that turns a real task into a reviewable result. The shape generalises: every agent you build later is the same four moves with different choices. You need an Editor role and a configured chat-tagged model on the org's provider. The conceptual side lives in [Agent concepts](/platform/agents/concepts); this walk is the end-to-end mechanic. ## Before you begin Confirm three things. Your role is at least Editor — agent editing is gated to Editor and above. The org has a provider configured and at least one chat-tagged model on it; without that, the test reply at the end fails on the model call. You have a question in mind the agent should answer — pick something narrow enough that a paragraph of instructions can frame it, like "summarise an inbound contact message into one sentence plus a recommended next action". ## Step 1 — Write the instructions Instructions are the system prompt — the prose that frames every reply. The first knob is the one most people overshoot. Open **Agents > New agent** and set: - **Name** — `Triage assistant` - **Instructions** — `You read a contact message and produce two lines. Line one: a one-sentence summary in plain English. Line two: a recommended next action — reply, escalate, or close. If the message is blank or off-topic, refuse and say so.` Save as a draft for now; publishing comes after the other knobs. Short, opinionated, concrete instructions outperform long ones — keep the rules under a paragraph. ## Step 2 — Decide on knowledge Knowledge is what the agent can reference at reply time. For this first agent, leave Knowledge empty: the job is reading the message, not retrieving anything. The Knowledge tab stays untouched. If you wanted to add knowledge later — say, an escalation matrix the agent should consult — you would upload the document, open the agent's **Knowledge** tab, and bind it. The full mechanic is in [Agent with knowledge](/tutorials/editor/agent-with-knowledge). ## Step 3 — Pick the tools Tools are what the agent can do beyond reply with text. For triage, no tools are needed: the agent reads input and writes output. Open the **Tools** tab and leave every toggle off. Every tool you grant widens the trust boundary; keep the list short. If the agent should write the recommended action back to a CRM, you would toggle the corresponding connector tool on later — but not before the text-only version works. ## Step 4 — Pick the model and publish Open the **Model** tab and pick the org default for the primary; set a smaller model as the fallback so the agent still runs when the primary is rate-limited. Save, then click **Publish**. The agent is now available to every project and automation with the right role — chat itself runs the built-in assistant only. Create a task, paste a real contact message into its description, and assign it to `Triage assistant`. The run's result should land in two lines per the instructions — a one-sentence summary and a recommended action. If the format drifts, tighten the instructions and republish; this is the loop you spend the most time in. ## Where this fits Four knobs, one published agent, one verified reply: the same shape every agent you build later follows. The next walks specialise on one knob each — [Agent with knowledge](/tutorials/editor/agent-with-knowledge) on the second knob, [Hand work to a worker](/tutorials/editor/delegate-between-agents) on the third. For the concept page that names the four knobs and the trade-offs between them, see [Agent concepts](/platform/agents/concepts). For versioning and rollback once the agent matures, see [Agent versions](/platform/agents/versions). # Build a workflow with an approval Source: https://tale.dev/docs/tutorials/editor/workflow-with-approvals A workflow with a human decision in the middle is the shape you reach for when the work has a draft, a review, and an action — and you want a person between the draft and the action. The run pauses as **Waiting for input** until someone answers; the next step only fires on a green light. This walk builds a daily-summary workflow that way, and you meet both human gates on the road: approving the AI editor's proposal, and answering the paused run. You need an Editor role and one agent that produces a draft (the first useful agent from [Build your first agent](/tutorials/editor/first-agent-end-to-end) works fine). The conceptual side lives in [Automation concepts](/platform/automations/concepts) and [Approval concepts](/platform/approvals/concepts); this walk is the end-to-end mechanic. ## Before you begin Confirm three things. Your role is at least Editor — workflow editing is gated to Editor and above. You have a draft-producing agent ready to call; without it the draft step has nothing to invoke. And you can answer the review yourself — the paused run waits for a human, and in this walk that human is you. ## Step 1 — Open a workflow in the editor Workflows live inside the automation they power: open the automation and its **Editor** tab is the workflow, with the step graph on a canvas. For this walk, open a workflow you own or one your org's task-ops pack provisioned — anything you are allowed to edit works, because the AI editor builds the new definition for you either way. ## Step 2 — Describe the workflow to the AI editor Toggle the **AI editor** on the canvas toolbar and describe the whole shape in one message: > Every weekday at 08:00, have the <your agent> agent summarise yesterday's unread contact messages into one paragraph, then ask a human to review the draft, and only send the approved text to the team channel. The AI editor answers with a proposal card — **Create workflow** with the step count, or **Update workflow** when it reworks the one you opened. Nothing touches the definition while the card is pending: expand it, check the steps it lists — an **LLM** step for the draft, the review pause, the send — and approve it. The change is applied and versioned like any manual save. ## Step 3 — Attach the schedule Switch to the **Triggers** tab and click **Add schedule**. Pick the **Every day** preset and adjust the cron to weekdays (`0 8 * * 1-5`) — or describe the timing in plain language and click **Generate** to let the AI write the cron. **Workflow variables** pre-fills from the workflow's input schema; leave it as proposed. The row appears with an **Active** toggle already on. ## Step 4 — Run it and answer the review Back in the editor, open **Test workflow**, paste the input JSON the panel proposes, and click **Execute**. The panel mirrors the run step by step: the draft step fires, then the run pauses — **Waiting for input** — and the review arrives as a form card holding the draft. Fill it and click **Submit response** to approve, or **Reply differently** to push back in free text; the run resumes with your answer and the send step fires. Open the **Executions** tab and expand the run: the journal shows one entry per step — the draft the agent produced, who answered the review and what, and the send with its output. That journal is the audit trail; the same record appears for every future scheduled run. ## Where this fits Draft, decide, act — with the decision a human's — is the smallest useful workflow-with-approval, and you built it without placing a single step by hand: the AI editor proposed, you approved, the run asked, you answered. The same shape scales — add a second review before a destructive step, or let [Approvals in workflows](/platform/automations/approvals-in-workflows) show you the other gates around a workflow. For the vocabulary behind definition, trigger, and execution, [Automation concepts](/platform/automations/concepts) is the page this walk assumed. # Chat effectively Source: https://tale.dev/docs/tutorials/member/chat-effectively Chatting effectively in Tale is not about clever prompts; it is about giving the assistant enough to read your intent the first time — and knowing which work does not belong in a chat at all. Five small habits — asking instead of commissioning, picking the right model, feeding Knowledge instead of pasting, reading the thought timeline, and checking the sources — turn the average reply from "thanks for the wall of text" into "exactly what I needed". This page walks the habits in order on a fresh chat. You need a Member role — the floor for chat. The conceptual side lives in [Chat basics](/platform/chat/basics); this walk is the daily-driver mechanic. ## Habit 1 — Ask; don't commission Chat answers questions and retrieves material. It deliberately does not produce deliverables — ask for a presentation, a translated document, or a report, and the assistant sketches the short version and tells you to create a task instead. Work with that boundary rather than against it: when you catch yourself writing "create", "generate the file", or "translate this document", head for a task and assign it to an agent — you get an owner, a reviewable result, and a Done that a person controls. Translating a sentence you pasted is chat work; translating a file is task work. ## Habit 2 — Let Auto work; pin when you know better The picker opens on **Auto**, which reads each message and matches a model to it — a quick lookup lands on a fast model, a long reasoning question on a strong one, and the reply's details name which one answered. That is the right default for most days. Pin a model from the list when you know something Auto cannot: the same model must answer a whole series, a specific model is the one being evaluated, or you want the reasoning-effort knob — the picker's second section, which appears for a pinned model that has one. Raise the effort for gnarly questions, and expect slower, costlier replies at the top level; hand the picker back to Auto when the series is done. ## Habit 3 — Feed Knowledge; don't paste walls The assistant searches the organisation's knowledge — documents, knowledge entries, crawled websites, products, contacts — and loads the full text of what it finds. That only works for material that is actually there: upload the price list or the policy document once under [Knowledge](/platform/knowledge/documents), and every future chat can find and cite it. Pasting a 200-page document into the message field fills the context budget and dilutes the answer; a specific question against uploaded material ("what does the refund policy say about opened boxes?") outperforms "tell me everything about refunds" every time. ## Habit 4 — Read the timeline, not just the answer Above each reply, the thought timeline records what the assistant did: a collapsible thinking line, and one step row per search or page fetch — _Searching knowledge base for "…"_, _Reading example.com_. Glance at it before trusting the answer. A reply with no search step behind a factual claim came from the model's own knowledge; a search step that reports nothing found tells you what is missing — including when a whole source is unavailable, such as documents not being searchable until an admin configures an embedding model. The timeline is also where a failed fetch says why, instead of the answer quietly working around it. ## Habit 5 — Check the sources before you forward the summary Below an answer that read something, **Sources** lists exactly the pages and documents the assistant loaded — derived from what actually ran, so an empty list means nothing was read. Open one before you act on the reply: the two-minute habit of confirming a source per reply catches the small subset where the summary overreached. A web source opens the live page in a new tab; a document source names the file to find under Knowledge. ## Where this fits Five habits, one chat, the same loop every time you open the Chat tab. The habits compound — asking inside chat's boundary keeps the answers crisp; fed Knowledge makes the searches land; the timeline and sources close the trust loop. For the surface these habits live on, see [Chat basics](/platform/chat/basics). For the file side — what the assistant can search and cite — see [Knowledge](/platform/knowledge/overview). # Use projects to bundle files and chats Source: https://tale.dev/docs/tutorials/member/use-projects A project is what you reach for the second time you find yourself pasting the same context into a chat. It bundles files, instructions, and chats around one body of work — a contact, a launch, a long investigation — so every new conversation starts with the context already loaded. This walk takes a fresh project from "I keep re-uploading the same brief" to "every chat inside this project already knows the brief" on one instance. You need a Member role (the floor for creating projects) and three or four files you keep referencing. The conceptual side lives in [Project concepts](/platform/projects/concepts); this walk is the end-to-end mechanic. ## Before you begin Confirm two things. Your role is at least Member — project creation is gated to Member and above. You have three to four files that recur across the chats you have been having — a brief, a transcript, a price list, a policy. Those become the project's working set. ## Step 1 — Create the project The project is the container the rest of the pieces live in. Open **Projects > New project** and set: - **Name** — `Acme account` (or whatever names the body of work) - **Description** — one sentence on what the project is for - **Members** — leave it private for now; you can add teammates after the first chat works Save. The project appears in the sidebar; clicking it opens an empty project view with tabs for Knowledge, Threads, Agents, and Instructions. ## Step 2 — Upload the files once The project's files are visible to every chat inside the project, so this upload happens once and pays back on every later chat. Open the **Knowledge** tab and drag in the three or four files you confirmed in the prerequisites. Each file lands in the project's storage and indexes the same way a knowledge-base document does. Once the status is **Ready**, the files are reachable by any chat started inside the project. ## Step 3 — Add project instructions Project instructions frame every chat in the project. They compose with the agent's own instructions: the project frames the work, the agent frames the reply. Open the **Instructions** tab and set: `You are working on the Acme account. The contract and the call notes in the Knowledge tab are the source of truth; cite them when you make a claim. The contact's voice is conservative — drafts should not promise dates we have not confirmed.` Save. Every new chat in the project will now run with this preamble in addition to the agent's own instructions. ## Step 4 — Start a chat and verify the context follows Open the **Threads** tab and click **New chat**. Pick an agent — the default Assistant is fine for the first run — and ask a question one of the project's files answers (`What does the contract say about the renewal clause?`). The reply should cite the contract; the citation opens the file from the project's Knowledge tab, not from the org-wide library. If the agent answers without citing, the project's files were not retrieved — usually because the chosen agent has no retrieval tool enabled. Switch to an agent with RAG on, or enable it on the Assistant for project use. ## Where this fits A project with files, instructions, and threads is the smallest useful unit of shared context in Tale. The same shape scales — add members so a team works the project together, add a project-scoped agent so the voice is locked in, archive the project when the work ships. For the deeper model of what a project is and when to reach for one, see [Project concepts](/platform/projects/concepts). For project-scoped agents, see [Project agents](/platform/projects/project-agents). # Tutorials Source: https://tale.dev/docs/tutorials/overview Tutorials are end-to-end walkthroughs: each takes a fresh instance from "I want to do X" to a working, verified result. They assume you have the right role and a running workspace; the concept pages under [Platform](/platform) explain the mental model, tutorials show the mechanic from start to finish. If you have not walked a [get-started journey](/get-started/quickstart) yet, start there — tutorials build on the day-one moves those cover. ## Pick by role <CardGroup cols="2"> <Card title="Video series" icon="play" href="/tutorials/videos"> Produced walkthroughs of the whole platform — grounding, agents, automations, governance — three minutes at a time, in three languages. </Card> <Card title="Member tutorials" icon="message-circle" href="/tutorials/member/chat-effectively"> Chat effectively, work in projects, hold voice conversations. </Card> <Card title="Editor tutorials" icon="bot" href="/tutorials/editor/first-agent-end-to-end"> Build a first agent end to end, bind knowledge, delegate between agents, ship workflows with approvals. </Card> <Card title="Developer tutorials" icon="terminal" href="/tutorials/developer/call-tale-from-a-script"> Call Tale from a script, trigger workflows via webhooks, build custom tools, stand up an MCP server. </Card> <Card title="Admin tutorials" icon="shield" href="/tutorials/admin/office-add-in"> Install the Office add-in, wire meeting transcription, connect a local provider. </Card> </CardGroup> ## Where this fits Tutorials cite the feature references under [Platform](/platform) for the conceptual scaffolding; once you have walked one, the page worth re-reading is the underlying concept page. If you do not know which tutorial to pick, [Build your first agent](/tutorials/editor/first-agent-end-to-end) is the closest thing to a "hello world" for the product — most product capabilities you eventually touch appear in it. # Episode 5 — Automations & approvals Source: https://tale.dev/docs/tutorials/videos/automations-and-approvals By the end of this episode you'll have used an automation for real: you read the installed triage workflow before trusting it, create a task and watch it get scored and assigned on camera, follow that run through its journal, open the one that failed and trace it to its step — and approve an outbound customer email with your own click, then find that decision in the audit log seconds later. Step by step, at a pace you can follow along with. <Video src="/videos/en/tutorials/ep5-automations/ep5-automations.en.mp4" poster="/videos/en/tutorials/ep5-automations/ep5-automations.en.webp" captions="/videos/en/tutorials/ep5-automations/ep5-automations.en.vtt" lang="en" title="Episode 5 — Automations & approvals" caption="Episode 5 — Automations & approvals (6:20, captions available)"> </Video> ## What the episode shows | At | Scene | | ---- | -------------------------------------------------------- | | 0:27 | The job: a board of unowned tasks | | 0:48 | The catalog, and what a bundle's preview panel tells you | | 1:44 | Reading the workflow: trigger, score step, schema | | 2:45 | The tester — and the honest way to trigger a run | | 3:04 | A real task, created and auto-assigned on camera | | 3:58 | The red run, diagnosed down to its step | | 4:40 | The approval card: read, adjust, submit | | 5:32 | The decision in the audit log | ## Where to go next [Automation concepts](/platform/automations/concepts) and the [catalog](/platform/automations/catalog) cover the bundles; the [editor](/platform/automations/editor), [triggers](/platform/automations/triggers), and [execution logs](/platform/automations/execution-logs) go deep on what you saw. For the card itself, read [approval concepts](/platform/approvals/concepts) and [approvals in workflows](/platform/automations/approvals-in-workflows) — then build one with the editor tutorial [a workflow with approvals](/tutorials/editor/workflow-with-approvals). # Episode 2 — Chat, in depth Source: https://tale.dev/docs/tutorials/videos/chat-in-depth Episode 1 toured the workspace; this episode moves into the room your team will actually live in — and runs a full working session. Its core beat is a controlled experiment: the same onboarding question asked twice, once with no context and once with the Q2 support review attached, so you watch a fluent answer and a grounded answer stop being the same thing. Then the grounded thread gets questioned ("which document says that?"), an Arena verdict gets decided with reasons, and a leadership brief lands on the canvas — and gets cut to three bullets with one sentence. <Video src="/videos/en/tutorials/ep2-chat/ep2-chat.en.mp4" poster="/videos/en/tutorials/ep2-chat/ep2-chat.en.webp" captions="/videos/en/tutorials/ep2-chat/ep2-chat.en.vtt" lang="en" title="Episode 2 — Chat, in depth" caption="Episode 2 — Chat, in depth (5:44, captions available)"> </Video> ## What the episode shows | At | Scene | | ---- | -------------------------------------------------------- | | 0:27 | The composer's three choices: agent, model, context | | 0:48 | The experiment, part one: asking with nothing attached | | 1:06 | The trap, read together — fluent, confident, guessing | | 1:24 | Part two: the same question, grounded in a real document | | 2:00 | Questioning the answer: "which document says that?" | | 2:20 | Rating an answer — where feedback analytics begin | | 3:00 | Arena Mode: two models, one prompt, a reasoned verdict | | 3:53 | The canvas: a brief lands as a file, then gets refined | | 4:39 | Deep research, and where it lives | ## Where to go next [Chat basics](/platform/chat/basics) covers the composer, the three retrieval tools, and the thought timeline in reference depth. For the model side, read [models](/platform/models) and [Arena Mode](/platform/chat/arena-mode); for work that ends in a deliverable, [Agent concepts](/platform/agents/concepts) is where chat hands off. # Episode 7 — Connectors & the outside world Source: https://tale.dev/docs/tutorials/videos/connectors Your workspace does not live alone. This episode walks the doors to the outside world and the discipline built into each one: a connector you can read before you open it, the capability that lights up when an connector is bound, MCP tools that arrive with their own approval flags, and a sandbox network that answers no by default. <Video src="/videos/en/tutorials/ep7-connectors/ep7-connectors.en.mp4" poster="/videos/en/tutorials/ep7-connectors/ep7-connectors.en.webp" captions="/videos/en/tutorials/ep7-connectors/ep7-connectors.en.vtt" lang="en" title="Episode 7 — Connectors & the outside world" caption="Episode 7 — Connectors & the outside world (2:30, captions available)"> </Video> ## What the episode shows | At | Scene | | ---- | -------------------------------------------------------------------- | | 0:13 | The catalog: connect once, the whole workspace borrows it | | 0:30 | Reading the door: operations and allowed hosts, before anything runs | | 0:46 | The payoff: deep research exists because Tavily is bound | | 1:00 | MCP: your own tools, served to agents like native ones | | 1:15 | Per-tool approval flags — native-looking is not native-trusted | | 1:31 | The last door: sandboxed code, default-deny egress, fail-closed | | 1:51 | The pattern at every door | ## Where to go next The [connectors overview](/platform/connectors/overview) covers connecting and sharing connectors; [MCP servers](/platform/connectors/mcp-servers) the protocol and its approval flags. For the network boundary, read the [run-code policy](/platform/admin/governance/run-code-policy) — and for what a bound connector unlocks, see [automation concepts](/platform/automations/concepts). # Episode 9 — Governance, cost & trust Source: https://tale.dev/docs/tutorials/videos/governance-and-trust The finale is for whoever answers for AI in the organization. It tours the control room end to end — which models run and for whom, the guardrails that scan both directions, the audit log where episode five's approval actually landed, the cost and quality charts where episode two's Arena verdicts ended up, and the region dial — then closes the series with its five habits: ground it, gate it, scope it, log it, measure it. <Video src="/videos/en/tutorials/ep9-governance/ep9-governance.en.mp4" poster="/videos/en/tutorials/ep9-governance/ep9-governance.en.webp" captions="/videos/en/tutorials/ep9-governance/ep9-governance.en.vtt" lang="en" title="Episode 9 — Governance, cost & trust" caption="Episode 9 — Governance, cost & trust (3:01, captions available)"> </Video> ## What the episode shows | At | Scene | | ---- | --------------------------------------------------------------- | | 0:16 | Providers: one gateway, your own keys, or your own hardware | | 0:32 | Model policy: who may use which model | | 0:47 | Guardrails: PII masked, unsafe content blocked, both directions | | 1:06 | The audit log — episode five's approval, on the record | | 1:24 | Usage analytics: cost with names on it, budgets that warn | | 1:40 | Feedback analytics: quality measured, Arena verdicts included | | 1:56 | Data residency: a setting, not a negotiation | | 2:10 | The five habits of using AI well | ## Where to go next [Providers](/platform/admin/providers) and [models](/platform/models) cover the machinery; [content models](/platform/admin/governance/content-models) and [policies and limits](/platform/admin/governance/policies-and-limits) the policy layer; [guardrails](/platform/admin/governance/guardrails), [audit logs](/platform/admin/governance/audit-logs), [usage analytics](/platform/admin/governance/usage-analytics), and [feedback analytics](/platform/admin/governance/feedback-analytics) the controls you toured. For residency, see [cloud data residency](/cloud/data-residency). # Video tutorials Source: https://tale.dev/docs/tutorials/videos The video series walks the platform the way a colleague would show it to you: on screen, area by area, with the honest caveats spoken out loud. Episodes are short — three to four minutes — and each one picks up a piece of general AI literacy along the way: what grounding means, why hallucinations happen, where a human belongs in the loop. Every episode page carries the video with captions in the page's language, a chapter list, and links into the deeper reference pages. <CardGroup cols="1"> <Card title="Episode 1 — Welcome to Tale" icon="play" href="/tutorials/videos/welcome-to-tale"> The guided tour: ask a grounded question, find the cited file in Knowledge, meet the agent that answered, and read a live automation's journal. Four minutes. </Card> <Card title="Episode 2 — Chat, in depth" icon="play" href="/tutorials/videos/chat-in-depth"> A real working session: the same question ungrounded and grounded, a source check, a reasoned Arena verdict, and a brief built and refined on the canvas. Six minutes. </Card> <Card title="Episode 3 — Knowledge" icon="play" href="/tutorials/videos/knowledge"> Work inside the library: create an entry and hear it cited back, learn what Indexed means, look up a record, read the crawler's boundary — and meet the stale-knowledge trap live. Six minutes. </Card> <Card title="Episode 4 — Your first agent" icon="play" href="/tutorials/videos/your-first-agent"> An agent built end to end on camera — instructions, knowledge scope, tools, model — then tested live. Capability is exposure: start small. Three minutes. </Card> <Card title="Episode 5 — Automations & approvals" icon="play" href="/tutorials/videos/automations-and-approvals"> Use a live automation end to end: read the triage workflow, trigger a real run with a task created on camera, debug the run that failed, and approve an outbound email yourself. Six minutes. </Card> <Card title="Episode 6 — Projects with AI" icon="play" href="/tutorials/videos/projects-with-ai"> The board mid-flight, files as scoped context, and a task created on camera that an agent visibly takes. Initiative stays human. Two and a half minutes. </Card> <Card title="Episode 7 — Connectors & the outside world" icon="play" href="/tutorials/videos/connectors"> Connectors you can read before opening, MCP tools with approval flags, and egress that fails closed. Every door opened deliberately. Two and a half minutes. </Card> <Card title="Episode 8 — People, roles & teams" icon="play" href="/tutorials/videos/people-roles-and-teams"> The human half of trust: the role ladder, teams as knowledge walls, and identity hygiene. Access is designed, not assumed. Two minutes. </Card> <Card title="Episode 9 — Governance, cost & trust" icon="play" href="/tutorials/videos/governance-and-trust"> The finale: providers and model policy, guardrails, the audit log, cost and quality charts, residency — and the five habits of using AI well. Three minutes. </Card> <Card title="Bonus — Tale for developers" icon="play" href="/tutorials/videos/tale-for-developers"> The builder's lap: scoped keys, four API doors, webhooks, and harnesses that fail closed. Two minutes. </Card> </CardGroup> ## The series ahead That completes the series: the tour, seven deep dives, and a developer bonus — each in English, German, and French. The documentation around every episode goes further; start wherever your role starts. # Episode 3 — Knowledge Source: https://tale.dev/docs/tutorials/videos/knowledge The grounded answers of episode 2 all came from one place; this episode works in it. You add a real fact as a knowledge entry, learn what the Indexed badge actually means (and why indexing is not training), look a price up in a typed record, read the crawler's scan interval, open the control that limits a document to one team — and then meet the failure you'll actually hit: not a missing fact, an outdated one. At the end, a fresh chat cites the entry you created minutes earlier. <Video src="/videos/en/tutorials/ep3-knowledge/ep3-knowledge.en.mp4" poster="/videos/en/tutorials/ep3-knowledge/ep3-knowledge.en.webp" captions="/videos/en/tutorials/ep3-knowledge/ep3-knowledge.en.vtt" lang="en" title="Episode 3 — Knowledge" caption="Episode 3 — Knowledge (5:50, captions available)"> </Video> ## What the episode shows | At | Scene | | ---- | ------------------------------------------------------------- | | 0:27 | The map: Documents, entries, websites, products — one tab row | | 0:54 | Entry vs document vs record — picking the right shape | | 1:18 | A knowledge entry created live: topic, content, save | | 1:44 | What Indexed means — retrieval at answer time, not training | | 2:11 | A real lookup in a typed record | | 2:37 | The crawler: a domain, a scan interval, an honest boundary | | 3:09 | Who reads what: a document assigned to a team | | 3:41 | The stale-knowledge trap, asked live | | 4:35 | The proof: a fresh chat cites the entry you just created | ## Where to go next The [knowledge overview](/platform/knowledge/overview) maps the whole library; [documents](/platform/knowledge/documents) covers the indexing pipeline, [knowledge entries](/platform/knowledge/knowledge-entries) the curated facts, [structured data](/platform/knowledge/structured-data) the typed records, and [crawling](/platform/knowledge/crawling) the websites. For the scope switches, read [agent knowledge](/platform/agents/knowledge). # Episode 8 — People, roles & teams Source: https://tale.dev/docs/tutorials/videos/people-roles-and-teams Episode five gated the machines; this episode gates the people. It walks the workspace roster and the four-step role ladder, opens the add-member dialog just long enough to learn it, draws the team boundaries that decide who reads what, and closes on the boring guardrails that matter most: two-factor and single sign-on. <Video src="/videos/en/tutorials/ep8-people/ep8-people.en.mp4" poster="/videos/en/tutorials/ep8-people/ep8-people.en.webp" captions="/videos/en/tutorials/ep8-people/ep8-people.en.vtt" lang="en" title="Episode 8 — People, roles & teams" caption="Episode 8 — People, roles & teams (2:15, captions available)"> </Video> ## What the episode shows | At | Scene | | ---- | ---------------------------------------------------------- | | 0:13 | The roster: five people, four roles | | 0:26 | Adding someone — and the role ladder that matters | | 0:47 | Roles are blast radius, not status | | 1:02 | Teams: the walls of the smallest library | | 1:20 | Identity hygiene: 2FA and enterprise SSO | | 1:35 | One principle, both sides: access is designed, not assumed | ## Where to go next [Members and roles](/platform/admin/members-and-roles) is the full reference for the ladder; [teams](/platform/admin/teams) covers the boundaries you saw. For identity, read [two-factor authentication](/platform/admin/two-factor-authentication) and [enterprise SSO](/platform/admin/enterprise-sso). # Episode 6 — Projects with AI Source: https://tale.dev/docs/tutorials/videos/projects-with-ai Chat is where you ask; projects are where the work lives. This episode walks the relaunch project the team actually runs — and then creates a task on camera, the usual way, so you can watch the triage automation score it and an agent take it. The backlog closes the loop: agents propose, people promote. <Video src="/videos/en/tutorials/ep6-projects/ep6-projects.en.mp4" poster="/videos/en/tutorials/ep6-projects/ep6-projects.en.webp" captions="/videos/en/tutorials/ep6-projects/ep6-projects.en.vtt" lang="en" title="Episode 6 — Projects with AI" caption="Episode 6 — Projects with AI (2:21, captions available)"> </Video> ## What the episode shows | At | Scene | | ---- | ---------------------------------------------------------------- | | 0:13 | The relaunch board, mid-flight — avatars say who holds what | | 0:26 | Project files: the shelf agents read first | | 0:39 | Discussions live beside the work | | 0:52 | A task created the usual way | | 1:08 | The agent takes it: scored, assigned, its reasoning in a comment | | 1:28 | The backlog: agents propose, a person promotes | | 1:42 | Each project staffs its own crew of agents and models | ## Where to go next [Project concepts](/platform/projects/concepts) and the [overview](/platform/projects/overview) map the surface; [task automation](/platform/projects/task-automation) explains the score-assign-report loop you watched, [backlog](/platform/projects/backlog) the proposal flow, and [project agents](/platform/projects/project-agents) the per-project crew. # Bonus — Tale for developers Source: https://tale.dev/docs/tutorials/videos/tale-for-developers Everything the series showed has an API underneath. The bonus episode walks the developer surface: named, revocable API keys; REST, MCP, WebDAV, and sandbox runtimes; webhooks that fire agents from any system; the harnesses — Claude Code, Cursor — working in isolated containers; and the run-code policy that names what may install and where code may connect. Power tools, contained blast radius. <Video src="/videos/en/tutorials/ep10-developers/ep10-developers.en.mp4" poster="/videos/en/tutorials/ep10-developers/ep10-developers.en.webp" captions="/videos/en/tutorials/ep10-developers/ep10-developers.en.vtt" lang="en" title="Bonus — Tale for developers" caption="Bonus — Tale for developers (2:08, captions available)"> </Video> ## What the episode shows | At | Scene | | ---- | ------------------------------------------------- | | 0:14 | API keys: named, scoped, revocable, audited | | 0:29 | Four doors: REST, MCP, WebDAV, sandbox runtimes | | 0:44 | Webhooks: any system can fire an agent | | 0:59 | Harnesses: Claude Code, Cursor, and peers | | 1:17 | The run-code policy: packages, hosts, fail-closed | | 1:35 | Power tools, contained blast radius | ## Where to go next The [develop overview](/develop/overview) maps the whole surface; the [API reference](/develop/api-reference) and [webhooks](/develop/webhooks) carry the contracts. For harness turns, read [Harnesses](/platform/agents/harnesses) and the [run-code policy](/platform/admin/governance/run-code-policy). # Episode 1 — Welcome to Tale Source: https://tale.dev/docs/tutorials/videos/welcome-to-tale The series opener walks the workspace one area at a time, at a pace you can follow along with. You ask a real question grounded in a company document, watch the answer name its sources, then close the loop: find that exact file in Knowledge, meet the Assistant that answered, and read the journal of an automation that's been running the whole time. Every stop shows a real artifact — nothing is asserted that isn't on screen. <Video src="/videos/en/tutorials/ep1-welcome/ep1-welcome.en.mp4" poster="/videos/en/tutorials/ep1-welcome/ep1-welcome.en.webp" captions="/videos/en/tutorials/ep1-welcome/ep1-welcome.en.vtt" lang="en" title="Episode 1 — Welcome to Tale" caption="Episode 1 — Welcome to Tale (4:07, captions available)"> </Video> ## What the episode shows | At | Scene | | ---- | ----------------------------------------------------- | | 0:18 | Reading the sidebar: every stop on the tour, one rail | | 0:36 | The hero ask — a document attached as context | | 1:12 | Why grounding matters (and what a hallucination is) | | 1:32 | Closing the loop: the cited file, found in Knowledge | | 1:50 | The Assistant — an agent is AI with a job description | | 2:12 | Automations: the catalog, and a journal of real runs | | 2:55 | Projects: your people and your agents on one board | | 3:12 | Control: providers, data residency, and the audit log | ## Where to go next The [quickstart](/get-started/quickstart) reproduces the episode's first chat in your own workspace in about five minutes. For the concepts in depth: [chat](/platform/chat/overview), [knowledge](/platform/knowledge/overview), [agents](/platform/agents/concepts), [automations](/platform/automations/concepts), and [approvals](/platform/approvals/concepts). # Episode 4 — Your first agent Source: https://tale.dev/docs/tutorials/videos/your-first-agent Chat taught you to ask; knowledge taught you what answers stand on. This episode builds the thing that puts both to work: an agent, created from scratch on camera. The through-line is the trust boundary — every tool you grant widens what the agent can do, so the smallest agent that does the job is the safest one. <Video src="/videos/en/tutorials/ep4-agent/ep4-agent.en.mp4" poster="/videos/en/tutorials/ep4-agent/ep4-agent.en.webp" captions="/videos/en/tutorials/ep4-agent/ep4-agent.en.vtt" lang="en" title="Episode 4 — Your first agent" caption="Episode 4 — Your first agent (2:46, captions available)"> </Video> ## What the episode shows | At | Scene | | ---- | --------------------------------------------------------------- | | 0:13 | The agents list — builtins, and where yours will live | | 0:26 | Create: a technical name, a display name, continue | | 0:43 | Instructions — the job description, including the hand-off rule | | 1:00 | Knowledge scope: the smallest library that does the job | | 1:13 | Tools: capability is exposure — start with none | | 1:33 | The model and its fallback | | 1:44 | Visible in chat, then the first live ask | | 2:06 | Iterate freely: versions keep every draft | ## Where to go next [Agent concepts](/platform/agents/concepts) is the mental model behind the four decisions; [create an agent](/platform/agents/create) the reference walkthrough. Deepen each knob with [tools](/platform/agents/tools), [knowledge](/platform/agents/knowledge), and [versions](/platform/agents/versions) — then follow the editor tutorial [from first agent to production](/tutorials/editor/first-agent-end-to-end). # Privacy policy Source: https://tale.dev/docs/legal/privacy This policy describes how Tale handles personal data when you use Tale Cloud, the docs site, the marketing site, or the in-product features. The shape is the same whether you are an end user, an org admin, or a visitor reading the docs — different surfaces collect different data, and each is named below. The policy applies to Tale Cloud; self-hosted instances are operated by the organisation that runs them and the controller is that organisation, not Tale. Read this when you want to know what Tale stores about you, why, and how to remove it. Come back when policy changes — material changes are announced on the status page and emailed to org Owners. ## What we collect Three buckets of data exist, each with its own retention rule: - **Account data.** Name, email, organisation, role, and the credentials you use to sign in. Required to operate the service. - **Product data.** Everything you put into the product — agents, workflows, documents, conversations, knowledge base entries, connector credentials. Stored as long as the parent org exists; deleted on org deletion or via the data-subject request flow. - **Operational data.** Server logs, audit trails, support ticket contents, performance metrics. Tied to your account or org for as long as the data is useful for security, debugging, and compliance — typically up to 90 days for logs and indefinitely for audit trails. We do not sell personal data. We do not use product data to train models — your conversations and documents are not part of any model training set, neither ours nor any provider's, except where you have explicitly enabled a feature that requires it and acknowledged the consent prompt. ## Why we collect it The legal basis for each bucket is one of: - **Contractual necessity.** Account data and the product data you create exist because you asked us to provide the service. We cannot run the platform without them. - **Legitimate interest.** Operational data is collected to keep the platform secure, debug failures, and meet contractual SLAs. - **Consent.** Marketing communications, analytics on the marketing site, and any feature that processes data beyond the contract are consent-based — opt-in, revocable, and recorded. The lawful-basis breakdown per data category lives in the Data Processing Agreement available to enterprise customers on request. ## How long we keep it | Data | Retention | | --------------------- | ------------------------------------------------------------------------ | | Account data | Lifetime of the org plus 30 days after deletion | | Product data | Lifetime of the org; immediate erasure on org deletion | | Documents and uploads | Lifetime of the parent record; soft-deleted records purged after 30 days | | Server logs | 90 days | | Audit logs | Org-configurable floor; default 365 days, no upper bound | | Backups | 30 days, encrypted at rest | Erasure follows the documented data-subject request workflow inside the product — see the in-product governance page for the operator surface. ## Subprocessors Tale Cloud uses a small number of third parties to deliver the service. Each is named, located, and scoped on the [Subprocessors](/legal/subprocessors) page. Material changes to the subprocessor list are announced 30 days before they take effect; org Owners can object via support and have the contract terminated if the new subprocessor is not acceptable. ## Your rights You have the rights granted by GDPR (and the equivalent FADP rights for Swiss data subjects): access, rectification, erasure, restriction, portability, and objection. The mechanics: - **Access and portability.** Export your data from inside the product or via the API; raw exports of org-scoped data are available on request. - **Rectification.** Edit account data and product data inside the product. For data you cannot reach (server logs, audit entries with your user ID), submit a request through support. - **Erasure.** Use the data-subject request workflow under **Settings > Governance > Data subject requests**. Erasure crosses every service that holds the data, including backups via key destruction. - **Restriction and objection.** Submit through support; Tale acknowledges within five business days. Contact: `privacy@tale.dev`. For complaints, the supervisory authority is the data-protection authority of the country in which you reside. ## Where this fits Privacy is the data-handling contract; [Trust and compliance](/cloud/trust-and-compliance) is the operational evidence behind it. If you want to know which third parties touch your data, [Subprocessors](/legal/subprocessors) is the list; if you operate self-hosted, the data never leaves your infrastructure and this policy applies only to your use of Tale's own surfaces (the docs and marketing sites). # Subprocessors Source: https://tale.dev/docs/legal/subprocessors A subprocessor is a third party Tale engages to process customer personal data on its behalf. The list below covers Tale Cloud; self-hosted operators control their own infrastructure and the subprocessor list for those deployments is whichever providers you choose. Material additions are announced 30 days in advance and org Owners are notified by email. Read this when an auditor asks who else touches your data. Come back when a procurement review needs the current vendor list and the location of each. This page mirrors **Appendix A** of the [Data Processing Agreement](https://tale.dev/legal/data-processing-agreement) — both are updated in the same change. The endpoints and data flows of the Tale platform itself are described in the public [API documentation](https://demo.tale.dev/docs). ## No use of customer data for model training Tale does not use customer data — prompts, inputs, outputs, embeddings, audio, images, or any derived artifacts — to train, fine-tune, or improve any AI model. Each AI subprocessor below is contractually bound, via its enterprise or API terms with Tale, to the same. This may only be varied by a separate written opt-in agreement signed by both parties; continued use of the services, in-product toggles, or implicit consent do not count. The binding clause lives at [Data Processing Agreement § 5](https://tale.dev/legal/data-processing-agreement#5-ai-processing--no-use-for-training-or-improvement). ## Current subprocessors Each subprocessor name links to that provider's publicly available DPA (or equivalent terms). Certifications and trust pages are listed in the next section. Platform hosting follows your org's data-residency choice: the first table applies to orgs in the EU/EEA, the second to Swiss orgs. AI calls (LLM inference, audio, and image processing) are processed in the EU/EEA for all orgs — no AI subprocessor Tale engages operates a Swiss region, and none of those calls is processed in third countries such as the USA. ### Orgs in the EU/EEA | Subprocessor (legal entity) | Registered address | Type of service | Place of processing | | ----------------------------------------------------- | --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | | [Akenes SA (Exoscale)](https://www.exoscale.com/dpa/) | Boulevard de Grancy 19A, 1006 Lausanne, Switzerland | Cloud infrastructure (datacenter): hosting of the Tale Cloud platform — VMs, container runtime, database, and storage. | Germany (Frankfurt region). | | [OpenRouter, Inc.](https://openrouter.ai/privacy) | 169 Madison Avenue, New York, NY 10016, USA | LLM inference (chat, vision, embeddings), audio (speech-to-text and text-to-speech), plus image processing and generation. | European Union (in-region routing via `eu.openrouter.ai`: prompts and responses are processed exclusively within the EU). | ### Swiss orgs | Subprocessor (legal entity) | Registered address | Type of service | Place of processing | | ----------------------------------------------------- | --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | | [Akenes SA (Exoscale)](https://www.exoscale.com/dpa/) | Boulevard de Grancy 19A, 1006 Lausanne, Switzerland | Cloud infrastructure (datacenter): hosting of the Tale Cloud platform — VMs, container runtime, database, and storage. | Switzerland (Zurich; disaster-recovery replica in Geneva). | | [OpenRouter, Inc.](https://openrouter.ai/privacy) | 169 Madison Avenue, New York, NY 10016, USA | LLM inference (chat, vision, embeddings), audio (speech-to-text and text-to-speech), plus image processing and generation. | European Union (in-region routing via `eu.openrouter.ai`). | For Swiss orgs, platform hosting stays entirely in Switzerland. The AI subprocessor does not offer a Swiss region; those calls are processed in the EU/EEA — every EU/EEA country is on the Swiss Federal Council's adequacy list under Art. 16 FADP, so the transfer requires no additional safeguards. Two notes on the AI subprocessor (OpenRouter): it is engaged only when an AI feature routes a call to it — an org that uses no LLM inference, audio, or image features sends it no data. Model providers reachable through OpenRouter (Anthropic, Google, Meta, Mistral, OpenAI, etc.) are upstream providers of OpenRouter, not Tale's direct subprocessors — the default audio models (Whisper for speech-to-text, gpt-4o-mini-tts for text-to-speech) are OpenAI models reached this way. They operate under OpenRouter's own contractual terms; in-region routing restricts every call to provider endpoints inside the EU. ## Certifications and trust pages Each subprocessor maintains its own security certifications and publishes them on a trust page: - **Exoscale (Akenes SA)** — ISO/IEC 27001:2022, ISO/IEC 27017, ISO/IEC 27018, SOC 2 Type II, PCI DSS v4.0, HDS, BSI C5, TISAX. Trust page: [exoscale.com/compliance](https://www.exoscale.com/compliance/). - **OpenRouter, Inc.** — SOC 2; evidence available through the access-gated trust portal [trust.openrouter.ai](https://trust.openrouter.ai). EU Standard Contractual Clauses apply to transfers outside the EU/EEA. ## Scope of processing For each subprocessor: - **Exoscale (Akenes SA)** runs the Tale Cloud middleware, application state, and supporting infrastructure on VMs and container infrastructure in your org's selected region (Switzerland: Zurich with disaster recovery in Geneva; EU: Frankfurt). Encryption at rest is provided by Exoscale's storage layer. - **OpenRouter** processes prompts and responses for the specific LLM call routed to it (chat, vision, embeddings), audio payloads for speech-to-text and the text input for text-to-speech, plus image prompts and generated images. The data is sent over OpenRouter's in-region routing (`eu.openrouter.ai`) and is not retained by Tale as a separate copy. ## Sub-subprocessors Each subprocessor above engages its own subprocessors (cloud hosting, CDN, secret stores). Their lists are public and linked from each provider's trust page; Tale tracks material changes to the upstream lists through the same 30-day notice mechanism. ## Self-hosted: what changes If you run Tale on your own infrastructure, the only data Tale processes on your behalf is the support and update traffic you opt into (image pulls from the registry, optional telemetry, support tickets). The hosting and model providers in the table above are operated by you, not by Tale; the subprocessor list for your deployment is whatever stack you assemble. ## Where this fits Subprocessors are the vendor inventory; the [Data Processing Agreement](https://tale.dev/legal/data-processing-agreement) is the contract under which they operate (Appendix A is the canonical list); the [Privacy policy](/legal/privacy) is the user-facing policy; [Trust and compliance](/cloud/trust-and-compliance) is the operational evidence. An auditor usually wants the four together — the vendor list, the contract, the policy, and the controls — so the linked pages are mutually consistent and updated in the same change. # Arena-Modus Source: https://tale.dev/docs/de/platform/chat/arena-mode Der Arena-Modus führt dasselbe Prompt parallel gegen zwei Modelle aus und fragt dich, welche Antwort besser ist. Die Bewertung fließt in die Feedback-Analyse der Org; mit der Zeit zeigen die Daten, welches Modell das Team für welche Art von Frage tatsächlich bevorzugt — getrennt vom Bauchgefühl. Greif zur Arena, wenn die Modellwahl eine Debatte statt einer Entscheidung war — Antworten nebeneinander zu vergleichen bricht das Patt mit Belegen statt mit Meinungen. Für gewöhnliche Arbeit reicht der reguläre Modell-Picker; der Wert der Arena sind die Bewertungen, die sie produziert, nicht die Vergleichsansicht selbst. ## Wie die Arena rendert Öffne das Plus-Menü des Chats und wähl **Arena-Modus** — der Chat bekommt zwei Modell-Picker mit den Beschriftungen **Modell A** und **Modell B**. Eine Nachricht zu senden führt beide Modelle parallel aus; der Bildschirm teilt sich, und jede Antwort streamt in ihre eigene Spalte. Sind beide fertig, erscheint unter den Spalten eine Bewertungszeile mit vier Knöpfen: **A ist besser**, **B ist besser**, **Unentschieden**, **Beide schlecht**. <Frame caption="Dasselbe Prompt, von zwei Modellen beantwortet, mit der Bewertungszeile darunter."> ![Der Arena-Modus mit einem Prompt für eine Launch-Checkliste, beantwortet in zwei Spalten — links liefert Claude Haiku 4.5 eine nummerierte Liste aus fünf Schritten, rechts gruppiert Claude Sonnet 4.6 dieselbe Arbeit unter Überschriften und ergänzt die Risiken, die eine Erwähnung wert sind — über den Bewertungs-Knöpfen A ist besser, B ist besser, Unentschieden und Beide schlecht.](/images/platform/chat-arena-split.webp) </Frame> <Note> Beide Spalten laufen mit demselben Agent — wähl den Agent, um den es dir geht, bevor du die Arena aktivierst. Der Vergleich sagt nur dann etwas aus, wenn Instructions, Tools und Wissen auf beiden Seiten identisch sind. </Note> ## Die Kontrahenten wählen Die beiden Picker sind unabhängig — jedes Modell, das die Policy des Agents erlaubt, ist auf jeder Seite zulässig. Dasselbe Modell auf beiden Seiten zu wählen ist erlaubt (nützlich, um Temperaturunterschiede zu testen, wenn der Agent das freigibt), aber die meisten Vergleiche spannen über Anbieter oder Größen. Die Instructions, das Wissen und die Tools des Agents gelten für beide Spalten; nur das zugrunde liegende Modell unterscheidet sich. ## Eine Bewertung abgeben Die Bewertung ist ein einzelner Klick. **A ist besser** und **B ist besser** erklären sich selbst; **Unentschieden** ist für ungefähr gleich gute Antworten; **Beide schlecht** für den Fall, dass keine akzeptabel ist. Der Knopf, den du klickst, speichert die Bewertung und löst den Chat zur gewinnenden Spalte hin auf — die nächste Nachricht, die du sendest, geht nur an dieses Modell. **Unentschieden** oder **Beide schlecht** lässt beide Spalten für eine weitere Runde aktiv. ## Wo Bewertungen auftauchen Bewertungen laufen unter **Arena-Urteile** in der [Feedback-Analyse](/de/platform/admin/governance/feedback-analytics) zusammen, neben einer Tabelle **Top Modell-Duelle**, die Paarungen nach Gewinnrate ordnet. Die Daten sind org-gebunden statt pro User — eine Handvoll bewusster Urteile kann also einen viel größeren Stapel Gewohnheit überwiegen, wenn jemand die Tabelle liest, um zu entscheiden, zu welchem Modell das Team greifen sollte. ## Wann du danach greifst | Nutz … wenn | Arena-Modus | Regulärer Modell-Picker | | -------------------------------------------------------------------- | ----------- | ----------------------- | | Du entscheidest, welches Modell zum Standard werden soll | ✓ | | | Du vermutest eine Modell-Regression nach einem Upgrade | ✓ | | | Du weißt schon, welches Modell du willst; du willst nur eine Antwort | | ✓ | | Die Anfrage ist kurz und gewöhnlich | | ✓ | ## Wo das hineinpasst Die Arena ist die leichtgewichtige Rückkopplungsschleife auf der Modellwahl. Die schwerere Oberfläche ist die [Feedback-Analyse](/de/platform/admin/governance/feedback-analytics) — dort werden deine Bewertungen zu einem Diagramm, mit dem jemand später über Defaults streitet. Wenn du derjenige bist, der die Tabelle später liest, dreh vorher eine Handvoll Arena-Runden; die selbst abgegebenen Bewertungen sagen dir, ob die Rahmung der Tabelle deine Erfahrung trifft. # Chat-Grundlagen Source: https://tale.dev/docs/de/platform/chat/basics Diese Seite ist das mentale Modell für alles im Chat-Tab. Sie benennt die Teile der Eingabezeile, verfolgt eine Nachricht vom Tastendruck bis zur gestreamten Antwort, sagt genau, was das Modell in die Hand bekommt und was es unterwegs aufrufen darf, und zeigt, wie du liest, was zurückkam. Lies sie einmal, und die übrigen Chat-Seiten sind Variationen desselben Ablaufs. <Frame caption="Der Chat-Tab mit einer gestreamten Antwort über der Eingabezeile."> ![Ein Chat-Thread zeigt eine Nutzerfrage zu Onboarding-Feedback und eine Assistenten-Antwort mit einer Markdown-Tabelle aus drei Themen.](/images/platform/chat-thread-reply.webp) </Frame> ## Die Eingabezeile Die Eingabezeile ist der Eingabestreifen am unteren Bildschirmrand. Das Nachrichtenfeld sendet mit **Enter** und bricht die Zeile mit **Shift+Enter** um. Ein Picker neben dem `+`-Menü hält die Modellwahl — **Auto**, der Standard, lässt Tale pro Nachricht ein Modell wählen, oder du benennst eines — und, bei einem benannten Modell, das ihn anbietet, den Denkaufwand. Mehr Wahlen gibt es nicht, mit Absicht: kein Agent-Picker, kein Skill-Picker, keine Stellschraube dafür, wo der Zug läuft. Das `+`-Menü trägt **Fotos & Dateien hinzufügen** und, wo ein Chat ihn hergibt, den **Arena-Modus** ([Arena-Modus](/de/platform/chat/arena-mode)); **Antworten vorlesen** ([Sprachmodus](/de/platform/chat/voice-mode)) ist der Lautsprecher-Schalter neben dem Mikrofon, und das Mikrofon diktiert ins Feld. Während eine Antwort streamt, wird aus dem Senden-Knopf Stopp. Stoppen behält alles, was schon gestreamt ist — die Antwort bleibt stehen, wie sie ist, notfalls mitten im Satz. ### Anhänge Zieh Dateien vom Desktop irgendwo auf die Eingabezeile — beim Überfahren sagt eine Einblendung **Dateien hier ablegen zum Hochladen** —, füge einen Screenshot direkt ins Nachrichtenfeld ein oder wähle Dateien über **Fotos & Dateien hinzufügen** im `+`-Menü. Der Chat nimmt Bilder, Dokumente (PDF, Office, OpenDocument, CSV), textbasierte Dateien und Audio/Video. Jedes Bild liegt als kleine Miniatur über dem Feld: Ein Klick zoomt hinein, das ✕ entfernt es. Alles andere erscheint als benannter Chip mit Verarbeitungsstatus: Das Transkriptionsmodell deiner Organisation macht aus Audio und Video Text, Dokumente werden für den Abruf indexiert. Senden wartet auf keinen Fortschrittsbalken — eine Nachricht, die du abschickst, während Dateien noch verarbeiten, parkt über der Eingabezeile und geht von selbst raus, sobald alles bereit ist; ihr ✕ verwirft die wartende Nachricht und legt den Text zurück ins Feld. Bis zu zehn Dateien reisen mit einer Nachricht. Füge einen Videolink ein (YouTube, Vimeo, Bilibili und Co.) und auch er wird zum Chip: Tale holt im Hintergrund die Untertitel — oder extrahiert und transkribiert die Tonspur, wenn es keine gibt — und das Transkript reist mit deiner Nachricht wie eine hochgeladene Aufnahme. Nur ein fehlgeschlagener Video-Chip hält das Senden auf, weil das Warten darauf nie enden würde: Versuch es erneut oder entferne ihn, alles andere reiht sich ein. Ein Modell, das Bilder sehen kann, bekommt die Pixel selbst, mitten in deinen Worten; bei einem, das es nicht kann, sagt die Eingabezeile das schon beim Anhängen — dieses Modell sähe nur die Dateinamen. Audio erreicht das Chat-Modell nie als Bytes: das Modell bekommt das Transkript als Text, deine Blase behält die Worte, die du getippt hast (plus den Audio-Chip). Der Inhalt eines Dokuments erreicht den Assistenten über seine Wissenswerkzeuge — die Runde nennt ihm die angehängten Dateien und er liest sie mit `rag_fetch`; rechne also mit einem Abrufschritt vor der Antwort. Ein Format ohne Textextraktion (alte Office-Dateien wie `.doc`) hängt trotzdem an, aber der Assistent sieht nur den Namen — und sagt das, statt zu raten. Hier abgelegte Dokumente bleiben privat in diesem Chat — sie landen nie in der [Wissens](/de/platform/knowledge/overview)-Bibliothek der Organisation, und kein anderer Chat und niemand sonst kann sie abrufen. Angehängte Dateien gehören zu dem Chat, in dem du sie angehängt hast (ein Chatwechsel leert sie), und eine neu generierte Antwort schickt dieselben Anhänge noch einmal mit — Transkripte und Dokumentzugriff baut die Runde für das Modell aus den gespeicherten Dateien neu auf. Arbeit, die Dateien erzeugt, gehört in einen Task. Ins Mikrofon sprechen ist ein eigener Weg — siehe [Sprachmodus](/de/platform/chat/voice-mode). <Frame caption="Die Eingabezeile: Nachrichtenfeld, der Picker für Modell und Denkaufwand, Diktat, Senden."> ![Die Chat-Eingabezeile mit ihrem Plus-Menü, dem Modell-Picker auf Auto, dem Mikrofon-Knopf und dem Senden-Knopf.](/images/platform/chat-composer.webp) </Frame> ## Ein Modell wählen Der Picker startet auf **Auto**: Tale liest jede Nachricht — Länge, Code, Thema — und wählt ihr ein Modell aus derselben Liste, die der Picker zeigt: ein leichtes für die schnelle Frage, ein starkes für harten oder heiklen Boden. Ein angehängtes Dokument hebt die Untergrenze: Eine Nachricht, die eine Datei zum Lesen trägt, geht nie ans leichteste Modell, so kurz die Frage auch ist. Keine zweite KI entscheidet das (es ist eine schlichte Heuristik auf der Nachricht), und still ausgewichen wird nie: Das Modell, das deine Antwort beginnt, beantwortet sie auch, und die Nachrichtendetails nennen es. Trägt eine Nachricht Bilder, kommen nur Modelle infrage, die sie sehen können; kann es keines, sagt der Versand das, statt zu raten. Entscheidest du lieber selbst? Wähl ein Modell aus der Liste — der Picker listet die Modelle, für die die Organisation ein aktives, direkt nutzbares Credential hält; ein Modell, das nur im eigenen Werkzeug seines Anbieters laufen könnte, taucht hier nicht auf. Eine benannte Wahl bleibt deine, bis du sie an Auto zurückgibst, und beides bleibt als Standard für deine nächsten Chats stehen. Auto erscheint nur, wenn es wirklich etwas zu wählen gibt — bei einem einzigen nutzbaren Modell nennt der Picker schlicht dieses. Bei Modellen mit steuerbarer Denktiefe setzt der zweite Abschnitt des Pickers den Denkaufwand. Die Wahl reist mit dem Gespräch — jeder folgende Zug läuft auf der Stufe, die du gesetzt hast, und Modelle ohne den Regler ignorieren sie. Auf **Standard** antwortet ein Modell, das ohne langes Nachdenken auskommt, genau so — wähl eine Stufe, wenn es länger nachdenken soll. Auf Auto bleibt der Aufwand-Abschnitt aus dem Menü: Wie hart ein Modell nachdenkt, gehört zu der Frage, _welches_ Modell läuft — nagle eines fest, um ihn zu setzen. ## Was das Modell bekommt Der Prompt entsteht in einer festen Reihenfolge, und die Liste ist bewusst kurz: die verbindlichen Anweisungen der Organisation, der eingebaute Leitfaden des Assistenten, die Regeln für den Umgang mit nicht vertrauenswürdigen Inhalten, eine kurze Zeile Dokumentation pro Tool, dann der aktuelle Zeitstempel mit der Sprachvorgabe für die Antwort und schließlich der vollständige Nachrichtenverlauf — samt jedem Tool-Aufruf und jedem Ergebnis, genau so, wie sie passiert sind. Mehr kommt nicht dazu. Es gibt keinen Personalisierungs-Block, keine heimlich eingeschobenen Memories, keinen automatischen Wissensabruf und keinen automatischen Web-Kontext. Alles, was das Modell über seine Anweisungen hinaus erfährt, erfährt es über einen Tool-Aufruf — und damit steht es im Transkript, zuordenbar und ablehnbar. <Info> Wächst das Gespräch über das Kontextfenster des Modells hinaus, fallen die ältesten Nachrichten weg, und an ihre Stelle tritt ein sichtbarer Hinweis. Zusammengefasst wird nichts: Eine Zusammenfassung wäre ein zweiter Modellaufruf, der genau die Historie erfinden kann, die er bewahren soll — weggefallene Nachrichten dagegen verlieren Information auf eine Art, die du siehst. </Info> ## Die drei Tools Der Assistent trägt genau drei Tools, alle drei reiner Lese-Abruf — das ist die Grenze, die Chat ein Gespräch bleiben lässt statt einer Werkbank. | Tool | Was es erreicht | | ------------ | ------------------------------------------------------------------------------------------------------------------------------------- | | `rag_search` | Das Wissen der Organisation: Dokumente, Wissenseinträge, gecrawlte Website-Seiten, Produkte und Kontakte | | `rag_fetch` | Der Volltext hinter einer Referenz — ein angehängtes oder gefundenes Dokument über seine Datei-ID, eine gecrawlte Seite über ihre URL | | `web_fetch` | Eine öffentliche Webseite, live geholt — der Schritt über das Org-Wissen hinaus; bereits gecrawlte Inhalte liefert `rag_fetch` | Eine Suche ist ehrlich darüber, was sie abgedeckt hat: Das Ergebnis benennt jede durchsuchte Quelle und sagt, welche nicht verfügbar waren — eine Organisation ohne konfiguriertes Embedding-Modell bekommt zum Beispiel „Dokumente und gecrawlte Seiten sind noch nicht durchsuchbar" statt einer stumm leeren Liste, und der Assistent gibt das weiter, statt darum herumzuraten. Mehr gibt es bewusst nicht — kein Code-Ausführen, kein Datei-Schreiben, keine Connectors, keine Sub-Agents. Diese Fähigkeiten leben auf Aufgaben und in Automatisierungen, wo es Verantwortliche, einen Prüfschritt und ein Audit-Protokoll gibt, das ihnen gewachsen ist. ## Nach einem Arbeitsergebnis fragen Bitte den Assistenten um eine Präsentation, ein übersetztes Dokument oder ein anderes Artefakt, und er baut es nicht halbfertig im Chat: Er gibt dir die Kurzfassung, wenn eine nützlich ist, und verweist dich dann darauf, eine Aufgabe zu erstellen und sie einem Agent zuzuweisen. Eine Aufgabe hat Verantwortliche, produziert ein prüfbares Ergebnis, und nur ein Mensch setzt sie auf Erledigt — nichts davon kann eine Chat-Antwort bieten. Einen eingefügten Satz zu übersetzen ist Chat-Arbeit; eine Datei zu übersetzen ist Aufgaben-Arbeit. ## Die Antwort lesen Die Antwort streamt herein, während sie entsteht. Darüber hält der Denkverlauf fest, was der Assistent getan hat, in Reihenfolge: - Eine einklappbare Zeile **„Hat _n_ s nachgedacht"** trägt das Nachdenken des Modells — ein Klick klappt die Prosa auf. - Jeder Tool-Aufruf ist eine Schrittzeile — _Durchsucht die Wissensdatenbank nach "…"_, _Liest example.com_ — mit einem Spinner, solange er läuft, und einer Warnung samt Grund, wenn er scheitert. Die Schritte bleiben sichtbar, wenn das Nachdenken eingeklappt ist; sie sind das Protokoll dessen, wonach der Assistent gegriffen hat. Unter der Antwort listet **Quellen** die Seiten und Dokumente, die der Assistent tatsächlich geladen hat — abgeleitet aus den Tool-Ergebnissen, nicht aus der Prosa, sodass eine Quellenkarte nie eine Lektüre behauptet, die nicht stattgefunden hat. Web-Quellen öffnen in einem neuen Tab. Die Werkzeugleiste unter einer fertigen Antwort kopiert den Text, zeigt Token-Zahlen und Zeiten (**Senden → erstes Wort** ab Senden; **Start → fertig** und **Start → erster Token** ab dem Start der Antwort auf dem Server), nimmt eine Daumen-Bewertung entgegen und forkt den Chat — eine sichtbare Kopie des Gesprächs bis zu diesem Punkt, fortgesetzt als eigener neuer Chat. ## Konversationen versus Chats Innerhalb von Chat ist die Einheit ein **Chat** — das Wort, das jede Schaltfläche und jeder Toast verwendet. Das Datenmodell dahinter heißt `threads`, und die URL trägt `threads/$threadId`; die Docs folgen der UI und sagen in der Prosa „Chat". Die Kontaktkanal-Inbox, die eine installierte E-Mail-Automatisierung hinzufügt, ist eine andere Oberfläche: Eine Konversation dort ist ein Kontakt-Thread und kein Chat — diese Bedeutung steht unter [Mitgelieferte Automatisierungen](/de/platform/automations/builtin). ## Verlauf und Suche Die Verlaufs-Sidebar listet jeden Chat, den du in dieser Org fortsetzen kannst, den neuesten zuoberst — deine angehefteten Chats schwimmen obenauf, in Projekte eingeordnete Chats stehen unter ihren Ordnern; eine Auswahl öffnet das volle Transkript. Die Suche dort filtert nach Titel, und die Volltextsuche über Nachrichtentexte läuft pro Chat statt org-weit. Benennst du einen Chat um, überschreibt der eigene Titel den generierten. Löschst du einen Chat, wandert er in den [Papierkorb](/de/platform/admin/governance/trash), wo die Aufbewahrung ihn nach der Schonfrist wegräumt. ## Wo das hineinpasst Chat-Grundlagen ist die Seite, die der Rest dieses Abschnitts verfeinert: Der [Arena-Modus](/de/platform/chat/arena-mode) schickt einen Prompt durch zwei Modelle nebeneinander, der [Sprachmodus](/de/platform/chat/voice-mode) behandelt das Sprechen statt Tippen, und [Geteilte Chats](/de/platform/chat/shared-threads) das Veröffentlichen eines Transkripts an die Org. Ist aus deiner Frage Arbeit geworden — etwas mit einem Ergebnis am Ende —, sind die [Agent-Konzepte](/de/platform/agents/concepts) die nächste Lektüre: Agents tun auf Aufgaben all das, was Chat bewusst weglässt. # Sprachmodus Source: https://tale.dev/docs/de/platform/chat/voice-mode Der Sprachmodus verwandelt die Eingabezeile in ein Mikrofon. Du sprichst, die Aufnahme wird zu deiner nächsten Nachricht transkribiert, der Agent antwortet in Text, und diese Antwort kann laut vorgelesen werden. Die Schleife ist freihändig, was viel wert ist, wenn du unterwegs bist, kochst oder müde vom Tippen — und sie durchquert zwei Sprachanbieter, was du wissen solltest, bevor die Daten deiner Organisation dort hindurchlaufen. Diese Seite beschreibt beide Hälften der Runde und die Grenze, die das Audio überschreitet. Am Chat selbst ändert sich nichts: Sprache ist eine Hülle um denselben Nachrichtenfluss, den [Chat-Grundlagen](/de/platform/chat/basics) beschreibt. ## Sprache zu Text Starte die Aufnahme über das Mikrofon in der Eingabezeile und sprich; auf demselben Weg beendest du sie. Die Aufnahme wandert nach oben, ein Speech-to-Text-Modell transkribiert sie, und das Transkript wird zur nächsten Nachricht im Chat — genau so, als hättest du sie getippt. Du kannst das Transkript vor dem Absenden lesen, und das zählt: Ein Transkriptionsfehler ist von einer schlecht formulierten Frage nicht mehr zu unterscheiden, sobald der Agent geantwortet hat. Die Transkription läuft einmal pro gesprochener Nachricht. Was der Agent bekommt, ist Text; Audio erreicht das Chat-Modell nie. ## Text zu Sprache Ob eine Antwort vorgelesen wird, entscheidest du in der Eingabezeile, für den Zug, den du gerade absendest. Schalte die Sprachausgabe ein, und die zurückkommende Antwort geht an ein Text-to-Speech-Modell und wird abgespielt, während sie eintrifft; lässt du sie aus, landet die Antwort als Text wie jede andere. Die Wiedergabe lässt sich vorzeitig stoppen, und die letzte Antwort lässt sich erneut abspielen, ohne die Frage zu wiederholen. <Note> Die Sprachausgabe ist ein Bedienelement der Eingabezeile und keine gespeicherte Einstellung. Es gibt keine Stimme, die an einem Agent hängt, und keine organisationsweite Vorgabe, die für dich entscheidet — der Zug, den du gerade sendest, ist der ganze Geltungsbereich der Wahl. Das bewahrt dich davor, dass eine freihändige Sitzung dir ins Großraumbüro folgt. </Note> ## Wer welchen Teil hält Zwei Modellwahlen zählen hier, und keine davon ist das Modell im Modell-Picker. Speech-to-Text läuft vor dem Agent-Zug, auf dem Audio. Text-to-Speech läuft danach, auf der fertigen Antwort. Der Agent dazwischen bleibt unverändert — dieselben Instructions, dieselben Tools, derselbe Kontext-Vertrag. Beide richtet ein, wer die Anbieter der Organisation verwaltet. Ist kein Sprachanbieter eingerichtet, haben die Sprach-Bedienelemente nichts zum Aufrufen, und die Lösung ist ein angebundener Anbieter, nicht eine Änderung im Chat. ## Die Datenschutzgrenze Die Aufnahme verlässt dein Gerät. Sie wandert in Tales Speicher, geht an den Speech-to-Text-Anbieter, den die Organisation eingerichtet hat, und das entstehende Transkript bleibt im Chat-Verlauf neben den getippten Nachrichten — durchsuchbar, exportierbar und denselben Aufbewahrungsregeln unterworfen wie alles andere im Chat. Für das Audio selbst gilt die Aufbewahrungsrichtlinie der Org. Antworten gehen als reiner Text an den Text-to-Speech-Anbieter, und das zurückkommende Audio streamt auf dein Gerät, statt gespeichert zu werden. <Warning> Organisationen mit strengen Regeln zur Datenlokalität sollten Sprachanbieter in derselben Region wählen wie den Rest des Stacks — für Audio und Transkript gelten dieselben Regeln wie für jeden anderen Nachrichteninhalt. Siehe [Datenresidenz](/de/cloud/data-residency). </Warning> ## Wann Sprache den Text schlägt Sprache ist schneller als Tippen bei kurzen, gesprächigen Fragen und deutlich langsamer bei allem, was du hinterher kopieren würdest. Eine gesprochene Antwort hörst du einmal; eine geschriebene lässt sich überfliegen, zitieren und einfügen. | Nimm … wenn | Sprache | Text | | ------------------------------------------------------ | ------- | ---- | | Du die Hände voll hast und schnell etwas wissen willst | ✓ | | | Die Antwort eine lange Liste oder ein Code-Block wird | | ✓ | | Die Antwort in eine spätere Schreibarbeit einfließt | | ✓ | | Du eine Sprache übst und sie hören willst | ✓ | | ## Wo das hineinpasst Sprache ist die zweite Eingabeform derselben Eingabezeile, neben dem Tippen. Der Datenschutz wiegt hier am schwersten, weil zwei zusätzliche Anbieter die Daten berühren — welche Seite du als Nächstes liest, hängt darum von deiner Edition ab: [Datenresidenz](/de/cloud/data-residency) in der Cloud oder [Anbieter](/de/self-hosted/configuration/providers), wenn du Tale selbst betreibst und die Sprachanbieter genauso wählst wie die Chat-Modelle. # Geteilte Chats Source: https://tale.dev/docs/de/platform/chat/shared-threads Einen Chat zu teilen veröffentlicht einen schreibgeschützten Snapshot davon unter einem Link, den jeder in deiner Organisation öffnen kann. Das Ganze ist eine Geste: **Teilen** kopiert den Link in deine Zwischenablage, und du fügst ihn dort ein, wo dein Team sich unterhält. Der Mechanismus ist leicht genug für den beiläufigen Einsatz — teil eine Frage und ihre Antwort so, wie du ein Dokument teilen würdest. ## Einen Chat teilen Öffne den Chat und klicke auf das **⋯**-Menü in der Kopfzeile, dann auf **Teilen**. Der Link landet sofort in deiner Zwischenablage — ein Toast **Link kopiert** bestätigt es. Derselbe Eintrag liegt im Zeilenmenü jedes Chats in der Sidebar. Zwei Dinge, die du über den Link wissen solltest: - **Er ist auf die Org begrenzt.** Nur angemeldete Mitglieder deiner Organisation können ihn öffnen; eine öffentliche URL ist er nicht. - **Er ist ein Snapshot.** Empfänger sehen das Gespräch in dem Stand, in dem du es geteilt hast. Läuft der Chat weiter und du willst den neueren Stand teilen, klick erneut auf **Teilen** — der Link bleibt derselbe, der Snapshot erneuert sich. <Frame caption="Was Empfänger öffnen: der geteilte, schreibgeschützte Snapshot mit dem Vermerk, wer wann geteilt hat."> ![Ein geteilter Chat in der schreibgeschützten Ansicht: das Gesprächstranskript unter der Überschrift Geteilter Chat, mit einem Vermerk, wer ihn wann geteilt hat.](/images/platform/chat-shared-view.webp) </Frame> ## Was Betrachter sehen Der Link öffnet eine schreibgeschützte Ansicht **Geteilter Chat**: das Transkript, mit einem Vermerk, wer geteilt hat und wann. Eine Eingabezeile gibt es nicht — ein geteilter Chat ist etwas zum Lesen, kein Ort zum Antworten. Wer das Thema weiterführen will, startet einen eigenen Chat — oder eine Aufgabe in einem [Projekt](/de/platform/projects/overview), wenn ein Arbeitsergebnis gefragt ist. ## Teilen beenden Sobald ein Chat geteilt ist, bietet sein Zeilenmenü **Teilen beenden** an. Der Link funktioniert sofort nicht mehr; Besucher landen auf einer Seite „nicht mehr verfügbar". Den Chat zu löschen hat auf den Link denselben Effekt. Teilst du später erneut, entsteht ein frischer Snapshot. ## Wo das hineinpasst Geteilte Chats sind der leichtgewichtige Weg, jemandem im Team ein Gespräch zu übergeben, ohne das Produkt zu verlassen. Die schwergewichtige Alternative ist, die Person in ein [Projekt](/de/platform/projects/overview) zu holen, wo Chats, Dateien und Agents standardmäßig geteilt sind. Teilen ist für einmalige Übergaben; ein Projekt ist für laufende Zusammenarbeit an derselben Arbeit. # Chat Source: https://tale.dev/docs/de/platform/chat/overview Chat ist der tägliche Einstieg in Tale. Du fragst, der Assistent durchsucht das Wissen der Organisation oder holt eine Seite, wenn die Frage es verlangt, und die Antwort streamt zurück — jeder Schritt und jede Quelle sichtbar. Chat macht bewusst genau eine Sache: Fragen und Nachschlagen. Arbeit, die Verantwortliche und ein prüfbares Ergebnis braucht — eine Präsentation, ein übersetztes Dokument, ein Datenexport —, lebt auf einer Aufgabe; ein fester Prozess lebt in einer Automatisierung. Der Assistent kennt diese Grenze und verweist dich auf eine Aufgabe, sobald eine Anfrage sie überschreitet — nichts Schweres bleibt je halbfertig in einem Chat liegen. <Frame caption="Ein Chat mit einer gestreamten Antwort — die Frage, die Schritte des Assistenten und die Antwort."> ![Ein Chat-Thread zeigt eine Nutzerfrage zu Onboarding-Feedback und eine Assistenten-Antwort mit einer Markdown-Tabelle aus drei Themen.](/images/platform/chat-thread-reply.webp) </Frame> ## Die Teile des Bildschirms Die Sidebar listet jeden Chat, den du fortsetzen kannst — einsortiert unter deinen Projektordnern, angeheftete Favoriten zuoberst, darunter Suche und Archiv. Die Gesprächsspalte trägt den Austausch: Über jeder Antwort hält eine einklappbare Denkzeile fest, was der Assistent getan hat — das Nachdenken und jede Wissenssuche und jeden Seitenabruf, in Reihenfolge —, und unter der Antwort listet **Quellen**, was er tatsächlich gelesen hat. Die Eingabezeile am unteren Rand ist das Nachrichtenfeld plus ein Picker für das Modell — **Auto** als Standard, jedes gelistete Modell zum Festnageln und der Denkaufwand für ein festgenageltes Modell mit Regler; im `+`-Menü liegen das Vorlesen und der Arena-Modus, und das Mikrofon diktiert. Während eine Antwort streamt, wird aus Senden Stopp. Ein frischer Chat öffnet mit vier Gesprächsstartern. Klick einen an, und er wird deine erste Nachricht — der schnellste Weg, die ganze Schleife einmal laufen zu sehen. <Frame caption="Ein neuer Chat: die Begrüßung, vier Gesprächsstarter und die Eingabezeile."> ![Der leere Bildschirm eines neuen Chats mit der Begrüßung, vier Gesprächsstarter-Knöpfen und der Eingabezeile darunter.](/images/platform/chat-starters-empty.webp) </Frame> ## Chat, Aufgabe oder Automatisierung? Ordne die Arbeit der passenden Fläche zu — jede Art hat genau ein Zuhause. | Art der Arbeit | Wo sie lebt | Warum | | ---------------------------------------------------------------------------------- | --------------- | -------------------------------------------------------------------------------------- | | Nach Wissen, Dokumenten oder einer öffentlichen Webseite fragen | Chat | Ein Gespräch mit sichtbaren Schritten und Quellen; nichts abzunehmen | | Ein Arbeitsergebnis produzieren — eine Präsentation, eine Übersetzung, ein Bericht | Aufgabe | Braucht Verantwortliche und Prüfung; ein Agent arbeitet, ein Mensch setzt auf Erledigt | | Ein fester Prozess mit Kontrollpunkten und menschlichen Schritten | Automatisierung | Der Prozess ist das Produkt; Menschen und Agents handeln in ihm | Die erste Zeile setzt der Assistent selbst durch: Bitte ihn um einen Aufsatz mit 2000 Wörtern, und er gibt dir eine kurze Skizze — und verweist dich dann darauf, eine Aufgabe zu erstellen und sie einem Agent zuzuweisen. Das ist Absicht: Ein Arbeitsergebnis, das direkt im Chat entstünde, hätte weder Prüfschritt noch Verantwortliche. ## Seiten in diesem Abschnitt <CardGroup cols="2"> <Card title="Chat-Grundlagen" icon="message-circle" href="/de/platform/chat/basics"> Was zwischen dem Senden und der landenden Antwort passiert — die Eingabezeile, die drei Abruf-Tools, der Denkverlauf und die Quellen. </Card> <Card title="Arena-Modus" icon="swords" href="/de/platform/chat/arena-mode"> Modell-Vergleich nebeneinander, und wie Urteile in die Feedback-Analyse einfließen. </Card> <Card title="Sprachmodus" icon="mic" href="/de/platform/chat/voice-mode"> Sprechen statt Tippen — die STT- und TTS-Übergaben und die Datenschutzgrenze. </Card> <Card title="Geteilte Chats" icon="share-2" href="/de/platform/chat/shared-threads"> Einen schreibgeschützten Snapshot eines Chats mit dem Rest der Org teilen — und das Teilen später beenden. </Card> </CardGroup> ## Wo das hineinpasst Chat ist die Frage-Fläche; der Rest der Plattform ist das, was er befragt. Wissen füttert seine Suchen, und [Projekte](/de/platform/projects/overview) ordnen seinen Verlauf ein und tragen die Aufgaben, die alles übernehmen, was Chat bewusst nicht inline baut. Die Seite, die du dir zuerst merken solltest, ist [Chat-Grundlagen](/de/platform/chat/basics) — sobald du den Weg vom Senden zur Antwort verstanden hast, liest sich jede andere Chat-Seite als Variation davon. # MCP-Server Source: https://tale.dev/docs/de/platform/connectors/mcp-servers Ein MCP-Server ist ein externer Prozess, der Tales Agents über das Model Context Protocol Tools bereitstellt. Wo eine [Connector](/de/platform/connectors/overview) ein anbieterspezifischer Konnektor ist, den Tale mitliefert, ist ein MCP-Server eine generische Brücke, die jeder hosten kann — eine interne API, ein Anbieter ohne Konnektor, ein Skript, das etwas berechnet, was Tales eingebaute Tools nicht können. Du hostest den Server; Tale spricht nur mit ihm. <Frame caption="Das Formular MCP-Server hinzufügen — eine Verbindung und eine Authentifizierungsmethode sind die ganze Registrierung."> ![Der Dialog MCP-Server hinzufügen unter Einstellungen API MCP, ausgefüllt für einen Server für Support-Tickets — Anzeigename Support Tickets, eine einzeilige Beschreibung, Streamable HTTP als Transporttyp, die Server-URL und Keine als Authentifizierungsmethode — über der MCP-Seite, auf der bereits ein Server Internal Wiki registriert ist.](/images/platform/settings-mcp-add-dialog.webp) </Frame> ## Einen Server registrieren Öffne **Einstellungen > API > MCP** und klicke auf **MCP-Server hinzufügen**. Das Formular nimmt: - **Name** und **Anzeigename** — die Kennung und das Label, das Agents und Genehmigungskarten zeigen. - **Transporttyp** — **Streamable HTTP**, **SSE** oder **stdio**. Die HTTP-Transporte nehmen eine **URL** — das Formular markiert eine fehlerhafte URL inline, bevor du speichern kannst; stdio nimmt den Befehl, den Tale startet. - **Authentifizierung** — **Keine**, **API-Key** oder **OAuth 2.0** (Token-URL, Client-ID und -Geheimnis, Bereiche). - **Erlaubte Agents** — welche Agents sich an diesen Server binden dürfen. Standard ist keine Agents; greif zu **Alle Agents** nur, wenn der Server generisch genug ist, dass jeder Agent profitiert. **Server speichern**, dann **Verbindung testen** auf der Zeile, um den Handshake zu prüfen — der Status der Zeile zeigt **Verbunden**, **Getrennt** oder **Fehler** mit der Meldung der Gegenseite. ## Die erkannten Tools Sobald die Verbindung steht, holt Tale das Manifest des Servers und listet es als **Erkannte Tools** — Name und Beschreibung jedes Tools und ob der Server es mit **Genehmigung erforderlich** markiert. Markierte Tools fragen im Chat bei jedem Aufruf durch einen Agent, mit den exakten Argumenten auf der Karte; unmarkierte laufen wie jedes eingebaute Tool. <Warning> Jedes MCP-Tool weitet aus, was deine Agents erreichen können, und die Genehmigungs-Flags stammen vom Autor des Servers — einen Server zu verbinden heißt, seinen Tool-Vertrag anzunehmen. Lies die erkannte Liste, bevor du Agents auf einen Server richtest, den du nicht selbst geschrieben hast. </Warning> ## Aus Agents heraus nutzen Die Tools eines registrierten, aktiven Servers reihen sich in das Tool-Set ein, das Agents aufrufen können; die Anfrage reist durch Tale zu deinem Server, und die Antwort kommt zurück ins Gespräch. Der Server kann auch Ressourcen und Prompts bereitstellen, wo sein Autor sie implementiert — Tools sind die gemeinsame Oberfläche. ## Deaktivieren und entfernen Jede Server-Zeile lässt sich deaktivieren — seine Tools fallen aus den Tool-Sets der Agents heraus, bis du ihn wieder aktivierst; die Registrierung bleibt erhalten. Den Server zu löschen entfernt die Registrierung nach einer Bestätigung vollständig; ihn später erneut hinzuzufügen ist eine frische Registrierung mit einem frischen Manifest-Abruf. ## MCP-Server oder Connector Beide lassen einen Agent über Tale hinausgreifen; der Unterschied ist, wem der Konnektor gehört. Connectors sind anbieterspezifisch, mitgeliefert und im Katalog gepflegt; MCP-Server sind generisch, und du betreibst sie selbst. Greif zur Connector, wenn eine für das Zielsystem existiert; greif zu MCP, wenn die Brücke dein eigener Code sein soll. ## Wo das hingehört MCP ist die offene Erweiterungsfläche des Agent-Tool-Sets. Die natürlichen nächsten Lektüren sind [Agent-Tools](/de/platform/agents/tools) dafür, wie Tools an einem Agent auftauchen, [Genehmigungen konfigurieren](/de/platform/approvals/configure) für die Flags, die riskante Aufrufe anhalten, und das Tutorial [MCP-Server von Grund auf](/de/tutorials/developer/mcp-server-from-scratch) für den Bau von Anfang bis Ende. # WebDAV Source: https://tale.dev/docs/de/platform/connectors/webdav WebDAV verwandelt Tales Dokumentenspeicher in einen entfernten Ordner, den du wie jedes geteilte Netzlaufwerk einhängst. Der dahinterliegende Speicher ist derselbe, den der Dokumenten-Hub zeigt — was du in den eingehängten Ordner legst, erscheint in der UI, und umgekehrt. Alles Nötige liegt auf einem Panel: **Einstellungen > API > WebDAV** trägt die Verbindungsdaten und den App-Passwort-Generator. <Frame caption="Einstellungen > API > WebDAV — oben die vorbefüllten Verbindungsdaten, darunter der App-Passwort-Generator."> ![Die WebDAV-Einstellungsseite mit einer Verbindungs-URL, einem Benutzernamensfeld mit der Konto-E-Mail, einer Erklärung, dass das Passwort ein erzeugtes App-Passwort ist, und einer App-Passwort-Tabelle mit zwei Einträgen — Design workstation und MacBook Pro, jeder nur mit seinem Präfix und dem Erstellungsdatum — neben einem Erzeugen-Button.](/images/platform/settings-webdav.webp) </Frame> ## Ein App-Passwort erzeugen Der Endpunkt authentifiziert mit App-Passwörtern — kurzen Geheimnissen, die du pro Gerät prägst — weil jeder WebDAV-Client seinen Zugangsnachweis im System-Schlüsselbund ablegt, und dorthin gehört ein begrenztes, widerrufbares Geheimnis statt deines Konto-Passworts. Dein Konto-Passwort funktioniert an diesem Endpunkt nicht. Klicke auf **Erzeugen**, benenne das Passwort nach dem Gerät (`MacBook Finder`, `ops-laptop rclone`) und kopiere es — nutze eines pro Gerät; das vollständige Passwort erscheint nur einmal. Danach behält die Tabelle nur die Bezeichnung und ein kurzes Präfix, genug, um die Zeile wiederzuerkennen, wenn du sie widerrufst. Das Erzeugen verlangt dieselbe Berechtigung, die auch API-Schlüssel schützt; Mitglieder ohne sie bitten einen Admin. Für den Benutzernamen nimm deine Tale-Konto-E-Mail. Der Server prüft tatsächlich nur das Passwort, aber die E-Mail hält Audit-Zeilen lesbar und entspricht dem, was Client-Dialoge erwarten. ## Von deinem Gerät verbinden Die Adresse ist die URL vom Panel — `https://<your-site>/dav/<orgSlug>/documents/`. <Tabs> <Tab title="macOS Finder"> Drücke **⌘K** (Mit Server verbinden), füge die URL ein und melde dich mit deiner E-Mail und dem App-Passwort an. Die Freigabe erscheint in der Seitenleiste; zieh Dateien hinein zum Hochladen, hinaus zum Herunterladen, und benenne um oder lösche direkt an Ort und Stelle. Das erste Auflisten eines großen Baums kann ein paar Sekunden dauern. </Tab> <Tab title="Windows"> Wähle in **Dieser PC** die Option **Netzlaufwerk verbinden**, füge die URL als Ordner ein und wähle **Verbindung mit anderen Anmeldeinformationen herstellen**. Windows deckelt WebDAV-Übertragungen standardmäßig bei 50 MB pro Datei — erhöhe `FileSizeLimitInBytes` unter dem Registrierungsschlüssel `WebClient\Parameters` und starte den WebClient-Dienst neu. Auf einem Nicht-Standard-HTTPS-Port setze `BasicAuthLevel` unter demselben Schlüssel auf `2`. </Tab> <Tab title="iOS Files"> Tippe auf das Dreipunkt-Menü, wähle **Mit Server verbinden** und gib dieselbe URL und dieselben Zugangsdaten ein. Die Dateien-App unterstützt Durchsuchen und Herunterladen; Bearbeiten an Ort und Stelle funktioniert für Formate mit einer iOS-App. </Tab> <Tab title="rclone"> ```bash rclone config create tale webdav \ url=https://<your-site>/dav/<orgSlug>/documents/ \ vendor=other \ user=<your-email> \ pass=$(rclone obscure '<app-password>') rclone copy ./local-folder tale: --progress ``` `vendor=other` ist richtig — Tales Server ist generisch, keine benannte Spielart, die rclone kennt. </Tab> </Tabs> ## Was das eingehängte Laufwerk kann Lese- und Schreibzugriffe spiegeln deine Berechtigungen im Dokumenten-Hub, Dateien, die du hochlädst, landen im Index und in der Suche wie direkte Uploads, und ihr Quellfeld steht auf `webdav` zum Filtern in Audit-Ansichten. Projekt-Dateien sind die Ausnahme: Der **Wissen**-Tab eines Projekts ist auf dieses eine Projekt begrenzt und taucht nie über WebDAV auf, das eingehängte Laufwerk zeigt also nur den org-weiten Dokumenten-Hub. Der Namensraum `.trash/` listet weich gelöschte Dokumente schreibgeschützt — lade zur Wiederherstellung herunter, stelle über die UI wieder her. Editoren, die WebDAV-Locks nehmen (Office, LibreOffice), bekommen sie; ein konkurrierender Schreibzugriff während einer Bearbeitung erhält `423 Locked`. ## Widerrufen Widerrufe ein Passwort mit dem Papierkorb-Symbol auf seiner Zeile — die nächste Anfrage damit wird abgewiesen, andere Geräte bleiben unberührt, und alle Locks, die es hielt, werden freigegeben. Es gibt kein Zurück; präge ein neues Passwort, wenn du die falsche Zeile widerrufst. <Warning> Basic Auth sendet das App-Passwort mit jeder Anfrage. Hänge nur über HTTPS ein, lass das Passwort im Schlüsselbund des Betriebssystems und füge es nie in eine URL der Form `https://user:pass@host/` ein — Shell-Verlauf und Proxy-Logs überleben das Laufwerk. Widerrufe sofort bei jedem Verdacht auf ein Leck. </Warning> ## Wo das hingehört WebDAV ist die gerätezugewandte Tür pro Nutzer zu denselben Daten wie der [Dokumenten-Hub](/de/platform/knowledge/documents); das Drahtprotokoll steht unter [WebDAV-API](/de/develop/webdav-api). Für Maschine-zu-Maschine-Importe sind [API-Schlüssel](/de/platform/admin/api-keys) plus die REST-API meist die bessere Wahl. # Connectors Source: https://tale.dev/docs/de/platform/connectors/overview Eine Connector besteht aus zwei Teilen: einem **Connector**, der mit der Plattform ausgeliefert wird, und den **Zugangsdaten**, die deine Organisation dazu hinterlegt. Der Connector bringt das Wissen über den Anbieter mit — welche Aktionen es gibt, was jede davon entgegennimmt und zurückgibt, wie die Anmeldung läuft — und sieht in jeder Organisation gleich aus. Die Zugangsdaten gehören dir, und ein Connector hält davon so viele, wie du brauchst: einen Eintrag pro Workspace, Shop, Postfach oder Bot. Dreizehn Connectoren werden ausgeliefert, und jeder davon steht bereits unter **Einstellungen > Connectors** und wartet auf seinen ersten Eintrag. Lieber erst zusehen? Episode 7 geht die Türen zur Außenwelt ab — Connectoren, MCP und die Grenzen — in knapp drei Minuten, mit Untertiteln. <Video src="/videos/de/tutorials/ep7-connectors/ep7-connectors.de.mp4" poster="/videos/de/tutorials/ep7-connectors/ep7-connectors.de.webp" captions="/videos/de/tutorials/ep7-connectors/ep7-connectors.de.vtt" lang="de" title="Episode 7 — Connectors & die Außenwelt" caption="Episode 7 — Connectors & die Außenwelt (2:52)"> </Video> ## Was ein Connector ist Es gibt nichts zu installieren. Jeder Connector kommt mit der Plattform, deshalb sieht der Katalog in jeder Organisation gleich aus und deshalb hält ein Upgrade ihn aktuell, ohne dass jemand ihn pflegt. Ein Connector ist eine Definition: ein Anzeigename mit einer Zeile Beschreibung, die Kategorien, zu denen er gehört, die Authentifizierungsmethoden, die er akzeptiert, und die Liste der Aktionen, die er beim Anbieter ausführen kann. Weil diese Definition für alle gilt, entscheidet deine Organisation nur eines: als welche Konten Tale handeln darf. Diese Entscheidung sind die Zugangsdaten, und mehr Einrichtung gibt es nicht. ## Die mitgelieferten Connectoren Dreizehn Connectoren werden ausgeliefert, jeder mit der Kategorie, zu der er gehört — Knowledge, Messaging, Email, Developer, Commerce, Search oder Files. **Anmeldung** ist die Authentifizierungsmethode, die der Connector akzeptiert; sie bestimmt, wonach das Formular fragt. **Aktionen** ist die Anzahl der Operationen, die er anbietet — dieselbe Zahl, die der Abschnitt des Connectors in den Einstellungen zeigt. | Connector | Was dir das Verbinden bringt | Anmeldung | Aktionen | | ----------------------- | -------------------------------------------------------------------------------------------------------------- | ----------------------- | -------- | | **Confluence** | Confluence-Cloud-Seiten in die Wissensdatenbank von Tale importieren. | Benutzername & Passwort | 2 | | **Discord** | Nachrichten posten und Kanäle im eigenen Discord-Server verwalten. | Token | 8 | | **GitHub** | Repositories, Issues und Pull Requests auf GitHub verwalten. | Token | 19 | | **Gmail** | E-Mails in Gmail lesen, senden und sortieren. | OAuth | 9 | | **Google Drive** | Dateien aus Google Drive in die Wissensdatenbank von Tale importieren. | OAuth | 2 | | **IMAP / SMTP Mailbox** | Einen eigenen IMAP- und SMTP-Mailserver an Conversations anbinden — ohne Gmail- oder Outlook-Konto. | Benutzername & Passwort | 2 | | **Microsoft Outlook** | Outlook-Mail, -Kalender und -Kontakte verwalten. | OAuth | 10 | | **Shopify** | Produkte, Kunden und Bestellungen aus dem eigenen Shopify-Shop abgleichen. | API-Schlüssel | 9 | | **Slack** | Nachrichten senden und mit Kanälen in Slack arbeiten. | OAuth | 7 | | **Tavily** | Websuche und Seitenextraktion in Echtzeit für KI-Recherche. | API-Schlüssel | 2 | | **Microsoft Teams** | Nachrichten senden und Kanäle in Microsoft Teams verwalten. | OAuth | 9 | | **Twilio** | SMS verschicken und Sprachanrufe über Twilio führen. | Benutzername & Passwort | 7 | | **WebDAV Files** | Dateien im WebDAV-Speicher der Organisation lesen, schreiben und auflisten — dieselben, die `/dav` ausliefert. | Benutzername & Passwort | 4 | Seiten und Dateien, die über Confluence oder Google Drive hereinkommen, laufen durch dieselbe Indexierung wie ein direkter Upload, und Antworten zitieren sie zurück auf die Quelle — siehe [Dokumente](/de/platform/knowledge/documents). Der WebDAV-Connector ist die Schreibseite desselben Speichers, den deine Geräte als Netzlaufwerk einbinden; das beschreibt [WebDAV](/de/platform/connectors/webdav). ## Zugangsdaten an einem Connector Ein Connector hält so viele Zugangsdaten, wie deine Organisation braucht. Ein Slack-Workspace pro Geschäftsbereich, ein Shopify-Shop pro Markt, ein Postfach pro Support-Warteschlange — jeder davon ist eine eigene Zeile unter dem Connector, mit eigenem Secret und eigenem Zustand. Genau das lässt eine gemeinsame Automations-Bibliothek mehrere Teams bedienen, ohne dass eines das Konto eines anderen mitbenutzt. Jeder Eintrag trägt vier Dinge: - **Name** — unter diesem Namen wählt eine Aktion diesen Eintrag aus. Schreib ihn für die Person, die in einem halben Jahr die Automation liest: `Support-Postfach`, `Shop EU`, `Release-Bot`. - **Authentifizierungsmethode** — **API-Schlüssel**, **Token**, **Benutzername & Passwort** oder **OAuth**, ausgewählt aus dem, was der Connector akzeptiert. - **Standard** — ein Eintrag pro Connector kann das sein. Ein Automations-Node oder eine Chat-Aktion ohne eigene Angabe nutzt ihn. - **Zustand** — ein Eintrag ist entweder im Einsatz oder **Deaktiviert**. Deaktivieren behält die Zeile samt Konfiguration, verhindert aber jeden Aufruf darüber. Ohne Standard funktioniert ein Connector weiterhin für alle Aufrufer, die einen Eintrag benennen — wer keinen benennt, hat jedoch nichts, worauf er zurückfallen kann. Der Abschnitt des Connectors sagt das, und die Lösung ist, einen der vorhandenen Einträge zum Standard zu machen. <Note> Confluence und Shopify haben keinen einheitlichen Anbieter-Host — die API liegt auf deiner eigenen Atlassian-Site oder in deinem eigenen `myshopify.com`-Shop. Beide fragen deshalb pro Eintrag nach einer **Instanz-URL**, und ihr Abschnitt trägt die Zeile _Jeder Eintrag nennt seine eigene Instanz._ Richte Confluence auf die Adresse, unter der du Confluence öffnest, und Shopify auf die Admin-Adresse des Shops statt auf die Storefront-Domain. </Note> ## Einen Connector verbinden Wo du anfängst, hängt davon ab, was der Connector akzeptiert. Connectoren mit Token oder Schlüssel öffnen ein Formular und nehmen das Secret direkt entgegen; OAuth-Connectoren schicken dich auf den Freigabe-Dialog des Anbieters und kommen mit einem fertig ausgefüllten Eintrag zurück. Beide Wege enden am selben Punkt — einer benannten Zeile unter dem Connector. <Steps> <Step title="Einstellungen > Connectors öffnen"> Jeder Connector hat einen Abschnitt, überschrieben mit Icon, Beschreibung, Kategorien und Aktionszahl. Nichts versteckt sich hinter einem Katalog-Dialog. </Step> <Step title="Zugangsdaten hinzufügen"> **Zugangsdaten hinzufügen** öffnet das Formular bei Connectoren, die einen Schlüssel, ein Token oder Benutzername und Passwort entgegennehmen. **Verbinden** startet bei OAuth-Connectoren den Freigabe-Flow des Anbieters und legt danach eine neue Zeile an. </Step> <Step title="Benennen und zum Standard machen"> Gib dem Eintrag einen Namen, auf den deine Automationen zeigen können, und mache ihn zum Standard, wenn er greifen soll, sobald niemand einen Eintrag benennt. Die Aktionen des Connectors stehen Automationen und Chat zur Verfügung, sobald die Zeile existiert. </Step> </Steps> Die Details pro Methode — wonach jedes Formular fragt, wie du ein Secret ersetzt, was bei einer abgelaufenen Autorisierung passiert — stehen unter [Zugangsdaten für Connectors](/de/platform/admin/connectors). ## Aktionen in Automationen und im Chat Jede Aktion, die ein Connector deklariert, hat einen Namen, eine Beschreibung, ein Eingabe-Schema, eine Ausgabe-Signatur und einen deklarierten Effekt: `read` oder `write`. Automationen setzen eine Aktion als Node in den Workflow-Editor; im Chat erreichen Agents dieselben Aktionen als Tools. In beiden Fällen löst der Aufruf zuerst die Zugangsdaten auf — den benannten Eintrag oder den Standard des Connectors — und scheitert mit klarer Meldung, wenn es beides nicht gibt. <Warning> Schreibende Aktionen verändern etwas im anderen System: eine gepostete Nachricht, ein angelegtes Issue, eine verschickte SMS. Solche Aufrufe laufen über die Genehmigungsrichtlinie deiner Organisation, der Agent schlägt den Aufruf also vor und eine Person gibt ihn frei. Lies [Genehmigungen konfigurieren](/de/platform/approvals/configure), bevor du einen Agent darauf ansetzt. </Warning> ## Wenn kein Connector passt Dreizehn Connectoren decken die Systeme ab, zu denen die meisten Teams greifen — und sie decken keine interne API ab, kein selbstgebautes Tool und keinen Anbieter, für den niemand einen Connector geschrieben hat. Dafür gibt es MCP: du betreibst einen Server, Tale registriert ihn, und seine Tools reihen sich neben den Connector-Aktionen in den Werkzeugkasten des Agents ein. Die Brücke ist dann dein Code statt einer mitgelieferten Definition — genau das ist der Handel: mehr Freiheit, mehr Wartung. Registriert wird ein solcher Server unter **Einstellungen > API > MCP**, beschrieben in [MCP-Server](/de/platform/connectors/mcp-servers). ## Wo das hingehört Connectoren sind der Weg, auf dem Tale die Systeme erreicht, in denen deine Arbeit ohnehin stattfindet; Zugangsdaten sind die Entscheidung darüber, als welche Konten Tale dabei handelt. Von hier aus zeigt [Zugangsdaten für Connectors](/de/platform/admin/connectors) die Betriebsseite — Einträge anlegen, ersetzen, deaktivieren und neu verbinden. [Agent-Tools](/de/platform/agents/tools) zeigt, wie die Aktionen eines Connectors im Werkzeugkasten eines Agents ankommen, [Genehmigungen konfigurieren](/de/platform/approvals/configure) hält die schreibenden zurück, und [MCP-Server](/de/platform/connectors/mcp-servers) deckt ab, was der Katalog offen lässt. </content> </invoke> # Skill-Bibliothek Source: https://tale.dev/docs/de/platform/workspace/skills Ein Skill ist eine Anweisung, die du einmal schreibst und die danach jeder Agent lesen kann. Er liegt als kleines Bundle im Dateibaum deiner Organisation — eine `SKILL.md` mit der Anweisung im Body, dazu das Referenzmaterial, auf das sich diese Anweisung stützt. Unter **Einstellungen > Skills** legst du solche Bundles an, lädst sie hoch und pflegst sie. Jedes Mitglied kann Skills erstellen; was du bearbeiten darfst, entscheidet sich pro Bundle. Diese Seite erklärt, was ein Skill ist, aus welcher Datei er besteht, wer ihn zu sehen bekommt und wie du einen anlegst und wieder aus dem Verkehr ziehst. Die Agent-Seite steht unter [Skills auf Agenten](/de/platform/agents/skills) — lies sie, sobald ein bestimmter Agent nach einem bestimmten Bundle greifen soll. ## Was ein Skill ist und was nicht Ein Skill ist ein **Wissenspaket**. Sein Body ist eine Anweisung, die ein Modell liest, wenn die Arbeit danach verlangt: eine Hausstimme fürs Schreiben, eine Checkliste deines Teams, die Art, wie deine Organisation eine Absage formuliert. Ein Modell findet das Bundle über seine Beschreibung, liest den Body, wenn diese Beschreibung zur Aufgabe passt, und öffnet einzelne Bundle-Dateien, wenn der Body auf sie verweist. Ein Skill ist nie etwas, das die Plattform ausführt. Ein Bundle hat keinen Einstiegspunkt, kein Kommando und keine Laufzeit — eine Datei unter `scripts/` ist Material, das ein Modell lesen und anpassen darf, kein Programm, das Tale für dich startet. Genau diese Grenze macht ein Bundle von außen annehmbar: Wer den Skill einer anderen Person importiert, holt sich Prosa und Referenzdateien ins Haus — und nichts, das von allein handeln kann. ## Die Datei SKILL.md Jedes Bundle hat genau eine `SKILL.md` an seiner Wurzel — ein YAML-Frontmatter, dann der Anweisungs-Body in Markdown. ```markdown --- name: release-notes description: Verwandle eine Liste gemergter Änderungen in Release Notes in unserer Hausstimme. Nutze das, wenn jemand nach einem Changelog, Release Notes oder einer Zusammenfassung fragt. visibility: team teams: - jx7d… license: CC-BY-4.0 --- Schreibe Release Notes als drei Abschnitte — Added, Changed, Fixed — und beginne jede Zeile mit dem Verb... ``` Die Schlüssel folgen der agentskills.io-Konvention in Kebab-Case, und jeden Schlüssel, den Tale nicht kennt, bewahrt es unverändert — ein Bundle, das für ein anderes Tool geschrieben wurde, übersteht Bearbeiten und Speichern unversehrt. | Schlüssel | Was er trägt | | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `name` | Der Slug, der dem Ordnernamen des Bundles entsprechen muss — Kleinbuchstaben, Ziffern und einzelne Bindestriche, höchstens 64 Zeichen. `anthropic` und `claude` sind reserviert. | | `description` | Bis zu 1024 Zeichen — das Feld, das entscheidet, ob ein Modell überhaupt zum Skill greift. Sag, was er tut und wann er passt. | | `visibility` | `team` oder `org`. Fehlt der Eintrag, gilt `org`. `private` ist ausgemustert — ein Bundle, das es schon trägt, wird weiter gelesen, aber kein neuer Skill bekommt es. | | `teams` | Die Team-IDs, mit denen ein `team`-Skill geteilt ist — dort Pflicht, sonst abgelehnt. Die Sichtbarkeits-Auswahl der Bibliothek füllt das Feld für dich. | | `owner` | Das Mitglied, dem das Bundle gehört — bei einem geteilten Skill reine Zuschreibung, bei einem alten `private`-Skill Pflicht. | | `license` | Freitext, für ein Bundle, das du importiert hast oder weitergeben willst. | | `recommended-packages` | Python- oder Node-Pakete, die der Autor empfiehlt. Nur ein Hinweis — Tale installiert nie etwas im Namen eines Skills. | | `disable-model-invocation` | Auf `true` gesetzt, darf ein Modell nicht von sich aus zum Skill greifen. Für einen expliziten Abruf bleibt er verfügbar. | | `icon` und `labels` | Eine Iconify-ID und bis zu acht Chips für die Karte des Skills in der Bibliothek. | Zwei Obergrenzen gelten: Das Frontmatter darf 16 KB erreichen, die ganze `SKILL.md` 512 KB. Bundle-Assets zählen nicht in dieses Budget. ## Wer ihn sieht Freigabe ist ein Feld, keine Berechtigungstabelle. `visibility: team` teilt das Bundle mit den Teams unter `teams`; du wählst sie im Abschnitt **Sichtbarkeit** der Bibliothek. `visibility: org` heißt: Jedes Mitglied sieht ihn, und die Agenten jedes Projekts können ihn ausrüsten. Jedes Mitglied darf einen Skill team- oder organisationsweit teilen; den geteilten Skill einer anderen Person bearbeitet oder löscht nur ein Org-Admin. Ein Bundle ganz ohne `visibility` — auch eines, das du hochlädst — zählt als Organisations-Skill, und die Upload-Vorschau sagt dir das, bevor du bestätigst. <Note> `visibility: private` ist ausgemustert. Agenten sind die einzige Oberfläche, die Skills ausrüstet, und die Agenten eines Projekts sehen nie das private Bundle eines einzelnen Mitglieds — ein privater Skill wäre also nur für dich sichtbar und nirgends nutzbar. Ein Bundle, das den Eintrag schon trägt, funktioniert für seinen Inhaber weiter (selbst ein Admin liest es nicht), und der Inhaber kann die Freigabe jederzeit erweitern; neue Skills und Uploads, die `private` deklarieren, werden abgelehnt. </Note> Schränkst du die Freigabe eines Skills ein — von Organisation auf Team, oder ein Team fällt weg — bestätigst du das zuerst: Wer den Skill aus dem Blick verliert, verliert ihn auch in jedem Agenten, der ihn über diese Person ausgerüstet hat. ## Einen Skill anlegen Öffne **Einstellungen > Skills**. Die Seite ist eine Tabelle aller Skills, die du sehen darfst — Name, Beschreibung, Sichtbarkeit und Labels — mit einer Suche über Name, Beschreibung und Labels und Filtern für Sichtbarkeit und Label. Ein Klick auf eine Zeile öffnet das Bundle. **Skill hinzufügen** bietet drei Startpunkte. <Steps> <Step title="Leer starten"> **Leerer Skill** fragt nach einem Namen — dem Slug aus Kleinbuchstaben, Ziffern und einzelnen Bindestrichen — dazu Beschreibung und Freigabe, und einem Anweisungs-Body, den du direkt schreibst. Neue Skills starten organisationsweit geteilt; grenze die Freigabe auf Teams ein, wo das Wissen ihnen gehört. </Step> <Step title="Oder ein Bundle hochladen"> **Zip hochladen** nimmt ein `.zip` mit `SKILL.md` an der Wurzel, daneben Ordner wie `scripts/`, `references/` oder `assets/`; **Ordner hochladen** nimmt den Ordner selbst und zippt ihn für dich. In beiden Fällen liest Tale das Frontmatter, bevor irgendetwas geschrieben wird, und zeigt dir den Fund — die Beschreibung, die Freigabe, mit der das Bundle landet, die Lizenz und die vollständige Dateiliste mit Größen. Du bestätigst also ein Bundle, das du wirklich gesehen hast. Existiert der Slug schon, fragt Tale zuerst, ob du ersetzen willst. </Step> <Step title="Den Body schreiben"> Öffne den Skill und schreibe die Anweisung unter **Anweisungen (Body)**. Diesen Text liest das Modell — schreib ihn so, wie du eine Kollegin briefen würdest: wofür der Skill da ist, wann er gilt und wie ein gutes Ergebnis aussieht. </Step> </Steps> ## Was im Bundle liegt Die Detailansicht eines Skills zeigt **Bundle** — den Dateibaum, wie er auf der Festplatte liegt — mit einem Viewer für jede Datei, die du anklickst. Der kleinste nützliche Skill ist eine einzelne Datei; die meisten wachsen Ordner für Ordner. ```text release-notes/ ├── SKILL.md ├── references/ │ └── voice-and-tone.md └── scripts/ └── group-changes.py ``` Halte die Assets klein und lesbar. Text, den ein Modell günstig öffnen kann, wird genutzt; ein großes Binary bleibt ungelesen liegen, und der Viewer sagt offen, dass er es nicht anzeigen kann. ## Einen Skill ausmustern **Skill löschen** in der Detailansicht entfernt das Bundle von der Festplatte; jeder Agent, der es ausgerüstet hat, verliert den Zugriff — ersatzlos. Versionen lassen sich nicht festnageln: Ein Skill wird immer genau so gelesen, wie er jetzt dasteht. Genau das macht ihn wertvoll — eine Änderung erreicht alle, die ihn halten. ## Wo das hingehört Die Skill-Bibliothek ist die leichteste Wiederverwendung, die Tale bietet: eine Datei, ein Feld für die Freigabe, nichts, das du über mehrere Köpfe hinweg synchron halten musst. Hier hört eine Formulierung, die du ständig neu tippst, auf, etwas zu sein, das du neu tippst. Liegt ein Bundle erst in der Bibliothek, bleibt die Frage, welche Agenten es bekommen — das ist [Skills auf Agenten](/de/platform/agents/skills): das Ausrüsten der Agenten eines Projekts und der Weg eines Bundles in die Sandbox. # Harnesses Source: https://tale.dev/docs/de/platform/agents/harnesses Ein **Harness** ist eine mitgelieferte Coding-CLI — Claude Code, Codex, Cursor und weitere —, die dein gewähltes Modell in einem isolierten Container ausführt statt in der gewöhnlichen Chat-Schleife. Das Harness plant, schreibt Dateien, führt Befehle aus, installiert Pakete und berichtet zurück. Im Chat-Composer wählst du kein Harness: Chat wählt nur ein **Modell**. Das Harness legst du fest, wenn du einen **Projekt-Agenten** oder einen Automation-**Agent**-Knoten anlegst — beide Oberflächen nennen das Feld **Agent-Laufzeit**. Diese Seite behandelt, welche Harnesses mit Tale kommen, wo du eines bindest, woher der Zugang stammt und was der Container erreichen darf und was nicht. Die Zugänge selbst sind Sache der Organisation — siehe [Provider](/de/platform/admin/providers). Unter **Einstellungen > Provider** zeigt der Tab **Harnesses**, wie jedes Harness für die Organisation aufgelöst würde. ## Wo du ein Harness wählst Öffne den Tab **Agenten** eines Projekts und leg einen Agenten an oder bearbeite einen. Der Dialog fragt nach einer **Agent-Laufzeit** — dem Harness, der Coding-CLI, auf der dieser Agent läuft — neben Modell, Ausrüstung und Anweisungen. Weist du diesem Agenten eine Board-Aufgabe zu, arbeitet er in einer Sandbox auf genau diesem Harness. In einer Automation trägt ein **Agent**-Knoten dasselbe Feld **Agent-Laufzeit**. Erreicht der Workflow diesen Knoten, läuft der Zug auf dem gewählten Harness. Chat listet keine Harnesses. Die Auswahl im Composer ist nur Modelle; Harness-Arbeit kommt über einen Projekt-Agenten oder einen Automation-Agent-Knoten, nicht über eine Composer-Gruppe. ## Was ein Harness-Zug ist Beschreib die Aufgabe in normaler Sprache — „schreib ein kleines Python-CLI und teste es", „klon dieses Repository und behebe den Fehler aus Issue 42". Die Nachricht geht an das Harness und nicht direkt an das Modell. Das Harness treibt das Modell in einer Schleife im Container an und entscheidet selbst, wann es eine Datei liest, einen Befehl ausführt oder es noch einmal versucht; die Antwort kommt, wenn sein Zug abgeschlossen ist. Daraus folgen zwei Dinge. Die Arbeit ist echt und nicht beschrieben: Dateien existieren, Befehle sind tatsächlich gelaufen, und ihre Ausgabe ist das, worüber das Modell nachgedacht hat. Und die Form des Zuges gehört dem Harness, nicht Tale — ein Harness mit Plan-Modus endet mit einem Vorschlag, den du prüfen kannst, eines für einzelne Durchläufe läuft schlicht durch. ## Die mitgelieferten Harnesses Neun Harnesses kommen mit der Plattform. Sie unterscheiden sich darin, wie sie einen Prompt entgegennehmen, ob sie sich mitten im Zug lenken lassen und ob sie MCP-Server erreichen. | Harness | Akzeptierte Zugänge | Wissenswertes | | ----------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | | Claude Code | Verwaltet oder dein eigener | Das leistungsfähigste: mitten im Zug lenkbar, mit einem Plan-Modus, der in einem prüfbaren Vorschlag endet. Erreicht MCP-Server. | | Codex | Verwaltet oder dein eigener | Einzelne Durchläufe. Erreicht MCP-Server. | | Cursor | Nur dein eigener | Einzelne Durchläufe. Sein CLI kann nicht über das Gateway der Plattform laufen, ein verwalteter Zugang wird also abgelehnt. | | Gemini CLI | Verwaltet oder dein eigener | Einzelne Durchläufe. Erreicht MCP-Server. | | Hermes | Verwaltet oder dein eigener | Einzelne Durchläufe, ohne MCP-Kanal. | | OpenClaw | Verwaltet oder dein eigener | Einzelne Durchläufe. Erreicht MCP-Server. | | OpenCode | Nur verwaltet | Einzelne Durchläufe. Erreicht MCP-Server. Läuft über das Gateway, ein eigener Schlüssel wird abgelehnt. | | Pi | Verwaltet oder dein eigener | Einzelne Durchläufe, ohne MCP-Kanal. | | Qwen Code | Verwaltet oder dein eigener | Einzelne Durchläufe. Erreicht MCP-Server. | In der Praxis macht sich der Unterschied beim Lenken bemerkbar. Bei Claude Code erreicht eine Korrektur, die du während des laufenden Zuges schickst, den Agenten an seiner nächsten Tool-Grenze — „nimm pnpm, nicht npm" landet also, während die Arbeit noch läuft. Jedes andere Harness nimmt eine wartende Nachricht erst an der Zuggrenze auf. ## Woher der Zugang stammt Der Zugang gehört der Organisation, nicht dem Agenten. Ein Agent hält keine eigenen Schlüssel, und es gibt keinen Zugangs-Tab pro Agent; womit sich ein Zug ausweist, ergibt sich aus dem Provider-Zugang hinter dem Modell, das du gewählt hast, eingerichtet unter [Provider](/de/platform/admin/providers). Welche von zwei Haltungen ein Zug einnimmt, folgt daraus, welche Art von Zugang das ist. **Ein hinterlegter API-Schlüssel oder einer aus einer Umgebungsvariable der Installation** bleibt bei der Plattform. Tale erzeugt für den Zug einen auf die Sitzung begrenzten Gateway-Schlüssel, und das Harness weist sich damit aus statt mit dem echten Geheimnis — der Container hält also nie einen Zugang, der die Sitzung überdauert. Das ist die verwaltete Haltung, und das einzige Harness, das sie ablehnt, ist Cursor. **Ein Vendor-Abonnement** — ein Coding-Plan-Schlüssel, ein Portal-Schlüssel, ein OAuth-Blob oder ein Pool rotierender Tokens von einem Broker — funktioniert anders, weil Anbieter solche Zugänge nur für ihr eigenes Agenten-Werkzeug freigeben. Ein Abo-Zugang zwingt den Zug deshalb auf genau ein Harness: Ein gewöhnlicher Chat-Zug wird mit einer Begründung abgelehnt, die dieses Harness benennt, und ein anderes Harness ebenso. Das Geheimnis wird in die Umgebung der Sitzung gelegt, also in der Bring-your-own-Haltung, und das erzwungene Harness muss sie annehmen — OpenCode läuft nur über das Gateway und lehnt ab. <Note> Ein Harness-Zug benennt immer ein konkretes Harness. Nichts rät eines für dich: Der einzige Fall, in dem eines von selbst kommt, ist der Abo-Zugang, der seine erzwungene Wahl mitbringt. </Note> ## Was die Sandbox erreicht Der Container startet mit leerem Arbeitsverzeichnis und ist standardmäßig abgeriegelt. Dateien und Ordner, die du mit `@` anheftest, fahren unter `/user/uploads/` in die Sitzung mit, der Agent öffnet also die echten Bytes statt eines Such-Schnipsels, und was er unter `/user/output/` schreibt, kommt als Datei in den Chat zurück. Ausgehender Netzwerkverkehr ist bis auf eine schmale Freigabeliste gesperrt — Paketregister und GitHub —, der Agent kann also installieren, was er braucht, und ein öffentliches Repository klonen, ohne beliebige Hosts zu erreichen. Angebundene Connectors erreichen den Agenten über einen Broker statt über die Box. Ruft der Agent eine auf, geht die Anfrage zurück an Tale, das sie mit dem hinterlegten Zugang ausführt und nur das Ergebnis zurückgibt — ein kompromittierter Container kann deine Schlüssel also nicht lesen. Ein Schreibvorgang erscheint als Freigabekarte im Chat und läuft weiter, sobald du zustimmst. GitHub ist die bewusste Ausnahme: `git` und das `gh`-CLI brauchen lokal ein Token; ein Zug läuft also mit einem eingeschränkten, solange die Unterhaltung den GitHub-Connector ausgerüstet hat — es kommt pro Zug hinein und verschwindet mit dessen Ende. An den Agenten gebundene Skills werden als Dateien in die Sitzung gelegt statt über ein Tool geholt, und ein Skill, den das ausgecheckte Repository mitbringt, gewinnt gegen die Kopie, die Tale legen würde — die Vorrangregel steht unter [Agent-Skills](/de/platform/agents/skills). Auch deine eigenen [Umgebungsvariablen und Geheimnisse](/de/platform/member/environment) werden im Container gesetzt; so kommt ein persönliches Token oder ein eigener Endpunkt zur Arbeit, ohne dass die Sitzung einer anderen Person es sieht. ## Kosten und Messung Ein Harness-Zug kann lang sein und das Modell viele Male aufrufen, er kostet also mehr als eine einzelne Chat-Antwort. Verwaltete Züge laufen über das Gateway, und genau das macht sie messbar: Sie landen in der [Nutzungsanalyse](/de/platform/admin/governance/usage-analytics) neben jedem anderen Zug, und die [Richtlinien und Limits](/de/platform/admin/governance/policies-and-limits) der Organisation deckeln, was sie ausgeben dürfen. Züge auf einem Abo-Zugang umgehen das Gateway von Bauart her, weil das Geheimnis in den Container geht und das Werkzeug des Anbieters direkt mit ihm spricht. Diese Züge werden nicht gemessen, und die Ausgabendeckel der Organisation greifen nicht — die Abrechnung liegt bei dem, dem das Abonnement gehört. ## Wo das hingehört Ein Harness macht aus einem Projekt-Agenten oder einem Automation-Agent-Knoten eine laufende Sitzung mit einem Coding-Werkzeug in einem isolierten Container: Du steuerst in normaler Sprache, es arbeitet an echten Dateien, und das Harness bestimmt den Takt des Zuges. Chat wählt nur Modelle; das Feld **Harness** sitzt am Agenten oder am Automation-Knoten. Wie viel davon unter der Kontrolle der Organisation bleibt, entscheidet der Zugang — ein hinterlegter Schlüssel hält den Zug am Gateway, unter den Deckeln und in der Messung, während ein Vendor-Abonnement ihn in die Box und auf das Konto dieses Anbieters schiebt. Lies diese Seite zusammen mit [Provider](/de/platform/admin/providers) für die Zugangsseite und [Connectors](/de/platform/connectors/overview) für das, was der Agent im Betrieb erreichen kann. # Agent-Worker Source: https://tale.dev/docs/de/platform/agents/delegation Einen Worker startest du, wenn eine Aufgabe ihren eigenen fokussierten Kontext verdient: offene Recherche, Massen-Extraktion, ein langer Entwurf. Der Agent, mit dem du chattest, stellt bei Bedarf einen **Worker** zusammen — Name, Aufgabenanweisungen, optional eine Arbeitsmethode und eine Tool-Auswahl — lässt ihn laufen und faltet das Ergebnis in seine Antwort zurück. Worker sind flüchtig: Sie existieren für genau einen Job, und ihr Lauf erscheint als **Job-Karte** im Chat. Diese Seite gibt dir das Denkmodell, wann ein Worker die richtige Form ist und wie die Plattform ihn begrenzt hält. Der End-to-End-Durchlauf steht in [Arbeit an einen Worker geben](/tutorials/editor/delegate-between-agents). ## Wie ein Job läuft Ruft der Agent **spawn_agent** auf, löst Tale die Fähigkeiten des Workers auf, startet eine frische Kind-Konversation und lässt den Worker nicht-interaktiv laufen: Er sieht nur die Aufgabe, die der Agent geschickt hat (nicht den ganzen Chat-Verlauf), verfolgt seinen Fortschritt auf einer live sichtbaren Checkliste, und seine letzte Nachricht geht als Ergebnis an den Agenten zurück. Der Chat zeigt eine Job-Karte mit Name, Live-Fortschritt, Endstatus und einem aufklappbaren Protokoll von allem, was der Worker getan hat. Worker sprechen nie mit dir. Braucht ein Worker eine Eingabe, die nur ein Mensch geben kann, sagt er das in seinem Ergebnis, und der Agent fragt dich — Fragen kommen immer von dem Agenten, mit dem du tatsächlich sprichst. ## Fähigkeiten sind immer eine Teilmenge Ein Worker kann höchstens halten, was der startende Agent selbst hält. Drei Ebenen bestimmen die wirksame Auswahl: - **Org-Konfiguration** — die Tools, Skills und Connectors des Agenten, wie von deinen Admins konfiguriert. Pro Worker gibt es nichts zu pflegen. - **Die Job-Auswahl** — der Agent wählt für diese Aufgabe die kleinste Menge aus seinen eigenen Fähigkeiten (weniger Tools = ein fokussierterer Worker). - **Plattform-Ausnahmen** — einige Tools wandern nie mit, allen voran das Nutzer-Frage-Tool: Die Fragen eines Workers laufen über den Agenten, damit eine Antwort nie ins Leere führt. Worker können auch keine Worker starten. Eine Ausnahme läuft in die Gegenrichtung: Die Dateien des Threads (Uploads, erzeugte Ergebnisse) kann jeder Worker immer auflisten und lesen — Dateien schreiben oder Code ausführen bleibt eine ausdrückliche Auswahl. Alles außerhalb dieser Grenzen wird still übersprungen und gemeldet — die Job-Karte zeigt, was weggeschnitten wurde, und der Agent passt sich an (sagt dir zum Beispiel, dass eine Connector verbunden werden muss). ## Arbeitsmethoden Für offene Aufgaben kann der Agent einen **Methodik-Skill** als Arbeitsmethode mitgeben — `web-research` ist eingebaut: Live-Planung auf der Checkliste, Suchbudgets pro Frage und ein zitiertes Ergebnis. Methodiken sind Skills; deine Admins steuern sie wie jeden anderen Skill. ## Grenzen und Verbrauch Ein Worker läuft im Zug, der ihn gestartet hat, und kann ihn nicht überdauern; ist die Obergrenze erreicht, endet der Job, und sein Teilfortschritt bleibt auf der Karte sichtbar. Diese Grenze gehört dem Host, der den Zug ausführt, nicht dem Agenten, der keine eigene Frist trägt. Token-Verbrauch rollt zum startenden Agenten hoch, und Ausgabengrenzen greifen für die Organisation als Ganzes statt pro Agent, die Kosten eines Jobs landen also beim übrigen Verbrauch der Organisation. Admins begrenzen, wie viele Jobs gleichzeitig laufen dürfen, über **Governance → agent_jobs** (Standard 10). ## Wann du danach greifst | Nimm … wenn | Worker | Einzelner Agent | Workflow | | -------------------------------------------------------- | ------ | --------------- | -------- | | Eine Teilaufgabe von einem isolierten Kontext profitiert | ✓ | | | | Der Agent inline gut antworten kann | | ✓ | | | Arbeit feste Stufen mit Freigaben dazwischen hat | | | ✓ | Die Kosten eines Workers sind ein zusätzlicher Lauf; der Gewinn ist ein sauberer Kontext mit genau den richtigen Fähigkeiten für die Teilaufgabe — und eine Job-Karte, die zeigt, was passiert ist. Sind die Stufen fest und willst du Freigaben oder Zeitpläne dazwischen, ist ein Workflow die richtige Form. # Skills auf Agenten Source: https://tale.dev/docs/de/platform/agents/skills Ein Agent kommt an einen Skill nur heran, wenn er ausgerüstet ist — und ausgerüstet wird aus der [Skill-Bibliothek](/de/platform/workspace/skills) der Organisation. Diese Seite handelt von den Oberflächen, die daraus wählen: den Agenten eines Projekts und den Agent-Knoten einer Automation. Eine Regel entscheidet, was sie wählen dürfen: **Es zählt die Sichtbarkeit des Projekts selbst, nie die des Mitglieds, das konfiguriert.** ## Was Ausrüsten entscheidet Ein ausgerüsteter Skill wird dem Modell über seine Beschreibung angeboten. Hält das Modell diese Beschreibung für relevant für deine Anfrage, liest es den Body der `SKILL.md` und öffnet einzelne Bundle-Dateien, wo der Body auf sie verweist. Nichts wird ausgeführt, nichts vorab eingefügt — ein Skill kostet nur in den Zügen Kontext, in denen das Modell wirklich zu ihm greift. Ein Bundle mit `disable-model-invocation: true` im Frontmatter verhält sich anders: Es bleibt ausgerüstet und lesbar, aber das Modell darf nicht ungefragt danach greifen; es wartet auf einen Zug, in dem es jemand beim Namen nennt. ## Die Agenten eines Projekts ausrüsten Ein [Projekt-Agent](/de/platform/agents/create) trägt seine eigene Ausrüstung, gewählt im Ausrüstungsmenü im Dialog des Agenten. Die Liste dort folgt der Sichtbarkeit des **Projekts**, nicht deiner: organisationsweite Skills plus Team-Skills, die mit einem der Teams des Projekts geteilt sind. Ein organisationsweites Projekt sieht nur Organisations-Skills, und niemandes alte private Skills tauchen auf — ein Projekt-Agent läuft für jedes Mitglied des Projekts, seine Ausrüstung darf also nie etwas einschmuggeln, das nur seine Autorin sehen könnte. Dieselbe Regel gilt zur Laufzeit. Ein Task-Lauf lädt die Skills des Agenten als das Projekt; eine Automation auf Organisationsebene als die Organisation. Ein Skill, der für diese Sicht unsichtbar wird, lässt den Lauf mit seinem Namen fehlschlagen, statt still ohne ihn zu laufen — bewusst gewählte Ausrüstung, die stumm fehlt, ist schlimmer als ein fehlgeschlagener Lauf. ## Skills in einer Sandbox-Sitzung Läuft ein Zug in einer Sandbox, kommen ausgerüstete Bundles nicht über einen Tool-Aufruf an. Sie werden als Dateien in die Sitzung geladen, im Layout, das die Laufzeit ohnehin kennt — das Harness findet sie so, wie es einen Skill auf jeder Maschine fände, auf der es arbeitet. Für Kollisionen gilt eine Regel: Das Repository gewinnt. Liefert das ausgecheckte Repository einen Skill unter demselben Slug wie einer, den Tale laden würde, hält Tale seine Kopie zurück, und die Version des Repositories steht. Ein Repository kann immer überschreiben, was die Plattform dem Agenten sonst beibringen würde, und die Sitzung hält nie zwei Bundles mit demselben Namen. ## Skill oder Instruktionen | Nimm … wenn | Skill | Agent-Instruktionen | | ----------------------------------------------------------- | ----- | ------------------- | | Das Muster wiederholt sich über mehrere Agenten | ✓ | | | Das Verhalten braucht Referenzdateien neben der Prosa | ✓ | | | Das Verhalten ist die Stimme genau dieses einen Agenten | | ✓ | | Eine Änderung soll alle erreichen, die das Verhalten nutzen | ✓ | | | Die Instruktionen des Agenten passen noch auf einen Schirm | | ✓ | Instruktionen sind die richtige Form für den eigenen Charakter eines Agenten. Ein Skill ist die richtige Form, sobald dasselbe Verhalten beim zweiten und dritten Agenten auftaucht und es dich etwas kostet, ihre Instruktionen im Gleichschritt zu halten. ## Wo das hingehört Ausrüsten ist die schmale Hälfte der Skills: Die Bibliothek entscheidet, was existiert und wer es sieht; der Agenten-Dialog eines Projekts und die Agent-Knoten einer Automation entscheiden, wo es genutzt wird — immer durch die Sichtbarkeit des Projekts oder der Organisation selbst. Halte Ausrüstungslisten kurz, ersetze ein Bundle lieber, statt es zu klonen, und lass ein Repository überschreiben, was die Plattform laden würde, wenn ein Agent in einem arbeitet. Die andere Hälfte der Geschichte — eine `SKILL.md` schreiben, einen Ordner hochladen, ein Bundle teilen — ist die [Skill-Bibliothek](/de/platform/workspace/skills). # Einen Agent erstellen Source: https://tale.dev/docs/de/platform/agents/create Diese Anleitung führt vom leeren Dialog zu einem Agenten, den deine Kolleginnen auswählen können. Am Ende steht eine Persona, die ihre Domäne kennt, die Tools hat, um mit dem Gelesenen etwas anzufangen, und aus jedem Chat deiner Organisation erreichbar ist. Rechne mit rund fünfzehn Minuten. Als durchgehendes Beispiel dient ein Agent für die Support-Triage — derselbe, den [Agent-Konzepte](/de/platform/agents/concepts) einführt. Setz ruhig deine eigene Domäne ein; keiner der Schritte hängt am Beispiel. ## Bevor du anfängst Zwei Dinge sollten stehen: - Deine Organisation hat mindestens einen Provider-Zugang unter **Einstellungen > Provider**. Der Agent selbst nennt kein Modell — wer eine Nachricht abschickt, wählt es im Composer —, aber der Composer hat nichts anzubieten, solange kein Zugang existiert. In der Cloud ist einer voreingestellt; wer selbst hostet, folgt [Konfiguration → Provider](/de/self-hosted/configuration/providers). - Du hast hier mindestens die Rolle Editor. Unter [Mitglieder und Rollen](/de/platform/admin/members-and-roles) siehst du nach, falls du unsicher bist. ## Schritt 1 — Benennen und festlegen, wer ihn sieht Öffne **Agenten** in der Seitenleiste und lege einen neuen an. Der Dialog fragt nach einem **Namen** — der eindeutigen ID, die in Links und in der API auftaucht und sich später nicht mehr ändern lässt, also lieber sprechend und klein geschrieben, `support-triage` statt `agent2` — dazu nach einem **Anzeigenamen**, unter dem das Team ihm begegnet, und einer kurzen **Beschreibung**. Bestätige, und der Editor öffnet sich auf **Allgemein**. Auf **Allgemein** sitzt die Identität: Anzeigename, Beschreibung, ein Icon und die **Sichtbarkeit** des Agenten. Halte ihn privat, solange du noch an ihm formst, dann kommst nur du heran; gib ihn für die Organisation frei, und jedes Mitglied kann ihn im Composer auswählen. Ein privater Agent hält einen Besitzer fest, und das bist du — ein Agent, den niemand besitzt und niemand sieht, wäre für niemanden erreichbar. ## Schritt 2 — Die Anweisungen schreiben Öffne **Anweisungen**. Das Feld ist reines Markdown, begrenzt auf 20.000 Zeichen, und es wird jedem Zug vorangestellt, den der Agent beantwortet. Drei Ratschläge aus der Praxis: - **Fang mit der Stimme an.** Ein Absatz dazu, wer der Agent ist, wem er antwortet und welchen Ton er trifft. Das Modell wertet ihn als das stärkste Signal der ganzen Datei. - **Benenne die Ablehnungsfälle ausdrücklich.** Drei, vier Sätze dazu, was der Agent nicht tut und was er sagt, wenn er ablehnt. - **Widersteh der Lust, jedes Verhalten festzuschreiben.** Lange Anweisungen verwässern in langen Gesprächen. Gehört ein Verhalten in Code, nimm ein Tool; gehört es in Dokumente, nimm den Wissensbereich; wiederholt es sich über Agenten hinweg, nimm einen Skill. Die Anweisungen lassen sich wie Anzeigename und Beschreibung pro Sprache übersetzen — eine französische Leserin bekommt so einen auf Französisch gebrieften Agenten und nicht ein englisches Briefing, das auf Französisch antwortet. ## Schritt 3 — Tools und Skills gewähren Wechsle auf **Tools**. Tools sind einzelne Schalter, gebündelt in Kategorie-Karten — Kontakte, Produkte, Dateien, Wissen, Automatisierungen und mehr —, und jeder gewährte Schalter erweitert, was der Agent in deinem Namen lesen oder ändern darf. Gewähre das kleinste Set, das die Aufgabe erledigt, und lass den Rest aus. Angebundene Connectors und die Automatisierungen der Organisation stehen in derselben Liste, das Binden ist also derselbe Handgriff wie das Gewähren eines Plattform-Tools. <Frame caption="Der Tool-Katalog — eine Karte pro Kategorie, jede mit der Zahl der Tools, die der Agent gewährt bekommen hat."> ![Der Tools-Tab des Agenten-Editors, gescrollt zu den Kategorie-Karten, mit Wissen bei drei von vier angehakten Tools und Dateien bei sieben von sieben, während Konversationen, Diskussionen, Analysen und Aufgaben & Projekte nichts gewährt bekommen haben.](/images/platform/agent-editor-tools.webp) </Frame> <Note> **Code ausführen** startet Skripte in einer Sandbox und untersteht der [Run-Code-Policy](/de/platform/admin/governance/run-code-policy) der Organisation — der Schalter gewährt das Tool, die Policy entscheidet, was ein Lauf tatsächlich darf. </Note> Öffne danach **Skills** und binde die Bundles, die dieser Agent aufklappen können soll, höchstens zehn. Ein Skill ist ein Wissenspaket aus der [Skill-Bibliothek](/de/platform/workspace/skills) der Organisation: Bind hier das hauseigene Bundle für den Antwortton, und der Triage-Agent formuliert wie jeder andere Agent auch. Bleibt die Liste leer, klappt er nichts auf. ## Schritt 4 — Das Wissen eingrenzen Wechsle auf **Wissen**. Eine Einstellung entscheidet, welchen Bestand die Suche des Agenten lesen darf: die hochgeladenen **Dokumente** der Organisation, die für sie geholten **Web**-Seiten, **alles** davon zusammengeführt, oder **nichts**, womit der Agent gar keine Suche angeboten bekommt. Gesucht wird nur, wenn der Agent es für nötig hält — in eine Antwort rutscht nichts, wonach er nicht gefragt hat. Grenz ein, wo du kannst. Alles im Bereich konkurriert bei jeder Frage um Relevanz, und ein Agent, der auf die Dokumente zeigt, um die es geht, antwortet besser als einer, der auf alles zeigt, was die Organisation besitzt. ## Schritt 5 — Speichern und ausprobieren Klick auf **Speichern**. Öffne einen neuen Chat, wähle den Agenten, wähle im Composer ein Modell und schick eine Nachricht, die das Wissen und die Tools beansprucht, die du gewährt hast. Das Modell ist bei jedem Zug deine Wahl, derselbe Agent kann also eine billige Frage auf einem kleinen und eine harte auf einem großen Modell beantworten, ohne dass du etwas änderst. Antwortet er so, wie du ihn geschrieben hast, bist du fertig. Wenn nicht, liegen unter **Verlauf** oben rechts im Editor alle gespeicherten Fassungen zum Vergleichen und Zurückholen — siehe [Agent-Versionen](/de/platform/agents/versions). ## Fehlersuche - **Der Agent taucht in der Chat-Auswahl nicht auf.** Seine Sichtbarkeit steht noch auf privat, also siehst nur du ihn. Gib ihn auf dem Tab **Allgemein** für die Organisation frei. - **Antworten ignorieren das Wissen.** Der Wissensbereich steht womöglich auf nichts, oder das Dokument ist noch nicht indexiert — sieh es unter [Dokumente](/de/platform/knowledge/documents) nach. - **Ein gebundener Skill wird nie benutzt.** Ein Modell greift über die Beschreibung nach einem Skill, eine vage Beschreibung wird also übergangen; sag, was er tut und wann er passt. Ein Bundle mit `disable-model-invocation` wartet absichtlich darauf, benannt zu werden. - **Ein Tool-Aufruf wird zur Laufzeit abgelehnt.** Dann bremst eine Governance-Policy: Der Agent darf das Tool aufrufen, und die Laufzeit lehnt ab. Sieh unter [Richtlinien und Limits](/de/platform/admin/governance/policies-and-limits) nach. ## Wo das gebraucht wird Mit dem ersten eigenen Agenten fängt der Rest der Plattform an, sich nach Tale anzufühlen und nicht nach einem beliebigen Chatfenster. Du hast eine Persona geschrieben, ihre Grenzen mit zwei Erlaubnislisten und einem Wissensbereich gezogen und jede Frage nach dem Ablauf eines Zuges dem Gespräch überlassen. Der nächste sinnvolle Weg ist [Agent mit Wissen](/de/tutorials/editor/agent-with-knowledge) — dieselbe Form, aber mit einem gebundenen Dokumentenordner und der Belegkette von Anfang bis Ende. Wie ein Agent eine Teilaufgabe an einen Worker abgibt, zeigt [Arbeit an einen Worker geben](/de/tutorials/editor/delegate-between-agents). # Agent-Tools Source: https://tale.dev/docs/de/platform/agents/tools Tools sind das, was ein Agent über das Erzeugen von Text hinaus tun kann. Das Modell entscheidet, welches Tool es aus der Liste aufruft, die der Autor des Agents gewährt hat; Tale führt das Tool aus, reicht das Ergebnis zurück, und das Modell macht weiter. Der Tab **Tools** des Agents ist diese Liste — ein durchsuchbarer Katalog mit Schaltern pro Tool, gruppiert in Kategorie-Karten. <Frame caption="Der Tool-Katalog — eine Karte pro Kategorie, jede mit der Zahl der Tools, die der Agent gewährt bekommen hat."> ![Der Tools-Tab des Agenten-Editors, gescrollt zu den Kategorie-Karten, mit Wissen bei drei von vier angehakten Tools und Dateien bei sieben von sieben, während Konversationen, Diskussionen, Analysen und Aufgaben & Projekte nichts gewährt bekommen haben.](/images/platform/agent-editor-tools.webp) </Frame> ## Tools einzeln gewähren Setz den Haken bei einem Tool, und der Agent kann es ab der nächsten Anfrage aufrufen; entfern den Haken, und der Agent vergisst, dass es existiert. **Tools durchsuchen…** filtert den Katalog nach Name oder Kategorie, jede Tool-Zeile trägt eine einzeilige Beschreibung dessen, was sie gewährt, und die Kopf-Checkbox einer Kategorie schaltet die ganze Gruppe auf einmal — der Zähler daneben zeigt, wie viele Tools der Gruppe an sind. Die Kategorien bilden die Oberflächen der Plattform ab: **Kontakte**, **Produkte**, **Lieferanten** und **Websites** stellen Lese- und Update-Tools über strukturierte Datensätze bereit; **Konversationen** lässt den Agent lesen und antworten; **Wissen** deckt Dokumentsuche und Schreiben ab; **Aufgaben & Projekte** enthält die eigene To-do-Liste des Agents; **Automatisierungen** lässt ihn die Automatisierungen der Organisation anlegen und ausführen; **Web** hält die Suche über die Sites, die deine Organisation hinzugefügt hat; **Dateien** deckt die Dateioperationen des Agents ab; **System** hält **Code ausführen**, **Mensch fragen** und die übrigen Laufzeit-Tools. Gewähre die kleinste Menge, die den Job erledigt — jedes aktivierte Tool weitet, was der Agent in deinem Namen lesen oder ändern kann. **Code ausführen** in der Gruppe **System** ist das weitreichendste dieser Tools: Es führt Python, Node oder bash in der eigenen Sandbox des Chats aus und arbeitet dabei auf den Dateien, die der Chat schon hält, statt in einer leeren Box. Ein Aufruf führt einen Schnipsel direkt aus, führt ein Skript aus, das der Agent unter `/user/code/` abgelegt hat, oder installiert nur Pakete — deklarierte Pakete werden zuerst installiert und bleiben den Rest des Zugs erhalten, und was der Lauf unter `/user/output/` schreibt, erscheint als Datei im Chat. Dateien und Ordner, die du mit `@` anheftest, landen in dieser Sandbox unter `/user/uploads/`, sodass der Code die echten Bytes öffnet statt eines Retrieval-Schnipsels. <Note> Ein Agent startet für eine Teilaufgabe von sich aus einen fokussierten **Worker** — das ist kein Tool, das du hier umschaltest. [Agent-Worker](/de/platform/agents/delegation) deckt ab, wann das der richtige Zug ist und wie ein Worker eine begrenzte Teilmenge der Fähigkeiten des Agents erbt. </Note> ## Web-Zugang ist ein Tool, kein Modus Die Websuche steht im Katalog wie alles andere. Gewähr sie, und der Agent kann suchen, wenn er es für richtig hält; lass sie aus, und er kann gar nicht suchen. Es gibt keinen eigenen Modus einzustellen und kein automatisches Einspeisen von Ergebnissen in eine Antwort — der Agent greift nach der Suche wie nach jedem anderen Tool. Durchsucht wird das Material, das deine Organisation hinzugefügt hat, und kein offener Crawl; die Quellen verwaltest du also unter [Websites](/de/platform/knowledge/crawling). ## Auch Connectors und Automatisierungen sind Fähigkeiten Eine angebundene Connector und eine veröffentlichte Automatisierung erreichen den Agenten über dieselbe Liste. Darunter liegt keine zweite Binde-Oberfläche: Nenn die Fähigkeit in der Erlaubnisliste des Agenten, und er kann sie aufrufen, ohne die Connector oder die Automatisierungs-Id selbst zu zitieren. Verbundene [MCP-Server](/de/platform/connectors/mcp-servers) kommen auf demselben Weg, über die Connectors der Organisation. Eine Automatisierung, die nur ein Ereignis starten kann, wird aufgeführt, ist aber nicht aufrufbar. Der Agent sieht, dass es sie gibt, und wird klar darauf hingewiesen, dass sie läuft, wenn ihr Ereignis eintritt, und nicht auf Zuruf — ein Agent, der die Automatisierungen der Organisation nicht sieht, erfindet Umwege, statt auf die eine zu zeigen, die die Arbeit längst erledigt. ## Wie Tool-Aufrufe erscheinen Tool-Aufrufe erscheinen im Chat als eingeklappte Karten zwischen der Nachricht des Users und der Antwort. Eine aufgeklappte Karte zeigt den Tool-Namen, die Eingaben, die das Modell ausgegeben hat, und das Ergebnis, das Tale zurückgab. Ein fehlgeschlagener Tool-Aufruf zeigt den Fehler; das Modell versucht es beim nächsten Zug meist mit anderer Form erneut. ## Wann du danach greifst | Nutze Tools, wenn… | Nutze Wissen, wenn… | | --------------------------------------------------------------- | -------------------------------------------------- | | Der Agent handeln muss — abfragen, ändern, ausführen, antworten | Der Agent abgerufene Dokumente zitieren muss | | Die Daten strukturierte Datensätze oder Live-Systeme sind | Die Daten hochgeladene oder gecrawlte Inhalte sind | ## Wo das hingehört Tools weiten, was ein Agent tun kann; sie weiten auch die Vertrauensgrenze, denn der Agent kann jetzt in deinem Namen lesen, schreiben oder aufrufen. Lies diese Seite zusammen mit der [Run-Code-Richtlinie](/de/platform/admin/governance/run-code-policy), wenn der Agent Code ausführen soll. Die Anweisungen des Agents bleiben der Ort der **Richtlinie**; der Tab **Tools** ist der Ort der **Oberfläche**. # Agent-Versionen Source: https://tale.dev/docs/de/platform/agents/versions Jeder Speichervorgang eines Agents erzeugt einen Snapshot. Der Button **Verlauf** oben rechts im Agenten-Editor öffnet diese Snapshots in umgekehrt chronologischer Reihenfolge; Vergleichen zeigt, was sich geändert hat, und Wiederherstellen ersetzt den aktuellen Stand durch eine frühere Version. Es gibt keine Unterscheidung zwischen manuellem Speichern und Auto-Speichern — jede persistierte Änderung ist eine Version. Der Mechanismus ist klein, aber lasttragend. Die meisten Teams justieren die Anweisungen eines Agents wöchentlich; ohne den Verlauf würde das Team den Änderungen nie trauen. ## Eine Änderung prüfen Öffne den Agent und klicke auf **Verlauf**. Die Liste zeigt oben **Aktuelle Version** und darunter jede frühere **Snapshot-Version**, mit Autor und Zeitstempel pro Zeile. Wähle einen Snapshot, und **Änderungen vergleichen** stellt die Unterschiede zwischen ihm und der aktuellen Version gegenüber — die geänderten Felder heben sich hervor —, bevor du dich für das Wiederherstellen entscheidest. ## Eine Version wiederherstellen Klicke in einem Snapshot auf **Diese Version wiederherstellen**. Der aktuelle Stand des Agents wird durch den Snapshot ersetzt — eine Meldung bestätigt **Agent aus Verlauf wiederhergestellt** — und die Wiederherstellung landet als eigener Eintrag auf der Zeitleiste; Wiederherstellungen sind also additiv, nicht destruktiv. Chats, die schon gegen die vorherige Version laufen, laufen auf ihr weiter, bis sie enden; die wiederhergestellte Version gilt ab dem nächsten Chat. ## Was versioniert wird Die Versionierung deckt alles ab, was der Agent selbst trägt: seine Anzeigetexte und Beschreibung, seine Anweisungen, die Erlaubnislisten für Tools und Skills, den Wissensbereich, seine Sichtbarkeit und seine Metadaten. Was ein Agent nur ansteuert, erreicht sie nicht. Ein ersetztes Dokument, aus dem er abruft, ändert seine Antwort, ohne die Version zu erhöhen, und ein ersetztes Skill-Bundle, das er bindet, ebenso — die Bindung nennt einen Slug, seine eigene Konfiguration bleibt also unverändert, sein Verhalten nicht. Um beides zu prüfen, siehe [Audit-Logs](/de/platform/admin/governance/audit-logs). ## Wo das hingehört Versionen sind das Sicherheitsnetz des Agents, aus demselben Grund, aus dem git das der Codebasis ist: alles Gespeicherte ist wiederherstellbar. Die Begleitseite ist [Audit-Logs](/de/platform/admin/governance/audit-logs) — sie deckt die organisationsweite Spur ab, wer was getan hat; der Verlauf deckt die Spur pro Agent ab, was es war. # Agent-Konzepte Source: https://tale.dev/docs/de/platform/agents/concepts Zu einem Agenten greift Tale, wenn dieselbe Frage immer wiederkommt. Er ist eine **Persona** und keine Laufzeitumgebung: Er sagt, wer da antwortet — Name, Anweisungen, wonach er greifen darf und wer in der Organisation ihn benutzen darf — und nichts darüber, wie ein Zug abläuft. Gebaut wird er von Editoren und Developern, benutzt von allen Mitgliedern. Diese Seite gibt dir das Denkmodell, das der Rest des Kapitels voraussetzt. Lies sie einmal, bevor du deinen ersten Agenten baust, und komm zurück, wenn du nicht mehr weißt, ob das Verhalten, das du ändern willst, in den Anweisungen, den Tools, den Skills oder dem Wissensbereich steckt. Lieber erst zusehen? Episode 4 baut einen Agenten in gut drei Minuten von Anfang bis Ende, mit Untertiteln. <Video src="/videos/de/tutorials/ep4-agent/ep4-agent.de.mp4" poster="/videos/de/tutorials/ep4-agent/ep4-agent.de.webp" captions="/videos/de/tutorials/ep4-agent/ep4-agent.de.vtt" lang="de" title="Episode 4 — Dein erster Agent" caption="Episode 4 — Dein erster Agent (3:18)"> </Video> ## Was ein Agent mitbringt **Identität.** Den Slug, unter dem der Agent abgelegt ist, den Anzeigenamen, unter dem ihm die Leute begegnen, eine kurze Beschreibung seines Zwecks und optional Fassungen dieser Texte pro Sprache, damit deutsche und französische Leser den Agenten in ihrer eigenen Sprache antreffen. Der Slug steht fest, sobald der Agent existiert; den Anzeigenamen änderst du, wann immer sich die Aufgabe verschiebt. **Anweisungen.** Die Prosa, die jedem Zug vorangestellt wird, den der Agent beantwortet. Halte sie kurz, meinungsstark und konkret — lange Anweisungen verwässern in langen Gesprächen. Benenne die Stimme, die Grenzen und die Fälle, in denen der Agent ablehnen soll. **Tools und Skills.** Zwei Erlaubnislisten. Die Tools benennen die Fähigkeiten, die der Agent aufrufen darf, und Plattform-Tools, angebundene Connectors und die Automatisierungen der Organisation stehen alle in dieser einen Liste. Die Skills benennen die Wissenspakete, die er aufklappen darf, höchstens zehn davon. Für beide gilt dieselbe Regel: Rührst du eine Liste nicht an, ist der Agent nicht eingeschränkt; nennst du eine, gilt genau das Genannte. **Wissensbereich.** Eine einzige Einstellung dafür, welchen Bestand die Suche des Agenten lesen darf — die eigenen Dokumente der Organisation, die für sie geholten Webseiten, beides zusammen oder gar nichts. Gesucht wird nur, wenn der Agent es für nötig hält, also landet nichts in einer Antwort, wonach er nicht selbst gesucht hat. **Sichtbarkeit.** `private`, sodass nur der Besitzer herankommt, oder `org`, sodass jedes Mitglied es tut. Ein privater Agent nennt einen Besitzer, denn ein privater Agent ohne Besitzer wäre für niemanden erreichbar. ```mermaid flowchart LR I[Anweisungen] --> A((Agent)) T[Tools] --> A S[Skills] --> A K[Wissensbereich] --> A A --> R[Antwort mit Belegen] ``` ## Worüber der Agent nicht entscheidet Das Modell gehört nicht zum Agenten. Wem der Zug gehört, dem gehört auch diese Wahl — die Auswahl im Composer ist nur Modelle: Sie startet auf **Auto** (Tale wählt pro Nachricht ein Modell, und die Antwort hält fest, welches lief), und jedes direkt bediente Modell steht daneben zum Festnageln bereit. Ein Agent, der ein Modell festnagelt, würde stillschweigend die Wahl überschreiben, die gerade jemand vor dem Bildschirm getroffen hat, also hält er keines. Aus derselben Überlegung sind einige Einstellungen weggefallen, nach denen du vielleicht suchst. Ein Chat-Agent hat keinen Typ und keinen Harness-Picker: Ob Arbeit auf einem Coding-[Harness](/de/platform/agents/harnesses) läuft, entscheidest du beim Anlegen eines **Projekt-Agenten** oder eines Automation-**Agent**-Knotens (beide nennen das Feld **Agent-Laufzeit**), und manche Provider-Zugänge erzwingen eines. Er trägt keine Zeitgrenze, denn eine Obergrenze gehört zu dem Host, der den Zug ausführt, und nicht zu einer Persona. Er hält keine Umgebungsvariablen und keine eigenen Zugangsdaten — die liegen bei den Provider-Einträgen der Organisation, wo sie an einer Stelle rotiert und geprüft werden. Und er bringt keine fertigen Gesprächseinstiege mit, weil der Composer der Einstieg ist. ## Zusammengesetzt — ein Agent für die Support-Triage Ein erster nützlicher Agent ist der für die Support-Triage: Er liest die eingehende Frage, beantwortet, was er kann, und reicht den Rest weiter. Die Entscheidungen: - Anweisungen: ein Absatz zur Stimme, dazu drei ausdrückliche Fälle, in denen er ablehnt. - Tools: Websuche und die Gesprächs-Tools. Keine Codeausführung. - Skills: das hauseigene Bundle für den Antwortton, damit die Formulierung überall gleich klingt. - Wissen: auf die Dokumente der Organisation eingegrenzt, das gecrawlte Web bleibt außen vor. - Sichtbarkeit: `org`, damit das ganze Support-Team ihn im Composer auswählen kann. Danach läuft das Gespräch so ab: Deine Nachricht kommt an, die Anweisungen rahmen die Antwort, die Suche findet die Passagen, die sie stützen, die erlaubten Tools füllen die Lücken, und die Antwort landet mit Belegen. Die Weitergabe an eine Spezialistin ist kein Schalter, sondern folgt den Worker-Beziehungen zwischen Agenten — nachzulesen unter [Agent-Worker](/de/platform/agents/delegation). ## Wann du dazu greifst Ein einzelner Agent ist die richtige Form, solange das Gespräch in einer Domäne und einer Stimme bleibt. Zu einer [Automatisierung](/de/platform/automations/concepts) greifst du, wenn die Arbeit feste Stufen hat und du Freigaben oder Zeitpläne dazwischen willst; zu einem einfachen Chat ohne Agenten, wenn du selbst eine Antwort erkundest und die Voreinstellungen des Modells reichen. | Nimm … wenn | Agent | Einfacher Chat | Automatisierung | | ------------------------------------------------------ | ----- | -------------- | --------------- | | Dieselbe Frage wiederkehrt | ✓ | | | | Die Stimme oder die Grenzen zählen | ✓ | | | | Zwischen Schritten Freigaben oder Zeitpläne nötig sind | | | ✓ | | Du eine Antwort einmalig erkundest | | ✓ | | ## Bau einen Ein Agent besteht aus Identität, Anweisungen, zwei Erlaubnislisten, einem Wissensbereich und einer Sichtbarkeit — änderst du eines davon, hat er ein anderes Verhalten, änderst du drei, hast du ein anderes Produkt. Alles, was den Ablauf eines Zuges betrifft, bleibt außerhalb der Persona und entscheidet sich pro Gespräch. Der nächste sinnvolle Schritt ist [Einen Agenten anlegen](/de/platform/agents/create) — dort geht es Tab für Tab durch den Editor. # Bildgenerierung Source: https://tale.dev/docs/de/platform/agents/image-generation Bildgenerierung ist in Tale ein Tool und keine Art von Agent. Jeder Agent, dem `generate_image` gewährt ist, kann ein Bild direkt in der Antwort liefern: Du bittest ihn, etwas zu erstellen, zu zeichnen oder zu entwerfen, das Modell ruft das Tool auf, und das Bild erscheint in der Antwort wie ein Anhang. Es gibt keinen Modus, in den du vorher wechseln müsstest, und keine besondere Persona, die du auswählen müsstest. Diese Seite behandelt dieses Tool — was es tut, wie du es gewährst oder vorenthältst, wie das Ergebnis im Gespräch landet und was es kostet. Die Mechanik darunter gehört dem Provider: Qualität, Preis und Tempo gehen zwischen Bildmodellen weit auseinander. ## Das Tool generate_image `generate_image` nimmt genau eines entgegen — einen Prompt, der das gewünschte Bild beschreibt. Dieser Prompt steht für sich, denn das Bildmodell sieht das Gespräch nie: Der Agent faltet alles, was du zu Stil, Stimmung, Bildaufbau und Farbe gesagt hast, in diese eine Beschreibung. Das Ergebnis kommt als Datei zurück, erscheint direkt in der Antwort, und der Text des Agenten legt sich darum. Weil es ein gewöhnliches Tool ist, gilt hier alles, was für den Rest der Tool-Oberfläche gilt. Das Modell entscheidet aus der gewährten Liste heraus, wann es aufruft, Aufruf und Ergebnis erscheinen im Gespräch wie jeder andere Tool-Aufruf, und ein Agent ohne diese Gewährung kommt gar nicht daran. ## Gewähren oder vorenthalten Öffne den Tab **Tools** des Agenten und gewähre `generate_image` dort, wo Bilder zur Aufgabe gehören; lass es aus bei einem Agenten, der nur in Text antworten soll. Mehr ist nicht einzustellen — keine Bild-Option pro Agent, keine reine Bild-Persona und kein Typ, auf den du einen Agenten umschalten müsstest. Das Modell hinter dem Bild kommt von derselben Stelle wie jedes andere Modell: Wer die Nachricht abschickt, wählt es im Composer, statt dass der Agent eines festnagelt. Bietet in einer Organisation kein Provider etwas Bildfähiges an, kommt eine klare Absage statt einer Vermutung zurück — das ist der Hinweis für eine Administratorin, unter [Provider](/de/platform/admin/providers) eines hinzuzufügen. ## Wie das Bild in der Antwort landet Das erzeugte Bild erscheint neben dem Text des Agenten und öffnet sich in voller Größe, wenn du es anklickst. Die Datei liegt bei den Anhängen des Gesprächs und folgt denselben Aufbewahrungsregeln; ein erzeugtes Bild ist damit genauso dauerhaft — und genauso löschbar — wie alles, was du selbst in diesen Chat hochgeladen hast. Weil das Bild über einen Tool-Aufruf entsteht, lässt es sich auch wie einer nachvollziehen: Im Aufruf steht der Prompt, den das Modell tatsächlich abgeschickt hat, und das ist meist der schnellste Weg herauszufinden, warum ein Bild anders aussieht als gedacht. ## Kosten und Budget Bildmodelle kosten pro Aufruf mehr als Textmodelle, manchmal um eine Größenordnung. Die [Richtlinien und Limits](/de/platform/admin/governance/policies-and-limits) der Organisation deckeln die Ausgaben pro Person, pro Team und pro Agent; ist ein Deckel erreicht, erscheint das im Chat, statt dass ein Bild entsteht. Die Ausgaben tauchen in der [Nutzungsanalyse](/de/platform/admin/governance/usage-analytics) in denselben Tabellen auf wie die Textnutzung. ## Wo das hingehört Bildgenerierung ist ein Eintrag auf einer Liste, und genau darum geht es: Ein Agent, der zeichnen soll, bekommt `generate_image`, ein Agent, der das nicht soll, bekommt es nicht, und kein Teil der Persona muss um Bilder herum umgebaut werden. Was hier am ehesten veraltet, sind Provider- und Modellnamen — halte dich lieber an die laufende Liste unter [Provider](/de/platform/admin/providers) als an gemerkte Modell-IDs, und für den Rest des Katalogs an [Agent-Tools](/de/platform/agents/tools). # Agent-Wissen Source: https://tale.dev/docs/de/platform/agents/knowledge Wissen ist das, was ein Agent zur Antwortzeit heraussuchen und belegen kann. Ohne das bleibt er allgemein; damit antwortet er aus dem Material deiner Organisation und zeigt, woher die Antwort kommt. Auf dem Tab **Wissen** steht genau eine Entscheidung: welchen Bestand die Suche dieses Agenten lesen darf. Diese Entscheidung ist kleiner, als sie einmal sein musste, denn die Suche selbst ist kein Modus mehr, den du einstellst. Ein Agent sucht, wenn er es für nötig hält, und in eine Antwort rutscht nichts, wonach er nicht selbst gesucht hat. ## Einen Bereich wählen Vier Werte, eine Einstellung: - **Dokumente** — die hochgeladenen Dateien der Organisation und sonst nichts. - **Web** — die für die Organisation geholten Seiten und sonst nichts. - **Alles** — beide Bestände, zu einem Ranking zusammengeführt. Das bekommt ein Agent, wenn ihn niemand eingrenzt. - **Nichts** — dem Agenten wird gar keine Suche angeboten. Nimm das, wenn seine Aufgabe Denken oder Formulieren ist und Belege nur stören würden. Jeder Bestand gehört deiner Organisation, ein weiterer Bereich reicht also nie in fremdes Material hinein. Er entscheidet nur, auf wie viel vom Eigenen der Agent zeigt. ## Bewusst eingrenzen Alles im Bereich konkurriert bei jeder Frage um Relevanz, und deshalb antwortet ein enger Bereich meist besser als ein weiter. Ein Agent, der auf die Dokumente zeigt, die dein Team tatsächlich pflegt, findet die richtige Passage; derselbe Agent, der zusätzlich auf jede gecrawlte Seite zeigt, muss erst das Rauschen schlagen. Nimm **Dokumente**, wenn die Wahrheit in Dateien liegt, die du kontrollierst, und eine veraltete Webseite ein Risiko wäre. Nimm **Web**, wenn es dem Agenten um Veröffentlichtes geht und nicht um Abgelegtes. Nimm **Alles**, wenn wirklich beides zählt und dir Trefferbreite lieber ist. Das Material selbst — was hochgeladen, was gecrawlt und was indexiert ist — verwaltest du unter [Dokumente](/de/platform/knowledge/documents) und [Websites](/de/platform/knowledge/crawling) und nicht hier; dieser Tab zeigt den Agenten nur darauf. ## Wie die Suche in der Antwort landet Sucht der Agent, hängen die Belege an den Sätzen, die sie stützen — beim Überfahren siehst du die Quelle, mit einem Klick öffnest du sie. Ein Dokument, dessen Indexierung noch läuft, ist noch nicht auffindbar; ein Agent, der eine offensichtliche Quelle zu übergehen scheint, wartet also oft nur auf den Index, statt falsch eingestellt zu sein. ## Wann du dazu greifst Strukturierte Datensätze und laufende Systeme sind Tools und kein Wissen. Die Grenzen: | Nimm … | Wenn der Agent … braucht | | ------------------------------------------------------- | ----------------------------------------------------------- | | Wissen (diesen Tab) | Suche und Belege im Material der Organisation | | [Tools](/de/platform/agents/tools) | Kontakte, Produkte, Lieferanten, Websites, laufende Systeme | | [Projekt-Agenten](/de/platform/projects/project-agents) | Wissen, das auf ein Projekt begrenzt ist | ## Wo das hingehört Agent-Wissen beantwortet eine Frage — soll dieser Agent die Dokumente der Organisation lesen, ihr gecrawltes Web, beides oder keines von beidem. Im größeren Kapitel [Wissen](/de/platform/knowledge/overview) leben und indexieren sich die Quellen; dieser Tab hängt einen Agenten an einen Ausschnitt davon. Den Weg von Anfang bis Ende — hochladen, eingrenzen, fragen, Belege prüfen — geht [Agent mit Wissen](/de/tutorials/editor/agent-with-knowledge). # Entwickler Source: https://tale.dev/docs/de/platform/developer/overview Entwickler ist die In-App-Oberfläche für die Personen, die Tale an den Rest ihres Stacks verdrahten. Sie gruppiert die vier Hebel, die externem Code erlauben, mit Tale zu sprechen, und Tale erlauben, mit externem Code zu sprechen: API-Schlüssel für die REST-Oberfläche, Custom Tools, die die Reichweite eines Agents erweitern, Agent-Webhooks für eingehende Trigger und MCP-Server für die Brücke zu externen Prozessen. Personen mit Entwickler-Rolle sehen dieses Menü; Mitglieder und Redakteure nicht. Diese Übersicht nennt, was jede Seite behandelt, und verweist auf die tiefere Referenz. Entwickler-Rollen-Benutzer landen meist hier an ihrem ersten Tag, richten die Anmeldedaten und Tools ein, die sie brauchen, und kommen wieder, wenn sie den Stack erweitern — einen neuen MCP-Server hinzufügen, einen Schlüssel rotieren, einen neuen Webhook registrieren. ## Was Entwickler abdeckt Die Entwickler-Oberfläche sitzt neben dem Rest der Einstellungen der Organisation, aber mit einem engeren Publikum. Sie setzt voraus, dass du weißt, was eine REST-API ist, wie ein Webhook aussieht und was ein MCP-Server tut — die Seiten erklären die zugrundeliegenden Konzepte nicht neu; sie erklären, wie Tale sie offenlegt. Dieselbe Oberfläche in den Cloud- und Self-hosted-Tabs unterscheidet sich nur in der Deployment-Form; die Oberfläche hier ist identisch. Die Konfigurationsdatei-Entsprechungen einiger dieser Funktionen (Env-Vars, JSON-Konfigurationen für Custom Tools) liegen einen Tab weiter in der Self-hosted-Dokumentation. ## Seiten in diesem Bereich <CardGroup cols="2"> <Card title="API-Schlüssel" icon="key" href="/de/platform/admin/api-keys"> Ein Skript, einen Cron-Job oder einen internen Dienst an Tales REST-API verdrahten. Geteilt mit Admin unter Einstellungen > API-Schlüssel. </Card> <Card title="MCP-Server" icon="server" href="/de/platform/connectors/mcp-servers"> Einen externen MCP-Protokoll-Prozess registrieren und wählen, welche seiner Tools die Agents der Organisation aufrufen dürfen. </Card> <Card title="Agent-Tools" icon="wrench" href="/de/platform/agents/tools"> Den Toolbelt eines Agents um ein Custom Tool erweitern, das die Agents der Organisation aufrufen können. </Card> </CardGroup> ## Wo das hingehört Entwickler ist die Brücke zwischen Tale und dem Rest der Codebase, die die Organisation fährt. Die natürliche Erstlektüre hängt davon ab, was du verdrahten willst — für ausgehend (etwas innerhalb von Tale ruft nach außen) [Agent-Tools](/de/platform/agents/tools) und [MCP-Server](/de/platform/connectors/mcp-servers); für eingehend (etwas von außen ruft in Tale hinein) [API-Schlüssel](/de/platform/admin/api-keys). # Plattform Source: https://tale.dev/docs/de/platform Plattform ist die kanonische Produktreferenz: jedes nutzersichtbare Feature in Tale, identisch für Cloud und selbst gehostet. Die Seiten hier beschreiben die UI, die jemand anklickt, das Konzept dahinter und die Trade-offs zwischen Features, die ähnlich aussehen. Der Abschnitt ist nach Bereich und innerhalb eines Bereichs nach Feature gegliedert. Die meisten Leser arbeiten ihn nicht von vorne bis hinten durch — sie landen aus einer Suche oder aus einem Tutorial-Link hier, und die Seite, auf der sie landen, sollte die Frage beantworten, die sie mitgebracht haben. ## Feature-Bereiche <CardGroup cols="2"> <Card title="Chat" icon="message-circle" href="/de/platform/chat/overview"> Der alltägliche Einstieg — Konversationen, Agents im Chat, Anhänge, Arena-Modus, Sprachmodus, der Canvas-Bereich, Teilen. </Card> <Card title="Projekte" icon="folder-open" href="/de/platform/projects/overview"> Geteilte Arbeitsbereiche, die Dateien, Anweisungen, Konversationen und projektgebundene Agents bündeln. </Card> <Card title="Agents" icon="bot" href="/de/platform/agents/concepts"> Anweisungen, Wissen, Tools, Modell — plus Fähigkeiten, Worker, Versionierung und Webhook-Trigger. </Card> <Card title="Automatisierungen" icon="layout-grid" href="/de/platform/automations/concepts"> Installierbare Bündel aus Connectors, Agents, Skills und einem Workflow — der Katalog, der Installations-Assistent, der Editor und die Trigger hinter jeder Automatisierung und die Laufhistorie, die sie hinterlässt. </Card> <Card title="Wissen" icon="library" href="/de/platform/knowledge/overview"> Dokumente, Kontakte, Produkte, Lieferanten, Websites — das Modell für strukturierte Daten, das Agents zitieren. </Card> <Card title="Genehmigungen" icon="check-check" href="/de/platform/approvals/concepts"> Inline-Karten, Workflow-Gates und der Genehmiger-Pool, der Menschen in der Schleife hält. </Card> <Card title="Skill-Bibliothek" icon="list-plus" href="/de/platform/workspace/skills"> Wiederverwendbare Anleitungs-Bundles, die du privat behältst oder mit der ganzen Organisation teilst. </Card> <Card title="Modelle" icon="cpu" href="/de/platform/models"> Der Modellkatalog hinter jedem Picker — Fähigkeits-Tags, Standards und die ausgelieferte Liste. </Card> <Card title="Connectors" icon="plug" href="/de/platform/connectors/overview"> Drittanbieter-Pairings und MCP-Server. </Card> </CardGroup> ## Richte deinen ersten Tag ein Vier rollenbasierte Einträge zeigen dieselben Features von der Seite des Lesers — was ein Mitglied, ein Redakteur, ein Entwickler oder die Verwaltung am ersten Tag tatsächlich anfasst. <CardGroup cols="2"> <Card title="Mitglied" icon="user" href="/de/platform/member/overview"> Chat, Wissen, persönliche Einstellungen — die Oberfläche, die die meisten Leute in den meisten Orgs nutzen. </Card> <Card title="Redakteur" icon="pencil-ruler" href="/de/platform/editor/overview"> Die Bau-Oberfläche — Agents, Wissenspflege, Automatisierungen, Projekte. </Card> <Card title="Entwickler" icon="terminal" href="/de/platform/developer/overview"> API-Schlüssel, eigene Tools, Webhooks, MCP-Server — Tale an externen Code anbinden. </Card> <Card title="Verwaltung" icon="shield" href="/de/platform/admin/overview"> Organisationseinstellungen, Anbieter, Branding, Connectors und der Governance-Unterzweig. </Card> </CardGroup> ## Wo das hingehört Plattform ist der Gravitationsbrunnen — Cloud und selbst gehostet verlinken beide für Feature-Dokumentation hier hinein, und jedes Tutorial zitiert Seiten von hier für die zugrundeliegenden Konzepte. Die Seite, die du dir an deinem ersten Tag setzen willst, ist [Agents → concepts](/de/platform/agents/concepts) — fast jede andere Produktseite setzt das Vier-Knöpfe-Modell voraus, das dort aufgebaut wird. # Genehmigungskonzepte Source: https://tale.dev/docs/de/platform/approvals/concepts Eine Genehmigung ist die Naht zwischen der Initiative eines Agents und deinem Urteil: eine Karte, die im Chat dort erscheint, wo die Aktion versucht wurde, und die Aktion anhält, bis ein Mensch entscheidet. Agents schlagen vor — einen Dokument-Schreibzugriff, einen ausgehenden API-Aufruf, einen Workflow-Lauf — und nichts läuft, solange die Karte aussteht. Der Chat sagt es ausdrücklich: **Beantworte die ausstehende Anfrage oben, um fortzufahren**. Diese Seite ist das Denkmodell — was eine Genehmigung auslöst, was die Karte bietet und was eine Entscheidung hinterlässt. Die Workflow-spezifischen Tore stehen auf [Genehmigungen in Workflows](/de/platform/automations/approvals-in-workflows); wo die Anforderungen deklariert werden, steht auf [Genehmigungen konfigurieren](/de/platform/approvals/configure). ## Was eine Genehmigung auslöst Jede Karte stammt von einem Agent, der auf etwas wirken will, das das Gespräch überdauert: - **Pläne** — ein Agent schlägt einen mehrstufigen Plan als Karte **Vorgeschlagener Plan** vor; **Genehmigen & ausführen** startet ihn. - **Dokument-Schreibzugriffe** — eine Karte **In Dokumenten speichern** hält Dateien, die ein Agent ablegen will; nichts landet im Dokumenten-Hub, bevor du genehmigst. - **Wissens-Schreibzugriffe** — eine Karte **In Wissensdatenbank speichern** hält einen Fakt, den ein Agent organisationsweit festhalten will. - **Connector-Aufrufe** — eine Operation mit Genehmigungspflicht (typischerweise ausgehende Schreibzugriffe) hält an, mit den exakten Parametern sichtbar. - **MCP-Tools** — ein Tool, das der Server mit **Genehmigung erforderlich** markiert, fragt, bevor es läuft. - **Workflow-Erstellung, -Aktualisierungen und -Läufe** — die Tore auf der Workflow-Seite, behandelt in [Genehmigungen in Workflows](/de/platform/automations/approvals-in-workflows). ## Die Entscheidungen auf einer Karte Jede Karte trägt den exakten Payload der Aktion — die Datei, den Fakt, die Parameter — und zwei Entscheidungen: genehmigen (der Button benennt die Aktion, etwa **Workflow ausführen** oder **Genehmigen & ausführen**) oder ablehnen. Connectorskarten fügen einen dritten Weg hinzu, **Änderungen vorschlagen**: Beschreib in freiem Text, was falsch ist, und der Agent überarbeitet den Aufruf, statt ihn aufzugeben. <Note> Genehmigungen werden in dem Gespräch entschieden, das sie unterbrechen — von der Person, die diesen Chat führt. Es gibt keinen separaten Genehmigungs-Posteingang und kein Routing an einen Genehmiger-Pool; die Person, für die der Agent arbeitet, ist die Person, die entscheidet. </Note> ## Zustände und die Spur Eine Karte wandert von **Ausstehend** über **Wird ausgeführt** zu **Abgeschlossen** — oder **Abgelehnt** — und behält ihren entschiedenen Zustand im Transkript, sodass sich ein Chat als Protokoll dessen wiederliest, was erlaubt wurde. Jede Entscheidung landet außerdem im [Audit-Log](/de/platform/admin/governance/audit-logs) mit Akteur, Aktion und Zeitstempel. Entschiedene Karten lassen sich nicht wieder öffnen; ein neuer Versuch heißt ein frischer Vorschlag und eine frische Karte. ## Wo das hingehört Genehmigungen sind das, was dich Agents echte Fähigkeiten anvertrauen lässt — Dateien, APIs, Workflows — ohne das Protokoll aus der Hand zu geben, wer was erlaubt hat. Lies als Nächstes [Genehmigungen konfigurieren](/de/platform/approvals/configure), um zu sehen, wo eine Anforderung eingeschaltet wird, und [Genehmigungen in Workflows](/de/platform/automations/approvals-in-workflows) für die Tore rund um Workflows. # Genehmigungen konfigurieren Source: https://tale.dev/docs/de/platform/approvals/configure Genehmigungspflichten sind in Tale deklarativ: Jede Fähigkeit trägt ihr eigenes Flag, das sagt, ob ein Agent zuerst fragen muss, und das Flag reist mit der Connector oder dem Server, der die Fähigkeit bereitstellt. Damit die Voreinstellung stimmt, musst du nichts konfigurieren — diese Seite zeigt, wo jedes Flag lebt, welche Schreibzugriffe von sich aus fragen und wie du das für deine Organisation änderst. Das Modell, was eine Genehmigungskarte ist und wer sie entscheidet, steht auf [Genehmigungskonzepte](/de/platform/approvals/concepts). Was folgt, ist die Konfigurationsoberfläche, Fähigkeit für Fähigkeit. ## Connector-Operationen Jede Connector deklariert ihre Operationen, und jede Operation trägt ihr eigenes Genehmigungs-Flag. Öffne **Einstellungen > Connectors**, klicke auf eine Connector, und ihre Operationsliste kennzeichnet die als **Genehmigung erforderlich** markierten — bei den mitgelieferten Konnektoren ist das die Schreibseite: Mail senden, Nachrichten posten, Issues erstellen. Lesezugriffe laufen ohne Karte; markierte Schreibzugriffe halten im Chat mit ihren exakten Parametern, bis jemand genehmigt. Das Flag ist keine separate Einstellung, die ein Admin umlegt. Jede Aktion, die ein Connector deklariert, trägt einen Effekt — `read` oder `write` —, und die Schreibseite ist das, was die Genehmigungsrichtlinie abfängt. Das hält beide ehrlich zueinander: Eine Aktion kann sich nicht klammheimlich von einem Lese- in einen Schreibzugriff verwandeln, ohne auch zu ändern, wofür sie fragen muss. ## Welche Schreibzugriffe fragen Eine Karte ist die Aufmerksamkeit eines Menschen wert, wenn der Schreibzugriff **deinen Mandanten verlässt**. Genau dort liegt die Grenze: - **Schreibzugriffe in fremde Systeme fragen** — Mail senden, in Slack posten, ein GitHub-Issue öffnen, auf eine WebDAV-Ablage schreiben. Diese Connectors halten deine Zugangsdaten und handeln in Systemen, die Tale nicht gehören. - **Schreibzugriffe auf Tales eigener Oberfläche fragen nicht** — eine Aufgabe verschieben, sie kommentieren, ein Dokument im Projekt ablegen, ein Skript in deiner eigenen Sandbox laufen lassen. Sie sind schon durch die Rechte dessen gebunden, der sie ausführt, eine Automatisierung dahinter hat ihr Deploy-Gate passiert, und jeder davon steht im Trace des Laufs und im Audit-Log. Ohne diese Grenze stapelt ein einzelner Automatisierungslauf ein halbes Dutzend Karten für seine eigene Buchführung — „diese Karte auf In Bearbeitung setzen" — und begräbt darunter die eine Karte, die wirklich einen Menschen brauchte. ## Die Grenze für deine Organisation verschieben Beide Richtungen sind pro Organisation konfigurierbar, in `governance/approval-policy.yml` in deinem Konfigurationsverzeichnis. Jede Regel nennt **ein** Ziel — einen ganzen Connector oder eine einzelne Aktion als `<connector>.<aktion>` — und die spezifischere Regel gewinnt: ```yaml rules: # Dieses Team prüft jede Aufgabe, die der Desk anfasst. - connector: task decision: require_approval # Der nächtliche Report-Mail wird vertraut; andere Mail-Aktionen fragen weiter. - action: imap-smtp.send decision: auto_approve ``` Eine Operation, die schon auf einer Karte wartet, behält ihre Karte auch dann, wenn die Richtlinie danach gelockert wird — eine Entscheidung gehört zu der Operation, für die sie erbeten wurde, und ein geparkter Lauf bleibt so nie hängen. ## MCP-Tools Das Manifest eines MCP-Servers markiert, welche seiner Tools ein Einverständnis brauchen. Öffne **Einstellungen > API > MCP**, klappe einen Server aus, und seine Liste **Erkannte Tools** kennzeichnet jedes markierte Tool mit **Genehmigung erforderlich** — diese fragen im Chat bei jedem Aufruf durch einen Agent. Das Flag stammt vom Autor des Servers; einen Server zu verbinden heißt, seinen Tool-Vertrag anzunehmen — lies die Liste also, bevor du einen aktivierst. [MCP-Server](/de/platform/connectors/mcp-servers) behandelt die Registrierung. ## Eingebaute Schreib-Tore Einige Tore sind ab Werk an und nicht konfigurierbar, weil die Aktion ihrer Natur nach folgenreich ist: - **Dokument-Schreibzugriffe** — ein Agent, der Dateien im Dokumenten-Hub ablegt, fragt immer (**In Dokumenten speichern**). - **Wissens-Schreibzugriffe** — ein Agent, der einen organisationsweiten Fakt speichert, fragt immer (**In Wissensdatenbank speichern**). - **Workflow-Erstellung, -Aktualisierungen und -Läufe** — ein Agent, der einen Workflow baut, bearbeitet oder startet, fragt immer; siehe [Genehmigungen in Workflows](/de/platform/automations/approvals-in-workflows). <Note> Der Hebel dafür ist nicht das Genehmigungs-Flag, sondern die Fähigkeit selbst: Ein Agent ohne Dokument- oder Workflow-Tools produziert die Karte gar nicht erst. Beschneide das [Tool-Set](/de/platform/agents/tools) des Agents, um die Fähigkeit ganz zu entfernen. </Note> ## Prüfen, was fragen wird Bevor du einen Agent vor echte Systeme stellst, lies seine Fähigkeiten wie ein Genehmiger: die Operationsliste der Connector auf markierte Schreibzugriffe, die **Erkannte Tools** des MCP-Servers auf markierte Tools und den Tool-Tab des Agents darauf, ob er überhaupt Schreib-Tools hält. Das [Audit-Log](/de/platform/admin/governance/audit-logs) protokolliert anschließend jede Entscheidung, die dieses Setup produziert. ## Wo das hingehört Konfiguration ist hier Verteilung — die Flags leben bei den Connectors und Servern, denen die Fähigkeiten gehören. Lies [Genehmigungskonzepte](/de/platform/approvals/concepts) für den Kartenlebenszyklus, den diese Flags produzieren, und [Agent-Tools](/de/platform/agents/tools) für die Fähigkeitsseite derselben Grenze. # Modellkatalog Source: https://tale.dev/docs/de/platform/models Jeder Modell-Picker in Tale bietet dasselbe an — die Modelle, die deine Organisation gerade wirklich erreichen kann. Diese Menge entsteht pro Anbieter, aus der Modellliste des Connectors und den Zugangsdaten, die du dagegen hältst, und wird danach von deinen Governance-Regeln eingeengt. Diese Seite erklärt, woher jedes Stück kommt, damit „warum fehlt dieses Modell“ eine Antwort hat, mit der du etwas anfangen kannst. ## Der Katalog gehört zum Anbieter Eine einzige globale Modellliste gibt es nicht. Jeder Anbieter-Connector deklariert, woher seine Modelle kommen, und das Badge im Abschnitt dieses Connectors unter **Einstellungen > KI-Anbieter** benennt die Quelle: - **Mitgelieferter Katalog** — die Liste kommt mit der Plattform und wird mit ihr aktualisiert. So arbeiten OpenAI, Anthropic, Gemini, DeepSeek, Moonshot AI (Kimi), Qwen (Alibaba), SpaceXAI und Z.ai (GLM). - **OpenRouter-Katalog** — direkt aus OpenRouters eigenem Katalog geholt und beim Eintreffen normalisiert. So arbeitet OpenRouter, weshalb seine Liste mit Abstand die längste ist. - **Models-Endpunkt des Anbieters** — aus der Modell-Auflistung des Anbieters selbst geholt. So arbeitet Vercel AI Gateway. - **Kein Katalog** — der Anbieter veröffentlicht nichts, was sich mitliefern liesse, also kommen die Modelle stattdessen aus den einzelnen Zugangsdaten. So arbeiten Azure OpenAI und Nous Portal (Hermes). Die Zahl neben dem Badge ist die aktuelle Liste dieses Connectors. Diese Zahl sagt nichts darüber, was deine Organisation aufrufen darf, sondern nur, was der Anbieter anbietet. ## Was über Verfügbarkeit entscheidet Ein Modell erreicht eine Auswahl, nachdem es zwei Schranken in dieser Reihenfolge passiert hat. Die erste sind die Zugangsdaten. Ein Connector ohne Zugangsdaten ist ein Anbieter, den du nicht aufrufen kannst — Katalog hin oder her. Ein Eintrag mit leerer Liste **Erlaubte Modelle** bietet den ganzen Katalog seines Connectors an, ein Eintrag mit gefüllter Liste nur die Modelle darauf. Die Vereinigung über alle aktiven Zugangsdaten ist das, was deine Organisation technisch erreicht. Die zweite ist Governance. Die Modellzugriffs-Regeln unter [Inhalte und Modelle](/de/platform/admin/governance/content-models) erlauben oder sperren Modelle pro Organisation, Team, Rolle oder Person und greifen auf die erste Schranke obendrauf. Ein Modell, das die Zugangsdaten passiert, aber nicht die Richtlinie, bleibt für diesen Geltungsbereich unsichtbar, und die Auflösung bindet auch dann nicht daran, wenn ein Agent es fest gesetzt hat. <Note> Fehlt ein Modell, das du erwartet hast, geh die beiden Schranken in dieser Reihenfolge durch. Prüf, ob Zugangsdaten für seinen Anbieter existieren und aktiv sind, ob deren Liste erlaubter Modelle es ausschliesst, und dann die Modellzugriffs-Regeln für den Geltungsbereich, aus dem du schaust. Fast jedes „fehlende Modell“ ist einer dieser drei Fälle. </Note> ## Anbieter ohne mitgelieferten Katalog Manche Anbieter können keine Liste veröffentlichen, die Tale mitliefern könnte. Bei diesen Connectoren ist die Liste **Erlaubte Modelle** kein Filter mehr, sondern die Verfügbarkeit selbst: Das Feld nimmt freien Text, du trägst Modell-IDs durch Kommas getrennt ein, und genau diese IDs sind die einzigen Modelle, die der Eintrag erreicht. <Info> Bei Azure OpenAI sind das die Deployment-Namen, die du in deiner Azure-Ressource vergeben hast, nicht die öffentlichen Modellnamen des Herstellers. Ein Eintrag mit leerer Liste stellt dort überhaupt kein Modell bereit — das ist die übliche Ursache für einen Azure-Connector, der konfiguriert aussieht und trotzdem nichts anbietet. </Info> ## Einen Live-Katalog aktualisieren Kataloge, die von einem Anbieter geholt werden, liegen im Cache und werden nur auf Zuruf erneuert. Die Karte **Modellkataloge** oben auf **Einstellungen > KI-Anbieter** trägt den Knopf **Kataloge aktualisieren**, der jede Live-Quelle neu holt und eine Zeile pro Connector meldet: die Anzahl gefundener Modelle oder den Fehler, der sie gestoppt hat. Einen Hintergrundabgleich und einen geplanten Job gibt es nicht, also erscheint ein heute Morgen veröffentlichtes Modell nach der nächsten Aktualisierung und keine Minute früher. Wenn jeder Connector deiner Instanz einen mitgelieferten Katalog hat, gibt es nichts zu holen, und die Karte sagt genau das. ## Ein Modell auswählen Der Chat startet auf **Auto**: Tale liest jede Nachricht und wählt ein Modell dafür — eine leichte Heuristik über Länge, Code, Thema und angehängte Dokumente, nie ein weiterer KI-Aufruf — und lässt genau dieses Modell laufen. Auf der Antwort steht es dann fest; die Nachrichtendetails nennen es beim Namen. Wählst du stattdessen ein Modell aus dem Menü, bleibt die Wahl deine, bis du sie an Auto zurückgibst — ein Modell festzunageln ist die Lösung, wenn die automatische Wahl zu langsam, zu teuer oder für die Aufgabe falsch ist. Überall sonst wird das Modell immer ausdrücklich benannt: auf einem Agenten, auf jedem Workflow-Schritt, der ein Modell aufruft, und auf jeder API-Anfrage. Dort routet nichts für dich — keine Auswahl nach Aufgabenkomplexität, keine Qualitätsstufen. Und nirgendwo — der Chat eingeschlossen — gibt es stilles Ausweichen: Das Modell, das eine Antwort beginnt, beantwortet sie auch, oder du siehst den Fehler. Ein Lauf bleibt reproduzierbar und eine Rechnung zuordenbar, denn welches Modell lief, wird festgehalten, nie geraten. <Tip> Wenn mehrere Modelle die Aufgabe plausibel erledigen könnten, schickt [Arena-Modus](/de/platform/chat/arena-mode) denselben Prompt nebeneinander an mehrere davon — aus der Wahl wird ein Vergleich statt eines Bauchgefühls. </Tip> ## Wo das hingehört Der Katalog ist die sichtbare Hälfte der Anbieter-Konfiguration: Was ein Admin unter [KI-Anbieter](/de/platform/admin/providers) verbindet, sehen alle anderen hier in einer Auswahl. Die Menge zu erweitern heisst, Zugangsdaten hinzuzufügen oder eine Liste zu lockern; sie zu verengen heisst, eine Liste erlaubter Modelle zu setzen oder eine Modellzugriffs-Regel unter [Inhalte und Modelle](/de/platform/admin/governance/content-models). Wie das Modell neben Anweisungen, Wissen und Werkzeugen in einen Agenten passt, steht in [Agent-Konzepte](/de/platform/agents/concepts). # Umgebungsvariablen & Geheimnisse Source: https://tale.dev/docs/de/platform/member/environment Umgebungsvariablen & Geheimnisse ist dein persönlicher Speicher für Variablen, die Tale in jede Sandbox einspeist, die du in dieser Organisation startest. Startet ein [Projekt-Agent oder Automation-Agent-Knoten](/de/platform/agents/harnesses) einen Harness-Zug, setzt Tale jeden hier gespeicherten Eintrag in die Umgebung, bevor der Agent läuft — ein Befehl, den der Agent absetzt, oder der Agent selbst kann ihn dann lesen. Greif dazu, wenn die Arbeit etwas von dir braucht, das sonst niemand halten soll: ein persönliches API-Token für einen Dienst, den die Organisation nicht angebunden hat, einen Endpunkt, der bei dir anders ist, einen Schlüssel, der an dein eigenes Konto hängt. Es ist eine Seite auf Mitglieds-Ebene, die jede Rolle erreicht, und die Einträge sind auf dich und die aktuelle Organisation begrenzt — sie dringen nie zu Teamkolleginnen durch und folgen dir nie in eine andere Organisation. Diese Seite zeigt die zwei Arten von Eintrag, wie Geheimnisse geschützt werden, welche Regeln Name und Wert erfüllen müssen, und wo die Werte landen. <Frame caption="Einstellungen > Umgebung — die gespeicherten Einträge, jeder mit dem Schalter Geheim, der entscheidet, ob sein Wert zurückgelesen werden kann."> ![Die Umgebungs-Einstellungsseite listet drei gespeicherte Einträge — ANALYTICS_ORG und CRM_BASE_URL mit offen sichtbaren Werten und CRM_API_TOKEN als Punkte maskiert, mit angehaktem Kästchen Geheim — über der Aktion Variable hinzufügen.](/images/platform/settings-environment.webp) </Frame> ## Variablen und Geheimnisse Öffne **Einstellungen > Umgebung**. **Variable hinzufügen** öffnet einen Dialog für einen neuen Eintrag, darunter steht die Liste dessen, was du gespeichert hast. Jeder Eintrag hat einen **Name** und einen **Wert**, dazu einen **Geheimnis**-Schalter, der entscheidet, wie der Wert gespeichert und angezeigt wird. Eine einfache Variable wird unverändert gespeichert und in der Liste in voller Länge zurückgezeigt — nimm sie für unkritische Konfiguration, die der Agent erwartet, einen Regionsnamen oder einen Endpunkt. Ein **Geheimnis** wird im Moment des Speicherns verschlüsselt und ist von da an schreibgeschützt: Die Liste zeigt `••••••••` statt des Werts, und es gibt keinen Weg, ihn zurückzulesen. Schalt den Schalter für alles Sensible ein — einen API-Schlüssel, einen OAuth-Token, ein Passwort. Der Preis dafür ist, dass du den Wert eines Geheimnisses später nicht mehr prüfen kannst: Bist du dir unsicher, ob er stimmt, lösch ihn und füg ihn neu hinzu, statt nach einem Anzeigen-Knopf zu suchen, den es nicht gibt. Jede Zeile trägt den Namen, den Wert oder seine Maske, und wann er zuletzt aktualisiert wurde. Das Papierkorb-Symbol fragt vor dem Entfernen nach Bestätigung, denn einen Eintrag zu löschen nimmt ihn beim nächsten Lauf aus jeder deiner Sandboxes. ## Namen, Werte und Grenzen Ein **Name** muss mit einem Buchstaben oder Unterstrich beginnen und darf nur Buchstaben, Ziffern und Unterstriche enthalten — die Form einer gewöhnlichen Umgebungsvariable, `MY_API_KEY` statt `my-api.key`. Namen sind auf 128 Zeichen begrenzt, Werte auf 8.192 — Platz für einen langen Token oder einen mehrzeiligen Schlüssel, aber nicht für eine Datei. Du kannst bis zu 100 Einträge halten. Tale schneidet Leerzeichen am Anfang und Ende eines Werts beim Speichern ab, denn ein versehentlicher Zeilenumbruch aus dem Kopieren ist der häufigste Grund, warum ein Token still fehlschlägt. Leerzeichen oder Zeilenumbrüche _innerhalb_ des Werts bleiben unangetastet, aber Tale warnt, wenn es welche findet: Anmeldedaten haben normalerweise keine, also bedeutet Leerraum im Inneren meist, dass ein Token beim Einfügen über mehrere Zeilen in deinem Terminal umbrochen wurde. Die Warnung blockiert das Speichern nicht — ein echt mehrzeiliges Geheimnis wie ein privater PEM-Schlüssel behält seine Zeilenumbrüche —, also lies sie und entscheide selbst. ## Wie die Werte in die Sandbox kommen Ein Geheimnis reist nie im Klartext, außer in deine eigene Sandbox. In Ruhe liegt es im Backend von Tale verschlüsselt, unter einem Schlüssel, den die Plattform hält, und die Listen-Abfrage liefert nur die Maske zurück, nie den Klartext. Beginnt ein Turn, entschlüsselt die Plattform deine Geheimnisse und setzt sie, neben deinen einfachen Variablen, in die Umgebung deiner Sandbox für diesen Lauf. Wird ein Geheimnis für einen Turn eingespeist, hält das Audit-Log diesen Zugriff fest. Dieser letzte Schritt ist die Grenze, die es zu verstehen lohnt: Die Werte landen in deinem Sandbox-Container, also ist die Isolation der Sandbox — nicht der Geheimnis-Speicher —, was zwischen deinen Anmeldedaten und allem anderen steht, das dort läuft. Das deckt sich damit, wie der GitHub-Token in der Sandbox funktioniert, und ist der Grund, warum diese Einträge nur auf dich begrenzt sind statt mit der Organisation geteilt. Was nicht von hier kommt, ist der Zugang, mit dem ein Zug sein Modell erreicht. Der gehört zu den Provider-Einträgen der Organisation unter [Provider](/de/platform/admin/providers), wo er an einer Stelle rotiert und geprüft wird — ein Agent hält keine eigenen Schlüssel, und diese Seite auch nicht an seiner Stelle. Behalte diese Einträge für das, was deine eigene Arbeit braucht, und lass den Modell-Zugang dort, wo die Organisation ihn steuern kann. ## Wo das hingehört Umgebungsvariablen & Geheimnisse ist die eine Seite auf Mitglieds-Ebene, die in die Sandbox reicht statt in den Chat — so kommen deine eigenen Schlüssel und deine Konfiguration zu der Arbeit, die du startest, ohne dass ein Redakteur oder Admin sie für dich setzt. Lies sie neben [Harnesses](/de/platform/agents/harnesses), wo steht, was der Container sonst noch hält und was er erreichen darf. Für den Rest deiner persönlichen Einstellungen — Anzeigename, Passwort, eigene Anweisungen — siehe [Einstellungen](/de/platform/member/preferences). # Als App installieren Source: https://tale.dev/docs/de/platform/member/install-as-app Tale ist eine Progressive Web App. Die Installation legt ein Icon ins Dock oder auf den Homescreen, lässt Tale in einem eigenen Fenster ohne Browser-Beiwerk laufen und behält dieselbe Session, die du im Browser hattest. Es gibt keinen separaten nativen Build zum Herunterladen und keine Erweiterung zum Installieren — dieselbe URL, mit der du dich anmeldest, ist dieselbe App, in einer eigenständigen Hülle. Diese Seite deckt die drei Stellen ab, an denen du die Installation auslöst: die Zeile **App installieren** im Profilmenü von Chromium-Browsern, den Teilen-Schritt in iOS Safari und das Installations-Banner, das Android Chrome von selbst zeigt. Einmal installiert, verhält sich Tale identisch; die Installation ändert nur das Beiwerk drumherum. ## Die Profilmenü-Verknüpfung In Chrome, Edge, Brave, Arc und den anderen Chromium-Browsern führt Tales Profil-Dropdown eine Zeile **App installieren**, wenn der Browser bereit ist zu installieren. Öffne das Menü über deinen Avatar oben rechts, scroll am Themen-Wechsler und am Sprach-Wechsler vorbei und klick **App installieren**. Der Browser öffnet seine native Installations-Bestätigung; akzeptier sie, und Tale landet binnen ein, zwei Sekunden in deinem Dock (macOS), deiner Taskleiste (Windows) oder deiner App-Liste (ChromeOS). Die Zeile ist nur da, wenn der Browser sein `beforeinstallprompt`-Event gefeuert hat und die App noch nicht installiert ist. Browser, die dieses Event nicht feuern — Firefox, Safari, alles im privaten Fenster — zeigen die Zeile nicht, also bleibt das Menü einen Eintrag kürzer, statt etwas zu versprechen, was es nicht liefern kann. ## iOS und iPadOS iOS Safari feuert kein `beforeinstallprompt`, also erscheint die Zeile **App installieren** nicht im Menü. Der Installationspfad liegt stattdessen im Teilen-Sheet von Safari. Öffne Tale in Safari, tipp auf das Teilen-Symbol in der Symbolleiste, scroll runter zu **Zum Home-Bildschirm**, und bestätige. Tale erscheint auf deinem Home-Bildschirm mit demselben Icon wie das Browser-Favicon. Tipp drauf, und Tale öffnet sich in einem eigenen Fenster — keine Safari-Adressleiste, keine Tab-Leiste, kein Zurück-Knopf außerhalb dessen, was Tale selbst zeigt. Benachrichtigungen funktionieren genauso wie im Browser-Tab; die Installation ist der einzige Unterschied. Andere iOS-Browser — Chrome, Edge, Firefox auf iOS — sind unter der Haube Safari und haben keinen eigenen Zum-Home-Bildschirm-Eintrag. Der Safari-Pfad ist der einzige iOS-Installationspfad, der eine echte eigenständige App erzeugt. ## Android Android Chrome regelt die Installation an zwei Stellen. Die erste ist dieselbe Zeile **App installieren** in Tales Profilmenü, identisch zum Desktop-Ablauf. Die zweite ist Chromes eigenes Installations-Banner — eine einzeilige Leiste, die von unten auf der Seite hochfährt, bei Sites, die der Browser für installierbar hält. Tipp **Installieren** im Banner, bestätige im System-Sheet, und Tale landet auf deinem Home-Bildschirm. Wenn du das Banner einmal weggewischt hast, kommt es meist eine Weile nicht wieder. Die Profilmenü-Verknüpfung funktioniert unabhängig davon, ob das Banner gezeigt wurde oder nicht. Andere Android-Browser — Firefox, Samsung Internet, Brave — haben jeweils ihren eigenen Installationspfad im Browser-Menü, typischerweise beschriftet mit **App installieren** oder **Zum Home-Bildschirm**. ## Nach der Installation Tale in einem PWA-Fenster ist dasselbe Tale wie in einem Browser-Tab. Die Session, die Chats, die Wissensdatenbank, die Agents — alles davon ist dieselbe Oberfläche. Die Unterschiede sind kosmetisch und klein: kein Browser-Beiwerk um das App-Fenster, ein Icon im Launcher, und auf den meisten Plattformen merkt sich das Fenster Größe und Position zwischen Starts. Die Deinstallation folgt der Plattform-Konvention. Auf macOS zieh das Icon aus dem Dock; auf Windows rechtsklicke und deinstallier; auf iOS und Android halt das Icon gedrückt und entferne es. Die Deinstallation räumt die PWA-Hülle weg, aber nicht die Session — meld dich wieder über den Browser an, und deine Daten sind dort, wo du sie gelassen hast. ## Wann du dazu greifst Die Installation lohnt sich, sobald du Tale jeden Tag öffnest und willst, dass es sich wie eine deiner Apps anfühlt statt wie einer deiner Tabs. Installier auch, wenn du das Chat-Fenster auf einem virtuellen Desktop oder in einem Stage-Manager-Slot fixieren willst, den Browser-Tabs nicht respektieren würden. Lass die Installation aus, wenn du dich von vielen Maschinen anmeldest und den Browser-Tab bevorzugst — Tale funktioniert so oder so gleich. Die benachbarte Lektüre ist [Mitglieds-Übersicht](/de/platform/member/overview) — sie ist die Karte dessen, was der Rest der Mitglieder-Oberfläche abdeckt, sobald Tale in deinem Dock sitzt. # Einstellungen Source: https://tale.dev/docs/de/platform/member/preferences Einstellungen sind die Schrauben, die dir gehören, nicht der Organisation. Dein Name ist das, was Agents und Teamkolleginnen in Chats und Genehmigungen sehen. Deine Locale und dein Theme folgen dir zwischen Geräten. Deine Erinnerungen sind Fakten, die ein Agent über dich vorgeschlagen und du freigegeben hast — getrennt von allem, was Admin oder Redakteur auf Organisationsebene gesetzt hat. Diese Seite zeigt, wo jeder Hebel sitzt und was er ändert. Die Form ist bewusst zweischichtig: das Profilmenü (überall, einen Klick vom Avatar entfernt) trägt die schnellen Schalter; **Einstellungen > Konto** und **Einstellungen > Personalisierung** tragen die tieferen Kontofelder. Alles hier gehört dir — nichts davon lecken zu anderen Mitgliedern oder anderen Organisationen durch. ## Das Profilmenü Klick auf deinen Avatar oben rechts. Das Dropdown öffnet sich mit deinem Namen, deiner E-Mail und der aktuellen Build-Version. Unter dem Kopf sitzen vier Schnellschalter, die jedes Mitglied unabhängig von der Rolle sieht: der Theme-Wechsler (**Systemdesign** / **Helles Design** / **Dunkles Design**), das **Sprach**-Untermenü (English, Deutsch, Français), die Zeile **App installieren**, wenn der Browser Tale als PWA installieren kann, und **Abmelden**. Theme und Sprache greifen sofort und bleiben pro Gerät erhalten. Das Menü trägt außerdem einen Organisationswechsler, wenn du zu mehr als einer Organisation gehörst, und einen Team-Filter, wenn deine aktuelle Organisation Teams hat. Das sind keine Einstellungen — sie ändern, was Tale dir zeigt, nicht wie Tale sich verhält. Unter dem Team-Filter öffnet **Benutzereinstellungen** den Bereich **Einstellungen > Konto**, die nächste Seite hier. ## Konto — Name, E-Mail, Passwort, Zwei-Faktor Öffne **Einstellungen > Konto**. Drei Abschnitte sitzen auf der Seite: **Profil**, **Sicherheit** und **Zwei-Faktor-Authentifizierung**. Der Profil-Abschnitt zeigt zuerst deine **E-Mail**, dann deinen **Namen** — die E-Mail legt den Namen nahe, den Tale vorschlägt und den du frei bearbeiten kannst. Der Name ist inline bearbeitbar; die Änderung speichert und schlägt beim nächsten Render in jedem Chat und jeder Genehmigung durch. Die E-Mail ist schreibgeschützt — sie ist das, womit du dich angemeldet hast, und ein Wechsel läuft über den Support. Es gibt kein Avatar-Feld auf der Seite; Tale leitet einen Avatar aus den Initialen deines Namens ab. Der Sicherheits-Abschnitt hält einen einzelnen Knopf: **Passwort ändern**, wenn du dich mit E-Mail und Passwort registriert hast, **Passwort festlegen**, wenn dein Konto über SSO föderiert ist und du ein Passwort als Rückfall hinzufügen willst. Beide Abläufe erzwingen die Passwort-Richtlinie der Organisation und zeigen die Regeln live, während du tippst, und ein falsches aktuelles Passwort wird direkt am Feld markiert statt als flüchtiger Fehler. Das Ändern deines Passworts meldet dich auf allen Geräten ab — der Dialog warnt dich, bevor du bestätigst, und du meldest dich anschließend mit dem neuen Passwort wieder an. Der Zwei-Faktor-Abschnitt paart das Konto mit einer TOTP-App oder einem Hardware-Schlüssel und zeigt die Backup-Codes einmal bei der Einrichtung. ## Erinnerungen und die Freigabe davor Eine Erinnerung ist eine kurze Tatsache über dich, die ein Agent vorgeschlagen hat und du behalten hast — eine Vorliebe, die du genannt hast, eine Einschränkung, die du ständig wiederholst, ein Kontext, den mitzunehmen sich lohnt. Erinnerungen sind der einzige Teil deines Kontos, in den ein Agent schreiben kann, und genau deshalb geht der Schreibvorgang zuerst über dich. Eine vorzuschlagen tut das Modell, indem es ein Tool aufruft — kein Hintergrundprozess liest dabei deine Gespräche mit. Der Aufruf legt den Eintrag als **ausstehend** an und schreibt zugleich eine Audit-Zeile, denn dauerhaftes Wissen über eine Person vorzuschlagen ist protokollierenswert, noch bevor jemand zustimmt. Ein ausstehender Eintrag bewirkt von sich aus nichts: Er wartet als Vorschlag unter **Einstellungen > Personalisierung**, bis du ihn speicherst oder verwirfst, und nur eine gespeicherte Erinnerung lässt sich je wieder lesen. <Info> Nichts wandert in deinem Namen in einen Prompt. Eine gespeicherte Erinnerung erreicht eine Antwort nur, wenn das Modell danach sucht und die Suche sie zurückgibt — ein Modell kann sich kein dauerhaftes Wissen über dich verschaffen, indem es es aufschreibt, und es kann einen Vorschlag, den du abgelehnt hast, nicht heimlich nachschlagen. </Info> Gespeicherte Erinnerungen stehen auf derselben Seite, jede mit einem Knopf zum Löschen. Eine Erinnerung zu löschen nimmt sie aus dem heraus, was eine Suche zurückgeben kann — mehr Wirkung hat sie nicht, denn es fährt keine zweite Kopie in irgendeinem anderen Prompt mit. ## Abmelden Die Zeile **Abmelden** unten im Profilmenü bestätigt mit einem Dialog, bevor sie die Session löscht. Nach der Bestätigung lädt Tale die Seite zur Anmeldeseite hart neu, damit kein veralteter Zustand im Tab hängenbleibt. Das Abmelden ist pro Gerät — dich auf dem Laptop abzumelden, meldet dich nicht auf dem Handy ab, und umgekehrt. ## Wo das hingehört Einstellungen sind die Linie zwischen dir und dem Rest der Organisation. Der Org-Admin setzt die Standardwerte — die Passwort-Richtlinie, welche Modelle erlaubt sind, welche Governance für einen Chat gilt — und deine Einstellungen überschreiben sie dort, wo Tale es zulässt. Eine persönliche Seite steht abseits dieses Sets: [Umgebungsvariablen & Geheimnisse](/de/platform/member/environment) hält Variablen und Anmeldedaten, die innerhalb einer einzelnen Organisation auf dich begrenzt sind, statt dir über Organisationen hinweg zu folgen — der Ort für den Provider-Schlüssel, den ein BYO-Agent benutzt. Die nächste Lektüre, die sich lohnt, ist [Mitglieds-Übersicht](/de/platform/member/overview) für die Karte des restlichen Mitglieder-Bereichs, oder [Als App installieren](/de/platform/member/install-as-app), wenn du willst, dass Tale in deinem Dock statt in deinen Browser-Tabs lebt. # Mitglied Source: https://tale.dev/docs/de/platform/member/overview Mitglied ist die Standardrolle, die die meisten Personen in den meisten Organisationen tragen. Es ist die Endbenutzer-Oberfläche von Tale — mit Agents chatten, durch die Wissensdatenbank stöbern, in der Inbox einer installierten Automatisierung auf Kontakt-E-Mails antworten, die Genehmigungen entscheiden, die andere zu dir geroutet haben, und Feedback zu Antworten hinterlassen. Mitglieder bauen keine Agents, konfigurieren keine Anbieter, installieren keine Automatisierungen. Sie nutzen das Produkt, das die Redakteure und Entwickler für sie gebaut haben. Diese Übersicht nennt, was ein Mitglied tun kann, und verweist auf die Per-Funktions-Seiten. Mitglieder landen typischerweise zuerst auf Chat; der Rest dieser Seite ist das, was du liest, wenn Chat allein nicht reicht — wenn du wissen willst, woher ein Zitat kam, was eine Genehmigungs-Karte ist oder was ein Projekt bündelt. ## Was Mitglied abdeckt Die Mitglieder-Oberfläche ist bewusst eng. Die vier Kübel sind: - **Chat** — einen Agent (oder keinen) wählen, eine Nachricht senden, die Antwort lesen. Der Chat legt die Skill-Bibliothek, Anhänge, Voice-Modus, Arena-Modus für Seite-an-Seite-Vergleich und die Canvas-Spalte frei, wenn eine Antwort mehr produziert, als der Chat inline halten kann. - **Wissen** — Dokumente, Kontakte, Produkte, Lieferanten, Websites durchstöbern, die die Organisation geladen hat. Nur-Lese für Mitglieder; das Kuratieren passiert auf der Redakteur-Seite. - **Inbox** — im Tab **Inbox** antworten, den eine installierte E-Mail-Automatisierung hinzufügt. Mitglieder antworten, wenn ein Agent eine Konversation zurückgibt; die Automatisierung selbst zu installieren ist eine Admin-Aktion. - **Genehmigungen** — die Genehmigungs-Karten lesen, die zu dir geroutet wurden. Klick auf Genehmigen, Ablehnen oder Änderungen anfordern; hinterlass einen Kommentar, wenn die Regel danach fragt. Die Org-Konfigurationseinstellungen — Anbieter, Connectors, Agents, Governance — sind für Mitglieder ausgeblendet; was bleibt, ist zum Großteil die Arbeits-Oberfläche. Die Ausnahme ist eine kleine persönliche Einstellungs-Gruppe, die jede Rolle trägt: Konto, Personalisierung und [Umgebungsvariablen & Geheimnisse](/de/platform/member/environment), die Schlüssel und Variablen, die in die Sandboxes injiziert werden, die du fährst. ## Seiten in diesem Bereich Dieser Bereich ist kurz — die Mitglieder-Oberfläche ist die Querschnittsmenge der Seiten, für die Redakteure bauen und die alle nutzen. Die tiefere Lektüre liegt in den Per-Funktions-Bereichen. <CardGroup cols="2"> <Card title="Chat" icon="message-circle" href="/de/platform/chat/overview"> Der alltägliche Einstieg — Chat, Agents, Anhänge, Zitate. </Card> <Card title="Wissen" icon="library" href="/de/platform/knowledge/overview"> Das Nur-Lese-Fenster in das, was die Organisation geladen hat. </Card> <Card title="Mitgelieferte Automatisierungen" icon="inbox" href="/de/platform/automations/builtin"> Die E-Mail-Automatisierungen, die einen Inbox-Tab hinzufügen — und was jede einzelne tut. </Card> <Card title="Genehmigungen" icon="check-check" href="/de/platform/approvals/concepts"> Was eine Genehmigungs-Karte ist und was jeder Knopf tut. </Card> </CardGroup> ## Wo das hingehört Mitglied ist die Rolle, die konsumiert, was der Redakteur baut und der Admin steuert. Die natürliche Erstlektüre ist [Chat](/de/platform/chat/overview) — dort verbringt jedes Mitglied die meiste Zeit, und die meisten anderen Mitglieder-Oberflächen fächern sich von einem Chat aus, der mehr tun wollte. # Projekt-Backlog Source: https://tale.dev/docs/de/platform/projects/backlog Eine Aufgabe im Status **`backlog`** ist vorgeschlagene Arbeit, für die sich noch niemand verpflichtet hat — meist eingespeist von einer Automatisierung wie [GitHub-Issues sichten](/de/platform/automations/builtin). Sie liegt in der **linken Spalte** auf dem Board und im **obersten Abschnitt** in der Liste, mit derselben Karte, demselben Detail-Sheet, demselben Status-Picker und demselben Zuweisungs-Picker wie jeder andere Status. [Aufgaben-Automatisierung](/de/platform/projects/task-automation) behandelt, was passiert, sobald eine Aufgabe **Zu erledigen** erreicht und in die Zuweisungs-Schleife eintritt. ## Eine synchronisierte Aufgabe GitHub-Issues sichten schlägt eine Aufgabe pro umsetzbarem offenem Issue vor, verankert am Issue, sodass ein späterer Abgleich sie nie doppelt anlegt: Der Titel lautet `#<Nummer> <Titel>` — zum Beispiel `#482 Login-Button auf Safari verschoben` —, die Beschreibung beginnt mit der eigenen GitHub-URL des Issues, und ihre Labels spiegeln die GitHub-Labels des Issues. Eine Aufgabe, die du vom Board aus mit dem Standardstatus anlegst, startet bei **Zu erledigen**; wähle **Backlog** im Erstellungsformular, wenn du selbst einen Vorschlag ablegen willst. ## Arbeit weiterbewegen Es gibt keine Backlog-spezifischen Buttons. Ziehe eine Karte in eine andere Spalte, öffne das Detail-Sheet und wähle einen neuen Status, oder weise einen Owner zu — dieselben Wege wie bei **Zu erledigen** oder **In Bearbeitung**. Auto-Zuweisung und Zuweisungs-Vorschläge von Agenten laufen nur bei **Zu erledigen**, nicht solange die Aufgabe im **Backlog** liegt. Wenn du einen Vorschlag direkt nach **In Bearbeitung** schiebst oder von Hand zuweist, übernimmst du die Verantwortung selbst. Lehne einen Vorschlag ab wie jede andere Aufgabe: Setze den Status im Picker auf **Abgebrochen**. Eine menschliche Stornierung bleibt bestehen — ein späterer GitHub-Abgleich holt einen abgelehnten Vorschlag nicht zurück, solange das Issue auf GitHub offen bleibt. War eine Aufgabe auf dem Board **Erledigt** und jemand öffnet das Issue auf GitHub wieder, setzt der Abgleich die Aufgabe zurück ins **Backlog**. ## Wo das hineinpasst Backlog ist die Eingangsspalte zwischen einer Automatisierung, die Arbeit vorschlägt, und deinem Team, das sich dazu verpflichtet. Die natürliche nächste Lektüre ist [Aufgaben-Automatisierung](/de/platform/projects/task-automation) für das, was bei **Zu erledigen** passiert, oder [Mitgelieferte Automatisierungen](/de/platform/automations/builtin) dafür, was überhaupt Aufgaben vorschlägt. # Aufgaben-Automatisierung Source: https://tale.dev/docs/de/platform/projects/task-automation Eine Board-Aufgabe einem KI-Agenten zuzuweisen setzt ihn in Bewegung. Wer bei der Aufgabe als **Zuständig** eingetragen ist — eine Person, ein Projekt-Agent oder eine Automatisierung — treibt die Arbeit und die Board-Choreografie; der **Reviewer** ist der benannte Mensch, auf den das fertige Ergebnis wartet. Eine Aufgabe, die eine Automatisierung vorschlägt, liegt im [Backlog](/de/platform/projects/backlog), bis ein Mensch sie startet — von diesem Moment an ist sie eine Board-Aufgabe wie jede andere und tritt in die Schleife unten ein. <Frame caption="Das Aufgaben-Board eines Projekts — eine Karte einem Agenten zuzuweisen startet die Schleife unten."> ![Ein Kanban-Aufgaben-Board im Projekt Website-Relaunch mit sieben Aufgabenkarten, verteilt über seine Status-Spalten, von Backlog und Zu erledigen über In Prüfung bis Erledigt und Abgebrochen.](/images/platform/projects-task-board.webp) </Frame> ## Die Ausführungsschleife 1. **Weise** die Aufgabe einem Agenten zu. Die Karte wandert nach _In Bearbeitung_, und der Agent arbeitet in seiner eigenen Sandbox-Session — mit Beschreibung, Kommentaren und Eingabedateien der Aufgabe als Kontext. 2. Der Agent **meldet sich zurück**: Sein Ergebnis landet als Kommentar an der Aufgabe (Dateien in der Output-Zone), und die Aufgabe parkt auf **_In Prüfung_** — Agenten können nie auf _Erledigt_ stellen; diese Regel setzt der Server durch. 3. Mit dem Parken geht die **Review-Anfrage** raus: Der **Reviewer** der Aufgabe bekommt eine Glocke im Posteingang und eine E-Mail, und im Aufgabenblatt erscheint die Review-Karte — _Wartet auf {name}_. Ist niemand benannt, landet die Anfrage bei der Person, die die Aufgabe angelegt hat (sonst beim Projekt-Ersteller) — ein Abschluss bleibt nie stumm. 4. Ein Mensch **entscheidet auf der Review-Karte**: **Freigeben** schließt die Aufgabe ab — _Erledigt_ wird als Entscheidung dieser Person festgehalten, nie als die des Agenten. **Änderungen anfordern** speichert dein Feedback als Kommentar an der Aufgabe und gibt sie direkt an den Agenten zurück; der startet einen Überarbeitungslauf und parkt das Ergebnis wieder auf _In Prüfung_. Ein fehlgeschlagener Lauf lässt die Aufgabe, wo sie war, und erklärt sich im Aufgabenblatt; starte den Lauf erneut, sobald die Ursache behoben ist. Eine übergeordnete Aufgabe mit offenen Teilaufgaben lässt sich erst schließen, wenn die letzte Teilaufgabe erledigt ist. ## Zuständig und Reviewer Die beiden Rollen sind bewusst getrennte Felder: | Rolle | Wer | Aufgabe | | ------------- | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | **Zuständig** | Person, Agent oder Automatisierung | Treibt die Arbeit und den Board-Status — der eine, polymorphe Zuständige | | **Reviewer** | ein Projektmitglied mit Bearbeitungsrechten | Der benannte Mensch, auf den gewartet wird: erhält die Review-Anfrage, füllt den Filter **Wartet auf mein Review**, entscheidet die Karte | Den Reviewer wählst du im Aufgabenblatt im Feld **Reviewer**. Die Benennung ist bewusst **weich**: Sie steuert Benachrichtigungen und die Warteschlange, aber jedes Projektmitglied mit Bearbeitungsrechten kann weiterhin auf ein Review antworten — und anders als beim Zuständigen darfst du den Reviewer auch ändern, während ein Lauf läuft. Zum Prüfen musst du die Aufgabe nie übernehmen: Agent oder Automatisierung bleiben zuständig, die Choreografie läuft nach der Entscheidung weiter. Das Board benennt die Wartestelle: Karten auf _In Prüfung_ tragen einen Chip **Wartet auf {name}** (bzw. _Wartet auf dein Review_), und der Board-Filter **Review** reduziert das Board auf die Aufgaben, die auf dich warten — deine persönliche Review-Warteschlange im Projekt. ## Erwähnungen **Erwähne einen Agenten mit @** in einem Aufgaben-Kommentar, und er liest den erwähnenden Text und handelt. Ein `@` öffnet eine Autovervollständigung über Mitglieder und die Agenten des Projekts; der Composer zeigt vorab, ob jeder erwähnte Agent wirklich reagiert (Automatisierung aus, Sicherung ausgelöst, im Projekt nicht erwähnbar). Eine Erwähnung des **Zuständigen** gilt als Feedback zu seiner Arbeit: Ein laufender Agent nimmt den Kommentar mitten im Lauf auf, ein untätiger startet einen Überarbeitungslauf, der den Kommentar wortwörtlich mitbekommt. ## Leitplanken Jeder Agenten-Lauf — Zuweisung, Erwähnung, Review-Überarbeitung — passiert dasselbe Zulassungstor: - **Ein Motor pro Aufgabe**: Eine Aufgabe mit laufendem Lauf lehnt einen zweiten ab, und eine Neuzuweisung mitten im Lauf wird verweigert (erst abbrechen — der Picker bietet Abbrechen-und-neu-zuweisen an). - **Parallelität**: Agent-Sessions schöpfen aus der Kapazität der Organisation; überzählige Läufe reihen sich ein und starten, sobald ein Platz frei wird. - **Sicherung pro Aufgabe**: Zu viele automatische Läufe innerhalb einer Stunde auf einer Aufgabe pausieren die Automatisierung dort, bis ein Mensch ihren Status ändert. ## Den Zuständigen wählen Nicht jede Aufgabe gehört auf einen Coding-Harness. Als Faustregel: | Aufgabentyp | Zuweisen an | | ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | | Recherche, Texte, Zusammenfassungen, persönliche Ergebnisse | Eine **Person** | | Board-Arbeit, die ein bereitgestellter Desk treibt | Eine **Automatisierung** — ihr Desk treibt dann die Status-Verben des Boards, und die Prüfung findet im Subjekt-Panel der Aufgabe statt | | Repository-Arbeit — Bugs, Features, Refactorings, PRs | Einen **Agenten** auf einem Coding-[**Harness**](/de/platform/agents/harnesses) — angelegt im Agents-Tab des Projekts mit dem Harness, der zur Arbeit passt | Der Zuständigen-Picker gruppiert **Agenten** und **Automatisierungen**. Jeder Agent läuft in einer Sandbox auf dem **Harness**, der bei seiner Erstellung gewählt wurde — vorab ausgestattet mit seinen Skills, Konnektoren und Anweisungen. ## Der Notausschalter Die Governance-Richtlinie `task_automation` trägt den Hauptschalter: Ausschalten stoppt den Startpfad — laufende Arbeit endet regulär, Neues startet nicht. Nur Admins dürfen das, und es wird auditiert; auf einer selbst gehosteten Instanz ist die Richtlinie eine der Governance-Konfigurationsdateien der Organisation, neben den Limits auf [Richtlinien und Limits](/de/platform/admin/governance/policies-and-limits). ## Wo das hingehört Aufgaben-Automatisierung macht aus dem Projekt-Board eine Delegationsfläche statt einer To-do-Liste: Ein Mensch weist zu, ein benannter Mensch prüft, der Agent erledigt alles dazwischen — und _Erledigt_ bleibt eine menschliche Entscheidung. Als Nächstes lohnt sich [Backlog](/de/platform/projects/backlog): wie vorgeschlagene Arbeit in die Schleife gelangt. # Projekt-Agenten Source: https://tale.dev/docs/de/platform/projects/project-agents Der Tab **Agenten** eines Projekts ist seine Crew: benannte Agenten, die du einmal konfigurierst und denen du dann Arbeit zuweist — jeder kombiniert ein Coding-[Harness](/de/platform/agents/harnesses), ein Modell, Skills und Connectors sowie stehende Anweisungen. Der Chat läuft weiter über den eingebauten Assistenten — diese Agenten sind für das Board da: Weise einem eine Aufgabe zu, und er arbeitet in einer isolierten Sandbox und meldet sich zur Prüfung zurück. Verwalten kann sie, wer das Projekt bearbeiten darf; ein Projekt fasst bis zu 50. <Frame caption="Der Tab Agenten — die eigenen Agenten des Projekts; jede Zeile nennt Agent-Laufzeit, Provider und Modell."> ![Der Tab Agenten eines Projekts mit benannten Agenten, jeweils mit Agent-Laufzeit, Provider, Modell-ID und Ausrüstungszahl.](/images/platform/project-agents-models.webp) </Frame> ## Einen Agenten anlegen <Steps> <Step title="Tab öffnen und loslegen"> Öffne den Tab **Agenten** des Projekts und klicke auf **Neuer Agent**. Gib unter **Name** einen Namen, den dein Team auf Aufgabenkarten wiedererkennt, und wähle die **Agent-Laufzeit** — die Coding-CLI, auf der der Agent läuft. </Step> <Step title="Modell wählen — und damit den Provider"> Die Liste unter **Modell** ist durchsuchbar; ein Modell, das mehrere Provider anbieten, erscheint einmal pro Provider, mit dem Provider unter jedem Eintrag. Die Wahl ist exakt: Die Läufe des Agenten rufen dieses Modell über diesen Provider auf — und die Kosten landen auf dessen Zugang. Kann der gewählte Provider das Modell nicht mehr bedienen, schlägt der Lauf mit der Begründung fehl, statt still auf die Rechnung eines anderen Providers auszuweichen. Abo-Einträge — etwa ein Claude-Abo — erscheinen nur, solange die **Agent-Laufzeit** das Harness ist, das dieses Abo antreibt; ein Lauf darauf authentifiziert sich mit dem Abo des Anbieters statt mit einem API-Schlüssel der Organisation. </Step> <Step title="Ausrüsten und Anweisungen setzen"> **Skills, Connectors & Tools** bestimmen, was der Agent jenseits seines Workspace erreicht; die Liste folgt dem Team-Zugriff des Projekts, nicht deiner persönlichen Sichtbarkeit. Skills stellen Referenz-Bundles in die Sandbox, Connectors vermitteln einen verbundenen Dienst, und **Plattform-Tools** lassen den Agenten die eigenen Daten deiner Organisation lesen und schreiben — Aufgaben, Kontakte, Produkte, Dokumente und Wissen finden und lesen und, wenn du ein Schreib-Tool gibst, Aufgaben erstellen, kommentieren, zwischen Spalten verschieben, ein externes Element mit einer Aufgabe abgleichen oder ein Dokument speichern. Ein Schreib-Tool ist mit _Schreibt Daten_ markiert: Das Gewähren ist die Berechtigung, ein Agent mit `Aufgaben erstellen` legt also ohne weitere Freigabe echte Aufgaben an. Lesen und Schreiben bleiben auf das Projekt beschränkt — ein Agent sieht nie das Board eines anderen Projekts. **Secrets** geben dem Agenten einen API-Schlüssel als Umgebungsvariable — der Ausweg für einen Dienst ohne Connector. Lege eines an (ein Name wie `GLITCHTIP_TOKEN` und das Token), und der Agent erhält es in seiner Shell und ruft die API dieses Dienstes direkt auf, mit der Doku des Anbieters. Der Wert wird verschlüsselt gespeichert und nie wieder angezeigt; hinterlege nur gering privilegierte, rotierbare Tokens, denn der laufende Agent kann sie lesen. Secrets gehören der Organisation, dasselbe wird also über mehrere Agenten hinweg genutzt und an einer Stelle rotiert. **Anweisungen** reisen bei jedem Lauf als stehende Anweisung mit — was dieser Agent verantwortet, wie er arbeiten soll und welche Grenzen er einhalten muss. </Step> </Steps> Klicke auf **Agent erstellen**. Die Zeile nennt Agent-Laufzeit, Provider, Modell und die Ausrüstungszahl — dieselbe Zusammenfassung, die dein Team beim Zuweisen sieht. ## Arbeit zuweisen Weise dem Agenten eine Board-Aufgabe zu und klicke auf der Aufgabe auf **Agent starten**. Der Lauf arbeitet in einer isolierten Sandbox mit einem stehenden Workspace, der über die Aufgaben des Agenten hinweg bestehen bleibt, schreibt seinen Bericht als Kommentar an die Aufgabe zurück, hängt erzeugte Dateien als **Ergebnisdateien** an und parkt die Aufgabe **In Prüfung** — Agenten schließen keine Arbeit ab; das tut ein Mensch. Kommentiere die Aufgabe und erwähne den Agenten mit @, um einen laufenden Lauf zu lenken — oder einen frischen zu starten, der deinen Kommentar zuerst liest. [Aufgaben-Automatisierung](/de/platform/projects/task-automation) beschreibt die Board-Schleife von Anfang bis Ende. ## Ändern oder entfernen Änderungen greifen ab dem nächsten Lauf — ein laufender behält die Konfiguration, mit der er gestartet ist; erst der nächste Lauf übernimmt deine Änderungen. Löschst du einen Agenten, behalten alle Aufgaben ihre Historie; nur die Zuweisung wird leer. ## Chat-Assistent oder Projekt-Agent? | Nimm… | wenn die Arbeit… | | --------------------- | ----------------------------------------------------------------------------------------------- | | den Chat | ein Gespräch ist — Fragen, Entwürfe, Recherche; das erledigt der eingebaute Assistent. | | einen Projekt-Agenten | eine Aufgabe ist — Repo- oder Dateiarbeit auf einem Harness, erledigt von einer stehenden Crew. | ## Wo das hingehört Der Agent bündelt projektseitig, was andere Seiten erklären: Der Harness-Katalog und seine Fähigkeiten stehen unter [Harnesses](/de/platform/agents/harnesses); welche Provider und Zugänge die Modelle bedienen — hinterlegte Schlüssel über das gemessene Gateway oder Anbieter-Abos auf dem Konto des Anbieters — ist Sache von [KI-Anbieter](/de/platform/admin/providers). # Projekt-Konzepte Source: https://tale.dev/docs/de/platform/projects/concepts Ein Projekt ist die Einheit, zu der Tale greift, wenn ein Arbeitsvorhaben dieselben Dateien, dieselben Anweisungen und dieselben Arbeitsflächen über viele Chats und viele Personen hinweg braucht. Diese Seite gibt dir das mentale Modell — lies sie, bevor du dein erstes Projekt erstellst, und komm zurück, wenn du entscheidest, ob ein wachsender Chat in eines befördert werden soll. <Frame caption="Der Tab Allgemein — Identität, Freigabe und die Statistik-Leiste sind die Eingangstür des Projekts."> ![Der Tab Allgemein des Projekts Website-Relaunch mit den Feldern für Name und Beschreibung, dem Freigabe-Bereich, in dem Organisationsweit als verantwortliches Team steht, und einer Statistik-Leiste, die zwei Dateien, keine Chats und Organisationsweit zeigt.](/images/platform/project-general-tab.webp) </Frame> ## Was ein Projekt besitzt **Chats**, die im Projekt gestartet werden, tragen seinen Kontext automatisch. Sie bleiben deine, bis du an einem Chat **Mit Projekt teilen** umlegst — der Chats-Tab teilt sich entsprechend in **Deine Chats** und **Mit Projekt geteilt**. Das Teilen eines Chats blendet deine persönlichen Erinnerungen und Anweisungen aus den Antworten aus, die andere Mitglieder sehen. **Anweisungen** sind Kontext, der für jeden Chat im Projekt gilt — die Rahmung, die Randbedingungen und das Vokabular der Arbeit —, damit niemand sie pro Chat neu einfügt. **Dateien** auf dem Tab **Wissen** sind Referenzmaterial, aus dem jeder Chat im Projekt schöpfen kann — abgelegt in einem Ordnerbaum, den du einmal befüllst, statt sie pro Chat neu anzuhängen. Sie bleiben auf dieses Projekt begrenzt und tauchen weder in der org-weiten Bibliothek noch in `@`-Pickern außerhalb davon auf — siehe [Dateien verwalten](/de/platform/projects/manage-files). **Aufgaben** machen das Projekt zu einem Ort, an dem Arbeit läuft, statt nur besprochen zu werden: ein Board mit Status und [Automatisierung](/de/platform/projects/task-automation), mit Kommentar-Threads an jeder Aufgabe für die zugehörigen Entscheidungen. **Agenten** ist die Crew des Projekts: benannte Agenten, jeder mit Agent-Laufzeit, einem Modell samt gewähltem Provider, Ausrüstung und stehenden Anweisungen, bereit, Aufgaben vom Board zu übernehmen ([Projekt-Agenten](/de/platform/projects/project-agents)). ## Erstellen und Identität **Projekt erstellen** fragt nach einem Namen und einem **Projektkürzel** — dem Präfix für Aufgaben-IDs wie `WR-1`. Das Kürzel steht fest; nach dem Erstellen des Projekts lässt es sich nicht mehr ändern. Beschreibung, besitzendes Team, Icon und Farbe bleiben später auf dem Tab **Allgemein** änderbar, wo die vereinheitlichten Buttons **Speichern** und **Verwerfen** in der Tab-Leiste sitzen. ## Das Freigabe-Modell Geteilt wird pro Team, nicht per Einzeleinladung. Ein Projekt steht standardmäßig auf **Organisationsweit**; wählst du ein besitzendes Team, gilt es nur für dieses Team, und weitere Teams kommen auf dem Tab Allgemein dazu. Org-Admins haben immer Zugriff. Umbenennen, Archivieren und Löschen liegen im Zeilenmenü der Projektliste — beim Löschen fragt Tale, was mit dem Inhalt passiert: Dateien und Chats lösen (sie werden zu Bibliotheksdokumenten und persönlichen Chats) oder sie mitlöschen. ## Wann du danach greifst | Nimm … wenn | Projekt | Einzel-Chat | | ----------------------------------------------------------- | ------- | ----------- | | Dieselben Dateien gelten über viele Chats | ✓ | | | Dieselben Anweisungen gelten über viele Chats | ✓ | | | Mehrere Personen arbeiten am selben Vorhaben | ✓ | | | Die Arbeit hat Aufgaben, Verantwortliche und Entscheidungen | ✓ | | | Die Frage ist einmalig | | ✓ | Ein Einzel-Chat ist die richtige Form, um eine Antwort einmal zu erkunden. In dem Moment, in dem der Kontext den Chat überleben soll, zieh um — die Chat-Aktion **In Projekt verschieben…** trägt einen bestehenden Chat in ein Projekt. ## Wo das hingehört Projekte sind die Naht, an der Chats, Wissen und Aufgaben-Automatisierung zusammentreffen. Die natürliche nächste Lektüre ist [Projekte nutzen](/de/tutorials/member/use-projects) — ein frisches Projekt von Anfang bis Ende; die Tab-Seiten in diesem Bereich vertiefen [Dateien](/de/platform/projects/manage-files) und [Agenten und Modelle](/de/platform/projects/project-agents). # Projekt-Dateien verwalten Source: https://tale.dev/docs/de/platform/projects/manage-files Der **Wissen**-Tab eines Projekts ist der geteilte Dateibereich, den jeder Chat im Projekt erreichen kann. Lade eine Datei einmal hoch, und jeder Chat im Projekt — und jeder Agent, der darin läuft — kann sie ohne erneutes Hochladen lesen. Diese Seite deckt den Ordnerbaum, den Upload-Mechanismus, das Anheften und die Grenzen ab. Der Wissen-Tab ist nicht die org-weite Wissensdatenbank im Sinn von [Dokumente](/de/platform/knowledge/documents). Seine Dateien sind auf ein Projekt begrenzt und tauchen weder in der org-weiten Bibliothek noch in `@`-Pickern ausserhalb des Projekts noch über WebDAV auf; das Projekt zu löschen löscht die Dateien. Für org-weites Referenzmaterial nutz [Dokumente](/de/platform/knowledge/documents) und bind sie an Agents. <Frame caption="Der Wissen-Tab — der Dateibaum des Projekts; jede Datei bleibt auf dieses Projekt begrenzt und ist für die Suche indexiert."> ![Der Wissen-Tab des Projekts Website relaunch mit zwei indexierten Dateien im Dateibaum, einem Neuer-Ordner-Button und der Dropzone zum Hinzufügen von Dateien.](/images/platform/project-knowledge-files.webp) </Frame> ## Ordner Projekt-Dateien liegen in einem Ordnerbaum. **Neuer Ordner** legt einen Ordner auf der Wurzelebene an; das Ordner-Plus-Symbol auf einer Ordnerzeile erstellt einen Unterordner. Klick einen Ordner an, um ihn auszuwählen — der Drop-Bereich wechselt zu _Datei zu „…" hinzufügen_ und Uploads landen darin. Einen Ordner zu löschen löscht alles darin, inklusive der Einträge im Retrieval-Index; die Bestätigung sagt das, bevor irgendetwas passiert. Ordner hier sind projekt-gebunden: ein gleichnamiger Ordner in der org-weiten Dokumentbibliothek ist ein anderer Ordner. ## Ein durchgespielter Upload Öffne das Projekt, klick **Wissen**, wähl den Zielordner (oder keinen für die Wurzel) und zieh Dateien auf den Drop-Bereich. Die Zeile erscheint im Baum und löst zu **Indexed** auf, sobald das Retrieval sie aufgenommen hat. Derselbe Upload ist nun aus jedem Chat erreichbar, den das Projekt besitzt: Sende eine Nachricht, die das Thema referenziert, und der Agent ruft sie ab — oder tippe `@` im Chat und hefte die Datei oder gleich einen ganzen Ordner an den Turn. ## Ersetzen und Löschen Eine Datei zu ersetzen lädt eine neue Kopie unter demselben Namen hoch; die frühere Version wandert in die Versions-History des Projekts. Zitate aus früheren Chats verweisen weiterhin auf die Version, die aktiv war, als der Chat sie referenzierte. Eine Datei zu löschen entfernt sie sofort aus dem Picker; bestehende Chats behalten ihre Zitate, aber die darunterliegende Datei wird mit dem Rest der Aufbewahrungs-Kohorte des Projekts in den [Papierkorb](/de/platform/admin/governance/trash) verschoben. ## Eine Datei als gelenktes Dokument führen Wenn die Freigabe mit genau der Datei verknüpft bleiben muss, die der Reviewer gesehen hat — eine SOP, ein Validierungsplan —, öffne das Zeilenmenü der Datei und klick **Als gelenktes Dokument führen**. Die Zeile trägt danach `v1 · Entwurf` und durchläuft denselben Lebenszyklus wie ein gelenktes Dokument in der org-weiten Bibliothek: **Zum Review einreichen** friert die Datei für einen benannten Reviewer ein, die Freigabe macht die Version unveränderlich, und **Neue Revision** öffnet den nächsten Entwurf. Den vollständigen Lebenszyklus — inklusive Ersetzen der Entwurfsdatei — beschreibt [Dokumente](/de/platform/knowledge/documents#gelenktes-dokument-ueberarbeiten). Am Geltungsbereich ändert das nichts: Eine gelenkte Projekt-Datei bleibt eine Projekt-Datei und ist nur im Projekt sichtbar. ## Grössenlimits Pro-Datei- und Pro-Projekt-Limits werden von der Org unter [Richtlinien und Limits](/de/platform/admin/governance/policies-and-limits) gesetzt. Ein Pro-Datei-Limit zu treffen scheitert den Upload mit einem Toast; ein Pro-Projekt-Limit zu treffen scheitert den Upload mit einem anderen Toast, der die Richtlinie benennt. Mitglieder, die ein Limit treffen, können es nicht selbst anheben — ein Admin justiert die Richtlinie, oder der Projektbesitzer löscht ältere Dateien. ## Auftauchen in Chats Ein Chat, der in einem Projekt gestartet wird, hat automatisch Zugriff auf jede Datei im Wissen-Tab des Projekts. Das Retrieval-Tool des Agents sieht Projekt-Dateien neben jeglichen agent-gebundenen Wissensquellen. Zitate aus Projekt-Dateien sind auf den Chat begrenzt, der sie erzeugt hat — einen Chat ausserhalb des Projekts zu teilen bewahrt die Zitate, aber der Betrachter kann nicht zur Quelle durchklicken, ausser er ist auch im Projekt. Anheften mit `@` verengt einen einzelnen Turn: `@Datei` heftet eine Datei an, `@Ordner` einen Ordner samt allem darunter (der Picker bietet in Projekt-Chats die Ordner des Projekts an, überall sonst die org-weiten Ordner). Angeheftete Dateien werden zusätzlich in die Sandbox des Agents unter `/user/uploads` geliefert — ein Projekt-Agent auf einem Coding-Harness wie Claude Code öffnet also die echten Bytes, statt nur Retrieval-Schnipsel zu zitieren. ## Wo das hineinpasst Dateien verwalten ist die operative Seite für den Wissen-Tab — die konzeptuelle Rahmung liegt in den [Projekt-Konzepten](/de/platform/projects/concepts), und das agent-gebundene Äquivalent über die ganze Org ist [Dokumente](/de/platform/knowledge/documents). Wenn du dich dabei ertappst, dieselben Dateien in viele Projekte erneut hochzuladen, ist das das Signal, sie in die [Dokumente](/de/platform/knowledge/documents) zu verschieben und stattdessen einen Agent daran zu binden. # Projekte Source: https://tale.dev/docs/de/platform/projects/overview Ein Projekt ist ein geteilter Arbeitsbereich, der alles bündelt, was ein Stück Arbeit braucht — die Chats, die Referenzdateien, die Anweisungen und das Aufgaben-Board —, damit der Kontext der Arbeit folgt, statt in jeden Chat neu kopiert zu werden. Wo ein einzelner Chat eine Frage beantwortet, ist ein Projekt der Ort, an dem ein Team einen Kontakt, einen Launch oder eine länger laufende Untersuchung in Bewegung hält. Lieber erst zusehen? Episode 6 geht in knapp drei Minuten durch ein echtes Projekt — samt einer Aufgabe, die ein Agent vor der Kamera übernimmt. <Video src="/videos/de/tutorials/ep6-projects/ep6-projects.de.mp4" poster="/videos/de/tutorials/ep6-projects/ep6-projects.de.webp" captions="/videos/de/tutorials/ep6-projects/ep6-projects.de.vtt" lang="de" title="Episode 6 — Projekte mit KI" caption="Episode 6 — Projekte mit KI (2:47)"> </Video> <Frame caption="Das Aufgaben-Board eines Projekts — einer der acht Tabs, die jedes Projekt trägt."> ![Ein Kanban-Aufgaben-Board im Projekt Website-Relaunch mit sieben Aufgabenkarten, verteilt über die Spalten Backlog, Zu erledigen, In Bearbeitung, In Prüfung, Erledigt und Abgebrochen.](/images/platform/projects-task-board.webp) </Frame> ## Die Teile eines Projekts Jedes Projekt öffnet auf derselben Tab-Leiste: **Allgemein** (Name, Beschreibung, Freigabe und die letzten Chats), **Chats** (deine Chats im Projekt plus die mit ihm geteilten), **Aufgaben** (das Board), **Wissen** (die Dateien des Projekts, in einem Ordnerbaum) und **Agenten** (die eigenen Agenten des Projekts) — dazu **Automatisierungen**, sobald eine an das Projekt gebunden ist, und **Umgebung** für Projekt-Admins. In das Projekt installierte Apps hängen ihre eigenen Tabs dahinter an. ## Seiten in diesem Bereich <CardGroup cols="2"> <Card title="Projekt-Konzepte" icon="compass" href="/de/platform/projects/concepts"> Das mentale Modell — was ein Projekt besitzt, wann es einen Einzel-Chat schlägt und wie die Freigabe funktioniert. </Card> <Card title="Dateien verwalten" icon="folder-open" href="/de/platform/projects/manage-files"> Der Wissen-Tab — Dateien in Ordner hochladen, der Index-Status und wie Projektdateien auf das Projekt begrenzt bleiben. </Card> <Card title="Projekt-Agenten" icon="bot" href="/de/platform/projects/project-agents"> Die eigenen Agenten des Projekts — Agent-Laufzeit, Modell samt Provider, Ausrüstung und stehende Anweisungen — und wie Aufgaben sie an die Arbeit schicken. </Card> <Card title="Aufgaben-Automatisierung" icon="workflow" href="/de/platform/projects/task-automation"> Board-Aufgaben an Agenten übergeben — die Ausführungsschleife, das Review-Gate und die Leitplanken. </Card> <Card title="Backlog" icon="gauge" href="/de/platform/projects/backlog"> Vorgeschlagene Aufgaben, die eine Automatisierung oder ein Teammitglied hereinsynchronisiert hat — mit Starten aufs Board holen oder mit Schließen abhaken. </Card> </CardGroup> ## Wo das hingehört Projekte liegen in der Sidebar neben dem Chat, und die Übergabe ist natürlich: Eine Frage beginnt im Chat, erweist sich als größer als ein Chat und zieht in ein Projekt um — die Chat-Aktion **In Projekt verschieben…** trägt einen bestehenden Chat hinüber. Wenn Projekte neu für dich sind, starte mit den [Projekt-Konzepten](/de/platform/projects/concepts) für das Modell und geh dann [Projekte nutzen](/de/tutorials/member/use-projects) an einem frischen Projekt von Anfang bis Ende durch. # Redakteur Source: https://tale.dev/docs/de/platform/editor/overview Redakteur ist die Bau-Oberfläche von Tale. Während Mitglied die Rolle ist, die das Produkt nutzt, und Admin die Rolle ist, die es steuert, ist Redakteur die Rolle, die die Dinge erstellt, die alle anderen nutzen — Agents, Projekte, Automatisierungen, die Dokumente und strukturierten Daten, die die Wissensdatenbank hält, die Prompts, die fürs Team gespeichert sind. Personen mit Redakteurs-Rolle sehen das volle Set an Bau-Tabs ohne die Admin-Governance-Oberfläche und ohne die nur-Entwickler-Hebel. Diese Übersicht nennt, was ein Redakteur tut, wo er es tut und welche Seiten jeden Teil abdecken. Redakteure landen typischerweise hier am ersten Tag, bauen den ersten nützlichen Agent und das erste Projekt der Organisation aus und kommen wieder auf diesen Tab, wann immer das Nächste gebaut werden muss. Die Rollen- und Berechtigungs-Geschichte hinter den Tabs liegt auf [Mitglieder und Rollen](/de/platform/admin/members-and-roles). ## Was Redakteur abdeckt Die Arbeit eines Redakteurs fällt in vier Bereiche: **Agents** bauen (Anweisungen, Wissensbindungen, Tools, Modelle), die **Wissensdatenbank** kuratieren (Dokumente hochladen, Kontakte, Produkte, Lieferanten, Websites pflegen), **Automatisierungen** verfassen (Workflows mit Triggern, Schritten und Genehmigungs-Gates) und **Projekte** bündeln (Dateimengen, projektgebundene Agents, Projekt-Anweisungen). Jeder davon hat seinen eigenen Ort in Platform; der Redakteurs-Tab ist der Index über sie hinweg. Redakteure teilen die Bau-Oberfläche mit Entwicklern — Entwickler sehen ebenfalls alle vier Bereiche und können alles, was ein Redakteur kann, plus die API- und Connector-Ebene. Greif zu einem Redakteur, wenn die tägliche Arbeit Inhalt und Konfiguration ist; greif zu einem Entwickler, wenn die Arbeit in Code oder externe Systeme übergeht. ## Seiten in diesem Bereich Die Redakteurs-Oberfläche ist dieselbe Oberfläche, die die Per-Bereich-Sektionen von Platform dokumentieren. Was folgt, ist der Index über sie hinweg. <CardGroup cols="2"> <Card title="Agents" icon="bot" href="/de/platform/agents/concepts"> Das Vier-Knöpfe-Mentalmodell, aus dem ein Redakteur jeden Agent baut. </Card> <Card title="Automatisierungen" icon="workflow" href="/de/platform/automations/concepts"> Workflows, Trigger, Schritte, Ausführungen. </Card> <Card title="Wissen" icon="library" href="/de/platform/knowledge/overview"> Der Dokumente- und Strukturdaten-Bereich, den ein Redakteur kuratiert. </Card> <Card title="Projekte" icon="folder-open" href="/de/platform/projects/overview"> Der geteilte Workspace, den ein Redakteur um einen Kontakt oder einen Launch bündelt. </Card> <Card title="Skill-Bibliothek" icon="list-plus" href="/de/platform/workspace/skills"> Die Bundle-Bibliothek, in der ein Redakteur eine wiederkehrende Anleitung über Chats und Agents hinweg wiederverwendbar hält. </Card> </CardGroup> ## Wo das hingehört Redakteur ist die Rolle, von der die meisten Teams mehrere haben — die Personen, die die Bauarbeit machen, die andere Rollen konsumieren. Die natürliche Erstlektüre am ersten Tag ist [Agent-Konzepte](/de/platform/agents/concepts), weil das Vier-Knöpfe-Modell das ist, was jede andere Bau-Seite voraussetzt. Die natürliche Zweite ist [Deinen ersten Agent bauen](/de/tutorials/editor/first-agent-end-to-end) — sie geht die vier Knöpfe Ende zu Ende auf einer frischen Instanz durch. # Dokumente Source: https://tale.dev/docs/de/platform/knowledge/documents Der Dokumente-Tab ist die Dateifläche der Wissensdatenbank. Redakteure laden Dateien hoch, Tale schickt jede durch die Indexierungs-Pipeline — Text extrahieren, chunken, die Chunks einbetten, speichern —, und Agenten, deren Wissens-Umfang das Dokument abdeckt, rufen zur Antwortzeit relevante Passagen ab und zitieren sie. Diese Seite behandelt die Operator-Seite: Hochladen, die Status-Spalte, Team-Bindung, Ordner und den Lebenszyklus eines Dokuments. <Frame caption="Die Dokumente-Tabelle — Größe, Quelle, RAG-Status und Team-Bindung pro Datei."> ![Der Dokumente-Tab des Wissensbereichs mit drei hochgeladenen Textdateien samt Spalten für Größe, Quelle, RAG-Status und Team.](/images/get-started/documents-list.webp) </Frame> ## Hochladen Öffne **Wissen > Dokumente** und klicke auf **Dokumente hochladen** — das Menü bietet **Von deinem Gerät** und **Von Microsoft 365**. Das Upload-Tor akzeptiert die Formate, die den Großteil des Org-Wissens abdecken: PDF, Word (`.doc`, `.docx`), OpenDocument-Text (`.odt`), PowerPoint (`.ppt`, `.pptx`), Excel (`.xls`, `.xlsx`), CSV, reinen Text und Bilder (JPG, PNG, GIF, WEBP). Alles andere wird beim Upload abgewiesen. Hochladen und Indexieren sind zwei getrennte Tatsachen, und die Spalte **RAG-Status** verfolgt die zweite: **Wird indexiert**, während die Pipeline läuft, **Indexiert**, wenn Agenten den Inhalt abrufen können, **Fehlgeschlagen**, wenn die Pipeline auf einen Fehler lief, und **Neuindexierung nötig**, wenn die gespeicherten Chunks veraltet sind. Moderne Formate indexieren; das alte Office-Trio (`.doc`, `.xls`, `.ppt`) lädt hoch und bleibt herunterladbar, zeigt aber **Nicht indexiert** — Agenten kommen an den Inhalt erst heran, wenn du die Datei im modernen Format neu speicherst. ## Gelenktes Dokument überarbeiten Nutze ein gelenktes Dokument, wenn die Freigabe mit genau der Datei verknüpft bleiben muss, die der Reviewer gesehen hat. Ersetzt du die Datei im Entwurf, aktualisiert Tale den bestehenden Datensatz; lädst du eine weitere Datei mit demselben Namen hoch, entsteht weiterhin ein separates Dokument. <Steps> <Step title="Gelenktes Dokument wählen"> Öffne bei einem normalen Upload das Zeilenmenü und klicke auf **Als gelenktes Dokument führen**. Der Datensatz steht danach auf `v1 · Entwurf`. Ein freigegebenes Dokument bietet **Datei ersetzen** und **Neue Revision**. Nutze **Neue Revision** nur, wenn du den nächsten Entwurf ohne Ersatzdatei brauchst. </Step> <Step title="Aktuelle Datei ersetzen"> Öffne das Zeilenmenü eines Entwurfs oder freigegebenen Dokuments und klicke auf **Datei ersetzen**. Wähle eine Datei im selben Format. Ein Entwurf behält seine Revision. Bei einem freigegebenen Dokument erhält Tale die freigegebene Version vN und öffnet Entwurf vN+1 erst, wenn das Ersetzen abgeschlossen ist; brichst du ab oder schlägt der Upload fehl, bleibt vN freigegeben. Ein Legal Hold blockiert beide Wege. <Frame caption="Der Dialog nimmt genau eine Datei im vorhandenen Format des Datensatzes an."> ![Der Dialog „Datei ersetzen" für ein gelenktes Textdokument mit einer Dateiauswahl für dasselbe Format und dem Hinweis, dass freigegebene Versionen im Verlauf bleiben.](/images/platform/controlled-document-replace-file.webp) </Frame> </Step> <Step title="Revision prüfen und einreichen"> Öffne die Dokumentvorschau und prüfe, ob sie die Ersatzdatei zeigt. Öffne dann das Zeilenmenü und klicke auf **Zum Review einreichen**. Die Auswahl bietet nur Mitglieder an, die das Dokument auch öffnen können — eine Projekt-Datei verlangt Bearbeitungszugriff auf das Projekt. Der Entwurf bleibt während der Entscheidung für genau diese Datei gesperrt; der Reviewer wird über die Glocke und per E-Mail benachrichtigt, und die Entscheidung kommt auf demselben Weg zu dir zurück — eine Änderungsanforderung trägt das Feedback des Reviewers, das der Einreichen-Dialog vor deinem nächsten Anlauf ebenfalls zeigt. </Step> </Steps> ## Import aus Microsoft 365 **Von Microsoft 365** importiert aus OneDrive oder SharePoint statt von der Festplatte: wähle Dateien oder Ordner und entscheide dich für einen Import-Modus. **Einmaliger Import** holt die Dateien einmal — sie verhalten sich wie Uploads von der Festplatte. **Synchronisierungsimport** hält die Auswahl synchron: neue Dateien im OneDrive-Ordner erscheinen bei einem späteren Sync-Lauf, geänderte Dateien werden neu indexiert, und an der Quelle gelöschte Dateien verschwinden aus dem Workspace. Beide Modi erhalten die Ordnerstruktur deiner Auswahl. Die Synchronisierung deckt persönliche OneDrive-Ordner ab — eine SharePoint-Auswahl importiert immer einmalig. Um die Synchronisierung zu beenden — bei einem ganzen synchronisierten Ordner oder einer einzelnen synchronisierten Datei — öffne das Menü der Zeile und klicke auf **Synchronisierung beenden**; die importierten Dokumente bleiben im Workspace und werden nicht mehr aktualisiert. Auch das Löschen eines synchronisierten Ordners oder einer einzelnen Datei beendet die Synchronisierung. In allen Fällen bleiben die Dateien in OneDrive unberührt. ## Team-Bindung, Ordner, Quellen Jede Zeile trägt eine Zelle **Teams** — standardmäßig **Organisationsweit**, oder die Teams, die du über **Team zuweisen** im Zeilenmenü wählst. Ein team-gebundenes Dokument ist für Mitglieder und Agenten außerhalb des Teams unsichtbar; das ist der Zugriffshebel der Wissensdatenbank. Projekt-Dateien liegen ganz außerhalb dieses Modells: Der **Wissen**-Tab eines Projekts hält Dateien, die auf dieses eine Projekt begrenzt sind, und sie tauchen weder in dieser Bibliothek noch in ihrer Team-Bindung auf — siehe [Dateien verwalten](/de/platform/projects/manage-files). **Neuer Ordner** hält große Bibliotheken navigierbar, und Connectors bringen ihre eigene Struktur mit: Dokumente aus einem OneDrive- oder SharePoint-Sync landen unter Sync-Ordnern und zeigen ihre Herkunft in der Spalte **Quelle**, was Zitate bis ins Quellsystem nachvollziehbar hält. <Warning> Das Löschen eines Ordners löscht jede Datei und jeden Unterordner darin endgültig. Das Löschen eines OneDrive-Sync-Ordners entfernt auch dessen Auto-Sync-Konfiguration und -Historie — nie aber die Dateien in OneDrive selbst. </Warning> ## Neu indexieren und löschen **Neu indexieren** (Zeilenmenü) lässt die Pipeline erneut über die gespeicherte Datei laufen — der richtige Zug nach einem Indexierungsfehler oder wenn ein Dokument **Neuindexierung nötig** zeigt. **Löschen** entfernt das Dokument und seine indexierten Chunks; die Bestätigung sagt es unumwunden — die Aktion lässt sich nicht rückgängig machen. Dieselbe Datei erneut hochzuladen bringt den Inhalt als frisches Dokument zurück. Ein gelenktes Dokument lässt sich nicht mehr löschen, sobald irgendeine Version freigegeben wurde — im Review, freigegeben oder mit offenem nächsten Entwurf zeigt der Menüeintrag stattdessen **Geschütztes gelenktes Dokument**, und ein Ordner mit so einem Datensatz verweigert das Ordner-Löschen genauso. Der freigegebene Stand ist ein aufbewahrtes Dokument; genau dafür gibt es den Lebenszyklus. Jedes Dokument zeigt einen Status: **In Warteschlange** (wartet — eine ausgelastete Organisation indexiert einige Dateien gleichzeitig, der Rest reiht sich ein), **Wird indexiert**, **Indexiert**, **Fehlgeschlagen** oder **Nicht unterstützt** (ein Altformat wie `.doc`/`.ppt`/`.xls`, das sich problemlos speichern und herunterladen lässt, aber keinen Text-Extraktor hat und daher nie für die Suche indexiert wird). Ein durch ein Zeitlimit oder einen Backend-Neustart unterbrochener Indexierungsvorgang erholt sich innerhalb weniger Minuten von selbst — er wird wiederholt oder als **Fehlgeschlagen** mit Wiederholen-Option markiert, nie steckengelassen. Wenn deine Organisation ein Speicher-Kontingent pro Nutzer durchsetzt, zählen fehlgeschlagene und nicht unterstützte Dateien weiterhin dagegen, bis sie gelöscht werden — Platz schaffen heißt also, nicht mehr benötigte Dateien zu entfernen. Ein Klick auf ein Dokument öffnet die Vorschau, mit einer Seitenleiste für Größe, Quelle, RAG-Status, Teams, hochladende Person und Änderungsdatum — der schnellste Weg zu prüfen, worauf ein Zitat wirklich zeigt. ## Dokumente gegenüber strukturierten Daten Dokumente sind die unstrukturierte Hälfte der Wissensdatenbank. Ist der Inhalt eine Liste gleichartiger Dinge mit denselben Feldern — Kontakte, Produkte, Zulieferer —, dient ein typisierter Datensatz den Agenten besser als ein hochgeladenes Tabellenblatt: exakte Werte statt abgerufener Passagen. Die Entscheidungsregeln stehen in [Strukturierte Daten](/de/platform/knowledge/structured-data). ## Wo das hingehört Dokumente sind die meistgenutzte Ecke der Wissensdatenbank — die meisten Zitate in den meisten Antworten zeigen hierher. Die Abrufseite — wie der Wissens-Umfang eines Agenten entscheidet, was er durchsucht — ist [Agent-Wissen](/de/platform/agents/knowledge); die faktengroße Schwesterfläche sind die [Wissenseinträge](/de/platform/knowledge/knowledge-entries), die dieselbe Pipeline dokumentweise nutzen. # Strukturierte Daten Source: https://tale.dev/docs/de/platform/knowledge/structured-data Tales Wissensdatenbank führt zwei Formen nebeneinander. Dokumente sind Text, aus dem der Agent Chunks abruft; strukturierte Datensätze sind typisierte Zeilen, aus denen der Agent Felder liest. Die Form, die du wählst, ist die wichtigste Entscheidung dafür, wie ein Agent dein Wissen nutzt — liegst du falsch, verwässert der Agent entweder eine klare Antwort oder rät bei einem Wert, den du längst vorliegen hast. Diese Seite gibt dir das mentale Modell dafür, wann welche Form die richtige ist. Lies sie, bevor du einen Ordner voller Dateien lädst; komm zurück, wenn du versucht bist, eine Tabelle als PDF hochzuladen. ## Dokumente gegenüber strukturierten Datensätzen Ein Dokument ist frei geformt: Die Indexierungs-Pipeline extrahiert Text, chunked ihn, bettet die Chunks ein und serviert zur Antwortzeit Passagen über den Abruf. Der Agent sieht Passagen und zitiert sie nach Quelle. Das ist die richtige Form, wenn der Inhalt Prosa ist — Verträge, Handbücher, Wissensdatenbank-Artikel, Meeting-Notizen. Ein strukturierter Datensatz ist typisiert: Die Entität hat bekannte Felder (ein Kontakt hat einen Namen, eine E-Mail, eine Branche; ein Produkt hat eine SKU, einen Preis, einen Bestand). Der Agent liest die Felder direkt, verknüpft über Entitäten hinweg und antwortet mit dem Wert. Das ist die richtige Form, wenn die Quelle eine Datenbankzeile ist — Konten, Bestellungen, Teile, Lieferantendaten. ## Die vier eingebauten Entitäten Vier strukturierte Tabs sitzen im Wissensbereich neben **Dokumente** und **Wissenseinträge**: - **Kontakte** — die Menschen und Organisationen, mit denen du Geschäfte machst. - **Produkte** — die Dinge, die du verkaufst. - **Lieferanten** — die Zulieferer, bei denen du einkaufst. - **Websites** — öffentliche Seiten, die ein Crawler nach Zeitplan holt; der Datensatz hält Domain und Scan-Einstellungen, die indexierten Seiten halten den Inhalt ([Crawling](/de/platform/knowledge/crawling)). Strukturierte Datensätze teilen die Team-Bindungshebel der Wissensdatenbank: Ein team-gebundener Datensatz ist außerhalb des Teams genauso unsichtbar wie ein team-gebundenes Dokument. ## Content-Modelle für eigene Formen Wenn die vier eingebauten Entitäten nicht passen, definierst du mit Content-Modellen einen eigenen strukturierten Datensatztyp: die Entität benennen, ihre Felder deklarieren, Zugriff pro Feld setzen — und der neue Typ erscheint neben den eingebauten. Die Definitionen liegen bei den [Content-Modellen](/de/platform/admin/governance/content-models) der Governance. <Note> Content-Modelle kosten Governance-Aufmerksamkeit — Zugriff und Aufbewahrung jedes Feldes liegen bei dir. Greif dazu, wenn die Daten wirklich eine neue Form sind, nicht eine leichte Variante einer der vier eingebauten. </Note> ## Alles zusammen — ein CRM-Agent Ein CRM-Agent, der „Wo stehen wir mit Acme?“ beantwortet, nutzt beide Formen. Die Entität Kontakte hält den kanonischen Datensatz — Name, Hauptkontakt, Branche, Status. Dokumente halten die Gesprächsnotizen und Verträge. Der Agent liest die Felder des Kontakts direkt, ruft Passagen aus den Dokumenten ab und antwortet mit beidem: dem strukturierten Status aus Kontakten, dem jüngsten Kontext aus der letzten Gesprächsnotiz. Ohne strukturierte Datensätze muss der Agent Acme namentlich über PDFs hinweg suchen und riskiert, zwei ähnlich benannte Kontakte zu verwechseln. Ohne Dokumente kennt der Agent Acmes Status, kann dir aber nicht sagen, was im Gespräch am Dienstag passiert ist. ## Wann du wozu greifst | Nimm … wenn | Dokumente | Strukturierter Datensatz | | ------------------------------------------------------------------ | --------- | ------------------------ | | Die Quelle ist freie Prosa | ✓ | | | Die Quelle hat typisierte Felder und du willst exakte Werte zurück | | ✓ | | Du musst über viele Datensätze hinweg verknüpfen | | ✓ | | Der Agent soll Passagen nach Fundstelle zitieren | ✓ | | ## Wo das hingehört Strukturierte Daten sind die Naht zwischen deinen operativen Daten und der Agenten-Fläche. Nimm die vier eingebauten Entitäten für das, was sie abdecken; greif zu [Content-Modellen](/de/platform/admin/governance/content-models), wenn eine fünfte Form auftaucht. Die nächste Lektüre, die sich lohnt, ist [Dokumente](/de/platform/knowledge/documents) — die Indexierungs-Pipeline, die die unstrukturierte Hälfte bedient. # Wissenseinträge Source: https://tale.dev/docs/de/platform/knowledge/knowledge-entries Wissenseinträge sind die Faktenfläche der Wissensdatenbank. Wo ein Dokument eine ganze Datei trägt, trägt ein Eintrag einen kleinen, haltbaren Fakt — „Der Laden öffnet um 9“, „Das Rückgabefenster beträgt 3 Tage“ —, abgelegt unter einem Themennamen. Einträge fahren auf derselben Indexierungs-Pipeline wie Dokumente, jeder Agent mit passendem Umfang ruft sie also ab und zitiert sie wie jede andere Quelle; besonders macht sie, wie sie hereinkommen und wie Korrekturen ersetzen, was sie korrigieren. <Frame caption="Der Wissenseinträge-Tab — Thema, Inhalt, Quelle und Indexierungsstatus pro Fakt."> ![Der Wissenseinträge-Tab mit drei von Hand hinzugefügten Fakten, jeder mit dem Quellen-Tag Manuell und dem Status-Badge Indexiert.](/images/platform/knowledge-entries-list.webp) </Frame> ## Woher Einträge kommen **Aus dem Chat, mit deiner Freigabe.** Agenten mit aktiviertem Wissens-Schreib-Tool können vorschlagen, einen Fakt zu speichern, den du im Chat genannt oder korrigiert hast. Der Vorschlag erscheint als Karte im Chat — **In Wissensdatenbank speichern**, mit dem Thema und dem vollen Inhalt; existiert das Thema bereits, wird die Karte zu **Wissensdatenbank aktualisieren** und warnt, dass die Freigabe den bestehenden Eintrag ersetzt. Nichts landet, bevor du auf **Genehmigen** klickst; **Ablehnen** verwirft den Vorschlag. <Note> Das Tool ist standardmäßig aus — aktiviere es pro Agent in den Tool-Einstellungen des Agenten. Ein Agent kann nie in das geteilte Wissen der Org schreiben, ohne dass ein Mensch den exakten Text abgesegnet hat. </Note> **Von Hand.** Klicke unter **Wissen > Wissenseinträge** auf **Eintrag hinzufügen**. Gib ein **Thema** (bis zu 120 Zeichen — kurz und stabil, wie eine Überschrift) und den **Inhalt** als Markdown (bis zu 8000 Zeichen), so geschrieben, dass er ohne umgebendes Gespräch verständlich ist. Die Spalte **Quelle** hält die zwei Herkünfte auseinander: **Chat** oder **Manuell**. ## Eine aktive Version pro Thema Themen sind der Dedup-Schlüssel: Ein freigegebener Chat-Vorschlag für ein bestehendes Thema oder eine Bearbeitung ersetzt die aktive Version, statt eine zweite daneben zu stellen — die Wissensdatenbank serviert nie zwei Versionen desselben Fakts. Einen neuen Eintrag unter einem bestehenden Thema anzulegen wird mit einem Duplikat-Fehler abgewiesen; bearbeite stattdessen den bestehenden Eintrag. Ersetzte Versionen gehen nicht verloren. Öffne einen Eintrag für seine Details — Indexierungsstatus, letzte Aktualisierung und den **Versionsverlauf** mit jeder abgelösten Version und dem Zeitpunkt der Ablösung. Nur die aktive Version ist für den Abruf indexiert; der Verlauf existiert für Audit und Nachschlagen. ## Bearbeiten, Indexieren, Löschen Bearbeiten erzeugt eine neue aktive Version und indexiert im Hintergrund neu — das **Status**-Badge fällt kurz in die Indexierung und kehrt zu **Indexiert** zurück, sobald die Suche den neuen Text aufgenommen hat. Löschen entfernt den ganzen Eintrag: Die Bestätigung warnt, dass er auch aus der Wissensdatenbank verschwindet, Agenten ihn also nicht mehr finden, und dass sich die Aktion nicht rückgängig machen lässt. War der Fakt richtig, füge ihn neu hinzu. ## Wo das hingehört Wissenseinträge schließen die Schleife zwischen Gesprächen und der Wissensdatenbank: Eine einmal im Chat gemachte Korrektur wird ein Fakt, den jeder Agent abruft — ein Mensch gibt den exakten Wortlaut frei, und eine aktive Version pro Thema garantiert, dass der alte Fakt verschwindet, sobald der neue landet. Für die dateiförmige Hälfte lies [Dokumente](/de/platform/knowledge/documents); wie Agenten binden und abrufen, steht in [Agent-Wissen](/de/platform/agents/knowledge). # Crawling Source: https://tale.dev/docs/de/platform/knowledge/crawling Eine Website ist die Form der Wissensdatenbank für „eine öffentliche Seite, die der Agent kennen soll“. Du gibst Tale eine Domain und ein Scan-Intervall; der Crawler entdeckt URLs, holt Seiten, extrahiert den Hauptinhalt, chunked und bettet den Text ein und serviert die Chunks zur Antwortzeit genauso wie bei Dokumenten. Brauchst du gezielte Seiten statt einer ganzen Website, übergibst du stattdessen eine URL-Liste — dieselbe Pipeline läuft dann genau über die Seiten, die du nennst. Diese Seite geht durch, was du zwischen dem Hinzufügen einer Domain und den ersten Agenten-Zitaten ihrer Seiten siehst. <Frame caption="Eine Website hinzufügen — im Modus „Gesamte Website“ ist Domain plus Scan-Intervall das ganze Formular."> ![Der Dialog Website hinzufügen auf dem Websites-Tab, der nach einer Domain und einem Scan-Intervall fragt, das standardmäßig auf alle sechs Stunden steht.](/images/platform/websites-add-dialog.webp) </Frame> ## Eine Website hinzufügen Öffne **Wissen > Websites** und klicke auf **Website hinzufügen**. Der **Quellentyp** entscheidet, was die Quelle abdeckt: **Gesamte Website** — der Standard — crawlt alles, was sich auf der Domain entdecken lässt, **URL-Liste** indexiert genau die Seiten, die du einfügst (dazu der nächste Abschnitt). Im Modus Gesamte Website hat der Dialog zwei Felder: **Domain** (zum Beispiel `example.com`) und **Scan-Intervall** — jede Stunde, alle 6 Stunden (der Standard), alle 12 Stunden, täglich, alle 5 Tage, alle 7 Tage oder alle 30 Tage. Tale normalisiert die Domain — `https://`, `www.` und Schrägstriche am Ende sind verkraftbar — und weist alles ab, was sich nicht als Hostname lesen lässt. Klicke auf **Speichern**; der Scheduler nimmt neue Websites beim nächsten Takt auf, der erste Scan startet also binnen Sekunden. <Note> Es gibt kein Auth-Feld und keine Include/Exclude-Pfadliste — der Crawler sieht exakt das, was ein anonymer Besucher sieht. Alles hinter einem Login gehört stattdessen in [Dokumente](/de/platform/knowledge/documents) oder eine [Connector](/de/platform/connectors/overview). </Note> ## Eine URL-Liste hinzufügen Stelle den **Quellentyp** auf **URL-Liste**, wenn du bestimmte Seiten willst statt einer ganzen Website — hier ein Bericht, da eine Preisseite, dazu eine Handvoll PDFs. Füge unter **URLs** eine URL pro Zeile ein; nur diese Seiten werden geholt und indexiert, Links darüber hinaus folgt der Crawler nicht. Die Zeilen dürfen mehrere Websites mischen: Der Dialog gruppiert sie zu einer Quelle pro Website, aus einem Einfügen über drei Domains werden also drei Zeilen. Fügst du für eine Website, die schon eine Liste hat, erneut URLs ein, landen die neuen in der bestehenden Quelle — nichts fällt weg, und das Scan-Intervall wechselt auf deine neue Wahl. Listen scannen im selben Takt wie ganze Websites; ihre Zeilen tragen in der Tabelle das Badge **URL-Liste**. ## Wie URLs entdeckt werden Der Crawler versucht zuerst den kooperativen Weg. Er löst die Startseite auf und geht jede Sitemap durch, die die Website veröffentlicht — `sitemap.xml`, Sitemap-Indizes, gezippte und in der robots-Datei deklarierte Sitemaps — und sammelt so die URL-Liste, die die Website selbst pflegt. Websites mit gesunder Sitemap bekommen vollständige Abdeckung ohne Raten. Fehlt die Sitemap, ist sie kaputt oder leer, fällt der Crawler auf einen Breitensuche-Linklauf von der Startseite zurück: nur Links innerhalb der Domain, externe und Social-Links fallen weg, Navigations- und Footer-Chrome wird vor der Extraktion entfernt. Der Fallback deckt Websites ohne Sitemap ab, erreicht aber nie die Vollständigkeit einer gepflegten Sitemap. Nicht nur Seiten zählen. Verlinkte Dokumente — PDF- und Office-Dateien (`docx`, `xlsx`, `pptx`, `odt`) — werden wie Seiten geholt und indexiert, egal ob der Crawler sie auf einer Website findet oder du sie direkt in einer URL-Liste aufführst. Bilder und gescannte Dokumente ohne eingebetteten Text werden übersprungen: Der Scan merkt sich, dass er nachgesehen hat, und speichert nichts. ## Der Scan-Zeitplan Das Intervall entscheidet, wie oft URLs neu entdeckt und Seiten neu geholt werden. Jeder Scan ist inkrementell: Unveränderte Seiten werden übersprungen, geänderte neu extrahiert und neu eingebettet, neue Seiten kommen dazu, entfernte fliegen aus dem Index. URL-Listen folgen demselben Takt mit festem Bestand — die gelisteten Seiten werden nach Zeitplan neu geholt, Neues wird nicht entdeckt. Agenten, die auf die Website zeigen, sehen den neuen Inhalt beim nächsten Abruf — einen separaten Veröffentlichungsschritt gibt es nicht. ## Die Tabelle lesen Jede Zeile zeigt die Domain (Quellen vom Typ URL-Liste tragen daneben das Badge **URL-Liste**), ihren **Status** — **Inaktiv** zwischen Scans, **Wird gescannt** im Flug, **Aktiv** nach einem erfolgreichen Scan, **Fehler**, wenn der letzte Scan fehlschlug, **Lösche…** während der Entfernung —, den Prozentwert **Indexiert** (Hover zeigt gecrawlte von insgesamt gefundenen Seiten), die letzte **Gescannt**-Zeit und das **Intervall**. Öffne eine Zeile für den entdeckten Titel und die Beschreibung der Website; klicke auf **Seiten anzeigen** für die Seitenliste — jede indexierte URL mit Wortzahl, Chunk-Zahl und letzter Crawl-Zeit, plus ein Suchfeld, das über die indexierten Chunks läuft und damit der schnellste Weg ist zu prüfen, was ein Agent wirklich abrufen würde. ## Wo das hingehört Crawling ist der günstige Weg, eine öffentliche Website in den Agenten-Kontext zu holen: eine Domain — oder eine handverlesene URL-Liste —, ein Takt, und der Rest ist das Problem des Crawlers. Der Preis ist die Grenze des anonymen Besuchers — private Inhalte brauchen [Dokumente](/de/platform/knowledge/documents) oder eine Connector. Wie die Website-Zeilen neben Kontakte, Produkten und Lieferanten stehen, liest du in [Strukturierte Daten](/de/platform/knowledge/structured-data). # Wissen Source: https://tale.dev/docs/de/platform/knowledge/overview Wissen ist der Bereich, in dem die Daten der Organisation liegen, damit Agenten sie lesen und zitieren können. Redakteure kuratieren sie einmal; Agenten rufen zur Antwortzeit darüber ab — deshalb kann ein Agent in Tale mit deiner Realität antworten statt mit den Trainingsdaten des Modells. Der Bereich öffnet auf sechs Tabs: **Dokumente**, **Wissenseinträge**, **Websites**, **Produkte**, **Kontakte** und **Lieferanten**. Lieber erst zusehen? Episode 3 geht die ganze Bibliothek in gut drei Minuten durch — Indexierung, Einträge, Datensätze, Crawler und Zugriff, mit Untertiteln. <Video src="/videos/de/tutorials/ep3-knowledge/ep3-knowledge.de.mp4" poster="/videos/de/tutorials/ep3-knowledge/ep3-knowledge.de.webp" captions="/videos/de/tutorials/ep3-knowledge/ep3-knowledge.de.vtt" lang="de" title="Episode 3 — Wissen" caption="Episode 3 — Wissen (3:22)"> </Video> <Frame caption="Der Dokumente-Tab — die meistgenutzte Ecke der Wissensdatenbank."> ![Der Dokumente-Tab des Wissensbereichs mit drei hochgeladenen Textdateien samt Spalten für Größe, Quelle, RAG-Status und Team.](/images/get-started/documents-list.webp) </Frame> ## Die zwei Formen Alles in diesem Bereich hat eine von zwei Formen. **Indexierte Inhalte** — die Dateien in Dokumente, die Fakten in Wissenseinträge, die Seiten, die ein Website-Crawl hereinholt — laufen durch die Indexierungs-Pipeline (extrahieren, chunken, einbetten, speichern), damit Agenten relevante Passagen abrufen und zitieren. **Typisierte Datensätze** — Produkte, Kontakte, Lieferanten — sind Zeilen mit benannten Feldern, die Agenten als Daten lesen, nicht als Prosa: exakte Werte, kein Abruf-Rätselraten. Die Form, die du wählst, entscheidet, wie ein Agent den Inhalt nutzen kann — deshalb ist [Strukturierte Daten](/de/platform/knowledge/structured-data) eine Entscheidungsseite, nicht nur eine Referenz. ## Wo der Index liegt Indexierte Inhalte werden in Tales eingebaute Vektordatenbank eingebettet — einen **PostgreSQL**-Speicher (ParadeDB), der `pgvector`-Embeddings mit Keyword-Suche (BM25) kombiniert und beide fusioniert, sodass die Suche sowohl semantische Treffer als auch exakte Begriffe erfasst. Er kommt mit der Plattform, es gibt also nichts zusätzlich zu lizenzieren oder zu betreiben, und Suche, Zitate, team-bezogene Berechtigungen und DSGVO-Löschung arbeiten alle auf einem Speicher. Embeddings stammen vom konfigurierten **Embedding-Modell** der Organisation — ein Org-Admin wählt Anbieter, Modell und Vektorbreite unter **Einstellungen > Datenresidenz**, und die Wissenssuche verweigert mit einem konkreten Hinweis, bis eines eingerichtet ist, statt ein Modell zu raten. **Bring deine eigene Vektordatenbank mit — es ist Postgres.** Weil der Vektorspeicher PostgreSQL ist, kannst du Tales Wissensdatenbank statt auf die mitgelieferte auf jedes von dir betriebene verwaltete PostgreSQL zeigen (mit den Erweiterungen `pgvector` und `pg_search`/ParadeDB) — deine Daten, deine Infrastruktur, deine Region. Ein Org-Admin richtet die Verbindung unter **Einstellungen > Datenresidenz** ein — trage Host, Datenbank und Anmeldedaten für dein Postgres ein, gleich für eine selbst gehostete Bereitstellung und eine dedizierte Cloud-Instanz. Tale prüft die Verbindung und das Vorhandensein der nötigen Erweiterungen, bevor du umstellst. Siehe [Datenresidenz](/de/self-hosted/configuration/data-residency) für die Verbindungsdetails und die Erweiterungs-Voraussetzungen. ## Wie Agenten hineingreifen Ein Agent sieht die ganze Bibliothek nicht von selbst. Der Tab **Wissen** des Agenten steuert seinen Abruf-Umfang — welche Teile der Bibliothek er zur Antwortzeit durchsucht —, und team-gebundene Einträge bleiben für Agenten und Mitglieder außerhalb des Teams unsichtbar. Den Abruf treiben die RAG-getaggten Tools des Agenten, und jede abgerufene Passage trägt ihre Quelle, sodass Zitate auf die Datei, den Eintrag oder die Seite zurückzeigen, aus der sie kamen. Die Mechanik auf Agenten-Seite steht in [Agent-Wissen](/de/platform/agents/knowledge). ## Seiten in diesem Bereich <CardGroup cols="2"> <Card title="Dokumente" icon="file-text" href="/de/platform/knowledge/documents"> Dateien hochladen, die Indexierungs-Pipeline, unterstützte Formate und der Lebenszyklus pro Dokument. </Card> <Card title="Wissenseinträge" icon="book-open" href="/de/platform/knowledge/knowledge-entries"> Kleine Fakten mit Themen-Schlüssel — aus dem Chat mit Freigabe erfasst oder von Hand hinzugefügt. </Card> <Card title="Crawling" icon="globe" href="/de/platform/knowledge/crawling"> Aus einer öffentlichen Website wird Wissen — Domain, Scan-Intervall und die Ansicht der indexierten Seiten. </Card> <Card title="Strukturierte Daten" icon="table" href="/de/platform/knowledge/structured-data"> Kontakte, Produkte, Lieferanten, Websites — wann ein typisierter Datensatz ein Dokument schlägt. </Card> </CardGroup> ## Wo das hingehört Wissen ist die Datenschicht, auf der jede verankerte Antwort steht; ohne sie wissen Agenten nur, was das Modell ohnehin weiß. Bring Inhalte über den Tab herein, der zu ihrer Form passt, und binde dann Agenten daran — die natürliche nächste Lektüre ist [Dokumente](/de/platform/knowledge/documents) für Dateien, [Strukturierte Daten](/de/platform/knowledge/structured-data) für Datensätze und [Agent-Wissen](/de/platform/agents/knowledge) für die Abrufseite. # KI-Anbieter Source: https://tale.dev/docs/de/platform/admin/providers Bevor deine Organisation nicht für mindestens einen KI-Anbieter funktionierende Zugangsdaten hat, beantwortet Tale keinen einzigen Prompt. **Einstellungen > KI-Anbieter** ist der Ort, an dem diese Zugangsdaten leben, und der einzige, an dem du neue anlegst. Admins und Developer öffnen die Seite; alle anderen begegnen ihrem Ergebnis später — als der Liste von Modellen, die sie im Chat, auf einem Agenten oder in einem Workflow-Schritt auswählen können. ## Connectoren und Zugangsdaten Auf dieser Seite treffen zwei verschiedene Dinge aufeinander, und wer sie auseinanderhält, versteht den Rest sofort. Ein **Connector** ist das mitgelieferte Wissen der Plattform über einen Anbieter: welchen Wire-Dialekt er spricht, auf welchem Endpunkt er antwortet, woher seine Modellliste kommt und welche Arten von Authentifizierung er akzeptiert. Connectoren kommen mit der Plattform. Du kannst keinen über die UI anlegen, ändern oder entfernen, und ein Upgrade der Plattform kann weitere mitbringen. **Zugangsdaten** sind deine Hälfte — der Teil, der einen Aufruf tatsächlich autorisiert. Du hinterlegst so viele davon pro Connector, wie du brauchst: einen Produktions- neben einem Staging-Schlüssel, einen Schlüssel pro Abteilung, eine von Ops verwaltete Variable neben einem, den du von Hand rotierst. Jeder Eintrag trägt einen Namen, eine Authentifizierungsmethode, optional eine Liste erlaubter Modelle und einen Aktiv-Zustand — und einer davon ist der Standard. Diese Connectoren werden heute mitgeliefert: | Connector | Wire-Format | Modellkatalog | | -------------------- | ---------------------- | ----------------------------- | | OpenRouter | OpenAI-kompatible API | OpenRouter-Katalog | | OpenAI | OpenAI-kompatible API | Mitgelieferter Katalog | | Anthropic | Anthropic-Messages-API | Mitgelieferter Katalog | | Gemini | OpenAI-kompatible API | Mitgelieferter Katalog | | Azure OpenAI | OpenAI-kompatible API | Kein Katalog | | DeepSeek | OpenAI-kompatible API | Mitgelieferter Katalog | | Moonshot AI (Kimi) | OpenAI-kompatible API | Mitgelieferter Katalog | | Qwen (Alibaba) | OpenAI-kompatible API | Mitgelieferter Katalog | | SpaceXAI | OpenAI-kompatible API | Mitgelieferter Katalog | | Z.ai (GLM) | OpenAI-kompatible API | Mitgelieferter Katalog | | Vercel AI Gateway | OpenAI-kompatible API | Models-Endpunkt des Anbieters | | Nous Portal (Hermes) | OpenAI-kompatible API | Kein Katalog | ## Was die Seite zeigt **Zugangsdaten** ist eine Tabelle dessen, was deine Organisation tatsächlich hält — eine Zeile pro gespeichertem Eintrag, nicht eine pro ausgeliefertem Anbieter. Eine Zeile zeigt den Namen, den Anbieter, gegen den sie sich authentifiziert, die Authentifizierungsmethode und die Koordinaten: eine maskierte Vorschau des gespeicherten Schlüssels oder den Namen der Umgebungsvariable dahinter, dazu die eigene Endpoint-URL dort, wo der Anbieter eine braucht, und wie viele Modelle die Liste erlaubt. Ein **Standard**-Badge markiert den Eintrag, auf den Anfragen zurückfallen, ein **Deaktiviert**-Badge jeden abgeschalteten. Alles Weitere steckt im Aktionsmenü der Zeile. Zwei Warnungen erscheinen hier statt in einem Dialog. Ein Anbieter, dessen Modellkatalog nicht geladen werden konnte, sagt das auf jeder Zeile, die von ihm abhängt — ein funktionierender Schlüssel nützt nichts, solange Tale nicht weiß, welche Modelle der Anbieter bedient. Und ein Anbieter mit Zugangsdaten, aber ohne Standard, wird über der Tabelle genannt: Anfragen können nicht automatisch wählen, solange du keinen Eintrag zum Standard machst. Unter der Tabelle zeigt **Harnesses**, wie sich jede Coding-Harness für deine Organisation auflöst. Der Abschnitt ist nur lesbar; geändert wird er über die Zugangsdaten darüber. ## Zugangsdaten hinzufügen <Steps> <Step title="Den Anbieter wählen"> **Zugangsdaten hinzufügen** öffnet den mitgelieferten Katalog. Anbieter, für die du schon Zugangsdaten hältst, stehen zuerst unter **In Verwendung**; alles andere folgt darunter, alphabetisch. Jeder Eintrag nennt seine Wire-Fakten — das API-Format und den Endpunkt-Host, etwa `OpenAI-kompatible API · openrouter.ai`, oder `Endpunkt pro Eintrag` — und wie viele Modelle sein Katalog hält. Die Suche grenzt die Liste ein; eine Auswahl führt zum Formular, **Zurück zum Katalog** wieder heraus. Weil das Formular zum gewählten Anbieter gehört, bietet es nur an, was dieser akzeptiert — nach einer Basis-URL, die die Plattform längst kennt, wirst du nie gefragt. </Step> <Step title="Die Authentifizierungsmethode wählen"> Die Methode schaltet den Rest des Formulars um: ein Secret-Feld für **API-Schlüssel** und **Abo-Schlüssel**, einen Variablennamen für **Umgebungsvariable**, das vollständige Broker-Formular für **Abo-Broker**. </Step> <Step title="Für die nächsten Leser benennen"> **Name** ist das, was jeder spätere Bildschirm anstelle des Secrets zeigt. Benenne den Eintrag nach seinem Zweck — `Produktionsschlüssel`, `Team Finanzen`, `Von Ops verwaltet` —, denn genau dieses Label wählt Monate später jemand aus einer Liste. </Step> <Step title="Entscheiden, ob du einschränkst"> **Erlaubte Modelle** ist optional. Lässt du das Feld leer, darf der Eintrag alles aus dem Katalog des Connectors nutzen; füllst du es, bleibt er auf deine Auswahl beschränkt. </Step> </Steps> ### API-Schlüssel Füg das Secret in **API-Schlüssel** ein. Tale speichert es verschlüsselt und zeigt es nie wieder — die Zeile zeigt eine maskierte Vorschau, nicht den Schlüssel. Zum Rotieren öffnest du das Menü der Zeile und wählst **API-Schlüssel ersetzen**; der Austausch greift sofort überall dort, wo diese Zugangsdaten verwendet werden. ### Umgebungsvariable Hier gelangt der Schlüssel gar nicht erst in Tale. Er bleibt auf dem Deployment, und die Zugangsdaten merken sich nur den Namen der Variable, die ihn hält. Du tippst nur das Suffix; das reservierte Präfix `TALE_PROVIDER_KEY_` steht fest und lässt sich nicht wegeditieren. <Note> Jeder Name ausserhalb dieses Präfixes wird abgelehnt, das Feld kann also nie auf ein fremdes Deployment-Geheimnis zeigen. Namen sind auf 40 Zeichen begrenzt. Die Variable selbst stellt bereit, wer das Deployment betreibt — die Operator-Seite steht in [Anbieter](/de/self-hosted/configuration/providers). </Note> ### Abo-Schlüssel und Broker Zwei Methoden decken Abonnements statt abgerechneter API-Schlüssel ab. **Abo-Schlüssel** speichert das Abo-Secret eines Anbieters direkt; ein Nous-Portal-Abo ist einer der mitgelieferten Fälle. **Abo-Broker** zeigt auf einen Endpunkt, der einen Pool rotierender OAuth-Tokens ausgibt — die Form, die ein Claude-Abo nutzt. Das Broker-Formular fragt nach **Broker-Endpunkt** und **HTTP-Methode**, dann unter **Broker-Authentifizierung** danach, wie Tale sich beim Broker ausweist: Keine, Bearer-Token oder Eigener Header, mit **Header-Name** und **Broker-Secret** — oder **Secret aus Umgebungsvariable**, wenn dein Ops-Team es hält. Der Rest beschreibt die Antwort: **Pfad zum Token-Array**, **Token-Feld**, die **Ziel-Umgebungsvariable**, in die das gewählte Token injiziert wird, und eine **Token-Auswahl** aus Zufällig, Erstes nutzbares oder Round-Robin. Unter **Erweitert** liegt die Feinjustierung: **Status-Feld**, **Wert für aktiv**, **Ablauf-Feld**, **Anfrage-Timeout (ms)**, **Maximale Antwortgröße (Bytes)** und **Sicherheitsabstand zum Ablauf (ms)**. <Info> Beide Arten werden im eigenen Tooling des Anbieters verbraucht statt über einen einfachen API-Aufruf, deshalb sagt es der Dialog offen: **Läuft in der Sandbox auf dem Harness des Anbieters.** Ein Anthropic-Abo-Broker läuft auf dem Harness `claude-code`, ein Nous-Portal-Abo-Schlüssel auf `hermes`. Direkte API-Aufrufe gibt es für diese Zugangsdaten nicht. </Info> ## Connectoren mit Endpunkt pro Eintrag Azure OpenAI hat keinen festen Endpunkt, weil jede Azure-Ressource ihren eigenen bedient, in der Form `https://<resource>.openai.azure.com/openai/v1`. Die Kopfzeile des Abschnitts sagt, dass der Endpunkt pro Eintrag gesetzt wird, und der Dialog ergänzt ein Feld **Endpoint-URL**, damit jeder Eintrag die Ressource trägt, zu der er gehört. Azure liefert auch keinen Modellkatalog mit, und der Grund lohnt sich, bevor du das Formular ausfüllst: Bei Azure ist die Modell-ID in einer Anfrage der Deployment-Name, den du in der Ressource vergeben hast — den kann Tale unmöglich vorher kennen. Trag diese Namen bei **Erlaubte Modelle** als kommagetrennte Liste ein. Ohne sie stellt der Eintrag überhaupt kein Modell bereit. ## Die Standard-Zugangsdaten wählen Eine Anfrage, die keine Zugangsdaten nennt, nimmt den Standard des Connectors. Das trifft auf den grössten Teil des Verkehrs zu, also ist der Standard der Eintrag, auf dem die alltägliche Arbeit landen soll — der gemeinsame Produktionsschlüssel, nicht das Experiment. Öffne das Menü einer Zeile und wähl **Zum Standard machen**. Pro Connector hält genau ein Eintrag diese Rolle, und wer sie einem anderen gibt, verschiebt sie. Ein deaktivierter Eintrag kann nicht Standard werden. Lässt du einen Connector ohne Standard, wählt die Plattform nicht für dich: Die Seite sagt es offen, und Anfragen ohne benannte Zugangsdaten haben nichts, worauf sie auflösen könnten. ## Einschränken, was ein Eintrag aufrufen darf **Erlaubte Modelle** begrenzt einen Eintrag auf einen Teil der Modelle seines Connectors. Mit Katalog dahinter ist das Feld eine durchsuchbare Mehrfachauswahl, ohne Katalog eine freie Liste von IDs. Lässt du es leer, steht der ganze Katalog offen. Füllst du es, zeigt die Zeile die Anzahl, und alles ausserhalb der Liste löst über diesen Eintrag nicht mehr auf. <Tip> Eine solche Liste schränkt genau einen Eintrag ein. Um über alle Anbieter hinweg zu bestimmen, was eine Person, ein Team oder eine Rolle wählen darf, nimm die Modellzugriffs-Regeln unter [Inhalte und Modelle](/de/platform/admin/governance/content-models). Beides greift zusammen: Ein Modell muss durch beide Schranken, bevor es in einer Auswahl auftaucht. </Tip> ## Die Modellkataloge aktuell halten **Kataloge aktualisieren** sitzt in der Kopfzeile der Seite und holt jeden Live-Katalog neu und meldet eine Zeile pro Connector — die Anzahl gefundener Modelle oder den Fehler, der dazwischenkam, damit ein ausgefallener Anbieter benannt und nicht stillschweigend übersprungen wird. Mitgelieferte Kataloge brauchen dafür nichts: Wenn jeder Connector einen hat, sagt die Meldung, dass es nichts zu aktualisieren gibt. Live-Kataloge werden zwischen zwei Aktualisierungen zwischengespeichert, einen Hintergrundabgleich gibt es nicht — ein heute Morgen veröffentlichtes Modell taucht auf, sobald jemand den Knopf drückt. ## Zugangsdaten deaktivieren und löschen **Deaktivieren** schaltet einen Eintrag ab und behält Konfiguration und erlaubte Modelle. Greif dazu, wenn ein Schlüssel im Verdacht steht, ein Kontingent aufgebraucht ist oder eine Abteilung pausiert — Wiedereinschalten ist ein Klick, und nichts muss neu eingegeben werden. <Warning> Löschen wirkt sofort und vollständig. Agenten und Anfragen, die diese Zugangsdaten verwenden, verlieren augenblicklich den Zugriff auf den Anbieter, also häng vorher alles um, was davon abhängt. Löschst du den Standard, bleibt der Connector ohne einen, bis du einen anderen ernennst — die Bestätigung sagt dir das, bevor du es tust. </Warning> ## Wo das hingehört Diese Seite ist der Boden, auf dem alles andere steht: Ein Agent, eine Chat-Antwort, ein Workflow-Schritt, ein Embedding für die Wissensdatenbank lösen alle auf ein Modell auf, und ein Modell ist nur erreichbar, wenn Zugangsdaten von dieser Seite es aufrufen können. Welche Modelle dabei herauskommen, steht im [Modellkatalog](/de/platform/models), die Governance-Schicht, die sie weiter einschränkt, unter [Inhalte und Modelle](/de/platform/admin/governance/content-models), und die Deployment-Variablen, die ein Operator bereitstellt, in [Anbieter](/de/self-hosted/configuration/providers). # Zugangsdaten für Connectors Source: https://tale.dev/docs/de/platform/admin/connectors Jeder Connector wird mit der Plattform ausgeliefert, deshalb besteht die Arbeit eines Admins nie aus Installation, sondern aus einer Entscheidung: als welche Konten Tale handeln darf, und wie diese Zugangsdaten gesund bleiben. Ein Connector hält so viele Einträge, wie du brauchst — einen pro Workspace, Shop, Postfach oder Bot — und einer davon antwortet für jeden Aufrufer, der keinen benennt. Diese Seite ist die Betriebsseite davon: was die Seite zeigt, wie jede Authentifizierungsmethode ausgefüllt wird und was beim Hochstufen, Deaktivieren, Löschen oder Neuverbinden einer Zeile geschieht. Der Katalog selbst — die dreizehn Connectoren, was jeder davon bringt und wie ihre Aktionen in Automationen und im Chat ankommen — steht unter [Connectors](/de/platform/connectors/overview). Hier lohnt sich die Zeit für den Lebenszyklus der Zugangsdaten, denn dieser Teil unterscheidet sich pro Organisation und dieser Teil geht kaputt. ## Was die Seite zeigt Öffne **Einstellungen > Connectors**. Die Seite verlangt Admin- oder Entwickler-Rechte und ist eine Tabelle der Zugangsdaten, die deine Organisation hält — eine Zeile pro Eintrag, nicht eine pro ausgeliefertem Connector. Eine Zeile zeigt den Namen, den Connector, gegen den sie sich authentifiziert, die Authentifizierungsmethode und die Koordinaten: eine maskierte Vorschau des gespeicherten Secrets sowie die Instanz-URL dort, wo der Connector eine braucht. Ein **Standard**-Badge markiert den Eintrag, auf den eine Aktion zurückfällt, ein **Deaktiviert**-Badge jeden abgeschalteten. Die Suche deckt sowohl den Namen ab, den du vergeben hast, als auch den Connector dahinter; der Filter-Knopf grenzt auf einen Connector ein. Ein `?connector=`-Link grenzt die Tabelle genauso ein — dorthin kehrt auch der OAuth-Umweg zurück. Zwei Warnungen erscheinen hier, und sie bedeuten Unterschiedliches. _Keine Standard-Zugangsdaten für {connector}_ heißt: jede Zeile funktioniert, aber für einen Aufrufer ohne eigene Angabe antwortet nichts. **Neu verbinden nötig** auf einer Zeile heißt: eine OAuth-Freigabe lässt sich nicht mehr erneuern und braucht neue Zustimmung — mit den Zugangsdaten selbst ist alles in Ordnung. ## Zugangsdaten hinzufügen **Zugangsdaten hinzufügen** öffnet den mitgelieferten Katalog. Connectoren, für die du schon Zugangsdaten hältst, stehen zuerst unter **In Verwendung**; alles andere folgt darunter, alphabetisch, jeweils mit den Kategorien und der Anzahl der Aktionen. Die Suche grenzt die Liste ein; eine Auswahl führt zum Einrichtungsschritt, **Zurück zum Katalog** wieder heraus. Die Einrichtung fragt zuerst nach einem **Namen**, und der Hilfetext des Felds erklärt, warum er zählt: unter diesem Namen wählt eine Aktion diesen Eintrag aus. Nimm etwas, das eine Autorin von Automationen Monate später wiedererkennt, etwa `Support-Postfach` oder `Shop EU`. Was nach dem Namen folgt, hängt von der **Authentifizierungsmethode** ab, die der Connector akzeptiert. <Tabs> <Tab title="API-Schlüssel"> Ein Feld, **API-Schlüssel**. Wohin der Schlüssel reist, entscheiden die Aktionen des Connectors selbst — ein Header, den der Anbieter vorgibt, oder der Request-Body, wo der Anbieter darauf besteht. Shopify und Tavily sind die ausgelieferten Fälle. </Tab> <Tab title="Token"> Ein Feld, **Token**, das bei jeder Anfrage als Authorization-Header gesendet wird. GitHub nimmt so ein Personal Access Token entgegen; Discord nimmt ein Bot-Token, das die Plattform unter Discords eigenem Schema statt unter dem üblichen sendet. </Tab> <Tab title="Benutzername & Passwort"> Zwei Felder, **Benutzername** und **Passwort**, gesendet als HTTP Basic. Das Paar ist nicht immer ein Login im Alltagssinn: Confluence nimmt die Konto-E-Mail mit einem API-Token, Twilio die Account SID mit dem Auth Token, und der WebDAV-Connector ein WebDAV-App-Passwort. IMAP / SMTP nimmt den Postfach-Login selbst. </Tab> <Tab title="OAuth"> Kein Secret zum Eintippen, der Einrichtungsschritt ist also allein die Übergabe: **Verbinden** bringt dich zum Freigabe-Dialog des Anbieters, und Tale legt ab, was zurückkommt — Access Token, Refresh Token, Ablauf und die erteilten Scopes — als neue Zeile. Gmail, Google Drive, Outlook, Teams und Slack verbinden sich so. Ein Connector, der beides akzeptiert, bietet beides an, mit **Verbinden** zuerst. </Tab> </Tabs> Einen zweiten Eintrag an einem Connector anzulegen, der schon einen hat, ist derselbe Ablauf noch einmal — der Connector steht dann im Katalog unter **In Verwendung**. Es gibt keine Grenze zu umgehen und nichts vorher zu trennen. <Note> Confluence und Shopify fragen zusätzlich nach einer **Instanz-URL**, weil beide keinen einheitlichen Anbieter-Host haben. Confluence will die Adresse deiner Atlassian-Site — dort, wo du Confluence öffnest. Shopify will die `myshopify.com`-Adresse deines Shops, also die Admin-Adresse statt der Storefront-Domain. Dieser Wert liegt absichtlich unverschlüsselt, damit die Tabelle zeigen kann, auf welche Instanz jede Zeile zeigt. </Note> ## Den Standard wählen Ein Eintrag pro Connector kann der **Standard** sein, und **Zum Standard machen** verschiebt ihn auf jede beliebige Zeile. Der Standard greift, wenn ein Automations-Node oder eine Chat-Aktion keine Zugangsdaten benennt. Der Mail-Sync ist die Ausnahme in die andere Richtung: `conversation.sync_mailbox` läuft über jeden _aktiven_ Eintrag des Connectors — ein zweites IMAP-Postfach (oder ein zweites Gmail-Konto) holt er also mit ab, ohne dass du es zum Standard machen musst. Jeder Eintrag merkt sich dabei seine eigene Position in seinem eigenen Postfach. Die Posteingangs-Sichtung verteilt sich über `conversation.list_mailbox_messages` genauso. Ein Connector mit mehreren Einträgen und ohne Standard ist eine funktionierende Konfiguration mit einer Lücke darin. Aufrufer, die eine Zeile benennen, laufen weiter; alle anderen können nicht wählen und scheitern. Stufe eine Zeile hoch, und die Lücke schließt sich sofort. ## Ein Secret ersetzen Einen Schlüssel zu wechseln ist eine Bearbeitung am Eintrag, keine eigene Operation. Öffne die Zeile und wähle je nach Methode **API-Schlüssel ersetzen**, **Token ersetzen** oder **Benutzername & Passwort ersetzen**. Das gespeicherte Secret wird nie angezeigt, und ein neuer Wert ersetzt es überall dort, wo dieser Eintrag verwendet wird — jeder Automations-Node und jede Chat-Aktion, die darauf zeigt, übernimmt den neuen Wert, ohne angefasst zu werden. Name, Standard-Kennzeichen und Instanz-URL überstehen den Wechsel, nachgelagert muss also nichts umgezogen werden. **Name & Instanz bearbeiten** deckt die andere Richtung ab: eine Zeile umbenennen oder auf eine andere Instanz umziehen. ## Deaktivieren und löschen **Deaktivieren** nimmt einen Eintrag aus dem Betrieb und behält die Zeile mit allem, was daran konfiguriert ist. Der Eintrag erscheint als **Deaktiviert**, und nichts löst mehr auf ihn auf; **Aktivieren** holt ihn zurück. Greif dazu, wenn ein Konto verdächtig ist statt erledigt, oder wenn eine Konfiguration geparkt werden soll, ohne verloren zu gehen. <Warning> **Löschen** wirkt sofort und endgültig. Automationen und Chat-Aktionen, die diesen Eintrag verwenden, verlieren augenblicklich den Zugriff auf diesen Connector — eine Schonfrist gibt es nicht. Löschst du den Standard, bleibt der Connector ohne einen, bis du eine andere Zeile hochstufst; die Rückfrage weist darauf hin, bevor du bestätigst. </Warning> ## Eine kaputte Autorisierung neu verbinden Ein OAuth-Eintrag, dessen gespeicherte Autorisierung abgelaufen ist oder widerrufen wurde, zeigt **Neu verbinden nötig** samt Grund. Das ist der Befund der Plattform und nicht die Entscheidung eines Admins, deshalb liest es sich anders als ein Eintrag, den jemand von Hand deaktiviert hat: an der Zeile ist nichts falsch, der Anbieter erkennt die Freigabe nur nicht mehr an. **Neu verbinden** startet den Freigabe-Dialog des Anbieters erneut und stellt den Zugriff auf derselben Zeile wieder her — mit Name, Standard-Kennzeichen und allen Verweisen darauf. Ein Eintrag, den du selbst deaktiviert hast, wird auf diesem Weg nicht repariert; dort hilft **Aktivieren**, und Neuverbinden würde die falsche Frage beantworten. ## Connectoren und MCP-Server Beide Oberflächen lassen einen Agent über Tale hinausgreifen, und der Unterschied liegt darin, wem die Brücke gehört. Ein Connector ist anbieterspezifisch, kommt mit der Plattform und wird für dich gepflegt; deine Seite davon sind die Zugangsdaten. Ein MCP-Server ist ein Prozess, den du selbst betreibst und unter **Einstellungen > API > MCP** registrierst, mit genau den Tools, die du schreibst. Greif zum Connector, wenn es einen für das Zielsystem gibt, und zu [MCP-Servern](/de/platform/connectors/mcp-servers), wenn nicht. ## Wo das hingehört Zugangsdaten zu verwalten ist inzwischen die gesamte Connector-Administration, weil nichts mehr installiert wird: Konten anlegen, gut benennen, pro Connector einen Standard halten und die OAuth-Einträge neu verbinden, die auslaufen. [Connectors](/de/platform/connectors/overview) ist der Katalog, an dem diese Einträge hängen, [Agent-Tools](/de/platform/agents/tools) zeigt, wie die daraus entstehenden Aktionen im Werkzeugkasten eines Agents ankommen, und [Genehmigungen konfigurieren](/de/platform/approvals/configure) ist der Ort, an dem schreibende Aktionen auf eine Freigabe warten. </content> </invoke> # Enterprise-SSO und Bereitstellung Source: https://tale.dev/docs/de/platform/admin/enterprise-sso Mit Enterprise-SSO melden sich deine Mitglieder über deinen Identitätsanbieter (IdP) an, statt mit einem Tale-Passwort, und SCIM lässt den IdP Mitglieder und Gruppen automatisch anlegen, aktualisieren und deaktivieren — ohne manuelle Einladungen. Eine Verbindung pro Organisation trägt das Anmeldeprotokoll, die Bereitstellungsrichtlinie und das SCIM-Token gemeinsam. Alles liegt auf einer Seite: **Einstellungen > Enterprise-SSO** (nur Administratoren). Tale spricht vier Protokolle: **OIDC**, einfaches **OAuth2**, **SAML 2.0** für die Anmeldung und **SCIM 2.0** für die Bereitstellung. Du kannst Anmeldung, Bereitstellung oder beides aktivieren. <Frame caption="Einstellungen > Enterprise-SSO — Protokoll-Auswähler und Anmeldefelder auf einer Seite; die Redirect-URL zum Registrieren im IdP steht bereit zum Kopieren."> ![Die Einstellungsseite Enterprise-SSO mit dem Protokoll-Dropdown auf Microsoft Entra ID und passendem Anzeigename, dazu ein Anmeldebereich mit der zu registrierenden Redirect-URL, einer Issuer-URL und einer Client-ID aus der App-Registrierung, einem leeren Client-Secret und den angeforderten Scopes.](/images/platform/settings-enterprise-sso.webp) </Frame> ## Protokoll wählen Öffne **Einstellungen > Enterprise-SSO**, wähle ein **Protokoll** und fülle nur die Felder dieses Protokolls aus — die übrigen bleiben ausgeblendet. Ein **Einrichtungsleitfaden** auf derselben Seite listet die genauen Schritte auf und zeigt die URLs, die du in deinen IdP einfügst. Verwende **Verbindung testen** vor dem Speichern, um die Konfiguration zu prüfen, und **Speichern**, um die Anmeldung zu aktivieren. - **Microsoft Entra ID** — Microsofts OIDC, mit Gruppe-zu-Team-Synchronisierung über Microsoft Graph. - **Generisches OIDC** — jeder OpenID-Connect-Anbieter (Google, Okta, Auth0, Keycloak, …). Endpunkte werden vom Issuer erkannt. - **OAuth2** — Anbieter ohne OIDC-Discovery; Autorisierungs-, Token- und Userinfo-Endpunkt konfigurierst du manuell. - **SAML 2.0** — XML-basiertes SSO; du tauschst Metadaten mit dem IdP aus. ## Microsoft Entra ID 1. Melde dich im [Microsoft Entra Admin Center](https://entra.microsoft.com) mindestens als Anwendungsentwickler an. 2. Geh zu **Entra ID > App-Registrierungen > Neue Registrierung**, benenne sie und wähle **Einzelner Mandant**. 3. Wähle unter **Umleitungs-URI** die Plattform **Web**, füge die auf der Tale-Seite angezeigte **Weiterleitungs-URL** ein und klicke auf **Registrieren**. 4. Kopiere auf der **Übersicht** die **Anwendungs-(Client-)ID** und die **Verzeichnis-(Mandanten-)ID**. Deine Issuer-URL lautet `https://login.microsoftonline.com/{tenant-id}/v2.0`. 5. Öffne **Zertifikate & Geheimnisse > Neues Clientgeheimnis** und kopiere den **Wert** des Geheimnisses (nicht die Geheimnis-ID). 6. Wähle in Tale **Microsoft Entra ID** und gib Client-ID, Clientgeheimnis und Issuer-URL ein. 7. Für die Gruppe-zu-Team-Synchronisierung füge unter **API-Berechtigungen** die Microsoft-Graph-Berechtigung **GroupMember.Read.All** hinzu und erteile die Administratorzustimmung. 8. Für die OneDrive- und SharePoint-Dokumentensynchronisation füge unter **API-Berechtigungen** die Microsoft-Graph-Berechtigungen **Files.Read** und **Sites.Read.All** hinzu und erteile die Administratorzustimmung. Eine neue Verbindung fordert beide standardmäßig an — das SSO-Token dient zugleich als Graph-Token, Mitglieder können also direkt nach der Anmeldung Dateien importieren. Soll die Organisation nur die Anmeldung nutzen, entferne die beiden Scopes aus dem Feld **Scopes**; der Microsoft-365-Eintrag bleibt dann auf der Dokumentenseite verborgen. ## Google Google wird als generischer OIDC-Anbieter konfiguriert. 1. Öffne in der [Google Cloud Console](https://console.cloud.google.com) **APIs & Dienste > Anmeldedaten > Anmeldedaten erstellen > OAuth-Client-ID**. 2. Wähle den Anwendungstyp **Webanwendung**. 3. Füge unter **Autorisierte Weiterleitungs-URIs** die auf der Tale-Seite angezeigte **Weiterleitungs-URL** hinzu und speichere. 4. Kopiere **Client-ID** und **Clientgeheimnis** oben auf der Client-Seite. 5. Wähle in Tale **Generisches OIDC**, gib Client-ID und Geheimnis ein und setze die Issuer-URL auf `https://accounts.google.com`. Die Endpunkte werden automatisch erkannt. Das Standard-OIDC von Google liefert **keine** Gruppenmitgliedschaften, daher ist die Gruppe-zu-Team-Synchronisierung mit Google allein nicht verfügbar — sie benötigt das Admin SDK / die Cloud Identity API mit einem Workspace-Administrator. Anmeldung und Rollenzuordnung per Claim funktionieren normal. ## Generisches OIDC und OAuth2 Für jeden anderen OIDC-Anbieter (Okta, Auth0, Keycloak) wähle **Generisches OIDC**, füge die **Issuer-URL** sowie Client-ID/Geheimnis ein — Tale liest die Autorisierungs-, Token- und Userinfo-Endpunkte aus dem `.well-known/openid-configuration` des Issuers. Wenn ein Anbieter OAuth2, aber kein Discovery-Dokument bietet, wähle **OAuth2** und gib die URLs für **Autorisierungs-**, **Token-** und **Userinfo**-Endpunkt manuell ein. Verwendet der Anbieter abweichende Claim-Namen, ordne **E-Mail**, **Name** und **Gruppen** in den erweiterten Feldern der Verbindung zu (Dot-Pfade werden unterstützt, z. B. `realm_access.roles`). ## SAML 2.0 1. Wähle in Tale **SAML 2.0**. Die Seite zeigt deine **SP-Metadaten-URL** und **ACS-URL (Antwort)** — kopiere diese. 2. Erstelle in deinem IdP eine neue SAML-2.0-Anwendung. Setze deren **ACS-URL** und **Entity-ID/Audience** auf die angezeigten SP-Werte (oder lade die SP-Metadaten-URL hoch) und das **Name-ID**-Format auf E-Mail-Adresse. 3. Füge unter **IdP-Metadaten importieren** die Föderations-Metadaten-URL deines IdP ein und klick auf **Importieren** — oder klick auf **XML hochladen**, falls dein IdP nur eine Datei zum Herunterladen anbietet. Tale liest die Metadaten aus und füllt Entity-ID, Anmelde-URL und Signaturzertifikat in den Feldern darunter, ohne dass du etwas abtippen musst. Alle drei Felder bleiben bearbeitbar — prüfe die importierten Werte (oder trag sie von Hand ein, falls dein IdP keine Metadaten veröffentlicht), bevor du speicherst. 4. Ordne die Attribute für **E-Mail**, **Name** und **Gruppe** in deinem IdP zu; weichen die Namen von den Standardwerten ab, trage die passenden Attributnamen in Tales erweiterten Feldern ein. Tale unterstützt sowohl IdP-initiiertes SAML (der IdP sendet eine Assertion an die ACS-URL) als auch SP-initiiertes SAML (ein Mitglied klickt auf **Mit SSO anmelden** und Tale leitet zum IdP weiter). Signierte Assertions sind erforderlich; verschlüsselte Assertions werden unterstützt, wenn du ein SP-Schlüsselpaar bereitstellst. ## Mehrere Organisationen auf einem Deployment Ein Deployment kann mehrere Organisationen mit jeweils eigener Verbindung beherbergen. Klicke auf der Anmeldeseite auf **Weiter mit SSO** und wähle deine Organisation aus der Liste — jeder Eintrag zeigt den **Anzeigenamen** der Verbindung. Dieser Name ist auf der Anmeldeseite für alle sichtbar; setze in **Einstellungen > Enterprise-SSO** pro Verbindung einen klaren Anzeigenamen. ## Bereitstellung: Rollen und Teams Jedes Protokoll teilt sich eine Bereitstellungsrichtlinie: - **Standardrolle** — die Rolle, die ein neu bereitgestelltes Mitglied erhält (standardmäßig Mitglied). - **Rollen automatisch zuweisen** — wenn aktiv, ordnen Rollenregeln einen Jobtitel, eine App-Rolle, eine Gruppe oder einen Claim einer Plattformrolle zu; trifft nichts zu, gilt die Standardrolle. - **Gruppen mit Teams synchronisieren** — wenn aktiv, wird jede IdP-Gruppe des Benutzers bei der Anmeldung zu einem gleichnamigen Team (oder tritt ihm bei); **Gruppen ausschließen** überspringt störende Gruppen (kommagetrennt). ## SCIM-Bereitstellung (Benutzer und Gruppen) Mit SCIM überträgt dein IdP Änderungen, ohne dass sich jemand anmelden muss. Klicke im Abschnitt **SCIM-Bereitstellung** auf **Token generieren** — kopiere es einmalig (es wird nicht erneut angezeigt) — und füge es zusammen mit der angezeigten **SCIM-Basis-URL** in die Bereitstellungseinstellungen deines IdP ein. Der IdP authentifiziert sich mit dem Token als Bearer-Anmeldedaten; Tale ermittelt die Organisation aus dem Token, das damit die Mandantengrenze bildet. Tale implementiert SCIM 2.0 **Users** und **Groups**: anlegen, lesen, auflisten (mit `userName`/`displayName`-Filtern), ersetzen, patchen und löschen. Bereitgestellte Benutzer entsprechen Organisationsmitgliedern, Gruppen entsprechen Teams. **Die Deaktivierung ist sanft** — setzt der IdP einen Benutzer inaktiv (`active: false`), wird die Rolle des Mitglieds auf `disabled` gesetzt (was den Zugriff entzieht), und eine Reaktivierung stellt die vorherige Rolle wieder her. Ein SCIM-**Löschen** entfernt die Mitgliedschaft aus der Organisation; das Benutzerkonto selbst bleibt bestehen, und eine erneute Bereitstellung fügt es mit der Standardrolle der Verbindung wieder hinzu. Der Inhaber der Organisation kann über SCIM nie entfernt werden. ## Überprüfung Verwende **Verbindung testen** für OIDC/OAuth2, um Discovery und Anmeldedaten vor dem Speichern zu bestätigen. Für SAML lade die SP-Metadaten in deinen IdP und führe eine Testanmeldung durch. Für SCIM bieten die meisten IdPs eine „Test"- oder „Jetzt bereitstellen"-Aktion, die einen Beispielbenutzer anlegt — prüfe, ob er unter **Einstellungen > Mitglieder** erscheint. Eine End-to-End-SSO-Anmeldung prüfst du am besten gegen deinen echten IdP in einer Staging-Organisation. # Mitglieder und Rollen Source: https://tale.dev/docs/de/platform/admin/members-and-roles Mitglieder sind die Personen in deiner Organisation, die sich bei Tale anmelden können. Rollen kontrollieren, was jedes Mitglied tun darf — lesen, schreiben, konfigurieren, regeln. Diese Seite ist die kanonische Referenz für die sechs Rollen und die Berechtigungen pro Ressource, die jede Rolle trägt. Sechs Rollen decken nahezu jedes Team ab, an das Tale ausgeliefert wird. Admins und Inhaber lesen diese Seite, wenn sie ein Team zum ersten Mal aufsetzen, wenn ein Audit fragt, wer welchen Zugriff hat, oder wenn sie wissen müssen, ob sie einem neuen Kollegen Redakteur oder Entwickler geben. Lieber erst zusehen? Episode 8 geht in gut zwei Minuten durch Besetzung, Rollenleiter und Teamwände — mit Untertiteln. <Video src="/videos/de/tutorials/ep8-people/ep8-people.de.mp4" poster="/videos/de/tutorials/ep8-people/ep8-people.de.webp" captions="/videos/de/tutorials/ep8-people/ep8-people.de.vtt" lang="de" title="Episode 8 — Menschen, Rollen & Teams" caption="Episode 8 — Menschen, Rollen & Teams (2:35)"> </Video> <Frame caption="Der Mitglieder-Abschnitt unter Einstellungen > Organisation — jeder Account und die Rolle, die ihn begrenzt."> ![Die Organisations-Einstellungsseite mit ihrem Mitglieder-Abschnitt, der den Inhaber des Workspace und eine Schaltfläche Mitglied hinzufügen zeigt.](/images/get-started/settings-organization-members.webp) </Frame> ## Ein Mitglied hinzufügen Um eine Person in deine Organisation aufzunehmen, öffne **Einstellungen > Organisation**, scroll zum Abschnitt **Mitglieder** und klick auf **Mitglied hinzufügen**. Trag **Name**, **E-Mail** und **Rolle** ein und vergib ein **Passwort** — Tale verschickt keine Einladungs-E-Mail, deshalb ist ein Passwort erforderlich, um ein neues Konto zu erstellen. (Gehört die E-Mail bereits zu einem Tale-Konto, wird kein Passwort verlangt: die Person meldet sich mit ihren bestehenden Zugangsdaten an und wird einfach dieser Organisation hinzugefügt.) Beim **Mitglied hinzufügen** zeigt Tale die neuen Zugangsdaten **einmalig** an, mit dem Hinweis, sie jetzt zu speichern — sie werden nicht erneut angezeigt. Gib sie dem neuen Mitglied auf einem anderen Weg weiter; es gibt keine Reset-E-Mail. Wer sein Passwort später vergisst, wendet sich an einen Admin, der im selben Mitglieder-Abschnitt ein neues setzen kann. Wähl die Rolle im Formular, bevor du absendest; sie später hochzustufen oder zu ändern ist eine Ein-Klick-Änderung im selben Mitglieder-Abschnitt. ## Die sechs Rollen **Inhaber** hat jede Berechtigung, die Admin hat, plus die eine, die Admin fehlt: Eigentum übertragen und die Organisation löschen. Die meisten Teams haben genau einen Inhaber; manche behalten zwei für Kontinuität. **Admin** regelt die Organisation: Mitglieder, Anbieter, Branding, Governance-Richtlinien, Connectors, das Audit-Log. Admins tun alles, was Redakteur und Entwickler tun, plus die Konfigurationsoberfläche. Sie können das Eigentum nicht übertragen. **Entwickler** baut: Agents, Workflows, Connectors, API-Keys, MCP-Server. Entwickler können jede Ressource lesen und in die meisten schreiben, inklusive Governance-Richtlinien (nur lesen). Greif zu Entwickler, wenn jemand die API-Ebene und das Connector-Tooling braucht. **Redakteur** kuratiert und betreibt: Agents, die Wissensdatenbank (Dokumente, Kontakte, Produkte, Lieferanten, Websites), den Konversations-Posteingang, Genehmigungen, die Skill-Bibliothek. Redakteure können Workflows lesen, aber nicht ändern; sie können Connectors lesen, aber nicht konfigurieren. Greif zu Redakteur, wenn jemand die tägliche Produktarbeit erledigt, ohne die API- oder Connectorsebene zu berühren. **Mitglied** nutzt: Chat, durchsucht die Wissensdatenbank und liest Konversationen und Genehmigungen. Konversationen sind zuweisungsbezogen sichtbar: Mitglieder sehen Threads, die ihnen zugewiesen oder in die Warteschlange ihrer Teams gelegt sind; wirklich unzugewiesene Post sichten nur Admins — nutze [Konversations-Routing](/de/platform/admin/governance/policies-and-limits#konversations-routing), damit eingehende Post beim Eintreffen in eine Team-Warteschlange landet. Mitglieder schreiben nur an Nachrichten-Feedback (Daumen hoch / runter). Greif zu Mitglied als Default — die meisten Benutzer in den meisten Organisationen sind Mitglieder. **Deaktiviert** hat keine Berechtigungen. Nutz das, um Zugriff zu entziehen, ohne den Account zu löschen; Transkripte und Audit-Historie bleiben intakt, und ein Reaktivieren stellt die vorherige Rolle wieder her. ## Die Berechtigungs-Matrix | Ressource | Inhaber | Admin | Entwickler | Redakteur | Mitglied | Deaktiviert | | ------------------------- | ------- | ----- | ---------- | --------- | -------- | ----------- | | Agents | R / W | R / W | R / W | R / W | R | — | | Dokumente | R / W | R / W | R / W | R / W | R | — | | Produkte | R / W | R / W | R / W | R / W | R | — | | Kontakte | R / W | R / W | R / W | R / W | R | — | | Lieferanten | R / W | R / W | R / W | R / W | R | — | | Projekte | R / W | R / W | R / W | R / W | R | — | | Websites | R / W | R / W | R / W | R / W | R | — | | Konversationen | R / W | R / W | R / W | R / W | R | — | | Konversations-Nachrichten | R / W | R / W | R / W | R / W | R | — | | Genehmigungen | R / W | R / W | R / W | R / W | R | — | | Workflow-Ausführungen | R / W | R / W | R / W | R | R | — | | Workflow-Processing | R / W | R / W | R / W | R | R | — | | Connectors | R / W | R / W | R / W | R | R | — | | OneDrive-Sync-Konfigs | R / W | R / W | R / W | R | R | — | | Prompt-Templates | R / W | R / W | R / W | R / W | R | — | | Audit-Logs | R / W | R / W | R / W | R / W | R | — | | Governance-Richtlinien | R / W | R / W | R | R | R | — | | Nachrichten-Feedback | R / W | R / W | R / W | R / W | R / W | — | | MCP-Server | R / W | R / W | R / W | R | R | — | R = lesen, W = schreiben, — = kein Zugriff. Die Matrix ist die autoritative Beschreibung, was jede Rolle über die Ressourcen tun kann, die Tale verfolgt; die Zeilen sind dieselbe Menge, die das In-Produkt-Berechtigungssystem zur Request-Zeit nutzt. ## Die Einstellungs-Oberfläche und das Menü Mitglieder, Redakteure und deaktivierte Benutzer sehen die Konfigurationsoberfläche nicht — nur ihre eigenen persönlichen Einstellungen. Entwickler sehen die Organisationseinstellungen, aber nicht den Governance-Unterzweig (außer Lese-Ansichten). Admins und Inhaber sehen alles. Das Einstellungsmenü ist gruppiert in **Persönlich** (Konto, Einstellungen, Umgebung — jede Rolle), **Organisation** (Teams, der Mitglieder-Abschnitt, KI-Anbieter, Branding, Governance und der Rest — Admin und Inhaber, wobei Entwickler eine Teilmenge sehen) und **Entwicklung** (die API- und Data-Residency-Oberfläche). Governance ist ein Eintrag innerhalb der Organisations-Gruppe, keine eigene Gruppe, und braucht Admin-Zugriff. ## Randfälle **Eigentum übertragen** verlangt, dass ein bestehender Inhaber einen aktuellen Admin oder Inhaber nominiert; die neue Inhaber-Rolle wirkt sofort. Der vorherige Inhaber wird zu Admin, außer er wird explizit herabgestuft. **Warnung „letzter Admin".** Der Mitglieder-Abschnitt warnt, wenn der letzte Admin oder Inhaber entfernt oder herabgestuft wird. Die Aktion ist erlaubt — Tale sperrt dich nicht aus — aber du solltest mindestens zwei Admin- oder Inhaber-Accounts für Kontinuität halten. **Zwei-Faktor zurücksetzen** liegt auf der Zeile des Mitglieds im Mitglieder-Abschnitt. Zurücksetzen entfernt den zweiten Faktor; der nächste Sign-in registriert neu. ## Wo das hingehört Rollen sind die Zugriffsoberfläche, die jede andere Admin-Seite berührt: SSO authentifiziert sie, API-Keys gehören ihnen, Audit-Logs benennen sie, Governance-Richtlinien grenzen Verhalten nach Rolle ein. Die nächste Lektüre hängt davon ab, was du als Nächstes tust. Wenn du Sign-in an deinen Identitätsanbieter verdrahtest, behandelt [Authentifizierung](/de/self-hosted/configuration/authentication) die vier Sign-in-Modi. Wenn du Zugriff nach Team statt nur nach Rolle eingrenzt, deckt [Teams](/de/platform/admin/teams) die Team-Ebene dieser Eingrenzung ab. # Agents (Admin-Sicht) Source: https://tale.dev/docs/de/platform/admin/agents Die Admin-Sicht auf Agenten ist das organisationsweite Verzeichnis jedes Agenten, der in Tale existiert, unabhängig davon, wer ihn gebaut hat. Editoren und Developer sehen die Agenten, auf die sie in ihrem eigenen Bereich Zugriff haben; Admins und Inhaber sehen alle, dazu die Steuerungshebel pro Agent und die Prüfspur pro Agent. Diese Seite behandelt diese aufsichtführende Oberfläche — was die Tabelle zeigt, was eine Administratorin ändern kann und was in der Hand des Agenten-Besitzers bleibt. Wie man einen Agenten baut, lehrt diese Seite nicht. Das ist die Editor-Sicht unter [Agent-Konzepte](/de/platform/agents/concepts). Hier geht es um die andere Seite: einen Agenten finden, eingreifen, wenn einer Aufmerksamkeit braucht, und wie die Rollengrenzen dabei halten. ## Was die Tabelle zeigt Öffne **Einstellungen > Agents** und du landest auf der organisationsweiten Liste. Jede Zeile nennt einen Agenten und zeigt, wem er gehört, ob er für die Organisation freigegeben oder privat gehalten ist und wann er zuletzt bearbeitet wurde. Die Liste ist nach Namen durchsuchbar, und die Voreinstellung sortiert zuletzt Bearbeitetes zuerst — praktisch, um zu sehen, was sich seit deinem letzten Blick geändert hat. Ein Klick auf eine Zeile öffnet denselben Agenten-Editor, den auch ein Editor oder Developer sähe, aber mit der Admin-Linse: Jeder Tab ist sichtbar, jede Bindung bearbeitbar, und der Verlauf zeigt die volle Bearbeitungsspur mit der handelnden Person und dem Diff jeder Speicherung. ## Was eine Administratorin kann, ein Editor nicht Admins erben jede Berechtigung, die Editoren und Developer auf der Agenten-Oberfläche tragen. Darüber hinaus bringt die Admin-Sicht drei Steuerungsschritte mit. - **Die Reichweite eines Agenten verengen.** Einen freigegebenen Agenten wieder auf privat zu stellen nimmt ihn aus der Auswahl jedes Mitglieds, ohne etwas zu löschen — seine Gespräche und sein Verlauf bleiben unversehrt, und eine erneute Freigabe stellt das vorige Verhalten wieder her. Greif dazu, wenn ein Agent aus der Reihe tanzt und du seine Nutzung stoppen willst, während du der Ursache nachgehst. - **Den Besitz übertragen.** Der Besitzer eines Agenten ist das Mitglied, das für ihn verantwortlich ist, und ein privater Agent muss immer eines haben. Ein Übertrag gibt den Agenten an jemand anderen; der bisherige Besitzer behält nur, was seine Rolle ihm gibt. Greif dazu, wenn ein Besitzer das Team wechselt oder geht. - **Eine Governance-Policy anlegen.** Admins können einem Agenten eine Policy anheften — verlangte Freigaben bei Schreibvorgängen, welche Tool-Familien erlaubt sind, welche Connectors erreichbar. Wo beide sich widersprechen, gewinnt die Policy über die eigene Konfiguration des Agenten, und dessen Besitzer sieht sie im Editor als schreibgeschütztes Abzeichen. ## Was beim Agenten-Besitzer bleibt Das meiste tägliche Bearbeiten bleibt bei dem, der den Agenten gebaut hat: umbenennen, Anweisungen umschreiben, den Wissensbereich anpassen, Tools gewähren oder entziehen, Skills binden und lösen, neue Versionen speichern. Die Admin-Sicht ist zum Eingreifen da, nicht zum Übernehmen. Wenn du dich dabei ertappst, regelmäßig fremde Agenten zu bearbeiten, ist die richtige Antwort meist eine Governance-Policy, die das Verhalten für eine Klasse von Agenten festlegt, und keine Handänderung an einem einzelnen. Eines liegt außerhalb beider Rollen: Niemand nagelt einem Agenten ein Modell fest. Das Modell wählt pro Zug, wer die Nachricht abschickt; welche Modelle benutzt werden dürfen, ist damit eine Frage der [Provider](/de/platform/admin/providers) und der [Richtlinien und Limits](/de/platform/admin/governance/policies-and-limits), nie eine von Agent zu Agent. ## Prüfung und Verlauf Jede Speicherung an einem Agenten landet im Prüfprotokoll mit der handelnden Person, dem Zeitstempel und dem geänderten Feld. Die Admin-Sicht zeigt den Ausschnitt pro Agent über den Verlauf im Agenten-Editor; dieselben Daten sind organisationsweit unter **Einstellungen > Governance** erreichbar. Bindungen liest man mit diesem Wissen im Kopf — die Konfiguration eines Agenten kann unverändert bleiben, während ein von ihm gebundenes Skill-Bundle darunter ersetzt wird, und das zeigt sich in der eigenen Prüfspur des Bundles. ## Wo das hingehört Die Admin-Sicht auf Agenten ist das aufsichtführende Gegenstück zur Bau-Sicht des Editors — dieselben Agenten, eine andere Linse. Meist solltest du erst dazu greifen, wenn etwas Aufmerksamkeit braucht; die tägliche Arbeit läuft im Agenten-Editor unter [Agent-Konzepte](/de/platform/agents/concepts). Wenn die richtige Antwort ist, das Verhalten für eine Klasse von Agenten festzulegen statt für einen, ist der nächste Schritt [Mitglieder und Rollen](/de/platform/admin/members-and-roles) — dort steht, wie Policies an Rollen hängen. # Teams Source: https://tale.dev/docs/de/platform/admin/teams Ein Team ist eine benannte Gruppe von Mitgliedern, die sich Zugriff auf Agents, Prompts, Projekte, Connectors und Konversationen teilt. Wo Rollen definieren, was eine Person tun _kann_, definieren Teams, in welchem Ausschnitt der Organisationsdaten diese Person arbeitet. Die meisten Organisationen landen bei einer Handvoll Teams — Support, Vertrieb, Betrieb — und die meisten alltäglichen Berechtigungs-Entscheidungen liegen auf der Team-Grenze, nicht auf der Rollen-Grenze. Admins verwalten Teams unter **Einstellungen > Teams**. Diese Seite ist die Referenz dafür, was ein Team besitzt, wie Mitgliedschaft funktioniert und wie die Team-Grenze mit den rollenbasierten Berechtigungen aus [Mitglieder und Rollen](/de/platform/admin/members-and-roles) zusammenspielt. Lies sie einmal, wenn du die Teams der Organisation aufsetzt; komm wieder, wenn du umorganisierst. <Frame caption="Einstellungen > Teams — jedes Team der Organisation mit seiner Mitgliederzahl, neben der Aktion Team erstellen."> ![Die Teams-Einstellungsseite listet drei Teams — Growth, Platform engineering und Customer success —, jedes mit einem Mitglied und dem Zeitpunkt, an dem es hinzugefügt wurde, neben der Schaltfläche Team erstellen.](/images/platform/settings-teams.webp) </Frame> ## Was ein Team besitzt Ein Team hält Mitgliedschaft und eine Menge ihm zugeordneter Ressourcen. Die Ressourcen sind: - **Agents** — Agents, die mit Team-Scope erstellt wurden, sind nur für Mitglieder dieses Teams sichtbar und editierbar. Organisationsweite Agents bleiben für alle mit passender Rolle sichtbar. - **Prompts** — gespeicherte Prompts mit Sichtbarkeit `Team` erscheinen nur für die Mitglieder dieses Teams. Persönliche Prompts bleiben privat beim Eigentümer; Globale Prompts sind organisationsweit sichtbar. - **Projekte** — Projekte können einem Team zugewiesen werden; die Mitglieder des Teams erben den Projekt-Zugriff, ohne einzeln hinzugefügt zu werden. - **Connectors** — Connectors, die auf bestimmte Teams beschränkt sind (über den Hebel **Erlaubte Teams** unter **Einstellungen > Connectors**), erscheinen nur in Pickern dieser Teams. - **Konversationen** — eine Konversation kann zusätzlich zu einer zuständigen Person auch einem Team zugewiesen werden, über die Zuweisungs-Auswahl in ihrer Kopfzeile. Die Sichtbarkeit folgt dieser Zuweisung: eine Team-Warteschlange ist für die Mitglieder dieses Teams sichtbar, eine Personenzuweisung für diese Person, und Admins sowie Inhaber sehen alles. Wirklich unzugewiesene Konversationen (weder Person noch Team) bleiben bei Admins zur Sichtung — kombiniere das mit [Konversations-Routing](/de/platform/admin/governance/policies-and-limits#konversations-routing), damit eingehende Post beim Eintreffen in ein Team landet. Eine Ressource ohne Team-Scope bleibt für alle sichtbar, deren Rolle es erlaubt. Teams sind eine _zusätzliche_ Eingrenzungsebene — sie engen Sichtbarkeit ein, weiten sie nie aus. ## Ein Team erstellen Öffne **Einstellungen > Teams** und klick auf **Team erstellen**. Gib dem Team einen Namen (`Support`, `Vertrieb`, `Betrieb`) und eine optionale Beschreibung; der Name erscheint überall, wo das Team auftaucht — Picker, Badges, team-eingegrenzter Dokumentzugriff und das Zuweisungsfeld eines Projekts. Speichern erstellt ein leeres Team, das du aus der Team-Zeile mit Mitgliedern füllen kannst. Die Team-Zeile trägt drei Untersichten: **Mitglieder** (wer im Team ist), **Ressourcen** (was das Team besitzt) und **Einstellungen** (Name, Beschreibung und Lebenszyklus des Teams). Die Ressourcen-Sicht ist der einfachste Weg, zu sehen, wohin ein Team reicht; sie dient zusätzlich als Audit-Oberfläche, wenn jemand fragt, warum ein Team einen bestimmten Agent sieht. ## Mitglieder hinzufügen und entfernen Öffne die Team-Zeile und klick auf **Mitglieder hinzufügen**. Der Picker listet die Mitglieder der Organisation; eines anzuhaken fügt es dem Team hinzu. Ein Mitglied kann mehreren Teams angehören; sein Zugriff ist die Vereinigung jedes Teams, in dem es ist, plus der organisationsweiten Reichweite seiner Rolle. Ein Mitglied aus einem Team zu entfernen, entzieht beim nächsten Request die team-gebundene Sichtbarkeit; laufende Chats werden fertig, aber der nächste Thread sieht die Ressourcen des Teams nicht mehr. ## Team versus Rolle Die Rolle entscheidet, was eine Person tun darf; das Team entscheidet, woran. Ein Mitglied-Rollen-Benutzer im Support-Team kann die Agents des Support-Teams lesen, aber nicht bearbeiten; ein Entwickler-Rollen-Benutzer im Support-Team kann die Agents des Support-Teams lesen und schreiben, aber die des Vertriebs nicht sehen. Teams gewähren nie Fähigkeiten, die der Rolle fehlen; Rollen weiten Sichtbarkeit nie über den Team-Scope hinaus. Wenn du eine Berechtigungs-Entscheidung brauchst, die bestehende Rollen und Teams nicht ausdrücken können, ist der nächste Hebel eine Governance-Richtlinie — siehe [Mitglieder und Rollen](/de/platform/admin/members-and-roles) dafür, wie Richtlinien sich an Rollen heften, und den Governance-Bereich für die Richtlinien-Felder selbst. ## Ein Team löschen Klick auf die Team-Zeile, dann auf **Team löschen**. Löschen ist Hard-Stop — das Team ist weg, jede team-gebundene Ressource, die es besaß, wechselt auf organisationsweite Sichtbarkeit, und Mitglieder verlieren den team-gebundenen Ausschnitt ihres Zugriffs. Es gibt kein Undo; verwaiste Ressourcen bleiben für alle erreichbar, deren Rolle es erlaubt, was selten das richtige Ergebnis ist. Greif zu Löschen, wenn ein Team wirklich aufgelöst wird, nicht wenn es umorganisiert wird. ## Wo das hingehört Teams sind die Eingrenzungsebene direkt unter Rollen — Rollen sagen _was_, Teams sagen _wo_. Die natürliche nächste Lektüre hängt von der Ressource ab, die du eingrenzt: [Skill-Bibliothek](/de/platform/workspace/skills) dafür, wie eine geteilte Anleitung alle erreicht, [Connectors (Admin-Sicht)](/de/platform/admin/connectors) für die Zugangsdaten, die die Automatisierungen eines Teams aufrufen, und [Projekte](/de/platform/projects/overview) für die Projekt-zu-Team-Zuweisung. # Changelog Source: https://tale.dev/docs/de/platform/admin/changelog Der Changelog ist der In-Produkt-Viewer, der Release Notes für die Tale-Plattform selbst anzeigt — nicht für Inhalte, die deine Mitglieder produzieren. Nach einem selbst gehosteten Upgrade oder einem Managed-Cloud-Rollout listet der Viewer auf, was sich zwischen der vorherigen Version und der jetzt laufenden geändert hat. Admins lesen ihn nach einem Upgrade, um das Team einzuweisen und alles zu markieren, was die Arbeit der Mitglieder berührt. Der Viewer liest Release Notes aus dem Tale-Repository auf GitHub und cached sie in deiner Instanz, damit die Seite auch lädt, wenn GitHub nicht erreichbar ist. ## Wo der Changelog lebt Der Changelog hat zwei Oberflächen. Die Seite **Was ist neu** unter **Hilfe** listet jeden jüngsten Release mit den vollen Notes. Der **Upgrade-Toast** feuert einmal pro Major-Versionssprung und verlinkt direkt auf die Seite — der Toast zeigt `Auf v<version> aktualisiert` und bleibt bis zum Schliessen stehen, damit ein Mitglied, das weg war, den Hinweis nicht verpasst. Öffne die Seite über das Hilfemenü in der oberen Leiste oder über den Upgrade-Toast, wenn er erscheint. Die Seite cached etwa dreissig jüngste Releases; ältere verlinken in die GitHub-Release-Historie. ## Was jeder Eintrag zeigt Jeder Release-Eintrag trägt vier Felder: das Versions-Tag, das Veröffentlichungsdatum, den Release-Namen (oft eine kurze Überschrift) und den Release-Body in Markdown. Tale rendert den Body wie GitHub — Überschriften, Listen, Links und Code-Fences überleben alle. Releases, die GitHub noch nicht veröffentlicht hat, zeigen eine kurze Erklär-Karte mit einem Link zur öffentlichen Release-Historie. ## Scope Der Changelog ist der Changelog der Plattform — was sich in Tale selbst geändert hat. Er zeigt nicht Änderungen an deinen Agents, deinen Workflows oder deiner Wissensdatenbank; die haben ihre eigene Pro-Ressource-Historie. Wenn du die Versionshistorie eines Agents oder Workflows suchst, öffne die Ressource und wechsle auf den Tab **Historie**. Der Viewer ist nur-lesend und für jedes angemeldete Mitglied sichtbar. Es gibt kein Admin-only-Flag — jeder mit einem Account kann die Seite öffnen. Die Daten, die der Viewer abruft, sind öffentliche Release-Informationen aus dem Tale-GitHub-Repository, also gibt es nichts Organisationsinternes zu verstecken. ## Ein durchgespieltes Upgrade Nach einem selbst gehosteten Upgrade von `v0.42` auf `v0.45` melde dich an und schau oben rechts nach dem Upgrade-Toast. Klick auf **Anzeigen**, um die Changelog-Seite zu öffnen. Die Seite zeigt drei Release-Einträge (`v0.43`, `v0.44`, `v0.45`), neuester zuerst, jeder mit den von Entwicklern geschriebenen Notes aus dem GitHub-Release. Geh die Highlights durch, teile den Link mit dem Team, falls etwas ein grösseres Publikum braucht, und der Toast verschwindet beim nächsten Neuladen. Wenn das Upgrade über das gecachte Fenster hinausgeht, zeigt die Seite die jüngsten Einträge mit einem Banner, der für die früheren Notes auf GitHub verlinkt. Der Cache bleibt warm für den nächsten Leser auf deiner Instanz. ## Wo das hingehört Der Changelog ist die Operator-Lesart dessen, was Tale selbst gerade getan hat; er steht neben dem Audit-Log (das festhält, was deine Mitglieder getan haben) und der Anbieter-Seite (die festhält, welche Modellversionen verdrahtet sind). Paar ihn mit [Selbst gehostetes Upgrade](/de/self-hosted/operate/upgrades), wenn du die Instanz betreibst — der Upgrade-Leitfaden geht den Versionssprung durch, und der Changelog liest auf der anderen Seite das Ergebnis aus. # API-Schlüssel Source: https://tale.dev/docs/de/platform/admin/api-keys API-Schlüssel sind die organisationsweiten Anmeldedaten, die Tale ausstellt, damit externer Code seine REST-API ohne Person in der Schleife aufrufen kann. Ein Schlüssel authentifiziert den Aufrufer als die Organisation, begrenzt durch die Rolle, die du beim Anlegen wählst. Admins und Entwickler verwalten Schlüssel; andere Rollen sehen die Seite nicht. Das ist die Referenz dafür, was ein Schlüssel ist, wie du einen erstellst, wie du ihn begrenzt und wie du ihn außer Dienst stellst, ohne etwas zu zerbrechen, das von ihm abhängt. Die hier gelisteten Schlüssel sind etwas anderes als die Per-Benutzer-Session-Tokens, die Tale beim Anmelden ausstellt. Die sind kurzlebig und an eine Person gebunden; API-Schlüssel sind langlebig und an die Organisation gebunden. Greif zu einem API-Schlüssel, wenn du ein Skript, einen Cron-Job, einen internen Dienst oder eine Drittanbieter-Connector an Tale anschließt; greif zur In-Produkt-Oberfläche, wenn eine Person an der Tastatur sitzt. <Frame caption="Einstellungen > API-Schlüssel — wo Schlüssel erstellt, rotiert und widerrufen werden."> ![Die REST-API-Schlüssel-Einstellungsseite listet zwei Schlüssel, jeder nur mit seinem Präfix, dem Datum unter Hinzugefügt und der Markierung Nie verwendet, neben der Schaltfläche API-Schlüssel erstellen.](/images/get-started/settings-api-keys.webp) </Frame> ## Einen Schlüssel erstellen Öffne **Einstellungen > API-Schlüssel** und klick auf **API-Schlüssel erstellen**. Gib dem Schlüssel einen Namen, der sagt, wer oder was ihn nutzt (`Billing-Sync`, `Slack-Relay`, `ops-cron`), wähl die Rolle, die er tragen soll, und wähl das Ablaufdatum. Tale zeigt das Geheimnis genau einmal bei der Erstellung — kopier es in deinen Passwort-Manager oder dein Deployment-System, bevor du den Dialog schließt. Danach ist nur noch das Präfix des Schlüssels in der Tabelle sichtbar. Die Rolle, die du wählst, begrenzt alles, was der Schlüssel tun kann. Ein Schlüssel mit Entwickler-Rolle kann jede Ressource lesen und in die meisten schreiben; ein Schlüssel mit Mitglied-Rolle kann die Wissensdatenbank lesen und Chats starten, aber nichts konfigurieren. Nimm die kleinste Rolle, die den Job erledigt — Schlüssel sind genau so gefährlich wie die Rolle, die sie tragen. ## Was die Tabelle zeigt Die API-Schlüssel-Tabelle listet jeden Schlüssel mit Name, Präfix, Rolle, Ersteller, Zeitstempel der letzten Nutzung und Ablauf. Das Präfix sind die ersten acht Zeichen des Geheimnisses — genug, um den Schlüssel in Logs zu identifizieren, ohne ihn offenzulegen. Der Zeitstempel der letzten Nutzung aktualisiert sich bei jeder erfolgreichen Anfrage, die der Schlüssel macht; ein Schlüssel, der wochenlang ungenutzt war, ist meist sicher auszumustern. Die Filterzeile lässt dich nach Rolle, Ersteller und Ablaufzeitraum einengen. Die Standardsortierung ist „zuletzt erstellt zuerst"; die sekundäre Sortierung ist „zuletzt genutzt". ## Einen Schlüssel rotieren Zum Rotieren erstellst du zuerst den neuen Schlüssel, deployst ihn auf das System, das den alten nutzt, prüfst, dass der neue funktioniert (der Zeitstempel der letzten Nutzung aktualisiert sich), und widerrufst erst dann den alten. Tale rotiert Schlüssel nicht automatisch; die Disziplin der Überlappung liegt bei dir. Rotation ist die richtige Bewegung, wenn ein Verdacht auf Leck besteht, wenn jemand mit Zugriff auf den Schlüssel die Organisation verlässt, oder in dem Rhythmus, den deine Sicherheitsrichtlinie vorgibt. ## Einen Schlüssel widerrufen Klick auf die Zeile, dann auf **Widerrufen**. Ein widerrufener Schlüssel authentifiziert sofort nicht mehr — jede laufende Anfrage wird abgeschlossen, aber die nächste schlägt mit `401` fehl. Widerrufene Schlüssel bleiben für den Audit-Pfad in der Tabelle; die Zeile markiert sie als widerrufen und zeigt, wer wann widerrufen hat. Es gibt kein Undo für einen Widerruf; wenn du den falschen widerrufen hast, lege einen neuen an. ## Bereiche und Grenzen Jeder Schlüssel trägt die Berechtigungen seiner Rolle zum Zeitpunkt jeder Anfrage, nicht zum Zeitpunkt der Erstellung. Wenn du die Berechtigungen einer Rolle über eine Governance-Richtlinie änderst, erbt jeder Schlüssel mit dieser Rolle die Änderung bei der nächsten Anfrage. Die Rate-Limits der Organisation gelten pro Schlüssel, nicht pro Organisation; ein lauter Schlüssel drosselt keinen ruhigen. Ein Schlüssel kann bei der Erstellung weiter durch eine IP-Allowlist eingeschränkt werden. Die Allowlist nimmt eine kommagetrennte Liste von CIDR-Blöcken; Anfragen außerhalb der Liste schlagen mit `403` fehl. Greif zur IP-Allowlist, wenn das aufrufende System einen stabilen Egress hat und du Tiefenverteidigung willst. ## Wo das hingehört API-Schlüssel sind die Brücke zwischen Tale und externem Code; sie sitzen neben [Connectors](/de/platform/admin/connectors) (Drittanbieter-Systeme, die Tale aufruft) und [Automatisierungs-Webhook-Triggern](/de/platform/automations/triggers) (Systeme, die Tale bei Ereignissen aufrufen). Die natürliche nächste Lektüre ist die REST-API selbst — siehe die API-Referenz im Develop-Tab für die Oberfläche, gegen die ein Schlüssel authentifiziert, und siehe [Mitglieder und Rollen](/de/platform/admin/members-and-roles) für die Rollen-zu-Berechtigungen-Karte, die jeder Schlüssel erbt. # Richtlinien und Limits Source: https://tale.dev/docs/de/platform/admin/governance/policies-and-limits Richtlinien und Limits ist die Oberfläche, auf der du deckelst, was deine Mitglieder und Agents verbrauchen können. Budgets deckeln Tokens, Kosten und Anfragen pro Abrechnungsperiode; Feature-Kontrollen schalten Web-Suche, Code-Ausführung und Datei-Upload pro Bereich um; Upload-Richtlinie regelt Dateitypen und Größen, die ein Mitglied anhängen darf; Aufbewahrungsrichtlinie entscheidet, wie lange jeder Datentyp lebt, bevor Cleanup eingreift. Admins und Inhaber lesen diese Seite, wenn eine Last über Budget ist, wenn ein Feature für eine Untermenge von Benutzern aus sein soll, oder wenn ein Regulierer ein Aufbewahrungsfenster benennt, das vom Default abweicht. <Frame caption="Governance > Richtlinien & Limits — die Tabelle der Budget-Regeln über der Upload-Richtlinie und den Aufbewahrungs-Kontrollen."> ![Die Governance-Seite Richtlinien und Limits zeigt drei monatliche Budget-Regeln — eine für die gesamte Organisation, eine als Default für alle Benutzer und eine für die Rolle developer, jede mit Obergrenzen für Tokens, Kosten und Anfragen — über den Feldern der Upload-Richtlinie für erlaubte Dateitypen, Größen und Volumen.](/images/platform/governance-policies-limits.webp) </Frame> ## Ein durchgespieltes Budget Um die monatlichen Ausgaben eines Redakteurs zu deckeln, öffne **Einstellungen > Richtlinien > Budgets** und klick auf **Regel hinzufügen**. Wähle **Rolle** als Bereich, **Redakteur** als Ziel, setze die Periode auf **Monatlich** und trage einen Höchstbetrag in USD ein. Speichern, und die nächste Monats-Periode-Anfrage, die einen Redakteur über das Limit drücken würde, wird mit einem Budget-überschritten-Fehler abgelehnt. Eine Warnschwelle unter dem Limit löst eine Warnung aus, bevor das Limit erreicht wird. Engere Bereiche übersteuern weitere — eine Benutzerregel schlägt eine Team-Regel schlägt eine Rollen-Regel — und org-weite Limits wirken immer zusätzlich obendrauf. ## Die vier Richtlinienebenen **Budgets** sind Token-, Kosten- und Anfragen-Limits pro Bereich und Periode. Bereiche sind Organisation, Rolle, Team, Benutzer oder API-Schlüssel. Jede Regel trägt ein Token-Limit, ein Kosten-Limit in USD, ein optionales Anfragen-Limit und eine Warnschwelle als Prozentwert des Limits. Eine API-Schlüssel-Regel zielt auf einen einzelnen ausgestellten Schlüssel (wähle **API-Schlüssel** als Bereich, dann den Schlüssel aus **Einstellungen > API**) und deckelt nur den mit diesem Schlüssel authentifizierten Traffic — die REST- und OpenAI-kompatible API — sodass du eine einzelne Connector messen kannst, ohne die In-App-Nutzung zu berühren. Bildgenerierung wird nach Kosten und Anzahl Anfragen gemessen, nicht nach Tokens — eine Bild-Anfrage meldet keine Tokens, also deckle Bild-Ausgaben mit dem Kosten- oder Anfragen-Limit, nicht mit dem Token-Limit. **Feature-Kontrollen** schalten Web-Suche, Code-Ausführung und Datei-Upload pro Bereich um und deckeln die maximalen Kontext-Tokens für AI-Antworten. Ein Feature, das für einen Bereich aus ist, blendet die Schaltfläche im Chat aus und lehnt die Anfrage serverseitig ab. **Upload-Richtlinie** regelt Dateierweiterungen, MIME-Typen und Größen, die ein Mitglied anhängen darf. Sie deckelt zudem das Gesamtvolumen pro Benutzer — nützlich, wenn Speicher gemessen wird. Schalte die Richtlinie aus für einen permissiven Default; schalte sie ein, um die Listen durchzusetzen. **Aufbewahrungsrichtlinie** entscheidet, wie lange jeder Datentyp (Chatverlauf, Dokumente, Prompts, Audit-Logs, Nutzungsbuch, Workflow-Läufe und mehr) bleibt, bevor der Cleanup-Lauf die Zeile entfernt. Die Seite zeigt die vom Betreiber gesetzten Grenzen, die Per-Org-Überschreibung innerhalb dieser Grenzen und ein Kulanzfenster vor der harten Löschung. ## Vorrang Alle vier Ebenen teilen sich dieselbe Bereichsleiter: Benutzer > Team > Rolle > Organisation > Default. Die engste Regel gewinnt. Wo eine Ebene ein org-weites Limit trägt (Budgets), wirkt das Limit als zusätzliche Decke über jeder engeren Regel. Ein API-Schlüssel-Budget steht außerhalb der Leiter als eigener, unabhängiger Topf: Es bindet den Traffic des Schlüssels selbst, unabhängig von den Benutzer-, Team- oder Org-Limits des Inhabers, sodass ein einzelner Schlüssel enger gedeckelt werden kann als die Person, die ihn ausgestellt hat. ## Aufbewahrungs-Grenzen und Freigaben Die Aufbewahrungsrichtlinie sitzt innerhalb von Grenzen, die der Betreiber gesetzt hat — der Selbsthosting-Betreiber setzt eine Untergrenze und eine Obergrenze pro Kategorie, und der Org-Wert klemmt auf diesen Bereich. Wenn der Betreiber eine engere Untergrenze oder eine niedrigere Obergrenze vorschlägt, erscheint die Änderung als Vorschlag, den Admins anwenden oder ablehnen können. Reduzierungen der Richtlinie landen mit einem Pending-Banner und einem Kulanzfenster, bevor sie wirken — dieselbe Kulanz gibt Admins die Möglichkeit, abzubrechen. ## Sitzungs-Leerlaufzeit Die Sitzungs-Leerlaufzeit meldet Mitglieder nach einer Phase der Inaktivität ab — die sitzungsgebundene Kontrolle, die Compliance-Rahmenwerke verlangen (SOC 2 CC6.1). Öffne **Einstellungen > Richtlinien > Sicherheit & Überwachung**, schalte **Sitzungs-Leerlaufzeit aktivieren** ein und setze **Leerlaufzeit (Minuten)** (1–1440, Standard 30). Mitglieder sehen kurz vor dem Ablauf eine Warnung; danach meldet sich der aktive Tab ab, und die Anmeldeseite erklärt die Abmeldung, statt nur ein leeres Formular zu zeigen. Das Fenster kann das installationsweite Limit nur verkürzen, niemals verlängern. Selbsthosting-Betreiber setzen diese harte Obergrenze per Umgebungsvariable (siehe die [Umgebungsreferenz](/de/self-hosted/configuration/environment-reference)); die Org-Richtlinie wirkt obendrauf, und das engere der beiden Fenster gewinnt. Ein Mitglied mehrerer Organisationen bekommt das engste Fenster über alle seine Organisationen. Die Durchsetzung hat zwei Hälften. Der Watchdog im Browser beendet offene, sichtbare Sitzungen auf die Minute. Geschlossene Tabs und liegen gelassene Geräte fängt serverseitig ein Widerrufs-Lauf ab, der etwa alle fünf Minuten läuft — eine Sitzung kann das Fenster also um einige Minuten überleben; wenn du die Kontrolle gegenüber einem Auditor benennst, rechne mit dem Fenster plus rund einer halben Stunde im schlechtesten Fall. Jeder serverseitige Widerruf landet als `session.idle_revoked` in den [Audit-Logs](/de/platform/admin/governance/audit-logs). Eine Einschränkung für Trusted-Headers-Deployments: dort besitzt der Reverse Proxy die Authentifizierung, eine widerrufene Sitzung entsteht also neu, sobald das Mitglied den Anmelde-Hinweis bestätigt — kombiniere die Richtlinie mit einer Leerlaufzeit auf Proxy- oder IdP-Seite für eine echte Sperre. ## Konversations-Routing Eingehende Post landet unzugewiesen, sofern keine Routing-Regel sie beansprucht. Unter **Einstellungen > Governance > Richtlinien & Grenzen** öffnest du **Konversations-Routing** und legst eine Regel an, die eine Empfängeradresse einem Team, einer Person oder beiden zuordnet: Die nächste Konversation, die an dieser Adresse eintrifft, wird im Moment ihrer Erstellung zugewiesen, bevor jemand die Inbox öffnet. Eine Regel trifft auf die Adresse zu, an die die absendende Person geschrieben hat — das `An` der Konversation — und zwar unabhängig von Groß- und Kleinschreibung; eine Adresse ohne Regel bleibt unzugewiesen. Die Sichtbarkeit ist eingebaut: eine einem Team zugewiesene Konversation ist nur für dessen Mitglieder sichtbar, eine einer Person zugewiesene nur für diese Person (bei beiden die Vereinigung). Wirklich unzugewiesene Konversationen — weder Person noch Team — sehen nur Admins und Inhaber, die sie sichten. Mitglieder und Redakteure sehen nur Arbeit, die in ihre Person- oder Team-Warteschlange geroutet oder zugewiesen wurde. Kombiniere Routing mit der Steuerung **Zuständig** in der Kopfzeile, damit eingehende Post in der richtigen Warteschlange landet. Routing weist nur zu; eine Konversation, die bereits eine Inhaberin oder ein Team hat, wird nie neu zugewiesen — eine Antwort, die sich in einen bestehenden Thread einreiht, bleibt also unberührt. Eine Regel, die auf ein zwischenzeitlich gelöschtes Team oder eine gelöschte Person zeigt, wird übersprungen — die Konversation trifft trotzdem ein, nur unzugewiesen für die Admin-Sichtung. ## Wo das hingehört Richtlinien und Limits ist die Budget- und Schleusen-Ebene, die die Organisation vor entgleitenden Ausgaben und unbeabsichtigtem Zugriff schützt. Paare das mit [Inhalte und Modelle](/de/platform/admin/governance/content-models), sodass das vom Budget gedeckelte Modell auch das ist, das die Zugriffsliste erlaubt, und mit [Aufbewahrungsrichtlinie auf derselben Seite](#aufbewahrungs-grenzen-und-freigaben), sodass die Daten, die die Organisation behält, ebenfalls begrenzt sind. Die Begleitseite ist [Audit-Logs](/de/platform/admin/governance/audit-logs) — jede Richtlinienänderung hier landet dort als dauerhafte Aufzeichnung. # Papierkorb Source: https://tale.dev/docs/de/platform/admin/governance/trash Papierkorb ist die Wiederherstellungsoberfläche für die Zeilen, die die Aufbewahrung soft-gelöscht, aber noch nicht hart-gelöscht hat. Wenn ein Chat-Thread, ein Dokument, eine Prompt-Vorlage oder ein Workflow-Lauf sein Aufbewahrungsfenster überschreitet, wandert er für das konfigurierte Kulanzfenster hierhin, bevor der nächste Cleanup-Lauf ihn endgültig entfernt. Admins und Inhaber lesen diese Seite, wenn ein Mitglied ein gelöschtes Artefakt zurückbittet, wenn ein Workflow das Falsche gelöscht hat, oder wenn ein Audit wissen muss, ob eine Zeile noch wiederherstellbar ist. ## Eine durchgespielte Wiederherstellung Um einen Chat-Verlauf-Thread wiederherzustellen, öffne **Einstellungen > Richtlinien > Papierkorb** und stelle den Filter **Kategorie** auf **Chatverlauf**. Jede Zeile trägt den Typ, den Namen, den Eigentümer, den Status und wann sie verworfen wurde. Klick auf **Wiederherstellen** in der Zeile, bestätige im Dialog, und die Zeile kehrt in ihre Quellliste zurück — Chat-Threads erscheinen wieder im Konversations-Posteingang und Dokumente in der Wissensdatenbank. Eine durch Aufbewahrung abgelaufene Zeile wiederherzustellen verlangt das Tippen von `restore` zur Bestätigung und wird als Überschreibung der Aufbewahrungsrichtlinie auditiert. ## Die zwei Status **Verworfen** ist der normale Soft-Delete-Zustand. Das Aufbewahrungsfenster der Zeile ist abgelaufen, sie ist in den Papierkorb gewandert, und das Kulanzfenster tickt noch. Wiederherstellen führt die Zeile in ihre Quellliste zurück, ohne die Richtlinie zu überschreiben. **Abgelaufen** ist der zweite Zustand — das Kulanzfenster ist abgelaufen und die Zeile ist für die endgültige Löschung im nächsten Cleanup vorgemerkt. Wiederherstellen ist weiterhin möglich, aber es ist eine Überschreibung: der Dialog verlangt, dass du `restore` tippst, und das Audit-Log dokumentiert die Überschreibung mit deinem Namen. ## Die Kategorien Der Papierkorb hält Zeilen aus vielen Kategorien. Der Kategoriefilter wechselt die Ansicht pro Tab: - Chatverlauf (Threads) - Dokumente - Temporäre Dateien - Prompt-Vorlagen - Nachrichten-Feedback - Kontakte - Lieferanten - Externe Konversationen - Nachrichten-Metadaten - Workflow-Läufe - Workflow-Trigger-Logs - Nutzungsbuch - Audit-Logs - Chat-Filter-Ereignisse - Memory-Audit Jede Kategorie respektiert ihr eigenes Aufbewahrungsfenster und ihr eigenes Kulanzfenster — gesetzt in der Aufbewahrungsrichtlinie unter [Richtlinien und Limits](/de/platform/admin/governance/policies-and-limits). ## Interaktion mit Legal Hold Zeilen unter Legal Hold erscheinen nicht im Papierkorb — der Hold heftet sie außer Reichweite jedes Aufbewahrungs-Schritts. Wenn du versuchst, eine gehaltene Zeile aus ihrer Quellliste zu löschen, lehnt Tale mit der Nachricht **Löschen ist durch einen aktiven Legal Hold gesperrt** ab. Den Hold aufheben lässt die Aufbewahrung die Zeile durch das Papierkorb-Fenster laufen, wie andere Kategorien fließen. ## Das Kulanzfenster Das Kulanzfenster ist pro Kategorie in der Aufbewahrungsrichtlinie konfigurierbar. Ein Kulanz-Wert von null überspringt den Papierkorb komplett — der Cleanup-Lauf löscht die Zeile hart, sobald die Aufbewahrung auslöst. Ein Wert über null hält die Zeile diese Anzahl Tage im Papierkorb und zeigt sie hier für das Admin-Fenster, in dem Wiederherstellen noch billig ist. ## Wo das hingehört Papierkorb ist die zweite Chance, die die Aufbewahrung jeder Kategorie gibt, bevor der Cleanup-Lauf eine Zeile endgültig entfernt. Er paart mit [Richtlinien und Limits](/de/platform/admin/governance/policies-and-limits) — die Aufbewahrungsseite setzt die Fenster; diese Seite ist die Wiederherstellungsansicht, in die diese Fenster speisen. Die Begleitseite ist [Legal Hold](/de/platform/admin/governance/legal-hold) — der einzige Mechanismus, der die Aufbewahrung schlägt, bevor eine Zeile überhaupt im Papierkorb landet. # Audit-Logs Source: https://tale.dev/docs/de/platform/admin/governance/audit-logs Das Audit-Log ist die unveränderliche Aufzeichnung jeder folgenreichen Aktion in deiner Organisation. Jede Anmeldung, Rollenänderung, Anbieter-Bearbeitung, Agent-Speicherung, Workflow-Ausführung und jeder Sandbox-Aufruf landet hier mit Akteur, Ressource, Vorher-/Nachher-Status und Zeitstempel. Admins und Inhaber lesen das, wenn ein Audit fragt, wer eine Ressource wann angefasst hat, wenn ein Compliance-Officer einen Export braucht, oder wenn etwas schiefläuft und die Frage ist _wer hat um 03:14 was geändert_. Diese Seite ist die Referenz für die Spalten, die Filter, die Kategorien und die Exportformate. Das Aufbewahrungsfenster für Audit-Zeilen wird im selben Governance-Bereich unter der Aufbewahrungsrichtlinie gesetzt — halte es lang genug, damit deine Compliance-Anforderungen erfüllt sind, bevor Zeilen ausgesteuert werden. ## Ein durchgespielter Filter Um den Moment zu finden, in dem die Rolle eines Mitglieds geändert wurde, öffne **Einstellungen > Richtlinien > Audit-Logs**, setze den Filter **Kategorie** auf **Mitglied** und suche nach Akteur oder Ziel über den Namen. Jede Zeile öffnet die volle Payload — vorheriger Status, neuer Status, die IP, wenn die Anfrage über das Netz kam, der Akteurstyp (Benutzer, System, API, Workflow). Exportiere die gefilterte Auswahl über die Symbolleiste über der Tabelle als CSV oder JSON. ## Die Spalten | Name | Typ | Pflicht | Beschreibung | | ---------------- | -------- | ------- | ------------------------------------------------------------------------------------------- | | Zeitstempel | ISO 8601 | ja | Serverzeit, zu der die Aktion committet wurde. | | Aktion | string | ja | Die semantische Aktion — `update_member_role`, `provider_created`, `agent_saved`. | | Benutzer | string | ja | Anzeigename des Akteurs; `System`, `API` oder `Workflow`, wenn der Akteur keine Person ist. | | Ressource | string | ja | Die berührte Ressource — `agent`, `provider`, `member`, `workflow`. | | Kategorie | enum | ja | Auth, Mitglied, Daten, Connector, Workflow, Sicherheit, Admin, AI, Skill, Agent. | | Status | enum | ja | Erfolg, Fehlschlag, Verweigert. | | Geänderte Felder | JSON | nein | Der Diff zwischen vorherigem und neuem Status bei Update-Aktionen. | ## Filter Filtere nach Zeitraum, Kategorie, Status, Akteur, Ressource oder Freitext über die Aktionsnamen. Kombiniere Filter — ein Zeitraum plus die Kategorie **Sicherheit** plus Status **Verweigert** bringt die fehlgeschlagenen Anmeldeversuche in einem Fenster zum Vorschein. Der Filterzustand spiegelt sich in der URL, sodass ein gespeicherter Link dieselbe Ansicht wieder öffnet. ## Exportieren Zwei Exportformate werden ausgeliefert: CSV für Tabellenkalkulationen und JSON für nachgelagerte Systeme. Beide respektieren die aktiven Filter — was du exportierst, ist was du siehst. Setz die Filter, die du willst (der durchgespielte Filter oben ist das Muster), und wähl dann CSV oder JSON aus der Symbolleiste über der Tabelle. Große Exporte streamen als Download; die Symbolleiste meldet Fortschritt und meldet Abschluss mit Dateigröße und Zeilenanzahl. Die CSV kommt als `audit-logs-<timestamp>.csv`, eine Zeile pro Aktion, mit einer flachen Spalte pro Feld; Zeitstempel sind ISO 8601 in UTC und jeder Wert mit einem Komma wird in Anführungszeichen gesetzt: ```csv timestamp,action,category,actorEmail,actorId,actorType,actorRole,resourceType,resourceId,resourceName,status,errorMessage 2026-01-14T03:14:07.000Z,member.role_changed,Member,admin@acme.example,usr_8f3a,user,owner,member,usr_2b91,jordan@acme.example,success, 2026-01-14T03:15:22.000Z,provider.updated,Provider,admin@acme.example,usr_8f3a,user,owner,provider,prov_openai,OpenAI,success, ``` Der JSON-Export (`audit-logs-<timestamp>.json`) trägt dieselben Zeilen als vollständige Objekte plus die Felder, die CSV wegflacht — den `previousState`/`newState`-Diff und den `integrityHash` pro Zeile. Greif zu JSON, wenn ein nachgelagertes System die Vorher/Nachher-Payload braucht oder jede Zeile gegen die SHA-256-Kette neu verifizieren muss (siehe Abschnitt „Aufbewahrung und Integrität" weiter unten); greif zu CSV, wenn eine Person sie in einer Tabellenkalkulation öffnet. ## Aufbewahrung und Integrität Audit-Zeilen sind unveränderlich: Bearbeitungen und Löschungen werden selbst auditiert, und das Zeilenschema trägt einen Integritäts-Hash, den du gegen den Export prüfen kannst. Eine täglich geplante Prüfung verifiziert die Hash-Kette serverseitig erneut und schreibt einen `security`-Audit-Eintrag, wenn die Verifikation fehlschlägt — sodass Manipulation oder eine Löschung außer der Reihe auch dann auffällt, wenn niemand die manuelle Prüfung ausführt. Eine fehlgeschlagene Prüfung löst zusätzlich eine kritische In-App-Benachrichtigung an die Admins der Organisation aus und geht an Slack, wenn ein Slack-Benachrichtigungskanal konfiguriert ist. Die Aufbewahrung steht standardmäßig auf 90 Tagen und ist auf der Seite zur Aufbewahrungsrichtlinie konfigurierbar (30 bis 365 Tage). Zeilen, die altern, werden vom nächsten Cleanup-Lauf entfernt — es gibt kein Soft-Delete-Fenster für Audit-Daten. ## Wo das hingehört Das Audit-Log ist die Leseseite jedes anderen Governance-Features: Legal Hold benennt die platzierten Holds, Anfragen betroffener Personen protokollieren jeden Cascade-Schritt, die Run-code-Richtlinie protokolliert die URLs, die jede Sandbox zu erreichen versuchte. Wenn eine Frage mit _wer, wann, was_ beginnt, ist das Audit-Log die Antwort. Die Begleitseite ist die [Aufbewahrungsrichtlinie](/de/platform/admin/governance/policies-and-limits) — sie steuert, wie lange diese Zeilen bleiben, bevor Cleanup sie entfernt. # Anfragen betroffener Personen Source: https://tale.dev/docs/de/platform/admin/governance/data-subject-requests Anfragen betroffener Personen ist der Workflow, den Tale für die Einhaltung von DSGVO Artikel 17 (Recht auf Löschung) und das entsprechende CCPA-Recht nach kalifornischem Recht ausliefert. Jede Anfrage wird zu einem Beleg: er nennt die betroffene Person, den Begründungs-Code, die SLA-Frist und die Kaskade von Zeilen, die das System über Threads, Dokumente, Workflow-Ausführungen und persönliche Prompt-Vorlagen hinweg gelöscht hat. Admins und Inhaber lesen diese Seite, wenn eine Person eine Anfrage stellt, wenn eine Frist näher rückt, oder wenn ein Audit den Beleg einer vergangenen Löschung verlangt. <Frame caption="Governance > Anfragen betroffener Personen — die DSAR-Governance-Richtlinie (Cooling-off-Fenster, Vier-Augen-Freigabe, Tageslimit) über der Liste der Anfrage-Belege mit Anfrage einreichen."> ![Die Governance-Seite Anfragen betroffener Personen zeigt das Cooling-off-Fenster, den Schalter für die Vier-Augen-Freigabe und die Tageslimit-Felder über einer Tabelle der Löschungs-Anfragen mit einer offenen Anfrage — betroffene Person Jordan Blake, Begründungs-Code Einwilligung widerrufen, noch 24 Stunden bis zur Ausführung und 29 Tage SLA-Frist —, daneben die Schaltfläche Anfrage einreichen.](/images/platform/governance-data-subject-requests.webp) </Frame> ## Eine durchgespielte Einreichung Um eine Anfrage einzureichen, öffne **Einstellungen > Richtlinien > Anfragen betroffener Personen** und klick auf **Anfrage einreichen**. Wähle die betroffene Person, wähle einen Begründungs-Code (Einwilligung widerrufen, nicht mehr erforderlich, unrechtmäßige Verarbeitung, rechtliche Verpflichtung, Widerspruch, minderjährige Person oder Vertragsende) und füge eine Freitext-Begründung hinzu. Die Anfrage tritt in ein Cooling-off-Fenster ein, bevor die Kaskade läuft — jeder Admin kann während des Fensters abbrechen. Nach Ablauf des Fensters löscht die Kaskade die Threads, Dokumente, Workflow-Ausführungen, RAG-Embeddings und persönlichen Prompts der Person, und der Beleg dokumentiert die Zähler für jede Kategorie. ## Status-Lebenszyklus | Name | Default | Beschreibung | | ------------------- | -------------- | -------------------------------------------------------------------------------------------------- | | Ausstehend | Anfangszustand | Die Anfrage ist eingereicht und wartet auf das Cooling-off-Fenster oder die zweite Admin-Freigabe. | | Wartet auf Freigabe | Vier-Augen | Ein zweiter Admin muss freigeben, bevor die Kaskade läuft. | | Läuft | mid-cascade | Die Kaskade läuft; Teilzähler aktualisieren sich, sobald jede Kategorie fertig ist. | | Abgeschlossen | terminal | Jede Kategorie ist ohne Fehler gelöscht. | | Teilweise | terminal | Einige Zeilen wurden übersprungen — meist hat ein Legal Hold sie blockiert. | | Fehlgeschlagen | terminal | Die Kaskade traf auf einen Fehler; der Beleg benennt die fehlgeschlagene Kategorie. | | Blockiert | terminal | Ein aktiver Legal Hold blockiert jeden Kaskade-Schritt. | | Abgebrochen | terminal | Ein Admin hat vor Ablauf des Cooling-off-Fensters abgebrochen. | ## SLA-Verfolgung Jede Anfrage trägt eine Service-Level-Frist — standardmäßig 30 Tage ab Einreichung. Die Anfragenliste zeigt verbleibende Tage oder ein Überfällig-Badge pro Zeile. Artikel 12(3) DSGVO erlaubt eine einmalige Verlängerung für komplexe Fälle; die Aktion **Frist verlängern** vermerkt die Verlängerung auf dem Beleg mit dem Namen des anfordernden Admins und einer Begründung. ## Interaktion mit Legal Hold Daten einer betroffenen Person werden _nicht_ gelöscht, solange sie auf Legal Hold liegen. Zeilen unter Hold erscheinen im Beleg in den Per-Kategorie-Zählern als **Durch Legal Hold übersprungen**; den Hold aufheben und die Anfrage erneut versuchen schließt die Löschung ab. Der Status Blockiert greift, wenn ein Hold von Anfang an jede Kategorie abdeckt — die Kaskade läuft nicht, und der Beleg spiegelt die Blockade. ## Die Kaskade-Kategorien Der Beleg schlüsselt die gelöschten Zeilen nach Kategorie auf — Threads, Dokumente, Workflow-Ausführungen, Prompt-Vorlagen, aus dem Vektorspeicher entfernte RAG-Dokumente. Lies das Drawer für Zähler und die Audit-Zeitleiste; das Audit-Log im selben Governance-Bereich trägt die volle Ereigniskette (`gdpr_erasure_requested`, `gdpr_erasure_executed`, `gdpr_erasure_extended`, `gdpr_erasure_cancelled`). ## Wo das hingehört Anfragen betroffener Personen ist das Compliance-Gesicht der Aufbewahrung — der auditierte, vier-Augen-kontrollierte Pfad, der eine bestimmte Person auf Anfrage löscht, statt der zeitgesteuerten Sweeps, die die Aufbewahrung über alle hinweg läuft. Die Begleitseite ist [Legal Hold](/de/platform/admin/governance/legal-hold) — sie deckt ab, wie Aufbewahrung und Löschungs-Kaskaden für Rechtsstreitigkeiten pausiert werden, bevor sie laufen. # Inhalte und Modelle Source: https://tale.dev/docs/de/platform/admin/governance/content-models Inhalte und Modelle ist die Oberfläche, auf der du entscheidest, welche LLMs die Personen in deiner Organisation erreichen können und auf welchem jede Gruppe per Default landet. Sie verbindet eine Zulassungs- oder Sperrliste pro Bereich (Organisation, Team, Rolle, Benutzer) mit einer Default-Modell-Regel, die der Resolver anwendet, wenn weder ein Agent noch eine Konversation die Wahl überschrieben hat. Admins und Inhaber lesen diese Seite, wenn eine Compliance-Regel eine Last an ein freigegebenes Modell bindet, wenn ein Team auf einem günstigeren Modell als der Rest der Organisation landen soll, oder wenn ein neues Modell eines bestehenden Anbieters erreichbar gemacht werden muss. <Frame caption="Governance > Inhalte & Modelle — der verpflichtende System-Prompt-Präfix und -Suffix über den Default-Modell-Regeln pro Bereich."> ![Die Governance-Seite Inhalte und Modelle zeigt die Felder für den verpflichtenden System-Prompt-Präfix und -Suffix, gefüllt mit den Hausregeln der Organisation, über einer Tabelle mit drei Default-Modell-Regeln — einem Default für alle Benutzer und je einer Rollen-Regel für Entwickler und Mitglied, jede auf ein OpenRouter-Modell festgelegt.](/images/platform/governance-content-models.webp) </Frame> ## Ein durchgespielter Default Um das Default-Modell für die Redakteur-Rolle zu setzen, öffne **Einstellungen > Richtlinien > Standardmodelle** und klick auf **Regel hinzufügen**. Wähle **Rolle** als Bereich, **Redakteur** als Ziel, dann wähle den Anbieter und das Modell. Speichern, und die nächste Anfrage eines Redakteurs ohne expliziten Per-Agent- oder Per-Konversations-Override landet auf dem Modell der Regel. Engere Bereiche gewinnen — eine Benutzerregel schlägt eine Team-Regel schlägt eine Rollen-Regel schlägt den Org-Default. ## Die zwei Ebenen **Modellzugriff** ist die Zulassungs- oder Sperrliste, die regelt, welche Modelle ein Bereich überhaupt nutzen darf. Ein Modell, das nicht auf der Zulassungsliste steht, ist für diesen Bereich unsichtbar — die Auswahl blendet es aus und der Resolver weigert sich, daran zu binden, selbst wenn ein Agent es gepinnt hat. Greif zur Zulassungsliste, wenn ein Regulierer die freigegebenen Modelle benennt; greif zur Sperrliste, wenn ein einzelnes Modell überall sonst nicht erreichbar sein soll. **Standardmodelle** ist die Resolver-Regel, die das Modell auswählt, wenn nichts anderes es getan hat — kein Per-Agent-Override, kein Per-Konversations-Override. Der Default wirkt in dem Moment, in dem der Benutzer einen frischen Chat startet, und wirkt als Fallback, wenn das gepinnte Modell eines Agents nicht erreichbar ist. ## Bereiche und Vorrang Beide Ebenen tragen einen Bereich: Organisation, Team, Rolle oder Benutzer. Der Resolver wertet von eng nach weit aus — Benutzer schlägt Team schlägt Rolle schlägt Org-Default. Die Modellzugriffs-Ebene kombiniert mit der Default-Modell-Ebene; der Default, den der Resolver wählt, muss auch die Zugriffsprüfung für denselben Bereich bestehen, andernfalls fällt der Resolver auf das nächste erlaubte Modell zurück. ## Zulassungs- und Sperrlisten-Warnungen Der Default-Modell-Editor zeigt eine Warnung, wenn eine Regel ein Modell nennt, das die Zulassungsliste für denselben Bereich nicht erlaubt, oder wenn die Sperrliste für denselben Bereich es blockiert. Die Warnung blockiert das Speichern nicht — der Resolver wird zur Anfragezeit zurückfallen — aber sie markiert die Diskrepanz, damit du das eine oder das andere korrigieren kannst. ## Das Modell, das Bilder liest Nicht jedes Modell kann sehen. Öffnet ein Agent auf einem reinen Textmodell einen Screenshot, eine eingescannte Rechnung oder eine gerenderte Folie, gibt Tale dieses Bild an ein zweites Modell und liefert dem Agenten die Abschrift zurück. Das läuft über das Gateway, es gelangt also kein Provider-Schlüssel in die Sandbox — und Modelle, die Bilder ohnehin lesen, überspringen den Umweg ganz. **Modell für Bilder** legt fest, wer diese Arbeit übernimmt. Bleibt es auf **Automatisch**, wählt Tale selbst: bevorzugt ein empfohlenes Modell für Bilder, sonst das günstigste, das deine Zugänge erreichen. Die Zeile unter der Auswahl nennt immer das Modell, das die Bilder gerade liest, und warum es gewählt wurde — die Frage „welches Modell liest unsere Bilder" bleibt damit nie offen. Lege ein Modell fest, wenn diese Wahl stehen bleiben soll. Automatisch liest einen aktuellen Provider-Katalog, das günstigste erreichbare Modell wechselt also mit jeder neuen Veröffentlichung — ein festgelegtes Modell hält die Strecke auf dem, das du getestet hast. Angeboten werden nur Modelle, die tatsächlich abschreiben können: Modelle, die Medien erzeugen, und kostenlose Zugänge fallen heraus, weil beide ein Bild annehmen und die Anfrage dann verweigern. Ist ein festgelegtes Modell später nicht mehr erreichbar — der Zugang wurde rotiert, die Zulassungsliste enger, der Provider hat es entfernt — protokolliert Tale das und fällt auf Automatisch zurück, statt deine Agenten blind arbeiten zu lassen. ## Wo das hingehört Inhalte und Modelle ist die Schleuse, die jeder Chat und jeder Agent zur Anfragezeit durchläuft. Modellzugriff mit Standardmodellen zu kombinieren erlaubt dir, eine enge Compliance-Haltung auszuliefern, ohne jedem Agent-Autor das Modell aufzuzwingen, das in diesem Quartal genehmigt ist. Die Begleitseite ist [Richtlinien und Limits](/de/platform/admin/governance/policies-and-limits) — sie deckt die Kosten- und Anfragen-Limits ab, die zusätzlich zu den hier getroffenen Modellwahlen gelten. # Nutzungs-Analyse Source: https://tale.dev/docs/de/platform/admin/governance/usage-analytics Nutzungs-Analyse ist das Dashboard, das jeden abrechenbaren AI-Aufruf in einer einzigen Ansicht von Tokens, Kosten und Anfragenvolumen aggregiert. Es schneidet nach Benutzer, Team, Rolle, Modell, Agent und Zeit, sodass die unerwartete Zeile auf der Rechnung zur Last zurückführbar ist, die sie verursacht hat. Admins und Inhaber lesen diese Seite, wenn eine Rechnung unerwartet ist, wenn die Führung die grobe Form der AI-Ausgaben will, oder wenn eine Budgetwarnung auslöst und die nächste Frage _wer und was_ ist. ## Eine durchgespielte Detailansicht Öffne **Einstellungen > Richtlinien > Nutzung**. Die Default-Ansicht sind die letzten 30 Tage, org-weit, mit den drei Kennzahlen-Zählern — Tokens insgesamt, Kosten insgesamt in USD, Anfragen insgesamt. Wechsle die Aufschlüsselung auf **Nach Benutzer**, um die größten Verbraucher zu finden, **Nach Modell**, um ein teures Primärmodell mit einem günstigeren Fallback zu vergleichen, oder **Nach Agent**, um den Agent zu finden, der die Last treibt. Jede Zeile öffnet eine Per-Zeile-Zeitreihe; die Diagrammachse folgt der gewählten Periode. ## Die Dimensionen - **Benutzer** — jedes Mitglied, das einen abrechenbaren Aufruf ausgelöst hat. Paare mit dem Team- oder Rollenfilter, um die Ansicht einzugrenzen. - **Team** — aggregiert über Team-Mitglieder; nützlich, wenn Budgets team-gebunden sind. - **Rolle** — Inhaber, Admin, Entwickler, Redakteur, Mitglied. - **Modell** — jedes Modell, das eine Antwort erzeugt hat, gruppiert nach Anbieter. - **Agent** — jeder benannte Agent (die Rangliste sortiert nach Token-Volumen, Kosten oder Anfragenzahl). - **Zeit** — täglicher Trend für kurze Fenster, wöchentlich für längere. ## Das Kostenmodell Kosten sind eine Schätzung. Jede Anfrage landet im Nutzungsbuch mit Eingabe-Tokens, Ausgabe-Tokens, dem veröffentlichten Preis des Modells pro Million Tokens und der Wanduhr-Dauer. Das Dashboard multipliziert Tokens mit Preis; Bildgenerierungsaufrufe landen mit einem Per-Bild-Preis, den der Anbieter zurückgibt. Die Zeile im Nutzungsbuch ist die Quelle der Wahrheit, und das [Audit-Log](/de/platform/admin/governance/audit-logs) trägt Akteur und Zeitstempel der Zeile für den Quervergleich. ## Budget-Überlagerungen Wenn [Richtlinien und Limits](/de/platform/admin/governance/policies-and-limits) ein Budget für einen Bereich hat, überlagert das Nutzungs-Diagramm das Limit als horizontale Linie. Beim Hovern auf einen Punkt erscheint der verbrauchte Anteil des Limits und der projizierte Monatsendwert basierend auf dem aktuellen Trend. Das Überschreiten der Warnschwelle färbt die Reihe orange; das Überschreiten des Limits färbt sie rot und zeigt die Budget-überschritten-Ereignisse als Marker auf der Zeitachse. ## Aufbewahrung von Nutzungs-Zeilen Das Nutzungsbuch hat sein eigenes Aufbewahrungsfenster in [Richtlinien und Limits](/de/platform/admin/governance/policies-and-limits). Default sind 365 Tage; kürze es und der historische Chart wird entsprechend gekürzt. Das Dashboard spiegelt, was das Nutzungsbuch hält — es gibt keine Archiv-Ebene darunter. ## Wo das hingehört Nutzungs-Analyse ist die Ausgaben- und Volumen-Seite derselben Last, die [Feedback-Analyse](/de/platform/admin/governance/feedback-analytics) für Qualität liest. Zusammen beantworten sie _ist dieser Agent seine Kosten wert_. Die Begleitseite ist [Richtlinien und Limits](/de/platform/admin/governance/policies-and-limits) — die Seite, auf der die Budgets, die dieses Dashboard überlagert, konfiguriert werden. # Legal Hold Source: https://tale.dev/docs/de/platform/admin/governance/legal-hold Legal Hold ist der Mechanismus, den Tale für die Beweissicherung unter Rechtshalt ausliefert. Ein Hold heftet ein Ziel — einen Benutzer, ein Dokument, einen Thread, eine Workflow-Ausführung oder die gesamte Organisation — außer Reichweite des Aufbewahrungs-Sweeps und der Löschungs-Kaskade für betroffene Personen. Admins und Inhaber lesen diese Seite, wenn der Rechtsbeistand bittet, die Daten einer Custodian-Person zu sichern, wenn ein Freigabeantrag die Vier-Augen-Freigabe braucht, oder wenn ein Audit abgleicht, welche Holds zu einem gegebenen Datum in Kraft waren. <Frame caption="Governance > Legal Hold — die Tabelle der aktiven Holds mit der Aktion Legal Hold setzen über der vier-Augen-kontrollierten Warteschlange der Freigabeanträge."> ![Die Governance-Seite Legal Hold zeigt einen aktiven Hold — Typ Benutzer auf marta.vogel, gesetzt von Alex Rivera zum Sachverhalt Northstar contract — neben der Schaltfläche Legal Hold setzen, darunter die Warteschlangen Ausstehende Genehmigung und Genehmigt, die beide Keine Freigabeanträge melden.](/images/platform/governance-legal-hold.webp) </Frame> ## Eine durchgespielte Platzierung Um einen Hold auf einen Benutzer zu setzen, öffne **Einstellungen > Richtlinien > Legal Hold** und klick auf **Legal Hold setzen**. Wähle den Zieltyp — Benutzer, Thread, Dokument, Ausführung oder Organisation — wähle das konkrete Ziel, füge einen Grund hinzu und verknüpfe den Hold mit einem Fall, falls einer offen ist. Der Hold wirkt sofort; Aufbewahrungs-Sweeps überspringen die Zeilen des Ziels, die Löschungs-Kaskade meldet sie als **Durch Legal Hold übersprungen**, und die Zielzeile trägt das Badge **Unter Legal Hold** in jeder Liste, in der sie erscheint. ## Die vier Bereiche **Aktive Holds** ist die Arbeitsliste jedes Holds, der gerade in Kraft ist. Jede Zeile trägt den Typ, das Ziel, den Grund, den Fall, wer ihn gesetzt hat und wann. Filtere nach Typ oder nach Fall, um die Ansicht einzugrenzen. **Freigabeanträge** ist die Vier-Augen-Warteschlange. Einen Hold freigeben verlangt, dass ein anderer Admin die Anfrage genehmigt; genehmigte Anfragen warten zusätzlich eine Abkühlphase ab, bevor sie wirken. Der Bereich teilt sich in _wartet auf Freigabe_ und _genehmigt, wartet auf Abkühlphase_, sodass die Warteschlange und der Timer beide sichtbar sind. **Fälle** gruppiert Holds nach Fall. Jeder Fall trägt einen Namen, eine Fallnummer und die Liste der verknüpften Holds. Einen Fall zu schließen reicht Freigabeanträge für jeden verknüpften Hold ein — weiterhin unter Vier-Augen-Genehmigung pro Antrag. **Freigabeverlauf** ist das nur-lesbare Audit der effektiven und abgelehnten Freigaben. Nutz es, um gegen ein Beweissicherungsschreiben der Gegenseite abzugleichen oder einen Audit-Bericht zu speisen. ## Hold-und-Kaskade-Interaktion Ein Hold blockiert jeden Aufbewahrungs-Lauf und jeden Löschungs-Schritt für das Ziel. Die Papierkorb-Seite zeigt den Banner **Löschen ist durch einen aktiven Legal Hold gesperrt**, wenn ein Admin versucht, eine Zeile unter Hold zu entfernen. Eine Anfrage einer betroffenen Person, deren Subjekt von einem Hold abgedeckt ist, landet im Status **Blockiert**, bis der Hold freigegeben ist; teilweise Abdeckung (manche Threads unter Hold, manche nicht) landet in **Teilweise** mit Per-Kategorie-Zählern im Beleg. ## Vier-Augen-Kontrolle Platzieren und Freigeben sind nicht symmetrisch. Platzieren ist eine Aktion durch einen Admin allein — die Geschwindigkeit zählt, wenn Rechtsstreit kommt. Freigeben ist vier-Augen-kontrolliert: der anfordernde Admin reicht ein, ein anderer Admin gibt frei, und zwischen Genehmigung und Wirkung gilt eine Abkühlphase, sodass eine voreilige Freigabe noch abgebrochen werden kann. Beide Hälften des Workflows werden Ende zu Ende auditiert. ## Wo das hingehört Legal Hold ist der Einfrier-Knopf auf der Aufbewahrung. Er ist der einzige Mechanismus, der den zeitgesteuerten Aufbewahrungs-Sweep und die Löschungs-Kaskade für betroffene Personen schlägt — beide respektieren Holds per Konstruktion. Die Begleitseiten sind [Anfragen betroffener Personen](/de/platform/admin/governance/data-subject-requests) für die Kaskaden-Seite und [Richtlinien und Limits](/de/platform/admin/governance/policies-and-limits) für die Aufbewahrungsfenster, die der Hold übersteuert. # Guardrails Source: https://tale.dev/docs/de/platform/admin/governance/guardrails Guardrails ist die Oberfläche, auf der du die drei Filterebenen konfigurierst, die Tale auf jede Chat-Nachricht in deiner Organisation anwendet. Jede Nachricht durchläuft Inhaltssicherheit (Wortlisten und Admin-Regex), dann PII-Erkennung (eingebaute Muster plus eigene), dann einen optionalen externen Moderationsanbieter — in dieser festen Reihenfolge, auf dem Weg hinein und auf dem Weg hinaus. Admins und Inhaber lesen diese Seite, wenn ein Regulierer eine Inhaltsregel benennt, wenn ein Leck eine strengere Richtlinie rechtfertigt, oder wenn die Antworten eines Agents bereinigt werden müssen, bevor sie das Modell verlassen. <Frame caption="Governance > Guardrails — die drei Status-Karten der Filterebenen (Inhaltssicherheit, PII-Erkennung, Moderationsanbieter) über dem Log der letzten Ereignisse."> ![Die Governance-Seite Guardrails zeigt drei Status-Karten — Inhaltssicherheit greift auf Ein- und Ausgabe über zwei Kategorien, die PII-Erkennung läuft im Modus mask über vier eingebaute Muster, und der Moderationsanbieter steht auf Deaktiviert, ohne konfigurierte externe API — über dem Feed der letzten Ereignisse, der noch keine Ereignisse meldet.](/images/platform/governance-guardrails.webp) </Frame> ## Eine durchgespielte Schichtung Um die Ebenen zu konfigurieren, öffne **Einstellungen > Richtlinien > Guardrails**. Die Übersicht zeigt drei Status-Karten, eine pro Ebene — Inhaltssicherheit, PII-Erkennung, Moderation. Jede Karte verlinkt auf ihre eigene Konfigurationsseite, auf der du wählst, ob die Ebene auf Eingaben, Ausgaben oder beidem läuft und was sie bei einem Treffer tut (Nachricht blockieren, Treffer maskieren oder markieren und durchlassen). Die Tabelle der letzten Ereignisse unten in der Übersicht zeigt die letzten 50 Erkennungen, Blockaden und Anbieter-Fehler mit ihrer Ebene, ihrer Richtung und ihrer Treffer-Kategorie. ## Inhaltssicherheit Inhaltssicherheit ist die Ebene, die du selbst besitzt. Definiere eine oder mehrere Kategorien — Hassrede, Profanität, eine eigene Regex für einen internen Codenamen — und wähle einen Modus pro Kategorie: **Blockieren** lehnt die Nachricht ab, **Maskieren** ersetzt Treffer durch einen Platzhalter, **Markieren** vermerkt die Erkennung, ohne die Nachricht zu ändern. Blockieren schlägt Maskieren schlägt Markieren, wenn mehr als eine Kategorie greift. Die Wortlisten und Muster dieser Ebene verlassen das Deployment nie. Getroffener Text wird nicht gespeichert — nur die Kategorie, die Richtung (Eingabe oder Ausgabe) und die Trefferanzahl landen im Audit-Ereignis. ## PII-Erkennung PII-Erkennung bringt Muster für E-Mails, Telefonnummern, Behörden-IDs, Zahlungsnummern und eine lange Liste regionaler Formate mit. Füge eigene Muster hinzu, wenn dein Regulierer ein Format benennt, das die eingebauten verfehlen. Wähle einen Modus — Blockieren, Maskieren mit einem Platzhalter, oder Markieren — und eine Anwendungsrichtung. Maskieren ist die typische Wahl für die Ausgabefilterung, wenn das Modell Zugriff auf Datensätze mit PII bekommen hat, die es nicht zurückspielen soll. ## Moderationsanbieter Die Moderationsebene ist ein externer Klassifikator — OpenAI Moderation, Azure Content Safety, Perspective API oder ein eigener HTTP-Endpunkt. Konfiguriere den Endpunkt des Anbieters, einen API-Key und das Kategorie-zu-Aktion-Mapping (jeder Anbieter liefert seine eigene Taxonomie zurück; das Mapping entscheidet, welche Kategorien blockieren, maskieren oder markieren). Die Ebene ist optional — lass sie deaktiviert und nur die ersten zwei Ebenen laufen. Der Anbieter sitzt auf dem Egress-Netzwerkpfad. Ausfälle sind pro Richtung konfigurierbar: Fail-open lässt die Nachricht durch, Fail-closed lehnt sie ab. Die Ansicht der letzten Ereignisse zeigt Anbieter-Fehler, HTTP-Statuscodes und Circuit-Open-Ereignisse, wenn die Ebene gerate-limited ist. ## Letzte Ereignisse Jede Erkennung, Blockade und jeder Anbieter-Fehler landet 30 Tage lang in der Tabelle der letzten Ereignisse. Filtere nach Ebene oder nach Art; klick auf eine Zeile, um die getroffenen Kategorien, den Akteur, die Nachrichten-ID und den Zeitstempel zu sehen. Getroffener Roh-Text wird nie gespeichert — die Ereignisse sind eine Tuning-Oberfläche, kein Inhalts-Archiv. ## Wo das hingehört Guardrails ist der Laufzeit-Filter zwischen Benutzer und Modell in beide Richtungen. Paare das mit [Inhalte und Modelle](/de/platform/admin/governance/content-models), sodass ein freigegebenes Modell auch den freigegebenen Inhaltsregeln unterliegt. Die Begleitseite ist das [Audit-Log](/de/platform/admin/governance/audit-logs) — jede Blockade und jede Maskierung der Guardrail-Ebenen landet dort als dauerhafte Aufzeichnung. # Run-code-Richtlinie Source: https://tale.dev/docs/de/platform/admin/governance/run-code-policy Run-code-Richtlinie ist die Oberfläche, auf der du entscheidest, welche Python- und Node-Pakete die Sandbox zur Laufzeit installieren kann. Skills mit Skripten und das Run-code-Tool laufen beide in derselben Sandbox; diese Richtlinie ist die einzige Naht, an der du anziehst oder lockerst, was sie installieren dürfen. Admins und Inhaber lesen diese Seite, wenn ein Agent eine neue Bibliothek braucht oder wenn ein Audit fragt, warum ein Paket zu einem bestimmten Zeitpunkt blockiert war. <Frame caption="Governance > Run-code-Pakete — die Radiogruppe für den Standardmodus über den Zulassungs- und Sperrlisten für Python und Node."> ![Die Governance-Seite Run-code-Richtlinie mit Zulassungsliste als gewähltem Standardmodus, darunter eine Python-Zulassungsliste mit pandas, numpy, scipy und scikit-learn, eine Python-Sperrliste mit paramiko, fabric, pexpect und scapy sowie eine Node-Zulassungsliste mit axios, date-fns, dayjs und lodash.](/images/platform/governance-run-code-policy.webp) </Frame> ## Ein durchgespielter Wechsel Der Standardmodus ist **Sperrliste** mit leerer Liste, was bedeutet, dass jedes Paket installierbar ist. Um auf eine kuratierte Menge zu wechseln, öffne **Einstellungen > Richtlinien > Run-code-Pakete**, ändere den Modus auf **Zulassungsliste** und liste die Pakete unter **Python-Zulassungsliste** und **Node-Zulassungsliste** auf, denen du vertraust. Speichern, und der nächste Sandbox-Lauf, der ein Paket außerhalb der Liste anfordert, scheitert mit dem Grund **nicht auf der Zulassungsliste** im Audit-Ereignis. ## Die zwei Modi | Name | Default | Beschreibung | | --------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | Zulassungsliste | aus | Nur die aufgelisteten Pakete installieren; alles andere wird abgelehnt. Nutz das, wenn ein Regulierer die freigegebenen Bibliotheken benennt. | | Sperrliste | an | Jedes Paket installiert außer den aufgelisteten. Nutz das, wenn eine kleine Menge als schlecht bekannt ist und der Rest vertraut wird. | ## Die vier Listen Jeder Modus liest aus zwei Listen — Python und Node. Ein Paket pro Zeile oder kommagetrennt. Versionsangaben werden automatisch entfernt (`pandas==2.1` entspricht `pandas`), sodass die Richtlinie namensbasiert ist und Bibliotheks-Upgrades übersteht. Scoped Node-Pakete (`@scope/pkg`) werden unterstützt. Die Listen sind pro Sprache unabhängig: eine Python-Zulassungsliste plus eine Node-Sperrliste ist eine gültige Kombination und bedeutet, dass Python streng ist und Node permissiv auf derselben Sandbox. ## Der Tester Das Test-Panel auf derselben Seite erlaubt dir, pip- oder npm-Spezifikationen einzufügen und zu sehen, ob jede unter dem aktuellen Entwurf durchgehen würde. Es verwendet deine ungespeicherten Änderungen, sodass du vor dem Speichern iterieren kannst. Jede Spezifikation wird geparst, von ihrer Versionsangabe befreit und gegen die Listen abgeglichen; das Panel meldet **Erlaubt** oder **Abgelehnt** mit der Begründung — passt-zur-Zulassungsliste, nicht-auf-der-Zulassungsliste, passt-zur-Sperrliste, nicht-auf-der-Sperrliste. ## Netzwerk-Egress und Skills Die Paket-Richtlinie regelt, _was_ in der Sandbox läuft. Dieselbe Sandbox läuft Skill-Skripte — siehe die [Skills-Konzeptseite](/de/platform/agents/skills). Ausgehendes Netzwerk aus Sandbox-Code ist standardmäßig offen, Cloud-Metadaten und private Adressbereiche sind immer blockiert; bei selbst gehosteten Deployments kann der Operator es auf Deployment-Ebene auf eine Hostname-Zulassungsliste einschränken — die Anleitung steht in [Hardening](/de/self-hosted/operate/security/hardening). Behandle das Veröffentlichen eines Skills mit Skript als Erweiterung der Vertrauensfläche für jeden Agent, der es aufnimmt; die Paket-Richtlinie und die Egress-Richtlinie des Deployments entscheiden zusammen, was das Skript tun darf. ## Wo das hingehört Run-code-Richtlinie ist die Schleuse auf der Sandbox, die sowohl das Run-code-Tool als auch Skill-Skripte trägt. Das begleitende Konzept ist [Agent-Skills](/de/platform/agents/skills) — es deckt ab, wann ein Skript als Skill veröffentlicht wird und warum die Paket-Richtlinie die tragende Schleuse ist. Die begleitende Governance-Seite ist [Audit-Logs](/de/platform/admin/governance/audit-logs) — jede abgelehnte Paket-Installation landet dort mit der Spezifikation und der Begründung. # Feedback-Analyse Source: https://tale.dev/docs/de/platform/admin/governance/feedback-analytics Feedback-Analyse ist das Dashboard, das die Per-Nachricht-Daumen und die Per-Chat-Bewertungen in Trendlinien verwandelt. Mitglieder hinterlassen das Feedback inline im Chat; diese Seite aggregiert es pro Agent, pro Modell und über die Zeit, sodass die Regression aus der Stimmänderung letzter Woche als Zahl sichtbar ist und nicht als Bauchgefühl. Admins und Inhaber lesen diese Seite, wenn ein Modellwechsel wie eine Verschlechterung aussieht, wenn ein Agent schlechter abschneidet als die anderen, oder wenn die Führung die grobe Qualitätshaltung jedes Agents in der Organisation will. ## Eine durchgespielte Detailansicht Öffne **Einstellungen > Richtlinien > Feedback** und die Default-Ansicht ist das organisationsweite Verhältnis über die letzten 30 Tage. Wechsle die Aufschlüsselung auf **Nach Agent**, um das Verhältnis pro Agent zu sehen — sortiere nach Feedback-Volumen, um die Agents zu finden, die Mitglieder tatsächlich nutzen, klick dann in einen hinein, um seine Modellhistorie neben demselben Verhältnis über die Zeit zu sehen. Die Ansicht Aufteilung nach Modell sind dieselben Daten, geschnitten auf das Modell, das jede bewertete Antwort erzeugt hat. ## Die zwei Signale **Daumen-Feedback** ist das Per-Nachricht-Signal — ein Daumen hoch oder ein Daumen runter auf eine Agent-Antwort. Der Daumen trägt einen optionalen Freitext-Kommentar; der Kommentar ist pro Zeile und fließt nie ins Verhältnis. Mitglieder können beides hinterlassen, eines bearbeiten oder ganz zurückziehen; die Zeitleiste zeigt den jeweils letzten Stand. **Chat-Bewertungen** ist das Per-Konversations-Signal — die Bewertung von eins bis fünf Sternen, die am Ende einer Konversation auftaucht. Bewertungen tragen auch einen optionalen Kommentar. Chat-Bewertungen sind gröber als Daumen und nützlich, um die Agent-Stimmung über viele Runden zu verfolgen, wo einzelne Daumen Rauschen wären. ## Aufschlüsselungen Das Dashboard schneidet nach drei Dimensionen: - **Agent** — jeder Agent in der Organisation bekommt seine eigene Zeile mit Verhältnis, Volumen und Trend. - **Modell** — jedes Modell, das eine bewertete Antwort erzeugt hat, trägt bei; nützlich beim Vergleich eines Primärmodells mit seinem Fallback. - **Zeit** — der Trend ist täglich für die letzten 30 Tage und wöchentlich für längere Fenster. ## Freitext-Kommentare Kommentare erscheinen unter den aggregierten Zahlen als Liste. Sortiere nach Aktualität oder nach Sentiment; klick durch zur Konversation im Kontext, um zu sehen, worauf die bewertete Antwort reagiert hat. Kommentare unterliegen derselben Aufbewahrungsrichtlinie wie die Konversationen, zu denen sie gehören; wird ein Thread gelöscht oder verworfen, gehen die Kommentare mit. ## Wo das hingehört Feedback-Analyse ist der Puls jedes Agents in der Organisation — der Ort, an dem eine Regression in Stimme oder Modellverhalten auftaucht, bevor jemand sie meldet. Die Begleitseite ist [Nutzungs-Analyse](/de/platform/admin/governance/usage-analytics) — dieselben Agents und Modelle, geschnitten nach Kosten und Token-Volumen statt nach Qualität. # Branding Source: https://tale.dev/docs/de/platform/admin/branding Branding ist die Oberfläche, die Tales Standard-Chrome gegen die deiner Organisation tauscht. Die Seite deckt die Assets ab, die die Plattform überzieht — Logo, Favicon und die Akzentfarbe, aus der sich die Palette ableitet — und erklärt, wo jedes davon erscheint, damit du vor dem Speichern eine Vorschau hast. Der Produktname selbst folgt automatisch dem Namen deiner Organisation, es gibt also kein separates Feld dafür. Admins greifen zu Branding, wenn eine selbst gehostete Instanz an ein externes Publikum geht oder wenn ein internes Rollout sich nativ für die Firma anfühlen soll. Nur Admins und Inhaber können Branding bearbeiten. Alle anderen sehen das Ergebnis; das Formular selbst ist für Redakteure, Entwickler und Mitglieder ausgeblendet. <Frame caption="Einstellungen > Branding — die Logo-, Favicon- und Farb-Steuerungen neben einer Live-Vorschau der Sidebar."> ![Die Branding-Einstellungsseite mit Logo- und Favicon-Uploads, einem Feld für die Akzentfarbe und einem Live-Vorschaubereich rechts.](/images/platform/settings-branding.webp) </Frame> ## Wo Branding lebt Öffne **Einstellungen > Branding**. Das Formular hat drei Abschnitte (Logo-Upload, Favicon-Upload, Akzentfarbe) und eine Live-Vorschau, die die Sidebar mit den Werten spiegelt, die du gerade bearbeitest. Speichern setzt die Änderung beim nächsten Seitenaufruf für jedes Mitglied _dieser_ Organisation um — eine Pro-Benutzer-Überschreibung gibt es nicht. Branding ist auf eine Organisation beschränkt. Jede Organisation behält ihr eigenes Logo, Favicon und ihre Akzentfarbe, sodass ein Wechsel der Organisation die Chrome auf das Branding dieser Organisation umstellt, statt das der vorherigen mitzunehmen. Bearbeitungen hier ändern nur die Organisation, in der du dich gerade befindest. ## Der Produktname Es gibt kein Feld für „App-Name" oder „Text-Logo". Die Wortmarke im Sidebar-Kopf und der Name im Browser-Tab-Titel sind der eigene Name deiner Organisation, den du auf der Seite **Einstellungen > Organisation** setzt. Benenn die Organisation um, und die Chrome folgt beim nächsten Seitenaufruf. Lade ein Logo-Bild hoch (siehe unten), und es nimmt den Platz der Wortmarke ein; ohne Logo wird der Organisationsname als Text-Wortmarke gerendert. ## Die Assets **Logo** ist ein Bild — PNG, SVG oder JPG. Die Plattform rendert es in Sidebar-Höhe; ziel auf transparenten Hintergrund und eine Wortmarke, die bei etwa 32 Pixel Höhe lesbar ist. Das Logo ist ein einzelner Upload für beide Themes — wähl eine Marke, die auf hellem wie dunklem Hintergrund lesbar ist. Ohne Logo fällt die Chrome auf den Namen deiner Organisation als Text-Wortmarke zurück. **Favicon** ist das Tab-Icon. Lade eine helle und eine dunkle Variante hoch, damit das Icon lesbar bleibt, egal welches Theme das Betriebssystem gewählt hat — oder lass es leer, und Tale leitet eines aus deinem Logo ab, sobald du es hochlädst, sodass ein einziger Upload sowohl die Sidebar als auch den Browser-Tab überzieht. Ein explizit gesetztes Favicon gewinnt immer gegen das automatisch abgeleitete. **Akzentfarbe** ist die eine Farbe, aus der sich die Marken-Palette ableitet — Buttons, Fokusringe, Auswahlzustände und die aktive Zeile in der Sidebar nehmen ihren Ton von ihr. Sie akzeptiert jeden Hex-Wert, einmal gewählt für hell wie dunkel; Tale leitet pro Theme eine lesbare Palette ab — wäre die gewählte Farbe gegen den Hintergrund eines Themes schwer lesbar, wird sie nur für dieses Theme in den Kontrast geschoben, das andere bleibt unangetastet, und dieselbe Marke liest sich auf beiden sauber. Die Vorschau zeigt die abgeleitete Palette für das Theme, das du gerade ansiehst. ## Ein durchgespieltes Rebranding Um eine Instanz für `Acme Corp` umzubranden, setz zuerst den Namen der Organisation auf `Acme Corp` auf der Seite **Einstellungen > Organisation** — dieser Name wird zur Sidebar-Wortmarke und zum Browser-Tab-Titel. Öffne dann **Einstellungen > Branding**, lade die Firmen-Wortmarke als Logo hoch und füge den Marken-Hex (`#3B82F6` im Beispiel) ins Feld für die Akzentfarbe ein. Lass das Favicon leer, und Tale erzeugt eines aus dem Logo. Das Vorschaufeld rechts aktualisiert sich, während du tippst. Speichern setzt die Änderung um; die Sidebar, der Browser-Tab und das Favicon spiegeln das neue Branding sofort. ## Der eigene Login-Screen Die Anmelde-, Registrierungs- und Passwort-Reset-Screens werden gerendert, bevor du eine Organisation gewählt hast — es gibt also keine Organisation im Kontext, mit der sie gebrandet werden könnten. Sie zeigen das Standard-Branding der Plattform statt das einer einzelnen Organisation; das Branding pro Organisation übernimmt, sobald du im Arbeitsbereich dieser Organisation landest. Melde dich ab und lade die Login-URL neu, um zu prüfen, welche Assets die Pre-Auth-Screens verwenden. ## Wo das hingehört Branding ist die visuelle Schicht über jeder anderen Admin-Oberfläche; SSO, E-Mail und Audit-Logs tragen die gebrandete Chrome zu deinen Mitgliedern. Weil der Produktname der eigene Name der Organisation ist, halt ihn bei [Mitglieder und Rollen](/de/platform/admin/members-and-roles) scharf. Paar Branding mit [Anbieter](/de/platform/admin/providers), damit die Modellnamen im Chat-Header zur Chrome drumherum passen, und mit [Mitglieder und Rollen](/de/platform/admin/members-and-roles), damit die Personen, die Branding bearbeiten dürfen, dieselben sind, denen der Rest der Org-Chrome gehört. # Zwei-Faktor-Authentifizierung Source: https://tale.dev/docs/de/platform/admin/two-factor-authentication Zwei-Faktor-Authentifizierung legt einen zweiten Identitätsbeweis über das Passwort — einen sechsstelligen Code aus einer Authenticator-App oder einen WebAuthn-Passkey. Tale bringt TOTP (zeitbasierte Einmal-Passwörter) mit, kompatibel zu Google Authenticator, 1Password, Authy und jeder anderen App, die dem Standard folgt, plus Passkeys als phishing-resistente Alternative. Die Seite deckt die Pro-Benutzer-Registrierung ab, Passkeys, die Backup-Codes, die einen Account wiederherstellen, wenn das Telefon weg ist, die organisationsweite Erzwingungsrichtlinie und das Admin-Reset für ein ausgesperrtes Mitglied. Zwei-Faktor ist standardmäßig optional. Admins können sie für die ganze Organisation verpflichtend machen, mit einem Karenzfenster, damit Mitglieder Zeit zum Einrichten haben. ## Pro-Benutzer-Registrierung Um 2FA für deinen eigenen Account einzuschalten, öffne **Konto > Sicherheit**. Klick auf **Zwei-Faktor aktivieren**, bestätige dein Passwort und scanne den QR-Code mit einer Authenticator-App. Tippe den sechsstelligen Code ein, den die App zeigt, um zu prüfen, dass das Geheimnis aufgenommen wurde, und sichere dann die Backup-Codes, die der nächste Bildschirm zeigt. Die Codes erscheinen einmal — lade oder kopiere sie, bevor du auf **Fertig** klickst. Derselbe Bildschirm trägt **Deaktivieren** und **Backup-Codes neu erzeugen**. Deaktivieren entfernt den zweiten Faktor; Neu-Erzeugen entwertet jeden vorherigen Backup-Code. Beide Aktionen verlangen das Account-Passwort zur Bestätigung. ## Backup-Codes Backup-Codes sind einmal verwendbare Strings, die die Plattform prägt, wenn 2FA aktiviert oder neu erzeugt wird. Jeder davon ersetzt den Authenticator-Code bei einem einzelnen Sign-in — nützlich, wenn das Telefon verloren ist, der Authenticator deinstalliert wurde oder du irgendwo ohne das Gerät feststeckst. Die Plattform beobachtet die verbleibende Anzahl und zeigt ein Niedrig-Banner, wenn nur noch wenige Codes übrig sind; das Banner verlinkt direkt auf den Neu-Erzeugen-Flow. Behandle Backup-Codes wie Passwörter. Lege sie in einen Passwort-Manager oder drucke sie und schließe sie weg. Wer dein Passwort und einen Backup-Code hat, kann sich als du anmelden. ## Passkeys Ein Passkey ist ein WebAuthn-Credential — Face ID, Touch ID, Windows Hello oder ein Hardware-Security-Key —, das bei jeder Anmeldung eine Challenge signiert, statt einen getippten Code zu liefern. Das Credential ist an die Origin der Site gebunden; eine täuschend ähnliche Phishing-Domain bekommt nichts, was sie wiederverwenden könnte. Ein Passkey ist dadurch phishing-resistent auf eine Art, die TOTP nicht erreicht, und er erfüllt eine erzwungene Zwei-Faktor-Richtlinie genau wie TOTP. Zum Registrieren öffne **Konto > Sicherheit** und klick auf **Passkey hinzufügen**. Gib dem Credential einen Namen, den du später wiedererkennst, und wähle den **Authenticator-Typ**: **Beliebig (empfohlen)** lässt den Browser alles anbieten, was verfügbar ist, **Dieses Gerät (Face ID, Touch ID, Windows Hello)** beschränkt die Zeremonie auf den eingebauten Authenticator, und **Security-Key oder Smartphone** auf einen externen. Den Rest erledigt der Browser mit der Registrierungszeremonie. Jeder Eintrag in derselben Liste trägt eine **Entfernen**-Schaltfläche (Symbol) zum Widerrufen deiner eigenen Credentials; sie fragt vor dem Entfernen des Passkeys nach einer Bestätigung. Ein registrierter Passkey funktioniert an drei Türen. Auf dem Login-Bildschirm meldet dich **Mit einem Passkey anmelden** ohne Passwort an — das Credential ist selbst ein starker Nachweis. Auf dem Bestätigungs-Bildschirm nach einem Passwort-Login ersetzt **Stattdessen einen Passkey verwenden** den sechsstelligen Code. Und auf dem Registrierungs-Bildschirm, zu dem eine erzwungene Richtlinie nicht registrierte Mitglieder leitet, sitzt **Stattdessen einen Passkey registrieren** neben der TOTP-Einrichtung — ein Mitglied, das nur einen Passkey registriert und nie TOTP, besteht die Richtlinie. Verliert ein Mitglied ein Gerät mit einem Passkey darauf, widerruft ein Admin das Credential: Öffne **Einstellungen > Organisation**, klick beim Mitglied auf **Mitglied bearbeiten** und entferne das Credential im Abschnitt **Passkeys** des Dialogs. Tale löscht das Credential und beendet jede aktive Sitzung des Mitglieds, sodass ein verlorener oder gestohlener Authenticator keine Sitzung am Leben hält. Registrierung, Selbst-Entfernen, Admin-Widerruf und jede Passkey-Anmeldung landen im Audit-Log (`passkey_added`, `passkey_removed`, `passkey_revoked_by_admin`, `passkey_sign_in`). ## Die Erzwingen-für-Org-Richtlinie Admins können Zwei-Faktor für jedes passwortauthentifizierte Mitglied der Organisation verpflichtend machen. Öffne **Einstellungen > Richtlinien > Sicherheit & Überwachung** und schalte unter **Zwei-Faktor-Authentifizierung** die Option **Zwei-Faktor-Authentifizierung verlangen** ein. Die Richtlinie trägt eine Karenzzeit (in Tagen), die jedem Mitglied vom ersten Sign-in unter der Richtlinie an Zeit zur Registrierung gibt; setz sie auf null für sofortige Erzwingung. <Frame caption="Governance > Sicherheit & Überwachung — Limits für Anmeldeversuche und Passwort-Richtlinie; die Richtlinie für die Zwei-Faktor-Authentifizierung sitzt weiter unten auf derselben Seite."> ![Die Governance-Seite Sicherheit & Überwachung zeigt die Felder für die Limits der Anmeldeversuche und die Zeichenklassen-Anforderungen der Passwort-Richtlinie; die Zwei-Faktor-Richtlinie steht weiter unten auf derselben Seite.](/images/platform/governance-security-monitoring.webp) </Frame> | Feld | Typ | Pflicht | Beschreibung | | --------------------------------------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------- | | Zwei-Faktor-Authentifizierung verlangen | Schalter | ja | Aus hält 2FA für jedes Mitglied optional; ein schaltet die Richtlinie an. | | Karenzzeit (Tage) | Ganzzahl | ja | Tage ab dem ersten angemeldeten Moment eines Mitglieds unter der Richtlinie, bevor die Registrierung verlangt wird. Null heißt sofort. | | Nur-SSO-Benutzer ausnehmen | Schalter | nein | Wenn an, vertrauen Mitglieder, deren einziger Account eine föderierte Identität ist, dem vorgelagerten IdP für MFA. | Ein Mitglied innerhalb des Karenzfensters sieht ein Countdown-Banner in der App, das auf den Registrierungs-Flow zeigt. Sobald die Karenz abläuft, leitet der nächste Sign-in durch den Registrierungs-Bildschirm, und das Mitglied kann erst weiter, nachdem es registriert ist. ## Admin-Reset für ein ausgesperrtes Mitglied Wenn ein Mitglied sein Telefon und seine Backup-Codes verliert, entfernt ein Admin den zweiten Faktor auf seinem Account. Öffne **Einstellungen > Organisation**, klick beim Mitglied auf **Mitglied bearbeiten** und dann auf **Zwei-Faktor zurücksetzen** im Dialog. Tale deaktiviert 2FA für den Account und beendet jede aktive Sitzung, sodass sich das Mitglied beim nächsten Sign-in neu registriert. Das Zurücksetzen wird im Audit-Log unter `2fa_reset_by_admin` festgehalten. Greif dazu als Wiederherstellungs-Aktion — das Mitglied sollte sich sofort neu registrieren, wenn es wieder drin ist. ## Wo das hingehört Zwei-Faktor sitzt eine Schicht über dem Passwort — gleicher Login-Bildschirm, zweiter Schritt. Paar es mit [Mitglieder und Rollen](/de/platform/admin/members-and-roles) (der Admin, der den zweiten Faktor zurücksetzt, ist derselbe Admin, der den Account verwaltet), mit [Richtlinien und Limits](/de/platform/admin/governance/policies-and-limits) (die Erzwingungsrichtlinie lebt in der Governance-Oberfläche) und mit [Audit-Logs](/de/platform/admin/governance/audit-logs) (jede Registrierung, Deaktivierung und jedes Admin-Reset landet dort). # Admin Source: https://tale.dev/docs/de/platform/admin/overview Admin ist die Konfigurationsebene von Tale. Sie umfasst die Personen, die sich anmelden dürfen, die Teams, die sie gruppieren, die KI-Anbieter hinter jeder Antwort, die API-Schlüssel, mit denen externer Code mit der Organisation spricht, die Drittanbieter-Connectors, durch die Agents nach außen greifen, und das Branding, das der Rest der Organisation sieht. Nur Admins und Inhaber sehen das volle Admin-Menü; Entwickler sehen eine Teilmenge, andere Rollen sehen es gar nicht. Diese Seiten beschreiben, was jede Einstellung tut und was sie am laufenden Produkt ändert. Die meisten liest du einmal beim Aufsetzen und besuchst sie wieder, wenn sich etwas ändert — eine neue Person, ein rotierter Schlüssel, ein neuer Anbieter. Die Rollen- und Berechtigungsgeschichte hinter dem ganzen Menü liegt in [Mitglieder und Rollen](/de/platform/admin/members-and-roles); fang dort an, denn jede andere Admin-Seite verweist auf die Rollennamen, die sie definiert. Lieber erst zusehen? Episode 9 durchquert den ganzen Kontrollraum — Anbieter, Leitplanken, Audit, Kosten — in gut drei Minuten, mit Untertiteln. <Video src="/videos/de/tutorials/ep9-governance/ep9-governance.de.mp4" poster="/videos/de/tutorials/ep9-governance/ep9-governance.de.webp" captions="/videos/de/tutorials/ep9-governance/ep9-governance.de.vtt" lang="de" title="Episode 9 — Richtlinien, Kosten & Vertrauen" caption="Episode 9 — Richtlinien, Kosten & Vertrauen (3:31)"> </Video> ## Konfigurationsbereiche <CardGroup cols="2"> <Card title="Mitglieder und Rollen" icon="users" href="/de/platform/admin/members-and-roles"> Die sechs Rollen und die ressourcengenaue Matrix, die sagt, wer lesen, schreiben, konfigurieren und regeln darf. </Card> <Card title="Teams" icon="users-round" href="/de/platform/admin/teams"> Gruppiere Mitglieder in Teams, die Agents, Skills und Connectors teilen. </Card> <Card title="Agents" icon="bot" href="/de/platform/admin/agents"> Jeder Agent, den die Organisation hat, und wo ein Admin eingreift, wenn einer Governance braucht. </Card> <Card title="KI-Anbieter" icon="cpu" href="/de/platform/admin/providers"> Hinterleg die Zugangsdaten hinter jeder Antwort und wähl, welche Modelle die Organisation aufrufen darf. </Card> <Card title="Connectors" icon="plug" href="/de/platform/admin/connectors"> Hinterleg und ersetz die Zugangsdaten hinter Slack, Gmail, Outlook, Google Drive, GitHub, Shopify und mehr. </Card> <Card title="Enterprise SSO" icon="shield-check" href="/de/platform/admin/enterprise-sso"> Verdrahte die Anmeldung mit deinem Identity-Provider über SAML oder OIDC. </Card> <Card title="API-Schlüssel" icon="key" href="/de/platform/admin/api-keys"> Erzeuge und begrenze die Schlüssel, mit denen externer Code Tales REST-API erreicht. </Card> <Card title="Branding" icon="palette" href="/de/platform/admin/branding"> Der Name, das Logo und die Farben, die der Rest der Organisation sieht. </Card> <Card title="Zwei-Faktor-Authentifizierung" icon="smartphone" href="/de/platform/admin/two-factor-authentication"> Verlange einen zweiten Faktor für die Anmeldung und verwalte die Einrichtung organisationsweit. </Card> <Card title="Changelog" icon="history" href="/de/platform/admin/changelog"> Der produktinterne Eintrag darüber, was wann ausgeliefert wurde. </Card> <Card title="Governance" icon="scale" href="/de/platform/admin/governance/audit-logs"> Audit-Logs, Richtlinien und Limits, Guardrails, Analysen, Aufbewahrung und Legal Hold. </Card> </CardGroup> ## Wo das hingehört Admin ist die Oberfläche, die jeder andere Tab voraussetzt. Chat löst ein Modell über die hier konfigurierten Anbieter auf; Agents rufen Tools über die hier konfigurierten Connectors auf; die Skill-Bibliothek und die Inbox respektieren die hier konfigurierten Team-Grenzen. Die natürliche erste Lektüre ist [Mitglieder und Rollen](/de/platform/admin/members-and-roles) — jede andere Admin-Seite verweist auf die Rollennamen, die sie definiert. # Mitgelieferte Automatisierungen Source: https://tale.dev/docs/de/platform/automations/builtin Tale liefert Automatisierungen von Haus aus mit: drei, die ein Postfach in einen geteilten Posteingang verwandeln, ein Bundle, das GitHub-Issues von Anfang bis Ende löst, eine Reihe von Sync- und Pflege-Vorlagen zum Installieren bei Bedarf, und die vorinstallierten Pakete, die Aufgaben-Boards und Erwähnungen für jede Organisation am Laufen halten. Redakteure und Mitglieder nutzen, was eine installierte Automatisierung mitbringt — einen Posteingang-Tab, einen Backlog-Eintrag —, ohne selbst etwas zu installieren; das Installieren ist eine Aktion für Inhaber, Admin oder Entwickler, die [Automatisierungen durchsuchen und installieren](/de/platform/automations/catalog) behandelt. Diese Seite benennt, was jede einzelne tut, und welche Connector zuerst verbunden sein muss. <Frame caption="Der Automatisierungs-Katalog — jede Karte ist eine Installation entfernt; versteckte Paket-Mitglieder und Bundle-Interna bleiben aus der Liste heraus."> ![Der Automatisierungs-Katalog auf dem Tab Alle Automatisierungen, mit Karten für die E-Mail-Automatisierungen und das Bundle GitHub-Issues lösen, jede mit Icon und Beschreibung.](/images/platform/automations-catalog.webp) </Frame> ## Gmail, Outlook und E-Mail über IMAP synchronisieren **Gmail-E-Mails synchronisieren**, **Outlook-E-Mails synchronisieren** und **E-Mails über SMTP/IMAP synchronisieren** sind dieselbe Automatisierung dreimal, je einmal pro Postfach-Art: Jede braucht genau die Connector, die ihr Name sagt, jede installiert dieselbe kanalunabhängige mitgelieferte Ansicht **Posteingang**, und jede bringt den Mail-Sync-Workflow mit, der das Postfach nach Zeitplan in Konversationen holt, ab Werk alle fünf Minuten — ändere den [Zeitplan-Trigger](/de/platform/automations/triggers), wenn du seltener abholen willst. Eine Organisation, die Mail auf mehr als einer Postfach-Art empfängt, installiert mehr als eine davon; jeder Posteingang zeigt nur den Verkehr seines eigenen Postfachs. Hat ein Connector mehrere Einträge — zwei IMAP-Postfächer, zwei Gmail-Konten — deckt ein Sync-Lauf jeden aktiven Eintrag ab, und jedes Postfach merkt sich seine eigene Position in seinem eigenen Verkehr: Ein später ergänztes Postfach überspringt also nicht alles, was älter ist als der Stand des ersten. Ein Postfach, das gerade nicht erreichbar ist, lässt der Lauf aus und nimmt es beim nächsten Mal wieder mit, ohne die anderen aufzuhalten. Die passenden **…-Posteingang sichten**-Automatisierungen verteilen sich genauso und schreiben danach eine Zusammenfassung über jedes verbundene Postfach. | Automatisierung | Braucht | Postfach | | -------------------------------------- | --------- | ----------------------------------------- | | Gmail-E-Mails synchronisieren | Gmail | Ein Gmail-Postfach | | Outlook-E-Mails synchronisieren | Outlook | Ein Microsoft-Outlook-Postfach | | E-Mails über SMTP/IMAP synchronisieren | IMAP/SMTP | Jedes private Postfach über IMAP und SMTP | ## Der Posteingang-Tab Jede der drei öffnet auf ihrem Tab **Posteingang**: vier Unter-Tabs — **Offen**, **Geschlossen**, **Spam**, **Archiviert** — jeder eine geteilte Ansicht mit der Konversationsliste links und dem ausgewählten Thread rechts. Eine Konversation zu öffnen füllt die rechte Seite mit ihrem vollständigen Nachrichtenverlauf; solange du keine auswählst, steht dort **Wähle eine Konversation, um Details anzuzeigen**. Das Nachrichtenfeld sitzt unter dem Thread im Tab **Offen** — Antworten gehören zu aktiven Konversationen, deshalb sind die anderen drei Tabs reine Leseansichten. Schreib in **Nachricht eingeben** und klick auf **Senden**; die Antwort geht über das Postfach hinaus, über das die Konversation ankam, mit Empfänger und Betreffzeile aus dem Thread abgeleitet — du adressierst nichts von Hand. Der Thread-Kopf zeigt den echten **Absender** dieser Konversation — die Adresse, an die der Kontakt geschrieben hat, oder den Absender, den du beim Verfassen wählst —, damit das, was du siehst, dem entspricht, was eine Antwort wirklich als Absender trägt. Bei einer Gmail- oder Outlook-Verbindung ist der **Absender** beim Verfassen die Adresse des verbundenen Kontos; bei IMAP/SMTP bearbeitest du nur den lokalen Teil von **Absender**, und die verifizierte Domain bleibt als Badge fixiert, damit du sie nicht verlässt. **Verbessern** überarbeitet deinen Entwurf mit AI, bevor du sendest. Bei der IMAP-Automatisierung landen auch Antworten, die direkt aus dem Postfach gesendet wurden — egal aus welchem Mail-Programm —, in der Konversation, eingeordnet in den übrigen Verlauf. Der Thread-Kopf trägt die Status-Verben für die ausgewählte Konversation — **Konversation schließen** und **Als Spam markieren** auf einem offenen Thread, **Konversation erneut öffnen** auf einem geschlossenen oder archivierten, **Kein Spam** und das destruktive **Löschen** auf Spam. Mehrere Zeilen in der Liste auszuwählen, bringt dieselben Verben als Massenaktionen hervor. Admins und Inhaber nutzen im Kopf außerdem die Steuerung **Zuständig**, um Arbeit zu verteilen. Öffne sie und wähl unter **Personen** und **Team** — die beiden Dimensionen sind unabhängig, eine Konversation kann also in der Warteschlange eines Teams liegen und trotzdem einer Person zugewiesen sein. Wechselt die Person, bekommt sie eine Benachrichtigung in der App und per E-Mail; weist du einem Team zu, bekommen dessen Mitglieder Bescheid (der Handelnde bleibt jeweils draußen). Selbstzuweisung, die Person freigeben (**Zuweisung aufheben**) und das Team entfernen (**Team entfernen**) benachrichtigen niemanden. Nicht-Admins sehen die aktuelle Zuweisung nur lesend. Die Sichtbarkeit folgt der Zuweisung: Mitglieder sehen nur ihre eigenen und die Warteschlangen ihrer Teams; wirklich unzugewiesene Post sichten nur Admins. Kombiniere die Zuweisung mit [Konversations-Routing](/de/platform/admin/governance/policies-and-limits#konversations-routing), wenn eingehende Adressen automatisch in eine Warteschlange sollen. ## GitHub-Issues lösen **GitHub-Issues lösen** ist ein Bundle, keine einzelne Automatisierung: Es installiert über einen gebündelten Assistenten vier versteckte Automatisierungen auf einmal, gebunden an das Projekt, das du wählst, und braucht die GitHub-Connector. Jedes Mitglied übernimmt eine Etappe der Schleife. **GitHub-Issues sichten** bewertet die offenen GitHub-Issues eines Repositorys und schlägt die umsetzbaren als Vorschlag im Projekt-Backlog vor — ein Mensch startet sie von dort. Die vorgeschlagene Aufgabe trägt den Titel `#<Nummer> <Titel>` und übernimmt die Labels des GitHub-Issues. **GitHub-Issues abgleichen** schließt eine Board-Aufgabe, wenn ihr GitHub-Issue geschlossen wurde. Prüft die offenen Aufgaben des Boards selbst und übersieht so keine. Nur Aktualisierung — legt nie neue Aufgaben an. Das gilt unabhängig davon, ob die Lösungskette den Fix gemergt hat oder jemand das Issue direkt auf GitHub geschlossen hat. **GitHub-Pull-Requests erstellen** liefert den PR-Creator-Agent: Sobald ein Mensch eine vorgeschlagene Aufgabe startet, klont er das Repository, öffnet oder übernimmt den Pull Request für das Issue, implementiert den Fix, prüft ihn gegen die eigenen Tests des Projekts und wartet, bis CI grün wird. **GitHub-Pull-Requests prüfen** liefert den PR-Reviewer-Agent: Er testet den Branch des PR-Creators erneut, bestätigt CI, und ein werkzeugloser Richter entscheidet über die Merge-Fähigkeit — genehmigt parkt die Aufgabe bei **In Prüfung** für einen Menschen, der auf GitHub merged; nicht genehmigt schickt sie mit Feedback zurück an den PR-Creator, bis zu einer kleinen Nacharbeits-Obergrenze. An zwei Stellen bleibt ein Mensch in der Schleife: beim Starten einer vorgeschlagenen Aufgabe aus dem Backlog, und beim Mergen des Pull Requests auf GitHub selbst — nichts im Bundle merged in deinem Namen. ## Sync- und Pflege-Vorlagen Acht weitere Automatisierungen liegen im Katalog für den Moment, in dem du sie brauchst. Jede ist ein einzelner Workflow: installieren, auf die eigenen Daten richten — die Sync-Vorlagen fragen ihre Quelle über den Zeitplan ab, den sie anlegen — und danach jederzeit auf der eigenen Seite der Automatisierung anpassbar, wo eine Änderung zu einer neuen Version wird, die du live schaltest, wenn du bereit bist. | Automatisierung | Braucht | Was sie tut | | ------------------------------------------------------ | ------------ | ---------------------------------------------------------------------------------------------------- | | Confluence-Seiten synchronisieren | Confluence | Importiert die Seiten eines Confluence-Bereichs nach Zeitplan in die Wissensbibliothek | | Google-Drive-Dateien synchronisieren | Google Drive | Importiert die Dokumente eines Drive-Ordners in die Wissensbibliothek | | Shopify-Kunden synchronisieren | Shopify | Importiert die Kundinnen und Kunden des Shops in die Kontaktdaten der Organisation | | Shopify-Produkte synchronisieren | Shopify | Importiert den Produktkatalog des Shops in die Produktdaten der Organisation | | Produktbeziehungen analysieren | — | Durchsucht den Produktkatalog und erfasst Zubehör, Varianten und Ergänzungen | | Dokumente für die Suche indexieren | — | Indexiert neu hochgeladene Dokumente, damit Agenten sie durchsuchen und zitieren können | | Inaktive Konversationen archivieren | — | Schließt Konversationen, die über ihr Inaktivitätsfenster hinaus still geblieben sind | | Mitglieder bei eingehenden Nachrichten benachrichtigen | — | Informiert Mitglieder, sobald eine neue eingehende Nachricht in einer offenen Konversation eintrifft | ## Die vorinstallierten Pakete Auch die Mechanik, die die Boards jeder Organisation antreibt, ist als Automatisierungen gebaut — bei der Erstellung automatisch installiert, im Katalog versteckt, auf dem Tab **Installiert** aber sichtbar wie alles andere. Das **Aufgaben-Paket** startet einen zugewiesenen Agenten, sobald eine Aufgabe bei ihm landet, sichtet unzugewiesene Arbeit, reagiert auf @-Erwähnungen, schickt erledigte Arbeit durch die Prüfung, räumt hängende Läufe auf, setzt SLAs durch und hält abhängige Aufgaben, Unteraufgaben und Archive in Bewegung; ein Schwesterpaket hält OneDrive-Dateien synchron. Jedes ist eine normale Automatisierung — öffne eine, um ihr Dokument auf dem Canvas zu lesen, in ihrer [Liste der Läufe](/de/platform/automations/execution-logs) zu verfolgen, was sie getan hat, oder einen [Trigger](/de/platform/automations/triggers) abzuschalten, damit sie nicht mehr feuert; eine Deinstallation bleibt bestehen und wird nie hinter deinem Rücken rückgängig gemacht. ## Wo das hineinpasst Die Posteingangs-Automatisierungen, das Bundle GitHub-Issues lösen und die Sync-Vorlagen sind das, was heute mitgeliefert wird; eine private Automatisierung, die deine Organisation baut oder hochlädt, taucht im selben Katalog gleich daneben auf. [Automatisierungen durchsuchen und installieren](/de/platform/automations/catalog) deckt die Katalog-Mechanik ab; [Projekt-Backlog](/de/platform/projects/backlog) ist die nächste Lektüre dafür, was mit einer Aufgabe passiert, nachdem GitHub-Issues sichten sie vorgeschlagen hat. # Automatisierungs-Trigger Source: https://tale.dev/docs/de/platform/automations/triggers Ein Trigger ist das, was eine Automatisierung startet, wenn niemand irgendwo klickt. Es gibt genau drei Arten, die Menge ist abgeschlossen, und eine Automatisierung darf mehrere davon gleichzeitig tragen. Das Nützlichste, was du über einen Trigger wissen kannst: Er hängt am **Namen** der Automatisierung und nicht an einer Version. Deshalb macht eine neu live geschaltete Version nie eine Webhook-URL ungültig, auf die ein externes System angewiesen ist, und wirft nie einen Zeitplan weg. Jeder Trigger startet die live geschaltete Version und läuft im Live-Modus — eine Automatisierung ohne Live-Version lässt sich von ihm also nicht starten. Jeder Trigger trägt einen Ein-Aus-Schalter und hält fest, wann der Scheduler zuletzt auf ihn reagiert hat. ## Die drei Arten | Art | Startet die Automatisierung, wenn … | | ---------- | -------------------------------------------------------------- | | `schedule` | ein Cron-Ausdruck in einer benannten IANA-Zeitzone fällig wird | | `webhook` | ein externes System an eine Token-geschützte URL sendet | | `event` | ein benanntes Plattform-Ereignis eintritt | Ein programmatischer Start braucht gar keinen Trigger: ein API-Client mit einem Organisationsschlüssel ruft `POST /api/v1/automations/{name}/runs` auf (oder das MCP-Tool `start_run`), und der Schlüssel selbst ist die Berechtigung — siehe die [API-Referenz](/de/develop/api-reference). ## Zeitpläne Ein Zeitplan trägt einen Cron-Ausdruck aus fünf Feldern und die IANA-Zeitzone, in der er gelesen wird. Die Felder sind Minute, Stunde, Tag des Monats, Monat und Wochentag, und jedes nimmt ein `*`, eine Zahl, einen Bereich, eine Schrittweite oder eine kommagetrennte Liste davon. ```text */15 * * * * alle fünfzehn Minuten 0 9 * * 1-5 09:00 an Werktagen 0 6 1 * * 06:00 am Ersten des Monats 30 8 1 * 1 08:30 am 1. und an jedem Montag ``` Der Wochentag läuft von 0 bis 7, wobei sowohl 0 als auch 7 Sonntag meinen. Schränkst du sowohl Tag des Monats **als auch** Wochentag ein, feuert ein Tag, der einem von beiden entspricht — dieselbe Regel wie bei crontab, und genau die lässt das letzte Beispiel so lesen, wie es sich verhält. Die Zeitzone wird als Uhrzeit vor Ort aufgelöst: Ein Zeitplan auf 09:00 in `Europe/Zurich` bleibt über eine Zeitumstellung hinweg bei 09:00, statt zweimal im Jahr um eine Stunde zu wandern. Ein Zeitplan ohne genannte Zeitzone wird in UTC gelesen. Die Auflösung beträgt eine Minute, und ein Zeitplan ist ein Herzschlag, keine Warteschlange: Nach einer Störung setzt die Automatisierung bei ihrem nächsten Termin ein, statt die verpassten nachzuholen. Ein Zeitplan, dessen Cron-Ausdruck sich nicht lesen lässt, wird übersprungen, statt die übrigen Zeitpläne der Plattform aufzuhalten — seine Zeit des letzten Feuerns rückt dann einfach nicht mehr vor, und das ist das Signal, ihn dir anzusehen. ## Webhooks Ein Webhook ist eine eingehende URL, geschützt durch ein Token. Beim Anlegen wird das Token erzeugt und einmal angezeigt; gespeichert wird nur sein Hash, sodass die Plattform einen Aufrufer prüfen kann, ohne die URL je rekonstruieren zu können. Jedes System, das dorthin sendet, startet einen Lauf, und der Body der Anfrage wird zur Payload des Laufs. ```bash curl -X POST https://<dein-tale-host>/api/automations/webhook/<token> \ -H 'Content-Type: application/json' \ -d '{"invoiceId": "inv-1"}' ``` Ein erfolgreicher Aufruf wird sofort angenommen und antwortet mit der id des gestarteten Laufs — der Aufrufer wartet also nie darauf, dass die Automatisierung fertig wird. Ein Body, der kein JSON ist, wird als Text durchgereicht statt abgewiesen, denn manche Anbieter senden Formular- oder Klartext-Payloads. Bodies sind auf 256 KB gedeckelt: Ein Webhook nimmt eine Payload entgegen, keinen Upload. Du kannst den Lauf auf ein Projekt beschränken, indem du der URL `?projectId=<id>` anhängst — das Projekt, das du in die URL einbackst, die du dem Anbieter gibst. Lässt du es weg, nutzt der Lauf die Bindung der Automatisierung selbst: eine an ein einzelnes Projekt gebundene Automatisierung läuft dort, eine an mehrere oder an keines gebundene läuft organisationsweit. Das Projekt wird gegen diese Bindungen geprüft, sodass eine öffentliche URL den Lauf nie über das hinaus ausweiten kann, woran die Automatisierung gebunden ist; ein Projekt außerhalb der Menge antwortet mit einem 400. Zwei Abweisungen lohnt es sich zu erkennen. Ein unbekanntes Token und ein Token eines ausgeschalteten Triggers antworten absichtlich gleich, damit niemand die Plattform danach abklopfen kann, welche Tokens existieren. Eine Automatisierung ohne live geschaltete Version antwortet stattdessen mit einem Konflikt — das sagt dir, dass die URL in Ordnung ist und das Live-Schalten fehlt. <Warning> Das Token in der URL ist die Zugangsberechtigung. Wer die URL hat, kann die Automatisierung starten. Bewahre sie auf wie ein Passwort, gib sie nur über einen sicheren Kanal weiter, und lösche den Trigger, um sie zu widerrufen — das Token lässt sich danach nicht wiederherstellen. </Warning> ## Ereignisse Ein Ereignis-Trigger benennt ein Plattform-Ereignis und feuert, sobald dieses Ereignis in der Organisation eintritt. Die Payload des Ereignisses wird zur Eingabe des Laufs — das ist die Art, zu der du greifst, wenn die Automatisierung auf etwas reagieren soll, das die Plattform gerade selbst getan hat. <Note> Ein Ereignis, das aus dem Lauf einer Automatisierung stammt, feuert nie Trigger. Eine Automatisierung, die einen Datensatz schreibt, der ein Ereignis auslöst, das dieselbe Automatisierung startet, wäre eine endlose Schleife, die keine Begrenzung pro Lauf stoppen kann — deshalb weist die Plattform schon bei der Zustellung ab. </Note> ## Was jede Art in den Lauf trägt Die Eingabe, die eine Automatisierung erhält, sagt, welche Art sie gestartet hat — ein einzelnes Dokument kann also mehr als einen Trigger bedienen und sich am Unterschied verzweigen. | Art | Die Eingabe des Laufs | | ---------- | ------------------------------------------------------------ | | `schedule` | Die Trigger-Art und der Termin, für den er gefeuert hat | | `webhook` | Die Trigger-Art und der gesendete Body als Payload | | `event` | Die Trigger-Art, der Name des Ereignisses und dessen Payload | Ein per API gestarteter Lauf trägt genau den `input`, den der Aufrufer gesendet hat. Deklarier die erwartete Form im `inputs`-Schema des Dokuments, und die Referenz darauf wird geprüft, bevor die Automatisierung überhaupt läuft. ## Live-Schalten stört sie nicht Weil ein Trigger die Automatisierung benennt statt eine Version, überlebt die ganze Menge jedes Live-Schalten und jedes Zurückrollen. Gib einem Partner eine Webhook-URL, schalte elf weitere Versionen live, roll zweimal zurück — diese URL funktioniert weiter und trifft jeweils das, was gerade live ist. Umgekehrt gilt dasselbe: Einen Trigger anzulegen, zu ändern oder zu entfernen ändert nichts am Dokument und nichts an seinen Versionen. Trigger und Versionen sind zwei unabhängige Dinge an derselben Automatisierung. ## Einen ausschalten, ohne ihn zu verlieren Jeder Trigger hat einen Schalter, und ihn auszuschalten ist der Weg, eine Automatisierung zu stoppen, ohne etwas aufzugeben. Ein ausgeschalteter Zeitplan wird nicht mehr fällig, eine ausgeschaltete Webhook-URL wird nicht mehr angenommen, und ein ausgeschalteter Ereignis-Trigger passt nicht mehr — während die Zeile, ihre Konfiguration und die gesamte Lauf-Historie der Automatisierung genau dort bleiben, wo sie waren. Schalt ihn wieder ein, und er nimmt seine Arbeit auf. Einen Trigger zu löschen ist die endgültige Fassung desselben Schritts, und bei einem Webhook widerrufst du damit zugleich die URL. Greif zum Schalter, wenn du eine Pause willst, und zum Löschen, wenn die Zugangsberechtigung weg soll. ## Wo das hingehört Drei Arten, ein Verhalten: Jede startet die live geschaltete Version im Live-Modus, jede hält fest, wann sie zuletzt gefeuert hat, und jede lässt sich pausieren, ohne verloren zu gehen — und keine kümmert es, wie oft du seitdem live geschaltet hast. [Automatisierungskonzepte](/de/platform/automations/concepts) erklärt, warum die Bindung an den Namen das möglich macht; [Ausführungsprotokolle](/de/platform/automations/execution-logs) zeigt die Läufe, die deine Trigger erzeugt haben, und welcher jeden gestartet hat. # Automatisierungen in deine Organisation bringen Source: https://tale.dev/docs/de/platform/automations/catalog Die Seite **Automatisierungen** in der Seitenleiste listet jede Automatisierung der Organisation und ist die Tür, durch die neue hereinkommen. Eine Organisation startet mit den mitgelieferten Packs, auf dem Canvas baust du neue von Grund auf, und **Paket hochladen** nimmt ein Pack an, das du anderswo gebaut hast — als einzelne Dateien oder als eine Zip, die auch die Skill-Bundles des Packs installiert. Die Seite verwalten dürfen Inhaber, Admins und Entwickler; alles, was ein Upload anlegt, bleibt ein Entwurf, bis du ihn deployst — nichts Laufendes ändert sich, nur weil eine Datei gelandet ist. Diese Seite behandelt, woher Automatisierungen kommen und was ein hochgeladenes Paket enthalten darf. Der Umgang mit einer einzelnen — Canvas, Versionen, Testläufe, Deployen — steht auf [Der Workflow-Editor](/de/platform/automations/editor); das Modell darunter auf [Automatisierungskonzepte](/de/platform/automations/concepts); was die mitgelieferten Packs tun, auf [Mitgelieferte Automatisierungen](/de/platform/automations/builtin). <Frame caption="Die Seite Automatisierungen — jede Zeile ist eine Automatisierung mit ihrer Versionszahl und der Version, die live ist, oder Nicht live."> ![Die Seite Automatisierungen mit den mitgelieferten E-Mail- und GitHub-Automatisierungen, jede Zeile mit Versionszahl und Deployment-Status.](/images/platform/automations-catalog.webp) </Frame> ## Was die Liste zeigt Jede Zeile ist eine Automatisierung: ihr Name, wie viele Versionen sie hat, und entweder die Live-Version oder **Nicht live**. Die Org-Seite listet Automatisierungen auf Organisationsebene; eine Automatisierung, die zu einem Projekt gehört, lebt stattdessen im **Automatisierungen**-Tab dieses Projekts — wo eine Automatisierung erscheint, entscheidet ihr erster Save, und danach zieht sie nie um. Klicke eine Zeile an und du landest auf der Seite der Automatisierung, wie [Der Workflow-Editor](/de/platform/automations/editor) sie beschreibt. **Neue Automatisierung** bietet zwei Wege, bei null zu starten: **Aus einem Ziel** übergibt deine Beschreibung dem Builder, der die Nodes für dich baut; **Leer (Trigger + Agent)** legt eine Ein-Agent-Automatisierung an, die du selbst verdrahtest — benenne sie, wähle das Modell des Agenten, und den Rest (Prompt, gewährte Tools und Secrets, Trigger) setzt du auf dem Canvas. Die mitgelieferten Packs brauchen gar keinen Installationsschritt: Jede Organisation wird bei ihrer Anlage damit ausgestattet, bereit zum Deployen. ## Ein Paket hochladen Ein Pack ist ein Verzeichnis: `workflow.yml` (das Automatisierungsdokument — erforderlich), `automation.yml` (das Manifest — optional) und, wenn das Pack eigenes Wissen mitbringt, ein Ordner pro Skill unter `skills/`. ```text review-invoices/ ├── workflow.yml ├── automation.yml └── skills/ └── invoice-rules/ ├── SKILL.md └── references/ └── checklist-rules.md ``` Zum Hochladen öffnest du **Automatisierungen**, wählst im Menü **Neue Automatisierung** den Punkt **Paket hochladen** und gibst eine der beiden Formen desselben Packs an: - **Die Dateien** — `workflow.yml`, plus `automation.yml`, wenn das Pack eine mitbringt. Richtig für ein Pack, das nur aus seinem Dokument besteht. - **Eine `.zip` des Pack-Verzeichnisses** — Pflicht, wenn das Pack Skills mitbringt, denn nur die Zip kann deren Ordner tragen. Markdown-Notizen außerhalb von `skills/` — etwa ein README — ignoriert der Upload, genauso wie Dotfiles und Build-Reste (`__pycache__/`, `node_modules/`); zippe das Verzeichnis also, wie es ist, ruhig direkt nach einem Testlauf. Die Zip bleibt unter 20 MiB. Wähle vor dem Absenden, wo die Automatisierung installiert wird — Organisation oder ein Projekt. Ein Pack, dessen Manifest `scope: project` deklariert, installiert sich nur in ein Projekt; einen organisationsweiten Upload lehnt der Server ab. Die Wahl ist nicht endgültig: Die Installation in ein Projekt bindet die Automatisierung daran, und im Bereich **Projekte** auf ihrer Seite verwaltest du die Bindungen später — binde weitere Projekte oder entferne alle, dann gilt sie organisationsweit. <Frame caption="Paket hochladen — die Dateien oder eine Zip, und wo die Automatisierung installiert wird."> ![Der Dialog zum Paket-Upload mit seiner Ablagezone und dem Auswahlfeld Installieren in, gesetzt auf Organisation.](/images/platform/automations-upload-dialog.webp) </Frame> Der Server validiert, bevor irgendetwas gespeichert wird. Das Dokument durchläuft dieselbe Engine-Validierung wie im Editor — ein Upload, der nicht laufen würde, wird mit den Meldungen der Engine abgelehnt statt kaputt gespeichert — und die Blöcke `subjects` und `settings` des Manifests werden zum Task-Vertrag und zu den [Einstellungsformularen](#einstellungen-die-das-paket-deklariert) der Automatisierung, genau wie ein Save vom Canvas sie setzen würde. Was landet, ist eine **Entwurfsversion** hinter dem normalen Deploy-Gate — kein Trigger läuft, solange keine Version live ist. Der Dialog bietet das Deployen direkt nach dem Upload an: Schalte die neue Version gleich dort live, oder wähle **Später** und deploye von der Seite der Automatisierung, wenn du bereit bist. Lädst du das Pack einer bestehenden Automatisierung erneut hoch, entsteht die nächste Version — der Store überschreibt nie Geschichte, jede frühere Version bleibt exakt, wo sie war. Wählst du dabei ein Projekt als Ziel, kommt dessen Bindung zu den bestehenden hinzu. ## Skills, die das Paket mitbringt Eine Zip darf die Skills mitliefern, auf die sich ihr Dokument stützt — die Bundles, die eine Agent-Node lädt oder aus denen ein Script-Schritt läuft. Das Manifest muss sie benennen, und die Deklaration wird in beide Richtungen geprüft: Ein `skills/`-Ordner, den das Manifest nicht deklariert, lehnt den Upload ab — genauso ein deklarierter Slug, den die Zip nicht mitbringt. ```yaml # automation.yml name: Review invoices skills: - invoice-rules subjects: task: # …der Task-Vertrag, unverändert ``` Jedes mitgebrachte Bundle wird als echter Skill validiert — Frontmatter geparst, `name` gleich seinem Ordner — und in die [Skill-Bibliothek](/de/platform/workspace/skills) der Organisation installiert, sobald der Upload angenommen ist; die Testläufe des Entwurfs finden sie also schon. Was pro Slug passiert, hängt davon ab, was die Bibliothek bereits hält: - **Neuer Slug** — das Bundle wird installiert. - **Identisches Bundle** — nichts wird geschrieben; der Upload meldet es als unverändert. - **Anderer Inhalt** — der Upload hält an und listet die kollidierenden Slugs. Bestätige, um sie durch die Versionen aus dem Paket zu ersetzen; die abgelöste `SKILL.md` bleibt im Verlauf des jeweiligen Skills. Nichts — weder die Automatisierung noch irgendein Skill — wird geschrieben, bevor du bestätigst. Ein Dokument, das einen Skill referenziert, den weder das Paket mitbringt noch die Bibliothek hält, lädt trotzdem hoch — die fehlende Referenz kommt als Warnung zurück, damit ein Pack einen Skill benennen kann, den du später installierst. ## Einstellungen, die das Paket deklariert Liest eine Automatisierung bei ihren Läufen Konfiguration, die den Betreibenden gehört — ein Fallprofil, eine Validierungsrichtlinie —, kann das Manifest sie als **Einstellungsformulare** deklarieren. Die Plattform zeigt sie im Erstellen-Dialog des Aufgabenboards und speichert jedes Formular als flache YAML-Datei in einem Projektordner: Niemand bearbeitet eine Datei von Hand, um die Automatisierung zu konfigurieren, und jedes Projekt behält seine eigenen Werte. ```yaml # automation.yml settings: folder: Setup forms: - file: validation-policy.yaml title: Validation policy required: true fields: - key: method label: Validation profile type: select default: strict_rules options: - value: strict_rules label: Strict checklist (standard) ``` Ein Formular besitzt seine Datei: Speichern schreibt `Setup/validation-policy.yaml` komplett aus den Formularwerten neu, und das Formular füllt sich aus dem, was die Datei enthält — egal ob das Formular sie geschrieben hat oder jemand sie von Hand hochgeladen hat. Felder sind `text`, `number`, `boolean` oder `select`; jeder Wert landet als String, ein `text`-Feld kann ein `pattern` festlegen, und Titel, Beschriftungen, Hilfetexte und Optionsnamen lokalisieren über `i18n`-Blöcke am jeweiligen Eintrag. Alles, was reicher ist als eine flache Schlüssel-Wert-Datei — verschachtelte Blöcke, Listen —, gehört in eine separate, von Hand gepflegte Datei, die der Workflow daneben liest. Markierst du ein Formular mit `required: true`, erzwingt der Erstellen-Dialog es pro Projekt: Wählt jemand die Aufgabenvorlage der Automatisierung zum ersten Mal in einem Projekt, das noch nicht eingerichtet ist, erscheinen die Formulare vor dem eigentlichen Aufgabenfeld, und das Erstellen geht erst weiter, wenn sie gespeichert sind. Von da an öffnet der Button **Einstellungen** im selben Dialog die Formulare zum Bearbeiten — jedes mit eigenem **Speichern**, aktiv nur, wenn sich etwas geändert hat. ## Ergebnisse, die das Paket deklariert Ein Pack, dessen Läufe Dokumente in den Ordner einer Aufgabe zurückschreiben, kann benennen, welche davon die **Ergebnisse** sind — das, wofür jemand die Aufgabe öffnet. Der Ergebnis-Bereich der Aufgabe zeigt genau diese, immer offen und in der deklarierten Reihenfolge, während alles andere im Ordner — die Uploads, die Arbeitsdateien des Laufs — unter **Dateien** eingeklappt bleibt. ```yaml # automation.yml subjects: task: outcome: files: - return.xml - report.md - journal.csv ``` Nur das Pack weiß, welche seiner geschriebenen Dateien der Punkt sind, also rät die Plattform nichts: Ein Name, den noch kein Lauf abgelegt hat, erscheint trotzdem als zugesagte Zeile mit dem Hinweis _Noch nicht bereit_ — die Aufgabe benennt also, was sie produzieren wird, bevor sie es produziert. `*` und `?` sind als Platzhalter erlaubt (`return-*.xml`), für einen Namen, den ein Lauf erst bildet. Deklarierst du nichts, zeigt der Ergebnis-Bereich jede Datei, die die Läufe abgelegt haben, die neueste zuerst. ## Wo das hingehört Automatisierungen kommen auf drei Wegen an — mit der Organisation ausgeliefert, auf dem Canvas gebaut oder als Pack hochgeladen — und jeder Weg endet an derselben Stelle: eine Entwurfsversion auf der Seite der Automatisierung, deployt auf dein Kommando. Ein Zip-Upload bestückt zusätzlich die [Skill-Bibliothek](/de/platform/workspace/skills) mit den Bundles, die die Automatisierung braucht, mit einer Bestätigung vor jedem Skill, den er ersetzen würde. [Der Workflow-Editor](/de/platform/automations/editor) ist die nächste Lektüre, um den Entwurf live zu nehmen. # Der Workflow-Editor Source: https://tale.dev/docs/de/platform/automations/editor Diese Seite ist die praktische Hälfte der Automatisierungen: was du klickst und in welcher Reihenfolge, um aus einer Idee die Version zu machen, die deine Trigger ausführen. Das Modell darunter — ein Dokument, unveränderliche Versionen, genau eine live, Trigger am Namen — steht in den [Automatisierungskonzepten](/de/platform/automations/concepts), und diese Seite setzt es voraus. Speichern, Testen und Live-Schalten sind hier drei getrennte Schritte, und genau diese Trennung erlaubt dir, eine laufende Automatisierung zu bearbeiten, ohne einen einzigen laufenden Job zu stören. ## Wo eine Automatisierung lebt Öffne **Automatisierungen** in der Seitenleiste. Die Liste zeigt jede Automatisierung der Organisation mit der Anzahl ihrer Versionen und entweder der Version, die live ist, oder **Nicht live**, solange es keine gibt. Klick eine an, und du landest auf ihrer Seite. Diese Seite ist eine einzige durchgehende Fläche statt einer Reihe von Tabs. Oben stehen der Name der Automatisierung, die Version, die du ansiehst, die Live-Version und die Schaltfläche zum Starten. Darunter liegt der Canvas mit dem Node-Panel daneben, dann die Speicherleiste, der Bereich **Trigger** und der Bereich **Projekte** — welche Projekt-Task-Boards die Automatisierung sehen; keiner heißt die ganze Organisation — und ganz unten die Listen **Versionen** und **Läufe** nebeneinander. ## Den Canvas lesen Der Canvas zeichnet die Version, die du gerade ansiehst. Jede Box ist eine Node, beschriftet mit ihrer id und ihrem Typ, und Boxen, die die Ausgabe einer anderen Node lesen, sagen das: Eine Zeile **Liest** nennt die Nodes, von denen sie abhängen. Die Pfeile dazwischen zeichnest du nicht selbst — ein Pfeil existiert, weil das Feld einer Node die Ausgabe einer anderen referenziert. Der Graph passt deshalb immer zum Dokument. Die Ablaufsteuerung erscheint als Badge an der Box, für die sie gilt, im selben Vokabular wie im Dokument: `wenn …`, `sonst zu …`, `für jedes …`, `wiederholen bis …` (mit dem Deckel, wo es einen gibt) und `bei Fehler weiterlaufen`. Nichts an der Form des Graphen versteckt sich in einem separaten Einstellungsdialog. Zwei Zustände lohnen sich zu kennen. Eine Version ohne Nodes sagt das und weist dich darauf hin, dem Dokument eine hinzuzufügen. Eine Version, deren Nodes im Kreis aufeinander verweisen, warnt dich, dass die gezeigte Reihenfolge die ist, in der sie im Dokument stehen, und nicht eine, die die Engine ausführen könnte — und bittet dich, eine der Referenzen zu entfernen, um den Kreis aufzubrechen. <Note> Der Canvas dient zum Lesen und Auswählen. Du verbindest Nodes, indem du sie referenzierst, nicht indem du eine Linie zwischen zwei Boxen ziehst. </Note> ## Eine Node bearbeiten Klick eine Box an, und das Node-Panel neben dem Canvas füllt sich mit den Feldern dieser Node. Welche Felder auftauchen, hängt vom Typ ab: **Code** bei einer `transform`, **Prompt**, **System-Prompt**, **Modell** und **Ausgabeschema** bei einer `llm`, **Workflow** bei einem `subworkflow` und **Eingabe** überall dort, wo es eine gibt. **Eingabe** ist ein JSON-Objekt, und dort leben die Referenzen. Ein Text-Wert darf die Ausgabe einer anderen Node referenzieren, und genau diese Referenz zeichnet den Pfeil auf dem Canvas. Solange das JSON unvollständig ist, sagt dir das Panel, dass es noch nicht gültig ist, und lässt die Node unverändert — eine halb getippte Änderung lässt sich so nie versehentlich speichern. Unter den typabhängigen Feldern sitzt die Gruppe **Ablaufsteuerung** mit **Wenn**, **Sonst zu**, **Für jedes** und **Wiederholen bis**. Es sind dieselben Felder, die die Badges auf dem Canvas spiegeln: Setzt du hier eines, ändert sich das Badge sofort. ## Speichern, starten, live schalten Die drei Schritte sind bewusst getrennt. Geh sie beim ersten Mal der Reihe nach durch, dann fühlt sich die Trennung nicht mehr nach Mehrarbeit an. <Steps> <Step title="Eine Version speichern"> Änderungen zeigen den Hinweis **Nicht gespeicherte Änderungen**, bis du speicherst. Schreib eine **Notiz zur Version**, die sagt, was sich geändert hat — diese Notiz unterscheidet später als Einziges zwei Versionen in der Liste —, und klick dann **Version speichern**. Das Speichern hängt eine neue Version an und lässt jede frühere genau so, wie sie war. Hat sich nichts geändert, sagt dir die Schaltfläche das, statt eine identische Version anzulegen. </Step> <Step title="Gegen Mocks laufen lassen"> **Testlauf** startet einen Lauf im Testmodus: Konnektoren liefern ihre deterministischen Platzhalter, und nichts außerhalb der Plattform wird berührt. Du kannst ihn beliebig oft drücken, und genau deshalb ist er die Schleife, in der du arbeitest, solange eine Node noch Form annimmt. Ist die Automatisierung an mehr als ein Projekt gebunden, sitzt neben den Lauf-Schaltflächen ein **Projektbereich**-Auswähler. Er steht standardmäßig auf organisationsweit; wähle eines der gebundenen Projekte, damit der Lauf — und die Aufgaben- und Dokument-Tools seiner Agents — nur in diesem Projekt wirkt. </Step> <Step title="Die gewünschte Version live schalten"> Klick in der Liste **Versionen** bei der Version, die deine Trigger ausführen sollen, auf **Live schalten**. Die aktuelle trägt das Badge **Live**, und eine andere live zu schalten verschiebt dieses Badge, ohne den Inhalt irgendeiner Version anzufassen. </Step> </Steps> <Note> Die Schaltfläche auf dieser Seite startet immer einen Lauf gegen Mocks. Ein Lauf, der die Außenwelt erreichen darf, wird von einem Trigger oder programmatisch gestartet, und das ist eine Entwickler-Berechtigung. </Note> ## Tests und das Tor zum Live-Schalten Tests sind Teil des Dokuments, kein eigenes Panel. Jeder trägt einen Namen, eine Eingabe und Erwartungen an die Ausgabe sowie an die Auswirkungen, die der Lauf erzeugen soll, und sie reisen mit der Version wie jedes andere Feld. ```yaml tests: - name: erinnert einen säumigen Zahler input: { invoiceId: 'inv-1' } expect: effects: - connector: email.send ``` Ob die Tests einer Version bestanden waren, wird beim Speichern festgehalten, und die Liste **Versionen** zeigt das Ergebnis als Badge **Tests bestanden** oder **Tests fehlgeschlagen**. Das Live-Schalten liest diesen Eintrag: Eine mit fehlgeschlagenen Tests gespeicherte Version wird abgewiesen, und die Liste sagt dir, dass sie nicht live geschaltet wurde, statt stillschweigend nichts zu tun. Behebe die Ursache und speichere eine neue Version — ein festgehaltenes Ergebnis ist eine Tatsache über diese Version und ändert sich nie. ## Zurückrollen Zurückrollen heißt, eine ältere Version live zu schalten. Such die Version in der Liste, lies ihre Notiz, um sicherzugehen, dass es die richtige ist, und klick **Live schalten**. Das Badge wandert, die neueren Versionen bleiben unangetastet in der Liste, und kein Dokument wird umgeschrieben. Deshalb zählen Versionsnotizen mehr, als sie aussehen. Sechs Versionen später sagt dir die Notiz, welche der letzte gute Stand war — schreib sie also für die Person, die sie während einer Störung lesen wird. ## Den letzten Lauf auf dem Canvas lesen Sobald eine Automatisierung gelaufen ist, legt **Letzten Lauf einblenden** diesen Lauf über den Canvas. Jede Box übernimmt den Status, den der Lauf ihr gegeben hat — sie ist **Gelaufen**, wurde **Übersprungen**, ist **Fehlgeschlagen**, wurde **Nie erreicht** oder ist **Noch nicht erreicht**, solange der Lauf weitergeht. Ein Fehler wird so als Stelle im Graphen sichtbar statt als Zeile in einem Log. Wähl bei eingeblendetem Lauf eine Node, und das Panel ergänzt einen Abschnitt **In diesem Lauf**: die **Aufgelöste Eingabe**, die die Node tatsächlich bekommen hat, nachdem jedes Template ausgewertet war, ihre **Ausgabe** und die Auswirkungen, die sie erzeugt hat, oder den Hinweis, dass sie außerhalb der Plattform nichts verändert hat. Die aufgelöste Eingabe beantwortet meist am schnellsten die Frage, warum eine Node getan hat, was sie getan hat — sie zeigt den Wert, den eine Referenz ergeben hat, nicht die Referenz, die du geschrieben hast. **Letzten Lauf öffnen** führt zur vollständigen Lauf-Seite, wo derselbe Canvas neben Eingabe, Ausgabe und der kompletten Liste der Auswirkungen steht. [Ausführungsprotokolle](/de/platform/automations/execution-logs) liest diese Seite von Anfang bis Ende. ## Wo das hingehört Die Schleife ist kurz, sobald die drei Schritte klar sind: eine Node bearbeiten, eine Version mit einer lesenswerten Notiz speichern, sie gegen Mocks laufen lassen, bis sie tut, was du meintest, und sie dann live schalten — und eine ältere live schalten, wenn du etwas rückgängig machen musst. [Automatisierungskonzepte](/de/platform/automations/concepts) ist das Modell, das diese Seite bedient; [Workflow-Trigger](/de/platform/automations/triggers) ist das, was die live geschaltete Version startet, sobald du zufrieden bist. # Ausführungsprotokolle Source: https://tale.dev/docs/de/platform/automations/execution-logs Jeder Start einer Automatisierung öffnet einen Lauf, und dieser Lauf schreibt weiter an sich selbst, bis er fertig ist. Er hält fest, was ihn gestartet hat, welche Version er benutzt hat, was er bekommen hat, was jede Node erzeugt hat und alles, was er außerhalb der Plattform verändert hat. Das ist die Fläche, auf die jede andere Automatisierungsseite zeigt, wenn etwas anders lief als erwartet — es lohnt sich also, einen Lauf lesen zu können, bevor du es musst. ## Die Liste der Läufe Die Seite einer Automatisierung endet mit einer Liste **Läufe**, neueste zuerst. Jede Zeile trägt den Status des Laufs, ob es ein Test oder ein Live-Lauf war, die ausgeführte Version, den Startzeitpunkt und was ihn gestartet hat. Ein fehlgeschlagener oder wartender Lauf zeigt den Grund direkt in der Zeile statt des Starters — oft beantwortet die Liste die Frage also, ohne dass du etwas öffnen musst. Eine Automatisierung, die noch nie gelaufen ist, sagt das, statt eine leere Tabelle zu zeigen. ## Was jeder Status bedeutet | Status | Was er dir sagt | | ------------------------ | ------------------------------------------------------------------------------------- | | **In der Warteschlange** | Der Lauf existiert und wartet darauf, dass die Engine ihn aufnimmt | | **Läuft** | Die Engine arbeitet sich durch die Nodes | | **Wartet** | Der Lauf steht auf einer menschlichen Entscheidung oder einer Antwort, die er braucht | | **Erfolgreich** | Jede erreichte Node ist fertig geworden und die Ausgabe wurde erzeugt | | **Fehlgeschlagen** | Eine Node lief auf einen Fehler, und nichts war so eingestellt, dass es weitergeht | | **Gestoppt** | Jemand hat den Lauf abgebrochen; bereits Erledigtes wird nicht rückgängig gemacht | **Wartet** wird am häufigsten falsch gelesen. Es ist kein Stillstand und kein Fehler — der Lauf hält seinen Platz und macht an genau der Node weiter, an der er stehen geblieben ist, sobald die Entscheidung gefallen ist. [Genehmigungen in Workflows](/de/platform/automations/approvals-in-workflows) behandelt, worauf er wartet. ## Testläufe und Live-Läufe Jeder Lauf ist als das eine oder das andere markiert, und der Unterschied ist, ob die Außenwelt berührt wurde. Ein **Test**-Lauf nutzt den deterministischen Platzhalter jedes Konnektors: Es geht keine Mail raus, kein Datensatz wird geschrieben, nichts wird abgerechnet. Ein **Live**-Lauf darf all das, weshalb ihn zu starten eine Entwickler-Berechtigung braucht und weshalb jede Auswirkung festgehalten wird. Ein Testlauf sagt dir, ob Graph und Datenfluss stimmen. Nur ein Live-Lauf sagt dir, ob sich die Systeme draußen so verhalten haben, wie du dachtest. ## Einen Lauf lesen Öffne einen Lauf, und du bekommst den Canvas der Automatisierung mit diesem Lauf darübergelegt, dazu die Eckdaten des Laufs: die Version, den Modus, wann er gestartet ist und wann er geendet hat. ### Ergebnisse pro Node Jede Box auf dem Canvas trägt den Status, den der Lauf ihr gegeben hat — sie ist **Gelaufen**, wurde **Übersprungen**, ist **Fehlgeschlagen**, wurde **Nie erreicht** oder ist **Noch nicht erreicht**, solange der Lauf weitergeht. Ein Fehler ist damit eine Stelle im Graphen statt einer Zeile, die du suchen musst, und die Nodes dahinter zeigen offensichtlich, dass sie nie erreicht wurden. Wähl eine Node, und das Panel zeigt, was mit ihr passiert ist: die **Aufgelöste Eingabe**, die sie tatsächlich bekommen hat, nachdem jedes Template ausgewertet war, und ihre **Ausgabe**. Die aufgelöste Eingabe ist das nützlichste Feld dieser Seite. Sie zeigt den Wert, den eine Referenz ergeben hat, statt der Referenz, die du geschrieben hast — so fällt ein Template auf, das still zu nichts aufgelöst wurde. Übersprungene Nodes lohnt es sich zu lesen, statt sie zu überfliegen, denn der Grund ist verschieden: Eine Node kann durch ihre eigene Bedingung übersprungen werden, weil eine Node, von der sie abhängt, übersprungen wurde, weil sie der Sonst-Zweig einer gelaufenen Node ist, oder weil sie unter einer Einstellung fehlschlug, die den Lauf weiterlaufen lässt. ### Auswirkungen Ein Lauf bewahrt außerdem die geordnete Liste von allem, was er außerhalb der Plattform verändert hat — jeder Eintrag nennt die verursachende Node, die aufgerufene Connector und die Eingabe, mit der sie aufgerufen wurde. Ein Lauf, der außerhalb der Plattform nichts verändert hat, sagt das ausdrücklich, und das ist eine echte Antwort statt eines leeren Abschnitts. Die Liste der Auswirkungen macht einen Lauf nachträglich prüfbar. Wenn jemand fragt, ob eine Nachricht tatsächlich rausging, ist das die Liste, die antwortet — und sie bleibt dauerhaft beim Lauf. ## Warum ein langer Lauf sich nicht wiederholt Ein Live-Lauf läuft nicht in einem Zug durch. Er geht Node für Node vor, und jede abgeschlossene Node wird festgehalten, bevor die nächste beginnt. Erreicht der Lauf das Zeitfenster der Plattform, gibt er sich zurück und setzt bei der letzten abgeschlossenen Node fort. Eine bereits gelaufene Node wird nie ein zweites Mal erreicht — das hindert einen unterbrochenen Lauf daran, dieselbe Nachricht zweimal zu senden. Dieselben Checkpoints decken einen Lauf ab, dessen Fortsetzung verloren ging. Ein Lauf, der über eine Schonfrist hinaus in einem nicht abgeschlossenen Zustand liegt, wird von selbst wieder aufgenommen und setzt dort fort, wo seine Checkpoints ihn verorten — statt neu zu starten oder für immer unfertig liegen zu bleiben. ## Eine durchgespielte Fehlersuche Die tägliche Erinnerung ging nicht raus. Öffne die Automatisierung und sieh in die Liste **Läufe**: Der Lauf von heute Morgen steht da und ist **Fehlgeschlagen**, mit dem Grund in der Zeile. Öffne ihn. Der Canvas zeigt die ersten drei Nodes als gelaufen, die vierte als fehlgeschlagen und alles danach als nie erreicht — die Frage ist damit schon auf eine Box eingegrenzt. Wähl die fehlgeschlagene Node und lies ihre **Aufgelöste Eingabe**: Der Kundenname ist da, die Rechnungs-id ist ein leerer Text. Das zeigt eine Node weiter nach oben. Wähl diese Node und lies ihre Ausgabe. Sie hat einen Datensatz ohne Feld `id` zurückgegeben, weil das gelesene Feld umbenannt worden war. Das Template darauf ergab nichts, und die Node dahinter scheiterte am leeren Wert statt an irgendetwas an sich selbst. <Tip> Lies die Liste der Auswirkungen, bevor du etwas reparierst. Sie sagt dir, ob der Lauf weit genug kam, um die Außenwelt zu berühren — und davon hängt ab, ob ein erneuter Lauf harmlos ist oder erst aufgeräumt werden muss. </Tip> Korrigier die Referenz im Node-Panel, speichere eine Version mit einer Notiz, die das umbenannte Feld nennt, und drück **Testlauf**. Der Testlauf geht denselben Graphen durch, und diesmal zeigt jede Box, dass sie gelaufen ist. Schalt diese Version live, und der Zeitplan von morgen nimmt sie auf. ## Einen Lauf stoppen Solange ein Lauf nicht fertig ist, kannst du ihn stoppen, und ein gestoppter Lauf ist endgültig — die Engine prüft an jeder Node-Grenze und plant die nächste nicht mehr ein. Bereits Erledigtes wird nicht zurückgenommen, weil es das nicht kann: Eine gesendete Nachricht ist gesendet. Lies die Liste der Auswirkungen, um zu sehen, wie weit er kam, bevor du entscheidest, was als Nächstes passiert. ## Wo das hingehört Ein Lauf ist die Quittung, die eine Automatisierung hinterlässt: Sein Status sagt, was passiert ist, seine Ergebnisse pro Node sagen wo, seine aufgelösten Eingaben sagen warum, und seine Auswirkungen sagen, was er außerhalb der Plattform verändert hat. Kombinier diese Seite mit [Workflow-Trigger](/de/platform/automations/triggers) für die Startarten, die diese Einträge öffnen, und mit [Audit-Logs](/de/platform/admin/governance/audit-logs) für die organisationsweite Spur, wer was geändert hat. # Automatisierungskonzepte Source: https://tale.dev/docs/de/platform/automations/concepts Eine Automatisierung ist ein gespeichertes Workflow-Dokument unter einem Namen — zusammen mit allem, was die Plattform darum herum aufbewahrt: der Historie seiner Versionen, der einen Version, die live ist, den Triggern, die sie starten dürfen, und dem Protokoll jedes Laufs. Öffne **Automatisierungen** in der Seitenleiste, und jede Zeile ist einer dieser Namen, mit der Version daneben, die live ist. Drei Gedanken auf dieser Seite bestimmen, wie sich alles Weitere verhält — Versionen ändern sich nie, Live-Schalten ist ein eigener Schritt, und ein Trigger hängt am Namen statt an einer Version —, also lies sie, bevor du etwas baust. Lieber erst zusehen? Episode 5 öffnet die Triage-Automatisierung von vorne bis hinten und entscheidet eine echte Freigabekarte vor der Kamera, mit Untertiteln. <Video src="/videos/de/tutorials/ep5-automations/ep5-automations.de.mp4" poster="/videos/de/tutorials/ep5-automations/ep5-automations.de.webp" captions="/videos/de/tutorials/ep5-automations/ep5-automations.de.vtt" lang="de" title="Episode 5 — Automatisierungen & Freigaben" caption="Episode 5 — Automatisierungen & Freigaben (3:11)"> </Video> ## Das Workflow-Dokument Alles, was eine Automatisierung tut, steht in einem einzigen Dokument. Sein `name` ist zugleich seine Identität — kleingeschriebene Slug-Segmente mit Bindestrichen, wobei `/` verwandte Automatisierungen zu Ordnern gruppiert, etwa `billing/dunning-reminder`. Um den Namen herum stehen eine `description`, ein `inputs`-JSON-Schema für die Eingabe zur Laufzeit, die `nodes`, die die Arbeit erledigen, ein `output` als Rückgabewert und die `tests`, die darüber entscheiden, ob eine Version live gehen darf. ```yaml name: billing/dunning-reminder description: Einen Kunden an eine überfällige Rechnung erinnern. inputs: type: object properties: invoiceId: { type: string } required: [invoiceId] nodes: - id: invoice type: transform input: id: '{{ input.invoiceId }}' code: 'return { id: input.id, daysLate: 14 };' - id: message type: llm model: openai/gpt-4o-mini prompt: 'Schreibe eine höfliche Erinnerung zu Rechnung {{ nodes.invoice.output.id }}.' output: text: '{{ nodes.message.output.text }}' tests: - name: erzeugt eine Erinnerung input: { invoiceId: 'inv-1' } ``` Die Positionen auf dem Canvas reisen in einem `ui`-Block mit, den die Engine ignoriert — eine Box zu verschieben ändert also nie das Verhalten. ### Kanten entstehen, sie werden nicht deklariert Es gibt keine Kantenliste. Eine Node liest eine andere, indem sie sie referenziert — `{{ nodes.invoice.output.id }}` —, und genau diese Referenz _ist_ die Kante, die der Canvas zeichnet. Die Reihenfolge ergibt sich aus einer topologischen Sortierung über diese abgeleiteten Kanten. Deshalb verschwindet mit einer gelöschten Referenz auch ein Pfeil, und deshalb weist die Plattform zwei Nodes zurück, die einander lesen. Templates nutzen eine einzige `{{ }}`-Grammatik aus JavaScript-Ausdrücken über `input`, `nodes.<id>.output` und, innerhalb einer iterierenden Node, `item` und `index`. ### Die Ablaufsteuerung sitzt an der Node Verzweigen und Wiederholen sind Felder an einer Node statt eigener Schritttypen. Der Canvas zeigt sie deshalb als Badges an genau der Box, die sie betreffen. | Feld | Wirkung | | ---------------------------- | --------------------------------------------------------------------------------------- | | `when` | Die Node läuft nur, wenn der Ausdruck wahr ist; abhängige Nodes werden mit übersprungen | | `elseOf` | Läuft genau dann, wenn die genannte Node durch ihr eigenes `when` übersprungen wurde | | `forEach` | Läuft einmal pro Element einer Sammlung, mit `item` und `index` im Zugriff | | `repeatUntil` / `maxRepeats` | Wiederholt, bis der Ausdruck wahr ist, mit Deckel (Standard 5, Maximum 20) | | `onError` | `fail` bricht den Lauf ab; `continue` notiert den Fehler und überspringt Abhängige | ### Node-Typen Drei Typen sind eingebaut, und jede Connectorsaktion sowie jede Plattformfunktion — Wissenssuche, Dokumentoperationen — reiht sich in dieselbe Tabelle daneben ein. **`transform`** führt reines JavaScript aus, um Daten umzuformen. Ohne Netzwerk und ohne Imports: Der Rumpf liest die aufgelöste `input` der Node und muss einen Wert zurückgeben. **`llm`** ruft ein Sprachmodell mit einem Prompt-Template auf. `model` ist Pflicht und immer ausdrücklich — eine Automatisierung wählt nie eines für dich (das Auto der Chat-Eingabezeile ist eine reine Chat-Sache). Die Ausgabe ist `{text}` oder das Objekt in Form des Schemas, wenn die Node ein `outputSchema` deklariert. **`subworkflow`** führt eine andere gespeicherte Automatisierung als einzelne Node aus, referenziert als `"name"` oder `"name@version"`. Ohne Version läuft die live geschaltete, und die Verschachtelung endet bei drei Ebenen. ### Strukturierte und unstrukturierte Ausgabe Die Ausgabe jedes Node-Typs ist von einer von zwei Arten, und daran stolpern Autoren am häufigsten. Eine **strukturierte** Ausgabe ist eine typisierte Form, in die du mit `nodes.<id>.output.<field>` hineingreifen darfst. Eine **unstrukturierte** Ausgabe ist freier Text: Es existiert nur `nodes.<id>.output.text`, und das nur im Textkontext. Ein Werkzeug ohne deklariertes Ausgabeschema ist per Definition unstrukturiert, und die eine vorgesehene Brücke von Text zu strukturierten Daten ist eine `llm`-Node mit `outputSchema`. Die Validierung weist den Fehler zurück, statt ihn erst zur Laufzeit auftauchen zu lassen, und jede Meldung trägt einen maschinenlesbaren Code sowie einen Hinweis darauf, was tatsächlich verfügbar ist. Diesen Hinweis zu lesen ist der Weg, die Form zu finden, die du referenzieren wolltest. ## Versionen ändern sich nie Speichern hängt eine neue Version an; es überschreibt nie eine bestehende. Versionen sind ab 1 nummeriert und bleiben je Automatisierung lückenlos, und jede trägt die Notiz, die ihr Autor zur Änderung geschrieben hat. Version 3 einer Automatisierung ist deshalb für immer dasselbe Dokument. Daraus folgt zweierlei. Eine Automatisierung zu bearbeiten kann nicht stören, was gerade läuft, denn die laufende Version ist eine andere Zeile. Und ein Lauf, der letzten Monat fehlgeschlagen ist, lässt sich gegen genau das Dokument lesen, das ihn erzeugt hat — dieses Dokument existiert unverändert weiter. ## Live-Schalten ist ein eigener Schritt Genau eine Version pro Automatisierung ist live, und diese Version führen die Trigger aus. Eine Version live zu schalten oder auf eine ältere zurückzugehen ist ein einzelner Schritt, der keine Historie umschreibt — die Versionsliste bleibt exakt, wie sie war, und nur der Zeiger wandert. Eine Automatisierung darf auch gar nichts live haben und rein als Entwurf existieren. Eine Version wird erst live-fähig, wenn ihre eigenen Tests bestanden sind. Tests liegen im Dokument: Jeder hat einen Namen, eine Eingabe und Erwartungen an die Ausgabe sowie an die Auswirkungen, die der Lauf erzeugen soll. Ob die Tests einer Version bestanden waren, wird beim Speichern festgehalten — das Live-Schalten liest diese festgehaltene Tatsache, statt die Suite erneut laufen zu lassen. <Note> Eine Automatisierung ohne live geschaltete Version lässt sich überhaupt nicht starten — weder von einem Trigger noch von Hand. Speichere eine Version und schalte sie dann live. </Note> ## Was einen Lauf startet Ein Trigger sagt, was eine Automatisierung starten darf, und es gibt genau drei Arten: einen **schedule** (ein Cron-Ausdruck, gelesen in einer benannten IANA-Zeitzone), einen **webhook** (eine eingehende URL, geschützt durch ein Token) und ein **event** (der Name eines Plattform-Ereignisses). Ein Trigger hängt am **Namen** der Automatisierung, nie an einer Version. Eine neue Version live zu schalten macht deshalb nie eine Webhook-URL ungültig, auf die ein externes System angewiesen ist, und wirft nie einen Zeitplan weg, auf den sich jemand verlässt. Jeder Trigger lässt sich aus- und wieder einschalten, ohne verloren zu gehen, und jeder hält fest, wann der Scheduler zuletzt auf ihn reagiert hat. [Workflow-Trigger](/de/platform/automations/triggers) behandelt, was jede Art in den Lauf trägt. ## Was ein Lauf festhält Ein Lauf ist ein dauerhaftes Objekt, keine Logzeile. Er hält seinen Status — `queued`, `running`, `waiting`, `success`, `failed` oder `cancelled` —, seinen Modus, was ihn gestartet hat, die empfangene Eingabe, die erzeugte Ausgabe und einen **Checkpoint für jede abgeschlossene Node**. Diese Checkpoints sind der Kern. Ein Live-Lauf geht Node für Node vor, und wenn er an das Zeitfenster der Plattform stößt, gibt er sich zurück und setzt bei der letzten abgeschlossenen Node fort, statt bereits erledigte Nebenwirkungen zu wiederholen. Ein Lauf bewahrt außerdem die vollständige Spur der Engine und die geordnete Liste der Auswirkungen, die er erzeugt hat — das ist es, was den Canvas den Lauf nachzeichnen lässt und was jede Veränderung außerhalb der Plattform nachträglich prüfbar hält. Läufe gibt es in zwei Modi. **Test** berührt die Außenwelt nie und ist die schnelle Rückmeldeschleife beim Bauen. **Live** darf es, weshalb einen solchen Lauf zu starten eine Entwickler-Berechtigung braucht. [Ausführungsprotokolle](/de/platform/automations/execution-logs) liest einen Lauf von Anfang bis Ende. ## Wo ein Mensch entscheidet Ein Lauf, der eine Freigabe braucht, schlägt nicht fehl und startet nicht neu. Er pausiert im Status `waiting`, und sobald die Freigabe beantwortet ist, setzt er an genau der Node wieder ein, an der er stehen geblieben war, und trägt die Antwort weiter. Ein Lauf, der auf eine menschliche Eingabe wartet, verhält sich genauso. [Genehmigungen in Workflows](/de/platform/automations/approvals-in-workflows) behandelt die Kontrollpunkte und was jede Entscheidung hinterlässt. ## Die richtige Einheit wählen | Greif zu … bei | Automatisierung | Agent | Agent-Webhook | | ---------------------------------------------------------------------------------- | --------------- | ----- | ------------- | | Arbeit mit mehreren Schritten, Verzweigungen, Zeitplänen oder Freigaben dazwischen | ✓ | | | | Etwas, das nach der Uhr laufen oder einen Webhook beantworten muss | ✓ | | | | Einer wiederkehrenden Frage im Chat, ohne externes System | | ✓ | | | Einer Agent-Antwort pro eingehendem POST | | | ✓ | Prüf den Katalog, bevor du baust — die Automatisierung, die du brauchst, wird vielleicht schon mitgeliefert. Ein [Webhook-Trigger](/de/platform/automations/triggers) ist die eingehende Naht; greif dazu, wenn eine externe Payload einen Lauf starten soll. ## Das Modell in die Praxis bringen Eine Automatisierung ist ein Dokument, geführt als ununterbrochene Kette von Versionen, von denen genau eine live ist, mit Triggern, die an ihrem Namen hängen statt an irgendeiner Version — und genau das macht Bearbeiten sicher, Zurückrollen billig und einen fehlgeschlagenen Lauf reproduzierbar. [Der Workflow-Editor](/de/platform/automations/editor) ist das praktische Handbuch zum Speichern, Testen, Live-Schalten und Zurückrollen; [Automatisierungen durchsuchen und installieren](/de/platform/automations/catalog) führt zu denen, die schon mitgeliefert werden. # Genehmigungen in Workflows Source: https://tale.dev/docs/de/platform/automations/approvals-in-workflows Workflows laufen ohne dich, aber sie ändern sich und starten nur mit dir. Drei menschliche Tore umgeben jeden Workflow: Die Änderungen des KI-Editors an einer Definition greifen erst nach deiner Genehmigung, ein Agent, der einen Workflow starten will, braucht zuerst dein Einverständnis, und ein Lauf, der auf eine Frage stößt, pausiert, bis jemand antwortet. Diese Seite behandelt die drei Tore; die organisationsweite Geschichte, was eine Genehmigungskarte ist, steht auf [Genehmigungskonzepte](/de/platform/approvals/concepts). <Frame caption="Der Canvas einer Automatisierung mit dem Panel daneben — eine vorgeschlagene Änderung kommt als Genehmigungskarte an und greift nie still ins Dokument ein."> ![Der Workflow-Canvas einer Automatisierung mit einem Graphen aus Nodes und einem geöffneten Panel daneben.](/images/platform/automation-editor-canvas.webp) </Frame> ## Änderungen an einer Definition genehmigen Bitte den Assistenten, eine Automatisierung zu bauen oder umzubauen, und sein Vorschlag landet als Karte statt als Änderung. Die Karte benennt, was sie tun würde — eine neue Automatisierung anlegen, eine einzelne Node anpassen oder das ganze Dokument ersetzen — und hält, bis du entscheidest. Genehmigst du sie, wird das Ergebnis als neue Version gespeichert, genau wie bei einem manuellen Speichern: Das Dokument, das du angesehen hast, bleibt unangetastet, und die live geschaltete Version bleibt live, bis jemand live schaltet. Abbrechen verwirft den Vorschlag, und solange die Karte aussteht, erreicht nichts das Dokument. ## Einen Lauf genehmigen Ein Agent im Chat, der die Automatisierungs-Tools hält, kann darum bitten, eine zu starten. Die Anfrage kommt als Karte an, die die Automatisierung benennt, und du kannst sie ausklappen, um vor der Entscheidung genau die Eingabe zu prüfen, mit der sie laufen würde. Nach der Genehmigung verfolgt dieselbe Karte den laufenden Lauf — an welcher Node er ist, wie lange er schon läuft und wie er geendet hat — und lässt dich ihn mitten im Flug stoppen oder den Lauf selbst für die vollständigen Details pro Node öffnen. <Note> Der Chat hält an, solange eine Anfrage aussteht, und sagt dir das auch. Entscheide die Karte, bevor du die nächste Nachricht schickst. </Note> ## Einen pausierten Lauf beantworten Ein Lauf, der eine menschliche Antwort braucht, nimmt in der [Liste der Läufe](/de/platform/automations/execution-logs) den Status **Wartet** an und parkt dort. Die Frage kommt als Formularkarte an — fülle sie aus und schick sie ab, oder widersprich in freiem Text, wenn das Formular nicht das Richtige fragt. Antworten startet nichts neu: Der Lauf setzt an genau der Node wieder ein, an der er stehen geblieben ist, trägt deine Antwort als deren Eingabe weiter und arbeitet den Rest des Graphen ab. Jede bereits abgeschlossene Node bleibt abgeschlossen, nichts von vorher passiert also zweimal. ## Was jede Entscheidung hinterlässt Jedes Tor durchläuft auf der Karte selbst dieselbe Handvoll Zustände — ausstehend, dann in Ausführung, dann abgeschlossen oder abgelehnt —, und die Entscheidung landet im [Audit-Log](/de/platform/admin/governance/audit-logs) mit Akteur und Zeitstempel. Eine entschiedene Karte lässt sich nicht wieder öffnen; um einen abgelehnten Lauf erneut zu versuchen, frag noch einmal und entscheide die frische Karte. Eine Genehmigung, die einen Lauf gestartet hat, hinterlässt diesen Lauf als eigenen Datensatz — was die Entscheidung tatsächlich bewirkt hat, bleibt also in der [Liste der Läufe](/de/platform/automations/execution-logs) lesbar, lange nachdem die Karte weg ist. ## Wo das hingehört Diese Tore sind die Workflow-Seite eines produktweiten Musters: Ein Agent schlägt vor, ein Mensch entscheidet. [Genehmigungskonzepte](/de/platform/approvals/concepts) benennt jeden Kartentyp jenseits von Workflows — Dokument-Schreibzugriffe, Wissens-Schreibzugriffe, Connector-Aufrufe — und [Genehmigungen konfigurieren](/de/platform/approvals/configure) zeigt, wo die Anforderungen deklariert sind. # Automatisierungs-Assistent Source: https://tale.dev/docs/de/platform/automations/assistant Der **Automatisierungs-Assistent** ist der Chat-Agent, der auf eine einzelne Automatisierung ausgerichtet ist und mit deren Dokument, ihren Agents, ihren Skills und ihren Connectors bereits im Kontext antwortet. Admins und Entwickler nutzen ihn, um eine Automatisierung zu verstehen, die sie nicht gebaut haben, eine bestehende zu erweitern statt sie zu duplizieren, oder Hilfe beim Verfassen der Bestandteile zu bekommen, die die eigene Seite der Automatisierung nicht editiert. Frag ihn, was etwas tut, bevor du von Hand daran rührst — er liest das ganze Dokument auf einmal statt eine Node nach der anderen. ## Was er direkt editiert Das Dokument der Automatisierung ist der eine Bestandteil, auf den der Assistent vollen Werkzeugzugriff hat: Er liest die aktuelle Version, editiert Nodes, validiert das Ergebnis, speichert eine neue Version und lässt sie gegen Mocks laufen — dieselben Schritte, die du von Hand ausführen würdest, in derselben Reihenfolge. Er arbeitet unter denselben Regeln wie du: Ein Speichern hängt eine Version an, statt eine zu überschreiben, und die live geschaltete Version bleibt live, bis jemand live schaltet. Bei Agents ist er einen Schritt zurück: Er liest die Liste und kann einen installieren, aktivieren oder deaktivieren, aber Instructions, Modell und der Rest der Konfiguration eines Agents bleiben deine eigene Aufgabe im Agent-Editor — der Assistent entwirft das genaue JSON, und du fügst es dort ein. ## Was er stattdessen entwirft Für Skills, Connectors und mitgelieferte Ansichten gibt es überhaupt kein Editier-Werkzeug: Der Assistent schreibt die Definition im richtigen Format und sagt dir genau, wo du sie anwendest — Einstellungen > Connectors für eine Anmeldung, die eigene Seite der Automatisierung für eine Ansicht. Installation und Einrichtung laufen genauso: Er geht die Einrichtungs-Checkliste mit dir durch und benennt, was noch verbunden und was noch aktiviert werden muss, statt selbst zu verbinden. Dieselbe Grenze gilt für Trigger. Der Assistent kann dir sagen, welchen Zeitplan-, Webhook- oder Ereignis-Trigger eine Automatisierung trägt und was jeder davon in einen Lauf schicken würde, und er kann dir den gewünschten Trigger genau ausformulieren — aber die Entscheidung, eine Automatisierung nach außen freizugeben, bleibt eine menschliche. [Automatisierungs-Trigger](/de/platform/automations/triggers) behandelt, was jede Art tut. ## Finden, was schon existiert Bevor er irgendetwas baut, sucht der Assistent nach einer Automatisierung oder einem Bundle, das er erweitern statt duplizieren kann — dieselbe Regel „Erst wiederverwenden, dann bauen", die auch beim Verfassen neuer Skills oder Connectors gilt. Seine Suche reicht bis zu Automatisierungen, die der Katalog selbst versteckt: Die versteckten Mitglieder eines Bundles (siehe [Automatisierungskonzepte](/de/platform/automations/concepts)) bleiben für den Assistenten sichtbar, sodass er dich zum Beispiel auf den PR-Creator-Agent verweisen kann, der in GitHub-Issues lösen vergraben ist, statt einen neuen vorzuschlagen. ## Wo das hineinpasst Der Automatisierungs-Assistent ist der schnellste Weg in eine Automatisierung, die du nicht selbst gebaut hast — frag ihn, was etwas tut, bevor du von Hand daran rührst. [Automatisierungskonzepte](/de/platform/automations/concepts) ist das Vokabular, das er voraussetzt; [Automatisierungen durchsuchen und installieren](/de/platform/automations/catalog) ist der Ort, an dem du umsetzt, was er dir sagt, falls die Automatisierung noch nicht installiert ist. # Status-Page Source: https://tale.dev/docs/de/develop/status-page Die Status-Page ist die kanonische Aufzeichnung der Verfügbarkeit von Tale Cloud. Jeder rotierbare Service hat seine eigene Status-Zeile, die Incident-Historie wird für den Audit-Pfad geführt, und die Seite ist der Kanal, den Tale während eines Incidents nutzt — bevor E-Mails rausgehen, bevor Support-Tickets beantwortet sind, wird die Seite aktualisiert. Lies das, wenn etwas sich seltsam verhält und du wissen willst, ob es nicht nur dich trifft. Abonnier den Feed, wenn du auf deiner Seite für die Connector verantwortlich bist — die Seite sagt dir, welcher Service degradiert ist, damit du den Alarm zum richtigen Team routen kannst, ohne die falsche Bereitschaft zu wecken. ## Ein durchgespieltes Abonnement Die Status-Page liegt unter `https://status.tale.dev`. Abonnieren ist eine URL: ```bash curl -sS https://status.tale.dev/history.rss ``` Der RSS-Feed trägt jeden Status-Wechsel — offen, Update, gelöst — für jeden Service. E-Mail-Abonnement ist dasselbe Ein-Klick-Formular auf der Seite; der E-Mail-Kanal liefert dieselben Events mit fünf Minuten Debounce. ## Umfang pro Service | Service | Was er abdeckt | Wann er rot wird | | ---------- | --------------------------------------------------------------------------------------- | ----------------------------------------------------------- | | `platform` | Die TanStack-Start-+-Convex-Anwendung — Agents, Workflows, Connectors, UI. | UI nicht erreichbar; API gibt 5xx; Auth defekt. | | `rag` | Der Python-FastAPI-Dokumentdienst — Indexierung, Retrieval. | Dokument-Uploads stocken; Retrieval ist leer. | | `crawler` | Der Crawl4AI-Web-Extraktionsdienst — verwendet von Document-Ingest und Tavily-Fallback. | Web-gezogene Dokumente scheitern; Deep Research stockt. | | `proxy` | Der Caddy-Edge — TLS-Terminierung, HTTP-Routing. | Gesamter Tale-Cloud-Verkehr betroffen. | | `db` | TimescaleDB — dauerhafter Zustand für die Convex-Schicht und Plattform-Metadaten. | Schreiben abgelehnt; die platform-Zeile wird ebenfalls rot. | Jede Zeile trägt die letzten 90 Tage Uptime als Sparkline. Ein Incident liest sich als farbiges Band auf der Zeile; ein Klick aufs Band öffnet den Verlauf — erstes Update, Folge-Updates, Auflösung, Post-Mortem, wenn eines ansteht. ## Incident-Historie Die Historie wird unbefristet aufbewahrt. Jeder Incident hält die betroffenen Services fest, die Kundenwirkungs-Aussage, den Verlauf und das Post-Mortem, wenn der Incident die Schwere-Schwelle reisst, die eines verlangt. Die Schwelle steht auf der Seite selbst; die Faustregel ist alles mit Cross-Org-Kundenwirkung und einer Dauer über 30 Minuten. Die Seite gehört der Bereitschafts-Rotation. Updates werden vom Engineer geschoben, der die Seite hält, nicht von einem automatisierten System — die Wahl ist bewusst, weil die Seite auch das Dokument ist, das nach dem Vorfall zu Kunden und Auditoren geht. ## Self-hosted: was sich ändert Selbst gehostete Instanzen erscheinen nicht auf `status.tale.dev` — die Seite deckt Tale Cloud ab. Jedes Deployment bringt stattdessen seine eigene Status-Page mit, von der Plattform ausgeliefert und ohne Anmeldung erreichbar unter `https://<dein-host>/status`. Sie rendert serverseitig eine Gesundheits-Zusammenfassung — operational, degraded oder outage — aus einem Liveness-Probe gegen das Convex-Backend, sodass ein Betreiber (oder ein Endnutzer, der prüft, ob es nur bei ihm hakt) die Verfügbarkeit ohne Login lesen kann. Die maschinenlesbare Form ist `https://<dein-host>/status.json`, die dasselbe Ergebnis als JSON zurückgibt, das ein Uptime-Monitor pollen kann. Diese Seite meldet die Verfügbarkeit des Deployments selbst. Für tieferes Betriebssignal — Container-Gesundheit von `tale status`, Anfrage-Metriken aus den Caddy-Logs und Control-Plane-Events im In-Product-Audit-Log — bildet die [Observability-Troubleshooting-Seite](/de/self-hosted/operate/observability/troubleshooting) Symptome auf Logs ab. ## Wo das hingehört Die Status-Page ist der operative Kanal; [Vertrauen und Compliance](/de/cloud/trust-and-compliance) ist der Audit-Kanal und listet die Seite als Beleg für die Infrastruktur-Verfügbarkeits-Kontrolle. Wenn du Tale in eine Pipeline verdrahtest und die Connector auf einen Tale-Ausfall reagieren soll, ist der RSS-Feed der Eingang; wenn du das hier liest, weil gerade etwas in deiner Connector scheitert, listet die [API-Referenz](/de/develop/api-reference) die Error-Codes, auf die du verzweigen solltest. # Contributor-Setup Source: https://tale.dev/docs/de/develop/contributor-setup Diese Seite ist für Contributors, die Tale aus dem Quellcode laufen lassen und eine Änderung zurückgeben wollen. Sie deckt die Voraussetzungen ab, das einmalige Setup, den Pre-flight-Check, der eine kaputte Maschine vor einem langen Boot erkennt, und was du von `bun run dev` erwarten kannst. Es ist nicht der Operator-Weg — willst du Tale benutzen statt verändern, installiert der [Self-hosted Quickstart](/de/self-hosted/install/quickstart) stattdessen den paketierten Stack mit der CLI. Der Quellcode ist ein einziger Bun-Workspace, von Anfang bis Ende — der ganze Stack ist TypeScript, ohne Python und ohne einen zweiten Paketmanager zu installieren. Ein einziges `bun install` verdrahtet jeden Dienst, und `bun run dev` bootet die Plattform mit einem lokalen Convex-Backend, generierten Dev-Secrets und Vite — kein Cloud-Konto, keine von Hand editierte `.env`. Die Wissens-Arbeit, die früher in eigenständigen Diensten lebte (RAG-Suche, Dokument-Ingestion, Web-Crawling, Dokumentgenerierung), läuft jetzt im Convex-Backend, also gibt es dafür nichts Zusätzliches zu starten. ## Ein funktionierendes Setup von Anfang bis Ende Der kürzeste Weg von einem frischen Klon zu einer laufenden App sind vier Befehle. Der Pre-flight-Check zwischen Install und Dev ist der, der dir ein verwirrendes Scheitern zehn Schichten tief erspart: ```bash bun install # jeden Workspace verdrahten bun run setup:check # Bun, die Dev-Ports und die Convex-CLI prüfen bun run dev # Convex + Vite booten (achte auf das READY-Banner) ``` Wenn `setup:check` durchweg grün ausgibt und `bun run dev` sein `READY`-Banner erreicht, ist deine Umgebung in Ordnung. Der Rest dieser Seite erklärt jedes Teil und was zu tun ist, wenn eines davon meckert. ## Voraussetzungen Nur ein Tool muss auf deinem `PATH` liegen, bevor irgendetwas anderes passiert, denn der ganze Stack ist TypeScript auf einer einzigen Laufzeit: - **Bun 1.3 oder höher** — die Workspace-Laufzeit und der Paketmanager. Installier es von [bun.sh](https://bun.sh/docs/installation) und bestätige mit `bun --version`. Alles andere, was der Quellcode braucht (die Convex-CLI, jede Dienst-Abhängigkeit), löst `bun install` auf. Für die lokale Entwicklung mit `bun run dev` brauchst du kein Docker — es spawnt Convex direkt auf deiner Maschine. Docker kommt nur für den containerisierten Hybrid-Modus weiter unten und für die Operator-Installation ins Spiel. ## Installation und Pre-flight Ein einziges Install deckt jeden Workspace ab, denn das Repo ist ein Bun-Workspace-Graph: ```bash bun install ``` Vor dem ersten `bun run dev` lauf den Pre-flight-Check. Er prüft deine Bun-Version, dass die Ports 3000 und 3210 frei sind und dass die Convex-CLI erreichbar ist — und gibt für alles Fehlende die exakte Korrektur aus, sodass du keine falsche Bun-Version mitten in einem Cold-Boot entdeckst: ```bash bun run setup:check ``` Jede fehlschlagende Zeile trägt ihre Korrektur: ein `bun upgrade` für ein altes Bun, ein `lsof`/`kill`-Paar für einen belegten Port. Ein sauberer Lauf endet mit Null und sagt dir, dass du mit `bun run dev` weitermachen kannst. ## Was `bun run dev` tut `bun run dev` ist der Entwicklungs-Orchestrator. Er lädt deine `.env`-Dateien, generiert unsichere lokale Defaults für jedes Secret, das du nicht gesetzt hast, spawnt ein lokales Convex-Backend im Anonymous-Modus, synct das Environment hinein, führt Convex-Codegen aus, wartet, bis die Auth-Routen antworten, und startet dann Vite. Die Plattform ist der langsamste Server beim Hochkommen, weil sie auf Convex wartet, also dauert ein Cold-Start 30 bis 90 Sekunden. Bis der Orchestrator sein `READY`-Banner ausgibt, ist es erwartet und kein Fehler, dass die App auf `http://localhost:3000` Verbindungen ablehnt — Vite hat den Port noch nicht gebunden. Siehst du das Banner, ist die App erreichbar und die Auth gesund. Stopp den ganzen Stack mit `Ctrl-C`; er fährt sowohl Convex als auch Vite sauber herunter. Der Dev-Orchestrator generiert alles, was er braucht, also ist eine lokale Kopie von `.env.example` für die lokale Entwicklung optional — die unsicheren Defaults (`INSTANCE_SECRET`, `BETTER_AUTH_SECRET`, der WebDAV-HMAC-Key) werden beim Boot gefüllt und als Warnungen ausgegeben. Setz echte Werte in `services/platform/.env.local` nur, wenn du produktionsförmiges Verhalten brauchst oder einen Default überschreiben willst. ## Wenn ein Port belegt ist `bun run dev` bindet zwei Ports: 3000 für die Vite-App und 3210 für das lokale Convex-Backend. Es scheitert sofort mit einer umsetzbaren Meldung, wenn einer belegt ist, denn ein stiller Fallback auf einen anderen Port würde den Convex-Proxy und jeden `localhost:3000`-Link brechen. Der übliche Verursacher ist ein vorheriges `bun run dev` oder `tale dev`, das nicht vollständig beendet wurde. Gib den Port frei und lauf erneut. Der Befehl, der den Halter findet und stoppt, ist derselbe, den `setup:check` und der Orchestrator vorschlagen: ```bash lsof -nP -iTCP:3000 -sTCP:LISTEN # die PID zeigen, die den App-Port hält kill <PID> # sie stoppen ``` Um die App stattdessen auf einem anderen Port laufen zu lassen, setz `PORT`: `PORT=3005 bun run dev`. Gerät das Convex-Deployment nach der automatischen Wartung in einen schlechten Zustand — veraltetes Schema nach abgebrochener Migration, korrupte lokale SQLite-Datei — siehe [Lokale Convex-Dev-Daten zurücksetzen](#lokale-convex-dev-daten-zurücksetzen) unten; lösch `.convex/local/` nicht beiläufig. ## Wartung des lokalen Convex-Speichers Jeder `convex dev`-Push legt ein neues Function-Bundle unter `services/platform/.convex/local/default/convex_local_storage/modules/` ab. Die Convex-CLI räumt alte Blobs lokal nie auf — nach Monaten täglicher Entwicklung können Zehntausende Dateien (10+ GB) entstehen, und Cold Starts scheitern im 30-Sekunden-Fenster der CLI. `bun run dev` führt Wartung automatisch aus, bevor Convex startet: - **Prune**, wenn der Modul-Speicher 1.500 Blobs oder 2 GB überschreitet — löscht nur unreferenzierte historische Function-Bundle-Blobs unter `convex_local_storage/modules/` und behält jedes Blob, das das aktuelle Deployment noch lädt (Modul-Source-Packages und ihre Node-`externalPackageId`-Deps-Parents, plus bis zu 1.000 neueste unreferenzierte Reste). SQLite-Datenbank, Uploads und Org-Konfig bleiben unberührt. Lassen sich die Live-Referenzen nicht lesen, oder wirken sie leer obwohl noch Blobs auf der Platte liegen, wird der Prune übersprungen statt zu raten. - **Integritätsprüfung** — fehlt ein Live-Modul-Blob schon auf der Platte, stoppt `bun run dev` mit einem klaren Fehler und verweist auf `setup:clean`. Weitermachen würde ein halb totes Backend starten (Chat und Crons scheitern mit undurchsichtigen Serverfehlern). - **Snapshot-Export-Artefakte löschen**, wenn die gecachte Convex-Backend-Version nicht mehr zur lokalen Deployment-Konfiguration passt — entfernt `export.zip` und Import/Export-Reste, die einen fehlgeschlagenen Re-Import auslösen können, ohne Dev-Daten zu löschen. Setz `TALE_DEV_SKIP_CONVEX_MAINTENANCE=1`, um Prune/Snapshot-Cleanup zu deaktivieren (die Integritätsprüfung läuft weiter). `bun run setup:check` warnt (nicht blockierend), wenn der Modul-Speicher den Prune-Schwellenwert schon überschreitet. ## Lokale Convex-Dev-Daten zurücksetzen Nur als letzter Ausweg — `bun run setup:clean` löscht **alle** lokalen Convex-Dev-Daten: jede Tabelle in der lokalen SQLite-Datei, jeden Upload in `convex_local_storage/files/` und jedes Function-Bundle. Org-Konfig auf der Platte und `.env.local` bleiben unberührt. **Über die 0.4-Baseline wechseln:** Lokale Dev-Daten und Per-Org-Konfigbäume aus Prä-0.4-Checkouts haben keinen Migrationspfad — der 0.4-Baseline-Reset hat die Migrations-Historie geleert, und auch der Export/Import-Roundtrip unten überbrückt das nicht (der alte Export passt nicht zum neuen Schema). Eine Dev-Maschine über die Baseline zu bewegen heißt: lokale Convex-Daten zurücksetzen und die Dev-Orgs neu anlegen; behandle Prä-0.4-Org-Verzeichnisse unter `$TALE_CONFIG_DIR` genauso. **Behalte deine Daten über den Reset hinweg.** Selbst wenn das Integritäts-Gate anschlägt (ein Bundle eines Live-Moduls fehlt), startet das Backend selbst noch — du kannst deine Daten also vorher exportieren und danach wiederherstellen, und der Reset verliert nichts: ```bash # 1. Backend starten (umgeht das Integritäts-Gate von `bun run dev`), dann # in einem zweiten Terminal exportieren: bun run --filter @tale/platform convex:dev cd services/platform && npx convex export --path convex-backup.zip # 2. Zurücksetzen (abgesichert — siehe unten), frisches Deployment # bootstrappen, dann wiederherstellen: bun run setup:clean # tippe: delete local convex bun run dev # auf das READY-Banner warten cd services/platform && npx convex import --replace-all convex-backup.zip ``` `bun run setup:clean` ist absichtlich abgesichert (Coding-Agenten dürfen es nicht laufen lassen, es sei denn, du hast ausdrücklich darum gebeten): 1. Selbst im Terminal ausführen — nicht über einen Agenten. 2. Beim Prompt die exakte Phrase `delete local convex` tippen (ein bloßes `y` wird abgelehnt). 3. Nicht-interaktive Läufe (CI) brauchen `TALE_CONFIRM_DESTROY_LOCAL_CONVEX=delete-local-convex` — in Agent-Shells nie setzen. Probier zuerst automatische Wartung und normales `bun run dev`. Musst du doch zurücksetzen, **exportiere vorher** (siehe oben), um deine Daten zu behalten — lass den Export nur weg, wenn du die lokalen Conversations, Uploads und den übrigen Anonymous-Deployment-Zustand wirklich nicht brauchst. ## Hybrid-Modus gegen ein containerisiertes Convex `bun run dev` spawnt standardmäßig ein ephemeres Convex-Backend, was für die meiste Arbeit das Richtige ist. Willst du schnelle Vite-Reloads gegen ein stabiles Convex, das Produktion spiegelt, fahr den dedizierten `convex`-Container und richte Vite stattdessen auf ihn: ```bash docker compose up convex # ein Terminal: das stabile Backend CONVEX_EXTERNAL=true bun run dev # ein anderes: Vite gegen den Container ``` Setz `CONVEX_URL`, wenn dein Container Convex auf einem Nicht-Standard-Host oder -Port bereitstellt. Das ist der einzige lokale Dev-Weg, der Docker braucht, und er ist optional — das ephemere Default-Backend braucht nichts außer den drei Voraussetzungen. ## Bevor du einen PR öffnest Jeder PR läuft durch ein Gate: `bun run check`, also Format, Lint, Typecheck und die volle Testsuite über jeden berührten Workspace. Ein grüner Lauf ist das Merge-Signal; ein roter blockiert. Die Pre-PR-Checkliste in [`AGENTS.md`](https://github.com/tale-project/tale/blob/main/AGENTS.md) listet den Rest — Docs und Übersetzungen kommen im selben PR wie der Code, der sie geändert hat. Berührt deine Änderung `services/docs/`, lauf auch das Docs-Gate (`bun run --filter @tale/docs test`), damit strukturelle Parität, Terminologie und Prosa-Checks vor dem Review passen. Alles, was ein Nutzer sehen, konfigurieren oder aufrufen kann, braucht seine Docs in allen drei Basis-Locales im selben Commit aktualisiert. ## Wo das hingehört Contributor-Setup ist der Boden, auf dem jede andere Entwickler-Aufgabe steht: bring die Voraussetzungen an ihren Platz, lass `setup:check` die Maschine bestätigen, und `bun run dev` gibt dir die ganze Plattform mit einem lokalen Backend in unter zwei Minuten, sobald die Images warm sind. Der Pre-flight-Check und die Port-Korrektur existieren, weil die häufigsten First-Run-Fehler eine falsche Tool-Version oder ein zurückgebliebener Prozess sind, der einen Port hält — beides Fünf-Sekunden-Korrekturen, sobald du sie sehen kannst. Läuft der Stack erst, rahmt die [Develop-Übersicht](/de/develop/overview) die externe Oberfläche, gegen die du baust, und [KI-gestützte Entwicklung](/de/develop/ai-assisted-development) deckt das Nutzen von Tales eigenen Agents zum Schreiben von Tale-Konfigurationen ab. Trägst du eine Container-Änderung statt einer Quellcode-Änderung bei, ist [Mitwirken](/de/self-hosted/contributing-docker) unter dem Reiter Selbst gehostet der Build-and-Test-Spaziergang für diesen Weg. # Webhooks Source: https://tale.dev/docs/de/develop/webhooks Ein Webhook-Trigger macht aus einem POST deines Systems einen Lauf einer deployten Automatisierung — kein API-Schlüssel, kein SDK, nur eine URL, die Tale beim Binden des Triggers erzeugt. Das ist die richtige Naht, wenn der Aufrufer ein Drittprodukt ist — ein Zahlungsanbieter, ein Formular-Tool, ein CI-Job — das nur einen HTTP-Request an eine URL feuern kann, die du ihm gibst. Lies das, wenn du ein externes System verdrahtest, das Automatisierungen starten soll. Für Aufrufe, bei denen du einen Wert zurückwillst oder einen API-Schlüssel hast, ist die [API-Referenz](/de/develop/api-reference) die synchrone Hälfte. ## Ein Trigger, durchgespielt Binde einen Webhook-Trigger an eine Automatisierung — im Editor der Automatisierung oder mit `PUT /api/v1/automations/{name}/triggers` und `{"kind": "webhook"}` — und Tale antwortet einmalig mit dem Token der Trigger-URL. Danach kann jedes System einen Lauf starten: ```bash curl -sS -X POST "https://your-host.example.com/api/automations/webhook/<token>" \ -H "Content-Type: application/json" \ -d '{ "orderId": "12345", "amount": 199.0 }' # → 202 { "runId": "..." } ``` Der Body wird zum Input des Laufs. Ein Body, der kein JSON ist, wird als Text durchgereicht statt abgewiesen — manche Anbieter senden reinen Text — und alles über 256 KB wird mit **413** abgelehnt. Polle den Lauf wie jeden anderen über `GET /api/v1/runs/{runId}` mit einem API-Schlüssel, oder schau ihm im Produkt zu. Das vollständige Antwortvokabular: - **202** `{ "runId": "..." }` — der Lauf ist gestartet. - **404** — unbekanntes, deaktiviertes oder vertipptes Token. Die Antwort unterscheidet die Fälle nie — wer rät, lernt nichts. - **409** `{ "error": "automation has no deployed version" }` — deploye eine Version, deren Tests bestehen, und derselbe Aufruf läuft. - **413** — der Body übersteigt 256 KB. ## Das Token ist die Berechtigung Es gibt keine Signatur und keinen Authorization-Header: das Token in der URL ist die ganze Berechtigung — behandle die URL wie ein Passwort. Tale speichert nur einen Hash und vergleicht in konstanter Zeit; der Klartext existiert genau einmal, in der Antwort, die ihn erzeugt hat. URL verloren oder geleakt? Rotiere sie — `PUT /api/v1/automations/{name}/triggers` mit `{"kind": "webhook", "rotateToken": true}` erzeugt ein frisches Token und antwortet es einmalig; die alte URL stirbt sofort. Das Lösen des Triggers (`DELETE .../triggers` oder im Editor) widerruft sie ganz; die Versionen und die Laufhistorie der Automatisierung bleiben. ## Idempotenz und Wiederholungen Der Trigger-Endpoint dedupliziert nicht: ein wiederholter POST startet einen zweiten Lauf. Sicher machen Wiederholungen der Lauf selbst — ein Live-Lauf checkpointet jeden abgeschlossenen Knoten, ein nach einer Unterbrechung fortgesetzter Lauf wiederholt also nie einen Effekt, den er schon erzeugt hat. Wo ein _doppelter Lauf_ trotzdem falsch wäre, gib deinen eigenen Deduplizierungs-Schlüssel im Payload mit und verzweige darauf im ersten Knoten der Automatisierung. Wiederholen ist Sache des Aufrufers: die Antwort sagt dir, ob der Lauf _gestartet_ ist, nicht ob er gelungen ist. Ein vernünftiger Aufrufer wiederholt Nicht-2xx-Antworten mit Backoff und behandelt 202 als erledigt. ## Wo das hingehört Der Webhook ist der Weg hinein ohne Schlüssel; alles andere läuft über einen API-Schlüssel. Die [Trigger-Seite](/de/platform/automations/triggers) behandelt die Produktseite — Zeitpläne, Events und Webhooks, wie der Automatisierungs-Editor sie zeigt. Die [API-Referenz](/de/develop/api-reference) behandelt das Starten von Läufen mit Schlüssel (`POST /api/v1/automations/{name}/runs`) — die bessere Naht, wenn der Aufrufer dein eigener Code ist. # Rate-Limits Source: https://tale.dev/docs/de/develop/rate-limits Die API ist pro Schlüssel mit Token-Buckets limitiert: Bursts gehen durch, Dauerfeuer antwortet **429**. Die Budgets sind so bemessen, dass eine normale Connector sie nie sieht — wenn ein bisher gesunder Client 429 zu treffen beginnt, fehlt fast immer ein Backoff oder eine Schleife läuft heiß, nicht die Kapazität. Lies das, wenn du einen Client verdrahtest, der die API nach Zeitplan oder unter Last aufruft. ## Die Buckets | Oberfläche | Budget | Burst | | --------------------------------------------------------------------------------------------------- | ------------------- | ----- | | Lesen und CRUD — jeder `/api/v1`-Endpoint, der unten nicht steht, einschließlich `POST /api/v1/mcp` | 120 Anfragen / Min. | 200 | | Arbeit starten — `POST /api/v1/automations/{name}/runs` und `POST /api/v1/threads/{id}/messages` | 20 Anfragen / Min. | 40 | Der zweite Bucket ist mit Absicht klein: jede dieser Anfragen kostet einen ganzen durablen Lauf oder einen Modell-Turn, keinen Datenbank-Read. Ein Token-Bucket füllt sich kontinuierlich — die Burst-Kapazität schluckt einen Stapel, danach gilt die Dauerrate. ## Die 429 Eine Überschreitung antwortet mit dem gewöhnlichen Fehlerumschlag der API — nichts zu parsen außer dem Status: ```json { "error": "Rate limit exceeded" } ``` Es gibt keine Rate-Limit-Header — kein `Retry-After`, keine Restbudget-Zähler. Backe blind zurück: starte bei einer Sekunde, verdopple pro aufeinanderfolgendem 429, deckle bei sechzig, und füge Jitter hinzu, damit parallele Worker nicht im Gleichschritt wiederholen. Weil ein Lauf-Start mit **202** antwortet, bevor die Arbeit passiert, ist eine verlorene Antwort billig zu erkennen — liste die letzten Läufe der Automatisierung, bevor du erneut feuerst, statt Schreibzugriffe auf Verdacht zu wiederholen. ## Wo das hingehört Die [API-Referenz](/de/develop/api-reference) nennt die 429 im Fehlermodell und zeigt hierher. Braucht dein Workload wirklich mehr, als die Budgets erlauben, bündle auf deiner Seite — `POST /api/v1/contacts/bulk` existiert genau dafür — oder strecke den Zeitplan; die Buckets gelten pro Schlüssel, zwei Schlüssel teilen sich also kein Budget. # Connectors Source: https://tale.dev/docs/de/develop/connectors Connectoren sind die anbieterspezifische Hälfte davon, wie Tale andere Systeme erreicht, und sie gehören zur Plattform statt zu etwas, das eine Organisation zusammenbaut. Jeder von ihnen ist eine YAML-Datei im Quellbaum und deklariert, mit wem er spricht, wie er sich anmeldet und jede Aktion, die er ausführen kann — daher sieht der Katalog in jedem Deployment gleich aus, und ein Upgrade genügt, um ihn weiterzubewegen. Lies das, wenn du wissen willst, was ein Connector einem Aufrufer tatsächlich zusichert, oder wenn du zwischen einem eigenen Beitrag und einem selbst betriebenen MCP-Server abwägst. Die Seite für Organisationen — Zugangsdaten anlegen, Standard setzen, eine abgelaufene Freigabe erneuern — ist [Zugangsdaten für Connectors](/de/platform/admin/connectors); der Katalog selbst steht unter [Connectors](/de/platform/connectors/overview). ## Wie ein Connector deklariert wird Jeder Connector ist ein Verzeichnis unter `configs/platform/system/connectors/`, benannt nach seinem Slug, mit einer `connector.yml` und dem Icon, das die Einstellungsseite rendert. Der Slug ist der Verzeichnisname, der deklarierte `name` des Connectors und die erste Hälfte des Node-Typs, mit dem eine Automation eine seiner Aktionen setzt — `<connector>.<action>`. Dreizehn dieser Verzeichnisse werden heute ausgeliefert. Die Datei beginnt mit der Identität des Connectors und seinem Authentifizierungs-Vertrag, danach folgen die Aktionen: ```yaml name: tavily displayName: Tavily description: Real-time web search and page extraction for AI research. tags: - Search allowedHosts: - api.tavily.com auth: - method: api-key actions: - name: search description: >- Search the open web via Tavily. Returns top results with title, URL, content snippet, and score. effects: read input: type: object required: [query] properties: query: { type: string, description: 'Natural-language search query.' } max_results: { type: number, description: 'Max results (1-10).' } output: '{ answer?: string, results: Array<{ title: string, url: string, content: string, score: number }> }' ``` `allowedHosts` ist die Egress-Grenze — ein Aktionsrumpf, der woanders hingreift, wird abgewiesen statt weitergeleitet. Ein Connector, dessen API bei der Kundschaft statt beim Anbieter liegt, ergänzt `endpointMode: per-credential`; jeder Eintrag trägt dann den Ursprung, aus dem seine Aufrufe gebaut werden. Confluence und Shopify sind die beiden ausgelieferten Fälle. <Info> Connectoren werden aus dem Baum der Plattform gelesen, nicht aus der Konfiguration einer Organisation, und es gibt keinen Upload-Weg, der zur Laufzeit einen hinzufügt. Einen Connector zu ergänzen ist ein Beitrag am Quellcode — siehe [Contributor-Setup](/de/develop/contributor-setup). Eine eigene Brücke ohne Eingriff in den Quellcode ist genau das, wofür MCP da ist. </Info> ## Was eine Aktion zusichert Eine Aktion ist ein Vertrag, und jedes Feld davon liegt offen, bevor der Aufruf passiert: - **Name und Beschreibung.** Der Name vervollständigt den Node-Typ; die Beschreibung ist das, was ein Agent liest, wenn er entscheidet, ob diese Aktion die richtige ist. - **Eingabe.** Ein JSON Schema — Objekttyp, Pflichtfelder und eine Beschreibung pro Property. Automationen prüfen die Konfiguration eines Nodes dagegen, und Agents füllen sie aus demselben Schema. - **Ausgabe.** Eine Signatur der Form, die zurückkommt, damit beim Bauen eines Workflows klar ist, worauf der nächste Schritt zugreifen kann. - **Effekte.** Entweder `read` oder `write`. Schreibende Aktionen laufen über die Genehmigungsrichtlinie der Organisation, und ein Aufruf, der keine Genehmigungsentscheidung erreicht, wird abgewiesen statt ungeprüft ausgeführt. Aktionen lösen ihre Zugangsdaten zum Aufrufzeitpunkt auf: den Eintrag, den der Aufrufer benennt, oder den Standard des Connectors, wenn er keinen benennt. Genau diese Naht lässt dieselbe Automation gegen ein anderes Konto laufen, sobald sie auf einen anderen Namen zeigt. Mail-Sync und Posteingangs-Sichtung weichen davon absichtlich ab: `conversation.sync_mailbox` und `conversation.list_mailbox_messages` laufen über jeden aktiven Eintrag des Connectors, damit jedes verbundene Postfach dran ist, ohne dass eine Automation sie einzeln benennen muss. ## Die Authentifizierungsmethoden Ein Connector deklariert die Methoden, die er akzeptiert, und ein Eintrag liegt an genau einer davon. Die vier stehen fest, weil jede einen anderen Weg beschreibt, auf dem ein Secret den Anbieter erreicht. | Methode | Bezeichnung in der Oberfläche | Was der Eintrag hält | | --------- | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | `api-key` | API-Schlüssel | Ein einzelnes Secret, das der Aktionsrumpf selbst platziert — ein Anbieter-Header, ein Query-Parameter oder ein Body-Feld. | | `bearer` | Token | Ein Token, gesendet als Authorization-Header unter dem Schema, das der Connector nennt. | | `basic` | Benutzername & Passwort | Benutzername und Passwort als HTTP Basic — dieselbe Form, die auch ein Postfach-Login annimmt. | | `oauth2` | OAuth | Ein Authorization-Code-Grant: Access Token, Refresh Token, Ablauf und die erteilten Scopes. | Secrets liegen verschlüsselt in einem einzigen Umschlag und wandern nie an einen Aufrufer zurück. Eine Auflistung zeigt eine maskierte Vorschau, die beim Schreiben des Eintrags berechnet wurde — das Lesen der Liste berührt den Geheimtext also nie. ## Eine OAuth-App registrieren Ein `oauth2`-Connector deklariert die Authorize- und Token-URLs des Anbieters sowie die Scopes, die er anfragt; das Deployment stellt die App bereit, gegen die sich diese URLs authentifizieren. Registriere beim Anbieter genau diesen Callback als erlaubte Redirect-URI, gebaut aus `SITE_URL` und einem etwaigen `BASE_PATH`-Präfix des Deployments: ```text ${SITE_URL}${BASE_PATH}/api/connectors/oauth2/callback ``` Client-ID und Secret kommen pro Connector aus der Umgebung des Deployments, benannt als `CONNECTOR_OAUTH_<SLUG>_CLIENT_ID` und `CONNECTOR_OAUTH_<SLUG>_CLIENT_SECRET`, mit großgeschriebenem Slug und Bindestrichen als Unterstriche. Ist `SITE_URL` nicht gesetzt, verweigert der Freigabe-Flow den Start, statt einen Ursprung aus der Anfrage zu raten. <Warning> Die Redirect-URI muss Byte für Byte übereinstimmen — Schema, Host, Pfad und kein abschließender Schrägstrich. Eine Abweichung scheitert schon am Freigabe-Dialog des Anbieters mit einem `redirect_uri`-Fehler, bevor Tale den Callback überhaupt sieht; das ist der mit Abstand häufigste Grund, warum ein frischer OAuth-Connector nicht verbindet. </Warning> ## Die passende Oberfläche wählen Zwei Oberflächen erreichen Systeme außerhalb von Tale, und die Wahl dreht sich darum, wem die Brücke gehört und wer sie betreibt. | Oberfläche | Greif dazu, wenn | | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Mitgelieferter Connector | Für das Zielsystem gibt es bereits einen. Deine Arbeit sind die Zugangsdaten, der Anbieter-Vertrag wird für dich gepflegt. | | MCP-Server | Nichts Mitgeliefertes deckt das System ab — eine interne API, ein selbstgebautes Tool, ein Host, den nur dein Netz erreicht. Du schreibst und betreibst den Prozess. | Ein MCP-Server wird unter **Einstellungen > API > MCP** registriert, und jedes Tool, das er freilegt, reiht sich neben den Connector-Aktionen in den Werkzeugkasten des Agents ein, jeweils mit eigenem Genehmigungs-Kennzeichen. Die Referenz ist [MCP-Server](/de/platform/connectors/mcp-servers); den Bau von Anfang bis Ende zeigt [MCP-Server von Grund auf](/de/tutorials/developer/mcp-server-from-scratch). ## Wo das hingehört Ein Connector ist ein deklarierter Vertrag — Hosts, Authentifizierung und eine typisierte Aktionsliste — der mit der Plattform kommt und aus Zugangsdaten gespeist wird, die der Organisation gehören. Lies [Connectors](/de/platform/connectors/overview) für das, was im Katalog steht, [Zugangsdaten für Connectors](/de/platform/admin/connectors) für den täglichen Umgang mit diesen Einträgen, und [MCP-Server](/de/platform/connectors/mcp-servers), wenn die Brücke, die du brauchst, dein eigener Code sein muss. </content> </invoke> # API-Referenz Source: https://tale.dev/docs/de/develop/api-reference Die Tale-API ist die Oberfläche für alle, die außerhalb des Produkts stehen und es skripten wollen: Wissensressourcen, Automatisierungen und ihre Läufe, Chat-Threads, Agenten und Skills — alles als JSON über HTTPS, mit einem API-Schlüssel im Header. Derselbe Schlüssel öffnet auch den [MCP-Endpoint](/de/develop/mcp-endpoint) — diese Seite behandelt die REST-Hälfte. Diese Seite ist das kanonische Inventar der Oberfläche, des Auth-Modells und der Fehlerform. Request- und Response-Schemas auf Feldebene liefert das OpenAPI-Dokument deiner Instanz unter `/docs` — lade es dort, wenn du jede Property brauchst; lies diese Seite, um zu verstehen, wie sich die API verhält. ## Eine erste Anfrage Die kürzeste nützliche Anfrage — die Automatisierungen der Organisation auflisten — ist ein curl: ```bash curl -sS "https://your-host.example.com/api/v1/automations" \ -H "Authorization: Bearer $TALE_API_KEY" ``` Eine erfolgreiche Antwort ist eine Seite: `{ "page": [ { "name": "billing/dunning", "latest": 3, "deployedVersion": 2 } ], "isDone": true, "continueCursor": null }`. Jeder Listen-Endpoint antwortet mit genau diesem Umschlag — gib `continueCursor` als `?cursor=` zurück, um die nächste Seite zu holen, und begrenze die Seitengröße mit `?limit=`. ## Authentifizierung API-Schlüssel erzeugt jeder mit Admin- oder Entwickler-Berechtigungen im Produkt — [API-Schlüssel](/de/platform/admin/api-keys) beschreibt das Panel. Ein Schlüssel wird bei der Erstellung genau einmal gezeigt und nie wieder; er gehört dem Benutzer, der ihn erzeugt hat, und dessen Organisation. Übergib den Schlüssel als Bearer-Token: `Authorization: Bearer <key>`. Der Organisationskontext kommt aus dem Schlüssel — außerhalb seiner Organisation ist er unbrauchbar, und alles, was er berührt, bleibt dort. Was der Schlüssel _tun darf_, folgt der Rolle seines Besitzers: Lesen und Mock-Läufe brauchen Mitgliedschaft; Live-Arbeit starten und Deploytes verändern braucht die Entwickler-Fähigkeit. Wo das zählt, sagen es die Abschnitte unten. ## Endpoint-Gruppen | Gruppe | Pfad | Was sie abdeckt | | ----------------- | --------------------------------------- | -------------------------------------------------------------------------------------------- | | Automatisierungen | `/api/v1/automations/...` | Auflisten, Versionen lesen, Läufe starten, Laufhistorie lesen, Trigger binden und lösen. | | Läufe | `/api/v1/runs/{runId}` | Ein durabler Lauf in voller Tiefe — Status, Output, Trace, Effekte — plus `POST .../cancel`. | | Threads | `/api/v1/threads/...` | Die Chat-Threads des Schlüsselbesitzers: erstellen, Nachrichten lesen, senden, Turn pollen. | | Agenten | `/api/v1/agents/...` | Agenten der Organisation auflisten, lesen, anlegen oder ersetzen, löschen. | | Skills | `/api/v1/skills/...` | Dieselbe Form wie Agenten, für Skills. | | Wissenseinträge | `/api/v1/knowledge-entries/...` | Themen-Fakten: auflisten, anlegen, ablösen, löschen. | | Wissenssuche | `POST /api/v1/knowledge/search` | Semantische Suche über das indexierte Wissen der Organisation. | | Dokumente | `/api/v1/documents/...` | Dokumente der Wissensdatenbank: CRUD plus `POST .../retry-indexing`. | | Websites | `/api/v1/websites/...` | Gecrawlte Quellen: CRUD plus `.../pages`, `.../sync`, `.../search`. | | Produkte | `/api/v1/products/...` | Produktkatalog-Einträge: CRUD. | | Kontakte | `/api/v1/contacts/...` | Kontaktdaten: CRUD plus `POST /api/v1/contacts/bulk`. | | MCP | `POST /api/v1/mcp` | Der [MCP-Endpoint](/de/develop/mcp-endpoint) — derselbe Schlüssel, JSON-RPC statt REST. | | Webhook-Trigger | `POST /api/automations/webhook/<token>` | Eine deployte Automatisierung von außen starten; die [Webhooks-Seite](/de/develop/webhooks). | ## Automatisierungsnamen in URLs Der Name einer Automatisierung ist ein `/`-Pfad — `billing/dunning` — und ein Pfad passt nicht in ein einzelnes URL-Segment. Schreib den Namen in jeder `/api/v1/automations/{name}/...`-URL mit `__` an Stelle jedes `/`: ```bash curl -sS "https://your-host.example.com/api/v1/automations/billing__dunning/runs" \ -H "Authorization: Bearer $TALE_API_KEY" ``` Antworten tragen immer den echten Namen (`"name": "billing/dunning"`); die `__`-Form existiert nur in URLs. Agent- und Skill-Slugs sind flach und brauchen keine Kodierung. ## Einen Lauf starten, dann pollen Ein Lauf ist durabel und darf Minuten dauern — der Start antwortet deshalb mit **202** und der Identität des Laufs, nicht mit seinem Ergebnis: ```bash curl -sS -X POST "https://your-host.example.com/api/v1/automations/billing__dunning/runs" \ -H "Authorization: Bearer $TALE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": { "customerId": "cus_123" } }' # → 202 { "runId": "...", "version": 2, "name": "billing/dunning", "mode": "live" } ``` Polle `GET /api/v1/runs/{runId}`, bis `status` `queued`/`running`/`waiting` verlässt; der fertige Lauf trägt `output`, den `trace` pro Knoten und die `effects`, die er erzeugt hat. `POST /api/v1/runs/{runId}/cancel` stoppt einen Lauf an seiner nächsten Knotengrenze — was ein Knoten schon getan hat, wird nicht rückgängig gemacht. `mode` ist standardmäßig `live`. Ein Live-Lauf handelt im Namen der Organisation und braucht deshalb einen Schlüssel, dessen Besitzer die Entwickler-Fähigkeit hat; `{"mode": "mock"}` läuft gegen deterministische Mocks und braucht nur Mitgliedschaft. Ein Start braucht keinen Trigger — der API-Schlüssel ist die Berechtigung. Eine Automatisierung ohne deployte Version antwortet **409**; deploye eine Version, deren Tests bestehen, und derselbe Aufruf geht durch. `projectId` benennt das Projekt, in dem der Lauf arbeitet — das Projekt, auf das seine Aufgaben- und Dokument-Tools wirken. Lässt du es weg, ist der Lauf organisationsweit — außer eine an ein einzelnes Projekt gebundene Automatisierung läuft automatisch in diesem einen; eine an mehrere gebundene akzeptiert nur eine `projectId` aus dieser Menge und weist jede andere ab. ## Eine Nachricht senden, dann den Turn pollen Chat hat dieselbe 202-dann-pollen-Form. Erstelle einen Thread, sende eine Nachricht, polle die Generierung, lies dann die Nachrichten: ```bash # 1. Ein eigener Thread curl -sS -X POST "https://your-host.example.com/api/v1/threads" \ -H "Authorization: Bearer $TALE_API_KEY" \ -H "Content-Type: application/json" -d '{}' # → 201 { "id": "<threadId>" } # 2. Nachricht senden — auf dieser API ist das Modell immer explizit, nie automatisch gewählt curl -sS -X POST "https://your-host.example.com/api/v1/threads/<threadId>/messages" \ -H "Authorization: Bearer $TALE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "content": "Fasse mir dieses Quartal zusammen.", "model": "<ein Modell deiner Organisation>" }' # → 202 { "threadId": "...", "status": "accepted", "model": "...", "poll": "/api/v1/threads/<threadId>/generation" } # 3. Bis idle pollen, dann lesen curl -sS "https://your-host.example.com/api/v1/threads/<threadId>/generation" \ -H "Authorization: Bearer $TALE_API_KEY" # → 200 { "status": "streaming" } … dann { "status": "idle" } ``` `{"status": "idle"}` heißt: kein Turn läuft — lies `GET /api/v1/threads/{id}/messages` für die Antwort. Ein Turn, der vor jeder Ausgabe scheitert, taucht trotzdem auf: der Fehler landet als Assistenten-Nachricht, nie lautlos. Über die API gelistete und gelesene Threads sind die des Schlüsselbesitzers; die Threads anderer Benutzer bleiben für deinen Schlüssel unsichtbar, auch innerhalb derselben Organisation. ## Fehlermodell Jede Nicht-2xx-Antwort trägt einen flachen Umschlag: ```json { "error": "Automation not found" } ``` Verzweige auf den HTTP-Status; die Meldung ist für Menschen: - **400** — fehlerhafte Anfrage: fehlendes Pflichtfeld, falscher Typ, nicht parsebarer Body. - **401** — fehlender oder ungültiger API-Schlüssel. - **403** — der Schlüssel ist gültig, aber der Rolle seines Besitzers fehlt die Fähigkeit (Live-Läufe, Trigger-Schreiben, Abbrechen). - **404** — die Ressource existiert nicht in deiner Organisation oder gehört zum Thread eines anderen. - **409** — der Zustand verweigert die Aktion: keine deployte Version, ein doppeltes Thema oder eine doppelte E-Mail, ein bereits laufender Turn. - **413** — der Body ist zu groß (der Webhook-Trigger deckelt bei 256 KB). - **429** — Rate-Limit erreicht; siehe [Rate-Limits](/de/develop/rate-limits). - **500** — interner Fehler. Zwei Lösch-Semantiken existieren, mit Absicht. Das Lösen eines Automatisierungs-Triggers (`DELETE .../triggers`) antwortet **204**, ob ein Trigger existierte oder nicht — ein idempotentes „stell es so her“. Das Löschen einer Ressource (`DELETE /api/v1/agents/{slug}`) antwortet **404**, wenn nichts da war — du wolltest etwas entfernen, das es nicht gibt. ## Versionierung Die API ist über das URL-Präfix versioniert — heute `/api/v1/` — und wächst darin additiv: neue Endpoints und neue optionale Felder kommen dazu, bestehende Formen bleiben. Ein Breaking Change würde unter einem neuen Präfix erscheinen. Das OpenAPI-Dokument unter `/docs` beschreibt immer die laufende Instanz. ## Wo das hingehört Diese Seite ist die REST-Hälfte der Außenfläche. Der [MCP-Endpoint](/de/develop/mcp-endpoint) öffnet dieselbe Plattform für MCP-Clients — das Autorieren von Automatisierungen lebt dort, nicht in REST. Die [Webhooks-Seite](/de/develop/webhooks) behandelt den eingehenden Trigger, der Läufe ohne Schlüssel startet. Baust du innerhalb des Produkts — Agenten, Automatisierungen, eigene Tools — ist der [Platform-Tab](/de/platform) dein Alltag; diese Seite ist für draußen. # AI-gestützte Entwicklung Source: https://tale.dev/docs/de/develop/ai-assisted-development Tale-Projekte sind JSON — Agents, Workflows, Connectors, Branding — und JSON lässt sich in AI-Editoren gut bearbeiten, wenn der Editor das Schema kennt. Die CLI legt dafür zwei Dinge an: eine Rules-Datei, die jeder Editor im Projekt-Root liest (`CLAUDE.md` für Claude Code, `.cursor/rules/tale.mdc` für Cursor, `.github/copilot-instructions.md` für Copilot, `.windsurfrules` für Windsurf), und einen schreibgeschützten Schema-Spiegel unter `.tale/reference/`, auf den die Rules-Datei den Editor verweist. Lies das, wenn du ein Tale-Projekt im AI-Editor bearbeiten willst, ohne JSON von Hand zu tippen. Komm zurück, wenn der Editor Felder erfindet oder die falsche Agent-Form verdrahtet — die Antwort ist fast immer, dass das Schema unter `.tale/reference/` veraltet ist. ## Ein durchgespieltes Setup Initialisier ein Projekt — die CLI schreibt die Rules-Datei und den Schema-Spiegel im selben Schritt: ```bash tale init my-org cd my-org ls -a # .cursor/ .github/ .tale/ .windsurfrules # CLAUDE.md agents/ workflows/ connectors/ branding/ ``` `CLAUDE.md` (gleichzeitig installiert als Cursor-`.mdc`, Copilot-`.md` und Windsurf-Rules) sagt dem Editor, wo er nachschlagen soll, bevor er eine Config bearbeitet: > Before creating or editing any config, read the relevant schemas and implementation code in `.tale/reference/` to understand the valid structure, fields, and constraints. Use existing config files in the project as examples. Die Direktive zählt, weil jeder Editor unter Last Schema-Reads überspringt, sofern nicht anders gesagt. Die Rules-Datei ist der Vertrag; der Schema-Spiegel ist die Wahrheit am Boden. ## Was wo liegt | Pfad | Was es ist | | -------------------------------- | ----------------------------------------------------------------------------------- | | `agents/` | Eine JSON-Datei pro Agent — Anweisungen, Wissen, Tools, Modell. | | `workflows/` | Workflow-JSON-Configs, gruppiert nach Kategorie-Unterverzeichnis. | | `connectors/<slug>/config.json` | Connector-Manifest — Operations, Auth-Methode, erlaubte Hosts. | | `connectors/<slug>/connector.ts` | Optionaler TypeScript-Connector für REST-Formen, die das Manifest nicht abdeckt. | | `branding/branding.json` | Org-Branding — Farben, Logos, E-Mail-Absender. | | `.tale/reference/` | Schreibgeschützter Schema-Spiegel; neu erzeugt durch `tale init` und `tale update`. | Der Reference-Baum ist byte-identisch zu den Schemas, gegen die die Plattform beim Deploy validiert. Behandle ihn als kanonisch: wenn ein Feldname in einer handgeschriebenen Config dem Reference widerspricht, gewinnt das Reference. ## Arbeiten mit dem Editor Die Rules-Datei nennt drei Regeln, die jeder Editor beim Bearbeiten durchsetzt: - **Agents binden, delegieren, hängen an.** Ein Agent kann gleichzeitig Connectors binden (`connectorBindings`), an andere Agents delegieren (`delegates`) und Workflows anhängen (`workflows`). Lies bestehende Configs, bevor du eine neue Bindung einführst. - **Workflows nutzen Connector-Operations.** Ein Workflow-Schritt referenziert Connector-Operations, die in `connectors/<slug>/config.json` deklariert sind. Ein Schritt gegen eine nicht-existente Operation zu bearbeiten, lässt die Validierung scheitern. - **Benennung ist erzwungen.** Agent-Dateinamen matchen `[a-z0-9][a-z0-9_-]*\.json`. Workflow-Step-Slugs matchen `[a-z0-9][a-z0-9_-]*`. Connector-Verzeichnisse sind kleingeschrieben alphanumerisch mit Bindestrichen oder Unterstrichen. Wenn der Editor eine Änderung vorschlägt, frag ihn, welche Datei in `.tale/reference/` er zugrunde gelegt hat. Wenn er das nicht kann, erzeug den Spiegel mit `tale update` neu und versuch es nochmal. ## Cursor: Config-Ebene vs. Runtime-Ebene Cursor taucht in Tale an zwei getrennten Stellen auf — verwechsle sie nicht. | Ebene | Was sie tut | Wo sie lebt | | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | | **Config** | Hilft Cursor (oder einem anderen AI-Editor), Tale-Projekt-JSON auf deinem Rechner zu bearbeiten | `.cursor/rules/tale.mdc`, `CLAUDE.md`, `.tale/reference/` — alles, was `tale init` schreibt | | **Runtime** | Führt die Cursor Agent CLI headless in einer isolierten Sandbox aus, wenn ein Projekt-Agent oder Automation-Agent-Knoten das Harness **Cursor** nutzt | Projekt-Agent / Automation-Agent-Knoten mit **Harness** = Cursor | Rules-Datei und Schema-Spiegel auf dieser Seite sind die **Config-Ebene**: Sie steuern einen lokalen Editor, während du Agents, Workflows und Connectors änderst. Die **Runtime-Ebene** ist ein verwalteter Harness-Zug — `agent -p --output-format stream-json` mit deinem `CURSOR_API_KEY`, normalisierter Fortschritt im Chat und Session-Resume über Follow-ups. Credentials, Modelle und Abrechnung für Runtime-Turns stehen in [Harnesses](/de/platform/agents/harnesses), nicht hier. ## Wo das hingehört AI-gestützte Entwicklung ist der Bearbeitungspfad; Deployment ist der Veröffentlichungspfad. Sobald eine Config die Editor-Validierung passiert, gleicht [`tale deploy`](/de/self-hosted/install/cli-install) sie gegen die Plattform ab — derselbe Schema-Check, diesmal als Schranke. Für Features, die der Editor nicht erreicht (der In-Product-Builder, der visuelle Workflow-Editor), ist der [Platform-Reiter](/de/platform) die kanonische Oberfläche; der AI-Editor-Pfad hier ist für Projekte, die Config-as-Code bevorzugen. # MCP-Endpoint Source: https://tale.dev/docs/de/develop/mcp-endpoint Tale ist selbst ein MCP-Server. Richte einen beliebigen MCP-Client — ein Agent-Harness, eine IDE, deine eigene SDK-Schleife — auf einen Endpoint, und er kann Automatisierungen autorieren und betreiben, durchsuchen, was die Organisation kann, eine Capability aufrufen und Wissen abrufen — mit demselben API-Schlüssel wie die REST-Oberfläche. Wo REST die Connectorsnaht für deinen Code ist, ist der MCP-Endpoint die Naht für _Modelle_: jedes Tool antwortet Text, den ein Modell lesen und verwerten kann. Lies das, um einen Client zu verbinden und das Tool-Inventar zu verstehen. Die Grammatik zum Autorieren von Automatisierungen ist hier bewusst nicht dupliziert — der Endpoint lehrt sie selbst, über `get_docs`. ## Einen Client verbinden Der Endpoint spricht MCP-Protokoll `2025-03-26` als JSON-RPC über HTTPS — reine JSON-Antworten, kein SSE-Stream, eine Nachricht pro Request (ein Batch antwortet Fehler `-32600`). Authentifiziere mit einem Organisations-API-Schlüssel ([API-Schlüssel](/de/platform/admin/api-keys) beschreibt das Erzeugen): ```json // POST https://your-host.example.com/api/v1/mcp // Authorization: Bearer tale_... { "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {} } ``` Der Server identifiziert sich als `tale-platform`. In einem Client mit Config-Block ist das alles, was du brauchst: ```json { "mcpServers": { "tale": { "url": "https://your-host.example.com/api/v1/mcp", "headers": { "Authorization": "Bearer tale_..." } } } } ``` `tools/list` liefert das volle Inventar; `GET` auf den Endpoint antwortet **405** — es gibt keinen Event-Stream zum Abonnieren. ## Die Tools Zweiundzwanzig Tools, in drei Gruppen. Die Autoring-Tools nehmen ganze Automatisierungsdokumente und validieren alles selbst — ihre Schemas sind auf dem Draht offen, und `get_docs` ist die Referenz, die ein Modell zuerst liest. Die Verwaltungs- und Capability-Tools nehmen einfache Argumente und deklarieren echte JSON-Schemas. ### Autorieren | Tool | Was es tut | | --------------------- | ------------------------------------------------------------------------ | | `get_docs` | Die Automatisierungsgrammatik und der Autoring-Leitfaden, als Text. | | `get_catalog` | Jeder Knotentyp, den dieses Deployment ausführen kann. | | `search_catalog` | Den Knotentyp-Katalog per Stichwort durchsuchen. | | `validate_automation` | Ein Automatisierungsdokument validieren, ohne es zu speichern. | | `run_automation` | Ein Automatisierungsdokument direkt ausführen (Mock oder Live). | | `test_automation` | Die eigenen Abnahmetests einer Automatisierung ausführen. | | `save_automation` | Ein Automatisierungsdokument als neue unveränderliche Version speichern. | | `get_automation` | Eine gespeicherte Version lesen (ohne Angabe die neueste). | | `list_automations` | Die Automatisierungen der Organisation mit ihren neuesten Versionen. | | `deploy_automation` | Eine gespeicherte Version zur Live-Version befördern. | ### Lauf- & Trigger-Verwaltung | Tool | Was es tut | | ---------------- | ----------------------------------------------------------------------------------------------------------------------- | | `run_deployed` | Die deployte Version ausführen und auf das fertige Ergebnis WARTEN — Output, Trace und Effekte in einer Antwort. | | `start_run` | Die deployte Version im Hintergrund starten und sofort einen Lauf-Handle zurückgeben; das Ergebnis über get_run pollen. | | `list_runs` | Die letzten Läufe, neueste zuerst — einer Automatisierung oder der ganzen Organisation. | | `get_run` | Ein Lauf in voller Tiefe: Status, Output, Trace und Effekte. | | `cancel_run` | Einen Lauf an seiner nächsten Knotengrenze stoppen. | | `list_versions` | Die unveränderliche Versionshistorie einer Automatisierung. | | `list_triggers` | Was die Automatisierungen startet (nie das Webhook-Geheimnis). | | `delete_trigger` | Den Trigger einer Automatisierung lösen; Versionen und Laufhistorie bleiben. | | `set_trigger` | Binden, was die Automatisierung startet (Zeitplan/Webhook/Event). | Nimm `run_deployed`, wenn die Automatisierung schnell ist und du einen Aufruf mit der Antwort darin willst. Nimm `start_run`, wenn der Lauf Minuten dauern darf — er gibt sofort eine `runId` zurück, und `get_run` pollt sie. Beide laufen live. `start_run` nimmt außerdem eine optionale `projectId` — das Projekt, in dem der Lauf arbeitet, sodass seine Aufgaben- und Dokument-Tools dort wirken. Lass sie weg für einen organisationsweiten Lauf oder, wenn die Automatisierung an ein einzelnes Projekt gebunden ist, für dieses. Eine gebundene Automatisierung akzeptiert nur ein Projekt, an das sie gebunden ist. ### Capabilities & Wissen | Tool | Was es tut | | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | `search_capabilities` | Alles durchsuchen, was diese Organisation kann — ihre Automatisierungen, Connectorsaktionen, Skills und Tools. | | `invoke_capability` | Eine Capability per id aufrufen. Eine Aktion, die die Organisation gated, antwortet mit einem Pending-Approval-Ergebnis, statt zu laufen. | | `get_knowledge` | Passagen aus dem Wissen der Organisation abrufen — ihren Dokumenten und ihren gecrawlten Webseiten. | Das ist dieselbe Registry, die ein Chat-Turn sieht: ein Namensraum über Builtins, Connectorsaktionen, Skills, Automatisierungen und verbundene MCP-Tools. Eine Capability, die die Organisation hinter eine Freigabe stellt, läuft nicht lautlos — `invoke_capability` antwortet mit einem Pending-Approval-Ergebnis, das das Modell weitergeben kann. ## Was der Schlüssel darf Der Schlüssel beweist, wer anruft; die Rolle seines Besitzers entscheidet, was der Aufruf darf — genau wie im Produkt: - **Jeder Mitglieds-Schlüssel** — jedes Lese-Tool, `run_automation` im Mock-Modus, `search_capabilities`, `get_knowledge`. - **Entwickler-Fähigkeit nötig** — `save_automation`, `deploy_automation`, `set_trigger`, `delete_trigger`, `cancel_run` und Live-Ausführung (`run_deployed`, `start_run`, `run_automation` im Live-Modus). Ein abgelehnter Aufruf ist kein Protokollfehler: das Tool antwortet mit einer lesbaren Ablehnung — `{"error": "...", "hint": "..."}` — damit das aufrufende Modell sich anpassen kann, statt abzustürzen. Diese Konvention gilt überall: Validierungsprobleme, fehlende Deployments und Rollenablehnungen kommen als Daten zurück; `isError` ist für Aufrufe reserviert, die wirklich geworfen haben. ## Wo das hingehört Der MCP-Endpoint und die [REST-API](/de/develop/api-reference) sind eine Oberfläche in zwei Dialekten — derselbe Schlüssel, dieselbe Organisations-Scopung, dieselben Lauf-Objekte (`start_run` hier und `POST .../runs` dort erzeugen denselben durablen Lauf). Einen eigenen MCP-Server bauen, den Tale konsumiert, ist die Gegenrichtung — das sind [MCP-Server](/de/platform/connectors/mcp-servers) unter Connectors. # WebDAV-API Source: https://tale.dev/docs/de/develop/webdav-api Tale exponiert den Dokumentenspeicher unter `/dav/<orgSlug>/` als lese- und schreibfähigen WebDAV-Class-2-Endpunkt (RFC 4918). Diese Seite ist die Protokoll-Referenz — die Wire-Level-Oberfläche, die ein Client-Implementierer oder ein Drittanbieter-Werkzeug zur Connector braucht. Für den Endbenutzer-Einrichtungsleitfaden und Per-Client-Anweisungen siehe [Plattform > Connectors > WebDAV](/platform/connectors/webdav). ## URL-Schema ```text /dav/<orgSlug>/documents/<path> R/W aktiver Dokumentenbaum /dav/<orgSlug>/.trash/<path> R/O gelöschte Dokumente (Soft-Delete-Ansicht) /dav/<orgSlug>/ R/O Sammlung, die die zwei obigen enthält ``` Segmente sind URL-kodiert. Der Server lehnt Segmente mit `/`, `\`, NUL oder den relativen Namen `.` und `..` ab. Jedes Segment muss 1–255 Byte umfassen. Der `orgSlug` entspricht `[a-zA-Z0-9_-]{1,64}`. Die Trailing-Slash-Konvention folgt WebDAV: Sammlungen (Ordner) werden mit Trailing Slash referenziert, Ressourcen (Dateien) ohne. Viele Clients normalisieren das unterwegs; der Server akzeptiert beide Formen beim Lookup und gibt die kanonische Form in PROPFIND-Antworten aus. ## Authentifizierung Nur HTTP Basic. Das Feld Benutzername kann ein beliebiger nicht-leerer Wert sein — das App-Passwort ist die eigentliche Berechtigung, und der Server vergleicht den Benutzernamen nicht mit deinem Konto. Deine Tale-Konto-E-Mail einzutragen ist die Konvention für lesbare Audit-Logs, und die meisten Clients erwarten eine E-Mail-ähnliche Zeichenkette, aber die Auth-Entscheidung wird allein auf dem Passwort getroffen. Das Passwort ist ein **App-Passwort**, das du unter Einstellungen > WebDAV erzeugst. Dein Haupt-Konto-Passwort wird auf diesem Endpunkt nicht akzeptiert. ```http Authorization: Basic <base64(email-oder-beliebig:app-passwort)> ``` App-Passwörter werden mit HMAC-SHA256 unter dem Deployment-Secret `WEBDAV_APP_PASSWORD_HMAC_KEY` gehasht. Der Schlüssel wird vom Plattform-Entrypoint (Prod) und von `server.ts` (Dev) deterministisch aus `INSTANCE_SECRET` abgeleitet — Operatoren müssen ihn nicht manuell setzen; ein expliziter Wert in `.env` überschreibt jedoch den abgeleiteten. Der Lookup grenzt über die ersten vier Zeichen des Passworts ein (neben dem Hash gespeichert für indexierten Lookup) und verifiziert mit einem Konstant-Zeit-HMAC-Vergleich. Jede authentifizierte Anfrage prüft zusätzlich, dass der anfragende Benutzer aktives Mitglied der Organisation in der URL ist — eine veraltete Zeile (Mitgliedschaft nach App-Passwort-Ausgabe entfernt) wird mit `403` abgelehnt. `OPTIONS` ist die einzige Methode ohne Authentifizierung; Clients nutzen sie zur DAV-Capability-Prüfung vor der Anmeldung. ## Methoden | Methode | Verhalten | Auth | | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | | OPTIONS | Capabilities ankündigen. Gibt `DAV: 1, 2`, `Allow: …` und `Microsoft-Server-WebDAV-Extensions: 1` für Windows-Kompatibilität zurück. | Anonym OK | | PROPFIND | Eine Ressource auflisten (Depth 0) oder die direkten Kinder einer Sammlung (Depth 1). Die emittierte Eigenschaftsliste ist unten dokumentiert. **Depth: infinity wird mit 403 abgelehnt**, um unbegrenzte Antworten zu verhindern. | Erforderlich | | PROPPATCH | Gibt 207-Erfolg pro Eigenschaft zurück, ohne Werte zu speichern. Dead Properties werden in v1 nicht persistiert; PROPPATCH gelingt optimistisch zur Client-Kompatibilität. | Erforderlich | | GET / HEAD | Den Dokument-Blob streamen. Setzt `Content-Type`, `Content-Length`, `ETag` und `Last-Modified`. GET auf eine Sammlung gibt 405 zurück. | Erforderlich | | PUT | Ein Dokument erstellen oder ersetzen. Neuer Blob im Convex-Speicher mit Content-Hash-Dedup; die Dokument-Zeile erhält `sourceProvider: "webdav"`. Gibt 201 beim Erstellen, 204 beim Überschreiben zurück. | Erforderlich | | DELETE | Ein Dokument soft-löschen (`lifecycleStatus: "trashed"`) oder einen Ordner (kaskadiert Trash auf enthaltene Dokumente, hard-löscht die Ordner-Zeilen). Gibt 204 zurück. | Erforderlich | | MKCOL | Einen Ordner unter einem bestehenden Eltern erstellen. Nur leerer Body. Gibt 201 zurück, 405 wenn das Ziel existiert oder 409 wenn der Eltern fehlt. | Erforderlich | | MOVE | Umbenennen oder verschieben. Atomar für Dokumente. Für Ordner wird die `parentId` des verschobenen Ordners aktualisiert. Beachtet `Overwrite: T/F` und `If`. Gibt 201 (neues Ziel) oder 204 (Überschreiben) zurück. | Erforderlich | | COPY | Serverseitige Kopie. Dokumentkopien wiederverwenden die Convex-Storage-ID (Dedup). Ordnerkopien rekursiv. Beachtet `Overwrite` und `If`. | Erforderlich | | LOCK | Class-2-exklusive oder geteilte Schreibsperre. Timeout aus `Timeout: Second-N`-Header, gedeckelt auf 3600. Refresh durch erneutes LOCK mit `If: (<opaquelocktoken:...>)` und leerem Body. | Erforderlich | | UNLOCK | Eine Sperre per Token freigeben. Nur der Sperr-Besitzer kann freigeben. Gibt 204 zurück. | Erforderlich | `HEAD` teilt seinen Handler mit `GET` ohne Body. ## Eigenschaften PROPFIND gibt diese Live-Eigenschaften für jede Ressource zurück: - `resourcetype` — `<collection/>` bei Ordnern, leer bei Dokumenten. - `displayname` — der Ordnername oder Dokumenttitel. - `getlastmodified` — RFC-1123-Zeitstempel. Dokumente nutzen `sourceModifiedAt` falls gesetzt, sonst die Erstellungszeit der Dokument-Zeile. - `creationdate` — ISO 8601 der Zeilen-Erstellungszeit. - `getcontenttype` — nur Dokumente; der MIME-Typ beim Upload. - `getcontentlength` — nur Dokumente; Bytes. - `getetag` — nur Dokumente; Content-Hash falls bekannt, sonst Dokument-ID. - `supportedlock` — bewirbt exklusive Schreibsperren. - `lockdiscovery` — vorhanden bei Ressourcen mit aktiven Sperren. Dead Properties werden nicht gespeichert. PROPPATCH gibt für eine allein gesetzte Dead Property 200 zurück, aber das Setzen einer Live-/geschützten Eigenschaft liefert pro Eigenschaft ein 403 (`cannot-modify-protected-property`), und alle Dead Properties derselben Anfrage werden dann als 424 Failed Dependency gemeldet (RFC 4918 §9.2 Atomarität). Es wird nie ein Wert persistiert. ## Sperrsemantik Sperren leben in ihrer eigenen Convex-Tabelle, gekeyt mit `(organizationId, resourcePath)`. Wire-Form ist `opaquelocktoken:<uuid>`. Der Server: - Deckelt Timeout auf 3600 Sekunden. Anfragen für längere Fenster werden still gekappt. - Behandelt `LOCK` mit `If: (<opaquelocktoken:UUID>)`-Header und leerem Body als Refresh — der Ablauf der bestehenden Sperre wird verlängert. - Gibt `412 Precondition Failed` beim Refresh zurück, wenn das gelieferte Token unbekannt ist. - Gibt `423 Locked` auf `PUT / DELETE / MOVE / COPY / MKCOL / PROPPATCH` gegen einen gesperrten Pfad zurück, wenn die Anfrage keinen passenden `If`-Header trägt. - Gibt `412 Precondition Failed` zurück, wenn das gelieferte `If`-Token nicht zur Live-Sperre passt. - Lässt Sperren faul ablaufen — die Lookup-Abfrage gibt null für abgelaufene Zeilen zurück und plant eine Fire-and-Forget-Löschung. - Hard-löscht jede unter einem App-Passwort gehaltene Sperre, wenn dieses App-Passwort widerrufen wird. `UNLOCK` erfordert sowohl einen gültigen `Lock-Token`-Header als auch, dass der anfragende Benutzer der Sperr-Besitzer ist. ## Statuscodes - `200` — OPTIONS, GET, HEAD, LOCK, LOCK-Refresh, PROPPATCH (pro Eigenschaft) - `201` — PUT erstellen, MKCOL, MOVE/COPY auf neues Ziel - `204` — DELETE, UNLOCK, PUT überschreiben, MOVE/COPY überschreiben - `207` — PROPFIND, PROPPATCH (Multi-Status-Hülle) - `400` — fehlerhafter `Destination` / `If` / `Lock-Token` / `Timeout`-Header - `401` — fehlende oder ungültige Basic-Auth - `403` — Depth: infinity abgelehnt; .trash-Schreibversuch; Root-Delete/Move; falscher App-Passwort-Besitzer bei UNLOCK; Benutzer kein Mitglied der Org; MOVE/COPY auf sich selbst oder in den eigenen Teilbaum; Cross-Org-`Destination` - `404` — Ressource nicht gefunden - `405` — GET auf eine Sammlung; PUT auf einen Sammlungs-Pfad; MKCOL auf existierendem Pfad; Root-MKCOL - `409` — MKCOL, MOVE oder COPY wenn das Ziel-Elternverzeichnis nicht existiert - `412` — `If`-Token-Mismatch; `If-Match` / `If-None-Match`-Vorbedingung fehlgeschlagen; MOVE/COPY mit `Overwrite: F` auf ein existierendes Ziel - `413` — PUT-Body über dem Größenlimit, oder ein XML-Request-Body (PROPFIND / PROPPATCH / MKCOL / LOCK) über 64 KB - `415` — MKCOL mit nicht-leerem XML-Body (extended MKCOL nicht implementiert) - `423` — Schreiben auf einem gesperrten Pfad ohne passendes `If` - `502` — Cross-Host-`Destination`; Storage-Proxy-Fetch fehlgeschlagen - `503` — LOCK-Anzahl-Limit für das App-Passwort überschritten (mit `Retry-After`) - `507` — Ordner-Teilbaum zu groß zum Löschen, Verschieben oder Kopieren in einer einzigen Anfrage ## Compliance - DAV Class **1** (Basis): vollständig. - DAV Class **2** (Sperren): vollständig, mit dem oben beschriebenen Lazy-Expiry-Verhalten. - DAV Class **3** (Kalender, Kontakte, Suche, ACL): nicht implementiert. Der Server bewirbt `DAV: 1, 2` in der OPTIONS-Antwort. ## Limits - `Depth: infinity` auf PROPFIND wird mit `403` abgelehnt. - `Timeout: Second-N` auf LOCK wird auf `[1, 3600]` begrenzt. - Die PUT-Body-Größe ist standardmäßig auf **5 GB** begrenzt (`413` bei Überschreitung), erzwungen sowohl am Reverse-Proxy als auch im Plattform-Server. Betreiber können das Limit über die Umgebungsvariable `WEBDAV_MAX_PUT_BYTES` anpassen. Der Body wird an eine Convex-Presigned-URL gestreamt, ohne dass ein großer Upload im Plattform-Speicher gepuffert wird. - XML-Request-Bodys (PROPFIND / PROPPATCH / MKCOL / LOCK) sind auf **64 KB** begrenzt (`413` bei Überschreitung) — diese Envelopes sind per Design winzig. - App-Passwörter werden mit HMAC-SHA256 gehasht; das Geheimnis taucht nach dem Create-Call in keiner Antwort mehr auf. - `lastUsedAt` wird höchstens einmal pro Minute pro App-Passwort gepatcht, um Write-Storms auf belebten Mounts zu vermeiden. ## Netzwerk-Voraussetzungen Der WebDAV-Endpunkt läuft im Plattform-Hono-Server (`platform:3000` in Compose). Caddy routet `/dav/*` über den Default-Fallback dorthin — keine Extra-Konfiguration erforderlich. Der Pfad erfordert, dass der Plattform-Server `ADMIN_KEY` in seiner Umgebung gesetzt hat, damit er interne Convex-Abfragen mit Admin-Auth aufrufen kann. Für Dev (`bun dev`) wird derselbe Dispatch als Vite-Middleware gemountet (`vite-plugins/serve-webdav.ts`) — `curl` und Clients können `http://localhost:3000/dav/<orgSlug>/...` gegen einen laufenden Dev-Server ohne Rebuild treffen. ## Sicherheit WebDAV schickt das App-Passwort als HTTP-Basic-Header bei jeder Anfrage — keine Session, kein Token-Refresh, einfach die nackte Berechtigung wiedergespielt bei jedem PROPFIND, PUT, LOCK und so weiter. Hänge den Endpunkt nur über HTTPS ein; über reines HTTP leakt das Passwort an jeden auf der Leitung, und ein Widerruf der Zeile ist die einzige Erholung. Stecke das App-Passwort niemals direkt in die URL (die `https://user:pass@host/...`-Kurzform) — die meisten Clients protokollieren URLs in Shell-History, Crash-Reports und Proxy-Access-Logs, wo die Berechtigung den Unmount weit überdauern würde. Lass den WebDAV-Client das Passwort im System-Schlüsselbund speichern (macOS Keychain, Windows Credential Manager, GNOME Keyring) und über den Standard-Credential-Prompt herausgeben. Der Server erzwingt TLS auf der Reverse-Proxy-Schicht in Produktion; der Dev-Modus über reines HTTP ist nur für `localhost`-Tests gedacht. Audit-Logs erfassen jede authentifizierte Anfrage mit dem Präfix des verwendeten Passworts, sodass eine geleakte Berechtigung sich nachverfolgen und widerrufen lässt, ohne die übrige Geräteflotte zu rotieren. ## Wo das hinpasst WebDAV ist die Mount-Protokoll-Oberfläche desselben Dokumentenspeichers, den die [REST-API-Referenz](/develop/api-reference) für Bulk-Import und Suche bedient — beide Wege schreiben in dieselbe Tabelle, aus der der [Dokumenten-Hub](/platform/knowledge/documents) liest, sodass eine über den Finder erstellte Datei ohne Sync-Schritt in der Web-Oberfläche erscheint. Das Protokoll ist die richtige Wahl, wenn Dokumente sich wie ein lokaler Ordner anfühlen sollen; die REST-API ist die richtige Wahl, wenn ein Skript oder Agent Byte-Kontrolle über das Geschriebene braucht. RFC 4918 ist die Wire-Level-Autorität für alles auf dieser Seite. # Entwicklung Source: https://tale.dev/docs/de/develop/overview Entwicklung ist der Abschnitt für Integratoren und Contributors — alle, die Tale an ein anderes System anbinden, auf der API aufsetzen oder eine Änderung am Quellcode liefern. Die Seiten hier beschreiben die externe Oberfläche (REST, Webhooks, OpenAI-kompatible Endpoints) und den Contributor-Workflow. Wenn du innerhalb des Produkts als Entwickler-Rolle arbeitest (Agents, Workflows, eigene Tools), deckt der Reiter Plattform deinen Alltag ab; Entwicklung ist dann gefragt, wenn du außerhalb des Produkts stehst und über die Leitung mit ihm sprichst. Lieber erst zusehen? Die Bonus-Episode geht die Entwickler-Oberfläche ab — Schlüssel, APIs, Webhooks, Harnesses — in gut zwei Minuten. <Video src="/videos/de/tutorials/ep10-developers/ep10-developers.de.mp4" poster="/videos/de/tutorials/ep10-developers/ep10-developers.de.webp" captions="/videos/de/tutorials/ep10-developers/ep10-developers.de.vtt" lang="de" title="Bonus — Tale für Entwickler" caption="Bonus — Tale für Entwickler (2:38)"> </Video> ## Seiten in diesem Abschnitt <CardGroup cols="2"> <Card title="API-Referenz" icon="code" href="/de/develop/api-reference"> Endpoints, Authentifizierung, OpenAI-kompatible Endpoints, Fehlermodell, Versionierung. </Card> <Card title="Webhooks" icon="webhook" href="/de/develop/webhooks"> Ausgehend (Tale → du) und eingehend (du → Tale), Signieren, Idempotenz, Wiederholungen. </Card> <Card title="KI-gestützte Entwicklung" icon="sparkles" href="/de/develop/ai-assisted-development"> Tale-Agents nutzen, um Tale-Workflows zu schreiben; die `.agents/`-Skill-Dateien. </Card> <Card title="Connectors" icon="plug" href="/de/develop/connectors"> Drittanbieter-Connectors aus Entwicklersicht. </Card> <Card title="Status-Seite" icon="activity" href="/de/develop/status-page"> Vorfallsmeldungen für Cloud, Metrik-Verweise für selbst gehostet. </Card> <Card title="Rate Limits" icon="gauge" href="/de/develop/rate-limits"> Limits pro Key, pro IP, pro Organisation und wie ein 429 zu lesen ist. </Card> </CardGroup> ## Wo das hingehört Entwicklung ist der kleinste Abschnitt, weil die meisten Nutzer ihn nie brauchen; das Publikum konzentriert sich auf zwei Rollen (Entwickler im Produkt, Contributor außerhalb), ist aber für beide tragend. Wenn du etwas Externes an Tale anbindest, ist [API-Referenz](/de/develop/api-reference) die erste Lektüre; wenn du am Quellcode beiträgst, ist [Mitwirken](/de/self-hosted/contributing-docker) — unter dem Reiter Selbst gehostet — die richtige. # Dein erster Tag als Agent-Autor Source: https://tale.dev/docs/de/get-started/editors Dieser Einstieg ist für die Person, die aus „das Team stellt immer dieselben Fragen“ einen Agent macht, der sie beantwortet. In fünfzehn Minuten erstellst du einen Agent, formst sein Verhalten und siehst ihm bei echter Arbeit auf einer Aufgabe zu — die Schleife, die jeder spätere Agent verfeinert. Du brauchst die Rolle **Redakteur** oder höher (der Bereich Agenten ist für Mitglieder ausgeblendet) in einem Arbeitsbereich, in dem der Chat bereits antwortet — das ist der [Quickstart](/de/get-started/quickstart). <Steps> <Step title="Erstelle den Agent"> Für einen Agent, den Teammitglieder an die Arbeit schicken können, öffne **Agenten** in der Sidebar und klicke auf **Agent erstellen**. Benenne ihn nach dem Job, nicht nach der Technologie — „Support-Triage“ schlägt „GPT-Helfer“ —, denn unter diesem Namen weisen Teammitglieder ihm später Aufgaben zu. </Step> <Step title="Gib ihm eine Identität"> Der Editor öffnet auf dem Tab **Allgemein**: der Anzeigename, den Teammitglieder sehen, und eine einzeilige Beschreibung. Die Einstellung, die am ersten Tag zählt, ist die Sichtbarkeit — sie entscheidet, wer in der Organisation den Agent an die Arbeit schicken darf. </Step> <Step title="Schreib die Anweisungen"> Öffne **Anweisungen** — der Hebel, der am meisten bewegt. Schreib einen Absatz, als würdest du eine neue Kollegin briefen: die Stimme, in der er antwortet, die Domäne, die er verantwortet, und die Fälle, die er ablehnen soll. Konkret schlägt vollständig — du verfeinerst, sobald du echte Antworten gesehen hast. Klicke auf **Speichern**; ab der nächsten Anfrage ist der Agent erreichbar, ein separater Rollout entfällt. </Step> <Step title="Sieh ihm bei der Arbeit zu"> Agents arbeiten auf Aufgaben — der Chat führt nur den eingebauten Assistenten aus. Öffne ein Projekt, füg deinen Agent auf dessen Tab **Agenten** hinzu, erstell dann eine Aufgabe, die die Arbeit in einem Satz benennt, und weis sie dem Agent zu. Starte den Lauf und verfolg seine Timeline; das Ergebnis kommt zur Prüfung zu dir zurück, und nur du kannst es auf Erledigt setzen. <Check> Folgt das Ergebnis der Stimme und dem Rahmen, die du geschrieben hast, greifen die Anweisungen — der Agent ist echt. </Check> </Step> </Steps> ## Wo du jetzt stehst Du hast den kleinsten echten Agent ausgeliefert: Anweisungen und einen Platz unter den Agenten der Org. Das vollständige Modell hinter dem, was du angefasst hast, sind die [Agent-Konzepte](/de/platform/agents/concepts) — Anweisungen, Wissen, Tools und Skills. Der natürliche nächste Bau ist [dein erster Agent von Anfang bis Ende](/de/tutorials/editor/first-agent-end-to-end), der Wissensanbindungen und eine echte Domäne ergänzt; danach führen [Agents mit Wissen](/de/tutorials/editor/agent-with-knowledge) und [Delegation zwischen Agents](/de/tutorials/editor/delegate-between-agents) dieselbe Schleife weiter. # Quickstart Source: https://tale.dev/docs/de/get-started/quickstart Das ist der kürzeste Weg zu einem funktionierenden Chat mit einem Agent: Instanz besorgen, anmelden, Nachricht senden, der Antwort beim Streamen zusehen. Auf einer bereiten Instanz dauert das rund fünf Minuten, auf deiner eigenen Maschine fünfzehn — und es endet mit dem Bildschirm unten, einer echten Antwort eines Agents über deinen Arbeitsbereich. <Frame caption="Wo dieser Quickstart endet: eine gestreamte Agent-Antwort im Chat."> ![Ein Chat-Verlauf mit einer Nutzerfrage zu Onboarding-Feedback und einer Assistenten-Antwort, die eine Markdown-Tabelle mit drei Themen enthält.](/images/platform/chat-thread-reply.webp) </Frame> Lieber als Video? Episode 1 geht denselben Weg in gut drei Minuten — Untertitel inklusive. <Video src="/videos/de/tutorials/ep1-welcome/ep1-welcome.de.mp4" poster="/videos/de/tutorials/ep1-welcome/ep1-welcome.de.webp" captions="/videos/de/tutorials/ep1-welcome/ep1-welcome.de.vtt" lang="de" title="Episode 1 — Willkommen bei Tale" caption="Episode 1 — Willkommen bei Tale (3:25)"> </Video> ## Hol dir eine Instanz Beide Editionen sind dasselbe Produkt — entscheide danach, wer den Stack betreiben soll. <Tabs> <Tab title="Selbst gehostet"> Mit laufendem [Docker](https://www.docker.com/products/docker-desktop) stellen drei Befehle den ganzen Stack auf deiner Maschine auf: ```bash curl -fsSL https://raw.githubusercontent.com/tale-project/tale/main/scripts/install-cli.sh | bash tale init my-project && cd my-project tale dev ``` Der erste Lauf zieht die Images — rechne mit fünf bis zehn Minuten. Sobald der Browser aufgeht, registriere dich: Das erste Konto übernimmt die Rolle **Inhaber** und erstellt deine Organisation. Der [selbst gehostete Quickstart](/de/self-hosted/install/quickstart) erklärt jeden Schritt in der Tiefe, samt Windows und Fehlersuche. </Tab> <Tab title="Cloud"> Cloud-Instanzen werden für dich aufgesetzt: Füll das [Demo-Formular](https://tale.dev/de/request-demo) aus, und das Tale-Team stellt deine eigene Instanz bereit. Sobald sie steht, öffne sie und registriere dich — das Formular fragt nach Name, E-Mail und Passwort; bestätige den E-Mail-Link, sobald er ankommt, benenne deine Organisation, und du landest im Dashboard. Der Setup-Assistent bietet direkt an, einen KI-Anbieter zu verbinden — füge dort einen [OpenRouter](https://openrouter.ai)-Schlüssel ein, und der Chat funktioniert sofort. Der [Einstieg für Admins](/de/get-started/admins) geht denselben Assistenten mit Screenshots durch, wenn du mehr willst als den Happy Path. </Tab> </Tabs> ## Schick deine erste Nachricht <Steps> <Step title="Öffne einen neuen Chat"> Klicke in der Sidebar auf **Neuer Chat**. Die Eingabezeile am unteren Bildschirmrand ist der Ort, an dem alles beginnt: das Nachrichtenfeld und ein Picker, der das Modell benennt, aus dem die Antwort kommen wird. Zeigt der Picker bereits ein Modell, bist du bereit zu senden — der Assistent selbst ist eingebaut, mehr gibt es nicht zu wählen. </Step> <Step title="Stell eine echte Frage"> Wähl im Picker irgendein Chat-Modell — jede Antwort kommt von genau dem Modell, das du benannt hast, hinter den Kulissen wird nichts für dich entschieden. Tippe eine Frage und sende sie. Die Antwort streamt Token für Token herein; wenn der Agent vor dem Antworten nachdenkt, erscheint über der Antwort eine aufklappbare Denk-Zeile. <Check> Eine gestreamte Antwort, die deine Frage beantwortet, heißt: Die ganze Kette funktioniert — Anbieter-Zugangsdaten, Modell und Assistent. Du hast einen funktionierenden Arbeitsbereich. </Check> </Step> </Steps> ## Wo du jetzt stehst Du hast eine laufende Instanz und einen Agent, der antwortet. Die nächsten fünfzehn Minuten hängen von deiner Rolle ab: Der [Einstieg für Mitglieder](/de/get-started/members) behandelt Dokumente und Projekte, der [Einstieg für Redakteure](/de/get-started/editors) veröffentlicht deinen ersten Spezialisten-Agent, der [Einstieg für Admins](/de/get-started/admins) richtet Team und Anbieter ein, und der [Einstieg für Entwickler](/de/get-started/developers) bringt dir einen API-Schlüssel und deine erste Anfrage. # Dein erster Tag mit der Tale-API Source: https://tale.dev/docs/de/get-started/developers Dieser Einstieg ist für die Person, die Tale mit anderen Systemen verdrahtet. In zehn Minuten erstellst du einen API-Schlüssel, machst deine erste authentifizierte Anfrage und weißt, an welche Tür du für Chat, Workflows und Dokumente klopfst. Du brauchst die Rolle **Entwickler** oder höher (darunter sind die API-Einstellungen ausgeblendet) auf einer laufenden Instanz — der [Quickstart](/de/get-started/quickstart) hilft, wenn du keine hast. Ersetze unten `your-host.example.com` durch den Host deiner Instanz. <Steps> <Step title="Erstelle einen API-Schlüssel"> Für einen Berechtigungsnachweis, den deine Skripte halten können, öffne **Einstellungen > API > REST** und klicke auf **API-Schlüssel erstellen**. Benenne ihn nach dem System, das ihn nutzen wird — Schlüssel werden nach Namen gelistet, und in einem Jahr schlägt „zapier-bridge“ jedes „test“. Der Schlüsselwert erscheint genau einmal, bei der Erstellung; leg ihn in deinen Secret-Manager, nicht in den Code. <Frame caption="Die REST-API-Einstellungen — Schlüssel werden hier erstellt und widerrufen."> ![Die Einstellungsseite für REST-API-Schlüssel listet zwei Schlüssel — Production ingest und CI pipeline —, jeder nur mit seinem Schlüssel-Präfix, dem Datum unter Hinzugefügt und der Markierung Nie verwendet, neben dem Knopf API-Schlüssel erstellen.](/images/get-started/settings-api-keys.webp) </Frame> </Step> <Step title="Mach die erste Anfrage"> Der kürzeste nützliche Aufruf listet die Agents, die dein Schlüssel sehen kann. Der Schlüssel reist als Bearer-Token mit; den Arbeitsbereichs-Kontext leitet Tale aus dem Schlüssel selbst ab: ```bash curl -sS https://your-host.example.com/api/v1/agents \ -H "Authorization: Bearer $TALE_API_KEY" ``` <Check> Ein JSON-Array von Agents — samt dem eingebauten Assistenten — beweist Schlüssel, Header und Route. Ein `401` heißt: Der Token-Header ist fehlerhaft, oder der Schlüssel wurde widerrufen. </Check> </Step> </Steps> ## Der Rest der Oberfläche Alles Weitere sind Variationen dieser Anfrage. Automatisierungen laufen per Name über `POST /api/v1/automations/<name>/runs` mit demselben Bearer-Schlüssel — beantwortet mit 202, gepollt über `/api/v1/runs/<runId>` — oder werden von außen über Webhook-URLs der Form `/api/automations/webhook/<token>` gefeuert; das Token in der URL ist der Berechtigungsnachweis. Chat ist ein Thread, eine gesendete Nachricht und ein Poll; Dokumente laden über `/api/v1/documents` hoch; und derselbe Schlüssel öffnet den [MCP-Endpoint](/de/develop/mcp-endpoint) für modellgetriebene Clients. Die [API-Referenz](/de/develop/api-reference) ist das vollständige Inventar mit Auth, Datenformen und Limits. ## Wo du jetzt stehst Du hältst einen funktionierenden Berechtigungsnachweis und hast die Anfrageform gesehen, die jeder Endpunkt teilt. Von hier aus macht [Tale aus einem Skript aufrufen](/de/tutorials/developer/call-tale-from-a-script) aus dem curl eine echte Connector, [eine Automatisierung per Webhook auslösen](/de/tutorials/developer/trigger-automation-via-webhook) behandelt die Push-Richtung, und der [MCP-Endpoint](/de/develop/mcp-endpoint) ist dieselbe Plattform für MCP-Clients. # Dein erster Tag als Arbeitsbereichs-Verantwortlicher Source: https://tale.dev/docs/de/get-started/admins Dieser Einstieg ist für die Person, die den Arbeitsbereich verantwortet. In fünfzehn Minuten erstellst du die Organisation, verbindest den Anbieter, der den Chat zum Antworten bringt, holst die ersten Teammitglieder an Bord und lernst, wo die Governance-Steuerung wohnt, bevor du sie brauchst. Du brauchst ein Konto auf einer laufenden Instanz ([Quickstart](/de/get-started/quickstart)); auf einer brandneuen Instanz ist das erste Konto automatisch **Inhaber**, und diese Rolle trägt jede Berechtigung unten. <Steps> <Step title="Erstelle den Arbeitsbereich"> Kommst du aus dem Quickstart, existiert deine Organisation schon — spring zum Anbieter-Schritt. Eine frische Anmeldung ohne Organisation landet im Erstellungsassistenten: Der **Organisationsname** ist der Anzeigename, den dein Team in der Ecke jeder Seite sieht — wähl einen, der ein Rebranding überlebt. Der Assistent bietet danach an, einen KI-Anbieter zu verbinden, und endet im Dashboard. <Frame caption="Der Arbeitsbereichs-Schritt des Erstellungsassistenten."> ![Der Assistent zum Erstellen einer Organisation auf seinem Arbeitsbereichs-Schritt, mit Northlight Labs im Feld Organisationsname und aktivem Knopf Weiter.](/images/get-started/org-create-wizard.webp) </Frame> </Step> <Step title="Verbinde einen KI-Anbieter"> Nichts antwortet, solange kein Anbieter verbunden ist. Hast du den Anbieter-Schritt des Assistenten übersprungen, öffne **Einstellungen > KI-Anbieter** und klicke bei einem Connector auf **Zugangsdaten hinzufügen** — ein [OpenRouter](https://openrouter.ai)-Schlüssel erreicht den breitesten Modellkatalog, und jeder direkte Anbieter bringt daneben seinen eigenen Connector mit. Zugangsdaten sind nutzbar, sobald sie gespeichert sind; ab dann kann jeder Agent im Arbeitsbereich mit jedem Modell antworten, das dieser Connector freigibt. <Frame caption="Ein verbundener Anbieter mit seinem Modellkatalog."> ![Die Einstellungsseite für KI-Anbieter listet einen verbundenen Anbieter, OpenRouter, mit seiner Basis-URL und 52 Modellen.](/images/get-started/settings-providers.webp) </Frame> </Step> <Step title="Hol das Team an Bord"> Um Personen hinzuzufügen, öffne **Einstellungen > Organisation**, scroll zum Abschnitt **Mitglieder** und klicke auf **Mitglied hinzufügen**. Jede Person landet mit einer Rolle, die absteckt, was sie tun kann: **Mitglied** liest und chattet, **Redakteur** baut Agents und Wissen, **Entwickler** verdrahtet Workflows, Automatisierungen und API-Zugriff, **Admin** betreibt den Arbeitsbereich. Fang niedrig an — eine Rolle später anzuheben ist ein Klick, geleakten Zugriff einzufangen nicht. <Frame caption="Der Abschnitt Mitglieder — jedes Konto und seine Rolle."> ![Die Organisationseinstellungen mit dem Abschnitt Mitglieder, der den Arbeitsbereichs-Inhaber Alex Rivera listet, und dem Knopf Mitglied hinzufügen.](/images/get-started/settings-organization-members.webp) </Frame> <Check> Ein Teammitglied, das sich anmeldet und im Chat eine Antwort bekommt, beweist die ganze Kette — Konto, Rolle, Anbieter — ohne dass du danebenstehst. </Check> </Step> <Step title="Wisse, wo Governance wohnt"> Am ersten Tag brauchst du keine Richtlinien, aber du solltest die Tür kennen: **Einstellungen > Richtlinien** hält Audit-Logs, Nutzungsanalysen, Inhaltsrichtlinien, Guardrails und Aufbewahrung. Die eine Gewohnheit, die sich heute schon lohnt: Überflieg nach der ersten Woche die [Audit-Logs](/de/platform/admin/governance/audit-logs) — sie zeigen dir, was dein Arbeitsbereich tatsächlich tut. </Step> </Steps> ## Wo du jetzt stehst Der Arbeitsbereich steht: Ein Anbieter antwortet, das Team ist mit abgesteckten Rollen drin, und du kennst die Orte der Steuerung. Die vollständige Berechtigungsmatrix sind [Mitglieder und Rollen](/de/platform/admin/members-and-roles); die [Admin-Übersicht](/de/platform/admin/overview) verzeichnet jeden Bereich, den du jetzt verantwortest; und wenn die Compliance fragt, ist [Governance](/de/platform/admin/governance/audit-logs) der Abschnitt, den du ihr zeigst. # Dein erster Tag mit Tale Source: https://tale.dev/docs/de/get-started/members Dieser Einstieg ist für alle, die Tale nutzen, statt es zu konfigurieren. In fünfzehn Minuten chattest du mit einem Agent, fügst ein Dokument hinzu, aus dem der ganze Arbeitsbereich schöpfen kann, und lernst, wo gemeinsame Arbeit lebt — die drei Handgriffe, die die meisten Tage abdecken. Du brauchst ein angemeldetes Konto in einem Arbeitsbereich, in dem der Chat bereits antwortet — das ist der [Quickstart](/de/get-started/quickstart). Chatten und Stöbern funktionieren mit der Rolle **Mitglied**; die zwei Schreib-Handgriffe unten (ein Dokument hochladen, eine Aufgabe verschieben) brauchen **Redakteur** oder höher — fehlt dir ein Knopf, ist das die Rollengrenze, kein kaputter Arbeitsbereich. <Steps> <Step title="Chatte mit einem Agent"> Deine erste Nachricht hast du schon im Quickstart geschickt — diesmal sieh zu, was der Agent daraus macht. Klicke auf **Neuer Chat**, frag etwas aus deiner echten Arbeit und klapp die Tool-Aufruf-Boxen über der Antwort auf: Sie zeigen, was der Agent gelesen oder ausgeführt hat, bevor er antwortete. Soll die Antwort aus einem Dokument kommen, lad es zuerst unter **Wissen** hoch — der Assistent durchsucht die Dokumente der Organisation und belegt, was er verwendet hat. Der nächste Schritt zeigt genau diesen Upload. </Step> <Step title="Gib dem Arbeitsbereich ein Dokument"> Wissen überdauert jeden Chat und zitiert sich in den Antworten selbst. Soll ein Dokument jedem Agent und jedem Teammitglied zur Verfügung stehen, öffne **Wissen > Dokumente** und klicke auf **Dokumente hochladen**, dann **Von deinem Gerät**, wähl die Datei und klicke auf **Hochladen**. Das Dokument erscheint in der Tabelle und wird im Hintergrund indiziert — sobald es indiziert ist, zitieren Agents es in ihren Antworten. Das Upload-Menü erscheint ab Redakteur; mit der Rolle Mitglied liest und durchsuchst du die Bibliothek und gibst die Datei einem Redakteur zum Hinzufügen. <Frame caption="Die Dokumente-Tabelle nach ein paar Uploads."> ![Die Dokumente-Tabelle im Bereich Wissen mit drei hochgeladenen Textdateien und ihrem Indizierungsstatus.](/images/get-started/documents-list.webp) </Frame> <Check> Stell in einem neuen Chat eine Frage, die nur dein Dokument beantworten kann. Eine Antwort, die das Dokument zitiert, beweist den Index von Anfang bis Ende. </Check> </Step> <Step title="Finde die Arbeit des Teams in Projekten"> Öffne **Projekte** in der Sidebar. Ein Projekt bündelt alles zu einem Vorhaben — Aufgaben auf einem Board, geteilte Dateien, Projekt-Chats und eigene Agents. Öffne ein Projekt und wechsle auf dem Tab **Aufgaben** zwischen **Board** und **Liste**; mit Bearbeitungszugriff (ab Redakteur) ziehst du eine Aufgabe zwischen den Spalten, um ihren Status zu ändern — bleibt die Karte nach einem Neuladen in ihrer neuen Spalte, ist die Änderung für alle gespeichert. <Frame caption="Das Aufgaben-Board eines Projekts — zieh Karten zwischen den Spalten."> ![Ein Projekt-Aufgabenboard mit dem Titel Website-Relaunch und sieben Aufgabenkarten, ein bis zwei je Spalte, verteilt über Backlog, Zu erledigen, In Bearbeitung, In Prüfung, Erledigt und Abgebrochen.](/images/platform/projects-task-board.webp) </Frame> </Step> <Step title="Finde zurück zu deinen Chats"> Chats verschwinden nie stillschweigend. Klicke über dem Chat auf **Verlauf anzeigen**, um die Verlaufs-Sidebar zu öffnen — jeder Chat, den du in diesem Arbeitsbereich fortsetzen kannst, der neueste zuerst. Benennst du einen Chat um, behält er diesen Titel dauerhaft; löschst du einen, wandert er in den Papierkorb des Arbeitsbereichs, statt zerstört zu werden. </Step> </Steps> ## Wo du jetzt stehst Du kannst chatten, den Arbeitsbereich mit Wissen füttern und dich in gemeinsamer Arbeit bewegen — die tägliche Schleife eines Mitglieds. Als Nächstes lohnen sich [Chat-Grundlagen](/de/platform/chat/basics) für das mentale Modell hinter dem Chat und [Projekte nutzen](/de/tutorials/member/use-projects) für einen tieferen Projekt-Walkthrough. Sobald du bereit bist, einen eigenen Agent zu bauen, wechsle zum [Einstieg für Redakteure](/de/get-started/editors). # Zu Docker-Images beitragen Source: https://tale.dev/docs/de/self-hosted/contributing-docker Jeder Container, den Tale ausliefert, hat sein Dockerfile im öffentlichen Quell-Repo. Forks, Air-gapped-Distributionen und einmalige Patches starten alle aus denselben Dateien; diese Seite ist der Operator-Durchgang durch das Selber-Bauen der Images, wo die Anpassungs-Nähte leben und wie du einen Fork mit Upstream synchron hältst, ohne bei den langweiligen Teilen abzudriften. Die Container-Architektur lebt in [Container-Architektur](/de/self-hosted/operate/container-architecture); diese Seite ist das, was du liest, wenn die veröffentlichten Images nicht passen und du deine eigenen bauen musst. ## Was die Images sind Der Stack ist vollständig TypeScript — kein Python-Image. Jedes Image hat ein Dockerfile unter `services/<name>/`: | Image | Quell-Pfad | Basis | | ------------------------ | ----------------------------- | ---------------------------- | | `tale-proxy` | `services/proxy/` | Caddy | | `tale-platform` | `services/platform/` | Bun + Debian slim | | `tale-convex` | `services/convex/` | Convex local-backend | | `tale-db` | `services/db/` | ParadeDB (Postgres) | | `tale-sandbox` | `services/sandbox/` | Bun + Docker-CLI | | `tale-sandbox-egress` | `services/sandbox-egress/` | Alpine + tinyproxy | | `tale-sandbox-runtime` | `services/sandbox-runtime/` | Bun + Chromium + Playwright | | `tale-sandbox-buildkitd` | `services/sandbox-buildkitd/` | Debian + BuildKit + redsocks | | `tale-controller` | `services/controller/` | Bun + Docker-CLI | Beide Datenbank-Container — `db` und `knowledge-db` — bauen aus demselben `tale-db`-ParadeDB-Image; der Unterschied ist die Datenbank, die jeder bedient. Das LLM-Gateway `tale-sandbox-llm-gateway` ist ein gepinntes Upstream-Image (`maximhq/bifrost`), hat also kein Dockerfile im Repo. Die Compose-Dateien im Repo-Root (`compose.yml` für Development, die CLI-generierte Produktions-Compose) referenzieren diese über `ghcr.io/tale-project/tale/<image>:<tag>`. Ein lokaler Build ersetzt den Registry-Pull mit einem `build:`-Block in Compose. ## Lokal bauen Ein erster Build jedes Images dauert etwa 15 Minuten auf einem aktuellen Laptop; nachfolgende Builds treffen den Layer-Cache von Docker und sind in unter einer Minute fertig für das Image, das du geändert hast. ```bash # Bau jedes Image in compose.yml docker compose build # Bau ein Image docker compose build platform ``` Setze `PULL_POLICY=build` in deiner Umgebung (oder in `.env`), um Compose zu zwingen zu bauen, statt das veröffentlichte Image zu ziehen. Die ausgelieferte `compose.yml` defaultet auf `build`, also baut ein lokales Clone ohne Overrides bereits; Produktions-Compose-Dateien, die `tale deploy` generiert, defaulten auf `always` und ziehen aus der Registry. ## Die Anpassungs-Nähte Die unterstützten Erweiterungs-Punkte für Forks sind auf der Dockerfile-Ebene. Der Entrypoint des Images und die Konfigurationsdateien darin sind stabil — patche sie, bau das Image, und der Rest des Systems muss es nicht wissen. - **Caddyfile** — `services/proxy/Caddyfile` steuert Routing und TLS-Terminierung. Custom Header, Custom Subdomains und Custom Rate-Limits landen hier. - **Plattform-Plop-Templates** — `services/platform/Dockerfile` läuft einen Build-Schritt, der die Messages, das Schema und die statischen Assets einbäckt. Ein Fork, der Custom-UI-Strings oder zusätzliche Routes ausliefert, baut das Plattform-Image. - **Sandbox-Runtime-Image** — `services/sandbox-runtime/Dockerfile` ist die Ausführungsumgebung für **Code-ausführen**, Web-Render und Dokumentgenerierung; es trägt bereits Chromium und Playwright. Ein Fork, der ein zusätzliches System-Paket oder einen anderen Browser-Build braucht, patcht hier. - **Sandbox-Egress-Proxy** — `services/sandbox-egress/tinyproxy.conf.template` ist die Proxy-Konfiguration, die der Entrypoint beim Start rendert: standardmäßig offenes Egress, oder ein Default-Deny-Hostname-Filter, wenn `SANDBOX_EGRESS_ALLOWLIST` gesetzt ist. Ein Fork, der anderes Proxy-Verhalten braucht, patcht hier. Was keine unterstützte Naht ist: der Anwendungscode des Convex-Backends, inklusive der Dokument-Extraktion und der RAG- und Crawler-Logik, die jetzt im Prozess leben (`services/platform/convex/`), und der Runtime-Code des Plattform-Containers (`services/platform/app/`). Diese Dateien sind Anwendungscode, keine Konfiguration — einen Dokumentformat-Extraktor hinzuzufügen oder das Retrieval-Verhalten zu ändern ist ein echter Fork und trägt die Upgrade-Steuer. ## Taggen und in eigene Registry pushen Für Air-gapped- oder vendored Distributionen ist der Pfad „bauen, taggen, in deine Registry pushen, die `image:`-Zeilen in Compose ändern". ```bash # Bauen, taggen, pushen export REGISTRY=registry.internal.example.com/tale docker compose build docker tag ghcr.io/tale-project/tale/tale-platform:latest \ $REGISTRY/tale-platform:vendored-1.0 docker push $REGISTRY/tale-platform:vendored-1.0 ``` Der Deploy des CLI generiert eine Compose-Datei mit dem Registry-Pfad; entweder patche die generierte Datei nach der Generierung, oder überspring das CLI und läufe `docker compose` direkt gegen eine Compose-Datei, die du selbst pflegst. ## Mit Upstream synchron bleiben Der günstige Pfad ist ein Fork auf GitHub, der periodisch von `tale-project/tale@main` mergt. Konflikte landen in den Dateien, die du gepatched hast; der Rest geht sauber durch. Die zwei Anti-Patterns: - **Anwendungscode patchen, statt ihn zurückzubeitragen.** Ist die Änderung breit nützlich, upstream einen PR — jede Release-Steuer geht runter. - **Auf ein altes Base-Image pinnen.** Die Caddy-, Bun- und Postgres-Basen nehmen Sicherheits-Patches beim Rebuild auf; die Basis für „Stabilität" zu pinnen heisst Ärger borgen. ## Wo das hingehört Diese Seite ist die contributor-seitige Naht der Operator-Story. Die Architektur-Übersicht lebt in [Container-Architektur](/de/self-hosted/operate/container-architecture); der Upgrade-Workflow, der die veröffentlichten Images läuft, ist in [Upgrades](/de/self-hosted/operate/upgrades). Ist dein Fork nicht-trivial, ist das Gespräch, das es wert ist anzufangen, bevor du Code schreibst, das auf dem Discord oder den GitHub Discussions des Projekts — viele Forks enden als Features, die darauf warten, Upstream zu landen. # Selbst gehostet Source: https://tale.dev/docs/de/self-hosted Selbst gehostetes Tale läuft auf deiner eigenen Infrastruktur — on-premise, in deiner VPC oder air-gapped. Sieben Container, deine Daten auf deinem Storage, keine Pro-Sitz-Abrechnung und kein Traffic, der zu Tales Servern fließt, außer du richtest einen Anbieter dort ein. Dieser Abschnitt ist für Operator: die Leute, die entscheiden, wo Tale läuft, es installieren, konfigurieren, gepatcht halten und den Pager übernehmen, wenn etwas schiefgeht. Endnutzer von selbst gehosteten Instanzen lesen meist den Reiter Plattform — die Produktoberfläche ist zwischen den Editionen identisch. ## Seiten in diesem Abschnitt **[Architektur-Überblick](/de/self-hosted/overview)** — was jeder Container tut, wo Daten auf dem Storage liegen, was mit was spricht. **[Installation](/de/self-hosted/install/quickstart)** — Quickstart auf dem Laptop, Produktions-Setup auf einem Linux-Host, die docker-compose-Referenz, erstes Admin-Setup, das CLI-Installationsskript. **[Konfiguration](/de/self-hosted/configuration/environment-reference)** — jede Umgebungsvariable, Provider-Dateien, Authentifizierungsmodi, TLS, Speicher, Aufbewahrung, SOPS-verschlüsselte Secrets, Observability. **[Betrieb](/de/self-hosted/operate/container-architecture)** — Upgrades, Backups und Restore, Observability und Troubleshooting, Security-Advisories, Härtung, Format der Release Notes. **[Mitwirken](/de/self-hosted/contributing-docker)** — wie du eine lokale Container-Änderung baust und testest. ## Wo das hingehört Selbst gehostet ist die Edition, in der der Operator mehr vom Stack besitzt. Wenn dein Team klein ist und der Betriebsaufwand die Produktarbeit verdrängen würde, ist [Cloud](/de/cloud) die andere Form desselben Produkts. Wenn du gerade eine frische Instanz aufsetzt, ist [Quickstart](/de/self-hosted/install/quickstart) der richtige nächste Lesestoff. # Upgrades Source: https://tale.dev/docs/de/self-hosted/operate/upgrades Upgrades auf einer self-hosted Tale-Instanz laufen durch zwei Kommandos: `tale update` bewegt das CLI-Binary auf die neue Version und synct deine Projektdateien passend dazu, dann rollt `tale deploy` die Plattform-Container. Der Deploy nutzt ein Blue-Green-Pattern — die neue Farbe startet neben der alten, Healthchecks bestehen, der Traffic kippt, die alte Farbe drainet. Zero-Downtime ist der Default; macht ein Patch-Release Ärger, bringt `tale rollback` den vorherigen Patch in einem Kommando zurück, und alles Größere recovert aus dem Pre-Upgrade-Snapshot. **Eine harte Ausnahme:** Von 0.3.x auf 0.4 gibt es keinen Upgrade-Pfad. 0.4 ist ein Breaking Cutover, der ein frisches Deployment verlangt — lies zuerst [0.3 → 0.4: Breaking Cutover](#03--04-breaking-cutover), wenn deine Instanz auf 0.3.x läuft. Was du nicht mehr tust, ist das CLI von Hand im Gleichschritt zu halten: Das CLI gleicht sich automatisch an die Instanz an (siehe unten), sodass der einzige bewusste Schritt die Wahl ist, wann du mit `tale update` die Version wechselst. Die CLI-Installation lebt in [Tale-CLI installieren](/de/self-hosted/install/cli-install). Diese Seite deckt ab, was jedes Kommando tut und wie das Versions-Modell funktioniert. ## Das CLI verfolgt die Instanz automatisch Das CLI-Binary hat immer dieselbe Version wie die Instanz, die es verwaltet. Der Workspace zeichnet diese Version in `tale.json` auf; bei jedem Kommando vergleicht das CLI seine eigene Version dagegen und aktualisiert sich selbst — auf- oder abwärts —, falls sie sich unterscheiden, bevor es läuft. Stimmen sie schon überein — der ganz überwiegend häufige Fall —, ist das ein No-op ohne Netzwerk-Aufruf, sodass du nie etwas davon merkst. Das heißt, du läufst `tale update` selten, außer wenn du bewusst auf eine neue Version willst. Ein Teamkollege, der ein neueres CLI als deine Instanz installiert hat, oder einen älteren Snapshot wiederhergestellt hat, bekommt beim nächsten Kommando automatisch die richtige CLI-Version. Es gibt kein Flag, das abzuschalten — Tool und Instanz im Gleichschritt zu halten ist das, was Deploys sicher macht. ## Bevor du upgradest Zwei Dinge sind es wert, zuerst zu bestätigen: - Deine Off-Host-Kopie des `backups`-Volumes ist aktuell — siehe [Backups und Restore](/de/self-hosted/operate/backups-and-restore). `tale update` snapshotet die Daten-Volumes automatisch vor jedem Schritt, der Daten migrieren kann, aber der Snapshot lebt auf demselben Host; die Off-Host-Kopie ist das, was eine tote Platte überlebt. - Die Release-Notes für die Zielversion nennen keinen breaking Change. Die Notes sind von der GitHub-Release-Seite verlinkt; breaking Changes sind oben als solche markiert. Überschreitet das Upgrade eine Major-Version (1.x → 2.x), lies die Migrations-Notes End-to-End, bevor du anfängst. Major-Versionen sind, wo Schema-Migrationen und Config-Datei-Format-Änderungen landen. ## Die zwei Kommandos `tale update` aktualisiert das CLI-Binary und synct dann deine Projektdateien auf die Templates dieser Version. Es fasst die laufenden Container **nicht** an — das ist der Job von `tale deploy`. Scheitert der Datei-Sync, rollt das CLI sein eigenes Binary auf die Version zurück, auf der dein Workspace war, sodass Binary und `tale.json` nie auseinanderdriften. Ohne Argumente zielt das Kommando auf das neueste Release **innerhalb deiner aktuellen x.y-Release-Linie** — eine 0.3.x-Instanz bewegt sich auf das neueste 0.3.x. Releases auf einer neueren Linie können breaking Changes tragen, deshalb überquert `tale update` diese Grenze nie von selbst: Existiert eine neuere Linie, sagt es das und bleibt stehen. Der Linienwechsel ist ein bewusster Schritt — lies zuerst die Release-Notes der neuen Linie und nagle die Zielversion dann mit `--version` fest. ```bash # Bewege das CLI und die Projektdateien auf das neueste Release der aktuellen x.y-Linie tale update # Eine bestimmte Version festnageln — der einzige Weg, die Linie zu wechseln (erlaubt Downgrades — siehe Zurückrollen) tale update --version 0.10.2 # Versions-Wechsel und Datei-Sync vorab ansehen, ohne etwas anzufassen tale update --dry-run ``` `tale deploy` macht den eigentlichen Rolling-Restart und deployt immer die eigene Version des CLI — die dank der Angleichung die Version ist, die dein Workspace aufzeichnet. Es sortiert die Services in drei Tiers: - **App-Tier** — `platform` — rollt bei **jedem** Deploy ohne Downtime (Blue-Green: die neue Farbe startet neben der alten, Healthchecks bestehen, der Traffic kippt, die alte Farbe drainet). - **Backend und Compute** — `convex`, `sandbox`, `sandbox-egress` — rollen ebenfalls bei jedem Deploy, sodass sie nie gegenüber `platform` versions-skewen. Jeder ist ein einzelner Container, der sich **in-place** neu erstellt, wenn sich sein Image tatsächlich geändert hat; der Deploy drainet zuerst die laufende Arbeit (Chat-Generierungen bei `convex`, Agent-Runs bei `sandbox`), damit der kurze Neustart keine lebende Anfrage abschneidet. - **Stop-gegateter Tier** — `db`, `proxy` — bleibt standardmäßig **laufend und unangetastet** (Postgres oder den Proxy neu zu erstellen ist eine kurze Ausfallzeit, die du bei einem Routine-Roll nicht willst). Mit `--stop` aktualisierst du sie; der Deploy warnt und nennt sie, wenn er sie überspringt. ```bash # Nach tale update die Container passend rollen (App-Tier + convex) tale deploy # Auch db/proxy aktualisieren (kurze Downtime, während sie neu erstellt werden) tale deploy --stop # Nur bestimmte Services rollen tale deploy --services platform # Vorschau ohne Änderungen tale deploy --dry-run ``` `--dry-run` ist es wert, vor jedem Produktions-Upgrade zu laufen — es bringt fehlende Images, fehlende Migrationen und Dependency-Mismatches zum Vorschein, ohne die laufenden Container zu berühren. ## Das Blue-Green-Pattern Eine laufende Instanz ist zu jeder Zeit eine der zwei Farben (Blue oder Green). Die Deploy-Phase bringt die andere Farbe hoch, wartet, bis sie Healthchecks besteht, und kippt dann Caddys Upstream auf die neue Farbe. Die alte Farbe drainet ihre in-flight-Anfragen (Default 30 s), dann beendet sie sich. Drei Garantien, die das Pattern dir gibt: - **Kein Fenster, in dem beide Farben Traffic servieren.** Ein Datenbank-Constraint setzt single-active durch — Caddy routet zur gesunden. - **Patch-Rollback ist ein Kommando.** `tale rollback` deployt das vorherige Patch-Release auf der inaktiven Farbe neu und kippt den Traffic zurück. Minor- und Major-Downgrades verweigert es — die können die Datenbank vor dem Binary zurücklassen, und ihr Recovery-Pfad ist ein Snapshot-Restore. - **Gescheiterte Healthchecks blockieren den Kipp.** Besteht die neue Farbe nicht innerhalb des Timeouts, bricht der Deploy ab und die alte Farbe serviert weiter. Die vollständige Deploy-Prozedur inklusive der Cleanup-Phase lebt in `tale --help`; das operatorseitige Rezept ist `tale update && tale deploy && tale status` und visuelle Bestätigung im Browser. ## Mit Datenmigrationen arbeiten Die Migrationskette beginnt an der **0.4.0-Baseline**: Releases ab 0.4.0 tragen versionierte Migrationen für die Änderungen, die sie ausliefern, und nichts Älteres — die Prä-0.4-Historie steckt in keinem Binary (genau das macht den 0.3 → 0.4 Cutover breaking). Innerhalb der 0.4.x-Linie wendet jedes Deploy ausstehende Datenmigrationen automatisch an — aber nur die nicht-destruktiven. Migrationen, die Daten entfernen oder überschreiben (ein Tabellen-Drop, eine entfernte Spalte), laufen nie unbeaufsichtigt: Das Deploy überspringt sie, listet auf, welche warten, und überlässt dir die Entscheidung. ```bash # Was angewendet ist, was aussteht, was fehlgeschlagen ist tale migrate status # Ausstehende Migrationen anwenden, jeden destruktiven Schritt einzeln prüfen tale migrate up --step # Alles ohne Rückfragen anwenden (CI / nach Prüfung des Plans) tale migrate up --yes # Daten auf eine frühere Version zurückrollen (0.4.0 oder neuer) tale migrate down --to 0.4.0 ``` Destruktive Migrationen sichern die betroffenen Zeilen bzw. Konfigurationsdateien, bevor sie sie anfassen — `tale migrate down` kann so wiederherstellen, was sie entfernt haben. Beide Richtungen sind fortsetzbar: Der Fortschritt wird pro Migration festgehalten (bei Konfigurationsdatei-Migrationen pro Organisation), ein Absturz oder Timeout setzt also dort wieder an, wo er unterbrochen wurde. Schlägt eine Migration während eines Deploys fehl, bootet die Plattform trotzdem auf ihrem aktuellen Schema — das Boot-Log zeigt einen deutlichen Fehler, und `tale migrate status` nennt die fehlgeschlagene Migration samt Fehlermeldung. Ursache beheben, dann `tale migrate up` erneut ausführen; bereits erledigte Arbeit wird übersprungen. ## Zurückrollen ```bash # Zurück zur vorherigen Patch-Version (fragt nach Bestätigung) tale rollback # Die Abfrage im nicht-interaktiven Betrieb überspringen tale rollback --yes ``` `tale rollback` ist auf Patch-Schritte begrenzt: Es zielt nur auf die aufgezeichnete vorherige Version und verweigert, wenn diese Version nicht `major.minor` mit der laufenden Plattform teilt. Patch-Releases tragen nie Migrationen, also ist das Redeploy des vorherigen Patches immer sicher. Alles Größere kann Daten vorwärts migriert haben — ein älteres Binary auf migrierten Daten zu deployen korrumpiert die Instanz, statt sie zu retten. Für diese Fälle ist der Recovery-Pfad, den Pre-Upgrade-Snapshot wiederherzustellen und mit `tale update --version <version>` gefolgt von `tale deploy --stop` (sodass `db`/`proxy` ebenfalls zurückrollen) auf die passende Version zurückzugehen; die Verweigerungs-Meldung druckt die exakten Kommandos, und der volle Walk lebt in [Backups und Restore](/de/self-hosted/operate/backups-and-restore). Weil das Zurückrollen die laufenden Container abräumt, warnt das Kommando, was es vorhat, und fragt nach Bestätigung, bevor es auch nur ein Image zieht; mit `--yes` überspringst du diese Abfrage in Skripten oder CI. ## Versions-Kompatibilität Tale-Versionen sind semver. Die Kompatibilitäts-Regeln: - Patch (`0.9.0 → 0.9.1`) — keine Migrationen, keine Config-Änderungen, `tale rollback` ist immer sicher. - Minor (`0.9.x → 0.10.x`) — kann forward-only Migrationen enthalten; `tale rollback` verweigert, Recovery ist Snapshot-Restore plus Redeploy. - Major (`0.x → 1.x`) — lies die Migrations-Notes, plan das Wartungsfenster, erwarte Überraschungen. - **Die 0.4.0-Baseline** — Versionen unter 0.4.0 und Versionen ab 0.4.0 sind getrennte Welten: kein Upgrade in keine Richtung, siehe den Cutover-Abschnitt unten. Minor-Versionen zu überspringen (von 0.9 auf 0.11 zu gehen) ist unterstützt, solange die Zwischen-Migrationen noch im Binary sind; die Release-Notes nennen es, wenn das nicht der Fall ist. Die 0.4.0-Baseline ist der Dauerfall dieser Ausnahme: Prä-0.4-Migrationen stecken in keinem 0.4+-Binary. Um bewusst eine Version _runter_ zu gehen — etwa wenn ein Minor-Release Ärger macht und du seine Migrationen schon zurückgenommen hast —, nagle das Ziel mit `tale update --version <version>` fest. Das Kommando warnt, wenn das Ziel älter als die laufende Version ist, und erinnert dich, zuerst die Daten-Migrationen zurückzunehmen. Ein Downgrade unter 0.4.0 kreuzt den Cutover rückwärts und ist nicht unterstützt: Ein 0.3.x-Release kann von 0.4+ erzeugte Daten nicht lesen — stelle einen Prä-0.4-Snapshot wieder her oder deploye 0.3.x frisch. ## 0.3 → 0.4: Breaking Cutover 0.4 hat das KI-Backend der Plattform — und damit das Datenmodell — von einer sauberen Baseline neu aufgebaut. Die versionierte Migrations-Historie wurde bei 0.4.0 zurückgesetzt: Kein 0.4+-Release trägt die Prä-0.4-Migrationen, also **lässt sich eine 0.3.x-Instanz nicht in-place upgraden — 0.4 verlangt ein frisches Deployment.** **Was das praktisch heißt:** - `tale deploy` mit einem 0.4+-CLI **verweigert** jede Instanz, deren laufende Version unter 0.4.0 liegt — bevor ein Image gezogen oder irgendetwas geschrieben wird. Der Container trägt dieselbe Wache beim Boot (Log-Marker `[migrations][breaking-cutover]`) für Stacks, die außerhalb des CLI verwaltet werden. - Nichts aus einer 0.3-Instanz wird übernommen: Chats, Automationen samt Lauf-Historie, Wissenseinträge, Aufgaben-Historie, Benutzer und Anmeldungen. Dateien in einem BYO-S3-Bucket bleiben physisch im Bucket, aber die neue Instanz hat keine Referenzen darauf. - Die 0.3.x-Linie bleibt für Sicherheits- und kritische Fixes auf dem Branch `release/0.3` gepflegt — eine Weile auf 0.3.x zu bleiben ist ein unterstützter Weg; der Wechsel auf 0.4 ist ein Re-Onboarding, kein Upgrade. **Der Weg auf 0.4:** ```bash # 1. Die 0.3-Instanz unangetastet lassen (sie bedient weiter). # 2. Ein NEUES Projektverzeichnis mit einem 0.4-CLI anlegen: mkdir tale-04 && cd tale-04 tale init tale deploy # 3. Re-Onboarding: Organisationen, Benutzer (Einladung / SSO), # Konfiguration, Dokumente und Wissen neu hochladen. # 4. Die 0.3-Instanz stilllegen, sobald die neue abgenommen ist. ``` Der Experten-Override — `tale deploy --accept-data-loss` bzw. `TALE_ACCEPT_DATA_LOSS=1` am Container — existiert für den seltenen Fall, dass du bewusst einen Host wiederverwendest, dessen alte Volumes du bereits behandelt hast. Er tut genau, was sein Name sagt: Prä-0.4-Daten dieser Instanz werden dauerhaft unlesbar. ## Wo das hingehört Der Upgrade-Flow knüpft jede andere Operate-Seite an — Backups sind das, was ein gescheitertes Upgrade wiederherstellbar macht, Observability ist das, was dir sagt, dass die neue Farbe healthy ist, Hardening ist das, was du nach einer Major-Version neu durchgehst. Setzt du das CLI zum ersten Mal auf, deckt [Tale-CLI installieren](/de/self-hosted/install/cli-install) das workstationseitige Setup ab; nimmst du den Pager mitten im Rollout auf, nennt [Troubleshooting](/de/self-hosted/operate/observability/troubleshooting) die Symptome. # Troubleshooting Source: https://tale.dev/docs/de/self-hosted/operate/observability/troubleshooting Diese Seite ist das symptomorientierte Nachschlagen, wenn jetzt gerade etwas falsch ist. Jeder Abschnitt fängt mit dem an, was der Benutzer tatsächlich meldet — was der Browser zeigt, woran der Agent scheitert, was der Upload-Bildschirm sagt — und geht zurück zur Ursache und zum Fix. Alles, was hier nicht gelistet ist, ist ein Kandidat für einen neuen Abschnitt, sobald es zweimal aufgetaucht ist. Die proaktive Seite — Signale, auf die zu alarmieren sich lohnt, was in Prometheus zu verdrahten ist — lebt in [Operations](/de/self-hosted/operate/observability/operations). Diese Seite ist für den Moment, nachdem die Page gefeuert hat. ## Browser sieht 502 oder „Bad Gateway" Der `tale-proxy`-Container hat die Plattform erreicht, aber die Plattform hat nicht geantwortet. Entweder ist `tale-platform` down oder sein Health-Endpoint unerreichbar. Prüf zuerst den Container-Zustand: ```bash docker compose ps tale-platform docker compose logs --tail=200 tale-platform ``` Startet der Container neu, zeigen die Logs am Boden den Crash-Grund — meist eine fehlkonfigurierte Env-Var (`SITE_URL`-Mismatch, fehlender `BETTER_AUTH_SECRET`) oder ein Postgres-Verbindungsfehler. Fix die Env, starte neu, versuche es erneut. Ist der Container healthy, aber der Browser sieht immer noch 502, ist der Proxy der Verdächtige — `docker compose restart tale-proxy` räumt die meisten davon weg. ## Browser sieht eine TLS-Warnung `TLS_MODE=selfsigned` ist die häufigste Ursache — der Browser vertraut der internen CA von Caddy beim ersten Besuch nicht. Vertrau entweder der CA auf dem Host (`docker exec tale-proxy caddy trust`) oder wechsel zu `TLS_MODE=letsencrypt` für ein echtes Zertifikat. Der vollständige Modus-Walk lebt in [TLS und Domains](/de/self-hosted/configuration/tls-and-domains). Ist der Modus bereits `letsencrypt`, prüf die Proxy-Logs auf ACME-Fehlschläge — DNS löst nicht auf die öffentliche IP des Hosts und Port 80 ist vom öffentlichen Internet nicht erreichbar sind die zwei häufigen Ursachen. ## UI lädt, aber keine Daten erscheinen Die UI-Shell sind statische Assets, von `tale-platform` serviert; alles andere fliesst durch `tale-convex` über einen WebSocket. Wenn der WebSocket sich nicht verbinden kann, lädt die Shell und bleibt leer. Symptome: Spinner, die nie auflösen, „reconnecting"-Toasts, der Chat-Input, der nie eine Nachricht annimmt. ```bash docker compose logs --tail=200 tale-convex ``` Der Convex-Container startet wahrscheinlich neu (such nach `panic` in den Logs) oder ist vom Proxy unerreichbar. Starte mit `docker compose restart tale-convex` neu — Sessions sind serverseitig, und Clients reabonnieren beim Reconnect, also ist der Restart sicher. ## Uploads stecken in „indexing" Die Dokument-Ingestion läuft im Convex-Backend und schreibt die extrahierten Chunks und Embeddings in die Datenbank des Wissens-Korpus. Ein langer „indexing"-Zustand bedeutet entweder, dass das Backend `tale-knowledge-db` nicht erreicht oder dass die Datei selbst nicht extrahiert werden konnte. Prüf zuerst die Convex-Logs und die Korpus-Datenbank: ```bash docker compose logs --tail=200 tale-convex | grep -iE "knowledge|ingest|embed" docker compose ps tale-knowledge-db ``` Zeigen die Logs Verbindungsfehler zu `knowledge-db`, starte die Korpus-Datenbank neu (`docker compose restart tale-knowledge-db`); die Ingestion versucht es beim nächsten Durchlauf erneut, Uploads müssen also nicht erneut eingereicht werden. Ist die Datenbank healthy, aber ein bestimmter Upload steckt, ist die Datei selbst der Verdächtige — beschädigte PDFs und passwortgeschützte Dokumente landen in einem Fehlzustand und brauchen Löschung und Re-Upload. ## Chat-Antworten hören mitten im Stream auf Der Token-Stream vom Upstream-Anbieter ist abgefallen — entweder hat der Anbieter rate-limited, die Verbindung ist getimeoutet, oder der Service des Anbieters ist degradiert. Prüf zuerst die Status-Seite des Anbieters; schau dann in die Plattform-Logs: ```bash docker compose logs --tail=200 tale-platform | grep -E "429|503|stream" ``` Ein `429` ist der häufige Fall. Entweder trifft das Budget der Org das Rate-Limit des Anbieters, oder der Anbieter-Schlüssel selbst ist gedrosselt. Das Default-Modell der Org auf einen weniger ausgelasteten Anbieter umzuschalten räumt das Symptom weg, während das Upstream abkühlt. ## Speichern scheitert mit „saving failed"-Toast Der Convex-Container konnte nicht in Postgres schreiben. Entweder ist `tale-db` down oder seine Platte ist voll: ```bash docker compose ps tale-db docker compose exec db df -h /var/lib/postgresql/data ``` Eine Platte bei 100 % ist der Fehler, der die meisten überraschten Gesichter erzeugt. Schaff Platz, starte `tale-db` neu, und die gepufferten Writes flushen. Hat die Platte Platz, ist der Verdächtige Verbindungs-Pool-Erschöpfung oder ein Lock — starte `tale-convex` neu, um den Pool zu räumen. ## „Run code"-Tool scheitert mit „egress denied" Der `tale-sandbox-egress`-Container ist der einzige ausgehende Netzwerk-Pfad für sandboxierten Code; ist er down oder fehlkonfiguriert, scheitert jede ausgehende Anfrage aus der Sandbox geschlossen. Prüf zuerst den Egress-Container: ```bash docker compose ps tale-sandbox-egress docker compose logs --tail=100 tale-sandbox-egress ``` Ist der Container healthy und du hast `SANDBOX_EGRESS_ALLOWLIST` gesetzt, hat die Anfrage die Allowlist getroffen — erweitere die Variable in `.env` und erzeuge `tale-sandbox-egress` neu. Ohne Allowlist ist der Proxy auf Hostname-Ebene offen; prüf stattdessen das Ziel: für HTTPS wird nur Port 443 getunnelt, und Cloud-Metadaten-Adressen sowie private Adressbereiche sind auf IP-Ebene immer blockiert. ## Sign-in läuft zurück in die Sign-in-Seite `SITE_URL` passt nicht zu dem, was der Browser tatsächlich angefragt hat. Auth-Cookies sind auf die URL gescopt, auf der die Anfrage landete; ein Mismatch (Trailing Slash, fehlender Port, `http` vs `https`, Base-Path-Präfix) bedeutet, dass das beim Callback gesetzte Cookie bei der nächsten Anfrage nicht mitgeschickt wird. Fix `.env`: ```bash SITE_URL=https://tale.example.com # exakt, was der Benutzer tippt ``` Erstell den Plattform-Container neu (`docker compose up -d --force-recreate tale-platform`), damit die Änderung im gerenderten HTML landet. ## Wo du Hilfe bekommst Self-hosted-Instanzen telefonieren nicht heim, also fängt Support bei dir an. Die zwei Kanäle: - **GitHub Issues** — Bugs und reproduzierbare Probleme. Der [tale-project/tale](https://github.com/tale-project/tale/issues)-Tracker hat ein Template, das nach dem Diagnose-Bundle fragt, das `tale diagnostics` produziert. - **Discord** — Fragen, Konfigurations-Debatten, „ist das ein Bug"-Triage. Die Einladung lebt im Repo-README. Reproduzierbare Diagnose macht jeden Kanal schneller. `tale diagnostics` sammelt sanitised Logs, Env-Vars (Secrets redigiert) und Container-Health in ein einzelnes Archiv, das es wert ist, angehängt zu werden. # Operations Source: https://tale.dev/docs/de/self-hosted/operate/observability/operations Die Operations-Seite ist das Alert-Playbook — welche Signale es wert sind, jemanden zu wecken, welche eine Kaffee-Runde überstehen können und wie die ersten fünf Minuten eines Vorfalls aussehen. Die Metrik-Oberfläche von Tale lebt hinter `METRICS_BEARER_TOKEN`; diese Seite nimmt an, dass du Prometheus und Grafana gemäss [Observability-Konfiguration](/de/self-hosted/configuration/observability-config) verdrahtet hast und jetzt wissen musst, welche Zahlen du beobachtest. Der symptomorientierte Index ist in [Troubleshooting](/de/self-hosted/operate/observability/troubleshooting). Diese Seite ist die proaktive Seite — Signale zuerst, Oncall-Checkliste zweitens. ## Signale, auf die zu alarmieren sich lohnt | Signal | Schweregrad | Warum es zählt | | ------------------------------------------- | ----------- | ---------------------------------------------------------- | | `tale-proxy`-Health-Probe scheitert > 1 Min | page | Jeder Benutzer sieht einen Verbindungsfehler | | `tale-platform` HTTP-5xx-Rate > 5 % | page | Die UI ist für einen relevanten Anteil der Anfragen kaputt | | `tale-convex` WebSocket-Reconnect-Storm | page | UI lädt, aber keine Daten fliessen | | Postgres-Verbindungen > 80 % des Pools | warn | Die nächste Spitze fängt an zu blockieren | | `db-data`-Volume > 80 % voll | warn | Das operative Postgres geht bei voll auf read-only | | `knowledge-db-data`-Volume > 80 % voll | warn | Ingestion scheitert, wenn die Korpus-Datenbank voll ist | | `tale-knowledge-db` von convex unerreichbar | warn | Wissens-Suche liefert leer; Ingestion stockt | | Anbieter-Anfrage-Fehlerrate > 20 % | warn | Der Upstream-LLM-Anbieter hat einen schlechten Tag | | Tägliches Backup nicht geschrieben | page | Restore-Drill scheitert zum schlimmsten Zeitpunkt | | TLS-Cert-Erneuerung gescheitert | warn | Erneuert 30 T vor Ablauf — du hast Zeit | Die ersten zwei Pages sind die wirklich kundenwirksamen. Die warns fangen Trends, bevor sie ins Page-Gebiet kippen. ## Log-Signale, nach denen man greppen sollte Logs kommen über stdout pro Container, aufgefangen vom `json-file`-Driver von Docker. Die vier Phrasen, die konsistent Ärger bedeuten: - `panic` oder `unexpected error` in `tale-convex`-Logs — Convex-Action-Crash. - `decryption failed` in `tale-platform`-Logs — SOPS-age-Schlüssel-Mismatch mit der Datei auf Platte. - `429 Too Many Requests` wiederholt von einem Anbieter — Rate-Limit getroffen, Agents fangen an zu scheitern. - `connection refused` oder `ECONNREFUSED` zu `knowledge-db` in `tale-convex`-Logs — das Backend erreicht die Korpus-Datenbank nicht; Ingestion und Wissens-Suche scheitern. Leite diese als abgeleitete Alerts an deinen Aggregator weiter; die Metric-Endpoints zeigen sie nicht als Gauges. ## Oncall-Checkliste Wenn eine Page landet, folgen die ersten fünf Minuten jedes Mal derselben Form. 1. **Bestätige, dass der Alert echt ist.** Öffne `$SITE_URL` im Browser. Lädt die UI und Chat funktioniert, schaust du auf ein Metrik- oder Scraper-Problem, nicht ein kundenwirksames. 2. **Identifiziere den Container.** `docker compose ps` zeigt, welcher unhealthy ist; `docker compose logs --tail=200 <service>` zeigt den letzten Fehler. 3. **Starte den wahrscheinlichsten Schuldigen neu.** `docker compose restart <service>` löst einen überraschenden Anteil der Vorfälle — Prozess-Crashes, abgestandene File-Watcher, erschöpfte Verbindungs-Pools. Die Architektur ist gebaut, um einen einzelnen Container-Restart sauber zu überleben. 4. **Prüf Upstream-Anbieter.** `https://status.openai.com`, `https://status.anthropic.com`, etc. Brennt der Anbieter, scheitern Agents; Tale ist nicht die Ursache. 5. **Page die diensthabende Ingenieurin, wenn das benutzerwirksame Symptom nach einem Restart bleibt.** Nicht früher eskalieren — die meisten Vorfälle lösen sich in den ersten drei Schritten. ## Was Oncall nicht braucht Ein `tale-knowledge-db`-Ausfall ist ein warn, kein page. Der Web-Crawl-Plan absorbiert Stunden von Downtime ohne Benutzerwirkung, und die Dokument-Ingestion versucht es erneut, statt Arbeit zu verwerfen — Uploads sitzen in „indexing", bis die Korpus-Datenbank zurück ist. Die Wissens-Suche liefert in der Zwischenzeit leer, aber Chats, die kein Wissen abrufen, arbeiten weiter. Fang das im warn-Band und fix es zu Geschäftszeiten. ## Antwortzeit-SLAs Zwei Antwortzeit-Budgets werden als erstklassige Signale verfolgt: interaktive Dialog-Eingabe und langlaufende Operationen wie Evaluierungen. Beide werden als **Mittelwert** über ein gleitendes Fenster verifiziert — die vertragliche Zahl ist ein Durchschnitt, keine Obergrenze pro Anfrage — und beide sind so verdrahtet, dass Prometheus alarmiert, sobald der Durchschnitt über das Budget driftet. | Budget | Statistik | Ziel | Fenster | Zugrundeliegende Serie | | --------------- | ---------- | ----- | ------- | ----------------------------- | | Dialog-Eingabe | Mittelwert | ~1 s | 30 Min | `tale_dialog_ttft_seconds` | | Lange Operation | Mittelwert | ~40 s | 6 Std | `tale_long_operation_seconds` | Jedes Ziel reitet zudem auf dem Plattform-Metrik-Endpoint als `tale_sla_target_seconds{sla,statistic}`, sodass ein Grafana-Panel die Budget-Linie direkt aus Prometheus zeichnet, statt sie fest zu verdrahten. Die zugrundeliegenden Latenz-Serien sind die Convex-Funktions-Ausführungs-Histogramme auf `/metrics/convex`; relabel oder record sie auf die Namen oben, damit die Rules auflösen. Die Plattform liefert die fertigen Recording- und Alerting-Rules unter `/metrics/sla-rules` (hinter demselben Bearer-Token wie die anderen Metrik-Pfade) — hole sie einmal und referenziere die Datei unter `rule_files:`, oder füge das Äquivalent ein: ```yaml groups: - name: tale-sla-recording rules: - record: tale_sla_dialog_ttft:mean30m expr: rate(tale_dialog_ttft_seconds_sum[30m]) / rate(tale_dialog_ttft_seconds_count[30m]) labels: sla: dialog_ttft - record: tale_sla_long_operation:mean6h expr: rate(tale_long_operation_seconds_sum[6h]) / rate(tale_long_operation_seconds_count[6h]) labels: sla: long_operation - name: tale-sla-alerts rules: - alert: TaleSlaDialogTtftBreached expr: tale_sla_dialog_ttft:mean30m > 1 for: 15m labels: severity: warn sla: dialog_ttft annotations: summary: 'Dialog input response time: mean response time over 30m exceeds the 1s SLA' description: Mean time-to-first-token for an interactive chat / dialog turn. - alert: TaleSlaLongOperationBreached expr: tale_sla_long_operation:mean6h > 40 for: 30m labels: severity: warn sla: long_operation annotations: summary: 'Long operation response time: mean response time over 6h exceeds the 40s SLA' description: Mean end-to-end time for long-running operations such as evaluations. ``` Ein Breach hier ist ein **warn**, kein page: ein driftender Durchschnitt ist eine Degradation, die zu Geschäftszeiten zu verfolgen ist, und die `for:`-Fenster warten bewusst eine kurze Spitze aus, bevor sie feuern. Das ~1-s-Dialog-Budget versöhnt sich mit dem lockereren ~3-s-Warm-Time-to-First-Token im manuellen Performance-Plan — jene ~3 s sind eine Obergrenze pro Anfrage für ein einzelnes kaltes, Auto-geroutetes erstes Token (das erste Text-Delta per Provider-SSE) inklusive Modell- und Netzwerk-Zeit, während die ~1 s hier der Steady-State-Mittelwert über Dialog-Turns ist, sodass gelegentliche erste Tokens, die die Obergrenze erreichen, mit einem Sub-Sekunden-Mittelwert vereinbar sind. Den 1-s-Mittelwert auf Live-Anbietern zu halten, kann noch die Backend-Overhead-Optimierung brauchen, die im Feature-Issue verfolgt wird; dieser Alert bestätigt, ob das Ziel erreicht ist. ## Wo das hingehört Die Signale oben sind die proaktive Seite des Betreibens einer Tale-Instanz; die reaktive Seite ist [Troubleshooting](/de/self-hosted/operate/observability/troubleshooting), und die Konfiguration, die die Metriken in Prometheus bekommt, ist [Observability-Konfiguration](/de/self-hosted/configuration/observability-config). Hast du `METRICS_BEARER_TOKEN` noch nicht gesetzt, ist jede Schwelle oben unbeobachtet — fang dort an. # Prometheus und Grafana Source: https://tale.dev/docs/de/self-hosted/operate/observability/prometheus-grafana Das ist das durchgespielte Beispiel hinter [Observability-Konfiguration](/de/self-hosted/configuration/observability-config): ein Paar aus Prometheus und Grafana, das du neben Tale stellst, auf die zwei Bearer-Token-Metrics-Endpoints gerichtet, mit einem Starter-Dashboard und einer Alert-Regel zum Ausbauen. Es ist für selbst hostende Betreiber, die `METRICS_BEARER_TOKEN` bereits gesetzt haben und jetzt Live-Graphen statt eines `curl` gegen `/metrics` wollen. Die Konfigurations-Referenzseite listet die Endpoints und die einzelne Scrape-Stanza; diese Seite stellt den ganzen Stack von Anfang bis Ende auf. Alles hier läuft auf demselben Host wie Tale, also verlässt keine Metrik die Maschine. ## Bevor du startest Setz `METRICS_BEARER_TOKEN` in deiner `.env` und starte den Proxy neu — ohne ihn geben die zwei Endpoints auf jede Anfrage 401 zurück, und Prometheus zeigt jedes Target als down. Die Endpoints, und was jeder trägt, sind die Tabelle in [Observability-Konfiguration](/de/self-hosted/configuration/observability-config#metrics): `/metrics/platform` und `/metrics/convex` (Letzterer trägt jetzt die In-Process-RAG- und Crawl-Timings), beide von `tale-proxy` über denselben Hostnamen wie die App ausgeliefert. ## Prometheus und Grafana zu deinem Stack hinzufügen Leg diese zwei Services in ein Compose-Override neben Tale. Prometheus scrapt in einem Intervall und speichert eine lokale TSDB; Grafana liest Prometheus und rendert die Dashboards. Beide binden nur an localhost — erreich Grafana über einen SSH-Tunnel oder stell es mit Auth hinter denselben Proxy, exponier es nie roh. ```yaml # docker-compose.metrics.yml — start with: docker compose -f docker-compose.yml -f docker-compose.metrics.yml up -d services: prometheus: image: prom/prometheus:v3.1.0 volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro - prometheus-data:/prometheus ports: - '127.0.0.1:9090:9090' restart: unless-stopped grafana: image: grafana/grafana:11.4.0 environment: GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD:?set a strong password} GF_USERS_ALLOW_SIGN_UP: 'false' volumes: - grafana-data:/var/lib/grafana ports: - '127.0.0.1:3001:3000' restart: unless-stopped volumes: prometheus-data: grafana-data: ``` ## Scrape-Konfiguration Tales zwei Endpoints teilen sich ein Bearer-Token, also ist die Scrape-Konfiguration die veröffentlichte Stanza, einmal pro Pfad wiederholt. Speicher das als `prometheus.yml` neben dem Override oben und setz deinen Host und dein Token ein — Prometheus liest das Token aus der Datei, also halt sie `chmod 600` und aus der Versionskontrolle raus. ```yaml global: scrape_interval: 30s scrape_configs: - job_name: tale-platform scheme: https metrics_path: /metrics/platform authorization: { credentials: '${METRICS_BEARER_TOKEN}' } static_configs: - targets: ['tale.example.com'] - job_name: tale-convex scheme: https metrics_path: /metrics/convex authorization: { credentials: '${METRICS_BEARER_TOKEN}' } static_configs: - targets: ['tale.example.com'] ``` Öffne `http://127.0.0.1:9090/targets` nach dem Start — beide Jobs sollten **UP** anzeigen. Ein Target, das mit 401 auf **DOWN** hängt, heisst, das Token in `prometheus.yml` stimmt nicht mit `METRICS_BEARER_TOKEN` überein; ein Verbindungsfehler heisst, Hostname oder Schema sind falsch. ## Ein Starter-Dashboard Richte Grafana zuerst auf Prometheus — füg eine Prometheus-Datenquelle unter `http://prometheus:9090` hinzu (Grafana erreicht sie über den Compose-Servicenamen). Bau dann ein Dashboard aus diesen Panels; die ersten drei nutzen Metriken, die immer vorhanden sind, und der Rest bildet die Signale in [Operations](/de/self-hosted/operate/observability/operations) ab. | Panel | Query | Liest sich als | | --------------- | ---------------------------------------------------- | ------------------------------------------------------------ | | Targets up | `up{job=~"tale-.*"}` | `1` pro gesundem Endpoint, `0` wenn das Scraping fehlschlägt | | Platform-Memory | `process_resident_memory_bytes{job="tale-platform"}` | Resident-Memory des platform-Containers | | Event-Loop-Lag | `nodejs_eventloop_lag_seconds{job="tale-platform"}` | Springt, wenn die Plattform gesättigt ist | | Convex up | `up{job="tale-convex"}` | Backend-Erreichbarkeit — `0` ist ein Page | Der platform-Endpoint trägt Nodes Default-Prozessmetriken (CPU, Memory, Event-Loop-Lag, GC), darum zielen die konkreten Queries oben auf ihn. Der Convex-Endpoint exponiert seine eigene reichere Reihe, inklusive der In-Process-RAG- und Crawl-Timings — öffne ihn einmal (`curl -H "Authorization: Bearer $TOKEN" https://tale.example.com/metrics/convex`), um die exakten Metriknamen deiner Version zu lesen, und füg dann Panels für den Wissens-Ingestion-Durchsatz und die Provider-Fehlerrate aus Operations hinzu. ## Eine erste Alert-Regel Fang mit dem einen Signal an, das eindeutig ist — ein Metrics-Target, das aufhört zu antworten. Füg diese Regel-Datei zu Prometheus hinzu (mounte sie und referenzier sie unter `rule_files:` in `prometheus.yml`), dann verdrahte Alertmanager oder Grafana-Alerting mit deinem Pager. ```yaml groups: - name: tale rules: - alert: TaleTargetDown expr: up{job=~"tale-.*"} == 0 for: 2m labels: { severity: page } annotations: summary: 'Tale metrics target {{ $labels.job }} is down' ``` Die volle Liste, was ein Page wert ist gegenüber was warten kann — platform-5xx-Rate, Postgres-Pool-Sättigung, Erreichbarkeit der Wissensdatenbank, tägliches-Backup-nicht-geschrieben — ist die Signaltabelle in [Operations](/de/self-hosted/operate/observability/operations); übersetz jede Zeile in eine Regel, sobald die passende Reihe auf deinem Dashboard ist. ## Wo das hingehört Diese Seite verwandelt die zwei dokumentierten Metrics-Endpoints in einen laufenden Prometheus-und-Grafana-Stack: ein Compose-Override, eine Zwei-Job-Scrape-Konfiguration, ein Starter-Dashboard und einen Target-down-Alert, den du mit den Operations-Schwellen ausbaust. Halt beide Services an localhost gebunden und das Bearer-Token nicht im Klartext auf der Festplatte, und die ganze Monitoring-Oberfläche bleibt mit Tale auf dem Host. Die Endpoints und das Token, das sie absichert, gehören [Observability-Konfiguration](/de/self-hosted/configuration/observability-config); die Schwellen und die Oncall-Checkliste sind [Operations](/de/self-hosted/operate/observability/operations). Wenn ein Panel rot wird, ist die Symptom-zu-Fix-Suche [Troubleshooting](/de/self-hosted/operate/observability/troubleshooting). # Container-Architektur Source: https://tale.dev/docs/de/self-hosted/operate/container-architecture Eine Tale-Instanz besteht aus acht Containern, verdrahtet durch docker compose. Die Architektur-Seite hat behandelt, wofür jeder Container da ist; diese Seite ist die Operator-Version — welcher Container welchen Job besitzt, wie eine Chat-Nachricht durch sie fliesst und wie der Fehlermodus aussieht, wenn einer von ihnen stirbt. Lies das, wenn du Bereitschaft hast. Komm zurück, wenn du entscheidest, welchen Container du während eines Upgrades zuerst rollst. ## Die acht Container, mit ihren Jobs | Container | Job | Ausfälle betreffen | | -------------------------- | -------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | | `tale-proxy` | TLS-Terminierung + Edge-Routing | Jeden Ingress — kein Client erreicht die UI | | `tale-platform` | UI-Server, statische Asset-Auslieferung | Browser sieht 502; die API ist erreichbar | | `tale-convex` | Backend Actions/Queries/Mutations + WebSocket, plus In-Process-RAG, Crawling und Dokumentgen | UI lädt, aber ohne Daten; laufende Chats stocken; Ingestion stockt | | `tale-db` | Operatives Postgres für Convex | Convex fällt in Read-only; Writes blockieren | | `tale-knowledge-db` | Postgres des Wissens-Korpus (Dokument-Chunks, Embeddings, gecrawlte Seiten) | Wissens-Suche liefert leer; Ingestion scheitert | | `tale-sandbox-llm-gateway` | LLM-Gateway für Harness-Züge | Harness-Züge erreichen kein Modell; Chat ist unbetroffen | | `tale-sandbox-egress` | Netzwerk-Egress für sandboxierten Code | **Code-ausführen**-Tool scheitert mit „Egress denied"; Web-Render scheitert | | `tale-sandbox` | Sandbox-Laufzeit + Headless-Browser für Web-Render und Dokumentgenerierung | **Code-ausführen**, Web-Crawl-Render und Dokumentgenerierung scheitern alle | Ein Container ist dem öffentlichen Netz exponiert (`tale-proxy` für HTTPS, optional `tale-sandbox-egress` ausgehend für die Sandbox); der Rest nur intern. Der Opt-in-Sidecar `tale-controller` (das `controller`-Profil) ist standardmäßig aus; aktiviert startet er `tale-convex` auf eine signierte Anfrage neu, damit eine Datenresidenz-Änderung greifen kann, ohne der Plattform Docker-Zugriff zu geben. ## Der Request-Pfad Eine Chat-Nachricht macht einen Durchlauf durch die Container: 1. Browser → `tale-proxy` (TLS terminiert). 2. `tale-proxy` → `tale-platform` für HTML/JS, → `tale-convex` für API + WebSocket. 3. `tale-convex` liest die Provider-Config der Organisation, wählt das Modell, öffnet einen Stream zum Upstream-Provider. 4. Holt der Agent Wissen: `tale-convex` fährt die RAG-Suche im Prozess und fragt `tale-knowledge-db` direkt ab — kein separater Retrieval-Dienst im Pfad. 5. Führt der Agent Code aus: `tale-convex` → `tale-sandbox` → `tale-sandbox-egress` für ausgehende Netzwerk-Aufrufe. 6. Der Provider-Stream gibt Tokens durch `tale-convex` zurück an den Browser über den WebSocket. Der heisse Pfad ist kurz. Fühlt sich die Chat-Latenz falsch an, ist der Container, der schuld ist, fast immer der Upstream-Provider, nicht Tale; die Metric-Endpoints auf `tale-convex` (das jetzt auch die RAG- und Crawl-Timings trägt) zeigen die Zeit in jedem Sprung. ## Die Sandbox-Ebene Sandboxierte Code-Ausführung läuft in `tale-sandbox`, mit `tale-sandbox-egress` als der einzigen Netzwerk-Naht. Die Zwei-Container-Trennung ist Absicht: `tale-sandbox` selbst hat kein ausgehendes Netz; jeder Request, den der sandboxierte Code macht, geht durch `tale-sandbox-egress`, der Cloud-Metadaten und private Adressbereiche auf IP-Ebene blockiert und — wenn der Operator `SANDBOX_EGRESS_ALLOWLIST` setzt — zusätzlich eine Default-Deny-Hostname-Allowlist durchsetzt. Ist der Egress-Container down, scheitert sandboxierter Code, der das Netz braucht, geschlossen mit „Egress denied" — nicht stiller Timeout. Die Sandbox-Laufzeit trägt Chromium und Playwright, also nutzt das Convex-Backend sie für die Headless-Arbeit, die es im Prozess nicht erledigen kann, erneut: das Rendern einer JavaScript-Seite während eines Web-Crawls und das Verwandeln von generiertem HTML in ein PDF oder Bild. Diese Jobs laufen als ephemere Sandbox-Ausführungen statt als User-Code, reiten aber dieselbe Egress- und Isolations-Naht. Die Sandbox ist der einzige Container, der eher-nicht-vertrauenswürdigen Code läuft (User-gelieferte Fähigkeits-Skripte, Agent-**Code-ausführen**-Aufrufe); der Rest des Stacks läuft den eigenen Code der Plattform. ## Fehler-Modi — wie der Ausfall jedes Containers aussieht **`tale-proxy` down.** TLS-Handshake scheitert; jeder Client sieht einen Verbindungsfehler. Im Host sind die Plattform- und Convex-Container weiter up — starte Proxy zuerst neu. **`tale-platform` down.** Browser bekommt 502 vom Proxy; die API arbeitet weiter. Bestehende Browser-Tabs mit gecachten Assets sprechen weiter mit Convex über den WebSocket und merken es vielleicht erst beim Reload. **`tale-convex` down.** Browser lädt die UI-Shell, aber nichts wird befüllt. WebSocket-Reconnect schleift. Convex neu zu starten ist sicher — Sessions sind serverseitig; Clients reabonnieren beim Reconnect. **`tale-db` down.** Convex tritt in seinen degradierten Modus: Reads aus dem Cache, Writes werden gepuffert. Lange Ausfälle zeigen sich irgendwann als „Speichern fehlgeschlagen"-Toasts. **`tale-knowledge-db` down.** Dokument-Ingestion scheitert und die Wissens-Suche liefert leer — Agents, die Wissen abrufen, bekommen eine leere Ergebnismenge und eine Warnung im Ausführungs-Log. Der Rest der App arbeitet weiter; Chats ohne Wissen sind unbetroffen. Den Container neu zu starten räumt das, und laufende Uploads versuchen es beim nächsten Durchlauf erneut. **`tale-sandbox` / `tale-sandbox-egress` down.** **Code-ausführen**-Tool-Aufrufe geben einen Fehler zurück und Fähigkeits-Skripte scheitern. Weil das Convex-Backend Webseiten rendert und Dokumente über die Sandbox-Laufzeit generiert, scheitern auch ein Web-Crawl, der JavaScript-Rendering braucht, und die Dokumentgenerierung geschlossen, solange die Sandbox down ist. Agents, die keines davon nutzen, arbeiten weiter. **`tale-sandbox-llm-gateway` down.** Harness-Züge verlieren ihren Pfad zu einem Modell-Provider. Regulärer Chat — der Provider direkt aus Convex aufruft, nicht über das LLM-Gateway — ist unbetroffen. ## Wo das hingehört Diese Seite ist die Karte des Operators; die [Architektur-Übersicht](/de/self-hosted/overview) ist die Einführung ins selbe Bild, die [Troubleshooting-Seite](/de/self-hosted/operate/observability/troubleshooting) ist der symptomorientierte Index, wenn etwas schiefgegangen ist. Wenn du Alert-Schwellen setzt, benennt [Operations](/de/self-hosted/operate/observability/operations) die Signale, die sich zu verdrahten lohnen. # Wie du Release-Notes liest Source: https://tale.dev/docs/de/self-hosted/operate/release-notes/format Tale liefert ein Release pro Minor-Version und Patches als Bugfix-Tags dazwischen aus. Die Release-Notes für jeden Tag folgen derselben Form, damit du eine in einer Minute scannen kannst und weißt, ob das Upgrade ein Fünf-Minuten-Bump oder ein Wartungsfenster ist. Diese Seite deckt das Format ab: das semver-Versprechen, was jeder Abschnitt garantiert, und wo du tiefer liest, wenn eine Zeile auf eine Migration zeigt. Die Notes selbst leben auf der GitHub-Release-Seite zu jedem Tag. Das CLI bringt sie ebenfalls hoch — `tale update --notes` druckt die Notes für die Version, die es gerade installieren will. ## Das semver-Versprechen Tale-Versionen sind semver, und die Versionsnummer ist die wichtigste Tatsache über ein Upgrade. - **Patch (`0.9.0 → 0.9.1`)** — nur Bugfixes. Keine Schema-Migrationen, keine Config-Änderungen, keine Verhaltens-Änderungen außer dem Fix selbst. Sicher zu upgraden, ohne weiter als bis zum Security-Abschnitt zu lesen. - **Minor (`0.9.x → 0.10.x`)** — neue Features, möglicherweise forward-only Migrationen. Rückwärtskompatibel standardmäßig; Deprecations werden ein Minor im Voraus angekündigt. Die eine stehende Ausnahme ist 0.4.0: ein Breaking Minor, der ein frisches Deployment verlangt (siehe [Upgrades → 0.3 → 0.4](/de/self-hosted/operate/upgrades)). - **Major (`0.x → 1.x`)** — breaking Changes sind erlaubt. Trägt immer einen Link auf die Migrations-Notes oben am Release; lies sie End-to-End, bevor du anfängst. Die Versionszeile oben auf jeder Release-Seite nennt die Art des Bumps in Klartext, damit du die Rechnerei nicht selbst machen musst. ## Die Abschnitte, die jedes Release hat Jede Release-Seite ist dieselbe geordnete Abschnitts-Liste. Leere Abschnitte werden weggelassen, nicht leer gelassen — siehst du einen Abschnitt nicht, gibt es dort nichts zu melden. - **Highlights** — ein oder zwei Absätze dazu, wofür das Release da ist. Lies das zuerst. - **Breaking Changes** — jede Änderung, die verlangt, dass der Operator vor oder nach dem Upgrade etwas tut. Jede Zeile nennt das Symptom, das du treffen würdest, wenn du sie überspringst, und die Aktion, die das vermeidet. - **Deprecations** — Features, die in diesem Release noch laufen, aber zur Entfernung markiert sind. Jede Zeile nennt die Removal-Version, damit du den Cutover planen kannst. - **Security** — Einträge im CVE-Format für Fixes, die eine Schwachstelle schließen. Der vollständige Feed lebt unter [Security-Advisories](/de/self-hosted/operate/security/advisories); die Release-Notes tragen die Ein-Zeilen-Zusammenfassung plus den Link auf das Advisory. - **Features und Fixes** — die lange Liste. Gruppiert nach Bereich (Platform, CLI, Docs); jede Zeile liest sich als ein Satz. - **Migrations-Notes** _(Major-Versionen und manche Minors)_ — der verlinkte Walk durch Schema-Migrationen, Config-Datei-Änderungen oder operatorseitige Umbenennungen. Bei Majors immer lesen. ## Wie du ein Release scannst Lies die Versionszeile, die Highlights und den Breaking-Changes-Abschnitt. Ist Breaking Changes leer und nennt der Security-Abschnitt keinen Fix, der dein Install berührt, ist das Upgrade die `tale update` + `tale deploy`-Sequenz aus [Upgrades](/de/self-hosted/operate/upgrades). Hat einer der beiden Abschnitte Zeilen, gehst du sie durch, bevor du `tale deploy` läufst. ```text 0.12.0 (minor) — 14.05.2026 Highlights Streaming-Tool-Calls streamen jetzt in den Chat, sobald sie emittieren. Breaking Changes (keine) Deprecations AGENTS_LEGACY_PROMPT env var — entfernt in 0.14. Security CVE-2026-XXXX — gepatchter Bypass in der Run-Code-Sandbox. Siehe: Advisory TAL-2026-007. ``` Die Form oben ist das, was `tale update --notes` druckt. Die Web-Version desselben Releases fügt auf jeder Advisory- und Migrations-Zeile Links hinzu. ## Wo das hingehört Das Release-Notes-Format ist der Vertrag zwischen Projekt und Operator — dieselbe Form bei jedem Release, damit die Upgrade-Entscheidung ein Scan ist, kein tiefes Lesen. Die natürlichen nächsten Schritte sind [Upgrades](/de/self-hosted/operate/upgrades) für die Deploy-Mechanik und [Security-Advisories](/de/self-hosted/operate/security/advisories) für den langen Schwachstellen-Feed, in den der Security-Abschnitt verlinkt. # Backups und Restore Source: https://tale.dev/docs/de/self-hosted/operate/backups-and-restore Tales Backup-Einheit ist der Volume-Snapshot: ein pausiertes, checksummengesichertes Tar jedes Daten-Volumes der Instanz, geschrieben in ein dediziertes `backups`-Volume, das neben den Daten lebt, die es schützt. Das CLI nimmt automatisch einen vor jedem Deploy-Schritt, der Daten migrieren kann, und `tale backup` nimmt einen auf Zuruf. Recovery ist `tale restore <snapshot-id>` plus ein Redeploy der passenden Version — dieses Paar ist die Antwort auf ein gescheitertes Upgrade und der Grund, warum `tale rollback` sich alles jenseits eines Patch-Schritts verweigern kann. Der Architektur-Kontext lebt in [Container-Architektur](/de/self-hosted/operate/container-architecture); diese Seite deckt ab, was ein Snapshot enthält, wann einer genommen wird, wie die Kopie vom Host runterkommt und den Restore-Walk. ## Was ein Snapshot enthält | Volume | Enthält | | ---------------------------- | ---------------------------------------------------- | | `db-data` | Postgres — Agents, Runs, das Audit-Log | | `convex-data` | Org-Config, Anbieter-Secrets, hochgeladenes Branding | | `rag-data` | Der Vektor-Index aus deinen Dokumenten | | `crawler-data` | Gecrawltes Website-Wissen | | `caddy-data`, `caddy-config` | TLS-Zertifikate und Proxy-State | Jeder Snapshot ist ein Verzeichnis mit einem Namen wie `20260611-142530-deploy` im `backups`-Volume des Projekts: ein `.tar.gz` pro Volume, je ein `.sha256`-Sidecar und ein zuletzt geschriebenes `manifest.json`. Ein Verzeichnis ohne Manifest ist ein unvollständiger Snapshot — er taucht nie in Listings auf und lässt sich nie wiederherstellen. Zwei Dinge leben außerhalb der Volumes und brauchen separate Erfassung: der Projekt-Workspace (das Verzeichnis mit `tale.json`) und `.env`. ## Wann Snapshots genommen werden `tale deploy` snapshotet vor seinem ersten mutierenden Schritt, wann immer der Deploy Daten ändern kann: Die Zielversion weicht von der laufenden ab oder ein Host-Config-Push (`--override` / `--override-all`) ist angefordert. Während jedes Volume getart wird, sind die Container, die es nutzen, für ein paar Sekunden pausiert, damit das Archiv crash-konsistent ist — eine Live-Kopie eines laufenden Postgres-Verzeichnisses ist nicht wiederherstellbar. Ein gescheiterter Snapshot bricht den Deploy ab. `--skip-backup` übersteuert das auf `tale deploy` — dann sind deine eigenen externen Backups der einzige Recovery-Pfad, und genau deshalb loggt das Flag eine laute Warnung. ```bash # Jetzt sofort einen Snapshot nehmen tale backup ``` ## Retention Die Rotation behält die neuesten fünf Snapshots und alles aus den letzten 14 Tagen — je nachdem, was großzügiger ist. Ein Snapshot wird nur gelöscht, wenn er sowohl jenseits des Anzahl-Fensters als auch älter als das Alters-Fenster ist; eine ruhige Instanz behält ihre letzten Snapshots also unbegrenzt. Übersteuere die Fenster mit `BACKUP_KEEP_COUNT` und `BACKUP_KEEP_DAYS` in `.env`. ## Off-Host-Kopie Die Snapshots leben auf demselben Host wie die Daten, die sie schützen — eine tote Platte nimmt beides mit. Richte dein bestehendes Backup-Tooling (Restic, Borg, Velero, Cloud-Provider-Snapshots) auf das `backups`-Volume und erfasse den Projekt-Workspace und `.env` im selben Job. Tale bringt keinen Upload-Schritt mit — die Off-Host-Kopie unter deinem bestehenden Backup-Vertrag zu halten ist Absicht. ```bash # crontab auf dem Host — stündliche Restic-Kopie des backups-Volumes nach S3 0 * * * * restic -r s3:s3.amazonaws.com/bucket/tale backup \ /var/lib/docker/volumes/<project-id>_backups/_data ``` Den Host-Pfad des Volumes findest du mit `docker volume inspect <project-id>_backups`; die Projekt-ID steht in `tale.json`. ## Einen Snapshot wiederherstellen `tale restore` ohne Argumente listet, was verfügbar ist; mit einer ID verifiziert es die Checksummen, leert die Daten-Volumes und entpackt den Snapshot. Es verweigert, solange irgendein Projekt-Container läuft — `--stop` stoppt sie — und fragt nach Bestätigung, bevor es irgendetwas anfasst. ```bash # Sehen, was verfügbar ist tale restore # Stack stoppen und wiederherstellen tale restore 20260611-142530-deploy --stop # Den Stack auf der Version zurückbringen, die zu den Daten passt tale update --version 0.9.6 tale deploy --stop ``` Das Redeploy der passenden Version ist Teil des Restores, kein optionales Extra: Der Snapshot hat die Daten exakt so erfasst, wie diese Plattform-Version sie hinterlassen hat, und ein neueres Binary würde sofort wieder seine Migrationen darauf laufen lassen. Die Restore-Ausgabe druckt die exakte Version aus dem Manifest des Snapshots. ## Restore-Drill Lauf den Drill vierteljährlich auf einem Nicht-Produktions-Host. Der Drill ist nicht „existiert ein Snapshot" — er ist „kann ein frischer Host aus der Off-Host-Kopie des `backups`-Volumes, dem Projekt-Workspace und `.env` in unter einer Stunde wiederaufgebaut werden". Die Fehler-Modi, die der Drill fängt: ein Off-Host-Job, der den Workspace nie erfasst hat, und eine veraltete `.env`, die nicht mehr zu den Anforderungen des aktuellen Binarys passt. ## Wo das hingehört Snapshots sind der billige Teil; der Restore-Drill ist das, was beweist, dass sie funktionieren, und die Redeploy-der-passenden-Version-Regel ist das eine, was du dir merken solltest — Recovery ist nie „das Binary zurückrollen", sondern „die Daten wiederherstellen und die Version deployen, zu der sie gehören". Der Upgrade-Flow, den diese Snapshots schützen, lebt in [Upgrades](/de/self-hosted/operate/upgrades); die Hardening-Checkliste, die Backups als Zeile nennt, ist in [Hardening](/de/self-hosted/operate/security/hardening). # Hardening Source: https://tale.dev/docs/de/self-hosted/operate/security/hardening Die Defaults, mit denen Tale ausgeliefert wird, sind sicher für Development und vernünftig für eine kleine Produktions-Installation. Von „vernünftig" zu „bereit für die Regulator" zu kommen ist eine Checkliste, kein Konfigurations-Flag — jede Zeile unten zieht eine spezifische Angriffsoberfläche an. Walk die Liste einmal, bevor du die URL für echte Benutzer öffnest, und walk sie nach jedem grösseren Upgrade erneut. Die Referenz-Details für jede Zeile leben anderswo — TLS in [TLS und Domains](/de/self-hosted/configuration/tls-and-domains), Backups in [Backups und Restore](/de/self-hosted/operate/backups-and-restore), Retention in [Retention](/de/self-hosted/configuration/retention). Diese Seite ist der Index, der nennt, was zu härten ist und auf die Seite zeigt, die es walkt. ## Host | Punkt | Warum es zählt | | ------------------------------------ | ------------------------------------------------------------------------- | | Non-Root-Operator-Benutzer | Begrenzt den Blast-Radius, wenn der Plattform-Benutzer kompromittiert ist | | Nur SSH-Schlüssel-Auth | Passwort-Auth ist die offene Tür, nach der Bots scannen | | Unbeaufsichtigte Sicherheits-Updates | Patcht das OS, ohne auf ein Wartungsfenster zu warten | | Host-Firewall (ufw / nftables) | Schliesst alles, was nicht 22, 80, 443 ist | | Platten-Verschlüsselung at-rest | Pflicht, wenn du SOPS im Klartext-Modus betreibst | Der Non-Root-Benutzer ist der, den die meisten Teams überspringen. Die Container von Tale laufen ihre eigenen Non-Root-Prozesse innen, aber der Docker-Daemon selbst läuft als Root — diesen Daemon als Operator-Benutzer zu betreiben (Mitglied der `docker`-Gruppe, nicht als Root) ist das günstigste Anziehen auf dieser Seite. Der vollständige Walk lebt in [Produktions-Linux-Server-Install](/de/self-hosted/install/linux-server). ## Netzwerk Der Proxy ist die einzige eingehende Oberfläche. Blockier alles andere. ```bash sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow OpenSSH sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable ``` Wenn du trusted-Headers-Auth betreibst, darf der Plattform-Port nicht direkt von irgendwo ausser dem vorgelagerten Proxy erreichbar sein — alles, was ihn mit den richtigen Headern treffen kann, wird zu diesem Benutzer. Ein Docker-Netzwerk oder eine Host-Firewall-Regel funktionieren beide; wähl eins und verifizier es von ausserhalb des Hosts. ## TLS `TLS_MODE=selfsigned` ist für Development. Produktion läuft `letsencrypt` (oder `external`, wenn du Tale mit deinem eigenen TLS-terminierenden Proxy davor stellst). Der Erneuerungs-Cron ist automatisch; der Alert, der feuert, wenn die Erneuerung scheitert, ist das, was dich 90 Tage später rettet. Siehe [TLS und Domains](/de/self-hosted/configuration/tls-and-domains). ## Secrets Jedes Secret in `.env` ist sensibel — das Auth-Signing-Secret, der Verschlüsselungs-Schlüssel, das Datenbank-Passwort, der age-Schlüssel, das Metric-Bearer-Token. Die Mindestmesslatte: - `.env` ist Modus 0600 und gehört dem Operator-Benutzer. - `BETTER_AUTH_SECRET`, `ENCRYPTION_SECRET_HEX`, `INSTANCE_SECRET` sind von den Beispielwerten weg rotiert, die `.env.example` mitbringt. - `DB_PASSWORD` ist vom Default-Platzhalter geändert. - `SOPS_AGE_KEY` oder `SOPS_AGE_KEY_FILE` ist gesetzt — beide unset zu lassen ist unterstützt, aber Hosts mit verschlüsselter Platte und externem Secret-Management vorbehalten. Der vollständige SOPS-Walk und die Rotations-Prozedur leben in [Secrets mit SOPS](/de/self-hosted/configuration/secrets-with-sops). ## Audit-Logs Audit-Logs sind unveränderlich und retentions-gebunden. Compliance-Frameworks erwarten mindestens ein Jahr; die Grenze wird pro Deployment durchgesetzt, also ist die strengste Einstellung der Org das, was tatsächlich läuft. Setz die Untergrenze in deiner Operator-Config so, dass sie zum lockersten Framework passt, das du unterstützt, und stell sicher, dass Backups Audit-Log-Zeilen mit dem Rest der Datenbank erfassen. Die Retention-Referenz lebt in [Retention](/de/self-hosted/configuration/retention). ## Backups Ein Backup, das nicht wiederhergestellt wurde, ist eine Hoffnung, kein Backup. Das Minimum: tägliche Postgres-Dumps, vom `tale-db`-Cron geschrieben, innerhalb der Stunde vom Host weg kopiert, und ein vierteljährlicher Restore-Drill, der eine funktionierende Instanz aus dem Snapshot wieder aufbaut. Die vollständige Prozedur ist in [Backups und Restore](/de/self-hosted/operate/backups-and-restore). ## Sandbox-Isolation Run-Code ist die riskanteste Oberfläche im Produkt — der einzige Ort, an dem benutzergelieferter Input zu ausgeführtem Code wird. `tale-sandbox` läuft ohne privilegierte Caps, sein Netzwerk ist intern, und `tale-sandbox-egress` ist sein einziger ausgehender Pfad. Auf Hostname-Ebene ist dieser Pfad standardmäßig offen: sandboxierter Code erreicht jeden öffentlichen Host über HTTPS, während Cloud-Metadaten-Endpunkte und private Adressbereiche auf IP-Ebene immer blockiert sind — dieser Boden hält in jeder Konfiguration. Der Hardening-Hebel ist `SANDBOX_EGRESS_ALLOWLIST`. Setz die Variable in `.env` auf eine Pipe-getrennte Liste von Hostname-Regexen und erzeuge `tale-sandbox-egress` neu — der Proxy kippt auf Default-Deny, nur passende Hosts sind erreichbar. Ein Lockdown auf reine Registries, der pip, npm, uv und Git über HTTPS am Laufen hält: ```bash SANDBOX_EGRESS_ALLOWLIST=^pypi\.org$|^files\.pythonhosted\.org$|^registry\.npmjs\.org$|^objects\.githubusercontent\.com$|^codeload\.github\.com$|^github\.com$|^api\.github\.com$ ``` Halt die Liste kurz und bevorzuge spezifische Hosts gegenüber Wildcards. Paket-Installationen regelt separat die [Run-Code-Richtlinie](/de/platform/admin/governance/run-code-policy). ## Monitoring `METRICS_BEARER_TOKEN` ist in `.env.example` unset — das ist Absicht, damit eine frische Installation keine Metriken leakt. Setz den Token, scrape aus deinem Prometheus, und die Alert-Schwellen in [Operations](/de/self-hosted/operate/observability/operations) decken die kundenwirksamen Signale ab. Die Hash-Kette des Audit-Logs wird automatisch jede Nacht verifiziert. Jeder Bruch löst einen kritischen Security-Alert an die Org-Admins aus — in der Notification-Glocke und, wenn Slack verbunden ist, in deinem Slack-Channel —, sodass Manipulation auffällt, auch wenn niemand die Logs beobachtet. Dieselbe Verifikation kannst du jederzeit on demand von der Admin-Audit-Log-Seite aus neu walken. ## HTTP-Sicherheitsheader Jede HTML-Antwort trägt einen strengen Satz an Sicherheitsheadern, und der Satz ist durch Tests abgesichert, sodass ein Upgrade keinen davon unbemerkt fallen lassen kann. Der Plattform-Webclient (`services/platform`) sendet eine Nonce-basierte Content-Security-Policy ohne `unsafe-inline`-Skripte, HSTS über HTTPS, `X-Content-Type-Options: nosniff`, `X-Frame-Options: DENY` zusammen mit CSP `frame-ancestors 'none'`, `Referrer-Policy: strict-origin-when-cross-origin`, eine restriktive `Permissions-Policy` und `X-Permitted-Cross-Domain-Policies: none`. Er erreicht A+ im MDN HTTP Observatory, und diese Note wird von der CI-Testsuite abgesichert — die Bewertung ist in Tests nachgebildet, die den Build bei jeder Regression scheitern lassen. Die Marketing-Seite und die Docs-Seite liefern dieselbe Header-Familie und ergänzen `Cross-Origin-Opener-Policy` und `Cross-Origin-Resource-Policy` mit `same-origin`. Gegen die eigene Bereitstellung prüfen: - `curl -sI https://<dein-host>/ | grep -iE 'content-security|strict-transport|x-frame|x-content-type|referrer-policy|permissions-policy|cross-origin'` - Den Host auf [securityheaders.com](https://securityheaders.com) oder im [MDN HTTP Observatory](https://developer.mozilla.org/de/observatory) scannen. <!-- The MDN Observatory UI is only localized in some languages. When adding a new docs language, check whether developer.mozilla.org/<lang>/observatory exists and fall back to the en-US analyze links if it does not. --> Die öffentliche Demo ist die Live-Referenz dafür, was eine korrekte Bereitstellung meldet: Der [Observatory-Scan von demo.tale.dev](https://developer.mozilla.org/de/observatory/analyze?host=demo.tale.dev) stand am 15.07.2026 bei A+ — Score 115/100, alle zehn Tests bestanden. Der einzige Header, der im Report als nicht implementiert steht — `Cross-Origin-Resource-Policy` — kostet keine Punkte und ist die bewusste Ausnahme direkt darunter. Cross-Origin-Isolation (COOP/CORP) bleibt auf der Plattform-App bewusst aus: `Cross-Origin-Opener-Policy: same-origin` würde die Fenster-Referenz kappen, über die ein OAuth-Anmelde-Popup die fertige Anmeldung an die App zurückmeldet, und `Cross-Origin-Resource-Policy` würde Branding-Assets blockieren, die von einem zweiten Host geladen werden. Die Content-Seiten, die beides nicht tun, aktivieren beide Header. HSTS wird nur ausgegeben, wenn `SITE_URL` `https://` ist. ## Wo das hingehört Hardening ist keine Ein-Durchgangs-Aufgabe — die Liste oben ist das, was du vor dem Launch walkst und nach jedem Upgrade oder nach jeder Änderung der Netzwerk-Form neu walkst. Das nächste, was es wert ist, danach zu lesen, ist die Zeile oben, die du noch nicht gemacht hast. # Audit-Log-Integritätswarnungen Source: https://tale.dev/docs/de/self-hosted/operate/security/audit-log-integrity Tale verifiziert die Audit-Log-Hash-Kette jeder Organisation nach Zeitplan und löst in dem Moment eine Warnung aus, in dem eine Verifizierung fehlschlägt. Diese Seite ist das Runbook für den Operator oder Admin, der diese Warnung erhalten hat: wie du den Befund liest, wie du ein echtes Manipulationssignal von einem gewöhnlichen Aufbewahrungs- oder Konfigurationsartefakt trennst und was du sicherst, bevor du irgendetwas anfasst. Die Warnung ist absichtlich laut, weil ein echter Bruch selten und ernst ist — aber die meisten Brüche, die in der Praxis feuern, haben eine alltägliche Erklärung, also besteht die Arbeit darin, diese methodisch auszuschließen, statt in Panik zu verfallen. ## Was sie auslöst Ein täglicher Cron läuft die append-only Audit-Kette jeder Organisation samt ihrer Aufbewahrungs- und Scrub-Checkpoints ab. Wenn eine Kette nicht verifiziert, tut der Lauf zwei Dinge. Er schreibt eine In-Band-Audit-Zeile der Kategorie `security` — bei jedem fehlschlagenden Lauf, damit der dauerhafte Datensatz immer vollständig ist — und er löst eine Out-of-Band-Benachrichtigung an die Admins der Organisation aus, in der Benachrichtigungsglocke und in deinem Slack-Kanal, wenn einer verbunden ist. Die Out-of-Band-Warnung ist dedupliziert. Du bekommst eine Benachrichtigung, wenn ein Bruch zuerst erkannt wird, und nur dann eine weitere, wenn er sich ändert — eine andere gebrochene Zeile oder ein anderer fehlschlagender Checkpoint — nicht jeden Tag einen frischen Alarm für denselben Bruch. Ein späterer sauberer Lauf räumt die Warnung von selbst ab; ein späterer, anderer Bruch löst eine neue aus. ## Manipulation oder Konfigurationslücke Die Warnung kommt in zwei Formen, und der Titel sagt dir, welche. **Integritätsprüfung des Audit-Logs fehlgeschlagen** ist die kritische: Die Hash-Kette selbst verifiziert nicht, oder die Signatur eines signierten Checkpoints passt nicht zum konfigurierten Schlüssel. Behandle das als mögliches Manipulationssignal, bis du es erklärt hast. **Audit-Log-Signaturen können nicht überprüft werden** ist eine ruhige Warnung, kein Einbruch: Ein Checkpoint ist signiert, aber das Deployment hat keinen `TALE_AUDIT_SIGNING_KEY` konfiguriert, gegen den sich die Signatur prüfen ließe. Nichts wurde gefälscht — Tale kann nur nicht beweisen, dass der Checkpoint echt ist, bis du den Schlüssel wiederherstellst. Das Panel im Produkt spiegelt die Trennung: Eine gesunde Kette zeigt das grüne Badge **Verifiziert**, ein aktiver Vorfall das rote Badge **Integritätswarnung aktiv**, und eine Organisation, die der Cron noch nicht erreicht hat, zeigt **Noch nicht geprüft**. ## Das Integritäts-Panel öffnen Die Admins einer Organisation inspizieren die Kette unter **Einstellungen > Richtlinien > Audit-Logs**. Das Panel **Ketten-Integrität** oben auf der Seite zeigt das Status-Badge, den Zeitpunkt der letzten automatischen Prüfung und einen Knopf **Jetzt prüfen**, der dieselbe Verifizierung auf Abruf erneut fährt. Kommst du aus der Benachrichtigung, führt dich ein Klick auf die Warnung per Deep-Link direkt zur markierten Zeile in der Audit-Tabelle statt an den Anfang des Logs. Fahre **Jetzt prüfen**, um den strukturierten Befund zu sehen. Bei einem Bruch der Hash-Kette zeigt das Panel **Ketten-Integrität verletzt** mit der **Eintrags-ID** der ersten fehlschlagenden Zeile, wann er **Aufgetreten** ist, dem **Erwarteter Hash** und dem **Gespeicherter Hash**, der nicht passte — plus einem Knopf **Diesen Eintrag öffnen**, der die Zeile in der Tabelle aufdeckt. Bei einem Checkpoint-Problem zeigt es **Checkpoint-Prüfung fehlgeschlagen** mit der **Checkpoint-ID** und einem **Grund**. Halte diese Details fest, bevor du irgendetwas änderst: Sie sind der Beweis. ## Die harmlosen Ursachen ausschließen Ein Hash-Bruch ist nur dann ein Manipulationssignal, wenn nichts Legitimes ihn erklärt, und der Verifizierer kennt die drei gewöhnlichen Ereignisse bereits, die fast jede Warnung verursachen — sie zu bestätigen ist dein erster Zug. **Ein Aufbewahrungsschnitt.** Wenn die Aufbewahrung alte Zeilen endgültig löscht, zeigt der überlebende Kettenkopf auf eine Zeile, die nicht mehr existiert. Der Verifizierer verankert die Kette über den Schnitt hinweg neu, über einen signierten Aufbewahrungs-Checkpoint — ein sauberer Schnitt verifiziert also normal. Siehst du stattdessen **Audit-Log-Signaturen können nicht überprüft werden**, ist der Schnitt selbst in Ordnung — dem Deployment fehlt der `TALE_AUDIT_SIGNING_KEY`, der den Checkpoint beglaubigt. Das ist eine Konfigurationslücke, keine Manipulation. **Ein DSGVO-Scrub.** Das Löschen einer betroffenen Person leert ihre Felder an Ort und Stelle, was die Hashes dieser Zeilen ändern würde — deshalb schreibt ein Scrub einen signierten Scrub-Checkpoint über die betroffenen Zeilen, und der Verifizierer vertraut ihnen auf dieser Grundlage. Ein Scrub sollte auf einem Deployment mit Signierschlüssel nie als Bruch auftauchen. **Alte Zeilen aus der Zeit vor der Kette.** Zeilen, die geschrieben wurden, bevor es die Audit-Hash-Verkettung gab, tragen keinen Integritäts-Hash. Der Verifizierer überspringt sie automatisch; sie sind kein Bruch. Ein echtes Manipulationssignal ist ein Hash-Unterschied ohne jede dieser Erklärungen: kein Aufbewahrungsschnitt an dieser Stelle, kein Scrub über der Zeile, und der Signierschlüssel vorhanden und korrekt. ## Auf einen echten Bruch reagieren Übersteht der Befund diese Triage — ein Hash-Unterschied, den du nicht erklären kannst —, behandle ihn als Sicherheitsvorfall und sichere zuerst die Beweise. Audit-Zeilen sind absichtlich append-only; lösche oder bearbeite keine Zeile, auch nicht die markierte, denn das zerstört den Datensatz, von dem eine Untersuchung abhängt. 1. Halte den Befund wörtlich fest — die **Eintrags-ID**, die Zeit unter **Aufgetreten**, **Erwarteter Hash** und **Gespeicherter Hash** (oder die **Checkpoint-ID** und den **Grund**) aus dem Panel. Kopiere sie oder mach einen Screenshot, statt dich allein auf die Warnung zu verlassen. 2. Bestätige, ob der Signierschlüssel auf dem Host konfiguriert ist, damit du einen echten Unterschied von einem nicht verifizierbaren Checkpoint unterscheiden kannst. Das meldet die Anwesenheit, ohne das Geheimnis auszugeben: ```bash grep -q '^TALE_AUDIT_SIGNING_KEY=' .env && echo configured || echo missing ``` 3. Korreliere den Zeitstempel des Bruchs mit jüngerer Aktivität — einem Aufbewahrungslauf, einem Scrub einer betroffenen Person, einem Deploy, einer Datenbank-Wiederherstellung oder direktem Datenbankzugriff. Ein Bruch, der mit einer Wartungsaktion zusammenfällt, hat meist eine gewöhnliche Ursache, die du jetzt benennen kannst. 4. Erklärt ihn nichts, eskaliere über deine Security-Incident-Richtlinie und behandle die Datenbank als potenziell kompromittiert, bis das Gegenteil bewiesen ist. Bewahre je einen Backup-Snapshot von vor und nach dem erkannten Bruch für die Forensik auf. ## Die Warnung abräumen Die Warnung ist vorfallbasiert, kein wiederkehrendes Ereignis. Sobald der Bruch behoben oder erklärt ist — der Schlüssel wiederhergestellt, das Aufbewahrungsartefakt verstanden, eine manipulierte Datenbank aus einem sauberen Backup neu aufgebaut —, verifiziert der nächste tägliche Lauf sauber und räumt die Warnung von selbst ab, und das Badge **Ketten-Integrität** kehrt zu **Verifiziert** zurück. Es gibt keinen Bestätigen- oder Verwerfen-Schritt, den du dir merken müsstest. Taucht später ein anderer Bruch auf, löst die Prüfung dafür eine frische Warnung aus — Stummschalten ist also nie nötig. ## Wo das einzuordnen ist Eine Integritätswarnung ist eine Aufforderung zur Untersuchung, kein Urteil — die tägliche Prüfung läuft laut, damit sich ein seltener echter Bruch nicht zwischen den Logs verstecken kann, und dieses Runbook trennt diesen seltenen Fall von den Aufbewahrungs- und Scrub-Artefakten hinter den meisten Warnungen. Der Mechanismus, den der Verifizierer prüft — die SHA-256-Hash-Kette und die HMAC-signierten Checkpoints — ist in [Kryptografie](/de/self-hosted/operate/security/cryptography) dokumentiert, und die Aufbewahrungsschnitte, die sie legitim neu verankern, stehen in [Aufbewahrung](/de/self-hosted/configuration/retention). Das Panel, die Spalten und der Export, mit denen du eine markierte Zeile liest, leben in der Referenz [Audit-Logs](/de/platform/admin/governance/audit-logs); die Checkliste [Härtung](/de/self-hosted/operate/security/hardening) ist der Ort, an dem dieses Monitoring überhaupt erst eingeschaltet wird. # Kryptografie Source: https://tale.dev/docs/de/self-hosted/operate/security/cryptography Diese Seite ist die Inventur jedes kryptografischen Primitivs, auf das sich Tale stützt: was Secrets auf der Festplatte schützt, was den Verkehr auf der Leitung schützt, wie Passwörter gehasht werden und wie das Audit-Log beweist, dass es nicht manipuliert wurde. Sie ist für Betreiber und Compliance-Prüfer geschrieben, die "welche Algorithmen, welche Schlüssellängen, wo liegen die Schlüssel" gegen einen Standard wie BSI TR-02102-1 beantworten müssen — Tale nutzt bereits konforme Primitive, und auf dieser Seite sind sie festgehalten. Die Angaben hier sind gegen den Quellcode verifiziert; wo ein Primitiv konfigurierbar ist, wird die Umgebungsvariable benannt, die es steuert, damit du dein eigenes Deployment prüfen kannst. Das ist kein Ersatz dafür, die Host-Festplatte zu verschlüsseln — siehe [Härtung](/de/self-hosted/operate/security/hardening) für die Schicht unter der Anwendung. ## Ruhende Daten Tale verschlüsselt zwei Klassen von Secrets im Ruhezustand, mit zwei verschiedenen Mechanismen. **Provider-API-Schlüssel** liegen in `providers/*.secrets.json` und werden mit [SOPS](/de/self-hosted/configuration/secrets-with-sops) unter Nutzung eines **age**-Schlüssels verschlüsselt. SOPS verschlüsselt jeden Wert mit **AES-256-GCM** und wrappt den Datenschlüssel an den age-Empfänger, dessen Schlüsselaustausch **X25519** ist. Ein verschlüsselter Wert liest sich auf der Festplatte als `ENC[AES256_GCM,data:…,iv:…,tag:…]`; die Entschlüsselung passiert in-process und der private age-Schlüssel verlässt den Speicher des platform-Containers nie. **Anwendungsverschlüsselte Felder** — OAuth-Connector-Tokens und ähnliche Credentials in der Datenbank — werden mit **AES-256-GCM** über ein kompaktes JWE (`alg: dir`, `enc: A256GCM`) verschlüsselt. Der 32-Byte-Schlüssel kommt aus `ENCRYPTION_SECRET` (base64) oder `ENCRYPTION_SECRET_HEX` (hex); die Plattform verweigert den Start des Verschlüsselungspfads mit einem Schlüssel, der nicht exakt 32 Byte hat. Der Convex-Datenspeicher und die Postgres-Volumes werden vom Host geschützt: betreibe sie auf einem verschlüsselten Dateisystem (LUKS oder die Volume-Verschlüsselung deines Cloud-Anbieters). Tale speichert Credentials nicht im Klartext — ein Provider-Schlüssel oder OAuth-Token ist entweder SOPS-verschlüsselt auf der Festplatte oder AES-256-GCM-verschlüsselt in der Datenbank, nie im Klartext geschrieben. **Kunden-PII und Anwendungsdaten** — Namen, E-Mail- und Postadressen, Gesprächsinhalte — sind im Ruhezustand durch dieselben Schichten geschützt, die die Datenbank als Ganzes schützen: Convex' Verschlüsselung im Ruhezustand, TLS 1.3 bei der Übertragung und zeilenbasierte Sicherheitsregeln (RLS), die jeden Lesezugriff auf die Organisation des Aufrufers begrenzen. Anwendungsseitige Feldverschlüsselung ist gezielt für Secrets gemacht — Provider-Schlüssel und OAuth-Tokens, die einmal geschrieben und von einem einzigen Code-Pfad gelesen werden. PII ist anders: Sie wird gefiltert, sortiert und über den exakten Wert nachgeschlagen, und die Kundentabelle ist nach Organisation und E-Mail indiziert. Diese Spalten auf Feldebene zu verschlüsseln würde Gleichheitsabfragen und indizierte Suche brechen — sofern nicht mit einem suchbaren Hash-Verfahren kombiniert, das genau die Gleichheit preisgibt, die es verbergen soll — bei zusätzlichen Kosten für die Schlüsselrotation und ohne Schutz, den die verschlüsselte Host-Festplatte unter der Anwendung gegen ein gestohlenes Volume nicht ohnehin bietet. Wenn dein Compliance-Regime zusätzlich Feldverschlüsselung für PII verlangt, ist das eine bewusste Anwendungsänderung statt eines Standards, den Tale mitliefert. ## Daten bei der Übertragung Aller Browser- und API-Verkehr terminiert TLS am Reverse-Proxy (Caddy), der TLS 1.3 (mit TLS 1.2 als Untergrenze) aushandelt und Zertifikate automatisch bezieht. Die Cipher-Suites sind die modernen Defaults des Proxys — AES-256-GCM und ChaCha20-Poly1305 mit ECDHE-Schlüsselaustausch. Konfiguriere Domain und Zertifikatsquelle in [TLS und Domains](/de/self-hosted/configuration/tls-and-domains); der Verkehr zwischen Containern bleibt im internen Docker-Netz des Hosts. ## Passwort-Hashing Lokale-Passwort-Konten werden mit **bcrypt** gehasht (über Better Auth), sodass eine gestohlene Datenbankzeile das Passwort nicht preisgibt und eine Verifikation bewusst ~100 ms kostet — was auch der Grund ist, warum das Timing des Login-Pfads verschleiert wird (siehe [Authentifizierung](/de/self-hosted/configuration/authentication)). Sessions werden mit `BETTER_AUTH_SECRET` (HMAC) signiert; das Rotieren dieses Secrets entwertet jede bestehende Session. ## Integrität des Audit-Logs Das Audit-Log ist über eine **SHA-256-Hash-Kette** manipulationssicher: jeder Eintrag speichert `SHA-256(previousHash + kanonisierter Datensatz)`, sodass das Ändern oder Löschen eines historischen Eintrags die Kette an dieser Stelle und bei jedem folgenden Eintrag bricht. Einträge tragen zusätzlich eine **HMAC-SHA-256**-Signatur. Die Admin-Integritätsprüfung verifiziert beides; siehe [Audit-Logs](/de/platform/admin/governance/audit-logs). ## Zuordnung zu BSI TR-02102-1 Jedes Primitiv unten liegt im empfohlenen Satz von BSI TR-02102-1. Tale liefert keinen veralteten Algorithmus aus (kein MD5, SHA-1, DES oder RSA < 3072 auf einem selbst erzeugten Schlüssel). | Verwendung | Algorithmus | Schlüssel-/Ausgabegröße | Gesteuert durch | | ----------------------- | --------------------------------- | ----------------------- | --------------------------------------------- | | Provider-Secrets (Disk) | AES-256-GCM + age (X25519) | 256-Bit | `SOPS_AGE_KEY` / `SOPS_AGE_KEY_FILE` | | App-Felder (Datenbank) | AES-256-GCM (JWE `dir`/`A256GCM`) | 256-Bit | `ENCRYPTION_SECRET` / `ENCRYPTION_SECRET_HEX` | | Übertragung | TLS 1.3 (AES-256-GCM, ECDHE) | 256-Bit | Reverse-Proxy / `tls-and-domains` | | Passwort-Hashing | bcrypt | Salt pro Hash | Better Auth (eingebaut) | | Session-Signierung | HMAC-SHA-256 | 256-Bit | `BETTER_AUTH_SECRET` | | Audit-Integrität | SHA-256-Kette + HMAC-SHA-256 | 256-Bit | eingebaut | ## Schlüsselspeicherung und -rotation Drei Secrets sind tragend, und jedes hat einen Rotationspfad. Der **private age-Schlüssel** (`SOPS_AGE_KEY`) entschlüsselt Provider-Secrets; rotier ihn, indem du einen neuen Empfänger hinzufügst und neu verschlüsselst, entlang des Wegs in [Secrets mit SOPS](/de/self-hosted/configuration/secrets-with-sops). Der **Feld-Verschlüsselungsschlüssel** (`ENCRYPTION_SECRET`) entschlüsselt Datenbank-Credentials; ihn zu rotieren erfordert das Neu-Verschlüsseln der betroffenen Zeilen, plan es also als Wartungsschritt statt als Hot-Swap. Das **Auth-Secret** (`BETTER_AUTH_SECRET`) signiert Sessions; es zu rotieren loggt alle bei ihrer nächsten Anfrage aus. Alle drei leben nur in der Umgebung des platform-Containers — committe sie nie und leg sie in deinem Secret-Manager der Wahl ab. ## Wo das hingehört Kryptografie in Tale ist geschichtet: SOPS+age und AES-256-GCM schützen Secrets im Ruhezustand, TLS 1.3 schützt sie bei der Übertragung, bcrypt schützt Passwörter, und eine SHA-256-Kette beweist, dass das Audit-Log intakt ist — alles Primitive, die im empfohlenen Satz von BSI TR-02102-1 liegen, mit den steuernden Umgebungsvariablen oben, damit du deine eigene Instanz verifizieren kannst. Die Schicht unter der Anwendung ist der Host selbst: [Härtung](/de/self-hosted/operate/security/hardening) deckt die Egress-Allowlist, die Container-Isolation und die Erwartungen an die Festplattenverschlüsselung ab, die diese Seite voraussetzt, und [Secrets mit SOPS](/de/self-hosted/configuration/secrets-with-sops) ist die operative Anleitung für den age-Schlüssel, von dem diese Algorithmen abhängen. # Security-Advisories Source: https://tale.dev/docs/de/self-hosted/operate/security/advisories Tale veröffentlicht ein Security-Advisory für jede Schwachstelle, die durch ein gepatchtes Release geschlossen wird. Der Feed lebt unter GitHub Security Advisories im Repository `tale-project/tale` und spiegelt auf einen RSS-Endpunkt, den Operator in ihr Alerting hängen können. Diese Seite deckt das Format ab, dem jedes Advisory folgt, die Severity-Skala, die Tale verwendet, die Disclosure-Timeline, der die Maintainer sich verpflichten, und die drei Subscription-Pfade. Die Advisories sind die Langform-Aufzeichnung. Die Ein-Zeilen-Zusammenfassung plus Link erscheint im **Security**-Abschnitt jeder [Release-Note](/de/self-hosted/operate/release-notes/format). ## Das Advisory-Format Jedes Advisory ist ein GitHub Security Advisory mit einem stabilen Identifier der Form `TAL-YYYY-NNN` (Tales interne ID) plus dem Upstream-`CVE-YYYY-NNNNN`, wenn eine zugewiesen wurde. Der Body ist dieselbe geordnete Abschnittsmenge, damit ein Operator die tragenden Fakten scannen kann, ohne die Prosa zu lesen. - **Summary** — ein Satz dazu, was ein Angreifer tun könnte und was der Fix ändert. - **Affected versions** — die Versions-Range, die die Schwachstelle enthält, in semver-Form (`>=0.8.0, <0.12.3`). - **Patched versions** — das erste Release, das den Fix enthält. Das Upgraden auf oder über diese Version schließt die Schwachstelle. - **Severity** — eine der vier Stufen unten, plus der CVSS-3.1-Vektor für Operator, die gegen ihr eigenes Threat-Model scoren. - **Workarounds** — was zu setzen, zu deaktivieren oder zu blockieren ist, um die Schwachstelle zu mitigieren, wenn ein sofortiges Upgrade nicht möglich ist. Leer, wenn kein Workaround existiert. - **Credits** — der Melder, wenn er namentlich genannt werden möchte. Die Patched-Versions-Zeile ist die, auf der die meisten Operator zuerst landen; das Upgrade selbst ist die Zwei-Kommando-Sequenz aus [Upgrades](/de/self-hosted/operate/upgrades). ## Die Severity-Skala Tale nutzt vier Stufen. Die Stufe wird aus dem CVSS-Score und der Erreichbarkeit der verwundbaren Oberfläche auf einem Standard-Install gesetzt. | Stufe | CVSS | Was es bedeutet | | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------ | | Critical | 9.0+ | Pre-authentifizierte Remote-Code-Execution oder unauthentifizierte Daten-Exfiltration. Patche innerhalb 24 Stunden. | | High | 7.0–8.9 | Authentifizierte Eskalation, Sandbox-Ausbruch oder Cross-Tenant-Daten-Leak. Patche innerhalb einer Woche. | | Moderate | 4.0–6.9 | Informations-Disclosure, Denial of Service oder Eskalation, die seltene Vorbedingungen verlangt. Patche im nächsten Wartungsfenster. | | Low | 0.1–3.9 | Defense-in-Depth-Fixes und Härtung ohne bekannten Exploit-Pfad. Patche, wenn es passt. | Der CVSS-Vektor lässt dich gegen dein eigenes Deployment neu scoren — ein Advisory, das gegen ein öffentliches Install High ist, kann gegen ein air-gapped Install Low sein. ## Die Disclosure-Timeline Die Maintainer verpflichten sich auf die folgende Timeline ab dem Moment, in dem ein Report bei `security@tale.dev` landet: - **Innerhalb 72 Stunden** — Bestätigung, ein Triage-Call und ein zugewiesener TAL-Identifier. - **Innerhalb 14 Tagen** — ein Fix oder ein Workaround, privat an den Melder veröffentlicht, und die gepatchte Version geplant. - **Bei Fix-Release** — das Advisory wird auf GitHub veröffentlicht, die CVE-Zuweisung wird angefordert, und der Security-Abschnitt der Release-Notes trägt die Zusammenfassung. - **30 Tage nach Release** — das technische Detail im Advisory erweitert sich um den Reproducer (wenn das Reproduzieren in der Öffentlichkeit ungepatchte Installs nicht mehr gefährdet). Melder können eine Verzögerung anfordern, wenn sie für die Offenlegung mehr Zeit brauchen; die Maintainer akzeptieren bis zu 90 Tage, bevor sie die Zusammenfassung trotzdem veröffentlichen. Auf der Engineering-Seite laufen Dependency-Fixes auf einem Fast Track, damit das gepatchte Release schnell erscheint: Renovate öffnet innerhalb von 24 Stunden nach einem Upstream-Advisory einen Security-Update-PR — am sonst üblichen Release-Age-Delay für Routine-Updates vorbei — und CI blockt jeden Merge, der ein bekanntes High- oder Critical-Advisory einführt. Ein offengelegter Dependency-CVE wird damit in Tagen zu einem gepatchten Tale-Release, nicht erst beim nächsten Routine-Zyklus. ## Anmelden Drei Pfade zum selben Feed: ```text GitHub-Watch — github.com/tale-project/tale → Watch → Custom → Security alerts RSS — https://github.com/tale-project/tale/security/advisories.atom E-Mail-Digest — security-announce@tale.dev (eine Mail pro Advisory, kein Verkehr dazwischen) ``` Der RSS-Feed ist das, was die meisten Operator in Slack oder PagerDuty einhängen; der E-Mail-Digest ist für Ein-Personen-Teams, die keine Alerting-Pipeline betreiben. ## Wo das hingehört Der Advisory-Feed ist einer der zwei Verträge, die Tale sicher selbst hostbar machen — Release-Notes nennen, was sich ändert, Advisories nennen, was falsch war. Die natürlichen nächsten Lesungen sind [Wie du Release-Notes liest](/de/self-hosted/operate/release-notes/format) für das passende Change-Log-Format und [Hardening](/de/self-hosted/operate/security/hardening) für die Checkliste, die Exposition begrenzt, bevor ein Advisory überhaupt feuert. # Anbieter Source: https://tale.dev/docs/de/self-hosted/configuration/providers Ein KI-Anbieter in Tale besteht aus zwei Hälften, die an zwei verschiedenen Orten leben. Der **Connector** — Wire-Format, Endpunkt, Quelle des Modellkatalogs, akzeptierte Authentifizierungsmethoden — kommt mit der Plattform als Datei, die du liest, aber nicht änderst. Die **Zugangsdaten** sind Organisationsdaten und werden in der App unter **Einstellungen > KI-Anbieter** angelegt und rotiert. Diese Seite ist die Operator-Hälfte: was in den mitgelieferten Dateien steht, und der eine Hebel, der wirklich dem Deployment gehört — Anbieter-Schlüssel in Umgebungsvariablen zu halten. ## Wo die Connectoren liegen Connector-Definitionen sind YAML-Dateien unter `configs/platform/system/providers/`, eine pro Anbieter, benannt nach dessen Slug — `openrouter.yml`, `openai.yml`, `anthropic.yml`, `azure.yml` und so weiter. Diese Dateien gehören zum Plattform-Image und werden mit ihm aktualisiert. Die passenden mitgelieferten Modellkataloge liegen daneben unter `configs/platform/system/models/<slug>.yml`. <Warning> Diese Dateien sind schreibgeschützte Eingaben, keine Deployment-Konfiguration. Wer eine davon in einem laufenden Container ändert, verliert die Änderung beim nächsten Upgrade, und eine Überschreibung auf Organisationsebene gibt es nicht. Fehlt ein Anbieter, den du brauchst, im mitgelieferten Satz, ist das eine Änderung an der Plattform und keine an der Konfiguration. </Warning> ## Was ein Connector deklariert Ein Connector ist bewusst kurz. Er nennt den Anbieter, den Wire-Dialekt seiner API, den Endpunkt, auf dem er antwortet, die Herkunft seiner Modellliste und die akzeptierten Authentifizierungsmethoden — nichts Organisationsspezifisches und keine Secrets. <CodeGroup> ```yaml anthropic.yml name: anthropic displayName: Anthropic apiFormat: anthropic baseUrl: https://api.anthropic.com catalog: source: static auth: - method: api-key - method: env - method: subscription-broker constraints: execution: sandbox harness: claude-code ``` ```yaml openrouter.yml name: openrouter displayName: OpenRouter apiFormat: openai baseUrl: https://openrouter.ai/api/v1 catalog: source: openrouter-api auth: - method: api-key - method: env ``` </CodeGroup> `apiFormat` ist der Wire-Dialekt — `openai` oder `anthropic`. Ein Connector im `openai`-Format kann zusätzlich `wireDialect: openai-modern` deklarieren, wie es die mitgelieferten OpenAI- und Azure-Connectors tun: Die Plattform schreibt das Ausgabelimit dann als `max_completion_tokens` und schickt Reasoning-Modellen keine eigene Temperatur mit — api.openai.com lehnt bei diesen Modellen `max_tokens` und jede vom Standard abweichende Temperatur ab, während OpenAI-kompatible Endpunkte von Drittanbietern die klassischen Felder behalten. `baseUrl` ist der feste Endpunkt; ein Connector, der ihn weglässt, deklariert stattdessen `endpointMode: per-credential`, so wie Azure OpenAI: Jede Azure-Ressource bedient ihren eigenen Endpunkt, also trägt dort jeder Zugangsdaten-Eintrag seine eigene URL. `catalog.source` ist eines von `static` (eine mitgelieferte Datei unter `configs/platform/system/models/`), `openrouter-api`, `models-endpoint` oder `none`. Jeder Eintrag unter `auth` ist eine Methode, die die Zugangsdaten dieses Anbieters nutzen dürfen, und eine Methode kann `constraints` tragen, die sie auf sandboxed Ausführung mit einem benannten Harness festlegen. ## Umgebungsvariable als Schlüsselquelle Wenn deine API-Schlüssel bereits in Kubernetes-Secrets, Vault oder einem Cloud-Secret-Manager liegen, müssen die Zugangsdaten das Secret nicht halten. Die Authentifizierungsmethode **Umgebungsvariable** speichert nur den _Namen_ einer Deployment-Variable, und die Plattform liest den Wert zur Aufrufzeit aus der Prozessumgebung. Das ist der von Ops verwaltete Weg: Der Schlüssel landet nie in der Anwendungsdatenbank, und Rotieren ist eine Sache des Deployments statt einer Admin-Aufgabe. Der Variablenname ist präfix-geschützt. Er muss mit `TALE_PROVIDER_KEY_` beginnen, und die App hält dieses Präfix im Formular fest, sodass nur das Suffix getippt wird: ```bash TALE_PROVIDER_KEY_OPENROUTER=sk-or-... TALE_PROVIDER_KEY_OPENAI_PROD=sk-... ``` <Note> Die Schranke ist fail-closed: Jeder Name ausserhalb des reservierten Präfixes wird abgelehnt. Genau das verhindert, dass Zugangsdaten ein fremdes Deployment-Geheimnis wie `SOPS_AGE_KEY` oder `BETTER_AUTH_SECRET` benennen und es als Bearer-Token an einen Anbieter-Endpunkt geschickt wird. Namen sind auf 40 Zeichen begrenzt — das Limit der Env-Synchronisierung von der Plattform zu Convex, denn ein längerer Name würde die Backend-Laufzeit nie erreichen. </Note> Definier die Variable so, dass sowohl der Plattform-Container als auch das Convex-Backend sie lesen können. Die Plattform synchronisiert ihre Umgebung beim Boot zu Convex, damit die dortigen Actions denselben Wert auflösen; eine nach dem Boot hinzugefügte oder geänderte Variable braucht einen Neustart des Plattform-Containers, bevor sie sichtbar wird. Werte werden getrimmt, was dir den Zeilenumbruch am Ende einer gemounteten Secret-Datei und den daraus folgenden `401` erspart. ## Broker-Secrets aus der Umgebung Zugangsdaten vom Typ **Abo-Broker** müssen sich erst beim Broker ausweisen, bevor sie einen Token-Pool holen können, und dieses Broker-Secret kann ebenfalls vom Deployment kommen. Seine Variablen tragen ein eigenes reserviertes Präfix, `TALE_TOKEN_SOURCE_`, getrennt von den Anbieter-Schlüsseln, damit die beiden Namensräume nicht verwechselt werden können. Es gilt dieselbe fail-closed-Regel: Ein Name ausserhalb des Präfixes wird abgelehnt. Im Formular heisst das Feld **Secret aus Umgebungsvariable**; lässt du es leer, wird das Broker-Secret stattdessen verschlüsselt bei den Zugangsdaten gespeichert. ## Was Organisationsdaten sind statt Deployment-Konfiguration Zugangsdaten, ihre Namen, ihre erlaubten Modelle, welcher Eintrag der Standard ist und welche aktiv sind — all das sind Organisationsdaten. Angelegt werden sie in der App, sie gehören genau einer Organisation, und es gibt keine Datei auf Platte, die du bearbeitest, um welche anzulegen — auch nicht auf einer selbst gehosteten Instanz. <Tip> Diese Trennung ordnet eine Aufgabe am schnellsten ein. Alles zur Frage, _welcher Anbieter existiert und was er kann_, ist ein mitgelieferter Connector; alles zur Frage, _wer ihn mit welchem Schlüssel aufrufen darf_, sind Zugangsdaten in der App. Die einzige Überschneidung ist der Weg über Umgebungsvariablen, bei dem das Deployment das Secret hält und die Zugangsdaten nur dessen Namen. </Tip> ## Wo das hingehört Die gesamte Oberfläche eines Operators besteht hier darin, Umgebungsvariablen bereitzustellen und zu wissen, welche Connectoren die Plattform mitbringt; alles andere rund um Anbieter passiert in der App. Die UI-Anleitung — Zugangsdaten anlegen, einen Standard wählen, erlaubte Modelle einschränken, Kataloge aktualisieren — ist [KI-Anbieter](/de/platform/admin/providers), was deine Leute am Ende sehen, steht im [Modellkatalog](/de/platform/models), und die Variablen selbst stehen neben dem Rest der Deployment-Konfiguration in der [Umgebungsvariablen-Referenz](/de/self-hosted/configuration/environment-reference). # Authentifizierung Source: https://tale.dev/docs/de/self-hosted/configuration/authentication Tale bringt vier Sign-in-Modi mit, die ein Operator pro Instanz wählt. Der Default ist lokales Passwort, mit einem Benutzer pro E-Mail; Microsoft Entra und generisches OIDC delegieren die Identität an einen externen Anbieter; trusted Headers übergibt die Verantwortung an einen Reverse-Proxy, der SSO upstream bereits terminiert. Die Entscheidung ist insofern dauerhaft, als sie prägt, wie Benutzer provisioniert werden — Modi nach Rollout zu wechseln ist möglich, aber jeder bestehende Benutzer muss auf die neue Identitätsquelle umgemappt werden. Lokales Passwort und trusted Headers schalten Env-Vars um ([Umgebungsvariablen-Referenz](/de/self-hosted/configuration/environment-reference)); Microsoft Entra und generisches OIDC werden pro Organisation in der laufenden App konfiguriert. Diese Seite ist der Modus-für-Modus-Durchgang — wann du jeden wählst, was er für den Benutzer verändert, was bricht, wenn er fehlkonfiguriert ist. ## Lokales Passwort (Default) Lokales Passwort ist der Modus, den du bekommst, wenn du nichts setzt. Die Plattform speichert einen bcrypt-Hash in Postgres, signiert die Session mit `BETTER_AUTH_SECRET`, und der Benutzer meldet sich mit einer E-Mail und einem Passwort an, mit dem der Admin ihn eingeladen hat. Kein externer Identitäts-Anbieter ist beteiligt. Greif danach auf kleinen Instanzen und Air-gapped-Deployments, wo das Hinzufügen eines IdP mehr Reibung erzeugt als es löst. Der Preis: Passwort-Reset läuft über den Admin (oder über E-Mail, wenn `SMTP_*` konfiguriert ist), und es gibt keine SSO-Story. ```bash # .env — keine Flags für lokales Passwort nötig HOST=localhost SITE_URL=https://localhost BETTER_AUTH_SECRET=... ``` ## Microsoft Entra Der Microsoft-Entra-Modus fügt einen **Weiter mit SSO**-Button zum Sign-in-Bildschirm hinzu und nimmt Benutzer aus einem Tenant an, den du kontrollierst. Es gibt keinen Env-Var-Schalter: Die Verbindung wird pro Organisation unter **Einstellungen > Enterprise-SSO** konfiguriert, sobald die Plattform läuft — wähle das Protokoll **Microsoft Entra ID** und trage Client-ID, Client-Secret und Issuer-URL aus deiner App-Registrierung ein. Der vollständige Durchgang, inklusive Rollen-Mapping und Gruppen-zu-Teams-Sync, ist [Enterprise-SSO und Bereitstellung](/de/platform/admin/enterprise-sso). Zwei Deployment-Werte müssen stimmen, bevor der Flow funktionieren kann: `SITE_URL`, weil die Sign-in-Redirect-URL daraus abgeleitet wird, und `BETTER_AUTH_SECRET`, das den OAuth-State signiert. Der Redirect-URI, den du in Entra registrierst, ist `${SITE_URL}${BASE_PATH}/http_api/api/sso/callback` — die Einstellungsseite zeigt die exakte URL zum Kopieren, und sie muss Byte für Byte übereinstimmen, sonst lehnt Entra den Sign-in mit `AADSTS50011` ab. Die Tenant-ID in der Entra-App-Registrierung grenzt ein, wer sich anmelden kann; eine Multi-Tenant-Registrierung akzeptiert jeden mit einem Microsoft-Konto, was selten ist, was du willst. ## Generisches OIDC Generisches OIDC akzeptiert jeden spec-konformen Identitäts-Anbieter — Keycloak, Authentik, Okta, Google Workspace. Die Konfiguration lebt auf der **Single Sign-On**-Karte unter **Einstellungen > Connectors**: Wähle den Anbietertyp **Generisches OIDC**, trag Aussteller-URL, Client-ID und Client-Secret ein, und Tale liest die Authorization-, Token- und Userinfo-Endpunkte aus dem `.well-known/openid-configuration`-Dokument des Ausstellers. Der Flow nutzt den Standard Authorization-Code-Grant mit PKCE (S256). Tale speichert kein Secret auf Platte für OIDC; Client-ID und Client-Secret liegen im verschlüsselten Credential-Store. Der Redirect-URI, den du bei deinem Anbieter registrierst, ist `${SITE_URL}/http_api/api/sso/callback`. Identitäts-Anbieter sind sich uneins, wo Claims liegen, also lässt dich die Karte auf deine zeigen. Die Felder **E-Mail-Claim**, **Namens-Claim** und **Gruppen-Claim** nehmen einen Claim-Namen oder einen Punktpfad in die Userinfo-Antwort — Keycloaks Realm-Rollen liegen zum Beispiel unter `realm_access.roles`. Rollenzuordnungsregeln weisen Plattformrollen beim Sign-in zu: Eine **Gruppe**-Regel matcht die Gruppen des Benutzers gegen ein Platzhalter-Muster (`platform-admin*` → Admin), eine **Claim**-Regel matcht einen beliebigen per Punktpfad aufgelösten Claim. **Teams automatisch bereitstellen** spiegelt die Gruppen, die dein Anbieter zurückgibt, bei jedem Sign-in als Tale-Teams — abzüglich der Gruppen, die du ausschließt. Ein durchgerechnetes Keycloak-Beispiel: Lege einen Confidential Client `tale-platform` mit dem Redirect-URI oben an, ergänze einen Group-Membership-Mapper, damit der Client `groups` in Userinfo ausgibt, setze dann in Tale den Aussteller auf `https://keycloak.example.com/realms/<realm>`, füge eine Gruppen-Regel `platform-admin*` → Admin hinzu und klicke **Verbindung testen** — das validiert die Discovery, bevor irgendetwas gespeichert wird. Das ist der Modus für Teams, die bereits einen IdP betreiben und ihre bestehende Identitäts-Oberfläche in Tale haben wollen. ## Trusted Headers Trusted Headers ist der Modus für Sites, die SSO an einem vorgelagerten Reverse-Proxy terminieren — oauth2-proxy, Pomerium, Authelia. Der Proxy authentifiziert den Benutzer und leitet identifizierende Header weiter (`X-Auth-Request-Email`, `X-Auth-Request-Preferred-Username`); Tale vertraut diesen Headern und legt den Benutzer-Datensatz on-the-fly an oder aktualisiert ihn. ```bash # .env TRUSTED_HEADERS_ENABLED=true ``` Das Bedrohungsmodell ist heikel. Alles, was den Plattform-Container mit diesen Headern erreichen kann, wird zum Benutzer, der in ihnen genannt ist. Beschränke den Plattform-Port so, dass nur der Proxy mit ihm sprechen kann (ein Docker-Netzwerk oder eine Host-Firewall-Regel), und exponier den Plattform-Container nie direkt zum Internet, wenn dieser Modus an ist. ## Wo das hingehört Die vier Modi sind im Geist gegenseitig ausschliessend, aber technisch additiv — Microsoft Entra und trusted Headers können auf derselben Instanz koexistieren, wenn deine IdP-Story mitten in der Migration steckt. Die volle per-Modus-Abwägungstabelle lebt in [Mitglieder und Rollen](/de/platform/admin/members-and-roles) auf der Benutzerseite; diese Seite deckt den Schalter des Operators ab. Die nächste Konfigurationsseite, die zu lesen sich lohnt, ist [Anbieter](/de/self-hosted/configuration/providers) — sobald Benutzer sich anmelden können, brauchst du immer noch mindestens einen Modell-Anbieter verdrahtet, bevor sie irgendetwas tun können. # Retention Source: https://tale.dev/docs/de/self-hosted/configuration/retention Retention in Tale ist die Policy, die alte Daten nach einem Zeitplan löscht — Chats, Dokumente, Audit-Logs, Workflow-Ausführungen, Token-Nutzungs-Ledger-Zeilen. Der Operator setzt Grenzen (Minimum und Maximum) pro Kategorie; der Admin jeder Organisation wählt das tatsächliche Retention-Fenster innerhalb dieser Grenzen über **Einstellungen > Governance > Retention-Policy**. Die Trennung existiert, damit ein Hosting-Team Compliance-Untergrenzen durchsetzen kann, ohne jede Mandantin im Detail zu mikromanagen. Diese Seite deckt die Operator-Oberfläche ab. Die Admin-seitigen Controls und die per-Kategorie-Beschreibungen leben in [Governance > Retention-Policy](/de/platform/admin/governance/policies-and-limits). ## Wie die Grenzen funktionieren Jede Retention-Kategorie — Chat-Threads, Dokumente, Kontakte, Lieferanten, Prompt-Templates, Ledger-Zeilen, Audit-Logs, Workflow-Ausführungen, Workflow-Trigger-Logs, Login-Versuche — hat ein `min` und ein `max`. Ein Org-Admin setzt einen Wert innerhalb dieses Fensters. Den Boden über eine bestehende Instanz hinweg anzuziehen ist ein mehrstufiger Flow: Operator schlägt die neue Grenze vor, jeder betroffene Admin sieht ein Banner, die Änderung greift, sobald sie akzeptiert ist. | Kategorie | Typische Untergrenze | Warum | | ------------------------- | -------------------- | ----------------------------------------------- | | Chat-Verlauf | 30 T | Die meisten wollen jüngsten Kontext, nicht ewig | | Dokumente | 1 J | Wissen veraltet langsam | | Audit-Logs | 1 J Minimum | Compliance-Frameworks erwarten ein Jahr | | Token-Nutzungs-Ledger | 90 T | Analytics und Budget-Berichte hängen an Zeilen | | Workflow-Ausführungs-Logs | 30 T | Debugging reicht selten weiter zurück | | Login-Versuche | 30 T | Brute-Force-Untersuchung braucht die Audit-Spur | Die mitgelieferten Defaults sind locker; zieh sie an, je nach deiner Compliance-Haltung. ## Wo du Grenzen setzt Unter dem Org-first-Layout sind Retention-Grenzen **pro Org**: editiere `retention.json` direkt im Unterbaum einer Org unter `TALE_CONFIG_DIR` (default `/app/data/` im Plattform-Container, also liegt die Datei unter `/app/data/<org>/retention.json`, z. B. `/app/data/default/retention.json`). Jede Org hat ihre eigene Datei; die `default`-Datei ist die Vorlage, die eine neue Installation beim ersten Start aufgreift. ```json { "chatHistory": { "min": 30, "max": 730, "unit": "days" }, "documents": { "min": 1, "max": 3650, "unit": "days" }, "auditLog": { "min": 365, "max": 3650, "unit": "days" }, "tokenLedger": { "min": 90, "max": 1095, "unit": "days" } } ``` Der Plattform-Container beobachtet die Datei; Änderungen schlagen ein Grenzen-Update für jede bestehende Org vor. Admins sehen den Vorschlag in ihrem **Retention-Policy**-Bildschirm und wenden ihn selbst an. Der Vorschlagen-dann-anwenden-Schritt ist Absicht: Eine Untergrenze anzuziehen kürzt Historie, was eine destruktive Aktion ist, die kein Operator stillschweigend bei jeder Mandantin landen sollte. Die vom Admin gewählten Aufbewahrungsfenster liegen in einer separaten Datei, `retention-policy.json`, neben den Grenzen im selben `governance/`-Ordner. Sie enthält flache Felder `<Kategorie>Enabled` / `<Kategorie>RetentionDays` (z. B. `"auditLogEnabled": true, "auditLogRetentionDays": 730`), nicht die `min`/`max`-Grenzen. Diese Datei schreibt **Einstellungen > Governance > Retention-Policy** in der App, Admins bearbeiten sie also normalerweise nie von Hand — halte sie getrennt von der vom Operator verwalteten Grenzen-Datei. ## Der Retention-Sweep Ein geplanter Cron in `tale-convex` läuft die tatsächliche Löschung. Jede Kategorie wird unabhängig gesweept — ein langsamer Lauf einer blockiert die anderen nicht. Löschungen sind audited (jede Kategorie hat ihr eigenes `*.retention_deleted`-Event), und eine Entität in ihrem Gnaden-Fenster wiederherzustellen ist von **Papierkorb** möglich, bevor der finale Sweep läuft. Audit-Log-Einträge unterliegen selbst der Retention, aber ihre Untergrenze wird pro Deployment durchgesetzt, nicht pro Org: Die strengste (kürzeste) Audit-Log-Retention über alle Orgs ist das, was tatsächlich läuft. Eine strengere Mandantin zieht alle enger — denk daran auf Multi-Tenant-Instanzen. ## Legal Hold Ein Legal Hold friert die Retention für einen bestimmten Scope ein: einen einzelnen Thread, einen Kunden-Datensatz oder eine ganze Organisation. Gehaltene Entitäten überspringen den Sweep, bis der Hold gelöst wird. Der Hold selbst ist audited; org-weite Holds sind laut genug, dass die UI eine Bestätigung anzeigt, bevor sie greifen. ## Wo das hingehört Die Grenzen-Datei ist der Hebel des Operators; die per-Kategorie-Fenster, die der Admin sieht, sind in [Retention-Policy](/de/platform/admin/governance/policies-and-limits) dokumentiert. Setzt du Grenzen gegen ein Compliance-Framework (DSGVO, HIPAA, SOC 2), ist die Audit-Log-Untergrenze meist das, was Auditoren zuerst prüfen. # TLS und Domains Source: https://tale.dev/docs/de/self-hosted/configuration/tls-and-domains Der `tale-proxy`-Container ist Caddy. Er besitzt die TLS-Terminierung, das Host-Routing und das Metric-Auth-Gate; jede Browser-seitige Anfrage landet zuerst hier. Die drei Modi — selbst signiert, Let's Encrypt, external — decken die drei Deployment-Formen ab, nach denen die meisten Operator greifen, und die Variable, die zwischen ihnen umschaltet, ist `TLS_MODE` in deiner `.env`. Die Env-Var-Referenz-Zeilen leben in [Umgebungsvariablen-Referenz](/de/self-hosted/configuration/environment-reference#tls). Diese Seite ist der per-Modus-Walkthrough und die Rezepte für Custom Domains und Bring-your-own-Zertifikate. ## Selbst signiert (Default) `TLS_MODE=selfsigned` lässt Caddy mit einem Zertifikat laufen, das es aus seiner internen CA generiert. Der Browser warnt beim ersten Mal, und der Host muss dem Cert vertrauen, um die Warnung zu unterdrücken — das ist für lokale Entwicklung gedacht: ```bash docker exec tale-proxy caddy trust ``` Das trust-Kommando importiert die CA von Caddy in den System-Trust-Store auf dem Host, der den Docker-Daemon laufen lässt. Andere Maschinen im Netzwerk sehen die Warnung weiter, ausser sie importieren die CA auch. Produktion nutzt diesen Modus nie. ## Let's Encrypt `TLS_MODE=letsencrypt` lässt Caddy ein echtes öffentliches Zertifikat ausstellen und erneuern. Drei Voraussetzungen müssen gelten, sonst scheitert die Ausstellungs-Schleife: - Der Hostname in `HOST` und `SITE_URL` löst zur öffentlichen IP des Hosts vom öffentlichen Internet auf. - Ports 80 und 443 sind vom öffentlichen Internet erreichbar (Port 80 trägt die ACME-HTTP-01-Challenge). - `TLS_EMAIL` ist auf ein Postfach gesetzt, das du liest — Let's Encrypt warnt dort vor Ablauf. ```bash # .env TLS_MODE=letsencrypt TLS_EMAIL=ops@yourdomain.com ``` Der erste Boot blockiert etwa eine Minute, während die ACME-Challenge läuft. Danach sind Erneuerungen automatisch 30 Tage vor Ablauf; Fehlschläge landen in `docker compose logs proxy`. ## Externer Proxy `TLS_MODE=external` lässt Caddy intern Klartext-HTTP servieren, und du stellst deinen eigenen Reverse-Proxy davor, der TLS upstream terminiert. Wähl das, wenn: - Du bereits ein CDN oder einen Load-Balancer betreibst, der Zertifikate handhabt. - Du TLS einmal am Rand deines VPCs terminieren und intern alles als Klartext laufen lassen willst. - Deine Compliance-Haltung eine bestimmte Zertifizierungsstelle verlangt, die Caddy nicht unterstützt. ```bash # .env TLS_MODE=external SITE_URL=https://tale.yourdomain.com # die URL, die deine Benutzer treffen ``` Der vorgelagerte Proxy braucht `X-Forwarded-Proto: https` auf jeder Anfrage, damit Tale korrekte Redirects und absolute URLs generiert. Ohne ihn landen Sign-in-Links auf `http://`, und das `Secure`-Flag des Auth-Cookies weist sie zurück. ## Custom Domain Die Domain selbst sind nur `HOST` und `SITE_URL`. Dasselbe Caddyfile in `tale-proxy` liest beide beim Boot. Änder sie, erstell den Proxy-Container neu (`docker compose up -d --force-recreate tale-proxy`), und die neue Domain ist innerhalb von Sekunden live. Let's Encrypt stellt für den neuen Namen bei der nächsten Anfrage, die den neuen Hostnamen trifft, neu aus. ```bash # .env HOST=tale.example.com SITE_URL=https://tale.example.com ``` Subpath-Deployments — Tale hinter `https://example.com/app/` — setzen zusätzlich `BASE_PATH=/app`. Der Reverse-Proxy upstream von Caddy strippt nichts; Tale handhabt das Präfix selbst. ## Bring-your-own-Zertifikat Für eine interne CA oder ein Wildcard-Cert, das du bereits besitzt, mountest du Cert und Schlüssel in `tale-proxy` und fügst eine `tls`-Direktive ins Caddyfile hinzu: ```yaml # compose.yml override services: proxy: volumes: - ./certs/fullchain.pem:/etc/tale/cert.pem:ro - ./certs/privkey.pem:/etc/tale/key.pem:ro environment: TLS_MODE: external # umgeht Caddys Auto-Ausstellung ``` Dann bau entweder ein `tale-proxy`-Image mit Custom-Caddyfile vor, oder stell deinen eigenen Reverse-Proxy vor Tale und bleib bei `TLS_MODE=external` — beide Pfade sind unterstützt, und der zweite ist einfacher. ## Wo das hingehört Die drei Modi decken die drei Deployment-Formen ab, die die meisten Teams treffen; die Env-Var-Zeilen leben in [Umgebungsvariablen-Referenz](/de/self-hosted/configuration/environment-reference#tls). Stellst du gerade einen frischen Produktions-Host auf, walkt [Produktions-Linux-Server-Install](/de/self-hosted/install/linux-server) Let's Encrypt End-to-End mit den Firewall- und DNS-Schritten in der richtigen Reihenfolge. # Secrets mit SOPS Source: https://tale.dev/docs/de/self-hosted/configuration/secrets-with-sops Tale speichert Anbieter-API-Schlüssel in `providers/*.secrets.json`-Dateien auf Platte. Der Default-Modus nach `tale init` verschlüsselt diese Dateien mit SOPS unter Verwendung eines age-Schlüssels; ein alternativer Modus liest mehrere Schlüssel aus einer Datei (der Rotations-Pfad); ein dritter Modus hält die Dateien als Klartext mit Dateimodus 0600 für Umgebungen, in denen die Platte at-rest verschlüsselt ist und die Rotation extern gehandhabt wird. Diese Seite ist der Operator-Durchgang durch die drei Modi und den sicheren Rotations-Pfad. Die Env-Vars, die die Modi steuern, sind `SOPS_AGE_KEY` und `SOPS_AGE_KEY_FILE` — ihre Referenz-Zeilen leben in [Umgebungsvariablen-Referenz](/de/self-hosted/configuration/environment-reference#provider-secrets-encryption). Diese Seite ist die längere Geschichte. ## Die drei Modi | Modus | Env-Vars | Wann nutzen | | -------------------- | ---------------------------------- | ------------------------------------------------------------------------ | | Inline age-Schlüssel | `SOPS_AGE_KEY=AGE-SECRET-KEY-1...` | Default nach `tale init`. Einzelner Host, einzelner Schlüssel. | | Schlüssel-Datei | `SOPS_AGE_KEY_FILE=/path/to/keys` | Pflicht für Rotation. Ein age-Schlüssel pro Zeile, `#`-Kommentare. | | Klartext bei 0600 | Beide unset | Platte at-rest verschlüsselt, oder externe Tooling schreibt die Dateien. | Der Plattform-Container wählt den Modus beim Boot. Die Inline-Form ist die einfachste; die Datei-Form ist die einzige, die mehrere Leser unterstützt (was Rotation ohne Downtime möglich macht); die Klartext-Form überspringt SOPS ganz und vertraut dem Dateisystem. ## Verschlüsselter Modus beim ersten Boot `tale init` generiert ein age-Schlüsselpaar und schreibt die private Hälfte in `SOPS_AGE_KEY` in deiner `.env`. Anbieter-Secret-Dateien, die durch **Einstellungen > Anbieter** geschrieben werden, werden beim Speichern verschlüsselt: ```bash # Inspizieren — die Datei ist SOPS-verschlüsseltes JSON, nicht der Klartext-API-Schlüssel cat providers/openai.secrets.json # { # "apiKey": "ENC[AES256_GCM,data:...,iv:...,tag:...]", # "sops": { ... } # } ``` Entschlüsselung passiert in-process, wenn der Plattform-Container die Datei liest. Der age-Schlüssel verlässt den Speicher des Plattform-Containers nie. ## Den age-Schlüssel rotieren Rotation ist der eine Pfad, den die Inline-Form nicht abdeckt — nur `SOPS_AGE_KEY_FILE` erlaubt dir, Ciphertext anzunehmen, der sowohl mit dem alten als auch dem neuen Schlüssel während des Umschaltens lesbar ist. Der Walk: ```bash # 1. Generiere einen neuen age-Schlüssel age-keygen -o /etc/tale/age-keys.txt # 2. Häng den neuen Schlüssel als zweite Zeile in der Datei an echo "AGE-SECRET-KEY-1NEW..." >> /etc/tale/age-keys.txt # 3. Richte .env auf die Datei und starte den Plattform-Container neu sed -i 's|^SOPS_AGE_KEY=.*|# SOPS_AGE_KEY=|' .env sed -i 's|^# SOPS_AGE_KEY_FILE=.*|SOPS_AGE_KEY_FILE=/etc/tale/age-keys.txt|' .env docker compose restart tale-platform tale-convex ``` Jetzt können sowohl der alte als auch der neue Schlüssel bestehende Dateien entschlüsseln. Speichere den API-Schlüssel jedes Anbieters unter **Einstellungen > Anbieter** neu — jedes Speichern erzeugt Ciphertext, der von beiden Schlüsseln lesbar ist. Sobald jeder Anbieter neu gespeichert wurde (die Spalte **Zuletzt rotiert** in der Anbieter-Tabelle sagt dir, welche noch alten Ciphertext halten), entferne den alten Schlüssel aus der Datei: ```bash # 4. Lass die alte Schlüssel-Zeile fallen und starte erneut neu sed -i '/^AGE-SECRET-KEY-1OLD/d' /etc/tale/age-keys.txt docker compose restart tale-platform tale-convex ``` Die Reihenfolge ist tragend: Entfern den alten Schlüssel nie, bevor jede Datei neu verschlüsselt ist, oder der Plattform-Container scheitert beim Lesen der noch-alten Dateien bei der nächsten Entschlüsselung. ## Auf Klartext umsteigen Wenn die Host-Platte at-rest verschlüsselt ist (LUKS, AWS-EBS-Verschlüsselung, GCP CSEK) und du keine zweite Schicht Schlüssel-Verwaltung willst, ist der Klartext-Modus die unterstützte Option. Kommentier sowohl `SOPS_AGE_KEY` als auch `SOPS_AGE_KEY_FILE` aus, starte neu und speichere jeden Anbieter neu — die Dateien sind jetzt JSON mit Modus 0600. Das Risikomodell verschiebt sich: Ein durchgesickerter Dateisystem-Dump ist jetzt ein durchgesickertes Credential-Dump. Wähl diesen Modus nur, wenn die Platten-Verschlüsselung echt ist (kein Häkchen), und auditiere die Backup-Story des Hosts, um zu bestätigen, dass kein Klartext-Snapshot entweicht. ## Externe Secret-Stores Wenn deine Schlüssel schon in Vault, einem Cloud-Secret-Manager oder Kubernetes Secrets liegen, ist die Umgebungsvariablen-Schlüsselquelle das erstklassige Pattern: zeig jeden Anbieter mit `secretsEnv` auf eine **Umgebungsvariable** und lass deinen Secret-Store diese Variable befüllen. Keine Klartext-Datei landet auf der Platte, und die Präfix-Schranke hindert einen Config-Schreib-Akteur daran, ein fremdes Deployment-Secret zu lesen. Der vollständige Mechanismus — die `TALE_PROVIDER_KEY_`-Präfix-Schranke, die Auflösungs-Reihenfolge und das Neustart-bei-Änderung-Verhalten — lebt in [Anbieter](/de/self-hosted/configuration/providers#environment-variable-key-source). Der Datei-Mount-Ansatz ist die Legacy-Alternative: Schreib die Klartext-`*.secrets.json`-Dateien aus dem externen Store und betreib Tale im Klartext-Modus. Das funktioniert weiterhin, legt aber den Klartext-Schlüssel auf die Platte und bricht, wenn du einen Anbieter über die UI speicherst — die UI überschreibt den Mount. Bevorzuge die Umgebungsvariablen-Quelle, sofern dich kein Zwang zur Datei-Form drängt. ## Wo das hingehört Diese Seite ist die vollständige Operator-Anleitung zur SOPS-Schicht; die Env-Var-Referenz-Zeilen sind in [Umgebungsvariablen-Referenz](/de/self-hosted/configuration/environment-reference#provider-secrets-encryption), und das Anbieter-Dateiformat selbst in [Anbieter](/de/self-hosted/configuration/providers). Ist ein Schlüssel durchgesickert, ist die Rotation derselbe Walk oben, dringend ausgeführt. # Umgebungsvariablen-Referenz Source: https://tale.dev/docs/de/self-hosted/configuration/environment-reference Tale liest seine Konfiguration aus einer einzigen `.env`-Datei im Repo-Stammverzeichnis. Etwa ein Dutzend Variablen sind beim ersten Boot Pflicht; der Rest stimmt das Verhalten ab. Diese Seite listet jede Variable, die [`.env.example`](https://github.com/tale-project/tale/blob/main/.env.example) mitbringt, was sie als Default hat und welche Oberfläche im Produkt sie konsumiert. Gruppen sind danach geordnet, wann du sie zuerst brauchst: Domain-Identität, TLS, Secrets, Datenbank, Instanz, Observability, Provider-Verschlüsselung. Ändert sich der Wert einer Variable, starte den Plattform-Container neu (`docker compose restart tale-platform tale-convex`), damit sie wirkt. ## Wie du diese Seite liest Jede Gruppe ist eine `Name | Default | Beschreibung`-Tabelle. Variablen, die als **Pflicht** markiert sind, müssen gesetzt sein, damit `docker compose up` erfolgreich ist. **Optionale** Variablen können unset bleiben; die Beschreibung benennt, was das Deaktivieren des Features bedeutet. Die `.env.example`-Datei bringt Inline-Kommentare mit, die jede Variable im Kontext erklären; diese Seite ist die strukturierte, gruppierte Referenz für dieselbe Menge. ## Domain-Identität (Pflicht beim ersten Boot) | Name | Default | Beschreibung | | ----------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | `HOST` | `localhost` | **Pflicht.** Hostname ohne Protokoll. Wird für Docker-Networking und ausgehende Mails verwendet. | | `SITE_URL` | `https://localhost` | **Pflicht.** Vollständige kanonische URL inklusive Schema und Port. Auth-Callbacks und externe Links nutzen das. | | `BASE_PATH` | unset | **Optional.** Pfad-Präfix für Subpath-Deployments hinter einem Reverse-Proxy (z. B. `/app`). Bei Root-Deployment unset lassen. | Die `SITE_URL` muss exakt mit dem übereinstimmen, was der Benutzer im Browser eingibt. Ein nachgestellter Slash, ein fehlender Port oder `http` statt `https` brechen den Auth-Callback und produzieren Sign-in-Schleifen. ## TLS | Name | Default | Beschreibung | | ----------- | ------------ | -------------------------------------------------------------------------------------------------------------------------- | | `TLS_MODE` | `selfsigned` | Einer von `selfsigned`, `letsencrypt`, `external`. Siehe [TLS und Domains](/de/self-hosted/configuration/tls-and-domains). | | `TLS_EMAIL` | unset | Kontakt-E-Mail für Let's-Encrypt-Benachrichtigungen. Optional aber empfohlen in Produktion. | `selfsigned` lässt Caddy mit einem generierten Cert laufen — der Browser warnt, in Ordnung für Development. `letsencrypt` braucht eine echte Domain und Ports 80/443 vom öffentlichen Internet erreichbar. `external` lässt Caddy nur HTTP servieren; ein vorgelagerter Reverse-Proxy terminiert TLS. ## Sicherheits-Secrets (Pflicht) | Name | Default | Beschreibung | | ----------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `BETTER_AUTH_SECRET` | Beispielwert in der Datei | **Pflicht.** Base64-Secret für den Better-Auth-Session-Signer. Generier mit `openssl rand -base64 32`. Rotieren invalidiert jede Session. | | `ENCRYPTION_SECRET_HEX` | Beispielwert in der Datei | **Pflicht.** 32-Byte-Hex-Schlüssel. AES-256-Schlüssel für OAuth- und Connector-Credentials und HKDF-Input für die Guardrails-Secret-Box. Generier mit `openssl rand -hex 32`. Rotieren invalidiert jeden DB-Ciphertext; Operator müssen betroffene Secrets neu eingeben. | | `INSTANCE_SECRET` | Beispielwert in der Datei | **Pflicht.** Wird genutzt, um den Convex-Admin-Schlüssel für `tale deploy` abzuleiten. Deploy schlägt fehl, wenn unset. | Ersetze die Werte, die in `.env.example` mitkommen, bevor du die Instanz exponierst — sie sind absichtlich unsichere Platzhalter. ## Datenbank Tale betreibt zwei Postgres-Datenbanken: den operativen Speicher (`db`, Port 5432) hinter dem Convex-Backend und den Wissens-Korpus (`knowledge-db`, Port 5433), der Dokument-Chunks, Embeddings und gecrawlte Seiten hält. Beide sind ParadeDB und teilen sich `DB_PASSWORD`, aber sie sind unabhängig — zeig jede für sich auf externe Infrastruktur. | Name | Default | Beschreibung | | ------------------------ | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `DB_PASSWORD` | `tale_password_change_me` | **Pflicht.** Passwort für den selbst gehosteten Postgres-Benutzer. Vor der Produktion ändern. Von beiden Datenbank-Containern genutzt. | | `POSTGRES_URL` | aus `DB_PASSWORD` konstruiert | **Optional.** Überschreibt die automatisch konstruierte URL der operativen Datenbank. Nutze das, wenn du auf einen externen Postgres oder einen Nicht-Standard-Host/Port zeigst. | | `KNOWLEDGE_DATABASE_URL` | `postgresql://tale:${DB_PASSWORD}@knowledge-db:5432/tale_knowledge` | **Optional.** Verbindungs-URL, die das Convex-Backend für den Wissens-Korpus nutzt. Überschreib sie, um den Korpus auf dein eigenes verwaltetes ParadeDB zu verlagern — der datenresidenz-sensible Speicher wandert unabhängig. | | `KNOWLEDGE_DB_NAME` | `tale_knowledge` | **Optional.** Name der Wissensdatenbank. Der mitgelieferte `knowledge-db`-Container erstellt diese Datenbank beim ersten Boot. | Die auto-konstruierte operative Form ist `postgresql://tale:${DB_PASSWORD}@db:5432`. Convex erwartet diese URL ohne Datenbanknamen; der Name wird aus der Instanz-Konfiguration abgeleitet. Der Wissens-Korpus lebt in `tale_knowledge` mit den Schemata `private_knowledge` und `public_web`; die UI unter **Einstellungen > Datenresidenz** schreibt eine reichere Per-Store-Konfiguration als diese rohen Variablen, behandelt in [Datenresidenz](/de/self-hosted/configuration/data-residency). ## Observability | Name | Default | Beschreibung | | --------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | `SENTRY_DSN` | unset | Sentry-DSN für Error-Tracking. Unset zum Deaktivieren. Kompatibel mit selbst gehostetem GlitchTip und Bugsink. | | `SENTRY_TRACES_SAMPLE_RATE` | unset | Optionale Sample-Rate für Performance-Traces (`0.0`–`1.0`). Standard-Verhalten hängt vom Deployment ab. | | `METRICS_BEARER_TOKEN` | unset | Bearer-Token, das für den Zugriff auf die Prometheus-`/metrics/*`-Endpoints nötig ist. Unset hält Metrics-Endpoints von aussen unerreichbar. | `METRICS_BEARER_TOKEN` zu setzen exponiert zwei Endpoints hinter dem Token: `/metrics/platform` und `/metrics/convex` (Convex' 261 eingebaute Metriken, die jetzt auch die RAG- und Crawl-Timings tragen). Siehe [Observability-Konfig](/de/self-hosted/configuration/observability-config) für die Scrape-Konfiguration. ## Provider-Secrets-Verschlüsselung | Name | Default | Beschreibung | | ------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `SOPS_AGE_KEY` | unset | Inline-age-Secret-Key. Verschlüsselt `providers/*.secrets.json`. Standardmodus nach `tale init`. Mehrere Keys sind inline nicht unterstützt. | | `SOPS_AGE_KEY_FILE` | unset | Pfad zu einer Datei mit einem oder mehreren age-Keys (einer pro Zeile; `#`-Kommentare erlaubt). Pflicht für Key-Rotation. Schliesst sich mit der Inline-Form aus. | Wenn beide age-Vars unset sind, speichert Tale `providers/*.secrets.json` als Klartext-JSON mit Modus 0600. Erreich diesen Modus nur, wenn der Host-Storage at-rest verschlüsselt ist oder die Dateien von externem Tooling erzeugt werden (ein Kubernetes-Secret-Mount, ein Vault-Template). Einen age-Key zu rotieren bedeutet, den neuen Key anzuhängen, jeden Provider in der UI neu zu speichern, dann den alten Key zu entfernen. Siehe [Secrets mit SOPS](/de/self-hosted/configuration/secrets-with-sops) für den vollen Rotations-Walkthrough. Die Umgebungsvariablen-Schlüsselquelle braucht keinen Deployment-Schalter: Zugangsdaten können statt eines gespeicherten Schlüssels nur den _Namen_ einer Umgebungsvariable halten, solange dieser Name das reservierte Präfix `TALE_PROVIDER_KEY_` trägt. Die Schranke ist fail-closed — jeder andere Name wird abgelehnt, das Feld kann also nie auf ein fremdes Deployment-Geheimnis zeigen — und Namen sind auf 40 Zeichen begrenzt. Definier die Variable hier oder in deinem Secret-Manager, damit sowohl die Plattform als auch das Convex-Backend sie lesen können; den vollen Mechanismus beschreibt [Anbieter](/de/self-hosted/configuration/providers). Zugangsdaten mit Subscription-Broker haben einen zweiten, getrennten Namensraum für das Geheimnis, das Tale **dem Broker** präsentiert: Dieses Feld nimmt einen Umgebungsvariablen-Namen unter dem reservierten Präfix `TALE_TOKEN_SOURCE_`, begrenzt auf 60 Zeichen. Die zwei Präfixe bleiben mit Absicht getrennt — ein Broker-Geheimnis ist kein Anbieter-API-Schlüssel, und keines der Felder kann eine Variable außerhalb seines eigenen Namensraums benennen. ## Feature-Flags Optionale Schalter für Features, die standardmässig nicht aktiviert sind. Jeder Flag schaltet ein Feature beim Boot ein oder aus; das Umschalten braucht einen Neustart des Plattform-Containers. | Name | Default | Beschreibung | | ------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | `TRUSTED_HEADERS_ENABLED` | `false` | Aktiviert den Trusted-Headers-Auth-Modus (Identität vom Reverse-Proxy geliefert). | | `FILE_EVENTS_ENABLED` | `false` | Aktiviert Datei-Watching-Events für die OneDrive-Sync-Connector. | | `TALE_DEPLOYMENT_CONFIG_ADMINS` | unset | Kommagetrennte E-Mail-Allowlist der Operatoren, die die Datenresidenz bearbeiten dürfen. Leer/nicht gesetzt = nur lesend für alle Admins. | ## Restart-Controller Der Opt-in-Sidecar `controller` treibt den Ein-Klick-Knopf **Anwenden & neu starten** auf der Seite [Datenresidenz](/de/self-hosted/configuration/data-residency): Er startet den `convex`-Container nach einer Konfigurationsänderung neu, damit die browserzugewandte Plattform nie Docker-Socket-Zugriff braucht. Aktiviere ihn mit `docker compose --profile controller up -d` und setze dann beide Variablen unten. Lass sie nicht gesetzt, um `convex` weiter von Hand neu zu starten. | Name | Default | Beschreibung | | ------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `CONTROLLER_TOKEN` | unset | Geteiltes HMAC-Geheimnis für **Anwenden & neu starten**. Der `controller` startet ohne es nicht, und die Plattform signiert jede Neustart-Anfrage damit — die beiden Werte müssen übereinstimmen. Erzeuge es mit `openssl rand -hex 32`. | | `CONTROLLER_URL` | unset | Basis-URL, über die die Plattform den `controller`-Sidecar erreicht (z. B. `http://controller:8004` im internen Netz). Ist diese oder `CONTROLLER_TOKEN` nicht gesetzt, zeigt **Anwenden & neu starten** stattdessen den manuellen Befehl. | ## RAG-Retrieval-Tuning Optionale Stellschrauben für die Wissensdatenbank-Suche. Der In-Process-RAG-Pfad (Convex-Node-Actions) bewertet Ergebnisse mit einem Cross-Encoder neu, wenn Re-Ranking an ist. Alle tragen das `RAG_`-Präfix und werden von den Containern `platform` und `convex` beim Boot gelesen; nach einer Änderung führe `docker compose restart platform convex` aus, damit sie wirkt. | Name | Default | Beschreibung | | ---------------------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `RAG_RERANKING_ENABLED` | `false` | Bewertet die zusammengeführten BM25- und Vektor-Kandidaten mit einem Cross-Encoder neu, bevor Ergebnisse zurückkommen. Mehr Präzision, mehr Latenz pro Query. | | `RAG_RERANKING_MODEL` | `cross-encoder/ms-marco-MiniLM-L-6-v2` | Cross-Encoder-Modellkennung, die an den Rerank-Provider übergeben wird. | | `RAG_RERANKING_PROVIDER` | `local` | Muss auf `api` gesetzt sein, um Re-Ranking zu aktivieren — es schickt die Kandidaten an einen externen `/rerank`-Endpoint (Cohere/Jina-kompatibel). `local` wird nicht mehr unterstützt und scheitert sofort. | | `RAG_RERANKING_TOP_K` | `10` | Maximale Anzahl Ergebnisse, die der Reranker zurückgibt. Die Antwort übersteigt nie das `top_k` der Anfrage. | | `RAG_RERANKING_CANDIDATES` | `30` | Grösse des Kandidaten-Pools für den Reranker. Ein breiterer Pool verbessert die Neubewertung und kostet proportional mehr Zeit pro Query. | | `RAG_RERANKING_API_BASE_URL` | unset | Basis-URL für den Rerank-Provider; die Plattform ruft `{base_url}/rerank` auf. Pflicht, wenn Re-Ranking aktiviert ist. | | `RAG_RERANKING_API_KEY` | unset | Bearer-Token für den externen Rerank-Endpoint. Unset lassen für unauthentifizierte Endpoints. | Re-Ranking ist standardmässig deaktiviert, weil es Latenz pro Query addiert und von einem externen Endpoint abhängt. Aktiviere es — indem du `RAG_RERANKING_PROVIDER=api` setzt und `RAG_RERANKING_API_BASE_URL` auf einen gehosteten Rerank-Service zeigst — wenn Retrieval-Präzision wichtiger ist als Antwortzeit. Es gibt kein In-Process-Modell zum Herunterladen oder Cachen; mit ausgeschaltetem Re-Ranking gibt die Suche das einfache zusammengeführte BM25-+-Vektor-Ranking zurück. ## Sitzungen | Name | Default | Beschreibung | | ------------------------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `SESSION_IDLE_TIMEOUT_MINUTES` | unset | **Optional.** Meldet eine Sitzung nach so vielen Minuten Inaktivität ab (`1`–`1440`). Das Fenster verschiebt sich bei Aktivität und wird serverseitig durchgesetzt — über E-Mail-/Passwort-, SSO- und Trusted-Headers-Sitzungen. | Lass es unset, um die Standard-Sitzungsdauer zu behalten. Wenn gesetzt, läuft eine inaktive Sitzung serverseitig ab, sobald das Fenster verstrichen ist, während eine aktive sich bei jeder Anfrage weiter verschiebt. Org-Admins können das wirksame Fenster pro Organisation verkürzen — niemals über diese Obergrenze hinaus verlängern — über die [Governance-Richtlinie zur Sitzungs-Leerlaufzeit](/de/platform/admin/governance/policies-and-limits); inaktive Sitzungen unter dieser Richtlinie widerruft ein Lauf, der etwa alle fünf Minuten läuft. ## Video-Link-Ingestion (yt-dlp) Liest Tale einen Video-Link ein, holt es dessen Transkript für den Agenten. YouTube blockiert automatisierten Zugriff von Rechenzentrums-/Server-IPs, sodass dies bei einer Cloud-Bereitstellung fehlschlagen kann. Die Bereitstellung bringt standardmäßig einen PO-Token-Provider verdrahtet mit (das vollständige Bild liefert [Video-Ingestion](/de/self-hosted/configuration/video-ingestion)); die Optionen unten sind optionale Überschreibungen und Eskalationen. Keine garantiert eine Umgehung — eine saubere Ausgangs-IP ist der wirksamste Hebel. Vom `convex`-Container gelesen und bei jeder Ingestion neu ausgewertet, sodass eine Änderung ohne Neustart greift. | Name | Standard | Beschreibung | | -------------------------------- | -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `VIDEO_INGEST_PROXY_URL` | nicht gesetzt | yt-dlp-Ausgang über einen Proxy leiten (eine Residential-/ISP-IP funktioniert am besten; Rechenzentrums-Proxys sind meist ebenfalls markiert). Schemata: `http`, `https`, `socks4`, `socks4a`, `socks5`, `socks5h` — bevorzugt `socks5h://`, damit DNS am Proxy aufgelöst wird. | | `VIDEO_INGEST_POT_PROVIDER_URL` | `http://bgutil-provider:4416` (eingebacken) | Basis-URL des PO-Token-Providers, der die GVS-Tokens liefert, die YouTubes Bot-Sperre auflösen. Standardmäßig das `bgutil-provider`-Compose-Sidecar, wenn das eingebackene Plugin vorhanden ist — nur setzen, um auf einen Provider auf einem anderen Host zu verweisen. | | `VIDEO_INGEST_FETCH_POT` | `always`, sobald ein Provider angebunden ist | Wann yt-dlp PO-Tokens beim Provider anfordert (`never`/`auto`/`always`). yt-dlps eigenes `auto` holt für den Player-Request nie ein Token — genau dort schlägt die Bot-Sperre zu —, deshalb setzt Tale mit Provider standardmäßig `always`. `never` umgeht einen fehlerhaften Provider. | | `VIDEO_INGEST_YTDLP_PLUGIN_DIRS` | `/opt/yt-dlp/plugins` (eingebacken) | Verzeichnis, aus dem yt-dlp Plugins lädt — jedes Plugin eine Ebene tiefer verschachtelt (`<dir>/<name>/yt_dlp_plugins/…`). Standardmäßig das eingebackene bgutil-Plugin-Verzeichnis, wenn vorhanden; nur überschreiben, um eigene Plugins zu ergänzen. | | `VIDEO_INGEST_COOKIES_FILE` | nicht gesetzt | Pfad zu einem Netscape-Cookie-Jar. Gast-Cookies aus einer Inkognito-Sitzung erhöhen das Ratenlimit ohne Sperrrisiko; Konto-Cookies schalten gesperrte Inhalte frei, riskieren aber das Konto. | | `VIDEO_INGEST_PLAYER_CLIENT` | `default,tv_simply` | Kommagetrennte Fallback-Liste der YouTube-Player-Clients. Mit angebundenem PO-Token-Provider erweitert sich der Standard auf `default,mweb,tv_simply` (mweb benötigt ein GVS-Token); explizit setzen, um eine Liste zu erzwingen. | | `VIDEO_INGEST_PO_TOKEN` | nicht gesetzt | Manuell gesetztes PO-Token (`CLIENT.CONTEXT+TOKEN`). Vor allem zum Testen — Tokens sind an die Video-ID gebunden und kurzlebig; den Provider bevorzugen. | | `VIDEO_INGEST_IMPERSONATE` | nicht gesetzt | Ziel für Browser-TLS/JA3-Imitation (z. B. `safari`). Erfordert `curl_cffi` im Image; nicht setzen, sofern nicht verfügbar. | | `VIDEO_INGEST_BIN_DIR` | nicht gesetzt | Verzeichnis, das dem `PATH` des yt-dlp/ffmpeg-Kindprozesses vorangestellt wird, damit ein selbst bereitgestelltes `yt-dlp` (samt Deno-Runtime) außerhalb der eingebackenen Bin-Verzeichnisse zuerst gefunden wird. Das `convex`-Image backt yt-dlp in den `PATH` ein, dort also nicht gesetzt lassen; auf einem Host- oder Dev-Rechner mit eigener Toolchain setzen. | | `VIDEO_INGEST_FFMPEG_LOCATION` | `/usr/bin/ffmpeg` | Absoluter Pfad zu dem ffmpeg, das yt-dlp für die Nachbearbeitung nutzt (Untertitel-Konvertierung, Audio-Extraktion). Überschreiben, wenn ffmpeg woanders liegt — z. B. Homebrews `/opt/homebrew/bin/ffmpeg` auf einem macOS-Dev-Rechner. | Keine dieser Optionen garantiert Erfolg gegen YouTubes adaptive Erkennung. Gewöhnliche öffentliche Videos, weniger aggressive Plattformen oder eine Bereitstellung mit Residential-IP bzw. Selbst-Hosting funktionieren üblicherweise auch ohne sie. ## Wo das hingehört Die Variablen hier sind die Kontaktoberfläche des Operators; die UI-Oberfläche, die die meisten von ihnen konsumiert, lebt unter [Plattform-Verwaltung](/de/platform/admin/overview). Provider-Keys sind die eine Halb-und-Halb-Sache: die Keys selbst leben in `providers/*.secrets.json`, aber die UI unter **Einstellungen > KI-Anbieter** ist, wie du sie in der Praxis hinzufügst und rotierst. Die nächste Lektüre, die sich lohnt, ist [Anbieter](/de/self-hosted/configuration/providers) — sie behandelt die mitgelieferten Connector-Dateien und die reservierten Variablen, die Anbieter-Schlüssel halten. # Datenresidenz Source: https://tale.dev/docs/de/self-hosted/configuration/data-residency Eine selbst gehostete Tale-Installation läuft auf Infrastruktur, die du ohnehin schon kontrollierst, also liegen ihre Daten standardmäßig auf deinen Hosts. **Datenresidenz** ist für den Fall gedacht, dass du einzelne Datenspeicher auf dein eigenes verwaltetes Postgres oder deinen Objektspeicher ausrichten willst statt auf die mitgelieferten Container — etwa um Dokumenttext in einer Datenbank zu halten, die dein Team betreibt, oder hochgeladene Dateien in deinem eigenen S3-Bucket. Der Wissens-Korpus läuft genau deshalb als eigener Container (`knowledge-db`), damit er sich unabhängig von der operativen Datenbank verlagern oder ersetzen lässt — er ist der Speicher, um den sich die meisten Residenz-Anforderungen drehen. Administratoren konfigurieren das unter **Einstellungen > Datenresidenz**; die Änderung wird in eine einzige Konfigurationsdatei auf Deployment-Ebene geschrieben und **greift, sobald die betroffenen Container neu starten**. Diese Seite behandelt, was sich verlagern lässt, die eine Voraussetzung, die zubeißt (ParadeDB), wie die Konfiguration abgelegt und angewendet wird, und wie du sicher neu startest. ## Bearbeitung aktivieren **Einstellungen > Datenresidenz** ist eine einzige Seite mit zwei Arten von Abschnitten: den deployment-weiten Speichern, die sich alle Organisationen teilen, und den Speichern, die eine einzelne Organisation selbst mitbringt. Jeder Abschnitt erscheint lesend oder bearbeitbar, je nachdem, was die lesende Person ändern darf, und die Seite benennt den Zustand. Ansehen darf jeder Owner oder Admin einer Organisation; die **deployment-weiten Speicher bearbeiten** — einen Datenspeicher umlenken, Secrets speichern, einen Verbindungstest laufen lassen oder einen Neustart auslösen — darf nur eine benannte Allowlist von Operatoren. Trage deren Anmelde-E-Mails (kommagetrennt) in `.env` ein und starte neu: ```bash TALE_DEPLOYMENT_CONFIG_ADMINS=alice@example.com,bob@example.com ``` Ist die Allowlist leer oder nicht gesetzt, zeigen die Deployment-Abschnitte Administratoren die aktuelle Konfiguration weiterhin an, aber nur lesend — die Kopfzeilen-Aktionen **Deployment speichern** und **Anwenden & neu starten** erscheinen nur für Operatoren auf der Allowlist. Nur ein angemeldeter Admin, dessen E-Mail auf der Liste steht, bekommt diese Abschnitte bearbeitbar; die Seite nennt dir, welche E-Mail einzutragen ist. Die Entrypoints lesen die Konfigurationsdatei unabhängig von der Allowlist, also kann ein Operator, der die Datei lieber direkt auf der Platte bearbeitet, das tun, ohne UI-Bearbeiter zu benennen. ## Was du verlagern kannst Drei Speicher, jeder unabhängig und optional. Eine fehlende Einstellung bedeutet „nimm den mitgelieferten Default" — eine frische Installation ohne Konfiguration bleibt also unverändert. - **Wissensdatenbank** — der Wissens-Korpus: Dokumentmetadaten, der extrahierte Chunk-Text, Embeddings, der BM25-Index, der semantische Cache und die gecrawlten Webseiten. Sie kommt als mitgelieferter `knowledge-db`-Container (`tale_knowledge`, mit den Schemata `private_knowledge` und `public_web`) und ist der Speicher, um den sich die meisten Residenz-Anforderungen drehen, weil er deinen Dokumentinhalt hält. Richte ihn auf dein eigenes verwaltetes Postgres aus, um den Korpus auf Infrastruktur zu halten, die dein Team betreibt. - **Dateispeicher** — wo hochgeladene Dateien (die ursprünglichen Blobs) liegen. Standardmäßig sitzen sie auf dem lokalen Convex-Volume; du kannst sie auf einen externen S3-kompatiblen Bucket ausrichten. - **Anwendungsdatenbank** (erweitert) — die operative Convex-Datenbank (der mitgelieferte `db`-Container). Das Convex-Backend leitet den Namen dieser Datenbank aus `INSTANCE_NAME` (`tale_platform`) ab und verbindet sich nur über Host:Port, daher muss das externe Postgres eine Datenbank mit genau dem Namen `tale_platform` enthalten. Ihr TLS-Modus wird vom Convex-Treiber vorgegeben und ist nicht konfigurierbar. > Hinweis: Die Wissensdatenbank und die Anwendungsdatenbank sind zwei separate Postgres-Instanzen — die eine zu verschieben rührt die andere nicht an. Die Wissensdatenbank zu verlagern verschiebt den extrahierten Text und die Embeddings; die ursprünglich hochgeladenen Dateien wandern erst mit, wenn du auch den **Dateispeicher** auf S3 ausrichtest. ## Die ParadeDB-Voraussetzung Die Wissensdatenbank nutzt zwei Postgres-Erweiterungen: `vector` (pgvector) für Embeddings und `pg_search` (ParadeDB) für die Volltext-/BM25-Hybrid-Suche. Ein externes Wissens-Postgres **muss ParadeDB ausführen** (das beide bündelt), damit die Suchqualität voll erhalten bleibt. Richtest du es auf ein schlichtes Postgres aus, das nur `pgvector` hat, funktionieren Indexierung und Vektor-Suche weiter, aber die Hybrid-Suche fällt auf **reine Vektor-Suche** zurück — die BM25-Hälfte wird still übersprungen. Der Knopf **Verbindung testen** meldet die Verfügbarkeit von `pgvector` und `pg_search`, damit du das siehst, bevor du dich festlegst. Die externe Wissensdatenbank muss bereits existieren (sie kann jeden Namen tragen, den du einträgst — `tale_knowledge` per Konvention) mit den Schemata `private_knowledge` und `public_web`; die Baseline-Schema-Migrationen leben in [`services/db/migrations/`](https://github.com/tale-project/tale/tree/main/services/db/migrations) und werden per dbmate angewendet, wenn die Datenbank hochkommt. ## Wissensdatenbanken pro Organisation Die Speicher oben gelten deployment-weit — jede Organisation teilt sie sich. Eine einzelne Organisation kann stattdessen **ihren eigenen** Wissens-Korpus auf ein Postgres ausrichten, das du für sie bereitstellst, während jede andere Org weiter den mitgelieferten `knowledge-db` nutzt. Greif dazu, wenn der Dokument- und Web-Crawl-Inhalt eines Mandanten auf Infrastruktur liegen muss, die vom Rest isoliert ist — eine strengere Residenz-Anforderung, als der Deployment-Default sie erfüllt. Der **gesamte** Wissens-Korpus der Org wandert — beide Schemata: `private_knowledge` (Dokumentmetadaten, Chunk-Text, Embeddings und der semantische Cache) und `public_web` (die vom Crawler erfassten Website-Seiten, ihr Chunk-Text und die Embeddings). Nichts in der Wissensdatenbank einer Organisation wird mit einer anderen Organisation geteilt. Die Verbindung liegt im eigenen Konfigurationsverzeichnis der Organisation, nicht in der Deployment-Datei: - `$TALE_CONFIG_DIR/<orgSlug>/knowledge/connection.json` — Host, Port, Datenbank, Benutzer und sslmode. - `$TALE_CONFIG_DIR/<orgSlug>/knowledge/connection.secrets.json` — das Passwort, SOPS-verschlüsselt, sobald ein SOPS-Age-Schlüssel konfiguriert ist (siehe [Secrets mit SOPS](/de/self-hosted/configuration/secrets-with-sops)). - `$TALE_CONFIG_DIR/<orgSlug>/knowledge/embedding.json` — das Embedding-Modell der Organisation: Anbieter, optional hinterlegte Zugangsdaten, Modell-Tag, Vektorbreite und eine optionale OpenAI-kompatible Basis-URL. Dieselbe ParadeDB-Voraussetzung gilt. Die Org prüft ihre Kandidaten-Datenbank mit einem organisationsweiten Verbindungstest, der die Verfügbarkeit von `pgvector` und `pg_search` meldet, bevor sie umschaltet; ein Ziel mit nur pgvector lässt die Suche dieser Org auf reine Vektor-Suche zurückfallen. Die Datenbank darf leer starten — Tale legt die Schemata `private_knowledge` und `public_web` beim ersten Zugriff an, du wendest die Baseline-Migrationen also nie von Hand an. Dieser Weg fällt sicher zurück. Eine Organisation ohne `connection.json` nutzt weiter den Deployment-Default `knowledge-db` genau wie zuvor, das Feature ändert also nichts für Orgs, die sich nicht dafür entscheiden. Zwei Organisationen, die auf dieselbe Datenbank zeigen, teilen sich einen Verbindungs-Pool, und — anders als die deployment-weiten Speicher — braucht eine Änderung pro Org keinen Container-Neustart: die nächste Anfrage dieser Org wird auf ihre eigene Datenbank geleitet. Ein Inhaber oder Admin der Organisation kann diese Verbindung auch über die UI verwalten: die Organisations-Abschnitte von **Einstellungen > Datenresidenz** lesen und schreiben genau diese Dateien, mit demselben Verbindungstest vor dem Umschalten. Diese Abschnitte bleiben für Inhaber und Admins der Organisation bearbeitbar, ob die Operator-Allowlist sie nennt oder nicht — die Dateien dahinter gehören der Organisation, nicht dem Deployment. Die JSON-Dateien auf der Platte bleiben die Quelle der Wahrheit — ein Operator, der sie lieber von Hand bearbeitet, braucht keinen UI-Schritt. ### Das Embedding-Modell der Organisation Die Wissenssuche braucht eine weitere Einstellung pro Organisation, bevor sie überhaupt laufen kann: das **Embedding-Modell** — welcher Anbieter und welches Modell Dokumente und Suchanfragen in Vektoren umwandeln, und mit exakt welcher Vektorbreite. Ohne diese Angabe verweigern Indexierung und Suche mit einem konkreten Hinweis, statt ein Modell zu raten. Richte es im Abschnitt **Embedding-Modell** von **Einstellungen > Datenresidenz** ein (oder schreib `embedding.json` von Hand): Wähle einen Anbieter, für den Zugangsdaten hinterlegt sind, nenne das Modell-Tag so, wie der Anbieter es schreibt, und gib die Breite an, die das Modell erzeugt — sie wird nie aus dem Modellnamen abgeleitet, weil eine falsche Vermutung Vektoren schreibt, mit denen die Suche stillschweigend nichts anfangen kann. Die Breite wird **pro Datenbank** festgelegt, sobald der erste Vektor geschrieben ist. Auf der gemeinsamen `knowledge-db` des Deployments müssen sich also alle Organisationen auf eine Breite einigen; eine Organisation, die ein anderes Embedding-Modell mit anderer Breite will, ist genau der Fall für eine eigene Wissensdatenbank oben. ## Objektspeicher pro Organisation Dasselbe Pro-Organisation-Muster deckt hochgeladene Dateien ab. Eine einzelne Organisation kann **ihre eigenen** Datei-Blobs — Knowledge-Hub-Dokumente, Chat-Anhänge, Audio und generierte Medien — auf einen S3-kompatiblen Bucket ausrichten, den du für sie bereitstellst (AWS S3, MinIO, Cloudflare R2, …), während jede andere Org weiter den Deployment-Default nutzt. Der Bucket gehört dieser einen Organisation; nichts darin wird mit anderen Organisationen geteilt. Die Verbindung liegt neben der Wissens-Verbindung im Konfigurationsverzeichnis der Organisation: - `$TALE_CONFIG_DIR/<orgSlug>/object-storage/connection.json` — Region, optionaler Endpoint (für MinIO/R2), Path-Style-Flag, Bucket und ein optionales Key-Präfix. - `$TALE_CONFIG_DIR/<orgSlug>/object-storage/connection.secrets.json` — das Schlüsselpaar, SOPS-verschlüsselt, sobald ein SOPS-Age-Schlüssel konfiguriert ist (siehe [Secrets mit SOPS](/de/self-hosted/configuration/secrets-with-sops)). Anders als der deployment-weite S3-Schalter oben ist dieser Weg **nicht** nur für Neuinstallationen: Sobald die Konfiguration existiert, landen neue Uploads im Bucket der Org, während zuvor gespeicherte Dateien lesbar bleiben, wo sie sind — gemischte Referenzen werden unterstützt, du kannst also jederzeit umschalten. Früher gespeicherte Dateien bleiben im Convex-Speicher, bis du sie mit dem Blob-Backfill unten verlagerst. Entfernst du die Konfiguration, landen neue Uploads wieder im Deployment-Default; bereits in den Bucket geschriebene Dateien bleiben dort, Tale kann sie aber erst wieder lesen, wenn die Verbindung erneut eingerichtet ist. Ein Neustart ist in keine Richtung nötig. Org-Admins verwalten auch diese Verbindung in denselben Organisations-Abschnitten von **Einstellungen > Datenresidenz**; der dortige Verbindungstest führt einen echten Hochladen-Lesen-Löschen-Durchlauf gegen den Bucket aus, bevor du dich festlegst. Wie bei der Wissens-Verbindung bleiben die JSON-Dateien die Quelle der Wahrheit. > **Erlaube den Origin der App in der CORS-Policy des Buckets.** Uploads und Downloads laufen über vorsignierte URLs direkt zwischen Browser und Bucket, der Bucket muss Cross-Origin-Anfragen von der URL deines Deployments also akzeptieren — erlaube diesen Origin mit den Methoden `GET`, `PUT` und `HEAD` sowie allen Request-Headern (Cloudflare R2: **Settings > CORS Policy** des Buckets; AWS S3 und MinIO: die CORS-Konfiguration des Buckets). Der Verbindungstest in der App läuft auf dem Server, nicht im Browser — eine fehlende CORS-Policy zeigt sich deshalb erst später, als fehlgeschlagener Upload. ### Vorhandene Dateien in den Bucket verschieben Den Bucket zu verbinden leitet nur **neue** Uploads um; die Blobs, die vor der Verbindung geschrieben wurden, bleiben in Convex' `_storage` und funktionieren weiter über die gemischten Referenzen oben. Um auch diese Historie auf deine eigene Infrastruktur zu holen — der eigentliche Sinn der Datenresidenz — führe den **Blob-Backfill** aus: Er kopiert jeden vorhandenen Blob in den Bucket der Org, prüft, dass er Byte für Byte identisch zurückkommt, schreibt jede referenzierende Zeile um und löscht die Convex-Kopie. Ein Org-Admin startet ihn in der UI: Ist die Bucket-Verbindung gespeichert, zeigt der Objektspeicher-Abschnitt von **Einstellungen > Datenresidenz** die Schaltfläche **Bestehende Dateien verschieben** — bestätige, und der Umzug läuft im Hintergrund, während Uploads weiter funktionieren; eine Statuszeile im selben Abschnitt meldet Fortschritt und Ausgang des letzten Laufs. Ein Operator mit Convex-CLI-Zugriff kann dieselbe Engine stattdessen aus einer Shell starten und die ID der Organisation übergeben. Mach zuerst einen Probelauf, um zu sehen, was verschoben würde, dann den echten Lauf: ```bash # Probelauf — zählt und sampelt, was verschoben würde, schreibt nichts: bunx convex run object_storage/backfill_actions:migrateOrgBlobsToObjectStorage '{"organizationId":"<organizationId>","dryRun":true}' # Der echte Lauf — lass dryRun weg, sobald die Zahlen stimmen: bunx convex run object_storage/backfill_actions:migrateOrgBlobsToObjectStorage '{"organizationId":"<organizationId>"}' ``` Der Backfill ist **idempotent** und **org-gebunden**: Er verschiebt nur die Blobs dieser Organisation, überspringt alles, was schon im Bucket liegt, und lässt jede Convex-Quelle stehen, bis ihre Kopie verifiziert ist — ein erneuter Lauf nach einer Unterbrechung setzt also sicher fort. Ein echter Lauf braucht die zuvor konfigurierte Bucket-Verbindung; ein Probelauf nicht. Das ist bewusst **keine** versionierte Framework-Migration — er läuft auf Abruf, pro Organisation, wenn du die Historie eines Mandanten verlagern willst, nicht an einer Release-Grenze. ## Dateispeicher auf S3 Externer Dateispeicher ist alles-oder-nichts über die Speicher-Use-Cases von Convex hinweg, also gibst du **fünf Buckets** an — files, exports, snapshot-imports, modules und search — plus Region und Anmeldedaten. Für S3-kompatible Dienste (MinIO, Cloudflare R2) setzt du den Endpunkt und aktivierst die Path-Style-Adressierung. > **Nur Greenfield.** Den Dateispeicher von lokal auf S3 umzustellen migriert die bereits auf dem lokalen Volume liegenden Blobs **nicht** — Convex sucht sie im Bucket und findet sie nicht. Setze S3 bei der ersten Installation, oder kopiere den vorhandenen lokalen Speicher vorab in den Bucket, bevor du umstellst. ## Wie die Konfiguration abgelegt wird Speichern schreibt zwei Dateien im Konfigurations-Root (nicht unter einem Org-Verzeichnis): - `deployment.json` — die nicht geheime Konfiguration (Hosts, Ports, Buckets, Modi). - `deployment.secrets.json` — die Datenbank-Passwörter und S3-Schlüssel, SOPS-verschlüsselt (siehe [Secrets mit SOPS](/de/self-hosted/configuration/secrets-with-sops)). Beim Boot liest der `convex`-Entrypoint diese und leitet seine Verbindungen ab, bevor er startet. Wissens-Ingestion und Retrieval laufen im Convex-Backend, also ist es der einzige Container, der die Verbindung zur Wissensdatenbank öffnet — es gibt keinen separaten Retrieval-Dienst zu konfigurieren. Der Vertrag ist **fail-closed**: ein vorhandenes, aber unparsbares `deployment.json`, ein nicht entschlüsselbares Secret oder eine Konfiguration ohne Pflichtfelder **bricht den Start ab**, statt still auf die mitgelieferte Datenbank zurückzufallen — regulierte Daten fehlzuleiten ist schlimmer, als nicht zu starten. Eine fehlende Datei ist der normale Default-Pfad. ## Eine Änderung anwenden: Neustart Die Konfiguration wird beim Boot gelesen, also greift ein Speichern erst, wenn der **`convex`**-Container neu startet (die Plattform selbst muss nicht neu starten). Zwei Wege: - **Manuell** — `docker compose restart convex`, oder `tale deploy --services convex` für einen Zero-Downtime-Blue-Green-Roll. - **Ein Klick** — aktiviere den Opt-in-Dienst `controller` (`docker compose --profile controller up -d`). Er ist ein kleiner, nur intern erreichbarer Sidecar, der den erlaubten `convex`-Dienst auf eine HMAC-signierte Anfrage der App neu startet, damit die browserzugewandte Plattform nie Docker-Socket-Zugriff braucht. Läuft er, erledigt der Knopf **Anwenden & neu starten** den Neustart für dich; setze `CONTROLLER_TOKEN` (geteilt mit der Plattform) und `CONTROLLER_URL` in `.env`. Ohne ihn zeigt der Knopf den manuellen Befehl. Die relevanten Umgebungsvariablen sind `TALE_DEPLOYMENT_CONFIG_ADMINS` (die kommagetrennte E-Mail-Allowlist der bearbeitungsberechtigten Operatoren) und — nur beim Ein-Klick-`controller` — `CONTROLLER_TOKEN` (das geteilte HMAC-Geheimnis) und `CONTROLLER_URL` (z. B. `http://controller:8004`). Setze sie in `.env`. Siehe auch [Umgebungsvariablen-Referenz](/de/self-hosted/configuration/environment-reference) und [Secrets mit SOPS](/de/self-hosted/configuration/secrets-with-sops). # Video-Ingestion Source: https://tale.dev/docs/de/self-hosted/configuration/video-ingestion Liest Tale einen Videolink ein, ruft es das Transkript des Videos mit `yt-dlp` ab. Video-Plattformen — YouTube am aggressivsten — fordern Anfragen von Rechenzentrums- und Server-IPs mit einer „Bist du ein Mensch?"-Abfrage heraus, sodass eine frische, selbst gehostete Bereitstellung auf einer Cloud-VM beim Einlesen scheitern kann, wo ein Laptop an einem Heimanschluss durchkäme. Diese Seite behandelt die drei Ebenen, die Tale mitbringt, um daran vorbeizukommen — von der, die keine Konfiguration braucht, bis zu der, die am meisten verlangt. <Info> Verwaltete **Cloud**-Bereitstellungen führen diese Maßnahmen für dich aus — diese Seite richtet sich an Betreiber, die Tale auf eigener Infrastruktur betreiben. </Info> ## Ebene 1 — der PO-Token-Provider (Standard, keine Konfiguration) Die wirksamste Einzelmaßnahme ist ein **Proof-of-Origin-(PO-)Token**: ein signierter Wert, der eine Anfrage so aussehen lässt, als käme sie aus einer echten Browser-Session. Tale bringt einen fertig verdrahteten Token-Provider mit — das `yt-dlp`-Plugin ist ins Image eingebacken, und ein `bgutil-provider`-Sidecar liefert die Tokens über das interne Netz. Keine Umgebungsvariable ist nötig; ein frisches `docker compose up` oder `tale deploy` hat ihn am Laufen. Du kannst `yt-dlp` mit `VIDEO_INGEST_POT_PROVIDER_URL` auf einen Provider auf einem anderen Host verweisen oder mit `VIDEO_INGEST_PO_TOKEN` ein manuell erstelltes Token übergeben — beides ist in der [Umgebungsreferenz](/de/self-hosted/configuration/environment-reference) dokumentiert. Ein ausgefallenes Sidecar bricht den Stack nie: Das Einlesen fällt auf kein Token zurück, genau so, als gäbe es die Ebene nicht. ## Ebene 2 — ein Egress-Proxy Reicht das Token allein nicht — manche IP-Bereiche sind ohnehin markiert —, leite den Abruf über einen **Egress-Proxy** auf einer IP, der die Plattform vertraut. Residential- und ISP-gehostete Proxys funktionieren am besten; Rechenzentrums- und kommerzielle Proxys sind oft genauso markiert wie der Server selbst. Setz `VIDEO_INGEST_PROXY_URL` auf die Proxy-URL. Ein `socks5h://`-Schema löst DNS am Proxy auf (die sicherste Wahl); `http`, `https`, `socks4`, `socks4a`, `socks5` und `socks5h` werden alle akzeptiert. Der Wert darf Zugangsdaten enthalten — Tale entfernt sie aus jeder Log-Zeile. ```bash .env VIDEO_INGEST_PROXY_URL=socks5h://user:pass@residential.example:1080 ``` Der Proxy gilt für jede Phase eines Abrufs — Metadaten, Untertitel und Audio —, sodass das gesamte Einlesen einen vertrauenswürdigen Ausgangspfad teilt. ## Ebene 3 — der vorgewärmte Browser-Session-Pool Die stärkste Maßnahme präsentiert Cookies aus einer **echten Browser-Session, die die Bot-Abfrage bereits bestanden hat**. Tale hält einen Pool solcher Sessions, nach Domain geschlüsselt, und gibt jedem Abruf eine davon, sodass die Plattform einen wiederkehrenden Besucher statt eines erstmaligen Servers sieht. Sessions werden verschlüsselt gespeichert (der Cookie-Jar wird mit dem `ENCRYPTION_SECRET_HEX` der Bereitstellung versiegelt) und werden nie an vom Agent ausgeführten Code weitergegeben — sie leben nur in der serverseitigen Abruf-Ebene. Eine Session, die blockiert zu werden beginnt, wird automatisch abgekühlt und dann stillgelegt, und abgelaufene Sessions werden planmäßig aufgeräumt. Den Pool zu füllen ist ein fortgeschrittener, händischer Schritt: Erfasse einen Netscape-Cookie-Jar aus einem Browser, der die Abfrage für die Zielplattform gelöst hat, und importier ihn dann über die interne Action `importBrowserSession`. Derselbe Pool trägt auch das Web-Fetch-Tool und den Crawler des Agents, sodass eine für eine Domain vorgewärmte Session jedem serverseitigen Zugriff darauf zugutekommt. <Warning> Konto-Cookies schalten gesperrte Inhalte frei, setzen das Konto aber aufs Spiel, wenn die Plattform automatisierte Nutzung markiert. Nutze bevorzugt Cookies aus einem Wegwerf- oder eigens angelegten Konto und checke einen Cookie-Jar niemals in die Versionsverwaltung ein. </Warning> ## Welche Ebene brauche ich? <CardGroup cols="2"> <Card title="Gerade deployt, einige Videos schlagen fehl" icon="circle-play"> Ebene 1 ist bereits aktiv. Versuch es erneut — viele Blockaden sind vorübergehend. Geh nur zu Ebene 2 über, wenn die Fehler anhalten. </Card> <Card title="Die meisten Videos schlagen auf diesem Host fehl" icon="globe"> Die IP der Bereitstellung ist wahrscheinlich markiert. Ergänze einen Egress-Proxy (Ebene 2) auf einer Residential-IP. </Card> <Card title="Eine bestimmte Plattform blockiert dich weiterhin" icon="key-round"> Wärme eine Browser-Session für diese Plattform vor (Ebene 3), damit der Abruf Cookies vorzeigt, die die Bot-Abfrage bestanden haben. </Card> <Card title="Vollständige Variablenreferenz" icon="settings"> Jeder `VIDEO_INGEST_*`-Regler, mit Standardwerten, steht in der [Umgebungsreferenz](/de/self-hosted/configuration/environment-reference). </Card> </CardGroup> ## Eine ehrliche Erwartung Keine dieser Ebenen kann das Einlesen gegen eine Plattform garantieren, die aktiv daran arbeitet, automatisierten Zugriff von beliebigen IPs zu blockieren. Zusammen bringen sie das Einlesen überall dort zum Erfolg, wo dein Ausgang vertrauenswürdig ist, und jede Bereitstellung hat einen unterstützten Weg zu eskalieren. Blockiert eine Plattform deinen Server hart, lässt sich das Transkript trotzdem von Hand hereinholen — füg es in ein [Wissen](/de/platform/knowledge/documents)-Dokument ein. # Observability-Konfiguration Source: https://tale.dev/docs/de/self-hosted/configuration/observability-config Tale bringt drei Observability-Nähte mit: stdout-Logs aus jedem Container, Metriken im Prometheus-Format hinter einem Bearer-Token und optionales Sentry-Error-Reporting. Die Defaults sind laut genug, um einen Crash zu sehen, und leise genug, um in das journald eines einzelnen Hosts zu passen; die Produktions-Knöpfe unten fügen die strukturierten Pfade hinzu, die dein bestehender Monitoring-Stack scrapen kann. Keine der drei schickt etwas vom Host weg, ausser du konfigurierst sie dazu. Diese Seite deckt die serverseitigen Schalter ab. Das operatorseitige Alert-Playbook lebt in [Operations](/de/self-hosted/operate/observability/operations), und das symptomorientierte Nachschlagen in [Troubleshooting](/de/self-hosted/operate/observability/troubleshooting). ## Logs Jeder Container schreibt strukturierte JSON- oder Console-Logs nach stdout, vom Default-Driver `json-file` von Docker mit einer Rotation von 10 MB pro Datei und drei Dateien aufgefangen. Das Log-Ziel ist eine Funktion davon, wie du deployest: - Einzelner Host mit journald — `journalctl -u docker` trägt alles. - Einzelner Host ohne journald — `docker compose logs -f <service>` für live tailing. - Aggregator (Loki, Vector, Fluent Bit) — richte den Docker-Logging-Driver über `daemon.json` dorthin. Tale bringt keinen Log-Shipper mit. Der Driver-Tausch ist der unterstützte Connector-Punkt. ## Metriken Der Caddy-Proxy exponiert drei Metric-Pfade, gegated von einem einzigen Bearer-Token: | Pfad | Quelle | Was drinsteckt | | -------------------- | --------------- | ----------------------------------------------------------------------------- | | `/metrics/platform` | `tale-platform` | HTTP-Latenz, Route-Counter, Node-Prozessmetriken, Antwortzeit-SLA-Ziel-Gauges | | `/metrics/convex` | `tale-convex` | 261 eingebaute Convex-Metriken, plus die RAG- und Crawl-Timings | | `/metrics/sla-rules` | `tale-platform` | Generierte Prometheus-Recording- + Alerting-Rules für die Antwortzeit-SLAs | Wissens-Arbeit (RAG-Suche, Dokument-Ingestion, Web-Crawling) läuft jetzt im Convex-Backend, also reiten ihre Timings auf der `/metrics/convex`-Reihe statt auf einem separaten Endpoint. Setze `METRICS_BEARER_TOKEN` in `.env`, um diese Endpoints zu aktivieren; lass es unset, damit sie jeder Anfrage 401 zurückgeben. Der `/metrics/sla-rules`-Pfad ist eine schreibgeschützte YAML-Rules-Datei, die du in Prometheus lädst, kein Scrape-Target — die Schwellen darin sind in [Operations](/de/self-hosted/operate/observability/operations) dokumentiert. Alles ausser den gelisteten Pfaden gibt ebenfalls 401 zurück, damit ein fehlgerouteter Scraper die internen Health-Endpoints der Plattform nicht versehentlich sieht. Eine funktionierende Prometheus-Scrape-Stanza: ```yaml scrape_configs: - job_name: tale-platform scheme: https metrics_path: /metrics/platform authorization: credentials: <METRICS_BEARER_TOKEN> static_configs: - targets: ['tale.example.com'] ``` Dupliziere die Stanza pro Pfad, oder nutze einen einzelnen Job mit `relabel_configs`, wenn du das bevorzugst. ## Error-Tracking mit Sentry Sentry ist opt-in über `SENTRY_DSN`. Selbst gehostete GlitchTip und Bugsink funktionieren auch, da sie dasselbe DSN-Format sprechen. Die Plattform- und die Convex-Container lesen beide den DSN und taggen Events mit dem Container-Namen. ```bash # .env SENTRY_DSN=https://your-key@your-sentry-host/project-id SENTRY_TRACES_SAMPLE_RATE=0.1 ``` Die Sample-Rate begrenzt Performance-Traces; lass sie unset für den Default 1.0 in Development und ziehe sie an (0.05–0.2) in Produktion. Stack-Frames werden unredigiert geschickt, also richte den DSN auf Infrastruktur, die du kontrollierst, wenn deine Error-Payloads sensibel sind. ## Was noch nicht mitkommt OpenTelemetry-Traces sind nicht in die Container eingebaut. Die Daten sind indirekt erreichbar — Convex-Action-Dauern und HTTP-Route-Timings kommen durch die Prometheus-Metriken — aber es gibt heute keinen OTLP-Exporter auf der Box. Brauchst du vollen Trace-Export, betreib einen OpenTelemetry Collector neben Tale und scrape die Prometheus-Endpoints aus ihm. ## Wo das hingehört Die drei Nähte oben sind die Kontaktpunkte mit dem Rest deines Monitoring-Stacks; die Alert-Schwellen und die Oncall-Checkliste leben in [Operations](/de/self-hosted/operate/observability/operations). Brennt etwas gerade und du brauchst den symptomorientierten Index, spring zu [Troubleshooting](/de/self-hosted/operate/observability/troubleshooting). # Die tale-CLI installieren Source: https://tale.dev/docs/de/self-hosted/install/cli-install Die `tale`-CLI ist der empfohlene Weg, Tale zu betreiben und zu bedienen. Der [Quickstart](/de/self-hosted/install/quickstart) nutzt sie bereits, um eine Instanz lokal mit `tale init` und `tale dev` aufzustellen; diese Seite ist die andere Hälfte — die CLI auf einer Workstation installieren, damit sie eine _entfernte_ Instanz fahren kann: neue Versionen deployen, Migrationen ausführen und Diagnostiken einfangen, ohne dass du dir jede `docker compose`-Invokation merken musst. Alles, was die CLI macht, lässt sich auch direkt mit `docker compose` und `ssh` machen, sodass ein Team, das schon tief in der eigenen Automatisierung steckt, bei Compose bleiben kann. Für alle anderen ist die CLI der kürzere Weg, und der Rest der self-hosted Docs setzt voraus, dass sie installiert ist. ## Bevor du beginnst Du brauchst: - Eine Workstation mit macOS, Linux oder Windows 10+. - SSH-Zugriff auf den Host, auf dem deine Tale-Instanz läuft, mit einem Operator-User, der `docker compose` ausführen kann. Der Installer lädt ein Release-Binary von GitHub. Unternehmensnetzwerke, die Raw-Content-Downloads blockieren, müssen `raw.githubusercontent.com` und `github.com` zulassen. ## Schritt 1 — install-cli.sh oder install-cli.ps1 ausführen Auf macOS oder Linux: ```bash curl -fsSL https://raw.githubusercontent.com/tale-project/tale/main/scripts/install-cli.sh | bash ``` Auf Windows PowerShell: ```powershell irm https://raw.githubusercontent.com/tale-project/tale/main/scripts/install-cli.ps1 | iex ``` Beide Installer erkennen Betriebssystem und CPU-Architektur, ziehen das passende Release-Binary aus dem neuesten GitHub-Release und legen es im `PATH` ab (`/usr/local/bin/tale` oder `%LOCALAPPDATA%\Programs\tale\tale.exe`) — ist das Installationsverzeichnis nicht beschreibbar, fragt der Installer nach `sudo`. Release-Binaries gibt es für macOS auf Apple Silicon und Intel sowie für Linux auf x86_64 und arm64; Windows-on-ARM-Maschinen führen das x64-Binary über die eingebaute Emulation aus. Auf einer Architektur ohne Release-Binary bricht der Installer mit einer klaren Meldung ab und verweist auf den Build aus dem Quellcode. Um eine Version festzuhalten, setze die Environment-Variable `VERSION`, bevor du in den Installer pipest; das Installationsverzeichnis wählst du mit `INSTALL_DIR` selbst. | OS | Installer-Skript | | ------- | ------------------------- | | macOS | `scripts/install-cli.sh` | | Linux | `scripts/install-cli.sh` | | Windows | `scripts/install-cli.ps1` | ## Schritt 2 — Verifizieren ```bash tale --version ``` Die CLI gibt ihre Version aus. Wird der Befehl nicht gefunden, hat der Installer das Binary ausserhalb des `PATH` abgelegt — die Installer-Ausgabe benennt das Zielverzeichnis. ## Schritt 3 — Konfiguration prüfen Es gibt kein `tale config set` — alles, was die CLI braucht, liegt im Projekt, das `tale init` angelegt hat. Führ jeden `tale`-Befehl aus diesem Verzeichnis heraus aus (die CLI läuft den Baum hoch, um `tale.json` zu finden), und prüf, dass es aufgelöst wird: ```bash tale config show ``` Der Host, auf dem der Proxy antwortet, die TLS-Einstellungen und alle Secrets liegen im `.env` des Projekts. Um den Host zu ändern, bearbeite dort `HOST` oder übergib `--host` an `tale dev` / `tale deploy`. Um einen entfernten Host zu betreiben, richte den Docker-Kontext deiner Shell (oder `DOCKER_HOST`) darauf aus — die CLI spricht denselben Docker-Endpunkt an wie jeder `docker`-Befehl. Der Admin-Key fürs Convex-Dashboard ist von der CLI-Konfiguration getrennt — er hat mit der Anmeldung nichts zu tun und ist deterministisch (abgeleitet aus `INSTANCE_NAME` und `INSTANCE_SECRET`, bleibt also über Neustarts hinweg gleich). Erzeug ihn mit `tale convex admin`, wenn du das Backend inspizieren willst (siehe [Erster Admin](/de/self-hosted/install/first-admin)). ## Schritt 4 — tale deploy ausführen ```bash tale deploy ``` `tale deploy` liefert immer die Version der CLI selbst aus: Es zieht die Images dieser Version, restartet die betroffenen Container in der richtigen Reihenfolge und führt Schema-Migrationen aus — auf eine andere Version wechselst du vorher mit `tale update`. Es ist der unterstützte Ersatz für das längere `docker compose pull && docker compose up -d`-Tänzchen. Bevorzugst du Compose direkt, lebt derselbe Effekt in [Upgrades](/de/self-hosted/operate/upgrades). ## Befehlsreferenz Die CLI gruppiert ihre Befehle danach, was du gerade tust — genau wie `tale --help`. Jeder Befehl und seine Argumente sind unten aufgeführt. So liest du die Notation: - Ein positionales Argument in `[eckigen Klammern]` ist **optional**, eines in `<spitzen Klammern>` ist **erforderlich**. - Jedes Flag ist **optional** — weglassen ergibt das Standardverhalten. - Ein Flag der Form `--flag <wert>` **erfordert einen Wert**, wenn du es nutzt (z. B. `--port 8443`); ein blosses Flag wie `--detach` ist ein boolescher Schalter. - **Standardwerte** stehen in Klammern hinter der Beschreibung. Kein Standard bedeutet, das Flag ist aus oder der Wert wird aus `.env` / Kontext aufgelöst. Führe `tale <befehl> --help` für die massgebliche Liste deiner installierten Version aus. **Globale Flags** funktionieren bei jedem Befehl: - `--verbose` — ausführliche Ausgabe: Debug-Logs und der rohe Subprozess-Stream (nur die Langform; ein `-v` gibt es nicht). - `-q, --quiet` — nur Warnungen und Fehler. - `-y, --yes` — bei allen Rückfragen «ja» annehmen (nicht-interaktiv). - `--no-color` — ANSI-Farben deaktivieren (berücksichtigt auch `NO_COLOR` / `FORCE_COLOR`). - `--json` — maschinenlesbares JSON auf stdout, menschliche Meldungen auf stderr; unterstützt von `status`, `config show` und `migrate status`. - `--ci` — erzwingt nicht-interaktive, rein anhängende Ausgabe (keine Cursor-Steuerung). Befehle beenden mit `0` bei Erfolg, `2` bei einem Nutzungsfehler, `3` bei einer nicht erfüllten Voraussetzung (kein Projekt, Docker läuft nicht, Port belegt), `4` bei einem Abbruch durch dich (Ctrl-C oder eine erforderliche Rückfrage ohne Terminal) und `5` beim Fehler einer externen Abhängigkeit — so können Skripte anhand der Ursache verzweigen. ### Einrichtung `tale init [directory]` — ein Projekt anlegen: erzeugt die Beispiel-Configs, `AGENTS.md` + einen `CLAUDE.md`-Verweis sowie eine lokale Standard-`.env` (localhost, selbstsigniertes Zertifikat, generierte Secrets). Docker braucht es nicht; Produktiv-Domain und TLS werden später bei `tale deploy` gewählt. Im Terminal fragt es nach einem Projektnamen, wenn `directory` fehlt, bestätigt vor dem Überschreiben eines bestehenden Projekts und fragt einmal, ob Agents in Sandboxes `docker` ausführen dürfen (Standard: nein — die Freigabe startet einen privilegierten inneren Docker); nicht-interaktive Läufe überspringen alle Rückfragen. `directory` ist optional (Standard: das aktuelle Verzeichnis). - `-f, --force` — eine vorhandene `tale.json` überschreiben statt abzubrechen. - `--no-env` — das Projekt anlegen, aber die `.env`-Generierung überspringen. `tale dev` — alle Dienste lokal mit selbstsigniertem Zertifikat starten. - `-d, --detach` — im Hintergrund laufen statt Logs zu streamen. - `-p, --port <port>` — auszugebender HTTPS-Port (Standard `443`). - `--host <hostname>` — Host-Alias für den Proxy (Standard `localhost`). - `-y, --yes` — nicht-interaktiv: Abfragen automatisch akzeptieren (z. B. Docker installieren oder starten). `tale deploy` — Blue-Green-Deployment ohne Ausfallzeit der aktuellen CLI-Version. Beim ersten Deploy fragt es nach deiner Produktiv-Domain und der Let's-Encrypt-E-Mail (oder übergib `--host`). - `--stop` — auch die stop-gebundene Schicht (`db`, `proxy`) aktualisieren — sie wird neu erstellt, also nimm eine kurze Ausfallzeit in Kauf; ohne das Flag bleiben laufende `db`/`proxy` unangetastet. - `-s, --services <list>` — nur diese kommagetrennten Dienste aktualisieren (Standard: alle rotierbaren Dienste). - `--host <hostname>` — Host-Alias für den Proxy (Standard: der `HOST`-Wert aus `.env`). - `--override` — Container-Config aus dem Host-Workspace überschreiben (verschlüsselte `*.secrets.json` und `.history/` bleiben stets erhalten). - `--override-all` — den Builtin-Katalog serverseitig in jede Organisation zurücksetzen; impliziert `--stop`. - `-q, --quiet` — Container-Logs während des Deployments unterdrücken. - `-y, --yes` — destruktive Bestätigungsabfragen automatisch akzeptieren (z. B. `--override-all`). - `--skip-backup` — den automatischen Pre-Deploy-Snapshot überspringen. - `--dry-run` — Vorschau ohne Änderungen. ### Betrieb `tale status` — den aktuellen Deployment-Status anzeigen. Keine Argumente. `tale logs <service>` — Logs eines Dienstes streamen (`service` ist einer der laufenden Dienste; auf einem reinen Dev-Stack ohne Deployment fällt der Befehl auf den Dev-Container zurück). - `-f, --follow` — der Log-Ausgabe folgen, während sie geschrieben wird. - `-n, --tail <lines>` — nur die letzten N Zeilen anzeigen. - `--since <duration>` — Logs seit einer relativen Zeit anzeigen (z. B. `1h`, `30m`). - `-c, --color <color>` — eine bestimmte Deployment-Farbe ansprechen (`blue` oder `green`). - `--raw` — die rohe, ungefilterte Log-Ausgabe streamen (keine Klassifizierung). `tale backup` — Snapshot aller Daten-Volumes in das Projekt-Backups-Volume. Keine Argumente. `tale restore [snapshot-id]` — einen Snapshot wiederherstellen; ohne ID werden die verfügbaren Snapshots aufgelistet. - `--stop` — laufende Projekt-Container vor dem Wiederherstellen stoppen. - `-y, --yes` — die Bestätigungsabfrage überspringen. `tale rollback` — auf die vorherige Patch-Version zurückrollen (nur Patch-Ebene). Fragt vorher nach Bestätigung. - `-y, --yes` — die Bestätigungsabfrage überspringen (im nicht-interaktiven Betrieb erforderlich). ### Wartung `tale update` — diese Tale-Instanz auf eine neue Version bewegen: zuerst das CLI-Binary aktualisieren, dann die Projektdateien synchronisieren; danach `tale deploy` ausführen, um die Container zu rollen. Die CLI gleicht sich bei jedem Befehl ohnehin an die Instanz-Version an, also brauchst du das nur, um die Version bewusst zu wechseln. - `-v, --version <version>` — auf genau diese Version aktualisieren (z. B. `0.9.0`) statt der neuesten; erlaubt Downgrades. - `-f, --force` — Re-Sync erzwingen und lokal geänderte Projektdateien überschreiben. - `--dry-run` — anzeigen, was sich ändern würde, ohne etwas zu ändern. `tale migrate` — die mitgelieferten Defaults neu provisionieren und die sicheren, ausstehenden Daten-Migrationen auf das laufende Deployment anwenden — dieselben idempotenten Schritte, die jeder Deploy ausführt, nur auf Zuruf. Die Subcommands geben dir gezielte, umkehrbare Kontrolle: `migrate status` zeigt angewendete und ausstehende Migrationen, `migrate up [--to <version>]` wendet ausstehende an (destruktive Schritte brauchen `-y, --yes` oder `--step`), `migrate down --to <version>` rollt zurück. `tale cleanup` — inaktive (nicht-aktuelle) Container entfernen. Keine Argumente. `tale reset` — alle Blue-Green-Container entfernen. - `-f, --force` — die Bestätigungsabfrage überspringen. - `-a, --all` — auch die zustandsbehafteten Infrastruktur-Container entfernen. - `--dry-run` — den Reset vorab anzeigen, ohne Änderungen. `tale uninstall` — das `tale`-CLI-Binary von diesem System entfernen. Fragt nach, bevor etwas gelöscht wird, und _bietet an_, zusätzlich die benutzereigene Konfiguration (`~/.tale-daemon`) zu entfernen und die Docker-Ressourcen und Dateien eines Projekts abzubauen. Ohne `--purge` bleiben ein Projekt und seine Container unangetastet — führ darin `tale reset --all` aus, um sie zu entfernen. - `-f, --force` — die Bestätigungsabfrage überspringen (entfernt nur das Binary; die optionalen Aufräumschritte brauchen weiterhin `--purge`). - `--purge` — zusätzlich `~/.tale-daemon` entfernen und, für ein vom aktuellen Verzeichnis aus gefundenes Projekt, dessen Docker-Ressourcen abbauen und seine Dateien löschen. Nicht umkehrbar. - `--dry-run` — anzeigen, was entfernt würde, ohne etwas zu entfernen. `tale config` — CLI-Konfiguration verwalten. Mit dem Unterbefehl `show` die aufgelöste Konfiguration ausgeben. ### Erweitert `tale auth reset-owner` — die Zugangsdaten des Owner-Kontos zurücksetzen. - `-e, --email <email>` — eine neue Owner-E-Mail-Adresse setzen. - `-p, --password <password>` — ein neues Owner-Passwort setzen. `tale convex admin` — einen Admin-Key für das Convex-Dashboard erzeugen. Keine Argumente. ## Fehlersuche - **`tale deploy` trifft die falsche Maschine.** Die CLI nutzt den Docker-Kontext / `DOCKER_HOST` deiner Shell. Wechsle mit `docker context use …` (oder setz `DOCKER_HOST`), sodass er auf den gewünschten Host zeigt, und lauf erneut. - **`tale deploy` nutzt den falschen Host-Alias.** Der Host, auf dem der Proxy antwortet, kommt aus `HOST` im `.env` des Projekts, nicht aus einem separaten CLI-Speicher. Bearbeite `.env` oder übergib `--host`, um ihn für einen Lauf zu überschreiben. - **Das Convex-Dashboard weist den Admin-Key ab.** Die Anmeldung fragt nie nach dem Key — nur das Dashboard. Der Key ist deterministisch (abgeleitet aus `INSTANCE_NAME` und `INSTANCE_SECRET`); eine Ablehnung heißt also meist, dass sich diese Werte zwischen Platform- und Convex-Service unterscheiden, oder die Deployment-URL falsch ist — nimm `SITE_URL`. Generier mit `tale convex admin` neu, um sicherzugehen, dass du den aktuellen Wert kopiert hast. - **Installer scheitert auf macOS, weil das Binary nicht ausführbar ist.** Verweigert das frisch installierte Binary den Start (z. B. weil Gatekeeper es beendet), bricht der Installer mit Hinweisen zur Behebung ab, statt Erfolg zu melden — folg ihnen und lauf den Installer erneut. - **`tale` nach der Installation auf Linux nicht gefunden.** Der Installer legt das Binary in `/usr/local/bin` ab; verifizier, dass das Verzeichnis im `PATH` des Users ist (`echo $PATH`). ## Wo das eingesetzt wird Sobald die CLI verdrahtet ist, schrumpft die tägliche Oberfläche des Betreibers auf eine Handvoll Subbefehle. Welche Seiten du als Nächstes liest, hängt davon ab, wozu du gekommen bist — [Upgrades](/de/self-hosted/operate/upgrades) für Versionsbumps, [Backups und Restore](/de/self-hosted/operate/backups-and-restore) für Snapshot-Übungen, [Container-Architektur](/de/self-hosted/operate/container-architecture) dafür, was die CLI beim Deploy restartet. # Selbst gehosteter Quickstart Source: https://tale.dev/docs/de/self-hosted/install/quickstart Das ist der schnellste Weg zu einem laufenden Tale: installiere die `tale`-CLI, dann zwei Befehle. Das Ergebnis ist deine eigene Org auf deiner eigenen Maschine, erreichbar im Browser. Gedacht ist das für einen Laptop oder einen einzelnen Host, auf dem du Tale ausprobieren willst; sobald du es ernsthaft betreiben willst, deckt die [Linux-Server-Strecke](/de/self-hosted/install/linux-server) eine gehärtete Produktions-Installation ab. ## Bevor du beginnst Du brauchst nichts zum Starten und eine Sache, bevor ein Agent antworten kann: - **Docker** — aber die CLI stellt es für dich bereit: Fehlt Docker, bietet `tale dev` an, es zu installieren oder zu starten, bevor irgendetwas anderes passiert. Läuft bei dir bereits [Docker Desktop](https://www.docker.com/products/docker-desktop) (v24+) oder Docker Engine plus Compose-Plugin unter Linux, nutzt die CLI das. - Einen **[OpenRouter-API-Schlüssel](https://openrouter.ai)** (oder einen beliebigen OpenAI-kompatiblen Anbieter), damit Agents ein Modell zum Reden haben. Für `tale init` brauchst du ihn nicht — du fügst ihn nach der Registrierung in der App hinzu, im Setup-Assistenten oder unter **Einstellungen > KI-Anbieter**, und du kannst später jeden Anbieter einwechseln. ## Von null bis angemeldet <Steps> <Step title="Installiere die CLI"> Der Installer erkennt dein OS, legt das `tale`-Binary auf deinen `PATH` und ist der einzige Schritt, der dein System anfasst — er fragt nach `sudo`, wenn das Installationsverzeichnis (Standard `/usr/local/bin`) nicht beschreibbar ist. <Tabs> <Tab title="macOS / Linux"> ```bash curl -fsSL https://raw.githubusercontent.com/tale-project/tale/main/scripts/install-cli.sh | bash ``` </Tab> <Tab title="Windows (PowerShell)"> ```powershell irm https://raw.githubusercontent.com/tale-project/tale/main/scripts/install-cli.ps1 | iex ``` </Tab> </Tabs> <Check> Gibt `tale --version` eine Versionsnummer aus, ist das Binary auf deinem `PATH` gelandet. </Check> </Step> <Step title="Erstelle ein Projekt"> ```bash tale init my-project cd my-project ``` `tale init` legt ein Projektverzeichnis an, generiert jedes Security-Secret und schreibt die `.env`, sodass es nichts von Hand zu editieren gibt. Die Defaults sind localhost und ein selbstsigniertes Zertifikat; die Produktions-Domäne wählst du später, bei `tale deploy`. Die eine Frage, die es stellt, ist, ob Agents in ihren Sandboxes `docker` / `docker compose` ausführen dürfen — der Default ist Nein, denn die Freigabe startet einen privilegierten inneren Docker; auf einer Einzelnutzer-Maschine kannst du zustimmen, als Multi-Tenant-Betreiber installierst du stattdessen Sysbox. Nach einem API-Schlüssel fragt es nicht; den sammelt die App ein, sobald du dich anmeldest. Es legt außerdem Beispiel-Agents, -Workflows, -Connectors, -Provider, -Skills und -Branding unter `default/` ab und schreibt `AGENTS.md` (plus einen `CLAUDE.md`-Verweis), damit ein KI-Editor Konfigurationen mit voller Schema-Kenntnis bauen kann. Das meiste davon ist ein Katalog, keine aktive Konfiguration: Auf einer neuen Organisation sind nur Einträge mit `autoInstall` aktiv — den Unterschied erklärt die generierte `default/README.md`. </Step> <Step title="Starte Tale"> ```bash tale dev ``` Fehlt Docker, bietet `tale dev` zuerst an, es zu installieren oder zu starten. Der erste Lauf zieht dann mehrere Gigabyte an Images und baut den Container-Graph — die CLI zeigt den Pull-Fortschritt pro Image an und wartet weiter; in einem langsamen Netz kann das Dutzende Minuten dauern. Sobald der Stack bereit meldet (`Tale is running — open https://localhost`), öffnet `tale dev` automatisch deinen Browser. Kann es das nicht, gibt es die URL zum Besuchen aus. <Note> Dein Browser zeigt eine Zertifikatswarnung für das lokale selbstsignierte Zertifikat. Das ist erwartet — akzeptier sie, um fortzufahren. </Note> Deine Konfiguration unter `default/` wird in die laufende Instanz gemountet, sodass Änderungen an Agents, Workflows und Connectors live nachladen. Stopp den Stack mit `Ctrl-C` (oder `tale dev --detach`, um ihn im Hintergrund laufen zu lassen). </Step> <Step title="Erstelle dein Konto"> Auf einer leeren Instanz gibt es keine Sign-up-Seite zu suchen: Der erste Besuch landet im einmaligen Setup-Wizard, der dein Konto anlegt, dich anmeldet, dich zum **Inhaber** macht und deine **Organisation** benennt. Du landest im Dashboard — ohne Admin-Key, und danach gibt es nichts abzuriegeln, denn alle nach dir kommen per Einladung dazu. <Note> [Erster Admin](/de/self-hosted/install/first-admin) behandelt den Wizard im Detail, wie Teammitglieder dazukommen und den Convex-Dashboard-Admin-Key — ein Backend-Inspektionswerkzeug, das mit der Anmeldung nichts zu tun hat. </Note> </Step> <Step title="Verbinde ein Modell und veröffentliche einen Agent"> Du hast jetzt eine leere Org. Zwei Handgriffe bringen dich zu etwas Nützlichem: Füg deinen OpenRouter-Schlüssel hinzu — der Setup-Assistent fragt direkt nach der Erstellung des Inhaber-Kontos danach, und **Einstellungen > KI-Anbieter** nimmt ihn jederzeit später an — und veröffentliche dann deinen ersten Agent mit [Einen Agent erstellen](/de/platform/agents/create). Eine Bestätigung auf der Anbieterzeile heißt, dass der Schlüssel funktioniert. <Check> Ein neuer Chat, der eine Nachricht beantwortet, ist der Beweis von Anfang bis Ende: Anbieter, Modell und Agent funktionieren. Von hier aus sind die [Plattform](/de/platform)-Docs die kanonische Referenz für jedes Feature, identisch zu Cloud. </Check> </Step> </Steps> ## Lieber pures Docker Compose? Die CLI umhüllt `docker compose`, damit du das nicht musst. Willst du den Stack lieber aus einem Klon des Repositorys fahren und Compose selbst verwalten — für Transparenz, Air-gapped-Builds oder deine eigene Automation — klon das Repo, kopier `.env.example` nach `.env`, setz `HOST` und `SITE_URL`, generier die Secrets und starte `docker compose up -d`. Die [Linux-Server-Strecke](/de/self-hosted/install/linux-server) und die [Docker-Compose-Referenz](/de/self-hosted/install/docker-compose-reference) decken diesen Weg von Anfang bis Ende ab. ## Fehlersuche - **`tale` nach der Installation nicht gefunden.** Der Installer benennt das Zielverzeichnis in seiner Ausgabe; stell sicher, dass dieses Verzeichnis auf deinem `PATH` liegt (unter Linux ist es meist `/usr/local/bin`). - **`tale dev` beendet mit einem Port-Konflikt.** Lies aus dem Compose-Fehler ab, welcher Port belegt ist. Ist es 443, bindet ein anderer Dienst HTTPS auf dem Host — gib ihn frei oder leg Tale mit `tale dev --port 8443` auf einen anderen Port (das Flag betrifft nur den HTTPS-Port). Der Sandbox-Spawner bindet immer `127.0.0.1:8003` und lässt sich nicht verlegen; deshalb können zwei Tale-Dev-Projekte nicht gleichzeitig auf einer Maschine laufen. - **Docker läuft nicht.** `tale dev` bietet an, es zu starten (oder zu installieren) — nimm die Rückfrage an, oder starte Docker Desktop selbst (`sudo systemctl start docker` unter Linux) und versuch es erneut. - **Ein Container crash-loopt beim ersten Boot.** Fast immer ein fehlendes Secret — lauf `tale dev` erneut, was das Environment-Setup erneut ausführt, oder inspizier die Logs mit `tale logs platform`. ## Wo das eingesetzt wird Du hast jetzt eine funktionierende Tale-Instanz auf deiner Maschine. Um sie ernsthaft zu betreiben, deckt die [Linux-Server-Strecke](/de/self-hosted/install/linux-server) TLS, Firewall, einen Non-root-Benutzer und die operativen Haken ab, die du vor echtem Traffic willst; [Die tale-CLI installieren](/de/self-hosted/install/cli-install) richtet die CLI so ein, dass du eine entfernte Instanz von deiner Workstation aus deployst und aktualisierst. # Installation Source: https://tale.dev/docs/de/self-hosted/install Tale zu installieren hat drei Formen, und die richtige hängt davon ab, was du mit dem Ergebnis vorhast. Diese Seite leitet dich zum passenden Weg — ein schneller lokaler Trial, eine Produktions-Installation hinter TLS oder die rohe Compose-Referenz, wenn du jeden Knopf besitzen willst — damit du keinen Härtungs-Spaziergang beginnst, wenn du nur herumklicken wolltest. Alle drei Wege landen auf demselben Produkt; der Unterschied ist, wie viel vom Stack du betreibst und wie haltbar das Ergebnis sein muss. Die CLI umhüllt Docker Compose für die ersten beiden, sodass es nichts von Hand zu editieren gibt, während der Referenz-Weg für Teams ist, die Compose selbst fahren. ## Tale auf einem Laptop ausprobieren Willst du eine laufende Instanz zum Durchklicken — auf deiner eigenen Maschine, ohne Domäne und ohne Härtung — ist der [Quickstart](/de/self-hosted/install/quickstart) der Weg. Installier die CLI, lauf `tale init` und dann `tale dev`, und du bist in Minuten in deiner eigenen Org angemeldet. Die CLI stellt Docker bereit, falls es fehlt, generiert jedes Secret und mountet deine Konfiguration, sodass Edits live nachladen. Das ist der richtige Weg für eine Evaluierung, eine Demo oder lokale Entwicklung gegen einen echten Stack. Wenn du dem Laptop entwächst und dasselbe Projekt auf einem echten Host willst, trägt das Trial-Projekt sich mit — `tale deploy` bringt es auf eine Domäne, ohne neu zu initialisieren. ## Tale in Produktion betreiben Wenn echter Verkehr auf der Instanz landet, ist der [Linux-Server](/de/self-hosted/install/linux-server)-Spaziergang der Weg. Er deckt TLS, eine Firewall, einen Non-root-User, den Reverse-Proxy und die operativen Haken ab, die du willst, bevor du eine Domäne darauf richtest. Die CLI macht weiterhin die Schwerarbeit — `tale deploy` fährt einen Blue-Green-Rollout ohne Ausfallzeit mit Health-Checks und Rollback — aber dieser Spaziergang fügt das Host-Level-Setup hinzu, das ein Trial überspringt. Nach dem ersten Deploy erklärt [Erster Admin](/de/self-hosted/install/first-admin) den einmaligen Setup-Wizard, der das erste Konto zum **Owner** macht — alle danach kommen per Einladung dazu, es gibt also keine offene Anmeldung zu schließen — und [CLI installieren](/de/self-hosted/install/cli-install) richtet die CLI auf einer Workstation ein, um eine entfernte Instanz zu deployen und zu upgraden. ## Die Compose-Schicht besitzen Willst du den Stack lieber aus einem Klon des Repositories fahren und Compose selbst verwalten — für Transparenz, Air-gapped-Builds oder deine eigene Automation — ist die [Docker-Compose-Referenz](/de/self-hosted/install/docker-compose-reference) der Weg. Sie dokumentiert die Basisdatei und die Overlays, die die CLI im Hintergrund generiert, sodass du sie von Hand reproduzieren oder erweitern kannst. Das ist die meiste Kontrolle und die meiste Arbeit; die meisten Teams sind mit den CLI-Wegen oben besser bedient. Dieser Weg paart sich mit dem [Linux-Server](/de/self-hosted/install/linux-server)-Spaziergang für die Host-Level-Teile (TLS, Firewall, User), die Compose allein nicht abdeckt. ## Wo das hingehört Die drei Installationswege tauschen Komfort gegen Kontrolle: der [Quickstart](/de/self-hosted/install/quickstart) ist der schnellste Weg zu einer laufenden Instanz, der [Linux-Server](/de/self-hosted/install/linux-server)-Spaziergang härtet sie für echten Verkehr, und die [Docker-Compose-Referenz](/de/self-hosted/install/docker-compose-reference) reicht dir jeden Knopf, wenn die Defaults der CLI nicht genügen. Wähl nach Haltbarkeit: ein Trial, den du wegwirfst, will den Quickstart; eine Instanz, von der dein Team abhängt, will den Produktions-Spaziergang. Einmal installiert, sind die [Konfigurations](/de/self-hosted/configuration/environment-reference)-Seiten die Quelle der Wahrheit für jede Umgebungsvariable und Provider-Datei, und der [Betreiben](/de/self-hosted/operate/container-architecture)-Abschnitt deckt Upgrades, Backups und Observability für den laufenden Stack ab. # Den ersten Admin erstellen Source: https://tale.dev/docs/de/self-hosted/install/first-admin Eine brandneue Tale-Instanz hat noch keine User. Die erste Person, die sie öffnet, durchläuft einen einmaligen Setup-Wizard, der ihr Konto anlegt, sie anmeldet, sie zum **Owner** macht und die erste Organisation benennt — kein Bootstrap-Key, keine manuelle Beförderung. Dieser Spaziergang deckt diesen ersten Lauf ab, wie Teammitglieder danach dazukommen und wo du den Convex-Dashboard-Admin-Key bekommst, falls du das Backend mal direkt inspizieren musst. Das Eine, was du aus älteren Anleitungen verlernen musst: Die erste Anmeldung fragt nicht mehr nach einem Admin-Key. Tale ist nach dem ersten Konto nur per Einladung zugänglich, also gibt es auch keine offene Sign-up-Seite, die du abriegeln müsstest. ## Bevor du beginnst Hab die Instanz laufen und unter `SITE_URL` erreichbar. Verifizier mit: ```bash docker compose ps ``` Jeder Service sollte `running` oder `healthy` zeigen. Ist einer ungesund, benennt die [Fehlersuche](/de/self-hosted/operate/observability/troubleshooting) die vier häufigen Ursachen. ## Den Setup-Wizard durchlaufen Öffne `SITE_URL`. Da es noch keine User gibt, schickt Tale dich direkt in den Setup-Wizard — es gibt keine separate Sign-up-Seite zu suchen, denn der Login-Bildschirm leitet eine leere Instanz automatisch ins Setup um. Der Wizard legt dein Konto an und meldet dich mitten im Flow an, dann benennt er deine erste Organisation. Der Provider-Schritt ist optional: Überspring ihn und füg einen Key später unter **Einstellungen > KI-Anbieter** hinzu, oder verbinde OpenRouter jetzt, um sofort zu chatten. Hol dir einen Key auf [openrouter.ai/keys](https://openrouter.ai/keys). Der Abschluss-Schritt setzt dich ins Dashboard. ## Bestätigen, dass du der Owner bist Das erste Konto auf einer frischen Instanz ist automatisch der **Owner** — kein Key zum Einfügen, kein Beförderungsschritt. Bestätig unter **Einstellungen > Personen**, dass deine Zeile das Owner-Badge trägt. ## Wie neue Leute dazukommen Es gibt kein Self-Service-Signup. Sobald ein Owner existiert, leitet `SITE_URL/sign-up` Besucher auf den Login-Bildschirm um, sodass niemand sich selbst ein Konto anlegen kann. Füg Teammitglieder per Einladung unter **Einstellungen > Personen** hinzu; jede Einladung trägt die Rolle, mit der das neue Mitglied startet. Das vollständige Rollenmodell steht in [Mitglieder und Rollen](/de/platform/admin/members-and-roles). ## Den Convex-Dashboard-Admin-Key holen Der Admin-Key spielt in den obigen Schritten keine Rolle — er schaltet nur das **Convex-Dashboard** frei, die Low-Level-Ansicht der Backend-Datenbank. Der Key ist deterministisch: Er wird aus `INSTANCE_SECRET` abgeleitet, bleibt also über Neustarts hinweg gleich und rotiert nicht. Hol ihn so, wie es zu deiner Installation passt: - Mit der CLI: `tale convex admin` findet den Platform-Container und gibt den Key aus. `tale dev` gibt ihn ebenfalls aus, sobald die Services gesund sind. - Aus einem Git-Klon: `./scripts/get-admin-key.sh` aus dem Repo-Root. Öffne `SITE_URL/convex-dashboard`, gib `SITE_URL` als Deployment-URL ein und füg den Key ein, wenn du danach gefragt wirst. ## Fehlersuche - **Der Wizard erschien nicht — du landest auf dem Login-Bildschirm.** Es gibt bereits User auf dieser Instanz; der Wizard läuft nur auf einer wirklich leeren. Melde dich stattdessen an, oder lass dich von einem bestehenden Owner unter **Einstellungen > Personen** einladen. - **Ein Service ist ungesund.** Der Platform-Container ist nicht vollständig oben. `docker compose ps` sagt, welcher Service scheitert; `docker compose logs platform` zeigt warum. - **Das Dashboard lehnt den Admin-Key ab.** Der Key ist deterministisch aus `INSTANCE_SECRET`, eine Ablehnung heisst also meist, dass sich `INSTANCE_NAME` und `INSTANCE_SECRET` zwischen Platform- und Convex-Service unterscheiden, oder die Deployment-URL falsch ist — nimm `SITE_URL`. Generier mit `tale convex admin` neu, um sicherzugehen, dass du den aktuellen Wert kopiert hast. ## Wo das eingesetzt wird Du hast jetzt einen Owner und eine Org und weisst, dass der Admin-Key ein Backend-Inspektionswerkzeug ist, kein Teil der Anmeldung. Der erste Lauf ist absichtlich keylos: Öffne die URL, der Wizard macht dich zum Owner, und alle anderen kommen per Einladung dazu. Die nächsten Schritte für den Kalender sind, den Rest der Admins einzuladen (unter **Einstellungen > Personen**), einen Modell-Provider hinzuzufügen und den ersten Agent zu veröffentlichen — der [Cloud-Onboarding](/de/cloud/onboarding)-Spaziergang ist von hier an identisch, ausser der URL. # Produktions-Linux-Server-Installation Source: https://tale.dev/docs/de/self-hosted/install/linux-server Dieser Spaziergang nimmt die [Quickstart](/de/self-hosted/install/quickstart)-Form und härtet sie für Produktionsverkehr. Das Ergebnis ist ein einzelner Linux-Host, der Tale hinter echtem TLS betreibt, mit einer Firewall, einem Non-root-Operator-User und den operativen Defaults, die das Team treffen sollte, bevor es User auf die URL zeigt. Der Spaziergang zielt auf ein aktuelles Ubuntu LTS oder Debian; Befehle übersetzen eins-zu-eins auf RHEL-Familie-Distros mit `dnf` statt `apt`. Spring keinen Schritt — die Reihenfolge zählt, und jeder Schritt setzt voraus, dass der vorherige sauber gelandet ist. ## Bevor du beginnst Du brauchst: - Eine VM oder einen Bare-Metal-Host mit mindestens 8 GB RAM, 4 vCPU und 100 GB Disk. Der Speicher wächst mit Anhängen und Wissen. - Einen DNS-A-Eintrag, der auf die öffentliche IP des Hosts zeigt. Ohne DNS kann Let's Encrypt kein Zertifikat ausstellen. - Ports 80, 443 aus dem öffentlichen Internet erreichbar für die TLS-Ausstellung; SSH auf welchem Port auch immer deine Operator-Policy sagt. - Sudo auf dem Host. ## Schritt 1 — Die Box provisionieren Aktualisiere und installier die Grundlagen: ```bash sudo apt update && sudo apt upgrade -y sudo apt install -y curl git ufw ``` Erstell einen Non-root-Operator-User namens `tale`: ```bash sudo adduser tale sudo usermod -aG sudo,docker tale ``` Wechsle zu diesem User (`sudo su - tale`) für den Rest des Spaziergangs. Tale als root zu betreiben holt einen höheren Wirkungsradius für keinen Nutzen; der Rest der Schritte setzt den `tale`-User voraus. ## Schritt 2 — Docker installieren ```bash curl -fsSL https://get.docker.com | sudo sh sudo systemctl enable --now docker ``` Verifizier mit `docker run hello-world`. Kann der User Docker nicht ohne sudo laufen lassen, melde dich ab und wieder an, um die `docker`-Gruppen-Mitgliedschaft zu übernehmen. ## Schritt 3 — Firewall und Reverse-Pfad konfigurieren Erlaub nur, was Tale braucht: ```bash sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow OpenSSH sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable ``` Stellst du Tale einen bestehenden Reverse-Proxy auf demselben Host vor (selten bei einer Single-Host-Installation), setze `TLS_MODE=external` in `.env` und passe die Firewall entsprechend an. Der Caddy-Container innerhalb von Tale terminiert TLS standardmässig. ## Schritt 4 — Tale ziehen ```bash git clone https://github.com/tale-project/tale.git cd tale cp .env.example .env ``` Setze `HOST`, `SITE_URL` und generier die vier Secrets wie im [Quickstart](/de/self-hosted/install/quickstart). Der Produktions-Diff gegenüber dem Quickstart lebt in Schritt 5 (TLS) und den operativen Haken am Ende dieses Spaziergangs. ## Schritt 5 — TLS via Let's Encrypt Öffne `.env` und setze: | Variable | Wert | | ----------- | ------------------------------ | | `TLS_MODE` | `letsencrypt` | | `TLS_EMAIL` | Ein Ops-Postfach, das du liest | Caddy stellt das Zertifikat aus und erneuert es automatisch über den DNS-Eintrag aus den Voraussetzungen. Der erste Boot wartet auf das Zertifikat; rechne mit einer Verzögerung von einer Minute beim ersten `docker compose up -d`, während die ACME-Challenge läuft. ## Schritt 6 — Erster Boot ```bash docker compose up -d docker compose ps ``` Jeder Service sollte `running` oder `healthy` zeigen. Folg dem **Schritt 4 — Den ersten Admin erstellen** aus dem [Quickstart](/de/self-hosted/install/quickstart), um im Dashboard zu landen. Öffne `SITE_URL` über `https://` — der Browser sollte nicht vor dem Zertifikat warnen. ## Schritt 7 — Operative Haken Bevor du User auf die URL zeigst, machen dir drei Haken später das Leben leichter: - **Backups.** Richt dein bestehendes Snapshot-Tooling auf `db-data` und das Object-Store-Volume — siehe [Backups und Restore](/de/self-hosted/operate/backups-and-restore). - **Logs.** Tale loggt auf stdout. Hat der Host journald, trägt `journalctl -u docker` alles; sonst pipe zu deinem Aggregator. - **Metriken.** Setze `METRICS_BEARER_TOKEN` in `.env` und scrap `/metrics` aus deinem Prometheus — siehe [Observability-Konfiguration](/de/self-hosted/configuration/observability-config). ## Port-Tabelle | Port | Richtung | Zweck | Erforderlich | | ---- | -------- | ---------------------------------------- | ----------------- | | 22 | inbound | SSH | ja, eingeschränkt | | 80 | inbound | HTTP, genutzt für ACME und 301 auf HTTPS | ja | | 443 | inbound | HTTPS, primärer Verkehr | ja | | 53 | outbound | DNS | ja | | 443 | outbound | Modell-Provider, Image-Pulls | ja | ## Fehlersuche - **Let's-Encrypt-Ausstellung scheitert.** DNS muss auf die öffentliche IP dieses Hosts aus dem öffentlichen Internet auflösen, und Port 80 muss aus dem öffentlichen Internet erreichbar sein. Lauf `curl -I http://$HOST` von einer anderen Maschine; trifft es die Caddy-Challenge, läuft der Pfad. - **Container können Modell-Provider nicht erreichen.** Die ausgehende Firewall des Hosts blockt vielleicht; verifizier mit `docker compose exec platform curl -I https://api.openai.com`. - **TLS-Zertifikat-Erneuerungen scheitern später.** Caddy erneuert 30 Tage vor Ablauf; Fehler zeigen sich in `docker compose logs proxy`. Die zwei häufigen Ursachen sind eine abgelaufene `TLS_EMAIL`-Mailbox und eine DNS-Änderung, die den Eintrag gebrochen hat. ## Wo das eingesetzt wird Du hast jetzt eine produktions-geformte Installation auf einem Host. Zwei Folgeaufgaben gehören in den Kalender — [Backups und Restore](/de/self-hosted/operate/backups-and-restore) und [Härten](/de/self-hosted/operate/security/hardening). Wächst dein Massstab über einen Host hinaus (Faustregel: etwa hundert gleichzeitige User auf der empfohlenen Spec), lebt die Multi-Host-Architektur unter [Container-Architektur](/de/self-hosted/operate/container-architecture). # Docker-Compose-Referenz Source: https://tale.dev/docs/de/self-hosted/install/docker-compose-reference Tale liefert eine Handvoll Docker-Compose-Dateien aus. Die Basis ist `compose.yml`; der Rest sind Overlays, die Services für spezifische Szenarien hinzufügen oder ersetzen — Entwicklung, Docs, Test. Diese Seite benennt jede Datei, sagt, wann du sie wählst, und gibt die Schichtungs-Regel, der alles andere folgt. Die Form ist absichtlich konservativ. Die Basis-Datei allein läuft in Produktion; jedes Overlay ist per `-f` opt-in und fügt nur hinzu, was es muss. Merk dir die Basis und ein einzelnes Overlay, nicht das ganze Raster. ## Ein durchgespieltes compose-up Eine produktive Single-Host-Instanz läuft allein aus der Basis: ```bash docker compose up -d ``` Ein Entwickler, der gleichzeitig an Platform und Docs hackt, schichtet zwei Overlays: ```bash docker compose -f compose.yml -f compose.dev.yml -f compose.docs.yml up -d ``` Die linkeste Datei ist die Basis; jede nachfolgende Datei merged ihre Schlüssel obendrauf. Konflikte (gleicher Service, gleicher Schlüssel) lösen mit Last-File-wins auf. Der gemergte Graph ist, was Docker hochfährt. ## Die Compose-Dateien | Datei | Anwendungsfall | Bemerkenswerte Overrides | | ----------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------- | | `compose.yml` | Produktion auf einem einzelnen Host | Die Basis — jeder Service, Healthchecks, Restart-Policy | | `compose.dev.yml` | Lokale Entwicklung mit Hot-Reload | Mountet Quellen in Container, tauscht auf Dev-Images, gibt Dev-Ports frei | | `compose.docs.yml` | Fügt den Docs-Site-Service hinzu | Fährt `tale-docs` hoch und routet `/docs` durch den Proxy | | `compose.web.yml` | Fügt den Marketing-Site-Service hinzu | Fährt `tale-web` hoch und routet `/` (Root) durch den Proxy | | `compose.test.yml` | Lässt die Platform-Test-Suite gegen den Stack laufen | Ersetzt das Platform-Image durch die test-geformte Variante | | `compose.web.test.yml` | Lässt Web-Tests laufen | Wie `web.yml`, aber die test-geformte Variante | | `compose.docs.test.yml` | Lässt Docs-Tests laufen | Wie `docs.yml`, aber die test-geformte Variante | | `compose.test.mock.yml` | Mock-gestützte Connectorstests | Tauscht Provider gegen Mock-Implementierungen | ## Services und ihre Rollen Der Basis-Graph fährt acht Container hoch: - `tale-proxy` — Caddy. TLS, Reverse-Proxy, 301s. - `tale-platform` — die TanStack-Start-App. Die User-zugewandte UI und API. - `tale-convex` — das Convex-Backend. WebSocket, Queries, Mutationen, Actions — und die In-Process-RAG-Suche, Dokument-Ingestion, das Web-Crawling und die Dokumentgenerierung, die früher separate Services waren. - `tale-db` — operatives Postgres (ParadeDB). Der persistente Speicher des Convex-Backends. - `tale-knowledge-db` — Postgres des Wissens-Korpus (ParadeDB). Die `tale_knowledge`-Datenbank mit Dokument-Chunks, Embeddings und gecrawlten Seiten, auf Port 5433, damit sie nie mit `tale-db` auf 5432 kollidiert. - `tale-sandbox-llm-gateway` — das LLM-Gateway für Harness-Züge (gepinntes externes Image). - `tale-sandbox-egress` und `tale-sandbox` — die Sandbox-Ebene. Run-Code-Container hinter einem Egress-Proxy (standardmäßig offen; sperrbar mit `SANDBOX_EGRESS_ALLOWLIST`), zugleich die Headless-Browser-Laufzeit, die das Convex-Backend für Web-Render und Dokumentgenerierung aufruft. Der Stack ist jetzt vollständig TypeScript — es gibt keinen Python-Service im Graph. [Container-Architektur](/de/self-hosted/operate/container-architecture) vertieft, was was besitzt. ## Overrides Operator-Anpassungen gehören in ein zusätzliches Overlay, nicht in Edits an den ausgelieferten Dateien. Erstell eine `compose.local.yml` mit den Overrides, die du brauchst: ```yaml services: platform: environment: - LOG_LEVEL=debug ``` Fahr den Stack mit dem lokalen Overlay zuletzt geschichtet hoch: ```bash docker compose -f compose.yml -f compose.local.yml up -d ``` Dieses Muster hält `git pull` sauber — keine Merge-Konflikte auf den ausgelieferten Dateien. Dasselbe Muster funktioniert für jedes benutzerdefinierte Volume-Mount, jeden benutzerdefinierten Port oder jedes Environment-Override. ## Profile Ein Service in der Basis-Datei nutzt ein Docker-Compose-Profil. Profile lassen einen Service im Graph existieren, aber nicht starten, ausser sein Profil ist aktiviert. Das im Einsatz befindliche Profil ist `controller` — der Opt-in-Sidecar `tale-controller`, der den Convex-Container auf eine signierte Anfrage neu startet, damit eine Datenresidenz-Änderung greift, ohne der Plattform Docker-Socket-Zugriff zu geben. Aktivier es mit: ```bash docker compose --profile controller up -d ``` ## Wo das hineinpasst Die Compose-Referenz ist das Raster des Betreibers für den Source-Tree. Für das Innere jedes Containers deckt die Seite [Container-Architektur](/de/self-hosted/operate/container-architecture) Verantwortlichkeiten ab; für die Variablen, die die Container beim Boot lesen, ist die [Environment-Referenz](/de/self-hosted/configuration/environment-reference) die Quelle der Wahrheit. # Selbst gehostete Architektur Source: https://tale.dev/docs/de/self-hosted/overview Eine Tale-Instanz besteht aus acht Containern hinter einem Caddy-Proxy, die mit zwei Postgres-Datenbanken sprechen — einer operativen, einer für den Wissens-Korpus; zwei davon sind Sandbox-Container an der Seite für Code-Ausführung. Die compose-Datei ist der Vertrag — was läuft, was exponiert ist, was gemountet ist. Diese Seite vermittelt das mentale Modell, sodass die Install-, Konfigurations- und Betriebsseiten es nicht erneut erklären müssen. Lies das, bevor du `docker compose up` ausführst. Komm zurück, wenn du einen Ausfall debuggst und wissen musst, welches Container-Log du zuerst öffnen solltest. ## Die acht Container **tale-proxy** ist Caddy am Rand. Er terminiert TLS, leitet alles unter `/` an den Plattform-Container und alles unter `/api/` und die Convex-Pfade an den Convex-Container weiter. Health-Checks leben hier. **tale-platform** ist der React + TanStack Start-Server. Er rendert die UI, liefert statische Assets aus und ist der einzige Container, der dem Browser exponiert ist. Er hält keinen Geschäfts-State — alles, was persistieren muss, spricht mit Convex. **tale-convex** ist das Backend: die Actions, Queries, Mutations und die WebSocket-Schicht, die die UI abonniert. Provider-Keys, Agent-Definitionen, Workflow-Läufe, Audit-Logs — alles davon lebt hier. Es läuft auch die Wissens-Arbeit im Prozess — Dokument-Ingestion, Web-Crawling, RAG-Suche und Dokumentgenerierung sind Convex-Node-Actions, keine separaten Services. Die Headless-Arbeit, die diese Jobs brauchen (eine Webseite rendern, HTML in ein PDF oder Bild verwandeln), wird an die Sandbox-Laufzeit delegiert, die ohnehin schon Chromium und Playwright mitbringt. **tale-db** ist das operative Postgres (ParadeDB). Es hält die Daten des Convex-Backends — Agents, Runs, das Audit-Log — und ist einer der zwei zustandsbehafteten Container, die für Backups zählen. **tale-knowledge-db** ist das Postgres des Wissens-Korpus (ParadeDB), die `tale_knowledge`-Datenbank mit zwei Schemata: `private_knowledge` (Chunks hochgeladener Dokumente, Embeddings, der BM25-Index, der semantische Cache) und `public_web` (gecrawlte Webseiten). Es ist von `tale-db` getrennt, damit der Korpus — der datenresidenz-sensible Speicher — sich für sich allein verlagern oder ersetzen lässt. Das Convex-Backend verbindet sich direkt mit ihm; nichts sonst tut das. **tale-sandbox-llm-gateway** ist das LLM-Gateway für Harness-Züge. Es ist der einzige Pfad von einem sandboxierten Harness zu einem Modell-Provider; die Plattform stellt es bereit und prägt Per-Session-Keys. **tale-sandbox** und **tale-sandbox-egress** führen sandboxierten Code für das **Code-ausführen**-Tool und Fähigkeits-Skripte aus und dienen als die Headless-Browser-Laufzeit, die das Convex-Backend für Web-Render und Dokumentgenerierung aufruft. Der Egress-Container ist der einzige Netzwerkweg, den die Sandbox hat. Egress ist standardmäßig offen — sandboxierter Code erreicht jeden öffentlichen Host über HTTPS, Cloud-Metadaten und private Adressbereiche bleiben auf IP-Ebene blockiert. Einschränken kannst du das mit `SANDBOX_EGRESS_ALLOWLIST` auf eine Hostname-Allowlist; die Anleitung steht in [Hardening](/de/self-hosted/operate/security/hardening). Ein weiterer Service kommt mit, bleibt aber standardmäßig aus: **tale-controller** ist ein Opt-in-Sidecar (das `controller`-compose-Profil), der den Convex-Container auf eine signierte Anfrage der App neu startet, damit eine Datenresidenz-Änderung greifen kann, ohne der browserzugewandten Plattform Docker-Socket-Zugriff zu geben. ## Daten auf dem Storage Vier Volumes überleben ein `docker compose down`: - `db-data` — das Datenverzeichnis des operativen Postgres: die Datenbank hinter Agents, Runs und dem Audit-Log. - `knowledge-db-data` — das Datenverzeichnis des Postgres für den Wissens-Korpus: Dokument-Chunks, Embeddings, die Such-Indizes und gecrawlte Webseiten. Sichert separat von `db-data`, weil es eine eigene Datenbank ist. - `backups` — checksummengesicherte Volume-Snapshots, geschrieben von `tale backup` und automatisch vor migrierenden Deploys; [Backups und Restore](/de/self-hosted/operate/backups-and-restore) ist der Drill. - Der Object-Store-Mount von Convex — hochgeladene Dateien, generierte Dokumente, exportierte Bundles. Alles andere ist flüchtig. Container können ohne Datenverlust ersetzt werden, solange die Volumes überleben. ## Provider-Secrets und die SOPS-Schicht Provider-Keys (OpenAI, Anthropic, Azure, Ollama, etc.) leben auf dem Storage in einem `providers/`-Verzeichnis, das in den Plattform-Container gemountet wird. Jeder Provider hat eine `<name>.json` und eine `<name>.secrets.json`; die Secrets-Datei ist mit SOPS und der Variable [`SOPS_AGE_KEY`](/de/self-hosted/configuration/environment-reference) verschlüsselt. Diese Trennung existiert aus zwei Gründen. Einen Provider-Key zu rotieren ist eine Datei zu bearbeiten, nicht die Plattform neu zu starten; die verschlüsselte Datei zu sichern ist sicher, sie neben der Infrastruktur zu committen. Der Klartext-Modus (kein SOPS, Secrets in Klartext) wird für streng kontrollierte Umgebungen unterstützt, wo der Storage selbst at-rest verschlüsselt ist. ## Auth und Sessions Sign-in ist Better Auth, das im Convex-Container läuft. Vier Sign-in-Modi sind dabei: lokales Passwort, Microsoft Entra (OAuth/OIDC), generisches OIDC und Trusted Headers (der Reverse-Proxy liefert die Identität). Der Plattform-Container liest das Cookie, übergibt es an Convex, und Convex entscheidet, was die Session tun darf, basierend auf der Rolle des Benutzers und der Berechtigungs-Matrix pro Ressource, die in [Mitglieder und Rollen](/de/platform/admin/members-and-roles) dokumentiert ist. Die [Authentifizierungs-Referenz](/de/self-hosted/configuration/authentication) behandelt die Umgebungsvariablen und die Trade-offs pro Modus. ## Wenn du Single-Host hinter dir lässt Die Standard-compose-Datei betreibt alle acht Container auf einem Host. Die Architektur ist single-tenant: nichts im Design teilt Arbeit über Hosts hinweg. Das Erste, was du ohne Re-Architektur von der Box bewegen kannst, ist der Wissens-Korpus — `tale-knowledge-db` ist ein eigenständiges Postgres, also ist es eine Connection-String-Änderung, es auf verwaltete Infrastruktur zu zeigen (für Kapazität oder eine Residenz-Anforderung), behandelt in [Datenresidenz](/de/self-hosted/configuration/data-residency). Die Convex-Schicht ist immer noch Single-Instance; horizontale Skalierung des Backends ist kein v1-Feature. ## Wo das hingehört Diese Architektur-Seite ist die Karte, die jede andere selbst-gehostete Seite voraussetzt. Die natürliche nächste Lektüre ist [Quickstart](/de/self-hosted/install/quickstart), wenn du eine frische Instanz aufsetzt, oder [Container-Architektur](/de/self-hosted/operate/container-architecture), wenn du eine betreibst und dasselbe Bild mit den Fehler-Modi überlagert brauchst. # Tale-Dokumentation Source: https://tale.dev/docs/de Tale ist der Orchestrator für KI-Agents. Du chattest mit Modellen über deine eigenen Dokumente, baust Agents, die eine Aufgabe von Anfang bis Ende übernehmen, lässt Automatisierungen im Hintergrund laufen und verwaltest Kunden-Konversationen in einem einzigen Posteingang — mit deiner Wahl an KI-Anbietern und deinen Daten in einer Region, die du selbst bestimmst. Jedes Feature, jede API und jede Rolle ist in beiden Editionen identisch; der einzige Unterschied ist, wer den Stack betreibt. Starte mit dem Quickstart und folge dann dem Einstieg, der zu deiner Rolle passt. <CardGroup cols="1"> <Card title="Quickstart — in 5 Minuten zur ersten Agent-Antwort" icon="zap" href="/de/get-started/quickstart"> Von einer laufenden Instanz zu einer funktionierenden Chat-Antwort, auf Cloud oder deiner eigenen Maschine. </Card> </CardGroup> ## Wähl deinen Einstieg Vier Einstiege für den ersten Tag, einer pro Rolle. Jeder dauert rund 15 Minuten und endet mit etwas, das funktioniert. <CardGroup cols="2"> <Card title="Ich nutze Tale" icon="message-circle" href="/de/get-started/members"> Dein erster Chat, dein erstes Dokument, dein erstes Projekt — der erste Tag als Mitglied. </Card> <Card title="Ich baue Agents" icon="bot" href="/de/get-started/editors"> Veröffentliche einen minimalen Agent und sieh ihm beim Antworten zu — der erste Tag als Redakteur. </Card> <Card title="Ich binde Tale an" icon="code" href="/de/get-started/developers"> Erstelle einen API-Schlüssel und mach deine erste authentifizierte Anfrage — der erste Tag als Entwickler. </Card> <Card title="Ich betreibe den Arbeitsbereich" icon="shield" href="/de/get-started/admins"> Richte den Arbeitsbereich ein, lade das Team ein, verbinde einen Anbieter — der erste Tag als Admin. </Card> </CardGroup> ## Wähl deine Edition <CardGroup cols="2"> <Card title="Cloud" icon="cloud" href="/de/cloud"> Tale betreibt den Stack — wähl das, wenn das Betreiben von Infrastruktur nicht der richtige Ort für die Stunden deines Teams ist. </Card> <Card title="Selbst gehostet" icon="server" href="/de/self-hosted"> Installiere Tale in deiner eigenen VPC, auf On-Premise-Hardware oder in einer Air-gapped-Umgebung. </Card> </CardGroup> ## Tiefer eintauchen <CardGroup cols="3"> <Card title="Plattform" icon="layout-dashboard" href="/de/platform"> Die kanonische Feature-Referenz, identisch für Cloud und selbst gehostet. </Card> <Card title="Tutorials" icon="route" href="/de/tutorials/overview"> Rollenbasierte Walkthroughs von „Ich möchte X tun" zum funktionierenden Ergebnis. </Card> <Card title="Entwicklung" icon="terminal" href="/de/develop/overview"> REST API, Webhooks, Connector-SDK, Contributor-Workflows. </Card> </CardGroup> ## Wo das hingehört Sobald du einen Einstieg durchlaufen hast, ist der Rest der Dokumentation einen Klick entfernt: [Plattform](/de/platform) ist die kanonische Referenz für jedes nutzersichtbare Feature, und die [Tutorials](/de/tutorials/overview) gehen bei kompletten Aufgaben in die Tiefe. Quellcode, Issues und Release-Ankündigungen leben auf [GitHub](https://github.com/tale-project/tale). # Trust und Compliance Source: https://tale.dev/docs/de/cloud/trust-and-compliance Trust und Compliance auf Cloud ist die Seite, die ein Auditor will. Sie benennt die Frameworks, gegen die die Plattform zertifiziert ist, trennt Verantwortlichkeiten zwischen Tale und deiner Org sauber, listet die für dich verfügbaren Datenschutzkontrollen und sagt dir, wen du anrufst, wenn etwas schiefgeht. Der Inhalt hier ist beschreibend — was heute ausgeliefert wird, welche Belege Tale auf Anfrage übergeben kann. Die rechtlichen Dokumente selbst (DPA, Terms, Privacy) leben unter [Legal](/de/legal/privacy); diese Seite ist die schnelle Betreiber-Referenz. ## Eine durchgespielte Kontrolle — Audit-Logs von Anfang bis Ende Der Compliance-Verantwortliche der Org muss nachweisen, dass „jede Änderung an Zugriffskontrollen mit Akteur, Ziel und Zeitstempel protokolliert wird". Tales [Audit-Logs](/de/platform/admin/governance/audit-logs) zeichnen jede Mitgliedseinladung, Rollenänderung, Entfernung und 2FA-Zurücksetzung mit der User-ID des Akteurs, der ID des betroffenen Mitglieds und einem ISO-Zeitstempel auf. Logs sind unveränderlich — einen Schnappschuss wiederherzustellen verändert sie nicht — und gemäss dem konfigurierten Floor der Org aufbewahrt. Der Verantwortliche exportiert einen Datumsbereich als CSV, übergibt ihn dem Auditor, und das durchgespielte Beispiel räumt die Kontrolle ab. ## Zertifizierungen und Frameworks Tale Cloud ist derzeit gegen die folgenden Frameworks auditiert oder attestiert; die Zertifizierungsberichte sind unter NDA über den Support verfügbar: - SOC 2 Type II (jährlich) - ISO/IEC 27001 - DSGVO-konforme Kontrollen (EDPB-Leitlinien angewendet) - FADP-konforme Kontrollen für die Schweizer Region (revDSG) Geplant: HIPAA BAA (US-Enterprise-Kunden), zusätzliche regionale Attestierungen, wenn die Regionsliste wächst. ## Geteilte Verantwortung | Kontrolle | Tale | Du | Beleg | | ----------------------------- | ---------------------- | ----------------------- | ------------------------------------------------------------- | | Infrastruktur-Verfügbarkeit | ✓ | | Status-Seite, SOC 2 SLA-Bericht | | Datenverschlüsselung ruhend | ✓ | | Architektur-Beschreibung | | Verschlüsselung im Transit | ✓ | | TLS-Terminierung an Tales Edge | | Mitgliedsidentität und Rollen | | ✓ | [Mitglieder und Rollen](/de/platform/admin/members-and-roles) | | API-Key-Ausgabe und Rotation | | ✓ | [API-Keys](/de/platform/admin/api-keys) | | Content-Filterung und DLP | Stellt Hooks bereit | Konfiguriert Regeln | [Guardrails](/de/platform/admin/governance/guardrails) | | Audit-Log-Aufbewahrung | Stellt Speicher bereit | Setzt die Aufbewahrung | [Aufbewahrung](/de/self-hosted/configuration/retention) | | Auskunftsanfragen | Stellt Workflow bereit | Initiiert und genehmigt | [DSAR](/de/platform/admin/governance/data-subject-requests) | | Provider-Credentials | | ✓ | [Provider](/de/platform/admin/providers) | ## Datenschutz-Kontrollen Innerhalb des Produkts zählen drei Kontroll-Oberflächen für Compliance: - **Audit-Logs** — unveränderlicher Datensatz, wer was getan hat; Aufbewahrung konfigurierbar. - **Legal Hold** — nimmt eine Datensatz-Menge bis zur Aufhebung aus der Aufbewahrung; abgedeckt in [Legal Hold](/de/platform/admin/governance/legal-hold). - **Auskunftsanfragen** — der Anfrage-→-Übernahme-→-Löschung-→-Audit-Workflow; abgedeckt in [DSAR](/de/platform/admin/governance/data-subject-requests). ## Vorfälle melden Tales Sicherheitsvorfall-Kontakt ist `security@tale.dev`. Vermutete Schwachstellen-Offenlegung folgt der Responsible-Disclosure-Policy auf derselben E-Mail. Kundenseitige Sicherheits-Advisories werden auf der Status-Seite veröffentlicht und dem Owner der Org per E-Mail zugestellt. ## Wo das hineinpasst Trust und Compliance ist die Audit-Zeit-Seite; [Daten-Residenz](/de/cloud/data-residency) ist die Architektur-Zeit-Seite; [Subprozessoren](/de/legal/subprocessors) ist die Vendor-Listen-Seite. Ein Auditor will normalerweise alle drei zugleich — leg dir Lesezeichen für alle drei. Betreibst du self-hosted, sind die Kontrollen dieselben; was sich ändert, ist, wer die Infrastruktur darunter betreibt — siehe [Self-hosted-Übersicht](/de/self-hosted/overview). # Auf Self-hosted migrieren Source: https://tale.dev/docs/de/cloud/migrate-to-self-hosted Die Migration von Cloud zu Self-hosted ist ein echtes Verfahren, kein Setting-Flip. Die Daten exportieren, die neue Instanz importieren, DNS schwenkt auf den neuen Host, und dein Team meldet sich in derselben Org an, die es hatte — dieselben Agents, dieselben Chats, dieselbe Audit-History. Dieses Tutorial führt das Verfahren und zeigt, wo es schiefgeht. Greif danach, wenn Self-hosting wirklich besser passt: Daten-Residenz erfordert Hardware unter deiner Kontrolle, Kosten im Massstab machen On-premise billiger als Pro-Token, oder die Org hat entschieden, den Stack selbst zu betreiben. Für die meisten Teams bleibt Cloud die richtige Wahl — lies [Cloud-Onboarding](/de/cloud/onboarding) noch einmal, wenn du noch entscheidest. ## Bevor du beginnst Hab diese Dinge vor dem Export bereit: - Einen Ziel-Host, der die Self-hosted-Voraussetzungen erfüllt — siehe [Quickstart](/de/self-hosted/install/quickstart) für die Spec. - DNS-Kontrolle über die Domain, die deine Org aktuell nutzt; du wirst sie beim Cutover schwenken. - Ein Wartungsfenster von mindestens einer Stunde. Der Import selbst ist schneller, aber DNS-Propagation und Validierung fügen Zeit hinzu. - Eine kürzliche Backup-Bestätigung im Audit-Log deiner Cloud-Org. Während einer Migration wird in der Quelle nichts gelöscht, aber das Export-Bundle ist dein Beleg, dass der Quellzustand konsistent war. ## Was mitkommt und was nicht Kommt mit: Chats, Threads, Nachrichten, Anhänge, Dokumente, Wissens-Embeddings, Agents, Agent-Versionen, Workflows, Executions, Audit-Logs, Mitglieder, Rollen, Teams, Branding, API-Keys, Connector-Metadaten. Kommt nicht mit: externe Connectors müssen gegen die neue Instanz neu authentifiziert werden (die Credentials leben im Provider, nicht im Export-Bundle); aktiv laufende Workflows pausieren und nehmen auf der neuen Instanz nach dem Cutover wieder auf; Sprach-Audios, die über das Aufbewahrungsfenster der Org hinaus aufbewahrt werden, bleiben im Cloud-Object-Store, bis sie geleert werden. ## Schritt 1 — Exportieren Öffne **Einstellungen > Organisation** auf Cloud und klick **Export**. Der Dialog führt den Export im Hintergrund aus und schickt einen Download-Link per E-Mail, wenn er fertig ist. Der Export ist ein einzelnes verschlüsseltes Bundle; die E-Mail enthält den Entschlüsselungs-Key. Lade das Bundle herunter und speichere den Key getrennt. ## Schritt 2 — Die Ziel-Instanz aufstellen Folg auf dem Ziel-Host [Quickstart](/de/self-hosted/install/quickstart) bis zum First-Admin-Schritt. Lad noch keine User ein — der Import überschreibt die Mitgliederliste. Bestätige, dass die neue Instanz bootet und du dich als Owner anmelden kannst. ## Schritt 3 — Importieren Melde dich auf der Ziel-Instanz als Owner an und besuche `/_internal/import` (verlinkt von der Einstellungsseite nach einer frischen Installation). Lad das Bundle hoch, füg den Entschlüsselungs-Key ein und klick **Import**. Der Import ist eine lang laufende Operation; die Seite zeigt Fortschritt pro Datenklasse. Löst sich die Seite zu **Import complete** auf, trägt die neue Instanz den vollen Zustand der Quell-Org. ## Schritt 4 — DNS schwenken Aktualisiere den DNS-Eintrag für die Domain der Org, sodass er auf die neue Instanz zeigt. Sobald die Propagation landet und das TLS der neuen Instanz gesund ist, landen User, die sich anmelden, auf der Self-hosted-Instanz mit ihren bestehenden Credentials. Die Cloud-Org wird an diesem Punkt nur-lesbar — um Drift zu vermeiden, archiv sie nach ein paar Tagen Vertrauen unter **Einstellungen > Organisation** auf Cloud. ## Fehlersuche - **Export hängt bei „preparing".** Sehr grosse Orgs (>100 GB) brauchen länger, als das E-Mail-Fenster annimmt. Öffne ein Support-Ticket; der Export läuft im Hintergrund bis zum Abschluss. - **Import scheitert an Schema-Mismatch.** Deine Ziel-Instanz läuft eine ältere Tale-Version als der Cloud-Export erwartet. Upgrade die Ziel-Instanz, bevor du es erneut versuchst — das Bundle ist vorwärts-kompatibel, nicht rückwärts-kompatibel. - **Mitglieder können sich nach dem Cutover nicht anmelden.** Session-Cookies sind auf den alten Host begrenzt. Mitglieder authentifizieren sich einmal neu; SSO- und 2FA-Einstellungen kommen mit. - **Workflows zeigen „pausiert" nach dem Import.** Erwartet — der Import bewahrt den Zustand, nimmt aber laufende Executions nicht automatisch wieder auf. Öffne jeden Workflow und klick **Resume**, nachdem du bestätigt hast, dass die Ziel-Instanz von externen Triggern erreichbar ist. ## Wo das eingesetzt wird Migration ist in der Praxis eine Einbahn-Operation — bist du einmal self-hosted, bleibst du es, ausser etwas ändert sich strukturell. Die umgekehrte Migration (Self-hosted zu Cloud) folgt derselben Form mit demselben Tooling und wird unterstützt, ist aber selten. Bist du noch auf Cloud und liest das für Kontext, ist die Anschluss-Seite [Self-hosted-Übersicht](/de/self-hosted/overview); sie benennt, was du dir aufhalst. # Cloud Source: https://tale.dev/docs/de/cloud Tale Cloud ist die verwaltete Edition. Tale betreibt die Infrastruktur, deine Daten liegen in der Schweiz oder in der EU, und die einzige Betriebssorge deines Teams ist, das Produkt zu nutzen. Der Code ist identisch mit der selbst gehosteten Variante; der Unterschied liegt darin, wer ihn laufen hält. Dieser Abschnitt behandelt die Themen, die spezifisch für Cloud sind — Onboarding, Regionen und Datenresidenz, Abrechnung, die Compliance-Position, die du einem Auditor vorlegen kannst, und wie du auf selbst gehostet migrierst, wenn sich deine Anforderungen ändern. Jede andere Feature-Referenz lebt einen Reiter weiter unter Plattform — identisch unabhängig von der Edition. ## Seiten in diesem Abschnitt <CardGroup cols="2"> <Card title="Onboarding" icon="rocket" href="/de/cloud/onboarding"> Instanz anfordern, Org erstellen, ersten Modell-Anbieter konfigurieren, ersten Agent veröffentlichen. Etwa eine Stunde für einen Redakteur. </Card> <Card title="Datenresidenz" icon="map-pin" href="/de/cloud/data-residency"> Wo deine Daten liegen, welche Sub-Auftragsverarbeiter sie berühren und was sich ändert, wenn du die Region wechselst. </Card> <Card title="Abrechnung" icon="credit-card" href="/de/cloud/billing"> Pläne, Sitze, abrechenbare Komponenten, Budgets, und wo du die Rechnung findest. </Card> <Card title="Vertrauen und Compliance" icon="shield-check" href="/de/cloud/trust-and-compliance"> Die Zertifizierungen, die Tale mitbringt, die geteilte Verantwortung und was du als Nachweis vorlegen kannst. </Card> <Card title="Auf selbst gehostet migrieren" icon="server" href="/de/cloud/migrate-to-self-hosted"> Aus Cloud exportieren, selbst gehostete Instanz aufsetzen, importieren. </Card> </CardGroup> ## Wo das hingehört Cloud ist die Eingangstür; Plattform ist der Ort, an dem die eigentliche Arbeit stattfindet. Sobald deine Organisation eingeloggt ist und der erste Agent läuft, verbringt dein Team nahezu die gesamte Zeit auf den Plattform-Seiten, nicht hier. Die eine Seite, die sich bei jeder Änderung deiner Betriebslage erneut lesen lohnt, ist [Datenresidenz](/de/cloud/data-residency) — sie zeigt jedes externe System, das deine Daten kreuzen. # Abrechnung Source: https://tale.dev/docs/de/cloud/billing Abrechnung auf Cloud ist gemessen, nicht pro Sitz. Du zahlst für Tokens, die von Chats und Agents verbraucht werden, für Sprachminuten, Bildgenerierungen und Speicher; die Plattform selbst kommt mit der Org. Diese Seite führt eine Rechnungszeile durch, listet die gemessenen Komponenten und verweist auf die Budgetkontrollen, die Überraschungen verhindern. Die Rechnung kommt monatlich per E-Mail und ist auch im Produkt unter **Einstellungen > Abrechnung** sichtbar. Cloud rechnet in der Abrechnungswährung deiner Org ab, die bei der Anmeldung auf USD voreingestellt ist und vor dem ersten Rechnungslauf geändert werden kann. ## Eine durchgespielte Rechnungszeile Eine Zeile auf der Rechnung lautet `Models — Anthropic Claude Sonnet — 1.2M tokens — $4.32`. Tale hat sie aus dem Pro-Nachricht-Nutzungs-Ledger zusammengesetzt: jede Chat-Antwort speichert das genutzte Modell, die Token-Zahl und den Preis zur Rate, die beim Abschluss des Aufrufs aktiv war. Zeilen aggregieren pro Provider und Modell pro Abrechnungsperiode. Das Detail ist als CSV vom selben Bildschirm herunterladbar. ## Plan-Tiers Tale bietet zwei Tiers — **Community** und **Enterprise**. Community ist die selbstgehostete Open-Source-Edition; du betreibst sie auf deiner eigenen Infrastruktur, und das Abrechnungskonzept dieser Seite gilt dafür nicht. **Enterprise** ist der gemanagte Tier (Cloud oder Self-hosted) mit Support-SLA, Audit-Log-Aufbewahrungs-Kontrollen, SSO, AVV und Zugriff auf Regionen jenseits des Defaults. Der Tier beeinflusst feste Monatsgebühren und Feature-Gates, nicht Pro-Aufruf-Kosten; das gemessene Pricing für Tokens, Sprache und Speicher unten gilt für Enterprise auf Cloud. ## Gemessene Komponenten | Komponente | Einheit | Gezählt als | Wo zu sehen | | ------------- | -------------------- | ------------------------------------------------- | ----------------------------------------------------------------- | | Modelle | Tokens (rein + raus) | Pro Provider-Aufruf; Aufschlag auf Provider-Rate | [Nutzungs-Analyse](/de/platform/admin/governance/usage-analytics) | | Sprache (TTS) | Gesprochene Zeichen | Pro als Audio gerenderter Agent-Antwort | Nutzungs-Analyse | | Sprache (STT) | Audio-Sekunden | Pro vom User aufgenommener Nachricht | Nutzungs-Analyse | | Bilder | Generierungen | Pro vom Modell zurückgegebenem Bild | Nutzungs-Analyse | | Speicher | GB-Monat | Object-Store-Verbrauch über die Periode gemittelt | Abrechnungsseite | ## Budgets und Überschreitungen Setz Budgets unter [Policies and limits](/de/platform/admin/governance/policies-and-limits). Eine **Budget rule** deckelt monatliche Ausgaben pro User, pro Team, pro Rolle oder pro Org. Ein Budget zu treffen liest sich als klarer Toast — **Nutzungslimit erreicht** — und pausiert den betroffenen Bereich, bis das Budget angehoben oder die Periode umgedreht wird. Die Default-Vorrangordnung ist `user > team > role > default` — die spezifischste Regel gewinnt. Eine **Warning threshold (%)** auf derselben Regel emittiert eine Benachrichtigung, wenn die Nutzung die Schwelle überschreitet, ohne zu blockieren. Greif zur Warnung, wenn du wissen, aber nicht unterbrechen willst; greif zu harten Limits, wenn Überschreitungen ein Notfall sind. ## Wo Nutzung zu finden ist Die reichste Ansicht ist [Nutzungs-Analyse](/de/platform/admin/governance/usage-analytics) unter Governance — sie bricht die Nutzung nach **Top Assistants**, **Top Models**, **Top Voice Models** und **Per-User Usage** auf, alle nach Datumsbereich filterbar. Die Abrechnungsseite in den Einstellungen zeigt die Rechnungs-Ansicht; die Nutzungs-Analyse zeigt die operative Ansicht. ## Wo das hineinpasst Abrechnung ist die Schlagzeilenseite des Betreibers; [Nutzungs-Analyse](/de/platform/admin/governance/usage-analytics) ist die alltägliche. Sind die Kosten deiner Org hauptsächlich Tokens, ist die Top-Models-Tabelle die zu setzende Lesezeichen-Seite — sie zeigt, auf welche Modelle sich das Team festgelegt hat, und sagt dir, ob ein Wechsel zu einer billigeren Alternative etwas brächte. Für Self-hosted-User gilt das Abrechnungskonzept nicht (du zahlst deinen Provider direkt); die Kosten-Sichtbarkeitsseite schon. # Cloud-Onboarding Source: https://tale.dev/docs/de/cloud/onboarding <!-- Internal, for agents editing this page: Tale Cloud has no self-serve sign-up — tale.dev ships no sign-up route. A Cloud customer fills in the demo request form (https://tale.dev/request-demo — /de/ and /fr/ localized), and the Tale team sets up a dedicated demo instance for them. The journey below only starts once that instance exists; from there it deliberately mirrors normal first-run onboarding (sign-up on the customer's own instance, org wizard, providers). Keep the request-your-instance step first and do not change the entry point back to a tale.dev sign-up. --> Diese Strecke führt von der Demo-Anfrage zu einer produktionsreifen Cloud-Org mit einem funktionierenden Agent. Das Ergebnis ist eine Org, in der sich dein Team anmelden, einen funktionierenden Agent wählen und ihn etwas Nützliches fragen kann — noch nichts Aufregendes, nur das Fundament, auf dem alles Weitere aufbaut. Du brauchst eine funktionierende E-Mail-Adresse und die Möglichkeit, sie zu verifizieren. Die Strecke setzt kein Tale-Vorwissen voraus; referenziert unten etwas ein Konzept, das du noch nicht kennst, führt die verlinkte Seite es ein. Sobald deine Instanz bereitsteht, dauert der praktische Teil unter einer Stunde — rund die Hälfte davon steckt im Anbieter-Schritt, der Rest ist überwiegend Klicken. ## Bevor du beginnst Klär drei Dinge: - Eine E-Mail-Adresse für den ersten Inhaber der Org. Dieses Konto trägt die höchste Rolle; wähl jemanden, der nicht nächste Woche das Team verlässt. - API-Zugangsdaten für mindestens einen Modellanbieter (OpenAI, Anthropic, Azure oder ein kompatibler lokaler). Das Portal des Anbieters zeigt, wo sie liegen. - Die Region, in der deine Daten liegen sollen. Cloud bietet die Schweiz und die EU; die Wahl gehört zum Instanz-Setup — ein späterer Wechsel ist eine echte Migration. ## Von der Demo-Anfrage zum funktionierenden Agent <Steps> <Step title="Fordere deine Instanz an"> Tale Cloud ist kein Self-Service — jede Cloud-Org läuft auf einer eigenen Instanz, die das Tale-Team für dich aufsetzt. Füll das Demo-Formular unter [tale.dev/de/request-demo](https://tale.dev/de/request-demo) aus; Name und E-Mail genügen, Firma und ein Satz dazu, was deine Agenten tun sollen, helfen dem Team, das Setup zuzuschneiden. Das Team setzt dann deine eigene Demo-Instanz auf — eine dedizierte Umgebung, keine geteilte Testumgebung — und meldet sich, sobald sie bereitsteht. </Step> <Step title="Erstelle deine Organisation"> Öffne deine Instanz und registriere dich. Das Formular fragt nach Name, E-Mail und Passwort; bestätige den E-Mail-Link, sobald er ankommt. Der nächste Bildschirm fragt eine Sache ab: **Organisationsname** — der Anzeigename, den dein Team in der Ecke jeder Seite sieht. Wähl einen, der ein Rebranding überlebt. <Frame caption="Der Arbeitsbereichs-Schritt — der Name, den dein Team überall sieht."> ![Der Assistent zum Erstellen einer Organisation auf seinem Arbeitsbereichs-Schritt, mit Northlight Labs im Feld Organisationsname und aktivem Knopf Weiter.](/images/get-started/org-create-wizard.webp) </Frame> Der erste Benutzer wird automatisch **Inhaber** der Org. Falls du es vergisst: Deine Rolle siehst du später im Abschnitt **Mitglieder** unter **Einstellungen > Organisation**. </Step> <Step title="Lade den ersten Admin ein"> Öffne **Einstellungen > Organisation**, scroll zum Abschnitt **Mitglieder** und klicke auf **Mitglied hinzufügen**. Gib die E-Mail des Admins ein und weise die Rolle **Admin** zu. Die eingeladene Person erhält eine E-Mail mit einem Magic-Link, registriert sich und landet in der Org mit der zugewiesenen Rolle. Die Sicherheitsregel „mindestens 2 Admins" verhindert, dass sich eine Org versehentlich aussperrt, indem sie ihren einzigen Admin entfernt — lad einen zweiten Admin ein, bevor du etwas tust, das sie voraussetzt. Die Rollen-Matrix (wer was darf) steht in [Mitglieder und Rollen](/de/platform/admin/members-and-roles). </Step> <Step title="Verbinde einen Modellanbieter"> Öffne **Einstellungen > KI-Anbieter**, such den Connector, für den du einen Schlüssel hast, und klicke auf **Zugangsdaten hinzufügen**. Gib den Zugangsdaten einen Namen, an dem später erkennbar ist, welcher Schlüssel dahintersteckt, wähl als Authentifizierungsmethode **API-Schlüssel** und füg den Schlüssel ein. Er wird verschlüsselt gespeichert und ist als erster Eintrag automatisch der Standard des Connectors; ein zweiter Eintrag am selben Connector ist erlaubt, und du entscheidest, welcher der Standard ist. Wird ein Schlüssel abgelehnt, liegt es meistens an Whitespace darum herum. <Frame caption="Der verbundene Anbieter — von hier kann jeder Agent antworten."> ![Die Einstellungsseite für KI-Anbieter listet einen verbundenen Anbieter, OpenRouter, mit seiner Basis-URL und 52 Modellen.](/images/get-started/settings-providers.webp) </Frame> <Note> An diesem Schritt stocken die meisten Onboarding-Sitzungen — das Anbieter-Portal ist meist ein anderes Login, und das Team muss nach dem Schlüssel graben. Hängt die Validierung länger als eine Minute, lade die Seite neu; der Schlüssel ist gespeichert, sobald **Speichern** bestätigt — die Zeile braucht manchmal ein Neuladen, um ihn anzuzeigen. </Note> </Step> <Step title="Veröffentliche deinen ersten Agent"> Öffne **Agenten** und klicke auf **Agent erstellen**. Wähl das gerade verbundene Modell. Schreib einen Absatz Anweisungen — die Stimme, in der der Agent antworten soll, die Domäne, die er kennt, die Fälle, die er ablehnt. Speichere. Schalte **Im Chat sichtbar** ein. Der Agent ist jetzt aus jedem Chat in der Org erreichbar. Was einen Agent gut macht, vertieft [Einen Agent erstellen](/de/platform/agents/create). </Step> <Step title="Öffne den Chat"> Klicke in der Sidebar auf **Neuer Chat**. Wähl den Agent in der Auswahl, tippe eine Frage aus seiner Domäne, sende. <Check> Die Antwort streamt zurück — landet sie so, wie du die Anweisungen geschrieben hast, ist die Org mit dem Onboarding fertig. </Check> Drei Anschlussaufgaben, die sich jetzt lohnen, solange alles frisch ist: - Öffne **Einstellungen > Branding** und lade das Org-Logo hoch. - Setz die Standardsprache der Org unter **Einstellungen > Organisation**. - Überflieg [Trust und Compliance](/de/cloud/trust-and-compliance), damit du weißt, was du einem Auditor zeigst, bevor einer fragt. </Step> </Steps> ## Fehlersuche - **Die Einladungs-E-Mail kommt nie an.** Schau im Spam-Ordner der eingeladenen Person nach. Tale sendet von `noreply@tale.dev`; manche Unternehmensfilter halten das zurück. - **Die Anbieter-Validierung scheitert mit „invalid key".** Kopier den Schlüssel erneut aus dem Anbieter-Portal — beim Kopieren landet oft ein führendes oder folgendes Leerzeichen mit. - **Der Agent taucht nicht in der Chat-Auswahl auf.** Prüfe, dass **Im Chat sichtbar** für den Agent eingeschaltet ist. ## Wo das eingesetzt wird Du hast jetzt eine Org mit einem funktionierenden Agent und einem Admin neben dir. Die natürliche nächste Strecke ist [Deinen ersten Agent bauen](/de/tutorials/editor/first-agent-end-to-end) — dieselbe Form, aber mit einem Agent, der über Wissensanbindungen echte Domänenarbeit leistet. Bist du hier, um Cloud gegen selbst gehostet abzuwägen, ist [Auf Self-hosted migrieren](/de/cloud/migrate-to-self-hosted) die Strecke in die Gegenrichtung. # Daten-Residenz Source: https://tale.dev/docs/de/cloud/data-residency Daten-Residenz auf Cloud beantwortet zwei Fragen, die jedes Audit am Ende stellt: welche Region hält deine Daten ruhend, und welche externen Systeme berühren sie im Fluss. Diese Seite verfolgt einen einzelnen Chat-Roundtrip von Anfang bis Ende, listet die Datenklassen und benennt jeden Sub-Prozessor, den deine Nachrichten passieren. Die Default-Region für neue Cloud-Orgs ist die Schweiz. Die Region nach der Anmeldung zu wechseln ist eine Migration, kein Setting-Flip — eine Org in der EU-Region neu zu erstellen ist schneller, als eine bestehende zu verschieben. Wähl einmal; wähl bewusst. ## Ein durchgespieltes Beispiel — ein Chat-Roundtrip Der User in Zürich öffnet Chat und sendet „fass den letzten Kundenanruf zusammen". Die Anfrage trifft Tales Edge in der gewählten Region, landet auf `tale-platform`, ruft in `tale-convex` (das Backend), liest Wissen aus der Datenbank des Wissens-Korpus, sobald das Wissens-Tool des Agents danach fragt, und emittiert einen ausgehenden Anruf an den Provider hinter dem Modell, das die sendende Person gewählt hat. Der Wissens-Abruf läuft im Convex-Backend — es fragt die Korpus-Datenbank direkt ab, ohne separaten Retrieval-Dienst im Pfad. Der Modell-Provider gibt Tokens zurück; Tale streamt sie auf demselben Pfad zurück. Die Antwort und die Zitate landen in der operativen Datenbank, der Korpus bleibt in der Wissensdatenbank, und beide werden innerhalb der Region repliziert. Zwei Pfeile überqueren in diesem Trip die regionale Grenze: der Anruf an den Modell-Provider (immer extern) und jeder Sub-Prozessor, den die Tools des Agents ausgelöst haben (Web-Fetch, OneDrive-Lese, MCP-Server in einer anderen Region). Alles andere bleibt in der Region. ## Primärregionen | Region | Postgres | Object Store | DR-Replikat | | ----------------- | --------- | ------------ | ----------- | | Schweiz | Zürich | Zürich | Genf | | Europäische Union | Frankfurt | Frankfurt | Dublin | Das DR-Replikat ist für Disaster Recovery, nicht für aktiven Verkehr. Die Daten einer Region fliessen nie zum Primary oder Replikat der anderen Region. ## Was in der Region bleibt, was sie verlässt | Datentyp | Region-gebunden | Überquert | Hinweise | | -------------------------------- | --------------- | --------- | ------------------------------------------------------------------------------------ | | Chats und Nachrichten | ✓ | | | | Dokumente und Wissens-Embeddings | ✓ | | | | Org-Konfiguration und Rollen | ✓ | | | | Audit-Logs | ✓ | | | | Modell-Provider-Anfragen | | ✓ | Geht an den konfigurierten Provider; wähl einen regionalen Endpunkt, wenn vorhanden. | | OneDrive-Sync | | ✓ | Die Speicherregion von Microsoft gilt. | | Web-Tool-Abrufe | | ✓ | Wohin die URL auflöst. | ## Backups und DR Tale schnappt beide Postgres-Datenbanken — den operativen Speicher und den Wissens-Korpus — täglich und den Object Store stündlich. Schnappschüsse sind ruhend verschlüsselt mit Schlüsseln, die Tale hält; das DR-Replikat erhält eine Kopie innerhalb der Region. Restores aus Schnappschüssen sind eine kundeninitiierte Operation, geroutet über den Support; das SLA deckt die Restore-Zeit ab. ## Region wechseln Ein Regionswechsel ist als Export aus der aktuellen Region, Import in die neue Region und DNS-Cutover implementiert. Die Prozedur ist dieselbe wie [Auf Self-hosted migrieren](/de/cloud/migrate-to-self-hosted), ausser dass beide Seiten Cloud-Regionen sind; rechne mit Ausfallzeit im Minutenbereich und einem geplanten Fenster. Es gibt keinen In-place-Region-Schalter. ## Wo das hineinpasst Daten-Residenz ist die erste Seite, die jede Compliance-Prüfung liest. Paar sie mit [Trust und Compliance](/de/cloud/trust-and-compliance) (welches Framework deckt was) und [Subprozessoren](/de/legal/subprocessors) (die Liste jedes externen Systems, das oben benannt ist). Erwägt deine Org Self-hosted wegen einer Residenz-Anforderung, ist [Self-hosted-Übersicht](/de/self-hosted/overview) die nächste Lektüre — den Stack auf eigener Hardware zu laufen bewegt jeden Pfeil dieser Seite innerhalb deiner eigenen Grenze. # Einen MCP-Server von Grund auf hochziehen Source: https://tale.dev/docs/de/tutorials/developer/mcp-server-from-scratch Ein Model-Context-Protocol-Server (MCP-Server) ist ein Prozess, der eine Liste von Tools über ein kleines JSON-RPC-Protokoll bereitstellt. Tale registriert einen MCP-Server einmal auf Org-Ebene; ab dann kann jeder Agent, der diesen Server in seinem Tools-Tab führt, dessen Tools aufrufen. Dieser Spaziergang führt einen brandneuen MCP-Server von „leerem Repo" zu „aus einem Chat von einem Agent aufgerufen" auf einer Tale-Instanz. Du brauchst eine Developer-Rolle, einen Host, der den MCP-Server laufen lassen kann (dein Laptop reicht für den Spaziergang; für Produktion ein Managed-Service oder Container) und eine HTTPS-URL, die Tale erreicht. Cloud-Orgs erreichen öffentliche URLs standardmässig; selbst gehostete Instanzen brauchen Netzwerk-Zugang dorthin, wo der MCP-Server läuft. ## Bevor du beginnst Bestätige zwei Dinge. Du hast Node 20 oder Python 3.11 installiert — die offiziellen MCP-SDKs zielen auf diese Laufzeiten. Die Tale-Instanz erreicht die URL deines MCP-Servers — für lokale Entwicklung tut's ein `ngrok`-Tunnel oder Äquivalent; für Produktion host den Server irgendwo mit einem stabilen HTTPS-Endpoint. Die konzeptuelle Seite von MCP in Tale lebt in [Agent-Tools](/de/platform/agents/tools); dieser Spaziergang ist die Verdrahtung. ## Schritt 1 — Den Server gerüstartig anlegen Der erste Zug ist, den minimalen MCP-Server zu generieren — ein Tool, ein Handler. Das offizielle SDK erledigt die Protokoll-Klempnerei, damit du nur das Tool schreibst. ```bash npm create mcp-server@latest hello-tale cd hello-tale ``` Öffne `src/index.ts` und ersetz das Beispiel-Tool durch eines, das die aktuelle Zeit in einer benannten Zeitzone zurückgibt: ```ts server.tool( 'current_time', 'Return the current time in a given timezone', { timezone: z.string() }, async ({ timezone }) => { const now = new Date().toLocaleString('en-US', { timeZone: timezone }); return { content: [{ type: 'text', text: now }] }; }, ); ``` Lass den Server lokal laufen: ```bash npm run start ``` Der Server lauscht standardmässig auf `http://localhost:3000/mcp`. Das Gerüst steht; in Tale weiss noch nichts davon. ## Schritt 2 — Auf HTTPS verfügbar machen MCP-Server, die Tale aufrufen kann, brauchen eine HTTPS-URL mit gültigem Zertifikat. Für lokale Entwicklung: einen `ngrok`-Tunnel auf Port 3000 zeigen lassen und die öffentliche URL kopieren, die der Tunnel ausgibt. Für Produktion host den Server hinter deinem normalen Ingress — Caddy, Nginx, eine Managed Function, alles, was TLS terminiert. Verifiziere, dass die öffentliche URL auf einen Health-Check antwortet: ```bash curl -sS "https://abcd.ngrok.app/mcp/health" ``` Eine 200 bestätigt Erreichbarkeit. Eine 502 oder ein Timeout heisst, der Tunnel leitet nicht weiter; starte ihn neu oder check die Firewall. ## Schritt 3 — Den Server in Tale registrieren Ein erreichbarer MCP-Server ist für Tale unsichtbar, bis du ihn registrierst. Öffne **Einstellungen > Connectors > MCP-Server** und klick **Neuer Server**. Füll aus: - **Name** — `Hello Tale time` - **URL** — die öffentliche HTTPS-URL aus Schritt 2 (z.B. `https://abcd.ngrok.app/mcp`) - **Auth** — Bearer-Token, falls dein Server eines verlangt, fürs Spaziergang keines Klick **Speichern**. Tale ruft die Methode `list_tools` des Servers auf, um den Tool-Bestand zu entdecken; das Panel zeigt `current_time` mit Beschreibung. Der Server ist nun org-weit registriert. ## Schritt 4 — Den Server an einen Agent hängen und das Tool aufrufen Ein registrierter Server ist nur erreichbar für Agenten, die sich anmelden. Öffne einen beliebigen Agent, klick **Tools > MCP**, schalte **Hello Tale time** ein und speicher. Öffne einen Chat mit dem Agent und frag „what time is it in Tokyo right now". Der Chat rendert eine `current_time`-Tool-Call-Karte; sie auszuklappen zeigt `{ "timezone": "Asia/Tokyo" }` und den Zeitstempel, den dein Server zurückgegeben hat, und die Antwort des Agenten nutzt den Zeitstempel. ## Wo das eingesetzt wird Ein MCP-Server ist die richtige Form, wenn ein Tool ausserhalb von Tale leben muss — Code, der deinem Team gehört, ein Dienst in einem anderen Netz, eine Drittanbieter-API, die du umschnürst. Eigene Tools aus [Ein eigenes Tool bauen](/de/tutorials/developer/build-a-custom-tool) sind die richtige Form, wenn das Tool einmalig ist und in den Einstellungen einer Org lebt. Fürs grössere Bild, wie Tools erweitern, was ein Agent kann, siehe [Agent-Tools](/de/platform/agents/tools). Für die Verdrahtung einer Connector, die statt eigenem Code eine Drittanbieter-API umschliesst, ist [Connectors-Überblick](/de/platform/connectors/overview) die nächste Lektüre. # Eine Automatisierung per Webhook auslösen Source: https://tale.dev/docs/de/tutorials/developer/trigger-automation-via-webhook Ein Webhook-Trigger macht aus einer Automatisierung etwas, das ein externes System per JSON-POST feuern kann. Tale gleicht das Token in der URL gegen den Trigger ab, und der gestartete Lauf gehört zur deployten Version der Automatisierung — nie zu einem Entwurf, an dem gerade jemand arbeitet. Dieser Durchlauf bringt eine Automatisierung von „ich will sie von außen feuern“ zu „ein Bestellereignis kommt an und der Lauf taucht auf“ auf einer einzelnen Instanz. Du brauchst die Rolle Entwickler in der Organisation, eine Automatisierung mit deployter Version und eine Shell mit `curl`. Der vollständige eingehende Vertrag — Statuscodes, Body-Behandlung, Größenlimits — steht in [Webhooks](/de/develop/webhooks); dieser Durchlauf ist die kleinste vollständige Nutzung davon. ## Bevor du beginnst Prüf zwei Dinge. Die Automatisierung, die du auslösen willst, hat eine **deployte** Version — eine gespeicherte Version reicht nicht, und deploybar wird eine Version erst, wenn ihre eigenen Tests grün sind; lass sie also zuerst laufen. Deine Rolle ist mindestens Entwickler; Trigger anlegen ist auf Entwickler und höher beschränkt. Hast du noch keine Automatisierung, ist die kanonische kleine „nimm das Payload auf und hör auf“ — bau sie über [Workflow mit Genehmigungen](/de/tutorials/editor/workflow-with-approvals) und lass für diesen Durchlauf den Genehmigungsknoten weg. ## Schritt 1 — Einen Webhook-Trigger anlegen Der erste Zug ist, einen Webhook-Trigger an die Automatisierung zu binden. Ohne ihn läuft die Automatisierung nur aus der UI oder per Zeitplan; mit ihm bekommt sie eine URL, auf die jedes System POSTen kann. Öffne den Tab **Trigger** der Automatisierung und leg einen Webhook an. Tale erzeugt eine URL, in deren Pfad der Berechtigungsnachweis als Token steckt — kein separater Schlüssel, kein Authorization-Header. Das Klartext-Token wird einmal angezeigt und nie gespeichert, kopier es also jetzt; abgelegt wird nur sein Hash, weshalb dir später niemand die URL zurückholen kann. Der Trigger bindet an den **Namen** der Automatisierung, nicht an die Version, die du deployt hast. Deploy morgen eine neue Version und diese URL funktioniert weiter — genau dafür sind die beiden getrennt. ```bash export TALE_TRIGGER_URL="https://your-host.example.com/api/automations/webhook/<token>" ``` ## Schritt 2 — Ein Payload per curl POSTen Die Webhook-URL ist ein gewöhnlicher POST-Endpunkt, und der Body wird die Eingabe des Laufs. Ein Body, der kein JSON ist, wird als Text durchgereicht statt abgelehnt — ein Anbieter, der formularkodiert postet, erreicht deinen ersten Knoten also trotzdem. ```bash curl -sS "$TALE_TRIGGER_URL" \ -H "Content-Type: application/json" \ -d '{ "orderId": "12345", "amount": 199.0 }' ``` Ein angenommener Aufruf antwortet **202** mit `{ "runId": "..." }`. Der Lauf arbeitet nun asynchron; öffne die Lauf-Liste der Automatisierung und du siehst ihn dort mit deinem Payload als Eingabe. ## Schritt 3 — Die Fehlerfälle lesen Vier Antworten decken alles ab, was der Endpunkt sagen kann, und jede zeigt auf eine andere Behebung. **404** heißt: Das Token passt zu keinem aktiven Trigger — es ist falsch, es wurde gelöscht, oder der Trigger ist deaktiviert. Die Antwort sagt bewusst nie, welcher Fall zutrifft, damit jemand, der Tokens rät, aus dem Unterschied nichts lernt. **409** mit `{ "error": "automation has no deployed version" }` heißt: Die Automatisierung existiert, aber nichts ist live — deploy eine Version, deren Tests grün sind, und derselbe Aufruf läuft. **413** heißt: Der Body liegt über 256 KB; poste dann eine Referenz statt der Nutzlast. **202** ist der einzige Erfolg. Retries verdienen einen eigenen Satz: Der Endpunkt dedupliziert nicht, ein wiederholter POST startet also einen zweiten Lauf. Sicher macht das der Lauf selbst — jeder abgeschlossene Knoten bekommt einen Checkpoint, ein nach einer Unterbrechung wiederaufgenommener Lauf wiederholt seine bereits erzeugten Seiteneffekte also nie. Wäre ein _doppelter_ Lauf trotzdem falsch, führ deine eigene Ereignis-ID im Payload mit und verzweig im ersten Knoten darauf. ## Wo das eingesetzt wird Webhook-Trigger sind die eingehende Naht der Automatisierungs-Engine — das, worauf dein CRM, dein Bestellsystem oder dein Monitoring POSTet. Greif dazu, wenn der Satz lautet „das ist bei uns passiert, lass bitte etwas dazu laufen“; greif zur [API-Referenz](/de/develop/api-reference), wenn du stattdessen eine synchrone Antwort willst. Die Trigger-seitige Konfiguration und die anderen drei Arten, dieselbe Automatisierung zu starten, stehen unter [Workflow-Trigger](/de/platform/automations/triggers). # Tale aus einem Skript aufrufen Source: https://tale.dev/docs/de/tutorials/developer/call-tale-from-a-script Tale aus einem Skript aufzurufen ist der Weg, wenn du einen Wert von der Plattform willst, ohne die UI zu öffnen. Die Tale-API spricht JSON über HTTPS und nimmt ein Bearer-Token im `Authorization`-Header; von da an ist jede Endpoint-Gruppe ein normaler REST-Aufruf. Dieser Walk bringt dich in einer Sitzung von „ich will Tale skripten" zu einer Assistenten-Antwort in deinem Terminal. Du brauchst eine Entwickler-Rolle (für API-Schlüssel), die URL deiner Tale-Instanz und eine Shell mit `curl` und Python. Die volle API-Oberfläche steht in der [API-Referenz](/de/develop/api-reference); diese Seite ist der kleinste End-to-End-Gang hindurch. ## Bevor du anfängst Prüfe drei Dinge. Deine Instanz ist über HTTPS erreichbar — öffne `https://your-host.example.com` und schau, ob das Dashboard lädt. Deine Rolle ist mindestens Entwickler — [API-Schlüssel](/de/platform/admin/api-keys) verwalten Admin- und Entwickler-Rollen. Du kennst ein Modell, das deine Organisation konfiguriert hat — die API wählt nie automatisch eins, jeder Chat-Aufruf nennt sein Modell explizit. ## Schritt 1 — API-Schlüssel erzeugen Der erste Zug ist ein API-Schlüssel. Ihn trägt jeder Skript-Aufruf; ohne ihn antwortet die API 401, und nach der Erstellung kannst du ihn nicht mehr auslesen. Erzeuge einen Schlüssel im [API-Schlüssel](/de/platform/admin/api-keys)-Panel und kopiere, was es zeigt — Tale zeigt ihn einmal und nie wieder. Leg ihn für den Rest dieses Walks als Umgebungsvariable ab: ```bash export TALE_API_KEY="tale_..." export TALE_BASE_URL="https://your-host.example.com" ``` Der Schlüssel gehört dir und deiner Organisation; was er darf, folgt deiner Rolle. Behandle ihn wie ein Passwort. ## Schritt 2 — Rauchtest mit curl Der kleinste End-to-End-Check ist das Auflisten der Automatisierungen der Organisation. Funktioniert das, stimmen Auth, Netzwerk und API; scheitert es, sagt dir die Fehlerart, welches der drei kaputt ist. ```bash curl -sS "$TALE_BASE_URL/api/v1/automations" \ -H "Authorization: Bearer $TALE_API_KEY" | jq ``` Eine 200 mit einem `{ "page": [...], "isDone": true, ... }`-Body bestätigt die Runde — jeder Listen-Endpoint antwortet mit genau diesem paginierten Umschlag. Eine 401 heißt: der Schlüssel ist falsch; alles andere heißt: die Instanz ist unerreichbar oder der Pfad vertippt. ## Schritt 3 — Ein Modell fragen und die Antwort lesen Chat über die API ist asynchron: du postest eine Nachricht, der Turn läuft im Hintergrund, und du pollst, bis er fertig ist. Drei Aufrufe, eine Schleife: ```python import os, time, requests base = os.environ["TALE_BASE_URL"] auth = {"Authorization": f"Bearer {os.environ['TALE_API_KEY']}"} # 1. Ein eigener Thread thread = requests.post(f"{base}/api/v1/threads", headers=auth, json={}).json() # 2. Nachricht senden — nenn ein Modell, das deine Organisation konfiguriert hat requests.post( f"{base}/api/v1/threads/{thread['id']}/messages", headers=auth, json={"content": "In einem Satz: Was ist Tale?", "model": "<dein-modell>"}, ).raise_for_status() # 3. Bis idle pollen, dann die letzte Nachricht lesen while True: status = requests.get( f"{base}/api/v1/threads/{thread['id']}/generation", headers=auth ).json()["status"] if status == "idle": break time.sleep(1) messages = requests.get( f"{base}/api/v1/threads/{thread['id']}/messages", headers=auth ).json()["page"] print(messages[-1]["content"]) ``` `{"status": "idle"}` heißt: der Turn ist fertig — auch ein gescheiterter, der als Assistenten-Nachricht mit dem Fehler landet, statt zu verschwinden. Der Sende-Aufruf antwortet sofort **202**; die Antwort existiert erst, wenn die Poll-Schleife `queued`/`streaming` verlässt. ## Schritt 4 — Einen Automatisierungslauf starten Dieselbe 202-dann-pollen-Form startet echte Arbeit. Automatisierungsnamen sind `/`-Pfade und stehen in URLs mit `__` — `billing/dunning` reist als `billing__dunning`: ```bash RUN=$(curl -sS -X POST "$TALE_BASE_URL/api/v1/automations/billing__dunning/runs" \ -H "Authorization: Bearer $TALE_API_KEY" \ -H "Content-Type: application/json" -d '{ "input": {} }' | jq -r .runId) curl -sS "$TALE_BASE_URL/api/v1/runs/$RUN" \ -H "Authorization: Bearer $TALE_API_KEY" | jq .status ``` Ein Live-Lauf braucht deine Entwickler-Rolle; mit `{"mode": "mock"}` probst du gegen deterministische Mocks, mit jedem Mitglieds-Schlüssel. Eine 409 heißt: die Automatisierung hat noch keine deployte Version. ## Wo das hingehört Ein Skript ist der Weg, wenn die Datenebene JSON ist, kein Bildschirm — Cron-Jobs, CI-Checks, interne Portale. Der API-Schlüssel trägt deine Rolle, jeder Listen-Endpoint antwortet mit demselben paginierten Umschlag, und alles, was echte Arbeit startet, antwortet 202 und gibt dir etwas zum Pollen. Für eingehende Trigger — ein Drittsystem postet in eine Tale-Automatisierung — siehe [Eine Automatisierung per Webhook auslösen](/de/tutorials/developer/trigger-automation-via-webhook). Für einen modellgetriebenen Client statt eines Skripts öffnet der [MCP-Endpoint](/de/develop/mcp-endpoint) dieselbe Plattform als Tools. Für das volle Endpoint-Inventar und das Fehlermodell ist die [API-Referenz](/de/develop/api-reference) die einzige Quelle der Wahrheit. # Ein eigenes Tool bauen Source: https://tale.dev/docs/de/tutorials/developer/build-a-custom-tool Ein eigenes Tool ist eine Funktion, die du schreibst und die das Modell eines Agenten beim Namen aufruft. Du deklarierst das Input-Schema und die Rückgabe-Form; Tale kümmert sich um die Serialisierung, die Tool-Call-Karte im Chat und das Zurückreichen des Resultats an das Modell. Dieser Spaziergang führt ein frisches eigenes Tool von „ich habe eine Funktion im Kopf" zu „der Agent ruft sie aus einem Chat heraus auf" auf einer einzigen Instanz. Du brauchst eine Developer-Rolle in der Org und Zugriff aufs Panel **Einstellungen > Eigene Tools**; alles andere passiert in der UI. Das zugrundeliegende Konzept lebt in [Agent-Tools](/de/platform/agents/tools); diese Seite richtet sich auf die Entwickler-Seite — Schemas, Transport, Fehler. ## Bevor du beginnst Bestätige zwei Dinge. Erstens: deine Rolle ist mindestens Developer — darunter ist das Panel versteckt. Zweitens: du hast einen Agent, den du bearbeiten kannst; falls nicht, erstelle einen über [Agent erstellen](/de/platform/agents/create), bevor du weitermachst. Der Spaziergang nutzt ein Tool mit einem Input und einem Output namens `lookup_order`, das eine Order-ID nimmt und einen Status-String zurückgibt — die kleinste Form, die das Schema, den Aufruf und das Rendern des Resultats übt. ## Schritt 1 — Das Tool in „Eigene Tools" definieren Der erste Zug ist das Registrieren von Tool-Name und JSON-Schema. Das Schema ist das, was das Modell sieht; ohne Schema hat das Modell keine Idee, welche Argumente es ausgeben soll, und der Aufruf passiert nie. Öffne **Einstellungen > Eigene Tools** und klick **Neues Tool**. Gib ihm einen Namen (`lookup_order`), eine Ein-Satz-Beschreibung (`Look up the status of an order by ID`) und ein JSON-Schema für den Input: ```json { "type": "object", "properties": { "orderId": { "type": "string", "description": "The order ID, e.g. ORD-12345" } }, "required": ["orderId"] } ``` Speichern. Das Tool ist nun in der Tool-Registry der Org registriert; noch nutzt es kein Agent. ## Schritt 2 — Die Implementierung verdrahten Ein registriertes Tool ohne Implementierung gibt dem Modell einen Fehler zurück. Tale bietet zwei Implementierungs-Modi: ein Inline-Sandbox-Skript (Python oder JavaScript, in Tales Sandbox ausgeführt) und einen ausgehenden HTTPS-Call (Tale POSTet die Argumente an deinen Endpoint, du gibst JSON zurück). Wähl für diesen Spaziergang den HTTPS-Modus — das ist die Form, zu der du in Produktion greifst. Im Detail-Panel des Tools setze: - **Endpoint-URL** — `https://your-api.example.com/lookup-order` - **Methode** — `POST` - **Auth-Kopfzeile** — ein Bearer-Token aus deinem Secret-Manager Tale POSTet `{ "orderId": "..." }` an deinen Endpoint; dein Endpoint gibt `{ "status": "shipped", "carrier": "DHL", "eta": "2026-06-01" }` zurück. Speichern. Das eigene Tool ist verdrahtet. ## Schritt 3 — Das Tool an einen Agent hängen Ein verdrahtetes Tool ist für Agenten unsichtbar, bis einer von ihnen die Erlaubnis bekommt, es aufzurufen. Öffne den Agent, den du erweitern willst, klick **Tools**, scroll zu **Eigene Tools** und schalte `lookup_order` ein. Speicher den Agent. Öffne einen Chat mit dem Agent und frag „what is the status of order ORD-12345". Der Chat zeigt zwischen deiner Nachricht und der Antwort eine eingeklappte `lookup_order`-Tool-Call-Karte; sie auszuklappen zeigt die Argumente, die das Modell ausgegeben hat (`{ "orderId": "ORD-12345" }`) und das JSON, das dein Endpoint zurückgegeben hat. Das Modell schreibt die Antwort dann mit dem Tool-Resultat. ## Wo das eingesetzt wird Ein eigenes Tool ist die Naht zwischen einem Agent und deiner Domäne — Order-Lookup, interne Suche, Rechner, alles, was eine Standard-Connector nicht abdeckt. Das Schema ist das, womit das Modell entscheidet, ob es aufruft — investier die Zeit für eine knappe Beschreibung und nimm nur die Felder, die du brauchst. Für Tools, die du Org-übergreifend teilen willst, siehe [MCP-Server von Grund auf](/de/tutorials/developer/mcp-server-from-scratch) — MCP ist das Protokoll für „ein Tool, viele Tale-Instanzen". Für die konzeptuelle Seite, was Tools in einem Agent tun, siehe [Agent-Tools](/de/platform/agents/tools). # Effektiv chatten Source: https://tale.dev/docs/de/tutorials/member/chat-effectively Effektives Chatten in Tale dreht sich nicht um clevere Prompts; es dreht sich darum, dem Assistenten genug mitzugeben, damit er deine Absicht beim ersten Lesen erfasst — und zu wissen, welche Arbeit gar nicht in einen Chat gehört. Fünf kleine Gewohnheiten — fragen statt beauftragen, das passende Modell wählen, Wissen füttern statt einfügen, den Denkverlauf lesen, die Quellen prüfen — drehen die durchschnittliche Antwort von „danke für die Textwand" zu „genau, was ich brauchte". Diese Seite geht die Gewohnheiten der Reihe nach in einem frischen Chat durch. Du brauchst eine Mitglied-Rolle — das Minimum für Chat. Die Konzeptseite ist [Chat-Grundlagen](/de/platform/chat/basics); dieser Spaziergang ist die Alltagsmechanik. ## Gewohnheit 1 — Fragen statt beauftragen Chat beantwortet Fragen und holt Material heran. Arbeitsergebnisse produziert er bewusst nicht — bitte um eine Präsentation, ein übersetztes Dokument oder einen Bericht, und der Assistent skizziert die Kurzfassung und verweist dich stattdessen auf eine Aufgabe. Arbeite mit dieser Grenze statt gegen sie: Ertappst du dich bei „erstell", „generier die Datei" oder „übersetz dieses Dokument", geh zu einer Aufgabe und weis sie einem Agent zu — du bekommst Verantwortliche, ein prüfbares Ergebnis und ein Erledigt, das ein Mensch kontrolliert. Einen eingefügten Satz zu übersetzen ist Chat-Arbeit; eine Datei zu übersetzen ist Aufgaben-Arbeit. ## Gewohnheit 2 — Lass Auto arbeiten; nagle fest, wenn du es besser weißt Der Picker startet auf **Auto**: Er liest jede Nachricht und sucht ihr ein passendes Modell — der schnelle Lookup landet auf einem flotten Modell, die lange Reasoning-Frage auf einem starken, und die Nachrichtendetails nennen, welches geantwortet hat. Für die meisten Tage ist das der richtige Standard. Nagle ein Modell aus der Liste fest, wenn du etwas weißt, was Auto nicht wissen kann: Dieselbe Serie soll durchgehend ein Modell beantworten, genau ein Modell steht auf dem Prüfstand, oder du willst den Denkaufwand-Regler — den zweiten Abschnitt des Pickers, der bei einem festgenagelten Modell mit Regler erscheint. Dreh ihn für knifflige Fragen hoch, rechne auf der obersten Stufe mit langsameren, teureren Antworten — und gib die Auswahl an Auto zurück, wenn die Serie durch ist. ## Gewohnheit 3 — Wissen füttern statt Textwände einfügen Der Assistent durchsucht das Wissen der Organisation — Dokumente, Wissenseinträge, gecrawlte Websites, Produkte, Kontakte — und lädt den Volltext seiner Funde. Das funktioniert nur mit Material, das wirklich da ist: Lad die Preisliste oder das Richtlinien-Dokument einmal unter [Wissen](/de/platform/knowledge/documents) hoch, und jeder künftige Chat kann sie finden und belegen. Ein 200-Seiten-Dokument ins Nachrichtenfeld einzufügen füllt das Kontext-Budget und verdünnt die Antwort; eine spezifische Frage gegen hochgeladenes Material („was sagt die Rückgaberichtlinie zu geöffneten Kartons?") schlägt „erzähl mir alles über Rückerstattungen" jedes Mal. ## Gewohnheit 4 — Den Denkverlauf lesen, nicht nur die Antwort Über jeder Antwort hält der Denkverlauf fest, was der Assistent getan hat: eine einklappbare Denkzeile und eine Schrittzeile pro Suche oder Seitenabruf — _Durchsucht die Wissensdatenbank nach "…"_, _Liest example.com_. Wirf einen Blick darauf, bevor du der Antwort traust. Eine Antwort ohne Suchschritt hinter einer Tatsachenbehauptung kam aus dem eigenen Wissen des Modells; ein Suchschritt, der nichts findet, sagt dir, was fehlt — auch dann, wenn eine ganze Quelle nicht verfügbar ist, etwa Dokumente, die erst durchsuchbar werden, sobald ein Admin ein Embedding-Modell konfiguriert. Im Denkverlauf steht auch, warum ein Abruf gescheitert ist, statt dass die Antwort still darum herumarbeitet. ## Gewohnheit 5 — Die Quellen prüfen, bevor du die Zusammenfassung weitergibst Unter einer Antwort, die etwas gelesen hat, listet **Quellen** genau die Seiten und Dokumente, die der Assistent geladen hat — abgeleitet aus dem, was wirklich lief; eine leere Liste heißt also: nichts gelesen. Öffne eine, bevor du auf die Antwort hin handelst: Die Zwei-Minuten-Gewohnheit, pro Antwort eine Quelle zu bestätigen, fängt die kleine Teilmenge ab, in der die Zusammenfassung über das Ziel hinausschoss. Eine Web-Quelle öffnet die Live-Seite in einem neuen Tab; eine Dokument-Quelle benennt die Datei, die du unter Wissen findest. ## Wo das eingesetzt wird Fünf Gewohnheiten, ein Chat, dieselbe Schleife bei jedem Öffnen des Chat-Tabs. Die Gewohnheiten verstärken sich — wer innerhalb der Chat-Grenze fragt, hält die Antworten knapp; gefüttertes Wissen lässt die Suchen treffen; Denkverlauf und Quellen schließen die Vertrauensschleife. Für die Oberfläche, auf der diese Gewohnheiten leben, siehe [Chat-Grundlagen](/de/platform/chat/basics). Für die Datei-Seite — was der Assistent durchsuchen und belegen kann — siehe [Wissen](/de/platform/knowledge/overview). # Projekte nutzen, um Dateien und Chats zu bündeln Source: https://tale.dev/docs/de/tutorials/member/use-projects Ein Projekt ist das, wozu du greifst, wenn du dich zum zweiten Mal beim Einkopieren desselben Kontexts in einen Chat ertappst. Es bündelt Dateien, Instruktionen und Chats rund um eine Arbeitssache — einen Kontakt, einen Launch, eine lange Untersuchung — damit jede neue Konversation mit bereits geladenem Kontext beginnt. Dieser Spaziergang führt ein frisches Projekt von „ich lade immer dasselbe Briefing erneut hoch" zu „jeder Chat in diesem Projekt kennt das Briefing schon" auf einer Instanz. Du brauchst eine Member-Rolle (das Minimum, um Projekte zu erstellen) und drei oder vier Dateien, auf die du immer wieder verweist. Die konzeptuelle Seite lebt in [Projekt-Konzepte](/de/platform/projects/concepts); dieser Spaziergang ist der End-to-End-Mechanismus. ## Bevor du beginnst Bestätige zwei Dinge. Deine Rolle ist mindestens Member — das Anlegen von Projekten ist auf Member und höher begrenzt. Du hast drei bis vier Dateien, die in deinen bisherigen Chats wiederkehren — ein Briefing, ein Transkript, eine Preisliste, eine Richtlinie. Die werden zum Arbeits-Set des Projekts. ## Schritt 1 — Das Projekt erstellen Das Projekt ist der Behälter, in dem die restlichen Teile leben. Öffne **Projekte > Neues Projekt** und setze: - **Name** — `Acme-Account` (oder was die Arbeitssache benennt) - **Beschreibung** — ein Satz, wofür das Projekt da ist - **Mitglieder** — vorerst privat lassen; du kannst Teammitglieder ergänzen, sobald der erste Chat funktioniert Speichern. Das Projekt erscheint in der Sidebar; ein Klick öffnet eine leere Projekt-Ansicht mit Tabs für Wissen, Threads, Agenten und Instruktionen. ## Schritt 2 — Die Dateien einmalig hochladen Die Projektdateien sind für jeden Chat im Projekt sichtbar, also passiert dieser Upload einmal und zahlt sich bei jedem späteren Chat aus. Öffne den **Wissen**-Tab und zieh die drei oder vier Dateien aus den Voraussetzungen hinein. Jede Datei landet im Projekt-Speicher und indexiert sich genauso wie ein Wissensdatenbank-Dokument. Sobald der Status **Bereit** ist, erreicht jeder im Projekt gestartete Chat die Dateien. ## Schritt 3 — Projekt-Instruktionen hinzufügen Projekt-Instruktionen rahmen jeden Chat im Projekt. Sie komponieren mit den eigenen Instruktionen des Agenten: das Projekt rahmt die Arbeit, der Agent rahmt die Antwort. Öffne den **Instruktionen**-Tab und setze: `You are working on the Acme account. The contract and the call notes in the Knowledge tab are the source of truth; cite them when you make a claim. The customer's voice is conservative — drafts should not promise dates we have not confirmed.` Speichern. Jeder neue Chat im Projekt läuft jetzt mit dieser Präambel zusätzlich zu den eigenen Instruktionen des Agenten. ## Schritt 4 — Einen Chat starten und prüfen, dass der Kontext mitgeht Öffne den **Threads**-Tab und klick **Neuer Chat**. Wähl einen Agent — der Default-Assistant reicht für den ersten Lauf — und stell eine Frage, die eine der Projektdateien beantwortet (`What does the contract say about the renewal clause?`). Die Antwort sollte den Vertrag zitieren; das Zitat öffnet die Datei aus dem Wissen-Tab des Projekts, nicht aus der Org-weiten Bibliothek. Antwortet der Agent ohne Zitat, wurden die Projektdateien nicht retrieved — meist weil der gewählte Agent kein Retrieval-Tool aktiviert hat. Wechsle auf einen Agent mit aktivem RAG oder aktivier es am Assistant für den Projektgebrauch. ## Wo das eingesetzt wird Ein Projekt mit Dateien, Instruktionen und Threads ist die kleinste nützliche Einheit von geteiltem Kontext in Tale. Dieselbe Form skaliert — Mitglieder ergänzen, damit ein Team das Projekt gemeinsam bearbeitet, einen projekt-skopierten Agent ergänzen, damit die Stimme festsitzt, das Projekt archivieren, wenn die Arbeit ausgeliefert ist. Für das tiefere Modell, was ein Projekt ist und wann man danach greift, siehe [Projekt-Konzepte](/de/platform/projects/concepts). Für projekt-skopierte Agenten siehe [Projekt-Agenten](/de/platform/projects/project-agents). # Episode 5 — Automatisierungen & Freigaben Source: https://tale.dev/docs/de/tutorials/videos/automations-and-approvals Am Ende dieser Episode hast du eine Automatisierung wirklich benutzt: Du liest den installierten Triage-Workflow, bevor du ihm vertraust, erstellst eine Aufgabe und siehst zu, wie sie vor der Kamera bewertet und zugewiesen wird, verfolgst diesen Lauf in seinem Journal, öffnest den fehlgeschlagenen und gehst ihm bis zu seinem Schritt nach — und gibst eine ausgehende Kundenmail mit deinem eigenen Klick frei. Sekunden später findest du die Entscheidung im Audit-Log. Schritt für Schritt, in einem Tempo zum Mitmachen. <Video src="/videos/de/tutorials/ep5-automations/ep5-automations.de.mp4" poster="/videos/de/tutorials/ep5-automations/ep5-automations.de.webp" captions="/videos/de/tutorials/ep5-automations/ep5-automations.de.vtt" lang="de" title="Episode 5 — Automatisierungen & Freigaben" caption="Episode 5 — Automatisierungen & Freigaben (7:04, mit Untertiteln)"> </Video> ## Was die Episode zeigt | Ab | Szene | | ---- | ---------------------------------------------------------- | | 0:28 | Der Job: ein Board voller Aufgaben ohne Besitzer | | 0:51 | Der Katalog, und was dir ein Paket-Panel zeigt | | 1:59 | Den Workflow lesen: Auslöser, Bewertungsschritt, Schema | | 3:09 | Der Tester — und der ehrliche Weg zu einem echten Lauf | | 3:30 | Eine echte Aufgabe, vor der Kamera erstellt und zugewiesen | | 4:26 | Der rote Lauf, bis zu seinem Schritt untersucht | | 5:16 | Die Freigabekarte: lesen, ergänzen, absenden | | 6:08 | Die Entscheidung im Audit-Log | ## Wie es weitergeht [Automatisierungs-Konzepte](/de/platform/automations/concepts) und der [Katalog](/de/platform/automations/catalog) behandeln die Pakete; [Editor](/de/platform/automations/editor), [Auslöser](/de/platform/automations/triggers) und [Ausführungsprotokolle](/de/platform/automations/execution-logs) vertiefen das Gesehene. Zur Karte selbst: [Freigabe-Konzepte](/de/platform/approvals/concepts) und [Freigaben in Workflows](/de/platform/automations/approvals-in-workflows) — und dann bau eine mit dem Tutorial [ein Workflow mit Freigaben](/de/tutorials/editor/workflow-with-approvals). # Episode 8 — Menschen, Rollen & Teams Source: https://tale.dev/docs/de/tutorials/videos/people-roles-and-teams Episode fünf hat die Maschinen eingehegt; diese Episode die Menschen. Sie geht die Besetzung des Arbeitsbereichs und die vierstufige Rollenleiter durch, öffnet den Mitglied-hinzufügen-Dialog gerade lange genug, um ihn zu lernen, zieht die Teamgrenzen, die entscheiden, wer was liest, und schließt mit den langweiligen Leitplanken, die am meisten zählen: Zwei-Faktor und Single Sign-on. <Video src="/videos/de/tutorials/ep8-people/ep8-people.de.mp4" poster="/videos/de/tutorials/ep8-people/ep8-people.de.webp" captions="/videos/de/tutorials/ep8-people/ep8-people.de.vtt" lang="de" title="Episode 8 — Menschen, Rollen & Teams" caption="Episode 8 — Menschen, Rollen & Teams (2:35, mit Untertiteln)"> </Video> ## Was die Episode zeigt | Ab | Szene | | ---- | ------------------------------------------------------------------- | | 0:15 | Die Besetzung: fünf Personen, vier Rollen | | 0:30 | Jemanden hinzufügen — und die Rollenleiter, auf die es ankommt | | 0:57 | Rollen sind Wirkungsradius, kein Status | | 1:14 | Teams: die Wände der kleinsten Bibliothek | | 1:33 | Identitäts-Hygiene: 2FA und Enterprise-SSO | | 1:51 | Ein Prinzip, beide Seiten: Zugriff wird entworfen, nicht angenommen | ## Wie es weitergeht [Mitglieder und Rollen](/de/platform/admin/members-and-roles) ist die volle Referenz zur Leiter; [Teams](/de/platform/admin/teams) behandelt die gesehenen Grenzen. Zur Identität: [Zwei-Faktor-Authentifizierung](/de/platform/admin/two-factor-authentication) und [Enterprise-SSO](/de/platform/admin/enterprise-sso). # Episode 7 — Connectors & die Außenwelt Source: https://tale.dev/docs/de/tutorials/videos/connectors Dein Arbeitsbereich lebt nicht allein. Diese Episode geht die Türen zur Außenwelt ab und die Disziplin in jeder einzelnen: ein Connector, den du lesen kannst, bevor du ihn öffnest, die Fähigkeit, die aufleuchtet, wenn eine Connector angebunden ist, MCP-Werkzeuge mit eigenen Freigabe-Flags und ein Sandbox-Netz, das standardmäßig Nein sagt. <Video src="/videos/de/tutorials/ep7-connectors/ep7-connectors.de.mp4" poster="/videos/de/tutorials/ep7-connectors/ep7-connectors.de.webp" captions="/videos/de/tutorials/ep7-connectors/ep7-connectors.de.vtt" lang="de" title="Episode 7 — Connectors & die Außenwelt" caption="Episode 7 — Connectors & die Außenwelt (2:52, mit Untertiteln)"> </Video> ## Was die Episode zeigt | Ab | Szene | | ---- | -------------------------------------------------------------------------- | | 0:15 | Der Katalog: einmal verbinden, der ganze Arbeitsbereich leiht | | 0:34 | Die Tür lesen: Operationen und erlaubte Hosts, bevor etwas läuft | | 0:52 | Der Gewinn: Tiefenrecherche gibt es, weil Tavily angebunden ist | | 1:09 | MCP: eure eigenen Werkzeuge, den Agenten wie eingebaute serviert | | 1:27 | Freigabe-Flags pro Werkzeug — eingebaut aussehen heißt nicht vertrauen | | 1:45 | Die letzte Tür: Sandbox-Code, Egress standardmäßig zu, schließt im Zweifel | | 2:07 | Das Muster an jeder Tür | ## Wie es weitergeht Der [Connectors-Überblick](/de/platform/connectors/overview) behandelt Verbinden und Teilen; [MCP-Server](/de/platform/connectors/mcp-servers) das Protokoll und seine Freigabe-Flags. Zur Netzgrenze lies die [Run-Code-Richtlinie](/de/platform/admin/governance/run-code-policy) — und was ein angebundener Connector freischaltet, zeigen die [Automatisierungs-Konzepte](/de/platform/automations/concepts). # Video-Tutorials Source: https://tale.dev/docs/de/tutorials/videos Die Videoserie zeigt dir die Plattform so, wie ein Kollege sie dir zeigen würde: am Bildschirm, Bereich für Bereich, mit den ehrlichen Einschränkungen laut ausgesprochen. Die Episoden sind kurz — drei bis vier Minuten — und jede nimmt nebenbei ein Stück allgemeiner KI-Kompetenz mit: was Verankerung bedeutet, warum Halluzinationen entstehen, wo der Mensch in den Ablauf gehört. Jede Episodenseite trägt das Video mit Untertiteln in der Seitensprache, eine Kapitelliste und Links in die tieferen Referenzseiten. <CardGroup cols="1"> <Card title="Episode 1 — Willkommen bei Tale" icon="play" href="/de/tutorials/videos/welcome-to-tale"> Die geführte Tour: eine verankerte Frage stellen, die zitierte Datei im Wissen finden, den antwortenden Agenten kennenlernen und das Journal einer laufenden Automatisierung lesen. Gut vier Minuten. </Card> <Card title="Episode 2 — Chat, im Detail" icon="play" href="/de/tutorials/videos/chat-in-depth"> Eine echte Arbeitssitzung: dieselbe Frage ohne und mit Verankerung, ein Quellen-Check, ein begründetes Arena-Urteil und ein Briefing, das im Canvas entsteht und dort schrumpft. Gut sechs Minuten. </Card> <Card title="Episode 3 — Wissen" icon="play" href="/de/tutorials/videos/knowledge"> Arbeit in der Bibliothek: einen Eintrag anlegen und zitiert zurückhören, verstehen, was „Indexiert" bedeutet, einen Datensatz nachschlagen, die Crawler-Grenze lesen — und die Falle veralteten Wissens live erleben. Knapp sieben Minuten. </Card> <Card title="Episode 4 — Dein erster Agent" icon="play" href="/de/tutorials/videos/your-first-agent"> Ein Agent, vor der Kamera gebaut — Anweisungen, Wissensbereich, Werkzeuge, Modell — und live getestet. Fähigkeit ist Angriffsfläche: fang klein an. Gut drei Minuten. </Card> <Card title="Episode 5 — Automatisierungen & Freigaben" icon="play" href="/de/tutorials/videos/automations-and-approvals"> Nutze eine laufende Automatisierung von Anfang bis Ende: Lies den Triage-Workflow, löse mit einer vor der Kamera erstellten Aufgabe einen echten Lauf aus, untersuche den fehlgeschlagenen Lauf und gib eine ausgehende Mail selbst frei. Sieben Minuten. </Card> <Card title="Episode 6 — Projekte mit KI" icon="play" href="/de/tutorials/videos/projects-with-ai"> Das Board mitten im Flug, Dateien als begrenzter Kontext und eine vor der Kamera angelegte Aufgabe, die ein Agent sichtbar übernimmt. Die Initiative bleibt beim Menschen. Knapp drei Minuten. </Card> <Card title="Episode 7 — Connectors & die Außenwelt" icon="play" href="/de/tutorials/videos/connectors"> Connectoren zum Lesen vor dem Öffnen, MCP-Werkzeuge mit Freigabe-Flags und Egress, der im Zweifel schließt. Jede Tür bewusst geöffnet. Knapp drei Minuten. </Card> <Card title="Episode 8 — Menschen, Rollen & Teams" icon="play" href="/de/tutorials/videos/people-roles-and-teams"> Die menschliche Hälfte des Vertrauens: die Rollenleiter, Teams als Wissenswände und Identitäts-Hygiene. Zugriff wird entworfen, nicht angenommen. Gut zwei Minuten. </Card> <Card title="Episode 9 — Richtlinien, Kosten & Vertrauen" icon="play" href="/de/tutorials/videos/governance-and-trust"> Das Finale: Anbieter und Modell-Richtlinien, Leitplanken, das Audit-Protokoll, Kosten- und Qualitätsdiagramme, Residenz — und die fünf Gewohnheiten guten KI-Einsatzes. Gut drei Minuten. </Card> <Card title="Bonus — Tale für Entwickler" icon="play" href="/de/tutorials/videos/tale-for-developers"> Die Runde für die Bauenden: begrenzte Schlüssel, vier API-Türen, Webhooks und Harnesses, die im Zweifel schließen. Gut zwei Minuten. </Card> </CardGroup> ## Die Serie danach Damit ist die Serie vollständig: der Rundgang, sieben Vertiefungen und ein Entwickler-Bonus — jeweils auf Englisch, Deutsch und Französisch. Die Dokumentation rund um jede Episode geht weiter; starte dort, wo deine Rolle beginnt. # Episode 1 — Willkommen bei Tale Source: https://tale.dev/docs/de/tutorials/videos/welcome-to-tale Die Auftaktepisode geht den Arbeitsbereich Bereich für Bereich durch — in einem Tempo zum Mitschauen. Du stellst eine echte Frage, verankert in einem Firmendokument, siehst die Antwort ihre Quellen benennen und schließt dann den Kreis: die zitierte Datei im Wissen finden, den Assistenten kennenlernen, der geantwortet hat, und das Journal einer Automatisierung lesen, die die ganze Zeit lief. Jede Station zeigt ein echtes Artefakt — nichts wird behauptet, was nicht auf dem Bildschirm steht. <Video src="/videos/de/tutorials/ep1-welcome/ep1-welcome.de.mp4" poster="/videos/de/tutorials/ep1-welcome/ep1-welcome.de.webp" captions="/videos/de/tutorials/ep1-welcome/ep1-welcome.de.vtt" lang="de" title="Episode 1 — Willkommen bei Tale" caption="Episode 1 — Willkommen bei Tale (4:21, mit Untertiteln)"> </Video> ## Was die Episode zeigt | Ab | Szene | | ---- | ----------------------------------------------------------- | | 0:20 | Die Seitenleiste lesen: jede Station der Tour, eine Leiste | | 0:42 | Die erste Frage — ein Dokument als Kontext angehängt | | 1:20 | Warum Verankerung zählt (und was eine Halluzination ist) | | 1:40 | Der Kreis schließt sich: die zitierte Datei im Wissen | | 1:58 | Der Assistent — ein Agent ist KI mit Stellenprofil | | 2:21 | Automatisierungen: der Katalog und ein Journal echter Läufe | | 3:08 | Projekte: deine Leute und deine Agenten an einem Board | | 3:26 | Kontrolle: Anbieter, Datenresidenz und das Audit-Log | ## Wie es weitergeht Der [Schnellstart](/de/get-started/quickstart) baut den ersten Chat der Episode in etwa fünf Minuten in deinem eigenen Arbeitsbereich nach. Für die Konzepte in der Tiefe: [Chat](/de/platform/chat/overview), [Wissen](/de/platform/knowledge/overview), [Agenten](/de/platform/agents/concepts), [Automatisierungen](/de/platform/automations/concepts) und [Freigaben](/de/platform/approvals/concepts). # Episode 2 — Chat, im Detail Source: https://tale.dev/docs/de/tutorials/videos/chat-in-depth Episode 1 war der Rundgang; diese Episode zieht in den Raum ein, in dem dein Team wirklich arbeiten wird — und fährt eine komplette Arbeitssitzung. Das Kernstück ist ein kontrolliertes Experiment: dieselbe Onboarding-Frage, zweimal gestellt — einmal ohne Kontext, einmal mit angehängtem Q2-Support-Bericht. So siehst du zu, wie eine flüssige Antwort und eine verankerte Antwort aufhören, dasselbe zu sein. Danach wird die verankerte Antwort hinterfragt („Welches Dokument sagt das?"), ein Arena-Urteil mit Begründung gefällt — und ein Briefing landet im Canvas und schrumpft mit einem Satz auf drei Punkte. <Video src="/videos/de/tutorials/ep2-chat/ep2-chat.de.mp4" poster="/videos/de/tutorials/ep2-chat/ep2-chat.de.webp" captions="/videos/de/tutorials/ep2-chat/ep2-chat.de.vtt" lang="de" title="Episode 2 — Chat, im Detail" caption="Episode 2 — Chat, im Detail (6:25, mit Untertiteln)"> </Video> ## Was die Episode zeigt | Ab | Szene | | ---- | -------------------------------------------------------------- | | 0:30 | Die drei Entscheidungen im Eingabefeld: Agent, Modell, Kontext | | 0:53 | Das Experiment, Teil eins: fragen, ohne etwas anzuhängen | | 1:14 | Die Falle, gemeinsam gelesen — flüssig, souverän, geraten | | 1:34 | Teil zwei: dieselbe Frage, verankert in einem echten Dokument | | 2:12 | Die Antwort hinterfragen: „Welches Dokument sagt das?" | | 2:34 | Eine Antwort bewerten — wo die Feedback-Analysen beginnen | | 3:22 | Arena-Modus: zwei Modelle, ein Prompt, ein begründetes Urteil | | 4:20 | Das Canvas: ein Briefing landet als Datei und wird gekürzt | | 5:13 | Tiefenrecherche, und wo sie wohnt | ## Wie es weitergeht [Chat-Grundlagen](/de/platform/chat/basics) behandelt die Eingabezeile, die drei Abruf-Tools und den Denkverlauf in Referenztiefe. Zur Modellseite: [Modelle](/de/platform/models) und der [Arena-Modus](/de/platform/chat/arena-mode); für Arbeit, die in einem Arbeitsergebnis endet, übergibt der Chat an die [Agent-Konzepte](/de/platform/agents/concepts). # Episode 9 — Richtlinien, Kosten & Vertrauen Source: https://tale.dev/docs/de/tutorials/videos/governance-and-trust Das Finale gehört denen, die für KI in der Organisation geradestehen. Es durchquert den Kontrollraum von vorne bis hinten — welche Modelle für wen laufen, die Leitplanken, die in beide Richtungen prüfen, das Audit-Protokoll, in dem die Freigabe aus Episode fünf tatsächlich gelandet ist, die Kosten- und Qualitätsdiagramme mit den Arena-Urteilen aus Episode zwei und den Regions-Regler — und schließt die Serie mit ihren fünf Gewohnheiten: verankern, absichern, begrenzen, protokollieren, messen. <Video src="/videos/de/tutorials/ep9-governance/ep9-governance.de.mp4" poster="/videos/de/tutorials/ep9-governance/ep9-governance.de.webp" captions="/videos/de/tutorials/ep9-governance/ep9-governance.de.vtt" lang="de" title="Episode 9 — Richtlinien, Kosten & Vertrauen" caption="Episode 9 — Richtlinien, Kosten & Vertrauen (3:31, mit Untertiteln)"> </Video> ## Was die Episode zeigt | Ab | Szene | | ---- | ----------------------------------------------------------------- | | 0:21 | Anbieter: ein Gateway, eigene Schlüssel oder eigene Hardware | | 0:39 | Modell-Richtlinie: wer welches Modell nutzen darf | | 0:56 | Leitplanken: PII maskiert, Unsicheres blockiert, beide Richtungen | | 1:20 | Das Audit-Protokoll — die Freigabe aus Episode fünf, aktenkundig | | 1:43 | Nutzungsanalysen: Kosten mit Namen daran, Budgets, die warnen | | 1:59 | Feedback-Analysen: Qualität gemessen, Arena-Urteile inklusive | | 2:17 | Datenresidenz: eine Einstellung, keine Verhandlung | | 2:34 | Die fünf Gewohnheiten guten KI-Einsatzes | ## Wie es weitergeht [Anbieter](/de/platform/admin/providers) und [Modelle](/de/platform/models) behandeln die Maschinerie; [Content-Modelle](/de/platform/admin/governance/content-models) und [Richtlinien und Limits](/de/platform/admin/governance/policies-and-limits) die Richtlinien-Schicht; [Leitplanken](/de/platform/admin/governance/guardrails), [Audit-Protokolle](/de/platform/admin/governance/audit-logs), [Nutzungsanalysen](/de/platform/admin/governance/usage-analytics) und [Feedback-Analysen](/de/platform/admin/governance/feedback-analytics) die besichtigten Kontrollen. Zur Residenz: [Cloud-Datenresidenz](/de/cloud/data-residency). # Episode 4 — Dein erster Agent Source: https://tale.dev/docs/de/tutorials/videos/your-first-agent Der Chat hat dir das Fragen beigebracht, das Wissen die Grundlage der Antworten. Diese Episode baut das Ding, das beides einsetzt: einen Agenten, von Null vor der Kamera. Der rote Faden ist die Vertrauensgrenze — jedes gewährte Werkzeug erweitert, was der Agent tun kann. Der kleinste Agent, der den Job erledigt, ist der sicherste. <Video src="/videos/de/tutorials/ep4-agent/ep4-agent.de.mp4" poster="/videos/de/tutorials/ep4-agent/ep4-agent.de.webp" captions="/videos/de/tutorials/ep4-agent/ep4-agent.de.vtt" lang="de" title="Episode 4 — Dein erster Agent" caption="Episode 4 — Dein erster Agent (3:18, mit Untertiteln)"> </Video> ## Was die Episode zeigt | Ab | Szene | | ---- | ------------------------------------------------------------- | | 0:17 | Die Agentenliste — die eingebauten, und wo deiner wohnen wird | | 0:32 | Anlegen: technischer Name, Anzeigename, weiter | | 0:51 | Anweisungen — die Stellenbeschreibung samt Übergabe-Regel | | 1:12 | Wissensbereich: die kleinste Bibliothek, die den Job erledigt | | 1:29 | Werkzeuge: Fähigkeit ist Angriffsfläche — starte ohne | | 1:53 | Das Modell und sein Fallback | | 2:10 | Im Chat sichtbar, dann die erste echte Frage | | 2:32 | Mutig verbessern: die Historie behält jede Version | ## Wie es weitergeht [Agenten-Konzepte](/de/platform/agents/concepts) liefert das Denkmodell hinter den vier Entscheidungen; [Agent anlegen](/de/platform/agents/create) den Referenz-Durchgang. Vertiefe jede Stellschraube mit [Werkzeugen](/de/platform/agents/tools), [Wissen](/de/platform/agents/knowledge) und [Versionen](/de/platform/agents/versions) — und folge dann dem Redaktions-Tutorial [vom ersten Agenten bis zur Produktion](/de/tutorials/editor/first-agent-end-to-end). # Episode 3 — Wissen Source: https://tale.dev/docs/de/tutorials/videos/knowledge Die verankerten Antworten aus Episode 2 kamen alle aus einem Ort — in dieser Episode arbeitest du darin. Du legst einen echten Fakt als Wissenseintrag an, lernst, was „Indexiert" wirklich bedeutet (und warum Indexieren kein Training ist), schlägst einen Preis in einem typisierten Datensatz nach, liest das Scan-Intervall des Crawlers, öffnest den Schalter, der ein Dokument auf ein Team begrenzt — und triffst dann den Fehler, der dich wirklich erwartet: keinen fehlenden Fakt, sondern einen veralteten. Am Ende zitiert ein frischer Chat den Eintrag, den du Minuten zuvor angelegt hast. <Video src="/videos/de/tutorials/ep3-knowledge/ep3-knowledge.de.mp4" poster="/videos/de/tutorials/ep3-knowledge/ep3-knowledge.de.webp" captions="/videos/de/tutorials/ep3-knowledge/ep3-knowledge.de.vtt" lang="de" title="Episode 3 — Wissen" caption="Episode 3 — Wissen (6:46, mit Untertiteln)"> </Video> ## Was die Episode zeigt | Ab | Szene | | ---- | ------------------------------------------------------------------- | | 0:32 | Die Karte: Dokumente, Einträge, Websites, Produkte — eine Tab-Zeile | | 1:04 | Eintrag, Dokument oder Datensatz — die richtige Form wählen | | 1:33 | Ein Wissenseintrag, live angelegt: Thema, Inhalt, speichern | | 1:59 | Was „Indexiert" bedeutet — Abruf zur Antwortzeit, kein Training | | 2:32 | Ein echter Blick in einen typisierten Datensatz | | 3:05 | Der Crawler: eine Domain, ein Scan-Intervall, eine ehrliche Grenze | | 3:44 | Wer liest was: ein Dokument einem Team zugewiesen | | 4:22 | Die Falle des veralteten Wissens, live gefragt | | 5:22 | Der Beweis: ein frischer Chat zitiert deinen neuen Eintrag | ## Wie es weitergeht Der [Wissens-Überblick](/de/platform/knowledge/overview) kartiert die ganze Bibliothek; [Dokumente](/de/platform/knowledge/documents) behandelt die Indexierung, [Wissenseinträge](/de/platform/knowledge/knowledge-entries) die gepflegten Fakten, [strukturierte Daten](/de/platform/knowledge/structured-data) die typisierten Datensätze und [Crawling](/de/platform/knowledge/crawling) die Websites. Zu den Zugriffsschaltern: [Agenten-Wissen](/de/platform/agents/knowledge). # Episode 6 — Projekte mit KI Source: https://tale.dev/docs/de/tutorials/videos/projects-with-ai Im Chat fragst du; in Projekten wohnt die Arbeit. Diese Episode geht durch das Relaunch-Projekt, das das Team wirklich betreibt — und legt dann vor der Kamera eine Aufgabe an, ganz normal, damit du zusehen kannst, wie die Triage sie bewertet und ein Agent sie übernimmt. Das Backlog schließt den Kreis: Agenten schlagen vor, Menschen befördern. <Video src="/videos/de/tutorials/ep6-projects/ep6-projects.de.mp4" poster="/videos/de/tutorials/ep6-projects/ep6-projects.de.webp" captions="/videos/de/tutorials/ep6-projects/ep6-projects.de.vtt" lang="de" title="Episode 6 — Projekte mit KI" caption="Episode 6 — Projekte mit KI (2:47, mit Untertiteln)"> </Video> ## Was die Episode zeigt | Ab | Szene | | ---- | ---------------------------------------------------------------------- | | 0:16 | Das Relaunch-Board mitten im Flug — Avatare zeigen, wer was hält | | 0:33 | Projektdateien: das Regal, das Agenten zuerst lesen | | 0:48 | Diskussionen wohnen neben der Arbeit | | 1:04 | Eine Aufgabe, ganz normal angelegt | | 1:21 | Der Agent übernimmt: bewertet, zugewiesen, die Begründung im Kommentar | | 1:43 | Das Backlog: Agenten schlagen vor, ein Mensch befördert | | 2:01 | Jedes Projekt besetzt seine eigene Crew aus Agenten und Modellen | ## Wie es weitergeht [Projekt-Konzepte](/de/platform/projects/concepts) und der [Überblick](/de/platform/projects/overview) kartieren die Oberfläche; [Aufgaben-Automatisierung](/de/platform/projects/task-automation) erklärt die Bewerten-Zuweisen-Berichten-Schleife von eben, [Backlog](/de/platform/projects/backlog) den Vorschlagsfluss und [Projekt-Agenten](/de/platform/projects/project-agents) die Crew pro Projekt. # Bonus — Tale für Entwickler Source: https://tale.dev/docs/de/tutorials/videos/tale-for-developers Alles, was die Serie gezeigt hat, trägt eine API darunter. Die Bonus-Episode geht die Entwickler-Oberfläche ab: benannte, widerrufbare API-Schlüssel; REST, MCP, WebDAV und Sandbox-Runtimes; Webhooks, die Agenten aus jedem System auslösen; die Harnesses — Claude Code, Cursor — in isolierten Containern; und die Run-Code-Richtlinie, die benennt, was installiert werden darf und wohin Code sich verbinden darf. Starke Werkzeuge, eingehegter Wirkungsradius. <Video src="/videos/de/tutorials/ep10-developers/ep10-developers.de.mp4" poster="/videos/de/tutorials/ep10-developers/ep10-developers.de.webp" captions="/videos/de/tutorials/ep10-developers/ep10-developers.de.vtt" lang="de" title="Bonus — Tale für Entwickler" caption="Bonus — Tale für Entwickler (2:38, mit Untertiteln)"> </Video> ## Was die Episode zeigt | Ab | Szene | | ---- | ----------------------------------------------------------- | | 0:18 | API-Schlüssel: benannt, begrenzt, widerrufbar, auditiert | | 0:36 | Vier Türen: REST, MCP, WebDAV, Sandbox-Runtimes | | 0:56 | Webhooks: jedes System kann einen Agenten auslösen | | 1:16 | Harnesses: Claude Code, Cursor und Kollegen | | 1:37 | Die Run-Code-Richtlinie: Pakete, Hosts, schließt im Zweifel | | 1:59 | Starke Werkzeuge, eingehegter Wirkungsradius | ## Wie es weitergeht Der [Develop-Überblick](/de/develop/overview) kartiert die ganze Oberfläche; die [API-Referenz](/de/develop/api-reference) und [Webhooks](/de/develop/webhooks) tragen die Verträge. Zu Harness-Zügen: [Harnesses](/de/platform/agents/harnesses) und die [Run-Code-Richtlinie](/de/platform/admin/governance/run-code-policy). # Einen Agent mit Wissen bauen Source: https://tale.dev/docs/de/tutorials/editor/agent-with-knowledge Ein Agent mit Wissen ist die Form, zu der du greifst, wenn das Modell aus bestimmten Dokumenten antworten soll — deinem Produkt-Handbuch, deinen Richtlinien, den Call-Notizen des letzten Quartals — und nicht aus dem, was es im Training gelernt hat. Der Agent holt zur Antwortzeit Chunks aus den gebundenen Quellen und zitiert sie. Dieser Spaziergang führt einen frischen Agent von „ich will, dass er meine Docs kennt" zu „die Antwort zitiert das richtige Dokument" auf einer Instanz. Du brauchst eine Editor-Rolle, die Fähigkeit, Dokumente in die Wissensdatenbank hochzuladen, und etwa drei zu bindende Dokumente. Die konzeptuelle Seite lebt in [Agent-Wissen](/de/platform/agents/knowledge); dieser Spaziergang ist der End-to-End-Mechanismus. ## Bevor du beginnst Bestätige drei Dinge. Deine Rolle ist mindestens Editor — die Agent-Bearbeitung ist auf Editor und höher begrenzt. Du hast mindestens drei Dokumente zum Hochladen bereit (PDFs, DOCX, Markdown — alles, was die Wissensdatenbank akzeptiert). Du hast einen Anbieter konfiguriert, damit der Agent laufen kann — ohne diesen scheitert die Test-Antwort am Ende beim Modell-Call. ## Schritt 1 — Dokumente in die Wissensdatenbank hochladen Der erste Zug ist, die Dokumente in Tales Wissensdatenbank zu legen. Dokumente ausserhalb der Wissensdatenbank lassen sich nicht binden; der Agent sieht nur Quellen, die er benennen kann. Öffne **Wissen > Dokumente** und klick **Hochladen**. Zieh die drei Dokumente hinein, gib ihnen sinnvolle Titel und warte, bis die Status-Spalte für jedes **Bereit** zeigt. Der Status durchläuft `hochgeladen → wird verarbeitet → bereit`; die Verarbeitung chunkt das Dokument und berechnet Embeddings. Ein typisches PDF erreicht **Bereit** in ein, zwei Minuten. Bleibt ein Dokument länger als fünf Minuten auf `wird verarbeitet`, öffne seine Zeile, um den Fehler zu sehen — die häufigste Ursache ist ein nicht unterstütztes Format (reine Bild-PDFs, passwortgeschützte Dateien) oder eine Datei grösser als das Upload-Limit der Org. ## Schritt 2 — Den Agent erstellen Ein gebundenes Dokument hängt an einem Agent, also muss der Agent zuerst existieren. Öffne **Agenten > Neuer Agent** und füll die vier Knöpfe als Basis aus: - **Name** — `Docs Q&A` - **Instruktionen** — `You answer questions strictly from the bound documents. If you cannot find the answer in the documents, say so explicitly. Cite the document title for every claim.` - **Tools** — **RAG** einschalten; alles andere aus - **Modell** — was immer die Org als Default nutzt Speichern und veröffentlichen. Der Agent existiert nun, hat aber kein Wissen — er wird jede Frage verweigern, weil er keine Quelle findet. ## Schritt 3 — Die Dokumente binden Die Bindung ist die Naht, die dem Agent Retrieval-Zugriff auf eine Teilmenge der Wissensdatenbank gibt. Öffne den Tab **Wissen** des Agenten und klick **Agent-Wissen**. Wähl die drei Dokumente aus Schritt 1 und speicher. Der Wissen-Tab listet jetzt drei gebundene Quellen. Das RAG-Tool des Agenten holt nur aus diesen drei; nichts anderes in der Wissensdatenbank ist von diesem Agent aus erreichbar, auch keine anderen Dokumente in derselben Bibliothek. ## Schritt 4 — Eine Frage stellen und das Zitat prüfen Öffne einen Chat mit `Docs Q&A` und stell eine Frage, die eines der Dokumente beantwortet. Die Antwort streamt mit inline gesetzten Zitaten herein — Hovern zeigt den Dokument-Titel, Klicken öffnet das Dokument am zitierten Chunk. Stell eine Frage, die keines der Dokumente abdeckt; der Agent sollte gemäss Instruktion explizit verweigern und keine Antwort erfinden. Erfindet der Agent trotzdem eine Antwort, sind die Instruktionen nicht streng genug — füg einen expliziten Verweigerungs-Fall hinzu („If you cannot find the answer in the bound documents, respond with exactly: 'I could not find this in the bound documents.'") und veröffentliche erneut. ## Wo das eingesetzt wird Die vier Züge oben sind der kanonische „Agent, der aus deinen Docs antwortet"-Bau: hochladen, Agent mit aktivem RAG erstellen, binden, mit einem Zitat verifizieren. Dieselbe Form skaliert — bind zehn Dokumente statt drei, füg eine Website oder einen Kunden-Datensatz hinzu, wechsle das Modell. Die Bindungen, nicht das Modell, machen den Agent zu deinem. Für die konzeptuelle Seite, wie Retrieval mit den anderen Knöpfen des Agenten zusammenspielt, siehe [Agent-Konzepte](/de/platform/agents/concepts). Für die breitere Wissensdatenbank-Geschichte — Kontakte, Produkte, Anbieter, Websites — siehe [Wissens-Überblick](/de/platform/knowledge/overview). # Arbeit an einen Worker geben Source: https://tale.dev/docs/de/tutorials/editor/delegate-between-agents Wenn eine Anfrage ihren eigenen fokussierten Kontext verdient — zitierte Recherche, Massen-Extraktion, ein langer Entwurf — startet der Assistent einen **Worker**: einen flüchtigen Agenten, zusammengestellt für genau diese Aufgabe, mit genau den Fähigkeiten, die der Assistent ihm aus seinem eigenen Satz mitgibt. Es gibt nichts zu konfigurieren; dieser Durchlauf fährt einen Recherche-Job von Anfang bis Ende und zeigt dir, wie du die Job-Karte liest. Die konzeptionelle Seite (Fähigkeits-Teilmengen, Budgets, Methodiken) steht in [Agent-Worker](/platform/agents/delegation). ## Bevor du beginnst Du brauchst einen chatfähigen Agenten (der eingebaute Assistent funktioniert direkt) auf einem Modell mit Tool-Calling. Für Live-Webquellen verbinde eine Such-Connector wie Tavily unter **Einstellungen > Connectors** — ohne sie fällt der Worker auf einfaches Web-Abrufen zurück und sagt das in seinem Ergebnis. ## Schritt 1 — Frag nach etwas, das einen Worker verdient Öffne einen Chat mit `Assistent` und bitte um offene, zitierbare Arbeit, zum Beispiel: `Recherchiere den Stand von Feststoffbatterien — Markt, wichtigste Akteure, zitierte Quellen.` Eine schnelle Faktenfrage startet keinen Worker (und sollte es auch nicht); Worker sind für Aufgaben, die von Isolation profitieren. ## Schritt 2 — Beobachte die Job-Karte Der Assistent ruft `spawn_agent` auf, und unter seinem Zug erscheint eine **Job-Karte**: der Name des Workers, ein Live-Status und die eigene Fortschritts-Checkliste des Workers, die sich füllt, während er plant und die Teilfragen abarbeitet. Die Karte blockiert nie den Eingabebereich — du kannst weitertippen, während der Worker läuft. Zeigt die Karte einen „Übersprungen“-Hinweis, hat der Assistent etwas außerhalb seiner eigenen Freigaben angefragt (etwa eine nicht verbundene Connector); der Lauf geht mit dem Rest weiter, und der Hinweis sagt dir, was du fürs nächste Mal verbinden solltest. ## Schritt 3 — Lies Ergebnis und Protokoll Ist der Job fertig, faltet der Assistent das Ergebnis des Workers in seine Antwort — bei Recherche ein Fazit, Kernpunkte mit Inline-Zitaten und Quellen. Klappe auf der Karte **Worker-Aktivität** auf, um das vollständige Protokoll zu sehen: jede Suche, jeden Tool-Aufruf und die Überlegungen des Workers. Dieses Protokoll ist der Audit-Trail, auf den du zeigst, wenn jemand fragt, was der Agent tatsächlich getan hat. ## Schritt 4 — Wenn etwas schiefgeht Ein Worker, dem die Zeit ausgeht oder der auf einen Fehler stößt, endet mit sichtbarem Status auf der Karte — `Zeit abgelaufen` oder `Fehlgeschlagen` — mit intaktem Teilfortschritt. Der Assistent berichtet, was er bekommen hat, und macht selbst weiter, wo er kann. Nichts scheitert still: Brauchte der Worker eine Eingabe, die nur du geben kannst, fragt dich der Assistent direkt. ## Wo das hingehört Eine Anfrage, ein Worker, eine Karte ist die kleinste nützliche Form. Dieselbe Mechanik skaliert auf mehrere Worker in einem Zug — jeder bekommt seine eigene Karte, seinen eigenen Fortschritt und sein eigenes Protokoll. Für feste Stufen mit Freigaben oder Zeitplänen dazwischen greif stattdessen zu einem [Workflow](/de/platform/automations/concepts). # Deinen ersten Agent bauen Source: https://tale.dev/docs/de/tutorials/editor/first-agent-end-to-end Ein erster Agent ist das kleinste nützliche Ding in Tale: Instruktionen plus Modell, manchmal mit einem Tool oder einem gebundenen Dokument. Dieser Spaziergang dreht die vier Knöpfe der Reihe nach — Instruktionen, Wissen, Tools, Modell — und hinterlässt dir einen veröffentlichten Agent, der aus einer echten Aufgabe ein prüfbares Ergebnis macht. Die Form verallgemeinert sich: jeder spätere Agent ist dieselben vier Züge mit anderen Entscheidungen. Du brauchst eine Editor-Rolle und ein konfiguriertes Chat-getaggtes Modell beim Anbieter der Org. Die konzeptuelle Seite lebt in [Agent-Konzepte](/de/platform/agents/concepts); dieser Spaziergang ist der End-to-End-Mechanismus. ## Bevor du beginnst Bestätige drei Dinge. Deine Rolle ist mindestens Editor — die Agent-Bearbeitung ist auf Editor und höher begrenzt. Die Org hat einen Anbieter konfiguriert und mindestens ein Chat-getaggtes Modell darauf; ohne das scheitert die Test-Antwort am Ende beim Modell-Call. Du hast eine Frage im Kopf, die der Agent beantworten soll — wähl etwas eng genug, dass ein Absatz Instruktionen sie rahmen kann, etwa „fass eine eingehende Kontaktnachricht in einen Satz plus eine empfohlene nächste Aktion zusammen". ## Schritt 1 — Die Instruktionen schreiben Instruktionen sind der System-Prompt — die Prosa, die jede Antwort rahmt. Der erste Knopf ist der, bei dem die meisten überdrehen. Öffne **Agenten > Neuer Agent** und setze: - **Name** — `Triage assistant` - **Instruktionen** — `You read a contact message and produce two lines. Line one: a one-sentence summary in plain English. Line two: a recommended next action — reply, escalate, or close. If the message is blank or off-topic, refuse and say so.` Speicher vorerst als Entwurf; veröffentlichen kommt nach den anderen Knöpfen. Kurze, meinungsstarke, konkrete Instruktionen schlagen lange — halt die Regeln unter einem Absatz. ## Schritt 2 — Über das Wissen entscheiden Wissen ist das, worauf der Agent zur Antwortzeit zurückgreifen kann. Lass Wissen für diesen ersten Agent leer: die Aufgabe ist, die Nachricht zu lesen, nicht etwas zu holen. Der Wissen-Tab bleibt unangetastet. Wolltest du später Wissen ergänzen — etwa eine Eskalations-Matrix, die der Agent konsultieren soll — würdest du das Dokument hochladen, den **Wissen**-Tab des Agenten öffnen und es binden. Der ganze Mechanismus liegt in [Agent mit Wissen](/de/tutorials/editor/agent-with-knowledge). ## Schritt 3 — Die Tools wählen Tools sind das, was der Agent jenseits von Text-Antworten tun kann. Für Triage brauchst du keine Tools: der Agent liest Input und schreibt Output. Öffne den Tab **Tools** und lass jeden Schalter aus. Jedes Tool, das du gewährst, erweitert die Vertrauensgrenze; halt die Liste kurz. Soll der Agent die empfohlene Aktion in ein CRM zurückschreiben, würdest du später den entsprechenden Connector-Tool-Schalter aktivieren — aber nicht, bevor die reine Text-Variante funktioniert. ## Schritt 4 — Modell wählen und veröffentlichen Öffne den Tab **Modell** und wähl als primäres den Org-Default; setz ein kleineres Modell als Fallback, damit der Agent läuft, wenn das primäre rate-limited ist. Speicher, dann klick **Veröffentlichen**. Der Agent steht nun jedem Projekt und jeder Automatisierung mit passender Rolle zur Verfügung — der Chat selbst führt nur den eingebauten Assistenten aus. Erstell eine Aufgabe, füg eine echte Kontaktnachricht in ihre Beschreibung ein und weis sie dem `Triage assistant` zu. Das Ergebnis des Laufs sollte gemäß den Instruktionen in zwei Zeilen landen — Ein-Satz-Zusammenfassung und empfohlene Aktion. Driftet das Format ab, zieh die Instruktionen straffer und veröffentliche neu; das ist die Schleife, in der du am meisten Zeit verbringst. ## Wo das eingesetzt wird Vier Knöpfe, ein veröffentlichter Agent, eine verifizierte Antwort: dieselbe Form, der jeder später gebaute Agent folgt. Die nächsten Spaziergänge spezialisieren sich auf je einen Knopf — [Agent mit Wissen](/de/tutorials/editor/agent-with-knowledge) auf den zweiten, [Arbeit an einen Worker geben](/de/tutorials/editor/delegate-between-agents) auf den dritten. Für die Konzept-Seite, die die vier Knöpfe und ihre Trade-offs benennt, siehe [Agent-Konzepte](/de/platform/agents/concepts). Für Versionierung und Rollback, sobald der Agent reift, siehe [Agent-Versionen](/de/platform/agents/versions). # Einen Workflow mit Freigabe bauen Source: https://tale.dev/docs/de/tutorials/editor/workflow-with-approvals Ein Workflow mit einer menschlichen Entscheidung in der Mitte ist die Form, zu der du greifst, wenn die Arbeit aus Entwurf, Review und Aktion besteht — und du eine Person zwischen Entwurf und Aktion willst. Der Lauf pausiert als **Wartet auf Eingabe**, bis jemand antwortet; der nächste Schritt feuert nur bei grünem Licht. Dieser Spaziergang baut so einen Daily-Summary-Workflow, und unterwegs begegnest du beiden menschlichen Toren: dem Genehmigen des KI-Editor-Vorschlags und dem Beantworten des pausierten Laufs. Du brauchst eine Editor-Rolle und einen Agent, der einen Entwurf produziert (der erste nützliche Agent aus [Deinen ersten Agent bauen](/de/tutorials/editor/first-agent-end-to-end) reicht). Die konzeptuelle Seite lebt in [Automatisierungskonzepte](/de/platform/automations/concepts) und [Genehmigungs-Konzepte](/de/platform/approvals/concepts); dieser Spaziergang ist der End-to-End-Mechanismus. ## Bevor du anfängst Prüf drei Dinge. Deine Rolle ist mindestens Editor — Workflow-Bearbeitung ist ab Editor aufwärts freigeschaltet. Du hast einen Entwurfs-Agent bereit; ohne ihn hat der Entwurfs-Schritt nichts aufzurufen. Und du kannst das Review selbst beantworten — der pausierte Lauf wartet auf einen Menschen, und in diesem Spaziergang bist du das. ## Schritt 1 — Einen Workflow im Editor öffnen Workflows leben in der Automatisierung, die sie antreiben: Öffne die Automatisierung, und ihr Tab **Editor** ist der Workflow, mit dem Schritt-Graphen auf der Leinwand. Öffne für diesen Spaziergang einen Workflow, der dir gehört, oder einen aus dem Task-Ops-Paket deiner Org — alles funktioniert, was du bearbeiten darfst, denn die neue Definition baut ohnehin der KI-Editor für dich. ## Schritt 2 — Dem KI-Editor den Workflow beschreiben Schalte den **KI-Editor** in der Leinwand-Werkzeugleiste ein und beschreib die ganze Form in einer Nachricht: > Lass jeden Werktag um 08:00 den Agent <dein Agent> die ungelesenen Kontaktnachrichten von gestern in einen Absatz zusammenfassen, dann einen Menschen den Entwurf prüfen, und schick nur den freigegebenen Text an den Team-Kanal. Der KI-Editor antwortet mit einer Vorschlagskarte — **Workflow erstellen** mit der Schrittzahl, oder **Workflow aktualisieren**, wenn er den geöffneten umbaut. Solange die Karte aussteht, passiert an der Definition nichts: Klapp sie auf, prüf die gelisteten Schritte — ein **LLM**-Schritt für den Entwurf, die Review-Pause, der Versand — und genehmige sie. Die Änderung wird angewendet und versioniert wie jedes manuelle Speichern. ## Schritt 3 — Den Zeitplan anhängen Wechsle zum Tab **Trigger** und klick **Zeitplan hinzufügen**. Nimm die Vorlage **Täglich** und pass den Cron auf Werktage an (`0 8 * * 1-5`) — oder beschreib die Zeit in Alltagssprache und klick **Generieren**, damit die KI den Cron schreibt. **Workflow-Variablen** füllt sich aus dem Eingabeschema des Workflows vor; lass es wie vorgeschlagen. Die Zeile erscheint mit bereits eingeschaltetem **Aktiv**-Schalter. ## Schritt 4 — Laufen lassen und das Review beantworten Zurück im Editor: Öffne **Workflow testen**, füg das vorgeschlagene Eingabe-JSON ein und klick **Ausführen**. Das Panel spiegelt den Lauf Schritt für Schritt: Der Entwurfs-Schritt feuert, dann pausiert der Lauf — **Wartet auf Eingabe** — und das Review kommt als Formular-Karte mit dem Entwurf an. Füll sie aus und klick **Antwort absenden**, um freizugeben, oder **Anders antworten**, um im Freitext zurückzugeben; der Lauf setzt mit deiner Antwort fort und der Versand-Schritt feuert. Öffne den Tab **Ausführungen** und klapp den Lauf auf: Das Journal zeigt einen Eintrag pro Schritt — den Entwurf des Agents, wer das Review beantwortet hat und wie, und den Versand mit seiner Ausgabe. Dieses Journal ist der Audit-Trail; derselbe Datensatz entsteht für jeden künftigen geplanten Lauf. ## Wo das hinführt Entwerfen, entscheiden, handeln — mit der Entscheidung bei einem Menschen — ist der kleinste nützliche Workflow mit Freigabe, und du hast ihn gebaut, ohne einen einzigen Schritt von Hand zu setzen: Der KI-Editor hat vorgeschlagen, du hast genehmigt, der Lauf hat gefragt, du hast geantwortet. Dieselbe Form skaliert — häng ein zweites Review vor einen destruktiven Schritt, oder lass dir von [Genehmigungen in Workflows](/de/platform/automations/approvals-in-workflows) die übrigen Tore rund um einen Workflow zeigen. Für das Vokabular hinter Definition, Trigger und Ausführung ist [Automatisierungskonzepte](/de/platform/automations/concepts) die Seite, die dieser Spaziergang vorausgesetzt hat. # Das Outlook-Add-in installieren Source: https://tale.dev/docs/de/tutorials/admin/office-add-in Das Outlook-Add-in blendet eine Tale-Sidebar in Outlook im Web, auf dem Desktop und mobil ein. Aus der Sidebar wählt ein Mitglied einen Agent, lässt den offenen Mail-Thread als Kontext einfliessen und bekommt einen Antwort-Draft zurück, ohne die App zu wechseln. Dieser Spaziergang richtet sich an einen Admin, der das Add-in organisationsweit ausrollt; er deckt den Manifest-Deploy, das Anmelden und die Verifikation ab. Du brauchst die Admin-Rolle in Tale, einen Microsoft-365-Tenant, in dem du Integrated Apps verwaltest, und eine Tale-Instanz, die aus der Microsoft-365-Cloud erreichbar ist. Cloud-Orgs sind standardmässig erreichbar; selbst gehostete Instanzen brauchen eine öffentliche HTTPS-URL. ## Bevor du beginnst Bestätige drei Dinge auf der Microsoft-Seite: du bist Global Administrator (oder hast die Exchange-Admin-Rolle mit Integrated Apps), die zentrale Bereitstellung ist für deinen Tenant aktiviert, und das Test-Postfach hat Add-ins nicht über eine Mailbox-Policy gesperrt. Auf der Tale-Seite öffne **Einstellungen > Connectors** und prüfe, dass **Microsoft 365** gelistet ist — dort veröffentlicht das Add-in die Manifest-URL. ## Schritt 1 — Die Manifest-URL aus Tale holen Das Add-in spricht mit Tale über ein Manifest-XML, das das Microsoft-365-Admin-Center hostet. Tale generiert das Manifest pro Instanz, damit die Sidebar auf deine URL zeigt und nicht auf einen geteilten Multi-Tenant-Endpunkt. Öffne **Einstellungen > Connectors > Microsoft 365** und kopier die **Add-in-Manifest-URL**, die das Panel zeigt. Du solltest eine URL sehen, die auf `/connectors/office/manifest.xml` endet. Öffne sie in einem neuen Tab, um zu bestätigen, dass sie XML zurückgibt und keine HTML-Fehlerseite — bricht das ab, ist deine Instanz von aussen nicht erreichbar oder die Connector ist deaktiviert. ## Schritt 2 — Übers Microsoft-365-Admin-Center ausrollen Das Manifest sagt Microsoft 365, welche Postfächer die Sidebar sehen dürfen und von welcher URL sie geladen wird. Zentrale Bereitstellung ist der unterstützte Pfad; das Side-Loading pro Nutzer funktioniert, übersteht aber keine Postfach-Migration. Öffne das Microsoft-365-Admin-Center, navigiere zu **Einstellungen > Integrierte Apps > Eigene Apps hochladen**, wähl **Office-Add-in** und **Link zur Manifest-Datei bereitstellen** und füg die URL aus Schritt 1 ein. Wähl die Rollout-Zielgruppe — den ganzen Tenant, eine Sicherheitsgruppe oder eine konkrete Nutzerliste. Senden. Microsoft bestätigt den Deploy mit einem grünen Banner; der Rollout erreicht Postfächer typischerweise innerhalb einer Stunde, bei grossen Tenants auch ein paar Stunden später. ## Schritt 3 — Aus der Sidebar anmelden Öffne Outlook als Nutzer in der Rollout-Zielgruppe, klick eine beliebige Mail an und such das Tale-Icon im Nachrichten-Ribbon. Ein Klick öffnet die Sidebar; beim ersten Öffnen verlangt sie eine Anmeldung mit dem Tale-Konto. Die Anmeldung läuft per OAuth über die Tale-Instanz — derselbe Identity-Anbieter wie in der Web-App. Nach der Anmeldung listet die Sidebar die für den Nutzer verfügbaren Agenten. Einen auswählen und **Antwort entwerfen** klicken zieht den offenen Mail-Thread als Kontext heran und streamt eine Antwort in die Sidebar. Der Nutzer prüft, bearbeitet und klickt **Einfügen**, um sie ins Outlook-Kompositionsfenster zu droppen. ## Wo das eingesetzt wird Das Add-in ist der leichteste Weg zu „Tale dort, wo deine Mitglieder ohnehin arbeiten" — kein Portal-Wechsel, kein Copy-Paste. Die Sidebar ist eine dünne Hülle um dieselben Agenten, die du in [Agent erstellen](/de/platform/agents/create) veröffentlichst; Änderungen an Instruktionen, Wissen oder Tools eines Agenten landen mit der nächsten Anfrage in der Sidebar. Für die breitere Connector-Story — Slack, Gmail, eigene MCP-Server — siehe [Connectors-Überblick](/de/platform/connectors/overview). Betreibst du eine selbst gehostete Instanz und ist die Manifest-URL aus Microsoft 365 nicht erreichbar, deckt die Seite [Linux-Server](/de/self-hosted/install/linux-server) die Voraussetzung „öffentliches HTTPS" ab. # Meeting-Transkripte in die Wissensdatenbank pipen Source: https://tale.dev/docs/de/tutorials/admin/meeting-transcription Ein Meeting-Transkript ist eines der wertvollsten Dokumente, die ein Projekt führen kann — Namen, Entscheidungen, Follow-ups, alles an einem durchsuchbaren Ort. Dieser Walk integriert Meetily, ein lokales Meeting-Transkriptions-Tool, mit einem Tale-Projekt, damit jedes Transkript, das Meetily erzeugt, in der Wissensdatenbank des Projekts als Dokument von selbst landet. Der Walk richtet sich an einen Admin auf einer selbst gehosteten Tale-Instanz, der sie mit einem Meetily-Install im selben Netzwerk paart. Du brauchst die Admin-Rolle in Tale, einen Meetily-Install, der vom `tale-platform`-Container erreichbar ist, und ein Projekt in Tale mit einer Wissensdatenbank, in die die Transkripte geroutet werden. Das Wissensdatenbank-Konzept lebt unter [Wissensdatenbank](/de/platform/knowledge/overview); diese Seite ist der Connector-Walk, nicht die Konzept-Seite. ## Bevor du beginnst Bestätige vier Dinge. Deine Rolle ist Admin oder Inhaber in Tale — das **Connectors**-Panel ist darunter versteckt. Meetily läuft und produziert Transkripte in einem Format, das Tale akzeptiert (Markdown, Klartext oder VTT). Der Meetily-Host ist von `tale-platform` über seinen Webhook- oder Shared-Folder-Pfad erreichbar. Und das Zielprojekt existiert in Tale bereits mit einer angehängten Wissensdatenbank — die Connector schreibt _in_ eine Wissensdatenbank, sie erstellt keine. ## Schritt 1 — Den Auslieferungspfad wählen Meetily kann Transkripte in zwei Formen an Tale übergeben, und sie haben unterschiedliche operative Eigenschaften. Die Wahl legt fest, wie der Rest des Walks zu lesen ist. Der **Webhook**-Pfad lässt Meetily jedes fertige Transkript an einen Tale-Ingest-Endpunkt POSTen, sobald das Meeting endet; das Transkript ist Sekunden nach Schließen des Meetings in der Wissensdatenbank. Der **Shared-Folder**-Pfad lässt Meetily Transkripte als Dateien in ein Verzeichnis schreiben, das die Tale-Plattform jede Minute pollt; die Latenz beträgt bis zu eine Minute, aber der Pfad braucht keine öffentliche URL und übersteht Meetily-Neustarts ohne Retry-Logik. Wähl Webhook, wenn beide Dienste im selben Netzwerk laufen und du schnelles Indizieren willst; wähl Shared Folder, wenn Meetily auf einer Workstation läuft, die unregelmäßig aufwacht, oder wenn das Operations-Team einen dateibasierten Audit-Trail bevorzugt. ## Schritt 2 — Den Ingest-Endpunkt oder Ordner in Tale erstellen Tale muss wissen, wo Transkripte landen werden und zu welchem Projekt sie gehören. Ohne diese Bindung kommen Transkripte an, aber keine Wissensdatenbank beansprucht sie. Öffne **Einstellungen > Connectors**, klick **Connector hinzufügen** und wähl **Meeting-Transkripte**. Wähl das Projekt aus dem Dropdown — die Wissensdatenbank, die das Projekt nutzt, ist das Ziel. Wähl den Auslieferungspfad, den du in Schritt 1 gewählt hast. Hast du Webhook gewählt, generiert Tale eine URL der Form `https://<dein-host>/connectors/transcripts/<token>` und zeigt sie einmal. Kopier die URL; sie funktioniert auch als Bearer-Credential, also behandle sie wie ein Geheimnis. Hast du Shared Folder gewählt, fragt Tale nach dem Pfad auf der Disk, den `tale-platform` beobachten soll (typisch `/data/transcripts/<project-slug>`). Erstell das Verzeichnis auf dem Host, gib ihm Gruppen-Eigentum, das dem `tale-platform`-Container-User entspricht, und bestätig. ## Schritt 3 — Meetily auf Tale zeigen lassen Meetily muss jetzt wissen, wohin jedes Transkript zu liefern ist. Die Einstellungen leben in der eigenen Config von Meetily. Für den Webhook-Pfad öffnest du die Einstellungen von Meetily und fügst ein Webhook-Ziel mit der URL aus Schritt 2 hinzu. Wähl das Transkript-Format — Markdown ist das, was sich in einer Tale-Dokument-Vorschau am besten liest, aber VTT und Klartext werden beide korrekt indiziert. Für den Shared-Folder-Pfad setz das Transkript-Ausgabe-Verzeichnis von Meetily auf den Pfad, den du in Schritt 2 erstellt hast. Stell sicher, dass Meetily eine Datei pro Meeting schreibt, benannt nach Meeting-Titel und Zeitstempel. Beende ein kurzes Test-Meeting in Meetily und beobachte das Tale-Connectors-Panel. Die Connector-Zeile zeigt einen **Letzte Auslieferung**-Zeitstempel, der innerhalb einer Minute (Folder-Modus) oder weniger Sekunden (Webhook-Modus) aktualisiert. ## Schritt 4 — Verifizieren, dass das Dokument landet und indiziert Der Beweis, dass die Verdrahtung funktioniert, ist ein Transkript, das in der Wissensdatenbank als durchsuchbares Dokument sichtbar ist. Ohne diesen Schritt weißt du nicht, ob Tale die Datei empfangen _und_ indiziert hat. Öffne das Zielprojekt, navigiere zu seiner Wissensdatenbank und such das neue Transkript oben in der Dokumentenliste. Klick in die Vorschau — das Transkript rendert als Dokument mit dem Meeting-Titel als Dokumentnamen und dem Meeting-Datum als Created-at. Wart, bis das Indizier-Badge sich klärt (wenige Sekunden für ein kurzes Transkript, bis zu eine Minute für ein langes), dann lauf eine Suche nach einem Namen oder einer Phrase, die du aus dem Test-Meeting erinnerst. Das Transkript sollte das erste Ergebnis mit der hervorgehobenen Phrase sein. Liegt das Dokument vor, bleibt das Indizier-Badge aber orange, ist die Indexierung im Rückstand — die Seite [Troubleshooting](/de/self-hosted/operate/observability/troubleshooting) nennt die Symptome. ## Vertrauensgrenze Die Connector überquert in jede Richtung ein Netzwerk und die Datenform zählt. - **Meetily → Tale.** Der Transkript-Body geht rüber, plus Meeting-Titel, Zeitstempel und alle Sprecher-Labels, die Meetily angehängt hat. Audio geht nicht rüber — Meetily transkribiert lokal und nur der Text wird ausgeliefert. Der Webhook-Pfad nutzt HTTPS mit dem Bearer-Token in der URL; der Folder-Pfad nutzt einen Dateisystem-Pfad ohne Netzwerk überhaupt. - **Tale → Meetily.** Nichts. Die Connector ist einseitig; Tale ruft nie zurück in Meetily. - **Tale → externe Dienste.** Der Transkript-Text geht zu dem Embedding-Anbieter, der an die Wissensdatenbank gebunden ist. Ist der Embedding-Anbieter ein lokaler (Ollama, LM Studio, vLLM über [Einen lokalen LLM-Anbieter anbinden](/de/tutorials/admin/connect-local-provider)), verlässt kein Transkript-Text den Host. Ist der Embedding-Anbieter OpenAI, Anthropic oder ein anderer gehosteter Endpunkt, wird der Transkript-Text gemäß der Daten-Handhabungs-Policy dieses Anbieters zur Vektorisierung dorthin geschickt. Enthalten Transkripte Inhalte, die die Org nicht an einen Cloud-Anbieter senden kann, ist das unterstützte Pattern, die Wissensdatenbank des Projekts an ein lokales Embedding-Modell zu binden. Die Anbieter-Bindung passiert in den Wissensdatenbank-Einstellungen, nicht in dieser Connector. ## Wo das hingehört Die Meeting-Transkriptions-Connector ist das sauberste Beispiel für „Tale indiziert, was deine anderen Tools schon produzieren" — kein Copy-Paste, kein manueller Upload, kein zusätzlicher Schritt im Meeting-Workflow. Die natürlichen nächsten Lesungen sind [Wissensdatenbank](/de/platform/knowledge/overview) dafür, wofür das indizierte Transkript dann in einem Agent verwendet werden kann, und [Einen lokalen LLM-Anbieter anbinden](/de/tutorials/admin/connect-local-provider), wenn der Abschnitt oben dich dazu drängt, den Embedding-Schritt auf dem Host zu behalten. # Einen lokalen LLM-Anbieter anbinden Source: https://tale.dev/docs/de/tutorials/admin/connect-local-provider Ein lokaler Anbieter ist der Weg, Modelle im eigenen Perimeter laufen zu lassen — keine ausgehenden API-Aufrufe, keine Rechnung pro Token, kein Transkript bei Dritten. Dieser Durchlauf bringt eine selbst gehostete Tale-Instanz von „ich habe einen Ollama-, LM-Studio- oder vLLM-Endpunkt“ zu „ein Chat in der Organisation ruft ein lokales Modell auf und die Antwort streamt zurück“. Der Durchlauf ist für Admins einer selbst gehosteten Installation; Cloud-Organisationen greifen nicht in dein Netzwerk und überspringen diese Seite. Du brauchst die Admin-Rolle in Tale, einen lokalen Inferenz-Server, den der `tale-platform`-Container über TLS erreicht, und ein bereits geladenes Modell auf diesem Server. Das Connector-Format und das Zugangsdaten-Modell stehen in [Anbieter](/de/self-hosted/configuration/providers); diese Seite geht einen vollständigen Weg ab und verifiziert das Ergebnis. ## Bevor du beginnst Prüf vier Dinge. Deine Rolle ist Admin oder Inhaber — **Einstellungen > KI-Anbieter** ist darunter ausgeblendet. Dein lokaler Inferenz-Server beantwortet `GET /v1/models` (oder das Ollama-Pendant `GET /api/tags`) aus dem Tale-Docker-Netz heraus. Mindestens ein Modell ist geladen — Ollama-Nutzer haben `ollama pull llama3.1:8b` oder Ähnliches laufen lassen, LM-Studio-Nutzer haben im Server-Tab ein Modell geladen, vLLM-Nutzer haben den Server mit `--model` auf einen Checkpoint gestartet. Und der Server ist über `https://` erreichbar: Die Base-URL eines Connectors muss eine HTTPS-URL sein, also terminiere TLS vor dem Inferenz-Server — ein Reverse-Proxy mit internem Zertifikat ist die übliche Antwort — statt ihn im Klartext freizulegen. ## Schritt 1 — Den Inferenz-Server aus Tale erreichbar machen Der erste Zug ist die Bestätigung, dass `tale-platform` den Inferenz-Server per Hostname über TLS erreicht. Ohne das quittiert jeder Modellaufruf einen Verbindungsfehler und kein Modell ist aufrufbar. Läuft der Inferenz-Server hinter einem Proxy im selben Docker-Netz, ist der erreichbare Hostname der Service-Name dieses Proxys. Setz ein einmaliges curl aus dem `tale-platform`-Container ab, bevor du irgendeine Konfiguration schreibst: ```bash docker compose exec platform curl -sf https://ollama.internal/api/tags ``` Eine JSON-Liste geladener Modelle ist das Erfolgssignal. Ein Verbindungsfehler heißt: falscher Hostname, nicht vertrauenswürdiges Zertifikat, oder der Inferenz-Server lauscht nicht auf der Schnittstelle, die der Container erreicht. ## Schritt 2 — Den Connector deklarieren Die mitgelieferten Connectors decken die öffentlichen Anbieter ab; eine Maschine in deinem eigenen Netz ist ein selbst definierter Connector — eine YAML-Datei im Config-Baum der Organisation. Die Datei sagt Tale, wohin Anfragen gehen, welchen Wire-Dialekt der Endpunkt spricht und woher seine Modellliste kommt. Schreib `$TALE_CONFIG_DIR/<orgSlug>/providers/local-ollama.yml`. Der `name` muss dem Dateinamen-Stamm entsprechen und darf mit keinem mitgelieferten Connector kollidieren: ```yaml name: local-ollama displayName: Local Ollama apiFormat: openai baseUrl: https://ollama.internal/v1 catalog: source: models-endpoint auth: - method: api-key - method: env ``` `apiFormat: openai` passt für Ollama, LM Studio und vLLM — alle drei sprechen die OpenAI-Chat-Completions-Form. `catalog.source: models-endpoint` weist Tale an, Modelle über `GET {baseUrl}/models` zu listen statt eine statische Liste mitzubringen; genau das willst du, wenn sich die geladenen Modelle ändern. Eine Datei, die nicht validiert, wird übersprungen und der Grund geloggt — lies also das Plattform-Log, wenn der Connector nicht auftaucht. ## Schritt 3 — Die Zugangsdaten hinterlegen Ein Connector allein ruft nichts auf. Was eine Anfrage autorisiert, sind Zugangsdaten an diesem Connector, und ein Connector hält so viele, wie du brauchst. Öffne **Einstellungen > KI-Anbieter**. Der neue Connector steht neben den mitgelieferten; klicke dort auf **Zugangsdaten hinzufügen**. Wähl **API-Schlüssel** und füg das Token ein, das dein Server erwartet — LM Studio ignoriert den Wert, vLLM will das Token, das du an `--api-key` übergeben hast. Benenne den Eintrag nach der Maschine, die er erreicht (`GPU-Kiste, Rack 2`), und lass die **Modell-Allowlist** leer, um alles freizugeben, was der Server listet, oder wähl die Teilmenge, die die Organisation aufrufen darf. Der erste Eintrag an einem Connector wird sein Standard. Soll der Schlüssel lieber auf dem Deployment liegen? Wähl **Umgebungsvariable** und benenne eine Deployment-Variable unter dem reservierten Präfix `TALE_PROVIDER_KEY_`. Das Geheimnis landet dann nie in Tales eigenem Speicher, und dein Betriebsteam besitzt die Rotation. ## Schritt 4 — Mit einem Chat verifizieren Der Beweis, dass die Verdrahtung sitzt, ist eine gestreamte Chat-Antwort vom lokalen Server. Ohne diesen Schritt weißt du nur, dass die Konfiguration parst. Öffne einen neuen Chat, öffne die Modell-Auswahl und wähl eines der lokalen Modelle namentlich — lass die Auswahl nicht auf **Auto** stehen, das diese Nachricht womöglich zu einem anderen Anbieter lenkt; dieser Schritt braucht die Antwort von genau der Maschine, auf die du schaust. Sende einen kurzen Prompt (`Antworte nur mit dem Wort "bereit"`). Die Antwort streamt binnen Sekunden herein. Verfolg dabei das Log des Inferenz-Servers auf dem Host — Ollama loggt die Request-Zeile, LM Studio druckt eine Request-Zusammenfassung, vLLM die Generierungslatenz. Die Anfrage auf dem lokalen Server auflaufen zu sehen ist die Verifikation, dass der Verkehr in deinem Netz bleibt statt über eine externe API zu springen. ## Troubleshooting - **Symptom:** Der Connector taucht unter **Einstellungen > KI-Anbieter** nie auf. **Ursache:** Das YAML validiert nicht, oder sein `name` entspricht nicht dem Dateinamen-Stamm. **Behebung:** Lies das Plattform-Log — ein abgelehnter Connector wird mit Datei und Grund geloggt — und korrigier die Datei. - **Symptom:** Der Connector erscheint, seine Modellliste bleibt leer. **Ursache:** Der Inferenz-Server ist erreichbar, hat aber kein Modell geladen, oder sein `/models`-Endpunkt hat einen Fehler geantwortet. **Behebung:** Lad ein Modell und klicke dann auf der Anbieter-Seite auf **Kataloge aktualisieren**. Kataloge aktualisieren sich nur, wenn du sie aktualisierst. - **Symptom:** Die Datei wird abgelehnt, weil die Base-URL kein HTTPS ist oder auf `localhost`, `127.0.0.1` oder eine private IP zeigt. **Ursache:** Connector-Base-URLs sind HTTPS-only, und die Host-Policy blockt Loopback- und private Adressen. **Behebung:** Stell einen TLS-terminierenden Reverse-Proxy vor den Inferenz-Server und nimm dessen internen Hostnamen. - **Symptom:** Die Chat-Antwort ist ein Fehler, der das Modell nennt. **Ursache:** Die Modell-ID passt nicht zur Upstream-ID. **Behebung:** Wähl in der Modell-Auswahl neu — Ollama-Tags wie `:latest` zählen upstream und müssen exakt stimmen. ## Wo das hingehört Ein lokaler Anbieter ist die Naht zwischen Tale und deinen eigenen GPUs — dieselbe Connector-und-Zugangsdaten-Form wie bei einem öffentlichen Anbieter, aber kein Verkehr verlässt dein Netz. Die natürlichen nächsten Lektüren sind [Anbieter](/de/self-hosted/configuration/providers) für das Connector-Format in voller Länge und den Weg über Umgebungsvariablen, und [Härtung](/de/self-hosted/operate/security/hardening) für die Egress-Garantien, die einen Agent davon abhalten, ein Cloud-Modell zu erreichen, das du nicht vorgesehen hast. # Tutorials Source: https://tale.dev/docs/de/tutorials/overview Tutorials sind Walkthroughs von Anfang bis Ende: Jedes bringt eine frische Instanz von „Ich möchte X tun" zu einem funktionierenden, verifizierten Ergebnis. Vorausgesetzt werden die passende Rolle und ein laufender Arbeitsbereich; die Konzept-Seiten unter [Plattform](/de/platform) erklären das mentale Modell, die Tutorials zeigen den Mechanismus von vorne bis hinten. Bist du noch keinen [Einstieg](/de/get-started/quickstart) durchgegangen, fang dort an — die Tutorials bauen auf den Handgriffen des ersten Tages auf, die dort abgedeckt sind. ## Wähl nach Rolle <CardGroup cols="2"> <Card title="Videoserie" icon="play" href="/de/tutorials/videos"> Produzierte Rundgänge durch die ganze Plattform — Verankerung, Agenten, Automatisierungen, Richtlinien — je drei Minuten, in drei Sprachen. </Card> <Card title="Mitglieder-Tutorials" icon="message-circle" href="/de/tutorials/member/chat-effectively"> Effektiv chatten, in Projekten arbeiten, Sprach-Konversationen führen. </Card> <Card title="Redakteurs-Tutorials" icon="bot" href="/de/tutorials/editor/first-agent-end-to-end"> Einen ersten Agent von Anfang bis Ende bauen, Wissen anbinden, zwischen Agents delegieren, Workflows mit Genehmigungen ausliefern. </Card> <Card title="Entwickler-Tutorials" icon="terminal" href="/de/tutorials/developer/call-tale-from-a-script"> Tale aus einem Skript aufrufen, Workflows per Webhook auslösen, eigene Tools bauen, einen MCP-Server aufsetzen. </Card> <Card title="Verwaltungs-Tutorials" icon="shield" href="/de/tutorials/admin/office-add-in"> Das Office-Add-in installieren, Meeting-Transkription verdrahten, einen lokalen Anbieter verbinden. </Card> </CardGroup> ## Wo das hingehört Tutorials zitieren die Feature-Referenzen unter [Plattform](/de/platform) für das konzeptuelle Gerüst; sobald du eines durchgegangen bist, lohnt sich die zugehörige Konzept-Seite als zweite Lektüre. Weißt du nicht, welches Tutorial du wählen sollst: [Deinen ersten Agent bauen](/de/tutorials/editor/first-agent-end-to-end) ist das, was einem „Hallo Welt" für das Produkt am nächsten kommt — die meisten Produktfähigkeiten, die du später anfasst, tauchen dort schon auf. # Mode Arène Source: https://tale.dev/docs/fr/platform/chat/arena-mode Le Mode Arène exécute le même prompt contre deux modèles à la fois et te demande quelle réponse est la meilleure. Le verdict alimente l’analyse des retours de l’organisation ; avec le temps, les données disent quel modèle l’équipe préfère vraiment pour quel type de question, indépendamment du ressenti de chacun. Va vers l’Arène quand le choix d’un modèle a été un débat plutôt qu’une décision — comparer des réponses côte à côte casse l’impasse avec des preuves plutôt qu’avec des opinions. Pour le travail ordinaire, le sélecteur de modèles classique suffit ; la valeur de l’Arène, ce sont les verdicts qu’elle produit, pas la vue de comparaison elle-même. ## Comment l’Arène s’affiche Ouvre le menu plus du chat et choisis **Mode Arène** — le chat fait pousser deux sélecteurs de modèles étiquetés **Modèle A** et **Modèle B**. Envoyer un message exécute les deux modèles en parallèle ; l’écran se sépare et chaque réponse arrive en streaming dans sa propre colonne. Une fois les deux terminées, une rangée de verdict apparaît sous les colonnes avec quatre boutons : **A est meilleur**, **B est meilleur**, **Égalité**, **Les deux sont mauvais**. <Frame caption="Le même prompt traité par deux modèles, avec la rangée de verdict en dessous."> ![Le Mode Arène avec un prompt de checklist de lancement traité dans deux colonnes — à gauche, Claude Haiku 4.5 rend une liste numérotée de cinq étapes, à droite, Claude Sonnet 4.6 regroupe le même travail sous des titres et ajoute les risques à signaler — au-dessus des boutons de verdict A est meilleur, B est meilleur, Égalité et Les deux sont mauvais.](/images/platform/chat-arena-split.webp) </Frame> <Note> Les deux colonnes tournent avec le même agent — choisis l’agent qui t’intéresse avant d’activer l’Arène. La comparaison ne dit quelque chose que si les instructions, les tools et la connaissance sont identiques de part et d’autre. </Note> ## Choisir les concurrents Les deux sélecteurs sont indépendants — n’importe quel modèle que la politique de l’agent autorise est valable de chaque côté. Choisir le même modèle des deux côtés est permis (utile pour tester des différences de température si l’agent expose ça), mais la plupart des comparaisons traversent fournisseurs ou tailles. Les instructions, les connaissances et les tools de l’agent s’appliquent aux deux colonnes ; seul le modèle sous-jacent diffère. ## Émettre un verdict Le verdict se donne en un clic. **A est meilleur** et **B est meilleur** parlent d’eux-mêmes ; **Égalité** sert quand les deux réponses se valent à peu près ; **Les deux sont mauvais** quand aucune n’est acceptable. Le bouton que tu cliques enregistre le verdict et résout le chat sur la colonne gagnante — le message suivant que tu envoies ne va qu’à ce modèle. **Égalité** ou **Les deux sont mauvais** laissent les deux colonnes actives pour un tour de plus. ## Où les verdicts apparaissent Les verdicts remontent dans l’[Analyse des retours](/fr/platform/admin/governance/feedback-analytics) sous **Verdicts d'arène**, à côté d’un tableau **Top duels de modèles** qui classe les paires par taux de victoire. Les données sont à l’échelle de l’organisation plutôt que par utilisateur : une poignée de verdicts délibérés peut donc peser plus lourd qu’un gros tas d’habitudes quand quelqu’un lit le tableau pour décider vers quel modèle l’équipe devrait aller. ## Quand y recourir | Utilise … quand | Mode Arène | Sélecteur classique | | ----------------------------------------------------------------------- | ---------- | ------------------- | | Tu décides quel modèle mettre par défaut | ✓ | | | Tu soupçonnes une régression de modèle après une mise à niveau | ✓ | | | Tu sais déjà quel modèle tu veux ; tu veux juste une réponse maintenant | | ✓ | | La requête est courte et ordinaire | | ✓ | ## Où ça s’inscrit L’Arène est la boucle de retour légère par-dessus le choix de modèle. La surface lourde est l’[Analyse des retours](/fr/platform/admin/governance/feedback-analytics) — c’est là que les verdicts que tu émets deviennent un graphique avec lequel quelqu’un argumentera plus tard sur les défauts. Si c’est toi qui liras le graphique, fais une poignée de tours d’Arène avant de le lire ; les verdicts que tu émets toi-même te diront si le cadrage du tableau correspond à ton expérience. # Bases du chat Source: https://tale.dev/docs/fr/platform/chat/basics Cette page est le modèle mental de tout l’onglet Chat. Elle nomme les parties de la zone de saisie, suit un message de la frappe jusqu’à la réponse en streaming, dit exactement ce que le modèle reçoit et ce qu’il a le droit d’appeler en chemin, et montre comment lire ce qui est revenu. Lis-la une fois et les autres pages du chat se liront comme des variations du même parcours. <Frame caption="L’onglet Chat avec une réponse en streaming au-dessus de la zone de saisie."> ![Un fil de chat montrant une question d’utilisateur sur des retours d’onboarding et une réponse de l’assistant contenant un tableau markdown de trois thèmes.](/images/platform/chat-thread-reply.webp) </Frame> ## La zone de saisie La zone de saisie est la bande en bas de l’écran. Le champ de message envoie sur **Entrée** et va à la ligne sur **Maj+Entrée**. Un seul sélecteur, à côté du menu `+`, porte le choix du modèle — **Auto**, le défaut, laisse Tale choisir un modèle par message, ou tu en nommes un — et, pour un modèle nommé qui l’expose, l’effort de raisonnement. C’est là, à dessein, tout l’éventail des choix : pas de sélecteur d’agent, pas de sélecteur de skills, aucun contrôle sur l’endroit où le tour s’exécute. Le menu `+` porte **Ajouter photos et fichiers** et, quand un chat peut l’accueillir, le **Mode Arène** ([Mode Arène](/fr/platform/chat/arena-mode)) ; **Lire les réponses à voix haute** ([Mode vocal](/fr/platform/chat/voice-mode)) est l’interrupteur haut-parleur à côté du micro, et le micro dicte dans le champ. Pendant qu’une réponse arrive en streaming, le bouton d’envoi devient un bouton d’arrêt. Arrêter garde tout ce qui a déjà été diffusé — la réponse reste telle quelle, au milieu d’une phrase si c’est là qu’elle en était. ### Pièces jointes Glisse des fichiers depuis ton bureau n’importe où sur la zone de saisie — un bandeau dit **Dépose les fichiers ici pour téléverser** pendant le survol —, colle une capture d’écran directement dans le champ de message, ou choisis des fichiers via **Ajouter photos et fichiers** dans le menu `+`. Le chat accepte les images, les documents (PDF, Office, OpenDocument, CSV), les fichiers texte et l’audio/vidéo. Chaque image se pose en petite miniature au-dessus du champ : un clic l’agrandit, son ✕ la retire. Le reste se pose en puce nommée qui suit son traitement : le modèle de transcription de ton organisation transforme l’audio et la vidéo en texte, et les documents sont indexés pour la récupération. L’envoi n’attend jamais une barre de progression — un message envoyé pendant que des fichiers se traitent encore se gare au-dessus de la zone de saisie et part tout seul dès que tout est prêt ; son ✕ abandonne l’envoi en attente et remet le texte dans le champ. Jusqu’à dix fichiers voyagent avec un message. Colle un lien vidéo (YouTube, Vimeo, Bilibili et compagnie) et il devient une puce lui aussi : Tale récupère les sous-titres en arrière-plan — ou extrait et transcrit la piste audio quand il n’y en a pas — et la transcription voyage avec ton message comme un enregistrement téléversé. Seule une puce vidéo en échec retient l’envoi, parce que l’attendre ne finirait jamais : relance-la ou retire-la, tout le reste se met en file. Un modèle qui sait voir les images reçoit les pixels eux-mêmes, au fil de tes mots ; pour un modèle qui ne le sait pas, la zone de saisie le dit dès l’attache — ce modèle ne verrait que les noms de fichier. L’audio n’atteint jamais le modèle de chat en octets : le modèle reçoit la transcription en texte, tandis que ta bulle garde les mots que tu as tapés (et la puce audio). Le contenu d’un document parvient à l’assistant par ses outils de connaissances — le tour lui nomme les fichiers joints et il les lit avec `rag_fetch` ; attends-toi donc à une étape de récupération avant la réponse. Un format sans extracteur de texte (anciens fichiers Office comme `.doc`) s’attache quand même, mais l’assistant n’en voit que le nom — et le dit au lieu de deviner. Les documents déposés ici restent privés dans cette conversation — ils ne rejoignent jamais la [Base de connaissances](/fr/platform/knowledge/overview) de l’organisation, et aucun autre chat ni collègue ne peut les récupérer. Les fichiers attachés appartiennent au chat où tu les as posés (changer de chat les efface), et régénérer une réponse renvoie les mêmes pièces jointes — transcriptions et accès aux documents sont reconstruits pour le modèle depuis les fichiers stockés. Le travail qui produit des fichiers revient à une tâche. Parler dans le micro est un autre chemin — voir [Mode vocal](/fr/platform/chat/voice-mode). <Frame caption="La zone de saisie : le champ de message, le sélecteur de modèle et d’effort, la dictée, l’envoi."> ![La zone de saisie du chat avec son menu plus, le sélecteur de modèle affichant Auto, le bouton micro et le bouton d’envoi.](/images/platform/chat-composer.webp) </Frame> ## Choisir un modèle Le sélecteur s’ouvre sur **Auto** : pour chaque message, Tale lit ce que tu as écrit — longueur, code, sujet — et lui choisit un modèle dans la même liste que montre le sélecteur : un modèle léger pour la question rapide, un modèle fort pour le terrain difficile ou sensible. Un document joint relève le plancher : un message qui porte un fichier à lire ne part jamais sur le modèle le plus léger, aussi courte que soit la question. Aucune seconde IA ne tranche (c’est une heuristique toute simple sur le message), et il n’y a jamais de bascule silencieuse : le modèle qui commence ta réponse est celui qui la termine, et les détails du message le nomment. Dès qu’un message porte des images, seuls les modèles capables de les voir entrent en jeu ; si aucun ne le peut, l’envoi le dit au lieu de deviner. Tu préfères décider ? Choisis un modèle dans la liste — le sélecteur liste les modèles pour lesquels l’organisation détient un identifiant actif et directement utilisable ; un modèle qui ne pourrait tourner que dans l’outillage propre d’un fournisseur n’est pas proposé ici. Un choix nommé reste le tien jusqu’à ce que tu le rendes à Auto, et l’un comme l’autre reste le défaut de tes prochains chats. Auto n’apparaît que s’il y a un vrai choix à faire — avec un seul modèle utilisable, le sélecteur le nomme, tout simplement. Pour les modèles à profondeur de raisonnement réglable, la deuxième section du sélecteur fixe l’effort. Ce choix accompagne la conversation — chaque tour suivant tourne au niveau que tu as posé, et les modèles sans ce réglage l’ignorent. Laissé sur **Par défaut**, un modèle qui sait répondre sans raisonnement étendu répond ainsi — pose un niveau quand tu veux qu’il réfléchisse plus longtemps. Sur Auto, la section d’effort reste hors du menu : l’intensité de réflexion va de pair avec _quel_ modèle tourne — épingle-en un pour la régler. ## Ce que le modèle reçoit Le prompt est assemblé dans un ordre fixe, et la liste est courte par choix : les instructions obligatoires de l’organisation, le guide intégré de l’assistant, les règles de traitement des contenus non fiables, une courte ligne de documentation par outil, puis l’horodatage courant avec la consigne de langue de réponse, et enfin l’historique complet des messages — chaque appel d’outil et son résultat compris, exactement comme ils se sont produits. Rien d’autre ne s’y ajoute. Pas de bloc de personnalisation, pas de mémoires glissées dans ton dos, pas de récupération automatique de connaissances, pas de contexte web automatique. Tout ce que le modèle apprend au-delà de ses instructions, il l’apprend en appelant un outil — l’appel apparaît donc dans la transcription, attribuable et refusable. <Info> Quand la conversation dépasse la fenêtre de contexte du modèle, les messages les plus anciens sont retirés et un avis visible prend leur place. Ils ne sont pas résumés : un résumé serait un second appel de modèle capable d’inventer l’historique qu’il devait préserver, alors que retirer des messages perd de l’information d’une façon que tu peux voir. </Info> ## Les trois outils L’assistant porte exactement trois outils, tous tournés vers la récupération et tous en lecture seule — c’est la frontière qui fait du chat une conversation plutôt qu’un établi. | Outil | Ce qu’il atteint | | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `rag_search` | Les connaissances de l’organisation : documents, entrées de connaissances, pages de sites web explorés, produits et contacts | | `rag_fetch` | Le texte intégral derrière une référence — un document joint ou trouvé par son identifiant de fichier, ou une page explorée par son URL | | `web_fetch` | Une page web publique, récupérée en direct — l’étape au-delà des connaissances de l’organisation ; le contenu déjà exploré passe par `rag_fetch` | Une recherche est honnête sur ce qu’elle a couvert : le résultat nomme chaque source interrogée et dit lesquelles étaient indisponibles — une organisation sans modèle d’embedding configuré reçoit par exemple « les documents et les pages explorées ne peuvent pas encore être cherchés » plutôt qu’une liste vide et muette, et l’assistant relaie ce constat au lieu de deviner autour. Il n’y a délibérément rien d’autre — pas d’exécution de code, pas d’écriture de fichiers, pas de connectors, pas de sous-agents. Ces capacités vivent sur les tâches et dans les automatisations, là où existent un responsable, une étape de relecture et une piste d’audit à leur mesure. ## Demander un livrable Demande à l’assistant une présentation, un document traduit ou n’importe quel autre artefact : il n’en bâtira pas une moitié dans le fil. Il te donne la version courte si elle est utile, puis te dit de créer une tâche et de l’assigner à un agent. Une tâche a un responsable, produit un résultat à relire, et seule une personne la marque Terminé — rien de tout cela n’est à la portée d’une réponse de chat. Traduire une phrase que tu as collée est un travail de chat ; traduire un fichier est un travail de tâche. ## Lire la réponse La réponse arrive en streaming à mesure qu’elle se génère. Au-dessus d’elle, le déroulé de réflexion consigne ce que l’assistant a fait, dans l’ordre : - Une ligne repliable **« A réfléchi pendant _n_ s »** porte le raisonnement du modèle — clique pour déplier la prose. - Chaque appel d’outil est une ligne d’étape — _Recherche dans la base de connaissances pour « … »_, _Lecture de example.com_ — avec un indicateur d’activité pendant qu’il tourne et, quand il échoue, un avertissement qui en donne la raison. Les étapes restent visibles quand le raisonnement est replié ; elles sont la trace de ce que l’assistant est allé chercher. Sous la réponse, **Sources** liste les pages et les documents que l’assistant a réellement chargés — la liste dérive des résultats d’outils, pas de la prose, si bien qu’une carte de source ne revendique jamais une lecture qui n’a pas eu lieu. Les sources web s’ouvrent dans un nouvel onglet. La barre d’outils sous une réponse posée copie le texte, montre les comptes de tokens et les durées (**Envoyer → premiers mots** depuis Envoyer ; **Début → fin** et **Début → premier token** depuis le démarrage de la réponse sur le serveur), recueille un avis pouce levé ou baissé, et duplique le chat — une copie visible de la conversation jusque-là, poursuivie comme un chat à part entière. ## Conversations versus chats Dans Chat, l’unité est un **chat** — c’est le mot qu’emploient tous les boutons et toutes les notifications. Le modèle de données derrière s’appelle `threads` et l’URL porte `threads/$threadId` ; la doc suit l’interface et dit « chat » dans le corps du texte. La boîte de réception de canaux de contact qu’ajoute une automatisation e-mail installée est une autre surface : une conversation là-bas est un fil de contact, pas un chat — voir [Automatisations fournies](/fr/platform/automations/builtin) pour ce sens-là. ## Historique et recherche La barre latérale d’historique liste chaque chat que tu peux reprendre dans cette organisation, du plus récent au plus ancien, tes chats épinglés en tête et les chats rangés dans un projet sous leurs dossiers ; en sélectionner un ouvre la transcription complète. La recherche y filtre par titre, et la recherche plein texte dans le corps des messages se fait chat par chat plutôt qu’à l’échelle de l’organisation. Renommer un chat pose un titre à toi qui remplace celui généré. Supprimer un chat le déplace vers la [Corbeille](/fr/platform/admin/governance/trash), où la rétention le balaie après le délai de grâce. ## Où cela s’inscrit Bases du chat est la page que le reste de cette section affine : le [Mode Arène](/fr/platform/chat/arena-mode) fait tourner un même prompt sur deux modèles côte à côte, le [Mode vocal](/fr/platform/chat/voice-mode) couvre le fait de parler plutôt que de taper, et les [Chats partagés](/fr/platform/chat/shared-threads) la publication d’une transcription à l’organisation. Si ta question s’est changée en travail — quelque chose qui finit sur un livrable — [Concepts d’agent](/fr/platform/agents/concepts) est la lecture suivante : sur les tâches, les agents font tout ce que le chat laisse délibérément de côté. # Mode vocal Source: https://tale.dev/docs/fr/platform/chat/voice-mode Le mode vocal transforme la zone de saisie en microphone. Tu parles, l’enregistrement est transcrit dans ton message suivant, l’agent répond en texte, et cette réponse peut être lue à voix haute. La boucle se fait sans les mains, ce qui vaut beaucoup quand tu marches, tu cuisines ou tu en as assez de taper — et elle traverse deux fournisseurs vocaux, ce qui mérite d’être su avant d’y faire passer les données de ton organisation. Cette page couvre les deux moitiés de l’aller-retour et la frontière que franchit l’audio. Le chat lui-même ne change pas : la voix est une enveloppe autour du même flux de messages que décrit [Bases du chat](/fr/platform/chat/basics). ## De la parole au texte Lance l’enregistrement depuis le micro de la zone de saisie et parle ; arrête-le de la même façon. L’enregistrement part, un modèle de reconnaissance vocale le transcrit, et la transcription devient le message suivant du chat — exactement comme si tu l’avais tapé. Tu peux relire la transcription avant qu’elle parte, et cela compte : une erreur de transcription devient indiscernable d’une question mal formulée dès que l’agent y a répondu. La transcription tourne une fois par message parlé. Ce que l’agent reçoit, c’est du texte ; aucun audio n’atteint le modèle de chat. ## Du texte à la parole Faire lire une réponse à voix haute est un choix que tu poses dans la zone de saisie, pour le tour que tu t’apprêtes à envoyer. Active la sortie vocale et la réponse qui revient part vers un modèle de synthèse et se joue à mesure qu’elle arrive ; laisse-la éteinte et la réponse atterrit en texte comme n’importe quelle autre. La lecture peut être coupée avant la fin, et la dernière réponse peut être rejouée sans reposer la question. <Note> La sortie vocale est un contrôle de la zone de saisie, pas une préférence enregistrée. Aucune voix n’est épinglée à un agent et aucune valeur par défaut à l’échelle de l’organisation ne décide pour toi — la portée du choix est le tour que tu envoies, ce qui évite qu’une session mains libres te suive jusque dans un bureau partagé. </Note> ## Qui détient quelle partie Deux choix de modèles comptent ici, et aucun n’est le modèle du sélecteur. La reconnaissance vocale tourne avant le tour de l’agent, sur l’audio. La synthèse tourne après, sur la réponse finie. L’agent entre les deux ne change pas — mêmes instructions, mêmes tools, même contrat de contexte. Les deux sont configurés par la personne qui administre les fournisseurs de l’organisation. Si aucun fournisseur vocal n’est configuré, les contrôles vocaux n’ont rien à appeler, et la réponse est d’en connecter un plutôt que de changer quoi que ce soit dans le chat. ## La frontière de confidentialité L’enregistrement quitte ton appareil. Il est déposé dans le stockage de Tale, envoyé au fournisseur de reconnaissance vocale que l’organisation a configuré, et la transcription obtenue reste dans l’historique du chat à côté des messages tapés — cherchable, exportable, et soumise aux mêmes règles de rétention que le reste du chat. L’audio lui-même suit la politique de rétention de l’organisation. Les réponses partent vers le fournisseur de synthèse en texte brut, et l’audio renvoyé est streamé vers ton appareil plutôt que stocké. <Warning> Les organisations soumises à des règles strictes de résidence des données devraient choisir des fournisseurs vocaux dans la même région que le reste de la pile — l’audio et la transcription relèvent des mêmes règles que n’importe quel autre contenu de message. Voir [Résidence des données](/fr/cloud/data-residency). </Warning> ## Quand la voix bat le texte La voix va plus vite que le clavier pour les questions courtes et conversationnelles, et nettement moins vite pour tout ce que tu recopieras ensuite. Une réponse parlée s’entend une fois ; une réponse écrite se survole, se cite et se colle. | Prends … quand | Voix | Texte | | --------------------------------------------------- | ---- | ----- | | Tu as les mains prises et tu veux un fait rapide | ✓ | | | La réponse sera une longue liste ou un bloc de code | | ✓ | | La réponse alimentera un travail écrit plus tard | | ✓ | | Tu pratiques une langue et tu veux l’entendre | ✓ | | ## Où cela s’inscrit La voix est la deuxième forme d’entrée de la même zone de saisie, à côté de la frappe. La confidentialité pèse le plus lourd ici parce que deux fournisseurs supplémentaires touchent les données ; la page suivante dépend donc de ton édition — [Résidence des données](/fr/cloud/data-residency) sur le Cloud, ou [Fournisseurs](/fr/self-hosted/configuration/providers) si tu héberges Tale toi-même et choisis les fournisseurs vocaux comme les modèles de chat. # Chats partagés Source: https://tale.dev/docs/fr/platform/chat/shared-threads Partager un chat publie un instantané de la conversation en lecture seule, derrière un lien que toute personne de ton organisation peut ouvrir. Le tout tient en un geste : **Partager** copie le lien dans ton presse-papiers, et tu le colles là où ton équipe discute. Le mécanisme est assez léger pour un usage courant — partage une question et sa réponse comme tu partagerais un document. ## Partager un chat Ouvre le chat et clique sur le menu **⋯** dans l’en-tête, puis sur **Partager**. Le lien atterrit aussitôt dans ton presse-papiers — un toast **Lien copié** le confirme. La même entrée figure aussi dans le menu de la ligne de chaque chat, dans la barre latérale. Deux choses à savoir sur ce lien : - **Il est limité à l’organisation.** Seuls les membres connectés de ton organisation peuvent l’ouvrir ; ce n’est pas une URL publique. - **C’est un instantané.** Le destinataire voit la conversation telle qu’elle était au moment du partage. Si le chat a avancé et que tu veux partager l’état plus récent, clique de nouveau sur **Partager** — le lien reste le même et l’instantané se rafraîchit. <Frame caption="Ce que le destinataire ouvre : l’instantané partagé, en lecture seule, avec sa mention de partage."> ![Un chat partagé consulté en lecture seule, montrant la transcription de la conversation sous un titre Chat partagé, avec la mention de qui l’a partagé et quand.](/images/platform/chat-shared-view.webp) </Frame> ## Ce que voit le visiteur Le lien ouvre une vue **Chat partagé** en lecture seule : la transcription, avec la mention de qui a partagé le chat et quand. Il n’y a pas de zone de saisie — un chat partagé se lit, on n’y répond pas. Le visiteur qui veut aller plus loin sur le sujet démarre son propre chat — ou une tâche dans un [projet](/fr/platform/projects/overview), si c’est un livrable qu’il lui faut. ## Arrêter le partage Une fois le chat partagé, le menu de sa ligne propose **Arrêter le partage**. Le lien cesse de fonctionner immédiatement ; les visiteurs atterrissent sur une page indiquant que le chat n’est plus disponible. Supprimer le chat a le même effet sur le lien. Partager de nouveau plus tard publie un nouvel instantané. ## Où cela s’inscrit Les chats partagés sont la façon légère de passer une conversation à un coéquipier sans quitter le produit. L’alternative plus lourde est d’amener le coéquipier dans un [Projet](/fr/platform/projects/overview) où chats, fichiers et agents sont partagés par défaut. Le partage sert les passations ponctuelles ; un Projet sert la collaboration continue sur le même travail. # Chat Source: https://tale.dev/docs/fr/platform/chat/overview Le chat est le point d’entrée quotidien à Tale. Tu poses ta question, l’assistant cherche dans les connaissances de l’organisation ou va chercher une page quand la question le demande, et la réponse arrive en streaming, chaque étape et chaque source à l’affiche. Le chat ne fait délibérément qu’un seul travail — les questions et la récupération. Le travail qui demande un responsable et un résultat à relire — une présentation, un document traduit, un export de données — vit sur une tâche ; un processus fixe vit dans une automatisation. L’assistant connaît cette frontière et te renvoie vers une tâche dès qu’une demande la franchit, si bien que rien de lourd ne reste à moitié bâti dans un chat. <Frame caption="Un chat avec une réponse en streaming — la question, les étapes de l’assistant et la réponse."> ![Un fil de chat montrant une question d’utilisateur sur des retours d’onboarding et une réponse de l’assistant contenant un tableau markdown de trois thèmes.](/images/platform/chat-thread-reply.webp) </Frame> ## Les parties de l’écran La barre latérale liste chaque chat que tu peux reprendre, rangé sous tes dossiers de projet, favoris épinglés en tête, avec la recherche et les chats archivés en dessous. La colonne de conversation porte l’échange : au-dessus de chaque réponse, une ligne de réflexion repliable consigne ce que l’assistant a fait — le raisonnement, puis chaque recherche de connaissances ou récupération de page, dans l’ordre — et sous la réponse, **Sources** liste ce qu’il a réellement lu. La zone de saisie, en bas, est le champ de message plus un sélecteur unique pour le modèle — **Auto** par défaut, chaque modèle listé à épingler, et l’effort de raisonnement pour un modèle épinglé qui en a un ; le menu `+` porte la lecture à voix haute et le Mode Arène, et le micro dicte. Pendant qu’une réponse arrive en streaming, le bouton d’envoi devient un bouton d’arrêt. Un chat tout neuf s’ouvre sur quatre suggestions de départ. Clique sur l’une d’elles : elle devient ton premier message — le moyen le plus rapide de voir toute la boucle tourner une fois. <Frame caption="Un nouveau chat : le message d’accueil, les quatre suggestions de départ et la zone de saisie."> ![L’écran d’un nouveau chat encore vide, avec le message d’accueil, quatre boutons de suggestions de conversation et la zone de saisie en dessous.](/images/platform/chat-starters-empty.webp) </Frame> ## Chat, tâche ou automatisation ? Fais correspondre le travail à la surface — chaque type de travail a exactement une place. | Type de travail | Où il vit | Pourquoi | | ----------------------------------------------------------------------- | -------------- | -------------------------------------------------------------------------------------------------------- | | Interroger les connaissances, les documents ou une page web publique | Chat | Une conversation aux étapes et aux sources visibles ; rien à faire valider | | Produire un livrable — une présentation, une traduction, un rapport | Tâche | Il faut un responsable et une relecture ; un agent fait le travail, une personne marque la tâche Terminé | | Un processus fixe, avec des portes de validation et des étapes humaines | Automatisation | Le processus est le produit ; personnes et agents agissent à l’intérieur | L’assistant fait respecter la première ligne lui-même : demande-lui une dissertation de 2 000 mots et il t’en donne une esquisse courte, puis te dit de créer une tâche et de l’assigner à un agent. C’est voulu — un livrable produit directement dans le chat n’aurait ni étape de relecture ni responsable. ## Les pages de cette section <CardGroup cols="2"> <Card title="Bases du chat" icon="message-circle" href="/fr/platform/chat/basics"> Ce qui se passe entre l’envoi et l’arrivée de la réponse — la zone de saisie, les trois outils de récupération, le déroulé de réflexion et les sources. </Card> <Card title="Mode Arène" icon="swords" href="/fr/platform/chat/arena-mode"> La comparaison de modèles côte à côte, et comment les verdicts remontent dans l’analyse des retours. </Card> <Card title="Mode vocal" icon="mic" href="/fr/platform/chat/voice-mode"> Parler au lieu de taper — les passations STT et TTS et la frontière de confidentialité. </Card> <Card title="Chats partagés" icon="share-2" href="/fr/platform/chat/shared-threads"> Partager un instantané en lecture seule d’un chat avec le reste de l’organisation, et arrêter le partage plus tard. </Card> </CardGroup> ## Où cela s’inscrit Le chat est la surface qui pose les questions ; le reste de la plateforme est ce qu’il interroge. La base de connaissances alimente ses recherches, et les [projets](/fr/platform/projects/overview) classent son historique et portent les tâches qui reprennent tout ce que le chat refuse délibérément de bâtir sur place. La page à mettre en favori en premier est [Bases du chat](/fr/platform/chat/basics) — une fois compris le chemin de l’envoi à la réponse, chaque autre page du chat se lit comme une variation autour. # Serveurs MCP Source: https://tale.dev/docs/fr/platform/connectors/mcp-servers Un serveur MCP est un processus externe qui expose des outils aux agents de Tale via le Model Context Protocol. Là où une [connector](/fr/platform/connectors/overview) est un connecteur propre à un fournisseur que Tale livre, un serveur MCP est un pont générique que n’importe qui peut héberger — une API interne, un fournisseur sans connecteur, un script qui calcule ce que les outils intégrés de Tale ne savent pas calculer. Tu héberges le serveur ; Tale ne fait que lui parler. <Frame caption="Le formulaire Ajouter un serveur MCP — une connexion et une méthode d’authentification sont tout l’enregistrement."> ![La boîte de dialogue Ajouter un serveur MCP sous Paramètres API MCP, remplie pour un serveur de tickets de support — nom d’affichage Support Tickets, une description d’une ligne, Streamable HTTP comme type de transport, l’URL du serveur et Aucune comme méthode d’authentification — par-dessus la page MCP, où un serveur Internal Wiki est déjà enregistré.](/images/platform/settings-mcp-add-dialog.webp) </Frame> ## Enregistrer un serveur Ouvre **Paramètres > API > MCP** et clique sur **Ajouter un serveur MCP**. Le formulaire prend : - **Nom** et **Nom d'affichage** — l’identifiant, et le libellé que les agents et les cartes d’approbation affichent. - **Type de transport** — **Streamable HTTP**, **SSE** ou **stdio**. Les transports HTTP prennent une **URL** — le formulaire signale une URL malformée en ligne avant que tu puisses enregistrer ; stdio prend la commande que Tale lance. - **Authentification** — **Aucune**, **Clé API** ou **OAuth 2.0** (URL du jeton, ID client et secret, portées). - **Agents autorisés** — quels agents peuvent se lier à ce serveur. Le défaut est aucun agent ; va vers **Tous les agents** seulement quand le serveur est assez générique pour que chaque agent en bénéficie. **Enregistrer le serveur**, puis utilise **Tester la connexion** sur la ligne pour vérifier la poignée de main — le statut de la ligne affiche **Connecté**, **Déconnecté** ou **Erreur** avec le message amont. ## Les outils découverts Une fois connecté, Tale récupère le manifeste du serveur et le liste comme **Outils découverts** — le nom de chaque outil, sa description et si le serveur le marque **Nécessite une approbation**. Les outils marqués demandent dans le chat chaque fois qu’un agent les appelle, avec les arguments exacts affichés sur la carte ; les outils non marqués s’exécutent comme n’importe quel outil intégré. <Warning> Chaque outil MCP élargit ce que tes agents peuvent atteindre, et les drapeaux d’approbation viennent de l’auteur du serveur — connecter un serveur, c’est accepter son contrat d’outils. Lis la liste découverte avant de pointer des agents vers un serveur que tu n’as pas écrit. </Warning> ## L’utiliser depuis les agents Les outils d’un serveur enregistré et actif rejoignent la panoplie que les agents peuvent appeler ; la requête voyage à travers Tale jusqu’à ton serveur et la réponse revient dans la conversation. Le serveur peut aussi exposer des ressources et des prompts là où son auteur les implémente — les outils sont la surface commune. ## Désactiver et supprimer Chaque ligne de serveur peut être désactivée — ses outils sortent des panoplies d’agents jusqu’à ce que tu le réactives, l’enregistrement étant conservé. Supprimer le serveur retire l’enregistrement entièrement après une confirmation ; le rajouter plus tard est un enregistrement neuf avec une récupération neuve du manifeste. ## Serveur MCP ou connector Les deux laissent un agent atteindre au-delà de Tale ; la différence est qui possède le connecteur. Les connectors sont propres à un fournisseur, livrées et entretenues dans le catalogue ; les serveurs MCP sont génériques et à toi de les faire tourner. Va vers l’connector quand il en existe une pour le système cible ; va vers MCP quand le pont doit être ton propre code. ## Où cela s’inscrit MCP est la surface d’extension ouverte de la panoplie d’agent. Les lectures suivantes naturelles sont [Outils d’agent](/fr/platform/agents/tools) pour la façon dont les outils font surface sur un agent, [Configurer les approbations](/fr/platform/approvals/configure) pour les drapeaux qui retiennent les appels risqués, et le tutoriel [Serveur MCP en partant de zéro](/fr/tutorials/developer/mcp-server-from-scratch) pour en construire un de bout en bout. # WebDAV Source: https://tale.dev/docs/fr/platform/connectors/webdav WebDAV transforme le magasin de documents de Tale en un dossier distant que tu montes comme n’importe quel lecteur réseau partagé. Le magasin sous-jacent est le même que celui que montre le hub documentaire — ce que tu déposes dans le dossier monté apparaît dans l’interface, et inversement. Tout ce qu’il te faut tient sur un panneau : **Paramètres > API > WebDAV** porte les détails de connexion et le générateur de mots de passe applicatifs. <Frame caption="Paramètres > API > WebDAV — les détails de connexion préremplis en haut, le générateur de mots de passe applicatifs en dessous."> ![La page des paramètres WebDAV montrant une URL de connexion, un champ de nom d’utilisateur avec l’e-mail du compte, une explication indiquant que le mot de passe est un mot de passe applicatif généré, et un tableau de mots de passe applicatifs qui tient deux entrées — Design workstation et MacBook Pro, chacune avec son seul préfixe et sa date de création — à côté d’un bouton Générer.](/images/platform/settings-webdav.webp) </Frame> ## Générer un mot de passe applicatif Le point de terminaison s’authentifie avec des mots de passe applicatifs — de courts secrets que tu frappes par appareil — parce que chaque client WebDAV stocke son identifiant dans le trousseau du système, et qu’un secret cadré et révocable y a sa place, pas le mot de passe de ton compte. Le mot de passe de ton compte ne fonctionne pas sur ce point de terminaison. Clique sur **Générer**, étiquette le mot de passe d’après l’appareil (`MacBook Finder`, `ops-laptop rclone`) et copie-le — un par appareil ; le mot de passe complet ne s’affiche qu’une seule fois. Ensuite le tableau ne garde que le libellé et un court préfixe, assez pour reconnaître la ligne quand tu la révoques. Générer exige la même capacité que celle qui garde les clés API ; les simples Membres demandent à un admin. Pour le nom d’utilisateur, utilise l’e-mail de ton compte Tale. Seul le mot de passe est réellement vérifié, mais l’e-mail garde les lignes d’audit lisibles et correspond à ce que les boîtes de dialogue des clients attendent. ## Se connecter depuis ton appareil L’adresse est l’URL du panneau — `https://<your-site>/dav/<orgSlug>/documents/`. <Tabs> <Tab title="Finder macOS"> Appuie sur **⌘K** (Se connecter au serveur), colle l’URL et connecte-toi avec ton e-mail et le mot de passe applicatif. Le partage se monte dans la barre latérale ; glisse des fichiers dedans pour téléverser, dehors pour télécharger, et renomme ou supprime sur place. Le premier listage d’une grande arborescence peut prendre quelques secondes. </Tab> <Tab title="Windows"> Dans **Ce PC**, choisis **Connecter un lecteur réseau**, colle l’URL comme dossier et coche **Se connecter à l’aide d’informations d’identification différentes**. Windows plafonne les transferts WebDAV à 50 Mo par fichier par défaut — augmente `FileSizeLimitInBytes` sous la clé de registre `WebClient\Parameters` et redémarre le service WebClient. Sur un port HTTPS non standard, règle `BasicAuthLevel` à `2` sous la même clé. </Tab> <Tab title="Fichiers iOS"> Touche le menu à trois points, choisis **Se connecter au serveur** et saisis la même URL et les mêmes identifiants. Fichiers prend en charge la navigation et le téléchargement ; la modification sur place fonctionne pour les formats dotés d’une app iOS. </Tab> <Tab title="rclone"> ```bash rclone config create tale webdav \ url=https://<your-site>/dav/<orgSlug>/documents/ \ vendor=other \ user=<your-email> \ pass=$(rclone obscure '<app-password>') rclone copy ./local-folder tale: --progress ``` `vendor=other` est correct — le serveur de Tale est générique, pas une saveur nommée que rclone reconnaît. </Tab> </Tabs> ## Ce que le montage sait faire Les lectures et écritures reflètent tes permissions du hub documentaire, les fichiers que tu téléverses s’indexent et se recherchent comme des téléversements directs, et leur champ source est réglé sur `webdav` pour le filtrage dans les vues d’audit. Les fichiers de projet font exception : l’onglet **Connaissances** d’un projet est scopé à ce seul projet et n’apparaît jamais via WebDAV, le montage ne montre donc que le hub documentaire de l’organisation. L’espace `.trash/` liste les documents supprimés de façon réversible, en lecture seule — télécharge pour récupérer, restaure via l’interface. Les éditeurs qui prennent des verrous WebDAV (Office, LibreOffice) les obtiennent ; une écriture concurrente pendant une modification renvoie `423 Locked`. ## Révoquer Révoque un mot de passe avec l’icône corbeille de sa ligne — la requête suivante qui le porte est rejetée, les autres appareils ne sont pas touchés, et les verrous qu’il tenait sont libérés. Il n’y a pas d’annulation ; frappe un nouveau mot de passe si tu révoques la mauvaise ligne. <Warning> L’authentification Basic envoie le mot de passe applicatif à chaque requête. Ne monte qu’en HTTPS, garde le mot de passe dans le trousseau du système et ne le colle jamais dans une URL `https://user:pass@host/` — l’historique du shell et les journaux de proxy survivent au montage. Révoque immédiatement au moindre soupçon de fuite. </Warning> ## Où cela s’inscrit WebDAV est la porte par utilisateur, côté appareil, vers les mêmes données que le [hub documentaire](/fr/platform/knowledge/documents) ; le protocole réseau vit sous [API WebDAV](/fr/develop/webdav-api). Pour les imports machine à machine, les [clés API](/fr/platform/admin/api-keys) plus l’API REST sont en général le meilleur choix. # Connectors Source: https://tale.dev/docs/fr/platform/connectors/overview Une connector, c’est deux choses à la fois : un **connecteur** livré avec la plateforme, et les **identifiants** que ton organisation enregistre en face de ce connecteur. Le connecteur porte la connaissance du fournisseur — quelles actions existent, ce que chacune prend et renvoie, comment se fait la connexion — et il est identique dans toutes les organisations. Les identifiants, eux, sont à toi, et un connecteur en porte autant que nécessaire : un par espace de travail, boutique, boîte mail ou bot. Treize connecteurs sont livrés aujourd’hui, et chacun figure déjà sous **Paramètres > Connectors**, en attente de son premier identifiant. Tu préfères regarder d’abord ? L’épisode 7 parcourt les portes vers l’extérieur — connecteurs, MCP et frontières — en deux minutes et demie, sous-titres compris. <Video src="/videos/fr/tutorials/ep7-connectors/ep7-connectors.fr.mp4" poster="/videos/fr/tutorials/ep7-connectors/ep7-connectors.fr.webp" captions="/videos/fr/tutorials/ep7-connectors/ep7-connectors.fr.vtt" lang="fr" title="Épisode 7 — Connectors & le monde extérieur" caption="Épisode 7 — Connectors & le monde extérieur (2:18)"> </Video> ## Ce qu’est un connecteur Il n’y a rien à installer. Chaque connecteur arrive avec la plateforme, c’est pourquoi le catalogue est le même dans toutes les organisations et qu’une mise à jour suffit à le faire avancer sans que personne l’entretienne. Un connecteur est une définition : un nom affiché avec une ligne de description, les catégories auxquelles il appartient, les méthodes d’authentification qu’il accepte, et la liste des actions qu’il sait exécuter chez le fournisseur. Comme cette définition vaut pour tout le monde, ton organisation ne décide que d’une chose : au nom de quels comptes Tale peut agir. Cette décision, ce sont les identifiants, et la configuration s’arrête là. ## Les connecteurs livrés Treize connecteurs sont livrés, chacun marqué de la catégorie à laquelle il appartient — Knowledge, Messaging, Email, Developer, Commerce, Search ou Files. **Connexion** est la méthode d’authentification que le connecteur accepte, celle qui décide de ce que le formulaire demande ; **Actions** est le nombre d’opérations qu’il expose, le même compte que celui affiché dans sa section des paramètres. | Connector | Ce que la connexion t’apporte | Connexion | Actions | | ----------------------- | ----------------------------------------------------------------------------------------------------------- | --------------------------------- | ------- | | **Confluence** | Importer des pages Confluence Cloud dans la base de connaissances de Tale. | Nom d’utilisateur et mot de passe | 2 | | **Discord** | Poster des messages et gérer les canaux de ton serveur Discord. | Jeton | 8 | | **GitHub** | Gérer dépôts, tickets et pull requests sur GitHub. | Jeton | 19 | | **Gmail** | Lire, envoyer et classer le courrier dans Gmail. | OAuth | 9 | | **Google Drive** | Importer des fichiers depuis Google Drive dans la base de connaissances de Tale. | OAuth | 2 | | **IMAP / SMTP Mailbox** | Brancher un serveur mail IMAP + SMTP privé sur Conversations, sans compte Gmail ni Outlook. | Nom d’utilisateur et mot de passe | 2 | | **Microsoft Outlook** | Gérer le courrier, l’agenda et les contacts Outlook. | OAuth | 10 | | **Shopify** | Synchroniser produits, clients et commandes depuis ta boutique Shopify. | Clé API | 9 | | **Slack** | Envoyer des messages et travailler avec les canaux dans Slack. | OAuth | 7 | | **Tavily** | Recherche web en temps réel et extraction de pages pour la recherche IA. | Clé API | 2 | | **Microsoft Teams** | Envoyer des messages et gérer les canaux dans Microsoft Teams. | OAuth | 9 | | **Twilio** | Envoyer des SMS et passer des appels vocaux via Twilio. | Nom d’utilisateur et mot de passe | 7 | | **WebDAV Files** | Lire, écrire et lister les fichiers du stockage WebDAV de l’organisation — ceux que sert l’endpoint `/dav`. | Nom d’utilisateur et mot de passe | 4 | Les pages et fichiers entrés par Confluence ou Google Drive passent par la même indexation qu’un téléversement direct, et les réponses les citent en remontant à la source — voir [Documents](/fr/platform/knowledge/documents). Le connecteur WebDAV est le côté écriture du stockage que tes appareils montent comme lecteur réseau, décrit dans [WebDAV](/fr/platform/connectors/webdav). ## Les identifiants d’un connecteur Un connecteur porte autant d’identifiants que ton organisation en a besoin. Un espace Slack par entité, une boutique Shopify par marché, une boîte mail par file de support — chacun est une ligne distincte sous le connecteur, avec son propre secret et son propre état. C’est ce qui permet à une même bibliothèque d’automatisations de servir plusieurs équipes sans qu’aucune emprunte le compte d’une autre. Chaque identifiant porte quatre choses : - **Nom** — le nom sous lequel une action choisit ces identifiants. Écris-le pour la personne qui relira l’automatisation dans six mois : `Boîte de support`, `Boutique UE`, `Bot de release`. - **Méthode d’authentification** — **Clé API**, **Jeton**, **Nom d’utilisateur et mot de passe** ou **OAuth**, pris dans ce que le connecteur accepte. - **Par défaut** — un identifiant par connecteur peut l’être. Un nœud d’automatisation ou une action de chat qui n’en nomme aucun l’utilise. - **État** — un identifiant est soit en service, soit **Désactivé**. Le désactiver garde la ligne et sa configuration mais empêche tout appel qui passerait par elle. Sans identifiant par défaut, un connecteur continue de servir tous les appelants qui en nomment un ; celui qui n’en nomme aucun n’a plus rien sur quoi se rabattre. La section du connecteur le dit, et le remède est de promouvoir l’un des identifiants existants. <Note> Confluence et Shopify n’ont pas d’hôte unique côté fournisseur : l’API vit sur ton propre site Atlassian ou dans ta propre boutique `myshopify.com`. Les deux demandent donc une **URL de l’instance** par identifiant, et leur section porte la ligne _Chaque identifiant nomme sa propre instance._ Pointe Confluence sur l’adresse où tu ouvres Confluence, et Shopify sur l’adresse d’administration de la boutique plutôt que sur le domaine de la vitrine. </Note> ## En connecter un Le point de départ dépend de ce que le connecteur accepte. Les connecteurs à clé ou à jeton ouvrent un formulaire et prennent le secret directement ; les connecteurs OAuth t’envoient sur l’écran de consentement du fournisseur et reviennent avec un identifiant déjà rempli. Les deux chemins finissent au même endroit — une ligne nommée sous le connecteur. <Steps> <Step title="Ouvrir Paramètres > Connectors"> Chaque connecteur a sa section, en tête de laquelle figurent son icône, sa description, ses catégories et son nombre d’actions. Rien ne se cache derrière une boîte de dialogue de catalogue. </Step> <Step title="Ajouter des identifiants"> **Ajouter des identifiants** ouvre le formulaire sur les connecteurs qui prennent une clé, un jeton ou un couple nom d’utilisateur et mot de passe. **Connecter** déroule le consentement du fournisseur sur les connecteurs OAuth, puis crée une ligne avec le résultat. </Step> <Step title="Le nommer et le définir par défaut"> Donne à l’identifiant un nom que tes automatisations pourront viser, et promeus-le s’il doit répondre quand personne n’en nomme un. Les actions du connecteur deviennent disponibles dans les automatisations et le chat dès que la ligne existe. </Step> </Steps> Le détail par méthode — ce que chaque formulaire demande, comment remplacer un secret, ce qui se passe quand une autorisation expire — vit sur [Identifiants d’connector](/fr/platform/admin/connectors). ## Les actions dans les automatisations et le chat Chaque action déclarée par un connecteur a un nom, une description, un schéma d’entrée, une signature de sortie et un effet déclaré : `read` ou `write`. Les automatisations posent une action comme nœud dans l’éditeur de workflow ; le chat atteint les mêmes actions sous forme d’outils d’agent. Dans les deux cas l’appel résout d’abord un identifiant — celui que l’appelant nomme, ou celui par défaut du connecteur — et échoue clairement quand il n’y en a ni l’un ni l’autre. <Warning> Les actions en écriture changent quelque chose dans l’autre système : un message posté, un ticket ouvert, un SMS envoyé. Elles passent par la politique d’approbation de ton organisation, l’agent propose donc l’appel et une personne le libère. Lis [Configurer les approbations](/fr/platform/approvals/configure) avant de lancer un agent dessus. </Warning> ## Quand aucun connecteur ne convient Treize connecteurs couvrent les systèmes vers lesquels la plupart des équipes se tournent, et ils ne couvrent ni une API interne, ni un outil maison, ni un fournisseur pour lequel personne n’a écrit de connecteur. C’est à cela que sert MCP : tu héberges un serveur, Tale l’enregistre, et ses outils rejoignent la trousse de l’agent aux côtés des actions de connecteur. Le pont devient ton code au lieu d’une définition livrée — c’est exactement l’échange : plus de liberté, plus d’entretien. Un tel serveur s’enregistre sous **Paramètres > API > MCP**, comme le décrit [Serveurs MCP](/fr/platform/connectors/mcp-servers). ## Où cela s’inscrit Les connecteurs sont la façon dont Tale atteint les systèmes où ton travail se trouve déjà, et les identifiants sont la décision de savoir au nom de quels comptes il y agit. À partir d’ici, [Identifiants d’connector](/fr/platform/admin/connectors) couvre l’exploitation — ajouter, remplacer, désactiver et reconnecter les lignes sous chaque connecteur. [Outils d’agent](/fr/platform/agents/tools) montre comment les actions d’un connecteur arrivent dans la trousse d’un agent, [Configurer les approbations](/fr/platform/approvals/configure) retient celles en écriture, et [Serveurs MCP](/fr/platform/connectors/mcp-servers) couvre le terrain que le catalogue laisse ouvert. </content> </invoke> # Bibliothèque de skills Source: https://tale.dev/docs/fr/platform/workspace/skills Un skill est une consigne que tu écris une fois et que chaque agent peut ensuite lire. Il vit dans l'arborescence de fichiers de ton organisation sous forme d'un petit bundle : une `SKILL.md` qui porte la consigne dans son corps, plus le matériel de référence sur lequel cette consigne s'appuie. **Paramètres > Skills** est l'endroit où tu crées, téléverses et entretiens ces bundles. Chaque membre peut créer des skills ; ce que tu peux modifier se décide bundle par bundle. Cette page couvre ce qu'est un skill, le fichier dont il est fait, qui le voit, et comment tu en ajoutes ou en retires un. Lis le côté agent sur [Les skills sur les agents](/fr/platform/agents/skills) dès qu'un agent doit aller chercher un bundle précis. ## Ce qu'est un skill, et ce qu'il n'est pas Un skill est un **paquet de connaissances**. Son corps est une consigne qu'un modèle lit quand le travail le demande : une voix maison pour l'écriture, une checklist que ton équipe suit, la façon dont ton organisation formule un refus. Un modèle trouve le bundle par sa description, lit le corps quand cette description correspond à la tâche, et ouvre les fichiers du bundle quand le corps pointe vers eux. Un skill n'est jamais quelque chose que la plateforme exécute. Un bundle n'a ni point d'entrée, ni commande, ni runtime — un fichier sous `scripts/` est du matériel qu'un modèle peut lire et adapter, pas un programme que Tale lance pour toi. C'est cette limite qui rend un bundle acceptable venu de l'extérieur : importer le skill de quelqu'un d'autre apporte à ton organisation de la prose et des fichiers de référence, et rien qui puisse agir tout seul. ## Le fichier SKILL.md Chaque bundle a exactement une `SKILL.md` à sa racine — un frontmatter YAML, puis le corps de la consigne en markdown. ```markdown --- name: release-notes description: Transforme une liste de changements mergés en notes de version dans notre voix maison. À utiliser quand on demande un changelog, des notes de version ou un résumé de ce qui a été livré. visibility: team teams: - jx7d… license: CC-BY-4.0 --- Écris les notes de version en trois sections — Added, Changed, Fixed — et commence chaque ligne par le verbe... ``` Les clés suivent la convention agentskills.io en kebab-case, et toute clé que Tale ne reconnaît pas est conservée telle quelle : un bundle écrit pour un autre outil survit à une édition et un enregistrement sans changer. | Clé | Ce qu'elle porte | | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `name` | Le slug, qui doit être égal au nom du dossier du bundle — lettres minuscules, chiffres et tirets simples, 64 caractères au plus. `anthropic` et `claude` sont réservés. | | `description` | Jusqu'à 1024 caractères — le champ qui décide si un modèle va chercher le skill. Dis ce qu'il fait et quand il s'applique. | | `visibility` | `team` ou `org`. Absente, elle vaut `org`. `private` est retiré — un bundle qui le porte déjà se lit encore, mais aucun nouveau skill ne le prend. | | `teams` | Les ids des équipes avec lesquelles un skill `team` est partagé — obligatoire là, rejeté ailleurs. Le sélecteur de partage de la bibliothèque le remplit pour toi. | | `owner` | Le membre à qui appartient le bundle — de l'attribution sur un skill partagé, obligatoire sur un ancien skill `private`. | | `license` | Texte libre, pour un bundle importé ou que tu comptes transmettre. | | `recommended-packages` | Des paquets Python ou Node que l'auteur suggère. Purement indicatif — Tale n'installe jamais rien au nom d'un skill. | | `disable-model-invocation` | À `true`, un modèle ne doit pas aller chercher le skill de lui-même. Il reste disponible pour un rappel explicite. | | `icon` et `labels` | Un id Iconify et jusqu'à huit puces, pour la carte du skill dans la bibliothèque. | Deux plafonds s'appliquent : le frontmatter peut atteindre 16 Ko, et la `SKILL.md` entière 512 Ko. Les assets du bundle vivent hors de ce budget. ## Qui le voit Le partage tient dans un champ, pas dans une table de permissions. `visibility: team` partage le bundle avec les équipes listées sous `teams` ; choisis-les dans la section **Visibilité** de la bibliothèque. `visibility: org` signifie que chaque membre le voit et que les agents de n'importe quel projet peuvent l'équiper. N'importe quel membre peut partager un skill avec des équipes ou toute l'organisation ; modifier ou supprimer le skill partagé de quelqu'un d'autre demande un admin de l'organisation. Un bundle sans aucune `visibility` — y compris celui que tu téléverses — compte comme un skill d'organisation, et l'aperçu du téléversement te le dit avant que tu confirmes. <Note> `visibility: private` est retiré. Les agents sont la seule surface qui équipe des skills, et les agents d'un projet ne voient jamais le bundle privé d'un seul membre — un skill privé ne serait donc visible que pour toi et utilisable nulle part. Un bundle qui porte déjà cette valeur continue de fonctionner pour son propriétaire (même un admin ne le lit pas), et son propriétaire peut élargir le partage à tout moment ; les nouveaux skills et les téléversements qui déclarent `private` sont refusés. </Note> Restreindre le partage d'un skill — d'organisation à équipe, ou retirer une équipe — demande d'abord confirmation : qui perd le skill de vue le perd aussi dans chaque agent qui l'équipait à travers lui. ## Ajouter un skill à la bibliothèque Ouvre **Paramètres > Skills**. La page est un tableau de tous les skills que tu peux voir — nom, description, visibilité et libellés — avec une recherche qui couvre le nom, la description et les libellés, et des filtres pour la visibilité et le libellé. Un clic sur une ligne ouvre le bundle. **Ajouter un skill** propose trois points de départ. <Steps> <Step title="Partir de zéro"> **Skill vierge** demande un nom — le slug, en lettres minuscules, chiffres et tirets simples — plus la description et le partage, et un corps de consigne que tu écris sur place. Un nouveau skill démarre partagé avec l'organisation ; restreins le partage aux équipes quand le savoir leur appartient. </Step> <Step title="Ou téléverser un bundle"> **Téléverser un zip** prend un `.zip` avec `SKILL.md` à la racine, à côté de dossiers comme `scripts/`, `references/` ou `assets/` ; **Téléverser un dossier** prend le dossier lui-même et le zippe pour toi. Dans les deux cas, Tale lit le frontmatter avant d'écrire quoi que ce soit et te montre ce qu'il a trouvé — la description, le partage avec lequel le bundle arrivera, la licence et la liste complète des fichiers avec leurs tailles. Tu approuves donc un bundle que tu as réellement vu. Si le slug existe déjà, Tale demande d'abord si tu veux remplacer. </Step> <Step title="Écrire le corps"> Ouvre le skill et écris la consigne sous **Instructions (corps)**. C'est le texte que le modèle lit — écris-le comme tu brieferais une collègue : à quoi sert le skill, quand il s'applique, et à quoi ressemble un bon résultat. </Step> </Steps> ## Ce que contient le bundle La vue détaillée d'un skill montre **Bundle** — l'arborescence telle qu'elle existe sur le disque — avec un visualiseur pour chaque fichier que tu cliques. Le plus petit skill utile tient dans un seul fichier ; la plupart grandissent dossier par dossier. ```text release-notes/ ├── SKILL.md ├── references/ │ └── voice-and-tone.md └── scripts/ └── group-changes.py ``` Garde les assets petits et lisibles. Un texte qu'un modèle ouvre à peu de frais sert ; un gros binaire reste là sans être lu, et le visualiseur dit franchement qu'il ne peut pas l'afficher. ## Retirer un skill **Supprimer le skill** dans la vue détaillée retire le bundle du disque ; chaque agent qui l'équipait perd l'accès, sans solution de repli. Il n'y a pas d'épinglage de version — un skill est toujours lu exactement tel qu'il est maintenant, et c'est aussi ce qui le rend précieux : une modification atteint tout le monde. ## Où cela s'inscrit La bibliothèque de skills est la réutilisation la plus légère que Tale offre : un fichier, un champ pour le partage, rien à garder synchronisé entre les personnes qui en ont besoin. C'est là qu'une formulation que tu retapes sans arrêt cesse d'être quelque chose que tu retapes. Une fois le bundle dans la bibliothèque, reste à décider quels agents le reçoivent — c'est [Les skills sur les agents](/fr/platform/agents/skills) : équiper les agents d'un projet et le chemin d'un bundle vers la sandbox. # Harnesses Source: https://tale.dev/docs/fr/platform/agents/harnesses Un **Harness** est une CLI de code livrée avec la plateforme — Claude Code, Codex, Cursor et les autres — qui exécute le modèle choisi dans un conteneur isolé, au lieu de la boucle de chat ordinaire. Le harness planifie, écrit des fichiers, lance des commandes, installe des paquets et rend compte. Tu ne choisis jamais un harness dans le composer du chat : le chat ne sélectionne qu’un **modèle**. Le harness se choisit quand tu crées un **agent de projet** ou un nœud **agent** d’automatisation — les deux surfaces nomment le champ **Harness**. Cette page traite des harnesses livrés avec Tale, de l’endroit où tu en choisis un, de l’origine de l’accès, et de ce que le conteneur peut ou ne peut pas atteindre. Les accès eux-mêmes relèvent de l’organisation — voir [Fournisseurs](/fr/platform/admin/providers). **Paramètres > Fournisseurs** porte aussi un onglet **Harnesses** qui montre comment chaque harness se résoudrait pour l’organisation. ## Où tu choisis un harness Ouvre l’onglet **Agents** d’un projet et crée ou modifie un agent. Le dialogue demande un **Harness** — la CLI de code sur laquelle cet agent tournera — à côté de son modèle, de son équipement et de ses instructions. Assigne une tâche du tableau à cet agent et il travaille dans une sandbox sur ce harness. Dans une automatisation, un nœud **agent** porte le même champ **Harness**. Quand le workflow atteint ce nœud, le tour s’exécute sur le harness choisi. Le chat ne liste aucun harness. Le sélecteur du composer ne propose que des modèles ; le travail sur harness arrive par un agent de projet ou un nœud agent d’automatisation, pas par un groupe du composer. ## Ce qu’est un tour sur harness Décris la tâche en langage ordinaire : « écris une petite CLI Python et teste-la », « clone ce dépôt et corrige le bug de l’issue 42 ». Le message part vers le harness, pas directement vers le modèle. Le harness pilote le modèle en boucle à l’intérieur du conteneur et décide lui-même quand lire un fichier, lancer une commande ou refaire un essai ; la réponse arrive quand son tour se termine. Deux conséquences. Le travail est réel plutôt que décrit : les fichiers existent, les commandes ont bel et bien tourné, et c’est leur sortie que le modèle a analysée. Et la forme du tour appartient au harness, pas à Tale — un harness doté d’un mode plan termine sur une proposition que tu peux relire, un harness fait pour les passages uniques va simplement au bout. ## Les harnesses livrés Neuf harnesses sont livrés avec la plateforme. Ils diffèrent par la façon dont ils reçoivent un prompt, par la possibilité de les infléchir en cours de tour, et par leur accès aux serveurs MCP. | Harness | Accès acceptés | Bon à savoir | | ----------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- | | Claude Code | Géré ou le tien | Le plus capable : infléchissable en cours de tour, avec un mode plan qui se termine par une proposition relisible. Atteint les serveurs MCP. | | Codex | Géré ou le tien | Tours en un seul passage. Atteint les serveurs MCP. | | Cursor | Le tien uniquement | Tours en un seul passage. Sa CLI ne sait pas passer par la passerelle de la plateforme, un accès géré est donc refusé. | | Gemini CLI | Géré ou le tien | Tours en un seul passage. Atteint les serveurs MCP. | | Hermes | Géré ou le tien | Tours en un seul passage, sans canal MCP. | | OpenClaw | Géré ou le tien | Tours en un seul passage. Atteint les serveurs MCP. | | OpenCode | Géré uniquement | Tours en un seul passage. Atteint les serveurs MCP. Passe par la passerelle, ta propre clé est refusée. | | Pi | Géré ou le tien | Tours en un seul passage, sans canal MCP. | | Qwen Code | Géré ou le tien | Tours en un seul passage. Atteint les serveurs MCP. | En pratique, la différence se joue sur l’inflexion. Avec Claude Code, une correction envoyée pendant que le tour tourne atteint l’agent à sa prochaine frontière d’outil : « prends pnpm, pas npm » arrive donc pendant que le travail est encore en cours. Tous les autres harnesses récupèrent un message en attente à la frontière du tour. ## D’où vient l’accès L’accès appartient à l’organisation, pas à l’agent. Un agent ne détient aucune clé propre, et il n’existe pas d’onglet d’accès par agent ; ce avec quoi un tour s’authentifie découle de l’accès fournisseur associé au modèle que tu as choisi, configuré sous [Fournisseurs](/fr/platform/admin/providers). Laquelle des deux postures un tour adopte découle du type d’accès dont il s’agit. **Une clé d’API stockée, ou lue dans une variable d’environnement du déploiement**, reste chez la plateforme. Tale frappe pour le tour une clé de passerelle limitée à la session, et le harness s’authentifie avec elle plutôt qu’avec le vrai secret : le conteneur ne détient donc jamais un accès qui survive à la session. C’est la posture gérée, et le seul harness qui la refuse est Cursor. **Un abonnement fournisseur** — clé de plan de code, clé de portail, blob OAuth, ou pool de jetons rotatifs récupérés auprès d’un broker — fonctionne autrement, parce que les fournisseurs réservent ces accès à leur propre outillage d’agent. Un accès par abonnement force donc le tour sur un harness précis : demander un tour de chat ordinaire est refusé avec un motif qui nomme ce harness, et demander un autre harness l’est aussi. Le secret est injecté dans l’environnement de la session, donc en posture bring-your-own, et le harness imposé doit l’accepter — OpenCode, qui ne passe que par la passerelle, refuse. <Note> Un tour sur harness nomme toujours un harness concret. Rien n’en devine un à ta place : le seul cas où un harness arrive de lui-même est l’accès par abonnement, qui porte son choix imposé avec lui. </Note> ## Ce que la sandbox peut atteindre Le conteneur démarre sur un répertoire de travail vide et reste verrouillé par défaut. Les fichiers et dossiers que tu épingles avec `@` entrent dans la session sous `/user/uploads/`, de sorte que l’agent ouvre les vrais octets plutôt qu’un extrait de recherche, et ce qu’il écrit sous `/user/output/` revient dans la conversation sous forme de fichier. Le trafic sortant est bloqué hormis une liste étroite — registres de paquets et GitHub — si bien que l’agent peut installer ce dont il a besoin et cloner un dépôt public sans atteindre des hôtes arbitraires. Les connectors connectées atteignent l’agent par un broker, pas par la boîte. Quand l’agent en appelle une, la requête repart vers Tale, qui l’exécute avec l’accès stocké et ne renvoie que le résultat : un conteneur compromis ne peut donc pas lire tes clés. Une écriture apparaît comme une carte de validation dans la conversation et se poursuit une fois que tu l’approuves. GitHub est l’exception assumée : `git` et la CLI `gh` ont besoin d’un jeton en local ; un tour s’exécute donc avec un jeton restreint tant que la conversation garde le connecteur GitHub équipé — injecté à chaque tour, disparu dès la fin du tour. Les skills liés à l’agent sont déposés dans la session sous forme de fichiers plutôt que récupérés par un outil, et un skill livré par le dépôt cloné l’emporte sur la copie que Tale déposerait — cette règle de priorité est détaillée dans [Skills d’agent](/fr/platform/agents/skills). Tes propres [variables d’environnement et secrets](/fr/platform/member/environment) sont également posés dans le conteneur : c’est ainsi qu’un jeton personnel ou un point d’accès à toi rejoint le travail sans qu’aucune autre session le voie. ## Coût et mesure Un tour sur harness peut être long et appeler le modèle de nombreuses fois : il coûte donc plus qu’une simple réponse de chat. Les tours gérés passent par la passerelle, et c’est ce qui les rend mesurables : ils atterrissent dans l’[Analytique d’usage](/fr/platform/admin/governance/usage-analytics) au même titre que tous les autres, et les [Politiques et limites](/fr/platform/admin/governance/policies-and-limits) de l’organisation plafonnent ce qu’ils peuvent dépenser. Les tours sur un accès par abonnement contournent la passerelle par construction, puisque le secret entre dans le conteneur et que l’outillage du fournisseur lui parle directement. Ces tours ne sont pas mesurés et les plafonds de dépense de l’organisation ne les atteignent pas — la comptabilité revient à qui détient l’abonnement. ## Où cela se place Un harness transforme un agent de projet ou un nœud agent d’automatisation en session vivante avec un outil de code dans un conteneur isolé : tu le diriges en langage ordinaire, il travaille sur de vrais fichiers, et le harness impose le rythme du tour. Le chat reste limité aux modèles ; le champ **Harness** vit sur l’agent ou sur le nœud d’automatisation. Ce qui décide de la part restant sous le contrôle de l’organisation, c’est l’accès — une clé stockée garde le tour sur la passerelle, sous les plafonds et dans la mesure, tandis qu’un abonnement fournisseur le pousse dans la boîte et sur le compte de ce fournisseur. Lis cette page avec [Fournisseurs](/fr/platform/admin/providers) pour le versant accès et [Connectors](/fr/platform/connectors/overview) pour ce que l’agent peut atteindre une fois lancé. # Workers d'agent Source: https://tale.dev/docs/fr/platform/agents/delegation Tu lances un worker quand une tâche mérite son propre contexte ciblé : recherche ouverte, extraction en masse, rédaction d'un long document. L'agent avec qui tu discutes compose un **worker** à la demande — un nom, des instructions de tâche, une méthode de travail optionnelle et une sélection d'outils — le fait tourner et replie le résultat dans sa réponse. Les workers sont éphémères : ils existent pour un seul job, et leur exécution apparaît comme une **carte de job** dans le chat. Cette page te donne le modèle mental pour savoir quand un worker est la bonne forme et comment la plateforme le maintient borné. Le parcours de bout en bout vit dans [Confier du travail à un worker](/fr/tutorials/editor/delegate-between-agents). ## Comment tourne un job Quand l'agent appelle **spawn_agent**, Tale résout les capacités du worker, démarre une conversation enfant fraîche et fait tourner le worker en mode non interactif : il ne voit que la tâche envoyée par l'agent (pas tout l'historique du chat), suit sa progression sur une checklist visible en direct, et son dernier message revient à l'agent comme résultat. Le chat affiche une carte de job avec le nom du worker, la progression en direct, le statut final et une transcription dépliable de tout ce qu'il a fait. Les workers ne te parlent jamais. Si un worker a besoin d'une information que seul un humain peut donner, il le dit dans son résultat et l'agent te pose la question — les questions viennent toujours de l'agent avec qui tu parles réellement. ## Les capacités sont toujours un sous-ensemble Un worker ne peut détenir au plus que ce que détient l'agent qui le lance. Trois couches décident de la sélection effective : - **La configuration de l'org** — les outils, skills et connectors de l'agent, tels que configurés par tes admins. Rien à gérer par worker. - **La sélection par job** — l'agent choisit le plus petit ensemble dans ses propres capacités pour cette tâche (moins d'outils = un worker plus ciblé). - **Les exceptions de plateforme** — quelques outils ne se transmettent jamais, au premier rang l'outil de question à l'utilisateur : les questions d'un worker passent par l'agent, pour qu'une réponse ne parte jamais dans le vide. Les workers ne peuvent pas non plus lancer de workers. Une exception va dans l'autre sens : chaque worker peut toujours lister et lire les fichiers du thread (téléversements, sorties générées) — écrire des fichiers ou exécuter du code reste une sélection explicite. Tout ce qui sort de ces bornes est silencieusement ignoré et signalé — la carte de job montre ce qui a été retranché, et l'agent s'adapte (en te disant par exemple qu'une connector doit être connectée). ## Méthodes de travail Pour du travail ouvert, l'agent peut accorder un **skill de méthodologie** comme méthode de travail du worker — `web-research` est fourni : planification en direct sur la checklist, budgets de recherche par question et un livrable cité. Les méthodologies sont des skills ; tes admins les gouvernent comme n'importe quel autre skill. ## Limites et dépense Un worker tourne dans le tour qui l'a lancé et ne peut pas lui survivre ; quand le plafond est atteint, le job se termine avec sa progression partielle encore visible sur la carte. Ce plafond appartient à l'hôte qui exécute le tour, pas à l'agent, qui ne porte aucun délai propre. La consommation de tokens remonte à l'agent qui a lancé le job, et les limites de dépense s'appliquent à l'organisation dans son ensemble plutôt que par agent : le coût d'un job atterrit donc avec le reste de l'usage de l'organisation. Les admins plafonnent le nombre de jobs qui tournent en même temps via **Gouvernance → agent_jobs** (10 par défaut). ## Quand y recourir | Prends … quand | Worker | Agent seul | Workflow | | -------------------------------------------------------- | ------ | ---------- | -------- | | Une sous-tâche profite d'un contexte isolé et ciblé | ✓ | | | | L'agent peut bien répondre directement | | ✓ | | | Le travail a des étapes fixes avec des validations entre | | | ✓ | Le coût d'un worker est une exécution de plus ; le gain, un contexte propre avec exactement les bonnes capacités pour la sous-tâche — et une carte de job qui montre ce qui s'est passé. Quand les étapes sont fixes et que tu veux des validations ou de la planification entre elles, un workflow est la bonne forme. # Les skills sur les agents Source: https://tale.dev/docs/fr/platform/agents/skills Un agent n'atteint un skill que s'il est équipé — et l'équipement se choisit dans la [bibliothèque de skills](/fr/platform/workspace/skills) de l'organisation. Cette page parle des surfaces qui y puisent : les agents d'un projet et les nœuds agent d'une automatisation. Une seule règle décide de ce qu'elles peuvent choisir : **c'est la visibilité du projet lui-même qui compte, jamais celle du membre qui configure.** ## Ce que décide l'équipement Un skill équipé est proposé au modèle par sa description. Quand le modèle juge cette description pertinente pour ta demande, il lit le corps de la `SKILL.md`, puis ouvre les fichiers du bundle là où le corps pointe vers eux. Rien n'est exécuté et rien n'est collé d'avance — un skill ne coûte du contexte que sur les tours où le modèle va réellement le chercher. Un bundle dont le frontmatter porte `disable-model-invocation: true` se comporte autrement. Il reste équipé et lisible, mais le modèle ne doit pas y aller de lui-même ; il attend un tour où quelqu'un le nomme. ## Équiper les agents d'un projet Un [agent de projet](/fr/platform/agents/create) porte son propre équipement, choisi dans le menu d'équipement du dialogue de l'agent. La liste y suit la visibilité du **projet**, pas la tienne : les skills de toute l'organisation, plus les skills d'équipe partagés avec l'une des équipes du projet. Un projet ouvert à toute l'organisation ne voit que les skills d'organisation, et les anciens skills privés n'apparaissent jamais — un agent de projet tourne pour chaque membre du projet, son équipement ne doit donc jamais embarquer quelque chose que seule son autrice pouvait voir. La même règle tient à l'exécution. Un run de tâche charge les skills de l'agent en tant que projet ; une automatisation au niveau de l'organisation charge en tant qu'organisation. Un skill qui devient invisible pour ce périmètre fait échouer le run en le nommant, plutôt que de tourner sans lui en silence — un équipement choisi qui manque sans bruit est pire qu'un run raté. ## Les skills dans une session sandbox Quand un tour s'exécute dans une sandbox, les bundles équipés n'arrivent pas par un appel d'outil. Ils sont chargés dans la session comme des fichiers, dans la disposition que le runtime sait déjà découvrir : le harness les trouve comme il trouverait un skill sur n'importe quelle machine où il travaille. Une règle gouverne les collisions : le dépôt gagne. Si le dépôt extrait embarque un skill sous le même slug qu'un skill que Tale chargerait, Tale retient sa copie et la version du dépôt reste. Un dépôt peut toujours remplacer ce que la plateforme apprendrait sinon à l'agent, et la session ne tient jamais deux bundles qui revendiquent le même nom. ## Skill ou instructions | Prends … quand | Skill | Instructions d'agent | | --------------------------------------------------------------- | ----- | -------------------- | | Le motif se répète sur plusieurs agents | ✓ | | | Le comportement a besoin de fichiers de référence avec la prose | ✓ | | | Le comportement est la voix de cet agent-là | | ✓ | | Une modification doit atteindre tous ceux qui l'utilisent | ✓ | | | Les instructions de l'agent tiennent encore sur un écran | | ✓ | Les instructions sont la bonne forme pour le caractère propre d'un agent. Un skill est la bonne forme dès que le même comportement apparaît chez un deuxième puis un troisième agent et que garder leurs instructions au pas commence à te coûter. ## Où cela s'inscrit Équiper est la moitié étroite des skills : la bibliothèque décide de ce qui existe et de qui le voit ; le dialogue d'agent d'un projet et les nœuds agent d'une automatisation décident où cela sert — toujours à travers la visibilité du projet ou de l'organisation elle-même. Garde les listes d'équipement courtes, préfère remplacer un bundle plutôt que le cloner, et laisse un dépôt remplacer ce que la plateforme chargerait quand un agent travaille dedans. L'autre moitié de l'histoire — écrire une `SKILL.md`, téléverser un dossier, partager un bundle — c'est la [bibliothèque de skills](/fr/platform/workspace/skills). # Créer un agent Source: https://tale.dev/docs/fr/platform/agents/create Ce parcours va d’un dialogue vide à un agent que tes collègues peuvent choisir. À l’arrivée, tu as une persona qui connaît son domaine, dispose des outils pour agir sur ce qu’elle lit, et reste joignable depuis n’importe quelle conversation de ton organisation. Compte une quinzaine de minutes. L’exemple fil rouge est un agent de tri du support, celui-là même que présente [Concepts d’agent](/fr/platform/agents/concepts). Remplace-le par ton propre domaine sans hésiter : aucune étape ne dépend de l’exemple. ## Avant de commencer Deux choses doivent être en place : - Ton organisation dispose d’au moins un accès fournisseur sous **Paramètres > Fournisseurs**. L’agent lui-même ne nomme aucun modèle — c’est celui qui envoie le message qui le choisit dans le composer — mais le composer n’a rien à proposer tant qu’aucun accès n’existe. En Cloud, il y en a un par défaut ; en auto-hébergement, suis [Configuration → fournisseurs](/fr/self-hosted/configuration/providers). - Tu as ici le rôle Editor ou plus. Vérifie sur [Membres et rôles](/fr/platform/admin/members-and-roles) si tu as un doute. ## Étape 1 — Le nommer et décider qui le voit Ouvre **Agents** dans la barre latérale et crées-en un. Le dialogue demande un **Nom** — l’identifiant unique utilisé dans les liens et l’API, impossible à changer ensuite, donc parlant et en minuscules, `support-triage` plutôt que `agent2` — puis un **Nom affiché** sous lequel l’équipe le rencontre et une courte **Description**. Valide, et l’éditeur s’ouvre sur **Général**. **Général** porte l’identité : le nom affiché, la description, une icône et la **visibilité** de l’agent. Garde-le privé tant que tu le façonnes, et toi seul l’atteins ; partage-le avec l’organisation, et chaque membre peut le choisir dans le composer. Un agent privé enregistre un propriétaire, en l’occurrence toi : un agent que personne ne possède et que personne ne voit ne serait joignable par personne. ## Étape 2 — Écrire les instructions Ouvre **Instructions**. Le champ est du markdown simple, plafonné à 20 000 caractères, et il est placé en tête de chaque tour auquel l’agent répond. Trois conseils de terrain : - **Commence par la voix.** Un paragraphe qui dit qui est l’agent, à qui il répond et sur quel ton. Le modèle en fait le signal le plus fort de tout le fichier. - **Nomme explicitement les cas de refus.** Trois ou quatre phrases sur ce que l’agent ne fait pas, et sur ce qu’il répond quand il refuse. - **Résiste à tout spécifier.** De longues instructions se diluent dans les longues conversations. Si un comportement relève du code, appuie-toi sur un outil ; s’il relève des documents, sur la portée des connaissances ; s’il se répète d’un agent à l’autre, sur un skill. Les instructions se traduisent par langue, au même titre que le nom affiché et la description : un lecteur français obtient ainsi un agent briefé en français, plutôt qu’un briefing anglais qui répond en français. ## Étape 3 — Accorder outils et skills Passe sur **Outils**. Les outils sont des interrupteurs individuels regroupés en cartes de catégorie — contacts, produits, fichiers, connaissances, automatisations et le reste — et chacun que tu accordes élargit ce que l’agent peut lire ou modifier en ton nom. Accorde le plus petit ensemble qui fait le travail et laisse le reste éteint. Les connectors connectées et les automatisations de l’organisation figurent dans la même liste : en lier une revient exactement à accorder un outil de la plateforme. <Frame caption="Le catalogue d’outils — une carte par catégorie, chacune comptant combien de ses outils l’agent a reçus."> ![L’onglet Outils de l’éditeur d’agent, défilé jusqu’aux cartes de catégorie, avec Connaissances à trois outils cochés sur quatre et Fichiers à sept sur sept, tandis que Conversations, Discussions, Analytique et Tâches et projets n’ont rien d’accordé.](/images/platform/agent-editor-tools.webp) </Frame> <Note> **Exécuter du code** lance des scripts dans une sandbox et relève de la [politique d’exécution de code](/fr/platform/admin/governance/run-code-policy) de l’organisation : l’interrupteur accorde l’outil, la politique décide de ce qu’une exécution a réellement le droit de faire. </Note> Ouvre ensuite **Skills** et lie les bundles que cet agent doit pouvoir déplier, dix au plus. Un skill est un paquet de connaissances issu de la [bibliothèque de skills](/fr/platform/workspace/skills) de l’organisation : lie ici le bundle maison sur le ton des réponses, et l’agent de tri formulera comme tous les autres. Laisse la liste vide et il ne déplie rien. ## Étape 4 — Cadrer ses connaissances Passe sur **Connaissances**. Un seul réglage décide quel corpus la recherche de l’agent a le droit de lire : les **documents** téléversés par l’organisation, les pages **web** récupérées pour son compte, **tout** cela fusionné, ou **rien**, auquel cas aucune recherche ne lui est proposée. La recherche ne part que si l’agent la juge utile : rien n’est injecté dans une réponse sans qu’il l’ait demandé. Resserre la portée quand tu le peux. Tout ce qui est dans le périmètre se dispute la pertinence à chaque question, et un agent pointé sur les documents qui comptent répond mieux qu’un agent pointé sur tout ce que possède l’organisation. ## Étape 5 — Enregistrer et essayer Clique sur **Enregistrer**. Ouvre une nouvelle conversation, choisis l’agent, choisis un modèle dans le sélecteur du composer et envoie un message qui sollicite les connaissances et les outils que tu as accordés. Le modèle est ton choix à chaque tour : le même agent peut donc traiter une question bon marché sur un petit modèle et une question difficile sur un grand, sans la moindre modification. S’il répond comme tu l’as écrit, c’est terminé. Sinon, le bouton **Historique** en haut à droite de l’éditeur conserve chaque version enregistrée et permet de comparer ou de restaurer — voir [Versions d’agent](/fr/platform/agents/versions). ## Dépannage - **L’agent n’apparaît pas dans le sélecteur du chat.** Sa visibilité est encore privée, donc toi seul le vois. Partage-le avec l’organisation depuis l’onglet **Général**. - **Les réponses ignorent les connaissances.** La portée est peut-être réglée sur rien, ou le document n’est pas encore indexé — ouvre-le depuis [Documents](/fr/platform/knowledge/documents) pour vérifier son état. - **Un skill lié ne sert jamais.** Un modèle va chercher un skill par sa description, donc une description vague est ignorée : dis ce qu’il fait et quand il s’applique. Un bundle marqué `disable-model-invocation` attend délibérément qu’on le nomme. - **Un appel d’outil est refusé à l’exécution.** Une politique de gouvernance filtre l’outil : l’agent a le droit de l’appeler, et l’exécution refuse. Regarde du côté de [Politiques et limites](/fr/platform/admin/governance/policies-and-limits). ## Où cela sert Créer un premier agent, c’est le moment où le reste de la plateforme se met à ressembler à Tale plutôt qu’à une fenêtre de chat générique. Tu as écrit une persona, tracé ses limites avec deux listes d’autorisation et une portée de connaissances, et laissé à la conversation toute question sur le déroulé d’un tour. La suite naturelle est [Agent avec connaissances](/fr/tutorials/editor/agent-with-knowledge) — même forme, mais avec un dossier de documents lié et la chaîne de citations exercée de bout en bout. Pour voir un agent confier une sous-tâche à un worker, parcours [Confier du travail à un worker](/fr/tutorials/editor/delegate-between-agents). # Outils d’agent Source: https://tale.dev/docs/fr/platform/agents/tools Les outils sont ce qu’un agent peut faire au-delà de produire du texte. Le modèle choisit quel outil appeler dans la liste que l’auteur de l’agent a accordée ; Tale exécute l’outil, rend le résultat, et le modèle continue. L’onglet **Outils** de l’agent est cette liste — un catalogue interrogeable d’interrupteurs par outil, groupés en cartes de catégorie. <Frame caption="Le catalogue d’outils — une carte par catégorie, chacune comptant combien de ses outils l’agent a reçus."> ![L’onglet Outils de l’éditeur d’agent, défilé jusqu’aux cartes de catégorie, avec Connaissances à trois outils cochés sur quatre et Fichiers à sept sur sept, tandis que Conversations, Discussions, Analytique et Tâches et projets n’ont rien d’accordé.](/images/platform/agent-editor-tools.webp) </Frame> ## Accorder les outils un par un Coche un outil et l’agent peut l’appeler dès la prochaine requête ; décoche-le et l’agent oublie qu’il existe. **Rechercher des outils…** filtre le catalogue par nom ou par catégorie, chaque ligne d’outil porte une description d’une ligne de ce qu’elle accorde, et la case d’en-tête d’une catégorie active tout le groupe d’un coup — le compteur à côté montre combien d’outils du groupe sont actifs. Les catégories reflètent les surfaces de la plateforme : **Contacts**, **Produits**, **Fournisseurs** et **Sites web** exposent des outils de lecture et de mise à jour sur des enregistrements structurés ; **Conversations** laisse l’agent lire et répondre ; **Connaissances** couvre la recherche et l’écriture de documents ; **Tâches et projets** inclut la propre liste de tâches de l’agent ; **Automatisations** lui permet de créer et lancer les automatisations de l’organisation ; **Web** contient la recherche sur les sites que ton organisation a ajoutés ; **Fichiers** couvre les opérations de l’agent sur les fichiers ; **Système** contient **Exécuter du code**, **Demander à un humain** et les autres outils d’exécution. Accorde le plus petit ensemble qui fait le travail — chaque outil activé élargit ce que l’agent peut lire ou changer en ton nom. **Exécuter du code**, dans le groupe **Système**, est le plus large de ces outils : il exécute du Python, du Node ou du bash dans la sandbox propre au chat, et travaille sur les fichiers que le chat tient déjà plutôt que dans une boîte vide. Un appel lance un extrait de code directement, lance un script que l’agent a déposé sous `/user/code/`, ou installe seulement des paquets — les paquets déclarés s’installent d’abord et persistent le reste du tour, et ce que l’exécution écrit sous `/user/output/` réapparaît comme fichier dans le chat. Les fichiers et dossiers que tu épingles avec `@` arrivent dans cette sandbox sous `/user/uploads/`, si bien que le code ouvre les vrais octets plutôt qu’un extrait de récupération. <Note> Un agent lance de lui-même un **worker** ciblé pour une sous-tâche — ce n’est pas un outil que tu actives ici. [Workers d’agent](/fr/platform/agents/delegation) couvre quand c’est le bon mouvement et comment un worker hérite d’un sous-ensemble borné des capacités de l’agent. </Note> ## L’accès web est un outil, pas un mode La recherche web est dans le catalogue comme le reste. Accorde-la et l’agent peut chercher quand il le juge bon ; laisse-la éteinte et il ne peut pas chercher du tout. Il n’y a aucun mode distinct à régler et aucune injection automatique de résultats dans une réponse — l’agent va chercher comme il va chercher n’importe quel autre outil. Ce qu’il parcourt, c’est le matériel que ton organisation a ajouté, pas un crawl ouvert ; gère donc les sources sous [Sites web](/fr/platform/knowledge/crawling). ## Les connectors et les automatisations sont aussi des capacités Une connector connectée et une automatisation publiée atteignent l’agent par cette même liste. Il n’y a pas de seconde surface de liaison en dessous : nomme la capacité dans la liste d’autorisation de l’agent, et il peut l’appeler sans avoir à citer l’connector ou l’identifiant de l’automatisation. Les [serveurs MCP](/fr/platform/connectors/mcp-servers) connectés arrivent par le même chemin, à travers les connectors de l’organisation. Une automatisation que seul un événement peut lancer est listée mais pas appelable. L’agent voit qu’elle existe et on lui dit clairement qu’elle tourne quand son événement se déclenche, pas sur demande — un agent qui ne voit pas les automatisations de l’organisation invente des détours au lieu de pointer sur celle qui fait déjà le travail. ## Comment les appels d’outil s’affichent Les appels d’outil apparaissent dans le chat comme des cartes repliées entre le message de l’utilisateur et la réponse. Déplier une carte révèle le nom de l’outil, les entrées émises par le modèle et le résultat rendu par Tale. Un appel d’outil échoué montre l’erreur ; le modèle réessaie en général avec une autre forme au tour suivant. ## Quand y recourir | Utilise les outils quand… | Utilise les connaissances quand… | | ----------------------------------------------------------------------- | -------------------------------------------------- | | L’agent doit agir — interroger, mettre à jour, exécuter, répondre | L’agent doit citer les documents qu’il a récupérés | | Les données sont des enregistrements structurés ou des systèmes vivants | Les données sont du contenu téléversé ou crawlé | ## Où ça se situe Les outils élargissent ce qu’un agent peut faire ; ils élargissent aussi la frontière de confiance, puisque l’agent peut désormais lire, écrire ou appeler des choses au nom de la personne qui l’emploie. Couple cette page avec la [politique run-code](/fr/platform/admin/governance/run-code-policy) si l’agent exécutera du code. Les instructions de l’agent restent l’endroit où vit la **politique** ; l’onglet **Outils** est l’endroit où vit la **surface**. # Versions d’agent Source: https://tale.dev/docs/fr/platform/agents/versions Chaque enregistrement d’un agent crée un instantané. Le bouton **Historique** en haut à droite de l’éditeur d’agent ouvre ces instantanés du plus récent au plus ancien ; comparer montre ce qui a changé, et restaurer remplace l’état courant par une version passée. Il n’y a pas de distinction entre enregistrement manuel et automatique — chaque changement persisté est une version. La mécanique est petite mais porteuse. La plupart des équipes ajustent les instructions d’un agent chaque semaine ; sans l’historique, l’équipe ne ferait jamais confiance aux modifications. ## Passer un changement en revue Ouvre l’agent et clique sur **Historique**. La liste montre **Version actuelle** en haut et chaque **Version de l'instantané** antérieure en dessous, avec l’auteur et l’horodatage sur chaque ligne. Choisis un instantané et **Comparer les modifications** passe en revue les différences entre lui et la version actuelle — les champs modifiés se surlignent — avant que tu décides de restaurer. ## Restaurer une version Depuis un instantané, clique sur **Restaurer cette version**. L’état courant de l’agent est remplacé par l’instantané — un toast confirme **Agent restauré depuis l'historique** — et la restauration atterrit sur la frise comme sa propre entrée, donc les restaurations s’additionnent, elles ne détruisent rien. Les chats déjà en cours sur la version précédente y restent jusqu’à leur fin ; la version restaurée s’applique à partir du chat suivant. ## Ce qui est versionné Le versionnage couvre la configuration de l’agent : ses textes d’affichage et sa description, ses instructions, les listes d’autorisation d’outils et de skills, la portée des connaissances, sa visibilité et ses métadonnées. Il n’atteint pas ce que l’agent se contente de désigner. Remplacer un document depuis lequel il récupère change sa réponse sans incrémenter sa version, et remplacer un bundle de skill qu’il lie aussi — la liaison nomme un slug, donc la configuration propre de l’agent reste inchangée alors que son comportement, non. Pour auditer l’un comme l’autre, voir [Journaux d’audit](/fr/platform/admin/governance/audit-logs). ## Où ça se situe Les versions sont le filet de sécurité de l’agent pour la même raison que git est celui du code : tout ce qui est enregistré est récupérable. La page à lire en regard est [Journaux d’audit](/fr/platform/admin/governance/audit-logs) — elle couvre la piste qui-a-fait-quoi à l’échelle de l’organisation ; l’Historique couvre la piste qu’était-ce, agent par agent. # Concepts d’agent Source: https://tale.dev/docs/fr/platform/agents/concepts C’est vers un agent que Tale se tourne quand la même question ne cesse de revenir. Il s’agit d’une **persona** plutôt que d’un environnement d’exécution : il dit qui répond — un nom, des instructions, ce qu’il a le droit de solliciter et qui dans l’organisation peut s’en servir — et rien sur la façon dont un tour s’exécute. Les éditeurs et les développeurs les construisent, tous les membres les utilisent. Cette page te donne le modèle mental que le reste du chapitre présuppose. Lis-la une fois avant de construire ton premier agent, puis reviens-y quand tu ne sais plus si le comportement que tu veux changer tient aux instructions, aux outils, aux skills ou à la portée des connaissances. Tu préfères regarder d’abord ? L’épisode 4 construit un agent de bout en bout en moins de trois minutes, sous-titres compris. <Video src="/videos/fr/tutorials/ep4-agent/ep4-agent.fr.mp4" poster="/videos/fr/tutorials/ep4-agent/ep4-agent.fr.webp" captions="/videos/fr/tutorials/ep4-agent/ep4-agent.fr.vtt" lang="fr" title="Épisode 4 — Ton premier agent" caption="Épisode 4 — Ton premier agent (2:42)"> </Video> ## Ce que porte un agent **L’identité.** Le slug sous lequel l’agent est rangé, le nom affiché sous lequel les gens le rencontrent, une courte description de son objet, et au besoin des versions de ces textes par langue, pour qu’un lecteur allemand ou français tombe sur l’agent dans sa propre langue. Le slug est figé dès que l’agent existe ; le nom affiché, tu le changes chaque fois que le travail se déplace. **Les instructions.** La prose placée en tête de chaque tour auquel l’agent répond. Garde-la courte, tranchée et concrète : de longues instructions se diluent dans les longues conversations. Nomme la voix, les limites, et les cas où l’agent doit refuser. **Les outils et les skills.** Deux listes d’autorisation. Les outils nomment les capacités que l’agent peut appeler, et les outils de la plateforme, les connectors connectées et les automatisations de l’organisation figurent tous dans cette même liste. Les skills nomment les paquets de connaissances qu’il peut déplier, dix au plus. La même règle vaut pour les deux : laisse une liste intacte et l’agent n’est pas restreint, remplis-la et il s’en tient exactement à ce que tu as nommé. **La portée des connaissances.** Un seul réglage décide quel corpus la recherche de l’agent a le droit de lire : les documents propres à l’organisation, les pages récupérées pour son compte, les deux ensemble, ou rien du tout. La recherche ne part que lorsque l’agent la juge nécessaire, si bien que rien n’atterrit dans une réponse sans qu’il soit allé le chercher. **La visibilité.** `private`, et seul son propriétaire l’atteint ; `org`, et tous les membres l’atteignent. Un agent privé nomme un propriétaire, faute de quoi personne ne pourrait l’atteindre. ```mermaid flowchart LR I[Instructions] --> A((Agent)) T[Outils] --> A S[Skills] --> A K[Portée des connaissances] --> A A --> R[Réponse avec citations] ``` ## Ce dont l’agent ne décide pas Le modèle ne fait pas partie de l’agent. Ce choix appartient à qui compose le tour : le sélecteur du composer ne propose que des modèles — il s’ouvre sur **Auto** (Tale choisit un modèle par message, et la réponse enregistre lequel a tourné), avec chaque modèle servi en direct à portée d’épingle. Un agent qui épinglerait un modèle écraserait en silence le choix que quelqu’un vient de faire devant l’écran, alors il n’en porte aucun. Le même raisonnement écarte plusieurs réglages que tu pourrais chercher. Un agent de chat n’a ni type ni sélecteur de harness : savoir si le travail tourne sur un [harness](/fr/platform/agents/harnesses) de code se décide quand tu crées un **agent de projet** ou un nœud **agent** d’automatisation (les deux nomment le champ **Harness**), et certains accès fournisseur en imposent un. Il ne porte aucun délai d’exécution, parce qu’un plafond appartient à l’hôte qui exécute le tour et non à une persona. Il ne détient ni variables d’environnement ni identifiants propres — ceux-là vivent sur les fiches fournisseur de l’organisation, où ils se font tourner et auditer au même endroit. Et il ne livre aucune amorce toute faite, puisque le composer est le point d’entrée. ## Mis bout à bout — un agent de tri du support Un premier agent utile, c’est celui du tri du support : il lit la question entrante, répond à ce qu’il peut et transmet le reste. Les décisions : - Instructions : un paragraphe pour la voix, plus trois cas explicites où il refuse. - Outils : la recherche web et les outils de conversation. Pas d’exécution de code. - Skills : le bundle maison pour le ton des réponses, afin que la formulation soit la même partout. - Connaissances : limitées aux documents de l’organisation, le web collecté reste dehors. - Visibilité : `org`, pour que toute l’équipe support puisse le choisir dans le composer. La conversation se déroule ensuite ainsi : ton message arrive, les instructions cadrent la réponse, la recherche trouve les passages qui l’étayent, les outils accordés comblent les trous, et la réponse arrive avec ses citations. Passer la main à un spécialiste n’est pas un interrupteur : cela suit les relations de worker entre agents, décrites dans [Workers d’agent](/fr/platform/agents/delegation). ## Quand y recourir Un agent seul est la bonne forme tant que la conversation reste dans un domaine et une voix. Tourne-toi vers une [automatisation](/fr/platform/automations/concepts) quand le travail a des étapes fixes et que tu veux des validations ou une planification entre elles ; vers une simple conversation sans agent quand tu explores toi-même une réponse et que les réglages par défaut du modèle suffisent. | Choisis … quand | Agent | Conversation simple | Automatisation | | ----------------------------------------------------- | ----- | ------------------- | -------------- | | La même question revient | ✓ | | | | La voix ou les limites comptent | ✓ | | | | Il faut des validations ou un calendrier entre étapes | | | ✓ | | Tu explores une réponse une seule fois | | ✓ | | ## Construis-en un Un agent, c’est une identité, des instructions, deux listes d’autorisation, une portée de connaissances et une visibilité — change l’un d’eux et tu as changé son comportement, change-en trois et tu as un autre produit. Tout ce qui touche au déroulé d’un tour reste hors de la persona et se décide par conversation. La suite naturelle est [Créer un agent](/fr/platform/agents/create), qui parcourt cet éditeur tab par tab. # Génération d’images Source: https://tale.dev/docs/fr/platform/agents/image-generation Dans Tale, la génération d’images est un outil, pas une catégorie d’agent. Tout agent à qui `generate_image` est accordé peut produire une image dans le fil de sa réponse : demande-lui de créer, de dessiner ou de concevoir quelque chose, le modèle appelle l’outil, et l’image s’affiche dans la réponse comme le ferait une pièce jointe. Aucun mode dans lequel basculer d’abord, aucune persona spécialisée à choisir. Cette page traite de cet outil : ce qu’il fait, comment tu l’accordes ou le retiens, comment le résultat arrive dans la conversation, et ce qu’il coûte. La mécanique en dessous appartient au fournisseur — qualité, prix et vitesse varient beaucoup d’un modèle d’image à l’autre. ## L’outil generate_image `generate_image` prend une seule chose : un prompt décrivant l’image à produire. Ce prompt se suffit à lui-même, car le modèle d’image ne voit jamais la conversation — l’agent replie dans cette unique description tout ce que tu as dit du style, de l’ambiance, de la composition et des couleurs. Le résultat revient sous forme de fichier, s’affiche dans le fil, et le texte de l’agent s’enroule autour. Puisque c’est un outil ordinaire, tout ce qui vaut pour le reste de la surface d’outils vaut ici. Le modèle décide quand l’appeler à partir de la liste accordée à son agent, l’appel et son résultat apparaissent dans la conversation comme n’importe quel autre appel d’outil, et un agent à qui l’outil n’a jamais été accordé ne peut pas l’atteindre. ## L’accorder ou le retenir Ouvre l’onglet **Outils** de l’agent et accorde `generate_image` là où le travail implique des images ; laisse-le éteint pour un agent qui ne doit répondre qu’en texte. Il n’y a rien d’autre à régler — pas de paramètre image par agent, pas de persona réservée à l’image, pas de type dans lequel basculer un agent. Le modèle derrière l’image vient du même endroit que tous les autres : celui qui envoie le message le choisit dans le composer, plutôt que l’agent n’en épingle un. Si aucun fournisseur de l’organisation ne propose de modèle capable de produire des images, tu reçois un refus net plutôt qu’une approximation — c’est le signal pour qu’un admin en ajoute un sous [Fournisseurs](/fr/platform/admin/providers). ## Comment l’image arrive dans la réponse L’image produite s’affiche à côté du texte de l’agent et s’ouvre en grand quand tu cliques dessus. Le fichier est rangé avec les pièces jointes de la conversation et hérite des mêmes règles de conservation : une image générée est donc exactement aussi durable — et aussi supprimable — que ce que tu as toi-même téléversé dans ce fil. Comme l’image passe par un appel d’outil, elle s’audite comme tel : le prompt réellement envoyé par le modèle est visible dans l’appel, et c’est le plus souvent le moyen le plus rapide de comprendre pourquoi une image ne ressemble pas à ce que tu imaginais. ## Coût et budget Les modèles d’image coûtent plus cher par appel que les modèles de texte, parfois d’un ordre de grandeur. Les [Politiques et limites](/fr/platform/admin/governance/policies-and-limits) de l’organisation plafonnent la dépense par personne, par équipe et par agent, et atteindre un plafond se traduit par un message dans la conversation plutôt que par une image. La dépense apparaît dans l’[Analytique d’usage](/fr/platform/admin/governance/usage-analytics), dans les mêmes tableaux que l’usage texte. ## Où cela se place La génération d’images est une entrée dans une liste, et c’est tout l’intérêt : un agent qui doit dessiner reçoit `generate_image`, un agent qui ne doit pas ne le reçoit pas, et aucune partie de la persona n’a besoin d’être refaçonnée autour des images. Ce qui vieillit le plus vite ici, ce sont les noms de fournisseurs et de modèles — appuie-toi sur la liste vivante dans [Fournisseurs](/fr/platform/admin/providers) plutôt que sur des identifiants mémorisés, et sur [Outils d’agent](/fr/platform/agents/tools) pour le reste du catalogue. # Connaissances d’agent Source: https://tale.dev/docs/fr/platform/agents/knowledge Les connaissances, c’est ce qu’un agent peut retrouver et citer au moment de répondre. Sans elles il reste générique ; avec elles il répond à partir du matériel de ton organisation et montre d’où vient sa réponse. L’onglet **Connaissances** de l’agent porte une seule décision : quel corpus la recherche de cet agent a le droit de lire. Cette décision est plus petite qu’elle ne devait l’être auparavant, parce que la recherche elle-même n’est plus un mode que tu configures. Un agent cherche quand il juge en avoir besoin, et rien n’est injecté dans une réponse sans qu’il soit allé le chercher. ## Choisir une portée Quatre valeurs, un seul réglage : - **Documents** — les fichiers téléversés par l’organisation, et rien d’autre. - **Web** — les pages récupérées pour le compte de l’organisation, et rien d’autre. - **Tout** — les deux corpus, fusionnés en un seul classement. C’est ce qu’obtient un agent que personne n’a restreint. - **Rien** — aucune recherche n’est proposée à l’agent. Choisis-le quand son travail est de raisonner ou de rédiger et que des citations ne feraient que du bruit. Chaque corpus appartient à ton organisation : élargir la portée ne franchit donc jamais la frontière vers le matériel d’un autre client. Cela décide seulement de la part du tien vers laquelle l’agent est pointé. ## Restreindre à dessein Tout ce qui est dans la portée se dispute la pertinence à chaque question, et c’est pourquoi une portée étroite répond en général mieux qu’une portée large. Un agent pointé sur les documents que ton équipe entretient vraiment trouve le bon passage ; le même agent pointé en plus sur toutes les pages collectées doit d’abord battre le bruit. Choisis **Documents** quand la vérité vit dans des fichiers que tu contrôles et qu’une page web périmée serait un risque. Choisis **Web** quand le travail de l’agent porte sur ce qui est publié plutôt que sur ce qui est classé. Choisis **Tout** quand les deux comptent réellement et que tu préfères le rappel. Le matériel lui-même — ce qui est téléversé, collecté et indexé — se gère sous [Documents](/fr/platform/knowledge/documents) et [Sites web](/fr/platform/knowledge/crawling), pas ici : cet onglet ne fait qu’y pointer l’agent. ## Comment la recherche arrive dans la réponse Quand l’agent cherche, les citations se rattachent aux phrases qu’elles étayent — le survol montre la source, le clic l’ouvre. Un document dont l’indexation n’est pas terminée n’est pas encore trouvable : un agent qui semble ignorer une source évidente attend donc souvent l’index plutôt qu’il n’est mal réglé. ## Quand y recourir Les enregistrements structurés et les systèmes vivants sont des outils, pas des connaissances. Les frontières : | Prends… | Quand l’agent a besoin… | | ------------------------------------------------------------ | ------------------------------------------------------------------ | | Les connaissances (cet onglet) | De chercher et citer le matériel de l’organisation | | [Les outils](/fr/platform/agents/tools) | De contacts, produits, fournisseurs, sites web ou systèmes vivants | | [Les agents de projet](/fr/platform/projects/project-agents) | De connaissances limitées à un projet | ## Où cela se place Les connaissances d’agent répondent à une seule question : cet agent doit-il lire les documents de l’organisation, son web collecté, les deux, ou aucun. La section [Connaissances](/fr/platform/knowledge/overview) plus large est là où ces sources vivent et s’indexent ; cet onglet raccorde un agent à une tranche d’entre elles. Pour le parcours complet — téléverser, cadrer, demander, vérifier les citations — suis [Agent avec connaissances](/fr/tutorials/editor/agent-with-knowledge). # Développeur Source: https://tale.dev/docs/fr/platform/developer/overview Développeur est la surface en-app pour les personnes qui câblent Tale au reste de leur pile. Elle regroupe les quatre leviers qui laissent du code externe parler à Tale et Tale parler à du code externe : clés API pour la surface REST, tools personnalisés qui étendent la portée d’un agent, webhooks d’agent pour les déclencheurs entrants, et serveurs MCP pour le pont processus-externe. Les personnes de rôle Développeur voient ce menu ; les Membres et Éditeurs ne le voient pas. Cette vue d’ensemble nomme ce que couvre chaque page et pointe vers la référence plus profonde. Les utilisateurs de rôle Développeur atterrissent typiquement ici à leur premier jour, montent les identifiants et tools dont ils ont besoin, et reviennent quand ils étendent la pile — ajouter un nouveau serveur MCP, roter une clé, enregistrer un nouveau webhook. ## Ce que couvre Développeur La surface Développeur s’asseoit à côté du reste des paramètres de l’org mais avec une audience plus étroite. Elle suppose que tu sais ce qu’est une API REST, à quoi ressemble un webhook, et ce que fait un serveur MCP — les pages ne réexpliquent pas les concepts sous-jacents ; elles expliquent comment Tale les expose. La même surface dans les onglets Cloud et self-hosted ne diffère que par la forme de déploiement ; l’UI ici est identique. Les équivalents fichier-de-configuration de certaines de ces fonctionnalités (variables d’environnement, configs JSON pour tools personnalisés) vivent un onglet plus loin dans la documentation self-hosted. ## Pages dans cette section <CardGroup cols="2"> <Card title="Clés API" icon="key" href="/fr/platform/admin/api-keys"> Câbler un script, une tâche cron, ou un service interne à l’API REST de Tale. Partagée avec Admin sous Paramètres > Clés API. </Card> <Card title="Serveurs MCP" icon="server" href="/fr/platform/connectors/mcp-servers"> Enregistrer un processus externe protocole MCP et choisir quels de ses tools les agents de l’org peuvent appeler. </Card> <Card title="Tools d’agent" icon="wrench" href="/fr/platform/agents/tools"> Étendre le toolbelt d’un agent avec un tool personnalisé que les agents de l’org peuvent appeler. </Card> </CardGroup> ## Où cela s’inscrit Développeur est le pont entre Tale et le reste de la base de code que l’org fait tourner. La première lecture naturelle dépend de ce que tu viens câbler — pour sortant (quelque chose dans Tale appelle dehors) [Tools d’agent](/fr/platform/agents/tools) et [Serveurs MCP](/fr/platform/connectors/mcp-servers) ; pour entrant (quelque chose dehors appelle dans Tale) [Clés API](/fr/platform/admin/api-keys). # Plateforme Source: https://tale.dev/docs/fr/platform Plateforme est la référence produit canonique : chaque fonctionnalité visible par l’utilisateur dans Tale, identique pour Cloud et auto-hébergé. Les pages ici décrivent l’UI qu’on clique, le concept derrière l’UI, et les arbitrages entre fonctionnalités qui se ressemblent. La section est organisée par domaine, puis par fonctionnalité au sein d’un domaine. La plupart des lecteurs ne la lisent pas de bout en bout — ils atterrissent ici depuis une recherche ou un lien de tutoriel, et la page sur laquelle ils tombent doit répondre à la question qu’ils ont apportée. ## Domaines de fonctionnalités <CardGroup cols="2"> <Card title="Chat" icon="message-circle" href="/fr/platform/chat/overview"> Le point d’entrée quotidien — conversations, agents dans le chat, pièces jointes, mode arène, mode vocal, le volet canevas, partage. </Card> <Card title="Projets" icon="folder-open" href="/fr/platform/projects/overview"> Espaces partagés qui regroupent fichiers, instructions, conversations et agents liés au projet. </Card> <Card title="Agents" icon="bot" href="/fr/platform/agents/concepts"> Instructions, connaissances, outils, modèle — plus compétences, workers, versionnage et déclencheurs webhook. </Card> <Card title="Automatisations" icon="layout-grid" href="/fr/platform/automations/concepts"> Des paquets installables qui regroupent connectors, agents, compétences et un workflow — le catalogue, l’assistant d’installation, l’éditeur et les déclencheurs derrière chaque automatisation, et l’historique des runs qu’elle laisse. </Card> <Card title="Connaissances" icon="library" href="/fr/platform/knowledge/overview"> Documents, contacts, produits, fournisseurs, sites web — le modèle de données structurées que les agents citent. </Card> <Card title="Approbations" icon="check-check" href="/fr/platform/approvals/concepts"> Cartes inline, points dans les workflows et le pool d’approbateurs qui garde les humains dans la boucle. </Card> <Card title="Bibliothèque de skills" icon="list-plus" href="/fr/platform/workspace/skills"> Des bundles d’instructions réutilisables que tu gardes privés ou partages avec toute l’organisation. </Card> <Card title="Modèles" icon="cpu" href="/fr/platform/models"> Le catalogue de modèles derrière chaque sélecteur — étiquettes de capacité, valeurs par défaut et la liste livrée. </Card> <Card title="Connectors" icon="plug" href="/fr/platform/connectors/overview"> Appariements SaaS tiers et serveurs MCP. </Card> </CardGroup> ## Prépare ta première journée Quatre entrées indexées par rôle cartographient les mêmes fonctionnalités du côté du lecteur — ce qu’un Membre, un Éditeur, un Développeur ou l’Administration touche réellement le premier jour. <CardGroup cols="2"> <Card title="Membre" icon="user" href="/fr/platform/member/overview"> Chat, connaissances, préférences personnelles — la surface que la plupart des gens utilisent dans la plupart des orgs. </Card> <Card title="Éditeur" icon="pencil-ruler" href="/fr/platform/editor/overview"> La surface de construction — agents, curation des connaissances, automatisations, projets. </Card> <Card title="Développeur" icon="terminal" href="/fr/platform/developer/overview"> Clés API, outils personnalisés, webhooks, serveurs MCP — brancher Tale à du code externe. </Card> <Card title="Administration" icon="shield" href="/fr/platform/admin/overview"> Paramètres de l’organisation, fournisseurs, branding, connectors et le sous-arbre gouvernance. </Card> </CardGroup> ## Où cela s’inscrit Plateforme est le puits gravitationnel — Cloud et auto-hébergé pointent tous deux ici pour la documentation des fonctionnalités, et chaque tutoriel cite des pages d’ici pour les concepts sous-jacents. La page à mettre en favori dès le premier jour est [Agents → concepts](/fr/platform/agents/concepts) — presque toutes les autres pages produit supposent le modèle mental à quatre boutons que cette page construit. # Concepts d’approbation Source: https://tale.dev/docs/fr/platform/approvals/concepts Une approbation est la couture entre l’initiative d’un agent et ton jugement : une carte qui apparaît dans le chat où l’action a été tentée, retenant cette action jusqu’à ce qu’une personne décide. Les agents proposent — une écriture de document, un appel d’API sortant, une exécution de workflow — et rien ne s’exécute tant que la carte est en attente. Le chat le dit explicitement : **Réponds à la demande en attente ci-dessus pour continuer**. Cette page est le modèle mental — ce qui déclenche une approbation, ce que la carte offre et ce qu’une décision laisse derrière elle. Les portes propres aux workflows vivent sur [Approbations dans les workflows](/fr/platform/automations/approvals-in-workflows) ; l’endroit où les exigences sont déclarées vit sur [Configurer les approbations](/fr/platform/approvals/configure). ## Ce qui déclenche une approbation Chaque carte vient d’un agent qui tente d’agir sur quelque chose qui survit à la conversation : - **Plans** — un agent propose un plan multi-étapes comme carte **Plan proposé** ; **Approuver et exécuter** le démarre. - **Écritures de documents** — une carte **Enregistrer dans les documents** retient les fichiers qu’un agent veut stocker ; rien n’atterrit dans le hub documentaire avant approbation. - **Écritures de connaissances** — une carte **Enregistrer dans la base de connaissances** retient un fait qu’un agent veut mémoriser à l’échelle de l’org. - **Appels d’connector** — une opération marquée comme exigeant une approbation (des écritures sortantes, typiquement) tient avec les paramètres exacts affichés. - **Outils MCP** — un outil que le serveur marque **Nécessite une approbation** demande avant de s’exécuter. - **Création, mises à jour et exécutions de workflows** — les portes côté workflow, couvertes dans [Approbations dans les workflows](/fr/platform/automations/approvals-in-workflows). ## Les décisions sur une carte Chaque carte porte le payload exact de l’action — le fichier, le fait, les paramètres — et deux décisions : approuver (le bouton nomme l’action, comme **Exécuter le workflow** ou **Approuver et exécuter**) ou rejeter. Les cartes d’connector ajoutent une troisième voie, **Suggérer des modifications** : décris ce qui ne va pas en texte libre et l’agent révise l’appel au lieu de l’abandonner. <Note> Les approbations se décident dans la conversation qu’elles interrompent — par la personne qui tient ce chat. Il n’y a ni boîte de réception d’approbations séparée ni routage vers un groupe d’approbateurs ; la personne pour qui l’agent travaille est la personne qui décide. </Note> ## Les états et la trace Une carte passe de **En attente** à **Exécution** puis **Terminé** — ou **Rejeté** — et garde son état résolu dans la transcription, si bien qu’un chat se relit comme le procès-verbal de ce qui a été autorisé. Chaque décision atterrit aussi dans le [journal d’audit](/fr/platform/admin/governance/audit-logs) avec l’acteur, l’action et l’horodatage. Les cartes résolues ne peuvent pas être rouvertes ; retenter signifie une proposition neuve et une carte neuve. ## Où cela s’inscrit Les approbations sont ce qui te laisse confier aux agents de vraies capacités — fichiers, API, workflows — sans céder le registre de qui a autorisé quoi. Lis ensuite [Configurer les approbations](/fr/platform/approvals/configure) pour voir où une exigence s’active, et [Approbations dans les workflows](/fr/platform/automations/approvals-in-workflows) pour les portes autour des workflows. # Configurer les approbations Source: https://tale.dev/docs/fr/platform/approvals/configure Les exigences d’approbation dans Tale sont déclaratives : chaque capacité porte son propre drapeau disant si un agent doit d’abord demander, et le drapeau voyage avec l’connector ou le serveur qui fournit la capacité. Rien n’est à configurer pour que les valeurs par défaut soient justes — cette page montre où vit chaque drapeau, quelles écritures demandent d’elles-mêmes et comment changer cela pour ton organisation. Le modèle de ce qu’est une carte d’approbation et de qui la décide vit sur [Concepts d’approbation](/fr/platform/approvals/concepts). Ce qui suit est la surface de configuration, capacité par capacité. ## Opérations d’connector Chaque connector déclare ses opérations, et chaque opération porte son propre drapeau d’approbation. Ouvre **Paramètres > Connectors**, clique sur une connector, et sa liste d’opérations badge celles marquées **Nécessite une approbation** — pour les connecteurs livrés, c’est le versant écriture : envoyer du courrier, poster des messages, créer des tickets. Les lectures s’exécutent sans carte ; les écritures marquées tiennent dans le chat avec leurs paramètres exacts jusqu’à ce que quelqu’un approuve. Le drapeau n’est pas un réglage séparé qu’un administrateur bascule. Chaque action déclarée par un connecteur porte un effet — `read` ou `write` — et c’est le versant écriture que la politique d’approbation retient. Cela garde les deux honnêtes l’un envers l’autre : une action ne peut pas passer discrètement d’une lecture à une écriture sans changer aussi ce pour quoi elle doit demander. ## Quelles écritures demandent Une carte mérite l’attention de quelqu’un quand l’écriture **quitte ton locataire**. C’est là que passe la ligne par défaut : - **Les écritures vers des systèmes externes demandent** — envoyer du courrier, poster dans Slack, ouvrir un ticket GitHub, écrire sur un partage WebDAV. Ces connecteurs détiennent tes identifiants et agissent sur des systèmes qui n’appartiennent pas à Tale. - **Les écritures sur la surface de Tale ne demandent pas** — déplacer une tâche, la commenter, déposer un document dans le projet, lancer un script dans ton propre bac à sable. Elles sont déjà bornées par les droits de qui les exécute, l’automatisation qui les effectue a passé son gate de déploiement, et chacune figure dans la trace de l’exécution et dans le journal d’audit. Sans cette ligne, une seule exécution empile une demi-douzaine de cartes pour sa propre comptabilité — « passer cette carte à En cours » — et enterre la seule carte qui demandait vraiment un humain. ## Déplacer la ligne pour ton organisation Les deux directions se configurent par organisation, dans `governance/approval-policy.yml` sous ton répertoire de configuration. Chaque règle nomme **une** cible — un connecteur entier, ou une action précise sous la forme `<connecteur>.<action>` — et la règle la plus spécifique gagne : ```yaml rules: # Cette équipe relit chaque tâche que le desk touche. - connector: task decision: require_approval # Le mail de rapport nocturne est de confiance ; les autres actions mail demandent toujours. - action: imap-smtp.send decision: auto_approve ``` Une opération déjà en attente sur une carte garde sa carte même si la politique est assouplie ensuite — une décision appartient à l’opération pour laquelle elle a été demandée, et une exécution en pause n’est donc jamais laissée en plan. ## Outils MCP Le manifeste d’un serveur MCP marque lesquels de ses outils exigent un accord. Ouvre **Paramètres > API > MCP**, déplie un serveur, et sa liste **Outils découverts** badge chaque outil marqué avec **Nécessite une approbation** — ceux-là demandent dans le chat chaque fois qu’un agent les appelle. Le drapeau vient de l’auteur du serveur ; connecter un serveur, c’est accepter son contrat d’outils, donc relis la liste avant d’en activer un. [Serveurs MCP](/fr/platform/connectors/mcp-servers) couvre l’enregistrement. ## Garde-fous d’écriture intégrés Certaines portes sont livrées actives et ne se configurent pas, parce que l’action est lourde de conséquences par nature : - **Écritures de documents** — un agent qui enregistre des fichiers dans le hub documentaire demande toujours (**Enregistrer dans les documents**). - **Écritures de connaissances** — un agent qui stocke un fait à l’échelle de l’org demande toujours (**Enregistrer dans la base de connaissances**). - **Création, mises à jour et exécutions de workflows** — un agent qui construit, modifie ou démarre un workflow demande toujours ; voir [Approbations dans les workflows](/fr/platform/automations/approvals-in-workflows). <Note> Le levier pour celles-ci n’est pas le drapeau d’approbation mais la capacité elle-même : un agent sans les outils de documents ou de workflows ne produit jamais la carte. Taille le [jeu d’outils](/fr/platform/agents/tools) de l’agent pour retirer la capacité entièrement. </Note> ## Vérifier ce qui demandera Avant de mettre un agent devant de vrais systèmes, lis ses capacités comme le ferait un approbateur : la liste d’opérations de l’connector pour les écritures marquées, les **Outils découverts** du serveur MCP pour les outils marqués, et l’onglet outils de l’agent pour savoir s’il tient des outils d’écriture tout court. Le [journal d’audit](/fr/platform/admin/governance/audit-logs) enregistre ensuite chaque décision que produit l’installation. ## Où cela s’inscrit Configurer ici, c’est distribuer — les drapeaux vivent avec les connectors et les serveurs qui possèdent les capacités. Lis [Concepts d’approbation](/fr/platform/approvals/concepts) pour le cycle de vie de carte que ces drapeaux produisent, et [Outils d’agent](/fr/platform/agents/tools) pour le versant capacité de la même frontière. # Catalogue de modèles Source: https://tale.dev/docs/fr/platform/models Chaque sélecteur de modèle dans Tale propose la même chose — les modèles que ton organisation peut réellement joindre à cet instant. Cet ensemble se construit par fournisseur, à partir de la liste de modèles du connecteur et des identifiants que tu détiens en face, puis se resserre selon tes règles de gouvernance. Cette page explique d’où vient chaque morceau, pour que « pourquoi ce modèle manque-t-il » ait une réponse sur laquelle agir plutôt qu’une hypothèse. ## Le catalogue appartient au fournisseur Il n’existe pas de liste globale unique. Chaque connecteur de fournisseur déclare d’où viennent ses modèles, et le badge de sa section sous **Paramètres > Fournisseurs IA** nomme la source : - **Catalogue intégré** — la liste est livrée avec la plateforme et évolue avec elle. C’est le cas d’OpenAI, Anthropic, Gemini, DeepSeek, Moonshot AI (Kimi), Qwen (Alibaba), SpaceXAI et Z.ai (GLM). - **Catalogue OpenRouter** — récupéré depuis le catalogue d’OpenRouter et normalisé à l’arrivée. C’est le cas d’OpenRouter, ce qui explique que sa liste soit de loin la plus longue. - **Endpoint models du fournisseur** — récupéré depuis la liste de modèles du fournisseur lui-même. C’est le cas de Vercel AI Gateway. - **Pas de catalogue** — le fournisseur ne publie rien qui vaille la peine d’être livré, donc les modèles viennent de chaque identifiant. C’est le cas d’Azure OpenAI et de Nous Portal (Hermes). Le compte à côté du badge est la liste actuelle de ce connecteur. Il ne dit rien de ce que ton organisation peut appeler, seulement de ce que le fournisseur propose. ## Ce qui décide de la disponibilité Un modèle atteint un sélecteur après avoir franchi deux barrières, dans cet ordre. La première, ce sont les identifiants. Un connecteur sans identifiant est un fournisseur que tu ne peux pas appeler, catalogue ou pas. Un identifiant dont les **Modèles autorisés** sont vides offre tout le catalogue de son connecteur ; un identifiant avec une liste n’offre que les modèles qui y figurent. L’union sur tous les identifiants actifs est ce que ton organisation peut techniquement joindre. La seconde, c’est la gouvernance. Les règles d’accès aux modèles sous [Contenu et modèles](/fr/platform/admin/governance/content-models) autorisent ou bloquent des modèles par organisation, équipe, rôle ou personne, et s’appliquent par-dessus la première. Un modèle qui franchit les identifiants mais pas la règle reste invisible pour ce périmètre, et la résolution refuse de s’y lier même si un agent l’a épinglé. <Note> Quand un modèle attendu est absent, parcours les deux barrières dans cet ordre. Vérifie qu’un identifiant existe pour son fournisseur et qu’il est actif, regarde si la liste de cet identifiant l’exclut, puis contrôle les règles d’accès aux modèles pour le périmètre depuis lequel tu regardes. Presque tous les « modèles manquants » sont l’un de ces trois cas. </Note> ## Les fournisseurs sans catalogue livré Certains fournisseurs ne peuvent pas publier une liste que Tale pourrait livrer. Pour ces connecteurs, les **Modèles autorisés** d’un identifiant cessent d’être un filtre et deviennent la disponibilité elle-même : le champ accepte du texte libre, tu y saisis des ids de modèles séparés par des virgules, et ces ids sont les seuls modèles que cet identifiant peut joindre. <Info> Sur Azure OpenAI, ces ids sont les noms de déploiement que tu as choisis dans ta ressource Azure, pas les noms publics du fournisseur. Un identifiant dont la liste est vide n’y rend aucun modèle disponible, ce qui est la cause habituelle d’un connecteur Azure qui a l’air configuré et ne propose rien. </Info> ## Actualiser un catalogue en ligne Les catalogues récupérés chez un fournisseur sont mis en cache et ne se rafraîchissent que sur demande. La carte **Catalogues de modèles**, en haut de **Paramètres > Fournisseurs IA**, porte un bouton **Actualiser les catalogues** qui recharge chaque source en ligne et rend une ligne par connecteur : le nombre de modèles trouvés, ou l’erreur qui l’a arrêté. Il n’y a ni synchronisation en arrière-plan ni tâche planifiée, donc un modèle publié ce matin apparaît à la prochaine actualisation et pas avant. Quand chaque connecteur de ton instance livre un catalogue intégré, il n’y a rien à récupérer et la carte le dit. ## Choisir un modèle Le chat s’ouvre sur **Auto** : Tale lit chaque message et lui choisit un modèle — une heuristique légère sur la longueur, le code, le sujet et les documents joints, jamais un appel IA de plus — puis exécute exactement ce modèle et l’inscrit sur la réponse, où les détails du message le nomment. Choisis plutôt un modèle dans le menu et le choix reste le tien jusqu’à ce que tu le rendes à Auto ; épingler un modèle est le remède quand la sélection automatique est lente, chère ou mal adaptée. Partout ailleurs, le modèle est toujours nommé explicitement : sur un agent, sur toute étape de workflow qui appelle un modèle, et sur chaque requête API. Là, rien ne route à ta place — pas de sélection selon la complexité de la tâche, pas de paliers de qualité. Et nulle part — chat compris — il n’y a de bascule silencieuse : le modèle qui commence une réponse est celui qui la termine, ou tu vois l’erreur. Une exécution reste reproductible et une facture attribuable, parce que le modèle qui a tourné est enregistré, jamais deviné. <Tip> Quand plusieurs modèles pourraient plausiblement faire le travail, le [Mode Arène](/fr/platform/chat/arena-mode) envoie le même prompt à plusieurs d’entre eux côte à côte, ce qui transforme le choix en comparaison plutôt qu’en intuition. </Tip> ## Où cela s’inscrit Le catalogue est la moitié visible de la configuration des fournisseurs : ce qu’un Administrateur connecte sous [Fournisseurs IA](/fr/platform/admin/providers) est ce que tout le monde voit ici dans un sélecteur. Élargir l’ensemble revient à ajouter un identifiant ou à relâcher une liste ; le rétrécir revient à poser une liste de modèles autorisés ou une règle d’accès sous [Contenu et modèles](/fr/platform/admin/governance/content-models). Pour savoir comment le modèle se place à côté des instructions, des connaissances et des outils dans un agent, lis [Concepts d’agent](/fr/platform/agents/concepts). # Variables d’environnement et secrets Source: https://tale.dev/docs/fr/platform/member/environment Variables d’environnement et secrets est ton magasin personnel de variables que Tale injecte dans chaque sandbox que tu lances dans cette organisation. Quand un [agent de projet ou un nœud agent d’automatisation](/fr/platform/agents/harnesses) démarre un tour sur harness, chaque entrée que tu as enregistrée ici est posée dans l’environnement avant que l’agent tourne, pour qu’une commande lancée par l’agent — ou l’agent lui-même — puisse la lire. Sers-t’en quand le travail réclame quelque chose de toi que personne d’autre ne doit détenir : un jeton API personnel pour un service que l’organisation n’a pas connecté, un point d’accès qui diffère chez toi, une clé attachée à ton propre compte. C’est une page de niveau membre que chaque rôle peut ouvrir, et les entrées sont cantonnées à toi et à l’organisation actuelle, donc elles ne fuient jamais vers tes coéquipiers et ne te suivent jamais dans une autre org. Cette page couvre les deux types d’entrée, comment les secrets sont protégés, les règles qu’un nom et une valeur doivent respecter, et où les valeurs finissent. <Frame caption="Paramètres > Environnement — les entrées enregistrées, chacune avec l’interrupteur Secret qui décide si sa valeur peut être relue."> ![La page de paramètres Environnement listant trois entrées enregistrées — ANALYTICS_ORG et CRM_BASE_URL avec leurs valeurs en clair, et CRM_API_TOKEN masquée en points avec sa case Secret cochée — au-dessus de l’action Ajouter une variable.](/images/platform/settings-environment.webp) </Frame> ## Variables et secrets Ouvre **Paramètres > Environnement**. **Ajouter une variable** ouvre une boîte de dialogue pour une nouvelle entrée, avec la liste de ce que tu as enregistré en dessous. Chaque entrée est un **Nom** et une **Valeur**, plus une bascule **Secret** qui décide comment la valeur est stockée et affichée. Une variable simple est stockée telle quelle et réaffichée en entier dans la liste — utilise-la pour la configuration non sensible que l’agent attend, un nom de région ou un endpoint. Un **secret** est chiffré dès l’instant où tu l’enregistres et devient en écriture seule à partir de là : la liste montre `••••••••` à la place de la valeur, et il n’y a aucun moyen de la relire. Active la bascule pour tout ce qui est sensible — une clé API, un jeton OAuth, un mot de passe. Le compromis, c’est que tu ne peux pas revoir la valeur d’un secret plus tard, donc si tu n’es pas sûr qu’elle soit bonne, supprime-le et ajoute-le à nouveau plutôt que de chercher un bouton d’affichage qui n’existe pas. Chaque ligne porte le nom, la valeur ou son masque, et la date de dernière mise à jour. L’icône corbeille demande confirmation avant de retirer l’entrée, car en supprimer une la sort de chacune de tes sandboxes au prochain lancement. ## Noms, valeurs et limites Un **nom** doit commencer par une lettre ou un tiret bas et ne contenir que des lettres, des chiffres et des tirets bas — la forme d’une variable d’environnement ordinaire, `MY_API_KEY` plutôt que `my-api.key`. Les noms sont plafonnés à 128 caractères et les valeurs à 8 192, ce qui laisse la place pour un long jeton ou une clé multiligne mais pas pour un fichier. Tu peux garder jusqu’à 100 entrées. Tale rogne les espaces au début et à la fin d’une valeur quand tu l’enregistres, parce qu’un saut de ligne égaré venu d’un copier-coller est la cause la plus fréquente d’un jeton qui échoue silencieusement. Il ne rogne pas les espaces ni les sauts de ligne _à l’intérieur_ de la valeur, mais il te prévient quand il en trouve : un identifiant n’en a normalement aucun, donc un blanc intérieur signifie d’ordinaire un jeton qui s’est replié sur plusieurs lignes dans ton terminal au moment du collage. L’avertissement ne bloque pas l’enregistrement — un secret réellement multiligne comme une clé privée PEM garde ses sauts de ligne — donc lis-le et décide. ## Comment les valeurs atteignent la sandbox Un secret ne voyage jamais en clair, sauf vers ta propre sandbox. Au repos il est chiffré dans le backend de Tale sous une clé que la plateforme détient, et la requête de liste ne renvoie que le masque, jamais le texte en clair. Quand un tour démarre, la plateforme déchiffre tes secrets et les pose, aux côtés de tes variables simples, dans l’environnement de ta sandbox pour ce lancement. Chaque fois qu’un secret est injecté pour un tour, cet accès est consigné dans le journal d’audit. Cette dernière étape est la frontière à comprendre : les valeurs atterrissent à l’intérieur de ton conteneur sandbox, donc c’est l’isolement de la sandbox — et non le magasin de secrets — qui se tient entre tes identifiants et tout ce qui tourne là. C’est le même fonctionnement que le jeton GitHub dans la sandbox, et c’est pour cela que ces entrées sont cantonnées à toi seul plutôt que partagées avec l’org. Ce qui ne vient pas d’ici, c’est l’identifiant avec lequel un tour atteint son modèle. Celui-là appartient aux fiches fournisseur de l’organisation, sous [Fournisseurs](/fr/platform/admin/providers), où il se fait tourner et auditer au même endroit — un agent ne détient aucune clé propre, et cette page non plus à sa place. Garde ces entrées pour ce dont ton propre travail a besoin, et laisse l’identifiant du modèle là où l’organisation peut le gouverner. ## Où cela s’inscrit Variables d’environnement et secrets est l’unique page de niveau membre qui atteint la sandbox plutôt que le chat — c’est par elle que tes propres clés et ta configuration parviennent au travail que tu lances, sans qu’un Éditeur ou un Admin ne les pose à ta place. Lis-la en parallèle de [Harnesses](/fr/platform/agents/harnesses), qui couvre ce que le conteneur détient d’autre et ce qu’il a le droit d’atteindre. Pour le reste de tes réglages personnels — nom d’affichage, mot de passe, instructions personnalisées — vois [Préférences](/fr/platform/member/preferences). # Installer en tant qu'app Source: https://tale.dev/docs/fr/platform/member/install-as-app Tale est livré comme Progressive Web App. L'installer pose une icône dans ton dock ou sur ton écran d'accueil, lance Tale dans sa propre fenêtre sans l'habillage du navigateur, et garde la même session que tu avais dans le navigateur. Il n'y a pas de build natif séparé à télécharger et pas d'extension à installer — la même URL avec laquelle tu te connectes est la même app, dans une coque autonome. Cette page couvre les trois endroits où tu déclenches l'installation : la ligne **Installer l'app** dans ton menu de profil sur les navigateurs Chromium, l'étape de la feuille de partage sur iOS Safari, et la bannière d'installation qu'Android Chrome affiche de lui-même. Une fois installé, Tale se comporte de manière identique ; l'installation ne change que l'habillage autour. ## Le raccourci du menu de profil Sur Chrome, Edge, Brave, Arc et les autres navigateurs Chromium, le menu déroulant de profil de Tale porte une ligne **Installer l'app** quand le navigateur est prêt à installer. Ouvre le menu depuis ton avatar en haut à droite, fais défiler après le sélecteur de thème et le sélecteur de langue, et clique **Installer l'app**. Le navigateur ouvre sa confirmation d'installation native ; accepte-la, et Tale atterrit dans ton dock (macOS), ta barre des tâches (Windows) ou ta liste d'apps (ChromeOS) en une seconde ou deux. La ligne n'est là que quand le navigateur a tiré son événement `beforeinstallprompt` et que l'app n'est pas déjà installée. Les navigateurs qui ne tirent pas cet événement — Firefox, Safari, tout en fenêtre privée — n'affichent pas la ligne, donc le menu reste plus court d'un élément plutôt que de promettre ce qu'il ne peut pas livrer. ## iOS et iPadOS iOS Safari ne tire pas `beforeinstallprompt`, donc la ligne **Installer l'app** n'apparaît pas dans le menu. Le chemin d'installation vit dans la feuille de partage de Safari à la place. Ouvre Tale dans Safari, tape l'icône de partage dans la barre d'outils, fais défiler jusqu'à **Sur l'écran d'accueil**, et confirme. Tale apparaît sur ton écran d'accueil avec la même icône que la favicon du navigateur. Tape dessus, et Tale s'ouvre dans sa propre fenêtre — pas de barre d'adresse Safari, pas de barre d'onglets, pas de bouton retour au-delà de ce que Tale lui-même expose. Les notifications fonctionnent de la même manière que dans l'onglet du navigateur ; l'installation est la seule différence. Les autres navigateurs iOS — Chrome, Edge, Firefox sur iOS — sont Safari sous le capot. Ils n'ont pas leur propre entrée Sur-l'écran-d'accueil. Le chemin Safari est le seul chemin d'installation iOS qui produit une vraie app autonome. ## Android Android Chrome gère l'installation à deux endroits. Le premier est la même ligne **Installer l'app** dans le menu de profil de Tale, identique au flux desktop. Le second est la bannière d'installation propre à Chrome — une barre d'une ligne qui glisse depuis le bas de la page sur les sites qu'il considère installables. Tape **Installer** sur la bannière, confirme dans la feuille système, et Tale atterrit sur ton écran d'accueil. Si tu as écarté la bannière une fois, elle ne revient généralement pas avant un moment. Le raccourci du menu de profil continue à fonctionner que la bannière ait été affichée ou non. Les autres navigateurs Android — Firefox, Samsung Internet, Brave — ont chacun leur propre chemin d'installation dans le menu du navigateur, généralement étiqueté **Installer l'app** ou **Sur l'écran d'accueil**. ## Après l'installation Tale tournant dans une fenêtre PWA est le même Tale tournant dans un onglet de navigateur. La session, les chats, la base de connaissances, les agents — tout cela est la même surface. Les différences sont cosmétiques et petites : pas d'habillage navigateur autour de la fenêtre de l'app, une icône dans ton lanceur, et sur la plupart des plateformes la fenêtre se rappelle de sa taille et de sa position entre les lancements. La désinstallation suit la convention de la plateforme. Sur macOS, glisse l'icône hors du dock ; sur Windows, clic droit et désinstaller ; sur iOS et Android, appui long sur l'icône et retirer. La désinstallation efface la coque PWA mais pas la session — reconnecte-toi via le navigateur, et tes données sont là où tu les as laissées. ## Quand y recourir L'installation vaut le coup dès que tu te retrouves à ouvrir Tale chaque jour et que tu veux qu'il se sente comme une de tes apps plutôt que comme un de tes onglets. C'est aussi le bon mouvement quand tu veux la fenêtre de chat épinglée sur un bureau virtuel ou une fente Stage Manager que les onglets de navigateur ne respecteraient pas. Saute l'installation si tu te connectes depuis beaucoup de machines et préfères l'onglet du navigateur — Tale marche pareil dans les deux cas. La lecture voisine est [Vue d'ensemble Membre](/fr/platform/member/overview) — c'est la carte de ce que couvre le reste de la surface Membre une fois Tale posé dans ton dock. # Préférences Source: https://tale.dev/docs/fr/platform/member/preferences Les préférences sont les molettes qui t’appartiennent plutôt qu’à l’org. Ton nom est ce que voient agents et coéquipiers dans les chats et les approbations. Ta langue et ton thème te suivent entre les appareils. Tes mémoires sont des faits qu’un agent a proposés à ton sujet et que tu as validés, tenus à l’écart de tout ce que l’Administrateur ou l’Éditeur a posé au niveau de l’org. Cette page cartographie où vit chaque levier et ce qu’il change. La forme est volontairement à deux couches : le menu de profil (partout, à un clic de l’avatar) porte les bascules rapides ; **Paramètres > Compte** et **Paramètres > Personnalisation** portent les champs de compte plus profonds. Tout ici t’appartient — rien ne fuite vers d’autres membres ou d’autres orgs. ## Le menu de profil Clique ton avatar en haut à droite. Le menu déroulant s’ouvre avec ton nom, ton e-mail et la version de build actuelle. Sous l’en-tête se trouvent quatre contrôles rapides que voit chaque membre quelle que soit sa rôle : le sélecteur de **thème** (Système / Clair / Sombre), le sous-menu de **langue** (English, Deutsch, Français), la ligne **Installer l'app** quand le navigateur peut installer Tale en tant que PWA, et **Se déconnecter**. Le thème et la langue prennent effet immédiatement et persistent par appareil. Le menu porte aussi un sélecteur d’organisation quand tu appartiens à plus d’une org et un filtre d’équipe quand ton org actuelle a des équipes. Ce ne sont pas des préférences — ils changent ce que Tale t’affiche, pas la manière dont Tale se comporte. Sous le filtre d’équipe, **Paramètres utilisateur** ouvre **Paramètres > Compte**, la page couverte ensuite. ## Compte — nom, e-mail, mot de passe, double authentification Ouvre **Paramètres > Compte**. Trois sections siègent sur la page : **Profil**, **Sécurité** et **Authentification à deux facteurs**. La section Profil affiche d’abord ton **e-mail**, puis ton **nom** — l’e-mail suggère le nom que Tale propose, que tu peux modifier librement. Le nom s’édite en ligne ; la modification s’enregistre et se propage dans chaque chat et chaque approbation au prochain rendu. L’e-mail est en lecture seule — c’est avec lui que tu t’es connecté, et un changement passe par le support. Il n’y a pas de champ avatar sur la page ; Tale dérive un avatar à partir des initiales de ton nom. La section Sécurité tient un seul bouton : **Changer le mot de passe** si tu t’es inscrit avec e-mail et mot de passe, **Définir le mot de passe** si ton compte est fédéré via SSO et que tu veux ajouter un mot de passe comme repli. Les deux flux imposent la politique de mot de passe de l’org et affichent les règles en direct pendant que tu tapes, et un mot de passe actuel erroné est signalé directement sur le champ plutôt que comme une erreur passagère. Changer ton mot de passe te déconnecte de tous les appareils — le dialogue t’avertit avant que tu confirmes, et tu te reconnectes ensuite avec le nouveau mot de passe. La section Deux-facteurs apparie le compte à une app TOTP ou à une clé matérielle et affiche les codes de secours une fois à l’enrôlement. ## Les mémoires, et l’accord qui les précède Une mémoire est un court fait à ton sujet qu’un agent a proposé et que tu as gardé — une préférence que tu as exprimée, une contrainte que tu répètes sans cesse, un contexte qui mérite de voyager d’un chat à l’autre. Les mémoires sont la seule partie de ton compte dans laquelle un agent peut écrire, et c’est précisément pour cela que l’écriture passe par toi d’abord. En proposer une, c’est un tool que le modèle appelle : aucun processus d’arrière-plan ne lit tes conversations pour cela. L’appel inscrit l’entrée comme **en attente** et pose en même temps une ligne d’audit, parce que proposer un savoir durable sur une personne mérite d’être tracé avant même que quiconque soit d’accord. Une entrée en attente ne fait rien d’elle-même : elle patiente comme suggestion sous **Paramètres > Personnalisation** jusqu’à ce que tu l’enregistres ou l’écartes, et seule une mémoire enregistrée pourra être relue. <Info> Rien n’est ajouté à un prompt en ton nom. Une mémoire enregistrée n’atteint une réponse que si le modèle la cherche et que la recherche la renvoie — un modèle ne peut pas se donner un savoir durable sur toi en l’écrivant, et il ne peut pas consulter en douce une suggestion que tu as refusée. </Info> Les mémoires enregistrées figurent sur la même page, chacune avec un bouton pour la supprimer. Supprimer une mémoire la retire de ce qu’une recherche peut renvoyer, et c’est tout son effet — aucune seconde copie ne voyage dans un autre prompt. ## Se déconnecter La ligne **Se déconnecter** en bas du menu de profil confirme via une boîte de dialogue avant de purger la session. Après confirmation, Tale fait un rechargement complet vers la page de connexion pour qu’aucun état périmé ne traîne dans l’onglet. La déconnexion est par appareil — te déconnecter sur ton laptop ne te déconnecte pas sur ton téléphone, et réciproquement. ## Où cela s’inscrit Les préférences sont la ligne entre toi et le reste de l’org. L’Administrateur de l’org pose les valeurs par défaut — la politique de mot de passe, les modèles autorisés, la gouvernance qui s’applique à un chat — et tes préférences les remplacent là où Tale le permet. Une page personnelle se tient à l’écart de cet ensemble : [Variables d’environnement et secrets](/fr/platform/member/environment) porte des variables et des identifiants cantonnés à toi au sein d’une seule organisation plutôt qu’ils ne te suivent d’une org à l’autre — l’endroit où garder la clé de fournisseur qu’utilise un agent BYO. La lecture suivante à mettre en file est [Vue d’ensemble Membre](/fr/platform/member/overview) pour la carte du reste de la surface Membre, ou [Installer en tant qu’app](/fr/platform/member/install-as-app) si tu veux que Tale vive dans ton dock plutôt que dans tes onglets de navigateur. # Membre Source: https://tale.dev/docs/fr/platform/member/overview Membre est le rôle par défaut que portent la plupart des personnes dans la plupart des orgs. C’est la surface utilisateur final de Tale — chatter avec des agents, parcourir la base de connaissances, répondre au courriel client dans la Boîte de réception d’une automatisation installée, agir sur les approbations que d’autres ont routées vers toi, et laisser des retours sur les réponses. Les Membres ne construisent pas d’agents, ne configurent pas de fournisseurs, n’installent pas d’automatisations. Ils utilisent le produit que les Éditeurs et Développeurs ont bâti pour eux. Cette vue d’ensemble nomme ce qu’un Membre peut faire et pointe vers les pages par fonctionnalité. Les Membres atterrissent typiquement d’abord sur Chat ; le reste de cette page est ce qu’il faut lire quand chat seul ne suffit pas — quand tu veux savoir d’où vient une citation, ce qu’est une carte d’approbation, ou ce qu’empaquette un projet. ## Ce que couvre Membre La surface Membre est volontairement étroite. Les quatre seaux sont : - **Chat** — choisir un agent (ou aucun), envoyer un message, lire la réponse. Le chat expose la bibliothèque de skills, les pièces jointes, le mode vocal, le mode arène pour la comparaison côte à côte, et le panneau Canevas quand une réponse produit plus que le chat peut tenir en ligne. - **Connaissance** — parcourir les documents, contacts, produits, fournisseurs, sites web que l’org a chargés. Lecture seule pour les Membres ; la curation arrive du côté Éditeur. - **Boîte de réception** — répondre dans l’onglet **Boîte de réception** qu’ajoute une automatisation d’e-mail installée. Les Membres répondent quand un agent leur rend une conversation ; installer l’automatisation elle-même est une action d’admin. - **Approbations** — lire les cartes d’approbation routées vers toi. Clique sur Approuver, Rejeter, ou Demander des changements ; laisse un commentaire si la règle le demande. Les réglages de configuration de l’org — Fournisseurs, Connectors, Agents, Gouvernance — sont cachés pour les Membres ; la surface travail est l’essentiel de ce qui reste. L’exception est un petit groupe de réglages personnels que porte chaque rôle : Compte, Personnalisation et [Variables d’environnement et secrets](/fr/platform/member/environment), les clés et variables injectées dans les sandboxes que tu fais tourner. ## Pages dans cette section Cette section est courte — la surface Membre est l’intersection des pages que les Éditeurs construisent et que tout le monde utilise. La lecture plus profonde vit dans les zones par fonctionnalité. <CardGroup cols="2"> <Card title="Chat" icon="message-circle" href="/fr/platform/chat/overview"> Le point d’entrée quotidien — chat, agents, pièces jointes, citations. </Card> <Card title="Connaissance" icon="library" href="/fr/platform/knowledge/overview"> La fenêtre lecture seule sur ce que l’org a chargé. </Card> <Card title="Automatisations livrées" icon="inbox" href="/fr/platform/automations/builtin"> Les automatisations d’e-mail qui ajoutent un onglet Boîte de réception — et ce que fait chacune. </Card> <Card title="Approbations" icon="check-check" href="/fr/platform/approvals/concepts"> Ce qu’est une carte d’approbation et ce que fait chaque bouton. </Card> </CardGroup> ## Où cela s’inscrit Membre est le rôle qui consomme ce que l’Éditeur construit et que l’Administrateur gouverne. La première lecture naturelle est [Chat](/fr/platform/chat/overview) — c’est là que chaque Membre passe le plus de temps, et la plupart des autres surfaces Membre se déploient depuis un chat qui voulait faire plus. # Backlog du projet Source: https://tale.dev/docs/fr/platform/projects/backlog Une tâche au statut **`backlog`** est du travail proposé auquel personne ne s’est encore engagé — le plus souvent synchronisé par une automatisation comme [Trier les issues GitHub](/fr/platform/automations/builtin). Elle vit dans la **colonne la plus à gauche** du Tableau et la **section du haut** de la Liste, avec la même carte, la même fiche de détail, le même sélecteur de statut et le même sélecteur d’affectation que tout autre statut. [Automatisation des tâches](/fr/platform/projects/task-automation) couvre ce qui se passe une fois qu’une tâche atteint **À faire** et entre dans la boucle d’affectation. ## Une tâche synchronisée Trier les issues GitHub propose une tâche par issue ouverte exploitable, rattachée à l’issue pour qu’une synchronisation ultérieure ne la crée jamais en double : le titre est `#<numéro> <titre>` — par exemple `#482 Bouton de connexion mal aligné sur Safari` —, la description s’ouvre sur l’URL GitHub de l’issue elle-même, et ses étiquettes reflètent celles de l’issue sur GitHub. Une tâche que tu crées depuis le tableau avec le statut par défaut démarre à **À faire** ; choisis **Backlog** dans le formulaire de création pour déposer toi-même une proposition. ## Faire avancer le travail Il n’y a pas de boutons réservés au backlog. Glisse une carte vers une autre colonne, ouvre la fiche de détail et choisis un nouveau statut, ou affecte un responsable — les mêmes chemins que pour **À faire** ou **En cours**. L’auto-affectation et les suggestions d’affectation par agent ne tournent qu’à **À faire**, pas tant que la tâche reste en **Backlog**. Si tu passes une proposition directement à **En cours** ou si tu l’affectes à la main, tu prends la responsabilité toi-même. Écarte une proposition comme toute autre tâche : passe le statut à **Annulé** dans le sélecteur. Une annulation humaine tient — une synchronisation GitHub ultérieure ne ressuscite pas une proposition que tu as rejetée tant que l’issue reste ouverte sur GitHub. Quand une tâche était **Terminée** sur le tableau et que quelqu’un rouvre l’issue sur GitHub, la synchronisation la remet en **Backlog**. ## Où cela s’inscrit Le backlog est la colonne d’entrée entre une automatisation qui propose du travail et ton équipe qui s’y engage. La lecture suivante naturelle est [Automatisation des tâches](/fr/platform/projects/task-automation) pour ce qui se passe à **À faire**, ou [Automatisations livrées](/fr/platform/automations/builtin) pour ce qui propose des tâches en premier lieu. # Automatisation des tâches Source: https://tale.dev/docs/fr/platform/projects/task-automation Affecter une tâche du tableau à un agent IA la met au travail. La personne ou le système **assigné** à la tâche — un membre, un agent du projet ou une automatisation — conduit le travail et la chorégraphie du tableau ; le **Relecteur** est l’humain nommé qu’attend le résultat terminé. Une tâche qu’une automatisation propose reste dans le [Backlog](/fr/platform/projects/backlog) jusqu’à ce qu’un humain la démarre — à partir de ce moment, c’est une tâche de tableau comme une autre et elle entre dans la boucle ci-dessous. <Frame caption="Le tableau des tâches du projet — affecter une carte à un agent est ce qui lance la boucle ci-dessous."> ![Un tableau kanban de tâches dans le projet Website relaunch, montrant sept cartes de tâches réparties sur ses colonnes de statut, du Backlog et de À faire jusqu’à En revue, Terminé et Annulé.](/images/platform/projects-task-board.webp) </Frame> ## La boucle d’exécution 1. **Affecte** la tâche à un agent. La carte passe à _En cours_ et l’agent travaille dans sa propre session sandbox, avec la description, les commentaires et les fichiers d’entrée de la tâche comme contexte. 2. L’agent **rend compte** : son résultat arrive en commentaire sur la tâche (les livrables dans la zone Output), et la tâche se gare sur **_En revue_** — un agent ne peut jamais passer une tâche à _Terminé_ ; la règle est appliquée côté serveur. 3. Ce stationnement **demande une relecture** : le **Relecteur** de la tâche reçoit une cloche dans sa boîte et un e-mail, et la fiche de tâche affiche la carte de revue — _En attente de {name}_. Sans relecteur désigné, la demande arrive chez la personne qui a créé la tâche (sinon chez le créateur du projet) — une fin de travail ne reste jamais silencieuse. 4. Un humain **décide sur la carte de revue** : **Approuver** termine la tâche — _Terminé_ est enregistré comme la décision de cette personne, jamais celle de l’agent. **Demander des modifications** ajoute ton feedback en commentaire sur la tâche et la renvoie directement à l’agent, qui lance une exécution de reprise et gare le résultat de nouveau sur _En revue_. Une exécution qui échoue laisse la tâche où elle était et s’explique dans la fiche ; relance l’exécution une fois la cause corrigée. Une tâche parente avec des sous-tâches ouvertes refuse de se fermer tant que la dernière n’est pas terminée. ## Assigné et Relecteur Les deux rôles sont des champs volontairement séparés : | Rôle | Qui | Ce qu’il fait | | ------------- | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | **Assigné à** | membre, agent ou automatisation | Conduit le travail et le statut du tableau — l’assigné unique, polymorphe | | **Relecteur** | un membre du projet qui peut le modifier | L’humain nommé qu’on attend : reçoit la demande de relecture, alimente le filtre **En attente de ma relecture**, décide sur la carte de revue | Le relecteur se choisit dans la fiche de tâche, champ **Relecteur**. La désignation est volontairement **souple** : elle route les notifications et la file d’attente, mais tout membre qui peut modifier le projet peut encore répondre à une revue — et contrairement à l’assigné, tu peux poser ou changer le relecteur pendant qu’une exécution tourne. Relire n’oblige jamais à reprendre la tâche : l’agent ou l’automatisation reste assigné, et la chorégraphie continue après la décision. Le tableau nomme l’attente : les cartes garées sur _En revue_ portent une puce **En attente de {name}** (ou _En attente de ta relecture_), et le filtre **Relecture** du tableau le réduit aux tâches qui t’attendent — ta file de relecture personnelle dans le projet. ## Mentions **Mentionne un agent avec @** dans un commentaire de tâche : il lit le texte qui le mentionne et agit. Taper `@` ouvre une autocomplétion sur les membres et les agents du projet ; le composeur montre à l’avance si chaque agent mentionné répondra vraiment (automatisation coupée, disjoncteur déclenché, non mentionnable dans ce projet). Une mention de l’**assigné** vaut feedback sur son travail : un agent en cours d’exécution reprend le commentaire en vol, un agent au repos lance une exécution de reprise qui reçoit le commentaire tel quel. ## Garde-fous Chaque exécution d’agent — affectation, mention, reprise après revue — passe la même porte d’admission : - **Un moteur par tâche** : une tâche avec une exécution en cours en refuse une seconde, et une réaffectation en plein vol est refusée (annule d’abord — le sélecteur propose annuler-puis-réaffecter). - **Simultanéité** : les sessions d’agents puisent dans la capacité de l’organisation ; les exécutions en trop patientent et démarrent dès qu’une place se libère. - **Disjoncteur par tâche** : trop d’exécutions automatiques en une heure sur une même tâche suspendent l’automatisation sur cette tâche jusqu’à ce qu’un humain change son statut. ## Choisir l’assigné Toute tâche n’a pas sa place sur un harness de code. En règle générale : | Type de tâche | Affecter à | | ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | | Recherche, rédaction, synthèses, livrables personnels | Une **personne** | | Travail de tableau conduit par une automatisation déployée | Une **Automatisation** — son desk conduit alors les verbes de statut du tableau, et la revue se fait sur le panneau sujet de la tâche | | Travail de dépôt — bugs, fonctionnalités, refactorings, PR | Un **Agent** sur un [**Harness**](/fr/platform/agents/harnesses) de code — créé dans l’onglet Agents du projet avec le harness qui correspond au travail | Le sélecteur d’assigné groupe **Agents** et **Automatisations**. Chaque agent tourne dans une sandbox sur le **Harness** choisi à sa création, pré-équipé de ses skills, connecteurs et instructions. ## L’arrêt d’urgence La politique de gouvernance `task_automation` porte l’interrupteur principal : la couper stoppe le chemin d’exécution — le travail en vol se termine, rien de neuf ne démarre. Réservée aux admins et auditée ; sur une instance auto-hébergée, la politique est l’un des fichiers de configuration de gouvernance de l’organisation, à côté des limites décrites sur [Politiques et limites](/fr/platform/admin/governance/policies-and-limits). ## Où cela s’inscrit L’automatisation des tâches transforme le tableau de projet d’une liste de choses à faire en surface de délégation : un humain affecte, un humain nommé relit, l’agent exécute tout ce qu’il y a entre les deux — et _Terminé_ reste une décision humaine. La suite naturelle : [Backlog](/fr/platform/projects/backlog), pour comprendre comment le travail proposé entre dans la boucle. # Agents de projet Source: https://tale.dev/docs/fr/platform/projects/project-agents L'onglet **Agents** d'un projet, c'est son équipe : des agents nommés que tu configures une fois puis à qui tu confies du travail — chacun combine un [harness](/fr/platform/agents/harnesses) de code, un modèle, des skills et des connectors, et des instructions permanentes. Le chat continue de tourner sur l'assistant intégré — ces agents existent pour le tableau : assigne une tâche à l'un d'eux, il travaille dans une sandbox isolée puis revient rendre compte pour revue. Toute personne qui peut modifier le projet les gère ; un projet en accueille jusqu'à 50. <Frame caption="L'onglet Agents — les agents du projet ; chaque ligne nomme le harness, le fournisseur et le modèle."> ![L'onglet Agents d'un projet listant des agents nommés, chacun avec son harness, le fournisseur qui le sert, l'identifiant du modèle et le nombre d'équipements.](/images/platform/project-agents-models.webp) </Frame> ## Créer un agent <Steps> <Step title="Ouvre l'onglet et lance-toi"> Ouvre l'onglet **Agents** du projet et clique sur **Nouvel agent**. Donne-lui un **Nom** que ton équipe reconnaîtra sur les cartes de tâches, et choisis le **Harness** — la CLI de code sur laquelle l'agent tourne. </Step> <Step title="Choisis le modèle — et avec lui le fournisseur"> La liste **Modèle** se filtre à la saisie ; un modèle servi par plusieurs fournisseurs apparaît une fois par fournisseur, le nom du fournisseur sous chaque entrée. Le choix est exact : les runs de l'agent appellent ce modèle via ce fournisseur — et la dépense atterrit sur son accès. Si le fournisseur choisi ne peut plus servir le modèle, le run échoue en le disant, au lieu de basculer en silence sur la facture d'un autre. Les entrées servies par abonnement — un abonnement Claude, par exemple — n'apparaissent que lorsque le **Harness** est celui que cet abonnement pilote ; le run s'authentifie alors avec l'abonnement du fournisseur plutôt qu'avec une clé API de l'organisation. </Step> <Step title="Équipe-le et fixe ses instructions"> **Skills, connectors & outils** décident de ce que l'agent atteint au-delà de son espace de travail ; la liste suit l'accès des équipes du projet, pas ta visibilité personnelle. Les skills fournissent des bundles de référence dans la sandbox, les connectors relaient un service connecté, et les **outils de la plateforme** laissent l'agent lire et écrire les données de ton organisation — trouver et lire des tâches, contacts, produits, documents et connaissances, et, quand tu accordes un outil d'écriture, créer des tâches, les commenter, les déplacer entre colonnes, synchroniser un élément externe vers une tâche ou enregistrer un document. Un outil d'écriture est marqué _Écrit des données_ : l'accorder vaut autorisation, un agent équipé de `Créer des tâches` crée donc de vraies tâches sans autre validation. Lecture et écriture restent limitées au projet — un agent ne voit jamais le tableau d'un autre projet. Les **secrets** remettent à l'agent une clé API sous forme de variable d'environnement — l'échappatoire pour un service sans connector. Ajoutes-en un (un nom comme `GLITCHTIP_TOKEN` et le jeton), et l'agent le reçoit dans son shell et appelle l'API de ce service directement, avec la doc du fournisseur. La valeur est stockée chiffrée et n'est plus jamais affichée ; ne stocke que des jetons peu privilégiés et renouvelables, car l'agent en cours d'exécution peut les lire. Les secrets appartiennent à l'organisation, le même est donc réutilisé entre agents et renouvelé à un seul endroit. Les **Instructions** accompagnent chaque run comme consigne permanente — ce que cet agent prend en charge, comment il doit travailler et les limites à respecter. </Step> </Steps> Clique sur **Créer l'agent**. La ligne affiche le harness, le fournisseur, le modèle et le nombre d'équipements — le même résumé que voient tes coéquipiers au moment d'assigner. ## Mets-le au travail Assigne une tâche du tableau à l'agent et clique sur **Démarrer l'agent** depuis la tâche. Le run travaille dans une sandbox isolée avec un espace de travail permanent qui persiste d'une tâche à l'autre, poste son rapport en commentaire de la tâche, joint ce qu'il produit sous **Fichiers produits** et gare la tâche **En revue** — un agent ne clôt jamais un travail ; c'est une personne qui le fait. Commente la tâche en mentionnant l'agent avec @ pour orienter un run en cours, ou pour en lancer un nouveau qui lit d'abord ton commentaire. [Automatisation des tâches](/fr/platform/projects/task-automation) décrit la boucle du tableau de bout en bout. ## Modifier ou supprimer Les modifications s'appliquent au run suivant — un run en cours garde sa configuration de départ ; c'est le run suivant qui reprend tes changements. Supprimer un agent conserve l'historique de chaque tâche ; seule l'assignation se vide. ## Assistant de chat ou agent de projet ? | Prends… | quand le travail est… | | ------------------ | -------------------------------------------------------------------------------------------- | | le chat | une conversation — questions, brouillons, recherche ; l'assistant intégré s'en charge. | | un agent de projet | une tâche — du travail sur dépôt ou fichiers via un harness, fait par une équipe permanente. | ## Où ça se range L'agent regroupe côté projet des choix que d'autres pages détaillent : le catalogue des harnesses et leurs capacités vivent dans [Harnesses](/fr/platform/agents/harnesses) ; savoir quels fournisseurs et quels accès servent les modèles — clés stockées sur la passerelle mesurée, ou abonnements sur le compte du fournisseur — relève de [Fournisseurs IA](/fr/platform/admin/providers). # Concepts de projet Source: https://tale.dev/docs/fr/platform/projects/concepts Un projet est l’unité que Tale sort quand un chantier a besoin des mêmes fichiers, des mêmes instructions et des mêmes surfaces de travail à travers beaucoup de chats et beaucoup de personnes. Cette page te donne le modèle mental — lis-la avant de créer ton premier projet, et reviens-y au moment de décider si un chat qui grossit mérite d’être promu en projet. <Frame caption="L’onglet Général — identité, partage et bandeau de statistiques sont la porte d’entrée du projet."> ![L’onglet Général du projet Website relaunch montrant les champs de nom et de description, la section de partage où l’équipe propriétaire est Toute l’organisation, et un bandeau de statistiques indiquant deux fichiers, aucun chat et Toute l’organisation.](/images/platform/project-general-tab.webp) </Frame> ## Ce qu’un projet possède Les **chats** démarrés dans le projet portent son contexte automatiquement. Ils restent les tiens jusqu’à ce que tu actives **Partager avec le projet** sur un chat — l’onglet Chats se divise en **Tes chats** et **Partagés avec le projet** en conséquence. Partager un chat masque tes souvenirs et tes instructions personnels dans les réponses que voient les autres membres. Les **instructions** sont du contexte qui s’applique à chaque chat du projet — le cadre, les contraintes et le vocabulaire du travail — pour que personne ne les recolle chat par chat. Les **fichiers** de l’onglet **Connaissances** sont le matériel de référence où chaque chat du projet peut puiser, rangés dans une arborescence de dossiers que tu remplis une fois plutôt que de les rattacher chat par chat. Ils restent scopés à ce projet — ils n’apparaissent jamais dans la bibliothèque de l’organisation ni dans les sélecteurs `@` hors du projet — voir [Gérer les fichiers](/fr/platform/projects/manage-files). Les **tâches** font du projet un endroit où mener le travail, pas seulement en parler : un tableau avec des statuts et de l’[automatisation](/fr/platform/projects/task-automation), et des fils de commentaires sur chaque tâche pour les décisions qui l’entourent. **Agents**, c'est l'équipe du projet : des agents nommés, chacun avec un harness, un modèle sur le fournisseur que tu choisis, un équipement et des instructions permanentes, prêts à prendre des tâches du tableau ([Agents de projet](/fr/platform/projects/project-agents)). ## Création et identité **Créer un projet** demande un nom et une **Clé du projet** — le préfixe des identifiants de tâches comme `WR-1`. La clé est fixe ; elle ne peut plus changer une fois le projet créé. La description, l’équipe propriétaire, l’icône et la couleur restent modifiables ensuite sur l’onglet **Général**, où les boutons unifiés **Enregistrer** et **Abandonner** siègent dans la barre d’onglets. ## Le modèle de partage Le partage se fait par équipe, pas par invitation individuelle. Un projet démarre en **Toute l'organisation** ; choisir une équipe propriétaire le limite à cette équipe, et d’autres équipes s’ajoutent sur l’onglet Général. Les admins de l’organisation ont toujours accès. Renommer, archiver et supprimer vivent dans le menu de ligne de la liste des projets — la suppression demande ce qu’il advient du contenu : détacher les fichiers et les chats (ils redeviennent des documents de bibliothèque et des chats personnels) ou les supprimer aussi. ## Quand y recourir | Choisis … quand | Projet | Chat isolé | | ---------------------------------------------------------- | ------ | ---------- | | Les mêmes fichiers servent à beaucoup de chats | ✓ | | | Les mêmes instructions s’appliquent à beaucoup de chats | ✓ | | | Plusieurs personnes travaillent le même chantier | ✓ | | | Le travail a des tâches, des responsables et des décisions | ✓ | | | La question est ponctuelle | | ✓ | Un chat isolé est la bonne forme pour explorer une réponse une fois. Dès que le contexte doit survivre au chat, déménage-le — l’action **Déplacer vers un projet…** du chat transporte un chat existant dans un projet. ## Où cela s’inscrit Les projets sont la couture où se rejoignent les chats, les connaissances et l’automatisation des tâches. La lecture suivante naturelle est [Utiliser les projets](/fr/tutorials/member/use-projects), qui déroule un projet neuf de bout en bout ; les pages par onglet de cette section approfondissent les [fichiers](/fr/platform/projects/manage-files) et les [agents et modèles](/fr/platform/projects/project-agents). # Gérer les fichiers du projet Source: https://tale.dev/docs/fr/platform/projects/manage-files L’onglet **Connaissances** d’un projet est la zone de fichiers partagée que chaque chat du projet peut atteindre. Téléverse un fichier une fois et chaque chat du projet — et chaque agent qui y tourne — peut le lire sans nouveau téléversement. Cette page couvre l’arborescence de dossiers, le mécanisme de téléversement, l’épinglage et les limites. L’onglet Connaissances n’est pas la base de connaissances de l’organisation au sens de [Documents](/fr/platform/knowledge/documents). Ses fichiers sont scopés à un projet et n’apparaissent jamais dans la bibliothèque de l’organisation, dans les sélecteurs `@` hors du projet, ni via WebDAV ; supprimer le projet supprime les fichiers. Pour du matériel de référence à l’échelle de l’organisation, utilise [Documents](/fr/platform/knowledge/documents) et lie-les à des agents. <Frame caption="L’onglet Connaissances — l’arborescence de fichiers du projet ; chaque fichier reste borné à ce projet et indexé pour la recherche."> ![L’onglet Connaissances du projet Website relaunch montrant deux fichiers indexés dans l’arborescence, un bouton Nouveau dossier et la zone de dépôt Ajouter un fichier.](/images/platform/project-knowledge-files.webp) </Frame> ## Dossiers Les fichiers du projet vivent dans une arborescence de dossiers. **Nouveau dossier** en crée un à la racine ; l’icône dossier-plus sur une ligne de dossier crée un sous-dossier. Clique un dossier pour le sélectionner — la zone de dépôt passe à _Ajouter un fichier à « … »_ et les téléversements y atterrissent. Supprimer un dossier supprime tout son contenu, y compris les entrées des fichiers dans l’index de récupération ; la confirmation le dit avant que quoi que ce soit n’arrive. Les dossiers ici sont scopés au projet : un dossier homonyme dans la bibliothèque de l’organisation est un dossier différent. ## Un téléversement déroulé Ouvre le projet, clique **Connaissances**, sélectionne le dossier cible (ou aucun pour la racine), et glisse des fichiers sur la zone de dépôt. La ligne apparaît dans l’arborescence et passe à **Indexed** une fois que la récupération l’a intégrée. Le même téléversement est désormais accessible depuis n’importe quel chat que le projet possède : envoie un message qui référence le sujet et l’agent le récupère, ou tape `@` dans le chat et épingle le fichier — ou un dossier entier — au tour. ## Remplacer et supprimer Remplacer un fichier téléverse une nouvelle copie sous le même nom ; l’ancienne version passe dans l’historique de versions du projet. Les citations des chats antérieurs continuent de pointer vers la version qui était active quand le chat l’a référencée. Supprimer un fichier le retire du sélecteur immédiatement ; les chats existants gardent leurs citations, mais le fichier sous-jacent passe dans la [Corbeille](/fr/platform/admin/governance/trash) avec le reste de la cohorte de rétention du projet. ## Verrouiller un fichier derrière une relecture Quand l’approbation doit rester liée au fichier exact que le relecteur a vu — une SOP, un plan de validation —, ouvre le menu de la ligne du fichier et clique **Marquer comme document maîtrisé**. La ligne porte alors `v1 · Brouillon` et suit le même cycle de vie qu’un document maîtrisé dans la bibliothèque de l’organisation : **Soumettre à la relecture** fige le fichier pour un relecteur nommé, l’approbation rend la version immuable, et **Nouvelle révision** ouvre le brouillon suivant. Le cycle de vie complet — remplacement du fichier d’un brouillon compris — est sur [Documents](/fr/platform/knowledge/documents#reviser-un-document-maitrise). La portée ne change pas : un fichier de projet maîtrisé reste un fichier de projet, visible seulement dans le projet. ## Limites de taille Les limites par fichier et par projet sont fixées par l’organisation sous [Politiques et limites](/fr/platform/admin/governance/policies-and-limits). Atteindre une limite par fichier fait échouer le téléversement avec un toast ; atteindre une limite par projet le fait échouer avec un autre toast qui nomme la politique. Les membres qui atteignent une limite ne peuvent pas l’élever eux-mêmes — un Admin ajuste la politique, ou le propriétaire du projet supprime des fichiers plus anciens. ## Apparition dans les chats Un chat démarré à l’intérieur d’un projet a automatiquement accès à chaque fichier de l’onglet Connaissances du projet. L’outil de récupération de l’agent voit les fichiers du projet à côté de toute source de Connaissances liée à l’agent. Les citations issues de fichiers du projet sont scopées au chat qui les a produites — partager ce chat hors du projet préserve les citations, mais le visiteur ne peut pas cliquer vers la source à moins d’être lui aussi dans le projet. Épingler avec `@` resserre un seul tour : `@fichier` épingle un fichier, `@dossier` épingle un dossier et tout ce qu’il contient (le sélecteur propose les dossiers du projet dans les chats de projet, et les dossiers de l’organisation partout). Les fichiers épinglés sont aussi livrés dans la sandbox de l’agent sous `/user/uploads` — un agent de projet sur un harness de code comme Claude Code ouvre donc les vrais octets au lieu de ne citer que des extraits de récupération. ## Où cela s’inscrit Gérer les fichiers est la page opérationnelle de l’onglet Connaissances — le cadrage conceptuel est sur [Concepts de projet](/fr/platform/projects/concepts), et l’équivalent lié à l’agent à l’échelle de l’organisation entière est [Documents](/fr/platform/knowledge/documents). Si tu te surprends à téléverser les mêmes fichiers dans plusieurs projets, c’est le signal pour les déplacer dans [Documents](/fr/platform/knowledge/documents) et lier un agent à la place. # Projets Source: https://tale.dev/docs/fr/platform/projects/overview Un projet est un espace de travail partagé qui regroupe tout ce dont un travail a besoin — les chats, les fichiers de référence, les instructions et le tableau des tâches — pour que le contexte suive le travail au lieu d’être recollé dans chaque chat. Là où un chat isolé répond à une question, un projet est l’endroit où une équipe fait avancer un contact, un lancement ou une enquête au long cours. Tu préfères regarder d’abord ? L’épisode 6 parcourt un vrai projet en deux minutes et demie — avec une tâche qu’un agent prend à l’écran. <Video src="/videos/fr/tutorials/ep6-projects/ep6-projects.fr.mp4" poster="/videos/fr/tutorials/ep6-projects/ep6-projects.fr.webp" captions="/videos/fr/tutorials/ep6-projects/ep6-projects.fr.vtt" lang="fr" title="Épisode 6 — Les projets avec l'IA" caption="Épisode 6 — Les projets avec l'IA (2:21)"> </Video> <Frame caption="Le tableau des tâches d’un projet — l’un des huit onglets que porte chaque projet."> ![Un tableau kanban de tâches dans le projet Website relaunch, avec sept cartes de tâches réparties sur les colonnes Backlog, À faire, En cours, En revue, Terminé et Annulé.](/images/platform/projects-task-board.webp) </Frame> ## Les pièces d’un projet Chaque projet s’ouvre sur la même barre d’onglets : **Général** (nom, description, partage et chats récents), **Chats** (tes chats dans le projet plus ceux qui lui sont partagés), **Tâches** (le tableau), **Connaissances** (les fichiers du projet, dans une arborescence de dossiers) et **Agents** (les agents du projet) — plus **Automatisations** dès qu’une est liée au projet, et **Environnement** pour les admins du projet. Les apps installées dans le projet ajoutent leurs propres onglets à la suite. ## Pages dans cette section <CardGroup cols="2"> <Card title="Concepts de projet" icon="compass" href="/fr/platform/projects/concepts"> Le modèle mental — ce qu’un projet possède, quand il bat un chat isolé et comment le partage fonctionne. </Card> <Card title="Gérer les fichiers" icon="folder-open" href="/fr/platform/projects/manage-files"> L’onglet Connaissances — téléverser des fichiers dans des dossiers, le statut d’indexation et comment les fichiers du projet restent scopés au projet. </Card> <Card title="Agents de projet" icon="bot" href="/fr/platform/projects/project-agents"> Les agents du projet — harness, modèle et fournisseur, équipement et instructions permanentes — et comment les tâches les mettent au travail. </Card> <Card title="Automatisation des tâches" icon="workflow" href="/fr/platform/projects/task-automation"> Affecter les tâches du tableau à des agents — la boucle d’exécution, le portail de revue et les garde-fous. </Card> <Card title="Backlog" icon="gauge" href="/fr/platform/projects/backlog"> Les tâches proposées qu’une automatisation ou un coéquipier a synchronisées — Démarrer les met sur le tableau, Fermer les écarte. </Card> </CardGroup> ## Où cela s’inscrit Les projets vivent à côté du Chat dans la barre latérale, et le passage de relais est naturel : une question démarre dans le Chat, se révèle plus grande qu’un chat et déménage dans un projet — l’action **Déplacer vers un projet…** du chat transporte un chat existant. Si les projets sont nouveaux pour toi, commence par [Concepts de projet](/fr/platform/projects/concepts) pour le modèle, puis déroule [Utiliser les projets](/fr/tutorials/member/use-projects) de bout en bout sur un projet neuf. # Éditeur Source: https://tale.dev/docs/fr/platform/editor/overview Éditeur est la surface de construction de Tale. Là où Membre est le rôle qui utilise le produit et Administrateur le rôle qui le gouverne, Éditeur est le rôle qui crée les choses que tout le monde consomme — agents, projets, automatisations, les documents et données structurées que tient la base de connaissances, les prompts enregistrés pour l’équipe. Les personnes de rôle Éditeur voient l’ensemble complet d’onglets de construction sans la surface gouvernance admin et sans les leviers réservés aux développeurs. Cette vue d’ensemble nomme ce que fait un Éditeur, où il le fait, et quelles pages couvrent chaque pièce. Les Éditeurs atterrissent typiquement ici à leur premier jour, construisent le premier agent et projet utile de l’org, et reviennent sur cet onglet chaque fois que la prochaine chose doit être bâtie. L’histoire des rôles et permissions derrière les onglets vit sur [Membres et rôles](/fr/platform/admin/members-and-roles). ## Ce que couvre Éditeur Le travail d’un Éditeur tombe dans quatre seaux : construire des **agents** (instructions, liaisons de connaissance, tools, modèles), curer la **base de connaissances** (téléverser des documents, maintenir contacts, produits, fournisseurs, sites web), écrire des **automatisations** (workflows avec déclencheurs, étapes, gates d’approbation), et empaqueter des **projets** (jeux de fichiers, agents cadrés, instructions de projet). Chaque seau a sa propre section dans Platform ; l’onglet Éditeur est l’index à travers. Les Éditeurs partagent la surface de construction avec les Développeurs — les Développeurs voient aussi les quatre seaux et peuvent tout ce qu’un Éditeur peut, plus le plan API et connectors. Va vers un Éditeur quand le travail quotidien est contenu et configuration ; va vers un Développeur quand le travail croise le code ou les systèmes externes. ## Pages dans cette section La surface Éditeur est la même surface que documentent les sections par domaine de Platform. Ce qui suit est l’index à travers. <CardGroup cols="2"> <Card title="Agents" icon="bot" href="/fr/platform/agents/concepts"> Le modèle mental à quatre boutons à partir duquel un Éditeur construit chaque agent. </Card> <Card title="Automatisations" icon="workflow" href="/fr/platform/automations/concepts"> Workflows, déclencheurs, étapes, exécutions. </Card> <Card title="Connaissance" icon="library" href="/fr/platform/knowledge/overview"> La zone documents-et-données-structurées qu’un Éditeur cure. </Card> <Card title="Projets" icon="folder-open" href="/fr/platform/projects/overview"> L’espace de travail partagé qu’un Éditeur empaquette autour d’un contact ou d’un lancement. </Card> <Card title="Bibliothèque de skills" icon="list-plus" href="/fr/platform/workspace/skills"> La bibliothèque de bundles qu’un Éditeur utilise pour garder une instruction récurrente réutilisable d’un chat à l’autre. </Card> </CardGroup> ## Où cela s’inscrit Éditeur est le rôle dont la plupart des équipes ont plusieurs — les personnes qui font le travail de construction que les autres rôles consomment. La première lecture naturelle au jour un est [Concepts agents](/fr/platform/agents/concepts), parce que le modèle à quatre boutons est ce que chaque autre page de construction présuppose. La seconde naturelle est [Construire ton premier agent](/fr/tutorials/editor/first-agent-end-to-end) — elle parcourt les quatre boutons de bout en bout sur une instance fraîche. # Documents Source: https://tale.dev/docs/fr/platform/knowledge/documents L’onglet Documents est la surface fichiers de la base de connaissances. Les éditeurs téléversent des fichiers, Tale fait passer chacun par le pipeline d’indexation — extraire le texte, le découper, calculer les embeddings, les stocker — et les agents dont le périmètre de connaissances couvre le document récupèrent les passages pertinents au moment de répondre et les citent. Cette page couvre le côté opérateur : le téléversement, la colonne de statut, la portée par équipe, les dossiers et le cycle de vie d’un document. <Frame caption="La table des documents — taille, source, statut RAG et portée d’équipe par fichier."> ![L’onglet Documents de la base de connaissances listant trois fichiers texte téléversés avec les colonnes taille, source, statut RAG et équipes.](/images/get-started/documents-list.webp) </Frame> ## Téléverser Ouvre **Connaissances > Documents** et clique sur **Téléverser des documents** — le menu propose **Depuis ton appareil** et **Depuis Microsoft 365**. Le portail de téléversement accepte les formats qui couvrent l’essentiel des connaissances d’une organisation : PDF, Word (`.doc`, `.docx`), texte OpenDocument (`.odt`), PowerPoint (`.ppt`, `.pptx`), Excel (`.xls`, `.xlsx`), CSV, texte brut et images (JPG, PNG, GIF, WEBP). Tout le reste est refusé dès le téléversement. Téléverser et indexer sont deux faits distincts, et la colonne **Statut RAG** suit le second : **Indexation** pendant que le pipeline tourne, **Indexé** quand les agents peuvent récupérer le contenu, **Échoué** quand le pipeline a rencontré une erreur, et **Réindexation nécessaire** quand les fragments stockés sont périmés. Les formats modernes s’indexent ; le trio Office historique (`.doc`, `.xls`, `.ppt`) se téléverse et reste téléchargeable mais affiche **Non indexé** — les agents ne peuvent pas récupérer son contenu tant que tu ne l’as pas réenregistré au format moderne. ## Réviser un document maîtrisé Utilise un document maîtrisé quand l’approbation doit rester liée au fichier exact que le relecteur a vu. Remplacer le fichier de son brouillon met à jour l’enregistrement existant ; téléverser un autre fichier du même nom crée toujours un document distinct. <Steps> <Step title="Choisir le document maîtrisé"> Pour un téléversement ordinaire, ouvre le menu de la ligne et clique sur **Marquer comme document maîtrisé**. L’enregistrement passe à `v1 · Brouillon`. Un document approuvé propose **Remplacer le fichier** et **Nouvelle révision**. Utilise **Nouvelle révision** seulement si tu veux ouvrir le brouillon suivant sans remplacer son fichier. </Step> <Step title="Remplacer le fichier actuel"> Ouvre le menu de la ligne d’un brouillon ou d’un document approuvé et clique sur **Remplacer le fichier**, puis choisis un fichier au même format. Un brouillon garde sa révision actuelle. Pour un document approuvé, Tale conserve la vN approuvée et n’ouvre le brouillon vN+1 qu’une fois le remplacement terminé ; si tu annules ou si le téléversement échoue, la vN reste approuvée. Une conservation légale bloque les deux parcours. <Frame caption="La boîte de dialogue accepte un seul fichier au format actuel du document."> ![La boîte de dialogue « Remplacer le fichier » d’un document texte maîtrisé, avec un sélecteur de fichier au même format et un rappel que les versions approuvées restent dans l’historique.](/images/platform/controlled-document-replace-file.webp) </Frame> </Step> <Step title="Vérifier et soumettre la révision"> Ouvre l’aperçu du document et vérifie qu’il affiche le fichier de remplacement. Ouvre ensuite le menu de la ligne et clique sur **Soumettre à la relecture**. Le sélecteur ne propose que les membres qui peuvent réellement ouvrir le document — un fichier de projet exige l’accès en édition au projet. Tale fige le brouillon pendant que le relecteur statue sur ce fichier exact ; le relecteur est prévenu par la cloche et par e-mail, et la décision te revient par le même chemin — une demande de modifications porte le retour du relecteur, que la boîte de dialogue de soumission affiche aussi avant ta prochaine tentative. </Step> </Steps> ## Importer depuis Microsoft 365 **Depuis Microsoft 365** importe depuis OneDrive ou SharePoint au lieu du disque : choisis des fichiers ou des dossiers, puis le mode d’importation. **Importation unique** apporte les fichiers une fois — ils se comportent comme des téléversements depuis le disque. **Importation synchronisée** garde la sélection synchronisée : les nouveaux fichiers du dossier OneDrive apparaissent lors d’un passage de sync ultérieur, les fichiers modifiés sont réindexés, et les fichiers supprimés à la source quittent l’espace de travail. Les deux modes préservent la structure de dossiers de ta sélection. La synchronisation couvre les dossiers OneDrive personnels — une sélection SharePoint s’importe toujours une seule fois. Pour arrêter la synchronisation — d’un dossier synchronisé entier ou d’un seul fichier synchronisé — ouvre le menu de la ligne et clique sur **Arrêter la synchronisation** ; les documents importés restent dans l’espace de travail et cessent d’être mis à jour. Supprimer un dossier ou un fichier synchronisé arrête aussi sa synchronisation. Dans tous les cas, les fichiers dans OneDrive restent intacts. ## Portée, dossiers, sources Chaque ligne porte une cellule **Équipes** — **Toute l'organisation** par défaut, ou les équipes que tu choisis via **Assigner une équipe** dans le menu de la ligne. Un document limité à une équipe est invisible pour les membres et les agents hors de cette équipe ; c’est le levier d’accès de la base de connaissances. Les fichiers de projet sont entièrement hors de ce modèle : l’onglet **Connaissances** d’un projet contient des fichiers scopés à ce seul projet, et ils n’apparaissent ni dans cette bibliothèque ni dans sa portée par équipe — voir [Gérer les fichiers](/fr/platform/projects/manage-files). **Nouveau dossier** garde les grandes bibliothèques navigables, et les connectors apportent leur propre structure : les documents synchronisés depuis OneDrive ou SharePoint atterrissent dans des dossiers de synchronisation et affichent leur origine dans la colonne **Source**, ce qui garde les citations traçables jusqu’au système amont. <Warning> Supprimer un dossier supprime définitivement chaque fichier et sous-dossier qu’il contient. Supprimer un dossier de synchronisation OneDrive retire aussi sa configuration de synchronisation automatique et son historique — mais jamais les fichiers dans OneDrive lui-même. </Warning> ## Réindexer et supprimer **Réindexer** (menu de la ligne) refait passer le pipeline sur le fichier stocké — le bon geste après un échec d’indexation ou quand un document affiche **Réindexation nécessaire**. **Supprimer** retire le document et ses fragments indexés ; la confirmation le dit sans détour — l’action est irréversible. Retéléverser le même fichier ramène le contenu sous la forme d’un nouveau document. Un document maîtrisé cesse d’être supprimable dès qu’une de ses versions est approuvée — en relecture, approuvé ou avec le brouillon suivant ouvert, l’entrée du menu affiche **Document maîtrisé protégé**, et un dossier qui en contient un refuse la suppression du dossier de la même façon. L’instantané approuvé est un enregistrement conservé ; c’est précisément le rôle du cycle de vie. Chaque document affiche un statut : **En file** (en attente — une organisation chargée indexe quelques fichiers à la fois et le reste patiente), **Indexation**, **Indexé**, **Échoué** ou **Non pris en charge** (un ancien format comme `.doc`/`.ppt`/`.xls` qui se stocke et se télécharge sans souci mais n’a pas d’extracteur de texte, donc jamais indexé pour la recherche). Une indexation interrompue par un délai dépassé ou un redémarrage du backend se rétablit d’elle-même en quelques minutes — elle est relancée ou marquée **Échoué** avec une option de reprise, jamais laissée bloquée. Si ton organisation applique un quota de stockage par utilisateur, les fichiers échoués et non pris en charge comptent toujours dedans jusqu’à leur suppression : libérer de l’espace revient donc à retirer les fichiers dont tu n’as plus besoin. Cliquer sur un document ouvre l’aperçu, avec un panneau latéral qui montre la taille, la source, le statut RAG, les équipes, l’auteur du téléversement et la date de modification — le moyen le plus rapide de vérifier ce que vise réellement une citation. ## Documents ou données structurées Les documents sont la moitié non structurée de la base de connaissances. Quand le contenu est une liste d’éléments partageant les mêmes champs — contacts, produits, fournisseurs — une fiche typée sert mieux les agents qu’un tableur téléversé : des valeurs exactes au lieu de passages récupérés. Les règles de décision vivent dans [Données structurées](/fr/platform/knowledge/structured-data). ## Où cela s’inscrit Les documents sont le coin le plus utilisé de la base de connaissances — la plupart des citations, dans la plupart des réponses, pointent ici. Le volet récupération — comment le périmètre de connaissances d’un agent décide de ce qu’il interroge — est [Connaissances de l’agent](/fr/platform/agents/knowledge) ; la surface sœur au format fait est [Entrées de connaissances](/fr/platform/knowledge/knowledge-entries), qui emprunte le même pipeline un document à la fois. # Données structurées Source: https://tale.dev/docs/fr/platform/knowledge/structured-data La base de connaissances de Tale embarque deux formes côte à côte. Les documents sont du texte dont l’agent récupère des fragments ; les fiches structurées sont des lignes typées dont l’agent lit les champs. La forme que tu choisis est la décision la plus lourde dans la façon dont un agent exploitera tes connaissances — trompe-toi et l’agent dilue une réponse claire, ou devine une valeur que tu as pourtant en stock. Cette page te donne le modèle mental pour savoir quand chaque forme est la bonne. Lis-la avant de charger un dossier de fichiers ; reviens-y quand tu es tenté de téléverser un tableur en PDF. ## Documents ou fiches structurées Un document est libre : le pipeline d’indexation extrait le texte, le découpe, calcule les embeddings et sert des passages par récupération au moment de répondre. L’agent voit des passages et les cite par source. C’est la bonne forme quand le contenu est de la prose — contrats, manuels, articles de base de connaissances, comptes rendus de réunion. Une fiche structurée est typée : l’entité a des champs connus (un contact a un nom, un e-mail, un secteur ; un produit a un SKU, un prix, un stock). L’agent lit les champs directement, croise les entités entre elles et répond avec la valeur. C’est la bonne forme quand la source est une ligne de base de données — comptes, commandes, pièces, fiches fournisseurs. ## Les quatre entités intégrées Quatre onglets structurés côtoient **Documents** et **Entrées de connaissances** dans la base de connaissances : - **Contacts** — les personnes et organisations avec qui tu fais affaire. - **Produits** — ce que tu vends. - **Fournisseurs** — ceux auprès de qui tu achètes. - **Sites web** — des sites publics qu’un crawler va chercher selon un planning ; la fiche porte le domaine et les réglages d’analyse, les pages indexées portent le contenu ([Exploration de sites web](/fr/platform/knowledge/crawling)). Les fiches structurées partagent les leviers de portée par équipe de la base de connaissances : une fiche limitée à une équipe est invisible hors de l’équipe, exactement comme un document limité à une équipe. ## Des modèles de contenu pour les formes sur mesure Quand les quatre entités intégrées ne conviennent pas, les modèles de contenu te laissent définir un type de fiche structurée sur mesure : nomme l’entité, déclare ses champs, règle l’accès champ par champ, et le nouveau type apparaît à côté des types intégrés. Les définitions vivent dans les [modèles de contenu de la gouvernance](/fr/platform/admin/governance/content-models). <Note> Les modèles de contenu coûtent de l’attention de gouvernance — l’accès et la politique de conservation de chaque champ sont à ta charge. Choisis-les quand la donnée est réellement une forme nouvelle, pas une variation légère d’une des quatre entités intégrées. </Note> ## En pratique — un agent CRM Un agent CRM qui répond à « où en est-on avec Acme ? » utilise les deux formes. L’entité Contacts tient la fiche canonique — nom, contact principal, secteur, statut. Les documents tiennent les notes d’appel et les contrats. L’agent lit directement les champs du contact, récupère des passages dans les documents et répond avec les deux : le statut structuré depuis Contacts, le contexte le plus frais depuis la dernière note d’appel. Sans fiches structurées, l’agent doit retrouver Acme par son nom à travers des PDF et risque de confondre deux contacts aux noms proches. Sans documents, l’agent connaît le statut d’Acme mais ne peut pas te dire ce qui s’est passé pendant l’appel de mardi. ## Quand y recourir | Choisis … quand | Documents | Fiche structurée | | ----------------------------------------------------------- | --------- | ---------------- | | La source est de la prose libre | ✓ | | | La source a des champs typés et tu veux des valeurs exactes | | ✓ | | Tu dois croiser de nombreuses fiches | | ✓ | | L’agent doit citer des passages par leur emplacement | ✓ | | ## Où cela s’inscrit Les données structurées sont la couture entre tes données opérationnelles et la surface agent. Utilise les quatre entités intégrées pour ce qu’elles couvrent ; passe aux [modèles de contenu](/fr/platform/admin/governance/content-models) quand une cinquième forme apparaît. La lecture suivante à mettre en file est [Documents](/fr/platform/knowledge/documents) — le pipeline d’indexation qui sert la moitié non structurée. # Entrées de connaissances Source: https://tale.dev/docs/fr/platform/knowledge/knowledge-entries Les entrées de connaissances sont la surface « faits » de la base de connaissances. Là où un document transporte un fichier entier, une entrée porte un seul fait, petit et durable — « le magasin ouvre à 9 h », « le délai de retour est de 3 jours » — indexé par un nom de sujet. Les entrées empruntent le même pipeline d’indexation que les documents, si bien que chaque agent dont le périmètre les couvre les récupère et les cite comme n’importe quelle source ; ce qui les rend particulières, c’est la façon dont elles entrent et dont les corrections remplacent ce qu’elles corrigent. <Frame caption="L’onglet Entrées de connaissances — sujet, contenu, source et statut d’indexation par fait."> ![L’onglet Entrées de connaissances listant trois faits ajoutés à la main, chacun avec l’étiquette de source Manuel et le badge de statut Indexé.](/images/platform/knowledge-entries-list.webp) </Frame> ## D’où viennent les entrées **Depuis le chat, avec ton approbation.** Les agents dont l’outil d’écriture dans les connaissances est activé peuvent proposer d’enregistrer un fait que tu as énoncé ou corrigé pendant un chat. La proposition apparaît comme une carte dans le chat — **Enregistrer dans la base de connaissances**, avec le sujet et le contenu complet ; quand le sujet existe déjà, la carte devient **Mettre à jour la base de connaissances** et prévient que l’approbation remplacera l’entrée existante. Rien n’atterrit tant que tu n’as pas cliqué sur **Approuver** ; **Rejeter** écarte la proposition. <Note> L’outil est désactivé par défaut — active-le agent par agent dans les réglages d’outils de l’agent. Un agent ne peut jamais écrire dans les connaissances partagées de l’organisation sans qu’un humain valide le texte exact. </Note> **À la main.** Clique sur **Ajouter une entrée** dans **Connaissances > Entrées de connaissances**. Donne-lui un **Sujet** (120 caractères au maximum — court et stable, comme un titre) et le **Contenu** en markdown (8 000 caractères au maximum), rédigé pour rester compréhensible sans la conversation autour. La colonne **Source** distingue les deux origines : **Chat** ou **Manuel**. ## Une seule version active par sujet Le sujet est la clé de déduplication : une proposition de chat approuvée pour un sujet existant, ou une modification, remplace la version active au lieu d’en ajouter une seconde — la base de connaissances ne sert jamais deux versions du même fait. Ajouter une nouvelle entrée sous un sujet existant est refusé avec une erreur de sujet en double ; modifie l’entrée existante à la place. Les versions remplacées ne sont pas perdues. Ouvre une entrée pour voir ses détails — le statut d’indexation, la dernière mise à jour et l’**Historique des versions**, avec chaque version remplacée et la date de son remplacement. Seule la version active est indexée pour la récupération ; l’historique existe pour l’audit et la référence. ## Modifier, indexer, supprimer Modifier crée une nouvelle version active et réindexe en arrière-plan — le badge de statut repasse par l’indexation et revient à **Indexé** quand la recherche reprend le nouveau texte. Supprimer retire l’entrée entière : la confirmation prévient qu’elle disparaît aussi de la base de connaissances, que les agents ne pourront plus la trouver, et que l’action est irréversible. Si le fait était juste, ajoute-le de nouveau. ## Où cela s’inscrit Les entrées de connaissances bouclent la boucle entre les conversations et la base de connaissances : une correction faite une fois dans le chat devient un fait que chaque agent récupère, avec un humain qui approuve la formulation exacte, et une seule version active par sujet qui garantit que l’ancien fait disparaît quand le nouveau atterrit. Pour la moitié au format fichier, lis [Documents](/fr/platform/knowledge/documents) ; pour la façon dont les agents s’y relient et récupèrent, lis [Connaissances de l’agent](/fr/platform/agents/knowledge). # Exploration de sites web Source: https://tale.dev/docs/fr/platform/knowledge/crawling Un site web est la forme que prend, dans la base de connaissances, « un site public que l’agent doit connaître ». Tu confies à Tale un domaine et un intervalle d’analyse ; le crawler découvre les URL, va chercher les pages, extrait le contenu principal, découpe le texte et calcule ses embeddings, puis sert les fragments au moment de répondre, exactement comme pour les Documents. Quand tu veux des pages précises plutôt qu’un site entier, confie-lui une liste d’URL — le même pipeline tourne alors exactement sur les pages que tu nommes. Cette page parcourt ce que tu vois entre l’ajout d’un domaine et les citations de ses pages par les agents. <Frame caption="Ajouter un site web — en mode « Site web entier », un domaine plus un intervalle d’analyse, et le formulaire est complet."> ![La boîte de dialogue Ajouter un site web de l’onglet Sites web, demandant un domaine et un intervalle d’analyse réglé par défaut sur toutes les 6 heures.](/images/platform/websites-add-dialog.webp) </Frame> ## Ajouter un site web Ouvre **Connaissances > Sites web** et clique sur **Ajouter un site web**. Le **Type de source** décide de ce que couvre la source : **Site web entier** — le réglage par défaut — explore tout ce qui se découvre sur le domaine, **Liste d'URL** indexe exactement les pages que tu colles (la section suivante y revient). En mode Site web entier, la boîte de dialogue a deux champs : **Domaine** (par exemple `example.com`) et **Intervalle d'analyse** — toutes les heures, toutes les 6 heures (le réglage par défaut), toutes les 12 heures, tous les jours, tous les 5, 7 ou 30 jours. Tale normalise le domaine — `https://`, `www.` et les barres obliques finales sont tolérés — et rejette tout ce qui ne se lit pas comme un nom d’hôte. Clique sur **Enregistrer** ; le planificateur ramasse les nouveaux sites à son prochain passage, la première analyse démarre donc en quelques secondes. <Note> Il n’y a ni champ d’authentification ni liste de chemins à inclure ou exclure — le crawler voit exactement ce qu’un visiteur anonyme voit. Tout ce qui vit derrière une connexion relève de [Documents](/fr/platform/knowledge/documents) ou d’une [connector](/fr/platform/connectors/overview). </Note> ## Ajouter une liste d’URL Passe le **Type de source** sur **Liste d'URL** quand tu veux des pages précises, pas un site entier — un rapport ici, une page de tarifs là, quelques PDF. Colle une URL par ligne dans le champ **URL** ; seules ces pages sont chargées et indexées, le crawler ne suit aucun lien au-delà. Les lignes peuvent mélanger plusieurs sites web : la boîte de dialogue les regroupe en une source par site web, un collage qui couvre trois domaines crée donc trois lignes. Recoller une liste pour un site qui en a déjà une ajoute les nouvelles URL à la source existante — rien ne se perd, et l’intervalle d’analyse passe à ton nouveau choix. Les listes se ré-analysent à la même cadence que les sites entiers ; leurs lignes portent le badge **Liste d'URL** dans la table. ## Comment les URL sont découvertes Le crawler tente d’abord la voie coopérative. Il résout la page d’accueil et parcourt chaque sitemap que le site publie — `sitemap.xml`, index de sitemaps, sitemaps compressés ou déclarés dans le robots.txt — pour collecter la liste d’URL que le site entretient lui-même. Les sites au sitemap sain obtiennent une couverture complète, sans rien deviner. Quand le sitemap manque, est cassé ou vide, le crawler se rabat sur un parcours de liens en largeur depuis la page d’accueil : liens du domaine uniquement, liens externes et sociaux écartés, navigation et pied de page retirés avant l’extraction. Ce repli couvre les sites sans sitemap, mais il ne peut pas égaler la complétude d’un sitemap bien tenu. Les pages ne sont pas le seul contenu qui compte. Les documents liés — PDF et fichiers Office (`docx`, `xlsx`, `pptx`, `odt`) — sont chargés et indexés comme des pages, que le crawler les trouve sur un site ou que tu les listes directement dans une liste d’URL. Les images et les documents numérisés sans texte intégré sont ignorés : l’analyse note qu’elle a regardé et n’enregistre rien. ## Le planning d’analyse L’intervalle décide de la fréquence à laquelle les URL sont redécouvertes et les pages rechargées. Chaque analyse est incrémentale : les pages inchangées sont sautées, les pages modifiées sont réextraites et réindexées, les nouvelles pages sont ajoutées, les pages disparues sont retirées de l’index. Une liste d’URL suit la même cadence avec un ensemble fixe — les pages listées sont rechargées selon le planning, rien de nouveau n’est découvert. Les agents pointés sur le site voient le nouveau contenu dès la récupération suivante — il n’y a pas d’étape de publication séparée. ## Lire la table Chaque ligne montre le domaine (les sources de type liste d’URL portent à côté le badge **Liste d'URL**), son **Statut** — **Inactif** entre deux analyses, **En cours d'analyse** en vol, **Actif** après une analyse réussie, **Erreur** quand la dernière analyse a échoué, **Suppression en cours** pendant le retrait — le pourcentage **Indexé** (survole-le pour le compte de pages explorées sur le total), l’heure de dernière analyse dans **Analysé** et l’**Intervalle**. Ouvre une ligne pour le titre et la description découverts du site ; clique sur **Voir les pages** pour la liste des pages — chaque URL indexée avec son nombre de mots, son nombre de fragments et sa dernière exploration, plus un champ de recherche qui interroge les fragments indexés : le moyen le plus rapide de vérifier ce qu’un agent récupérerait réellement. ## Où cela s’inscrit L’exploration est le moyen économique d’amener un site public dans le contexte des agents : un domaine — ou une liste d’URL choisie à la main — une cadence, et le reste est l’affaire du crawler. La contrepartie est la frontière du visiteur anonyme — le contenu privé passe par [Documents](/fr/platform/knowledge/documents) ou une connector. Pour la place des lignes Sites web à côté des Contacts, Produits et Fournisseurs, lis [Données structurées](/fr/platform/knowledge/structured-data). # Base de connaissances Source: https://tale.dev/docs/fr/platform/knowledge/overview La base de connaissances est l’espace où vivent les données de l’organisation pour que les agents puissent les lire et les citer. Les éditeurs la constituent une fois ; les agents y puisent au moment de répondre — c’est ce qui permet à un agent Tale de répondre avec ta réalité plutôt qu’avec les données d’entraînement du modèle. L’espace s’ouvre sur six onglets : **Documents**, **Entrées de connaissances**, **Sites web**, **Produits**, **Contacts** et **Fournisseurs**. Tu préfères regarder d’abord ? L’épisode 3 parcourt toute la bibliothèque en trois minutes — indexation, entrées, fiches, crawler et périmètres, sous-titres compris. <Video src="/videos/fr/tutorials/ep3-knowledge/ep3-knowledge.fr.mp4" poster="/videos/fr/tutorials/ep3-knowledge/ep3-knowledge.fr.webp" captions="/videos/fr/tutorials/ep3-knowledge/ep3-knowledge.fr.vtt" lang="fr" title="Épisode 3 — Connaissances" caption="Épisode 3 — Connaissances (2:45)"> </Video> <Frame caption="L’onglet Documents — le coin le plus utilisé de la base de connaissances."> ![L’onglet Documents de la base de connaissances listant trois fichiers texte téléversés avec les colonnes taille, source, statut RAG et équipes.](/images/get-started/documents-list.webp) </Frame> ## Les deux formes Tout ce que contient l’espace prend l’une de deux formes. Le **contenu indexé** — les fichiers de Documents, les faits des Entrées de connaissances, les pages qu’une exploration de site web ramène — passe par le pipeline d’indexation (extraction, découpage, embeddings, stockage) pour que les agents récupèrent les passages pertinents et les citent. Les **fiches typées** — Produits, Contacts, Fournisseurs — sont des lignes à champs nommés que les agents lisent comme des données, pas comme de la prose : des valeurs exactes, sans approximation de récupération. La forme que tu choisis décide de la façon dont un agent peut exploiter le contenu — c’est pourquoi [Données structurées](/fr/platform/knowledge/structured-data) est une page de décision, pas seulement une référence. ## Où réside l'index Le contenu indexé est intégré dans la base de données vectorielle intégrée de Tale — un stockage **PostgreSQL** (ParadeDB) qui combine les embeddings `pgvector` avec la recherche par mots-clés (BM25) et fusionne les deux, de sorte que la recherche capte à la fois les correspondances sémantiques et les termes exacts. Il est livré avec la plateforme : rien de plus à licencier ni à exploiter, et la recherche, les citations, les permissions par équipe et l'effacement RGPD agissent tous sur un seul stockage. Les embeddings proviennent du **modèle d'embedding** configuré par l'organisation — un admin d'org choisit le fournisseur, le modèle et la largeur des vecteurs dans **Paramètres > Résidence des données**, et la recherche de connaissances refuse avec une erreur actionnable tant qu'aucun n'est configuré, plutôt que de deviner un modèle. **Apporte ta propre base de données vectorielle — c'est du Postgres.** Comme le stockage vectoriel est PostgreSQL, tu peux pointer la base de connaissances de Tale vers n'importe quel PostgreSQL géré que tu exploites (avec les extensions `pgvector` et `pg_search`/ParadeDB) au lieu de celui fourni — tes données, ton infrastructure, ta région. Un admin d'org renseigne la connexion dans **Paramètres > Résidence des données** — saisis l'hôte, la base et les identifiants de ton Postgres, de la même façon pour un déploiement auto-hébergé et une instance cloud dédiée. Tale vérifie la connexion et la présence des extensions requises avant que tu bascules. Voir [Résidence des données](/fr/self-hosted/configuration/data-residency) pour les détails de connexion et les prérequis d'extensions. ## Comment les agents y puisent Un agent ne voit pas toute la bibliothèque par défaut. L’onglet **Base de connaissances** de l’agent contrôle son périmètre de récupération — les parties de la bibliothèque qu’il interroge au moment de répondre — et les éléments limités à une équipe restent invisibles pour les agents et les membres hors de cette équipe. La récupération passe par les outils RAG de l’agent, et chaque passage récupéré porte sa source : les citations renvoient au fichier, à l’entrée ou à la page d’origine. La mécanique côté agent vit dans [Connaissances de l’agent](/fr/platform/agents/knowledge). ## Pages dans cette section <CardGroup cols="2"> <Card title="Documents" icon="file-text" href="/fr/platform/knowledge/documents"> Téléverser des fichiers, le pipeline d’indexation, les formats pris en charge et le cycle de vie de chaque document. </Card> <Card title="Entrées de connaissances" icon="book-open" href="/fr/platform/knowledge/knowledge-entries"> De petits faits indexés par sujet — capturés depuis le chat avec approbation ou ajoutés à la main. </Card> <Card title="Exploration de sites web" icon="globe" href="/fr/platform/knowledge/crawling"> Transformer un site public en connaissances — domaine, intervalle d’analyse et vue des pages indexées. </Card> <Card title="Données structurées" icon="table" href="/fr/platform/knowledge/structured-data"> Contacts, Produits, Fournisseurs, Sites web — quand une fiche typée bat un document. </Card> </CardGroup> ## Où cela s’inscrit La base de connaissances est la couche de données sur laquelle repose chaque réponse ancrée ; sans elle, les agents ne savent que ce que le modèle sait déjà. Fais entrer le contenu par l’onglet qui correspond à sa forme, puis branche les agents dessus — la suite naturelle est [Documents](/fr/platform/knowledge/documents) pour les fichiers, [Données structurées](/fr/platform/knowledge/structured-data) pour les fiches et [Connaissances de l’agent](/fr/platform/agents/knowledge) pour le volet récupération. # Fournisseurs IA Source: https://tale.dev/docs/fr/platform/admin/providers Tale ne répond à aucun prompt tant que ton organisation ne détient pas d’identifiants valides pour au moins un fournisseur IA. **Paramètres > Fournisseurs IA** est l’endroit où vivent ces identifiants, et le seul où on peut en créer. Les Administrateurs et les Développeurs ouvrent la page ; tous les autres en rencontrent le résultat plus tard, sous la forme de la liste de modèles qu’ils peuvent choisir dans le chat, sur un agent ou sur une étape de workflow. ## Connectors et identifiants Deux choses distinctes se rejoignent sur cette page, et les distinguer rend tout le reste évident. Un **connecteur** est ce que la plateforme sait d’avance d’un fournisseur : le dialecte réseau qu’il parle, l’endpoint sur lequel il répond, d’où vient sa liste de modèles, et quelles méthodes d’authentification il accepte. Les connecteurs sont livrés avec la plateforme. Tu ne peux ni en ajouter, ni en modifier, ni en supprimer depuis l’interface, et une mise à niveau peut en apporter d’autres. Les **identifiants** sont ta moitié — la part qui autorise réellement un appel. Tu en enregistres autant que nécessaire par connecteur : une clé de production à côté d’une clé de test, une clé par service, une variable gérée par les ops à côté d’une clé que tu fais tourner à la main. Chacun porte un nom, une méthode d’authentification, une liste de modèles autorisés facultative et un état d’activation — et l’un d’eux est le défaut. Voici les connecteurs livrés aujourd’hui : | Connector | Format réseau | Catalogue de modèles | | -------------------- | ---------------------- | ------------------------------ | | OpenRouter | API compatible OpenAI | Catalogue OpenRouter | | OpenAI | API compatible OpenAI | Catalogue intégré | | Anthropic | API Anthropic Messages | Catalogue intégré | | Gemini | API compatible OpenAI | Catalogue intégré | | Azure OpenAI | API compatible OpenAI | Pas de catalogue | | DeepSeek | API compatible OpenAI | Catalogue intégré | | Moonshot AI (Kimi) | API compatible OpenAI | Catalogue intégré | | Qwen (Alibaba) | API compatible OpenAI | Catalogue intégré | | SpaceXAI | API compatible OpenAI | Catalogue intégré | | Z.ai (GLM) | API compatible OpenAI | Catalogue intégré | | Vercel AI Gateway | API compatible OpenAI | Endpoint models du fournisseur | | Nous Portal (Hermes) | API compatible OpenAI | Pas de catalogue | ## Ce que la page affiche **Identifiants** est un tableau de ce que ton organisation détient réellement — une ligne par identifiant stocké, pas une par fournisseur livré. Une ligne montre son nom, le fournisseur qu’il authentifie, sa méthode d’authentification et ses coordonnées : un aperçu masqué de la clé stockée ou le nom de la variable d’environnement qui la porte, plus l’URL d’endpoint propre à l’identifiant là où le fournisseur en réclame une et le nombre de modèles que sa liste autorise. Un badge **Par défaut** marque celui vers lequel les requêtes retombent, un badge **Désactivé** ceux qui sont coupés. Le menu d’actions de la ligne porte tout le reste. Deux avertissements apparaissent ici plutôt que dans une boîte de dialogue. Un fournisseur dont le catalogue de modèles n’a pas pu être récupéré le dit sur chaque ligne qui en dépend — une clé qui fonctionne ne sert à rien tant que Tale ignore quels modèles le fournisseur sert. Et un fournisseur qui a des identifiants mais aucun défaut est nommé au-dessus du tableau : les requêtes ne peuvent pas en choisir un automatiquement tant que tu n’en promeus pas un. Sous le tableau, **Harnesses** indique comment chaque harness de code se résout pour ton organisation. La section est en lecture seule ; ce sont les identifiants au-dessus qui la changent. ## Ajouter des identifiants <Steps> <Step title="Choisir le fournisseur"> **Ajouter des identifiants** ouvre le catalogue livré. Les fournisseurs pour lesquels tu détiens déjà un identifiant viennent en premier, sous **Utilisés** ; tout le reste suit en dessous, par ordre alphabétique. Chaque entrée nomme ses faits réseau — le format d’API et l’hôte de l’endpoint, comme `API compatible OpenAI · openrouter.ai`, ou `endpoint défini par identifiant` — et le nombre de modèles que son catalogue contient. La recherche réduit la liste ; un choix mène au formulaire, et **Retour au catalogue** en ressort. Comme le formulaire appartient au fournisseur choisi, il ne propose que ce que celui-ci accepte — on ne te demande jamais une URL de base que la plateforme connaît déjà. </Step> <Step title="Choisir la méthode d’authentification"> La méthode change le reste du formulaire : un champ secret pour **Clé API** et **Clé d’abonnement**, un nom de variable pour **Variable d’environnement**, le formulaire complet du courtier pour **Courtier d’abonnement**. </Step> <Step title="Le nommer pour la personne qui lira ensuite"> **Nom** est ce que tous les écrans suivants montrent à la place du secret. Nomme-le pour son usage — `Clé de production`, `Équipe finance`, `Géré par les ops` — parce que c’est cette étiquette que quelqu’un choisira dans une liste des mois plus tard. </Step> <Step title="Décider si tu restreins"> **Modèles autorisés** est facultatif. Laisse le champ vide et l’identifiant peut utiliser tout le catalogue du connecteur ; remplis-le et il reste confiné à ta sélection. </Step> </Steps> ### Clé API Colle le secret dans **Clé API**. Tale le stocke chiffré et ne le réaffiche jamais — la ligne montre un aperçu masqué, pas la clé. Pour faire tourner la clé, ouvre le menu de la ligne et choisis **Remplacer la clé API** ; le remplacement prend effet partout où ces identifiants servent, immédiatement. ### Variable d’environnement Ici la clé n’entre jamais dans Tale. Elle reste sur le déploiement, et l’identifiant n’enregistre que le nom de la variable qui la porte. Tu ne saisis que le suffixe ; le préfixe réservé `TALE_PROVIDER_KEY_` est fixe et ne peut pas être effacé. <Note> Tout nom hors de ce préfixe est rejeté, donc le champ ne peut jamais pointer sur un secret de déploiement étranger. Les noms sont plafonnés à 40 caractères. La variable elle-même est fournie par qui exploite le déploiement — le versant opérateur est documenté dans [Fournisseurs](/fr/self-hosted/configuration/providers). </Note> ### Abonnements et courtiers Deux méthodes couvrent les abonnements plutôt que les clés API facturées à l’usage. **Clé d’abonnement** stocke directement le secret d’abonnement d’un fournisseur ; un abonnement Nous Portal en est un cas livré. **Courtier d’abonnement** pointe vers un endpoint qui distribue un pool de jetons OAuth rotatifs — la forme qu’utilise un abonnement Claude. Le formulaire du courtier demande l’**Endpoint du courtier** et sa **Méthode HTTP**, puis comment Tale s’authentifie auprès du courtier sous **Authentification du courtier** : Aucune, Jeton Bearer ou En-tête personnalisé, avec un **Nom de l’en-tête** et le **Secret du courtier**, ou **Secret depuis une variable d’environnement** quand ce sont tes ops qui le détiennent. Le reste décrit la réponse : le **Chemin du tableau de jetons**, le **Champ du jeton**, la **Variable d’environnement cible** dans laquelle le jeton choisi est injecté, et une **Sélection du jeton** parmi Aléatoire, Premier utilisable ou Round-robin. **Avancé** porte le réglage fin : **Champ de statut**, **Valeur de statut actif**, **Champ d’expiration**, **Délai de la requête (ms)**, **Taille max de la réponse (octets)** et **Marge de sécurité avant expiration (ms)**. <Info> Les deux formes se consomment dans l’outillage propre du fournisseur plutôt que par un appel d’API ordinaire, et la boîte de dialogue le dit : **S’exécute en sandbox sur le harness de son fournisseur.** Un courtier d’abonnement Anthropic tourne sur le harness `claude-code`, une clé d’abonnement Nous Portal sur `hermes`. L’appel d’API direct n’est jamais proposé pour ces identifiants. </Info> ## Les connecteurs dont l’endpoint est défini par identifiant Azure OpenAI n’a pas d’endpoint fixe, parce que chaque ressource Azure sert le sien, sous la forme `https://<resource>.openai.azure.com/openai/v1`. L’en-tête de sa section indique que l’endpoint est défini par identifiant, et sa boîte de dialogue ajoute un champ **URL de l’endpoint** pour que chaque identifiant porte la ressource à laquelle il appartient. Azure ne livre pas non plus de catalogue de modèles, et la raison mérite d’être connue avant de remplir le formulaire : sur Azure, l’id de modèle dans une requête est le nom de déploiement que tu as choisi dans la ressource, ce que Tale ne peut pas deviner. Saisis ces noms dans les **Modèles autorisés** de l’identifiant, séparés par des virgules. Sans eux, l’identifiant ne rend aucun modèle disponible. ## Choisir les identifiants par défaut Une requête qui ne nomme aucun identifiant utilise le défaut du connecteur. C’est le cas de la majeure partie du trafic, donc le défaut est l’identifiant sur lequel le travail ordinaire doit atterrir — la clé de production partagée, pas l’expérimentation. Ouvre le menu d’une ligne et choisis **Définir par défaut**. Un seul identifiant par connecteur tient ce rôle, et en promouvoir un autre le déplace. Un identifiant désactivé ne peut pas devenir le défaut. Laisse un connecteur sans défaut et la plateforme ne choisira pas à ta place : elle le dit sur la page, et les requêtes qui ne nomment pas d’identifiant n’ont plus rien à résoudre. ## Restreindre ce qu’un identifiant peut appeler **Modèles autorisés** limite un identifiant à une partie des modèles de son connecteur. Avec un catalogue derrière, le champ est une sélection multiple cherchable ; sans catalogue, c’est une liste d’ids en texte libre. Laisse-le vide et tout le catalogue reste ouvert. Remplis-le et la ligne affiche le compte, tandis que ce qui n’y figure pas cesse de se résoudre via cet identifiant. <Tip> Une telle liste ne restreint qu’un identifiant. Pour décider d’un coup ce qu’une personne, une équipe ou un rôle peut choisir chez tous les fournisseurs, utilise les règles d’accès aux modèles sous [Contenu et modèles](/fr/platform/admin/governance/content-models). Les deux se composent : un modèle doit franchir les deux barrières avant d’apparaître dans un sélecteur. </Tip> ## Garder les catalogues de modèles à jour **Actualiser les catalogues** siège dans l’en-tête de la page et recharge chaque catalogue en ligne et rend une ligne par connecteur — le nombre de modèles trouvés, ou l’erreur rencontrée, pour qu’un fournisseur en panne soit nommé plutôt qu’ignoré en silence. Les catalogues livrés avec la plateforme n’en ont pas besoin : quand chaque connecteur en a un, la carte annonce qu’il n’y a rien à actualiser. Les catalogues en ligne sont mis en cache entre deux actualisations et aucune synchronisation ne tourne en arrière-plan — un modèle publié ce matin apparaît quand quelqu’un appuie sur le bouton. ## Désactiver et supprimer des identifiants **Désactiver** coupe un identifiant en conservant sa configuration et ses modèles autorisés. Sers-t’en quand une clé est suspecte, qu’un quota est épuisé ou qu’un service est en pause — le réactiver tient en un clic et rien n’est à ressaisir. <Warning> La suppression est immédiate et totale. Les agents et les requêtes qui utilisent ces identifiants perdent aussitôt l’accès au fournisseur, donc redirige d’abord tout ce qui en dépend. Supprimer le défaut laisse le connecteur sans défaut jusqu’à ce que tu en promeuves un autre, ce que la confirmation t’annonce avant que tu valides. </Warning> ## Où cela s’inscrit Cette page est le sol sur lequel tout le reste repose : un agent, une réponse de chat, une étape de workflow, un embedding pour la base de connaissances se résolvent tous vers un modèle, et un modèle n’est joignable que si des identifiants de cette page peuvent l’appeler. Ce qu’il en reste côté choix est couvert par le [Catalogue de modèles](/fr/platform/models), la couche de gouvernance qui restreint encore par [Contenu et modèles](/fr/platform/admin/governance/content-models), et les variables de déploiement qu’un opérateur fournit par [Fournisseurs](/fr/self-hosted/configuration/providers). # Identifiants d’connector Source: https://tale.dev/docs/fr/platform/admin/connectors Chaque connecteur est livré avec la plateforme, le travail d’administration ne consiste donc jamais à installer : il consiste à décider au nom de quels comptes Tale peut agir, puis à garder ces identifiants en bonne santé. Un connecteur porte autant de lignes que nécessaire — une par espace de travail, boutique, boîte mail ou bot — et l’une d’elles répond pour tout appelant qui n’en nomme aucune. Cette page est le versant exploitation : ce que la page affiche, comment se remplit chaque méthode d’authentification, et ce qui arrive quand tu promeus, désactives, supprimes ou reconnectes une ligne. Le catalogue lui-même — les treize connecteurs, ce que chacun apporte, et comment leurs actions rejoignent les automatisations et le chat — est sur [Connectors](/fr/platform/connectors/overview). Le temps de lecture ici est mieux investi dans le cycle de vie des identifiants, parce que c’est la partie qui varie d’une organisation à l’autre et la partie qui casse. ## Ce que la page affiche Ouvre **Paramètres > Connectors**. La page demande des droits Admin ou Développeur et c’est un tableau des identifiants que ton organisation détient — une ligne par identifiant, pas une par connecteur livré. Une ligne montre son nom, le connecteur qu’il authentifie, sa méthode d’authentification et ses coordonnées : un aperçu masqué du secret stocké, plus l’URL d’instance là où le connecteur en réclame une. Un badge **Par défaut** marque celui vers lequel une action retombe, un badge **Désactivé** ceux qui sont coupés. La recherche couvre à la fois le nom que tu as donné et le connecteur derrière ; le bouton de filtre réduit à un seul connecteur. Un lien `?connector=` réduit le tableau de la même façon, et c’est là que le détour OAuth te ramène. Deux avertissements apparaissent ici, et ils ne disent pas la même chose. _Aucun identifiant par défaut pour {connector}_ signifie que chaque ligne fonctionne mais que rien ne répond à un appelant qui n’en nomme aucune. **Reconnexion requise** sur une ligne signifie qu’une autorisation OAuth ne se renouvelle plus et redemande un consentement — l’identifiant lui-même est sain. ## Ajouter des identifiants **Ajouter des identifiants** ouvre le catalogue livré. Les connecteurs pour lesquels tu détiens déjà un identifiant viennent en premier, sous **Utilisés** ; tout le reste suit en dessous, par ordre alphabétique, chacun avec ses catégories et le nombre d’actions qu’il expose. La recherche réduit la liste ; un choix mène à l’étape de configuration, et **Retour au catalogue** en ressort. La configuration demande d’abord un **Nom**, et le texte d’aide du champ dit pourquoi il compte : le nom sous lequel une action choisit ces identifiants. Prends quelque chose qu’un auteur d’automatisations reconnaîtra des mois plus tard, comme `Boîte de support` ou `Boutique UE`. Ce qui suit le nom dépend de la **Méthode d’authentification** que le connecteur accepte. <Tabs> <Tab title="Clé API"> Un seul champ, **Clé API**. Ce sont les actions du connecteur qui décident par où la clé voyage — un en-tête imposé par le fournisseur, ou le corps de la requête là où le fournisseur l’exige. Shopify et Tavily sont les cas livrés. </Tab> <Tab title="Jeton"> Un seul champ, **Jeton**, envoyé dans l’en-tête Authorization à chaque requête. GitHub prend ainsi un jeton d’accès personnel ; Discord prend un jeton de bot, que la plateforme envoie sous le schéma propre à Discord plutôt que sous le schéma habituel. </Tab> <Tab title="Nom d’utilisateur et mot de passe"> Deux champs, **Nom d’utilisateur** et **Mot de passe**, envoyés en HTTP Basic. Le couple n’est pas toujours un login au sens courant : Confluence prend l’e-mail du compte avec un jeton d’API, Twilio prend l’Account SID avec l’Auth Token, et le connecteur WebDAV prend un mot de passe d’application WebDAV. IMAP / SMTP prend le login de la boîte elle-même. </Tab> <Tab title="OAuth"> Aucun secret à saisir, donc l’étape de configuration se réduit au passage de relais : **Connecter** te mène à l’écran de consentement du fournisseur, et Tale range ce qui revient — jeton d’accès, jeton de rafraîchissement, expiration et portées accordées — dans une nouvelle ligne. Gmail, Google Drive, Outlook, Teams et Slack se connectent ainsi. Un connecteur qui accepte les deux propose les deux, avec **Connecter** en premier. </Tab> </Tabs> Ajouter un second identifiant à un connecteur qui en a déjà un, c’est le même parcours une seconde fois — le connecteur apparaît simplement sous **Utilisés** dans le catalogue. Il n’y a aucune limite à contourner ni rien à déconnecter avant. <Note> Confluence et Shopify demandent en plus une **URL de l’instance**, faute d’hôte unique côté fournisseur. Confluence veut l’adresse de ton site Atlassian — celle où tu ouvres Confluence. Shopify veut l’adresse `myshopify.com` de ta boutique, c’est-à-dire l’adresse d’administration et non le domaine de la vitrine. Cette valeur est stockée en clair à dessein, pour que le tableau puisse montrer sur quelle instance pointe chaque ligne. </Note> ## Choisir l’identifiant par défaut Un identifiant par connecteur peut être celui **Par défaut**, et **Définir par défaut** le déplace sur n’importe quelle ligne. C’est lui qui répond quand un nœud d’automatisation ou une action de chat ne nomme aucun identifiant. La sync mail est l’exception dans l’autre sens : `conversation.sync_mailbox` parcourt chaque identifiant _actif_ du connecteur, pour qu’une deuxième boîte IMAP (ou un deuxième compte Gmail) soit relevée sans que tu aies à la promouvoir. Chaque identifiant garde sa propre position dans sa propre boîte. Le triage de boîte se répartit de la même façon via `conversation.list_mailbox_messages`. Un connecteur avec plusieurs identifiants et aucun par défaut est une configuration qui marche, avec un trou dedans. Les appelants qui nomment une ligne continuent de tourner ; les autres ne peuvent pas choisir et échouent. Promeus une ligne et le trou se referme aussitôt. ## Remplacer un secret Changer une clé est une modification de l’identifiant, pas une opération à part. Ouvre la ligne et choisis **Remplacer la clé API**, **Remplacer le jeton** ou **Remplacer le nom d’utilisateur et le mot de passe**, selon la méthode. Le secret stocké n’est jamais réaffiché, et en saisir un nouveau le remplace partout où cet identifiant est utilisé — chaque nœud d’automatisation et chaque action de chat qui pointe dessus reprend le nouveau secret sans qu’on y touche. L’identifiant garde son nom, son drapeau par défaut et son URL d’instance à travers un remplacement, rien n’a donc besoin d’être repointé en aval. **Modifier le nom et l’instance** couvre l’autre sens : renommer une ligne, ou la déplacer vers une autre instance. ## Désactiver et supprimer **Désactiver** retire un identifiant du service tout en gardant la ligne et tout ce qui y est configuré. L’identifiant apparaît comme **Désactivé** et plus rien ne se résout vers lui ; **Activer** le remet en jeu. Sers-t’en quand un compte est suspect plutôt que terminé, ou quand tu veux mettre une configuration de côté sans la perdre. <Warning> **Supprimer** agit tout de suite et sans retour. Les automatisations et actions de chat qui utilisent cet identifiant perdent l’accès à ce connecteur sur-le-champ — il n’y a pas de délai de grâce. Supprimer celui par défaut laisse le connecteur sans défaut jusqu’à ce qu’une autre ligne soit promue, et la confirmation le dit avant que tu valides. </Warning> ## Reconnecter une autorisation cassée Un identifiant OAuth dont l’autorisation stockée a expiré ou a été révoquée affiche **Reconnexion requise** avec le motif. C’est un constat de la plateforme, pas une décision d’exploitant, et c’est pourquoi cela se lit autrement qu’un identifiant désactivé à la main : rien ne cloche dans la ligne, le fournisseur a seulement cessé d’honorer l’autorisation. **Reconnecter** relance le consentement du fournisseur et rétablit l’accès sur la même ligne, en gardant son nom, son drapeau par défaut et toutes les références qui pointent dessus. Un identifiant que tu as désactivé toi-même ne se répare pas ainsi : là, c’est **Activer** qui règle la question, et reconnecter répondrait à la mauvaise. ## Connectors et serveurs MCP Les deux surfaces laissent un agent aller au-delà de Tale, et la différence tient à qui possède le pont. Un connecteur est propre à un fournisseur, arrive avec la plateforme et est maintenu pour toi ; ta part, ce sont les identifiants. Un serveur MCP est un processus que tu héberges et enregistres sous **Paramètres > API > MCP**, exposant les outils que tu écris. Prends le connecteur quand il en existe un pour le système visé, et les [serveurs MCP](/fr/platform/connectors/mcp-servers) quand il n’y en a pas. ## Où cela s’inscrit Gérer les identifiants, c’est désormais toute l’administration des connectors, puisque plus rien ne s’installe : ajouter les comptes, les nommer correctement, garder un identifiant par défaut par connecteur, et reconnecter les lignes OAuth qui expirent. [Connectors](/fr/platform/connectors/overview) est le catalogue auquel ces identifiants s’attachent, [Outils d’agent](/fr/platform/agents/tools) montre comment les actions qui en découlent arrivent dans la trousse d’un agent, et [Configurer les approbations](/fr/platform/approvals/configure) est l’endroit où les actions en écriture attendent qu’une personne les libère. </content> </invoke> # SSO d’entreprise et provisionnement Source: https://tale.dev/docs/fr/platform/admin/enterprise-sso Le SSO d’entreprise permet à tes membres de se connecter via ton fournisseur d’identité (IdP) plutôt qu’avec un mot de passe Tale, et SCIM laisse l’IdP créer, mettre à jour et désactiver automatiquement les membres et les groupes — sans invitation manuelle. Une connexion par organisation porte ensemble le protocole de connexion, la politique de provisionnement et le jeton SCIM. Tout se trouve sur une seule page : **Paramètres > SSO d'entreprise** (administrateurs uniquement). Tale parle quatre protocoles : **OIDC**, **OAuth2** simple, **SAML 2.0** pour la connexion et **SCIM 2.0** pour le provisionnement. Tu peux activer la connexion, le provisionnement, ou les deux. <Frame caption="Paramètres > SSO d’entreprise — le sélecteur de protocole et les champs de connexion sur une page ; l’URL de redirection à enregistrer dans l’IdP, prête à copier."> ![La page de paramètres SSO d’entreprise avec le menu Protocole réglé sur Microsoft Entra ID et un nom d’affichage assorti, puis une section connexion qui porte l’URL de redirection à enregistrer, une URL d’émetteur et un ID client repris de l’enregistrement d’application, un secret client vide et les scopes demandés.](/images/platform/settings-enterprise-sso.webp) </Frame> ## Choisir un protocole Ouvre **Paramètres > SSO d'entreprise**, choisis un **Protocole** et remplis uniquement les champs de ce protocole — les autres restent masqués. Un **Guide de configuration** sur la même page liste les étapes exactes et affiche les URL à coller dans ton IdP. Utilise **Tester la connexion** avant d’enregistrer pour valider la configuration, et **Enregistrer** pour activer la connexion. - **Microsoft Entra ID** — l’OIDC de Microsoft, avec synchronisation groupe-vers-équipe via Microsoft Graph. - **OIDC générique** — n’importe quel fournisseur OpenID Connect (Google, Okta, Auth0, Keycloak, …). Les points de terminaison sont détectés depuis l’émetteur. - **OAuth2** — fournisseurs sans découverte OIDC ; tu configures manuellement les points de terminaison d’autorisation, de jeton et userinfo. - **SAML 2.0** — SSO basé sur XML ; tu échanges des métadonnées avec l’IdP. ## Microsoft Entra ID 1. Connecte-toi au [centre d’administration Microsoft Entra](https://entra.microsoft.com) en tant que développeur d’applications au minimum. 2. Va dans **Entra ID > Inscriptions d'applications > Nouvelle inscription**, nomme-la et choisis **Locataire unique**. 3. Sous **URI de redirection**, sélectionne la plateforme **Web**, colle l'**URL de redirection** affichée sur la page Tale, puis clique sur **Inscrire**. 4. Sur la **Vue d'ensemble**, copie l'**ID d'application (client)** et l'**ID de répertoire (locataire)**. Ton URL d’émetteur est `https://login.microsoftonline.com/{tenant-id}/v2.0`. 5. Ouvre **Certificats et secrets > Nouveau secret client** et copie la **Valeur** du secret (pas son ID). 6. Dans Tale, choisis **Microsoft Entra ID** et saisis l’ID client, le secret client et l’URL d’émetteur. 7. Pour la synchronisation groupe-vers-équipe, ajoute l’autorisation Microsoft Graph **GroupMember.Read.All** sous **Autorisations d'API** et accorde le consentement administrateur. 8. Pour la synchronisation de documents OneDrive et SharePoint, ajoute les autorisations Microsoft Graph **Files.Read** et **Sites.Read.All** sous **Autorisations d'API** et accorde le consentement administrateur. Une nouvelle connexion demande les deux par défaut — le token SSO sert aussi de token Graph, les membres peuvent donc importer des fichiers dès la connexion. Si l’organisation ne veut que la connexion, retire ces deux scopes du champ **Scopes** ; l’entrée Microsoft 365 reste alors masquée sur la page des documents. ## Google Google se configure comme un fournisseur OIDC générique. 1. Dans la [console Google Cloud](https://console.cloud.google.com), ouvre **API et services > Identifiants > Créer des identifiants > ID client OAuth**. 2. Choisis le type d’application **Application Web**. 3. Sous **URI de redirection autorisés**, ajoute l'**URL de redirection** affichée sur la page Tale, puis enregistre. 4. Copie l'**ID client** et le **secret client** en haut de la page du client. 5. Dans Tale, choisis **OIDC générique**, saisis l’ID client et le secret, et définis l’URL d’émetteur sur `https://accounts.google.com`. Les points de terminaison sont détectés automatiquement. L’OIDC standard de Google ne renvoie **pas** les appartenances aux groupes : la synchronisation groupe-vers-équipe n’est donc pas disponible avec Google seul — elle nécessite l’Admin SDK / l’API Cloud Identity avec un administrateur Workspace. La connexion et le mappage de rôle par claim fonctionnent normalement. ## OIDC générique et OAuth2 Pour tout autre fournisseur OIDC (Okta, Auth0, Keycloak), choisis **OIDC générique**, colle l'**URL d'émetteur** et l’ID/secret client — Tale lit les points de terminaison d’autorisation, de jeton et userinfo depuis le `.well-known/openid-configuration` de l’émetteur. Si un fournisseur expose OAuth2 mais pas de document de découverte, choisis **OAuth2** et saisis manuellement les URL des points de terminaison d'**autorisation**, de **jeton** et **userinfo**. Lorsque le fournisseur utilise des noms de claims non standard, mappe **e-mail**, **nom** et **groupes** dans les champs avancés de la connexion (les chemins en points sont pris en charge, p. ex. `realm_access.roles`). ## SAML 2.0 1. Dans Tale, choisis **SAML 2.0**. La page affiche ton **URL des métadonnées SP** et ton **URL ACS (réponse)** — copie-les. 2. Dans ton IdP, crée une nouvelle application SAML 2.0. Définis son **URL ACS** et son **Entity ID / Audience** sur les valeurs SP affichées (ou importe l’URL des métadonnées SP), et le format **Name ID** sur l’adresse e-mail. 3. Sous **Importer les métadonnées de l'IdP**, colle l’URL des métadonnées de fédération de ton IdP et clique sur **Importer** — ou clique sur **Téléverser le XML** si ton IdP ne propose qu’un fichier à télécharger. Tale lit les métadonnées et remplit l’ID d’entité, l’URL de connexion et le certificat de signature dans les champs ci-dessous, sans que tu aies à les ressaisir. Les trois champs restent modifiables — vérifie les valeurs importées (ou saisis-les toi-même si ton IdP ne publie aucune métadonnée) avant d’enregistrer. 4. Mappe les attributs **e-mail**, **nom** et **groupe** dans ton IdP ; si leurs noms diffèrent des valeurs par défaut, indique les noms d’attributs correspondants dans les champs avancés de Tale. Tale prend en charge le SAML initié par l’IdP (l’IdP envoie une assertion à l’URL ACS) et le SAML initié par le SP (un membre clique sur **Se connecter avec le SSO** et Tale redirige vers l’IdP). Les assertions signées sont requises ; les assertions chiffrées sont prises en charge si tu fournis une paire de clés SP. ## Plusieurs organisations sur un même déploiement Un déploiement peut héberger plusieurs organisations, chacune avec sa propre connexion. Sur la page de connexion, clique sur **Continuer avec SSO**, puis choisis ton organisation dans la liste — chaque entrée affiche le **Nom affiché** de la connexion. Ce nom est visible par quiconque sur la page de connexion ; définis un nom clair par connexion dans **Paramètres > Enterprise SSO**. ## Provisionnement : rôles et équipes Chaque protocole partage une politique de provisionnement : - **Rôle par défaut** — le rôle attribué à un membre nouvellement provisionné (Membre par défaut). - **Attribution automatique des rôles** — lorsqu’il est activé, des règles de mappage associent un intitulé de poste, un rôle d’application, un groupe ou un claim à un rôle de la plateforme ; le rôle par défaut s’applique si rien ne correspond. - **Synchroniser les groupes en équipes** — lorsqu’il est activé, chaque groupe IdP de l’utilisateur devient (ou rejoint) une équipe du même nom à la connexion ; **Exclure des groupes** ignore les groupes parasites (séparés par des virgules). ## Provisionnement SCIM (utilisateurs et groupes) SCIM permet à ton IdP de transmettre les changements sans que personne ne se connecte. Dans la section **Provisionnement SCIM**, clique sur **Générer un jeton** — copie-le une seule fois (il n’est plus jamais affiché) — et colle-le, avec l'**URL de base SCIM** affichée, dans les paramètres de provisionnement de ton IdP. L’IdP s’authentifie avec le jeton comme identifiant Bearer ; Tale détermine l’organisation à partir du jeton, qui constitue donc la frontière de locataire. Tale implémente SCIM 2.0 **Users** et **Groups** : créer, lire, lister (avec filtres `userName`/`displayName`), remplacer, modifier (patch) et supprimer. Les utilisateurs provisionnés correspondent à des membres de l’organisation, les groupes à des équipes. **La désactivation est douce** — lorsque l’IdP rend un utilisateur inactif (`active: false`), le rôle du membre passe à `disabled` (ce qui retire son accès), et une réactivation restaure son rôle précédent. Une **suppression** SCIM retire l’appartenance à l’organisation ; le compte utilisateur est conservé, et un nouveau provisionnement le rattache avec le rôle par défaut de la connexion. Le propriétaire de l’organisation ne peut jamais être déprovisionné via SCIM. ## Vérification Utilise **Tester la connexion** pour OIDC/OAuth2 afin de confirmer la découverte et les identifiants avant d’enregistrer. Pour SAML, importe les métadonnées SP dans ton IdP et effectue une connexion de test. Pour SCIM, la plupart des IdP proposent une action « test » ou « provisionner maintenant » qui crée un utilisateur d’exemple — vérifie qu’il apparaît sous **Paramètres > Membres**. Une connexion SSO de bout en bout se vérifie au mieux contre ton IdP réel dans une organisation de préproduction. # Membres et rôles Source: https://tale.dev/docs/fr/platform/admin/members-and-roles Les membres sont les personnes de ton organisation qui peuvent se connecter à Tale. Les rôles contrôlent ce que chaque membre peut faire — lire, écrire, configurer, gouverner. Cette page est la référence canonique pour les six rôles et les permissions par ressource que chaque rôle porte. Six rôles couvrent presque chaque équipe à laquelle Tale est livré. Les Administrateurs et Propriétaires lisent cette page quand ils montent une équipe pour la première fois, quand un audit demande qui a quel accès, ou quand ils doivent décider entre Éditeur et Développeur pour un nouveau venu. Tu préfères regarder d’abord ? L’épisode 8 parcourt l’effectif, l’échelle des rôles et les murs d’équipe en deux minutes — sous-titres compris. <Video src="/videos/fr/tutorials/ep8-people/ep8-people.fr.mp4" poster="/videos/fr/tutorials/ep8-people/ep8-people.fr.webp" captions="/videos/fr/tutorials/ep8-people/ep8-people.fr.vtt" lang="fr" title="Épisode 8 — Personnes, rôles & équipes" caption="Épisode 8 — Personnes, rôles & équipes (2:06)"> </Video> <Frame caption="La section Membres sous Paramètres > Organisation — chaque compte et le rôle qui le borne."> ![La page de paramètres Organisation avec sa section Membres listant le propriétaire de l’espace de travail et un bouton Ajouter un membre.](/images/get-started/settings-organization-members.webp) </Frame> ## Ajouter un membre Pour ajouter une personne à ton organisation, ouvre **Paramètres > Organisation**, fais défiler jusqu’à la section **Membres** et clique sur **Ajouter un membre**. Renseigne son **Nom**, son **E-mail** et son **Rôle**, puis définis un **Mot de passe** — Tale n’envoie pas d’invitation par e-mail, un mot de passe est donc requis pour créer un nouveau compte. (Si l’e-mail correspond déjà à un compte Tale, aucun mot de passe n’est demandé : la personne se connecte avec ses identifiants existants et est simplement ajoutée à cette organisation.) Lors de l’**Ajouter un membre**, Tale affiche les nouveaux identifiants **une seule fois**, en rappelant de les enregistrer maintenant : ils ne seront plus affichés. Transmets-les au nouveau membre par un autre canal ; il n’y a pas d’e-mail de réinitialisation. Quiconque oublie ensuite son mot de passe contacte un administrateur, qui peut en définir un nouveau depuis la même section Membres. Choisis le rôle dans le formulaire avant de valider ; le promouvoir ou le changer ensuite est une modification en un clic dans la même section Membres. ## Les six rôles **Propriétaire** a chaque permission qu’a Admin, plus celle qui manque à Admin : transférer la propriété et supprimer l’organisation. La plupart des équipes ont exactement un Propriétaire ; certaines en gardent deux pour la continuité. **Admin** gouverne l’organisation : membres, fournisseurs, branding, politiques de gouvernance, connectors, le journal d’audit. Les Administrateurs font tout ce que fait Éditeur et tout ce que fait Développeur, plus la surface de configuration. Ils ne peuvent pas transférer la propriété. **Développeur** construit : agents, automatisations, connectors, clés API, serveurs MCP. Les Développeurs peuvent lire chaque ressource et écrire dans la plupart, y compris les politiques de gouvernance (lecture seule). Va vers Développeur quand quelqu’un a besoin du plan API et de l’outillage d’connector. **Éditeur** organise et opère : agents, base de connaissances (documents, contacts, produits, fournisseurs, sites web), boîte de réception des conversations, approbations, bibliothèque de skills. Les Éditeurs peuvent lire les workflows mais pas les modifier ; ils peuvent lire les connectors mais pas les configurer. Va vers Éditeur quand quelqu’un fait le travail produit quotidien sans toucher au plan API ou connectors. **Membre** exécute : chat, parcourt la base de connaissances, et lit les conversations et approbations. La lecture des conversations suit l’assignation : les Membres voient les fils qui leur sont assignés ou mis en file pour leurs équipes ; le courrier vraiment non assigné est réservé au triage admin — utilise le [Routage des conversations](/fr/platform/admin/governance/policies-and-limits#routage-des-conversations) pour que le courrier entrant atterrisse dans une file d’équipe dès l’arrivée. Les Membres n’écrivent que dans le feedback de message (pouce en haut / en bas). Va vers Membre comme défaut — la plupart des utilisateurs dans la plupart des organisations sont Membres. **Désactivé** n’a aucune permission. Utilise ça pour révoquer l’accès sans supprimer le compte ; les transcriptions et l’historique d’audit restent intacts, et réactiver restaure le rôle précédent. ## La matrice de permissions | Ressource | Propriétaire | Admin | Développeur | Éditeur | Membre | Désactivé | | ------------------------- | ------------ | ----- | ----------- | ------- | ------ | --------- | | Agents | R / W | R / W | R / W | R / W | R | — | | Documents | R / W | R / W | R / W | R / W | R | — | | Produits | R / W | R / W | R / W | R / W | R | — | | Contacts | R / W | R / W | R / W | R / W | R | — | | Fournisseurs | R / W | R / W | R / W | R / W | R | — | | Projets | R / W | R / W | R / W | R / W | R | — | | Sites web | R / W | R / W | R / W | R / W | R | — | | Conversations | R / W | R / W | R / W | R / W | R | — | | Messages de conversation | R / W | R / W | R / W | R / W | R | — | | Approbations | R / W | R / W | R / W | R / W | R | — | | Exécutions workflow | R / W | R / W | R / W | R | R | — | | Traitement workflow | R / W | R / W | R / W | R | R | — | | Connectors | R / W | R / W | R / W | R | R | — | | Configs OneDrive sync | R / W | R / W | R / W | R | R | — | | Templates de prompts | R / W | R / W | R / W | R / W | R | — | | Journaux d’audit | R / W | R / W | R / W | R / W | R | — | | Politiques de gouvernance | R / W | R / W | R | R | R | — | | Feedback de messages | R / W | R / W | R / W | R / W | R / W | — | | Serveurs MCP | R / W | R / W | R / W | R | R | — | R = lecture, W = écriture, — = aucun accès. La matrice est la description faisant autorité de ce que chaque rôle peut faire sur les ressources que Tale piste ; les lignes sont l’ensemble qu’utilise le système de permissions interne au produit à la requête. ## La surface Paramètres et le menu Les Membres, Éditeurs et utilisateurs Désactivés ne voient pas la surface de configuration — seulement leurs propres paramètres personnels. Les Développeurs voient les paramètres d’organisation mais pas le sous-arbre gouvernance (sauf vues en lecture). Les Administrateurs et Propriétaires voient tout. Le menu des paramètres est groupé en **Personnel** (Compte, Préférences, Environnement — chaque rôle), **Organisation** (Équipes, la section Membres, Fournisseurs IA, Branding, Gouvernance et le reste — Admin et Propriétaire, les Développeurs en voyant un sous-ensemble) et **Développement** (la surface API et résidence des données). La gouvernance est un élément dans le groupe Organisation, pas un groupe à part, et demande l’accès Admin. ## Cas limites **Transférer la propriété** demande qu’un Propriétaire existant nomme un Admin ou Propriétaire actuel ; le nouveau rôle Propriétaire prend effet immédiatement. Le Propriétaire précédent devient Admin sauf rétrogradation explicite. **Avertissement « dernier Admin ».** La section Membres avertit quand on retire ou rétrograde le dernier Admin ou Propriétaire. L’action est autorisée — Tale ne te verrouille pas dehors — mais tu devrais garder au moins deux comptes Admin-ou-Propriétaire pour la continuité. **Réinitialiser la 2FA** se trouve sur la ligne du membre dans la section Membres. Réinitialiser efface le second facteur ; le sign-in suivant réenrôle. ## Où cela s’inscrit Les rôles sont la surface d’accès que touche chaque autre page admin : le SSO les authentifie, les clés API leur appartiennent, les journaux d’audit les nomment, les politiques de gouvernance scopent le comportement par rôle. La lecture suivante dépend de ce que tu fais ensuite. Si tu câbles le sign-in à ton fournisseur d’identité, [authentification](/fr/self-hosted/configuration/authentication) couvre les quatre modes. Si tu scopes l’accès par équipe plutôt que par rôle seul, [Équipes](/fr/platform/admin/teams) couvre la couche par équipe. # Agents (vue Admin) Source: https://tale.dev/docs/fr/platform/admin/agents La vue Admin des agents est l’annuaire, à l’échelle de l’organisation, de tous les agents qui existent dans Tale, quel qu’en soit le constructeur. Les éditeurs et les développeurs voient les agents auxquels ils ont accès dans leur propre espace ; les administrateurs et les propriétaires les voient tous, avec en plus les leviers de gouvernance et la piste d’audit par agent. Cette page couvre cette surface de supervision : ce que montre le tableau, ce qu’un administrateur peut changer, et ce qui reste sous le contrôle du propriétaire de l’agent. Cette page n’apprend pas à construire un agent : c’est la vue éditeur, sous [Concepts d’agent](/fr/platform/agents/concepts). Ce qui suit est l’autre versant — comment retrouver un agent, comment intervenir quand l’un d’eux demande de l’attention, et comment les frontières de rôle tiennent quand tu le fais. ## Ce que montre le tableau Ouvre **Paramètres > Agents** pour arriver sur la liste de l’organisation. Chaque ligne nomme un agent et indique à qui il appartient, s’il est partagé avec l’organisation ou gardé privé, et la date de sa dernière modification. La liste se cherche par nom, et le tri par défaut place les modifications les plus récentes en tête — pratique pour voir ce qui a bougé depuis ton dernier passage. Cliquer sur une ligne ouvre le même éditeur d’agent qu’un éditeur ou un développeur verrait, mais avec la lentille Admin : tous les onglets sont visibles, toutes les liaisons modifiables, et l’historique montre la trace complète des modifications, avec l’auteur et le diff de chaque enregistrement. ## Ce qu’un administrateur peut faire et pas un éditeur Les administrateurs héritent de toutes les permissions que portent les éditeurs et les développeurs sur la surface des agents. Au-delà, la vue Admin ajoute trois gestes de gouvernance. - **Restreindre la portée d’un agent.** Remettre en privé un agent partagé le retire du sélecteur de tous les membres sans rien supprimer : ses conversations et son historique restent intacts, et le repartager rétablit le comportement précédent. Sers-t’en quand un agent dérape et que tu veux en arrêter l’usage le temps de comprendre pourquoi. - **Transférer la propriété.** Le propriétaire d’un agent est le membre qui en répond, et un agent privé doit toujours en avoir un. Le transfert confie l’agent à quelqu’un d’autre ; l’ancien propriétaire ne garde que ce que son rôle lui donne. Sers-t’en quand un propriétaire change d’équipe ou s’en va. - **Appliquer une politique de gouvernance.** Un administrateur peut rattacher une politique à un agent : validations requises sur les écritures, familles d’outils permises, connectors joignables. La politique l’emporte sur la configuration de l’agent partout où les deux divergent, et le propriétaire la voit dans l’éditeur comme un badge en lecture seule. ## Ce qui reste au propriétaire de l’agent L’essentiel du travail quotidien reste à qui a construit l’agent : le renommer, réécrire ses instructions, ajuster sa portée de connaissances, accorder ou retirer des outils, lier et délier des skills, enregistrer de nouvelles versions. La vue Admin sert à intervenir, pas à reprendre la main. Si tu te surprends à modifier régulièrement les agents des autres, la bonne réponse est en général une politique de gouvernance qui cadre le comportement pour une classe d’agents, plutôt qu’une retouche manuelle sur l’un d’eux. Une chose échappe aux deux rôles : personne n’épingle un modèle à un agent. Le modèle est choisi tour par tour par celui qui envoie le message ; gouverner quels modèles sont utilisables est donc une question de [Fournisseurs](/fr/platform/admin/providers) et de [Politiques et limites](/fr/platform/admin/governance/policies-and-limits), jamais une question agent par agent. ## Audit et historique Chaque enregistrement sur un agent atterrit dans le journal d’audit avec l’auteur, l’horodatage et le champ modifié. La vue Admin en expose la tranche par agent via l’historique de l’éditeur ; les mêmes données sont accessibles pour toute l’organisation sous **Paramètres > Gouvernance**. Les liaisons se lisent en gardant cela en tête : la configuration d’un agent peut rester inchangée pendant qu’un bundle de skill qu’il lie est remplacé en dessous, et c’est la piste d’audit de ce bundle qui le montre. ## Où cela se place La vue Admin des agents est le pendant de supervision de la vue de construction de l’éditeur — les mêmes agents, une autre lentille. La plupart du temps, tu ne devrais y venir que lorsque quelque chose demande de l’attention ; le travail quotidien se passe dans l’éditeur d’agent, sous [Concepts d’agent](/fr/platform/agents/concepts). Quand la bonne réponse consiste à cadrer le comportement d’une classe d’agents plutôt que d’un seul, la suite est [Membres et rôles](/fr/platform/admin/members-and-roles), qui explique comment les politiques se rattachent aux rôles. # Équipes Source: https://tale.dev/docs/fr/platform/admin/teams Une équipe est un groupe nommé de membres qui partage l’accès aux agents, prompts, projets, connectors et conversations. Là où les rôles définissent ce qu’une personne _peut_ faire, les équipes définissent dans quelle tranche des données de l’org cette personne travaille. La plupart des orgs finissent avec une poignée d’équipes — support, ventes, opérations — et la plupart des décisions quotidiennes de permission atterrissent sur la frontière équipe, pas sur la frontière rôle. Les Administrateurs gèrent les équipes sous **Paramètres > Équipes**. Cette page est la référence pour ce qu’une équipe possède, comment marche l’appartenance, et comment la frontière équipe interagit avec les permissions basées sur les rôles documentées sous [Membres et rôles](/fr/platform/admin/members-and-roles). Lis-la une fois quand tu mets les équipes de l’org en place ; reviens quand tu réorganises. <Frame caption="Paramètres > Équipes — chaque équipe de l’organisation avec son nombre de membres, à côté de l’action Créer une équipe."> ![La page de paramètres Équipes listant trois équipes — Growth, Platform engineering et Customer success — chacune avec un membre et la date de son ajout, à côté d’un bouton Créer une équipe.](/images/platform/settings-teams.webp) </Frame> ## Ce qu’une équipe possède Une équipe porte l’appartenance et un ensemble de ressources qui lui sont cadrées. Les ressources sont : - **Agents** — les agents créés avec un cadre d’équipe ne sont visibles et éditables que par les membres de cette équipe. Les agents à l’échelle de l’org restent visibles pour quiconque a le bon rôle. - **Prompts** — les prompts enregistrés avec visibilité `Équipe` n’apparaissent que pour les membres de cette équipe. Les prompts personnels restent privés à leur propriétaire ; les prompts Globaux sont visibles à l’échelle de l’org. - **Projets** — les projets peuvent être assignés à une équipe ; les membres de l’équipe héritent de l’accès au projet sans être ajoutés un par un. - **Connectors** — les connectors restreintes à certaines équipes (sous le levier **Équipes autorisées** dans **Paramètres > Connectors**) n’apparaissent que dans les pickers de ces équipes. - **Conversations** — une conversation peut être assignée à une équipe autant qu’à un responsable individuel, depuis le sélecteur d’assignation de son en-tête. La visibilité suit cette assignation : une file d’équipe est visible pour les membres de cette équipe, une assignation personne pour cette personne, et les administrateurs et propriétaires voient tout. Les conversations vraiment non assignées (ni personne ni équipe) restent aux admins pour le triage — associe cela au [Routage des conversations](/fr/platform/admin/governance/policies-and-limits#routage-des-conversations) pour que le courrier entrant atterrisse dans une équipe dès l’arrivée. Une ressource sans cadre équipe reste visible pour quiconque dont le rôle l’autorise. Les équipes sont une couche de cadrage _additive_ — elles rétrécissent la visibilité, jamais ne l’élargissent. ## Créer une équipe Ouvre **Paramètres > Équipes** et clique sur **Créer une équipe**. Donne à l’équipe un nom (`Support`, `Ventes`, `Opérations`) et une description optionnelle ; le nom apparaît partout où l’équipe surgit — pickers, badges, accès aux documents cadré par équipe et champ d’assignation d’un projet. Enregistrer crée une équipe vide que tu peux remplir de membres depuis la ligne de l’équipe. La ligne de l’équipe porte trois sous-vues : **Membres** (qui est dans l’équipe), **Ressources** (ce que l’équipe possède) et **Paramètres** (nom, description et cycle de vie de l’équipe). La vue Ressources est la façon la plus simple de voir jusqu’où une équipe peut atteindre ; elle sert aussi de surface d’audit quand quelqu’un demande pourquoi une équipe voit un agent particulier. ## Ajouter et retirer des membres Ouvre la ligne de l’équipe et clique sur **Ajouter des membres**. Le picker liste les membres de l’org ; en cocher un l’ajoute à l’équipe. Un membre peut appartenir à plusieurs équipes ; son accès est l’union de chaque équipe dans laquelle il est plus la portée à l’échelle de l’org de son rôle. Retirer un membre d’une équipe arrache la visibilité cadrée équipe à la requête suivante ; les chats en vol se terminent, mais le thread suivant ne voit pas les ressources de l’équipe. ## Équipe versus rôle Le rôle décide ce qu’une personne peut faire ; l’équipe décide à quoi elle peut le faire. Un utilisateur de rôle Membre dans l’équipe Support peut lire les agents de l’équipe support mais ne peut pas les éditer ; un utilisateur de rôle Développeur dans l’équipe Support peut lire et écrire les agents de l’équipe support mais ne peut pas voir ceux des Ventes. Les équipes n’accordent jamais des capacités que le rôle n’a pas ; les rôles n’élargissent jamais la visibilité au-delà du cadre équipe. Quand tu as besoin d’une décision de permission que les rôles et équipes existants ne peuvent pas exprimer, le levier suivant est une politique de gouvernance — voir [Membres et rôles](/fr/platform/admin/members-and-roles) pour comment les politiques s’attachent aux rôles, et la section gouvernance pour les champs de politique eux-mêmes. ## Supprimer une équipe Clique la ligne de l’équipe, puis **Supprimer l'équipe**. La suppression est définitive — l’équipe est partie, chaque ressource cadrée équipe qu’elle possédait passe à la visibilité à l’échelle de l’org, et les membres perdent la tranche cadrée équipe de leur accès. Pas d’annulation ; les ressources orphelines restent joignables par quiconque dont le rôle l’autorise, ce qui est rarement le bon résultat. Va vers supprimer quand une équipe est vraiment retirée, pas quand elle se réorganise. ## Où cela s’inscrit Les équipes sont la couche de cadrage juste sous les rôles — les rôles disent _quoi_, les équipes disent _où_. La lecture suivante naturelle dépend de la ressource que tu cadres : [Bibliothèque de skills](/fr/platform/workspace/skills) pour comment une instruction partagée atteint tout le monde, [Connectors (vue Admin)](/fr/platform/admin/connectors) pour les identifiants qu’appellent les automatisations d’une équipe, et [Projets](/fr/platform/projects/overview) pour l’assignation projet-à-équipe. # Changelog Source: https://tale.dev/docs/fr/platform/admin/changelog Le changelog est le visualiseur in-produit qui montre les notes de version pour la plateforme Tale elle-même — pas pour le contenu que tes membres produisent. Après une mise à jour auto-hébergée ou un déploiement en cloud géré, le visualiseur liste ce qui a changé entre la version précédente et celle qui tourne maintenant. Les Administrateurs le lisent après une mise à jour pour briefer l'équipe et signaler tout ce qui affecte le travail des membres. Le visualiseur lit les notes de version depuis le dépôt Tale sur GitHub et les met en cache dans ton instance pour que la page charge même quand GitHub est injoignable. ## Où vit le changelog Le changelog a deux surfaces. La page **Quoi de neuf** sous **Aide** liste chaque release récente avec ses notes complètes. Le **toast de mise à jour** se déclenche une fois par saut de version majeure et renvoie directement à la page — le toast montre `Mis à jour vers v<version>` et reste jusqu'à fermeture pour qu'un membre absent ne manque pas l'info. Ouvre la page depuis le menu d'aide dans la barre supérieure, ou depuis le toast de mise à jour quand il apparaît. La page met en cache environ trente releases récentes ; les plus anciennes renvoient vers l'historique des releases GitHub. ## Ce que chaque entrée montre Chaque entrée de release porte quatre champs : le tag de version, la date de publication, le nom de la release (souvent un titre court) et le corps de la release en Markdown. Tale rend le corps comme GitHub — titres, listes, liens et blocs de code survivent tous. Les releases que GitHub n'a pas encore publiées affichent une courte carte explicative avec un lien vers l'historique public des releases. ## Portée Le changelog est le changelog de la plateforme — ce qui a changé dans Tale lui-même. Il ne montre pas les changements à tes agents, à tes workflows ou à ta base de connaissances ; ceux-là ont leur propre historique par ressource. Si tu cherches l'historique de version d'un agent ou d'un workflow, ouvre la ressource et passe à l'onglet **Historique**. Le visualiseur est en lecture seule et visible pour chaque membre connecté. Il n'y a pas de flag Admin-seul — quiconque a un compte peut ouvrir la page. Les données que le visualiseur récupère sont des informations publiques de release du dépôt GitHub Tale, donc il n'y a rien de portée-org à cacher. ## Une mise à jour mise en pratique Après une mise à jour auto-hébergée de `v0.42` à `v0.45`, connecte-toi et cherche le toast de mise à jour en haut à droite. Clique sur **Voir** pour ouvrir la page changelog. La page montre trois entrées de release (`v0.43`, `v0.44`, `v0.45`), les plus récentes en premier, chacune avec les notes écrites par les ingénieurs depuis la release GitHub. Parcours les points saillants, partage le lien avec l'équipe si quelque chose mérite un public plus large, et le toast s'efface au prochain rechargement. Quand la mise à jour dépasse la fenêtre cachée, la page montre les entrées les plus récentes avec une bannière qui renvoie à GitHub pour les notes plus anciennes. Le cache reste chaud pour le prochain lecteur sur ton instance. ## Où ça s'inscrit Le changelog est la lecture opérateur de ce que Tale lui-même vient de faire ; il se tient à côté du journal d'audit (qui enregistre ce que tes membres ont fait) et de la page fournisseurs (qui suit quelles versions de modèles sont câblées). Combine-le avec [mise à jour auto-hébergée](/fr/self-hosted/operate/upgrades) quand tu opères l'instance — le guide de mise à jour parcourt le saut de version, et le changelog en lit le résultat de l'autre côté. # Clés API Source: https://tale.dev/docs/fr/platform/admin/api-keys Les clés API sont les identifiants à l’échelle de l’org que Tale émet pour qu’un code externe appelle son API REST sans humain dans la boucle. Une clé authentifie l’appelant comme étant l’organisation, scopée par le rôle que tu choisis quand tu la fabriques. Les Administrateurs et Développeurs gèrent les clés ; les autres rôles ne voient pas la page. Voilà la référence pour ce qu’est une clé, comment en créer une, comment la scoper, et comment la retirer sans casser ce qui en dépend. Les clés listées ici sont différentes des jetons de session par utilisateur que Tale émet à la connexion. Ceux-ci sont de courte durée et liés à une personne ; les clés API sont de longue durée et liées à l’organisation. Va vers une clé API quand tu branches un script, une tâche cron, un service interne, ou une connector tierce à Tale ; va vers l’UI en-produit quand une personne est au clavier. <Frame caption="Paramètres > Clés API — là où les clés sont créées, rotées et révoquées."> ![La page de paramètres des clés API REST listant deux clés dont chacune n’affiche que son préfixe, sa date d’ajout et la mention Jamais utilisée, à côté d’un bouton Créer une clé API.](/images/get-started/settings-api-keys.webp) </Frame> ## Créer une clé Ouvre **Paramètres > Clés API** et clique sur **Créer une clé API**. Donne à la clé un nom qui dit qui ou quoi va l’utiliser (`Sync facturation`, `Relais Slack`, `ops-cron`), choisis le rôle qu’elle doit porter, et choisis l’expiration. Tale montre le secret exactement une fois à la création — copie-le dans ton gestionnaire de mots de passe ou ton système de déploiement avant de fermer la boîte de dialogue. Après, seul le préfixe de la clé est visible depuis la table. Le rôle que tu choisis scope tout ce que la clé peut faire. Une clé portant le rôle Développeur peut lire chaque ressource et écrire dans la plupart ; une clé portant le rôle Membre peut lire la base de connaissances et démarrer des chats mais rien configurer. Prends le plus petit rôle qui fait le job — les clés sont aussi dangereuses que le rôle qu’elles portent. ## Ce que la table montre La table des clés API liste chaque clé par nom, préfixe, rôle, créateur, horodatage de dernière utilisation et expiration. Le préfixe est les huit premiers caractères du secret — assez pour identifier la clé dans les journaux sans l’exposer. L’horodatage de dernière utilisation s’actualise à chaque requête réussie que fait la clé ; une clé non utilisée depuis des semaines est généralement sûre à retirer. La ligne de filtre te laisse rétrécir par rôle, créateur et fenêtre d’expiration. Le tri par défaut est « créées le plus récemment d’abord » ; le tri secondaire est « utilisées le plus récemment ». ## Roter une clé Pour roter, crée d’abord la nouvelle clé, déploie-la sur le système qui utilise l’ancienne, vérifie que la nouvelle fonctionne (l’horodatage de dernière utilisation s’actualise), et alors seulement révoque l’ancienne. Tale n’autorote pas les clés ; la discipline du chevauchement est la tienne. La rotation est le bon mouvement quand on soupçonne une fuite, quand quelqu’un ayant accès à la clé quitte l’organisation, ou au rythme que ta politique de sécurité impose. ## Révoquer une clé Clique la ligne, puis **Révoquer**. Une clé révoquée arrête d’authentifier immédiatement — toute requête en vol se termine, mais la suivante échoue avec `401`. Les clés révoquées restent dans la table pour la piste d’audit ; la ligne les marque comme révoquées et montre qui les a révoquées et quand. Pas d’annulation pour la révocation ; si tu révoques la mauvaise clé, fabriques-en une nouvelle. ## Périmètres et limites Chaque clé porte les permissions de son rôle au moment de chaque requête, pas au moment de la création. Si tu modifies les permissions d’un rôle via une politique de gouvernance, chaque clé portant ce rôle hérite du changement à la requête suivante. Les limites de débit de l’org s’appliquent par clé, pas par organisation ; une clé bruyante ne ralentit pas une clé tranquille. Une clé peut être restreinte plus encore par une allowlist IP à la création. L’allowlist prend une liste de blocs CIDR séparés par virgules ; les requêtes hors liste échouent avec `403`. Va vers l’allowlist IP quand le système appelant a une sortie stable et que tu veux de la défense en profondeur. ## Où cela s’inscrit Les clés API sont le pont entre Tale et le code externe ; elles s’asseyent à côté des [Connectors](/fr/platform/admin/connectors) (systèmes tiers que Tale appelle) et des [déclencheurs webhook des automatisations](/fr/platform/automations/triggers) (systèmes qui appellent Tale sur événement). La lecture suivante naturelle est l’API REST elle-même — voir la référence API dans l’onglet Develop pour la surface contre laquelle une clé authentifie, et voir [Membres et rôles](/fr/platform/admin/members-and-roles) pour la carte rôle-vers-permission que chaque clé hérite. # Politiques et limites Source: https://tale.dev/docs/fr/platform/admin/governance/policies-and-limits Politiques et limites est la surface où tu plafonnes ce que tes membres et agents peuvent consommer. Les budgets plafonnent les tokens, le coût et les requêtes par période de facturation ; les contrôles de fonctionnalité activent la recherche web, l’exécution de code et l’upload de fichiers par scope ; la politique d’upload régit les types et tailles de fichiers qu’un membre peut joindre ; la politique de rétention décide combien de temps chaque type de donnée vit avant le nettoyage. Les Administrateurs et Propriétaires lisent cette page quand une charge dépasse le budget, quand une fonctionnalité doit être coupée pour un sous-ensemble d’utilisateurs, ou quand un régulateur nomme une fenêtre de rétention différente du défaut. <Frame caption="Gouvernance > Politiques et limites — le tableau des règles de budget, au-dessus de la politique d’upload et des contrôles de rétention."> ![La page de gouvernance Politiques et limites montrant trois règles de budget mensuelles — une pour l’organisation entière, une par défaut pour tous les utilisateurs et une pour le rôle developer, chacune plafonnant les tokens, le coût et les requêtes — au-dessus des champs de politique d’upload pour les types de fichiers autorisés, les tailles et le volume.](/images/platform/governance-policies-limits.webp) </Frame> ## Un budget mis en pratique Pour plafonner la dépense mensuelle d’un Éditeur, ouvre **Paramètres > Gouvernance > Budgets** et clique sur **Ajouter une règle**. Choisis **Rôle** comme scope, **Éditeur** comme cible, règle la période sur **Mensuel** et entre un coût max en USD. Enregistre et la prochaine requête de mois-période qui pousserait un Éditeur au-delà du plafond est refusée avec une erreur budget-dépassé. Un seuil d’avertissement sous le plafond déclenche une alerte avant que le plafond ne soit atteint. Les scopes plus étroits l’emportent sur les plus larges — une règle utilisateur bat une règle équipe bat une règle rôle — et les limites au niveau org s’appliquent toujours par-dessus comme plafond additionnel. ## Les quatre couches de politique **Budgets** sont des plafonds de tokens, coût et requêtes par scope et période. Les scopes sont org, rôle, équipe, utilisateur ou clé API. Chaque règle porte un plafond de tokens, un plafond de coût en USD, un plafond de requêtes optionnel et un seuil d’avertissement exprimé en pourcentage du plafond. Une règle sur clé API vise une seule clé émise (choisis **Clé API** comme scope, puis la clé depuis **Paramètres > API**) et ne plafonne que le trafic authentifié avec cette clé — l’API REST et compatible OpenAI — pour que tu mesures une connector précise sans toucher à l’usage in-app. La génération d’images est mesurée par coût et nombre de requêtes, pas par tokens — une requête d’image ne rapporte aucun token, alors plafonne les dépenses d’images avec le plafond de coût ou de requêtes, pas celui de tokens. **Contrôles de fonctionnalité** activent la recherche web, l’exécution de code et l’upload de fichiers par scope, et plafonnent les tokens de contexte max pour les réponses AI. Une fonctionnalité coupée pour un scope cache la bascule dans le chat et refuse la requête côté serveur. **Politique d'upload** régit les extensions de fichiers, types MIME et tailles qu’un membre peut joindre. Elle plafonne aussi le volume total par utilisateur — utile quand le stockage est mesuré. Désactive la politique pour un défaut permissif ; active-la pour appliquer les listes. **Politique de rétention** décide combien de temps chaque type de donnée (historique de chat, documents, prompts, journaux d’audit, registre d’utilisation, exécutions de workflow et plus) reste avant que la passe de nettoyage ne retire la ligne. La page affiche les bornes imposées par l’opérateur, la surcharge par organisation dans ces bornes, et une fenêtre de grâce avant la suppression dure. ## Priorité Les quatre couches partagent la même échelle de scope : utilisateur > équipe > rôle > org > défaut. La règle la plus étroite l’emporte. Là où une couche porte un plafond au niveau org (budgets), le plafond s’applique comme plafond additionnel au-dessus de toute règle plus étroite. Un budget sur clé API sort de l’échelle comme son propre bucket indépendant : il lie le trafic de la clé elle-même, indépendamment des plafonds utilisateur, équipe ou org de son propriétaire, si bien qu’une seule clé peut être tenue à une allocation plus serrée que la personne qui l’a émise. ## Bornes de rétention et approbations La politique de rétention vit à l’intérieur de bornes imposées par l’opérateur — l’opérateur en self-hosted règle un plancher et un plafond par catégorie, et la valeur de l’organisation se clampe à cette plage. Quand l’opérateur propose un plancher plus serré ou un plafond plus bas, le changement remonte comme proposition que les Administrateurs peuvent appliquer ou rejeter. Les réductions de la politique atterrissent avec un bandeau de changement en attente et une fenêtre de grâce avant prise d’effet — la même grâce donne aux Administrateurs la chance d’annuler. ## Délai d’inactivité de session Le délai d’inactivité de session déconnecte les membres après une période d’inactivité — le contrôle lié aux sessions que les référentiels de conformité demandent (SOC 2 CC6.1). Ouvre **Paramètres > Gouvernance > Sécurité et surveillance**, active **Activer le délai d'inactivité de session** et règle **Délai d'inactivité (minutes)** (1–1440, 30 par défaut). Les membres voient un avertissement peu avant la coupure ; ensuite l’onglet actif se déconnecte et la page de connexion explique la déconnexion au lieu d’afficher un simple formulaire. La fenêtre peut uniquement raccourcir la limite définie pour le déploiement, jamais l’allonger. Les opérateurs en self-hosted règlent ce plafond dur par variable d’environnement (voir la [référence d’environnement](/fr/self-hosted/configuration/environment-reference)) ; la politique d’organisation s’applique par-dessus, et la plus stricte des deux fenêtres l’emporte. Un membre de plusieurs organisations reçoit la fenêtre la plus stricte de toutes ses organisations. L’application a deux moitiés. Le watchdog côté navigateur termine à la minute près les sessions ouvertes et visibles. Les onglets fermés et les appareils abandonnés sont rattrapés côté serveur par une passe de révocation qui tourne environ toutes les cinq minutes — une session peut donc survivre quelques minutes au-delà de la fenêtre ; quand tu présentes le contrôle à un auditeur, compte la fenêtre plus une demi-heure environ dans le pire cas. Chaque révocation côté serveur atterrit dans les [journaux d’audit](/fr/platform/admin/governance/audit-logs) comme `session.idle_revoked`. Une réserve pour les déploiements trusted headers : le reverse proxy y possède l’authentification, donc une session révoquée se rétablit dès que le membre confirme l’avis de connexion — associe la politique à un délai d’inactivité côté proxy ou IdP pour un vrai verrouillage. ## Routage des conversations Le courrier entrant arrive non assigné tant qu’une règle de routage ne le revendique pas. Sous **Paramètres > Gouvernance > Politiques et limites**, ouvre **Routage des conversations** et ajoute une règle associant une adresse destinataire à une équipe, une personne, ou les deux : la prochaine conversation qui arrive à cette adresse est assignée dès sa création, avant que quiconque n’ouvre la boîte de réception. Une règle correspond à l’adresse à laquelle l’expéditeur a écrit — le `À` de la conversation — sans tenir compte de la casse ; une adresse sans règle reste non assignée. La visibilité est intégrée : une conversation assignée à une équipe n’est visible que par ses membres, et une conversation assignée à une personne n’est visible que par elle (l’union quand les deux sont définis). Les conversations vraiment non assignées — ni personne ni équipe — ne sont visibles que par les administrateurs et propriétaires, qui les trient. Les Membres et Éditeurs ne voient que le travail routé ou assigné dans leur file personnelle ou d’équipe. Associe le routage au contrôle **Responsable** de l’en-tête pour que le courrier entrant atterrisse dans la bonne file dès l’arrivée. Le routage ne fait qu’assigner ; il ne réassigne jamais une conversation qui a déjà un responsable ou une équipe, de sorte qu’une réponse s’enchaînant dans un fil existant est laissée intacte. Une règle pointant vers une équipe ou une personne supprimée depuis est ignorée — la conversation arrive quand même, simplement non assignée pour le triage admin. ## Où cela s’inscrit Politiques et limites est la couche budget et porte qui protège l’organisation des dépenses qui s’emballent et des accès non voulus. Associe-la à [contenu et modèles](/fr/platform/admin/governance/content-models), pour que le modèle plafonné par budget soit aussi celui que la liste d’accès autorise, et à [politique de rétention sur la même page](#bornes-de-retention-et-approbations), pour que les données que l’organisation garde soient aussi bornées. La page compagnon est [journaux d’audit](/fr/platform/admin/governance/audit-logs) — chaque changement de politique ici y atterrit comme enregistrement permanent. # Corbeille Source: https://tale.dev/docs/fr/platform/admin/governance/trash Corbeille est la surface de récupération pour les lignes que la rétention a soft-supprimées sans encore les avoir hard-supprimées. Quand un thread de chat, un document, un modèle de prompt ou une exécution de workflow dépasse sa fenêtre de rétention, il se déplace ici pour la fenêtre de grâce configurée avant que la prochaine passe de nettoyage ne le retire pour de bon. Les Administrateurs et Propriétaires lisent cette page quand un membre redemande un artefact supprimé, quand un workflow a supprimé le mauvais élément, ou quand un audit doit savoir si une ligne est encore récupérable. ## Une restauration mise en pratique Pour restaurer un thread d'historique de chat, ouvre **Paramètres > Gouvernance > Corbeille** et bascule le filtre **Catégorie** sur **Historique de chat**. Chaque ligne porte le type, le nom, le propriétaire, le statut et le moment de mise à la corbeille. Clique sur **Restaurer** sur la ligne, confirme dans la boîte de dialogue, et la ligne retourne dans sa liste source — les threads de chat réapparaissent dans la boîte de réception des conversations et les documents dans la base de connaissances. Restaurer une ligne expirée par la rétention demande de taper `restore` pour confirmer et est audité comme un dépassement de la politique de rétention. ## Les deux statuts **Mis à la corbeille** est l'état soft-delete normal. La fenêtre de rétention de la ligne a expiré, elle s'est déplacée à la corbeille, et la fenêtre de grâce tourne encore. Restaurer ramène la ligne dans sa liste source sans dépasser la politique. **Expiré** est le second état — la fenêtre de grâce s'est écoulée et la ligne est en file pour suppression définitive au prochain nettoyage. Restaurer reste possible mais est un dépassement : la boîte de dialogue te demande de taper `restore` et le journal d'audit enregistre le dépassement avec ton nom. ## Les catégories La corbeille contient des lignes de nombreuses catégories. Le filtre de catégorie change la vue par onglet : - Historique de chat (threads) - Documents - Fichiers temporaires - Modèles de prompt - Retours sur messages - Contacts - Fournisseurs - Conversations externes - Métadonnées de message - Exécutions de workflow - Logs de déclencheur de workflow - Registre d'utilisation - Logs d'audit - Événements de filtre de chat - Audit de mémoire Chaque catégorie respecte sa propre fenêtre de rétention et sa propre fenêtre de grâce — réglées dans la politique de rétention dans [politiques et limites](/fr/platform/admin/governance/policies-and-limits). ## Interaction avec la conservation légale Les lignes sous conservation légale n'apparaissent pas dans la corbeille — le hold les épingle hors de portée de chaque étape de rétention. Quand tu tentes de supprimer une ligne sous hold depuis sa liste source, Tale refuse avec le message **La suppression est bloquée par un legal hold actif**. Lever le hold laisse la rétention faire passer la ligne par la fenêtre de corbeille comme les autres catégories. ## La fenêtre de grâce La fenêtre de grâce est configurable par catégorie dans la politique de rétention. Une grâce de zéro saute la corbeille entièrement — la passe de nettoyage hard-supprime la ligne immédiatement quand la rétention se déclenche. Une grâce au-dessus de zéro garde la ligne dans la corbeille ce nombre de jours et la fait apparaître ici pendant la fenêtre Administrateur où restaurer reste peu coûteux. ## Où cela s'inscrit Corbeille est la seconde chance que la rétention donne à chaque catégorie avant que la passe de nettoyage ne retire une ligne pour de bon. Elle s'associe à [politiques et limites](/fr/platform/admin/governance/policies-and-limits) — la page rétention règle les fenêtres ; cette page est la vue de récupération que ces fenêtres alimentent. La page compagnon est [conservation légale](/fr/platform/admin/governance/legal-hold), le seul mécanisme qui bat la rétention avant qu'une ligne n'atterrisse dans la corbeille. # Journaux d'audit Source: https://tale.dev/docs/fr/platform/admin/governance/audit-logs Le journal d'audit est l'enregistrement immuable de chaque action conséquente dans ton organisation. Chaque connexion, changement de rôle, modification de fournisseur, sauvegarde d'agent, exécution de workflow et invocation de sandbox y atterrit avec l'acteur, la ressource, l'état avant/après et l'horodatage. Les Administrateurs et Propriétaires lisent ceci quand un audit demande qui a touché une ressource et quand, quand un responsable conformité a besoin d'un export, ou quand quelque chose dérape et la question est _qui a changé quoi à 03:14_. Cette page est la référence pour les colonnes, les filtres, les catégories et les formats d'export. La fenêtre de rétention pour les lignes d'audit se règle dans la même zone Gouvernance sous politique de rétention — garde-la assez longue pour satisfaire tes exigences de conformité avant que les lignes ne soient éliminées. ## Un filtre mis en pratique Pour trouver le moment où le rôle d'un membre a changé, ouvre **Paramètres > Gouvernance > Journaux d'audit**, règle le filtre **Catégorie** sur **Membre** et cherche l'acteur ou la cible par nom. Chaque ligne s'étend en payload complète — état précédent, état nouveau, l'IP si la requête est passée par le réseau, le type d'acteur (utilisateur, système, API, workflow). Exporte la sélection filtrée en CSV ou JSON depuis la barre d'outils au-dessus du tableau. ## Les colonnes | Nom | Type | Requis | Description | | --------------- | -------- | ------ | ---------------------------------------------------------------------------------------------- | | Horodatage | ISO 8601 | oui | Heure serveur à laquelle l'action a été validée. | | Action | string | oui | L'action sémantique — `update_member_role`, `provider_created`, `agent_saved`. | | Utilisateur | string | oui | Nom affiché de l'acteur ; `System`, `API` ou `Workflow` quand l'acteur n'est pas une personne. | | Ressource | string | oui | La ressource touchée par l'action — `agent`, `provider`, `member`, `workflow`. | | Catégorie | enum | oui | Auth, Membre, Données, Connector, Workflow, Sécurité, Admin, AI, Skill, Agent. | | Statut | enum | oui | Succès, Échec, Refusé. | | Champs modifiés | JSON | non | Le diff entre l'état précédent et le nouveau pour les actions de mise à jour. | ## Filtres Filtre par plage de dates, catégorie, statut, acteur, ressource ou recherche libre sur les noms d'action. Combine les filtres — une plage de dates plus la catégorie **Sécurité** plus le statut **Refusé** fait remonter les tentatives de connexion ratées sur une fenêtre. L'état des filtres se reflète dans l'URL ; un lien sauvegardé rouvre la même vue. ## Exporter Deux formats d'export sont livrés : CSV pour les tableurs et JSON pour les systèmes en aval. Les deux respectent les filtres actifs — ce que tu exportes est ce que tu vois. Définis les filtres voulus (le filtre mis en pratique ci-dessus est le modèle), puis choisis CSV ou JSON dans la barre d'outils au-dessus du tableau. Les exports volumineux se téléchargent en streaming ; la barre d'outils suit la progression et signale la fin avec la taille du fichier et le nombre de lignes. Le CSV arrive sous `audit-logs-<timestamp>.csv`, une ligne par action, avec une colonne plate par champ ; les horodatages sont en ISO 8601 (UTC) et toute valeur contenant une virgule est mise entre guillemets : ```csv timestamp,action,category,actorEmail,actorId,actorType,actorRole,resourceType,resourceId,resourceName,status,errorMessage 2026-01-14T03:14:07.000Z,member.role_changed,Member,admin@acme.example,usr_8f3a,user,owner,member,usr_2b91,jordan@acme.example,success, 2026-01-14T03:15:22.000Z,provider.updated,Provider,admin@acme.example,usr_8f3a,user,owner,provider,prov_openai,OpenAI,success, ``` L'export JSON (`audit-logs-<timestamp>.json`) porte les mêmes lignes en objets complets, plus les champs que le CSV aplatit — le diff `previousState`/`newState` et l'`integrityHash` par ligne. Choisis JSON quand un système en aval a besoin de la charge avant/après ou doit re-vérifier chaque ligne contre la chaîne SHA-256 (vois la section « Rétention et intégrité » plus bas) ; choisis CSV quand une personne l'ouvre dans un tableur. ## Rétention et intégrité Les lignes d'audit sont immuables : les modifications et suppressions sont elles-mêmes auditées, et le schéma de ligne porte un hash d'intégrité que tu peux vérifier contre l'export. Une tâche planifiée quotidienne re-vérifie la chaîne de hachage côté serveur et écrit une entrée d'audit `security` si la vérification échoue — ainsi une altération ou une suppression hors bande ressort même si personne ne lance la vérification manuelle. Une vérification en échec déclenche aussi une notification critique dans l'app pour les admins de l'organisation et part vers Slack quand un canal de notification Slack est configuré. La rétention est de 90 jours par défaut et se configure sur la page de politique de rétention (30 à 365 jours). Les lignes qui vieillissent sont retirées par la prochaine passe de nettoyage — il n'y a pas de fenêtre de soft-delete pour les données d'audit. ## Où cela s'inscrit Le journal d'audit est le côté lecture de toute autre fonction gouvernance : la conservation légale nomme les holds qu'elle a placés, les demandes des personnes concernées loggent chaque étape de cascade, la politique run-code logge les URLs que chaque sandbox a tenté d'atteindre. Quand une question commence par _qui, quand, quoi_, le journal d'audit est la réponse. La page compagnon est la [politique de rétention](/fr/platform/admin/governance/policies-and-limits) — elle contrôle combien de temps ces lignes restent avant que le nettoyage ne les retire. # Demandes des personnes concernées Source: https://tale.dev/docs/fr/platform/admin/governance/data-subject-requests Demandes des personnes concernées est le workflow que Tale livre pour honorer l’article 17 du RGPD (droit à l’effacement) et le droit équivalent CCPA sous la loi californienne. Chaque demande devient un reçu : il nomme la personne concernée, le code de motif, l’échéance SLA et la cascade de lignes que le système a effacées dans les threads, documents, exécutions de workflow et modèles de prompts personnels. Les Administrateurs et Propriétaires lisent cette page quand une personne dépose une demande, quand une échéance approche, ou quand un audit demande le reçu d’un effacement passé. <Frame caption="Gouvernance > Demandes des personnes concernées — la politique de gouvernance DSAR (fenêtre d’attente, double approbation, limite quotidienne), au-dessus de la liste des reçus de demandes avec Déposer une demande."> ![La page de gouvernance Demandes des personnes concernées montrant les champs de fenêtre d’attente, de bascule de double approbation et de limite quotidienne, au-dessus d’un tableau de demandes d’effacement qui porte une demande en attente — personne concernée Jordan Blake, code de motif Consentement retiré, 24 h avant exécution et 29 jours restants sur son SLA — à côté d’un bouton Déposer une demande.](/images/platform/governance-data-subject-requests.webp) </Frame> ## Un dépôt mis en pratique Pour déposer une demande, ouvre **Paramètres > Gouvernance > Demandes des personnes concernées** et clique sur **Déposer une demande**. Choisis la personne, choisis un code de motif (consentement retiré, plus nécessaire, traitement illégal, obligation légale, opposition, mineur ou fin de contrat) et ajoute une narration libre. La demande entre dans une fenêtre d’attente avant l’exécution de la cascade — tout Administrateur peut annuler pendant la fenêtre. Une fois la fenêtre écoulée, la cascade efface les threads, documents, exécutions de workflow, embeddings RAG et prompts personnels de la personne, et le reçu enregistre les compteurs par catégorie. ## Cycle de vie du statut | Nom | Par défaut | Description | | ------------------------ | --------------- | ------------------------------------------------------------------------------------------------------- | | En attente | état initial | La demande est déposée et attend la fenêtre d’attente ou la seconde approbation administrateur. | | En attente d’approbation | double contrôle | Un second Administrateur doit approuver avant que la cascade ne s’exécute. | | En cours | mid-cascade | La cascade est en cours ; les compteurs partiels se mettent à jour à mesure que chaque catégorie finit. | | Terminée | terminal | Chaque catégorie effacée sans erreur. | | Partielle | terminal | Certaines lignes ont été ignorées — généralement une conservation légale les a bloquées. | | Échouée | terminal | La cascade a rencontré une erreur ; le reçu nomme la catégorie en échec. | | Bloquée | terminal | Une conservation légale active bloque chaque étape de cascade. | | Annulée | terminal | Un Administrateur a annulé avant que la fenêtre d’attente n’expire. | ## Suivi du SLA Chaque demande porte une échéance niveau de service — par défaut, 30 jours depuis le dépôt. La liste des demandes affiche les jours restants ou un badge en retard par ligne. L’article 12(3) du RGPD autorise une prolongation unique pour les cas complexes ; l’action **Prolonger l'échéance** consigne la prolongation sur le reçu avec le nom de l’administrateur demandeur et une narration. ## Interaction avec la conservation légale Les données d’une personne ne sont _pas_ effacées tant qu’elles sont sous conservation légale. Les lignes sous hold apparaissent comme **Ignorées par hold** dans les compteurs par catégorie du reçu ; lever le hold et relancer la demande termine l’effacement. Le statut Bloquée se déclenche quand un hold couvre toutes les catégories dès le départ — la cascade ne s’exécute pas, et le reçu reflète le blocage. ## Les catégories de cascade Le reçu ventile les lignes effacées par catégorie — threads, documents, exécutions de workflow, modèles de prompts, documents RAG retirés du magasin vectoriel. Lis le drawer pour voir les compteurs et la timeline d’audit ; le journal d’audit dans la même zone Gouvernance porte la chaîne d’événements complète (`gdpr_erasure_requested`, `gdpr_erasure_executed`, `gdpr_erasure_extended`, `gdpr_erasure_cancelled`). ## Où cela s’inscrit Demandes des personnes concernées est le visage conformité de la rétention — le chemin audité, à double contrôle, qui efface une personne précise sur demande au lieu du balayage chronométré que la rétention applique à tous. La page compagnon est [conservation légale](/fr/platform/admin/governance/legal-hold) — elle couvre comment mettre la rétention et les cascades d’effacement en pause pour les litiges avant qu’elles ne s’exécutent. # Contenu et modèles Source: https://tale.dev/docs/fr/platform/admin/governance/content-models Contenu et modèles est la surface où tu décides quels LLMs les personnes de ton organisation peuvent atteindre et celui sur lequel chaque groupe atterrit par défaut. Elle associe une liste d’autorisation ou de blocage par scope (organisation, équipe, rôle, utilisateur) à une règle de modèle par défaut que le résolveur applique quand aucun agent ni aucune conversation n’a outrepassé le choix. Les Administrateurs et Propriétaires lisent cette page quand une règle de conformité épingle une charge à un modèle approuvé, quand une équipe doit avoir un modèle par défaut moins cher que le reste de l’organisation, ou quand un nouveau modèle d’un fournisseur existant doit être rendu joignable. <Frame caption="Gouvernance > Contenu et modèles — le préfixe et le suffixe de prompt système obligatoires, au-dessus des règles de modèle par défaut par scope."> ![La page de gouvernance Contenu et modèles montrant les champs de préfixe et de suffixe de prompt système obligatoires remplis des règles maison de l’organisation, au-dessus d’un tableau de modèles par défaut qui porte trois règles — un défaut pour tous les utilisateurs et une règle de rôle pour Développeur et pour Membre, chacune épinglée à un modèle OpenRouter.](/images/platform/governance-content-models.webp) </Frame> ## Un défaut mis en pratique Pour régler le modèle par défaut du rôle Éditeur, ouvre **Paramètres > Gouvernance > Default Models** et clique sur **Ajouter une règle**. Choisis **Rôle** comme scope, **Éditeur** comme cible, puis choisis le fournisseur et le modèle. Enregistre et la prochaine requête d’un Éditeur sans surcharge explicite par agent ou par conversation atterrit sur le modèle de la règle. Les scopes plus étroits l’emportent — une règle utilisateur bat une règle équipe bat une règle rôle bat le défaut org. ## Les deux couches **Accès au modèle** est la liste d’autorisation ou de blocage qui régit quels modèles un scope peut utiliser tout court. Un modèle absent de la liste d’autorisation est invisible pour ce scope — le sélecteur le cache et le résolveur refuse de s’y lier, même si un agent l’a épinglé. Va vers la liste d’autorisation quand un régulateur nomme les modèles approuvés ; va vers la liste de blocage quand un seul modèle doit être hors-limites partout ailleurs. **Modèles par défaut** est la règle du résolveur qui choisit le modèle quand rien d’autre ne l’a fait — pas de surcharge par agent, pas de surcharge par conversation. Le défaut s’applique au moment où l’utilisateur lance un chat frais et s’applique en repli quand le modèle épinglé d’un agent n’est pas joignable. ## Scopes et priorité Les deux couches portent un scope : organisation, équipe, rôle ou utilisateur. Le résolveur évalue du plus étroit au plus large — utilisateur l’emporte sur équipe sur rôle sur défaut org. La couche d’accès au modèle se combine avec la couche de modèle par défaut ; le défaut que le résolveur choisit doit aussi passer le contrôle d’accès du même scope, sinon le résolveur se replie sur le modèle autorisé le plus proche. ## Avertissements liste d’autorisation et liste de blocage L’éditeur de modèles par défaut affiche un avertissement quand une règle nomme un modèle que la liste d’autorisation du même scope n’autorise pas, ou quand la liste de blocage du même scope le bloque. L’avertissement n’empêche pas d’enregistrer — le résolveur se repliera à la requête — mais il signale l’incohérence pour que tu corriges l’une ou l’autre. ## Le modèle qui lit les images Tous les modèles ne voient pas. Quand un agent tournant sur un modèle texte seul ouvre une capture d’écran, une facture scannée ou une diapositive rendue, Tale confie cette image à un second modèle et rend la transcription à l’agent. Tout passe par la passerelle, donc aucune clé de fournisseur n’entre dans le sandbox — et un modèle qui lit déjà les images se passe entièrement du détour. **Modèle pour les images** décide qui fait ce travail. Laisse-le sur **Automatique** et Tale choisit à ta place : d’abord un modèle recommandé, sinon le moins cher que tes accès atteignent. La ligne sous le sélecteur nomme toujours le modèle qui lit les images en ce moment, et pourquoi celui-là — « quel modèle lit nos images » n’est donc jamais une devinette. Fixe un modèle quand tu veux que ce choix cesse de bouger. Automatique lit un catalogue de fournisseur vivant : le modèle le moins cher change à chaque nouvelle publication, alors qu’un modèle fixé tient la ligne sur celui que tu as testé. Seuls les modèles capables de transcrire sont proposés — les générateurs de médias et les accès gratuits sont écartés, car les deux acceptent une image puis refusent la requête. Si un modèle fixé devient inatteignable — accès renouvelé, liste d’autorisation resserrée, retrait par le fournisseur — Tale le consigne et revient à Automatique plutôt que de laisser tes agents sans lecture. ## Où cela s’inscrit Contenu et modèles est la porte que chaque chat et chaque agent franchissent à la requête. Associer accès au modèle et modèles par défaut permet de livrer une posture de conformité serrée sans forcer chaque auteur d’agent à se souvenir du modèle approuvé ce trimestre. La page compagnon est [politiques et limites](/fr/platform/admin/governance/policies-and-limits) — elle couvre les plafonds de coût et de requêtes qui s’appliquent au-dessus des choix de modèle faits ici. # Analyse d'utilisation Source: https://tale.dev/docs/fr/platform/admin/governance/usage-analytics Analyse d'utilisation est le dashboard qui agrège chaque appel AI facturable dans une vue unique de tokens, coût et volume de requêtes. Il découpe par utilisateur, équipe, rôle, modèle, agent et temps, pour que la ligne inattendue sur la facture soit traçable jusqu'à la charge qui l'a portée. Les Administrateurs et Propriétaires lisent cette page quand une facture est inattendue, quand la direction veut la forme approximative des dépenses AI, ou quand une alerte de budget se déclenche et la question suivante est _qui et quoi_. ## Un drill-down mis en pratique Ouvre **Paramètres > Gouvernance > Utilisation**. La vue par défaut sont les 30 derniers jours, org-wide, avec les trois compteurs phares — tokens totaux, coût total en USD, requêtes totales. Bascule la ventilation sur **Par utilisateur** pour trouver les plus gros consommateurs, **Par modèle** pour comparer un primaire coûteux à un repli moins cher, ou **Par agent** pour trouver l'agent qui porte la charge. Chaque ligne renvoie à une série temporelle par ligne ; l'axe du graphique suit la période choisie. ## Les dimensions - **Utilisateur** — chaque membre qui a déclenché un appel facturable. Associe au filtre équipe ou rôle pour cadrer la vue. - **Équipe** — agrégé par membre d'équipe ; utile quand les budgets sont cadrés par équipe. - **Rôle** — Propriétaire, Administrateur, Développeur, Éditeur, Membre. - **Modèle** — chaque modèle qui a produit une réponse, groupé par fournisseur. - **Agent** — chaque agent nommé (le classement trie par volume de tokens, coût ou nombre de requêtes). - **Temps** — tendance quotidienne pour les fenêtres courtes, hebdomadaire pour les fenêtres plus longues. ## Le modèle de coût Le coût est une estimation. Chaque requête atterrit dans le registre d'utilisation avec les tokens d'entrée, les tokens de sortie, le prix publié du modèle par million de tokens et la durée wall-clock. Le dashboard multiplie tokens par prix ; les appels de génération d'images atterrissent avec un coût par image que le fournisseur renvoie. La ligne du registre est la source de vérité, et le [journal d'audit](/fr/platform/admin/governance/audit-logs) porte l'acteur et l'horodatage de la ligne pour le recoupement. ## Superpositions de budget Quand [politiques et limites](/fr/platform/admin/governance/policies-and-limits) a un budget pour un scope, le graphique d'utilisation superpose le plafond comme une ligne horizontale. Survoler un point affiche le pourcentage du plafond consommé et la projection de fin de mois basée sur la tendance courante. Franchir le seuil d'avertissement colore la série en ambre ; franchir le plafond la colore en rouge et fait apparaître les événements budget-dépassé comme marqueurs sur l'axe temps. ## Rétention des lignes d'utilisation Le registre d'utilisation a sa propre fenêtre de rétention dans [politiques et limites](/fr/platform/admin/governance/policies-and-limits). Le défaut est 365 jours ; raccourcis-le et le graphique historique se tronque en conséquence. Le dashboard reflète ce que tient le registre — il n'y a pas de couche d'archive en dessous. ## Où cela s'inscrit Analyse d'utilisation est le côté dépense et volume de la même charge que [analyse des retours](/fr/platform/admin/governance/feedback-analytics) lit pour la qualité. Ensemble elles répondent à _cet agent vaut-il son coût_. La page compagnon est [politiques et limites](/fr/platform/admin/governance/policies-and-limits) — la page où les budgets que ce dashboard superpose sont configurés. # Conservation légale Source: https://tale.dev/docs/fr/platform/admin/governance/legal-hold Conservation légale est le mécanisme que Tale livre pour préserver des preuves sous conservation contentieuse. Un hold épingle une cible — un utilisateur, un document, un thread, une exécution de workflow ou l’organisation entière — hors de portée du balayage de rétention et de la cascade d’effacement des personnes concernées. Les Administrateurs et Propriétaires lisent cette page quand le conseil leur demande de préserver les données d’un custodian, quand une demande de levée a besoin de la signature à double contrôle, ou quand un audit réconcilie quels holds étaient en vigueur à une date donnée. <Frame caption="Gouvernance > Conservation légale — le tableau des holds actifs avec l’action Placer une conservation légale, au-dessus de la file à double contrôle des demandes de levée."> ![La page de gouvernance Conservation légale montrant un hold actif — de type Utilisateur sur marta.vogel, placé par Alex Rivera au titre de l’affaire Northstar contract — à côté d’un bouton Placer une conservation légale, au-dessus des deux files de demandes de levée, Approbation en attente et Approuvées, qui n’affichent aucune demande.](/images/platform/governance-legal-hold.webp) </Frame> ## Une mise en place mise en pratique Pour placer un hold sur un utilisateur, ouvre **Paramètres > Gouvernance > Conservation légale** et clique sur **Placer une conservation légale**. Choisis le type de cible — utilisateur, thread, document, exécution ou organisation — choisis la cible précise, ajoute un motif et lie le hold à un dossier s’il y en a un d’ouvert. Le hold prend effet immédiatement ; les balayages de rétention sautent les lignes de la cible, la cascade d’effacement les rapporte comme **Ignorées par hold**, et la ligne cible porte le badge **Sous conservation légale** dans chaque liste où elle apparaît. ## Les quatre sections **Holds actifs** est la liste de travail de chaque hold actuellement en vigueur. Chaque ligne porte le type, la cible, le motif, le dossier, qui l’a placé et quand. Filtre par type ou par dossier pour cadrer la vue. **Demandes de levée** est la file à double contrôle. Lever un hold demande qu’un autre Administrateur approuve la demande ; les demandes approuvées attendent encore un délai de refroidissement avant de prendre effet. La section se sépare en _en attente d’approbation_ et _approuvée, en attente du refroidissement_, pour que la file et le minuteur soient tous deux visibles. **Dossiers** groupe les holds par affaire. Chaque dossier porte un nom, un numéro de dossier et la liste des holds liés. Fermer un dossier dépose des demandes de levée pour chaque hold lié — toujours soumises à l’approbation à double contrôle par demande. **Historique des levées** est l’audit en lecture seule des levées effectuées et rejetées. Utilise-le pour réconcilier contre une lettre de préservation du conseil adverse ou alimenter un rapport d’audit. ## Interaction hold-et-cascade Un hold bloque chaque passage de rétention et chaque étape d’effacement pour la cible. La page Corbeille affiche le bandeau **La suppression est bloquée par un legal hold actif** quand un Administrateur tente de purger une ligne sous hold. Une demande de personne concernée dont le sujet est couvert par un hold atterrit en statut **Bloquée** jusqu’à ce que le hold soit levé ; une couverture partielle (certains threads sous hold, d’autres pas) atterrit en **Partielle** avec des compteurs par catégorie dans le reçu. ## Double contrôle Placer et lever ne sont pas symétriques. Placer est une action d’un Administrateur seul — la vitesse compte quand un litige arrive. Lever est à double contrôle : l’Administrateur demandeur dépose, un autre Administrateur approuve, et un délai de refroidissement s’applique entre l’approbation et l’effet pour qu’une levée hâtive puisse encore être annulée. Les deux moitiés du workflow sont auditées de bout en bout. ## Où cela s’inscrit Conservation légale est le bouton gel sur la rétention. C’est le seul mécanisme qui bat le balayage chronométré de la rétention et la cascade d’effacement des personnes concernées — les deux respectent les holds par conception. Les pages compagnons sont [demandes des personnes concernées](/fr/platform/admin/governance/data-subject-requests) pour le côté cascade et [politiques et limites](/fr/platform/admin/governance/policies-and-limits) pour les fenêtres de rétention que le hold outrepasse. # Garde-fous Source: https://tale.dev/docs/fr/platform/admin/governance/guardrails Garde-fous est la surface où tu configures les trois couches de filtres que Tale applique à chaque message de chat dans ton organisation. Chaque message traverse la sécurité du contenu (listes de mots et regex administrateur), puis la détection PII (motifs intégrés plus personnalisés), puis un fournisseur de modération externe optionnel — dans cet ordre fixe, à l’entrée et à la sortie. Les Administrateurs et Propriétaires lisent cette page quand un régulateur nomme une règle de contenu, quand une fuite justifie une politique plus stricte, ou quand les réponses d’un agent doivent être assainies avant de quitter le modèle. <Frame caption="Gouvernance > Garde-fous — les trois cartes de statut des couches de filtres (sécurité du contenu, détection PII, fournisseur de modération), au-dessus du journal des événements récents."> ![La page de gouvernance Garde-fous montrant trois cartes de statut — la sécurité du contenu appliquée à l’entrée et à la sortie sur deux catégories, la détection PII en mode mask sur quatre motifs intégrés, et le fournisseur de modération marqué Désactivé, sans API externe configurée — au-dessus du flux des événements récents, qui n’en signale encore aucun.](/images/platform/governance-guardrails.webp) </Frame> ## Un layering mis en pratique Pour configurer les couches, ouvre **Paramètres > Gouvernance > Garde-fous**. L’aperçu affiche trois cartes de statut, une par couche — sécurité du contenu, détection PII, modération. Chaque carte renvoie vers sa propre page de configuration où tu choisis si la couche tourne sur l’entrée, sur la sortie ou les deux, et ce qu’elle fait à un match (bloquer le message, masquer le match, ou marquer et laisser passer). Le tableau des événements récents en bas de l’aperçu affiche les 50 dernières détections, blocages et erreurs fournisseur avec leur couche, leur direction et leur catégorie de match. ## Sécurité du contenu La sécurité du contenu est la couche que tu possèdes toi-même. Définis une ou plusieurs catégories — discours haineux, profanité, une regex personnalisée pour un nom de code interne — et choisis un mode par catégorie : **Bloquer** refuse le message, **Masquer** remplace les matches par un placeholder, **Marquer** consigne la détection sans changer le message. Bloquer l’emporte sur Masquer l’emporte sur Marquer quand plusieurs catégories matchent. Les listes de mots et motifs de cette couche ne quittent jamais le déploiement. Le texte trouvé n’est pas stocké — seule la catégorie, la direction (entrée ou sortie) et le nombre de matches finissent dans l’événement d’audit. ## Détection PII La détection PII embarque des motifs pour les e-mails, téléphones, IDs gouvernementaux, numéros de paiement et une longue traîne de formats régionaux. Ajoute des motifs personnalisés si ton régulateur nomme un format que les motifs intégrés ratent. Choisis un mode — Bloquer, Masquer avec un placeholder, ou Marquer — et une direction d’application. Masquer est le choix typique pour le filtrage de sortie quand le modèle a eu accès à des enregistrements contenant des PII qu’il ne doit pas répéter. ## Fournisseur de modération La couche modération est un classifieur externe — OpenAI Moderation, Azure Content Safety, Perspective API, ou un endpoint HTTP personnalisé. Configure l’endpoint du fournisseur, une clé API et le mapping catégorie-vers-action (chaque fournisseur renvoie sa propre taxonomie ; le mapping décide quelles catégories bloquent, masquent ou marquent). La couche est optionnelle — laisse-la désactivée et seules les deux premières couches tournent. Le fournisseur se trouve sur le chemin d’egress réseau. Les pannes sont configurables par direction : fail-open laisse passer le message, fail-closed le refuse. La vue des événements récents affiche les erreurs fournisseur, les statuts HTTP et les événements circuit-open quand la couche est rate-limited. ## Événements récents Chaque détection, blocage et erreur fournisseur atterrit dans le tableau des événements récents pour 30 jours. Filtre par couche ou par type ; clique sur une ligne pour voir les catégories trouvées, l’acteur, l’identifiant de message et l’horodatage. Le texte brut trouvé n’est jamais stocké — les événements sont une surface de réglage, pas une archive de contenu. ## Où cela s’inscrit Garde-fous est le filtre runtime entre l’utilisateur et le modèle dans les deux sens. Associe-le à [contenu et modèles](/fr/platform/admin/governance/content-models), pour qu’un modèle approuvé soit aussi soumis aux règles de contenu approuvées. La page compagnon est le [journal d’audit](/fr/platform/admin/governance/audit-logs) — chaque blocage et chaque masquage que les couches garde-fous appliquent y atterrit comme enregistrement permanent. # Politique run-code Source: https://tale.dev/docs/fr/platform/admin/governance/run-code-policy Politique run-code est la surface où tu décides quels paquets Python et Node la sandbox peut installer à l’exécution. Les skills avec scripts et l’outil Run code tournent tous deux dans la même sandbox ; cette politique est la couture unique où tu serres ou desserres ce qu’ils peuvent installer. Les Administrateurs et Propriétaires lisent cette page quand un agent a besoin d’une nouvelle bibliothèque, ou quand un audit demande pourquoi un paquet était bloqué à un moment donné. <Frame caption="Gouvernance > Paquets run-code — le groupe d’options du mode par défaut, au-dessus des listes d’autorisation et de blocage Python et Node."> ![La page de gouvernance Politique run-code avec Liste d’autorisation coché dans le groupe d’options du mode par défaut, au-dessus d’une liste d’autorisation Python qui tient pandas, numpy, scipy et scikit-learn, d’une liste de blocage Python qui tient paramiko, fabric, pexpect et scapy, et d’une liste d’autorisation Node qui tient axios, date-fns, dayjs et lodash.](/images/platform/governance-run-code-policy.webp) </Frame> ## Un basculement mis en pratique Le mode par défaut est **Liste de blocage** avec liste vide, ce qui veut dire que tous les paquets sont installables. Pour passer à un ensemble curé, ouvre **Paramètres > Gouvernance > Paquets run-code**, change le mode en **Liste d'autorisation** et énumère les paquets de confiance sous **Liste d'autorisation Python** et **Liste d'autorisation Node**. Enregistre et la prochaine exécution sandbox qui demande un paquet hors de la liste échoue avec la raison **absent de la liste d'autorisation** dans l’événement d’audit. ## Les deux modes | Nom | Par défaut | Description | | -------------------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------- | | Liste d’autorisation | off | Seuls les paquets listés s’installent ; tout le reste est rejeté. À utiliser quand un régulateur nomme les bibliothèques approuvées. | | Liste de blocage | on | Tous les paquets s’installent sauf ceux listés. À utiliser quand un petit ensemble est connu mauvais et que le reste est de confiance. | ## Les quatre listes Chaque mode lit deux listes — Python et Node. Un paquet par ligne, ou séparé par des virgules. Les contraintes de version sont retirées automatiquement (`pandas==2.1` correspond à `pandas`), donc la politique est basée sur le nom et survit aux montées de version des bibliothèques. Les paquets Node scopés (`@scope/pkg`) sont pris en charge. Les listes sont indépendantes par langage : une liste d’autorisation Python plus une liste de blocage Node est une combinaison valide, et veut dire que Python est strict et Node est permissif sur la même sandbox. ## Le testeur Le panneau Test sur la même page permet de coller des spécifications pip ou npm et voir si chacune passerait sous le brouillon courant. Il utilise tes modifications non enregistrées, donc tu peux itérer avant d’enregistrer. Chaque spécification est parsée, dépouillée de sa contrainte de version et confrontée aux listes ; le panneau rapporte **Autorisé** ou **Refusé** avec la raison — correspond-à-la-liste-d’autorisation, absent-de-la-liste-d’autorisation, correspond-à-la-liste-de-blocage, absent-de-la-liste-de-blocage. ## Egress réseau et skills La politique de paquets régit _ce qui_ tourne dans la sandbox. La même sandbox fait tourner les scripts de skill — voir la [page concept Skills](/fr/platform/agents/skills). Le réseau sortant depuis le code sandbox est ouvert par défaut, les métadonnées cloud et les plages privées étant toujours bloquées ; sur les déploiements auto-hébergés, l’opérateur peut le restreindre à une allowlist d’hôtes au niveau du déploiement — la marche à suivre vit dans [Durcissement](/fr/self-hosted/operate/security/hardening). Traite la publication d’un skill avec script comme un élargissement de la surface de confiance pour chaque agent qui l’adopte ; la politique de paquets et la politique d’egress du déploiement décident ensemble ce que le script peut faire. ## Où cela s’inscrit Politique run-code est la porte sur la sandbox qui supporte à la fois l’outil Run code et les scripts de skill. Le concept compagnon est [skills d’agent](/fr/platform/agents/skills) — il couvre quand publier un script comme skill, et pourquoi la politique de paquets est la porte porteuse. La page gouvernance compagnon est [journaux d’audit](/fr/platform/admin/governance/audit-logs) — chaque installation de paquet refusée y atterrit avec la spécification et la raison. # Analyse des retours Source: https://tale.dev/docs/fr/platform/admin/governance/feedback-analytics Analyse des retours est le dashboard qui transforme les pouces par message et les notations par chat en courbes de tendance. Les membres laissent le retour inline dans le chat ; cette page l'agrège par agent, par modèle et dans le temps, pour que la régression du changement de voix de la semaine dernière soit visible comme un chiffre, pas comme un pressentiment. Les Administrateurs et Propriétaires lisent cette page quand un changement de modèle ressemble à une dégradation, quand un agent performe moins que les autres, ou quand la direction veut la posture qualité approximative de chaque agent dans l'organisation. ## Un drill-down mis en pratique Ouvre **Paramètres > Gouvernance > Retours** et la vue par défaut est le ratio org-wide sur les 30 derniers jours. Bascule la ventilation sur **Par agent** pour voir le ratio par agent — trie par volume de retours pour trouver les agents que les membres utilisent vraiment, puis clique dans l'un pour voir son historique de modèles à côté du même ratio dans le temps. La vue split-par-modèle est la même donnée découpée selon le modèle qui a produit chaque réponse notée. ## Les deux signaux **Retour pouces** est le signal par message — un pouce en haut ou un pouce en bas sur une réponse d'agent. Le pouce porte un commentaire libre optionnel ; le commentaire est par ligne et n'entre jamais dans le ratio. Les membres peuvent laisser les deux, modifier l'un ou retirer entièrement ; la timeline reflète le dernier état. **Notations de chat** est le signal par conversation — la notation d'une à cinq étoiles qui apparaît à la fin d'une conversation. Les notations portent aussi un commentaire optionnel. Les notations de chat sont plus grossières que les pouces et utiles pour suivre l'ambiance au niveau agent sur de nombreux tours, là où les pouces individuels seraient du bruit. ## Ventilations Le dashboard découpe selon trois dimensions : - **Agent** — chaque agent de l'organisation a sa propre ligne avec ratio, volume et tendance. - **Modèle** — chaque modèle qui a produit une réponse notée contribue ; utile quand tu compares un primaire à son repli. - **Temps** — la tendance est quotidienne pour les 30 derniers jours et hebdomadaire pour les fenêtres plus longues. ## Commentaires libres Les commentaires apparaissent sous les chiffres agrégés en liste. Trie par récence ou par sentiment ; clique pour rejoindre la conversation en contexte et voir ce à quoi la réponse notée répondait. Les commentaires sont soumis à la même politique de rétention que les conversations auxquelles ils appartiennent ; si un thread est purgé ou mis à la corbeille, ses commentaires partent avec. ## Où cela s'inscrit Analyse des retours est le pouls de chaque agent dans l'organisation — l'endroit où une régression de voix ou de comportement de modèle apparaît avant que quelqu'un la signale. La page compagnon est [analyse d'utilisation](/fr/platform/admin/governance/usage-analytics) — les mêmes agents et modèles, découpés par dépense et volume de tokens au lieu de qualité. # Branding Source: https://tale.dev/docs/fr/platform/admin/branding Le branding est la surface qui échange le chrome par défaut de Tale contre celui de ton organisation. La page couvre les assets que la plateforme habille — logo, favicon et la couleur d’accentuation dont dérive la palette — et explique où chacun apparaît pour que tu aies un aperçu avant d’enregistrer. Le nom du produit lui-même suit automatiquement le nom de ton organisation, il n’y a donc pas de champ séparé à remplir. Les Administrateurs vont vers le branding quand une instance auto-hébergée s’expose à un public externe ou quand un déploiement interne doit sembler natif à l’entreprise. Seuls les Administrateurs et Propriétaires peuvent éditer le branding. Tous les autres voient le résultat ; le formulaire lui-même est caché aux Éditeurs, Développeurs et Membres. <Frame caption="Paramètres > Branding — les contrôles de logo, favicon et couleur d’accentuation à côté d’un aperçu en direct de la barre latérale."> ![La page de paramètres Branding avec les téléversements de logo et favicon, un champ de couleur d’accentuation, et un panneau d’aperçu en direct à droite.](/images/platform/settings-branding.webp) </Frame> ## Où vit le branding Ouvre **Paramètres > Branding**. Le formulaire a trois sections (téléversement du logo, téléversement du favicon, couleur d’accentuation) et un aperçu en direct qui reflète la barre latérale avec les valeurs que tu édites. Enregistrer applique le changement pour chaque membre de _cette_ organisation à son prochain chargement de page — il n’y a pas de surcharge par utilisateur. Le branding est limité à une organisation. Chaque organisation conserve son propre logo, favicon et sa couleur d’accentuation, donc changer d’organisation bascule le chrome vers le branding de cette organisation au lieu de garder celui de la précédente. Éditer ici ne change que l’organisation dans laquelle tu te trouves actuellement. ## Le nom du produit Il n’y a pas de champ « nom d’app » ni « logo texte ». La marque de mot dans l’en-tête de la barre latérale et le nom dans le titre d’onglet du navigateur sont le nom propre de ton organisation, que tu définis sur la page **Paramètres > Organisation**. Renomme l’organisation et le chrome suit au prochain chargement de page. Téléverse une image de logo (ci-dessous) et elle prend la place de la marque de mot ; sans logo, le nom de l’organisation est rendu comme marque de mot textuelle. ## Les assets **Logo** est une image — PNG, SVG ou JPG. La plateforme la rend à la hauteur de la barre latérale ; vise un fond transparent et une marque de mot lisible à environ 32 pixels de haut. Le logo est un téléversement unique utilisé sur les deux thèmes — choisis une marque lisible sur fond clair comme sombre. Sans logo, le chrome retombe sur le nom de ton organisation comme marque de mot textuelle. **Favicon** est l’icône d’onglet. Téléverse une variante claire et une variante sombre pour que l’icône reste lisible quel que soit le thème choisi par le système d’exploitation — ou laisse-le vide, et Tale en dérive un de ton logo dès que tu le téléverses, si bien qu’un seul téléversement habille à la fois la barre latérale et l’onglet du navigateur. Un favicon explicite l’emporte toujours sur celui dérivé automatiquement. **Couleur d'accentuation** est la seule couleur dont dérive la palette de marque — boutons, anneaux de focus, états de sélection et la ligne active de la barre latérale en tirent tous leur ton. Elle accepte toute valeur hex, choisie une fois pour les modes clair et sombre ; Tale dérive une palette lisible par thème — une couleur difficile à lire contre le fond d’un thème est poussée vers le contraste pour ce thème seulement, l’autre reste intact, et la même marque se lit proprement sur les deux. L’aperçu reflète la palette dérivée pour le thème que tu regardes actuellement. ## Un rebranding mis en pratique Pour rebrander une instance pour `Acme Corp`, mets d’abord le nom de l’organisation à `Acme Corp` sur la page **Paramètres > Organisation** — ce nom devient la marque de mot de la barre latérale et le titre d’onglet du navigateur. Ouvre ensuite **Paramètres > Branding**, téléverse la marque de mot de l’entreprise comme logo, et colle le hex de marque (`#3B82F6` dans l’exemple) dans le champ de couleur d’accentuation. Laisse le favicon vide, et Tale en génère un depuis le logo. Le panneau d’aperçu à droite se met à jour pendant que tu tapes. Enregistrer applique le changement ; la barre latérale, l’onglet du navigateur et le favicon reflètent le nouveau branding immédiatement. ## L’écran de connexion personnalisé Les écrans de connexion, d’inscription et de réinitialisation de mot de passe s’affichent avant que tu aies choisi une organisation — il n’y a donc aucune organisation dans le contexte pour les brander. Ils montrent le branding par défaut de la plateforme plutôt que celui d’une organisation précise ; le branding par organisation prend le relais dès que tu arrives dans l’espace de travail de cette organisation. Déconnecte-toi et recharge l’URL de connexion pour vérifier quels assets utilisent les écrans pré-authentification. ## Où ça s’inscrit Le branding est la couche visuelle au-dessus de toute autre surface admin ; SSO, courriels et journaux d’audit portent le chrome brandé jusqu’à tes membres. Comme le nom du produit est le nom propre de l’organisation, garde-le net dans [membres et rôles](/fr/platform/admin/members-and-roles). Combine le branding avec [fournisseurs](/fr/platform/admin/providers) pour que les noms de modèles dans l’en-tête de chat correspondent au chrome qui les entoure, et avec [membres et rôles](/fr/platform/admin/members-and-roles) pour que les personnes qui peuvent éditer le branding soient les mêmes qui détiennent le reste du chrome de l’org. # Authentification à deux facteurs Source: https://tale.dev/docs/fr/platform/admin/two-factor-authentication L’authentification à deux facteurs ajoute une seconde preuve d’identité par-dessus le mot de passe — un code à six chiffres d’une appli authenticator, ou un passkey WebAuthn. Tale embarque TOTP (mots de passe à usage unique basés sur le temps) compatible avec Google Authenticator, 1Password, Authy et toute autre appli qui suit le standard, plus les passkeys comme alternative résistante au phishing. La page couvre l’inscription par utilisateur, les passkeys, les codes de secours qui récupèrent un compte quand le téléphone n’est plus là, la politique d’application org-large et la réinitialisation admin pour un membre verrouillé. La 2FA est optionnelle par défaut. Les Administrateurs peuvent l’exiger pour toute l’organisation avec une fenêtre de grâce pour que les membres aient le temps de s’inscrire. ## Inscription par utilisateur Pour activer la 2FA sur ton propre compte, ouvre **Compte > Sécurité**. Clique sur **Activer la deux-facteurs**, confirme ton mot de passe et scanne le code QR avec une appli authenticator. Saisis le code à six chiffres que l’appli affiche pour vérifier que le secret a été capté, puis sauvegarde les codes de secours que l’écran suivant présente. Les codes apparaissent une seule fois — télécharge-les ou copie-les avant de cliquer sur **Terminé**. Le même écran porte **Désactiver** et **Régénérer les codes de secours**. Désactiver supprime le second facteur ; régénérer invalide chaque code de secours précédent. Les deux actions exigent le mot de passe du compte comme confirmation. ## Codes de secours Les codes de secours sont des chaînes à usage unique que la plateforme frappe quand la 2FA est activée ou régénérée. Chacun remplace le code authenticator sur une seule connexion — utile quand le téléphone est perdu, l’authenticator désinstallé, ou que tu es coincé quelque part sans l’appareil. La plateforme surveille le compte restant et affiche une bannière de niveau bas quand il ne reste que quelques codes ; la bannière renvoie directement au flux de régénération. Traite les codes de secours comme des mots de passe. Range-les dans un gestionnaire de mots de passe ou imprime-les et mets-les sous clé. Quiconque a ton mot de passe et un code de secours peut se connecter à ta place. ## Passkeys Un passkey est un identifiant WebAuthn — Face ID, Touch ID, Windows Hello ou une clé de sécurité matérielle — qui signe un défi à chaque connexion au lieu de produire un code à taper. L’identifiant est lié à l’origine du site : un domaine de phishing qui lui ressemble n’obtient rien à rejouer. Un passkey résiste donc au phishing d’une façon que TOTP n’atteint pas, et il satisfait une politique de deux facteurs appliquée exactement comme TOTP. Pour en enregistrer un, ouvre **Compte > Sécurité** et clique sur **Ajouter un passkey**. Donne à l’identifiant un nom que tu reconnaîtras plus tard, puis choisis le **Type d'authentificateur** : **Indifférent (recommandé)** laisse le navigateur proposer tout ce qui est disponible, **Cet appareil (Face ID, Touch ID, Windows Hello)** restreint la cérémonie à l’authentificateur intégré, et **Clé de sécurité ou téléphone** à un authentificateur itinérant. Le navigateur déroule la cérémonie d’enregistrement à partir de là. Chaque entrée de la même liste porte un bouton-icône **Supprimer** pour révoquer tes propres passkeys ; il demande une confirmation avant de supprimer le passkey. Un passkey enregistré fonctionne à trois portes. Sur l’écran de connexion, **Se connecter avec un passkey** te connecte sans taper le mot de passe — l’identifiant est lui-même une preuve forte. Sur l’écran de vérification après une connexion par mot de passe, **Utiliser un passkey à la place** remplace le code à six chiffres. Et sur l’écran d’inscription vers lequel une politique appliquée route les membres non inscrits, **Enregistrer un passkey à la place** se trouve à côté de la configuration TOTP — un membre qui n’enregistre qu’un passkey, jamais TOTP, passe la politique. Quand un membre perd un appareil qui porte un passkey, un Administrateur révoque l’identifiant : ouvre **Paramètres > Organisation**, clique sur **Modifier le membre** et supprime l’identifiant dans la section **Passkeys** du dialogue. Tale supprime l’identifiant et met fin à chaque session active du membre, donc un authentificateur perdu ou volé ne garde aucune session en vie. L’enregistrement, la suppression par soi-même, la révocation admin et chaque connexion par passkey atterrissent dans le journal d’audit (`passkey_added`, `passkey_removed`, `passkey_revoked_by_admin`, `passkey_sign_in`). ## La politique d’application pour l’org Les Administrateurs peuvent exiger le second facteur pour chaque membre authentifié par mot de passe de l’organisation. Ouvre **Paramètres > Gouvernance > Security & Monitoring** et, sous **Authentification à deux facteurs**, bascule **Exiger l'authentification à deux facteurs**. La politique porte une période de grâce (en jours) qui donne à chaque membre du temps pour s’inscrire à partir de sa première connexion sous la politique ; mets-la à zéro pour une application immédiate. <Frame caption="Gouvernance > Security & Monitoring — limites de tentatives de connexion et politique de mot de passe ; la politique d’authentification à deux facteurs se trouve plus bas sur la même page."> ![La page de gouvernance Security & Monitoring montrant les champs de limite de tentatives de connexion et les exigences de classes de caractères de la politique de mot de passe ; la politique de deux facteurs se trouve plus bas sur la même page.](/images/platform/governance-security-monitoring.webp) </Frame> | Champ | Type | Requis | Description | | ----------------------------------------- | ------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------ | | Exiger l’authentification à deux facteurs | Bascule | oui | Off garde la 2FA optionnelle pour chaque membre ; on active la politique. | | Période de grâce (jours) | Entier | oui | Jours à partir de la première connexion d’un membre sous la politique avant que l’inscription soit requise. Zéro veut dire immédiat. | | Exempter les utilisateurs SSO-seuls | Bascule | non | Quand on, les membres dont le seul compte est une identité fédérée s’appuient sur l’IdP en amont pour la MFA. | Un membre dans la fenêtre de grâce voit une bannière de compte à rebours dans l’appli qui pointe vers le flux d’inscription. Une fois la grâce expirée, la connexion suivante passe par l’écran d’inscription et le membre ne peut pas continuer tant qu’il n’est pas inscrit. ## Réinitialisation admin pour un membre verrouillé Quand un membre perd son téléphone et ses codes de secours, un Administrateur efface le second facteur sur son compte. Ouvre **Paramètres > Organisation**, clique sur **Modifier le membre** puis sur **Réinitialiser le double facteur** dans le dialogue. Tale désactive la 2FA pour le compte et met fin à chaque session active, donc le membre se réinscrit à sa prochaine connexion. La réinitialisation est enregistrée dans le journal d’audit sous `2fa_reset_by_admin`. Va vers ça comme action de récupération — le membre doit se réinscrire immédiatement une fois revenu. ## Où ça s’inscrit La 2FA est une couche au-dessus du mot de passe — même écran de connexion, deuxième étape. Combine-la avec [membres et rôles](/fr/platform/admin/members-and-roles) (l’admin qui réinitialise le second facteur est le même admin qui gère le compte), avec [politiques et limites](/fr/platform/admin/governance/policies-and-limits) (la politique d’application vit dans la surface gouvernance) et avec [journaux d’audit](/fr/platform/admin/governance/audit-logs) (chaque inscription, désactivation et réinitialisation admin y atterrit). # Admin Source: https://tale.dev/docs/fr/platform/admin/overview Admin est le plan de configuration de Tale. Cela couvre les personnes qui peuvent se connecter, les équipes qui les regroupent, les fournisseurs IA derrière chaque réponse, les clés API qui permettent à du code externe de parler à l’organisation, les connectors tierces que les agents traversent, et le branding que le reste de l’organisation voit. Seuls les Administrateurs et Propriétaires voient le menu Admin complet ; les Développeurs en voient un sous-ensemble, et les autres rôles ne le voient pas du tout. Ces pages décrivent ce que fait chaque réglage et ce qu’il change au produit en cours. La plupart se lisent une fois au montage, puis se revisitent quand quelque chose change — un nouveau collègue, une clé rotée, un nouveau fournisseur. L’histoire des rôles et permissions derrière tout le menu vit dans [Membres et rôles](/fr/platform/admin/members-and-roles) ; commence par là, car chaque autre page Admin renvoie aux noms de rôles qu’elle définit. Tu préfères regarder d’abord ? L’épisode 9 traverse toute la salle de contrôle — fournisseurs, garde-fous, audit, coûts — en trois minutes, sous-titres compris. <Video src="/videos/fr/tutorials/ep9-governance/ep9-governance.fr.mp4" poster="/videos/fr/tutorials/ep9-governance/ep9-governance.fr.webp" captions="/videos/fr/tutorials/ep9-governance/ep9-governance.fr.vtt" lang="fr" title="Épisode 9 — Gouvernance, coûts & confiance" caption="Épisode 9 — Gouvernance, coûts & confiance (2:48)"> </Video> ## Domaines de configuration <CardGroup cols="2"> <Card title="Membres et rôles" icon="users" href="/fr/platform/admin/members-and-roles"> Les six rôles et la matrice au niveau ressource qui dit qui peut lire, écrire, configurer et gouverner. </Card> <Card title="Équipes" icon="users-round" href="/fr/platform/admin/teams"> Regroupe les membres en équipes qui partagent agents, skills et connectors. </Card> <Card title="Agents" icon="bot" href="/fr/platform/admin/agents"> Chaque agent de l’organisation, et là où un Administrateur intervient quand l’un a besoin de gouvernance. </Card> <Card title="Fournisseurs IA" icon="cpu" href="/fr/platform/admin/providers"> Enregistre les identifiants derrière chaque réponse et choisis quels modèles l’organisation peut appeler. </Card> <Card title="Connectors" icon="plug" href="/fr/platform/admin/connectors"> Enregistre et remplace les identifiants derrière Slack, Gmail, Outlook, Google Drive, GitHub, Shopify et plus. </Card> <Card title="Enterprise SSO" icon="shield-check" href="/fr/platform/admin/enterprise-sso"> Branche la connexion à ton fournisseur d’identité via SAML ou OIDC. </Card> <Card title="Clés API" icon="key" href="/fr/platform/admin/api-keys"> Émets et cadre les clés que le code externe utilise pour joindre l’API REST de Tale. </Card> <Card title="Branding" icon="palette" href="/fr/platform/admin/branding"> Le nom, le logo et les couleurs que le reste de l’organisation voit. </Card> <Card title="Authentification à deux facteurs" icon="smartphone" href="/fr/platform/admin/two-factor-authentication"> Exige un second facteur à la connexion et gère l’enrôlement dans toute l’organisation. </Card> <Card title="Changelog" icon="history" href="/fr/platform/admin/changelog"> Le journal in-produit de ce qui a été livré et quand. </Card> <Card title="Gouvernance" icon="scale" href="/fr/platform/admin/governance/audit-logs"> Journaux d’audit, politiques et limites, garde-fous, analyses, rétention et legal hold. </Card> </CardGroup> ## Où cela s’inscrit Admin est la surface que suppose chaque autre onglet. Chat résout un modèle via les fournisseurs configurés ici ; les agents appellent des outils via les connectors configurées ici ; la bibliothèque de skills et l’inbox respectent les frontières d’équipe configurées ici. La lecture naturelle en premier est [Membres et rôles](/fr/platform/admin/members-and-roles) — chaque autre page Admin renvoie aux noms de rôles qu’elle définit. # Automatisations livrées Source: https://tale.dev/docs/fr/platform/automations/builtin Tale livre des automatisations prêtes à l’emploi : trois à but unique qui transforment une boîte aux lettres en une boîte de réception partagée, et un bundle qui résout les issues GitHub de bout en bout. Les Éditeurs et Membres se servent de ce qu’une automatisation installée ajoute — un onglet Boîte de réception, une entrée de Backlog — sans rien installer eux-mêmes ; installer est une action Propriétaire/Admin/Développeur couverte sur [Parcourir et installer des automatisations](/fr/platform/automations/catalog). Cette page nomme ce que fait chacune et l’connector qu’il faut connecter en premier. <Frame caption="Le catalogue des automatisations — chaque carte est à une installation près ; les membres de packs cachés et l’intérieur des bundles restent hors de la liste."> ![Le catalogue des automatisations sur l’onglet Toutes les automatisations, avec les cartes des automatisations e-mail et du bundle Résoudre les issues GitHub, chacune avec son icône et sa description.](/images/platform/automations-catalog.webp) </Frame> ## Synchroniser les e-mails Gmail, Outlook et IMAP **Synchroniser les e-mails Gmail**, **Synchroniser les e-mails Outlook** et **Synchroniser les e-mails via SMTP/IMAP** sont la même automatisation répétée trois fois, une par type de boîte aux lettres : chacune requiert exactement le connecteur que son nom indique, chacune installe la même vue intégrée **Boîte de réception**, indépendante du canal, et chacune embarque le workflow de synchronisation qui rapatrie la boîte aux lettres dans les conversations selon une planification, toutes les cinq minutes d'origine — change le [déclencheur de planification](/fr/platform/automations/triggers) pour rapatrier moins souvent. Une organisation qui reçoit du courrier sur plus d'un type de boîte aux lettres en installe plusieurs ; chaque Boîte de réception ne montre que le trafic de sa propre boîte aux lettres. Quand un connecteur porte plusieurs identifiants — deux boîtes IMAP, deux comptes Gmail — une passe de sync couvre chaque identifiant actif, et chaque boîte garde sa propre position dans son propre courrier : une boîte ajoutée plus tard ne saute donc pas tout ce qui est plus ancien que ce que la première a déjà relevé. Une boîte injoignable est laissée de côté pour cette passe et reprise à la suivante, sans retenir les autres. Les automatisations **Trier la boîte de réception …** correspondantes se répartissent de la même façon avant d’écrire un seul résumé sur chaque boîte connectée. | Automatisation | Requiert | Boîte aux lettres | | -------------------------------------- | --------- | --------------------------------- | | Synchroniser les e-mails Gmail | Gmail | Une boîte Gmail | | Synchroniser les e-mails Outlook | Outlook | Une boîte Microsoft Outlook | | Synchroniser les e-mails via SMTP/IMAP | IMAP/SMTP | Toute boîte privée en IMAP / SMTP | ## L’onglet Boîte de réception Chacune des trois s’ouvre sur son onglet **Boîte de réception** : quatre sous-onglets — **Ouvert**, **Fermé**, **Spam**, **Archivé** — chacun une vue scindée avec la liste des conversations à gauche et le fil sélectionné à droite. Ouvrir une conversation remplit le panneau de droite avec tout l’historique de ses messages ; tant que tu n’en as choisi aucune, le panneau affiche **Sélectionne une conversation pour voir les détails**. Le champ de message se trouve sous le fil dans l’onglet **Ouvert** — les réponses appartiennent aux conversations actives, donc les trois autres onglets sont en lecture seule. Écris dans **Saisis un message** et clique sur **Envoyer** ; la réponse part par la boîte aux lettres sur laquelle la conversation est arrivée, avec le destinataire et l’objet dérivés du fil — rien à adresser à la main. L’en-tête du fil montre le vrai **Expéditeur** de cette conversation — l’adresse à laquelle le contact a écrit, ou l’expéditeur que tu choisis à la rédaction — pour que ce que tu vois corresponde à ce qu’une réponse envoie vraiment. Sur une connexion Gmail ou Outlook, le champ **Expéditeur** à la rédaction est l’adresse du compte connecté ; sur IMAP/SMTP tu n’édites que la partie locale de **Expéditeur**, et le domaine vérifié reste fixé en badge pour que tu ne le quittes jamais. **Améliorer** réécrit ton brouillon avec l’IA avant l’envoi. Sur l’automatisation IMAP, les réponses envoyées depuis la boîte elle-même — depuis n’importe quel client mail — se synchronisent aussi dans la conversation, ordonnées avec le reste du fil. L’en-tête du fil porte les verbes de statut de la conversation sélectionnée — **Fermer la conversation** et **Marquer comme spam** sur un fil ouvert, **Rouvrir la conversation** sur un fil fermé ou archivé, **Pas du spam** et le destructeur **Supprimer** sur le spam. Sélectionner plusieurs lignes dans la liste fait apparaître les mêmes verbes en actions groupées. Les Admins et Propriétaires utilisent aussi le contrôle **Responsable** dans l’en-tête pour mettre le travail en file. Ouvre-le et choisis sous **Personnes** et **Équipe** — les deux dimensions sont indépendantes, donc une conversation peut rester dans la file d’une équipe et être quand même assignée à une personne. Changer la personne la notifie dans l’app et par e-mail ; assigner à une équipe notifie les membres de cette équipe (l’acteur est exclu dans les deux cas). S’assigner soi-même, retirer la personne (**Retirer l'attribution**) et retirer l’équipe (**Retirer l'équipe**) ne notifient personne. Les non-admins voient l’assignation courante en lecture seule. La visibilité suit l’assignation : les Membres ne voient que leurs propres files et celles de leurs équipes ; le courrier vraiment non assigné est réservé au triage admin. Associe l’assignation au [Routage des conversations](/fr/platform/admin/governance/policies-and-limits#routage-des-conversations) quand les adresses entrantes doivent atterrir automatiquement dans une file. ## Résoudre les issues GitHub **Résoudre les issues GitHub** est un bundle, pas une automatisation seule : l’installer lance un seul assistant agrégé qui installe quatre automatisations cachées d’un coup, liées au projet que tu choisis, et requiert l’connector GitHub. Chaque membre couvre une étape de la boucle. **Trier les issues GitHub** — « Évalue les issues GitHub ouvertes d’un dépôt et propose les issues exploitables dans le backlog du projet — un humain les démarre depuis là. » — tourne sur une planification récurrente. **Synchroniser les issues GitHub** — « Termine une tâche du tableau lorsque son issue GitHub est fermée. Parcourt les tâches ouvertes du tableau lui-même, sans jamais en manquer. Mise à jour uniquement — ne crée jamais de tâche. » — que la fermeture vienne de la chaîne de résolution ou d’un humain agissant directement sur GitHub, le résultat est le même : jamais de création, jamais de réouverture. **Créer des pull requests GitHub** livre l’agent PR Creator : une fois qu’un humain a cliqué **Démarrer** sur une tâche proposée, il clone le dépôt, ouvre ou reprend la pull request de l’issue, implémente le correctif, le vérifie contre les tests du projet, et attend que la CI passe au vert. **Examiner les pull requests GitHub** livre l’agent PR Reviewer : il reteste la branche du PR Creator, confirme la CI, et un juge sans outils décide de la fusionnabilité — approuvé gare la tâche en **En revue** pour qu’un humain la fusionne sur GitHub ; non approuvé la renvoie au PR Creator avec un retour, jusqu’à un petit plafond de reprises. Un humain reste dans la boucle à deux moments : démarrer une tâche proposée depuis le Backlog, et fusionner la pull request sur GitHub lui-même — rien dans le bundle ne fusionne à ta place. ## Modèles de synchronisation et d’entretien Huit automatisations de plus attendent dans le catalogue pour le moment où tu en as besoin. Chacune est un workflow unique : installe-la, pointe-la vers tes données — les modèles de synchronisation demandent leur source via la planification qu’ils créent — puis ajuste-la librement sur la page de l’automatisation, où une modification devient une nouvelle version que tu mets en service quand tu es prêt. | Automatisation | Requiert | Ce qu’elle fait | | ------------------------------------------ | ------------ | -------------------------------------------------------------------------------------------------- | | Synchroniser les pages Confluence | Confluence | Importe les pages d’un espace Confluence dans la bibliothèque de connaissances selon un planning | | Synchroniser les fichiers Google Drive | Google Drive | Importe les documents d’un dossier Drive dans la bibliothèque de connaissances | | Synchroniser les clients Shopify | Shopify | Importe les clients de la boutique dans les fiches contacts de l’organisation | | Synchroniser les produits Shopify | Shopify | Importe le catalogue produits de la boutique dans les fiches produits de l’organisation | | Analyser les relations entre produits | — | Parcourt le catalogue et consigne accessoires, variantes et compléments | | Indexer les documents pour la recherche | — | Indexe les documents fraîchement importés pour que les agents puissent les rechercher et les citer | | Archiver les conversations inactives | — | Clôt les conversations restées silencieuses au-delà de leur période d’inactivité | | Notifier les membres des messages entrants | — | Alerte les membres dès qu’un nouveau message entrant arrive dans une conversation ouverte | ## Les packs préinstallés La mécanique qui fait tourner les tableaux de chaque organisation est elle aussi faite d’automatisations — installées automatiquement à la création, cachées du catalogue, mais visibles sur l’onglet **Installées** comme tout le reste. Le **pack tâches** lance un agent assigné dès qu’une tâche lui arrive, trie le travail non assigné, réagit aux @-mentions, fait passer le travail terminé par la relecture, balaie les exécutions bloquées, fait respecter les SLA et garde en mouvement tâches dépendantes, sous-tâches et archives ; un pack voisin garde les fichiers OneDrive synchronisés. Chacune est une automatisation normale — ouvre-la pour lire son document sur le canvas, suivre ce qu’elle a fait dans sa [liste des exécutions](/fr/platform/automations/execution-logs), ou couper un [déclencheur](/fr/platform/automations/triggers) pour qu’elle cesse de se lancer ; une désinstallation tient, et rien ne la réinstalle dans ton dos. ## Où cela s’inscrit Les automatisations de boîte de réception, le bundle Résoudre les issues GitHub et les modèles de synchronisation sont ce qui est livré aujourd’hui ; une automatisation privée que ton organisation construit ou téléverse apparaît dans le même catalogue, juste à côté. [Parcourir et installer des automatisations](/fr/platform/automations/catalog) couvre la mécanique du catalogue ; [Backlog du projet](/fr/platform/projects/backlog) est la lecture suivante pour ce qui arrive à une tâche une fois que Trier les issues GitHub l’a proposée. # Déclencheurs d’automatisation Source: https://tale.dev/docs/fr/platform/automations/triggers Un déclencheur, c’est ce qui lance une automatisation quand personne ne clique nulle part. Il en existe exactement trois sortes, l’ensemble est fermé, et une automatisation peut en porter plusieurs à la fois. Le plus utile à savoir sur un déclencheur : il se rattache au **nom** de l’automatisation et non à une version. C’est pour cela que mettre une nouvelle version en service n’invalide jamais une URL de webhook dont dépend un système externe, et ne fait jamais disparaître une planification. Chaque déclencheur lance la version en service et s’exécute en mode réel : une automatisation sans version en service ne peut donc pas être lancée par l’un d’eux. Chaque déclencheur porte un interrupteur et retient la dernière fois que le planificateur a agi dessus. ## Les trois sortes | Sorte | Lance l’automatisation quand… | | ---------- | --------------------------------------------------------------- | | `schedule` | une expression cron arrive à échéance dans un fuseau IANA nommé | | `webhook` | un système externe poste sur une URL protégée par un token | | `event` | un événement nommé de la plateforme se produit | Un démarrage programmatique n'a besoin d'aucun déclencheur : un client d'API avec une clé d'organisation appelle `POST /api/v1/automations/{name}/runs` (ou l'outil MCP `start_run`), et la clé elle-même est le droit d'entrée — voir la [référence API](/fr/develop/api-reference). ## Planifications Une planification porte une expression cron à cinq champs et le fuseau IANA dans lequel elle est lue. Les champs sont la minute, l’heure, le jour du mois, le mois et le jour de la semaine, et chacun accepte un `*`, un nombre, une plage, un pas, ou une liste de ceux-ci séparée par des virgules. ```text */15 * * * * toutes les quinze minutes 0 9 * * 1-5 09:00 en semaine 0 6 1 * * 06:00 le premier du mois 30 8 1 * 1 08:30 le 1er et chaque lundi ``` Le jour de la semaine va de 0 à 7, où 0 comme 7 désignent le dimanche. Quand tu restreins à la fois le jour du mois **et** le jour de la semaine, un jour correspondant à l’un ou à l’autre déclenche — la règle même de crontab, et celle qui fait que le dernier exemple se lit comme il se comporte. Le fuseau est résolu en heure locale : une planification écrite pour 09:00 dans `Europe/Zurich` reste à 09:00 au passage à l’heure d’été, au lieu de dériver d’une heure deux fois par an. Une planification qui ne nomme aucun fuseau est lue en UTC. La résolution est d’une minute, et une planification est un battement de cœur, pas une file d’attente : après une panne, l’automatisation repart à sa prochaine échéance au lieu de rejouer celles qu’elle a manquées. Une planification dont l’expression cron ne se lit pas est ignorée plutôt que d’arrêter les autres planifications de la plateforme — sa date de dernier déclenchement cesse simplement d’avancer, et c’est le signal d’aller la relire. ## Webhooks Un webhook est une URL entrante protégée par un token. Sa création engendre le token et l’affiche une seule fois ; seul son empreinte est stockée, de sorte que la plateforme peut vérifier un appelant sans jamais pouvoir reconstituer l’URL. Tout système qui y poste lance une exécution, et le corps de la requête devient la charge utile de l’exécution. ```bash curl -X POST https://<ton-hote-tale>/api/automations/webhook/<token> \ -H 'Content-Type: application/json' \ -d '{"invoiceId": "inv-1"}' ``` Un appel réussi est accepté immédiatement et répond avec l’id de l’exécution lancée : l’appelant n’attend donc jamais que l’automatisation se termine. Un corps qui n’est pas du JSON est transmis tel quel en texte plutôt que refusé, car certains fournisseurs postent des charges utiles en formulaire ou en texte brut. Les corps sont plafonnés à 256 Ko : un webhook reçoit une charge utile, pas un téléversement. Tu peux restreindre l’exécution à un projet en ajoutant `?projectId=<id>` à l’URL — le projet que tu intègres dans l’URL donnée au fournisseur. Omets-le et l’exécution utilise la liaison de l’automatisation elle-même : une automatisation liée à un seul projet s’y exécute, une liée à plusieurs ou à aucun s’exécute sur toute l’organisation. Le projet est vérifié contre ces liaisons, de sorte qu’une URL publique ne peut jamais étendre l’exécution au-delà de ce à quoi l’automatisation est liée ; un projet hors de l’ensemble répond par un 400. Deux refus valent la peine d’être reconnus. Un token inconnu et le token d’un déclencheur éteint répondent volontairement de la même manière, pour que personne ne puisse sonder la plateforme afin de savoir quels tokens existent. Une automatisation sans version en service répond plutôt par un conflit, ce qui te dit que l’URL va bien et que c’est la mise en service qui manque. <Warning> Le token dans l’URL est l’identifiant. Quiconque détient l’URL peut lancer l’automatisation. Conserve-la comme un mot de passe, transmets-la par un canal sûr, et supprime le déclencheur pour la révoquer — le token ne se récupère pas ensuite. </Warning> ## Événements Un déclencheur d’événement nomme un événement de la plateforme et se déclenche dès que cet événement se produit dans l’organisation. La charge utile de l’événement devient l’entrée de l’exécution, ce qui en fait la sorte vers laquelle se tourner quand le travail de l’automatisation est de réagir à quelque chose que la plateforme vient de faire elle-même. <Note> Un événement émis par l’exécution d’une automatisation ne déclenche jamais de déclencheur. Une automatisation qui écrit un enregistrement, lequel émet un événement, lequel lance la même automatisation, serait une boucle sans fin qu’aucune limite par exécution ne peut arrêter — la plateforme refuse donc dès la distribution. </Note> ## Ce que chaque sorte transporte dans l’exécution L’entrée que reçoit une automatisation dit quelle sorte l’a lancée : un même document peut donc servir plusieurs déclencheurs et se brancher sur la différence. | Sorte | L’entrée de l’exécution | | ---------- | ---------------------------------------------------------------------- | | `schedule` | La sorte de déclencheur et l’échéance pour laquelle il s’est déclenché | | `webhook` | La sorte de déclencheur et le corps posté en charge utile | | `event` | La sorte de déclencheur, le nom de l’événement et sa charge utile | Une exécution démarrée par l'API porte exactement l'`input` envoyé par l'appelant. Déclare la forme attendue dans le schéma `inputs` du document, et la référence qui la lit est vérifiée avant même que l’automatisation ne s’exécute. ## La mise en service ne les dérange pas Parce qu’un déclencheur nomme l’automatisation plutôt qu’une version, l’ensemble survit à chaque mise en service et à chaque retour arrière. Publie une URL de webhook auprès d’un partenaire, mets onze versions de plus en service, reviens deux fois en arrière : cette URL continue de fonctionner et atteint chaque fois ce qui est en service à ce moment-là. L’inverse est vrai aussi : ajouter, modifier ou retirer un déclencheur ne change rien au document ni à ses versions. Déclencheurs et versions sont deux choses indépendantes à propos de la même automatisation. ## En éteindre un sans le perdre Chaque déclencheur a un interrupteur, et l’éteindre est la façon d’empêcher une automatisation de se lancer sans rien abandonner. Une planification éteinte n’arrive plus à échéance, une URL de webhook éteinte n’est plus honorée, et un déclencheur d’événement éteint ne correspond plus — tandis que la ligne, sa configuration et tout l’historique des exécutions de l’automatisation restent exactement où ils étaient. Rallume-le et il repart. Supprimer un déclencheur est la version définitive du même geste, et pour un webhook c’est aussi la façon de révoquer l’URL. Prends l’interrupteur quand tu veux une pause, et la suppression quand tu veux que l’identifiant disparaisse. ## Où cela s’inscrit Trois sortes, un seul comportement : chacune lance la version en service en mode réel, chacune retient son dernier déclenchement, et chacune se met en pause sans être perdue — et aucune ne se soucie du nombre de mises en service depuis. [Concepts d’automatisation](/fr/platform/automations/concepts) explique pourquoi le rattachement au nom rend cela vrai ; [Journaux d’exécution](/fr/platform/automations/execution-logs) montre les exécutions que tes déclencheurs ont produites et laquelle a lancé chacune. # Ajouter des automatisations à ton organisation Source: https://tale.dev/docs/fr/platform/automations/catalog La page **Automatisations** de la barre latérale liste chaque automatisation de l’organisation et sert de porte d’entrée aux nouvelles. Une organisation démarre avec les packs livrés déjà en place, tu peux en créer une de zéro sur son canvas, et **Téléverser un paquet** accepte un pack construit ailleurs — sous forme de fichiers, ou d’un seul zip qui installe aussi les bundles de skills que le pack embarque. Gérer la page demande les permissions Propriétaire, Admin ou Développeur ; tout ce qu’un téléversement crée reste un brouillon jusqu’au déploiement — rien de ce qui tourne ne change parce qu’un fichier a atterri. Cette page couvre la provenance des automatisations et ce qu’un paquet téléversé peut contenir. En piloter une — canvas, versions, exécutions de test, déploiement — vit sur [L’éditeur de workflow](/fr/platform/automations/editor) ; le modèle sous-jacent sur [Concepts d’automatisation](/fr/platform/automations/concepts) ; ce que font les packs livrés sur [Automatisations livrées](/fr/platform/automations/builtin). <Frame caption="La page Automatisations — chaque ligne est une automatisation avec son nombre de versions et la version en service, ou Pas en service."> ![La page Automatisations listant les automatisations e-mail et GitHub livrées, chaque ligne avec son nombre de versions et son état de déploiement.](/images/platform/automations-catalog.webp) </Frame> ## Ce que montre la liste Chaque ligne est une automatisation : son nom, son nombre de versions, et soit la version en service, soit **Pas en service**. La page de l’org liste les automatisations au niveau de l’organisation ; une automatisation qui appartient à un projet vit dans l’onglet **Automatisations** de ce projet — l’endroit où elle apparaît se décide une fois, à son premier enregistrement, et ne bouge plus. Clique une ligne pour arriver sur la page de l’automatisation, que décrit [L’éditeur de workflow](/fr/platform/automations/editor). **Nouvelle automatisation** propose deux façons de partir de zéro : **À partir d’un objectif** confie ta description au builder, qui construit les nœuds pour toi ; **Vierge (trigger + agent)** échafaude une automatisation à un seul agent que tu câbles toi-même — nomme-la, choisis le modèle de l’agent, et le reste (le prompt, les outils et secrets accordés, le trigger) est à toi de le poser sur le canvas. Les packs livrés ne demandent aucune installation : chaque organisation en est équipée à sa création, prêts à déployer. ## Téléverser un paquet Un pack est un dossier : `workflow.yml` (le document de l’automatisation — requis), `automation.yml` (le manifeste — optionnel) et, quand le pack apporte son propre savoir, un dossier par skill sous `skills/`. ```text review-invoices/ ├── workflow.yml ├── automation.yml └── skills/ └── invoice-rules/ ├── SKILL.md └── references/ └── checklist-rules.md ``` Pour téléverser, ouvre **Automatisations**, choisis **Téléverser un paquet** dans le menu **Nouvelle automatisation**, puis l’une des deux formes du même pack : - **Les fichiers** — `workflow.yml`, plus `automation.yml` si le pack en fournit un. Le bon choix pour un pack qui n’est que son document. - **Un seul `.zip` du dossier du pack** — obligatoire quand le pack embarque des skills, puisque seul le zip peut porter leurs dossiers. Les notes Markdown hors de `skills/` (un README, par exemple) sont ignorées, tout comme les dotfiles et les résidus de build (`__pycache__/`, `node_modules/`) — alors zippe le dossier tel quel, même juste après avoir lancé les tests. Le zip reste sous 20 MiB. Choisis avant d’envoyer où l’automatisation s’installe — l’organisation, ou un projet. Un pack dont le manifeste déclare `scope: project` ne s’installe que dans un projet ; le serveur refuse de l’installer à l’échelle de l’organisation. Le choix n’est pas définitif : installer dans un projet lie l’automatisation à ce projet, et le panneau **Projets** de sa page gère l’ensemble ensuite — lie d’autres projets, ou aucun pour qu’elle serve toute l’organisation. <Frame caption="Téléverser un paquet — les fichiers ou un zip, et où l’automatisation s’installe."> ![Le dialogue de téléversement de paquet avec sa zone de dépôt et le sélecteur Installer dans réglé sur Organisation.](/images/platform/automations-upload-dialog.webp) </Frame> Le serveur valide avant d’enregistrer quoi que ce soit. Le document passe par la même validation moteur que l’éditeur — un téléversement qui ne tournerait pas est refusé avec les messages du moteur, pas enregistré cassé — et les blocs `subjects` et `settings` du manifeste deviennent le contrat de tâches et les [formulaires de paramètres](#paramètres-déclarés-par-le-pack) de l’automatisation, exactement comme le ferait un enregistrement depuis le canvas. Ce qui atterrit est une **version brouillon** derrière la barrière de déploiement habituelle — aucun déclencheur ne tourne tant qu’aucune version n’est en service. Le dialogue propose la mise en service dès que le téléversement réussit : mets la nouvelle version en service directement, ou choisis **Plus tard** et fais-le depuis la page de l’automatisation quand tu veux. Téléverser à nouveau le pack d’une automatisation existante ajoute la version suivante — le store n’écrase jamais l’historique, chaque version antérieure reste exactement où elle était. Choisir un projet comme cible lie aussi l’automatisation existante à ce projet, en plus de ceux qu’elle sert déjà. ## Les skills que le paquet embarque Un zip peut livrer les skills sur lesquels son document s’appuie — les bundles qu’un nœud agent charge ou depuis lesquels une étape de script tourne. Le manifeste doit les nommer, et la déclaration se vérifie dans les deux sens : un dossier `skills/` que le manifeste ne déclare pas refuse le téléversement, tout comme un slug déclaré que le zip n’apporte pas. ```yaml # automation.yml name: Review invoices skills: - invoice-rules subjects: task: # …le contrat de tâches, inchangé ``` Chaque bundle embarqué est validé comme un vrai skill — frontmatter parsé, `name` égal à son dossier — et installé dans la [bibliothèque de skills](/fr/platform/workspace/skills) de l’organisation dès que le téléversement est accepté ; les exécutions de test du brouillon les trouvent donc déjà. Ce qui arrive par slug dépend de ce que la bibliothèque tient déjà : - **Slug nouveau** — le bundle est installé. - **Bundle identique** — rien n’est écrit ; le téléversement le signale inchangé. - **Contenu différent** — le téléversement s’arrête et liste les slugs en collision. Confirme pour les remplacer par les versions du paquet ; l’ancien `SKILL.md` reste dans l’historique de chaque skill. Rien — ni l’automatisation, ni aucun skill — n’est écrit avant ta confirmation. Un document qui référence un skill que le paquet n’embarque pas et que la bibliothèque ne tient pas se téléverse quand même — la référence manquante revient en avertissement, pour qu’un pack puisse nommer un skill que tu installeras plus tard. ## Paramètres déclarés par le pack Quand une automatisation lit à chaque exécution une configuration qui appartient à l’opérateur — un profil de dossier, une politique de validation —, le manifeste peut la déclarer comme **formulaires de paramètres**. La plateforme les affiche dans le dialogue de création du tableau des tâches et enregistre chaque formulaire comme fichier YAML plat dans un dossier du projet : personne n’édite un fichier à la main pour configurer l’automatisation, et chaque projet garde ses propres valeurs. ```yaml # automation.yml settings: folder: Setup forms: - file: validation-policy.yaml title: Validation policy required: true fields: - key: method label: Validation profile type: select default: strict_rules options: - value: strict_rules label: Strict checklist (standard) ``` Un formulaire possède son fichier : enregistrer réécrit `Setup/validation-policy.yaml` entièrement à partir des valeurs du formulaire, et le formulaire se préremplit avec ce que contient le fichier — qu’il l’ait écrit lui-même ou que quelqu’un l’ait déposé à la main. Les champs sont `text`, `number`, `boolean` ou `select` ; chaque valeur est stockée comme chaîne, un champ `text` peut imposer un `pattern`, et les titres, libellés, textes d’aide et noms d’options se localisent via des blocs `i18n` sur chaque entrée. Tout ce qui dépasse un fichier clé-valeur plat — blocs imbriqués, listes — va dans un fichier séparé, tenu à la main, que le workflow lit à côté. Marque un formulaire `required: true` et le dialogue de création l’impose par projet : la première fois que quelqu’un choisit le modèle de tâche de l’automatisation dans un projet pas encore configuré, les formulaires apparaissent avant le champ de la tâche, et la création ne continue qu’une fois qu’ils sont enregistrés. Ensuite, le bouton **Paramètres** du même dialogue rouvre les formulaires pour les modifier — chacun avec son propre **Enregistrer**, actif seulement quand quelque chose a changé. ## Livrables déclarés par le pack Un pack dont les exécutions déposent des documents dans le dossier d'une tâche peut nommer lesquels sont les **livrables** — ce pour quoi quelqu'un ouvre la tâche. La zone Résultat de la tâche liste exactement ceux-là, toujours ouverte et dans l'ordre déclaré, tandis que tout le reste du dossier — les fichiers déposés, les fichiers de travail de l'exécution — se replie sous **Fichiers**. ```yaml # automation.yml subjects: task: outcome: files: - return.xml - report.md - journal.csv ``` Seul le pack sait lesquels de ses fichiers écrits sont l'essentiel : la plateforme ne devine rien. Un nom qu'aucune exécution n'a encore déposé apparaît quand même comme une ligne promise marquée _Pas encore prêt_ — la tâche nomme donc ce qu'elle produira avant de le produire. Les jokers `*` et `?` sont acceptés (`return-*.xml`) pour un nom qu'une exécution construit. Ne déclare rien et la zone Résultat retombe sur tous les fichiers déposés par les exécutions, le plus récent d'abord. ## Où cela s’insère Les automatisations arrivent par trois chemins — livrées avec l’organisation, créées sur le canvas, ou téléversées en pack — et chaque chemin finit au même endroit : une version brouillon sur la page de l’automatisation, déployée quand tu le décides. Un téléversement en zip alimente aussi la [bibliothèque de skills](/fr/platform/workspace/skills) avec les bundles dont l’automatisation a besoin, avec une confirmation devant chaque skill qu’il remplacerait. [L’éditeur de workflow](/fr/platform/automations/editor) est la lecture suivante pour mettre ce brouillon en service. # L’éditeur de workflow Source: https://tale.dev/docs/fr/platform/automations/editor Cette page est la moitié pratique des automatisations : ce que tu cliques, et dans quel ordre, pour transformer une idée en la version que tes déclencheurs exécutent. Le modèle en dessous — un document, des versions immuables, une seule en service, des déclencheurs rattachés au nom — vit dans les [concepts d’automatisation](/fr/platform/automations/concepts), et cette page le suppose acquis. Enregistrer, tester et mettre en service sont trois gestes distincts ici, et c’est cette séparation qui te laisse modifier une automatisation en service sans déranger la moindre exécution en cours. ## Où vit une automatisation Ouvre **Automatisations** dans la barre latérale. La liste montre chaque automatisation de l’organisation avec son nombre de versions et soit la version en service, soit **Pas en service** tant qu’il n’y en a aucune. Clique sur l’une d’elles et tu arrives sur sa page. Cette page est une seule surface qui défile, pas une série d’onglets. En haut se trouvent le nom de l’automatisation, la version que tu regardes, celle qui est en service et le bouton de lancement. En dessous vient le canvas avec le panneau du nœud à côté, puis la barre d’enregistrement, le panneau **Déclencheur** et le panneau **Projets** — les projets dont les boards de tâches voient l’automatisation ; aucun veut dire toute l’organisation — et tout en bas les listes **Versions** et **Exécutions** côte à côte. ## Lire le canvas Le canvas dessine la version affichée. Chaque boîte est un nœud, étiqueté avec son id et son type, et les boîtes qui lisent la sortie d’un autre nœud le disent : une ligne **Lit** nomme les nœuds dont elles dépendent. Les flèches entre les boîtes ne sont pas quelque chose que tu traces — une flèche existe parce que le champ d’un nœud référence la sortie d’un autre. Le graphe correspond donc toujours au document. Le contrôle du flux apparaît en badge sur la boîte concernée, dans le même vocabulaire que le document : `si …`, `sinon de …`, `pour chaque …`, `répéter jusqu’à …` (avec le plafond quand il y en a un) et `continuer en cas d’erreur`. Rien de la forme du graphe ne se cache dans un écran de réglages à part. Deux états valent la peine d’être reconnus. Une version sans nœud le dit et t’invite à en ajouter un au document. Une version dont les nœuds se référencent en boucle t’avertit que l’ordre affiché est celui dans lequel ils sont écrits, pas un ordre que le moteur pourrait exécuter, et te demande de retirer l’une des références pour rompre la boucle. <Note> Le canvas sert à lire et à sélectionner. Tu relies des nœuds en les référençant, pas en tirant une liaison entre deux boîtes. </Note> ## Modifier un nœud Clique sur une boîte et le panneau à côté du canvas se remplit des champs de ce nœud. Les champs affichés dépendent du type : **Code** pour un `transform`, **Prompt**, **Prompt système**, **Modèle** et **Schéma de sortie** pour un `llm`, **Workflow** pour un `subworkflow`, et **Entrée** partout où il y en a une. **Entrée** est un objet JSON, et c’est là que vivent les références. Une valeur texte peut référencer la sortie d’un autre nœud, et c’est précisément cette référence qui trace la flèche sur le canvas. Tant que le JSON est incomplet, le panneau te dit qu’il n’est pas encore valide et laisse le nœud inchangé : une modification à moitié tapée ne peut donc jamais être enregistrée par accident. Sous les champs propres au type se trouve le groupe **Contrôle du flux** avec **Si**, **Sinon de**, **Pour chaque** et **Répéter jusqu’à**. Ce sont les mêmes champs que reflètent les badges du canvas : en régler un ici change le badge immédiatement. ## Enregistrer, lancer, mettre en service Les trois gestes sont volontairement distincts. Parcours-les dans l’ordre la première fois et la séparation cesse de ressembler à du travail en plus. <Steps> <Step title="Enregistrer une version"> Les modifications affichent la mention **Modifications non enregistrées** jusqu’à ce que tu enregistres. Écris une **Note de version** qui dit ce qui a changé — cette note sera plus tard la seule chose qui distingue deux versions dans la liste — puis clique sur **Enregistrer une version**. L’enregistrement ajoute une version et laisse chaque précédente exactement telle qu’elle était. Si rien n’a changé, le bouton te le dit au lieu de créer une version identique. </Step> <Step title="La lancer contre des simulations"> **Essai** lance une exécution en mode simulé : les connecteurs renvoient leurs valeurs déterministes et rien hors de la plateforme n’est touché. Tu peux appuyer autant de fois que tu veux, et c’est ce qui en fait la boucle où travailler tant qu’un nœud prend encore forme. Quand l’automatisation est liée à plus d’un projet, un sélecteur de **portée du projet** se place à côté des commandes d’exécution. Il vaut « toute l’organisation » par défaut ; choisis l’un des projets liés pour que l’exécution — et les outils de tâches et de documents de ses agents — n’agisse que dans ce projet. </Step> <Step title="Mettre en service la version voulue"> Dans la liste **Versions**, clique sur **Mettre en service** pour la version que tes déclencheurs doivent exécuter. Celle en service porte le badge **En service**, et en mettre une autre en service déplace ce badge sans toucher au contenu d’aucune version. </Step> </Steps> <Note> Le bouton de lancement de cette page exécute toujours contre des simulations. Une exécution autorisée à atteindre le monde extérieur est lancée par un déclencheur ou par un appel programmatique, et cela demande un droit de développeur. </Note> ## Les tests et la porte de mise en service Les tests font partie du document, pas d’un panneau séparé. Chacun porte un nom, une entrée et des attentes sur la sortie comme sur les effets que l’exécution doit produire, et ils voyagent avec la version comme n’importe quel autre champ. ```yaml tests: - name: relance un mauvais payeur input: { invoiceId: 'inv-1' } expect: effects: - connector: email.send ``` Le résultat des tests d’une version est consigné à l’enregistrement, et la liste **Versions** l’affiche en badge **Tests réussis** ou **Tests en échec**. La mise en service lit ce fait : une version enregistrée avec des tests en échec est refusée, et la liste indique qu’elle n’a pas été mise en service plutôt que de ne rien faire en silence. Corrige la cause et enregistre une nouvelle version — un résultat consigné est un fait sur cette version-là et ne change jamais. ## Revenir en arrière Revenir en arrière, c’est mettre en service une version plus ancienne. Trouve-la dans la liste, lis sa note pour confirmer que c’est la bonne, et clique sur **Mettre en service**. Le badge se déplace, les versions plus récentes restent intactes dans la liste, et aucun document n’est réécrit. C’est pour cela que les notes de version comptent plus qu’il n’y paraît. Six versions plus tard, c’est la note qui te dit laquelle était le dernier bon état : écris-la donc pour la personne qui la lira pendant un incident. ## Lire la dernière exécution sur le canvas Dès qu’une automatisation s’est exécutée, **Afficher la dernière exécution** superpose cette exécution au canvas. Chaque boîte reprend le statut que l’exécution lui a donné — **Exécuté**, **Ignoré**, **En échec**, **Jamais atteint**, ou **Pas encore atteint** tant que l’exécution continue. Un échec devient ainsi une position dans le graphe plutôt qu’une ligne à chercher dans un log. Sélectionne un nœud avec la superposition active et le panneau ajoute une section **Dans cette exécution** : l’**Entrée résolue** que le nœud a réellement reçue une fois tous les templates évalués, sa **Sortie**, et les effets qu’il a produits, ou une note disant qu’il n’a rien changé hors de la plateforme. L’entrée résolue est en général la réponse la plus rapide à la question de savoir pourquoi un nœud a fait ce qu’il a fait : elle montre la valeur qu’une référence a produite, pas la référence que tu as écrite. **Ouvrir la dernière exécution** mène à la page complète de l’exécution, où le même canvas côtoie son entrée, sa sortie et la liste complète des effets. [Journaux d’exécution](/fr/platform/automations/execution-logs) lit cette page de bout en bout. ## Où cela s’inscrit La boucle est courte une fois les trois gestes bien séparés : modifier un nœud, enregistrer une version avec une note qui vaut la peine d’être lue, la lancer contre des simulations jusqu’à ce qu’elle fasse ce que tu voulais, puis la mettre en service — et mettre en service une version plus ancienne quand il faut défaire. [Concepts d’automatisation](/fr/platform/automations/concepts) est le modèle que cette page manœuvre ; [Déclencheurs de workflow](/fr/platform/automations/triggers) est ce qui lancera la version en service une fois que tu en seras content. # Journaux d’exécution Source: https://tale.dev/docs/fr/platform/automations/execution-logs Chaque lancement d’une automatisation ouvre une exécution, et cette exécution continue de s’écrire elle-même jusqu’à ce qu’elle se termine. Elle enregistre ce qui l’a lancée, la version qu’elle a utilisée, ce qu’elle a reçu, ce que chaque nœud a produit et tout ce qu’elle a changé hors de la plateforme. C’est la surface vers laquelle pointe chaque autre page d’automatisation quand quelque chose ne s’est pas passé comme prévu : autant savoir en lire une avant d’en avoir besoin. ## La liste des exécutions La page d’une automatisation se termine par une liste **Exécutions**, la plus récente en premier. Chaque ligne porte le statut de l’exécution, s’il s’agissait d’un essai ou d’une exécution réelle, la version employée, l’heure de départ et ce qui l’a lancée. Une exécution en échec ou en attente affiche la raison sur la ligne même plutôt que son lanceur : la liste répond donc souvent à la question sans qu’il faille ouvrir quoi que ce soit. Une automatisation qui ne s’est jamais exécutée le dit, au lieu d’afficher un tableau vide. ## Ce que dit chaque statut | Statut | Ce qu’il t’apprend | | --------------------- | ------------------------------------------------------------------------------ | | **En file d’attente** | L’exécution existe et attend que le moteur la prenne en charge | | **En cours** | Le moteur avance à travers les nœuds | | **En attente** | L’exécution est arrêtée sur une décision humaine ou une réponse qu’elle attend | | **Réussie** | Chaque nœud atteint est allé au bout et la sortie a été produite | | **En échec** | Un nœud a levé une erreur et rien n’était réglé pour continuer au-delà | | **Arrêtée** | Quelqu’un a annulé l’exécution ; ce qui était déjà fait n’est pas défait | **En attente** est le statut le plus mal lu. Ce n’est ni un blocage ni un échec : l’exécution garde sa place et repartira du nœud où elle s’est arrêtée dès que la décision qu’elle attend sera prise. [Approbations dans les workflows](/fr/platform/automations/approvals-in-workflows) explique ce qu’elle attend. ## Essais et exécutions réelles Chaque exécution est marquée comme l’un ou l’autre, et la différence tient à ce que le monde extérieur ait été touché ou non. Un **essai** utilise la valeur déterministe de chaque connecteur : aucun courrier ne part, aucun enregistrement n’est écrit, rien n’est facturé. Une exécution **réelle** peut faire les trois, et c’est pourquoi en lancer une demande un droit de développeur et pourquoi chacun de ses effets est enregistré. Lire un essai te dit si le graphe et le flux de données sont justes. Seule une exécution réelle te dit si les systèmes extérieurs se sont comportés comme tu le pensais. ## Lire une exécution Ouvre une exécution et tu obtiens le canvas de l’automatisation avec cette exécution peinte dessus, plus les faits propres à l’exécution autour : la version, le mode, l’heure de départ et l’heure de fin. ### Résultats par nœud Chaque boîte du canvas porte le statut que l’exécution lui a donné — **Exécuté**, **Ignoré**, **En échec**, **Jamais atteint**, ou **Pas encore atteint** tant que l’exécution continue. Un échec est donc une position dans le graphe plutôt qu’une ligne à chercher, et les nœuds en aval montrent clairement qu’ils n’ont jamais été atteints. Sélectionne un nœud et le panneau montre ce qui lui est arrivé : l’**Entrée résolue** qu’il a réellement reçue une fois tous les templates évalués, et sa **Sortie**. L’entrée résolue est le champ le plus utile de cette page. Elle montre la valeur qu’une référence a produite plutôt que la référence que tu as écrite, et c’est ainsi qu’on attrape un template qui s’est résolu en silence vers rien. Les nœuds ignorés méritent d’être lus plutôt que survolés, car la raison diffère : un nœud peut être ignoré par sa propre condition, parce qu’un nœud dont il dépend a été ignoré, parce qu’il est la branche « sinon » d’un nœud qui s’est exécuté, ou parce qu’il a échoué sous un réglage qui laisse l’exécution continuer. ### Effets Une exécution conserve aussi la liste ordonnée de tout ce qu’elle a changé hors de la plateforme — chaque entrée nommant le nœud responsable, l’connector appelée et l’entrée avec laquelle elle a été appelée. Une exécution qui n’a rien changé hors de la plateforme le dit explicitement, et c’est une vraie réponse plutôt qu’une section vide. La liste des effets est ce qui rend une exécution vérifiable après coup. Quand quelqu’un demande si un message est vraiment parti, c’est cette liste qui répond, et elle reste attachée à l’exécution en permanence. ## Pourquoi une longue exécution ne se répète pas Une exécution réelle ne se déroule pas d’un seul tenant. Elle avance nœud par nœud, et chaque nœud terminé est enregistré comme point de reprise avant que le suivant ne commence : quand l’exécution atteint la fenêtre de temps de la plateforme, elle se rend la main et repart du dernier nœud terminé. Un nœud déjà exécuté n’est jamais atteint une seconde fois, et c’est ce qui empêche une exécution interrompue d’envoyer deux fois le même message. Ces mêmes points de reprise couvrent une exécution dont la continuation a été perdue. Une exécution restée dans un état non terminal au-delà d’un délai de grâce est reprise automatiquement et continue là où ses points de reprise la situent, plutôt que de redémarrer ou de rester inachevée pour toujours. ## Une séance de débogage jouée de bout en bout La relance quotidienne n’est pas partie. Ouvre l’automatisation et regarde la liste **Exécutions** : celle de ce matin est là et elle est **En échec**, avec sa raison sur la ligne. Ouvre-la. Le canvas montre les trois premiers nœuds comme exécutés, le quatrième en échec, et tout ce qui suit comme jamais atteint : la question est déjà réduite à une boîte. Sélectionne le nœud en échec et lis son **Entrée résolue** : le nom du client est là, l’id de facture est une chaîne vide. Cela renvoie un nœud plus haut. Sélectionne ce nœud en amont et lis sa sortie. Il a retourné un enregistrement sans champ `id`, parce que le champ qu’il lisait avait été renommé. Le template qui le référençait s’est résolu vers rien, et le nœud en aval a échoué sur la valeur vide plutôt que sur quoi que ce soit qui lui soit propre. <Tip> Lis la liste des effets avant de corriger quoi que ce soit. Elle te dit si l’exécution est allée assez loin pour toucher le monde extérieur, ce qui décide si relancer est sans risque ou demande d’abord un nettoyage. </Tip> Corrige la référence dans le panneau du nœud, enregistre une version avec une note nommant le champ renommé, et appuie sur **Essai**. L’essai parcourt le même graphe et cette fois chaque boîte apparaît comme exécutée. Mets cette version en service, et la planification de demain la reprendra. ## Arrêter une exécution Tant qu’une exécution n’est pas terminée, tu peux l’arrêter, et une exécution arrêtée est définitive : le moteur vérifie à chaque frontière de nœud et cesse de planifier le suivant. Ce qui a déjà été fait n’est pas annulé, parce que cela ne peut pas l’être : un message envoyé est envoyé. Lis la liste des effets pour voir jusqu’où elle est allée avant de décider de la suite. ## Où cela s’inscrit Une exécution est le reçu que laisse une automatisation : son statut dit ce qui s’est passé, ses résultats par nœud disent où, ses entrées résolues disent pourquoi, et ses effets disent ce qu’elle a changé hors de la plateforme. Associe cette page à [Déclencheurs de workflow](/fr/platform/automations/triggers) pour les sortes de lancement qui ouvrent ces enregistrements, et aux [journaux d’audit](/fr/platform/admin/governance/audit-logs) pour la trace, à l’échelle de l’organisation, de qui a changé quoi. # Concepts d’automatisation Source: https://tale.dev/docs/fr/platform/automations/concepts Une automatisation, c’est un document de workflow enregistré sous un nom, plus tout ce que la plateforme conserve autour : l’historique des versions de ce document, la seule version en service, les déclencheurs autorisés à la lancer, et la trace de chaque exécution. Ouvre **Automatisations** dans la barre latérale et chaque ligne est l’un de ces noms, avec à côté la version en service. Trois idées de cette page commandent tout le reste — les versions ne changent jamais, la mise en service est un geste distinct, et un déclencheur se rattache au nom plutôt qu’à une version —, alors lis-les avant de construire quoi que ce soit. Tu préfères regarder d’abord ? L’épisode 5 ouvre l’automatisation de triage de bout en bout et décide une vraie carte de validation à l’écran, sous-titres compris. <Video src="/videos/fr/tutorials/ep5-automations/ep5-automations.fr.mp4" poster="/videos/fr/tutorials/ep5-automations/ep5-automations.fr.webp" captions="/videos/fr/tutorials/ep5-automations/ep5-automations.fr.vtt" lang="fr" title="Épisode 5 — Automatisations & validations" caption="Épisode 5 — Automatisations & validations (2:34)"> </Video> ## Le document de workflow Tout ce que fait une automatisation est déclaré dans un seul document. Son `name` est aussi son identité — des segments de slug en minuscules, séparés par des tirets, où `/` regroupe en dossiers les automatisations voisines, comme `billing/dunning-reminder`. Autour du nom viennent une `description`, un schéma JSON `inputs` qui décrit l’entrée d’exécution, les `nodes` qui font le travail, un `output` qui est la valeur de retour, et les `tests` qui décident si une version peut être mise en service. ```yaml name: billing/dunning-reminder description: Relancer un client sur une facture en retard. inputs: type: object properties: invoiceId: { type: string } required: [invoiceId] nodes: - id: invoice type: transform input: id: '{{ input.invoiceId }}' code: 'return { id: input.id, daysLate: 14 };' - id: message type: llm model: openai/gpt-4o-mini prompt: 'Rédige une relance polie pour la facture {{ nodes.invoice.output.id }}.' output: text: '{{ nodes.message.output.text }}' tests: - name: rédige une relance input: { invoiceId: 'inv-1' } ``` Les positions sur le canvas voyagent dans un bloc `ui` que le moteur ignore : déplacer une boîte ne change donc jamais le comportement. ### Les liaisons se déduisent, elles ne se déclarent pas Il n’y a pas de liste de liaisons. Un nœud en lit un autre en le référençant — `{{ nodes.invoice.output.id }}` — et cette référence _est_ la liaison que trace le canvas. L’ordre d’exécution est un tri topologique sur ces liaisons déduites : supprimer une référence retire donc aussi une flèche, et deux nœuds qui se lisent l’un l’autre sont refusés comme une boucle. Les templates utilisent une seule grammaire `{{ }}` d’expressions JavaScript sur `input`, `nodes.<id>.output` et, à l’intérieur d’un nœud qui itère, `item` et `index`. ### Le contrôle du flux vit sur le nœud Brancher et répéter sont des champs du nœud plutôt que des types d’étape à part. Le canvas les montre donc comme des badges sur la boîte qu’ils concernent. | Champ | Ce qu’il fait | | ---------------------------- | --------------------------------------------------------------------------------------------- | | `when` | N’exécute le nœud que si l’expression est vraie ; ses dépendants sont ignorés avec lui | | `elseOf` | S’exécute exactement quand le nœud nommé a été ignoré par son propre `when` | | `forEach` | S’exécute une fois par élément d’une collection, avec `item` et `index` disponibles | | `repeatUntil` / `maxRepeats` | Relance jusqu’à ce que l’expression soit vraie, avec un plafond (5 par défaut, 20 au maximum) | | `onError` | `fail` arrête l’exécution ; `continue` note l’erreur et ignore les dépendants | ### Les types de nœud Trois types sont intégrés, et chaque action d’connector comme chaque capacité native de la plateforme — recherche dans les connaissances, opérations sur documents — rejoint la même table à côté d’eux. **`transform`** exécute du JavaScript pur pour remettre des données en forme. Sans réseau ni imports : le corps lit l’`input` résolue du nœud et doit retourner une valeur. **`llm`** appelle un modèle de langage avec un prompt en template. `model` est obligatoire et toujours explicite — une automatisation n’en choisit jamais un à ta place (l’Auto du composer est une affaire de chat, et de chat seulement). La sortie est `{text}`, ou l’objet à la forme du schéma quand le nœud déclare un `outputSchema`. **`subworkflow`** exécute une autre automatisation enregistrée comme un seul nœud, référencée en `"name"` ou `"name@version"`. Sans version, c’est celle en service, et l’imbrication s’arrête à trois niveaux. ### Sortie structurée et non structurée La sortie de chaque type de nœud est de l’une des deux sortes, et c’est là que les auteurs trébuchent le plus. Une sortie **structurée** est une forme typée dans laquelle tu peux descendre avec `nodes.<id>.output.<field>`. Une sortie **non structurée** est du texte libre : seul `nodes.<id>.output.text` existe, et uniquement en contexte texte. Un outil qui ne déclare aucun schéma de sortie est non structuré par définition, et le seul pont prévu du texte vers des données structurées est un nœud `llm` avec un `outputSchema`. La validation refuse l’erreur au lieu de la laisser surgir à l’exécution, et chaque message porte un code lisible par une machine ainsi qu’une indication de ce qui est réellement disponible. Lire cette indication, c’est la façon de retrouver la forme que tu voulais référencer. ## Les versions ne changent jamais Enregistrer ajoute une version ; cela n’en modifie jamais une existante. Les versions sont numérotées à partir de 1 et restent contiguës par automatisation, et chacune porte la note que son auteur a écrite sur ce qui a changé. La version 3 d’une automatisation est donc le même document pour toujours. Deux conséquences. Modifier une automatisation ne peut pas perturber ce qui tourne déjà, puisque la version qui tourne est une autre ligne. Et une exécution tombée en échec le mois dernier se relit contre exactement le document qui l’a produite, puisque ce document existe encore, intact. ## La mise en service est un geste distinct Une seule version par automatisation est en service, et c’est celle que lancent les déclencheurs. Mettre une version en service, ou revenir à une plus ancienne, est un geste unique qui ne réécrit aucun historique : la liste des versions reste exactement telle quelle, seul le pointeur bouge. Une automatisation peut aussi n’avoir aucune version en service et vivre uniquement à l’état de brouillon. Une version ne devient éligible qu’une fois ses propres tests réussis. Les tests sont rangés dans le document : chacun porte un nom, une entrée, et des attentes sur la sortie comme sur les effets que l’exécution doit produire. Le résultat des tests d’une version est consigné au moment de l’enregistrement, si bien que la mise en service lit ce fait consigné au lieu de rejouer la suite. <Note> Une automatisation sans version en service ne peut pas être lancée du tout — ni par un déclencheur, ni à la main. Enregistre une version, puis mets-la en service. </Note> ## Ce qui lance une exécution Un déclencheur dit ce qui a le droit de lancer une automatisation, et il en existe exactement trois sortes : un **schedule** (une expression cron lue dans un fuseau IANA nommé), un **webhook** (une URL entrante protégée par un token) et un **event** (le nom d’un événement de la plateforme). Un déclencheur se rattache au **nom** de l’automatisation, jamais à une version. Mettre une nouvelle version en service n’invalide donc jamais une URL de webhook dont dépend un système externe, et ne fait jamais disparaître une planification sur laquelle quelqu’un compte. Chaque déclencheur s’éteint et se rallume sans être perdu, et chacun retient la dernière fois que le planificateur a agi dessus. [Déclencheurs de workflow](/fr/platform/automations/triggers) détaille ce que chaque sorte emporte dans l’exécution. ## Ce qu’une exécution enregistre Une exécution est un objet durable, pas une ligne de log. Elle retient son statut — `queued`, `running`, `waiting`, `success`, `failed` ou `cancelled` —, son mode, ce qui l’a lancée, l’entrée reçue, la sortie produite, et un **point de reprise pour chaque nœud terminé**. Ces points de reprise sont l’essentiel. Une exécution réelle avance nœud par nœud, et quand elle atteint la fenêtre de temps de la plateforme, elle se rend la main et reprend au dernier nœud terminé au lieu de refaire des effets déjà produits. Une exécution conserve aussi la trace complète du moteur et la liste ordonnée des effets qu’elle a produits — c’est ce qui permet au canvas de la rejouer et ce qui garde vérifiable après coup chaque changement hors de la plateforme. Les exécutions ont deux modes. **Essai** ne touche jamais l’extérieur et c’est la boucle de retour rapide pendant que tu construis. **Réel** peut y toucher, et c’est pourquoi en lancer une demande un droit de développeur. [Journaux d’exécution](/fr/platform/automations/execution-logs) lit une exécution de bout en bout. ## Là où un humain décide Une exécution qui a besoin d’une validation ne tombe pas en échec et ne repart pas de zéro. Elle se met en pause au statut `waiting`, et dès que la validation est répondue, elle repart exactement au nœud où elle s’était arrêtée en emportant la réponse. Une exécution qui attend une saisie humaine se comporte pareil. [Approbations dans les workflows](/fr/platform/automations/approvals-in-workflows) couvre ces portes et ce que chaque décision laisse derrière elle. ## Choisir la bonne unité | Choisis … | Automatisation | Agent | Webhook d’agent | | --------------------------------------------------------------------------- | -------------- | ----- | --------------- | | Un travail à plusieurs étapes, avec branches, planifications ou validations | ✓ | | | | Quelque chose qui doit tourner à l’heure ou répondre à un webhook | ✓ | | | | Une question qui revient dans le chat, sans système externe en jeu | | ✓ | | | Une réponse d’agent par POST entrant | | | ✓ | Vérifie le catalogue avant de construire — l’automatisation dont tu as besoin est peut-être déjà livrée. Un [déclencheur webhook](/fr/platform/automations/triggers) est la couture entrante ; recours-y quand une charge utile externe doit lancer une exécution. ## Mettre le modèle en pratique Une automatisation est un document, tenu comme une chaîne ininterrompue de versions dont une seule est en service, avec des déclencheurs rattachés à son nom plutôt qu’à une version — et c’est précisément ce qui rend la modification sûre, le retour arrière bon marché et une exécution en échec reproductible. [L’éditeur de workflow](/fr/platform/automations/editor) est le manuel pratique pour enregistrer, tester, mettre en service et revenir en arrière ; [Parcourir et installer des automatisations](/fr/platform/automations/catalog) mène à celles qui sont déjà livrées. # Approbations dans les workflows Source: https://tale.dev/docs/fr/platform/automations/approvals-in-workflows Les workflows s’exécutent sans toi, mais ils ne changent et ne démarrent qu’avec toi. Trois portes humaines entourent chaque workflow : les modifications de l’éditeur IA sur une définition ne s’appliquent qu’après ton approbation, un agent qui veut exécuter un workflow a d’abord besoin de ton accord, et une exécution qui rencontre une question se met en pause jusqu’à ce que quelqu’un réponde. Cette page couvre les trois portes ; l’histoire à l’échelle de l’org de ce qu’est une carte d’approbation vit sur [Concepts d’approbation](/fr/platform/approvals/concepts). <Frame caption="Le canvas d’une automatisation avec son panneau latéral — une modification proposée arrive comme carte d’approbation et ne touche jamais le document en silence."> ![Le canvas de workflow d’une automatisation montrant un graphe de nœuds, avec un panneau ouvert à côté.](/images/platform/automation-editor-canvas.webp) </Frame> ## Approuver les modifications d’une définition Demande à l’assistant de construire ou de retravailler une automatisation et sa proposition arrive comme une carte plutôt que comme un changement. La carte nomme ce qu’elle ferait — créer une nouvelle automatisation, corriger un seul nœud, ou remplacer le document entier — et tient jusqu’à ta décision. Approuve-la et le résultat est enregistré comme une nouvelle version, exactement comme un enregistrement manuel : le document que tu regardais reste intact, et la version en service le reste jusqu’à ce que quelqu’un en mette une autre en service. Annuler écarte la proposition, et rien n’atteint le document tant que la carte est en attente. ## Approuver une exécution Un agent en chat qui détient les outils d’automatisation peut demander à en lancer une. La demande arrive comme une carte nommant l’automatisation, et tu peux la déplier pour inspecter l’entrée exacte avec laquelle elle s’exécuterait avant de décider. Après approbation, la même carte suit l’exécution en direct — sur quel nœud elle se trouve, depuis combien de temps elle tourne et comment elle s’est terminée — et te laisse l’arrêter en vol ou ouvrir l’exécution elle-même pour le détail complet par nœud. <Note> Le chat se met en pause tant qu’une demande est en attente, et il te le dit. Décide la carte avant d’envoyer le message suivant. </Note> ## Répondre à une exécution en pause Une exécution qui a besoin d’une réponse humaine prend le statut **En attente** dans la [liste des exécutions](/fr/platform/automations/execution-logs) et s’y arrête. La question arrive comme une carte-formulaire — remplis-la et envoie-la, ou réplique en texte libre quand le formulaire ne demande pas la bonne chose. Répondre ne relance rien : l’exécution repart au nœud où elle s’était arrêtée, emporte ta réponse comme entrée de ce nœud, et termine le reste du graphe. Chaque nœud déjà terminé le reste, donc rien de ce qu’elle avait fait avant la pause n’arrive deux fois. ## Ce que chaque décision laisse derrière elle Chaque porte traverse la même poignée d’états sur la carte elle-même — en attente, puis en cours d’application, puis terminée ou rejetée —, et la décision atterrit dans le [journal d’audit](/fr/platform/admin/governance/audit-logs) avec l’acteur et l’horodatage. Une carte résolue ne peut pas être rouverte ; pour retenter une exécution rejetée, redemande et décide la carte neuve. Une approbation qui a lancé une exécution laisse cette exécution derrière elle comme enregistrement propre : ce que la décision a réellement provoqué reste donc lisible dans la [liste des exécutions](/fr/platform/automations/execution-logs) longtemps après la disparition de la carte. ## Où cela s’inscrit Ces portes sont la face côté workflow d’un motif qui traverse tout le produit : un agent propose, un humain dispose. [Concepts d’approbation](/fr/platform/approvals/concepts) nomme chaque type de carte au-delà des workflows — écritures de documents, écritures de connaissances, appels d’connector — et [Configurer les approbations](/fr/platform/approvals/configure) montre où les exigences sont déclarées. # Assistant d’automatisation Source: https://tale.dev/docs/fr/platform/automations/assistant L’**Assistant d’automatisation** est l’agent de chat rattaché à une seule automatisation, et il répond avec déjà en contexte son document, ses agents, ses compétences et ses connectors. Les Admins et Développeurs s’en servent pour comprendre une automatisation qu’ils n’ont pas construite, en étendre une plutôt que la dupliquer, ou se faire aider à rédiger les pièces que la page de l’automatisation ne modifie pas. Demande-lui ce que fait quelque chose avant d’y toucher à la main : il lit le document entier d’un coup plutôt qu’un nœud à la fois. ## Ce qu’il modifie directement Le document de l’automatisation est la seule pièce à laquelle l’assistant a un accès outil complet : il lit la version courante, modifie des nœuds, valide le résultat, enregistre une nouvelle version et la lance contre des simulations — les mêmes gestes que tu ferais à la main, dans le même ordre. Il travaille sous les mêmes règles que toi : un enregistrement ajoute une version au lieu d’en modifier une, et la version en service le reste jusqu’à ce que quelqu’un en mette une autre en service. Les agents viennent juste après : il lit le roster et peut en installer, activer ou désactiver un, mais les instructions, le modèle et le reste de la configuration d’un agent restent à modifier par toi dans l’éditeur d’agent, l’assistant rédigeant le JSON exact que tu colles. ## Ce qu’il rédige à ta place Les compétences, les connectors et les vues intégrées n’ont aucun outil d’édition : l’assistant écrit la définition selon la compétence d’écriture correspondante et te dit exactement où l’appliquer — Paramètres > Connectors pour un identifiant, la page de l’automatisation elle-même pour une vue. Installer et configurer fonctionnent pareil : il parcourt la checklist de préparation en nommant ce qui reste à connecter et ce qui reste à activer, plutôt que de faire la connexion lui-même. La même frontière vaut pour les déclencheurs. L’assistant peut te dire quelle planification, quel webhook ou quel événement porte une automatisation comme déclencheur et ce que chacun enverrait dans une exécution, et il peut te rédiger celui que tu veux — mais la décision d’exposer une automatisation au monde extérieur reste humaine. [Déclencheurs d’automatisation](/fr/platform/automations/triggers) couvre ce que fait chaque sorte. ## Trouver ce qui existe déjà Avant de construire quoi que ce soit, l’assistant cherche une automatisation ou un bundle à étendre plutôt qu’à dupliquer — la même règle de réutilisation d’abord que toute compétence d’écriture impose. Sa recherche atteint des automatisations que le catalogue lui-même cache : les membres cachés d’un bundle (voir [Concepts d’automatisation](/fr/platform/automations/concepts)) restent visibles pour l’assistant, qui peut donc te pointer vers, disons, l’agent PR Creator enfoui dans Résoudre les issues GitHub plutôt que d’en proposer un nouveau. ## Où cela s’inscrit L’Assistant d’automatisation est le chemin le plus rapide vers une automatisation que tu n’as pas construite toi-même — demande-lui ce que fait quelque chose avant d’y toucher à la main. [Concepts d’automatisation](/fr/platform/automations/concepts) est le vocabulaire qu’il présuppose ; [Parcourir et installer des automatisations](/fr/platform/automations/catalog) est l’endroit où agir sur ce qu’il te dit si l’automatisation n’est pas encore installée. # Page de statut Source: https://tale.dev/docs/fr/develop/status-page La page de statut est le registre canonique de la disponibilité de Tale Cloud. Chaque service rotatif a sa propre ligne de statut, l'historique des incidents est conservé pour la piste d'audit, et la page est le canal que Tale utilise pendant un incident — avant que les courriels ne partent, avant que les tickets de support ne soient répondus, la page est mise à jour. Lis ceci quand quelque chose se conduit mal et que tu veux savoir si c'est juste toi. Abonne-toi au flux quand tu es responsable de le connector côté toi — la page te dit quel service s'est dégradé pour que tu routes l'alerte vers la bonne équipe sans réveiller la mauvaise astreinte. ## Un abonnement mis en pratique La page de statut est à `https://status.tale.dev`. S'abonner prend une URL : ```bash curl -sS https://status.tale.dev/history.rss ``` Le flux RSS porte chaque changement d'état — ouvert, mise à jour, résolu — pour chaque service. L'abonnement par courriel est le même formulaire en un clic sur la page ; le canal courriel livre les mêmes événements avec un debounce de cinq minutes. ## Périmètre par service | Service | Ce qu'il couvre | Quand il passe au rouge | | ---------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | | `platform` | L'application TanStack Start + Convex — agents, workflows, connectors, UI. | UI injoignable ; l'API renvoie 5xx ; l'auth est cassée. | | `rag` | Le service Python FastAPI de traitement de documents — indexation, récupération. | Les téléversements de documents calent ; la récupération est vide. | | `crawler` | Le service d'extraction web Crawl4AI — utilisé par l'ingestion de documents et le repli Tavily. | Les documents tirés du web échouent ; la recherche profonde cale. | | `proxy` | Le bord Caddy — terminaison TLS, routage HTTP. | Tout le trafic Tale Cloud est touché. | | `db` | TimescaleDB — état durable pour la couche Convex et les métadonnées de la plateforme. | Écritures refusées ; la ligne platform passe aussi au rouge. | Chaque ligne porte les 90 derniers jours d'uptime comme un sparkline. Un incident se lit comme une bande colorée sur la ligne ; cliquer la bande ouvre le chronogramme — première mise à jour, suites, résolution, post-mortem quand l'incident en exige un. ## Historique des incidents L'historique est conservé indéfiniment. Chaque incident enregistre les services touchés, l'énoncé d'impact client, le chronogramme, et le post-mortem quand l'incident dépasse le seuil de sévérité qui en impose un. Le seuil est publié sur la page elle-même ; la règle empirique est tout ce qui a un impact client cross-org et une durée au-dessus de 30 minutes. La page appartient à la rotation d'astreinte. Les mises à jour sont poussées par l'ingénieur qui tient la page, pas par un système automatisé — le choix est délibéré, parce que la page est aussi le document qui va aux clients et aux auditeurs après coup. ## Auto-hébergé : ce qui change Les instances auto-hébergées n'apparaissent pas sur `status.tale.dev` — cette page couvre Tale Cloud. Chaque déploiement embarque sa propre page de statut à la place, servie par la plateforme et accessible sans connexion à `https://<ton-hôte>/status`. Elle rend côté serveur un résumé de santé — operational, degraded ou outage — à partir d'une sonde de liveness contre le backend Convex, si bien qu'un opérateur (ou un utilisateur qui vérifie si le souci ne vient que de lui) peut lire la disponibilité sans se connecter. La forme lisible par machine est `https://<ton-hôte>/status.json`, qui renvoie le même résultat en JSON qu'un moniteur d'uptime peut interroger. Cette page rapporte la disponibilité du déploiement lui-même. Pour un signal d'exploitation plus fin — santé des conteneurs depuis `tale status`, métriques de requêtes depuis les journaux Caddy, et événements du plan de contrôle dans le journal d'audit du produit — la [page de dépannage observabilité](/fr/self-hosted/operate/observability/troubleshooting) associe les symptômes aux journaux. ## Où cela s'inscrit La page de statut est le canal opérationnel ; [Confiance et conformité](/fr/cloud/trust-and-compliance) est le canal d'audit et liste la page comme preuve du contrôle de disponibilité d'infrastructure. Si tu câbles Tale dans un pipeline et veux que le connector réagisse à une panne Tale, le flux RSS est l'entrée ; si tu lis ceci parce que quelque chose dans ton connector échoue maintenant, la [Référence API](/fr/develop/api-reference) liste les codes d'erreur sur lesquels tu dois brancher. # Configuration contributeur Source: https://tale.dev/docs/fr/develop/contributor-setup Cette page est pour les contributeurs qui veulent faire tourner Tale depuis le code source et renvoyer une modification. Elle couvre les prérequis, la mise en place unique, la vérification pré-vol qui détecte une machine cassée avant un long démarrage, et ce que tu peux attendre de `bun run dev`. Ce n'est pas le chemin de l'opérateur — si tu veux faire tourner Tale pour l'utiliser, pas le modifier, le [démarrage rapide auto-hébergé](/fr/self-hosted/install/quickstart) installe la stack empaquetée avec la CLI à la place. Le code source est un seul workspace Bun, de bout en bout — toute la stack est TypeScript, sans Python ni second gestionnaire de paquets à installer. Un seul `bun install` câble chaque service, et `bun run dev` démarre la plateforme avec un backend Convex local, des secrets de dev générés et Vite — pas de compte cloud, pas de `.env` édité à la main. Le travail de connaissances qui vivait autrefois dans des services autonomes (recherche RAG, ingestion de documents, crawling web, génération de documents) tourne désormais dans le backend Convex, donc il n'y a rien de plus à démarrer pour lui. ## Une configuration qui marche, de bout en bout Le chemin le plus court d'un clone neuf à une app qui tourne fait quatre commandes. La vérification pré-vol entre install et dev est celle qui t'épargne un échec déroutant dix couches en profondeur : ```bash bun install # câbler chaque workspace bun run setup:check # valider Bun, les ports de dev et la CLI Convex bun run dev # démarrer Convex + Vite (guette la bannière READY) ``` Si `setup:check` affiche tout en vert et que `bun run dev` atteint sa bannière `READY`, ton environnement est sain. Le reste de cette page explique chaque pièce et quoi faire quand l'une d'elles se plaint. ## Prérequis Un seul outil doit être sur ton `PATH` avant tout le reste, parce que toute la stack est du TypeScript sur une seule runtime : - **Bun 1.3 ou plus** — la runtime de workspace et le gestionnaire de paquets. Installe-le depuis [bun.sh](https://bun.sh/docs/installation), puis confirme avec `bun --version`. Tout le reste dont le code source a besoin (la CLI Convex, chaque dépendance de service) est résolu par `bun install`. Tu n'as pas besoin de Docker pour le développement local avec `bun run dev` — il lance Convex directement sur ta machine. Docker n'entre en jeu que pour le mode hybride conteneurisé plus bas et pour l'installation de l'opérateur. ## Installation et pré-vol Une seule installation couvre chaque workspace, parce que le dépôt est un graphe de workspaces Bun unique : ```bash bun install ``` Avant le premier `bun run dev`, lance la vérification pré-vol. Elle valide ta version de Bun, que les ports 3000 et 3210 sont libres et que la CLI Convex est joignable — et imprime la correction exacte pour tout ce qui manque, pour que tu ne découvres pas une mauvaise version de Bun à mi-chemin d'un démarrage à froid : ```bash bun run setup:check ``` Chaque ligne en échec porte sa correction : un `bun upgrade` pour un vieux Bun, une paire `lsof`/`kill` pour un port occupé. Un passage propre se termine à zéro et te dit d'avancer avec `bun run dev`. ## Ce que fait `bun run dev` `bun run dev` est l'orchestrateur de développement. Il charge tes fichiers `.env`, génère des valeurs par défaut locales non sécurisées pour chaque secret que tu n'as pas réglé, lance un backend Convex local en mode anonyme, y synchronise l'environnement, exécute le codegen Convex, attend que les routes d'auth répondent, puis démarre Vite. La plateforme est le serveur le plus lent à monter parce qu'elle attend Convex, donc un démarrage à froid prend de 30 à 90 secondes. Tant que l'orchestrateur n'imprime pas sa bannière `READY`, le fait que l'app refuse les connexions sur `http://localhost:3000` est attendu, pas un échec — Vite n'a pas encore lié le port. Quand tu vois la bannière, l'app est joignable et l'auth est saine. Arrête toute la stack avec `Ctrl-C` ; elle ferme proprement Convex et Vite. L'orchestrateur de dev génère tout ce dont il a besoin, donc une copie locale de `.env.example` est optionnelle pour le développement local — les valeurs par défaut non sécurisées (`INSTANCE_SECRET`, `BETTER_AUTH_SECRET`, la clé HMAC WebDAV) sont remplies au démarrage et imprimées comme avertissements. Règle de vraies valeurs dans `services/platform/.env.local` seulement quand tu as besoin d'un comportement façonné pour la production ou veux surcharger une valeur par défaut. ## Quand un port est occupé `bun run dev` lie deux ports : 3000 pour l'app Vite et 3210 pour le backend Convex local. Il échoue tout de suite avec un message actionnable quand l'un est pris, parce qu'un repli silencieux vers un autre port casserait le proxy Convex et chaque lien `localhost:3000`. Le coupable habituel est un `bun run dev` ou `tale dev` précédent qui n'a pas complètement quitté. Libère le port et relance. La commande qui trouve et arrête le détenteur est celle que `setup:check` et l'orchestrateur suggèrent : ```bash lsof -nP -iTCP:3000 -sTCP:LISTEN # montrer la PID qui tient le port de l'app kill <PID> # l'arrêter ``` Pour faire tourner l'app sur un autre port à la place, règle `PORT` : `PORT=3005 bun run dev`. Si le déploiement Convex reste dans un mauvais état après la maintenance automatique — schéma périmé après migration avortée, SQLite locale corrompue — voir [Réinitialiser les données Convex de dev locales](#réinitialiser-les-données-convex-de-dev-locales) ci-dessous ; ne supprime pas `.convex/local/` à la légère. ## Maintenance du stockage Convex local Chaque push `convex dev` stocke un nouveau bundle de fonctions sous `services/platform/.convex/local/default/convex_local_storage/modules/`. La CLI Convex ne garbage-collecte jamais les anciens blobs en local — des mois de dev quotidien peuvent accumuler des dizaines de milliers de fichiers (10+ Go) et faire échouer les cold starts dans la fenêtre de 30 secondes de la CLI. `bun run dev` lance la maintenance automatiquement avant de spawner Convex : - **Prune** quand le stockage modules dépasse 1 500 blobs ou 2 Go — ne supprime que les blobs historiques non référencés sous `convex_local_storage/modules/`, en gardant chaque blob que le déploiement actuel charge encore (packages source des modules et leurs parents deps node via `externalPackageId`, plus jusqu'à 1 000 restes non référencés les plus récents). La base SQLite, les fichiers uploadés et la config org restent intacts. Si les références live ne peuvent pas être lues, ou semblent vides alors que des blobs restent sur disque, le prune est ignoré plutôt que de deviner. - **Contrôle d'intégrité** — si un blob de module live manque déjà sur disque, `bun run dev` s'arrête avec une erreur claire qui pointe vers `setup:clean`. Continuer démarrerait un backend à moitié mort (chat et crons échouent avec des erreurs serveur opaques). - **Supprime les artefacts d'export snapshot** quand la version binaire Convex en cache ne correspond plus à celle enregistrée dans le déploiement local — retire `export.zip` et les restes d'import/export qui peuvent déclencher un ré-import raté au cold start, sans effacer les données de dev. Règle `TALE_DEV_SKIP_CONVEX_MAINTENANCE=1` pour désactiver le prune/nettoyage snapshot (le contrôle d'intégrité tourne quand même). `bun run setup:check` avertit (sans bloquer) quand le stockage modules dépasse déjà le seuil de prune. ## Réinitialiser les données Convex de dev locales En dernier recours seulement — `bun run setup:clean` efface **toutes** les données Convex de dev locales : chaque table du SQLite local, chaque upload dans `convex_local_storage/files/`, chaque bundle de fonctions. La config org sur disque et `.env.local` restent intacts. **Traverser la baseline 0.4 :** les données de dev locales et les arborescences de config par org créées par des checkouts pré-0.4 n'ont aucun chemin de migration — la remise à zéro de la baseline 0.4 a vidé l'historique des migrations, et l'aller-retour export/import ci-dessous ne peut pas non plus faire le pont (l'ancien export ne correspond pas au nouveau schéma). Faire passer une machine de dev de l'autre côté de la baseline, c'est réinitialiser les données Convex locales et recréer tes orgs de dev ; traite les répertoires d'org `$TALE_CONFIG_DIR` pré-0.4 de la même façon. **Garde tes données à travers le reset.** Même quand la barrière d'intégrité se déclenche (le bundle d'un module actif manque), le backend lui-même démarre encore — tu peux donc exporter tes données avant et les restaurer après, et le reset ne perd alors rien : ```bash # 1. Démarre le backend (cela contourne la barrière d'intégrité de # `bun run dev`), puis exporte dans un second terminal : bun run --filter @tale/platform convex:dev cd services/platform && npx convex export --path convex-backup.zip # 2. Réinitialise (protégé — voir ci-dessous), bootstrappe un déploiement # neuf, puis restaure : bun run setup:clean # tape : delete local convex bun run dev # attends la bannière READY cd services/platform && npx convex import --replace-all convex-backup.zip ``` `bun run setup:clean` est volontairement protégé (les agents de code ne doivent pas l'exécuter sauf demande explicite de ta part) : 1. Lance-le toi-même dans un terminal — pas via un agent. 2. Au prompt, tape la phrase exacte `delete local convex` (un simple `y` est refusé). 3. Les exécutions non interactives (CI) exigent `TALE_CONFIRM_DESTROY_LOCAL_CONVEX=delete-local-convex` — ne jamais le définir dans les shells d'agents. Essaie d'abord la maintenance automatique et un `bun run dev` normal. S'il faut vraiment réinitialiser, **exporte d'abord** (ci-dessus) pour garder tes données — ne saute l'export que si tu n'as réellement pas besoin des conversations locales, des uploads et du reste de l'état du déploiement anonyme. ## Mode hybride contre un Convex conteneurisé `bun run dev` lance par défaut un backend Convex éphémère, ce qui est la bonne chose pour l'essentiel du travail. Quand tu veux des reloads Vite rapides contre un Convex stable qui reflète la production, fais tourner le conteneur `convex` dédié et pointe Vite vers lui à la place : ```bash docker compose up convex # un terminal : le backend stable CONVEX_EXTERNAL=true bun run dev # un autre : Vite contre le conteneur ``` Règle `CONVEX_URL` si ton conteneur expose Convex sur un hôte ou un port non standard. C'est le seul chemin de dev local qui a besoin de Docker, et il est optionnel — le backend éphémère par défaut n'a besoin de rien au-delà des trois prérequis. ## Avant d'ouvrir une PR Chaque PR passe par un gate : `bun run check`, c'est-à-dire format, lint, typecheck et la suite de tests complète sur chaque workspace touché. Un passage vert est le signal de merge ; un rouge bloque. La checklist pré-PR dans [`AGENTS.md`](https://github.com/tale-project/tale/blob/main/AGENTS.md) liste le reste — la doc et les traductions arrivent dans la même PR que le code qui les a modifiées. Si ta modification touche `services/docs/`, lance aussi le gate de la doc (`bun run --filter @tale/docs test`) pour que la parité structurelle, la terminologie et les vérifications de prose passent avant la revue. Tout ce qu'un utilisateur peut voir, configurer ou appeler a besoin de sa doc mise à jour dans les trois locales de base dans le même commit. ## Où cela s'inscrit La configuration contributeur est le sol sur lequel se tient chaque autre tâche de développeur : mets les prérequis en place, laisse `setup:check` confirmer la machine, et `bun run dev` te donne toute la plateforme avec un backend local en moins de deux minutes une fois les images chaudes. La vérification pré-vol et la correction de port existent parce que les échecs de premier passage les plus courants sont une mauvaise version d'outil ou un processus résiduel qui tient un port — deux corrections de cinq secondes une fois que tu peux les voir. Une fois la stack en marche, l'[aperçu Développement](/fr/develop/overview) cadre la surface externe contre laquelle tu construis, et [Développement assisté par IA](/fr/develop/ai-assisted-development) couvre l'usage des agents Tale pour écrire des configurations Tale. Si tu contribues une modification de conteneur plutôt qu'une modification de code source, [Contribuer](/fr/self-hosted/contributing-docker) sous l'onglet Auto-hébergé est le parcours build-and-test pour ce chemin. # Webhooks Source: https://tale.dev/docs/fr/develop/webhooks Un déclencheur webhook transforme un POST de ton système en exécution d'une automatisation déployée — pas de clé API, pas de SDK, juste une URL que Tale frappe quand tu lies le déclencheur. C'est la bonne couture quand l'appelant est un produit tiers — un prestataire de paiement, un outil de formulaires, un job CI — qui ne sait que tirer une requête HTTP sur une URL que tu lui donnes. Lis ceci quand tu câbles un système externe qui doit démarrer des automatisations. Pour les appels où tu veux une valeur en retour ou détiens une clé API, la [référence API](/fr/develop/api-reference) est la moitié synchrone. ## Un déclencheur, de bout en bout Lie un déclencheur webhook à une automatisation — dans l'éditeur de l'automatisation, ou avec `PUT /api/v1/automations/{name}/triggers` et `{"kind": "webhook"}` — et Tale répond une seule fois avec le jeton de l'URL. Ensuite, n'importe quel système démarre une exécution : ```bash curl -sS -X POST "https://your-host.example.com/api/automations/webhook/<token>" \ -H "Content-Type: application/json" \ -d '{ "orderId": "12345", "amount": 199.0 }' # → 202 { "runId": "..." } ``` Le corps devient l'entrée de l'exécution. Un corps qui n'est pas du JSON passe tel quel comme texte au lieu d'être refusé — certains fournisseurs envoient du texte brut — et tout ce qui dépasse 256 Ko est rejeté en **413**. Suis l'exécution comme n'importe quelle autre via `GET /api/v1/runs/{runId}` avec une clé API, ou regarde-la dans le produit. Le vocabulaire complet des réponses : - **202** `{ "runId": "..." }` — l'exécution a démarré. - **404** — jeton inconnu, désactivé ou mal tapé. La réponse ne distingue jamais les cas — qui devine n'apprend rien. - **409** `{ "error": "automation has no deployed version" }` — déploie une version dont les tests passent et le même appel s'exécute. - **413** — le corps dépasse 256 Ko. ## Le jeton est l'identifiant Pas de signature, pas de header Authorization : le jeton dans l'URL est tout l'identifiant — traite l'URL comme un mot de passe. Tale n'en stocke qu'un hachage et compare en temps constant ; le texte en clair existe exactement une fois, dans la réponse qui l'a frappé. URL perdue ou fuitée ? Fais-la tourner — `PUT /api/v1/automations/{name}/triggers` avec `{"kind": "webhook", "rotateToken": true}` frappe un jeton neuf et le répond une fois ; l'ancienne URL meurt aussitôt. Délier le déclencheur (`DELETE .../triggers`, ou dans l'éditeur) la révoque entièrement ; les versions et l'historique d'exécution de l'automatisation restent. ## Idempotence et relances L'endpoint de déclenchement ne déduplique pas : un POST rejoué démarre une seconde exécution. Ce qui rend les relances sûres, c'est l'exécution elle-même — une exécution live pose un checkpoint à chaque nœud terminé, donc une exécution qui reprend après une interruption ne répète jamais un effet déjà produit. Là où une _exécution en double_ resterait fausse, mets ta propre clé de déduplication dans la charge utile et branche dessus dans le premier nœud de l'automatisation. Relancer est la responsabilité de l'appelant : la réponse te dit si l'exécution a _démarré_, pas si elle a réussi. Un appelant raisonnable rejoue les réponses non-2xx avec backoff et considère 202 comme acquis. ## Où ça se place Le webhook est l'entrée sans clé ; tout le reste passe par une clé API. La [page Déclencheurs](/fr/platform/automations/triggers) couvre le côté produit — plannings, événements et webhooks tels que l'éditeur d'automatisation les présente. La [référence API](/fr/develop/api-reference) couvre le démarrage d'exécutions avec clé (`POST /api/v1/automations/{name}/runs`) — la meilleure couture quand l'appelant est ton propre code. # Limites de débit Source: https://tale.dev/docs/fr/develop/rate-limits L'API est limitée par clé avec des token buckets : les rafales passent, le martèlement continu répond **429**. Les budgets sont taillés pour qu'une connector normale ne les voie jamais — quand un client jusque-là sain se met à recevoir des 429, la cause est presque toujours un backoff manquant ou une boucle chaude, pas un manque de capacité. Lis ceci quand tu câbles un client qui appelle l'API sur un planning ou sous charge. ## Les buckets | Surface | Budget | Rafale | | -------------------------------------------------------------------------------------------------------- | ------------------ | ------ | | Lectures et CRUD — chaque endpoint `/api/v1` absent de la ligne du dessous, y compris `POST /api/v1/mcp` | 120 requêtes / min | 200 | | Démarrer du travail — `POST /api/v1/automations/{name}/runs` et `POST /api/v1/threads/{id}/messages` | 20 requêtes / min | 40 | Le second bucket est petit à dessein : chacune de ces requêtes coûte une exécution durable entière ou un tour de modèle, pas une lecture de base. Un token bucket se remplit en continu — la capacité de rafale absorbe un lot, puis le débit soutenu s'applique. ## La 429 Un dépassement répond avec l'enveloppe d'erreur ordinaire de l'API — rien à parser au-delà du statut : ```json { "error": "Rate limit exceeded" } ``` Il n'y a pas de headers de limite — pas de `Retry-After`, pas de compteurs de budget restant. Recule à l'aveugle : commence à une seconde, double à chaque 429 consécutif, plafonne à soixante, et ajoute du jitter pour que des workers parallèles ne relancent pas au pas. Comme démarrer une exécution répond **202** avant que le travail n'ait lieu, une réponse perdue se détecte à bas prix — liste les dernières exécutions de l'automatisation avant de tirer à nouveau, plutôt que de rejouer des écritures au soupçon. ## Où ça se place La [référence API](/fr/develop/api-reference) nomme la 429 dans le modèle d'erreur et pointe ici. Si ta charge a vraiment besoin de plus que les budgets, regroupe de ton côté — `POST /api/v1/contacts/bulk` existe exactement pour ça — ou étale le planning ; les buckets valent par clé, deux clés ne partagent donc pas un budget. # Connectors Source: https://tale.dev/docs/fr/develop/connectors Les connecteurs sont la moitié propre aux fournisseurs de la façon dont Tale atteint d’autres systèmes, et ils font partie de la plateforme plutôt que d’un assemblage à la charge d’une organisation. Chacun est un fichier YAML dans l’arbre des sources qui déclare à qui il parle, comment il s’authentifie et chaque action qu’il sait exécuter — d’où un catalogue identique dans tous les déploiements, qu’une mise à jour suffit à faire avancer. Lis cette page pour savoir ce qu’un connecteur promet réellement à un appelant, ou quand tu hésites entre contribuer un connecteur et héberger un serveur MCP. Le versant organisation — ajouter des identifiants, choisir celui par défaut, relancer une autorisation expirée — est [Identifiants d’connector](/fr/platform/admin/connectors), et le catalogue lui-même est [Connectors](/fr/platform/connectors/overview). ## Comment un connecteur est déclaré Chaque connecteur est un répertoire sous `configs/platform/system/connectors/`, nommé d’après son slug, contenant un `connector.yml` et l’icône que la page de paramètres affiche. Le slug est à la fois le nom du répertoire, le `name` déclaré du connecteur et la première moitié du type de nœud avec lequel une automatisation pose une de ses actions — `<connector>.<action>`. Treize de ces répertoires sont livrés aujourd’hui. Le fichier s’ouvre sur l’identité du connecteur et son contrat d’authentification, puis énumère les actions : ```yaml name: tavily displayName: Tavily description: Real-time web search and page extraction for AI research. tags: - Search allowedHosts: - api.tavily.com auth: - method: api-key actions: - name: search description: >- Search the open web via Tavily. Returns top results with title, URL, content snippet, and score. effects: read input: type: object required: [query] properties: query: { type: string, description: 'Natural-language search query.' } max_results: { type: number, description: 'Max results (1-10).' } output: '{ answer?: string, results: Array<{ title: string, url: string, content: string, score: number }> }' ``` `allowedHosts` est la frontière de sortie — un corps d’action qui viserait ailleurs est refusé plutôt que relayé. Un connecteur dont l’API vit chez le client plutôt que chez le fournisseur ajoute `endpointMode: per-credential`, et chaque identifiant porte alors l’origine à partir de laquelle ses appels sont construits ; Confluence et Shopify sont les deux cas livrés. <Info> Les connecteurs sont lus dans l’arbre de la plateforme, pas dans la configuration d’une organisation, et aucun chemin de téléversement n’en ajoute à l’exécution. Ajouter un connecteur est une contribution au code source — voir [Configuration du contributeur](/fr/develop/contributor-setup). Héberger ton propre pont sans toucher aux sources, c’est précisément ce à quoi sert MCP. </Info> ## Ce qu’une action déclare Une action est un contrat, et chacun de ses champs est visible pour l’appelant avant que l’appel n’ait lieu : - **Nom et description.** Le nom complète le type de nœud ; la description est ce que lit un agent quand il décide si cette action est la bonne. - **Entrée.** Un JSON Schema — type objet, champs obligatoires et une description par propriété. Les automatisations valident la configuration d’un nœud contre lui, et les agents la remplissent à partir du même schéma. - **Sortie.** Une signature décrivant la forme qui revient, pour que l’auteur d’un workflow sache ce que l’étape suivante peut référencer. - **Effets.** Soit `read`, soit `write`. Les actions en écriture passent par la politique d’approbation de l’organisation, et un appel qui n’atteint aucune décision d’approbation est refusé plutôt qu’exécuté sans contrôle. Les actions résolvent leur identifiant au moment de l’appel : celui que l’appelant nomme, ou celui par défaut du connecteur quand il n’en nomme aucun. C’est cette couture qui permet à la même automatisation de tourner sur un autre compte en la pointant vers un autre nom d’identifiant. La sync mail et le triage de boîte s’écartent volontairement de cette règle : `conversation.sync_mailbox` et `conversation.list_mailbox_messages` parcourent chaque identifiant actif du connecteur, pour couvrir chaque boîte connectée sans qu’une automatisation ait à les nommer une à une. ## Les méthodes d’authentification Un connecteur déclare les méthodes qu’il accepte, et un identifiant est enregistré sous exactement l’une d’elles. Les quatre sont fixes, parce que chacune décrit un chemin différent par lequel un secret atteint le fournisseur. | Méthode | Libellé dans l’interface | Ce que porte l’identifiant | | --------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | `api-key` | Clé API | Un secret unique que le corps de l’action place lui-même — un en-tête du fournisseur, un paramètre d’URL ou un champ du corps. | | `bearer` | Jeton | Un jeton envoyé dans l’en-tête Authorization, sous le schéma que le connecteur nomme. | | `basic` | Nom d’utilisateur et mot de passe | Un nom d’utilisateur et un mot de passe en HTTP Basic, la forme que prend aussi un login de boîte mail. | | `oauth2` | OAuth | Une autorisation par code : jeton d’accès, jeton de rafraîchissement, expiration et portées accordées. | Les secrets sont chiffrés au repos dans une seule enveloppe et ne ressortent jamais vers un appelant. Une liste affiche un aperçu masqué calculé à l’écriture de l’identifiant, si bien que lire la liste ne touche jamais au chiffré. ## Enregistrer une application OAuth Un connecteur `oauth2` déclare les URL d’autorisation et de jeton du fournisseur ainsi que les portées qu’il demande, et le déploiement fournit l’application contre laquelle ces URL s’authentifient. Enregistre exactement ce callback comme URI de redirection autorisée côté fournisseur, construit à partir du `SITE_URL` du déploiement et de son éventuel préfixe `BASE_PATH` : ```text ${SITE_URL}${BASE_PATH}/api/connectors/oauth2/callback ``` L’identifiant client et le secret de chaque connecteur viennent de l’environnement du déploiement, nommés par connecteur `CONNECTOR_OAUTH_<SLUG>_CLIENT_ID` et `CONNECTOR_OAUTH_<SLUG>_CLIENT_SECRET`, le slug en majuscules et ses tirets changés en tirets bas. Quand `SITE_URL` n’est pas défini, le consentement refuse de démarrer au lieu de deviner une origine à partir de la requête. <Warning> L’URI de redirection doit correspondre octet pour octet — schéma, hôte, chemin, et pas de barre oblique finale. Un écart échoue dès l’écran de consentement du fournisseur avec une erreur `redirect_uri`, avant même que Tale ne voie le callback ; c’est de loin la raison la plus fréquente pour laquelle un nouveau connecteur OAuth ne se connecte pas. </Warning> ## Choisir une surface Deux surfaces atteignent des systèmes hors de Tale, et le choix porte sur qui possède le pont et qui le fait tourner. | Surface | Prends-la quand | | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | Connector livré | Un connecteur existe déjà pour le système visé. Ton travail se limite aux identifiants, et le contrat fournisseur est maintenu pour toi. | | Serveur MCP | Rien de livré ne couvre le système — une API interne, un outil maison, un hôte que seul ton réseau atteint. Tu écris et fais tourner le processus. | Un serveur MCP s’enregistre sous **Paramètres > API > MCP**, et chaque outil qu’il expose rejoint la trousse de l’agent aux côtés des actions de connecteur, avec son propre drapeau d’approbation. La référence est [Serveurs MCP](/fr/platform/connectors/mcp-servers) ; la construction de bout en bout est [Monter un serveur MCP de zéro](/fr/tutorials/developer/mcp-server-from-scratch). ## Où cela s’inscrit Un connecteur est un contrat déclaré — hôtes, authentification et une liste d’actions typées — livré avec la plateforme et alimenté par des identifiants qui appartiennent à l’organisation. Lis [Connectors](/fr/platform/connectors/overview) pour ce que contient le catalogue, [Identifiants d’connector](/fr/platform/admin/connectors) pour la gestion quotidienne de ces identifiants, et [Serveurs MCP](/fr/platform/connectors/mcp-servers) quand le pont dont tu as besoin doit être ton propre code. </content> </invoke> # Référence API Source: https://tale.dev/docs/fr/develop/api-reference L'API de Tale est la surface des intégrateurs qui se tiennent hors du produit et veulent le scripter : ressources de connaissances, automatisations et leurs exécutions, threads de chat, agents et skills — le tout en JSON sur HTTPS, avec une clé API dans un header. La même clé ouvre aussi l'[endpoint MCP](/fr/develop/mcp-endpoint) — cette page couvre la moitié REST. Cette page est l'inventaire canonique de la surface, du modèle d'authentification et de la forme d'erreur. Les schémas de requête et de réponse champ par champ vivent dans le document OpenAPI que ton instance sert sous `/docs` — charge-le quand il te faut chaque propriété ; lis cette page pour comprendre comment l'API se comporte. ## Une première requête La requête utile la plus courte — lister les automatisations de l'organisation — tient dans un curl : ```bash curl -sS "https://your-host.example.com/api/v1/automations" \ -H "Authorization: Bearer $TALE_API_KEY" ``` Une réponse réussie est une page : `{ "page": [ { "name": "billing/dunning", "latest": 3, "deployedVersion": 2 } ], "isDone": true, "continueCursor": null }`. Chaque endpoint de liste répond avec cette même enveloppe — renvoie `continueCursor` en `?cursor=` pour la page suivante, et borne la taille avec `?limit=`. ## Authentification Les clés API se créent dans le produit par toute personne avec les permissions Admin ou Développeur — [Clés API](/fr/platform/admin/api-keys) décrit le panneau. Une clé s'affiche une seule fois à la création, jamais ensuite ; elle appartient à la personne qui l'a créée et à son organisation. Passe la clé en bearer token : `Authorization: Bearer <key>`. Le contexte d'organisation vient de la clé — inutilisable hors de son organisation, et tout ce qu'elle touche y reste. Ce que la clé _peut faire_ suit le rôle de son détenteur : lire et lancer en mock demandent l'appartenance ; démarrer du travail live et modifier ce qui est déployé demande la capacité développeur. Les sections ci-dessous le précisent là où ça compte. ## Groupes d'endpoints | Groupe | Chemin | Ce qu'il couvre | | -------------------------- | --------------------------------------- | ------------------------------------------------------------------------------------------------------- | | Automatisations | `/api/v1/automations/...` | Lister, lire les versions, démarrer des exécutions, lire l'historique, lier et délier les déclencheurs. | | Exécutions | `/api/v1/runs/{runId}` | Une exécution durable en entier — statut, sortie, trace, effets — plus `POST .../cancel`. | | Threads | `/api/v1/threads/...` | Les threads de chat du détenteur de la clé : créer, lire les messages, envoyer, suivre le tour. | | Agents | `/api/v1/agents/...` | Lister, lire, créer ou remplacer, supprimer les agents de l'organisation. | | Skills | `/api/v1/skills/...` | La même forme que les agents, pour les skills. | | Entrées de connaissances | `/api/v1/knowledge-entries/...` | Des faits par sujet : lister, créer, remplacer, supprimer. | | Recherche de connaissances | `POST /api/v1/knowledge/search` | Recherche sémantique sur les connaissances indexées de l'organisation. | | Documents | `/api/v1/documents/...` | Les documents de la base de connaissances : CRUD plus `POST .../retry-indexing`. | | Sites web | `/api/v1/websites/...` | Les sources crawlées : CRUD plus `.../pages`, `.../sync`, `.../search`. | | Produits | `/api/v1/products/...` | Les entrées du catalogue produit : CRUD. | | Contacts | `/api/v1/contacts/...` | Les fiches contact : CRUD plus `POST /api/v1/contacts/bulk`. | | MCP | `POST /api/v1/mcp` | L'[endpoint MCP](/fr/develop/mcp-endpoint) — même clé, JSON-RPC au lieu de REST. | | Déclencheur webhook | `POST /api/automations/webhook/<token>` | Démarrer une automatisation déployée de l'extérieur ; la [page Webhooks](/fr/develop/webhooks). | ## Les noms d'automatisation dans les URL Le nom d'une automatisation est un chemin en `/` — `billing/dunning` — et un chemin ne tient pas dans un seul segment d'URL. Dans chaque URL `/api/v1/automations/{name}/...`, écris le nom avec `__` à la place de chaque `/` : ```bash curl -sS "https://your-host.example.com/api/v1/automations/billing__dunning/runs" \ -H "Authorization: Bearer $TALE_API_KEY" ``` Les réponses portent toujours le vrai nom (`"name": "billing/dunning"`) ; la forme `__` n'existe que dans les URL. Les slugs d'agents et de skills sont plats et ne s'encodent pas. ## Démarrer une exécution, puis la suivre Une exécution est durable et peut prendre des minutes — le démarrage répond donc **202** avec l'identité de l'exécution, pas son résultat : ```bash curl -sS -X POST "https://your-host.example.com/api/v1/automations/billing__dunning/runs" \ -H "Authorization: Bearer $TALE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": { "customerId": "cus_123" } }' # → 202 { "runId": "...", "version": 2, "name": "billing/dunning", "mode": "live" } ``` Interroge `GET /api/v1/runs/{runId}` jusqu'à ce que `status` quitte `queued`/`running`/`waiting` ; l'exécution terminée porte `output`, la `trace` nœud par nœud et les `effects` produits. `POST /api/v1/runs/{runId}/cancel` arrête une exécution à sa prochaine frontière de nœud — ce qu'un nœud a déjà fait n'est pas défait. `mode` vaut `live` par défaut. Une exécution live agit au nom de l'organisation, elle exige donc une clé dont le détenteur a la capacité développeur ; `{"mode": "mock"}` tourne contre des mocks déterministes et ne demande que l'appartenance. Démarrer ne demande aucun déclencheur — la clé API est le droit d'entrée. Une automatisation sans version déployée répond **409** ; déploie une version dont les tests passent et le même appel passe. `projectId` nomme le projet dans lequel l’exécution opère — le projet sur lequel agissent ses outils de tâches et de documents. Omets-le et l’exécution porte sur toute l’organisation, sauf qu’une automatisation liée à un seul projet s’exécute dans celui-là automatiquement ; une automatisation liée à plusieurs n’accepte qu’un `projectId` parmi eux, et refuse tout autre. ## Envoyer un message, puis suivre le tour Le chat suit la même forme 202-puis-suivi. Crée un thread, poste un message, interroge la génération, puis lis les messages : ```bash # 1. Un thread à toi curl -sS -X POST "https://your-host.example.com/api/v1/threads" \ -H "Authorization: Bearer $TALE_API_KEY" \ -H "Content-Type: application/json" -d '{}' # → 201 { "id": "<threadId>" } # 2. Envoyer un message — sur cette API le modèle est toujours explicite, jamais choisi pour toi curl -sS -X POST "https://your-host.example.com/api/v1/threads/<threadId>/messages" \ -H "Authorization: Bearer $TALE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "content": "Résume-moi ce trimestre.", "model": "<un modèle configuré dans ton organisation>" }' # → 202 { "threadId": "...", "status": "accepted", "model": "...", "poll": "/api/v1/threads/<threadId>/generation" } # 3. Interroger jusqu'à idle, puis lire curl -sS "https://your-host.example.com/api/v1/threads/<threadId>/generation" \ -H "Authorization: Bearer $TALE_API_KEY" # → 200 { "status": "streaming" } … puis { "status": "idle" } ``` `{"status": "idle"}` signifie qu'aucun tour ne tourne — lis `GET /api/v1/threads/{id}/messages` pour la réponse. Un tour qui échoue avant toute sortie reste visible : l'erreur atterrit comme message d'assistant, jamais en silence. Les threads listés et lus par l'API sont ceux du détenteur de la clé ; les threads d'un autre utilisateur restent invisibles pour ta clé, même dans la même organisation. ## Modèle d'erreur Chaque réponse non-2xx porte une enveloppe plate : ```json { "error": "Automation not found" } ``` Branche sur le statut HTTP ; le message est pour les humains : - **400** — requête mal formée : champ requis manquant, mauvais type, corps illisible. - **401** — clé API absente ou invalide. - **403** — la clé est valide mais le rôle de son détenteur n'a pas la capacité (exécutions live, écriture de déclencheurs, annulation). - **404** — la ressource n'existe pas dans ton organisation, ou appartient au thread de quelqu'un d'autre. - **409** — l'état refuse l'action : pas de version déployée, un sujet ou un e-mail en double, un tour déjà en cours. - **413** — le corps est trop gros (le déclencheur webhook plafonne à 256 Ko). - **429** — limite de débit atteinte ; voir [Limites de débit](/fr/develop/rate-limits). - **500** — erreur interne. Deux sémantiques de suppression existent, à dessein. Délier le déclencheur d'une automatisation (`DELETE .../triggers`) répond **204**, qu'un déclencheur ait existé ou non — un « fais que ce soit ainsi » idempotent. Supprimer une ressource (`DELETE /api/v1/agents/{slug}`) répond **404** quand rien n'existait — tu as demandé de retirer une chose absente. ## Versionnage L'API est versionnée par le préfixe d'URL — aujourd'hui `/api/v1/` — et y évolue par ajout : de nouveaux endpoints et de nouveaux champs optionnels arrivent, les formes existantes restent. Un changement cassant sortirait sous un nouveau préfixe. Le document OpenAPI sous `/docs` décrit toujours l'instance qui tourne. ## Où ça se place Cette page est la moitié REST de la surface externe. L'[endpoint MCP](/fr/develop/mcp-endpoint) expose la même plateforme aux clients MCP — l'écriture d'automatisations vit là-bas, pas dans REST. La [page Webhooks](/fr/develop/webhooks) couvre le déclencheur entrant qui démarre des exécutions sans clé. Si tu construis dans le produit — agents, automatisations, outils maison — l'onglet [Platform](/fr/platform) est ton quotidien ; cette page est pour l'extérieur. # Développement assisté par IA Source: https://tale.dev/docs/fr/develop/ai-assisted-development Les projets Tale sont du JSON — agents, workflows, connectors, branding — et le JSON s'édite bien dans les éditeurs IA quand l'éditeur connaît le schéma. La CLI pose deux choses pour cela : un fichier de règles que chaque éditeur lit à la racine du projet (`CLAUDE.md` pour Claude Code, `.cursor/rules/tale.mdc` pour Cursor, `.github/copilot-instructions.md` pour Copilot, `.windsurfrules` pour Windsurf), et un miroir de schéma en lecture seule sous `.tale/reference/` vers lequel le fichier de règles pointe l'éditeur. Lis ceci quand tu veux éditer un projet Tale dans un éditeur IA sans taper le JSON à la main. Reviens-y quand l'éditeur invente des champs ou câble la mauvaise forme d'agent — la réponse est presque toujours que le schéma sous `.tale/reference/` est périmé. ## Une mise en place mise en pratique Initialise un projet — la CLI écrit le fichier de règles et le miroir de schéma dans la même étape : ```bash tale init my-org cd my-org ls -a # .cursor/ .github/ .tale/ .windsurfrules # CLAUDE.md agents/ workflows/ connectors/ branding/ ``` `CLAUDE.md` (installé en même temps comme `.mdc` Cursor, `.md` Copilot et fichier de règles Windsurf) dit à l'éditeur où regarder avant d'éditer une config : > Before creating or editing any config, read the relevant schemas and implementation code in `.tale/reference/` to understand the valid structure, fields, and constraints. Use existing config files in the project as examples. La directive compte parce que tout éditeur sous charge saute les lectures de schéma sauf instruction contraire. Le fichier de règles est le contrat ; le miroir de schéma est la vérité du terrain. ## Ce qui vit où | Chemin | Ce que c'est | | -------------------------------- | ----------------------------------------------------------------------------------- | | `agents/` | Un fichier JSON par agent — instructions, connaissances, tools, modèle. | | `workflows/` | Configs JSON de workflow, groupées par sous-répertoire de catégorie. | | `connectors/<slug>/config.json` | Manifeste de connector — operations, méthode d'auth, hôtes autorisés. | | `connectors/<slug>/connector.ts` | Connector TypeScript optionnel pour les formes REST que le manifeste ne couvre pas. | | `branding/branding.json` | Branding de l'org — couleurs, logos, expéditeurs courriel. | | `.tale/reference/` | Miroir de schéma en lecture seule ; régénéré par `tale init` et `tale update`. | L'arbre de référence est byte-à-byte identique aux schémas contre lesquels la plateforme valide au déploiement. Traite-le comme canonique : quand un nom de champ dans une config écrite à la main désaccorde avec la référence, la référence gagne. ## Travailler avec l'éditeur Le fichier de règles nomme trois règles que chaque éditeur applique pendant l'édition : - **Les agents lient, délèguent, attachent.** Un agent peut simultanément lier des connectors (`connectorBindings`), déléguer à d'autres agents (`delegates`) et attacher des workflows (`workflows`). Lis les configs existantes avant d'introduire une nouvelle liaison. - **Les workflows utilisent les operations de connector.** Une étape de workflow référence une operation de connector déclarée dans `connectors/<slug>/config.json`. Éditer une étape contre une operation qui n'existe pas fait échouer la validation. - **Le nommage est imposé.** Les noms de fichier d'agent correspondent à `[a-z0-9][a-z0-9_-]*\.json`. Les slugs d'étape de workflow correspondent à `[a-z0-9][a-z0-9_-]*`. Les répertoires de connector sont en minuscules alphanumériques avec tirets ou soulignés. Quand l'éditeur propose un changement, demande-lui de citer le fichier dans `.tale/reference/` sur lequel il s'est appuyé. S'il ne peut pas, régénère le miroir avec `tale update` et réessaie. ## Cursor : plan config vs plan runtime Cursor apparaît dans Tale à deux endroits distincts — ne les confonds pas. | Plan | Rôle | Où ça vit | | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | | **Config** | Aide Cursor (ou tout éditeur IA) à éditer le JSON d'un projet Tale sur ta machine | `.cursor/rules/tale.mdc`, `CLAUDE.md`, `.tale/reference/` — tout ce que `tale init` écrit | | **Runtime** | Lance la CLI Cursor Agent en mode headless dans une sandbox isolée quand un agent de projet ou un nœud agent d’automatisation utilise le harness **Cursor** | Agent de projet / nœud agent d’automatisation avec **Harness** = Cursor | Le fichier de règles et le miroir de schéma sur cette page sont le **plan config** : ils guident un éditeur local pendant que tu modifies agents, workflows et connectors. Le **plan runtime**, c’est un tour sur harness géré — `agent -p --output-format stream-json` avec ta `CURSOR_API_KEY`, progression normalisée dans le chat et reprise de session entre les relances. Credentials, modèles et facturation des tours runtime sont dans [Harnesses](/fr/platform/agents/harnesses), pas ici. ## Où cela s'inscrit Le développement assisté par IA est le chemin d'édition ; le déploiement est le chemin de publication. Une fois qu'une config passe la validation de l'éditeur, [`tale deploy`](/fr/self-hosted/install/cli-install) la rapproche de la plateforme — le même contrôle de schéma, cette fois comme barrière. Pour les fonctionnalités que l'éditeur n'atteint pas (le constructeur dans le produit, l'éditeur visuel de workflow), l'[onglet Platform](/fr/platform) est la surface canonique ; le chemin éditeur IA ici est pour les projets qui préfèrent la config-as-code. # Endpoint MCP Source: https://tale.dev/docs/fr/develop/mcp-endpoint Tale est lui-même un serveur MCP. Pointe n'importe quel client MCP — un harnais d'agent, un IDE, ta propre boucle SDK — vers un endpoint, et il peut écrire et opérer des automatisations, chercher ce que l'organisation sait faire, invoquer une capacité et récupérer des connaissances, avec la même clé API que la surface REST. Là où REST est la couture de connector pour ton code, l'endpoint MCP est la couture pour les *modèles* : chaque outil répond du texte qu'un modèle peut lire et exploiter. Lis ceci pour connecter un client et comprendre l'inventaire des outils. La grammaire d'écriture des automatisations n'est volontairement pas dupliquée ici — l'endpoint l'enseigne lui-même, via `get_docs`. ## Connecter un client L'endpoint parle le protocole MCP `2025-03-26` en JSON-RPC sur HTTPS — réponses JSON pures, pas de flux SSE, un message par requête (un batch répond l'erreur `-32600`). Authentifie-toi avec une clé API d'organisation ([Clés API](/fr/platform/admin/api-keys) décrit la création) : ```json // POST https://your-host.example.com/api/v1/mcp // Authorization: Bearer tale_... { "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {} } ``` Le serveur s'identifie comme `tale-platform`. Dans un client à bloc de config, c'est tout ce qu'il faut : ```json { "mcpServers": { "tale": { "url": "https://your-host.example.com/api/v1/mcp", "headers": { "Authorization": "Bearer tale_..." } } } } ``` `tools/list` renvoie l'inventaire complet ; `GET` sur l'endpoint répond **405** — il n'y a pas de flux d'événements à écouter. ## Les outils Vingt-deux outils, en trois groupes. Les outils d'écriture prennent des documents d'automatisation entiers et valident tout eux-mêmes — leurs schémas restent ouverts sur le fil, et `get_docs` est la référence qu'un modèle lit d'abord. Les outils de gestion et de capacités prennent des arguments simples et déclarent de vrais schémas JSON. ### Écriture | Outil | Ce qu'il fait | | --------------------- | -------------------------------------------------------------------- | | `get_docs` | La grammaire des automatisations et le guide d'écriture, en texte. | | `get_catalog` | Chaque type de nœud que ce déploiement sait exécuter. | | `search_catalog` | Chercher dans le catalogue de types de nœuds par mot-clé. | | `validate_automation` | Valider un document d'automatisation sans l'enregistrer. | | `run_automation` | Exécuter un document d'automatisation directement (mock ou live). | | `test_automation` | Lancer les tests d'acceptation propres à une automatisation. | | `save_automation` | Enregistrer un document comme nouvelle version immuable. | | `get_automation` | Lire une version enregistrée (la dernière sans précision). | | `list_automations` | Les automatisations de l'organisation avec leurs dernières versions. | | `deploy_automation` | Promouvoir une version enregistrée comme version live. | ### Gestion des exécutions & déclencheurs | Outil | Ce qu'il fait | | ---------------- | -------------------------------------------------------------------------------------------------------------- | | `run_deployed` | Exécuter la version déployée et ATTENDRE le résultat fini — sortie, trace et effets en une réponse. | | `start_run` | Démarrer la version déployée en arrière-plan et rendre aussitôt une poignée d'exécution ; suivre avec get_run. | | `list_runs` | Les exécutions récentes, la plus récente d'abord — d'une automatisation ou de toute l'organisation. | | `get_run` | Une exécution en entier : statut, sortie, trace et effets. | | `cancel_run` | Arrêter une exécution à sa prochaine frontière de nœud. | | `list_versions` | L'historique de versions immuable d'une automatisation. | | `list_triggers` | Ce qui démarre les automatisations (jamais le secret du webhook). | | `delete_trigger` | Délier le déclencheur d'une automatisation ; ses versions et son historique restent. | | `set_trigger` | Lier ce qui démarre l'automatisation (planning/webhook/événement). | Prends `run_deployed` quand l'automatisation est rapide et que tu veux un seul appel avec la réponse dedans. Prends `start_run` quand l'exécution peut durer des minutes — elle rend un `runId` aussitôt, et `get_run` le suit. Les deux tournent en live. `start_run` prend aussi un `projectId` optionnel — le projet dans lequel l’exécution opère, pour que ses outils de tâches et de documents y agissent. Omets-le pour une exécution à l’échelle de l’organisation ou, quand l’automatisation est liée à un seul projet, pour celui-là. Une automatisation liée n’accepte qu’un projet auquel elle est liée. ### Capacités & connaissances | Outil | Ce qu'il fait | | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | `search_capabilities` | Chercher tout ce que cette organisation sait faire — ses automatisations, actions de connector, skills et outils. | | `invoke_capability` | Invoquer une capacité par id. Une action que l'organisation soumet à validation répond un résultat d'approbation en attente au lieu de s'exécuter. | | `get_knowledge` | Récupérer des passages des connaissances de l'organisation — ses documents et ses pages web crawlées. | C'est le même registre qu'un tour de chat voit : un seul espace de noms sur les builtins, les actions de connector, les skills, les automatisations et les outils MCP connectés. Une capacité que l'organisation place derrière une approbation ne s'exécute pas en silence — `invoke_capability` répond un résultat d'approbation en attente que le modèle peut relayer. ## Ce que la clé peut faire La clé prouve qui appelle ; le rôle de son détenteur décide ce que l'appel peut faire — exactement comme dans le produit : - **Toute clé de membre** — chaque outil de lecture, `run_automation` en mode mock, `search_capabilities`, `get_knowledge`. - **Capacité développeur requise** — `save_automation`, `deploy_automation`, `set_trigger`, `delete_trigger`, `cancel_run`, et l'exécution live (`run_deployed`, `start_run`, `run_automation` en mode live). Un appel refusé n'est pas une erreur de protocole : l'outil répond un refus lisible — `{"error": "...", "hint": "..."}` — pour que le modèle appelant s'ajuste au lieu de planter. Cette convention vaut partout : problèmes de validation, déploiements manquants et refus de rôle reviennent comme des données ; `isError` est réservé à un appel qui a réellement levé. ## Où ça se place L'endpoint MCP et l'[API REST](/fr/develop/api-reference) sont une seule surface en deux dialectes — même clé, même périmètre d'organisation, mêmes objets d'exécution (`start_run` ici et `POST .../runs` là-bas produisent la même exécution durable). Construire ton propre serveur MCP que Tale consomme, c'est la direction inverse — ce sont les [serveurs MCP](/fr/platform/connectors/mcp-servers) côté connectors. # API WebDAV Source: https://tale.dev/docs/fr/develop/webdav-api Tale expose le dépôt de documents sous `/dav/<orgSlug>/` comme point de terminaison WebDAV Class 2 lecture-écriture (RFC 4918). Cette page est la référence du protocole — la surface filaire dont un implémenteur de client ou un outil tiers a besoin pour intégrer. Pour le guide de configuration utilisateur final et les instructions par client, voir [Plateforme > Connectors > WebDAV](/fr/platform/connectors/webdav). ## Schéma d’URL ```text /dav/<orgSlug>/documents/<path> R/W arbre de documents actifs /dav/<orgSlug>/.trash/<path> R/O documents soft-supprimés (vue corbeille) /dav/<orgSlug>/ R/O collection contenant les deux ci-dessus ``` Les segments sont URL-encodés. Le serveur rejette les segments contenant `/`, `\`, NUL, ou les noms relatifs `.` et `..`. Chaque segment doit faire 1–255 octets. Le `orgSlug` correspond à `[a-zA-Z0-9_-]{1,64}`. La politique de slash final suit la convention WebDAV : les collections (dossiers) sont référencées avec un slash final, les ressources (fichiers) sans. Beaucoup de clients normalisent à la volée ; le serveur accepte les deux formes à la résolution et émet la forme canonique dans les réponses PROPFIND. ## Authentification HTTP Basic uniquement. Le champ nom d’utilisateur peut être n’importe quelle valeur non vide — le mot de passe applicatif est la vraie information d’identification, et le serveur ne compare pas le nom d’utilisateur à ton enregistrement de compte. Utiliser l’e-mail de ton compte Tale est la convention pour la lisibilité des journaux d’audit, et les clients qui pré-remplissent depuis le trousseau attendent une chaîne en forme d’e-mail, mais la décision d’authentification se fait uniquement sur le mot de passe. Le mot de passe est un **mot de passe applicatif** généré sous Paramètres > WebDAV. Le mot de passe principal n’est pas accepté sur ce point de terminaison. ```http Authorization: Basic <base64(email-ou-autre:mot-de-passe-applicatif)> ``` Les mots de passe applicatifs sont hachés avec HMAC-SHA256 sous le secret de déploiement `WEBDAV_APP_PASSWORD_HMAC_KEY`. La clé est dérivée de manière déterministe depuis `INSTANCE_SECRET` par l’entrypoint de la plateforme (prod) et `server.ts` (dev), donc les opérateurs n’ont pas à la définir manuellement ; une valeur explicite dans `.env` remplace la valeur dérivée. La recherche restreint via les quatre premiers caractères du mot de passe (stockés à côté du hash pour une recherche indexée) et vérifie avec une comparaison HMAC à temps constant. Chaque requête authentifiée vérifie aussi que l’utilisateur est membre actif de l’organisation dans l’URL — une ligne périmée (appartenance retirée après l’émission) est rejetée avec `403`. `OPTIONS` est la seule méthode autorisée sans authentification ; les clients l’utilisent pour sonder la capacité DAV avant de se connecter. ## Méthodes | Méthode | Comportement | Auth | | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | | OPTIONS | Annoncer les capacités. Renvoie `DAV: 1, 2`, `Allow: …`, et `Microsoft-Server-WebDAV-Extensions: 1` pour la compatibilité Windows. | Anonyme OK | | PROPFIND | Lister une ressource (Depth 0) ou les enfants directs d’une collection (Depth 1). La liste de propriétés émise est documentée plus bas. **Depth: infinity est rejeté avec 403** pour éviter des réponses sans borne. | Requise | | PROPPATCH | Renvoie succès 207 par propriété sans stocker les valeurs. Les dead properties ne sont pas persistées en v1 ; PROPPATCH réussit de manière optimiste pour la compatibilité client. | Requise | | GET / HEAD | Streamer le blob du document. Pose `Content-Type`, `Content-Length`, `ETag` et `Last-Modified`. GET sur une collection renvoie 405. | Requise | | PUT | Créer ou remplacer un document. Le nouveau blob est stocké dans le stockage Convex avec déduplication par hash ; la ligne du document reçoit `sourceProvider: "webdav"`. Renvoie 201 à la création, 204 à l’écrasement. | Requise | | DELETE | Soft-supprimer un document (`lifecycleStatus: "trashed"`) ou un dossier (corbeille en cascade sur les documents contenus, hard-supprime les lignes de dossier). Renvoie 204. | Requise | | MKCOL | Créer un dossier sous un parent existant. Corps vide uniquement. Renvoie 201, 405 si la cible existe, 409 si le parent manque. | Requise | | MOVE | Renommer ou déplacer. Atomique pour les documents. Pour les dossiers, met à jour le `parentId` du dossier déplacé. Respecte `Overwrite: T/F` et `If`. Renvoie 201 (nouvelle destination) ou 204 (écrasement). | Requise | | COPY | Copie côté serveur. Les copies de documents réutilisent l’identifiant de stockage Convex (déduplication). Les copies de dossiers sont récursives. Respecte `Overwrite` et `If`. | Requise | | LOCK | Verrou d’écriture Class 2 exclusif ou partagé. Timeout depuis le header `Timeout: Second-N`, plafonné à 3600. Rafraîchissement en renvoyant LOCK avec `If: (<opaquelocktoken:...>)` et un corps vide. | Requise | | UNLOCK | Libérer un verrou par son jeton. Seul le propriétaire peut libérer. Renvoie 204. | Requise | `HEAD` partage son handler avec `GET`, corps en moins. ## Propriétés PROPFIND renvoie ces propriétés vivantes pour chaque ressource : - `resourcetype` — `<collection/>` sur les dossiers, vide sur les documents. - `displayname` — le nom du dossier ou le titre du document. - `getlastmodified` — horodatage RFC 1123. Les documents utilisent `sourceModifiedAt` s’il est défini, sinon l’heure de création de la ligne. - `creationdate` — ISO 8601 de l’heure de création de la ligne. - `getcontenttype` — documents uniquement ; le MIME type au moment du téléversement. - `getcontentlength` — documents uniquement ; en octets. - `getetag` — documents uniquement ; le hash de contenu s’il est connu, sinon l’identifiant du document. - `supportedlock` — annonce le support des verrous d’écriture exclusifs. - `lockdiscovery` — présent sur les ressources avec verrous actifs. Les dead properties ne sont pas stockées. PROPPATCH renvoie 200 pour une dead property définie seule, mais définir une propriété live/protégée renvoie un 403 par propriété (`cannot-modify-protected-property`), et toutes les dead properties de la même requête sont alors signalées en 424 Failed Dependency (RFC 4918 §9.2 atomicité). Aucune valeur n’est jamais persistée. ## Sémantique des verrous Les verrous vivent dans leur propre table Convex, indexés par `(organizationId, resourcePath)`. La forme filaire est `opaquelocktoken:<uuid>`. Le serveur : - Plafonne le timeout à 3600 secondes. Les requêtes pour des fenêtres plus longues sont silencieusement bornées. - Traite `LOCK` avec un header `If: (<opaquelocktoken:UUID>)` et un corps vide comme un refresh — l’expiration du verrou existant est repoussée. - Renvoie `412 Precondition Failed` au refresh si le jeton fourni est inconnu. - Renvoie `423 Locked` sur `PUT / DELETE / MOVE / COPY / MKCOL / PROPPATCH` contre un chemin verrouillé quand la requête n’a pas de header `If` correspondant. - Renvoie `412 Precondition Failed` si le jeton `If` fourni ne correspond pas au verrou vivant. - Expire les verrous paresseusement — la requête de lookup renvoie null pour les lignes expirées et planifie une suppression fire-and-forget. - Hard-supprime tout verrou détenu sous un mot de passe applicatif quand ce mot de passe est révoqué. `UNLOCK` requiert à la fois un header `Lock-Token` valide et que l’utilisateur soit le propriétaire du verrou. ## Codes de statut - `200` — OPTIONS, GET, HEAD, LOCK, refresh LOCK, PROPPATCH (par propriété) - `201` — création PUT, MKCOL, MOVE/COPY vers une nouvelle destination - `204` — DELETE, UNLOCK, écrasement PUT, écrasement MOVE/COPY - `207` — PROPFIND, PROPPATCH (enveloppe multi-status) - `400` — header `Destination` / `If` / `Lock-Token` / `Timeout` mal formé - `401` — Basic auth absente ou invalide - `403` — Depth: infinity rejeté ; tentative d’écriture .trash ; suppression/déplacement de la racine ; mauvais propriétaire de mot de passe applicatif sur UNLOCK ; utilisateur pas membre de l’org ; MOVE/COPY sur lui-même ou dans son propre sous-arbre ; `Destination` cross-org - `404` — ressource introuvable - `405` — GET sur une collection ; PUT sur un chemin de collection ; MKCOL sur un chemin existant ; MKCOL racine - `409` — MKCOL, MOVE ou COPY quand le parent de destination n’existe pas - `412` — non-correspondance de jeton `If` ; précondition `If-Match` / `If-None-Match` échouée ; MOVE/COPY avec `Overwrite: F` sur une destination existante - `413` — corps PUT au-delà de la limite de taille, ou un corps XML (PROPFIND / PROPPATCH / MKCOL / LOCK) au-delà de 64 Ko - `415` — MKCOL avec corps XML non vide (extended MKCOL non implémenté) - `423` — écriture tentée sur un chemin verrouillé sans `If` correspondant - `502` — `Destination` cross-host ; fetch proxy stockage échoué - `503` — limite du nombre de LOCK dépassée pour le mot de passe applicatif (avec `Retry-After`) - `507` — sous-arbre de dossier trop volumineux pour être supprimé, déplacé ou copié en une seule requête ## Conformité - DAV Class **1** (base) : complète. - DAV Class **2** (verrouillage) : complète, avec le comportement d’expiration paresseuse décrit ci-dessus. - DAV Class **3** (calendrier, contacts, recherche, ACL) : non implémentée. Le serveur annonce `DAV: 1, 2` dans la réponse OPTIONS. ## Limites - `Depth: infinity` sur PROPFIND est rejeté avec `403`. - `Timeout: Second-N` sur LOCK est borné à `[1, 3600]`. - La taille du corps PUT est plafonnée à **5 Go** par défaut (`413` au-delà), appliquée à la fois au reverse-proxy et dans le serveur de plateforme. Les opérateurs peuvent l’ajuster via la variable d’environnement `WEBDAV_MAX_PUT_BYTES`. Le corps est streamé vers une URL pré-signée Convex sans qu’un gros upload soit mis en mémoire tampon côté plateforme. - Les corps XML (PROPFIND / PROPPATCH / MKCOL / LOCK) sont plafonnés à **64 Ko** (`413` au-delà) — ces enveloppes sont minuscules par conception. - Les mots de passe applicatifs sont hachés avec HMAC-SHA256 ; le secret n’apparaît dans aucune réponse après l’appel de création. - `lastUsedAt` est patché au plus une fois par minute par mot de passe applicatif pour éviter les write-storms sur les montages actifs. ## Prérequis réseau Le point de terminaison WebDAV tourne dans le serveur Hono de la plateforme (`platform:3000` en compose). Caddy route `/dav/*` vers lui via le fallback par défaut — aucune configuration supplémentaire n’est requise. Le chemin requiert que le serveur de plateforme ait `ADMIN_KEY` défini dans son environnement pour appeler les requêtes internes Convex avec auth admin. Pour le dev (`bun dev`), le même dispatch est monté comme middleware Vite (`vite-plugins/serve-webdav.ts`) — `curl` et les clients peuvent atteindre `http://localhost:3000/dav/<orgSlug>/...` contre un serveur dev qui tourne sans rebuild. ## Sécurité WebDAV envoie le mot de passe applicatif à chaque requête sous forme de header HTTP Basic — pas de session, pas de rafraîchissement de jeton, juste l’identifiant brut rejoué à chaque PROPFIND, PUT, LOCK et ainsi de suite. Ne monte le point de terminaison que sur HTTPS ; sur HTTP en clair, le mot de passe fuite vers quiconque se trouve sur le câble, et révoquer la ligne est le seul moyen de récupérer. Ne mets jamais le mot de passe applicatif dans l’URL elle-même (la forme abrégée `https://user:pass@host/...`) — la plupart des clients consignent les URL dans l’historique du shell, les rapports de crash et les journaux d’accès du proxy, où l’identifiant survivrait bien après le démontage. Laisse le client WebDAV stocker le mot de passe dans le trousseau du système d’exploitation (macOS Keychain, Windows Credential Manager, GNOME Keyring) et le présenter via l’invite d’identifiants standard. Le serveur impose TLS au niveau du reverse proxy en production ; le mode dev sur HTTP en clair est uniquement prévu pour les tests `localhost`. Les journaux d’audit enregistrent chaque requête authentifiée avec le préfixe du mot de passe utilisé, donc un identifiant fuité peut être tracé et révoqué sans faire tourner le reste de la flotte d’appareils. ## Comment ça s’intègre WebDAV est la surface mount-protocole du même dépôt de documents que la [référence de l’API REST](/fr/develop/api-reference) anime pour l’import en lot et la recherche — les deux voies écrivent dans la table que le [Hub de documents](/fr/platform/knowledge/documents) lit, donc un fichier créé via Finder apparaît dans l’interface web sans aucune étape de synchronisation. Le protocole est le bon choix quand un utilisateur veut que ses documents se comportent comme un dossier local ; l’API REST est le bon choix quand un script ou un agent veut un contrôle au niveau de l’octet sur ce qui est écrit et quand. La RFC 4918 est l’autorité au niveau filaire pour tout ce qui se trouve sur cette page. # Développement Source: https://tale.dev/docs/fr/develop/overview Développement est la section pour les intégrateurs et les contributeurs — tous ceux qui branchent Tale sur un autre système, construisent au-dessus de l’API ou livrent une modification du code source. Les pages ici décrivent la surface externe (REST, webhooks, endpoints compatibles OpenAI) et le workflow de contribution. Si tu es à l’intérieur du produit avec le rôle Développeur (construction d’agents, d’automatisations, d’outils sur mesure), l’onglet Plateforme couvre ton quotidien ; Développement sert quand tu es à l’extérieur du produit et que tu lui parles via le fil. Tu préfères regarder d’abord ? L’épisode bonus parcourt la surface développeur — clés, API, webhooks, harnesses — en deux minutes. <Video src="/videos/fr/tutorials/ep10-developers/ep10-developers.fr.mp4" poster="/videos/fr/tutorials/ep10-developers/ep10-developers.fr.webp" captions="/videos/fr/tutorials/ep10-developers/ep10-developers.fr.vtt" lang="fr" title="Bonus — Tale pour les développeurs" caption="Bonus — Tale pour les développeurs (2:04)"> </Video> ## Pages de cette section <CardGroup cols="2"> <Card title="Référence API" icon="code" href="/fr/develop/api-reference"> Endpoints, authentification, endpoints compatibles OpenAI, modèle d’erreur, versionnage. </Card> <Card title="Webhooks" icon="webhook" href="/fr/develop/webhooks"> Sortants (Tale → toi) et entrants (toi → Tale), signature, idempotence, retraitements. </Card> <Card title="Développement assisté par IA" icon="sparkles" href="/fr/develop/ai-assisted-development"> Utiliser les agents Tale pour écrire des workflows Tale, les fichiers de skill `.agents/`. </Card> <Card title="Connectors" icon="plug" href="/fr/develop/connectors"> Connectors tierces vues côté développeur. </Card> <Card title="Page de statut" icon="activity" href="/fr/develop/status-page"> Rapport d’incident pour Cloud, pointeurs de métriques pour auto-hébergé. </Card> <Card title="Limites de débit" icon="gauge" href="/fr/develop/rate-limits"> Limites par clé, par IP, par organisation, et comment lire un 429. </Card> </CardGroup> ## Où cela s’inscrit Développement est la section la plus petite, parce que la plupart des utilisateurs n’en ont jamais besoin ; le public se concentre sur deux rôles (Développeur dans le produit, contributeur en dehors), mais elle est porteuse pour les deux. Si tu branches quelque chose d’externe sur Tale, [Référence API](/fr/develop/api-reference) est la première lecture ; si tu contribues au code source, [Contribuer](/fr/self-hosted/contributing-docker) — sous l’onglet Auto-hébergé — est la bonne. # Ton premier jour de création d’agents Source: https://tale.dev/docs/fr/get-started/editors Ce parcours s’adresse à la personne qui transforme « l’équipe pose toujours les mêmes questions » en un agent qui y répond. En quinze minutes, tu crées un agent, tu façonnes son comportement et tu le regardes faire un vrai travail sur une tâche — la boucle que chaque agent suivant raffine. Il te faut le rôle **Éditeur** ou plus (la section Agents est masquée pour les membres) sur un espace de travail où le chat répond déjà — c’est le [démarrage rapide](/fr/get-started/quickstart). <Steps> <Step title="Crée l’agent"> Pour lancer un agent que tes collègues peuvent mettre au travail, ouvre **Agents** dans la barre latérale et clique sur **Créer un agent**. Nomme-le d’après le travail, pas la technologie — « Tri support » bat « GPT Helper » — parce que c’est à ce nom que tes collègues assigneront des tâches plus tard. </Step> <Step title="Façonne son identité"> L’éditeur s’ouvre sur l’onglet **Général** : le nom affiché que voient tes collègues et une description d’une ligne. Le réglage qui compte au premier jour est la visibilité — elle décide qui, dans l’organisation, peut mettre l’agent au travail. </Step> <Step title="Écris les instructions"> Ouvre **Instructions** — le levier qui compte le plus. Écris un paragraphe comme si tu briefais un nouveau collègue : la voix dans laquelle répondre, le domaine qu’il possède et les cas qu’il doit refuser. Concret bat complet — tu affineras après avoir vu de vraies réponses. Clique sur **Enregistrer** ; l’agent est joignable dès la requête suivante, sans étape de publication séparée. </Step> <Step title="Regarde-le travailler"> Les agents font leur travail sur des tâches — le chat, lui, ne fait tourner que l’assistant intégré. Ouvre un projet, ajoute ton agent dans son onglet **Agents**, puis crée une tâche qui énonce le travail en une phrase et assigne-la à l’agent. Lance l’exécution et suis son déroulé ; le résultat revient pour ta relecture, et le marquer terminé n’appartient qu’à toi. <Check> Un résultat qui suit la voix et le périmètre que tu as écrits prouve que les instructions tiennent — l’agent est réel. </Check> </Step> </Steps> ## Où tu en es Tu as livré le plus petit agent réel : des instructions et une place dans l’effectif de l’organisation. Le modèle complet derrière ce que tu viens de toucher est [Concepts d’agent](/fr/platform/agents/concepts) — instructions, connaissances, outils et skills. La construction suivante naturelle est [ton premier agent de bout en bout](/fr/tutorials/editor/first-agent-end-to-end), qui ajoute des liaisons de connaissances et un vrai domaine ; ensuite, [agents avec connaissances](/fr/tutorials/editor/agent-with-knowledge) et [délégation entre agents](/fr/tutorials/editor/delegate-between-agents) poussent la même boucle plus loin. # Démarrage rapide Source: https://tale.dev/docs/fr/get-started/quickstart C’est le chemin le plus court vers un chat qui répond : obtenir une instance, se connecter, envoyer un message, regarder la réponse arriver en streaming. Compte environ cinq minutes sur une instance prête et quinze sur ta propre machine ; à la fin tu vois l’écran ci-dessous — une vraie réponse d’un agent sur ton espace de travail. <Frame caption="Là où ce démarrage rapide se termine : une réponse d’agent en streaming dans l’onglet Chat."> ![Un fil de chat montrant une question d’utilisateur sur des retours d’onboarding et une réponse de l’assistant contenant un tableau markdown de trois thèmes.](/images/platform/chat-thread-reply.webp) </Frame> Tu préfères la vidéo ? L'épisode 1 parcourt le même chemin en trois minutes — sous-titres compris. <Video src="/videos/fr/tutorials/ep1-welcome/ep1-welcome.fr.mp4" poster="/videos/fr/tutorials/ep1-welcome/ep1-welcome.fr.webp" captions="/videos/fr/tutorials/ep1-welcome/ep1-welcome.fr.vtt" lang="fr" title="Épisode 1 — Bienvenue dans Tale" caption="Épisode 1 — Bienvenue dans Tale (2:46)"> </Video> ## Obtenir une instance Les deux éditions font tourner le même produit — choisis selon qui doit exploiter la stack. <Tabs> <Tab title="Auto-hébergé"> Avec [Docker](https://www.docker.com/products/docker-desktop) en marche, trois commandes montent toute la stack sur ta machine : ```bash curl -fsSL https://raw.githubusercontent.com/tale-project/tale/main/scripts/install-cli.sh | bash tale init my-project && cd my-project tale dev ``` Le premier lancement récupère les images — compte cinq à dix minutes. Quand le navigateur s’ouvre, inscris-toi : le premier compte revendique le rôle **Propriétaire** et crée ton organisation. Le [démarrage rapide auto-hébergé](/fr/self-hosted/install/quickstart) couvre chaque étape en profondeur, Windows et dépannage compris. </Tab> <Tab title="Cloud"> Les instances Cloud sont montées pour toi : remplis le [formulaire de demande de démo](https://tale.dev/fr/request-demo) et l’équipe Tale provisionne ta propre instance. Une fois qu’elle est prête, ouvre-la et inscris-toi — le formulaire demande ton nom, ton e-mail et un mot de passe ; vérifie le lien reçu par e-mail, nomme ton organisation et tu atterris dans le dashboard. L’assistant de configuration propose de connecter un fournisseur d’IA tout de suite — colle une clé [OpenRouter](https://openrouter.ai) à cet endroit et le chat fonctionne immédiatement. Le [parcours admin](/fr/get-started/admins) déroule le même assistant, captures d’écran à l’appui, quand tu veux plus que le chemin le plus direct. </Tab> </Tabs> ## Envoyer ton premier message <Steps> <Step title="Ouvre un nouveau chat"> Clique sur **Nouveau chat** dans la barre latérale. La zone de saisie en bas de l’écran est le point de départ de tout : le champ de message, et un seul sélecteur qui nomme le modèle d’où viendra la réponse. Un modèle déjà affiché sur le sélecteur signifie que tu es prêt à envoyer — l’assistant est intégré, il n’y a donc rien d’autre à choisir. </Step> <Step title="Pose une vraie question"> Choisis n’importe quel modèle de chat dans le sélecteur — chaque réponse vient du modèle que tu as nommé, rien n’est choisi pour toi en coulisses. Tape une question et envoie-la. La réponse arrive en streaming, token par token ; quand l’agent raisonne avant de répondre, une ligne de réflexion repliable apparaît au-dessus de la réponse. <Check> Une réponse en streaming qui répond à ta question prouve que toute la chaîne fonctionne — identifiant de fournisseur, modèle et assistant. Tu as un espace de travail opérationnel. </Check> </Step> </Steps> ## Où tu en es Tu as une instance qui tourne et un agent qui répond. Les quinze prochaines minutes dépendent de ton rôle : le [parcours membre](/fr/get-started/members) couvre les documents et les projets, le [parcours éditeur](/fr/get-started/editors) publie ton premier agent spécialiste, le [parcours admin](/fr/get-started/admins) monte l’équipe et les fournisseurs, et le [parcours développeur](/fr/get-started/developers) te donne une clé API et ta première requête. # Ton premier jour d’connector avec Tale Source: https://tale.dev/docs/fr/get-started/developers Ce parcours s’adresse à la personne qui câble Tale dans d’autres systèmes. En dix minutes, tu crées une clé API, tu envoies ta première requête authentifiée et tu sais à quelle porte frapper pour le chat, les workflows et les documents. Il te faut le rôle **Développeur** ou plus (les paramètres d’API sont masqués en dessous) sur une instance qui tourne — [démarrage rapide](/fr/get-started/quickstart) si tu n’en as pas. Remplace `your-host.example.com` ci-dessous par l’hôte de ton instance. <Steps> <Step title="Crée une clé API"> Pour obtenir un identifiant que tes scripts peuvent porter, ouvre **Paramètres > API > REST** et clique sur **Créer une clé API**. Nomme-la d’après le système qui l’utilisera — les clés sont listées par nom, et dans un an « zapier-bridge » bat « test ». La valeur de la clé ne s’affiche qu’une fois, à la création ; range-la dans ton gestionnaire de secrets, pas dans le code. <Frame caption="Les paramètres de l’API REST — les clés se créent et se révoquent ici."> ![La page des paramètres des clés API REST listant deux clés — Production ingest et CI pipeline — dont chacune n’affiche que son préfixe, sa date d’ajout et la mention Jamais utilisée, à côté d’un bouton Créer une clé API.](/images/get-started/settings-api-keys.webp) </Frame> </Step> <Step title="Envoie la première requête"> L’appel utile le plus court liste les agents que ta clé peut voir. La clé voyage comme un token bearer ; le contexte de l’espace de travail se déduit de la clé elle-même : ```bash curl -sS https://your-host.example.com/api/v1/agents \ -H "Authorization: Bearer $TALE_API_KEY" ``` <Check> Un tableau JSON d’agents — dont l’Assistant intégré — prouve la clé, l’en-tête et la route. Un `401` signifie que l’en-tête du token est malformé ou que la clé a été révoquée. </Check> </Step> </Steps> ## Le reste de la surface Tout le reste est une variation de cette requête. Les automatisations se lancent par nom via `POST /api/v1/automations/<name>/runs` avec la même clé Bearer — répondu 202, suivi via `/api/v1/runs/<runId>` — ou se déclenchent depuis l’extérieur via des URL de webhook de la forme `/api/automations/webhook/<token>`, où le jeton dans l’URL est l’identifiant. Le chat, c’est un thread, un message posté et un suivi ; les documents se téléversent via `/api/v1/documents` ; et la même clé ouvre l’[endpoint MCP](/fr/develop/mcp-endpoint) pour les clients pilotés par modèle. La [référence API](/fr/develop/api-reference) est l’inventaire complet avec l’authentification, les formes et les limites. ## Où tu en es Tu tiens un identifiant qui fonctionne et tu as vu la forme de requête que chaque endpoint partage. À partir d’ici, [appeler Tale depuis un script](/fr/tutorials/developer/call-tale-from-a-script) transforme le curl en vraie connector, [déclencher une automatisation par webhook](/fr/tutorials/developer/trigger-automation-via-webhook) couvre le sens entrant — tes systèmes qui déclenchent Tale — et l’[endpoint MCP](/fr/develop/mcp-endpoint) est la même plateforme pour les clients MCP. # Ton premier jour d’administration Source: https://tale.dev/docs/fr/get-started/admins Ce parcours s’adresse à la personne responsable de l’espace de travail. En quinze minutes, tu crées l’organisation, tu connectes le fournisseur qui fait répondre le chat, tu fais entrer tes premiers collègues et tu apprends où vivent les contrôles de gouvernance avant d’en avoir besoin. Il te faut un compte sur une instance qui tourne ([démarrage rapide](/fr/get-started/quickstart)) ; sur une instance toute neuve, le premier compte est automatiquement **Propriétaire**, ce qui porte toutes les permissions ci-dessous. <Steps> <Step title="Crée l’espace de travail"> Si tu arrives du démarrage rapide, ton organisation existe déjà — passe directement à la connexion d’un fournisseur. Une première connexion sans organisation atterrit sur l’assistant de création : le **Nom de l'organisation** est le nom affiché que ton équipe voit dans le coin de chaque page — choisis-en un qui survit à un rebranding. L’assistant propose ensuite de connecter un fournisseur d’IA et se termine sur le dashboard. <Frame caption="L’étape espace de travail de l’assistant de création."> ![L’assistant de création d’organisation à son étape espace de travail, avec Northlight Labs saisi dans le champ Nom de l’organisation et le bouton Suivant actif.](/images/get-started/org-create-wizard.webp) </Frame> </Step> <Step title="Connecte un fournisseur d’IA"> Rien ne répond tant qu’aucun fournisseur n’est connecté. Si tu as sauté l’étape fournisseur de l’assistant, ouvre **Paramètres > Fournisseurs IA** et clique sur **Ajouter un identifiant** sur un connecteur — une clé [OpenRouter](https://openrouter.ai) atteint le catalogue de modèles le plus large, et chaque fournisseur direct apporte son propre connecteur à côté. Un identifiant est utilisable dès qu’il est enregistré ; à partir de là, chaque agent de l’espace de travail peut répondre avec n’importe quel modèle que ce connecteur expose. <Frame caption="Un fournisseur connecté avec son catalogue de modèles."> ![La page des paramètres des fournisseurs d’IA listant un seul fournisseur connecté, OpenRouter, avec son URL de base et ses 52 modèles.](/images/get-started/settings-providers.webp) </Frame> </Step> <Step title="Fais entrer l’équipe"> Pour ajouter des personnes, ouvre **Paramètres > Organisation**, descends jusqu’à la section **Membres** et clique sur **Ajouter un membre**. Chaque personne arrive avec un rôle qui borne ce qu’elle peut faire : **Membre** lit et discute, **Éditeur** construit agents et connaissances, **Développeur** câble workflows, automatisations et accès API, **Admin** gère l’espace de travail. Commence bas — monter un rôle plus tard prend un clic, et reprendre un accès qui a fuité, non. <Frame caption="La section Membres — chaque compte et son rôle."> ![La page des paramètres de l’organisation avec sa section Membres listant le propriétaire de l’espace de travail Alex Rivera et un bouton Ajouter un membre.](/images/get-started/settings-organization-members.webp) </Frame> <Check> Un collègue qui se connecte et obtient une réponse dans le chat prouve toute la chaîne — compte, rôle, fournisseur — sans que tu sois à côté de lui. </Check> </Step> <Step title="Sache où vit la gouvernance"> Tu n’auras pas besoin de politiques le premier jour, mais tu dois connaître la porte : **Paramètres > Gouvernance** regroupe journaux d’audit, analyses d’usage, politiques de contenu, garde-fous et rétention. La seule habitude qui vaut d’être prise aujourd’hui est de parcourir les [journaux d’audit](/fr/platform/admin/governance/audit-logs) après la première semaine — ils montrent ce que ton espace de travail fait vraiment. </Step> </Steps> ## Où tu en es L’espace de travail tient debout : un fournisseur répond, l’équipe est entrée avec des rôles bornés et tu sais où vivent les contrôles. La matrice complète des permissions est [Membres et rôles](/fr/platform/admin/members-and-roles) ; la [vue d’ensemble admin](/fr/platform/admin/overview) cartographie chaque panneau que tu possèdes désormais ; et quand la conformité te sollicite, la [gouvernance](/fr/platform/admin/governance/audit-logs) est la section à lui montrer. # Ton premier jour avec Tale Source: https://tale.dev/docs/fr/get-started/members Ce parcours s’adresse à tous ceux qui utilisent Tale sans le configurer. En quinze minutes, tu discutes avec un agent, tu ajoutes un document que tout l’espace de travail peut exploiter et tu apprends où vit le travail partagé — les trois gestes qui couvrent la plupart des journées. Il te faut un compte connecté sur un espace de travail où le chat répond déjà — c’est le [démarrage rapide](/fr/get-started/quickstart). Discuter et parcourir fonctionnent avec le rôle **Membre** ; les deux gestes d’écriture ci-dessous (téléverser un document, déplacer une tâche) demandent **Éditeur** ou plus — si un bouton te manque, c’est la frontière de rôle, pas un espace de travail cassé. <Steps> <Step title="Discute avec un agent"> Tu as déjà envoyé un premier message dans le démarrage rapide — cette fois, regarde ce que l’agent en fait. Clique sur **Nouveau chat**, pose une question tirée de ton vrai travail et déplie les blocs repliables d’appels d’outils au-dessus de la réponse : ils montrent ce que l’agent a lu ou exécuté avant de répondre. Quand la réponse doit venir d’un document, téléverse-le d’abord sous **Connaissances** — l’assistant cherche dans les documents de l’organisation et cite ce qu’il a utilisé. L’étape suivante couvre justement ce téléversement. </Step> <Step title="Donne un document à l’espace de travail"> Les connaissances persistent d’un chat à l’autre, et les réponses les citent. Pour rendre un document disponible à chaque agent et à chaque collègue, ouvre **Connaissances > Documents** et clique sur **Téléverser des documents**, puis **Depuis ton appareil**, choisis le fichier et clique sur **Téléverser**. Le document apparaît dans le tableau et s’indexe en arrière-plan — une fois indexé, les agents le citent dans leurs réponses. Le menu de téléversement apparaît pour les Éditeurs et au-dessus ; avec le rôle Membre, tu lis et cherches dans la bibliothèque, et tu confies le fichier à un Éditeur pour l’ajouter. <Frame caption="Le tableau Documents après quelques téléversements."> ![Le tableau des documents de la section Connaissances listant trois fichiers texte téléversés avec leur statut d’indexation.](/images/get-started/documents-list.webp) </Frame> <Check> Pose dans un nouveau chat une question à laquelle seul ton document peut répondre. Une réponse qui cite le document prouve que l’index fonctionne de bout en bout. </Check> </Step> <Step title="Retrouve le travail de l’équipe dans les projets"> Ouvre **Projets** dans la barre latérale. Un projet regroupe tout ce qui touche à un même effort — des tâches sur un tableau, des fichiers partagés, des chats de projet et ses propres agents. Ouvre un projet et bascule entre **Tableau** et **Liste** dans l’onglet Tâches ; avec l’accès en édition (Éditeur et au-dessus), glisse une tâche d’une colonne à l’autre pour mettre à jour son statut, et la carte qui reste dans sa nouvelle colonne après un rechargement signifie que le changement a persisté pour tout le monde. <Frame caption="Le tableau des tâches d’un projet — glisse les cartes entre les colonnes."> ![Un tableau de tâches de projet intitulé « Website relaunch » avec sept cartes réparties à une ou deux par colonne sur Backlog, À faire, En cours, En revue, Terminé et Annulé.](/images/platform/projects-task-board.webp) </Frame> </Step> <Step title="Retrouve ton chemin"> Les chats ne disparaissent jamais en silence. Clique sur **Afficher l'historique** au-dessus du chat pour ouvrir la barre latérale d’historique — chaque chat que tu peux reprendre dans cet espace de travail, du plus récent au plus ancien. Renommer un chat lui donne un titre qui reste ; en supprimer un l’envoie dans la corbeille de l’espace de travail au lieu de le détruire. </Step> </Steps> ## Où tu en es Tu sais discuter, nourrir l’espace de travail en connaissances et naviguer dans le travail partagé — la boucle quotidienne du membre. Les lectures suivantes naturelles sont [Bases du chat](/fr/platform/chat/basics) pour le modèle mental derrière le chat, et [Utiliser les projets](/fr/tutorials/member/use-projects) pour un parcours projet plus profond. Quand tu veux construire ton propre agent, passe au [parcours éditeur](/fr/get-started/editors). # Contribuer aux images Docker Source: https://tale.dev/docs/fr/self-hosted/contributing-docker Chaque conteneur que Tale ship a son Dockerfile dans le repo source public. Les forks, distributions air-gapped et patches one-off partent tous des mêmes fichiers ; cette page est le walk opérateur à travers la construction des images toi-même, où les coutures de personnalisation vivent, et comment garder un fork en sync avec l'amont sans diverger sur les parties ennuyeuses. L'architecture des conteneurs vit dans [Architecture des conteneurs](/fr/self-hosted/operate/container-architecture) ; cette page est ce que tu lis quand les images publiées ne vont pas et qu'il te faut construire les tiennes. ## Quelles sont les images La stack est entièrement TypeScript — pas d'image Python. Chaque image a un Dockerfile sous `services/<name>/` : | Image | Chemin source | Base | | ------------------------ | ----------------------------- | ---------------------------- | | `tale-proxy` | `services/proxy/` | Caddy | | `tale-platform` | `services/platform/` | Bun + Debian slim | | `tale-convex` | `services/convex/` | Convex local-backend | | `tale-db` | `services/db/` | ParadeDB (Postgres) | | `tale-sandbox` | `services/sandbox/` | Bun + CLI Docker | | `tale-sandbox-egress` | `services/sandbox-egress/` | Alpine + tinyproxy | | `tale-sandbox-runtime` | `services/sandbox-runtime/` | Bun + Chromium + Playwright | | `tale-sandbox-buildkitd` | `services/sandbox-buildkitd/` | Debian + BuildKit + redsocks | | `tale-controller` | `services/controller/` | Bun + CLI Docker | Les deux conteneurs de base de données — `db` et `knowledge-db` — se construisent depuis la même image ParadeDB `tale-db` ; la différence est la base que chacun sert. La gateway LLM, `tale-sandbox-llm-gateway`, est une image amont pinnée (`maximhq/bifrost`), elle n'a donc pas de Dockerfile dans le repo. Les fichiers compose à la racine du repo (`compose.yml` pour développement, le compose de production généré par la CLI) les référencent via `ghcr.io/tale-project/tale/<image>:<tag>`. Un build local remplace le pull de registre par un bloc `build:` dans compose. ## Construire localement Un premier build de chaque image prend environ 15 minutes sur un laptop récent ; les builds suivants touchent le cache de layers de Docker et finissent en moins d'une minute pour l'image que tu as changée. ```bash # Construis chaque image dans compose.yml docker compose build # Construis une image docker compose build platform ``` Mets `PULL_POLICY=build` dans ton environnement (ou dans `.env`) pour forcer compose à construire plutôt qu'à puller l'image publiée. Le `compose.yml` livré défaut sur `build`, donc un clone local sans overrides construit déjà ; les fichiers compose de production que `tale deploy` génère défautent sur `always` et pullent depuis le registre. ## Les coutures de personnalisation Les points d'extension supportés pour les forks sont au niveau du Dockerfile. L'entrypoint de l'image et les fichiers de configuration à l'intérieur sont stables — patche-les, construis l'image, et le reste du système n'a pas besoin de savoir. - **Caddyfile** — `services/proxy/Caddyfile` contrôle le routage et la terminaison TLS. Les en-têtes personnalisés, sous-domaines personnalisés et rate limits personnalisés atterrissent ici. - **Templates plop plateforme** — `services/platform/Dockerfile` lance une étape de build qui cuit les messages, le schéma et les assets statiques. Un fork qui ship des chaînes UI personnalisées ou des routes supplémentaires construit l'image plateforme. - **Image runtime sandbox** — `services/sandbox-runtime/Dockerfile` est l'environnement d'exécution pour **Exécuter du code**, le rendu web et la génération de documents ; il embarque déjà Chromium et Playwright. Un fork qui a besoin d'un paquet système supplémentaire ou d'un build de navigateur différent patche ici. - **Proxy d'egress sandbox** — `services/sandbox-egress/tinyproxy.conf.template` est la configuration proxy que l'entrypoint rend au démarrage : egress ouvert par défaut, ou un filtre d'hôtes en refus par défaut quand `SANDBOX_EGRESS_ALLOWLIST` est défini. Un fork qui a besoin d'un autre comportement proxy patche ici. Ce qui n'est pas une couture supportée : le code applicatif du backend convex, y compris l'extraction de documents et la logique RAG et crawler qui vit désormais en in-process (`services/platform/convex/`), et le code runtime du conteneur plateforme (`services/platform/app/`). Ces fichiers sont du code applicatif, pas de la configuration — ajouter un extracteur de format de document ou changer le comportement de récupération est un vrai fork et porte la taxe de montée de version. ## Tagger et pousser vers ta propre registre Pour les distributions air-gapped ou vendorisées, le chemin est « construire, tagger, pousser vers ta registre, changer les lignes `image:` du compose ». ```bash # Construire, tagger, pousser export REGISTRY=registry.internal.example.com/tale docker compose build docker tag ghcr.io/tale-project/tale/tale-platform:latest \ $REGISTRY/tale-platform:vendored-1.0 docker push $REGISTRY/tale-platform:vendored-1.0 ``` Le déploiement de la CLI génère un fichier compose avec le chemin de registre ; soit patche le fichier généré après génération, soit saute la CLI et lance `docker compose` directement contre un fichier compose que tu maintiens toi-même. ## Rester en sync avec l'amont Le chemin bon marché est un fork sur GitHub qui merge périodiquement depuis `tale-project/tale@main`. Les conflits atterrissent dans les fichiers que tu as patchés ; le reste passe propre. Les deux anti-patterns : - **Patcher du code applicatif au lieu de le contribuer en retour.** Si le changement est largement utile, upstream une PR — chaque taxe de release descend. - **Pinner sur une vieille image de base.** Les bases Caddy, Bun et Postgres prennent les patches de sécurité à la reconstruction ; pinner la base pour la « stabilité » est emprunter des ennuis. ## Où cela s'inscrit Cette page est la couture côté contributeur de l'histoire opérateur. La vue d'ensemble de l'architecture vit dans [Architecture des conteneurs](/fr/self-hosted/operate/container-architecture) ; le workflow de montée de version qui fait tourner les images publiées est dans [Montées de version](/fr/self-hosted/operate/upgrades). Si ton fork est non-trivial, la conversation qui vaut la peine d'être lancée avant que tu n'écrives du code est celle sur le Discord ou les GitHub Discussions du projet — beaucoup de forks finissent par être des fonctionnalités qui attendent d'atterrir en amont. # Auto-hébergé Source: https://tale.dev/docs/fr/self-hosted Tale auto-hébergé tourne sur ta propre infrastructure — on-premise, dans ton VPC, ou coupé du réseau. Sept conteneurs, tes données sur ton stockage, aucune facturation au siège, et aucun trafic qui rejoint les serveurs de Tale, sauf si tu y pointes un fournisseur. Cette section s'adresse aux opérateurs : les personnes qui décident où Tale tourne, l'installent, le configurent, le maintiennent à jour et récupèrent le pager quand quelque chose va de travers. Les utilisateurs finaux des instances auto-hébergées lisent surtout l'onglet Plateforme — la surface produit est identique entre les éditions. ## Pages de cette section **[Vue d'ensemble de l'architecture](/fr/self-hosted/overview)** — ce que fait chaque conteneur, où vivent les données sur le stockage, qui parle à qui. **[Installation](/fr/self-hosted/install/quickstart)** — quickstart sur portable, installation de production sur un hôte Linux, la référence docker compose, premier admin, l'installateur du CLI. **[Configuration](/fr/self-hosted/configuration/environment-reference)** — chaque variable d'environnement, fichiers de fournisseur, modes d'authentification, TLS, stockage, rétention, secrets chiffrés par SOPS, observabilité. **[Exploitation](/fr/self-hosted/operate/container-architecture)** — montées de version, sauvegardes et restauration, observabilité et dépannage, avis de sécurité, durcissement, format des notes de version. **[Contribuer](/fr/self-hosted/contributing-docker)** — comment construire et tester une modification locale de conteneur. ## Où cela s'inscrit Auto-hébergé est l'édition où l'opérateur possède davantage de la stack. Si ton équipe est petite et que la charge d'exploitation écraserait le travail produit, [Cloud](/fr/cloud) est l'autre forme du même produit. Si tu montes une instance neuve maintenant, [Quickstart](/fr/self-hosted/install/quickstart) est la lecture suivante adéquate. # Montées de version Source: https://tale.dev/docs/fr/self-hosted/operate/upgrades Les montées de version sur une instance Tale auto-hébergée passent par deux commandes : `tale update` bouge le binaire CLI à la nouvelle version et synchronise tes fichiers projet pour correspondre, puis `tale deploy` roule les conteneurs plateforme. Le déploiement utilise un pattern blue-green — la nouvelle couleur démarre à côté de l'ancienne, les healthchecks passent, le trafic bascule, l'ancienne couleur draine. Zéro downtime est le défaut ; si une release patch se comporte mal, `tale rollback` ramène le patch précédent en une commande, et tout ce qui est plus gros se récupère depuis le snapshot pré-upgrade. **Une exception dure :** il n'existe aucun chemin de montée de version de 0.3.x vers 0.4. La 0.4 est une rupture qui exige un déploiement neuf — lis [0.3 → 0.4 : rupture de version](#03--04--rupture-de-version) avant toute chose si ton instance est en 0.3.x. Ce que tu ne fais plus, c'est garder la CLI synchronisée à la main : la CLI s'aligne elle-même sur l'instance automatiquement (voir plus bas), donc le seul pas délibéré est de choisir quand bouger de version avec `tale update`. L'installation de la CLI vit dans [Installer la CLI tale](/fr/self-hosted/install/cli-install). Cette page couvre ce que fait chaque commande et comment le modèle de versions fonctionne. ## La CLI suit l'instance automatiquement Le binaire CLI est toujours à la même version que l'instance qu'il gère. Le workspace enregistre cette version dans `tale.json` ; à chaque commande, la CLI compare sa propre version à celle-là et, si elles diffèrent, se met à jour pour correspondre (en montant ou en descendant) avant de tourner. Quand elles correspondent déjà — le cas largement le plus fréquent — c'est un no-op sans appel réseau, donc tu ne le remarques jamais. Cela veut dire que tu lances rarement `tale update`, sauf quand tu veux délibérément bouger vers une nouvelle version. Un coéquipier qui a installé une CLI plus récente que ton instance, ou restauré un snapshot plus ancien, obtient la bonne version de CLI automatiquement à sa prochaine commande. Il n'y a aucun flag pour désactiver ça — garder l'outil et l'instance au pas l'un de l'autre est ce qui rend les déploiements sûrs. ## Avant de monter de version Deux choses valent la peine d'être confirmées d'abord : - Ta copie hors-hôte du volume `backups` est à jour — voir [Backups et restauration](/fr/self-hosted/operate/backups-and-restore). `tale update` snapshotte automatiquement les volumes de données avant toute étape qui peut migrer des données, mais le snapshot vit sur le même hôte ; la copie hors-hôte est ce qui survit à un disque mort. - Les notes de version pour la version cible ne nomment pas un changement breaking. Les notes sont liées depuis la page de release GitHub ; les changements breaking sont flaggés comme tels en haut. Si la montée de version traverse une version majeure (1.x → 2.x), lis les notes de migration de bout en bout avant de commencer. Les versions majeures sont où atterrissent les migrations de schéma et les changements de format de fichier de config. ## Les deux commandes `tale update` met à jour le binaire CLI, puis synchronise tes fichiers projet sur les templates de cette version. Il ne **touche pas** aux conteneurs en marche — c'est le boulot de `tale deploy`. Si la synchro des fichiers échoue, la CLI fait reculer son propre binaire à la version sur laquelle ton workspace était, pour que le binaire et `tale.json` ne dérivent jamais l'un de l'autre. Lancée sans argument, la commande vise la release la plus récente **de ta ligne x.y actuelle** — une instance 0.3.x bouge vers la 0.3.x la plus récente. Les releases d'une ligne plus récente peuvent porter des changements breaking, donc la commande ne franchit jamais cette frontière d'elle-même : quand une ligne plus récente existe, elle le dit et reste en place. Changer de ligne est un pas délibéré — lis d'abord les notes de version de la nouvelle ligne, puis fixe la version cible avec `--version`. ```bash # Bouge la CLI et les fichiers projet à la release la plus récente de la ligne x.y actuelle tale update # Fixe une version précise — le seul moyen de changer de ligne (autorise les downgrades — voir Rollback) tale update --version 0.10.2 # Aperçu du changement de version et de la synchro des fichiers sans rien toucher tale update --dry-run ``` `tale deploy` fait le vrai redémarrage rolling, et il déploie toujours la version propre à la CLI — qui, grâce à l'alignement, est la version qu'enregistre ton workspace. Il trie les services en trois étages : - **Étage app** — `platform` — roule à **chaque** déploiement, sans downtime (blue-green : la nouvelle couleur démarre à côté de l'ancienne, les healthchecks passent, le trafic bascule, l'ancienne couleur draine). - **Backend et compute** — `convex`, `sandbox`, `sandbox-egress` — roulent à chaque déploiement eux aussi, pour ne jamais dériver en version d'avec `platform`. Chacun est un conteneur unique qui se recrée **en place** quand son image a réellement changé ; le déploiement draine d'abord le travail en cours (générations de chat pour `convex`, runs d'agent pour `sandbox`) pour que le bref redémarrage ne coupe pas une requête en vol. - **Étage à arrêt requis** — `db`, `proxy` — laissés **en marche et intacts** par défaut (recréer Postgres ou le proxy est une brève coupure que tu ne veux pas sur un roll de routine). Passe `--stop` pour les mettre à jour ; le déploiement prévient et les nomme quand il les saute. ```bash # Après tale update, roule les conteneurs pour correspondre (étage app + convex) tale deploy # Mets aussi à jour db/proxy (brève coupure pendant qu'ils se recréent) tale deploy --stop # Roule seulement des services spécifiques tale deploy --services platform # Aperçu sans changement tale deploy --dry-run ``` `--dry-run` mérite d'être lancé avant chaque montée de version en production — il fait remonter les images manquantes, les migrations manquantes et les mismatches de dépendances sans toucher aux conteneurs en marche. ## Le pattern blue-green Une instance en marche est l'une des deux couleurs (blue ou green) à un instant donné. La phase de déploiement monte l'autre couleur, attend qu'elle passe les healthchecks, puis bascule l'upstream de Caddy sur la nouvelle couleur. L'ancienne couleur draine ses requêtes en vol (défaut 30 s), puis sort. Trois garanties que le pattern te donne : - **Aucune fenêtre où les deux couleurs servent du trafic.** Un constraint de base impose single-active — Caddy route vers la saine. - **Le rollback de patch est une commande.** `tale rollback` redéploie la release patch précédente sur la couleur inactive et rebascule le trafic. Il refuse les downgrades minor et major — ceux-là peuvent laisser la base en avance sur le binaire, et leur chemin de récupération est une restauration de snapshot. - **Les healthchecks échoués bloquent la bascule.** Si la nouvelle couleur ne passe pas dans le timeout, le déploiement abandonne et l'ancienne couleur continue à servir. La procédure complète de déploiement, y compris la phase de cleanup, vit dans `tale --help` ; la recette côté opérateur est `tale update && tale deploy && tale status` et confirmation visuelle dans le navigateur. ## Travailler avec les migrations de données La chaîne de migrations démarre à la **baseline 0.4.0** : les releases à partir de la 0.4.0 embarquent des migrations versionnées pour les changements qu'elles livrent, et rien de plus ancien — l'historique pré-0.4 n'est dans aucun binaire (c'est ce qui rend la rupture 0.3 → 0.4 définitive). Au sein de la ligne 0.4.x, chaque déploiement applique automatiquement les migrations de données en attente — mais seulement celles qui ne détruisent rien. Les migrations qui suppriment ou écrasent des données (suppression d'une table, retrait d'une colonne) ne tournent jamais sans surveillance : le déploiement les saute, affiche celles qui attendent et vous laisse la décision. ```bash # Ce qui est appliqué, en attente, en échec tale migrate status # Appliquer les migrations en attente, en validant chaque étape destructrice tale migrate up --step # Tout appliquer sans confirmation (CI / après revue du plan) tale migrate up --yes # Ramener les données à une version antérieure (0.4.0 ou plus récente) tale migrate down --to 0.4.0 ``` Les migrations destructrices sauvegardent les lignes ou fichiers de configuration concernés avant d'y toucher : `tale migrate down` peut ainsi reconstruire ce qu'elles ont retiré. Les deux sens sont reprenables : la progression est suivie par migration (et par organisation pour les migrations de fichiers de configuration), un crash ou un timeout reprend donc là où il s'était arrêté. Si une migration échoue pendant un déploiement, la plateforme démarre quand même sur son schéma actuel — le journal de démarrage affiche une erreur bien visible et `tale migrate status` montre la migration en échec avec son message. Corrigez la cause, puis relancez `tale migrate up` ; le travail déjà accompli est sauté. ## Rollback ```bash # Retour à la version patch précédente (demande confirmation) tale rollback # Ignorer l'invite en mode non-interactif tale rollback --yes ``` `tale rollback` est limité aux pas de patch : il ne cible que la version précédente enregistrée, et refuse si cette version ne partage pas `major.minor` avec la plateforme qui tourne. Les releases patch ne portent jamais de migrations, donc redéployer le patch précédent est toujours sûr. Tout ce qui est plus gros peut avoir migré les données vers l'avant — déployer un binaire plus vieux sur des données migrées corrompt l'instance au lieu de la sauver. Pour ces cas, le chemin de récupération est de restaurer le snapshot pré-upgrade et de revenir à la version qui lui correspond avec `tale update --version <version>` suivi de `tale deploy --stop` (pour que `db`/`proxy` reculent aussi) ; le message de refus imprime les commandes exactes, et le walk complet vit dans [Backups et restauration](/fr/self-hosted/operate/backups-and-restore). Comme le rollback démolit les conteneurs en cours d'exécution, la commande prévient de ce qu'elle s'apprête à faire et demande confirmation avant de tirer la moindre image ; passe `--yes` pour ignorer cette invite dans les scripts ou en CI. ## Compatibilité de versions Les versions Tale sont en semver. Les règles de compatibilité : - Patch (`0.9.0 → 0.9.1`) — pas de migrations, pas de changements de config, `tale rollback` est toujours sûr. - Minor (`0.9.x → 0.10.x`) — peut inclure des migrations forward-only ; `tale rollback` refuse, la récupération est restauration-de-snapshot plus redéploiement. - Major (`0.x → 1.x`) — lis les notes de migration, planifie la fenêtre de maintenance, attends-toi à des surprises. - **La baseline 0.4.0** — les versions sous la 0.4.0 et les versions à partir de la 0.4.0 sont deux mondes séparés : aucune montée ni descente entre eux, voir la section rupture ci-dessous. Sauter des versions mineures (passer de 0.9 à 0.11) est supporté tant que les migrations intermédiaires sont encore dans le binaire ; les notes de version le mentionnent quand ce n'est pas le cas. La baseline 0.4.0 est le cas permanent de cette exception : les migrations pré-0.4 ne sont dans aucun binaire 0.4+. Pour descendre _délibérément_ d'une version — disons qu'une release minor se comporte mal et que tu as déjà inversé ses migrations — fixe la cible avec `tale update --version <version>`. La commande prévient quand la cible est plus ancienne que la version qui tourne et te rappelle d'inverser d'abord les migrations de données. Descendre sous la 0.4.0 traverse la rupture à rebours et n'est pas supporté : une release 0.3.x ne peut pas lire des données créées par la 0.4+ — restaure un snapshot pré-0.4 ou déploie la 0.3.x à neuf. ## 0.3 → 0.4 : rupture de version La 0.4 a reconstruit le backend IA de la plateforme, et avec lui le modèle de données, depuis une baseline propre. L'historique des migrations versionnées a été remis à zéro à la 0.4.0 : aucune release 0.4+ n'embarque les migrations pré-0.4, donc **une instance 0.3.x ne peut pas être montée en place — la 0.4 exige un déploiement neuf.** **Ce que ça veut dire concrètement :** - `tale deploy` avec une CLI 0.4+ **refuse** de toucher une instance dont la version qui tourne est sous la 0.4.0, avant de tirer une image ou d'écrire quoi que ce soit. Le conteneur porte la même garde au démarrage (marqueur de log `[migrations][breaking-cutover]`) pour les stacks gérées hors CLI. - Rien d'une instance 0.3 n'est repris : chats, automatisations et leur historique d'exécution, entrées de connaissance, historique des tâches, utilisateurs et connexions. Les fichiers d'un bucket BYO-S3 restent physiquement dans le bucket, mais la nouvelle instance n'a aucune référence vers eux. - La ligne 0.3.x reste maintenue pour la sécurité et les correctifs critiques sur la branche `release/0.3` — rester en 0.3.x un moment est un choix supporté ; passer à la 0.4 est un ré-embarquement, pas une montée de version. **Passer à la 0.4 :** ```bash # 1. Laisser l'instance 0.3 intacte (elle continue de servir). # 2. Créer un NOUVEAU répertoire projet avec une CLI 0.4 : mkdir tale-04 && cd tale-04 tale init tale deploy # 3. Ré-embarquer : organisations, utilisateurs (invitation / SSO), # configuration, re-téléversement des documents et connaissances. # 4. Décommissionner l'instance 0.3 une fois la nouvelle validée. ``` Le contournement expert — `tale deploy --accept-data-loss`, ou `TALE_ACCEPT_DATA_LOSS=1` sur le conteneur — existe pour le cas rare où tu réutilises délibérément un hôte dont tu as déjà traité les anciens volumes. Il fait exactement ce que son nom dit : les données pré-0.4 de cette instance deviennent définitivement illisibles. ## Où cela s'inscrit Le flow de montée de version noue chaque autre page d'exploitation — les backups sont ce qui rend une montée de version échouée récupérable, l'observabilité est ce qui te dit que la nouvelle couleur est saine, le durcissement est ce que tu reparcours après une version majeure. Si tu mets en place la CLI pour la première fois, [Installer la CLI tale](/fr/self-hosted/install/cli-install) couvre le setup côté workstation ; si tu prends le pager en plein rollout, [Dépannage](/fr/self-hosted/operate/observability/troubleshooting) nomme les symptômes. # Dépannage Source: https://tale.dev/docs/fr/self-hosted/operate/observability/troubleshooting Cette page est la recherche par symptôme quand quelque chose ne va pas, là, tout de suite. Chaque section commence par ce que l'utilisateur rapporte réellement — ce que le navigateur affiche, sur quoi l'agent échoue, ce que l'écran de téléversement dit — et remonte à la cause et au fix. Tout ce qui n'est pas listé ici est candidat pour une nouvelle section dès qu'il s'est présenté deux fois. Le côté proactif — signaux qui méritent une alerte, ce qu'il faut câbler à Prometheus — vit dans [Opérations](/fr/self-hosted/operate/observability/operations). Cette page est pour le moment après que la page a sonné. ## Le navigateur voit 502 ou « Bad Gateway » Le conteneur `tale-proxy` a joint la plateforme, mais la plateforme n'a pas répondu. Soit `tale-platform` est down, soit son endpoint de santé est injoignable. Vérifie l'état du conteneur en premier : ```bash docker compose ps tale-platform docker compose logs --tail=200 tale-platform ``` Si le conteneur redémarre, les logs en bas montrent la raison du crash — habituellement une variable d'env mal configurée (mismatch `SITE_URL`, `BETTER_AUTH_SECRET` manquant) ou un échec de connexion Postgres. Fix l'env, redémarre, réessaie. Si le conteneur est sain mais que le navigateur voit encore 502, le proxy est le suspect — `docker compose restart tale-proxy` règle la plupart. ## Le navigateur voit un avertissement TLS `TLS_MODE=selfsigned` est la cause la plus commune — le navigateur ne fait pas confiance à la CA interne de Caddy à la première visite. Soit fais confiance à la CA sur l'hôte (`docker exec tale-proxy caddy trust`), soit bascule sur `TLS_MODE=letsencrypt` pour un vrai certificat. Le walk complet des modes vit dans [TLS et domaines](/fr/self-hosted/configuration/tls-and-domains). Si le mode est déjà `letsencrypt`, vérifie les logs du proxy pour les échecs ACME — DNS qui ne résout pas vers l'IP publique de l'hôte et port 80 injoignable depuis l'Internet public sont les deux causes communes. ## L'UI charge mais aucune donnée n'apparaît Le shell UI sont des assets statiques servis par `tale-platform` ; tout le reste circule par `tale-convex` sur un WebSocket. Quand le WebSocket ne peut pas se connecter, le shell charge et reste vide. Symptômes : spinners qui ne se résolvent jamais, toasts « reconnecting », le champ de chat qui n'accepte jamais un message. ```bash docker compose logs --tail=200 tale-convex ``` Le conteneur convex redémarre probablement (cherche `panic` dans les logs) ou est injoignable depuis le proxy. Redémarre avec `docker compose restart tale-convex` — les sessions sont côté serveur et les clients se réabonnent à la reconnexion, donc le redémarrage est sûr. ## Téléversements bloqués en « indexation » L'ingestion de documents tourne dans le backend Convex et écrit les fragments extraits et les embeddings dans la base du corpus de connaissances. Un long état « indexation » signifie soit que le backend ne peut pas joindre `tale-knowledge-db`, soit que le fichier lui-même n'a pas pu être extrait. Vérifie les logs convex et la base du corpus en premier : ```bash docker compose logs --tail=200 tale-convex | grep -iE "knowledge|ingest|embed" docker compose ps tale-knowledge-db ``` Si les logs montrent des erreurs de connexion à `knowledge-db`, redémarre la base du corpus (`docker compose restart tale-knowledge-db`) ; l'ingestion retente à la passe suivante, donc les téléversements n'ont pas à être re-soumis. Si la base est saine mais qu'un téléversement spécifique est bloqué, le fichier lui-même est le suspect — les PDFs corrompus et les documents protégés par mot de passe atterrissent en état d'échec et exigent suppression + re-téléversement. ## Les réponses chat s'arrêtent au milieu du stream Le stream de tokens depuis le fournisseur amont est tombé — soit le fournisseur a rate-limité, soit la connexion a timeouté, soit le service du fournisseur est dégradé. Vérifie la page de statut du fournisseur d'abord ; puis regarde dans les logs plateforme : ```bash docker compose logs --tail=200 tale-platform | grep -E "429|503|stream" ``` Un `429` est le cas commun. Soit le budget de l'org touche le rate limit du fournisseur, soit la clé fournisseur elle-même est throttlée. Basculer le modèle par défaut de l'org sur un fournisseur moins chargé efface le symptôme pendant que l'amont refroidit. ## La sauvegarde échoue avec un toast « saving failed » Le conteneur convex n'a pas pu écrire dans Postgres. Soit `tale-db` est down, soit son disque est plein : ```bash docker compose ps tale-db docker compose exec db df -h /var/lib/postgresql/data ``` Un disque à 100 % est l'échec qui produit le plus de visages surpris. Libère de l'espace, redémarre `tale-db`, et les écritures en file flushent. Si le disque a de l'espace, le suspect est l'épuisement du pool de connexions ou un lock — redémarre `tale-convex` pour vider le pool. ## L'outil « Exécuter du code » échoue avec « egress denied » Le conteneur `tale-sandbox-egress` est le seul chemin réseau sortant pour le code en sandbox ; s'il est down ou mal configuré, chaque requête sortante de la sandbox échoue en mode fermé. Vérifie le conteneur egress d'abord : ```bash docker compose ps tale-sandbox-egress docker compose logs --tail=100 tale-sandbox-egress ``` Si le conteneur est sain et que tu as défini `SANDBOX_EGRESS_ALLOWLIST`, la requête a touché l'allowlist — étends la variable dans `.env` et recrée `tale-sandbox-egress`. Sans allowlist, le proxy est ouvert au niveau des hôtes ; vérifie plutôt la cible : seul le port 443 est tunnelisé pour HTTPS, et les adresses de métadonnées cloud et de plages privées sont toujours bloquées au niveau IP. ## Le sign-in revient en boucle à l'écran de sign-in `SITE_URL` ne correspond pas à ce que le navigateur a effectivement demandé. Les cookies d'auth sont scope sur l'URL où la requête a atterri ; un mismatch (slash en queue, port manquant, `http` vs `https`, préfixe base-path) signifie que le cookie posé au callback n'est pas envoyé à la prochaine requête. Fix `.env` : ```bash SITE_URL=https://tale.example.com # exactement ce que l'utilisateur tape ``` Recrée le conteneur plateforme (`docker compose up -d --force-recreate tale-platform`) pour que le changement atterrisse dans le HTML rendu. ## Où obtenir de l'aide Les instances auto-hébergées ne téléphonent pas à la maison, donc le support commence chez toi. Les deux canaux : - **GitHub Issues** — bugs et problèmes reproductibles. Le tracker [tale-project/tale](https://github.com/tale-project/tale/issues) a un template qui demande le bundle de diagnostics que `tale diagnostics` produit. - **Discord** — questions, débats de configuration, triage « est-ce un bug ». L'invitation vit dans le README du repo. Des diagnostics reproductibles rendent chaque canal plus rapide. `tale diagnostics` collecte les logs assainis, les variables d'env (secrets caviardés) et la santé des conteneurs dans une archive unique qui vaut la peine d'être attachée. # Opérations Source: https://tale.dev/docs/fr/self-hosted/operate/observability/operations La page opérations est le playbook d'alerte — quels signaux valent la peine de réveiller quelqu'un, lesquels peuvent attendre un café, et à quoi ressemblent les cinq premières minutes d'un incident. La surface de métriques de Tale vit derrière `METRICS_BEARER_TOKEN` ; cette page suppose que tu as câblé Prometheus et Grafana selon [Configuration de l'observabilité](/fr/self-hosted/configuration/observability-config) et qu'il te faut maintenant savoir quels chiffres regarder. L'index par symptôme est dans [Dépannage](/fr/self-hosted/operate/observability/troubleshooting). Cette page est le côté proactif — signaux d'abord, checklist d'astreinte ensuite. ## Signaux qui méritent une alerte | Signal | Sévérité | Pourquoi ça compte | | ---------------------------------------------- | -------- | --------------------------------------------------------------- | | Sonde de santé `tale-proxy` en échec > 1 min | page | Chaque utilisateur voit une erreur de connexion | | Taux HTTP 5xx `tale-platform` > 5 % | page | L'UI est cassée pour une part significative des requêtes | | Tempête de reconnexion WebSocket `tale-convex` | page | L'UI charge mais aucune donnée ne circule | | Connexions Postgres > 80 % du pool | warn | Le prochain pic va commencer à bloquer | | Volume `db-data` > 80 % plein | warn | Le Postgres opérationnel passe en lecture seule à plein | | Volume `knowledge-db-data` > 80 % plein | warn | L'ingestion échoue quand la base du corpus est pleine | | `tale-knowledge-db` injoignable depuis convex | warn | La recherche de connaissances renvoie vide ; l'ingestion stagne | | Taux d'erreur de requête fournisseur > 20 % | warn | Le fournisseur LLM amont passe une mauvaise journée | | Backup quotidien non écrit | page | Le drill de restauration échouera au pire moment | | Renouvellement de cert TLS échoué | warn | Renouvelle 30 j avant l'expiration — tu as le temps | Les deux premières pages sont les seules réellement client-impactantes. Les warns attrapent les tendances avant qu'elles ne basculent dans le territoire page. ## Signaux de logs à grepper Les logs arrivent par stdout par conteneur, capturés par le driver `json-file` de Docker. Les quatre phrases qui signifient consistamment un souci : - `panic` ou `unexpected error` dans les logs `tale-convex` — crash d'action Convex. - `decryption failed` dans les logs `tale-platform` — mismatch entre clé age SOPS et fichier sur disque. - `429 Too Many Requests` répété d'un fournisseur — rate limit atteint, les agents vont commencer à échouer. - `connection refused` ou `ECONNREFUSED` vers `knowledge-db` dans les logs `tale-convex` — le backend ne peut pas joindre la base du corpus ; l'ingestion et la recherche de connaissances échouent. Pipe ceux-ci vers ton aggregator comme alertes dérivées ; les endpoints de métriques ne les exposent pas comme gauges. ## Checklist d'astreinte Quand une page atterrit, les cinq premières minutes suivent la même forme à chaque fois. 1. **Confirme que l'alerte est réelle.** Ouvre `$SITE_URL` dans un navigateur. Si l'UI charge et que le chat marche, tu regardes un souci de métriques ou de scraper, pas un client-impactant. 2. **Identifie le conteneur.** `docker compose ps` montre lequel est unhealthy ; `docker compose logs --tail=200 <service>` montre la dernière erreur. 3. **Redémarre le coupable le plus probable.** `docker compose restart <service>` résout une fraction surprenante des incidents — crashs de processus, watchers de fichiers périmés, pools de connexion épuisés. L'architecture est construite pour survivre proprement à un redémarrage de conteneur unique. 4. **Vérifie les fournisseurs amont.** `https://status.openai.com`, `https://status.anthropic.com`, etc. Si le fournisseur brûle, les agents échouent ; Tale n'est pas la cause. 5. **Page l'ingénieur d'astreinte si le symptôme côté utilisateur persiste après un redémarrage.** Pas besoin d'escalader plus tôt — la plupart des incidents se résolvent dans les trois premières étapes. ## Ce qui n'a pas besoin d'astreinte Une panne de `tale-knowledge-db` est un warn, pas un page. Le planning du crawl web absorbe des heures de downtime sans impact utilisateur, et l'ingestion de documents retente plutôt que de jeter le travail — les téléversements restent en « indexation » jusqu'au retour de la base du corpus. La recherche de connaissances renvoie vide entre-temps, mais les chats qui ne récupèrent pas de connaissances continuent de marcher. Attrape ça dans la bande warn et corrige-le pendant les heures de bureau. ## SLA de temps de réponse Deux budgets de temps de réponse sont suivis comme signaux de premier ordre : la saisie de dialogue interactive et les opérations longues comme les évaluations. Les deux sont vérifiés comme une **moyenne** sur une fenêtre glissante — le chiffre contractuel est une moyenne, pas un plafond par requête — et les deux sont câblés pour que Prometheus alerte dès que la moyenne dérive au-delà du budget. | Budget | Statistique | Cible | Fenêtre | Série sous-jacente | | ---------------- | ----------- | ----- | ------- | ----------------------------- | | Saisie dialogue | moyenne | ~1 s | 30 min | `tale_dialog_ttft_seconds` | | Opération longue | moyenne | ~40 s | 6 h | `tale_long_operation_seconds` | Chaque cible chevauche aussi l'endpoint de métriques de la plateforme sous `tale_sla_target_seconds{sla,statistic}`, pour qu'un panel Grafana trace la ligne de budget directement depuis Prometheus au lieu de la coder en dur. Les séries de latence sous-jacentes sont les histogrammes d'exécution de fonction Convex sur `/metrics/convex` ; relabel ou record-les vers les noms ci-dessus pour que les rules se résolvent. La plateforme sert les rules de recording et d'alerting prêtes à l'emploi sous `/metrics/sla-rules` (derrière le même bearer token que les autres chemins de métriques) — récupère-le une fois et référence le fichier sous `rule_files:`, ou colle l'équivalent : ```yaml groups: - name: tale-sla-recording rules: - record: tale_sla_dialog_ttft:mean30m expr: rate(tale_dialog_ttft_seconds_sum[30m]) / rate(tale_dialog_ttft_seconds_count[30m]) labels: sla: dialog_ttft - record: tale_sla_long_operation:mean6h expr: rate(tale_long_operation_seconds_sum[6h]) / rate(tale_long_operation_seconds_count[6h]) labels: sla: long_operation - name: tale-sla-alerts rules: - alert: TaleSlaDialogTtftBreached expr: tale_sla_dialog_ttft:mean30m > 1 for: 15m labels: severity: warn sla: dialog_ttft annotations: summary: 'Dialog input response time: mean response time over 30m exceeds the 1s SLA' description: Mean time-to-first-token for an interactive chat / dialog turn. - alert: TaleSlaLongOperationBreached expr: tale_sla_long_operation:mean6h > 40 for: 30m labels: severity: warn sla: long_operation annotations: summary: 'Long operation response time: mean response time over 6h exceeds the 40s SLA' description: Mean end-to-end time for long-running operations such as evaluations. ``` Un breach ici est un **warn**, pas un page : une moyenne qui dérive est une dégradation à traiter pendant les heures de bureau, et les fenêtres `for:` attendent délibérément qu'un pic court s'estompe avant de déclencher. Le budget dialogue de ~1 s se réconcilie avec le time-to-first-token chaud plus lâche de ~3 s du plan de performance manuel — ces ~3 s sont un plafond par requête pour un seul premier token froid (le premier delta texte SSE du fournisseur), routé en Auto, temps modèle et réseau inclus, alors que les ~1 s ici sont la moyenne en régime permanent sur les tours de dialogue, donc des premiers tokens atteignant occasionnellement le plafond restent compatibles avec une moyenne sous la seconde. Tenir la moyenne de 1 s sur des fournisseurs live peut encore exiger l'optimisation du surcoût backend suivie sur l'issue de fonctionnalité ; cette alerte est ce qui confirme si la cible est atteinte. ## Où cela s'inscrit Les signaux ci-dessus sont le côté proactif d'opérer une instance Tale ; le côté réactif est [Dépannage](/fr/self-hosted/operate/observability/troubleshooting), et la configuration qui fait passer les métriques dans Prometheus est [Configuration de l'observabilité](/fr/self-hosted/configuration/observability-config). Si tu n'as pas encore réglé `METRICS_BEARER_TOKEN`, chaque seuil ci-dessus est non surveillé — commence par là. # Prometheus et Grafana Source: https://tale.dev/docs/fr/self-hosted/operate/observability/prometheus-grafana C'est l'exemple mis en pratique derrière [Configuration de l'observabilité](/fr/self-hosted/configuration/observability-config) : une paire Prometheus et Grafana que tu poses à côté de Tale, pointée sur les deux endpoints de métriques à bearer token, avec un tableau de bord de départ et une règle d'alerte à étoffer. C'est pour les opérateurs auto-hébergés qui ont déjà défini `METRICS_BEARER_TOKEN` et veulent maintenant des graphes en direct plutôt qu'un `curl` contre `/metrics`. La page de référence de configuration liste les endpoints et la stanza de scrape unique ; cette page monte tout le stack de bout en bout. Tout ici tourne sur le même hôte que Tale, donc aucune métrique ne quitte la machine. ## Avant de commencer Définis `METRICS_BEARER_TOKEN` dans ton `.env` et redémarre le proxy — sans lui, les deux endpoints renvoient 401 à chaque requête, et Prometheus affichera chaque cible comme down. Les endpoints, et ce que chacun porte, sont le tableau dans [Configuration de l'observabilité](/fr/self-hosted/configuration/observability-config#metrics) : `/metrics/platform` et `/metrics/convex` (ce dernier porte désormais les timings RAG et de crawl en in-process), tous deux servis par `tale-proxy` sur le même nom d'hôte que l'app. ## Ajouter Prometheus et Grafana à ta stack Pose ces deux services dans un override compose à côté de Tale. Prometheus scrape à un intervalle et stocke une TSDB locale ; Grafana lit Prometheus et rend les tableaux de bord. Les deux se lient à localhost uniquement — atteins Grafana via un tunnel SSH ou mets-le derrière le même proxy avec auth, ne l'expose jamais brut. ```yaml # docker-compose.metrics.yml — start with: docker compose -f docker-compose.yml -f docker-compose.metrics.yml up -d services: prometheus: image: prom/prometheus:v3.1.0 volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro - prometheus-data:/prometheus ports: - '127.0.0.1:9090:9090' restart: unless-stopped grafana: image: grafana/grafana:11.4.0 environment: GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD:?set a strong password} GF_USERS_ALLOW_SIGN_UP: 'false' volumes: - grafana-data:/var/lib/grafana ports: - '127.0.0.1:3001:3000' restart: unless-stopped volumes: prometheus-data: grafana-data: ``` ## Configuration du scraping Les deux endpoints de Tale partagent un bearer token, donc la config de scrape est la stanza publiée, répétée une fois par chemin. Enregistre ceci comme `prometheus.yml` à côté de l'override ci-dessus et substitue ton hôte et ton token — Prometheus lit le token depuis le fichier, garde-le donc en `chmod 600` et hors du contrôle de version. ```yaml global: scrape_interval: 30s scrape_configs: - job_name: tale-platform scheme: https metrics_path: /metrics/platform authorization: { credentials: '${METRICS_BEARER_TOKEN}' } static_configs: - targets: ['tale.example.com'] - job_name: tale-convex scheme: https metrics_path: /metrics/convex authorization: { credentials: '${METRICS_BEARER_TOKEN}' } static_configs: - targets: ['tale.example.com'] ``` Ouvre `http://127.0.0.1:9090/targets` après le démarrage — les deux jobs devraient afficher **UP**. Une cible bloquée en **DOWN** avec un 401 signifie que le token dans `prometheus.yml` ne correspond pas à `METRICS_BEARER_TOKEN` ; une erreur de connexion signifie que le nom d'hôte ou le schéma est faux. ## Un tableau de bord de départ Pointe d'abord Grafana sur Prometheus — ajoute une source de données Prometheus à `http://prometheus:9090` (Grafana l'atteint par le nom de service compose). Construis ensuite un tableau de bord à partir de ces panneaux ; les trois premiers utilisent des métriques toujours présentes, et le reste correspond aux signaux dans [Opérations](/fr/self-hosted/operate/observability/operations). | Panneau | Requête | Se lit comme | | ------------------- | ---------------------------------------------------- | --------------------------------------------------- | | Cibles up | `up{job=~"tale-.*"}` | `1` par endpoint sain, `0` quand le scraping échoue | | Mémoire plateforme | `process_resident_memory_bytes{job="tale-platform"}` | Mémoire résidente du conteneur platform | | Lag de l'event-loop | `nodejs_eventloop_lag_seconds{job="tale-platform"}` | Bondit quand la plateforme est saturée | | Convex up | `up{job="tale-convex"}` | Joignabilité du backend — `0` est un page | L'endpoint platform porte les métriques de processus par défaut de Node (CPU, mémoire, lag de l'event-loop, GC), c'est pourquoi les requêtes concrètes ci-dessus le ciblent. L'endpoint Convex expose sa propre série plus riche, dont les timings RAG et de crawl en in-process — ouvre-le une fois (`curl -H "Authorization: Bearer $TOKEN" https://tale.example.com/metrics/convex`) pour lire les noms de métriques exacts qu'expose ta version, puis ajoute des panneaux pour le débit d'ingestion de connaissances et le taux d'erreur fournisseur évoqués dans Opérations. ## Une première règle d'alerte Commence par le seul signal sans ambiguïté — une cible de métriques qui cesse de répondre. Ajoute ce fichier de règle à Prometheus (monte-le et référence-le sous `rule_files:` dans `prometheus.yml`), puis câble Alertmanager ou l'alerting Grafana sur ton pager. ```yaml groups: - name: tale rules: - alert: TaleTargetDown expr: up{job=~"tale-.*"} == 0 for: 2m labels: { severity: page } annotations: summary: 'Tale metrics target {{ $labels.job }} is down' ``` La liste complète de ce qui vaut un page contre ce qui peut attendre — taux de 5xx de la plateforme, saturation du pool Postgres, joignabilité de la base de connaissances, sauvegarde-quotidienne-non-écrite — est le tableau de signaux dans [Opérations](/fr/self-hosted/operate/observability/operations) ; traduis chaque ligne en règle dès que la série correspondante est sur ton tableau de bord. ## Où cela s'inscrit Cette page transforme les deux endpoints de métriques documentés en un stack Prometheus et Grafana qui tourne : un override compose, une config de scrape à deux jobs, un tableau de bord de départ et une alerte cible-down que tu étoffes avec les seuils d'Opérations. Garde les deux services liés à localhost et le bearer token hors du disque en clair, et toute la surface de monitoring reste sur l'hôte avec Tale. Les endpoints et le token qui les protège appartiennent à [Configuration de l'observabilité](/fr/self-hosted/configuration/observability-config) ; les seuils et la checklist d'astreinte sont [Opérations](/fr/self-hosted/operate/observability/operations). Quand un panneau passe au rouge, la recherche symptôme-vers-correction est [Dépannage](/fr/self-hosted/operate/observability/troubleshooting). # Architecture des conteneurs Source: https://tale.dev/docs/fr/self-hosted/operate/container-architecture Une instance Tale, ce sont huit conteneurs câblés par docker compose. La page d'architecture a couvert à quoi sert chaque conteneur ; cette page-ci est la version de l'opérateur — quel conteneur possède quel travail, comment un message chat y circule et à quoi ressemble le mode de défaillance quand l'un d'eux meurt. Lis ceci quand tu es d'astreinte. Reviens-y quand tu décides quel conteneur rouler en premier pendant une montée de version. ## Les huit conteneurs, avec leurs tâches | Conteneur | Tâche | Une panne affecte | | -------------------------- | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | | `tale-proxy` | Terminaison TLS + routage en bordure | Tous les ingress — aucun client ne joint l'UI | | `tale-platform` | Serveur UI, livraison des assets statiques | Le navigateur voit 502 ; l'API reste joignable | | `tale-convex` | Actions/queries/mutations backend + WebSocket, plus RAG, crawling et génération de documents en in-process | L'UI charge mais sans données ; les chats en vol stagnent ; l'ingestion stagne | | `tale-db` | Postgres opérationnel pour Convex | Convex bascule en lecture seule ; les écritures bloquent | | `tale-knowledge-db` | Postgres du corpus de connaissances (fragments de documents, embeddings, pages crawlées) | La recherche de connaissances renvoie vide ; l'ingestion échoue | | `tale-sandbox-llm-gateway` | Gateway LLM pour les tours sur harness | Les tours sur harness ne joignent aucun modèle ; le chat n'est pas affecté | | `tale-sandbox-egress` | Sortie réseau pour code sandbox | L'outil **Exécuter du code** échoue avec « egress denied » ; le rendu web échoue | | `tale-sandbox` | Runtime sandbox + navigateur headless pour le rendu web et la génération de documents | **Exécuter du code**, le rendu de crawl web et la génération de documents échouent | Un conteneur est exposé au réseau public (`tale-proxy` pour HTTPS, et optionnellement `tale-sandbox-egress` sortant pour la sandbox) ; le reste est interne seulement. Le sidecar `tale-controller`, à activer explicitement (le profil `controller`), est éteint par défaut ; une fois activé, il redémarre `tale-convex` sur une requête signée pour qu'un changement de résidence des données s'applique sans donner à la plateforme l'accès à Docker. ## Le chemin de requête Un message chat fait un aller-retour par les conteneurs : 1. Navigateur → `tale-proxy` (TLS terminé). 2. `tale-proxy` → `tale-platform` pour HTML/JS, → `tale-convex` pour API + WebSocket. 3. `tale-convex` lit la config fournisseur de l'organisation, choisit le modèle, ouvre un flux vers le fournisseur amont. 4. Si l'agent récupère des connaissances : `tale-convex` exécute la recherche RAG en in-process, interrogeant directement `tale-knowledge-db` — sans service de récupération séparé sur le chemin. 5. Si l'agent exécute du code : `tale-convex` → `tale-sandbox` → `tale-sandbox-egress` pour tout appel sortant. 6. Le flux du fournisseur renvoie des tokens via `tale-convex` jusqu'au navigateur via le WebSocket. Le chemin chaud est court. Si la latence du chat semble fausse, le conteneur à blâmer est presque toujours le fournisseur amont, pas Tale ; les endpoints de métriques sur `tale-convex` (qui porte désormais aussi les timings RAG et de crawl) exposent le temps passé à chaque saut. ## Le plan sandbox L'exécution de code en sandbox tourne dans `tale-sandbox`, avec `tale-sandbox-egress` comme seule couture réseau. La séparation en deux conteneurs est délibérée : `tale-sandbox` lui-même n'a aucune sortie réseau ; chaque requête que le code sandbox fait passe par `tale-sandbox-egress`, qui bloque les métadonnées cloud et les plages privées au niveau IP et — quand l'opérateur définit `SANDBOX_EGRESS_ALLOWLIST` — impose en plus une allowlist d'hôtes en refus par défaut. Si le conteneur egress est down, le code sandbox qui a besoin du réseau échoue en mode fermé avec « egress denied » — pas un timeout silencieux. Le runtime sandbox embarque Chromium et Playwright, donc le backend convex le réutilise pour le travail headless qu'il ne peut pas faire en in-process : rendre une page JavaScript pendant un crawl web, et transformer du HTML généré en PDF ou en image. Ces tâches tournent comme des exécutions sandbox éphémères plutôt que du code utilisateur, mais elles empruntent la même couture d'egress et d'isolation. La sandbox est le seul conteneur qui exécute du code potentiellement non fiable (scripts de compétence fournis par l'utilisateur, invocations **Exécuter du code** d'agent) ; le reste de la stack exécute le code propre à la plateforme. ## Modes de défaillance — à quoi ressemble une panne de chaque conteneur **`tale-proxy` en panne.** Le handshake TLS échoue ; chaque client voit une erreur de connexion. Dans l'hôte, les conteneurs plateforme et convex restent debout — redémarre proxy en premier. **`tale-platform` en panne.** Le navigateur obtient 502 du proxy ; l'API continue de marcher. Les onglets navigateur existants avec assets en cache continuent à parler à convex via le WebSocket et peuvent ne pas s'en apercevoir avant un rechargement. **`tale-convex` en panne.** Le navigateur charge le shell UI mais rien ne se remplit. Les boucles de reconnexion WebSocket. Redémarrer convex est sûr — les sessions sont côté serveur ; les clients se réabonnent à la reconnexion. **`tale-db` en panne.** Convex entre dans son mode dégradé : lectures depuis le cache, écritures en file. De longues pannes finissent par afficher des toasts « échec de l'enregistrement ». **`tale-knowledge-db` en panne.** L'ingestion de documents échoue et la recherche de connaissances renvoie vide — les agents qui récupèrent des connaissances obtiennent un ensemble de résultats vide et un avertissement dans le log d'exécution. Le reste de l'app continue de marcher ; les chats sans connaissances ne sont pas affectés. Redémarrer le conteneur règle ça, et les téléversements en vol retentent à la passe suivante. **`tale-sandbox` / `tale-sandbox-egress` en panne.** Les appels de l'outil **Exécuter du code** retournent une erreur et les scripts de compétence échouent. Parce que le backend convex rend les pages web et génère les documents via le runtime sandbox, un crawl web qui a besoin de rendu JavaScript et la génération de documents échouent aussi en mode fermé tant que la sandbox est down. Les agents qui n'utilisent aucun de ces éléments continuent de marcher. **`tale-sandbox-llm-gateway` en panne.** Les tours sur harness perdent leur chemin vers un fournisseur de modèles. Le chat ordinaire — qui appelle les fournisseurs directement depuis convex, pas via la gateway LLM — n'est pas affecté. ## Où cela s'inscrit Cette page est la carte de l'opérateur ; la [vue d'ensemble de l'architecture](/fr/self-hosted/overview) est l'introduction à la même image, la page [Dépannage](/fr/self-hosted/operate/observability/troubleshooting) est l'index par symptôme quand quelque chose a mal tourné. Si tu fixes des seuils d'alerte, [Opérations](/fr/self-hosted/operate/observability/operations) nomme les signaux à câbler. # Comment lire les notes de version Source: https://tale.dev/docs/fr/self-hosted/operate/release-notes/format Tale publie une version par minor et des patches comme tags correctifs entre elles. Les notes de version pour chaque tag suivent la même forme afin que tu puisses en scanner une en une minute et savoir si la montée de version est un bump de cinq minutes ou une fenêtre de maintenance. Cette page couvre le format : la promesse semver, ce que chaque section garantit, et où lire plus en profondeur quand une ligne pointe vers une migration. Les notes elles-mêmes vivent sur la page de release GitHub de chaque tag. La CLI les fait aussi remonter — `tale update --notes` imprime les notes de la version qu'elle est sur le point d'installer. ## La promesse semver Les versions Tale sont en semver, et le numéro de version est le fait principal d'une montée de version. - **Patch (`0.9.0 → 0.9.1`)** — corrections de bugs uniquement. Pas de migration de schéma, pas de changement de config, pas de changement de comportement autre que le fix lui-même. Sûr à monter sans lire au-delà de la section sécurité. - **Minor (`0.9.x → 0.10.x`)** — nouvelles fonctionnalités, possiblement des migrations forward-only. Rétrocompatible par défaut ; les obsolescences sont annoncées une minor à l'avance. L'exception permanente est la 0.4.0 : une minor de rupture qui exige un déploiement neuf (voir [Montées de version → 0.3 → 0.4](/fr/self-hosted/operate/upgrades)). - **Major (`0.x → 1.x`)** — les changements breaking sont permis. Porte toujours un lien vers les notes de migration en haut de la release ; lis-les de bout en bout avant de commencer. La ligne de version en haut de chaque page de release nomme le type de bump en clair pour que tu n'aies pas à faire l'arithmétique toi-même. ## Les sections que chaque release a Chaque page de release est la même liste ordonnée de sections. Les sections vides sont omises, pas laissées vierges — si tu ne vois pas une section, c'est qu'il n'y a rien à rapporter là. - **Highlights** — un ou deux paragraphes nommant à quoi sert la release. Lis ça en premier. - **Changements breaking** — chaque changement qui demande à l'opérateur de faire quelque chose avant ou après la montée de version. Chaque ligne nomme le symptôme que tu rencontrerais si tu sautais, et l'action qui l'évite. - **Obsolescences** — fonctionnalités qui marchent encore dans cette release mais marquées pour suppression. Chaque ligne nomme la version de suppression pour que tu planifies la bascule. - **Sécurité** — entrées au format CVE pour les fixes qui ferment une vulnérabilité. Le flux complet vit sous [Avis de sécurité](/fr/self-hosted/operate/security/advisories) ; les notes de version portent le résumé d'une ligne plus le lien vers l'avis. - **Fonctionnalités et corrections** — la longue liste. Groupée par domaine (Platform, CLI, Docs) ; chaque ligne se lit comme une phrase. - **Notes de migration** _(versions majeures et certaines mineures)_ — le parcours lié à travers les migrations de schéma, les changements de fichier de config ou les renommages côté opérateur. À lire systématiquement pour les majeures. ## Comment scanner une release Lis la ligne de version, les highlights et la section des changements breaking. Si la section breaking est vide et que la section sécurité ne nomme pas un fix qui touche ton install, la montée de version est la séquence `tale update` + `tale deploy` depuis [Montées de version](/fr/self-hosted/operate/upgrades). Si l'une ou l'autre des sections a des lignes, parcours-les avant de lancer `tale deploy`. ```text 0.12.0 (minor) — 14/05/2026 Highlights Les tool calls en streaming streament maintenant dans le chat à mesure qu'ils émettent. Changements breaking (aucun) Obsolescences AGENTS_LEGACY_PROMPT env var — retirée en 0.14. Sécurité CVE-2026-XXXX — bypass patché dans la sandbox run-code. Voir : avis TAL-2026-007. ``` La forme ci-dessus est ce qu'imprime `tale update --notes`. La version web de la même release ajoute des liens sur chaque ligne d'avis et de migration. ## Où cela s'inscrit Le format des notes de version est le contrat entre le projet et l'opérateur — la même forme à chaque release pour que la décision de montée de version soit un scan, pas une lecture profonde. Les prochaines étapes naturelles sont [Montées de version](/fr/self-hosted/operate/upgrades) pour la mécanique de déploiement et [Avis de sécurité](/fr/self-hosted/operate/security/advisories) pour le flux long format des vulnérabilités vers lequel la section sécurité pointe. # Backups et restauration Source: https://tale.dev/docs/fr/self-hosted/operate/backups-and-restore L'unité de backup de Tale est le snapshot de volume : un tar checksummé, pris à containers en pause, de chaque volume de données de l'instance, écrit dans un volume `backups` dédié qui vit à côté des données qu'il protège. La CLI en prend un automatiquement avant toute étape de déploiement qui peut migrer des données, et `tale backup` en prend un à la demande. La récupération, c'est `tale restore <snapshot-id>` plus un redéploiement de la version correspondante — cette paire est la réponse à une montée de version échouée, et la raison pour laquelle `tale rollback` peut se permettre de refuser tout ce qui dépasse un pas de patch. Le contexte d'architecture vit dans [Architecture des conteneurs](/fr/self-hosted/operate/container-architecture) ; cette page couvre ce qu'un snapshot contient, quand il est pris, comment la copie quitte l'hôte et le walk de restauration. ## Ce qu'un snapshot contient | Volume | Contient | | ---------------------------- | --------------------------------------------------------- | | `db-data` | Postgres — agents, runs, l'audit log | | `convex-data` | Config d'org, secrets de fournisseurs, branding téléversé | | `rag-data` | L'index vectoriel construit depuis tes documents | | `crawler-data` | Connaissance web crawlée | | `caddy-data`, `caddy-config` | Certificats TLS et état du proxy | Chaque snapshot est un répertoire nommé comme `20260611-142530-deploy` dans le volume `backups` du projet : un `.tar.gz` par volume, un sidecar `.sha256` chacun et un `manifest.json` écrit en dernier. Un répertoire sans manifest est un snapshot incomplet — il n'apparaît jamais dans les listings et ne peut jamais être restauré. Deux choses vivent hors des volumes et demandent une capture séparée : le workspace du projet (le répertoire qui contient `tale.json`) et `.env`. ## Quand les snapshots sont pris `tale deploy` snapshotte avant sa première étape mutante dès que le déploiement peut changer des données : la version cible diffère de celle qui tourne, ou un push de config hôte (`--override` / `--override-all`) est demandé. Pendant que chaque volume est mis en tar, les conteneurs qui l'utilisent sont mis en pause quelques secondes pour que l'archive soit cohérente après crash — une copie à chaud d'un répertoire Postgres en marche n'est pas restaurable. Un snapshot échoué interrompt le déploiement. `--skip-backup` outrepasse cela sur `tale deploy` — tes propres backups externes deviennent alors le seul chemin de récupération, et c'est exactement pour ça que le flag logge un avertissement bien visible. ```bash # Prendre un snapshot tout de suite tale backup ``` ## Rétention La rotation garde les cinq snapshots les plus récents et tout ce qui date des 14 derniers jours — selon ce qui est le plus généreux. Un snapshot n'est supprimé que s'il est à la fois au-delà de la fenêtre de compte et plus vieux que la fenêtre d'âge ; une instance calme garde donc ses derniers snapshots indéfiniment. Ajuste les fenêtres avec `BACKUP_KEEP_COUNT` et `BACKUP_KEEP_DAYS` dans `.env`. ## Copie hors-hôte Les snapshots vivent sur le même hôte que les données qu'ils protègent — un disque mort emporte les deux. Pointe ton outillage de backup existant (Restic, Borg, Velero, snapshots de cloud provider) sur le volume `backups`, et capture le workspace du projet et `.env` dans le même job. Tale n'embarque pas d'étape d'upload — garder la copie hors-hôte sous ton contrat de backup existant est délibéré. ```bash # crontab sur l'hôte — copie Restic horaire du volume backups vers S3 0 * * * * restic -r s3:s3.amazonaws.com/bucket/tale backup \ /var/lib/docker/volumes/<project-id>_backups/_data ``` Trouve le chemin hôte du volume avec `docker volume inspect <project-id>_backups` ; l'id du projet vit dans `tale.json`. ## Restaurer un snapshot `tale restore` sans argument liste ce qui est disponible ; avec un id, il vérifie les checksums, vide les volumes de données et extrait le snapshot. Il refuse tant qu'un conteneur du projet tourne — passe `--stop` pour les arrêter — et demande confirmation avant de toucher à quoi que ce soit. ```bash # Voir ce qui est disponible tale restore # Arrêter le stack et restaurer tale restore 20260611-142530-deploy --stop # Remonter le stack sur la version qui correspond aux données tale update --version 0.9.6 tale deploy --stop ``` Le redéploiement de la version correspondante fait partie de la restauration, ce n'est pas un extra optionnel : le snapshot a capturé les données exactement comme cette version de la plateforme les a laissées, et un binaire plus récent relancerait immédiatement ses migrations dessus. La sortie de la restauration imprime la version exacte enregistrée dans le manifest du snapshot. ## Drill de restauration Fais tourner le drill trimestriellement sur un hôte non-production. Le drill n'est pas « un snapshot existe-t-il » — c'est « un hôte frais peut-il être reconstruit depuis la copie hors-hôte du volume `backups`, le workspace du projet et `.env` en moins d'une heure ». Les modes d'échec que le drill attrape : un job hors-hôte qui n'a jamais capturé le workspace, et un `.env` périmé qui ne correspond plus aux exigences du binaire courant. ## Où cela s'inscrit Les snapshots sont la partie bon marché ; le drill de restauration est ce qui prouve qu'ils marchent, et la règle redéployer-la-version-correspondante est la seule chose à retenir — la récupération n'est jamais « faire reculer le binaire », c'est « restaurer les données et déployer la version à laquelle elles appartiennent ». Le flow de montée de version que ces snapshots protègent vit dans [Montées de version](/fr/self-hosted/operate/upgrades) ; la checklist de durcissement qui nomme les backups comme une ligne est dans [Durcissement](/fr/self-hosted/operate/security/hardening). # Durcissement Source: https://tale.dev/docs/fr/self-hosted/operate/security/hardening Les défauts livrés par Tale sont sûrs pour le développement et raisonnables pour une petite installation en production. Passer de « raisonnable » à « prêt pour le régulateur » est une checklist, pas un flag de configuration — chaque ligne ci-dessous resserre une surface d'attaque spécifique. Walk la liste une fois avant d'ouvrir l'URL à de vrais utilisateurs, et walk-la à nouveau après chaque montée de version majeure. Le détail de référence pour chaque ligne vit ailleurs — TLS dans [TLS et domaines](/fr/self-hosted/configuration/tls-and-domains), backups dans [Backups et restauration](/fr/self-hosted/operate/backups-and-restore), rétention dans [Rétention](/fr/self-hosted/configuration/retention). Cette page est l'index qui nomme ce qu'il faut durcir et pointe vers la page qui le walk. ## Hôte | Élément | Pourquoi ça compte | | ---------------------------------------- | ------------------------------------------------------------------ | | Utilisateur opérateur non-root | Limite le blast radius si l'utilisateur plateforme est compromis | | Auth SSH par clé uniquement | L'auth par mot de passe est la porte ouverte que les bots scannent | | Mises à jour de sécurité non surveillées | Patche l'OS sans attendre une fenêtre de maintenance | | Firewall hôte (ufw / nftables) | Ferme tout ce qui n'est pas 22, 80, 443 | | Chiffrement du disque au repos | Requis si tu fais tourner SOPS en mode clair | L'utilisateur non-root est celui que la plupart des équipes sautent. Les conteneurs de Tale font tourner leurs propres processus non-root à l'intérieur, mais le démon Docker lui-même tourne en root — opérer ce démon en tant qu'utilisateur opérateur (membre du groupe `docker`, pas en tant que root) est le resserrement le moins cher de cette page. Le walk complet vit dans [Installation serveur Linux de production](/fr/self-hosted/install/linux-server). ## Réseau Le proxy est la seule surface entrante. Bloque tout le reste. ```bash sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow OpenSSH sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable ``` Si tu fais tourner l'auth trusted-headers, le port plateforme ne doit pas être joignable directement depuis ailleurs que le proxy amont — tout ce qui peut le frapper avec les bons en-têtes devient cet utilisateur. Un réseau Docker ou une règle firewall hôte marchent tous les deux ; choisis-en un et vérifie-le depuis l'extérieur de l'hôte. ## TLS `TLS_MODE=selfsigned` est pour le développement. La production fait tourner `letsencrypt` (ou `external` si tu mets ton propre proxy TLS-terminant devant Tale). Le cron de renouvellement est automatique ; l'alerte qui sonne quand le renouvellement échoue est ce qui te sauve 90 jours plus tard. Voir [TLS et domaines](/fr/self-hosted/configuration/tls-and-domains). ## Secrets Chaque secret dans `.env` est sensible — le secret de signature d'auth, la clé de chiffrement, le mot de passe de base, la clé age, le bearer token de métriques. La barre minimale : - `.env` est en mode 0600 et appartient à l'utilisateur opérateur. - `BETTER_AUTH_SECRET`, `ENCRYPTION_SECRET_HEX`, `INSTANCE_SECRET` sont rotés depuis les valeurs d'exemple livrées dans `.env.example`. - `DB_PASSWORD` est changé du placeholder par défaut. - `SOPS_AGE_KEY` ou `SOPS_AGE_KEY_FILE` est défini — laisser les deux non définis est supporté mais réservé aux hôtes à disque chiffré avec gestion de secrets externe. Le walk SOPS complet et la procédure de rotation vivent dans [Secrets avec SOPS](/fr/self-hosted/configuration/secrets-with-sops). ## Audit logs Les audit logs sont immuables et bornés par rétention. Les frameworks de compliance attendent au moins un an ; la borne est imposée par déploiement, donc le réglage de l'org le plus strict est ce qui tourne effectivement. Fixe le plancher dans ta config opérateur pour correspondre au framework le plus lâche que tu supportes, et assure-toi que les backups capturent les lignes d'audit log avec le reste de la base. La référence de rétention vit dans [Rétention](/fr/self-hosted/configuration/retention). ## Backups Un backup qui n'a pas été restauré est un espoir, pas un backup. Le minimum : dumps Postgres quotidiens écrits par le cron `tale-db`, copiés hors-hôte dans l'heure, et un drill de restauration trimestriel qui reconstruit une instance fonctionnelle depuis le snapshot. La procédure complète est dans [Backups et restauration](/fr/self-hosted/operate/backups-and-restore). ## Isolation de la sandbox Run-code est la surface la plus risquée du produit — le seul endroit où un input fourni par l'utilisateur devient du code exécuté. `tale-sandbox` tourne sans cap privilégié, son réseau est interne uniquement, et `tale-sandbox-egress` est son seul chemin sortant. Au niveau des hôtes, ce chemin est ouvert par défaut : le code en sandbox atteint n'importe quel hôte public en HTTPS, tandis que les endpoints de métadonnées cloud et les plages d'adresses privées sont toujours bloqués au niveau IP — ce plancher tient dans toutes les configurations. Le levier de durcissement est `SANDBOX_EGRESS_ALLOWLIST`. Mets-la dans `.env` sur une liste de regex d'hôtes séparées par des pipes et recrée `tale-sandbox-egress` : le proxy bascule en refus par défaut — seuls les hôtes correspondants sont joignables. Un verrouillage limité aux registres, qui garde pip, npm, uv et Git via HTTPS fonctionnels : ```bash SANDBOX_EGRESS_ALLOWLIST=^pypi\.org$|^files\.pythonhosted\.org$|^registry\.npmjs\.org$|^objects\.githubusercontent\.com$|^codeload\.github\.com$|^github\.com$|^api\.github\.com$ ``` Garde la liste courte et préfère des hôtes spécifiques aux wildcards. Les installations de paquets sont régies séparément, via l'écran [politique run-code](/fr/platform/admin/governance/run-code-policy). ## Monitoring `METRICS_BEARER_TOKEN` est non défini dans `.env.example` — c'est intentionnel, pour qu'une installation fraîche ne leak pas de métriques. Règle le token, scrape depuis ton Prometheus, et les seuils d'alerte dans [Opérations](/fr/self-hosted/operate/observability/operations) couvrent les signaux client-impactants. La chaîne de hachage du journal d'audit est vérifiée automatiquement chaque nuit. Toute rupture déclenche une alerte de sécurité critique vers les admins de l'org — dans la cloche de notifications et, lorsque Slack est connecté, dans ton canal Slack — pour que toute altération ressorte même quand personne ne surveille les logs. Tu peux re-walk la même vérification à la demande depuis la page d'administration du journal d'audit. ## En-têtes de sécurité HTTP Chaque réponse HTML porte un ensemble strict d'en-têtes de sécurité, et cet ensemble est verrouillé par des tests pour qu'une mise à jour ne puisse pas en supprimer un discrètement. Le client web de la plateforme (`services/platform`) envoie une Content-Security-Policy à nonce sans scripts `unsafe-inline`, HSTS en HTTPS, `X-Content-Type-Options: nosniff`, `X-Frame-Options: DENY` avec CSP `frame-ancestors 'none'`, `Referrer-Policy: strict-origin-when-cross-origin`, une `Permissions-Policy` restrictive et `X-Permitted-Cross-Domain-Policies: none`. Il obtient A+ au MDN HTTP Observatory, et cette note est garantie par la suite de tests CI — le calcul du score est réimplémenté dans des tests qui font échouer le build à la moindre régression. Le site vitrine et le site de documentation livrent la même famille d'en-têtes, en ajoutant `Cross-Origin-Opener-Policy` et `Cross-Origin-Resource-Policy` à `same-origin`. Vérifie-le sur ton propre déploiement : - `curl -sI https://<ton-hôte>/ | grep -iE 'content-security|strict-transport|x-frame|x-content-type|referrer-policy|permissions-policy|cross-origin'` - Analyse l'hôte sur [securityheaders.com](https://securityheaders.com) ou le [MDN HTTP Observatory](https://developer.mozilla.org/fr/observatory). <!-- The MDN Observatory UI is only localized in some languages. When adding a new docs language, check whether developer.mozilla.org/<lang>/observatory exists and fall back to the en-US analyze links if it does not. --> La démo publique est la référence en direct de ce qu’un déploiement correct rapporte : le [scan Observatory de demo.tale.dev](https://developer.mozilla.org/fr/observatory/analyze?host=demo.tale.dev) affichait A+ le 15/07/2026 — score 115/100, dix tests sur dix réussis. Le seul en-tête que le rapport liste comme non implémenté, `Cross-Origin-Resource-Policy`, ne coûte aucun point ; c’est l’exception délibérée décrite juste en dessous. L’isolation cross-origin (COOP/CORP) reste volontairement désactivée sur l’app de la plateforme : `Cross-Origin-Opener-Policy: same-origin` couperait la référence de fenêtre par laquelle un popup de connexion OAuth renvoie l’authentification terminée à l’app, et `Cross-Origin-Resource-Policy` bloquerait les ressources de marque chargées depuis un second hôte. Les sites de contenu, qui ne font ni l’un ni l’autre, activent les deux. HSTS n’est émis que lorsque `SITE_URL` est `https://`. ## Où cela s'inscrit Le durcissement n'est pas une tâche d'une seule passe — la liste ci-dessus est ce que tu walks avant le lancement, et que tu re-walks après chaque montée de version ou après chaque changement de la forme du réseau. La prochaine chose qui vaut la lecture après ceci est la ligne ci-dessus que tu n'as pas encore faite. # Alertes d’intégrité du journal d’audit Source: https://tale.dev/docs/fr/self-hosted/operate/security/audit-log-integrity Tale vérifie la chaîne de hachage du journal d’audit de chaque organisation selon un planning et lève une alerte à l’instant où une vérification échoue. Cette page est le runbook de l’opérateur ou de l’admin qui a reçu cette alerte : comment lire le constat, comment séparer un vrai signal de falsification d’un artefact ordinaire de rétention ou de configuration, et quoi préserver avant de toucher à quoi que ce soit. L’alerte est volontairement bruyante parce qu’une vraie rupture est rare et grave — mais la plupart des ruptures qui se déclenchent en pratique ont une explication banale, donc le travail consiste à les écarter méthodiquement plutôt qu’à paniquer. ## Ce qui la déclenche Un cron quotidien parcourt la chaîne d’audit en append-only de chaque organisation, avec ses points de contrôle de rétention et de scrub. Quand une chaîne ne se vérifie pas, l’exécution fait deux choses. Elle écrit une ligne d’audit in-band de catégorie `security` — à chaque exécution en échec, pour que l’enregistrement durable soit toujours complet — et elle lève une notification out-of-band vers les admins de l’organisation, dans la cloche de notifications et dans ton canal Slack quand il y en a un de connecté. L’alerte out-of-band est dédupliquée. Tu reçois une notification à la première détection d’une rupture, et une autre seulement si elle change — une autre ligne rompue, ou un autre point de contrôle en échec — pas une nouvelle alarme chaque jour pour la même rupture. Une exécution propre ultérieure efface l’alerte d’elle-même ; une rupture différente, plus tard, en lève une nouvelle. ## Falsification ou lacune de configuration L’alerte arrive sous deux formes, et le titre te dit laquelle. **Échec du contrôle d'intégrité du journal d'audit** est la critique : la chaîne de hachage elle-même ne se vérifie pas, ou la signature d’un point de contrôle signé ne correspond pas à la clé configurée. Traite-la comme un signal de falsification possible tant que tu ne l’as pas expliquée. **Les signatures du journal d'audit ne peuvent pas être vérifiées** est un avertissement calme, pas une intrusion : un point de contrôle est signé, mais le déploiement n’a aucune `TALE_AUDIT_SIGNING_KEY` configurée pour vérifier cette signature. Rien n’a été forgé — Tale ne peut pas prouver que le point de contrôle est authentique tant que tu n’as pas restauré la clé. Le panneau dans le produit reflète la distinction : une chaîne saine montre le badge vert **Vérifié**, un incident actif le badge rouge **Alerte d'intégrité active**, et une organisation que le cron n’a pas encore atteinte montre **Pas encore vérifié**. ## Ouvrir le panneau d’intégrité Les admins d’une organisation inspectent la chaîne depuis **Paramètres > Gouvernance > Journaux d'audit**. Le panneau **Intégrité de la chaîne** en haut de la page montre le badge de statut, l’heure du dernier contrôle automatique et un bouton **Vérifier maintenant** qui relance la même vérification à la demande. Si tu arrives depuis la notification, cliquer sur l’alerte te mène directement à la ligne signalée dans le tableau d’audit au lieu du haut du journal. Lance **Vérifier maintenant** pour voir le constat structuré. Pour une rupture de la chaîne de hachage, le panneau montre **Intégrité de la chaîne rompue** avec l’**ID de l'entrée** de la première ligne en échec, le moment (**Survenue le**), le **Hachage attendu** et le **Hachage stocké** qui n’a pas correspondu — plus un bouton **Ouvrir cette entrée** qui révèle la ligne dans le tableau. Pour un problème de point de contrôle, il montre **Échec de la vérification du point de contrôle** avec l’**ID du point de contrôle** et une **Raison**. Note ces détails avant de changer quoi que ce soit : ils sont la preuve. ## Écarter les causes bénignes Une rupture de hachage n’est un signal de falsification que si rien de légitime ne l’explique, et le vérificateur connaît déjà les trois événements ordinaires derrière presque toutes les alertes — les confirmer est ton premier geste. **Une coupe de rétention.** Quand la rétention supprime définitivement d’anciennes lignes, la tête de chaîne survivante pointe vers une ligne qui n’existe plus. Le vérificateur ré-ancre la chaîne par-dessus la coupe grâce à un point de contrôle de rétention signé — une coupe propre se vérifie donc normalement. Si tu vois à la place **Les signatures du journal d'audit ne peuvent pas être vérifiées**, la coupe elle-même va bien — il manque au déploiement la `TALE_AUDIT_SIGNING_KEY` qui authentifie le point de contrôle. C’est une lacune de configuration, pas une falsification. **Un scrub RGPD.** Effacer une personne concernée vide ses champs sur place, ce qui changerait les hachages de ces lignes — un scrub écrit donc un point de contrôle de scrub signé couvrant les lignes touchées, et le vérificateur leur fait confiance sur cette base. Un scrub ne devrait jamais apparaître comme une rupture sur un déploiement qui a une clé de signature. **Les anciennes lignes d’avant la chaîne.** Les lignes écrites avant l’existence du chaînage de hachage d’audit ne portent aucun hachage d’intégrité. Le vérificateur les saute automatiquement ; ce n’est pas une rupture. Un vrai signal de falsification est un écart de hachage sans aucune de ces explications : pas de coupe de rétention à cet endroit, pas de scrub couvrant la ligne, et la clé de signature présente et correcte. ## Réagir à une vraie rupture Si le constat survit à ce triage — un écart de hachage que tu ne peux pas expliquer —, traite-le comme un incident de sécurité et préserve d’abord les preuves. Les lignes d’audit sont en append-only par conception ; ne supprime ni ne modifie aucune ligne, y compris la ligne signalée, car cela détruit l’enregistrement dont une enquête dépend. 1. Note le constat mot pour mot — l’**ID de l'entrée**, l’heure sous **Survenue le**, le **Hachage attendu** et le **Hachage stocké** (ou l’**ID du point de contrôle** et la **Raison**) affichés dans le panneau. Copie-les ou fais-en une capture plutôt que de te fier à la seule alerte. 2. Confirme si la clé de signature est configurée sur l’hôte, pour distinguer un vrai écart d’un point de contrôle invérifiable. Ceci rapporte la présence sans imprimer le secret : ```bash grep -q '^TALE_AUDIT_SIGNING_KEY=' .env && echo configured || echo missing ``` 3. Corrèle l’horodatage de la rupture avec l’activité récente — une passe de rétention, un scrub de personne concernée, un déploiement, une restauration de base de données ou un accès direct à la base. Une rupture alignée sur une action de maintenance a le plus souvent une cause ordinaire que tu peux maintenant nommer. 4. Si rien ne l’explique, escalade via ta politique d’incident de sécurité et traite la base de données comme potentiellement compromise jusqu’à preuve du contraire. Garde un snapshot de sauvegarde d’avant et d’après la rupture détectée pour l’investigation. ## Effacer l’alerte L’alerte est liée à l’incident, pas récurrente. Une fois la rupture résolue ou expliquée — la clé restaurée, l’artefact de rétention compris, une base falsifiée reconstruite depuis une sauvegarde saine —, la prochaine exécution quotidienne se vérifie proprement et efface l’alerte d’elle-même, et le badge **Intégrité de la chaîne** revient à **Vérifié**. Il n’y a aucune étape d’accusé de réception ou de rejet à retenir. Si une rupture différente apparaît plus tard, le contrôle lève une nouvelle alerte pour celle-là — couper le son n’est donc jamais nécessaire. ## Où cela s’inscrit Une alerte d’intégrité est une invitation à enquêter, pas un verdict — le contrôle quotidien tourne fort pour qu’une rare vraie rupture ne puisse pas se cacher parmi les journaux, et ce runbook est la façon de séparer ce cas rare des artefacts de rétention et de scrub derrière la plupart des alertes. Le mécanisme que le vérificateur contrôle — la chaîne de hachage SHA-256 et les points de contrôle signés en HMAC — est documenté dans [Cryptographie](/fr/self-hosted/operate/security/cryptography), et les coupes de rétention qui la ré-ancrent légitimement sont dans [Rétention](/fr/self-hosted/configuration/retention). Le panneau, les colonnes et l’export avec lesquels tu lis une ligne signalée vivent dans la référence [Journaux d'audit](/fr/platform/admin/governance/audit-logs) ; la checklist [Durcissement](/fr/self-hosted/operate/security/hardening) est l’endroit où ce monitoring s’allume en premier lieu. # Cryptographie Source: https://tale.dev/docs/fr/self-hosted/operate/security/cryptography Cette page est l'inventaire de chaque primitive cryptographique sur laquelle Tale s'appuie : ce qui protège les secrets sur le disque, ce qui protège le trafic sur le réseau, comment les mots de passe sont hachés, et comment le journal d'audit prouve qu'il n'a pas été altéré. Elle est écrite pour les opérateurs et les auditeurs de conformité qui doivent répondre à « quels algorithmes, quelles longueurs de clé, où sont les clés » face à une norme comme BSI TR-02102-1 — Tale utilise déjà des primitives conformes, et cette page est l'endroit où elles sont consignées. Les affirmations ici sont vérifiées contre le code source ; là où une primitive est configurable, la variable d'environnement qui la contrôle est nommée pour que tu puisses auditer ton propre déploiement. Ce n'est pas un substitut au chiffrement du disque hôte — vois [Durcissement](/fr/self-hosted/operate/security/hardening) pour la couche sous l'application. ## Données au repos Tale chiffre deux classes de secrets au repos, avec deux mécanismes différents. **Les clés API des fournisseurs** vivent dans `providers/*.secrets.json` et sont chiffrées avec [SOPS](/fr/self-hosted/configuration/secrets-with-sops) en utilisant une clé **age**. SOPS chiffre chaque valeur avec **AES-256-GCM** et enveloppe la clé de données vers le destinataire age, dont l'échange de clés est **X25519**. Une valeur chiffrée se lit `ENC[AES256_GCM,data:…,iv:…,tag:…]` sur le disque ; le déchiffrement se fait in-process et la clé privée age ne quitte jamais la mémoire du conteneur platform. **Les champs chiffrés par l'application** — tokens de connector OAuth et identifiants similaires stockés en base — sont chiffrés avec **AES-256-GCM** via un JWE compact (`alg: dir`, `enc: A256GCM`). La clé de 32 octets vient de `ENCRYPTION_SECRET` (base64) ou `ENCRYPTION_SECRET_HEX` (hex) ; la plateforme refuse de démarrer le chemin de chiffrement avec une clé qui ne fait pas exactement 32 octets. Le magasin de données Convex et les volumes Postgres sont protégés par l'hôte : fais-les tourner sur un système de fichiers chiffré (LUKS, ou le chiffrement de volume de ton fournisseur cloud). Tale ne stocke pas d'identifiants en clair — une clé de fournisseur ou un token OAuth est soit chiffré par SOPS sur le disque, soit chiffré en AES-256-GCM en base, jamais écrit en clair. **Les données personnelles des clients et les enregistrements applicatifs** — noms, adresses e-mail et postales, contenu des conversations — sont protégés au repos par les mêmes couches qui protègent la base dans son ensemble : le chiffrement au repos de Convex, TLS 1.3 en transit, et la sécurité au niveau des lignes (RLS) qui restreint chaque lecture à l'organisation de l'appelant. Le chiffrement applicatif au niveau des champs est conçu pour les secrets — clés de fournisseur et tokens OAuth, écrits une fois et lus par un unique chemin de code. Les données personnelles sont différentes : elles sont filtrées, triées et recherchées par valeur exacte, et la table des clients est indexée par organisation et e-mail. Chiffrer ces colonnes au niveau des champs casserait les recherches par égalité et l'indexation — sauf à les coupler à un schéma de hachage recherchable qui révèle l'égalité même qu'il est censé masquer — au prix d'une rotation des clés et sans protection que le système de fichiers hôte chiffré sous l'application n'offre déjà contre un volume volé. Si ta réglementation de conformité exige en plus un chiffrement des données personnelles au niveau des champs, c'est une modification applicative délibérée plutôt qu'un défaut livré par Tale. ## Données en transit Tout le trafic navigateur et API termine TLS au reverse proxy (Caddy), qui négocie TLS 1.3 (avec TLS 1.2 comme plancher) et obtient les certificats automatiquement. Les suites de chiffrement sont les défauts modernes du proxy — AES-256-GCM et ChaCha20-Poly1305 avec échange de clés ECDHE. Configure le domaine et la source de certificat dans [TLS et domaines](/fr/self-hosted/configuration/tls-and-domains) ; le trafic entre conteneurs reste sur le réseau Docker interne de l'hôte. ## Hachage des mots de passe Les comptes à mot de passe local sont hachés avec **bcrypt** (via Better Auth), de sorte qu'une ligne de base de données volée ne révèle pas le mot de passe et qu'une vérification coûte délibérément ~100 ms — ce qui explique aussi pourquoi le timing du chemin de connexion est brouillé (vois [Authentification](/fr/self-hosted/configuration/authentication)). Les sessions sont signées avec `BETTER_AUTH_SECRET` (HMAC) ; faire tourner ce secret invalide toute session existante. ## Intégrité du journal d'audit Le journal d'audit est inviolable grâce à une **chaîne de hachage SHA-256** : chaque entrée stocke `SHA-256(previousHash + enregistrement canonisé)`, donc modifier ou supprimer une entrée historique casse la chaîne à cet endroit et à chaque entrée suivante. Les entrées portent en plus une signature **HMAC-SHA-256**. La vérification d'intégrité admin vérifie les deux ; vois [Journaux d'audit](/fr/platform/admin/governance/audit-logs). ## Correspondance avec BSI TR-02102-1 Chaque primitive ci-dessous est dans l'ensemble recommandé de BSI TR-02102-1. Tale ne livre aucun algorithme déprécié (pas de MD5, SHA-1, DES ni RSA < 3072 sur une clé qu'il génère). | Usage | Algorithme | Taille de clé / sortie | Contrôlé par | | ----------------------------- | --------------------------------- | ---------------------- | --------------------------------------------- | | Secrets fournisseurs (disque) | AES-256-GCM + age (X25519) | 256 bits | `SOPS_AGE_KEY` / `SOPS_AGE_KEY_FILE` | | Champs app (base de données) | AES-256-GCM (JWE `dir`/`A256GCM`) | 256 bits | `ENCRYPTION_SECRET` / `ENCRYPTION_SECRET_HEX` | | Transport | TLS 1.3 (AES-256-GCM, ECDHE) | 256 bits | Reverse proxy / `tls-and-domains` | | Hachage des mots de passe | bcrypt | sel par hachage | Better Auth (intégré) | | Signature de session | HMAC-SHA-256 | 256 bits | `BETTER_AUTH_SECRET` | | Intégrité d'audit | chaîne SHA-256 + HMAC-SHA-256 | 256 bits | intégré | ## Stockage et rotation des clés Trois secrets sont porteurs, et chacun a un chemin de rotation. La **clé privée age** (`SOPS_AGE_KEY`) déchiffre les secrets fournisseurs ; fais-la tourner en ajoutant un nouveau destinataire et en re-chiffrant, en suivant le parcours dans [Secrets avec SOPS](/fr/self-hosted/configuration/secrets-with-sops). La **clé de chiffrement de champ** (`ENCRYPTION_SECRET`) déchiffre les identifiants en base ; la faire tourner exige de re-chiffrer les lignes concernées, planifie-la donc comme une étape de maintenance plutôt qu'un échange à chaud. Le **secret d'auth** (`BETTER_AUTH_SECRET`) signe les sessions ; le faire tourner déconnecte tout le monde à la requête suivante. Les trois ne vivent que dans l'environnement du conteneur platform — ne les committe jamais et range-les dans ton gestionnaire de secrets de référence. ## Où cela s'inscrit La cryptographie dans Tale est en couches : SOPS+age et AES-256-GCM protègent les secrets au repos, TLS 1.3 les protège en transit, bcrypt protège les mots de passe, et une chaîne SHA-256 prouve que le journal d'audit est intact — toutes des primitives qui sont dans l'ensemble recommandé de BSI TR-02102-1, avec les variables d'environnement de contrôle ci-dessus pour que tu puisses vérifier ta propre instance. La couche sous l'application est l'hôte lui-même : [Durcissement](/fr/self-hosted/operate/security/hardening) couvre l'allowlist d'egress, l'isolation des conteneurs et les attentes de chiffrement de disque que cette page présuppose, et [Secrets avec SOPS](/fr/self-hosted/configuration/secrets-with-sops) est le guide opérationnel pour la clé age dont ces algorithmes dépendent. # Avis de sécurité Source: https://tale.dev/docs/fr/self-hosted/operate/security/advisories Tale publie un avis de sécurité pour chaque vulnérabilité qui se ferme par une release patchée. Le flux vit sous GitHub Security Advisories sur le dépôt `tale-project/tale` et se miroite vers un endpoint RSS que les opérateurs peuvent brancher dans leur alerting. Cette page couvre le format que suit chaque avis, l'échelle de sévérité que Tale utilise, le calendrier de divulgation auquel les mainteneurs s'engagent, et les trois chemins d'abonnement. Les avis sont l'enregistrement long format. Le résumé d'une ligne plus un lien apparaît dans la section **Sécurité** de chaque [note de version](/fr/self-hosted/operate/release-notes/format). ## Le format des avis Chaque avis est un GitHub Security Advisory avec un identifiant stable de la forme `TAL-YYYY-NNN` (ID interne de Tale) plus le `CVE-YYYY-NNNNN` upstream s'il en a un d'attribué. Le corps est le même ensemble ordonné de sections pour qu'un opérateur scanne les faits porteurs sans lire la prose. - **Résumé** — une phrase nommant ce qu'un attaquant pourrait faire et ce que le fix change. - **Versions affectées** — la plage de versions qui contient la vulnérabilité, en forme semver (`>=0.8.0, <0.12.3`). - **Versions patchées** — la première release qui contient le fix. Monter à ou au-delà de cette version ferme la vulnérabilité. - **Sévérité** — un des quatre niveaux ci-dessous, plus le vecteur CVSS 3.1 pour les opérateurs qui scorent contre leur propre threat model. - **Contournements** — quoi régler, désactiver ou bloquer pour mitiger la vulnérabilité quand une montée de version immédiate n'est pas possible. Vide quand aucun contournement n'existe. - **Crédits** — le rapporteur, quand il a demandé à être nommé. La ligne des versions patchées est celle sur laquelle la plupart des opérateurs atterrissent en premier ; la montée de version elle-même est la séquence à deux commandes de [Montées de version](/fr/self-hosted/operate/upgrades). ## L'échelle de sévérité Tale utilise quatre niveaux. Le niveau est posé à partir du score CVSS et de l'accessibilité de la surface vulnérable sur un install par défaut. | Niveau | CVSS | Ce que ça veut dire | | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------- | | Critical | 9.0+ | Exécution de code à distance pré-authentifiée ou exfiltration de données non authentifiée. Patche sous 24 heures. | | High | 7.0–8.9 | Escalade authentifiée, évasion de sandbox ou fuite de données cross-tenant. Patche sous une semaine. | | Moderate | 4.0–6.9 | Divulgation d'information, déni de service ou escalade demandant des préconditions rares. Patche à la prochaine fenêtre de maintenance. | | Low | 0.1–3.9 | Fixes de défense en profondeur et durcissement sans chemin d'exploitation connu. Patche quand ça t'arrange. | Le vecteur CVSS te laisse re-scorer contre ton propre déploiement — un avis noté High contre un install public peut être Low contre un air-gappé. ## Le calendrier de divulgation Les mainteneurs s'engagent sur le calendrier suivant à partir du moment où un rapport atterrit à `security@tale.dev` : - **Sous 72 heures** — accusé de réception, un triage call et un identifiant TAL attribué. - **Sous 14 jours** — un fix ou un contournement publié en privé au rapporteur, et la version patchée planifiée. - **À la sortie du fix** — l'avis est publié sur GitHub, l'attribution du CVE est demandée, et la section sécurité des notes de version porte le résumé. - **30 jours après la sortie** — le détail technique dans l'avis s'étend avec le reproducteur (quand reproduire en public ne met plus en risque les installs non patchés). Les rapporteurs peuvent demander un délai s'ils ont besoin de plus de temps pour divulguer ; les mainteneurs acceptent jusqu'à 90 jours avant de publier le résumé malgré tout. Côté ingénierie, les correctifs de dépendances passent par une voie rapide pour que la version corrigée arrive vite : Renovate ouvre une PR de mise à jour de sécurité dans les 24 heures suivant un advisory amont — en contournant le délai d'âge de version appliqué aux mises à jour de routine — et la CI bloque tout merge introduisant un advisory connu noté High ou Critical. Un CVE de dépendance divulgué devient ainsi une version Tale corrigée en quelques jours, et non au prochain cycle de routine. ## S'abonner Trois chemins vers le même flux : ```text Watch GitHub — github.com/tale-project/tale → Watch → Custom → Security alerts RSS — https://github.com/tale-project/tale/security/advisories.atom Digest courriel — security-announce@tale.dev (un courriel par avis, pas de trafic entre) ``` Le flux RSS est ce que la plupart des opérateurs branchent dans Slack ou PagerDuty ; le digest courriel est pour les équipes d'une personne qui ne font pas tourner de pipeline d'alerting. ## Où cela s'inscrit Le flux des avis est un des deux contrats qui rendent Tale auto-hébergeable sereinement — les notes de version nomment ce qui change, les avis nomment ce qui n'allait pas. Les prochaines lectures naturelles sont [Comment lire les notes de version](/fr/self-hosted/operate/release-notes/format) pour le format de changelog correspondant et [Durcissement](/fr/self-hosted/operate/security/hardening) pour la checklist qui limite l'exposition avant qu'un avis ne tire. # Fournisseurs Source: https://tale.dev/docs/fr/self-hosted/configuration/providers Un fournisseur IA dans Tale, ce sont deux moitiés qui vivent à deux endroits différents. Le **connecteur** — le format réseau, l’endpoint, la source du catalogue de modèles, les méthodes d’authentification acceptées — est livré avec la plateforme sous forme de fichier que tu lis sans le modifier. Les **identifiants** sont des données d’organisation, créées et renouvelées dans l’application sous **Paramètres > Fournisseurs IA**. Cette page couvre la moitié opérateur : ce que contiennent les fichiers livrés, et le seul levier qui appartienne vraiment au déploiement, à savoir porter les clés API des fournisseurs dans des variables d’environnement. ## Où vivent les connecteurs Les définitions de connecteurs sont des fichiers YAML sous `configs/platform/system/providers/`, un par fournisseur, nommés d’après son slug — `openrouter.yml`, `openai.yml`, `anthropic.yml`, `azure.yml`, et ainsi de suite. Ils font partie de l’image de la plateforme et évoluent avec elle. Les catalogues de modèles intégrés correspondants se trouvent à côté, sous `configs/platform/system/models/<slug>.yml`. <Warning> Ces fichiers sont des entrées en lecture seule, pas de la configuration de déploiement. Modifier l’un d’eux dans un conteneur en cours d’exécution est écrasé à la mise à niveau suivante, et il n’existe aucune surcharge au niveau d’une organisation. Quand un fournisseur dont tu as besoin ne figure pas dans le jeu livré, c’est un changement de plateforme et non un changement de configuration. </Warning> ## Ce qu’un connecteur déclare Un connecteur est court par construction. Il nomme le fournisseur, le dialecte réseau que son API parle, l’endpoint sur lequel il répond, la provenance de sa liste de modèles et les méthodes d’authentification qu’il accepte — rien de spécifique à une organisation et aucun secret. <CodeGroup> ```yaml anthropic.yml name: anthropic displayName: Anthropic apiFormat: anthropic baseUrl: https://api.anthropic.com catalog: source: static auth: - method: api-key - method: env - method: subscription-broker constraints: execution: sandbox harness: claude-code ``` ```yaml openrouter.yml name: openrouter displayName: OpenRouter apiFormat: openai baseUrl: https://openrouter.ai/api/v1 catalog: source: openrouter-api auth: - method: api-key - method: env ``` </CodeGroup> `apiFormat` est le dialecte réseau — `openai` ou `anthropic`. Un connecteur au format `openai` peut aussi déclarer `wireDialect: openai-modern`, comme le font les connecteurs OpenAI et Azure livrés : la plateforme écrit alors le plafond de sortie `max_completion_tokens` et n’envoie pas de température personnalisée aux modèles de raisonnement, parce que api.openai.com rejette `max_tokens` et toute température non standard sur ces modèles, tandis que les endpoints compatibles OpenAI tiers gardent les champs classiques. `baseUrl` est l’endpoint fixe ; un connecteur qui l’omet déclare `endpointMode: per-credential` à la place, ce que fait Azure OpenAI, puisque chaque ressource Azure sert son propre endpoint et que chaque identifiant porte donc sa propre URL. `catalog.source` vaut `static` (un fichier livré sous `configs/platform/system/models/`), `openrouter-api`, `models-endpoint` ou `none`. Chaque entrée sous `auth` est une méthode que les identifiants de ce fournisseur peuvent employer, et une méthode peut porter des `constraints` qui l’épinglent à une exécution en sandbox sur un harness nommé. ## Source de clé par variable d’environnement Si tes clés API vivent déjà dans des secrets Kubernetes, Vault ou un gestionnaire de secrets cloud, un identifiant n’a pas à porter le secret. La méthode d’authentification **Variable d’environnement** ne stocke que le _nom_ d’une variable du déploiement, et la plateforme en lit la valeur dans l’environnement du processus au moment de l’appel. C’est le chemin géré par les ops : la clé n’entre jamais dans la base de l’application, et la renouveler relève du déploiement plutôt que d’une tâche d’administration. Le nom de la variable est protégé par un préfixe. Il doit commencer par `TALE_PROVIDER_KEY_`, et l’application fixe ce préfixe dans le formulaire, si bien que seul le suffixe se saisit : ```bash TALE_PROVIDER_KEY_OPENROUTER=sk-or-... TALE_PROVIDER_KEY_OPENAI_PROD=sk-... ``` <Note> La barrière est fail-closed : tout nom hors du préfixe réservé est rejeté, ce qui empêche un identifiant de désigner un secret de déploiement étranger comme `SOPS_AGE_KEY` ou `BETTER_AUTH_SECRET` et de le voir partir en jeton Bearer vers l’endpoint d’un fournisseur. Les noms sont plafonnés à 40 caractères, la limite de la synchronisation d’environnement entre la plateforme et Convex — un nom plus long n’atteindrait jamais le runtime du backend. </Note> Définis la variable de façon que le conteneur de la plateforme et le backend Convex puissent tous deux la lire. La plateforme synchronise son environnement vers Convex au boot, donc les actions qui y tournent résolvent la même valeur ; une variable ajoutée ou changée après le boot demande un redémarrage du conteneur plateforme avant d’être visible. Les valeurs sont nettoyées de leurs espaces, ce qui t’épargne le retour à la ligne que porte souvent un fichier de secret monté, et le `401` qui s’ensuit. ## Secrets de courtier depuis l’environnement Des identifiants de type **Courtier d’abonnement** s’authentifient auprès du courtier avant de pouvoir récupérer un pool de jetons, et ce secret de courtier peut lui aussi venir du déploiement. Ses variables portent leur propre préfixe réservé, `TALE_TOKEN_SOURCE_`, distinct de celui des clés de fournisseur pour que les deux espaces de noms ne se confondent pas. La même règle fail-closed s’applique : un nom hors du préfixe est rejeté. Dans le formulaire, le champ s’appelle **Secret depuis une variable d’environnement** ; le laisser vide signifie que le secret du courtier est stocké chiffré avec les identifiants. ## Ce qui relève de l’organisation et non du déploiement Les identifiants, leurs noms, leurs listes de modèles autorisés, celui qui fait office de défaut et ceux qui sont actifs sont tous des données d’organisation. Ils naissent dans l’application, ils appartiennent à une seule organisation, et aucun fichier sur disque ne sert à en ajouter — y compris sur une instance auto-hébergée. <Tip> Cette séparation est le moyen le plus rapide de situer une tâche. Tout ce qui touche à _quel fournisseur existe et à ce qu’il sait faire_ est un connecteur livré ; tout ce qui touche à _qui peut l’appeler et avec quelle clé_ est un identifiant dans l’application. Le seul recouvrement est le chemin par variable d’environnement, où le déploiement porte le secret et l’identifiant n’en porte que le nom. </Tip> ## Où cela s’inscrit Toute la surface d’un opérateur tient ici à provisionner des variables d’environnement et à savoir quels connecteurs la plateforme livre ; le reste se passe dans l’application. Le parcours d’interface — ajouter des identifiants, désigner un défaut, restreindre une liste, actualiser les catalogues — c’est [Fournisseurs IA](/fr/platform/admin/providers), ce que tes utilisateurs finissent par voir c’est le [Catalogue de modèles](/fr/platform/models), et les variables elles-mêmes figurent aux côtés du reste de la configuration dans la [Référence des variables d’environnement](/fr/self-hosted/configuration/environment-reference). # Authentification Source: https://tale.dev/docs/fr/self-hosted/configuration/authentication Tale ship quatre modes de sign-in qu'un opérateur choisit par instance. Le défaut est mot de passe local, avec un utilisateur par e-mail ; Microsoft Entra et OIDC générique délèguent l'identité à un fournisseur externe ; trusted headers remet la responsabilité à un reverse proxy qui termine déjà SSO en amont. La décision est permanente au sens où elle façonne comment les utilisateurs sont provisionnés — changer de mode après le rollout est possible, mais chaque utilisateur existant doit être re-mappé sur la nouvelle source d'identité. Mot de passe local et trusted headers se basculent par variables d'env ([Référence des variables d'environnement](/fr/self-hosted/configuration/environment-reference)) ; Microsoft Entra et OIDC générique se configurent par organisation dans l'app en marche. Cette page est le walkthrough mode par mode — quand choisir chacun, ce qu'il change pour l'utilisateur, ce qui casse quand il est mal configuré. ## Mot de passe local (défaut) Mot de passe local est le mode que tu obtiens si tu ne règles rien. La plateforme stocke un hash bcrypt dans Postgres, signe la session avec `BETTER_AUTH_SECRET`, et l'utilisateur se connecte avec un e-mail et un mot de passe que l'admin lui a fourni dans l'invitation. Aucun fournisseur d'identité externe n'est impliqué. Choisis-le sur les petites instances et les déploiements auto-hébergés air-gapped où ajouter un IdP crée plus de friction qu'il n'en résout. Le coût : la réinitialisation de mot de passe passe par l'admin (ou par e-mail si `SMTP_*` est configuré), et il n'y a pas d'histoire SSO. ```bash # .env — pas de flag nécessaire pour le mot de passe local HOST=localhost SITE_URL=https://localhost BETTER_AUTH_SECRET=... ``` ## Microsoft Entra Le mode Microsoft Entra ajoute un bouton **Continuer avec SSO** à l'écran de sign-in et accepte les utilisateurs d'un tenant que tu contrôles. Il n'y a pas d'interrupteur par variable d'env : la connexion se configure par organisation sous **Paramètres > SSO d'entreprise** une fois la plateforme démarrée — choisis le protocole **Microsoft Entra ID** et renseigne le client ID, le client secret et l'URL d'issuer de ton enregistrement d'application. Le walkthrough complet, y compris le mapping des rôles et la synchronisation groupes-vers-équipes, est [SSO d'entreprise et provisionnement](/fr/platform/admin/enterprise-sso). Deux valeurs de déploiement doivent être justes avant que le flow fonctionne : `SITE_URL`, car l'URL de redirection de sign-in en est dérivée, et `BETTER_AUTH_SECRET`, qui signe le state OAuth. L'URI de redirection à enregistrer dans Entra est `${SITE_URL}${BASE_PATH}/http_api/api/sso/callback` — la page de paramètres affiche l'URL exacte à copier, et elle doit correspondre octet pour octet, sinon Entra rejette le sign-in avec `AADSTS50011`. L'ID du tenant dans l'enregistrement d'application Entra restreint qui peut se connecter ; un enregistrement multi-tenant accepte quiconque a un compte Microsoft, ce qui est rarement ce que tu veux. ## OIDC générique L'OIDC générique accepte tout fournisseur d'identité conforme à la spec — Keycloak, Authentik, Okta, Google Workspace. La configuration vit sur la carte **Authentification unique** sous **Paramètres > Connectors** : choisis le type de fournisseur **OIDC générique**, saisis l'URL de l'émetteur, le client ID et le client secret, et Tale lit les points de terminaison d'autorisation, de jeton et userinfo depuis le document `.well-known/openid-configuration` de l'émetteur. Le flow utilise le grant Authorization Code standard avec PKCE (S256). Tale ne stocke aucun secret sur disque pour OIDC ; le client ID et le client secret vivent dans le credential store chiffré. L'URI de redirection à enregistrer chez ton fournisseur est `${SITE_URL}/http_api/api/sso/callback`. Les fournisseurs d'identité ne s'accordent pas sur l'emplacement des claims, donc la carte te laisse pointer Tale vers les tiens. Les champs **Claim d'e-mail**, **Claim de nom** et **Claim de groupes** prennent un nom de claim ou un chemin en notation pointée dans la réponse userinfo — les rôles de realm de Keycloak, par exemple, vivent sous `realm_access.roles`. Les règles de correspondance des rôles attribuent les rôles de la plateforme au sign-in : une règle **Groupe** compare les groupes de l'utilisateur à un motif avec caractère générique (`platform-admin*` → Admin), une règle **Claim** compare n'importe quel claim résolu par chemin pointé. **Provisionnement automatique des équipes** reflète les groupes renvoyés par ton fournisseur comme équipes Tale à chaque sign-in, moins les groupes que tu exclus. Un exemple Keycloak complet : crée un client confidentiel `tale-platform` avec l'URI de redirection ci-dessus, ajoute un mapper Group Membership pour que le client émette `groups` dans userinfo, puis dans Tale règle l'émetteur sur `https://keycloak.example.com/realms/<realm>`, ajoute une règle de groupe `platform-admin*` → Admin et clique sur **Tester la connexion** — la discovery est validée avant que quoi que ce soit ne soit enregistré. C'est le mode pour les équipes qui font déjà tourner un IdP et veulent leur surface d'identité existante dans Tale. ## Trusted headers Trusted headers est le mode pour les sites qui terminent SSO sur un reverse proxy en amont — oauth2-proxy, Pomerium, Authelia. Le proxy authentifie l'utilisateur et transmet les en-têtes d'identification (`X-Auth-Request-Email`, `X-Auth-Request-Preferred-Username`) ; Tale fait confiance à ces en-têtes et crée ou met à jour l'enregistrement utilisateur à la volée. ```bash # .env TRUSTED_HEADERS_ENABLED=true ``` Le modèle de menace est délicat. Tout ce qui peut joindre le conteneur plateforme avec ces en-têtes devient l'utilisateur qu'ils nomment. Restreins le port plateforme pour que seul le proxy puisse lui parler (un réseau Docker ou une règle firewall hôte), et n'expose jamais le conteneur plateforme directement à Internet quand ce mode est actif. ## Où cela s'inscrit Les quatre modes sont mutuellement exclusifs en esprit mais techniquement additifs — Microsoft Entra et trusted headers peuvent coexister sur la même instance si ton histoire IdP est en pleine migration. La table complète des compromis par mode vit dans [Membres et rôles](/fr/platform/admin/members-and-roles) côté utilisateur ; cette page couvre le commutateur de l'opérateur. La prochaine page de configuration qui vaut la lecture est [Fournisseurs](/fr/self-hosted/configuration/providers) — une fois que les utilisateurs peuvent se connecter, il faut toujours au moins un fournisseur de modèle câblé avant qu'ils ne puissent faire quoi que ce soit. # Rétention Source: https://tale.dev/docs/fr/self-hosted/configuration/retention La rétention dans Tale est la policy qui supprime les vieilles données sur un planning — chats, documents, audit logs, exécutions de workflow, lignes du ledger d'usage de tokens. L'opérateur fixe les bornes (minimums et maximums) par catégorie ; l'admin de chaque organisation choisit la fenêtre de rétention réelle dans ces bornes via **Paramètres > Gouvernance > Politique de rétention**. La séparation existe pour qu'une équipe d'hébergement puisse imposer des planchers de compliance sans micromanager chaque tenant. Cette page couvre la surface opérateur. Les contrôles côté admin et les descriptions par catégorie vivent dans [Gouvernance > Politique de rétention](/fr/platform/admin/governance/policies-and-limits). ## Comment marchent les bornes Chaque catégorie de rétention — fils de chat, documents, contacts, fournisseurs, templates de prompt, lignes de ledger, audit logs, exécutions de workflow, logs de triggers de workflow, tentatives de login — a un `min` et un `max`. Un admin d'org fixe une valeur dans cette fenêtre. Resserrer le plancher sur une instance existante est un flow en plusieurs étapes : l'opérateur propose la nouvelle borne, chaque admin affecté voit une bannière, le changement s'applique une fois accepté. | Catégorie | Plancher typique | Pourquoi | | ---------------------------- | ---------------- | --------------------------------------------------------- | | Historique de chat | 30 j | La plupart veulent du contexte récent, pas pour toujours | | Documents | 1 a | Les connaissances vieillissent lentement | | Audit logs | 1 a minimum | Les frameworks de compliance attendent un an | | Ledger d'usage de tokens | 90 j | Analytics et rapports de budget s'appuient sur les lignes | | Logs d'exécution de workflow | 30 j | Le debugging remonte rarement plus loin | | Tentatives de login | 30 j | L'enquête brute-force a besoin de la trace d'audit | Les défauts livrés sont lâches ; resserre selon ta posture de compliance. ## Où tu fixes les bornes Sous la disposition org-first, les bornes de rétention sont **par org** : édite `retention.json` directement dans le sous-arbre d'une org sous `TALE_CONFIG_DIR` (par défaut `/app/data/` dans le conteneur plateforme, le fichier se trouve donc à `/app/data/<org>/retention.json`, p. ex. `/app/data/default/retention.json`). Chaque org a son propre fichier ; celui de l'org `default` est le modèle qu'un nouveau déploiement reprend au premier démarrage. ```json { "chatHistory": { "min": 30, "max": 730, "unit": "days" }, "documents": { "min": 1, "max": 3650, "unit": "days" }, "auditLog": { "min": 365, "max": 3650, "unit": "days" }, "tokenLedger": { "min": 90, "max": 1095, "unit": "days" } } ``` Le conteneur plateforme surveille le fichier ; les changements proposent une mise à jour de bornes pour chaque org existante. Les admins voient la proposition dans leur écran **Politique de rétention** et l'appliquent eux-mêmes. L'étape propose-puis-applique est délibérée : resserrer un plancher raccourcit l'historique, ce qui est une action destructive qu'aucun opérateur ne devrait poser silencieusement sur chaque tenant. Les fenêtres de rétention choisies par l'admin vivent dans un fichier distinct, `retention-policy.json`, à côté des bornes dans le même dossier `governance/`. Il contient des champs plats `<catégorie>Enabled` / `<catégorie>RetentionDays` (p. ex. `"auditLogEnabled": true, "auditLogRetentionDays": 730`), pas les bornes `min`/`max`. Ce fichier est écrit par **Paramètres > Gouvernance > Politique de rétention** dans l'app, donc les admins ne l'éditent normalement jamais à la main — garde-le distinct du fichier de bornes géré par l'opérateur. ## Le sweep de rétention Un cron planifié dans `tale-convex` fait la suppression réelle. Chaque catégorie est sweepée indépendamment — un run lent sur une ne bloque pas les autres. Les suppressions sont auditées (chaque catégorie a son propre événement `*.retention_deleted`), et restaurer une entité dans sa fenêtre de grâce est possible depuis **Corbeille** avant le sweep final. Les entrées d'audit log sont elles-mêmes soumises à la rétention, mais leur plancher est imposé par déploiement, pas par org : la rétention d'audit log la plus stricte (la plus courte) à travers toutes les orgs est ce qui tourne effectivement. Un tenant plus strict tire tout le monde plus serré — garde ça en tête sur les instances multi-tenants. ## Legal hold Un legal hold gèle la rétention pour un scope spécifique : un fil unique, un enregistrement client, ou toute une organisation. Les entités tenues sautent le sweep jusqu'à ce que le hold soit relâché. Le hold lui-même est audité ; les holds à l'échelle de l'org sont assez bruyants pour que l'UI fasse remonter une confirmation avant qu'ils s'appliquent. ## Où cela s'inscrit Le fichier de bornes est le levier de l'opérateur ; les fenêtres par catégorie que l'admin voit sont documentées dans [Politique de rétention](/fr/platform/admin/governance/policies-and-limits). Si tu fixes des bornes contre un framework de compliance (RGPD, HIPAA, SOC 2), le plancher d'audit log est habituellement ce que les auditeurs vérifient en premier. # TLS et domaines Source: https://tale.dev/docs/fr/self-hosted/configuration/tls-and-domains Le conteneur `tale-proxy` est Caddy. Il possède la terminaison TLS, le routage par hôte et la barrière d'auth des métriques ; chaque requête venue du navigateur y atterrit en premier. Les trois modes — auto-signé, Let's Encrypt, externe — couvrent les trois formes de déploiement que la plupart des opérateurs choisissent, et la variable qui bascule entre eux est `TLS_MODE` dans ton `.env`. Les lignes de référence des variables d'env vivent dans [Référence des variables d'environnement](/fr/self-hosted/configuration/environment-reference#tls). Cette page est le walkthrough mode par mode et les recettes pour les domaines personnalisés et bring-your-own certificats. ## Auto-signé (défaut) `TLS_MODE=selfsigned` fait tourner Caddy avec un certificat qu'il génère depuis sa CA interne. Le navigateur avertit la première fois, et l'hôte doit faire confiance au certificat pour supprimer l'avertissement — c'est destiné au développement local : ```bash docker exec tale-proxy caddy trust ``` La commande trust importe la CA de Caddy dans le trust store système sur l'hôte qui fait tourner le démon Docker. Les autres machines du réseau voient encore l'avertissement sauf si elles importent la CA aussi. La production n'utilise jamais ce mode. ## Let's Encrypt `TLS_MODE=letsencrypt` laisse Caddy émettre et renouveler un vrai certificat public. Trois prérequis doivent tenir sinon la boucle d'émission échoue : - Le hostname dans `HOST` et `SITE_URL` résout vers l'IP publique de l'hôte depuis l'Internet public. - Les ports 80 et 443 sont joignables depuis l'Internet public (le port 80 porte le challenge ACME HTTP-01). - `TLS_EMAIL` est mis sur une boîte mail que tu lis — Let's Encrypt y avertit avant l'expiration. ```bash # .env TLS_MODE=letsencrypt TLS_EMAIL=ops@yourdomain.com ``` Le premier boot bloque environ une minute pendant que le challenge ACME tourne. Après ça, les renouvellements sont automatiques 30 jours avant l'expiration ; les échecs atterrissent dans `docker compose logs proxy`. ## Proxy externe `TLS_MODE=external` fait que Caddy sert du HTTP en clair à l'intérieur, et tu le mets derrière ton propre reverse proxy qui termine TLS en amont. Choisis ça quand : - Tu fais déjà tourner un CDN ou un load balancer qui gère les certificats. - Tu veux terminer TLS une seule fois au bord de ton VPC et faire tourner tout l'interne en clair. - Ta posture de compliance exige une autorité de certification spécifique que Caddy ne supporte pas. ```bash # .env TLS_MODE=external SITE_URL=https://tale.yourdomain.com # l'URL que tes utilisateurs frappent ``` Le proxy en amont a besoin que `X-Forwarded-Proto: https` soit posé sur chaque requête pour que Tale génère des redirects et des URL absolues correctes. Sans lui, les liens de sign-in atterrissent sur `http://` et le flag `Secure` du cookie d'auth les rejette. ## Domaine personnalisé Le domaine lui-même n'est que `HOST` et `SITE_URL`. Le même Caddyfile dans `tale-proxy` lit les deux au boot. Change-les, recrée le conteneur proxy (`docker compose up -d --force-recreate tale-proxy`), et le nouveau domaine est live en quelques secondes. Let's Encrypt réémet pour le nouveau nom à la prochaine requête qui frappe le nouveau hostname. ```bash # .env HOST=tale.example.com SITE_URL=https://tale.example.com ``` Les déploiements en sous-chemin — Tale derrière `https://example.com/app/` — règlent en plus `BASE_PATH=/app`. Le reverse proxy en amont de Caddy ne strip rien ; Tale gère le préfixe lui-même. ## Apporter ton propre certificat Pour une CA interne ou un certificat wildcard que tu possèdes déjà, monte le certificat et la clé dans `tale-proxy` et ajoute une directive `tls` au Caddyfile : ```yaml # override compose.yml services: proxy: volumes: - ./certs/fullchain.pem:/etc/tale/cert.pem:ro - ./certs/privkey.pem:/etc/tale/key.pem:ro environment: TLS_MODE: external # contourne l'auto-émission de Caddy ``` Ensuite, soit pré-construis une image `tale-proxy` avec un Caddyfile personnalisé, soit mets ton propre reverse proxy devant Tale et reste sur `TLS_MODE=external` — les deux chemins sont supportés et le second est plus simple. ## Où cela s'inscrit Les trois modes couvrent les trois formes de déploiement que la plupart des équipes touchent ; les lignes de variables d'env vivent dans [Référence des variables d'environnement](/fr/self-hosted/configuration/environment-reference#tls). Si tu mets en place un hôte de production frais maintenant, [Installation serveur Linux de production](/fr/self-hosted/install/linux-server) walk Let's Encrypt de bout en bout avec les étapes firewall et DNS dans l'ordre. # Secrets avec SOPS Source: https://tale.dev/docs/fr/self-hosted/configuration/secrets-with-sops Tale stocke les clés API des fournisseurs dans des fichiers `providers/*.secrets.json` sur disque. Le mode par défaut après `tale init` chiffre ces fichiers avec SOPS en utilisant une clé age ; un mode alternatif lit plusieurs clés depuis un fichier (le chemin de rotation) ; un troisième mode garde les fichiers en clair au mode 0600 pour les environnements où le disque est chiffré au repos et où la rotation est gérée en externe. Cette page est le walkthrough opérateur des trois modes et du chemin de rotation sûr. Les variables d'env qui pilotent les modes sont `SOPS_AGE_KEY` et `SOPS_AGE_KEY_FILE` — leurs lignes de référence vivent dans [Référence des variables d'environnement](/fr/self-hosted/configuration/environment-reference#provider-secrets-encryption). Cette page est la version plus longue. ## Les trois modes | Mode | Variables d'env | Quand utiliser | | --------------- | ---------------------------------- | ----------------------------------------------------------------- | | Clé age inline | `SOPS_AGE_KEY=AGE-SECRET-KEY-1...` | Défaut après `tale init`. Hôte unique, clé unique. | | Fichier de clés | `SOPS_AGE_KEY_FILE=/path/to/keys` | Requis pour la rotation. Une clé age par ligne, commentaires `#`. | | Clair à 0600 | Les deux non définis | Disque chiffré au repos, ou outillage externe écrit les fichiers. | Le conteneur plateforme choisit le mode au boot. La forme inline est la plus simple ; la forme fichier est la seule qui supporte plusieurs lecteurs (ce qui rend la rotation possible sans downtime) ; la forme en clair saute SOPS entièrement et fait confiance au système de fichiers. ## Mode chiffré au premier boot `tale init` génère une paire de clés age et écrit la moitié privée dans `SOPS_AGE_KEY` de ton `.env`. Les fichiers de secret de fournisseur écrits via **Paramètres > Fournisseurs** sont chiffrés à la sauvegarde : ```bash # Inspecte — le fichier est du JSON SOPS-chiffré, pas la clé API en clair cat providers/openai.secrets.json # { # "apiKey": "ENC[AES256_GCM,data:...,iv:...,tag:...]", # "sops": { ... } # } ``` Le déchiffrement se passe in-process quand le conteneur plateforme lit le fichier. La clé age ne quitte jamais la mémoire du conteneur plateforme. ## Faire tourner la clé age La rotation est le seul chemin que la forme inline ne couvre pas — seul `SOPS_AGE_KEY_FILE` te laisse accepter du ciphertext lisible par l'ancienne et la nouvelle clé pendant le cutover. Le walk : ```bash # 1. Génère une nouvelle clé age age-keygen -o /etc/tale/age-keys.txt # 2. Ajoute la nouvelle clé comme deuxième ligne dans le fichier echo "AGE-SECRET-KEY-1NEW..." >> /etc/tale/age-keys.txt # 3. Pointe .env sur le fichier et redémarre le conteneur plateforme sed -i 's|^SOPS_AGE_KEY=.*|# SOPS_AGE_KEY=|' .env sed -i 's|^# SOPS_AGE_KEY_FILE=.*|SOPS_AGE_KEY_FILE=/etc/tale/age-keys.txt|' .env docker compose restart tale-platform tale-convex ``` Maintenant l'ancienne et la nouvelle clé peuvent déchiffrer les fichiers existants. Re-sauvegarde la clé API de chaque fournisseur sous **Paramètres > Fournisseurs** — chaque sauvegarde produit du ciphertext lisible par les deux clés. Une fois que chaque fournisseur a été re-sauvegardé (la colonne **Dernière rotation** dans le tableau des fournisseurs te dit lesquels tiennent encore l'ancien ciphertext), retire l'ancienne clé du fichier : ```bash # 4. Drop la ligne de l'ancienne clé et redémarre à nouveau sed -i '/^AGE-SECRET-KEY-1OLD/d' /etc/tale/age-keys.txt docker compose restart tale-platform tale-convex ``` L'ordre est porteur : ne retire jamais l'ancienne clé avant que chaque fichier soit re-chiffré, sinon le conteneur plateforme échouera à lire les fichiers encore-anciens au prochain déchiffrement. ## Basculer en clair Quand le disque hôte est chiffré au repos (LUKS, chiffrement AWS EBS, GCP CSEK) et que tu ne veux pas d'une deuxième couche de gestion de clés, le mode en clair est l'option supportée. Commente `SOPS_AGE_KEY` et `SOPS_AGE_KEY_FILE`, redémarre et re-sauvegarde chaque fournisseur — les fichiers sont maintenant du JSON au mode 0600. Le modèle de risque change : un dump de système de fichiers leaké est maintenant un dump de credentials leaké. Choisis ce mode seulement quand le chiffrement de disque est réel (pas une case à cocher) et audite l'histoire de backup de l'hôte pour confirmer qu'aucun snapshot en clair n'échappe. ## Stores de secret externes Quand tes clés vivent déjà dans Vault, un gestionnaire de secrets cloud ou Kubernetes Secrets, le pattern de première classe est la source de clé par variable d'environnement : pointe chaque fournisseur sur une **variable d'environnement** avec `secretsEnv` et laisse ton store de secrets remplir cette variable. Aucun fichier en clair ne touche le disque, et la barrière de préfixe empêche un acteur qui écrit la config de lire un secret de déploiement étranger. Le mécanisme complet — la barrière de préfixe `TALE_PROVIDER_KEY_`, l'ordre de résolution et le comportement de redémarrage au changement — vit dans [Fournisseurs](/fr/self-hosted/configuration/providers#environment-variable-key-source). L'approche par mount de fichier est l'alternative legacy : écris les fichiers `*.secrets.json` en clair depuis le store externe et fais tourner Tale en mode clair. Cela fonctionne toujours, mais pose la clé en clair sur le disque et casse si tu sauvegardes un fournisseur via l'UI — l'UI écrase le mount. Préfère la source par variable d'environnement, sauf si une contrainte impose la forme fichier. ## Où cela s'inscrit Cette page est le guide opérateur complet de la couche SOPS ; les lignes de référence de variables d'env sont dans [Référence des variables d'environnement](/fr/self-hosted/configuration/environment-reference#provider-secrets-encryption), et le format des fichiers fournisseur lui-même dans [Fournisseurs](/fr/self-hosted/configuration/providers). Si une clé est leakée, la rotation est le même walk ci-dessus exécuté en urgence. # Référence des variables d'environnement Source: https://tale.dev/docs/fr/self-hosted/configuration/environment-reference Tale lit sa configuration depuis un unique fichier `.env` à la racine du dépôt. Environ une douzaine de variables sont obligatoires au premier boot ; les autres ajustent le comportement. Cette page liste chaque variable que [`.env.example`](https://github.com/tale-project/tale/blob/main/.env.example) ship, sa valeur par défaut et la surface produit qui la consomme. Les groupes sont ordonnés selon le moment où tu en as besoin la première fois : identité de domaine, TLS, secrets, base de données, instance, observabilité, chiffrement des fournisseurs. Si une variable change de valeur, redémarre le conteneur plateforme (`docker compose restart tale-platform tale-convex`) pour qu'elle prenne effet. ## Comment lire cette page Chaque groupe est un tableau `Nom | Défaut | Description`. Les variables marquées **Obligatoire** doivent être définies pour que `docker compose up` réussisse. Les variables marquées **Optionnel** peuvent rester non définies ; la description nomme ce que désactiver la fonctionnalité signifie. Le fichier `.env.example` ship des commentaires inline qui expliquent chaque variable dans son contexte ; cette page est la référence structurée et groupée pour le même ensemble. ## Identité de domaine (obligatoire au premier boot) | Nom | Défaut | Description | | ----------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | `HOST` | `localhost` | **Obligatoire.** Nom d'hôte sans protocole. Utilisé pour le réseau Docker et le mail sortant. | | `SITE_URL` | `https://localhost` | **Obligatoire.** URL canonique complète incluant le schéma et tout port non standard. Les callbacks d'auth l'utilisent. | | `BASE_PATH` | non défini | **Optionnel.** Préfixe de chemin pour les déploiements en sous-chemin derrière un reverse proxy (ex. `/app`). Laisse vide pour la racine. | Le `SITE_URL` doit correspondre exactement à ce que l'utilisateur tape dans le navigateur. Un slash en queue, un port manquant ou `http` au lieu de `https` cassent le callback d'auth et produisent des boucles de sign-in. ## TLS | Nom | Défaut | Description | | ----------- | ------------ | --------------------------------------------------------------------------------------------------------------------- | | `TLS_MODE` | `selfsigned` | Un de `selfsigned`, `letsencrypt`, `external`. Voir [TLS et domaines](/fr/self-hosted/configuration/tls-and-domains). | | `TLS_EMAIL` | non défini | E-mail de contact pour les notifications Let's Encrypt. Optionnel mais recommandé en production. | `selfsigned` fait tourner Caddy avec un certificat généré — le navigateur avertit, OK pour le développement. `letsencrypt` exige un vrai domaine et les ports 80/443 joignables depuis l'Internet public. `external` fait servir Caddy en HTTP brut ; un reverse proxy amont termine TLS. ## Secrets de sécurité (obligatoire) | Nom | Défaut | Description | | ----------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `BETTER_AUTH_SECRET` | valeur d'exemple dans le fichier | **Obligatoire.** Secret base64 pour le signeur de session Better Auth. Génère avec `openssl rand -base64 32`. La rotation invalide chaque session. | | `ENCRYPTION_SECRET_HEX` | valeur d'exemple dans le fichier | **Obligatoire.** Clé hex de 32 octets. Clé AES-256 pour les credentials OAuth et connectors et entrée HKDF pour la secret-box des garde-fous. Génère avec `openssl rand -hex 32`. La rotation invalide chaque ciphertext en base ; les opérateurs doivent réinscrire les secrets concernés. | | `INSTANCE_SECRET` | valeur d'exemple dans le fichier | **Obligatoire.** Sert à dériver la clé admin Convex pour `tale deploy`. Le déploiement échoue si non défini. | Remplace les valeurs livrées dans `.env.example` avant d'exposer l'instance — ce sont des espaces réservés volontairement non sûrs. ## Base de données Tale fait tourner deux bases Postgres : la base opérationnelle (`db`, port 5432) derrière le backend Convex, et le corpus de connaissances (`knowledge-db`, port 5433) qui détient les fragments de documents, les embeddings et les pages crawlées. Les deux sont ParadeDB et partagent `DB_PASSWORD`, mais elles sont indépendantes — pointe l'une ou l'autre vers une infrastructure externe séparément. | Nom | Défaut | Description | | ------------------------ | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `DB_PASSWORD` | `tale_password_change_me` | **Obligatoire.** Mot de passe pour l'utilisateur Postgres auto-hébergé. Change-le avant la production. Utilisé par les deux conteneurs de base de données. | | `POSTGRES_URL` | construit depuis `DB_PASSWORD` | **Optionnel.** Override de l'URL de la base opérationnelle construite automatiquement. Utilise-le pour pointer sur un Postgres externe ou un hôte/port non standard. | | `KNOWLEDGE_DATABASE_URL` | `postgresql://tale:${DB_PASSWORD}@knowledge-db:5432/tale_knowledge` | **Optionnel.** URL de connexion que le backend Convex utilise pour le corpus de connaissances. Override pour relocaliser le corpus vers ton propre ParadeDB géré — la banque sensible à la résidence se déplace indépendamment. | | `KNOWLEDGE_DB_NAME` | `tale_knowledge` | **Optionnel.** Nom de la base de connaissances. Le conteneur `knowledge-db` fourni crée cette base au premier boot. | La forme opérationnelle auto-construite est `postgresql://tale:${DB_PASSWORD}@db:5432`. Convex attend cette URL sans nom de base ; le nom est dérivé de la configuration d'instance. Le corpus de connaissances vit dans `tale_knowledge` avec les schémas `private_knowledge` et `public_web` ; l'UI **Paramètres > Résidence des données** écrit une config par banque plus riche que ces variables brutes, couverte dans [Résidence des données](/fr/self-hosted/configuration/data-residency). ## Observabilité | Nom | Défaut | Description | | --------------------------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | `SENTRY_DSN` | non défini | DSN Sentry pour le suivi d'erreurs. Laisse vide pour désactiver. Compatible avec GlitchTip et Bugsink auto-hébergés. | | `SENTRY_TRACES_SAMPLE_RATE` | non défini | Taux d'échantillonnage optionnel pour les traces de performance (`0.0`–`1.0`). Le comportement par défaut dépend du déploiement. | | `METRICS_BEARER_TOKEN` | non défini | Token bearer requis pour accéder aux endpoints Prometheus `/metrics/*`. Laisse vide pour rendre les endpoints inatteignables de l'extérieur. | Définir `METRICS_BEARER_TOKEN` expose deux endpoints derrière le token : `/metrics/platform` et `/metrics/convex` (les 261 métriques intégrées de Convex, qui portent désormais aussi les timings RAG et de crawl). Voir [Configuration d'observabilité](/fr/self-hosted/configuration/observability-config) pour la configuration de scrape. ## Chiffrement des secrets de fournisseur | Nom | Défaut | Description | | ------------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `SOPS_AGE_KEY` | non défini | Clé secrète age inline. Chiffre `providers/*.secrets.json`. Mode par défaut après `tale init`. Plusieurs clés ne sont pas supportées en inline. | | `SOPS_AGE_KEY_FILE` | non défini | Chemin vers un fichier avec une ou plusieurs clés age (une par ligne ; commentaires `#` autorisés). Obligatoire pour la rotation. S'exclut mutuellement avec la forme inline. | Si les deux clés age ne sont pas définies, Tale stocke `providers/*.secrets.json` en JSON clair en mode 0600. Atteins ce mode seulement si le disque hôte est chiffré au repos ou si les fichiers sont produits par un outillage externe (un montage de secret Kubernetes, un template Vault). Faire tourner une clé age, c'est ajouter la nouvelle clé, réenregistrer chaque fournisseur dans l'UI, puis retirer l'ancienne. Voir [Secrets avec SOPS](/fr/self-hosted/configuration/secrets-with-sops) pour la marche complète de rotation. La source de clé par variable d'environnement ne nécessite aucun commutateur de déploiement : des identifiants peuvent porter seulement le _nom_ d'une variable d'environnement au lieu d'une clé stockée, tant que ce nom porte le préfixe réservé `TALE_PROVIDER_KEY_`. La barrière est fail-closed — tout autre nom est rejeté, donc le champ ne peut jamais pointer sur un secret de déploiement étranger — et les noms sont plafonnés à 40 caractères. Définis la variable ici ou dans ton gestionnaire de secrets pour que la plateforme et le backend Convex puissent tous deux la lire ; le mécanisme complet est documenté dans [Fournisseurs](/fr/self-hosted/configuration/providers). Un identifiant de type courtier d'abonnement dispose d'un second espace de noms, distinct, pour le secret que Tale présente **au courtier** : ce champ accepte un nom de variable d'environnement sous le préfixe réservé `TALE_TOKEN_SOURCE_`, plafonné à 60 caractères. Les deux préfixes restent séparés à dessein — un secret de courtier n'est pas une clé API de fournisseur, et aucun des deux champs ne peut nommer une variable hors de son propre espace de noms. ## Drapeaux de fonctionnalité Bascules optionnelles pour des fonctionnalités non activées par défaut. Chaque drapeau active ou désactive une fonctionnalité au boot ; basculer demande un redémarrage du conteneur plateforme. | Nom | Défaut | Description | | ------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `TRUSTED_HEADERS_ENABLED` | `false` | Active le mode auth par trusted headers (identité fournie par le reverse proxy). | | `FILE_EVENTS_ENABLED` | `false` | Active les événements de surveillance de fichiers pour le connector OneDrive-sync. | | `TALE_DEPLOYMENT_CONFIG_ADMINS` | non défini | Allowlist de courriels (séparés par des virgules) des opérateurs autorisés à modifier la résidence des données du déploiement. Vide/non défini = lecture seule pour tous les admins. | ## Contrôleur de redémarrage Le sidecar `controller`, à activer explicitement, alimente le bouton en un clic **Appliquer & redémarrer** de la page [Résidence des données](/fr/self-hosted/configuration/data-residency) : il redémarre le conteneur `convex` après un changement de configuration, pour que la plateforme exposée au navigateur n'ait jamais besoin d'accéder au socket Docker. Active-le avec `docker compose --profile controller up -d`, puis définis les deux variables ci-dessous. Laisse-les non définies pour continuer à redémarrer `convex` à la main. | Nom | Défaut | Description | | ------------------ | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `CONTROLLER_TOKEN` | non défini | Secret HMAC partagé pour **Appliquer & redémarrer**. Le `controller` refuse de démarrer sans lui, et la plateforme signe chaque requête de redémarrage avec lui — les deux valeurs doivent correspondre. Génère-le avec `openssl rand -hex 32`. | | `CONTROLLER_URL` | non défini | URL de base que la plateforme utilise pour joindre le sidecar `controller` (p. ex. `http://controller:8004` sur le réseau interne). Si celle-ci ou `CONTROLLER_TOKEN` est non définie, **Appliquer & redémarrer** montre plutôt la commande manuelle. | ## Réglage du retrieval RAG Réglages optionnels pour la recherche dans la base de connaissances. Le chemin RAG en in-process (node-actions Convex) re-note les résultats avec un cross-encoder quand le re-ranking est activé. Tous portent le préfixe `RAG_` et sont lus par les conteneurs `platform` et `convex` au boot ; après un changement, lance `docker compose restart platform convex` pour qu'il prenne effet. | Nom | Défaut | Description | | ---------------------------- | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `RAG_RERANKING_ENABLED` | `false` | Re-note les candidats fusionnés BM25 + vecteur avec un cross-encoder avant de renvoyer les résultats. Améliore la précision au prix de la latence par requête. | | `RAG_RERANKING_MODEL` | `cross-encoder/ms-marco-MiniLM-L-6-v2` | Identifiant du modèle cross-encoder transmis au fournisseur de rerank. | | `RAG_RERANKING_PROVIDER` | `local` | Doit être réglé sur `api` pour activer le re-ranking — il poste les candidats à un endpoint `/rerank` externe (compatible Cohere/Jina). `local` n'est plus supporté et échoue tout de suite. | | `RAG_RERANKING_TOP_K` | `10` | Nombre maximal de résultats que le reranker renvoie. La réponse ne dépasse jamais le `top_k` de la requête. | | `RAG_RERANKING_CANDIDATES` | `30` | Taille du pool de candidats fourni au reranker. Un pool plus large améliore la qualité de re-notation et coûte proportionnellement plus de temps par requête. | | `RAG_RERANKING_API_BASE_URL` | non défini | URL de base du fournisseur de rerank ; la plateforme appelle `{base_url}/rerank`. Obligatoire quand le re-ranking est activé. | | `RAG_RERANKING_API_KEY` | non défini | Token Bearer envoyé à l'endpoint de rerank externe. Laisse-le non défini pour les endpoints sans authentification. | Le re-ranking est livré désactivé parce qu'il ajoute de la latence par requête et dépend d'un endpoint externe. Active-le — en réglant `RAG_RERANKING_PROVIDER=api` et en pointant `RAG_RERANKING_API_BASE_URL` vers un service de rerank hébergé — quand la précision du retrieval compte plus que le temps de réponse. Il n'y a aucun modèle en in-process à télécharger ou à mettre en cache ; le re-ranking désactivé, la recherche renvoie le classement hybride BM25 + vecteur simple. ## Sessions | Nom | Défaut | Description | | ------------------------------ | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `SESSION_IDLE_TIMEOUT_MINUTES` | non défini | **Optionnel.** Déconnecte une session après ce nombre de minutes d'inactivité (`1`–`1440`). La fenêtre glisse à chaque activité et est appliquée côté serveur — sessions e-mail/mot de passe, SSO et trusted headers. | Laisse-le non défini pour conserver la durée de session par défaut. Si défini, une session inactive expire côté serveur une fois la fenêtre écoulée, tandis qu'une session active continue de glisser à chaque requête. Les Administrateurs d'organisation peuvent raccourcir la fenêtre effective par organisation — jamais l'allonger au-delà de ce plafond — via la [politique de gouvernance du délai d'inactivité de session](/fr/platform/admin/governance/policies-and-limits) ; les sessions inactives sous cette politique sont révoquées par une passe qui tourne environ toutes les cinq minutes. ## Ingestion de liens vidéo (yt-dlp) Quand Tale ingère un lien vidéo, il récupère sa transcription pour l'agent. YouTube bloque l'accès automatisé depuis les IP de centres de données/serveurs, ce qui peut échouer sur un déploiement cloud. Le déploiement embarque par défaut un fournisseur de PO tokens câblé d'origine (voir [Ingestion vidéo](/fr/self-hosted/configuration/video-ingestion) pour le tableau complet) ; les options ci-dessous sont des surcharges et des escalades facultatives. Aucune ne garantit un contournement — une IP de sortie propre est le levier le plus important. Lues par le conteneur `convex` et réévaluées à chaque ingestion, donc une modification prend effet sans redémarrage. | Nom | Défaut | Description | | -------------------------------- | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `VIDEO_INGEST_PROXY_URL` | non défini | Acheminer la sortie de yt-dlp via un proxy (une IP résidentielle/FAI fonctionne le mieux ; les proxys de centre de données sont généralement signalés aussi). Schémas : `http`, `https`, `socks4`, `socks4a`, `socks5`, `socks5h` — privilégie `socks5h://` pour que le DNS soit résolu au niveau du proxy. | | `VIDEO_INGEST_POT_PROVIDER_URL` | `http://bgutil-provider:4416` (intégré) | URL de base du fournisseur de PO tokens qui fournit les tokens GVS levant le mur anti-bot de YouTube. Par défaut, le sidecar compose `bgutil-provider` quand le plugin intégré est présent — à définir uniquement pour pointer vers un fournisseur sur un autre hôte. | | `VIDEO_INGEST_FETCH_POT` | `always` dès qu'un fournisseur est branché | Quand yt-dlp demande des PO tokens au fournisseur (`never`/`auto`/`always`). Le `auto` de yt-dlp n'en demande jamais pour la requête player — précisément là où le mur anti-bot frappe —, Tale passe donc à `always` dès qu'un fournisseur est présent. `never` contourne un fournisseur défaillant. | | `VIDEO_INGEST_YTDLP_PLUGIN_DIRS` | `/opt/yt-dlp/plugins` (intégré) | Répertoire depuis lequel yt-dlp charge les plugins — chaque plugin imbriqué un niveau plus bas (`<dir>/<nom>/yt_dlp_plugins/…`). Par défaut, le répertoire de plugins bgutil intégré quand il est présent ; ne le remplace que pour ajouter tes propres plugins. | | `VIDEO_INGEST_COOKIES_FILE` | non défini | Chemin vers un fichier de cookies Netscape. Des cookies invités issus d'une session privée augmentent la limite de débit sans risque de bannissement ; des cookies de compte débloquent le contenu restreint mais risquent le compte. | | `VIDEO_INGEST_PLAYER_CLIENT` | `default,tv_simply` | Liste de repli des clients de lecture YouTube, séparés par des virgules. Quand un fournisseur de PO tokens est branché, la valeur par défaut s'élargit à `default,mweb,tv_simply` (mweb exige un token GVS) ; définis-la explicitement pour forcer une liste. | | `VIDEO_INGEST_PO_TOKEN` | non défini | PO token défini manuellement (`CLIENT.CONTEXT+TOKEN`). Surtout pour les tests — les tokens sont liés à l'ID de la vidéo et éphémères ; privilégie le fournisseur. | | `VIDEO_INGEST_IMPERSONATE` | non défini | Cible d'imitation TLS/JA3 du navigateur (p. ex. `safari`). Nécessite `curl_cffi` dans l'image ; à laisser non défini sauf disponibilité connue. | | `VIDEO_INGEST_BIN_DIR` | non défini | Répertoire ajouté en tête du `PATH` du processus enfant yt-dlp/ffmpeg, pour qu'un `yt-dlp` auto-provisionné (et son runtime Deno) installé hors des répertoires bin intégrés soit trouvé en premier. L'image `convex` intègre yt-dlp dans le `PATH`, donc laisse-le non défini là ; définis-le sur un hôte ou une machine de dev avec sa propre toolchain. | | `VIDEO_INGEST_FFMPEG_LOCATION` | `/usr/bin/ffmpeg` | Chemin absolu vers le ffmpeg que yt-dlp utilise pour la post-production (conversion des sous-titres, extraction audio). À surcharger quand ffmpeg vit ailleurs — p. ex. le `/opt/homebrew/bin/ffmpeg` de Homebrew sur une machine de dev macOS. | Aucune de ces options ne garantit le succès face à la détection adaptative de YouTube. Les vidéos publiques ordinaires, les plateformes moins agressives ou un déploiement à IP résidentielle/auto-hébergé fonctionnent généralement sans elles. ## Où cela s'inscrit Les variables ici sont la surface de contact de l'opérateur ; la surface UI qui en consomme la plupart vit sous [Plateforme administration](/fr/platform/admin/overview). Les clés de fournisseur sont la moitié-et-moitié : les clés elles-mêmes vivent dans `providers/*.secrets.json`, mais l'UI sous **Paramètres > Fournisseurs IA** est ainsi que tu les ajoutes et les fais tourner en pratique. La lecture suivante à mettre en file est [Fournisseurs](/fr/self-hosted/configuration/providers) — elle couvre les fichiers de connecteurs livrés et les variables réservées qui portent les clés de fournisseur. # Résidence des données Source: https://tale.dev/docs/fr/self-hosted/configuration/data-residency Une installation Tale auto-hébergée tourne sur une infrastructure que tu contrôles déjà, donc ses données vivent sur tes hôtes par défaut. La **résidence des données** sert au cas où tu veux pointer des banques de données précises vers ton propre Postgres géré ou ton stockage objet plutôt que vers les conteneurs fournis — par exemple pour garder le texte des documents dans une base que ton équipe exploite, ou les fichiers téléversés dans ton propre bucket S3. Le corpus de connaissances tourne comme son propre conteneur (`knowledge-db`) précisément pour pouvoir être relocalisé ou remplacé indépendamment de la base opérationnelle — c'est la banque qui compte le plus pour la majorité des exigences de résidence. Les administrateurs configurent cela dans **Paramètres > Résidence des données** ; le changement est écrit dans un seul fichier de configuration au niveau du déploiement et **prend effet au redémarrage des conteneurs concernés**. Cette page couvre ce qui peut être déplacé, le seul prérequis qui mord (ParadeDB), comment la configuration est stockée et appliquée, et comment redémarrer sans risque. ## Activer la modification **Paramètres > Résidence des données** est une seule page avec deux familles de sections : les banques à l'échelle du déploiement que toutes les organisations partagent, et celles qu'une organisation apporte pour elle seule. Chaque section s'affiche en lecture seule ou modifiable selon ce que la personne qui la lit a le droit de changer, et la page nomme l'état dans lequel tu te trouves. Voir la page est ouvert à tout owner ou admin d'une organisation ; **modifier les banques du déploiement** — repointer une banque de données, enregistrer des secrets, lancer un test de connexion ou appliquer un redémarrage — est réservé à une allowlist nommée d'opérateurs. Liste leurs courriels de connexion (séparés par des virgules) dans `.env` et redémarre : ```bash TALE_DEPLOYMENT_CONFIG_ADMINS=alice@example.com,bob@example.com ``` Si l'allowlist est vide ou non définie, les sections de déploiement montrent toujours la configuration actuelle aux administrateurs, mais en lecture seule — les actions d'en-tête **Enregistrer le déploiement** et **Appliquer & redémarrer** n'apparaissent que pour les opérateurs de l'allowlist. Seul un admin connecté dont le courriel figure sur la liste rend ces sections modifiables ; la page t'indique quel courriel ajouter. Les entrypoints consomment le fichier de configuration quelle que soit l'allowlist, donc un opérateur qui préfère éditer le fichier à la main sur le disque peut le faire sans nommer d'éditeurs UI. ## Ce que tu peux relocaliser Trois banques de données, chacune indépendante et optionnelle. Un réglage absent signifie « utilise le défaut fourni » — une installation neuve sans configuration reste donc inchangée. - **Base de connaissances** — le corpus de connaissances : métadonnées des documents, texte des fragments extraits, embeddings, index BM25, cache sémantique et pages web crawlées. Elle est livrée comme le conteneur `knowledge-db` (`tale_knowledge`, avec les schémas `private_knowledge` et `public_web`) et c'est la banque qui compte le plus pour les exigences de résidence, car elle détient le contenu de tes documents. Pointe-la vers ton propre Postgres géré pour garder le corpus sur une infrastructure que ton équipe exploite. - **Stockage de fichiers** — où vivent les fichiers téléversés (les blobs d'origine). Par défaut ils résident sur le volume Convex local ; tu peux les pointer vers un bucket externe compatible S3. - **Base de données applicative** (avancé) — la base Convex opérationnelle (le conteneur `db` fourni). Le backend Convex déduit le nom de cette base de `INSTANCE_NAME` (`tale_platform`) et se connecte uniquement via hôte:port, donc le Postgres externe doit contenir une base nommée exactement `tale_platform`. Son mode TLS est fixé par le pilote Convex et n'est pas configurable. > Note : la base de connaissances et la base de données applicative sont deux instances Postgres séparées — déplacer l'une ne touche pas l'autre. Relocaliser la base de connaissances déplace le texte extrait et les embeddings ; les fichiers téléversés d'origine ne suivent que si tu relocalises aussi le **stockage de fichiers** vers S3. ## Le prérequis ParadeDB La base de connaissances utilise deux extensions Postgres : `vector` (pgvector) pour les embeddings et `pg_search` (ParadeDB) pour la recherche hybride plein texte/BM25. Un Postgres de connaissances externe **doit faire tourner ParadeDB** (qui regroupe les deux) pour une qualité de recherche complète. Si tu le pointes vers un Postgres simple qui n'a que `pgvector`, l'indexation et la recherche vectorielle fonctionnent toujours, mais la recherche hybride se réduit à du **vectoriel seul** — la moitié BM25 est silencieusement sautée. Le bouton **Tester la connexion** signale la disponibilité de `pgvector` et de `pg_search` pour que tu le voies avant de t'engager. La base de connaissances externe doit déjà exister (elle peut porter n'importe quel nom que tu saisis — `tale_knowledge` par convention) avec les schémas `private_knowledge` et `public_web` ; les migrations de schéma de base vivent dans [`services/db/migrations/`](https://github.com/tale-project/tale/tree/main/services/db/migrations) et sont appliquées via dbmate quand la base démarre. ## Bases de connaissances par organisation Les banques ci-dessus sont au niveau du déploiement — chaque organisation les partage. Une organisation seule peut au contraire pointer **son propre** corpus de connaissances vers un Postgres que tu provisionnes pour elle, pendant que toutes les autres orgs gardent le `knowledge-db` fourni. Réserve cela aux cas où le contenu documentaire et web-crawlé d'un locataire doit résider sur une infrastructure isolée du reste — une exigence de résidence plus stricte que ce que le défaut du déploiement satisfait. L'intégralité du corpus de connaissances de l'org se déplace — les deux schémas : `private_knowledge` (métadonnées des documents, texte des fragments, embeddings et cache sémantique) et `public_web` (les pages de sites web du crawler, leur texte de fragments et les embeddings). Rien dans la base de connaissances d'une organisation n'est partagé avec une autre organisation. La connexion vit dans le répertoire de configuration propre à l'organisation, pas dans le fichier de déploiement : - `$TALE_CONFIG_DIR/<orgSlug>/knowledge/connection.json` — hôte, port, base, utilisateur et sslmode. - `$TALE_CONFIG_DIR/<orgSlug>/knowledge/connection.secrets.json` — le mot de passe, chiffré avec SOPS dès qu'une clé age SOPS est configurée (voir [Secrets avec SOPS](/fr/self-hosted/configuration/secrets-with-sops)). - `$TALE_CONFIG_DIR/<orgSlug>/knowledge/embedding.json` — le modèle d'embedding de l'organisation : fournisseur, identifiants stockés optionnels, tag du modèle, largeur des vecteurs et URL de base optionnelle compatible OpenAI. Le même prérequis ParadeDB s'applique. L'org valide sa base candidate avec un test de connexion à l'échelle de l'organisation qui signale la disponibilité de `pgvector` et `pg_search` avant de basculer ; une cible avec seulement pgvector réduit la recherche de cette org au vectoriel seul. La base peut démarrer vide — Tale crée les schémas `private_knowledge` et `public_web` au premier accès, tu n'appliques donc jamais les migrations de base à la main. Ce chemin retombe sans risque. Une organisation sans `connection.json` garde le `knowledge-db` par défaut du déploiement exactement comme avant, la fonctionnalité ne change donc rien pour les orgs qui n'y adhèrent pas. Deux organisations qui pointent vers la même base partagent un seul pool de connexions et — contrairement aux banques au niveau du déploiement — un changement par org ne demande aucun redémarrage de conteneur : la prochaine requête de cette org est routée vers sa propre base. Un propriétaire ou un admin de l'organisation peut aussi gérer cette connexion depuis l'UI : les sections par organisation de **Paramètres > Résidence des données** lisent et écrivent exactement ces fichiers, avec le même test de connexion avant de basculer. Ces sections restent modifiables pour un propriétaire ou un admin d'org, que l'allowlist d'opérateurs les nomme ou non, parce que les fichiers qu'elles touchent appartiennent à l'organisation et non au déploiement. Les fichiers JSON sur le disque restent la source de vérité — un opérateur qui préfère les éditer à la main n'a besoin d'aucune étape UI. ### Le modèle d'embedding de l'organisation La recherche de connaissances demande un réglage de plus par organisation avant de pouvoir tourner : le **modèle d'embedding** — quel fournisseur et quel modèle transforment documents et requêtes en vecteurs, et à quelle largeur exacte. Sans lui, l'indexation et la recherche refusent avec une erreur actionnable plutôt que de deviner un modèle. Règle-le dans la section **Modèle d'embedding** de **Paramètres > Résidence des données** (ou écris `embedding.json` à la main) : choisis un fournisseur pour lequel des identifiants sont stockés, nomme le tag du modèle comme le fournisseur l'écrit, et déclare la largeur que produit le modèle — elle n'est jamais déduite du nom du modèle, parce qu'une mauvaise supposition écrit des vecteurs que la recherche ne peut silencieusement plus exploiter. La largeur est fixée **par base de données** à l'écriture du premier vecteur. Sur le `knowledge-db` partagé du déploiement, toutes les organisations doivent donc s'accorder sur une largeur ; une organisation qui veut un autre modèle d'embedding à une autre largeur est exactement le cas de la base de connaissances dédiée ci-dessus. ## Stockage d'objets par organisation Le même schéma par organisation couvre les fichiers téléversés. Une organisation seule peut pointer **ses propres** blobs de fichiers — documents du Knowledge Hub, pièces jointes de chat, audio et médias générés — vers un bucket compatible S3 que tu provisionnes pour elle (AWS S3, MinIO, Cloudflare R2, …), pendant que toutes les autres orgs gardent le défaut du déploiement. Le bucket est dédié à cette organisation ; rien de ce qu'il contient n'est partagé avec une autre. La connexion vit à côté de celle des connaissances, dans le répertoire de configuration de l'organisation : - `$TALE_CONFIG_DIR/<orgSlug>/object-storage/connection.json` — région, endpoint optionnel (pour MinIO/R2), indicateur path-style, bucket et un préfixe de clé optionnel. - `$TALE_CONFIG_DIR/<orgSlug>/object-storage/connection.secrets.json` — la paire de clés d'accès, chiffrée avec SOPS dès qu'une clé age SOPS est configurée (voir [Secrets avec SOPS](/fr/self-hosted/configuration/secrets-with-sops)). Contrairement au basculement S3 au niveau du déploiement ci-dessus, ce chemin n'est **pas** réservé aux installations neuves : dès que la configuration existe, les nouveaux téléversements vont dans le bucket de l'org, tandis que les fichiers stockés avant restent lisibles là où ils sont — les références mixtes sont prises en charge, tu peux donc basculer à tout moment. Les fichiers stockés plus tôt restent dans le stockage Convex jusqu'à ce que tu les relocalises avec le backfill de blobs ci-dessous. Si tu supprimes la configuration, les nouveaux téléversements retournent au défaut du déploiement ; les fichiers déjà écrits dans le bucket y restent, mais Tale ne peut plus les lire tant que la connexion n'est pas rétablie. Aucun redémarrage n'est nécessaire, dans un sens comme dans l'autre. Les admins d'org gèrent aussi cette connexion dans les mêmes sections par organisation de **Paramètres > Résidence des données** ; son test de connexion effectue un aller-retour réel écriture-lecture-suppression contre le bucket avant que tu t'engages. Comme pour la connexion des connaissances, les fichiers JSON restent la source de vérité. > **Autorise l'origine de l'app dans la politique CORS du bucket.** Les téléversements et les téléchargements passent directement du navigateur au bucket via des URL présignées : le bucket doit donc accepter les requêtes cross-origin depuis l'URL de ton déploiement — autorise cette origine avec les méthodes `GET`, `PUT` et `HEAD` et tous les en-têtes de requête (Cloudflare R2 : **Settings > CORS Policy** du bucket ; AWS S3 et MinIO : la configuration CORS du bucket). Le test de connexion dans l'app s'exécute côté serveur, pas dans le navigateur — une politique CORS manquante ne se montre donc que plus tard, sous la forme d'un téléversement échoué. ### Déplacer les fichiers pré-existants dans le bucket Connecter le bucket ne réachemine que les **nouveaux** téléversements ; les blobs écrits avant la connexion restent dans le `_storage` de Convex et continuent de fonctionner via les références mixtes ci-dessus. Pour amener aussi cet historique sur ta propre infrastructure — tout l'intérêt de la résidence des données — lance le **backfill de blobs** : il copie chaque blob pré-existant dans le bucket de l'org, vérifie qu'il revient identique octet pour octet, réécrit chaque ligne qui le référence et supprime la copie Convex. Un admin d'org le lance depuis l'UI : une fois la connexion au bucket enregistrée, la section Stockage d'objets de **Paramètres > Résidence des données** affiche **Déplacer les fichiers existants** — confirme, et le déplacement tourne en arrière-plan pendant que les téléversements continuent ; une ligne de statut dans la même section rapporte la progression et l'issue du dernier lancement. Un opérateur ayant accès à la CLI Convex peut lancer le même moteur depuis un shell, en passant l'id de l'organisation. Fais d'abord un essai à blanc pour voir ce qui serait déplacé, puis le vrai lancement : ```bash # Essai à blanc — compte et échantillonne ce qui serait déplacé, n'écrit rien : bunx convex run object_storage/backfill_actions:migrateOrgBlobsToObjectStorage '{"organizationId":"<organizationId>","dryRun":true}' # Le vrai lancement — retire dryRun une fois les comptes vérifiés : bunx convex run object_storage/backfill_actions:migrateOrgBlobsToObjectStorage '{"organizationId":"<organizationId>"}' ``` Le backfill est **idempotent** et **limité à l'org** : il ne déplace que les blobs de cette organisation, saute tout ce qui est déjà dans le bucket, et laisse chaque source Convex en place tant que sa copie n'est pas vérifiée — un nouveau lancement après une interruption reprend donc sans risque. Un vrai lancement exige que la connexion au bucket soit déjà configurée ; un essai à blanc, non. Ce n'est délibérément **pas** une migration de framework versionnée — il tourne à la demande, par organisation, quand tu choisis de relocaliser l'historique d'un locataire, pas à une frontière de version. ## Stockage de fichiers sur S3 Le stockage de fichiers externe est tout-ou-rien à travers les cas d'usage de stockage de Convex, donc tu fournis **cinq buckets** — files, exports, snapshot-imports, modules et search — plus une région et des identifiants. Pour les services compatibles S3 (MinIO, Cloudflare R2), définis l'endpoint et active l'adressage path-style. > **Greenfield uniquement.** Faire passer le stockage de fichiers de local à S3 ne migre **pas** les blobs déjà sur le volume local — Convex les cherche dans le bucket et ne les trouve pas. Définis S3 au déploiement initial, ou copie le stockage local existant dans le bucket hors bande avant de basculer. ## Comment la configuration est stockée Enregistrer écrit deux fichiers à la racine de configuration (pas sous un répertoire d'org) : - `deployment.json` — la configuration non secrète (hôtes, ports, buckets, modes). - `deployment.secrets.json` — les mots de passe de base de données et les clés S3, chiffrés avec SOPS (voir [Secrets avec SOPS](/fr/self-hosted/configuration/secrets-with-sops)). Au démarrage, l'entrypoint `convex` les lit et en dérive ses connexions avant de démarrer. L'ingestion et la récupération de connaissances tournent dans le backend Convex, c'est donc le seul conteneur qui ouvre la connexion à la base de connaissances — il n'y a pas de service de récupération séparé à configurer. Le contrat est **fail-closed** : un `deployment.json` présent mais impossible à parser, un secret indéchiffrable ou une configuration sans champs requis **interrompt le démarrage** au lieu de retomber silencieusement sur la base fournie — mal router des données réglementées est pire que ne pas démarrer. Un fichier absent est le chemin par défaut normal. ## Appliquer un changement : redémarrage La configuration est lue au démarrage, donc un enregistrement ne prend effet qu'au redémarrage du conteneur **`convex`** (la plateforme elle-même n'a pas besoin de redémarrer). Deux façons : - **Manuel** — `docker compose restart convex`, ou `tale deploy --services convex` pour un roulement blue-green sans interruption. - **Un clic** — active le service `controller` à activer explicitement (`docker compose --profile controller up -d`). C'est un petit sidecar uniquement interne qui redémarre le service `convex` autorisé sur une requête signée par HMAC venant de l'app, pour que la plateforme exposée au navigateur n'ait jamais besoin d'accéder au socket Docker. Quand il tourne, le bouton **Appliquer & redémarrer** fait le redémarrage pour toi ; définis `CONTROLLER_TOKEN` (partagé avec la plateforme) et `CONTROLLER_URL` dans `.env`. Sans lui, le bouton montre la commande manuelle. Les variables d'environnement pertinentes sont `TALE_DEPLOYMENT_CONFIG_ADMINS` (l'allowlist de courriels, séparés par des virgules, des opérateurs autorisés à modifier) et — seulement avec le `controller` en un clic — `CONTROLLER_TOKEN` (le secret HMAC partagé) et `CONTROLLER_URL` (p. ex. `http://controller:8004`). Définis-les dans `.env`. Voir aussi [Référence des variables d'environnement](/fr/self-hosted/configuration/environment-reference) et [Secrets avec SOPS](/fr/self-hosted/configuration/secrets-with-sops). # Ingestion vidéo Source: https://tale.dev/docs/fr/self-hosted/configuration/video-ingestion Quand Tale ingère un lien vidéo, il va chercher la transcription de la vidéo avec `yt-dlp`. Les plateformes vidéo — YouTube le plus agressivement — soumettent les requêtes venant d’IP de centres de données et de serveurs à un mur « confirme que tu n’es pas un robot », si bien qu’un déploiement auto-hébergé tout neuf sur une VM cloud peut voir l’ingestion échouer là où un ordinateur portable sur une connexion domestique réussirait. Cette page couvre les trois couches que Tale fournit pour passer outre, de celle qui ne demande aucune configuration à celle qui en demande le plus. <Info> Les déploiements **Cloud** managés exécutent ces mesures à ta place — cette page s’adresse aux opérateurs qui font tourner Tale sur leur propre infrastructure. </Info> ## Couche 1 — le fournisseur de PO tokens (par défaut, sans config) La mesure la plus efficace à elle seule est un **token de preuve d’origine (PO)** : une valeur signée qui fait passer une requête pour une vraie session de navigateur. Tale embarque un fournisseur de tokens câblé d’origine — le plugin `yt-dlp` est intégré à l’image et un sidecar `bgutil-provider` sert les tokens sur le réseau interne. Aucune variable d’environnement n’est requise ; un `docker compose up` ou `tale deploy` tout frais le fait tourner. Tu peux pointer `yt-dlp` vers un fournisseur sur un autre hôte avec `VIDEO_INGEST_POT_PROVIDER_URL`, ou fournir un token frappé manuellement avec `VIDEO_INGEST_PO_TOKEN` — les deux sont documentés dans la [référence d’environnement](/fr/self-hosted/configuration/environment-reference). Un sidecar en panne ne casse jamais la stack : l’ingestion se rabat sur l’absence de token, exactement comme si la couche était absente. ## Couche 2 — un proxy de sortie Quand le token seul ne suffit pas — certaines plages d’IP sont signalées quoi qu’il arrive —, achemine la récupération via un **proxy de sortie** sur une IP à laquelle la plateforme fait confiance. Les proxys résidentiels et hébergés chez un FAI fonctionnent le mieux ; les proxys de centre de données et commerciaux sont souvent signalés au même titre que le serveur lui-même. Règle `VIDEO_INGEST_PROXY_URL` sur l’URL du proxy. Un schéma `socks5h://` résout le DNS au niveau du proxy (le choix le plus sûr) ; `http`, `https`, `socks4`, `socks4a`, `socks5` et `socks5h` sont tous acceptés. La valeur peut porter des identifiants — Tale les efface de chaque ligne de log. ```bash .env VIDEO_INGEST_PROXY_URL=socks5h://user:pass@residential.example:1080 ``` Le proxy s’applique à chaque phase d’une récupération — métadonnées, sous-titres et audio —, si bien que toute l’ingestion partage un seul chemin de sortie de confiance. ## Couche 3 — le pool de sessions de navigateur préchauffées La mesure la plus forte consiste à présenter des cookies issus d’une **vraie session de navigateur qui a déjà passé la vérification anti-bot**. Tale garde un pool de ces sessions, indexé par domaine, et en confie une à chaque récupération pour que la plateforme voie un visiteur qui revient plutôt qu’un serveur au premier contact. Les sessions sont stockées chiffrées au repos (le fichier de cookies est scellé avec l’`ENCRYPTION_SECRET_HEX` du déploiement) et ne sont jamais exposées au code exécuté par l’agent — elles ne vivent que dans la couche de récupération côté serveur. Une session qui commence à se faire bloquer est refroidie puis mise hors service automatiquement, et les sessions expirées sont balayées selon un calendrier. Remplir le pool est une étape avancée et manuelle : capture un fichier de cookies Netscape depuis un navigateur qui a résolu le défi pour la plateforme cible, puis importe-le via l’action interne `importBrowserSession`. Le même pool alimente aussi l’outil de récupération web et le crawler de l’agent, si bien qu’une session préchauffée pour un domaine profite à chaque accès côté serveur vers celui-ci. <Warning> Les cookies de compte débloquent le contenu restreint mais mettent le compte en danger si la plateforme signale un usage automatisé. Privilégie des cookies issus d’un compte jetable ou créé pour l’occasion, et ne commite jamais un fichier de cookies dans le gestionnaire de versions. </Warning> ## De quelle couche ai-je besoin ? <CardGroup cols="2"> <Card title="Tout juste déployé, certaines vidéos échouent" icon="circle-play"> La couche 1 est déjà active. Réessaie — beaucoup de blocages sont passagers. Ne passe à la couche 2 que si les échecs persistent. </Card> <Card title="La plupart des vidéos échouent sur cet hôte" icon="globe"> L’IP du déploiement est probablement signalée. Ajoute un proxy de sortie (couche 2) sur une IP résidentielle. </Card> <Card title="Une plateforme précise te bloque encore" icon="key-round"> Préchauffe une session de navigateur pour cette plateforme (couche 3) pour que la récupération présente des cookies déjà validés. </Card> <Card title="Référence complète des variables" icon="settings"> Chaque réglage `VIDEO_INGEST_*`, avec ses valeurs par défaut, se trouve dans la [référence d’environnement](/fr/self-hosted/configuration/environment-reference). </Card> </CardGroup> ## Une attente honnête Aucune de ces couches ne peut garantir l’ingestion face à une plateforme qui travaille activement à bloquer l’accès automatisé depuis des IP arbitraires. Ensemble, elles font réussir l’ingestion partout où ta sortie est de confiance, et chaque déploiement dispose d’un chemin pris en charge pour escalader. Si une plateforme bloque durement ton serveur, la transcription peut tout de même être amenée à la main — colle-la dans un document [Connaissances](/fr/platform/knowledge/documents). # Configuration de l'observabilité Source: https://tale.dev/docs/fr/self-hosted/configuration/observability-config Tale ship trois coutures d'observabilité : logs stdout depuis chaque conteneur, métriques au format Prometheus derrière un bearer token, et reporting d'erreurs Sentry optionnel. Les défauts sont assez bruyants pour repérer un crash et assez discrets pour tenir dans le journald d'un seul hôte ; les boutons de production ci-dessous ajoutent les chemins structurés que ta stack de monitoring existante peut scraper. Aucune des trois n'envoie quoi que ce soit hors-hôte sauf si tu le configures. Cette page couvre les interrupteurs côté serveur. Le playbook d'alerte côté opérateur vit dans [Opérations](/fr/self-hosted/operate/observability/operations), et la recherche par symptôme dans [Dépannage](/fr/self-hosted/operate/observability/troubleshooting). ## Logs Chaque conteneur écrit des logs JSON structurés ou console vers stdout, capturés par le driver `json-file` par défaut de Docker avec une rotation de 10 Mo par fichier et 3 fichiers. La destination des logs est fonction de comment tu déploies : - Hôte unique avec journald — `journalctl -u docker` porte le tout. - Hôte unique sans journald — `docker compose logs -f <service>` pour le tailing en direct. - Aggregator (Loki, Vector, Fluent Bit) — pointe le driver de logging Docker dessus via `daemon.json`. Tale ne ship pas de log shipper. L'échange de driver est le point de connector supporté. ## Métriques Le proxy Caddy expose trois chemins de métriques derrière un seul bearer token : | Chemin | Source | Ce qui est dedans | | -------------------- | --------------- | ------------------------------------------------------------------------------------------------------- | | `/metrics/platform` | `tale-platform` | Latence HTTP, compteurs de routes, métriques de processus Node, gauges de cible SLA de temps de réponse | | `/metrics/convex` | `tale-convex` | 261 métriques Convex intégrées, plus les timings RAG et de crawl | | `/metrics/sla-rules` | `tale-platform` | Rules Prometheus de recording + alerting générées pour les SLA de temps de réponse | Le travail de connaissances (recherche RAG, ingestion de documents, crawling web) tourne désormais dans le backend Convex, donc ses timings empruntent la série `/metrics/convex` plutôt qu'un endpoint séparé. Mets `METRICS_BEARER_TOKEN` dans `.env` pour activer ces endpoints ; laisse-le non défini pour qu'ils retournent 401 à chaque requête. Le chemin `/metrics/sla-rules` est un fichier YAML de rules en lecture seule que tu charges dans Prometheus, pas une cible de scrape — les seuils qu'il porte sont documentés dans [Opérations](/fr/self-hosted/operate/observability/operations). Tout sauf les chemins listés retourne aussi 401, donc un scraper mal routé ne voit pas accidentellement les endpoints de santé internes de la plateforme. Une stanza de scrape Prometheus qui marche : ```yaml scrape_configs: - job_name: tale-platform scheme: https metrics_path: /metrics/platform authorization: credentials: <METRICS_BEARER_TOKEN> static_configs: - targets: ['tale.example.com'] ``` Duplique la stanza par chemin, ou utilise un job unique avec `relabel_configs` si tu préfères. ## Suivi d'erreurs avec Sentry Sentry est opt-in via `SENTRY_DSN`. GlitchTip et Bugsink auto-hébergés marchent aussi, puisqu'ils parlent le même format de DSN. Les conteneurs plateforme et convex lisent tous les deux le DSN et taguent les événements avec le nom du conteneur. ```bash # .env SENTRY_DSN=https://your-key@your-sentry-host/project-id SENTRY_TRACES_SAMPLE_RATE=0.1 ``` Le sample rate plafonne les traces de performance ; laisse-le non défini pour le défaut 1.0 en développement et resserre-le (0.05–0.2) en production. Les stack frames sont envoyés sans rédaction, donc pointe le DSN sur une infra que tu contrôles si tes payloads d'erreur sont sensibles. ## Ce qui ne ship pas encore Les traces OpenTelemetry ne sont pas intégrées aux conteneurs. Les données sont joignables indirectement — les durées d'action Convex et les timings de routes HTTP arrivent par les métriques Prometheus — mais il n'y a pas d'exportateur OTLP sur la boîte aujourd'hui. Si tu as besoin d'export de traces complet, fais tourner un OpenTelemetry Collector à côté de Tale et scrape les endpoints Prometheus depuis lui. ## Où cela s'inscrit Les trois coutures ci-dessus sont les points de contact avec le reste de ta stack de monitoring ; les seuils d'alerte et la checklist d'astreinte vivent dans [Opérations](/fr/self-hosted/operate/observability/operations). Si quelque chose brûle là, maintenant, et qu'il te faut l'index par symptôme, saute à [Dépannage](/fr/self-hosted/operate/observability/troubleshooting). # Installer la CLI tale Source: https://tale.dev/docs/fr/self-hosted/install/cli-install La CLI `tale` est la façon recommandée de faire tourner et d'exploiter Tale. Le [démarrage rapide](/fr/self-hosted/install/quickstart) l'utilise déjà pour monter une instance en local avec `tale init` et `tale dev` ; cette page est l'autre moitié — installer la CLI sur une station de travail pour qu'elle puisse piloter une instance _distante_ : déployer de nouvelles versions, lancer des migrations et capturer des diagnostics sans que tu aies à te souvenir de chaque invocation `docker compose`. Tout ce que fait la CLI peut aussi se faire directement avec `docker compose` et `ssh`, donc une équipe déjà profondément dans sa propre automatisation peut rester sur compose. Pour tous les autres, la CLI est le chemin le plus court, et le reste de la doc auto-hébergée suppose qu'elle est installée. ## Avant de commencer Il te faut : - Une station de travail sous macOS, Linux ou Windows 10+. - Un accès SSH à l'hôte où tourne ton instance Tale, avec l'utilisateur opérateur capable de lancer `docker compose`. L'installeur télécharge un binaire de release depuis GitHub. Les réseaux d'entreprise qui bloquent les téléchargements de contenu brut doivent autoriser `raw.githubusercontent.com` et `github.com`. ## Étape 1 — Lancer install-cli.sh ou install-cli.ps1 Sur macOS ou Linux : ```bash curl -fsSL https://raw.githubusercontent.com/tale-project/tale/main/scripts/install-cli.sh | bash ``` Sur Windows PowerShell : ```powershell irm https://raw.githubusercontent.com/tale-project/tale/main/scripts/install-cli.ps1 | iex ``` Les deux installeurs détectent l'OS et l'architecture CPU, récupèrent le binaire de release correspondant depuis la dernière release GitHub, et le déposent sur le `PATH` (`/usr/local/bin/tale` ou `%LOCALAPPDATA%\Programs\tale\tale.exe`) — quand le répertoire d'installation n'est pas accessible en écriture, l'installeur demande `sudo`. Les binaires de release existent pour macOS sur Apple Silicon et Intel, et pour Linux sur x86_64 et arm64 ; les machines Windows-on-ARM exécutent le binaire x64 via l'émulation intégrée. Sur une architecture sans binaire de release, l'installeur s'arrête avec un message clair et renvoie vers la compilation depuis les sources. Pour fixer une version, règle la variable d'environnement `VERSION` avant de piper dans l'installeur ; pour choisir toi-même le répertoire d'installation, règle `INSTALL_DIR`. | OS | Script d'installeur | | ------- | ------------------------- | | macOS | `scripts/install-cli.sh` | | Linux | `scripts/install-cli.sh` | | Windows | `scripts/install-cli.ps1` | ## Étape 2 — Vérifier ```bash tale --version ``` La CLI imprime sa version. Si la commande n'est pas trouvée, l'installeur a déposé le binaire hors du `PATH` — la sortie de l'installeur nomme le répertoire de destination. ## Étape 3 — Vérifier la configuration Il n'y a pas de `tale config set` — tout ce dont la CLI a besoin vit dans le projet créé par `tale init`. Lance chaque commande `tale` depuis ce répertoire (la CLI remonte l'arborescence pour trouver `tale.json`), et vérifie qu'il se résout : ```bash tale config show ``` L'hôte sur lequel le proxy répond, les réglages TLS et tous les secrets vivent dans le `.env` du projet. Pour changer l'hôte, modifie `HOST` là-bas ou passe `--host` à `tale dev` / `tale deploy`. Pour piloter un hôte distant, pointe le contexte Docker de ton shell (ou `DOCKER_HOST`) dessus — la CLI parle au même endpoint Docker que n'importe quelle commande `docker`. La clé admin du tableau de bord Convex est séparée de la configuration de la CLI — elle ne conditionne jamais l'inscription et elle est déterministe (dérivée de `INSTANCE_NAME` et `INSTANCE_SECRET`, donc identique d'un redémarrage à l'autre). Génère-la avec `tale convex admin` quand tu veux inspecter le backend (voir [Premier admin](/fr/self-hosted/install/first-admin)). ## Étape 4 — Lancer tale deploy ```bash tale deploy ``` `tale deploy` livre toujours la version de la CLI elle-même : il récupère les images de cette version, redémarre les conteneurs affectés dans le bon ordre, et lance les migrations de schéma — pour passer à une autre version, commence par `tale update`. C'est le remplacement pris en charge pour la danse plus longue `docker compose pull && docker compose up -d`. Si tu préfères compose directement, le même effet vit dans [Mises à jour](/fr/self-hosted/operate/upgrades). ## Référence des commandes Le CLI regroupe ses commandes selon ce que tu fais, comme le fait `tale --help`. Chaque commande et ses arguments sont listés ci-dessous. Comment lire la notation : - Un argument positionnel entre `[crochets]` est **optionnel** ; entre `<chevrons>`, il est **requis**. - Chaque option est **optionnelle** — l'omettre donne le comportement par défaut. - Une option de la forme `--option <valeur>` **exige une valeur** quand tu l'utilises (p. ex. `--port 8443`) ; une option seule comme `--detach` est un commutateur booléen. - Les **valeurs par défaut** figurent entre parenthèses après la description. Aucune valeur par défaut signifie que l'option est désactivée, ou que la valeur est résolue depuis `.env` / le contexte. Lance `tale <commande> --help` pour la liste de référence de ta version installée. **Les options globales** fonctionnent sur chaque commande : - `--verbose` — sortie détaillée : logs de débogage et flux brut du sous-processus (forme longue uniquement ; il n'y a pas de `-v`). - `-q, --quiet` — uniquement les avertissements et les erreurs. - `-y, --yes` — répondre « oui » à toutes les questions (non interactif). - `--no-color` — désactiver les couleurs ANSI (respecte aussi `NO_COLOR` / `FORCE_COLOR`). - `--json` — JSON lisible par machine sur stdout, messages humains sur stderr ; pris en charge par `status`, `config show` et `migrate status`. - `--ci` — forcer une sortie non interactive en mode ajout seul (sans contrôle du curseur). Les commandes se terminent avec `0` en cas de succès, `2` pour une erreur d'utilisation, `3` pour une condition préalable non remplie (pas de projet, Docker arrêté, port occupé), `4` pour une interruption par l'utilisateur (Ctrl-C, ou une question requise sans terminal) et `5` pour l'échec d'une dépendance externe — ainsi les scripts peuvent se ramifier selon la cause. ### Installation `tale init [directory]` — créer un projet : échafaude les configs d'exemple, `AGENTS.md` + un pointeur `CLAUDE.md` et un `.env` local par défaut (localhost, certificat auto-signé, secrets générés). Aucun Docker requis ; le domaine de production et le TLS sont choisis plus tard, lors de `tale deploy`. Dans un terminal, il demande un nom de projet quand `directory` est omis, confirme avant d'écraser un projet existant, et demande une fois si les agents peuvent lancer `docker` dans les sandboxes (par défaut : non — l'activer fait tourner un Docker interne privilégié) ; les exécutions non interactives sautent toutes les questions. `directory` est optionnel (par défaut : le répertoire courant). - `-f, --force` — écraser un `tale.json` existant au lieu d'abandonner. - `--no-env` — échafauder le projet mais ignorer la génération du `.env`. `tale dev` — démarrer tous les services localement avec un certificat auto-signé. - `-d, --detach` — s'exécuter en arrière-plan au lieu de diffuser les logs. - `-p, --port <port>` — port HTTPS à exposer (par défaut `443`). - `--host <hostname>` — alias d'hôte pour le proxy (par défaut `localhost`). - `-y, --yes` — non-interactif : accepter automatiquement les invites (p. ex. installer ou démarrer Docker). `tale deploy` — déploiement blue-green sans interruption de la version actuelle du CLI. Au premier déploiement, il demande ton domaine de production et l'e-mail Let's Encrypt (ou passe `--host`). - `--stop` — mettre aussi à jour le palier arrêté-puis-recréé (`db`, `proxy`) — ces conteneurs sont recréés, donc accepte une brève interruption ; sans l'option, les `db`/`proxy` en marche restent intouchés. - `-s, --services <list>` — ne mettre à jour que ces services séparés par des virgules (par défaut : tous les services rotatifs). - `--host <hostname>` — alias d'hôte pour le proxy (par défaut : la valeur `HOST` de `.env`). - `--override` — écraser la config du conteneur depuis le workspace local (les `*.secrets.json` chiffrés et `.history/` sont toujours préservés). - `--override-all` — réinitialiser le catalogue intégré dans chaque organisation côté serveur ; implique `--stop`. - `-q, --quiet` — masquer les logs des conteneurs pendant le déploiement. - `-y, --yes` — accepter automatiquement les confirmations destructives (p. ex. `--override-all`). - `--skip-backup` — ignorer le snapshot de volume automatique d'avant déploiement. - `--dry-run` — prévisualiser sans rien modifier. ### Exploitation `tale status` — afficher l'état actuel du déploiement. Aucun argument. `tale logs <service>` — diffuser les logs d'un service (`service` est l'un des services en cours d'exécution ; sur une stack de dev sans déploiement, la commande retombe sur le conteneur de dev). - `-f, --follow` — suivre la sortie des logs au fil de l'écriture. - `-n, --tail <lines>` — n'afficher que les N dernières lignes. - `--since <duration>` — afficher les logs depuis une durée relative (p. ex. `1h`, `30m`). - `-c, --color <color>` — cibler une couleur de déploiement précise (`blue` ou `green`). - `--raw` — diffuser la sortie brute, non filtrée (aucune classification). `tale backup` — snapshot de tous les volumes de données vers le volume de sauvegardes du projet. Aucun argument. `tale restore [snapshot-id]` — restaurer un snapshot ; sans id, la liste des snapshots disponibles s'affiche. - `--stop` — arrêter les conteneurs du projet avant la restauration. - `-y, --yes` — ignorer l'invite de confirmation. `tale rollback` — revenir à la version patch précédente (niveau patch uniquement). Demande confirmation au préalable. - `-y, --yes` — ignorer l'invite de confirmation (requis en mode non-interactif). ### Maintenance `tale update` — bouger cette instance Tale vers une nouvelle version : mettre à jour le binaire CLI, puis synchroniser les fichiers projet sur les templates de cette version. Lance `tale deploy` ensuite pour rouler les conteneurs. La CLI s'aligne aussi d'elle-même sur la version de l'instance à chaque commande, donc ceci n'est nécessaire que pour changer délibérément de version. - `-v, --version <version>` — mettre à jour vers exactement cette version (p. ex. `0.9.0`) au lieu de la dernière ; autorise les rétrogradations. - `-f, --force` — forcer la re-synchronisation et écraser les fichiers projet modifiés localement. - `--dry-run` — montrer ce qui changerait sans rien modifier. `tale migrate` — reprovisionner les valeurs par défaut intégrées et appliquer les migrations de données sûres en attente sur le déploiement en cours — les mêmes étapes idempotentes que chaque déploiement exécute, à la demande. Les sous-commandes donnent un contrôle fin et réversible : `migrate status` montre les migrations appliquées et en attente, `migrate up [--to <version>]` applique celles en attente (les étapes destructives demandent `-y, --yes` ou `--step`), `migrate down --to <version>` revient en arrière. `tale cleanup` — supprimer les conteneurs inactifs (couleur non courante). Aucun argument. `tale reset` — supprimer tous les conteneurs blue-green. - `-f, --force` — ignorer l'invite de confirmation. - `-a, --all` — supprimer aussi les conteneurs d'infrastructure avec état. - `--dry-run` — prévisualiser la réinitialisation sans rien modifier. `tale uninstall` — supprimer le binaire CLI `tale` de ce système. Il demande confirmation avant de supprimer quoi que ce soit et _propose_ de retirer aussi la configuration propre à l'utilisateur (`~/.tale-daemon`) et de démanteler les ressources Docker et les fichiers d'un projet. Sans `--purge`, un projet et ses conteneurs restent intacts — lance `tale reset --all` à l'intérieur pour les supprimer. - `-f, --force` — ignorer l'invite de confirmation (supprime uniquement le binaire ; les nettoyages optionnels nécessitent toujours `--purge`). - `--purge` — retirer aussi `~/.tale-daemon` et, pour un projet trouvé depuis le répertoire courant, démanteler ses ressources Docker et supprimer ses fichiers. Irréversible. - `--dry-run` — montrer ce qui serait supprimé sans rien supprimer. `tale config` — gérer la configuration du CLI. Utilise le sous-commande `show` pour afficher la configuration résolue. ### Avancé `tale auth reset-owner` — réinitialiser les identifiants du compte propriétaire. - `-e, --email <email>` — définir une nouvelle adresse e-mail du propriétaire. - `-p, --password <password>` — définir un nouveau mot de passe du propriétaire. `tale convex admin` — générer une clé admin pour le tableau de bord Convex. Aucun argument. ## Dépannage - **`tale deploy` vise la mauvaise machine.** La CLI utilise le contexte Docker / `DOCKER_HOST` de ton shell. Bascule avec `docker context use …` (ou définis `DOCKER_HOST`) pour qu'il pointe sur l'hôte voulu, puis relance. - **`tale deploy` utilise le mauvais alias d'hôte.** L'hôte sur lequel le proxy répond vient de `HOST` dans le `.env` du projet, pas d'un stockage CLI séparé. Modifie `.env` ou passe `--host` pour le remplacer le temps d'un lancement. - **Le tableau de bord Convex rejette la clé admin.** L'inscription ne demande jamais la clé — seul le tableau de bord le fait. La clé est déterministe (dérivée de `INSTANCE_NAME` et `INSTANCE_SECRET`), donc un rejet signifie généralement que ces valeurs diffèrent entre les services platform et Convex, ou que l'URL de déploiement est fausse — utilise `SITE_URL`. Régénère avec `tale convex admin` pour être sûr d'avoir copié la valeur actuelle. - **L'installeur échoue sur macOS parce que le binaire ne peut pas s'exécuter.** Quand le binaire fraîchement installé refuse de démarrer (p. ex. Gatekeeper le tue), l'installeur échoue avec des pistes de récupération au lieu d'annoncer un succès — suis-les, puis relance l'installeur. - **`tale` introuvable après installation sous Linux.** L'installeur dépose le binaire dans `/usr/local/bin` ; vérifie que le répertoire est dans le `PATH` de l'utilisateur (`echo $PATH`). ## Où ça s'utilise Une fois la CLI branchée, la surface quotidienne de l'opérateur se réduit à une poignée de sous-commandes. Les pages à lire ensuite dépendent de pourquoi tu es venu — [Mises à jour](/fr/self-hosted/operate/upgrades) pour les bumps de version, [Sauvegardes et restauration](/fr/self-hosted/operate/backups-and-restore) pour les exercices de snapshot, [Architecture des conteneurs](/fr/self-hosted/operate/container-architecture) pour ce que la CLI redémarre quand elle déploie. # Démarrage rapide auto-hébergé Source: https://tale.dev/docs/fr/self-hosted/install/quickstart C’est le chemin le plus rapide vers un Tale qui tourne : installe la CLI `tale`, puis deux commandes. Le résultat est ta propre organisation sur ta propre machine, joignable dans le navigateur. C’est pensé pour un laptop ou un hôte unique sur lequel essayer Tale ; quand tu veux le faire tourner pour de vrai, le parcours [serveur Linux](/fr/self-hosted/install/linux-server) couvre une installation de production durcie. ## Avant de commencer Il ne te faut rien pour démarrer, et une chose avant qu’un agent puisse répondre : - **Docker** — mais la CLI le provisionne pour toi : s’il manque, `tale dev` propose de l’installer ou de le démarrer avant toute autre chose. Si tu fais déjà tourner [Docker Desktop](https://www.docker.com/products/docker-desktop) (v24+), ou Docker Engine plus le plugin Compose sous Linux, la CLI s’en sert. - Une **[clé API OpenRouter](https://openrouter.ai)** (ou n’importe quel fournisseur compatible OpenAI) pour que les agents aient un modèle à qui parler. Tu n’en as pas besoin pour `tale init` — tu l’ajoutes dans l’app après l’inscription, dans l’assistant de configuration ou sous **Paramètres > Fournisseurs IA**, et tu peux changer de fournisseur plus tard. ## De zéro à connecté <Steps> <Step title="Installe la CLI"> L’installateur détecte ton OS, dépose le binaire `tale` sur ton `PATH`, et c’est la seule étape qui touche ton système — il demande `sudo` quand le répertoire d’installation (par défaut `/usr/local/bin`) n’est pas accessible en écriture. <Tabs> <Tab title="macOS / Linux"> ```bash curl -fsSL https://raw.githubusercontent.com/tale-project/tale/main/scripts/install-cli.sh | bash ``` </Tab> <Tab title="Windows (PowerShell)"> ```powershell irm https://raw.githubusercontent.com/tale-project/tale/main/scripts/install-cli.ps1 | iex ``` </Tab> </Tabs> <Check> `tale --version` qui imprime un numéro de version confirme que le binaire a atterri sur ton `PATH`. </Check> </Step> <Step title="Crée un projet"> ```bash tale init my-project cd my-project ``` `tale init` échafaude un répertoire de projet, génère chaque secret de sécurité et écrit le `.env`, de sorte qu’il n’y a rien à éditer à la main. Les valeurs par défaut sont localhost et un certificat auto-signé ; le domaine de production se choisit plus tard, à `tale deploy`. La seule question qu’il pose est de savoir si les agents peuvent lancer `docker` / `docker compose` dans leurs sandboxes — le défaut est non, car l’activer fait tourner un Docker interne privilégié ; une installation mono-utilisateur peut dire oui, un opérateur multi-tenant installe plutôt Sysbox. Il ne demande pas de clé API ; celle-ci est collectée dans l’app une fois que tu es connecté. Il dépose aussi des agents, workflows, connectors, fournisseurs, skills et branding d’exemple sous `default/`, et écrit `AGENTS.md` (plus un pointeur `CLAUDE.md`) afin qu’un éditeur IA puisse construire des configurations en pleine connaissance du schéma. L’essentiel de cette arborescence est un catalogue, pas une configuration active : sur une nouvelle organisation, seules les entrées marquées `autoInstall` sont actives — le `default/README.md` généré explique la différence. </Step> <Step title="Démarre Tale"> ```bash tale dev ``` Si Docker manque, `tale dev` propose d’abord de l’installer ou de le démarrer. Le premier passage récupère ensuite plusieurs gigaoctets d’images et construit le graphe de conteneurs — la CLI affiche la progression du pull image par image et continue d’attendre ; sur un réseau lent, ça peut prendre des dizaines de minutes. Dès que la stack se signale prête (`Tale is running — open https://localhost`), `tale dev` ouvre ton navigateur automatiquement. S’il ne peut pas, il imprime l’URL à visiter. <Note> Ton navigateur affiche un avertissement de certificat pour le certificat local auto-signé. C’est attendu — accepte-le pour continuer. </Note> Ta configuration sous `default/` est montée dans l’instance en marche, donc les modifications d’agents, de workflows et d’connectors rechargent à chaud. Arrête la stack avec `Ctrl-C` (ou `tale dev --detach` pour la laisser tourner en arrière-plan). </Step> <Step title="Crée ton compte"> Sur une instance vide, il n’y a pas de page d’inscription à chercher : la première visite atterrit dans l’assistant de configuration unique, qui crée ton compte, te connecte, fait de toi le **Propriétaire** et nomme ton **Organisation**. Tu atterris dans le dashboard — aucune clé admin en jeu, et rien à verrouiller ensuite, car tous ceux qui te suivent arrivent par invitation. <Note> [Premier admin](/fr/self-hosted/install/first-admin) couvre l’assistant en détail, comment les coéquipiers arrivent, et la clé admin du tableau de bord Convex — un outil d’inspection du backend qui ne joue aucun rôle dans la connexion. </Note> </Step> <Step title="Ajoute un modèle et publie un agent"> Tu as maintenant une organisation vide. Deux gestes t’amènent à quelque chose d’utile : ajoute ta clé OpenRouter — l’assistant de configuration la demande juste après la création du compte propriétaire, et **Paramètres > Fournisseurs IA** la prend à tout moment — puis publie ton premier agent avec [Créer un agent](/fr/platform/agents/create). Une confirmation sur la ligne du fournisseur signifie que la clé fonctionne. <Check> Un nouveau chat qui répond à un message est la preuve de bout en bout : fournisseur, modèle et agent fonctionnent tous. À partir d’ici, la doc [Plateforme](/fr/platform) est la référence canonique de chaque fonctionnalité, identique à Cloud. </Check> </Step> </Steps> ## Plutôt du Docker Compose brut ? La CLI enveloppe `docker compose` pour que tu n’aies pas à le faire. Si tu préfères faire tourner la stack depuis un clone du dépôt et gérer Compose toi-même — pour la transparence, des builds air-gapped ou ta propre automatisation — clone le dépôt, copie `.env.example` vers `.env`, règle `HOST` et `SITE_URL`, génère les secrets et lance `docker compose up -d`. Le parcours [serveur Linux](/fr/self-hosted/install/linux-server) et la [référence Docker Compose](/fr/self-hosted/install/docker-compose-reference) couvrent ce chemin de bout en bout. ## Dépannage - **`tale` introuvable après l’installation.** L’installateur nomme le répertoire de destination dans sa sortie ; assure-toi que ce répertoire est sur ton `PATH` (sous Linux, c’est généralement `/usr/local/bin`). - **`tale dev` se termine sur un conflit de port.** Lis l’erreur compose pour voir quel port est pris. Si c’est 443, un autre service lie HTTPS sur l’hôte — libère-le, ou déplace Tale avec `tale dev --port 8443` (l’option ne déplace que le port HTTPS). Le spawner de sandbox lie toujours `127.0.0.1:8003` et ne peut pas être déplacé ; deux projets Tale en dev ne peuvent donc pas tourner en même temps sur une machine. - **Docker ne tourne pas.** `tale dev` propose de le démarrer (ou de l’installer) — accepte l’invite, ou démarre Docker Desktop toi-même (`sudo systemctl start docker` sous Linux) et réessaie. - **Un conteneur crash-loope au premier démarrage.** Presque toujours un secret manquant — relance `tale dev`, qui relance la configuration d’environnement, ou inspecte les logs avec `tale logs platform`. ## Où ça s’utilise Tu as maintenant une instance Tale qui fonctionne sur ta machine. Pour la faire tourner pour de vrai, le parcours [serveur Linux](/fr/self-hosted/install/linux-server) couvre TLS, pare-feu, un utilisateur non-root et les crochets opérationnels que tu veux avant que le vrai trafic n’arrive ; [Installer la CLI tale](/fr/self-hosted/install/cli-install) prépare la CLI à déployer et mettre à jour une instance distante depuis ta machine de travail. # Installation Source: https://tale.dev/docs/fr/self-hosted/install Installer Tale prend trois formes, et la bonne dépend de ce que tu fais du résultat. Cette page t'aiguille vers le chemin qui convient — un essai local rapide, une installation de production derrière TLS, ou la référence Compose brute quand tu veux posséder chaque bouton — pour que tu ne te lances pas dans un parcours de durcissement alors que tu voulais juste cliquer un peu. Les trois chemins atterrissent sur le même produit ; la différence est la part de la stack que tu exploites et la durabilité dont le résultat a besoin. La CLI enveloppe Docker Compose pour les deux premiers, de sorte qu'il n'y a rien à éditer à la main, tandis que le chemin de la référence est pour les équipes qui font tourner Compose elles-mêmes. ## Essayer Tale sur un laptop Si tu veux une instance qui tourne pour cliquer dedans — sur ta propre machine, sans domaine ni durcissement — le [démarrage rapide](/fr/self-hosted/install/quickstart) est le chemin. Installe la CLI, lance `tale init` puis `tale dev`, et tu es connecté à ta propre organisation en quelques minutes. La CLI provisionne Docker s'il manque, génère chaque secret et monte ta configuration de sorte que les édits rechargent à chaud. C'est le bon chemin pour une évaluation, une démo, ou du développement local contre une vraie stack. Quand tu dépasses le laptop et veux le même projet sur un vrai hôte, le projet d'essai se reporte — `tale deploy` l'amène sur un domaine sans réinitialiser. ## Faire tourner Tale en production Quand du vrai trafic atterrira sur l'instance, le parcours [Linux serveur](/fr/self-hosted/install/linux-server) est le chemin. Il couvre TLS, un pare-feu, un utilisateur non-root, le reverse proxy et les crochets opérationnels que tu veux avant de pointer un domaine dessus. La CLI fait toujours le gros du travail — `tale deploy` exécute un déploiement blue-green sans interruption avec health checks et rollback — mais ce parcours ajoute la configuration au niveau de l'hôte qu'un essai saute. Après le premier déploiement, [Premier admin](/fr/self-hosted/install/first-admin) explique l'assistant de configuration unique qui fait du premier compte l'**Owner** — tous les suivants arrivent par invitation, donc il n'y a pas d'inscription ouverte à fermer — et [Installation de la CLI](/fr/self-hosted/install/cli-install) configure la CLI sur une workstation pour déployer et mettre à jour une instance distante. ## Posséder la couche Compose Si tu préfères faire tourner la stack depuis un clone du dépôt et gérer Compose toi-même — pour la transparence, des builds air-gapped ou ta propre automation — la [référence Docker Compose](/fr/self-hosted/install/docker-compose-reference) est le chemin. Elle documente le fichier de base et les overlays que la CLI génère en coulisse, pour que tu puisses les reproduire ou les étendre à la main. C'est le plus de contrôle et le plus de travail ; la plupart des équipes sont mieux servies par les chemins CLI ci-dessus. Ce chemin se marie au parcours [Linux serveur](/fr/self-hosted/install/linux-server) pour les pièces au niveau de l'hôte (TLS, pare-feu, utilisateur) que Compose seul ne couvre pas. ## Où cela s'inscrit Les trois chemins d'installation échangent la commodité contre le contrôle : le [démarrage rapide](/fr/self-hosted/install/quickstart) est le moyen le plus rapide vers une instance qui tourne, le parcours [Linux serveur](/fr/self-hosted/install/linux-server) la durcit pour du vrai trafic, et la [référence Docker Compose](/fr/self-hosted/install/docker-compose-reference) te remet chaque bouton quand les valeurs par défaut de la CLI ne suffisent pas. Choisis selon la durabilité : un essai que tu jetteras veut le démarrage rapide ; une instance dont ton équipe dépend veut le parcours de production. Une fois installé, les pages [Configuration](/fr/self-hosted/configuration/environment-reference) sont la source de vérité pour chaque variable d'environnement et fichier de fournisseur, et la section [Exploiter](/fr/self-hosted/operate/container-architecture) couvre les mises à jour, les sauvegardes et l'observabilité de la stack en marche. # Créer le premier admin Source: https://tale.dev/docs/fr/self-hosted/install/first-admin Une instance Tale toute neuve n'a pas encore d'utilisateurs. La première personne qui l'ouvre déroule un assistant de configuration unique qui crée son compte, la connecte, en fait l'**Owner** et nomme la première organisation — aucune clé de bootstrap, aucune promotion manuelle. Ce parcours couvre ce premier lancement, comment les coéquipiers arrivent ensuite, et où obtenir la clé admin du tableau de bord Convex si tu dois un jour inspecter le backend directement. La seule chose à désapprendre des anciennes instructions : la première inscription ne demande plus de clé admin. Tale est sur invitation seulement après le premier compte, donc il n'y a pas non plus de page d'inscription ouverte à verrouiller. ## Avant de commencer Aie l'instance qui tourne et joignable sur `SITE_URL`. Vérifie avec : ```bash docker compose ps ``` Chaque service devrait montrer `running` ou `healthy`. Si l'un est unhealthy, le [dépannage](/fr/self-hosted/operate/observability/troubleshooting) nomme les quatre causes courantes. ## Dérouler l'assistant de configuration Ouvre `SITE_URL`. Comme il n'y a pas encore d'utilisateurs, Tale t'envoie directement dans l'assistant de configuration — il n'y a pas de page d'inscription séparée à chercher, car l'écran de connexion redirige automatiquement une instance vide vers la configuration. L'assistant crée ton compte et te connecte en plein flux, puis nomme ta première organisation. L'étape du fournisseur est optionnelle : saute-la et ajoute une clé plus tard sous **Paramètres > Fournisseurs IA**, ou connecte OpenRouter maintenant pour discuter tout de suite. Obtiens une clé sur [openrouter.ai/keys](https://openrouter.ai/keys). L'étape finale te dépose dans le tableau de bord. ## Confirmer que tu es l'Owner Le premier compte sur une instance neuve est automatiquement l'**Owner** — aucune clé à coller, aucune étape de promotion. Confirme sous **Paramètres > Personnes** que ta ligne porte le badge Owner. ## Comment les nouvelles personnes arrivent Il n'y a pas d'inscription en libre-service. Une fois qu'un Owner existe, `SITE_URL/sign-up` redirige les visiteurs vers l'écran de connexion, donc personne ne peut créer un compte de lui-même. Ajoute les coéquipiers par invitation sous **Paramètres > Personnes** ; chaque invitation porte le rôle avec lequel le nouveau membre démarre. Le modèle de rôles complet est dans [Membres et rôles](/fr/platform/admin/members-and-roles). ## Obtenir la clé admin du tableau de bord Convex La clé admin ne joue aucun rôle dans les étapes ci-dessus — elle ne débloque que le **tableau de bord Convex**, la vue bas niveau de la base de données du backend. La clé est déterministe : elle est dérivée de `INSTANCE_SECRET`, donc elle reste la même d'un redémarrage à l'autre au lieu de tourner. Obtiens-la de la façon qui correspond à ton installation : - Avec la CLI : `tale convex admin` trouve le conteneur platform et imprime la clé. `tale dev` l'imprime aussi une fois les services en bonne santé. - Depuis un clone git : `./scripts/get-admin-key.sh` à la racine du dépôt. Ouvre `SITE_URL/convex-dashboard`, saisis `SITE_URL` comme URL de déploiement, et colle la clé quand on te la demande. ## Dépannage - **L'assistant n'est pas apparu — tu atterris sur l'écran de connexion.** Des utilisateurs existent déjà sur cette instance ; l'assistant ne tourne que sur une instance vraiment vide. Connecte-toi à la place, ou fais-toi inviter par un Owner existant sous **Paramètres > Personnes**. - **Un service est unhealthy.** Le conteneur platform n'est pas entièrement monté. `docker compose ps` dit quel service échoue ; `docker compose logs platform` montre pourquoi. - **Le tableau de bord rejette la clé admin.** La clé est déterministe à partir de `INSTANCE_SECRET`, donc un rejet signifie généralement que `INSTANCE_NAME` et `INSTANCE_SECRET` diffèrent entre les services platform et Convex, ou que l'URL de déploiement est fausse — utilise `SITE_URL`. Régénère avec `tale convex admin` pour être sûr d'avoir copié la valeur actuelle. ## Où ça s'utilise Tu as maintenant un Owner et une organisation, et tu sais que la clé admin est un outil d'inspection du backend, pas une partie de la connexion. Le premier lancement est sans clé par conception : ouvre l'URL, l'assistant te fait Owner, et tous les autres arrivent par invitation. Les étapes suivantes pour le calendrier sont d'inviter le reste des admins (sous **Paramètres > Personnes**), d'ajouter un fournisseur de modèles, et de publier le premier agent — le parcours [Onboarding Cloud](/fr/cloud/onboarding) est identique à partir d'ici, à l'URL près. # Installation Linux serveur de production Source: https://tale.dev/docs/fr/self-hosted/install/linux-server Ce parcours prend la forme du [démarrage rapide](/fr/self-hosted/install/quickstart) et la durcit pour le trafic de production. Le résultat est un seul hôte Linux qui fait tourner Tale derrière du vrai TLS, avec un pare-feu, un utilisateur opérateur non-root, et les défauts opérationnels que l'équipe devrait toucher avant de pointer des utilisateurs sur l'URL. Le parcours vise un Ubuntu LTS récent ou Debian ; les commandes se traduisent une-pour-une vers les distros de la famille RHEL avec `dnf` au lieu d'`apt`. Ne saute rien — l'ordre compte, et chaque étape suppose que la précédente est tombée proprement. ## Avant de commencer Il te faut : - Une VM ou un hôte bare-metal avec au moins 8 Go de RAM, 4 vCPU et 100 Go de disque. Le stockage croît avec les pièces jointes et les connaissances. - Un enregistrement DNS A qui pointe vers l'IP publique de l'hôte. Sans DNS, Let's Encrypt ne peut pas émettre un certificat. - Les ports 80, 443 joignables depuis l'internet public pour l'émission TLS ; SSH sur le port que ta politique opérateur indique. - Sudo sur l'hôte. ## Étape 1 — Provisionner la machine Mets à jour et installe les fondations : ```bash sudo apt update && sudo apt upgrade -y sudo apt install -y curl git ufw ``` Crée un utilisateur opérateur non-root nommé `tale` : ```bash sudo adduser tale sudo usermod -aG sudo,docker tale ``` Bascule vers cet utilisateur (`sudo su - tale`) pour le reste du parcours. Opérer Tale en root tire un rayon d'impact plus large pour aucun bénéfice ; le reste des étapes suppose l'utilisateur `tale`. ## Étape 2 — Installer Docker ```bash curl -fsSL https://get.docker.com | sudo sh sudo systemctl enable --now docker ``` Vérifie avec `docker run hello-world`. Si l'utilisateur ne peut pas lancer docker sans sudo, déconnecte-toi et reconnecte-toi pour reprendre l'appartenance au groupe `docker`. ## Étape 3 — Configurer le pare-feu et le chemin inverse Autorise seulement ce dont Tale a besoin : ```bash sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow OpenSSH sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable ``` Si tu places Tale derrière un reverse-proxy existant sur le même hôte (rare sur une installation sur un seul hôte), règle `TLS_MODE=external` dans `.env` et ajuste le pare-feu en conséquence. Le conteneur Caddy à l'intérieur de Tale termine TLS par défaut. ## Étape 4 — Récupérer Tale ```bash git clone https://github.com/tale-project/tale.git cd tale cp .env.example .env ``` Règle `HOST`, `SITE_URL`, et génère les quatre secrets comme dans le [démarrage rapide](/fr/self-hosted/install/quickstart). Le diff production par rapport au démarrage rapide vit dans l'étape 5 (TLS) et les crochets opérationnels à la fin de ce parcours. ## Étape 5 — TLS via Let's Encrypt Ouvre `.env` et règle : | Variable | Valeur | | ----------- | ------------------------ | | `TLS_MODE` | `letsencrypt` | | `TLS_EMAIL` | Une boîte ops que tu lis | Caddy émet et renouvelle le certificat automatiquement en utilisant l'enregistrement DNS des prérequis. Le premier démarrage attend le certificat ; compte un délai d'une minute sur le premier `docker compose up -d` pendant que le défi ACME se joue. ## Étape 6 — Premier démarrage ```bash docker compose up -d docker compose ps ``` Chaque service devrait être `running` ou `healthy`. Parcours **Étape 4 — Créer le premier admin** depuis le [démarrage rapide](/fr/self-hosted/install/quickstart) pour atterrir dans le dashboard. Ouvre `SITE_URL` en `https://` — le navigateur ne devrait pas avertir au sujet du certificat. ## Étape 7 — Crochets opérationnels Avant de pointer des utilisateurs sur l'URL, trois crochets te facilitent la vie plus tard : - **Sauvegardes.** Pointe ton outillage de snapshot existant vers `db-data` et le volume du stockage objet — voir [Sauvegardes et restauration](/fr/self-hosted/operate/backups-and-restore). - **Logs.** Tale logue sur stdout. Si l'hôte a journald, `journalctl -u docker` transporte tout ; sinon, pipe vers ton agrégateur. - **Métriques.** Règle `METRICS_BEARER_TOKEN` dans `.env` et scrape `/metrics` depuis ton Prometheus — voir [Configuration de l'observabilité](/fr/self-hosted/configuration/observability-config). ## Tableau des ports | Port | Direction | Objet | Requis | | ---- | --------- | ----------------------------------------------- | -------------- | | 22 | entrant | SSH | oui, restreint | | 80 | entrant | HTTP, sert pour ACME et 301 vers HTTPS | oui | | 443 | entrant | HTTPS, trafic principal | oui | | 53 | sortant | DNS | oui | | 443 | sortant | fournisseurs de modèles, récupérations d'images | oui | ## Dépannage - **L'émission Let's Encrypt échoue.** Le DNS doit résoudre vers l'IP publique de cet hôte depuis l'internet public, et le port 80 doit être joignable depuis l'internet public. Lance `curl -I http://$HOST` depuis une autre machine ; s'il atteint le défi Caddy, le chemin marche. - **Les conteneurs ne peuvent pas joindre les fournisseurs de modèles.** Le pare-feu sortant de l'hôte bloque peut-être ; vérifie avec `docker compose exec platform curl -I https://api.openai.com`. - **Les renouvellements TLS échouent plus tard.** Caddy renouvelle 30 jours avant l'expiration ; les échecs apparaissent dans `docker compose logs proxy`. Les deux causes fréquentes sont une boîte `TLS_EMAIL` expirée et un changement DNS qui a cassé l'enregistrement. ## Où ça s'utilise Tu as maintenant une installation de forme production sur un seul hôte. Deux suites doivent figurer au calendrier — [Sauvegardes et restauration](/fr/self-hosted/operate/backups-and-restore) et [Durcissement](/fr/self-hosted/operate/security/hardening). Si ton échelle dépasse un hôte (règle du pouce : environ cent utilisateurs concurrents sur la spec recommandée), l'architecture multi-hôtes vit sur [Architecture des conteneurs](/fr/self-hosted/operate/container-architecture). # Référence Docker Compose Source: https://tale.dev/docs/fr/self-hosted/install/docker-compose-reference Tale livre une poignée de fichiers Docker Compose. La base est `compose.yml` ; le reste, ce sont des overlays qui ajoutent ou remplacent des services pour des scénarios précis — développement, docs, test. Cette page nomme chaque fichier, dit quand le choisir, et donne la règle de superposition à laquelle tout le reste obéit. La forme est volontairement conservatrice. Le fichier de base tout seul tourne en production ; chaque overlay est opt-in via `-f` et n'ajoute que ce qu'il doit. Mémorise la base et un seul overlay, pas toute la grille. ## Un compose-up déroulé Une instance de production sur un seul hôte tourne depuis la base seule : ```bash docker compose up -d ``` Un développeur qui hacke sur platform et docs en même temps superpose deux overlays : ```bash docker compose -f compose.yml -f compose.dev.yml -f compose.docs.yml up -d ``` Le fichier le plus à gauche est la base ; chaque fichier suivant fusionne ses clés par-dessus. Les conflits (même service, même clé) se résolvent dernier-fichier-gagne. Le graphe fusionné est ce que Docker démarre. ## Les fichiers compose | Fichier | Cas d'usage | Overrides notables | | ----------------------- | ----------------------------------------------- | --------------------------------------------------------------------------------------- | | `compose.yml` | Production sur un seul hôte | La base — chaque service, healthchecks, politique de redémarrage | | `compose.dev.yml` | Développement local avec hot-reload | Monte les sources dans les conteneurs, bascule sur les images dev, expose des ports dev | | `compose.docs.yml` | Ajoute le service du site de docs | Démarre `tale-docs` et route `/docs` à travers le proxy | | `compose.web.yml` | Ajoute le service du site marketing | Démarre `tale-web` et route `/` (racine) à travers le proxy | | `compose.test.yml` | Lance la suite de tests platform contre la pile | Remplace l'image platform par la variante de forme test | | `compose.web.test.yml` | Lance les tests web | Comme `web.yml`, mais la variante de forme test | | `compose.docs.test.yml` | Lance les tests docs | Comme `docs.yml`, mais la variante de forme test | | `compose.test.mock.yml` | Tests de connector adossés à des mocks | Remplace les fournisseurs par des implémentations mock | ## Services et leurs rôles Le graphe de base démarre huit conteneurs : - `tale-proxy` — Caddy. TLS, reverse-proxy, redirections 301. - `tale-platform` — l'app TanStack Start. L'UI et l'API côté utilisateur. - `tale-convex` — le backend Convex. WebSocket, queries, mutations, actions — et la recherche RAG, l'ingestion de documents, le crawling web et la génération de documents en in-process, qui étaient autrefois des services séparés. - `tale-db` — Postgres opérationnel (ParadeDB). Le stockage persistant du backend Convex. - `tale-knowledge-db` — Postgres du corpus de connaissances (ParadeDB). La base `tale_knowledge` qui détient les fragments de documents, les embeddings et les pages crawlées, sur le port 5433 pour ne jamais entrer en conflit avec `tale-db` sur 5432. - `tale-sandbox-llm-gateway` — la gateway LLM pour les tours sur harness (image externe pinnée). - `tale-sandbox-egress` et `tale-sandbox` — le plan sandbox. Conteneurs Run-code derrière un proxy de sortie (ouvert par défaut ; verrouillable avec `SANDBOX_EGRESS_ALLOWLIST`), aussi le runtime de navigateur headless que le backend convex appelle pour le rendu web et la génération de documents. La stack est désormais entièrement TypeScript — il n'y a pas de service Python dans le graphe. [Architecture des conteneurs](/fr/self-hosted/operate/container-architecture) creuse qui possède quoi. ## Surcharges Les personnalisations d'opérateur appartiennent à un overlay supplémentaire, pas à des édits sur les fichiers livrés. Crée un `compose.local.yml` avec les surcharges dont tu as besoin : ```yaml services: platform: environment: - LOG_LEVEL=debug ``` Démarre la pile avec l'overlay local superposé en dernier : ```bash docker compose -f compose.yml -f compose.local.yml up -d ``` Ce motif garde `git pull` propre — pas de conflits de merge sur les fichiers livrés. Le même motif fonctionne pour tout montage de volume personnalisé, port personnalisé, ou surcharge d'environnement. ## Profils Un service du fichier de base utilise un profil Docker Compose. Les profils permettent à un service d'exister dans le graphe mais de ne pas démarrer tant que son profil n'est pas activé. Le profil en usage est `controller` — le sidecar `tale-controller`, à activer explicitement, qui redémarre le conteneur convex sur une requête signée pour qu'un changement de résidence des données s'applique sans donner à la plateforme l'accès au socket Docker. Active-le avec : ```bash docker compose --profile controller up -d ``` ## Où ça s'inscrit La référence compose est la grille de l'opérateur pour l'arbre source. Pour l'intérieur de chaque conteneur, la page [Architecture des conteneurs](/fr/self-hosted/operate/container-architecture) couvre les responsabilités ; pour les variables que les conteneurs lisent au démarrage, la [Référence d'environnement](/fr/self-hosted/configuration/environment-reference) est la source de vérité. # Architecture auto-hébergée Source: https://tale.dev/docs/fr/self-hosted/overview Une instance Tale, ce sont huit conteneurs derrière un proxy Caddy, parlant à deux bases Postgres — une opérationnelle, une pour le corpus de connaissances ; deux d'entre eux sont des conteneurs sandbox sur le côté pour l'exécution de code. Le fichier compose est le contrat — ce qui tourne, ce qui est exposé, ce qui est monté. Cette page te donne le modèle mental pour que les pages installation, configuration et exploitation n'aient pas à le réexpliquer. Lis ceci avant de `docker compose up`. Reviens-y quand tu débogues un incident et que tu dois savoir quel log de conteneur ouvrir en premier. ## Les huit conteneurs **tale-proxy** est Caddy en bordure. Il termine TLS, route tout sous `/` vers le conteneur plateforme, et tout sous `/api/` et les chemins Convex vers le conteneur convex. Les healthchecks vivent ici. **tale-platform** est le serveur React + TanStack Start. Il rend l'UI, sert les assets statiques et est le seul conteneur exposé au navigateur. Il ne porte pas d'état métier — tout ce qui doit persister parle à convex. **tale-convex** est le backend : les actions, queries, mutations et la couche WebSocket à laquelle l'UI s'abonne. Clés de fournisseur, définitions d'agent, exécutions de workflow, journaux d'audit — tout cela vit ici. Il exécute aussi le travail de connaissances en in-process — l'ingestion de documents, le crawling web, la recherche RAG et la génération de documents sont des node-actions Convex, pas des services séparés. Le travail headless dont ces tâches ont besoin (rendre une page web, transformer du HTML en PDF ou en image) est délégué au runtime sandbox, qui embarque déjà Chromium et Playwright. **tale-db** est le Postgres opérationnel (ParadeDB). Il porte les données du backend Convex — agents, runs, le log d'audit — et est l'un des deux conteneurs stateful qui comptent pour les sauvegardes. **tale-knowledge-db** est le Postgres du corpus de connaissances (ParadeDB), la base `tale_knowledge` avec deux schémas : `private_knowledge` (fragments de documents téléversés, embeddings, index BM25, cache sémantique) et `public_web` (pages web crawlées). Il est séparé de `tale-db` pour que le corpus — la banque sensible à la résidence des données — puisse être relocalisé ou remplacé tout seul. Le backend Convex s'y connecte directement ; rien d'autre ne le fait. **tale-sandbox-llm-gateway** est la gateway LLM pour les tours sur harness. C'est le seul chemin d'un harness en sandbox vers un fournisseur de modèles ; la plateforme le provisionne et frappe des clés par session. **tale-sandbox** et **tale-sandbox-egress** exécutent du code en sandbox pour le compte de l'outil **Exécuter du code** et des scripts de compétence, et servent de runtime de navigateur headless que le backend convex appelle pour le rendu web et la génération de documents. Le conteneur egress est le seul chemin que la sandbox a vers le réseau. L'egress est ouvert par défaut — le code en sandbox atteint n'importe quel hôte public en HTTPS, tandis que les métadonnées cloud et les plages d'adresses privées restent bloquées au niveau IP ; restreins-le à une allowlist d'hôtes avec `SANDBOX_EGRESS_ALLOWLIST`, décrite dans [Durcissement](/fr/self-hosted/operate/security/hardening). Un service de plus est livré mais reste éteint par défaut : **tale-controller** est un sidecar à activer explicitement (le profil compose `controller`) qui redémarre le conteneur convex sur une requête signée venant de l'app, pour qu'un changement de résidence des données s'applique sans donner à la plateforme exposée au navigateur l'accès au socket Docker. ## Données sur le disque Quatre volumes survivent à un `docker compose down` : - `db-data` — le répertoire de données du Postgres opérationnel : la base derrière les agents, les runs et le log d'audit. - `knowledge-db-data` — le répertoire de données du Postgres du corpus de connaissances : fragments de documents, embeddings, index de recherche et pages web crawlées. Se sauvegarde séparément de `db-data` parce que c'est une base distincte. - `backups` — snapshots de volumes checksummés, écrits par `tale backup` et automatiquement avant les déploiements migrants ; [Backups et restauration](/fr/self-hosted/operate/backups-and-restore) est le drill. - Le montage du magasin d'objets Convex — fichiers téléversés, documents générés, bundles exportés. Tout le reste est éphémère. Les conteneurs peuvent être remplacés sans perte de données tant que les volumes survivent. ## Secrets de fournisseur et couche SOPS Les clés de fournisseur (OpenAI, Anthropic, Azure, Ollama, etc.) vivent sur le disque dans un répertoire `providers/` monté dans le conteneur plateforme. Chaque fournisseur a un `<nom>.json` et un `<nom>.secrets.json` ; le fichier secrets est chiffré avec SOPS et la variable [`SOPS_AGE_KEY`](/fr/self-hosted/configuration/environment-reference). Cette séparation existe pour deux raisons. Faire tourner une clé de fournisseur, c'est éditer un fichier, pas redémarrer la plateforme ; sauvegarder le fichier chiffré est sûr à committer aux côtés de l'infrastructure. Le mode clair (pas de SOPS, secrets en clair) est supporté pour des environnements étroitement contrôlés où le disque lui-même est chiffré au repos. ## Auth et sessions Le sign-in est Better Auth tournant dans le conteneur convex. Quatre modes de sign-in sont fournis : mot de passe local, Microsoft Entra (OAuth/OIDC), OIDC générique et trusted headers (le reverse proxy fournit l'identité). Le conteneur plateforme lit le cookie, le passe à convex, et convex décide de ce que la session peut faire sur la base du rôle de l'utilisateur et de la matrice de permissions par ressource documentée dans [Membres et rôles](/fr/platform/admin/members-and-roles). La [référence d'authentification](/fr/self-hosted/configuration/authentication) couvre les variables d'environnement et les arbitrages par mode. ## Quand tu sors du single-host Le fichier compose par défaut fait tourner les huit conteneurs sur un hôte. L'architecture est mono-tenant : rien dans le design ne répartit le travail entre hôtes. La première chose que tu peux sortir de la boîte sans réarchitecturer, c'est le corpus de connaissances — `tale-knowledge-db` est un Postgres autonome, donc le pointer vers une infrastructure gérée (pour la capacité ou pour une exigence de résidence) est un changement de chaîne de connexion, couvert dans [Résidence des données](/fr/self-hosted/configuration/data-residency). La couche Convex reste mono-instance ; la scalabilité horizontale du backend n'est pas une fonctionnalité v1. ## Où cela s'inscrit Cette page d'architecture est la carte que présuppose chaque autre page auto-hébergée. La lecture suivante naturelle est [Quickstart](/fr/self-hosted/install/quickstart) si tu montes une instance neuve, ou [Architecture des conteneurs](/fr/self-hosted/operate/container-architecture) si tu en exploites une et que tu veux la même image superposée aux modes de défaillance. # Documentation Tale Source: https://tale.dev/docs/fr Tale est l’orchestrateur pour agents IA. Tu discutes avec des modèles sur tes propres documents, tu construis des agents qui prennent une tâche en charge de bout en bout, tu lances des automatisations en arrière-plan et tu gères les conversations avec les contacts depuis une seule boîte de réception — avec les fournisseurs d’IA de ton choix et tes données ancrées dans une région que tu contrôles. Chaque fonctionnalité, chaque API et chaque rôle est identique entre les deux éditions ; la seule différence est qui exploite la stack. Commence par le démarrage rapide, puis suis le parcours qui correspond à ton rôle. <CardGroup cols="1"> <Card title="Démarrage rapide — ta première réponse d’agent en 5 minutes" icon="zap" href="/fr/get-started/quickstart"> D’une instance qui tourne à une réponse dans le chat, sur Cloud ou sur ta propre machine. </Card> </CardGroup> ## Choisis ton parcours Quatre parcours pour le premier jour, un par rôle. Chacun prend environ quinze minutes et se termine sur quelque chose qui fonctionne. <CardGroup cols="2"> <Card title="J’utilise Tale" icon="message-circle" href="/fr/get-started/members"> Ton premier chat, ton premier document, ton premier projet — le premier jour du membre. </Card> <Card title="Je construis des agents" icon="bot" href="/fr/get-started/editors"> Publie un agent minimal et regarde-le répondre dans le chat — le premier jour de l’éditeur. </Card> <Card title="J’intègre Tale" icon="code" href="/fr/get-started/developers"> Crée une clé API et envoie ta première requête authentifiée — le premier jour du développeur. </Card> <Card title="Je gère l’espace de travail" icon="shield" href="/fr/get-started/admins"> Monte l’espace de travail, invite l’équipe, connecte un fournisseur — le premier jour de l’admin. </Card> </CardGroup> ## Choisis ton édition <CardGroup cols="2"> <Card title="Cloud" icon="cloud" href="/fr/cloud"> Tale exploite la stack — choisis cette voie quand exploiter de l’infrastructure n’est pas là où ton équipe doit passer ses heures. </Card> <Card title="Auto-hébergé" icon="server" href="/fr/self-hosted"> Installe Tale dans ton propre VPC, sur du matériel on-premise ou dans un environnement coupé du réseau. </Card> </CardGroup> ## Aller plus loin <CardGroup cols="3"> <Card title="Plateforme" icon="layout-dashboard" href="/fr/platform"> La référence canonique des fonctionnalités, identique pour Cloud et auto-hébergé. </Card> <Card title="Tutoriels" icon="route" href="/fr/tutorials/overview"> Des parcours indexés par rôle, de « je veux faire X » au résultat qui fonctionne. </Card> <Card title="Développement" icon="terminal" href="/fr/develop/overview"> REST API, webhooks, SDK d’connector, workflows pour les contributeurs. </Card> </CardGroup> ## Où cela s’inscrit Une fois un parcours de démarrage terminé, le reste de la documentation est à un clic : [Plateforme](/fr/platform) est la référence canonique de chaque fonctionnalité visible par l’utilisateur, et les [Tutoriels](/fr/tutorials/overview) approfondissent des tâches complètes. Le code source, les issues et les annonces de release vivent sur [GitHub](https://github.com/tale-project/tale). # Trust et conformité Source: https://tale.dev/docs/fr/cloud/trust-and-compliance Trust et conformité sur Cloud est la page qu'un auditeur veut. Elle nomme les cadres contre lesquels la plateforme est certifiée, sépare proprement les responsabilités entre Tale et ton organisation, liste les contrôles de protection des données à ta disposition, et te dit qui appeler quand quelque chose tourne mal. Le contenu ici est descriptif — ce qui est livré aujourd'hui, quelles preuves Tale peut fournir sur demande. Les documents légaux eux-mêmes (DPA, conditions, politique de confidentialité) vivent sous [Mentions légales](/fr/legal/privacy) ; cette page est la référence rapide de l'opérateur. ## Un contrôle déroulé — journaux d'audit de bout en bout Le responsable conformité de l'organisation doit démontrer que « chaque changement de contrôle d'accès est journalisé avec l'acteur, la cible et l'horodatage ». Les [Journaux d'audit](/fr/platform/admin/governance/audit-logs) de Tale enregistrent chaque invitation de membre, changement de rôle, suppression et réinitialisation 2FA avec l'ID utilisateur de l'acteur, l'ID du membre affecté, et un horodatage ISO. Les journaux sont immuables — restaurer un instantané ne les modifie pas — et conservés selon le plancher configuré par l'organisation. Le responsable exporte une plage de dates en CSV, la remet à l'auditeur, et l'exemple déroulé valide le contrôle. ## Certifications et cadres Tale Cloud est actuellement audité ou attesté contre les cadres suivants ; les rapports de certification sont disponibles sous NDA via le support : - SOC 2 Type II (annuel) - ISO/IEC 27001 - Contrôles alignés RGPD (lignes directrices EDPB appliquées) - Contrôles alignés LPD pour la région Suisse (nLPD) En attente ou prévus : BAA HIPAA (clients entreprise US), attestations régionales supplémentaires à mesure que la liste des régions s'agrandit. ## Responsabilité partagée | Contrôle | Tale | Toi | Preuve | | --------------------------------- | -------------------- | -------------------- | ---------------------------------------------------------- | | Disponibilité d'infrastructure | ✓ | | Page de statut, rapport SLA SOC 2 | | Chiffrement des données au repos | ✓ | | Description d'architecture | | Chiffrement en transit | ✓ | | Terminaison TLS par le edge de Tale | | Identité des membres et rôles | | ✓ | [Membres et rôles](/fr/platform/admin/members-and-roles) | | Émission et rotation des clés API | | ✓ | [Clés API](/fr/platform/admin/api-keys) | | Filtrage de contenu et DLP | Fournit les crochets | Configure les règles | [Guardrails](/fr/platform/admin/governance/guardrails) | | Rétention des journaux d'audit | Fournit le stockage | Règle la rétention | [Rétention](/fr/self-hosted/configuration/retention) | | Demandes de personnes concernées | Fournit le workflow | Initie et approuve | [DSR](/fr/platform/admin/governance/data-subject-requests) | | Identifiants fournisseurs | | ✓ | [Providers](/fr/platform/admin/providers) | ## Contrôles de protection des données Dans le produit, trois surfaces de contrôle comptent pour la conformité : - **Journaux d'audit** — enregistrement immuable de qui a fait quoi ; rétention configurable. - **Conservation légale** — exempte un ensemble d'enregistrements de la rétention jusqu'à la levée ; couvert dans [Conservation légale](/fr/platform/admin/governance/legal-hold). - **Demandes de personnes concernées** — le workflow demande → prise en charge → effacement → audit ; couvert dans [DSR](/fr/platform/admin/governance/data-subject-requests). ## Signaler les incidents Le contact incident sécurité de Tale est `security@tale.dev`. La divulgation de vulnérabilités présumées suit la politique de divulgation responsable sur le même e-mail. Les bulletins de sécurité côté client sont publiés sur la page de statut et envoyés par e-mail au Owner de l'organisation. ## Où ça s'inscrit Trust et conformité est la page du moment d'audit ; [Résidence des données](/fr/cloud/data-residency) est la page du moment d'architecture ; [Sous-traitants](/fr/legal/subprocessors) est la page liste-de-vendeurs. Un auditeur veut généralement les trois en même temps — mets-les toutes en favoris. Si tu opères en auto-hébergé, les contrôles sont les mêmes ; ce qui change est qui fait tourner l'infrastructure en dessous — voir [Aperçu auto-hébergé](/fr/self-hosted/overview). # Migrer vers auto-hébergé Source: https://tale.dev/docs/fr/cloud/migrate-to-self-hosted La migration de Cloud vers l'auto-hébergement est une vraie procédure, pas un basculement de réglage. Les données s'exportent, la nouvelle instance importe, le DNS bascule vers le nouvel hôte, et ton équipe se connecte dans la même organisation qu'avant — mêmes agents, mêmes chats, même historique d'audit. Ce tutoriel parcourt la procédure et pointe vers les endroits où elle déraille. Va-y quand l'auto-hébergement convient vraiment mieux : la résidence des données exige du matériel sous ton contrôle, les coûts à l'échelle rendent on-premise moins cher que au-token, ou l'organisation a décidé de faire tourner la pile elle-même. Pour la plupart des équipes, Cloud reste le bon choix — relis [Onboarding Cloud](/fr/cloud/onboarding) si tu hésites encore. ## Avant de commencer Mets ces choses en place avant d'exporter quoi que ce soit : - Un hôte cible qui répond aux prérequis auto-hébergé — voir [Démarrage rapide](/fr/self-hosted/install/quickstart) pour le cahier des charges. - Le contrôle DNS sur le domaine que ton organisation utilise actuellement ; tu le balanceras lors de la bascule. - Une fenêtre de maintenance d'au moins une heure. L'import lui-même est plus rapide, mais la propagation DNS et la validation ajoutent du temps. - Une confirmation de sauvegarde récente dans le journal d'audit de ton organisation Cloud. Rien n'est supprimé dans la source pendant une migration, mais le bundle d'export est ta preuve que l'état source était cohérent. ## Ce qui est transféré et ce qui ne l'est pas Transféré : chats, threads, messages, pièces jointes, documents, embeddings de connaissances, agents, versions d'agents, workflows, exécutions, journaux d'audit, membres, rôles, équipes, branding, clés API, métadonnées de connectors. Pas transféré : les connectors externes doivent être réauthentifiées contre la nouvelle instance (les identifiants vivent chez le fournisseur, pas dans le bundle d'export) ; les workflows actifs en cours se mettent en pause et reprennent sur la nouvelle instance après la bascule ; les audios vocaux conservés au-delà de la fenêtre de rétention de l'organisation restent dans le stockage objet Cloud jusqu'à leur purge. ## Étape 1 — Exporter Ouvre **Paramètres > Organisation** sur Cloud et clique **Export**. Le dialogue lance l'export en arrière-plan et envoie par e-mail un lien de téléchargement une fois terminé. L'export est un seul bundle chiffré ; l'e-mail contient la clé de déchiffrement. Télécharge le bundle et garde la clé séparément. ## Étape 2 — Mettre en place l'instance cible Sur l'hôte cible, suis [Démarrage rapide](/fr/self-hosted/install/quickstart) jusqu'à l'étape premier-admin. N'invite pas encore d'utilisateurs — l'import écrase la liste des membres. Confirme que la nouvelle instance démarre et que tu peux te connecter comme Owner. ## Étape 3 — Importer Sur l'instance cible, connecte-toi comme Owner et visite `/_internal/import` (lié depuis la page Paramètres après une installation neuve). Téléverse le bundle, colle la clé de déchiffrement, et clique **Import**. L'import est une opération longue ; la page montre la progression par classe de données. Quand la page se résout à **Import complete**, la nouvelle instance porte l'état complet de l'organisation source. ## Étape 4 — Basculer le DNS Mets à jour l'enregistrement DNS du domaine de l'organisation pour pointer vers la nouvelle instance. Une fois la propagation effectuée et le TLS de la nouvelle instance en bonne santé, les utilisateurs qui se connectent arrivent sur l'instance auto-hébergée avec leurs identifiants existants. L'organisation Cloud devient en lecture seule à ce moment — pour éviter la dérive, archive-la sous **Paramètres > Organisation** sur Cloud après quelques jours de confiance. ## Dépannage - **L'export reste bloqué à « preparing ».** Les très grosses organisations (>100 Go) prennent plus de temps que la fenêtre e-mail suppose. Ouvre un ticket support ; l'export va jusqu'au bout en arrière-plan. - **L'import échoue sur un schéma incompatible.** Ton instance cible fait tourner une version Tale plus ancienne que ce que l'export Cloud attend. Mets à jour la cible avant de retenter — le bundle est compatible vers l'avant, pas vers l'arrière. - **Les membres ne peuvent pas se connecter après la bascule.** Les cookies de session sont scopés à l'ancien hôte. Les membres se ré-authentifient une fois ; les réglages SSO et 2FA traversent. - **Les workflows affichent « en pause » après l'import.** Attendu — l'import préserve l'état mais ne reprend pas automatiquement les exécutions en cours. Ouvre chaque workflow et clique **Resume** après avoir confirmé que l'instance cible est joignable depuis les déclencheurs externes. ## Où ça s'utilise La migration est en pratique une opération à sens unique — une fois auto-hébergé, tu y restes, sauf changement structurel. La migration inverse (auto-hébergé vers Cloud) suit la même forme avec les mêmes outils et est prise en charge, mais rare. Si tu es encore sur Cloud et tu lis ça pour le contexte, la page à enchaîner est [Aperçu auto-hébergé](/fr/self-hosted/overview) ; elle nomme ce que tu prends sur les épaules. # Cloud Source: https://tale.dev/docs/fr/cloud Tale Cloud est l’édition gérée. Tale exploite l’infrastructure, tes données sont ancrées en Suisse ou dans l’UE, et la seule préoccupation opérationnelle de ton équipe est d’utiliser le produit. Le code est identique à la version auto-hébergée ; la différence porte sur qui le fait tourner. Cette section couvre ce qui est spécifique à Cloud — l’onboarding, les régions et la résidence des données, la facturation, la posture de conformité que tu peux remettre à un auditeur, et comment migrer vers de l’auto-hébergé si tes besoins changent. Toute autre référence de fonctionnalité vit un onglet plus loin, sous Plateforme, identique quelle que soit l’édition. ## Pages de cette section <CardGroup cols="2"> <Card title="Onboarding" icon="rocket" href="/fr/cloud/onboarding"> Demande d’instance, création de l’organisation, configuration du premier fournisseur de modèle, publication du premier agent. Environ une heure pour un Éditeur. </Card> <Card title="Résidence des données" icon="map-pin" href="/fr/cloud/data-residency"> Où vivent tes données, quels sous-traitants les touchent et ce qui change quand tu changes de région. </Card> <Card title="Facturation" icon="credit-card" href="/fr/cloud/billing"> Plans, sièges, composants facturés, budgets, et où trouver la facture. </Card> <Card title="Confiance et conformité" icon="shield-check" href="/fr/cloud/trust-and-compliance"> Les certifications dont Tale dispose, le partage des responsabilités, et les preuves que tu peux remettre à un auditeur. </Card> <Card title="Migrer vers l’auto-hébergé" icon="server" href="/fr/cloud/migrate-to-self-hosted"> Exporter depuis Cloud, monter une instance auto-hébergée, importer. </Card> </CardGroup> ## Où cela s’inscrit Cloud est la porte d’entrée pratique ; Plateforme est l’endroit où le vrai travail se passe. Une fois ton organisation connectée et le premier agent en route, ton équipe passe la quasi-totalité de son temps dans les pages Plateforme, pas ici. La seule page qui mérite une relecture à chaque changement de ta posture opérationnelle est [Résidence des données](/fr/cloud/data-residency) — elle expose chaque système externe que tes données traversent. # Facturation Source: https://tale.dev/docs/fr/cloud/billing La facturation sur Cloud est mesurée, pas par siège. Tu paies pour les tokens consommés par les chats et les agents, les minutes vocales, les générations d'images et le stockage ; la plateforme elle-même vient avec l'organisation. Cette page parcourt une ligne de facture, liste les composants mesurés, et pointe vers les contrôles de budget qui évitent les surprises. La facture arrive chaque mois par e-mail et est aussi visible dans le produit sous **Paramètres > Facturation**. Cloud facture dans la devise de facturation de ton organisation, qui par défaut est USD à l'inscription et peut être changée avant la première facture. ## Une ligne de facture déroulée Une ligne sur la facture lit `Models — Anthropic Claude Sonnet — 1.2M tokens — $4.32`. Tale l'a assemblée depuis le ledger d'usage par message : chaque réponse de chat enregistre le modèle utilisé, le compte de tokens, et le coût au tarif actif quand l'appel s'est terminé. Les lignes s'agrègent par fournisseur et par modèle par période de facturation. Le détail est téléchargeable en CSV depuis le même écran. ## Plans Tale propose deux plans — **Community** et **Enterprise**. Community est l'édition open source auto-hébergée ; tu la fais tourner sur ta propre infrastructure et le concept de facturation décrit sur cette page ne s'applique pas. **Enterprise** est le plan géré (Cloud ou auto-hébergé) avec un SLA de support, des contrôles de rétention des journaux d'audit, SSO, le DPA et l'accès à des régions au-delà du défaut. Le plan affecte les frais fixes mensuels et les barrières fonctionnelles, pas le coût par appel ; le tarif mesuré pour les tokens, la voix et le stockage ci-dessous s'applique à Enterprise sur Cloud. ## Composants mesurés | Composant | Unité | Compté comme | Où le voir | | ---------- | ----------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------- | | Modèles | Tokens (in + out) | Par appel fournisseur ; marge en plus du tarif fournisseur | [Analytique d'utilisation](/fr/platform/admin/governance/usage-analytics) | | Voix (TTS) | Caractères parlés | Par réponse d'agent rendue en audio | Analytique d'utilisation | | Voix (STT) | Secondes audio | Par message utilisateur enregistré | Analytique d'utilisation | | Images | Générations | Par image retournée par le modèle | Analytique d'utilisation | | Stockage | Go-mois | Usage du stockage objet moyenné sur la période | Page de facturation | ## Budgets et dépassements Règle les budgets sous [Politiques et limites](/fr/platform/admin/governance/policies-and-limits). Une **Budget rule** plafonne la dépense mensuelle par utilisateur, par équipe, par rôle ou par organisation. Atteindre un budget se lit comme un toast clair — **Limite d'utilisation atteinte** — et met en pause la portée affectée jusqu'à ce que le budget soit relevé ou que la période bascule. La précédence par défaut est `utilisateur > équipe > rôle > défaut` — la règle la plus spécifique l'emporte. Un **Warning threshold (%)** sur la même règle émet une notification quand l'usage franchit le seuil sans bloquer. Va vers l'avertissement quand tu veux savoir sans interrompre ; va vers les limites dures quand les dépassements sont une urgence. ## Où trouver l'usage La vue la plus riche est [Analytique d'utilisation](/fr/platform/admin/governance/usage-analytics) sous Gouvernance — elle décompose l'usage par **Top Assistants**, **Top Models**, **Top Voice Models** et **Per-User Usage**, tous filtrables par plage de dates. La page Facturation dans Paramètres montre la vue niveau facture ; Analytique d'utilisation montre la vue opérationnelle. ## Où ça s'inscrit La facturation est la page phare de l'opérateur ; [Analytique d'utilisation](/fr/platform/admin/governance/usage-analytics) est la page quotidienne. Si le coût de ton organisation est surtout des tokens, la page à mettre en favori est la table Top Models — elle fait remonter quels modèles l'équipe a adoptés et te dit si un basculement vers une alternative moins chère ferait la différence. Pour les utilisateurs auto-hébergés, le concept de facturation ne s'applique pas (tu paies ton fournisseur directement) ; la page de visibilité des coûts, si. # Onboarding Cloud Source: https://tale.dev/docs/fr/cloud/onboarding <!-- Internal, for agents editing this page: Tale Cloud has no self-serve sign-up — tale.dev ships no sign-up route. A Cloud customer fills in the demo request form (https://tale.dev/request-demo — /de/ and /fr/ localized), and the Tale team sets up a dedicated demo instance for them. The journey below only starts once that instance exists; from there it deliberately mirrors normal first-run onboarding (sign-up on the customer's own instance, org wizard, providers). Keep the request-your-instance step first and do not change the entry point back to a tale.dev sign-up. --> Ce parcours va de la demande de démo à une organisation Cloud prête pour la production avec un agent qui fonctionne. Le résultat est une organisation où ton équipe peut se connecter, choisir un agent qui marche et lui demander quelque chose d’utile — rien d’extraordinaire encore, juste le socle sur lequel tout le reste se construit. Il te faut une adresse e-mail qui fonctionne et la possibilité de la vérifier. Le parcours ne suppose aucune connaissance préalable de Tale ; si quelque chose ci-dessous mentionne un concept que tu n’as pas rencontré, la page liée l’introduit. Une fois ton instance prête, la partie pratique prend moins d’une heure — environ la moitié part dans l’étape du fournisseur, le reste est surtout des clics. ## Avant de commencer Cale trois choses : - Une adresse e-mail pour le premier compte **Propriétaire** de l’organisation. Ce compte portera le rôle le plus élevé ; choisis quelqu’un qui ne quittera pas l’équipe la semaine prochaine. - Des identifiants API pour au moins un fournisseur de modèles (OpenAI, Anthropic, Azure ou un compatible local). Le portail du fournisseur montre où ils vivent. - La région où ancrer tes données. Cloud propose la Suisse et l’UE ; le choix fait partie de la mise en place de l’instance — changer plus tard est une vraie migration. ## De la demande de démo à un agent qui fonctionne <Steps> <Step title="Demande ton instance"> Tale Cloud ne s’active pas en libre-service — chaque organisation Cloud tourne sur sa propre instance, montée pour toi par l’équipe Tale. Remplis le formulaire de demande de démo sur [tale.dev/fr/request-demo](https://tale.dev/fr/request-demo) ; le nom et l’e-mail suffisent, la société et une ligne sur ce que tes agents doivent faire aident l’équipe à ajuster la mise en place. L’équipe monte ensuite ta propre instance de démo — un environnement dédié, pas un essai partagé — et revient vers toi dès qu’elle est prête. </Step> <Step title="Crée ton organisation"> Ouvre ton instance et inscris-toi. Le formulaire demande ton nom, ton e-mail et un mot de passe ; vérifie le lien reçu par e-mail. L’écran suivant demande le **Nom de l'organisation** — le nom affiché que ton équipe verra dans le coin de chaque page. Choisis-en un qui survit à un rebranding. <Frame caption="L’étape espace de travail — le nom que ton équipe voit partout."> ![L’assistant de création d’organisation à son étape espace de travail, avec Northlight Labs saisi dans le champ Nom de l’organisation et le bouton Suivant actif.](/images/get-started/org-create-wizard.webp) </Frame> Le premier utilisateur devient automatiquement **Propriétaire** de l’organisation. Tu retrouveras ton rôle plus tard dans la section **Membres** sous **Paramètres > Organisation** si tu l’oublies. </Step> <Step title="Invite le premier admin"> Ouvre **Paramètres > Organisation**, descends jusqu’à la section **Membres** et clique sur **Ajouter un membre**. Saisis l’e-mail de l’admin et assigne le rôle **Admin**. L’invité reçoit un e-mail avec un lien magique ; il s’inscrit et atterrit dans l’organisation avec le rôle que tu as assigné. La règle de sécurité « au moins 2 Admins » empêche une organisation de s’enfermer dehors en retirant son seul Admin — invite un second admin avant toute action qui l’exige. Pour la matrice des rôles (qui peut faire quoi), voir [Membres et rôles](/fr/platform/admin/members-and-roles). </Step> <Step title="Ajoute un fournisseur de modèles"> Ouvre **Paramètres > Fournisseurs IA**, repère le connecteur pour lequel tu détiens une clé et clique sur **Ajouter un identifiant**. Donne-lui un nom qui dira plus tard de quelle clé il s’agit, choisis **Clé API** comme méthode d’authentification et colle la clé. Elle est stockée chiffrée et devient l’identifiant par défaut du connecteur quand c’est le premier ; un second identifiant sur le même connecteur est permis, et c’est toi qui désignes le défaut. Quand une clé est rejetée, c’est presque toujours un espace autour d’elle. <Frame caption="Le fournisseur connecté — à partir d’ici, chaque agent peut répondre."> ![La page des paramètres des fournisseurs d’IA listant un seul fournisseur connecté, OpenRouter, avec son URL de base et ses 52 modèles.](/images/get-started/settings-providers.webp) </Frame> <Note> C’est l’étape où la plupart des sessions d’onboarding calent — le portail du fournisseur est souvent un autre login, et l’équipe doit creuser pour retrouver la clé. Si la validation reste bloquée plus d’une minute, recharge la page ; la clé est enregistrée dès que **Enregistrer** confirme, la ligne a parfois juste besoin d’un rechargement pour se mettre à jour. </Note> </Step> <Step title="Publie ton premier agent"> Ouvre **Agents** et clique sur **Créer un agent**. Choisis le modèle que tu viens d’ajouter. Écris un bloc d’instructions d’un paragraphe — la voix dans laquelle l’agent doit répondre, le domaine qu’il connaît, les cas qu’il refuse. Enregistre. Active **Visible dans le chat**. L’agent est maintenant joignable depuis n’importe quel chat de l’organisation. Pour un parcours plus profond sur ce qui fait un bon agent, voir [Créer un agent](/fr/platform/agents/create). </Step> <Step title="Ouvre le chat"> Clique sur **Nouveau chat** dans la barre latérale. Choisis l’agent dans le sélecteur, tape une question que son domaine couvre, envoie. <Check> La réponse arrive en streaming — si elle atterrit comme tu l’as voulue dans les instructions, l’organisation a fini son onboarding. </Check> Trois suites qui valent la peine maintenant, pendant que tout est frais : - Ouvre **Paramètres > Branding** et téléverse le logo de l’organisation. - Règle la langue par défaut de l’organisation sous **Paramètres > Organisation**. - Parcours [Trust et conformité](/fr/cloud/trust-and-compliance) pour savoir quoi montrer à un auditeur avant qu’on te le demande. </Step> </Steps> ## Dépannage - **L’e-mail d’invitation n’arrive jamais.** Vérifie le dossier spam de l’invité. Tale envoie depuis `noreply@tale.dev` ; certains filtres d’entreprise le mettent en quarantaine. - **La validation du fournisseur échoue avec « invalid key ».** Recopie la clé depuis le portail du fournisseur — la copie embarque souvent un espace en tête ou en queue. - **L’agent n’apparaît pas dans le sélecteur du chat.** Confirme que **Visible dans le chat** est activé pour l’agent. ## Où ça s’utilise Tu as maintenant une organisation avec un agent qui fonctionne et un admin en plus de toi. Le parcours suivant naturel est [Construire ton premier agent de bout en bout](/fr/tutorials/editor/first-agent-end-to-end) — même forme, mais avec un agent qui fait un vrai travail de domaine grâce à des liaisons de connaissances. Si tu es venu évaluer Cloud face à l’auto-hébergé, [Migrer vers auto-hébergé](/fr/cloud/migrate-to-self-hosted) est le parcours inverse. # Résidence des données Source: https://tale.dev/docs/fr/cloud/data-residency La résidence des données sur Cloud répond à deux questions que chaque audit finit par poser : quelle région détient tes données au repos, et quels systèmes externes les touchent en vol. Cette page trace un seul aller-retour de chat de bout en bout, liste les classes de données, et nomme chaque sous-traitant que tes messages traversent. La région par défaut pour les nouvelles organisations Cloud est la Suisse. Changer de région après l'inscription est une migration, pas un basculement de réglage — recréer une organisation dans la région UE est plus rapide que d'en déplacer une existante. Choisis une fois ; choisis délibérément. ## Un exemple déroulé — un aller-retour de chat L'utilisateur à Zurich ouvre Chat et envoie « résume le dernier appel client ». La requête frappe le edge de Tale dans la région choisie, atterrit sur `tale-platform`, qui appelle dans `tale-convex` (le backend), lit les connaissances depuis la base de connaissances dès que l'outil de connaissances de l'agent les demande, et émet un appel sortant vers le fournisseur derrière le modèle choisi par la personne qui envoie. La récupération de connaissances tourne dans le backend Convex — elle interroge directement la base de connaissances, sans service de récupération séparé sur le chemin. Le fournisseur de modèles retourne des tokens ; Tale les streame en retour sur le même chemin. La réponse et les citations atterrissent dans la base de données opérationnelle, le corpus reste dans la base de connaissances, et les deux sont répliqués dans la région. Deux flèches franchissent la frontière régionale dans ce trajet : l'appel vers le fournisseur de modèles (toujours externe) et tout sous-traitant déclenché par les outils de l'agent (fetch web, lecture OneDrive, serveur MCP dans une autre région). Tout le reste reste dans la région. ## Régions primaires | Région | Postgres | Stockage objet | Réplica DR | | ---------------- | --------- | -------------- | ---------- | | Suisse | Zurich | Zurich | Genève | | Union européenne | Francfort | Francfort | Dublin | Le réplica DR sert au plan de reprise après sinistre, pas au trafic actif. Les données d'une région ne circulent jamais vers le primaire ou le réplica de l'autre. ## Ce qui reste dans la région, ce qui en sort | Type de données | Lié à la région | Traverse | Notes | | ---------------------------------------- | --------------- | -------- | ------------------------------------------------------------------------------ | | Chats et messages | ✓ | | | | Documents et embeddings de connaissances | ✓ | | | | Configuration d'organisation et rôles | ✓ | | | | Journaux d'audit | ✓ | | | | Requêtes vers le fournisseur de modèles | | ✓ | Va vers le fournisseur configuré ; choisis un endpoint régional si disponible. | | Synchronisation OneDrive | | ✓ | La région de stockage de Microsoft s'applique. | | Récupérations de l'outil web | | ✓ | Là où l'URL résout. | ## Sauvegardes et DR Tale prend un instantané des deux bases Postgres — la base opérationnelle et le corpus de connaissances — chaque jour, et du stockage objet chaque heure. Les instantanés sont chiffrés au repos avec des clés détenues par Tale ; le réplica DR reçoit une copie dans la région. Les restaurations à partir d'instantanés sont une opération initiée par le client routée via le support ; le SLA couvre le temps de restauration. ## Changer de région Un changement de région s'implémente comme un export depuis la région courante, un import dans la nouvelle région, et un basculement DNS. La procédure est la même que [Migrer vers auto-hébergé](/fr/cloud/migrate-to-self-hosted), sauf que les deux côtés sont des régions Cloud ; attends-toi à une indisponibilité de l'ordre de la minute et une fenêtre planifiée. Il n'y a pas de bascule de région in-place. ## Où ça s'inscrit La résidence des données est la première page que toute revue de conformité lit. Couple-la avec [Trust et conformité](/fr/cloud/trust-and-compliance) (quel cadre couvre quoi) et [Sous-traitants](/fr/legal/subprocessors) (la liste de chaque système externe nommé ci-dessus). Si ton organisation envisage l'auto-hébergement pour une exigence de résidence, [Aperçu auto-hébergé](/fr/self-hosted/overview) est la lecture suivante — faire tourner la pile sur ton propre matériel déplace chaque flèche de cette page à l'intérieur de ta propre frontière. # Monter un serveur MCP depuis zéro Source: https://tale.dev/docs/fr/tutorials/developer/mcp-server-from-scratch Un serveur Model Context Protocol (MCP) est un processus qui expose une liste d'outils via un petit protocole JSON-RPC. Tale enregistre un serveur MCP une fois au niveau de l'organisation ; à partir de là, chaque agent dont l'onglet Outils inclut ce serveur peut appeler ses outils. Ce parcours mène un serveur MCP tout neuf de « repo vide » à « appelé par un agent dans un chat » sur une instance Tale. Il te faut le rôle Developer, un hôte qui peut exécuter le serveur MCP (ton portable suffit pour le parcours ; un service managé ou un conteneur pour la production) et une URL HTTPS que Tale peut joindre. Les organisations Cloud joignent les URLs publiques par défaut ; les instances auto-hébergées ont besoin d'un accès réseau vers l'endroit où tourne le serveur MCP. ## Avant de commencer Confirme deux choses. Tu as Node 20 ou Python 3.11 installé — les SDK MCP officiels visent ces runtimes. L'instance Tale peut joindre l'URL de ton serveur MCP — pour le développement local, un tunnel `ngrok` ou équivalent fait l'affaire ; pour la production, héberge le serveur quelque part avec un endpoint HTTPS stable. Le côté conceptuel de MCP dans Tale vit dans [Outils d'agent](/fr/platform/agents/tools) ; ce parcours est le câblage. ## Étape 1 — Échafauder le serveur Le premier geste est de générer le serveur MCP minimal — un outil, un handler. Le SDK officiel s'occupe de la plomberie du protocole pour que tu n'écrives que l'outil. ```bash npm create mcp-server@latest hello-tale cd hello-tale ``` Ouvre `src/index.ts` et remplace l'outil d'exemple par un qui renvoie l'heure courante dans un fuseau horaire donné : ```ts server.tool( 'current_time', 'Return the current time in a given timezone', { timezone: z.string() }, async ({ timezone }) => { const now = new Date().toLocaleString('en-US', { timeZone: timezone }); return { content: [{ type: 'text', text: now }] }; }, ); ``` Lance le serveur localement : ```bash npm run start ``` Le serveur écoute sur `http://localhost:3000/mcp` par défaut. L'échafaudage est en place ; rien dans Tale ne le connaît encore. ## Étape 2 — L'exposer en HTTPS Les serveurs MCP que Tale peut appeler ont besoin d'une URL HTTPS avec un certificat valide. Pour le développement local, pointe un tunnel `ngrok` sur le port 3000 et copie l'URL publique qu'il affiche. Pour la production, héberge le serveur derrière ton ingress habituel — Caddy, Nginx, une fonction managée, tout ce qui termine le TLS. Vérifie que l'URL publique répond à un health-check : ```bash curl -sS "https://abcd.ngrok.app/mcp/health" ``` Un 200 confirme la joignabilité. Un 502 ou un timeout veut dire que le tunnel ne route pas ; relance-le ou vérifie le pare-feu. ## Étape 3 — Enregistrer le serveur dans Tale Un serveur MCP joignable reste invisible pour Tale tant que tu ne l'as pas enregistré. Ouvre **Paramètres > Connectors > Serveurs MCP** et clique **Nouveau serveur**. Remplis : - **Nom** — `Hello Tale time` - **URL** — l'URL HTTPS publique de l'étape 2 (par ex. `https://abcd.ngrok.app/mcp`) - **Auth** — bearer token si ton serveur en exige un, aucun pour le parcours Clique **Enregistrer**. Tale appelle la méthode `list_tools` du serveur pour découvrir l'inventaire d'outils ; le panneau affiche `current_time` avec sa description. Le serveur est désormais enregistré pour toute l'organisation. ## Étape 4 — Attacher le serveur à un agent et appeler l'outil Un serveur enregistré n'est joignable que par les agents qui s'y abonnent. Ouvre n'importe quel agent, clique **Outils > MCP**, active **Hello Tale time** et enregistre. Ouvre un chat avec l'agent et demande « what time is it in Tokyo right now ». Le chat rend une carte d'appel d'outil `current_time` ; la déplier montre `{ "timezone": "Asia/Tokyo" }` et l'horodatage que ton serveur a renvoyé, et la réponse de l'agent utilise l'horodatage. ## Où ça s'utilise Un serveur MCP est la bonne forme quand un outil doit vivre hors de Tale — du code possédé par ton équipe, un service dans un autre réseau, une API tierce que tu enveloppes. Les outils personnalisés de [Construire un outil personnalisé](/fr/tutorials/developer/build-a-custom-tool) sont la bonne forme quand l'outil est ponctuel et vit dans les paramètres d'une seule organisation. Pour la grande image de comment les outils élargissent ce qu'un agent peut faire, voir [Outils d'agent](/fr/platform/agents/tools). Pour câbler une connector qui enveloppe une API tierce plutôt que ton propre code, [Aperçu des connectors](/fr/platform/connectors/overview) est la lecture suivante. # Déclencher une automatisation par webhook Source: https://tale.dev/docs/fr/tutorials/developer/trigger-automation-via-webhook Un déclencheur webhook transforme une automatisation en quelque chose qu'un système externe peut tirer par un POST JSON. Tale compare le jeton de l'URL au déclencheur, et l'exécution lancée appartient à la version déployée de l'automatisation — jamais à un brouillon que quelqu'un est en train de modifier. Ce parcours mène une automatisation de « je veux la tirer depuis l'extérieur » à « un événement de commande arrive et l'exécution apparaît » sur une seule instance. Il te faut le rôle Développeur dans l'organisation, une automatisation avec une version déployée, et un shell avec `curl`. Le contrat entrant complet — codes de statut, traitement du body, limites de taille — vit dans [Webhooks](/fr/develop/webhooks) ; ce parcours en est le plus petit usage de bout en bout. ## Avant de commencer Vérifie deux choses. L'automatisation que tu vas déclencher a une version **déployée** — enregistrer une version ne suffit pas, et une version ne devient déployable qu'une fois ses propres tests au vert ; lance-les d'abord. Ton rôle est au moins Développeur ; ajouter des déclencheurs est réservé à Développeur et au-dessus. Si tu n'as pas encore d'automatisation, la plus petite canonique est « enregistre la charge utile puis arrête-toi » — construis-la via [Workflow avec approbations](/fr/tutorials/editor/workflow-with-approvals) et retire le nœud d'approbation pour ce parcours. ## Étape 1 — Ajouter un déclencheur webhook Le premier geste consiste à lier un déclencheur webhook à l'automatisation. Sans lui, l'automatisation ne part que depuis l'interface ou un planning ; avec lui, elle obtient une URL sur laquelle n'importe quel système peut POSTer. Ouvre l'onglet **Déclencheurs** de l'automatisation et ajoute un webhook. Tale émet une URL dont le chemin porte le justificatif sous forme de jeton — pas de clé séparée, pas d'en-tête Authorization. Le jeton en clair est affiché une seule fois et n'est jamais stocké : copie-le maintenant ; seul son hachage est conservé, ce qui explique que personne ne puisse te retrouver l'URL plus tard. Le déclencheur se lie au **nom** de l'automatisation, pas à la version que tu as déployée. Déploie une nouvelle version demain et cette URL continue de marcher — c'est tout l'intérêt de séparer les deux. ```bash export TALE_TRIGGER_URL="https://your-host.example.com/api/automations/webhook/<token>" ``` ## Étape 2 — POSTer une charge utile depuis curl L'URL de webhook est un point de terminaison POST ordinaire, et le body devient l'entrée de l'exécution. Un body qui n'est pas du JSON est transmis tel quel en texte plutôt que refusé : un fournisseur qui poste des données encodées en formulaire atteint donc quand même ton premier nœud. ```bash curl -sS "$TALE_TRIGGER_URL" \ -H "Content-Type: application/json" \ -d '{ "orderId": "12345", "amount": 199.0 }' ``` Un appel accepté répond **202** avec `{ "runId": "..." }`. L'exécution tourne désormais en asynchrone ; ouvre la liste des exécutions de l'automatisation et tu l'y verras avec ta charge utile en entrée. ## Étape 3 — Lire les cas d'échec Quatre réponses couvrent tout ce que le point de terminaison peut dire, et chacune désigne un correctif différent. **404** signifie que le jeton ne correspond à aucun déclencheur actif — il est faux, il a été supprimé, ou le déclencheur est désactivé. La réponse ne dit délibérément jamais lequel, pour que celui qui devine des jetons n'apprenne rien de la différence. **409** avec `{ "error": "automation has no deployed version" }` signifie que l'automatisation existe mais que rien n'est en ligne : déploie une version dont les tests passent et le même appel s'exécute. **413** signifie que le body dépasse 256 Ko ; poste alors une référence plutôt que la charge utile. **202** est le seul succès. Les retries méritent leur propre phrase : le point de terminaison ne déduplique pas, un POST retenté lance donc une seconde exécution. Ce qui rend cela sûr, c'est l'exécution elle-même — chaque nœud terminé pose un point de reprise, une exécution reprise après une interruption ne rejoue donc jamais les effets de bord déjà produits. Là où une exécution _en double_ resterait fausse, transporte ton propre identifiant d'événement dans la charge utile et branche dessus dans le premier nœud. ## Où ça s'utilise Les déclencheurs webhook sont la couture entrante du moteur d'automatisation — ce sur quoi ton CRM, ton système de commandes ou ta supervision POSTe. Vas-y quand la phrase est « ceci est arrivé chez nous, lance quelque chose là-dessus » ; va vers la [référence API](/fr/develop/api-reference) quand tu veux plutôt une réponse synchrone. La configuration côté déclencheur, et les trois autres façons de lancer la même automatisation, vivent sur [Déclencheurs de workflow](/fr/platform/automations/triggers). # Appeler Tale depuis un script Source: https://tale.dev/docs/fr/tutorials/developer/call-tale-from-a-script Appeler Tale depuis un script, c'est le chemin que tu prends quand tu veux une valeur de la plateforme sans ouvrir l'UI. L'API de Tale parle JSON sur HTTPS et prend un bearer token dans le header `Authorization` ; à partir de là, chaque groupe d'endpoints est un appel REST normal. Cette marche t'amène en une séance de « je veux scripter Tale » à une réponse d'assistant imprimée dans ton terminal. Il te faut un rôle Développeur (pour les clés API), l'URL de ton instance Tale, et un shell avec `curl` et Python. La surface complète vit dans la [référence API](/fr/develop/api-reference) ; cette page en est la traversée de bout en bout la plus courte. ## Avant de commencer Vérifie trois choses. Ton instance répond en HTTPS — ouvre `https://your-host.example.com` et regarde si le tableau de bord charge. Ton rôle est au moins Développeur — les [clés API](/fr/platform/admin/api-keys) se gèrent avec les rôles Admin et Développeur. Tu connais un modèle configuré dans ton organisation — l'API n'en choisit jamais un à ta place, chaque appel de chat nomme son modèle explicitement. ## Étape 1 — Créer une clé API Le premier geste est une clé API. C'est elle que chaque appel de script transporte ; sans elle l'API répond 401, et après la création tu ne peux plus la relire. Crée une clé dans le panneau [Clés API](/fr/platform/admin/api-keys) et copie ce qu'il montre — Tale l'affiche une fois et jamais plus. Range-la en variable d'environnement pour le reste de cette marche : ```bash export TALE_API_KEY="tale_..." export TALE_BASE_URL="https://your-host.example.com" ``` La clé t'appartient, à toi et à ton organisation ; ce qu'elle peut faire suit ton rôle. Traite-la comme un mot de passe. ## Étape 2 — Test de fumée avec curl La plus petite vérification de bout en bout : lister les automatisations de l'organisation. Si ça marche, l'auth, le réseau et l'API vont bien ; si ça échoue, le mode d'échec te dit lequel des trois est cassé. ```bash curl -sS "$TALE_BASE_URL/api/v1/automations" \ -H "Authorization: Bearer $TALE_API_KEY" | jq ``` Un 200 avec un corps `{ "page": [...], "isDone": true, ... }` confirme l'aller-retour — chaque endpoint de liste répond cette même enveloppe paginée. Un 401 dit que la clé est fausse ; tout le reste dit que l'instance est injoignable ou le chemin mal tapé. ## Étape 3 — Interroger un modèle et lire la réponse Le chat par l'API est asynchrone : tu postes un message, le tour tourne en arrière-plan, et tu interroges jusqu'à la fin. Trois appels, une boucle : ```python import os, time, requests base = os.environ["TALE_BASE_URL"] auth = {"Authorization": f"Bearer {os.environ['TALE_API_KEY']}"} # 1. Un thread à toi thread = requests.post(f"{base}/api/v1/threads", headers=auth, json={}).json() # 2. Envoyer un message — nomme un modèle configuré dans ton organisation requests.post( f"{base}/api/v1/threads/{thread['id']}/messages", headers=auth, json={"content": "En une phrase : c'est quoi, Tale ?", "model": "<ton-modele>"}, ).raise_for_status() # 3. Interroger jusqu'à idle, puis lire le dernier message while True: status = requests.get( f"{base}/api/v1/threads/{thread['id']}/generation", headers=auth ).json()["status"] if status == "idle": break time.sleep(1) messages = requests.get( f"{base}/api/v1/threads/{thread['id']}/messages", headers=auth ).json()["page"] print(messages[-1]["content"]) ``` `{"status": "idle"}` signifie que le tour est fini — y compris un tour raté, qui atterrit comme message d'assistant portant l'erreur au lieu de disparaître. L'envoi répond **202** aussitôt ; la réponse n'existe qu'une fois la boucle sortie de `queued`/`streaming`. ## Étape 4 — Démarrer une exécution d'automatisation La même forme 202-puis-suivi démarre du vrai travail. Les noms d'automatisation sont des chemins en `/` et s'écrivent avec `__` dans les URL — `billing/dunning` voyage en `billing__dunning` : ```bash RUN=$(curl -sS -X POST "$TALE_BASE_URL/api/v1/automations/billing__dunning/runs" \ -H "Authorization: Bearer $TALE_API_KEY" \ -H "Content-Type: application/json" -d '{ "input": {} }' | jq -r .runId) curl -sS "$TALE_BASE_URL/api/v1/runs/$RUN" \ -H "Authorization: Bearer $TALE_API_KEY" | jq .status ``` Une exécution live demande ton rôle Développeur ; avec `{"mode": "mock"}` tu répètes contre des mocks déterministes, avec n'importe quelle clé de membre. Un 409 dit que l'automatisation n'a pas encore de version déployée. ## Où ça se place Un script est le chemin quand le plan de données est du JSON, pas un écran — jobs cron, vérifications CI, portails internes. La clé API porte ton rôle, chaque endpoint de liste répond la même enveloppe paginée, et tout ce qui démarre du vrai travail répond 202 et te donne quelque chose à suivre. Pour les déclencheurs entrants — un système tiers poste dans une automatisation Tale — voir [Déclencher une automatisation par webhook](/fr/tutorials/developer/trigger-automation-via-webhook). Pour un client piloté par modèle plutôt qu'un script, l'[endpoint MCP](/fr/develop/mcp-endpoint) expose la même plateforme en outils. Pour l'inventaire complet et le modèle d'erreur, la [référence API](/fr/develop/api-reference) est la seule source de vérité. # Construire un outil personnalisé Source: https://tale.dev/docs/fr/tutorials/developer/build-a-custom-tool Un outil personnalisé est une fonction que tu écris et que le modèle d'un agent peut appeler par son nom. Tu déclares le schéma d'entrée et la forme de retour ; Tale s'occupe de la sérialisation, de la carte d'appel d'outil dans le chat et du renvoi du résultat au modèle. Ce parcours mène un outil personnalisé neuf de « j'ai une fonction en tête » à « l'agent l'appelle depuis un chat » sur une seule instance. Il te faut le rôle Developer dans l'organisation et l'accès au panneau **Paramètres > Outils personnalisés** ; tout le reste se passe dans l'UI. Le concept sous-jacent vit dans [Outils d'agent](/fr/platform/agents/tools) ; la surface côté développeur — schémas, transport, erreurs — est l'objet ici. ## Avant de commencer Confirme deux choses. Premièrement, ton rôle est au moins Developer — le panneau est caché en-dessous. Deuxièmement, tu as un agent éditable ; sinon, crée-en un via [Créer un agent](/fr/platform/agents/create) avant de continuer. Le parcours utilise un outil à une entrée et une sortie nommé `lookup_order` qui prend un ID de commande et renvoie une chaîne de statut — la plus petite forme qui exerce le schéma, l'appel et le rendu du résultat. ## Étape 1 — Définir l'outil dans Outils personnalisés Le premier geste est d'enregistrer le nom de l'outil et son JSON Schema. Le schéma est ce que voit le modèle ; sans schéma, le modèle n'a aucune idée des arguments à émettre, et l'appel ne se produit jamais. Ouvre **Paramètres > Outils personnalisés** et clique **Nouvel outil**. Donne-lui un nom (`lookup_order`), une description d'une phrase (`Look up the status of an order by ID`) et un JSON Schema pour l'entrée : ```json { "type": "object", "properties": { "orderId": { "type": "string", "description": "The order ID, e.g. ORD-12345" } }, "required": ["orderId"] } ``` Enregistre. L'outil est désormais enregistré dans le registre des outils personnalisés de l'organisation ; aucun agent ne l'utilise encore. ## Étape 2 — Câbler l'implémentation Un outil enregistré sans implémentation renvoie une erreur au modèle. Tale expose deux modes d'implémentation : un script sandbox inline (Python ou JavaScript, exécuté dans la sandbox de Tale) et un appel HTTPS sortant (Tale POST les arguments à ton endpoint, tu renvoies du JSON). Choisis le mode HTTPS pour ce parcours — c'est la forme vers laquelle tu te tournes en production. Dans le panneau de détail de l'outil, règle : - **URL de l'endpoint** — `https://your-api.example.com/lookup-order` - **Méthode** — `POST` - **En-tête d'auth** — un bearer token issu de ton gestionnaire de secrets Tale POST `{ "orderId": "..." }` à ton endpoint ; ton endpoint renvoie `{ "status": "shipped", "carrier": "DHL", "eta": "2026-06-01" }`. Enregistre. L'outil personnalisé est câblé. ## Étape 3 — Attacher l'outil à un agent Un outil câblé reste invisible aux agents jusqu'à ce qu'on en autorise un à l'appeler. Ouvre l'agent à étendre, clique **Outils**, descends jusqu'à **Outils personnalisés** et active `lookup_order`. Enregistre l'agent. Ouvre un chat avec l'agent et demande « what is the status of order ORD-12345 ». Le chat affiche une carte d'appel d'outil `lookup_order` repliée entre ton message et la réponse ; la déplier montre les arguments émis par le modèle (`{ "orderId": "ORD-12345" }`) et le JSON renvoyé par ton endpoint. Le modèle écrit ensuite la réponse avec le résultat de l'outil. ## Où ça s'utilise Un outil personnalisé est la couture entre un agent et ton domaine — recherche de commande, recherche interne, calculatrice, tout ce qu'une connector prête à l'emploi ne couvre pas. Le schéma est ce que le modèle utilise pour décider d'appeler, alors prends le temps d'écrire une description serrée et de ne garder que les champs nécessaires. Pour des outils à partager entre organisations, voir [Serveur MCP depuis zéro](/fr/tutorials/developer/mcp-server-from-scratch) — MCP est le protocole pour « un outil, plusieurs instances Tale ». Pour le côté conceptuel de ce que font les outils dans un agent, voir [Outils d'agent](/fr/platform/agents/tools). # Chatter efficacement Source: https://tale.dev/docs/fr/tutorials/member/chat-effectively Chatter efficacement dans Tale ne tient pas à des prompts astucieux ; il s’agit de donner à l’assistant de quoi lire ton intention du premier coup — et de savoir quel travail n’a pas sa place dans un chat. Cinq petites habitudes — demander au lieu de passer commande, choisir le bon modèle, nourrir la base de connaissances au lieu de coller, lire le déroulé de réflexion, vérifier les sources — font passer la réponse moyenne de « merci pour le pavé » à « exactement ce qu’il me fallait ». Cette page déroule les habitudes dans l’ordre sur un chat neuf. Il te faut un rôle Membre — le plancher pour le chat. Le côté conceptuel vit dans [Bases du chat](/fr/platform/chat/basics) ; ce parcours est le mécanisme quotidien. ## Habitude 1 — Demande ; ne passe pas commande Le chat répond aux questions et retrouve du matériel. Il ne produit délibérément pas de livrables — demande une présentation, un document traduit ou un rapport, et l’assistant esquisse la version courte puis te dit de créer une tâche à la place. Travaille avec cette frontière plutôt que contre elle : quand tu te surprends à écrire « crée », « génère le fichier » ou « traduis ce document », prends le chemin de la tâche et assigne-la à un agent — tu y gagnes un responsable, un résultat à relire et un Terminé qu’une personne contrôle. Traduire une phrase que tu as collée est un travail de chat ; traduire un fichier est un travail de tâche. ## Habitude 2 — Laisse Auto travailler ; épingle quand tu en sais plus Le sélecteur s’ouvre sur **Auto** : il lit chaque message et lui assortit un modèle — la recherche rapide tombe sur un modèle vif, la longue question de raisonnement sur un modèle fort, et les détails de la réponse nomment lequel a répondu. C’est le bon défaut presque tous les jours. Épingle un modèle de la liste quand tu sais une chose qu’Auto ne peut pas savoir : la même série doit être répondue par un seul modèle, c’est un modèle précis qui est à l’essai, ou tu veux le réglage d’effort de raisonnement — la deuxième section du sélecteur, qui apparaît pour un modèle épinglé qui en a un. Monte-le pour les questions épineuses, attends-toi, au niveau le plus haut, à des réponses plus lentes et plus chères — et rends le sélecteur à Auto une fois la série finie. ## Habitude 3 — Nourris la base de connaissances ; ne colle pas de pavés L’assistant cherche dans les connaissances de l’organisation — documents, entrées de connaissances, sites web explorés, produits, contacts — et charge le texte intégral de ce qu’il trouve. Cela ne marche que pour le matériel qui s’y trouve vraiment : téléverse la liste de prix ou le document de politique une fois sous [Connaissances](/fr/platform/knowledge/documents), et chaque chat à venir saura le trouver et le citer. Coller un document de 200 pages dans le champ de message remplit le budget de contexte et dilue la réponse ; une question précise sur du matériel téléversé (« que dit la politique de remboursement sur les boîtes ouvertes ? ») bat à chaque fois « dis-moi tout sur les remboursements ». ## Habitude 4 — Lis le déroulé, pas seulement la réponse Au-dessus de chaque réponse, le déroulé de réflexion consigne ce que l’assistant a fait : une ligne de réflexion repliable, et une ligne d’étape par recherche ou récupération de page — _Recherche dans la base de connaissances pour « … »_, _Lecture de example.com_. Jette-y un œil avant de croire la réponse. Une réponse sans étape de recherche derrière une affirmation factuelle vient du savoir propre du modèle ; une étape de recherche qui ne rapporte rien te dit ce qui manque — y compris quand toute une source est indisponible, comme des documents impossibles à chercher tant qu’une personne admin n’a pas configuré de modèle d’embedding. Le déroulé est aussi l’endroit où une récupération échouée dit pourquoi, au lieu que la réponse contourne l’échec en silence. ## Habitude 5 — Vérifie les sources avant de transférer le résumé Sous une réponse qui a lu quelque chose, **Sources** liste exactement les pages et les documents que l’assistant a chargés — la liste dérive de ce qui a réellement tourné, donc une liste vide veut dire que rien n’a été lu. Ouvres-en une avant d’agir sur la réponse : l’habitude de deux minutes qui consiste à confirmer une source par réponse attrape la petite part de résumés qui en disent plus que leur source. Une source web ouvre la page en direct dans un nouvel onglet ; une source document nomme le fichier à retrouver sous Connaissances. ## Où cela s’inscrit Cinq habitudes, un chat, la même boucle à chaque ouverture de l’onglet Chat. Les habitudes se cumulent — demander à l’intérieur de la frontière du chat garde les réponses nettes ; une base de connaissances nourrie fait aboutir les recherches ; le déroulé et les sources ferment la boucle de confiance. Pour la surface sur laquelle ces habitudes vivent, voir [Bases du chat](/fr/platform/chat/basics). Pour le côté fichiers — ce que l’assistant peut chercher et citer — voir la [Base de connaissances](/fr/platform/knowledge/overview). # Utiliser les projets pour grouper fichiers et chats Source: https://tale.dev/docs/fr/tutorials/member/use-projects Un projet est ce vers quoi tu te tournes la deuxième fois que tu te surprends à coller le même contexte dans un chat. Il regroupe fichiers, instructions et chats autour d'une seule chose à faire — un contact, un lancement, une longue enquête — pour que chaque nouvelle conversation démarre avec le contexte déjà chargé. Ce parcours mène un projet neuf de « je recharge sans cesse le même brief » à « chaque chat dans ce projet connaît déjà le brief » sur une seule instance. Il te faut un rôle Membre (le plancher pour créer un projet) et trois ou quatre fichiers que tu référence régulièrement. Le côté conceptuel vit dans [Concepts de projet](/fr/platform/projects/concepts) ; ce parcours est le mécanisme de bout en bout. ## Avant de commencer Confirme deux choses. Ton rôle est au moins Membre — la création de projet est verrouillée à Membre et au-dessus. Tu as trois à quatre fichiers qui reviennent dans les chats que tu as eus — un brief, une transcription, une liste de prix, une politique. Ils deviennent l'ensemble de travail du projet. ## Étape 1 — Créer le projet Le projet est le conteneur dans lequel vivent les autres pièces. Ouvre **Projets > Nouveau projet** et règle : - **Nom** — `Compte Acme` (ou ce qui nomme la chose à faire) - **Description** — une phrase sur l'objet du projet - **Membres** — laisse en privé pour l'instant ; tu pourras ajouter des coéquipiers après que le premier chat marche Enregistre. Le projet apparaît dans la sidebar ; un clic ouvre une vue de projet vide avec des onglets pour Connaissances, Threads, Agents et Instructions. ## Étape 2 — Charger les fichiers une seule fois Les fichiers du projet sont visibles pour chaque chat dans le projet, donc ce chargement se fait une fois et se rembourse à chaque chat ultérieur. Ouvre l'onglet **Connaissances** et glisse les trois ou quatre fichiers confirmés dans les prérequis. Chaque fichier atterrit dans le stockage du projet et s'indexe comme un document de base de connaissances. Une fois le statut **Prêt**, n'importe quel chat démarré dans le projet peut atteindre les fichiers. ## Étape 3 — Ajouter les instructions du projet Les instructions du projet encadrent chaque chat dans le projet. Elles composent avec les propres instructions de l'agent : le projet cadre le travail, l'agent cadre la réponse. Ouvre l'onglet **Instructions** et règle : `You are working on the Acme account. The contract and the call notes in the Knowledge tab are the source of truth; cite them when you make a claim. The customer's voice is conservative — drafts should not promise dates we have not confirmed.` Enregistre. Chaque nouveau chat du projet tournera désormais avec ce préambule en plus des propres instructions de l'agent. ## Étape 4 — Démarrer un chat et vérifier que le contexte suit Ouvre l'onglet **Threads** et clique **Nouveau chat**. Choisis un agent — l'Assistant par défaut suffit pour le premier run — et pose une question à laquelle un des fichiers du projet répond (`What does the contract say about the renewal clause?`). La réponse doit citer le contrat ; la citation ouvre le fichier depuis l'onglet Connaissances du projet, pas depuis la bibliothèque de l'organisation. Si l'agent répond sans citer, les fichiers du projet n'ont pas été récupérés — généralement parce que l'agent choisi n'a pas de tool de retrieval activé. Passe à un agent avec RAG actif, ou active-le sur l'Assistant pour l'usage projet. ## Où ça s'utilise Un projet avec fichiers, instructions et threads est la plus petite unité utile de contexte partagé dans Tale. La même forme passe à l'échelle — ajoute des membres pour qu'une équipe travaille le projet ensemble, ajoute un agent à périmètre projet pour verrouiller la voix, archive le projet quand le travail est livré. Pour le modèle plus profond de ce qu'est un projet et de quand on s'en sert, voir [Concepts de projet](/fr/platform/projects/concepts). Pour les agents à périmètre projet, voir [Agents de projet](/fr/platform/projects/project-agents). # Épisode 5 — Automatisations & validations Source: https://tale.dev/docs/fr/tutorials/videos/automations-and-approvals À la fin de cet épisode, tu auras vraiment utilisé une automatisation : tu lis le workflow de triage installé avant de lui faire confiance, tu crées une tâche et la regardes se faire noter et assigner à l'écran, tu suis cette exécution dans son journal, tu ouvres celle qui a échoué et tu la remontes jusqu'à son étape — puis tu valides l'envoi d'un e-mail client d'un clic, et tu retrouves la décision dans le journal d'audit quelques secondes plus tard. Étape par étape, à un rythme qu'on peut suivre. <Video src="/videos/fr/tutorials/ep5-automations/ep5-automations.fr.mp4" poster="/videos/fr/tutorials/ep5-automations/ep5-automations.fr.webp" captions="/videos/fr/tutorials/ep5-automations/ep5-automations.fr.vtt" lang="fr" title="Épisode 5 — Automatisations & validations" caption="Épisode 5 — Automatisations & validations (6:18, sous-titres disponibles)"> </Video> ## Ce que montre l'épisode | À | Scène | | ---- | ------------------------------------------------------ | | 0:27 | Le job : un tableau de tâches sans responsable | | 0:48 | Le catalogue, et ce qu'un panneau de lot te montre | | 1:45 | Lire le workflow : déclencheur, étape de score, schéma | | 2:44 | Le testeur — et la façon honnête de déclencher | | 3:03 | Une vraie tâche, créée et assignée à l'écran | | 3:57 | L'exécution rouge, remontée jusqu'à son étape | | 4:39 | La carte de validation : lire, ajuster, soumettre | | 5:31 | La décision dans le journal d'audit | ## Pour continuer [Les concepts d'automatisation](/fr/platform/automations/concepts) et le [catalogue](/fr/platform/automations/catalog) couvrent les lots ; [l'éditeur](/fr/platform/automations/editor), [les déclencheurs](/fr/platform/automations/triggers) et [les journaux d'exécution](/fr/platform/automations/execution-logs) approfondissent ce que tu as vu. Pour la carte elle-même, lis [les concepts de validation](/fr/platform/approvals/concepts) et [les validations dans les workflows](/fr/platform/automations/approvals-in-workflows) — puis construis-en une avec le tutoriel [un workflow avec validations](/fr/tutorials/editor/workflow-with-approvals). # Épisode 8 — Personnes, rôles & équipes Source: https://tale.dev/docs/fr/tutorials/videos/people-roles-and-teams L'épisode cinq a mis des portes aux machines ; celui-ci en met aux personnes. Il parcourt l'effectif de l'espace et l'échelle des quatre rôles, ouvre le dialogue d'ajout de membre juste assez longtemps pour l'apprendre, trace les frontières d'équipe qui décident qui lit quoi, et se termine sur les garde-fous ennuyeux qui comptent le plus : la double authentification et le SSO. <Video src="/videos/fr/tutorials/ep8-people/ep8-people.fr.mp4" poster="/videos/fr/tutorials/ep8-people/ep8-people.fr.webp" captions="/videos/fr/tutorials/ep8-people/ep8-people.fr.vtt" lang="fr" title="Épisode 8 — Personnes, rôles & équipes" caption="Épisode 8 — Personnes, rôles & équipes (2:06, sous-titres disponibles)"> </Video> ## Ce que montre l'épisode | À | Scène | | ---- | ------------------------------------------------------------------ | | 0:11 | L'effectif : cinq personnes, quatre rôles | | 0:24 | Ajouter quelqu'un — et l'échelle des rôles qui compte | | 0:45 | Les rôles sont un rayon d'action, pas un statut | | 0:59 | Les équipes : les murs de la plus petite bibliothèque | | 1:16 | L'hygiène d'identité : 2FA et SSO d'entreprise | | 1:30 | Un principe, deux côtés : l'accès se conçoit, il ne se présume pas | ## Pour continuer [Membres et rôles](/fr/platform/admin/members-and-roles) est la référence complète de l'échelle ; [les équipes](/fr/platform/admin/teams) couvrent les frontières vues ici. Pour l'identité : [la double authentification](/fr/platform/admin/two-factor-authentication) et [le SSO d'entreprise](/fr/platform/admin/enterprise-sso). # Épisode 7 — Connectors & le monde extérieur Source: https://tale.dev/docs/fr/tutorials/videos/connectors Ton espace de travail ne vit pas seul. Cet épisode parcourt les portes vers l'extérieur et la discipline logée dans chacune : un connecteur qu'on lit avant de l'ouvrir, la capacité qui s'allume quand une connector est reliée, des outils MCP qui arrivent avec leurs propres drapeaux de validation, et un réseau bac à sable qui répond non par défaut. <Video src="/videos/fr/tutorials/ep7-connectors/ep7-connectors.fr.mp4" poster="/videos/fr/tutorials/ep7-connectors/ep7-connectors.fr.webp" captions="/videos/fr/tutorials/ep7-connectors/ep7-connectors.fr.vtt" lang="fr" title="Épisode 7 — Connectors & le monde extérieur" caption="Épisode 7 — Connectors & le monde extérieur (2:18, sous-titres disponibles)"> </Video> ## Ce que montre l'épisode | À | Scène | | ---- | ------------------------------------------------------------------------------------------ | | 0:12 | Le catalogue : on connecte une fois, tout l'espace emprunte | | 0:28 | Lire la porte : opérations et hôtes autorisés, avant toute exécution | | 0:43 | Le gain : la recherche approfondie existe parce que Tavily est reliée | | 0:57 | MCP : vos propres outils, servis aux agents comme des natifs | | 1:11 | Les drapeaux de validation par outil — avoir l'air natif n'est pas être digne de confiance | | 1:26 | La dernière porte : code en bac à sable, sortie refusée par défaut | | 1:45 | Le motif à chaque porte | ## Pour continuer [L'aperçu des connectors](/fr/platform/connectors/overview) couvre la connexion et le partage ; [les serveurs MCP](/fr/platform/connectors/mcp-servers) le protocole et ses drapeaux. Pour la frontière réseau, lis la [politique d'exécution de code](/fr/platform/admin/governance/run-code-policy) — et pour ce qu'une connector reliée débloque, va voir les [concepts d'automatisation](/fr/platform/automations/concepts). # Tutoriels vidéo Source: https://tale.dev/docs/fr/tutorials/videos La série vidéo te montre la plateforme comme un collègue le ferait : à l'écran, zone par zone, avec les limites honnêtes dites à voix haute. Les épisodes sont courts — trois à quatre minutes — et chacun aborde au passage un morceau de culture IA : ce que veut dire l'ancrage, pourquoi les hallucinations arrivent, où l'humain garde sa place dans la boucle. Chaque page d'épisode porte la vidéo avec des sous-titres dans la langue de la page, une liste de chapitres et des liens vers les pages de référence. <CardGroup cols="1"> <Card title="Épisode 1 — Bienvenue dans Tale" icon="play" href="/fr/tutorials/videos/welcome-to-tale"> La visite guidée : poser une question ancrée, retrouver le fichier cité dans Connaissances, rencontrer l’agent qui a répondu et lire le journal d’une automatisation en marche. Trois minutes et demie. </Card> <Card title="Épisode 2 — Le chat, en profondeur" icon="play" href="/fr/tutorials/videos/chat-in-depth"> Une vraie session de travail : la même question sans puis avec ancrage, un contrôle de source, un verdict d'Arène motivé, et une synthèse construite puis raccourcie sur le canevas. Cinq minutes et demie. </Card> <Card title="Épisode 3 — Connaissances" icon="play" href="/fr/tutorials/videos/knowledge"> Travailler dans la bibliothèque : créer une entrée et l'entendre citée, comprendre « Indexé », consulter une fiche, lire la limite du crawler — et croiser le piège du savoir périmé en direct. Presque six minutes. </Card> <Card title="Épisode 4 — Ton premier agent" icon="play" href="/fr/tutorials/videos/your-first-agent"> Un agent construit de bout en bout à l'écran — instructions, connaissances, outils, modèle — puis testé en direct. La capacité, c'est de l'exposition : commence petit. Trois minutes. </Card> <Card title="Épisode 5 — Automatisations & validations" icon="play" href="/fr/tutorials/videos/automations-and-approvals"> Utilise une automatisation en vrai : lis le workflow de triage, déclenche une exécution avec une tâche créée à l'écran, examine celle qui a échoué, et valide toi-même l'envoi d'un mail. Six minutes. </Card> <Card title="Épisode 6 — Les projets avec l'IA" icon="play" href="/fr/tutorials/videos/projects-with-ai"> Le tableau en plein vol, les fichiers comme contexte borné, et une tâche créée à l'écran qu'un agent prend visiblement. L'initiative reste humaine. Deux minutes et demie. </Card> <Card title="Épisode 7 — Connectors & le monde extérieur" icon="play" href="/fr/tutorials/videos/connectors"> Des connecteurs qu'on lit avant d'ouvrir, des outils MCP avec drapeaux de validation, et une sortie réseau qui échoue fermée. Chaque porte ouverte délibérément. Deux minutes et demie. </Card> <Card title="Épisode 8 — Personnes, rôles & équipes" icon="play" href="/fr/tutorials/videos/people-roles-and-teams"> La moitié humaine de la confiance : l'échelle des rôles, les équipes comme murs de connaissances, et l'hygiène d'identité. L'accès se conçoit, il ne se présume pas. Deux minutes. </Card> <Card title="Épisode 9 — Gouvernance, coûts & confiance" icon="play" href="/fr/tutorials/videos/governance-and-trust"> Le final : fournisseurs et politique de modèles, garde-fous, journal d'audit, graphiques de coûts et de qualité, résidence — et les cinq habitudes d'un bon usage de l'IA. Trois minutes. </Card> <Card title="Bonus — Tale pour les développeurs" icon="play" href="/fr/tutorials/videos/tale-for-developers"> Le tour des bâtisseurs : clés bornées, quatre portes d'API, webhooks et harnesses qui échouent fermés. Deux minutes. </Card> </CardGroup> ## La suite de la série La série est désormais complète : la visite, sept plongées et un bonus développeur — chacun en français, en anglais et en allemand. La documentation autour de chaque épisode va plus loin ; commence là où commence ton rôle. # Épisode 1 — Bienvenue dans Tale Source: https://tale.dev/docs/fr/tutorials/videos/welcome-to-tale L'épisode d'ouverture parcourt l'espace de travail zone par zone, à un rythme qu'on peut suivre. Tu poses une vraie question, ancrée dans un document de l'entreprise, tu regardes la réponse nommer ses sources — puis tu boucles la boucle : retrouver ce fichier exact dans Connaissances, rencontrer l'Assistant qui a répondu, et lire le journal d'une automatisation qui tournait pendant tout ce temps. Chaque étape montre un artefact réel — rien n'est affirmé qui ne soit à l'écran. <Video src="/videos/fr/tutorials/ep1-welcome/ep1-welcome.fr.mp4" poster="/videos/fr/tutorials/ep1-welcome/ep1-welcome.fr.webp" captions="/videos/fr/tutorials/ep1-welcome/ep1-welcome.fr.vtt" lang="fr" title="Épisode 1 — Bienvenue dans Tale" caption="Épisode 1 — Bienvenue dans Tale (3:36, sous-titres disponibles)"> </Video> ## Ce que montre l'épisode | À | Scène | | ---- | --------------------------------------------------------------- | | 0:18 | Lire la barre latérale : chaque étape de la visite | | 0:35 | La première question — un document attaché comme contexte | | 1:08 | Pourquoi l'ancrage compte (et ce qu'est une hallucination) | | 1:25 | La boucle bouclée : le fichier cité, retrouvé | | 1:41 | L'Assistant — un agent, c'est une IA avec une fiche de poste | | 1:58 | Automatisations : le catalogue et un journal d'exécutions | | 2:35 | Projets : ton équipe et tes agents sur un même tableau | | 2:51 | Contrôle : fournisseurs, résidence des données, journal d'audit | ## Pour continuer Le [démarrage rapide](/fr/get-started/quickstart) reproduit le premier chat de l'épisode dans ton propre espace de travail en cinq minutes environ. Pour approfondir les concepts : [chat](/fr/platform/chat/overview), [connaissances](/fr/platform/knowledge/overview), [agents](/fr/platform/agents/concepts), [automatisations](/fr/platform/automations/concepts) et [validations](/fr/platform/approvals/concepts). # Épisode 2 — Le chat, en profondeur Source: https://tale.dev/docs/fr/tutorials/videos/chat-in-depth L'épisode 1 faisait le tour ; celui-ci s'installe dans la pièce où ton équipe va réellement travailler — et déroule une session complète. Le cœur est une expérience contrôlée : la même question d'onboarding posée deux fois — une fois sans contexte, une fois avec la revue support du T2 attachée. Tu regardes une réponse fluide et une réponse ancrée cesser d'être la même chose. Ensuite, la réponse ancrée est mise à l'épreuve (« quel document le dit ? »), un verdict d'Arène est rendu avec ses raisons — et une synthèse atterrit sur le canevas, puis tient en trois puces sur une seule phrase. <Video src="/videos/fr/tutorials/ep2-chat/ep2-chat.fr.mp4" poster="/videos/fr/tutorials/ep2-chat/ep2-chat.fr.webp" captions="/videos/fr/tutorials/ep2-chat/ep2-chat.fr.vtt" lang="fr" title="Épisode 2 — Le chat, en profondeur" caption="Épisode 2 — Le chat, en profondeur (5:33, sous-titres disponibles)"> </Video> ## Ce que montre l'épisode | À | Scène | | ---- | -------------------------------------------------------------- | | 0:27 | Les trois choix du composeur : agent, modèle, contexte | | 0:47 | L'expérience, première partie : demander sans rien attacher | | 1:04 | Le piège, lu ensemble — fluide, assuré, deviné | | 1:22 | Deuxième partie : la même question, ancrée dans un document | | 1:57 | Mettre la réponse à l'épreuve : « quel document le dit ? » | | 2:16 | Noter une réponse — où commencent les analyses de feedback | | 2:54 | Mode Arène : deux modèles, un prompt, un verdict motivé | | 3:47 | Le canevas : une synthèse atterrit en fichier, puis raccourcit | | 4:32 | La recherche approfondie, et où elle vit | ## Pour continuer [Les bases du chat](/fr/platform/chat/basics) couvrent en profondeur la zone de saisie, les trois outils de récupération et le déroulé de réflexion. Côté modèles : [les modèles](/fr/platform/models) et le [mode Arène](/fr/platform/chat/arena-mode) ; pour le travail qui finit sur un livrable, [Concepts d'agent](/fr/platform/agents/concepts) est l'endroit où le chat passe la main. # Épisode 9 — Gouvernance, coûts & confiance Source: https://tale.dev/docs/fr/tutorials/videos/governance-and-trust Le final s'adresse à ceux qui répondent de l'IA dans l'organisation. Il traverse la salle de contrôle de bout en bout — quels modèles tournent et pour qui, les garde-fous qui scrutent les deux sens, le journal d'audit où la validation de l'épisode cinq a réellement atterri, les graphiques de coûts et de qualité où ont fini les verdicts d'Arène de l'épisode deux, et le cadran des régions — puis referme la série sur ses cinq habitudes : ancrer, verrouiller, borner, journaliser, mesurer. <Video src="/videos/fr/tutorials/ep9-governance/ep9-governance.fr.mp4" poster="/videos/fr/tutorials/ep9-governance/ep9-governance.fr.webp" captions="/videos/fr/tutorials/ep9-governance/ep9-governance.fr.vtt" lang="fr" title="Épisode 9 — Gouvernance, coûts & confiance" caption="Épisode 9 — Gouvernance, coûts & confiance (2:48, sous-titres disponibles)"> </Video> ## Ce que montre l'épisode | À | Scène | | ---- | --------------------------------------------------------------------------- | | 0:15 | Les fournisseurs : une passerelle, vos clés, ou votre matériel | | 0:29 | La politique de modèles : qui peut utiliser quoi | | 0:44 | Les garde-fous : PII masquées, contenus bloqués, les deux sens | | 1:01 | Le journal d'audit — la validation de l'épisode cinq, au dossier | | 1:19 | Les analyses d'usage : des coûts avec des noms, des budgets qui préviennent | | 1:33 | Les analyses de feedback : la qualité mesurée, verdicts d'Arène compris | | 1:48 | La résidence des données : un réglage, pas une négociation | | 2:00 | Les cinq habitudes d'un bon usage de l'IA | ## Pour continuer [Les fournisseurs](/fr/platform/admin/providers) et [les modèles](/fr/platform/models) couvrent la machinerie ; [les modèles de contenu](/fr/platform/admin/governance/content-models) et [les politiques et limites](/fr/platform/admin/governance/policies-and-limits) la couche politique ; [les garde-fous](/fr/platform/admin/governance/guardrails), [les journaux d'audit](/fr/platform/admin/governance/audit-logs), [les analyses d'usage](/fr/platform/admin/governance/usage-analytics) et [les analyses de feedback](/fr/platform/admin/governance/feedback-analytics) les contrôles visités. Pour la résidence : [la résidence des données cloud](/fr/cloud/data-residency). # Épisode 4 — Ton premier agent Source: https://tale.dev/docs/fr/tutorials/videos/your-first-agent Le chat t'a appris à demander ; les connaissances, sur quoi reposent les réponses. Cet épisode construit ce qui met les deux au travail : un agent, créé de zéro à l'écran. Le fil rouge est la frontière de confiance — chaque outil accordé élargit ce que l'agent peut faire. Le plus petit agent qui fait le travail est le plus sûr. <Video src="/videos/fr/tutorials/ep4-agent/ep4-agent.fr.mp4" poster="/videos/fr/tutorials/ep4-agent/ep4-agent.fr.webp" captions="/videos/fr/tutorials/ep4-agent/ep4-agent.fr.vtt" lang="fr" title="Épisode 4 — Ton premier agent" caption="Épisode 4 — Ton premier agent (2:42, sous-titres disponibles)"> </Video> ## Ce que montre l'épisode | À | Scène | | ---- | ------------------------------------------------------------------------ | | 0:13 | La liste des agents — les intégrés, et où vivra le tien | | 0:24 | Créer : un nom technique, un nom d'affichage, continuer | | 0:41 | Les instructions — la fiche de poste, règle de passage de relais incluse | | 0:58 | Le périmètre de connaissances : la plus petite bibliothèque utile | | 1:11 | Les outils : la capacité, c'est de l'exposition — commence sans rien | | 1:30 | Le modèle et son secours | | 1:44 | Visible dans le chat, puis la première vraie question | | 2:06 | Améliore sans peur : l'historique garde chaque version | ## Pour continuer [Les concepts d'agent](/fr/platform/agents/concepts) donnent le modèle mental derrière les quatre décisions ; [créer un agent](/fr/platform/agents/create) le parcours de référence. Approfondis chaque réglage avec [les outils](/fr/platform/agents/tools), [les connaissances](/fr/platform/agents/knowledge) et [les versions](/fr/platform/agents/versions) — puis suis le tutoriel d'édition [du premier agent à la production](/fr/tutorials/editor/first-agent-end-to-end). # Épisode 3 — Connaissances Source: https://tale.dev/docs/fr/tutorials/videos/knowledge Les réponses ancrées de l'épisode 2 venaient toutes d'un seul endroit — dans cet épisode, tu y travailles. Tu ajoutes un vrai fait comme entrée de connaissances, tu apprends ce que « Indexé » veut vraiment dire (et pourquoi indexer n'est pas entraîner), tu consultes un prix dans une fiche typée, tu lis l'intervalle de scan du crawler, tu ouvres le réglage qui limite un document à une équipe — puis tu rencontres l'échec que tu croiseras vraiment : pas un fait manquant, un fait périmé. À la fin, un chat tout neuf cite l'entrée que tu as créée quelques minutes plus tôt. <Video src="/videos/fr/tutorials/ep3-knowledge/ep3-knowledge.fr.mp4" poster="/videos/fr/tutorials/ep3-knowledge/ep3-knowledge.fr.webp" captions="/videos/fr/tutorials/ep3-knowledge/ep3-knowledge.fr.vtt" lang="fr" title="Épisode 3 — Connaissances" caption="Épisode 3 — Connaissances (5:42, sous-titres disponibles)"> </Video> ## Ce que montre l'épisode | À | Scène | | ---- | --------------------------------------------------------------------------- | | 0:27 | La carte : documents, entrées, sites web, produits — une rangée d'onglets | | 0:52 | Entrée, document ou fiche — choisir la bonne forme | | 1:16 | Une entrée de connaissances créée en direct : sujet, contenu, enregistrer | | 1:42 | Ce que veut dire « Indexé » — récupération à la réponse, pas d'entraînement | | 2:09 | Une vraie consultation dans une fiche typée | | 2:34 | Le crawler : un domaine, un intervalle de scan, une limite honnête | | 3:06 | Qui lit quoi : un document assigné à une équipe | | 3:37 | Le piège du savoir périmé, posé en direct | | 4:30 | La preuve : un chat neuf cite l'entrée que tu viens de créer | ## Pour continuer [L'aperçu des connaissances](/fr/platform/knowledge/overview) cartographie toute la bibliothèque ; [les documents](/fr/platform/knowledge/documents) couvrent l'indexation, [les entrées de connaissances](/fr/platform/knowledge/knowledge-entries) les faits entretenus, [les données structurées](/fr/platform/knowledge/structured-data) les fiches typées et [le crawling](/fr/platform/knowledge/crawling) les sites web. Pour les périmètres, lis [les connaissances des agents](/fr/platform/agents/knowledge). # Épisode 6 — Les projets avec l'IA Source: https://tale.dev/docs/fr/tutorials/videos/projects-with-ai Le chat, c'est là où tu demandes ; les projets, là où vit le travail. Cet épisode parcourt le projet de refonte que l'équipe fait réellement tourner — puis crée une tâche à l'écran, le plus normalement du monde, pour te laisser regarder le triage la noter et un agent la prendre. Le backlog boucle la boucle : les agents proposent, les humains promeuvent. <Video src="/videos/fr/tutorials/ep6-projects/ep6-projects.fr.mp4" poster="/videos/fr/tutorials/ep6-projects/ep6-projects.fr.webp" captions="/videos/fr/tutorials/ep6-projects/ep6-projects.fr.vtt" lang="fr" title="Épisode 6 — Les projets avec l'IA" caption="Épisode 6 — Les projets avec l'IA (2:21, sous-titres disponibles)"> </Video> ## Ce que montre l'épisode | À | Scène | | ---- | -------------------------------------------------------------------------- | | 0:13 | Le tableau de la refonte, en plein vol — les avatars disent qui tient quoi | | 0:26 | Les fichiers du projet : l'étagère que les agents lisent d'abord | | 0:38 | Les discussions vivent à côté du travail | | 0:51 | Une tâche créée le plus normalement du monde | | 1:06 | L'agent la prend : notée, assignée, sa justification en commentaire | | 1:26 | Le backlog : les agents proposent, une personne promeut | | 1:41 | Chaque projet compose son équipage d'agents et de modèles | ## Pour continuer [Les concepts de projet](/fr/platform/projects/concepts) et [l'aperçu](/fr/platform/projects/overview) cartographient la surface ; [l'automatisation des tâches](/fr/platform/projects/task-automation) explique la boucle noter-assigner-rendre-compte que tu viens de voir, [le backlog](/fr/platform/projects/backlog) le flux de propositions, et [les agents de projet](/fr/platform/projects/project-agents) l'équipage par projet. # Bonus — Tale pour les développeurs Source: https://tale.dev/docs/fr/tutorials/videos/tale-for-developers Tout ce que la série a montré repose sur une API. L'épisode bonus parcourt la surface développeur : des clés API nommées et révocables ; REST, MCP, WebDAV et les runtimes bac à sable ; des webhooks qui déclenchent des agents depuis n'importe quel système ; les harnesses — Claude Code, Cursor — dans des conteneurs isolés ; et la politique d'exécution qui nomme ce qui peut s'installer et où le code peut se connecter. Des outils puissants, un rayon d'action contenu. <Video src="/videos/fr/tutorials/ep10-developers/ep10-developers.fr.mp4" poster="/videos/fr/tutorials/ep10-developers/ep10-developers.fr.webp" captions="/videos/fr/tutorials/ep10-developers/ep10-developers.fr.vtt" lang="fr" title="Bonus — Tale pour les développeurs" caption="Bonus — Tale pour les développeurs (2:04, sous-titres disponibles)"> </Video> ## Ce que montre l'épisode | À | Scène | | ---- | -------------------------------------------------------- | | 0:13 | Les clés API : nommées, bornées, révocables, auditées | | 0:27 | Quatre portes : REST, MCP, WebDAV, runtimes bac à sable | | 0:41 | Les webhooks : n'importe quel système déclenche un agent | | 0:58 | Les harnesses : Claude Code, Cursor | | 1:15 | La politique d'exécution : paquets, hôtes, échec fermé | | 1:31 | Des outils puissants, un rayon d'action contenu | ## Pour continuer [L'aperçu Develop](/fr/develop/overview) cartographie toute la surface ; [la référence API](/fr/develop/api-reference) et [les webhooks](/fr/develop/webhooks) portent les contrats. Pour les tours sur harness : [Harnesses](/fr/platform/agents/harnesses) et [la politique d'exécution de code](/fr/platform/admin/governance/run-code-policy). # Construire un agent avec du savoir Source: https://tale.dev/docs/fr/tutorials/editor/agent-with-knowledge Un agent avec du savoir est la forme vers laquelle tu te tournes quand le modèle doit répondre à partir de documents spécifiques — ton manuel produit, tes politiques, les notes d'appel du trimestre dernier — et non depuis ce qu'il a appris durant l'entraînement. L'agent récupère des chunks dans les sources liées au moment de la réponse et les cite. Ce parcours mène un agent neuf de « je veux qu'il connaisse mes docs » à « la réponse cite le bon document » sur une seule instance. Il te faut un rôle Éditeur, la capacité de charger des documents dans la base de connaissances, et environ trois documents à lier. Le côté conceptuel vit dans [Savoir de l'agent](/fr/platform/agents/knowledge) ; ce parcours est le mécanisme de bout en bout. ## Avant de commencer Confirme trois choses. Ton rôle est au moins Éditeur — l'édition d'agent est verrouillée à Éditeur et au-dessus. Tu as au moins trois documents prêts à charger (PDF, DOCX, Markdown — tout ce que la base de connaissances accepte). Tu as un fournisseur configuré pour que l'agent puisse tourner — sans cela, la réponse de test à la fin échoue sur l'appel au modèle. ## Étape 1 — Charger les documents dans la base de connaissances Le premier geste est de mettre les documents dans la base de connaissances de Tale. Des documents hors de la base ne se lient pas ; l'agent ne voit que des sources qu'il peut nommer. Ouvre **Savoir > Documents** et clique **Charger**. Glisse les trois documents, donne-leur des titres parlants, et attends que la colonne de statut affiche **Prêt** pour chacun. Le statut parcourt `chargé → en traitement → prêt` ; le traitement découpe le document en chunks et calcule les embeddings. Un PDF typique atteint **Prêt** en une ou deux minutes. Si un document reste sur `en traitement` plus de cinq minutes, ouvre sa ligne pour voir l'erreur — la cause la plus fréquente est un format non supporté (PDF en images, fichiers protégés par mot de passe) ou un fichier plus gros que la limite d'upload de l'organisation. ## Étape 2 — Créer l'agent Un document lié s'accroche à un agent, donc l'agent doit exister d'abord. Ouvre **Agents > Nouvel agent** et remplis les quatre boutons comme base : - **Nom** — `Docs Q&A` - **Instructions** — `You answer questions strictly from the bound documents. If you cannot find the answer in the documents, say so explicitly. Cite the document title for every claim.` - **Tools** — active **RAG** ; tout le reste désactivé - **Modèle** — celui que l'organisation utilise par défaut Enregistre et publie. L'agent existe désormais mais n'a aucun savoir — il refusera toute question, faute de source à trouver. ## Étape 3 — Lier les documents La liaison est la couture qui donne à l'agent un accès retrieval à un sous-ensemble de la base de connaissances. Ouvre l'onglet **Savoir** de l'agent et clique **Savoir de l'agent**. Choisis les trois documents de l'Étape 1 et enregistre. L'onglet Savoir liste maintenant trois sources liées. Le tool RAG de l'agent ne récupère que parmi ces trois ; rien d'autre dans la base de connaissances n'est atteignable depuis cet agent, pas même les autres documents de la même bibliothèque. ## Étape 4 — Poser une question et vérifier la citation Ouvre un chat avec `Docs Q&A` et pose une question à laquelle un des documents répond. La réponse arrive en streaming avec des citations en ligne — survoler montre le titre du document, cliquer ouvre le document au chunk cité. Pose une question qu'aucun des documents ne couvre ; l'agent doit refuser explicitement selon l'instruction, et non inventer une réponse. Si l'agent invente quand même une réponse, les instructions ne sont pas assez strictes — ajoute un cas de refus explicite (« If you cannot find the answer in the bound documents, respond with exactly: 'I could not find this in the bound documents.' ») et republie. ## Où ça s'utilise Les quatre gestes ci-dessus sont le build canonique de « l'agent qui répond depuis tes docs » : charger, créer l'agent avec RAG actif, lier, vérifier avec une citation. La même forme passe à l'échelle — lie dix documents au lieu de trois, ajoute un site web ou un dossier client, change de modèle. Ce sont les liaisons, pas le modèle, qui font que l'agent est le tien. Pour le côté conceptuel — comment le retrieval se compose avec les autres boutons de l'agent — voir [Concepts des agents](/fr/platform/agents/concepts). Pour l'histoire plus large de la base de connaissances — Contacts, Produits, Fournisseurs, Sites web — voir [Aperçu du savoir](/fr/platform/knowledge/overview). # Confier du travail à un worker Source: https://tale.dev/docs/fr/tutorials/editor/delegate-between-agents Quand une demande mérite son propre contexte ciblé — recherche citée, extraction en masse, longue rédaction — l'assistant lance un **worker** : un agent éphémère composé pour exactement cette tâche, avec exactement les capacités que l'assistant lui accorde depuis son propre ensemble. Il n'y a rien à configurer ; ce parcours fait tourner un job de recherche de bout en bout et te montre comment lire la carte de job. Le versant conceptuel (sous-ensembles de capacités, budgets, méthodologies) vit dans [Workers d'agent](/fr/platform/agents/delegation). ## Avant de commencer Il te faut un agent de chat (l'Assistant intégré fonctionne tel quel) sur un modèle avec tool-calling. Pour des sources web en direct, connecte une connector de recherche comme Tavily sous **Paramètres > Connectors** — sans elle, le worker retombe sur la simple récupération web et le dit dans son résultat. ## Étape 1 — Demande quelque chose qui mérite un worker Ouvre un chat avec `Assistant` et demande un travail ouvert et citable, par exemple : `Fais une recherche sur l'état des batteries à électrolyte solide — marché, acteurs clés, sources citées.` Une question factuelle rapide ne lance pas de worker (et ne le devrait pas) ; les workers sont pour les tâches qui profitent de l'isolation. ## Étape 2 — Observe la carte de job L'assistant appelle `spawn_agent` et une **carte de job** apparaît sous son tour : le nom du worker, un statut en direct et la checklist de progression du worker qui se remplit pendant qu'il planifie et traite les sous-questions. La carte ne bloque jamais le champ de saisie — tu peux continuer à écrire pendant que le worker tourne. Si la carte affiche une note « ignoré », l'assistant a demandé quelque chose hors de ses propres accès (par exemple une connector non connectée) ; l'exécution continue avec le reste, et la note te dit quoi connecter pour la prochaine fois. ## Étape 3 — Lis le résultat et la transcription Quand le job se termine, l'assistant replie le livrable du worker dans sa réponse — pour une recherche : une conclusion, des points clés avec citations en ligne et les sources. Sur la carte, déplie **l'activité du worker** pour voir la transcription complète : chaque recherche, chaque appel d'outil et le raisonnement du worker. Cette transcription est la piste d'audit à montrer quand on te demande ce que l'agent a réellement fait. ## Étape 4 — Quand quelque chose tourne mal Un worker à court de temps ou frappé par une erreur se termine avec un statut visible sur la carte — `temps écoulé` ou `échoué` — avec sa progression partielle intacte. L'assistant rapporte ce qu'il a obtenu et continue lui-même là où il peut. Rien n'échoue en silence : si le worker avait besoin d'une information que toi seul peux donner, l'assistant te la demande directement. ## Où cela s'inscrit Une demande, un worker, une carte : c'est la plus petite forme utile. La même mécanique passe à l'échelle avec plusieurs workers dans un tour — chacun a sa carte, sa progression et sa transcription. Pour des étapes fixes avec validations ou planification entre elles, prends plutôt une [automatisation](/fr/platform/automations/concepts). # Construire ton premier agent Source: https://tale.dev/docs/fr/tutorials/editor/first-agent-end-to-end Un premier agent est la plus petite chose utile dans Tale : des instructions plus un modèle, parfois avec un tool ou un document lié. Ce parcours tourne les quatre boutons dans l'ordre — instructions, savoir, tools, modèle — et te laisse avec un agent publié qui transforme une vraie tâche en un résultat à relire. La forme se généralise : chaque agent que tu construis plus tard est les mêmes quatre gestes avec d'autres choix. Il te faut un rôle Éditeur et un modèle marqué Chat configuré chez le fournisseur de l'organisation. Le côté conceptuel vit dans [Concepts des agents](/fr/platform/agents/concepts) ; ce parcours est le mécanisme de bout en bout. ## Avant de commencer Confirme trois choses. Ton rôle est au moins Éditeur — l'édition d'agent est verrouillée à Éditeur et au-dessus. L'organisation a un fournisseur configuré et au moins un modèle marqué Chat dessus ; sans cela, la réponse de test à la fin échoue sur l'appel au modèle. Tu as une question en tête à laquelle l'agent doit répondre — choisis quelque chose d'assez étroit pour qu'un paragraphe d'instructions puisse l'encadrer, comme « résume un message d'un contact entrant en une phrase plus une action suivante recommandée ». ## Étape 1 — Écrire les instructions Les instructions sont le system prompt — la prose qui encadre chaque réponse. Le premier bouton est celui que la plupart des gens forcent trop. Ouvre **Agents > Nouvel agent** et règle : - **Nom** — `Triage assistant` - **Instructions** — `You read a contact message and produce two lines. Line one: a one-sentence summary in plain English. Line two: a recommended next action — reply, escalate, or close. If the message is blank or off-topic, refuse and say so.` Enregistre comme brouillon pour l'instant ; la publication vient après les autres boutons. Des instructions courtes, tranchées et concrètes battent les longues — garde les règles sous un paragraphe. ## Étape 2 — Décider du savoir Le savoir est ce que l'agent peut référencer au moment de la réponse. Pour ce premier agent, laisse Savoir vide : le travail est de lire le message, pas de récupérer quoi que ce soit. L'onglet Savoir reste intact. Si tu voulais ajouter du savoir plus tard — disons une matrice d'escalade que l'agent doit consulter — tu chargerais le document, ouvrirais l'onglet **Savoir** de l'agent et le lierais. Le mécanisme complet vit dans [Agent avec savoir](/fr/tutorials/editor/agent-with-knowledge). ## Étape 3 — Choisir les tools Les tools sont ce que l'agent peut faire au-delà de répondre en texte. Pour le triage, aucun tool n'est nécessaire : l'agent lit l'entrée et écrit la sortie. Ouvre l'onglet **Tools** et laisse chaque interrupteur désactivé. Chaque tool que tu accordes élargit la frontière de confiance ; garde la liste courte. Si l'agent doit écrire l'action recommandée dans un CRM, tu activerais plus tard le tool de connector correspondant — mais pas avant que la version texte seul fonctionne. ## Étape 4 — Choisir le modèle et publier Ouvre l'onglet **Modèle** et choisis le défaut de l'organisation comme primaire ; règle un modèle plus petit en fallback pour que l'agent tourne encore quand le primaire est rate-limited. Enregistre, puis clique **Publier**. L'agent est désormais disponible pour chaque projet et chaque automatisation avec le bon rôle — le chat, lui, ne fait tourner que l'assistant intégré. Crée une tâche, colle un vrai message d'un contact dans sa description et assigne-la à `Triage assistant`. Le résultat de l'exécution doit atterrir en deux lignes selon les instructions — un résumé en une phrase et une action recommandée. Si le format dérive, resserre les instructions et republie ; c'est la boucle dans laquelle tu passes le plus de temps. ## Où ça s'utilise Quatre boutons, un agent publié, une réponse vérifiée : la même forme que suit chaque agent que tu construiras plus tard. Les parcours suivants se spécialisent sur un bouton chacun — [Agent avec savoir](/fr/tutorials/editor/agent-with-knowledge) sur le deuxième, [Confier du travail à un worker](/fr/tutorials/editor/delegate-between-agents) sur le troisième. Pour la page de concept qui nomme les quatre boutons et les arbitrages entre eux, voir [Concepts des agents](/fr/platform/agents/concepts). Pour la version et le rollback une fois que l'agent mûrit, voir [Versions d'agent](/fr/platform/agents/versions). # Construire un workflow avec approbation Source: https://tale.dev/docs/fr/tutorials/editor/workflow-with-approvals Un workflow avec une décision humaine au milieu est la forme vers laquelle tu te tournes quand le travail comporte un brouillon, une relecture et une action — et que tu veux une personne entre le brouillon et l'action. Le run se met en pause comme **En attente de saisie** jusqu'à ce que quelqu'un réponde ; l'étape suivante ne se déclenche qu'avec le feu vert. Ce parcours construit un workflow de résumé quotidien de cette façon, et tu croises en chemin les deux portes humaines : approuver la proposition de l'Éditeur IA, puis répondre au run en pause. Il te faut un rôle Éditeur et un agent qui produit un brouillon (le premier agent utile de [Construire ton premier agent](/fr/tutorials/editor/first-agent-end-to-end) suffit). Le côté conceptuel vit dans [Concepts d’automatisation](/fr/platform/automations/concepts) et [Concepts d'approbation](/fr/platform/approvals/concepts) ; ce parcours est le mécanisme de bout en bout. ## Avant de commencer Confirme trois choses. Ton rôle est au moins Éditeur — l'édition de workflow est verrouillée à Éditeur et au-dessus. Tu as un agent rédacteur de brouillon prêt ; sans lui, l'étape de brouillon n'a rien à invoquer. Et tu peux répondre à la relecture toi-même — le run en pause attend un humain, et dans ce parcours, cet humain, c'est toi. ## Étape 1 — Ouvrir un workflow dans l'éditeur Les workflows vivent dans l'automatisation qu'ils animent : ouvre l'automatisation et son onglet **Éditeur** est le workflow, avec le graphe d'étapes sur le canevas. Pour ce parcours, ouvre un workflow à toi ou un workflow du pack task-ops provisionné dans ton organisation — tout ce que tu as le droit de modifier convient, puisque c'est de toute façon l'Éditeur IA qui construit la nouvelle définition pour toi. ## Étape 2 — Décrire le workflow à l'Éditeur IA Active l'**Éditeur IA** dans la barre d'outils du canevas et décris toute la forme en un seul message : > Chaque jour ouvré à 8 h, fais résumer par l'agent <ton agent> les messages de contacts non lus d'hier en un paragraphe, puis fais relire le brouillon par un humain, et n'envoie au canal d'équipe que le texte approuvé. L'Éditeur IA répond par une carte de proposition — **Créer le workflow** avec le nombre d'étapes, ou **Mettre à jour le workflow** s'il retravaille celui que tu as ouvert. Tant que la carte est en attente, rien ne touche la définition : déplie-la, vérifie les étapes listées — une étape **LLM** pour le brouillon, la pause de relecture, l'envoi — et approuve-la. Le changement s'applique et se versionne comme n'importe quelle sauvegarde manuelle. ## Étape 3 — Attacher la planification Passe à l'onglet **Déclencheurs** et clique **Ajouter une planification**. Prends le préréglage **Tous les jours** et ajuste le cron aux jours ouvrés (`0 8 * * 1-5`) — ou décris l'horaire en langage courant et clique **Générer** pour laisser l'IA écrire le cron. **Variables du workflow** se préremplit depuis le schéma d'entrée du workflow ; laisse la proposition telle quelle. La ligne apparaît avec l'interrupteur **Actif** déjà activé. ## Étape 4 — Lancer et répondre à la relecture De retour dans l'éditeur, ouvre **Tester le workflow**, colle le JSON d'entrée proposé et clique **Exécuter**. Le panneau reflète le run étape par étape : l'étape de brouillon se déclenche, puis le run se met en pause — **En attente de saisie** — et la relecture arrive comme une carte-formulaire qui porte le brouillon. Remplis-la et clique **Soumettre la réponse** pour approuver, ou **Répondre différemment** pour renvoyer du texte libre ; le run reprend avec ta réponse et l'étape d'envoi se déclenche. Ouvre l'onglet **Exécutions** et déplie le run : le journal montre une entrée par étape — le brouillon produit par l'agent, qui a répondu à la relecture et quoi, et l'envoi avec sa sortie. Ce journal est la piste d'audit ; le même enregistrement naît à chaque futur run planifié. ## Où ça mène Rédiger, décider, agir — avec la décision entre les mains d'un humain — est le plus petit workflow-avec-approbation utile, et tu l'as construit sans poser une seule étape à la main : l'Éditeur IA a proposé, tu as approuvé, le run a demandé, tu as répondu. La même forme passe à l'échelle — ajoute une seconde relecture avant une étape destructrice, ou laisse [Approbations dans les workflows](/fr/platform/automations/approvals-in-workflows) te montrer les autres portes autour d'un workflow. Pour le vocabulaire derrière définition, déclencheur et exécution, [Concepts d’automatisation](/fr/platform/automations/concepts) est la page que ce parcours a supposée connue. # Installer le complément Outlook Source: https://tale.dev/docs/fr/tutorials/admin/office-add-in Le complément Outlook fait apparaître une sidebar Tale dans Outlook sur le web, sur poste de travail et sur mobile. Depuis la sidebar, un membre choisit un agent, glisse le fil de courriel ouvert comme contexte et récupère un brouillon de réponse sans changer d'application. Ce parcours s'adresse à un Admin qui déploie le complément à l'échelle de l'organisation ; il couvre le déploiement du manifeste, la connexion et la vérification. Il te faut le rôle Admin dans Tale, un tenant Microsoft 365 où tu peux gérer les Integrated Apps et une instance Tale joignable depuis le cloud Microsoft 365. Les organisations Cloud sont joignables par défaut ; les instances auto-hébergées ont besoin d'une URL HTTPS publique. ## Avant de commencer Confirme trois choses côté Microsoft : tu es Global Administrator (ou disposes du rôle Exchange Admin avec Integrated Apps), le déploiement centralisé est activé pour ton tenant, et la boîte aux lettres de test n'a pas bloqué les compléments via une mailbox policy. Côté Tale, ouvre **Paramètres > Connectors** et vérifie que **Microsoft 365** est listé — c'est là que le complément publie l'URL du manifeste. ## Étape 1 — Récupérer l'URL du manifeste depuis Tale Le complément parle à Tale via un manifeste XML hébergé par le centre d'administration Microsoft 365. Tale génère le manifeste par instance pour que la sidebar pointe sur ton URL et non sur un endpoint multi-tenant partagé. Ouvre **Paramètres > Connectors > Microsoft 365** et copie l'**URL du manifeste du complément** que le panneau affiche. Tu devrais voir une URL se terminant par `/connectors/office/manifest.xml`. Ouvre-la dans un nouvel onglet pour confirmer qu'elle renvoie du XML et pas une page d'erreur HTML — si elle échoue, ton instance n'est pas joignable depuis l'extérieur ou le connector est désactivée. ## Étape 2 — Déployer via le centre d'administration Microsoft 365 Le manifeste dit à Microsoft 365 quelles boîtes aux lettres voient la sidebar et depuis quelle URL la charger. Le déploiement centralisé est le chemin pris en charge ; le side-loading utilisateur par utilisateur fonctionne mais ne survit pas à une migration de boîte. Ouvre le centre d'administration Microsoft 365, navigue vers **Paramètres > Applications intégrées > Charger des applications personnalisées**, choisis **Complément Office** et **Fournir le lien vers le fichier manifeste**, et colle l'URL de l'étape 1. Choisis l'audience du déploiement — tout le tenant, un groupe de sécurité ou une liste précise d'utilisateurs. Soumets. Microsoft confirme le déploiement par une bannière verte ; le déploiement atteint typiquement les boîtes en une heure, parfois quelques heures sur un grand tenant. ## Étape 3 — Se connecter depuis la sidebar Ouvre Outlook avec un utilisateur de l'audience, clique sur un message quelconque et cherche l'icône Tale dans le ruban du message. Un clic ouvre la sidebar ; à la première ouverture elle demande à l'utilisateur de se connecter avec son compte Tale. La connexion passe par OAuth via l'instance Tale — même fournisseur d'identité que l'application web. Une fois connecté, la sidebar liste les agents disponibles pour cet utilisateur. En choisir un et cliquer **Rédiger une réponse** intègre le fil de courriel ouvert comme contexte et streame une réponse dans la sidebar. L'utilisateur révise, modifie et clique **Insérer** pour la déposer dans la fenêtre de rédaction Outlook. ## Où ça s'utilise Le complément est le chemin le plus léger vers « Tale là où tes membres travaillent déjà » — pas de changement de portail, pas de copier-coller. La sidebar est une fine enveloppe autour des mêmes agents que tu publies dans [Créer un agent](/fr/platform/agents/create) ; les changements d'instructions, de connaissances ou d'outils d'un agent atterrissent dans la sidebar à la requête suivante. Pour la grande histoire de connector — Slack, Gmail, serveurs MCP personnalisés — voir [Aperçu des connectors](/fr/platform/connectors/overview). Si tu exploites une instance auto-hébergée et que l'URL du manifeste n'est pas joignable depuis Microsoft 365, la page [Linux serveur](/fr/self-hosted/install/linux-server) couvre le prérequis HTTPS public. # Piper les transcriptions de réunions dans la Base de connaissances Source: https://tale.dev/docs/fr/tutorials/admin/meeting-transcription Une transcription de réunion est l'un des documents les plus précieux qu'un projet puisse garder — noms, décisions, suivis, le tout dans un endroit cherchable. Ce parcours intègre Meetily, un outil local de transcription de réunions, avec un projet Tale pour que chaque transcription que produit Meetily atterrisse dans la Base de connaissances du projet comme document à part entière. Le parcours s'adresse à un Admin sur une instance Tale auto-hébergée qui l'associe à un install Meetily sur le même réseau. Il te faut un rôle Admin dans Tale, un install Meetily joignable depuis le conteneur `tale-platform` et un projet dans Tale avec une Base de connaissances vers laquelle router les transcriptions. Le concept de Base de connaissances vit dans [Base de connaissances](/fr/platform/knowledge/overview) ; cette page est le parcours de connector, pas la page de concept. ## Avant de commencer Confirme quatre choses. Ton rôle est Admin ou Propriétaire dans Tale — le panneau **Connectors** est caché en dessous. Meetily tourne et produit des transcriptions dans un format que Tale accepte (Markdown, texte brut ou VTT). L'hôte Meetily est joignable depuis `tale-platform` par son chemin webhook ou son dossier partagé. Et le projet cible existe déjà dans Tale avec une Base de connaissances attachée — le connector écrit _dans_ une Base de connaissances, elle n'en crée pas. ## Étape 1 — Choisir un chemin de livraison Meetily peut remettre des transcriptions à Tale sous deux formes, et elles ont des propriétés opérationnelles différentes. Le choix verrouille la suite du parcours. Le chemin **webhook** fait que Meetily POSTe chaque transcription terminée à un endpoint d'ingestion Tale dès que la réunion finit ; la transcription est dans la Base de connaissances en quelques secondes après la fin de la réunion. Le chemin **dossier partagé** fait que Meetily écrit les transcriptions comme fichiers dans un répertoire que la plateforme Tale poll chaque minute ; la latence va jusqu'à une minute mais le chemin n'a besoin d'aucune URL publique et survit aux redémarrages de Meetily sans logique de retry. Choisis le webhook quand les deux services tournent dans le même réseau et que tu veux une indexation rapide ; choisis le dossier partagé quand Meetily tourne sur un poste qui s'éveille de manière irrégulière ou quand l'équipe d'exploitation préfère une trace d'audit basée fichier. ## Étape 2 — Créer l'endpoint d'ingestion ou le dossier dans Tale Tale doit savoir où les transcriptions atterriront et à quel projet elles appartiennent. Sans cette liaison, les transcriptions arrivent mais aucune Base de connaissances ne les réclame. Ouvre **Paramètres > Connectors**, clique **Ajouter une connector** et choisis **Transcriptions de réunions**. Choisis le projet dans la liste déroulante — la Base de connaissances que le projet utilise est la destination. Choisis le chemin de livraison que tu as choisi à l'étape 1. Si tu as choisi le webhook, Tale génère une URL de la forme `https://<ton-hôte>/connectors/transcripts/<token>` et la montre une fois. Copie l'URL ; elle sert aussi de credential bearer, donc traite-la comme un secret. Si tu as choisi le dossier partagé, Tale demande le chemin sur disque que `tale-platform` doit surveiller (typiquement `/data/transcripts/<project-slug>`). Crée le répertoire sur l'hôte, donne-lui une appartenance de groupe qui correspond à l'utilisateur du conteneur `tale-platform`, et confirme. ## Étape 3 — Pointer Meetily vers Tale Meetily doit maintenant savoir où livrer chaque transcription. Les réglages vivent dans la config propre à Meetily. Pour le chemin webhook, ouvre les paramètres de Meetily et ajoute une destination webhook avec l'URL de l'étape 2. Choisis le format de transcription — le Markdown est ce qui se lit le mieux dans un aperçu de document Tale, mais le VTT et le texte brut s'indexent correctement tous les deux. Pour le chemin dossier partagé, règle le répertoire de sortie de transcriptions de Meetily sur le chemin que tu as créé à l'étape 2. Assure-toi que Meetily écrit un fichier par réunion, nommé avec le titre de la réunion et l'horodatage. Termine une courte réunion de test dans Meetily et observe le panneau Connectors de Tale. La ligne de connector affiche un horodatage **Dernière livraison** qui se met à jour dans la minute (mode dossier) ou en quelques secondes (mode webhook). ## Étape 4 — Vérifier que le document atterrit et s'indexe La preuve que le câblage marche est une transcription visible dans la Base de connaissances comme document cherchable. Sans cette étape tu ne sais pas si Tale a reçu le fichier _et_ l'a indexé. Ouvre le projet cible, navigue vers sa Base de connaissances et cherche la nouvelle transcription en haut de la liste des documents. Clique dans l'aperçu — la transcription se rend comme document avec le titre de la réunion en nom de document et la date de la réunion en created-at. Attends que le badge d'indexation se libère (quelques secondes pour une courte transcription, jusqu'à une minute pour une longue), puis lance une recherche sur un nom ou une phrase dont tu te souviens de la réunion de test. La transcription devrait être le premier résultat avec la phrase surlignée. Si le document est là mais que le badge d'indexation reste orange, l'indexation est en retard — la page [Dépannage](/fr/self-hosted/operate/observability/troubleshooting) nomme les symptômes. ## Notes de confidentialité L'connector traverse un réseau dans chaque direction et la forme des données compte. - **Meetily → Tale.** Le corps de la transcription traverse, plus le titre de la réunion, l'horodatage et les étiquettes de locuteur que Meetily a attachées. L'audio ne traverse pas — Meetily transcrit localement et seul le texte est livré. Le chemin webhook utilise HTTPS avec le token bearer dans l'URL ; le chemin dossier utilise un chemin de système de fichiers sans réseau du tout. - **Tale → Meetily.** Rien. L'connector est à sens unique ; Tale ne rappelle jamais Meetily. - **Tale → services externes.** Le texte de la transcription traverse vers le fournisseur d'embedding qui est lié à la Base de connaissances. Si le fournisseur d'embedding est local (Ollama, LM Studio, vLLM via [Brancher un fournisseur LLM local](/fr/tutorials/admin/connect-local-provider)), aucun texte de transcription ne quitte l'hôte. Si le fournisseur d'embedding est OpenAI, Anthropic ou un autre endpoint hébergé, le texte de la transcription est envoyé à cet endpoint pour vectorisation selon la politique de traitement des données de ce fournisseur. Quand les transcriptions contiennent du contenu que l'organisation ne peut pas envoyer à un fournisseur cloud, le pattern pris en charge est de lier la Base de connaissances du projet à un modèle d'embedding local. La liaison du fournisseur se passe dans les paramètres de la Base de connaissances, pas dans cette connector. ## Où cela s'inscrit L'connector de transcription de réunions est l'exemple le plus net de « Tale indexe ce que tes autres outils produisent déjà » — pas de copier-coller, pas d'upload manuel, pas d'étape supplémentaire dans le flux de réunion. Les prochaines lectures naturelles sont [Base de connaissances](/fr/platform/knowledge/overview) pour à quoi la transcription indexée peut alors servir à l'intérieur d'un agent, et [Brancher un fournisseur LLM local](/fr/tutorials/admin/connect-local-provider) quand la section ci-dessus te pousse à garder l'étape d'embedding sur l'hôte. # Brancher un fournisseur LLM local Source: https://tale.dev/docs/fr/tutorials/admin/connect-local-provider Un fournisseur local, c'est la voie pour faire tourner des modèles dans ton propre périmètre — aucun appel API sortant, aucune facture au token, aucune transcription chez un tiers. Ce parcours mène une instance Tale auto-hébergée de « j'ai un point de terminaison Ollama, LM Studio ou vLLM » à « un chat de l'organisation appelle un modèle local et la réponse arrive en streaming ». Il s'adresse à un Administrateur sur une installation auto-hébergée ; les organisations Cloud n'atteignent pas ton réseau et sautent cette page. Il te faut le rôle Administrateur dans Tale, un serveur d'inférence local joignable depuis le conteneur `tale-platform` en TLS, et un modèle déjà chargé sur ce serveur. Le format du connecteur et le modèle d'identifiants sont documentés dans [Fournisseurs](/fr/self-hosted/configuration/providers) ; cette page déroule un chemin complet et en vérifie le résultat. ## Avant de commencer Vérifie quatre choses. Ton rôle est Administrateur ou Propriétaire — **Paramètres > Fournisseurs IA** est masqué en dessous. Ton serveur d'inférence local répond à `GET /v1/models` (ou l'équivalent Ollama `GET /api/tags`) depuis l'intérieur du réseau Docker de Tale. Au moins un modèle est chargé — côté Ollama tu as lancé `ollama pull llama3.1:8b` ou équivalent, côté LM Studio un modèle est chargé dans l'onglet serveur, côté vLLM le serveur est démarré avec `--model` pointé sur un checkpoint. Et le serveur est joignable en `https://` : l'URL de base d'un connecteur doit être une URL HTTPS, alors termine le TLS devant le serveur d'inférence — un reverse proxy avec un certificat interne est la réponse habituelle — plutôt que de l'exposer en clair. ## Étape 1 — Rendre le serveur d'inférence joignable depuis Tale Le premier geste consiste à confirmer que `tale-platform` joint le serveur d'inférence par son nom d'hôte en TLS. Sans cela, chaque appel de modèle remonte une erreur de connexion et aucun modèle n'est appelable. Quand le serveur d'inférence tourne derrière un proxy du même réseau Docker, le nom d'hôte joignable est le nom de service de ce proxy. Lance un curl unique depuis le conteneur `tale-platform` avant d'écrire la moindre configuration : ```bash docker compose exec platform curl -sf https://ollama.internal/api/tags ``` Une liste JSON des modèles chargés est le signal de succès. Une erreur de connexion signifie un mauvais nom d'hôte, un certificat non approuvé, ou un serveur d'inférence qui n'écoute pas sur l'interface que le conteneur atteint. ## Étape 2 — Déclarer le connecteur Les connecteurs livrés couvrent les fournisseurs publics ; une machine de ton propre réseau est un connecteur maison — un fichier YAML dans l'arbre de configuration de l'organisation. Le fichier dit à Tale où envoyer les requêtes, quel dialecte le point de terminaison parle et d'où vient sa liste de modèles. Écris `$TALE_CONFIG_DIR/<orgSlug>/providers/local-ollama.yml`. Le `name` doit correspondre à la racine du nom de fichier, et il ne doit entrer en collision avec aucun connecteur livré : ```yaml name: local-ollama displayName: Local Ollama apiFormat: openai baseUrl: https://ollama.internal/v1 catalog: source: models-endpoint auth: - method: api-key - method: env ``` `apiFormat: openai` convient à Ollama, LM Studio et vLLM — les trois exposent la forme OpenAI Chat Completions. `catalog.source: models-endpoint` dit à Tale de lister les modèles via `GET {baseUrl}/models` au lieu d'embarquer une liste statique, ce que tu veux quand les modèles chargés changent. Un fichier qui ne valide pas est ignoré et la raison est journalisée : lis le log de la plateforme si le connecteur n'apparaît pas. ## Étape 3 — Enregistrer l'identifiant Un connecteur seul n'appelle rien. Ce qui autorise une requête, c'est un identifiant enregistré sur ce connecteur, et un connecteur en porte autant que nécessaire. Ouvre **Paramètres > Fournisseurs IA**. Le nouveau connecteur s'affiche à côté des connecteurs livrés ; clique sur **Ajouter un identifiant** dessus. Choisis **Clé API** et colle le token qu'attend ton serveur — LM Studio ignore la valeur, vLLM veut le token passé à `--api-key`. Nomme l'identifiant d'après la machine qu'il atteint (`Machine GPU, baie 2`), et laisse la **Liste blanche de modèles** vide pour exposer tout ce que le serveur liste, ou choisis le sous-ensemble que l'organisation peut appeler. Le premier identifiant d'un connecteur en devient le défaut. Tu préfères que la clé vive sur le déploiement ? Choisis **Variable d'environnement** et nomme une variable de déploiement sous le préfixe réservé `TALE_PROVIDER_KEY_`. Le secret n'entre alors jamais dans le stockage de Tale, et ton équipe d'exploitation possède la rotation. ## Étape 4 — Vérifier avec un chat La preuve que le câblage tient, c'est une réponse de chat en streaming venue du serveur local. Sans cette étape, tu sais seulement que la configuration se parse. Ouvre un nouveau chat, ouvre le sélecteur de modèle et choisis l'un des modèles locaux par son nom — ne laisse pas le sélecteur sur **Auto**, qui pourrait router ce message vers un autre fournisseur ; cette étape exige que la réponse vienne de la machine que tu regardes. Envoie un prompt court (`Réponds par le seul mot "prêt"`). La réponse arrive en quelques secondes. Suis le log du serveur d'inférence sur l'hôte pendant l'envoi — Ollama journalise la ligne de requête, LM Studio imprime un résumé de requête, vLLM la latence de génération. Voir la requête arriver sur le serveur local, c'est la vérification que le trafic reste dans ton réseau au lieu de rebondir par une API externe. ## Dépannage - **Symptôme :** le connecteur n'apparaît jamais dans **Paramètres > Fournisseurs IA**. **Cause :** le YAML n'a pas validé, ou son `name` ne correspond pas à la racine du nom de fichier. **Correctif :** lis le log de la plateforme — un connecteur rejeté y est journalisé avec le fichier et la raison — puis corrige le fichier. - **Symptôme :** le connecteur apparaît mais sa liste de modèles reste vide. **Cause :** le serveur d'inférence est joignable mais n'a aucun modèle chargé, ou son point de terminaison `/models` a répondu une erreur. **Correctif :** charge un modèle, puis clique sur **Actualiser les catalogues** sur la page des fournisseurs. Les catalogues ne se mettent à jour que quand tu les actualises. - **Symptôme :** le fichier est rejeté parce que l'URL de base n'est pas en HTTPS, ou pointe sur `localhost`, `127.0.0.1` ou une IP privée. **Cause :** les URL de base de connecteur sont HTTPS uniquement, et la politique d'hôtes bloque le loopback et les adresses privées. **Correctif :** place un reverse proxy qui termine le TLS devant le serveur d'inférence et utilise son nom d'hôte interne. - **Symptôme :** la réponse du chat est une erreur qui nomme le modèle. **Cause :** l'identifiant du modèle ne correspond pas à celui de l'amont. **Correctif :** rechoisis dans le sélecteur de modèle — les tags Ollama comme `:latest` comptent en amont et doivent correspondre exactement. ## Où cela s'inscrit Un fournisseur local est la couture entre Tale et tes propres GPU — la même forme connecteur-et-identifiant qu'un fournisseur public, mais aucun trafic ne quitte ton réseau. Les lectures suivantes naturelles sont [Fournisseurs](/fr/self-hosted/configuration/providers) pour le format complet du connecteur et la voie par variable d'environnement, et [Durcissement](/fr/self-hosted/operate/security/hardening) pour les garanties de sortie qui empêchent un agent d'atteindre un modèle cloud que tu n'avais pas prévu. # Tutoriels Source: https://tale.dev/docs/fr/tutorials/overview Les tutoriels sont des parcours de bout en bout : chacun amène une instance neuve de « je veux faire X » à un résultat qui fonctionne et se vérifie. Ils supposent que tu as le bon rôle et un espace de travail qui tourne ; les pages de concept sous [Plateforme](/fr/platform) expliquent le modèle mental, les tutoriels montrent le mécanisme du début à la fin. Si tu n’as pas encore suivi un [parcours de démarrage](/fr/get-started/quickstart), commence là — les tutoriels s’appuient sur les gestes du premier jour que ces pages couvrent. ## Choisis par rôle <CardGroup cols="2"> <Card title="Série vidéo" icon="play" href="/fr/tutorials/videos"> Des visites produites de toute la plateforme — ancrage, agents, automatisations, gouvernance — trois minutes à la fois, en trois langues. </Card> <Card title="Tutoriels membre" icon="message-circle" href="/fr/tutorials/member/chat-effectively"> Chatter efficacement, travailler dans les projets, mener des conversations vocales. </Card> <Card title="Tutoriels éditeur" icon="bot" href="/fr/tutorials/editor/first-agent-end-to-end"> Construire un premier agent de bout en bout, lier des connaissances, déléguer entre agents, livrer des workflows avec approbations. </Card> <Card title="Tutoriels développeur" icon="terminal" href="/fr/tutorials/developer/call-tale-from-a-script"> Appeler Tale depuis un script, déclencher des workflows par webhook, construire des outils sur mesure, monter un serveur MCP. </Card> <Card title="Tutoriels admin" icon="shield" href="/fr/tutorials/admin/office-add-in"> Installer l’add-in Office, câbler la transcription de réunion, connecter un fournisseur local. </Card> </CardGroup> ## Où cela s’inscrit Les tutoriels citent les références de fonctionnalités sous [Plateforme](/fr/platform) pour l’échafaudage conceptuel ; une fois un tutoriel parcouru, la page qui mérite une relecture est la page de concept sous-jacente. Si tu ne sais pas lequel choisir, [Construire ton premier agent](/fr/tutorials/editor/first-agent-end-to-end) est ce qui se rapproche le plus d’un « hello world » pour le produit — la plupart des capacités que tu finiras par toucher y apparaissent. # Auftragsverarbeiter Source: https://tale.dev/docs/de/legal/subprocessors Ein Auftragsverarbeiter ist eine Drittpartei, die Tale beauftragt, personenbezogene Kundendaten in seinem Auftrag zu verarbeiten. Die Liste unten bezieht sich auf Tale Cloud; Self-hosted-Betreiber kontrollieren ihre eigene Infrastruktur, und die Auftragsverarbeiter-Liste solcher Deployments sind die Anbieter, die du wählst. Wesentliche Ergänzungen werden 30 Tage im Voraus angekündigt, und Org-Inhaber werden per E-Mail benachrichtigt. Lies das, wenn ein Auditor fragt, wer sonst noch deine Daten berührt. Komm zurück, wenn ein Beschaffungs-Review die aktuelle Anbieterliste und den Standort jedes einzelnen braucht. Diese Seite spiegelt **Anhang A** der [Auftragsverarbeitungsvereinbarung](https://tale.dev/de/legal/data-processing-agreement) — beide werden in derselben Änderung aktualisiert. Die Endpunkte und Datenflüsse der Tale-Plattform selbst sind in der öffentlichen [API-Dokumentation](https://demo.tale.dev/docs) beschrieben. ## Keine Nutzung von Kundendaten zum Modell-Training Tale nutzt Kundendaten — Prompts, Eingaben, Ausgaben, Embeddings, Audio, Bilder oder daraus abgeleitete Artefakte — nicht zum Training, Fine-Tuning oder zur Verbesserung von KI-Modellen. Jeder unten genannte KI-Auftragsverarbeiter ist über seine Enterprise- oder API-Bedingungen mit Tale vertraglich an dasselbe gebunden. Eine Abweichung ist nur durch eine gesonderte, beidseitig unterzeichnete Opt-in-Vereinbarung möglich; die fortgesetzte Nutzung der Leistungen, Einstellungs-Schalter im Produkt oder implizite Zustimmung gelten nicht. Die bindende Klausel steht in [Auftragsverarbeitungsvereinbarung § 5](https://tale.dev/de/legal/data-processing-agreement#5-ki-verarbeitung--keine-nutzung-zum-training-oder-zur-verbesserung). ## Aktuelle Auftragsverarbeiter Jeder Name verlinkt auf die öffentlich zugängliche AVV (oder gleichwertige Bedingungen) des jeweiligen Anbieters. Zertifizierungen und Trust-Seiten stehen im nächsten Abschnitt. Das Plattform-Hosting folgt der Datenresidenz-Wahl deiner Org: die erste Tabelle gilt für Orgs in der EU/im EWR, die zweite für Schweizer Orgs. KI-Aufrufe (LLM-Inferenz, Audio- und Bild-Verarbeitung) werden für alle Orgs in der EU/im EWR verarbeitet — kein eingesetzter KI-Auftragsverarbeiter betreibt eine Schweizer Region, und keiner dieser Aufrufe wird in Drittstaaten wie den USA verarbeitet. ### Orgs in der EU/im EWR | Auftragsverarbeiter (Firma) | Ladungsfähige Adresse | Art der Leistung | Ort der Verarbeitung | | ----------------------------------------------------- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | [Akenes SA (Exoscale)](https://www.exoscale.com/dpa/) | Boulevard de Grancy 19A, 1006 Lausanne, Schweiz | Bereitstellung der Cloud-Infrastruktur (Rechenzentrum): Hosting der Tale-Cloud-Plattform — VMs, Container-Runtime, Datenbank und Storage. | Deutschland (Region Frankfurt). | | [OpenRouter, Inc.](https://openrouter.ai/privacy) | 169 Madison Avenue, New York, NY 10016, USA | Bereitstellung der LLM-Inferenz (Chat, Vision, Embeddings), der Audio-Verarbeitung (Speech-to-Text und Text-to-Speech) sowie der Bild-Verarbeitung und -Generierung. | Europäische Union (In-Region-Routing über `eu.openrouter.ai`: Prompts und Antworten werden ausschließlich innerhalb der EU verarbeitet). | ### Schweizer Orgs | Auftragsverarbeiter (Firma) | Ladungsfähige Adresse | Art der Leistung | Ort der Verarbeitung | | ----------------------------------------------------- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- | | [Akenes SA (Exoscale)](https://www.exoscale.com/dpa/) | Boulevard de Grancy 19A, 1006 Lausanne, Schweiz | Bereitstellung der Cloud-Infrastruktur (Rechenzentrum): Hosting der Tale-Cloud-Plattform — VMs, Container-Runtime, Datenbank und Storage. | Schweiz (Zürich; Disaster-Recovery-Replikat in Genf). | | [OpenRouter, Inc.](https://openrouter.ai/privacy) | 169 Madison Avenue, New York, NY 10016, USA | Bereitstellung der LLM-Inferenz (Chat, Vision, Embeddings), der Audio-Verarbeitung (Speech-to-Text und Text-to-Speech) sowie der Bild-Verarbeitung und -Generierung. | Europäische Union (In-Region-Routing über `eu.openrouter.ai`). | Für Schweizer Orgs bleibt das Plattform-Hosting vollständig in der Schweiz. Der KI-Auftragsverarbeiter bietet keine Schweizer Region an; diese Aufrufe werden in der EU/im EWR verarbeitet — alle EU-/EWR-Staaten stehen auf der Staatenliste des Bundesrats nach Art. 16 FADP, die Übermittlung erfordert keine zusätzlichen Garantien. Zwei Hinweise zum KI-Auftragsverarbeiter (OpenRouter): er wird nur eingesetzt, wenn eine KI-Funktion einen Aufruf an ihn routet — eine Org, die weder LLM-Inferenz, Audio noch Bild-Funktionen nutzt, sendet ihm keine Daten. Modell-Anbieter, die über OpenRouter erreichbar sind (Anthropic, Google, Meta, Mistral, OpenAI usw.), sind Upstream-Anbieter von OpenRouter und keine direkten Auftragsverarbeiter von Tale — die Standard-Audio-Modelle (Whisper für Speech-to-Text, gpt-4o-mini-tts für Text-to-Speech) sind auf diesem Weg erreichte OpenAI-Modelle. Sie unterliegen den eigenen Vertragsbedingungen von OpenRouter; das In-Region-Routing beschränkt jeden Aufruf auf Anbieter-Endpunkte innerhalb der EU. ## Zertifizierungen und Trust-Seiten Jeder Auftragsverarbeiter führt eigene Sicherheitszertifizierungen und veröffentlicht sie auf seiner Trust-Seite: - **Exoscale (Akenes SA)** — ISO/IEC 27001:2022, ISO/IEC 27017, ISO/IEC 27018, SOC 2 Type II, PCI DSS v4.0, HDS, BSI C5, TISAX. Trust-Seite: [exoscale.com/compliance](https://www.exoscale.com/compliance/). - **OpenRouter, Inc.** — SOC 2; Nachweise über das zugangsbeschränkte Trust-Portal [trust.openrouter.ai](https://trust.openrouter.ai). Für Übermittlungen außerhalb der EU/des EWR gelten EU-Standardvertragsklauseln. ## Umfang der Verarbeitung Für jeden Auftragsverarbeiter: - **Exoscale (Akenes SA)** betreibt die Tale-Cloud-Middleware, den Anwendungs-State und die unterstützende Infrastruktur auf VMs und Container-Infrastruktur in der von deiner Org gewählten Region (Schweiz: Zürich mit Disaster-Recovery in Genf; EU: Frankfurt). Verschlüsselung at rest stellt Exoscales Storage-Schicht bereit. - **OpenRouter** verarbeitet Prompts und Antworten des jeweiligen LLM-Aufrufs (Chat, Vision, Embeddings), Audio-Payloads für Speech-to-Text und den Texteingang für Text-to-Speech sowie Bild-Prompts und generierte Bilder. Die Daten gehen über das In-Region-Routing von OpenRouter (`eu.openrouter.ai`) und werden auf Tales Seite nicht als separate Kopie gespeichert. ## Unter-Auftragsverarbeiter Jeder Auftragsverarbeiter oben beauftragt eigene Auftragsverarbeiter (Cloud-Hosting, CDN, Secret-Stores). Ihre Listen sind öffentlich und von der Trust-Seite jedes Anbieters verlinkt; Tale verfolgt wesentliche Änderungen an den Upstream-Listen über denselben 30-Tage-Hinweis-Mechanismus. ## Self-hosted: was sich ändert Wenn du Tale auf eigener Infrastruktur betreibst, sind die einzigen Daten, die Tale in deinem Auftrag verarbeitet, der Support- und Update-Verkehr, dem du zustimmst (Image-Pulls aus der Registry, optionale Telemetrie, Support-Tickets). Die Hosting- und Modell-Anbieter in der Tabelle oben werden von dir betrieben, nicht von Tale; die Auftragsverarbeiter-Liste deines Deployments ist der Stack, den du zusammenstellst. ## Wo das hingehört Auftragsverarbeiter sind das Anbieter-Inventar; die [Auftragsverarbeitungsvereinbarung](https://tale.dev/de/legal/data-processing-agreement) ist der Vertrag, unter dem sie operieren (Anhang A ist die kanonische Liste); die [Datenschutzerklärung](/de/legal/privacy) ist die nutzerseitige Erklärung; [Vertrauen und Compliance](/de/cloud/trust-and-compliance) ist der operative Beleg. Ein Auditor will die vier meist zusammen — die Anbieterliste, den Vertrag, die Erklärung und die Kontrollen — daher sind die verlinkten Seiten wechselseitig konsistent und werden in derselben Änderung aktualisiert. # Datenschutzerklärung Source: https://tale.dev/docs/de/legal/privacy Diese Erklärung beschreibt, wie Tale personenbezogene Daten verarbeitet, wenn du Tale Cloud, die Docs-Seite, die Marketing-Seite oder die Features im Produkt nutzt. Die Form ist dieselbe, ob du Endnutzer, Org-Admin oder Besucher der Docs bist — verschiedene Oberflächen erheben verschiedene Daten, und jede wird unten benannt. Die Erklärung gilt für Tale Cloud; selbst gehostete Instanzen werden von der Organisation betrieben, die sie betreibt, und Verantwortlicher ist diese Organisation, nicht Tale. Lies das, wenn du wissen willst, was Tale über dich speichert, warum, und wie du es entfernen kannst. Komm zurück, wenn sich die Erklärung ändert — wesentliche Änderungen werden auf der Status-Page angekündigt und an Org-Inhaber per E-Mail geschickt. ## Was wir erheben Drei Eimer an Daten existieren, jeder mit eigener Aufbewahrungsregel: - **Konto-Daten.** Name, E-Mail, Organisation, Rolle und die Credentials, mit denen du dich anmeldest. Nötig, um den Dienst zu betreiben. - **Produkt-Daten.** Alles, was du ins Produkt steckst — Agents, Workflows, Dokumente, Konversationen, Knowledge-Einträge, Connector-Credentials. Gespeichert, solange die Parent-Org existiert; gelöscht beim Org-Löschen oder über den Datenauskunfts-Workflow. - **Betriebs-Daten.** Server-Logs, Audit-Pfade, Support-Ticket-Inhalte, Performance-Metriken. An dein Konto oder deine Org gebunden, solange die Daten für Sicherheit, Debugging und Compliance nützlich sind — typisch bis zu 90 Tage für Logs und unbefristet für Audit-Pfade. Wir verkaufen keine personenbezogenen Daten. Wir nutzen Produkt-Daten nicht, um Modelle zu trainieren — deine Konversationen und Dokumente sind in keinem Modell-Trainingssatz, weder unserem noch dem eines Anbieters, ausser wo du ein Feature ausdrücklich aktiviert hast, das das verlangt, und der Einwilligungs-Prompt bestätigt wurde. ## Warum wir es erheben Die rechtliche Grundlage für jeden Eimer ist eine von: - **Vertragsnotwendigkeit.** Konto-Daten und die Produkt-Daten, die du anlegst, existieren, weil du uns gebeten hast, den Dienst bereitzustellen. Wir können die Plattform ohne sie nicht betreiben. - **Berechtigtes Interesse.** Betriebs-Daten werden erhoben, um die Plattform sicher zu halten, Ausfälle zu debuggen und vertragliche SLAs zu erfüllen. - **Einwilligung.** Marketing-Kommunikation, Analytik auf der Marketing-Seite und jedes Feature, das Daten über den Vertrag hinaus verarbeitet, sind einwilligungsbasiert — opt-in, widerrufbar und protokolliert. Die Aufschlüsselung der Rechtsgrundlage pro Datenkategorie steht im Auftragsverarbeitungs-Vertrag, der Enterprise-Kunden auf Anfrage zur Verfügung steht. ## Wie lange wir es aufbewahren | Daten | Aufbewahrung | | --------------------- | ------------------------------------------------------------------------------------ | | Konto-Daten | Lebensdauer der Org plus 30 Tage nach Löschung | | Produkt-Daten | Lebensdauer der Org; sofortige Löschung bei Org-Löschen | | Dokumente und Uploads | Lebensdauer des Parent-Datensatzes; soft-gelöschte Datensätze nach 30 Tagen gepurged | | Server-Logs | 90 Tage | | Audit-Logs | Org-konfigurierbarer Boden; Standard 365 Tage, keine Obergrenze | | Backups | 30 Tage, verschlüsselt at rest | Löschungen folgen dem dokumentierten Datenauskunfts-Workflow im Produkt — siehe die In-Product-Governance-Seite für die Betreiber-Oberfläche. ## Auftragsverarbeiter Tale Cloud nutzt eine kleine Anzahl Dritter, um den Dienst zu liefern. Jeder ist auf der [Auftragsverarbeiter-Seite](/de/legal/subprocessors) benannt, lokalisiert und im Umfang beschrieben. Wesentliche Änderungen an der Auftragsverarbeiter-Liste werden 30 Tage vor Wirksamwerden angekündigt; Org-Inhaber können über den Support widersprechen und den Vertrag kündigen, wenn der neue Auftragsverarbeiter nicht akzeptabel ist. ## Deine Rechte Du hast die Rechte aus der DSGVO (und die entsprechenden FADP-Rechte für Schweizer Betroffene): Auskunft, Berichtigung, Löschung, Einschränkung, Datenübertragbarkeit und Widerspruch. Die Mechanik: - **Auskunft und Übertragbarkeit.** Exportier deine Daten aus dem Produkt oder über die API; Roh-Exporte org-bezogener Daten sind auf Anfrage verfügbar. - **Berichtigung.** Bearbeite Konto-Daten und Produkt-Daten im Produkt. Für Daten, die du nicht erreichst (Server-Logs, Audit-Einträge mit deiner User-ID), reich eine Anfrage über den Support ein. - **Löschung.** Nutz den Datenauskunfts-Workflow unter **Einstellungen > Governance > Datenauskunfts-Anfragen**. Die Löschung erreicht jeden Dienst, der die Daten hält, einschliesslich Backups via Schlüsselzerstörung. - **Einschränkung und Widerspruch.** Reich über den Support ein; Tale bestätigt innerhalb von fünf Werktagen. Kontakt: `privacy@tale.dev`. Für Beschwerden ist die Aufsichtsbehörde die Datenschutzbehörde des Landes, in dem du wohnst. ## Wo das hingehört Datenschutz ist der Datenverarbeitungs-Vertrag; [Vertrauen und Compliance](/de/cloud/trust-and-compliance) ist der operative Beleg dahinter. Wenn du wissen willst, welche Dritten deine Daten berühren, ist [Auftragsverarbeiter](/de/legal/subprocessors) die Liste; wenn du selbst hostest, verlassen die Daten deine Infrastruktur nicht, und diese Erklärung gilt nur für deine Nutzung der eigenen Oberflächen von Tale (der Docs- und Marketing-Seiten). # Sous-traitants ultérieurs Source: https://tale.dev/docs/fr/legal/subprocessors Un sous-traitant ultérieur est un tiers que Tale engage pour traiter les données personnelles des clients pour son compte. La liste ci-dessous couvre Tale Cloud ; les opérateurs auto-hébergés contrôlent leur propre infrastructure et la liste de sous-traitants pour ces déploiements est celle des fournisseurs que tu choisis. Les ajouts substantiels sont annoncés 30 jours à l’avance et les Propriétaires d’org sont avertis par courriel. Lis ceci quand un auditeur demande qui d’autre touche tes données. Reviens-y quand une revue d’achats a besoin de la liste actuelle de fournisseurs et de la localisation de chacun. Cette page reprend l’**Annexe A** de l’[Accord de traitement des données](https://tale.dev/fr/legal/data-processing-agreement) — les deux sont mis à jour dans le même changement. Les endpoints et flux de données de la plateforme Tale elle-même sont décrits dans la [documentation API](https://demo.tale.dev/docs) publique. ## Aucune utilisation des données du client pour l’entraînement de modèles Tale n’utilise pas les données du client — prompts, entrées, sorties, embeddings, audio, images ou artefacts dérivés — pour entraîner, ajuster ou améliorer un modèle d’IA. Chaque sous-traitant ultérieur d’IA listé ci-dessous est contractuellement tenu, via ses conditions Enterprise ou API avec Tale, à la même chose. Une dérogation n’est possible que par un accord opt-in écrit séparé signé par les deux parties ; l’usage continu des services, des interrupteurs dans le produit ou un consentement implicite ne suffisent pas. La clause contraignante figure à l’[Accord de traitement des données § 5](https://tale.dev/fr/legal/data-processing-agreement#5-traitement-par-ia--aucune-utilisation-pour-lentrainement-ou-lamelioration). ## Sous-traitants ultérieurs actuels Chaque nom renvoie au DPA public du fournisseur (ou aux conditions équivalentes). Les certifications et pages de confiance figurent dans la section suivante. L’hébergement de la plateforme suit la résidence de données choisie par ton org : le premier tableau s’applique aux orgs de l’UE/EEE, le second aux orgs suisses. Les appels IA (inférence LLM, traitement audio et traitement d’images) sont traités dans l’UE/EEE pour toutes les orgs — aucun sous-traitant ultérieur d’IA engagé par Tale n’opère de région suisse, et aucun de ces appels n’est traité dans des pays tiers comme les États-Unis. ### Orgs de l’UE/EEE | Sous-traitant ultérieur (entité juridique) | Adresse du siège | Nature de la prestation | Lieu du traitement | | ----------------------------------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | | [Akenes SA (Exoscale)](https://www.exoscale.com/dpa/) | Boulevard de Grancy 19A, 1006 Lausanne, Suisse | Infrastructure cloud (centre de données) : hébergement de la plateforme Tale Cloud — VM, runtime conteneurs, base de données et stockage. | Allemagne (région de Francfort). | | [OpenRouter, Inc.](https://openrouter.ai/privacy) | 169 Madison Avenue, New York, NY 10016, États-Unis | Inférence LLM (chat, vision, embeddings), traitement audio (Speech-to-Text et Text-to-Speech) ainsi que traitement et génération d’images. | Union européenne (routage in-region via `eu.openrouter.ai` : prompts et réponses traités exclusivement dans l’UE). | ### Orgs suisses | Sous-traitant ultérieur (entité juridique) | Adresse du siège | Nature de la prestation | Lieu du traitement | | ----------------------------------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------- | | [Akenes SA (Exoscale)](https://www.exoscale.com/dpa/) | Boulevard de Grancy 19A, 1006 Lausanne, Suisse | Infrastructure cloud (centre de données) : hébergement de la plateforme Tale Cloud — VM, runtime conteneurs, base de données et stockage. | Suisse (Zurich ; réplique de reprise après sinistre à Genève). | | [OpenRouter, Inc.](https://openrouter.ai/privacy) | 169 Madison Avenue, New York, NY 10016, États-Unis | Inférence LLM (chat, vision, embeddings), traitement audio (Speech-to-Text et Text-to-Speech) ainsi que traitement et génération d’images. | Union européenne (routage in-region via `eu.openrouter.ai`). | Pour les orgs suisses, l’hébergement de la plateforme reste intégralement en Suisse. Le sous-traitant ultérieur d’IA n’offre pas de région suisse ; ces appels sont traités dans l’UE/EEE — tous les pays de l’UE/EEE figurent sur la liste d’adéquation du Conseil fédéral au sens de l’art. 16 LPD, le transfert n’exige donc aucune garantie supplémentaire. Deux remarques sur le sous-traitant ultérieur d’IA (OpenRouter) : il n’est engagé que lorsqu’une fonctionnalité d’IA route un appel vers lui — une org qui n’utilise ni l’inférence LLM, ni l’audio, ni les fonctionnalités d’images ne lui envoie aucune donnée. Les fournisseurs de modèles accessibles via OpenRouter (Anthropic, Google, Meta, Mistral, OpenAI, etc.) sont des fournisseurs amont d’OpenRouter, pas des sous-traitants ultérieurs directs de Tale — les modèles audio par défaut (Whisper pour le Speech-to-Text, gpt-4o-mini-tts pour le Text-to-Speech) sont des modèles OpenAI atteints de cette façon. Ils opèrent sous les conditions contractuelles propres à OpenRouter ; le routage in-region limite chaque appel aux endpoints de fournisseurs situés dans l’UE. ## Certifications et pages de confiance Chaque sous-traitant ultérieur détient ses propres certifications de sécurité et les publie sur sa page de confiance : - **Exoscale (Akenes SA)** — ISO/IEC 27001:2022, ISO/IEC 27017, ISO/IEC 27018, SOC 2 Type II, PCI DSS v4.0, HDS, BSI C5, TISAX. Page de confiance : [exoscale.com/compliance](https://www.exoscale.com/compliance/). - **OpenRouter, Inc.** — SOC 2 ; preuves disponibles via le portail de confiance à accès restreint [trust.openrouter.ai](https://trust.openrouter.ai). Les clauses contractuelles types de l’UE s’appliquent aux transferts hors UE/EEE. ## Périmètre du traitement Pour chaque sous-traitant ultérieur : - **Exoscale (Akenes SA)** exécute la middleware Tale Cloud, l’état applicatif et l’infrastructure de support sur des VM et une infrastructure conteneurs dans la région choisie par ton org (Suisse : Zurich avec reprise après sinistre à Genève ; UE : Francfort). Le chiffrement au repos est fourni par la couche de stockage d’Exoscale. - **OpenRouter** traite les prompts et réponses de l’appel LLM concerné (chat, vision, embeddings), les payloads audio pour le Speech-to-Text et l’entrée texte pour le Text-to-Speech, ainsi que les prompts d’images et les images générées. Les données partent via le routage in-region d’OpenRouter (`eu.openrouter.ai`) et ne sont pas conservées côté Tale comme copie séparée. ## Sous-sous-traitants Chaque sous-traitant ultérieur ci-dessus engage ses propres sous-traitants (hébergement cloud, CDN, magasins de secrets). Leurs listes sont publiques et liées depuis la page de confiance de chaque fournisseur ; Tale suit les changements substantiels aux listes amont via le même mécanisme de préavis de 30 jours. ## Auto-hébergé : ce qui change Si tu fais tourner Tale sur ta propre infrastructure, les seules données que Tale traite pour ton compte sont le trafic de support et de mise à jour auquel tu consens (tirages d’images depuis le registre, télémétrie optionnelle, tickets de support). Les fournisseurs d’hébergement et de modèles dans le tableau ci-dessus sont opérés par toi, pas par Tale ; la liste de sous-traitants de ton déploiement est la stack que tu assembles. ## Où cela s’inscrit Les sous-traitants ultérieurs sont l’inventaire des fournisseurs ; l’[Accord de traitement des données](https://tale.dev/fr/legal/data-processing-agreement) est le contrat sous lequel ils opèrent (l’Annexe A est la liste de référence) ; la [Politique de confidentialité](/fr/legal/privacy) est la politique côté utilisateur ; [Confiance et conformité](/fr/cloud/trust-and-compliance) est la preuve opérationnelle. Un auditeur veut généralement les quatre ensemble — la liste de fournisseurs, le contrat, la politique et les contrôles — donc les pages liées sont mutuellement cohérentes et mises à jour dans le même changement. # Politique de confidentialité Source: https://tale.dev/docs/fr/legal/privacy Cette politique décrit comment Tale traite les données personnelles quand tu utilises Tale Cloud, le site de docs, le site marketing ou les fonctionnalités dans le produit. La forme est la même que tu sois utilisateur final, admin d'org ou visiteur lisant les docs — des surfaces différentes collectent des données différentes, et chacune est nommée plus bas. La politique s'applique à Tale Cloud ; les instances auto-hébergées sont opérées par l'organisation qui les fait tourner, et le responsable de traitement est cette organisation, pas Tale. Lis ceci quand tu veux savoir ce que Tale conserve à ton sujet, pourquoi, et comment l'enlever. Reviens-y quand la politique change — les changements substantiels sont annoncés sur la page de statut et envoyés par courriel aux Propriétaires d'org. ## Ce que nous collectons Trois seaux de données existent, chacun avec sa propre règle de conservation : - **Données de compte.** Nom, courriel, organisation, rôle et identifiants avec lesquels tu te connectes. Nécessaires pour opérer le service. - **Données produit.** Tout ce que tu mets dans le produit — agents, workflows, documents, conversations, entrées de base de connaissances, identifiants de connector. Stockées tant que l'org parente existe ; supprimées à la suppression de l'org ou via le flux de demande de la personne concernée. - **Données opérationnelles.** Journaux serveur, pistes d'audit, contenu des tickets de support, métriques de performance. Liées à ton compte ou à ton org tant que la donnée sert à la sécurité, au débogage et à la conformité — typiquement jusqu'à 90 jours pour les journaux et indéfiniment pour les pistes d'audit. Nous ne vendons pas de données personnelles. Nous n'utilisons pas les données produit pour entraîner des modèles — tes conversations et tes documents ne font partie d'aucun jeu d'entraînement de modèle, ni le nôtre ni celui d'aucun fournisseur, sauf quand tu as explicitement activé une fonctionnalité qui le requiert et confirmé l'invite de consentement. ## Pourquoi nous le collectons La base légale de chaque seau est l'une de : - **Nécessité contractuelle.** Les données de compte et les données produit que tu crées existent parce que tu nous as demandé de fournir le service. Nous ne pouvons pas opérer la plateforme sans elles. - **Intérêt légitime.** Les données opérationnelles sont collectées pour garder la plateforme sûre, déboguer les pannes et respecter les SLA contractuels. - **Consentement.** Les communications marketing, l'analytique sur le site marketing et toute fonctionnalité qui traite des données au-delà du contrat sont fondées sur le consentement — opt-in, révocable et tracé. La ventilation de la base légale par catégorie de donnée vit dans l'Accord de Traitement de Données disponible aux clients entreprise sur demande. ## Combien de temps nous le gardons | Donnée | Conservation | | --------------------------- | ------------------------------------------------------------------------------- | | Données de compte | Vie de l'org plus 30 jours après suppression | | Données produit | Vie de l'org ; effacement immédiat à la suppression de l'org | | Documents et téléversements | Vie de l'enregistrement parent ; enregistrements soft-deleted purgés à 30 jours | | Journaux serveur | 90 jours | | Journaux d'audit | Plancher configurable par l'org ; défaut 365 jours, pas de plafond | | Sauvegardes | 30 jours, chiffrées au repos | L'effacement suit le flux de demande de la personne concernée documenté dans le produit — voir la page gouvernance dans le produit pour la surface opérateur. ## Sous-traitants ultérieurs Tale Cloud utilise un petit nombre de tiers pour livrer le service. Chacun est nommé, localisé et périmétré sur la page [Sous-traitants ultérieurs](/fr/legal/subprocessors). Les changements substantiels à la liste des sous-traitants sont annoncés 30 jours avant prise d'effet ; les Propriétaires d'org peuvent s'opposer via le support et faire résilier le contrat si le nouveau sous-traitant n'est pas acceptable. ## Tes droits Tu as les droits accordés par le RGPD (et les droits FADP équivalents pour les personnes concernées suisses) : accès, rectification, effacement, restriction, portabilité et opposition. La mécanique : - **Accès et portabilité.** Exporte tes données depuis le produit ou via l'API ; les exports bruts des données au périmètre org sont disponibles sur demande. - **Rectification.** Édite les données de compte et les données produit depuis le produit. Pour les données que tu n'atteins pas (journaux serveur, entrées d'audit avec ton ID utilisateur), soumets une demande via le support. - **Effacement.** Utilise le flux de demande de la personne concernée sous **Paramètres > Gouvernance > Demandes des personnes concernées**. L'effacement traverse chaque service qui détient la donnée, y compris les sauvegardes via destruction de clé. - **Restriction et opposition.** Soumets via le support ; Tale accuse réception sous cinq jours ouvrés. Contact : `privacy@tale.dev`. Pour les plaintes, l'autorité de contrôle est l'autorité de protection des données du pays où tu résides. ## Où cela s'inscrit La confidentialité est le contrat de traitement des données ; [Confiance et conformité](/fr/cloud/trust-and-compliance) est la preuve opérationnelle qui en découle. Si tu veux savoir quels tiers touchent tes données, [Sous-traitants ultérieurs](/fr/legal/subprocessors) est la liste ; si tu opères en auto-hébergé, la donnée ne quitte pas ton infrastructure, et cette politique ne s'applique qu'à ton usage des surfaces propres à Tale (les sites de docs et marketing).