import { StreamHelper } from "../stream/stream-helpers.js";
import { MidGenerationCompressor } from "../compression/MidGenerationCompressor.js";
import { ContextResolver } from "../context/ContextResolver.js";
import "../context/index.js";
import { ImageDetail } from "../types/chat.js";
import { SandboxConfig } from "../types/executionContext.js";
import { SkillData } from "./types.js";
import { SystemPromptBuilder } from "./SystemPromptBuilder.js";
import { AgentMcpManager } from "./services/AgentMcpManager.js";
import { AgentConversationHistoryConfig, Artifact, ArtifactComponentApiInsert, CredentialStoreRegistry, CredentialStuffer, DataComponentApiInsert, FullExecutionContext, McpTool, MessageContent, Models, ResolvedRef, SubAgentStopWhen } from "@inkeep/agents-core";
import { FinishReason, StepResult, ToolSet } from "ai";

//#region src/domains/run/agents/agent-types.d.ts
type AiSdkTextPart = {
  type: 'text';
  text: string;
};
type AiSdkImagePart = {
  type: 'image';
  image: string | URL;
  experimental_providerMetadata?: {
    openai?: {
      imageDetail?: ImageDetail;
    };
  };
};
type AiSdkFilePart = {
  type: 'file';
  data: string | URL;
  mediaType: string;
  filename?: string;
};
type AiSdkContentPart = AiSdkTextPart | AiSdkImagePart | AiSdkFilePart;
/**
 * 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;
  usage?: {
    promptTokens?: number;
    completionTokens?: number;
    inputTokens?: number;
    outputTokens?: number;
    totalTokens?: number;
  };
  totalUsage?: {
    promptTokens?: number;
    completionTokens?: number;
    inputTokens?: number;
    outputTokens?: number;
    totalTokens?: number;
  };
  response?: {
    modelId?: string;
  };
}
/**
 * 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>;
declare function validateModel(modelString: string | undefined, modelType: string): string;
type AgentConfig = {
  id: string;
  tenantId: string;
  projectId: string;
  agentId: string;
  agentName?: 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[];
  skills?: SkillData[];
  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 function isValidTool(tool: unknown): tool is {
  description: string;
  inputSchema: NonNullable<ToolSet[string]['inputSchema']>;
  execute: (args: unknown, context?: unknown) => Promise<unknown>;
};
type AiSdkToolDefinition = {
  id?: string;
  description?: string;
  inputSchema?: unknown;
  parameters?: {
    safeParse?: (args: unknown) => {
      success: true;
      error?: never;
    } | {
      success: false;
      error: {
        message: string;
      };
    };
  };
  execute?: (args: unknown, context?: unknown) => Promise<unknown>;
};
interface AgentRunContext {
  config: AgentConfig;
  executionContext: FullExecutionContext;
  mcpManager: AgentMcpManager | undefined;
  contextResolver?: ContextResolver;
  credentialStoreRegistry?: CredentialStoreRegistry;
  credentialStuffer?: CredentialStuffer;
  systemPromptBuilder: SystemPromptBuilder<any>;
  streamHelper?: StreamHelper;
  streamRequestId?: string;
  conversationId?: string;
  delegationId?: string;
  isDelegatedAgent: boolean;
  artifactComponents: ArtifactComponentApiInsert[];
  currentCompressor: MidGenerationCompressor | null;
  functionToolRelationshipIdByName: Map<string, string>;
  taskDenialRedirects: Array<{
    toolName: string;
    toolCallId: string;
    reason: string;
  }>;
  durableWorkflowRunId?: string;
  approvedToolCalls?: Record<string, Array<{
    approved: boolean;
    reason?: string;
    originalToolCallId?: string;
  }>>;
  pendingDurableApproval?: {
    toolCallId: string;
    toolName: string;
    args: unknown;
  };
}
//#endregion
export { AgentConfig, AgentRunContext, AiSdkContentPart, AiSdkFilePart, AiSdkImagePart, AiSdkTextPart, AiSdkToolDefinition, DelegateRelation, ExternalAgentRelationConfig, ResolvedGenerationResponse, TeamAgentRelationConfig, ToolType, hasToolCallWithPrefix, isValidTool, resolveGenerationResponse, validateModel };