web-task-api 0.2.1
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/CHANGELOG.md +25 -0
- package/README.md +284 -0
- package/dist/scripts/demo.d.ts +1 -0
- package/dist/scripts/demo.js +32 -0
- package/dist/scripts/demo.js.map +1 -0
- package/dist/scripts/profile-login.d.ts +1 -0
- package/dist/scripts/profile-login.js +38 -0
- package/dist/scripts/profile-login.js.map +1 -0
- package/dist/src/agents/auto-agent.d.ts +22 -0
- package/dist/src/agents/auto-agent.js +54 -0
- package/dist/src/agents/auto-agent.js.map +1 -0
- package/dist/src/agents/cliproxy-agent.d.ts +18 -0
- package/dist/src/agents/cliproxy-agent.js +137 -0
- package/dist/src/agents/cliproxy-agent.js.map +1 -0
- package/dist/src/agents/index.d.ts +2 -0
- package/dist/src/agents/index.js +17 -0
- package/dist/src/agents/index.js.map +1 -0
- package/dist/src/agents/mock-agent.d.ts +15 -0
- package/dist/src/agents/mock-agent.js +132 -0
- package/dist/src/agents/mock-agent.js.map +1 -0
- package/dist/src/agents/opencode-agent.d.ts +20 -0
- package/dist/src/agents/opencode-agent.js +122 -0
- package/dist/src/agents/opencode-agent.js.map +1 -0
- package/dist/src/agents/planner-prompt.d.ts +6 -0
- package/dist/src/agents/planner-prompt.js +116 -0
- package/dist/src/agents/planner-prompt.js.map +1 -0
- package/dist/src/browser/session.d.ts +41 -0
- package/dist/src/browser/session.js +267 -0
- package/dist/src/browser/session.js.map +1 -0
- package/dist/src/client.d.ts +44 -0
- package/dist/src/client.js +59 -0
- package/dist/src/client.js.map +1 -0
- package/dist/src/config.d.ts +16 -0
- package/dist/src/config.js +18 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +15 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/lib.d.ts +6 -0
- package/dist/src/lib.js +5 -0
- package/dist/src/lib.js.map +1 -0
- package/dist/src/mcp-server.d.ts +3 -0
- package/dist/src/mcp-server.js +191 -0
- package/dist/src/mcp-server.js.map +1 -0
- package/dist/src/mcp.d.ts +2 -0
- package/dist/src/mcp.js +14 -0
- package/dist/src/mcp.js.map +1 -0
- package/dist/src/recipes/registry.d.ts +21 -0
- package/dist/src/recipes/registry.js +38 -0
- package/dist/src/recipes/registry.js.map +1 -0
- package/dist/src/server/app.d.ts +5 -0
- package/dist/src/server/app.js +89 -0
- package/dist/src/server/app.js.map +1 -0
- package/dist/src/sessions/store.d.ts +48 -0
- package/dist/src/sessions/store.js +84 -0
- package/dist/src/sessions/store.js.map +1 -0
- package/dist/src/storage/run-store.d.ts +12 -0
- package/dist/src/storage/run-store.js +30 -0
- package/dist/src/storage/run-store.js.map +1 -0
- package/dist/src/tasks/errors.d.ts +5 -0
- package/dist/src/tasks/errors.js +11 -0
- package/dist/src/tasks/errors.js.map +1 -0
- package/dist/src/tasks/output-validator.d.ts +1 -0
- package/dist/src/tasks/output-validator.js +21 -0
- package/dist/src/tasks/output-validator.js.map +1 -0
- package/dist/src/tasks/runner.d.ts +38 -0
- package/dist/src/tasks/runner.js +236 -0
- package/dist/src/tasks/runner.js.map +1 -0
- package/dist/src/tasks/schemas.d.ts +266 -0
- package/dist/src/tasks/schemas.js +67 -0
- package/dist/src/tasks/schemas.js.map +1 -0
- package/dist/tests/agent-adapters.test.d.ts +1 -0
- package/dist/tests/agent-adapters.test.js +87 -0
- package/dist/tests/agent-adapters.test.js.map +1 -0
- package/dist/tests/agent-selection.test.d.ts +1 -0
- package/dist/tests/agent-selection.test.js +26 -0
- package/dist/tests/agent-selection.test.js.map +1 -0
- package/dist/tests/auto-agent.test.d.ts +1 -0
- package/dist/tests/auto-agent.test.js +86 -0
- package/dist/tests/auto-agent.test.js.map +1 -0
- package/dist/tests/browser-session.test.d.ts +1 -0
- package/dist/tests/browser-session.test.js +41 -0
- package/dist/tests/browser-session.test.js.map +1 -0
- package/dist/tests/client.test.d.ts +1 -0
- package/dist/tests/client.test.js +35 -0
- package/dist/tests/client.test.js.map +1 -0
- package/dist/tests/fixture-site.d.ts +6 -0
- package/dist/tests/fixture-site.js +93 -0
- package/dist/tests/fixture-site.js.map +1 -0
- package/dist/tests/mcp.test.d.ts +1 -0
- package/dist/tests/mcp.test.js +186 -0
- package/dist/tests/mcp.test.js.map +1 -0
- package/dist/tests/output-validator.test.d.ts +1 -0
- package/dist/tests/output-validator.test.js +27 -0
- package/dist/tests/output-validator.test.js.map +1 -0
- package/dist/tests/request-validation.test.d.ts +1 -0
- package/dist/tests/request-validation.test.js +25 -0
- package/dist/tests/request-validation.test.js.map +1 -0
- package/dist/tests/runner-options.test.d.ts +1 -0
- package/dist/tests/runner-options.test.js +44 -0
- package/dist/tests/runner-options.test.js.map +1 -0
- package/dist/tests/session-api.test.d.ts +1 -0
- package/dist/tests/session-api.test.js +244 -0
- package/dist/tests/session-api.test.js.map +1 -0
- package/dist/tests/session-client.test.d.ts +1 -0
- package/dist/tests/session-client.test.js +28 -0
- package/dist/tests/session-client.test.js.map +1 -0
- package/dist/tests/task-api-failure.test.d.ts +1 -0
- package/dist/tests/task-api-failure.test.js +39 -0
- package/dist/tests/task-api-failure.test.js.map +1 -0
- package/dist/tests/task-api.test.d.ts +1 -0
- package/dist/tests/task-api.test.js +50 -0
- package/dist/tests/task-api.test.js.map +1 -0
- package/docs/design.md +513 -0
- package/docs/releasing.md +62 -0
- package/package.json +78 -0
- package/recipes/dexscreener-token-read.json +19 -0
- package/recipes/fixture-catalog.json +14 -0
- package/recipes/generic-search.json +14 -0
- package/recipes/gmgn-token-read.json +19 -0
- package/server.json +79 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AgentAdapter, AgentTurnInput, PlannedAction, TaskRequest } from "../tasks/schemas.js";
|
|
2
|
+
export declare class MockAgent implements AgentAdapter {
|
|
3
|
+
private readonly request;
|
|
4
|
+
constructor(request: TaskRequest);
|
|
5
|
+
init(): Promise<void>;
|
|
6
|
+
nextAction(input: AgentTurnInput): Promise<PlannedAction>;
|
|
7
|
+
close(): Promise<void>;
|
|
8
|
+
debugInfo(): {
|
|
9
|
+
planner: string;
|
|
10
|
+
reason: string;
|
|
11
|
+
};
|
|
12
|
+
private lookupInput;
|
|
13
|
+
private findField;
|
|
14
|
+
private findButton;
|
|
15
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
export class MockAgent {
|
|
2
|
+
request;
|
|
3
|
+
constructor(request) {
|
|
4
|
+
this.request = request;
|
|
5
|
+
}
|
|
6
|
+
async init() { }
|
|
7
|
+
async nextAction(input) {
|
|
8
|
+
const queryValue = this.lookupInput(input, "query");
|
|
9
|
+
const text = input.snapshot.textPreview.toLowerCase();
|
|
10
|
+
const lastStep = input.history.at(-1);
|
|
11
|
+
const lastReadText = typeof input.lastToolResult?.text === "string" ? input.lastToolResult.text : undefined;
|
|
12
|
+
if (lastReadText) {
|
|
13
|
+
return {
|
|
14
|
+
type: "finish",
|
|
15
|
+
reason: "Structured fields were extracted from the visible result page.",
|
|
16
|
+
result: extractResult(lastReadText, input.outputSchema, input.request.input),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
const queryField = this.findField(input, ["query", "search", "term", "keyword", "q"]);
|
|
20
|
+
const alreadyFilled = lastStep?.action.type === "fill";
|
|
21
|
+
if (queryValue && queryField && !alreadyFilled && !text.includes("product:")) {
|
|
22
|
+
return {
|
|
23
|
+
type: "fill",
|
|
24
|
+
elementId: queryField.id,
|
|
25
|
+
text: String(queryValue),
|
|
26
|
+
reason: "Fill the main query field from task input.",
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
const submit = this.findButton(input, ["search", "submit", "go", "find"]);
|
|
30
|
+
const alreadySubmitted = input.history.some((step) => step.action.type === "click" || step.action.type === "press");
|
|
31
|
+
if (submit && !alreadySubmitted && !text.includes("product:")) {
|
|
32
|
+
return {
|
|
33
|
+
type: "click",
|
|
34
|
+
elementId: submit.id,
|
|
35
|
+
reason: "Submit the obvious search action.",
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (text.includes("product:") || text.includes("price:") || text.includes("stock:")) {
|
|
39
|
+
return {
|
|
40
|
+
type: "read_page",
|
|
41
|
+
reason: "Result details are visible, so read the page for extraction.",
|
|
42
|
+
maxChars: 4_000,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
if (input.request.startUrl && input.step === 1 && input.snapshot.url !== input.request.startUrl) {
|
|
46
|
+
return {
|
|
47
|
+
type: "navigate",
|
|
48
|
+
url: input.request.startUrl,
|
|
49
|
+
reason: "Navigate to the provided start URL first.",
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
type: "fail",
|
|
54
|
+
reason: "The mock agent could not find a safe next step.",
|
|
55
|
+
error: "mock_agent_stuck",
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
async close() { }
|
|
59
|
+
debugInfo() {
|
|
60
|
+
return { planner: "mock", reason: "deterministic local test agent" };
|
|
61
|
+
}
|
|
62
|
+
lookupInput(input, key) {
|
|
63
|
+
const direct = input.request.input[key];
|
|
64
|
+
if (direct !== undefined) {
|
|
65
|
+
return direct;
|
|
66
|
+
}
|
|
67
|
+
const aliases = input.recipe?.inputAliases?.[key] ?? [];
|
|
68
|
+
for (const alias of aliases) {
|
|
69
|
+
if (input.request.input[alias] !== undefined) {
|
|
70
|
+
return input.request.input[alias];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
findField(input, tokens) {
|
|
76
|
+
return input.snapshot.interactive.find((element) => {
|
|
77
|
+
if (!["input", "textarea"].includes(element.tag)) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
const haystack = [element.label, element.placeholder, element.name, element.text]
|
|
81
|
+
.filter(Boolean)
|
|
82
|
+
.join(" ")
|
|
83
|
+
.toLowerCase();
|
|
84
|
+
return tokens.some((token) => haystack.includes(token));
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
findButton(input, tokens) {
|
|
88
|
+
return input.snapshot.interactive.find((element) => {
|
|
89
|
+
const inputButton = element.tag === "input" && ["submit", "button"].includes(element.type ?? "");
|
|
90
|
+
if (!(element.tag === "button" || element.tag === "a" || inputButton)) {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
const haystack = [element.text, element.label, element.name, element.placeholder]
|
|
94
|
+
.filter(Boolean)
|
|
95
|
+
.join(" ")
|
|
96
|
+
.toLowerCase();
|
|
97
|
+
return tokens.some((token) => haystack.includes(token));
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function extractResult(text, schema, input) {
|
|
102
|
+
const result = {};
|
|
103
|
+
const schemaProperties = typeof schema?.properties === "object" && schema.properties !== null
|
|
104
|
+
? schema.properties
|
|
105
|
+
: {};
|
|
106
|
+
for (const key of Object.keys(schemaProperties)) {
|
|
107
|
+
const label = key.replace(/_/g, " ");
|
|
108
|
+
const variants = [label, toTitleCase(label)];
|
|
109
|
+
for (const variant of variants) {
|
|
110
|
+
const regex = new RegExp(`${escapeRegex(variant)}\\s*:\\s*([^\\n]+)`, "i");
|
|
111
|
+
const match = text.match(regex);
|
|
112
|
+
if (match?.[1]) {
|
|
113
|
+
result[key] = match[1].trim();
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (result.product === undefined && input.query !== undefined) {
|
|
119
|
+
result.product = input.query;
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
function toTitleCase(value) {
|
|
124
|
+
return value
|
|
125
|
+
.split(" ")
|
|
126
|
+
.map((part) => part.slice(0, 1).toUpperCase() + part.slice(1))
|
|
127
|
+
.join(" ");
|
|
128
|
+
}
|
|
129
|
+
function escapeRegex(value) {
|
|
130
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=mock-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-agent.js","sourceRoot":"","sources":["../../../src/agents/mock-agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AgentAdapter, AgentTurnInput, PlannedAction, TaskRequest } from "../tasks/schemas.js";
|
|
2
|
+
export declare class OpencodeAgent implements AgentAdapter {
|
|
3
|
+
private readonly request;
|
|
4
|
+
private client;
|
|
5
|
+
private sessionId;
|
|
6
|
+
private server?;
|
|
7
|
+
constructor(request: TaskRequest);
|
|
8
|
+
init(): Promise<void>;
|
|
9
|
+
nextAction(input: AgentTurnInput): Promise<PlannedAction>;
|
|
10
|
+
close(): Promise<void>;
|
|
11
|
+
debugInfo(): {
|
|
12
|
+
planner: string;
|
|
13
|
+
reason: string;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export declare function extractOpencodeStructuredOutput(response: any): unknown;
|
|
17
|
+
export declare function parseModel(model?: string): {
|
|
18
|
+
providerID: string;
|
|
19
|
+
modelID: string;
|
|
20
|
+
} | undefined;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { createOpencode, createOpencodeClient, } from "@opencode-ai/sdk";
|
|
2
|
+
import { DEFAULT_OPENCODE_BASE_URL, DEFAULT_OPENCODE_MODEL, } from "../config.js";
|
|
3
|
+
import { OPENCODE_ACTION_SCHEMA, buildPlannerPrompt, systemInstructions, validatePlannedAction, } from "./planner-prompt.js";
|
|
4
|
+
export class OpencodeAgent {
|
|
5
|
+
request;
|
|
6
|
+
client;
|
|
7
|
+
sessionId;
|
|
8
|
+
server;
|
|
9
|
+
constructor(request) {
|
|
10
|
+
this.request = request;
|
|
11
|
+
}
|
|
12
|
+
async init() {
|
|
13
|
+
const baseUrl = DEFAULT_OPENCODE_BASE_URL ?? (await detectRunningOpencodeUrl());
|
|
14
|
+
if (baseUrl) {
|
|
15
|
+
this.client = createOpencodeClient({ baseUrl });
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
const model = this.request.agent.model ?? DEFAULT_OPENCODE_MODEL;
|
|
19
|
+
const opencode = await createOpencode({
|
|
20
|
+
...(model ? { config: { model } } : {}),
|
|
21
|
+
});
|
|
22
|
+
this.client = opencode.client;
|
|
23
|
+
this.server = opencode.server;
|
|
24
|
+
}
|
|
25
|
+
const session = await this.client.session.create({
|
|
26
|
+
body: { title: `web-task: ${this.request.goal.slice(0, 80)}` },
|
|
27
|
+
});
|
|
28
|
+
this.sessionId = session.data.id;
|
|
29
|
+
await this.client.session.prompt({
|
|
30
|
+
path: { id: this.sessionId },
|
|
31
|
+
body: {
|
|
32
|
+
noReply: true,
|
|
33
|
+
parts: [{ type: "text", text: systemInstructions() }],
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
async nextAction(input) {
|
|
38
|
+
const model = parseModel(this.request.agent.model ?? DEFAULT_OPENCODE_MODEL);
|
|
39
|
+
const response = await this.client.session.prompt({
|
|
40
|
+
path: { id: this.sessionId },
|
|
41
|
+
body: {
|
|
42
|
+
...(model ? { model } : {}),
|
|
43
|
+
parts: [{ type: "text", text: buildPlannerPrompt(input) }],
|
|
44
|
+
format: {
|
|
45
|
+
type: "json_schema",
|
|
46
|
+
retryCount: 2,
|
|
47
|
+
schema: OPENCODE_ACTION_SCHEMA,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
const structured = normalizeOpencodeAction(extractOpencodeStructuredOutput(response));
|
|
52
|
+
if (!structured || typeof structured !== "object") {
|
|
53
|
+
throw new Error("OpenCode did not return structured_output for planner step.");
|
|
54
|
+
}
|
|
55
|
+
validatePlannedAction(structured);
|
|
56
|
+
return structured;
|
|
57
|
+
}
|
|
58
|
+
async close() {
|
|
59
|
+
if (this.server?.close) {
|
|
60
|
+
await this.server.close();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
debugInfo() {
|
|
64
|
+
return {
|
|
65
|
+
planner: "opencode",
|
|
66
|
+
reason: "OpenCode local runtime or attached server selected",
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export function extractOpencodeStructuredOutput(response) {
|
|
71
|
+
const info = response?.data?.info;
|
|
72
|
+
return info?.structured ?? info?.structured_output;
|
|
73
|
+
}
|
|
74
|
+
export function parseModel(model) {
|
|
75
|
+
if (!model) {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
const [providerID, ...rest] = model.split("/");
|
|
79
|
+
const modelID = rest.join("/");
|
|
80
|
+
if (!providerID || !modelID) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
return { providerID, modelID };
|
|
84
|
+
}
|
|
85
|
+
async function detectRunningOpencodeUrl() {
|
|
86
|
+
const candidate = "http://127.0.0.1:4096";
|
|
87
|
+
try {
|
|
88
|
+
const response = await fetch(`${candidate}/global/health`);
|
|
89
|
+
if (response.ok) {
|
|
90
|
+
return candidate;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
function normalizeOpencodeAction(action) {
|
|
99
|
+
if (!action || typeof action !== "object") {
|
|
100
|
+
return action;
|
|
101
|
+
}
|
|
102
|
+
const value = { ...action };
|
|
103
|
+
if (value.type === "fill" && typeof value.text !== "string" && typeof value.value === "string") {
|
|
104
|
+
value.text = value.value;
|
|
105
|
+
}
|
|
106
|
+
if (value.type === "select" && typeof value.value !== "string" && typeof value.text === "string") {
|
|
107
|
+
value.value = value.text;
|
|
108
|
+
}
|
|
109
|
+
if (value.type === "finish" && !value.result && typeof value.text === "string") {
|
|
110
|
+
try {
|
|
111
|
+
value.result = JSON.parse(value.text);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// ignore parse failure and let validator surface it
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (value.type === "fail" && typeof value.error !== "string" && typeof value.text === "string") {
|
|
118
|
+
value.error = value.text;
|
|
119
|
+
}
|
|
120
|
+
return value;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=opencode-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode-agent.js","sourceRoot":"","sources":["../../../src/agents/opencode-agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AgentTurnInput } from "../tasks/schemas.js";
|
|
2
|
+
export declare const ACTION_SCHEMA: Record<string, unknown>;
|
|
3
|
+
export declare const OPENCODE_ACTION_SCHEMA: Record<string, unknown>;
|
|
4
|
+
export declare function systemInstructions(): string;
|
|
5
|
+
export declare function buildPlannerPrompt(input: AgentTurnInput): string;
|
|
6
|
+
export declare function validatePlannedAction(action: unknown): void;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import AjvModule from "ajv";
|
|
2
|
+
const AjvCtor = AjvModule;
|
|
3
|
+
const ajv = new AjvCtor({ allErrors: true, strict: false });
|
|
4
|
+
export const ACTION_SCHEMA = {
|
|
5
|
+
oneOf: [
|
|
6
|
+
actionVariant("navigate", ["url"]),
|
|
7
|
+
actionVariant("click", ["elementId"]),
|
|
8
|
+
actionVariant("fill", ["elementId", "text"]),
|
|
9
|
+
actionVariant("press", ["elementId", "key"]),
|
|
10
|
+
actionVariant("select", ["elementId", "value"]),
|
|
11
|
+
actionVariant("wait_for_text", ["text"]),
|
|
12
|
+
actionVariant("read_page", []),
|
|
13
|
+
actionVariant("finish", ["result"]),
|
|
14
|
+
actionVariant("fail", ["error"]),
|
|
15
|
+
],
|
|
16
|
+
};
|
|
17
|
+
export const OPENCODE_ACTION_SCHEMA = {
|
|
18
|
+
type: "object",
|
|
19
|
+
additionalProperties: false,
|
|
20
|
+
required: ["type", "reason"],
|
|
21
|
+
properties: {
|
|
22
|
+
type: {
|
|
23
|
+
type: "string",
|
|
24
|
+
enum: [
|
|
25
|
+
"navigate",
|
|
26
|
+
"click",
|
|
27
|
+
"fill",
|
|
28
|
+
"press",
|
|
29
|
+
"select",
|
|
30
|
+
"wait_for_text",
|
|
31
|
+
"read_page",
|
|
32
|
+
"finish",
|
|
33
|
+
"fail",
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
reason: { type: "string" },
|
|
37
|
+
url: { type: "string" },
|
|
38
|
+
elementId: { type: "string" },
|
|
39
|
+
text: { type: "string" },
|
|
40
|
+
key: { type: "string" },
|
|
41
|
+
value: { type: "string" },
|
|
42
|
+
timeoutMs: { type: "number" },
|
|
43
|
+
maxChars: { type: "number" },
|
|
44
|
+
error: { type: "string" },
|
|
45
|
+
result: { type: "object", additionalProperties: true },
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
export function systemInstructions() {
|
|
49
|
+
return [
|
|
50
|
+
"You are the planning agent for a browser-task API.",
|
|
51
|
+
"You do not click raw selectors. You only act through the current snapshot and element IDs.",
|
|
52
|
+
"Choose the next single best action. Do not emit multiple actions.",
|
|
53
|
+
"Prefer outcome-oriented progress: fill obvious fields, submit obvious forms, read the page, then finish.",
|
|
54
|
+
"When the task goal is satisfied, return type=finish with a result object that fits the output schema.",
|
|
55
|
+
"If the run is blocked or impossible, return type=fail with a short machine-readable error.",
|
|
56
|
+
"Do not invent fields that are not grounded in the page or task input.",
|
|
57
|
+
].join(" ");
|
|
58
|
+
}
|
|
59
|
+
function actionVariant(type, extraRequired) {
|
|
60
|
+
return {
|
|
61
|
+
type: "object",
|
|
62
|
+
additionalProperties: false,
|
|
63
|
+
required: ["type", "reason", ...extraRequired],
|
|
64
|
+
properties: {
|
|
65
|
+
type: { type: "string", const: type },
|
|
66
|
+
reason: { type: "string" },
|
|
67
|
+
url: { type: "string" },
|
|
68
|
+
elementId: { type: "string" },
|
|
69
|
+
text: { type: "string" },
|
|
70
|
+
key: { type: "string" },
|
|
71
|
+
value: { type: "string" },
|
|
72
|
+
timeoutMs: { type: "number" },
|
|
73
|
+
maxChars: { type: "number" },
|
|
74
|
+
error: { type: "string" },
|
|
75
|
+
result: { type: "object", additionalProperties: true },
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export function buildPlannerPrompt(input) {
|
|
80
|
+
const history = input.history.slice(-6).map((step) => ({
|
|
81
|
+
step: step.index,
|
|
82
|
+
action: step.action,
|
|
83
|
+
result: step.result,
|
|
84
|
+
}));
|
|
85
|
+
return JSON.stringify({
|
|
86
|
+
role: "browser-task-planner",
|
|
87
|
+
step: input.step,
|
|
88
|
+
maxSteps: input.maxSteps,
|
|
89
|
+
goal: input.request.goal,
|
|
90
|
+
mode: input.request.mode,
|
|
91
|
+
startUrl: input.request.startUrl,
|
|
92
|
+
taskInput: input.request.input,
|
|
93
|
+
outputSchema: input.outputSchema,
|
|
94
|
+
recipe: input.recipe,
|
|
95
|
+
sessionContext: input.sessionContext,
|
|
96
|
+
lastToolResult: input.lastToolResult,
|
|
97
|
+
snapshot: input.snapshot,
|
|
98
|
+
recentHistory: history,
|
|
99
|
+
instructions: [
|
|
100
|
+
"Return the next best action as JSON matching the provided schema.",
|
|
101
|
+
"Use current element IDs only.",
|
|
102
|
+
"If result information is visible but not fully parsed, use read_page next.",
|
|
103
|
+
],
|
|
104
|
+
}, null, 2);
|
|
105
|
+
}
|
|
106
|
+
export function validatePlannedAction(action) {
|
|
107
|
+
const validate = ajv.compile(ACTION_SCHEMA);
|
|
108
|
+
if (validate(action)) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const message = validate.errors
|
|
112
|
+
?.map((error) => `${error.instancePath || "$"} ${error.message ?? "is invalid"}`.trim())
|
|
113
|
+
.join("; ") ?? "invalid action";
|
|
114
|
+
throw new Error(`Planner returned invalid action: ${message}; action=${JSON.stringify(action)}`);
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=planner-prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planner-prompt.js","sourceRoot":"","sources":["../../../src/agents/planner-prompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { PageSnapshot, PlannedAction } from "../tasks/schemas.js";
|
|
2
|
+
export type LaunchOptions = {
|
|
3
|
+
headless: boolean;
|
|
4
|
+
profile?: string | undefined;
|
|
5
|
+
userDataDir?: string | undefined;
|
|
6
|
+
storageStatePath?: string | undefined;
|
|
7
|
+
screenshotsDir: string;
|
|
8
|
+
preferChrome?: boolean | undefined;
|
|
9
|
+
protectedSiteMode?: boolean | undefined;
|
|
10
|
+
};
|
|
11
|
+
export declare class BrowserSession {
|
|
12
|
+
private readonly browser;
|
|
13
|
+
private readonly context;
|
|
14
|
+
private readonly page;
|
|
15
|
+
private readonly screenshotsDir;
|
|
16
|
+
private readonly profile?;
|
|
17
|
+
private readonly tempUserDataDir?;
|
|
18
|
+
private readonly storageStatePath?;
|
|
19
|
+
private constructor();
|
|
20
|
+
private currentElements;
|
|
21
|
+
static launch(options: LaunchOptions): Promise<BrowserSession>;
|
|
22
|
+
getProfile(): string | undefined;
|
|
23
|
+
getUserDataDirDebug(): string | undefined;
|
|
24
|
+
navigate(url: string): Promise<Record<string, unknown>>;
|
|
25
|
+
snapshot(): Promise<PageSnapshot>;
|
|
26
|
+
execute(action: Exclude<PlannedAction, {
|
|
27
|
+
type: "finish" | "fail";
|
|
28
|
+
}>): Promise<Record<string, unknown>>;
|
|
29
|
+
captureScreenshot(name: string): Promise<string>;
|
|
30
|
+
close(): Promise<void>;
|
|
31
|
+
private resolve;
|
|
32
|
+
private waitForSettled;
|
|
33
|
+
private isAntiBotPage;
|
|
34
|
+
}
|
|
35
|
+
export declare function resolveUserDataDir(profile?: string, sharedUserDataDir?: string | undefined, explicitUserDataDir?: string | undefined): Promise<{
|
|
36
|
+
userDataDir: string;
|
|
37
|
+
tempUserDataDir: undefined;
|
|
38
|
+
} | {
|
|
39
|
+
userDataDir: undefined;
|
|
40
|
+
tempUserDataDir: undefined;
|
|
41
|
+
}>;
|