llmist 2.5.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ZodType, ZodTypeAny } from 'zod';
2
2
  export { z } from 'zod';
3
- import { A as AgentHooks, s as ModelRegistry, I as IConversationManager, b as LLMMessage, t as MessageContent, S as StreamEvent, T as TokenUsage, G as GadgetRegistry, u as LLMist, a as LLMStreamChunk, C as CompactionStrategy, R as ResolvedCompactionConfig, v as CompactionContext, w as CompactionResult, x as CompactionConfig, y as CompactionEvent, z as CompactionStats, H as HintTemplate, E as ExecutionContext, D as GadgetExecuteReturn, F as GadgetExample, B as BaseGadget, P as ParsedGadgetCall, J as GadgetExecutionResult, K as ProviderAdapter, N as ModelDescriptor, O as ModelSpec, Q as LLMGenerationOptions, L as LLMStream, U as ImageModelSpec, V as ImageGenerationOptions, W as ImageGenerationResult, X as SpeechModelSpec, Y as SpeechGenerationOptions, Z as SpeechGenerationResult } from './mock-stream-ga4KIiwX.js';
4
- export { a6 as AfterGadgetExecutionAction, a7 as AfterGadgetExecutionControllerContext, a8 as AfterLLMCallAction, a9 as AfterLLMCallControllerContext, aa as AfterLLMErrorAction, a1 as AgentBuilder, ab as AgentOptions, az as AudioContentPart, aA as AudioMimeType, aB as AudioSource, ac as BeforeGadgetExecutionAction, ad as BeforeLLMCallAction, ae as ChunkInterceptorContext, aC as ContentPart, af as Controllers, b1 as CostEstimate, bl as CostReportingLLMist, aw as DEFAULT_COMPACTION_CONFIG, bb as DEFAULT_HINTS, bc as DEFAULT_PROMPTS, ax as DEFAULT_SUMMARIZATION_PROMPT, a2 as EventHandlers, bj as GadgetClass, bm as GadgetExecuteResult, ag as GadgetExecutionControllerContext, bk as GadgetOrClass, ah as GadgetParameterInterceptorContext, ai as GadgetResultInterceptorContext, bn as GadgetSkippedEvent, b7 as HintContext, _ as HistoryMessage, aD as ImageBase64Source, aE as ImageContentPart, aF as ImageMimeType, aG as ImageSource, aH as ImageUrlSource, aj as Interceptors, ak as LLMCallControllerContext, al as LLMErrorControllerContext, aZ as LLMMessageBuilder, aX as LLMRole, ay as LLMistOptions, am as MessageInterceptorContext, au as MessageTurn, d as MockBuilder, f as MockManager, l as MockMatcher, n as MockMatcherContext, o as MockOptions, M as MockProviderAdapter, p as MockRegistration, q as MockResponse, r as MockStats, b2 as ModelFeatures, b6 as ModelIdentifierParser, b3 as ModelLimits, b4 as ModelPricing, an as ObserveChunkContext, av as ObserveCompactionContext, ao as ObserveGadgetCompleteContext, ap as ObserveGadgetStartContext, aq as ObserveLLMCallContext, ar as ObserveLLMCompleteContext, as as ObserveLLMErrorContext, at as Observers, b8 as PromptConfig, b9 as PromptContext, ba as PromptTemplate, b5 as ProviderIdentifier, bg as QuickOptions, aI as TextContentPart, bo as TextOnlyAction, bp as TextOnlyContext, bq as TextOnlyCustomHandler, br as TextOnlyGadgetConfig, bs as TextOnlyHandler, bt as TextOnlyStrategy, $ as TrailingMessage, a0 as TrailingMessageContext, a$ as VisionAnalyzeOptions, b0 as VisionAnalyzeResult, aJ as audioFromBase64, aK as audioFromBuffer, a3 as collectEvents, a4 as collectText, bh as complete, c as createMockAdapter, e as createMockClient, h as createMockStream, i as createTextMockStream, aL as detectAudioMimeType, aM as detectImageMimeType, aY as extractText, g as getMockManager, aN as imageFromBase64, aO as imageFromBuffer, aP as imageFromUrl, aQ as isAudioPart, aR as isDataUrl, aS as isImagePart, aT as isTextPart, m as mockLLM, a_ as normalizeContent, aU as parseDataUrl, bd as resolveHintTemplate, be as resolvePromptTemplate, bf as resolveRulesTemplate, a5 as runWithHandlers, bi as stream, aV as text, aW as toBase64 } from './mock-stream-ga4KIiwX.js';
3
+ import { A as AgentHooks, s as ModelRegistry, t as LLMist, C as CompactionConfig, I as IConversationManager, u as CompactionEvent, L as LLMMessage, v as CompactionStats, w as CompactionStrategy, R as ResolvedCompactionConfig, x as CompactionContext, y as CompactionResult, z as MessageContent, G as GadgetMediaOutput, H as HintTemplate, S as StreamEvent, T as TokenUsage, D as GadgetRegistry, E as MediaStore, b as LLMStreamChunk, F as ExecutionContext, J as GadgetExecuteReturn, K as GadgetExample, B as BaseGadget, P as ParsedGadgetCall, N as GadgetExecutionResult, O as MediaKind, Q as MediaMetadata, U as GadgetExecuteResultWithMedia, V as ProviderAdapter, W as ModelDescriptor, X as ModelSpec, Y as LLMGenerationOptions, a as LLMStream, Z as ImageModelSpec, _ as ImageGenerationOptions, $ as ImageGenerationResult, a0 as SpeechModelSpec, a1 as SpeechGenerationOptions, a2 as SpeechGenerationResult } from './mock-stream-Jgg5u6Uf.js';
4
+ export { ab as AfterGadgetExecutionAction, ac as AfterGadgetExecutionControllerContext, ad as AfterLLMCallAction, ae as AfterLLMCallControllerContext, af as AfterLLMErrorAction, a6 as AgentBuilder, ag as AgentOptions, aE as AudioContentPart, aF as AudioMimeType, aG as AudioSource, ah as BeforeGadgetExecutionAction, ai as BeforeLLMCallAction, aj as ChunkInterceptorContext, aH as ContentPart, ak as Controllers, b4 as CostEstimate, bq as CostReportingLLMist, aB as DEFAULT_COMPACTION_CONFIG, bg as DEFAULT_HINTS, bh as DEFAULT_PROMPTS, aC as DEFAULT_SUMMARIZATION_PROMPT, a7 as EventHandlers, bo as GadgetClass, br as GadgetExecuteResult, al as GadgetExecutionControllerContext, bp as GadgetOrClass, am as GadgetParameterInterceptorContext, an as GadgetResultInterceptorContext, bs as GadgetSkippedEvent, bc as HintContext, a3 as HistoryMessage, aI as ImageBase64Source, aJ as ImageContentPart, aK as ImageMimeType, aL as ImageSource, aM as ImageUrlSource, ao as Interceptors, ap as LLMCallControllerContext, aq as LLMErrorControllerContext, b2 as LLMMessageBuilder, b0 as LLMRole, aD as LLMistOptions, ar as MessageInterceptorContext, as as MessageTurn, d as MockBuilder, f as MockManager, l as MockMatcher, n as MockMatcherContext, o as MockOptions, M as MockProviderAdapter, p as MockRegistration, q as MockResponse, r as MockStats, b5 as ModelFeatures, bb as ModelIdentifierParser, b6 as ModelLimits, b7 as ModelPricing, at as ObserveChunkContext, au as ObserveCompactionContext, av as ObserveGadgetCompleteContext, aw as ObserveGadgetStartContext, ax as ObserveLLMCallContext, ay as ObserveLLMCompleteContext, az as ObserveLLMErrorContext, aA as Observers, bd as PromptConfig, be as PromptContext, bf as PromptTemplate, ba as ProviderIdentifier, bl as QuickOptions, bt as StoredMedia, aN as TextContentPart, bu as TextOnlyAction, bv as TextOnlyContext, bw as TextOnlyCustomHandler, bx as TextOnlyGadgetConfig, by as TextOnlyHandler, bz as TextOnlyStrategy, a4 as TrailingMessage, a5 as TrailingMessageContext, b8 as VisionAnalyzeOptions, b9 as VisionAnalyzeResult, aO as audioFromBase64, aP as audioFromBuffer, a8 as collectEvents, a9 as collectText, bm as complete, c as createMockAdapter, e as createMockClient, h as createMockStream, i as createTextMockStream, aQ as detectAudioMimeType, aR as detectImageMimeType, b1 as extractText, g as getMockManager, aS as imageFromBase64, aT as imageFromBuffer, aU as imageFromUrl, aV as isAudioPart, aW as isDataUrl, aX as isImagePart, aY as isTextPart, m as mockLLM, b3 as normalizeContent, aZ as parseDataUrl, bi as resolveHintTemplate, bj as resolvePromptTemplate, bk as resolveRulesTemplate, aa as runWithHandlers, bn as stream, a_ as text, a$ as toBase64 } from './mock-stream-Jgg5u6Uf.js';
5
5
  import { Logger, ILogObj } from 'tslog';
6
6
  import { MessageCreateParamsStreaming, MessageStreamEvent } from '@anthropic-ai/sdk/resources/messages';
7
7
  import OpenAI from 'openai';
@@ -713,289 +713,93 @@ declare class HookPresets {
713
713
  }
714
714
 
715
715
  /**
716
- * ConversationManager handles conversation state and message building.
717
- * Extracted from AgentLoop to follow Single Responsibility Principle.
718
- */
719
-
720
- /**
721
- * Options for ConversationManager constructor.
722
- */
723
- interface ConversationManagerOptions {
724
- /** Custom gadget start marker prefix */
725
- startPrefix?: string;
726
- /** Custom gadget end marker prefix */
727
- endPrefix?: string;
728
- /** Custom argument prefix for block format */
729
- argPrefix?: string;
730
- }
731
- /**
732
- * Default implementation of IConversationManager.
733
- * Manages conversation history by building on top of base messages (system prompt, gadget instructions).
734
- */
735
- declare class ConversationManager implements IConversationManager {
736
- private readonly baseMessages;
737
- private readonly initialMessages;
738
- private historyBuilder;
739
- private readonly startPrefix?;
740
- private readonly endPrefix?;
741
- private readonly argPrefix?;
742
- constructor(baseMessages: LLMMessage[], initialMessages: LLMMessage[], options?: ConversationManagerOptions);
743
- addUserMessage(content: MessageContent): void;
744
- addAssistantMessage(content: string): void;
745
- addGadgetCall(gadgetName: string, parameters: Record<string, unknown>, result: string): void;
746
- getMessages(): LLMMessage[];
747
- getHistoryMessages(): LLMMessage[];
748
- getBaseMessages(): LLMMessage[];
749
- replaceHistory(newHistory: LLMMessage[]): void;
750
- }
751
-
752
- /**
753
- * StreamProcessor: The heart of the new hooks architecture.
716
+ * CompactionManager - Central orchestrator for context compaction.
754
717
  *
755
- * Replaces the complex wiring between Agent, ResponseProcessor, and GadgetRuntime.
756
- * Owns ALL stream processing and hook coordination with a clean, predictable flow.
718
+ * Monitors token usage and coordinates compaction strategies to keep
719
+ * conversation context within model limits.
757
720
  */
758
721
 
759
722
  /**
760
- * Configuration for the StreamProcessor.
761
- */
762
- interface StreamProcessorOptions {
763
- /** Current iteration number */
764
- iteration: number;
765
- /** Gadget registry for execution */
766
- registry: GadgetRegistry;
767
- /** Custom gadget start prefix */
768
- gadgetStartPrefix?: string;
769
- /** Custom gadget end prefix */
770
- gadgetEndPrefix?: string;
771
- /** Custom argument prefix for block format */
772
- gadgetArgPrefix?: string;
773
- /** Hooks for lifecycle events */
774
- hooks?: AgentHooks;
775
- /** Logger instance */
776
- logger?: Logger<ILogObj>;
777
- /** Callback for human input */
778
- onHumanInputRequired?: (question: string) => Promise<string>;
779
- /** Whether to stop on gadget errors */
780
- stopOnGadgetError?: boolean;
781
- /** Custom error continuation logic */
782
- shouldContinueAfterError?: (context: {
783
- error: string;
784
- gadgetName: string;
785
- errorType: "parse" | "validation" | "execution";
786
- parameters?: Record<string, unknown>;
787
- }) => boolean | Promise<boolean>;
788
- /** Default gadget timeout */
789
- defaultGadgetTimeoutMs?: number;
790
- /** LLMist client for ExecutionContext.llmist */
791
- client?: LLMist;
792
- }
793
- /**
794
- * Result of stream processing.
723
+ * Pre-computed token counts to avoid redundant counting.
724
+ * Passed from checkAndCompact to compact for efficiency.
795
725
  */
796
- interface StreamProcessingResult {
797
- /** All emitted events */
798
- outputs: StreamEvent[];
799
- /** Whether the loop should break */
800
- shouldBreakLoop: boolean;
801
- /** Whether any gadgets were executed */
802
- didExecuteGadgets: boolean;
803
- /** LLM finish reason */
804
- finishReason: string | null;
805
- /** Token usage (including cached token counts when available) */
806
- usage?: TokenUsage;
807
- /** The raw accumulated response text */
808
- rawResponse: string;
809
- /** The final message (after interceptors) */
810
- finalMessage: string;
726
+ interface PrecomputedTokens {
727
+ historyMessages: LLMMessage[];
728
+ baseMessages: LLMMessage[];
729
+ historyTokens: number;
730
+ baseTokens: number;
731
+ currentTokens: number;
811
732
  }
812
733
  /**
813
- * StreamProcessor: Coordinates all stream processing and hook execution.
734
+ * CompactionManager orchestrates context compaction for an agent.
814
735
  *
815
- * Execution order:
816
- * 1. Raw chunk arrives from LLM
817
- * 2. Interceptor: interceptRawChunk (transform raw text)
818
- * 3. Observer: onStreamChunk (logging)
819
- * 4. Parse for gadgets
820
- * 5. If gadget found:
821
- * a. Interceptor: interceptGadgetParameters (transform params)
822
- * b. Controller: beforeGadgetExecution (can skip)
823
- * c. Observer: onGadgetExecutionStart
824
- * d. Execute gadget
825
- * e. Interceptor: interceptGadgetResult (transform result)
826
- * f. Controller: afterGadgetExecution (can provide fallback)
827
- * g. Observer: onGadgetExecutionComplete
828
- * 6. If text chunk:
829
- * a. Interceptor: interceptTextChunk (transform display text)
830
- * b. Yield to user
831
- * 7. Stream complete
832
- * 8. Interceptor: interceptAssistantMessage (transform final message)
736
+ * It:
737
+ * - Monitors token usage before each LLM call
738
+ * - Triggers compaction when threshold is exceeded
739
+ * - Coordinates with ConversationManager to update history
740
+ * - Tracks statistics for observability
833
741
  */
834
- declare class StreamProcessor {
835
- private readonly iteration;
836
- private readonly registry;
837
- private readonly hooks;
838
- private readonly logger;
839
- private readonly parser;
840
- private readonly executor;
841
- private readonly stopOnGadgetError;
842
- private readonly shouldContinueAfterError?;
843
- private accumulatedText;
844
- private shouldStopExecution;
845
- private observerFailureCount;
846
- /** Gadgets waiting for their dependencies to complete */
847
- private pendingGadgets;
848
- /** Completed gadget results, keyed by invocation ID */
849
- private completedResults;
850
- /** Invocation IDs of gadgets that have failed (error or skipped due to dependency) */
851
- private failedInvocations;
852
- constructor(options: StreamProcessorOptions);
853
- /**
854
- * Process an LLM stream and return structured results.
855
- */
856
- process(stream: AsyncIterable<LLMStreamChunk>): Promise<StreamProcessingResult>;
857
- /**
858
- * Process a single parsed event (text or gadget call).
859
- */
860
- private processEvent;
861
- /**
862
- * Process a text event through interceptors.
863
- */
864
- private processTextEvent;
742
+ declare class CompactionManager {
743
+ private readonly client;
744
+ private readonly model;
745
+ private readonly config;
746
+ private readonly strategy;
747
+ private modelLimits?;
748
+ private totalCompactions;
749
+ private totalTokensSaved;
750
+ private lastTokenCount;
751
+ constructor(client: LLMist, model: string, config?: CompactionConfig);
865
752
  /**
866
- * Process a gadget call through the full lifecycle, handling dependencies.
753
+ * Check if compaction is needed and perform it if so.
867
754
  *
868
- * Gadgets without dependencies (or with all dependencies satisfied) execute immediately.
869
- * Gadgets with unsatisfied dependencies are queued for later execution.
870
- * After each execution, pending gadgets are checked to see if they can now run.
871
- */
872
- private processGadgetCall;
873
- /**
874
- * Execute a gadget through the full hook lifecycle.
875
- * This is the core execution logic, extracted from processGadgetCall.
876
- */
877
- private executeGadgetWithHooks;
878
- /**
879
- * Handle a gadget that cannot execute because a dependency failed.
880
- * Calls the onDependencySkipped controller to allow customization.
881
- */
882
- private handleFailedDependency;
883
- /**
884
- * Process pending gadgets whose dependencies are now satisfied.
885
- * Executes ready gadgets in parallel and continues until no more can be triggered.
886
- */
887
- private processPendingGadgets;
888
- /**
889
- * Safely execute an observer, catching and logging any errors.
890
- * Observers are non-critical, so errors are logged but don't crash the system.
755
+ * @param conversation - The conversation manager to compact
756
+ * @param iteration - Current agent iteration (for event metadata)
757
+ * @returns CompactionEvent if compaction was performed, null otherwise
891
758
  */
892
- private safeObserve;
759
+ checkAndCompact(conversation: IConversationManager, iteration: number): Promise<CompactionEvent | null>;
893
760
  /**
894
- * Execute multiple observers in parallel.
895
- * All observers run concurrently and failures are tracked but don't crash.
761
+ * Force compaction regardless of threshold.
762
+ *
763
+ * @param conversation - The conversation manager to compact
764
+ * @param iteration - Current agent iteration (for event metadata). Use -1 for manual compaction.
765
+ * @param precomputed - Optional pre-computed token counts (passed from checkAndCompact for efficiency)
766
+ * @returns CompactionEvent with compaction details
896
767
  */
897
- private runObserversInParallel;
768
+ compact(conversation: IConversationManager, iteration: number, precomputed?: PrecomputedTokens): Promise<CompactionEvent | null>;
898
769
  /**
899
- * Check if execution should continue after an error.
900
- *
901
- * Returns true if we should continue processing subsequent gadgets, false if we should stop.
902
- *
903
- * Logic:
904
- * - If custom shouldContinueAfterError is provided, use it
905
- * - Otherwise, use stopOnGadgetError config:
906
- * - stopOnGadgetError=true → return false (stop execution)
907
- * - stopOnGadgetError=false → return true (continue execution)
770
+ * Get compaction statistics.
908
771
  */
909
- private checkContinueAfterError;
772
+ getStats(): CompactionStats;
910
773
  /**
911
- * Determine the type of error from a gadget execution.
774
+ * Check if compaction is enabled.
912
775
  */
913
- private determineErrorType;
776
+ isEnabled(): boolean;
914
777
  }
915
778
 
916
779
  /**
917
- * Storage for large gadget outputs that exceed the configured limit.
780
+ * Hybrid Compaction Strategy
918
781
  *
919
- * When a gadget returns more data than the configured limit, the output
920
- * is stored here and can be browsed later using GadgetOutputViewer.
921
- */
922
- /**
923
- * Metadata and content for a stored gadget output.
782
+ * Combines sliding window and summarization for the best of both worlds:
783
+ * 1. Identifies which turns to compact vs keep (like sliding window)
784
+ * 2. Summarizes the older turns (like summarization)
785
+ * 3. Returns summary + recent turns intact
786
+ *
787
+ * Falls back to sliding window if there are too few turns to summarize.
924
788
  */
925
- interface StoredOutput {
926
- /** Unique identifier (e.g., "Search_d34db33f") */
927
- id: string;
928
- /** Name of the gadget that produced this output */
929
- gadgetName: string;
930
- /** Full output content */
931
- content: string;
932
- /** Size in bytes */
933
- byteSize: number;
934
- /** Number of lines */
935
- lineCount: number;
936
- /** When the output was stored */
937
- timestamp: Date;
938
- }
789
+
939
790
  /**
940
- * In-memory store for large gadget outputs.
941
- *
942
- * Outputs are stored with generated IDs in the format `{GadgetName}_{hex8}`.
943
- * The store is tied to an agent run and cleared when the agent completes.
944
- *
945
- * @example
946
- * ```typescript
947
- * const store = new GadgetOutputStore();
948
- * const id = store.store("Search", largeOutput);
949
- * // id = "Search_a1b2c3d4"
791
+ * Hybrid strategy - summarizes old turns + keeps recent turns.
950
792
  *
951
- * const stored = store.get(id);
952
- * console.log(stored?.lineCount); // 4200
953
- * ```
793
+ * This is the recommended default strategy as it:
794
+ * - Preserves important historical context via summarization
795
+ * - Keeps recent conversation turns verbatim for continuity
796
+ * - Falls back gracefully to sliding window when appropriate
954
797
  */
955
- declare class GadgetOutputStore {
956
- private outputs;
957
- /**
958
- * Store a gadget output and return its ID.
959
- *
960
- * @param gadgetName - Name of the gadget that produced the output
961
- * @param content - Full output content to store
962
- * @returns Generated ID for retrieving the output later
963
- */
964
- store(gadgetName: string, content: string): string;
965
- /**
966
- * Retrieve a stored output by ID.
967
- *
968
- * @param id - The output ID (e.g., "Search_d34db33f")
969
- * @returns The stored output or undefined if not found
970
- */
971
- get(id: string): StoredOutput | undefined;
972
- /**
973
- * Check if an output exists.
974
- *
975
- * @param id - The output ID to check
976
- * @returns True if the output exists
977
- */
978
- has(id: string): boolean;
979
- /**
980
- * Get all stored output IDs.
981
- *
982
- * @returns Array of output IDs
983
- */
984
- getIds(): string[];
985
- /**
986
- * Get the number of stored outputs.
987
- */
988
- get size(): number;
989
- /**
990
- * Clear all stored outputs.
991
- * Called when the agent run completes.
992
- */
993
- clear(): void;
994
- /**
995
- * Generate a unique ID for a stored output.
996
- * Format: {GadgetName}_{8 hex chars}
997
- */
998
- private generateId;
798
+ declare class HybridStrategy implements CompactionStrategy {
799
+ readonly name = "hybrid";
800
+ private readonly slidingWindow;
801
+ private readonly summarization;
802
+ compact(messages: LLMMessage[], config: ResolvedCompactionConfig, context: CompactionContext): Promise<CompactionResult>;
999
803
  }
1000
804
 
1001
805
  /**
@@ -1055,93 +859,125 @@ declare class SummarizationStrategy implements CompactionStrategy {
1055
859
  }
1056
860
 
1057
861
  /**
1058
- * Hybrid Compaction Strategy
1059
- *
1060
- * Combines sliding window and summarization for the best of both worlds:
1061
- * 1. Identifies which turns to compact vs keep (like sliding window)
1062
- * 2. Summarizes the older turns (like summarization)
1063
- * 3. Returns summary + recent turns intact
1064
- *
1065
- * Falls back to sliding window if there are too few turns to summarize.
862
+ * ConversationManager handles conversation state and message building.
863
+ * Extracted from AgentLoop to follow Single Responsibility Principle.
1066
864
  */
1067
865
 
1068
866
  /**
1069
- * Hybrid strategy - summarizes old turns + keeps recent turns.
1070
- *
1071
- * This is the recommended default strategy as it:
1072
- * - Preserves important historical context via summarization
1073
- * - Keeps recent conversation turns verbatim for continuity
1074
- * - Falls back gracefully to sliding window when appropriate
867
+ * Options for ConversationManager constructor.
1075
868
  */
1076
- declare class HybridStrategy implements CompactionStrategy {
1077
- readonly name = "hybrid";
1078
- private readonly slidingWindow;
1079
- private readonly summarization;
1080
- compact(messages: LLMMessage[], config: ResolvedCompactionConfig, context: CompactionContext): Promise<CompactionResult>;
869
+ interface ConversationManagerOptions {
870
+ /** Custom gadget start marker prefix */
871
+ startPrefix?: string;
872
+ /** Custom gadget end marker prefix */
873
+ endPrefix?: string;
874
+ /** Custom argument prefix for block format */
875
+ argPrefix?: string;
876
+ }
877
+ /**
878
+ * Default implementation of IConversationManager.
879
+ * Manages conversation history by building on top of base messages (system prompt, gadget instructions).
880
+ */
881
+ declare class ConversationManager implements IConversationManager {
882
+ private readonly baseMessages;
883
+ private readonly initialMessages;
884
+ private historyBuilder;
885
+ private readonly startPrefix?;
886
+ private readonly endPrefix?;
887
+ private readonly argPrefix?;
888
+ constructor(baseMessages: LLMMessage[], initialMessages: LLMMessage[], options?: ConversationManagerOptions);
889
+ addUserMessage(content: MessageContent): void;
890
+ addAssistantMessage(content: string): void;
891
+ addGadgetCall(gadgetName: string, parameters: Record<string, unknown>, result: string, media?: GadgetMediaOutput[], mediaIds?: string[]): void;
892
+ getMessages(): LLMMessage[];
893
+ getHistoryMessages(): LLMMessage[];
894
+ getBaseMessages(): LLMMessage[];
895
+ replaceHistory(newHistory: LLMMessage[]): void;
1081
896
  }
1082
897
 
1083
898
  /**
1084
- * CompactionManager - Central orchestrator for context compaction.
899
+ * Storage for large gadget outputs that exceed the configured limit.
1085
900
  *
1086
- * Monitors token usage and coordinates compaction strategies to keep
1087
- * conversation context within model limits.
901
+ * When a gadget returns more data than the configured limit, the output
902
+ * is stored here and can be browsed later using GadgetOutputViewer.
1088
903
  */
1089
-
1090
904
  /**
1091
- * Pre-computed token counts to avoid redundant counting.
1092
- * Passed from checkAndCompact to compact for efficiency.
905
+ * Metadata and content for a stored gadget output.
1093
906
  */
1094
- interface PrecomputedTokens {
1095
- historyMessages: LLMMessage[];
1096
- baseMessages: LLMMessage[];
1097
- historyTokens: number;
1098
- baseTokens: number;
1099
- currentTokens: number;
907
+ interface StoredOutput {
908
+ /** Unique identifier (e.g., "Search_d34db33f") */
909
+ id: string;
910
+ /** Name of the gadget that produced this output */
911
+ gadgetName: string;
912
+ /** Full output content */
913
+ content: string;
914
+ /** Size in bytes */
915
+ byteSize: number;
916
+ /** Number of lines */
917
+ lineCount: number;
918
+ /** When the output was stored */
919
+ timestamp: Date;
1100
920
  }
1101
921
  /**
1102
- * CompactionManager orchestrates context compaction for an agent.
922
+ * In-memory store for large gadget outputs.
1103
923
  *
1104
- * It:
1105
- * - Monitors token usage before each LLM call
1106
- * - Triggers compaction when threshold is exceeded
1107
- * - Coordinates with ConversationManager to update history
1108
- * - Tracks statistics for observability
924
+ * Outputs are stored with generated IDs in the format `{GadgetName}_{hex8}`.
925
+ * The store is tied to an agent run and cleared when the agent completes.
926
+ *
927
+ * @example
928
+ * ```typescript
929
+ * const store = new GadgetOutputStore();
930
+ * const id = store.store("Search", largeOutput);
931
+ * // id = "Search_a1b2c3d4"
932
+ *
933
+ * const stored = store.get(id);
934
+ * console.log(stored?.lineCount); // 4200
935
+ * ```
1109
936
  */
1110
- declare class CompactionManager {
1111
- private readonly client;
1112
- private readonly model;
1113
- private readonly config;
1114
- private readonly strategy;
1115
- private modelLimits?;
1116
- private totalCompactions;
1117
- private totalTokensSaved;
1118
- private lastTokenCount;
1119
- constructor(client: LLMist, model: string, config?: CompactionConfig);
937
+ declare class GadgetOutputStore {
938
+ private outputs;
939
+ /**
940
+ * Store a gadget output and return its ID.
941
+ *
942
+ * @param gadgetName - Name of the gadget that produced the output
943
+ * @param content - Full output content to store
944
+ * @returns Generated ID for retrieving the output later
945
+ */
946
+ store(gadgetName: string, content: string): string;
947
+ /**
948
+ * Retrieve a stored output by ID.
949
+ *
950
+ * @param id - The output ID (e.g., "Search_d34db33f")
951
+ * @returns The stored output or undefined if not found
952
+ */
953
+ get(id: string): StoredOutput | undefined;
954
+ /**
955
+ * Check if an output exists.
956
+ *
957
+ * @param id - The output ID to check
958
+ * @returns True if the output exists
959
+ */
960
+ has(id: string): boolean;
1120
961
  /**
1121
- * Check if compaction is needed and perform it if so.
962
+ * Get all stored output IDs.
1122
963
  *
1123
- * @param conversation - The conversation manager to compact
1124
- * @param iteration - Current agent iteration (for event metadata)
1125
- * @returns CompactionEvent if compaction was performed, null otherwise
964
+ * @returns Array of output IDs
1126
965
  */
1127
- checkAndCompact(conversation: IConversationManager, iteration: number): Promise<CompactionEvent | null>;
966
+ getIds(): string[];
1128
967
  /**
1129
- * Force compaction regardless of threshold.
1130
- *
1131
- * @param conversation - The conversation manager to compact
1132
- * @param iteration - Current agent iteration (for event metadata). Use -1 for manual compaction.
1133
- * @param precomputed - Optional pre-computed token counts (passed from checkAndCompact for efficiency)
1134
- * @returns CompactionEvent with compaction details
968
+ * Get the number of stored outputs.
1135
969
  */
1136
- compact(conversation: IConversationManager, iteration: number, precomputed?: PrecomputedTokens): Promise<CompactionEvent | null>;
970
+ get size(): number;
1137
971
  /**
1138
- * Get compaction statistics.
972
+ * Clear all stored outputs.
973
+ * Called when the agent run completes.
1139
974
  */
1140
- getStats(): CompactionStats;
975
+ clear(): void;
1141
976
  /**
1142
- * Check if compaction is enabled.
977
+ * Generate a unique ID for a stored output.
978
+ * Format: {GadgetName}_{8 hex chars}
1143
979
  */
1144
- isEnabled(): boolean;
980
+ private generateId;
1145
981
  }
1146
982
 
1147
983
  /**
@@ -1188,134 +1024,300 @@ declare class CompactionManager {
1188
1024
  */
1189
1025
  interface IterationHintOptions {
1190
1026
  /**
1191
- * When to show the hint.
1192
- * - "always": Show on every iteration
1193
- * - "late": Show only when >= 50% through iterations
1194
- * - "urgent": Show only when >= 80% through iterations
1195
- * @default "always"
1027
+ * When to show the hint.
1028
+ * - "always": Show on every iteration
1029
+ * - "late": Show only when >= 50% through iterations
1030
+ * - "urgent": Show only when >= 80% through iterations
1031
+ * @default "always"
1032
+ */
1033
+ timing?: "always" | "late" | "urgent";
1034
+ /**
1035
+ * Whether to include urgency indicators for late iterations.
1036
+ * Adds extra text when running low on iterations.
1037
+ * @default true
1038
+ */
1039
+ showUrgency?: boolean;
1040
+ /**
1041
+ * Custom template. Supports placeholders: {iteration}, {maxIterations}, {remaining}
1042
+ * Or a function receiving HintContext.
1043
+ * @default DEFAULT_HINTS.iterationProgressHint
1044
+ */
1045
+ template?: HintTemplate;
1046
+ }
1047
+ /**
1048
+ * Options for parallel gadget usage hint.
1049
+ */
1050
+ interface ParallelGadgetHintOptions {
1051
+ /**
1052
+ * Minimum number of gadget calls to consider "efficient".
1053
+ * If response has fewer calls, hint will suggest parallelization.
1054
+ * @default 2
1055
+ */
1056
+ minGadgetsForEfficiency?: number;
1057
+ /**
1058
+ * Custom message when single gadget detected.
1059
+ * @default DEFAULT_HINTS.parallelGadgetsHint
1060
+ */
1061
+ message?: string;
1062
+ /**
1063
+ * Whether to enable this hint.
1064
+ * @default true
1065
+ */
1066
+ enabled?: boolean;
1067
+ }
1068
+ /**
1069
+ * Combined hints configuration for createHints().
1070
+ */
1071
+ interface HintsConfig {
1072
+ /**
1073
+ * Enable iteration progress hints.
1074
+ * Pass `true` for defaults, or options object for customization.
1075
+ */
1076
+ iterationProgress?: boolean | IterationHintOptions;
1077
+ /**
1078
+ * Enable parallel gadget hints.
1079
+ * Pass `true` for defaults, or options object for customization.
1080
+ */
1081
+ parallelGadgets?: boolean | ParallelGadgetHintOptions;
1082
+ /**
1083
+ * Additional custom hooks to merge.
1084
+ */
1085
+ custom?: AgentHooks[];
1086
+ }
1087
+ /**
1088
+ * Creates a proactive hint that informs the LLM about iteration progress.
1089
+ *
1090
+ * This hint is injected before each LLM call (via beforeLLMCall controller),
1091
+ * helping the LLM understand how much "budget" remains for completing the task.
1092
+ *
1093
+ * @param options - Configuration options
1094
+ * @returns AgentHooks that can be merged with other hooks
1095
+ *
1096
+ * @example
1097
+ * ```typescript
1098
+ * // Basic usage - show on every iteration
1099
+ * const hooks = iterationProgressHint();
1100
+ *
1101
+ * // Show only when running low on iterations
1102
+ * const hooks = iterationProgressHint({ timing: "late" });
1103
+ *
1104
+ * // Custom template
1105
+ * const hooks = iterationProgressHint({
1106
+ * template: "Turn {iteration} of {maxIterations}. {remaining} turns left.",
1107
+ * });
1108
+ * ```
1109
+ */
1110
+ declare function iterationProgressHint(options?: IterationHintOptions): AgentHooks;
1111
+ /**
1112
+ * Creates a reactive hint that encourages parallel gadget usage.
1113
+ *
1114
+ * This hint analyzes the LLM's response and, if only a single gadget was called,
1115
+ * appends a reminder that multiple gadgets can be used in parallel for efficiency.
1116
+ *
1117
+ * @param options - Configuration options
1118
+ * @returns AgentHooks that can be merged with other hooks
1119
+ *
1120
+ * @example
1121
+ * ```typescript
1122
+ * // Basic usage
1123
+ * const hooks = parallelGadgetHint();
1124
+ *
1125
+ * // Custom threshold and message
1126
+ * const hooks = parallelGadgetHint({
1127
+ * minGadgetsForEfficiency: 3,
1128
+ * message: "Consider calling multiple gadgets at once!",
1129
+ * });
1130
+ * ```
1131
+ */
1132
+ declare function parallelGadgetHint(options?: ParallelGadgetHintOptions): AgentHooks;
1133
+ /**
1134
+ * Creates combined hints from a configuration object.
1135
+ *
1136
+ * This is a convenience function that creates and merges multiple hints
1137
+ * based on a simple configuration object.
1138
+ *
1139
+ * @param config - Configuration for which hints to enable
1140
+ * @returns Merged AgentHooks
1141
+ *
1142
+ * @example
1143
+ * ```typescript
1144
+ * const hooks = createHints({
1145
+ * iterationProgress: { timing: "late" },
1146
+ * parallelGadgets: true,
1147
+ * });
1148
+ *
1149
+ * const agent = new AgentBuilder()
1150
+ * .withHooks(HookPresets.merge(existingHooks, hooks))
1151
+ * .build();
1152
+ * ```
1153
+ */
1154
+ declare function createHints(config: HintsConfig): AgentHooks;
1155
+
1156
+ /**
1157
+ * StreamProcessor: The heart of the new hooks architecture.
1158
+ *
1159
+ * Replaces the complex wiring between Agent, ResponseProcessor, and GadgetRuntime.
1160
+ * Owns ALL stream processing and hook coordination with a clean, predictable flow.
1161
+ */
1162
+
1163
+ /**
1164
+ * Configuration for the StreamProcessor.
1165
+ */
1166
+ interface StreamProcessorOptions {
1167
+ /** Current iteration number */
1168
+ iteration: number;
1169
+ /** Gadget registry for execution */
1170
+ registry: GadgetRegistry;
1171
+ /** Custom gadget start prefix */
1172
+ gadgetStartPrefix?: string;
1173
+ /** Custom gadget end prefix */
1174
+ gadgetEndPrefix?: string;
1175
+ /** Custom argument prefix for block format */
1176
+ gadgetArgPrefix?: string;
1177
+ /** Hooks for lifecycle events */
1178
+ hooks?: AgentHooks;
1179
+ /** Logger instance */
1180
+ logger?: Logger<ILogObj>;
1181
+ /** Callback for human input */
1182
+ onHumanInputRequired?: (question: string) => Promise<string>;
1183
+ /** Whether to stop on gadget errors */
1184
+ stopOnGadgetError?: boolean;
1185
+ /** Custom error continuation logic */
1186
+ shouldContinueAfterError?: (context: {
1187
+ error: string;
1188
+ gadgetName: string;
1189
+ errorType: "parse" | "validation" | "execution";
1190
+ parameters?: Record<string, unknown>;
1191
+ }) => boolean | Promise<boolean>;
1192
+ /** Default gadget timeout */
1193
+ defaultGadgetTimeoutMs?: number;
1194
+ /** LLMist client for ExecutionContext.llmist */
1195
+ client?: LLMist;
1196
+ /** MediaStore for storing gadget media outputs */
1197
+ mediaStore?: MediaStore;
1198
+ }
1199
+ /**
1200
+ * Result of stream processing.
1201
+ */
1202
+ interface StreamProcessingResult {
1203
+ /** All emitted events */
1204
+ outputs: StreamEvent[];
1205
+ /** Whether the loop should break */
1206
+ shouldBreakLoop: boolean;
1207
+ /** Whether any gadgets were executed */
1208
+ didExecuteGadgets: boolean;
1209
+ /** LLM finish reason */
1210
+ finishReason: string | null;
1211
+ /** Token usage (including cached token counts when available) */
1212
+ usage?: TokenUsage;
1213
+ /** The raw accumulated response text */
1214
+ rawResponse: string;
1215
+ /** The final message (after interceptors) */
1216
+ finalMessage: string;
1217
+ }
1218
+ /**
1219
+ * StreamProcessor: Coordinates all stream processing and hook execution.
1220
+ *
1221
+ * Execution order:
1222
+ * 1. Raw chunk arrives from LLM
1223
+ * 2. Interceptor: interceptRawChunk (transform raw text)
1224
+ * 3. Observer: onStreamChunk (logging)
1225
+ * 4. Parse for gadgets
1226
+ * 5. If gadget found:
1227
+ * a. Interceptor: interceptGadgetParameters (transform params)
1228
+ * b. Controller: beforeGadgetExecution (can skip)
1229
+ * c. Observer: onGadgetExecutionStart
1230
+ * d. Execute gadget
1231
+ * e. Interceptor: interceptGadgetResult (transform result)
1232
+ * f. Controller: afterGadgetExecution (can provide fallback)
1233
+ * g. Observer: onGadgetExecutionComplete
1234
+ * 6. If text chunk:
1235
+ * a. Interceptor: interceptTextChunk (transform display text)
1236
+ * b. Yield to user
1237
+ * 7. Stream complete
1238
+ * 8. Interceptor: interceptAssistantMessage (transform final message)
1239
+ */
1240
+ declare class StreamProcessor {
1241
+ private readonly iteration;
1242
+ private readonly registry;
1243
+ private readonly hooks;
1244
+ private readonly logger;
1245
+ private readonly parser;
1246
+ private readonly executor;
1247
+ private readonly stopOnGadgetError;
1248
+ private readonly shouldContinueAfterError?;
1249
+ private accumulatedText;
1250
+ private shouldStopExecution;
1251
+ private observerFailureCount;
1252
+ /** Gadgets waiting for their dependencies to complete */
1253
+ private pendingGadgets;
1254
+ /** Completed gadget results, keyed by invocation ID */
1255
+ private completedResults;
1256
+ /** Invocation IDs of gadgets that have failed (error or skipped due to dependency) */
1257
+ private failedInvocations;
1258
+ constructor(options: StreamProcessorOptions);
1259
+ /**
1260
+ * Process an LLM stream and return structured results.
1196
1261
  */
1197
- timing?: "always" | "late" | "urgent";
1262
+ process(stream: AsyncIterable<LLMStreamChunk>): Promise<StreamProcessingResult>;
1198
1263
  /**
1199
- * Whether to include urgency indicators for late iterations.
1200
- * Adds extra text when running low on iterations.
1201
- * @default true
1264
+ * Process a single parsed event (text or gadget call).
1202
1265
  */
1203
- showUrgency?: boolean;
1266
+ private processEvent;
1204
1267
  /**
1205
- * Custom template. Supports placeholders: {iteration}, {maxIterations}, {remaining}
1206
- * Or a function receiving HintContext.
1207
- * @default DEFAULT_HINTS.iterationProgressHint
1268
+ * Process a text event through interceptors.
1208
1269
  */
1209
- template?: HintTemplate;
1210
- }
1211
- /**
1212
- * Options for parallel gadget usage hint.
1213
- */
1214
- interface ParallelGadgetHintOptions {
1270
+ private processTextEvent;
1215
1271
  /**
1216
- * Minimum number of gadget calls to consider "efficient".
1217
- * If response has fewer calls, hint will suggest parallelization.
1218
- * @default 2
1272
+ * Process a gadget call through the full lifecycle, handling dependencies.
1273
+ *
1274
+ * Gadgets without dependencies (or with all dependencies satisfied) execute immediately.
1275
+ * Gadgets with unsatisfied dependencies are queued for later execution.
1276
+ * After each execution, pending gadgets are checked to see if they can now run.
1219
1277
  */
1220
- minGadgetsForEfficiency?: number;
1278
+ private processGadgetCall;
1221
1279
  /**
1222
- * Custom message when single gadget detected.
1223
- * @default DEFAULT_HINTS.parallelGadgetsHint
1280
+ * Execute a gadget through the full hook lifecycle.
1281
+ * This is the core execution logic, extracted from processGadgetCall.
1224
1282
  */
1225
- message?: string;
1283
+ private executeGadgetWithHooks;
1226
1284
  /**
1227
- * Whether to enable this hint.
1228
- * @default true
1285
+ * Handle a gadget that cannot execute because a dependency failed.
1286
+ * Calls the onDependencySkipped controller to allow customization.
1229
1287
  */
1230
- enabled?: boolean;
1231
- }
1232
- /**
1233
- * Combined hints configuration for createHints().
1234
- */
1235
- interface HintsConfig {
1288
+ private handleFailedDependency;
1236
1289
  /**
1237
- * Enable iteration progress hints.
1238
- * Pass `true` for defaults, or options object for customization.
1290
+ * Process pending gadgets whose dependencies are now satisfied.
1291
+ * Executes ready gadgets in parallel and continues until no more can be triggered.
1239
1292
  */
1240
- iterationProgress?: boolean | IterationHintOptions;
1293
+ private processPendingGadgets;
1241
1294
  /**
1242
- * Enable parallel gadget hints.
1243
- * Pass `true` for defaults, or options object for customization.
1295
+ * Safely execute an observer, catching and logging any errors.
1296
+ * Observers are non-critical, so errors are logged but don't crash the system.
1244
1297
  */
1245
- parallelGadgets?: boolean | ParallelGadgetHintOptions;
1298
+ private safeObserve;
1246
1299
  /**
1247
- * Additional custom hooks to merge.
1300
+ * Execute multiple observers in parallel.
1301
+ * All observers run concurrently and failures are tracked but don't crash.
1248
1302
  */
1249
- custom?: AgentHooks[];
1303
+ private runObserversInParallel;
1304
+ /**
1305
+ * Check if execution should continue after an error.
1306
+ *
1307
+ * Returns true if we should continue processing subsequent gadgets, false if we should stop.
1308
+ *
1309
+ * Logic:
1310
+ * - If custom shouldContinueAfterError is provided, use it
1311
+ * - Otherwise, use stopOnGadgetError config:
1312
+ * - stopOnGadgetError=true → return false (stop execution)
1313
+ * - stopOnGadgetError=false → return true (continue execution)
1314
+ */
1315
+ private checkContinueAfterError;
1316
+ /**
1317
+ * Determine the type of error from a gadget execution.
1318
+ */
1319
+ private determineErrorType;
1250
1320
  }
1251
- /**
1252
- * Creates a proactive hint that informs the LLM about iteration progress.
1253
- *
1254
- * This hint is injected before each LLM call (via beforeLLMCall controller),
1255
- * helping the LLM understand how much "budget" remains for completing the task.
1256
- *
1257
- * @param options - Configuration options
1258
- * @returns AgentHooks that can be merged with other hooks
1259
- *
1260
- * @example
1261
- * ```typescript
1262
- * // Basic usage - show on every iteration
1263
- * const hooks = iterationProgressHint();
1264
- *
1265
- * // Show only when running low on iterations
1266
- * const hooks = iterationProgressHint({ timing: "late" });
1267
- *
1268
- * // Custom template
1269
- * const hooks = iterationProgressHint({
1270
- * template: "Turn {iteration} of {maxIterations}. {remaining} turns left.",
1271
- * });
1272
- * ```
1273
- */
1274
- declare function iterationProgressHint(options?: IterationHintOptions): AgentHooks;
1275
- /**
1276
- * Creates a reactive hint that encourages parallel gadget usage.
1277
- *
1278
- * This hint analyzes the LLM's response and, if only a single gadget was called,
1279
- * appends a reminder that multiple gadgets can be used in parallel for efficiency.
1280
- *
1281
- * @param options - Configuration options
1282
- * @returns AgentHooks that can be merged with other hooks
1283
- *
1284
- * @example
1285
- * ```typescript
1286
- * // Basic usage
1287
- * const hooks = parallelGadgetHint();
1288
- *
1289
- * // Custom threshold and message
1290
- * const hooks = parallelGadgetHint({
1291
- * minGadgetsForEfficiency: 3,
1292
- * message: "Consider calling multiple gadgets at once!",
1293
- * });
1294
- * ```
1295
- */
1296
- declare function parallelGadgetHint(options?: ParallelGadgetHintOptions): AgentHooks;
1297
- /**
1298
- * Creates combined hints from a configuration object.
1299
- *
1300
- * This is a convenience function that creates and merges multiple hints
1301
- * based on a simple configuration object.
1302
- *
1303
- * @param config - Configuration for which hints to enable
1304
- * @returns Merged AgentHooks
1305
- *
1306
- * @example
1307
- * ```typescript
1308
- * const hooks = createHints({
1309
- * iterationProgress: { timing: "late" },
1310
- * parallelGadgets: true,
1311
- * });
1312
- *
1313
- * const agent = new AgentBuilder()
1314
- * .withHooks(HookPresets.merge(existingHooks, hooks))
1315
- * .build();
1316
- * ```
1317
- */
1318
- declare function createHints(config: HintsConfig): AgentHooks;
1319
1321
 
1320
1322
  /**
1321
1323
  * Model shortcuts and aliases for more expressive DX.
@@ -1541,25 +1543,6 @@ interface CreateGadgetConfig<TSchema extends ZodType> {
1541
1543
  */
1542
1544
  declare function createGadget<TSchema extends ZodType>(config: CreateGadgetConfig<TSchema>): BaseGadget;
1543
1545
 
1544
- /**
1545
- * Create a GadgetOutputViewer gadget instance bound to a specific output store.
1546
- *
1547
- * This is a factory function because the gadget needs access to the output store,
1548
- * which is created per-agent-run.
1549
- *
1550
- * @param store - The GadgetOutputStore to read outputs from
1551
- * @param maxOutputChars - Maximum characters to return (default: 76,800 = ~19k tokens)
1552
- * @returns A GadgetOutputViewer gadget instance
1553
- *
1554
- * @example
1555
- * ```typescript
1556
- * const store = new GadgetOutputStore();
1557
- * const viewer = createGadgetOutputViewer(store, 76_800);
1558
- * registry.register("GadgetOutputViewer", viewer);
1559
- * ```
1560
- */
1561
- declare function createGadgetOutputViewer(store: GadgetOutputStore, maxOutputChars?: number): BaseGadget;
1562
-
1563
1546
  /**
1564
1547
  * Exception that gadgets can throw to signal the agent loop should terminate.
1565
1548
  *
@@ -1669,10 +1652,11 @@ declare class GadgetExecutor {
1669
1652
  private readonly onHumanInputRequired?;
1670
1653
  private readonly defaultGadgetTimeoutMs?;
1671
1654
  private readonly client?;
1655
+ private readonly mediaStore?;
1672
1656
  private readonly logger;
1673
1657
  private readonly errorFormatter;
1674
1658
  private readonly argPrefix;
1675
- constructor(registry: GadgetRegistry, onHumanInputRequired?: ((question: string) => Promise<string>) | undefined, logger?: Logger<ILogObj>, defaultGadgetTimeoutMs?: number | undefined, errorFormatterOptions?: ErrorFormatterOptions, client?: LLMist | undefined);
1659
+ constructor(registry: GadgetRegistry, onHumanInputRequired?: ((question: string) => Promise<string>) | undefined, logger?: Logger<ILogObj>, defaultGadgetTimeoutMs?: number | undefined, errorFormatterOptions?: ErrorFormatterOptions, client?: LLMist | undefined, mediaStore?: MediaStore | undefined);
1676
1660
  /**
1677
1661
  * Creates a promise that rejects with a TimeoutException after the specified timeout.
1678
1662
  * Aborts the provided AbortController before rejecting, allowing gadgets to clean up.
@@ -1680,7 +1664,8 @@ declare class GadgetExecutor {
1680
1664
  private createTimeoutPromise;
1681
1665
  /**
1682
1666
  * Normalizes gadget execute result to consistent format.
1683
- * Handles both string returns (backwards compat) and object returns with cost.
1667
+ * Handles string returns (backwards compat), object returns with cost,
1668
+ * and object returns with media.
1684
1669
  */
1685
1670
  private normalizeExecuteResult;
1686
1671
  execute(call: ParsedGadgetCall): Promise<GadgetExecutionResult>;
@@ -1692,6 +1677,25 @@ declare class GadgetExecutor {
1692
1677
  private deepEquals;
1693
1678
  }
1694
1679
 
1680
+ /**
1681
+ * Create a GadgetOutputViewer gadget instance bound to a specific output store.
1682
+ *
1683
+ * This is a factory function because the gadget needs access to the output store,
1684
+ * which is created per-agent-run.
1685
+ *
1686
+ * @param store - The GadgetOutputStore to read outputs from
1687
+ * @param maxOutputChars - Maximum characters to return (default: 76,800 = ~19k tokens)
1688
+ * @returns A GadgetOutputViewer gadget instance
1689
+ *
1690
+ * @example
1691
+ * ```typescript
1692
+ * const store = new GadgetOutputStore();
1693
+ * const viewer = createGadgetOutputViewer(store, 76_800);
1694
+ * registry.register("GadgetOutputViewer", viewer);
1695
+ * ```
1696
+ */
1697
+ declare function createGadgetOutputViewer(store: GadgetOutputStore, maxOutputChars?: number): BaseGadget;
1698
+
1695
1699
  interface StreamParserOptions {
1696
1700
  startPrefix?: string;
1697
1701
  endPrefix?: string;
@@ -1887,6 +1891,207 @@ declare function Gadget<TSchema extends ZodType>(config: GadgetConfig<TSchema>):
1887
1891
  };
1888
1892
  };
1889
1893
 
1894
+ /**
1895
+ * Helper functions for gadget authors to easily return media outputs.
1896
+ *
1897
+ * These functions provide type-specific conveniences while using the
1898
+ * generic GadgetMediaOutput system underneath.
1899
+ *
1900
+ * @example
1901
+ * ```typescript
1902
+ * import { resultWithImage } from "llmist/gadgets";
1903
+ *
1904
+ * const screenshotGadget = createGadget({
1905
+ * name: "Screenshot",
1906
+ * schema: z.object({ url: z.string() }),
1907
+ * execute: async ({ url }) => {
1908
+ * const screenshot = await takeScreenshot(url);
1909
+ * return resultWithImage(
1910
+ * `Screenshot of ${url}`,
1911
+ * screenshot,
1912
+ * { description: "Webpage screenshot" }
1913
+ * );
1914
+ * },
1915
+ * });
1916
+ * ```
1917
+ */
1918
+
1919
+ /**
1920
+ * Create a GadgetMediaOutput from raw data.
1921
+ *
1922
+ * @param kind - Type of media
1923
+ * @param data - Raw binary data (Buffer or Uint8Array)
1924
+ * @param mimeType - MIME type string
1925
+ * @param options - Optional description, metadata, and fileName
1926
+ * @returns A GadgetMediaOutput ready to include in results
1927
+ */
1928
+ declare function createMedia(kind: MediaKind, data: Buffer | Uint8Array, mimeType: string, options?: {
1929
+ description?: string;
1930
+ metadata?: MediaMetadata;
1931
+ fileName?: string;
1932
+ }): GadgetMediaOutput;
1933
+ /**
1934
+ * Create a result with multiple media outputs.
1935
+ *
1936
+ * @param result - Text result string
1937
+ * @param media - Array of GadgetMediaOutput items (must not be empty)
1938
+ * @param cost - Optional cost in USD
1939
+ * @returns A GadgetExecuteResultWithMedia
1940
+ * @throws Error if media array is empty
1941
+ *
1942
+ * @example
1943
+ * ```typescript
1944
+ * return resultWithMedia(
1945
+ * "Generated 2 charts",
1946
+ * [
1947
+ * createMedia("image", barChartPng, "image/png", { description: "Bar chart" }),
1948
+ * createMedia("image", pieChartPng, "image/png", { description: "Pie chart" }),
1949
+ * ],
1950
+ * 0.002
1951
+ * );
1952
+ * ```
1953
+ */
1954
+ declare function resultWithMedia(result: string, media: GadgetMediaOutput[], cost?: number): GadgetExecuteResultWithMedia;
1955
+ /**
1956
+ * Options for resultWithImage helper.
1957
+ */
1958
+ interface ImageOptions {
1959
+ /** MIME type (auto-detected if not provided) */
1960
+ mimeType?: string;
1961
+ /** Human-readable description */
1962
+ description?: string;
1963
+ /** Image dimensions and other metadata */
1964
+ metadata?: MediaMetadata;
1965
+ /** Cost in USD */
1966
+ cost?: number;
1967
+ /** Filename to use when saving (if not provided, auto-generated) */
1968
+ fileName?: string;
1969
+ }
1970
+ /**
1971
+ * Create a result with a single image output.
1972
+ *
1973
+ * @param result - Text result string
1974
+ * @param imageData - Raw image data (PNG, JPEG, GIF, WebP)
1975
+ * @param options - Optional MIME type, description, metadata, cost
1976
+ * @returns A GadgetExecuteResultWithMedia
1977
+ *
1978
+ * @example
1979
+ * ```typescript
1980
+ * const screenshot = await page.screenshot({ type: "png" });
1981
+ * return resultWithImage(
1982
+ * "Screenshot captured",
1983
+ * screenshot,
1984
+ * { description: "Homepage screenshot", metadata: { width: 1920, height: 1080 } }
1985
+ * );
1986
+ * ```
1987
+ */
1988
+ declare function resultWithImage(result: string, imageData: Buffer | Uint8Array, options?: ImageOptions): GadgetExecuteResultWithMedia;
1989
+ /**
1990
+ * Image item for resultWithImages helper.
1991
+ */
1992
+ interface ImageItem {
1993
+ /** Raw image data */
1994
+ data: Buffer | Uint8Array;
1995
+ /** MIME type (auto-detected if not provided) */
1996
+ mimeType?: string;
1997
+ /** Human-readable description */
1998
+ description?: string;
1999
+ /** Image dimensions and other metadata */
2000
+ metadata?: MediaMetadata;
2001
+ /** Filename to use when saving (if not provided, auto-generated) */
2002
+ fileName?: string;
2003
+ }
2004
+ /**
2005
+ * Create a result with multiple image outputs.
2006
+ *
2007
+ * @param result - Text result string
2008
+ * @param images - Array of image items (must not be empty)
2009
+ * @param cost - Optional cost in USD
2010
+ * @returns A GadgetExecuteResultWithMedia
2011
+ * @throws Error if images array is empty
2012
+ *
2013
+ * @example
2014
+ * ```typescript
2015
+ * return resultWithImages(
2016
+ * "Generated comparison images",
2017
+ * [
2018
+ * { data: beforeImg, description: "Before" },
2019
+ * { data: afterImg, description: "After" },
2020
+ * ],
2021
+ * 0.01
2022
+ * );
2023
+ * ```
2024
+ */
2025
+ declare function resultWithImages(result: string, images: ImageItem[], cost?: number): GadgetExecuteResultWithMedia;
2026
+ /**
2027
+ * Options for resultWithAudio helper.
2028
+ */
2029
+ interface AudioOptions {
2030
+ /** MIME type (auto-detected if not provided) */
2031
+ mimeType?: string;
2032
+ /** Human-readable description */
2033
+ description?: string;
2034
+ /** Duration in milliseconds */
2035
+ durationMs?: number;
2036
+ /** Cost in USD */
2037
+ cost?: number;
2038
+ /** Filename to use when saving (if not provided, auto-generated) */
2039
+ fileName?: string;
2040
+ }
2041
+ /**
2042
+ * Create a result with a single audio output.
2043
+ *
2044
+ * @param result - Text result string
2045
+ * @param audioData - Raw audio data (MP3, WAV, OGG, etc.)
2046
+ * @param options - Optional MIME type, description, duration, cost
2047
+ * @returns A GadgetExecuteResultWithMedia
2048
+ *
2049
+ * @example
2050
+ * ```typescript
2051
+ * const speech = await generateSpeech(text);
2052
+ * return resultWithAudio(
2053
+ * `Generated speech for: "${text.slice(0, 50)}..."`,
2054
+ * speech,
2055
+ * { mimeType: "audio/mp3", durationMs: 5000 }
2056
+ * );
2057
+ * ```
2058
+ */
2059
+ declare function resultWithAudio(result: string, audioData: Buffer | Uint8Array, options?: AudioOptions): GadgetExecuteResultWithMedia;
2060
+ /**
2061
+ * Options for resultWithFile helper.
2062
+ */
2063
+ interface FileOptions {
2064
+ /** Human-readable description */
2065
+ description?: string;
2066
+ /** Cost in USD */
2067
+ cost?: number;
2068
+ /** Filename to use when saving (if not provided, auto-generated) */
2069
+ fileName?: string;
2070
+ }
2071
+ /**
2072
+ * Create a result with a generic file output.
2073
+ *
2074
+ * Use this for arbitrary file types that don't fit image/audio categories.
2075
+ *
2076
+ * @param result - Text result string
2077
+ * @param fileData - Raw file data
2078
+ * @param mimeType - MIME type (required, not auto-detected)
2079
+ * @param options - Optional description and cost
2080
+ * @returns A GadgetExecuteResultWithMedia
2081
+ *
2082
+ * @example
2083
+ * ```typescript
2084
+ * const pdf = await generatePdf(content);
2085
+ * return resultWithFile(
2086
+ * "Generated PDF report",
2087
+ * pdf,
2088
+ * "application/pdf",
2089
+ * { description: "Monthly report" }
2090
+ * );
2091
+ * ```
2092
+ */
2093
+ declare function resultWithFile(result: string, fileData: Buffer | Uint8Array, mimeType: string, options?: FileOptions): GadgetExecuteResultWithMedia;
2094
+
1890
2095
  /**
1891
2096
  * Validation utilities for gadget parameters.
1892
2097
  *
@@ -2317,4 +2522,4 @@ declare class OpenAIChatProvider extends BaseProviderAdapter {
2317
2522
  }
2318
2523
  declare function createOpenAIProviderFromEnv(): OpenAIChatProvider | null;
2319
2524
 
2320
- export { AbortError, AgentHooks, AnthropicMessagesProvider, BaseGadget, BreakLoopException, CompactionConfig, CompactionContext, CompactionEvent, CompactionManager, CompactionResult, CompactionStats, CompactionStrategy, ConversationManager, type CreateGadgetConfig, ExecutionContext, Gadget, type GadgetConfig, GadgetExample, GadgetExecuteReturn, GadgetExecutionResult, GadgetExecutor, GadgetOutputStore, GadgetRegistry, GeminiGenerativeProvider, HintTemplate, type HintsConfig, HookPresets, HumanInputException, HybridStrategy, IConversationManager, type IterationHintOptions, LLMGenerationOptions, LLMMessage, LLMStream, LLMStreamChunk, LLMist, type LoggerOptions, type LoggingOptions, MODEL_ALIASES, MessageContent, ModelDescriptor, ModelRegistry, ModelSpec, OpenAIChatProvider, type ParallelGadgetHintOptions, ParsedGadgetCall, ProviderAdapter, ResolvedCompactionConfig, SlidingWindowStrategy, type StoredOutput, StreamEvent, StreamParser, type StreamProcessingResult, StreamProcessor, type StreamProcessorOptions, SummarizationStrategy, TokenUsage, type ValidationIssue, type ValidationResult, createAnthropicProviderFromEnv, createGadget, createGadgetOutputViewer, createGeminiProviderFromEnv, createHints, createLogger, createOpenAIProviderFromEnv, defaultLogger, discoverProviderAdapters, getModelId, getProvider, hasProviderPrefix, iterationProgressHint, parallelGadgetHint, resolveModel, validateAndApplyDefaults, validateGadgetParams };
2525
+ export { AbortError, AgentHooks, AnthropicMessagesProvider, BaseGadget, BreakLoopException, CompactionConfig, CompactionContext, CompactionEvent, CompactionManager, CompactionResult, CompactionStats, CompactionStrategy, ConversationManager, type CreateGadgetConfig, ExecutionContext, Gadget, type GadgetConfig, GadgetExample, GadgetExecuteResultWithMedia, GadgetExecuteReturn, GadgetExecutionResult, GadgetExecutor, GadgetMediaOutput, GadgetOutputStore, GadgetRegistry, GeminiGenerativeProvider, HintTemplate, type HintsConfig, HookPresets, HumanInputException, HybridStrategy, IConversationManager, type IterationHintOptions, LLMGenerationOptions, LLMMessage, LLMStream, LLMStreamChunk, LLMist, type LoggerOptions, type LoggingOptions, MODEL_ALIASES, MediaKind, MediaMetadata, MediaStore, MessageContent, ModelDescriptor, ModelRegistry, ModelSpec, OpenAIChatProvider, type ParallelGadgetHintOptions, ParsedGadgetCall, ProviderAdapter, ResolvedCompactionConfig, SlidingWindowStrategy, type StoredOutput, StreamEvent, StreamParser, type StreamProcessingResult, StreamProcessor, type StreamProcessorOptions, SummarizationStrategy, TokenUsage, type ValidationIssue, type ValidationResult, createAnthropicProviderFromEnv, createGadget, createGadgetOutputViewer, createGeminiProviderFromEnv, createHints, createLogger, createMedia, createOpenAIProviderFromEnv, defaultLogger, discoverProviderAdapters, getModelId, getProvider, hasProviderPrefix, iterationProgressHint, parallelGadgetHint, resolveModel, resultWithAudio, resultWithFile, resultWithImage, resultWithImages, resultWithMedia, validateAndApplyDefaults, validateGadgetParams };