Commit Graph

229 Commits

Author SHA1 Message Date
Rob Colbert
e0fd6ece54 fix: remove syncIndexes from models, mock DB in drone-session tests
- Removed auto-invoked syncIndexes() blocks from all 11 model files
  (api-client, api-client-log, csrf-token, drone-monitor,
  drone-registration, email-log, email-verification, ide-session,
  user, web-token, web-visit) — no longer needed
- Fixed drone-session.test.ts by mocking ChatSession.updateOne(),
  VectorStoreService.ingestTurn(), and MessageQueue to prevent
  real DB connections during tests
- Removed unused mongoose Types import from drone-session test
- All 129 tests now pass across all packages
2026-05-19 16:32:58 -04:00
Rob Colbert
a7a6a91a13 fix: pass requested vector dimension to embedding API (Ollama + OpenAI)
The qwen3-embedding:4b model defaults to 2560-d vectors. Both
Ollama (client.embed()) and OpenAI support a dimensions parameter
to request a specific output size. This change threads the configured
qdrant.vectorSize through the AI provider layer so the model returns
vectors matching the Qdrant collection dimensions.

- AiApi.embeddings() now accepts optional dimensions parameter
- Ollama provider: switched from client.embeddings() to client.embed()
- OpenAI provider: passes dimensions to embeddings.create()
- VectorStoreService.getEmbedding() passes env.qdrant.vectorSize
- Added unit tests for dimension mismatch detection, collection
  creation, and search guards
2026-05-19 16:21:04 -04:00
Rob Colbert
3c076fc01a Merge branch 'develop' of git.digitaltelepresence.com:rob/gadget into develop 2026-05-19 15:46:16 -04:00
Rob Colbert
66774d94f9 search input and backend error fixes 2026-05-19 15:43:24 -04:00
Rob Colbert
00e2fdfa4f a little logging and formatting cleanup 2026-05-19 15:42:48 -04:00
Rob Colbert
70ad578425 Merge branch 'develop' of git.digitaltelepresence.com:rob/gadget into develop 2026-05-19 14:30:04 -04:00
Rob Colbert
9aaacead42 quick auto-scroll fix 2026-05-19 14:29:58 -04:00
Rob Colbert
56f35a2fdf feat: Qdrant semantic search over chat history
Adds vector-based semantic search across all chat sessions using Qdrant.
When a ChatTurn finishes, its content is chunked, embedded, and upserted
to a Qdrant collection. A search API and UI components enable searching
at user, project, and session scope.

Phase 1 — Configuration & Dependencies
- Add port/apiKey to GadgetCodeConfig.qdrant type
- Uncomment and update qdrant section in YAML config example
- Add qdrant config passthrough in env.ts
- Add @qdrant/js-client-rest dependency

Phase 2 — AI Embedding API (@gadget/ai)
- Add IAiEmbeddingResponse interface and abstract embeddings() to AiApi
- Implement embeddings() in OllamaAiApi (client.embeddings)
- Implement embeddings() in OpenAiApi (client.embeddings.create)
- Export IAiEmbeddingResponse from package index

Phase 3 — Backend Vector Store Service
- Create VectorStoreService (ingestTurn, search, removeTurnPoints)
- Hook fire-and-forget ingest after turn.save() in drone-session
- Register VectorStoreService in service startup/shutdown

Phase 4 — Backend Search API
- Create POST /api/v1/search controller with userId enforcement
- Batch-hydrate results from MongoDB (user, project, session, turn)
- Register search route in v1 API router

Phase 5 — Frontend Search Components
- SearchInput: debounced input with lucide-react icons
- ChatSearchResults: modal with score badges, metadata, loading states
- DroneSelectionModal: drone picker for sessions without a drone
- Add searchApi and ISearchResult to API client
- Add search to Home (global), ProjectManager (project), ChatSessionView (session)
- Add id=turn-{turnId} to ChatTurn for scroll targeting
- Scroll-to-turn from search result selection and router state
- Show DroneSelectionModal when no drone available
- Add Select Drone button in ChatSessionView sidebar
2026-05-19 14:28:30 -04:00
Rob Colbert
d47ef96916 remove empty content continue; prettier then reformatted many things 2026-05-19 11:48:56 -04:00
Rob Colbert
1758bb2db7 add @langchain/textsplitters for text vector processing 2026-05-19 11:08:56 -04:00
Rob Colbert
aeaefc53dd cleanup 2026-05-19 09:54:36 -04:00
Rob Colbert
faf815d66d added Qdrant embedding model config 2026-05-19 09:34:35 -04:00
Rob Colbert
e2cefc2617 added qdrant config 2026-05-19 03:53:21 -04:00
Rob Colbert
f539f91018 Merge branch 'develop' of git.digitaltelepresence.com:rob/gadget into develop 2026-05-19 02:22:49 -04:00
Rob Colbert
cf31aff8db added a clean script 2026-05-19 02:22:39 -04:00
Rob Colbert
6696d79a0d repairs for OpenAI token stats/economics 2026-05-18 16:40:19 -04:00
Rob Colbert
ef43fa2a00 yet another attempt from yet another agent on trying to just capture some simple stats 2026-05-18 16:08:12 -04:00
Rob Colbert
241f3b5b69 feat(ai): add raw API response logging at OpenAI client call sites
- Log the SDK response object immediately after client.chat.completions.create()
  in both generate() and readStreamingChatCompletion()
- These debug-level logs capture the response at the call site before any
  iteration or processing
- All downstream info-level logs continue to dump raw chunk/response objects
2026-05-18 15:45:27 -04:00
Rob Colbert
73b0b3149d fix(ai): log raw OpenAI API response objects, not cooked usage
- Add rawUsage field to OpenAiChatIterationResult to carry the
  original OpenAI SDK usage object through the call chain
- All downstream chat() logs now dump rawUsage via
  JSON.parse(JSON.stringify()) instead of our cooked
  { promptTokens, completionTokens }
- This exposes completion_tokens_details.reasoning_tokens and
  any other fields OpenAI returns that we weren't capturing
2026-05-18 15:29:59 -04:00
Rob Colbert
51b3013659 feat(ai): add DtpLog logging of all OpenAI API responses
- Fix broken chunkCount reference in generate() usage chunk log
- Add generate() complete log with usage, response/thinking lengths
- Add readStreamingChatCompletion() usage chunk log (full chunk dump)
- Add readStreamingChatCompletion() iteration complete log
- Add readNonStreamingChatCompletion() full response dump
- Add chat() streaming iteration usage log
- Add chat() non-streaming fallback usage log
- Add chat() final response stats log

All logs use info level and 'OpenAI {method}: {event}' naming for
easy grep/filtering. Streaming chunks use JSON.parse(JSON.stringify())
to serialize the full OpenAI SDK response objects.
2026-05-18 15:20:53 -04:00
Rob Colbert
2483161663 context window fuel gauge auto update fix 2026-05-18 15:00:40 -04:00
Rob Colbert
00969cf9bc feat: token economics — real API token extraction, stats propagation, and context window fuel gauge
Phase 1: OpenAI API Token Extraction
- Add stream_options: { include_usage: true } to all streaming API calls
- Capture chunk.usage from final streaming chunks and response.usage from non-streaming
- Extend OpenAiChatIterationResult with optional usage field
- Update buildStats() to accept and return real token counts from usage data
- Wire iteration.usage through chat() to both buildStats() call sites

Phase 2: Agent Loop Stats Propagation
- Rename inputTokens/outputTokens to masterInputTokens/masterOutputTokens, add masterThinkingTokens
- Accumulate response.stats.tokenCounts after each master AI call
- Delete all Math.ceil(length/4) crude approximations (master and subagent loops)
- Track startTime/durationMs and emit IWorkOrderCompleteStats with workOrderComplete
- Subagent loop uses response.stats?.tokenCounts instead of Math.ceil

Phase 3: Database Model Changes
- Add contextWindowUsage field to IChatSession, ChatSessionSchema, and frontend ChatSession
- Initialize contextWindowUsage: 0 on session creation

Phase 4: Persist Stats on Turn Completion
- drone-session: accept IWorkOrderCompleteStats, persist turn stats, walk subagent records for aggregate
- drone-session: $inc session stats and contextWindowUsage, add formatDurationLabel() helper
- code-session: accept and forward stats, update in-memory session stats
- message-queue: Redis replay handles 4th stats arg
- Update WorkOrderCompleteMessage type in @gadget/api to accept stats parameter

Phase 5: UI — Context Window Fuel Gauge
- Add contextWindowUsage prop to SessionPanel
- Add fuel gauge bar with E→F labels, green/yellow/red zones, token count display
- Visible for ALL provider types (not gated by apiType)

Phase 6: Frontend Streaming State
- Add IWorkOrderCompleteStats interface to frontend api.ts
- handleWorkOrderComplete accepts stats, updates turn stats and session contextWindowUsage
- Pass contextWindowUsage prop to SessionPanel
2026-05-18 14:36:36 -04:00
Rob Colbert
9c1e65785d feat: add chat_export tool for session export (markdown/json)
New chat tool: chat_export

- Export current ChatSession and all finished ChatTurn records to disk
- Two formats: markdown (human-readable) and json (machine-readable)
- JSON exports always include a companion -readme.md with author credits,
  Gadget Code version/link, AI provider/model/parameters
- Output to .gadget/exports/ with sanitized session name + timestamp
- Security-first: excludes emails, API keys, baseUrls, system prompts,
  gitUrls, and other PII/infrastructure details from all exports
- Only finished/aborted/error turns included (processing excluded)
- Follows SubagentTool setter-injection pattern for session data
- Available in all chat session modes (plan/build/test/ship/dev)

Files:
- packages/ai-toolbox/src/chat/export.ts (NEW - 729 lines)
- packages/ai-toolbox/src/chat/index.ts (barrel update)
- gadget-drone/src/tools/index.ts (re-export update)
- gadget-drone/src/services/agent.ts (import, register, getExportData)
2026-05-18 11:44:53 -04:00
Rob Colbert
0437ca66d8 Merge branch 'develop' of git.digitaltelepresence.com:rob/gadget into develop 2026-05-18 09:11:16 -04:00
Rob Colbert
ca0cbf8e71 added lucide-react 2026-05-18 09:11:08 -04:00
Rob Colbert
802184a487 fix: home sidebar flex column layout with independent scrolling sections
- Convert sidebar <aside> to flex column container (flex flex-col overflow-hidden min-h-0)
- Remove sidebar-level scroll (overflow-y-auto → overflow-hidden)
- Add min-h-0 to parent flex containers in both layout paths for proper height containment
- Reorder sidebar sections: Clock → Projects → Drones → Recent Chats
- Add shrink-0 to Clock component to keep it at intrinsic content size
- Convert Projects, Drones, and Recent Chats sections to flex-1 min-h-0 flex-col with scrollable inner content
- Pin section headers with shrink-0; list content scrolls independently via overflow-y-auto
- Pin Recent Chats hint/footer with shrink-0 below its scrollable list
- No logic changes — purely CSS/flexbox layout correction
2026-05-18 09:04:25 -04:00
Rob Colbert
c2028f45c5 release: 1.0.1 2026-05-17 19:02:08 -04:00
Rob Colbert
12b69b9664 docs: add RELEASE.md for v1.0.1 Liberation 2026-05-17 19:00:22 -04:00
Rob Colbert
ff46c35d38 docs: update CHANGE.md and README.md for v1.0.1 release 2026-05-17 18:57:23 -04:00
Rob Colbert
7997b8a2a2 fix: update code-session tests to expect reality
- auto-generate name test: mock drone to accept work order so success callback runs
- session lock test: make async, mock TabLock, use vi.waitFor for async callback chain
2026-05-17 18:53:50 -04:00
Rob Colbert
3e1135ed2b feat: add hardened release script with error handling and pre-flight checks 2026-05-17 18:32:53 -04:00
Rob Colbert
a23224279e prompt draft save/restore in Chat Session view 2026-05-17 17:39:34 -04:00
Rob Colbert
e7857016e3 feat(workspace): intelligent startup - detect workspace by walking up directory hierarchy
- Add detectWorkspace() utility in packages/api/src/lib/workspace-detector.ts
  that walks up from process.cwd() looking for .gadget/workspace.json
- Update gadget-drone to detect workspace at startup, change to workspace
  directory, and restore original startup directory on shutdown
- Update gadget-tasks with same workspace detection pattern
- Both tools now fail fast if started outside a managed workspace
- Prevents creating invalid workspaces when started from subdirectories
2026-05-17 17:09:16 -04:00
Rob Colbert
c90e8ce0e8 plan tool updates
Plan tools extended to all modes; recent chat sessions added to
Authenticated Home view; drone locking and chat session startup factored
out of Project Manager into Chat Session view and made universal; update
for AGENTS.md.
2026-05-17 14:09:24 -04:00
Rob Colbert
ec774cfe99 docs(changelog): update for 2026-05-16 and 2026-05-17 2026-05-17 10:42:25 -04:00
Rob Colbert
29c8c663f1 subagent context management 2026-05-17 10:21:41 -04:00
Rob Colbert
4fa4f29f0b ex[amded prompt editor 2026-05-17 02:00:53 -04:00
Rob Colbert
4d8f403d78 docs: add gadget-tasks documentation, update README and agent-toolbox
- README.md: Added gadget-tasks and @gadget/ai-toolbox to projects table,
  added Scheduled Tasks architecture section with diagram, updated
  monorepo structure, added gadget-tasks to dev server instructions,
  added doc link

- docs/agent-toolbox.md: Updated to reflect @gadget/ai-toolbox extraction
  from @gadget/ai. Changed IAiEnvironment → GadgetToolboxEnvironment,
  AiTool → GadgetTool, updated import paths, config examples, and added
  Tool Categories section. Clarified gadget-tasks is NOT a consumer.

- docs/gadget-tasks.md: New documentation covering architecture, per-task
  execution flow, configuration, startup/shutdown sequences, concurrency,
  work order tracking, heartbeat, error recovery, and getting started.
2026-05-17 01:30:35 -04:00
Rob Colbert
f742a1d765 install/global link fixes and updates 2026-05-17 01:11:35 -04:00
Rob Colbert
b906cb2377 feat(gadget-tasks): course correction — headless IDE client architecture
Converts gadget-tasks from a duplicated codebase with direct MongoDB access
to a headless IDE client that uses gadget-code's REST API and Socket.IO
protocol to submit and process task prompts through the existing pipeline.

Deleted (no longer needed):
- gadget-tasks/src/models/ (5 Mongoose models — duplicated from gadget-code)
- gadget-tasks/data/prompts/ (11 prompt templates — duplicated from gadget-code)
- gadget-tasks/src/services/executor.ts (629-line AWL loop — duplicated from gadget-drone)
- gadget-tasks/src/services/ai.ts (direct AI API calls — drones do this now)
- gadget-tasks/src/services/workspace.ts (workspace management — drones do this now)

Added:
- gadget-tasks/src/services/platform.ts — REST API + Socket.IO headless IDE client
  with session lock, workspace mode, prompt submission, work order tracking

Rewritten:
- gadget-tasks/src/gadget-tasks.ts — new startup: user login → auth → drone
  selection → Socket.IO connect → schedule tasks (no MongoDB)
- gadget-tasks/src/services/scheduler.ts — delegates to PlatformService.executeTask()
- gadget-tasks/src/config/env.ts — platform.baseUrl config, no mongodb/google

gadget-code changes:
- Added PATCH /api/v1/projects/:projectId/tasks/:taskId/lastRun route
- Added ProjectService.updateTaskLastRun() for atomic task field update

Config changes:
- GadgetTasksConfig: replaced mongodb with platform.baseUrl, removed google.cse
- Dependencies: removed mongoose, @gadget/ai, @gadget/ai-toolbox, dayjs,
  simple-git, nanoid; added socket.io-client, @inquirer/prompts
2026-05-17 00:48:39 -04:00
Rob Colbert
79a6f77659 AI toolbox refactor/extraction complete (checkpoint) 2026-05-16 17:06:08 -04:00
Rob Colbert
5eab058304 Merge branch 'feature/pull-project' of git.digitaltelepresence.com:rob/gadget into feature/pull-project 2026-05-16 13:59:58 -04:00
Rob Colbert
b8321cbb00 type fix for references 2026-05-16 13:59:40 -04:00
Rob Colbert
79d494ec79 remove simplegit (wrong package) 2026-05-16 11:38:38 -04:00
Rob Colbert
5058489c2f Merge branch 'feature/pull-project' of git.digitaltelepresence.com:rob/gadget into feature/pull-project 2026-05-16 10:49:31 -04:00
Rob Colbert
72102e7fdb project manager upgrades Phases 1-4 2026-05-16 10:48:42 -04:00
Rob Colbert
4df5e6dec7 Merge branch 'feature/pull-project' of git.digitaltelepresence.com:rob/gadget into feature/pull-project 2026-05-15 19:38:36 -04:00
Rob Colbert
4fb8594987 typo fixes 2026-05-15 19:38:02 -04:00
Rob Colbert
cc7cdee60b Pull Project initial implementation 2026-05-15 19:34:08 -04:00
Rob Colbert
69f45867b2 tool call observability 2026-05-15 18:24:00 -04:00