@phaseo/agent-sdk 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +219 -0
- package/README.md +309 -2
- package/SKILL.md +24 -0
- package/dist/adapters/gateway-client.d.ts +24 -0
- package/dist/adapters/gateway-client.js +179 -0
- package/dist/agent.d.ts +7 -0
- package/dist/agent.js +11 -0
- package/dist/devtools.d.ts +26 -0
- package/dist/devtools.js +102 -0
- package/dist/errors.d.ts +60 -0
- package/dist/errors.js +161 -0
- package/dist/index.d.ts +8 -1
- package/dist/index.js +4 -1
- package/dist/runtime/loop.d.ts +3 -0
- package/dist/runtime/loop.js +1070 -0
- package/dist/types.d.ts +215 -0
- package/dist/types.js +1 -0
- package/examples/coding-review-agent.ts +108 -0
- package/examples/parallel-tool-agent.ts +60 -0
- package/examples/research-brief-agent.ts +70 -0
- package/examples/support-triage-agent.ts +104 -0
- package/package.json +24 -6
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import Phaseo, {} from "@phaseo/sdk";
|
|
2
|
+
import { AgentGatewayError } from "../errors.js";
|
|
3
|
+
function coerceTextContent(content) {
|
|
4
|
+
return typeof content === "string" ? content : String(content ?? "");
|
|
5
|
+
}
|
|
6
|
+
function toPresetModelAlias(preset) {
|
|
7
|
+
if (typeof preset !== "string")
|
|
8
|
+
return undefined;
|
|
9
|
+
const normalized = preset.trim().replace(/^@+/, "");
|
|
10
|
+
return normalized.length > 0 ? `@${normalized}` : undefined;
|
|
11
|
+
}
|
|
12
|
+
function toResponsesInput(messages) {
|
|
13
|
+
return messages.flatMap((message) => {
|
|
14
|
+
if (message.role === "system")
|
|
15
|
+
return [];
|
|
16
|
+
if (message.role === "tool") {
|
|
17
|
+
return [{
|
|
18
|
+
type: "function_call_output",
|
|
19
|
+
call_id: message.toolCallId,
|
|
20
|
+
output: coerceTextContent(message.content),
|
|
21
|
+
}];
|
|
22
|
+
}
|
|
23
|
+
const baseMessage = {
|
|
24
|
+
type: "message",
|
|
25
|
+
role: message.role,
|
|
26
|
+
content: coerceTextContent(message.content),
|
|
27
|
+
};
|
|
28
|
+
if (message.role === "assistant" &&
|
|
29
|
+
Array.isArray(message.toolCalls) &&
|
|
30
|
+
message.toolCalls.length > 0) {
|
|
31
|
+
baseMessage.tool_calls = message.toolCalls.map((toolCall) => ({
|
|
32
|
+
id: toolCall.id,
|
|
33
|
+
type: "function",
|
|
34
|
+
function: {
|
|
35
|
+
name: toolCall.name,
|
|
36
|
+
arguments: JSON.stringify(toolCall.input ?? {}),
|
|
37
|
+
},
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
return [baseMessage];
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function toInstructions(messages, override) {
|
|
44
|
+
const systemText = messages
|
|
45
|
+
.filter((message) => message.role === "system")
|
|
46
|
+
.map((message) => coerceTextContent(message.content))
|
|
47
|
+
.filter((value) => value.trim().length > 0)
|
|
48
|
+
.join("\n\n");
|
|
49
|
+
if (override && systemText)
|
|
50
|
+
return `${override}\n\n${systemText}`;
|
|
51
|
+
return (override ?? systemText) || undefined;
|
|
52
|
+
}
|
|
53
|
+
function buildFunctionTools(request) {
|
|
54
|
+
return request.tools.map((tool) => ({
|
|
55
|
+
type: "function",
|
|
56
|
+
function: {
|
|
57
|
+
name: tool.id,
|
|
58
|
+
description: tool.description,
|
|
59
|
+
parameters: tool.parameters && typeof tool.parameters === "object"
|
|
60
|
+
? tool.parameters
|
|
61
|
+
: {
|
|
62
|
+
type: "object",
|
|
63
|
+
additionalProperties: true,
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
function buildRequestTools(request, extraTools) {
|
|
69
|
+
const functionTools = buildFunctionTools(request);
|
|
70
|
+
const nativeTools = Array.isArray(extraTools) ? extraTools : [];
|
|
71
|
+
const mergedTools = [...functionTools, ...nativeTools];
|
|
72
|
+
return mergedTools.length > 0 ? mergedTools : undefined;
|
|
73
|
+
}
|
|
74
|
+
function safeParseToolInput(raw) {
|
|
75
|
+
if (!raw)
|
|
76
|
+
return {};
|
|
77
|
+
try {
|
|
78
|
+
return JSON.parse(raw);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return { raw };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function extractToolCalls(response) {
|
|
85
|
+
const items = Array.isArray(response.output_items)
|
|
86
|
+
? response.output_items
|
|
87
|
+
: Array.isArray(response.output)
|
|
88
|
+
? response.output
|
|
89
|
+
: [];
|
|
90
|
+
const toolCalls = items
|
|
91
|
+
.filter((item) => String(item?.type ?? "").toLowerCase() === "function_call")
|
|
92
|
+
.map((item, index) => ({
|
|
93
|
+
id: item.call_id ?? `tool_call_${index}`,
|
|
94
|
+
name: item.name ?? "tool",
|
|
95
|
+
input: safeParseToolInput(item.arguments),
|
|
96
|
+
}));
|
|
97
|
+
return toolCalls.length > 0 ? toolCalls : undefined;
|
|
98
|
+
}
|
|
99
|
+
function extractAssistantText(response) {
|
|
100
|
+
const items = Array.isArray(response.output_items)
|
|
101
|
+
? response.output_items
|
|
102
|
+
: Array.isArray(response.output)
|
|
103
|
+
? response.output
|
|
104
|
+
: [];
|
|
105
|
+
const textParts = [];
|
|
106
|
+
for (const item of items) {
|
|
107
|
+
if (String(item?.type ?? "").toLowerCase() !== "message")
|
|
108
|
+
continue;
|
|
109
|
+
const content = Array.isArray(item.content) ? item.content : [];
|
|
110
|
+
for (const part of content) {
|
|
111
|
+
if (String(part?.type ?? "").toLowerCase() === "output_text" && typeof part.text === "string") {
|
|
112
|
+
textParts.push(part.text);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return textParts.join("\n\n");
|
|
117
|
+
}
|
|
118
|
+
function isAsyncIterableResponse(value) {
|
|
119
|
+
return Symbol.asyncIterator in Object(value);
|
|
120
|
+
}
|
|
121
|
+
function extractResponseMeta(response) {
|
|
122
|
+
const meta = response.meta;
|
|
123
|
+
if (!meta || typeof meta !== "object" || Array.isArray(meta))
|
|
124
|
+
return undefined;
|
|
125
|
+
return meta;
|
|
126
|
+
}
|
|
127
|
+
export function createGatewayAgentClient(options = {}) {
|
|
128
|
+
const client = options.client ?? new Phaseo(options.clientOptions ?? {});
|
|
129
|
+
return {
|
|
130
|
+
async generate(request) {
|
|
131
|
+
let response;
|
|
132
|
+
try {
|
|
133
|
+
const requestPayload = {
|
|
134
|
+
model: request.model ??
|
|
135
|
+
options.model ??
|
|
136
|
+
toPresetModelAlias(options.preset) ??
|
|
137
|
+
"phaseo/free",
|
|
138
|
+
input: toResponsesInput(request.messages),
|
|
139
|
+
instructions: toInstructions(request.messages, request.instructions),
|
|
140
|
+
tools: buildRequestTools(request, options.gatewayTools),
|
|
141
|
+
tool_choice: options.toolChoice,
|
|
142
|
+
parallel_tool_calls: options.parallelToolCalls,
|
|
143
|
+
temperature: options.temperature,
|
|
144
|
+
max_output_tokens: options.maxOutputTokens,
|
|
145
|
+
provider: options.provider,
|
|
146
|
+
reasoning: options.reasoning,
|
|
147
|
+
metadata: options.metadata,
|
|
148
|
+
meta: options.includeMeta,
|
|
149
|
+
user: options.user,
|
|
150
|
+
response_format: options.responseFormat,
|
|
151
|
+
web_search_options: options.webSearchOptions,
|
|
152
|
+
plugins: options.plugins,
|
|
153
|
+
provider_options: options.providerOptions,
|
|
154
|
+
prompt_cache_key: options.promptCacheKey,
|
|
155
|
+
};
|
|
156
|
+
response = await client.responses.create(requestPayload);
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
throw AgentGatewayError.fromUnknown(error) ?? error;
|
|
160
|
+
}
|
|
161
|
+
if (isAsyncIterableResponse(response)) {
|
|
162
|
+
throw new Error("Streaming agent client responses are not supported in the basic gateway adapter");
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
message: {
|
|
166
|
+
role: "assistant",
|
|
167
|
+
content: extractAssistantText(response),
|
|
168
|
+
toolCalls: extractToolCalls(response),
|
|
169
|
+
},
|
|
170
|
+
usage: response.usage,
|
|
171
|
+
requestId: response.id,
|
|
172
|
+
nativeResponseId: response.nativeResponseId ?? null,
|
|
173
|
+
provider: response.provider,
|
|
174
|
+
model: response.model,
|
|
175
|
+
responseMeta: extractResponseMeta(response),
|
|
176
|
+
};
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
}
|
package/dist/agent.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AgentContinueOptions, AgentDefinition, AgentRunOptions, AgentTool } from "./types.js";
|
|
2
|
+
export declare function defineTool<TInput = unknown, TOutput = unknown, TContext = unknown>(tool: AgentTool<TInput, TOutput, TContext>): AgentTool<TInput, TOutput, TContext>;
|
|
3
|
+
export declare function createAgent<TInput = unknown, TOutput = string, TContext = unknown>(definition: AgentDefinition<TInput, TOutput, TContext>): {
|
|
4
|
+
definition: AgentDefinition<TInput, TOutput, TContext>;
|
|
5
|
+
run: (options: AgentRunOptions<TInput, TContext>) => Promise<import("./types.js").AgentRunResult<TOutput, TInput, TContext>>;
|
|
6
|
+
continueRun: (options: AgentContinueOptions<TInput, TOutput, TContext>) => Promise<import("./types.js").AgentRunResult<TOutput, TInput, TContext>>;
|
|
7
|
+
};
|
package/dist/agent.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { continueAgent, runAgent, } from "./runtime/loop.js";
|
|
2
|
+
export function defineTool(tool) {
|
|
3
|
+
return tool;
|
|
4
|
+
}
|
|
5
|
+
export function createAgent(definition) {
|
|
6
|
+
return {
|
|
7
|
+
definition,
|
|
8
|
+
run: (options) => runAgent(definition, options),
|
|
9
|
+
continueRun: (options) => continueAgent(definition, options),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { AgentDefinition, AgentRunResult } from "./types.js";
|
|
2
|
+
export type AgentDevtoolsConfig = {
|
|
3
|
+
enabled?: boolean;
|
|
4
|
+
directory?: string;
|
|
5
|
+
flushIntervalMs?: number;
|
|
6
|
+
maxQueueSize?: number;
|
|
7
|
+
captureHeaders?: boolean;
|
|
8
|
+
saveAssets?: boolean;
|
|
9
|
+
};
|
|
10
|
+
export declare function createAgentDevtools(options?: AgentDevtoolsConfig): Partial<AgentDevtoolsConfig>;
|
|
11
|
+
export declare function captureAgentRunDevtools<TInput, TOutput, TContext>(args: {
|
|
12
|
+
type: "agent.run" | "agent.continue";
|
|
13
|
+
definition: AgentDefinition<TInput, TOutput, TContext>;
|
|
14
|
+
options: {
|
|
15
|
+
input?: TInput;
|
|
16
|
+
context?: TContext;
|
|
17
|
+
model?: string;
|
|
18
|
+
preset?: string;
|
|
19
|
+
maxSteps?: number;
|
|
20
|
+
devtools?: Partial<AgentDevtoolsConfig>;
|
|
21
|
+
};
|
|
22
|
+
startedAt: number;
|
|
23
|
+
result?: AgentRunResult<TOutput, TInput, TContext>;
|
|
24
|
+
error?: unknown;
|
|
25
|
+
runId?: string;
|
|
26
|
+
}): void;
|
package/dist/devtools.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
const AGENT_SDK_VERSION = "0.1.2";
|
|
5
|
+
const DEFAULT_DEVTOOLS_DIR = ".phaseo-devtools";
|
|
6
|
+
export function createAgentDevtools(options = {}) {
|
|
7
|
+
return {
|
|
8
|
+
enabled: true,
|
|
9
|
+
...options,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function captureAgentRunDevtools(args) {
|
|
13
|
+
const config = resolveDevtoolsConfig(args.options.devtools);
|
|
14
|
+
if (!config.enabled)
|
|
15
|
+
return;
|
|
16
|
+
const latestStep = findLatestStep(args.result?.steps);
|
|
17
|
+
const entry = {
|
|
18
|
+
id: args.result?.run.id ?? args.runId ?? randomUUID(),
|
|
19
|
+
type: args.type,
|
|
20
|
+
timestamp: args.startedAt,
|
|
21
|
+
duration_ms: Date.now() - args.startedAt,
|
|
22
|
+
request: {
|
|
23
|
+
agent_id: args.definition.id,
|
|
24
|
+
input: args.options.input,
|
|
25
|
+
context: args.options.context,
|
|
26
|
+
model: args.options.model ?? args.definition.model,
|
|
27
|
+
preset: args.options.preset ?? args.definition.preset,
|
|
28
|
+
max_steps: args.options.maxSteps ?? args.definition.maxSteps,
|
|
29
|
+
tool_count: args.definition.tools?.length ?? 0,
|
|
30
|
+
},
|
|
31
|
+
response: args.result
|
|
32
|
+
? {
|
|
33
|
+
run: args.result.run,
|
|
34
|
+
steps: args.result.steps,
|
|
35
|
+
output: args.result.output,
|
|
36
|
+
messages: args.result.messages,
|
|
37
|
+
}
|
|
38
|
+
: null,
|
|
39
|
+
error: args.error ? toDevtoolsError(args.error) : null,
|
|
40
|
+
metadata: {
|
|
41
|
+
sdk: "typescript",
|
|
42
|
+
sdk_version: AGENT_SDK_VERSION,
|
|
43
|
+
stream: false,
|
|
44
|
+
model: latestStep?.model,
|
|
45
|
+
provider: latestStep?.provider,
|
|
46
|
+
request_id: latestStep?.requestId,
|
|
47
|
+
native_response_id: latestStep?.nativeResponseId ?? undefined,
|
|
48
|
+
agent_id: args.definition.id,
|
|
49
|
+
run_id: args.result?.run.id ?? args.runId,
|
|
50
|
+
run_status: args.result?.run.status,
|
|
51
|
+
step_count: args.result?.steps.length,
|
|
52
|
+
tool_count: countToolCalls(args.result?.steps),
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
writeDevtoolsEntry(config.directory, entry);
|
|
56
|
+
}
|
|
57
|
+
function resolveDevtoolsConfig(config) {
|
|
58
|
+
const enabled = typeof config?.enabled === "boolean"
|
|
59
|
+
? config.enabled
|
|
60
|
+
: process.env.PHASEO_DEVTOOLS === "true";
|
|
61
|
+
return {
|
|
62
|
+
enabled,
|
|
63
|
+
directory: config?.directory ?? process.env.PHASEO_DEVTOOLS_DIR ?? DEFAULT_DEVTOOLS_DIR,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function writeDevtoolsEntry(directory, entry) {
|
|
67
|
+
fs.mkdirSync(path.join(directory, "assets", "images"), { recursive: true });
|
|
68
|
+
fs.mkdirSync(path.join(directory, "assets", "audio"), { recursive: true });
|
|
69
|
+
fs.mkdirSync(path.join(directory, "assets", "video"), { recursive: true });
|
|
70
|
+
const metadataPath = path.join(directory, "metadata.json");
|
|
71
|
+
if (!fs.existsSync(metadataPath)) {
|
|
72
|
+
fs.writeFileSync(metadataPath, JSON.stringify({
|
|
73
|
+
session_id: randomUUID(),
|
|
74
|
+
started_at: Date.now(),
|
|
75
|
+
sdk: "typescript",
|
|
76
|
+
sdk_version: AGENT_SDK_VERSION,
|
|
77
|
+
platform: process.platform,
|
|
78
|
+
node_version: process.version,
|
|
79
|
+
}, null, 2), "utf-8");
|
|
80
|
+
}
|
|
81
|
+
fs.appendFileSync(path.join(directory, "generations.jsonl"), `${JSON.stringify(entry)}\n`, "utf-8");
|
|
82
|
+
}
|
|
83
|
+
function findLatestStep(steps) {
|
|
84
|
+
if (!steps?.length)
|
|
85
|
+
return undefined;
|
|
86
|
+
return steps[steps.length - 1];
|
|
87
|
+
}
|
|
88
|
+
function countToolCalls(steps) {
|
|
89
|
+
if (!steps?.length)
|
|
90
|
+
return 0;
|
|
91
|
+
return steps.reduce((count, step) => count + (step.toolCalls?.length ?? 0), 0);
|
|
92
|
+
}
|
|
93
|
+
function toDevtoolsError(error) {
|
|
94
|
+
return {
|
|
95
|
+
message: error instanceof Error ? error.message : String(error),
|
|
96
|
+
code: typeof error?.code === "string" ? error.code : undefined,
|
|
97
|
+
status: typeof error?.status === "number"
|
|
98
|
+
? error.status
|
|
99
|
+
: undefined,
|
|
100
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
101
|
+
};
|
|
102
|
+
}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export type AgentGatewayErrorBody = {
|
|
2
|
+
message?: string;
|
|
3
|
+
error?: unknown;
|
|
4
|
+
reason?: string;
|
|
5
|
+
error_origin?: string;
|
|
6
|
+
error_type?: string;
|
|
7
|
+
request_id?: string;
|
|
8
|
+
generation_id?: string;
|
|
9
|
+
failed_providers?: string[];
|
|
10
|
+
failed_statuses?: number[];
|
|
11
|
+
provider_failure_diagnostics?: Record<string, unknown>;
|
|
12
|
+
provider_enablement?: Record<string, unknown>;
|
|
13
|
+
routing_diagnostics?: Record<string, unknown>;
|
|
14
|
+
details?: Array<Record<string, unknown>>;
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
} | string | undefined;
|
|
17
|
+
export type AgentGatewayErrorDetails = {
|
|
18
|
+
status: number;
|
|
19
|
+
statusText: string;
|
|
20
|
+
message: string;
|
|
21
|
+
requestId: string | null;
|
|
22
|
+
generationId: string | null;
|
|
23
|
+
reason: string | null;
|
|
24
|
+
errorOrigin: string | null;
|
|
25
|
+
errorType: string | null;
|
|
26
|
+
failedProviders: string[];
|
|
27
|
+
failedStatuses: number[];
|
|
28
|
+
providerFailureDiagnostics: Record<string, unknown> | null;
|
|
29
|
+
providerEnablement: Record<string, unknown> | null;
|
|
30
|
+
routingDiagnostics: Record<string, unknown> | null;
|
|
31
|
+
details: Array<Record<string, unknown>>;
|
|
32
|
+
};
|
|
33
|
+
export declare class AgentGatewayError extends Error {
|
|
34
|
+
readonly status: number;
|
|
35
|
+
readonly statusText: string;
|
|
36
|
+
readonly headers: Record<string, string>;
|
|
37
|
+
readonly body: AgentGatewayErrorBody;
|
|
38
|
+
readonly requestId: string | null;
|
|
39
|
+
readonly generationId: string | null;
|
|
40
|
+
readonly reason: string | null;
|
|
41
|
+
readonly errorOrigin: string | null;
|
|
42
|
+
readonly errorType: string | null;
|
|
43
|
+
readonly failedProviders: string[];
|
|
44
|
+
readonly failedStatuses: number[];
|
|
45
|
+
readonly providerFailureDiagnostics: Record<string, unknown> | null;
|
|
46
|
+
readonly providerEnablement: Record<string, unknown> | null;
|
|
47
|
+
readonly routingDiagnostics: Record<string, unknown> | null;
|
|
48
|
+
readonly details: Array<Record<string, unknown>>;
|
|
49
|
+
constructor(args: {
|
|
50
|
+
status: number;
|
|
51
|
+
statusText: string;
|
|
52
|
+
headers?: Record<string, string>;
|
|
53
|
+
body: AgentGatewayErrorBody;
|
|
54
|
+
message?: string;
|
|
55
|
+
cause?: unknown;
|
|
56
|
+
});
|
|
57
|
+
static fromUnknown(error: unknown): AgentGatewayError | null;
|
|
58
|
+
}
|
|
59
|
+
export declare function isAgentGatewayError(error: unknown): error is AgentGatewayError;
|
|
60
|
+
export declare function toAgentGatewayErrorDetails(error: AgentGatewayError): AgentGatewayErrorDetails;
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
function isRecord(value) {
|
|
2
|
+
return typeof value === "object" && value !== null;
|
|
3
|
+
}
|
|
4
|
+
function normalizeHeaders(value) {
|
|
5
|
+
if (!isRecord(value))
|
|
6
|
+
return {};
|
|
7
|
+
const headers = {};
|
|
8
|
+
for (const [key, rawValue] of Object.entries(value)) {
|
|
9
|
+
if (typeof rawValue === "string") {
|
|
10
|
+
headers[key.toLowerCase()] = rawValue;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return headers;
|
|
14
|
+
}
|
|
15
|
+
function readString(value) {
|
|
16
|
+
return typeof value === "string" && value.trim().length > 0 ? value : undefined;
|
|
17
|
+
}
|
|
18
|
+
function headerValue(headers, ...keys) {
|
|
19
|
+
for (const key of keys) {
|
|
20
|
+
const value = headers[key.toLowerCase()];
|
|
21
|
+
if (typeof value === "string" && value.length > 0)
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
function isGatewayHttpErrorLike(value) {
|
|
27
|
+
if (!isRecord(value))
|
|
28
|
+
return false;
|
|
29
|
+
return (typeof value.status === "number" &&
|
|
30
|
+
typeof value.statusText === "string" &&
|
|
31
|
+
"body" in value &&
|
|
32
|
+
(value.name === "PhaseoHttpError" || value.name === "PhaseoHttpError" || "headers" in value));
|
|
33
|
+
}
|
|
34
|
+
function formatGatewayErrorMessage(args) {
|
|
35
|
+
if (args.fallback)
|
|
36
|
+
return args.fallback;
|
|
37
|
+
if (typeof args.body === "string" && args.body.trim().length > 0) {
|
|
38
|
+
return `Gateway request failed: ${args.status} ${args.statusText} - ${args.body}`;
|
|
39
|
+
}
|
|
40
|
+
if (isRecord(args.body)) {
|
|
41
|
+
const message = readString(args.body.message) ??
|
|
42
|
+
readString(args.body.description) ??
|
|
43
|
+
readString(args.body.reason);
|
|
44
|
+
if (message) {
|
|
45
|
+
return `Gateway request failed: ${args.status} ${args.statusText} - ${message}`;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return `Gateway request failed: ${args.status} ${args.statusText}`;
|
|
49
|
+
}
|
|
50
|
+
export class AgentGatewayError extends Error {
|
|
51
|
+
status;
|
|
52
|
+
statusText;
|
|
53
|
+
headers;
|
|
54
|
+
body;
|
|
55
|
+
requestId;
|
|
56
|
+
generationId;
|
|
57
|
+
reason;
|
|
58
|
+
errorOrigin;
|
|
59
|
+
errorType;
|
|
60
|
+
failedProviders;
|
|
61
|
+
failedStatuses;
|
|
62
|
+
providerFailureDiagnostics;
|
|
63
|
+
providerEnablement;
|
|
64
|
+
routingDiagnostics;
|
|
65
|
+
details;
|
|
66
|
+
constructor(args) {
|
|
67
|
+
super(formatGatewayErrorMessage({
|
|
68
|
+
status: args.status,
|
|
69
|
+
statusText: args.statusText,
|
|
70
|
+
body: args.body,
|
|
71
|
+
fallback: args.message,
|
|
72
|
+
}), { cause: args.cause });
|
|
73
|
+
this.name = "AgentGatewayError";
|
|
74
|
+
this.status = args.status;
|
|
75
|
+
this.statusText = args.statusText;
|
|
76
|
+
this.headers = args.headers ?? {};
|
|
77
|
+
this.body = args.body;
|
|
78
|
+
if (isRecord(args.body)) {
|
|
79
|
+
this.requestId =
|
|
80
|
+
readString(args.body.request_id) ??
|
|
81
|
+
headerValue(this.headers, "x-request-id", "request-id", "x-phaseo-request-id") ??
|
|
82
|
+
null;
|
|
83
|
+
this.generationId = readString(args.body.generation_id) ?? null;
|
|
84
|
+
this.reason = readString(args.body.reason) ?? null;
|
|
85
|
+
this.errorOrigin = readString(args.body.error_origin) ?? null;
|
|
86
|
+
this.errorType = readString(args.body.error_type) ?? null;
|
|
87
|
+
this.failedProviders = Array.isArray(args.body.failed_providers)
|
|
88
|
+
? args.body.failed_providers.filter((value) => typeof value === "string")
|
|
89
|
+
: [];
|
|
90
|
+
this.failedStatuses = Array.isArray(args.body.failed_statuses)
|
|
91
|
+
? args.body.failed_statuses.filter((value) => typeof value === "number")
|
|
92
|
+
: [];
|
|
93
|
+
this.providerFailureDiagnostics = isRecord(args.body.provider_failure_diagnostics)
|
|
94
|
+
? args.body.provider_failure_diagnostics
|
|
95
|
+
: null;
|
|
96
|
+
this.providerEnablement = isRecord(args.body.provider_enablement)
|
|
97
|
+
? args.body.provider_enablement
|
|
98
|
+
: null;
|
|
99
|
+
this.routingDiagnostics = isRecord(args.body.routing_diagnostics)
|
|
100
|
+
? args.body.routing_diagnostics
|
|
101
|
+
: null;
|
|
102
|
+
this.details = Array.isArray(args.body.details)
|
|
103
|
+
? args.body.details.filter((value) => isRecord(value))
|
|
104
|
+
: [];
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
this.requestId =
|
|
108
|
+
headerValue(this.headers, "x-request-id", "request-id", "x-phaseo-request-id") ??
|
|
109
|
+
null;
|
|
110
|
+
this.generationId = null;
|
|
111
|
+
this.reason = null;
|
|
112
|
+
this.errorOrigin = null;
|
|
113
|
+
this.errorType = null;
|
|
114
|
+
this.failedProviders = [];
|
|
115
|
+
this.failedStatuses = [];
|
|
116
|
+
this.providerFailureDiagnostics = null;
|
|
117
|
+
this.providerEnablement = null;
|
|
118
|
+
this.routingDiagnostics = null;
|
|
119
|
+
this.details = [];
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
static fromUnknown(error) {
|
|
123
|
+
if (!isGatewayHttpErrorLike(error))
|
|
124
|
+
return null;
|
|
125
|
+
return new AgentGatewayError({
|
|
126
|
+
status: error.status,
|
|
127
|
+
statusText: error.statusText,
|
|
128
|
+
headers: normalizeHeaders(error.headers),
|
|
129
|
+
body: error.body,
|
|
130
|
+
message: typeof error.message === "string" ? error.message : undefined,
|
|
131
|
+
cause: error,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
export function isAgentGatewayError(error) {
|
|
136
|
+
return error instanceof AgentGatewayError;
|
|
137
|
+
}
|
|
138
|
+
export function toAgentGatewayErrorDetails(error) {
|
|
139
|
+
return {
|
|
140
|
+
status: error.status,
|
|
141
|
+
statusText: error.statusText,
|
|
142
|
+
message: error.message,
|
|
143
|
+
requestId: error.requestId,
|
|
144
|
+
generationId: error.generationId,
|
|
145
|
+
reason: error.reason,
|
|
146
|
+
errorOrigin: error.errorOrigin,
|
|
147
|
+
errorType: error.errorType,
|
|
148
|
+
failedProviders: [...error.failedProviders],
|
|
149
|
+
failedStatuses: [...error.failedStatuses],
|
|
150
|
+
providerFailureDiagnostics: error.providerFailureDiagnostics
|
|
151
|
+
? structuredClone(error.providerFailureDiagnostics)
|
|
152
|
+
: null,
|
|
153
|
+
providerEnablement: error.providerEnablement
|
|
154
|
+
? structuredClone(error.providerEnablement)
|
|
155
|
+
: null,
|
|
156
|
+
routingDiagnostics: error.routingDiagnostics
|
|
157
|
+
? structuredClone(error.routingDiagnostics)
|
|
158
|
+
: null,
|
|
159
|
+
details: structuredClone(error.details),
|
|
160
|
+
};
|
|
161
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1,8 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { createAgent, defineTool } from "./agent.js";
|
|
2
|
+
export { createGatewayAgentClient } from "./adapters/gateway-client.js";
|
|
3
|
+
export { createAgentDevtools } from "./devtools.js";
|
|
4
|
+
export { AgentGatewayError, isAgentGatewayError } from "./errors.js";
|
|
5
|
+
export type { AgentDefinition, AgentContinueOptions, AgentEvent, AgentEventHandler, AgentHumanPause, AgentHumanReviewContext, AgentHumanReviewRequest, AgentMessage, AgentModelClient, AgentModelRetryConfig, AgentModelRequest, AgentModelResponse, AgentRunOptions, AgentRunRecord, AgentRunResult, AgentRunStatus, AgentRuntimeContext, AgentStepRecord, AgentStepStatus, AgentTool, AgentToolCall, AgentToolExecutionConfig, } from "./types.js";
|
|
6
|
+
export type { AgentDevtoolsConfig } from "./devtools.js";
|
|
7
|
+
export type { GatewayAgentClientOptions } from "./adapters/gateway-client.js";
|
|
8
|
+
export type { AgentGatewayErrorBody, AgentGatewayErrorDetails } from "./errors.js";
|
package/dist/index.js
CHANGED
|
@@ -1 +1,4 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { createAgent, defineTool } from "./agent.js";
|
|
2
|
+
export { createGatewayAgentClient } from "./adapters/gateway-client.js";
|
|
3
|
+
export { createAgentDevtools } from "./devtools.js";
|
|
4
|
+
export { AgentGatewayError, isAgentGatewayError } from "./errors.js";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { AgentContinueOptions, AgentDefinition, AgentRunOptions, AgentRunResult } from "../types.js";
|
|
2
|
+
export declare function runAgent<TInput, TOutput, TContext>(definition: AgentDefinition<TInput, TOutput, TContext>, options: AgentRunOptions<TInput, TContext>): Promise<AgentRunResult<TOutput, TInput, TContext>>;
|
|
3
|
+
export declare function continueAgent<TInput, TOutput, TContext>(definition: AgentDefinition<TInput, TOutput, TContext>, options: AgentContinueOptions<TInput, TOutput, TContext>): Promise<AgentRunResult<TOutput, TInput, TContext>>;
|