feat: 添加日历批量操作与客户端时区感知功能,优化前端 UI 交互体验
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
import pytest
|
||||
from ag_ui.core import RunAgentInput
|
||||
from agentscope.message import Msg
|
||||
@@ -208,3 +210,89 @@ async def test_execute_uses_router_ui_mode_to_select_worker_output_model(
|
||||
]
|
||||
assert result["router"]["ui"]["ui_mode"] == "rich"
|
||||
assert result["worker"]["answer"] == "done"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_execute_passes_runtime_client_time_to_router_and_worker(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
runner = AgentScopeRunner()
|
||||
pipeline = _FakePipeline()
|
||||
captured: dict[str, object] = {}
|
||||
|
||||
class _CommitSession:
|
||||
async def commit(self) -> None:
|
||||
return None
|
||||
|
||||
monkeypatch.setattr(
|
||||
"core.agentscope.runtime.runner.AsyncSessionLocal",
|
||||
lambda: _FakeSessionCtx(_CommitSession()),
|
||||
)
|
||||
|
||||
async def _load_system_agent_config(**kwargs):
|
||||
return SystemAgentRuntimeConfig(
|
||||
agent_type=kwargs["agent_type"],
|
||||
model_code="model-a",
|
||||
llm_config=SystemAgentLLMConfig(
|
||||
temperature=0.1, max_tokens=256, timeout_seconds=30
|
||||
),
|
||||
)
|
||||
|
||||
monkeypatch.setattr(runner, "_load_system_agent_config", _load_system_agent_config)
|
||||
|
||||
async def _run_router_stage(**kwargs):
|
||||
captured["router_timezone"] = kwargs["runtime_client_time"].device_timezone
|
||||
return StageExecutionResult(
|
||||
message=Msg(name="router", content="", role="assistant"),
|
||||
payload=_router_output(ui_mode=UiMode.NONE).model_dump(mode="json"),
|
||||
response_metadata={},
|
||||
)
|
||||
|
||||
async def _run_worker_stage(**kwargs):
|
||||
captured["worker_timezone"] = kwargs["runtime_client_time"].device_timezone
|
||||
return StageExecutionResult(
|
||||
message=Msg(name="worker", content="ok", role="assistant"),
|
||||
payload={
|
||||
"status": "success",
|
||||
"answer": "ok",
|
||||
"key_points": [],
|
||||
"result_type": "direct_answer",
|
||||
"suggested_actions": [],
|
||||
"error": None,
|
||||
},
|
||||
response_metadata={},
|
||||
)
|
||||
|
||||
monkeypatch.setattr(runner, "_run_router_stage", _run_router_stage)
|
||||
monkeypatch.setattr(runner, "_run_worker_stage", _run_worker_stage)
|
||||
monkeypatch.setattr(
|
||||
"core.agentscope.runtime.runner.persist_router_message", AsyncMock()
|
||||
)
|
||||
|
||||
run_input = RunAgentInput.model_validate(
|
||||
{
|
||||
"threadId": "00000000-0000-0000-0000-000000000010",
|
||||
"runId": "run-client-time",
|
||||
"state": {},
|
||||
"messages": [{"id": "u1", "role": "user", "content": "hello"}],
|
||||
"tools": [],
|
||||
"context": [],
|
||||
"forwardedProps": {
|
||||
"client_time": {
|
||||
"device_timezone": "America/Los_Angeles",
|
||||
"client_now_iso": "2026-03-16T09:12:33-07:00",
|
||||
"client_epoch_ms": 1773658353000,
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
await runner.execute(
|
||||
user_context=_user_context(),
|
||||
context_messages=[],
|
||||
pipeline=pipeline,
|
||||
run_input=run_input,
|
||||
)
|
||||
|
||||
assert captured["router_timezone"] == "America/Los_Angeles"
|
||||
assert captured["worker_timezone"] == "America/Los_Angeles"
|
||||
|
||||
@@ -157,3 +157,75 @@ def test_parse_run_input_accepts_snake_case_aliases() -> None:
|
||||
assert run_input.thread_id == "00000000-0000-0000-0000-000000000001"
|
||||
assert run_input.run_id == "run-1"
|
||||
validate_run_request_messages_contract(run_input)
|
||||
|
||||
|
||||
def test_parse_run_input_accepts_client_time_forwarded_props() -> None:
|
||||
payload = _base_payload()
|
||||
payload["forwardedProps"] = {
|
||||
"client_time": {
|
||||
"device_timezone": "America/Los_Angeles",
|
||||
"client_now_iso": "2026-03-16T09:12:33-07:00",
|
||||
"client_epoch_ms": 1773658353000,
|
||||
}
|
||||
}
|
||||
|
||||
run_input = parse_run_input(payload)
|
||||
|
||||
assert run_input.forwarded_props is not None
|
||||
|
||||
|
||||
def test_parse_run_input_rejects_invalid_client_time_timezone() -> None:
|
||||
payload = _base_payload()
|
||||
payload["forwardedProps"] = {
|
||||
"client_time": {
|
||||
"device_timezone": "Mars/OlympusMons",
|
||||
"client_now_iso": "2026-03-16T09:12:33-07:00",
|
||||
"client_epoch_ms": 1773658353000,
|
||||
}
|
||||
}
|
||||
|
||||
with pytest.raises(ValueError, match="invalid RunAgentInput.forwardedProps"):
|
||||
parse_run_input(payload)
|
||||
|
||||
|
||||
def test_parse_run_input_rejects_invalid_client_time_now_iso() -> None:
|
||||
payload = _base_payload()
|
||||
payload["forwardedProps"] = {
|
||||
"client_time": {
|
||||
"device_timezone": "America/Los_Angeles",
|
||||
"client_now_iso": "2026-03-16 09:12:33",
|
||||
"client_epoch_ms": 1773658353000,
|
||||
}
|
||||
}
|
||||
|
||||
with pytest.raises(ValueError, match="invalid RunAgentInput.forwardedProps"):
|
||||
parse_run_input(payload)
|
||||
|
||||
|
||||
def test_parse_run_input_rejects_invalid_client_time_epoch_type() -> None:
|
||||
payload = _base_payload()
|
||||
payload["forwardedProps"] = {
|
||||
"client_time": {
|
||||
"device_timezone": "America/Los_Angeles",
|
||||
"client_now_iso": "2026-03-16T09:12:33-07:00",
|
||||
"client_epoch_ms": "1773658353000",
|
||||
}
|
||||
}
|
||||
|
||||
with pytest.raises(ValueError, match="invalid RunAgentInput.forwardedProps"):
|
||||
parse_run_input(payload)
|
||||
|
||||
|
||||
def test_parse_run_input_rejects_unknown_forwarded_props_key() -> None:
|
||||
payload = _base_payload()
|
||||
payload["forwardedProps"] = {
|
||||
"client_time": {
|
||||
"device_timezone": "America/Los_Angeles",
|
||||
"client_now_iso": "2026-03-16T09:12:33-07:00",
|
||||
"client_epoch_ms": 1773658353000,
|
||||
},
|
||||
"unexpected": {"foo": "bar"},
|
||||
}
|
||||
|
||||
with pytest.raises(ValueError, match="invalid RunAgentInput.forwardedProps"):
|
||||
parse_run_input(payload)
|
||||
|
||||
@@ -1,189 +1,166 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timezone
|
||||
from types import SimpleNamespace
|
||||
from typing import Any, cast
|
||||
from typing import Any
|
||||
from uuid import uuid4
|
||||
|
||||
import pytest
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from agentscope.tool import ToolResponse
|
||||
from core.agentscope.tools.custom import calendar as calendar_module
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_calendar_read_returns_list_payload(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
async def _fake_execute(**kwargs: Any) -> dict[str, object]:
|
||||
del kwargs
|
||||
return {"type": "calendar_event_list.v1", "version": "v1", "data": {"ok": True}}
|
||||
def _decode_tool_response(response: ToolResponse) -> dict[str, Any]:
|
||||
assert response.content
|
||||
first = response.content[0]
|
||||
if isinstance(first, dict):
|
||||
text = str(first.get("text", ""))
|
||||
else:
|
||||
text = str(getattr(first, "text", ""))
|
||||
return json.loads(text)
|
||||
|
||||
monkeypatch.setattr(calendar_module, "_execute_list_calendar_events", _fake_execute)
|
||||
monkeypatch.setattr(calendar_module, "_verify_user_token", lambda **_: True)
|
||||
monkeypatch.setattr(calendar_module, "build_tool_response", lambda payload: payload)
|
||||
|
||||
result = await calendar_module.calendar_read(
|
||||
session=cast(AsyncSession, SimpleNamespace()),
|
||||
owner_id=uuid4(),
|
||||
user_token="token-abc",
|
||||
)
|
||||
assert result["type"] == "calendar_event_list.v1"
|
||||
@dataclass
|
||||
class _FakeService:
|
||||
created_request: Any = None
|
||||
|
||||
async def create_agent_generated(self, request):
|
||||
self.created_request = request
|
||||
return SimpleNamespace(
|
||||
id=uuid4(),
|
||||
title=request.title,
|
||||
description=request.description,
|
||||
start_at=request.start_at,
|
||||
end_at=request.end_at,
|
||||
timezone=request.timezone,
|
||||
metadata=request.metadata,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_calendar_read_requires_valid_user_token(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
monkeypatch.setattr(calendar_module, "_verify_user_token", lambda **_: False)
|
||||
monkeypatch.setattr(calendar_module, "build_tool_response", lambda payload: payload)
|
||||
async def test_calendar_write_requires_runtime_context() -> None:
|
||||
result = await calendar_module.calendar_write(operations=["create"])
|
||||
payload = _decode_tool_response(result)
|
||||
|
||||
result = await calendar_module.calendar_read(
|
||||
session=cast(AsyncSession, SimpleNamespace()),
|
||||
owner_id=uuid4(),
|
||||
user_token="bad-token",
|
||||
)
|
||||
|
||||
assert result["data"]["ok"] is False
|
||||
assert result["data"]["code"] == "UNAUTHORIZED"
|
||||
assert payload["status"] == "failure"
|
||||
assert payload["error"]["code"] == "MISSING_RUNTIME_ARGS"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_calendar_write_maps_event_id_for_update(
|
||||
async def test_calendar_write_create_requires_start_at(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
captured: dict[str, object] = {}
|
||||
|
||||
async def _fake_execute(**kwargs: Any) -> dict[str, object]:
|
||||
captured.update(cast(dict[str, object], kwargs["tool_args"]))
|
||||
return {"type": "calendar_card.v1", "version": "v1", "data": {"ok": True}}
|
||||
|
||||
fake_service = _FakeService()
|
||||
monkeypatch.setattr(
|
||||
calendar_module, "_execute_mutate_calendar_event", _fake_execute
|
||||
calendar_module, "create_schedule_service", lambda *_: fake_service
|
||||
)
|
||||
monkeypatch.setattr(calendar_module, "_verify_user_token", lambda **_: True)
|
||||
monkeypatch.setattr(calendar_module, "build_tool_response", lambda payload: payload)
|
||||
|
||||
result = await calendar_module.calendar_write(
|
||||
session=cast(AsyncSession, SimpleNamespace()),
|
||||
operations=["create"],
|
||||
event_timezones=["Asia/Shanghai"],
|
||||
session=SimpleNamespace(),
|
||||
owner_id=uuid4(),
|
||||
user_token="token-abc",
|
||||
operation="update",
|
||||
event_id=str(uuid4()),
|
||||
title="新标题",
|
||||
)
|
||||
assert result["type"] == "calendar_card.v1"
|
||||
assert captured["operation"] == "update"
|
||||
assert "eventId" in captured
|
||||
payload = _decode_tool_response(result)
|
||||
|
||||
assert payload["status"] == "failure"
|
||||
assert payload["error"]["code"] == "INVALID_ARGUMENT"
|
||||
assert "start_at" in payload["error"]["message"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_calendar_write_maps_reminder_minutes(
|
||||
async def test_calendar_write_create_requires_event_timezone(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
captured: dict[str, object] = {}
|
||||
|
||||
async def _fake_execute(**kwargs: Any) -> dict[str, object]:
|
||||
captured.update(cast(dict[str, object], kwargs["tool_args"]))
|
||||
return {"type": "calendar_card.v1", "version": "v1", "data": {"ok": True}}
|
||||
|
||||
fake_service = _FakeService()
|
||||
monkeypatch.setattr(
|
||||
calendar_module, "_execute_mutate_calendar_event", _fake_execute
|
||||
calendar_module, "create_schedule_service", lambda *_: fake_service
|
||||
)
|
||||
monkeypatch.setattr(calendar_module, "_verify_user_token", lambda **_: True)
|
||||
monkeypatch.setattr(calendar_module, "build_tool_response", lambda payload: payload)
|
||||
|
||||
await calendar_module.calendar_write(
|
||||
session=cast(AsyncSession, SimpleNamespace()),
|
||||
owner_id=uuid4(),
|
||||
user_token="token-abc",
|
||||
operation="create",
|
||||
reminder_minutes=15,
|
||||
)
|
||||
|
||||
assert captured["reminderMinutes"] == 15
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_calendar_write_returns_failed_tool_response_on_error(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
async def _fake_execute(**kwargs: Any) -> dict[str, object]:
|
||||
del kwargs
|
||||
raise ValueError("eventId is required")
|
||||
|
||||
monkeypatch.setattr(
|
||||
calendar_module, "_execute_mutate_calendar_event", _fake_execute
|
||||
)
|
||||
monkeypatch.setattr(calendar_module, "_verify_user_token", lambda **_: True)
|
||||
monkeypatch.setattr(calendar_module, "build_tool_response", lambda payload: payload)
|
||||
|
||||
result = await calendar_module.calendar_write(
|
||||
session=cast(AsyncSession, SimpleNamespace()),
|
||||
operations=["create"],
|
||||
start_ats=["2026-03-16T09:00:00+08:00"],
|
||||
session=SimpleNamespace(),
|
||||
owner_id=uuid4(),
|
||||
user_token="token-abc",
|
||||
operation="update",
|
||||
)
|
||||
payload = _decode_tool_response(result)
|
||||
|
||||
assert result["type"] == "calendar_operation.v1"
|
||||
assert result["data"]["ok"] is False
|
||||
assert result["data"]["code"] == "INVALID_ARGUMENT"
|
||||
assert payload["status"] == "failure"
|
||||
assert payload["error"]["code"] == "INVALID_ARGUMENT"
|
||||
assert "event_timezone" in payload["error"]["message"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_calendar_share_maps_arguments(
|
||||
async def test_calendar_write_rejects_naive_start_at(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
captured: dict[str, object] = {}
|
||||
|
||||
async def _fake_execute(**kwargs: Any) -> dict[str, object]:
|
||||
captured.update(cast(dict[str, object], kwargs["tool_args"]))
|
||||
return {
|
||||
"type": "calendar_operation.v1",
|
||||
"version": "v1",
|
||||
"data": {"operation": "share", "ok": True},
|
||||
}
|
||||
|
||||
monkeypatch.setattr(calendar_module, "_execute_share_calendar_event", _fake_execute)
|
||||
monkeypatch.setattr(calendar_module, "_verify_user_token", lambda **_: True)
|
||||
monkeypatch.setattr(calendar_module, "build_tool_response", lambda payload: payload)
|
||||
|
||||
result = await calendar_module.calendar_share(
|
||||
session=cast(AsyncSession, SimpleNamespace()),
|
||||
owner_id=uuid4(),
|
||||
user_token="token-abc",
|
||||
event_id=str(uuid4()),
|
||||
invite_user_emails=["a@example.com"],
|
||||
invite_user_names=["alice"],
|
||||
invite_user_ids=[str(uuid4())],
|
||||
invite_permission_view=True,
|
||||
invite_permission_edit=True,
|
||||
invite_permission_invite=True,
|
||||
fake_service = _FakeService()
|
||||
monkeypatch.setattr(
|
||||
calendar_module, "create_schedule_service", lambda *_: fake_service
|
||||
)
|
||||
|
||||
assert result["type"] == "calendar_operation.v1"
|
||||
assert captured["eventId"]
|
||||
assert captured["inviteUserEmails"] == ["a@example.com"]
|
||||
assert captured["inviteUserNames"] == ["alice"]
|
||||
assert isinstance(captured["inviteUserIds"], list)
|
||||
assert captured["invitePermissionView"] is True
|
||||
assert captured["invitePermissionEdit"] is True
|
||||
assert captured["invitePermissionInvite"] is True
|
||||
result = await calendar_module.calendar_write(
|
||||
operations=["create"],
|
||||
start_ats=["2026-03-16T09:00:00"],
|
||||
event_timezones=["Asia/Shanghai"],
|
||||
session=SimpleNamespace(),
|
||||
owner_id=uuid4(),
|
||||
)
|
||||
payload = _decode_tool_response(result)
|
||||
|
||||
assert payload["status"] == "failure"
|
||||
assert payload["error"]["code"] == "INVALID_ARGUMENT"
|
||||
assert "时区" in payload["error"]["message"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_calendar_share_requires_valid_user_token(
|
||||
async def test_calendar_write_create_normalizes_to_utc(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
monkeypatch.setattr(calendar_module, "_verify_user_token", lambda **_: False)
|
||||
monkeypatch.setattr(calendar_module, "build_tool_response", lambda payload: payload)
|
||||
|
||||
result = await calendar_module.calendar_share(
|
||||
session=cast(AsyncSession, SimpleNamespace()),
|
||||
owner_id=uuid4(),
|
||||
user_token="bad-token",
|
||||
event_id=str(uuid4()),
|
||||
invite_user_emails=["a@example.com"],
|
||||
fake_service = _FakeService()
|
||||
monkeypatch.setattr(
|
||||
calendar_module, "create_schedule_service", lambda *_: fake_service
|
||||
)
|
||||
|
||||
assert result["data"]["ok"] is False
|
||||
assert result["data"]["code"] == "UNAUTHORIZED"
|
||||
result = await calendar_module.calendar_write(
|
||||
operations=["create"],
|
||||
titles=["晨会"],
|
||||
start_ats=["2026-03-16T09:00:00+08:00"],
|
||||
end_ats=["2026-03-16T10:00:00+08:00"],
|
||||
event_timezones=["Asia/Shanghai"],
|
||||
session=SimpleNamespace(),
|
||||
owner_id=uuid4(),
|
||||
)
|
||||
payload = _decode_tool_response(result)
|
||||
|
||||
assert payload["status"] == "success"
|
||||
assert fake_service.created_request is not None
|
||||
request = fake_service.created_request
|
||||
assert request.timezone == "Asia/Shanghai"
|
||||
assert request.start_at == datetime(2026, 3, 16, 1, 0, tzinfo=timezone.utc)
|
||||
assert request.end_at == datetime(2026, 3, 16, 2, 0, tzinfo=timezone.utc)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_calendar_write_rejects_misaligned_batch_lists(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
fake_service = _FakeService()
|
||||
monkeypatch.setattr(
|
||||
calendar_module, "create_schedule_service", lambda *_: fake_service
|
||||
)
|
||||
|
||||
result = await calendar_module.calendar_write(
|
||||
operations=["create", "delete"],
|
||||
start_ats=["2026-03-16T09:00:00+08:00"],
|
||||
event_timezones=["Asia/Shanghai", "Asia/Shanghai"],
|
||||
session=SimpleNamespace(),
|
||||
owner_id=uuid4(),
|
||||
)
|
||||
payload = _decode_tool_response(result)
|
||||
|
||||
assert payload["status"] == "failure"
|
||||
assert payload["error"]["code"] == "INVALID_ARGUMENT"
|
||||
assert "长度必须与 operations 一致" in payload["error"]["message"]
|
||||
|
||||
@@ -7,6 +7,7 @@ from core.agentscope.prompts.system_prompt import (
|
||||
_build_env_section,
|
||||
build_system_prompt,
|
||||
)
|
||||
from schemas.agent.forwarded_props import ClientTimeContext
|
||||
from schemas.agent.system_agent import AgentType
|
||||
from schemas.user.context import UserContext, parse_profile_settings
|
||||
|
||||
@@ -35,6 +36,7 @@ def test_build_env_section_uses_balanced_runtime_context_structure() -> None:
|
||||
section = _build_env_section(
|
||||
user_context=_build_user_context(),
|
||||
now_utc=datetime(2026, 3, 11, 0, 0, tzinfo=timezone.utc),
|
||||
runtime_client_time=None,
|
||||
extra_context=None,
|
||||
)
|
||||
|
||||
@@ -49,7 +51,7 @@ def test_build_env_section_uses_balanced_runtime_context_structure() -> None:
|
||||
assert "Response language default: ai_language=zh-CN." in section
|
||||
assert "UI labels and short actions default: interface_language=zh-CN." in section
|
||||
assert (
|
||||
"Resolve ambiguous dates/times with timezone=Asia/Shanghai and system_time_local."
|
||||
"Resolve ambiguous dates/times with timezone_effective=Asia/Shanghai and system_time_local."
|
||||
in section
|
||||
)
|
||||
assert "Use country=CN only when locale is unspecified." in section
|
||||
@@ -59,6 +61,7 @@ def test_build_env_section_omits_removed_redundant_contract_phrasing() -> None:
|
||||
section = _build_env_section(
|
||||
user_context=_build_user_context(),
|
||||
now_utc=datetime(2026, 3, 11, 0, 0, tzinfo=timezone.utc),
|
||||
runtime_client_time=None,
|
||||
extra_context=None,
|
||||
)
|
||||
|
||||
@@ -91,6 +94,7 @@ def test_build_env_section_includes_optional_privacy_and_notification_hints() ->
|
||||
section = _build_env_section(
|
||||
user_context=user_context,
|
||||
now_utc=datetime(2026, 3, 11, 0, 0, tzinfo=timezone.utc),
|
||||
runtime_client_time=None,
|
||||
extra_context="runtime flag: mobile-client",
|
||||
)
|
||||
|
||||
@@ -105,6 +109,27 @@ def test_build_env_section_includes_optional_privacy_and_notification_hints() ->
|
||||
assert '"system_time_local":"2026-03-11T01:00:00+01:00"' in section
|
||||
|
||||
|
||||
def test_build_env_section_prefers_device_timezone_when_present() -> None:
|
||||
section = _build_env_section(
|
||||
user_context=_build_user_context(timezone_name="Asia/Shanghai"),
|
||||
now_utc=datetime(2026, 3, 11, 0, 0, tzinfo=timezone.utc),
|
||||
runtime_client_time=ClientTimeContext(
|
||||
device_timezone="America/Los_Angeles",
|
||||
client_now_iso="2026-03-10T17:00:00-07:00",
|
||||
client_epoch_ms=1773658353000,
|
||||
),
|
||||
extra_context=None,
|
||||
)
|
||||
|
||||
assert '"timezone_profile":"Asia/Shanghai"' in section
|
||||
assert '"timezone_device":"America/Los_Angeles"' in section
|
||||
assert '"timezone_effective":"America/Los_Angeles"' in section
|
||||
assert (
|
||||
"Resolve ambiguous dates/times with timezone_effective=America/Los_Angeles"
|
||||
in section
|
||||
)
|
||||
|
||||
|
||||
def test_build_system_prompt_keeps_sections_focused_without_language_duplication() -> (
|
||||
None
|
||||
):
|
||||
|
||||
Reference in New Issue
Block a user