@sayer/agent-step 0.1.0

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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +2 -0
  3. package/dist/agent/action-executor.d.ts +20 -0
  4. package/dist/agent/action-executor.d.ts.map +1 -0
  5. package/dist/agent/action-executor.js +112 -0
  6. package/dist/agent/action-executor.js.map +1 -0
  7. package/dist/agent/agent-runtime.d.ts +11 -0
  8. package/dist/agent/agent-runtime.d.ts.map +1 -0
  9. package/dist/agent/agent-runtime.js +103 -0
  10. package/dist/agent/agent-runtime.js.map +1 -0
  11. package/dist/agent/browser-tools.d.ts +28 -0
  12. package/dist/agent/browser-tools.d.ts.map +1 -0
  13. package/dist/agent/browser-tools.js +259 -0
  14. package/dist/agent/browser-tools.js.map +1 -0
  15. package/dist/agent/model.d.ts +6 -0
  16. package/dist/agent/model.d.ts.map +1 -0
  17. package/dist/agent/model.js +161 -0
  18. package/dist/agent/model.js.map +1 -0
  19. package/dist/agent/redaction.d.ts +4 -0
  20. package/dist/agent/redaction.d.ts.map +1 -0
  21. package/dist/agent/redaction.js +37 -0
  22. package/dist/agent/redaction.js.map +1 -0
  23. package/dist/agent/types.d.ts +89 -0
  24. package/dist/agent/types.d.ts.map +1 -0
  25. package/dist/agent/types.js +2 -0
  26. package/dist/agent/types.js.map +1 -0
  27. package/dist/agent/verifier.d.ts +22 -0
  28. package/dist/agent/verifier.d.ts.map +1 -0
  29. package/dist/agent/verifier.js +209 -0
  30. package/dist/agent/verifier.js.map +1 -0
  31. package/dist/agent-step.d.ts +10 -0
  32. package/dist/agent-step.d.ts.map +1 -0
  33. package/dist/agent-step.js +68 -0
  34. package/dist/agent-step.js.map +1 -0
  35. package/dist/agent-test.d.ts +10 -0
  36. package/dist/agent-test.d.ts.map +1 -0
  37. package/dist/agent-test.js +7 -0
  38. package/dist/agent-test.js.map +1 -0
  39. package/dist/index.d.ts +4 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +3 -0
  42. package/dist/index.js.map +1 -0
  43. package/package.json +68 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 sayer122
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,2 @@
1
+ # agent-step
2
+ A playwright fixture for adding agentic actions to tests and combining with other test steps.
@@ -0,0 +1,20 @@
1
+ import { type BrowserToolContext } from './browser-tools.js';
2
+ import type { ModelClient, TokenUsage, TranscriptEntry } from './types.js';
3
+ export interface ActionExecutorOptions {
4
+ modelClient: ModelClient;
5
+ ctx: BrowserToolContext;
6
+ action: string;
7
+ maxTurns: number;
8
+ signal: AbortSignal;
9
+ }
10
+ export interface ActionExecutorResult {
11
+ transcript: TranscriptEntry[];
12
+ tokenUsage: TokenUsage;
13
+ doneSummary: string;
14
+ }
15
+ export declare class ActionExecutor {
16
+ private readonly options;
17
+ constructor(options: ActionExecutorOptions);
18
+ run(): Promise<ActionExecutorResult>;
19
+ }
20
+ //# sourceMappingURL=action-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-executor.d.ts","sourceRoot":"","sources":["../../src/agent/action-executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAEV,WAAW,EACX,UAAU,EACV,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,WAAW,CAAC;IACzB,GAAG,EAAE,kBAAkB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,qBAAqB;IAErD,GAAG,IAAI,OAAO,CAAC,oBAAoB,CAAC;CA8G3C"}
@@ -0,0 +1,112 @@
1
+ import { BrowserTools, BROWSER_TOOL_DEFINITIONS, } from './browser-tools.js';
2
+ import { redactObject } from './redaction.js';
3
+ export class ActionExecutor {
4
+ options;
5
+ constructor(options) {
6
+ this.options = options;
7
+ }
8
+ async run() {
9
+ const tools = new BrowserTools(this.options.ctx);
10
+ const transcript = [];
11
+ const tokenUsage = {
12
+ promptTokens: 0,
13
+ completionTokens: 0,
14
+ totalTokens: 0,
15
+ };
16
+ const messages = [
17
+ {
18
+ role: 'system',
19
+ content: [
20
+ 'You are a browser automation agent operating inside a Playwright test.',
21
+ 'Use only the provided tools. Always start with browser_snapshot.',
22
+ 'Interact using snapshot refs via target (or ref).',
23
+ 'Use %SECRET_NAME% placeholders for sensitive browser_type values.',
24
+ 'Call done when the requested action is complete.',
25
+ 'Do not navigate away from the current origin unless the action requires it.',
26
+ ].join(' '),
27
+ },
28
+ {
29
+ role: 'user',
30
+ content: `Perform this action:\n${this.options.action}`,
31
+ },
32
+ ];
33
+ for (let turn = 1; turn <= this.options.maxTurns; turn++) {
34
+ if (this.options.signal.aborted) {
35
+ throw new Error('Agent step timed out during action execution');
36
+ }
37
+ const response = await this.options.modelClient.chat({
38
+ messages,
39
+ tools: BROWSER_TOOL_DEFINITIONS,
40
+ toolChoice: 'required',
41
+ signal: this.options.signal,
42
+ });
43
+ accumulateUsage(tokenUsage, response.usage);
44
+ if (response.content) {
45
+ transcript.push({
46
+ turn,
47
+ type: 'message',
48
+ content: response.content,
49
+ });
50
+ }
51
+ if (response.toolCalls.length === 0) {
52
+ throw new Error('Model returned no tool calls during action execution');
53
+ }
54
+ messages.push({
55
+ role: 'assistant',
56
+ content: response.content,
57
+ toolCalls: response.toolCalls,
58
+ });
59
+ for (const toolCall of response.toolCalls) {
60
+ let parsedArgs;
61
+ try {
62
+ parsedArgs = JSON.parse(toolCall.arguments);
63
+ }
64
+ catch {
65
+ throw new Error(`Malformed tool arguments for ${toolCall.name}`);
66
+ }
67
+ transcript.push({
68
+ turn,
69
+ type: 'tool_call',
70
+ name: toolCall.name,
71
+ input: redactObject(parsedArgs, this.options.ctx.secrets),
72
+ });
73
+ let output;
74
+ try {
75
+ output = await tools.execute(toolCall.name, parsedArgs);
76
+ }
77
+ catch (error) {
78
+ const message = error instanceof Error ? error.message : String(error);
79
+ if (message.startsWith('Origin not allowed')) {
80
+ throw error;
81
+ }
82
+ output = { error: message };
83
+ }
84
+ transcript.push({
85
+ turn,
86
+ type: 'tool_result',
87
+ name: toolCall.name,
88
+ output: redactObject(output, this.options.ctx.secrets),
89
+ });
90
+ messages.push({
91
+ role: 'tool',
92
+ toolCallId: toolCall.id,
93
+ content: JSON.stringify(output),
94
+ });
95
+ if (toolCall.name === 'done' && tools.isDone()) {
96
+ return {
97
+ transcript,
98
+ tokenUsage,
99
+ doneSummary: tools.getDoneSummary() ?? 'Action completed',
100
+ };
101
+ }
102
+ }
103
+ }
104
+ throw new Error(`Action executor exhausted maximum turns (${this.options.maxTurns})`);
105
+ }
106
+ }
107
+ function accumulateUsage(target, delta) {
108
+ target.promptTokens += delta.promptTokens;
109
+ target.completionTokens += delta.completionTokens;
110
+ target.totalTokens += delta.totalTokens;
111
+ }
112
+ //# sourceMappingURL=action-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-executor.js","sourceRoot":"","sources":["../../src/agent/action-executor.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BrowserTools,\n BROWSER_TOOL_DEFINITIONS,\n type BrowserToolContext,\n} from './browser-tools.js';\nimport { redactObject } from './redaction.js';\nimport type {\n ChatMessage,\n ModelClient,\n TokenUsage,\n TranscriptEntry,\n} from './types.js';\n\nexport interface ActionExecutorOptions {\n modelClient: ModelClient;\n ctx: BrowserToolContext;\n action: string;\n maxTurns: number;\n signal: AbortSignal;\n}\n\nexport interface ActionExecutorResult {\n transcript: TranscriptEntry[];\n tokenUsage: TokenUsage;\n doneSummary: string;\n}\n\nexport class ActionExecutor {\n constructor(private readonly options: ActionExecutorOptions) {}\n\n async run(): Promise<ActionExecutorResult> {\n const tools = new BrowserTools(this.options.ctx);\n const transcript: TranscriptEntry[] = [];\n const tokenUsage: TokenUsage = {\n promptTokens: 0,\n completionTokens: 0,\n totalTokens: 0,\n };\n\n const messages: ChatMessage[] = [\n {\n role: 'system',\n content: [\n 'You are a browser automation agent operating inside a Playwright test.',\n 'Use only the provided tools. Always start with browser_snapshot.',\n 'Interact using snapshot refs via target (or ref).',\n 'Use %SECRET_NAME% placeholders for sensitive browser_type values.',\n 'Call done when the requested action is complete.',\n 'Do not navigate away from the current origin unless the action requires it.',\n ].join(' '),\n },\n {\n role: 'user',\n content: `Perform this action:\\n${this.options.action}`,\n },\n ];\n\n for (let turn = 1; turn <= this.options.maxTurns; turn++) {\n if (this.options.signal.aborted) {\n throw new Error('Agent step timed out during action execution');\n }\n\n const response = await this.options.modelClient.chat({\n messages,\n tools: BROWSER_TOOL_DEFINITIONS,\n toolChoice: 'required',\n signal: this.options.signal,\n });\n\n accumulateUsage(tokenUsage, response.usage);\n\n if (response.content) {\n transcript.push({\n turn,\n type: 'message',\n content: response.content,\n });\n }\n\n if (response.toolCalls.length === 0) {\n throw new Error('Model returned no tool calls during action execution');\n }\n\n messages.push({\n role: 'assistant',\n content: response.content,\n toolCalls: response.toolCalls,\n });\n\n for (const toolCall of response.toolCalls) {\n let parsedArgs: Record<string, unknown>;\n try {\n parsedArgs = JSON.parse(toolCall.arguments) as Record<string, unknown>;\n } catch {\n throw new Error(`Malformed tool arguments for ${toolCall.name}`);\n }\n\n transcript.push({\n turn,\n type: 'tool_call',\n name: toolCall.name,\n input: redactObject(parsedArgs, this.options.ctx.secrets),\n });\n\n let output: unknown;\n try {\n output = await tools.execute(toolCall.name, parsedArgs);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (message.startsWith('Origin not allowed')) {\n throw error;\n }\n output = { error: message };\n }\n\n transcript.push({\n turn,\n type: 'tool_result',\n name: toolCall.name,\n output: redactObject(output, this.options.ctx.secrets),\n });\n\n messages.push({\n role: 'tool',\n toolCallId: toolCall.id,\n content: JSON.stringify(output),\n });\n\n if (toolCall.name === 'done' && tools.isDone()) {\n return {\n transcript,\n tokenUsage,\n doneSummary: tools.getDoneSummary() ?? 'Action completed',\n };\n }\n }\n }\n\n throw new Error(`Action executor exhausted maximum turns (${this.options.maxTurns})`);\n }\n}\n\nfunction accumulateUsage(target: TokenUsage, delta: TokenUsage): void {\n target.promptTokens += delta.promptTokens;\n target.completionTokens += delta.completionTokens;\n target.totalTokens += delta.totalTokens;\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import type { AgentRuntimeOptions, AgentStepInput, AgentStepResult } from './types.js';
2
+ export declare class AgentRuntime {
3
+ private readonly options;
4
+ constructor(options: AgentRuntimeOptions);
5
+ runStep(input: AgentStepInput): Promise<AgentStepResult>;
6
+ }
7
+ export declare class AgentStepError extends Error {
8
+ readonly result?: AgentStepResult | undefined;
9
+ constructor(message: string, result?: AgentStepResult | undefined);
10
+ }
11
+ //# sourceMappingURL=agent-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-runtime.d.ts","sourceRoot":"","sources":["../../src/agent/agent-runtime.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,mBAAmB,EACnB,cAAc,EACd,eAAe,EAEhB,MAAM,YAAY,CAAC;AAKpB,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,mBAAmB;IAEnD,OAAO,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;CAgF/D;AAED,qBAAa,cAAe,SAAQ,KAAK;IAGrC,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe;gBADjC,OAAO,EAAE,MAAM,EACN,MAAM,CAAC,EAAE,eAAe,YAAA;CAKpC"}
@@ -0,0 +1,103 @@
1
+ import { ActionExecutor } from './action-executor.js';
2
+ import { createModelClient, loadAgentConfig } from './model.js';
3
+ import { Verifier } from './verifier.js';
4
+ const DEFAULT_MAX_TURNS = 8;
5
+ const DEFAULT_TIMEOUT_MS = 60_000;
6
+ export class AgentRuntime {
7
+ options;
8
+ constructor(options) {
9
+ this.options = options;
10
+ }
11
+ async runStep(input) {
12
+ const maxTurns = this.options.maxTurns ?? DEFAULT_MAX_TURNS;
13
+ const defaultTimeout = this.options.defaultTimeout ?? DEFAULT_TIMEOUT_MS;
14
+ const timeout = input.timeout ?? defaultTimeout;
15
+ const controller = new AbortController();
16
+ const timer = setTimeout(() => controller.abort(), timeout);
17
+ try {
18
+ const modelClient = this.options.modelClient ?? createModelClient(loadAgentConfig());
19
+ const allowedOrigins = this.options.allowedOrigins ??
20
+ deriveAllowedOrigins(this.options.page.url());
21
+ const secrets = input.secrets ?? {};
22
+ const ctx = {
23
+ page: this.options.page,
24
+ allowedOrigins,
25
+ secrets,
26
+ };
27
+ const actionResult = await new ActionExecutor({
28
+ modelClient,
29
+ ctx,
30
+ action: input.action,
31
+ maxTurns,
32
+ signal: controller.signal,
33
+ }).run();
34
+ const snapshotResult = await this.options.page.ariaSnapshotJSON({
35
+ mode: 'ai',
36
+ });
37
+ const verificationResult = await new Verifier({
38
+ modelClient,
39
+ expect: input.expect,
40
+ snapshot: snapshotResult,
41
+ url: this.options.page.url(),
42
+ signal: controller.signal,
43
+ }).run();
44
+ const tokenUsage = mergeUsage(actionResult.tokenUsage, verificationResult.tokenUsage);
45
+ const result = {
46
+ action: input.action,
47
+ expect: input.expect,
48
+ actionTranscript: actionResult.transcript,
49
+ verification: verificationResult.verification,
50
+ tokenUsage,
51
+ rawVerifierContent: verificationResult.rawContent,
52
+ };
53
+ if (!result.verification.passed) {
54
+ const failed = result.verification.criteria
55
+ .filter((item) => !item.passed)
56
+ .map((item) => `- ${item.criterion}: ${item.evidence}`)
57
+ .join('\n');
58
+ const prefix = result.verification.inconclusive
59
+ ? 'Agent verification inconclusive'
60
+ : 'Agent verification failed';
61
+ throw new AgentStepError(`${prefix}:\n${failed}`, result);
62
+ }
63
+ return result;
64
+ }
65
+ catch (error) {
66
+ if (error instanceof AgentStepError) {
67
+ throw error;
68
+ }
69
+ if (controller.signal.aborted) {
70
+ throw new Error(`Agent step timed out after ${timeout}ms`);
71
+ }
72
+ throw error;
73
+ }
74
+ finally {
75
+ clearTimeout(timer);
76
+ }
77
+ }
78
+ }
79
+ export class AgentStepError extends Error {
80
+ result;
81
+ constructor(message, result) {
82
+ super(message);
83
+ this.result = result;
84
+ this.name = 'AgentStepError';
85
+ }
86
+ }
87
+ function deriveAllowedOrigins(currentUrl) {
88
+ try {
89
+ const origin = new URL(currentUrl).origin;
90
+ return origin === 'null' ? ['null'] : [origin];
91
+ }
92
+ catch {
93
+ return ['null'];
94
+ }
95
+ }
96
+ function mergeUsage(a, b) {
97
+ return {
98
+ promptTokens: a.promptTokens + b.promptTokens,
99
+ completionTokens: a.completionTokens + b.completionTokens,
100
+ totalTokens: a.totalTokens + b.totalTokens,
101
+ };
102
+ }
103
+ //# sourceMappingURL=agent-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-runtime.js","sourceRoot":"","sources":["../../src/agent/agent-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { ActionExecutor } from './action-executor.js';\nimport { createModelClient, loadAgentConfig } from './model.js';\nimport { Verifier } from './verifier.js';\nimport type {\n AgentRuntimeOptions,\n AgentStepInput,\n AgentStepResult,\n TokenUsage,\n} from './types.js';\n\nconst DEFAULT_MAX_TURNS = 8;\nconst DEFAULT_TIMEOUT_MS = 60_000;\n\nexport class AgentRuntime {\n constructor(private readonly options: AgentRuntimeOptions) {}\n\n async runStep(input: AgentStepInput): Promise<AgentStepResult> {\n const maxTurns = this.options.maxTurns ?? DEFAULT_MAX_TURNS;\n const defaultTimeout = this.options.defaultTimeout ?? DEFAULT_TIMEOUT_MS;\n const timeout = input.timeout ?? defaultTimeout;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeout);\n\n try {\n const modelClient =\n this.options.modelClient ?? createModelClient(loadAgentConfig());\n\n const allowedOrigins =\n this.options.allowedOrigins ??\n deriveAllowedOrigins(this.options.page.url());\n\n const secrets = input.secrets ?? {};\n const ctx = {\n page: this.options.page,\n allowedOrigins,\n secrets,\n };\n\n const actionResult = await new ActionExecutor({\n modelClient,\n ctx,\n action: input.action,\n maxTurns,\n signal: controller.signal,\n }).run();\n\n const snapshotResult = await this.options.page.ariaSnapshotJSON({\n mode: 'ai',\n });\n\n const verificationResult = await new Verifier({\n modelClient,\n expect: input.expect,\n snapshot: snapshotResult,\n url: this.options.page.url(),\n signal: controller.signal,\n }).run();\n\n const tokenUsage = mergeUsage(\n actionResult.tokenUsage,\n verificationResult.tokenUsage,\n );\n\n const result: AgentStepResult = {\n action: input.action,\n expect: input.expect,\n actionTranscript: actionResult.transcript,\n verification: verificationResult.verification,\n tokenUsage,\n rawVerifierContent: verificationResult.rawContent,\n };\n\n if (!result.verification.passed) {\n const failed = result.verification.criteria\n .filter((item) => !item.passed)\n .map((item) => `- ${item.criterion}: ${item.evidence}`)\n .join('\\n');\n const prefix = result.verification.inconclusive\n ? 'Agent verification inconclusive'\n : 'Agent verification failed';\n throw new AgentStepError(`${prefix}:\\n${failed}`, result);\n }\n\n return result;\n } catch (error) {\n if (error instanceof AgentStepError) {\n throw error;\n }\n if (controller.signal.aborted) {\n throw new Error(`Agent step timed out after ${timeout}ms`);\n }\n throw error;\n } finally {\n clearTimeout(timer);\n }\n }\n}\n\nexport class AgentStepError extends Error {\n constructor(\n message: string,\n readonly result?: AgentStepResult,\n ) {\n super(message);\n this.name = 'AgentStepError';\n }\n}\n\nfunction deriveAllowedOrigins(currentUrl: string): string[] {\n try {\n const origin = new URL(currentUrl).origin;\n return origin === 'null' ? ['null'] : [origin];\n } catch {\n return ['null'];\n }\n}\n\nfunction mergeUsage(a: TokenUsage, b: TokenUsage): TokenUsage {\n return {\n promptTokens: a.promptTokens + b.promptTokens,\n completionTokens: a.completionTokens + b.completionTokens,\n totalTokens: a.totalTokens + b.totalTokens,\n };\n}\n"]}
@@ -0,0 +1,28 @@
1
+ import type { Page } from '@playwright/test';
2
+ import type { ToolDefinition } from './types.js';
3
+ export interface BrowserToolContext {
4
+ page: Page;
5
+ allowedOrigins: string[];
6
+ secrets: Record<string, string>;
7
+ }
8
+ export declare const BROWSER_TOOL_DEFINITIONS: ToolDefinition[];
9
+ export declare class BrowserTools {
10
+ private readonly ctx;
11
+ private doneSummary;
12
+ constructor(ctx: BrowserToolContext);
13
+ isDone(): boolean;
14
+ getDoneSummary(): string | null;
15
+ execute(name: string, args: Record<string, unknown>): Promise<unknown>;
16
+ snapshot(): Promise<{
17
+ snapshot: unknown;
18
+ url: string;
19
+ }>;
20
+ private click;
21
+ private type;
22
+ private select;
23
+ private check;
24
+ private press;
25
+ private assertRef;
26
+ private assertAllowedOrigin;
27
+ }
28
+ //# sourceMappingURL=browser-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-tools.d.ts","sourceRoot":"","sources":["../../src/agent/browser-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,IAAI,CAAC;IACX,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAQD,eAAO,MAAM,wBAAwB,EAAE,cAAc,EAqIpD,CAAC;AAIF,qBAAa,YAAY;IAGX,OAAO,CAAC,QAAQ,CAAC,GAAG;IAFhC,OAAO,CAAC,WAAW,CAAuB;gBAEb,GAAG,EAAE,kBAAkB;IAEpD,MAAM,IAAI,OAAO;IAIjB,cAAc,IAAI,MAAM,GAAG,IAAI;IAIzB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IA0BtE,QAAQ,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;YAM/C,KAAK;YAML,IAAI;YAcJ,MAAM;YAMN,KAAK;YAWL,KAAK;IAQnB,OAAO,CAAC,SAAS;YAMH,mBAAmB;CAelC"}
@@ -0,0 +1,259 @@
1
+ import { resolveSecretValue } from './redaction.js';
2
+ const targetParam = {
3
+ type: 'string',
4
+ description: 'Element ref from the latest accessibility snapshot, such as e2 or f1e3.',
5
+ };
6
+ export const BROWSER_TOOL_DEFINITIONS = [
7
+ {
8
+ type: 'function',
9
+ function: {
10
+ name: 'browser_snapshot',
11
+ description: 'Capture the current page accessibility snapshot with element refs for interaction.',
12
+ parameters: {
13
+ type: 'object',
14
+ properties: {},
15
+ additionalProperties: false,
16
+ },
17
+ },
18
+ },
19
+ {
20
+ type: 'function',
21
+ function: {
22
+ name: 'browser_click',
23
+ description: 'Click an element identified by a snapshot ref.',
24
+ parameters: {
25
+ type: 'object',
26
+ properties: {
27
+ target: targetParam,
28
+ ref: targetParam,
29
+ },
30
+ additionalProperties: false,
31
+ },
32
+ },
33
+ },
34
+ {
35
+ type: 'function',
36
+ function: {
37
+ name: 'browser_type',
38
+ description: 'Fill a text input identified by a snapshot ref. Use %SECRET_NAME% placeholders for sensitive values.',
39
+ parameters: {
40
+ type: 'object',
41
+ properties: {
42
+ target: targetParam,
43
+ ref: targetParam,
44
+ text: { type: 'string' },
45
+ value: { type: 'string' },
46
+ submit: {
47
+ type: 'boolean',
48
+ description: 'If true, press Enter after filling.',
49
+ },
50
+ },
51
+ additionalProperties: false,
52
+ },
53
+ },
54
+ },
55
+ {
56
+ type: 'function',
57
+ function: {
58
+ name: 'browser_select_option',
59
+ description: 'Select dropdown option(s) identified by a snapshot ref.',
60
+ parameters: {
61
+ type: 'object',
62
+ properties: {
63
+ target: targetParam,
64
+ ref: targetParam,
65
+ values: {
66
+ type: 'array',
67
+ items: { type: 'string' },
68
+ },
69
+ value: { type: 'string' },
70
+ },
71
+ additionalProperties: false,
72
+ },
73
+ },
74
+ },
75
+ {
76
+ type: 'function',
77
+ function: {
78
+ name: 'browser_check',
79
+ description: 'Check a checkbox or radio identified by a snapshot ref.',
80
+ parameters: {
81
+ type: 'object',
82
+ properties: {
83
+ target: targetParam,
84
+ ref: targetParam,
85
+ },
86
+ additionalProperties: false,
87
+ },
88
+ },
89
+ },
90
+ {
91
+ type: 'function',
92
+ function: {
93
+ name: 'browser_uncheck',
94
+ description: 'Uncheck a checkbox identified by a snapshot ref.',
95
+ parameters: {
96
+ type: 'object',
97
+ properties: {
98
+ target: targetParam,
99
+ ref: targetParam,
100
+ },
101
+ additionalProperties: false,
102
+ },
103
+ },
104
+ },
105
+ {
106
+ type: 'function',
107
+ function: {
108
+ name: 'browser_press_key',
109
+ description: 'Press a keyboard key. Allowed keys: Enter, Tab, Escape, ArrowDown, ArrowUp.',
110
+ parameters: {
111
+ type: 'object',
112
+ properties: {
113
+ key: { type: 'string' },
114
+ },
115
+ required: ['key'],
116
+ additionalProperties: false,
117
+ },
118
+ },
119
+ },
120
+ {
121
+ type: 'function',
122
+ function: {
123
+ name: 'done',
124
+ description: 'Signal that the requested Playwright test action has been completed.',
125
+ parameters: {
126
+ type: 'object',
127
+ properties: {
128
+ summary: { type: 'string' },
129
+ },
130
+ required: ['summary'],
131
+ additionalProperties: false,
132
+ },
133
+ },
134
+ },
135
+ ];
136
+ const ALLOWED_KEYS = new Set(['Enter', 'Tab', 'Escape', 'ArrowDown', 'ArrowUp']);
137
+ export class BrowserTools {
138
+ ctx;
139
+ doneSummary = null;
140
+ constructor(ctx) {
141
+ this.ctx = ctx;
142
+ }
143
+ isDone() {
144
+ return this.doneSummary !== null;
145
+ }
146
+ getDoneSummary() {
147
+ return this.doneSummary;
148
+ }
149
+ async execute(name, args) {
150
+ await this.assertAllowedOrigin();
151
+ switch (name) {
152
+ case 'browser_snapshot':
153
+ return this.snapshot();
154
+ case 'browser_click':
155
+ return this.click(readTarget(args));
156
+ case 'browser_type':
157
+ return this.type(readTarget(args), readText(args), Boolean(args.submit));
158
+ case 'browser_select_option':
159
+ return this.select(readTarget(args), readSelectValues(args));
160
+ case 'browser_check':
161
+ return this.check(readTarget(args), true);
162
+ case 'browser_uncheck':
163
+ return this.check(readTarget(args), false);
164
+ case 'browser_press_key':
165
+ return this.press(String(args.key));
166
+ case 'done':
167
+ this.doneSummary = String(args.summary);
168
+ return { ok: true, summary: this.doneSummary };
169
+ default:
170
+ throw new Error(`Disallowed tool: ${name}`);
171
+ }
172
+ }
173
+ async snapshot() {
174
+ await this.assertAllowedOrigin();
175
+ const snapshot = await this.ctx.page.ariaSnapshotJSON({ mode: 'ai' });
176
+ return { snapshot, url: this.ctx.page.url() };
177
+ }
178
+ async click(ref) {
179
+ this.assertRef(ref);
180
+ await this.ctx.page.locator(`aria-ref=${ref}`).click();
181
+ return { ok: true, url: this.ctx.page.url() };
182
+ }
183
+ async type(ref, text, submit) {
184
+ this.assertRef(ref);
185
+ const resolved = resolveSecretValue(text, this.ctx.secrets);
186
+ await this.ctx.page.locator(`aria-ref=${ref}`).fill(resolved);
187
+ if (submit) {
188
+ await this.press('Enter');
189
+ }
190
+ return { ok: true };
191
+ }
192
+ async select(ref, values) {
193
+ this.assertRef(ref);
194
+ await this.ctx.page.locator(`aria-ref=${ref}`).selectOption(values);
195
+ return { ok: true };
196
+ }
197
+ async check(ref, checked) {
198
+ this.assertRef(ref);
199
+ const locator = this.ctx.page.locator(`aria-ref=${ref}`);
200
+ if (checked) {
201
+ await locator.check();
202
+ }
203
+ else {
204
+ await locator.uncheck();
205
+ }
206
+ return { ok: true };
207
+ }
208
+ async press(key) {
209
+ if (!ALLOWED_KEYS.has(key)) {
210
+ throw new Error(`Disallowed key: ${key}`);
211
+ }
212
+ await this.ctx.page.keyboard.press(key);
213
+ return { ok: true };
214
+ }
215
+ assertRef(ref) {
216
+ if (!/^(?:f\d+)?e\d+$/.test(ref)) {
217
+ throw new Error(`Invalid aria-ref format: ${ref}`);
218
+ }
219
+ }
220
+ async assertAllowedOrigin() {
221
+ const url = this.ctx.page.url();
222
+ if (url === 'about:blank')
223
+ return;
224
+ let origin;
225
+ try {
226
+ origin = new URL(url).origin;
227
+ }
228
+ catch {
229
+ throw new Error(`Invalid page URL: ${url}`);
230
+ }
231
+ if (!this.ctx.allowedOrigins.includes(origin)) {
232
+ throw new Error(`Origin not allowed: ${origin}`);
233
+ }
234
+ }
235
+ }
236
+ function readTarget(args) {
237
+ const target = args.target ?? args.ref;
238
+ if (typeof target !== 'string' || !target) {
239
+ throw new Error('Missing snapshot target/ref');
240
+ }
241
+ return target;
242
+ }
243
+ function readText(args) {
244
+ const text = args.text ?? args.value;
245
+ if (typeof text !== 'string') {
246
+ throw new Error('Missing text/value to type');
247
+ }
248
+ return text;
249
+ }
250
+ function readSelectValues(args) {
251
+ if (Array.isArray(args.values)) {
252
+ return args.values.map(String);
253
+ }
254
+ if (typeof args.value === 'string') {
255
+ return [args.value];
256
+ }
257
+ throw new Error('Missing values to select');
258
+ }
259
+ //# sourceMappingURL=browser-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-tools.js","sourceRoot":"","sources":["../../src/agent/browser-tools.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Page } from '@playwright/test';\nimport { resolveSecretValue } from './redaction.js';\nimport type { ToolDefinition } from './types.js';\n\nexport interface BrowserToolContext {\n page: Page;\n allowedOrigins: string[];\n secrets: Record<string, string>;\n}\n\nconst targetParam = {\n type: 'string',\n description:\n 'Element ref from the latest accessibility snapshot, such as e2 or f1e3.',\n};\n\nexport const BROWSER_TOOL_DEFINITIONS: ToolDefinition[] = [\n {\n type: 'function',\n function: {\n name: 'browser_snapshot',\n description:\n 'Capture the current page accessibility snapshot with element refs for interaction.',\n parameters: {\n type: 'object',\n properties: {},\n additionalProperties: false,\n },\n },\n },\n {\n type: 'function',\n function: {\n name: 'browser_click',\n description: 'Click an element identified by a snapshot ref.',\n parameters: {\n type: 'object',\n properties: {\n target: targetParam,\n ref: targetParam,\n },\n additionalProperties: false,\n },\n },\n },\n {\n type: 'function',\n function: {\n name: 'browser_type',\n description:\n 'Fill a text input identified by a snapshot ref. Use %SECRET_NAME% placeholders for sensitive values.',\n parameters: {\n type: 'object',\n properties: {\n target: targetParam,\n ref: targetParam,\n text: { type: 'string' },\n value: { type: 'string' },\n submit: {\n type: 'boolean',\n description: 'If true, press Enter after filling.',\n },\n },\n additionalProperties: false,\n },\n },\n },\n {\n type: 'function',\n function: {\n name: 'browser_select_option',\n description: 'Select dropdown option(s) identified by a snapshot ref.',\n parameters: {\n type: 'object',\n properties: {\n target: targetParam,\n ref: targetParam,\n values: {\n type: 'array',\n items: { type: 'string' },\n },\n value: { type: 'string' },\n },\n additionalProperties: false,\n },\n },\n },\n {\n type: 'function',\n function: {\n name: 'browser_check',\n description: 'Check a checkbox or radio identified by a snapshot ref.',\n parameters: {\n type: 'object',\n properties: {\n target: targetParam,\n ref: targetParam,\n },\n additionalProperties: false,\n },\n },\n },\n {\n type: 'function',\n function: {\n name: 'browser_uncheck',\n description: 'Uncheck a checkbox identified by a snapshot ref.',\n parameters: {\n type: 'object',\n properties: {\n target: targetParam,\n ref: targetParam,\n },\n additionalProperties: false,\n },\n },\n },\n {\n type: 'function',\n function: {\n name: 'browser_press_key',\n description:\n 'Press a keyboard key. Allowed keys: Enter, Tab, Escape, ArrowDown, ArrowUp.',\n parameters: {\n type: 'object',\n properties: {\n key: { type: 'string' },\n },\n required: ['key'],\n additionalProperties: false,\n },\n },\n },\n {\n type: 'function',\n function: {\n name: 'done',\n description:\n 'Signal that the requested Playwright test action has been completed.',\n parameters: {\n type: 'object',\n properties: {\n summary: { type: 'string' },\n },\n required: ['summary'],\n additionalProperties: false,\n },\n },\n },\n];\n\nconst ALLOWED_KEYS = new Set(['Enter', 'Tab', 'Escape', 'ArrowDown', 'ArrowUp']);\n\nexport class BrowserTools {\n private doneSummary: string | null = null;\n\n constructor(private readonly ctx: BrowserToolContext) {}\n\n isDone(): boolean {\n return this.doneSummary !== null;\n }\n\n getDoneSummary(): string | null {\n return this.doneSummary;\n }\n\n async execute(name: string, args: Record<string, unknown>): Promise<unknown> {\n await this.assertAllowedOrigin();\n\n switch (name) {\n case 'browser_snapshot':\n return this.snapshot();\n case 'browser_click':\n return this.click(readTarget(args));\n case 'browser_type':\n return this.type(readTarget(args), readText(args), Boolean(args.submit));\n case 'browser_select_option':\n return this.select(readTarget(args), readSelectValues(args));\n case 'browser_check':\n return this.check(readTarget(args), true);\n case 'browser_uncheck':\n return this.check(readTarget(args), false);\n case 'browser_press_key':\n return this.press(String(args.key));\n case 'done':\n this.doneSummary = String(args.summary);\n return { ok: true, summary: this.doneSummary };\n default:\n throw new Error(`Disallowed tool: ${name}`);\n }\n }\n\n async snapshot(): Promise<{ snapshot: unknown; url: string }> {\n await this.assertAllowedOrigin();\n const snapshot = await this.ctx.page.ariaSnapshotJSON({ mode: 'ai' });\n return { snapshot, url: this.ctx.page.url() };\n }\n\n private async click(ref: string): Promise<{ ok: true; url: string }> {\n this.assertRef(ref);\n await this.ctx.page.locator(`aria-ref=${ref}`).click();\n return { ok: true, url: this.ctx.page.url() };\n }\n\n private async type(\n ref: string,\n text: string,\n submit: boolean,\n ): Promise<{ ok: true }> {\n this.assertRef(ref);\n const resolved = resolveSecretValue(text, this.ctx.secrets);\n await this.ctx.page.locator(`aria-ref=${ref}`).fill(resolved);\n if (submit) {\n await this.press('Enter');\n }\n return { ok: true };\n }\n\n private async select(ref: string, values: string[]): Promise<{ ok: true }> {\n this.assertRef(ref);\n await this.ctx.page.locator(`aria-ref=${ref}`).selectOption(values);\n return { ok: true };\n }\n\n private async check(ref: string, checked: boolean): Promise<{ ok: true }> {\n this.assertRef(ref);\n const locator = this.ctx.page.locator(`aria-ref=${ref}`);\n if (checked) {\n await locator.check();\n } else {\n await locator.uncheck();\n }\n return { ok: true };\n }\n\n private async press(key: string): Promise<{ ok: true }> {\n if (!ALLOWED_KEYS.has(key)) {\n throw new Error(`Disallowed key: ${key}`);\n }\n await this.ctx.page.keyboard.press(key);\n return { ok: true };\n }\n\n private assertRef(ref: string): void {\n if (!/^(?:f\\d+)?e\\d+$/.test(ref)) {\n throw new Error(`Invalid aria-ref format: ${ref}`);\n }\n }\n\n private async assertAllowedOrigin(): Promise<void> {\n const url = this.ctx.page.url();\n if (url === 'about:blank') return;\n\n let origin: string;\n try {\n origin = new URL(url).origin;\n } catch {\n throw new Error(`Invalid page URL: ${url}`);\n }\n\n if (!this.ctx.allowedOrigins.includes(origin)) {\n throw new Error(`Origin not allowed: ${origin}`);\n }\n }\n}\n\nfunction readTarget(args: Record<string, unknown>): string {\n const target = args.target ?? args.ref;\n if (typeof target !== 'string' || !target) {\n throw new Error('Missing snapshot target/ref');\n }\n return target;\n}\n\nfunction readText(args: Record<string, unknown>): string {\n const text = args.text ?? args.value;\n if (typeof text !== 'string') {\n throw new Error('Missing text/value to type');\n }\n return text;\n}\n\nfunction readSelectValues(args: Record<string, unknown>): string[] {\n if (Array.isArray(args.values)) {\n return args.values.map(String);\n }\n if (typeof args.value === 'string') {\n return [args.value];\n }\n throw new Error('Missing values to select');\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import type { AgentConfig, ChatResponse, ModelClient } from './types.js';
2
+ export declare function normalizeOpenAICompatibleBaseURL(baseURL: string): string;
3
+ export declare function loadAgentConfig(): AgentConfig;
4
+ export declare function createModelClient(config: AgentConfig): ModelClient;
5
+ export declare function parseOpenAIChatResponse(response: unknown, baseURL: string, model: string): ChatResponse;
6
+ //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/agent/model.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EAEX,YAAY,EACZ,WAAW,EAEZ,MAAM,YAAY,CAAC;AAEpB,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKxE;AAED,wBAAgB,eAAe,IAAI,WAAW,CAgB7C;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAoClE;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GACZ,YAAY,CAoCd"}