Skip to content

Commit 5e5b5ef

Browse files
Normalize structured agent output types at runtime
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent bdefa85 commit 5e5b5ef

4 files changed

Lines changed: 40 additions & 4 deletions

File tree

currentState.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,11 @@ HyperAgent exposes a TypeScript SDK for browser automation with three primary pa
111111
- Hardened perform-action failure formatting with explicit bounded diagnostics, including trap-prone DOM element lookup failures.
112112
- Hardened Anthropic provider structured-output warning diagnostics in schema validation fallback branches.
113113
- Hardened network-settle waiting (`waitForSettledDOM`) with safe listener attach/detach handling, timeout fallback when listener registration fails, and bounded stalled-request diagnostics.
114+
- Added bounded timeout normalization in `waitForSettledDOM` so invalid/non-finite/non-positive waits no longer resolve immediately and oversized values are capped.
114115
- Hardened replay-step diagnostics in `runFromActionCache` to strip control characters in cached-step/page getter failure messages.
115116
- Sanitized control characters in prompt-builder task/step/DOM payload serialization before truncation to keep LLM context inputs clean under malformed runtime values.
117+
- Tightened agent-loop action/output typing by normalizing parsed structured outputs into explicit `AgentOutput`/`ActionType` shapes before runtime dispatch and cache recording.
118+
- Removed direct `as any` casts in OpenAI/Anthropic/DeepSeek/Gemini provider request payload assembly in favor of SDK-derived parameter field typing.
116119
- Expanded top-level package exports for key workflow/config types at `@hyperbrowser/agent`.
117120
- Removed stale script entry (`build-dom-tree-script`) and improved README usage docs.
118121
- Added canonical single-action debug writer helper (`writePerformDebug`) while preserving deprecated alias compatibility.

src/agent/tools/agent.test.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,12 @@ function createMockPage(): Page {
4646
} as unknown as Page;
4747
}
4848

49-
function createCompleteActionDefinition(): AgentActionDefinition {
49+
function createCompleteActionDefinition(): AgentActionDefinition<
50+
z.ZodObject<{
51+
success: z.ZodBoolean;
52+
text: z.ZodOptional<z.ZodString>;
53+
}>
54+
> {
5055
return {
5156
type: "complete",
5257
actionParams: z.object({

src/agent/tools/agent.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
ActionCacheOutput,
3+
AgentOutput,
34
AgentStep,
45
AgentTaskOutput,
56
} from "@/types/agent/types";
@@ -227,6 +228,28 @@ function normalizeActionOutput(
227228
};
228229
}
229230

231+
function normalizeAgentOutput(value: unknown): AgentOutput {
232+
const thoughts = formatDiagnosticText(
233+
safeReadRecordField(value, "thoughts"),
234+
MAX_RUNTIME_ACTION_MESSAGE_CHARS,
235+
""
236+
);
237+
const memory = formatDiagnosticText(
238+
safeReadRecordField(value, "memory"),
239+
MAX_RUNTIME_ACTION_MESSAGE_CHARS,
240+
""
241+
);
242+
const action = safeReadRecordField(value, "action");
243+
return {
244+
thoughts,
245+
memory,
246+
action: {
247+
type: normalizeRuntimeActionType(safeReadRecordField(action, "type")),
248+
params: safeReadRecordField(action, "params"),
249+
},
250+
};
251+
}
252+
230253
function resolveCompleteActionFormatter(
231254
actions: Array<AgentActionDefinition>
232255
):
@@ -855,7 +878,7 @@ export const runAgentTask = async (
855878
}
856879

857880
// Invoke LLM with structured output
858-
const agentOutput = await (async () => {
881+
const rawAgentOutput = await (async () => {
859882
const maxAttempts = 3;
860883
let currentMsgs = msgs;
861884

@@ -1004,6 +1027,7 @@ export const runAgentTask = async (
10041027
}
10051028
throw new Error("Failed to get structured output from LLM");
10061029
})();
1030+
const agentOutput = normalizeAgentOutput(rawAgentOutput);
10071031

10081032
params?.debugOnAgentOutput?.(agentOutput);
10091033

src/types/agent/types.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { z } from "zod";
2-
import { ActionOutput } from "./actions/types";
2+
import { ActionOutput, ActionType } from "./actions/types";
33
import { Page } from "playwright-core";
44
import { ErrorEmitter } from "@/utils";
55
import type { HyperAgentLLM } from "@/llm/types";
@@ -24,7 +24,11 @@ export const AgentOutputFn = (
2424
action: actionsSchema,
2525
});
2626

27-
export type AgentOutput = z.infer<ReturnType<typeof AgentOutputFn>>;
27+
export interface AgentOutput {
28+
thoughts: string;
29+
memory: string;
30+
action: ActionType;
31+
}
2832

2933
export interface AgentStep {
3034
idx: number;

0 commit comments

Comments
 (0)