libretto 0.6.7 → 0.6.9
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/README.md +26 -74
- package/README.template.md +26 -74
- package/dist/cli/commands/execution.js +13 -1
- package/dist/cli/commands/setup.js +12 -4
- package/dist/cli/commands/status.js +1 -1
- package/dist/cli/core/ai-model.js +12 -4
- package/dist/cli/core/browser-daemon.js +122 -0
- package/dist/cli/core/browser.js +54 -180
- package/dist/cli/core/config.js +1 -1
- package/dist/cli/core/providers/browserbase.js +1 -0
- package/dist/cli/core/providers/kernel.js +1 -0
- package/dist/cli/core/providers/libretto-cloud.js +9 -4
- package/dist/cli/core/resolve-model.js +20 -2
- package/dist/cli/workers/run-integration-runtime.js +3 -0
- package/dist/shared/dom-semantics.js +0 -1
- package/package.json +1 -1
- package/skills/libretto/SKILL.md +14 -3
- package/skills/libretto-readonly/SKILL.md +1 -1
- package/src/cli/commands/execution.ts +13 -1
- package/src/cli/commands/setup.ts +11 -3
- package/src/cli/commands/status.ts +1 -1
- package/src/cli/core/ai-model.ts +10 -2
- package/src/cli/core/browser-daemon.ts +198 -0
- package/src/cli/core/browser.ts +50 -190
- package/src/cli/core/config.ts +1 -1
- package/src/cli/core/providers/browserbase.ts +1 -0
- package/src/cli/core/providers/kernel.ts +1 -0
- package/src/cli/core/providers/libretto-cloud.ts +18 -5
- package/src/cli/core/providers/types.ts +12 -1
- package/src/cli/core/resolve-model.ts +20 -2
- package/src/cli/workers/run-integration-runtime.ts +10 -0
- package/src/shared/dom-semantics.ts +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { LanguageModel } from "ai";
|
|
2
2
|
|
|
3
|
-
export type Provider = "google" | "vertex" | "anthropic" | "openai";
|
|
3
|
+
export type Provider = "google" | "vertex" | "anthropic" | "openai" | "openrouter";
|
|
4
4
|
|
|
5
5
|
const GEMINI_API_KEY_ENV_VARS = [
|
|
6
6
|
"GEMINI_API_KEY",
|
|
@@ -19,6 +19,7 @@ const SUPPORTED_PROVIDER_ALIASES = {
|
|
|
19
19
|
anthropic: "anthropic",
|
|
20
20
|
codex: "openai",
|
|
21
21
|
openai: "openai",
|
|
22
|
+
openrouter: "openrouter",
|
|
22
23
|
} as const satisfies Record<string, Provider>;
|
|
23
24
|
|
|
24
25
|
function readFirstEnvValue(
|
|
@@ -51,7 +52,7 @@ export function parseModel(model: string): {
|
|
|
51
52
|
|
|
52
53
|
if (!provider) {
|
|
53
54
|
throw new Error(
|
|
54
|
-
`Unsupported provider "${providerInput}". Supported providers: openai/codex, anthropic, google (Gemini API), and
|
|
55
|
+
`Unsupported provider "${providerInput}". Supported providers: openai/codex, anthropic, google (Gemini API), vertex, and openrouter.`,
|
|
55
56
|
);
|
|
56
57
|
}
|
|
57
58
|
|
|
@@ -71,6 +72,8 @@ export function hasProviderCredentials(
|
|
|
71
72
|
return Boolean(env.ANTHROPIC_API_KEY?.trim());
|
|
72
73
|
case "openai":
|
|
73
74
|
return Boolean(env.OPENAI_API_KEY?.trim());
|
|
75
|
+
case "openrouter":
|
|
76
|
+
return Boolean(env.OPENROUTER_API_KEY?.trim());
|
|
74
77
|
}
|
|
75
78
|
}
|
|
76
79
|
|
|
@@ -86,6 +89,9 @@ export function missingProviderCredentialsMessage(provider: Provider): string {
|
|
|
86
89
|
case "openai": {
|
|
87
90
|
return "OpenAI API key is missing. Set OPENAI_API_KEY.";
|
|
88
91
|
}
|
|
92
|
+
case "openrouter": {
|
|
93
|
+
return "OpenRouter API key is missing. Set OPENROUTER_API_KEY.";
|
|
94
|
+
}
|
|
89
95
|
}
|
|
90
96
|
}
|
|
91
97
|
|
|
@@ -133,6 +139,18 @@ async function getProviderModel(
|
|
|
133
139
|
const openai = createOpenAI({ apiKey });
|
|
134
140
|
return openai(modelId);
|
|
135
141
|
}
|
|
142
|
+
case "openrouter": {
|
|
143
|
+
const apiKey = process.env.OPENROUTER_API_KEY?.trim();
|
|
144
|
+
if (!apiKey) {
|
|
145
|
+
throw new Error(missingProviderCredentialsMessage(provider));
|
|
146
|
+
}
|
|
147
|
+
const { createOpenAI } = await import("@ai-sdk/openai");
|
|
148
|
+
const openrouter = createOpenAI({
|
|
149
|
+
apiKey,
|
|
150
|
+
baseURL: "https://openrouter.ai/api/v1",
|
|
151
|
+
});
|
|
152
|
+
return openrouter(modelId);
|
|
153
|
+
}
|
|
136
154
|
}
|
|
137
155
|
}
|
|
138
156
|
|
|
@@ -269,6 +269,16 @@ async function runIntegrationInternal(
|
|
|
269
269
|
},
|
|
270
270
|
});
|
|
271
271
|
|
|
272
|
+
// tsx/esbuild injects __name() wrappers when keepNames is true. Playwright
|
|
273
|
+
// serializes callbacks via Function#toString() into the browser context which
|
|
274
|
+
// lacks __name, causing ReferenceError. Inject a no-op polyfill into every page.
|
|
275
|
+
await browserSession.context.addInitScript(() => {
|
|
276
|
+
(globalThis as Record<string, unknown>).__name = (
|
|
277
|
+
target: unknown,
|
|
278
|
+
value: string,
|
|
279
|
+
) => Object.defineProperty(target as object, "name", { value, configurable: true });
|
|
280
|
+
});
|
|
281
|
+
|
|
272
282
|
const workflowContext: LibrettoWorkflowContext = {
|
|
273
283
|
session: args.session,
|
|
274
284
|
page: browserSession.page,
|
|
@@ -58,7 +58,6 @@ export function isObfuscatedClass(cls: string): boolean {
|
|
|
58
58
|
if (cls.length > 80) return true;
|
|
59
59
|
if (/^_?[0-9a-f]{6,}$/i.test(cls)) return true;
|
|
60
60
|
if (/^[a-z]+_[0-9a-f]{4,}$/i.test(cls)) return true;
|
|
61
|
-
if (/^[a-z]{1,2}[0-9]{2,}$/i.test(cls)) return true;
|
|
62
61
|
|
|
63
62
|
const digits = (cls.match(/[0-9]/g) || []).length;
|
|
64
63
|
const letters = (cls.match(/[a-zA-Z]/g) || []).length;
|