diff --git a/ai-service/src/handlers/chat/route.ts b/ai-service/src/handlers/chat/route.ts index bf59a592a..3b5c0a0b5 100644 --- a/ai-service/src/handlers/chat/route.ts +++ b/ai-service/src/handlers/chat/route.ts @@ -52,7 +52,7 @@ export const handleChatRequest = async (c: Context) => { }).toUIMessageStreamResponse(); } - const imagineClient = await createImagineClient({ + const { imagineClient } = await createImagineClient({ projectId, token // TODO: use the token from the request }); diff --git a/ai-service/src/handlers/conversation.ts b/ai-service/src/handlers/conversation.ts index 098132fd9..4c07a3ee1 100644 --- a/ai-service/src/handlers/conversation.ts +++ b/ai-service/src/handlers/conversation.ts @@ -21,7 +21,7 @@ export const getConversation = async (c: Context) => { const projectId = process.env.IMAGINE_PROJECT_ID!; const artifactId = process.env.IMAGINE_ARTIFACT_ID!; - const imagineClient = await createImagineClient({ + const { imagineClient } = await createImagineClient({ projectId, token }); @@ -41,7 +41,7 @@ export const getConversations = async (c: Context) => { return c.json({ error: "Unauthorized" }, 401); } - const imagineClient = await createImagineClient({ + const { imagineClient } = await createImagineClient({ projectId, token }); diff --git a/ai-service/src/lib/imagine/create-artifact-client.ts b/ai-service/src/lib/imagine/create-artifact-client.ts index 73913cd32..1c52e1447 100644 --- a/ai-service/src/lib/imagine/create-artifact-client.ts +++ b/ai-service/src/lib/imagine/create-artifact-client.ts @@ -1,5 +1,6 @@ import { Client } from "@appwrite.io/console"; import { Imagine } from "./imagine-api-client"; +import { Workspaces } from "./workspaces-api-client"; export async function createImagineClient({ projectId, @@ -15,5 +16,6 @@ export async function createImagineClient({ .setMode("admin") .setJWT(token); const imagineClient = new Imagine(clientProject); - return imagineClient; + const workspacesClient = new Workspaces(clientProject); + return { imagineClient, workspacesClient }; } \ No newline at end of file diff --git a/ai-service/src/lib/imagine/imagine-api-client.ts b/ai-service/src/lib/imagine/imagine-api-client.ts index dece9a9b1..0002cd557 100644 --- a/ai-service/src/lib/imagine/imagine-api-client.ts +++ b/ai-service/src/lib/imagine/imagine-api-client.ts @@ -285,209 +285,6 @@ and all associated resources will be removed. 'content-type': 'application/json' }; - return this.client.call('delete', uri, apiHeaders, payload); - } - /** - * List all messages in a conversation. This endpoint supports pagination and searching. - * - * @param {string} artifactId - * @param {string} conversationId - * @param {string[]} queries - * @param {string} search - * @throws {AppwriteException} - * @returns {Promise} - */ - listMessages( - artifactId: string, - conversationId: string, - queries?: string[], - search?: string - ): Promise { - if (typeof artifactId === 'undefined') { - throw new AppwriteException('Missing required parameter: "artifactId"'); - } - if (typeof conversationId === 'undefined') { - throw new AppwriteException('Missing required parameter: "conversationId"'); - } - const apiPath = '/imagine/artifacts/{artifactId}/conversations/{conversationId}/messages' - .replace('{artifactId}', artifactId) - .replace('{conversationId}', conversationId); - const payload: Payload = {}; - if (typeof queries !== 'undefined') { - payload['queries'] = queries; - } - if (typeof search !== 'undefined') { - payload['search'] = search; - } - const uri = new URL(this.client.config.endpoint + apiPath); - - const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json' - }; - - return this.client.call('get', uri, apiHeaders, payload); - } - /** - * Create a new message in a conversation. - * - * @param {string} artifactId - * @param {string} conversationId - * @param {Type} type - * @param {string} content - * @throws {AppwriteException} - * @returns {Promise} - */ - createMessage( - artifactId: string, - conversationId: string, - type: Type, - content: string - ): Promise { - if (typeof artifactId === 'undefined') { - throw new AppwriteException('Missing required parameter: "artifactId"'); - } - if (typeof conversationId === 'undefined') { - throw new AppwriteException('Missing required parameter: "conversationId"'); - } - if (typeof type === 'undefined') { - throw new AppwriteException('Missing required parameter: "type"'); - } - if (typeof content === 'undefined') { - throw new AppwriteException('Missing required parameter: "content"'); - } - const apiPath = '/imagine/artifacts/{artifactId}/conversations/{conversationId}/messages' - .replace('{artifactId}', artifactId) - .replace('{conversationId}', conversationId); - const payload: Payload = {}; - if (typeof type !== 'undefined') { - payload['type'] = type; - } - if (typeof content !== 'undefined') { - payload['content'] = content; - } - const uri = new URL(this.client.config.endpoint + apiPath); - - const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json' - }; - - return this.client.call('post', uri, apiHeaders, payload); - } - /** - * Get a message by its unique ID. - * - * @param {string} artifactId - * @param {string} conversationId - * @param {string} messageId - * @throws {AppwriteException} - * @returns {Promise} - */ - getMessage( - artifactId: string, - conversationId: string, - messageId: string - ): Promise { - if (typeof artifactId === 'undefined') { - throw new AppwriteException('Missing required parameter: "artifactId"'); - } - if (typeof conversationId === 'undefined') { - throw new AppwriteException('Missing required parameter: "conversationId"'); - } - if (typeof messageId === 'undefined') { - throw new AppwriteException('Missing required parameter: "messageId"'); - } - const apiPath = - '/imagine/artifacts/{artifactId}/conversations/{conversationId}/messages/{messageId}' - .replace('{artifactId}', artifactId) - .replace('{conversationId}', conversationId) - .replace('{messageId}', messageId); - const payload: Payload = {}; - const uri = new URL(this.client.config.endpoint + apiPath); - - const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json' - }; - - return this.client.call('get', uri, apiHeaders, payload); - } - /** - * Update a message by its unique ID. This endpoint allows you to update the message's content and type. - * - * @param {string} artifactId - * @param {string} conversationId - * @param {string} messageId - * @param {string} content - * @param {string} type - * @throws {AppwriteException} - * @returns {Promise} - */ - updateMessage( - artifactId: string, - conversationId: string, - messageId: string, - content?: string, - type?: string - ): Promise { - if (typeof artifactId === 'undefined') { - throw new AppwriteException('Missing required parameter: "artifactId"'); - } - if (typeof conversationId === 'undefined') { - throw new AppwriteException('Missing required parameter: "conversationId"'); - } - if (typeof messageId === 'undefined') { - throw new AppwriteException('Missing required parameter: "messageId"'); - } - const apiPath = - '/imagine/artifacts/{artifactId}/conversations/{conversationId}/messages/{messageId}' - .replace('{artifactId}', artifactId) - .replace('{conversationId}', conversationId) - .replace('{messageId}', messageId); - const payload: Payload = {}; - if (typeof content !== 'undefined') { - payload['content'] = content; - } - if (typeof type !== 'undefined') { - payload['type'] = type; - } - const uri = new URL(this.client.config.endpoint + apiPath); - - const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json' - }; - - return this.client.call('patch', uri, apiHeaders, payload); - } - /** - * Delete a message by its unique ID. Once deleted, the message will no longer be available. - * - * @param {string} artifactId - * @param {string} conversationId - * @param {string} messageId - * @throws {AppwriteException} - * @returns {Promise<{}>} - */ - deleteMessage(artifactId: string, conversationId: string, messageId: string): Promise<{}> { - if (typeof artifactId === 'undefined') { - throw new AppwriteException('Missing required parameter: "artifactId"'); - } - if (typeof conversationId === 'undefined') { - throw new AppwriteException('Missing required parameter: "conversationId"'); - } - if (typeof messageId === 'undefined') { - throw new AppwriteException('Missing required parameter: "messageId"'); - } - const apiPath = - '/imagine/artifacts/{artifactId}/conversations/{conversationId}/messages/{messageId}' - .replace('{artifactId}', artifactId) - .replace('{conversationId}', conversationId) - .replace('{messageId}', messageId); - const payload: Payload = {}; - const uri = new URL(this.client.config.endpoint + apiPath); - - const apiHeaders: { [header: string]: string } = { - 'content-type': 'application/json' - }; - return this.client.call('delete', uri, apiHeaders, payload); } } @@ -496,6 +293,7 @@ export enum Type { Text = 'text', Image = 'image' } + export type Artifact = { /** * Artifact unique ID. @@ -634,74 +432,3 @@ export type ConversationsList = { */ conversations: Conversation[]; }; -/** - * Conversations Messages List - */ -export type ConversationsMessagesList = { - /** - * Total number of messages documents that matched your query. - */ - total: number; - /** - * List of messages. - */ - messages: ConversationsMessage[]; -}; - -/** - * Message - */ -export type Message = { - /** - * Message ID. - */ - $id: string; - /** - * Message creation time in ISO 8601 format. - */ - $createdAt: string; - /** - * Message update date in ISO 8601 format. - */ - $updatedAt: string; - /** - * Message provider type. - */ - providerType: string; - /** - * Topic IDs set as recipients. - */ - topics: string[]; - /** - * User IDs set as recipients. - */ - users: string[]; - /** - * Target IDs set as recipients. - */ - targets: string[]; - /** - * The scheduled time for message. - */ - scheduledAt?: string; - /** - * The time when the message was delivered. - */ - deliveredAt?: string; - /** - * Delivery errors if any. - */ - deliveryErrors?: string[]; - /** - * Number of recipients the message was delivered to. - */ - deliveredTotal: number; - /** - * Data of the message. - */ - data: object; - /** - * Status of delivery. - */ - status: string; -}; diff --git a/ai-service/src/lib/imagine/workspaces-api-client.ts b/ai-service/src/lib/imagine/workspaces-api-client.ts new file mode 100644 index 000000000..4c3b02b84 --- /dev/null +++ b/ai-service/src/lib/imagine/workspaces-api-client.ts @@ -0,0 +1,237 @@ +import { AppwriteException } from '@appwrite.io/console'; +import type { Client, Models, Payload } from '@appwrite.io/console'; + +export class Workspaces { + client: Client; + + constructor(client: Client) { + this.client = client; + } + + /** + * List all workspaces. This endpoint supports pagination and searching. + * + * @param {string[]} queries + * @param {string} search + * @throws {AppwriteException} + * @returns {Promise} + */ + list(queries?: string[], search?: string): Promise { + const apiPath = '/workspaces'; + const payload: Payload = {}; + if (typeof queries !== 'undefined') { + payload['queries'] = queries; + } + if (typeof search !== 'undefined') { + payload['search'] = search; + } + const uri = new URL(this.client.config.endpoint + apiPath); + + const apiHeaders: { [header: string]: string } = { + } + + return this.client.call( + 'get', + uri, + apiHeaders, + payload + ); + } + /** + * Create a new workspace. You can pass a custom ID or generate a random ID with `ID.unique()`. + * + * @param {string} name + * @param {string} workspaceId + * @param {string} specification + * @throws {AppwriteException} + * @returns {Promise} + */ + create(name: string, workspaceId?: string, specification?: string): Promise { + if (typeof name === 'undefined') { + throw new AppwriteException('Missing required parameter: "name"'); + } + const apiPath = '/workspaces'; + const payload: Payload = {}; + if (typeof workspaceId !== 'undefined') { + payload['workspaceId'] = workspaceId; + } + if (typeof name !== 'undefined') { + payload['name'] = name; + } + if (typeof specification !== 'undefined') { + payload['specification'] = specification; + } + const uri = new URL(this.client.config.endpoint + apiPath); + + const apiHeaders: { [header: string]: string } = { + 'content-type': 'application/json', + } + + return this.client.call( + 'post', + uri, + apiHeaders, + payload + ); + } + /** + * Get workspace with ID. + * + * @param {string} workspaceId + * @throws {AppwriteException} + * @returns {Promise} + */ + get(workspaceId: string): Promise { + if (typeof workspaceId === 'undefined') { + throw new AppwriteException('Missing required parameter: "workspaceId"'); + } + const apiPath = '/workspaces/{workspaceId}'.replace('{workspaceId}', workspaceId); + const payload: Payload = {}; + const uri = new URL(this.client.config.endpoint + apiPath); + + const apiHeaders: { [header: string]: string } = { + } + + return this.client.call( + 'get', + uri, + apiHeaders, + payload + ); + } + /** + * Update a workspace name by its unique ID. + * + * @param {string} workspaceId + * @param {string} name + * @throws {AppwriteException} + * @returns {Promise} + */ + update(workspaceId: string, name?: string): Promise { + if (typeof workspaceId === 'undefined') { + throw new AppwriteException('Missing required parameter: "workspaceId"'); + } + const apiPath = '/workspaces/{workspaceId}'.replace('{workspaceId}', workspaceId); + const payload: Payload = {}; + if (typeof name !== 'undefined') { + payload['name'] = name; + } + const uri = new URL(this.client.config.endpoint + apiPath); + + const apiHeaders: { [header: string]: string } = { + 'content-type': 'application/json', + } + + return this.client.call( + 'patch', + uri, + apiHeaders, + payload + ); + } + /** + * Delete a workspace by its unique ID. Once deleted, the workspace will no longer be available +and all associated resources will be removed. + * + * @param {string} workspaceId + * @throws {AppwriteException} + * @returns {Promise<{}>} + */ + delete(workspaceId: string): Promise<{}> { + if (typeof workspaceId === 'undefined') { + throw new AppwriteException('Missing required parameter: "workspaceId"'); + } + const apiPath = '/workspaces/{workspaceId}'.replace('{workspaceId}', workspaceId); + const payload: Payload = {}; + const uri = new URL(this.client.config.endpoint + apiPath); + + const apiHeaders: { [header: string]: string } = { + 'content-type': 'application/json', + } + + return this.client.call( + 'delete', + uri, + apiHeaders, + payload + ); + } + + /** + * Create a new proxy rule for executing Appwrite Workspace on custom domain. + * + * @param {string} domain + * @param {string} workspaceId + * @throws {AppwriteException} + * @returns {Promise} + */ + createWorkspaceProxyRule(domain: string, workspaceId: string): Promise { + if (typeof domain === 'undefined') { + throw new AppwriteException('Missing required parameter: "domain"'); + } + if (typeof workspaceId === 'undefined') { + throw new AppwriteException('Missing required parameter: "workspaceId"'); + } + const apiPath = '/proxy/rules/workspace'; + const payload: Payload = {}; + if (typeof domain !== 'undefined') { + payload['domain'] = domain; + } + if (typeof workspaceId !== 'undefined') { + payload['workspaceId'] = workspaceId; + } + const uri = new URL(this.client.config.endpoint + apiPath); + + const apiHeaders: { [header: string]: string } = { + 'content-type': 'application/json', + } + + return this.client.call( + 'post', + uri, + apiHeaders, + payload + ); + } +} + +/** + * Workspace + */ +export type Workspace = { + /** + * Workspace ID + */ + $id: string; + /** + * Workspace name + */ + name: string; + /** + * Machine specification for builds and executions. + */ + specification: string; + /** + * Workspace status + */ + status: string; + /** + * User ID. + */ + userId: string; + /** + * Team ID. + */ + teamId: string; +} + +export type WorkspacesList = { + /** + * Total number of workspaces documents that matched your query. + */ + total: number; + /** + * List of workspaces. + */ + workspaces: Workspace[]; +} \ No newline at end of file