ollaagent 0.1.9__tar.gz → 0.2.0__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 (33) hide show
  1. {ollaagent-0.1.9 → ollaagent-0.2.0}/CHANGELOG.md +13 -0
  2. {ollaagent-0.1.9 → ollaagent-0.2.0}/PKG-INFO +1 -1
  3. {ollaagent-0.1.9 → ollaagent-0.2.0}/ollaAgent/agent.py +3 -8
  4. {ollaagent-0.1.9 → ollaagent-0.2.0}/pyproject.toml +1 -1
  5. {ollaagent-0.1.9 → ollaagent-0.2.0}/tests/test_agent.py +0 -45
  6. {ollaagent-0.1.9 → ollaagent-0.2.0}/uv.lock +1 -1
  7. {ollaagent-0.1.9 → ollaagent-0.2.0}/.agentic_python/guidelines.md +0 -0
  8. {ollaagent-0.1.9 → ollaagent-0.2.0}/.agentic_python/reviewer_role.md +0 -0
  9. {ollaagent-0.1.9 → ollaagent-0.2.0}/.env.sample +0 -0
  10. {ollaagent-0.1.9 → ollaagent-0.2.0}/.gitignore +0 -0
  11. {ollaagent-0.1.9 → ollaagent-0.2.0}/.python-version +0 -0
  12. {ollaagent-0.1.9 → ollaagent-0.2.0}/AGENT.md +0 -0
  13. {ollaagent-0.1.9 → ollaagent-0.2.0}/CLAUDE.md +0 -0
  14. {ollaagent-0.1.9 → ollaagent-0.2.0}/LICENSE +0 -0
  15. {ollaagent-0.1.9 → ollaagent-0.2.0}/README.md +0 -0
  16. {ollaagent-0.1.9 → ollaagent-0.2.0}/README_ko.md +0 -0
  17. {ollaagent-0.1.9 → ollaagent-0.2.0}/main.py +0 -0
  18. {ollaagent-0.1.9 → ollaagent-0.2.0}/ollaAgent/__init__.py +0 -0
  19. {ollaagent-0.1.9 → ollaagent-0.2.0}/ollaAgent/config_loader.py +0 -0
  20. {ollaagent-0.1.9 → ollaagent-0.2.0}/ollaAgent/memory.py +0 -0
  21. {ollaagent-0.1.9 → ollaagent-0.2.0}/ollaAgent/ollama_client.py +0 -0
  22. {ollaagent-0.1.9 → ollaagent-0.2.0}/ollaAgent/permissions.py +0 -0
  23. {ollaagent-0.1.9 → ollaagent-0.2.0}/ollaAgent/plan_mode.py +0 -0
  24. {ollaagent-0.1.9 → ollaagent-0.2.0}/ollaAgent/subagent.py +0 -0
  25. {ollaagent-0.1.9 → ollaagent-0.2.0}/ollaAgent/tool_bash.py +0 -0
  26. {ollaagent-0.1.9 → ollaagent-0.2.0}/tests/__init__.py +0 -0
  27. {ollaagent-0.1.9 → ollaagent-0.2.0}/tests/conftest.py +0 -0
  28. {ollaagent-0.1.9 → ollaagent-0.2.0}/tests/test_config_loader.py +0 -0
  29. {ollaagent-0.1.9 → ollaagent-0.2.0}/tests/test_memory.py +0 -0
  30. {ollaagent-0.1.9 → ollaagent-0.2.0}/tests/test_permissions.py +0 -0
  31. {ollaagent-0.1.9 → ollaagent-0.2.0}/tests/test_plan_mode.py +0 -0
  32. {ollaagent-0.1.9 → ollaagent-0.2.0}/tests/test_subagent.py +0 -0
  33. {ollaagent-0.1.9 → ollaagent-0.2.0}/tests/test_tool_bash.py +0 -0
@@ -7,6 +7,19 @@ Versioning: [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
7
7
 
8
8
  ---
9
9
 
10
+ ## [0.2.0] - 2026-03-23
11
+
12
+ ### Fixed
13
+ - 이중 출력 완전 해결 — `Live(auto_refresh=False)` + `live.refresh()` + `Markdown` 유지
14
+ - `Text` + 완료 후 Markdown 재출력 방식 폐기
15
+ - chunk마다 즉시 Markdown 갱신 → 실시간성 + 가독성 동시 확보
16
+
17
+ ### Removed
18
+ - 불필요해진 `Text` import 제거
19
+ - `transient=True` 관련 테스트 3종 제거
20
+
21
+ ---
22
+
10
23
  ## [0.1.9] - 2026-03-23
11
24
 
12
25
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ollaagent
3
- Version: 0.1.9
3
+ Version: 0.2.0
4
4
  Summary: Local LLM agent powered by ollama — memory, plan mode, subagents
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.11
@@ -15,7 +15,7 @@ try:
15
15
  except ImportError:
16
16
  pass # Windows 환경에서는 무시
17
17
 
18
- __version__ = "0.1.9"
18
+ __version__ = "0.2.0"
19
19
 
20
20
  from dotenv import load_dotenv
21
21
  from ollama import Client
@@ -23,7 +23,6 @@ from rich.console import Console
23
23
  from rich.live import Live
24
24
  from rich.markdown import Markdown
25
25
  from rich.panel import Panel
26
- from rich.text import Text
27
26
 
28
27
  from ollaAgent.config_loader import build_system_prompt, load_config
29
28
  from ollaAgent.memory import SESSION_DIR, SessionMemory, save_session
@@ -411,7 +410,7 @@ def stream_response(stream: Any) -> tuple[str, str, dict[int, dict], int]:
411
410
  accumulated_tool_calls: dict[int, dict] = {}
412
411
  prompt_eval_count: int = 0
413
412
 
414
- with Live(console=console, auto_refresh=False, transient=True) as live:
413
+ with Live(console=console, auto_refresh=False) as live:
415
414
  for chunk in stream:
416
415
  msg = chunk.get("message") or {}
417
416
  thinking = msg.get("thinking") or ""
@@ -420,17 +419,13 @@ def stream_response(stream: Any) -> tuple[str, str, dict[int, dict], int]:
420
419
  content = msg.get("content") or ""
421
420
  if content:
422
421
  assistant_content += content
423
- live.update(Text(assistant_content))
422
+ live.update(Markdown(assistant_content))
424
423
  live.refresh() # 매 chunk 즉시 출력
425
424
  _accumulate_tool_calls(msg, accumulated_tool_calls)
426
425
  # done=True 인 마지막 chunk에서 토큰 수 캡처
427
426
  if chunk.get("done"):
428
427
  prompt_eval_count = chunk.get("prompt_eval_count") or 0
429
428
 
430
- # 스트림 완료 후 Markdown으로 최종 렌더링 (가독성 확보)
431
- if assistant_content:
432
- console.print(Markdown(assistant_content))
433
-
434
429
  return (
435
430
  assistant_content,
436
431
  thinking_content,
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ollaagent"
3
- version = "0.1.9"
3
+ version = "0.2.0"
4
4
  description = "Local LLM agent powered by ollama — memory, plan mode, subagents"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -1,7 +1,6 @@
1
1
  from unittest.mock import MagicMock, patch
2
2
 
3
3
  import pytest
4
- from rich.markdown import Markdown
5
4
 
6
5
  import ollaAgent.agent as agent
7
6
  from ollaAgent.agent import (_is_model_available, _parse_subagent_input,
@@ -451,50 +450,6 @@ class TestStreamResponse:
451
450
  content, _, _, _ = self._run(chunks)
452
451
  assert content == ""
453
452
 
454
- def test_markdown_printed_once_after_stream(self):
455
- """스트림 완료 후 console.print(Markdown)이 정확히 1회 호출된다."""
456
- chunks = [
457
- {"message": {"content": "hello"}, "done": True, "prompt_eval_count": 0}
458
- ]
459
- with (
460
- patch("ollaAgent.agent.Live"),
461
- patch("ollaAgent.agent.console") as mock_console,
462
- ):
463
- stream_response(iter(chunks))
464
-
465
- calls = mock_console.print.call_args_list
466
- markdown_calls = [
467
- c for c in calls if c.args and isinstance(c.args[0], Markdown)
468
- ]
469
- assert len(markdown_calls) == 1
470
-
471
- def test_markdown_not_printed_when_no_content(self):
472
- """content 없으면 console.print(Markdown)이 호출되지 않는다."""
473
- chunks = [{"message": {"content": ""}, "done": True, "prompt_eval_count": 0}]
474
- with (
475
- patch("ollaAgent.agent.Live"),
476
- patch("ollaAgent.agent.console") as mock_console,
477
- ):
478
- stream_response(iter(chunks))
479
-
480
- calls = mock_console.print.call_args_list
481
- markdown_calls = [
482
- c for c in calls if c.args and isinstance(c.args[0], Markdown)
483
- ]
484
- assert len(markdown_calls) == 0
485
-
486
- def test_live_created_with_transient_true(self):
487
- """Live가 transient=True로 생성된다 (plain text가 화면에 남지 않음)."""
488
- chunks = [{"message": {"content": "hi"}, "done": True, "prompt_eval_count": 0}]
489
- with (
490
- patch("ollaAgent.agent.Live") as mock_live,
491
- patch("ollaAgent.agent.console"),
492
- ):
493
- stream_response(iter(chunks))
494
-
495
- _, kwargs = mock_live.call_args
496
- assert kwargs.get("transient") is True
497
-
498
453
 
499
454
  # ──────────────────────────────────────────
500
455
  # Unit Tests: _read_user_input
@@ -187,7 +187,7 @@ wheels = [
187
187
 
188
188
  [[package]]
189
189
  name = "ollaagent"
190
- version = "0.1.8"
190
+ version = "0.1.9"
191
191
  source = { editable = "." }
192
192
  dependencies = [
193
193
  { name = "ollama" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes