forked from i-am-alice/3rd-devs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
2,595 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
import OpenAI, { toFile } from "openai"; | ||
import type { ChatCompletionMessageParam } from "openai/resources/chat/completions"; | ||
import fs from 'fs/promises'; | ||
import type { CreateEmbeddingResponse } from 'openai/resources/embeddings'; | ||
|
||
export interface ImageProcessingResult { | ||
description: string; | ||
source: string; | ||
} | ||
|
||
export class OpenAIService { | ||
private openai: OpenAI; | ||
|
||
constructor() { | ||
this.openai = new OpenAI(); | ||
} | ||
|
||
async completion(config: { | ||
messages: ChatCompletionMessageParam[], | ||
model?: string, | ||
stream?: boolean, | ||
jsonMode?: boolean, | ||
maxTokens?: number | ||
}): Promise<OpenAI.Chat.Completions.ChatCompletion | AsyncIterable<OpenAI.Chat.Completions.ChatCompletionChunk>> { | ||
const { messages, model = "gpt-4o", stream = false, jsonMode = false, maxTokens = 4096 } = config; | ||
try { | ||
const chatCompletion = await this.openai.chat.completions.create({ | ||
messages, | ||
model, | ||
...(model !== 'o1-mini' && model !== 'o1-preview' && { | ||
stream, | ||
max_tokens: maxTokens, | ||
response_format: jsonMode ? { type: "json_object" } : { type: "text" } | ||
}) | ||
}); | ||
|
||
return stream | ||
? chatCompletion as AsyncIterable<OpenAI.Chat.Completions.ChatCompletionChunk> | ||
: chatCompletion as OpenAI.Chat.Completions.ChatCompletion; | ||
} catch (error) { | ||
console.error("Error in OpenAI completion:", error); | ||
throw error; | ||
} | ||
} | ||
|
||
async createEmbedding(text: string): Promise<number[]> { | ||
try { | ||
const response: CreateEmbeddingResponse = await this.openai.embeddings.create({ | ||
model: "text-embedding-3-large", | ||
input: text, | ||
}); | ||
return response.data[0].embedding; | ||
} catch (error) { | ||
console.error("Error creating embedding:", error); | ||
throw error; | ||
} | ||
} | ||
|
||
async processImage(imagePath: string): Promise<ImageProcessingResult> { | ||
try { | ||
const image = await fs.readFile(imagePath); | ||
const base64Image = image.toString('base64'); | ||
|
||
const response = await this.openai.chat.completions.create({ | ||
model: "gpt-4-vision-preview", | ||
messages: [ | ||
{ | ||
role: "user", | ||
content: [ | ||
{ type: "text", text: "Describe this image in detail." }, | ||
{ type: "image_url", image_url: { url: `data:image/jpeg;base64,${base64Image}` } }, | ||
], | ||
}, | ||
], | ||
}); | ||
|
||
return { | ||
description: response.choices[0].message.content || "No description available.", | ||
source: imagePath, | ||
}; | ||
} catch (error) { | ||
console.error(`Error processing image ${imagePath}:`, error); | ||
throw error; | ||
} | ||
} | ||
|
||
async processImages(imagePaths: string[]): Promise<ImageProcessingResult[]> { | ||
try { | ||
const results = await Promise.all(imagePaths.map(path => this.processImage(path))); | ||
return results; | ||
} catch (error) { | ||
console.error("Error processing multiple images:", error); | ||
throw error; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import { v9 as Todoist } from 'todoist'; | ||
|
||
export class TasksService { | ||
private todoist: any; | ||
|
||
constructor(token: string) { | ||
this.todoist = Todoist(token); | ||
} | ||
|
||
async sync() { | ||
await this.todoist.sync(); | ||
} | ||
|
||
async addTasks(tasks: { name: string, project_id?: string, due?: string, description?: string }[]) { | ||
|
||
const promises = tasks.map(async task => { | ||
const newItem = await this.todoist.items.add({ | ||
content: task.name, | ||
project_id: task.project_id, | ||
due: { date: task.due }, | ||
description: task.description | ||
}); | ||
|
||
return newItem; | ||
}); | ||
return Promise.all(promises); | ||
} | ||
|
||
async updateTasks(tasks: { task_id: string, project_id?: string, content?: string, due?: string, status?: string, description?: string }[]) { | ||
const promises = tasks.map(async task => { | ||
let previousProjectId: string | undefined; | ||
|
||
if (task.project_id) { | ||
previousProjectId = task.project_id; | ||
await this.todoist.items.move({ id: task.task_id, project_id: task.project_id }); | ||
} | ||
|
||
const updateData: any = { | ||
id: task.task_id, | ||
content: task.content || undefined, | ||
due: task.due ? { date: task.due } : undefined, | ||
project_id: task.project_id || undefined, | ||
checked: task.status === 'DONE', | ||
description: task.description || undefined | ||
}; | ||
|
||
if (task.status === 'DONE') { | ||
await this.todoist.items.close({ id: task.task_id }); | ||
} | ||
|
||
await this.todoist.items.update(updateData); | ||
|
||
const updatedTask = this.todoist.items.get().find(item => item.id === task.task_id); | ||
|
||
if (previousProjectId) { | ||
updatedTask.previous_project = previousProjectId; | ||
} | ||
|
||
return updatedTask; | ||
}); | ||
return Promise.all(promises); | ||
} | ||
|
||
async deleteTasks(taskIds: string[]) { | ||
|
||
const promises = taskIds.map(async id => { | ||
await this.todoist.items.delete({ id }); | ||
|
||
return id; // Return the ID of the deleted task | ||
}); | ||
return Promise.all(promises); | ||
} | ||
|
||
async listProjects() { | ||
return this.todoist.projects.get(); | ||
} | ||
|
||
async getProjectData(projectId: string) { | ||
await this.todoist.sync(); | ||
return this.todoist.projects.get(); | ||
} | ||
|
||
async syncData() { | ||
await this.todoist.sync(); | ||
return { | ||
projects: this.todoist.projects.get(), | ||
tasks: this.todoist.items.get() | ||
}; | ||
} | ||
|
||
async listTasksFromProjects(projectIds: string[], statuses?: string[], startDate?: string, endDate?: string) { | ||
const { projects, tasks } = await this.syncData(); | ||
|
||
const relevantProjects = projects.filter(project => projectIds.includes(project.id)); | ||
const relevantTasks = tasks.filter(task => projectIds.includes(task.project_id)); | ||
|
||
// Apply filters | ||
return relevantTasks.filter((task: any) => { | ||
// Status check | ||
if (statuses && statuses.length > 0) { | ||
const taskStatus = task.checked ? 'DONE' : 'ACTIVE'; | ||
if (!statuses.includes(taskStatus)) return false; | ||
} | ||
|
||
// Date filtering | ||
if (startDate || endDate) { | ||
const taskDate = task.due?.date ? new Date(task.due.date + 'T00:00:00Z') : null; | ||
if (taskDate) { | ||
if (startDate && taskDate < new Date(startDate)) return false; | ||
if (endDate && taskDate > new Date(endDate)) return false; | ||
} | ||
} | ||
|
||
return true; | ||
}); | ||
} | ||
|
||
async getTaskDetails(taskId: string) { | ||
|
||
return this.todoist.items.get().find(task => task.id === taskId); | ||
} | ||
} |
Oops, something went wrong.