Metadata-Version: 2.4
Name: fruxon
Version: 0.10.0
Summary: The Fruxon SDK is a lightweight Python client for integrating with the Fruxon platform.
Project-URL: bugs, https://github.com/fruxon-ai/fruxon-sdk/issues
Project-URL: changelog, https://github.com/fruxon-ai/fruxon-sdk/blob/main/HISTORY.md
Project-URL: homepage, https://github.com/fruxon-ai/fruxon-sdk
Author-email: Hagai Cohen <hagai@fruxon.com>
Maintainer-email: Hagai Cohen <hagai@fruxon.com>
License: MIT
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.10
Requires-Dist: click>=8.2
Requires-Dist: keyring>=24.0
Requires-Dist: typer>=0.13
Provides-Extra: test
Requires-Dist: coverage; extra == 'test'
Requires-Dist: ipdb; extra == 'test'
Requires-Dist: pre-commit; extra == 'test'
Requires-Dist: pytest; extra == 'test'
Requires-Dist: ruff; extra == 'test'
Requires-Dist: ty; extra == 'test'
Description-Content-Type: text/markdown

# fruxon

[![PyPI version](https://img.shields.io/pypi/v/fruxon.svg)](https://pypi.org/project/fruxon/)
[![Python](https://img.shields.io/pypi/pyversions/fruxon.svg)](https://pypi.org/project/fruxon/)
[![License](https://img.shields.io/pypi/l/fruxon.svg)](https://github.com/fruxon-ai/fruxon-sdk/blob/develop/LICENSE)

Run, build, and orchestrate AI agents from your terminal — the official Python SDK and CLI for the [Fruxon](https://fruxon.com) platform.

## Install

```bash
pip install fruxon
```

Requires Python 3.10+.

## 30-second quickstart

```bash
fruxon login                                       # opens a browser; stores the token in your OS keychain
fruxon agents list                                 # see what's deployed in your workspace
fruxon agents schema my-agent                      # learn what parameters my-agent expects
fruxon agents draft pull my-agent                  # fetch the working copy locally
fruxon agents draft validate my-agent              # lint the flow structure before pushing
fruxon agents draft run my-agent -p question="hi"  # run the draft to validate it
```

Production invocation of a *deployed* agent isn't a CLI concern — call it
from your app via the [Python client](#the-python-client). The CLI is for
building and maintaining agents.

`fruxon doctor` will tell you if anything's misconfigured.

## The CLI

Top-level discovery commands — useful whether you're a human or an AI agent driving the CLI:

| Command | What it does |
| --- | --- |
| `fruxon describe` | Dump the entire CLI surface as one JSON document (paths, args, options, types, defaults, choices, examples). The right entry point for an LLM driver — read it once, fluent. |
| `fruxon examples [topic]` | Curated, pasteable invocations grouped by topic (`draft`, `agents`, `executions`, …). |
| `fruxon completion {bash\|zsh\|fish}` | Print a shell-completion script. `eval "$(fruxon completion zsh)"` to install. |
| `fruxon guides list / show <id>` | Bundled CLI playbooks. Start with `fruxon-meet`; AI-agent drivers should load `fruxon-agent-mode` first. |
| `fruxon doctor` | Diagnose local setup (interpreter, SDK version, credentials, API reachability, auth). |

Auth:

| Command | What it does |
| --- | --- |
| `fruxon login` | Browser-based sign-in. token goes to your OS keychain (Keychain on macOS, Secret Service on Linux, Credential Manager on Windows). `--token $KEY` for headless. `--preset observer\|operator\|developer\|maintainer\|admin` declares the access level the key is minted with (default: developer); the approval page shows it for the user to approve or deny. |
| `fruxon whoami` | Show the active key/workspace and where each value came from (flag, env, keychain, file). |
| `fruxon logout` | Forget stored credentials. |
| `fruxon config list / get / set / unset` | Read/edit the persistent CLI config. |

Execution:

| Command | What it does |
| --- | --- |
| `fruxon agents draft run <agent> -p k=v` | Run the agent's **draft** revision (Origin=TEST — owner-scoped, no prod spend). The CLI's one execution surface. Streams text by default; pass `--output json` or `--no-stream` for the full result envelope. Under agent mode, emits NDJSON on stdout — one JSON record per SSE event. |
| `fruxon agents executions list <agent>` | List past executions, newest-first. Filter by `--status`, `--origin` (PRODUCTION default / TEST), `--revision`, `--since`/`--until`, `--limit`. The discovery step — find a record id. |
| `fruxon agents executions get <agent> <record-id>` | Record summary for one execution — status, duration, cost, tokens. |
| `fruxon agents executions trace <agent> <record-id>` | Step-by-step trace of one execution — LLM/tool calls, durations. |
| `fruxon agents executions result <agent> <record-id>` | The final output one execution produced. |
| `fruxon agents approvals list/get/respond/cancel <agent>` | Operate a step's human-in-the-loop gate — see what a run is blocked on and answer it. `respond`/`cancel` confirm first and refuse without `--yes` in agent mode (an LLM must not silently auto-approve). |
| `fruxon agents memory list/subjects/get/forget-subject <agent>` | Inspect and prune what an agent remembers. `list` filters server-side by `--subject`/`--search`/`--scope`; `forget-subject` is a GDPR-style delete (confirms; refuses without `--yes` in agent mode). |
| `fruxon agents topics list/search/get/messages <agent>` + `fruxon agents inbox <agent>` | Read the conversation spine — the agent's topics (threads), one topic's transcript, and its inbox (what it's focused on). `list`/`search` filter server-side by `--state`/`--participant`/`--query`. Read-only. |
| `fruxon agents sandbox open/turn/fire/resolve-input/stream/answer/close <session>` | Drive an agent-network sandbox end-to-end without real channels — send turns as participants, test-fire triggers, and watch the run (`stream`, NDJSON in agent mode). Sandbox **captures the reply and hard-blocks every real send**; `--await` makes consult/approval gates suspend so they can be resolved (`answer` for consults, `approvals respond` for approvals). |
| `fruxon agents sandbox test <file-or-dir>` | Run scenario-based e2e tests of an agent's network behavior. A scenario (YAML/JSON) declares `steps` (turns / trigger fires), `responders` (scripted consult/approval answers), and `expect` assertions (reply / routing / no-leak / outcome); the runner drives a sandbox session and returns one verdict — exit 0 (pass) / 1 (fail) / 12 (bad file), with `--junit` for CI. An optional `setup` block provisions real resources first — an `asset` (uploaded + ingestion-waited), `participant`, or `agent` — templated as `${asset.catalog.id}` and **torn down afterwards even on failure** (`--keep` to inspect). Assertions are deterministic by default; `reply_judge: {metric, min_score}` adds an opt-in **semantic** check that scores the reply against a tenant eval metric. The thing an agent runs to prove the agent it built works. |

Invoking a *deployed* agent in production goes through the [Python client](#the-python-client) (`FruxonClient.stream` / `execute`), not the CLI.

Agent authoring + management:

| Command | What it does |
| --- | --- |
| `fruxon agents list` | Browse every agent in your workspace. `--output id` for shell pipes; `--include-disabled` (`-a`) to include disabled ones. |
| `fruxon agents get <id>` | Inspect one agent — display name, deployed revision, tags, expected parameters. |
| `fruxon agents schema <id>` | Typed parameter metadata — names, types, required, options. The shape a run will accept. |
| `fruxon agents validate <id> -p k=v` | Pre-flight a payload against the schema. Catches missing-required / wrong-type / invalid-option client-side, surfacing every finding in one pass. |
| `fruxon agents create --file <body.json>` | Provision a new agent shell. Pair with `--schema` to print the JSON schema for the body first. |
| `fruxon agents draft schema` | Print the JSON Schema for a draft body (`DraftPayload`) — the flow file you author, full step-capability closure inlined. |
| `fruxon agents draft validate <id> [--online]` | Lint a draft body's flow structure locally (no network): missing entry/exit, slot ids, tool→slot wiring, AGENT provider config, dangling edges. `--online` also resolves references against the live catalog (unknown/unpublished config, unreal model, bad tool id). `{valid, errors, warnings}` envelope (the same `errors` as `agents validate`); exits 12 on any error. `warnings[]` are advisory wiring gaps (`consult_unwired`, `approver_slot_undeclared`) that never flip `valid` or the exit code. |
| `fruxon agents draft run <id> --file <def.json>` | Run a draft flow definition against an existing agent without publishing it. A CI gate for agent changes. |
| `fruxon agents revisions create/get/deploy` | Mint and deploy immutable revisions. `create --deploy` does both in one step. |
| `fruxon agents check <id>` | Audit whether a **deployed** agent is wired to run end-to-end, beyond the flow body: a deployed revision, an inbound path (bound trigger / channel), a consult roster if a step enables consult, declared approver slots, every bound trigger populating the agent's required params, and that the revision's references resolve. `{overall, checks[]}` (doctor-style); exits non-zero only on a hard fail (no deployed revision) — advisory `warn` rows stay exit 0. |
| `fruxon agents draft pull/push/status/undo/redo/reset/discard` | Local working-copy authoring loop — same draft an open studio tab edits. |
| `fruxon agents draft evaluate <id> --dataset <uuid>` | Score the draft against a golden dataset (expensive — every sample is a full agent run). |
| `fruxon agents tests list/show/watch/cost/delete` | Browse + tail the test-chat sessions you've run on an agent (owner-scoped). |
| `fruxon agents budget list/get/set/delete` | Per-origin (PRODUCTION / TEST) cost caps and spend visibility. |

Integrations + tools:

| Command | What it does |
| --- | --- |
| `fruxon integrations list/get/create/update/verify/open` | Manage external integrations — the connections agents draw tools from. `create`/`update`/`verify` take a `--file` JSON body; `open` opens the dashboard. |
| `fruxon integrations configs list/get` | Inspect the per-integration auth/config records. |
| `fruxon integrations authorize <integration>` | Mint an application-level OAuth authorization URL to **connect** an integration — auto-detects its OAuth2 method (`--auth-method` to pick, `--scope`/`--config-param` to tune). OAuth needs a browser consent step, so the CLI hands you the link; a human clicks it, and the connection is saved as a tenant config a slot can pin. |
| `fruxon integrations triggers <integration>` | List the event types an integration can fire an agent on — each descriptor's `id` is the `eventType` a trigger listens for, plus the `payloadFields` (dotted paths) a binding's `parameterMappings` can read. Discovery for wiring an inbound-event trigger without guessing. |
| `fruxon integrations mcp …` | Inspect and enable the MCP server for an integration. |
| `fruxon tools list/get/create/update/delete/test` | Manage the tools inside an integration. Integration-scoped. `test` runs a tool with sample params before wiring it into an agent. |
| `fruxon keys list/mint/revoke/delete/history/scopes` | Audit and revoke scoped tokens. Minting opens the dashboard so the secret never enters the CLI process. |
| `fruxon llm-providers list/get/models` | Browse LLM providers and models supported at the tenant level. |
| `fruxon assets create/list/get/wait/operations/delete` | Manage knowledge-base (RAG) assets a step can query — upload local files, wait for async ingestion, inspect operations, and use the ids for `assetConfig.assetIds`. `delete` confirms + refuses without `--yes` in agent mode. |
| `fruxon metrics list` | Browse the evaluation-metric catalog — the ids a step's LLM-judge config (`judge.metrics[]`) binds, with a default weight each. |
| `fruxon triggers list/get/create/update/delete/fire/bind/unbind` | Manage triggers — the schedule/event sources that fire agents. `create`/`update` take `--file` (+`--schema`); `bind`/`unbind` wire which agents fire; `fire` runs it now. `fire`/`delete`/`unbind` confirm + refuse without `--yes` in agent mode. The control plane for autonomy. |
| `fruxon secrets list/get/grants` | Discover tenant secrets a step can reference — the ids for `allowedSecretIds` and the `{{secret.KEY}}` names, with publish-state and per-agent grants. Metadata only; values are never returned. |
| `fruxon participants list/get/create/update/delete/enable/disable` | Manage agent-network participants (people / groups / agents the network routes to). `create`/`update` take `--file` (+`--schema`); `enable`/`disable` toggle routing; `delete` confirms + refuses without `--yes` in agent mode. |
| `fruxon capabilities list/get/create/update/delete` | Manage the consult-routing vocabulary (capabilities = name/area/description) that roster bindings and pins reference. `create`/`update` take `--file` (+`--schema`); `delete` --yes-gated in agent mode. |
| `fruxon participants bind/unbind/roster` + `fruxon agents roster` | Wire a participant onto an agent's consult roster and set its policy (roles / urgency / response policy); `agents roster` reads who advises an agent. `unbind` --yes-gated. |
| `fruxon consult-pins list/get/create/delete` | Deterministic capability→participant routing overrides (skip the network's scoring). `create` takes `--file` (+`--schema`); `delete` --yes-gated. |
| `fruxon triggers list/get` | Discover tenant triggers — the scheduled / event sources that fire agents, invisible to draft authoring otherwise. |
| `fruxon agents channels list / agents endpoints` | Inspect how a networked agent receives inbound — its channel bindings and resolved provider endpoints (with bot identity). |
| `fruxon skills list/show` | Browse the tenant's product-skill catalog (resources that attach to agents at runtime). |

### `fruxon agents draft run` — examples

```bash
fruxon agents draft pull my-agent                                  # fetch the working copy first
fruxon agents draft run my-agent -p question="Hello" -p lang=en
fruxon agents draft run my-agent -p temp:=0.7 -p tags:='["a","b"]' # ':=' for typed JSON
fruxon agents draft run my-agent -p prompt=@./prompt.md            # '@file' reads from disk
fruxon agents draft run my-agent --params ./params.json            # whole-object input
cat params.json | fruxon agents draft run my-agent --stdin
fruxon agents draft run my-agent --output json                     # full result envelope
fruxon agents draft run my-agent --file my-agent.draft.json        # push local edits, then run
```

### Agent mode (CI, Claude Code, custom orchestrators)

When `CLAUDECODE=1`, `CI=1`, or `FRUXON_AGENT_MODE=1` is set, the CLI flips to a contract designed for parseability:

- **JSON by default.** Every `--output` flag defaults to `json`. Every read command emits a stable shape; every write echoes the server's response.
- **NDJSON streaming.** `fruxon agents draft run` and `fruxon agents tests watch` emit one JSON record per line on stdout (`{"type":"text","delta":"..."}`, `{"type":"tool_call",...}`, `{"type":"done",...}`).
- **Typed exit codes.** `10` = auth_required, `11` = not_found, `12` = validation, `13` = conflict, `14` = server_error, `15` = network_error, `16` = interactive_required. Match on the number, not on prose.
- **Structured errors.** Every failure emits a one-line JSON envelope on stderr: `{"error":{"code","message","exit_code","hint"}}`.
- **Interactive guards.** Any path that would block on stdin (browser login, `--edit`, missing `--yes`) fails fast with `EXIT_INTERACTIVE_REQUIRED` and a hint naming the bypass flag.
- **Cold-start manifest.** Bare `fruxon` invocation emits a one-line JSON manifest with next-step commands so an LLM driver learns the surface without `--help` walking.

Full contract: `fruxon guides show fruxon-agent-mode`.

## The Python client

```python
from fruxon import FruxonClient

client = FruxonClient(token="...", workspace="acme-corp")

# One-shot
result = client.execute(
    "support-agent",
    parameters={"question": "How do I reset my password?"},
)
print(result.response)
print(f"{result.trace.duration}ms · ${result.trace.total_cost:.4f}")

# Multi-turn — thread the session ID into subsequent calls
followup = client.execute(
    "support-agent",
    parameters={"question": "Tell me more"},
    session_id=result.session_id,
)

# Streaming
for chunk in client.stream_text("support-agent", parameters={"question": "Hi"}):
    print(chunk, end="", flush=True)

# Lower-level: typed SSE events (text, tool_call, tool_result, done, …)
for event in client.stream("support-agent", parameters={"question": "Hi"}):
    ...

# Discovery
for agent in client.list_agents():
    print(agent.id, agent.current_revision)

# Typed parameter metadata — what `execute` / `stream` will accept
schema = client.get_agent_parameter_metadata("support-agent", revision=1)
for p in schema["metadata"]:
    print(p["name"], p["type"], "required" if p.get("required") else "optional")

# Test a draft flow without publishing it (same result shape as execute)
result = client.test("support-agent", {"flow": {...}, "baseRevision": 3, "parameters": {...}})
for event in client.stream_test("support-agent", {"flow": {...}}):
    ...

# Integrations & tools — the connections + capabilities agents are built from
for integ in client.list_integrations(types=["CUSTOM"]):
    print(integ.id, integ.type)
client.create_integration({"id": "github", "displayName": "GitHub", "configMetadata": {...}})
for tool in client.list_tools("github"):
    print(tool.id, tool.tool_type)
client.create_tool("github", {"id": "list_commits", "integrationId": "github", "descriptor": {...}})
client.test_tool("github", {"descriptor": {...}, "parameters": {"repo": "fruxon-sdk"}})

# Assets — local files become RAG knowledge sources after async ingestion
created = client.create_asset_from_file("./handbook.pdf", name="Support handbook")
asset_id = created["asset"]["id"]
client.wait_for_asset(asset_id, operation=created["longOperation"]["id"])
for asset in client.list_assets():
    print(asset.id, asset.vectorized)
```

The client picks up `FRUXON_TOKEN`, `FRUXON_WORKSPACE`, and `FRUXON_BASE_URL` only if you read them yourself — the constructor takes explicit values. The CLI resolves them automatically (flags → env → stored config).

## Credentials & storage

The CLI resolves auth in this order (first non-empty wins):

1. Explicit flags — `--token` / `--workspace` / `--base-url`
2. Environment — `FRUXON_TOKEN` / `FRUXON_WORKSPACE` / `FRUXON_BASE_URL`
3. Stored credentials (managed by `fruxon login`)

The stored layer is split:

- **token** → OS keychain via [`keyring`](https://pypi.org/project/keyring/). Set `FRUXON_NO_KEYRING=1` or let the keyring be unavailable to fall back to a `0600` JSON file.
- **Non-secrets** (`workspace`, `base_url`) → plain JSON under `~/.fruxon/credentials`.

`fruxon config list` shows both sources side by side.

## Environment variables

| Var | Effect |
| --- | --- |
| `FRUXON_TOKEN` | Default token. |
| `FRUXON_WORKSPACE` | Default workspace. |
| `FRUXON_BASE_URL` | Override the API base URL (staging / self-hosted). |
| `FRUXON_CONFIG_DIR` | Override the credentials directory (default `~/.fruxon`). |
| `FRUXON_DASHBOARD_URL` | Override where `fruxon login` points the browser. |
| `FRUXON_AGENT_MODE=1` | Opt into the agent-mode contract (JSON outputs, NDJSON streams, typed exits, structured errors). Also auto-detected from `CLAUDECODE=1` / `CI=1`. |
| `FRUXON_NO_KEYRING=1` | Force the JSON-file fallback for the token. |
| `FRUXON_CA_BUNDLE` | Path to a PEM file of extra trusted CAs (corporate TLS proxies). |
| `FRUXON_INSECURE=1` | Disable TLS verification (dev/staging only — never production). |
| `FRUXON_NO_BANNER=1` | Suppress all branding chrome. |
| `FRUXON_NO_UPDATE_CHECK=1` | Opt out of the "newer version available" notifier. |
| `NO_COLOR=1` | Standard convention — disables color output. |

## Docs

- [Installation](docs/installation.md)
- [CLI reference](docs/cli.md)
- [Python client](docs/python-client.md)
- [Auth & configuration](docs/auth-and-config.md)

In-CLI:
- `fruxon describe` — the whole command tree as JSON
- `fruxon guides list` — bundled procedural playbooks (orientation, build-agent, agent-mode contract, debug-revision, …)

## License

MIT — see [LICENSE](LICENSE).
