Skip to content

Feat/2.6.0 beta4#2160

Open
RUCYancy wants to merge 12 commits into
releasefrom
feat/2.6.0-beta4
Open

Feat/2.6.0 beta4#2160
RUCYancy wants to merge 12 commits into
releasefrom
feat/2.6.0-beta4

Conversation

@RUCYancy

Copy link
Copy Markdown
Collaborator

No description provided.

zgqgit and others added 5 commits June 11, 2026 17:23
The previous AUTOCOMMIT approach broke chat completions on DaMeng: returning
an isolation_level="AUTOCOMMIT" connection to the pool makes SQLAlchemy reset
the isolation level on checkin, and the dmAsync dialect cannot change session
characteristics while a transaction is open -> dmPython [CODE:-6510]
"Try to change property before transaction end".

Drop async_execute_autocommit entirely and instead wrap touch_session's
UPDATE->COMMIT in asyncio.shield, so a cancelled request cannot interrupt it
between taking the row lock and committing (which leaked the lock). This uses
the normal transaction path (no isolation-level changes), so it is DaMeng-safe.

Test: test_touch_session_completes_write_despite_cancellation.
Copilot AI review requested due to automatic review settings June 11, 2026 11:26

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR advances the v2.6.0 “Linsight task mode” groundwork (Wave-0/Track-0) by adding shared fixtures/POC scripts, introducing a plain-Redis LangGraph checkpointer, and updating backend runtime/build baselines (Python 3.11, dependency + Docker changes) alongside a new default loading SVG for the frontend brand config.

Changes:

  • Add shared Linsight fixtures/stubs (WS event samples, step_type variants, Skill API mock, in-memory workspace backend) plus POC spike scripts and results docs.
  • Introduce PlainRedisCheckpointer (plain Redis, no RediSearch) and add linsight_skill domain model + Alembic migration + Skill error codes / contract updates.
  • Upgrade backend baseline to Python 3.11 (deps + Dockerfile/base image adjustments) and set brand loading icon SVG paths in both frontend bundles.

Reviewed changes

Copilot reviewed 33 out of 36 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/frontend/platform/public/assets/bisheng/loading.svg Adds animated loading SVG asset for platform bundle.
src/frontend/platform/public/assets/bisheng/config.js Points brand loading icon config to the new SVG.
src/frontend/client/public/assets/bisheng/loading.svg Adds animated loading SVG asset for client bundle.
src/frontend/client/public/assets/bisheng/config.js Points brand loading icon config to the new SVG.
src/backend/test/linsight/fixtures/ws_events/step_types.json Adds WS fixture covering task_execute_step.step_type variants.
src/backend/test/linsight/fixtures/ws_events/event_samples.json Adds canonical WS event samples fixture for protocol C1.
src/backend/test/linsight/fixtures/skill_api_mock.json Adds Skill API mock responses + frontmatter/activation/errcode contract notes.
src/backend/test/linsight/fixtures/README.md Documents purpose/usage of shared fixtures/stubs.
src/backend/test/linsight/fixtures/fake_workspace_backend.py Provides in-memory WorkspaceBackend stub for cross-track development.
src/backend/test/linsight/fixtures/init.py Package marker / high-level fixture description.
src/backend/test/database/test_session_lock_safety.py Updates regression tests around cancellation rollback + touch_session behavior.
src/backend/scripts/035-linsight-deepagents/RESULTS.md Captures Wave-0 POC spike conclusions and decisions.
src/backend/scripts/035-linsight-deepagents/README.md Documents how to run POC scripts and what they validate.
src/backend/scripts/035-linsight-deepagents/poc_p5_required_files.py Adds P5 evaluation skeleton for required_files compliance.
src/backend/scripts/035-linsight-deepagents/poc_p4_skill_call_reason.py Adds P4 evaluation skeleton for call_reason + skill hit rate.
src/backend/scripts/035-linsight-deepagents/poc_p3_redis_checkpointer_resume.py Adds P3 checkpointer/interrupt-resume validation script.
src/backend/scripts/035-linsight-deepagents/poc_p2_subgraph_streaming.py Adds P2 subgraph streaming + namespace isolation script.
src/backend/scripts/035-linsight-deepagents/poc_p1_backend_injection.py Adds P1 backend injection validation script.
src/backend/pyproject.toml Raises Python baseline to 3.11, swaps to faust-cchardet, adds deepagents.
src/backend/Dockerfile.dm-test Removes DaMeng connectivity test Dockerfile.
src/backend/Dockerfile Refactors build to use uv sync + venv, updates DM_HOME pathing.
src/backend/bisheng/linsight/domain/services/checkpointer.py Implements plain-Redis LangGraph checkpointer (PlainRedisCheckpointer).
src/backend/bisheng/linsight/domain/models/linsight_skill.py Adds SQLModel for tenant-scoped custom Skill metadata.
src/backend/bisheng/database/models/session.py Changes touch_session to use a shielded update/commit path.
src/backend/bisheng/core/database/tenant_filter.py Type-hint/style adjustments; adds linsight_skill module to import list.
src/backend/bisheng/core/database/manager.py Removes async_execute_autocommit helper wrapper.
src/backend/bisheng/core/database/connection.py Removes async_execute_autocommit implementation.
src/backend/bisheng/core/database/alembic/versions/v2_6_0_f035_linsight_skill.py Adds Alembic migration creating linsight_skill table.
src/backend/bisheng/core/database/init.py Updates exports to remove async_execute_autocommit.
src/backend/bisheng/common/errcode/linsight.py Normalizes strings + adds Skill-management error codes (11051–11055).
src/backend/base.Dockerfile Switches base image to Python 3.11 slim; caches Playwright Chromium install.
features/v2.6.0/release-contract.md Updates release-contract notes for F035 errcode/pylib baseline details.
features/v2.6.0/035-linsight-task-mode/依赖与契约约定.md Freezes contracts; updates C2/C3/C5 details and checklists.
features/v2.6.0/035-linsight-task-mode/tasks.md Updates task plan/status and records key deviations/decisions.
features/v2.6.0/035-linsight-task-mode/design.md Minor wording correction re: tenant resolution in worker context.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/backend/Dockerfile
Comment on lines +5 to +8
# 先装依赖再复制源码,利用 Docker 层缓存:uv.lock 不变时此层命中缓存
COPY ./pyproject.toml ./uv.lock ./
RUN uv sync --frozen --no-dev && uv cache clean
ENV PATH="/app/.venv/bin:$PATH"
Comment thread src/backend/Dockerfile
Comment on lines +10 to +13
# 安装 NLTK 数据(依赖 Python 环境,放在 uv sync 之后)
RUN python -c "import nltk; nltk.download('punkt'); nltk.download('punkt_tab'); nltk.download('averaged_perceptron_tagger'); nltk.download('averaged_perceptron_tagger_eng')"

# Patch SQLAlchemy's aiomysql adapter: AsyncAdapt_aiomysql_connection.ping is
# declared with `reconnect: bool` (no default) in every released 2.0.x, but
# the pymysql dialect's pool pre-checkout calls `dbapi_connection.ping()`
# without args (PyMySQL >= 1.0 defaults reconnect=False, so SQLAlchemy infers
# it can be called bare). The mismatch raises TypeError on every connection
# checkout, which breaks login. Upstream has no fix as of 2.0.49, so we
# inject the default here. Safe to remove once SQLAlchemy ships the fix.
RUN SITE=$(python -c "import site; print(site.getsitepackages()[0])") && \
AIOMYSQL_PY="$SITE/sqlalchemy/dialects/mysql/aiomysql.py" && \
if [ -f "$AIOMYSQL_PY" ]; then \
sed -i 's|def ping(self, reconnect: bool) -> None:|def ping(self, reconnect: bool = False) -> None:|' "$AIOMYSQL_PY" && \
grep -q "def ping(self, reconnect: bool = False)" "$AIOMYSQL_PY" || (echo "sqlalchemy aiomysql ping patch did not apply, aborting build" && exit 1); \
fi
COPY ./ ./
Comment on lines +84 to +87
@staticmethod
def _decode_task_id(encoded: str) -> str:
padding = 4 - len(encoded) % 4
return base64.urlsafe_b64decode(encoded + "=" * padding).decode()
Comment on lines +345 to +369
def get_tuple(self, config: RunnableConfig) -> CheckpointTuple | None:
return asyncio.get_event_loop().run_until_complete(self.aget_tuple(config))

def list(
self,
config: RunnableConfig | None,
*,
filter: dict[str, Any] | None = None,
before: RunnableConfig | None = None,
limit: int | None = None,
):
async def _collect():
return [t async for t in self.alist(config, filter=filter, before=before, limit=limit)]

return iter(asyncio.get_event_loop().run_until_complete(_collect()))

def put(
self,
config: RunnableConfig,
checkpoint: Checkpoint,
metadata: CheckpointMetadata,
new_versions: ChannelVersions,
) -> RunnableConfig:
return asyncio.get_event_loop().run_until_complete(self.aput(config, checkpoint, metadata, new_versions))

Comment on lines +82 to +86
task = asyncio.ensure_future(session_module.MessageSessionDao.touch_session("chat-abc"))
await asyncio.sleep(0) # let the shielded write start
task.cancel()
with pytest.raises(asyncio.CancelledError):
await task
Comment on lines +318 to +328
async def _run() -> None:
async with get_async_db_session() as session:
await session.exec(statement)
await session.commit()

# Shield the UPDATE -> COMMIT so a cancelled request cannot interrupt it
# between taking the row lock and committing, which would leak the lock
# (idle-in-transaction) and stall the pool. AUTOCOMMIT was avoided
# because the dmAsync dialect cannot reset the isolation level on
# connection checkin while a transaction is open ([CODE:-6510]).
await asyncio.shield(_run())
Comment on lines +36 to +40
enabled: bool = Field(
default=True,
description="Whether the skill is enabled",
sa_column=Column("enabled", Integer, nullable=False, server_default=text("1"), comment="Enabled flag"),
)
Comment on lines +19 to +29
import asyncio
import operator
import uuid
from typing import Annotated, TypedDict

from langgraph.checkpoint.memory import InMemorySaver
from langgraph.graph import END, START, StateGraph
from langgraph.types import Command, interrupt

REDIS_URL = "redis://192.168.106.116:6379/9"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants