refactor: streamline type exports and improve import organization

- Refactored type exports in skill-api, runtime-addon, and types files for better clarity and consistency.
- Updated import paths to utilize centralized type definitions, enhancing maintainability.
- Improved the BrowserMessageActions component to handle text content more effectively when copying messages.

These changes contribute to a cleaner codebase and improved functionality across the project.
This commit is contained in:
ropzislaw
2026-03-08 15:53:47 +08:00
parent b0b6020132
commit 017481a690
17 changed files with 134 additions and 113 deletions

View File

@@ -21,10 +21,16 @@ import { shareConversation } from "../services/share-conversation";
import { isByokConfigured } from "./ai-provider";
export function BrowserMessageActions({
message,
onRegenerate,
onCopy,
}: MessageActionsSlotProps) {
const { messages, sendMessage } = useChatContext();
const textContent = message.parts
.filter((p) => p.type === "text")
.map((p) => (p.type === "text" ? p.text : ""))
.join("\n");
const { user } = useAuth();
const { settings } = useConfigContext();
const [isSharing, setIsSharing] = useState(false);
@@ -57,8 +63,8 @@ export function BrowserMessageActions({
return (
<Actions className="mt-2">
{onCopy && (
<Action onClick={onCopy} label="Copy">
{onCopy && textContent && (
<Action onClick={() => onCopy(textContent)} label="Copy">
<CopyIcon className="size-3" />
</Action>
)}

View File

@@ -4,14 +4,10 @@
* between QuickJS VM and the host environment
*/
import type { FileStats } from "./types";
import { zenfs } from "./zenfs-manager";
export interface FileStats {
isFile: boolean;
isDirectory: boolean;
size: number;
mtime: Date;
}
export type { FileStats };
export interface ToolDefinition {
name: string;

View File

@@ -0,0 +1,6 @@
export interface FileStats {
isFile: boolean;
isDirectory: boolean;
size: number;
mtime: Date;
}

View File

@@ -5,7 +5,7 @@
import { configure, fs } from "@zenfs/core";
import { IndexedDB } from "@zenfs/dom";
import type { FileStats } from "./skill-api";
import type { FileStats } from "./types";
type FsPromises = {
mkdir: (...args: any[]) => Promise<any>;

View File

@@ -1,30 +1,17 @@
import type { ContextProvider } from "@aipexstudio/aipex-core";
import type { RuntimeAddon } from "./runtime-addon.js";
import type { RuntimeBroadcastMessage } from "./types.js";
import type {
AutomationTarget,
RuntimeAddon,
RuntimeBroadcastMessage,
SnapshotCaptureOptions,
SnapshotResult,
} from "./types.js";
export interface AutomationTarget {
tabId: number;
frameId?: number;
windowId?: number;
}
export interface SnapshotCaptureOptions {
includeDom?: boolean;
includeScreenshot?: boolean;
includeContext?: boolean;
reason?: string;
tabId?: number;
}
export interface SnapshotResult {
id: string;
capturedAt: number;
screenshot?: string;
dom?: string;
title?: string;
url?: string;
metadata?: Record<string, unknown>;
}
export type {
AutomationTarget,
SnapshotCaptureOptions,
SnapshotResult,
} from "./types.js";
export interface CaptureSessionOptions {
target: AutomationTarget;

View File

@@ -1,22 +1,4 @@
import type {
AutomationTarget,
SnapshotCaptureOptions,
SnapshotResult,
} from "./browser-automation-host.js";
import type { RuntimeBroadcastMessage } from "./types.js";
export interface SnapshotHookContext {
target: AutomationTarget;
options?: SnapshotCaptureOptions;
}
export interface RuntimeAddon {
id: string;
initialize?(): Promise<void> | void;
onMessage?(message: RuntimeBroadcastMessage): Promise<void> | void;
onBeforeSnapshot?(ctx: SnapshotHookContext): Promise<void> | void;
onAfterSnapshot?(
result: SnapshotResult,
ctx: SnapshotHookContext,
): Promise<void> | void;
}
export type {
RuntimeAddon,
SnapshotHookContext,
} from "./types.js";

View File

@@ -8,3 +8,43 @@ export interface RuntimeBroadcastMessage<TPayload = unknown> {
export interface RuntimeAddonCleanup {
dispose(): Promise<void> | void;
}
export interface AutomationTarget {
tabId: number;
frameId?: number;
windowId?: number;
}
export interface SnapshotCaptureOptions {
includeDom?: boolean;
includeScreenshot?: boolean;
includeContext?: boolean;
reason?: string;
tabId?: number;
}
export interface SnapshotResult {
id: string;
capturedAt: number;
screenshot?: string;
dom?: string;
title?: string;
url?: string;
metadata?: Record<string, unknown>;
}
export interface SnapshotHookContext {
target: AutomationTarget;
options?: SnapshotCaptureOptions;
}
export interface RuntimeAddon {
id: string;
initialize?(): Promise<void> | void;
onMessage?(message: RuntimeBroadcastMessage): Promise<void> | void;
onBeforeSnapshot?(ctx: SnapshotHookContext): Promise<void> | void;
onAfterSnapshot?(
result: SnapshotResult,
ctx: SnapshotHookContext,
): Promise<void> | void;
}

View File

@@ -128,47 +128,8 @@ export function registerDefaultBrowserTools<T extends ToolRegistryLike>(
return registry;
}
/**
* Get the currently active tab
* @throws Error if no active tab is found
*/
export async function getActiveTab(): Promise<chrome.tabs.Tab> {
const [tab] = await chrome.tabs.query({
active: true,
currentWindow: true,
});
if (!tab?.id) {
throw new Error("No active tab found");
}
return tab;
}
/**
* Execute a script in a specific tab
*/
export async function executeScriptInTab<T, Args extends any[]>(
tabId: number,
func: (...args: Args) => T,
args: Args,
): Promise<T> {
const results = await chrome.scripting.executeScript({
target: { tabId },
func,
args,
});
return results[0]?.result as T;
}
/**
* Execute a script in the active tab
*/
export async function executeScriptInActiveTab<T, Args extends any[]>(
func: (...args: Args) => T,
args: Args,
): Promise<T> {
const tab = await getActiveTab();
return await executeScriptInTab(tab.id!, func, args);
}
export {
executeScriptInActiveTab,
executeScriptInTab,
getActiveTab,
} from "./tab-utils";

View File

@@ -1,6 +1,6 @@
import { tool } from "@aipexstudio/aipex-core";
import { z } from "zod";
import { getActiveTab } from "./index";
import { getActiveTab } from "./tab-utils";
/**
* Get page metadata including title, description, keywords, etc.

View File

@@ -3,11 +3,11 @@ import { z } from "zod";
import { cacheScreenshotMetadata } from "../automation/computer";
import { RuntimeScreenshotStorage } from "../lib/screenshot-storage";
import { getAutomationMode } from "../runtime/automation-mode";
import { getActiveTab } from "./index";
import {
captureVisibleTabWithElementCrop,
MAX_PADDING,
} from "./screenshot-helpers.js";
import { getActiveTab } from "./tab-utils";
// Re-export the shared helper types/function so existing consumers aren't broken
export type {

View File

@@ -1,7 +1,7 @@
import { tool } from "@aipexstudio/aipex-core";
import { z } from "zod";
import * as snapshotProvider from "../automation/snapshot-provider";
import { getActiveTab } from "./index";
import { getActiveTab } from "./tab-utils";
export const takeSnapshotTool = tool({
name: "take_snapshot",

View File

@@ -0,0 +1,44 @@
/**
* Get the currently active tab
* @throws Error if no active tab is found
*/
export async function getActiveTab(): Promise<chrome.tabs.Tab> {
const [tab] = await chrome.tabs.query({
active: true,
currentWindow: true,
});
if (!tab?.id) {
throw new Error("No active tab found");
}
return tab;
}
/**
* Execute a script in a specific tab
*/
export async function executeScriptInTab<T, Args extends any[]>(
tabId: number,
func: (...args: Args) => T,
args: Args,
): Promise<T> {
const results = await chrome.scripting.executeScript({
target: { tabId },
func,
args,
});
return results[0]?.result as T;
}
/**
* Execute a script in the active tab
*/
export async function executeScriptInActiveTab<T, Args extends any[]>(
func: (...args: Args) => T,
args: Args,
): Promise<T> {
const tab = await getActiveTab();
return await executeScriptInTab(tab.id!, func, args);
}

View File

@@ -1,7 +1,7 @@
import { tool } from "@aipexstudio/aipex-core";
import { z } from "zod";
import { getAutomationMode } from "../runtime/automation-mode";
import { getActiveTab } from "./index";
import { getActiveTab } from "./tab-utils";
/**
* Get all open tabs across all windows

View File

@@ -1,4 +1,4 @@
import type { ProviderType } from "./settings.js";
import type { ProviderType } from "./types.js";
export interface AIProviderConfig {
name: string;

View File

@@ -1,6 +1,7 @@
import type { AIProviderKey } from "./ai-providers.js";
import type { ProviderType } from "./types.js";
export type ProviderType = "google" | "openai" | "claude";
export type { ProviderType };
export interface CustomModelConfig {
id: string;

View File

@@ -0,0 +1 @@
export type ProviderType = "google" | "openai" | "claude";

View File

@@ -4,10 +4,7 @@ import type {
Agent as OpenAIAgent,
} from "@openai/agents";
import type { AiSdkModel } from "@openai/agents-extensions";
import type { AIPex } from "./agent/aipex.js";
import type { Context, ContextManager } from "./context/index.js";
import type { ConversationManager } from "./conversation/manager.js";
import type { Session } from "./conversation/session.js";
import type { AgentError } from "./utils/errors.js";
// Re-export types from @openai/agents for convenient access
@@ -73,7 +70,7 @@ export interface AIPexOptions<
* Fully custom ConversationManager instance.
* When provided, storage and compression options are ignored.
*/
conversationManager?: ConversationManager;
conversationManager?: import("./conversation/manager.js").ConversationManager;
/**
* Context manager for providing additional context to the agent.
@@ -161,7 +158,7 @@ export interface MetricsPayload {
}
export interface AgentPluginContext {
agent: AIPex;
agent: import("./agent/aipex.js").AIPex;
}
export interface AgentPluginHooks {
@@ -240,8 +237,8 @@ export interface SessionTree {
}
export interface SessionStorageAdapter {
save(session: Session): Promise<void>;
load(id: string): Promise<Session | null>;
save(session: import("./conversation/session.js").Session): Promise<void>;
load(id: string): Promise<import("./conversation/session.js").Session | null>;
delete(id: string): Promise<void>;
listAll(): Promise<SessionSummary[]>;
getSessionTree(rootId?: string): Promise<SessionTree[]>;