Metadata-Version: 2.4
Name: deepflow-openagent-cli
Version: 0.1.9
Summary: Command-line client for OpenAgent OpenAPI (agents, conversations, SSE chat, tools, channels, knowledge bases).
Author: DeepFlow AI
Project-URL: Repository, https://github.com/DeepFlowAI/OpenAgent
Keywords: deepflow,openagent,newagent,openapi,cli,sse,chat
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Provides-Extra: dev
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"

# deepflow-openagent-cli

Python command-line client for the OpenAgent OpenAPI: agents, conversations, SSE chat, tools, channels, documents, and knowledge bases.

## Install

```bash
pip install deepflow-openagent-cli
```

## Usage

```bash
export OPENAGENT_HOST="https://your-api-host"
export OPENAGENT_API_KEY="sk-..."
deepflow_openagent_cli docs list
deepflow_openagent_cli agents list
```

Equivalent module invocation:

```bash
python -m deepflow_openagent_cli docs list
```

## Configure API host and key

| Method | Variable / flag |
|--------|------------------|
| Host | `OPENAGENT_HOST` or `--host` |
| API key | `OPENAGENT_API_KEY` or `--api-key` |

Legacy `NEWAGENT_HOST` and `NEWAGENT_API_KEY` are still read as fallbacks.

When using flags, put global flags before the command:

```bash
deepflow_openagent_cli --host http://localhost:5001 --api-key sk-... agents list
```

## Common commands

```bash
deepflow_openagent_cli docs show chat.stream --json
deepflow_openagent_cli knowledge list --page 1 --per-page 10
deepflow_openagent_cli knowledge documents 1
deepflow_openagent_cli knowledge query-document 6670 --slice-id 512208 --line 1720

# Knowledge-base file library (requires config scope)
deepflow_openagent_cli knowledge directories create 1 --name "Policies"
deepflow_openagent_cli knowledge files create 1 \
  --directory-id 2 --name "Product Manual" --custom-version v1 \
  --original ./manual.pdf --markdown ./manual.md
deepflow_openagent_cli knowledge files list 1 --markdown-filter has-missing
deepflow_openagent_cli knowledge versions upload 1 3 \
  --custom-version v2 --original ./manual-v2.pdf
deepflow_openagent_cli knowledge versions attach-markdown 1 3 4 \
  --markdown ./manual-v2.md
deepflow_openagent_cli knowledge versions set-current 1 3 4
deepflow_openagent_cli knowledge versions original 1 3 4 --output ./manual-v2.pdf
deepflow_openagent_cli knowledge versions markdown 1 3 4 --output ./manual-v2.md

deepflow_openagent_cli chat 1 --message "Hello"
deepflow_openagent_cli steps 1 42
deepflow_openagent_cli steps get 1 42 100
deepflow_openagent_cli steps feedback 1 42 100 --rating like --comment "Helpful answer"

# Python code tool (create → update config → debug execute)
deepflow_openagent_cli tools create 1 --name order_query --tool-type python_code
deepflow_openagent_cli tools update 1 2 --json '{"config":{"code":"import openagent\nopenagent.set_output(openagent.args)","parameters_json":"{\"type\":\"object\",\"properties\":{\"order_id\":{\"type\":\"string\"}},\"required\":[\"order_id\"]}"}}'
deepflow_openagent_cli tools execute 1 2 --json '{"brief":"查订单","order_id":"A1"}'
```

## Development (build wheel/sdist locally)

From this directory:

```bash
pip install -e ".[dev]"
pytest
python -m build
```

Upload to PyPI (use a **new** API token; never commit tokens):

```bash
python -m twine upload dist/*
```

When prompted, username is `__token__` and password is the token value.

## Cloud PC management

Requires a tenant API key with **config** scope and Cloud PC enabled. Global
options (`--host`, `--api-key`, `--raw`, `--no-pretty`) go before the command.

```bash
deepflow_openagent_cli cloudpc capability
deepflow_openagent_cli agents list --kind cloudpc
deepflow_openagent_cli agents get 123
deepflow_openagent_cli cloudpc config get 123
deepflow_openagent_cli cloudpc versions list 123

# Create from the newest saved snapshot (not necessarily the published version).
# Other explicit sources: published, base, or a numeric version ID.
deepflow_openagent_cli cloudpc dev create 123 --from latest
deepflow_openagent_cli cloudpc dev get 123
deepflow_openagent_cli cloudpc files tree 123
deepflow_openagent_cli cloudpc files read 123 \
  --path .agents/skills/demo/SKILL.md --output ./SKILL.md
```

`files read --output` saves exact UTF-8 content and prints metadata including
`sha256`. After editing the local file, pass that **original remote hash** to
reject an intervening change:

```bash
deepflow_openagent_cli cloudpc files write 123 \
  --path .agents/skills/demo/SKILL.md --file ./SKILL.md \
  --if-match <SHA256_FROM_READ>
deepflow_openagent_cli cloudpc versions save 123 \
  --version 1.0.2 --remark "Update skill"
deepflow_openagent_cli cloudpc versions publish 123 <SAVED_VERSION_ID>
```

Replace the angle-bracket placeholders with actual values before executing.
Omitting `--if-match` performs an unconditional write; `--file -` reads UTF-8
from stdin. `--raw cloudpc files read ...` prints only file content, with no
added newline. Text reads default to a 1 MiB limit; binary/oversized files
produce a nonzero exit code instead of writing an empty local file.

Files always belong to the **running development sandbox**, under
`/workspace/agent`. They can differ from both saved and published versions.
An existing development sandbox is never automatically replaced. Save needed
changes before explicitly destroying it. `latest` / `published` fail if the
selected version does not exist; use `--from base` for a fresh environment.
Version ID is different from the `x.y.z` version label. First save automatically
publishes; later saves require a separate `versions publish` command.

Binary uploads (including PDF) use the same sandbox upload writer as the workbench:

```bash
deepflow_openagent_cli cloudpc files upload 123 --file ./report.pdf
# After retry exhaustion, reuse BOTH printed IDs and the same local file:
deepflow_openagent_cli cloudpc files upload 123 --file ./report.pdf \
  --upload-id UPLOAD_ID --sandbox-id SANDBOX_ID
```

Uploads accept 1 byte–50 MiB and create `/workspace/files/uploads` automatically.
The returned path is `/workspace/files/uploads/<upload_id>-<original_filename>`;
use that path in subsequent OCR or chat commands. The ID prefix prevents duplicate
files after a lost response. Reusing the same ID/name with different bytes is
rejected. The sandbox ID pins retries to the original development environment.
This admin/config API accepts binary content; channel visitor format restrictions
still apply only to visitor uploads. Uploading does not automatically start OCR.

Uploads and `dev exec` submission/status/stop retry connection failures and HTTP
408/429/502/503/504 up to four times (1/2/4/8 second delays). Execution retries keep
the same execution ID and output cursor. Upload retries resend the whole binary
body; chunk resume is not implemented. Other mutating commands are not retried.
Requires updated CLI, API server and Cloud PC control plane; no VM image rebuild
is needed for the upload writer.

Additional operations:

```bash
deepflow_openagent_cli cloudpc create --name "Assistant"
deepflow_openagent_cli cloudpc config update 123 --json-file ./config.json
deepflow_openagent_cli cloudpc dev pause 123
deepflow_openagent_cli cloudpc dev resume 123
deepflow_openagent_cli cloudpc files mkdir 123 --path skills/demo
deepflow_openagent_cli cloudpc files rename 123 --src old.md --dst new.md
deepflow_openagent_cli cloudpc files delete 123 --path old.md
deepflow_openagent_cli cloudpc dev destroy 123
deepflow_openagent_cli docs show cloudpc.files.write --json
```

Config update replaces configuration: provide `model_name`, `reasoning_effort`
and the complete `env_vars` list (omitting `env_vars` resets it to `[]`).
Use `high` or `max` for the three supported DeepSeek models; use `default` for
Kimi K2.6, GLM-5.1, MiMo V2.5 Pro and MiniMax M2.7. Unsupported models are rejected.
Reasoning is always enabled. The deprecated `thinking_enabled` field is ignored.
Legacy clients omitting effort retain a valid saved effort when switching between
adjustable models; otherwise the new-model default is `high` or `default`.
Explicit null or invalid effort is rejected. Changes apply to the next turn,
without republishing a version. For example (replace `env_vars` with the complete
list to retain existing environment variables):

```bash
deepflow_openagent_cli cloudpc config update 123 --json '{"model_name":"deepseek-flash","reasoning_effort":"max","env_vars":[]}'
```

Change `max` to `high` for high reasoning effort.
Config queries include environment variable values. File mutation and snapshot
operations share the per-agent management lock; direct writes by the sandbox's
Agent or terminal are outside that lock. Upload and execution requests have a
120-second per-attempt timeout and the retries described above. Other Cloud PC
HTTP requests have a 900-second timeout and are not automatically retried. After a timeout, inspect sandbox or
version state before retrying a mutation. Conversation logs and chat-control
routes still require an administrator session.

### Execute commands and talk to the development Agent

Both commands require **config** scope and an existing development sandbox.
`exec` requires it to be running; Agent chat can resume a paused sandbox.

```bash
# Install and verify a library inside the development sandbox.
deepflow_openagent_cli cloudpc dev exec 123 \
  --command "python3 -m pip install pandas" --timeout 600
deepflow_openagent_cli cloudpc dev exec 123 \
  --command "python3 -c 'import pandas; print(pandas.__version__)'"

# Ask the same built-in Agent used by the web development workbench.
deepflow_openagent_cli cloudpc dev chat 123 \
  --message "Install pandas, verify import, and update the dependency declaration"
deepflow_openagent_cli cloudpc dev chat 123 \
  --conversation-id 456 --message "Also verify CSV parsing with a small example"
```

Commands run through `/bin/bash -lc`, without a PTY or interactive stdin. `--cwd`
is relative to `/workspace/agent` (default `.`). Agent-configured environment
variables are passed to the command. `--timeout` defaults to 600 seconds and
accepts 1–7200. stdout/stderr are shown separately; the CLI returns the remote
exit code (130 for cancellation, 124 for timeout). Ctrl+C requests remote
cancellation, killing the command process group and its ordinary descendants.
Background daemons are not supported. The group leader also stops the command
if its owning bridge dies.

Each command prints `execution_id` to stderr **before submission**. Network
loss does not restart or cancel it. Use that ID to inspect, attach, or stop:

```bash
deepflow_openagent_cli cloudpc dev exec-status 123 EXECUTION_ID
deepflow_openagent_cli cloudpc dev exec-attach 123 EXECUTION_ID --after 12
deepflow_openagent_cli cloudpc dev exec-stop 123 EXECUTION_ID
```

`--after` is the last received output cursor (default 0 replays retained output).
Use `--execution-id` on `exec` to supply a stable ID: identical submissions return
the same retained execution; reusing an ID with different inputs is rejected.
The sandbox retains 32 recent executions and at most 1 MiB / 4096 output events
per execution. Runtime restart or eviction loses these records; attach reports
an error and never runs the command again. IDs refer to the current development
sandbox, not to a destroyed/replaced one.

Agent chat prints `client_message_id` and `conversation_id` to stderr. Reply text
goes to stdout, tool activity to stderr; `--json-events` emits structured NDJSON
with SSE event IDs. To reconnect to the original task without submitting it again:

```bash
deepflow_openagent_cli cloudpc dev chat 123 \
  --attach --client-message-id ROUND_ID --conversation-id 456 \
  --last-event-id r1-e12
deepflow_openagent_cli cloudpc dev chat-stop 123 \
  --client-message-id ROUND_ID --conversation-id 456
```

`--last-event-id` is optional; omit it to replay available buffered events.
Ctrl+C sends `chat-stop`. A lost HTTP connection leaves the detached task running;
`--attach` only subscribes, and fails if its retained task is unavailable. Include
the conversation ID when stopping after an API-worker restart so the remote Pi
round can also be stopped. SSE errors, failed/cancelled tasks, and streams ending
without `done` return a nonzero CLI exit code.

A development Agent round, shell command, file mutation, snapshot, pause or destroy
cannot overlap conflicting development work. This includes browser workbench
rounds and remote work surviving an API-worker restart. Ordinary file reads remain
available. Generic chat/conversation creation also requires config permission
when targeting development; normal published API chat retains chat scope.

After installation or Agent edits, use `cloudpc versions save` and optionally
`versions publish` to preserve and publish the environment. Deploy the updated
OpenAgent backend, cloudpc VM service, and bridge bundle together; update the CLI
package as well. No database migration is required.

### Cloud PC channels

Cloud PC channel settings use `cloudpc channels`, separately from Agent settings
(`cloudpc config`) and Web SDK channels (`channels`). These commands require an
API key with `config` scope and Cloud PC enabled for the tenant. The backend must
also include support for API key authentication on `/api/v1/cloudpc/channels`;
older backends accept administrator sessions only.

```bash
deepflow_openagent_cli cloudpc channels list --page 1 --per-page 20
deepflow_openagent_cli cloudpc channels create --name "Cloud workspace"
deepflow_openagent_cli cloudpc channels agent-options
deepflow_openagent_cli cloudpc channels get 7
deepflow_openagent_cli docs show cloudpc.channels.update --json
```

Update uses the existing PUT replacement contract. Read the current channel
first and prepare `channel.json` with the complete name, description, ordered
`agent_ids` and `appearance`. Convert the returned `bindings` to their `id`
values; the GET response is not itself an update payload.

```json
{
  "name": "Cloud workspace",
  "description": "Team assistant",
  "agent_ids": [123, 456],
  "appearance": {
    "pageTitle": "Workspace",
    "title": "Assistant",
    "embedButtonBgColor": "#18181B",
    "embedButtonIconColor": "#FFFFFF",
    "userMessageStyle": {
      "backgroundColor": "#1A1A1A",
      "borderColor": "#CCCCCC",
      "textColor": "#FFFFFF",
      "borderRadius": {
        "topLeft": 14,
        "topRight": 14,
        "bottomLeft": 14,
        "bottomRight": 4
      }
    }
  },
  "require_auth": false,
  "file_upload": {
    "enabled": true,
    "allowed_extensions": [".pdf", ".txt"]
  }
}
```

```bash
deepflow_openagent_cli cloudpc channels update 7 --json-file ./channel.json
deepflow_openagent_cli cloudpc channels get 7
```

`--json` also accepts an inline JSON object. `name` is required; omitted
`description`, `agent_ids` and `appearance` reset to null, an empty list and
empty appearance respectively. Omitted/null `require_auth` and `file_upload`
preserve the current values. Enabling uploads requires at least one extension.
Only Cloud PCs belonging to the current tenant can be bound (up to 20).

User message styles are configured under `appearance.userMessageStyle` in the
same update payload. They apply to both main and follow-up messages, including
history and SDK embeds, after opening or refreshing the channel. They do not
change Agent replies or the admin workbench.

| Field | Value | Reset behavior |
| --- | --- | --- |
| `backgroundColor` | `#RRGGBB` | Empty string, null or omission restores each bubble's default |
| `borderColor` | `#RRGGBB`, rendered as a 1px solid border | Empty string, null or omission removes the border |
| `textColor` | `#RRGGBB`, also applied to the follow-up label | Empty string, null or omission restores the default |
| `borderRadius` | Object containing all four integer corners, 0–100 px | Null or omission restores each bubble's default |

The server trims and uppercases colors. Radius keys are `topLeft`, `topRight`,
`bottomLeft`, and `bottomRight`; partial groups, negative/fractional/out-of-range
values, strings and booleans are rejected with HTTP 422 (CLI exits nonzero).
To clear only one override, set that field to null while retaining the other
settings. To reset all user message styles, set `"userMessageStyle": null` in
the complete `channel.json`, then run the same update command. The outer PUT
still replaces `appearance` and bindings: keep all unrelated settings from the
GET response in the payload. Reading the channel returns the saved style under
`appearance.userMessageStyle`.

`deepflow_openagent_cli cloudpc channels delete 7` deletes the channel and
destroys its instances. The server entry point
`python -m app.openapi_cli cloudpc channels ...` supports the same commands.
This feature requires updating the backend and CLI; no database migration or
Cloud PC sandbox image update is needed.
