assistant-cloud
Version:
Cloud integration for assistant-ui
169 lines (146 loc) • 4.79 kB
text/typescript
import { AssistantCloudThreadRuns } from "./AssistantCloudThreadRuns";
import type { AssistantCloudAPI } from "./AssistantCloudAPI";
import { AssistantCloudThreadMessages } from "./AssistantCloudThreadMessages";
import {
readCloudArray,
readCloudBoolean,
readCloudInteger,
readCloudNullableString,
readCloudRecord,
readCloudString,
readCloudTimestamp,
} from "./cloudResponse";
type AssistantCloudThreadsListQuery = {
is_archived?: boolean;
limit?: number;
after?: string;
};
export type CloudThread = {
title: string;
last_message_at: Date;
metadata: unknown;
external_id: string | null;
id: string;
project_id: string;
created_at: Date;
updated_at: Date;
workspace_id: string;
is_archived: boolean;
};
type AssistantCloudThreadsListResponse = {
threads: CloudThread[];
};
type AssistantCloudThreadsCreateBody = {
title?: string | undefined;
last_message_at: Date;
metadata?: unknown | undefined;
external_id?: string | undefined;
upsert?: boolean | undefined;
};
type AssistantCloudThreadsCreateResponse = {
thread_id: string;
};
type AssistantCloudThreadsClaimBody = {
refresh_token: string;
};
type AssistantCloudThreadsClaimResponse = {
moved: number;
};
type AssistantCloudThreadsUpdateBody = {
title?: string | undefined;
last_message_at?: Date | undefined;
metadata?: unknown | undefined;
is_archived?: boolean | undefined;
};
export const decodeCloudThread = (
value: unknown,
field: string,
): CloudThread => {
const thread = readCloudRecord(value, field);
return {
title: readCloudNullableString(thread.title, `${field}.title`) ?? "",
last_message_at: readCloudTimestamp(
thread.last_message_at,
`${field}.last_message_at`,
),
metadata: thread.metadata,
external_id: readCloudNullableString(
thread.external_id,
`${field}.external_id`,
),
id: readCloudString(thread.id, `${field}.id`),
project_id: readCloudString(thread.project_id, `${field}.project_id`),
created_at: readCloudTimestamp(thread.created_at, `${field}.created_at`),
updated_at: readCloudTimestamp(thread.updated_at, `${field}.updated_at`),
workspace_id: readCloudString(thread.workspace_id, `${field}.workspace_id`),
is_archived: readCloudBoolean(thread.is_archived, `${field}.is_archived`),
};
};
export class AssistantCloudThreads {
public readonly messages: AssistantCloudThreadMessages;
public readonly runs: AssistantCloudThreadRuns;
private cloud: AssistantCloudAPI;
constructor(cloud: AssistantCloudAPI) {
this.cloud = cloud;
this.messages = new AssistantCloudThreadMessages(cloud);
this.runs = new AssistantCloudThreadRuns(cloud);
}
public async list(
query?: AssistantCloudThreadsListQuery,
): Promise<AssistantCloudThreadsListResponse> {
const requestQuery =
query?.is_archived === undefined
? query
: { ...query, is_archived: String(query.is_archived) };
const response = readCloudRecord(
await this.cloud.makeRequest("/threads", { query: requestQuery }),
"thread list response",
);
const threads = readCloudArray(response.threads, "threads");
return {
threads: threads.map((thread, index) =>
decodeCloudThread(thread, `threads[${index}]`),
),
};
}
public async get(threadId: string): Promise<CloudThread> {
const response = readCloudRecord(
await this.cloud.makeRequest(`/threads/${encodeURIComponent(threadId)}`),
"thread response",
);
return decodeCloudThread(response.thread, "thread");
}
public async create(
body: AssistantCloudThreadsCreateBody,
): Promise<AssistantCloudThreadsCreateResponse> {
const response = readCloudRecord(
await this.cloud.makeRequest("/threads", { method: "POST", body }),
"thread create response",
);
return { thread_id: readCloudString(response.thread_id, "thread_id") };
}
public async update(
threadId: string,
body: AssistantCloudThreadsUpdateBody,
): Promise<void> {
return this.cloud.makeRequest(`/threads/${encodeURIComponent(threadId)}`, {
method: "PUT",
body,
});
}
/** Moves every thread of the anonymous identity behind `refresh_token` into the caller's workspace. */
public async claim(
body: AssistantCloudThreadsClaimBody,
): Promise<AssistantCloudThreadsClaimResponse> {
const response = readCloudRecord(
await this.cloud.makeRequest("/threads/claim", { method: "POST", body }),
"thread claim response",
);
return { moved: readCloudInteger(response.moved, "moved") };
}
public async delete(threadId: string): Promise<void> {
return this.cloud.makeRequest(`/threads/${encodeURIComponent(threadId)}`, {
method: "DELETE",
});
}
}