@ddwang/magnitude-core 0.3.1-ddwang.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/dist/actions/desktopActions.d.ts +58 -0
- package/dist/actions/desktopActions.js +154 -0
- package/dist/actions/index.d.ts +26 -0
- package/dist/actions/index.js +11 -0
- package/dist/actions/taskActions.d.ts +8 -0
- package/dist/actions/taskActions.js +27 -0
- package/dist/actions/types.d.ts +31 -0
- package/dist/actions/types.js +5 -0
- package/dist/actions/util.d.ts +20 -0
- package/dist/actions/util.js +297 -0
- package/dist/actions/webActions.d.ts +79 -0
- package/dist/actions/webActions.js +190 -0
- package/dist/agent/browserAgent.d.ts +29 -0
- package/dist/agent/browserAgent.js +122 -0
- package/dist/agent/errors.d.ts +8 -0
- package/dist/agent/errors.js +68 -0
- package/dist/agent/index.d.ts +53 -0
- package/dist/agent/index.js +377 -0
- package/dist/agent/narrator.d.ts +4 -0
- package/dist/agent/narrator.js +63 -0
- package/dist/agent/pause.test.d.ts +1 -0
- package/dist/agent/pause.test.js +194 -0
- package/dist/ai/baml_client/async_client.d.ts +73 -0
- package/dist/ai/baml_client/async_client.js +152 -0
- package/dist/ai/baml_client/async_request.d.ts +35 -0
- package/dist/ai/baml_client/async_request.js +98 -0
- package/dist/ai/baml_client/config.d.ts +11 -0
- package/dist/ai/baml_client/config.js +20 -0
- package/dist/ai/baml_client/globals.d.ts +16 -0
- package/dist/ai/baml_client/globals.js +37 -0
- package/dist/ai/baml_client/index.d.ts +16 -0
- package/dist/ai/baml_client/index.js +41 -0
- package/dist/ai/baml_client/inlinedbaml.d.ts +19 -0
- package/dist/ai/baml_client/inlinedbaml.js +31 -0
- package/dist/ai/baml_client/parser.d.ts +53 -0
- package/dist/ai/baml_client/parser.js +86 -0
- package/dist/ai/baml_client/partial_types.d.ts +61 -0
- package/dist/ai/baml_client/partial_types.js +10 -0
- package/dist/ai/baml_client/sync_client.d.ts +50 -0
- package/dist/ai/baml_client/sync_client.js +100 -0
- package/dist/ai/baml_client/sync_request.d.ts +35 -0
- package/dist/ai/baml_client/sync_request.js +98 -0
- package/dist/ai/baml_client/tracing.d.ts +16 -0
- package/dist/ai/baml_client/tracing.js +18 -0
- package/dist/ai/baml_client/type_builder.d.ts +38 -0
- package/dist/ai/baml_client/type_builder.js +96 -0
- package/dist/ai/baml_client/types.d.ts +69 -0
- package/dist/ai/baml_client/types.js +15 -0
- package/dist/ai/claudeCode.d.ts +1 -0
- package/dist/ai/claudeCode.js +186 -0
- package/dist/ai/modelHarness.d.ts +39 -0
- package/dist/ai/modelHarness.js +189 -0
- package/dist/ai/multiModelHarness.d.ts +27 -0
- package/dist/ai/multiModelHarness.js +52 -0
- package/dist/ai/types.d.ts +90 -0
- package/dist/ai/types.js +5 -0
- package/dist/ai/util.d.ts +13 -0
- package/dist/ai/util.js +165 -0
- package/dist/cli.d.ts +0 -0
- package/dist/cli.js +3 -0
- package/dist/common/actions.d.ts +0 -0
- package/dist/common/actions.js +14 -0
- package/dist/common/events.d.ts +15 -0
- package/dist/common/events.js +3 -0
- package/dist/common/failure.d.ts +68 -0
- package/dist/common/failure.js +1 -0
- package/dist/common/index.d.ts +3 -0
- package/dist/common/index.js +3 -0
- package/dist/common/retry.d.ts +16 -0
- package/dist/common/retry.js +30 -0
- package/dist/common/util.d.ts +23 -0
- package/dist/common/util.js +132 -0
- package/dist/connectors/browserConnector.d.ts +40 -0
- package/dist/connectors/browserConnector.js +127 -0
- package/dist/connectors/desktopConnector.d.ts +58 -0
- package/dist/connectors/desktopConnector.js +68 -0
- package/dist/connectors/index.d.ts +10 -0
- package/dist/connectors/index.js +2 -0
- package/dist/index.cjs +6143 -0
- package/dist/index.d.cts +825 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +26 -0
- package/dist/index.mjs +6097 -0
- package/dist/logger.d.ts +3 -0
- package/dist/logger.js +15 -0
- package/dist/memory/agentMemory.d.ts +37 -0
- package/dist/memory/agentMemory.js +121 -0
- package/dist/memory/image.d.ts +26 -0
- package/dist/memory/image.js +106 -0
- package/dist/memory/index.d.ts +3 -0
- package/dist/memory/index.js +3 -0
- package/dist/memory/masking.d.ts +7 -0
- package/dist/memory/masking.js +141 -0
- package/dist/memory/masking.test.d.ts +1 -0
- package/dist/memory/masking.test.js +117 -0
- package/dist/memory/observation.d.ts +38 -0
- package/dist/memory/observation.js +79 -0
- package/dist/memory/rendering/index.d.ts +10 -0
- package/dist/memory/rendering/index.js +13 -0
- package/dist/memory/rendering/renderJsonParts.d.ts +3 -0
- package/dist/memory/rendering/renderJsonParts.js +115 -0
- package/dist/memory/rendering/renderJsonParts.test.d.ts +1 -0
- package/dist/memory/rendering/renderJsonParts.test.js +217 -0
- package/dist/memory/rendering/renderXmlParts.d.ts +7 -0
- package/dist/memory/rendering/renderXmlParts.js +127 -0
- package/dist/memory/serde.d.ts +20 -0
- package/dist/memory/serde.js +81 -0
- package/dist/memory/util.d.ts +2 -0
- package/dist/memory/util.js +17 -0
- package/dist/telemetry/events.d.ts +9 -0
- package/dist/telemetry/events.js +80 -0
- package/dist/telemetry/index.d.ts +6 -0
- package/dist/telemetry/index.js +91 -0
- package/dist/types.d.ts +30 -0
- package/dist/types.js +1 -0
- package/dist/util.d.ts +1 -0
- package/dist/util.js +12 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +3 -0
- package/dist/web/browserProvider.d.ts +23 -0
- package/dist/web/browserProvider.js +153 -0
- package/dist/web/harness.d.ts +102 -0
- package/dist/web/harness.js +340 -0
- package/dist/web/stability.d.ts +57 -0
- package/dist/web/stability.js +316 -0
- package/dist/web/tabs.d.ts +58 -0
- package/dist/web/tabs.js +293 -0
- package/dist/web/transformer.d.ts +7 -0
- package/dist/web/transformer.js +41 -0
- package/dist/web/types.d.ts +32 -0
- package/dist/web/types.js +2 -0
- package/dist/web/util.d.ts +3 -0
- package/dist/web/util.js +81 -0
- package/dist/web/visualizer/cursor.d.ts +16 -0
- package/dist/web/visualizer/cursor.js +152 -0
- package/dist/web/visualizer/index.d.ts +22 -0
- package/dist/web/visualizer/index.js +47 -0
- package/dist/web/visualizer/mouseEffects.d.ts +18 -0
- package/dist/web/visualizer/mouseEffects.js +287 -0
- package/dist/web/visualizer/typeEffects.d.ts +10 -0
- package/dist/web/visualizer/typeEffects.js +190 -0
- package/package.json +71 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { ActionDefinition } from ".";
|
|
2
|
+
export declare const clickCoordAction: ActionDefinition<{
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
}>;
|
|
6
|
+
export declare const mouseDoubleClickAction: ActionDefinition<{
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
}>;
|
|
10
|
+
export declare const mouseRightClickAction: ActionDefinition<{
|
|
11
|
+
x: number;
|
|
12
|
+
y: number;
|
|
13
|
+
}>;
|
|
14
|
+
export declare const mouseDragAction: ActionDefinition<{
|
|
15
|
+
from: {
|
|
16
|
+
x: number;
|
|
17
|
+
y: number;
|
|
18
|
+
};
|
|
19
|
+
to: {
|
|
20
|
+
x: number;
|
|
21
|
+
y: number;
|
|
22
|
+
};
|
|
23
|
+
}>;
|
|
24
|
+
export declare const typeAction: ActionDefinition<{
|
|
25
|
+
content: string;
|
|
26
|
+
}>;
|
|
27
|
+
export declare const keyboardEnterAction: ActionDefinition<any>;
|
|
28
|
+
export declare const keyboardTabAction: ActionDefinition<any>;
|
|
29
|
+
export declare const keyboardBackspaceAction: ActionDefinition<any>;
|
|
30
|
+
export declare const keyboardSelectAllAction: ActionDefinition<any>;
|
|
31
|
+
export declare const scrollCoordAction: ActionDefinition<{
|
|
32
|
+
x: number;
|
|
33
|
+
y: number;
|
|
34
|
+
deltaX: number;
|
|
35
|
+
deltaY: number;
|
|
36
|
+
}>;
|
|
37
|
+
export declare const switchTabAction: ActionDefinition<{
|
|
38
|
+
index: number;
|
|
39
|
+
}>;
|
|
40
|
+
export declare const newTabAction: ActionDefinition<{}>;
|
|
41
|
+
export declare const navigateAction: ActionDefinition<{
|
|
42
|
+
url: string;
|
|
43
|
+
}>;
|
|
44
|
+
export declare const goBackAction: ActionDefinition<{}>;
|
|
45
|
+
export declare const waitAction: ActionDefinition<{
|
|
46
|
+
seconds: number;
|
|
47
|
+
}>;
|
|
48
|
+
export declare const webActions: readonly [ActionDefinition<{
|
|
49
|
+
x: number;
|
|
50
|
+
y: number;
|
|
51
|
+
}>, ActionDefinition<{
|
|
52
|
+
x: number;
|
|
53
|
+
y: number;
|
|
54
|
+
}>, ActionDefinition<{
|
|
55
|
+
x: number;
|
|
56
|
+
y: number;
|
|
57
|
+
}>, ActionDefinition<{
|
|
58
|
+
x: number;
|
|
59
|
+
y: number;
|
|
60
|
+
deltaX: number;
|
|
61
|
+
deltaY: number;
|
|
62
|
+
}>, ActionDefinition<{
|
|
63
|
+
from: {
|
|
64
|
+
x: number;
|
|
65
|
+
y: number;
|
|
66
|
+
};
|
|
67
|
+
to: {
|
|
68
|
+
x: number;
|
|
69
|
+
y: number;
|
|
70
|
+
};
|
|
71
|
+
}>, ActionDefinition<{}>, ActionDefinition<{
|
|
72
|
+
index: number;
|
|
73
|
+
}>, ActionDefinition<{
|
|
74
|
+
url: string;
|
|
75
|
+
}>, ActionDefinition<{
|
|
76
|
+
content: string;
|
|
77
|
+
}>, ActionDefinition<any>, ActionDefinition<any>, ActionDefinition<any>, ActionDefinition<any>, ActionDefinition<{
|
|
78
|
+
seconds: number;
|
|
79
|
+
}>];
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { createAction } from ".";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { BrowserConnector } from "@/connectors/browserConnector"; // Changed from WebInteractionFacet
|
|
4
|
+
export const clickCoordAction = createAction({
|
|
5
|
+
name: 'mouse:click',
|
|
6
|
+
description: "Click something",
|
|
7
|
+
schema: z.object({
|
|
8
|
+
x: z.number().int(),
|
|
9
|
+
y: z.number().int(),
|
|
10
|
+
}),
|
|
11
|
+
resolver: async ({ input: { x, y }, agent }) => {
|
|
12
|
+
const web = agent.require(BrowserConnector);
|
|
13
|
+
const harness = web.getHarness();
|
|
14
|
+
await harness.click({ x, y });
|
|
15
|
+
},
|
|
16
|
+
render: ({ x, y }) => `⊙ click (${x}, ${y})`
|
|
17
|
+
});
|
|
18
|
+
export const mouseDoubleClickAction = createAction({
|
|
19
|
+
name: 'mouse:double_click',
|
|
20
|
+
schema: z.object({
|
|
21
|
+
x: z.number().int(),
|
|
22
|
+
y: z.number().int(),
|
|
23
|
+
}),
|
|
24
|
+
resolver: async ({ input: { x, y }, agent }) => {
|
|
25
|
+
const web = agent.require(BrowserConnector);
|
|
26
|
+
const harness = web.getHarness();
|
|
27
|
+
await harness.doubleClick({ x, y });
|
|
28
|
+
},
|
|
29
|
+
render: ({ x, y }) => `⊙ double click (${x}, ${y})`
|
|
30
|
+
});
|
|
31
|
+
export const mouseRightClickAction = createAction({
|
|
32
|
+
name: 'mouse:right_click',
|
|
33
|
+
schema: z.object({
|
|
34
|
+
x: z.number().int(),
|
|
35
|
+
y: z.number().int(),
|
|
36
|
+
}),
|
|
37
|
+
resolver: async ({ input: { x, y }, agent }) => {
|
|
38
|
+
await agent.require(BrowserConnector).getHarness().rightClick({ x, y });
|
|
39
|
+
},
|
|
40
|
+
render: ({ x, y }) => `⊙ right click (${x}, ${y})`
|
|
41
|
+
});
|
|
42
|
+
export const mouseDragAction = createAction({
|
|
43
|
+
name: 'mouse:drag',
|
|
44
|
+
description: "Click and hold mouse in one location and release in another",
|
|
45
|
+
schema: z.object({
|
|
46
|
+
from: z.object({ x: z.number().int(), y: z.number().int() }),
|
|
47
|
+
to: z.object({ x: z.number().int(), y: z.number().int() })
|
|
48
|
+
}),
|
|
49
|
+
resolver: async ({ input: { from, to }, agent }) => {
|
|
50
|
+
const web = agent.require(BrowserConnector);
|
|
51
|
+
const harness = web.getHarness();
|
|
52
|
+
await harness.drag({ x1: from.x, y1: from.y, x2: to.x, y2: to.y });
|
|
53
|
+
},
|
|
54
|
+
render: ({ from, to }) => `⤡ drag (${from.x}, ${from.y}) -> (${to.x}, ${to.y})`
|
|
55
|
+
});
|
|
56
|
+
export const typeAction = createAction({
|
|
57
|
+
name: 'keyboard:type',
|
|
58
|
+
description: "Make sure to click where you need to type first", // make sure you click into it first
|
|
59
|
+
schema: z.object({
|
|
60
|
+
content: z.string().describe("Content to type"),
|
|
61
|
+
}),
|
|
62
|
+
resolver: async ({ input: { content }, agent }) => {
|
|
63
|
+
const webConnector = agent.require(BrowserConnector);
|
|
64
|
+
const harness = webConnector.getHarness();
|
|
65
|
+
await harness.type({ content });
|
|
66
|
+
},
|
|
67
|
+
render: ({ content }) => `⌨︎ type "${content}"`
|
|
68
|
+
});
|
|
69
|
+
export const keyboardEnterAction = createAction({
|
|
70
|
+
name: 'keyboard:enter',
|
|
71
|
+
resolver: async ({ agent }) => {
|
|
72
|
+
await agent.require(BrowserConnector).getHarness().enter();
|
|
73
|
+
},
|
|
74
|
+
render: () => `⏎ press enter`
|
|
75
|
+
});
|
|
76
|
+
export const keyboardTabAction = createAction({
|
|
77
|
+
name: 'keyboard:tab',
|
|
78
|
+
resolver: async ({ agent }) => {
|
|
79
|
+
await agent.require(BrowserConnector).getHarness().tab();
|
|
80
|
+
},
|
|
81
|
+
render: () => `⇥ press tab`
|
|
82
|
+
});
|
|
83
|
+
export const keyboardBackspaceAction = createAction({
|
|
84
|
+
name: 'keyboard:backspace',
|
|
85
|
+
resolver: async ({ agent }) => {
|
|
86
|
+
await agent.require(BrowserConnector).getHarness().backspace();
|
|
87
|
+
},
|
|
88
|
+
render: () => `⌫ press backspace`
|
|
89
|
+
});
|
|
90
|
+
export const keyboardSelectAllAction = createAction({
|
|
91
|
+
name: 'keyboard:select_all',
|
|
92
|
+
description: "Select all content in the active text area (CTRL+A)",
|
|
93
|
+
resolver: async ({ input: { content }, agent }) => {
|
|
94
|
+
await agent.require(BrowserConnector).getHarness().selectAll();
|
|
95
|
+
},
|
|
96
|
+
render: () => `⬚ select all`
|
|
97
|
+
});
|
|
98
|
+
export const scrollCoordAction = createAction({
|
|
99
|
+
name: 'mouse:scroll',
|
|
100
|
+
description: "Hover mouse over target and scroll",
|
|
101
|
+
schema: z.object({
|
|
102
|
+
x: z.number().int(),
|
|
103
|
+
y: z.number().int(),
|
|
104
|
+
deltaX: z.number().int().describe("Pixels to scroll horizontally"),
|
|
105
|
+
deltaY: z.number().int().describe("Pixels to scroll vertically"),
|
|
106
|
+
}),
|
|
107
|
+
resolver: async ({ input: { x, y, deltaX, deltaY }, agent }) => {
|
|
108
|
+
const webConnector = agent.require(BrowserConnector);
|
|
109
|
+
const harness = webConnector.getHarness();
|
|
110
|
+
await harness.scroll({ x, y, deltaX, deltaY });
|
|
111
|
+
},
|
|
112
|
+
render: ({ x, y, deltaX, deltaY }) => `↕ scroll (${deltaX}px, ${deltaY}px)`
|
|
113
|
+
});
|
|
114
|
+
// Grounding agnostic
|
|
115
|
+
export const switchTabAction = createAction({
|
|
116
|
+
name: 'browser:tab:switch',
|
|
117
|
+
description: "Switch to a tab that is already open",
|
|
118
|
+
schema: z.object({
|
|
119
|
+
index: z.number().int().describe("Index of tab to switch to"),
|
|
120
|
+
}),
|
|
121
|
+
resolver: async ({ input: { index }, agent }) => {
|
|
122
|
+
const webConnector = agent.require(BrowserConnector);
|
|
123
|
+
const harness = webConnector.getHarness();
|
|
124
|
+
await harness.switchTab({ index });
|
|
125
|
+
},
|
|
126
|
+
render: ({ index }) => `⧉ switch to tab ${index}`
|
|
127
|
+
});
|
|
128
|
+
export const newTabAction = createAction({
|
|
129
|
+
name: 'browser:tab:new',
|
|
130
|
+
description: "Open and switch to a new tab",
|
|
131
|
+
schema: z.object({}),
|
|
132
|
+
resolver: async ({ agent }) => {
|
|
133
|
+
const webConnector = agent.require(BrowserConnector);
|
|
134
|
+
const harness = webConnector.getHarness();
|
|
135
|
+
await harness.newTab();
|
|
136
|
+
},
|
|
137
|
+
render: () => `⊞ open new tab`
|
|
138
|
+
});
|
|
139
|
+
export const navigateAction = createAction({
|
|
140
|
+
name: 'browser:nav',
|
|
141
|
+
description: "Navigate to a URL directly",
|
|
142
|
+
schema: z.object({
|
|
143
|
+
url: z.string().describe('URL to navigate to'),
|
|
144
|
+
}),
|
|
145
|
+
resolver: async ({ input: { url }, agent }) => {
|
|
146
|
+
const webConnector = agent.require(BrowserConnector);
|
|
147
|
+
const harness = webConnector.getHarness();
|
|
148
|
+
await harness.navigate(url);
|
|
149
|
+
},
|
|
150
|
+
render: ({ url }) => `⛓︎ navigate to ${url}`
|
|
151
|
+
});
|
|
152
|
+
export const goBackAction = createAction({
|
|
153
|
+
name: 'browser:nav:back',
|
|
154
|
+
description: "Go back",
|
|
155
|
+
schema: z.object({}),
|
|
156
|
+
resolver: async ({ agent }) => {
|
|
157
|
+
const webConnector = agent.require(BrowserConnector);
|
|
158
|
+
const harness = webConnector.getHarness();
|
|
159
|
+
await harness.goBack();
|
|
160
|
+
},
|
|
161
|
+
render: () => `← navigate back`
|
|
162
|
+
});
|
|
163
|
+
// gets overused currently if we include this
|
|
164
|
+
export const waitAction = createAction({
|
|
165
|
+
name: 'wait',
|
|
166
|
+
description: "Actions include smart waiting automatically - so only use this when a significant additional wait is clearly required.",
|
|
167
|
+
schema: z.object({
|
|
168
|
+
seconds: z.number()
|
|
169
|
+
}),
|
|
170
|
+
resolver: async ({ input: { seconds }, agent }) => {
|
|
171
|
+
await new Promise((resolve) => setTimeout(resolve, seconds * 1000));
|
|
172
|
+
},
|
|
173
|
+
render: ({ seconds }) => `◴ wait for ${seconds}s`
|
|
174
|
+
});
|
|
175
|
+
export const webActions = [
|
|
176
|
+
clickCoordAction,
|
|
177
|
+
mouseDoubleClickAction,
|
|
178
|
+
mouseRightClickAction,
|
|
179
|
+
scrollCoordAction,
|
|
180
|
+
mouseDragAction,
|
|
181
|
+
newTabAction,
|
|
182
|
+
switchTabAction,
|
|
183
|
+
navigateAction,
|
|
184
|
+
typeAction,
|
|
185
|
+
keyboardEnterAction,
|
|
186
|
+
keyboardTabAction,
|
|
187
|
+
keyboardBackspaceAction,
|
|
188
|
+
keyboardSelectAllAction,
|
|
189
|
+
waitAction,
|
|
190
|
+
];
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { BrowserContext, Page } from "playwright";
|
|
2
|
+
import { Agent, AgentOptions } from ".";
|
|
3
|
+
import { BrowserConnectorOptions } from "@/connectors/browserConnector";
|
|
4
|
+
import { Schema, ZodSchema } from "zod";
|
|
5
|
+
import z from "zod";
|
|
6
|
+
import EventEmitter from "eventemitter3";
|
|
7
|
+
export declare function startBrowserAgent(options?: AgentOptions & BrowserConnectorOptions & {
|
|
8
|
+
narrate?: boolean;
|
|
9
|
+
}): Promise<BrowserAgent>;
|
|
10
|
+
type ExtractedOutput = string | number | boolean | bigint | Date | null | undefined | {
|
|
11
|
+
[key: string]: ExtractedOutput;
|
|
12
|
+
} | ExtractedOutput[];
|
|
13
|
+
export interface BrowserAgentEvents {
|
|
14
|
+
'nav': (url: string) => void;
|
|
15
|
+
'extractStarted': (instructions: string, schema: ZodSchema) => void;
|
|
16
|
+
'extractDone': (instructions: string, data: ExtractedOutput) => void;
|
|
17
|
+
}
|
|
18
|
+
export declare class BrowserAgent extends Agent {
|
|
19
|
+
readonly browserAgentEvents: EventEmitter<BrowserAgentEvents>;
|
|
20
|
+
constructor({ agentOptions, browserOptions }: {
|
|
21
|
+
agentOptions?: Partial<AgentOptions>;
|
|
22
|
+
browserOptions?: BrowserConnectorOptions;
|
|
23
|
+
});
|
|
24
|
+
get page(): Page;
|
|
25
|
+
get context(): BrowserContext;
|
|
26
|
+
nav(url: string): Promise<void>;
|
|
27
|
+
extract<T extends Schema>(instructions: string, schema: T): Promise<z.infer<T>>;
|
|
28
|
+
}
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { Agent } from ".";
|
|
2
|
+
import { BrowserConnector } from "@/connectors/browserConnector";
|
|
3
|
+
import { buildDefaultBrowserAgentOptions } from "@/ai/util";
|
|
4
|
+
import { narrateBrowserAgent } from "./narrator";
|
|
5
|
+
import { partitionHtml, serializeToMarkdown } from 'magnitude-extract';
|
|
6
|
+
import EventEmitter from "eventemitter3";
|
|
7
|
+
import { retry } from "@/common/retry";
|
|
8
|
+
// export interface StartAgentWithWebOptions {
|
|
9
|
+
// agentBaseOptions?: Partial<AgentOptions>;
|
|
10
|
+
// webConnectorOptions?: BrowserConnectorOptions;
|
|
11
|
+
// }
|
|
12
|
+
const DEFAULT_BROWSER_AGENT_TEMP = 0.2;
|
|
13
|
+
// Helper function to start a web agent
|
|
14
|
+
export async function startBrowserAgent(options //StartAgentWithWebOptions = {}
|
|
15
|
+
) {
|
|
16
|
+
//console.log("sba options:", options);
|
|
17
|
+
const { agentOptions, browserOptions } = buildDefaultBrowserAgentOptions({ agentOptions: options ?? {}, browserOptions: options ?? {} });
|
|
18
|
+
const agent = new BrowserAgent({
|
|
19
|
+
agentOptions: agentOptions,
|
|
20
|
+
browserOptions: browserOptions,
|
|
21
|
+
});
|
|
22
|
+
if (options?.narrate || process.env.MAGNITUDE_NARRATE) {
|
|
23
|
+
narrateBrowserAgent(agent);
|
|
24
|
+
//agent.events.on('actionStarted', (action: any) => { console.log(action) })
|
|
25
|
+
}
|
|
26
|
+
//console.log('starting agent')
|
|
27
|
+
await agent.start();
|
|
28
|
+
//console.log('agent started');
|
|
29
|
+
return agent;
|
|
30
|
+
}
|
|
31
|
+
async function getFullPageContent(page) {
|
|
32
|
+
// 1. Get all iframe element handles
|
|
33
|
+
const iframeHandles = await page.locator('iframe').elementHandles();
|
|
34
|
+
// 2. Iterate through each iframe handle
|
|
35
|
+
for (const iframeHandle of iframeHandles) {
|
|
36
|
+
// 3. Get the Frame object for the iframe
|
|
37
|
+
const frame = await iframeHandle.contentFrame();
|
|
38
|
+
if (frame) {
|
|
39
|
+
// 4. Get the HTML content of the iframe
|
|
40
|
+
const iframeContent = await frame.content();
|
|
41
|
+
// 5. Use evaluate to replace the iframe element with its content.
|
|
42
|
+
// We pass the content as an argument to avoid issues with string escaping.
|
|
43
|
+
await iframeHandle.evaluate((iframeNode, { content }) => {
|
|
44
|
+
// Create a new div element to hold the iframe's content
|
|
45
|
+
const div = document.createElement('div');
|
|
46
|
+
// Use DOMParser to handle Trusted Types restrictions
|
|
47
|
+
const parser = new DOMParser();
|
|
48
|
+
const doc = parser.parseFromString(content, 'text/html');
|
|
49
|
+
// Move all body children to the div
|
|
50
|
+
while (doc.body.firstChild) {
|
|
51
|
+
div.appendChild(doc.body.firstChild);
|
|
52
|
+
}
|
|
53
|
+
// Also preserve any head elements that might be important (styles, etc)
|
|
54
|
+
const headElements = doc.head.querySelectorAll('style, link[rel="stylesheet"]');
|
|
55
|
+
headElements.forEach(el => div.appendChild(el.cloneNode(true)));
|
|
56
|
+
// Add a data-attribute to mark that this was an expanded iframe
|
|
57
|
+
div.dataset.expandedFromIframe = 'true';
|
|
58
|
+
div.dataset.iframeSrc = iframeNode.getAttribute('src') || '';
|
|
59
|
+
// Replace the iframeNode with the new div
|
|
60
|
+
iframeNode.parentNode?.replaceChild(div, iframeNode);
|
|
61
|
+
}, { content: iframeContent });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// 6. Return the final, modified page content
|
|
65
|
+
return page.content();
|
|
66
|
+
}
|
|
67
|
+
export class BrowserAgent extends Agent {
|
|
68
|
+
browserAgentEvents = new EventEmitter();
|
|
69
|
+
constructor({ agentOptions, browserOptions }) {
|
|
70
|
+
//console.log("agent options:", agent);
|
|
71
|
+
//console.log("browser options:", browserOptions);
|
|
72
|
+
super({
|
|
73
|
+
...agentOptions,
|
|
74
|
+
connectors: [new BrowserConnector(browserOptions || {}), ...(agentOptions?.connectors ?? [])]
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
get page() {
|
|
78
|
+
return this.require(BrowserConnector).getHarness().page;
|
|
79
|
+
}
|
|
80
|
+
get context() {
|
|
81
|
+
return this.require(BrowserConnector).getHarness().context;
|
|
82
|
+
}
|
|
83
|
+
async nav(url) {
|
|
84
|
+
this.browserAgentEvents.emit('nav', url);
|
|
85
|
+
await this.require(BrowserConnector).getHarness().navigate(url);
|
|
86
|
+
}
|
|
87
|
+
async extract(instructions, schema) {
|
|
88
|
+
this.browserAgentEvents.emit('extractStarted', instructions, schema);
|
|
89
|
+
//const htmlContent = await this.page.content();
|
|
90
|
+
const htmlContent = await retry(async () => await getFullPageContent(this.page), { retries: 5, delay: 200, exponential: true });
|
|
91
|
+
// const accessibilityTree = await this.page.accessibility.snapshot({ interestingOnly: true });
|
|
92
|
+
// const pageRepr = renderMinimalAccessibilityTree(accessibilityTree);
|
|
93
|
+
const partitionOptions = {
|
|
94
|
+
extractImages: true,
|
|
95
|
+
extractForms: true,
|
|
96
|
+
extractLinks: true,
|
|
97
|
+
skipNavigation: false, // NAVIGATION SKIPPING IS BROKEN
|
|
98
|
+
minTextLength: 3,
|
|
99
|
+
includeOriginalHtml: false,
|
|
100
|
+
includeMetadata: true
|
|
101
|
+
};
|
|
102
|
+
// Process HTML
|
|
103
|
+
const result = partitionHtml(htmlContent, partitionOptions);
|
|
104
|
+
// Configure markdown serializer options
|
|
105
|
+
const markdownOptions = {
|
|
106
|
+
includeMetadata: false,
|
|
107
|
+
includePageNumbers: true,
|
|
108
|
+
includeElementIds: false,
|
|
109
|
+
includeCoordinates: false,
|
|
110
|
+
preserveHierarchy: true,
|
|
111
|
+
escapeSpecialChars: true,
|
|
112
|
+
includeFormFields: true,
|
|
113
|
+
includeImageMetadata: true
|
|
114
|
+
};
|
|
115
|
+
// Convert to markdown
|
|
116
|
+
const markdown = serializeToMarkdown(result, markdownOptions);
|
|
117
|
+
const screenshot = await this.require(BrowserConnector).getHarness().screenshot();
|
|
118
|
+
const data = await this.models.extract(instructions, schema, screenshot, markdown);
|
|
119
|
+
this.browserAgentEvents.emit('extractDone', instructions, data);
|
|
120
|
+
return data;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// export class AgentError extends Error {
|
|
2
|
+
// public readonly failure: FailureDescriptor;
|
|
3
|
+
// public readonly options: Required<AgentErrorOptions>;
|
|
4
|
+
// constructor(failure: FailureDescriptor, options: AgentErrorOptions = {}) {
|
|
5
|
+
// super(`${failure.variant}: ${JSON.stringify(failure.variant, null, 4)}`);
|
|
6
|
+
// this.options = {
|
|
7
|
+
// adaptable: options.adaptable ?? false
|
|
8
|
+
// };
|
|
9
|
+
// this.failure = failure;
|
|
10
|
+
// }
|
|
11
|
+
// }
|
|
12
|
+
export class AgentError extends Error {
|
|
13
|
+
//public readonly failure: FailureDescriptor;
|
|
14
|
+
options;
|
|
15
|
+
constructor(message, options = {}) {
|
|
16
|
+
// super(`${failure.variant}: ${JSON.stringify(failure.variant, null, 4)}`);
|
|
17
|
+
super(message);
|
|
18
|
+
this.options = {
|
|
19
|
+
variant: options.variant ?? 'unknown',
|
|
20
|
+
adaptable: options.adaptable ?? false,
|
|
21
|
+
};
|
|
22
|
+
// if (options.variant !== 'unknown') {
|
|
23
|
+
// super(`${failure.variant}: ${JSON.stringify(failure.variant, null, 4)}`);
|
|
24
|
+
// }
|
|
25
|
+
//this.options = options;
|
|
26
|
+
//this.failure = failure;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// // Agent will only throw these types of errors
|
|
30
|
+
// import { ActionIngredient } from "./recipe/types";
|
|
31
|
+
// import { WebAction } from "./web/types";
|
|
32
|
+
// export class TestCaseError extends Error {};
|
|
33
|
+
// // Base class for wrapping errors
|
|
34
|
+
// class WrapperError extends TestCaseError {
|
|
35
|
+
// public readonly originalError: Error;
|
|
36
|
+
// constructor(message: string, originalError: Error) {
|
|
37
|
+
// super(`${message} - ${originalError.message}`);
|
|
38
|
+
// this.name = this.constructor.name;
|
|
39
|
+
// this.originalError = originalError;
|
|
40
|
+
// // Preserve the stack trace
|
|
41
|
+
// if (Error.captureStackTrace) {
|
|
42
|
+
// Error.captureStackTrace(this, this.constructor);
|
|
43
|
+
// }
|
|
44
|
+
// }
|
|
45
|
+
// }
|
|
46
|
+
// export class NavigationError extends WrapperError {
|
|
47
|
+
// public readonly url: string;
|
|
48
|
+
// constructor(url: string, originalError: Error) {
|
|
49
|
+
// super(`Failed to navigate to URL: ${url}`, originalError);
|
|
50
|
+
// this.url = url;
|
|
51
|
+
// }
|
|
52
|
+
// }
|
|
53
|
+
// export class ActionExecutionError extends WrapperError {
|
|
54
|
+
// public readonly action: WebAction;
|
|
55
|
+
// public readonly statusCode?: number;
|
|
56
|
+
// constructor(action: WebAction, originalError: Error) {
|
|
57
|
+
// super(`Browser encountered error while executing action: ${action}`, originalError);
|
|
58
|
+
// this.action = action;
|
|
59
|
+
// }
|
|
60
|
+
// }
|
|
61
|
+
// export class ActionConversionError extends WrapperError {
|
|
62
|
+
// public readonly action: ActionIngredient;
|
|
63
|
+
// public readonly statusCode?: number;
|
|
64
|
+
// constructor(action: ActionIngredient, originalError: Error) {
|
|
65
|
+
// super(`Micro failed to convert action (does the target line up with the screenshot?): ${action}`, originalError);
|
|
66
|
+
// this.action = action;
|
|
67
|
+
// }
|
|
68
|
+
// }
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import EventEmitter from "eventemitter3";
|
|
2
|
+
import z from "zod";
|
|
3
|
+
import { Action } from "@/actions/types";
|
|
4
|
+
import { AgentEvents } from "@/common/events";
|
|
5
|
+
import { AgentConnector } from '@/connectors';
|
|
6
|
+
import { RenderableContent } from '@/memory/observation';
|
|
7
|
+
import { LLMClient } from "@/ai/types";
|
|
8
|
+
import { AgentMemory } from "@/memory";
|
|
9
|
+
import { ActionDefinition } from "@/actions";
|
|
10
|
+
import { MultiModelHarness } from '@/ai/multiModelHarness';
|
|
11
|
+
export interface AgentOptions {
|
|
12
|
+
llm?: LLMClient | LLMClient[];
|
|
13
|
+
connectors?: AgentConnector[];
|
|
14
|
+
actions?: ActionDefinition<any>[];
|
|
15
|
+
prompt?: string | null;
|
|
16
|
+
telemetry?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface ActOptions {
|
|
19
|
+
prompt?: string;
|
|
20
|
+
data?: RenderableContent;
|
|
21
|
+
memory?: AgentMemory;
|
|
22
|
+
}
|
|
23
|
+
export declare class Agent {
|
|
24
|
+
private options;
|
|
25
|
+
private connectors;
|
|
26
|
+
private actions;
|
|
27
|
+
private memoryOptions;
|
|
28
|
+
readonly models: MultiModelHarness;
|
|
29
|
+
readonly events: EventEmitter<AgentEvents>;
|
|
30
|
+
private doneActing;
|
|
31
|
+
private _paused;
|
|
32
|
+
private _pauseResolve;
|
|
33
|
+
protected latestTaskMemory: AgentMemory;
|
|
34
|
+
constructor(baseConfig?: Partial<AgentOptions>);
|
|
35
|
+
getConnector<C extends AgentConnector>(connectorClass: new (...args: any[]) => C): C | undefined;
|
|
36
|
+
require<C extends AgentConnector>(connectorClass: new (...args: any[]) => C): C;
|
|
37
|
+
start(): Promise<void>;
|
|
38
|
+
identifyAction(action: Action): ActionDefinition<any>;
|
|
39
|
+
exec(action: Action, memory?: AgentMemory): Promise<void>;
|
|
40
|
+
protected _recordConnectorObservations(memory: AgentMemory): Promise<void>;
|
|
41
|
+
get memory(): AgentMemory;
|
|
42
|
+
act(taskOrSteps: string | string[], options?: ActOptions): Promise<void>;
|
|
43
|
+
_traceAct(task: string, memory: AgentMemory, options?: ActOptions): Promise<void>;
|
|
44
|
+
private _buildContext;
|
|
45
|
+
_act(description: string, memory: AgentMemory, options?: ActOptions): Promise<void>;
|
|
46
|
+
query<T extends z.Schema>(query: string, schema: T): Promise<z.infer<T>>;
|
|
47
|
+
queueDone(): Promise<void>;
|
|
48
|
+
private _waitIfPaused;
|
|
49
|
+
pause(): void;
|
|
50
|
+
resume(): void;
|
|
51
|
+
get paused(): boolean;
|
|
52
|
+
stop(): Promise<void>;
|
|
53
|
+
}
|