package caps import ( "context" "encoding/json" abiv1 "git.dev.alexdunmow.com/block/core/abi/v1" "git.dev.alexdunmow.com/block/core/ai" ) // aiStub implements ai.ToolRegistry (ai.tools.register) and backs the // CoreServices.AITextCall func field (ai.text_call). // // ToolDefinition.Handler stays guest-side: registration marshals only the // static descriptor. Host→guest tool execution is a runtime-WO concern // flagged in core/docs/wasm-abi.md. type aiStub struct{ base } var _ ai.ToolRegistry = (*aiStub)(nil) // Register has no error channel; a transport failure is dropped (the host // records nothing, matching the "best effort at load" contract). func (s *aiStub) Register(tool *ai.ToolDefinition) { if tool == nil { return } req := &abiv1.AiToolRegisterRequest{ Slug: tool.Slug, Name: tool.Name, Description: tool.Description, } if tool.ParameterSchema != nil { if raw, err := json.Marshal(tool.ParameterSchema); err == nil { req.ParameterSchemaJson = raw } } _ = s.invoke(context.Background(), "tools.register", req, &abiv1.AiToolRegisterResponse{}) } // textCall backs CoreServices.AITextCall. func (s *aiStub) textCall(ctx context.Context, taskKey, systemPrompt, userMessage string) (string, error) { req := &abiv1.AiTextCallRequest{ TaskKey: taskKey, SystemPrompt: systemPrompt, UserMessage: userMessage, } resp := &abiv1.AiTextCallResponse{} if err := s.invoke(ctx, "text_call", req, resp); err != nil { return "", err } return resp.GetText(), nil }