mirror of
https://github.com/tiddly-gittly/TidGi-Desktop.git
synced 2026-03-19 05:11:48 -07:00
* Add wiki tiddler attachment support to agent chat Implements the ability to attach wiki tiddlers to agent chat messages. Updates the UI to allow selection of tiddlers from active wiki workspaces, fetches and renders tiddler content as plain text, and appends it to the user message sent to the AI. Includes e2e tests, updates to store actions, service interfaces, and prompt concatenation logic to support this feature. * fix: callback not useCallback cause autocomplete panel flash * Add wiki tiddler attachments to message bubbles Message bubbles now display attached wiki tiddlers as clickable chips, allowing users to navigate directly to the referenced tiddler in the appropriate workspace. Metadata handling and persistence for wiki tiddlers has been updated to include workspaceId, and tests have been added to verify the new UI behavior. The chat view also now closes the TiddlyWiki sidebar for better focus when navigating from a selection. * Support split view navigation for wiki tiddler attachments Adds isSplitView prop to ChatTabContent and related components to distinguish between split view and normal tab modes. Wiki tiddler attachment navigation now uses a different strategy in split view, opening tiddlers directly in the browser view. Updates types and tests to reflect the new behavior, and improves robustness of response handling in several places. * docs: move to .github/instructions/testing.instructions.md * test: view loading slow on mac * refactor(e2e): move wiki load steps to Background in talkWithAI.feature; remove all sidebar close delays and polling, only set state when TiddlyWiki is ready; clean up code and logs for sidebar auto-close in split view * docs: make test inst shorter * lint * refactor(view): slim ViewService, move menu to separate file, orchestrate view logic in WorkspaceViewService, update all callers, fix lint floating promise, all unit and e2e tests pass * fix: add data-testid to attachment listbox for E2E test - Add slotProps to MUI Autocomplete to ensure attachment-listbox is rendered with correct test-id - Fix E2E test timeout when waiting for attachment listbox element * lint * put 'Talk with AI' menu on top and attachment i18n Introduce a reusable createTalkWithAIMenuItems helper to build "Talk with AI" menu entries (default agent + other agents submenu) and integrate it into workspace menu generation. Add new i18n keys for Agent.Attachment and WikiEmbed across locales and update UI to use translation keys (remove hardcoded fallback strings). Improve chat input/attachment behavior: expose a test-id for the attachment listbox, use i18n for labels/placeholders, and tweak input component wiring. Fix Cucumber step handling by normalizing expected newline sequences and safely handling empty message content. Also adjust memo deps in SortableWorkspaceSelectorButton to include id. * feat: enhance AI interaction in workspace context menu with local trigger support * feat: add tool approval and timeout settings - Introduced ToolApprovalConfig and related types for managing tool execution approvals. - Implemented WebFetch and ZxScript tools for fetching web content and executing scripts, respectively. - Added token estimation utilities for context window management. - Enhanced ModelInfo interface with context window size and max output tokens. - Created API Retry Utility for handling transient failures with exponential backoff. - Updated AIAgent preferences section to include Tool Approval & Timeout Settings dialog. - Developed ToolApprovalSettingsDialog for configuring tool-specific approval rules and retry settings. - Modified vitest configuration to support aliasing for easier imports and stubbing. * Refactor agent instance tools and services for improved modularity and maintainability - Extracted type definitions and tool registry from defineTool.ts into separate files (defineToolTypes.ts, toolRegistry.ts) to reduce file size and enhance importability. - Implemented a retry mechanism in ExternalAPIService for stream creation to handle transient failures. - Updated ToolApprovalSettingsDialog to persist settings using localStorage instead of a preference service. - Created agentMessagePersistence.ts and agentRepository.ts to manage agent message and instance CRUD operations, reducing the size of AgentInstanceService. - Added a progress tracker document (AgentTODO.md) for the ongoing enhancement plan of the TidGi Agent. * feat: add AgentSwitcher component for agent definition switching - Implemented AgentSwitcher component with dropdown functionality for selecting agent definitions. - Integrated loading of agent definitions on dropdown open. - Added visual feedback for current selection and disabled state. feat: create ToolResultRenderer for generic tool result messages - Developed ToolResultRenderer to handle rendering of <functions_result> messages. - Included collapsible parameters and result display with error handling. - Added truncation for long results in collapsed view. test: add comprehensive tests for MessageRenderer components - Implemented tests for AskQuestionRenderer, ToolResultRenderer, ToolApprovalRenderer, and BaseMessageRenderer. - Ensured proper rendering and functionality for various message types and states. - Included pattern routing tests for MessageRenderer. feat: introduce TurnActionBar for action management in agent turns - Created TurnActionBar component for managing actions like rollback, retry, delete, and copy. - Integrated visual feedback for file changes and rollback status. - Added functionality for copying agent responses and full conversation to clipboard. feat: implement askQuestionPending for managing user responses - Developed infrastructure for handling pending ask-question requests. - Implemented promise-based blocking until user responds to agent questions. - Added timeout handling for ask-question requests. * feat: Implement background task management for agent instances - Added functionality to restore heartbeat timers and alarms for active agents upon service initialization. - Introduced methods to retrieve active background tasks and cancel them via the UI. - Enhanced alarm clock tool to persist alarm data in the database, ensuring alarms survive app restarts. - Updated agent instance schema to include scheduled alarm data. - Modified prompt concatenation logic to support context window size for message history. - Removed system prompt parameter from model parameters schema and related components. - Improved UI to display and manage background tasks, including heartbeat and alarm details. * feat: Implement Scheduled Tasks Management and Background Task Settings - Add feature for managing scheduled tasks for agents, including viewing, adding, and editing tasks. - Create tests for agent repository and background task settings APIs. - Introduce ScheduledTaskManager for unified scheduling of tasks with interval, at, and cron schedules. - Implement edit-agent-definition tool for modifying agent configurations, including heartbeat and prompt settings. - Ensure tasks persist across app restarts and respect active hours filtering. * Update wiki * fix(security): harden htmlToText against XSS via encoded tags - Use tolerant script/style regex that handles </script > with spaces - Stop decoding </> entities to prevent reintroducing HTML tags - Decode & last to avoid double-unescaping (&lt; < <) - Fixes all 4 CodeQL findings (bad filtering, incomplete sanitization, double escaping, incomplete multi-character sanitization) * fix: lint and format errors (eslint naming, dprint formatting, stub classes) * fix: exclude tidgi.config.json from template copy and fix log marker pattern - Skip tidgi.config.json when copying wiki template to prevent overriding workspace name - Change waitForLogMarker default pattern from 'wiki-' to '*' to match actual log filenames - Filter tidgi.config.json in e2e step too (fs.copy in wiki creation step) * perf(e2e): merge 5 scheduledTask scenarios into 2 to reduce app restarts * perf(e2e): merge crossWindowSync and streamingStatus scenarios to reduce CI time * ci: increase test timeout to 20min for larger e2e scenario count * perf(e2e): merge agent scenarios and enable parallel on CI - Merge agent.feature wiki-search + wiki-operation into one scenario - Merge agent.feature create-agent-from-newtab + create-agent-from-fallback into one - Enable cucumber parallel: 2 on CI (7GB RAM, dynamic ports for mock servers) - Total scenarios: 66 -> 61 * fix: cleanup MCP client processes when deleting or closing agent * ci: disable parallel (CPU contention), increase timeout to 30min for 61 scenarios * perf(e2e): merge 3 preference background-task scenarios into 1, increase timeout to 45min - Preference alarm/heartbeat CRUD merged into single scenario (saves 2 app restarts) - Total scenarios: 59 (was 66) - CI timeout 45min for the expanded e2e suite * fix: restructure e2e scenarios, fix subscription leak and debounce cleanup - Restructure agent/talkWithAI/streamingStatus feature files for reliability - Fix talkWithAI scenarios missing mock server startup and app launch - Remove duplicate subscription in handleSwitchAgent (useEffect already handles it) - Clean up debounced update functions when agent is deleted/closed - Use agentId:messageId key for debounced functions to enable per-agent cleanup * fix(e2e): remove :last-child selectors broken by TurnActionBar, fix tab/dialog selectors, increase CI timeout to 25min * fix: use const for non-reassigned variable (lint) * fix(e2e): fix close-all-tabs opacity issue, scheduledTask undefined steps, MUI multiline textarea targeting * fix(e2e): use tab-list-dropdown to close all tabs, fix selector for actual TabListDropdown component * fix(e2e): add timing waits for BrowserView repositioning and git log UI refresh * fix(e2e): make 'should not see' step wait for element to disappear instead of instant check * fix(e2e): increase executeInBrowserView default timeout from 500ms to 2000ms
15 KiB
15 KiB
Agent Enhancement — Session 2026-03-05/06
Current Plan (Source of Truth)
Goals
- Unified ScheduledTask system replacing fragmented heartbeat/alarm.
- Keep agent background scheduling useful but explicit to users.
- Prevent sub-agent scheduling side effects.
- Make scheduling observable and editable from UI.
- Keep tests strict: treat interruption/timeout as real failures and fix root causes.
Architecture Decisions
- Closing a chat tab does not stop the agent process; tab is a view, agent is runtime state.
- Sub-agents are
volatileand should not restore background scheduling after restart. - ScheduledTask is an independent DB entity (not embedded in AgentDefinition/AgentInstance) — enables unified UI, multiple concurrent tasks, and cross-agent queries (needed for Tab indicator).
- croner library for cron parsing — lightweight (10 KB), no extra deps, IANA timezone support.
- UI shows schedule signal where users actually operate tabs (header tab dropdown path).
- Timer lifecycle must not block process exit (
unreffor long-running timers). - Tab close does not stop background agent tasks — tooltip correctly says "will continue running in background".
Completed Work
Phase 1: Bug Fixes
- Added shared
AgentBackgroundTaskcontract inagentInstance/interface.ts. - Added
nextWakeAtISOexposure for heartbeat and alarm tasks. - Fixed sub-agent behavior:
spawnAgentnow creates child with{ volatile: true }.sendMsgToAgentno longer auto-starts heartbeat for volatile instances.
- Fixed cleanup behavior:
closeAgent/deleteAgentnow clear alarm + heartbeat + ScheduledTaskManager tasks.
- Timer robustness:
heartbeatManagerinterval isunref-ed.alarmClocktimeout/interval timers areunref-ed.
- Task Agent template changed so
alarmClockdefault approval mode isauto. - Added settings API for alarm upsert:
setBackgroundAlarm(agentId, ...). - Added settings API for heartbeat upsert:
setBackgroundHeartbeat(agentId, ...). - Added task metadata tracking for runtime observability:
createdBylastRunAtISOrunCount
- Fixed
getAgentsquery filters to use real persisted fields (volatile).
Phase 2: Unified ScheduledTask System
cronerlibrary installed via pnpm.ScheduledTaskEntityadded tosrc/services/database/schema/agent.ts:id,agentInstanceId,agentDefinitionId,namescheduleKind: 'interval' | 'at' | 'cron'schedule: ScheduleConfig(union ofIntervalSchedule | AtSchedule | CronSchedule)payload,enabled,deleteAfterRunactiveHoursStart/End,lastRunAt,nextRunAt,runCount,maxRuns,createdBy- Registered in
DatabaseServiceentity list.
ScheduledTaskManager(scheduledTaskManager.ts):initScheduledTaskManager(repo, agentInstanceService)— boot hookaddTask / updateTask / removeTask— CRUD with DB persistencerestoreScheduledTasks(repo, isVolatile)— re-creates timers on app start, skipping volatile agentsgetActiveTasks / getActiveTasksForAgent— query active in-memory registrycancelTasksForAgent(agentInstanceId)— used bycloseAgent/deleteAgentgetCronPreviewDates(expr, tz, n)— returns next N run datetimes (for UI preview)stopAllScheduledTasks()— for app shutdown- Uses
croner.Cronfor cron-kind tasks;setInterval/setTimeout+.unref()for others
IAgentInstanceServiceextended with:createScheduledTask / updateScheduledTask / deleteScheduledTasklistScheduledTasks / listScheduledTasksForAgentgetCronPreviewDatesCreateScheduledTaskInput,UpdateScheduledTaskInput,ScheduledTasktypes re-exported from manager
AgentInstanceServicewired:initializeDatabase()initialises ScheduledTaskManagerinitialize()callsrestoreScheduledTaskManagerTasks()on startupdeleteAgent/closeAgentcallcancelTasksForAgent- 6 new public methods delegating to ScheduledTaskManager
Phase 3: EditAgentDefinition Schedule UI
EditAgentDefinitionContent.tsx— added "Scheduled Wake-up" section:- Mode dropdown: None / Interval / Daily / Advanced cron
- Interval: number + unit (s/min/h)
- Daily: time picker + timezone field
- Cron: expression field + timezone + live "next 3 runs" preview (calls
getCronPreviewDates) - Wake-up message textarea
- Active hours start/end
- Save/Update button (disabled until preview agent loads)
- Loads existing task via
listScheduledTasksForAgentwhen preview agent is created
Phase 4: Tab Icon & Close Warning
- Schedule indicator + close warning text in tab UIs.
- Implemented on real active path:
TabListDropdown(header tab menu). TabItemshows clock icon with next-run tooltip.- Close button tooltip warns "will continue running in background".
Phase 5: Preferences Background Tasks Upgrade
- AIAgent.tsx — new "Scheduled Tasks" section with MUI Table:
- Columns: Name, Agent, Type, Schedule, Next Run, Runs, Enabled (Switch), Actions (Edit/Delete)
- Empty state with description text + quick create entry
- "Add Task" button → ScheduledTask create/edit dialog (supports interval + cron, cron preview)
- Enable/disable via Switch without deleting
- Refresh button
- Legacy "Background Tasks" section (Chip list, alarm/heartbeat dialogs) preserved for backward compatibility.
ScheduledTaskFormDialoginline state in AIAgent.tsx; shared pattern with EditAgentDef section.
Phase 6: Agent Tool Upgrades
alarmClock.tsupgraded — added sub-tools alongside legacyalarm-clock:schedule-task— create ScheduledTask (interval/at/cron) viaaddTask()list-schedules— list active tasks for this agent viagetActiveTasksForAgent()remove-schedule— remove by task ID viaremoveTask()update-schedule— enable/disable/change message viaupdateTask()
editAgentDefinition.ts— new tool registered intools/index.ts:edit-heartbeat— modify heartbeat config viasetBackgroundHeartbeat()edit-agent-prompt-config— modify agentFrameworkConfig field viaupdateAgentDef()
Phase 7: Tests
- Unit tests
scheduledTaskManager.test.ts(12 tests, all green):- initScheduledTaskManager, addTask, removeTask, updateTask
- cancelTasksForAgent
- restoreScheduledTasks (non-volatile restored, volatile skipped)
- Active hours filtering (fires when no restriction; skips outside narrow window)
- getCronPreviewDates (valid + invalid expression)
- Legacy unit tests preserved:
backgroundTaskSettings.test.ts,agentRepository.test.ts, etc. — all 27 pass. - E2E feature:
scheduledTask.feature— 5 scenarios covering:- View / open / cancel scheduled task dialog in preferences
- Create interval task in preferences
- Cron mode shows expression + timezone fields
- EditAgentDef schedule section renders
- Tab clock indicator scenario (manual verify)
Remaining TODO (Future Enhancements)
- Data migration: auto-migrate
AgentDefinition.heartbeat→ScheduledTaskEntityon first run; deprecate old heartbeat field. - DST-aware daily scheduling: current cron mode handles DST via IANA timezone; daily mode in EditAgentDef uses cron expression under the hood.
- Historical task analytics: persist run history beyond
runCount/lastRunAt. - Sub-agent volatile warning: log warning when a volatile sub-agent calls
schedule-task(task will not survive restart). - Expand E2E: step definitions for
select {value} from {element}may need to be added to cover the new cron mode scenario fully. AgentBrowserTabEntitymissing from DB import — verify it is still registered (unchanged from before this PR).
Risks / Notes
- Very large future
wakeAtISOcan overflowsetTimeoutin JS runtime; tests use realistic timestamps. - LSP may show "error typed value" for
ScheduledTaskEntitymembers — this is a cold-start TypeORM decorator resolution issue;tsc --noEmitreports no errors. - The
alarmClocklegacy system and newScheduledTaskManagercoexist; both persist to DB but in different tables. Full migration of legacy alarms is a future task.
Goals
- Keep agent background scheduling useful but explicit to users.
- Prevent sub-agent scheduling side effects.
- Make scheduling observable and editable from UI.
- Keep tests strict: treat interruption/timeout as real failures and fix root causes.
Architecture Decisions
- Closing a chat tab does not stop the agent process; tab is a view, agent is runtime state.
- Sub-agents are
volatileand should not restore background scheduling after restart. - Heartbeat/Alarm tasks are listed centrally by
getBackgroundTasks(). - UI shows schedule signal where users actually operate tabs (header tab dropdown path).
- Timer lifecycle must not block process exit (
unreffor long-running timers).
Completed Work
Backend
- Added shared
AgentBackgroundTaskcontract inagentInstance/interface.ts. - Added
nextWakeAtISOexposure for heartbeat and alarm tasks. - Fixed sub-agent behavior:
spawnAgentnow creates child with{ volatile: true }.sendMsgToAgentno longer auto-starts heartbeat for volatile instances.
- Fixed cleanup behavior:
closeAgent/deleteAgentnow both clear alarm + heartbeat.
- Timer robustness:
heartbeatManagerinterval isunref-ed.alarmClocktimeout/interval timers areunref-ed.
- Task Agent template changed so
alarmClockdefault approval mode isauto. - Added settings API for alarm upsert:
setBackgroundAlarm(agentId, ...). - Added settings API for heartbeat upsert:
setBackgroundHeartbeat(agentId, ...). - Added task metadata tracking for runtime observability:
createdBylastRunAtISOrunCount
- Fixed
getAgentsquery filters to use real persisted fields (volatile).
UI
- Added schedule indicator + close warning text in tab UIs.
- Implemented on real active path:
TabListDropdown(header tab menu). - Preferences
AIAgentsection consumes shared background task type. - Preferences supports alarm creation/editing (countdown/daily/interval).
- Preferences supports heartbeat creation/editing (enable/disable, interval, active-hours window).
- Task list now shows richer metadata (creator / last run / run count).
Tests
- Added unit test:
agentRepository.test.tsfor volatile creation path. - Fixed previously interrupted streaming test by timer lifecycle fix.
- Added and validated e2e scenario for scheduled indicator + close warning.
- Added focused unit tests for background settings APIs:
- alarm upsert
- heartbeat upsert
- startup restoration behavior
- Added e2e scenarios for preferences-based scheduling workflows:
- create countdown alarm
- edit + cancel alarm
- create + disable heartbeat
Remaining TODO (Next Steps)
Phase 2 — Unified Scheduling System (croner)
- Install
cronerlibrary as cron expression parser (same choice as OpenClaw; lightweight, IANA tz aware). - Add
ScheduledTaskEntitytosrc/services/database/schema/agent.ts:- Fields:
id,agentInstanceId(FK),agentDefinitionId(FK optional),name,scheduleKind(interval|at|cron),schedule(JSON),payload(JSON{message}),enabled,deleteAfterRun,activeHoursStart,activeHoursEnd,lastRunAt,nextRunAt,runCount,maxRuns,createdBy,created,updated.
- Fields:
- Create
src/services/agentInstance/scheduledTaskManager.ts— unified manager using croner for cron tasks, setTimeout/setInterval for others. API:addTask / updateTask / removeTask / restoreTasks / getActiveTasks / getActiveTasksForAgent. - Expose CRUD via IPC:
createScheduledTask / updateScheduledTask / deleteScheduledTask / listScheduledTasks / listScheduledTasksForAgentonIAgentInstanceService. - Migrate existing data on
initialize():AgentDefinition.heartbeat→ScheduledTaskEntity;AgentInstanceEntity.scheduledAlarm→ScheduledTaskEntity.
Phase 3 — Agent Definition Edit UI: Schedule Section
- Add "Scheduled Wake-up"
SectionContainertoEditAgentDefinitionContent.tsx:- Mode select: none / interval / daily / cron.
- Interval: number input + unit select (s/min/h).
- Daily: TimePicker + active-hours range.
- Cron: text input + timezone select + live preview (next 3 triggers via croner).
- Message textarea.
- On save: call
createScheduledTask/updateScheduledTask.
Phase 5 — Preferences Background Tasks Panel Upgrade
- Redesign
AIAgent.tsxBackground Tasks area:- Replace Chip list with MUI
Table(sortable columns: Name, Agent, Type, Schedule, Next Run, Last Run, Runs, Enabled toggle, Actions). - Shared
ScheduledTaskFormDialogcomponent reused between preferences and EditAgentDef. - Improved empty state: explain purpose + quick-create CTA.
- Replace Chip list with MUI
Phase 6 — Tool Upgrades
- Upgrade
alarmClock.ts→ add sub-tools:schedule-task(cron support),list-schedules,remove-schedule,update-schedule. Keep old schema as alias. - Add
editAgentDefinitiontool (src/services/agentInstance/tools/editAgentDefinition.ts): lets agent modify its own AgentDefinition (heartbeat, tools, prompt). Approval mode:confirm. Syncs heartbeat changes toScheduledTaskEntity.
Phase 7 — Tests
- Unit tests for
ScheduledTaskManager: cron parsing, timezone handling, restore logic, active hours, volatile exemption, expiry. - E2E: new
scheduledTask.featurecovering table CRUD in preferences, agent-def schedule config, tab clock icon, close warning. - Manual: restart app → tasks restored; spawnAgent → no inherited schedule; tab close warning interaction.
Decisions
- Tab close does not stop agent (keep current behavior).
- Sub-agents are
volatile: true— exempt from schedule restore. ScheduledTaskEntityis independent (not embedded) for unified UI query and concurrent tasks.cronerlibrary chosen: 10 KB, no extra deps, IANA timezone, same as OpenClaw.- Close-tab tooltip says "Agent continues running in background" (accurate behavior description).
Risks / Notes
- Very large future
wakeAtISOcan overflowsetTimeoutin JS runtime; tests should use realistic timestamps. - Daily mode implemented as repeating interval may drift around DST boundaries; cron-mode solves this.
- Current UX now warns explicitly: closing tab does not stop background wake-ups.
Risks / Notes
- Very large future
wakeAtISOcan overflowsetTimeoutin JS runtime; tests should use realistic timestamps. - Daily mode implemented as repeating interval may drift around DST boundaries; cron-mode can solve this later.
- Current UX now warns explicitly: closing tab does not stop background wake-ups.