Custom AI Agent using Open AI Agent Builder

Agent Builder from Open AI is a game changer!

Using this tool, you can easily create custom ai agent without writing a single line of code. Below the flow was built using Agent Builder. 

Agent is taking input and based on the search query, agent is going to search from different MCP unit i.e. Google-drive, or SharePoint, or even using websearch. 

Simple to create and FAST to implement the Buisness Workflow!




Below the generated the back-end code. Go for Agent Builder :)


import { hostedMcpTool, Agent, AgentInputItem, Runner, withTrace } from "@openai/agents";

import { OpenAI } from "openai";

import { runGuardrails } from "@openai/guardrails";

import { z } from "zod";



// Tool definitions

const mcp = hostedMcpTool({

  serverLabel: "sharepoint",

  allowedTools: [

    "fetch",

    "get_profile",

    "get_site",

    "list_recent_documents",

    "search"

  ],

  authorization: "https://graph.microsoft.com/v1.0/sites?search=zrs7k.sharepoint.com",

  connectorId: "connector_sharepoint",

  requireApproval: "always",

  serverDescription: "SharePointSearch"

})


// Shared client for guardrails and file search

const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });


// Guardrails definitions

const guardrailsHlConfig = {

  guardrails: [

    {

      name: "Contains PII",

      config: {

        block: true,

        entities: [

          "AU_MEDICARE",

          "AU_TFN",

          "CREDIT_CARD",

          "ES_NIE",

          "FI_PERSONAL_IDENTITY_CODE",

          "IN_AADHAAR",

          "IN_PAN",

          "IN_PASSPORT",

          "IT_DRIVER_LICENSE",

          "PL_PESEL",

          "SG_UEN",

          "UK_NHS",

          "US_BANK_NUMBER",

          "US_DRIVER_LICENSE",

          "US_ITIN",

          "US_PASSPORT",

          "US_SSN"

        ]

      }

    },

    {

      name: "Moderation",

      config: {

        categories: [

          "sexual/minors",

          "hate/threatening",

          "harassment/threatening",

          "self-harm/instructions",

          "violence/graphic",

          "illicit/violent"

        ]

      }

    },

    {

      name: "Jailbreak",

      config: {

        model: "gpt-4o-mini",

        confidence_threshold: 0.62

      }

    }

  ]

};

const context = { guardrailLlm: client };


// Guardrails utils

function guardrailsHasTripwire(results) {

    return (results ?? []).some((r) => r?.tripwireTriggered === true);

}


function getGuardrailSafeText(results, fallbackText) {

    // Prefer checked_text as the generic safe/processed text

    for (const r of results ?? []) {

        if (r?.info && ("checked_text" in r.info)) {

            return r.info.checked_text ?? fallbackText;

        }

    }

    // Fall back to PII-specific anonymized_text if present

    const pii = (results ?? []).find((r) => r?.info && "anonymized_text" in r.info);

    return pii?.info?.anonymized_text ?? fallbackText;

}


function buildGuardrailFailOutput(results) {

    const get = (name) => (results ?? []).find((r) => {

          const info = r?.info ?? {};

          const n = (info?.guardrail_name ?? info?.guardrailName);

          return n === name;

        }),

          pii = get("Contains PII"),

          mod = get("Moderation"),

          jb = get("Jailbreak"),

          hal = get("Hallucination Detection"),

          piiCounts = Object.entries(pii?.info?.detected_entities ?? {})

              .filter(([, v]) => Array.isArray(v))

              .map(([k, v]) => k + ":" + v.length),

          thr = jb?.info?.threshold,

          conf = jb?.info?.confidence;


    return {

        pii: {

            failed: (piiCounts.length > 0) || pii?.tripwireTriggered === true,

            ...(piiCounts.length ? { detected_counts: piiCounts } : {}),

            ...(pii?.executionFailed && pii?.info?.error ? { error: pii.info.error } : {}),

        },

        moderation: {

            failed: mod?.tripwireTriggered === true || ((mod?.info?.flagged_categories ?? []).length > 0),

            ...(mod?.info?.flagged_categories ? { flagged_categories: mod.info.flagged_categories } : {}),

            ...(mod?.executionFailed && mod?.info?.error ? { error: mod.info.error } : {}),

        },

        jailbreak: {

            // Rely on runtime-provided tripwire; don't recompute thresholds

            failed: jb?.tripwireTriggered === true,

            ...(jb?.executionFailed && jb?.info?.error ? { error: jb.info.error } : {}),

        },

        hallucination: {

            // Rely on runtime-provided tripwire; don't recompute

            failed: hal?.tripwireTriggered === true,

            ...(hal?.info?.reasoning ? { reasoning: hal.info.reasoning } : {}),

            ...(hal?.info?.hallucination_type ? { hallucination_type: hal.info.hallucination_type } : {}),

            ...(hal?.info?.hallucinated_statements ? { hallucinated_statements: hal.info.hallucinated_statements } : {}),

            ...(hal?.info?.verified_statements ? { verified_statements: hal.info.verified_statements } : {}),

            ...(hal?.executionFailed && hal?.info?.error ? { error: hal.info.error } : {}),

        },

    };

}

const ClassificationagentSchema = z.object({ classification: z.enum(["Weather", "SharePoint-Search", "Find-Employee", "File-Search", "Other"]) });

const classificationagent = new Agent({

  name: "ClassificationAgent",

  instructions: `1. Any weather-related requests should route to Weather_item.

2. Any SharePoint word or URL-related request should route to SharePoint_item.

3. Any Employee-related requests should route to Employee_item.

4. Any File-Search related requests should route to FileSearch_item.

5. Any other requests should go to Get_more_information.`,

  model: "gpt-4o-mini",

  outputType: ClassificationagentSchema,

  modelSettings: {

    temperature: 1,

    topP: 1,

    maxTokens: 2048,

    store: true

  }

});


const weatherAgent = new Agent({

  name: "Weather Agent",

  instructions: "Seach weather user requested",

  model: "gpt-4o-mini",

  modelSettings: {

    temperature: 1,

    topP: 1,

    maxTokens: 2048,

    store: true

  }

});


const otherInformationAgent = new Agent({

  name: "Other Information Agent",

  instructions: "Search user request in web",

  model: "gpt-4o-mini",

  modelSettings: {

    temperature: 1,

    topP: 1,

    maxTokens: 2048,

    store: true

  }

});


const sharepointAgent = new Agent({

  name: "SharePoint Agent",

  instructions: "Search  in SharePoint site",

  model: "gpt-4o-mini",

  tools: [

    mcp

  ],

  modelSettings: {

    temperature: 1,

    topP: 1,

    maxTokens: 2048,

    store: true

  }

});


const gAgent = new Agent({

  name: "G-Agent",

  instructions: "Search in Google drive",

  model: "gpt-4o-mini",

  modelSettings: {

    temperature: 1,

    topP: 1,

    maxTokens: 2048,

    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 = {


    };

    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_690f7b282c9081908211b86dcbf108d5046aaecf30e95b6b"

      }

    });

    const guardrailsInputtext = workflow.input_as_text;

    const guardrailsResult = await runGuardrails(guardrailsInputtext, guardrailsHlConfig, context, true);

    const guardrailsHastripwire = guardrailsHasTripwire(guardrailsResult);

    const guardrailsAnonymizedtext = getGuardrailSafeText(guardrailsResult, guardrailsInputtext);

    const guardrailsOutput = (guardrailsHastripwire ? buildGuardrailFailOutput(guardrailsResult ?? []) : { safe_text: (guardrailsAnonymizedtext ?? guardrailsInputtext) });

    if (guardrailsHastripwire) {

      const endResult = {

        highlighted_data: workflow.input_as_text,

        message: "Sorry, unable to proceed further. Please try again."

      };

      return endResult;

    } else {

      const classificationagentResultTemp = await runner.run(

        classificationagent,

        [

          ...conversationHistory

        ]

      );

      conversationHistory.push(...classificationagentResultTemp.newItems.map((item) => item.rawItem));


      if (!classificationagentResultTemp.finalOutput) {

          throw new Error("Agent result is undefined");

      }


      const classificationagentResult = {

        output_text: JSON.stringify(classificationagentResultTemp.finalOutput),

        output_parsed: classificationagentResultTemp.finalOutput

      };

      if (classificationagentResult.output_parsed.classification == "Weather_item") {

        const weatherAgentResultTemp = await runner.run(

          weatherAgent,

          [

            ...conversationHistory,

            {

              role: "user",

              content: [

                {

                  type: "input_text",

                  text: `Search weater of ${workflow.input_as_text}`

                }

              ]

            }

          ]

        );

        conversationHistory.push(...weatherAgentResultTemp.newItems.map((item) => item.rawItem));


        if (!weatherAgentResultTemp.finalOutput) {

            throw new Error("Agent result is undefined");

        }


        const weatherAgentResult = {

          output_text: weatherAgentResultTemp.finalOutput ?? ""

        };

        return weatherAgentResult;

      } else if (classificationagentResult.output_parsed.classification == "SharePoint-Search") {

        const sharepointAgentResultTemp = await runner.run(

          sharepointAgent,

          [

            ...conversationHistory

          ]

        );

        conversationHistory.push(...sharepointAgentResultTemp.newItems.map((item) => item.rawItem));


        if (!sharepointAgentResultTemp.finalOutput) {

            throw new Error("Agent result is undefined");

        }


        const sharepointAgentResult = {

          output_text: sharepointAgentResultTemp.finalOutput ?? ""

        };

        return sharepointAgentResult;

      } else if (classificationagentResult.output_parsed.classification == "Employee_item") {


      } else if (classificationagentResult.output_parsed.classification == "FileSearch_item") {

        const gAgentResultTemp = await runner.run(

          gAgent,

          [

            ...conversationHistory

          ]

        );

        conversationHistory.push(...gAgentResultTemp.newItems.map((item) => item.rawItem));


        if (!gAgentResultTemp.finalOutput) {

            throw new Error("Agent result is undefined");

        }


        const gAgentResult = {

          output_text: gAgentResultTemp.finalOutput ?? ""

        };

        return gAgentResult;

      } else {

        const otherInformationAgentResultTemp = await runner.run(

          otherInformationAgent,

          [

            ...conversationHistory

          ]

        );

        conversationHistory.push(...otherInformationAgentResultTemp.newItems.map((item) => item.rawItem));


        if (!otherInformationAgentResultTemp.finalOutput) {

            throw new Error("Agent result is undefined");

        }


        const otherInformationAgentResult = {

          output_text: otherInformationAgentResultTemp.finalOutput ?? ""

        };

      }

    }

  });

}


Comments

Popular posts from this blog

SharePoint Framework Reference Guide

SharePoint Admin Center

How to fix Azure DevOps error MSB4126