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);