@@ -3,74 +3,31 @@ import { memoMap } from "@/effect/run-service"
33import { Question } from "@/question"
44import { QuestionID } from "@/question/schema"
55import { lazy } from "@/util/lazy"
6+ import { QuestionReply , QuestionRequest , questionApi } from "@opencode-ai/server"
67import { Effect , Layer , Schema } from "effect"
78import { HttpRouter , HttpServer } from "effect/unstable/http"
8- import { HttpApi , HttpApiBuilder , HttpApiEndpoint , HttpApiGroup , OpenApi } from "effect/unstable/httpapi"
9+ import { HttpApiBuilder } from "effect/unstable/httpapi"
910import type { Handler } from "hono"
1011
1112const root = "/experimental/httpapi/question"
12- const Reply = Schema . Struct ( {
13- answers : Schema . Array ( Question . Answer ) . annotate ( {
14- description : "User answers in order of questions (each answer is an array of selected labels)" ,
15- } ) ,
16- } )
17-
18- const Api = HttpApi . make ( "question" )
19- . add (
20- HttpApiGroup . make ( "question" )
21- . add (
22- HttpApiEndpoint . get ( "list" , root , {
23- success : Schema . Array ( Question . Request ) ,
24- } ) . annotateMerge (
25- OpenApi . annotations ( {
26- identifier : "question.list" ,
27- summary : "List pending questions" ,
28- description : "Get all pending question requests across all sessions." ,
29- } ) ,
30- ) ,
31- HttpApiEndpoint . post ( "reply" , `${ root } /:requestID/reply` , {
32- params : { requestID : QuestionID } ,
33- payload : Reply ,
34- success : Schema . Boolean ,
35- } ) . annotateMerge (
36- OpenApi . annotations ( {
37- identifier : "question.reply" ,
38- summary : "Reply to question request" ,
39- description : "Provide answers to a question request from the AI assistant." ,
40- } ) ,
41- ) ,
42- )
43- . annotateMerge (
44- OpenApi . annotations ( {
45- title : "question" ,
46- description : "Experimental HttpApi question routes." ,
47- } ) ,
48- ) ,
49- )
50- . annotateMerge (
51- OpenApi . annotations ( {
52- title : "opencode experimental HttpApi" ,
53- version : "0.0.1" ,
54- description : "Experimental HttpApi surface for selected instance routes." ,
55- } ) ,
56- )
5713
5814const QuestionLive = HttpApiBuilder . group (
59- Api ,
15+ questionApi ,
6016 "question" ,
6117 Effect . fn ( "QuestionHttpApi.handlers" ) ( function * ( handlers ) {
6218 const svc = yield * Question . Service
19+ const decode = Schema . decodeUnknownSync ( Schema . Array ( QuestionRequest ) )
6320
6421 const list = Effect . fn ( "QuestionHttpApi.list" ) ( function * ( ) {
65- return yield * svc . list ( )
22+ return decode ( yield * svc . list ( ) )
6623 } )
6724
6825 const reply = Effect . fn ( "QuestionHttpApi.reply" ) ( function * ( ctx : {
69- params : { requestID : QuestionID }
70- payload : Schema . Schema . Type < typeof Reply >
26+ params : { requestID : string }
27+ payload : Schema . Schema . Type < typeof QuestionReply >
7128 } ) {
7229 yield * svc . reply ( {
73- requestID : ctx . params . requestID ,
30+ requestID : QuestionID . make ( ctx . params . requestID ) ,
7431 answers : ctx . payload . answers ,
7532 } )
7633 return true
@@ -84,7 +41,7 @@ const web = lazy(() =>
8441 HttpRouter . toWebHandler (
8542 Layer . mergeAll (
8643 AppLayer ,
87- HttpApiBuilder . layer ( Api , { openapiPath : `${ root } /doc` } ) . pipe (
44+ HttpApiBuilder . layer ( questionApi , { openapiPath : `${ root } /doc` } ) . pipe (
8845 Layer . provide ( QuestionLive ) ,
8946 Layer . provide ( HttpServer . layerServices ) ,
9047 ) ,
0 commit comments