diff --git a/packages/opencode/src/v2/message.ts b/packages/opencode/src/v2/message.ts new file mode 100644 index 000000000..008a45a36 --- /dev/null +++ b/packages/opencode/src/v2/message.ts @@ -0,0 +1,68 @@ +import { Identifier } from "@/id/id" +import { withStatics } from "@/util/schema" +import { DateTime, Effect, Schema } from "effect" + +export namespace Message { + export const ID = Schema.String.pipe(Schema.brand("Message.ID")).pipe( + withStatics((s) => ({ + create: () => s.make(Identifier.ascending("message")), + prefix: "msg", + })), + ) + + export class File extends Schema.Class("Message.File")({ + url: Schema.String, + mime: Schema.String, + }) { + static create(url: string) { + return new File({ + url, + mime: "text/plain", + }) + } + } + + export class UserContent extends Schema.Class("Message.User.Content")({ + text: Schema.String, + synthetic: Schema.Boolean.pipe(Schema.optional), + agent: Schema.String.pipe(Schema.optional), + files: Schema.Array(File).pipe(Schema.optional), + }) {} + + export class User extends Schema.Class("Message.User")({ + id: ID, + type: Schema.Literal("user"), + time: Schema.Struct({ + created: Schema.DateTimeUtc, + }), + content: UserContent, + }) { + static create(content: Schema.Schema.Type) { + const msg = new User({ + id: ID.create(), + type: "user", + time: { + created: Effect.runSync(DateTime.now), + }, + content, + }) + return msg + } + + static file(url: string) { + return new File({ + url, + mime: "text/plain", + }) + } + } + + export namespace User {} +} + +const msg = Message.User.create({ + text: "Hello world", + files: [Message.File.create("file://example.com/file.txt")], +}) + +console.log(JSON.stringify(msg, null, 2))