import { SandboxConfig } from "../types/executionContext.js";
import { StreamHelper } from "../utils/stream-helpers.js";
import { AgentConversationHistoryConfig, Artifact, ArtifactComponentApiInsert, CredentialStoreRegistry, DataComponentApiInsert, FullExecutionContext, McpTool, MessageContent, Models, ResolvedRef, SubAgentStopWhen } from "@inkeep/agents-core";
import { FinishReason, StepResult, ToolSet } from "ai";

//#region src/domains/run/agents/Agent.d.ts

/**
 * Creates a stopWhen condition that stops when any tool call name starts with the given prefix
 * @param prefix - The prefix to check for in tool call names
 * @returns A function that can be used as a stopWhen condition
 */
declare function hasToolCallWithPrefix(prefix: string): ({
  steps
}: {
  steps: Array<any>;
}) => any;
/**
 * Shape of a generation response after all Promise-based getters have been resolved.
 *
 * The AI SDK's `GenerateTextResult` and `StreamTextResult` classes expose properties
 * like `text`, `steps`, `finishReason`, and `output` as **prototype getters** — not
 * own enumerable properties. When one of these class instances is spread with `{ ...result }`,
 * the spread operator copies only own enumerable properties and silently drops the getters,
 * causing those fields to become `undefined` on the resulting plain object.
 *
 * This type represents the safely-resolved plain object produced by
 * `resolveGenerationResponse`, where every needed getter has been awaited and
 * assigned as a concrete own property.
 */
interface ResolvedGenerationResponse {
  steps: Array<StepResult<ToolSet>>;
  text: string;
  finishReason: FinishReason;
  output?: any;
  object?: any;
  formattedContent?: MessageContent | null;
}
/**
 * Resolves a generation response from either `generateText` or `streamText` into
 * a plain object with all needed values as own properties.
 *
 * **Why this exists:** The AI SDK returns class instances whose key properties
 * (`text`, `steps`, `finishReason`, `output`) are prototype getters.
 * `StreamTextResult` getters return `PromiseLike` values; `GenerateTextResult`
 * getters return direct values. In both cases, the spread operator `{ ...result }`
 * silently drops them. This function uses `Promise.resolve()` to safely resolve
 * both styles, then spreads them as explicit own properties so downstream code
 * (and further spreads) never loses them.
 */
declare function resolveGenerationResponse(response: Record<string, unknown>): Promise<ResolvedGenerationResponse>;
type AgentConfig = {
  id: string;
  tenantId: string;
  projectId: string;
  agentId: string;
  relationId?: string;
  baseUrl: string;
  apiKey?: string;
  apiKeyId?: string;
  name: string;
  description?: string;
  prompt?: string;
  subAgentRelations: AgentConfig[];
  transferRelations: AgentConfig[];
  delegateRelations: DelegateRelation[];
  tools?: McpTool[];
  artifacts?: Record<string, Artifact>;
  functionTools?: Array<{
    name: string;
    description: string;
    execute: (params: any) => Promise<any>;
    parameters?: Record<string, any>;
    schema?: any;
  }>;
  contextConfigId?: string;
  dataComponents?: DataComponentApiInsert[];
  artifactComponents?: ArtifactComponentApiInsert[];
  conversationHistoryConfig?: AgentConversationHistoryConfig;
  models?: Models;
  stopWhen?: SubAgentStopWhen;
  sandboxConfig?: SandboxConfig;
  /** User ID for user-scoped credential lookup (from temp JWT) */
  userId?: string;
  /** Headers to forward to MCP servers (e.g., x-forwarded-cookie for user session auth) */
  forwardedHeaders?: Record<string, string>;
};
type ExternalAgentRelationConfig = {
  relationId: string;
  id: string;
  name: string;
  description: string;
  ref: ResolvedRef;
  baseUrl: string;
  credentialReferenceId?: string | null;
  headers?: Record<string, string> | null;
  relationType: string;
};
type TeamAgentRelationConfig = {
  relationId: string;
  id: string;
  ref: ResolvedRef;
  name: string;
  description: string;
  baseUrl: string;
  headers?: Record<string, string> | null;
};
type DelegateRelation = {
  type: 'internal';
  config: AgentConfig;
} | {
  type: 'external';
  config: ExternalAgentRelationConfig;
} | {
  type: 'team';
  config: TeamAgentRelationConfig;
};
type ToolType = 'transfer' | 'delegation' | 'mcp' | 'tool';
declare class Agent {
  #private;
  private config;
  private systemPromptBuilder;
  private credentialStuffer?;
  private streamHelper?;
  private streamRequestId?;
  private conversationId?;
  private delegationId?;
  private artifactComponents;
  private isDelegatedAgent;
  private contextResolver?;
  private credentialStoreRegistry?;
  private mcpClientCache;
  private mcpConnectionLocks;
  private currentCompressor;
  private executionContext;
  private functionToolRelationshipIdByName;
  constructor(config: AgentConfig, executionContext: FullExecutionContext, credentialStoreRegistry?: CredentialStoreRegistry);
  /**
   * Get the maximum number of generation steps for this agent
   * Uses agent's stopWhen.stepCountIs config or defaults to AGENT_EXECUTION_MAX_GENERATION_STEPS
   */
  private getMaxGenerationSteps;
  /**
   * Sanitizes tool names at runtime for AI SDK compatibility.
   * The AI SDK requires tool names to match pattern ^[a-zA-Z0-9_-]{1,128}$
   */
  private sanitizeToolsForAISDK;
  /**
   * Get the primary model settings for text generation
   * Requires model to be configured at project level
   */
  private getPrimaryModel;
  /**
   * Get the model settings for structured output generation
   * Falls back to base model if structured output not configured
   */
  private getStructuredOutputModel;
  /**
   * Get the model settings for summarization/distillation
   * Falls back to base model if summarizer not configured
   */
  private getSummarizerModel;
  setConversationId(conversationId: string): void;
  /**
   * Simple compression fallback: drop oldest messages to fit under token limit
   */
  /**
   * Set delegation status for this agent instance
   */
  setDelegationStatus(isDelegated: boolean): void;
  /**
   * Set delegation ID for this agent instance
   */
  setDelegationId(delegationId: string | undefined): void;
  /**
   * Get streaming helper if this agent should stream to user
   * Returns undefined for delegated agents to prevent streaming data operations to user
   */
  getStreamingHelper(): StreamHelper | undefined;
  /**
   * Wraps a tool with streaming lifecycle tracking (start, complete, error) and AgentSession recording
   */
  private wrapToolWithStreaming;
  getRelationTools(runtimeContext?: {
    contextId: string;
    metadata: {
      conversationId: string;
      threadId: string;
      streamRequestId?: string;
      streamBaseUrl?: string;
      apiKey?: string;
      baseUrl?: string;
    };
  }, sessionId?: string): any;
  getMcpTools(sessionId?: string, streamRequestId?: string): Promise<ToolSet>;
  /**
   * Convert database McpTool to builder MCPToolConfig format
   */
  private convertToMCPToolConfig;
  getMcpTool(tool: McpTool): Promise<{
    tools: any;
    toolPolicies: Record<string, {
      needsApproval?: boolean | undefined;
    }>;
    mcpServerId: string;
    mcpServerName: string;
  }>;
  private createMcpConnection;
  getFunctionTools(sessionId?: string, streamRequestId?: string): Promise<ToolSet>;
  /**
   * Get resolved context using ContextResolver - will return cached data or fetch fresh data as needed
   */
  getResolvedContext(conversationId: string, headers?: Record<string, unknown>): Promise<Record<string, unknown> | null>;
  /**
   * Get the agent prompt for this agent's agent
   */
  private getPrompt;
  /**
   * Check if any agent in the agent has artifact components configured
   */
  private hasAgentArtifactComponents;
  /**
   * Get the client's current time formatted in their timezone
   */
  private getClientCurrentTime;
  private buildSystemPrompt;
  private getArtifactTools;
  private getDefaultTools;
  private getStreamRequestId;
  private applyToolOverrides;
  /**
   * Format tool result for storage in conversation history
   */
  private formatToolResult;
  /**
   * Get the conversation ID for storing tool results
   * Always uses the real conversation ID - delegation filtering happens at query time
   */
  private getToolResultConversationId;
  /**
   * Analyze tool result structure and add helpful path hints for artifact creation
   * Only adds hints when artifact components are available
   */
  private enhanceToolResultWithStructureHints;
  private agentHasArtifactComponents;
  generate(userMessage: string, runtimeContext?: {
    contextId: string;
    metadata: {
      conversationId: string;
      threadId: string;
      taskId: string;
      streamRequestId: string;
      apiKey?: string;
    };
  }): Promise<ResolvedGenerationResponse>;
  /**
   * Setup generation context and initialize streaming helper
   */
  private setupGenerationContext;
  /**
   * Load all tools and system prompts in parallel, then combine and sanitize them
   */
  private loadToolsAndPrompts;
  /**
   * Build conversation history based on configuration mode and filters
   */
  private buildConversationHistory;
  /**
   * Configure model settings, timeouts, and streaming behavior
   */
  private configureModelSettings;
  /**
   * Build initial messages array with system prompt and user content
   */
  private buildInitialMessages;
  /**
   * Setup compression for the current generation
   */
  private setupCompression;
  /**
   * Prepare step function for streaming with compression logic
   */
  private handlePrepareStepCompression;
  private handleStopWhenConditions;
  private setupStreamParser;
  private buildTelemetryConfig;
  private buildBaseGenerationConfig;
  private buildDataComponentsSchema;
  private formatFinalResponse;
  private handleGenerationError;
  /**
   * Public cleanup method for external lifecycle management (e.g., session cleanup)
   * Performs full cleanup of compression state when agent/session is ending
   */
  cleanupCompression(): void;
  private handleStreamGeneration;
  private processStreamEvents;
}
//#endregion
export { Agent, AgentConfig, DelegateRelation, ExternalAgentRelationConfig, ResolvedGenerationResponse, TeamAgentRelationConfig, ToolType, hasToolCallWithPrefix, resolveGenerationResponse };