fix(ts-sdk): await identity before building project-scoped URLs (#6802)
This commit is contained in:
@@ -81,6 +81,8 @@ class APIError extends Error {
|
||||
interface ClientOptions {
|
||||
apiKey: string;
|
||||
host?: string;
|
||||
/** Max cached identities per process. Defaults to 50. */
|
||||
identityCacheMax?: number;
|
||||
}
|
||||
|
||||
interface ClientIdentity {
|
||||
@@ -90,7 +92,7 @@ interface ClientIdentity {
|
||||
}
|
||||
|
||||
// Shares one ping per (host, api key) across clients; FIFO-capped.
|
||||
const IDENTITY_CACHE_MAX = 50;
|
||||
const IDENTITY_CACHE_MAX_DEFAULT = 50;
|
||||
const identityByCredentials = new Map<string, Promise<ClientIdentity>>();
|
||||
|
||||
export default class MemoryClient {
|
||||
@@ -102,6 +104,7 @@ export default class MemoryClient {
|
||||
client: any;
|
||||
telemetryId: string;
|
||||
private initialized: Promise<void>;
|
||||
private identityCacheMax: number;
|
||||
|
||||
_validateApiKey(): any {
|
||||
if (!this.apiKey) {
|
||||
@@ -120,6 +123,8 @@ export default class MemoryClient {
|
||||
this.host = options.host || "https://api.mem0.ai";
|
||||
this.organizationId = null;
|
||||
this.projectId = null;
|
||||
this.identityCacheMax =
|
||||
options.identityCacheMax ?? IDENTITY_CACHE_MAX_DEFAULT;
|
||||
|
||||
this.headers = {
|
||||
Authorization: `Token ${this.apiKey}`,
|
||||
@@ -136,7 +141,7 @@ export default class MemoryClient {
|
||||
|
||||
this.telemetryId = "";
|
||||
|
||||
// Requests never wait on this; only telemetry does.
|
||||
// Memory requests never wait on this; telemetry and _awaitIdentity do.
|
||||
this.initialized = this._resolveIdentity();
|
||||
}
|
||||
|
||||
@@ -146,7 +151,7 @@ export default class MemoryClient {
|
||||
let shared = identityByCredentials.get(credentials);
|
||||
if (!shared) {
|
||||
shared = this._initializeClient();
|
||||
if (identityByCredentials.size >= IDENTITY_CACHE_MAX) {
|
||||
if (identityByCredentials.size >= this.identityCacheMax) {
|
||||
identityByCredentials.delete(
|
||||
identityByCredentials.keys().next().value!,
|
||||
);
|
||||
@@ -165,6 +170,11 @@ export default class MemoryClient {
|
||||
});
|
||||
}
|
||||
|
||||
// Blocks until the ping has populated organizationId/projectId.
|
||||
private async _awaitIdentity(): Promise<void> {
|
||||
await this.initialized;
|
||||
}
|
||||
|
||||
private async _initializeClient(): Promise<ClientIdentity> {
|
||||
try {
|
||||
await this.ping();
|
||||
@@ -616,6 +626,7 @@ export default class MemoryClient {
|
||||
const payloadKeys = Object.keys(options || {});
|
||||
this._captureEvent("get_project", [payloadKeys]);
|
||||
const { fields } = options;
|
||||
await this._awaitIdentity();
|
||||
|
||||
if (!(this.organizationId && this.projectId)) {
|
||||
throw new Error(
|
||||
@@ -639,6 +650,7 @@ export default class MemoryClient {
|
||||
prompts: PromptUpdatePayload,
|
||||
): Promise<Record<string, any>> {
|
||||
this._captureEvent("update_project", []);
|
||||
await this._awaitIdentity();
|
||||
if (!(this.organizationId && this.projectId)) {
|
||||
throw new Error(
|
||||
"organizationId and projectId must be set to update instructions or categories",
|
||||
@@ -659,7 +671,11 @@ export default class MemoryClient {
|
||||
// WebHooks
|
||||
async getWebhooks(data?: { projectId?: string }): Promise<Array<Webhook>> {
|
||||
this._captureEvent("get_webhooks", []);
|
||||
if (!data?.projectId) await this._awaitIdentity();
|
||||
const project_id = data?.projectId || this.projectId;
|
||||
if (!project_id) {
|
||||
throw new Error("projectId must be set to access webhooks");
|
||||
}
|
||||
const response = await this._fetchWithErrorHandling(
|
||||
`${this.host}/api/v1/webhooks/projects/${project_id}/`,
|
||||
{
|
||||
@@ -671,6 +687,10 @@ export default class MemoryClient {
|
||||
|
||||
async createWebhook(webhook: WebhookCreatePayload): Promise<Webhook> {
|
||||
this._captureEvent("create_webhook", []);
|
||||
await this._awaitIdentity();
|
||||
if (!this.projectId) {
|
||||
throw new Error("projectId must be set to create a webhook");
|
||||
}
|
||||
const body = {
|
||||
name: webhook.name,
|
||||
url: webhook.url,
|
||||
|
||||
Reference in New Issue
Block a user