question.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. export * as QuestionV1 from "./question"
  2. import { Schema } from "effect"
  3. import { define, inventory } from "../event"
  4. import { ascending } from "../identifier"
  5. import { statics } from "../schema"
  6. import { SessionID } from "../session-id"
  7. import { SessionV1 } from "./session"
  8. export const ID = Schema.String.check(Schema.isStartsWith("que")).pipe(
  9. Schema.brand("QuestionID"),
  10. statics((schema) => ({ ascending: (id?: string) => schema.make(id ?? "que_" + ascending()) })),
  11. )
  12. export const Option = Schema.Struct({
  13. label: Schema.String.annotate({ description: "Display text (1-5 words, concise)" }),
  14. description: Schema.String.annotate({ description: "Explanation of choice" }),
  15. }).annotate({ identifier: "QuestionOption" })
  16. const base = {
  17. question: Schema.String.annotate({ description: "Complete question" }),
  18. header: Schema.String.annotate({ description: "Very short label (max 30 chars)" }),
  19. options: Schema.Array(Option).annotate({ description: "Available choices" }),
  20. multiple: Schema.optional(Schema.Boolean).annotate({ description: "Allow selecting multiple choices" }),
  21. }
  22. export const Info = Schema.Struct({
  23. ...base,
  24. custom: Schema.optional(Schema.Boolean).annotate({ description: "Allow typing a custom answer (default: true)" }),
  25. }).annotate({ identifier: "QuestionInfo" })
  26. export const Prompt = Schema.Struct(base).annotate({ identifier: "QuestionPrompt" })
  27. export const Tool = Schema.Struct({ messageID: SessionV1.MessageID, callID: Schema.String }).annotate({
  28. identifier: "QuestionTool",
  29. })
  30. export const Request = Schema.Struct({
  31. id: ID,
  32. sessionID: SessionID,
  33. questions: Schema.Array(Info).annotate({ description: "Questions to ask" }),
  34. tool: Schema.optional(Tool),
  35. }).annotate({ identifier: "QuestionRequest" })
  36. export const Answer = Schema.Array(Schema.String).annotate({ identifier: "QuestionAnswer" })
  37. export const Reply = Schema.Struct({
  38. answers: Schema.Array(Answer).annotate({
  39. description: "User answers in order of questions (each answer is an array of selected labels)",
  40. }),
  41. }).annotate({ identifier: "QuestionReply" })
  42. export const Replied = Schema.Struct({
  43. sessionID: SessionID,
  44. requestID: ID,
  45. answers: Schema.Array(Answer),
  46. }).annotate({
  47. identifier: "QuestionReplied",
  48. })
  49. export const Rejected = Schema.Struct({ sessionID: SessionID, requestID: ID }).annotate({
  50. identifier: "QuestionRejected",
  51. })
  52. const Asked = define({ type: "question.asked", schema: Request.fields })
  53. const RepliedEvent = define({ type: "question.replied", schema: Replied.fields })
  54. const RejectedEvent = define({ type: "question.rejected", schema: Rejected.fields })
  55. export const Event = {
  56. Asked,
  57. Replied: RepliedEvent,
  58. Rejected: RejectedEvent,
  59. Definitions: inventory(Asked, RepliedEvent, RejectedEvent),
  60. }