mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-08-26 14:32:22 +02:00
[aidan] fix/app-selection: surface real app workspace path in selection so the builder edits in place
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
from pydantic import BaseModel, Field, model_validator
|
||||
import os
|
||||
|
||||
from pydantic import BaseModel, Field, computed_field, model_validator
|
||||
from typing import Literal, Optional, Any
|
||||
from uuid import uuid4
|
||||
from datetime import datetime
|
||||
|
||||
from backend.config.paths import OUTPUTS_WORKSPACE_DIR
|
||||
|
||||
|
||||
class Output(BaseModel):
|
||||
id: str = Field(default_factory=lambda: uuid4().hex)
|
||||
@@ -49,6 +53,14 @@ class Output(BaseModel):
|
||||
data.pop("backend_code", None)
|
||||
return data
|
||||
|
||||
@computed_field
|
||||
@property
|
||||
def workspace_path(self) -> str:
|
||||
"""Absolute on-disk folder for this app, resolved from workspace_id. API-only (excluded from the saved JSON since it's machine-specific and re-derivable); lets the frontend show the real edit path when an App card is selected."""
|
||||
if not self.workspace_id:
|
||||
return ""
|
||||
return os.path.abspath(os.path.join(OUTPUTS_WORKSPACE_DIR, self.workspace_id))
|
||||
|
||||
@property
|
||||
def frontend_code(self) -> str:
|
||||
return self.files.get("index.html", "")
|
||||
|
||||
@@ -30,7 +30,7 @@ def load_all() -> list[Output]:
|
||||
|
||||
|
||||
def save(output: Output):
|
||||
atomic_write_json(os.path.join(DATA_DIR, f"{output.id}.json"), output.model_dump())
|
||||
atomic_write_json(os.path.join(DATA_DIR, f"{output.id}.json"), output.model_dump(exclude={"workspace_path"}))
|
||||
|
||||
|
||||
def load(output_id: str) -> Output:
|
||||
|
||||
@@ -79,13 +79,23 @@ export function appendSelectedElements(trimmed: string, selectedEls: SelectedEle
|
||||
lines.push(` browser_id: ${el.semanticData.selectId}`);
|
||||
if (url) lines.push(` URL: ${url}`);
|
||||
lines.push(` (Use BrowserAgent with this browser_id to interact with it, or CreateBrowserAgent for a new browser)`);
|
||||
} else if (el.semanticType === 'view-card') {
|
||||
const appName = typeof el.semanticData?.name === 'string' ? el.semanticData.name : (el.semanticLabel || 'Untitled App');
|
||||
const appPath = typeof el.semanticData?.path === 'string' ? el.semanticData.path : '';
|
||||
lines.push(`${i + 1}. [App Card] ${appName}`);
|
||||
if (appPath) {
|
||||
lines.push(` Workspace path: ${appPath}`);
|
||||
lines.push(` (Edit this app's files in place at the path above. Don't recreate it or write files elsewhere.)`);
|
||||
} else {
|
||||
// No resolved path means the app's folder is gone or unsaved; tell the agent rather than emit a confusing opaque id.
|
||||
lines.push(` (This app has no on-disk workspace yet; ask the user to save or reopen it before editing.)`);
|
||||
}
|
||||
} else if (el.semanticType && el.semanticData) {
|
||||
const typeLabel = {
|
||||
'agent-card': 'Agent Card',
|
||||
'message': 'Message',
|
||||
'tool-call': 'Tool Call',
|
||||
'tool-group': 'Tool Group',
|
||||
'view-card': 'App Card',
|
||||
'browser-card': 'Browser Card',
|
||||
'workflow-card': 'Workflow Card',
|
||||
'workflows-hub-card': 'Workflows Hub',
|
||||
|
||||
@@ -342,7 +342,7 @@ const DashboardViewCard: React.FC<Props> = ({
|
||||
<Box
|
||||
data-select-type="view-card"
|
||||
data-select-id={output.id}
|
||||
data-select-meta={JSON.stringify({ name: output.name, description: output.description })}
|
||||
data-select-meta={JSON.stringify({ name: output.name, description: output.description, path: output.workspace_path })}
|
||||
onPointerDownCapture={() => onBringToFront?.(output.id, 'view')}
|
||||
onClick={(e: React.MouseEvent) => {
|
||||
if (justDraggedRef.current) return;
|
||||
|
||||
@@ -20,6 +20,8 @@ export interface Output {
|
||||
/** Linkage so reopening App Builder reattaches to the in-progress session and workspace. */
|
||||
session_id?: string | null;
|
||||
workspace_id?: string | null;
|
||||
/** Backend-resolved absolute on-disk folder for this app; API-only, empty when no workspace_id. */
|
||||
workspace_path?: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
/** App publishing to {slug}.openswarm.host. Server-managed; mirrored here after a publish/unpublish. */
|
||||
|
||||
Reference in New Issue
Block a user