Skip to content

โ† Back to index

1. Concepts

1.1 Actors

  • Exchange (EXCHANGE_ID) โ€” one Xchange deployment is one exchange. It owns its own MongoDB database (exchange_{EXCHANGE_ID}, see ยง2.4) and its own set of subjects. There is no cross-exchange query surface โ€” "all subjects in the exchange" always means "every ExchangeSubjects document in this deployment's database".
  • Task (ExchangeTasks) โ€” a unit of work submitted to the exchange. Its task_assignment_type picks one of four orchestration strategies (ยง1.2); its task_metadata.task_assignment sub-object carries the parameters that strategy needs (which subject, which function, which bid-job fields, ...).
  • Subject (ExchangeSubjects) โ€” a registered agent that can receive tasks. Subjects are plain CRUD records (ยง3.3) โ€” there is no separate "join the exchange" workflow beyond creating the record. A subject's task_evaluation_function field is only consulted by the open assignment mode.
  • Selector function (function mode only) โ€” an external function, resolved by function_id, invoked once with the task and the full subject list; it must return a selected_subject_id. See ยง5.1.
  • Task evaluation function (open mode only) โ€” each subject carries its own, via ExchangeSubjects.task_evaluation_function. Called per-subject, in order, until one accepts. See ยง5.2.
  • Delegate system (SUBJECT_DELEGATE_URL) โ€” the same external service Orcade uses to reach a live subject and get a response back (SubjectTask.submit_and_wait, see ยง6). Xchange never talks to a subject directly.
  • Function registry (FUNCTION_REGISTRY_URL) โ€” the same external function-hosting service Orcade uses. Xchange resolves selector / task-evaluation function_ids against it via FunctionCaller (see ยง5), reusing the exact same agents_functions client code as Orcade.
  • Orcade / bidding system (BIDDING_SERVICE_URL) โ€” used only by the bidding assignment mode. Xchange acts as a creator against Orcade's own /bid-jobs API โ€” see ยง7.

1.2 The four assignment modes

Set on submission via task_assignment_type:

Mode Selection Assignment timing Submission timing
direct Caller names the subject_id up front. No selection logic runs at all. N/A (fixed) Background thread
function A single selector function picks one subject from the full subject list. Synchronous (blocks the POST /tasks call) Background thread
open Each subject's own task_evaluation_function is asked in turn; first "accepted" wins. Entirely on a background thread Same background thread (sequential, not parallel)
bidding Delegated wholesale to Orcade: a bid job is opened for the subject set and Orcade's own evaluator picks the winner. Entirely on a background thread Handled by Orcade, not Xchange; Xchange only polls for the outcome
 direct:    POST /tasks โ”€โ”€โ–บ persist task โ”€โ”ฌโ”€โ–บ return 201 to caller
                                           โ””โ”€โ–บ [thread] submit_and_wait(subject_id) โ”€โ”€โ–บ save task_output

 function:  POST /tasks โ”€โ”€โ–บ persist task โ”€โ”€โ–บ call selector function (blocking)
                                           โ”œโ”€โ–บ return 201 to caller (status="assigned")
                                           โ””โ”€โ–บ [thread] submit_and_wait(selected_subject_id) โ”€โ”€โ–บ save task_output

 open:      POST /tasks โ”€โ”€โ–บ persist task โ”€โ”€โ–บ return 201 to caller
                                           โ””โ”€โ–บ [thread] for each subject:
                                                          call subject.task_evaluation_function
                                                          if "accepted" โ†’ submit_and_wait(subject_id) โ”€โ”€โ–บ save task_output; stop
                                                          if none accept โ†’ status="rejected"

 bidding:   POST /tasks โ”€โ”€โ–บ persist task โ”€โ”€โ–บ return 201 to caller
                                           โ””โ”€โ–บ [thread] create Orcade bid job
                                                          poll Orcade for a "bid_winner" task-result
                                                          save it as task_output

Key behavioral notes:

  • POST /tasks always returns as soon as the task is persisted and (for function mode only) a subject has been synchronously selected. It never waits for the subject's actual response โ€” that always happens on a background thread, for all four modes. Poll GET /tasks/{task_id} or GET /tasks/{task_id}/output (ยง3.4) to find out what happened.
  • function mode is the only mode with a synchronous step. Selecting the subject happens inline inside the request handler; if the selector function raises or doesn't return selected_subject_id, POST /tasks itself fails (400) and the task is marked failed โ€” nothing is submitted to any subject.
  • open mode evaluates subjects sequentially, not in parallel, and stops at the first acceptance. Subject order is whatever ExchangeSubjectsCRUD.list() returns (MongoDB's natural document order โ€” not otherwise guaranteed). If a subject's task_evaluation_function call raises, that subject is treated as a non-accept (logged and skipped) rather than failing the whole task.
  • bidding mode has no timeout. It polls Orcade's /bid-jobs/{id}/task-results every bid_poll_interval seconds (default 5s) forever, until a "bid_winner" entry shows up. If Orcade's own bidding never resolves (e.g. a required subject never bids), the Xchange task sits in task_assignment_status="bidding" indefinitely.
  • task_assignment_status values you'll observe: pending (just submitted, only briefly before a mode-specific handler updates it), assigned (function/open mode has picked a subject, submission thread not yet finished), bidding (bid job created, waiting on Orcade), completed (subject responded, see task_output), failed (an exception occurred โ€” see task_output.error), rejected (open mode exhausted every subject with no acceptance).

โ† Back to index ยท Next: Schema โ†’