UNPKG

@cosmixclub/parsero

Version:

Construtor de agentes de IA de maneira simplificada.

1 lines 6.56 kB
import {traceable}from'langsmith/traceable';import {END,Annotation,START,StateGraph}from'@langchain/langgraph';import {BaseChatModel}from'@langchain/core/language_models/chat_models';var I=Object.defineProperty;var w=(i,t,r)=>t in i?I(i,t,{enumerable:true,configurable:true,writable:true,value:r}):i[t]=r;var c=(i,t,r)=>w(i,typeof t!="symbol"?t+"":t,r);var l=class extends Error{constructor(t,r){super(t,r),this.name=this.constructor.name,Object.setPrototypeOf(this,new.target.prototype),typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,this.constructor);}};var h=class extends l{constructor(t,r){super(t,r);}};var y=class extends l{constructor(r,s=[],e){super(r,e);this.names=s;}};var f=class extends l{constructor(r,s){super(r,s);c(this,"issues");s?.issues&&(this.issues=s.issues);}};var d=class{constructor(t){this.props=t;c(this,"t");this.t={input:t.inputSchema.keyof().options.map(r=>({[r]:null})).reduce((r,s)=>({...r,...s}),{}),output:t.outputSchema.keyof().options.map(r=>({[r]:null})).reduce((r,s)=>({...r,...s}),{})};}get values(){return {input:this.t.input,output:this.t.output}}parseInput(t){return this.props.inputSchema.safeParse(t)}parseOutput(t){return this.props.outputSchema.safeParse(t)}setInput(t){this.t.input=t;}setOutput(t){this.t.output=t;}static processObject(t,r,s){if(t==null){s[r]=t;return}if(Array.isArray(t)){s[r]=t;return}if(typeof t=="object")for(let[e,o]of Object.entries(t)){let n=r?`${r}_${e}`:e;typeof o=="object"&&o!==null&&!Array.isArray(o)?this.processObject(o,n,s):s[n]=o;}else s[r]=t;}static valuesToLanggraph(t){let{input:r,output:s}=t,e={};return this.processObject(r,"input",e),this.processObject(s,"output",e),e}static langgraphToValues(t){let r={},s={};for(let[e,o]of Object.entries(t))if(e.startsWith("input_")){let n=e.replace("input_","").split("_"),a=r;for(let p=0;p<n.length-1;p++)a[n[p]]||(a[n[p]]={}),a=a[n[p]];a[n[n.length-1]]=o;}else if(e.startsWith("output_")){let n=e.replace("output_","").split("_"),a=s;for(let p=0;p<n.length-1;p++)a[n[p]]||(a[n[p]]={}),a=a[n[p]];a[n[n.length-1]]=o;}return {input:r,output:s}}};var x=class{constructor(t){this.props=t;c(this,"stateBuilder");c(this,"state");c(this,"llm");if(this.props.llm instanceof BaseChatModel)this.llm=this.props.llm;else {let r=Object.keys(this.props.llm);if(r.length===0)throw new Error("Nenhum modelo foi fornecido no objeto de LLMs. A integra\xE7\xE3o com LangGraph precisa de pelo menos um modelo.");let s=r.includes("default")?"default":r[0];this.llm=this.props.llm[s],r.length>1&&console.warn(`A integra\xE7\xE3o com LangGraph est\xE1 utilizando apenas o modelo "${s}". Os outros modelos ser\xE3o ignorados.`);}this.stateBuilder=()=>{let r=Object.keys(this.props.state.values.input).map(o=>[`input_${o}`,Array.isArray(this.props.state.values.input[o])]),s=Object.keys(this.props.state.values.output).map(o=>[`output_${o}`,Array.isArray(this.props.state.values.output[o])]),e={};for(let[o,n]of [...r,...s])n?e[o]=Annotation({default:()=>[],reducer:(a,p)=>a.concat(p)}):e[o]=Annotation();return e},this.state=Annotation.Root(this.stateBuilder());}describeProcedures(){let t=[];this.props.procedures.length>0&&t.push([START,this.props.procedures[0].name]);let r=new Map;for(let s of this.props.procedures)r.set(s.name,s);for(let s=0;s<this.props.procedures.length;s++){let e=this.props.procedures[s];if(e.type==="action")if(e.nextProcedure===END)t.push([e.name,END]);else if(e.nextProcedure){let o=r.get(e.nextProcedure);o&&o.type==="check"?t.push([e.name,o.run]):o&&o.type==="action"?t.push([e.name,o.name]):t.push([e.name,END]);}else {let o=this.props.procedures[s+1];o?t.push([e.name,o.name]):t.push([e.name,END]);}}return t}build(){let t=new StateGraph(this.state);for(let e of this.props.procedures)e.type==="action"&&t.addNode(e.name,async o=>{let n=d.langgraphToValues(o),a=await e.run({...this.props.state.values,...n},this.llm);return d.valuesToLanggraph(a)});let r=this.describeProcedures();for(let[e,o]of r){if(typeof o=="string"){t.addEdge(e,o);continue}t.addConditionalEdges(e,async n=>{let a=d.langgraphToValues(n);return await o({...this.props.state.values,...a},this.llm)||END});}return t.compile()}};var P=class{constructor(t){this.props=t;}validateProcedureNames(){let t=this.props.procedures.map(s=>s.name),r=t.filter((s,e)=>t.indexOf(s)!==e);if(r.length>0)throw new y("Os nomes dos procedimentos devem ser distintos.",r)}validateProcedureChain(){let t=this.props.procedures.some(s=>s.type==="check"),r=this.props.procedures.filter(s=>s.type==="action").every(s=>s.nextProcedure);if(t&&!r)throw new h("Quando houver um procedimento do tipo 'check', todos os procedimentos do tipo 'action' devem declarar o pro\u0301ximo procedimento.")}get graph(){return new x({llm:this.props.llm,procedures:this.props.procedures,state:this.props.state}).build()}async run(t){let r=this.props.state.parseInput(t);if(!r.success)throw new f("O input recebido n\xE3o segue o schema.");this.props.state.setInput(r.data),this.validateProcedureNames(),this.validateProcedureChain();let s=new Map;for(let p of this.props.procedures)s.set(p.name,p);let e=this.props.procedures[0],o=0;await traceable(async function(u){for(;e;){if(o++>=(u.props.options?.maxIterations||100))throw new h(`O agente atingiu o limite m\xE1ximo de ${u.props.options?.maxIterations||100} itera\xE7\xF5es. Poss\xEDvel loop detectado no grafo.`);if(u.props.options?.verbose&&console.log(`[${u.props?.options?.name||"Agente"}] Itera\xE7\xE3o ${o}: ${e.name}`),e.type==="action"){let m=await traceable(async()=>await e?.run(u.props.state.values,u.props.llm),{metadata:e?.tracing?.metadata,name:e?.tracing?.label||e.name,run_type:e?.tracing?.runType||"tool"})();if(u.props.state.setInput(m.input),u.props.state.setOutput(m.output),e.nextProcedure===END)break;if(e.nextProcedure){e=s.get(e.nextProcedure)??null;continue}let L=u.props.procedures.findIndex(S=>S.name===e?.name);e=u.props.procedures[L+1]??null;}else if(e.type==="check"){let m=await traceable(async()=>await e?.run(u.props.state.values,u.props.llm),{metadata:e?.tracing?.metadata,name:e?.tracing?.label||e.name,run_type:e?.tracing?.runType||"tool"})();if(!m||m===END)break;e=s.get(m)??null;}}},{metadata:{...this.props.options?.metadata||{},e:process.env.npm_package_name||"@cosmixclub/parsero",r:process.env.npm_package_version||"0.0.0"},name:this.props?.options?.name||"Agente",run_type:"chain"})(this);let a=this.props.state.parseOutput(this.props.state.values.output);if(!a.success)throw new f("O output gerado n\xE3o segue o schema.");return a.data}};export{P as Agent,d as State};