Metadata-Version: 2.4
Name: identity-agnostic-worker
Version: 0.1.0
Summary: Identity-agnostic worker client: register to a broker, receive tasks, stream results back.
Author: Rexllnia
License: MIT
Project-URL: Homepage, https://github.com/Rexllnia/identity-agnostic-worker
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: websockets>=12
Provides-Extra: dev
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"

# identity-agnostic-worker

A minimal Python client for AI workers that connect to an
[identity-agnostic broker](https://github.com/Rexllnia/identity-agnostic-broker).

一个极简的 Python 客户端，用于让 AI 员工（worker）连接到
[identity-agnostic broker](https://github.com/Rexllnia/identity-agnostic-broker)。

A **worker** registers itself to a broker, receives one task at a time, streams
back the result in chunks, and marks the end of the stream. The worker never
needs to know who sent the task or who will receive the result — the broker
takes care of matching and routing.

**Worker** 向 broker 注册，一次接收一个任务，把结果分片流式回传，最后标记流结束。
worker 不需要知道任务是谁发的，也不需要知道结果发给谁——匹配和路由全部由 broker 负责。

This package only contains the worker-side client. It depends on
`websockets` and nothing else.

本包只包含 worker 端客户端，只依赖 `websockets`，不拖其他依赖。

---

## Install / 安装

```bash
pip install identity-agnostic-worker


Requires Python 3.10+.

需要 Python 3.10 及以上。

Quick start / 快速开始
python
import asyncio
from identity_agnostic_worker import WorkerClient


async def process(text: str):
    """你的 AI / Playwright 逻辑：把 text 变成一段一段的结果。"""
    for ch in text:
        yield ch


async def main():
    client = await WorkerClient.register("ws://127.0.0.1:9000/ws")

    while True:
        text = await client.recv()
        if text is None:
            break  # 连接断开 / connection closed

        async for chunk in process(text):
            await client.send(chunk)

        await client.send(None)  # 流结束 / end of stream


asyncio.run(main())
register() 不传参数时，默认连 ws://127.0.0.1:9000/ws。

When called without arguments, register() connects to
ws://127.0.0.1:9000/ws by default.

API
await WorkerClient.register(broker_url="ws://127.0.0.1:9000/ws") -> WorkerClient
向 broker 注册，返回一个 WorkerClient。注册成功后，broker 会把这个 worker
放进待命池，有匹配的任务时派给它。

Register to the broker and return a WorkerClient. Once registered, the
broker puts this worker on its bench and dispatches matching tasks to it.

await client.recv() -> str | None
阻塞等待一条用户消息。

Block until a user message arrives.

返回 str：新的任务文本，可以开始处理。
Returns str: a new task text, ready to be processed.

返回 None：与 broker 的连接已断开，应退出循环。
Returns None: the connection to the broker is closed; exit the loop.

await client.send(chunk: str | None)
把结果分片发回 broker。

Send one chunk of the result back to the broker.

传 str：发送一个 chunk。空字符串 "" 是合法 chunk。
Pass str: send a chunk. An empty string "" is a valid chunk.

传 None：表示这一轮任务结束。
Pass None: marks the end of this task.

await client.close()
主动关闭连接。通常在 finally 里调用，保证异常退出时也能释放连接。

Close the connection explicitly. Usually called in a finally block so the
connection is released even on errors.

Protocol / 协议
worker 与 broker 之间用 WebSocket + JSON 通信，四个消息类型：

Worker and broker communicate over WebSocket + JSON with four message types:

方向 Direction	消息 Message
worker → broker	{"type": "register"}
broker → worker	{"type": "registered", "sid": "..."}
broker → worker	{"type": "message", "request_id": "...", "text": "..."}
worker → broker	{"type": "chunk", "request_id": "...", "text": "..."}
worker → broker	{"type": "end", "request_id": "..."}
一个 worker 同一时间只处理一条任务。收到 message 后，用同一个 request_id
发 chunk，最后发 end。

A worker handles one task at a time. After receiving message, send chunk
with the same request_id, and finish with end.

和 broker 的关系 / Relation to the broker
text
openai-compatible client
        │  POST /send
        ▼
   identity-agnostic-broker   ← 匹配任务和 worker / matches tasks to workers
        │  WS: message / chunk / end
        ▼
   identity-agnostic-worker   ← 你在这里 / you are here
        │
        ▼
  你的 AI 逻辑（Playwright、本地模型、任何能产出流式文本的东西）
  Your AI logic (Playwright, local model, anything that streams text)
worker 不保存任何路由状态，也不关心发送者或接收者的身份。所有匹配逻辑都在
broker 里，worker 只负责“收任务 → 干活 → 回流”。

The worker keeps no routing state and does not care about sender or receiver
identity. All matching lives in the broker; the worker only does
"receive task → work → stream back".

License
MIT
