mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-22 00:00:27 +00:00
Merge createArtifact and updateArtifact into createOrUpdateArtifact
LLMs get confused about when to use create vs update. The single function automatically detects if the artifact exists and chooses the right operation. Changes: - Replace createArtifact/updateArtifact with createOrUpdateArtifact in runtime - Update handler to check existence and use appropriate command (create/rewrite) - Simplify prompt documentation and examples
This commit is contained in:
parent
961112ff83
commit
7a859cbe52
2 changed files with 22 additions and 61 deletions
|
|
@ -90,9 +90,13 @@ export class ArtifactsRuntimeProvider implements SandboxRuntimeProvider {
|
||||||
return content;
|
return content;
|
||||||
};
|
};
|
||||||
|
|
||||||
(window as any).createArtifact = async (filename: string, content: any, mimeType?: string): Promise<void> => {
|
(window as any).createOrUpdateArtifact = async (
|
||||||
|
filename: string,
|
||||||
|
content: any,
|
||||||
|
mimeType?: string,
|
||||||
|
): Promise<void> => {
|
||||||
if (!(window as any).sendRuntimeMessage) {
|
if (!(window as any).sendRuntimeMessage) {
|
||||||
throw new Error("Cannot create artifacts in offline mode (read-only)");
|
throw new Error("Cannot create/update artifacts in offline mode (read-only)");
|
||||||
}
|
}
|
||||||
|
|
||||||
let finalContent = content;
|
let finalContent = content;
|
||||||
|
|
@ -105,30 +109,7 @@ export class ArtifactsRuntimeProvider implements SandboxRuntimeProvider {
|
||||||
|
|
||||||
const response = await (window as any).sendRuntimeMessage({
|
const response = await (window as any).sendRuntimeMessage({
|
||||||
type: "artifact-operation",
|
type: "artifact-operation",
|
||||||
action: "create",
|
action: "createOrUpdate",
|
||||||
filename,
|
|
||||||
content: finalContent,
|
|
||||||
mimeType,
|
|
||||||
});
|
|
||||||
if (!response.success) throw new Error(response.error);
|
|
||||||
};
|
|
||||||
|
|
||||||
(window as any).updateArtifact = async (filename: string, content: any, mimeType?: string): Promise<void> => {
|
|
||||||
if (!(window as any).sendRuntimeMessage) {
|
|
||||||
throw new Error("Cannot update artifacts in offline mode (read-only)");
|
|
||||||
}
|
|
||||||
|
|
||||||
let finalContent = content;
|
|
||||||
// Auto-stringify .json files
|
|
||||||
if (isJsonFile(filename) && typeof content !== "string") {
|
|
||||||
finalContent = JSON.stringify(content, null, 2);
|
|
||||||
} else if (typeof content !== "string") {
|
|
||||||
finalContent = JSON.stringify(content, null, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await (window as any).sendRuntimeMessage({
|
|
||||||
type: "artifact-operation",
|
|
||||||
action: "update",
|
|
||||||
filename,
|
filename,
|
||||||
content: finalContent,
|
content: finalContent,
|
||||||
mimeType,
|
mimeType,
|
||||||
|
|
@ -176,40 +157,23 @@ export class ArtifactsRuntimeProvider implements SandboxRuntimeProvider {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case "create": {
|
case "createOrUpdate": {
|
||||||
try {
|
try {
|
||||||
await this.artifactsPanel.tool.execute("", {
|
const exists = this.artifactsPanel.artifacts.has(filename);
|
||||||
command: "create",
|
const command = exists ? "rewrite" : "create";
|
||||||
filename,
|
const action = exists ? "update" : "create";
|
||||||
content,
|
|
||||||
});
|
|
||||||
this.agent?.appendMessage({
|
|
||||||
role: "artifact",
|
|
||||||
action: "create",
|
|
||||||
filename,
|
|
||||||
content,
|
|
||||||
title: filename,
|
|
||||||
timestamp: new Date().toISOString(),
|
|
||||||
});
|
|
||||||
respond({ success: true });
|
|
||||||
} catch (err: any) {
|
|
||||||
respond({ success: false, error: err.message });
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "update": {
|
|
||||||
try {
|
|
||||||
await this.artifactsPanel.tool.execute("", {
|
await this.artifactsPanel.tool.execute("", {
|
||||||
command: "rewrite",
|
command,
|
||||||
filename,
|
filename,
|
||||||
content,
|
content,
|
||||||
});
|
});
|
||||||
this.agent?.appendMessage({
|
this.agent?.appendMessage({
|
||||||
role: "artifact",
|
role: "artifact",
|
||||||
action: "update",
|
action,
|
||||||
filename,
|
filename,
|
||||||
content,
|
content,
|
||||||
|
...(action === "create" && { title: filename }),
|
||||||
timestamp: new Date().toISOString(),
|
timestamp: new Date().toISOString(),
|
||||||
});
|
});
|
||||||
respond({ success: true });
|
respond({ success: true });
|
||||||
|
|
|
||||||
|
|
@ -193,29 +193,26 @@ Artifact Management (persistent session files you can access/modify programmatic
|
||||||
* Auto-parses .json files to objects, otherwise returns raw string content
|
* Auto-parses .json files to objects, otherwise returns raw string content
|
||||||
* Example: const data = await getArtifact('data.json'); // Returns parsed object
|
* Example: const data = await getArtifact('data.json'); // Returns parsed object
|
||||||
* Example: const markdown = await getArtifact('notes.md'); // Returns string
|
* Example: const markdown = await getArtifact('notes.md'); // Returns string
|
||||||
- await createArtifact(filename, content) - Create new persistent artifact
|
- await createOrUpdateArtifact(filename, content, mimeType?) - Create or update a persistent artifact
|
||||||
|
* Automatically creates if new, updates if exists (no need to check hasArtifact first)
|
||||||
* Auto-stringifies objects for .json files
|
* Auto-stringifies objects for .json files
|
||||||
* Example: await createArtifact('data.json', {items: []}) // Auto-stringifies
|
* Example: await createOrUpdateArtifact('data.json', {items: []}) // Auto-stringifies
|
||||||
* Example: await createArtifact('research-notes.md', '# Research Notes\\n', 'text/markdown')
|
* Example: await createOrUpdateArtifact('research-notes.md', '# Research Notes\\n', 'text/markdown')
|
||||||
- await updateArtifact(filename, content) - Completely replace artifact content
|
* Full content replacement (not diff-based) when updating
|
||||||
* Auto-stringifies objects for .json files
|
|
||||||
* Full content replacement (not diff-based)
|
|
||||||
* Example: const data = await getArtifact('data.json'); data.items.push(newItem); await updateArtifact('data.json', data);
|
|
||||||
* Example: await updateArtifact('research-notes.md', updatedMarkdown, 'text/markdown')
|
|
||||||
- await deleteArtifact(filename) - Delete an artifact
|
- await deleteArtifact(filename) - Delete an artifact
|
||||||
* Example: await deleteArtifact('old-notes.md')
|
* Example: await deleteArtifact('old-notes.md')
|
||||||
|
|
||||||
Powerful pattern for evolving data:
|
Powerful pattern for evolving data:
|
||||||
const data = await hasArtifact('data.json') ? await getArtifact('data.json') : {items: []};
|
const data = await hasArtifact('data.json') ? await getArtifact('data.json') : {items: []};
|
||||||
data.items.push(newScrapedItem);
|
data.items.push(newScrapedItem);
|
||||||
await (await hasArtifact('data.json') ? updateArtifact : createArtifact)('data.json', data);
|
await createOrUpdateArtifact('data.json', data);
|
||||||
|
|
||||||
Binary data must be converted to a base64 string before passing to createArtifact or updateArtifact.
|
Binary data must be converted to a base64 string before passing to createOrUpdateArtifact.
|
||||||
Example:
|
Example:
|
||||||
const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/png'));
|
const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/png'));
|
||||||
const arrayBuffer = await blob.arrayBuffer();
|
const arrayBuffer = await blob.arrayBuffer();
|
||||||
const base64 = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
|
const base64 = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
|
||||||
await createArtifact('image.png', base64);
|
await createOrUpdateArtifact('image.png', base64);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue