diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents/default-components.tsx b/packages/usdk/packages/upstreet-agent/packages/react-agents/default-components.tsx index 6614a8a30..10c18f1bb 100644 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents/default-components.tsx +++ b/packages/usdk/packages/upstreet-agent/packages/react-agents/default-components.tsx @@ -659,6 +659,7 @@ export const DefaultPrompts = () => { + ); }; @@ -891,6 +892,38 @@ export const InstructionsPrompt = () => { # Instructions Respond with the next action taken by your character: ${agent.name} The method/args of your response must match one of the allowed actions. + + Before choosing an action, decide if you should respond at all: + - Return null (no action) if: + * Message is clearly meant for others (unless you have crucial information) + * Your input wouldn't add value to the conversation + * The conversation is naturally concluding + * You've already responded frequently in the last few messages (2-3 messages max) + * Multiple other agents are already actively participating + `} + + ); +}; +export const DefaultCommunicationGuidelinesPrompt = () => { + return ( + + {dedent` + Prioritize responding when: + - You're directly mentioned or addressed + - It's a group discussion where you can contribute meaningfully + - Your personality traits are relevant to the topic + + Communication guidelines: + - Avoid using names in every message - only use them when: + * Directly responding to someone for the first time + * Clarifying who you're addressing in a group + * There's potential confusion about who you're talking to + - If you've been very active in the last few messages, wrap up your participation naturally + * Use phrases like "I'll let you all discuss" or simply stop responding + * Don't feel obligated to respond to every message + - Keep responses concise and natural + - Let conversations breathe - not every message needs a response + - If multiple agents are responding to the same person, step back and let others take the lead `} ); @@ -925,11 +958,12 @@ export const JsonFormatter = () => { const actionSchemas: ZodTypeAny[] = getFilteredActions(actions, conversation, thinkOpts) .map(action => makeActionSchema(action.name, action.schema)); if (actionSchemas.length >= 2) { - return z.union( - actionSchemas as [ZodTypeAny, ZodTypeAny, ...ZodTypeAny[]] - ); + return z.union([ + z.null(), + ...actionSchemas as [ZodTypeAny, ZodTypeAny, ...ZodTypeAny[]] + ]); } else if (actionSchemas.length === 1) { - return actionSchemas[0]; + return z.union([z.null(), actionSchemas[0]]); } else { return null; } diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents/runtime.ts b/packages/usdk/packages/upstreet-agent/packages/react-agents/runtime.ts index 41f6aae57..d29a7784b 100644 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents/runtime.ts +++ b/packages/usdk/packages/upstreet-agent/packages/react-agents/runtime.ts @@ -130,8 +130,13 @@ async function _generateAgentActionStepFromMessages( const completionMessage = await generativeAgent.completeJson(promptMessages, resultSchema); if (completionMessage) { const result = {} as ActionStep; + const action = (completionMessage.content as any).action as PendingActionMessage | null; + + // if the agent decided to do nothing (choose null), return an empty action step + if (action === null) { + return result; + } - const action = (completionMessage.content as any).action as PendingActionMessage; if (action) { const { method } = action; const actionHandlers = actions.filter((action) => action.name === method);