源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
Creator App Tests / PR Spam Gate (push) Skipped
Frontend Tests / PR Spam Gate (push) Skipped
NPM Format (website & console) / PR Spam Gate (push) Skipped
Pre-commit Checks / PR Spam Gate (push) Skipped
QwenPaw Creator Plugin Release / check-version (push) Canceled after 0s
QwenPaw Creator Plugin Release / upload-oss (push) Canceled after 0s
Tests / PR Spam Gate (push) Skipped
CodeQL / CodeQL (python) (push) Canceled after 0s
CodeQL / CodeQL (typescript) (push) Canceled after 0s
Creator App Tests / Creator Backend Tests (push) Canceled after 0s
Creator App Tests / Creator UI Build & Tests (push) Canceled after 0s
E2E Smoke Tests / Playwright UI Smoke (push) Canceled after 0s
Frontend Tests / Detect console changes (push) Canceled after 0s
NPM Format (website & console) / website format check (push) Canceled after 0s
NPM Format (website & console) / console format check (push) Canceled after 0s
Pre-commit Checks / Pre-commit (push) Canceled after 0s
QwenPaw Data Plugin Release / check-version (push) Canceled after 0s
Tests / Detect code changes (push) Canceled after 0s
Frontend Tests / Vitest Unit Tests (push) Canceled after 0s
Frontend Tests / Frontend Summary (push) Canceled after 0s
QwenPaw Data Plugin Release / upload-oss (push) Canceled after 0s
Tests / Maintainer Approval (push) Canceled after 0s
Tests / Unit Tests - py3.11 - macos-latest (push) Canceled after 0s
Tests / Unit Tests - py3.11 - ubuntu-latest (push) Canceled after 0s
Tests / Unit Tests - py3.13 - ubuntu-latest (push) Canceled after 0s
Tests / Unit Tests - py3.11 - windows-latest (push) Canceled after 0s
Tests / Contract Tests - py3.11 - macos-latest (push) Canceled after 0s
Tests / Contract Tests - py3.11 - ubuntu-latest (push) Canceled after 0s
Tests / Contract Tests - py3.13 - ubuntu-latest (push) Canceled after 0s
Tests / Contract Tests - py3.11 - windows-latest (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - macos-latest - p0 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - macos-latest - p1 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - macos-latest - p2 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - ubuntu-latest - fallback (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - ubuntu-latest - p0 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - ubuntu-latest - p1 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - ubuntu-latest - p2 (push) Canceled after 0s
Tests / Integrated Tests - py3.13 - ubuntu-latest - p0 (push) Canceled after 0s
Tests / Integrated Tests - py3.13 - ubuntu-latest - p1 (push) Canceled after 0s
Tests / Integrated Tests - py3.13 - ubuntu-latest - p2 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - windows-latest - p0 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - windows-latest - p1 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - windows-latest - p2 (push) Canceled after 0s
Tests / Coverage Report (push) Canceled after 0s
Tests / Test Summary (push) Canceled after 0s
Creator App Tests / PR Spam Gate (push) Skipped
Frontend Tests / PR Spam Gate (push) Skipped
NPM Format (website & console) / PR Spam Gate (push) Skipped
Pre-commit Checks / PR Spam Gate (push) Skipped
QwenPaw Creator Plugin Release / check-version (push) Canceled after 0s
QwenPaw Creator Plugin Release / upload-oss (push) Canceled after 0s
Tests / PR Spam Gate (push) Skipped
CodeQL / CodeQL (python) (push) Canceled after 0s
CodeQL / CodeQL (typescript) (push) Canceled after 0s
Creator App Tests / Creator Backend Tests (push) Canceled after 0s
Creator App Tests / Creator UI Build & Tests (push) Canceled after 0s
E2E Smoke Tests / Playwright UI Smoke (push) Canceled after 0s
Frontend Tests / Detect console changes (push) Canceled after 0s
NPM Format (website & console) / website format check (push) Canceled after 0s
NPM Format (website & console) / console format check (push) Canceled after 0s
Pre-commit Checks / Pre-commit (push) Canceled after 0s
QwenPaw Data Plugin Release / check-version (push) Canceled after 0s
Tests / Detect code changes (push) Canceled after 0s
Frontend Tests / Vitest Unit Tests (push) Canceled after 0s
Frontend Tests / Frontend Summary (push) Canceled after 0s
QwenPaw Data Plugin Release / upload-oss (push) Canceled after 0s
Tests / Maintainer Approval (push) Canceled after 0s
Tests / Unit Tests - py3.11 - macos-latest (push) Canceled after 0s
Tests / Unit Tests - py3.11 - ubuntu-latest (push) Canceled after 0s
Tests / Unit Tests - py3.13 - ubuntu-latest (push) Canceled after 0s
Tests / Unit Tests - py3.11 - windows-latest (push) Canceled after 0s
Tests / Contract Tests - py3.11 - macos-latest (push) Canceled after 0s
Tests / Contract Tests - py3.11 - ubuntu-latest (push) Canceled after 0s
Tests / Contract Tests - py3.13 - ubuntu-latest (push) Canceled after 0s
Tests / Contract Tests - py3.11 - windows-latest (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - macos-latest - p0 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - macos-latest - p1 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - macos-latest - p2 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - ubuntu-latest - fallback (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - ubuntu-latest - p0 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - ubuntu-latest - p1 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - ubuntu-latest - p2 (push) Canceled after 0s
Tests / Integrated Tests - py3.13 - ubuntu-latest - p0 (push) Canceled after 0s
Tests / Integrated Tests - py3.13 - ubuntu-latest - p1 (push) Canceled after 0s
Tests / Integrated Tests - py3.13 - ubuntu-latest - p2 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - windows-latest - p0 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - windows-latest - p1 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - windows-latest - p2 (push) Canceled after 0s
Tests / Coverage Report (push) Canceled after 0s
Tests / Test Summary (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# pylint: disable=protected-access
|
||||
"""Agent-level tests for compression strategy middleware wiring."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from types import SimpleNamespace
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
from agentscope.agent import Agent, ContextConfig, ReActConfig
|
||||
from agentscope.message import HintBlock, Msg, TextBlock
|
||||
from agentscope.tool import Toolkit
|
||||
|
||||
from qwenpaw.agents.command_handler import CommandHandler
|
||||
from qwenpaw.agents.middlewares import (
|
||||
MemoryMiddleware,
|
||||
auto_memory_turn_state,
|
||||
)
|
||||
from qwenpaw.agents.react_agent import QwenPawAgent
|
||||
from qwenpaw.constant import (
|
||||
EXTERNAL_USER_QUERY_MESSAGE_TAG,
|
||||
QWENPAW_MESSAGE_TAG_KEY,
|
||||
)
|
||||
|
||||
|
||||
class _TokenModel:
|
||||
context_size = 100
|
||||
|
||||
async def count_tokens(self, **_kwargs: Any) -> int:
|
||||
return 90
|
||||
|
||||
|
||||
class _MemoryManager:
|
||||
def __init__(self, events: list[str]) -> None:
|
||||
self._events = events
|
||||
self.enabled = True
|
||||
self.submitted: list[list[str]] = []
|
||||
|
||||
def get_memory_prompt(self) -> str:
|
||||
return ""
|
||||
|
||||
async def auto_memory(self, _messages: list[Msg], **_kwargs: Any) -> None:
|
||||
self._events.append("auto_memory")
|
||||
|
||||
def add_summarize_task(
|
||||
self,
|
||||
messages: list[Msg],
|
||||
**_kwargs: Any,
|
||||
) -> None:
|
||||
self._events.append("handler_memory")
|
||||
self.submitted.append([msg.get_text_content() for msg in messages])
|
||||
|
||||
|
||||
def test_qwenpaw_agent_disables_runtime_state_injection() -> None:
|
||||
"""The AgentScope 2.0.6 opt-in must preserve QwenPaw's old prompts."""
|
||||
agent = QwenPawAgent(
|
||||
name="QwenPaw",
|
||||
model=_TokenModel(),
|
||||
system_prompt="",
|
||||
toolkit=Toolkit(tools=[]),
|
||||
react_config=ReActConfig(),
|
||||
middlewares=[],
|
||||
agent_config=SimpleNamespace(language="en-US"),
|
||||
)
|
||||
|
||||
assert agent.injection_config.inject_runtime_state is False
|
||||
|
||||
|
||||
class _ScrollManager:
|
||||
def __init__(self, events: list[str]) -> None:
|
||||
self._events = events
|
||||
self.instructions: HintBlock | None = None
|
||||
self.last_compress = {"evicted": 0, "folded": 0}
|
||||
|
||||
async def compress(
|
||||
self,
|
||||
_agent: Any,
|
||||
_context_config: Any = None,
|
||||
instructions: HintBlock | None = None,
|
||||
) -> None:
|
||||
self.instructions = instructions
|
||||
self.last_compress["evicted"] = 1
|
||||
self._events.append("scroll")
|
||||
|
||||
|
||||
def _scroll_agent(
|
||||
memory_manager: _MemoryManager,
|
||||
scroll_manager: _ScrollManager,
|
||||
) -> QwenPawAgent:
|
||||
agent = object.__new__(QwenPawAgent)
|
||||
Agent.__init__(
|
||||
agent,
|
||||
name="QwenPaw",
|
||||
system_prompt="",
|
||||
model=_TokenModel(),
|
||||
middlewares=[MemoryMiddleware(memory_manager=memory_manager)],
|
||||
context_config=ContextConfig(trigger_ratio=0.5, reserve_ratio=0.1),
|
||||
)
|
||||
agent._agent_config = SimpleNamespace(
|
||||
running=SimpleNamespace(
|
||||
light_context_config=SimpleNamespace(
|
||||
context_compact_config=SimpleNamespace(enabled=True),
|
||||
),
|
||||
),
|
||||
)
|
||||
agent._request_context = {
|
||||
"source": "user",
|
||||
"session_id": "session-1",
|
||||
}
|
||||
agent._context_manager = scroll_manager
|
||||
agent.state.session_id = "session-1"
|
||||
user = Msg(
|
||||
name="user",
|
||||
role="user",
|
||||
content=[TextBlock(type="text", text="remember this")],
|
||||
metadata={
|
||||
QWENPAW_MESSAGE_TAG_KEY: EXTERNAL_USER_QUERY_MESSAGE_TAG,
|
||||
},
|
||||
)
|
||||
user.id = "turn-1"
|
||||
agent.state.context = [user]
|
||||
turn_state = auto_memory_turn_state(agent.state)
|
||||
turn_state["pending"] = ["turn-1"]
|
||||
turn_state["seen"] = {"turn-1": None}
|
||||
return agent
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_scroll_runs_before_auto_memory() -> None:
|
||||
"""Scroll must not bypass AgentScope's compression middleware chain."""
|
||||
events: list[str] = []
|
||||
memory_manager = _MemoryManager(events)
|
||||
scroll_manager = _ScrollManager(events)
|
||||
agent = _scroll_agent(memory_manager, scroll_manager)
|
||||
|
||||
instructions = HintBlock(hint="preserve decisions", source="user")
|
||||
await agent.compress_context(instructions=instructions)
|
||||
|
||||
assert events == ["scroll", "auto_memory"]
|
||||
assert scroll_manager.instructions is instructions
|
||||
assert not auto_memory_turn_state(agent.state)["pending"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_manual_compact_submits_auto_memory_once() -> None:
|
||||
"""The command handler, not compression middleware, owns manual memory."""
|
||||
events: list[str] = []
|
||||
memory_manager = _MemoryManager(events)
|
||||
scroll_manager = _ScrollManager(events)
|
||||
agent = _scroll_agent(memory_manager, scroll_manager)
|
||||
agent.state.context.append(
|
||||
Msg(
|
||||
name="QwenPaw",
|
||||
role="assistant",
|
||||
content=[TextBlock(type="text", text="answer-1")],
|
||||
),
|
||||
)
|
||||
handler = CommandHandler(
|
||||
agent_name="QwenPaw",
|
||||
agent=agent,
|
||||
memory_manager=memory_manager,
|
||||
)
|
||||
handler._get_agent_config = lambda: SimpleNamespace(
|
||||
running=SimpleNamespace(
|
||||
light_context_config=SimpleNamespace(
|
||||
strategy="scroll",
|
||||
context_compact_config=SimpleNamespace(enabled=True),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
await handler.handle_command("/compact")
|
||||
|
||||
assert events == ["scroll", "handler_memory"]
|
||||
assert memory_manager.submitted == [["remember this", "answer-1"]]
|
||||
assert not auto_memory_turn_state(agent.state)["pending"]
|
||||
Reference in New Issue
Block a user