feat: auto-create artifacts from file_write tool output
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
When the agent writes files via the file_write tool, artifacts are now automatically created in the artifact panel. The file extension determines the artifact type (code/markdown/text) and syntax highlighting language. This connects the existing ArtifactPanel UI to actual tool output data.
This commit is contained in:
@@ -34,6 +34,7 @@ import {
|
|||||||
resolveGatewayAgentId,
|
resolveGatewayAgentId,
|
||||||
} from './conversationStore';
|
} from './conversationStore';
|
||||||
import { useMessageStore } from './messageStore';
|
import { useMessageStore } from './messageStore';
|
||||||
|
import { useArtifactStore } from './artifactStore';
|
||||||
|
|
||||||
const log = createLogger('StreamStore');
|
const log = createLogger('StreamStore');
|
||||||
|
|
||||||
@@ -297,6 +298,39 @@ export const useStreamStore = create<StreamState>()(
|
|||||||
return { ...m, toolSteps: steps };
|
return { ...m, toolSteps: steps };
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Auto-create artifact when file_write tool produces output
|
||||||
|
if (tool === 'file_write' && output) {
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(output);
|
||||||
|
const filePath = parsed?.path || parsed?.file_path || '';
|
||||||
|
const content = parsed?.content || '';
|
||||||
|
if (filePath && content) {
|
||||||
|
const fileName = filePath.split('/').pop() || filePath;
|
||||||
|
const ext = fileName.split('.').pop()?.toLowerCase() || '';
|
||||||
|
const typeMap: Record<string, 'code' | 'markdown' | 'text'> = {
|
||||||
|
ts: 'code', tsx: 'code', js: 'code', jsx: 'code',
|
||||||
|
py: 'code', rs: 'code', go: 'code', java: 'code',
|
||||||
|
md: 'markdown', txt: 'text', json: 'code',
|
||||||
|
html: 'code', css: 'code', sql: 'code', sh: 'code',
|
||||||
|
};
|
||||||
|
const langMap: Record<string, string> = {
|
||||||
|
ts: 'typescript', tsx: 'typescript', js: 'javascript', jsx: 'javascript',
|
||||||
|
py: 'python', rs: 'rust', go: 'go', java: 'java',
|
||||||
|
html: 'html', css: 'css', sql: 'sql', sh: 'bash', json: 'json',
|
||||||
|
};
|
||||||
|
useArtifactStore.getState().addArtifact({
|
||||||
|
id: `artifact_${Date.now()}`,
|
||||||
|
name: fileName,
|
||||||
|
content: typeof content === 'string' ? content : JSON.stringify(content, null, 2),
|
||||||
|
type: typeMap[ext] || 'text',
|
||||||
|
language: langMap[ext],
|
||||||
|
createdAt: new Date(),
|
||||||
|
sourceStepId: assistantId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch { /* non-critical: artifact creation from tool output */ }
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// toolStart: create new running step
|
// toolStart: create new running step
|
||||||
const step: ToolCallStep = {
|
const step: ToolCallStep = {
|
||||||
|
|||||||
Reference in New Issue
Block a user