Skip to content

Commit 28bdae5

Browse files
committed
minor changes
1 parent 6c74476 commit 28bdae5

11 files changed

Lines changed: 27 additions & 206 deletions

File tree

src/server/core/acontext_core/infra/db.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ async def create_tables(self) -> None:
197197
logger.info("pgvector extension init")
198198
async with self.engine.begin() as conn:
199199
await conn.run_sync(ORM_BASE.metadata.create_all)
200+
# Apply idempotent schema patches after the ORM tables exist so older
201+
# deployments pick up the new session title column without a manual migration.
200202
await self._apply_schema_migrations()
201203

202204
self._table_created = True

src/server/core/acontext_core/infra/schema_migrations.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
from sqlalchemy.ext.asyncio import AsyncSession
33

44
DISPLAY_TITLE_COLUMN_PATCH_NAME = "sessions.display_title"
5+
# Use IF NOT EXISTS so the patch is safe on both fresh databases and older
6+
# deployments that may already have the new column.
57
DISPLAY_TITLE_COLUMN_PATCH_SQL = text(
68
"ALTER TABLE sessions ADD COLUMN IF NOT EXISTS display_title TEXT;"
79
)

src/server/core/acontext_core/llm/complete/mock_sdk.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ async def mock_complete(
3232
- If prompt contains "SESSION_TITLE_E2E" -> Create one deterministic task, then stop
3333
- Otherwise return a generic response
3434
"""
35-
# Safe handling of mutable default arguments
35+
# Accept both dict-shaped messages and SDK objects so the mock can stand in
36+
# for the different response-to-message adapters used across the codebase.
3637
history_messages = history_messages or []
3738
prompt_kwargs = prompt_kwargs or {}
3839
prompt_id = prompt_kwargs.get("prompt_id", "mock-prompt")
@@ -70,7 +71,9 @@ async def mock_complete(
7071
)
7172
]
7273
elif "SESSION_TITLE_E2E" in full_text:
74+
# The live e2e test uses this trigger to force one deterministic task.
7375
if "Task 1 created" in full_text:
76+
# After the first tool round, return plain content so the agent stops.
7477
content = "Session title task captured"
7578
tool_calls = None
7679
else:

src/server/core/acontext_core/schema/orm/session.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ class Session(CommonMixin):
5656
default=None, metadata={"db": Column(JSONB, nullable=True)}
5757
)
5858

59+
# Generated, user-facing label for the session. It stays nullable until the
60+
# first real task description is available.
5961
display_title: Optional[str] = field(
6062
default=None, metadata={"db": Column(Text, nullable=True)}
6163
)

src/server/core/acontext_core/service/controller/message.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,17 @@ async def process_session_pending_message(
9191
for m in messages
9292
]
9393

94+
# Resolve the learning-space link in a separate short-lived transaction
95+
# so the message status update path stays focused on queue state.
9496
ls_session = None
9597
async with DB_CLIENT.get_session_context() as session:
9698
r = await LS.get_learning_space_for_session(session, session_id)
9799
_ls_session, eil = r.unpack()
98100
if eil is None:
99101
ls_session = _ls_session
100102

103+
# Run the agent only after the read-only lookups are complete so the
104+
# long-running LLM work does not hold the earlier DB session open.
101105
agent_result = await AT.task_agent_curd(
102106
project_id,
103107
session_id,
@@ -118,6 +122,8 @@ async def process_session_pending_message(
118122
else:
119123
wide["task_agent_outcome"] = "success"
120124

125+
# Persist the final status in a fresh transaction so the message rows
126+
# reflect the agent result even if the agent work was slow.
121127
async with DB_CLIENT.get_session_context() as db_session:
122128
await MD.update_message_status_to(
123129
db_session, pending_message_ids, after_status

src/server/core/acontext_core/service/data/session.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ async def fetch_session(
1616
async def update_session_display_title(
1717
db_session: AsyncSession, session_id: asUUID, display_title: str
1818
) -> Result[None]:
19+
# Force-write helper used by callers that intentionally want to replace a
20+
# previously generated title.
1921
session_record = await db_session.get(Session, session_id)
2022
if session_record is None:
2123
return Result.reject(f"Session {session_id} not found")
@@ -32,6 +34,7 @@ async def update_session_display_title_once(
3234
session_record, eil = (await fetch_session(db_session, session_id)).unpack()
3335
if eil:
3436
return Result.reject(eil.errmsg)
37+
# Preserve the first non-empty title we have already stored.
3538
if (session_record.display_title or "").strip():
3639
return Result.resolve(False)
3740
session_record.display_title = display_title
@@ -46,6 +49,7 @@ async def should_generate_session_display_title(
4649
session_record, eil = r.unpack()
4750
if eil:
4851
return Result.reject(eil.errmsg)
52+
# Empty strings are treated the same as NULL so we can regenerate blanks.
4953
return Result.resolve(
5054
session_record.display_title is None
5155
or session_record.display_title.strip() == ""

src/server/core/acontext_core/service/data/task.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ async def fetch_current_tasks(
9090
async def fetch_first_task_description(
9191
db_session: AsyncSession, session_id: asUUID
9292
) -> Result[str | None]:
93+
# The session title mirrors the first real task, not the planning section.
9394
query = (
9495
select(Task)
9596
.where(Task.session_id == session_id)
@@ -105,6 +106,7 @@ async def fetch_first_task_description(
105106
async def _sync_session_display_title(
106107
db_session: AsyncSession, session_id: asUUID
107108
) -> None:
109+
# Best-effort sync: only write when we have a non-empty title candidate.
108110
title, eil = (await fetch_first_task_description(db_session, session_id)).unpack()
109111
if eil is None and title:
110112
await SD.update_session_display_title_once(db_session, session_id, title)
@@ -139,6 +141,7 @@ async def update_task(
139141
flag_modified(task, "data")
140142

141143
await db_session.flush()
144+
# Flush first so the title lookup sees the final task state for this edit.
142145
await _sync_session_display_title(db_session, task.session_id)
143146
# Changes will be committed when the session context exits
144147
return Result.resolve(task)
@@ -193,6 +196,8 @@ async def insert_task(
193196

194197
db_session.add(task)
195198
await db_session.flush()
199+
# Insertions can change the first visible task, so sync the title after the
200+
# new row is persisted.
196201
await _sync_session_display_title(db_session, session_id)
197202
return Result.resolve(task)
198203

src/server/core/tests/llm/test_mock_sdk.py

Lines changed: 0 additions & 26 deletions
This file was deleted.

src/server/core/tests/service/test_session_data.py

Lines changed: 0 additions & 64 deletions
This file was deleted.

src/server/core/tests/service/test_task_data.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ async def test_fetch_tasks_no_results(self, db_client):
145145
class TestFetchFirstTaskDescription:
146146
@pytest.mark.asyncio
147147
async def test_returns_first_non_planning_task_by_order(self, db_client):
148+
# Planning tasks are excluded so the title comes from the first real task.
148149
async with db_client.get_session_context() as session:
149150
project = Project(
150151
secret_key_hmac="task_title_h1", secret_key_hash_phc="task_title_h1"
@@ -190,6 +191,7 @@ async def test_returns_first_non_planning_task_by_order(self, db_client):
190191

191192
@pytest.mark.asyncio
192193
async def test_returns_none_without_non_planning_tasks(self, db_client):
194+
# A planning-only session should not produce a title candidate.
193195
async with db_client.get_session_context() as session:
194196
project = Project(
195197
secret_key_hmac="task_title_h2", secret_key_hash_phc="task_title_h2"

0 commit comments

Comments
 (0)