mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-01 08:06:14 +00:00
mac: bundle web chat assets
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
import { ARTIFACTS_RUNTIME_PROVIDER_DESCRIPTION_RO, ARTIFACTS_RUNTIME_PROVIDER_DESCRIPTION_RW, } from "../../prompts/prompts.js";
|
||||
/**
|
||||
* Artifacts Runtime Provider
|
||||
*
|
||||
* Provides programmatic access to session artifacts from sandboxed code.
|
||||
* Allows code to create, read, update, and delete artifacts dynamically.
|
||||
* Supports both online (extension) and offline (downloaded HTML) modes.
|
||||
*/
|
||||
export class ArtifactsRuntimeProvider {
|
||||
constructor(artifactsPanel, agent, readWrite = true) {
|
||||
this.artifactsPanel = artifactsPanel;
|
||||
this.agent = agent;
|
||||
this.readWrite = readWrite;
|
||||
}
|
||||
getData() {
|
||||
// Inject artifact snapshot for offline mode
|
||||
const snapshot = {};
|
||||
this.artifactsPanel.artifacts.forEach((artifact, filename) => {
|
||||
snapshot[filename] = artifact.content;
|
||||
});
|
||||
return { artifacts: snapshot };
|
||||
}
|
||||
getRuntime() {
|
||||
// This function will be stringified, so no external references!
|
||||
return (_sandboxId) => {
|
||||
// Auto-parse/stringify for .json files
|
||||
const isJsonFile = (filename) => filename.endsWith(".json");
|
||||
window.listArtifacts = async () => {
|
||||
// Online: ask extension
|
||||
if (window.sendRuntimeMessage) {
|
||||
const response = await window.sendRuntimeMessage({
|
||||
type: "artifact-operation",
|
||||
action: "list",
|
||||
});
|
||||
if (!response.success)
|
||||
throw new Error(response.error);
|
||||
return response.result;
|
||||
}
|
||||
// Offline: return snapshot keys
|
||||
else {
|
||||
return Object.keys(window.artifacts || {});
|
||||
}
|
||||
};
|
||||
window.getArtifact = async (filename) => {
|
||||
let content;
|
||||
// Online: ask extension
|
||||
if (window.sendRuntimeMessage) {
|
||||
const response = await window.sendRuntimeMessage({
|
||||
type: "artifact-operation",
|
||||
action: "get",
|
||||
filename,
|
||||
});
|
||||
if (!response.success)
|
||||
throw new Error(response.error);
|
||||
content = response.result;
|
||||
}
|
||||
// Offline: read snapshot
|
||||
else {
|
||||
if (!window.artifacts?.[filename]) {
|
||||
throw new Error(`Artifact not found (offline mode): ${filename}`);
|
||||
}
|
||||
content = window.artifacts[filename];
|
||||
}
|
||||
// Auto-parse .json files
|
||||
if (isJsonFile(filename)) {
|
||||
try {
|
||||
return JSON.parse(content);
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Failed to parse JSON from ${filename}: ${e}`);
|
||||
}
|
||||
}
|
||||
return content;
|
||||
};
|
||||
window.createOrUpdateArtifact = async (filename, content, mimeType) => {
|
||||
if (!window.sendRuntimeMessage) {
|
||||
throw new Error("Cannot create/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.sendRuntimeMessage({
|
||||
type: "artifact-operation",
|
||||
action: "createOrUpdate",
|
||||
filename,
|
||||
content: finalContent,
|
||||
mimeType,
|
||||
});
|
||||
if (!response.success)
|
||||
throw new Error(response.error);
|
||||
};
|
||||
window.deleteArtifact = async (filename) => {
|
||||
if (!window.sendRuntimeMessage) {
|
||||
throw new Error("Cannot delete artifacts in offline mode (read-only)");
|
||||
}
|
||||
const response = await window.sendRuntimeMessage({
|
||||
type: "artifact-operation",
|
||||
action: "delete",
|
||||
filename,
|
||||
});
|
||||
if (!response.success)
|
||||
throw new Error(response.error);
|
||||
};
|
||||
};
|
||||
}
|
||||
async handleMessage(message, respond) {
|
||||
if (message.type !== "artifact-operation") {
|
||||
return;
|
||||
}
|
||||
const { action, filename, content, mimeType } = message;
|
||||
try {
|
||||
switch (action) {
|
||||
case "list": {
|
||||
const filenames = Array.from(this.artifactsPanel.artifacts.keys());
|
||||
respond({ success: true, result: filenames });
|
||||
break;
|
||||
}
|
||||
case "get": {
|
||||
const artifact = this.artifactsPanel.artifacts.get(filename);
|
||||
if (!artifact) {
|
||||
respond({ success: false, error: `Artifact not found: ${filename}` });
|
||||
}
|
||||
else {
|
||||
respond({ success: true, result: artifact.content });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "createOrUpdate": {
|
||||
try {
|
||||
const exists = this.artifactsPanel.artifacts.has(filename);
|
||||
const command = exists ? "rewrite" : "create";
|
||||
const action = exists ? "update" : "create";
|
||||
await this.artifactsPanel.tool.execute("", {
|
||||
command,
|
||||
filename,
|
||||
content,
|
||||
});
|
||||
this.agent?.appendMessage({
|
||||
role: "artifact",
|
||||
action,
|
||||
filename,
|
||||
content,
|
||||
...(action === "create" && { title: filename }),
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
respond({ success: true });
|
||||
}
|
||||
catch (err) {
|
||||
respond({ success: false, error: err.message });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "delete": {
|
||||
try {
|
||||
await this.artifactsPanel.tool.execute("", {
|
||||
command: "delete",
|
||||
filename,
|
||||
});
|
||||
this.agent?.appendMessage({
|
||||
role: "artifact",
|
||||
action: "delete",
|
||||
filename,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
respond({ success: true });
|
||||
}
|
||||
catch (err) {
|
||||
respond({ success: false, error: err.message });
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
respond({ success: false, error: `Unknown artifact action: ${action}` });
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
respond({ success: false, error: error.message });
|
||||
}
|
||||
}
|
||||
getDescription() {
|
||||
return this.readWrite ? ARTIFACTS_RUNTIME_PROVIDER_DESCRIPTION_RW : ARTIFACTS_RUNTIME_PROVIDER_DESCRIPTION_RO;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=ArtifactsRuntimeProvider.js.map
|
||||
Reference in New Issue
Block a user