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
6 changes: 3 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Changelog
All notable changes to this project's latest version.

## [0.1.28] - 2025-11-13
## [0.1.29] - 2025-11-13

### Miscellaneous Tasks

- Update GitHub Actions permissions for release jobs
- Bump version to v0.1.28
- Update TypeScript release workflow to enhance security
- Bump version to v0.1.29

<!-- generated by git-cliff -->
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ build-backend = "hatchling.build"

[project]
name = "runagent"
version = "0.1.29"
version = "0.1.30"
description = "A command-line tool and SDK for deploying, managing, and interacting with AI agents"
readme = "README.md"
requires-python = ">=3.9"
Expand Down Expand Up @@ -103,7 +103,7 @@ line_length = 88
skip = ["docs"]

[tool.mypy]
python_version = "0.1.29"
python_version = "0.1.30"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
Expand Down Expand Up @@ -159,7 +159,7 @@ fail_under = 80

[tool.ruff]
line-length = 88
target-version = "0.1.29"
target-version = "0.1.30"
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
Expand Down
2 changes: 1 addition & 1 deletion runagent-go/runagent/version.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package runagent

// Version represents the current version of the RunAgent Go SDK
const Version = "0.1.29"
const Version = "0.1.30"
2 changes: 1 addition & 1 deletion runagent-rust/runagent/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "runagent"
version = "0.1.29"
version = "0.1.30"
edition = "2021"
description = "RunAgent SDK for Rust - Client SDK for interacting with deployed AI agents"
license = "MIT"
Expand Down
19 changes: 17 additions & 2 deletions runagent-ts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ For browser builds, you can expose these via bundler secrets or a custom `global
### 1. Remote agent

```ts
import { RunAgentClient } from 'runagent';
import { RunAgentClient, RunAgentExecutionError } from 'runagent';

const client = new RunAgentClient({
agentId: 'agent-id-from-dashboard',
Expand All @@ -77,7 +77,7 @@ console.log(result);
### 2. Remote streaming

```ts
import { RunAgentClient } from 'runagent';
import { RunAgentClient, RunAgentExecutionError } from 'runagent';

const client = new RunAgentClient({
agentId: 'agent-id-from-dashboard',
Expand Down Expand Up @@ -180,6 +180,21 @@ for await (const chunk of client.runStream({ message: 'Need help' })) {
- `getExtraParams(): Record<string, unknown> | undefined`
Returns any metadata passed in `extraParams`. Reserved for forward compatibility.

- **Errors**
Both `run()` and `runStream()` throw `RunAgentExecutionError` when the agent reports a failure (or when the transport breaks). Inspect `error.code`, `error.message`, and `error.suggestion` to deliver actionable feedback:

```ts
try {
const result = await client.run({ prompt: '...' });
} catch (error) {
if (error instanceof RunAgentExecutionError) {
console.error(error.code, error.message, error.suggestion);
} else {
throw error;
}
}
```

### Constructor precedence rules

1. Explicit constructor values.
Expand Down
4 changes: 2 additions & 2 deletions runagent-ts/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion runagent-ts/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "runagent",
"version": "0.1.29",
"version": "0.1.30",
"type": "module",
"files": [
"dist"
Expand Down
63 changes: 51 additions & 12 deletions runagent-ts/src/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ import type {
RunAgentConfig,
AgentArchitecture,
JsonValue,
ApiResponse,
} from '../types/index.js';
import type { RunAgentRegistry } from '../database/index.js';
import { RunAgentExecutionError } from '../errors/index.js';

type WebSocketClientType = BrowserWebSocketClient | NodeWebSocketClient;

Expand Down Expand Up @@ -242,9 +244,10 @@ export class RunAgentClient {
}

if (!host || !port) {
throw new Error(
`Unable to determine host/port for local agent ${this.agentId}. ` +
`Provide 'host' and 'port' in RunAgentClient config or register the agent locally.`
throw new RunAgentExecutionError(
'AGENT_ADDRESS_NOT_FOUND',
`Unable to determine host/port for local agent ${this.agentId}`,
"Provide 'host' and 'port' in RunAgentClient config or register the agent locally."
);
}

Expand Down Expand Up @@ -288,7 +291,8 @@ export class RunAgentClient {
await this.ensureInitialized();

if (this.entrypointTag.endsWith('_stream')) {
throw new Error(
throw new RunAgentExecutionError(
'STREAM_ENTRYPOINT',
`Entrypoint \`${this.entrypointTag}\` is streaming. Use runStream() instead.`
);
}
Expand All @@ -302,7 +306,8 @@ export class RunAgentClient {
await this.ensureInitialized();

if (!this.entrypointTag.endsWith('_stream')) {
throw new Error(
throw new RunAgentExecutionError(
'NON_STREAM_ENTRYPOINT',
`Entrypoint \`${this.entrypointTag}\` is not streaming. Use run() instead.`
);
}
Expand Down Expand Up @@ -358,13 +363,11 @@ export class RunAgentClient {
return payload ?? null;
}

const errorMessage =
typeof response.error === 'string'
? response.error
: (response.error as { message?: string })?.message ??
'Agent execution failed';

throw new Error(errorMessage);
throw this.buildExecutionError(
response.error,
response.message,
'EXECUTION_ERROR'
);
}

private executeStream(
Expand Down Expand Up @@ -424,4 +427,40 @@ export class RunAgentClient {
static async getRegistryInstance(): Promise<RunAgentRegistry | null> {
return await this.getRegistry(true);
}

private buildExecutionError(
errorInfo: ApiResponse['error'],
fallbackMessage?: string | null,
defaultCode = 'UNKNOWN_ERROR'
): RunAgentExecutionError {
const fallback = this.sanitizeMessage(fallbackMessage) ?? 'Unknown error';

if (!errorInfo) {
return new RunAgentExecutionError(defaultCode, fallback);
}

if (typeof errorInfo === 'string') {
return new RunAgentExecutionError(
defaultCode,
this.sanitizeMessage(errorInfo) ?? fallback
);
}

const { code, message, suggestion, details } = errorInfo;
const normalizedMessage =
this.sanitizeMessage(message) ?? fallback;

return new RunAgentExecutionError(
code ?? defaultCode,
normalizedMessage,
suggestion,
details
);
}

private sanitizeMessage(value?: string | null): string | undefined {
if (!value) return undefined;
const trimmed = value.trim();
return trimmed.length > 0 ? trimmed : undefined;
}
}
21 changes: 20 additions & 1 deletion runagent-ts/src/errors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,23 @@ export class HttpException extends Error {
super(message, statusCode, response);
this.name = 'ConnectionError';
}
}
}

export class RunAgentExecutionError extends Error {
public code: string;
public suggestion?: string | null;
public details?: unknown;

constructor(
code: string,
message: string,
suggestion?: string | null,
details?: unknown
) {
super(message || 'Unknown error');
this.name = 'RunAgentExecutionError';
this.code = code || 'UNKNOWN_ERROR';
this.suggestion = suggestion;
this.details = details;
}
}
12 changes: 12 additions & 0 deletions runagent-ts/src/rest/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ export class RestClient {
error: {
code,
message: errorMessage,
suggestion:
code === 'PERMISSION_ERROR'
? 'Verify the agent ID and ensure your API key has access to this agent.'
: 'Check that RUNAGENT_API_KEY is set correctly and has not expired.',
},
};
}
Expand All @@ -94,6 +98,8 @@ export class RestClient {
error: {
code: 'VALIDATION_ERROR',
message: errorMessage,
suggestion:
'Inspect the input arguments and ensure they match the agent entrypoint schema.',
},
};
}
Expand All @@ -104,6 +110,8 @@ export class RestClient {
error: {
code: 'CONNECTION_ERROR',
message: errorMessage,
suggestion:
'Check your network connection and confirm the RunAgent service URL is reachable.',
},
};
}
Expand All @@ -114,6 +122,7 @@ export class RestClient {
error: {
code: 'SERVER_ERROR',
message: errorMessage,
suggestion: 'Try the request again. If the issue persists, contact RunAgent support.',
},
};
}
Expand All @@ -124,6 +133,8 @@ export class RestClient {
error: {
code: 'CLIENT_ERROR',
message: errorMessage,
suggestion:
'Review the request payload or configuration for potential mistakes.',
},
};
}
Expand All @@ -133,6 +144,7 @@ export class RestClient {
error: {
code: 'UNKNOWN_ERROR',
message: errorMessage,
suggestion: 'Retry the request or inspect the agent logs for more detail.',
},
};
}
Expand Down
1 change: 1 addition & 0 deletions runagent-ts/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export interface ApiResponse<T = JsonValue> {
| {
code?: string;
message?: string;
suggestion?: string | null;
details?: unknown;
field?: string | null;
};
Expand Down
Loading
Loading