diff options
| author | soryu <soryu@soryu.co> | 2026-04-28 19:12:52 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-04-28 19:12:52 +0100 |
| commit | d1fdfb140cc440664f77a24886172f9976a05a31 (patch) | |
| tree | 454739f80dde60fc6c1cd97acbaef3223ac041c6 /frontend/src/services | |
| parent | 636694182fe9381479f2e9062229dda3838c5421 (diff) | |
| download | soryu-d1fdfb140cc440664f77a24886172f9976a05a31.tar.gz soryu-d1fdfb140cc440664f77a24886172f9976a05a31.zip | |
feat: revert broken directive PRs, re-implement Lexical document orchestrator (#98)
* feat: soryu-co/soryu - makima: Revert broken directive PRs and verify clean build
* feat: soryu-co/soryu - makima: Re-implement frontend: Lexical document editor with feature flag and base components
* WIP: heartbeat checkpoint
* feat: soryu-co/soryu - makima: Add contract blocks, expandable log rows, and interaction controls
* WIP: heartbeat checkpoint
* feat: soryu-co/soryu - makima: End-to-end build verification and integration polish
Diffstat (limited to 'frontend/src/services')
| -rw-r--r-- | frontend/src/services/directiveApi.ts | 21 | ||||
| -rw-r--r-- | frontend/src/services/taskWs.ts | 88 |
2 files changed, 21 insertions, 88 deletions
diff --git a/frontend/src/services/directiveApi.ts b/frontend/src/services/directiveApi.ts index 4d1fd82..fcb6636 100644 --- a/frontend/src/services/directiveApi.ts +++ b/frontend/src/services/directiveApi.ts @@ -162,3 +162,24 @@ export async function startTask(taskId: string): Promise<void> { method: 'POST', }) } + +// ---- Contract interaction APIs ---- + +export async function sendContractMessage(taskId: string, message: string): Promise<void> { + await apiFetch(`/api/v1/mesh/tasks/${taskId}/message`, { + method: 'POST', + body: JSON.stringify({ message }), + }) +} + +export async function interruptContract(taskId: string): Promise<void> { + await apiFetch(`/api/v1/mesh/tasks/${taskId}/message`, { + method: 'POST', + body: JSON.stringify({ message: '/interrupt' }), + }) +} + +export async function getContractOutput(taskId: string): Promise<{ output: string }> { + const response = await apiFetch(`/api/v1/mesh/tasks/${taskId}/output`) + return response.json() +} diff --git a/frontend/src/services/taskWs.ts b/frontend/src/services/taskWs.ts deleted file mode 100644 index 832648e..0000000 --- a/frontend/src/services/taskWs.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { VNWebSocket } from './ws' - -export interface TaskOutputMessage { - task_id: string - message_type: string - content: string - tool_name?: string - tool_input?: string - is_error?: boolean - cost_usd?: number - duration_ms?: number - is_partial?: boolean -} - -type TaskOutputCallback = (msg: TaskOutputMessage) => void - -export class TaskOutputStream { - private ws: VNWebSocket - private listeners: Map<string, Set<TaskOutputCallback>> = new Map() - private connected = false - - constructor() { - const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:' - this.ws = new VNWebSocket(`${protocol}//${window.location.host}/ws/tasks`) - - this.ws.on('message', (data: any) => { - if (data && data.type === 'TaskOutput') { - const payload = data.payload || data - const taskId = payload.task_id - if (taskId && this.listeners.has(taskId)) { - this.listeners.get(taskId)!.forEach(cb => cb(payload)) - } - } - }) - - this.ws.on('open', () => { - this.connected = true - // Re-subscribe all active subscriptions on reconnect - for (const taskId of this.listeners.keys()) { - this.ws.send({ type: 'SubscribeOutput', task_id: taskId }) - } - }) - - this.ws.on('close', () => { - this.connected = false - }) - } - - connect() { - this.ws.connect() - } - - subscribe(taskId: string, callback: TaskOutputCallback) { - if (!this.listeners.has(taskId)) { - this.listeners.set(taskId, new Set()) - // Only send subscribe if this is a new task subscription - this.ws.send({ type: 'SubscribeOutput', task_id: taskId }) - } - this.listeners.get(taskId)!.add(callback) - } - - unsubscribe(taskId: string, callback?: TaskOutputCallback) { - if (!this.listeners.has(taskId)) return - - if (callback) { - this.listeners.get(taskId)!.delete(callback) - if (this.listeners.get(taskId)!.size > 0) return - } - - this.listeners.delete(taskId) - this.ws.send({ type: 'UnsubscribeOutput', task_id: taskId }) - } - - close() { - this.ws.close() - this.listeners.clear() - } -} - -let instance: TaskOutputStream | null = null - -export function getTaskOutputStream(): TaskOutputStream { - if (!instance) { - instance = new TaskOutputStream() - instance.connect() - } - return instance -} |
