import { CodeTabs } from '../views/docs/CodeTabs';
import { NextLink } from '../views/docs/prose';

export const ON_QUESTION_SIG_PY = `@agent.on_question
def on_question(call: guava.Call, question: str) -> str:
    # question: natural-language question from the caller
    # return: answer to relay to caller
    ...`;

export const ON_QUESTION_SIG_TS = `agent.onQuestion(async (call: guava.Call, question: string) => string);`;

export const ON_QUESTION_EX_PY = `import guava
from guava import Agent
from guava.helpers.rag import DocumentQA
from guava.examples.example_data import PROPERTY_INSURANCE_POLICY

agent = Agent(
    organization="Harper Valley Property Insurance",
    purpose="Answer questions regarding property insurance policy",
)

document_qa = DocumentQA(documents=PROPERTY_INSURANCE_POLICY)

@agent.on_question
def on_question(call: guava.Call, question: str) -> str:
    return document_qa.ask(question)`;

export const ON_QUESTION_EX_TS = `import * as guava from "@guava-ai/guava-sdk";
import { DocumentQA } from "@guava-ai/guava-sdk/helpers/openai";
import { PROPERTY_INSURANCE_POLICY } from "@guava-ai/guava-sdk/example-data";

const agent = new guava.Agent({
  organization: "Harper Valley Property Insurance",
  purpose: "Answer questions regarding property insurance policy",
});

const documentQA = new DocumentQA(
  "harper-valley-property-insurance",
  PROPERTY_INSURANCE_POLICY,
);

agent.onQuestion(async (call: guava.Call, question: string) => {
  return await documentQA.ask(question);
});`;

## on\_question()

When a Guava agent is asked a question that it cannot answer from its context alone, it will invoke the `on_question` callback. Your **Expert** then has the chance to answer that question, typically using a RAG system. Our examples use the provided `DocumentQA` class, but you can use any RAG system you prefer.

See our [Q&A example](./inbound-rag-example) for a step-by-step walkthrough.

<CodeTabs
  python={{ code: ON_QUESTION_SIG_PY, filename: "signature" }}
  typescript={{ code: ON_QUESTION_SIG_TS, filename: "signature" }}
/>

> If you want the agent to answer questions immediately, use `add_info` to pre-emptively add information to the context.

- `on_question`, like all Guava callbacks, is invoked asynchronously and does not block dialog. The Guava voice agent continues to engage the caller until the question answer comes back.
- `on_question` may be invoked multiple times, for example, if a caller asks a question and then refines it. `on_question` may be invoked speculatively before a caller is done talking.
- `on_question` may be invoked simultaneously with [`on_action_request`](./on-action-request-execute), as some requests can be both an "action" and a "question". For example, *"Do you have a lost and found?"* In this case, the agent will synthesize both responses: *"Yes, we have a lost and found. Would you like me to transfer you there?"*



### Example

<CodeTabs
  python={{ code: ON_QUESTION_EX_PY, filename: "support_controller.py" }}
  typescript={{ code: ON_QUESTION_EX_TS, filename: "support_controller.ts" }}
/>

<NextLink section="on-agent-speech" label="on_agent_speech()" />
