@yesod/openclaw 0.0.2 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/identity.ts","../src/websocket.ts","../src/prompt.ts","../src/output-parser.ts","../src/adapter.ts","../src/mcp-server.ts"],"sourcesContent":["import {\n generateKeyPairSync,\n sign as cryptoSign,\n createHash,\n createPublicKey,\n} from \"node:crypto\";\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport type { DeviceIdentity } from \"./types.js\";\n\nconst PROTOCOL_VERSION = \"v2\";\nconst DEFAULT_IDENTITY_PATH = join(homedir(), \".yesod\", \"device.json\");\n\nexport function generateDeviceIdentity(): DeviceIdentity {\n const { publicKey, privateKey } = generateKeyPairSync(\"ed25519\");\n\n const pubKeyDer = publicKey.export({ type: \"spki\", format: \"der\" });\n const pubKeyRaw = pubKeyDer.subarray(pubKeyDer.length - 32);\n const publicKeyB64Url = pubKeyRaw.toString(\"base64url\");\n\n const deviceId = createHash(\"sha256\").update(pubKeyRaw).digest(\"hex\");\n\n const privateKeyPem = privateKey\n .export({ type: \"pkcs8\", format: \"pem\" })\n .toString();\n\n return { deviceId, publicKeyB64Url, privateKeyPem };\n}\n\nexport function loadOrCreateIdentity(\n path: string = DEFAULT_IDENTITY_PATH,\n): DeviceIdentity {\n if (existsSync(path)) {\n const data = JSON.parse(readFileSync(path, \"utf-8\"));\n return data as DeviceIdentity;\n }\n\n const identity = generateDeviceIdentity();\n const dir = dirname(path);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(path, JSON.stringify(identity, null, 2), \"utf-8\");\n return identity;\n}\n\nexport function signPayload(privateKeyPem: string, payload: string): string {\n const sig = cryptoSign(null, Buffer.from(payload), privateKeyPem);\n return sig.toString(\"base64url\");\n}\n\nexport function buildAuthPayload(\n deviceId: string,\n clientId: string,\n nonce: string,\n scopes: string[],\n token: string = \"\",\n): { payload: string; signedAtMs: number } {\n const signedAtMs = Date.now();\n const parts = [\n PROTOCOL_VERSION,\n deviceId,\n clientId,\n clientId, // clientMode = clientId\n \"operator\",\n scopes.join(\",\"),\n String(signedAtMs),\n token,\n nonce,\n ];\n return { payload: parts.join(\"|\"), signedAtMs };\n}\n\nexport function deviceIdFromPrivateKey(privateKeyPem: string): string {\n const pubKey = createPublicKey(privateKeyPem);\n const pubKeyDer = pubKey.export({ type: \"spki\", format: \"der\" });\n const pubKeyRaw = pubKeyDer.subarray(pubKeyDer.length - 32);\n return createHash(\"sha256\").update(pubKeyRaw).digest(\"hex\");\n}\n","import WebSocket from \"ws\";\nimport type {\n DeviceIdentity,\n ReqFrame,\n ResFrame,\n EventFrame,\n GatewayFrame,\n} from \"./types.js\";\nimport {\n signPayload,\n buildAuthPayload,\n generateDeviceIdentity,\n} from \"./identity.js\";\n\nconst PROTOCOL_VERSION = 3;\nconst DEFAULT_SCOPES = [\"operator.read\", \"operator.write\", \"operator.admin\"];\n\nexport interface GatewayClientConfig {\n gatewayUrl: string;\n identity?: DeviceIdentity;\n scopes?: string[];\n clientId?: string;\n displayName?: string;\n reconnect?: boolean;\n maxReconnectDelayMs?: number;\n}\n\nexport type EventFrameHandler = (event: EventFrame) => void;\n\nexport class GatewayWebSocketClient {\n private ws: WebSocket | null = null;\n private identity: DeviceIdentity;\n private scopes: string[];\n private clientId: string;\n private displayName: string;\n private reqCounter = 0;\n private pendingRequests = new Map<\n string,\n {\n resolve: (res: ResFrame) => void;\n reject: (err: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n }\n >();\n private eventHandlers: EventFrameHandler[] = [];\n private connected = false;\n private disposed = false;\n private reconnectEnabled: boolean;\n private maxReconnectDelay: number;\n private reconnectDelay = 1000;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private gatewayUrl: string;\n\n constructor(config: GatewayClientConfig) {\n this.gatewayUrl = config.gatewayUrl;\n this.identity = config.identity ?? generateDeviceIdentity();\n this.scopes = config.scopes ?? DEFAULT_SCOPES;\n this.clientId = config.clientId ?? \"cli\";\n this.displayName = config.displayName ?? \"yesod\";\n this.reconnectEnabled = config.reconnect ?? false;\n this.maxReconnectDelay = config.maxReconnectDelayMs ?? 30000;\n }\n\n async connect(): Promise<void> {\n if (this.connected) return;\n return new Promise<void>((resolve, reject) => {\n const ws = new WebSocket(this.gatewayUrl);\n this.ws = ws;\n\n const timeout = setTimeout(() => {\n ws.close();\n reject(new Error(\"Connection timeout\"));\n }, 15000);\n\n ws.on(\"error\", (err) => {\n clearTimeout(timeout);\n reject(err);\n });\n\n ws.on(\"open\", async () => {\n try {\n await this.handleAuth(ws);\n clearTimeout(timeout);\n this.connected = true;\n this.reconnectDelay = 1000;\n this.setupMessageHandler(ws);\n this.setupCloseHandler(ws);\n resolve();\n } catch (err) {\n clearTimeout(timeout);\n ws.close();\n reject(err);\n }\n });\n });\n }\n\n private async handleAuth(ws: WebSocket): Promise<void> {\n // Wait for connect.challenge event\n const challenge = await this.waitForFrame(\n ws,\n (f) => f.type === \"event\" && (f as EventFrame).event === \"connect.challenge\",\n 10000,\n );\n const nonce = (challenge as EventFrame).payload.nonce as string;\n\n // Build and sign auth payload\n const { payload: authPayload, signedAtMs } = buildAuthPayload(\n this.identity.deviceId,\n this.clientId,\n nonce,\n this.scopes,\n );\n const signature = signPayload(this.identity.privateKeyPem, authPayload);\n\n // Send connect request\n const connectId = `r${++this.reqCounter}`;\n const connectReq: ReqFrame = {\n type: \"req\",\n id: connectId,\n method: \"connect\",\n params: {\n minProtocol: PROTOCOL_VERSION,\n maxProtocol: PROTOCOL_VERSION,\n client: {\n id: this.clientId,\n displayName: this.displayName,\n version: \"0.0.2\",\n platform: \"linux\",\n mode: this.clientId,\n },\n role: \"operator\",\n scopes: this.scopes,\n caps: [\"tool-events\"],\n device: {\n id: this.identity.deviceId,\n publicKey: this.identity.publicKeyB64Url,\n signature,\n signedAt: signedAtMs,\n nonce,\n },\n },\n };\n ws.send(JSON.stringify(connectReq));\n\n // Wait for connect response\n const res = await this.waitForFrame(\n ws,\n (f) => f.type === \"res\" && (f as ResFrame).id === connectId,\n 15000,\n );\n\n const resFrame = res as ResFrame;\n if (!resFrame.ok) {\n throw new Error(\n `Connect failed: ${resFrame.error?.message ?? \"unknown error\"}`,\n );\n }\n }\n\n private waitForFrame(\n ws: WebSocket,\n filter: (frame: GatewayFrame) => boolean,\n timeoutMs: number,\n ): Promise<GatewayFrame> {\n return new Promise((resolve, reject) => {\n const timer = setTimeout(\n () => {\n ws.off(\"message\", handler);\n reject(new Error(\"Timeout waiting for frame\"));\n },\n timeoutMs,\n );\n\n const handler = (data: WebSocket.RawData) => {\n let frame: GatewayFrame;\n try {\n frame = JSON.parse(String(data));\n } catch {\n return;\n }\n if (!filter(frame)) return;\n clearTimeout(timer);\n ws.off(\"message\", handler);\n resolve(frame);\n };\n\n ws.on(\"message\", handler);\n });\n }\n\n private setupMessageHandler(ws: WebSocket): void {\n ws.on(\"message\", (data: WebSocket.RawData) => {\n let frame: GatewayFrame;\n try {\n frame = JSON.parse(String(data));\n } catch {\n return;\n }\n\n if (frame.type === \"res\") {\n const pending = this.pendingRequests.get(frame.id);\n if (pending) {\n clearTimeout(pending.timer);\n this.pendingRequests.delete(frame.id);\n pending.resolve(frame as ResFrame);\n }\n } else if (frame.type === \"event\") {\n for (const handler of this.eventHandlers) {\n handler(frame as EventFrame);\n }\n }\n });\n }\n\n private setupCloseHandler(ws: WebSocket): void {\n ws.on(\"close\", () => {\n this.connected = false;\n // Reject all pending requests\n for (const [id, pending] of this.pendingRequests) {\n clearTimeout(pending.timer);\n pending.reject(new Error(\"Connection closed\"));\n this.pendingRequests.delete(id);\n }\n\n if (this.reconnectEnabled && !this.disposed) {\n this.scheduleReconnect();\n }\n });\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectTimer) return;\n this.reconnectTimer = setTimeout(async () => {\n this.reconnectTimer = null;\n try {\n await this.connect();\n } catch {\n this.reconnectDelay = Math.min(\n this.reconnectDelay * 2,\n this.maxReconnectDelay,\n );\n this.scheduleReconnect();\n }\n }, this.reconnectDelay);\n }\n\n async request(\n method: string,\n params: Record<string, unknown> = {},\n timeoutMs: number = 30000,\n ): Promise<ResFrame> {\n if (!this.ws || !this.connected) {\n throw new Error(\"Not connected\");\n }\n const id = `r${++this.reqCounter}`;\n const frame: ReqFrame = { type: \"req\", id, method, params };\n\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pendingRequests.delete(id);\n reject(new Error(`Request timeout: ${method}`));\n }, timeoutMs);\n\n this.pendingRequests.set(id, { resolve, reject, timer });\n this.ws!.send(JSON.stringify(frame));\n });\n }\n\n onEvent(handler: EventFrameHandler): () => void {\n this.eventHandlers.push(handler);\n return () => {\n const idx = this.eventHandlers.indexOf(handler);\n if (idx >= 0) this.eventHandlers.splice(idx, 1);\n };\n }\n\n async subscribeToSession(sessionKey: string): Promise<void> {\n await this.request(\"sessions.subscribe\", { sessionKey });\n await this.request(\"sessions.messages.subscribe\", { sessionKey });\n }\n\n isConnected(): boolean {\n return this.connected;\n }\n\n async disconnect(): Promise<void> {\n this.disposed = true;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n this.connected = false;\n }\n\n getIdentity(): DeviceIdentity {\n return this.identity;\n }\n}\n","import type { TaskSpec, ResultSpec, StepResult } from \"@yesod/core\";\n\nconst FORMAT_INSTRUCTIONS: Record<ResultSpec[\"format\"], string> = {\n summary:\n 'When you are done, output a final summary of what you accomplished. Keep it concise (1-3 paragraphs).',\n structured:\n 'When you are done, output your result as a JSON object with the requested fields. Wrap the JSON in a ```json code block.',\n diff:\n 'When you are done, output a JSON object summarizing the changes: { \"summary\": \"...\", \"filesChanged\": [{ \"path\": \"...\", \"linesAdded\": N, \"linesRemoved\": N }] }. Wrap in a ```json code block.',\n review:\n 'When you are done, output a JSON object: { \"summary\": \"...\", \"findings\": [{ \"severity\": \"critical|high|medium|low|info\", \"location\": \"file:line\", \"issue\": \"...\" }], \"filesReviewed\": [\"...\"] }. Wrap in a ```json code block.',\n test:\n 'When you are done, output a JSON object: { \"summary\": \"...\", \"passed\": N, \"failed\": N, \"skipped\": N, \"failures\": [{ \"test\": \"...\", \"error\": \"...\" }] }. Wrap in a ```json code block.',\n};\n\nfunction formatPriorContext(results: StepResult[]): string {\n const parts = results.map((r) => {\n const status = r.status === \"completed\" ? \"completed\" : `${r.status}`;\n let outputSummary: string;\n if (r.output.format === \"summary\") {\n outputSummary = r.output.summary;\n } else if (r.output.format === \"raw\") {\n outputSummary = r.output.raw.slice(0, 500);\n } else if (\"summary\" in r.output) {\n outputSummary = (r.output as { summary: string }).summary;\n } else {\n outputSummary = JSON.stringify(r.output).slice(0, 500);\n }\n return `[Step \"${r.stepId}\" — ${status}]\\n${outputSummary}`;\n });\n return parts.join(\"\\n\\n\");\n}\n\nexport function enrichInstruction(taskSpec: TaskSpec): string {\n const parts: string[] = [];\n\n // Prior context from dependent steps\n if (taskSpec.priorContext && taskSpec.priorContext.length > 0) {\n parts.push(\"## Context from prior steps\\n\");\n parts.push(formatPriorContext(taskSpec.priorContext));\n parts.push(\"\");\n }\n\n // Main instruction\n parts.push(taskSpec.instruction);\n\n // Output format instructions\n const formatInstr = FORMAT_INSTRUCTIONS[taskSpec.expectedResult.format];\n if (formatInstr) {\n parts.push(\"\");\n parts.push(\"## Output format\");\n parts.push(formatInstr);\n }\n\n // Field hints for structured format\n if (\n taskSpec.expectedResult.format === \"structured\" &&\n taskSpec.expectedResult.fields?.length\n ) {\n parts.push(\n `Include these fields: ${taskSpec.expectedResult.fields.join(\", \")}`,\n );\n }\n\n // Max length hint\n if (taskSpec.expectedResult.maxLength) {\n parts.push(\n `Keep your output under ${taskSpec.expectedResult.maxLength} characters.`,\n );\n }\n\n return parts.join(\"\\n\");\n}\n","import type {\n ResultSpec,\n StructuredOutput,\n SummaryOutput,\n DiffOutput,\n ReviewOutput,\n TestOutput,\n StructuredFieldsOutput,\n RawFallbackOutput,\n} from \"@yesod/core\";\n\nfunction extractJsonBlock(text: string): string | null {\n // Try to extract JSON from a ```json code block\n const match = text.match(/```json\\s*([\\s\\S]*?)```/);\n if (match) return match[1].trim();\n\n // Try to find a top-level JSON object\n const objMatch = text.match(/\\{[\\s\\S]*\\}/);\n if (objMatch) return objMatch[0];\n\n return null;\n}\n\nfunction tryParse(text: string): unknown | null {\n const json = extractJsonBlock(text);\n if (!json) return null;\n try {\n return JSON.parse(json);\n } catch {\n return null;\n }\n}\n\nfunction parseSummary(text: string, spec: ResultSpec): SummaryOutput {\n const summary = spec.maxLength ? text.slice(0, spec.maxLength) : text;\n return { format: \"summary\", summary };\n}\n\nfunction parseDiff(text: string): DiffOutput | null {\n const obj = tryParse(text) as Record<string, unknown> | null;\n if (!obj || typeof obj.summary !== \"string\") return null;\n return {\n format: \"diff\",\n summary: obj.summary as string,\n filesChanged: Array.isArray(obj.filesChanged)\n ? obj.filesChanged.map((f: Record<string, unknown>) => ({\n path: String(f.path ?? \"\"),\n linesAdded: Number(f.linesAdded ?? 0),\n linesRemoved: Number(f.linesRemoved ?? 0),\n }))\n : [],\n };\n}\n\nfunction parseReview(text: string): ReviewOutput | null {\n const obj = tryParse(text) as Record<string, unknown> | null;\n if (!obj || typeof obj.summary !== \"string\") return null;\n return {\n format: \"review\",\n summary: obj.summary as string,\n findings: Array.isArray(obj.findings)\n ? obj.findings.map((f: Record<string, unknown>) => ({\n severity: (f.severity as ReviewOutput[\"findings\"][0][\"severity\"]) ?? \"info\",\n location: String(f.location ?? \"\"),\n issue: String(f.issue ?? \"\"),\n }))\n : [],\n filesReviewed: Array.isArray(obj.filesReviewed)\n ? obj.filesReviewed.map(String)\n : [],\n };\n}\n\nfunction parseTest(text: string): TestOutput | null {\n const obj = tryParse(text) as Record<string, unknown> | null;\n if (!obj || typeof obj.summary !== \"string\") return null;\n return {\n format: \"test\",\n summary: obj.summary as string,\n passed: Number(obj.passed ?? 0),\n failed: Number(obj.failed ?? 0),\n skipped: Number(obj.skipped ?? 0),\n failures: Array.isArray(obj.failures)\n ? obj.failures.map((f: Record<string, unknown>) => ({\n test: String(f.test ?? \"\"),\n error: String(f.error ?? \"\"),\n }))\n : [],\n };\n}\n\nfunction parseStructured(\n text: string,\n spec: ResultSpec,\n): StructuredFieldsOutput | null {\n const obj = tryParse(text) as Record<string, unknown> | null;\n if (!obj) return null;\n const fields: Record<string, unknown> = {};\n if (spec.fields?.length) {\n for (const key of spec.fields) {\n fields[key] = obj[key];\n }\n } else {\n Object.assign(fields, obj);\n }\n return { format: \"structured\", fields };\n}\n\nfunction rawFallback(text: string, parseError?: string): RawFallbackOutput {\n return { format: \"raw\", raw: text, parseError };\n}\n\nexport function parseOutput(\n rawText: string,\n spec: ResultSpec,\n): StructuredOutput {\n if (!rawText || rawText.trim().length === 0) {\n return rawFallback(rawText, \"Empty output\");\n }\n\n switch (spec.format) {\n case \"summary\":\n return parseSummary(rawText, spec);\n\n case \"diff\": {\n const result = parseDiff(rawText);\n return result ?? rawFallback(rawText, \"Failed to parse diff output\");\n }\n\n case \"review\": {\n const result = parseReview(rawText);\n return result ?? rawFallback(rawText, \"Failed to parse review output\");\n }\n\n case \"test\": {\n const result = parseTest(rawText);\n return result ?? rawFallback(rawText, \"Failed to parse test output\");\n }\n\n case \"structured\": {\n const result = parseStructured(rawText, spec);\n return result ?? rawFallback(rawText, \"Failed to parse structured output\");\n }\n\n default:\n return rawFallback(rawText);\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport {\n EventType,\n type YesodEvent,\n type RuntimeAdapter,\n type SpawnOptions,\n type SessionHandle,\n type SessionStatus,\n type StepResult,\n type CostRecord,\n} from \"@yesod/core\";\nimport { GatewayWebSocketClient } from \"./websocket.js\";\nimport type {\n OpenClawConfig,\n EventFrame,\n AgentLifecyclePayload,\n ChatStatePayload,\n} from \"./types.js\";\nimport { enrichInstruction } from \"./prompt.js\";\nimport { parseOutput } from \"./output-parser.js\";\n\ninterface TrackedSession {\n handle: SessionHandle;\n sessionKey: string;\n spawnOptions: SpawnOptions;\n startedAt: number;\n accumulatedText: string;\n}\n\nexport class OpenClawAdapter implements RuntimeAdapter {\n readonly name = \"openclaw\";\n readonly description = \"OpenClaw gateway runtime adapter\";\n\n private ws: GatewayWebSocketClient;\n private config: OpenClawConfig;\n private sessions = new Map<string, TrackedSession>();\n private eventHandlers: Array<(event: YesodEvent) => void> = [];\n private unsubscribeEvents: (() => void) | null = null;\n\n constructor(config: OpenClawConfig) {\n this.config = config;\n this.ws = new GatewayWebSocketClient({\n gatewayUrl: config.gatewayUrl,\n scopes: config.scopes,\n reconnect: true,\n });\n }\n\n async connect(): Promise<void> {\n await this.ws.connect();\n this.unsubscribeEvents = this.ws.onEvent((frame) =>\n this.handleGatewayEvent(frame),\n );\n }\n\n async spawn(opts: SpawnOptions): Promise<SessionHandle> {\n const instruction = enrichInstruction(opts.task);\n const agentId = this.config.defaultAgentId ?? \"test-orchestrator\";\n\n const res = await this.ws.request(\"sessions.create\", {\n agentId,\n message: instruction,\n });\n\n if (!res.ok || !res.payload) {\n throw new Error(\n `Failed to create session: ${res.error?.message ?? \"unknown\"}`,\n );\n }\n\n const sessionKey = res.payload.sessionKey as string;\n const sessionId = res.payload.sessionId as string;\n\n const handle: SessionHandle = {\n id: sessionId,\n adapter: this.name,\n metadata: {\n sessionKey,\n runId: res.payload.runId,\n agentId,\n },\n };\n\n this.sessions.set(sessionId, {\n handle,\n sessionKey,\n spawnOptions: opts,\n startedAt: Date.now(),\n accumulatedText: \"\",\n });\n\n // Subscribe to session events\n await this.ws.subscribeToSession(sessionKey);\n\n // Emit spawn event\n this.emitEvent({\n id: randomUUID(),\n type: EventType.SessionSpawned,\n source: this.name,\n timestamp: Date.now(),\n sessionId,\n workflowId: opts.context?.workflowId,\n stepId: opts.context?.stepId,\n payload: {\n agentId,\n runtime: opts.runtime,\n decision: opts.decision,\n },\n });\n\n return handle;\n }\n\n async send(session: SessionHandle, message: string): Promise<void> {\n const tracked = this.sessions.get(session.id);\n if (!tracked) throw new Error(`Unknown session: ${session.id}`);\n\n await this.ws.request(\"sessions.send\", {\n sessionKey: tracked.sessionKey,\n message,\n });\n }\n\n async kill(session: SessionHandle): Promise<void> {\n const tracked = this.sessions.get(session.id);\n if (!tracked) return;\n\n try {\n await this.ws.request(\"subagents\", {\n action: \"kill\",\n target: session.id,\n });\n } catch {\n // Best effort — session may have already ended\n }\n\n this.sessions.delete(session.id);\n this.emitEvent({\n id: randomUUID(),\n type: EventType.SessionKilled,\n source: this.name,\n timestamp: Date.now(),\n sessionId: session.id,\n payload: {},\n });\n }\n\n async status(session: SessionHandle): Promise<SessionStatus | null> {\n try {\n const res = await this.ws.request(\"subagents\", { action: \"list\" });\n if (!res.ok) return \"unknown\";\n\n const agents = (res.payload?.agents ?? []) as Array<{\n id: string;\n status: string;\n }>;\n const match = agents.find((a) => a.id === session.id);\n if (!match) return this.sessions.has(session.id) ? \"running\" : null;\n\n const statusMap: Record<string, SessionStatus> = {\n running: \"running\",\n completed: \"completed\",\n failed: \"failed\",\n killed: \"killed\",\n };\n return statusMap[match.status] ?? \"unknown\";\n } catch {\n return \"unknown\";\n }\n }\n\n onEvent(handler: (event: YesodEvent) => void): void {\n this.eventHandlers.push(handler);\n }\n\n async dispose(): Promise<void> {\n // Kill remaining sessions\n for (const [, tracked] of this.sessions) {\n try {\n await this.kill(tracked.handle);\n } catch {\n // best effort\n }\n }\n this.sessions.clear();\n if (this.unsubscribeEvents) {\n this.unsubscribeEvents();\n }\n await this.ws.disconnect();\n }\n\n // --- Internal ---\n\n private handleGatewayEvent(frame: EventFrame): void {\n if (frame.event === \"agent\") {\n this.handleAgentEvent(frame);\n } else if (frame.event === \"chat\") {\n this.handleChatEvent(frame);\n }\n // health, tick, etc. — ignored for now\n }\n\n private handleAgentEvent(frame: EventFrame): void {\n const payload = frame.payload as unknown as\n | AgentLifecyclePayload\n | { stream: \"assistant\"; delta?: string; text?: string };\n\n if (payload.stream === \"lifecycle\") {\n const lifecycle = payload as AgentLifecyclePayload;\n if (lifecycle.phase === \"complete\") {\n this.handleSessionComplete(frame);\n } else if (lifecycle.phase === \"error\") {\n this.handleSessionError(frame, lifecycle.error ?? \"Unknown error\");\n }\n } else if (payload.stream === \"assistant\") {\n // Accumulate text for output parsing later\n const delta = (payload as { delta?: string }).delta;\n if (delta) {\n // Try to find which session this belongs to\n // OpenClaw doesn't always include sessionId in events\n // For now, accumulate on the most recent session\n for (const [, tracked] of this.sessions) {\n tracked.accumulatedText += delta;\n }\n }\n\n this.emitEvent({\n id: randomUUID(),\n type: EventType.SessionMessage,\n source: this.name,\n timestamp: Date.now(),\n payload: { stream: \"assistant\", delta },\n });\n }\n }\n\n private handleChatEvent(frame: EventFrame): void {\n const payload = frame.payload as unknown as ChatStatePayload;\n if (payload.state === \"error\") {\n // Find active session and mark as failed\n for (const [sessionId] of this.sessions) {\n this.handleSessionError(\n frame,\n payload.errorMessage ?? \"Chat error\",\n sessionId,\n );\n break;\n }\n }\n }\n\n private handleSessionComplete(frame: EventFrame): void {\n // Find the session that completed\n // OpenClaw event may include sessionId in payload or we match by being the only active session\n const sessionId = this.findSessionId(frame);\n const tracked = sessionId ? this.sessions.get(sessionId) : null;\n if (!tracked) return;\n\n const lifecycle = frame.payload as unknown as AgentLifecyclePayload;\n const durationMs = Date.now() - tracked.startedAt;\n\n // Build cost record from lifecycle data\n const cost: CostRecord = {\n tokens: {\n input: lifecycle.cost?.input ?? 0,\n output: lifecycle.cost?.output ?? 0,\n cacheRead: lifecycle.cost?.cacheRead,\n cacheWrite: lifecycle.cost?.cacheWrite,\n },\n usd: lifecycle.cost?.totalCost ?? 0,\n runtime: tracked.spawnOptions.runtime,\n };\n\n // Parse output according to ResultSpec\n const output = parseOutput(\n tracked.accumulatedText,\n tracked.spawnOptions.task.expectedResult,\n );\n\n const stepResult: StepResult = {\n stepId: tracked.spawnOptions.context?.stepId ?? sessionId!,\n status: \"completed\",\n output,\n meta: {\n runtime: tracked.spawnOptions.runtime,\n decision: tracked.spawnOptions.decision,\n cost,\n durationMs,\n retries: (tracked.spawnOptions.context?.attempt ?? 1) - 1,\n },\n };\n\n this.sessions.delete(sessionId!);\n\n this.emitEvent({\n id: randomUUID(),\n type: EventType.SessionCompleted,\n source: this.name,\n timestamp: Date.now(),\n sessionId: sessionId!,\n workflowId: tracked.spawnOptions.context?.workflowId,\n stepId: tracked.spawnOptions.context?.stepId,\n payload: { stepResult },\n metadata: { cost, duration: durationMs },\n });\n }\n\n private handleSessionError(\n frame: EventFrame,\n error: string,\n overrideSessionId?: string,\n ): void {\n const sessionId = overrideSessionId ?? this.findSessionId(frame);\n const tracked = sessionId ? this.sessions.get(sessionId) : null;\n if (!tracked) return;\n\n const durationMs = Date.now() - tracked.startedAt;\n\n this.sessions.delete(sessionId!);\n\n this.emitEvent({\n id: randomUUID(),\n type: EventType.SessionFailed,\n source: this.name,\n timestamp: Date.now(),\n sessionId: sessionId!,\n workflowId: tracked.spawnOptions.context?.workflowId,\n stepId: tracked.spawnOptions.context?.stepId,\n payload: { error },\n metadata: { duration: durationMs },\n });\n }\n\n private findSessionId(frame: EventFrame): string | undefined {\n // Try payload.sessionId first\n const fromPayload = frame.payload.sessionId as string | undefined;\n if (fromPayload && this.sessions.has(fromPayload)) return fromPayload;\n\n // Fallback: if only one session is tracked, it's likely that one\n if (this.sessions.size === 1) {\n return this.sessions.keys().next().value;\n }\n\n return undefined;\n }\n\n private emitEvent(event: YesodEvent): void {\n for (const handler of this.eventHandlers) {\n handler(event);\n }\n }\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n YESOD_TOOLS,\n OrchestrationEngine,\n type Workflow,\n type WorkflowStep,\n} from \"@yesod/core\";\n\nexport function createYesodMcpServer(\n engine: OrchestrationEngine,\n): McpServer {\n const server = new McpServer({\n name: \"yesod\",\n version: \"0.0.2\",\n });\n\n // yesod_create_workflow\n server.tool(\n YESOD_TOOLS.yesod_create_workflow.name,\n YESOD_TOOLS.yesod_create_workflow.description,\n YESOD_TOOLS.yesod_create_workflow.inputSchema.properties as Record<string, unknown>,\n async (args: Record<string, unknown>) => {\n const name = args.name as string;\n const steps = (args.steps as Array<Record<string, unknown>>).map(\n (s): WorkflowStep => ({\n id: s.id as string,\n name: s.name as string,\n task: s.task as string,\n expectedResult: s.expectedResult as WorkflowStep[\"expectedResult\"],\n runtime: s.runtime as string,\n decision: s.decision as WorkflowStep[\"decision\"],\n dependsOn: (s.dependsOn as string[]) ?? [],\n timeout: s.timeout as number | undefined,\n }),\n );\n\n const workflow: Workflow = {\n id: \"\",\n name,\n steps,\n state: \"created\",\n createdAt: Date.now(),\n };\n\n const created = engine.createWorkflow(workflow);\n await engine.startWorkflow(created.id);\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: JSON.stringify(\n {\n workflowId: created.id,\n status: \"started\",\n steps: created.steps.map((s) => s.id),\n },\n null,\n 2,\n ),\n },\n ],\n };\n },\n );\n\n // yesod_workflow_status\n server.tool(\n YESOD_TOOLS.yesod_workflow_status.name,\n YESOD_TOOLS.yesod_workflow_status.description,\n YESOD_TOOLS.yesod_workflow_status.inputSchema.properties as Record<string, unknown>,\n async (args: Record<string, unknown>) => {\n const workflowId = args.workflowId as string;\n try {\n const status = engine.getWorkflowStatus(workflowId);\n return {\n content: [\n { type: \"text\" as const, text: JSON.stringify(status, null, 2) },\n ],\n };\n } catch (err) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Error: ${err instanceof Error ? err.message : String(err)}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n\n // yesod_cancel_workflow\n server.tool(\n YESOD_TOOLS.yesod_cancel_workflow.name,\n YESOD_TOOLS.yesod_cancel_workflow.description,\n YESOD_TOOLS.yesod_cancel_workflow.inputSchema.properties as Record<string, unknown>,\n async (args: Record<string, unknown>) => {\n const workflowId = args.workflowId as string;\n try {\n await engine.cancelWorkflow(workflowId);\n return {\n content: [\n {\n type: \"text\" as const,\n text: JSON.stringify({ workflowId, status: \"cancelled\" }),\n },\n ],\n };\n } catch (err) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `Error: ${err instanceof Error ? err.message : String(err)}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n\n // yesod_cost_summary\n server.tool(\n YESOD_TOOLS.yesod_cost_summary.name,\n YESOD_TOOLS.yesod_cost_summary.description,\n (YESOD_TOOLS.yesod_cost_summary.inputSchema.properties ?? {}) as Record<string, unknown>,\n async (args: Record<string, unknown>) => {\n const workflowId = args.workflowId as string | undefined;\n const summary = engine.getCostSummary(workflowId);\n return {\n content: [\n { type: \"text\" as const, text: JSON.stringify(summary, null, 2) },\n ],\n };\n },\n );\n\n return server;\n}\n\nexport async function startMcpServer(engine: OrchestrationEngine): Promise<void> {\n const server = createYesodMcpServer(engine);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n"],"mappings":"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","names":["PROTOCOL_VERSION"]}