Commit Graph

51 Commits

Author SHA1 Message Date
Ken a21329bb04 ci: simplify deploy workflow - frontend now builds in Docker
Deploy Research Workbench / deploy (push) Failing after 14m27s
Removed npm ci/build step from workflow since the Dockerfile now
handles the full frontend build. Increased health check timeout to 180s.

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
2026-05-26 23:52:27 +00:00
Ken a84fd517a8 fix: remove duplicate amplifier-foundation dep from Dockerfile
Deploy Research Workbench / deploy (push) Failing after 10m24s
uv resolves conflicting URLs when amplifier-foundation is specified both
explicitly and as a transitive dep of amplifierd. Just install amplifierd
and let it resolve its own dependencies.

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
2026-05-26 23:51:31 +00:00
Ken c632a9d147 fix: Dockerfile — all build and runtime issues
Deploy Research Workbench / deploy (push) Failing after 12m28s
Sequential build failures fixed:
1. uv run playwright install chromium → playwright not in pyproject.toml/venv
   Fix: npm install -g @playwright/cli playwright && playwright install chromium
   Also installs @playwright/cli (the browser CLI used by research agents)

2. uv pip install amplifierd → package not on PyPI
   Fix: uv pip install --system from github.com/microsoft/amplifierd
   Also installs amplifier-foundation (also not on PyPI, git-only dep)
   Uses uv (not plain pip) to respect [tool.uv.sources] resolution

3. COPY frontend/dist/ → dist is gitignored, breaks fresh-clone builds
   Fix: build the frontend inside Docker using the installed Node.js
   (npm ci + npm run build); removes the pre-built dist assumption

Other fixes:
- Add git to apt-get (required for pip/uv git+https installs)
- Fix entrypoint.sh: amplifierd uses 'serve' subcommand and NAME=URI
  bundle format — was: amplifierd --port ... --bundle /path
  now: amplifierd serve --port ... --bundle name=/path --default-bundle name
- Add .dockerignore to exclude node_modules, .venv, dist, .git, etc.
  (keeps build context small and avoids stale artifacts in COPY steps)
2026-05-26 23:44:20 +00:00
Ken c6d8d4dfe6 fix: set UV_LINK_MODE=copy in Dockerfile for overlayfs compatibility
Deploy Research Workbench / deploy (push) Failing after 14m14s
uv's reflink-based file cloning fails with EAGAIN inside Docker's
overlayfs. Setting UV_LINK_MODE=copy forces regular file copies.

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
2026-05-26 23:07:40 +00:00
Ken d17b79ad95 ci: retrigger deploy (transient uv sync failure)
Deploy Research Workbench / deploy (push) Failing after 13m50s
🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
2026-05-26 22:53:04 +00:00
Ken a897d1cd00 fix: remove non-existent @anthropic-ai/playwright-cli from Dockerfile
Deploy Research Workbench / deploy (push) Failing after 13m37s
Package doesn't exist on npm. Playwright is already installed via
the Python backend deps (uv sync) and 'uv run playwright install chromium'.

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
2026-05-26 22:38:19 +00:00
Ken 7dd333b19d ci: add Gitea Actions deploy workflow
Deploy Research Workbench / deploy (push) Failing after 15m18s
Triggers on push to main. Builds frontend, stops old container,
builds and starts new Docker container, verifies the new UI is live.

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
2026-05-26 22:21:33 +00:00
Ken 389a8fb655 refactor: extract parseA2UIBlocks to lib/a2ui.ts; remove unused import re
- Extract parseA2UIBlocks() from A2UIRenderer.tsx into its own
  frontend/src/lib/a2ui.ts module to satisfy react-refresh/only-export-
  components ESLint rule (A2UIRenderer should only export React components)
- Update ChatPanel.tsx and test files to import from lib/a2ui
- Split ChatPanel.test.tsx mock: separate vi.mock for lib/a2ui
  (parseA2UIBlocks) and A2UIRenderer (component only)
- Remove unused 'import re' from tests/test_runtime_html.py (ruff F401)

All 216 frontend tests and 242 bash tests still pass. TypeScript and
Vite builds are clean. Remaining ESLint warnings (react-hooks/set-state-
in-effect in MCPAppRenderer and useSessions) are pre-existing patterns
not introduced by Phase 3.
2026-05-26 21:14:10 +00:00
Ken 2c3cfdbedc fix: resolve code review issues — schema mismatch, test fixes, pop-out render
- Fix a2ui-format.md schema to match renderer: rename 'options' → 'filters' in
  filters block, replace 'active: boolean' with 'value: string' in filter options,
  update form select options from string[] to {label, value}[] objects (Critical #1)
- Fix 3 failing tests in test_researcher_agent.sh to use @mention paths without .md
  extension (Important #2)
- Complete pop-out feature in VisualBlock.handlePopOut() by posting render message
  to popup window after 500ms initialization delay (Important #3)
- Update test_context_files.sh to match new a2ui-format.md schema (filters array
  key check, value field check)
2026-05-26 20:54:58 +00:00
Ken 92df88975c feat: docker-compose.yml for local development 2026-05-26 20:45:02 +00:00
Ken b895a1c94b feat: wire RightPanel with Browser + Artifacts, add A2UI rendering to chat
- RightPanel: replace placeholder content with BrowserPanel + ArtifactsPanel
  components, routing sessionId to whichever tab is active
- ChatPanel: import A2UIRenderer + parseA2UIBlocks; render A2UI blocks between
  markdown and tool-call cards in assistant messages; onAction sends
  '[action] {json}' back via onSend
- ChatPanel: add parseVisualBlocks() helper, VisualBlock wrapper component
  (loads runtime.html via MCPAppRenderer, view-source toggle, pop-out),
  rendered after A2UI blocks in assistant messages
- MCPAppRenderer: on ui/initialize route runtime='visual-artifact' data to a
  render dispatch instead of tool/input; add render forwarding case
- Fix pre-existing TS6133 unused-import errors in A2UIRenderer + BrowserPanel test
- All 216 tests pass; npm run build succeeds
2026-05-26 20:43:28 +00:00
Ken ab99259bcc feat: A2UI renderer for filters, tables, cards, forms 2026-05-26 20:29:42 +00:00
Ken a3635a9eb7 feat: artifacts panel with tabbed markdown rendering 2026-05-26 20:24:12 +00:00
Ken c1533fe25c feat: browser panel with noVNC iframe 2026-05-26 20:19:39 +00:00
Ken 74b2861db5 feat: complete bundle with visual artifact runtime and context 2026-05-26 20:16:02 +00:00
Ken 6538d0aa25 feat: visual artifacts context file with 5 example patterns for AI-generated visuals 2026-05-26 20:13:31 +00:00
Ken 0751fbfa0a feat: visual artifact runtime for AI-generated inline visualizations
- Add bundle/apps/runtime.html: universal runtime that executes
  AI-generated visualization code in a sandboxed context
- Pre-loads CDN libraries: Tabler CSS, Leaflet CSS+JS, Chart.js v4,
  React 19 UMD, ReactDOM 19 UMD, Babel standalone 7
- Implements mcpBridge with JSON-RPC 2.0 protocol:
  sendToHost, callTool (with UUID ids + Promise), sendMessage, resize
- executeVisual detects JSX/HTML/plain-JS paths via regex
- Auto-resize via requestAnimationFrame + scrollHeight + 32, capped at 800
- Initial ui/initialize handshake with runtime='visual-artifact' v1.0.0
- Listens for 'render' and legacy 'tool/input' methods
- Add tests/test_runtime_html.py: 61 tests covering all spec requirements
2026-05-26 20:08:22 +00:00
Ken 9367d2b957 feat: context files for A2UI format, artifact conventions, researcher instructions 2026-05-26 20:03:53 +00:00
Ken 9f5a407773 feat: researcher agent with playwright-cli, A2UI, inline visuals, artifact conventions
- Add bundle/agents/researcher.md with full YAML frontmatter:
  - meta.name: researcher
  - meta.description with WHY/WHEN/WHAT/HOW pattern and 4 delegation examples
    (hybrid cars near Woodinville, project management tools, Seattle-Tokyo flights,
    mechanical keyboards for programming)
  - model_role: [research, general]
- Body sections: Browser Control with 11-command playwright-cli table, Snapshot
  Refs subsection, Best Practices, A2UI @mention, Artifacts @mention, Inline Visuals
  @mention to visual-artifacts.md with proactive visual generation guidance, and
  6-step Research Workflow (Understand → Plan → Browse/Extract → Present →
  Generate Artifacts → Iterate)
- Add tests/test_researcher_agent.sh with 53 checks covering all spec requirements

Co-authored-by: Amplifier <amplifier@microsoft.com>
2026-05-26 20:00:03 +00:00
Ken 922e28a196 feat: research-workbench behavior wiring researcher agent 2026-05-26 19:55:15 +00:00
Ken 3a76e52a5d feat: thin root bundle including foundation 2026-05-26 19:54:18 +00:00
Ken b2a278762b fix: remove unused refresh destructure from App.tsx after review fix
The prior review fix (#4) removed the redundant `await refresh()` call from
the onCreate handler, but left `refresh` in the useSessions() destructure.
TypeScript (noUnusedLocals) flagged it as an error, breaking the build.

Remove the unused binding to restore a clean build.
2026-05-26 19:48:40 +00:00
Ken 8e69ac185e fix: address code review findings from Phase 2 final review
- ChatPanel: add 'chat-message ${role}' CSS classes to message wrappers
  so .chat-message.user and .chat-message.assistant rules apply correctly
- LoginPage: rename className 'login-error' -> 'error' to match the
  .login-card .error selector in globals.css
- MCPAppRenderer: verify event.source matches iframe contentWindow before
  processing postMessage to close cross-window injection vector
- App: remove redundant await refresh() after createNew() since
  createNew() already calls refresh() internally
- useArtifacts: wrap listArtifacts call in try/catch with console.error,
  matching the error-handling pattern already used in useSessions
2026-05-26 19:46:38 +00:00
Ken 9d118d60ce feat: wire MCPAppRenderer into ChatPanel for MCP App tool results 2026-05-26 19:39:34 +00:00
Ken 12d1df417f feat: MCPAppRenderer for inline MCP App iframes with JSON-RPC postMessage bridge 2026-05-26 19:36:28 +00:00
Ken 3723c5bf93 feat: App shell with login, session sidebar, chat panel, right panel
- Create RightPanel component with browser/artifacts tab switching
- Replace App.tsx with 3-column layout (auth loading/login/app states)
- Replace main.tsx with globals.css import (remove index.css)
- Remove Vite template files (App.css, index.css, assets/react.svg)
- Fix LoginPage.tsx FormEvent type-only import for verbatimModuleSyntax
- Fix vite.config.ts to use vitest/config for proper test property typing
- Add tests: RightPanel (10 tests), App rendering states (7 tests)
2026-05-26 19:34:07 +00:00
Ken 3b01753336 feat: chat panel with SSE streaming and tool call cards 2026-05-26 19:28:12 +00:00
Ken c24fd11f03 feat: session sidebar component with create, select, logout 2026-05-26 19:20:37 +00:00
Ken 77fe2bafd4 feat: login page component 2026-05-26 19:17:16 +00:00
Ken c24fd035eb feat: API client and hooks for auth, sessions, chat SSE, artifacts 2026-05-26 19:13:46 +00:00
Ken 5069676914 feat: global styles with Tabler dark theme, 3-column layout 2026-05-26 19:08:49 +00:00
Ken e1e001c7e0 feat: TypeScript types for sessions, artifacts, A2UI, tool calls, auth 2026-05-26 19:06:01 +00:00
Ken 64b18613e1 feat: scaffold Vite + React + TypeScript frontend 2026-05-26 19:03:56 +00:00
Ken 5ba367af2f fix: code review fixes — auth gap, path traversal, dead code, health-check timeout
- backend/app.py: add Depends(_require_auth) to /api/copilotkit endpoint (critical
  security fix — endpoint was fully unprotected; now requires valid session cookie)
- backend/app.py: move 'from ag_ui.core import RunStartedEvent' from inline function
  body to top-level imports (style consistency)
- backend/auth.py: remove dead AUTH_PASS_HASH module-level constant (verify_password
  already reads from os.environ at call time; the cached binding was unused dead code)
- backend/artifacts.py: add path traversal guards to list_artifacts, get_artifact,
  and save_artifact — resolve paths and verify they stay within ARTIFACTS_DIR
- entrypoint.sh: health-check loop now sets READY flag and exits 1 if amplifierd
  fails to start within 30s (previously fell through silently, causing 502s)
- tests/test_app.py: add TestCopilotKitAuth — verifies unauthenticated requests to
  /api/copilotkit return 401; includes note explaining why streaming is not tested here
- tests/test_structure.sh: update to reflect that Dockerfile and entrypoint.sh now
  exist (created in Tasks 7+8); convert absent-checks to presence-checks

Co-authored-by: Amplifier <amplifier@anthropic.com>
2026-05-26 18:52:12 +00:00
Ken 6be77d1a56 feat: entrypoint.sh starting all services 2026-05-26 18:43:40 +00:00
Ken 2838cff67c feat: Dockerfile with all-in-one container 2026-05-26 18:41:33 +00:00
Ken 9103b3ecf5 feat: FastAPI app with auth, AG-UI endpoint, session proxy, artifact API 2026-05-26 18:38:20 +00:00
Ken 026825ce02 feat: AG-UI adapter translating amplifierd SSE events to AG-UI protocol (with MCP App metadata passthrough) 2026-05-26 18:29:26 +00:00
Ken 8e065266ea feat: artifact storage module with per-session CRUD 2026-05-26 18:23:44 +00:00
Ken 7acad01047 feat: auth module with bcrypt password verification and session tokens 2026-05-26 18:21:18 +00:00
Ken 9b941d173d feat: add backend pyproject.toml with dependencies 2026-05-26 18:18:38 +00:00
Ken 04ae443207 chore: remove old car-help files, prepare new structure 2026-05-26 18:16:07 +00:00
Ken 4656af010e docs: implementation plans for research workbench (3 phases, 30 tasks)
Phase 1: Infrastructure (8 tasks) - Dockerfile, amplifierd, FastAPI, auth, AG-UI adapter
Phase 2: Frontend (10 tasks) - React/TS/Vite, Tabler, CopilotKit headless, SSE streaming
Phase 3: Bundle + Browser + Artifacts (12 tasks) - Amplifier bundle, researcher agent,
  AI-generated visual artifacts (Claude builds visuals style), noVNC browser panel
2026-05-26 18:01:47 +00:00
Ken dc1a3aee8b refactor: rename to research-workbench, update cloudflared to research.ampbox.io
- Renamed repo from car-help to research-workbench
- Remote now points to git.ampbox.io/ken/research-workbench
- cloudflared: research.ampbox.io (app) + vnc.ampbox.io (browser)
- Updated all references from browser.ampbox.io to research.ampbox.io
2026-05-26 16:11:46 +00:00
Ken 2bbf2c840f docs: research workbench design - generalized chat + browser + artifacts tool
Captures the architecture for generalizing car-help into a universal
research workbench powered by amplifierd + playwright-cli + noVNC.
2026-05-26 15:40:05 +00:00
Ken 7e19b740cb feat: LLM-powered search with free-text query, filter toggles, and auto-generated guide
- Search box: type anything, toggle filter pills (hybrid, price range, distance, etc.)
- Backend calls Anthropic to parse query into search params
- Playwright crawls Craigslist, CarGurus, AutoTempest with dynamic URLs
- Results scored/ranked with car-specific scoring engine
- Second Anthropic call generates a custom buying guide from actual results
- Guide sections: top picks, checklist, mechanics, negotiation, budget
- All visible live in the browser panel via noVNC
2026-05-25 23:31:19 +00:00
Ken 7e8fa0024a fix: split noVNC to separate vnc.ampbox.io host for WebSocket support
- FastAPI httpx proxy can't handle WebSocket upgrades (status 101)
- noVNC iframe now points to vnc.ampbox.io (port 6080 via cloudflared)
- App UI stays at browser.ampbox.io (port 8080 via cloudflared)
- Auto-detects local vs ampbox.io for iframe src
2026-05-25 23:17:51 +00:00
Ken f30af4aefd fix: extract real titles from Craigslist listings, add image URLs
- Parse .cl-search-result inner text for title, price, location
- Fallback to URL slug extraction for missing titles
- Capture listing images for display in UI
- AutoTempest scraper also improved with better selectors
2026-05-25 22:57:14 +00:00
Ken 8dfafcc63d feat: car-help web UI with browser view, search API, and buying guide
- FastAPI backend on port 8080 with noVNC proxy for same-origin iframe
- Split-panel UI: live browser (55%) + search/guide/saved tabs (45%)
- Car buying guide: target models, pre-purchase checklist, mechanics nearby,
  negotiation tips, budget breakdown
- Scoring/ranking engine for listings (Toyota Prius = highest)
- Docker container runs Xvfb + x11vnc + noVNC + FastAPI together
- Accessible at browser.ampbox.io via cloudflared tunnel
2026-05-25 20:34:16 +00:00
Ken f09317f95b feat: add noVNC headed mode for interactive browser sessions
- Dockerfile with Xvfb + x11vnc + noVNC for browser-in-a-URL
- search.py auto-detects DISPLAY env to run headed vs headless
- pause_for_human() function for CAPTCHA/login handoff
- Facebook Marketplace search (headed mode only, needs login)
- Updated README with both modes
2026-05-25 06:56:21 +00:00