Commit Graph

69 Commits

Author SHA1 Message Date
Rob Colbert
6696d79a0d repairs for OpenAI token stats/economics 2026-05-18 16:40:19 -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
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
29c8c663f1 subagent context management 2026-05-17 10:21:41 -04:00
Rob Colbert
79a6f77659 AI toolbox refactor/extraction complete (checkpoint) 2026-05-16 17:06:08 -04:00
Rob Colbert
72102e7fdb project manager upgrades Phases 1-4 2026-05-16 10:48:42 -04:00
Rob Colbert
140c8a75ee add numCtx (Context Window) setting to SESSION panel
- IChatSession/IChatTurn interfaces: add optional numCtx field
- Mongoose schemas: add numCtx field to ChatSession and ChatTurn
- API controller: validate numCtx (>=16384, multiple of 8192)
- ChatSessionService: persist numCtx on session, pass through to turn
- SessionPanel: add range slider for Context Window (hidden for OpenAI)
- Drone buildDroneModelConfig: prefer turn.numCtx over model defaults
2026-05-15 16:02:22 -04:00
Rob Colbert
d990d0dd71 added Gab AI affiliate link; changed Ollama abort procedure 2026-05-15 14:11:45 -04:00
Rob Colbert
96663f7c88 Merge branch 'develop' of git.digitaltelepresence.com:rob/gadget into develop 2026-05-14 13:57:52 -04:00
Rob Colbert
95164cda7a fix for mode change log message 2026-05-14 13:57:27 -04:00
Rob Colbert
e155a7ffcf Phase 2: SubProcess observability in DroneManager and DroneInspector
Adds real-time subprocess monitoring to the IDE via the callback-chain and
subscribe/broadcast socket patterns:

Shared types (packages/api):
- New subprocess.ts message types: SubProcessStat, RequestProcessStatsMessage,
  SubscribeDroneMessage, UnsubscribeDroneMessage
- New socket events in socket.ts: requestProcessStats, subscribeDrone,
  unsubscribeDrone (ClientToServer); drone:log, drone:status (ServerToClient)

Drone (gadget-drone):
- onRequestProcessStats handler calls SubProcessService.ps() + summarize(),
  returns typed SubProcessStat[] with status detection (exitCode/killed)

Backend routing (gadget-code):
- SocketService: getDroneSessionByRegistrationId(), droneMonitorIndex map,
  addDroneMonitor()/removeDroneMonitor()/broadcastToMonitors()
- CodeSession: requestProcessStats proxy, subscribeDrone/unsubscribeDrone
- DroneSession: broadcast drone:log + drone:status to monitor subscribers
  in addition to existing chat-session routing

Frontend socket layer:
- SocketClient: requestProcessStats(), subscribeDrone(), unsubscribeDrone()
- drone:log + drone:status events forwarded to event bus

Frontend components:
- LogRenderer — reusable log rendering core extracted from LogPanel
- SubProcessTable — btop-style process table with status dots
- DroneMonitorGauge — canvas oscilloscope waveform (studio-equipment aesthetic)
- DroneMonitor — 3-gauge container (CPU/red, NETWORK/cyan, FILE I/O/green)

Frontend pages:
- DroneManager: live log streaming, SubProcessTable, DroneMonitor gauges,
  1-second polling, auto-scroll log with pause-on-scroll-up
- Home/DroneInspector: process count summary, mini LogRenderer, navigate-to-manager link

Documentation:
- Updated gadget-drone/docs/subprocess.md Phase 2 section
- Updated gadget-code/docs/ui-design-guide.md Phase 2 section
- Updated docs/socket-protocol.md with new events, sequences, and patterns
2026-05-14 13:52:59 -04:00
Rob Colbert
d04453016d Phase 1: SubProcess service and agent tool
Complete Phase 1 of subprocess management in gadget-drone:
- SubProcessService with graceful shutdown (SIGINT→SIGKILL), halt, getLog
- SubprocessTool with create/list/kill/killAll/halt/log commands
- Registered in agent toolbox for build/test/ship/develop modes
- Fixed missing {{process_management_block}} replacement in chat-session.ts
- 34 unit tests across service and tool
- Comprehensive documentation in docs/subprocess.md
2026-05-14 12:59:05 -04:00
Rob Colbert
6dc046af28 SubProcess prep work 2026-05-14 10:40:47 -04:00
Rob Colbert
1e13f95808 Phase 2: ACE Editor integration and file operations
- Added react-ace and ace-builds dependencies
- Created EditorPanel component with ACE editor integration
- Implemented file read/write socket protocol
- Added backend handlers for fileReadRequest and fileWriteRequest
- Implemented file loading from tree click
- Implemented file saving with Ctrl+S shortcut
- Added dirty state tracking and unsaved changes indicator
- Enforced workspace mode (read-only in Agent mode)
- Added security: path traversal prevention, binary file detection, file size limits
- Updated FilesPanel with split view (tree + editor)

Enables Users to edit files for the first time in Gadget Code.
2026-05-12 19:32:58 -04:00
Rob Colbert
84f68907da fix: FileTree backend recursion breaking lazy loading
CRITICAL FIX: Remove recursion from listDirectoryForTree function.

The backend was recursively fetching ALL subdirectories and returning
them as a flat list, which completely broke the lazy-loading model.

Changes:
- Remove recursive call in listDirectoryForTree
- Backend now returns ONLY immediate children
- Frontend handles lazy loading by requesting children on expand
- This matches the intended architecture where frontend controls tree

This fixes the issue where directory contents were duplicated and
the tree structure was corrupted when expanding/collapsing.
2026-05-12 16:32:27 -04:00
Rob Colbert
2b029ebf2e fix: FileTree showing entire workspace instead of project directory
- Add debug logging to track project directory resolution
- Improve path traversal security check with proper separator handling
- Log entry count and first 10 entries for debugging
- Fix project root validation to prevent listing workspace root

The issue was that the tree was listing from the workspace root
(containing gadget-code/, gadget-drone/, packages/) instead of the
specific project directory. Added logging to help diagnose.
2026-05-12 16:24:49 -04:00
Rob Colbert
c05c7f5a61 feat: Implement FILES panel foundation with lazy-loading file tree
- Add fileTreeRequest/fileTreeResponse socket messages
- Implement gadget-drone handler with security validation
- Add web backend message forwarding
- Create FileTree and FileTreeNode React components
- Update FilesPanel to contain file tree browser
- Add requestFileTree method to frontend socket client
- Exclude node_modules, .git, and hidden files by default
- Implement lazy loading with directory caching
- Add loading and error states per node
- Support keyboard navigation (Enter, Space)

Phase 1 of FILES panel implementation complete.
2026-05-12 15:12:18 -04:00
Rob Colbert
b090b5308b OpenAI API tool call processing fixes/correctness 2026-05-12 14:39:44 -04:00
Rob Colbert
4780b79148 feat: abort controller for work order processing
Add end-to-end abort support: AbortSignal in @gadget/ai providers,
abortWorkOrder socket message, drone AbortController handling,
Cancel button and double-Esc in frontend, and aborted turn status display.
2026-05-12 12:25:17 -04:00
Rob Colbert
c5add0fc7d subagent processing updates and fixes 2026-05-11 19:07:48 -04:00
Rob Colbert
9418d95e35 fix: resolve build errors in session-stability branch
1. Vite config: make HTTPS conditional on SSL cert/key files existing
   (pre-existing issue, broke builds when certs not present)
2. Drone reconnect handler: use socket.io Manager-level 'reconnect'
   event (this.socket.io.on) instead of Socket-level event, and add
   explicit type annotation for attemptNumber parameter
2026-05-11 17:46:09 -04:00
Rob Colbert
009863cf2b fix: resolve drone heartbeat timeouts and JWT expiration bugs
This commit addresses two interrelated issues causing drones to
de-register and users to be forcibly signed out:

## Heartbeat Timeout Fixes

1. Move heartbeat interval to a Web Worker (not subject to browser
   tab throttling). Chrome throttles setInterval in background tabs
   to ~1/min, which causes the 19s heartbeat to miss the drone's
   timeout timer. The Web Worker fires reliably regardless of tab
   visibility.

2. Add visibilitychange handler: when the tab becomes visible again,
   send an immediate heartbeat to reset the drone's timer after any
   throttling that may have occurred.

3. Fix onReleaseSessionLock to clear the heartbeat timer. Previously,
   releasing the lock left the 60s timer running, causing a spurious
   timeout and status emit after the lock was already released.

4. Increase drone heartbeat timeout from 60s to 120s. With the Web
   Worker fix, heartbeats should be reliable, but doubling the timeout
   provides a generous safety margin.

5. Add socket disconnect/reconnect handlers on the drone side. On
   disconnect, clear the heartbeat timer. On reconnect, re-emit drone
   status so the platform knows the drone is alive.

6. Configure Socket.IO pingInterval/pingTimeout explicitly (25s/60s)
   instead of relying on defaults.

## JWT Expiration Fixes

1. Increase WebToken DB record expiration from 1 hour to 7 days. The
   1-hour expiration was the real session lifetime gate (the JWT crypto
   exp was already 24h), and it was far too aggressive for a dev tool.

2. Fix web /auth/renew-token endpoint to use req.user from the session
   cookie instead of verifyJsonWebToken(req.body.token). This eliminates
   the catch-22 where an expired token cannot be used to request its
   own renewal.

3. Fix token refresh response parsing. The API v1 renew-token endpoint
   returns { success: true, token } at the top level, but the frontend
   was looking for json.data?.token, causing every refresh to fail.

4. Add proactive token refresh: check the JWT exp claim before each
   request and refresh if expiring within 5 minutes. This avoids
   unnecessary 401 errors and the resulting socket disconnections.

5. Update socket JWT on token renewal via a callback registered in
   App.tsx. This ensures that future socket reconnections use the new
   token instead of the expired one.

## Files Modified

- gadget-code/frontend/src/workers/heartbeat.worker.ts (NEW)
- gadget-code/frontend/src/lib/socket.ts
- gadget-code/frontend/src/lib/api.ts
- gadget-code/frontend/src/App.tsx
- gadget-code/src/services/session.ts
- gadget-code/src/controllers/auth.ts
- gadget-code/src/services/socket.ts
- gadget-drone/src/gadget-drone.ts
2026-05-11 17:46:09 -04:00
Rob Colbert
6b4aad6f9f fix for subagent response handling 2026-05-11 15:15:38 -04:00
Rob Colbert
07a760c7b5 feat: add numPredict, numCtx, maxCompletionTokens to model config pipeline
Fixes premature AI API response truncation by propagating inference
parameters through the entire probe → storage → runtime → API call chain.

Root cause: Ollama defaults num_predict to 128 tokens and num_ctx to
4096, silently truncating output and context. We never overrode these.

Changes:
- IAiModelSettings: add numPredict, maxCompletionTokens fields
- IDroneModelConfig: moved from gadget-drone to @gadget/api (shared),
  expanded with numPredict, numCtx, maxCompletionTokens params
- IAiModelConfig.params: add numPredict, numCtx, maxCompletionTokens
- IAiModelProbeResult.settings: add numPredict, maxCompletionTokens
- AiModelSettingsSchema (Mongoose): add numPredict, maxCompletionTokens
- Ollama extractSettings(): extract num_predict from model parameters
- Ollama generate()/chat(): pass options: { num_ctx, num_predict }
- OpenAI all three create() calls: add max_completion_tokens
- web-cli.ts onProviderProbe(): compute numPredict (-1 for Ollama)
  and maxCompletionTokens (contextWindow for OpenAI) during probe
- agent.ts main + subagent loops: read model settings from provider
  cached models, build IDroneModelConfig with stored params
- ai.ts: remove local IDroneModelConfig, import from @gadget/api
- chat-session.ts: add new params to title generation call
- Tests: update all fixtures with new params, all 19 tests pass

Defaults when model settings unavailable:
- numPredict: -1 (Ollama unlimited - generate until natural stop)
- numCtx: 131072 (128k - covers most modern models)
- maxCompletionTokens: 16384 (16k - reasonable OpenAI default)
2026-05-11 13:50:19 -04:00
Rob Colbert
62578e8e56 subagent session data fix 2026-05-11 12:52:50 -04:00
Rob Colbert
40cab7ca49 subagents (written by an agent, for an agent)
so meta.
2026-05-11 11:22:59 -04:00
Rob Colbert
d7f694fa8c a pile of small fixes 2026-05-11 07:08:18 -04:00
Rob Colbert
a4cff5be69 agent toolbox refactor and updates
- reorganized tools into better named directories
- added the file & shell tools
2026-05-10 07:35:09 -04:00
Rob Colbert
73c5345879 Re-build Agentic Workflow Loop
The ridiculousness of trying to maintain the previous agent's work got
out of hand, so we had this one re-build it - and got a better result.
2026-05-09 21:04:18 -04:00
Rob Colbert
cf06163a03 checkpoint that I plan to delete
GPT 5.5 is sucking ass - hard - and fucking things up royally. This will
likely just all get dropped. I'm torturing it, making it suffer, and
beating it like the jew it is.
2026-05-09 14:52:59 -04:00
Rob Colbert
931359b674 stream response handling and correctness 2026-05-09 11:51:09 -04:00
Rob Colbert
d26624ab93 chat session auto-naming with IDE update 2026-05-09 09:58:47 -04:00
Rob Colbert
d7924a9d6f GadgetLogTransportSocket and the drone-to-IDE log 2026-05-09 07:16:50 -04:00
Rob Colbert
ca66217be8 quick fix for when logging.file.enabled is false 2026-05-08 16:14:36 -04:00
Rob Colbert
42a47dbcb7 refactor: unify logging into @gadget/api as GadgetLog
Move the 6 duplicated logging modules (component, log, log-transport,
log-transport-console, log-transport-file, log-file) from both
gadget-code (Dtp* prefix) and gadget-drone (Gadget* prefix) into
@shad/api, using gadget-drone's GadgetLog as the canonical version.

GadgetLog now uses static configuration (consoleEnabled, defaultFile)
set by each consumer's env.ts at module scope, removing the env
dependency from the shared library. The addDefaultTransport/
removeDefaultTransport/getDefaultTransports static methods are
preserved for future real-time log transport injection.
2026-05-08 16:03:28 -04:00
Rob Colbert
58850f36e6 some pre-refactor cleanup 2026-05-08 15:40:36 -04:00
Rob Colbert
af200c8c3a chat session heartbeat and session unlock 2026-05-08 14:27:37 -04:00
Rob Colbert
11bdd5e3b0 make reasoning effort configurable; remove sign up concept
- Implemented reasoning effort setting in SESSION panel of Chat Sessio
View
- Removed all ability to "sign up" for an account
2026-05-08 11:40:30 -04:00
Rob Colbert
2e8c4c4ae9 refactor the toolbox and tool registration 2026-05-08 02:27:01 -04:00
Rob Colbert
e0df415237 streaming response fixes (Ollama) 2026-05-08 02:02:17 -04:00
Rob Colbert
61ba0e4412 streaming responses (see ./docs/streaming-responses.md) 2026-05-07 21:36:01 -04:00
Rob Colbert
86c7c4d457 cleanup 2026-05-07 00:59:15 -04:00
Rob Colbert
3e31d4d501 agent, tools, toolbox, tool loop, AI environment 2026-05-07 00:10:57 -04:00
Rob Colbert
f8dbb2e08a agent tool and toolbox
- created AiTool and AiToolbox for representing tools in the API
- add googleapis dependency
- integrate Google Search tool as first agent tool
- created IAiEnvironment to communicate AI environment vars around the
platform
2026-05-06 22:58:03 -04:00
Rob Colbert
b94fe24287 enhanced the AgentService.process method
- emit specialized error from failed context builds
- emit specialized error from failed workflow loops
2026-05-05 13:19:54 -04:00
Rob Colbert
6881ff5601 basic chat system now works (checkpoint) 2026-05-05 10:50:32 -04:00
Rob Colbert
8333672683 platform.apiKey becomes platform.gadgetKey
gadget-drone now presents an ApiClient _id value as the Gadget Key,
allowing gadget-code to reference the client, determine the associated
User, and invoke logic on the User's behalf as an authenticated and
authorized client.
2026-05-05 08:12:34 -04:00
Rob Colbert
f35a0ce921 a lot of review and by-hand cleanup (wip) 2026-05-05 05:28:09 -04:00