UNPKG

@xynehq/jaf

Version:

Juspay Agent Framework - A purely functional agent framework with immutable state and composable tools

223 lines 7.34 kB
/** * Pure functional A2A agent creation utilities * No classes, only pure functions and immutable data */ import { z } from 'zod'; import { run } from '../core/engine.js'; import { createRunId, createTraceId } from '../core/types.js'; // Pure function to create A2A compatible agent export const createA2AAgent = (config) => ({ name: config.name, description: config.description, supportedContentTypes: config.supportedContentTypes || ['text/plain', 'application/json'], instruction: config.instruction, tools: config.tools }); // Pure function to create A2A tool export const createA2ATool = (config) => ({ name: config.name, description: config.description, parameters: config.parameters, execute: config.execute }); // Pure function to get processing message export const getProcessingMessage = (agentName) => `${agentName} is processing your request...`; // Pure function to create initial agent state export const createInitialAgentState = (sessionId) => ({ sessionId, messages: [], context: {}, artifacts: [], timestamp: new Date().toISOString() }); // Pure function to add message to state export const addMessageToState = (state, message) => ({ ...state, messages: [...state.messages, message], timestamp: new Date().toISOString() }); // Pure function to update state from run result export const updateStateFromRunResult = (state, outcome) => ({ ...state, artifacts: outcome.artifacts ? [...state.artifacts, ...outcome.artifacts] : state.artifacts, timestamp: new Date().toISOString() }); // Pure function to create user message export const createUserMessage = (text) => ({ role: 'user', content: text }); // Pure function to transform A2A agent to JAF agent export const transformA2AAgentToJAF = (a2aAgent) => ({ name: a2aAgent.name, instructions: () => a2aAgent.instruction, tools: a2aAgent.tools.map(transformA2AToolToJAF), outputCodec: z.string() }); // Pure function to transform A2A tool to JAF tool export const transformA2AToolToJAF = (a2aTool) => ({ schema: { name: a2aTool.name, description: a2aTool.description, parameters: a2aTool.parameters }, execute: async (args, context) => { const toolContext = { actions: { requiresInput: false, skipSummarization: false, escalate: false }, metadata: context || {} }; const result = await a2aTool.execute(args, toolContext); // Handle ToolResult format if (typeof result === 'object' && result !== null && 'result' in result) { return result.result; } return result; } }); // Pure function to create run configuration for A2A agent export const createRunConfigForA2AAgent = (a2aAgent, modelProvider) => { const jafAgent = transformA2AAgentToJAF(a2aAgent); return { agentRegistry: new Map([[a2aAgent.name, jafAgent]]), modelProvider, maxTurns: 10, onEvent: (event) => { console.log(`[A2A:${a2aAgent.name}] ${event.type}:`, event.data); } }; }; // Pure function to transform agent state to JAF run state export const transformToRunState = (state, agentName, context = {}) => ({ runId: createRunId(`run_${Date.now()}`), traceId: createTraceId(`trace_${Date.now()}`), messages: state.messages, currentAgentName: agentName, context, turnCount: 0 }); // Pure async generator function to process agent query export const processAgentQuery = async function* (agent, query, state, modelProvider) { // Transform query to JAF message format const userMessage = createUserMessage(query); const newState = addMessageToState(state, userMessage); // Create JAF configuration const runConfig = createRunConfigForA2AAgent(agent, modelProvider); const runState = transformToRunState(newState, agent.name); try { // Execute JAF engine (pure function) const result = await run(runState, runConfig); if (result.outcome.status === 'completed') { const finalState = updateStateFromRunResult(newState, result.outcome); yield { isTaskComplete: true, content: result.outcome.output, newState: finalState, timestamp: new Date().toISOString() }; } else { const finalState = updateStateFromRunResult(newState, result.outcome); yield { isTaskComplete: true, content: `Error: ${JSON.stringify(result.outcome.error)}`, newState: finalState, timestamp: new Date().toISOString() }; } } catch (error) { yield { isTaskComplete: true, content: `Error: ${error instanceof Error ? error.message : String(error)}`, newState, timestamp: new Date().toISOString() }; } }; // Pure function to extract text from A2A message export const extractTextFromA2AMessage = (message) => { if (!message?.parts) return ''; return message.parts .filter((part) => part.kind === 'text') .map((part) => part.text) .join('\n'); }; // Pure function to create A2A text message export const createA2ATextMessage = (text, contextId, taskId) => ({ role: 'agent', parts: [{ kind: 'text', text }], messageId: `msg_${Date.now()}`, contextId, taskId, kind: 'message', timestamp: new Date().toISOString() }); // Pure function to create A2A data message export const createA2ADataMessage = (data, contextId, taskId) => ({ role: 'agent', parts: [{ kind: 'data', data }], messageId: `msg_${Date.now()}`, contextId, taskId, kind: 'message', timestamp: new Date().toISOString() }); // Pure function to create A2A task export const createA2ATask = (message, contextId) => ({ id: `task_${Date.now()}`, contextId: contextId || `ctx_${Date.now()}`, status: { state: 'submitted', timestamp: new Date().toISOString() }, history: [message], artifacts: [], kind: 'task' }); // Pure function to update A2A task status export const updateA2ATaskStatus = (task, state, message) => ({ ...task, status: { state, message, timestamp: new Date().toISOString() } }); // Pure function to add artifact to A2A task export const addArtifactToA2ATask = (task, parts, name) => ({ ...task, artifacts: [ ...task.artifacts, { artifactId: `artifact_${Date.now()}`, name, parts, timestamp: new Date().toISOString() } ] }); // Pure function to complete A2A task export const completeA2ATask = (task, result) => ({ ...task, status: { state: 'completed', timestamp: new Date().toISOString() }, ...(result && { artifacts: [ ...task.artifacts, { artifactId: `result_${Date.now()}`, name: 'final_result', parts: [{ kind: 'text', text: String(result) }], timestamp: new Date().toISOString() } ] }) }); //# sourceMappingURL=agent.js.map