Ctrl K
ComunidadGuías…

server/README.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Bumblehive Server

FastAPI adapter for the Bumblehive Python SDK.

## Development

From the repository root:

```bash
conda activate bumblehive_env
pnpm run setup
pnpm run dev:server
```

See the root README for the Node.js and pnpm prerequisites. The root launcher sets the cross-platform `PYTHONPATH` automatically. Use `pnpm run dev` to start the Server and WebUI together.

The server listens on `127.0.0.1:18421` by default and reads configuration from
`~/.bumblehive/config.json`.

Environment overrides:

```text
BUMBLEHIVE_CONFIG=/path/to/config.json
BUMBLEHIVE_HOST=127.0.0.1
BUMBLEHIVE_PORT=18421
BUMBLEHIVE_ALLOWED_ORIGINS=http://127.0.0.1:1420,tauri://localhost
```

## API

```text
GET    /api/v1/health
GET    /api/v1/settings
PUT    /api/v1/settings
POST   /api/v1/sessions
GET    /api/v1/sessions
GET    /api/v1/sessions/{session_id}
DELETE /api/v1/sessions/{session_id}
WS     /ws/v1/chat/{session_id}
```

### Chat input

Send `{"type":"message","message_id":"unique-id","content":"..."}` to start a
turn or queue a follow-up. Follow-ups run one at a time in submission order.
Use `{"type":"steer","message_id":"..."}` to send a queued message into the
current turn, or `{"type":"remove_pending","message_id":"..."}` to remove it.
The server acknowledges each change with `message_status`: `queued`, `started`,
`steered`, or `removed`.

Each session owns its run, pending messages and approvals. Closing the WebSocket
only disconnects that subscriber. On reconnect, `ready` returns the current run,
pending messages and approvals; load saved conversation history through the
session API. Stream events from the disconnected interval are not replayed.
Cancellation and errors pause follow-ups; send a pending message explicitly to
resume. Steering that the SDK has not consumed is restored with its original
message ID and queue order. Its `queued` receipt includes a zero-based `position`
so clients can reinsert the card at the correct place. Consumed steering is not
requeued. Pending messages survive a connection loss, but are held in memory and
do not survive a server restart.

### Ask user

The application registers `ask_user(question, options?)` without requiring tool
approval. It asks one question, with optional suggested answers and an always
available free-text input above the composer. Its `task_id` is the originating
tool call ID, shared by the card, submissions, and results.

During the first 60 seconds, an answer returns
`{"task_id":"...","status":"answered","answer":"..."}` and skipping returns
`{"task_id":"...","status":"skipped"}`. Otherwise the tool returns
`{"task_id":"...","status":"pending"}` and keeps the question answerable for
up to 120 more seconds. A background answer delivers `answered`; skipping,
closing the card, or reaching the deadline delivers `skipped`. Background results
use the session notification queue: steering while running, a new turn while
naturally idle, or queued until resume after a stop or error. They do not append
a second tool response for the original call.

The server sends `question_request`. Submit
`{"type":"question_answer","task_id":"...","answer":"..."}` to answer, or
`{"type":"question_skip","task_id":"..."}` to skip. The × and Skip buttons
both end the question. On completion, the server removes the question and sends
`question_closed`; the frontend removes its card. The first answer, skip, or
expiration wins. Input errors include `task_id` so the corresponding card can be
resubmitted. Ended questions are not retained or replayed.

Only unresolved questions appear in `ready.questions`. Switching sessions or
losing the connection does not reset the server deadline. Stopping during the
initial wait leaves the card answerable without starting a background deadline;
a later answer follows the normal user-input path. Stopping after `pending`
leaves the background deadline running, but automatic results do not resume the
stopped Agent. Closing or deleting the server session cancels its question
waiters. Questions do not survive a server restart. Sub-agents do not receive
this tool.

Backend callers can deliver input to a running turn or start one while idle:

```python
controller = service.get_session_controller(session_id)
await controller.submit(request, steer=True)
```

### Sub-agents

The server's read-only `sub_agent(title, task)` runs in the background and returns
`{"status":"pending","task_id":"..."}` after startup. The task ID is the
originating tool call ID; success and failure reports include that same ID.
The final report or failure is delivered automatically to the parent: through
steering while running, or a new turn when naturally idle. After a stop or error,
reports stay queued until the user resumes. Background work survives disconnects
and parent-turn cancellation; deleting its session cancels it.

The parent's `ready.running_subagents` lists active background children for
reconnection. Child events retain their own session IDs. Task ownership and
pending reports are in memory; conversation history is saved as usual.

### Background result messages

The server wraps Ask User and sub-agent background results in the same
`user` message format, using the original tool call ID:

```text
[Background tool result]
Task ID: call_123

Tool return content
```

Strings are included as-is; structured results are serialized as JSON. Each
tool defines its own result content. This is a later conversation input, not a
second tool response for the original call.

## Desktop sidecar

Build the standalone binary from the repository root with the Python build
environment activated:

```bash
pnpm run build:sidecar
```

The script writes a standalone directory to
`desktop/src-tauri/sidecar/bumblehive-server/`. Tauri bundles that directory,
starts its executable when the desktop application opens, and stops it when
the application exits.