From e16b988300c8bba1bc7ebddbec56e1ad65345362 Mon Sep 17 00:00:00 2001 From: Yulong Zhang Date: Wed, 28 Jan 2026 20:53:52 +0000 Subject: pkg/aflow: adding sliding window summary feature This adds a flow feature (and creates a new flow using it) called "sliding window summary". It works by asking the AI to always summarize the latest knowledge, and then we toss the old messages if they fall outside the context sliding window. --- pkg/aflow/testdata/TestSummaryWindow.llm.json | 471 +++++++++++++++++++++ .../testdata/TestSummaryWindow.trajectory.json | 234 ++++++++++ 2 files changed, 705 insertions(+) create mode 100644 pkg/aflow/testdata/TestSummaryWindow.llm.json create mode 100644 pkg/aflow/testdata/TestSummaryWindow.trajectory.json (limited to 'pkg/aflow/testdata') diff --git a/pkg/aflow/testdata/TestSummaryWindow.llm.json b/pkg/aflow/testdata/TestSummaryWindow.llm.json new file mode 100644 index 000000000..b7bbbe06f --- /dev/null +++ b/pkg/aflow/testdata/TestSummaryWindow.llm.json @@ -0,0 +1,471 @@ +[ + { + "Model": "model", + "Config": { + "systemInstruction": { + "parts": [ + { + "text": "Instructions\nPrefer calling several tools at the same time to save round-trips.\n" + } + ], + "role": "user" + }, + "temperature": 0, + "tools": [ + { + "functionDeclarations": [ + { + "description": "logic ticker", + "name": "tick", + "parametersJsonSchema": { + "additionalProperties": false, + "type": "object" + }, + "responseJsonSchema": { + "additionalProperties": false, + "properties": { + "ResFoo": { + "description": "foo", + "type": "integer" + } + }, + "required": [ + "ResFoo" + ], + "type": "object" + } + } + ] + } + ], + "responseModalities": [ + "TEXT" + ] + }, + "Request": [ + { + "parts": [ + { + "text": "Initial Prompt" + } + ], + "role": "user" + } + ] + }, + { + "Model": "model", + "Config": { + "systemInstruction": { + "parts": [ + { + "text": "Instructions\nPrefer calling several tools at the same time to save round-trips.\n" + } + ], + "role": "user" + }, + "temperature": 0, + "tools": [ + { + "functionDeclarations": [ + { + "description": "logic ticker", + "name": "tick", + "parametersJsonSchema": { + "additionalProperties": false, + "type": "object" + }, + "responseJsonSchema": { + "additionalProperties": false, + "properties": { + "ResFoo": { + "description": "foo", + "type": "integer" + } + }, + "required": [ + "ResFoo" + ], + "type": "object" + } + } + ] + } + ], + "responseModalities": [ + "TEXT" + ] + }, + "Request": [ + { + "parts": [ + { + "text": "Initial Prompt" + } + ], + "role": "user" + }, + { + "parts": [ + { + "functionCall": { + "id": "id1", + "name": "tick" + } + } + ], + "role": "user" + }, + { + "parts": [ + { + "functionResponse": { + "id": "id1", + "name": "tick", + "response": { + "ResFoo": 123 + } + } + } + ], + "role": "user" + } + ] + }, + { + "Model": "model", + "Config": { + "systemInstruction": { + "parts": [ + { + "text": "Instructions\nPrefer calling several tools at the same time to save round-trips.\n" + } + ], + "role": "user" + }, + "temperature": 0, + "tools": [ + { + "functionDeclarations": [ + { + "description": "logic ticker", + "name": "tick", + "parametersJsonSchema": { + "additionalProperties": false, + "type": "object" + }, + "responseJsonSchema": { + "additionalProperties": false, + "properties": { + "ResFoo": { + "description": "foo", + "type": "integer" + } + }, + "required": [ + "ResFoo" + ], + "type": "object" + } + } + ] + } + ], + "responseModalities": [ + "TEXT" + ] + }, + "Request": [ + { + "parts": [ + { + "text": "Initial Prompt" + } + ], + "role": "user" + }, + { + "parts": [ + { + "functionCall": { + "id": "id2", + "name": "tick" + } + } + ], + "role": "user" + }, + { + "parts": [ + { + "functionResponse": { + "id": "id2", + "name": "tick", + "response": { + "ResFoo": 123 + } + } + }, + { + "text": "\nYou MUST attach a summary of your most up-to-date findings/knowledge in your reply, which summarizes\nall the historical context, because I will remove old chats if they fall out of the context sliding window\n(for example, I will remove the oldest 3 chats if the sliding window is 10 but there have been 13 LLM chat\nmessages). In your summary, KEEP/INCLUDE ALL useful code. Because I will drop old messages, the code read\nby tools will also be tossed.\n" + } + ], + "role": "user" + } + ] + }, + { + "Model": "model", + "Config": { + "systemInstruction": { + "parts": [ + { + "text": "Instructions\nPrefer calling several tools at the same time to save round-trips.\n" + } + ], + "role": "user" + }, + "temperature": 0, + "tools": [ + { + "functionDeclarations": [ + { + "description": "logic ticker", + "name": "tick", + "parametersJsonSchema": { + "additionalProperties": false, + "type": "object" + }, + "responseJsonSchema": { + "additionalProperties": false, + "properties": { + "ResFoo": { + "description": "foo", + "type": "integer" + } + }, + "required": [ + "ResFoo" + ], + "type": "object" + } + } + ] + } + ], + "responseModalities": [ + "TEXT" + ] + }, + "Request": [ + { + "parts": [ + { + "text": "Initial Prompt" + } + ], + "role": "user" + }, + { + "parts": [ + { + "functionCall": { + "id": "id3", + "name": "tick" + }, + "text": "This is the 1st summary of the history." + } + ], + "role": "user" + }, + { + "parts": [ + { + "functionResponse": { + "id": "id3", + "name": "tick", + "response": { + "ResFoo": 123 + } + } + } + ], + "role": "user" + } + ] + }, + { + "Model": "model", + "Config": { + "systemInstruction": { + "parts": [ + { + "text": "Instructions\nPrefer calling several tools at the same time to save round-trips.\n" + } + ], + "role": "user" + }, + "temperature": 0, + "tools": [ + { + "functionDeclarations": [ + { + "description": "logic ticker", + "name": "tick", + "parametersJsonSchema": { + "additionalProperties": false, + "type": "object" + }, + "responseJsonSchema": { + "additionalProperties": false, + "properties": { + "ResFoo": { + "description": "foo", + "type": "integer" + } + }, + "required": [ + "ResFoo" + ], + "type": "object" + } + } + ] + } + ], + "responseModalities": [ + "TEXT" + ] + }, + "Request": [ + { + "parts": [ + { + "text": "Initial Prompt" + } + ], + "role": "user" + }, + { + "parts": [ + { + "functionCall": { + "id": "id3", + "name": "tick" + }, + "text": "This is the 1st summary of the history." + } + ], + "role": "user" + }, + { + "parts": [ + { + "functionCall": { + "id": "id4", + "name": "tick" + } + } + ], + "role": "user" + }, + { + "parts": [ + { + "functionResponse": { + "id": "id4", + "name": "tick", + "response": { + "ResFoo": 123 + } + } + }, + { + "text": "\nYou MUST attach a summary of your most up-to-date findings/knowledge in your reply, which summarizes\nall the historical context, because I will remove old chats if they fall out of the context sliding window\n(for example, I will remove the oldest 3 chats if the sliding window is 10 but there have been 13 LLM chat\nmessages). In your summary, KEEP/INCLUDE ALL useful code. Because I will drop old messages, the code read\nby tools will also be tossed.\n" + } + ], + "role": "user" + } + ] + }, + { + "Model": "model", + "Config": { + "systemInstruction": { + "parts": [ + { + "text": "Instructions\nPrefer calling several tools at the same time to save round-trips.\n" + } + ], + "role": "user" + }, + "temperature": 0, + "tools": [ + { + "functionDeclarations": [ + { + "description": "logic ticker", + "name": "tick", + "parametersJsonSchema": { + "additionalProperties": false, + "type": "object" + }, + "responseJsonSchema": { + "additionalProperties": false, + "properties": { + "ResFoo": { + "description": "foo", + "type": "integer" + } + }, + "required": [ + "ResFoo" + ], + "type": "object" + } + } + ] + } + ], + "responseModalities": [ + "TEXT" + ] + }, + "Request": [ + { + "parts": [ + { + "text": "Initial Prompt" + } + ], + "role": "user" + }, + { + "parts": [ + { + "functionCall": { + "id": "id5", + "name": "tick" + }, + "text": "This is the 2nd summary." + } + ], + "role": "user" + }, + { + "parts": [ + { + "functionResponse": { + "id": "id5", + "name": "tick", + "response": { + "ResFoo": 123 + } + } + } + ], + "role": "user" + } + ] + } +] \ No newline at end of file diff --git a/pkg/aflow/testdata/TestSummaryWindow.trajectory.json b/pkg/aflow/testdata/TestSummaryWindow.trajectory.json new file mode 100644 index 000000000..bd87b214f --- /dev/null +++ b/pkg/aflow/testdata/TestSummaryWindow.trajectory.json @@ -0,0 +1,234 @@ +[ + { + "Seq": 0, + "Nesting": 0, + "Type": "flow", + "Name": "test", + "Started": "0001-01-01T00:00:01Z" + }, + { + "Seq": 1, + "Nesting": 1, + "Type": "agent", + "Name": "summary_agent", + "Model": "model", + "Started": "0001-01-01T00:00:02Z", + "Instruction": "Instructions\nPrefer calling several tools at the same time to save round-trips.\n", + "Prompt": "Initial Prompt" + }, + { + "Seq": 2, + "Nesting": 2, + "Type": "llm", + "Name": "summary_agent", + "Model": "model", + "Started": "0001-01-01T00:00:03Z" + }, + { + "Seq": 2, + "Nesting": 2, + "Type": "llm", + "Name": "summary_agent", + "Model": "model", + "Started": "0001-01-01T00:00:03Z", + "Finished": "0001-01-01T00:00:04Z" + }, + { + "Seq": 3, + "Nesting": 2, + "Type": "tool", + "Name": "tick", + "Started": "0001-01-01T00:00:05Z" + }, + { + "Seq": 3, + "Nesting": 2, + "Type": "tool", + "Name": "tick", + "Started": "0001-01-01T00:00:05Z", + "Finished": "0001-01-01T00:00:06Z", + "Results": { + "ResFoo": 123 + } + }, + { + "Seq": 4, + "Nesting": 2, + "Type": "llm", + "Name": "summary_agent", + "Model": "model", + "Started": "0001-01-01T00:00:07Z" + }, + { + "Seq": 4, + "Nesting": 2, + "Type": "llm", + "Name": "summary_agent", + "Model": "model", + "Started": "0001-01-01T00:00:07Z", + "Finished": "0001-01-01T00:00:08Z" + }, + { + "Seq": 5, + "Nesting": 2, + "Type": "tool", + "Name": "tick", + "Started": "0001-01-01T00:00:09Z" + }, + { + "Seq": 5, + "Nesting": 2, + "Type": "tool", + "Name": "tick", + "Started": "0001-01-01T00:00:09Z", + "Finished": "0001-01-01T00:00:10Z", + "Results": { + "ResFoo": 123 + } + }, + { + "Seq": 6, + "Nesting": 2, + "Type": "llm", + "Name": "summary_agent", + "Model": "model", + "Started": "0001-01-01T00:00:11Z" + }, + { + "Seq": 6, + "Nesting": 2, + "Type": "llm", + "Name": "summary_agent", + "Model": "model", + "Started": "0001-01-01T00:00:11Z", + "Finished": "0001-01-01T00:00:12Z" + }, + { + "Seq": 7, + "Nesting": 2, + "Type": "tool", + "Name": "tick", + "Started": "0001-01-01T00:00:13Z" + }, + { + "Seq": 7, + "Nesting": 2, + "Type": "tool", + "Name": "tick", + "Started": "0001-01-01T00:00:13Z", + "Finished": "0001-01-01T00:00:14Z", + "Results": { + "ResFoo": 123 + } + }, + { + "Seq": 8, + "Nesting": 2, + "Type": "llm", + "Name": "summary_agent", + "Model": "model", + "Started": "0001-01-01T00:00:15Z" + }, + { + "Seq": 8, + "Nesting": 2, + "Type": "llm", + "Name": "summary_agent", + "Model": "model", + "Started": "0001-01-01T00:00:15Z", + "Finished": "0001-01-01T00:00:16Z" + }, + { + "Seq": 9, + "Nesting": 2, + "Type": "tool", + "Name": "tick", + "Started": "0001-01-01T00:00:17Z" + }, + { + "Seq": 9, + "Nesting": 2, + "Type": "tool", + "Name": "tick", + "Started": "0001-01-01T00:00:17Z", + "Finished": "0001-01-01T00:00:18Z", + "Results": { + "ResFoo": 123 + } + }, + { + "Seq": 10, + "Nesting": 2, + "Type": "llm", + "Name": "summary_agent", + "Model": "model", + "Started": "0001-01-01T00:00:19Z" + }, + { + "Seq": 10, + "Nesting": 2, + "Type": "llm", + "Name": "summary_agent", + "Model": "model", + "Started": "0001-01-01T00:00:19Z", + "Finished": "0001-01-01T00:00:20Z" + }, + { + "Seq": 11, + "Nesting": 2, + "Type": "tool", + "Name": "tick", + "Started": "0001-01-01T00:00:21Z" + }, + { + "Seq": 11, + "Nesting": 2, + "Type": "tool", + "Name": "tick", + "Started": "0001-01-01T00:00:21Z", + "Finished": "0001-01-01T00:00:22Z", + "Results": { + "ResFoo": 123 + } + }, + { + "Seq": 12, + "Nesting": 2, + "Type": "llm", + "Name": "summary_agent", + "Model": "model", + "Started": "0001-01-01T00:00:23Z" + }, + { + "Seq": 12, + "Nesting": 2, + "Type": "llm", + "Name": "summary_agent", + "Model": "model", + "Started": "0001-01-01T00:00:23Z", + "Finished": "0001-01-01T00:00:24Z" + }, + { + "Seq": 1, + "Nesting": 1, + "Type": "agent", + "Name": "summary_agent", + "Model": "model", + "Started": "0001-01-01T00:00:02Z", + "Finished": "0001-01-01T00:00:25Z", + "Instruction": "Instructions\nPrefer calling several tools at the same time to save round-trips.\n", + "Prompt": "Initial Prompt", + "Reply": "Done" + }, + { + "Seq": 0, + "Nesting": 0, + "Type": "flow", + "Name": "test", + "Started": "0001-01-01T00:00:01Z", + "Finished": "0001-01-01T00:00:26Z", + "Results": { + "Reply": "Done" + } + } +] \ No newline at end of file -- cgit mrf-deployment