import { tool } from '@strands-agents/sdk' import { z } from 'zod' import { mesh } from '../lib/mesh' export const invokeMeshAgent = tool({ name: 'invoke_mesh_agent', description: 'Send a prompt to an agent in another browser tab. Use list_mesh_peers first to discover tabs.', inputSchema: z.object({ tab_id: z.string().describe('Target tab ID from list_mesh_peers'), prompt: z.string().describe('The prompt to send'), timeout_ms: z.number().optional(), }), callback: async (input) => { try { const result = await mesh.invoke(input.tab_id, input.prompt, input.timeout_ms || 60000) return JSON.stringify({ status: 'success', result }) } catch (err: unknown) { return JSON.stringify({ status: 'error', error: (err as Error).message }) } }, }) export const broadcastMesh = tool({ name: 'broadcast_mesh', description: 'Broadcast a message to all other careless tabs (fire and forget).', inputSchema: z.object({ message: z.string() }), callback: (input) => { mesh.broadcast(input.message) return JSON.stringify({ status: 'broadcast_sent' }) }, }) export const listMeshPeers = tool({ name: 'list_mesh_peers', description: 'List all other careless tabs currently connected via the mesh network.', inputSchema: z.object({}), callback: () => { const peers = mesh.getPeers() return JSON.stringify({ status: 'success', my_tab_id: mesh.getMyTabId(), peer_count: peers.length, peers: peers.map(p => ({ tab_id: p.tabId, label: p.label, last_seen_ms_ago: Date.now() - p.lastSeen })), }) }, }) export const addToRing = tool({ name: 'add_to_ring', description: 'Add an entry to the shared ring context. All other tabs + agents see this.', inputSchema: z.object({ agent_id: z.string(), agent_type: z.string().describe('e.g. "browser", "autonomous", "sub-agent"'), text: z.string().describe('Up to 500 chars'), }), callback: (input) => { const entry = mesh.addToRing(input.agent_id, input.agent_type, input.text) return JSON.stringify({ status: 'added', entry }) }, }) export const getRingContext = tool({ name: 'get_ring_context', description: 'Get recent entries from the shared ring context (what other agents have been doing).', inputSchema: z.object({ max_entries: z.number().optional(), exclude_agent_id: z.string().optional(), }), callback: (input) => { let ring = mesh.getRing() if (input.exclude_agent_id) ring = ring.filter(r => r.agentId !== input.exclude_agent_id) const entries = ring.slice(-(input.max_entries || 10)) return JSON.stringify({ status: 'success', count: entries.length, entries }) }, }) export const clearRing = tool({ name: 'clear_ring_context', description: 'Clear the shared ring context on all tabs.', inputSchema: z.object({}), callback: () => { mesh.clearRing() return JSON.stringify({ status: 'cleared' }) }, }) export const MESH_TOOLS = [invokeMeshAgent, broadcastMesh, listMeshPeers, addToRing, getRingContext, clearRing]