diff --git a/package.json b/package.json index 41dd0ef..78012d7 100644 --- a/package.json +++ b/package.json @@ -24,9 +24,9 @@ "dependencies": { "@effect-http/client": "^0.26.1", "@effect/data": "^0.12.2", - "@effect/io": "^0.25.12", + "@effect/io": "^0.25.13", "@effect/stream": "^0.21.1", - "dfx": "^0.45.8", + "dfx": "^0.45.9", "dotenv": "^16.0.3", "openai": "^3.2.1" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 73b02e1..5b77b55 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,14 +8,14 @@ dependencies: specifier: ^0.12.2 version: 0.12.2 '@effect/io': - specifier: ^0.25.12 - version: 0.25.12 + specifier: ^0.25.13 + version: 0.25.13 '@effect/stream': specifier: ^0.21.1 version: 0.21.1 dfx: - specifier: ^0.45.8 - version: 0.45.8 + specifier: ^0.45.9 + version: 0.45.9 dotenv: specifier: ^16.0.3 version: 16.0.3 @@ -43,7 +43,7 @@ packages: resolution: {integrity: sha512-QVT5PWM4t0PmTyHMvlK12mzULQ4NEIhE8Kw1/Zdcm/7AoBSUzJzEj2Tbdg1EL3OJlDnNjZS6zahW9jcckkXvJQ==} dependencies: '@effect/data': 0.12.2 - '@effect/io': 0.25.12 + '@effect/io': 0.25.13 '@effect/schema': 0.19.3 '@effect/stream': 0.21.1 dev: false @@ -52,8 +52,8 @@ packages: resolution: {integrity: sha512-bmWRTcsSRG1FlBswT+D8SxW6r3c4B3pKJrjYfitCD03tXHnup5gLHaWqbFgIjiyYITS+UsJRRjVrNxvyGG4ZNQ==} dev: false - /@effect/io@0.25.12: - resolution: {integrity: sha512-hZDAVq8UENvfptp4yZczU+33SvrqqreD5SSAbZfv3CYNRdtmyKiPrb5pjBJL52p9Br7Ka0Akvnm6KMkSM4JgGA==} + /@effect/io@0.25.13: + resolution: {integrity: sha512-NdZFSaNbG6AN8bzSAPdmi95AXgHWr4dH58R8viqbFBb0zmfQ/PQq+5XEsC++qy/qpT/ZLzpvJJWhW9jf1atq2g==} dependencies: '@effect/data': 0.12.2 dev: false @@ -62,7 +62,7 @@ packages: resolution: {integrity: sha512-jR7o19HBX7PBYRLV1G6ZlM90giRe+lZkA6BqVNamkhNfVsHU4MnGr2lqM2H4fy4MgR744GGXuxCDjVdydkMvAw==} dependencies: '@effect/data': 0.12.2 - '@effect/io': 0.25.12 + '@effect/io': 0.25.13 fast-check: 3.9.0 dev: false @@ -70,7 +70,7 @@ packages: resolution: {integrity: sha512-x227xIB+PC/xaz4R3RYkjg2Z0sw5Fgkt5hfxXeGHpKThhmqVEeIXjd0v04pcoz2lJtStcvWL5Wuh/Z8HP3Hw/Q==} dependencies: '@effect/data': 0.12.2 - '@effect/io': 0.25.12 + '@effect/io': 0.25.13 dev: false /@types/node@20.2.3: @@ -119,12 +119,12 @@ packages: engines: {node: '>=0.4.0'} dev: false - /dfx@0.45.8: - resolution: {integrity: sha512-DzUTrnyhYzVkNdFKnx2OswaQME9vBBQyNomnDSu7dXyRKeKmraJ/0O7BKeYiQ77qNH5Ap9O7JqLCZ2dYp9C/9g==} + /dfx@0.45.9: + resolution: {integrity: sha512-eaTZ8usr9S1AfGXpQDmpzWAWDRVgIjc074nitYkhHWI7jwRvgd01CYy1tuGwhY2RcsaRqe7dNpUFVGzvo2hVqg==} dependencies: '@effect-http/client': 0.26.1 '@effect/data': 0.12.2 - '@effect/io': 0.25.12 + '@effect/io': 0.25.13 '@effect/stream': 0.21.1 tweetnacl: 1.0.3 optionalDependencies: diff --git a/src/Summarizer.ts b/src/Summarizer.ts index af68326..71e071e 100644 --- a/src/Summarizer.ts +++ b/src/Summarizer.ts @@ -82,6 +82,7 @@ const make = Effect.gen(function* (_) { channel: Discord.Channel, thread: Discord.Channel, messages: Chunk.Chunk, + small: boolean, ) => Effect.map( Effect.forEachParWithIndex(messages, (message, index) => { @@ -94,7 +95,7 @@ const make = Effect.gen(function* (_) { index => [Chunk.unsafeGet(messages, index), index + 1] as const, ), ) - return summarizeMessage(thread, index + 1, message, reply) + return summarizeMessage(thread, index + 1, message, reply, small) }), messageContent => `# ${thread.name} @@ -112,18 +113,27 @@ ${messageContent.join("\n\n")}`, index: number, message: Discord.Message, replyTo: Option.Option, + small: boolean, ) => Effect.gen(function* (_) { const user = message.author const member = yield* _(members.get(thread.guild_id!, message.author.id)) const username = member.nick ?? user.username - const content = `${index}: **${username}**${Option.match( + + const smallOpen = small ? "" : "" + const smallClose = small ? "" : "" + + const reply = Option.match( replyTo, () => "", ([, index]) => ` (replying to \\#${index})`, - )} — ${new Date( + ) + + const header = `${smallOpen}${smallOpen}${index}: **${username}**${reply} ${smallOpen}— ${new Date( message.timestamp, - ).toUTCString()}
+ ).toUTCString()}${smallClose}${smallClose}${smallClose}` + + const content = `${header}
${message.content .replace(/```ts\b/g, "```typescript") .replace(/^```/, "\n```") @@ -156,6 +166,7 @@ ${message.content const followUpResponse = ( context: Discord.Interaction, channel: Discord.Channel, + small: boolean, ) => pipe( Effect.all({ @@ -168,7 +179,7 @@ ${message.content ), ), Effect.bind("summary", ({ parentChannel, messages }) => - summarize(parentChannel, channel, messages), + summarize(parentChannel, channel, messages, small), ), Effect.tap(({ summary }) => { const formData = new FormData() @@ -205,29 +216,44 @@ ${message.content { name: "summarize", description: "Create a summary of the current thread", + options: [ + { + type: Discord.ApplicationCommandOptionType.BOOLEAN, + name: "small", + description: "Add tags to the message headers", + required: false, + }, + ], }, - pipe( - Effect.all({ context: Ix.Interaction }), - Effect.bind("channel", ({ context }) => - channels.get(context.guild_id!, context.channel_id!), - ), - Effect.filterOrFail( - ({ channel }) => channel.type === Discord.ChannelType.PUBLIC_THREAD, - () => new NotInThreadError(), - ), - Effect.tap(({ context, channel }) => - Effect.forkIn(followUpResponse(context, channel), scope), - ), - Effect.as( - Ix.response({ - type: Discord.InteractionCallbackType.CHANNEL_MESSAGE_WITH_SOURCE, - data: { - content: "Creating summary...", - flags: Discord.MessageFlag.EPHEMERAL, - }, + ix => + pipe( + Effect.all({ + context: Ix.Interaction, + small: Effect.map( + ix.optionValueOptional("small"), + Option.getOrElse(() => true), + ), }), + Effect.bind("channel", ({ context }) => + channels.get(context.guild_id!, context.channel_id!), + ), + Effect.filterOrFail( + ({ channel }) => channel.type === Discord.ChannelType.PUBLIC_THREAD, + () => new NotInThreadError(), + ), + Effect.tap(({ context, channel, small }) => + Effect.forkIn(followUpResponse(context, channel, small), scope), + ), + Effect.as( + Ix.response({ + type: Discord.InteractionCallbackType.CHANNEL_MESSAGE_WITH_SOURCE, + data: { + content: "Creating summary...", + flags: Discord.MessageFlag.EPHEMERAL, + }, + }), + ), ), - ), ) const ix = Ix.builder