@tea-agent/loop-agent 0.16.5 → 0.16.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -15,6 +15,12 @@
15
15
  - Pi SDK 执行长推理或大段结构化输出时不再把高频流式增量事件无界累积到内存;同一响应在多个生命周期事件中重复出现的 Token 用量只统计一次,避免 `Invalid string length` 和成本数据虚高。
16
16
  - 后端测试复合执行节点继续保持 clean environment、失败分类和 fail-closed outcome,并为 initial/final Result、repair eligibility、traceability 与 Observe 投影保留结构化运行证据。
17
17
 
18
+ ## [0.16.6] - 2026-07-20
19
+
20
+ ### 修复
21
+
22
+ - write guard 忽略 `__pycache__` / `.pytest_cache` 等 ephemeral 解释器缓存,避免 backend-test 生成节点本地冒烟 pytest 时被误拦;并明确 generate-pytest 节点不负责执行测试。
23
+
18
24
  ## [0.16.5] - 2026-07-20
19
25
 
20
26
  ### 修复
@@ -30,6 +30,33 @@ export function pathsChangedDuringRun(before, after) {
30
30
  return Array.from(changed).sort();
31
31
  }
32
32
  const DAG_RUNS_PREFIX = ".harness/dag-runs/";
33
+ /**
34
+ * Ephemeral interpreter/tool caches that writers may create while drafting tests.
35
+ * They are not product evidence and must not fail exclusive write guards.
36
+ * Intentional report/product writes remain governed by writePolicy/writeSet.
37
+ */
38
+ export function isEphemeralToolCachePath(filePath) {
39
+ const normalized = normalizePath(filePath);
40
+ if (!normalized)
41
+ return false;
42
+ if (normalized === ".pytest_cache" || normalized.startsWith(".pytest_cache/")) {
43
+ return true;
44
+ }
45
+ if (normalized === ".mypy_cache" || normalized.startsWith(".mypy_cache/")) {
46
+ return true;
47
+ }
48
+ if (normalized === ".ruff_cache" || normalized.startsWith(".ruff_cache/")) {
49
+ return true;
50
+ }
51
+ if (normalized === ".coverage" || normalized.startsWith(".coverage.")) {
52
+ return true;
53
+ }
54
+ if (/(?:^|\/)__pycache__(?:\/|$)/.test(normalized))
55
+ return true;
56
+ if (/\.(?:pyc|pyo)$/.test(normalized))
57
+ return true;
58
+ return false;
59
+ }
33
60
  /** MVP post-run guard: only paths that changed during the shell node are checked. */
34
61
  export function validateShellWriteGuard(input) {
35
62
  const violations = [];
@@ -42,6 +69,9 @@ export function validateShellWriteGuard(input) {
42
69
  if (filePath.startsWith(DAG_RUNS_PREFIX)) {
43
70
  continue;
44
71
  }
72
+ if (isEphemeralToolCachePath(filePath)) {
73
+ continue;
74
+ }
45
75
  if (matchesAnyPattern(filePath, forbiddenPaths)) {
46
76
  violations.push(filePath);
47
77
  continue;
@@ -3008,6 +3008,7 @@ function buildGenerateBackendPytestNode(sources) {
3008
3008
  "- If a test filename exists, add suffix: test_order.py → test_order_01.py",
3009
3009
  "- Do NOT re-read source documents — use reviewed cases under testcase/md/ and upstream analyze-inputs-pi output only",
3010
3010
  "- Read existing conftest.py/pytest.ini to understand conventions, but do NOT modify them",
3011
+ "- Do NOT execute pytest/python -m pytest or npm test in this node; initial/final execution is owned by dedicated shell nodes. Local smoke runs create __pycache__/.pytest_cache and are unnecessary here.",
3011
3012
  ].join("\n\n"),
3012
3013
  };
3013
3014
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tea-agent/loop-agent",
3
- "version": "0.16.5",
3
+ "version": "0.16.6",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "loop-agent": "bin/loop-agent.js",