From fa904859822fbcf3e1b3dd751666165edf1fc0d2 Mon Sep 17 00:00:00 2001
From: yunxilyf <2574379425@qq.com>
Date: Sat, 14 Mar 2026 21:34:51 +0800
Subject: [PATCH 1/4] feat(providers): parse thinking tags in OpenAI compatible
models
---
.../providers/openai_chat_model_compat.py | 37 +++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/src/copaw/providers/openai_chat_model_compat.py b/src/copaw/providers/openai_chat_model_compat.py
index 8d9bf5dd2..7e13f8d33 100644
--- a/src/copaw/providers/openai_chat_model_compat.py
+++ b/src/copaw/providers/openai_chat_model_compat.py
@@ -11,6 +11,10 @@
from agentscope.model import OpenAIChatModel
from agentscope.model._model_response import ChatResponse
from pydantic import BaseModel
+from ..local_models.tag_parser import (
+ extract_thinking_from_text,
+ text_contains_think_tag,
+)
def _clone_with_overrides(obj: Any, **overrides: Any) -> Any:
@@ -198,6 +202,39 @@ async def _parse_openai_stream_response(
response=sanitized_response,
structured_model=structured_model,
):
+ if parsed and isinstance(parsed.content, list):
+ new_content = []
+ for block in parsed.content:
+ if (
+ isinstance(block, dict)
+ and block.get("type") == "text"
+ and isinstance(block.get("text"), str)
+ and text_contains_think_tag(block.get("text"))
+ ):
+ parsed_thinking = extract_thinking_from_text(
+ block.get("text") or "",
+ )
+ if parsed_thinking.thinking:
+ new_content.append(
+ {
+ "type": "thinking",
+ "thinking": parsed_thinking.thinking,
+ },
+ )
+ if parsed_thinking.remaining_text:
+ new_content.append(
+ {
+ "type": "text",
+ "text": parsed_thinking.remaining_text,
+ },
+ )
+ else:
+ new_content.append(block)
+ parsed = ChatResponse(
+ content=new_content,
+ usage=parsed.usage,
+ metadata=getattr(parsed, "metadata", None),
+ )
if sanitized_response.extra_contents:
for block in parsed.content:
if block.get("type") != "tool_use":
From a2d2db27f072e865b3a3e7ff058168c1049971a6 Mon Sep 17 00:00:00 2001
From: yunxilyf <2574379425@qq.com>
Date: Sat, 14 Mar 2026 21:35:01 +0800
Subject: [PATCH 2/4] feat(console): enable message filtering settings for all
channels
---
.../Channels/components/ChannelDrawer.tsx | 38 +++++++++----------
console/src/pages/Control/Channels/index.tsx | 8 ++--
2 files changed, 22 insertions(+), 24 deletions(-)
diff --git a/console/src/pages/Control/Channels/components/ChannelDrawer.tsx b/console/src/pages/Control/Channels/components/ChannelDrawer.tsx
index 193ea0666..94b2532f7 100644
--- a/console/src/pages/Control/Channels/components/ChannelDrawer.tsx
+++ b/console/src/pages/Control/Channels/components/ChannelDrawer.tsx
@@ -541,26 +541,24 @@ export function ChannelDrawer({
)}
- {activeKey !== "console" && (
- <>
-
-
-
-
-
-
- >
- )}
+ <>
+
+
+
+
+
+
+ >
{isBuiltin
? renderBuiltinExtraFields(activeKey)
diff --git a/console/src/pages/Control/Channels/index.tsx b/console/src/pages/Control/Channels/index.tsx
index 3af6f23b1..23c825aa4 100644
--- a/console/src/pages/Control/Channels/index.tsx
+++ b/console/src/pages/Control/Channels/index.tsx
@@ -56,8 +56,8 @@ function ChannelsPage() {
const channelConfig = channels[key] || { enabled: false, bot_prefix: "" };
form.setFieldsValue({
...channelConfig,
- filter_tool_messages: !channelConfig.filter_tool_messages,
- filter_thinking: !channelConfig.filter_thinking,
+ filter_tool_messages: !Boolean(channelConfig.filter_tool_messages),
+ filter_thinking: !Boolean(channelConfig.filter_thinking),
});
};
@@ -74,8 +74,8 @@ function ChannelsPage() {
const updatedChannel: Record = {
...savedConfig,
...values,
- filter_tool_messages: !values.filter_tool_messages,
- filter_thinking: !values.filter_thinking,
+ filter_tool_messages: !Boolean(values.filter_tool_messages),
+ filter_thinking: !Boolean(values.filter_thinking),
};
setSaving(true);
From 12f13e36e005ec6dc91788dd0c1e5447b7528cb5 Mon Sep 17 00:00:00 2001
From: yunxilyf <2574379425@qq.com>
Date: Sat, 14 Mar 2026 21:35:11 +0800
Subject: [PATCH 3/4] chore(gitignore): ignore .copaw working directory
---
.gitignore | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.gitignore b/.gitignore
index c7c3e5f65..8f26d53ca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -89,3 +89,5 @@ CLAUDE.md
# Build cache
.cache/ # Includes conda_unpack_wheels/ for Windows packaging workaround
+.copaw
+.copaw.secret
\ No newline at end of file
From 81c930b0612daf3cb25f4795af2436be2e3ce684 Mon Sep 17 00:00:00 2001
From: yunxilyf <2574379425@qq.com>
Date: Sat, 14 Mar 2026 22:08:04 +0800
Subject: [PATCH 4/4] fix(providers): resolve mypy type check error
---
src/copaw/providers/openai_chat_model_compat.py | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/copaw/providers/openai_chat_model_compat.py b/src/copaw/providers/openai_chat_model_compat.py
index 7e13f8d33..80dcd4e2f 100644
--- a/src/copaw/providers/openai_chat_model_compat.py
+++ b/src/copaw/providers/openai_chat_model_compat.py
@@ -205,14 +205,15 @@ async def _parse_openai_stream_response(
if parsed and isinstance(parsed.content, list):
new_content = []
for block in parsed.content:
+ text_val = block.get("text") if isinstance(block, dict) else None
if (
isinstance(block, dict)
and block.get("type") == "text"
- and isinstance(block.get("text"), str)
- and text_contains_think_tag(block.get("text"))
+ and isinstance(text_val, str)
+ and text_contains_think_tag(text_val)
):
parsed_thinking = extract_thinking_from_text(
- block.get("text") or "",
+ text_val or "",
)
if parsed_thinking.thinking:
new_content.append(