import type { components as ApiComponents } from "./types/tabbyApi"; import { AgentConfig, PartialAgentConfig } from "./AgentConfig"; export type AgentInitOptions = Partial<{ config: PartialAgentConfig; client: string; clientProperties: Record; }>; export type ServerHealthState = ApiComponents["schemas"]["HealthState"]; export type CompletionRequest = { filepath: string; language: string; text: string; position: number; manually?: boolean; }; export type CompletionResponse = ApiComponents["schemas"]["CompletionResponse"]; export type LogEventRequest = ApiComponents["schemas"]["LogEventRequest"] & { select_kind?: "line"; }; export type AbortSignalOption = { signal: AbortSignal }; export type SlowCompletionResponseTimeIssue = { name: "slowCompletionResponseTime"; completionResponseStats: Record; }; export type HighCompletionTimeoutRateIssue = { name: "highCompletionTimeoutRate"; completionResponseStats: Record; }; export type AgentIssue = SlowCompletionResponseTimeIssue | HighCompletionTimeoutRateIssue; /** * Represents the status of the agent. * @enum * @property {string} notInitialized - When the agent is not initialized. * @property {string} ready - When the agent gets a valid response from the server. * @property {string} disconnected - When the agent fails to connect to the server. * @property {string} unauthorized - When the server is set to a Tabby Cloud endpoint that requires auth, * and no `Authorization` request header is provided in the agent config, * and the user has not completed the auth flow or the auth token is expired. * See also `requestAuthUrl` and `waitForAuthToken`. */ export type AgentStatus = "notInitialized" | "ready" | "disconnected" | "unauthorized"; export interface AgentFunction { /** * Initialize agent. Client should call this method before calling any other methods. * @param options */ initialize(options?: AgentInitOptions): Promise; /** * Finalize agent. Client should call this method before exiting. */ finalize(): Promise; /** * The agent configuration has the following levels, will be deep merged in the order: * 1. Default config * 2. User config file `~/.tabby-client/agent/config.toml` (not available in browser) * 3. Agent `initialize` and `updateConfig` methods * * This method will update the 3rd level config. * @param key the key of the config to update, can be nested with dot, e.g. `server.endpoint` * @param value the value to set */ updateConfig(key: string, value: any): Promise; /** * Clear the 3rd level config. * @param key the key of the config to clear, can be nested with dot, e.g. `server.endpoint` */ clearConfig(key: string): Promise; /** * @returns the current config */ getConfig(): AgentConfig; /** * @returns the current status */ getStatus(): AgentStatus; /** * @returns the current issues if any exists */ getIssues(detail?: boolean): AgentIssue["name"][]; /** * Get the detail of an issue by index or name. * @param options if `index` is provided, `name` will be ignored * @returns the issue detail if exists, otherwise null */ getIssueDetail(options: { index?: number; name?: AgentIssue["name"] }): AgentIssue | null; /** * @returns server info returned from latest server health check, returns null if not available */ getServerHealthState(): ServerHealthState | null; /** * Request auth url for Tabby Cloud endpoint. Only return value when the `AgentStatus` is `unauthorized`. * Otherwise, return null. See also `AgentStatus`. * @returns the auth url for redirecting, and the code for next step `waitingForAuth` * @throws Error if agent is not initialized */ requestAuthUrl(options?: AbortSignalOption): Promise<{ authUrl: string; code: string } | null>; /** * Wait for auth token to be ready after redirecting user to auth url, * returns nothing, but `AgentStatus` will change to `ready` if resolved successfully. * @param code from `requestAuthUrl` * @throws Error if agent is not initialized */ waitForAuthToken(code: string, options?: AbortSignalOption): Promise; /** * Provide completions for the given request. This method is debounced, calling it before the previous * call is resolved will cancel the previous call. The debouncing interval is automatically calculated * or can be set in the config. * @param request * @returns * @throws Error if agent is not initialized */ provideCompletions(request: CompletionRequest, options?: AbortSignalOption): Promise; /** * @param event * @returns * @throws Error if agent is not initialized */ postEvent(event: LogEventRequest, options?: AbortSignalOption): Promise; } export type StatusChangedEvent = { event: "statusChanged"; status: AgentStatus; }; export type ConfigUpdatedEvent = { event: "configUpdated"; config: AgentConfig; }; /** * This event is emitted when the server is set to a Tabby Cloud endpoint that requires auth, * and no `Authorization` request header is provided in the agent config. */ export type AuthRequiredEvent = { event: "authRequired"; server: AgentConfig["server"]; }; export type IssuesUpdatedEvent = { event: "issuesUpdated"; issues: AgentIssue["name"][]; }; export type AgentEvent = StatusChangedEvent | ConfigUpdatedEvent | AuthRequiredEvent | IssuesUpdatedEvent; export const agentEventNames: AgentEvent["event"][] = [ "statusChanged", "configUpdated", "authRequired", "issuesUpdated", ]; export interface AgentEventEmitter { on(eventName: T["event"], callback: (event: T) => void): this; } export type Agent = AgentFunction & AgentEventEmitter;