browser-use 0.0.1 → 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.
- package/LICENSE +21 -0
- package/README.md +761 -0
- package/dist/agent/cloud-events.d.ts +264 -0
- package/dist/agent/cloud-events.js +318 -0
- package/dist/agent/gif.d.ts +15 -0
- package/dist/agent/gif.js +215 -0
- package/dist/agent/index.d.ts +8 -0
- package/dist/agent/index.js +8 -0
- package/dist/agent/message-manager/service.d.ts +30 -0
- package/dist/agent/message-manager/service.js +208 -0
- package/dist/agent/message-manager/utils.d.ts +2 -0
- package/dist/agent/message-manager/utils.js +41 -0
- package/dist/agent/message-manager/views.d.ts +26 -0
- package/dist/agent/message-manager/views.js +73 -0
- package/dist/agent/prompts.d.ts +52 -0
- package/dist/agent/prompts.js +259 -0
- package/dist/agent/service.d.ts +290 -0
- package/dist/agent/service.js +2200 -0
- package/dist/agent/views.d.ts +741 -0
- package/dist/agent/views.js +537 -0
- package/dist/browser/browser.d.ts +7 -0
- package/dist/browser/browser.js +5 -0
- package/dist/browser/context.d.ts +8 -0
- package/dist/browser/context.js +4 -0
- package/dist/browser/dvd-screensaver.d.ts +101 -0
- package/dist/browser/dvd-screensaver.js +270 -0
- package/dist/browser/extensions.d.ts +63 -0
- package/dist/browser/extensions.js +359 -0
- package/dist/browser/index.d.ts +10 -0
- package/dist/browser/index.js +9 -0
- package/dist/browser/playwright-manager.d.ts +47 -0
- package/dist/browser/playwright-manager.js +146 -0
- package/dist/browser/profile.d.ts +196 -0
- package/dist/browser/profile.js +815 -0
- package/dist/browser/session.d.ts +505 -0
- package/dist/browser/session.js +3409 -0
- package/dist/browser/types.d.ts +1184 -0
- package/dist/browser/types.js +1 -0
- package/dist/browser/utils.d.ts +1 -0
- package/dist/browser/utils.js +19 -0
- package/dist/browser/views.d.ts +78 -0
- package/dist/browser/views.js +72 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +44 -0
- package/dist/config.d.ts +108 -0
- package/dist/config.js +430 -0
- package/dist/controller/index.d.ts +3 -0
- package/dist/controller/index.js +3 -0
- package/dist/controller/registry/index.d.ts +2 -0
- package/dist/controller/registry/index.js +2 -0
- package/dist/controller/registry/service.d.ts +45 -0
- package/dist/controller/registry/service.js +184 -0
- package/dist/controller/registry/views.d.ts +55 -0
- package/dist/controller/registry/views.js +174 -0
- package/dist/controller/service.d.ts +49 -0
- package/dist/controller/service.js +1176 -0
- package/dist/controller/views.d.ts +241 -0
- package/dist/controller/views.js +88 -0
- package/dist/dom/clickable-element-processor/service.d.ts +11 -0
- package/dist/dom/clickable-element-processor/service.js +60 -0
- package/dist/dom/dom_tree/index.js +1400 -0
- package/dist/dom/history-tree-processor/service.d.ts +14 -0
- package/dist/dom/history-tree-processor/service.js +75 -0
- package/dist/dom/history-tree-processor/view.d.ts +54 -0
- package/dist/dom/history-tree-processor/view.js +56 -0
- package/dist/dom/playground/extraction.d.ts +19 -0
- package/dist/dom/playground/extraction.js +187 -0
- package/dist/dom/playground/process-dom.d.ts +1 -0
- package/dist/dom/playground/process-dom.js +5 -0
- package/dist/dom/playground/test-accessibility.d.ts +44 -0
- package/dist/dom/playground/test-accessibility.js +111 -0
- package/dist/dom/service.d.ts +19 -0
- package/dist/dom/service.js +227 -0
- package/dist/dom/utils.d.ts +1 -0
- package/dist/dom/utils.js +6 -0
- package/dist/dom/views.d.ts +61 -0
- package/dist/dom/views.js +247 -0
- package/dist/event-bus.d.ts +11 -0
- package/dist/event-bus.js +19 -0
- package/dist/exceptions.d.ts +10 -0
- package/dist/exceptions.js +22 -0
- package/dist/filesystem/file-system.d.ts +68 -0
- package/dist/filesystem/file-system.js +412 -0
- package/dist/filesystem/index.d.ts +1 -0
- package/dist/filesystem/index.js +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +33 -0
- package/dist/integrations/gmail/actions.d.ts +12 -0
- package/dist/integrations/gmail/actions.js +113 -0
- package/dist/integrations/gmail/index.d.ts +2 -0
- package/dist/integrations/gmail/index.js +2 -0
- package/dist/integrations/gmail/service.d.ts +61 -0
- package/dist/integrations/gmail/service.js +260 -0
- package/dist/llm/anthropic/chat.d.ts +28 -0
- package/dist/llm/anthropic/chat.js +126 -0
- package/dist/llm/anthropic/index.d.ts +2 -0
- package/dist/llm/anthropic/index.js +2 -0
- package/dist/llm/anthropic/serializer.d.ts +68 -0
- package/dist/llm/anthropic/serializer.js +285 -0
- package/dist/llm/aws/chat-anthropic.d.ts +61 -0
- package/dist/llm/aws/chat-anthropic.js +176 -0
- package/dist/llm/aws/chat-bedrock.d.ts +15 -0
- package/dist/llm/aws/chat-bedrock.js +80 -0
- package/dist/llm/aws/index.d.ts +3 -0
- package/dist/llm/aws/index.js +3 -0
- package/dist/llm/aws/serializer.d.ts +5 -0
- package/dist/llm/aws/serializer.js +68 -0
- package/dist/llm/azure/chat.d.ts +15 -0
- package/dist/llm/azure/chat.js +83 -0
- package/dist/llm/azure/index.d.ts +1 -0
- package/dist/llm/azure/index.js +1 -0
- package/dist/llm/base.d.ts +16 -0
- package/dist/llm/base.js +1 -0
- package/dist/llm/deepseek/chat.d.ts +15 -0
- package/dist/llm/deepseek/chat.js +51 -0
- package/dist/llm/deepseek/index.d.ts +2 -0
- package/dist/llm/deepseek/index.js +2 -0
- package/dist/llm/deepseek/serializer.d.ts +6 -0
- package/dist/llm/deepseek/serializer.js +57 -0
- package/dist/llm/exceptions.d.ts +10 -0
- package/dist/llm/exceptions.js +18 -0
- package/dist/llm/google/chat.d.ts +20 -0
- package/dist/llm/google/chat.js +144 -0
- package/dist/llm/google/index.d.ts +2 -0
- package/dist/llm/google/index.js +2 -0
- package/dist/llm/google/serializer.d.ts +6 -0
- package/dist/llm/google/serializer.js +64 -0
- package/dist/llm/groq/chat.d.ts +15 -0
- package/dist/llm/groq/chat.js +52 -0
- package/dist/llm/groq/index.d.ts +3 -0
- package/dist/llm/groq/index.js +3 -0
- package/dist/llm/groq/parser.d.ts +32 -0
- package/dist/llm/groq/parser.js +189 -0
- package/dist/llm/groq/serializer.d.ts +6 -0
- package/dist/llm/groq/serializer.js +56 -0
- package/dist/llm/messages.d.ts +77 -0
- package/dist/llm/messages.js +157 -0
- package/dist/llm/ollama/chat.d.ts +15 -0
- package/dist/llm/ollama/chat.js +77 -0
- package/dist/llm/ollama/index.d.ts +2 -0
- package/dist/llm/ollama/index.js +2 -0
- package/dist/llm/ollama/serializer.d.ts +6 -0
- package/dist/llm/ollama/serializer.js +53 -0
- package/dist/llm/openai/chat.d.ts +38 -0
- package/dist/llm/openai/chat.js +174 -0
- package/dist/llm/openai/index.d.ts +3 -0
- package/dist/llm/openai/index.js +3 -0
- package/dist/llm/openai/like.d.ts +17 -0
- package/dist/llm/openai/like.js +19 -0
- package/dist/llm/openai/serializer.d.ts +6 -0
- package/dist/llm/openai/serializer.js +57 -0
- package/dist/llm/openrouter/chat.d.ts +15 -0
- package/dist/llm/openrouter/chat.js +74 -0
- package/dist/llm/openrouter/index.d.ts +2 -0
- package/dist/llm/openrouter/index.js +2 -0
- package/dist/llm/openrouter/serializer.d.ts +3 -0
- package/dist/llm/openrouter/serializer.js +3 -0
- package/dist/llm/schema.d.ts +6 -0
- package/dist/llm/schema.js +77 -0
- package/dist/llm/views.d.ts +15 -0
- package/dist/llm/views.js +12 -0
- package/dist/logging-config.d.ts +25 -0
- package/dist/logging-config.js +89 -0
- package/dist/mcp/client.d.ts +142 -0
- package/dist/mcp/client.js +638 -0
- package/dist/mcp/controller.d.ts +6 -0
- package/dist/mcp/controller.js +38 -0
- package/dist/mcp/index.d.ts +3 -0
- package/dist/mcp/index.js +3 -0
- package/dist/mcp/server.d.ts +134 -0
- package/dist/mcp/server.js +759 -0
- package/dist/observability-decorators.d.ts +158 -0
- package/dist/observability-decorators.js +286 -0
- package/dist/observability.d.ts +23 -0
- package/dist/observability.js +58 -0
- package/dist/screenshots/index.d.ts +1 -0
- package/dist/screenshots/index.js +1 -0
- package/dist/screenshots/service.d.ts +6 -0
- package/dist/screenshots/service.js +28 -0
- package/dist/sync/auth.d.ts +27 -0
- package/dist/sync/auth.js +205 -0
- package/dist/sync/index.d.ts +2 -0
- package/dist/sync/index.js +2 -0
- package/dist/sync/service.d.ts +21 -0
- package/dist/sync/service.js +146 -0
- package/dist/telemetry/index.d.ts +2 -0
- package/dist/telemetry/index.js +2 -0
- package/dist/telemetry/service.d.ts +12 -0
- package/dist/telemetry/service.js +85 -0
- package/dist/telemetry/views.d.ts +112 -0
- package/dist/telemetry/views.js +112 -0
- package/dist/tokens/index.d.ts +2 -0
- package/dist/tokens/index.js +2 -0
- package/dist/tokens/service.d.ts +35 -0
- package/dist/tokens/service.js +423 -0
- package/dist/tokens/views.d.ts +58 -0
- package/dist/tokens/views.js +1 -0
- package/dist/utils.d.ts +128 -0
- package/dist/utils.js +529 -0
- package/package.json +94 -5
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Observability Decorators and Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides debugging and performance tracking capabilities
|
|
5
|
+
* for browser automation operations.
|
|
6
|
+
*
|
|
7
|
+
* Note: TypeScript decorators work differently than Python.
|
|
8
|
+
* These are implemented as wrapper functions that can be used
|
|
9
|
+
* in a similar way to decorators.
|
|
10
|
+
*/
|
|
11
|
+
import { createLogger } from './logging-config.js';
|
|
12
|
+
/**
|
|
13
|
+
* Debug observation configuration
|
|
14
|
+
*/
|
|
15
|
+
export interface ObserveDebugOptions {
|
|
16
|
+
/** Enable detailed logging */
|
|
17
|
+
verbose?: boolean;
|
|
18
|
+
/** Log function arguments */
|
|
19
|
+
logArgs?: boolean;
|
|
20
|
+
/** Log return values */
|
|
21
|
+
logResult?: boolean;
|
|
22
|
+
/** Log execution time */
|
|
23
|
+
logTime?: boolean;
|
|
24
|
+
/** Custom logger instance */
|
|
25
|
+
logger?: ReturnType<typeof createLogger>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Observe and debug async function execution
|
|
29
|
+
* Wraps an async function to add logging and debugging capabilities
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* const debuggedFn = observeDebug(myAsyncFn, { verbose: true, logArgs: true });
|
|
33
|
+
* await debuggedFn(arg1, arg2);
|
|
34
|
+
*/
|
|
35
|
+
export declare function observeDebug<T extends (...args: any[]) => Promise<any>>(fn: T, options?: ObserveDebugOptions): T;
|
|
36
|
+
/**
|
|
37
|
+
* Method decorator for observing debug (TypeScript experimental decorators)
|
|
38
|
+
* This requires "experimentalDecorators": true in tsconfig.json
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* class MyClass {
|
|
42
|
+
* @observeDebugMethod({ verbose: true })
|
|
43
|
+
* async myMethod(arg: string) {
|
|
44
|
+
* // method implementation
|
|
45
|
+
* }
|
|
46
|
+
* }
|
|
47
|
+
*/
|
|
48
|
+
export declare function observeDebugMethod(options?: ObserveDebugOptions): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
|
|
49
|
+
/**
|
|
50
|
+
* Performance tracking for async functions
|
|
51
|
+
* Combines time execution tracking with debug observation
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* const trackedFn = trackPerformance(myAsyncFn, 'MyOperation');
|
|
55
|
+
* await trackedFn(arg1, arg2);
|
|
56
|
+
*/
|
|
57
|
+
export declare function trackPerformance<T extends (...args: any[]) => Promise<any>>(fn: T, operationName?: string): T;
|
|
58
|
+
/**
|
|
59
|
+
* Comprehensive observability wrapper
|
|
60
|
+
* Combines debugging, performance tracking, and error handling
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* const observedFn = withObservability(myAsyncFn, {
|
|
64
|
+
* name: 'CriticalOperation',
|
|
65
|
+
* debug: true,
|
|
66
|
+
* trackPerformance: true,
|
|
67
|
+
* onError: (error) => console.error('Operation failed:', error)
|
|
68
|
+
* });
|
|
69
|
+
*/
|
|
70
|
+
export declare function withObservability<T extends (...args: any[]) => Promise<any>>(fn: T, options?: {
|
|
71
|
+
name?: string;
|
|
72
|
+
debug?: boolean;
|
|
73
|
+
debugOptions?: ObserveDebugOptions;
|
|
74
|
+
trackPerformance?: boolean;
|
|
75
|
+
onError?: (error: Error) => void;
|
|
76
|
+
onSuccess?: (result: any) => void;
|
|
77
|
+
}): T;
|
|
78
|
+
/**
|
|
79
|
+
* Create a debug trace for a series of operations
|
|
80
|
+
* Useful for tracking complex workflows
|
|
81
|
+
*/
|
|
82
|
+
type TraceOperation = {
|
|
83
|
+
name: string;
|
|
84
|
+
startTime: number;
|
|
85
|
+
endTime?: number;
|
|
86
|
+
duration?: number;
|
|
87
|
+
status: 'pending' | 'success' | 'error';
|
|
88
|
+
error?: Error;
|
|
89
|
+
};
|
|
90
|
+
export declare class OperationTrace {
|
|
91
|
+
private operations;
|
|
92
|
+
private logger;
|
|
93
|
+
private traceName;
|
|
94
|
+
constructor(traceName: string, customLogger?: ReturnType<typeof createLogger>);
|
|
95
|
+
/**
|
|
96
|
+
* Start tracking an operation
|
|
97
|
+
*/
|
|
98
|
+
startOperation(name: string): void;
|
|
99
|
+
/**
|
|
100
|
+
* Mark an operation as completed successfully
|
|
101
|
+
*/
|
|
102
|
+
completeOperation(name: string): void;
|
|
103
|
+
/**
|
|
104
|
+
* Mark an operation as failed
|
|
105
|
+
*/
|
|
106
|
+
failOperation(name: string, error: Error): void;
|
|
107
|
+
/**
|
|
108
|
+
* Get trace summary
|
|
109
|
+
*/
|
|
110
|
+
getSummary(): {
|
|
111
|
+
traceName: string;
|
|
112
|
+
totalOperations: number;
|
|
113
|
+
successCount: number;
|
|
114
|
+
errorCount: number;
|
|
115
|
+
pendingCount: number;
|
|
116
|
+
totalDuration: number;
|
|
117
|
+
operations: TraceOperation[];
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Log trace summary
|
|
121
|
+
*/
|
|
122
|
+
logSummary(): void;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Simple performance counter for tracking operation metrics
|
|
126
|
+
*/
|
|
127
|
+
export declare class PerformanceCounter {
|
|
128
|
+
private counters;
|
|
129
|
+
private logger;
|
|
130
|
+
constructor(customLogger?: ReturnType<typeof createLogger>);
|
|
131
|
+
/**
|
|
132
|
+
* Record an operation execution
|
|
133
|
+
*/
|
|
134
|
+
record(operationName: string, durationMs: number): void;
|
|
135
|
+
/**
|
|
136
|
+
* Get statistics for an operation
|
|
137
|
+
*/
|
|
138
|
+
getStats(operationName: string): {
|
|
139
|
+
count: number;
|
|
140
|
+
avgTime: number;
|
|
141
|
+
minTime: number;
|
|
142
|
+
maxTime: number;
|
|
143
|
+
totalTime: number;
|
|
144
|
+
} | null;
|
|
145
|
+
/**
|
|
146
|
+
* Get all statistics
|
|
147
|
+
*/
|
|
148
|
+
getAllStats(): Map<string, ReturnType<PerformanceCounter['getStats']>>;
|
|
149
|
+
/**
|
|
150
|
+
* Log statistics summary
|
|
151
|
+
*/
|
|
152
|
+
logSummary(): void;
|
|
153
|
+
/**
|
|
154
|
+
* Reset all counters
|
|
155
|
+
*/
|
|
156
|
+
reset(): void;
|
|
157
|
+
}
|
|
158
|
+
export {};
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Observability Decorators and Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides debugging and performance tracking capabilities
|
|
5
|
+
* for browser automation operations.
|
|
6
|
+
*
|
|
7
|
+
* Note: TypeScript decorators work differently than Python.
|
|
8
|
+
* These are implemented as wrapper functions that can be used
|
|
9
|
+
* in a similar way to decorators.
|
|
10
|
+
*/
|
|
11
|
+
import { createLogger } from './logging-config.js';
|
|
12
|
+
import { time_execution_async } from './utils.js';
|
|
13
|
+
const logger = createLogger('browser_use.observability');
|
|
14
|
+
/**
|
|
15
|
+
* Observe and debug async function execution
|
|
16
|
+
* Wraps an async function to add logging and debugging capabilities
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* const debuggedFn = observeDebug(myAsyncFn, { verbose: true, logArgs: true });
|
|
20
|
+
* await debuggedFn(arg1, arg2);
|
|
21
|
+
*/
|
|
22
|
+
export function observeDebug(fn, options = {}) {
|
|
23
|
+
const { verbose = false, logArgs = true, logResult = false, logTime = true, logger: customLogger = logger, } = options;
|
|
24
|
+
const wrappedFn = async function (...args) {
|
|
25
|
+
const fnName = fn.name || 'anonymous';
|
|
26
|
+
const startTime = Date.now();
|
|
27
|
+
try {
|
|
28
|
+
// Log function entry
|
|
29
|
+
if (verbose) {
|
|
30
|
+
customLogger.debug(`→ Entering ${fnName}`);
|
|
31
|
+
}
|
|
32
|
+
// Log arguments
|
|
33
|
+
if (logArgs && args.length > 0) {
|
|
34
|
+
customLogger.debug(`${fnName} arguments:`, args);
|
|
35
|
+
}
|
|
36
|
+
// Execute function
|
|
37
|
+
const result = await fn.apply(this, args);
|
|
38
|
+
// Log execution time
|
|
39
|
+
if (logTime) {
|
|
40
|
+
const duration = Date.now() - startTime;
|
|
41
|
+
customLogger.debug(`${fnName} completed in ${duration}ms`);
|
|
42
|
+
}
|
|
43
|
+
// Log result
|
|
44
|
+
if (logResult) {
|
|
45
|
+
customLogger.debug(`${fnName} result:`, result);
|
|
46
|
+
}
|
|
47
|
+
// Log function exit
|
|
48
|
+
if (verbose) {
|
|
49
|
+
customLogger.debug(`← Exiting ${fnName}`);
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
const duration = Date.now() - startTime;
|
|
55
|
+
customLogger.error(`${fnName} failed after ${duration}ms: ${error.message}`);
|
|
56
|
+
customLogger.debug(`${fnName} error stack:`, error.stack);
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
// Preserve function name
|
|
61
|
+
Object.defineProperty(wrappedFn, 'name', {
|
|
62
|
+
value: fn.name,
|
|
63
|
+
configurable: true,
|
|
64
|
+
});
|
|
65
|
+
return wrappedFn;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Method decorator for observing debug (TypeScript experimental decorators)
|
|
69
|
+
* This requires "experimentalDecorators": true in tsconfig.json
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* class MyClass {
|
|
73
|
+
* @observeDebugMethod({ verbose: true })
|
|
74
|
+
* async myMethod(arg: string) {
|
|
75
|
+
* // method implementation
|
|
76
|
+
* }
|
|
77
|
+
* }
|
|
78
|
+
*/
|
|
79
|
+
export function observeDebugMethod(options = {}) {
|
|
80
|
+
return function (target, propertyKey, descriptor) {
|
|
81
|
+
const originalMethod = descriptor.value;
|
|
82
|
+
descriptor.value = observeDebug(originalMethod, {
|
|
83
|
+
...options,
|
|
84
|
+
logger: options.logger ||
|
|
85
|
+
createLogger(`${target.constructor.name}.${propertyKey}`),
|
|
86
|
+
});
|
|
87
|
+
return descriptor;
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Performance tracking for async functions
|
|
92
|
+
* Combines time execution tracking with debug observation
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* const trackedFn = trackPerformance(myAsyncFn, 'MyOperation');
|
|
96
|
+
* await trackedFn(arg1, arg2);
|
|
97
|
+
*/
|
|
98
|
+
export function trackPerformance(fn, operationName) {
|
|
99
|
+
const name = operationName || fn.name || 'anonymous';
|
|
100
|
+
return time_execution_async(name)(fn);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Comprehensive observability wrapper
|
|
104
|
+
* Combines debugging, performance tracking, and error handling
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* const observedFn = withObservability(myAsyncFn, {
|
|
108
|
+
* name: 'CriticalOperation',
|
|
109
|
+
* debug: true,
|
|
110
|
+
* trackPerformance: true,
|
|
111
|
+
* onError: (error) => console.error('Operation failed:', error)
|
|
112
|
+
* });
|
|
113
|
+
*/
|
|
114
|
+
export function withObservability(fn, options = {}) {
|
|
115
|
+
const { name = fn.name, debug = false, debugOptions = {}, trackPerformance: shouldTrackPerformance = true, onError, onSuccess, } = options;
|
|
116
|
+
let wrappedFn = fn;
|
|
117
|
+
// Apply debug observation if requested
|
|
118
|
+
if (debug) {
|
|
119
|
+
wrappedFn = observeDebug(wrappedFn, debugOptions);
|
|
120
|
+
}
|
|
121
|
+
// Apply performance tracking if requested
|
|
122
|
+
if (shouldTrackPerformance) {
|
|
123
|
+
wrappedFn = trackPerformance(wrappedFn, name);
|
|
124
|
+
}
|
|
125
|
+
// Add error/success callbacks
|
|
126
|
+
if (onError || onSuccess) {
|
|
127
|
+
const callbackFn = async function (...args) {
|
|
128
|
+
try {
|
|
129
|
+
const result = await wrappedFn.apply(this, args);
|
|
130
|
+
if (onSuccess) {
|
|
131
|
+
onSuccess(result);
|
|
132
|
+
}
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
if (onError) {
|
|
137
|
+
onError(error);
|
|
138
|
+
}
|
|
139
|
+
throw error;
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
wrappedFn = callbackFn;
|
|
143
|
+
}
|
|
144
|
+
return wrappedFn;
|
|
145
|
+
}
|
|
146
|
+
export class OperationTrace {
|
|
147
|
+
operations = [];
|
|
148
|
+
logger;
|
|
149
|
+
traceName;
|
|
150
|
+
constructor(traceName, customLogger) {
|
|
151
|
+
this.traceName = traceName;
|
|
152
|
+
this.logger = customLogger || createLogger(`trace.${traceName}`);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Start tracking an operation
|
|
156
|
+
*/
|
|
157
|
+
startOperation(name) {
|
|
158
|
+
this.operations.push({
|
|
159
|
+
name,
|
|
160
|
+
startTime: Date.now(),
|
|
161
|
+
status: 'pending',
|
|
162
|
+
});
|
|
163
|
+
this.logger.debug(`Started operation: ${name}`);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Mark an operation as completed successfully
|
|
167
|
+
*/
|
|
168
|
+
completeOperation(name) {
|
|
169
|
+
const op = this.operations.find((o) => o.name === name && o.status === 'pending');
|
|
170
|
+
if (op) {
|
|
171
|
+
op.endTime = Date.now();
|
|
172
|
+
op.duration = op.endTime - op.startTime;
|
|
173
|
+
op.status = 'success';
|
|
174
|
+
this.logger.debug(`Completed operation: ${name} (${op.duration}ms)`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Mark an operation as failed
|
|
179
|
+
*/
|
|
180
|
+
failOperation(name, error) {
|
|
181
|
+
const op = this.operations.find((o) => o.name === name && o.status === 'pending');
|
|
182
|
+
if (op) {
|
|
183
|
+
op.endTime = Date.now();
|
|
184
|
+
op.duration = op.endTime - op.startTime;
|
|
185
|
+
op.status = 'error';
|
|
186
|
+
op.error = error;
|
|
187
|
+
this.logger.error(`Failed operation: ${name} (${op.duration}ms) - ${error.message}`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Get trace summary
|
|
192
|
+
*/
|
|
193
|
+
getSummary() {
|
|
194
|
+
const successCount = this.operations.filter((o) => o.status === 'success').length;
|
|
195
|
+
const errorCount = this.operations.filter((o) => o.status === 'error').length;
|
|
196
|
+
const pendingCount = this.operations.filter((o) => o.status === 'pending').length;
|
|
197
|
+
const totalDuration = this.operations.reduce((sum, op) => sum + (op.duration || 0), 0);
|
|
198
|
+
return {
|
|
199
|
+
traceName: this.traceName,
|
|
200
|
+
totalOperations: this.operations.length,
|
|
201
|
+
successCount,
|
|
202
|
+
errorCount,
|
|
203
|
+
pendingCount,
|
|
204
|
+
totalDuration,
|
|
205
|
+
operations: this.operations,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Log trace summary
|
|
210
|
+
*/
|
|
211
|
+
logSummary() {
|
|
212
|
+
const summary = this.getSummary();
|
|
213
|
+
this.logger.info(`Trace "${this.traceName}" completed: ${summary.successCount} succeeded, ${summary.errorCount} failed, ${summary.pendingCount} pending (total: ${summary.totalDuration}ms)`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Simple performance counter for tracking operation metrics
|
|
218
|
+
*/
|
|
219
|
+
export class PerformanceCounter {
|
|
220
|
+
counters = new Map();
|
|
221
|
+
logger;
|
|
222
|
+
constructor(customLogger) {
|
|
223
|
+
this.logger = customLogger || createLogger('performance_counter');
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Record an operation execution
|
|
227
|
+
*/
|
|
228
|
+
record(operationName, durationMs) {
|
|
229
|
+
const current = this.counters.get(operationName) || {
|
|
230
|
+
count: 0,
|
|
231
|
+
totalTime: 0,
|
|
232
|
+
minTime: Infinity,
|
|
233
|
+
maxTime: 0,
|
|
234
|
+
};
|
|
235
|
+
this.counters.set(operationName, {
|
|
236
|
+
count: current.count + 1,
|
|
237
|
+
totalTime: current.totalTime + durationMs,
|
|
238
|
+
minTime: Math.min(current.minTime, durationMs),
|
|
239
|
+
maxTime: Math.max(current.maxTime, durationMs),
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Get statistics for an operation
|
|
244
|
+
*/
|
|
245
|
+
getStats(operationName) {
|
|
246
|
+
const counter = this.counters.get(operationName);
|
|
247
|
+
if (!counter) {
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
return {
|
|
251
|
+
count: counter.count,
|
|
252
|
+
avgTime: counter.totalTime / counter.count,
|
|
253
|
+
minTime: counter.minTime,
|
|
254
|
+
maxTime: counter.maxTime,
|
|
255
|
+
totalTime: counter.totalTime,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Get all statistics
|
|
260
|
+
*/
|
|
261
|
+
getAllStats() {
|
|
262
|
+
const stats = new Map();
|
|
263
|
+
for (const [name] of this.counters) {
|
|
264
|
+
stats.set(name, this.getStats(name));
|
|
265
|
+
}
|
|
266
|
+
return stats;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Log statistics summary
|
|
270
|
+
*/
|
|
271
|
+
logSummary() {
|
|
272
|
+
this.logger.info('Performance Counter Summary:');
|
|
273
|
+
for (const [name, stats] of this.getAllStats()) {
|
|
274
|
+
if (stats) {
|
|
275
|
+
this.logger.info(` ${name}: count=${stats.count}, avg=${stats.avgTime.toFixed(2)}ms, min=${stats.minTime.toFixed(2)}ms, max=${stats.maxTime.toFixed(2)}ms`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Reset all counters
|
|
281
|
+
*/
|
|
282
|
+
reset() {
|
|
283
|
+
this.counters.clear();
|
|
284
|
+
this.logger.debug('Performance counters reset');
|
|
285
|
+
}
|
|
286
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
type SpanType = 'DEFAULT' | 'LLM' | 'TOOL';
|
|
2
|
+
export interface ObserveOptions {
|
|
3
|
+
name?: string | null;
|
|
4
|
+
ignoreInput?: boolean;
|
|
5
|
+
ignoreOutput?: boolean;
|
|
6
|
+
metadata?: Record<string, unknown> | null;
|
|
7
|
+
spanType?: SpanType;
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
}
|
|
10
|
+
type AnyFunc = (...args: any[]) => any;
|
|
11
|
+
type Decorator<T extends AnyFunc> = (fn: T) => T;
|
|
12
|
+
export declare const observe: (options?: ObserveOptions) => Decorator<AnyFunc>;
|
|
13
|
+
export declare const observeDebug: (options?: ObserveOptions) => Decorator<AnyFunc>;
|
|
14
|
+
export declare const observe_debug: (options?: ObserveOptions) => Decorator<AnyFunc>;
|
|
15
|
+
export declare const isLmnrAvailable: () => boolean;
|
|
16
|
+
export declare const isDebugMode: () => boolean;
|
|
17
|
+
export declare const getObservabilityStatus: () => {
|
|
18
|
+
lmnrAvailable: boolean;
|
|
19
|
+
debugMode: boolean;
|
|
20
|
+
observeActive: boolean;
|
|
21
|
+
observeDebugActive: boolean;
|
|
22
|
+
};
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { config as loadEnv } from 'dotenv';
|
|
3
|
+
import { createLogger } from './logging-config.js';
|
|
4
|
+
loadEnv();
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
const logger = createLogger('browser_use.observability');
|
|
7
|
+
let lmnrObserve = null;
|
|
8
|
+
let lmnrAvailable = false;
|
|
9
|
+
try {
|
|
10
|
+
const lmnr = require('lmnr');
|
|
11
|
+
if (typeof lmnr?.observe === 'function') {
|
|
12
|
+
lmnrObserve = (options) => lmnr.observe(options);
|
|
13
|
+
lmnrAvailable = true;
|
|
14
|
+
if (process.env.BROWSER_USE_VERBOSE_OBSERVABILITY?.toLowerCase() === 'true') {
|
|
15
|
+
logger.info('Lmnr is available for observability');
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
lmnrObserve = null;
|
|
21
|
+
lmnrAvailable = false;
|
|
22
|
+
if (process.env.BROWSER_USE_VERBOSE_OBSERVABILITY?.toLowerCase() === 'true') {
|
|
23
|
+
logger.info(`Lmnr is not available for observability (${error.message})`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const isDebugModeEnv = () => process.env.LMNR_LOGGING_LEVEL?.toLowerCase() === 'debug';
|
|
27
|
+
const createNoopDecorator = () => (fn) => fn;
|
|
28
|
+
const normalizeOptions = (options = {}) => ({
|
|
29
|
+
name: options.name ?? null,
|
|
30
|
+
ignoreInput: options.ignoreInput ?? false,
|
|
31
|
+
ignoreOutput: options.ignoreOutput ?? false,
|
|
32
|
+
metadata: options.metadata ?? null,
|
|
33
|
+
spanType: options.spanType ?? 'DEFAULT',
|
|
34
|
+
...options,
|
|
35
|
+
});
|
|
36
|
+
export const observe = (options = {}) => {
|
|
37
|
+
const normalized = normalizeOptions(options);
|
|
38
|
+
if (lmnrAvailable && lmnrObserve) {
|
|
39
|
+
return lmnrObserve(normalized);
|
|
40
|
+
}
|
|
41
|
+
return createNoopDecorator();
|
|
42
|
+
};
|
|
43
|
+
export const observeDebug = (options = {}) => {
|
|
44
|
+
const normalized = normalizeOptions(options);
|
|
45
|
+
if (lmnrAvailable && lmnrObserve && isDebugModeEnv()) {
|
|
46
|
+
return lmnrObserve(normalized);
|
|
47
|
+
}
|
|
48
|
+
return createNoopDecorator();
|
|
49
|
+
};
|
|
50
|
+
export const observe_debug = observeDebug;
|
|
51
|
+
export const isLmnrAvailable = () => lmnrAvailable;
|
|
52
|
+
export const isDebugMode = () => isDebugModeEnv();
|
|
53
|
+
export const getObservabilityStatus = () => ({
|
|
54
|
+
lmnrAvailable,
|
|
55
|
+
debugMode: isDebugModeEnv(),
|
|
56
|
+
observeActive: lmnrAvailable,
|
|
57
|
+
observeDebugActive: lmnrAvailable && isDebugModeEnv(),
|
|
58
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './service.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './service.js';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
const decodeBase64 = (data) => Buffer.from(data, 'base64');
|
|
4
|
+
export class ScreenshotService {
|
|
5
|
+
screenshotsDir;
|
|
6
|
+
constructor(agentDirectory) {
|
|
7
|
+
this.screenshotsDir = path.join(agentDirectory, 'screenshots');
|
|
8
|
+
fs.mkdirSync(this.screenshotsDir, { recursive: true });
|
|
9
|
+
}
|
|
10
|
+
async store_screenshot(screenshot_b64, step_number) {
|
|
11
|
+
const filename = `step_${step_number}.png`;
|
|
12
|
+
const filepath = path.join(this.screenshotsDir, filename);
|
|
13
|
+
await fs.promises.writeFile(filepath, decodeBase64(screenshot_b64));
|
|
14
|
+
return filepath;
|
|
15
|
+
}
|
|
16
|
+
async get_screenshot(screenshot_path) {
|
|
17
|
+
if (!screenshot_path) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
const data = await fs.promises.readFile(screenshot_path);
|
|
22
|
+
return data.toString('base64');
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type AxiosInstance } from 'axios';
|
|
2
|
+
export declare const TEMP_USER_ID = "99999999-9999-9999-9999-999999999999";
|
|
3
|
+
export declare class DeviceAuthClient {
|
|
4
|
+
private readonly baseUrl;
|
|
5
|
+
private readonly clientId;
|
|
6
|
+
private readonly scope;
|
|
7
|
+
private readonly httpClient?;
|
|
8
|
+
private authConfig;
|
|
9
|
+
private _deviceId;
|
|
10
|
+
constructor(baseUrl?: string, httpClient?: AxiosInstance);
|
|
11
|
+
get device_id(): string;
|
|
12
|
+
get is_authenticated(): boolean;
|
|
13
|
+
get api_token(): string | null;
|
|
14
|
+
get user_id(): string;
|
|
15
|
+
private get client();
|
|
16
|
+
private buildUrl;
|
|
17
|
+
private postForm;
|
|
18
|
+
start_device_authorization(agent_session_id?: string | null): Promise<Record<string, any>>;
|
|
19
|
+
poll_for_token(device_code: string, interval?: number, timeout?: number): Promise<Record<string, any> | null>;
|
|
20
|
+
authenticate(agent_session_id?: string | null, show_instructions?: boolean): Promise<boolean>;
|
|
21
|
+
get_headers(): {
|
|
22
|
+
Authorization: string;
|
|
23
|
+
} | {
|
|
24
|
+
Authorization?: undefined;
|
|
25
|
+
};
|
|
26
|
+
clear_auth(): void;
|
|
27
|
+
}
|