import { EMPTY_TOKEN_USAGE } from '../constants/limits.js';
import { ZERO_COST } from '../utils/cost.js';
import { toErrorMessage } from '../utils/error.js';
import { generateRunId } from '../utils/id.js';
import { getRootLogger } from '../utils/logger.js';
import { InvocationLock } from './lock.js';
export class AbstractAgent {
    metadata;
    log;
    abortController;
    invocationLock;
    agentManager;
    currentRunId;
    constructor(metadata) {
        this.metadata = metadata;
        this.abortController = new AbortController();
        this.invocationLock = new InvocationLock();
        this.log = getRootLogger().child({
            component: `Agent:${metadata.type}`,
            agentId: metadata.id,
        });
    }
    /**
     * Acquire the invocation lock to prevent concurrent execution.
     * Returns a Disposable that must be disposed to release the lock.
     *
     * Usage:
     * ```typescript
     * const lock = this.acquireInvocationLock()
     * try {
     *   // do work
     * } finally {
     *   lock[Symbol.dispose]()
     * }
     * ```
     *
     * @throws {ConcurrentInvocationError} if the agent is already executing
     */
    acquireInvocationLock() {
        return this.invocationLock.acquire(this.metadata.id);
    }
    async cancel() {
        this.abortController.abort();
        if (this.agentManager && this.currentRunId) {
            this.agentManager.cancelAll(this.currentRunId);
        }
    }
    getCapabilities() {
        return this.metadata.capabilities;
    }
    createRunId() {
        return generateRunId();
    }
    createEmptyResult(runId, startTime) {
        return {
            runId,
            status: 'idle',
            usage: { ...EMPTY_TOKEN_USAGE },
            cost: { ...ZERO_COST },
            iterations: 0,
            durationMs: Date.now() - startTime,
            messages: [],
        };
    }
    async emitEvent(event, listener) {
        if (!listener)
            return;
        try {
            await listener(event);
        }
        catch (err) {
            this.log.error('Event listener error', {
                error: toErrorMessage(err),
            });
        }
    }
}
//# sourceMappingURL=AbstractAgent.js.map