-
Notifications
You must be signed in to change notification settings - Fork 10
Architecture
Contract-driven agent platform for travel distribution, with pipeline validation and LLM orchestration.
graph TB
subgraph "LLM Layer"
LLM["Claude / any tool-calling LLM"]
end
subgraph "Agent Layer (75 agents)"
REF["Stage 0 Reference (7)"]
SEARCH["Stage 1 Search (9)"]
PRICE["Stage 2 Pricing (7)"]
BOOK["Stage 3 Booking (8)"]
TICKET["Stage 4 Ticketing (5)"]
EXCH["Stage 5 Exchange (6)"]
SETTLE["Stage 6 Settlement (6)"]
RECON["Stage 7 Reconciliation (6)"]
TMC["Stage 8 TMC (5)"]
PLAT["Stage 9 Platform (9)"]
LODGE["Stage 20 Lodging (7)"]
end
subgraph "Pipeline Infrastructure"
TB["Tool Bridge<br/>agentToTool()"]
PV["Pipeline Validator<br/>6 gates"]
CR["Capability Registry"]
ES["EventStore"]
end
subgraph "Adapter Layer"
AMADEUS["Amadeus GDS"]
SABRE["Sabre GDS"]
NAV["Navitaire LCC"]
TP["TripPro Aggregator"]
DUFFEL["Duffel NDC"]
HAIP["HAIP Hotel"]
end
subgraph "Suppliers"
S1["Airlines"]
S2["Hotels"]
end
LLM -->|tool_use| TB
TB -->|runAgent| PV
PV -->|execute| REF & SEARCH & PRICE & BOOK & TICKET & EXCH & SETTLE & RECON & TMC & PLAT & LODGE
PV -->|append| ES
SEARCH & BOOK --> CR
CR --> AMADEUS & SABRE & NAV & TP & DUFFEL & HAIP
AMADEUS & SABRE & NAV & TP & DUFFEL --> S1
HAIP --> S2
Every agent invocation runs through six gates. Gates 1–4 run before execute(), gates 5–6 run after.
sequenceDiagram
participant LLM
participant Bridge as Tool Bridge
participant PV as Pipeline Validator
participant Agent
participant ES as EventStore
LLM->>Bridge: tool_use(input)
Bridge->>PV: runAgent(session, agentId, input)
Note over PV: Gate 1 — Intent Lock
PV->>PV: checkIntentRelevance & drift
Note over PV: Gate 2 — Schema In
PV->>PV: inputSchema.safeParse(input)
Note over PV: Gate 3 — Semantic In
PV->>PV: contract.validate(input, ctx)
Note over PV: Gate 4 — Cross-Agent
PV->>PV: checkConsistency(input, priorOutputs)
PV->>Agent: execute(input)
Agent-->>PV: AgentOutput
Note over PV: Gate 5 — Schema Out + Confidence
PV->>PV: outputSchema.safeParse & confidence >= floor
Note over PV: Gate 6 — Action Classification
PV->>PV: irreversible mutations require approval
PV->>ES: append(agent.executed)
PV-->>Bridge: RunAgentResult
Bridge-->>LLM: tool_result
| Gate | Runs | Purpose |
|---|---|---|
| 1 Intent Lock | before execute | Agent is relevant to the session intent; no drift |
| 2 Schema In | before execute | Zod safeParse on input against contract.inputSchema
|
| 3 Semantic In | before execute | Domain checks via contract.validate()
|
| 4 Cross-Agent | before execute | Input fields consistent with prior agent outputs |
| 5 Schema Out + Confidence | after execute | Output structure valid; output.confidence >= threshold
|
| 6 Action Classification | after execute | Irreversible mutations gated behind approval |
The tool bridge converts a contracted agent into an LLM-callable tool. No hand-written JSON schemas.
graph LR
subgraph "Contract"
AC["AgentContract<br/>inputSchema<br/>outputSchema<br/>actionType<br/>validate()"]
end
subgraph "Bridge"
ATT["agentToTool()"]
end
subgraph "ToolDefinition"
TD["name (AGENT_TOOL_NAMES)<br/>description<br/>inputSchema: Zod<br/>execute()"]
end
subgraph "Anthropic API"
AT["Anthropic.Tool<br/>input_schema: JSON Schema"]
end
AC --> ATT --> TD -->|zodToJsonSchema| AT
The agent loop (@otaip/core/agent-loop) drives the Anthropic Messages API, converts each tool_use block into a runAgent() call against the pipeline validator, then returns tool_result blocks to the model.
Every agent execution is appended to the EventStore. Governance agents (9.6–9.9) query the store to audit the platform.
graph TB
subgraph "Event types"
AE["agent.executed"]
RD["routing.decided"]
RO["routing.outcome"]
BC["booking.completed"]
BF["booking.failed"]
AH["adapter.health"]
end
subgraph "EventStore"
ES["append(event)<br/>query(filter)<br/>aggregate(metric, window)"]
end
subgraph "Implementations"
IM["InMemoryEventStore (ships with core)"]
PG["PostgresEventStore (planned)"]
end
AE & RD & RO & BC & BF & AH --> ES --> IM
ES -.-> PG
The capability registry maps abstract functions (search, price, book, ticket, refund) to concrete channels. Each adapter registers a ChannelCapabilityManifest:
-
channelId,channelType(gds|ndc|lcc|hospitality|aggregator) -
supportedCarriers,supportedFunctions -
reliabilityScore,latencyScore,costScore -
supportsOrders(when AIDM 24.1 order operations are implemented)
The GdsNdcRouter (3.1) reads the registry to route a booking to the best channel for each carrier.
packages/
core/ @otaip/core — Agent interface, errors, pipeline validator,
tool bridge, EventStore, agent loop, OfferEvaluator (1.9)
connect/ @otaip/connect — ConnectAdapter interface, BaseAdapter,
Amadeus, Sabre, Navitaire, TripPro, HAIP
adapters/duffel/ @otaip/adapter-duffel — standalone Duffel NDC adapter
cli/ @otaip/cli — command-line interface
agents/
reference/ @otaip/agents-reference — Stage 0
search/ @otaip/agents-search — Stage 1
pricing/ @otaip/agents-pricing — Stage 2
booking/ @otaip/agents-booking — Stage 3
ticketing/ @otaip/agents-ticketing — Stage 4
exchange/ @otaip/agents-exchange — Stage 5
settlement/ @otaip/agents-settlement — Stage 6
reconciliation/ @otaip/agents-reconciliation — Stage 7
lodging/ @otaip/agents-lodging — Stage 20
agents-tmc/ @otaip/agents-tmc — Stage 8
agents-platform/ @otaip/agents-platform — Stage 9
examples/
ota/ @otaip/ota-example — reference OTA
demo/ pipeline demos
All 16 packages typecheck clean with TypeScript strict mode.
-
Contract-first. Agent behavior is declared as an
AgentContractwith Zod schemas. No hand-written JSON schemas. -
Pipeline-validated. Six gates run around every
execute()call. The LLM cannot hallucinate offer IDs, change destinations mid-flow, or ticket without approval. - Event-sourced observability. Every execution is logged with duration, confidence, and gate results for governance agents to analyze.
-
Adapter-agnostic. Agents talk to a
ConnectAdapter/DistributionAdapterinterface. Swapping suppliers does not touch agent code. -
Domain-safe. No invented domain logic. Travel edge cases are surfaced as
DOMAIN_QUESTIONcomments, never guessed.