Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Message Attachment Image Recognition #118

Merged
merged 5 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ services:
build: ./ # find docker file in designated path
container_name: discord
restart: always # rebuild container always
image: kevinthedang/discord-ollama:0.5.11
image: kevinthedang/discord-ollama:0.6.0
environment:
CLIENT_TOKEN: ${CLIENT_TOKEN}
MODEL: ${MODEL}
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "discord-ollama",
"version": "0.5.11",
"version": "0.6.0",
"description": "Ollama Integration into discord",
"main": "build/index.js",
"exports": "./build/index.js",
Expand Down
3 changes: 2 additions & 1 deletion src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,6 @@ await client.login(Keys.clientToken)
// queue up bots name
messageHistory.enqueue({
role: 'assistant',
content: `My name is ${client.user?.username}`
content: `My name is ${client.user?.username}`,
images: []
})
12 changes: 9 additions & 3 deletions src/events/messageCreate.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { embedMessage, event, Events, normalMessage, UserMessage } from '../utils/index.js'
import { getChannelInfo, getServerConfig, getUserConfig, openChannelInfo, openConfig, ServerConfig, UserConfig } from '../utils/index.js'
import { getChannelInfo, getServerConfig, getUserConfig, openChannelInfo, openConfig, UserConfig, getAttachmentData } from '../utils/index.js'
import { clean } from '../utils/mentionClean.js'
import { TextChannel } from 'discord.js'

Expand Down Expand Up @@ -102,6 +102,10 @@ export default event(Events.MessageCreate, async ({ log, msgHist, tokens, ollama
// response string for ollama to put its response
let response: string

// get message attachment if exists
const messageAttachment: string[] = await getAttachmentData(message.attachments.first())
log(messageAttachment)

// set up new queue
msgHist.setQueue(chatMessages)

Expand All @@ -111,7 +115,8 @@ export default event(Events.MessageCreate, async ({ log, msgHist, tokens, ollama
// push user response before ollama query
msgHist.enqueue({
role: 'user',
content: clean(message.content)
content: clean(message.content),
images: messageAttachment || []
})

// undefined or false, use normal, otherwise use embed
Expand All @@ -129,7 +134,8 @@ export default event(Events.MessageCreate, async ({ log, msgHist, tokens, ollama
// successful query, save it in context history
msgHist.enqueue({
role: 'assistant',
content: response
content: response,
images: messageAttachment || []
})

// only update the json on success
Expand Down
3 changes: 2 additions & 1 deletion src/utils/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ export type ChatParams = {
*/
export type UserMessage = {
role: string,
content: string
content: string,
images: string[] // May or may not have images in message
}

// Event properties
Expand Down
45 changes: 45 additions & 0 deletions src/utils/handlers/bufferHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Attachment } from "discord.js"

async function getAttachmentBuffer(url: string): Promise<ArrayBuffer> {
console.log(url)
// Get the data from the image
const response = await fetch(url)
console.log('After fetch()')

// Validate the image came in fine
if (!response.ok)
throw new Error('Failed to fetch the attachment.')

// Return image as Buffer
return await response.arrayBuffer()
}

function arrayBufferToBase64(buffer: ArrayBuffer): string {
// Converting to Uint8Array
const uint8Array = new Uint8Array(buffer)
let binary = ''
const len = uint8Array.byteLength;
for (let i = 0; i < len; i++) {
binary += String.fromCharCode(uint8Array[i])
}

// Return as Base64
return Buffer.from(binary, 'binary').toString('base64')
}

export async function getAttachmentData(attachment: Attachment | undefined): Promise<string[]> {
console.log(`The attachment is: ${attachment}`)
const url: string = attachment !== undefined ? attachment.url : "Missing Url"

// case of no attachment
if (url === "Missing Url")
return []

console.log(`before buffer with url as ${url || "Invalid"}`)
// Convert data to base64
const buffer = await getAttachmentBuffer(url)
console.log('Before ArrayBuffer to Base64')
const base64String = arrayBufferToBase64(buffer)
console.log(`finished getAttachmentData with ${base64String}`)
return [base64String]
}
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export * from './configInterfaces.js'
export * from './handlers/chatHistoryHandler.js'
export * from './handlers/configHandler.js'
export * from './handlers/streamHandler.js'
export * from './handlers/bufferHandler.js'