import type { DipclawConfig } from "../config/types.js";
import type { ContentBlock } from "../llm/types.js";
import { type SyncOmniFlowSessionDeps } from "../center/session-sync.js";
import type { SessionBlob } from "dp-shared";
export type { AttachmentSendPayload, AttachmentSender, ProgressNotifier, FrontendId, } from "./agent-types.js";
export { NoChatContext } from "./agent-types.js";
import type { AttachmentSender, ProgressNotifier, FrontendId } from "./agent-types.js";
type ChatInput = string | ContentBlock[];
export declare class Agent {
    private config;
    private llmClient;
    private browser;
    private browserActions;
    private taskRunner;
    private scheduler;
    private memory;
    private store;
    private skillGenerator;
    private imageGenerator;
    private tui;
    private telegramBot;
    private orgManager;
    private chatEngine;
    private browserLock;
    private chromeWatchdog;
    /** Per-session chat logger. Lazy-created on first chat turn, reset on clearChat. */
    private chatLogger;
    private attachmentSenders;
    private progressNotifiers;
    constructor(config: DipclawConfig);
    start(opts?: {
        skipScheduler?: boolean;
    }): Promise<void>;
    /**
     * Run a center-dispatched prompt against this worker under the BrowserLock.
     *
     * The contract matches the M3 "single worker end-to-end" path in
     * docs/architecture.md: center writes a task_run row + dispatches a
     * `task_dispatch` message; the worker frontend (center-frontend.ts) calls
     * this method and is responsible for emitting `task_event` messages
     * (`dispatched_ack` immediately on receipt, `finished` when the
     * promise here resolves with the outcome).
     *
     * Why this lives on Agent and not on center-frontend: BrowserLock is owned
     * by Agent, and so is the per-turn logger wiring. Keeping the lock
     * acquisition here means center-frontend stays a pure adapter.
     */
    enqueueTaskFromCenter(taskRunId: string, prompt: string, opts?: {
        signal?: AbortSignal;
    }): Promise<{
        status: "success" | "failed" | "cancelled";
        result?: string;
        error?: string;
    }>;
    /**
     * Pull a center-published OmniFlow session export into the local workspace.
     * Acquires the BrowserLock so the swap can't race a chat turn / task,
     * closes Chrome, updates the local session JSON only when the content hash
     * changed, and launches Chrome again so the bundled extension imports it.
     */
    swapSession(blob: SessionBlob, deps?: Partial<SyncOmniFlowSessionDeps>): Promise<void>;
    /**
     * Public read of BrowserLock state — true when a task or chat turn is
     * currently using the browser (or queued ahead of us). Frontends
     * (center-frontend, Telegram bot) use this to surface "worker busy, queued"
     * to the user without taking the lock themselves.
     */
    isBusy(): boolean;
    /**
     * 启动员工的组织任务轮询机制。
     * 此方法会在后台每隔 10 秒扫描一次该员工的“私有信箱”(inbox)。
     * 如果发现有老板派发的新任务，将按顺序逐一执行。
     */
    private startOrgTaskPolling;
    /**
     * 处理单一的组织指派任务。
     * 任务状态流转：pending -> running -> completed/failed
     */
    private handleOrgTask;
    stop(): Promise<void>;
    getName(): string;
    getWorkspace(): string;
    /**
     * Register a frontend's delivery callbacks under a stable id (e.g.
     * "telegram", "center"). Multiple frontends can be registered simultaneously;
     * the Agent dispatches each tool call through every registered callback in
     * insertion order, and the first one that doesn't throw NoChatContext
     * handles it. Frontends should scope their callbacks to their own
     * AsyncLocalStorage and throw NoChatContext when the store is empty, so
     * the dispatcher can find the frontend whose chat handler is on the stack.
     */
    registerFrontend(id: FrontendId, hooks: {
        sender?: AttachmentSender;
        notifier?: ProgressNotifier;
    }): void;
    /** Drop both the sender and notifier registered under `id`, if any. */
    unregisterFrontend(id: FrontendId): void;
    /**
     * @deprecated Use `registerFrontend("legacy", { sender })`.
     *
     * Single-slot legacy API. Pass `null` to clear the legacy slot only —
     * does not touch other registered frontends.
     */
    setAttachmentSender(sender: AttachmentSender | null): void;
    /** @deprecated Use `registerFrontend("legacy", { notifier })`. */
    setProgressNotifier(notifier: ProgressNotifier | null): void;
    /**
     * Clear chat history and start a new session.
     *
     * Queues on the browser lock so it runs AFTER any in-flight chat turn. This
     * guarantees the turn's finally block writes `chat_turn_end` before we emit
     * `chat_session_end`, and prevents the old turn from pushing messages into
     * the cleared chatHistory.
     */
    clearChat(): Promise<void>;
    /** Lazily create a per-session chat logger. One jsonl per chat session. */
    private ensureChatLogger;
    /** Chat with the agent (LLM-driven, with tool use) */
    chat(message: ChatInput): Promise<string>;
    /** Chat with streaming — yields text deltas, handles tool calls internally */
    chatStream(message: ChatInput): AsyncIterable<string>;
    listTasks(): string;
    addTask(name: string, cron: string, prompt: string, timezone?: string): string;
    removeTask(id: string): string;
    toggleTask(id: string, enabled: boolean): string;
    updateTask(id: string, patch: {
        name?: string;
        cron?: string;
        prompt?: string;
        timezone?: string;
        enabled?: boolean;
        storagePolicyMode?: "auto" | "off";
    }): string;
    runTaskById(id: string): Promise<string>;
    listSkills(): string;
    generateSkill(logFileName: string): Promise<string>;
    listMemories(): string;
    private runScheduledTaskWithWatchdog;
    private resetTabsOrRestart;
    private restartBrowser;
    /**
     * Idle-close path: tear Chrome down but keep workspace ownership so the
     * next browser action relaunches in-place. Caller (watchdog) holds the
     * browser lock.
     */
    private closeBrowserIdle;
    private isBrowserLockIdle;
    private tryAcquireBrowserLock;
    /**
     * Acquire a serialized lock for browser access.
     * All operations that may use the browser (chat, scheduled tasks) must go through this
     * to prevent concurrent browser manipulation.
     */
    private acquireBrowserLock;
}
