@morphllm/morphsdk 0.2.40 → 0.2.41
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-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-Y2IY7NYY.js → chunk-O5DA5V5S.js} +2 -2
- package/dist/{chunk-4A7UBGLS.js → chunk-OUEJ6XEO.js} +2 -2
- package/dist/chunk-SQN4DUQS.js +84 -0
- package/dist/chunk-SQN4DUQS.js.map +1 -0
- package/dist/{chunk-N5654KQR.js → chunk-W3XLPMV3.js} +15 -15
- package/dist/{chunk-DIWNR3UP.js → chunk-W7NRFNLI.js} +4 -4
- package/dist/{chunk-AG3ICTC5.js → chunk-WM77HRKO.js} +4 -7
- package/dist/chunk-WM77HRKO.js.map +1 -0
- package/dist/{chunk-WHZQDTM6.js → chunk-ZRLEAPZV.js} +2 -2
- package/dist/client.cjs +3 -6
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.ts +114 -0
- package/dist/client.js +5 -4
- 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 +3 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +14 -0
- package/dist/index.js +5 -4
- 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 +6 -6
- 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.d.ts +4 -0
- package/dist/tools/fastapply/core.d.ts +41 -0
- package/dist/tools/fastapply/index.d.ts +10 -0
- package/dist/tools/fastapply/openai.d.ts +4 -0
- package/dist/tools/fastapply/prompts.d.ts +7 -0
- package/dist/tools/fastapply/types.d.ts +77 -0
- package/dist/tools/fastapply/vercel.d.ts +4 -0
- package/dist/tools/index.d.ts +10 -0
- 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-Y2IY7NYY.js.map → chunk-O5DA5V5S.js.map} +0 -0
- /package/dist/{chunk-4A7UBGLS.js.map → chunk-OUEJ6XEO.js.map} +0 -0
- /package/dist/{chunk-N5654KQR.js.map → chunk-W3XLPMV3.js.map} +0 -0
- /package/dist/{chunk-DIWNR3UP.js.map → chunk-W7NRFNLI.js.map} +0 -0
- /package/dist/{chunk-WHZQDTM6.js.map → chunk-ZRLEAPZV.js.map} +0 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { RouterConfig, Provider, RouterInput, RouterResult, RawRouterResult } from './types.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Core implementation for intelligent model routing
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
declare abstract class BaseRouter {
|
|
8
|
+
protected config: Required<Omit<RouterConfig, 'apiKey' | 'retryConfig'>> & Pick<RouterConfig, 'apiKey' | 'retryConfig'>;
|
|
9
|
+
protected provider: Provider;
|
|
10
|
+
constructor(provider: Provider, config?: RouterConfig);
|
|
11
|
+
/**
|
|
12
|
+
* Select the optimal model for a given input and mode
|
|
13
|
+
*/
|
|
14
|
+
selectModel(input: RouterInput): Promise<RouterResult>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* OpenAI model router for GPT-5 series
|
|
18
|
+
*/
|
|
19
|
+
declare class OpenAIRouter extends BaseRouter {
|
|
20
|
+
constructor(config?: RouterConfig);
|
|
21
|
+
/**
|
|
22
|
+
* Select optimal GPT-5 model
|
|
23
|
+
*
|
|
24
|
+
* @param input - User input and mode
|
|
25
|
+
* @returns Selected model name (gpt-5-mini | gpt-5-low | gpt-5-medium | gpt-5-high)
|
|
26
|
+
*/
|
|
27
|
+
selectModel(input: RouterInput): Promise<RouterResult>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Anthropic model router for Claude 4.5 series
|
|
31
|
+
*/
|
|
32
|
+
declare class AnthropicRouter extends BaseRouter {
|
|
33
|
+
constructor(config?: RouterConfig);
|
|
34
|
+
/**
|
|
35
|
+
* Select optimal Claude model
|
|
36
|
+
*
|
|
37
|
+
* @param input - User input and mode
|
|
38
|
+
* @returns Selected model name (claude-4.5-haiku | claude-4.5-sonnet)
|
|
39
|
+
*/
|
|
40
|
+
selectModel(input: RouterInput): Promise<RouterResult>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Google Gemini model router
|
|
44
|
+
*/
|
|
45
|
+
declare class GeminiRouter extends BaseRouter {
|
|
46
|
+
constructor(config?: RouterConfig);
|
|
47
|
+
/**
|
|
48
|
+
* Select optimal Gemini model
|
|
49
|
+
*
|
|
50
|
+
* @param input - User input and mode
|
|
51
|
+
* @returns Selected model name (gemini-2.5-flash | gemini-2.5-pro)
|
|
52
|
+
*/
|
|
53
|
+
selectModel(input: RouterInput): Promise<RouterResult>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Raw difficulty classification router (no provider-specific mapping)
|
|
57
|
+
*/
|
|
58
|
+
declare class RawRouter extends BaseRouter {
|
|
59
|
+
constructor(config?: RouterConfig);
|
|
60
|
+
/**
|
|
61
|
+
* Get raw difficulty classification
|
|
62
|
+
*
|
|
63
|
+
* @param input - User input and mode
|
|
64
|
+
* @returns Raw difficulty (easy | medium | hard | needs-info)
|
|
65
|
+
*/
|
|
66
|
+
classify(input: RouterInput): Promise<RawRouterResult>;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export { AnthropicRouter, GeminiRouter, OpenAIRouter, RawRouter };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model router types for intelligent model selection
|
|
3
|
+
*/
|
|
4
|
+
type ComplexityLevel = 'easy' | 'medium' | 'hard' | 'needs-info';
|
|
5
|
+
type RouterMode = 'balanced' | 'aggressive';
|
|
6
|
+
type Provider = 'openai' | 'anthropic' | 'gemini';
|
|
7
|
+
interface RouterConfig {
|
|
8
|
+
/** Morph API key (defaults to MORPH_API_KEY env var) */
|
|
9
|
+
apiKey?: string;
|
|
10
|
+
/** Router API URL (defaults to https://api.morphllm.com) */
|
|
11
|
+
apiUrl?: string;
|
|
12
|
+
/** Request timeout in milliseconds (default: 10000) */
|
|
13
|
+
timeout?: number;
|
|
14
|
+
/** Enable debug logging */
|
|
15
|
+
debug?: boolean;
|
|
16
|
+
/** Retry configuration */
|
|
17
|
+
retryConfig?: {
|
|
18
|
+
maxRetries?: number;
|
|
19
|
+
initialDelay?: number;
|
|
20
|
+
maxDelay?: number;
|
|
21
|
+
backoffMultiplier?: number;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
interface RouterInput {
|
|
25
|
+
/** User input or task description */
|
|
26
|
+
input: string;
|
|
27
|
+
/** Routing mode: balanced (cheaper models) or aggressive (more capable models) */
|
|
28
|
+
mode?: RouterMode;
|
|
29
|
+
}
|
|
30
|
+
interface RouterResult {
|
|
31
|
+
/** Selected model name */
|
|
32
|
+
model: string;
|
|
33
|
+
}
|
|
34
|
+
interface RawRouterResult {
|
|
35
|
+
/** Raw difficulty classification */
|
|
36
|
+
difficulty: ComplexityLevel;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type { ComplexityLevel, Provider, RawRouterResult, RouterConfig, RouterInput, RouterMode, RouterResult };
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { ChatCompletionTool } from 'openai/resources/chat/completions';
|
|
2
|
+
import { EditFileInput, EditFileConfig, EditFileResult } from './tools/fastapply/types.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* OpenAI SDK adapter for edit_file tool
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* OpenAI-native tool definition for edit_file
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import OpenAI from 'openai';
|
|
14
|
+
* import { editFileTool } from 'morphsdk/tools/openai';
|
|
15
|
+
*
|
|
16
|
+
* const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
|
|
17
|
+
*
|
|
18
|
+
* const response = await client.chat.completions.create({
|
|
19
|
+
* model: "gpt-4o",
|
|
20
|
+
* tools: [editFileTool],
|
|
21
|
+
* messages: [{ role: "user", content: "Fix the bug in app.ts" }]
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
declare const editFileTool: ChatCompletionTool;
|
|
26
|
+
/**
|
|
27
|
+
* Execute an edit_file tool call
|
|
28
|
+
*
|
|
29
|
+
* @param input - The tool input from GPT (parsed from tool_calls)
|
|
30
|
+
* @param config - Optional configuration
|
|
31
|
+
* @returns The result of the edit operation
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* const args = JSON.parse(toolCall.function.arguments);
|
|
36
|
+
* const result = await execute(args);
|
|
37
|
+
* console.log('Changes applied:', result.udiff);
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
declare function execute(input: EditFileInput, config?: EditFileConfig): Promise<EditFileResult>;
|
|
41
|
+
/**
|
|
42
|
+
* Get the system prompt for edit_file usage
|
|
43
|
+
*
|
|
44
|
+
* Add this to your system message to guide GPT on using edit_file properly.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* const response = await client.chat.completions.create({
|
|
49
|
+
* model: "gpt-4o",
|
|
50
|
+
* messages: [
|
|
51
|
+
* { role: "system", content: getSystemPrompt() },
|
|
52
|
+
* { role: "user", content: "Fix bugs" }
|
|
53
|
+
* ],
|
|
54
|
+
* tools: [editFileTool]
|
|
55
|
+
* });
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
declare function getSystemPrompt(): string;
|
|
59
|
+
/**
|
|
60
|
+
* Format the result for passing back to GPT
|
|
61
|
+
*
|
|
62
|
+
* @param result - The edit result
|
|
63
|
+
* @returns Formatted string for tool message
|
|
64
|
+
*/
|
|
65
|
+
declare function formatResult(result: EditFileResult): string;
|
|
66
|
+
/**
|
|
67
|
+
* Create a custom edit_file tool with configuration and methods
|
|
68
|
+
*
|
|
69
|
+
* @param config - Configuration options
|
|
70
|
+
* @returns Tool definition with execute and formatResult methods
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```ts
|
|
74
|
+
* import OpenAI from 'openai';
|
|
75
|
+
* import { createEditFileTool } from 'morphsdk/tools/fastapply/openai';
|
|
76
|
+
*
|
|
77
|
+
* const tool = createEditFileTool({
|
|
78
|
+
* baseDir: './src',
|
|
79
|
+
* generateUdiff: true,
|
|
80
|
+
* description: 'Custom tool description for your use case'
|
|
81
|
+
* });
|
|
82
|
+
*
|
|
83
|
+
* const client = new OpenAI();
|
|
84
|
+
*
|
|
85
|
+
* const response = await client.chat.completions.create({
|
|
86
|
+
* model: 'gpt-4o',
|
|
87
|
+
* tools: [tool], // tool itself is the ChatCompletionTool
|
|
88
|
+
* messages: [{ role: 'user', content: 'Fix bug in app.ts' }]
|
|
89
|
+
* });
|
|
90
|
+
*
|
|
91
|
+
* // Execute and format
|
|
92
|
+
* const result = await tool.execute(toolCallArgs);
|
|
93
|
+
* const formatted = tool.formatResult(result);
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
declare function createEditFileTool(config?: EditFileConfig): ChatCompletionTool & {
|
|
97
|
+
execute: (input: EditFileInput | string) => Promise<EditFileResult>;
|
|
98
|
+
formatResult: (result: EditFileResult) => string;
|
|
99
|
+
getSystemPrompt: () => string;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
declare const openai_createEditFileTool: typeof createEditFileTool;
|
|
103
|
+
declare const openai_editFileTool: typeof editFileTool;
|
|
104
|
+
declare const openai_execute: typeof execute;
|
|
105
|
+
declare const openai_formatResult: typeof formatResult;
|
|
106
|
+
declare const openai_getSystemPrompt: typeof getSystemPrompt;
|
|
107
|
+
declare namespace openai {
|
|
108
|
+
export { openai_createEditFileTool as createEditFileTool, editFileTool as default, openai_editFileTool as editFileTool, openai_execute as execute, openai_formatResult as formatResult, openai_getSystemPrompt as getSystemPrompt };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export { execute as a, createEditFileTool as c, editFileTool as e, formatResult as f, getSystemPrompt as g, openai as o };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Tool } from '@anthropic-ai/sdk/resources/messages.mjs';
|
|
2
|
+
import { BrowserConfig, BrowserTaskInput, BrowserTaskResult } from './types.js';
|
|
3
|
+
import '../utils/resilience.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Anthropic SDK adapter for browser automation tool
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Anthropic tool definition for browser automation
|
|
11
|
+
*/
|
|
12
|
+
declare const browserTool: Tool;
|
|
13
|
+
/**
|
|
14
|
+
* Create a configured browser tool with execute and formatResult methods
|
|
15
|
+
*
|
|
16
|
+
* @param config - Browser worker configuration
|
|
17
|
+
* @returns Tool definition with execute and formatResult methods
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import Anthropic from '@anthropic-ai/sdk';
|
|
22
|
+
* import { createBrowserTool } from 'morphsdk/tools/browser/anthropic';
|
|
23
|
+
*
|
|
24
|
+
* const tool = createBrowserTool({
|
|
25
|
+
* apiKey: process.env.MORPH_API_KEY,
|
|
26
|
+
* timeout: 180000
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* const client = new Anthropic();
|
|
30
|
+
*
|
|
31
|
+
* const response = await client.messages.create({
|
|
32
|
+
* model: 'claude-sonnet-4-5-20250929',
|
|
33
|
+
* tools: [tool], // tool itself is the Tool definition
|
|
34
|
+
* messages: [{
|
|
35
|
+
* role: 'user',
|
|
36
|
+
* content: 'Test the checkout flow at https://3000-abc.e2b.dev'
|
|
37
|
+
* }]
|
|
38
|
+
* });
|
|
39
|
+
*
|
|
40
|
+
* // Execute and format
|
|
41
|
+
* const result = await tool.execute(toolUseBlock.input);
|
|
42
|
+
* const formatted = tool.formatResult(result);
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
declare function createBrowserTool(config?: BrowserConfig): Tool & {
|
|
46
|
+
execute: (input: BrowserTaskInput) => Promise<BrowserTaskResult>;
|
|
47
|
+
formatResult: (result: BrowserTaskResult) => string;
|
|
48
|
+
getSystemPrompt: () => string;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export { browserTool, createBrowserTool };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../tools/browser/anthropic.ts"],"sourcesContent":["/**\n * Anthropic SDK adapter for browser automation tool\n */\n\nimport type { Tool } from '@anthropic-ai/sdk/resources/messages.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 * Anthropic tool definition for browser automation\n */\nexport const browserTool: Tool = {\n name: 'browser_task',\n description: BROWSER_TOOL_DESCRIPTION,\n input_schema: {\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 * Format browser task result for Anthropic 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 */\nfunction 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 * 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 Anthropic from '@anthropic-ai/sdk';\n * import { createBrowserTool } from 'morphsdk/tools/browser/anthropic';\n * \n * const tool = createBrowserTool({\n * apiKey: process.env.MORPH_API_KEY,\n * timeout: 180000\n * });\n * \n * const client = new Anthropic();\n * \n * const response = await client.messages.create({\n * model: 'claude-sonnet-4-5-20250929',\n * tools: [tool], // tool itself is the Tool definition\n * messages: [{\n * role: 'user',\n * content: 'Test the checkout flow at https://3000-abc.e2b.dev'\n * }]\n * });\n * \n * // Execute and format\n * const result = await tool.execute(toolUseBlock.input);\n * const formatted = tool.formatResult(result);\n * ```\n */\nexport function createBrowserTool(config?: BrowserConfig) {\n return Object.assign({}, browserTool, {\n execute: async (input: BrowserTaskInput): Promise<BrowserTaskResult> => {\n return executeBrowserTask(input, config);\n },\n formatResult: (result: BrowserTaskResult): string => {\n return formatResult(result);\n },\n getSystemPrompt: (): string => {\n return BROWSER_SYSTEM_PROMPT;\n },\n });\n}\n\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../tools/browser/anthropic.ts"],"sourcesContent":["/**\n * Anthropic SDK adapter for browser automation tool\n */\n\nimport type { Tool } from '@anthropic-ai/sdk/resources/messages.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 * Anthropic tool definition for browser automation\n */\nexport const browserTool: Tool = {\n name: 'browser_task',\n description: BROWSER_TOOL_DESCRIPTION,\n input_schema: {\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 * Format browser task result for Anthropic 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 */\nfunction 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 * 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 Anthropic from '@anthropic-ai/sdk';\n * import { createBrowserTool } from 'morphsdk/tools/browser/anthropic';\n * \n * const tool = createBrowserTool({\n * apiKey: process.env.MORPH_API_KEY,\n * timeout: 180000\n * });\n * \n * const client = new Anthropic();\n * \n * const response = await client.messages.create({\n * model: 'claude-sonnet-4-5-20250929',\n * tools: [tool], // tool itself is the Tool definition\n * messages: [{\n * role: 'user',\n * content: 'Test the checkout flow at https://3000-abc.e2b.dev'\n * }]\n * });\n * \n * // Execute and format\n * const result = await tool.execute(toolUseBlock.input);\n * const formatted = tool.formatResult(result);\n * ```\n */\nexport function createBrowserTool(config?: BrowserConfig) {\n return Object.assign({}, browserTool, {\n execute: async (input: BrowserTaskInput): Promise<BrowserTaskResult> => {\n return executeBrowserTask(input, config);\n },\n formatResult: (result: BrowserTaskResult): string => {\n return formatResult(result);\n },\n getSystemPrompt: (): string => {\n return BROWSER_SYSTEM_PROMPT;\n },\n });\n}\n\n"],"mappings":";;;;;;;;;;;;AAgBO,IAAM,cAAoB;AAAA,EAC/B,MAAM;AAAA,EACN,aAAa;AAAA,EACb,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,YAAY;AAAA,MACV,MAAM;AAAA,QACJ,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,KAAK;AAAA,QACH,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,WAAW;AAAA,QACT,MAAM;AAAA,QACN,aAAa;AAAA,QACb,SAAS;AAAA,MACX;AAAA,MACA,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,MAAM,CAAC,OAAO,KAAK;AAAA,QACnB,aAAa;AAAA,QACb,SAAS;AAAA,MACX;AAAA,IACF;AAAA,IACA,UAAU,CAAC,MAAM;AAAA,EACnB;AACF;AAYA,SAAS,aAAa,QAAmC;AACvD,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;AAkCO,SAAS,kBAAkB,QAAwB;AACxD,SAAO,OAAO,OAAO,CAAC,GAAG,aAAa;AAAA,IACpC,SAAS,OAAO,UAAwD;AACtE,aAAO,mBAAmB,OAAO,MAAM;AAAA,IACzC;AAAA,IACA,cAAc,CAAC,WAAsC;AACnD,aAAO,aAAa,MAAM;AAAA,IAC5B;AAAA,IACA,iBAAiB,MAAc;AAC7B,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACH;","names":[]}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { BrowserConfig, BrowserTaskInput, BrowserTaskResult, BrowserTaskWithPromise, BrowserTaskInputWithSchema, BrowserTaskWithPromiseAndSchema, RecordingStatus, ErrorsResponse } from './types.js';
|
|
2
|
+
import '../utils/resilience.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Core implementation for browser automation tasks
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* BrowserClient class for easier usage with instance configuration
|
|
10
|
+
*/
|
|
11
|
+
declare class BrowserClient {
|
|
12
|
+
private config;
|
|
13
|
+
constructor(config?: BrowserConfig);
|
|
14
|
+
/**
|
|
15
|
+
* Execute a browser automation task
|
|
16
|
+
*/
|
|
17
|
+
execute(input: BrowserTaskInput): Promise<BrowserTaskResult>;
|
|
18
|
+
createTask(input: BrowserTaskInput): Promise<BrowserTaskWithPromise>;
|
|
19
|
+
createTask<T>(input: BrowserTaskInputWithSchema<T>): Promise<BrowserTaskWithPromiseAndSchema<T>>;
|
|
20
|
+
/**
|
|
21
|
+
* Execute task with recording and wait for video to be ready
|
|
22
|
+
*/
|
|
23
|
+
executeWithRecording(input: BrowserTaskInput & {
|
|
24
|
+
record_video: true;
|
|
25
|
+
}): Promise<BrowserTaskResult & {
|
|
26
|
+
recording?: RecordingStatus;
|
|
27
|
+
}>;
|
|
28
|
+
/**
|
|
29
|
+
* Get recording status and URLs
|
|
30
|
+
*/
|
|
31
|
+
getRecording(recordingId: string): Promise<RecordingStatus>;
|
|
32
|
+
/**
|
|
33
|
+
* Wait for recording to complete with automatic polling
|
|
34
|
+
*/
|
|
35
|
+
waitForRecording(recordingId: string, options?: {
|
|
36
|
+
timeout?: number;
|
|
37
|
+
pollInterval?: number;
|
|
38
|
+
}): Promise<RecordingStatus>;
|
|
39
|
+
/**
|
|
40
|
+
* Get errors from recording with screenshots
|
|
41
|
+
*/
|
|
42
|
+
getErrors(recordingId: string): Promise<ErrorsResponse>;
|
|
43
|
+
/**
|
|
44
|
+
* Check if browser worker service is healthy
|
|
45
|
+
*/
|
|
46
|
+
checkHealth(): Promise<{
|
|
47
|
+
ok: boolean;
|
|
48
|
+
google_configured: boolean;
|
|
49
|
+
database_configured: boolean;
|
|
50
|
+
s3_configured: boolean;
|
|
51
|
+
error?: string;
|
|
52
|
+
}>;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Execute a natural language browser automation task
|
|
56
|
+
*
|
|
57
|
+
* Returns the full task result including rich agent history data (urls, errors,
|
|
58
|
+
* action_history, judgement, etc.). When using this as an agent tool, use the
|
|
59
|
+
* formatResult() functions from the SDK adapters to return a concise summary.
|
|
60
|
+
*
|
|
61
|
+
* @param input - Task parameters
|
|
62
|
+
* @param config - Optional configuration (apiKey, apiUrl to override default)
|
|
63
|
+
* @returns Task result with success status, findings, and comprehensive execution history
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* const result = await executeBrowserTask(
|
|
68
|
+
* {
|
|
69
|
+
* task: "Test checkout flow for buying a pineapple",
|
|
70
|
+
* url: "https://3000-abc.e2b.dev",
|
|
71
|
+
* max_steps: 20,
|
|
72
|
+
* repo_id: "my-project",
|
|
73
|
+
* commit_id: "uuid-here"
|
|
74
|
+
* },
|
|
75
|
+
* {
|
|
76
|
+
* apiKey: process.env.MORPH_API_KEY,
|
|
77
|
+
* // apiUrl: 'http://localhost:8001' // Override for local testing
|
|
78
|
+
* }
|
|
79
|
+
* );
|
|
80
|
+
*
|
|
81
|
+
* if (result.success) {
|
|
82
|
+
* console.log('Task completed:', result.result);
|
|
83
|
+
* console.log('URLs visited:', result.urls);
|
|
84
|
+
* console.log('Actions taken:', result.action_names);
|
|
85
|
+
* console.log('Has errors:', result.has_errors);
|
|
86
|
+
* console.log('Replay:', result.replay_url);
|
|
87
|
+
* }
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
declare function executeBrowserTask(input: BrowserTaskInput, config?: BrowserConfig): Promise<BrowserTaskResult>;
|
|
91
|
+
/**
|
|
92
|
+
* Get recording status and video URL
|
|
93
|
+
*
|
|
94
|
+
* @param recordingId - Recording UUID from BrowserTaskResult
|
|
95
|
+
* @param config - Configuration with apiKey
|
|
96
|
+
* @returns Recording status with video URL when ready
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```typescript
|
|
100
|
+
* const status = await getRecording('uuid-here', { apiKey: 'key' });
|
|
101
|
+
* if (status.status === 'COMPLETED' && status.video_url) {
|
|
102
|
+
* console.log('Video ready:', status.video_url);
|
|
103
|
+
* }
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
declare function getRecording(recordingId: string, config?: BrowserConfig): Promise<RecordingStatus>;
|
|
107
|
+
/**
|
|
108
|
+
* Wait for recording to complete with automatic polling
|
|
109
|
+
*
|
|
110
|
+
* @param recordingId - Recording UUID
|
|
111
|
+
* @param config - Configuration with apiKey
|
|
112
|
+
* @param options - Polling options
|
|
113
|
+
* @returns Recording status when completed or errored
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```typescript
|
|
117
|
+
* const result = await executeBrowserTask({ task: '...', record_video: true }, config);
|
|
118
|
+
* if (result.recording_id) {
|
|
119
|
+
* const recording = await waitForRecording(result.recording_id, config, {
|
|
120
|
+
* timeout: 60000, // 1 minute
|
|
121
|
+
* pollInterval: 2000 // Check every 2 seconds
|
|
122
|
+
* });
|
|
123
|
+
* console.log('Video URL:', recording.video_url);
|
|
124
|
+
* }
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
declare function waitForRecording(recordingId: string, config?: BrowserConfig, options?: {
|
|
128
|
+
timeout?: number;
|
|
129
|
+
pollInterval?: number;
|
|
130
|
+
}): Promise<RecordingStatus>;
|
|
131
|
+
/**
|
|
132
|
+
* Execute task with recording and wait for video to be ready
|
|
133
|
+
*
|
|
134
|
+
* @param input - Task parameters with record_video=true
|
|
135
|
+
* @param config - Configuration with apiKey
|
|
136
|
+
* @returns Task result with ready video URL
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```typescript
|
|
140
|
+
* const result = await executeWithRecording(
|
|
141
|
+
* {
|
|
142
|
+
* task: "Test checkout flow",
|
|
143
|
+
* url: "https://example.com",
|
|
144
|
+
* record_video: true,
|
|
145
|
+
* repo_id: "my-project"
|
|
146
|
+
* },
|
|
147
|
+
* { apiKey: process.env.MORPH_API_KEY }
|
|
148
|
+
* );
|
|
149
|
+
*
|
|
150
|
+
* console.log('Task result:', result.result);
|
|
151
|
+
* console.log('Video URL:', result.recording?.video_url);
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
declare function executeWithRecording(input: BrowserTaskInput & {
|
|
155
|
+
record_video: true;
|
|
156
|
+
}, config?: BrowserConfig): Promise<BrowserTaskResult & {
|
|
157
|
+
recording?: RecordingStatus;
|
|
158
|
+
}>;
|
|
159
|
+
/**
|
|
160
|
+
* Get errors from recording with screenshots
|
|
161
|
+
*
|
|
162
|
+
* Screenshots are captured in real-time (500ms after error occurs) during the browser session.
|
|
163
|
+
*
|
|
164
|
+
* @param recordingId - Recording UUID from BrowserTaskResult
|
|
165
|
+
* @param config - Configuration with apiKey
|
|
166
|
+
* @returns Errors with real-time screenshots
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```typescript
|
|
170
|
+
* const { errors, total_errors } = await getErrors('uuid-here', { apiKey: 'key' });
|
|
171
|
+
*
|
|
172
|
+
* console.log(`Found ${total_errors} errors`);
|
|
173
|
+
*
|
|
174
|
+
* errors.forEach(err => {
|
|
175
|
+
* console.log(`[${err.type}] ${err.message}`);
|
|
176
|
+
* if (err.url) console.log(` URL: ${err.url}`);
|
|
177
|
+
* if (err.screenshot_url) console.log(` Screenshot: ${err.screenshot_url}`);
|
|
178
|
+
*
|
|
179
|
+
* // Download screenshot
|
|
180
|
+
* if (err.screenshot_url) {
|
|
181
|
+
* const response = await fetch(err.screenshot_url);
|
|
182
|
+
* const screenshot = await response.arrayBuffer();
|
|
183
|
+
* // Save or process screenshot
|
|
184
|
+
* }
|
|
185
|
+
* });
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
declare function getErrors(recordingId: string, config?: BrowserConfig): Promise<ErrorsResponse>;
|
|
189
|
+
/**
|
|
190
|
+
* Check if browser worker service is healthy
|
|
191
|
+
*
|
|
192
|
+
* @param config - Optional configuration
|
|
193
|
+
* @returns Health status
|
|
194
|
+
*/
|
|
195
|
+
declare function checkHealth(config?: BrowserConfig): Promise<{
|
|
196
|
+
ok: boolean;
|
|
197
|
+
google_configured: boolean;
|
|
198
|
+
database_configured: boolean;
|
|
199
|
+
s3_configured: boolean;
|
|
200
|
+
error?: string;
|
|
201
|
+
}>;
|
|
202
|
+
|
|
203
|
+
export { BrowserClient, checkHealth, executeBrowserTask, executeWithRecording, getErrors, getRecording, waitForRecording };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { BrowserClient, checkHealth, executeBrowserTask, executeWithRecording, getErrors, getRecording, waitForRecording } from './core.js';
|
|
2
|
+
export { BrowserConfig, BrowserError, BrowserModel, BrowserTaskInput, BrowserTaskInputWithSchema, BrowserTaskResult, BrowserTaskWithPromise, BrowserTaskWithPromiseAndSchema, ErrorsResponse, IframeOptions, LiveSessionOptions, RecordingStatus } from './types.js';
|
|
3
|
+
export { BROWSER_SYSTEM_PROMPT, BROWSER_TOOL_DESCRIPTION } from './prompts.js';
|
|
4
|
+
export { LIVE_PRESETS, buildEmbedCode, buildLiveIframe, buildLiveUrl } from './live.js';
|
|
5
|
+
import '../utils/resilience.js';
|
|
@@ -4,17 +4,19 @@ import {
|
|
|
4
4
|
} from "../../chunk-EI4UKP24.js";
|
|
5
5
|
import {
|
|
6
6
|
BrowserClient,
|
|
7
|
-
LIVE_PRESETS,
|
|
8
|
-
buildEmbedCode,
|
|
9
|
-
buildLiveIframe,
|
|
10
|
-
buildLiveUrl,
|
|
11
7
|
checkHealth,
|
|
12
8
|
executeBrowserTask,
|
|
13
9
|
executeWithRecording,
|
|
14
10
|
getErrors,
|
|
15
11
|
getRecording,
|
|
16
12
|
waitForRecording
|
|
17
|
-
} from "../../chunk-
|
|
13
|
+
} from "../../chunk-EYHXBQQX.js";
|
|
14
|
+
import {
|
|
15
|
+
LIVE_PRESETS,
|
|
16
|
+
buildEmbedCode,
|
|
17
|
+
buildLiveIframe,
|
|
18
|
+
buildLiveUrl
|
|
19
|
+
} from "../../chunk-SQN4DUQS.js";
|
|
18
20
|
import "../../chunk-4VWJFZVS.js";
|
|
19
21
|
import "../../chunk-PZ5AY32C.js";
|
|
20
22
|
export {
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// tools/browser/live.ts
|
|
21
|
+
var live_exports = {};
|
|
22
|
+
__export(live_exports, {
|
|
23
|
+
LIVE_PRESETS: () => LIVE_PRESETS,
|
|
24
|
+
buildEmbedCode: () => buildEmbedCode,
|
|
25
|
+
buildLiveIframe: () => buildLiveIframe,
|
|
26
|
+
buildLiveUrl: () => buildLiveUrl,
|
|
27
|
+
resolvePreset: () => resolvePreset
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(live_exports);
|
|
30
|
+
var LIVE_PRESETS = {
|
|
31
|
+
/** Read-only monitoring (no interaction) */
|
|
32
|
+
readonly: { interactive: false },
|
|
33
|
+
/** Interactive control (human-in-the-loop) */
|
|
34
|
+
interactive: { interactive: true },
|
|
35
|
+
/** Watch-only without controls */
|
|
36
|
+
monitoring: { interactive: false, showControls: false }
|
|
37
|
+
};
|
|
38
|
+
function buildLiveUrl(debugUrl, options = {}) {
|
|
39
|
+
if (!debugUrl) {
|
|
40
|
+
throw new Error(
|
|
41
|
+
"debugUrl is required. Ensure your backend returns debugUrl in the task response. Contact support@morphllm.com if you need help."
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
const url = new URL(debugUrl);
|
|
45
|
+
if (options.interactive !== void 0) {
|
|
46
|
+
url.searchParams.set("interactive", String(options.interactive));
|
|
47
|
+
}
|
|
48
|
+
if (options.theme) {
|
|
49
|
+
url.searchParams.set("theme", options.theme);
|
|
50
|
+
}
|
|
51
|
+
if (options.showControls !== void 0) {
|
|
52
|
+
url.searchParams.set("showControls", String(options.showControls));
|
|
53
|
+
}
|
|
54
|
+
if (options.pageId) {
|
|
55
|
+
url.searchParams.set("pageId", options.pageId);
|
|
56
|
+
}
|
|
57
|
+
if (options.pageIndex) {
|
|
58
|
+
url.searchParams.set("pageIndex", options.pageIndex);
|
|
59
|
+
}
|
|
60
|
+
return url.toString();
|
|
61
|
+
}
|
|
62
|
+
function buildLiveIframe(debugUrl, options = {}) {
|
|
63
|
+
const {
|
|
64
|
+
width = "100%",
|
|
65
|
+
height = "600px",
|
|
66
|
+
style = "",
|
|
67
|
+
className = "",
|
|
68
|
+
...sessionOptions
|
|
69
|
+
} = options;
|
|
70
|
+
const src = buildLiveUrl(debugUrl, sessionOptions);
|
|
71
|
+
const widthStr = typeof width === "number" ? `${width}px` : width;
|
|
72
|
+
const heightStr = typeof height === "number" ? `${height}px` : height;
|
|
73
|
+
const baseStyle = `width: ${widthStr}; height: ${heightStr}; border: none;`;
|
|
74
|
+
const fullStyle = style ? `${baseStyle} ${style}` : baseStyle;
|
|
75
|
+
const attributes = [
|
|
76
|
+
`src="${src}"`,
|
|
77
|
+
`style="${fullStyle}"`
|
|
78
|
+
];
|
|
79
|
+
if (className) {
|
|
80
|
+
attributes.push(`class="${className}"`);
|
|
81
|
+
}
|
|
82
|
+
return `<iframe ${attributes.join(" ")}></iframe>`;
|
|
83
|
+
}
|
|
84
|
+
function buildEmbedCode(debugUrl, options = {}) {
|
|
85
|
+
const iframe = buildLiveIframe(debugUrl, options);
|
|
86
|
+
return `<!-- Embed Morph Live Session -->
|
|
87
|
+
${iframe}`;
|
|
88
|
+
}
|
|
89
|
+
function resolvePreset(optionsOrPreset) {
|
|
90
|
+
if (!optionsOrPreset) {
|
|
91
|
+
return {};
|
|
92
|
+
}
|
|
93
|
+
if (typeof optionsOrPreset === "string") {
|
|
94
|
+
const preset = LIVE_PRESETS[optionsOrPreset];
|
|
95
|
+
if (!preset) {
|
|
96
|
+
throw new Error(
|
|
97
|
+
`Unknown preset: ${optionsOrPreset}. Available presets: ${Object.keys(LIVE_PRESETS).join(", ")}`
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
return preset;
|
|
101
|
+
}
|
|
102
|
+
return optionsOrPreset;
|
|
103
|
+
}
|
|
104
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
105
|
+
0 && (module.exports = {
|
|
106
|
+
LIVE_PRESETS,
|
|
107
|
+
buildEmbedCode,
|
|
108
|
+
buildLiveIframe,
|
|
109
|
+
buildLiveUrl,
|
|
110
|
+
resolvePreset
|
|
111
|
+
});
|
|
112
|
+
//# sourceMappingURL=live.cjs.map
|