chore: initialize EverOS 1.0.0
md-first memory extraction framework for AI agents. Markdown is the single source of truth; SQLite holds state and LanceDB provides the rebuildable vector + BM25 + scalar index. The codebase follows a single-direction DDD layering (entrypoints -> service -> memory -> infra, with component / core / config cross-cutting) enforced by import-linter. Engineering surface: - Coding conventions in .claude/rules/ (path-scoped) and workflows in .claude/skills/ (/commit, /new-branch, /pr). - GitHub Actions CI runs make lint + test + integration; pre-commit mirrors the gates locally (ruff, hygiene hooks, gitlint commit-msg). - Commit messages follow Conventional Commits, enforced by gitlint. - make lint also enforces datetime two-zone discipline and OpenAPI drift.
This commit is contained in:
39
tests/fixtures/README.md
vendored
Normal file
39
tests/fixtures/README.md
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
# Test Fixtures
|
||||
|
||||
The fixtures in this directory are checked-in artifacts. The two largest
|
||||
of them were originally produced by converter scripts that have been
|
||||
removed from the repository — the fixtures themselves are the source of
|
||||
truth and should rarely need to be regenerated.
|
||||
|
||||
## `long_conversation_locomo_caroline_melanie.json`
|
||||
|
||||
Derived from the LoCoMo dataset (`snap-research/locomo`, file
|
||||
`data/locomo10.json`).
|
||||
|
||||
**License: CC BY-NC 4.0** — non-commercial use only. This file is
|
||||
carved out of the project-wide Apache-2.0 license; see `NOTICE` at the
|
||||
repository root for the explicit declaration.
|
||||
|
||||
If you need to regenerate it: fetch `locomo10.json` from the upstream
|
||||
LoCoMo project, then adapt it to the fields the tests consume
|
||||
(`everos_session_id`, `everos_user_id_for_test`, `speakers`,
|
||||
`dialog`, ...). The original conversion script is not part of the
|
||||
public repository.
|
||||
|
||||
## `agent_trajectories/*.json`
|
||||
|
||||
Hand-curated subset of agent tool-call traces. The selection that the
|
||||
e2e tests load is enumerated in
|
||||
`tests/e2e/test_add_flush_agent_pipeline_e2e.py` — that file is the
|
||||
source of truth.
|
||||
|
||||
If you need to add or replace a trajectory, author the fixture by hand
|
||||
(or with your own one-off script). The previous converter pulled from
|
||||
internal paths and is not maintained as part of this repository.
|
||||
|
||||
## `search_seed/`
|
||||
|
||||
LanceDB / SQLite seed bundle for `/search` e2e. Produced by
|
||||
`_dump_search_seed.py` (kept in-tree); regenerate by running that
|
||||
script after a successful `add → flush` pipeline against the LoCoMo
|
||||
fixture above.
|
||||
135
tests/fixtures/_dump_search_seed.py
vendored
Normal file
135
tests/fixtures/_dump_search_seed.py
vendored
Normal file
@ -0,0 +1,135 @@
|
||||
"""One-shot dumper: extract a search-test seed from a corpus snapshot.
|
||||
|
||||
Reads the LanceDB tables under
|
||||
``/tmp/everos_corpus_v2/.index/lancedb/`` (the snapshot produced by
|
||||
``tests/e2e/test_add_flush_user_pipeline_e2e.py`` with ``EVEROS_KEEP_CORPUS_TO``
|
||||
set), samples a small representative slice, and emits JSON fixtures
|
||||
under ``tests/fixtures/search_seed/``.
|
||||
|
||||
Sampling rules:
|
||||
|
||||
- **episode**: first 8 rows per owner (caroline + melanie). Captures
|
||||
the parent_id (= memcell_id) set so downstream tables can be
|
||||
bridge-consistent.
|
||||
- **atomic_fact**: every row whose ``parent_id`` is in the episode-
|
||||
parent set above, capped at 50 to keep the seed compact. This
|
||||
guarantees MRAG-fusion testing can verify "facts sharing a
|
||||
memcell with the matched episode get embedded".
|
||||
- **foresight**: 5 per owner. Archived for future use; current
|
||||
``/search`` does not query foresight, so the seed only exists so
|
||||
downstream tests can opt in without re-cutting the corpus.
|
||||
- **user_profile**: 1 per owner (= 2 total).
|
||||
|
||||
Run::
|
||||
|
||||
python tests/fixtures/_dump_search_seed.py
|
||||
|
||||
Re-run any time the corpus changes; output JSON is committed to
|
||||
git so other contributors don't need the corpus locally.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import lancedb
|
||||
|
||||
CORPUS = Path("/tmp/everos_corpus_v2/.index/lancedb")
|
||||
OUT_DIR = Path(__file__).parent / "search_seed"
|
||||
ALL_OWNERS = ("caroline", "melanie")
|
||||
|
||||
|
||||
def _serialise(row: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Make a LanceDB row dict JSON-safe (numpy → list, datetime → ISO)."""
|
||||
out: dict[str, Any] = {}
|
||||
for k, v in row.items():
|
||||
if v is None:
|
||||
out[k] = None
|
||||
elif hasattr(v, "tolist"): # numpy ndarray (vector)
|
||||
out[k] = v.tolist()
|
||||
elif isinstance(v, datetime):
|
||||
out[k] = v.isoformat()
|
||||
else:
|
||||
out[k] = v
|
||||
return out
|
||||
|
||||
|
||||
def _read(db: lancedb.DBConnection, table: str) -> list[dict[str, Any]]:
|
||||
if f"{table}.lance" not in {p.name for p in CORPUS.iterdir()}:
|
||||
raise FileNotFoundError(f"corpus table missing: {table}")
|
||||
return db.open_table(table).to_arrow().to_pylist()
|
||||
|
||||
|
||||
def main() -> None:
|
||||
if not CORPUS.exists():
|
||||
print(f"corpus not found: {CORPUS}", file=sys.stderr)
|
||||
print("hint: run the add+flush pipeline first with", file=sys.stderr)
|
||||
print(" EVEROS_KEEP_CORPUS_TO=/tmp/everos_corpus_v2", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
OUT_DIR.mkdir(parents=True, exist_ok=True)
|
||||
db = lancedb.connect(str(CORPUS))
|
||||
|
||||
# 1) episodes — first 8 per owner.
|
||||
eps_all = _read(db, "episode")
|
||||
eps: list[dict[str, Any]] = []
|
||||
parent_memcells: set[str] = set()
|
||||
for owner in ALL_OWNERS:
|
||||
owned = [r for r in eps_all if r["owner_id"] == owner][:8]
|
||||
eps.extend(owned)
|
||||
for r in owned:
|
||||
parent_memcells.add(r["parent_id"])
|
||||
|
||||
# 2) atomic_facts — every fact whose parent_id is in the episode
|
||||
# parent set, capped to keep the seed compact (and so MRAG
|
||||
# ``facts_for_episodes`` has a useful but bounded pool to
|
||||
# bucket back into episodes).
|
||||
afs_all = _read(db, "atomic_fact")
|
||||
# Atomic facts fan out per-owner (a single fact about a memcell that
|
||||
# mentions two users gets two rows, one for each owner) — sampling
|
||||
# naively can leave one owner with zero facts. Take per-owner caps
|
||||
# so both caroline and melanie have facts whose parent_id matches
|
||||
# their own episodes' parent_id (MRAG bridge).
|
||||
afs: list[dict[str, Any]] = []
|
||||
for owner in ALL_OWNERS:
|
||||
afs.extend(
|
||||
[
|
||||
r
|
||||
for r in afs_all
|
||||
if r["owner_id"] == owner and r["parent_id"] in parent_memcells
|
||||
][:10]
|
||||
)
|
||||
|
||||
# 3) foresights — 5 per owner, archived for future use.
|
||||
fss_all = _read(db, "foresight")
|
||||
fss: list[dict[str, Any]] = []
|
||||
for owner in ALL_OWNERS:
|
||||
fss.extend([r for r in fss_all if r["owner_id"] == owner][:5])
|
||||
|
||||
# 4) user_profile — 1 per owner.
|
||||
ups_all = _read(db, "user_profile")
|
||||
ups = [r for r in ups_all if r["owner_id"] in ALL_OWNERS]
|
||||
|
||||
written: list[tuple[str, int, int]] = []
|
||||
for name, rows in (
|
||||
("episode", eps),
|
||||
("atomic_fact", afs),
|
||||
("foresight", fss),
|
||||
("user_profile", ups),
|
||||
):
|
||||
serialised = [_serialise(r) for r in rows]
|
||||
out = OUT_DIR / f"{name}.json"
|
||||
out.write_text(json.dumps(serialised, indent=2, default=str))
|
||||
written.append((name, len(serialised), out.stat().st_size))
|
||||
|
||||
for name, count, size in written:
|
||||
print(f" {name:14s}: {count:3d} rows ({size // 1024} KB)")
|
||||
print(f" parent_memcells captured: {len(parent_memcells)}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
1183
tests/fixtures/agent_trajectories/session_django_14311.json
vendored
Normal file
1183
tests/fixtures/agent_trajectories/session_django_14311.json
vendored
Normal file
File diff suppressed because one or more lines are too long
355
tests/fixtures/agent_trajectories/session_django_16255.json
vendored
Normal file
355
tests/fixtures/agent_trajectories/session_django_16255.json
vendored
Normal file
@ -0,0 +1,355 @@
|
||||
{
|
||||
"source_file": "0043.json",
|
||||
"swe_bench_task": "django/django-16255",
|
||||
"everos_session_id": "session_django_16255",
|
||||
"everos_agent_sender_id": "agent_django",
|
||||
"everos_user_sender_id": "user_001",
|
||||
"everos_tool_sender_id": "tool_runner",
|
||||
"base_timestamp_ms": 1700000000000,
|
||||
"inter_message_gap_ms": 1000,
|
||||
"message_count": 30,
|
||||
"conversion_rules": {
|
||||
"role": "verbatim from source (user / assistant / tool)",
|
||||
"sender_id": "user→user_001, assistant→agent_<project>, tool→tool_runner",
|
||||
"timestamp": "BASE_TIMESTAMP_MS + idx * 1000",
|
||||
"content": "verbatim; empty string for assistant tool-call-only turns",
|
||||
"tool_calls": "kept on assistant rows (OpenAI Chat Completions shape)",
|
||||
"tool_call_id": "kept on tool rows"
|
||||
},
|
||||
"messages": [
|
||||
{
|
||||
"sender_id": "user_001",
|
||||
"role": "user",
|
||||
"timestamp": 1700000000000,
|
||||
"content": "WRAPPER_PATH: /tmp/sweb.eval.django__django-16255.full-run-exec\n\n你需要修复一个开源项目的 bug。代码仓库是 django/django,已经 checkout 到了 bug 存在的版本。\n任务总时限 30 分钟,请合理安排时间。\n\n【严格规则】\n- 所有命令必须通过 WRAPPER_PATH 执行\n- 严禁使用 read、write、edit、Read、Write、Edit 工具(这些工具操作的是宿主机,不是任务环境)\n- 严禁直接使用 exec 运行命令(必须通过 WRAPPER_PATH)\n- 写文件必须用 WRAPPER_PATH write,不要用 tmux-run + cat/heredoc(会有转义问题)\n- 不要修改测试文件\n- 严禁执行 git commit、git add、git stash 等 git 操作,只需修改文件即可,评测系统会自动收集你的改动\n\n操作方式:\n 执行命令: exec(\"/tmp/sweb.eval.django__django-16255.full-run-exec tmux-run \\\"命令\\\" 等待秒数\")\n 轮询等待: exec(\"/tmp/sweb.eval.django__django-16255.full-run-exec tmux-run \\\"\\\" 10\")\n 写文件: exec(\"/tmp/sweb.eval.django__django-16255.full-run-exec write /目标路径 << 'EOF'\\n文件内容\\nEOF\")\n 中断命令: exec(\"/tmp/sweb.eval.django__django-16255.full-run-exec tmux-run \\\"ctrl-c\\\" 3\")\n\n## Bug 描述\n\nSitemaps without items raise ValueError on callable lastmod.\nDescription\n\t\nWhen sitemap contains not items, but supports returning lastmod for an item, it fails with a ValueError:\nTraceback (most recent call last):\n File \"/usr/local/lib/python3.10/site-packages/django/core/handlers/exception.py\", line 55, in inner\n\tresponse = get_response(request)\n File \"/usr/local/lib/python3.10/site-packages/django/core/handlers/base.py\", line 197, in _get_response\n\tresponse = wrapped_callback(request, *callback_args, **callback_kwargs)\n File \"/usr/local/lib/python3.10/site-packages/django/utils/decorators.py\", line 133, in _wrapped_view\n\tresponse = view_func(request, *args, **kwargs)\n File \"/usr/local/lib/python3.10/site-packages/django/contrib/sitemaps/views.py\", line 34, in inner\n\tresponse = func(request, *args, **kwargs)\n File \"/usr/local/lib/python3.10/site-packages/django/contrib/sitemaps/views.py\", line 76, in index\n\tsite_lastmod = site.get_latest_lastmod()\n File \"/usr/local/lib/python3.10/site-packages/django/contrib/sitemaps/__init__.py\", line 170, in get_latest_lastmod\n\treturn max([self.lastmod(item) for item in self.items()])\nException Type: ValueError at /sitemap.xml\nException Value: max() arg is an empty sequence\nSomething like this might be a solution:\n\t def get_latest_lastmod(self):\n\t\t if not hasattr(self, \"lastmod\"):\n\t\t\t return None\n\t\t if callable(self.lastmod):\n\t\t\t try:\n\t\t\t\t return max([self.lastmod(item) for item in self.items()])\n-\t\t\texcept TypeError:\n+\t\t\texcept (TypeError, ValueError):\n\t\t\t\t return None\n\t\t else:\n\t\t\t return self.lastmod\n\n\n修复完成后回复 TASK_COMPLETE。"
|
||||
},
|
||||
{
|
||||
"sender_id": "agent_django",
|
||||
"role": "assistant",
|
||||
"timestamp": 1700000001000,
|
||||
"content": "",
|
||||
"tool_calls": [
|
||||
{
|
||||
"id": "call_2a516e487ab64c7093b0e8da",
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "exec",
|
||||
"arguments": "{\"command\": \"/tmp/sweb.eval.django__django-16255.full-run-exec tmux-run \\\"find /testbed -name '*.py' -path '*/sitemaps/*' | head -20\\\" 5\"}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"sender_id": "tool_runner",
|
||||
"role": "tool",
|
||||
"timestamp": 1700000002000,
|
||||
"content": "(testbed) root@55ab59df2a68:/testbed# find /testbed -name '*.py' -path '*/sitemaps/*' | head -20\n/testbed/django/contrib/gis/sitemaps/__init__.py\n/testbed/django/contrib/gis/sitemaps/views.py\n/testbed/django/contrib/gis/sitemaps/kml.py\n/testbed/django/contrib/sitemaps/management/commands/__init__.py\n... (42 lines omitted) ...",
|
||||
"tool_call_id": "call_2a516e487ab64c7093b0e8da"
|
||||
},
|
||||
{
|
||||
"sender_id": "agent_django",
|
||||
"role": "assistant",
|
||||
"timestamp": 1700000003000,
|
||||
"content": "",
|
||||
"tool_calls": [
|
||||
{
|
||||
"id": "call_6142f3a745ac480dbe29f2f1",
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "exec",
|
||||
"arguments": "{\"command\": \"/tmp/sweb.eval.django__django-16255.full-run-exec tmux-run \\\"cat /testbed/django/contrib/sitemaps/__init__.py\\\" 5\"}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"sender_id": "tool_runner",
|
||||
"role": "tool",
|
||||
"timestamp": 1700000004000,
|
||||
"content": "(testbed) root@55ab59df2a68:/testbed# cat /testbed/django/contrib/sitemaps/__init__.py\nimport warnings\nfrom urllib.parse import urlencode\nfrom urllib.request import urlopen\n\n... (205 lines omitted) ...\n }\n )\n if self.x_default:\n lang_code = settings.LANGUAGE_CODE\n loc = f\"{protocol}://{domain}{self._location(item, lang_code)}\"\n loc = loc.replace(f\"/{lang_code}/\", \"/\", 1)\n url_info[\"alternates\"].append(\n {\n \"location\": loc,\n \"lang_code\": \"x-default\",\n }\n )\n\n urls.append(url_info)\n\n if all_items_lastmod and latest_lastmod:\n self.latest_lastmod = latest_lastmod\n\n return urls\n\n\nclass GenericSitemap(Sitemap):\n priority = None\n changefreq = None\n\n def __init__(self, info_dict, priority=None, changefreq=None, protocol=None):\n self.queryset = info_dict[\"queryset\"]\n self.date_field = info_dict.get(\"date_field\")\n self.priority = self.priority or priority\n self.changefreq = self.changefreq or changefreq\n self.protocol = self.protocol or protocol\n\n def items(self):\n # Make sure to return a clone; we don't want premature evaluation.\n return self.queryset.filter()\n\n def lastmod(self, item):\n if self.date_field is not None:\n return getattr(item, self.date_field)\n return None\n\n def get_latest_lastmod(self):\n if self.date_field is not None:\n return (\n self.queryset.order_by(\"-\" + self.date_field)\n .values_list(self.date_field, flat=True)\n .first()\n )\n return None\n(testbed) root@55ab59df2a68:/testbed#",
|
||||
"tool_call_id": "call_6142f3a745ac480dbe29f2f1"
|
||||
},
|
||||
{
|
||||
"sender_id": "agent_django",
|
||||
"role": "assistant",
|
||||
"timestamp": 1700000005000,
|
||||
"content": "",
|
||||
"tool_calls": [
|
||||
{
|
||||
"id": "call_c991e3fac2c24689989e7fe3",
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "exec",
|
||||
"arguments": "{\"command\": \"/tmp/sweb.eval.django__django-16255.full-run-exec tmux-run \\\"grep -n 'get_latest_lastmod' /testbed/django/contrib/sitemaps/__init__.py\\\" 3\"}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"sender_id": "tool_runner",
|
||||
"role": "tool",
|
||||
"timestamp": 1700000006000,
|
||||
"content": "(testbed) root@55ab59df2a68:/testbed# grep -n 'get_latest_lastmod' /testbed/django/contrib/sitemaps/__init__.py\n165: def get_latest_lastmod(self):\n251: def get_latest_lastmod(self):\n(testbed) root@55ab59df2a68:/testbed#",
|
||||
"tool_call_id": "call_c991e3fac2c24689989e7fe3"
|
||||
},
|
||||
{
|
||||
"sender_id": "agent_django",
|
||||
"role": "assistant",
|
||||
"timestamp": 1700000007000,
|
||||
"content": "",
|
||||
"tool_calls": [
|
||||
{
|
||||
"id": "call_337dae1280a8457ea798ce4b",
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "exec",
|
||||
"arguments": "{\"command\": \"/tmp/sweb.eval.django__django-16255.full-run-exec tmux-run \\\"sed -n '160,180p' /testbed/django/contrib/sitemaps/__init__.py\\\" 3\"}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"sender_id": "tool_runner",
|
||||
"role": "tool",
|
||||
"timestamp": 1700000008000,
|
||||
"content": "(testbed) root@55ab59df2a68:/testbed# sed -n '160,180p' /testbed/django/contrib/sitemaps/__init__.py\n def get_urls(self, page=1, site=None, protocol=None):\n protocol = self.get_protocol(protocol)\n domain = self.get_domain(site)\n return self._urls(page, protocol, domain)\n\n def get_latest_lastmod(self):\n if not hasattr(self, \"lastmod\"):\n return None\n if callable(self.lastmod):\n try:\n return max([self.lastmod(item) for item in self.items()])\n except TypeError:\n return None\n else:\n return self.lastmod\n\n def _urls(self, page, protocol, domain):\n urls = []\n latest_lastmod = None\n all_items_lastmod = True # track if all items have a lastmod\n\n(testbed) root@55ab59df2a68:/testbed#",
|
||||
"tool_call_id": "call_337dae1280a8457ea798ce4b"
|
||||
},
|
||||
{
|
||||
"sender_id": "agent_django",
|
||||
"role": "assistant",
|
||||
"timestamp": 1700000009000,
|
||||
"content": "Now I can see the bug. The `get_latest_lastmod` method at line 165-174 catches `TypeError` but not `ValueError`. When `self.items()` returns an empty list, `max()` raises `ValueError: max() arg is an empty sequence`.\n\nLet me fix this by adding `ValueError` to the exception handling:",
|
||||
"tool_calls": [
|
||||
{
|
||||
"id": "call_a763a7e71fc8408fb45e9ce0",
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "exec",
|
||||
"arguments": "{\"command\": \"/tmp/sweb.eval.django__django-16255.full-run-exec tmux-run \\\"sed -n '165,175p' /testbed/django/contrib/sitemaps/__init__.py\\\" 3\"}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"sender_id": "tool_runner",
|
||||
"role": "tool",
|
||||
"timestamp": 1700000010000,
|
||||
"content": "(testbed) root@55ab59df2a68:/testbed# sed -n '165,175p' /testbed/django/contrib/sitemaps/__init__.py\n def get_latest_lastmod(self):\n if not hasattr(self, \"lastmod\"):\n return None\n if callable(self.lastmod):\n try:\n return max([self.lastmod(item) for item in self.items()])\n except TypeError:\n return None\n else:\n return self.lastmod\n\n(testbed) root@55ab59df2a68:/testbed#",
|
||||
"tool_call_id": "call_a763a7e71fc8408fb45e9ce0"
|
||||
},
|
||||
{
|
||||
"sender_id": "agent_django",
|
||||
"role": "assistant",
|
||||
"timestamp": 1700000011000,
|
||||
"content": "",
|
||||
"tool_calls": [
|
||||
{
|
||||
"id": "call_9602e2041f164372812d86e2",
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "exec",
|
||||
"arguments": "{\"command\": \"/tmp/sweb.eval.django__django-16255.full-run-exec tmux-run \\\"sed -i 's/except TypeError:/except (TypeError, ValueError):/' /testbed/django/contrib/sitemaps/__init__.py\\\" 3\"}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"sender_id": "tool_runner",
|
||||
"role": "tool",
|
||||
"timestamp": 1700000012000,
|
||||
"content": "(testbed) root@55ab59df2a68:/testbed# sed -i 's/except TypeError:/except (TypeError, ValueError):/' /testbed/django/contrib/sitemaps/__init__.py\n(testbed) root@55ab59df2a68:/testbed#",
|
||||
"tool_call_id": "call_9602e2041f164372812d86e2"
|
||||
},
|
||||
{
|
||||
"sender_id": "agent_django",
|
||||
"role": "assistant",
|
||||
"timestamp": 1700000013000,
|
||||
"content": "",
|
||||
"tool_calls": [
|
||||
{
|
||||
"id": "call_dfd83b1b3eee49fbb28a9654",
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "exec",
|
||||
"arguments": "{\"command\": \"/tmp/sweb.eval.django__django-16255.full-run-exec tmux-run \\\"sed -n '165,175p' /testbed/django/contrib/sitemaps/__init__.py\\\" 3\"}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"sender_id": "tool_runner",
|
||||
"role": "tool",
|
||||
"timestamp": 1700000014000,
|
||||
"content": "(testbed) root@55ab59df2a68:/testbed# sed -n '165,175p' /testbed/django/contrib/sitemaps/__init__.py\n def get_latest_lastmod(self):\n if not hasattr(self, \"lastmod\"):\n return None\n if callable(self.lastmod):\n try:\n return max([self.lastmod(item) for item in self.items()])\n except (TypeError, ValueError):\n return None\n else:\n return self.lastmod\n\n(testbed) root@55ab59df2a68:/testbed#",
|
||||
"tool_call_id": "call_dfd83b1b3eee49fbb28a9654"
|
||||
},
|
||||
{
|
||||
"sender_id": "agent_django",
|
||||
"role": "assistant",
|
||||
"timestamp": 1700000015000,
|
||||
"content": "The fix has been applied. Let me verify it works by running the sitemap tests:",
|
||||
"tool_calls": [
|
||||
{
|
||||
"id": "call_fd3ac38f848f45d594861cf5",
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "exec",
|
||||
"arguments": "{\"command\": \"/tmp/sweb.eval.django__django-16255.full-run-exec tmux-run \\\"cd /testbed && python -m pytest tests/sitemaps_tests/test_sitemap.py -v -x 2>&1 | head -100\\\" 30\"}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"sender_id": "tool_runner",
|
||||
"role": "tool",
|
||||
"timestamp": 1700000016000,
|
||||
"content": "(testbed) root@55ab59df2a68:/testbed# cd /testbed && python -m pytest tests/sitemaps_tests/test_sitemap.py -v -x 2>&1 | head -100\n/opt/miniconda3/envs/testbed/bin/python: No module named pytest\n(testbed) root@55ab59df2a68:/testbed#",
|
||||
"tool_call_id": "call_fd3ac38f848f45d594861cf5"
|
||||
},
|
||||
{
|
||||
"sender_id": "agent_django",
|
||||
"role": "assistant",
|
||||
"timestamp": 1700000017000,
|
||||
"content": "",
|
||||
"tool_calls": [
|
||||
{
|
||||
"id": "call_749cde7219dd49d6a193fe05",
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "exec",
|
||||
"arguments": "{\"command\": \"/tmp/sweb.eval.django__django-16255.full-run-exec tmux-run \\\"cd /testbed && python runtests.py sitemaps_tests 2>&1 | tail -50\\\" 30\"}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"sender_id": "tool_runner",
|
||||
"role": "tool",
|
||||
"timestamp": 1700000018000,
|
||||
"content": "(testbed) root@55ab59df2a68:/testbed# cd /testbed && python runtests.py sitemaps_tests 2>&1 | tail -50\npython: can't open file '/testbed/runtests.py': [Errno 2] No such file or directory\n(testbed) root@55ab59df2a68:/testbed#",
|
||||
"tool_call_id": "call_749cde7219dd49d6a193fe05"
|
||||
},
|
||||
{
|
||||
"sender_id": "agent_django",
|
||||
"role": "assistant",
|
||||
"timestamp": 1700000019000,
|
||||
"content": "",
|
||||
"tool_calls": [
|
||||
{
|
||||
"id": "call_058e8950b1234318b8360376",
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "exec",
|
||||
"arguments": "{\"command\": \"/tmp/sweb.eval.django__django-16255.full-run-exec tmux-run \\\"find /testbed -name 'runtests.py' 2>/dev/null | head -5\\\" 5\"}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"sender_id": "tool_runner",
|
||||
"role": "tool",
|
||||
"timestamp": 1700000020000,
|
||||
"content": "(testbed) root@55ab59df2a68:/testbed# find /testbed -name 'runtests.py' 2>/dev/null | head -5\n/testbed/tests/runtests.py\n(testbed) root@55ab59df2a68:/testbed#",
|
||||
"tool_call_id": "call_058e8950b1234318b8360376"
|
||||
},
|
||||
{
|
||||
"sender_id": "agent_django",
|
||||
"role": "assistant",
|
||||
"timestamp": 1700000021000,
|
||||
"content": "",
|
||||
"tool_calls": [
|
||||
{
|
||||
"id": "call_be1f9922d97f4387a78de883",
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "exec",
|
||||
"arguments": "{\"command\": \"/tmp/sweb.eval.django__django-16255.full-run-exec tmux-run \\\"cd /testbed && python tests/runtests.py sitemaps_tests 2>&1 | tail -50\\\" 30\"}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"sender_id": "tool_runner",
|
||||
"role": "tool",
|
||||
"timestamp": 1700000022000,
|
||||
"content": "(testbed) root@55ab59df2a68:/testbed# cd /testbed && python tests/runtests.py sitemaps_tests 2>&1 | tail -50\nCreating test database for alias 'default'...\nTesting against Django installed in '/testbed/django' with up to 128 processes\nFound 60 test(s).\nCloning test database for alias 'default'...\nCloning test database for alias 'default'...\nCloning test database for alias 'default'...\nCloning test database for alias 'default'...\nCloning test database for alias 'default'...\nCloning test database for alias 'default'...\nCloning test database for alias 'default'...\nSystem check identified no issues (0 silenced).\n............................................................\n----------------------------------------------------------------------\nRan 60 tests in 0.133s\n\nOK\nDestroying test database for alias 'default'...\nDestroying test database for alias 'default'...\nDestroying test database for alias 'default'...\nDestroying test database for alias 'default'...\nDestroying test database for alias 'default'...\nDestroying test database for alias 'default'...\nDestroying test database for alias 'default'...\nDestroying test database for alias 'default'...\n(testbed) root@55ab59df2a68:/testbed#",
|
||||
"tool_call_id": "call_be1f9922d97f4387a78de883"
|
||||
},
|
||||
{
|
||||
"sender_id": "agent_django",
|
||||
"role": "assistant",
|
||||
"timestamp": 1700000023000,
|
||||
"content": "All 60 sitemap tests pass. Let me also create a quick test to verify the specific bug scenario is fixed:",
|
||||
"tool_calls": [
|
||||
{
|
||||
"id": "call_a9cced7b7ac140d3b46b54d0",
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "exec",
|
||||
"arguments": "{\"command\": \"/tmp/sweb.eval.django__django-16255.full-run-exec tmux-run \\\"cd /testbed && python -c \\\\\\\"\\\\nfrom django.contrib.sitemaps import Sitemap\\\\n\\\\nclass EmptySitemap(Sitemap):\\\\n def items(self):\\\\n return []\\\\n \\\\n def lastmod(self, item):\\\\n return None\\\\n\\\\nsitemap = EmptySitemap()\\\\nresult = sitemap.get_latest_lastmod()\\\\nprint(f'Result: {result}')\\\\nprint('Bug is fixed! No ValueError raised.')\\\\n\\\\\\\" 2>&1\\\" 5\"}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"sender_id": "tool_runner",
|
||||
"role": "tool",
|
||||
"timestamp": 1700000024000,
|
||||
"content": "(testbed) root@55ab59df2a68:/testbed# cd /testbed && python -c \"\\nfrom django.contrib.sitemaps import Sitemap\\n\\nclass EmptySitemap(Sitemap):\\n def items(self):\\n return []\\n \\n def la\nstmod(self, item):\\n return None\\n\\nsitemap = EmptySitemap()\\nresult = sitemap.get_latest_lastmod()\\nprint(f'Result: {result}')\\nprint('Bug is fixed! No ValueError raised.')\\n\" 2>&1\n File \"<string>\", line 1\n \\nfrom django.contrib.sitemaps import Sitemap\\n\\nclass EmptySitemap(Sitemap):\\n def items(self):\\n return []\\n \\n def lastmod(self, item):\\n return None\\n\\nsitemap = EmptySi\ntemap()\\nresult = sitemap.get_latest_lastmod()\\nprint(f'Result: {result}')\\nprint('Bug is fixed! No ValueError raised.')\\n\n ^\nSyntaxError: unexpected character after line continuation character\n(testbed) root@55ab59df2a68:/testbed#",
|
||||
"tool_call_id": "call_a9cced7b7ac140d3b46b54d0"
|
||||
},
|
||||
{
|
||||
"sender_id": "agent_django",
|
||||
"role": "assistant",
|
||||
"timestamp": 1700000025000,
|
||||
"content": "",
|
||||
"tool_calls": [
|
||||
{
|
||||
"id": "call_113222361ba64a98b38b2211",
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "exec",
|
||||
"arguments": "{\"command\": \"/tmp/sweb.eval.django__django-16255.full-run-exec write /tmp/test_fix.py << 'EOF'\\nfrom django.contrib.sitemaps import Sitemap\\n\\nclass EmptySitemap(Sitemap):\\n def items(self):\\n return []\\n \\n def lastmod(self, item):\\n return None\\n\\nsitemap = EmptySitemap()\\nresult = sitemap.get_latest_lastmod()\\nprint(f'Result: {result}')\\nprint('Bug is fixed! No ValueError raised.')\\nEOF\"}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"sender_id": "tool_runner",
|
||||
"role": "tool",
|
||||
"timestamp": 1700000026000,
|
||||
"content": "Written 303 bytes to /tmp/test_fix.py",
|
||||
"tool_call_id": "call_113222361ba64a98b38b2211"
|
||||
},
|
||||
{
|
||||
"sender_id": "agent_django",
|
||||
"role": "assistant",
|
||||
"timestamp": 1700000027000,
|
||||
"content": "",
|
||||
"tool_calls": [
|
||||
{
|
||||
"id": "call_72954bffd06a4878ad2340d1",
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "exec",
|
||||
"arguments": "{\"command\": \"/tmp/sweb.eval.django__django-16255.full-run-exec tmux-run \\\"cd /testbed && python /tmp/test_fix.py\\\" 5\"}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"sender_id": "tool_runner",
|
||||
"role": "tool",
|
||||
"timestamp": 1700000028000,
|
||||
"content": "(testbed) root@55ab59df2a68:/testbed# cd /testbed && python /tmp/test_fix.py\nResult: None\nBug is fixed! No ValueError raised.\n(testbed) root@55ab59df2a68:/testbed#",
|
||||
"tool_call_id": "call_72954bffd06a4878ad2340d1"
|
||||
},
|
||||
{
|
||||
"sender_id": "agent_django",
|
||||
"role": "assistant",
|
||||
"timestamp": 1700000029000,
|
||||
"content": "The bug is fixed. The fix:\n- Changed `except TypeError:` to `except (TypeError, ValueError):` in the `get_latest_lastmod` method\n- This handles the case when `self.items()` returns an empty list, which causes `max()` to raise `ValueError: max() arg is an empty sequence`\n- All 60 sitemap tests pass\n- The specific bug scenario (empty sitemap with callable lastmod) now returns `None` instead of raising an exception\n\nTASK_COMPLETE"
|
||||
}
|
||||
]
|
||||
}
|
||||
3736
tests/fixtures/agent_trajectories/session_django_16263.json
vendored
Normal file
3736
tests/fixtures/agent_trajectories/session_django_16263.json
vendored
Normal file
File diff suppressed because one or more lines are too long
2494
tests/fixtures/agent_trajectories/session_pytest_7236.json
vendored
Normal file
2494
tests/fixtures/agent_trajectories/session_pytest_7236.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1045
tests/fixtures/agent_trajectories/session_sympy_18763.json
vendored
Normal file
1045
tests/fixtures/agent_trajectories/session_sympy_18763.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3508
tests/fixtures/long_conversation_locomo_caroline_melanie.json
vendored
Normal file
3508
tests/fixtures/long_conversation_locomo_caroline_melanie.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
20862
tests/fixtures/search_seed/atomic_fact.json
vendored
Normal file
20862
tests/fixtures/search_seed/atomic_fact.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
16770
tests/fixtures/search_seed/episode.json
vendored
Normal file
16770
tests/fixtures/search_seed/episode.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
10482
tests/fixtures/search_seed/foresight.json
vendored
Normal file
10482
tests/fixtures/search_seed/foresight.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
28
tests/fixtures/search_seed/user_profile.json
vendored
Normal file
28
tests/fixtures/search_seed/user_profile.json
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user