* refactor: simplify tool writing * feat: load prompt from plugin in a wiki, let agent know what to do based on https://github.com/TiddlyWiki/TiddlyWiki5/issues/9378 * fix: i18n fix: i18n fix: wrong i18n structure fix: empty i18n * Add ContentLoading component and suspense fallback * fix: monaco loading * docs: usage of chrome mcp to contron during dev * fix: provider config truncate user input when typing * fix: legacy usage * Update package.json * fix: not loadin initial data * feat: better prompt sort * fix: sorting of array * fix: drag * Create DragAndDrop.md * feat: directly enter edit mode * fix: workspace config change cause immediate main wiki restart * Add 'Press Enter to confirm' to tag help texts * fix: dont show system tag when adding sub wiki * feat: inform user to press enter on tag auto complete * refactor: let sub wiki auto complete tag * Revert Add 'Press Enter to confirm' to tag help texts * fix: not able to open prompt editor by click prompt tree * fix: click to open plugin config * chore: remove log * feat: Auto-select the first file if none is selected * fix: don't preview not enabled prompt parts * fix: Keep i18n ally think these keys exist, otherwise it will delete them during "check usage" * lint: fix * Update externalAPI.logging.test.ts
5.5 KiB
Prompt Tree Navigation to Form Editor
Overview
Click on any prompt item in the tree view and automatically open the corresponding form editor with the correct tab and expanded state.
Implementation Details
1. Source Path Tracking
When plugins inject content into the prompt tree using injectToolList() or injectContent(), the system automatically adds a source field to track the original configuration location.
File: src/services/agentInstance/tools/defineTool.ts
// Build source path pointing to the plugin configuration
const pluginIndex = context.pluginIndex;
const source = pluginIndex !== undefined ? ['plugins', toolConfig.id] : undefined;
const toolPrompt: IPrompt = {
id: `${toolId}-tool-list-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,
text: toolContent,
caption: options.caption ?? `${definition.displayName} Tools`,
enabled: true,
source, // ['plugins', 'plugin-id']
};
The source array format: ['plugins', pluginId] or ['prompts', promptId, ...]
2. Navigation Trigger
File: src/pages/ChatTabContent/components/PromptTree.tsx
When a user clicks a tree node:
const handleNodeClick = useCallback((event: React.MouseEvent) => {
event.stopPropagation();
// Use source path if available, otherwise construct from fieldPath
const targetFieldPath = (node.source && node.source.length > 0)
? node.source
: [...fieldPath, node.id];
setFormFieldsToScrollTo(targetFieldPath);
}, [node.source, node.id, fieldPath, setFormFieldsToScrollTo]);
3. Tab Switching
File: src/pages/ChatTabContent/components/PromptPreviewDialog/PromptConfigForm/templates/RootObjectFieldTemplate.tsx
The root form template listens to the navigation path and switches to the appropriate tab:
useEffect(() => {
if (formFieldsToScrollTo.length > 0) {
const targetTab = formFieldsToScrollTo[0]; // 'prompts', 'plugins', or 'response'
const tabIndex = properties.findIndex(property => property.name === targetTab);
if (tabIndex !== -1 && tabIndex !== activeTab) {
setActiveTab(tabIndex);
}
}
}, [formFieldsToScrollTo, properties, activeTab]);
4. Item Expansion
File: src/pages/ChatTabContent/components/PromptPreviewDialog/EditView.tsx
The EditView component handles the expansion of nested items:
useEffect(() => {
if (formFieldsToScrollTo.length > 0 && editorMode === 'form') {
const savedPath = [...formFieldsToScrollTo];
// Wait for RootObjectFieldTemplate to switch tabs
setTimeout(() => {
setFormFieldsToScrollTo([]); // Clear after tab switches
// Step 1: Expand top-level item
const topLevelKey = savedPath[0];
const firstItemId = savedPath[1];
expandItemsByPath(topLevelKey, [firstItemId]);
// Step 2: Expand nested children if present
if (savedPath.length > 2) {
setTimeout(() => {
const parentIndex = findParentIndex(topLevelKey, firstItemId);
const nestedFieldPath = `${topLevelKey}_${parentIndex}_children`;
const nestedItemIds = savedPath.slice(2);
expandItemsByPath(nestedFieldPath, nestedItemIds);
}, 300);
}
}, 100);
}
}, [formFieldsToScrollTo, editorMode, agentFrameworkConfig]);
5. Store Management
File: src/pages/Agent/store/agentChatStore/PromptPreviewStore.ts
The store maintains:
- Expansion state for all array fields
- Navigation path queue
- Helper functions to expand/collapse items
interface PromptPreviewStore {
arrayExpansionStore: Record<string, Record<number, boolean>>;
formFieldsToScrollTo: string[];
setItemExpanded: (fieldPath: string, index: number, expanded: boolean) => void;
setFormFieldsToScrollTo: (path: string[]) => void;
}
Data Flow
- User clicks "Git Tools" in tree view
PromptTreereadsnode.source→['plugins', 'g3f4e5d6-7e8f-9g0h-1i2j-l3m4n5o6p7q8']- Calls
setFormFieldsToScrollTo(['plugins', 'g3f4e5d6-7e8f-9g0h-1i2j-l3m4n5o6p7q8']) RootObjectFieldTemplatedetects path[0] = 'plugins' → switches to plugins tabEditViewexpands the plugin item with id 'g3f4e5d6-7e8f-9g0h-1i2j-l3m4n5o6p7q8'- Form scrolls to and highlights the target element
Timing Considerations
The implementation uses careful timing to ensure proper rendering:
- 100ms delay: Wait for tab switch before expanding items
- 300ms delay: Wait for parent expansion before expanding nested children
- 500ms delay: Wait for all expansions before scrolling to target
These delays account for React's rendering cycles and DOM updates.
Extension Points
To add navigation support for custom components:
- Add
sourcefield when creating prompts - Ensure
sourcepoints to the configuration location:['topLevelKey', 'itemId', ...] - The navigation system will automatically handle the rest
Related Files
src/services/agentInstance/tools/defineTool.ts- Source path injectionsrc/services/agentInstance/tools/types.ts- Context types with pluginIndexsrc/services/agentInstance/promptConcat/promptConcat.ts- Plugin index passingsrc/pages/ChatTabContent/components/PromptTree.tsx- Click handlersrc/pages/ChatTabContent/components/PromptPreviewDialog/EditView.tsx- Expansion logicsrc/pages/ChatTabContent/components/PromptPreviewDialog/PromptConfigForm/templates/RootObjectFieldTemplate.tsx- Tab switchingsrc/pages/Agent/store/agentChatStore/PromptPreviewStore.ts- State management