Add Infer Property (#2452)

This commit is contained in:
Saket Aryan
2025-03-27 21:18:42 +05:30
committed by GitHub
parent 0eb53b9f27
commit bc4ab3db77
10 changed files with 202 additions and 349 deletions

View File

@@ -62,7 +62,7 @@ export default class MemoryClient {
(this.organizationName !== null && this.projectName === null)
) {
console.warn(
"Warning: Both organizationName and projectName must be provided together when using either. This will be removedfrom the version 1.0.40. Note that organizationName/projectName are being deprecated in favor of organizationId/projectId.",
"Warning: Both organizationName and projectName must be provided together when using either. This will be removed from version 1.0.40. Note that organizationName/projectName are being deprecated in favor of organizationId/projectId.",
);
}
@@ -72,7 +72,7 @@ export default class MemoryClient {
(this.organizationId !== null && this.projectId === null)
) {
console.warn(
"Warning: Both organizationId and projectId must be provided together when using either. This will be removedfrom the version 1.0.40.",
"Warning: Both organizationId and projectId must be provided together when using either. This will be removed from version 1.0.40.",
);
}
}
@@ -108,59 +108,42 @@ export default class MemoryClient {
private async _initializeClient() {
try {
// do this only in browser
if (typeof window !== "undefined") {
this.telemetryId = await generateHash(this.apiKey);
await captureClientEvent("init", this);
}
// Generate telemetry ID
this.telemetryId = generateHash(this.apiKey);
// Wrap methods after initialization
this.add = this.wrapMethod("add", this.add);
this.get = this.wrapMethod("get", this.get);
this.getAll = this.wrapMethod("get_all", this.getAll);
this.search = this.wrapMethod("search", this.search);
this.delete = this.wrapMethod("delete", this.delete);
this.deleteAll = this.wrapMethod("delete_all", this.deleteAll);
this.history = this.wrapMethod("history", this.history);
this.users = this.wrapMethod("users", this.users);
this.deleteUser = this.wrapMethod("delete_user", this.deleteUser);
this.deleteUsers = this.wrapMethod("delete_users", this.deleteUsers);
this.batchUpdate = this.wrapMethod("batch_update", this.batchUpdate);
this.batchDelete = this.wrapMethod("batch_delete", this.batchDelete);
this.getProject = this.wrapMethod("get_project", this.getProject);
this.updateProject = this.wrapMethod(
"update_project",
this.updateProject,
);
this.getWebhooks = this.wrapMethod("get_webhook", this.getWebhooks);
this.createWebhook = this.wrapMethod(
"create_webhook",
this.createWebhook,
);
this.updateWebhook = this.wrapMethod(
"update_webhook",
this.updateWebhook,
);
this.deleteWebhook = this.wrapMethod(
"delete_webhook",
this.deleteWebhook,
);
} catch (error) {
// Capture initialization event
await captureClientEvent("init", this, {
api_version: "v1",
client_type: "MemoryClient",
});
} catch (error: any) {
console.error("Failed to initialize client:", error);
await captureClientEvent("init_error", this, {
error: error?.message || "Unknown error",
stack: error?.stack || "No stack trace",
});
}
}
wrapMethod(methodName: any, method: any) {
return async function (...args: any) {
// @ts-ignore
await captureClientEvent(methodName, this);
// @ts-ignore
return method.apply(this, args);
}.bind(this);
private _captureEvent(methodName: string, args: any[]) {
captureClientEvent(methodName, this, {
success: true,
args_count: args.length,
keys: args.length > 0 ? args[0] : [],
}).catch((error: any) => {
console.error("Failed to capture event:", error);
});
}
async _fetchWithErrorHandling(url: string, options: any): Promise<any> {
const response = await fetch(url, options);
const response = await fetch(url, {
...options,
headers: {
...options.headers,
Authorization: `Token ${this.apiKey}`,
"Mem0-User-ID": this.telemetryId,
},
});
if (!response.ok) {
const errorData = await response.text();
throw new APIError(`API request failed: ${errorData}`);
@@ -211,6 +194,11 @@ export default class MemoryClient {
}
const payload = this._preparePayload(messages, options);
// get payload keys whose value is not null or undefined
const payloadKeys = Object.keys(payload);
this._captureEvent("add", [payloadKeys]);
const response = await this._fetchWithErrorHandling(
`${this.host}/v1/memories/`,
{
@@ -227,6 +215,10 @@ export default class MemoryClient {
const payload = {
text: message,
};
const payloadKeys = Object.keys(payload);
this._captureEvent("update", [payloadKeys]);
const response = await this._fetchWithErrorHandling(
`${this.host}/v1/memories/${memoryId}/`,
{
@@ -239,6 +231,7 @@ export default class MemoryClient {
}
async get(memoryId: string): Promise<Memory> {
this._captureEvent("get", []);
return this._fetchWithErrorHandling(
`${this.host}/v1/memories/${memoryId}/`,
{
@@ -249,6 +242,8 @@ export default class MemoryClient {
async getAll(options?: SearchOptions): Promise<Array<Memory>> {
this._validateOrgProject();
const payloadKeys = Object.keys(options || {});
this._captureEvent("get_all", [payloadKeys]);
const { api_version, page, page_size, ...otherOptions } = options!;
if (this.organizationName != null && this.projectName != null) {
otherOptions.org_name = this.organizationName;
@@ -294,6 +289,8 @@ export default class MemoryClient {
async search(query: string, options?: SearchOptions): Promise<Array<Memory>> {
this._validateOrgProject();
const payloadKeys = Object.keys(options || {});
this._captureEvent("search", [payloadKeys]);
const { api_version, ...otherOptions } = options!;
const payload = { query, ...otherOptions };
if (this.organizationName != null && this.projectName != null) {
@@ -322,6 +319,7 @@ export default class MemoryClient {
}
async delete(memoryId: string): Promise<{ message: string }> {
this._captureEvent("delete", []);
return this._fetchWithErrorHandling(
`${this.host}/v1/memories/${memoryId}/`,
{
@@ -333,6 +331,8 @@ export default class MemoryClient {
async deleteAll(options: MemoryOptions = {}): Promise<{ message: string }> {
this._validateOrgProject();
const payloadKeys = Object.keys(options || {});
this._captureEvent("delete_all", [payloadKeys]);
if (this.organizationName != null && this.projectName != null) {
options.org_name = this.organizationName;
options.project_name = this.projectName;
@@ -358,6 +358,7 @@ export default class MemoryClient {
}
async history(memoryId: string): Promise<Array<MemoryHistory>> {
this._captureEvent("history", []);
const response = await this._fetchWithErrorHandling(
`${this.host}/v1/memories/${memoryId}/history/`,
{
@@ -369,6 +370,7 @@ export default class MemoryClient {
async users(): Promise<AllUsers> {
this._validateOrgProject();
this._captureEvent("users", []);
const options: MemoryOptions = {};
if (this.organizationName != null && this.projectName != null) {
options.org_name = this.organizationName;
@@ -397,6 +399,7 @@ export default class MemoryClient {
entityId: string,
entity: { type: string } = { type: "user" },
): Promise<{ message: string }> {
this._captureEvent("delete_user", []);
const response = await this._fetchWithErrorHandling(
`${this.host}/v1/entities/${entity.type}/${entityId}/`,
{
@@ -409,6 +412,7 @@ export default class MemoryClient {
async deleteUsers(): Promise<{ message: string }> {
this._validateOrgProject();
this._captureEvent("delete_users", []);
const entities = await this.users();
for (const entity of entities.results) {
@@ -433,6 +437,7 @@ export default class MemoryClient {
}
async batchUpdate(memories: Array<MemoryUpdateBody>): Promise<string> {
this._captureEvent("batch_update", []);
const memoriesBody = memories.map((memory) => ({
memory_id: memory.memoryId,
text: memory.text,
@@ -449,6 +454,7 @@ export default class MemoryClient {
}
async batchDelete(memories: Array<string>): Promise<string> {
this._captureEvent("batch_delete", []);
const memoriesBody = memories.map((memory) => ({
memory_id: memory,
}));
@@ -465,7 +471,8 @@ export default class MemoryClient {
async getProject(options: ProjectOptions): Promise<ProjectResponse> {
this._validateOrgProject();
const payloadKeys = Object.keys(options || {});
this._captureEvent("get_project", [payloadKeys]);
const { fields } = options;
if (!(this.organizationId && this.projectId)) {
@@ -490,7 +497,7 @@ export default class MemoryClient {
prompts: PromptUpdatePayload,
): Promise<Record<string, any>> {
this._validateOrgProject();
this._captureEvent("update_project", []);
if (!(this.organizationId && this.projectId)) {
throw new Error(
"organizationId and projectId must be set to update instructions or categories",
@@ -510,6 +517,7 @@ export default class MemoryClient {
// WebHooks
async getWebhooks(data?: { projectId?: string }): Promise<Array<Webhook>> {
this._captureEvent("get_webhooks", []);
const project_id = data?.projectId || this.projectId;
const response = await this._fetchWithErrorHandling(
`${this.host}/api/v1/webhooks/projects/${project_id}/`,
@@ -521,6 +529,7 @@ export default class MemoryClient {
}
async createWebhook(webhook: WebhookPayload): Promise<Webhook> {
this._captureEvent("create_webhook", []);
const response = await this._fetchWithErrorHandling(
`${this.host}/api/v1/webhooks/projects/${this.projectId}/`,
{
@@ -533,6 +542,7 @@ export default class MemoryClient {
}
async updateWebhook(webhook: WebhookPayload): Promise<{ message: string }> {
this._captureEvent("update_webhook", []);
const project_id = webhook.projectId || this.projectId;
const response = await this._fetchWithErrorHandling(
`${this.host}/api/v1/webhooks/${webhook.webhookId}/`,
@@ -551,6 +561,7 @@ export default class MemoryClient {
async deleteWebhook(data: {
webhookId: string;
}): Promise<{ message: string }> {
this._captureEvent("delete_webhook", []);
const webhook_id = data.webhookId || data;
const response = await this._fetchWithErrorHandling(
`${this.host}/api/v1/webhooks/${webhook_id}/`,
@@ -563,6 +574,8 @@ export default class MemoryClient {
}
async feedback(data: FeedbackPayload): Promise<{ message: string }> {
const payloadKeys = Object.keys(data || {});
this._captureEvent("feedback", [payloadKeys]);
const response = await this._fetchWithErrorHandling(
`${this.host}/v1/feedback/`,
{