Host Integration
taskbridge-fastapi is designed to be embedded into a host FastAPI application, not to replace it. The host owns the application shell and infrastructure wiring; TaskBridge owns the task-streaming contract and orchestration around it.
What the host owns
The host application owns:
FastAPI()construction;- middleware and request lifecycle;
- authentication strategy;
- dependency override wiring;
- concrete
TaskRegistry,EventStore, andTaskExecutorimplementations; - any runtime adapter instances such as Temporal clients.
The host is also the right place for product-specific preprocessing before a task is created.
What TaskBridge owns
TaskBridge owns:
- typed models and stable error envelopes;
- service-layer orchestration;
- reusable HTTP, SSE, and WebSocket route builders;
- replay-safe task event delivery semantics;
- host-overridable observability and readiness abstractions.
The host should not re-implement stream loops manually if a TaskBridge helper already covers that case.
Ownership boundary
flowchart TD
Host[Host FastAPI app]
Host --> AppShell[App shell and middleware]
Host --> Auth[Auth and dependency wiring]
Host --> Infra[Registry, event store, executor instances]
TaskBridge[taskbridge-fastapi] --> Models[Models and errors]
TaskBridge --> Services[Services]
TaskBridge --> Routes[Route builders]
TaskBridge --> Runtime[Stream runtime helpers]
Real integration shape
from fastapi import FastAPI
from taskbridge.routes_http import build_http_router, install_http_exception_handlers
from taskbridge.routes_ws import build_ws_router
app = FastAPI()
app.include_router(build_http_router())
app.include_router(build_ws_router())
install_http_exception_handlers(app)
This is the intended integration direction: use TaskBridge route builders and then wire host-specific dependencies underneath them.
Dependency override model
The route builders rely on dependency hooks such as:
get_task_creation_serviceget_task_polling_serviceget_task_cancellation_serviceget_task_action_serviceget_websocket_subscription_serviceget_auth_context_resolverget_ownership_policyget_upload_policyget_metrics_sinkget_transport_diagnostics_sinkget_readiness_probe
This keeps route code generic while letting the host inject real infrastructure.
Good host patterns
- keep auth resolution in host wiring and convert it into
AuthContext; - keep storage implementations outside the TaskBridge package;
- keep runtime-specific clients and adapters in your host or adapter layer;
- keep domain-level task shaping outside the generic route and service code.
Durable action acceptance
Hosts own action-specific validation; the generic library treats payload and metadata as opaque dictionaries.
- TaskBridge verifies task ownership and the suspension's
allowed_actions. - Exact action-ID replays deduplicate only when
suspend_id,action_type,payload, andmetadataall match. Any difference is an idempotency conflict. Ana2ui_actionwith empty metadata is rejected before receipt lookup, so a legacy receipt cannot make a new request without a snapshot appear accepted. - For a new action on an open suspension, an injected
ActionValidationPolicy.validate_action(command, task, suspension)may validate host-specific rules before acceptance. It must raiseInvalidRequestErrorfor invalid input and must not mutate the command, task, or suspension. Fora2ui_action, the host policy is required and must validate the model snapshot plus any negotiated capabilities, current surface/component/action, and referenced media or context. TaskBridge does not define snapshot keys or an A2UI schema. - After validation, TaskBridge claims the open suspension via CAS. It then stores the accepted receipt, including the complete payload and metadata snapshot, and appends
TASK_ACTION_ACCEPTED. - The host resume handler receives the accepted command. If dispatch fails, the handoff remains pending and reconciliation retries from the receipt snapshot. Legacy
a2ui_actionreceipts without metadata remain pending instead of being dispatched. The base no-opTaskResumeServiceis not valid for A2UI: a host override is required before acceptance or reconciliation.
The CAS, receipt store, and event store are not one cross-store transaction. Recovery is guaranteed only after the receipt and accepted event have both been stored; a crash in the intervening write window can leave pending state without one of them.
Bad host patterns
- handwritten SSE generators that duplicate TaskBridge stream runtime helpers;
- direct vendor runtime logic inside
taskbridge-fastapicore; - embedding product authorization rules directly in generic route code.