From 1a53cff36868cb002bd370a431a40e56bc4c5cdd Mon Sep 17 00:00:00 2001 From: sawradip Date: Fri, 1 May 2026 19:51:11 +0600 Subject: [PATCH 1/2] feat(ts): add persistent_memory and user_id support - Add userId and persistentMemory to RunAgentConfig interface - Add user_id and persistent_memory to ExecutionRequest interface - Store fields in RunAgentClient with env var fallback (RUNAGENT_USER_ID) - Add getUserId() and getPersistentMemory() getter methods - Conditionally include user_id and persistent_memory in REST request body - Conditionally include user_id and persistent_memory in WebSocket request payload Co-Authored-By: Claude Opus 4.6 --- runagent-ts/src/client/index.ts | 20 ++++++++++++++++++-- runagent-ts/src/rest/index.ts | 19 +++++++++++++++---- runagent-ts/src/types/index.ts | 4 ++++ runagent-ts/src/websocket/base.ts | 11 ++++++++++- 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/runagent-ts/src/client/index.ts b/runagent-ts/src/client/index.ts index a47664b..82cf39f 100644 --- a/runagent-ts/src/client/index.ts +++ b/runagent-ts/src/client/index.ts @@ -91,6 +91,8 @@ export class RunAgentClient { private timeoutSeconds: number; private extraParams?: Record; private enableRegistry: boolean; + private _userId?: string; + private _persistentMemory: boolean; constructor(config: RunAgentConfig) { this.serializer = new CoreSerializer(); @@ -105,6 +107,8 @@ export class RunAgentClient { this.apiKey = config.apiKey ?? getEnvVar(API_KEY_ENV); this.baseUrl = config.baseUrl ?? getEnvVar(BASE_URL_ENV); this.baseSocketUrl = config.baseSocketUrl; + this._userId = config.userId ?? getEnvVar('RUNAGENT_USER_ID'); + this._persistentMemory = config.persistentMemory ?? false; if (!this.baseUrl && !this.local) { this.baseUrl = DEFAULT_REMOTE_BASE_URL; @@ -354,7 +358,9 @@ export class RunAgentClient { inputArgs: [], inputKwargs, timeoutSeconds: this.timeoutSeconds, - } + }, + this._userId, + this._persistentMemory ); if (response.success !== false) { @@ -405,7 +411,9 @@ export class RunAgentClient { inputArgs: [], inputKwargs, timeoutSeconds: this.timeoutSeconds, - } + }, + this._userId, + this._persistentMemory ); } @@ -429,6 +437,14 @@ export class RunAgentClient { return this.extraParams; } + getUserId(): string | undefined { + return this._userId; + } + + getPersistentMemory(): boolean { + return this._persistentMemory; + } + /** * Check if registry features are available. */ diff --git a/runagent-ts/src/rest/index.ts b/runagent-ts/src/rest/index.ts index f9ce927..4088975 100644 --- a/runagent-ts/src/rest/index.ts +++ b/runagent-ts/src/rest/index.ts @@ -49,7 +49,9 @@ export class RestClient { async runAgent( agentId: string, entrypointTag: string, - options: RunAgentOptions = {} + options: RunAgentOptions = {}, + userId?: string, + persistentMemory?: boolean ): Promise { const { inputArgs = [], @@ -57,20 +59,29 @@ export class RestClient { timeoutSeconds = this.defaultTimeoutSeconds, } = options; - const requestData = { + const requestData: Record = { entrypoint_tag: entrypointTag, input_args: inputArgs, input_kwargs: inputKwargs, timeout_seconds: timeoutSeconds, async_execution: false, - } as JsonValue; + }; + + if (userId) { + requestData.user_id = userId; + } + if (persistentMemory) { + requestData.persistent_memory = persistentMemory; + } + + const typedRequestData = requestData as JsonValue; const timeoutMs = timeoutSeconds * 1000 + 10_000; // Add buffer similar to Python SDK try { const response = await this.http.post( `/agents/${agentId}/run`, - requestData, + typedRequestData, { timeout: timeoutMs } ); diff --git a/runagent-ts/src/types/index.ts b/runagent-ts/src/types/index.ts index a139c3e..d069e48 100644 --- a/runagent-ts/src/types/index.ts +++ b/runagent-ts/src/types/index.ts @@ -11,6 +11,8 @@ export interface RunAgentConfig { timeoutSeconds?: number; extraParams?: Record; enableRegistry?: boolean; + userId?: string; + persistentMemory?: boolean; } export interface ApiResponse { @@ -61,6 +63,8 @@ export interface ExecutionRequest { input_kwargs: Record; timeout_seconds?: number; async_execution?: boolean; + user_id?: string; + persistent_memory?: boolean; } export interface SerializedObject { diff --git a/runagent-ts/src/websocket/base.ts b/runagent-ts/src/websocket/base.ts index bbda23f..be885fe 100644 --- a/runagent-ts/src/websocket/base.ts +++ b/runagent-ts/src/websocket/base.ts @@ -57,7 +57,9 @@ export abstract class BaseWebSocketClient { async *runStream( agentId: string, entrypointTag: string, - options: RunStreamOptions = {} + options: RunStreamOptions = {}, + userId?: string, + persistentMemory?: boolean ): AsyncGenerator { const { inputArgs = null, inputKwargs = null, timeoutSeconds } = options; const endpoint = `${this.baseSocketUrl}/agents/${agentId}/run-stream`; @@ -87,6 +89,13 @@ export abstract class BaseWebSocketClient { async_execution: false, }; + if (userId) { + request.user_id = userId; + } + if (persistentMemory) { + request.persistent_memory = persistentMemory; + } + this.sendMessage(websocket, JSON.stringify(request)); yield* this.createWebSocketIterator(websocket); From 38e9b979411242d32f749a328342fdda6959a989 Mon Sep 17 00:00:00 2001 From: sawradip Date: Sat, 2 May 2026 10:09:28 +0600 Subject: [PATCH 2/2] fix(ts): use !== undefined guard for persistent_memory, add env var support - Fix: use `persistentMemory !== undefined` instead of `if (persistentMemory)` so `false` can be sent over the wire (REST + WebSocket) - Add RUNAGENT_PERSISTENT_MEMORY env var support with parseEnvBool helper, matching the Go SDK reference implementation Co-Authored-By: Claude Opus 4.6 --- runagent-ts/src/client/index.ts | 8 +++++++- runagent-ts/src/rest/index.ts | 2 +- runagent-ts/src/websocket/base.ts | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/runagent-ts/src/client/index.ts b/runagent-ts/src/client/index.ts index 82cf39f..2afc1bb 100644 --- a/runagent-ts/src/client/index.ts +++ b/runagent-ts/src/client/index.ts @@ -73,6 +73,12 @@ const getEnvVar = (name: string): string | undefined => { return undefined; }; +const parseEnvBool = (name: string): boolean | undefined => { + const val = getEnvVar(name); + if (val === undefined) return undefined; + return val.toLowerCase() === 'true' || val === '1'; +}; + export class RunAgentClient { private serializer: CoreSerializer; private local: boolean; @@ -108,7 +114,7 @@ export class RunAgentClient { this.baseUrl = config.baseUrl ?? getEnvVar(BASE_URL_ENV); this.baseSocketUrl = config.baseSocketUrl; this._userId = config.userId ?? getEnvVar('RUNAGENT_USER_ID'); - this._persistentMemory = config.persistentMemory ?? false; + this._persistentMemory = config.persistentMemory ?? parseEnvBool('RUNAGENT_PERSISTENT_MEMORY') ?? false; if (!this.baseUrl && !this.local) { this.baseUrl = DEFAULT_REMOTE_BASE_URL; diff --git a/runagent-ts/src/rest/index.ts b/runagent-ts/src/rest/index.ts index 4088975..62c201e 100644 --- a/runagent-ts/src/rest/index.ts +++ b/runagent-ts/src/rest/index.ts @@ -70,7 +70,7 @@ export class RestClient { if (userId) { requestData.user_id = userId; } - if (persistentMemory) { + if (persistentMemory !== undefined) { requestData.persistent_memory = persistentMemory; } diff --git a/runagent-ts/src/websocket/base.ts b/runagent-ts/src/websocket/base.ts index be885fe..1f7ddd3 100644 --- a/runagent-ts/src/websocket/base.ts +++ b/runagent-ts/src/websocket/base.ts @@ -92,7 +92,7 @@ export abstract class BaseWebSocketClient { if (userId) { request.user_id = userId; } - if (persistentMemory) { + if (persistentMemory !== undefined) { request.persistent_memory = persistentMemory; }