import { Type } from "typebox"; import { formatAskResult, formatAuthError, formatBillingError, formatUnavailableError, formatGenericError, formatApiKeyMissingError, formatRateLimitError } from "../format"; export function makeAskTool(store) { return { name: "alchemyst_context_ask", label: "Alchemyst Context Ask", description: "Ask a question grounded in AlchemystAI's Context Layer and get a synthesized answer (not raw chunks). Use for quick factual lookups; use `alchemyst_context_search` instead when you want to see and judge the underlying source chunks yourself.", parameters: Type.Object({ query: Type.String({ description: "Natural language question to ask against stored context" }), steeringPrompt: Type.Optional(Type.String()), scope: Type.Optional( Type.Union([ Type.Literal("internal"), Type.Literal("external"), ]) ), similarity_threshold: Type.Optional(Type.Number({ description: "Maximum similarity threshold (0-1)" })), minimum_similarity_threshold: Type.Optional( Type.Number({ description: "Minimum similarity threshold (0-1)" }) ), }), async execute(_toolCallId, params) { if (!store.client) { return { content: [{ type: "text", text: formatApiKeyMissingError() }], details: {}, }; } const result = await store.client.ask({ query: params.query, similarity_threshold: params.similarity_threshold ?? 0.8, minimum_similarity_threshold: params.minimum_similarity_threshold ?? 0.5, scope: params.scope ?? "internal", ...(params.steeringPrompt ? { steeringPrompt: params.steeringPrompt } : {}), }); if (!result.ok) { if (result.status === 401 || result.status === 403) return { content: [{ type: "text", text: formatAuthError() }], details: {}, }; if (result.status === 402) return { content: [{ type: "text", text: formatBillingError() }], details: {}, }; if (result.status === 429) return { content: [{ type: "text", text: formatRateLimitError() }], details: {}, }; if (result.status && result.status >= 500) return { content: [{ type: "text", text: formatUnavailableError() }], details: {}, }; return { content: [{ type: "text", text: formatGenericError(result.error) }], details: {}, }; } return { content: [{ type: "text", text: formatAskResult(result.data.answer) }], details: { usage: result.data.usage }, }; }, }; }