Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions runagent-ts/src/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -91,6 +97,8 @@ export class RunAgentClient {
private timeoutSeconds: number;
private extraParams?: Record<string, unknown>;
private enableRegistry: boolean;
private _userId?: string;
private _persistentMemory: boolean;

constructor(config: RunAgentConfig) {
this.serializer = new CoreSerializer();
Expand All @@ -105,6 +113,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 ?? parseEnvBool('RUNAGENT_PERSISTENT_MEMORY') ?? false;

if (!this.baseUrl && !this.local) {
this.baseUrl = DEFAULT_REMOTE_BASE_URL;
Expand Down Expand Up @@ -354,7 +364,9 @@ export class RunAgentClient {
inputArgs: [],
inputKwargs,
timeoutSeconds: this.timeoutSeconds,
}
},
this._userId,
this._persistentMemory
);

if (response.success !== false) {
Expand Down Expand Up @@ -405,7 +417,9 @@ export class RunAgentClient {
inputArgs: [],
inputKwargs,
timeoutSeconds: this.timeoutSeconds,
}
},
this._userId,
this._persistentMemory
);
}

Expand All @@ -429,6 +443,14 @@ export class RunAgentClient {
return this.extraParams;
}

getUserId(): string | undefined {
return this._userId;
}

getPersistentMemory(): boolean {
return this._persistentMemory;
}

/**
* Check if registry features are available.
*/
Expand Down
19 changes: 15 additions & 4 deletions runagent-ts/src/rest/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,28 +49,39 @@ export class RestClient {
async runAgent(
agentId: string,
entrypointTag: string,
options: RunAgentOptions = {}
options: RunAgentOptions = {},
userId?: string,
persistentMemory?: boolean
): Promise<ApiResponse> {
const {
inputArgs = [],
inputKwargs = {},
timeoutSeconds = this.defaultTimeoutSeconds,
} = options;

const requestData = {
const requestData: Record<string, unknown> = {
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 !== undefined) {
requestData.persistent_memory = persistentMemory;
}
Comment on lines +62 to +75
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use a nullish check for userId.

if (userId) drops an explicitly configured empty string, so the field can disappear even when the caller set it. Switching to a null/undefined check keeps the request body aligned with the stored config; please mirror the same behavior in websocket/base.ts so REST/WS stay consistent.

🔧 Proposed fix
-      if (userId) {
+      if (userId != null) {
         requestData.user_id = userId;
       }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const requestData: Record<string, unknown> = {
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 requestData: Record<string, unknown> = {
entrypoint_tag: entrypointTag,
input_args: inputArgs,
input_kwargs: inputKwargs,
timeout_seconds: timeoutSeconds,
async_execution: false,
};
if (userId != null) {
requestData.user_id = userId;
}
if (persistentMemory) {
requestData.persistent_memory = persistentMemory;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@runagent-ts/src/rest/index.ts` around lines 62 - 75, The REST handler builds
requestData and currently uses a truthy check (if (userId)) which drops
explicitly set empty strings; change that to a nullish check (if (userId !=
null)) so user_id is included when caller sets "" but excluded only when
null/undefined, and apply the same change pattern to the analogous logic in
websocket/base.ts to keep REST and WS behavior consistent; update the reference
to requestData.user_id and ensure any similar check for persistentMemory uses
the same nullish pattern if intended.


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 }
);

Expand Down
4 changes: 4 additions & 0 deletions runagent-ts/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export interface RunAgentConfig {
timeoutSeconds?: number;
extraParams?: Record<string, unknown>;
enableRegistry?: boolean;
userId?: string;
persistentMemory?: boolean;
}

export interface ApiResponse<T = JsonValue> {
Expand Down Expand Up @@ -61,6 +63,8 @@ export interface ExecutionRequest {
input_kwargs: Record<string, unknown>;
timeout_seconds?: number;
async_execution?: boolean;
user_id?: string;
persistent_memory?: boolean;
}

export interface SerializedObject {
Expand Down
11 changes: 10 additions & 1 deletion runagent-ts/src/websocket/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ export abstract class BaseWebSocketClient {
async *runStream(
agentId: string,
entrypointTag: string,
options: RunStreamOptions = {}
options: RunStreamOptions = {},
userId?: string,
persistentMemory?: boolean
): AsyncGenerator<unknown, void, unknown> {
const { inputArgs = null, inputKwargs = null, timeoutSeconds } = options;
const endpoint = `${this.baseSocketUrl}/agents/${agentId}/run-stream`;
Expand Down Expand Up @@ -87,6 +89,13 @@ export abstract class BaseWebSocketClient {
async_execution: false,
};

if (userId) {
request.user_id = userId;
}
if (persistentMemory !== undefined) {
request.persistent_memory = persistentMemory;
}

this.sendMessage(websocket, JSON.stringify(request));

yield* this.createWebSocketIterator(websocket);
Expand Down