diff --git a/.cspell.json b/.cspell.json index 31f2158..066fcfb 100644 --- a/.cspell.json +++ b/.cspell.json @@ -43,6 +43,7 @@ "Hubspot", "hypervisor", "Intercom", + "journalctl", "Kimi", "Linear", "MDX", @@ -82,6 +83,11 @@ "Supabase", "timecode", "uvx", - "webhook" + "uuidgen", + "webhook", + "healthz", + "OpenRouter", + "versionable", + "xhigh" ] } diff --git a/AGENTS.md b/AGENTS.md index 9a0f3b9..13d7b61 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,10 +13,12 @@ The navigation keeps Home first and sorts the top-level sections alphabetically. Agents follows the user journey. Other sections keep their existing order: - **Administration** - `/admin-panel`. Browser-admin access, dashboards, governance records, runtime controls, and network policy. -- **Agents (Beta)** - `/developers/*`. Start with a familiar task, then improvement and scheduling. Keep Examples, More about Agents (`/developers/guides/*`), and For developers (`/developers/api-ref/*`) collapsed by default. Introduce features when they help the reader's current task. Keep prompts natural and explain terms before using them. +- **Agents (Beta)** - `/developers/*`. Start with a familiar task, then improvement and scheduling. Keep Examples and More about Agents (`/developers/guides/*`) collapsed by default. Introduce features when they help the reader's current task. Keep prompts natural and explain terms before using them. - **App setup** - `/integrations/{github, gmail, google-calendar, slack}`. Per-app permissions and prompts, not feature pages. All of them connect through the Apps tab of the Add MCP dialog. - **Deployment models** - `/deployment-models`. Current availability and operating boundaries for Fluso Cloud, dedicated AWS VPC, planned Azure VNet, and scoped on-premises deployments. - **Features** - `/features/*`. Approvals and permissions, Apps and MCP servers, Chat, Confidential mode, Imports, Memory, Projects, Skills, and Tasks. +- **Fluso API** - `/api/*`. Start with access and a first request. Keep Cloud and daemon credentials and administration separate. Document shared workflows once under Use the API. Lead with a useful task, runnable requests, and the expected result. Reuse the deployment's example helpers. Put protocol details and recovery rules beside the step that needs them. Each deployment's `/docs` and `/v1/openapi.json` own exact request and response schemas. Keep endpoint tables collapsed after the workflow. Preserve old API URLs with redirects. +- **Fluso Local** - `/workspaces/*`. Setup and everyday use on your own machine, followed by settings and maintenance. Keep macOS and Linux as choices inside one setup guide. Request daemon download links from support; do not publish unlisted release URLs. API access is documented under Fluso API. - **Get started** - `/going-deeper`, `/introduction`, `/quickstart`. These pages explain the path from first setup to daily use. - **Reference** - `/resources/{faq, legal, pricing}`. Legal links to the terms of service at `https://fluso.ai/terms` and privacy policy at `https://fluso.ai/privacy`; do not duplicate the policies in the docs. - **Release notes** - `/release-notes`. Customer-facing changes, newest first. diff --git a/app/global.css b/app/global.css index 25d980c..ea1d67c 100644 --- a/app/global.css +++ b/app/global.css @@ -7,6 +7,11 @@ quotes: none; } +/* Keep reference descriptions readable beside long endpoint paths on phones. */ +#nd-page details td:last-child { + min-width: 14rem; +} + /* Fluso brand (ported from Mintlify docs.json colors) */ :root { --color-fd-primary: #5b21b6; diff --git a/components/diagrams.tsx b/components/diagrams.tsx index 7bc4168..705f13f 100644 --- a/components/diagrams.tsx +++ b/components/diagrams.tsx @@ -1,14 +1,8 @@ import { - Bot, Clock3, - Database, FileText, FolderClosed, MessageSquareText, - Network, - PlugZap, - Server, - ShieldCheck, Users, } from 'lucide-react'; @@ -208,316 +202,3 @@ export function KnowledgeGraphDiagram() { ); } - -const architectureServices = [ - { - label: 'Fluso client', - detail: 'Desktop or remote', - x: 10, - icon: MessageSquareText, - }, - { - label: 'Edge', - detail: 'TLS + routing', - x: 162, - icon: ShieldCheck, - }, - { - label: 'REST API', - detail: 'Identity + records', - x: 314, - icon: Server, - }, - { - label: 'Agent gateway', - detail: 'Admission + routing', - x: 466, - icon: Network, - emphasis: true, - }, - { - label: 'User runtime', - detail: 'Thread worker + tools', - x: 618, - icon: Bot, - }, -] as const; - -const architectureData = [ - { - label: 'PostgreSQL', - detail: 'Platform records', - owner: 'REST API', - x: 380, - icon: Database, - }, - { - label: 'Isolated user storage', - detail: 'Projects, sessions, Agents', - owner: 'Gateway + runtime', - x: 532, - icon: FolderClosed, - }, -] as const; - -const ARCHITECTURE_NODE_WIDTH = 132; - -function ArchitectureNode({ - label, - detail, - x, - icon: Icon, - emphasis = false, -}: { - label: string; - detail: string; - x: number; - icon: typeof FolderClosed; - emphasis?: boolean; -}) { - return ( - - - - ); -} - -export function ArchitectureDiagram() { - return ( -
-

- Scroll horizontally to view the full diagram. -

-
- - - Fluso request and data boundaries - - - A Fluso client sends an authenticated request through the edge, REST - API, Agent gateway, and a user runtime. The API owns platform - records. The gateway and runtime use durable workspace storage. The - runtime queries knowledge and calls governed MCP servers. - - - - - - - - - - Request path - - - - - - - - - - - - - {architectureServices.map((node) => ( - - ))} - - - - Data and context - - - - - - {architectureData.map(({ label, detail, owner, x, icon: Icon }) => ( - - - - {label} - - - {detail} - - - {owner} - - - ))} - - - - - Runtime context - - - - - Knowledge service - - - - - - MCP servers - - - - -
- -
- Compute, platform state, workspace data, knowledge, and external sources - meet through explicit service boundaries. -
-
- ); -} diff --git a/content/docs/admin-panel.mdx b/content/docs/admin-panel.mdx index 3403be5..439ff2b 100644 --- a/content/docs/admin-panel.mdx +++ b/content/docs/admin-panel.mdx @@ -45,7 +45,7 @@ The **Admin** organization role does not grant access to Fluso Admin. Panel acce Each governance event records the actor, action, target, detail, and time. Current action types cover Microsoft Entra metadata, tenant configuration, teams, roles, access requests, and Agent access records. -This is not an Agent activity trace or a complete record of Admin mutations. It does not show tool calls, logins, prompts, document edits, messages, files, knowledge graphs, runtime controls, Sponsored Confidential changes, or network-policy changes. Inspect the Agent's conversation and [Inbox](/developers/guides/inbox) for work and failures, or use the [Runs API](/developers/api-ref/runs) for recorded request state. +This is not an Agent activity trace or a complete record of Admin mutations. It does not show tool calls, logins, prompts, document edits, messages, files, knowledge graphs, runtime controls, Sponsored Confidential changes, or network-policy changes. Inspect the Agent's conversation and [Inbox](/developers/guides/inbox) for work and failures, or use the [Runs API](/api/workflows/runs) for recorded request state. ## Runtime and user controls diff --git a/content/docs/api/cloud/apps.mdx b/content/docs/api/cloud/apps.mdx new file mode 100644 index 0000000..67799bc --- /dev/null +++ b/content/docs/api/cloud/apps.mdx @@ -0,0 +1,44 @@ +--- +title: Managed app connections +icon: plug +description: Connect a supported Cloud app when your integration needs its data or tools. +--- + +Cloud can guide users through connecting supported apps, such as Google Workspace. A connection belongs to the authenticated account. Completing sign-in does not remove its tool-approval rules. + +For a daemon or a custom server, use [custom MCP connections](/api/workflows/connections). + +## Connect the requested app + +For example, a morning-brief Agent may need a calendar connection. Its run can enter `waiting_action` with an `mcp_connect` action in thread state. + +1. Read the action to identify the requested `app_id`. +2. Check the managed connection list for that app. +3. Send `POST /v1/mcp-oauth/catalog/{app_id}/connect` if it needs connection. +4. If the response says `redirect`, open its `authorization_url` for the user. +5. Let the user complete the provider sign-in and Fluso callback. +6. Check connection status and thread state before continuing. + +A `connected` response needs no browser handoff. `PROVISIONING` means provider sign-in succeeded but Fluso setup is still finishing. A refresh can complete registration. It cannot authorize an unconnected app. + +## Complete a custom callback client + +Fluso's signed-in callback normally completes the handoff. A client that handles an allowed callback itself must submit its `completion_proof` under the initiating account. + +Send the proof to `POST /v1/mcp-oauth/catalog/connect/complete`. Optionally set `expected_server_id` to check the returned connection. Protect the proof like a temporary credential. It expires after five minutes. + +A provider redirect alone does not establish that the connection is usable. Wait for the completion response or verified connection status. + + + | Method and path | Use | + | --- | --- | + | `GET /v1/mcp-oauth/catalog` | List app IDs and connection metadata. | + | `GET /v1/mcp-oauth/catalog/connections` | Read provider connection status without repairing it. | + | `POST /v1/mcp-oauth/catalog/{app_id}/connect` | Start authorization or return an existing usable connection. | + | `GET /v1/mcp-oauth/catalog/callback` | Provider/browser handoff. Do not use it for polling. | + | `POST /v1/mcp-oauth/catalog/connect/complete` | Complete the account-bound proof exchange. | + + Reads accept a developer read token. Connection changes require write access. The provider callback validates its own handoff state. + + Managed apps can be unavailable in a deployment, returning 503. `redirect_url`, when supplied, must match an allowed Fluso callback location. + diff --git a/content/docs/api/cloud/client-sign-in.mdx b/content/docs/api/cloud/client-sign-in.mdx new file mode 100644 index 0000000..30950c2 --- /dev/null +++ b/content/docs/api/cloud/client-sign-in.mdx @@ -0,0 +1,120 @@ +--- +title: Client sign-in +icon: log-in +description: Let users sign in to a configured Cloud client and keep their session active. +--- + +For your own script or service, use a [developer token](/api/cloud/tokens). It needs no browser callback or refresh flow. + +Use client sign-in when each person must connect their own Fluso account to a supported client. Fluso handles sign-in in the browser. Your client receives a one-use code and exchanges it for tokens. + + + A new client needs a configured Fluso callback. [Contact support](mailto:support@premai.io) before implementing that integration. These endpoints do not register arbitrary callback URLs. + + +## Sign in once + + + + Your client requests a sign-in URL. Open it in the user's browser. + + + Fluso handles sign-in and returns a one-use code through your configured callback. + + + Your client sends the code with its private proof. Fluso returns tokens for API access and session renewal. + + + +The proof, called **PKCE**, keeps another client from using the returned code. Generate it once for each sign-in attempt. + +Use `auth.access_token` as `Authorization: Bearer TOKEN` for API requests. Save `auth.refresh_token` privately for renewal. `auth.expires_in` tells you when the access token expires. + + + Use Node 22 or later. Set `baseUrl` to your Cloud API URL, including `/v1`. Use your configured `client` name. Set `clientUserId` to the user's stable ID within your client. + + Generate the proof and request the browser URL: + + ```javascript + import { randomBytes, createHash } from 'node:crypto'; + + const baseUrl = 'https://api.fluso.ai/v1'; + const client = 'YOUR_CONFIGURED_CLIENT'; + const clientUserId = 'YOUR_CLIENT_USER_ID'; + + const verifier = randomBytes(32).toString('base64url'); + const challenge = createHash('sha256').update(verifier).digest('base64url'); + const start = await fetch(`${baseUrl}/auth/client/start`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + client, client_user_id: clientUserId, code_challenge: challenge, + }), + }); + if (!start.ok) throw new Error(`Sign-in could not start (${start.status})`); + const { url } = await start.json(); + ``` + + Open `url` in the user's browser. Keep `verifier` on the initiating client. Do not log it or send it to the callback URL. + + After the configured callback returns `code`, exchange it using the same client identity and verifier: + + ```javascript + const exchange = await fetch(`${baseUrl}/auth/client/exchange`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + client, client_user_id: clientUserId, code, code_verifier: verifier, + }), + }); + if (!exchange.ok) throw new Error(`Sign-in exchange failed (${exchange.status})`); + const { auth } = await exchange.json(); + ``` + + Store `auth` in the client's credential store. It includes `access_token`, `refresh_token`, `expires_in`, `session_id`, and `user`. + + The browser step calls `POST /v1/auth/client/complete` with the returned state under the user's Clerk app session. Current browser callbacks support configured Fluso handoffs, including Telegram. A developer token cannot perform that browser step. + + Sign-in state expires after ten minutes. The returned code expires after five minutes and works once. If the exchange response is lost, start sign-in again. + + For another language, generate a verifier with 43 to 128 ASCII letters, digits, or `-._~`. Its challenge is SHA-256 encoded as unpadded base64url. + + +## Keep the session active + +Before the access token expires, send the saved refresh token to `POST /v1/auth/client/refresh`: + +```json +{ + "refresh_token": "YOUR_SAVED_REFRESH_TOKEN" +} +``` + +The response contains replacement `access_token` and `refresh_token` values. Save both together before sending further requests. Allow only one refresh at a time for that session. + + + Retry the same refresh token within 30 seconds to recover the same replacement pair. Reusing it after that window revokes the session. + + Refresh extends the session's 30-day expiry. If refresh is rejected, ask the user to sign in again. Do not create a new session for each API request. + + +## Sign out + +Send the refresh-token body above to `POST /v1/auth/client/revoke`. Remove the local credentials after revocation. + + + | Method and path | Required credential and use | + | --- | --- | + | `POST /v1/auth/client/start` | PKCE challenge. Request the browser URL. | + | `POST /v1/auth/client/complete` | Clerk app session and returned state. Issue the one-use code. | + | `POST /v1/auth/client/exchange` | Code, client identity, and original verifier. Issue tokens. | + | `POST /v1/auth/client/sessions` | Clerk app session. Create a client session for an already signed-in app. | + | `GET /v1/auth/client/sessions` | Clerk app session. List up to 100 active sessions, newest first. | + | `DELETE /v1/auth/client/sessions/{session_id}` | Clerk session for any owned session, or a client token for itself. | + | `POST /v1/auth/client/refresh` | Refresh token. Rotate the token pair. | + | `POST /v1/auth/client/revoke` | Refresh token. Revoke its session. Returns 204 even if already invalid. | + + Client tokens cannot manage developer tokens. That operation requires Clerk sign-in. + + Your [deployment's schema](/api#find-the-exact-fields) lists exact identifier constraints and response fields. + diff --git a/content/docs/api/cloud/meta.json b/content/docs/api/cloud/meta.json new file mode 100644 index 0000000..f56a7bc --- /dev/null +++ b/content/docs/api/cloud/meta.json @@ -0,0 +1,11 @@ +{ + "title": "Cloud API", + "icon": "cloud", + "defaultOpen": false, + "pages": [ + "tokens", + "client-sign-in", + "apps", + "sharing" + ] +} diff --git a/content/docs/api/cloud/sharing.mdx b/content/docs/api/cloud/sharing.mdx new file mode 100644 index 0000000..cc6803b --- /dev/null +++ b/content/docs/api/cloud/sharing.mdx @@ -0,0 +1,101 @@ +--- +title: Sharing +sidebarTitle: Sharing +icon: share-2 +description: Share an Agent, conversation, or file, and understand what a public link exposes. +--- + +Public sharing is Cloud-only. Anyone with a published link can read its contents. Owner operations require [authentication](/api/cloud/tokens). Public reads do not. + +## Share an Agent + +An Agent link publishes a saved copy of selected setup. It does not expose the owner's live workspace. + +Read `GET /v1/agents/{agent_id}/share-options` to choose resources. Publish the selection through `POST /v1/agents/{agent_id}/share`: + +```json +{ + "skills": [], + "knowledge_files": [], + "connectors": [] +} +``` + +Use IDs from share options for skills, knowledge names for `knowledge_files`, and server IDs for `connectors`. Instructions and portable settings are included even with empty selections. Selected skill folders and knowledge contents share limits of 20 MiB and 512 regular files. Symbolic links are rejected. Custom connection URLs with query parameters are excluded from share options. + +Review all selected contents and connection URLs before publishing. Stored authentication, conversations, routines, and project files are not bundled. See [Sharing and copies](/developers/guides/sharing) for the recipient experience. + +## Preview and import + +Read `GET /v1/shared/agents/{share_id}` before importing. Send its exact `published_at` with the new name and project to `POST /v1/shared/agents/{share_id}/import`: + +```json +{ + "name": "My release reviewer", + "project_id": "Home", + "published_at": "" +} +``` + +Generate and save a new `Idempotency-Key` for each import. Reuse it and the unchanged body to recover an uncertain import without creating another copy. A changed snapshot returns a conflict rather than silently importing something different from the preview. + +The recipient gets independent setup and selected resource copies. Imported custom skills receive distinct names. App credentials are never inherited. Read the imported Agent's `setup_requirements`, then complete missing connections and consent in its manager conversation. + +A revoked link becomes unavailable. Unsupported older snapshots may require republication by their owner. Revocation does not delete copies already imported. + + + | Method and path | Behavior | + | --- | --- | + | `GET /v1/agents/{agent_id}/share-options` | Available custom skills, knowledge, and custom connections | + | `GET /v1/agents/{agent_id}/share` | Current link record or `null` | + | `POST /v1/agents/{agent_id}/share` | Publish a snapshot | + | `POST /v1/agent-shares/{share_id}/refresh` | Replace the snapshot at the same link | + | `DELETE /v1/agent-shares/{share_id}` | Revoke the link | + | `GET /v1/agent-templates` | Fluso starting-point snapshots | + | `GET /v1/shared/agents/{share_id}` | Public setup, resource manifest, required filenames, and `published_at` | + | `POST /v1/shared/agents/{share_id}/import` | Authenticated import into the recipient's workspace | + + +## Share a conversation + +Publish a conversation with `POST /v1/chat-shares` and its `thread_id`. The link shows a snapshot of its saved messages. Later messages remain private until you refresh that link. + +Revoke the link to prevent further public reads. The private conversation remains. Deleting the conversation itself does not revoke a separately published snapshot. + + + | Method and path | Use | + | --- | --- | + | `POST /v1/chat-shares/lookup-batch` | Find existing links for `thread_ids` without publishing. | + | `POST /v1/chat-shares` | Publish the current conversation or return its existing link. | + | `POST /v1/chat-shares/{share_id}/refresh` | Update saved messages at the same link. | + | `DELETE /v1/chat-shares/{share_id}` | Revoke the link while keeping the private conversation. | + | `GET /v1/shared/chats/{share_id}` | Read the public snapshot without authentication. | + + +## Share a file + +Choose `share_mode` explicitly when publishing a workspace file: + +| Mode | What readers get | +| --- | --- | +| `snapshot` | A saved copy. Later file changes require a refresh. | +| `live` | The current file at its workspace path. A view can start the owner's runtime. | + +Anyone with the link can download the file. Review its contents before publication. + +If an active link already exists, creation returns it even when you request a different mode. Revoke it before changing modes. Refreshing a live link converts it to a snapshot. A failed refresh preserves the existing link. + + + | Method and path | Use | + | --- | --- | + | `POST /v1/asset-shares/lookup-batch` | Find active links for workspace paths without publishing. | + | `POST /v1/asset-shares` | Publish with explicit `share_mode`. Creation can start the runtime in either mode. | + | `POST /v1/asset-shares/{share_id}/refresh` | Save the current file as a new snapshot at the same link. | + | `DELETE /v1/asset-shares/{share_id}` | Revoke the link while keeping the workspace file. | + | `GET /v1/shared/assets/{share_id}` | Read public bytes or follow a snapshot download redirect. | + | `GET /v1/shared/assets/{share_id}/{file_name}` | Read the same file with a descriptive URL suffix. | + + Public reads need no bearer token. Follow redirects and inspect `Content-Type` instead of parsing the response as JSON. + + Revocation blocks new public requests. A previously issued snapshot download URL can remain valid for five minutes. Revocation cannot remove copies someone already downloaded. + diff --git a/content/docs/api/cloud/tokens.mdx b/content/docs/api/cloud/tokens.mdx new file mode 100644 index 0000000..4c60e14 --- /dev/null +++ b/content/docs/api/cloud/tokens.mdx @@ -0,0 +1,68 @@ +--- +title: Developer tokens +icon: key-round +description: Create and maintain Cloud API access for your own integration. +--- + +A developer token lets a script use your Fluso Cloud account. Create it in the app, then store it as your integration's secret. + +## Create a token in Fluso + +1. Open **Settings → Developer tokens** in your Cloud workspace. +2. Click **Create token**. +3. Enter a name that identifies the integration, such as **Weekly report**. +4. Choose **Read only** to inspect data, or **Read and write** to submit work. +5. Choose an expiry, then click **Create token**. +6. Click **Copy token** before closing the result. + + + + Create developer token form with Weekly report, Read and write access, and a 90-day expiry. + + + +The secret appears once. If you lose it, revoke that token and create a replacement. + +## Check access + +After [setting the URL and token](/api/first-request#1-get-access), check the authenticated identity: + +```bash +curl --fail-with-body --silent --show-error \ + "$FLUSO_API_URL/auth/me" \ + -H "Authorization: Bearer $FLUSO_API_TOKEN" +``` + +This read does not start a runtime. Check the account and access level before your integration submits work. + +| Access | What it permits | +| --- | --- | +| `read` | Read your Agents, conversations, files, usage, and results | +| `write` | Also submit work, change files and schedules, connect services, and decide individual tool approvals | +| Signed-in app session | Manage developer tokens and permanent tool permissions | + +Access covers the account. A token is not restricted to one Agent or project. Work uses that account's limits. + +## Replace or revoke a token + +Create a replacement in Settings. Update your integration's secret, then check it with `/auth/me`. Revoke the old token after the replacement works. + +The default expiry is 90 days. Revocation reaches cached authentication and open streams within 30 seconds. Revocation does not stop accepted work or existing schedules. [Stop work](/api/workflows/runs#stop-work) or [pause schedules](/api/workflows/schedules) separately. + + + These four management routes require the owning account's Clerk app session. Developer tokens and native client tokens cannot manage developer tokens. + + | Method and path | Use | + | --- | --- | + | `GET /v1/account/tokens` | List metadata, including revoked tokens. Follow `next_cursor` as `after`. | + | `POST /v1/account/tokens` | Create with `name`, `access`, and optional `expires_at`. Requires `Idempotency-Key`. | + | `PATCH /v1/account/tokens/{token_id}` | Change `name` only. Replace the token to change access or expiry. | + | `DELETE /v1/account/tokens/{token_id}` | Revoke it. Repeated revocation returns 204. | + | `GET /v1/auth/me` | Read the authenticated identity. Accepts developer tokens too. | + + Creation returns 201 and the secret once. Retrying the same key and body returns 200 with `secret: null`. A changed body returns 409. If the first response was lost, revoke that token and create another with a new key. + + Omit `expires_at` for 90 days. Send `null` for no expiry, or a future timestamp with a timezone. An account can have at most 100 active tokens. + + +For a native application with an existing sign-in integration, see [client sessions](/api/cloud/client-sign-in). diff --git a/content/docs/api/daemon/meta.json b/content/docs/api/daemon/meta.json new file mode 100644 index 0000000..839afd6 --- /dev/null +++ b/content/docs/api/daemon/meta.json @@ -0,0 +1,9 @@ +{ + "title": "Daemon API", + "icon": "server", + "defaultOpen": false, + "pages": [ + "pairing", + "settings" + ] +} diff --git a/content/docs/api/daemon/pairing.mdx b/content/docs/api/daemon/pairing.mdx new file mode 100644 index 0000000..1d06321 --- /dev/null +++ b/content/docs/api/daemon/pairing.mdx @@ -0,0 +1,71 @@ +--- +title: Pair an API client +icon: link +description: Give a client access to your Fluso Local workspace. +--- + +A daemon belongs to one owner. Each paired device gets its own token for that owner's workspace. Pairing does not create a separate account or private set of files. + +[Set up Fluso Local](/workspaces/setup) and its provider before submitting work. For remote access, use HTTPS or an SSH tunnel. + +## Get a device token + +On the daemon's host, run this from the installed package folder. Use the same state root as your running daemon: + +```bash +./fluso-daemon pair --root /path/to/state +``` + +Exchange its one-use code from your client: + +```bash +curl --fail-with-body --silent --show-error \ + 'http://127.0.0.1:4111/daemon/v1/pair' \ + -H 'Content-Type: application/json' \ + --data-raw '{"code":"PAIRING_CODE","name":"Weekly report integration"}' +``` + +Replace the address for a remote daemon. Replace `PAIRING_CODE` with the code from the host. + +Save `token` privately. Keep the returned client `id` and `daemonId` with your connection settings. If that daemon identity changes later, pair again. + +Codes expire after ten minutes and work once. If the exchange response is lost, generate a new code. Device tokens expire after 30 idle days. Authenticated use renews them. + + + A normal device token grants read/write workspace access, including tool approvals. Add `--manage-host` only for clients that also need machine administration. + + +Use the token as `Authorization: Bearer YOUR_TOKEN`. Browser requests must come from the daemon's exact origin. Use a native or server client for an integration hosted elsewhere. For the [first request](/api/first-request), set `FLUSO_API_URL` to `http://127.0.0.1:4111/v1` or your remote equivalent. + +## Check support and readiness + +`GET /v1/capabilities` reports supported features. Use it to show only the controls available on that daemon. + +`GET /daemon/v1/discovery` reports identity and configuration state. Its `ready` status means configuration is ready. Check `/v1/agent/runtime/status` for runtime readiness. + +`GET /healthz` only proves the daemon is listening. A successful health check does not prove that the model provider works. + +## Remove a device + +Send `DELETE /daemon/v1/clients/{clientId}` to revoke a token. A device can revoke itself. Host-management access also permits listing and revoking other devices. + +Revocation closes that device's streams and prevents further access. The workspace, accepted work, and schedules remain. [Stop work](/api/workflows/runs#stop-work) or [pause schedules](/api/workflows/schedules) separately. + + + | Method and path | Access and use | + | --- | --- | + | `GET /healthz` | No token. Check liveness. | + | `POST /daemon/v1/pair` | One-use pairing code. Issue a device token. | + | `GET /daemon/v1/discovery` | Paired device. Read identity and configuration state. Host fields require host management. | + | `GET /v1/capabilities` | Paired device. Read feature support. | + | `GET /v1/confidential/attestation` | Paired device. Read the configured confidential-mode verification response. | + | `POST /daemon/v1/pairing-codes` | Host management. Create a code with `manageHost: true` or `false`. | + | `GET /daemon/v1/clients` | Host management. List current devices without token values. | + | `DELETE /daemon/v1/clients/{clientId}` | Self, or host management for another device. Revoke access. | + + Pairing returns `expiresAt` in Unix milliseconds. Device listings use `expires_at` and `manage_host`. Use the exact field names in each response. + + +After enabling and applying confidential mode, `/v1/confidential/attestation` reports `success`, `unavailable`, or `error`. `unavailable` can mean the mode is off or no key is active. + +Cloud sign-in, developer-token management, managed app catalogs, and public sharing are unavailable on a daemon. Use [custom MCP connections](/api/workflows/connections) and its own [host settings](/api/daemon/settings). diff --git a/content/docs/api/daemon/settings.mdx b/content/docs/api/daemon/settings.mdx new file mode 100644 index 0000000..387c7e3 --- /dev/null +++ b/content/docs/api/daemon/settings.mdx @@ -0,0 +1,75 @@ +--- +title: Host settings +icon: settings-2 +description: Change a daemon's model provider, sandbox resources, and shared folders safely. +--- + +These operations require a device paired with `--manage-host`. Ordinary pairing already permits workspace work. Host management adds authority over this machine's configuration and connected devices. + +Prefer [Workspace settings in Fluso](/workspaces/manage) for interactive setup. Use this API when your client needs to manage the same settings. + +## Read, save, then apply + +Saving settings does not apply them to the running sandbox. + +1. Read `GET /daemon/v1/settings` and `GET /daemon/v1/sandbox`. +2. Keep each response's `revision`. +3. Save the change with that resource's `expectedRevision`. +4. Keep the new revisions returned by the saves. +5. Apply both revisions with `POST /daemon/v1/apply`. +6. Read discovery and runtime status to check the outcome. + +For example, change the model while keeping the existing provider and key: + +```json +{ + "expectedRevision": "SETTINGS_REVISION_FROM_READ", + "settings": { + "FLUSO_MODEL": "MODEL_ID_SUPPORTED_BY_YOUR_PROVIDER" + } +} +``` + +Send that body to `PATCH /daemon/v1/settings`. Omitted fields remain unchanged. `null` clears a field. Returned `secrets` are presence flags, not key values. + +Apply the saved revisions with: + +```json +{ + "settingsRevision": "SETTINGS_REVISION_FROM_SAVE", + "sandboxRevision": "SANDBOX_REVISION_FROM_READ", + "interrupt": false +} +``` + +A 409 `INTERRUPTION_REQUIRED` means active work would be interrupted. Ask the owner before repeating with `interrupt: true`. + +## Change the provider or sandbox + +For an OpenAI-compatible endpoint, set `FLUSO_PROVIDER: "custom"`, `OPENAI_BASE_URL`, `FLUSO_MODEL`, and `OPENAI_API_KEY`. Include `/v1` in the base URL when the provider requires it. Other provider choices are `openrouter`, `openai`, and `pcci`. + +A saved key stays tied to its endpoint. Enter a key again when changing that destination. Audio has separate provider and key settings. The [daemon's schema](/api#find-the-exact-fields) lists every supported setting. + +Sandbox changes use `PUT /daemon/v1/sandbox` with `expectedRevision` and the complete `config`. Preserve all intended `hostFiles` grants. An empty list removes shared-folder access. + +Host paths refer to the daemon's machine, even when you connect remotely. Grant only the required folders. Writable grants permit changing or deleting the original host files. Workspace `/v1/files` paths do not grant access to arbitrary host paths. + + + | Method and path | Use | + | --- | --- | + | `GET /daemon/v1/settings` | Read saved provider settings and their revision. | + | `PATCH /daemon/v1/settings` | Save changed fields. `preview: true` validates without saving. | + | `GET /daemon/v1/sandbox` | Read configuration, revision, host RAM, and disk budgets. | + | `PUT /daemon/v1/sandbox` | Replace the sandbox configuration with revision protection. | + | `POST /daemon/v1/apply` | Apply the saved settings and sandbox revisions. | + + Sandbox `config` contains `runtimeProfile`, `hostFiles`, `memoryGiB`, and `diskGiB`. RAM is the VM allocation. Disk is the combined saved-work and temporary-work budget. It excludes images, backups, and shared host folders. Existing workspace data must fit a smaller budget before you apply it. + + On 409 `CONFIGURATION_CONFLICT`, reload both resources and review the newer changes. Do not substitute a fresh revision without reviewing them. + + During an update or apply, workspace routes can return 503 with `Retry-After`. Discovery shows `applying` or `configuration_error` where applicable. Resolve a configuration error before resubmitting work. A 423 locked credential store requires recovery on the host. + + Discovery exposes saved and applied revisions and `restartRequired` to host-authorized clients. After a lost apply response, read those values before another apply. + + +Binary updates, backups, and credential-store recovery use the [daemon CLI](/workspaces/manage). The settings API does not replace those operations. diff --git a/content/docs/api/first-request.mdx b/content/docs/api/first-request.mdx new file mode 100644 index 0000000..442489d --- /dev/null +++ b/content/docs/api/first-request.mdx @@ -0,0 +1,94 @@ +--- +title: Your first request +icon: terminal +description: Send a message, get an answer, and keep the conversation open for follow-ups. +--- + +This example asks Fluso to explain three ways to check a source. You get a complete answer and a conversation you can continue. + +## 1. Get access + +For Cloud, create a [developer token](/api/cloud/tokens) with **Read and write** access. For Fluso Local, [pair a client](/api/daemon/pairing) after configuring its model provider. + +Open your workspace's [API reference](/api#find-the-exact-fields) to check availability in that release. + +Start a Bash shell in a new, empty directory. You need cURL 7.87 or later, `jq`, and `uuidgen`. + +Set the URL for your workspace: + +```bash +export FLUSO_API_URL='https://api.fluso.ai/v1' +``` + +For Fluso Dev, use `https://api.dev.khichdi.cc/v1`. For a local daemon, use `http://127.0.0.1:4111/v1`. The token must belong to that workspace. + +Read your token without showing it or saving it in shell history: + +```bash +read -r -s -p 'Fluso token: ' FLUSO_API_TOKEN +echo +export FLUSO_API_TOKEN +``` + +## 2. Get an answer + +Download the example from that workspace: + +```bash +curl --fail --silent --show-error \ + "$FLUSO_API_URL/examples/quickstart.sh" -o quickstart.sh && +cat quickstart.sh +``` + +Read the script, then run it in the same Bash shell: + +```bash +source quickstart.sh +``` + +It prints Fluso's answer after reading every result page. If work needs attention, it prints the run's status instead. Stop on an error and use [recovery](/api/workflows/runs) before submitting again. + +Keep this shell open. The other guides use the values and functions it provides: + +| Name | What it gives you | +| --- | --- | +| `thread_id` | The conversation to continue | +| `run_id` | The work started by your message | +| `input_key`, `input_body` | The exact request to reuse after a lost response | +| `api` | An authenticated request to your chosen workspace | +| `wait_for_run`, `read_run_items` | Wait for completion, then read all saved output | + +For example, `api "/threads/$thread_id/state"` reads the conversation's state. `api` adds the base URL and bearer token. It uses ordinary cURL options. + + + A timeout does not cancel work. Do not rerun the quickstart to recover: it creates a new request. Read the [saved run](/api/workflows/runs) instead. + + +## 3. Continue from here + +[Send a follow-up](/api/workflows/conversations) to turn the answer into a checklist. You can also [attach a document](/api/workflows/files) or [create a reusable Agent](/api/workflows/agents). + + + It sends `POST /v1/threads` with an `input` message and a new `Idempotency-Key`. The response identifies the accepted work: + + ```json + { + "thread_id": "thread_example", + "input_id": "message-1", + "run_id": "message-1", + "disposition": "running" + } + ``` + + Save the returned IDs. Do not assume `input_id` and `run_id` are equal. + + **202 means accepted.** The example reads `GET /v1/threads/{thread_id}/runs/{run_id}` until completion, then reads the items for that run. + + An idempotency key identifies one submitted message. Save it and the body before sending. Reuse both after a lost response. A new key starts new work. + + + + Save any output you need. Download `$FLUSO_API_URL/examples/cleanup.sh`, read it, then run `source cleanup.sh` in the same shell. It deletes the example conversation and any files created by the file examples. + + The scripts are examples, not an SDK. In your application, store tokens in a secret store and save request IDs durably. Keep credentials out of URLs, source control, logs, and screenshots. + diff --git a/content/docs/api/index.mdx b/content/docs/api/index.mdx new file mode 100644 index 0000000..8d3a848 --- /dev/null +++ b/content/docs/api/index.mdx @@ -0,0 +1,57 @@ +--- +title: Fluso API +icon: code-xml +description: Give Fluso work from your own script or application, then read the result. +--- + +Use the API to send a message, attach a document, or run a saved Agent. Your integration uses the same workspace as the Fluso app. + +Start with one conversation. Add schedules, connections, or live updates when your application needs them. + + + Get access, submit a short task, and read the saved answer. + + +## Choose your workspace + +Cloud and Fluso Local share the conversation, Agent, file, and schedule APIs. Their credentials and administration differ. Data stays in the workspace you address. + +| | Cloud API | Daemon API | +| --- | --- | --- | +| Where work runs | Your Fluso Cloud workspace | Your own machine's Fluso Local workspace | +| Access for scripts | [Developer token](/api/cloud/tokens) | [Paired device token](/api/daemon/pairing) | +| Example base URL | `https://api.fluso.ai/v1` | `http://127.0.0.1:4111/v1` | +| Connected apps | Managed apps and custom MCP servers | Custom MCP servers | +| Public sharing | Agents, conversations, and files | Unavailable | +| Machine settings | Managed by the service | [Provider, sandbox, and devices](/api/daemon/settings) | + +Fluso Dev uses `https://api.dev.khichdi.cc/v1`. Use credentials from the same environment as the URL. + +For a remote daemon, use its HTTPS address or an [SSH tunnel](/workspaces/setup#connect-from-another-mac). A Cloud token cannot access a daemon. + +## Find the exact fields + +Open **Settings → Developer tokens → API reference** in Cloud. On a daemon's host, open `http://127.0.0.1:4111/docs`. + +Releases with this API serve the endpoint reference at `/docs` and the OpenAPI schema at `/v1/openapi.json`. These describe the fields and operations available in that deployment. The reference also supplies runnable examples under `/v1/examples/`. The daemon serves its schema and examples locally. Its interactive reference needs internet access to load the viewer. + +The guides below explain how to combine those operations. Endpoint tables sit inside each guide, after the main workflow. + + + + Create a developer token and choose its access. + + + Pair a client with your own workspace. + + + Continue work and read the complete answer. + + + Handle a timeout without starting the same work twice. + + + + + If your app lacks **Developer tokens** or its API reference returns 404, contact [support](mailto:support@premai.io) about availability for your release. + diff --git a/content/docs/api/meta.json b/content/docs/api/meta.json new file mode 100644 index 0000000..894994d --- /dev/null +++ b/content/docs/api/meta.json @@ -0,0 +1,10 @@ +{ + "pages": [ + "!index", + "[code-xml][Overview](/api)", + "first-request", + "cloud", + "daemon", + "workflows" + ] +} diff --git a/content/docs/api/workflows/agents.mdx b/content/docs/api/workflows/agents.mdx new file mode 100644 index 0000000..a3ec4ac --- /dev/null +++ b/content/docs/api/workflows/agents.mdx @@ -0,0 +1,125 @@ +--- +title: Use Agents +icon: bot +description: Create a meeting assistant, give it work, and improve its saved instructions. +--- + +An Agent keeps instructions for work you repeat. This example creates a meeting assistant that turns notes into decisions and open questions. + +Use the Bash shell from [your first request](/api/first-request). It provides authenticated requests through `api`. + +## Create the assistant + +```bash +agent_key=$(uuidgen) && +agent_body='{ + "name": "Meeting assistant", + "instructions": "Turn my notes into a meeting brief. List decisions needed and open questions." +}' && +agent=$(api /agents \ + -H "Idempotency-Key: $agent_key" \ + -H 'Content-Type: application/json' -d "$agent_body") && +agent_id=$(printf '%s' "$agent" | jq -er '.agent_id') +``` + +This saves the Agent without starting a conversation. Keep `agent_id` for later use. If the response is lost, repeat the request with the same `agent_key` and `agent_body`. + +## Give it work + +Send a message with that Agent's ID: + +```bash +agent_input_key=$(uuidgen) && +agent_input_body=$(jq -nc --arg agent_id "$agent_id" \ + '{agent_id: $agent_id, + input: ("Notes: Maya will send the revised budget on Thursday. " + + "We still need to choose a launch date. Prepare my meeting brief.")}') && +agent_receipt=$(api /threads \ + -H "Idempotency-Key: $agent_input_key" \ + -H 'Content-Type: application/json' -d "$agent_input_body") && +agent_thread_id=$(printf '%s' "$agent_receipt" | jq -er '.thread_id') && +agent_run_id=$(printf '%s' "$agent_receipt" | jq -er '.run_id') +``` + +Read the answer with the quickstart's helpers. The parentheses keep your original conversation IDs unchanged: + +```bash +( + thread_id=$agent_thread_id + run_id=$agent_run_id + wait_for_run && read_run_items | jq '.data' +) +``` + +Opening this Agent again returns the same main conversation. Other callers share its history and queue. To open its setup conversation, include `purpose: "manager"` in the thread request. + +## Improve its instructions + +First read the current setup. Then send your edit with its `current_config_id`: + +```bash +agent=$(api "/agents/$agent_id") && +config_id=$(printf '%s' "$agent" | jq -er '.current_config_id') && +edit_body=$(jq -nc --arg base "$config_id" \ + '{base_config_id: $base, + instructions: ("Turn my notes into a short meeting brief. " + + "Start with decisions I need to make, then open questions. " + + "Do not invent owners or dates.")}') && +api "/agents/$agent_id" -X PATCH \ + -H 'Content-Type: application/json' -d "$edit_body" +``` + +A 409 means another edit arrived first. Read the newer setup and review it before retrying. The main conversation uses saved changes on its next turn. Existing work sessions keep their saved configuration. + +Next, [schedule this assistant](/api/workflows/schedules) using `agent_id` and `agent_thread_id`. + + + Use skill names from [skill inventory](/api/workflows/workspace#choose-skills-for-an-agent) and server IDs from [connection inventory](/api/workflows/connections). + + Omitted `skills` or `connectors` stay unchanged during an update. `null` removes the selection restriction. An empty list or map selects none. Connector `allow` still respects account consent. + + Upload knowledge or copy a workspace file through the knowledge endpoints below. Add the returned reference to `knowledge_files` in an update with the current `base_config_id`. + + Uploading alone does not attach knowledge to the Agent. Knowledge is a copy, so later edits to the original file do not change it. + + Each Agent accepts up to 25 knowledge files, each no larger than 20 MiB. Use `knowledge_files: []` to remove the selection. + + + + Supported effort values are `off`, `minimal`, `low`, `medium`, `high`, and `xhigh`. An input's explicit effort overrides the Agent default. The runtime chooses the nearest supported effort, preferring a higher level before a lower one. + + Steering without an effort keeps the active setting. An explicit change applies at the next execution attempt, without restarting an in-flight model call. + + `run.execution` records the configuration, provider, model, and effort used when execution starts. + + Public clients open main and manager conversations, not Agent work sessions. Omit `agent_id` for independent ordinary conversations. + + Conversations share workspace files. Use distinct output paths for concurrent jobs that must not overwrite each other. + + + + Duplication creates independent setup. Retry it with the same idempotency key to recover the original copy. + + [Public sharing](/api/cloud/sharing) is Cloud-only. Its snapshot excludes credentials, conversations, and schedules. After import, read `setup_requirements` and complete setup in the Manager conversation. + + `DELETE /v1/agents/{agent_id}` removes the Agent, its owned conversations, and its schedules. It also revokes the Agent's share link. Save needed results before deletion. + + + + | Method and path | Use | + | --- | --- | + | `GET /v1/agents` | Search or list Agents. Use numbered pages or `all=true`. | + | `POST /v1/agents` | Create saved setup without starting a turn. | + | `GET /v1/agents/{agent_id}` | Read setup and `current_config_id`. | + | `PATCH /v1/agents/{agent_id}` | Save changes with `base_config_id`. | + | `DELETE /v1/agents/{agent_id}` | Delete setup and conversations, retire schedules, and revoke its Agent link. | + | `POST /v1/agents/{agent_id}/avatar` | Save appearance. `avatar: null` resets it. | + | `POST /v1/agents/{agent_id}/star` | Set `starred` to true or false. | + | `POST /v1/agents/{agent_id}/duplicate` | Copy setup and knowledge. Use an idempotency key for retries. | + | `POST /v1/agents/{agent_id}/knowledge-files` | Store multipart `file` and return its reference. | + | `POST /v1/agents/{agent_id}/knowledge-files/from-workspace` | Copy `path` into knowledge and return its reference. | + + Appearance and starring do not change instructions or configuration bindings. Duplication excludes conversations, schedules, and public links. + + Creation and duplication receipts remain with the saved Agent. Their keys do not use the input receipt's 24-hour window. Older `creation_id` is accepted for creation. Do not supply conflicting identifiers. + diff --git a/content/docs/api/workflows/connections.mdx b/content/docs/api/workflows/connections.mdx new file mode 100644 index 0000000..f344585 --- /dev/null +++ b/content/docs/api/workflows/connections.mdx @@ -0,0 +1,114 @@ +--- +title: Connections and approvals +icon: plug +description: Connect a service once, then help users decide when Fluso needs permission. +--- + +Your integration can use the services already connected to the same Fluso workspace. A connection gives access to tools. The user's permission settings decide which actions can proceed. + +For an initial setup, connect the service in **Plugins → MCP** in Fluso. Cloud offers managed apps such as Google Workspace. Fluso Local uses custom MCP servers. + +The examples below use `api`, `thread_id`, and `run_id` from [your first request](/api/first-request). + +## Handle a waiting run + +When a run reports `waiting_action`, read its pending action: + +```bash +state=$(api "/threads/$thread_id/state") && +approval_url=$(printf '%s' "$state" | jq -er --arg run "$run_id" \ + 'first(.pending_actions[] | select(.run_id == $run)) | .url') && +approval_route=${approval_url#/v1} && +approval=$(api "$approval_route") && +printf '%s' "$approval" | jq '{kind, status, app_id, server_id, tool_name, arguments, expires_at}' +``` + +The action URL already starts with `/v1`. The example removes that prefix because `api` includes it. If there is no matching action, check the run again. It may have resumed or finished. + +| Action kind | What to show the user | +| --- | --- | +| `mcp_connect` | The service they need to connect. Follow [managed app sign-in](/api/cloud/apps) or custom setup below. | +| `mcp_tool` | The requested tool and its actual arguments, with a choice to allow or deny. | + +For a **pending `mcp_tool` action**, send this only after the user approves the displayed call: + +```bash +api "$approval_route/decision" \ + -H 'Content-Type: application/json' \ + -d '{"decision":"allow","scope":"once"}' +``` + +Use `decision: "deny"` to refuse it. After either decision, follow the same run. Do not resend its input. + +A 409 or 410 means the action needs another read. Do not approve a replacement without reviewing it. A successful decision saves consent, but does not mean the run completed. + +## Connect a custom MCP server + +MCP is the protocol that lets a service expose tools to Fluso. Start with the service's public HTTPS endpoint. + +Probe the endpoint before saving it. Replace the example URL with your service's URL: + +```bash +api /mcp-oauth/probe \ + -H 'Content-Type: application/json' \ + -d '{"server_url":"https://your-service.example/mcp"}' +``` + +The response identifies its transport and authentication method. Choose the matching connection flow: + +| The service uses | Start with | +| --- | --- | +| No authentication, bearer token, or API key | `POST /v1/mcp-oauth/connections/static` | +| OAuth with automatic client registration | `POST /v1/mcp-oauth/sessions` | +| OAuth with your own client registration | `POST /v1/mcp-oauth/sessions/byo-oauth` | + +Open the returned `authorization_url` for OAuth. `already_connected` needs no sign-in. Wait for the session status to become `connected` before treating setup as complete. + + + On Cloud, the callback submits `completion_proof` under the initiating account. On a daemon, `/daemon/v1/oauth/callback` completes it directly. Use the returned authorization URL unchanged. + + Read `GET /v1/mcp-oauth/connections` to inspect saved connections. `needs_reauth` means the user must reconnect. Saved inventory alone does not prove the service is reachable. + + A developer write token can decide one-time tool approvals. Permanent rules require a Cloud app session or a paired daemon device. + + + + | Method and path | Use | + | --- | --- | + | `POST /v1/mcp-oauth/probe` | Discover transport and authentication. | + | `POST /v1/mcp-oauth/connections/static` | Save a key-based or unauthenticated connection. | + | `POST /v1/mcp-oauth/sessions` | Start custom OAuth authorization. | + | `POST /v1/mcp-oauth/sessions/byo-oauth` | Start OAuth with your client registration. | + | `POST /v1/mcp-oauth/sessions/complete` | Cloud only. Save the connection from its completion proof. | + | `GET /v1/mcp-oauth/sessions/{session_id}/status` | Read authorization progress. | + | `GET /daemon/v1/oauth/callback` | Daemon only. Receive the provider's OAuth callback. | + | `GET /v1/mcp-oauth/connections` | List connections without exposing secrets. | + | `POST /v1/mcp-oauth/connections/refresh` | Refresh Cloud registrations or daemon tool discovery. | + | `DELETE /v1/mcp-oauth/connections/{server_id}` | Disconnect and invalidate its pending authority. | + | `GET /v1/mcp-oauth/connections/{server_id}/tools` | Read tool descriptions, input schemas, and read-only classifications. | + | `POST /v1/mcp-oauth/connections/{server_id}/tools` | Refresh or repair the connection before tool discovery. | + + Reusing a static connection's `server_id` updates that connection. Its `auth_method` is `bearer`, `api_key`, or `no_auth`. Only the first two accept a token. API keys use `header_name`, which defaults to `X-Api-Key`. + + Tool discovery can return saved tool information with an `error`. A 409 `CONNECTION_CHANGING` includes `Retry-After: 1`. Check the connection again after that delay. + + OAuth `pending` and `processing` are unfinished states. Handle `error`, `expired`, or `superseded` before a new sign-in attempt. + + + + | Method and path | Use | + | --- | --- | + | `GET /v1/mcp-oauth/permissions/approvals/{approval_id}` | Read the action, status, and expiry. | + | `POST /v1/mcp-oauth/permissions/approvals/{approval_id}/decision` | Allow or deny a tool request. | + | `POST /v1/mcp-oauth/permissions/approvals/{approval_id}/cancel` | Dismiss the pending action without granting access. | + | `GET /v1/mcp-oauth/permissions/mode` | Read a thread's `auto_approve` setting and `version`. Supply `thread_id`. | + | `PUT /v1/mcp-oauth/permissions/mode` | Change it with `expected_version` and the same `thread_id`. | + | `GET /v1/mcp-oauth/permissions/default` | Read the account default. | + | `PUT /v1/mcp-oauth/permissions/default` | Change the default with `expected_version`. | + | `GET /v1/mcp-oauth/connections/{server_id}/permissions` | Read saved and effective tool policies. | + | `PUT /v1/mcp-oauth/connections/{server_id}/permissions` | Change persistent connection or tool policies. | + + Cloud developer tokens cannot use these PUT routes or decision `scope: "always"`. Use a signed-in app session for permanent changes. Paired daemon devices can make these changes. + + A stale permission version returns 409. Enabling thread auto-approval can resolve an eligible pending request. An explicitly denied tool remains denied. Changing the account default does not decide an existing pending approval. + diff --git a/content/docs/api/workflows/conversations.mdx b/content/docs/api/workflows/conversations.mdx new file mode 100644 index 0000000..5816cdb --- /dev/null +++ b/content/docs/api/workflows/conversations.mdx @@ -0,0 +1,95 @@ +--- +title: Send messages +icon: messages-square +description: Continue a conversation and read its complete answer. +--- + +Turn the answer from [your first request](/api/first-request) into a checklist. Use the same Bash shell, which already has your token, `api` helper, and conversation IDs. + +A **thread** is the conversation. Each message you submit is an **input**. A **run** tracks the work that follows. + +## Send a follow-up + +Save a new key and message, then send them to the existing conversation: + +```bash +input_key=$(uuidgen) && +input_body='{ + "input": "Turn those checks into a three-item checklist.", + "mode": "queue" +}' && +receipt=$(api "/threads/$thread_id/inputs" \ + -H "Idempotency-Key: $input_key" \ + -H 'Content-Type: application/json' -d "$input_body") && +run_id=$(printf '%s' "$receipt" | jq -er '.run_id') +``` + +The receipt identifies this new run. If the conversation is busy, `queue` waits for the current work to finish. Use `steer` to guide active work instead. + +Keep `input_key` and `input_body` if the response is lost. [Retry those same values](/api/workflows/runs), without generating another key. + +## Read the answer + +The quickstart's helpers wait for the run and read every output page: + +```bash +wait_for_run && +items=$(read_run_items) && +printf '%s' "$items" | jq '.data[] | select(.type == "message" and .role == "assistant")' +``` + +You receive the saved assistant messages, including any attachments. A message can contain a file without text. Use each attachment's returned path to [download its content](/api/workflows/files). + +If the run needs approval or fails, `wait_for_run` stops and prints its status. Follow [Runs and retries](/api/workflows/runs) before sending more work. + +## Start a separate conversation + +Send `POST /v1/threads` with an `input` and a new key, as the quickstart does. Omit `input` and `attachments` to open an empty conversation. + +Include `agent_id` to use a [saved Agent](/api/workflows/agents). Its main conversation is reused. Add `purpose: "manager"` to open that Agent's setup conversation. + +## Read message history + +For your own client, use `GET /v1/threads/{thread_id}/items?run_id={run_id}`. Omit `run_id` to read the whole conversation. + +Entries are in `data`. Pass `next_cursor` as `after`, with the unchanged `revision`, until `next_cursor` is null. Keep filters unchanged. The `read_run_items` helper performs these steps for you. + +An empty page does not prove completion. Check the [run status](/api/workflows/runs). To display progress while waiting, add [live updates](/api/workflows/streaming). + + + Edits or deletions can invalidate an item snapshot. On a pagination conflict, discard the partial read and restart without `after` or `revision`. New messages alone do not invalidate it. + + Read thread state before editing queued work. Active or completed inputs cannot be edited as queued messages. + + A queued edit needs its own new `Idempotency-Key`. Keep that edit key on retries. If the input started meanwhile, keep the user's draft when the API returns 409. + + Stopping a thread holds follow-up inputs. Review state before resuming a held input. + + + + `DELETE /v1/threads/{thread_id}` stops and deletes an ordinary conversation. Save needed results first. Agent main and manager conversations require deleting their Agent instead. + + Conversation deletion does not remove a separately published chat snapshot or all workspace files. + + + + | Method and path | Use | + | --- | --- | + | `GET /v1/threads` | List by Agent, project, or purpose. Follow numbered `pagination.page` and `pages`. | + | `POST /v1/threads` | Create an ordinary chat or open an Agent's main or manager conversation. | + | `GET /v1/threads/{thread_id}` | Read details and configuration binding. | + | `PATCH /v1/threads/{thread_id}` | Change title, archive, pin, labels, or application metadata. | + | `DELETE /v1/threads/{thread_id}` | Stop and remove an ordinary conversation. | + | `POST /v1/threads/{thread_id}/inputs` | Submit new work or steer active work. | + | `PATCH /v1/threads/{thread_id}/inputs/{input_id}` | Replace queued content with an edit key. | + | `DELETE /v1/threads/{thread_id}/inputs/{input_id}` | Cancel that queued input. | + | `POST /v1/threads/{thread_id}/inputs/{input_id}/resume` | Resume a held input. | + | `GET /v1/threads/{thread_id}/items` | Read saved items with snapshot pagination. | + | `GET /v1/threads/{thread_id}/state` | Read active work, queues, partial output, and pending actions. | + | `GET /v1/threads/{thread_id}/preview` | Read the latest short message preview. | + | `GET /v1/threads/{thread_id}/files` | List files associated with this conversation. | + | `POST /v1/threads/{thread_id}/read` | Update unread tracking. Does not approve tools. | + | `PATCH /v1/threads/{thread_id}/reorder` | Set position within its current project. Cross-project moves are rejected. | + + Agent binding and provenance belong to the server. Custom metadata cannot change them. See [live events](/api/workflows/streaming) and [cancellation](/api/workflows/runs#stop-work) for execution controls. + diff --git a/content/docs/api/workflows/files.mdx b/content/docs/api/workflows/files.mdx new file mode 100644 index 0000000..507084e --- /dev/null +++ b/content/docs/api/workflows/files.mdx @@ -0,0 +1,162 @@ +--- +title: Work with files +icon: folder-kanban +description: Attach a report, get a summary file, and edit saved content without losing another change. +--- + +Give Fluso a short report and get a summary file back. This example covers upload, attachment, execution, and download. + +Use the Bash shell from [your first request](/api/first-request), plus Node 22 or later. Keep the example in its own directory. + +## Upload a report and get a summary + +Download the two examples from your workspace: + +```bash +curl --fail --silent --show-error \ + "$FLUSO_API_URL/examples/upload.mjs" -o upload.mjs && +curl --fail --silent --show-error \ + "$FLUSO_API_URL/examples/attach.sh" -o attach.sh +``` + +Read both files before running them. The example writes `report.txt` and `summary.md` locally, so use a directory where those names are unused. + +```bash +source attach.sh +``` + +It uploads a sample report, sends it to your conversation, waits for completion, and downloads the returned attachment as `summary.md`. + +Keep `input_path` for the uploaded report and `output_path` for the summary in your workspace. Use returned paths for future requests. Do not guess them from the prompt. + +If the example stops on an error, retain its upload key and receipt. Use the recovery details below before repeating a transfer. + +## Download an attachment + +A saved message can contain attachments without text. Read all items for its run, then use each attachment's path: + +```bash +api /files/download --get \ + --data-urlencode "path=$output_path" --output downloaded-summary.md +``` + +Choose a local output name you can replace. `available: false` on an attachment means its file is no longer at that path. + +## Edit without losing another change + +Read the report and its current revision: + +```bash +saved=$(api /files/read --get --data-urlencode "path=$input_path") && +printf '%s' "$saved" | jq '{content, revision}' +``` + +A revision identifies the content you read. Include it when saving your edit: + +```bash +edit_body=$(printf '%s' "$saved" | jq --arg path "$input_path" \ + '{path: $path, revision, content: (.content + "\nReviewed by me.\n")}') && +api /files/text -X PUT \ + -H 'Content-Type: application/json' -d "$edit_body" +``` + +If another writer changed the file, the save fails with 409. Read the new content and merge your edit. Keep the revision check. + +For a new file, use `overwrite: false`. Add `recursive: true` when its parent directories do not exist. Text writes allow 1 MiB of UTF-8 content. Reads default to 5 MiB. + +## Projects + +Use `GET /v1/projects` to choose a project and `GET /v1/files` to browse its files. Project IDs are storage names. Keep their exact returned values when building paths. + +Deleting a project removes its conversations and files, then retires their schedules. Save or export needed results first. + + + 1. Send `POST /v1/uploads` with the filename, MIME type, byte size, and a saved `Idempotency-Key`. + 2. POST the bytes to `upload_url` as multipart data, with returned `upload_fields` unchanged and the file last. + 3. Send `POST /v1/uploads/confirm` with `{"id":"UPLOAD_ID"}`. + 4. Read `GET /v1/uploads/{upload_id}` until it finishes. + 5. Attach the returned `target_path` to your next input. + + Do not send your Fluso bearer token to `upload_url`. The downloadable example uses text files. Supply the correct MIME type for other files, such as PDFs. + + `confirmed` means the file is ready. `history_unavailable` means it was saved without a new recorded version. Show that warning. For `failed`, `cancelled`, or `conflict`, inspect the saved error before another transfer. + + A timeout does not prove import failure. Read the existing upload. A confirmed receipt also does not promise that later edits left its bytes unchanged. + + + + Versions and comments apply under `/files/` and `/projects/{project_id}/files/`, excluding hidden directories. + + Read `/v1/files/versions` before restoring a file. Download a version through `/v1/files/versions/content` with its `path` and `commit`. A missing version returns 404, never the current bytes. + + Restore preserves the replaced bytes as a version first. If preservation fails, review the warning before permitting `allow_history_loss: true`. Other files remain unchanged. + + The same history protection applies to writes, uploads, copies, and moves. Directory copies can partly succeed. Inspect the destination before retrying. + + File comments can refer to a passage, slide, sheet range, or image region. A comment does not start an Agent run. + + + + | Method and path | Use | + | --- | --- | + | `GET /v1/projects` | List projects. Follow `next_cursor` as `after`. | + | `POST /v1/projects` | Create a project. Its name becomes its ID. | + | `GET /v1/projects/{project_id}` | Read details and conversation counts. | + | `PATCH /v1/projects/{project_id}` | Change description, icon, labels, archive, or pin settings. Does not rename it. | + | `DELETE /v1/projects/{project_id}` | Delete its conversations and files, then retire schedules. | + | `GET /v1/projects/{project_id}/export` | Stream an export download, not JSON. | + | `GET /v1/projects/{project_id}/search` | Search project files with `q`. | + | `GET /v1/projects/{project_id}/files/origins` | Read recorded file provenance. Missing entries mean unknown origin. | + | `PATCH /v1/projects/{project_id}/files/pins` | Add or remove relative paths such as `files/report.pdf`. | + + Names use 1 to 64 ASCII letters, digits, single spaces, hyphens, or underscores, starting with a letter or digit. URL-encode names in paths. + + Deleting Home also removes its work. An empty Home is recreated on first use. Retry a failed deletion to finish schedule cleanup. If you reuse the project name, deletion addresses the new project. + + + + | Method and path | Use | + | --- | --- | + | `POST /v1/uploads` | Prepare transfer with `file_name`, `mime_type`, and byte `file_size`. | + | `POST /v1/uploads/confirm` | Confirm transfer with `id`. Repeating confirmation is safe. | + | `GET /v1/uploads/{upload_id}` | Read import progress and the final `target_path`. | + | `GET /v1/uploads` | List receipts, following `next_cursor` as `after`. | + | `DELETE /v1/uploads/{file_id}` | Cancel a pending transfer or dismiss a saved-file history warning. | + + Save an `Idempotency-Key` when preparing a transfer. Retrying the same settings returns its receipt. Changed settings return 409. At most four uploads can be pending. + + A retry after transfer credentials expire can return a receipt without `upload_url`. Read or confirm that upload before starting another. A processing or completed receipt needs no repeat transfer. + + Confirmation can return 200 while import is still processing. Poll until a final status. Receipts remain for seven days after completion. Receipt expiry does not delete the saved file. + + Cancelling a pending upload removes temporary bytes. Dismissing `history_unavailable` keeps the saved file. This endpoint does not delete workspace content. + + + + | Method and path | Use | + | --- | --- | + | `GET /v1/files` | Browse a directory, optionally recursively. Keep filters while following `next_cursor`. | + | `GET /v1/files/stat` | Read metadata for a workspace `path`. | + | `GET /v1/files/read` | Read UTF-8 content and its revision. | + | `GET /v1/files/download` | Stream raw bytes and download headers. | + | `PUT /v1/files/text` | Write text, optionally with a revision or `overwrite: false`. | + | `POST /v1/files/edit` | Replace matching text. `replace_all: true` changes every occurrence. | + | `POST /v1/files/directories` | Create a directory. `recursive: true` creates missing parents. | + | `POST /v1/files/move` | Move or rename. Existing destinations require explicit overwrite. | + | `POST /v1/files/copy` | Copy. Directory copies require `recursive: true`. | + | `DELETE /v1/files` | Supply `path` in the query. Nonempty directories also need `recursive=true`. | + | `POST /v1/files/batch-delete` | Delete selected paths and report each result. | + | `GET /v1/files/versions` | List history and the current file fingerprint. | + | `PATCH /v1/files/versions` | Rename a recorded version. | + | `GET /v1/files/versions/{commit}` | Read version metadata without its bytes. | + | `GET /v1/files/versions/content` | Download the selected version's exact bytes. | + | `POST /v1/files/versions/restore` | Restore one file, preserving the replaced version first. | + | `GET /v1/files/comments` | Read file comments across conversations. | + | `POST /v1/files/comments` | Add a note with a passage or object anchor. | + | `PATCH /v1/files/comments` | Edit a note, anchor, or status. | + | `DELETE /v1/files/comments` | Remove a comment by ID. | + + Script-created files may have no history until delivered. `versionable: false` means an overwrite cannot preserve the current bytes. Do not treat version history as a complete workspace backup. + + File deletion revokes public links before removing content. If deletion fails, links remain revoked. Retry deletion to remove the remaining content. + diff --git a/content/docs/api/workflows/meta.json b/content/docs/api/workflows/meta.json new file mode 100644 index 0000000..1201821 --- /dev/null +++ b/content/docs/api/workflows/meta.json @@ -0,0 +1,16 @@ +{ + "title": "Use the API", + "icon": "workflow", + "defaultOpen": false, + "pages": [ + "conversations", + "runs", + "streaming", + "agents", + "files", + "connections", + "schedules", + "workspace", + "usage" + ] +} diff --git a/content/docs/api/workflows/runs.mdx b/content/docs/api/workflows/runs.mdx new file mode 100644 index 0000000..43b619b --- /dev/null +++ b/content/docs/api/workflows/runs.mdx @@ -0,0 +1,109 @@ +--- +title: Runs and retries +icon: activity +description: Find out what happened, recover a result, or stop work without submitting it twice. +--- + +A request timed out, or the connection closed before the answer arrived. Start by checking the work Fluso already accepted. + +Use the Bash shell from [your first request](/api/first-request). It contains the `api` helper and saved IDs. + +## Check the run + +```bash +api "/threads/$thread_id/runs/$run_id" | jq '{status, error}' +``` + +| Status | Your next step | +| --- | --- | +| `queued` or `running` | Wait, then check again. | +| `waiting_action` | Read thread state and [handle the pending action](/api/workflows/connections#handle-a-waiting-run). | +| `held` | Review the queue in thread state before resuming an input. | +| `completed` | [Read every result page](/api/workflows/conversations#read-message-history). | +| `failed` or `cancelled` | Read the error and partial results before deciding what to do next. | + +A completed run can contain a failed tool call. A failed run can still have changed an external service. Check the answer and tool results before repeating work. + +## Recover after a timeout + +| What you have | What to do | +| --- | --- | +| A receipt with `thread_id` and `run_id` | Read that run and its saved output. | +| A saved key and body, but no receipt | Repeat the original submission with both unchanged. | +| A disconnected stream | Reconnect for new events, then read saved state and items. | + +For a lost [follow-up response](/api/workflows/conversations#send-a-follow-up), resend the saved request: + +```bash +receipt=$(api "/threads/$thread_id/inputs" \ + -H "Idempotency-Key: $input_key" \ + -H 'Content-Type: application/json' -d "$input_body") && +run_id=$(printf '%s' "$receipt" | jq -er '.run_id') +``` + +Do not generate another key for this retry. A new key can start duplicate work. For the quickstart's initial submission, retry `/threads` instead of `/threads/$thread_id/inputs`. + +Input receipts remain until 24 hours after completion. After that, inspect the saved run before submitting again. Saved runs remain readable until their conversation is deleted. + + + An error from `POST /v1/threads` can include `error.details.thread_id`. Keep that ID and inspect its state. Thread creation alone does not prove that Fluso accepted the input. + + After resolving the error, send the original input and key to that thread's `/inputs` endpoint. This can recover an uncertain acceptance within the retry window. + + +## Stop work + +To cancel only the saved run: + +```bash +api "/threads/$thread_id/runs/$run_id/cancel" -X POST +``` + +Then check its status until execution stops. Cancellation cannot undo an external action that already completed. + +To stop the conversation and hold its follow-up messages, use `POST /v1/threads/{thread_id}/stop` instead. Review the queue before resuming held inputs. + +## Decide whether to retry + +For temporary read failures, wait before retrying. Increase the delay between attempts, set a maximum wait, and honor `Retry-After`. Stop when `error.retryable` is explicitly false. The quickstart's read helpers already do this. + +For writes, use the operation's own recovery rule. Inputs use saved keys and bodies. Uploads use their receipts. Schedules use their IDs. Configuration edits use revisions. + +A failed run stays failed when you resend its old key. Review partial results before choosing a new message and key. + + + | Response | Action | + | --- | --- | + | 400 or 422 | Correct the request fields. | + | 401 | Replace the credential or sign in again. | + | 402 | Check the account allowance and any `resets_at` value. | + | 403 | Use the required access level or signed-in app session. | + | 404 | Check the workspace and resource ID. The resource may no longer exist. | + | 409 | Read the resource before resolving the conflict. Keep unsent edits. | + | 410 | Follow the error's instructions for the expired resource or approval. | + | 413 or 507 | Reduce the transfer or free workspace storage. | + | 408, 429, 500, 502, 503, or 504 | Retry transient reads with a delay. Preserve keys for uncertain writes. | + + Errors include `error.code` and `error.message`, with details and retry guidance where available. Keep `request_id` or `X-Request-ID` for support. A request ID is not an idempotency key. + + Use UUIDs for new input keys. Accepted characters are ASCII letters, digits, `_`, `-`, `.`, `:`, and `@`, with a maximum of 128 characters. A single dot, consecutive dots, and the `agent-turn:` and `agent-result:` prefixes are reserved. + + For historical run IDs containing `/`, use `GET /v1/runs` with URL-encoded `thread_id` and `run_id` query parameters. Read output through the items endpoint's `run_id` filter. + + + + | Method and path | Use | + | --- | --- | + | `GET /v1/runs` | List saved runs or find one through query filters. | + | `GET /v1/threads/{thread_id}/runs` | List a conversation's runs. Follow `next_cursor` as `after`. | + | `GET /v1/threads/{thread_id}/runs/{run_id}` | Read status, error, and recorded execution settings. | + | `GET /v1/threads/{thread_id}/runs/{run_id}/usage` | Read recorded usage or `null` when unreported. | + | `POST /v1/threads/{thread_id}/runs/{run_id}/cancel` | Request cancellation of this run. | + | `POST /v1/threads/{thread_id}/stop` | Stop active work and hold follow-ups. | + + An input accepts up to 200,000 text characters and 25 attachments. A thread holds up to 100 queued inputs and 50 steering inputs per active turn. + + Each thread retains up to 1,000 recent input receipts. At capacity, admission refuses new work while preserving existing retry receipts. Waiting for a local timeout does not clear accepted work. + + Merge `state.runs` by ID when reading multiple item pages. An old item without a saved run has an unknown outcome. Its text alone does not prove success. + diff --git a/content/docs/api/workflows/schedules.mdx b/content/docs/api/workflows/schedules.mdx new file mode 100644 index 0000000..c72dfdc --- /dev/null +++ b/content/docs/api/workflows/schedules.mdx @@ -0,0 +1,77 @@ +--- +title: Schedule work +icon: calendar-clock +description: Ask an Agent to review its notes every weekday, then inspect or pause the schedule. +--- + +A schedule sends a message to an Agent at a chosen time. In the app, schedules are called **routines**. + +First [create the meeting assistant](/api/workflows/agents) and give it some notes. Keep that example's `agent_id` and `agent_thread_id` in the same Bash shell. + +## Create a weekday review + +This schedule asks the assistant to review its conversation every weekday at 9 AM in Zurich. Change the message and timezone for your work. + +```bash +schedule_id=$(uuidgen) && +schedule_body=$(jq -nc --arg id "$schedule_id" --arg thread "$agent_thread_id" \ + '{id: $id, thread_id: $thread, + message: ("Review the meeting notes in this conversation. " + + "Summarize decisions still open and actions due next."), + cron: "0 9 * * 1-5", timezone: "Europe/Zurich"}') && +api "/agents/$agent_id/schedules" \ + -H 'Content-Type: application/json' -d "$schedule_body" +``` + +The response includes `next_run_at`. Check that time before leaving the schedule active. Keep `schedule_id` and `schedule_body` for retries. A new ID creates another schedule. + +For a one-time task, replace `cron` with `at`, using a future timestamp with a UTC offset. For example, the format is `2030-01-02T09:00:00+01:00`. + +## Review and change future work + +Read this Agent's schedules: + +```bash +api "/agents/$agent_id/schedules" | jq '.data' +``` + +Look at `last_run.status` for the previous result. Use its `run_id` and the schedule's `thread_id` to [read the output](/api/workflows/conversations#read-message-history). + +Pause future submissions when you no longer need them: + +```bash +api "/schedules/$schedule_id" -X PATCH \ + -H 'Content-Type: application/json' -d '{"status":"paused"}' +``` + +Check the schedule list after saving. Use `status: "active"` to resume, or `DELETE /v1/schedules/{schedule_id}` to remove it. + +Pausing or deleting a schedule does not cancel work already accepted. [Cancel that run separately](/api/workflows/runs#stop-work). + + + Send changed fields with `PATCH /v1/schedules/{schedule_id}`. Omitted fields stay unchanged. Do not send `null` to clear fields. + + To switch between recurring and one-time timing, send only the new `cron` or `at` field. It replaces the previous timing. + + Use an IANA timezone such as `Europe/Zurich`. At daylight-saving changes, skipped local times move forward by the gap. Repeated times run at their first occurrence. + + + + The daemon host must be awake for work to run. After downtime, missed recurring runs combine into one catch-up run. + + Delivery failures can pause a schedule. A failed accepted run does not automatically pause recurring work. + + A one-time schedule stops submitting after acceptance, even if its run later fails. Inspect the saved run before deciding whether to request that work again. + + + + | Method and path | Use | + | --- | --- | + | `POST /v1/agents/{agent_id}/schedules` | Create with a caller-generated UUID and exactly one of `cron` or `at`. | + | `GET /v1/agents/{agent_id}/schedules` | List schedules for one Agent. | + | `GET /v1/schedules` | List all schedules. Use `attention=true` for delivery problems. | + | `PATCH /v1/schedules/{schedule_id}` | Edit, pause, or resume. | + | `DELETE /v1/schedules/{schedule_id}` | Prevent future submissions. | + + Follow numbered `pagination.page` and `pages` in list responses. The target conversation must belong to the Agent. + diff --git a/content/docs/api/workflows/streaming.mdx b/content/docs/api/workflows/streaming.mdx new file mode 100644 index 0000000..1b340fb --- /dev/null +++ b/content/docs/api/workflows/streaming.mdx @@ -0,0 +1,72 @@ +--- +title: Live updates +icon: radio +description: Show progress as Fluso works, and recover the answer after a dropped connection. +--- + +Add live updates when your interface needs to show progress before the answer is ready. Keep saved results as the source for the completed conversation. + +## Try the watcher + +Use the [quickstart's shell](/api/first-request) and Node 22 or later. Download the watcher from your workspace: + +```bash +curl --fail --silent --show-error \ + "$FLUSO_API_URL/examples/watch.mjs" -o watch.mjs && +cat watch.mjs +``` + +After reading it, watch the saved run: + +```bash +node watch.mjs "$thread_id" "$run_id" +``` + +The watcher prints saved conversation updates. It reads every page and reconnects after temporary failures without resubmitting input. Press **Ctrl+C** to stop watching. That does not cancel the run. + +## Connect without missing saved work + +Your client needs two sources: + +| Source | Use it for | +| --- | --- | +| Event stream | Show text and tool progress as it arrives. | +| Saved state and items | Recover missed updates and read the final answer. | + +Open the stream first, then read state and every item page. Match updates by input, run, and item IDs. Replace temporary text with its saved item to avoid duplicates. + +After a disconnection, repeat that sequence. Continue checking saved state periodically while work is active. `Last-Event-ID` does not replay missed events. + + + ```bash + curl --no-buffer --fail-with-body --silent --show-error \ + "$FLUSO_API_URL/threads/$thread_id/events" \ + -H "Authorization: Bearer $FLUSO_API_TOKEN" + ``` + + The response uses Server-Sent Events (SSE). Each `data` field contains a `ThreadEvent` JSON object. A blank line ends a frame. + + Buffer incomplete frames across network chunks. Ignore unknown event types and keepalive comments. Use a client that supports an Authorization header. Keep tokens out of URLs. + + If you use `stream: true` during input submission, save the first `input.accepted` receipt. It contains the IDs for recovery if the stream fails. + + For a daemon behind a proxy, disable response buffering for this stream. + + + + `progress.tool_start` and `progress.tool_end` describe tool execution. Your client displays these events. It does not execute the tool itself. + + A preview can omit arguments or results. `args_truncated: true` means the arguments are incomplete. If that flag is absent, completeness is unknown. + + For [tool approval](/api/workflows/connections#handle-a-waiting-run), fetch the pending action's actual arguments before asking the user to decide. + + + + | Method and path | Use | + | --- | --- | + | `GET /v1/threads/{thread_id}/events` | Stream new events. Optional `input_id` follows one input. | + | `GET /v1/threads/{thread_id}/state` | Recover active work, queues, partial output, and pending actions. | + | `GET /v1/threads/{thread_id}/items` | Recover saved messages and tool results. Follow every page. | + + The watcher's run ID is optional. Supply it to check the run even when it has no saved messages. A closed stream does not establish whether work finished. + diff --git a/content/docs/api/workflows/usage.mdx b/content/docs/api/workflows/usage.mdx new file mode 100644 index 0000000..794829f --- /dev/null +++ b/content/docs/api/workflows/usage.mdx @@ -0,0 +1,45 @@ +--- +title: Check usage +icon: chart-no-axes-combined +description: See what a run used, then inspect the model calls behind it. +--- + +Use the saved conversation and run IDs to inspect the cost of a task. The examples use the Bash shell from [your first request](/api/first-request). + +## Check one run + +```bash +api "/threads/$thread_id/runs/$run_id/usage" | jq . +``` + +The response contains `tokens`, estimated `cost`, and `entry_count`. A response of `null` means no usage was reported yet. A null `cost` means pricing is unknown, not zero. + +## See which calls contributed + +Filter individual usage records to that run: + +```bash +api /token-usage/entries --get \ + --data-urlencode "thread_id=$thread_id" \ + --data-urlencode "run_id=$run_id" | jq . +``` + +Use the records to compare model calls within the task. Further filters include `provider`, `model`, `since`, and `limit`. + +## Read workspace totals + +```bash +api /token-usage | jq '{totals, last_updated}' +``` + +Reports can arrive after execution. They are recorded estimates, not a final bill. For a daemon using your provider key, check that provider's billing too. + + + | Method and path | Use | + | --- | --- | + | `GET /v1/token-usage` | Workspace totals and session summaries. | + | `GET /v1/token-usage/entries` | Individual records with optional filters. | + | `GET /v1/threads/{thread_id}/runs/{run_id}/usage` | One run's recorded usage, or `null`. | + + Read access is sufficient. These queries do not start workspace compute. Responses use snake_case fields, including `last_updated` and `entry_count`. + diff --git a/content/docs/api/workflows/workspace.mdx b/content/docs/api/workflows/workspace.mdx new file mode 100644 index 0000000..a9157cd --- /dev/null +++ b/content/docs/api/workflows/workspace.mdx @@ -0,0 +1,100 @@ +--- +title: Workspace tools +icon: folder-cog +description: Inspect skills, organize labels, and manage runtime readiness. +--- + +Use these operations to choose skills, organize conversations, and check whether the workspace can run work. + +The examples use the authenticated `api` helper from [your first request](/api/first-request). + +## Choose skills for an Agent + +List the skills already available in this workspace: + +```bash +api /agent/skills | jq '.data' +``` + +For a meeting assistant, look for a skill that works with your document format. Use its exact name when updating the [Agent's configuration](/api/workflows/agents#improve-its-instructions). + +Built-in skills are already available. For a marketplace skill, read its detail and install it first. Then save its name in the [Agent's configuration](/api/workflows/agents). + +Selecting a missing skill does not install it. Removing a skill does not remove its name from existing Agent configurations. + + + | Method and path | Use | + | --- | --- | + | `GET /v1/agent/skills` | List built-in and workspace skills. | + | `GET /v1/agent/skills/marketplace` | Browse the installable catalog. | + | `GET /v1/agent/skills/marketplace/{skill_id}` | Read catalog and installation metadata. | + | `GET /v1/agent/skills/marketplace/{skill_id}/detail` | Review a skill's instructions before installation. | + | `GET /v1/agent/skills/repo/{skill_id}/detail` | Read a built-in skill's instructions. | + | `GET /v1/agent/skills/workspace/{skill_id}/detail` | Read an installed skill's instructions. | + | `POST /v1/agent/skills/marketplace/{skill_id}/install` | Install the selected catalog skill. | + | `DELETE /v1/agent/skills/marketplace/{skill_id}` | Remove its installed marketplace copy. | + | `DELETE /v1/agent/skills/workspace/{skill_id}` | Remove the named workspace skill directory. | + + Reading a skill document does not execute it. After removal, update Agents that selected the skill or reinstall it. + + +## Organize with labels + +For example, mark the quickstart conversation for review. Create a label first: + +```bash +label=$(api /agent/labels \ + -H 'Content-Type: application/json' -d '{"name":"API review"}') && +label_id=$(printf '%s' "$label" | jq -er '.id') +``` + +If that label already exists, reuse its ID from `GET /v1/agent/labels`. After a lost creation response, check that list before creating another. + +Add the label to the conversation without removing its existing labels: + +```bash +thread=$(api "/threads/$thread_id") && +label_body=$(printf '%s' "$thread" | jq --arg id "$label_id" \ + '{label_ids: ((.label_ids // []) + [$id] | unique)}') && +api "/threads/$thread_id" -X PATCH \ + -H 'Content-Type: application/json' -d "$label_body" +``` + +The updated conversation now includes this label's ID. Projects use the same `label_ids` field. Read the latest object before changing its labels. + + + | Method and path | Use | + | --- | --- | + | `GET /v1/agent/labels` | Read the label registry. | + | `POST /v1/agent/labels` | Create with `name` and optional hex `color`. | + | `PATCH /v1/agent/labels` | Send `id` with a changed `name`, `color`, or `order`. | + | `DELETE /v1/agent/labels` | Remove the query's `id`. Keep its conversations and files. | + + +## Check runtime readiness + +Input submission starts the runtime when needed. To check readiness without sending a message: + +```bash +api /agent/runtime/status | jq '{status, busy, can_wake, can_stop}' +``` + +Use `can_wake` and `can_stop` when offering those controls. A busy runtime can refuse a stop. Stop active work through its thread or run first. Respect `Retry-After` on temporary readiness errors. + + + +| Method and path | Use | +| --- | --- | +| `GET /v1/agent/runtime/status` | Read execution and storage readiness. | +| `POST /v1/agent/runtime/wake` | Start if needed, then wait for readiness without sending a chat message. | +| `POST /v1/agent/runtime/stop` | Release compute while keeping saved workspace data. | + + + + + `POST /v1/agent/workspace/reset` is destructive. It clears conversations, projects, workspace files, and installed or custom workspace skills. It also retires schedules. + + Saved Agents, their knowledge files, and account settings remain. Home is recreated automatically. Reassign Agents from removed projects before reopening their conversations. Reinstall the workspace skills they need. + + Use individual file, thread, or project deletion for targeted cleanup. + diff --git a/content/docs/deployment-models.mdx b/content/docs/deployment-models.mdx index dc29e58..0992015 100644 --- a/content/docs/deployment-models.mdx +++ b/content/docs/deployment-models.mdx @@ -2,7 +2,7 @@ title: Deployment models sidebarTitle: Overview icon: server-cog -description: Compare Fluso Cloud, dedicated AWS VPC, planned Azure VNet, and scoped on-premises deployments. +description: Compare Fluso Cloud, a workspace on your machine, and Enterprise deployments. --- Your deployment model decides who operates Fluso and where its runtime, durable data, and diagnostics can live. It does not by itself control where connected Apps or external model providers process data. @@ -10,6 +10,7 @@ Your deployment model decides who operates Fluso and where its runtime, durable | Model | Availability | Operations | | --- | --- | --- | | Fluso Cloud | Available | Managed by Fluso | +| Fluso Local | Contact Fluso for a matching Mac or Linux package | You operate one owner's workspace | | Dedicated AWS VPC | Supported for scoped Enterprise deployments | Responsibilities agreed during deployment design | | Azure VNet | Coming soon | Not available today | | On-premises | Scoped Enterprise engagement | Responsibilities agreed before implementation | @@ -20,6 +21,12 @@ Fluso Cloud is the standard managed service. It runs on AWS with European hostin Choose it when you want to start without operating infrastructure. See [Legal](/resources/legal) for Fluso's privacy policy. +## Fluso Local + +Install the daemon to run one owner's workspace on an Apple Silicon Mac or a supported Linux host. Conversations and files stay on that host. You manage its provider credentials, service, updates, and backups. + +The desktop app connects to this workspace. It does not install or update the daemon. This is separate from an Enterprise deployment of the whole platform. Start with [Set up Fluso Local](/workspaces/setup). + ## Dedicated AWS VPC A dedicated AWS VPC deployment is available for Enterprise customers whose network or residency requirements do not fit the managed service. It is a scoped deployment, not a self-service switch. @@ -59,8 +66,9 @@ Traces can include prompt and response text. For a dedicated or on-premises depl ## Choose a model - Start with Fluso Cloud when managed operations and European hosting meet the requirement. +- Use [Fluso Local](/workspaces) when you want to operate a workspace on your own machine. - Scope an AWS VPC deployment when you need a dedicated AWS network boundary. - Treat Azure VNet as future availability, not a current option. - Scope on-premises only after Fluso validates the infrastructure, residency, provider, telemetry, and support requirements. -For a custom deployment, [contact Fluso](mailto:sales@premai.io). For the component boundaries behind these models, read [Architecture](/developers/api-ref/architecture). +For a custom deployment, [contact Fluso](mailto:sales@premai.io). diff --git a/content/docs/developers/api-ref/agents-and-versions.mdx b/content/docs/developers/api-ref/agents-and-versions.mdx deleted file mode 100644 index 7c9fa23..0000000 --- a/content/docs/developers/api-ref/agents-and-versions.mdx +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: Agents -sidebarTitle: Agents -icon: bot -description: Create an Agent, update its current setup safely, and attach reference files. ---- - -These are authenticated beta client routes. Agent fields use camelCase and configurations use `schemaVersion: 2`. The current model has instructions, skills, app policies, and knowledge files. It has no separate description, goal, or thread-management mode. - -For the user workflow, see [Create and refine](/developers/agent-builder). - -## Create and read - - - -Creating a definition does not create or run a conversation. The project must already exist. `Home` is the default. - -```bash -curl "$FLUSO_API/v1/agents" \ - -H "Authorization: Bearer $FLUSO_TOKEN" \ - -H 'Content-Type: application/json' \ - -d '{ - "name": "Release reviewer", - "instructions": "Review supplied evidence. Separate blockers from missing information. Do not publish or contact anyone.", - "conversationStarters": ["Review this release candidate"], - "responseMode": "high", - "projectName": "Home", - "skills": ["pdf", "docx"], - "connectors": {} - }' -``` - -The `201` response contains `agentId`, `currentConfigId`, and `config`. Save the returned IDs. An optional UUID `creationId` supports retrying the same creation. - -| Method and path | Result | -| --- | --- | -| `GET /v1/agents?page=1&limit=50&q=release` | Agent summaries and pagination. `purpose` is derived from instructions | -| `GET /v1/agents?all=true` | The complete bounded library in one response | -| `GET /v1/agents/{agentId}` | Current Agent record and configuration | -| `GET /v1/agents/{agentId}/chats` | Main conversation, delegated sessions, and Manager, including role and earlier-setup markers | - -## Update without overwriting someone else's edit - - - -Read the Agent first. Send its `currentConfigId` as `baseConfigId`, with only the fields you intend to change. - -```json -{ - "baseConfigId": "", - "instructions": "Review supplied evidence. Missing evidence remains unresolved. Do not publish or contact anyone." -} -``` - -A stale revision returns `409 STALE_AGENT_CONFIG`. Read again and reapply the intended change. Do not blindly resend all fields from an old form. - -Omitted fields stay unchanged. Submitted lists and connector maps replace the whole field. - -| Field | Meaning | -| --- | --- | -| `skills: null` | All skills available to an ordinary chat, including later additions | -| `skills: []` | No selected skills | -| `connectors: null` or `{}` | No app grants | -| `connectors: {"": "allow"}` | Selected connection permitted, subject to account and approval policies | -| `read_only` / `deny` | Restrict that connection to classified read-only tools, or block it | - -The main conversation follows the current setup on its next accepted turn. Running turns and existing delegated sessions retain their accepted configuration. Changing `projectName` does not move existing conversations. - -Configurations are stored internally, but there is no current public version-list or rollback endpoint. - -## Attach knowledge - - - -Upload one multipart `file`, or use `POST /v1/agents/{agentId}/knowledge-files/from-workspace` with `{"path": "/projects/Home/files/rubric.md"}`. - -The response is a knowledge reference with `fileId`, `name`, `fileName`, and `bytes`. Attaching stores a copy. It does not add that reference to the active setup. PATCH `knowledgeFiles` with the full desired list and the latest `baseConfigId` to save it. Preserve entries you still want. - -Limits: 25 knowledge entries, 20 MiB per file, 4,000 instruction characters, three starters of 200 characters each, and 100 Agents per user. Workspace storage limits also apply. - -## Copy, share, or delete - -| Method and path | Behavior | -| --- | --- | -| `POST /v1/agents/{agentId}/duplicate` with `{}` | Independent setup and knowledge copy. No conversations or routines | -| `POST /v1/agents/{agentId}/star` with `{"starred": true}` | Set the library star | -| `DELETE /v1/agents/{agentId}` | Delete the Agent and its conversations, remove schedules, and revoke its public link | - -Sharing uses [separate snapshot routes](/developers/api-ref/sharing). To do work, [open the main conversation and send a message](/developers/api-ref/threads-and-messages). diff --git a/content/docs/developers/api-ref/architecture.mdx b/content/docs/developers/api-ref/architecture.mdx deleted file mode 100644 index 56f35ac..0000000 --- a/content/docs/developers/api-ref/architecture.mdx +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: Architecture -sidebarTitle: Architecture -icon: network -description: Follow a message through the platform and understand what survives a runtime restart. ---- - -Fluso separates the client, platform records, runtime compute, and durable user files. This explains why you can leave a chat, return to queued work, and reuse an Agent without rebuilding its setup. - - - -## From a message to a result - -1. The client sends an authenticated message with its conversation and request IDs. -2. The backend checks identity and usage, then forwards work through the gateway to the user's runtime. -3. The runtime admits the request into the conversation's durable queue. A session worker runs the turn with its accepted Agent setup. -4. Tools read or change workspace files and call connected apps through MCP, subject to access and approval rules. -5. Progress streams to the client. History and request state let it recover after a connection drops. - -A main Agent conversation and its Manager have separate histories. The Manager edits one Agent's setup. The main conversation performs its work and coordinates delegated sessions. - -## What is stored where - -| Boundary | Durable state | -| --- | --- | -| Platform database | User and access records, app connections, routine schedules, public share records | -| User storage | Agent definitions, knowledge files, projects, skills, conversations, request ledgers, and queues | -| Project working memory | Bounded summaries and evidence-backed observations within that project | -| External apps | Their own data and actions. Selected results may be copied into Fluso by the requested work | - -Runtime compute can be suspended or replaced without deliberately deleting those stored records. Current deployment paths include local Docker, AWS ECS, and MicroVM runtimes with ZeroFS storage. Availability depends on the deployment. - -## Configuration and context are different - -A saved Agent edit creates a new configuration. The main conversation uses it on its next turn. Active turns and existing delegated sessions keep the setup they accepted. Skill files and project files remain live shared resources. - -Separate conversations do not imply separate private filesystems. Agents within one user's workspace can use its shared files. Project context and knowledge selection guide the model. They are not a filesystem security boundary. - -## Routine and result delivery - -The scheduler sends a due routine through normal request admission using a stable ID for that occurrence. A busy conversation queues it. The scheduler avoids another overlapping occurrence of the same routine, retries temporary delivery failures, and records problems for Inbox. - -Delegated sessions return requested results to their parent. The main conversation must still reconcile those results with the user's latest direction and actual files. A returned report does not grant approval for a new action. - -## Recovery is not rollback - -A dropped stream does not prove a run failed. The client reconciles with saved history and status. Runtime recovery can resume interrupted work, but an external action that already succeeded is not automatically undone. - -Use conversation history, routine state, and [run status](/developers/api-ref/runs) to distinguish queued work, approval waits, failures, and completed output. Avoid resubmitting an uncertain operation under a new ID without checking it. - -See [Authentication](/developers/api-ref/authentication) for the current beta API boundary. diff --git a/content/docs/developers/api-ref/authentication.mdx b/content/docs/developers/api-ref/authentication.mdx deleted file mode 100644 index ce2a193..0000000 --- a/content/docs/developers/api-ref/authentication.mdx +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: Authentication -sidebarTitle: Authentication -icon: key-round -description: Understand bearer authentication and the limits of the current beta client API. ---- - -This reference documents the routes used by Fluso clients on the current development branch. It is not a promise that every feature is enabled in every deployed build. These beta contracts may change. - -Use the API host and authenticated session for the same environment. Production uses `https://api.fluso.ai`. Development clients must use their development API and identity environment. - -```bash -export FLUSO_API='https://' -export FLUSO_TOKEN='' - -curl "$FLUSO_API/v1/auth/me" \ - -H "Authorization: Bearer $FLUSO_TOKEN" -``` - -Keep tokens out of logs and source control. A token acts for its authenticated user. Supplying another user's IDs does not grant access. An `X-API-Key` header alone is not a replacement for the bearer session on these workspace proxy routes. - -## Read the authenticated identity - - - -Returns `user` and `api_key_id`. The latter is an identifier, not a secret API key. - -```json -{ - "user": { - "id": "22222222-2222-4222-8222-222222222222", - "email": "developer@example.com", - "name": "Developer", - "picture": null, - "created_at": "2026-10-08T09:00:00" - }, - "api_key_id": "33333333-3333-4333-8333-333333333333" -} -``` - -## Client sign-in is not generic CLI onboarding - -The backend has `/v1/auth/client/start`, `/complete`, `/exchange/{code}`, and `/refresh` routes for client handoff. The current frontend's completed handoff supports Telegram. Registering an arbitrary `client: "cli"` does not produce a working browser-to-CLI flow. - -For the supported product flow, use [Telegram setup](/remote/telegram). For another integration, confirm its sign-in and token handling with [support](mailto:support@premai.io) before building against the beta routes. - -A supported client exchanges a short-lived, single-use code for an access token and refresh token bound to its client identity. `POST /v1/auth/client/refresh` accepts `{"refresh_token": "..."}` and returns refreshed credentials and `api_key_id`. - -## Read failures correctly - -| Response | Meaning | -| --- | --- | -| `401` | Missing, invalid, or expired authentication | -| `403` | The authenticated user is not allowed to complete the request | -| `404` | The requested resource is unavailable to this user | -| `409` | A state conflict requires inspection, such as a stale Agent revision | -| `429` | A rate or usage limit was reached. Respect retry guidance | -| `502` / `503` | A service or runtime is unavailable. An interrupted write may still need verification | - -Do not treat a network failure as proof that a write did not happen. Use operation-specific IDs and reread state before repeating work. - -Next: [Agents](/developers/api-ref/agents-and-versions), [Threads and messages](/developers/api-ref/threads-and-messages), and [Runs](/developers/api-ref/runs). diff --git a/content/docs/developers/api-ref/files-and-projects.mdx b/content/docs/developers/api-ref/files-and-projects.mdx deleted file mode 100644 index 77124c4..0000000 --- a/content/docs/developers/api-ref/files-and-projects.mdx +++ /dev/null @@ -1,233 +0,0 @@ ---- -title: Files and projects -sidebarTitle: Files & projects -icon: folder-kanban -description: Work with durable project metadata and files in a user's Agent workspace. ---- - -Workspace projects and files use the `/v1/agent/*` routes. They belong to the authenticated user's durable workspace, outside disposable runtime compute. - -An [Agent](/developers/api-ref/agents-and-versions) places its main conversation in the configured project when that conversation is first created. Changing its setup later does not move existing conversations. - -## List projects - - - -Returns workspace projects and their thread summaries. - -```bash title="Request" -curl "$FLUSO_API/v1/agent/projects?includeArchived=false" \ - -H "Authorization: Bearer $FLUSO_TOKEN" -``` - -```json title="Response: 200" -{ - "projects": [ - { - "name": "Release Review", - "goal": "Decide launch readiness", - "createdAt": "2026-08-31T09:00:00Z", - "updatedAt": "2026-08-31T09:00:00Z", - "threads": [] - } - ] -} -``` - -## Create a project - - - -Creates a workspace project and its context file. - -```bash title="Request" -curl "$FLUSO_API/v1/agent/projects" \ - -X POST \ - -H "Authorization: Bearer $FLUSO_TOKEN" \ - -H 'Content-Type: application/json' \ - -d '{ - "name": "Release Review", - "goal": "Decide launch readiness", - "instructions": "Keep evidence and decisions in this project." - }' -``` - -```json title="Response: 201" -{ - "name": "Release Review", - "goal": "Decide launch readiness", - "instructions": "Keep evidence and decisions in this project.", - "createdAt": "2026-08-31T09:00:00Z", - "updatedAt": "2026-08-31T09:00:00Z", - "threads": [] -} -``` - -## Update a project - - - -Updates the project named in the request body. - -```bash title="Request" -curl "$FLUSO_API/v1/agent/projects" \ - -X PATCH \ - -H "Authorization: Bearer $FLUSO_TOKEN" \ - -H 'Content-Type: application/json' \ - -d '{ - "name": "Release Review", - "goal": "Decide launch readiness and record follow-up owners" - }' -``` - -```json title="Response: 200, selected fields" -{ - "name": "Release Review", - "goal": "Decide launch readiness and record follow-up owners", - "updatedAt": "2026-08-31T09:05:00Z", - "threads": [] -} -``` - -## Export a project - - - -Streams the named project as a ZIP archive. - -```bash title="Request" -curl -G "$FLUSO_API/v1/agent/projects/export" \ - -H "Authorization: Bearer $FLUSO_TOKEN" \ - --data-urlencode 'name=Release Review' \ - -o release-review.zip -``` - -```http title="Response" -HTTP/1.1 200 OK -Content-Type: application/zip -Content-Disposition: attachment; filename="Release Review.zip"; filename*=UTF-8''Release%20Review.zip -``` - -## List files - - - -Lists files or directories under a workspace path. - -```bash title="Request" -curl "$FLUSO_API/v1/agent/files?path=/files&recursive=false&includeStats=true" \ - -H "Authorization: Bearer $FLUSO_TOKEN" -``` - -```json title="Response: 200" -{ - "path": "/files", - "recursive": false, - "entries": [ - { - "path": "/files/release-brief.md", - "name": "release-brief.md", - "type": "file", - "size": 1240, - "modifiedAt": "2026-08-31T09:00:00Z", - "mimeType": "text/markdown" - } - ] -} -``` - -## Read a text file - - - -Returns a UTF-8 text file as JSON. - -```bash title="Request" -curl -G "$FLUSO_API/v1/agent/files/read" \ - -H "Authorization: Bearer $FLUSO_TOKEN" \ - --data-urlencode 'path=/files/release-brief.md' -``` - -```json title="Response: 200" -{ - "path": "/files/release-brief.md", - "content": "# Release candidate\n\nKnown issue: ...\n", - "encoding": "utf-8" -} -``` - -## Upload a file - -The current client uploads to temporary object storage, then confirms an import into the workspace. The older multipart `/v1/agent/files/upload` route is deprecated. - -1. `POST /v1/files/upload/presigned-url/get` with the file name, MIME type, size in bytes, and optional destination. -2. POST the returned `upload_fields` and file bytes as multipart form data to `upload_url`. The file is the last field. Do not send your Fluso bearer token to that storage URL. -3. `POST /v1/files/upload/presigned-url/confirm` with `{"id": ""}`. -4. Poll `GET /v1/files` for upload tracking and verify the destination file after the import finishes. - -```json title="Presign body" -{ - "file_name": "release-brief.md", - "mime_type": "text/markdown", - "file_size": 1240, - "target_path": "/projects/Home/files/release-brief.md", - "expected_revision": "missing" -} -``` - -Use the actual byte count. `expected_revision: "missing"` requires that no file exists at the destination when the import commits. To edit an existing file, supply its current revision hash. Omitting the field allows ordinary replacement in import order. - -Confirmation queues the import. It does not mean the file is already saved. Tracking rows remain for in-progress uploads, failures, and undismissed history warnings. Successful imports without warnings leave that tracking list. - -An account can have at most four pending uploads. A fifth presign request returns `429`. Confirm active uploads before requesting more. For an abandoned upload, use `DELETE /v1/files/upload/presigned-url/cancel/{id}` to cancel its pending record. Removing an attachment from the composer is not proof that the upload record was cancelled. - -If the destination changed, reread it before saving again. If prior file history cannot be preserved, inspect the reported failure or warning rather than treating the operation as a normal versioned save. Agent knowledge uses its [separate attach-and-save flow](/developers/api-ref/agents-and-versions#attach-knowledge). - -## Download a file - - - -Streams a file with attachment headers. - -```bash title="Request" -curl -G "$FLUSO_API/v1/agent/files/download" \ - -H "Authorization: Bearer $FLUSO_TOKEN" \ - --data-urlencode 'path=/files/release-report.pdf' \ - -o release-report.pdf -``` - -```http title="Response" -HTTP/1.1 200 OK -Content-Type: application/pdf -Content-Disposition: attachment; filename="release-report.pdf"; filename*=UTF-8''release-report.pdf -``` - -## Delete a file - - - -Deletes one file, or a directory when `recursive=true`. - -```bash title="Request" -curl -G "$FLUSO_API/v1/agent/files" \ - -X DELETE \ - -H "Authorization: Bearer $FLUSO_TOKEN" \ - --data-urlencode 'path=/files/release-brief.md' \ - --data 'recursive=false' -``` - -```json title="Response: 200" -{ - "success": true, - "path": "/files/release-brief.md" -} -``` - - - A recursive directory delete removes every child path. List the target first - when its contents are not already known. - - -## Next - -Read [Projects](/features/projects) for the product workflow, choose a project for [Agents](/developers/api-ref/agents-and-versions), or create project-bound [Threads and messages](/developers/api-ref/threads-and-messages). diff --git a/content/docs/developers/api-ref/meta.json b/content/docs/developers/api-ref/meta.json deleted file mode 100644 index 7bf9642..0000000 --- a/content/docs/developers/api-ref/meta.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "title": "For developers", - "icon": "code-xml", - "defaultOpen": false, - "pages": [ - "architecture", - "authentication", - "agents-and-versions", - "threads-and-messages", - "schedules", - "runs", - "files-and-projects", - "sharing", - "usage" - ] -} diff --git a/content/docs/developers/api-ref/runs.mdx b/content/docs/developers/api-ref/runs.mdx deleted file mode 100644 index 5834e2b..0000000 --- a/content/docs/developers/api-ref/runs.mdx +++ /dev/null @@ -1,115 +0,0 @@ ---- -title: Runs -sidebarTitle: Runs -icon: activity -description: Inspect Agent runs and stop work that is still active. ---- - -Run IDs are request IDs. A run can be `queued`, `running`, `held`, `completed`, `failed`, or `cancelled`. - -Runs originate from [messages](/developers/api-ref/threads-and-messages) and [schedules](/developers/api-ref/schedules). - -## List runs - - - -Returns recent runs, with optional thread, request, and attention filters. - -```bash title="Request" -curl "$FLUSO_API/v1/agent-runs?threadId=thread_agent_release&limit=20" \ - -H "Authorization: Bearer $FLUSO_TOKEN" -``` - -```json title="Response: 200" -{ - "agent_runs": [ - { - "id": "req_review_01", - "request_id": "req_review_01", - "thread_id": "thread_agent_release", - "target_thread_id": "thread_agent_release", - "agent_id": "agt_0123456789ab4def8123456789abcdef", - "thread_title": "Release review", - "status": "running", - "origin": "user", - "created_at": "2026-08-31T09:00:00Z", - "started_at": "2026-08-31T09:00:01Z", - "updated_at": "2026-08-31T09:00:02Z", - "completed_at": null, - "outcome": null, - "result_ref": null, - "error": null - } - ], - "settlement_cursor": "2026-08-31T09:00:02Z/req_review_01" -} -``` - -Use `attention=true` for owned approvals and current failures, with approval requests first. It also adds `schedule_failures` for routine delivery problems that did not produce a run. `agentId`, `threadId`, `status`, repeated `requestId`, and `limit` can filter the result. Add `includeRoutineResults=true` to include completed top-level routine runs. Delegated completions remain in their conversations. - -The feed is filtered before limiting. It is a recent status view, not a complete audit archive. A failed request superseded by newer work is omitted from attention. - -## Read one run - - - -Returns one matching run. Include `threadId` when request IDs may repeat across threads. - -```bash title="Request" -curl "$FLUSO_API/v1/agent-runs/req_review_01?threadId=thread_agent_release" \ - -H "Authorization: Bearer $FLUSO_TOKEN" -``` - -```json title="Response: 200" -{ - "id": "req_review_01", - "request_id": "req_review_01", - "thread_id": "thread_agent_release", - "target_thread_id": "thread_agent_release", - "agent_id": "agt_0123456789ab4def8123456789abcdef", - "status": "completed", - "origin": "user", - "created_at": "2026-08-31T09:00:00Z", - "started_at": "2026-08-31T09:00:01Z", - "updated_at": "2026-08-31T09:01:10Z", - "completed_at": "2026-08-31T09:01:10Z", - "outcome": "completed", - "result_ref": { - "thread_id": "thread_agent_release", - "request_id": "req_review_01" - }, - "error": null -} -``` - -## Stop a run - - - -Requests cancellation without starting a dormant runtime only to stop it. - -```bash title="Request" -curl "$FLUSO_API/v1/agent-runs/req_review_01/stop" \ - -X POST \ - -H "Authorization: Bearer $FLUSO_TOKEN" \ - -H 'Content-Type: application/json' \ - -d '{"threadId":"thread_agent_release"}' -``` - -```json title="Response: 200" -{ - "thread_id": "thread_agent_release", - "request_id": "req_review_01", - "status": "cancelled" -} -``` - -The status can also be `already_terminal` when the run settled before cancellation reached it. Stopping does not undo completed tool actions or pause future routine occurrences. Manage the routine separately. - -## Read a durable settlement status - -`GET /v1/agent-runs/{requestId}/status?thread_id={threadId}` returns `state: active | awaiting_approval | settled` and `outcome: completed | failed | canceled | null`. This endpoint uses `thread_id` and the single-l spelling `canceled`, unlike the list projection above. A missing status is not proof of completion. - -## Next - -Inspect token cost in [Usage](/developers/api-ref/usage), or create recurring and one-time [Schedules](/developers/api-ref/schedules). diff --git a/content/docs/developers/api-ref/schedules.mdx b/content/docs/developers/api-ref/schedules.mdx deleted file mode 100644 index 30c4738..0000000 --- a/content/docs/developers/api-ref/schedules.mdx +++ /dev/null @@ -1,147 +0,0 @@ ---- -title: Schedules -sidebarTitle: Schedules -icon: calendar-clock -description: Create, inspect, pause, and delete Agent schedules. ---- - -The UI calls these records **routines**. A schedule belongs to an Agent and one of that Agent's existing threads. Supply exactly one timing field: a five-field `cron` expression or a future `at` timestamp with an offset. `timezone` must be an IANA time zone. - -See [Threads and messages](/developers/api-ref/threads-and-messages) for the target thread and [Runs](/developers/api-ref/runs) for execution state. - -## List schedules - - - -Returns schedules for an Agent, optionally filtered by thread. - -```bash title="Request" -curl "$FLUSO_API/v1/agents/agt_0123456789ab4def8123456789abcdef/schedules?threadId=thread_agent_release&page=1&limit=100" \ - -H "Authorization: Bearer $FLUSO_TOKEN" -``` - -```json title="Response: 200" -{ - "schedules": [ - { - "id": "11111111-1111-4111-8111-111111111111", - "agentId": "agt_0123456789ab4def8123456789abcdef", - "threadId": "thread_agent_release", - "message": "Review the release candidate", - "cron": "0 9 * * 1-5", - "timezone": "Asia/Kolkata", - "status": "active", - "pauseReason": null, - "nextRunAt": "2026-09-01T03:30:00Z", - "attempts": 0, - "createdAt": "2026-08-31T09:00:00Z", - "updatedAt": "2026-08-31T09:00:00Z", - "firedAt": null, - "lastRun": null - } - ], - "pagination": { "page": 1, "limit": 100, "total": 1, "pages": 1 } -} -``` - -## Create a schedule - - - -Creates a recurring or one-time schedule. The caller supplies a UUID so retries can be idempotent. - -```bash title="Request" -curl "$FLUSO_API/v1/agents/agt_0123456789ab4def8123456789abcdef/schedules" \ - -X POST \ - -H "Authorization: Bearer $FLUSO_TOKEN" \ - -H 'Content-Type: application/json' \ - -d '{ - "id": "11111111-1111-4111-8111-111111111111", - "threadId": "thread_agent_release", - "message": "Review the release candidate", - "cron": "0 9 * * 1-5", - "timezone": "Asia/Kolkata" - }' -``` - -For a durable one-time schedule, replace `cron` with an offset-bearing `at` value: - -```json title="One-time timing fields" -{ - "at": "2030-01-15T09:00:00+05:30", - "timezone": "Asia/Kolkata" -} -``` - -```json title="Response: 201" -{ - "id": "11111111-1111-4111-8111-111111111111", - "agentId": "agt_0123456789ab4def8123456789abcdef", - "threadId": "thread_agent_release", - "message": "Review the release candidate", - "cron": "0 9 * * 1-5", - "timezone": "Asia/Kolkata", - "status": "active", - "pauseReason": null, - "nextRunAt": "2026-09-01T03:30:00Z", - "attempts": 0, - "createdAt": "2026-08-31T09:00:00Z", - "updatedAt": "2026-08-31T09:00:00Z", - "firedAt": null, - "lastRun": null -} -``` - -Choose an `at` value in the future at submission time. Replaying the same ID and body while the schedule is live returns the existing schedule with `200`. Reusing the live ID with different fields returns a conflict. After a one-time schedule fires or a schedule is deleted, that ID returns `410` for 24 hours. - -## Pause or edit a schedule - - - -Updates submitted fields. `threadId` is always required to guard the target. - -```bash title="Request" -curl "$FLUSO_API/v1/agents/agt_0123456789ab4def8123456789abcdef/schedules/11111111-1111-4111-8111-111111111111" \ - -X PATCH \ - -H "Authorization: Bearer $FLUSO_TOKEN" \ - -H 'Content-Type: application/json' \ - -d '{"threadId":"thread_agent_release","status":"paused"}' -``` - -```json title="Response: 200, selected fields" -{ - "id": "11111111-1111-4111-8111-111111111111", - "agentId": "agt_0123456789ab4def8123456789abcdef", - "threadId": "thread_agent_release", - "status": "paused", - "nextRunAt": "2026-09-01T03:30:00Z" -} -``` - -## Delete a schedule - - - -Deletes a schedule after matching it to the supplied thread. - -```bash title="Request" -curl "$FLUSO_API/v1/agents/agt_0123456789ab4def8123456789abcdef/schedules/11111111-1111-4111-8111-111111111111?threadId=thread_agent_release" \ - -X DELETE \ - -H "Authorization: Bearer $FLUSO_TOKEN" -``` - -```http title="Response" -HTTP/1.1 204 No Content -``` - -## Delivery behavior - -Each occurrence has a stable request ID and enters the target as `followUp`. Acceptance means queued or admitted, not completed. Another occurrence of the same recurring schedule waits while the prior request is queued, running, or held for approval. - -Temporary delivery failures retry with delays. 24 failed delivery attempts pause the schedule. Refused requests and invariant conflicts can pause it immediately. Usage limits defer delivery. Editing or pausing a schedule does not cancel a request already admitted. - -One-time schedules retire when accepted, even if the later Agent run fails. Deleting the target thread or Agent removes its schedules. See [Routines](/developers/schedules) for the user workflow and timezone controls. - -## Next - -Inspect each execution in [Runs](/developers/api-ref/runs), or manage the target in [Threads and messages](/developers/api-ref/threads-and-messages). diff --git a/content/docs/developers/api-ref/sharing.mdx b/content/docs/developers/api-ref/sharing.mdx deleted file mode 100644 index f38dace..0000000 --- a/content/docs/developers/api-ref/sharing.mdx +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: Sharing -sidebarTitle: Sharing -icon: share-2 -description: Publish a revocable Agent snapshot and import an independent copy. ---- - -Sharing stores a public snapshot. It does not expose a live view of the owner's workspace. Owner routes require [authentication](/developers/api-ref/authentication). A public snapshot read does not. - -## Publish and revoke - -| Method and path | Behavior | -| --- | --- | -| `GET /v1/agents/{agentId}/share-options` | Available custom skills, knowledge, and custom connections | -| `GET /v1/agents/{agentId}/share` | Current link record or `null` | -| `POST /v1/agents/{agentId}/share` | Publish a snapshot | -| `POST /v1/agent-shares/{shareId}/refresh` | Replace the snapshot at the same link | -| `DELETE /v1/agent-shares/{shareId}` | Revoke the link | - -Publishing and refreshing accept a selection: - -```json -{ - "skills": [], - "knowledgeFiles": [], - "connectors": [] -} -``` - -Use IDs from share options for skills, knowledge names for `knowledgeFiles`, and server IDs for `connectors`. Instructions and portable settings are included even with empty selections. Selected skill folders and knowledge contents share limits of 20 MiB and 512 regular files. Symbolic links are rejected. Custom connection URLs with query parameters are excluded from share options. - -Review all selected contents and connection URLs before publishing. Stored authentication, conversations, routines, and project files are not bundled. See [Sharing and copies](/developers/guides/sharing) for the recipient experience. - -## Preview and import - -| Method and path | Behavior | -| --- | --- | -| `GET /v1/agent-templates` | Fluso starting-point snapshots | -| `GET /v1/shared/agents/{shareId}` | Public setup, resource manifest, required filenames, and `publishedAt` | -| `POST /v1/shared/agents/{shareId}/import` | Authenticated import into the recipient's workspace | - -```json -{ - "name": "My release reviewer", - "projectName": "Home", - "creationId": "11111111-1111-4111-8111-111111111111", - "publishedAt": "" -} -``` - -Reuse `creationId` to recover an uncertain import without creating another copy. A changed snapshot returns a conflict rather than silently importing something different from the preview. - -The recipient gets independent setup and selected resource copies. Imported custom skills receive distinct names. App credentials are never inherited. Connection setup may remain unfinished. - -A revoked link becomes unavailable. Unsupported older snapshots may require republication by their owner. Revocation does not delete copies already imported. diff --git a/content/docs/developers/api-ref/threads-and-messages.mdx b/content/docs/developers/api-ref/threads-and-messages.mdx deleted file mode 100644 index b556a4e..0000000 --- a/content/docs/developers/api-ref/threads-and-messages.mdx +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: Threads and messages -sidebarTitle: Threads and messages -icon: messages-square -description: Open an Agent's main conversation, send a turn, and read durable history. ---- - -A thread is a conversation stored in a project. Agent-owned conversations have a saved Agent binding. An ordinary chat cannot be converted by adding an Agent ID to a later message. - -Each Agent has one main conversation and a separate Manager. Delegated sessions are created by the Agent's session tools. Do not create a new top-level thread for every message. - -## Open the main conversation - - - -Use the Agent's configured project and its ID in `metadata`. Omit `thread_id` to let repeated opens resolve to the existing main conversation. - -```bash -curl "$FLUSO_API/v1/threads" \ - -H "Authorization: Bearer $FLUSO_TOKEN" \ - -H 'Content-Type: application/json' \ - -d '{ - "project_id": "Home", - "metadata": {"agentId": ""} - }' -``` - -Use the returned `thread_id` and `project_id`, including when they refer to an existing conversation. Adding `"role": "manager"` to the creation metadata opens that Agent's Manager instead. Ordinary thread creation omits the Agent metadata. - -## Send a message - - - -```bash -curl -N "$FLUSO_API/v1/chat" \ - -H "Authorization: Bearer $FLUSO_TOKEN" \ - -H 'Content-Type: application/json' \ - -d '{ - "threadId": "", - "projectName": "", - "agentId": "", - "requestId": "", - "message": "Review the release evidence already in this project.", - "streamingBehavior": "followUp" - }' -``` - -The response uses the AI SDK UI message stream over SSE. A request can be queued, running, or held for approval before it settles. Stream acceptance is not completion. Use [Runs](/developers/api-ref/runs) and persisted history to recover after a disconnect. - -Use the same `requestId` when checking or retrying an ambiguous submission, with the same request content. Use a new ID for a genuinely new turn. - -`followUp` queues a separate turn if work is active. `steer` brings new input into the active turn where compatible, or starts it when idle. Input with a different saved Agent configuration must wait for its own turn. Do not assume every queued message can be steered. - -## Read and organize conversations - -| Method and path | Behavior | -| --- | --- | -| `GET /v1/threads?page=1&limit=20` | General chat list. Excludes Agent-owned conversations | -| `GET /v1/agents/{agentId}/chats` | Agent conversations, including `isOrchestrator`, `createdByThreadId`, `previousConfig`, `forked`, and `role` | -| `GET /v1/threads/{threadId}?project_id=Home` | Thread metadata | -| `GET /v1/threads/{threadId}/messages?project_id=Home` | Persisted messages and tool-status projections | -| `PATCH /v1/threads/{threadId}?project_id=Home` | Title, supported metadata, pin, archive state, or labels | -| `DELETE /v1/threads/{threadId}?project_id=Home` | Delete an eligible thread and its schedules | - -Thread and message responses use snake_case. Message `content` and `metadata` can contain serialized JSON. Parse them before reading their fields. - -## Read message history - -Use the messages endpoint above when reconnecting or keeping a copy of a conversation. Routine metadata identifies its scheduled origin. Collapsing it in the UI does not remove its full instructions from history. - -Agent and role bindings are fixed at creation. The main conversation uses the current Agent setup on a later turn. Delegated sessions keep their creation setup. The thread endpoints cannot archive or delete the main conversation. Deleting its project also removes it, as explained in [Files and context](/developers/guides/files). - -For user-facing behavior, see [Conversations and sessions](/developers/guides/conversations). diff --git a/content/docs/developers/api-ref/usage.mdx b/content/docs/developers/api-ref/usage.mdx deleted file mode 100644 index 501bb71..0000000 --- a/content/docs/developers/api-ref/usage.mdx +++ /dev/null @@ -1,144 +0,0 @@ ---- -title: Usage -sidebarTitle: Usage -icon: chart-no-axes-combined -description: Read current-user totals, session summaries, and filtered raw usage entries. ---- - -Usage records are user-scoped. Token counts and costs use camelCase fields, and cost values are denominated in US dollars. - -Filter entries by the request and thread identifiers returned from [Runs](/developers/api-ref/runs). - -## Read usage totals - - - -Returns totals for the current user plus a map of session summaries. - -```bash title="Request" -curl "$FLUSO_API/v1/token-usage" \ - -H "Authorization: Bearer $FLUSO_TOKEN" -``` - -```json title="Response: 200, selected fields" -{ - "userId": "22222222-2222-4222-8222-222222222222", - "lastUpdated": "2026-08-31T09:05:00Z", - "totals": { - "tokens": { - "input": 120, - "output": 40, - "cacheRead": 0, - "cacheWrite": 0, - "total": 160 - }, - "cost": { - "input": 0.001, - "output": 0.002, - "cacheRead": 0, - "cacheWrite": 0, - "total": 0.003 - }, - "entryCount": 1 - } -} -``` - -## List session summaries - - - -Returns the session map from the totals response as an array. - -```bash title="Request" -curl "$FLUSO_API/v1/token-usage/sessions" \ - -H "Authorization: Bearer $FLUSO_TOKEN" -``` - -```json title="Response: 200, selected fields" -[ - { - "sessionId": "sess_ddf284f4", - "threadId": "thread_agent_release", - "firstSeen": "2026-08-31T09:00:00Z", - "lastUpdated": "2026-08-31T09:05:00Z", - "entryCount": 1, - "tokens": { - "input": 120, - "output": 40, - "cacheRead": 0, - "cacheWrite": 0, - "total": 160 - }, - "cost": { - "input": 0.001, - "output": 0.002, - "cacheRead": 0, - "cacheWrite": 0, - "total": 0.003 - } - } -] -``` - -## List usage entries - - - -Returns raw usage entries that match the submitted filters. - -```bash title="Request" -curl "$FLUSO_API/v1/token-usage/entries?threadId=thread_agent_release&limit=100" \ - -H "Authorization: Bearer $FLUSO_TOKEN" -``` - -```json title="Response: 200, selected fields" -[ - { - "schemaVersion": 2, - "eventId": "use_0123456789abcdef0123456789abcdef", - "source": "pi-provider", - "ts": "2026-08-31T09:05:00Z", - "sessionId": "sess_ddf284f4", - "threadId": "thread_agent_release", - "component": "chat-agent", - "measurement": "actual", - "requestId": "req_review_01", - "provider": "openrouter", - "status": "success", - "model": "provider/model-id", - "tokens": { - "input": 120, - "output": 40, - "cacheRead": 0, - "cacheWrite": 0, - "total": 160 - }, - "cost": { - "input": 0.001, - "output": 0.002, - "cacheRead": 0, - "cacheWrite": 0, - "total": 0.003 - }, - "costSource": "provider" - } -] -``` - -| Parameter | Matches | Default | -| --- | --- | --- | -| `sessionId` | Session ID | - | -| `threadId` | Thread ID | - | -| `requestId` | Request ID | - | -| `component` | Emitting component | - | -| `provider` | Model provider | - | -| `providerSessionId` | Provider session ID | - | -| `providerGenerationId` | Provider generation ID | - | -| `model` | Model ID | - | -| `since` | Entries at or after an RFC 3339 instant | - | -| `limit` | Maximum entries, from 1 through 1000 | `100` | - -## Next - -Correlate costs with [Runs](/developers/api-ref/runs), or review the service boundaries in [Architecture](/developers/api-ref/architecture). diff --git a/content/docs/developers/meta.json b/content/docs/developers/meta.json index fb75c1d..550ecd7 100644 --- a/content/docs/developers/meta.json +++ b/content/docs/developers/meta.json @@ -6,7 +6,6 @@ "improve", "schedules", "examples", - "guides", - "api-ref" + "guides" ] } diff --git a/content/docs/features/open-architecture.mdx b/content/docs/features/open-architecture.mdx index c75bd35..76637dd 100644 --- a/content/docs/features/open-architecture.mdx +++ b/content/docs/features/open-architecture.mdx @@ -22,7 +22,7 @@ Different exports serve different purposes. A project ZIP is a file backup; a sh | **Audit logs** | In Fluso Admin, filter **Audit log**, then select **Export _N_ rows** | CSV containing the currently filtered rows from the latest 100 recorded identity and access events | | **Usage records** | In Fluso Admin, open **Observability → Export CSV** | CSV of the recorded daily gateway cost and token totals shown in the 14-day view | -Project ZIPs skip dotted runtime entries and symbolic links. They do not serve as a complete conversation archive. Use the [Threads and messages API](/developers/api-ref/threads-and-messages#read-message-history) when you need persisted chat records in a system you control. +Project ZIPs skip dotted runtime entries and symbolic links. They do not serve as a complete conversation archive. Use the [Threads and messages API](/api/workflows/conversations#read-message-history) when you need persisted chat records in a system you control. ## Skills stay readable @@ -52,4 +52,4 @@ These exports are independent snapshots. Later Fluso changes do not silently rew ## APIs for continuous access -Use the [API reference](/developers/api-ref/authentication) when a one-time download is not enough. The beta client API exposes Agent setup, sharing, projects and files, conversations, schedules, runs, and usage. Authenticate each request with a user bearer token and store only the data your integration needs. +Use [API access](/api/first-request) when a one-time download is not enough. The account API covers Agents, conversations, files, schedules, runs, and usage on Cloud and [daemon workspaces](/workspaces). Authenticate with a Cloud developer token or a paired daemon token. Store only the data your integration needs. diff --git a/content/docs/features/projects.mdx b/content/docs/features/projects.mdx index ab9e140..b685c95 100644 --- a/content/docs/features/projects.mdx +++ b/content/docs/features/projects.mdx @@ -41,7 +41,7 @@ Files created in project chats stay in the same workspace. That makes the projec On **Projects**, open the project's **•••** menu and select **Export as zip**. You can also open the project and select **Export**. -The ZIP contains the project's regular files, their folder paths, `context.md`, and project metadata. It omits empty folders, dotted runtime entries, and symbolic links. Conversation history is separate; use **Share chat** for a reviewable snapshot or the [Threads API](/developers/api-ref/threads-and-messages#read-message-history) for persisted messages. +The ZIP contains the project's regular files, their folder paths, `context.md`, and project metadata. It omits empty folders, dotted runtime entries, and symbolic links. Conversation history is separate; use **Share chat** for a reviewable snapshot or the [Threads API](/api/workflows/conversations#read-message-history) for persisted messages. ## Keep context in the right place @@ -66,4 +66,4 @@ If you already have useful context in ChatGPT, Claude, or another agent, use [Im ## Next -Read [Memory](/features/memory) for the context carried between chats, or [Files and projects](/developers/api-ref/files-and-projects) for the API. +Read [Memory](/features/memory) for the context carried between chats, or [Files and projects](/api/workflows/files) for the API. diff --git a/content/docs/index.mdx b/content/docs/index.mdx index e37dec3..abc44c4 100644 --- a/content/docs/index.mdx +++ b/content/docs/index.mdx @@ -48,6 +48,9 @@ Pick a workflow that matches a problem you have right now. Each one is a story, ## When you need it + + Set up Fluso on your own machine and use it with your files, Agents, and routines. + The five primitives: chat, apps, skills, tasks, memory. @@ -57,8 +60,8 @@ Pick a workflow that matches a problem you have right now. Each one is a story, Create an Agent, refine its setup, and return to its conversations, routines, and Inbox. - - Request flow, durable data boundaries, and replaceable components. + + Connect a script to Cloud or Fluso Local, submit work, and read the result. Plans, limits, billing. diff --git a/content/docs/meta.json b/content/docs/meta.json index 7435c5a..3d27ac8 100644 --- a/content/docs/meta.json +++ b/content/docs/meta.json @@ -12,6 +12,10 @@ "[server-cog][Overview](/deployment-models)", "---Features---", "...features", + "---Fluso API---", + "...api", + "---Fluso Local---", + "...workspaces", "---Get started---", "going-deeper", "introduction", diff --git a/content/docs/workspaces/index.mdx b/content/docs/workspaces/index.mdx new file mode 100644 index 0000000..26fe754 --- /dev/null +++ b/content/docs/workspaces/index.mdx @@ -0,0 +1,52 @@ +--- +title: Fluso Local +sidebarTitle: Overview +icon: monitor +description: Set up Fluso on your own machine and use it for your daily work. +--- + +Fluso Local runs your workspace on a computer you control. Use your Mac for work with local files, or a Linux machine for work that continues after you close your laptop. + +You still talk to Fluso in the desktop app. Your conversations, Agents, and workspace files stay on the machine you choose. + +## Choose where to run it + +| Where | Useful for | How you connect | +| --- | --- | --- | +| Your Apple Silicon Mac | Working with documents on your laptop | Choose **This Mac** in Fluso | +| A supported Linux machine | Keeping work running while your laptop is closed | Connect from Fluso on your Mac | + +A Linux machine can be at home or on a server you manage. A Raspberry Pi works only with a supported 64-bit system and working hardware virtualization. + + + + Get the download, choose macOS or Linux, and connect the app. + + + Work with your files, keep an Agent, and schedule useful work. + + + +## What you need + +You install a background program called the **daemon** on the machine that will do the work. It runs separately from the desktop app. You also supply a model provider key and keep that machine awake for work to continue. + +[Contact us](mailto:support@premai.io?subject=Fluso%20Local%20download) for the daemon download links. Include your operating system, processor type, and whether you use Fluso or Fluso Dev. + +The [setup guide](/workspaces/setup) checks your machine before installation. You do not need Docker or a source checkout. For use without the desktop app, follow [API access](/api/first-request) after setup. + +## Where your work stays + +Each machine has its own conversations, Agents, files, and connections. They are separate from Fluso Cloud. Switching workspaces does not move or synchronize your work. + +Fluso can use files you upload or folders you explicitly share. It has no access to your other personal folders by default. + +Your chosen model provider receives the content needed to answer. Connected services receive their tool requests. Local storage does not make all processing local. The desktop interface still needs internet access and Fluso sign-in. + + + Conversations, Agents, files, routines, and custom MCP connections use the selected workspace. Cloud billing, managed app connections, ingestion services, legacy Tasks, and public sharing are not available through the daemon. + + Each paired client has access to the same owner's workspace. Pairing does not create separate user accounts or private areas for different people. + + +Start with [Set up Fluso Local](/workspaces/setup). Return to [settings and maintenance](/workspaces/manage) for provider changes, updates, and backups. diff --git a/content/docs/workspaces/manage.mdx b/content/docs/workspaces/manage.mdx new file mode 100644 index 0000000..bafd6d5 --- /dev/null +++ b/content/docs/workspaces/manage.mdx @@ -0,0 +1,140 @@ +--- +title: Manage your workspace +sidebarTitle: Settings and maintenance +icon: settings-2 +description: Choose a provider, share folders, adjust resources, and keep your workspace recoverable. +--- + +Open **Workspaces** in Fluso and select the machine you want to change. These settings belong to that host, even when you use the app on another Mac. + +To use the terminal instead, run the commands below from the installed package folder on the host. Add `--root /path/to/state` only when selecting a different installation. + +## Choose a model provider + +Open **Model provider**, enter your provider details, then **Save and apply**. You supply the credentials. The daemon does not include a Fluso Cloud inference allowance. + +| Provider | What you supply | +| --- | --- | +| OpenRouter or OpenAI | API key and model ID | +| Custom | An OpenAI-compatible base URL, API key, and exact model ID | +| Prem · Confidential | Prem API key, then **Enable confidential inference** | + +For terminal setup, use `./fluso-daemon configure --apply`. Prompts hide your keys. Pressing Enter keeps a saved value. + +Saved changes need Apply or a restart before they take effect. Applying settings can restart the workspace's compute. Finish active work first. An explicit interruption can stop a running task. + + + A custom endpoint must support streaming and tool calls, a 128K context window, and up to 16K output tokens. Use HTTPS for a remote provider. Local or trusted-network inference endpoints can use HTTP. + + `localhost` refers to the daemon's host. For a Pi workspace, it does not refer to the Mac running Fluso. Changing an endpoint requires entering its key again. + + Prem confidential inference verifies the provider and encrypts inference requests. It does not encrypt every workspace file or make external tools confidential. Image generation and speech synthesis are unavailable in this mode. Turning it off restores your saved standard provider. + + Provider failures do not silently switch to another provider. Media features can need separate provider credentials. Configure these with the same CLI command. + + +## Connect an app + +Open **Plugins → MCP → Add MCP** and choose **Custom server**. Enter the service's public MCP endpoint and supply its credentials or complete its OAuth sign-in. + +The daemon does not copy Cloud connections or provide the managed app catalog. Custom MCP destinations must be public: private network addresses and redirects are blocked. Review the service's permissions before you connect it. + +## Share a folder + +No personal host files are shared by default. Uploaded workspace files are separate from these grants. + +1. In **File access**, add the file or folder the Agent needs. +2. Keep **Read only** for reference material. Choose **Read and write** for files the Agent should edit. +3. Review the native confirmation and select **Save and apply**. + +For a report-writing task, share a reference folder read-only and a separate drafts folder with write access. Tell the Agent which folder holds each kind of file. + +On a remote workspace, enter paths on that remote host. A Mac path such as `/Users/alex/Drafts` appears to tools under `/mnt/host/Users/alex/Drafts`. + +Read-only access prevents edits, but content can still reach the chosen model provider. Share a specific folder instead of your entire home directory. + + + Use `./fluso-daemon host-files --apply` for the same settings in a terminal. + + A folder grant includes its descendants. A single-file grant permits in-place edits. Share the parent folder when a tool must rename or replace files. Overlapping grants are rejected. + + Remove a path and apply the change to revoke access. This does not delete content already copied into the workspace or conversation. Operating-system permissions still apply to writable grants. + + +## Adjust memory and storage + +The default sandbox has **3 GiB of RAM** and a **64 GiB disk budget**. The disk grows as needed: 56 GiB holds saved work and 8 GiB is for temporary work. + +Change these values in the workspace settings, or run `./fluso-daemon resources --apply`. Leave memory and disk space for the operating system and other applications. + +Runtime images, backups, and shared host folders are outside this disk budget. Reducing a limit must still leave room for saved data. Applying the change preserves saved files and replaces temporary storage. + +**Resources and storage** shows the data directory. On This Mac, **Open data folder** opens it in Finder. In a terminal, `./fluso-daemon info` shows the same paths. + +## Update the daemon + +Run this on the host: + +```bash +./fluso-daemon update +./fluso-daemon version +./fluso-daemon status +``` + +The command finds the latest release for the installed development or production channel. You do not need another download URL or a GitHub login. + +It checks the download and signature before stopping the service. Updates keep files, conversations, settings, and pairings. If the replacement cannot start correctly, the updater restores the previous package. + +Updates run only when requested. The desktop app updates separately. A stopped service stays stopped. Active work must finish unless you explicitly allow interruption. + +Keep the current and previous package folders for recovery. Internet access is required for release verification. + +## Back up your work + +Run these commands one at a time on the host. Use a new backup folder: + +```bash +mkdir -p "$HOME/fluso/backups" +./fluso-daemon shutdown +./fluso-daemon backup --backup-dir "$HOME/fluso/backups/first-backup" +./fluso-daemon start +``` + +Continue to backup only after shutdown succeeds. Shutdown refuses to interrupt active work. If backup fails, inspect the error and restart the service when ready. + +The backup includes workspace files and its database. It excludes shared host folders. Back up those folders separately. + +Keep the **encryption key and file-access settings separately**. The backup does not contain the key needed to read saved credentials. + +- On macOS, the key is in the owner's Keychain. +- On Linux, the key is in the installation's `keys` folder. +- With `--root`, file-access settings are in `/sandbox/config.json`. The default Mac path is `~/.fluso/sandbox/config.json`. + +Backup files can contain readable documents. Store them privately and include them in your protected host backups. + + + Restore accepts a backup from the same installation. Keep its original encryption key available. Stop the service, then run `./fluso-daemon restore --backup-dir /path/to/backup`. Start the service after restore succeeds. + + Restore keeps the pre-restore data separately. You must pair clients again, restore host-file access, and explicitly resume schedules. Pending work and approvals are not resumed automatically. + + If the key is lost, ask support about a credential reset. This can preserve files and conversations, but requires new credentials and connections. + + Ask support before moving a workspace to another machine. Copying only the project-files folder or SQLite database is not a complete migration. + + +## When something needs attention + +Start with `./fluso-daemon status` and `./fluso-daemon doctor`. `./fluso-daemon doctor --fix` can repair startup or an interrupted update without resetting credentials or deleting workspace data. + +| Symptom | What to check | +| --- | --- | +| Settings cannot be changed | Reconnect with a code made by `pair --manage-host`. | +| Pairing code rejected | Generate a new code. Codes expire after ten minutes and work once. | +| Remote workspace unreachable | Check the host service and SSH tunnel or HTTPS address. | +| Configuration saved but not active | Apply it. If another client changed settings, reload and review before saving again. | +| Work pauses when the laptop closes | Keep the host awake, or use an always-on Linux host. | +| Model or tool call fails | Check that provider's credentials and the saved result before retrying work. | + +For logs, check `daemon.log` in the Mac data directory. On Linux, use `journalctl --user -u fluso-daemon` for the user service. Share the relevant error with [support](mailto:support@premai.io), without API keys or pairing codes. + +Disconnecting a reachable workspace revokes that client's access. Forgetting an offline connection cannot confirm revocation. Signing out or uninstalling the desktop app does not stop the daemon. diff --git a/content/docs/workspaces/meta.json b/content/docs/workspaces/meta.json new file mode 100644 index 0000000..fc64b41 --- /dev/null +++ b/content/docs/workspaces/meta.json @@ -0,0 +1,12 @@ +{ + "pages": [ + "!index", + "[monitor][Overview](/workspaces)", + "!setup", + "[download][Setup](/workspaces/setup)", + "!use", + "[messages-square][Everyday use](/workspaces/use)", + "!manage", + "[settings-2][Settings and maintenance](/workspaces/manage)" + ] +} diff --git a/content/docs/workspaces/setup.mdx b/content/docs/workspaces/setup.mdx new file mode 100644 index 0000000..ddb9280 --- /dev/null +++ b/content/docs/workspaces/setup.mdx @@ -0,0 +1,206 @@ +--- +title: Set up Fluso Local +sidebarTitle: Setup +icon: download +description: Install on macOS or Linux, choose a model provider, and connect Fluso. +--- + +import { Tab, Tabs } from 'fumadocs-ui/components/tabs'; + +Install the daemon on the machine that will run your work. You can use the same Mac as the desktop app, or connect to a separate Linux machine. + +You need internet access and your own model provider key. Allow at least 8 GiB of memory and 8 GiB of free disk space, plus room for files and backups. + +## 1. Get the download + +[Email support@premai.io](mailto:support@premai.io?subject=Fluso%20Local%20download) for the daemon package. Include your operating system, processor type, and whether you use Fluso or Fluso Dev. + +On a Mac, find these details in **Apple menu → About This Mac**. On Linux, run `uname -m` and `cat /etc/os-release`. + +Ask for the release version, archive URL, and matching checksum URL: + +| Machine | Archive | Checksum | +| --- | --- | --- | +| Apple Silicon Mac | `daemon-darwin-arm64.tar.gz` | `daemon-darwin-arm64.sha256` | +| Linux ARM64 (`aarch64`) | `daemon-linux-arm64.tar.gz` | `daemon-linux-arm64.sha256` | +| Linux x64 (`x86_64`) | `daemon-linux-x64.tar.gz` | `daemon-linux-x64.sha256` | + +Use links supplied by Fluso. You do not need a GitHub account, Docker, Bun, or a source checkout. + +## 2. Install on your machine + +Choose the operating system of the machine that will run Fluso: + + + + +You need an **Apple Silicon Mac**. This package does not support Intel Macs. + +**Download and check.** Open Terminal. Replace `ARCHIVE_URL` and `CHECKSUM_URL` with your links, keeping the quotes: + +```bash +mkdir -p "$HOME/Downloads/fluso-daemon" && +cd "$HOME/Downloads/fluso-daemon" && +curl --fail --location 'ARCHIVE_URL' -o daemon-darwin-arm64.tar.gz && +curl --fail --location 'CHECKSUM_URL' -o daemon-darwin-arm64.sha256 && +shasum -a 256 -c daemon-darwin-arm64.sha256 +``` + +Continue only if the check prints `daemon-darwin-arm64.tar.gz: OK`. If it fails, download both files again from the matching release links. + +**Extract the package.** Replace `RELEASE_VERSION` with the version supplied by support. Use a new folder: + +```bash +mkdir -p "$HOME/fluso/releases" && +mkdir "$HOME/fluso/releases/RELEASE_VERSION" && +tar -xzf daemon-darwin-arm64.tar.gz -C "$HOME/fluso/releases/RELEASE_VERSION" && +cd "$HOME/fluso/releases/RELEASE_VERSION" +``` + +Keep the whole folder in place. The executable needs the other files beside it. For later releases, use [update](/workspaces/manage#update-the-daemon). + +**Start and configure.** Run these commands one at a time as your normal Mac user, without `sudo`. If a command fails, stop and check its error: + +```bash +./fluso-daemon setup --manage-host +./fluso-daemon configure --apply +./fluso-daemon status +``` + +Setup checks the signed package and installs a background service. Follow the prompts to choose your model provider, model, and API key. Key entry stays hidden. Prem confidential inference needs only your Prem API key. + +Respond to macOS Keychain or folder-access prompts. Wait for `status` to report that the workspace is ready. + +The service starts when you log in. Closing Fluso leaves it running. Putting the Mac to sleep pauses its work. + + + + +Use **64-bit glibc Linux with systemd**: Ubuntu 24.04, Debian 13, or newer. The packages support ARM64 and x64. + +The host needs **KVM**, Linux's hardware virtualization facility. A virtual machine also needs nested virtualization from its host provider. + +**Check access to KVM.** Run this on the Linux machine: + +```bash +test -r /dev/kvm && test -w /dev/kvm && echo 'KVM access is ready' +``` + +If it does not print `KVM access is ready`, stop here. Ask your administrator to enable KVM and grant your user read/write access. After a group-permission change, sign out and sign in again. + + + A Raspberry Pi needs a supported 64-bit operating system and kernel with usable KVM. An ARM64 processor alone is not enough. Send your system details and KVM check to support if you are unsure. + + +On Ubuntu or Debian, install the native library and download tools: + +```bash +sudo apt-get update +sudo apt-get install libcap-ng0 curl ca-certificates +``` + +**Download and check.** These commands use ARM64. On x64, replace every `arm64` with `x64`. Replace the two URL placeholders with your links: + +```bash +mkdir -p "$HOME/Downloads/fluso-daemon" && +cd "$HOME/Downloads/fluso-daemon" && +curl --fail --location 'ARCHIVE_URL' -o daemon-linux-arm64.tar.gz && +curl --fail --location 'CHECKSUM_URL' -o daemon-linux-arm64.sha256 && +sha256sum -c daemon-linux-arm64.sha256 +``` + +Continue only if the check prints `OK`. If it fails, download both files again from the matching release links. + +**Extract the package.** Replace `RELEASE_VERSION` with the supplied version. Use a new folder: + +```bash +mkdir -p "$HOME/fluso/releases" && +mkdir "$HOME/fluso/releases/RELEASE_VERSION" && +tar -xzf daemon-linux-arm64.tar.gz -C "$HOME/fluso/releases/RELEASE_VERSION" && +cd "$HOME/fluso/releases/RELEASE_VERSION" +``` + +Keep all extracted files together. Do not overwrite an installed package. Use [update](/workspaces/manage#update-the-daemon) for later releases. + +**Start and configure.** Run these commands one at a time as the workspace owner, without `sudo`. If a command fails, stop and check its error: + +```bash +./fluso-daemon setup --root "$HOME/fluso/state" --manage-host +./fluso-daemon configure --root "$HOME/fluso/state" --apply +./fluso-daemon status +``` + +Follow the prompts for your own model provider and key. Setup keeps data and keys under `~/fluso/state`, outside the package. It remembers this installation for later commands. + +Wait for the workspace to become ready. Setup also arranges for the user service to run after logout and at boot. If administrator approval is needed, it prints a `sudo loginctl enable-linger` command. Have your administrator run that exact command. + + + + +`--manage-host` lets the connected app change the provider, resource limits, and shared folders. You can review these in [workspace settings](/workspaces/manage). + +## 3. Connect Fluso + +Open the matching, current [Fluso desktop app](https://fluso.ai/) on your Mac and sign in. + +### On the same Mac + +1. Open **Workspaces** from the account menu. **View → Workspace settings** opens the same page. +2. Open the workspace selector and choose **This Mac**. Complete any native confirmation. + +### Connect from another Mac + +The machine running Fluso must be reachable through SSH or HTTPS. For a Linux host, the SSH connection below is a way to start. You do not need a daemon on the Mac that connects to it. + +On the host, create a pairing code from the package folder: + +```bash +./fluso-daemon pair --manage-host +``` + +Keep the code private. Each code works once and expires after ten minutes. It gives the client workspace access and permission to change host settings. + +On your Mac, open Terminal. Replace `USER` and `HOST` with your host login and address: + +```bash +ssh -N -o ExitOnForwardFailure=yes -L 127.0.0.1:4111:127.0.0.1:4111 USER@HOST +``` + +Leave this terminal open. Use the same local and remote port shown by setup. The daemon checks the port in incoming requests. + +1. Open **Workspaces** in the current Fluso desktop app. +2. Under **Connect a remote workspace**, enter a name, such as `Home server`. +3. Enter `http://127.0.0.1:4111` as the **Workspace URL**, then paste the pairing code. +4. Select **Connect**. + +Closing the tunnel disconnects the client. It does not stop work on the host. Reopen the tunnel to reconnect. Pairing remains valid unless revoked or unused for 30 days. + + + A Mac daemon or another tunnel may already use that port. For a new host installation, choose two free ports during setup, for example `--port 4211 --control-port 4212`. + + Forward `127.0.0.1:4211` to `127.0.0.1:4211` and use port `4211` in the workspace URL. For an existing host, stop its service before repeating setup with changed ports. Keep its original `--root`. + + + + For a host with DNS and a trusted TLS certificate, add `--public-origin https://workspace.example.com` during setup. Put an HTTPS reverse proxy in front of port `4111`. + + The proxy must preserve the requested Host, support streamed responses, and block `/control/*`. Keep both daemon ports on loopback. Port `4112` is private runtime control. Configure OAuth callbacks for the final HTTPS origin. + + Use the HTTPS URL and a fresh pairing code in Fluso. Ordinary remote HTTP is not accepted. Ask support for help if you do not manage this infrastructure. + + +## 4. Try your first task + +Open a chat in the selected workspace. Attach a short document and ask Fluso to summarize its main points. + +Your Cloud conversations stay in Cloud. This workspace has its own data. Continue with [Use Fluso Local](/workspaces/use) for files, Agents, and routines. + + + From the package folder, run `./fluso-daemon status` and `./fluso-daemon doctor`. Use `./fluso-daemon info` to see its paths and API address. + + Start a stopped service with `./fluso-daemon start`. If configuration is missing, rerun `./fluso-daemon configure --apply`. + + In **Workspaces**, refresh the workspace list. A release mismatch requires a compatible desktop app and daemon. Changing the data directory does not fix it. Keep the original data and keys when diagnosing an existing installation. + + If macOS cannot verify the developer, use **System Settings → Privacy & Security → Open Anyway** only for the package supplied by Fluso. Follow [Apple's instructions](https://support.apple.com/en-us/102445) after checking the download. For a damaged-file or malware warning, contact support with the exact message. + diff --git a/content/docs/workspaces/use.mdx b/content/docs/workspaces/use.mdx new file mode 100644 index 0000000..730148e --- /dev/null +++ b/content/docs/workspaces/use.mdx @@ -0,0 +1,58 @@ +--- +title: Use Fluso Local +sidebarTitle: Everyday use +icon: messages-square +description: Work with your files, return to an Agent, and keep useful work running. +--- + +After [setup](/workspaces/setup), you use Fluso through the same desktop app. Start with a small task and check the result before giving it more work. + +## Open your workspace + +Open **Workspaces** from the account menu. Choose **This Mac** or the remote connection you saved. + +Each workspace has its own conversations, Agents, files, and connections. If your Cloud chats are missing, switch to **Fluso Cloud** to see them. + +When you reopen the app, it starts on Cloud. Select your saved local or remote workspace again. + +## Start with a document + +Open a chat and attach a document with the **+** button, or drag it into the conversation. Try a set of meeting notes: + +> *"Turn these notes into a short plan for next week. Separate agreed actions from open questions. Include an owner or date only where the notes give one."* + +Read the answer against your notes. Continue in the same chat to correct a detail or add another document. + +An attachment copies the file into the selected workspace. It does not give Fluso access to the rest of your computer. + +## Work with a folder + +For files you use repeatedly, [share a folder](/workspaces/manage#share-a-folder) in workspace settings. Keep reference files read-only. Grant write access only where you want Fluso to edit files. + +Tell Fluso the folder path shown by the settings and what you want: + +> *"Review the meeting notes in this folder. Give me a short list of decisions that are still open, with the source file for each. Leave the files unchanged."* + +For a remote workspace, shared folders belong to the remote machine. Attach a file from your Mac when you want to copy it there. + +## Keep an Agent for repeat work + +Create an [Agent](/developers/agent-builder) in this workspace to keep instructions for a job you return to. For example, keep an assistant for reviewing your project notes. + +Once its results are useful, ask in the Agent's working conversation: + +> *"Every Friday at 4 PM in Europe/Zurich, review this project's notes. Summarize progress, open decisions, and next week's priorities here."* + +Use your own time and timezone. Check the saved [routine](/developers/schedules) in **Routines**. Read its results in the conversation or **Inbox**. + +The machine running Fluso must stay awake and connected. Closing the desktop app leaves accepted work running. After downtime, missed recurring runs are combined into one catch-up run. + +## Return from another location + +For a remote machine, reopen your [SSH tunnel](/workspaces/setup#connect-from-another-mac) or use its configured HTTPS address. Your Mac must be able to reach that machine. Pairing alone does not make a home computer reachable over the internet. + +Select the saved connection to return to its work. Closing the tunnel disconnects your app, but leaves work running on the remote machine. + +To use an external service, [connect its custom MCP server](/workspaces/manage#connect-an-app) in this workspace. Cloud app connections do not carry over. + +For provider changes, storage, updates, and backups, open [settings and maintenance](/workspaces/manage). diff --git a/public/_redirects b/public/_redirects index b4c54d6..e8391c6 100644 --- a/public/_redirects +++ b/public/_redirects @@ -37,6 +37,42 @@ /developers/export-import-and-share-agents /developers/guides/sharing 301 /developers/export-import-and-share-agents/ /developers/guides/sharing 301 /llms.mdx/docs/developers/export-import-and-share-agents/content.md /llms.mdx/docs/developers/guides/sharing/content.md 301 -/developers/architecture /developers/api-ref/architecture 301 -/developers/architecture/ /developers/api-ref/architecture 301 -/llms.mdx/docs/developers/architecture/content.md /llms.mdx/docs/developers/api-ref/architecture/content.md 301 +/developers/architecture /api 301 +/developers/architecture/ /api 301 +/llms.mdx/docs/developers/architecture/content.md /llms.mdx/docs/api/content.md 301 +/workspaces/macos /workspaces/setup 301 +/workspaces/macos/ /workspaces/setup 301 +/workspaces/linux /workspaces/setup 301 +/workspaces/linux/ /workspaces/setup 301 +/llms.mdx/docs/workspaces/macos/content.md /llms.mdx/docs/workspaces/setup/content.md 301 +/llms.mdx/docs/workspaces/linux/content.md /llms.mdx/docs/workspaces/setup/content.md 301 +/developers/api-ref/authentication /api/first-request 301 +/developers/api-ref/authentication/ /api/first-request 301 +/llms.mdx/docs/developers/api-ref/authentication/content.md /llms.mdx/docs/api/first-request/content.md 301 +/developers/api-ref/threads-and-messages /api/workflows/conversations 301 +/developers/api-ref/threads-and-messages/ /api/workflows/conversations 301 +/llms.mdx/docs/developers/api-ref/threads-and-messages/content.md /llms.mdx/docs/api/workflows/conversations/content.md 301 +/developers/api-ref/runs /api/workflows/runs 301 +/developers/api-ref/runs/ /api/workflows/runs 301 +/llms.mdx/docs/developers/api-ref/runs/content.md /llms.mdx/docs/api/workflows/runs/content.md 301 +/developers/api-ref/agents-and-versions /api/workflows/agents 301 +/developers/api-ref/agents-and-versions/ /api/workflows/agents 301 +/llms.mdx/docs/developers/api-ref/agents-and-versions/content.md /llms.mdx/docs/api/workflows/agents/content.md 301 +/developers/api-ref/files-and-projects /api/workflows/files 301 +/developers/api-ref/files-and-projects/ /api/workflows/files 301 +/llms.mdx/docs/developers/api-ref/files-and-projects/content.md /llms.mdx/docs/api/workflows/files/content.md 301 +/developers/api-ref/schedules /api/workflows/schedules 301 +/developers/api-ref/schedules/ /api/workflows/schedules 301 +/llms.mdx/docs/developers/api-ref/schedules/content.md /llms.mdx/docs/api/workflows/schedules/content.md 301 +/developers/api-ref/usage /api/workflows/usage 301 +/developers/api-ref/usage/ /api/workflows/usage 301 +/llms.mdx/docs/developers/api-ref/usage/content.md /llms.mdx/docs/api/workflows/usage/content.md 301 +/developers/api-ref/sharing /api/cloud/sharing 301 +/developers/api-ref/sharing/ /api/cloud/sharing 301 +/llms.mdx/docs/developers/api-ref/sharing/content.md /llms.mdx/docs/api/cloud/sharing/content.md 301 +/developers/api-ref/architecture /api 301 +/developers/api-ref/architecture/ /api 301 +/llms.mdx/docs/developers/api-ref/architecture/content.md /llms.mdx/docs/api/content.md 301 +/api/architecture /api 301 +/api/architecture/ /api 301 +/llms.mdx/docs/api/architecture/content.md /llms.mdx/docs/api/content.md 301 diff --git a/public/images/api/developer-token-form.png b/public/images/api/developer-token-form.png new file mode 100644 index 0000000..832d687 Binary files /dev/null and b/public/images/api/developer-token-form.png differ