@@ -3,29 +3,77 @@ import { memoMap } from "@/effect/run-service"
33import { Question } from "@/question"
44import { QuestionID } from "@/question/schema"
55import { lazy } from "@/util/lazy"
6- import { makeQuestionHandler , questionApi } from "@opencode-ai/server"
7- import { Effect , Layer } from "effect"
6+ import { Effect , Layer , Schema } from "effect"
87import { HttpRouter , HttpServer } from "effect/unstable/http"
9- import { HttpApiBuilder } from "effect/unstable/httpapi"
8+ import { HttpApi , HttpApiBuilder , HttpApiEndpoint , HttpApiGroup , OpenApi } from "effect/unstable/httpapi"
109import type { Handler } from "hono"
1110
1211const root = "/experimental/httpapi/question"
1312
14- export const QuestionApi = questionApi
13+ export const QuestionApi = HttpApi . make ( "question" )
14+ . add (
15+ HttpApiGroup . make ( "question" )
16+ . add (
17+ HttpApiEndpoint . get ( "list" , root , {
18+ success : Schema . Array ( Question . Request ) ,
19+ } ) . annotateMerge (
20+ OpenApi . annotations ( {
21+ identifier : "question.list" ,
22+ summary : "List pending questions" ,
23+ description : "Get all pending question requests across all sessions." ,
24+ } ) ,
25+ ) ,
26+ HttpApiEndpoint . post ( "reply" , `${ root } /:requestID/reply` , {
27+ params : { requestID : QuestionID } ,
28+ payload : Question . Reply ,
29+ success : Schema . Boolean ,
30+ } ) . annotateMerge (
31+ OpenApi . annotations ( {
32+ identifier : "question.reply" ,
33+ summary : "Reply to question request" ,
34+ description : "Provide answers to a question request from the AI assistant." ,
35+ } ) ,
36+ ) ,
37+ )
38+ . annotateMerge (
39+ OpenApi . annotations ( {
40+ title : "question" ,
41+ description : "Experimental HttpApi question routes." ,
42+ } ) ,
43+ ) ,
44+ )
45+ . annotateMerge (
46+ OpenApi . annotations ( {
47+ title : "opencode experimental HttpApi" ,
48+ version : "0.0.1" ,
49+ description : "Experimental HttpApi surface for selected instance routes." ,
50+ } ) ,
51+ )
1552
16- export const QuestionLive = makeQuestionHandler ( {
17- list : Effect . fn ( "QuestionHttpApi.host.list" ) ( function * ( ) {
18- const svc = yield * Question . Service
19- return yield * svc . list ( )
20- } ) ,
21- reply : Effect . fn ( "QuestionHttpApi.host.reply" ) ( function * ( input ) {
53+ export const QuestionLive = Layer . unwrap (
54+ Effect . gen ( function * ( ) {
2255 const svc = yield * Question . Service
23- yield * svc . reply ( {
24- requestID : QuestionID . make ( input . requestID ) ,
25- answers : input . answers ,
56+
57+ const list = Effect . fn ( "QuestionHttpApi.list" ) ( function * ( ) {
58+ return yield * svc . list ( )
2659 } )
60+
61+ const reply = Effect . fn ( "QuestionHttpApi.reply" ) ( function * ( ctx : {
62+ params : { requestID : QuestionID }
63+ payload : Question . Reply
64+ } ) {
65+ yield * svc . reply ( {
66+ requestID : ctx . params . requestID ,
67+ answers : ctx . payload . answers ,
68+ } )
69+ return true
70+ } )
71+
72+ return HttpApiBuilder . group ( QuestionApi , "question" , ( handlers ) =>
73+ handlers . handle ( "list" , list ) . handle ( "reply" , reply ) ,
74+ )
2775 } ) ,
28- } ) . pipe ( Layer . provide ( Question . defaultLayer ) )
76+ ) . pipe ( Layer . provide ( Question . defaultLayer ) )
2977
3078const web = lazy ( ( ) =>
3179 HttpRouter . toWebHandler (
0 commit comments