-
+
Arguments:
- {parameters.map((param) => (
-
+ {parameters.map((param, idx) => (
+
{param[0]}
{`(${param[1].type}):`}
{param[1].description}
diff --git a/gui/src/components/modelSelection/ModelSelect.tsx b/gui/src/components/modelSelection/ModelSelect.tsx
index 98a5c7d4f76..3db6bd1b9ce 100644
--- a/gui/src/components/modelSelection/ModelSelect.tsx
+++ b/gui/src/components/modelSelection/ModelSelect.tsx
@@ -10,7 +10,6 @@ import { useAuth } from "../../context/Auth";
import { IdeMessengerContext } from "../../context/IdeMessenger";
import { AddModelForm } from "../../forms/AddModelForm";
import { useAppDispatch, useAppSelector } from "../../redux/hooks";
-import { EMPTY_CONFIG } from "../../redux/slices/configSlice";
import { setDialogMessage, setShowDialog } from "../../redux/slices/uiSlice";
import { updateSelectedModelByRole } from "../../redux/thunks/updateSelectedModelByRole";
import {
@@ -36,6 +35,7 @@ interface Option {
value: string;
title: string;
apiKey?: string;
+ sourceFile?: string;
}
function modelSelectTitle(model: any): string {
@@ -55,8 +55,6 @@ function ModelOption({
showMissingApiKeyMsg,
isSelected,
}: ModelOptionProps) {
- const ideMessenger = useContext(IdeMessengerContext);
-
function handleOptionClick(e: any) {
if (showMissingApiKeyMsg) {
e.preventDefault();
@@ -94,6 +92,7 @@ function ModelSelect() {
const isInEdit = useAppSelector((store) => store.session.isInEdit);
const config = useAppSelector((state) => state.config.config);
+ const isConfigLoading = useAppSelector((state) => state.config.loading);
const ideMessenger = useContext(IdeMessengerContext);
const buttonRef = useRef
(null);
const [options, setOptions] = useState
);
diff --git a/gui/src/pages/config/ModelRoleSelector.tsx b/gui/src/pages/config/ModelRoleSelector.tsx
index 1b73751b91e..5bdac5b4a92 100644
--- a/gui/src/pages/config/ModelRoleSelector.tsx
+++ b/gui/src/pages/config/ModelRoleSelector.tsx
@@ -48,10 +48,13 @@ const ModelRoleSelector = ({
onSelect(models.find((m) => m.title === title) ?? null);
}
- function onClickGear(e: MouseEvent
) {
+ function onClickGear(e: MouseEvent, model: ModelDescription) {
e.stopPropagation();
e.preventDefault();
- ideMessenger.post("config/openProfile", { profileId: undefined });
+ ideMessenger.post("config/openProfile", {
+ profileId: undefined,
+ element: model,
+ });
}
function handleOptionClick(
@@ -169,7 +172,9 @@ const ModelRoleSelector = ({
{hoveredIdx === idx && (
) =>
+ onClickGear(e, option)
+ }
/>
)}
{option.title === selectedModel?.title && (
diff --git a/gui/src/pages/config/UserSettingsForm.tsx b/gui/src/pages/config/UserSettingsForm.tsx
index 9eea8003b01..d507ef133ce 100644
--- a/gui/src/pages/config/UserSettingsForm.tsx
+++ b/gui/src/pages/config/UserSettingsForm.tsx
@@ -71,6 +71,10 @@ export function UserSettingsForm() {
handleUpdate({ optInNextEditFeature: value });
};
+ const handleEnableStaticContextualizationToggle = (value: boolean) => {
+ handleUpdate({ enableStaticContextualization: value });
+ };
+
useEffect(() => {
// Necessary so that reformatted/trimmed values don't cause dirty state
setFormPromptPath(promptPath);
@@ -92,6 +96,8 @@ export function UserSettingsForm() {
config.experimental?.optInNextEditFeature ?? false;
const codebaseToolCallingOnly =
config.experimental?.codebaseToolCallingOnly ?? false;
+ const enableStaticContextualization =
+ config.experimental?.enableStaticContextualization ?? false;
const allowAnonymousTelemetry = config.allowAnonymousTelemetry ?? true;
const disableIndexing = config.disableIndexing ?? false;
@@ -433,6 +439,12 @@ export function UserSettingsForm() {
)}
diff --git a/gui/src/pages/gui/StreamError.tsx b/gui/src/pages/gui/StreamError.tsx
index f642a6ee828..8245d7f5678 100644
--- a/gui/src/pages/gui/StreamError.tsx
+++ b/gui/src/pages/gui/StreamError.tsx
@@ -76,6 +76,7 @@ const StreamErrorDialog = ({ error }: StreamErrorProps) => {
onClick={() => {
ideMessenger.post("config/openProfile", {
profileId: undefined,
+ element: selectedModel ?? undefined,
});
}}
>
diff --git a/gui/src/pages/gui/ToolCallDiv/FunctionSpecificToolCallDiv.tsx b/gui/src/pages/gui/ToolCallDiv/FunctionSpecificToolCallDiv.tsx
index 378483d71f2..251a32e4e0a 100644
--- a/gui/src/pages/gui/ToolCallDiv/FunctionSpecificToolCallDiv.tsx
+++ b/gui/src/pages/gui/ToolCallDiv/FunctionSpecificToolCallDiv.tsx
@@ -18,25 +18,30 @@ function FunctionSpecificToolCallDiv({
case BuiltInToolNames.CreateNewFile:
return (
);
case BuiltInToolNames.EditExistingFile:
return (
);
case BuiltInToolNames.SearchAndReplaceInFile:
+ const changes = args.diffs
+ ? Array.isArray(args.diffs)
+ ? args.diffs.join("\n\n---\n\n")
+ : args.diffs
+ : "";
return (
@@ -44,7 +49,7 @@ function FunctionSpecificToolCallDiv({
case BuiltInToolNames.RunTerminalCommand:
return (
diff --git a/gui/src/pages/gui/ToolCallDiv/IndicatorBar.tsx b/gui/src/pages/gui/ToolCallDiv/IndicatorBar.tsx
new file mode 100644
index 00000000000..ce56dfd0cbc
--- /dev/null
+++ b/gui/src/pages/gui/ToolCallDiv/IndicatorBar.tsx
@@ -0,0 +1,19 @@
+import { ChevronDownIcon } from "@heroicons/react/24/outline";
+
+interface IndicatorBarProps {
+ text: string;
+ isExpanded: boolean;
+}
+
+export function IndicatorBar({ text, isExpanded }: IndicatorBarProps) {
+ return (
+
+ );
+}
diff --git a/gui/src/pages/gui/ToolCallDiv/RunTerminalCommand.tsx b/gui/src/pages/gui/ToolCallDiv/RunTerminalCommand.tsx
index 0b3bf1b9df8..566643ec74a 100644
--- a/gui/src/pages/gui/ToolCallDiv/RunTerminalCommand.tsx
+++ b/gui/src/pages/gui/ToolCallDiv/RunTerminalCommand.tsx
@@ -1,10 +1,10 @@
import { ToolCallState } from "core";
-import styled from "styled-components";
-import { vscForeground } from "../../../components";
+import { useMemo } from "react";
import Ansi from "../../../components/ansiTerminal/Ansi";
import StyledMarkdownPreview from "../../../components/StyledMarkdownPreview";
import { useAppDispatch } from "../../../redux/hooks";
import { moveTerminalProcessToBackground } from "../../../redux/thunks/moveTerminalProcessToBackground";
+import { TerminalCollapsibleContainer } from "./TerminalCollapsibleContainer";
interface RunTerminalCommandToolCallProps {
command: string;
@@ -12,64 +12,34 @@ interface RunTerminalCommandToolCallProps {
toolCallId: string | undefined;
}
-const CommandStatus = styled.div`
- font-size: 12px;
- color: var(--vscode-descriptionForeground, ${vscForeground}88);
- margin-top: 8px;
- display: flex;
- align-items: center;
- padding-left: 8px;
- padding-right: 8px;
-`;
-
-const StatusIcon = styled.span<{
+interface StatusIconProps {
status: "running" | "completed" | "failed" | "background";
-}>`
- width: 8px;
- height: 8px;
- border-radius: 50%;
- margin-right: 8px;
- background-color: ${(props) =>
- props.status === "running"
- ? "var(--vscode-testing-runAction, #4caf50)"
- : props.status === "completed"
- ? "var(--vscode-testing-iconPassed, #4caf50)"
- : props.status === "background"
- ? "var(--vscode-statusBarItem-prominentBackground, #2196f3)"
- : "var(--vscode-testing-iconFailed, #f44336)"};
- ${(props) =>
- props.status === "running" ? "animation: pulse 1.5s infinite;" : ""}
-`;
-
-// Waiting message styled for consistency
-const WaitingMessage = styled.div`
- padding: 8px;
- padding-left: 16px;
- padding-right: 16px;
- margin-top: 8px;
-`;
-
-// For consistency with the rest of the styled components
-const AnsiWrapper = styled.div`
- margin-top: 8px;
-`;
-
-const BackgroundLink = styled.a`
- font-size: 12px;
- color: var(--vscode-textLink-foreground, #3794ff);
- margin-left: 12px;
- cursor: pointer;
- text-decoration: none;
-
- &:hover {
- text-decoration: underline;
- }
-`;
+}
+
+function StatusIcon({ status }: StatusIconProps) {
+ const getStatusColor = () => {
+ switch (status) {
+ case "running":
+ return "bg-success";
+ case "completed":
+ return "bg-success";
+ case "background":
+ return "bg-accent";
+ case "failed":
+ return "bg-error";
+ default:
+ return "bg-success";
+ }
+ };
-// Just spacing between terminal components and the next toolcall
-const TerminalContainer = styled.div`
- margin-bottom: 16px;
-`;
+ return (
+
+ );
+}
export function RunTerminalCommand(props: RunTerminalCommandToolCallProps) {
const dispatch = useAppDispatch();
@@ -84,6 +54,42 @@ export function RunTerminalCommand(props: RunTerminalCommandToolCallProps) {
const isRunning = props.toolCallState.status === "calling";
const hasOutput = terminalContent.length > 0;
+ const displayLines = 15;
+
+ // Process terminal content for line limiting
+ const processedTerminalContent = useMemo(() => {
+ if (!terminalContent)
+ return {
+ fullContent: "",
+ limitedContent: "",
+ totalLines: 0,
+ isLimited: false,
+ hiddenLinesCount: 0,
+ };
+
+ const lines = terminalContent.split("\n");
+ const totalLines = lines.length;
+
+ if (totalLines > displayLines) {
+ const lastTwentyLines = lines.slice(-displayLines);
+ return {
+ fullContent: terminalContent,
+ limitedContent: lastTwentyLines.join("\n"),
+ totalLines,
+ isLimited: true,
+ hiddenLinesCount: totalLines - displayLines,
+ };
+ }
+
+ return {
+ fullContent: terminalContent,
+ limitedContent: terminalContent,
+ totalLines,
+ isLimited: false,
+ hiddenLinesCount: 0,
+ };
+ }, [terminalContent]);
+
// Determine status type
let statusType: "running" | "completed" | "failed" | "background" =
"completed";
@@ -96,7 +102,7 @@ export function RunTerminalCommand(props: RunTerminalCommandToolCallProps) {
}
return (
-
+
{/* Command */}
Waiting for output...
+ Waiting for output...
)}
{hasOutput && (
-
- {terminalContent}
-
+
+ {processedTerminalContent.limitedContent}
+
+ }
+ expandedContent={
+
+
{processedTerminalContent.fullContent}
+
+ }
+ />
)}
{/* Status information */}
{(statusMessage || isRunning) && (
-
+
{isRunning ? "Running" : statusMessage}
{isRunning && props.toolCallId && (
- {
// Dispatch the action to move the command to the background
dispatch(
@@ -128,12 +146,13 @@ export function RunTerminalCommand(props: RunTerminalCommandToolCallProps) {
}),
);
}}
+ className="text-link ml-3 cursor-pointer text-xs no-underline hover:underline"
>
Move to background
-
+
)}
-
+
)}
-
+
);
}
diff --git a/gui/src/pages/gui/ToolCallDiv/TerminalCollapsibleContainer.tsx b/gui/src/pages/gui/ToolCallDiv/TerminalCollapsibleContainer.tsx
new file mode 100644
index 00000000000..1f3ef7cea53
--- /dev/null
+++ b/gui/src/pages/gui/ToolCallDiv/TerminalCollapsibleContainer.tsx
@@ -0,0 +1,61 @@
+import { useState } from "react";
+import { IndicatorBar } from "./IndicatorBar";
+
+interface TerminalCollapsibleContainerProps {
+ collapsedContent: React.ReactNode;
+ expandedContent: React.ReactNode;
+ className?: string;
+ collapsible?: boolean;
+ hiddenLinesCount?: number;
+}
+
+export function TerminalCollapsibleContainer({
+ collapsedContent,
+ expandedContent,
+ className = "",
+ collapsible = false,
+ hiddenLinesCount = 0,
+}: TerminalCollapsibleContainerProps) {
+ const [isExpanded, setIsExpanded] = useState(false);
+
+ if (!collapsible) {
+ return
{collapsedContent}
;
+ }
+
+ return (
+
+ {/* Indicator bar - shows for both collapsed and expanded states */}
+ {((!isExpanded && hiddenLinesCount > 0) ||
+ (isExpanded && collapsible)) && (
+
+ )}
+
+ {/* Clickable overlay covering the entire content area */}
+ {collapsible && (
+
{
+ e.preventDefault();
+ e.stopPropagation();
+ setIsExpanded(!isExpanded);
+ }}
+ className="absolute inset-0 z-20 cursor-pointer"
+ />
+ )}
+
+ {/* Content container with proper constraint for gradient */}
+
+ {/* Gradient overlay on top of content - only when collapsed */}
+ {!isExpanded && hiddenLinesCount > 0 && (
+
+ )}
+
+ {isExpanded ? expandedContent : collapsedContent}
+
+
+ );
+}
diff --git a/gui/src/redux/slices/configSlice.ts b/gui/src/redux/slices/configSlice.ts
index 8766014a263..0deb9f6e4b0 100644
--- a/gui/src/redux/slices/configSlice.ts
+++ b/gui/src/redux/slices/configSlice.ts
@@ -68,6 +68,7 @@ export const configSlice = createSlice({
} else {
state.config = config;
}
+ state.loading = false;
},
updateConfig: (
state,
diff --git a/gui/src/redux/thunks/streamNormalInput.ts b/gui/src/redux/thunks/streamNormalInput.ts
index 6c722817bbd..6e95191c4d4 100644
--- a/gui/src/redux/thunks/streamNormalInput.ts
+++ b/gui/src/redux/thunks/streamNormalInput.ts
@@ -253,6 +253,7 @@ export const streamNormalInput = createAsyncThunk<
rules: appliedRules.map((rule) => ({
id: getRuleId(rule),
rule: rule.rule,
+ slug: rule.slug,
})),
}),
},
diff --git a/gui/src/util/clientTools/editImpl.ts b/gui/src/util/clientTools/editImpl.ts
index 6873e0512f3..a6f56e7c9f6 100644
--- a/gui/src/util/clientTools/editImpl.ts
+++ b/gui/src/util/clientTools/editImpl.ts
@@ -6,6 +6,11 @@ export const editToolImpl: ClientToolImpl = async (
toolCallId,
extras,
) => {
+ if (!args.filepath || !args.changes) {
+ throw new Error(
+ "`filepath` and `changes` arguments are required to edit an existing file.",
+ );
+ }
const firstUriMatch = await resolveRelativePathInDir(
args.filepath,
extras.ideMessenger.ide,
diff --git a/packages/config-types/src/index.ts b/packages/config-types/src/index.ts
index 8591c6b746b..fbc2d45fc40 100644
--- a/packages/config-types/src/index.ts
+++ b/packages/config-types/src/index.ts
@@ -210,6 +210,7 @@ export const siteIndexingConfigSchema = z.object({
maxDepth: z.number().optional(),
faviconUrl: z.string().optional(),
useLocalCrawling: z.boolean().optional(),
+ sourceFile: z.string().optional(),
});
export const controlPlaneConfigSchema = z.object({
diff --git a/packages/config-yaml/src/load/unroll.ts b/packages/config-yaml/src/load/unroll.ts
index 80403b5448a..adbe453244e 100644
--- a/packages/config-yaml/src/load/unroll.ts
+++ b/packages/config-yaml/src/load/unroll.ts
@@ -452,7 +452,15 @@ export async function unrollBlocks(
registry,
);
- return { blockType, resolvedBlock, error: null };
+ return {
+ blockType,
+ resolvedBlock,
+ source:
+ injectBlock.uriType === "file"
+ ? injectBlock.filePath
+ : undefined,
+ error: null,
+ };
} catch (err) {
let msg = "";
if (injectBlock.uriType === "file") {
@@ -475,7 +483,11 @@ export async function unrollBlocks(
const injectedResults = await Promise.all(injectedBlockPromises);
const injectedErrors: ConfigValidationError[] = [];
- const injectedBlocks: { blockType: string; resolvedBlock: any }[] = [];
+ const injectedBlocks: {
+ blockType: string;
+ resolvedBlock: any;
+ source?: string;
+ }[] = [];
for (const result of injectedResults) {
if (result.error) {
@@ -484,6 +496,7 @@ export async function unrollBlocks(
injectedBlocks.push({
blockType: result.blockType,
resolvedBlock: result.resolvedBlock,
+ source: result.source,
});
}
}
@@ -521,12 +534,21 @@ export async function unrollBlocks(
}
// Add injected blocks
- for (const { blockType, resolvedBlock } of injectedResult.injectedBlocks) {
+ for (const {
+ blockType,
+ resolvedBlock,
+ source,
+ } of injectedResult.injectedBlocks) {
const key = blockType as BlockType;
if (!unrolledAssistant[key]) {
unrolledAssistant[key] = [];
}
- unrolledAssistant[key]?.push(...((resolvedBlock[blockType] ?? []) as any));
+ const blocksWithSourceFiles = injectLocalSourceFile(
+ key,
+ resolvedBlock,
+ source,
+ );
+ unrolledAssistant[key]?.push(...blocksWithSourceFiles);
}
const configResult: ConfigResult
= {
@@ -541,6 +563,39 @@ export async function unrollBlocks(
return configResult;
}
+function injectLocalSourceFile(
+ blockType: BlockType,
+ resolvedBlock: any,
+ source?: string,
+): (any & { source?: string })[] {
+ const blocks: any[] = resolvedBlock[blockType] ?? [];
+ if (source === undefined) {
+ // If no source is provided, return blocks as is
+ return blocks;
+ }
+ if (blockType === "rules") {
+ // For rules, we need to ensure they are wrapped in an object with a `source
+ return blocks.map((block) => {
+ if (typeof block === "string") {
+ const rule = {
+ sourceFile: source,
+ name: block,
+ rule: block,
+ } as Rule;
+ return rule;
+ } else if (typeof block === "object") {
+ block.sourceFile = source;
+ }
+ return block;
+ });
+ }
+ // For other block types, we can directly inject the source file
+ return blocks.map((block) => ({
+ ...block,
+ sourceFile: source,
+ }));
+}
+
export async function resolveBlock(
id: PackageIdentifier,
inputs: Record | undefined,
diff --git a/packages/config-yaml/src/markdown/markdownToRule.ts b/packages/config-yaml/src/markdown/markdownToRule.ts
index 231b2ab4a30..f584a0549e4 100644
--- a/packages/config-yaml/src/markdown/markdownToRule.ts
+++ b/packages/config-yaml/src/markdown/markdownToRule.ts
@@ -112,5 +112,6 @@ export function markdownToRule(
regex: frontmatter.regex,
description: frontmatter.description,
alwaysApply: frontmatter.alwaysApply,
+ sourceFile: id.uriType === "file" ? id.filePath : undefined,
};
}
diff --git a/packages/config-yaml/src/schemas/data/autocomplete/index.ts b/packages/config-yaml/src/schemas/data/autocomplete/index.ts
index 458473c3be0..db2186e0f41 100644
--- a/packages/config-yaml/src/schemas/data/autocomplete/index.ts
+++ b/packages/config-yaml/src/schemas/data/autocomplete/index.ts
@@ -36,6 +36,9 @@ export const autocompleteEventAllSchema = baseDevDataAllSchema.extend({
uniqueId: z.string(),
timestamp: z.string(),
+ // For static contextualization.
+ enabledStaticContextualization: z.boolean().optional(),
+
// DEPRECATED - no more nested objects after v0.1.0, all flat values
completionOptions: completionOptionsSchema.optional(),
disableInFiles: z.array(z.string()).optional(),
diff --git a/packages/config-yaml/src/schemas/data/autocomplete/v0.2.0.ts b/packages/config-yaml/src/schemas/data/autocomplete/v0.2.0.ts
index 5866b986529..123a05b7535 100644
--- a/packages/config-yaml/src/schemas/data/autocomplete/v0.2.0.ts
+++ b/packages/config-yaml/src/schemas/data/autocomplete/v0.2.0.ts
@@ -38,6 +38,9 @@ export const autocompleteEventSchema_0_2_0 = autocompleteEventAllSchema.pick({
completionId: true,
uniqueId: true,
+ // For static contextualization.
+ enabledStaticContextualization: true,
+
// Note objects (completionOptions and disableInfiles) removed from 0.1.0 => 0.2.0
});
diff --git a/packages/config-yaml/src/schemas/data/chatInteraction/index.ts b/packages/config-yaml/src/schemas/data/chatInteraction/index.ts
index f13b630af99..14bb36ba9ba 100644
--- a/packages/config-yaml/src/schemas/data/chatInteraction/index.ts
+++ b/packages/config-yaml/src/schemas/data/chatInteraction/index.ts
@@ -13,6 +13,7 @@ export const chatInteractionEventAllSchema = baseDevDataAllSchema.extend({
z.object({
id: z.string(),
rule: z.string(),
+ slug: z.string().optional(),
}),
)
.optional(),
diff --git a/packages/config-yaml/src/schemas/data/editOutcome/index.ts b/packages/config-yaml/src/schemas/data/editOutcome/index.ts
index ec902364c0a..32c34632cf7 100644
--- a/packages/config-yaml/src/schemas/data/editOutcome/index.ts
+++ b/packages/config-yaml/src/schemas/data/editOutcome/index.ts
@@ -12,4 +12,5 @@ export const editOutcomeEventAllSchema = baseDevDataAllSchema.extend({
newCodeLines: z.number(),
lineChange: z.number(),
accepted: z.boolean(),
+ filepath: z.string(),
});
diff --git a/packages/config-yaml/src/schemas/data/editOutcome/v0.2.0.ts b/packages/config-yaml/src/schemas/data/editOutcome/v0.2.0.ts
index 1fdbfb96746..acd3be4bd0f 100644
--- a/packages/config-yaml/src/schemas/data/editOutcome/v0.2.0.ts
+++ b/packages/config-yaml/src/schemas/data/editOutcome/v0.2.0.ts
@@ -20,6 +20,7 @@ export const editOutcomeEventSchema_0_2_0 = editOutcomeEventAllSchema.pick({
previousCodeLines: true,
newCodeLines: true,
lineChange: true,
+ filepath: true,
});
export const editOutcomeEventSchema_0_2_0_noCode =
diff --git a/packages/config-yaml/src/schemas/index.ts b/packages/config-yaml/src/schemas/index.ts
index 4ac2aa1f54e..e15a5655d90 100644
--- a/packages/config-yaml/src/schemas/index.ts
+++ b/packages/config-yaml/src/schemas/index.ts
@@ -25,6 +25,7 @@ const mcpServerSchema = z.object({
cwd: z.string().optional(),
connectionTimeout: z.number().gt(0).optional(),
requestOptions: requestOptionsSchema.optional(),
+ sourceFile: z.string().optional(),
});
export type MCPServer = z.infer;
@@ -33,6 +34,7 @@ const promptSchema = z.object({
name: z.string(),
description: z.string().optional(),
prompt: z.string(),
+ sourceFile: z.string().optional(),
});
export type Prompt = z.infer;
@@ -42,8 +44,8 @@ const docSchema = z.object({
startUrl: z.string(),
rootUrl: z.string().optional(),
faviconUrl: z.string().optional(),
- maxDepth: z.number().optional(),
useLocalCrawling: z.boolean().optional(),
+ sourceFile: z.string().optional(),
});
export type DocsConfig = z.infer;
@@ -55,6 +57,7 @@ const ruleObjectSchema = z.object({
globs: z.union([z.string(), z.array(z.string())]).optional(),
regex: z.union([z.string(), z.array(z.string())]).optional(),
alwaysApply: z.boolean().optional(),
+ sourceFile: z.string().optional(), //TODO refactor RuleWithSource.ruleFile to align with sourceFile
});
const ruleSchema = z.union([z.string(), ruleObjectSchema]);
diff --git a/packages/config-yaml/src/schemas/models.ts b/packages/config-yaml/src/schemas/models.ts
index 8bdb6b66d82..283ec67812e 100644
--- a/packages/config-yaml/src/schemas/models.ts
+++ b/packages/config-yaml/src/schemas/models.ts
@@ -163,6 +163,7 @@ export const modelSchema = z.union([
z.object({
...baseModelFields,
provider: z.string().refine((val) => val !== "continue-proxy"),
+ sourceFile: z.string().optional(),
}),
]);
diff --git a/packages/openai-adapters/package-lock.json b/packages/openai-adapters/package-lock.json
index 06d32e3726b..73354c249c6 100644
--- a/packages/openai-adapters/package-lock.json
+++ b/packages/openai-adapters/package-lock.json
@@ -15,6 +15,7 @@
"@continuedev/config-yaml": "^1.0.51",
"@continuedev/fetch": "^1.0.15",
"dotenv": "^16.5.0",
+ "google-auth-library": "^10.1.0",
"json-schema": "^0.4.0",
"node-fetch": "^3.3.2",
"openai": "^4.104.0",
@@ -35,7 +36,7 @@
"semantic-release": "^24.2.7",
"ts-jest": "^29.2.3",
"ts-node": "^10.9.2",
- "vitest": "^1.6.1"
+ "vitest": "^3.2.4"
}
},
"node_modules/@ampproject/remapping": {
@@ -1386,9 +1387,9 @@
}
},
"node_modules/@esbuild/aix-ppc64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
- "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz",
+ "integrity": "sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==",
"cpu": [
"ppc64"
],
@@ -1399,13 +1400,13 @@
"aix"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/android-arm": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
- "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.8.tgz",
+ "integrity": "sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==",
"cpu": [
"arm"
],
@@ -1416,13 +1417,13 @@
"android"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
- "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.8.tgz",
+ "integrity": "sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==",
"cpu": [
"arm64"
],
@@ -1433,13 +1434,13 @@
"android"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
- "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.8.tgz",
+ "integrity": "sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==",
"cpu": [
"x64"
],
@@ -1450,13 +1451,13 @@
"android"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
- "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.8.tgz",
+ "integrity": "sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==",
"cpu": [
"arm64"
],
@@ -1467,13 +1468,13 @@
"darwin"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
- "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.8.tgz",
+ "integrity": "sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==",
"cpu": [
"x64"
],
@@ -1484,13 +1485,13 @@
"darwin"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
- "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.8.tgz",
+ "integrity": "sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==",
"cpu": [
"arm64"
],
@@ -1501,13 +1502,13 @@
"freebsd"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
- "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.8.tgz",
+ "integrity": "sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==",
"cpu": [
"x64"
],
@@ -1518,13 +1519,13 @@
"freebsd"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
- "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.8.tgz",
+ "integrity": "sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==",
"cpu": [
"arm"
],
@@ -1535,13 +1536,13 @@
"linux"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
- "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.8.tgz",
+ "integrity": "sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==",
"cpu": [
"arm64"
],
@@ -1552,13 +1553,13 @@
"linux"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
- "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.8.tgz",
+ "integrity": "sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==",
"cpu": [
"ia32"
],
@@ -1569,13 +1570,13 @@
"linux"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
- "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.8.tgz",
+ "integrity": "sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==",
"cpu": [
"loong64"
],
@@ -1586,13 +1587,13 @@
"linux"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
- "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.8.tgz",
+ "integrity": "sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==",
"cpu": [
"mips64el"
],
@@ -1603,13 +1604,13 @@
"linux"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
- "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.8.tgz",
+ "integrity": "sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==",
"cpu": [
"ppc64"
],
@@ -1620,13 +1621,13 @@
"linux"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
- "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.8.tgz",
+ "integrity": "sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==",
"cpu": [
"riscv64"
],
@@ -1637,13 +1638,13 @@
"linux"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
- "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.8.tgz",
+ "integrity": "sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==",
"cpu": [
"s390x"
],
@@ -1654,13 +1655,13 @@
"linux"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
- "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.8.tgz",
+ "integrity": "sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==",
"cpu": [
"x64"
],
@@ -1671,13 +1672,30 @@
"linux"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.8.tgz",
+ "integrity": "sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
- "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.8.tgz",
+ "integrity": "sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==",
"cpu": [
"x64"
],
@@ -1688,13 +1706,30 @@
"netbsd"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.8.tgz",
+ "integrity": "sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
- "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.8.tgz",
+ "integrity": "sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==",
"cpu": [
"x64"
],
@@ -1705,13 +1740,30 @@
"openbsd"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.8.tgz",
+ "integrity": "sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
- "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.8.tgz",
+ "integrity": "sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==",
"cpu": [
"x64"
],
@@ -1722,13 +1774,13 @@
"sunos"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
- "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.8.tgz",
+ "integrity": "sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==",
"cpu": [
"arm64"
],
@@ -1739,13 +1791,13 @@
"win32"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
- "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.8.tgz",
+ "integrity": "sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==",
"cpu": [
"ia32"
],
@@ -1756,13 +1808,13 @@
"win32"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
- "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz",
+ "integrity": "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==",
"cpu": [
"x64"
],
@@ -1773,7 +1825,7 @@
"win32"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@istanbuljs/load-nyc-config": {
@@ -3859,6 +3911,23 @@
"@babel/types": "^7.20.7"
}
},
+ "node_modules/@types/chai": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz",
+ "integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/deep-eql": "*"
+ }
+ },
+ "node_modules/@types/deep-eql": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz",
+ "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/estree": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
@@ -3926,11 +3995,12 @@
"dev": true
},
"node_modules/@types/node": {
- "version": "18.19.39",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz",
- "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==",
+ "version": "24.1.0",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.1.0.tgz",
+ "integrity": "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==",
+ "license": "MIT",
"dependencies": {
- "undici-types": "~5.26.4"
+ "undici-types": "~7.8.0"
}
},
"node_modules/@types/node-fetch": {
@@ -3976,103 +4046,115 @@
"dev": true
},
"node_modules/@vitest/expect": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.1.tgz",
- "integrity": "sha512-jXL+9+ZNIJKruofqXuuTClf44eSpcHlgj3CiuNihUF3Ioujtmc0zIa3UJOW5RjDK1YLBJZnWBlPuqhYycLioog==",
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz",
+ "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/spy": "1.6.1",
- "@vitest/utils": "1.6.1",
- "chai": "^4.3.10"
+ "@types/chai": "^5.2.2",
+ "@vitest/spy": "3.2.4",
+ "@vitest/utils": "3.2.4",
+ "chai": "^5.2.0",
+ "tinyrainbow": "^2.0.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
}
},
- "node_modules/@vitest/runner": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.1.tgz",
- "integrity": "sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA==",
+ "node_modules/@vitest/mocker": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz",
+ "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/utils": "1.6.1",
- "p-limit": "^5.0.0",
- "pathe": "^1.1.1"
+ "@vitest/spy": "3.2.4",
+ "estree-walker": "^3.0.3",
+ "magic-string": "^0.30.17"
},
"funding": {
"url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "msw": "^2.4.9",
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0"
+ },
+ "peerDependenciesMeta": {
+ "msw": {
+ "optional": true
+ },
+ "vite": {
+ "optional": true
+ }
}
},
- "node_modules/@vitest/runner/node_modules/p-limit": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz",
- "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==",
+ "node_modules/@vitest/pretty-format": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz",
+ "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "yocto-queue": "^1.0.0"
- },
- "engines": {
- "node": ">=18"
+ "tinyrainbow": "^2.0.0"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://opencollective.com/vitest"
}
},
- "node_modules/@vitest/runner/node_modules/yocto-queue": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.1.tgz",
- "integrity": "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==",
+ "node_modules/@vitest/runner": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz",
+ "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==",
"dev": true,
"license": "MIT",
- "engines": {
- "node": ">=12.20"
+ "dependencies": {
+ "@vitest/utils": "3.2.4",
+ "pathe": "^2.0.3",
+ "strip-literal": "^3.0.0"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://opencollective.com/vitest"
}
},
"node_modules/@vitest/snapshot": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.1.tgz",
- "integrity": "sha512-WvidQuWAzU2p95u8GAKlRMqMyN1yOJkGHnx3M1PL9Raf7AQ1kwLKg04ADlCa3+OXUZE7BceOhVZiuWAbzCKcUQ==",
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz",
+ "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "magic-string": "^0.30.5",
- "pathe": "^1.1.1",
- "pretty-format": "^29.7.0"
+ "@vitest/pretty-format": "3.2.4",
+ "magic-string": "^0.30.17",
+ "pathe": "^2.0.3"
},
"funding": {
"url": "https://opencollective.com/vitest"
}
},
"node_modules/@vitest/spy": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.1.tgz",
- "integrity": "sha512-MGcMmpGkZebsMZhbQKkAf9CX5zGvjkBTqf8Zx3ApYWXr3wG+QvEu2eXWfnIIWYSJExIp4V9FCKDEeygzkYrXMw==",
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz",
+ "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "tinyspy": "^2.2.0"
+ "tinyspy": "^4.0.3"
},
"funding": {
"url": "https://opencollective.com/vitest"
}
},
"node_modules/@vitest/utils": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.1.tgz",
- "integrity": "sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g==",
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz",
+ "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "diff-sequences": "^29.6.3",
- "estree-walker": "^3.0.3",
- "loupe": "^2.3.7",
- "pretty-format": "^29.7.0"
+ "@vitest/pretty-format": "3.2.4",
+ "loupe": "^3.1.4",
+ "tinyrainbow": "^2.0.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
@@ -4238,13 +4320,13 @@
"dev": true
},
"node_modules/assertion-error": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
- "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
+ "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
"dev": true,
"license": "MIT",
"engines": {
- "node": "*"
+ "node": ">=12"
}
},
"node_modules/async": {
@@ -4377,12 +4459,41 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/before-after-hook": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz",
"integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==",
"dev": true
},
+ "node_modules/bignumber.js": {
+ "version": "9.3.1",
+ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz",
+ "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==",
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/bottleneck": {
"version": "2.19.5",
"resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
@@ -4472,6 +4583,12 @@
"node-int64": "^0.4.0"
}
},
+ "node_modules/buffer-equal-constant-time": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+ "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
+ "license": "BSD-3-Clause"
+ },
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
@@ -4530,32 +4647,20 @@
"peer": true
},
"node_modules/chai": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz",
- "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==",
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.1.tgz",
+ "integrity": "sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A==",
"dev": true,
"license": "MIT",
"dependencies": {
- "assertion-error": "^1.1.0",
- "check-error": "^1.0.3",
- "deep-eql": "^4.1.3",
- "get-func-name": "^2.0.2",
- "loupe": "^2.3.6",
- "pathval": "^1.1.1",
- "type-detect": "^4.1.0"
+ "assertion-error": "^2.0.1",
+ "check-error": "^2.1.1",
+ "deep-eql": "^5.0.1",
+ "loupe": "^3.1.0",
+ "pathval": "^2.0.0"
},
"engines": {
- "node": ">=4"
- }
- },
- "node_modules/chai/node_modules/type-detect": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz",
- "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
+ "node": ">=18"
}
},
"node_modules/chalk": {
@@ -4584,16 +4689,13 @@
}
},
"node_modules/check-error": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz",
- "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz",
+ "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "get-func-name": "^2.0.2"
- },
"engines": {
- "node": "*"
+ "node": ">= 16"
}
},
"node_modules/ci-info": {
@@ -4778,13 +4880,6 @@
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true
},
- "node_modules/confbox": {
- "version": "0.1.8",
- "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
- "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/config-chain": {
"version": "1.1.13",
"resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
@@ -5026,11 +5121,12 @@
}
},
"node_modules/debug": {
- "version": "4.3.5",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
- "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "license": "MIT",
"dependencies": {
- "ms": "2.1.2"
+ "ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
@@ -5041,11 +5137,6 @@
}
}
},
- "node_modules/debug/node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
- },
"node_modules/dedent": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz",
@@ -5062,14 +5153,11 @@
}
},
"node_modules/deep-eql": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz",
- "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==",
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
+ "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "type-detect": "^4.0.0"
- },
"engines": {
"node": ">=6"
}
@@ -5173,6 +5261,15 @@
"readable-stream": "^2.0.2"
}
},
+ "node_modules/ecdsa-sig-formatter": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+ "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
"node_modules/ejs": {
"version": "3.1.10",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
@@ -5397,10 +5494,17 @@
"is-arrayish": "^0.2.1"
}
},
+ "node_modules/es-module-lexer": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
+ "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/esbuild": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
- "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz",
+ "integrity": "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
@@ -5408,32 +5512,35 @@
"esbuild": "bin/esbuild"
},
"engines": {
- "node": ">=12"
+ "node": ">=18"
},
"optionalDependencies": {
- "@esbuild/aix-ppc64": "0.21.5",
- "@esbuild/android-arm": "0.21.5",
- "@esbuild/android-arm64": "0.21.5",
- "@esbuild/android-x64": "0.21.5",
- "@esbuild/darwin-arm64": "0.21.5",
- "@esbuild/darwin-x64": "0.21.5",
- "@esbuild/freebsd-arm64": "0.21.5",
- "@esbuild/freebsd-x64": "0.21.5",
- "@esbuild/linux-arm": "0.21.5",
- "@esbuild/linux-arm64": "0.21.5",
- "@esbuild/linux-ia32": "0.21.5",
- "@esbuild/linux-loong64": "0.21.5",
- "@esbuild/linux-mips64el": "0.21.5",
- "@esbuild/linux-ppc64": "0.21.5",
- "@esbuild/linux-riscv64": "0.21.5",
- "@esbuild/linux-s390x": "0.21.5",
- "@esbuild/linux-x64": "0.21.5",
- "@esbuild/netbsd-x64": "0.21.5",
- "@esbuild/openbsd-x64": "0.21.5",
- "@esbuild/sunos-x64": "0.21.5",
- "@esbuild/win32-arm64": "0.21.5",
- "@esbuild/win32-ia32": "0.21.5",
- "@esbuild/win32-x64": "0.21.5"
+ "@esbuild/aix-ppc64": "0.25.8",
+ "@esbuild/android-arm": "0.25.8",
+ "@esbuild/android-arm64": "0.25.8",
+ "@esbuild/android-x64": "0.25.8",
+ "@esbuild/darwin-arm64": "0.25.8",
+ "@esbuild/darwin-x64": "0.25.8",
+ "@esbuild/freebsd-arm64": "0.25.8",
+ "@esbuild/freebsd-x64": "0.25.8",
+ "@esbuild/linux-arm": "0.25.8",
+ "@esbuild/linux-arm64": "0.25.8",
+ "@esbuild/linux-ia32": "0.25.8",
+ "@esbuild/linux-loong64": "0.25.8",
+ "@esbuild/linux-mips64el": "0.25.8",
+ "@esbuild/linux-ppc64": "0.25.8",
+ "@esbuild/linux-riscv64": "0.25.8",
+ "@esbuild/linux-s390x": "0.25.8",
+ "@esbuild/linux-x64": "0.25.8",
+ "@esbuild/netbsd-arm64": "0.25.8",
+ "@esbuild/netbsd-x64": "0.25.8",
+ "@esbuild/openbsd-arm64": "0.25.8",
+ "@esbuild/openbsd-x64": "0.25.8",
+ "@esbuild/openharmony-arm64": "0.25.8",
+ "@esbuild/sunos-x64": "0.25.8",
+ "@esbuild/win32-arm64": "0.25.8",
+ "@esbuild/win32-ia32": "0.25.8",
+ "@esbuild/win32-x64": "0.25.8"
}
},
"node_modules/escalade": {
@@ -5535,6 +5642,22 @@
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
+ "node_modules/expect-type": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz",
+ "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+ "license": "MIT"
+ },
"node_modules/fast-content-type-parse": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz",
@@ -5870,6 +5993,34 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/gaxios": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.1.tgz",
+ "integrity": "sha512-Odju3uBUJyVCkW64nLD4wKLhbh93bh6vIg/ZIXkWiLPBrdgtc65+tls/qml+un3pr6JqYVFDZbbmLDQT68rTOQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "extend": "^3.0.2",
+ "https-proxy-agent": "^7.0.1",
+ "node-fetch": "^3.3.2"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/gcp-metadata": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-7.0.1.tgz",
+ "integrity": "sha512-UcO3kefx6dCcZkgcTGgVOTFb7b1LlQ02hY1omMjjrrBzkajRMCFgYOjs7J71WqnuG1k2b+9ppGL7FsOfhZMQKQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "gaxios": "^7.0.0",
+ "google-logging-utils": "^1.0.0",
+ "json-bigint": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -5889,16 +6040,6 @@
"node": "6.* || 8.* || >= 10.*"
}
},
- "node_modules/get-func-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
- "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "*"
- }
- },
"node_modules/get-package-type": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
@@ -6023,12 +6164,52 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/google-auth-library": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.1.0.tgz",
+ "integrity": "sha512-GspVjZj1RbyRWpQ9FbAXMKjFGzZwDKnUHi66JJ+tcjcu5/xYAP1pdlWotCuIkMwjfVsxxDvsGZXGLzRt72D0sQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "base64-js": "^1.3.0",
+ "ecdsa-sig-formatter": "^1.0.11",
+ "gaxios": "^7.0.0",
+ "gcp-metadata": "^7.0.0",
+ "google-logging-utils": "^1.0.0",
+ "gtoken": "^8.0.0",
+ "jws": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/google-logging-utils": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.1.tgz",
+ "integrity": "sha512-rcX58I7nqpu4mbKztFeOAObbomBbHU2oIb/d3tJfF3dizGSApqtSwYJigGCooHdnMyQBIw8BrWyK96w3YXgr6A==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
"dev": true
},
+ "node_modules/gtoken": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-8.0.0.tgz",
+ "integrity": "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==",
+ "license": "MIT",
+ "dependencies": {
+ "gaxios": "^7.0.0",
+ "jws": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/handlebars": {
"version": "4.7.8",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
@@ -7186,6 +7367,15 @@
"node": ">=4"
}
},
+ "node_modules/json-bigint": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
+ "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
+ "license": "MIT",
+ "dependencies": {
+ "bignumber.js": "^9.0.0"
+ }
+ },
"node_modules/json-parse-better-errors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
@@ -7227,15 +7417,36 @@
"graceful-fs": "^4.1.6"
}
},
- "node_modules/kleur": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
- "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
- "dev": true,
- "peer": true,
- "engines": {
- "node": ">=6"
- }
+ "node_modules/jwa": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz",
+ "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==",
+ "license": "MIT",
+ "dependencies": {
+ "buffer-equal-constant-time": "^1.0.1",
+ "ecdsa-sig-formatter": "1.0.11",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/jws": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
+ "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
+ "license": "MIT",
+ "dependencies": {
+ "jwa": "^2.0.0",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/kleur": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
+ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
+ "dev": true,
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ }
},
"node_modules/leven": {
"version": "3.1.0",
@@ -7290,23 +7501,6 @@
"node": ">=4"
}
},
- "node_modules/local-pkg": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.1.tgz",
- "integrity": "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "mlly": "^1.7.3",
- "pkg-types": "^1.2.1"
- },
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/antfu"
- }
- },
"node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@@ -7369,14 +7563,11 @@
"dev": true
},
"node_modules/loupe": {
- "version": "2.3.7",
- "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz",
- "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==",
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.4.tgz",
+ "integrity": "sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==",
"dev": true,
- "license": "MIT",
- "dependencies": {
- "get-func-name": "^2.0.1"
- }
+ "license": "MIT"
},
"node_modules/lru-cache": {
"version": "5.1.1",
@@ -7619,26 +7810,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/mlly": {
- "version": "1.7.4",
- "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz",
- "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "acorn": "^8.14.0",
- "pathe": "^2.0.1",
- "pkg-types": "^1.3.0",
- "ufo": "^1.5.4"
- }
- },
- "node_modules/mlly/node_modules/pathe": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
- "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -10573,6 +10744,15 @@
}
}
},
+ "node_modules/openai/node_modules/@types/node": {
+ "version": "18.19.120",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.120.tgz",
+ "integrity": "sha512-WtCGHFXnVI8WHLxDAt5TbnCM4eSE+nI0QN2NJtwzcgMhht2eNz6V9evJrk+lwC8bCY8OWV5Ym8Jz7ZEyGnKnMA==",
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~5.26.4"
+ }
+ },
"node_modules/openai/node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
@@ -10592,6 +10772,12 @@
}
}
},
+ "node_modules/openai/node_modules/undici-types": {
+ "version": "5.26.5",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
+ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
+ "license": "MIT"
+ },
"node_modules/p-each-series": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-3.0.0.tgz",
@@ -10816,20 +11002,20 @@
}
},
"node_modules/pathe": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
- "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
"dev": true,
"license": "MIT"
},
"node_modules/pathval": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
- "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz",
+ "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==",
"dev": true,
"license": "MIT",
"engines": {
- "node": "*"
+ "node": ">= 14.16"
}
},
"node_modules/picocolors": {
@@ -10963,25 +11149,6 @@
"node": ">=8"
}
},
- "node_modules/pkg-types": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
- "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "confbox": "^0.1.8",
- "mlly": "^1.7.4",
- "pathe": "^2.0.1"
- }
- },
- "node_modules/pkg-types/node_modules/pathe": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
- "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/postcss": {
"version": "8.5.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
@@ -11396,8 +11563,7 @@
"node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"node_modules/semantic-release": {
"version": "24.2.7",
@@ -12055,9 +12221,9 @@
}
},
"node_modules/strip-literal": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.1.tgz",
- "integrity": "sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz",
+ "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12262,10 +12428,72 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/tinyexec": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
+ "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.14",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz",
+ "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.4.4",
+ "picomatch": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/tinyglobby/node_modules/fdir": {
+ "version": "6.4.6",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz",
+ "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tinyglobby/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
"node_modules/tinypool": {
- "version": "0.8.4",
- "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz",
- "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz",
+ "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ }
+ },
+ "node_modules/tinyrainbow": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz",
+ "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -12273,9 +12501,9 @@
}
},
"node_modules/tinyspy": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz",
- "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==",
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.3.tgz",
+ "integrity": "sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -12442,6 +12670,7 @@
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
"integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
"dev": true,
+ "peer": true,
"engines": {
"node": ">=4"
}
@@ -12473,13 +12702,6 @@
"node": ">=14.17"
}
},
- "node_modules/ufo": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz",
- "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/uglify-js": {
"version": "3.19.3",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz",
@@ -12494,9 +12716,10 @@
}
},
"node_modules/undici-types": {
- "version": "5.26.5",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
- "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
+ "version": "7.8.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
+ "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
+ "license": "MIT"
},
"node_modules/unicode-emoji-modifier-base": {
"version": "1.0.0",
@@ -12639,21 +12862,24 @@
}
},
"node_modules/vite": {
- "version": "5.4.19",
- "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.19.tgz",
- "integrity": "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==",
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.5.tgz",
+ "integrity": "sha512-1mncVwJxy2C9ThLwz0+2GKZyEXuC3MyWtAAlNftlZZXZDP3AJt5FmwcMit/IGGaNZ8ZOB2BNO/HFUB+CpN0NQw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "esbuild": "^0.21.3",
- "postcss": "^8.4.43",
- "rollup": "^4.20.0"
+ "esbuild": "^0.25.0",
+ "fdir": "^6.4.6",
+ "picomatch": "^4.0.2",
+ "postcss": "^8.5.6",
+ "rollup": "^4.40.0",
+ "tinyglobby": "^0.2.14"
},
"bin": {
"vite": "bin/vite.js"
},
"engines": {
- "node": "^18.0.0 || >=20.0.0"
+ "node": "^20.19.0 || >=22.12.0"
},
"funding": {
"url": "https://github.com/vitejs/vite?sponsor=1"
@@ -12662,19 +12888,25 @@
"fsevents": "~2.3.3"
},
"peerDependencies": {
- "@types/node": "^18.0.0 || >=20.0.0",
- "less": "*",
+ "@types/node": "^20.19.0 || >=22.12.0",
+ "jiti": ">=1.21.0",
+ "less": "^4.0.0",
"lightningcss": "^1.21.0",
- "sass": "*",
- "sass-embedded": "*",
- "stylus": "*",
- "sugarss": "*",
- "terser": "^5.4.0"
+ "sass": "^1.70.0",
+ "sass-embedded": "^1.70.0",
+ "stylus": ">=0.54.8",
+ "sugarss": "^5.0.0",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
},
"peerDependenciesMeta": {
"@types/node": {
"optional": true
},
+ "jiti": {
+ "optional": true
+ },
"less": {
"optional": true
},
@@ -12695,74 +12927,112 @@
},
"terser": {
"optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
}
}
},
"node_modules/vite-node": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.1.tgz",
- "integrity": "sha512-YAXkfvGtuTzwWbDSACdJSg4A4DZiAqckWe90Zapc/sEX3XvHcw1NdurM/6od8J207tSDqNbSsgdCacBgvJKFuA==",
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz",
+ "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==",
"dev": true,
"license": "MIT",
"dependencies": {
"cac": "^6.7.14",
- "debug": "^4.3.4",
- "pathe": "^1.1.1",
- "picocolors": "^1.0.0",
- "vite": "^5.0.0"
+ "debug": "^4.4.1",
+ "es-module-lexer": "^1.7.0",
+ "pathe": "^2.0.3",
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0"
},
"bin": {
"vite-node": "vite-node.mjs"
},
"engines": {
- "node": "^18.0.0 || >=20.0.0"
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
}
},
- "node_modules/vitest": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.1.tgz",
- "integrity": "sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag==",
+ "node_modules/vite/node_modules/fdir": {
+ "version": "6.4.6",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz",
+ "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "@vitest/expect": "1.6.1",
- "@vitest/runner": "1.6.1",
- "@vitest/snapshot": "1.6.1",
- "@vitest/spy": "1.6.1",
- "@vitest/utils": "1.6.1",
- "acorn-walk": "^8.3.2",
- "chai": "^4.3.10",
- "debug": "^4.3.4",
- "execa": "^8.0.1",
- "local-pkg": "^0.5.0",
- "magic-string": "^0.30.5",
- "pathe": "^1.1.1",
- "picocolors": "^1.0.0",
- "std-env": "^3.5.0",
- "strip-literal": "^2.0.0",
- "tinybench": "^2.5.1",
- "tinypool": "^0.8.3",
- "vite": "^5.0.0",
- "vite-node": "1.6.1",
- "why-is-node-running": "^2.2.2"
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/vitest": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz",
+ "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/chai": "^5.2.2",
+ "@vitest/expect": "3.2.4",
+ "@vitest/mocker": "3.2.4",
+ "@vitest/pretty-format": "^3.2.4",
+ "@vitest/runner": "3.2.4",
+ "@vitest/snapshot": "3.2.4",
+ "@vitest/spy": "3.2.4",
+ "@vitest/utils": "3.2.4",
+ "chai": "^5.2.0",
+ "debug": "^4.4.1",
+ "expect-type": "^1.2.1",
+ "magic-string": "^0.30.17",
+ "pathe": "^2.0.3",
+ "picomatch": "^4.0.2",
+ "std-env": "^3.9.0",
+ "tinybench": "^2.9.0",
+ "tinyexec": "^0.3.2",
+ "tinyglobby": "^0.2.14",
+ "tinypool": "^1.1.1",
+ "tinyrainbow": "^2.0.0",
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0",
+ "vite-node": "3.2.4",
+ "why-is-node-running": "^2.3.0"
},
"bin": {
"vitest": "vitest.mjs"
},
"engines": {
- "node": "^18.0.0 || >=20.0.0"
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
},
"peerDependencies": {
"@edge-runtime/vm": "*",
- "@types/node": "^18.0.0 || >=20.0.0",
- "@vitest/browser": "1.6.1",
- "@vitest/ui": "1.6.1",
+ "@types/debug": "^4.1.12",
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+ "@vitest/browser": "3.2.4",
+ "@vitest/ui": "3.2.4",
"happy-dom": "*",
"jsdom": "*"
},
@@ -12770,6 +13040,9 @@
"@edge-runtime/vm": {
"optional": true
},
+ "@types/debug": {
+ "optional": true
+ },
"@types/node": {
"optional": true
},
@@ -12787,148 +13060,17 @@
}
}
},
- "node_modules/vitest/node_modules/execa": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
- "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cross-spawn": "^7.0.3",
- "get-stream": "^8.0.1",
- "human-signals": "^5.0.0",
- "is-stream": "^3.0.0",
- "merge-stream": "^2.0.0",
- "npm-run-path": "^5.1.0",
- "onetime": "^6.0.0",
- "signal-exit": "^4.1.0",
- "strip-final-newline": "^3.0.0"
- },
- "engines": {
- "node": ">=16.17"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/execa?sponsor=1"
- }
- },
- "node_modules/vitest/node_modules/get-stream": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
- "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/vitest/node_modules/human-signals": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
- "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=16.17.0"
- }
- },
- "node_modules/vitest/node_modules/is-stream": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
- "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/vitest/node_modules/mimic-fn": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
- "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/vitest/node_modules/npm-run-path": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
- "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "path-key": "^4.0.0"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/vitest/node_modules/onetime": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
- "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "mimic-fn": "^4.0.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/vitest/node_modules/path-key": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
- "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/vitest/node_modules/signal-exit": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
- "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/vitest/node_modules/strip-final-newline": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
- "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
+ "node_modules/vitest/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/walker": {
diff --git a/packages/openai-adapters/package.json b/packages/openai-adapters/package.json
index 0771c7d8737..94334b70092 100644
--- a/packages/openai-adapters/package.json
+++ b/packages/openai-adapters/package.json
@@ -18,6 +18,7 @@
"@continuedev/config-yaml": "^1.0.51",
"@continuedev/fetch": "^1.0.15",
"dotenv": "^16.5.0",
+ "google-auth-library": "^10.1.0",
"json-schema": "^0.4.0",
"node-fetch": "^3.3.2",
"openai": "^4.104.0",
@@ -38,6 +39,6 @@
"semantic-release": "^24.2.7",
"ts-jest": "^29.2.3",
"ts-node": "^10.9.2",
- "vitest": "^1.6.1"
+ "vitest": "^3.2.4"
}
}
diff --git a/packages/openai-adapters/src/apis/Anthropic.ts b/packages/openai-adapters/src/apis/Anthropic.ts
index 5df8b7a1d95..2b986d1d537 100644
--- a/packages/openai-adapters/src/apis/Anthropic.ts
+++ b/packages/openai-adapters/src/apis/Anthropic.ts
@@ -55,7 +55,7 @@ export class AnthropicApi implements BaseLlmApi {
return cachingStrategy(cleanBody);
}
- private _convertToCleanAnthropicBody(oaiBody: ChatCompletionCreateParams) {
+ public _convertToCleanAnthropicBody(oaiBody: ChatCompletionCreateParams) {
let stop = undefined;
if (oaiBody.stop && Array.isArray(oaiBody.stop)) {
stop = oaiBody.stop.filter((x) => x.trim() !== "");
@@ -219,27 +219,9 @@ export class AnthropicApi implements BaseLlmApi {
],
};
}
- async *chatCompletionStream(
- body: ChatCompletionCreateParamsStreaming,
- signal: AbortSignal,
- ): AsyncGenerator {
- body.messages;
- const response = await customFetch(this.config.requestOptions)(
- new URL("messages", this.apiBase),
- {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- "anthropic-version": "2023-06-01",
- "anthropic-beta": "prompt-caching-2024-07-31",
- "x-api-key": this.config.apiKey,
- },
- body: JSON.stringify(this._convertBody(body)),
- signal,
- },
- );
+ // This is split off so e.g. VertexAI can use it
+ async *handleStreamResponse(response: any, model: string) {
let lastToolUseId: string | undefined;
let lastToolUseName: string | undefined;
@@ -272,7 +254,7 @@ export class AnthropicApi implements BaseLlmApi {
case "text_delta":
yield chatChunk({
content: value.delta.text,
- model: body.model,
+ model,
});
break;
case "input_json_delta":
@@ -280,7 +262,7 @@ export class AnthropicApi implements BaseLlmApi {
throw new Error("No tool use found");
}
yield chatChunkFromDelta({
- model: body.model,
+ model,
delta: {
tool_calls: [
{
@@ -308,13 +290,36 @@ export class AnthropicApi implements BaseLlmApi {
}
yield usageChatChunk({
- model: body.model,
+ model,
usage: {
...usage,
total_tokens: usage.completion_tokens + usage.prompt_tokens,
},
});
}
+
+ async *chatCompletionStream(
+ body: ChatCompletionCreateParamsStreaming,
+ signal: AbortSignal,
+ ): AsyncGenerator {
+ body.messages;
+ const response = await customFetch(this.config.requestOptions)(
+ new URL("messages", this.apiBase),
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ Accept: "application/json",
+ "anthropic-version": "2023-06-01",
+ "anthropic-beta": "prompt-caching-2024-07-31",
+ "x-api-key": this.config.apiKey,
+ },
+ body: JSON.stringify(this._convertBody(body)),
+ signal,
+ },
+ );
+ yield* this.handleStreamResponse(response, body.model);
+ }
async completionNonStream(
body: CompletionCreateParamsNonStreaming,
signal: AbortSignal,
diff --git a/packages/openai-adapters/src/apis/Gemini.ts b/packages/openai-adapters/src/apis/Gemini.ts
index c0e441a1df6..91021a8f429 100644
--- a/packages/openai-adapters/src/apis/Gemini.ts
+++ b/packages/openai-adapters/src/apis/Gemini.ts
@@ -84,7 +84,12 @@ export class GeminiApi implements BaseLlmApi {
}
}
- private _convertBody(oaiBody: ChatCompletionCreateParams, url: string) {
+ public _convertBody(
+ oaiBody: ChatCompletionCreateParams,
+ url: string,
+ includeToolCallIds: boolean,
+ overrideIsV1?: boolean,
+ ) {
const generationConfig: any = {};
if (oaiBody.top_p) {
@@ -101,7 +106,7 @@ export class GeminiApi implements BaseLlmApi {
generationConfig.stopSequences = stop.filter((x) => x.trim() !== "");
}
- const isV1API = url.includes("/v1/");
+ const isV1API = overrideIsV1 ?? url.includes("/v1/");
const toolCallIdToNameMap = new Map();
oaiBody.messages.forEach((msg) => {
@@ -127,7 +132,7 @@ export class GeminiApi implements BaseLlmApi {
role: "model" as const,
parts: msg.tool_calls.map((toolCall) => ({
functionCall: {
- id: toolCall.id,
+ id: includeToolCallIds ? toolCall.id : undefined,
name: toolCall.function.name,
args: safeParseArgs(
toolCall.function.arguments,
@@ -145,7 +150,7 @@ export class GeminiApi implements BaseLlmApi {
parts: [
{
functionResponse: {
- id: msg.tool_call_id,
+ id: includeToolCallIds ? msg.tool_call_id : undefined,
name: functionName ?? "unknown",
response: {
content:
@@ -250,23 +255,9 @@ export class GeminiApi implements BaseLlmApi {
};
}
- async *chatCompletionStream(
- body: ChatCompletionCreateParamsStreaming,
- signal: AbortSignal,
- ): AsyncGenerator {
- const apiURL = new URL(
- `models/${body.model}:streamGenerateContent?key=${this.config.apiKey}`,
- this.apiBase,
- ).toString();
- const convertedBody = this._convertBody(body, apiURL);
- const resp = await customFetch(this.config.requestOptions)(apiURL, {
- method: "POST",
- body: JSON.stringify(convertedBody),
- signal,
- });
-
+ async *handleStreamResponse(response: any, model: string) {
let buffer = "";
- for await (const chunk of streamResponse(resp as any)) {
+ for await (const chunk of streamResponse(response as any)) {
buffer += chunk;
if (buffer.startsWith("[")) {
buffer = buffer.slice(1);
@@ -301,11 +292,11 @@ export class GeminiApi implements BaseLlmApi {
if ("text" in part) {
yield chatChunk({
content: part.text,
- model: body.model,
+ model,
});
} else if ("functionCall" in part) {
yield chatChunkFromDelta({
- model: body.model,
+ model,
delta: {
tool_calls: [
{
@@ -333,6 +324,23 @@ export class GeminiApi implements BaseLlmApi {
}
}
}
+
+ async *chatCompletionStream(
+ body: ChatCompletionCreateParamsStreaming,
+ signal: AbortSignal,
+ ): AsyncGenerator {
+ const apiURL = new URL(
+ `models/${body.model}:streamGenerateContent?key=${this.config.apiKey}`,
+ this.apiBase,
+ ).toString();
+ const convertedBody = this._convertBody(body, apiURL, true);
+ const resp = await customFetch(this.config.requestOptions)(apiURL, {
+ method: "POST",
+ body: JSON.stringify(convertedBody),
+ signal,
+ });
+ yield* this.handleStreamResponse(resp, body.model);
+ }
completionNonStream(
body: CompletionCreateParamsNonStreaming,
): Promise {
diff --git a/packages/openai-adapters/src/apis/VertexAI.ts b/packages/openai-adapters/src/apis/VertexAI.ts
new file mode 100644
index 00000000000..74de768b8ca
--- /dev/null
+++ b/packages/openai-adapters/src/apis/VertexAI.ts
@@ -0,0 +1,569 @@
+import { streamSse } from "@continuedev/fetch";
+import { AuthClient, GoogleAuth, JWT, auth } from "google-auth-library";
+import {
+ ChatCompletion,
+ ChatCompletionChunk,
+ ChatCompletionCreateParams,
+ ChatCompletionCreateParamsNonStreaming,
+ ChatCompletionCreateParamsStreaming,
+ Completion,
+ CompletionCreateParamsNonStreaming,
+ CompletionCreateParamsStreaming,
+ CreateEmbeddingResponse,
+ EmbeddingCreateParams,
+ Model,
+} from "openai/resources/index";
+import { VertexAIConfig } from "../types.js";
+import { chatChunk, chatCompletion, customFetch, embedding } from "../util.js";
+import { AnthropicApi } from "./Anthropic.js";
+import {
+ BaseLlmApi,
+ CreateRerankResponse,
+ FimCreateParamsStreaming,
+ RerankCreateParams,
+} from "./base.js";
+import { GeminiApi } from "./Gemini.js";
+import { OpenAIApi } from "./OpenAI.js";
+
+export class VertexAIApi implements BaseLlmApi {
+ anthropicInstance: AnthropicApi;
+ geminiInstance: GeminiApi;
+ mistralInstance: OpenAIApi;
+ private clientPromise?: Promise;
+ static AUTH_SCOPES = "https://www.googleapis.com/auth/cloud-platform";
+
+ constructor(protected config: VertexAIConfig) {
+ this.setupAuthentication();
+
+ // These sub-instances are only used to convert and handle responses,
+ // So do not need apiKey, etc
+ this.anthropicInstance = new AnthropicApi({
+ provider: "anthropic",
+ apiKey: "dud",
+ });
+ this.geminiInstance = new GeminiApi({
+ provider: "gemini",
+ apiKey: "dud",
+ });
+ this.mistralInstance = new OpenAIApi({
+ provider: "mistral",
+ apiKey: "dud",
+ });
+ }
+
+ private setupAuthentication(): void {
+ const { apiKey, env } = this.config;
+ const { region, projectId, keyFile, keyJson } = env || {};
+
+ // Validate authentication configuration
+ if (apiKey) {
+ // Express mode validation
+ if (region || projectId || keyFile || keyJson) {
+ throw new Error(
+ "VertexAI in express mode (apiKey only) cannot be configured with region, projectId, keyFile, or keyJson",
+ );
+ }
+ } else {
+ // Standard mode validation
+ if (!region || !projectId) {
+ throw new Error(
+ "region and projectId are required for VertexAI (when not using express/apiKey mode)",
+ );
+ }
+ if (keyFile && keyJson) {
+ throw new Error(
+ "VertexAI credentials can be configured with either keyFile or keyJson but not both",
+ );
+ }
+ }
+
+ // Set up authentication client
+ if (keyJson) {
+ try {
+ const parsed = JSON.parse(keyJson);
+ if (!parsed?.private_key) {
+ throw new Error("VertexAI: keyJson must contain a valid private key");
+ }
+ parsed.private_key = parsed.private_key.replace(/\\n/g, "\n");
+ const jsonClient = auth.fromJSON(parsed);
+ if (jsonClient instanceof JWT) {
+ jsonClient.scopes = [VertexAIApi.AUTH_SCOPES];
+ } else {
+ throw new Error("VertexAI: keyJson must be a valid JWT");
+ }
+ this.clientPromise = Promise.resolve(jsonClient);
+ } catch (e) {
+ throw new Error("VertexAI: Failed to parse keyJson");
+ }
+ } else if (keyFile) {
+ if (typeof keyFile !== "string") {
+ throw new Error("VertexAI: keyFile must be a string");
+ }
+ this.clientPromise = new GoogleAuth({
+ scopes: VertexAIApi.AUTH_SCOPES,
+ keyFile,
+ })
+ .getClient()
+ .catch((e: Error) => {
+ console.warn(
+ `Failed to load credentials for Vertex AI: ${e.message}`,
+ );
+ });
+ } else if (!apiKey) {
+ // Application Default Credentials
+ this.clientPromise = new GoogleAuth({
+ scopes: VertexAIApi.AUTH_SCOPES,
+ })
+ .getClient()
+ .catch((e: Error) => {
+ console.warn(
+ `Failed to load credentials for Vertex AI: ${e.message}`,
+ );
+ });
+ }
+ }
+
+ private getApiBase(): string {
+ const { apiKey, env } = this.config;
+
+ if (this.config.apiBase) {
+ return this.config.apiBase;
+ }
+
+ if (apiKey) {
+ // Express mode
+ return "https://aiplatform.googleapis.com/v1/";
+ } else {
+ // Standard mode
+ const { region, projectId } = env!;
+ return `https://${region}-aiplatform.googleapis.com/v1/projects/${projectId}/locations/${region}/`;
+ }
+ }
+
+ private determineVertexProvider(
+ model: string,
+ ): "mistral" | "anthropic" | "gemini" | "unknown" {
+ if (
+ model.includes("mistral") ||
+ model.includes("codestral") ||
+ model.includes("mixtral")
+ ) {
+ return "mistral";
+ } else if (model.includes("claude")) {
+ return "anthropic";
+ } else if (model.includes("gemini")) {
+ return "gemini";
+ }
+ return "unknown";
+ }
+
+ private async getAuthHeaders(): Promise> {
+ const headers: Record = {
+ "Content-Type": "application/json",
+ // Accept: "application/json"
+ };
+
+ // TODO - support anthropic prompt caching with "anthropic-beta" header
+
+ if (this.config.apiKey) {
+ // Express mode - no Authorization header needed, API key is in URL
+ return headers;
+ } else {
+ // Standard mode - use OAuth token
+ const client = await this.clientPromise;
+ const result = await client?.getAccessToken();
+ if (!result?.token) {
+ throw new Error(
+ "Could not get an access token. Set up your Google Application Default Credentials.",
+ );
+ }
+ headers.Authorization = `Bearer ${result.token}`;
+ return headers;
+ }
+ }
+
+ private buildUrl(endpoint: string, model?: string): URL {
+ const apiBase = this.getApiBase();
+ const url = new URL(endpoint, apiBase);
+
+ if (this.config.apiKey) {
+ url.searchParams.set("key", this.config.apiKey);
+ }
+
+ return url;
+ }
+
+ private convertAnthropicBody(oaiBody: ChatCompletionCreateParams): object {
+ const body = this.anthropicInstance._convertToCleanAnthropicBody(oaiBody);
+ const { model, ...exceptModel } = body;
+ return {
+ ...exceptModel,
+ anthropic_version: "vertex-2023-10-16",
+ };
+ }
+
+ private convertGeminiBody(
+ oaiBody: ChatCompletionCreateParams,
+ url: URL,
+ ): object {
+ return this.geminiInstance._convertBody(
+ oaiBody,
+ url.toString(),
+ false,
+ false,
+ );
+ }
+
+ async chatCompletionNonStream(
+ body: ChatCompletionCreateParamsNonStreaming,
+ signal: AbortSignal,
+ ): Promise {
+ const vertexProvider = this.determineVertexProvider(body.model);
+
+ if (this.config.apiKey && vertexProvider !== "gemini") {
+ throw new Error(
+ "VertexAI: only gemini models are supported in express (apiKey) mode",
+ );
+ }
+
+ const headers = await this.getAuthHeaders();
+ let url: URL;
+ let requestBody: any;
+
+ switch (vertexProvider) {
+ case "anthropic":
+ url = this.buildUrl(
+ `publishers/anthropic/models/${body.model}:rawPredict`,
+ );
+ requestBody = this.convertAnthropicBody(body);
+ break;
+ case "gemini":
+ url = this.buildUrl(
+ `publishers/google/models/${body.model}:generateContent`,
+ );
+ requestBody = this.convertGeminiBody(body, url);
+ break;
+ case "mistral":
+ url = this.buildUrl(
+ `publishers/mistralai/models/${body.model}:rawPredict`,
+ );
+ requestBody = body;
+ break;
+ default:
+ throw new Error(`Unsupported model: ${body.model}`);
+ }
+
+ const response = await customFetch(this.config.requestOptions)(
+ url.toString(),
+ {
+ method: "POST",
+ headers,
+ body: JSON.stringify(requestBody),
+ signal,
+ },
+ );
+
+ const data = await response.json();
+
+ if (!response.ok) {
+ throw new Error(
+ `VertexAI API error: ${response.status} ${response.statusText}\n${JSON.stringify(data)}`,
+ );
+ }
+
+ // Convert response to OpenAI format
+ switch (vertexProvider) {
+ case "anthropic":
+ return chatCompletion({
+ content: data.content?.[0]?.text || "",
+ model: body.model,
+ });
+ case "gemini":
+ return chatCompletion({
+ content: data.candidates?.[0]?.content?.parts?.[0]?.text || "",
+ model: body.model,
+ });
+ case "mistral":
+ return chatCompletion({
+ content: data.choices?.[0]?.message?.content || "",
+ model: body.model,
+ });
+ default:
+ throw new Error(`Unsupported provider: ${vertexProvider}`);
+ }
+ }
+
+ async *chatCompletionStream(
+ body: ChatCompletionCreateParamsStreaming,
+ signal: AbortSignal,
+ ): AsyncGenerator {
+ const vertexProvider = this.determineVertexProvider(body.model);
+
+ if (this.config.apiKey && vertexProvider !== "gemini") {
+ throw new Error(
+ "VertexAI: only gemini models are supported in express (apiKey) mode",
+ );
+ }
+
+ const headers = await this.getAuthHeaders();
+ let url: URL;
+ let requestBody: any;
+
+ switch (vertexProvider) {
+ case "anthropic":
+ url = this.buildUrl(
+ `publishers/anthropic/models/${body.model}:streamRawPredict`,
+ );
+ requestBody = this.convertAnthropicBody(body);
+ break;
+ case "gemini":
+ url = this.buildUrl(
+ `publishers/google/models/${body.model}:streamGenerateContent`,
+ );
+ requestBody = this.convertGeminiBody(body, url);
+ break;
+ case "mistral":
+ url = this.buildUrl(
+ `publishers/mistralai/models/${body.model}:streamRawPredict`,
+ );
+ requestBody = body;
+ break;
+ default:
+ throw new Error(`Unsupported model: ${body.model}`);
+ }
+
+ switch (vertexProvider) {
+ case "mistral":
+ const mistralResponse =
+ await this.mistralInstance.openai.chat.completions.create(
+ this.mistralInstance.modifyChatBody(body),
+ {
+ signal,
+ headers,
+ },
+ );
+ for await (const result of mistralResponse) {
+ yield result;
+ }
+ break;
+ case "anthropic":
+ case "gemini":
+ const response = await customFetch(this.config.requestOptions)(
+ url.toString(),
+ {
+ method: "POST",
+ headers,
+ body: JSON.stringify(requestBody),
+ signal,
+ },
+ );
+
+ if (!response.ok) {
+ const data = await response.json();
+ throw new Error(
+ `VertexAI API error: ${response.status} ${response.statusText}\n${JSON.stringify(data)}`,
+ );
+ }
+
+ if (response.status === 499) {
+ return; // Aborted by user
+ }
+ if (vertexProvider === "gemini") {
+ yield* this.geminiInstance.handleStreamResponse(response, body.model);
+ } else {
+ yield* this.anthropicInstance.handleStreamResponse(
+ response,
+ body.model,
+ );
+ }
+ break;
+ }
+ }
+
+ async completionNonStream(
+ body: CompletionCreateParamsNonStreaming,
+ signal: AbortSignal,
+ ): Promise {
+ // Convert completion to chat completion and back
+ const promptText =
+ typeof body.prompt === "string"
+ ? body.prompt
+ : Array.isArray(body.prompt)
+ ? body.prompt.join("")
+ : "";
+
+ const chatBody: ChatCompletionCreateParamsNonStreaming = {
+ model: body.model,
+ messages: [{ role: "user", content: promptText }],
+ max_tokens: body.max_tokens,
+ temperature: body.temperature,
+ top_p: body.top_p,
+ stop: body.stop,
+ stream: false,
+ };
+
+ const chatResponse = await this.chatCompletionNonStream(chatBody, signal);
+
+ return {
+ id: chatResponse.id,
+ object: "text_completion",
+ created: chatResponse.created,
+ model: chatResponse.model,
+ choices: [
+ {
+ text: chatResponse.choices[0]?.message?.content || "",
+ index: 0,
+ logprobs: null,
+ finish_reason: chatResponse.choices[0]?.finish_reason || null,
+ },
+ ],
+ usage: chatResponse.usage,
+ } as Completion;
+ }
+
+ async *completionStream(
+ body: CompletionCreateParamsStreaming,
+ signal: AbortSignal,
+ ): AsyncGenerator {
+ // Convert completion to chat completion and back
+ const promptText =
+ typeof body.prompt === "string"
+ ? body.prompt
+ : Array.isArray(body.prompt)
+ ? body.prompt.join("")
+ : "";
+
+ const chatBody: ChatCompletionCreateParamsStreaming = {
+ model: body.model,
+ messages: [{ role: "user", content: promptText }],
+ max_tokens: body.max_tokens,
+ temperature: body.temperature,
+ top_p: body.top_p,
+ stop: body.stop,
+ stream: true,
+ };
+
+ for await (const chatChunk of this.chatCompletionStream(chatBody, signal)) {
+ yield {
+ id: chatChunk.id,
+ object: "text_completion",
+ created: chatChunk.created,
+ model: chatChunk.model,
+ choices: [
+ {
+ text: chatChunk.choices[0]?.delta?.content || "",
+ index: 0,
+ logprobs: null,
+ finish_reason: chatChunk.choices[0]?.finish_reason || null,
+ },
+ ],
+ } as Completion;
+ }
+ }
+
+ async *fimStream(
+ body: FimCreateParamsStreaming,
+ signal: AbortSignal,
+ ): AsyncGenerator {
+ // Only Codestral (Mistral) supports FIM in VertexAI
+ if (!body.model.includes("codestral")) {
+ throw new Error(
+ `FIM is only supported for Codestral models, got: ${body.model}`,
+ );
+ }
+
+ const headers = await this.getAuthHeaders();
+ const url = this.buildUrl(
+ `publishers/mistralai/models/${body.model}:streamRawPredict`,
+ );
+
+ const requestBody = {
+ model: body.model,
+ max_tokens: body.max_tokens,
+ temperature: body.temperature,
+ top_p: body.top_p,
+ stream: body.stream ?? true,
+ stop: body.stop,
+ prompt: body.prompt,
+ suffix: body.suffix,
+ };
+
+ const response = await customFetch(this.config.requestOptions)(
+ url.toString(),
+ {
+ method: "POST",
+ headers,
+ body: JSON.stringify(requestBody),
+ signal,
+ },
+ );
+
+ if (!response.ok) {
+ throw new Error(
+ `VertexAI API error: ${response.status} ${response.statusText}`,
+ );
+ }
+
+ for await (const chunk of streamSse(response)) {
+ if (chunk.choices?.[0]?.delta?.content) {
+ yield chatChunk({
+ content: chunk.choices[0].delta.content,
+ model: body.model,
+ });
+ }
+ }
+ }
+
+ async embed(body: EmbeddingCreateParams): Promise {
+ const headers = await this.getAuthHeaders();
+ const url = this.buildUrl(`publishers/google/models/${body.model}:predict`);
+
+ // Convert input to text strings
+ const textInputs = Array.isArray(body.input)
+ ? body.input.map((item) =>
+ typeof item === "string" ? item : JSON.stringify(item),
+ )
+ : [
+ typeof body.input === "string"
+ ? body.input
+ : JSON.stringify(body.input),
+ ];
+
+ const requestBody = {
+ instances: textInputs.map((text) => ({ content: text })),
+ };
+
+ const response = await customFetch(this.config.requestOptions)(
+ url.toString(),
+ {
+ method: "POST",
+ headers,
+ body: JSON.stringify(requestBody),
+ },
+ );
+
+ if (!response.ok) {
+ throw new Error(
+ `VertexAI API error: ${response.status} ${response.statusText}`,
+ );
+ }
+
+ const data = await response.json();
+ const embeddings = data.predictions.map(
+ (prediction: any) => prediction.embeddings.values,
+ );
+
+ return embedding({
+ data: embeddings,
+ model: body.model,
+ });
+ }
+
+ async rerank(body: RerankCreateParams): Promise {
+ throw new Error("Reranking is not supported by VertexAI");
+ }
+
+ async list(): Promise {
+ throw new Error("VertexAI provider does not support model listing.");
+ }
+}
diff --git a/packages/openai-adapters/src/index.ts b/packages/openai-adapters/src/index.ts
index 3e05fb15306..07f849f3375 100644
--- a/packages/openai-adapters/src/index.ts
+++ b/packages/openai-adapters/src/index.ts
@@ -14,6 +14,7 @@ import { MockApi } from "./apis/Mock.js";
import { MoonshotApi } from "./apis/Moonshot.js";
import { OpenAIApi } from "./apis/OpenAI.js";
import { RelaceApi } from "./apis/Relace.js";
+import { VertexAIApi } from "./apis/VertexAI.js";
import { WatsonXApi } from "./apis/WatsonX.js";
import { BaseLlmApi } from "./apis/base.js";
import { LLMConfig, OpenAIConfigSchema } from "./types.js";
@@ -56,6 +57,8 @@ export function constructLlmApi(config: LLMConfig): BaseLlmApi | undefined {
return new InceptionApi(config);
case "watsonx":
return new WatsonXApi(config);
+ case "vertexai":
+ return new VertexAIApi(config);
case "llamastack":
return new LlamastackApi(config);
case "continue-proxy":
diff --git a/packages/openai-adapters/src/types.ts b/packages/openai-adapters/src/types.ts
index 36da5936786..6786ec812c2 100644
--- a/packages/openai-adapters/src/types.ts
+++ b/packages/openai-adapters/src/types.ts
@@ -165,6 +165,19 @@ export const InceptionConfigSchema = OpenAIConfigSchema.extend({
});
export type InceptionConfig = z.infer;
+export const VertexAIConfigSchema = BasePlusConfig.extend({
+ provider: z.literal("vertexai"),
+ env: z
+ .object({
+ region: z.string().optional(),
+ projectId: z.string().optional(),
+ keyFile: z.string().optional(),
+ keyJson: z.string().optional(),
+ })
+ .optional(),
+});
+export type VertexAIConfig = z.infer;
+
// Discriminated union
export const LLMConfigSchema = z.discriminatedUnion("provider", [
OpenAIConfigSchema,
@@ -179,6 +192,7 @@ export const LLMConfigSchema = z.discriminatedUnion("provider", [
JinaConfigSchema,
MockConfigSchema,
InceptionConfigSchema,
+ VertexAIConfigSchema,
LlamastackConfigSchema,
ContinueProxyConfigSchema,
]);
diff --git a/scripts/oneper b/scripts/oneper
new file mode 100755
index 00000000000..52ad8623aec
--- /dev/null
+++ b/scripts/oneper
@@ -0,0 +1,283 @@
+#!/usr/bin/env bash
+set -e
+
+# oneper - Install Continue VS Code extension from PR builds or latest pre-release
+# Usage:
+# oneper install --pr X - Install VSIX from PR number X
+# oneper install --latest - Install latest pre-release from marketplace
+
+REPO="continuedev/continue"
+ONEPER_DIR="$HOME/.continue/.utils/oneper"
+
+show_help() {
+ echo "oneper - Install Continue VS Code extension from PR builds or latest pre-release"
+ echo ""
+ echo "Usage: oneper [options]"
+ echo " oneper -h | --help"
+ echo ""
+ echo "Commands:"
+ echo " install --pr [--platform ]"
+ echo " Download and install VSIX from specified PR number"
+ echo " Platform options: macos, linux (auto-detected by default)"
+ echo " install --latest Install latest pre-release from VS Code marketplace"
+ echo " clean Remove all downloaded VSIX files from oneper cache"
+ echo ""
+ echo "Options:"
+ echo " -h, --help Show this help message"
+ echo " --platform Specify platform for PR builds (macos, linux)"
+ echo ""
+ echo "Examples:"
+ echo " oneper install --pr 123 # Install VSIX from PR #123"
+ echo " oneper install --pr 123 --platform linux # Install Linux VSIX from PR #123"
+ echo " oneper install --latest # Install latest pre-release"
+ echo " oneper clean # Clear cached VSIX files"
+ echo " oneper -h # Show help"
+ echo ""
+ echo "VSIX files are cached in: ~/.continue/.utils/oneper/"
+}
+
+detect_os() {
+ case "$(uname -s)" in
+ "Darwin")
+ echo "macos"
+ ;;
+ "Linux")
+ echo "linux"
+ ;;
+ *)
+ echo "โ Unsupported operating system: $(uname -s)" >&2
+ echo " Supported platforms: macOS, Linux" >&2
+ exit 1
+ ;;
+ esac
+}
+
+check_dependencies() {
+ if ! command -v gh &> /dev/null; then
+ echo "โ GitHub CLI (gh) is required but not installed."
+ echo " Install with: brew install gh"
+ exit 1
+ fi
+
+ if ! command -v code &> /dev/null; then
+ echo "โ VS Code CLI (code) is required but not installed."
+ echo " Install VS Code and ensure 'code' command is in PATH"
+ exit 1
+ fi
+
+}
+
+ensure_oneper_dir() {
+ if [ ! -d "$ONEPER_DIR" ]; then
+ echo "๐ Creating oneper directory: $ONEPER_DIR"
+ mkdir -p "$ONEPER_DIR"
+ fi
+}
+
+install_from_pr() {
+ local pr_number=$1
+ local platform=${2:-$(detect_os)} # Auto-detect OS if not specified
+
+ if [ -z "$pr_number" ]; then
+ echo "โ PR number is required"
+ show_help
+ exit 1
+ fi
+
+ # Map platform names to GitHub runner OS names
+ local artifact_suffix
+ case "$platform" in
+ "macos")
+ artifact_suffix="macOS"
+ ;;
+ "linux")
+ artifact_suffix="Linux"
+ ;;
+ *)
+ echo "โ Unknown platform: $platform"
+ echo " Supported platforms: macos, linux"
+ exit 1
+ ;;
+ esac
+
+ echo "๐ Getting branch name for PR #$pr_number..."
+
+ # First get the branch name for the PR
+ local branch_name=$(gh pr view "$pr_number" --repo "$REPO" --json headRefName --jq '.headRefName')
+
+ if [ -z "$branch_name" ]; then
+ echo "โ Could not find PR #$pr_number"
+ exit 1
+ fi
+
+ echo "๐ Finding latest workflow run for branch: $branch_name..."
+
+ # Get the latest successful workflow run for the branch
+ local run_id=$(gh run list \
+ --repo "$REPO" \
+ --workflow="pr_checks.yaml" \
+ --branch="$branch_name" \
+ --json databaseId,status,conclusion \
+ --jq ".[] | select(.status == \"completed\" and .conclusion == \"success\") | .databaseId" \
+ | head -1)
+
+ if [ -z "$run_id" ]; then
+ echo "โ No successful workflow run found for PR #$pr_number"
+ echo " Make sure the PR exists and has a successful CI run"
+ exit 1
+ fi
+
+ echo "โ
Found workflow run: $run_id"
+ echo "๐ฅ Downloading vscode-extension-build-$artifact_suffix artifact..."
+
+ # Create temporary directory for download
+ local temp_dir=$(mktemp -d)
+
+ # Download the artifact
+ if ! gh run download "$run_id" \
+ --repo "$REPO" \
+ --name "vscode-extension-build-$artifact_suffix" \
+ --dir "$temp_dir"; then
+ echo "โ Failed to download artifact vscode-extension-build-$artifact_suffix"
+ echo " Make sure the workflow run completed successfully for $platform"
+ rm -rf "$temp_dir"
+ exit 1
+ fi
+
+ # Find the VSIX file in the downloaded artifact
+ local vsix_file=$(find "$temp_dir" -name "*.vsix" | head -1)
+
+ if [ -z "$vsix_file" ]; then
+ echo "โ No VSIX file found in artifact"
+ rm -rf "$temp_dir"
+ exit 1
+ fi
+
+ # Extract version from the original VSIX filename (e.g., continue-1.1.66.vsix -> 1.1.66)
+ local original_filename=$(basename "$vsix_file")
+ local version=$(echo "$original_filename" | sed 's/continue-\(.*\)\.vsix/\1/')
+
+ if [ -z "$version" ]; then
+ echo "โ ๏ธ Could not extract version from filename: $original_filename"
+ version="unknown"
+ fi
+
+ # Create new VSIX name with version and PR number
+ local target_path="$ONEPER_DIR/continue-${version}-${pr_number}.vsix"
+
+ # Check if file already exists and notify about overwrite
+ if [ -f "$target_path" ]; then
+ echo "โ ๏ธ Overwriting existing VSIX: $target_path"
+ fi
+
+ echo "๐ฆ Moving VSIX to: $target_path"
+ mv "$vsix_file" "$target_path"
+
+ # Clean up temp directory
+ rm -rf "$temp_dir"
+
+ # Install the extension
+ echo "๐ Installing VS Code extension..."
+ if code --install-extension "$target_path"; then
+ echo "โ
Successfully installed Continue extension from PR #$pr_number"
+ echo "๐ VSIX file saved to: $target_path"
+ echo ""
+ echo "๐ก To use the new extension version, reload your VS Code window:"
+ echo " โข Press Ctrl+Shift+P (Cmd+Shift+P on Mac)"
+ echo " โข Type 'Developer: Reload Window' and press Enter"
+ echo " โข Or restart VS Code entirely"
+ else
+ echo "โ Failed to install extension"
+ exit 1
+ fi
+}
+
+install_latest() {
+ echo "๐ Installing latest pre-release Continue extension..."
+ if code --install-extension --pre-release Continue.continue; then
+ echo "โ
Successfully installed latest pre-release Continue extension"
+ echo ""
+ echo "๐ก To use the new extension version, reload your VS Code window:"
+ echo " โข Press Ctrl+Shift+P (Cmd+Shift+P on Mac)"
+ echo " โข Type 'Developer: Reload Window' and press Enter"
+ echo " โข Or restart VS Code entirely"
+ else
+ echo "โ Failed to install extension"
+ exit 1
+ fi
+}
+
+clean_cache() {
+ if [ ! -d "$ONEPER_DIR" ]; then
+ echo "๐ Oneper cache directory doesn't exist: $ONEPER_DIR"
+ return 0
+ fi
+
+ local file_count=$(find "$ONEPER_DIR" -name "*.vsix" | wc -l | tr -d ' ')
+
+ if [ "$file_count" -eq 0 ]; then
+ echo "โจ Oneper cache is already empty"
+ return 0
+ fi
+
+ echo "๐งน Removing $file_count VSIX file(s) from oneper cache..."
+ rm -f "$ONEPER_DIR"/*.vsix
+
+ echo "โ
Oneper cache cleared successfully"
+ echo "๐ Cache directory: $ONEPER_DIR"
+}
+
+main() {
+ if [ $# -eq 0 ]; then
+ show_help
+ exit 1
+ fi
+
+ # Handle help flags first
+ case "$1" in
+ "-h"|"--help")
+ show_help
+ exit 0
+ ;;
+ esac
+
+ check_dependencies
+ ensure_oneper_dir
+
+ case "$1" in
+ "install")
+ case "$2" in
+ "--pr")
+ # Parse PR number and optional platform
+ local pr_number="$3"
+ local platform=$(detect_os) # auto-detect OS
+
+ # Check if --platform is specified to override auto-detection
+ if [ "$4" = "--platform" ] && [ -n "$5" ]; then
+ platform="$5"
+ fi
+
+ install_from_pr "$pr_number" "$platform"
+ ;;
+ "--latest")
+ install_latest
+ ;;
+ *)
+ echo "โ Unknown install option: $2"
+ show_help
+ exit 1
+ ;;
+ esac
+ ;;
+ "clean")
+ clean_cache
+ ;;
+ *)
+ echo "โ Unknown command: $1"
+ show_help
+ exit 1
+ ;;
+ esac
+}
+
+main "$@"
\ No newline at end of file