@vellumai/plugin-api 0.10.10 → 0.10.11-dev.202607212222.fe33210

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.
Files changed (3) hide show
  1. package/index.d.ts +484 -19
  2. package/index.js +8 -0
  3. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -295,33 +295,21 @@ declare const AssistantConfigSchema: z.ZodObject<{
295
295
  }>>;
296
296
  }, z.core.$strip>>;
297
297
  "web-fetch": z.ZodDefault<z.ZodObject<{
298
- mode: z.ZodDefault<z.ZodEnum<{
299
- managed: "managed";
300
- "your-own": "your-own";
301
- }>>;
302
298
  provider: z.ZodDefault<z.ZodEnum<{
303
299
  [x: string]: string;
304
300
  }>>;
305
301
  }, z.core.$strip>>;
306
302
  stt: z.ZodDefault<z.ZodObject<{
307
- mode: z.ZodDefault<z.ZodEnum<{
308
- managed: "managed";
309
- "your-own": "your-own";
310
- }>>;
311
- provider: z.ZodEnum<{
303
+ provider: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodEnum<{
312
304
  vellum: "vellum";
313
305
  deepgram: "deepgram";
314
306
  "google-gemini": "google-gemini";
315
307
  "openai-whisper": "openai-whisper";
316
308
  xai: "xai";
317
- }>;
309
+ }>>;
318
310
  providers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>>>;
319
311
  }, z.core.$strip>>;
320
312
  tts: z.ZodDefault<z.ZodObject<{
321
- mode: z.ZodDefault<z.ZodEnum<{
322
- managed: "managed";
323
- "your-own": "your-own";
324
- }>>;
325
313
  provider: z.ZodDefault<z.ZodEnum<{
326
314
  vellum: "vellum";
327
315
  deepgram: "deepgram";
@@ -370,7 +358,9 @@ declare const AssistantConfigSchema: z.ZodObject<{
370
358
  sampleRate: z.ZodDefault<z.ZodNumber>;
371
359
  bitRate: z.ZodDefault<z.ZodNumber>;
372
360
  }, z.core.$strip>>;
373
- vellum: z.ZodDefault<z.ZodObject<{}, z.core.$strip>>;
361
+ vellum: z.ZodDefault<z.ZodObject<{
362
+ model: z.ZodOptional<z.ZodString>;
363
+ }, z.core.$strip>>;
374
364
  }, z.core.$strip>>;
375
365
  }, z.core.$strip>>;
376
366
  "google-oauth": z.ZodDefault<z.ZodObject<{
@@ -717,13 +707,16 @@ declare const AssistantConfigSchema: z.ZodObject<{
717
707
  gemini: "gemini";
718
708
  fireworks: "fireworks";
719
709
  openrouter: "openrouter";
710
+ vellum: "vellum";
720
711
  ollama: "ollama";
721
712
  "vercel-ai-gateway": "vercel-ai-gateway";
722
713
  "openai-compatible": "openai-compatible";
723
714
  minimax: "minimax";
724
715
  atlascloud: "atlascloud";
725
716
  together: "together";
717
+ litellm: "litellm";
726
718
  baseten: "baseten";
719
+ chatgpt: "chatgpt";
727
720
  }>>;
728
721
  model: z.ZodOptional<z.ZodString>;
729
722
  maxTokens: z.ZodOptional<z.ZodNumber>;
@@ -839,6 +832,7 @@ declare const AssistantConfigSchema: z.ZodObject<{
839
832
  skillCategoryInference: "skillCategoryInference";
840
833
  inference: "inference";
841
834
  vision: "vision";
835
+ voiceFrontDecision: "voiceFrontDecision";
842
836
  trustRuleSuggestion: "trustRuleSuggestion";
843
837
  homeGreeting: "homeGreeting";
844
838
  homeSuggestedPrompts: "homeSuggestedPrompts";
@@ -850,13 +844,16 @@ declare const AssistantConfigSchema: z.ZodObject<{
850
844
  gemini: "gemini";
851
845
  fireworks: "fireworks";
852
846
  openrouter: "openrouter";
847
+ vellum: "vellum";
853
848
  ollama: "ollama";
854
849
  "vercel-ai-gateway": "vercel-ai-gateway";
855
850
  "openai-compatible": "openai-compatible";
856
851
  minimax: "minimax";
857
852
  atlascloud: "atlascloud";
858
853
  together: "together";
854
+ litellm: "litellm";
859
855
  baseten: "baseten";
856
+ chatgpt: "chatgpt";
860
857
  }>>;
861
858
  model: z.ZodOptional<z.ZodString>;
862
859
  maxTokens: z.ZodOptional<z.ZodNumber>;
@@ -1180,6 +1177,21 @@ declare const AssistantConfigSchema: z.ZodObject<{
1180
1177
  maxTurnDurationMs: z.ZodDefault<z.ZodNumber>;
1181
1178
  bargeInMinSpeechMs: z.ZodDefault<z.ZodNumber>;
1182
1179
  }, z.core.$strip>>;
1180
+ frontModel: z.ZodDefault<z.ZodObject<{
1181
+ endpointDecisionTimeoutMs: z.ZodDefault<z.ZodNumber>;
1182
+ endpointExtensionMs: z.ZodDefault<z.ZodNumber>;
1183
+ endpointMaxExtensions: z.ZodDefault<z.ZodNumber>;
1184
+ ackFirstDeltaTimeoutMs: z.ZodDefault<z.ZodNumber>;
1185
+ ackGenerationTimeoutMs: z.ZodDefault<z.ZodNumber>;
1186
+ llmAckText: z.ZodDefault<z.ZodBoolean>;
1187
+ progress: z.ZodDefault<z.ZodObject<{
1188
+ enabled: z.ZodDefault<z.ZodBoolean>;
1189
+ opsThreshold: z.ZodDefault<z.ZodNumber>;
1190
+ idleIntervalMs: z.ZodDefault<z.ZodNumber>;
1191
+ minGapMs: z.ZodDefault<z.ZodNumber>;
1192
+ generationTimeoutMs: z.ZodDefault<z.ZodNumber>;
1193
+ }, z.core.$strip>>;
1194
+ }, z.core.$strip>>;
1183
1195
  maxSessionDurationSeconds: z.ZodDefault<z.ZodNumber>;
1184
1196
  archiveAudio: z.ZodDefault<z.ZodBoolean>;
1185
1197
  }, z.core.$strip>>;
@@ -1937,6 +1949,8 @@ declare interface ConfigChanged {
1937
1949
  type: "config_changed";
1938
1950
  }
1939
1951
 
1952
+ declare type ConfiguredProviderOptions = Pick<ResolveCallSiteOpts, "overrideProfile" | "forceOverrideProfile" | "selectionSeed">;
1953
+
1940
1954
  declare type ConfirmationRequestEvent = z.infer<typeof ConfirmationRequestEventSchema>;
1941
1955
 
1942
1956
  declare const ConfirmationRequestEventSchema: z.ZodObject<{
@@ -2390,6 +2404,11 @@ declare interface CopyBlockSurfaceData {
2390
2404
  language?: string;
2391
2405
  }
2392
2406
 
2407
+ /** Create a live voice connection bound to the caller's `send` transport. */
2408
+ export declare function createLiveVoiceConnection(options: {
2409
+ send: LiveVoiceFrameSender;
2410
+ }): LiveVoiceConnection;
2411
+
2393
2412
  /**
2394
2413
  * Plugin-facing credential resolution.
2395
2414
  *
@@ -2805,10 +2824,7 @@ export declare function getAssistantName(): string | null;
2805
2824
  * `callSite` is required — see `resolveConfiguredProvider`. Returns `null`
2806
2825
  * when no providers are available.
2807
2826
  */
2808
- export declare function getConfiguredProvider(callSite: LLMCallSite, opts?: {
2809
- overrideProfile?: string;
2810
- forceOverrideProfile?: boolean;
2811
- }): Promise<Provider | null>;
2827
+ export declare function getConfiguredProvider(callSite: LLMCallSite, opts?: ConfiguredProviderOptions): Promise<Provider | null>;
2812
2828
 
2813
2829
  /** Look up a conversation row by id. */
2814
2830
  export declare function getConversation(id: string): Promise<ConversationRow | null>;
@@ -2842,6 +2858,34 @@ declare interface GetSigningIdentityRequest {
2842
2858
  requestId: string;
2843
2859
  }
2844
2860
 
2861
+ /**
2862
+ * Returns the workspace root for user-facing state.
2863
+ *
2864
+ * When the VELLUM_WORKSPACE_DIR env var is set, returns that value (used in
2865
+ * containerized deployments where the workspace is a separate volume).
2866
+ * Otherwise falls back to ~/.vellum/workspace.
2867
+ */
2868
+ export declare function getWorkspaceDir(): string;
2869
+
2870
+ /**
2871
+ * The subset of the Qdrant client the orphan sweep needs, narrowed to an
2872
+ * interface so the sweep can be unit-tested with a fake client.
2873
+ */
2874
+ declare interface GraphNodeSweepClient {
2875
+ scrollByTargetType(targetType: string): Promise<Array<{
2876
+ id: string;
2877
+ payload: Record<string, unknown>;
2878
+ }>>;
2879
+ deleteByTarget(targetType: string, targetId: string): Promise<void>;
2880
+ }
2881
+
2882
+ declare interface GraphNodeSweepResult {
2883
+ /** Distinct `graph_node` target ids currently indexed in Qdrant. */
2884
+ scanned: number;
2885
+ /** Orphan target ids whose Qdrant points were deleted. */
2886
+ deleted: number;
2887
+ }
2888
+
2845
2889
  declare interface GuardianActionDecisionResponse {
2846
2890
  type: "guardian_action_decision_response";
2847
2891
  applied: boolean;
@@ -3621,6 +3665,34 @@ export declare function isConversationProcessing(id: string): Promise<boolean>;
3621
3665
  */
3622
3666
  export declare function isMaxTokensStopReason(stopReason: string | null | undefined): boolean;
3623
3667
 
3668
+ /**
3669
+ * A user-role message carrying only tool results — local `tool_result` or
3670
+ * server `web_search_tool_result` — not a fresh prompt.
3671
+ */
3672
+ export declare function isToolResultMessage(message: Message): boolean;
3673
+
3674
+ /**
3675
+ * Whether a provider error message indicates the model can't accept image
3676
+ * input. Providers wrap raw upstream rejections in their own prose (e.g.
3677
+ * `Anthropic API error (400): …`, `Gemini API error (…): …`), so the classifier
3678
+ * matches the full {@link VISION_NOT_SUPPORTED_PATTERNS} set rather than any
3679
+ * single normalized phrase.
3680
+ */
3681
+ export declare function isVisionNotSupportedError(message: string): boolean;
3682
+
3683
+ /**
3684
+ * Index of the last user message carrying `tool_result` blocks — the
3685
+ * "current turn" boundary {@link stripOldMediaBlocks} keeps intact while
3686
+ * stripping media from older tool results. Returns -1 when no user message
3687
+ * has tool results.
3688
+ *
3689
+ * Targets the last user message with tool_results (not just the last user
3690
+ * message) because a plain-text user message may follow the tool-result turn;
3691
+ * using the last user message unconditionally would leave the most recent tool
3692
+ * screenshots unprotected from stripping.
3693
+ */
3694
+ export declare function lastToolResultUserMessageIndex(history: Message[]): number;
3695
+
3624
3696
  /**
3625
3697
  * The remote skill catalog, fetched via the shared catalog cache. Entries
3626
3698
  * whose declared feature flag is disabled are reported with
@@ -3661,6 +3733,209 @@ declare interface ListSurfaceData {
3661
3733
  selectionMode: "single" | "multiple" | "none";
3662
3734
  }
3663
3735
 
3736
+ declare const _LIVE_VOICE_SERVER_FRAME_TYPES: readonly ["ready", "busy", "speech_started", "utterance_end", "utterance_discarded", "stt_partial", "stt_final", "thinking", "assistant_text_delta", "tts_audio", "tts_done", "turn_cancelled", "metrics", "archived", "error"];
3737
+
3738
+ declare const LIVE_VOICE_TURN_DETECTION_MODES: readonly ["manual", "server_vad"];
3739
+
3740
+ declare interface LiveVoiceArchivedServerFrame extends LiveVoiceServerFrameBase {
3741
+ readonly type: "archived";
3742
+ readonly conversationId: string;
3743
+ readonly sessionId: string;
3744
+ readonly turnId?: string;
3745
+ readonly role?: "user" | "assistant";
3746
+ readonly attachmentId?: string;
3747
+ readonly attachmentIds?: string[];
3748
+ readonly warning?: {
3749
+ readonly code: string;
3750
+ readonly message: string;
3751
+ };
3752
+ }
3753
+
3754
+ declare interface LiveVoiceAssistantTextDeltaServerFrame extends LiveVoiceServerFrameBase {
3755
+ readonly type: "assistant_text_delta";
3756
+ readonly text: string;
3757
+ }
3758
+
3759
+ declare interface LiveVoiceBusyServerFrame extends LiveVoiceServerFrameBase {
3760
+ readonly type: "busy";
3761
+ readonly activeSessionId: string;
3762
+ }
3763
+
3764
+ export declare interface LiveVoiceConnection {
3765
+ /**
3766
+ * The active session id once a `start` frame has been accepted, else
3767
+ * `undefined`. Read-only — the connection assigns it on `start` and clears
3768
+ * it on `end`, teardown, or a session that the manager no longer knows.
3769
+ */
3770
+ readonly sessionId: string | undefined;
3771
+ /**
3772
+ * Handle one inbound transport message — a JSON text frame or a binary
3773
+ * audio chunk. Never rejects: protocol and handler failures are reported
3774
+ * back to the client as `error` frames.
3775
+ */
3776
+ handleMessage(message: string | ArrayBuffer | ArrayBufferView): Promise<void>;
3777
+ /**
3778
+ * Release the session bound to this connection when the transport closes.
3779
+ * Idempotent — a no-op when no session is active.
3780
+ */
3781
+ release(reason?: LiveVoiceSessionCloseReason): void;
3782
+ }
3783
+
3784
+ declare interface LiveVoiceErrorServerFrame extends LiveVoiceServerFrameBase {
3785
+ readonly type: "error";
3786
+ readonly code: LiveVoiceProtocolErrorCode;
3787
+ readonly message: string;
3788
+ /**
3789
+ * True when the session continues past the error (e.g. a transient
3790
+ * transcriber blip or one failed TTS segment). Absent (including on frames
3791
+ * from older daemons) means the error is terminal for the session.
3792
+ */
3793
+ readonly recoverable?: boolean;
3794
+ }
3795
+
3796
+ /**
3797
+ * Sends one fully-sequenced server frame to the client over the caller's
3798
+ * transport. The frame is a plain object; the caller is responsible for wire
3799
+ * encoding (e.g. `JSON.stringify` for a text WebSocket).
3800
+ */
3801
+ export declare type LiveVoiceFrameSender = (frame: LiveVoiceServerFrame) => void;
3802
+
3803
+ declare interface LiveVoiceMetricsServerFrame extends LiveVoiceServerFrameBase {
3804
+ readonly type: "metrics";
3805
+ readonly event?: string;
3806
+ readonly sessionId?: string;
3807
+ readonly conversationId?: string;
3808
+ readonly turnId: string;
3809
+ readonly metrics?: unknown;
3810
+ readonly sttMs: number | null;
3811
+ readonly llmFirstDeltaMs: number | null;
3812
+ readonly ttsFirstAudioMs: number | null;
3813
+ /** End-of-speech (utterance_end, or ptt_release in manual mode) to first TTS audio. */
3814
+ readonly roundTripMs: number | null;
3815
+ readonly totalMs: number | null;
3816
+ /**
3817
+ * Semantic-endpointing "hold" decisions taken during the turn. Present only
3818
+ * when the endpoint decider was consulted (otherwise the field is absent,
3819
+ * keeping frames unchanged).
3820
+ */
3821
+ readonly endpointHoldCount?: number;
3822
+ /** Worst endpoint-decision latency observed during the turn. */
3823
+ readonly endpointDecisionMaxLatencyMs?: number;
3824
+ /** Which floor-holding ack actually spoke during the turn, if any. */
3825
+ readonly ackSpoken?: "first_delta" | "tool_use";
3826
+ /**
3827
+ * Spoken progress narrations during the turn. Present only when at least
3828
+ * one progress update spoke (otherwise the field is absent, keeping frames
3829
+ * unchanged).
3830
+ */
3831
+ readonly progressUpdatesSpoken?: number;
3832
+ }
3833
+
3834
+ declare const LiveVoiceProtocolErrorCode: {
3835
+ readonly InvalidJson: "invalid_json";
3836
+ readonly InvalidFrame: "invalid_frame";
3837
+ readonly UnknownType: "unknown_type";
3838
+ readonly MissingRequiredField: "missing_required_field";
3839
+ readonly InvalidField: "invalid_field";
3840
+ readonly InvalidAudioPayload: "invalid_audio_payload";
3841
+ /**
3842
+ * Session startup was rejected because the daemon cannot run both audio
3843
+ * legs (STT/TTS providers or credentials are unresolved). The error
3844
+ * `message` names the offending provider(s) and missing credential(s).
3845
+ */
3846
+ readonly CredentialsUnavailable: "credentials_unavailable";
3847
+ };
3848
+
3849
+ declare type LiveVoiceProtocolErrorCode = (typeof LiveVoiceProtocolErrorCode)[keyof typeof LiveVoiceProtocolErrorCode];
3850
+
3851
+ declare interface LiveVoiceReadyServerFrame extends LiveVoiceServerFrameBase {
3852
+ readonly type: "ready";
3853
+ readonly sessionId: string;
3854
+ readonly conversationId: string;
3855
+ /**
3856
+ * Echoes the turn-detection mode the session is actually running, so
3857
+ * clients can detect a daemon that ignored a requested mode. Absent
3858
+ * (older daemons) means "manual".
3859
+ */
3860
+ readonly turnDetection?: LiveVoiceTurnDetectionMode;
3861
+ }
3862
+
3863
+ export declare type LiveVoiceServerFrame = LiveVoiceReadyServerFrame | LiveVoiceBusyServerFrame | LiveVoiceSpeechStartedServerFrame | LiveVoiceUtteranceEndServerFrame | LiveVoiceUtteranceDiscardedServerFrame | LiveVoiceSttPartialServerFrame | LiveVoiceSttFinalServerFrame | LiveVoiceThinkingServerFrame | LiveVoiceAssistantTextDeltaServerFrame | LiveVoiceTtsAudioServerFrame | LiveVoiceTtsDoneServerFrame | LiveVoiceTurnCancelledServerFrame | LiveVoiceMetricsServerFrame | LiveVoiceArchivedServerFrame | LiveVoiceErrorServerFrame;
3864
+
3865
+ declare interface LiveVoiceServerFrameBase {
3866
+ readonly type: LiveVoiceServerFrameType;
3867
+ readonly seq: number;
3868
+ }
3869
+
3870
+ declare type LiveVoiceServerFrameType = (typeof _LIVE_VOICE_SERVER_FRAME_TYPES)[number];
3871
+
3872
+ export declare type LiveVoiceSessionCloseReason = "client_end" | "error" | "websocket_close" | "transport_closed" | "manager_shutdown";
3873
+
3874
+ /**
3875
+ * Emitted when the server VAD detects user speech. The client MUST
3876
+ * immediately stop local TTS playback — this doubles as the flush-tail-audio
3877
+ * signal (the in-app analog of the phone stack's buffered-audio clear).
3878
+ */
3879
+ declare interface LiveVoiceSpeechStartedServerFrame extends LiveVoiceServerFrameBase {
3880
+ readonly type: "speech_started";
3881
+ }
3882
+
3883
+ declare interface LiveVoiceSttFinalServerFrame extends LiveVoiceServerFrameBase {
3884
+ readonly type: "stt_final";
3885
+ readonly text: string;
3886
+ }
3887
+
3888
+ declare interface LiveVoiceSttPartialServerFrame extends LiveVoiceServerFrameBase {
3889
+ readonly type: "stt_partial";
3890
+ readonly text: string;
3891
+ }
3892
+
3893
+ declare interface LiveVoiceThinkingServerFrame extends LiveVoiceServerFrameBase {
3894
+ readonly type: "thinking";
3895
+ readonly turnId: string;
3896
+ }
3897
+
3898
+ declare interface LiveVoiceTtsAudioServerFrame extends LiveVoiceServerFrameBase {
3899
+ readonly type: "tts_audio";
3900
+ readonly mimeType: string;
3901
+ readonly sampleRate: number;
3902
+ readonly dataBase64: string;
3903
+ }
3904
+
3905
+ declare interface LiveVoiceTtsDoneServerFrame extends LiveVoiceServerFrameBase {
3906
+ readonly type: "tts_done";
3907
+ readonly turnId: string;
3908
+ }
3909
+
3910
+ /**
3911
+ * Emitted when an in-flight assistant turn is aborted by barge-in. The client
3912
+ * must drop any buffered tts_audio for that turn; no tts_done will follow.
3913
+ */
3914
+ declare interface LiveVoiceTurnCancelledServerFrame extends LiveVoiceServerFrameBase {
3915
+ readonly type: "turn_cancelled";
3916
+ readonly turnId: string;
3917
+ }
3918
+
3919
+ declare type LiveVoiceTurnDetectionMode = (typeof LIVE_VOICE_TURN_DETECTION_MODES)[number];
3920
+
3921
+ /**
3922
+ * Emitted only in server_vad mode when the closed utterance produced no
3923
+ * usable speech: it is dropped without an assistant turn and the client
3924
+ * should return to listening.
3925
+ */
3926
+ declare interface LiveVoiceUtteranceDiscardedServerFrame extends LiveVoiceServerFrameBase {
3927
+ readonly type: "utterance_discarded";
3928
+ }
3929
+
3930
+ /**
3931
+ * Emitted when the server VAD closes the utterance and the turn's
3932
+ * transcription begins (plays the role ptt_release plays in manual mode).
3933
+ */
3934
+ declare interface LiveVoiceUtteranceEndServerFrame extends LiveVoiceServerFrameBase {
3935
+ readonly type: "utterance_end";
3936
+ readonly reason: "silence" | "max-duration";
3937
+ }
3938
+
3664
3939
  export declare type LLMCallSite = z.infer<typeof LLMCallSiteEnum>;
3665
3940
 
3666
3941
  /**
@@ -3707,6 +3982,7 @@ declare const LLMCallSiteEnum: z.ZodEnum<{
3707
3982
  skillCategoryInference: "skillCategoryInference";
3708
3983
  inference: "inference";
3709
3984
  vision: "vision";
3985
+ voiceFrontDecision: "voiceFrontDecision";
3710
3986
  trustRuleSuggestion: "trustRuleSuggestion";
3711
3987
  homeGreeting: "homeGreeting";
3712
3988
  homeSuggestedPrompts: "homeSuggestedPrompts";
@@ -4665,6 +4941,13 @@ export declare interface ProviderResponse {
4665
4941
  model: string;
4666
4942
  /** Provider that actually produced this response, which may differ from a wrapper provider name. */
4667
4943
  actualProvider?: string;
4944
+ /**
4945
+ * Base URL the provider's HTTP client actually resolved to for this request,
4946
+ * read from the live SDK client instance rather than re-derived from config.
4947
+ * Lets diagnostics observe the true routing target (e.g. a misrouted host)
4948
+ * instead of inferring it. Absent for providers that don't surface it.
4949
+ */
4950
+ resolvedEndpoint?: string;
4668
4951
  usage: {
4669
4952
  /** Total input tokens (input_tokens + cache_creation + cache_read). */
4670
4953
  inputTokens: number;
@@ -4714,6 +4997,18 @@ declare interface PublishPageResponse {
4714
4997
  errorCode?: string;
4715
4998
  }
4716
4999
 
5000
+ /**
5001
+ * Remove every previously-refused exchange from a working history: for each
5002
+ * assistant message that is exactly the refusal fallback, drop it together with
5003
+ * the contiguous run back to (and including) the nearest genuine user prompt.
5004
+ * That excises the flagged prompt (and any tool exchange in that run) so the
5005
+ * provider never replays it. Returns a new array; the input is untouched.
5006
+ */
5007
+ export declare function quarantineRefusedExchanges(messages: Message[]): {
5008
+ messages: Message[];
5009
+ droppedExchanges: number;
5010
+ };
5011
+
4717
5012
  declare type QuestionRequestEvent = z.infer<typeof QuestionRequestEventSchema>;
4718
5013
 
4719
5014
  declare const QuestionRequestEventSchema: z.ZodObject<{
@@ -4785,6 +5080,19 @@ export declare interface RedactedThinkingContent {
4785
5080
  data: string;
4786
5081
  }
4787
5082
 
5083
+ /**
5084
+ * User-facing text a refusal turn is rewritten into (single source of truth for
5085
+ * both the producer — the empty-response plugin's `post-model-call` hook — and
5086
+ * the detector below).
5087
+ *
5088
+ * DETECTION COUPLING: `isRefusalFallbackMessage` matches this string exactly,
5089
+ * so it doubles as the quarantine marker for already-persisted transcripts.
5090
+ * Editing the wording silently stops the sweep from recognizing conversations
5091
+ * poisoned under the old wording (re-introducing the dead-end for that cohort).
5092
+ * If the copy must change, keep matching the historical variants too.
5093
+ */
5094
+ export declare const REFUSAL_FALLBACK_TEXT = "Sorry \u2014 I wasn't able to generate a response to that. Please try rephrasing or asking in a different way.";
5095
+
4788
5096
  declare type RelationshipStateUpdatedEvent = z.infer<typeof RelationshipStateUpdatedEventSchema>;
4789
5097
 
4790
5098
  declare const RelationshipStateUpdatedEventSchema: z.ZodObject<{
@@ -4792,6 +5100,99 @@ declare const RelationshipStateUpdatedEventSchema: z.ZodObject<{
4792
5100
  updatedAt: z.ZodString;
4793
5101
  }, z.core.$strip>;
4794
5102
 
5103
+ declare type ResolutionFallbackReason = "missing" | "disabled" | "incomplete";
5104
+
5105
+ /**
5106
+ * Resolves a fully-specified `LLMConfigBase` for a given call site.
5107
+ *
5108
+ * Selection is a single-winner chain (see `selectWinningProfile`): the
5109
+ * highest-precedence rung that names a usable, complete profile wins, and the
5110
+ * resolved config is composed as code-owned schema defaults + the winning
5111
+ * profile's fragment + the call site's own tuning tweak. No profile ever
5112
+ * contributes a field to another profile — `deepMerge` here only lets nested
5113
+ * tweaks (e.g. `thinking.enabled`) combine leaf-wise with the winner rather
5114
+ * than wholesale-replacing sibling fields.
5115
+ *
5116
+ * Precedence of the selection chain (high → low):
5117
+ * 1. `opts.overrideProfile` (per-turn / per-conversation pin)
5118
+ * 2. `llm.activeProfile` — `mainAgent` only, since it IS that call site's
5119
+ * user-facing chat-model selection
5120
+ * 3. `llm.callSites[callSite].profile` (the call site's named profile)
5121
+ * 4. `CALL_SITE_DEFAULTS[callSite].profile` intent resolved through
5122
+ * `llm.defaultProvider`
5123
+ * 5. balanced intent through `llm.defaultProvider` — the code-owned anchor
5124
+ * for profileless call sites, or when nothing above is usable
5125
+ *
5126
+ * A winner must carry its own `provider` AND `model`: the base layer's schema
5127
+ * default identity never stands in for a selected profile. The anchor is
5128
+ * code-owned and resolved through `llm.defaultProvider`, never through
5129
+ * user-mutable state.
5130
+ *
5131
+ * `temperature`/`top_p` come only from the winner (or an explicit call-site
5132
+ * tweak); `logitBias` only ever from the winner. These are provider-coupled, so
5133
+ * a shadowed profile can never leak its sampling onto a different provider.
5134
+ *
5135
+ * `opts.forceOverrideProfile` is a no-op here: the override profile already
5136
+ * sits at the top of the chain for every call site.
5137
+ *
5138
+ * Profile names are resolved against the effective profile catalog
5139
+ * (code-defined defaults + workspace `llm.profiles`; see `getEffectiveProfile`).
5140
+ * A "mix" profile is expanded to one of its arms by a seeded weighted pick (see
5141
+ * `resolveProfileFragment` and `opts.selectionSeed`), uniformly wherever a name
5142
+ * is dereferenced. Missing references silently fall through (no throw) so the
5143
+ * resolver stays pure; schema validation catches unknown static references at
5144
+ * config-load time.
5145
+ *
5146
+ * Nested objects (`thinking`, `contextWindow`, and
5147
+ * `contextWindow.overflowRecovery`) are deep-merged so partial tweaks at any
5148
+ * nesting level merge into — rather than replace — the corresponding base
5149
+ * value.
5150
+ *
5151
+ * Pure & synchronous: no I/O, no async work. (Random selection only occurs for
5152
+ * mix profiles when no `selectionSeed` is supplied; with a seed the pick is
5153
+ * deterministic.)
5154
+ */
5155
+ declare interface ResolveCallSiteOpts {
5156
+ overrideProfile?: string;
5157
+ /**
5158
+ * Float `overrideProfile` above the call-site layers for non-main-agent call
5159
+ * sites. Retained for API compatibility; under single-winner selection the
5160
+ * override already sits at the top of the chain, so this is effectively a
5161
+ * no-op. Inert when `overrideProfile` is absent or references a missing
5162
+ * profile.
5163
+ */
5164
+ forceOverrideProfile?: boolean;
5165
+ /**
5166
+ * Per-conversation seed for expanding `mix` profiles. The chosen constituent
5167
+ * is a deterministic function of `selectionSeed` + the mix profile's own
5168
+ * name, so every `resolveCallSiteConfig` call for the same conversation picks
5169
+ * the SAME arm (stable across turns, retries, and restarts). Pass the
5170
+ * conversation id. When absent, the resolver falls back to a fresh random
5171
+ * pick per call — acceptable only for one-shot/background call sites that
5172
+ * resolve config exactly once per invocation.
5173
+ */
5174
+ selectionSeed?: string;
5175
+ /**
5176
+ * Invoked once for each mix profile the resolver expands, reporting which
5177
+ * constituent was chosen. Used by A/B-eval recording (usage attribution).
5178
+ */
5179
+ onMixSelected?: (info: {
5180
+ mixProfile: string;
5181
+ chosenProfile: string;
5182
+ }) => void;
5183
+ /**
5184
+ * Invoked once per chain rung that named a profile the resolver could not
5185
+ * use, before resolution continues to the next rung. Fallback is silent to
5186
+ * the call but must be visible in logs — callers on user-facing paths should
5187
+ * log at warn.
5188
+ */
5189
+ onResolutionFallback?: (info: {
5190
+ callSite: LLMCallSite;
5191
+ requested: string;
5192
+ reason: ResolutionFallbackReason;
5193
+ }) => void;
5194
+ }
5195
+
4795
5196
  /**
4796
5197
  * Resolve a credential reference to its plaintext value.
4797
5198
  *
@@ -4925,6 +5326,15 @@ export declare interface RunConversationTurnOptions {
4925
5326
  * controller fires, terminating the in-flight agent loop.
4926
5327
  */
4927
5328
  signal?: AbortSignal;
5329
+ /**
5330
+ * Conversation type for newly created conversations. When omitted,
5331
+ * defaults to `"standard"` (visible in the sidebar). Set to
5332
+ * `"background"` for plugin-driven conversations that should not
5333
+ * appear in the sidebar's Recents grouping.
5334
+ *
5335
+ * Ignored when `conversationId` references an existing conversation.
5336
+ */
5337
+ conversationType?: "standard" | "background";
4928
5338
  }
4929
5339
 
4930
5340
  export declare interface RunConversationTurnResult {
@@ -5107,6 +5517,13 @@ export declare interface SendMessageConfig {
5107
5517
  * stripped before any provider wire request.
5108
5518
  */
5109
5519
  selectionSeed?: string;
5520
+ /**
5521
+ * Id of the user conversation that causally triggered this call, stamped by
5522
+ * call sites so `UsageTrackingProvider` can attribute the usage-ledger event
5523
+ * to the conversation (and, at flush time, its turn). A resolution/routing-
5524
+ * time concern only; stripped before any provider wire request.
5525
+ */
5526
+ conversationId?: string;
5110
5527
  /**
5111
5528
  * Per-conversation prompt-cache key for providers with explicit prompt
5112
5529
  * caching (sent as the OpenAI `prompt_cache_key` request param). Set by
@@ -5588,6 +6005,34 @@ declare type SurfaceData = CardSurfaceData | ChoiceSurfaceData | CopyBlockSurfac
5588
6005
 
5589
6006
  declare type _SurfacesServerMessages = UiSurfaceShow | UiSurfaceUpdate | UiSurfaceDismiss | UiSurfaceComplete | UiSurfaceUndoResult;
5590
6007
 
6008
+ /**
6009
+ * Delete `graph_node` Qdrant points whose backing `memory_graph_nodes` row no
6010
+ * longer exists.
6011
+ *
6012
+ * `embedAndUpsert` treats the `memory_embeddings` cache write as best-effort: on
6013
+ * a cache-write failure it logs and still upserts the Qdrant point, so a node
6014
+ * can end up with a `graph_node` point but no cache row. Migration 340 discovers
6015
+ * orphans only through cache rows, so those cacheless points survive its sweep;
6016
+ * once migration 323 hard-deletes their backing nodes they keep consuming
6017
+ * `searchGraphNodes` top-K slots (the query hydrates hits from
6018
+ * `memory_graph_nodes` and silently drops rows that are gone).
6019
+ *
6020
+ * This enumerates the authoritative set of indexed `graph_node` points straight
6021
+ * from Qdrant — the only place cacheless points are recorded — and deletes any
6022
+ * whose `target_id` has no row in `memory_graph_nodes`. Membership is
6023
+ * existence-based, matching migration 340: a soft-deleted node keeps its row
6024
+ * (`fidelity = 'gone'`) and therefore its point.
6025
+ *
6026
+ * Idempotent: a second run finds no orphans. Deletion is by Qdrant payload
6027
+ * (`target_type` + `target_id`) via `deleteByTarget`, so it removes cacheless
6028
+ * points a cache lookup could never surface. Both the initial scroll and each
6029
+ * delete go through the Qdrant circuit breaker: an already-open circuit surfaces
6030
+ * as `QdrantCircuitOpenError` so the caller (the memory worker) defers the sweep
6031
+ * instead of spending its bounded retries, and a transient failure propagates
6032
+ * for retry on a later cycle.
6033
+ */
6034
+ export declare function sweepOrphanedGraphNodePoints(qdrant: GraphNodeSweepClient): Promise<GraphNodeSweepResult>;
6035
+
5591
6036
  declare type SyncChangedEvent = z.infer<typeof SyncChangedEventSchema>;
5592
6037
 
5593
6038
  declare const SyncChangedEventSchema: z.ZodObject<{
@@ -6007,8 +6452,27 @@ export declare interface ToolExecutionResult {
6007
6452
  content: string;
6008
6453
  /** When true, the agent loop treats `content` as an error and may surface it / retry. */
6009
6454
  isError: boolean;
6455
+ /**
6456
+ * Stable, machine-readable classification for an error result (e.g.
6457
+ * `acp_claude_oauth_missing`). Threaded to the client on the `tool_result`
6458
+ * event so surfaces can render a structured affordance for a known failure
6459
+ * instead of re-parsing the human `content` string. Only meaningful when
6460
+ * `isError` is true.
6461
+ */
6462
+ errorCode?: string;
6010
6463
  /** Optional short status message for client display (e.g. `"truncated"`, `"timed out"`). */
6011
6464
  status?: string;
6465
+ /**
6466
+ * Typed side channel from the app-builder executors to their post-execution
6467
+ * side-effect hooks (`daemon/tool-side-effects.ts`): the exact app id the
6468
+ * executor operated on. `app_id` is optional for the fallback tools
6469
+ * (`app_update`, `app_refresh`, `app_generate_icon`) — when the model omits
6470
+ * it the skill script resolves the conversation's active app — so hooks read
6471
+ * this authoritative id instead of re-parsing the LLM-facing `content`
6472
+ * payload, whose shape must stay decoupled from daemon logic (see
6473
+ * assistant/AGENTS.md § Post-execution hooks). Set only by the app_* executors.
6474
+ */
6475
+ resolvedAppId?: string;
6012
6476
  /**
6013
6477
  * When true, the agent loop should yield control back to the user after
6014
6478
  * returning this result — tool results are pushed to history and the loop
@@ -6250,6 +6714,7 @@ declare const ToolResultEventSchema: z.ZodObject<{
6250
6714
  mayRequireJavaScript: z.ZodOptional<z.ZodBoolean>;
6251
6715
  }, z.core.$strip>>;
6252
6716
  }, z.core.$strip>>;
6717
+ errorCode: z.ZodOptional<z.ZodString>;
6253
6718
  completedAt: z.ZodOptional<z.ZodNumber>;
6254
6719
  }, z.core.$strip>;
6255
6720
 
package/index.js CHANGED
@@ -4,11 +4,13 @@ export const CLI_COMMAND_HELP = api.CLI_COMMAND_HELP;
4
4
  export const CredentialResolutionError = api.CredentialResolutionError;
5
5
  export const HOOKS = api.HOOKS;
6
6
  export const INTERNAL_NUDGE_OUTPUT_SUPPRESSION = api.INTERNAL_NUDGE_OUTPUT_SUPPRESSION;
7
+ export const REFUSAL_FALLBACK_TEXT = api.REFUSAL_FALLBACK_TEXT;
7
8
  export const RiskLevel = api.RiskLevel;
8
9
  export const TtsSynthesisError = api.TtsSynthesisError;
9
10
  export const addMessage = api.addMessage;
10
11
  export const assistantEventHub = api.assistantEventHub;
11
12
  export const buildMessageExcerpt = api.buildMessageExcerpt;
13
+ export const createLiveVoiceConnection = api.createLiveVoiceConnection;
12
14
  export const deleteConversation = api.deleteConversation;
13
15
  export const doesSupportVision = api.doesSupportVision;
14
16
  export const embedAndUpsert = api.embedAndUpsert;
@@ -19,13 +21,18 @@ export const getConversation = api.getConversation;
19
21
  export const getConversationDirPath = api.getConversationDirPath;
20
22
  export const getMessages = api.getMessages;
21
23
  export const getModelProfiles = api.getModelProfiles;
24
+ export const getWorkspaceDir = api.getWorkspaceDir;
22
25
  export const hasLexicalTokens = api.hasLexicalTokens;
23
26
  export const isConversationProcessing = api.isConversationProcessing;
24
27
  export const isMaxTokensStopReason = api.isMaxTokensStopReason;
28
+ export const isToolResultMessage = api.isToolResultMessage;
29
+ export const isVisionNotSupportedError = api.isVisionNotSupportedError;
30
+ export const lastToolResultUserMessageIndex = api.lastToolResultUserMessageIndex;
25
31
  export const listCatalogSkills = api.listCatalogSkills;
26
32
  export const listConversations = api.listConversations;
27
33
  export const listInstalledSkills = api.listInstalledSkills;
28
34
  export const parseMessageMetadata = api.parseMessageMetadata;
35
+ export const quarantineRefusedExchanges = api.quarantineRefusedExchanges;
29
36
  export const resolveCredential = api.resolveCredential;
30
37
  export const resolveMediaSourceData = api.resolveMediaSourceData;
31
38
  export const resolveUserName = api.resolveUserName;
@@ -33,6 +40,7 @@ export const runConversationTurn = api.runConversationTurn;
33
40
  export const searchMessageIdsLexical = api.searchMessageIdsLexical;
34
41
  export const selectedBackendSupportsMultimodal = api.selectedBackendSupportsMultimodal;
35
42
  export const stringifyMessageContent = api.stringifyMessageContent;
43
+ export const sweepOrphanedGraphNodePoints = api.sweepOrphanedGraphNodePoints;
36
44
  export const syncMessageToDisk = api.syncMessageToDisk;
37
45
  export const synthesizeText = api.synthesizeText;
38
46
  export const updateMessageMetadata = api.updateMessageMetadata;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vellumai/plugin-api",
3
- "version": "0.10.10",
3
+ "version": "0.10.11-dev.202607212222.fe33210",
4
4
  "description": "Public TypeScript authoring contract for Vellum assistant plugins.",
5
5
  "license": "MIT",
6
6
  "type": "module",