@mce-bt/microagents-browser 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/dist/audit-logger.d.ts +9 -0
- package/dist/audit-logger.d.ts.map +1 -0
- package/dist/audit-logger.js +45 -0
- package/dist/audit-logger.js.map +1 -0
- package/dist/browser-manager.d.ts +27 -0
- package/dist/browser-manager.d.ts.map +1 -0
- package/dist/browser-manager.js +119 -0
- package/dist/browser-manager.js.map +1 -0
- package/dist/browser-session.d.ts +36 -0
- package/dist/browser-session.d.ts.map +1 -0
- package/dist/browser-session.js +160 -0
- package/dist/browser-session.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/schema.d.ts +7 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +46 -0
- package/dist/schema.js.map +1 -0
- package/dist/session-recorder.d.ts +22 -0
- package/dist/session-recorder.d.ts.map +1 -0
- package/dist/session-recorder.js +65 -0
- package/dist/session-recorder.js.map +1 -0
- package/dist/types.d.ts +75 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Pool } from 'pg';
|
|
2
|
+
import type { AuditEntry } from './types.js';
|
|
3
|
+
export declare class BrowserAuditLogger {
|
|
4
|
+
private readonly pool;
|
|
5
|
+
private readonly log;
|
|
6
|
+
constructor(pool: Pool | null, logger?: (message: string, data?: Record<string, unknown>) => void);
|
|
7
|
+
record(entry: Omit<AuditEntry, 'created_at'>): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=audit-logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-logger.d.ts","sourceRoot":"","sources":["../src/audit-logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA0B7C,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAc;IACnC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA4D;gBAEpE,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI;IAK3F,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAgBnE"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const REDACT_PATTERNS = [
|
|
2
|
+
/password/i,
|
|
3
|
+
/secret/i,
|
|
4
|
+
/token/i,
|
|
5
|
+
/credential/i,
|
|
6
|
+
/api.?key/i,
|
|
7
|
+
];
|
|
8
|
+
function redactSensitiveFields(obj) {
|
|
9
|
+
const result = {};
|
|
10
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
11
|
+
if (REDACT_PATTERNS.some((p) => p.test(key))) {
|
|
12
|
+
result[key] = '[REDACTED]';
|
|
13
|
+
}
|
|
14
|
+
else if (typeof value === 'string' && REDACT_PATTERNS.some((p) => p.test(value))) {
|
|
15
|
+
result[key] = '[REDACTED]';
|
|
16
|
+
}
|
|
17
|
+
else if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
18
|
+
result[key] = redactSensitiveFields(value);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
result[key] = value;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
export class BrowserAuditLogger {
|
|
27
|
+
pool;
|
|
28
|
+
log;
|
|
29
|
+
constructor(pool, logger) {
|
|
30
|
+
this.pool = pool;
|
|
31
|
+
this.log = logger || (() => { });
|
|
32
|
+
}
|
|
33
|
+
async record(entry) {
|
|
34
|
+
const redacted = redactSensitiveFields(entry.result);
|
|
35
|
+
this.log(`[browser-audit] ${entry.action_type}: ${entry.instruction}`, {
|
|
36
|
+
session_id: entry.session_id,
|
|
37
|
+
duration_ms: entry.duration_ms,
|
|
38
|
+
});
|
|
39
|
+
if (!this.pool)
|
|
40
|
+
return;
|
|
41
|
+
await this.pool.query(`INSERT INTO public.browser_audit_log (session_id, action_type, instruction, result, duration_ms)
|
|
42
|
+
VALUES ($1, $2, $3, $4, $5)`, [entry.session_id, entry.action_type, entry.instruction, JSON.stringify(redacted), entry.duration_ms]);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=audit-logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-logger.js","sourceRoot":"","sources":["../src/audit-logger.ts"],"names":[],"mappings":"AAGA,MAAM,eAAe,GAAG;IACtB,WAAW;IACX,SAAS;IACT,QAAQ;IACR,aAAa;IACb,WAAW;CACZ,CAAC;AAEF,SAAS,qBAAqB,CAAC,GAA4B;IACzD,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAC7C,MAAM,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC;QAC7B,CAAC;aAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YACnF,MAAM,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC;QAC7B,CAAC;aAAM,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACvE,MAAM,CAAC,GAAG,CAAC,GAAG,qBAAqB,CAAC,KAAgC,CAAC,CAAC;QACxE,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,OAAO,kBAAkB;IACZ,IAAI,CAAc;IAClB,GAAG,CAA4D;IAEhF,YAAY,IAAiB,EAAE,MAAkE;QAC/F,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAqC;QAChD,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAErD,IAAI,CAAC,GAAG,CAAC,mBAAmB,KAAK,CAAC,WAAW,KAAK,KAAK,CAAC,WAAW,EAAE,EAAE;YACrE,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,WAAW,EAAE,KAAK,CAAC,WAAW;SAC/B,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,OAAO;QAEvB,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnB;mCAC6B,EAC7B,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,CACtG,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { CredentialVault } from '@mce-bt/microagents-vault';
|
|
2
|
+
import { BrowserSession } from './browser-session.js';
|
|
3
|
+
import type { BrowserManagerConfig, SessionOptions } from './types.js';
|
|
4
|
+
export declare class BrowserManager {
|
|
5
|
+
private readonly profilesDir;
|
|
6
|
+
private readonly recordingsDir;
|
|
7
|
+
private readonly model;
|
|
8
|
+
private readonly modelApiKey;
|
|
9
|
+
private readonly modelBaseURL;
|
|
10
|
+
private readonly headless;
|
|
11
|
+
private readonly pool;
|
|
12
|
+
private readonly vault;
|
|
13
|
+
private readonly auditLogger;
|
|
14
|
+
private readonly log;
|
|
15
|
+
private activeSession;
|
|
16
|
+
constructor(config: BrowserManagerConfig);
|
|
17
|
+
createSession(agentId: string, goal: string, options?: SessionOptions): Promise<BrowserSession>;
|
|
18
|
+
closeSession(): Promise<void>;
|
|
19
|
+
isSessionActive(): boolean;
|
|
20
|
+
getVault(): CredentialVault | null;
|
|
21
|
+
/**
|
|
22
|
+
* Mark sessions stuck in 'running' state for longer than `thresholdMinutes` as 'failed'.
|
|
23
|
+
* Returns the number of sessions cleaned up.
|
|
24
|
+
*/
|
|
25
|
+
cleanupStaleSessions(thresholdMinutes: number): Promise<number>;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=browser-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-manager.d.ts","sourceRoot":"","sources":["../src/browser-manager.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAGjE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEvE,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAc;IACnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyB;IAC/C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA4D;IAChF,OAAO,CAAC,aAAa,CAA+B;gBAExC,MAAM,EAAE,oBAAoB;IAalC,aAAa,CACjB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,cAAc,CAAC;IAoEpB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAOnC,eAAe,IAAI,OAAO;IAI1B,QAAQ,IAAI,eAAe,GAAG,IAAI;IAIlC;;;OAGG;IACG,oBAAoB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CActE"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import { Stagehand } from '@browserbasehq/stagehand';
|
|
4
|
+
import { AISdkClient } from '@browserbasehq/stagehand/lib/v3/llm/aisdk.js';
|
|
5
|
+
import { createOpenAI } from '@ai-sdk/openai';
|
|
6
|
+
import { BrowserAuditLogger } from './audit-logger.js';
|
|
7
|
+
import { SessionRecorder } from './session-recorder.js';
|
|
8
|
+
import { BrowserSession } from './browser-session.js';
|
|
9
|
+
export class BrowserManager {
|
|
10
|
+
profilesDir;
|
|
11
|
+
recordingsDir;
|
|
12
|
+
model;
|
|
13
|
+
modelApiKey;
|
|
14
|
+
modelBaseURL;
|
|
15
|
+
headless;
|
|
16
|
+
pool;
|
|
17
|
+
vault;
|
|
18
|
+
auditLogger;
|
|
19
|
+
log;
|
|
20
|
+
activeSession = null;
|
|
21
|
+
constructor(config) {
|
|
22
|
+
this.profilesDir = config.profilesDir;
|
|
23
|
+
this.recordingsDir = config.recordingsDir;
|
|
24
|
+
this.model = config.model;
|
|
25
|
+
this.modelApiKey = config.modelApiKey;
|
|
26
|
+
this.modelBaseURL = config.modelBaseURL;
|
|
27
|
+
this.headless = config.headless ?? true;
|
|
28
|
+
this.pool = config.pool ?? null;
|
|
29
|
+
this.vault = config.vault ?? null;
|
|
30
|
+
this.log = config.logger || (() => { });
|
|
31
|
+
this.auditLogger = new BrowserAuditLogger(this.pool, this.log);
|
|
32
|
+
}
|
|
33
|
+
async createSession(agentId, goal, options) {
|
|
34
|
+
if (this.activeSession) {
|
|
35
|
+
throw new Error('A browser session is already active. Close it before starting a new one.');
|
|
36
|
+
}
|
|
37
|
+
const platform = options?.platform;
|
|
38
|
+
const profileDir = platform
|
|
39
|
+
? path.join(this.profilesDir, platform)
|
|
40
|
+
: path.join(this.profilesDir, '_default');
|
|
41
|
+
await fs.mkdir(profileDir, { recursive: true });
|
|
42
|
+
await fs.mkdir(this.recordingsDir, { recursive: true });
|
|
43
|
+
// Remove stale Chrome lock files that can prevent launch after a crash
|
|
44
|
+
for (const lockFile of ['SingletonLock', 'SingletonSocket', 'SingletonCookie']) {
|
|
45
|
+
await fs.rm(path.join(profileDir, lockFile), { force: true }).catch(() => { });
|
|
46
|
+
}
|
|
47
|
+
const recorder = new SessionRecorder(this.pool, this.recordingsDir);
|
|
48
|
+
const sessionId = await recorder.startSession(agentId, goal, platform);
|
|
49
|
+
// Build Stagehand options. When a custom API key/base URL is provided,
|
|
50
|
+
// create an explicit Chat-Completions LLM client so that OpenAI-compatible
|
|
51
|
+
// providers (e.g. OpenRouter) work — @ai-sdk/openai v2+ defaults to the
|
|
52
|
+
// Responses API which those endpoints don't support.
|
|
53
|
+
let llmClient;
|
|
54
|
+
if (this.modelApiKey) {
|
|
55
|
+
const provider = createOpenAI({
|
|
56
|
+
apiKey: this.modelApiKey,
|
|
57
|
+
...(this.modelBaseURL ? { baseURL: this.modelBaseURL } : {}),
|
|
58
|
+
});
|
|
59
|
+
// Extract the bare model name (strip provider prefix if present)
|
|
60
|
+
const modelId = this.model.includes('/') ? this.model.split('/').slice(1).join('/') : this.model;
|
|
61
|
+
const chatModel = provider.chat(modelId);
|
|
62
|
+
llmClient = new AISdkClient({ model: chatModel, logger: () => { } });
|
|
63
|
+
}
|
|
64
|
+
const stagehand = new Stagehand({
|
|
65
|
+
env: 'LOCAL',
|
|
66
|
+
model: this.model,
|
|
67
|
+
...(llmClient ? { llmClient } : {}),
|
|
68
|
+
experimental: true,
|
|
69
|
+
verbose: 0,
|
|
70
|
+
localBrowserLaunchOptions: {
|
|
71
|
+
headless: options?.headless ?? this.headless,
|
|
72
|
+
userDataDir: profileDir,
|
|
73
|
+
preserveUserDataDir: true,
|
|
74
|
+
viewport: options?.viewport || { width: 1288, height: 711 },
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
try {
|
|
78
|
+
await stagehand.init();
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
// Browser failed to launch — mark the DB session as failed so it doesn't stay orphaned
|
|
82
|
+
await recorder.endSession('failed');
|
|
83
|
+
throw err;
|
|
84
|
+
}
|
|
85
|
+
this.log('[browser] Session created', { sessionId, agentId, platform, goal });
|
|
86
|
+
const session = new BrowserSession(stagehand, sessionId, this.auditLogger, recorder, () => {
|
|
87
|
+
this.activeSession = null;
|
|
88
|
+
});
|
|
89
|
+
this.activeSession = session;
|
|
90
|
+
return session;
|
|
91
|
+
}
|
|
92
|
+
async closeSession() {
|
|
93
|
+
if (this.activeSession) {
|
|
94
|
+
await this.activeSession.close();
|
|
95
|
+
// activeSession is cleared by the onClose callback in BrowserSession
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
isSessionActive() {
|
|
99
|
+
return this.activeSession !== null;
|
|
100
|
+
}
|
|
101
|
+
getVault() {
|
|
102
|
+
return this.vault;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Mark sessions stuck in 'running' state for longer than `thresholdMinutes` as 'failed'.
|
|
106
|
+
* Returns the number of sessions cleaned up.
|
|
107
|
+
*/
|
|
108
|
+
async cleanupStaleSessions(thresholdMinutes) {
|
|
109
|
+
if (!this.pool)
|
|
110
|
+
return 0;
|
|
111
|
+
const result = await this.pool.query(`UPDATE public.browser_sessions
|
|
112
|
+
SET status = 'failed', ended_at = NOW()
|
|
113
|
+
WHERE status = 'running'
|
|
114
|
+
AND started_at < NOW() - make_interval(mins := $1)
|
|
115
|
+
RETURNING id`, [thresholdMinutes]);
|
|
116
|
+
return result.rowCount ?? 0;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=browser-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-manager.js","sourceRoot":"","sources":["../src/browser-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Stagehand } from '@browserbasehq/stagehand';
|
|
2
|
+
import type { ZodType } from 'zod';
|
|
3
|
+
import { BrowserAuditLogger } from './audit-logger.js';
|
|
4
|
+
import { SessionRecorder } from './session-recorder.js';
|
|
5
|
+
import type { ActOptions, ExtractOptions, AgentExecuteOptions } from './types.js';
|
|
6
|
+
type StagehandPage = ReturnType<Stagehand['context']['pages']>[number];
|
|
7
|
+
export declare class BrowserSession {
|
|
8
|
+
readonly stagehand: Stagehand;
|
|
9
|
+
private readonly sessionId;
|
|
10
|
+
private readonly auditLogger;
|
|
11
|
+
private readonly recorder;
|
|
12
|
+
private readonly onClose;
|
|
13
|
+
constructor(stagehand: Stagehand, sessionId: string, auditLogger: BrowserAuditLogger, recorder: SessionRecorder | null, onClose?: () => void);
|
|
14
|
+
get page(): StagehandPage;
|
|
15
|
+
goto(url: string): Promise<void>;
|
|
16
|
+
act(instruction: string, options?: ActOptions): Promise<{
|
|
17
|
+
success: boolean;
|
|
18
|
+
message: string;
|
|
19
|
+
}>;
|
|
20
|
+
extract<T = string>(instruction: string, schema?: ZodType<T>, options?: ExtractOptions): Promise<T>;
|
|
21
|
+
observe(instruction?: string): Promise<Array<{
|
|
22
|
+
selector: string;
|
|
23
|
+
description: string;
|
|
24
|
+
}>>;
|
|
25
|
+
agent(instruction: string, options?: AgentExecuteOptions): Promise<{
|
|
26
|
+
success: boolean;
|
|
27
|
+
message: string;
|
|
28
|
+
completed: boolean;
|
|
29
|
+
}>;
|
|
30
|
+
screenshot(): Promise<Buffer>;
|
|
31
|
+
close(): Promise<void>;
|
|
32
|
+
closeWithError(): Promise<void>;
|
|
33
|
+
private resolveVariables;
|
|
34
|
+
}
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=browser-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-session.d.ts","sourceRoot":"","sources":["../src/browser-session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AACnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,mBAAmB,EAAgB,MAAM,YAAY,CAAC;AAEhG,KAAK,aAAa,GAAG,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvE,qBAAa,cAAc;IACzB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAyB;IAClD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;gBAG5C,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,kBAAkB,EAC/B,QAAQ,EAAE,eAAe,GAAG,IAAI,EAChC,OAAO,CAAC,EAAE,MAAM,IAAI;IAStB,IAAI,IAAI,IAAI,aAAa,CAExB;IAEK,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBhC,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAuB9F,OAAO,CAAC,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAoCnG,OAAO,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAwBxF,KAAK,CACT,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC;IAyB/D,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAI7B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQtB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;YAQvB,gBAAgB;CAuB/B"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { BrowserAuditLogger } from './audit-logger.js';
|
|
2
|
+
import { SessionRecorder } from './session-recorder.js';
|
|
3
|
+
export class BrowserSession {
|
|
4
|
+
stagehand;
|
|
5
|
+
sessionId;
|
|
6
|
+
auditLogger;
|
|
7
|
+
recorder;
|
|
8
|
+
onClose;
|
|
9
|
+
constructor(stagehand, sessionId, auditLogger, recorder, onClose) {
|
|
10
|
+
this.stagehand = stagehand;
|
|
11
|
+
this.sessionId = sessionId;
|
|
12
|
+
this.auditLogger = auditLogger;
|
|
13
|
+
this.recorder = recorder;
|
|
14
|
+
this.onClose = onClose ?? null;
|
|
15
|
+
}
|
|
16
|
+
get page() {
|
|
17
|
+
return this.stagehand.context.pages()[0];
|
|
18
|
+
}
|
|
19
|
+
async goto(url) {
|
|
20
|
+
const start = Date.now();
|
|
21
|
+
await this.page.goto(url, { waitUntil: 'domcontentloaded' });
|
|
22
|
+
const duration = Date.now() - start;
|
|
23
|
+
await this.auditLogger.record({
|
|
24
|
+
session_id: this.sessionId,
|
|
25
|
+
action_type: 'goto',
|
|
26
|
+
instruction: url,
|
|
27
|
+
result: { success: true },
|
|
28
|
+
duration_ms: duration,
|
|
29
|
+
});
|
|
30
|
+
if (this.recorder) {
|
|
31
|
+
await this.recorder.captureStep(this.page, 'goto', url, { success: true }, duration);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async act(instruction, options) {
|
|
35
|
+
const variables = await this.resolveVariables(options);
|
|
36
|
+
const start = Date.now();
|
|
37
|
+
const result = await this.stagehand.act(instruction, {
|
|
38
|
+
variables,
|
|
39
|
+
timeout: options?.timeout,
|
|
40
|
+
});
|
|
41
|
+
const duration = Date.now() - start;
|
|
42
|
+
const entry = { success: result.success, message: result.message };
|
|
43
|
+
await this.auditLogger.record({
|
|
44
|
+
session_id: this.sessionId,
|
|
45
|
+
action_type: 'act',
|
|
46
|
+
instruction,
|
|
47
|
+
result: entry,
|
|
48
|
+
duration_ms: duration,
|
|
49
|
+
});
|
|
50
|
+
if (this.recorder) {
|
|
51
|
+
await this.recorder.captureStep(this.page, 'act', instruction, entry, duration);
|
|
52
|
+
}
|
|
53
|
+
return entry;
|
|
54
|
+
}
|
|
55
|
+
async extract(instruction, schema, options) {
|
|
56
|
+
const start = Date.now();
|
|
57
|
+
let result;
|
|
58
|
+
if (schema) {
|
|
59
|
+
result = await this.stagehand.extract(instruction, schema, {
|
|
60
|
+
selector: options?.selector,
|
|
61
|
+
timeout: options?.timeout,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
const raw = await this.stagehand.extract(instruction, undefined, {
|
|
66
|
+
selector: options?.selector,
|
|
67
|
+
timeout: options?.timeout,
|
|
68
|
+
});
|
|
69
|
+
result = raw;
|
|
70
|
+
}
|
|
71
|
+
const duration = Date.now() - start;
|
|
72
|
+
await this.auditLogger.record({
|
|
73
|
+
session_id: this.sessionId,
|
|
74
|
+
action_type: 'extract',
|
|
75
|
+
instruction,
|
|
76
|
+
result: { extracted: typeof result === 'object' ? result : { value: result } },
|
|
77
|
+
duration_ms: duration,
|
|
78
|
+
});
|
|
79
|
+
if (this.recorder) {
|
|
80
|
+
await this.recorder.captureStep(this.page, 'extract', instruction, { extracted: typeof result === 'object' ? result : { value: result } }, duration);
|
|
81
|
+
}
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
async observe(instruction) {
|
|
85
|
+
const start = Date.now();
|
|
86
|
+
const actions = instruction ? await this.stagehand.observe(instruction) : await this.stagehand.observe();
|
|
87
|
+
const duration = Date.now() - start;
|
|
88
|
+
await this.auditLogger.record({
|
|
89
|
+
session_id: this.sessionId,
|
|
90
|
+
action_type: 'observe',
|
|
91
|
+
instruction: instruction || '(page scan)',
|
|
92
|
+
result: { action_count: actions.length },
|
|
93
|
+
duration_ms: duration,
|
|
94
|
+
});
|
|
95
|
+
if (this.recorder) {
|
|
96
|
+
await this.recorder.captureStep(this.page, 'observe', instruction || '(page scan)', { action_count: actions.length }, duration);
|
|
97
|
+
}
|
|
98
|
+
return actions;
|
|
99
|
+
}
|
|
100
|
+
async agent(instruction, options) {
|
|
101
|
+
const variables = await this.resolveVariables(options);
|
|
102
|
+
const start = Date.now();
|
|
103
|
+
const agentHandle = this.stagehand.agent({ mode: 'dom' });
|
|
104
|
+
const result = await agentHandle.execute({
|
|
105
|
+
instruction,
|
|
106
|
+
maxSteps: options?.maxSteps || 20,
|
|
107
|
+
variables,
|
|
108
|
+
});
|
|
109
|
+
const duration = Date.now() - start;
|
|
110
|
+
const entry = { success: result.success, message: result.message, completed: result.completed };
|
|
111
|
+
await this.auditLogger.record({
|
|
112
|
+
session_id: this.sessionId,
|
|
113
|
+
action_type: 'agent',
|
|
114
|
+
instruction,
|
|
115
|
+
result: entry,
|
|
116
|
+
duration_ms: duration,
|
|
117
|
+
});
|
|
118
|
+
if (this.recorder) {
|
|
119
|
+
await this.recorder.captureStep(this.page, 'agent', instruction, entry, duration);
|
|
120
|
+
}
|
|
121
|
+
return entry;
|
|
122
|
+
}
|
|
123
|
+
async screenshot() {
|
|
124
|
+
return this.page.screenshot({ fullPage: false });
|
|
125
|
+
}
|
|
126
|
+
async close() {
|
|
127
|
+
if (this.recorder) {
|
|
128
|
+
await this.recorder.endSession('completed');
|
|
129
|
+
}
|
|
130
|
+
await this.stagehand.close();
|
|
131
|
+
this.onClose?.();
|
|
132
|
+
}
|
|
133
|
+
async closeWithError() {
|
|
134
|
+
if (this.recorder) {
|
|
135
|
+
await this.recorder.endSession('failed');
|
|
136
|
+
}
|
|
137
|
+
await this.stagehand.close({ force: true });
|
|
138
|
+
this.onClose?.();
|
|
139
|
+
}
|
|
140
|
+
async resolveVariables(options) {
|
|
141
|
+
if (!options?.vaultCredentials && !options?.variables)
|
|
142
|
+
return undefined;
|
|
143
|
+
const merged = {
|
|
144
|
+
...(options.variables || {}),
|
|
145
|
+
};
|
|
146
|
+
if (options.vaultCredentials) {
|
|
147
|
+
const { vault, platform, label } = options.vaultCredentials;
|
|
148
|
+
const cred = await vault.retrieve(platform, label);
|
|
149
|
+
if (cred) {
|
|
150
|
+
merged.username = { value: cred.username, description: `Login username for ${platform}` };
|
|
151
|
+
merged.password = { value: cred.password, description: `Login password for ${platform}` };
|
|
152
|
+
if (cred.totpCode) {
|
|
153
|
+
merged.totp_code = { value: cred.totpCode, description: `2FA code for ${platform}` };
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return Object.keys(merged).length > 0 ? merged : undefined;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=browser-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-session.js","sourceRoot":"","sources":["../src/browser-session.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { BrowserManager } from './browser-manager.js';
|
|
2
|
+
export { BrowserSession } from './browser-session.js';
|
|
3
|
+
export { BrowserAuditLogger } from './audit-logger.js';
|
|
4
|
+
export { SessionRecorder } from './session-recorder.js';
|
|
5
|
+
export { ensureBrowserSchema } from './schema.js';
|
|
6
|
+
export type { BrowserManagerConfig, SessionOptions, VaultOptions, ActOptions, ExtractOptions, AgentExecuteOptions, AuditEntry, SessionRecording, SessionStep, } from './types.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,YAAY,EACV,oBAAoB,EACpB,cAAc,EACd,YAAY,EACZ,UAAU,EACV,cAAc,EACd,mBAAmB,EACnB,UAAU,EACV,gBAAgB,EAChB,WAAW,GACZ,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { BrowserManager } from './browser-manager.js';
|
|
2
|
+
export { BrowserSession } from './browser-session.js';
|
|
3
|
+
export { BrowserAuditLogger } from './audit-logger.js';
|
|
4
|
+
export { SessionRecorder } from './session-recorder.js';
|
|
5
|
+
export { ensureBrowserSchema } from './schema.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAyC/B;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnE"}
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const SCHEMA_SQL = `
|
|
2
|
+
CREATE TABLE IF NOT EXISTS public.browser_sessions (
|
|
3
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
4
|
+
agent_id TEXT NOT NULL,
|
|
5
|
+
platform TEXT,
|
|
6
|
+
goal TEXT NOT NULL,
|
|
7
|
+
status TEXT NOT NULL DEFAULT 'running',
|
|
8
|
+
step_count INTEGER NOT NULL DEFAULT 0,
|
|
9
|
+
metadata JSONB NOT NULL DEFAULT '{}',
|
|
10
|
+
started_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
11
|
+
ended_at TIMESTAMPTZ
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
CREATE TABLE IF NOT EXISTS public.browser_session_steps (
|
|
15
|
+
id BIGSERIAL PRIMARY KEY,
|
|
16
|
+
session_id UUID NOT NULL REFERENCES public.browser_sessions(id) ON DELETE CASCADE,
|
|
17
|
+
step_index INTEGER NOT NULL,
|
|
18
|
+
action_type TEXT NOT NULL,
|
|
19
|
+
instruction TEXT NOT NULL,
|
|
20
|
+
result JSONB NOT NULL DEFAULT '{}',
|
|
21
|
+
screenshot_path TEXT,
|
|
22
|
+
duration_ms INTEGER,
|
|
23
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
CREATE TABLE IF NOT EXISTS public.browser_audit_log (
|
|
27
|
+
id BIGSERIAL PRIMARY KEY,
|
|
28
|
+
session_id UUID,
|
|
29
|
+
action_type TEXT NOT NULL,
|
|
30
|
+
instruction TEXT NOT NULL,
|
|
31
|
+
result JSONB NOT NULL DEFAULT '{}',
|
|
32
|
+
duration_ms INTEGER,
|
|
33
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
CREATE INDEX IF NOT EXISTS idx_browser_steps_session ON public.browser_session_steps(session_id);
|
|
37
|
+
CREATE INDEX IF NOT EXISTS idx_browser_audit_session ON public.browser_audit_log(session_id);
|
|
38
|
+
`;
|
|
39
|
+
/**
|
|
40
|
+
* Create the browser recording/audit tables if they don't exist.
|
|
41
|
+
* Idempotent — safe to call on every boot.
|
|
42
|
+
*/
|
|
43
|
+
export async function ensureBrowserSchema(pool) {
|
|
44
|
+
await pool.query(SCHEMA_SQL);
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqClB,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAAU;IAClD,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Pool } from 'pg';
|
|
2
|
+
interface ScreenshotCapable {
|
|
3
|
+
screenshot(options?: {
|
|
4
|
+
path?: string;
|
|
5
|
+
fullPage?: boolean;
|
|
6
|
+
}): Promise<Buffer>;
|
|
7
|
+
}
|
|
8
|
+
export declare class SessionRecorder {
|
|
9
|
+
private readonly pool;
|
|
10
|
+
private readonly recordingsDir;
|
|
11
|
+
private sessionId;
|
|
12
|
+
private sessionDir;
|
|
13
|
+
private stepIndex;
|
|
14
|
+
constructor(pool: Pool | null, recordingsDir: string);
|
|
15
|
+
startSession(agentId: string, goal: string, platform?: string, metadata?: Record<string, unknown>): Promise<string>;
|
|
16
|
+
captureStep(page: ScreenshotCapable, actionType: string, instruction: string, result: Record<string, unknown>, durationMs: number): Promise<void>;
|
|
17
|
+
endSession(status: 'completed' | 'failed'): Promise<void>;
|
|
18
|
+
getSessionId(): string | null;
|
|
19
|
+
getSessionDir(): string | null;
|
|
20
|
+
}
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=session-recorder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-recorder.d.ts","sourceRoot":"","sources":["../src/session-recorder.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE/B,UAAU,iBAAiB;IACzB,UAAU,CAAC,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC9E;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAc;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,SAAS,CAAK;gBAEV,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,aAAa,EAAE,MAAM;IAK9C,YAAY,CAChB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC;IAqBZ,WAAW,CACf,IAAI,EAAE,iBAAiB,EACvB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IA+BV,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAS/D,YAAY,IAAI,MAAM,GAAG,IAAI;IAI7B,aAAa,IAAI,MAAM,GAAG,IAAI;CAG/B"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
export class SessionRecorder {
|
|
4
|
+
pool;
|
|
5
|
+
recordingsDir;
|
|
6
|
+
sessionId = null;
|
|
7
|
+
sessionDir = null;
|
|
8
|
+
stepIndex = 0;
|
|
9
|
+
constructor(pool, recordingsDir) {
|
|
10
|
+
this.pool = pool;
|
|
11
|
+
this.recordingsDir = recordingsDir;
|
|
12
|
+
}
|
|
13
|
+
async startSession(agentId, goal, platform, metadata) {
|
|
14
|
+
if (!this.pool) {
|
|
15
|
+
this.sessionId = crypto.randomUUID();
|
|
16
|
+
this.sessionDir = path.join(this.recordingsDir, this.sessionId);
|
|
17
|
+
await fs.mkdir(this.sessionDir, { recursive: true });
|
|
18
|
+
return this.sessionId;
|
|
19
|
+
}
|
|
20
|
+
const result = await this.pool.query(`INSERT INTO public.browser_sessions (agent_id, platform, goal, metadata)
|
|
21
|
+
VALUES ($1, $2, $3, $4) RETURNING id`, [agentId, platform || null, goal, JSON.stringify(metadata || {})]);
|
|
22
|
+
this.sessionId = result.rows[0].id;
|
|
23
|
+
this.sessionDir = path.join(this.recordingsDir, this.sessionId);
|
|
24
|
+
await fs.mkdir(this.sessionDir, { recursive: true });
|
|
25
|
+
this.stepIndex = 0;
|
|
26
|
+
return this.sessionId;
|
|
27
|
+
}
|
|
28
|
+
async captureStep(page, actionType, instruction, result, durationMs) {
|
|
29
|
+
if (!this.sessionId || !this.sessionDir)
|
|
30
|
+
return;
|
|
31
|
+
const screenshotFile = `step-${String(this.stepIndex).padStart(3, '0')}.png`;
|
|
32
|
+
const screenshotPath = path.join(this.sessionDir, screenshotFile);
|
|
33
|
+
try {
|
|
34
|
+
await page.screenshot({ path: screenshotPath, fullPage: false });
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// Page may have navigated or closed — skip screenshot
|
|
38
|
+
}
|
|
39
|
+
if (this.pool) {
|
|
40
|
+
await this.pool.query(`INSERT INTO public.browser_session_steps (session_id, step_index, action_type, instruction, result, screenshot_path, duration_ms)
|
|
41
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7)`, [
|
|
42
|
+
this.sessionId,
|
|
43
|
+
this.stepIndex,
|
|
44
|
+
actionType,
|
|
45
|
+
instruction,
|
|
46
|
+
JSON.stringify(result),
|
|
47
|
+
screenshotPath,
|
|
48
|
+
durationMs,
|
|
49
|
+
]);
|
|
50
|
+
}
|
|
51
|
+
this.stepIndex++;
|
|
52
|
+
}
|
|
53
|
+
async endSession(status) {
|
|
54
|
+
if (!this.pool || !this.sessionId)
|
|
55
|
+
return;
|
|
56
|
+
await this.pool.query(`UPDATE public.browser_sessions SET status = $1, ended_at = NOW(), step_count = $2 WHERE id = $3`, [status, this.stepIndex, this.sessionId]);
|
|
57
|
+
}
|
|
58
|
+
getSessionId() {
|
|
59
|
+
return this.sessionId;
|
|
60
|
+
}
|
|
61
|
+
getSessionDir() {
|
|
62
|
+
return this.sessionDir;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=session-recorder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-recorder.js","sourceRoot":"","sources":["../src/session-recorder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAO7B,MAAM,OAAO,eAAe;IACT,IAAI,CAAc;IAClB,aAAa,CAAS;IAC/B,SAAS,GAAkB,IAAI,CAAC;IAChC,UAAU,GAAkB,IAAI,CAAC;IACjC,SAAS,GAAG,CAAC,CAAC;IAEtB,YAAY,IAAiB,EAAE,aAAqB;QAClD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,OAAe,EACf,IAAY,EACZ,QAAiB,EACjB,QAAkC;QAElC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;YACrC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAChE,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACrD,OAAO,IAAI,CAAC,SAAS,CAAC;QACxB,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAClC;4CACsC,EACtC,CAAC,OAAO,EAAE,QAAQ,IAAI,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAClE,CAAC;QAEF,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAChE,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,WAAW,CACf,IAAuB,EACvB,UAAkB,EAClB,WAAmB,EACnB,MAA+B,EAC/B,UAAkB;QAElB,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO;QAEhD,MAAM,cAAc,GAAG,QAAQ,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC;QAC7E,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QAElE,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QACnE,CAAC;QAAC,MAAM,CAAC;YACP,sDAAsD;QACxD,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnB;6CACqC,EACrC;gBACE,IAAI,CAAC,SAAS;gBACd,IAAI,CAAC,SAAS;gBACd,UAAU;gBACV,WAAW;gBACX,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;gBACtB,cAAc;gBACd,UAAU;aACX,CACF,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,SAAS,EAAE,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,MAA8B;QAC7C,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO;QAE1C,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnB,iGAAiG,EACjG,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CACzC,CAAC;IACJ,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,aAAa;QACX,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;CACF"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { CredentialVault } from '@mce-bt/microagents-vault';
|
|
2
|
+
export interface BrowserManagerConfig {
|
|
3
|
+
profilesDir: string;
|
|
4
|
+
recordingsDir: string;
|
|
5
|
+
model: string;
|
|
6
|
+
modelApiKey?: string;
|
|
7
|
+
modelBaseURL?: string;
|
|
8
|
+
headless?: boolean;
|
|
9
|
+
pool?: import('pg').Pool;
|
|
10
|
+
vault?: CredentialVault;
|
|
11
|
+
logger?: (message: string, data?: Record<string, unknown>) => void;
|
|
12
|
+
}
|
|
13
|
+
export interface SessionOptions {
|
|
14
|
+
platform?: string;
|
|
15
|
+
headless?: boolean;
|
|
16
|
+
viewport?: {
|
|
17
|
+
width: number;
|
|
18
|
+
height: number;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export interface VaultOptions {
|
|
22
|
+
vault: CredentialVault;
|
|
23
|
+
platform: string;
|
|
24
|
+
label?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface ActOptions {
|
|
27
|
+
variables?: Record<string, string | number | boolean | {
|
|
28
|
+
value: string | number | boolean;
|
|
29
|
+
description?: string;
|
|
30
|
+
}>;
|
|
31
|
+
vaultCredentials?: VaultOptions;
|
|
32
|
+
timeout?: number;
|
|
33
|
+
}
|
|
34
|
+
export interface ExtractOptions {
|
|
35
|
+
selector?: string;
|
|
36
|
+
timeout?: number;
|
|
37
|
+
}
|
|
38
|
+
export interface AgentExecuteOptions {
|
|
39
|
+
maxSteps?: number;
|
|
40
|
+
variables?: Record<string, string | number | boolean | {
|
|
41
|
+
value: string | number | boolean;
|
|
42
|
+
description?: string;
|
|
43
|
+
}>;
|
|
44
|
+
vaultCredentials?: VaultOptions;
|
|
45
|
+
timeout?: number;
|
|
46
|
+
}
|
|
47
|
+
export interface AuditEntry {
|
|
48
|
+
session_id: string;
|
|
49
|
+
action_type: string;
|
|
50
|
+
instruction: string;
|
|
51
|
+
result: Record<string, unknown>;
|
|
52
|
+
duration_ms: number;
|
|
53
|
+
created_at: Date;
|
|
54
|
+
}
|
|
55
|
+
export interface SessionRecording {
|
|
56
|
+
id: string;
|
|
57
|
+
agent_id: string;
|
|
58
|
+
platform: string | null;
|
|
59
|
+
goal: string;
|
|
60
|
+
status: 'running' | 'completed' | 'failed';
|
|
61
|
+
started_at: Date;
|
|
62
|
+
ended_at: Date | null;
|
|
63
|
+
step_count: number;
|
|
64
|
+
metadata: Record<string, unknown>;
|
|
65
|
+
}
|
|
66
|
+
export interface SessionStep {
|
|
67
|
+
step_index: number;
|
|
68
|
+
action_type: string;
|
|
69
|
+
instruction: string;
|
|
70
|
+
result: Record<string, unknown>;
|
|
71
|
+
screenshot_path: string | null;
|
|
72
|
+
duration_ms: number;
|
|
73
|
+
created_at: Date;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mce-bt/microagents-browser",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "AI-driven browser automation — Stagehand wrapper with vault integration and session recording",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc --build",
|
|
16
|
+
"clean": "rm -rf dist tsconfig.tsbuildinfo",
|
|
17
|
+
"test": "vitest run"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@ai-sdk/openai": "^2.0.0",
|
|
21
|
+
"@browserbasehq/stagehand": "^3.2.0",
|
|
22
|
+
"@mce-bt/microagents-vault": "^0.1.0"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@types/pg": "^8.11.0"
|
|
26
|
+
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"pg": "^8.0.0"
|
|
29
|
+
},
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"files": [
|
|
32
|
+
"dist"
|
|
33
|
+
],
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/cavillo/microagents.git",
|
|
40
|
+
"directory": "packages/browser"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://github.com/cavillo/microagents#readme",
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/cavillo/microagents/issues"
|
|
45
|
+
},
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=20.0.0"
|
|
48
|
+
}
|
|
49
|
+
}
|