import { Effect, Layer } from "effect";
import { type HttpClient } from "effect/unstable/http";
import { type FumaDb, type FumaTables, type StorageFailure } from "./fuma-runtime";
import { type BlobStore } from "./blob";
import type { Connection, ConnectionRef, CreateConnectionInput, UpdateConnectionInput } from "./connection";
import { type OnElicitation, type InvokeOptions } from "./elicitation";
export type { OnElicitation, InvokeOptions } from "./elicitation";
import { ConnectionNotFoundError, CredentialProviderNotRegisteredError, IntegrationNotFoundError, InvalidConnectionInputError, IntegrationRemovalNotAllowedError, type ExecuteError } from "./errors";
import { ConnectionAddress, ConnectionName, IntegrationSlug, Owner, ProviderKey, Subject, Tenant, ToolAddress, ToolName } from "./ids";
import type { Integration } from "./integration";
import type { OAuthService } from "./oauth-client";
import { type CreateToolPolicyInput, type EffectivePolicy, type RemoveToolPolicyInput, type ToolPolicy, type UpdateToolPolicyInput } from "./policies";
import type { CredentialProvider, ProviderEntry } from "./provider";
import type { AnyPlugin, PluginExtensions } from "./plugin";
import { ToolSchemaView, type IntegrationDetectionResult } from "./types";
import { type Tool, type ToolListFilter } from "./tool";
import { type OAuthEndpointUrlPolicy } from "./oauth-helpers";
export interface ParsedToolAddress {
    readonly integration: IntegrationSlug;
    readonly owner: Owner;
    readonly connection: ConnectionName;
    readonly tool: ToolName;
}
/** Parse a callable address; null when it's not a well-formed
 *  `tools.<integration>.<owner>.<connection>.<tool>`.
 *
 *  The four leading segments (prefix, integration, owner, connection) are
 *  slug-like and never contain a `.`; the `<tool>` segment is the *entire*
 *  remainder after the 4th dot, so it may itself contain dots. That lets a tool
 *  whose name is a structured `group.leaf` path (e.g. an OpenAPI
 *  `aliases.deleteAlias`) address naturally as
 *  `tools.<integration>.<owner>.<connection>.aliases.deleteAlias` — the same
 *  dotted nesting the sandbox `tools` proxy produces from property access. */
export declare const parseToolAddress: (address: string) => ParsedToolAddress | null;
export declare const connectionAddress: (owner: Owner, integration: IntegrationSlug, connection: ConnectionName) => ConnectionAddress;
export declare const toolAddress: (owner: Owner, integration: IntegrationSlug, connection: ConnectionName, tool: ToolName) => ToolAddress;
export type Executor<TPlugins extends readonly AnyPlugin[] = readonly []> = {
    readonly integrations: {
        readonly list: () => Effect.Effect<readonly Integration[], StorageFailure>;
        readonly get: (slug: IntegrationSlug) => Effect.Effect<Integration | null, StorageFailure>;
        readonly update: (slug: IntegrationSlug, patch: {
            readonly name?: string;
            readonly description?: string;
        }) => Effect.Effect<void, IntegrationNotFoundError | StorageFailure>;
        readonly remove: (slug: IntegrationSlug) => Effect.Effect<void, IntegrationRemovalNotAllowedError | StorageFailure>;
        readonly detect: (url: string) => Effect.Effect<readonly IntegrationDetectionResult[], StorageFailure>;
    };
    readonly connections: {
        readonly create: (input: CreateConnectionInput) => Effect.Effect<Connection, IntegrationNotFoundError | CredentialProviderNotRegisteredError | InvalidConnectionInputError | StorageFailure>;
        readonly list: (filter?: {
            readonly integration?: IntegrationSlug;
            readonly owner?: Owner;
        }) => Effect.Effect<readonly Connection[], StorageFailure>;
        readonly get: (ref: ConnectionRef) => Effect.Effect<Connection | null, StorageFailure>;
        /** Edit user-curated metadata (description, identityLabel). Credentials and
         *  OAuth lifecycle fields are not editable here. */
        readonly update: (ref: ConnectionRef, input: UpdateConnectionInput) => Effect.Effect<Connection, ConnectionNotFoundError | StorageFailure>;
        readonly remove: (ref: ConnectionRef) => Effect.Effect<void, ConnectionNotFoundError | StorageFailure>;
        readonly refresh: (ref: ConnectionRef) => Effect.Effect<readonly Tool[], ConnectionNotFoundError | IntegrationNotFoundError | StorageFailure>;
    };
    /** Shared OAuth service. Hosts use this through the core HTTP OAuth group;
     *  plugins see the same service as `ctx.oauth`. */
    readonly oauth: OAuthService;
    readonly tools: {
        readonly list: (filter?: ToolListFilter) => Effect.Effect<readonly Tool[], StorageFailure>;
        readonly schema: (address: ToolAddress) => Effect.Effect<ToolSchemaView | null, StorageFailure>;
    };
    readonly providers: {
        readonly list: () => Effect.Effect<readonly ProviderKey[]>;
        readonly items: (key: ProviderKey) => Effect.Effect<readonly ProviderEntry[], StorageFailure>;
    };
    readonly policies: {
        readonly list: () => Effect.Effect<readonly ToolPolicy[], StorageFailure>;
        readonly create: (input: CreateToolPolicyInput) => Effect.Effect<ToolPolicy, StorageFailure>;
        readonly update: (input: UpdateToolPolicyInput) => Effect.Effect<ToolPolicy, StorageFailure>;
        readonly remove: (input: RemoveToolPolicyInput) => Effect.Effect<void, StorageFailure>;
        readonly resolve: (address: ToolAddress) => Effect.Effect<EffectivePolicy, StorageFailure>;
    };
    readonly execute: (address: ToolAddress, args: unknown, options?: InvokeOptions) => Effect.Effect<unknown, ExecuteError>;
    readonly close: () => Effect.Effect<void, StorageFailure>;
} & PluginExtensions<TPlugins>;
export interface ExecutorDb {
    readonly db: FumaDb<any>;
    readonly close?: () => Effect.Effect<void, StorageFailure> | Promise<void> | void;
}
export type ExecutorDbInput = FumaDb<any> | ExecutorDb;
export type ExecutorDbFactory = (config: {
    readonly tables: FumaTables;
}) => ExecutorDbInput | Effect.Effect<ExecutorDbInput, StorageFailure>;
export interface ExecutorConfig<TPlugins extends readonly AnyPlugin[] = readonly []> {
    /** The org / workspace this executor is bound to. `owner: "org"` rows file
     *  here. */
    readonly tenant: Tenant;
    /** The acting member, or omit for a pure-org executor (no `owner:"user"`). */
    readonly subject?: Subject;
    readonly db?: ExecutorDbInput | ExecutorDbFactory;
    /**
     * Backend for the plugin blob seam (`StorageDeps.blobs`). Defaults to the
     * FumaDB `blob` table over `db`. Hosts with an object store hand one in
     * (e.g. the R2 store in `@executor-js/cloudflare/blob-store`) so multi-MB
     * values stay out of the relational tier.
     */
    readonly blobs?: BlobStore;
    readonly plugins?: TPlugins;
    /** Config-level credential providers, merged with every
     *  `plugin.credentialProviders`. Config providers register first, so the
     *  default (first writable) store is selected from them when present. */
    readonly providers?: readonly CredentialProvider[];
    /**
     * How to respond when a tool requests user input mid-invocation. Pass
     * `"accept-all"` for tests / non-interactive hosts, or a handler.
     */
    readonly onElicitation: OnElicitation;
    readonly httpClientLayer?: Layer.Layer<HttpClient.HttpClient>;
    /**
     * The OAuth callback URL (`${webBaseUrl}/oauth/callback`) the host serves and
     * sends to providers. There is NO localhost default: omit it (or pass
     * undefined) only for executors that never run interactive OAuth — the
     * redirect-requiring flows then fail loudly instead of guessing a callback.
     * Hosts serving OAuth derive this from the request origin / web base URL.
     */
    readonly redirectUri?: string;
    readonly oauthEndpointUrlPolicy?: OAuthEndpointUrlPolicy;
    /**
     * Enable the built-in `core-tools` plugin which contributes agent-facing
     * static tools over the v2 surface (integrations / connections / policies).
     */
    readonly coreTools?: {
        readonly webBaseUrl?: string;
        readonly includeProviders?: boolean;
    };
}
export declare const collectTables: () => FumaTables;
export declare const createExecutor: <const TPlugins extends readonly AnyPlugin[] = readonly []>(config: ExecutorConfig<TPlugins>) => Effect.Effect<Executor<TPlugins>, StorageFailure>;
//# sourceMappingURL=executor.d.ts.map