Skip to content

Commit 597ea70

Browse files
author
Tim Sinaeve
committed
v0.8.8: Agentic Chat & Workspace Orchestration
1 parent 2bec8fc commit 597ea70

11 files changed

Lines changed: 818 additions & 212 deletions

File tree

App.tsx

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ const MIN_LOGGER_HEIGHT = 100;
5151

5252
const DEFAULT_CHAT_PANEL_WIDTH = 360;
5353
const MIN_CHAT_PANEL_WIDTH = 280;
54-
const MAX_CHAT_PANEL_WIDTH = 600;
54+
const MAX_CHAT_PANEL_WIDTH = 1200;
5555

5656
const PREVIEW_INITIAL_SCALE = 1;
5757
const PREVIEW_MIN_SCALE = 0.25;
@@ -181,7 +181,7 @@ interface UpdateToastState {
181181

182182
export const MainApp: React.FC = () => {
183183
const { settings, saveSettings, loaded: settingsLoaded } = useSettings();
184-
const { items, addDocument, addFolder, updateItem, commitVersion, deleteItems, moveItems, getDescendantIds, duplicateItems, addDocumentsFromFiles, importNodesFromTransfer, createDocumentFromClipboard, setItemLock, isLoading: areDocumentsLoading } = useDocuments();
184+
const { nodes, items, addDocument, addFolder, updateItem, commitVersion, deleteItems, moveItems, getDescendantIds, duplicateItems, addDocumentsFromFiles, importNodesFromTransfer, createDocumentFromClipboard, setItemLock, isLoading: areDocumentsLoading } = useDocuments();
185185
const { templates, addTemplate, updateTemplate, deleteTemplate, deleteTemplates } = useTemplates();
186186
const { theme } = useTheme();
187187

@@ -1476,6 +1476,9 @@ export const MainApp: React.FC = () => {
14761476
storageService.load(LOCAL_STORAGE_KEYS.LOGGER_PANEL_HEIGHT, DEFAULT_LOGGER_HEIGHT).then(height => {
14771477
if (typeof height === 'number') setLoggerPanelHeight(height);
14781478
});
1479+
storageService.load(LOCAL_STORAGE_KEYS.CHAT_PANEL_WIDTH, DEFAULT_CHAT_PANEL_WIDTH).then(width => {
1480+
if (typeof width === 'number') setChatPanelWidth(width);
1481+
});
14791482

14801483
let isCancelled = false;
14811484

@@ -2902,11 +2905,15 @@ export const MainApp: React.FC = () => {
29022905

29032906
const handleGlobalMouseMove = useCallback((e: MouseEvent) => {
29042907
const zoomFactor = settings.uiScale / 100;
2908+
const mainContentMinWidth = 300;
2909+
const splitterWidth = 1.5;
29052910

29062911
if (isSidebarResizing.current) {
2907-
const mainContentMinWidth = 300;
29082912
const newWidth = e.clientX / zoomFactor;
2909-
const calculatedMaxWidth = (window.innerWidth / zoomFactor) - mainContentMinWidth;
2913+
// editorWidth = total - sidebarWidth - splitter - (chatVisible ? splitter + chatWidth : 0)
2914+
// sidebarWidth = total - editorWidth - splitter - (chatVisible ? splitter + chatWidth : 0)
2915+
const chatWidthPart = isChatPanelVisible ? chatPanelWidth + splitterWidth : 0;
2916+
const calculatedMaxWidth = (window.innerWidth / zoomFactor) - mainContentMinWidth - splitterWidth - chatWidthPart;
29102917

29112918
const clampedWidth = Math.max(MIN_SIDEBAR_WIDTH, Math.min(newWidth, calculatedMaxWidth));
29122919
setSidebarWidth(clampedWidth);
@@ -2921,10 +2928,13 @@ export const MainApp: React.FC = () => {
29212928
}
29222929
if (isChatResizing.current) {
29232930
const newWidth = (window.innerWidth - e.clientX) / zoomFactor;
2924-
const clampedWidth = Math.max(MIN_CHAT_PANEL_WIDTH, Math.min(newWidth, MAX_CHAT_PANEL_WIDTH));
2931+
// chatWidth = total - sidebarWidth - splitter - editorWidth - splitter
2932+
const calculatedMaxWidth = (window.innerWidth / zoomFactor) - mainContentMinWidth - sidebarWidth - (splitterWidth * 2);
2933+
2934+
const clampedWidth = Math.max(MIN_CHAT_PANEL_WIDTH, Math.min(newWidth, Math.min(MAX_CHAT_PANEL_WIDTH, calculatedMaxWidth)));
29252935
setChatPanelWidth(clampedWidth);
29262936
}
2927-
}, [settings.uiScale]);
2937+
}, [settings.uiScale, isChatPanelVisible, chatPanelWidth, sidebarWidth]);
29282938

29292939
const handleGlobalMouseUp = useCallback(() => {
29302940
if (isSidebarResizing.current) {
@@ -2937,13 +2947,14 @@ export const MainApp: React.FC = () => {
29372947
}
29382948
if (isChatResizing.current) {
29392949
isChatResizing.current = false;
2950+
storageService.save(LOCAL_STORAGE_KEYS.CHAT_PANEL_WIDTH, chatPanelWidth);
29402951
}
29412952

29422953
if (document.body.style.cursor !== 'default') {
29432954
document.body.style.cursor = 'default';
29442955
document.body.style.userSelect = 'auto';
29452956
}
2946-
}, [sidebarWidth, loggerPanelHeight]);
2957+
}, [sidebarWidth, loggerPanelHeight, chatPanelWidth]);
29472958

29482959
useEffect(() => {
29492960
window.addEventListener('mousemove', handleGlobalMouseMove);
@@ -3246,6 +3257,7 @@ export const MainApp: React.FC = () => {
32463257
onResizeStart={(e: React.MouseEvent) => {
32473258
e.preventDefault();
32483259
isChatResizing.current = true;
3260+
document.body.style.cursor = 'col-resize';
32493261
document.body.style.userSelect = 'none';
32503262
}}
32513263
settings={settings}
@@ -3257,6 +3269,18 @@ export const MainApp: React.FC = () => {
32573269
activeDocument={activeNode ? { title: activeNode.title, content: activeNode.content ?? '' } : undefined}
32583270
selectedText={selectedText}
32593271
addLog={addLog}
3272+
nodes={nodes}
3273+
addNode={handleNewDocument}
3274+
updateNode={handleRenameNode}
3275+
updateDocumentContent={handleCommitVersion}
3276+
deleteNodes={handleDeleteNode}
3277+
moveNodes={moveItems}
3278+
runPython={async (code, nodeId) => {
3279+
return "";
3280+
}}
3281+
runScript={async (lang, code, nodeId) => {
3282+
return "";
3283+
}}
32603284
/>
32613285
</section>
32623286
</>

FUNCTIONAL_MANUAL.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,18 @@ The "Chat with Workspace" feature allows you to query your entire collection of
156156
- **Source Attribution**: When the AI answers a question, it lists the specific documents it used as context. These sources are streamed immediately as soon as the search completes.
157157
- **Smart Privacy**: If the AI determines that none of the retrieved documents contain the answer to your question, the source list is automatically hidden to keep the chat interface clean.
158158

159+
#### Agentic Chat & Workspace Orchestration
160+
161+
Agent Mode transforms the chat assistant from a passive information retriever into an active workspace participant.
162+
163+
- **Tool Calling**: When Agent Mode is enabled, the AI can proactively use tools to interact with your workspace. This includes:
164+
- **Document Management**: Creating new documents or folders, renaming existing ones, and moving files between directories.
165+
- **Content Refactoring**: Reading document contents and performing bulk edits or restructurings based on your instructions.
166+
- **Script Execution**: Running Python, Shell, or PowerShell scripts to process data, generate files, or automate complex workflows.
167+
- **Action Approval Gate**: For security, all sensitive actions (like deleting documents or running scripts) can be configured to require your manual approval. A glassmorphic modal will appear showing exactly what the AI intends to do, including any script code or move parameters, allowing you to approve or deny the request before it executes.
168+
- **Thoughtful Execution**: The agent can perform multi-step tasks—for example, it can list all documents in a folder, search for specific patterns, and then create a summary document based on its findings—all in a single conversation turn.
169+
- **Deep Integration**: The agent has direct access to the same document hooks as the GUI, ensuring that its actions are consistent with the application's state and history.
170+
159171
#### Python Execution Panel
160172

161173
DocForge includes an embedded Python runner that integrates with the editor when you're working on Python content.

VERSION_LOG.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
## v0.8.8 - The Agentic Workspace Update
2+
3+
### ✨ Features
4+
5+
- **Agentic Chat & Workspace Orchestrator**:
6+
* Transformed the chat panel from a passive RAG assistant into an active **Workspace Agent**.
7+
* **Autonomous Operations**: The AI can now create, rename, move, and edit documents and folders directly through natural language commands.
8+
* **Script Orchestration**: The agent can write and execute **Python**, **Shell**, and **PowerShell** scripts to automate complex data processing or system tasks.
9+
* **Multi-Step Reasoning**: Capable of performing complex workflows (e.g., "Find all documents mentioning X, then move them to a new folder called Y") in a single conversation.
10+
- **Security & Action Approval**:
11+
* Implemented a high-fidelity **Action Approval Modal** with a glassmorphic design.
12+
* Configurable safety gates: Users can choose to require manual approval for all agent actions, especially destructive operations or script executions.
13+
- **UI/UX Polish**:
14+
* **Tool Execution Visibility**: Added specialized status indicators and animated icons to show when the AI is "thinking" or "using a tool."
15+
* **Syntax-Highlighted Tool Results**: Results from scripts and workspace operations are now rendered in a dedicated terminal-style card within the chat history.
16+
* **Enhanced Settings**: Added a new "AI Chat" settings section to toggle Agent Mode and Approval requirements.
17+
18+
### 🐛 Fixes
19+
20+
- **Chat Stability**: Fixed several syntax and state synchronization errors in the chat panel that could cause crashes during long-running tool executions.
21+
- **Tag Balance**: Resolved various build-breaking JSX tag mismatches in the Chat UI.
22+
123
## v0.8.7 - The RAG & Clipboard Image Update
224

325
### ✨ Features

0 commit comments

Comments
 (0)