openvibers/openvibe.codes Commits

Re-land C2: tasks with attempts and the event stream (#162), lost in #165 (#168)

OP OpenVibers committed 14 days ago · tag v0.5.0 · 0 files, +0 −0

* Tasks with attempts, a live event stream, and the engine deciding what happens next (C2)

A task is a timeline of attempts, never a new task per try. Each Run job is one
attempt; when an attempt ends the engine (engine/chain.js, engine/budget.js,
engine/router.js) looks at the task's attempts and decides: done, continue in the
same session, switch to the next agent, wrap up, or leave it unfinished.

- migrations/0010_task_attempts.sql: codes_attempts (id, task_id, n, agent, model,
  machine, job_id, session, state, reason, why, cost_usd, tokens, steps, started_at,
  finished_at, created_at, kind, follow_up_of), run_tasks.outcome / outcome_note /
  attempts_count, codes_session_lines.attempt_n. Every existing task becomes its own
  attempt 1.
- server/domain/attempts.js: the attempts and the decision. The engine's vocabulary
  is mapped onto Codes' (the reason is passed on, since the engine only reads the
  runners it knows).
- server/domain/run-tasks.js: the events inbox and the run.job.* handler update the
  attempt; the decision runs outside the transaction, because a follow-up starts a
  Run job. A follow-up is fenced by the unique follow_up_of, so two endings of the
  same attempt start one job, not two.
- server/http/task-events.js: GET /api/v1/tasks/:id/events, the session's lines in
  seq order, resumable with Last-Event-ID, a heartbeat every 15 s, the attempt each
  line belongs to and the attempts themselves.
- server/http/tasks-api.js: GET /api/v1/tasks/:id answers { task, attempts[],
  outcome }; POST /api/v1/tasks/:id/continue and /stop. The same auth as the tasks
  API: the owner, or a service with the codes.task capability.
- /run/tasks/:id shows the attempts above the session, each with its why.

* The read answers codes.task@2: the task at the top level, its attempts added

GET /api/v1/tasks/:id answers codes.task@2 now: the task's own fields stay at
the top level, exactly as codes.task@1 had them, and its attempts and its
outcome are added to them. A caller that reads the task — OpenVibe.Actor's
codes agent, which takes the answer as it comes — keeps working; one that
expected the task under a "task" key would not have.

Codes pins openvibe-contracts v0.242.0, which carries codes.task@2 (the v1
contract is unchanged, and codes.task.read declares the v2).

* Pin openvibe-contracts v0.242.1 (the release whose generated files carry
their own version)

* Pin openvibe-contracts v0.243.0 (main's release of codes.task@2)

Brings the contract package up from v0.242.1; contracts/codes is unchanged
(task.v2.json is the one the API answers), and the release adds AI credential
v2 schemas. README's "Depends on" line names the same versions as the
versions block again.

This commit has no diff to show.