import { tool } from "ai";
import { z } from "zod/v3";
const askHuman = tool({
description: "Ask a human a question",
parameters: z.object({
question: z.string().describe("The question to ask the human"),
}),
});
export const ask = action({
args: { question: v.string(), threadId: v.string() },
handler: async (ctx, { question, threadId }) => {
const result = await agent.generateText(
ctx,
{ threadId },
{
prompt: question,
tools: { askHuman },
},
);
const supportRequests = result.toolCalls
.filter((tc) => tc.toolName === "askHuman")
.map(({ toolCallId, args: { question } }) => ({
toolCallId,
question,
}));
if (supportRequests.length > 0) {
// Do something so the support agent knows they need to respond,
// e.g. save a message to their inbox
// await ctx.runMutation(internal.example.sendToSupport, {
// threadId,
// supportRequests,
// });
}
},
});
export const humanResponseAsToolCall = internalAction({
args: {
humanName: v.string(),
response: v.string(),
toolCallId: v.string(),
threadId: v.string(),
messageId: v.string(),
},
handler: async (ctx, args) => {
await agent.saveMessage(ctx, {
threadId: args.threadId,
message: {
role: "tool",
content: [
{
type: "tool-result",
result: args.response,
toolCallId: args.toolCallId,
toolName: "askHuman",
},
],
},
metadata: {
provider: "human",
providerMetadata: {
human: { name: args.humanName },
},
},
});
// Continue generating a response from the LLM
await agent.generateText(
ctx,
{ threadId: args.threadId },
{
promptMessageId: args.messageId,
},
);
},
});