import { MessageContent, CacheControl, LLMPort, LLMPriority } from '@llm-ports/core'; import { z } from 'zod'; /** * Shared utilities used by every capability factory. * * These helpers handle: * - dynamic prompt fragment resolution (string-or-function fields) * - safe hook invocation (errors in user hooks must not crash the call) * - common system prompt assembly */ /** * A prompt fragment may be a literal string OR a function that returns one. * Functions can be sync or async; capabilities resolve them lazily so users * can plug in DB lookups, feature flags, or context-derived content. */ type Resolvable = TOutput | ((input: TInput) => TOutput | Promise); interface CapabilityEvent { /** Human-readable capability name, e.g. "classify". */ capability: string; /** Schema/operation name as configured by the user. */ schemaName: string; /** Model id reported by the adapter. */ modelId: string; /** Provider alias used. */ providerAlias: string; /** Token usage and USD cost. */ usage: { inputTokens: number; outputTokens: number; totalTokens: number; }; /** * USD cost. `cacheSavingsUSD` is populated when the provider returned cache * telemetry on this call (so the consumer can attribute savings per-capability). * (alpha.19.1+) */ cost: { inputUSD: number; outputUSD: number; totalUSD: number; cacheSavingsUSD?: number; }; latencyMs: number; /** The validated output the capability returned. */ output: TOutput; /** Number of attempts (>1 if retry-with-feedback fired). */ validationAttempts?: number; } /** * createClassifier — pick one of N categories from input content. * * Returns a typed function that, given input content, returns a parsed * Zod-validated object (typically including the chosen category plus a * reasoning field). Configure once at app startup; call many times. */ interface ClassifyInput { content: MessageContent; /** Per-call context override; appended to systemContext. */ contextOverride?: string; /** Cancellation signal for this specific call. Threaded to the port. (alpha.13+) */ signal?: AbortSignal; /** Override task routing for this call only. (alpha.13+) */ forceProviderAlias?: string; /** Per-call escape hatch for provider-specific request fields (vLLM chat_template_kwargs, SGLang regex, etc.). Threaded to the underlying port call. (alpha.16+) */ providerExtras?: Record; /** Per-call prompt cache configuration. Forwarded to the underlying port call. (alpha.19.1+) */ cacheControl?: CacheControl; /** * Per-call override for strict-schema response_format mode. (alpha.21+) * Forwarded to the underlying port call. See `GenerateStructuredOptions.strict`. */ strict?: boolean; } interface CreateClassifierConfig { /** The LLM port. Typically `registry.getPort()`. */ port: LLMPort; /** The Zod schema the model's output must conform to. */ schema: TSchema; /** Operation name used in logs and the model prompt. */ schemaName: string; /** Optional rules text that defines the categories. */ rubric?: Resolvable; /** Optional boundary examples ("X is intent A; Y is intent B"). */ boundaryExamples?: Resolvable; /** Optional extra context (per-input) the model should consider. */ systemContext?: Resolvable; /** Task type for routing. Default: "classify". */ taskType?: string; priority?: LLMPriority; /** Default 0 (deterministic). */ temperature?: number; maxOutputTokens?: number; /** * Reasoning effort hint for o-series / gpt-5-nano / Groq gpt-oss-120b. * Applies to every call from this classifier. (alpha.13+) */ reasoningEffort?: "low" | "medium" | "high"; /** Hooks. Errors in hooks are caught and logged, never re-thrown. */ onBeforeCall?: (input: ClassifyInput) => void | Promise; onResult?: (event: CapabilityEvent>) => void | Promise; onError?: (error: Error, input: ClassifyInput) => void | Promise; } /** * Create a configured classifier function. * * @example * const classify = createClassifier({ * port: llm, * schema: z.object({ * intent: z.enum(["question", "request", "complaint"]), * reasoning: z.string(), * }), * schemaName: "user-intent", * rubric: "question: asking for info\nrequest: wants action\ncomplaint: reports problem", * }); * * const result = await classify({ content: "Can I get a refund?" }); * // { intent: "request", reasoning: "..." } */ declare function createClassifier(config: CreateClassifierConfig): (input: ClassifyInput) => Promise>; /** * createScorer — rate input against a rubric. Schema typically includes a * numerical score plus reasoning. */ interface ScoreInput { content: MessageContent; contextOverride?: string; /** Cancellation signal for this specific call. Threaded to the port. (alpha.13+) */ signal?: AbortSignal; /** Override task routing for this call only. (alpha.13+) */ forceProviderAlias?: string; /** Per-call escape hatch for provider-specific request fields (vLLM chat_template_kwargs, SGLang regex, etc.). Threaded to the underlying port call. (alpha.16+) */ providerExtras?: Record; /** Per-call prompt cache configuration. Forwarded to the underlying port call. (alpha.19.1+) */ cacheControl?: CacheControl; /** * Per-call override for strict-schema response_format mode. (alpha.21+) * Forwarded to the underlying port call. See `GenerateStructuredOptions.strict`. */ strict?: boolean; } interface CreateScorerConfig { port: LLMPort; schema: TSchema; schemaName: string; /** Required: the scoring rubric (what determines a high vs low score). */ rubric: Resolvable; /** Optional examples of low/medium/high scored items. */ examples?: Resolvable; systemContext?: Resolvable; taskType?: string; priority?: LLMPriority; /** Default 0.1 — slight randomness helps surface borderline cases consistently. */ temperature?: number; maxOutputTokens?: number; /** * Reasoning effort hint for o-series / gpt-5-nano / Groq gpt-oss-120b. * Applies to every call from this scorer. (alpha.13+) */ reasoningEffort?: "low" | "medium" | "high"; onBeforeCall?: (input: ScoreInput) => void | Promise; onResult?: (event: CapabilityEvent>) => void | Promise; onError?: (error: Error, input: ScoreInput) => void | Promise; } declare function createScorer(config: CreateScorerConfig): (input: ScoreInput) => Promise>; /** * createExtractor — pull structured fields from unstructured input. * * Returns Zod-validated typed data. Useful for: parsing emails for action * items, extracting contact info from text, structured data from documents. */ interface ExtractInput { content: MessageContent; contextOverride?: string; /** Cancellation signal for this specific call. Threaded to the port. (alpha.13+) */ signal?: AbortSignal; /** Override task routing for this call only. (alpha.13+) */ forceProviderAlias?: string; /** Per-call escape hatch for provider-specific request fields (vLLM chat_template_kwargs, SGLang regex, etc.). Threaded to the underlying port call. (alpha.16+) */ providerExtras?: Record; /** Per-call prompt cache configuration. Forwarded to the underlying port call. (alpha.19.1+) */ cacheControl?: CacheControl; /** * Per-call override for strict-schema response_format mode. (alpha.21+) * Forwarded to the underlying port call. See `GenerateStructuredOptions.strict`. */ strict?: boolean; } interface CreateExtractorConfig { port: LLMPort; schema: TSchema; schemaName: string; /** What to extract (instructions describing each field). */ fieldGuide?: Resolvable; /** Examples of input -> extracted output. */ examples?: Resolvable; systemContext?: Resolvable; taskType?: string; priority?: LLMPriority; /** Default 0 (deterministic). */ temperature?: number; maxOutputTokens?: number; /** * Reasoning effort hint for o-series / gpt-5-nano / Groq gpt-oss-120b. * Applies to every call from this extractor. (alpha.13+) */ reasoningEffort?: "low" | "medium" | "high"; onBeforeCall?: (input: ExtractInput) => void | Promise; onResult?: (event: CapabilityEvent>) => void | Promise; onError?: (error: Error, input: ExtractInput) => void | Promise; } declare function createExtractor(config: CreateExtractorConfig): (input: ExtractInput) => Promise>; /** * createSummarizer — compress input text while preserving the key meaning. * * Returns plain text. For structured summaries (e.g. bullet points + an * explicit list of action items), use createExtractor with a schema instead. */ interface SummarizeInput { content: MessageContent; contextOverride?: string; /** Cancellation signal for this specific call. Threaded to the port. (alpha.13+) */ signal?: AbortSignal; /** Override task routing for this call only. (alpha.13+) */ forceProviderAlias?: string; /** Per-call escape hatch for provider-specific request fields (vLLM chat_template_kwargs, SGLang regex, etc.). Threaded to the underlying port call. (alpha.16+) */ providerExtras?: Record; /** Per-call prompt cache configuration. Forwarded to the underlying port call. (alpha.19.1+) */ cacheControl?: CacheControl; } interface CreateSummarizerConfig { port: LLMPort; /** Operation name used in logs. Default: "summarize". */ schemaName?: string; /** Optional persona / focus instructions. */ persona?: Resolvable; /** Optional output style guide (e.g. "3-5 bullets, active voice"). */ styleGuide?: Resolvable; systemContext?: Resolvable; /** Approximate target length in words. */ targetWords?: number; taskType?: string; priority?: LLMPriority; /** Default 0.2. */ temperature?: number; maxOutputTokens?: number; /** * Reasoning effort hint for o-series / gpt-5-nano / Groq gpt-oss-120b. * Applies to every call from this summarizer. (alpha.13+) */ reasoningEffort?: "low" | "medium" | "high"; onBeforeCall?: (input: SummarizeInput) => void | Promise; onResult?: (event: CapabilityEvent) => void | Promise; onError?: (error: Error, input: SummarizeInput) => void | Promise; } declare function createSummarizer(config: CreateSummarizerConfig): (input: SummarizeInput) => Promise; /** * createDrafter — generate new text in a specific persona/style. * * Returns plain text. The persona is the most important configuration: it * tells the model who is "writing." Channel constraints (e.g. SMS = 160 * chars, email = 150-250 words) help the model size its output. */ interface DraftInput { /** Instruction for what to write (the user-facing intent). */ instructions: string; /** Optional thread/conversation history the draft is responding to. */ threadHistory?: MessageContent; /** Optional recipient context (e.g. CRM data, prior interactions). */ recipientContext?: string; contextOverride?: string; /** Cancellation signal for this specific call. Threaded to the port. (alpha.13+) */ signal?: AbortSignal; /** Override task routing for this call only. (alpha.13+) */ forceProviderAlias?: string; /** Per-call escape hatch for provider-specific request fields (vLLM chat_template_kwargs, SGLang regex, etc.). Threaded to the underlying port call. (alpha.16+) */ providerExtras?: Record; /** Per-call prompt cache configuration. Forwarded to the underlying port call. (alpha.19.1+) */ cacheControl?: CacheControl; } interface CreateDrafterConfig { port: LLMPort; /** Operation name used in logs. Default: "draft". */ schemaName?: string; /** REQUIRED. The persona/voice the draft should adopt. Often a tone profile. */ persona: Resolvable; /** Optional channel constraint (e.g. SMS, email, LinkedIn DM). */ channelConstraint?: Resolvable; /** Optional anti-pattern blacklist (phrases to avoid). */ antiPatterns?: Resolvable; /** Optional examples of correctly-styled drafts. */ writingSamples?: Resolvable; systemContext?: Resolvable; taskType?: string; priority?: LLMPriority; /** Default 0.4 (creative but controlled). */ temperature?: number; /** Hard character cap; truncates output if exceeded. */ maxLength?: number; maxOutputTokens?: number; /** * Reasoning effort hint for o-series / gpt-5-nano / Groq gpt-oss-120b. * Applies to every call from this drafter. (alpha.13+) */ reasoningEffort?: "low" | "medium" | "high"; onBeforeCall?: (input: DraftInput) => void | Promise; onResult?: (event: CapabilityEvent) => void | Promise; onError?: (error: Error, input: DraftInput) => void | Promise; } declare function createDrafter(config: CreateDrafterConfig): (input: DraftInput) => Promise; /** * createPlanner — decompose a goal into ordered or DAG-shaped steps. * * Returns Zod-validated structured output. The user supplies the schema * for what a "step" looks like (typically id + description + dependencies). */ interface PlanInput { goal: MessageContent; contextOverride?: string; /** Cancellation signal for this specific call. Threaded to the port. (alpha.13+) */ signal?: AbortSignal; /** Override task routing for this call only. (alpha.13+) */ forceProviderAlias?: string; /** Per-call escape hatch for provider-specific request fields (vLLM chat_template_kwargs, SGLang regex, etc.). Threaded to the underlying port call. (alpha.16+) */ providerExtras?: Record; /** Per-call prompt cache configuration. Forwarded to the underlying port call. (alpha.19.1+) */ cacheControl?: CacheControl; /** * Per-call override for strict-schema response_format mode. (alpha.21+) * Forwarded to the underlying port call. See `GenerateStructuredOptions.strict`. */ strict?: boolean; } interface CreatePlannerConfig { port: LLMPort; schema: TSchema; schemaName: string; /** Optional planning approach (e.g. "depth-first; minimize dependencies"). */ strategy?: Resolvable; /** Available tools / capabilities the plan may reference. */ toolCatalog?: Resolvable; /** Examples of well-formed plans for similar goals. */ examples?: Resolvable; systemContext?: Resolvable; taskType?: string; priority?: LLMPriority; /** Default 0.2. */ temperature?: number; maxOutputTokens?: number; /** * Reasoning effort hint for o-series / gpt-5-nano / Groq gpt-oss-120b. * Applies to every call from this planner. (alpha.13+) */ reasoningEffort?: "low" | "medium" | "high"; onBeforeCall?: (input: PlanInput) => void | Promise; onResult?: (event: CapabilityEvent>) => void | Promise; onError?: (error: Error, input: PlanInput) => void | Promise; } declare function createPlanner(config: CreatePlannerConfig): (input: PlanInput) => Promise>; /** * createAnalyzer — evaluate, critique, or compare. Returns Zod-validated * structured output. Use when the user wants a "what do you think about * this?" answer with explicit reasoning and recommendations. */ interface AnalyzeInput { content: MessageContent; /** Optional explicit question; if omitted, the analyzer's framework drives the analysis. */ question?: string; contextOverride?: string; /** Cancellation signal for this specific call. Threaded to the port. (alpha.13+) */ signal?: AbortSignal; /** Override task routing for this call only. (alpha.13+) */ forceProviderAlias?: string; /** Per-call escape hatch for provider-specific request fields (vLLM chat_template_kwargs, SGLang regex, etc.). Threaded to the underlying port call. (alpha.16+) */ providerExtras?: Record; /** Per-call prompt cache configuration. Forwarded to the underlying port call. (alpha.19.1+) */ cacheControl?: CacheControl; /** * Per-call override for strict-schema response_format mode. (alpha.21+) * Forwarded to the underlying port call. See `GenerateStructuredOptions.strict`. */ strict?: boolean; } interface CreateAnalyzerConfig { port: LLMPort; schema: TSchema; schemaName: string; /** REQUIRED. The analytical framework (e.g. SWOT, pros/cons, root-cause). */ framework: Resolvable; /** Optional examples of well-structured analyses. */ examples?: Resolvable; systemContext?: Resolvable; taskType?: string; priority?: LLMPriority; /** Default 0.3 — analysis benefits from some perspective variety. */ temperature?: number; maxOutputTokens?: number; /** * Reasoning effort hint for o-series / gpt-5-nano / Groq gpt-oss-120b. * Applies to every call from this analyzer. (alpha.13+) */ reasoningEffort?: "low" | "medium" | "high"; onBeforeCall?: (input: AnalyzeInput) => void | Promise; onResult?: (event: CapabilityEvent>) => void | Promise; onError?: (error: Error, input: AnalyzeInput) => void | Promise; } declare function createAnalyzer(config: CreateAnalyzerConfig): (input: AnalyzeInput) => Promise>; export { type AnalyzeInput, type CapabilityEvent, type ClassifyInput, type CreateAnalyzerConfig, type CreateClassifierConfig, type CreateDrafterConfig, type CreateExtractorConfig, type CreatePlannerConfig, type CreateScorerConfig, type CreateSummarizerConfig, type DraftInput, type ExtractInput, type PlanInput, type Resolvable, type ScoreInput, type SummarizeInput, createAnalyzer, createClassifier, createDrafter, createExtractor, createPlanner, createScorer, createSummarizer };