مخزن اختصاصی برنامهٔ وب؛ محتوای پوشهٔ web در ریشهٔ مخزن قرار گرفت. تاریخچهٔ پروژهٔ ربات (agy-bot) در این مخزن وجود ندارد و هیچ وابستگی runtime به آن نیست.
52 lines
1.9 KiB
Markdown
52 lines
1.9 KiB
Markdown
# `@agy/ai-runtime`
|
|
|
|
Drains the queue of tasks nobody has run yet, through the real run engine.
|
|
|
|
```bash
|
|
pnpm --filter @agy/ai-runtime run # one pass, then exit
|
|
pnpm --filter @agy/ai-runtime dev # poll every 30s
|
|
```
|
|
|
|
## Why it exists
|
|
|
|
The API can start a run inline — that is what the «اجرا» button does. But a
|
|
platform that *only* runs work on the request thread has two problems: a slow
|
|
model call holds a connection open, and a task created by anything other than a
|
|
button press (an automation, a seed script, a future integration) never runs at
|
|
all. This worker is the second driver.
|
|
|
|
## What it does
|
|
|
|
1. Find tasks in `new` or `triaged` state, oldest first.
|
|
2. Re-read each through `WorkforceService.get_task_or_404` — so the tenant check
|
|
and the "already closed" guard both apply. **The worker gets no privileged
|
|
bypass.**
|
|
3. Hand it to `WorkforceService.start_run` — the exact call the router makes.
|
|
4. Record the outcome and continue. One poisoned task must not block the queue
|
|
behind it.
|
|
|
|
Model routing, usage accounting, the run timeline and the artifact are all the
|
|
service's business; the worker owns none of it.
|
|
|
|
## Idempotency
|
|
|
|
A task that has been run is no longer in `new`/`triaged`, so a second pass finds
|
|
nothing. Re-running a completed task would double-bill the customer, which is
|
|
why the query filters on state rather than on "has a run".
|
|
|
|
## Implementation
|
|
|
|
`apps/api/app/workers/ai_runtime.py`. Tests:
|
|
`apps/api/tests/test_workers.py`.
|
|
|
|
## Extracting this into its own process
|
|
|
|
```bash
|
|
DATABASE_URL=... python -m app.workers ai-runtime --loop --interval 30
|
|
```
|
|
|
|
Note that the run engine currently executes inline within the worker process. To
|
|
make runs *asynchronous* for the customer (return `queued`, complete later), the
|
|
next step is to have the API enqueue and this worker claim, rather than having
|
|
the API call `start_run` directly. The port boundary for that already exists.
|