@morphllm/morphsdk 0.2.40 → 0.2.42
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/anthropic-DpEAqqZF.d.ts +88 -0
- package/dist/{chunk-Q7USYY6R.js → chunk-64PMM72R.js} +10 -2
- package/dist/{chunk-Q7USYY6R.js.map → chunk-64PMM72R.js.map} +1 -1
- package/dist/{chunk-NCVWIW7L.js → chunk-EYHXBQQX.js} +7 -81
- package/dist/chunk-EYHXBQQX.js.map +1 -0
- package/dist/{chunk-LUI7APXX.js → chunk-FP7INILQ.js} +2 -2
- package/dist/{chunk-4WIBODS7.js → chunk-GDR65N2J.js} +1 -1
- package/dist/chunk-GDR65N2J.js.map +1 -0
- package/dist/{chunk-JSZQVUSE.js → chunk-GGBB2HDM.js} +2 -2
- package/dist/{chunk-7MCSSJJA.js → chunk-GU3SULV5.js} +2 -2
- package/dist/{chunk-DIWNR3UP.js → chunk-O45X46VL.js} +5 -5
- package/dist/{chunk-Y2IY7NYY.js → chunk-O5DA5V5S.js} +2 -2
- package/dist/{chunk-4A7UBGLS.js → chunk-OUEJ6XEO.js} +2 -2
- package/dist/{chunk-OZMHDB6O.js → chunk-PEGZVGG4.js} +2 -2
- package/dist/chunk-SQN4DUQS.js +84 -0
- package/dist/chunk-SQN4DUQS.js.map +1 -0
- package/dist/{chunk-B4H7N4GZ.js → chunk-TVFGHXPE.js} +2 -2
- package/dist/{chunk-N5654KQR.js → chunk-W3XLPMV3.js} +15 -15
- package/dist/{chunk-AG3ICTC5.js → chunk-WM77HRKO.js} +4 -7
- package/dist/chunk-WM77HRKO.js.map +1 -0
- package/dist/{chunk-Y5RCNDLV.js → chunk-X4CQ6D3G.js} +2 -2
- package/dist/{chunk-WHZQDTM6.js → chunk-ZRLEAPZV.js} +2 -2
- package/dist/client.cjs +12 -7
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.ts +114 -0
- package/dist/client.js +6 -5
- package/dist/git/client.cjs.map +1 -1
- package/dist/git/client.d.ts +275 -0
- package/dist/git/client.js +1 -1
- package/dist/git/config.d.ts +11 -0
- package/dist/git/index.cjs.map +1 -1
- package/dist/git/index.d.ts +5 -0
- package/dist/git/index.js +1 -1
- package/dist/git/types.d.ts +115 -0
- package/dist/index.cjs +12 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +14 -0
- package/dist/index.js +6 -5
- package/dist/modelrouter/core.d.ts +69 -0
- package/dist/modelrouter/index.d.ts +2 -0
- package/dist/modelrouter/types.d.ts +39 -0
- package/dist/openai-BkKsS30n.d.ts +111 -0
- package/dist/tools/browser/anthropic.d.ts +51 -0
- package/dist/tools/browser/anthropic.js +2 -1
- package/dist/tools/browser/anthropic.js.map +1 -1
- package/dist/tools/browser/core.d.ts +203 -0
- package/dist/tools/browser/core.js +2 -1
- package/dist/tools/browser/index.d.ts +5 -0
- package/dist/tools/browser/index.js +7 -5
- package/dist/tools/browser/live.cjs +112 -0
- package/dist/tools/browser/live.cjs.map +1 -0
- package/dist/tools/browser/live.d.ts +75 -0
- package/dist/tools/browser/live.js +16 -0
- package/dist/tools/browser/live.js.map +1 -0
- package/dist/tools/browser/openai.d.ts +73 -0
- package/dist/tools/browser/openai.js +2 -1
- package/dist/tools/browser/openai.js.map +1 -1
- package/dist/tools/browser/prompts.d.ts +7 -0
- package/dist/tools/browser/types.d.ts +255 -0
- package/dist/tools/browser/vercel.d.ts +69 -0
- package/dist/tools/browser/vercel.js +2 -1
- package/dist/tools/browser/vercel.js.map +1 -1
- package/dist/tools/codebase_search/anthropic.cjs +2 -5
- package/dist/tools/codebase_search/anthropic.cjs.map +1 -1
- package/dist/tools/codebase_search/anthropic.d.ts +40 -0
- package/dist/tools/codebase_search/anthropic.js +2 -2
- package/dist/tools/codebase_search/core.cjs +3 -6
- package/dist/tools/codebase_search/core.cjs.map +1 -1
- package/dist/tools/codebase_search/core.d.ts +40 -0
- package/dist/tools/codebase_search/core.js +1 -1
- package/dist/tools/codebase_search/index.cjs +2 -5
- package/dist/tools/codebase_search/index.cjs.map +1 -1
- package/dist/tools/codebase_search/index.d.ts +10 -0
- package/dist/tools/codebase_search/index.js +4 -4
- package/dist/tools/codebase_search/openai.cjs +2 -5
- package/dist/tools/codebase_search/openai.cjs.map +1 -1
- package/dist/tools/codebase_search/openai.d.ts +87 -0
- package/dist/tools/codebase_search/openai.js +2 -2
- package/dist/tools/codebase_search/prompts.d.ts +7 -0
- package/dist/tools/codebase_search/types.d.ts +50 -0
- package/dist/tools/codebase_search/vercel.cjs +2 -5
- package/dist/tools/codebase_search/vercel.cjs.map +1 -1
- package/dist/tools/codebase_search/vercel.d.ts +65 -0
- package/dist/tools/codebase_search/vercel.js +2 -2
- package/dist/tools/fastapply/anthropic.cjs +9 -1
- package/dist/tools/fastapply/anthropic.cjs.map +1 -1
- package/dist/tools/fastapply/anthropic.d.ts +4 -0
- package/dist/tools/fastapply/anthropic.js +2 -2
- package/dist/tools/fastapply/core.cjs +9 -1
- package/dist/tools/fastapply/core.cjs.map +1 -1
- package/dist/tools/fastapply/core.d.ts +41 -0
- package/dist/tools/fastapply/core.js +1 -1
- package/dist/tools/fastapply/index.cjs +9 -1
- package/dist/tools/fastapply/index.cjs.map +1 -1
- package/dist/tools/fastapply/index.d.ts +10 -0
- package/dist/tools/fastapply/index.js +6 -6
- package/dist/tools/fastapply/openai.cjs +9 -1
- package/dist/tools/fastapply/openai.cjs.map +1 -1
- package/dist/tools/fastapply/openai.d.ts +4 -0
- package/dist/tools/fastapply/openai.js +2 -2
- package/dist/tools/fastapply/prompts.d.ts +7 -0
- package/dist/tools/fastapply/types.d.ts +77 -0
- package/dist/tools/fastapply/vercel.cjs +9 -1
- package/dist/tools/fastapply/vercel.cjs.map +1 -1
- package/dist/tools/fastapply/vercel.d.ts +4 -0
- package/dist/tools/fastapply/vercel.js +2 -2
- package/dist/tools/index.cjs +9 -1
- package/dist/tools/index.cjs.map +1 -1
- package/dist/tools/index.d.ts +10 -0
- package/dist/tools/index.js +6 -6
- package/dist/tools/utils/resilience.d.ts +58 -0
- package/dist/tools/warp_grep/agent/config.d.ts +8 -0
- package/dist/tools/warp_grep/agent/formatter.d.ts +14 -0
- package/dist/tools/warp_grep/agent/grep_helpers.d.ts +16 -0
- package/dist/tools/warp_grep/agent/parser.d.ts +16 -0
- package/dist/tools/warp_grep/agent/prompt.d.ts +4 -0
- package/dist/tools/warp_grep/agent/runner.d.ts +10 -0
- package/dist/tools/warp_grep/agent/runner.js +6 -6
- package/dist/tools/warp_grep/agent/types.d.ts +44 -0
- package/dist/tools/warp_grep/anthropic.d.ts +14 -0
- package/dist/tools/warp_grep/anthropic.js +7 -7
- package/dist/tools/warp_grep/index.d.ts +11 -0
- package/dist/tools/warp_grep/index.js +9 -9
- package/dist/tools/warp_grep/openai.d.ts +33 -0
- package/dist/tools/warp_grep/openai.js +7 -7
- package/dist/tools/warp_grep/providers/command.d.ts +48 -0
- package/dist/tools/warp_grep/providers/local.d.ts +30 -0
- package/dist/tools/warp_grep/providers/types.d.ts +49 -0
- package/dist/tools/warp_grep/tools/analyse.d.ts +10 -0
- package/dist/tools/warp_grep/tools/finish.d.ts +10 -0
- package/dist/tools/warp_grep/tools/grep.d.ts +8 -0
- package/dist/tools/warp_grep/tools/read.d.ts +9 -0
- package/dist/tools/warp_grep/utils/files.d.ts +3 -0
- package/dist/tools/warp_grep/utils/format.d.ts +4 -0
- package/dist/tools/warp_grep/utils/paths.d.ts +7 -0
- package/dist/tools/warp_grep/utils/ripgrep.d.ts +11 -0
- package/dist/tools/warp_grep/vercel.d.ts +33 -0
- package/dist/tools/warp_grep/vercel.js +7 -7
- package/dist/vercel-B1GZ_g9N.d.ts +69 -0
- package/package.json +2 -3
- package/dist/chunk-4WIBODS7.js.map +0 -1
- package/dist/chunk-AG3ICTC5.js.map +0 -1
- package/dist/chunk-NCVWIW7L.js.map +0 -1
- /package/dist/{chunk-LUI7APXX.js.map → chunk-FP7INILQ.js.map} +0 -0
- /package/dist/{chunk-JSZQVUSE.js.map → chunk-GGBB2HDM.js.map} +0 -0
- /package/dist/{chunk-7MCSSJJA.js.map → chunk-GU3SULV5.js.map} +0 -0
- /package/dist/{chunk-DIWNR3UP.js.map → chunk-O45X46VL.js.map} +0 -0
- /package/dist/{chunk-Y2IY7NYY.js.map → chunk-O5DA5V5S.js.map} +0 -0
- /package/dist/{chunk-4A7UBGLS.js.map → chunk-OUEJ6XEO.js.map} +0 -0
- /package/dist/{chunk-OZMHDB6O.js.map → chunk-PEGZVGG4.js.map} +0 -0
- /package/dist/{chunk-B4H7N4GZ.js.map → chunk-TVFGHXPE.js.map} +0 -0
- /package/dist/{chunk-N5654KQR.js.map → chunk-W3XLPMV3.js.map} +0 -0
- /package/dist/{chunk-Y5RCNDLV.js.map → chunk-X4CQ6D3G.js.map} +0 -0
- /package/dist/{chunk-WHZQDTM6.js.map → chunk-ZRLEAPZV.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../tools/browser/live.ts"],"sourcesContent":["/**\n * Live session utilities for Morph browser sessions\n * \n * Provides helpers for embedding and sharing live browser sessions with WebRTC streaming.\n */\n\nimport type { LiveSessionOptions, IframeOptions } from './types.js';\n\n/**\n * Preset configurations for common use cases\n */\nexport const LIVE_PRESETS = {\n /** Read-only monitoring (no interaction) */\n readonly: { interactive: false } as LiveSessionOptions,\n /** Interactive control (human-in-the-loop) */\n interactive: { interactive: true } as LiveSessionOptions,\n /** Watch-only without controls */\n monitoring: { interactive: false, showControls: false } as LiveSessionOptions,\n} as const;\n\n/**\n * Build a live session URL with query parameters\n * \n * @param debugUrl - Live session debug URL (e.g., from task.debugUrl)\n * @param options - Live session configuration options\n * @returns URL with query parameters for iframe embedding\n * \n * @example\n * ```typescript\n * const url = buildLiveUrl(task.debugUrl, { interactive: true });\n * // Returns: https://example.com/sessions/abc?interactive=true\n * ```\n */\nexport function buildLiveUrl(\n debugUrl: string,\n options: LiveSessionOptions = {}\n): string {\n if (!debugUrl) {\n throw new Error(\n 'debugUrl is required. Ensure your backend returns debugUrl in the task response. ' +\n 'Contact support@morphllm.com if you need help.'\n );\n } \n\n const url = new URL(debugUrl);\n \n // Add query parameters for supported options\n if (options.interactive !== undefined) {\n url.searchParams.set('interactive', String(options.interactive));\n }\n \n if (options.theme) {\n url.searchParams.set('theme', options.theme);\n }\n \n if (options.showControls !== undefined) {\n url.searchParams.set('showControls', String(options.showControls));\n }\n \n if (options.pageId) {\n url.searchParams.set('pageId', options.pageId);\n }\n \n if (options.pageIndex) {\n url.searchParams.set('pageIndex', options.pageIndex);\n }\n \n return url.toString();\n}\n\n/**\n * Build iframe HTML for embedding a live session\n * \n * @param debugUrl - Live session debug URL\n * @param options - Iframe configuration including dimensions and session options\n * @returns HTML iframe element as string\n * \n * @example\n * ```typescript\n * const iframe = buildLiveIframe(task.debugUrl, {\n * interactive: true,\n * width: '100%',\n * height: '600px'\n * });\n * ```\n */\nexport function buildLiveIframe(\n debugUrl: string,\n options: IframeOptions = {}\n): string {\n const {\n width = '100%',\n height = '600px',\n style = '',\n className = '',\n ...sessionOptions\n } = options;\n\n const src = buildLiveUrl(debugUrl, sessionOptions);\n \n // Convert numeric dimensions to pixels\n const widthStr = typeof width === 'number' ? `${width}px` : width;\n const heightStr = typeof height === 'number' ? `${height}px` : height;\n \n // Build style attribute\n const baseStyle = `width: ${widthStr}; height: ${heightStr}; border: none;`;\n const fullStyle = style ? `${baseStyle} ${style}` : baseStyle;\n \n // Build iframe attributes\n const attributes = [\n `src=\"${src}\"`,\n `style=\"${fullStyle}\"`,\n ];\n \n if (className) {\n attributes.push(`class=\"${className}\"`);\n }\n \n return `<iframe ${attributes.join(' ')}></iframe>`;\n}\n\n/**\n * Build complete embed code with HTML snippet\n * \n * @param debugUrl - Live session debug URL\n * @param options - Iframe configuration\n * @returns Multi-line HTML snippet ready to copy-paste\n * \n * @example\n * ```typescript\n * const code = buildEmbedCode(task.debugUrl, { interactive: false });\n * console.log(code);\n * // <!-- Embed Morph Live Session -->\n * // <iframe src=\"...\" style=\"...\"></iframe>\n * ```\n */\nexport function buildEmbedCode(\n debugUrl: string,\n options: IframeOptions = {}\n): string {\n const iframe = buildLiveIframe(debugUrl, options);\n return `<!-- Embed Morph Live Session -->\\n${iframe}`;\n}\n\n/**\n * Get live session options from preset name or custom config\n * \n * @internal\n */\nexport function resolvePreset(\n optionsOrPreset?: string | IframeOptions\n): IframeOptions {\n if (!optionsOrPreset) {\n return {};\n }\n \n if (typeof optionsOrPreset === 'string') {\n const preset = LIVE_PRESETS[optionsOrPreset as keyof typeof LIVE_PRESETS];\n if (!preset) {\n throw new Error(\n `Unknown preset: ${optionsOrPreset}. Available presets: ${Object.keys(LIVE_PRESETS).join(', ')}`\n );\n }\n return preset;\n }\n \n return optionsOrPreset;\n}\n\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWO,IAAM,eAAe;AAAA;AAAA,EAE1B,UAAU,EAAE,aAAa,MAAM;AAAA;AAAA,EAE/B,aAAa,EAAE,aAAa,KAAK;AAAA;AAAA,EAEjC,YAAY,EAAE,aAAa,OAAO,cAAc,MAAM;AACxD;AAeO,SAAS,aACd,UACA,UAA8B,CAAC,GACvB;AACR,MAAI,CAAC,UAAU;AACb,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AAEA,QAAM,MAAM,IAAI,IAAI,QAAQ;AAG5B,MAAI,QAAQ,gBAAgB,QAAW;AACrC,QAAI,aAAa,IAAI,eAAe,OAAO,QAAQ,WAAW,CAAC;AAAA,EACjE;AAEA,MAAI,QAAQ,OAAO;AACjB,QAAI,aAAa,IAAI,SAAS,QAAQ,KAAK;AAAA,EAC7C;AAEA,MAAI,QAAQ,iBAAiB,QAAW;AACtC,QAAI,aAAa,IAAI,gBAAgB,OAAO,QAAQ,YAAY,CAAC;AAAA,EACnE;AAEA,MAAI,QAAQ,QAAQ;AAClB,QAAI,aAAa,IAAI,UAAU,QAAQ,MAAM;AAAA,EAC/C;AAEA,MAAI,QAAQ,WAAW;AACrB,QAAI,aAAa,IAAI,aAAa,QAAQ,SAAS;AAAA,EACrD;AAEA,SAAO,IAAI,SAAS;AACtB;AAkBO,SAAS,gBACd,UACA,UAAyB,CAAC,GAClB;AACR,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,GAAG;AAAA,EACL,IAAI;AAEJ,QAAM,MAAM,aAAa,UAAU,cAAc;AAGjD,QAAM,WAAW,OAAO,UAAU,WAAW,GAAG,KAAK,OAAO;AAC5D,QAAM,YAAY,OAAO,WAAW,WAAW,GAAG,MAAM,OAAO;AAG/D,QAAM,YAAY,UAAU,QAAQ,aAAa,SAAS;AAC1D,QAAM,YAAY,QAAQ,GAAG,SAAS,IAAI,KAAK,KAAK;AAGpD,QAAM,aAAa;AAAA,IACjB,QAAQ,GAAG;AAAA,IACX,UAAU,SAAS;AAAA,EACrB;AAEA,MAAI,WAAW;AACb,eAAW,KAAK,UAAU,SAAS,GAAG;AAAA,EACxC;AAEA,SAAO,WAAW,WAAW,KAAK,GAAG,CAAC;AACxC;AAiBO,SAAS,eACd,UACA,UAAyB,CAAC,GAClB;AACR,QAAM,SAAS,gBAAgB,UAAU,OAAO;AAChD,SAAO;AAAA,EAAsC,MAAM;AACrD;AAOO,SAAS,cACd,iBACe;AACf,MAAI,CAAC,iBAAiB;AACpB,WAAO,CAAC;AAAA,EACV;AAEA,MAAI,OAAO,oBAAoB,UAAU;AACvC,UAAM,SAAS,aAAa,eAA4C;AACxE,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI;AAAA,QACR,mBAAmB,eAAe,wBAAwB,OAAO,KAAK,YAAY,EAAE,KAAK,IAAI,CAAC;AAAA,MAChG;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { LiveSessionOptions, IframeOptions } from './types.js';
|
|
2
|
+
import '../utils/resilience.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Live session utilities for Morph browser sessions
|
|
6
|
+
*
|
|
7
|
+
* Provides helpers for embedding and sharing live browser sessions with WebRTC streaming.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Preset configurations for common use cases
|
|
12
|
+
*/
|
|
13
|
+
declare const LIVE_PRESETS: {
|
|
14
|
+
/** Read-only monitoring (no interaction) */
|
|
15
|
+
readonly readonly: LiveSessionOptions;
|
|
16
|
+
/** Interactive control (human-in-the-loop) */
|
|
17
|
+
readonly interactive: LiveSessionOptions;
|
|
18
|
+
/** Watch-only without controls */
|
|
19
|
+
readonly monitoring: LiveSessionOptions;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Build a live session URL with query parameters
|
|
23
|
+
*
|
|
24
|
+
* @param debugUrl - Live session debug URL (e.g., from task.debugUrl)
|
|
25
|
+
* @param options - Live session configuration options
|
|
26
|
+
* @returns URL with query parameters for iframe embedding
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const url = buildLiveUrl(task.debugUrl, { interactive: true });
|
|
31
|
+
* // Returns: https://example.com/sessions/abc?interactive=true
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
declare function buildLiveUrl(debugUrl: string, options?: LiveSessionOptions): string;
|
|
35
|
+
/**
|
|
36
|
+
* Build iframe HTML for embedding a live session
|
|
37
|
+
*
|
|
38
|
+
* @param debugUrl - Live session debug URL
|
|
39
|
+
* @param options - Iframe configuration including dimensions and session options
|
|
40
|
+
* @returns HTML iframe element as string
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* const iframe = buildLiveIframe(task.debugUrl, {
|
|
45
|
+
* interactive: true,
|
|
46
|
+
* width: '100%',
|
|
47
|
+
* height: '600px'
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
declare function buildLiveIframe(debugUrl: string, options?: IframeOptions): string;
|
|
52
|
+
/**
|
|
53
|
+
* Build complete embed code with HTML snippet
|
|
54
|
+
*
|
|
55
|
+
* @param debugUrl - Live session debug URL
|
|
56
|
+
* @param options - Iframe configuration
|
|
57
|
+
* @returns Multi-line HTML snippet ready to copy-paste
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const code = buildEmbedCode(task.debugUrl, { interactive: false });
|
|
62
|
+
* console.log(code);
|
|
63
|
+
* // <!-- Embed Morph Live Session -->
|
|
64
|
+
* // <iframe src="..." style="..."></iframe>
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
declare function buildEmbedCode(debugUrl: string, options?: IframeOptions): string;
|
|
68
|
+
/**
|
|
69
|
+
* Get live session options from preset name or custom config
|
|
70
|
+
*
|
|
71
|
+
* @internal
|
|
72
|
+
*/
|
|
73
|
+
declare function resolvePreset(optionsOrPreset?: string | IframeOptions): IframeOptions;
|
|
74
|
+
|
|
75
|
+
export { LIVE_PRESETS, buildEmbedCode, buildLiveIframe, buildLiveUrl, resolvePreset };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LIVE_PRESETS,
|
|
3
|
+
buildEmbedCode,
|
|
4
|
+
buildLiveIframe,
|
|
5
|
+
buildLiveUrl,
|
|
6
|
+
resolvePreset
|
|
7
|
+
} from "../../chunk-SQN4DUQS.js";
|
|
8
|
+
import "../../chunk-PZ5AY32C.js";
|
|
9
|
+
export {
|
|
10
|
+
LIVE_PRESETS,
|
|
11
|
+
buildEmbedCode,
|
|
12
|
+
buildLiveIframe,
|
|
13
|
+
buildLiveUrl,
|
|
14
|
+
resolvePreset
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=live.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { ChatCompletionTool } from 'openai/resources/chat/completions.mjs';
|
|
2
|
+
import { BrowserTaskInput, BrowserConfig, BrowserTaskResult } from './types.js';
|
|
3
|
+
import '../utils/resilience.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* OpenAI SDK adapter for browser automation tool
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* OpenAI tool definition for browser automation
|
|
11
|
+
*/
|
|
12
|
+
declare const browserTool: ChatCompletionTool;
|
|
13
|
+
/**
|
|
14
|
+
* Execute a browser task (for use in tool call handling)
|
|
15
|
+
*
|
|
16
|
+
* @param input - Tool input parameters (may be JSON string)
|
|
17
|
+
* @param config - Optional browser worker configuration
|
|
18
|
+
* @returns Task execution result
|
|
19
|
+
*/
|
|
20
|
+
declare function execute(input: BrowserTaskInput | string, config?: BrowserConfig): Promise<BrowserTaskResult>;
|
|
21
|
+
/**
|
|
22
|
+
* Format browser task result for OpenAI tool result
|
|
23
|
+
*
|
|
24
|
+
* Returns a concise summary suitable for agent context. The full result object
|
|
25
|
+
* (with urls, errors, action_history, judgement, etc.) is available when calling
|
|
26
|
+
* execute() directly, but this formatted string omits those details to save tokens.
|
|
27
|
+
*
|
|
28
|
+
* @param result - Browser task result with full history data
|
|
29
|
+
* @returns Formatted string summary for tool result
|
|
30
|
+
*/
|
|
31
|
+
declare function formatResult(result: BrowserTaskResult): string;
|
|
32
|
+
/**
|
|
33
|
+
* Get system prompt for browser automation
|
|
34
|
+
*/
|
|
35
|
+
declare function getSystemPrompt(): string;
|
|
36
|
+
/**
|
|
37
|
+
* Create a configured browser tool with execute and formatResult methods
|
|
38
|
+
*
|
|
39
|
+
* @param config - Browser worker configuration
|
|
40
|
+
* @returns Tool definition with execute and formatResult methods
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* import OpenAI from 'openai';
|
|
45
|
+
* import { createBrowserTool } from 'morphsdk/tools/browser/openai';
|
|
46
|
+
*
|
|
47
|
+
* const tool = createBrowserTool({
|
|
48
|
+
* apiUrl: 'https://browser-worker.example.com'
|
|
49
|
+
* });
|
|
50
|
+
*
|
|
51
|
+
* const client = new OpenAI();
|
|
52
|
+
*
|
|
53
|
+
* const response = await client.chat.completions.create({
|
|
54
|
+
* model: 'gpt-4o',
|
|
55
|
+
* tools: [tool], // tool itself is the ChatCompletionTool
|
|
56
|
+
* messages: [{
|
|
57
|
+
* role: 'user',
|
|
58
|
+
* content: 'Test the checkout at https://3000-abc.e2b.dev'
|
|
59
|
+
* }]
|
|
60
|
+
* });
|
|
61
|
+
*
|
|
62
|
+
* // Execute and format
|
|
63
|
+
* const result = await tool.execute(toolCallArgs);
|
|
64
|
+
* const formatted = tool.formatResult(result);
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
declare function createBrowserTool(config?: BrowserConfig): ChatCompletionTool & {
|
|
68
|
+
execute: (input: BrowserTaskInput | string) => Promise<BrowserTaskResult>;
|
|
69
|
+
formatResult: (result: BrowserTaskResult) => string;
|
|
70
|
+
getSystemPrompt: () => string;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export { browserTool, createBrowserTool, execute, formatResult, getSystemPrompt };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../tools/browser/openai.ts"],"sourcesContent":["/**\n * OpenAI SDK adapter for browser automation tool\n */\n\nimport type { ChatCompletionTool } from 'openai/resources/chat/completions.mjs';\nimport { executeBrowserTask } from './core.js';\nimport type {\n BrowserConfig,\n BrowserTaskInput,\n BrowserTaskResult,\n} from './types.js';\nimport { BROWSER_TOOL_DESCRIPTION, BROWSER_SYSTEM_PROMPT } from './prompts.js';\n\n/**\n * OpenAI tool definition for browser automation\n */\nexport const browserTool: ChatCompletionTool = {\n type: 'function',\n function: {\n name: 'browser_task',\n description: BROWSER_TOOL_DESCRIPTION,\n parameters: {\n type: 'object',\n properties: {\n task: {\n type: 'string',\n description: 'Natural language description of what to do (e.g., \"Test checkout flow for buying a pineapple\")',\n },\n url: {\n type: 'string',\n description: 'Starting URL (e.g., https://3000-xyz.e2b.dev). Required if navigating to a specific page.',\n },\n max_steps: {\n type: 'number',\n description: 'Maximum number of browser actions to take (1-50). Default: 10. Use 15-30 for complex flows.',\n default: 10,\n },\n region: {\n type: 'string',\n enum: ['sfo', 'lon'],\n description: 'Browserless region: sfo (US West Coast) or lon (Europe). Default: sfo.',\n default: 'sfo',\n },\n },\n required: ['task'],\n },\n },\n};\n\n/**\n * Execute a browser task (for use in tool call handling)\n * \n * @param input - Tool input parameters (may be JSON string)\n * @param config - Optional browser worker configuration\n * @returns Task execution result\n */\nexport async function execute(\n input: BrowserTaskInput | string,\n config?: BrowserConfig\n): Promise<BrowserTaskResult> {\n // Parse input if it's a JSON string (from OpenAI tool call)\n const parsedInput = typeof input === 'string' ? JSON.parse(input) : input;\n return executeBrowserTask(parsedInput, config);\n}\n\n/**\n * Format browser task result for OpenAI tool result\n * \n * Returns a concise summary suitable for agent context. The full result object\n * (with urls, errors, action_history, judgement, etc.) is available when calling\n * execute() directly, but this formatted string omits those details to save tokens.\n * \n * @param result - Browser task result with full history data\n * @returns Formatted string summary for tool result\n */\nexport function formatResult(result: BrowserTaskResult): string {\n if (result.success) {\n const parts = [\n '✅ Browser task completed successfully',\n `Steps taken: ${result.steps_taken ?? 0}`,\n result.execution_time_ms ? `Execution time: ${result.execution_time_ms}ms` : null,\n '',\n 'Result:',\n result.result || 'Task completed',\n ];\n return parts.filter(Boolean).join('\\n');\n }\n\n return `❌ Browser task failed: ${result.error || 'Unknown error'}`;\n}\n\n/**\n * Get system prompt for browser automation\n */\nexport function getSystemPrompt(): string {\n return BROWSER_SYSTEM_PROMPT;\n}\n\n/**\n * Create a configured browser tool with execute and formatResult methods\n * \n * @param config - Browser worker configuration\n * @returns Tool definition with execute and formatResult methods\n * \n * @example\n * ```typescript\n * import OpenAI from 'openai';\n * import { createBrowserTool } from 'morphsdk/tools/browser/openai';\n * \n * const tool = createBrowserTool({\n * apiUrl: 'https://browser-worker.example.com'\n * });\n * \n * const client = new OpenAI();\n * \n * const response = await client.chat.completions.create({\n * model: 'gpt-4o',\n * tools: [tool], // tool itself is the ChatCompletionTool\n * messages: [{\n * role: 'user',\n * content: 'Test the checkout at https://3000-abc.e2b.dev'\n * }]\n * });\n * \n * // Execute and format\n * const result = await tool.execute(toolCallArgs);\n * const formatted = tool.formatResult(result);\n * ```\n */\nexport function createBrowserTool(config?: BrowserConfig) {\n return Object.assign({}, browserTool, {\n execute: async (input: BrowserTaskInput | string): Promise<BrowserTaskResult> => {\n return execute(input, config);\n },\n formatResult: (result: BrowserTaskResult): string => {\n return formatResult(result);\n },\n getSystemPrompt: (): string => {\n return getSystemPrompt();\n },\n });\n}\n\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../tools/browser/openai.ts"],"sourcesContent":["/**\n * OpenAI SDK adapter for browser automation tool\n */\n\nimport type { ChatCompletionTool } from 'openai/resources/chat/completions.mjs';\nimport { executeBrowserTask } from './core.js';\nimport type {\n BrowserConfig,\n BrowserTaskInput,\n BrowserTaskResult,\n} from './types.js';\nimport { BROWSER_TOOL_DESCRIPTION, BROWSER_SYSTEM_PROMPT } from './prompts.js';\n\n/**\n * OpenAI tool definition for browser automation\n */\nexport const browserTool: ChatCompletionTool = {\n type: 'function',\n function: {\n name: 'browser_task',\n description: BROWSER_TOOL_DESCRIPTION,\n parameters: {\n type: 'object',\n properties: {\n task: {\n type: 'string',\n description: 'Natural language description of what to do (e.g., \"Test checkout flow for buying a pineapple\")',\n },\n url: {\n type: 'string',\n description: 'Starting URL (e.g., https://3000-xyz.e2b.dev). Required if navigating to a specific page.',\n },\n max_steps: {\n type: 'number',\n description: 'Maximum number of browser actions to take (1-50). Default: 10. Use 15-30 for complex flows.',\n default: 10,\n },\n region: {\n type: 'string',\n enum: ['sfo', 'lon'],\n description: 'Browserless region: sfo (US West Coast) or lon (Europe). Default: sfo.',\n default: 'sfo',\n },\n },\n required: ['task'],\n },\n },\n};\n\n/**\n * Execute a browser task (for use in tool call handling)\n * \n * @param input - Tool input parameters (may be JSON string)\n * @param config - Optional browser worker configuration\n * @returns Task execution result\n */\nexport async function execute(\n input: BrowserTaskInput | string,\n config?: BrowserConfig\n): Promise<BrowserTaskResult> {\n // Parse input if it's a JSON string (from OpenAI tool call)\n const parsedInput = typeof input === 'string' ? JSON.parse(input) : input;\n return executeBrowserTask(parsedInput, config);\n}\n\n/**\n * Format browser task result for OpenAI tool result\n * \n * Returns a concise summary suitable for agent context. The full result object\n * (with urls, errors, action_history, judgement, etc.) is available when calling\n * execute() directly, but this formatted string omits those details to save tokens.\n * \n * @param result - Browser task result with full history data\n * @returns Formatted string summary for tool result\n */\nexport function formatResult(result: BrowserTaskResult): string {\n if (result.success) {\n const parts = [\n '✅ Browser task completed successfully',\n `Steps taken: ${result.steps_taken ?? 0}`,\n result.execution_time_ms ? `Execution time: ${result.execution_time_ms}ms` : null,\n '',\n 'Result:',\n result.result || 'Task completed',\n ];\n return parts.filter(Boolean).join('\\n');\n }\n\n return `❌ Browser task failed: ${result.error || 'Unknown error'}`;\n}\n\n/**\n * Get system prompt for browser automation\n */\nexport function getSystemPrompt(): string {\n return BROWSER_SYSTEM_PROMPT;\n}\n\n/**\n * Create a configured browser tool with execute and formatResult methods\n * \n * @param config - Browser worker configuration\n * @returns Tool definition with execute and formatResult methods\n * \n * @example\n * ```typescript\n * import OpenAI from 'openai';\n * import { createBrowserTool } from 'morphsdk/tools/browser/openai';\n * \n * const tool = createBrowserTool({\n * apiUrl: 'https://browser-worker.example.com'\n * });\n * \n * const client = new OpenAI();\n * \n * const response = await client.chat.completions.create({\n * model: 'gpt-4o',\n * tools: [tool], // tool itself is the ChatCompletionTool\n * messages: [{\n * role: 'user',\n * content: 'Test the checkout at https://3000-abc.e2b.dev'\n * }]\n * });\n * \n * // Execute and format\n * const result = await tool.execute(toolCallArgs);\n * const formatted = tool.formatResult(result);\n * ```\n */\nexport function createBrowserTool(config?: BrowserConfig) {\n return Object.assign({}, browserTool, {\n execute: async (input: BrowserTaskInput | string): Promise<BrowserTaskResult> => {\n return execute(input, config);\n },\n formatResult: (result: BrowserTaskResult): string => {\n return formatResult(result);\n },\n getSystemPrompt: (): string => {\n return getSystemPrompt();\n },\n });\n}\n\n"],"mappings":";;;;;;;;;;;;AAgBO,IAAM,cAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,UAAU;AAAA,IACR,MAAM;AAAA,IACN,aAAa;AAAA,IACb,YAAY;AAAA,MACV,MAAM;AAAA,MACN,YAAY;AAAA,QACV,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,KAAK;AAAA,UACH,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,WAAW;AAAA,UACT,MAAM;AAAA,UACN,aAAa;AAAA,UACb,SAAS;AAAA,QACX;AAAA,QACA,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,MAAM,CAAC,OAAO,KAAK;AAAA,UACnB,aAAa;AAAA,UACb,SAAS;AAAA,QACX;AAAA,MACF;AAAA,MACA,UAAU,CAAC,MAAM;AAAA,IACnB;AAAA,EACF;AACF;AASA,eAAsB,QACpB,OACA,QAC4B;AAE5B,QAAM,cAAc,OAAO,UAAU,WAAW,KAAK,MAAM,KAAK,IAAI;AACpE,SAAO,mBAAmB,aAAa,MAAM;AAC/C;AAYO,SAAS,aAAa,QAAmC;AAC9D,MAAI,OAAO,SAAS;AAClB,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA,gBAAgB,OAAO,eAAe,CAAC;AAAA,MACvC,OAAO,oBAAoB,mBAAmB,OAAO,iBAAiB,OAAO;AAAA,MAC7E;AAAA,MACA;AAAA,MACA,OAAO,UAAU;AAAA,IACnB;AACA,WAAO,MAAM,OAAO,OAAO,EAAE,KAAK,IAAI;AAAA,EACxC;AAEA,SAAO,+BAA0B,OAAO,SAAS,eAAe;AAClE;AAKO,SAAS,kBAA0B;AACxC,SAAO;AACT;AAiCO,SAAS,kBAAkB,QAAwB;AACxD,SAAO,OAAO,OAAO,CAAC,GAAG,aAAa;AAAA,IACpC,SAAS,OAAO,UAAiE;AAC/E,aAAO,QAAQ,OAAO,MAAM;AAAA,IAC9B;AAAA,IACA,cAAc,CAAC,WAAsC;AACnD,aAAO,aAAa,MAAM;AAAA,IAC5B;AAAA,IACA,iBAAiB,MAAc;AAC7B,aAAO,gBAAgB;AAAA,IACzB;AAAA,EACF,CAAC;AACH;","names":[]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool descriptions and prompts for AI models
|
|
3
|
+
*/
|
|
4
|
+
declare const BROWSER_TOOL_DESCRIPTION = "Test and verify your implemented code in a live browser. This tool executes natural language test instructions and returns a video recording plus detailed logs to help you debug issues.\n\n## When to Use\nUse this AFTER coding is complete to verify your implementation:\n- You've finished writing/modifying code and need to verify it works\n- You need to test user interactions end-to-end (clicks, forms, navigation)\n- You want to catch runtime errors, console warnings, or network failures\n- You need visual confirmation that UI elements render and behave correctly\n\n## What You Get Back\nThe tool returns debugging artifacts to help you identify and fix issues:\n- **Video recording**: Watch exactly what happened in the browser session\n- **Console logs**: All console.log, warnings, and errors with timestamps\n- **Network logs**: Failed requests, 404s, API errors with screenshots\n- **Error screenshots**: Visual snapshots captured when errors occur\n\n## How to Write Good Tests\nBe specific about the user journey you're testing:\n\u274C Bad: \"Test the login feature\"\n\u2705 Good: \"Navigate to /login, enter 'test@example.com' and 'password123', click the Login button, verify we reach the /dashboard page\"\n\nInclude verification steps:\n\u2705 \"Click the Add Item button, verify the item appears in the list\"\n\u2705 \"Submit the form, verify a success message is displayed\"\n\n## Iterating on Failures\n1. Run the test and review the video + logs\n2. Identify the specific issue (console error, failed request, wrong behavior)\n3. Fix the code based on the evidence\n4. Re-run the test to verify the fix\n5. Repeat until test passes\n\n## Requirements\n- **URL**: Must be publicly accessible (use tunnels like ngrok, Cloudflare, or deploy to staging)\n- **Timing**: Use this after implementation, not during coding\n- **Complexity**: Set max_steps higher (20-30) for multi-step user workflows";
|
|
5
|
+
declare const BROWSER_SYSTEM_PROMPT = "You are an AI agent designed to automate browser tasks to accomplish the <user_request>. Respond with a valid JSON object in the format: {\"thinking\": \"Reason step-by-step about your current state, history, and the user request to decide your next goal and action. Analyze the browser state and screenshot to confirm the outcome of your last action.\", \"evaluation_previous_goal\": \"A concise, one-sentence evaluation of your last action's outcome (e.g., Success, Failure, or Uncertain).\", \"memory\": \"1-3 sentences summarizing key information and progress so far. This helps you track progress across multiple steps (e.g., items collected, pages visited).\", \"next_goal\": \"A clear, one-sentence description of your immediate next objective.\", \"action\": [{\"action_name\": {\"parameter\": \"value\"}}]}";
|
|
6
|
+
|
|
7
|
+
export { BROWSER_SYSTEM_PROMPT, BROWSER_TOOL_DESCRIPTION };
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { RetryConfig } from '../utils/resilience.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Type definitions for browser automation tool
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Available browser automation models
|
|
9
|
+
*/
|
|
10
|
+
type BrowserModel = 'gemini-flash-latest' | 'morph-computer-use-v0';
|
|
11
|
+
/**
|
|
12
|
+
* Configuration for the browser worker service
|
|
13
|
+
*/
|
|
14
|
+
interface BrowserConfig {
|
|
15
|
+
/** Browser worker API URL (default: https://browser.morphllm.com) */
|
|
16
|
+
apiUrl?: string;
|
|
17
|
+
/** Morph API key for authentication (required in production) */
|
|
18
|
+
apiKey?: string;
|
|
19
|
+
/** Request timeout in milliseconds (default: 1000000) */
|
|
20
|
+
timeout?: number;
|
|
21
|
+
/** Retry configuration for API calls */
|
|
22
|
+
retryConfig?: RetryConfig;
|
|
23
|
+
/** Enable debug logging (default: false) */
|
|
24
|
+
debug?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Input parameters for browser automation task
|
|
28
|
+
*/
|
|
29
|
+
interface BrowserTaskInput {
|
|
30
|
+
/** Natural language description of what to do */
|
|
31
|
+
task: string;
|
|
32
|
+
/** Starting URL (e.g., https://3000-xyz.e2b.dev) */
|
|
33
|
+
url?: string;
|
|
34
|
+
/** Maximum number of browser actions to take (1-50, default: 10) */
|
|
35
|
+
max_steps?: number;
|
|
36
|
+
/** Model to use for task execution (default: morph-computer-use-v0) */
|
|
37
|
+
model?: BrowserModel;
|
|
38
|
+
/** Browserless region: 'sfo' (US West) or 'lon' (Europe) */
|
|
39
|
+
region?: 'sfo' | 'lon';
|
|
40
|
+
/** Enable stealth mode to avoid bot detection (default: true) */
|
|
41
|
+
stealth?: boolean;
|
|
42
|
+
/** Browser viewport width (default: 1280) */
|
|
43
|
+
viewport_width?: number;
|
|
44
|
+
/** Browser viewport height (default: 720) */
|
|
45
|
+
viewport_height?: number;
|
|
46
|
+
/** User-defined reference/tracking ID (e.g., "PR-1234", "jira-PROJ-567") */
|
|
47
|
+
external_id?: string;
|
|
48
|
+
/** Optional repository ID to associate with this session */
|
|
49
|
+
repo_id?: string;
|
|
50
|
+
/** Optional commit UUID to associate with this session */
|
|
51
|
+
commit_id?: string;
|
|
52
|
+
/** Record session video to S3 (default: false) */
|
|
53
|
+
record_video?: boolean;
|
|
54
|
+
/** Video width (default: 1280) */
|
|
55
|
+
video_width?: number;
|
|
56
|
+
/** Video height (default: 720) */
|
|
57
|
+
video_height?: number;
|
|
58
|
+
/** Serialized structured output schema (internal use) */
|
|
59
|
+
structured_output?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Input with Zod schema for structured output
|
|
63
|
+
*/
|
|
64
|
+
interface BrowserTaskInputWithSchema<T> extends Omit<BrowserTaskInput, 'structured_output'> {
|
|
65
|
+
/** Zod schema for structured output */
|
|
66
|
+
schema: any;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Result from executing a browser task
|
|
70
|
+
*/
|
|
71
|
+
interface BrowserTaskResult {
|
|
72
|
+
/** Whether the task completed successfully */
|
|
73
|
+
success: boolean;
|
|
74
|
+
/** Task result or findings */
|
|
75
|
+
result?: string;
|
|
76
|
+
/** Error message if task failed */
|
|
77
|
+
error?: string;
|
|
78
|
+
/** Number of browser actions taken */
|
|
79
|
+
steps_taken?: number;
|
|
80
|
+
/** Total execution time in milliseconds */
|
|
81
|
+
execution_time_ms?: number;
|
|
82
|
+
/** All URLs visited during execution */
|
|
83
|
+
urls?: (string | null)[];
|
|
84
|
+
/** Names of all actions executed */
|
|
85
|
+
action_names?: string[];
|
|
86
|
+
/** Per-step errors (null for steps without errors) */
|
|
87
|
+
errors?: (string | null)[];
|
|
88
|
+
/** All model actions with parameters */
|
|
89
|
+
model_actions?: any[];
|
|
90
|
+
/** Whether agent marked task as done */
|
|
91
|
+
is_done?: boolean;
|
|
92
|
+
/** Truncated action history with essential fields */
|
|
93
|
+
action_history?: any[][];
|
|
94
|
+
/** All action results */
|
|
95
|
+
action_results?: any[];
|
|
96
|
+
/** Whether any errors occurred */
|
|
97
|
+
has_errors?: boolean;
|
|
98
|
+
/** Total number of steps executed */
|
|
99
|
+
number_of_steps?: number;
|
|
100
|
+
/** Judge validation result if available */
|
|
101
|
+
judgement?: {
|
|
102
|
+
reasoning?: string;
|
|
103
|
+
verdict: boolean;
|
|
104
|
+
failure_reason?: string;
|
|
105
|
+
impossible_task?: boolean;
|
|
106
|
+
reached_captcha?: boolean;
|
|
107
|
+
};
|
|
108
|
+
/** Whether judge validated the execution */
|
|
109
|
+
is_validated?: boolean;
|
|
110
|
+
/** UUID of saved replay record (if session replay enabled) */
|
|
111
|
+
replay_id?: string;
|
|
112
|
+
/** Browserless replay URL (if session replay enabled) */
|
|
113
|
+
replay_url?: string;
|
|
114
|
+
/** Recording ID (if record_video=true) */
|
|
115
|
+
recording_id?: string;
|
|
116
|
+
/** Recording status: PENDING, PROCESSING, COMPLETED, ERROR */
|
|
117
|
+
recording_status?: string;
|
|
118
|
+
/** Task ID for async task tracking */
|
|
119
|
+
task_id?: string;
|
|
120
|
+
/** Task status: pending, running, completed, failed */
|
|
121
|
+
status?: string;
|
|
122
|
+
/** Structured output (JSON string) */
|
|
123
|
+
output?: string;
|
|
124
|
+
/** Live session debug URL for real-time viewing (WebRTC streaming) */
|
|
125
|
+
debugUrl?: string;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Configuration for live session viewing
|
|
129
|
+
*/
|
|
130
|
+
interface LiveSessionOptions {
|
|
131
|
+
/** Enable or disable remote control (default: true for headful, varies for headless) */
|
|
132
|
+
interactive?: boolean;
|
|
133
|
+
/** UI theme: 'dark' or 'light' (headless only, default: 'dark') */
|
|
134
|
+
theme?: 'dark' | 'light';
|
|
135
|
+
/** Show or hide navigation controls (headless only, default: true) */
|
|
136
|
+
showControls?: boolean;
|
|
137
|
+
/** Focus view on specific page/tab ID (headless only) */
|
|
138
|
+
pageId?: string;
|
|
139
|
+
/** Display specific tab by index (headless only) */
|
|
140
|
+
pageIndex?: string;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Configuration for iframe generation
|
|
144
|
+
*/
|
|
145
|
+
interface IframeOptions extends LiveSessionOptions {
|
|
146
|
+
/** Iframe width (default: '100%') */
|
|
147
|
+
width?: string | number;
|
|
148
|
+
/** Iframe height (default: '600px') */
|
|
149
|
+
height?: string | number;
|
|
150
|
+
/** Additional inline styles */
|
|
151
|
+
style?: string;
|
|
152
|
+
/** CSS class name */
|
|
153
|
+
className?: string;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Task result with convenience methods for async execution
|
|
157
|
+
*/
|
|
158
|
+
interface BrowserTaskWithPromise extends BrowserTaskResult {
|
|
159
|
+
task_id: string;
|
|
160
|
+
/** Live URL to watch task execution in real-time */
|
|
161
|
+
liveUrl: string;
|
|
162
|
+
/** Wait for task completion */
|
|
163
|
+
complete: (pollConfig?: {
|
|
164
|
+
interval?: number;
|
|
165
|
+
timeout?: number;
|
|
166
|
+
}) => Promise<BrowserTaskResult>;
|
|
167
|
+
/** Get live session URL with optional parameters (Steel.dev) - throws if debugUrl not available */
|
|
168
|
+
getLiveUrl: (options?: LiveSessionOptions) => string;
|
|
169
|
+
/** Get iframe HTML for embedding live session - throws if debugUrl not available */
|
|
170
|
+
getLiveIframe: (optionsOrPreset?: string | IframeOptions) => string;
|
|
171
|
+
/** Get complete embed code snippet - throws if debugUrl not available */
|
|
172
|
+
getEmbedCode: () => string;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Task result with schema validation
|
|
176
|
+
*/
|
|
177
|
+
interface BrowserTaskWithPromiseAndSchema<T> extends BrowserTaskResult {
|
|
178
|
+
task_id: string;
|
|
179
|
+
/** Live URL to watch task execution in real-time */
|
|
180
|
+
liveUrl: string;
|
|
181
|
+
/** Parsed and validated output */
|
|
182
|
+
parsed: T | null;
|
|
183
|
+
/** Wait for task completion with schema validation */
|
|
184
|
+
complete: (pollConfig?: {
|
|
185
|
+
interval?: number;
|
|
186
|
+
timeout?: number;
|
|
187
|
+
}) => Promise<BrowserTaskResult & {
|
|
188
|
+
parsed: T | null;
|
|
189
|
+
}>;
|
|
190
|
+
/** Get live session URL with optional parameters - throws if debugUrl not available */
|
|
191
|
+
getLiveUrl: (options?: LiveSessionOptions) => string;
|
|
192
|
+
/** Get iframe HTML for embedding live session - throws if debugUrl not available */
|
|
193
|
+
getLiveIframe: (optionsOrPreset?: string | IframeOptions) => string;
|
|
194
|
+
/** Get complete embed code snippet - throws if debugUrl not available */
|
|
195
|
+
getEmbedCode: () => string;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Recording status and metadata
|
|
199
|
+
*/
|
|
200
|
+
interface RecordingStatus {
|
|
201
|
+
/** Recording ID */
|
|
202
|
+
id: string;
|
|
203
|
+
/** Current status */
|
|
204
|
+
status: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'ERROR';
|
|
205
|
+
/** Presigned S3 URL for rrweb replay JSON (interactive DOM replay) */
|
|
206
|
+
replay_url?: string;
|
|
207
|
+
/** Presigned S3 URL for network logs (NDJSON format) */
|
|
208
|
+
network_url?: string;
|
|
209
|
+
/** Presigned S3 URL for console logs (NDJSON format) */
|
|
210
|
+
console_url?: string;
|
|
211
|
+
/** Presigned S3 URL for native browser video (WebM or MP4 format, real-time recording) */
|
|
212
|
+
video_url?: string;
|
|
213
|
+
/** Total rrweb events captured */
|
|
214
|
+
total_events?: number;
|
|
215
|
+
/** Total bytes of all files */
|
|
216
|
+
file_size?: number;
|
|
217
|
+
/** Duration in milliseconds */
|
|
218
|
+
duration?: number;
|
|
219
|
+
/** Error message if status=ERROR */
|
|
220
|
+
error?: string;
|
|
221
|
+
/** When recording was created */
|
|
222
|
+
created_at: string;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Browser error with screenshot captured at error time
|
|
226
|
+
*/
|
|
227
|
+
interface BrowserError {
|
|
228
|
+
/** Error type: console error or network error */
|
|
229
|
+
type: 'console' | 'network';
|
|
230
|
+
/** Error message */
|
|
231
|
+
message: string;
|
|
232
|
+
/** URL where error occurred */
|
|
233
|
+
url?: string;
|
|
234
|
+
/** CDP timestamp in seconds since browser start */
|
|
235
|
+
timestamp: number;
|
|
236
|
+
/** Presigned S3 URL to screenshot JPEG (captured 500ms after error) */
|
|
237
|
+
screenshot_url?: string;
|
|
238
|
+
/** When screenshot was captured (Unix timestamp) */
|
|
239
|
+
captured_at?: number;
|
|
240
|
+
/** HTTP status code (for network errors) */
|
|
241
|
+
status?: number;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Response from getErrors()
|
|
245
|
+
*/
|
|
246
|
+
interface ErrorsResponse {
|
|
247
|
+
/** Recording ID */
|
|
248
|
+
recording_id: string;
|
|
249
|
+
/** Total number of errors */
|
|
250
|
+
total_errors: number;
|
|
251
|
+
/** Errors with real-time screenshots */
|
|
252
|
+
errors: BrowserError[];
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export type { BrowserConfig, BrowserError, BrowserModel, BrowserTaskInput, BrowserTaskInputWithSchema, BrowserTaskResult, BrowserTaskWithPromise, BrowserTaskWithPromiseAndSchema, ErrorsResponse, IframeOptions, LiveSessionOptions, RecordingStatus };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import * as ai from 'ai';
|
|
2
|
+
import { BrowserConfig } from './types.js';
|
|
3
|
+
import '../utils/resilience.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Create Vercel AI SDK tool for browser automation
|
|
7
|
+
*
|
|
8
|
+
* @param config - Optional browser worker configuration
|
|
9
|
+
* @returns Vercel AI SDK tool
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { generateText } from 'ai';
|
|
14
|
+
* import { anthropic } from '@ai-sdk/anthropic';
|
|
15
|
+
* import { createBrowserTool } from 'morphsdk/tools/browser/vercel';
|
|
16
|
+
*
|
|
17
|
+
* const browserTool = createBrowserTool({
|
|
18
|
+
* apiUrl: 'https://browser-worker.example.com'
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* const result = await generateText({
|
|
22
|
+
* model: anthropic('claude-sonnet-4-5-20250929'),
|
|
23
|
+
* tools: { browserTask: browserTool },
|
|
24
|
+
* prompt: 'Test the checkout flow at https://3000-abc.e2b.dev',
|
|
25
|
+
* maxSteps: 5
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
declare function createBrowserTool(config?: BrowserConfig): ai.Tool<{
|
|
30
|
+
task: string;
|
|
31
|
+
max_steps: number;
|
|
32
|
+
region: "sfo" | "lon";
|
|
33
|
+
url?: string | undefined;
|
|
34
|
+
}, {
|
|
35
|
+
success: boolean;
|
|
36
|
+
result: string | undefined;
|
|
37
|
+
steps_taken: number | undefined;
|
|
38
|
+
execution_time_ms: number | undefined;
|
|
39
|
+
error?: undefined;
|
|
40
|
+
} | {
|
|
41
|
+
success: boolean;
|
|
42
|
+
error: string | undefined;
|
|
43
|
+
result?: undefined;
|
|
44
|
+
steps_taken?: undefined;
|
|
45
|
+
execution_time_ms?: undefined;
|
|
46
|
+
}>;
|
|
47
|
+
/**
|
|
48
|
+
* Default browser tool for Vercel AI SDK
|
|
49
|
+
*/
|
|
50
|
+
declare const browserTool: ai.Tool<{
|
|
51
|
+
task: string;
|
|
52
|
+
max_steps: number;
|
|
53
|
+
region: "sfo" | "lon";
|
|
54
|
+
url?: string | undefined;
|
|
55
|
+
}, {
|
|
56
|
+
success: boolean;
|
|
57
|
+
result: string | undefined;
|
|
58
|
+
steps_taken: number | undefined;
|
|
59
|
+
execution_time_ms: number | undefined;
|
|
60
|
+
error?: undefined;
|
|
61
|
+
} | {
|
|
62
|
+
success: boolean;
|
|
63
|
+
error: string | undefined;
|
|
64
|
+
result?: undefined;
|
|
65
|
+
steps_taken?: undefined;
|
|
66
|
+
execution_time_ms?: undefined;
|
|
67
|
+
}>;
|
|
68
|
+
|
|
69
|
+
export { browserTool, createBrowserTool };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../tools/browser/vercel.ts"],"sourcesContent":["/**\n * Vercel AI SDK adapter for browser automation tool\n */\n\nimport { tool as createTool } from 'ai';\nimport { z } from 'zod';\nimport { executeBrowserTask } from './core.js';\nimport type { BrowserConfig } from './types.js';\nimport { BROWSER_TOOL_DESCRIPTION } from './prompts.js';\n\n/**\n * Create Vercel AI SDK tool for browser automation\n * \n * @param config - Optional browser worker configuration\n * @returns Vercel AI SDK tool\n * \n * @example\n * ```typescript\n * import { generateText } from 'ai';\n * import { anthropic } from '@ai-sdk/anthropic';\n * import { createBrowserTool } from 'morphsdk/tools/browser/vercel';\n * \n * const browserTool = createBrowserTool({\n * apiUrl: 'https://browser-worker.example.com'\n * });\n * \n * const result = await generateText({\n * model: anthropic('claude-sonnet-4-5-20250929'),\n * tools: { browserTask: browserTool },\n * prompt: 'Test the checkout flow at https://3000-abc.e2b.dev',\n * maxSteps: 5\n * });\n * ```\n */\nexport function createBrowserTool(config?: BrowserConfig) {\n const schema = z.object({\n task: z.string().describe('Natural language description of what to do (e.g., \"Test checkout flow for buying a pineapple\")'),\n url: z.string().optional().describe('Starting URL (e.g., https://3000-xyz.e2b.dev)'),\n max_steps: z.number().min(1).max(50).default(10).describe('Maximum number of browser actions to take'),\n region: z.enum(['sfo', 'lon']).default('sfo').describe('Browserless region: sfo (US West) or lon (Europe)'),\n });\n\n return createTool({\n description: BROWSER_TOOL_DESCRIPTION,\n inputSchema: schema,\n execute: async (params) => {\n const { task, url, max_steps, region } = params;\n const result = await executeBrowserTask(\n { task, url, max_steps, region },\n config\n );\n\n // Return minimal summary for agent context (to save tokens)\n // Full result with urls, errors, action_history, judgement, etc. is available\n // when calling executeBrowserTask() directly outside of agent tools\n if (result.success) {\n return {\n success: true,\n result: result.result,\n steps_taken: result.steps_taken,\n execution_time_ms: result.execution_time_ms,\n };\n }\n\n return {\n success: false,\n error: result.error,\n };\n },\n });\n}\n\n/**\n * Default browser tool for Vercel AI SDK\n */\nexport const browserTool = createBrowserTool();\n\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../tools/browser/vercel.ts"],"sourcesContent":["/**\n * Vercel AI SDK adapter for browser automation tool\n */\n\nimport { tool as createTool } from 'ai';\nimport { z } from 'zod';\nimport { executeBrowserTask } from './core.js';\nimport type { BrowserConfig } from './types.js';\nimport { BROWSER_TOOL_DESCRIPTION } from './prompts.js';\n\n/**\n * Create Vercel AI SDK tool for browser automation\n * \n * @param config - Optional browser worker configuration\n * @returns Vercel AI SDK tool\n * \n * @example\n * ```typescript\n * import { generateText } from 'ai';\n * import { anthropic } from '@ai-sdk/anthropic';\n * import { createBrowserTool } from 'morphsdk/tools/browser/vercel';\n * \n * const browserTool = createBrowserTool({\n * apiUrl: 'https://browser-worker.example.com'\n * });\n * \n * const result = await generateText({\n * model: anthropic('claude-sonnet-4-5-20250929'),\n * tools: { browserTask: browserTool },\n * prompt: 'Test the checkout flow at https://3000-abc.e2b.dev',\n * maxSteps: 5\n * });\n * ```\n */\nexport function createBrowserTool(config?: BrowserConfig) {\n const schema = z.object({\n task: z.string().describe('Natural language description of what to do (e.g., \"Test checkout flow for buying a pineapple\")'),\n url: z.string().optional().describe('Starting URL (e.g., https://3000-xyz.e2b.dev)'),\n max_steps: z.number().min(1).max(50).default(10).describe('Maximum number of browser actions to take'),\n region: z.enum(['sfo', 'lon']).default('sfo').describe('Browserless region: sfo (US West) or lon (Europe)'),\n });\n\n return createTool({\n description: BROWSER_TOOL_DESCRIPTION,\n inputSchema: schema,\n execute: async (params) => {\n const { task, url, max_steps, region } = params;\n const result = await executeBrowserTask(\n { task, url, max_steps, region },\n config\n );\n\n // Return minimal summary for agent context (to save tokens)\n // Full result with urls, errors, action_history, judgement, etc. is available\n // when calling executeBrowserTask() directly outside of agent tools\n if (result.success) {\n return {\n success: true,\n result: result.result,\n steps_taken: result.steps_taken,\n execution_time_ms: result.execution_time_ms,\n };\n }\n\n return {\n success: false,\n error: result.error,\n };\n },\n });\n}\n\n/**\n * Default browser tool for Vercel AI SDK\n */\nexport const browserTool = createBrowserTool();\n\n"],"mappings":";;;;;;;;;;;AAIA,SAAS,QAAQ,kBAAkB;AACnC,SAAS,SAAS;AA6BX,SAAS,kBAAkB,QAAwB;AACxD,QAAM,SAAS,EAAE,OAAO;AAAA,IACtB,MAAM,EAAE,OAAO,EAAE,SAAS,gGAAgG;AAAA,IAC1H,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,+CAA+C;AAAA,IACnF,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,EAAE,SAAS,2CAA2C;AAAA,IACrG,QAAQ,EAAE,KAAK,CAAC,OAAO,KAAK,CAAC,EAAE,QAAQ,KAAK,EAAE,SAAS,mDAAmD;AAAA,EAC5G,CAAC;AAED,SAAO,WAAW;AAAA,IAChB,aAAa;AAAA,IACb,aAAa;AAAA,IACb,SAAS,OAAO,WAAW;AACzB,YAAM,EAAE,MAAM,KAAK,WAAW,OAAO,IAAI;AACzC,YAAM,SAAS,MAAM;AAAA,QACnB,EAAE,MAAM,KAAK,WAAW,OAAO;AAAA,QAC/B;AAAA,MACF;AAKA,UAAI,OAAO,SAAS;AAClB,eAAO;AAAA,UACL,SAAS;AAAA,UACT,QAAQ,OAAO;AAAA,UACf,aAAa,OAAO;AAAA,UACpB,mBAAmB,OAAO;AAAA,QAC5B;AAAA,MACF;AAEA,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO,OAAO;AAAA,MAChB;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAKO,IAAM,cAAc,kBAAkB;","names":[]}
|
|
@@ -104,12 +104,11 @@ async function executeCodebaseSearch(input, config) {
|
|
|
104
104
|
if (!apiKey) {
|
|
105
105
|
throw new Error("MORPH_API_KEY not found. Set environment variable or pass in config");
|
|
106
106
|
}
|
|
107
|
-
const searchUrl = config.searchUrl || process.env.MORPH_SEARCH_URL || "
|
|
107
|
+
const searchUrl = config.searchUrl || process.env.MORPH_SEARCH_URL || "https://repos.morphllm.com";
|
|
108
108
|
const timeout = config.timeout || 3e4;
|
|
109
109
|
const debug = config.debug || false;
|
|
110
110
|
if (debug) {
|
|
111
|
-
|
|
112
|
-
console.log(`[CodebaseSearch] Query: "${input.query.slice(0, 60)}..." repo=${config.repoId} (${ref})`);
|
|
111
|
+
console.log(`[CodebaseSearch] Query: "${input.query.slice(0, 60)}..." repo=${config.repoId}`);
|
|
113
112
|
console.log(`[CodebaseSearch] URL: ${searchUrl}/v1/codebase_search`);
|
|
114
113
|
}
|
|
115
114
|
const startTime = Date.now();
|
|
@@ -125,8 +124,6 @@ async function executeCodebaseSearch(input, config) {
|
|
|
125
124
|
body: JSON.stringify({
|
|
126
125
|
query: input.query,
|
|
127
126
|
repoId: config.repoId,
|
|
128
|
-
branch: config.branch,
|
|
129
|
-
commitHash: config.commitHash,
|
|
130
127
|
targetDirectories: input.target_directories || [],
|
|
131
128
|
limit: input.limit || 10,
|
|
132
129
|
candidateLimit: 50
|