import { fileSearchTool, webSearchTool, hostedMcpTool, codeInterpreterTool, Agent, AgentInputItem, Runner, withTrace } from "@openai/agents";
import { z } from "zod";
// Tool definitions
const fileSearch = fileSearchTool([
"vs_68e51f55b1008191ae15fe41ae140e85"
])
const webSearchPreview = webSearchTool({
searchContextSize: "medium",
userLocation: {
type: "approximate"
}
})
const mcp = hostedMcpTool({
serverLabel: "googledrive",
allowedTools: [
"fetch",
"get_profile",
"list_drives",
"recent_documents",
"search"
],
authorization: "REDACTED",
connectorId: "connector_googledrive",
requireApproval: "always",
serverDescription: "Онбординг"
})
const codeInterpreter = codeInterpreterTool({
container: {
type: "auto",
file_ids: []
}
})
const ClassifySchema = z.object({ operating_procedure: z.enum(["q-and-a", "fact-finding", "other"]) });
const queryRewrite = new Agent({
name: "Query rewrite",
instructions: "Rewrite the user's question to be more specific and relevant to the knowledge base.",
model: "gpt-5-nano",
modelSettings: {
reasoning: {
effort: "low",
summary: "auto"
},
store: true
}
});
const classify = new Agent({
name: "Classify",
instructions: `Determine whether the question should use the Q&A or fact-finding process.
You are a helpful onboarding classifier. Decide what category the employee’s question belongs to. `,
model: "gpt-5-nano",
outputType: ClassifySchema,
modelSettings: {
reasoning: {
effort: "low",
summary: "auto"
},
store: true
}
});
const internalQA = new Agent({
name: "Internal Q&A",
instructions: "Answer the user's question using the knowledge tools you have on hand (file or web search). Be concise and answer succinctly, using bullet points and summarizing the answer up front",
model: "gpt-5",
tools: [
fileSearch,
webSearchPreview,
mcp
],
modelSettings: {
reasoning: {
effort: "low",
summary: "auto"
},
store: true
}
});
const externalFactFinding = new Agent({
name: "External fact finding",
instructions: `Explore external information using the tools you have (web search, file search, code interpreter).
Analyze any relevant data, checking your work.
Make sure to output a concise answer followed by summarized bullet point of supporting evidence`,
model: "gpt-5",
tools: [
fileSearch,
webSearchPreview,
codeInterpreter,
mcp
],
modelSettings: {
reasoning: {
effort: "low",
summary: "auto"
},
store: true
}
});
type WorkflowInput = { input_as_text: string };
// Main code entrypoint
export const runWorkflow = async (workflow: WorkflowInput) => {
return await withTrace("New workflow", async () => {
const state = {
a: "{ \"employee_name\": \"string\", \"department\": \"string\", \"day_number\": \"number\", \"question\": \"string\" }"
};
const conversationHistory: AgentInputItem[] = [
{
role: "user",
content: [
{
type: "input_text",
text: workflow.input_as_text
}
]
}
];
const runner = new Runner({
traceMetadata: {
__trace_source__: "agent-builder",
workflow_id: "wf_68e51947d02881909f6bedc945eef3ba058eaaabb6388b4d"
}
});
const queryRewriteResultTemp = await runner.run(
queryRewrite,
[
...conversationHistory,
{
role: "user",
content: [
{
type: "input_text",
text: `Original question: ${workflow.input_as_text}`
}
]
}
]
);
conversationHistory.push(...queryRewriteResultTemp.newItems.map((item) => item.rawItem));
if (!queryRewriteResultTemp.finalOutput) {
throw new Error("Agent result is undefined");
}
const queryRewriteResult = {
output_text: queryRewriteResultTemp.finalOutput ?? ""
};
const classifyResultTemp = await runner.run(
classify,
[
...conversationHistory,
{
role: "user",
content: [
{
type: "input_text",
text: `Question: ${queryRewriteResult.output_text}`
}
]
}
]
);
conversationHistory.push(...classifyResultTemp.newItems.map((item) => item.rawItem));
if (!classifyResultTemp.finalOutput) {
throw new Error("Agent result is undefined");
}
const classifyResult = {
output_text: JSON.stringify(classifyResultTemp.finalOutput),
output_parsed: classifyResultTemp.finalOutput
};
if (classifyResult.output_parsed.operating_procedure == "q-and-a") {
const internalQAResultTemp = await runner.run(
internalQA,
[
...conversationHistory
]
);
conversationHistory.push(...internalQAResultTemp.newItems.map((item) => item.rawItem));
if (!internalQAResultTemp.finalOutput) {
throw new Error("Agent result is undefined");
}
const internalQAResult = {
output_text: internalQAResultTemp.finalOutput ?? ""
};
const endResult = {
output_text: internalQAResult.output_text
};
return endResult;
} else if (classifyResult.output_parsed.operating_procedure == "fact-finding") {
const externalFactFindingResultTemp = await runner.run(
externalFactFinding,
[
...conversationHistory
]
);
conversationHistory.push(...externalFactFindingResultTemp.newItems.map((item) => item.rawItem));
if (!externalFactFindingResultTemp.finalOutput) {
throw new Error("Agent result is undefined");
}
const externalFactFindingResult = {
output_text: externalFactFindingResultTemp.finalOutput ?? ""
};
const endResult = {
output_text: externalFactFindingResult.output_text
};
return endResult;
} else {
}
});
}