/** World-loaded worktree tools and the VFS-only gate before every guest tool. */ import { defineExtension, defineTool, hook, ToolTask, GenerationTask, ROOT_CONVERSATION_ID, section } from '@earendil-works/pi-durable' import { obj, oneOf, opt, str } from '@earendil-works/pi-schema' import { Workspaces, WorkspacesApi } from './api.ts' import { workspaces } from './workspaces.ts' import { lander } from './lander.ts' export const order=-200 export const docs=[Workspaces] export default function(host:any) { const service=workspaces(host), landing=lander(host,service) host.implement(WorkspacesApi,{...service,submit:landing.submit,doc:Workspaces}) return defineExtension({name:'workspaces',tasks:[service.Preparation,landing.task], hooks:[hook(ToolTask,{beforeTool:async(_call:any,api:any,ctx:any)=>{ const reason=await service.unavailable(api.conversationId,ctx) return reason?{block:reason}:undefined }}),hook(GenerationTask,{beforeInput:async(_input:any,api:any)=>{ const index=await api.tx.doc(Workspaces,ROOT_CONVERSATION_ID) if(Object.values(index.landerConversations).includes(api.conversationId))throw new Error('The lander runs no model') }})], sections:[section('workspace',async(input:any,ctx:any)=>{ await service.ready(input.conversationId,ctx) const workspace=await service.get(input.conversationId,ctx) return workspace?`Workspace: ${workspace.path} (${workspace.state}), branch ${workspace.branch}, target ${workspace.target}.`:'' })], tools:[defineTool({name:'workspace',description:'Inspect your workspace or submit its clean tip to the lander. State any divergence from the request.',parameters:obj({action:oneOf(['status','submit']),divergence:opt(str())}),replay:'safe',execute:async(args:any,api:any,ctx:any)=>{ if(args.action==='submit'&&!args.divergence?.trim())throw new Error('State divergence, or None') const result=args.action==='submit'?await landing.submit(api.conversationId,args.divergence,ctx,`workspace:${api.conversationId}:${api.callId}`):await service.get(api.conversationId,ctx) return {output:[{type:'text',text:JSON.stringify(result??{})}]} }})], }) }