Tracking collected information during the dialog with GPT
You can create asyncmem.dsl
and import "./asyncmem.dsl"
in your project for getting structured key/value dictionary of collected infromation without a latency penalty.
library context { output memory: { [name: string]: string; } = {}; memoryChildBlock: string = ""; input memoryVariables: VariablesDescription = { mood: { description: "mood" }, name: { description: "human first name" }, lastName: { description: "human last name" }, whenCallBack: { description: "when to call back to the human if it's required. in ISO timestamp format" } }; lastMemoryHistory: string = ""; } when starting do { set $memoryChildBlock = (blockcall memory_capturer()).id; } type VariablesDescription = { [name: string]: { description: string; }; } with { toString() : string { var result: string[] = []; for (var k in $this.keys()) { result.push("* " + k + " - " + ($this[k]?.description ?? "")); } return result.join("\n"); } }; preprocessor digression collect_memory { conditions { on true; } do { $.RequestMemoryUpdate(); return; } } function RequestMemoryUpdate(): boolean { var history = #getFormattedTranscription({ history_length: 4 }); if (history == $this.lastMemoryHistory) { return false; } set $this.lastMemoryHistory = history; var childId = $this.memoryChildBlock; var request = { history: history, variables: $this.memoryVariables.toString(), currentMemory: #stringify($this.memory) }; #sendMessageToAsyncBlock(childId, "Content", request ); return true; } type MemoryUpdate = { name: string; value: string; }; type AsyncMemResponse = { messageType:"Content"; sourceRouteId:string; targetRouteId:string; content: { memory: MemoryUpdate[]; }; }; when blockMessage handle_memory_update do { if (#isBlockMessage("Content") && (#getAsyncBlockMessage() as { sourceRouteId: string; })?.sourceRouteId == $memoryChildBlock) { #log("Update memory"); var message = #getAsyncBlockMessage() as AsyncMemResponse; if (message is null) { return; } var content = message.content; var update = content.memory; for (var kv in update) { set $memory[kv.name] = kv.value; } return; } } async block memory_capturer() { type AsyncMemRequest = { messageType:"Content"; sourceRouteId:string; targetRouteId:string; content: { history: string; variables: string; currentMemory: string; }; }; context { memory: MemoryUpdate[] = []; } /** * Call this function when you need to make adjustments to the memory. * @param updates Array of objects with key and value with memory updates * @return nothing */ function setOrUpdateMemory(updates: {key: string, value: string;}[]): unknown { for (var k in updates) { if (k.value != "") { $this.memory.push({ name: k.key, value: k.value }); } } return true; } start node root { do { wait *; } } digression exit_when_parent_block_exit { conditions { on #isBlockMessage("Terminated") tags: onblock; } do { exit; } } digression handle_block_content_message { conditions { on #isBlockMessage("Content") tags: onblock; } do { var message = #getAsyncBlockMessage() as AsyncMemRequest; if (message is null) { return; } var content = message.content; var variables = content.variables; var history = content.history; var currentMemory = content.currentMemory; var time = #unixTimeStamp(); var mem = #askGPT(`Save in to the memory key/value information collected from the human. Important: * Do not update variable with the same value. * Do not pass empty value, if history doesn't contains information related to this variable. Variables (every is optional): {{variables}} Current memory(json): {{currentMemory}} Current unix timestamp is {{time}} History: {{history}}`, { model: "openai/gpt-4o-mini", openai_apikey: "your_apikey", function_call: "setOrUpdateMemory", history_length: 0, save_response_in_history: false }, promptName: "memory_capturer"); #sendMessageToAsyncBlock(message.sourceRouteId, "Content", { memory: $memory } ); set $memory = []; return; } } }
Found a mistake? Let us know.