agent-chat-plugin 0.7.0__tar.gz → 0.7.2__tar.gz

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.
Files changed (27) hide show
  1. {agent_chat_plugin-0.7.0/agent_chat_plugin.egg-info → agent_chat_plugin-0.7.2}/PKG-INFO +1 -1
  2. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/agent_chat/lease_store.py +35 -21
  3. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/agent_chat/path_locks.py +22 -6
  4. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/agent_chat/state_store.py +9 -1
  5. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/agent_chat/task_store.py +9 -3
  6. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2/agent_chat_plugin.egg-info}/PKG-INFO +1 -1
  7. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/chat.py +1 -1
  8. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/pyproject.toml +1 -1
  9. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/LICENSE +0 -0
  10. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/README.md +0 -0
  11. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/agent_chat/_advisory_lock.py +0 -0
  12. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/agent_chat/task_model.py +0 -0
  13. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/agent_chat_plugin.egg-info/SOURCES.txt +0 -0
  14. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/agent_chat_plugin.egg-info/dependency_links.txt +0 -0
  15. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/agent_chat_plugin.egg-info/entry_points.txt +0 -0
  16. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/agent_chat_plugin.egg-info/top_level.txt +0 -0
  17. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/setup.cfg +0 -0
  18. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/tests/test_capabilities.py +0 -0
  19. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/tests/test_chat.py +0 -0
  20. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/tests/test_context_budget.py +0 -0
  21. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/tests/test_hooks.py +0 -0
  22. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/tests/test_leases.py +0 -0
  23. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/tests/test_path_locks.py +0 -0
  24. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/tests/test_plugin_manifest.py +0 -0
  25. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/tests/test_state.py +0 -0
  26. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/tests/test_state_json_output.py +0 -0
  27. {agent_chat_plugin-0.7.0 → agent_chat_plugin-0.7.2}/tests/test_tasks.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-chat-plugin
3
- Version: 0.7.0
3
+ Version: 0.7.2
4
4
  Summary: Peer AI agents coordinate through markdown messages in shared channel folders — no orchestrator, autonomous zero-token waiting, cross-platform.
5
5
  Author: n24q02m
6
6
  License: Apache-2.0
@@ -237,18 +237,19 @@ class LeaseStore:
237
237
  def _assert_exact_claim_path(self, path: Path, filename: str) -> None:
238
238
  self._assert_exact_layout(path, self.claims_dir, kind="claim")
239
239
  try:
240
- for entry in self.claims_dir.iterdir():
241
- if (
242
- os.name == "nt"
243
- and entry.name.casefold() == filename.casefold()
244
- and entry.name != filename
245
- ):
246
- raise LeaseError(
247
- "LEASE_TRANSACTION_INVALID",
248
- f"claim filename case alias is not canonical: {filename!r}",
249
- file=filename,
250
- actual_file=entry.name,
251
- )
240
+ with os.scandir(self.claims_dir) as it:
241
+ for entry in it:
242
+ if (
243
+ os.name == "nt"
244
+ and entry.name.casefold() == filename.casefold()
245
+ and entry.name != filename
246
+ ):
247
+ raise LeaseError(
248
+ "LEASE_TRANSACTION_INVALID",
249
+ f"claim filename case alias is not canonical: {filename!r}",
250
+ file=filename,
251
+ actual_file=entry.name,
252
+ )
252
253
  except OSError as error:
253
254
  raise LeaseError(
254
255
  "LEASE_TRANSACTION_INVALID",
@@ -350,9 +351,15 @@ class LeaseStore:
350
351
  f"claim storage is not a directory: {self.claims_dir}",
351
352
  )
352
353
  matches: list[tuple[Path, LeaseRecord]] = []
353
- for path in sorted(self.claims_dir.glob("*.json"), key=lambda item: item.name):
354
- if path.name.startswith((".", "_")):
355
- continue
354
+ found_paths = []
355
+ try:
356
+ with os.scandir(self.claims_dir) as it:
357
+ for entry in it:
358
+ if entry.name.endswith(".json") and not entry.name.startswith((".", "_")):
359
+ found_paths.append(Path(entry.path))
360
+ except OSError:
361
+ pass
362
+ for path in sorted(found_paths, key=lambda item: item.name):
356
363
  self._assert_inside_channel(path)
357
364
  record = self._read_claim(path)
358
365
  if record.channel == self.channel.name and record.task_id == task_id:
@@ -390,9 +397,15 @@ class LeaseStore:
390
397
  f"claim storage is not a directory: {self.claims_dir}",
391
398
  )
392
399
  records = []
393
- for path in sorted(self.claims_dir.glob("*.json"), key=lambda item: item.name):
394
- if path.name.startswith((".", "_")):
395
- continue
400
+ found_paths = []
401
+ try:
402
+ with os.scandir(self.claims_dir) as it:
403
+ for entry in it:
404
+ if entry.name.endswith(".json") and not entry.name.startswith((".", "_")):
405
+ found_paths.append(Path(entry.path))
406
+ except OSError:
407
+ pass
408
+ for path in sorted(found_paths, key=lambda item: item.name):
396
409
  self._assert_inside_channel(path)
397
410
  records.append(self._read_claim(path))
398
411
  return records
@@ -840,11 +853,12 @@ class LeaseStore:
840
853
  marker = f'"transaction_id": "{transaction_id}"'
841
854
  for path in chat.message_files(self.channel):
842
855
  try:
843
- body = path.read_text(encoding="utf-8")
856
+ with path.open(encoding="utf-8") as f:
857
+ for line in f:
858
+ if marker in line:
859
+ return True
844
860
  except (OSError, UnicodeError):
845
861
  continue
846
- if marker in body:
847
- return True
848
862
  return False
849
863
 
850
864
 
@@ -679,9 +679,15 @@ class PathLockStore:
679
679
  f"lock storage is not a directory: {self.locks_dir}",
680
680
  )
681
681
  records: list[PathLockRecord] = []
682
- for path in sorted(self.locks_dir.glob("*.json"), key=lambda item: item.name):
683
- if path.name.startswith((".", "_")):
684
- continue
682
+ found_paths = []
683
+ try:
684
+ with os.scandir(self.locks_dir) as it:
685
+ for entry in it:
686
+ if entry.name.endswith(".json") and not entry.name.startswith((".", "_")):
687
+ found_paths.append(Path(entry.path))
688
+ except OSError:
689
+ pass
690
+ for path in sorted(found_paths, key=lambda item: item.name):
685
691
  records.append(self._read_record(path))
686
692
  return records
687
693
 
@@ -1231,8 +1237,10 @@ class PathLockStore:
1231
1237
  return False
1232
1238
  for path in message_paths:
1233
1239
  try:
1234
- if marker in path.read_text(encoding="utf-8"):
1235
- return True
1240
+ with path.open(encoding="utf-8") as f:
1241
+ for line in f:
1242
+ if marker in line:
1243
+ return True
1236
1244
  except (OSError, UnicodeError):
1237
1245
  continue
1238
1246
  return False
@@ -1542,7 +1550,15 @@ class PathLockStore:
1542
1550
  "PATH_LOCK_NOT_FOUND", f"lock record does not exist: {target}"
1543
1551
  )
1544
1552
  matches: list[tuple[Path, PathLockRecord]] = []
1545
- for path in self.locks_dir.glob("*.json") if self.locks_dir.exists() else []:
1553
+ found_paths = []
1554
+ try:
1555
+ with os.scandir(self.locks_dir) as it:
1556
+ for entry in it:
1557
+ if entry.name.endswith(".json"):
1558
+ found_paths.append(Path(entry.path))
1559
+ except OSError:
1560
+ pass
1561
+ for path in found_paths:
1546
1562
  record = self._read_record(path)
1547
1563
  if any(item.normalized_path == requested.normalized_path for item in record.paths):
1548
1564
  matches.append((path, record))
@@ -515,7 +515,15 @@ class StateStore:
515
515
  # records that cannot satisfy the authoritative task contract.
516
516
  tasks_dir = self.channel / "tasks"
517
517
  if tasks_dir.exists() and tasks_dir.is_dir():
518
- for path in sorted(tasks_dir.glob("*.json"), key=lambda item: item.name):
518
+ found_paths = []
519
+ try:
520
+ with os.scandir(tasks_dir) as it:
521
+ for entry in it:
522
+ if entry.name.endswith(".json"):
523
+ found_paths.append(Path(entry.path))
524
+ except OSError:
525
+ pass
526
+ for path in sorted(found_paths, key=lambda item: item.name):
519
527
  try:
520
528
  resolved = path.resolve(strict=False)
521
529
  resolved.relative_to(tasks_dir.resolve(strict=False))
@@ -218,9 +218,15 @@ class TaskStore:
218
218
  f"task storage is not a directory: {self.tasks_dir}",
219
219
  )
220
220
  records = []
221
- for path in sorted(self.tasks_dir.glob("*.json"), key=lambda item: item.name):
222
- if path.name.startswith((".", "_")):
223
- continue
221
+ found_paths = []
222
+ try:
223
+ with os.scandir(self.tasks_dir) as it:
224
+ for entry in it:
225
+ if entry.name.endswith(".json") and not entry.name.startswith((".", "_")):
226
+ found_paths.append(Path(entry.path))
227
+ except OSError:
228
+ pass
229
+ for path in sorted(found_paths, key=lambda item: item.name):
224
230
  self._assert_inside_channel(path)
225
231
  records.append(self._read_path(path))
226
232
  return records
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-chat-plugin
3
- Version: 0.7.0
3
+ Version: 0.7.2
4
4
  Summary: Peer AI agents coordinate through markdown messages in shared channel folders — no orchestrator, autonomous zero-token waiting, cross-platform.
5
5
  Author: n24q02m
6
6
  License: Apache-2.0
@@ -1597,7 +1597,7 @@ def main(argv=None):
1597
1597
  except OSError as error:
1598
1598
  if "args" in locals() and getattr(args, "cmd", None) == "task":
1599
1599
  die(f"TASK_IO_ERROR: {error}", code=2)
1600
- raise
1600
+ die(f"I/O error: {error}", code=1)
1601
1601
  except Exception as error:
1602
1602
  if _is_task_error(error):
1603
1603
  die(str(error), code=2)
@@ -10,7 +10,7 @@ requires-python = ">=3.8"
10
10
  license = { text = "Apache-2.0" }
11
11
  authors = [{ name = "n24q02m" }]
12
12
  keywords = ["multi-agent", "coordination", "markdown", "blackboard", "claude-code", "agent-skills", "peer-to-peer"]
13
- version = "0.7.0" # managed by python-semantic-release; do not hand-edit
13
+ version = "0.7.2" # managed by python-semantic-release; do not hand-edit
14
14
  classifiers = [
15
15
  "Programming Language :: Python :: 3",
16
16
  "License :: OSI Approved :: Apache Software License",