Skip to content

feat(platform-ui): add Platform UI dashboard + developer playground#93

Merged
telivity-otaip merged 1 commit into
mainfrom
feat/platform-ui
May 6, 2026
Merged

feat(platform-ui): add Platform UI dashboard + developer playground#93
telivity-otaip merged 1 commit into
mainfrom
feat/platform-ui

Conversation

@telivity-otaip
Copy link
Copy Markdown
Collaborator

Summary

A new React/Vite app at examples/platform-ui/ plus the read-only telemetry endpoints that back it. Two views:

  • Dashboard — operational overview: total/active/stub agent counts, full agent registry with filter/sort/group-by-domain, adapter cards driven by env-var presence, health sidebar (uptime, requests, OTAIP version).
  • Playground — split-panel request builder + response viewer with three modes:
    • Search: full flight-search form against the configured adapter.
    • Agent: picker over every discovered agent. Whitelisted agents (v1: 0.1 AirportCodeResolver) execute end-to-end; everything else returns a clear 501 with a "not yet wired" hint.
    • Adapter: direct search / price / isAvailable against the configured adapter.

Response viewer has Formatted / Raw / Timeline tabs and a last-10 in-memory request history with one-click replay.

Why

OTAIP currently ships an OTA reference app (examples/ota) — a booking demo. There was no UI for OTAIP itself: no view of the agent registry, no view of adapter configuration, no way to poke at agents. This PR adds that — Stripe Dashboard-style control plane for travel AI agents.

Backend changes

  • @otaip/core gains src/discovery/agent-discovery.ts (moved verbatim from CLI; tweaked repoRoot() to walk up to pnpm-workspace.yaml rather than counting directories — more robust for both source and built consumers).
  • @otaip/cli agent-discovery.ts shrinks to a re-export from @otaip/core; every existing import path keeps working.
  • OTA Fastify server gains /api/platform/* (read-only telemetry, rate limit raised to 5 000/min so dashboard polling can't trip the global 100/min cap) and /api/playground/* (execution surface, AJV body schemas on every state-mutating route). One onRequest hook updates the dashboard's last-request timestamp.
  • 12 new test cases across platform.test.ts + playground.test.ts, Fastify inject() + MockOtaAdapter mirroring the existing search.test.ts shape.

Frontend changes

examples/platform-ui/ — Vite + React 18 + TypeScript strict + Tailwind + react-router-dom. ~30 files: tooling (6), src components (8), src pages (2), src API client (2), styling/config (4). Tailwind only — no MUI/Ant per the brief's "no heavyweight component library" rule. JSON viewer is a hand-rolled <pre> + copy button (no syntax-highlighter dep).

Vite proxies /apihttp://localhost:3000 in dev (override with OTA_SERVER_URL), so the browser sees same-origin and the existing CORS_ORIGIN env-var path stays untouched.

Curated agent whitelist

Generic agent execution requires PipelineOrchestrator + PipelineSession plumbing for every agent that has a Zod-typed contract. Doing that for 70+ agents would mean importing every package at boot. Instead the catalog endpoint surfaces all agents (so the picker works) but the executable_ids set starts at one — 0.1 AirportCodeResolver, the agent CLAUDE.md cites as the canonical reference pattern. Non-whitelisted IDs render a clear "not yet wired for playground execution" banner in the form area; submitting returns 501 with a pointer to the catalog. Adding more agents is a single object-literal entry in playground-service.ts.

Out of scope

  • Production packaging of the Vite app (Fastify serving the built dist/). Acceptance criteria stop at pnpm dev end-to-end; deferred.
  • Per-component unit tests on the React side. The brief asks for tests on the new endpoints — those land. UI is verified via tsc strict + manual checks.
  • Adapter book exposed through the playground — intentionally read-only.

Test plan

  • pnpm --filter @otaip/platform-ui typecheck — clean.
  • pnpm --filter @otaip/ota-example typecheck — clean.
  • pnpm --filter @otaip/cli typecheck — clean (uses the re-exported discoverAgents).
  • pnpm exec vitest run examples/ota100 passed across 9 files (88 existing + 12 new).
  • Manual: pnpm --filter @otaip/ota-example dev then pnpm --filter @otaip/platform-ui dev. Open http://localhost:5173:
    • Dashboard renders agent table grouped by domain; counts match pnpm cli agents.
    • Adapter cards reflect DUFFEL_API_KEY / HOTELBEDS_API_KEY env state.
    • Playground search returns offers from the mock or live adapter.
    • Playground agent → 0.1 with {"code":"JFK","code_type":"iata"} returns the resolved JFK record.
    • Playground agent → any other ID renders the "not yet wired" banner; clicking Execute returns 501 with the catalog hint.

🤖 Generated with Claude Code

A new React/Vite app at examples/platform-ui/ that gives developers a
visual control plane for an OTAIP instance, plus the read-only telemetry
endpoints on the existing OTA Fastify server it consumes.

This is NOT the OTA reference app. The OTA app is a flight-booking
demo; this one is OTAIP's own dashboard — agent registry, adapter
status, health sidebar, and an interactive Playground.

Reuses existing utilities per the brief (no rebuild):
- discoverAgents() from packages/cli/src/agent-discovery.ts
- generateCatalog() shape from packages/core/src/tool-interface

Backend (examples/ota):
- New routes /api/platform/{agents,adapters,health,stats} returning
  read-only telemetry. Per-route rate limit raised to 5000/min so
  dashboard polling never trips the global 100/min cap.
- New routes /api/playground/{catalog,search,agent,adapter}. catalog
  surfaces every discovered agent plus an executable_ids whitelist.
  search wraps SearchService against the configured adapter. agent
  dispatches into a curated whitelist (v1: 0.1 AirportCodeResolver);
  non-whitelisted IDs return 501 with a clear hint instead of pretending
  to run. adapter exposes search/price/isAvailable directly.
- onRequest hook tracks last-request timestamp for the health endpoint.
- Tests: 12 new cases across platform.test.ts + playground.test.ts,
  Fastify inject() + MockOtaAdapter following the existing search.test.ts
  shape.

discoverAgents move:
- packages/core gains src/discovery/agent-discovery.ts (verbatim from
  CLI, with a more robust repoRoot() that walks up to pnpm-workspace.yaml
  rather than counting directories).
- packages/cli/src/agent-discovery.ts shrinks to a re-export — every
  existing import path keeps working, behaviour unchanged.

Frontend (examples/platform-ui):
- Vite + React 18 + TS strict + Tailwind + react-router-dom.
- Dashboard: 4 stat cards, agent table with filter/sort/group-by-domain,
  adapter cards keyed off env vars, health sidebar polled every 15s.
- Playground: split-panel layout with Search/Agent/Adapter mode tabs,
  Formatted/Raw/Timeline response tabs, last-10 request history with
  one-click replay. JSON viewer is a hand-rolled <pre> + copy button —
  no heavyweight syntax-highlighter dep, matching the brief's "no
  heavy component library" rule.
- Vite proxies /api → http://localhost:3000 (override via OTA_SERVER_URL),
  so dev mode is same-origin and CORS is a non-issue.

Out of scope (intentional):
- Production packaging (Fastify serving the built dist/) — Vite dev-only
  this round.
- Generic agent execution. Whitelist starts at one; the surface to add
  more is a single object literal in playground-service.ts.

Verification:
- pnpm --filter @otaip/platform-ui typecheck → clean.
- pnpm exec vitest run examples/ota → 100/100 across 9 files.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@telivity-otaip telivity-otaip merged commit 6cac6b2 into main May 6, 2026
1 check passed
@telivity-otaip telivity-otaip deleted the feat/platform-ui branch May 6, 2026 15:52
telivity-otaip added a commit that referenced this pull request May 7, 2026
chore(release): v0.7.2 — Duffel Cars + auto-publish + post-#93 fix
ntbpy pushed a commit to ntbpy/AI_Agent_otaip that referenced this pull request May 11, 2026
 fix

Patch bump off v0.7.1. Three pieces:

- TelivityAI#99 @otaip/adapter-duffel adds Cars (search → quote → book → get
  → cancel) under /cars/. Same Bearer auth, AbortSignal threading
  on request(). 8 open DOMAIN_QUESTIONs captured in
  docs/knowledge-base/cars.md.
- TelivityAI#97 unbreaks the Release workflow's Count agents step that TelivityAI#93's
  CLI re-export indirection broke. Every push-to-main since TelivityAI#93
  had been failing silently — that's why v0.7.1's tag was created
  but the workspace npm bumps lagged behind for a while.
- TelivityAI#98 switches gh release create to RELEASE_PAT so the
  release: published event propagates to the Publish workflow.
  This is the first release that should auto-publish to npm
  without a manual workflow_dispatch.

Workspace-wide bump: 17 package.json files 0.7.1 → 0.7.2
(@otaip/adapter-duffel was already at 0.7.2 from TelivityAI#99). Going
forward, the next release is v0.7.3.

See CHANGELOG.md for details.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant