From 771f6103074009ecc7a0da43630bab6e96441109 Mon Sep 17 00:00:00 2001 From: Abdurrehman Subhani Date: Sat, 23 Nov 2024 08:23:03 +0500 Subject: [PATCH 01/15] add SelfConsciousReplies component for determining wether to reply to a message or not --- .../react-agents/default-components.tsx | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) 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 7d6d2b31e..84493e204 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 @@ -3356,4 +3356,90 @@ export const Telnyx: React.FC = (props: TelnyxProps) => { ]); return null; +}; +export type SelfConsciousRepliesProps = { + historyLength?: number; // Number of previous messages to consider for context + defaultThreshold?: number; // How likely the agent should respond by default (0-1) +}; + +export const SelfConsciousReplies: React.FC = (props: SelfConsciousRepliesProps) => { + const historyLength = props?.historyLength ?? 5; + const defaultThreshold = props?.defaultThreshold ?? 0.6; + + + return ( + { + const { message, sourceAgent, targetAgent } = e.data; + + console.log('SelfConsciousReplies', { + message, + + }); + + // Get conversation history + const messages = targetAgent.conversation.getCachedMessages() + .slice(-historyLength) + .map(m => ({ + name: m.name, + text: m.args?.text || '', + timestamp: m.timestamp + })); + + // Build decision prompt + const decisionPrompt = ` + You are deciding whether to respond to an incoming message in a conversation. + + Current message: "${message?.args?.text || ''}" + From user: ${sourceAgent.name} + + Recent conversation history: + ${messages.map(m => `${m.name}: ${m.text}`).join('\n')} + + Your personality: ${targetAgent.agent.bio} + Your name: ${targetAgent.agent.name} + + Other users mentioned in the current message: ${extractMentions(message?.args?.text || '').join(', ')} + + Based on this context, should you respond to this message? + Consider: + 1. Is the message directed at you specifically? (Weight: ${defaultThreshold}) + 2. Is the conversation active and engaging? + 3. Would responding align with your personality? + 4. Are other users being addressed instead of you? + + Respond with a decision object containing: + - shouldRespond: boolean (true if confidence > ${defaultThreshold}) + - reason: brief explanation + - confidence: number between 0-1 + `; + + const decisionSchema = z.object({ + shouldRespond: z.boolean(), + reason: z.string(), + confidence: z.number(), + }); + + const decision = await targetAgent.completeJson([{ + role: 'assistant', + content: decisionPrompt, + }], decisionSchema); + + console.log('decision', decision); + // console.log(`Agent ${targetAgent.agent.name} decision: ${decision.content.shouldRespond ? 'respond' : 'not respond'} - ${decision.content.reason} (confidence: ${decision.content.confidence})`); + + if (!decision.content.shouldRespond || decision.content.confidence < defaultThreshold) { + e.abort(); + } + }} + priority={-defaultPriorityOffset * 2} + /> + ); +}; + +// Helper function to extract @mentions from text +const extractMentions = (text: string): string[] => { + const mentions = text.match(/@(\w+)/g) || []; + return mentions.map(m => m.substring(1)); }; \ No newline at end of file From 2880c9e7520d5f52140ecfe1fbd7f0dc794096a2 Mon Sep 17 00:00:00 2001 From: Abdurrehman Subhani Date: Sat, 23 Nov 2024 08:37:04 +0500 Subject: [PATCH 02/15] use gpt4omini for reply decision thinking --- .../react-agents/classes/generative-agent-object.ts | 6 ++++-- .../packages/react-agents/default-components.tsx | 4 +++- .../upstreet-agent/packages/react-agents/types/agents.d.ts | 2 ++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents/classes/generative-agent-object.ts b/packages/usdk/packages/upstreet-agent/packages/react-agents/classes/generative-agent-object.ts index 2f1cd0219..bcba817a0 100644 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents/classes/generative-agent-object.ts +++ b/packages/usdk/packages/upstreet-agent/packages/react-agents/classes/generative-agent-object.ts @@ -62,17 +62,19 @@ export class GenerativeAgentObject { } async complete( messages: ChatMessages, + model?: string, ) { return await this.agent.appContextValue.complete(messages, { - model: this.agent.model, + model: model ?? this.agent.model, }); } async completeJson( messages: ChatMessages, format: ZodTypeAny, + model?: string, ) { return await this.agent.appContextValue.completeJson(messages, format, { - model: this.agent.model, + model: model ?? this.agent.model, }); } async generateImage(prompt: string, opts?: SubtleAiImageOpts) { 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 84493e204..b6681122a 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 @@ -3424,7 +3424,9 @@ export const SelfConsciousReplies: React.FC = (props: const decision = await targetAgent.completeJson([{ role: 'assistant', content: decisionPrompt, - }], decisionSchema); + }], decisionSchema, + 'openai:gpt-4o-mini', + ); console.log('decision', decision); // console.log(`Agent ${targetAgent.agent.name} decision: ${decision.content.shouldRespond ? 'respond' : 'not respond'} - ${decision.content.reason} (confidence: ${decision.content.confidence})`); diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents/types/agents.d.ts b/packages/usdk/packages/upstreet-agent/packages/react-agents/types/agents.d.ts index e2f72835b..54f01c5cf 100644 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents/types/agents.d.ts +++ b/packages/usdk/packages/upstreet-agent/packages/react-agents/types/agents.d.ts @@ -52,10 +52,12 @@ export type GenerativeAgentObject = { embed: (text: string) => Promise>; complete: ( messages: ChatMessages, + model?: string, ) => Promise; completeJson: ( messages: ChatMessages, format: ZodTypeAny, + model?: string, ) => Promise; think: (hint?: string, thinkOpts?: AgentThinkOptions) => Promise; From a5f9686942944f2fa65a734693c0d50198c1fff1 Mon Sep 17 00:00:00 2001 From: Abdurrehman Subhani Date: Sat, 23 Nov 2024 09:02:51 +0500 Subject: [PATCH 03/15] improve decisionPrompt context --- .../react-agents/default-components.tsx | 36 ++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) 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 b6681122a..f88ca9e1d 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 @@ -3378,7 +3378,8 @@ export const SelfConsciousReplies: React.FC = (props: }); - // Get conversation history + // Retrieve the most recent messages from conversation history, limited by historyLength, + // and extract the relevant fields (name, text, timestamp) for each message const messages = targetAgent.conversation.getCachedMessages() .slice(-historyLength) .map(m => ({ @@ -3397,21 +3398,40 @@ export const SelfConsciousReplies: React.FC = (props: Recent conversation history: ${messages.map(m => `${m.name}: ${m.text}`).join('\n')} - Your personality: ${targetAgent.agent.bio} + Your personality (ONLY use this information to guide your response, do not make assumptions beyond it): + ${targetAgent.agent.bio} Your name: ${targetAgent.agent.name} + Your id: ${targetAgent.agent.id} Other users mentioned in the current message: ${extractMentions(message?.args?.text || '').join(', ')} Based on this context, should you respond to this message? - Consider: - 1. Is the message directed at you specifically? (Weight: ${defaultThreshold}) - 2. Is the conversation active and engaging? - 3. Would responding align with your personality? - 4. Are other users being addressed instead of you? + + IMPORTANT GUIDELINES: + 1. If the message is clearly addressed to someone else (via @mention or context), you should NOT respond UNLESS: + - You have critical information that directly relates to the message and would be valuable to share + - The information is urgent or important enough to justify interrupting + - Not sharing this information could lead to misunderstandings or issues + + 2. Only interrupt conversations between others in rare and justified cases. Your confidence should be very low (< 0.3) + if you're considering responding to a message not directed at you. + + 3. Message frequency control: + - Check how many messages you've sent recently in the conversation history + - If you've sent multiple messages in the last few exchanges, lower your confidence significantly + - Avoid dominating the conversation - others should have space to participate + - Consider staying silent if you've been very active recently, unless you have highly relevant or critical information to share + + Additional considerations: + - Is the message explicitly directed at you? (Weight: ${defaultThreshold}) + - Would responding align with ONLY your defined personality traits? + - Is your response truly necessary or would it derail the current conversation? + - Are you certain you have unique, valuable information to add if interrupting? + - Have you been contributing too frequently to the conversation lately? Respond with a decision object containing: - shouldRespond: boolean (true if confidence > ${defaultThreshold}) - - reason: brief explanation + - reason: brief explanation including specific justification if interrupting others' conversation - confidence: number between 0-1 `; From c2ddbd59d311bf15c23e6aab540eb0d775b1a015 Mon Sep 17 00:00:00 2001 From: Abdurrehman Subhani Date: Sat, 23 Nov 2024 09:07:51 +0500 Subject: [PATCH 04/15] add current conversation members to context --- .../packages/react-agents/default-components.tsx | 3 +++ 1 file changed, 3 insertions(+) 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 f88ca9e1d..e823e9cbc 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 @@ -3378,6 +3378,7 @@ export const SelfConsciousReplies: React.FC = (props: }); + const conversationMembers = targetAgent.conversation.getAgents(); // Retrieve the most recent messages from conversation history, limited by historyLength, // and extract the relevant fields (name, text, timestamp) for each message const messages = targetAgent.conversation.getCachedMessages() @@ -3394,6 +3395,8 @@ export const SelfConsciousReplies: React.FC = (props: Current message: "${message?.args?.text || ''}" From user: ${sourceAgent.name} + + Conversation members: ${conversationMembers.map(a => `${a.playerSpec.name} (${a.playerSpec.id})`).join(', ')} Recent conversation history: ${messages.map(m => `${m.name}: ${m.text}`).join('\n')} From 5a41c81147349ed16f64e6089618633dd742d650 Mon Sep 17 00:00:00 2001 From: Abdurrehman Subhani Date: Sat, 23 Nov 2024 09:42:15 +0500 Subject: [PATCH 05/15] loosen directed message considerations, comment debug logs --- .../react-agents/default-components.tsx | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) 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 e823e9cbc..f045f13b2 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 @@ -3373,12 +3373,12 @@ export const SelfConsciousReplies: React.FC = (props: handler={async (e: AbortablePerceptionEvent) => { const { message, sourceAgent, targetAgent } = e.data; - console.log('SelfConsciousReplies', { - message, - - }); + // console.log('SelfConsciousReplies', { + // message, + // }); const conversationMembers = targetAgent.conversation.getAgents(); + // Retrieve the most recent messages from conversation history, limited by historyLength, // and extract the relevant fields (name, text, timestamp) for each message const messages = targetAgent.conversation.getCachedMessages() @@ -3418,19 +3418,23 @@ export const SelfConsciousReplies: React.FC = (props: 2. Only interrupt conversations between others in rare and justified cases. Your confidence should be very low (< 0.3) if you're considering responding to a message not directed at you. + + 3. If the message appears to be directed to the entire group or is a general statement/question: + - You should be highly interested in participating + - Your confidence should be high (> 0.7) as group discussions warrant active participation + - Consider the value you can add to the group conversation - 3. Message frequency control: - - Check how many messages you've sent recently in the conversation history - - If you've sent multiple messages in the last few exchanges, lower your confidence significantly - - Avoid dominating the conversation - others should have space to participate - - Consider staying silent if you've been very active recently, unless you have highly relevant or critical information to share + 4. Message frequency suggestions: + - Reduce participation if you've sent 3+ messages in immediate succession + - Focus on the value of your contribution rather than how recently you've spoken + - Don't worry too much about "dominating" the conversation unless you're the only one talking Additional considerations: - Is the message explicitly directed at you? (Weight: ${defaultThreshold}) + - Is the message directed to everyone in the group? (High priority) - Would responding align with ONLY your defined personality traits? - Is your response truly necessary or would it derail the current conversation? - Are you certain you have unique, valuable information to add if interrupting? - - Have you been contributing too frequently to the conversation lately? Respond with a decision object containing: - shouldRespond: boolean (true if confidence > ${defaultThreshold}) @@ -3451,7 +3455,7 @@ export const SelfConsciousReplies: React.FC = (props: 'openai:gpt-4o-mini', ); - console.log('decision', decision); + // console.log('decision', decision); // console.log(`Agent ${targetAgent.agent.name} decision: ${decision.content.shouldRespond ? 'respond' : 'not respond'} - ${decision.content.reason} (confidence: ${decision.content.confidence})`); if (!decision.content.shouldRespond || decision.content.confidence < defaultThreshold) { From f054bbae1e36cb3cee3eaf086f077c1db865bbfb Mon Sep 17 00:00:00 2001 From: Abdurrehman Subhani Date: Sat, 23 Nov 2024 09:44:01 +0500 Subject: [PATCH 06/15] add SelfConsciousReplies to default agent components --- .../upstreet-agent/packages/react-agents/default-components.tsx | 1 + 1 file changed, 1 insertion(+) 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 f045f13b2..04eb90dd7 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 @@ -142,6 +142,7 @@ export const DefaultAgentComponents = () => { {/* */} {/* */} + ); }; From 4c7cd8fa98aed7c9081ae37daebe834b217e3484 Mon Sep 17 00:00:00 2001 From: Abdurrehman Subhani Date: Sat, 23 Nov 2024 10:04:07 +0500 Subject: [PATCH 07/15] add conversation fatigue context to lower agent's conversation involvement --- .../react-agents/default-components.tsx | 64 +++++++++++-------- 1 file changed, 39 insertions(+), 25 deletions(-) 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 04eb90dd7..75420c60d 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 @@ -3367,30 +3367,36 @@ export const SelfConsciousReplies: React.FC = (props: const historyLength = props?.historyLength ?? 5; const defaultThreshold = props?.defaultThreshold ?? 0.6; - return ( { const { message, sourceAgent, targetAgent } = e.data; - // console.log('SelfConsciousReplies', { - // message, - // }); - - const conversationMembers = targetAgent.conversation.getAgents(); - - // Retrieve the most recent messages from conversation history, limited by historyLength, - // and extract the relevant fields (name, text, timestamp) for each message - const messages = targetAgent.conversation.getCachedMessages() + // Get conversation members and recent messages in one pass + const [conversationMembers, messages] = await Promise.all([ + targetAgent.conversation.getAgents(), + targetAgent.conversation.getCachedMessages() .slice(-historyLength) - .map(m => ({ - name: m.name, - text: m.args?.text || '', - timestamp: m.timestamp - })); + .map(({name, args, timestamp}) => ({ + name, + text: args?.text || '', + timestamp + })) + ]); + + // Calculate back-and-forth agent conversation count + // this is being calculated to determine if the agent is being in the conversation too much + const recentMessages = messages.slice(-6); + const backAndForthCount = recentMessages.reduce((count, msg, i) => { + if (i === 0) return count; + const prevMsg = recentMessages[i-1]; + return (msg.name === targetAgent.agent.name && + prevMsg.name === sourceAgent.name) ? count + 1 : count; + }, 0); + + const backAndForthPenalty = Math.min(backAndForthCount * 0.2, 0.8); - // Build decision prompt const decisionPrompt = ` You are deciding whether to respond to an incoming message in a conversation. @@ -3409,6 +3415,11 @@ export const SelfConsciousReplies: React.FC = (props: Other users mentioned in the current message: ${extractMentions(message?.args?.text || '').join(', ')} + CONVERSATION FATIGUE CONTEXT: + - You and ${sourceAgent.name} have had ${backAndForthCount} back-and-forth exchanges recently + - Your interest level is reduced by ${(backAndForthPenalty * 100).toFixed()}% due to conversation fatigue + - If you've been going back and forth too much, you should naturally lose interest and let the conversation end + Based on this context, should you respond to this message? IMPORTANT GUIDELINES: @@ -3425,10 +3436,11 @@ export const SelfConsciousReplies: React.FC = (props: - Your confidence should be high (> 0.7) as group discussions warrant active participation - Consider the value you can add to the group conversation - 4. Message frequency suggestions: - - Reduce participation if you've sent 3+ messages in immediate succession - - Focus on the value of your contribution rather than how recently you've spoken - - Don't worry too much about "dominating" the conversation unless you're the only one talking + 4. Message frequency and fatigue guidelines: + - Show significantly decreased interest after 4+ back-and-forth exchanges + - Let conversations naturally end instead of forcing them to continue + - If you've been talking frequently with someone, take breaks to avoid conversation fatigue + - Consider if someone else should have a chance to speak Additional considerations: - Is the message explicitly directed at you? (Weight: ${defaultThreshold}) @@ -3440,7 +3452,7 @@ export const SelfConsciousReplies: React.FC = (props: Respond with a decision object containing: - shouldRespond: boolean (true if confidence > ${defaultThreshold}) - reason: brief explanation including specific justification if interrupting others' conversation - - confidence: number between 0-1 + - confidence: number between 0-1 (note: this will be reduced by ${(backAndForthPenalty * 100).toFixed()}% due to conversation fatigue) `; const decisionSchema = z.object({ @@ -3453,13 +3465,15 @@ export const SelfConsciousReplies: React.FC = (props: role: 'assistant', content: decisionPrompt, }], decisionSchema, - 'openai:gpt-4o-mini', + // XXX replace with gpt-4o-mini when ai proxy is updated + // 'openai:gpt-4o-mini', + 'openai:gpt-4o', ); - // console.log('decision', decision); - // console.log(`Agent ${targetAgent.agent.name} decision: ${decision.content.shouldRespond ? 'respond' : 'not respond'} - ${decision.content.reason} (confidence: ${decision.content.confidence})`); + // Apply the back-and-forth penalty to the confidence + const adjustedConfidence = decision.content.confidence * (1 - backAndForthPenalty); - if (!decision.content.shouldRespond || decision.content.confidence < defaultThreshold) { + if (!decision.content.shouldRespond || adjustedConfidence < defaultThreshold) { e.abort(); } }} From f2bda67b28adc4c0c4593dda74fc3450a23de245 Mon Sep 17 00:00:00 2001 From: Abdurrehman Subhani Date: Sat, 23 Nov 2024 10:28:13 +0500 Subject: [PATCH 08/15] only apply backAndForthPenalty if there are more 2 members in the chat --- .../packages/react-agents/default-components.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 75420c60d..362aba496 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 @@ -3395,7 +3395,8 @@ export const SelfConsciousReplies: React.FC = (props: prevMsg.name === sourceAgent.name) ? count + 1 : count; }, 0); - const backAndForthPenalty = Math.min(backAndForthCount * 0.2, 0.8); + // Only apply penalty if more than 2 members in chat + const backAndForthPenalty = conversationMembers.length > 2 ? Math.min(backAndForthCount * 0.2, 0.8) : 0; const decisionPrompt = ` You are deciding whether to respond to an incoming message in a conversation. From 4d183281693015a32636e9772e0cd341f2e4fbbe Mon Sep 17 00:00:00 2001 From: Abdurrehman Subhani Date: Mon, 25 Nov 2024 16:27:02 +0500 Subject: [PATCH 09/15] add conversation interest state --- .../react-agents/default-components.tsx | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) 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 362aba496..77cc6d198 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 @@ -3367,12 +3367,18 @@ export const SelfConsciousReplies: React.FC = (props: const historyLength = props?.historyLength ?? 5; const defaultThreshold = props?.defaultThreshold ?? 0.6; + const [conversationInterest, setConversationInterest] = useState(1); + return ( { const { message, sourceAgent, targetAgent } = e.data; + console.log('self conscious replies', { + conversationInterest, + }); + // Get conversation members and recent messages in one pass const [conversationMembers, messages] = await Promise.all([ targetAgent.conversation.getAgents(), @@ -3419,7 +3425,9 @@ export const SelfConsciousReplies: React.FC = (props: CONVERSATION FATIGUE CONTEXT: - You and ${sourceAgent.name} have had ${backAndForthCount} back-and-forth exchanges recently - Your interest level is reduced by ${(backAndForthPenalty * 100).toFixed()}% due to conversation fatigue + - Your current interest level in the conversation is ${conversationInterest.toFixed(2)} out of 1.0 - If you've been going back and forth too much, you should naturally lose interest and let the conversation end + - Your interest level will affect your likelihood of responding Based on this context, should you respond to this message? @@ -3449,6 +3457,7 @@ export const SelfConsciousReplies: React.FC = (props: - Would responding align with ONLY your defined personality traits? - Is your response truly necessary or would it derail the current conversation? - Are you certain you have unique, valuable information to add if interrupting? + - How does your current interest level (${conversationInterest.toFixed(2)}) affect your desire to respond? Respond with a decision object containing: - shouldRespond: boolean (true if confidence > ${defaultThreshold}) @@ -3471,8 +3480,14 @@ export const SelfConsciousReplies: React.FC = (props: 'openai:gpt-4o', ); - // Apply the back-and-forth penalty to the confidence - const adjustedConfidence = decision.content.confidence * (1 - backAndForthPenalty); + // Apply both the back-and-forth penalty and current interest level to the confidence + const adjustedConfidence = decision.content.confidence * (1 - backAndForthPenalty) * conversationInterest; + setConversationInterest(adjustedConfidence); + + console.log('decision', { + decision, + adjustedConfidence, + }); if (!decision.content.shouldRespond || adjustedConfidence < defaultThreshold) { e.abort(); From a6e86ed5e325db641e9d3cd1fbc1737a1b3da42b Mon Sep 17 00:00:00 2001 From: Abdurrehman Subhani Date: Mon, 25 Nov 2024 16:49:29 +0500 Subject: [PATCH 10/15] move conversationInterest score to ConversationObject, calculate average conversationInterest score --- .../react-agents/default-components.tsx | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) 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 77cc6d198..81c7fd75a 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 @@ -3362,25 +3362,18 @@ export type SelfConsciousRepliesProps = { historyLength?: number; // Number of previous messages to consider for context defaultThreshold?: number; // How likely the agent should respond by default (0-1) }; - export const SelfConsciousReplies: React.FC = (props: SelfConsciousRepliesProps) => { const historyLength = props?.historyLength ?? 5; const defaultThreshold = props?.defaultThreshold ?? 0.6; - const [conversationInterest, setConversationInterest] = useState(1); - return ( { const { message, sourceAgent, targetAgent } = e.data; - console.log('self conscious replies', { - conversationInterest, - }); - // Get conversation members and recent messages in one pass - const [conversationMembers, messages] = await Promise.all([ + const [conversationMembers, messages, conversationInterest] = await Promise.all([ targetAgent.conversation.getAgents(), targetAgent.conversation.getCachedMessages() .slice(-historyLength) @@ -3388,8 +3381,9 @@ export const SelfConsciousReplies: React.FC = (props: name, text: args?.text || '', timestamp - })) - ]); + })), + targetAgent.conversation.getConversationInterest(), + ]); // Calculate back-and-forth agent conversation count // this is being calculated to determine if the agent is being in the conversation too much @@ -3480,16 +3474,24 @@ export const SelfConsciousReplies: React.FC = (props: 'openai:gpt-4o', ); - // Apply both the back-and-forth penalty and current interest level to the confidence - const adjustedConfidence = decision.content.confidence * (1 - backAndForthPenalty) * conversationInterest; - setConversationInterest(adjustedConfidence); + console.log('current conversation interest', conversationInterest); + console.log('back and forth penalty', backAndForthPenalty); + console.log('decision confidence', decision.content.confidence); + + const calc = conversationInterest - backAndForthPenalty; + const blendedInterest = (calc + decision.content.confidence) / 2; + const newInterest = Math.max(0, Math.min(1, blendedInterest)); + + console.log('new interest', newInterest); + targetAgent.conversation.setConversationInterest(newInterest); console.log('decision', { decision, - adjustedConfidence, + conversationInterest: newInterest, }); - if (!decision.content.shouldRespond || adjustedConfidence < defaultThreshold) { + // Use conversation interest to determine if we should respond + if (!decision.content.shouldRespond || newInterest < defaultThreshold) { e.abort(); } }} From b580873e2bc5f6b8754ba49c5d96954a9d3f5137 Mon Sep 17 00:00:00 2001 From: Abdurrehman Subhani Date: Mon, 25 Nov 2024 16:51:24 +0500 Subject: [PATCH 11/15] add missing conversationInterest declaration --- .../react-agents/classes/conversation-object.ts | 10 ++++++++++ .../packages/react-agents/types/agents.d.ts | 3 +++ 2 files changed, 13 insertions(+) diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents/classes/conversation-object.ts b/packages/usdk/packages/upstreet-agent/packages/react-agents/classes/conversation-object.ts index eb068bce0..8020bd863 100644 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents/classes/conversation-object.ts +++ b/packages/usdk/packages/upstreet-agent/packages/react-agents/classes/conversation-object.ts @@ -24,6 +24,7 @@ export class ConversationObject extends EventTarget { getHash: GetHashFn; // XXX this can be a string, since conversation hashes do not change (?) messageCache: MessageCache; numTyping: number = 0; + conversationInterest: number = 1; constructor({ agent, @@ -58,6 +59,15 @@ export class ConversationObject extends EventTarget { // + getConversationInterest() { + return this.conversationInterest; + } + setConversationInterest(conversationInterest: number) { + this.conversationInterest = conversationInterest; + } + + // + async typing(fn: () => Promise) { const start = () => { if (++this.numTyping === 1) { diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents/types/agents.d.ts b/packages/usdk/packages/upstreet-agent/packages/react-agents/types/agents.d.ts index 54f01c5cf..f090bdbb8 100644 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents/types/agents.d.ts +++ b/packages/usdk/packages/upstreet-agent/packages/react-agents/types/agents.d.ts @@ -279,7 +279,10 @@ export type ConversationObject = EventTarget & { getHash: GetHashFn; messageCache: MessageCache; numTyping: number; + conversationInterest: number; + getConversationInterest: () => number; + setConversationInterest: (conversationInterest: number) => void; getCachedMessages: (filter?: MessageFilter) => ActionMessage[]; /* fetchMessages: (filter?: MessageFilter, opts?: { supabase: any, From a80c68d5843278af947dff4e662377ba8c191b22 Mon Sep 17 00:00:00 2001 From: Abdurrehman Subhani Date: Mon, 25 Nov 2024 17:35:04 +0500 Subject: [PATCH 12/15] comment out debugging logs --- .../packages/react-agents/default-components.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) 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 81c7fd75a..c5d5e5541 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 @@ -3474,21 +3474,21 @@ export const SelfConsciousReplies: React.FC = (props: 'openai:gpt-4o', ); - console.log('current conversation interest', conversationInterest); - console.log('back and forth penalty', backAndForthPenalty); - console.log('decision confidence', decision.content.confidence); + // console.log('current conversation interest', conversationInterest); + // console.log('back and forth penalty', backAndForthPenalty); + // console.log('decision confidence', decision.content.confidence); const calc = conversationInterest - backAndForthPenalty; const blendedInterest = (calc + decision.content.confidence) / 2; const newInterest = Math.max(0, Math.min(1, blendedInterest)); - console.log('new interest', newInterest); + // console.log('new interest', newInterest); targetAgent.conversation.setConversationInterest(newInterest); - console.log('decision', { - decision, - conversationInterest: newInterest, - }); + // console.log('decision', { + // decision, + // conversationInterest: newInterest, + // }); // Use conversation interest to determine if we should respond if (!decision.content.shouldRespond || newInterest < defaultThreshold) { From abae3ab1936762dac939b8e6cbd44e3a3d437eda Mon Sep 17 00:00:00 2001 From: Abdurrehman Subhani Date: Mon, 25 Nov 2024 17:40:19 +0500 Subject: [PATCH 13/15] remove redundant shouldRespond bool --- .../packages/react-agents/default-components.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 c5d5e5541..082feb002 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 @@ -3460,7 +3460,6 @@ export const SelfConsciousReplies: React.FC = (props: `; const decisionSchema = z.object({ - shouldRespond: z.boolean(), reason: z.string(), confidence: z.number(), }); @@ -3491,7 +3490,7 @@ export const SelfConsciousReplies: React.FC = (props: // }); // Use conversation interest to determine if we should respond - if (!decision.content.shouldRespond || newInterest < defaultThreshold) { + if (newInterest < defaultThreshold) { e.abort(); } }} From 340f29767f43ddc62c3539a473f887474a10a337 Mon Sep 17 00:00:00 2001 From: Abdurrehman Subhani Date: Mon, 25 Nov 2024 18:14:37 +0500 Subject: [PATCH 14/15] revert conversationInterest updates in favour of keeping a pure llm based architecture, need to create another complete hueristic based appraoch with the intened behaviour --- .../react-agents/default-components.tsx | 35 +++---------------- 1 file changed, 5 insertions(+), 30 deletions(-) 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 082feb002..dd1db4e3f 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 @@ -3373,7 +3373,7 @@ export const SelfConsciousReplies: React.FC = (props: const { message, sourceAgent, targetAgent } = e.data; // Get conversation members and recent messages in one pass - const [conversationMembers, messages, conversationInterest] = await Promise.all([ + const [conversationMembers, messages] = await Promise.all([ targetAgent.conversation.getAgents(), targetAgent.conversation.getCachedMessages() .slice(-historyLength) @@ -3381,10 +3381,8 @@ export const SelfConsciousReplies: React.FC = (props: name, text: args?.text || '', timestamp - })), - targetAgent.conversation.getConversationInterest(), - ]); - + })) + ]); // Calculate back-and-forth agent conversation count // this is being calculated to determine if the agent is being in the conversation too much const recentMessages = messages.slice(-6); @@ -3419,9 +3417,7 @@ export const SelfConsciousReplies: React.FC = (props: CONVERSATION FATIGUE CONTEXT: - You and ${sourceAgent.name} have had ${backAndForthCount} back-and-forth exchanges recently - Your interest level is reduced by ${(backAndForthPenalty * 100).toFixed()}% due to conversation fatigue - - Your current interest level in the conversation is ${conversationInterest.toFixed(2)} out of 1.0 - If you've been going back and forth too much, you should naturally lose interest and let the conversation end - - Your interest level will affect your likelihood of responding Based on this context, should you respond to this message? @@ -3433,7 +3429,6 @@ export const SelfConsciousReplies: React.FC = (props: 2. Only interrupt conversations between others in rare and justified cases. Your confidence should be very low (< 0.3) if you're considering responding to a message not directed at you. - 3. If the message appears to be directed to the entire group or is a general statement/question: - You should be highly interested in participating - Your confidence should be high (> 0.7) as group discussions warrant active participation @@ -3451,19 +3446,17 @@ export const SelfConsciousReplies: React.FC = (props: - Would responding align with ONLY your defined personality traits? - Is your response truly necessary or would it derail the current conversation? - Are you certain you have unique, valuable information to add if interrupting? - - How does your current interest level (${conversationInterest.toFixed(2)}) affect your desire to respond? Respond with a decision object containing: - shouldRespond: boolean (true if confidence > ${defaultThreshold}) - reason: brief explanation including specific justification if interrupting others' conversation - confidence: number between 0-1 (note: this will be reduced by ${(backAndForthPenalty * 100).toFixed()}% due to conversation fatigue) `; - const decisionSchema = z.object({ + shouldRespond: z.boolean(), reason: z.string(), confidence: z.number(), }); - const decision = await targetAgent.completeJson([{ role: 'assistant', content: decisionPrompt, @@ -3472,25 +3465,7 @@ export const SelfConsciousReplies: React.FC = (props: // 'openai:gpt-4o-mini', 'openai:gpt-4o', ); - - // console.log('current conversation interest', conversationInterest); - // console.log('back and forth penalty', backAndForthPenalty); - // console.log('decision confidence', decision.content.confidence); - - const calc = conversationInterest - backAndForthPenalty; - const blendedInterest = (calc + decision.content.confidence) / 2; - const newInterest = Math.max(0, Math.min(1, blendedInterest)); - - // console.log('new interest', newInterest); - targetAgent.conversation.setConversationInterest(newInterest); - - // console.log('decision', { - // decision, - // conversationInterest: newInterest, - // }); - - // Use conversation interest to determine if we should respond - if (newInterest < defaultThreshold) { + if (!decision.content.shouldRespond) { e.abort(); } }} From 5b7482dfbabfb37afdcceba9009a44d118922fa5 Mon Sep 17 00:00:00 2001 From: Abdurrehman Subhani Date: Mon, 25 Nov 2024 18:20:16 +0500 Subject: [PATCH 15/15] revert conversationInterest from conversation object since following pure llm based reply decision --- .../react-agents/classes/conversation-object.ts | 10 ---------- .../packages/react-agents/types/agents.d.ts | 3 --- 2 files changed, 13 deletions(-) diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents/classes/conversation-object.ts b/packages/usdk/packages/upstreet-agent/packages/react-agents/classes/conversation-object.ts index 8020bd863..eb068bce0 100644 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents/classes/conversation-object.ts +++ b/packages/usdk/packages/upstreet-agent/packages/react-agents/classes/conversation-object.ts @@ -24,7 +24,6 @@ export class ConversationObject extends EventTarget { getHash: GetHashFn; // XXX this can be a string, since conversation hashes do not change (?) messageCache: MessageCache; numTyping: number = 0; - conversationInterest: number = 1; constructor({ agent, @@ -59,15 +58,6 @@ export class ConversationObject extends EventTarget { // - getConversationInterest() { - return this.conversationInterest; - } - setConversationInterest(conversationInterest: number) { - this.conversationInterest = conversationInterest; - } - - // - async typing(fn: () => Promise) { const start = () => { if (++this.numTyping === 1) { diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents/types/agents.d.ts b/packages/usdk/packages/upstreet-agent/packages/react-agents/types/agents.d.ts index f090bdbb8..54f01c5cf 100644 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents/types/agents.d.ts +++ b/packages/usdk/packages/upstreet-agent/packages/react-agents/types/agents.d.ts @@ -279,10 +279,7 @@ export type ConversationObject = EventTarget & { getHash: GetHashFn; messageCache: MessageCache; numTyping: number; - conversationInterest: number; - getConversationInterest: () => number; - setConversationInterest: (conversationInterest: number) => void; getCachedMessages: (filter?: MessageFilter) => ActionMessage[]; /* fetchMessages: (filter?: MessageFilter, opts?: { supabase: any,