prompt.ts 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import { Schema } from "effect"
  2. import { optional } from "./schema.js"
  3. import { statics } from "./schema.js"
  4. export interface PromptMention extends Schema.Schema.Type<typeof PromptMention> {}
  5. export const PromptMention = Schema.Struct({
  6. start: Schema.Finite,
  7. end: Schema.Finite,
  8. text: Schema.String,
  9. }).annotate({ identifier: "Prompt.Mention" })
  10. export const FileSource = Schema.Union([
  11. Schema.Struct({ type: Schema.Literal("inline") }),
  12. Schema.Struct({ type: Schema.Literal("uri"), uri: Schema.String }),
  13. ])
  14. .pipe(Schema.toTaggedUnion("type"))
  15. .annotate({ identifier: "Prompt.FileSource" })
  16. export type FileSource = typeof FileSource.Type
  17. export const Base64 = Schema.String.check(
  18. Schema.isPattern(/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/),
  19. ).annotate({ identifier: "Prompt.Base64" })
  20. export type Base64 = typeof Base64.Type
  21. export interface FileAttachment extends Schema.Schema.Type<typeof FileAttachment> {}
  22. export const FileAttachment = Schema.Struct({
  23. data: Base64,
  24. mime: Schema.String,
  25. source: FileSource,
  26. name: Schema.String.pipe(optional),
  27. description: Schema.String.pipe(optional),
  28. mention: PromptMention.pipe(optional),
  29. })
  30. .annotate({ identifier: "Prompt.FileAttachment" })
  31. .pipe(
  32. statics((schema) => ({
  33. create: (input: FileAttachment) =>
  34. schema.make({
  35. data: input.data,
  36. mime: input.mime,
  37. source: input.source,
  38. name: input.name,
  39. description: input.description,
  40. mention: input.mention,
  41. }),
  42. })),
  43. )
  44. export interface AgentAttachment extends Schema.Schema.Type<typeof AgentAttachment> {}
  45. export const AgentAttachment = Schema.Struct({
  46. name: Schema.String,
  47. mention: PromptMention.pipe(optional),
  48. }).annotate({ identifier: "Prompt.AgentAttachment" })
  49. export interface Prompt extends Schema.Schema.Type<typeof Prompt> {}
  50. export const Prompt = Schema.Struct({
  51. text: Schema.String,
  52. files: Schema.Array(FileAttachment).pipe(optional),
  53. agents: Schema.Array(AgentAttachment).pipe(optional),
  54. })
  55. .annotate({ identifier: "Prompt" })
  56. .pipe(
  57. statics((schema) => ({
  58. equivalence: Schema.toEquivalence(schema),
  59. fromUserMessage: (input: Pick<Prompt, "text" | "files" | "agents">) =>
  60. schema.make({
  61. text: input.text,
  62. ...(input.files === undefined ? {} : { files: input.files }),
  63. ...(input.agents === undefined ? {} : { agents: input.agents }),
  64. }),
  65. })),
  66. )