Files
sausage/extensions/workspaces/server.ts
T

32 lines
2.1 KiB
TypeScript

/** 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??{})}]}
}})],
})
}