Restore Agent workspace and add platform pixel avatars

This commit is contained in:
鲨鱼辣椒 committed 2026-10-12 17:05:24 +08:00
1 parent 7a7d1f7fd8
commit c14d996c05
22 files changed
+1387 -462

No files matched your search

+2
View File
@@ -43,6 +43,8 @@ export async function handleCloudAgentsRoutes(req: IncomingMessage, res: ServerR
data = await cloudAgents.resolvePending(await parseJsonBody(req));
} else if (path === '/avatars/pick' && req.method === 'POST') {
data = await cloudAgents.uploadAvatar();
} else if (path === '/avatars/preset' && req.method === 'POST') {
data = await cloudAgents.useAvatarPreset(await parseJsonBody(req));
} else if (path === '/attachments/pick' && req.method === 'POST') {
data = await cloudAgents.upload();
} else if (path === '/knowledge/pick' && req.method === 'POST') {
@@ -0,0 +1,20 @@
/// <reference types="vite/client" />
// Inline assets make the same allowlisted portraits available in development
// and packaged Main without accepting a path or image bytes from Renderer.
const portraits = import.meta.glob('../../src/assets/agent-avatars/avatar-*.png', {
eager: true,
import: 'default',
query: '?inline',
}) as Record<string, string>;
const presets = new Map(Array.from({ length: 16 }, (_, index) => {
const id = `avatar-${String(index + 1).padStart(2, '0')}`;
return [id, portraits[`../../src/assets/agent-avatars/${id}.png`]];
}));
export function cloudAgentAvatarPreset(id: string): { bytes: Uint8Array; fileName: string } | null {
const image = presets.get(id);
if (!image?.startsWith('data:image/png;base64,')) return null;
return { bytes: new Uint8Array(Buffer.from(image.slice('data:image/png;base64,'.length), 'base64')), fileName: `${id}.png` };
}
+11
View File
@@ -1,5 +1,6 @@
import { EMPTY_CLOUD_CONFIGURATION, type CloudAgentConfiguration, type CloudAgentDraft, type CloudAgentPage, type CreateCloudAgent, type SaveCloudAgentDraft, type CloudUpload } from '../../shared/cloud-agents';
import { operationPlan } from './cloud-agent-operations';
import { cloudAgentAvatarPreset } from './cloud-agent-avatar-presets';
const retiredChannelOperations = new Set([
'channelPolicy',
@@ -397,6 +398,16 @@ export class CloudAgentsModule {
return this.withAvatar({ icon: textField(result.icon, 255) });
}
async useAvatarPreset(value: unknown): Promise<{ icon: string; icon_url: string | null }> {
const id = textField(record(value).id, 32);
const preset = cloudAgentAvatarPreset(id);
if (!preset) throw new CloudAgentsError(422, 'invalid_input');
const body = new FormData();
body.append('file', new Blob([preset.bytes], { type: 'image/png' }), preset.fileName);
const result = record(await this.request('/api/makelore/avatars', 'POST', body));
return this.withAvatar({ icon: textField(result.icon, 255) });
}
async upload(): Promise<CloudUpload | null> {
const body = await this.pickUpload();
if (!body) return null;