fix: preprompt would show after loading session (#8744)
Signed-off-by: Matt Toohey <contact@matttoohey.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -28,28 +28,31 @@ use crate::providers::inventory::{
|
|||||||
};
|
};
|
||||||
use crate::session::session_manager::SessionType;
|
use crate::session::session_manager::SessionType;
|
||||||
use crate::session::{EnabledExtensionsState, Session, SessionManager};
|
use crate::session::{EnabledExtensionsState, Session, SessionManager};
|
||||||
|
use crate::utils::sanitize_unicode_tags;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use fs_err as fs;
|
use fs_err as fs;
|
||||||
use futures::future::{BoxFuture, Either};
|
use futures::future::{BoxFuture, Either};
|
||||||
use goose_acp_macros::custom_methods;
|
use goose_acp_macros::custom_methods;
|
||||||
use rmcp::model::{CallToolResult, RawContent, ResourceContents, Role};
|
use rmcp::model::{
|
||||||
|
AnnotateAble, CallToolResult, RawContent, RawTextContent, ResourceContents, Role,
|
||||||
|
};
|
||||||
use sacp::schema::{
|
use sacp::schema::{
|
||||||
AgentCapabilities, AuthMethod, AuthMethodAgent, AuthenticateRequest, AuthenticateResponse,
|
AgentCapabilities, Annotations, AuthMethod, AuthMethodAgent, AuthenticateRequest,
|
||||||
BlobResourceContents, CancelNotification, CloseSessionRequest, CloseSessionResponse,
|
AuthenticateResponse, BlobResourceContents, CancelNotification, CloseSessionRequest,
|
||||||
ConfigOptionUpdate, Content, ContentBlock, ContentChunk, CurrentModeUpdate, EmbeddedResource,
|
CloseSessionResponse, ConfigOptionUpdate, Content, ContentBlock, ContentChunk,
|
||||||
EmbeddedResourceResource, FileSystemCapabilities, ForkSessionRequest, ForkSessionResponse,
|
CurrentModeUpdate, EmbeddedResource, EmbeddedResourceResource, FileSystemCapabilities,
|
||||||
ImageContent, InitializeRequest, InitializeResponse, ListSessionsRequest, ListSessionsResponse,
|
ForkSessionRequest, ForkSessionResponse, ImageContent, InitializeRequest, InitializeResponse,
|
||||||
LoadSessionRequest, LoadSessionResponse, McpCapabilities, McpServer, Meta, ModelId, ModelInfo,
|
ListSessionsRequest, ListSessionsResponse, LoadSessionRequest, LoadSessionResponse,
|
||||||
NewSessionRequest, NewSessionResponse, PermissionOption, PermissionOptionKind,
|
McpCapabilities, McpServer, Meta, ModelId, ModelInfo, NewSessionRequest, NewSessionResponse,
|
||||||
PromptCapabilities, PromptRequest, PromptResponse, RequestPermissionOutcome,
|
PermissionOption, PermissionOptionKind, PromptCapabilities, PromptRequest, PromptResponse,
|
||||||
RequestPermissionRequest, ResourceLink, SessionCapabilities, SessionCloseCapabilities,
|
RequestPermissionOutcome, RequestPermissionRequest, ResourceLink, SessionCapabilities,
|
||||||
SessionConfigOption, SessionConfigOptionCategory, SessionConfigSelectOption, SessionId,
|
SessionCloseCapabilities, SessionConfigOption, SessionConfigOptionCategory,
|
||||||
SessionInfo, SessionListCapabilities, SessionMode, SessionModeId, SessionModeState,
|
SessionConfigSelectOption, SessionId, SessionInfo, SessionListCapabilities, SessionMode,
|
||||||
SessionModelState, SessionNotification, SessionUpdate, SetSessionConfigOptionRequest,
|
SessionModeId, SessionModeState, SessionModelState, SessionNotification, SessionUpdate,
|
||||||
SetSessionConfigOptionResponse, SetSessionModeRequest, SetSessionModeResponse,
|
SetSessionConfigOptionRequest, SetSessionConfigOptionResponse, SetSessionModeRequest,
|
||||||
SetSessionModelRequest, SetSessionModelResponse, StopReason, TextContent, TextResourceContents,
|
SetSessionModeResponse, SetSessionModelRequest, SetSessionModelResponse, StopReason,
|
||||||
ToolCall, ToolCallContent, ToolCallId, ToolCallLocation, ToolCallStatus, ToolCallUpdate,
|
TextContent, TextResourceContents, ToolCall, ToolCallContent, ToolCallId, ToolCallLocation,
|
||||||
ToolCallUpdateFields, ToolKind, Usage, UsageUpdate,
|
ToolCallStatus, ToolCallUpdate, ToolCallUpdateFields, ToolKind, Usage, UsageUpdate,
|
||||||
};
|
};
|
||||||
use sacp::util::MatchDispatchFrom;
|
use sacp::util::MatchDispatchFrom;
|
||||||
use sacp::{
|
use sacp::{
|
||||||
@@ -1155,16 +1158,49 @@ impl GooseAcpAgent {
|
|||||||
self.sessions.lock().await.contains_key(session_id)
|
self.sessions.lock().await.contains_key(session_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_acp_prompt_to_message(&self, prompt: Vec<ContentBlock>) -> Message {
|
/// Convert ACP prompt content blocks into a user message.
|
||||||
let mut user_message = Message::user();
|
fn convert_acp_prompt_to_message(prompt: &[ContentBlock]) -> Message {
|
||||||
|
let mut message = Message::user();
|
||||||
for block in prompt {
|
for block in prompt {
|
||||||
match block {
|
match block {
|
||||||
ContentBlock::Text(text) => {
|
ContentBlock::Text(text) => {
|
||||||
user_message = user_message.with_text(&text.text);
|
let annotated = if let Some(ref ann) = text.annotations {
|
||||||
|
let audience: Vec<Role> = ann
|
||||||
|
.audience
|
||||||
|
.as_ref()
|
||||||
|
.map(|roles| {
|
||||||
|
roles
|
||||||
|
.iter()
|
||||||
|
.filter_map(|r| match r {
|
||||||
|
sacp::schema::Role::Assistant => Some(Role::Assistant),
|
||||||
|
sacp::schema::Role::User => Some(Role::User),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
.unwrap_or_default();
|
||||||
|
let raw = RawTextContent {
|
||||||
|
text: sanitize_unicode_tags(&text.text),
|
||||||
|
meta: None,
|
||||||
|
};
|
||||||
|
if audience.is_empty() {
|
||||||
|
raw.no_annotation()
|
||||||
|
} else {
|
||||||
|
raw.no_annotation().with_audience(audience)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No annotations — regular user text.
|
||||||
|
let sanitized = sanitize_unicode_tags(&text.text);
|
||||||
|
RawTextContent {
|
||||||
|
text: sanitized,
|
||||||
|
meta: None,
|
||||||
|
}
|
||||||
|
.no_annotation()
|
||||||
|
};
|
||||||
|
message = message.with_content(MessageContent::Text(annotated));
|
||||||
}
|
}
|
||||||
ContentBlock::Image(image) => {
|
ContentBlock::Image(image) => {
|
||||||
user_message = user_message.with_image(&image.data, &image.mime_type);
|
message = message.with_image(&image.data, &image.mime_type);
|
||||||
}
|
}
|
||||||
ContentBlock::Resource(resource) => {
|
ContentBlock::Resource(resource) => {
|
||||||
if let EmbeddedResourceResource::TextResourceContents(text_resource) =
|
if let EmbeddedResourceResource::TextResourceContents(text_resource) =
|
||||||
@@ -1172,19 +1208,18 @@ impl GooseAcpAgent {
|
|||||||
{
|
{
|
||||||
let header = format!("--- Resource: {} ---\n", text_resource.uri);
|
let header = format!("--- Resource: {} ---\n", text_resource.uri);
|
||||||
let content = format!("{}{}\n---\n", header, text_resource.text);
|
let content = format!("{}{}\n---\n", header, text_resource.text);
|
||||||
user_message = user_message.with_text(&content);
|
message = message.with_text(&content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ContentBlock::ResourceLink(link) => {
|
ContentBlock::ResourceLink(link) => {
|
||||||
if let Some(text) = read_resource_link(link) {
|
if let Some(text) = read_resource_link(link.clone()) {
|
||||||
user_message = user_message.with_text(text)
|
message = message.with_text(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ContentBlock::Audio(..) | _ => (),
|
ContentBlock::Audio(..) | _ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
message
|
||||||
user_message
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_message_content(
|
async fn handle_message_content(
|
||||||
@@ -1943,9 +1978,21 @@ impl GooseAcpAgent {
|
|||||||
for content_item in &message.content {
|
for content_item in &message.content {
|
||||||
match content_item {
|
match content_item {
|
||||||
MessageContent::Text(text) => {
|
MessageContent::Text(text) => {
|
||||||
let chunk = ContentChunk::new(ContentBlock::Text(TextContent::new(
|
let mut tc = TextContent::new(text.text.clone());
|
||||||
text.text.clone(),
|
if let Some(audience) = text.audience() {
|
||||||
)));
|
tc = tc.annotations(
|
||||||
|
Annotations::new().audience(
|
||||||
|
audience
|
||||||
|
.iter()
|
||||||
|
.map(|r| match r {
|
||||||
|
Role::Assistant => sacp::schema::Role::Assistant,
|
||||||
|
Role::User => sacp::schema::Role::User,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let chunk = ContentChunk::new(ContentBlock::Text(tc));
|
||||||
let update = match message.role {
|
let update = match message.role {
|
||||||
Role::User => SessionUpdate::UserMessageChunk(chunk),
|
Role::User => SessionUpdate::UserMessageChunk(chunk),
|
||||||
Role::Assistant => SessionUpdate::AgentMessageChunk(chunk),
|
Role::Assistant => SessionUpdate::AgentMessageChunk(chunk),
|
||||||
@@ -2150,9 +2197,10 @@ impl GooseAcpAgent {
|
|||||||
.await?;
|
.await?;
|
||||||
debug!(target: "perf", sid = %sid, ms = t_agent.elapsed().as_millis() as u64, "perf: prompt get_session_agent (waits for agent setup)");
|
debug!(target: "perf", sid = %sid, ms = t_agent.elapsed().as_millis() as u64, "perf: prompt get_session_agent (waits for agent setup)");
|
||||||
|
|
||||||
let user_message = self.convert_acp_prompt_to_message(args.prompt);
|
let user_message = Self::convert_acp_prompt_to_message(&args.prompt);
|
||||||
|
|
||||||
let t_persist = std::time::Instant::now();
|
let t_persist = std::time::Instant::now();
|
||||||
|
// Persist user message (may contain assistant-only annotated blocks)
|
||||||
self.thread_manager
|
self.thread_manager
|
||||||
.append_message(&thread_id, Some(&internal_session_id), &user_message)
|
.append_message(&thread_id, Some(&internal_session_id), &user_message)
|
||||||
.await
|
.await
|
||||||
|
|||||||
@@ -97,6 +97,14 @@ interface ContentSection {
|
|||||||
items: MessageContent[] | ToolChainItem[];
|
items: MessageContent[] | ToolChainItem[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Keep only content blocks whose audience includes "user" (or has no audience). */
|
||||||
|
function filterUserVisibleContent(content: MessageContent[]): MessageContent[] {
|
||||||
|
return content.filter((b) => {
|
||||||
|
const aud = b.annotations?.audience;
|
||||||
|
return !aud || aud.length === 0 || aud.includes("user");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function findMatchingToolChainIndex(
|
function findMatchingToolChainIndex(
|
||||||
items: ToolChainItem[],
|
items: ToolChainItem[],
|
||||||
response: ToolResponseContent,
|
response: ToolResponseContent,
|
||||||
@@ -224,29 +232,17 @@ function renderContentBlock(
|
|||||||
case "toolResponse":
|
case "toolResponse":
|
||||||
// Handled by groupContentSections toolChain rendering
|
// Handled by groupContentSections toolChain rendering
|
||||||
return null;
|
return null;
|
||||||
case "thinking": {
|
case "thinking":
|
||||||
const th = content as ThinkingContent;
|
|
||||||
return (
|
|
||||||
<Reasoning
|
|
||||||
key={`thinking-${index}`}
|
|
||||||
isStreaming={isStreamingMsg}
|
|
||||||
defaultOpen={false}
|
|
||||||
>
|
|
||||||
<ReasoningTrigger />
|
|
||||||
<ReasoningContent>{th.text}</ReasoningContent>
|
|
||||||
</Reasoning>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
case "reasoning": {
|
case "reasoning": {
|
||||||
const r = content as ReasoningContentType;
|
const text = (content as ThinkingContent | ReasoningContentType).text;
|
||||||
return (
|
return (
|
||||||
<Reasoning
|
<Reasoning
|
||||||
key={`reasoning-${index}`}
|
key={`${content.type}-${index}`}
|
||||||
isStreaming={isStreamingMsg}
|
isStreaming={isStreamingMsg}
|
||||||
defaultOpen={false}
|
defaultOpen={false}
|
||||||
>
|
>
|
||||||
<ReasoningTrigger />
|
<ReasoningTrigger />
|
||||||
<ReasoningContent>{r.text}</ReasoningContent>
|
<ReasoningContent>{text}</ReasoningContent>
|
||||||
</Reasoning>
|
</Reasoning>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -318,7 +314,10 @@ export const MessageBubble = memo(function MessageBubble({
|
|||||||
}: MessageBubbleProps) {
|
}: MessageBubbleProps) {
|
||||||
const { t } = useTranslation(["chat", "common"]);
|
const { t } = useTranslation(["chat", "common"]);
|
||||||
const { formatDate } = useLocaleFormatting();
|
const { formatDate } = useLocaleFormatting();
|
||||||
const { role, content, created } = message;
|
const { role, content: rawContent, created } = message;
|
||||||
|
// Only user messages carry annotated blocks; skip the filter for others.
|
||||||
|
const content =
|
||||||
|
role === "user" ? filterUserVisibleContent(rawContent) : rawContent;
|
||||||
const { handleContentClick, pathNotice } = useArtifactLinkHandler();
|
const { handleContentClick, pathNotice } = useArtifactLinkHandler();
|
||||||
const persona = useAgentStore((state) =>
|
const persona = useAgentStore((state) =>
|
||||||
message.metadata?.personaId
|
message.metadata?.personaId
|
||||||
@@ -328,6 +327,9 @@ export const MessageBubble = memo(function MessageBubble({
|
|||||||
const { isCopied: isCopyConfirmed, copyToClipboard } = useCopyToClipboard();
|
const { isCopied: isCopyConfirmed, copyToClipboard } = useCopyToClipboard();
|
||||||
const personaAvatarUrl = useAvatarSrc(persona?.avatar);
|
const personaAvatarUrl = useAvatarSrc(persona?.avatar);
|
||||||
|
|
||||||
|
// Skip empty user bubbles (all blocks filtered as assistant-only).
|
||||||
|
if (role === "user" && content.length === 0) return null;
|
||||||
|
|
||||||
const textContent = content
|
const textContent = content
|
||||||
.filter((c): c is TextContent => c.type === "text")
|
.filter((c): c is TextContent => c.type === "text")
|
||||||
.map((c) => c.text)
|
.map((c) => c.text)
|
||||||
@@ -347,7 +349,6 @@ export const MessageBubble = memo(function MessageBubble({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const isUser = role === "user";
|
const isUser = role === "user";
|
||||||
const assistantProviderId = message.metadata?.providerId;
|
const assistantProviderId = message.metadata?.providerId;
|
||||||
const assistantProviderName = assistantProviderId
|
const assistantProviderName = assistantProviderId
|
||||||
|
|||||||
@@ -73,12 +73,15 @@ export async function acpSendMessage(
|
|||||||
throw new Error("Session not prepared. Call acpPrepareSession first.");
|
throw new Error("Session not prepared. Call acpPrepareSession first.");
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasSystem = systemPrompt && systemPrompt.trim().length > 0;
|
const content: ContentBlock[] = [];
|
||||||
const effectivePrompt = hasSystem
|
if (systemPrompt?.trim()) {
|
||||||
? `<persona-instructions>\n${systemPrompt}\n</persona-instructions>\n\n<user-message>\n${prompt}\n</user-message>`
|
content.push({
|
||||||
: prompt;
|
type: "text",
|
||||||
|
text: systemPrompt,
|
||||||
const content: ContentBlock[] = [{ type: "text", text: effectivePrompt }];
|
annotations: { audience: ["assistant"] },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
content.push({ type: "text", text: prompt });
|
||||||
if (images) {
|
if (images) {
|
||||||
for (const [data, mimeType] of images) {
|
for (const [data, mimeType] of images) {
|
||||||
content.push({ type: "image", data, mimeType } as ContentBlock);
|
content.push({ type: "image", data, mimeType } as ContentBlock);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
findLatestUnpairedToolRequest,
|
findLatestUnpairedToolRequest,
|
||||||
} from "@/features/chat/hooks/replayBuffer";
|
} from "@/features/chat/hooks/replayBuffer";
|
||||||
import type {
|
import type {
|
||||||
|
TextContent,
|
||||||
ToolRequestContent,
|
ToolRequestContent,
|
||||||
ToolResponseContent,
|
ToolResponseContent,
|
||||||
} from "@/shared/types/messages";
|
} from "@/shared/types/messages";
|
||||||
@@ -196,32 +197,32 @@ function handleReplay(sessionId: string, update: SessionUpdate): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "user_message_chunk": {
|
case "user_message_chunk": {
|
||||||
|
if (update.content.type !== "text" || !("text" in update.content)) break;
|
||||||
const messageId = update.messageId ?? crypto.randomUUID();
|
const messageId = update.messageId ?? crypto.randomUUID();
|
||||||
const buffer = ensureReplayBuffer(sessionId);
|
const buffer = ensureReplayBuffer(sessionId);
|
||||||
const existing = getBufferedMessage(sessionId, messageId);
|
const existing = getBufferedMessage(sessionId, messageId);
|
||||||
|
// biome-ignore lint/suspicious/noExplicitAny: wire format has annotations but SDK types don't
|
||||||
|
const rawAnn = (update.content as any).annotations;
|
||||||
|
const ann: TextContent["annotations"] | undefined =
|
||||||
|
typeof rawAnn === "object" && rawAnn !== null ? rawAnn : undefined;
|
||||||
|
// Drop assistant-only blocks so they never enter chat state.
|
||||||
if (
|
if (
|
||||||
!existing &&
|
ann?.audience &&
|
||||||
update.content.type === "text" &&
|
ann.audience.length > 0 &&
|
||||||
"text" in update.content
|
!ann.audience.includes("user")
|
||||||
) {
|
)
|
||||||
|
break;
|
||||||
|
const textBlock = makeTextBlock(update.content.text, ann);
|
||||||
|
if (!existing) {
|
||||||
buffer.push({
|
buffer.push({
|
||||||
id: messageId,
|
id: messageId,
|
||||||
role: "user",
|
role: "user",
|
||||||
created: Date.now(),
|
created: Date.now(),
|
||||||
content: [{ type: "text", text: update.content.text }],
|
content: [textBlock],
|
||||||
metadata: { userVisible: true, agentVisible: true },
|
metadata: { userVisible: true, agentVisible: true },
|
||||||
});
|
});
|
||||||
} else if (
|
} else {
|
||||||
existing &&
|
existing.content.push(textBlock);
|
||||||
update.content.type === "text" &&
|
|
||||||
"text" in update.content
|
|
||||||
) {
|
|
||||||
const last = existing.content[existing.content.length - 1];
|
|
||||||
if (last?.type === "text") {
|
|
||||||
(last as { type: "text"; text: string }).text += update.content.text;
|
|
||||||
} else {
|
|
||||||
existing.content.push({ type: "text", text: update.content.text });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -486,6 +487,13 @@ function findStreamingMessageId(sessionId: string): string | null {
|
|||||||
.streamingMessageId;
|
.streamingMessageId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function makeTextBlock(
|
||||||
|
text: string,
|
||||||
|
ann?: TextContent["annotations"],
|
||||||
|
): TextContent {
|
||||||
|
return { type: "text", text, ...(ann ? { annotations: ann } : {}) };
|
||||||
|
}
|
||||||
|
|
||||||
function findMessageInBuffer(
|
function findMessageInBuffer(
|
||||||
sessionId: string,
|
sessionId: string,
|
||||||
_toolCallId: string,
|
_toolCallId: string,
|
||||||
|
|||||||
@@ -33,10 +33,19 @@ export type ChatAttachmentDraft =
|
|||||||
// Message roles
|
// Message roles
|
||||||
export type MessageRole = "user" | "assistant" | "system";
|
export type MessageRole = "user" | "assistant" | "system";
|
||||||
|
|
||||||
|
/** ACP audience restriction — which roles may see a content block. */
|
||||||
|
export type Audience = ("user" | "assistant")[];
|
||||||
|
|
||||||
|
/** ACP content-block annotations (mirrors the SDK's Annotations shape). */
|
||||||
|
export interface ContentAnnotations {
|
||||||
|
audience?: Audience;
|
||||||
|
}
|
||||||
|
|
||||||
// Content block types
|
// Content block types
|
||||||
export interface TextContent {
|
export interface TextContent {
|
||||||
type: "text";
|
type: "text";
|
||||||
text: string;
|
text: string;
|
||||||
|
annotations?: ContentAnnotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ImageContent {
|
export interface ImageContent {
|
||||||
@@ -44,6 +53,7 @@ export interface ImageContent {
|
|||||||
source:
|
source:
|
||||||
| { type: "base64"; mediaType: string; data: string }
|
| { type: "base64"; mediaType: string; data: string }
|
||||||
| { type: "url"; url: string };
|
| { type: "url"; url: string };
|
||||||
|
annotations?: ContentAnnotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ToolCallStatus =
|
export type ToolCallStatus =
|
||||||
@@ -67,6 +77,7 @@ export interface ToolRequestContent {
|
|||||||
status: ToolCallStatus;
|
status: ToolCallStatus;
|
||||||
/** Epoch ms when the tool call started executing (set on event receipt). */
|
/** Epoch ms when the tool call started executing (set on event receipt). */
|
||||||
startedAt?: number;
|
startedAt?: number;
|
||||||
|
annotations?: ContentAnnotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ToolResponseContent {
|
export interface ToolResponseContent {
|
||||||
@@ -75,20 +86,24 @@ export interface ToolResponseContent {
|
|||||||
name: string;
|
name: string;
|
||||||
result: string;
|
result: string;
|
||||||
isError: boolean;
|
isError: boolean;
|
||||||
|
annotations?: ContentAnnotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ThinkingContent {
|
export interface ThinkingContent {
|
||||||
type: "thinking";
|
type: "thinking";
|
||||||
text: string;
|
text: string;
|
||||||
|
annotations?: ContentAnnotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RedactedThinkingContent {
|
export interface RedactedThinkingContent {
|
||||||
type: "redactedThinking";
|
type: "redactedThinking";
|
||||||
|
annotations?: ContentAnnotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ReasoningContent {
|
export interface ReasoningContent {
|
||||||
type: "reasoning";
|
type: "reasoning";
|
||||||
text: string;
|
text: string;
|
||||||
|
annotations?: ContentAnnotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ActionRequiredContent {
|
export interface ActionRequiredContent {
|
||||||
@@ -99,12 +114,14 @@ export interface ActionRequiredContent {
|
|||||||
toolName?: string;
|
toolName?: string;
|
||||||
arguments?: Record<string, unknown>;
|
arguments?: Record<string, unknown>;
|
||||||
schema?: Record<string, unknown>;
|
schema?: Record<string, unknown>;
|
||||||
|
annotations?: ContentAnnotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SystemNotificationContent {
|
export interface SystemNotificationContent {
|
||||||
type: "systemNotification";
|
type: "systemNotification";
|
||||||
notificationType: "compaction" | "info" | "warning" | "error";
|
notificationType: "compaction" | "info" | "warning" | "error";
|
||||||
text: string;
|
text: string;
|
||||||
|
annotations?: ContentAnnotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MessageContent =
|
export type MessageContent =
|
||||||
|
|||||||
Reference in New Issue
Block a user