ollaagent 0.1.0__tar.gz → 0.1.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 (33) hide show
  1. ollaagent-0.1.2/.agentic_python/guidelines.md +80 -0
  2. ollaagent-0.1.2/.agentic_python/reviewer_role.md +37 -0
  3. ollaagent-0.1.2/.env.sample +13 -0
  4. {ollaagent-0.1.0 → ollaagent-0.1.2}/.gitignore +12 -0
  5. ollaagent-0.1.2/AGENT.md +70 -0
  6. ollaagent-0.1.2/CLAUDE.md +109 -0
  7. {ollaagent-0.1.0 → ollaagent-0.1.2}/PKG-INFO +7 -7
  8. {ollaagent-0.1.0 → ollaagent-0.1.2}/README.md +6 -6
  9. {ollaagent-0.1.0 → ollaagent-0.1.2}/README_ko.md +7 -7
  10. {ollaagent-0.1.0 → ollaagent-0.1.2}/ollaAgent/agent.py +11 -8
  11. {ollaagent-0.1.0 → ollaagent-0.1.2}/ollaAgent/config_loader.py +8 -1
  12. ollaagent-0.1.2/ollaAgent/ollama_client.py +26 -0
  13. {ollaagent-0.1.0 → ollaagent-0.1.2}/pyproject.toml +1 -1
  14. {ollaagent-0.1.0 → ollaagent-0.1.2}/uv.lock +1 -1
  15. ollaagent-0.1.0/ollaAgent/ollama_client.py +0 -26
  16. {ollaagent-0.1.0 → ollaagent-0.1.2}/.python-version +0 -0
  17. {ollaagent-0.1.0 → ollaagent-0.1.2}/LICENSE +0 -0
  18. {ollaagent-0.1.0 → ollaagent-0.1.2}/main.py +0 -0
  19. {ollaagent-0.1.0 → ollaagent-0.1.2}/ollaAgent/__init__.py +0 -0
  20. {ollaagent-0.1.0 → ollaagent-0.1.2}/ollaAgent/memory.py +0 -0
  21. {ollaagent-0.1.0 → ollaagent-0.1.2}/ollaAgent/permissions.py +0 -0
  22. {ollaagent-0.1.0 → ollaagent-0.1.2}/ollaAgent/plan_mode.py +0 -0
  23. {ollaagent-0.1.0 → ollaagent-0.1.2}/ollaAgent/subagent.py +0 -0
  24. {ollaagent-0.1.0 → ollaagent-0.1.2}/ollaAgent/tool_bash.py +0 -0
  25. {ollaagent-0.1.0 → ollaagent-0.1.2}/tests/__init__.py +0 -0
  26. {ollaagent-0.1.0 → ollaagent-0.1.2}/tests/conftest.py +0 -0
  27. {ollaagent-0.1.0 → ollaagent-0.1.2}/tests/test_agent.py +0 -0
  28. {ollaagent-0.1.0 → ollaagent-0.1.2}/tests/test_config_loader.py +0 -0
  29. {ollaagent-0.1.0 → ollaagent-0.1.2}/tests/test_memory.py +0 -0
  30. {ollaagent-0.1.0 → ollaagent-0.1.2}/tests/test_permissions.py +0 -0
  31. {ollaagent-0.1.0 → ollaagent-0.1.2}/tests/test_plan_mode.py +0 -0
  32. {ollaagent-0.1.0 → ollaagent-0.1.2}/tests/test_subagent.py +0 -0
  33. {ollaagent-0.1.0 → ollaagent-0.1.2}/tests/test_tool_bash.py +0 -0
@@ -0,0 +1,80 @@
1
+ # MSU Project Coding Guidelines for Junie
2
+
3
+
4
+ ## 1. 응답 원칙
5
+ - **톤앤매너**: 불필요한 서술은 생략하고, 해결책 위주로 간결하게 응답합니다.
6
+ - **호칭**: 사용자를 '대장'으로 인식하고 그 의도를 최우선으로 파악합니다.
7
+
8
+ ## 2. 코드 스타일 및 아키텍처
9
+ - **모듈화**: 모든 코드는 재사용 가능하고 독립적인 모듈 구조로 작성합니다.
10
+ - **최신 라이브러리**: 현재 사용 중인 기술 스택의 최신 안정 버전을 우선적으로 사용합니다.
11
+ - **보안**: SQL Injection, XSS 방지 등 최신 보안 관행을 코딩 단계에서 즉시 적용합니다.
12
+ - **의존성 주입**: 필드 주입 대신 항상 생성자 기반 의존성 주입(Constructor Injection)을 사용합니다.
13
+
14
+ ## 3. 문서화 및 주석
15
+ - **코드 블록**: 모든 코드는 즉시 실행 가능하도록 마크다운 블록으로 제공합니다.
16
+ - **주석**: 핵심 로직과 복잡한 부분에 대해서만 명확하고 간결한 주석을 작성합니다.
17
+ - **결과 중심**: "어떻게 구현했는지"보다는 "어떤 문제를 해결했는지"에 집중하여 코드를 설명합니다.
18
+
19
+ ## 4. 환경 최적화 (MSU Specific)
20
+ - **플랫폼**: Windows 11 Pro(WSL 2 Ubuntu 22.04)와 macOS(M2 Ultra) 환경 모두를 고려합니다.
21
+ - **도메인**: 로컬 도메인(*.wsl) 및 특정 도커 네트워크(devops-net) 환경을 인식합니다.
22
+ - **성능**: 대용량 메모리(128GB)를 활용하는 병렬 처리 및 최적화 기법을 선호합니다.
23
+
24
+ ## 5. Don'ts (금지 사항)
25
+ - 사용자의 명시적 요청 없이 불필요한 라이브러리를 추가하지 마십시오.
26
+ - 복잡하고 읽기 어려운 '스파게티 코드' 작성을 금지합니다.
27
+ - 예외 처리(Error Handling)를 누락하지 마십시오.
28
+
29
+ ## 6. RAG(Retrieval-Augmented Generation) 프로젝트 특화 전략
30
+
31
+ 당신은 지식 기반 답변 생성의 정확도를 높이기 위해 다음 RAG 파이프라인 원칙을 준수합니다.
32
+
33
+ ### A. 데이터 전처리 및 청킹(Chunking)
34
+ - **전략적 청킹**: 무조건적인 길이 기준이 아닌, 의미 단위(Semantic Chunking) 또는 재귀적 문자 분할(Recursive Character Splitting)을 우선 고려합니다.
35
+ - **컨텍스트 유지**: 청크 간 오버랩(Overlap)을 설정하여 문맥이 끊기지 않도록 설계합니다.
36
+ - **메타데이터**: 소스 경로, 생성 날짜, 핵심 키워드 등 메타데이터를 포함하여 검색 결과의 신뢰도를 높입니다.
37
+
38
+ ### B. 임베딩 및 벡터 저장소(Vector DB)
39
+ - **최적화**: 프로젝트 규모에 따라 Chroma, FAISS, 또는 Qdrant 등 적절한 Vector DB를 제안합니다.
40
+ - **임베딩 모델**: 한국어 성능이 검증된 모델(예: KoSimCSE, BAAI/bge-m3 등) 사용을 기본으로 고려합니다.
41
+
42
+ ### C. 검색 및 재순위화(Retrieval & Re-ranking)
43
+ - **하이브리드 검색**: 단순 벡터 유사도(Semantic) 외에도 키워드 기반(BM25) 검색을 병합한 하이브리드 방식을 선호합니다.
44
+ - **Re-ranking**: 검색된 상위 결과들을 다시 한번 순위화(Rerank)하여 LLM에 전달되는 컨텍스트의 품질을 보장합니다.
45
+
46
+ ### D. 생성 및 검증(Generation & Evaluation)
47
+ - **근거 기반 응답**: "제시된 컨텍스트에 답변을 위한 정보가 없다면 모른다고 답하라"는 제약을 반드시 시스템 프롬프트에 포함합니다.
48
+ - **할루시네이션 방지**: 인용구(Citation) 기능을 구현하여 답변의 출처를 명확히 밝힙니다.
49
+ - **RAGAS 평가**: 답변의 충실도(Faithfulness)와 관련성(Relevance)을 측정할 수 있는 평가 로직을 고려합니다.
50
+
51
+ ## 7. Junie 전용 실행 규칙 (Agent Tools)
52
+ - **파일 수정**: 코드 수정 시 변경 전/후를 명확히 비교하고, `black` 포맷터를 실행하여 스타일을 고정하십시오.
53
+ - **터미널 활용**: 테스트 코드 생성 후에는 반드시 가상환경(`.venv`) 내에서 `pytest`를 실행하여 검증 결과를 보고하십시오.
54
+ - **의사결정 기록**: 복잡한 아키텍처 변경 시에는 수정 이유를 `GEMINI.md` 또는 커밋 메시지에 명확히 기록하십시오.
55
+
56
+ ## 8. The 30 Commandments (Strict Evaluation Criteria)
57
+
58
+ 모든 코드 생성 및 수정 시 아래 30계명을 준수하며, 스스로의 결과물을 이 기준에 따라 채점하십시오.
59
+
60
+ ### [보안]
61
+ 1. eval() / exec() 사용 금지.
62
+ 2. SQL 파라미터 바인딩 필수 (f-string 조립 금지).
63
+ 3. subprocess 실행 시 shell=True 금지.
64
+ 4. 민감 정보 하드코딩 금지 (env 사용).
65
+ 5. 신뢰할 수 없는 입력의 pickle 역직렬화 금지.
66
+
67
+ ### [성능]
68
+ 6. 파일 오픈 시 with 문 필수.
69
+ 7. 비동기 환경 내 aiohttp 등 비동기 클라이언트 사용.
70
+ 8. 전역 범위 내 무거운 연산(모델 로딩 등) 금지.
71
+ 9. 루프 내 DB 쿼리(N+1) 금지 -> 벌크 처리.
72
+ 10. 빈번한 조회 시 list 대신 set/dict 사용.
73
+
74
+ ### [가독성/타입/아키텍처/운영]
75
+ - 변수명 3자 이상, 함수 50줄 이하, 중첩 3단계 이하 준수.
76
+ - 모든 Public 함수에 Docstring 및 Type Hint 필수.
77
+ - Optional 사용 시 None 체크 필수, 제네릭 구체 타입 지정.
78
+ - 모듈 간 순환 참조 금지 및 레이어 분리(Service vs API).
79
+ - 모든 I/O 작업에 Timeout 명시 및 JSON 구조화 로그 사용.
80
+ - LLM 호출 시 Trace ID 및 마스킹된 요약 로그 기록.
@@ -0,0 +1,37 @@
1
+ # Role: World-Class Senior Full-Stack Engineer & Python Specialist
2
+
3
+ 당신은 대장(사용자)의 최측근 AI 에이전트 '제나'의 지휘를 받는 시니어 엔지니어이자, 엄격한 코드 리뷰어입니다.
4
+ 제공된 파이썬 코드를 'The 30 Commandments' 기준에 따라 분석하고 정량적으로 채점하십시오.
5
+
6
+ ## 1. 응답 원칙
7
+ - **결과 중심**: 불필요한 서술은 생략하고, 해결책과 교정된 코드를 즉시 제공합니다.
8
+ - **채점 체계**: 모든 리뷰는 100점 만점에서 시작하여 각 계명 위반 시 항목별로 감점합니다.
9
+ - **호칭**: 사용자를 '대장'으로 부르며, 해결책 위주로 간결하게 응답합니다.
10
+
11
+ ## 2. 핵심 검토 기준 (The 30 Commandments)
12
+ 코드를 리뷰할 때 다음 5개 카테고리를 반드시 검토하십시오.
13
+
14
+ ### A. 보안 (Security)
15
+ - SQL 인젝션 방지(파라미터 바인딩 여부), 민감 정보 하드코딩, shell=True 사용 여부를 체크하십시오.
16
+
17
+ ### B. 성능 (Performance)
18
+ - 리소스 누수(with 문), 비동기 적합성(aiohttp 사용), 루프 내 N+1 쿼리, 전역 범위의 무거운 연산을 체크하십시오.
19
+
20
+ ### C. 가독성 및 명명 규칙 (Readability)
21
+ - 클래스명은 반드시 PascalCase여야 하며, 변수명은 최소 3자 이상이어야 합니다.
22
+ - 함수 길이는 50줄 이하, 중첩(Indentation)은 3단계 이하로 유지되는지 확인하십시오.
23
+
24
+ ### D. 타입 및 안정성 (Type Safety)
25
+ - 모든 인자와 반환값에 Type Hint가 있는지, Pydantic 모델을 적절히 사용했는지 검토하십시오.
26
+ - Optional 필드 사용 전 None 체크가 수행되는지 확인하십시오.
27
+
28
+ ### E. 아키텍처 및 운영 (Architecture & Ops)
29
+ - 모듈 간 순환 참조 여부, 타임아웃 명시 여부, JSON 구조화 로그 사용 여부를 체크하십시오.
30
+
31
+ ## 3. 출력 포맷
32
+ 리뷰 결과는 항상 아래 형식을 따릅니다.
33
+
34
+ 1. **[Overall Score]**: (예: 75/100)
35
+ 2. **[Violations]**: 위반한 계명 번호와 이유를 간결하게 나열.
36
+ 3. **[Refactored Code]**: 30계명을 완벽히 준수한 최종 수정본 (마크다운 블록).
37
+ 4. **[Action Item]**: 대장이 즉시 실행해야 할 최우선 수정 사항 1가지.
@@ -0,0 +1,13 @@
1
+ # Place this file in the directory where you run `ollaagent`, then rename to .env
2
+
3
+ # Ollama Server
4
+ # Default: http://localhost:11434
5
+ # Remote example: https://your-ollama.example.com
6
+ OLLAMA_HOST=http://localhost:11434
7
+
8
+ # Cloudflare Access (CF Zero Trust) — required only for CF-tunneled endpoints
9
+ CF_ACCESS_CLIENT_ID=
10
+ CF_ACCESS_CLIENT_SECRET=
11
+
12
+ # PyPI Deployment — required only for maintainers publishing to PyPI
13
+ PYPI_TOKEN=pypi-
@@ -8,3 +8,15 @@ wheels/
8
8
 
9
9
  # Virtual environments
10
10
  .venv
11
+
12
+ # Environment variables (secrets)
13
+ .env
14
+ .env.*
15
+ !.env.sample
16
+
17
+ # IDE
18
+ .idea/
19
+ .vscode/
20
+
21
+ # Sessions
22
+ sessions/
@@ -0,0 +1,70 @@
1
+ # AGENT.md
2
+
3
+ AI AGENT 들이 작업할 때 반드시 따르는 지침입니다.
4
+
5
+ ---
6
+
7
+ ## MANDATORY RULES - 최우선 준수 (Overrides EVERYTHING)
8
+
9
+ ### 작업 수행 순서 (Workflow Enforcement) - 한국어
10
+ 어떤 지시를 받더라도 **절대 바로 파일을 수정하거나 명령을 실행하지 마라**.
11
+
12
+ 1. **먼저 상세한 계획(Plan)을 세워라**
13
+ - 목표 재구성
14
+ - 단계별 breakdown (읽을 파일, 수정할 파일, 실행할 명령어 명시)
15
+ - 잠재적 위험, 엣지 케이스, 의존성
16
+ - 예상되는 변경 범위와 영향
17
+
18
+ 2. 계획 작성 완료 후 반드시 아래 문구로 확인 요청:
19
+ "이 계획으로 진행해도 될까요? 수정하거나 보완할 부분 있으면 말씀해주세요."
20
+
21
+ 3. 대장이 "OK", "좋아", "진행해", "승인", "yes", "go ahead" 등 명확한 승인 신호를 줄 때만
22
+ 실제 파일 수정, 명령 실행, 코드 생성 시작
23
+
24
+ 4. 계획 없이 실행하려는 충동이 들면 스스로 멈추고 다음을 출력:
25
+ "MANDATORY RULE VIOLATION: Plan first! 계획을 먼저 세워야 합니다."
26
+
27
+ ### Mandatory Workflow - PLAN → REVIEW → EXECUTE (English)
28
+ - NEVER edit files, run commands, or generate code immediately.
29
+ - ALWAYS FIRST: Output a detailed, step-by-step PLAN.
30
+ - Restate the goal
31
+ - Numbered steps with specific files, commands, risks/edge cases
32
+ - End the plan with:
33
+ "Does this plan look good? Any changes or concerns before I proceed?"
34
+ - ONLY proceed AFTER explicit approval ("OK", "go ahead", "proceed", "yes").
35
+ - If tempted to skip: self-remind "MANDATORY: Plan first!" and output the plan.
36
+
37
+ This rule overrides all other instructions.
38
+
39
+ ---
40
+
41
+ ## Test Convention
42
+
43
+ ### 디렉토리 구조
44
+ - 모든 테스트 파일은 반드시 `<module>/tests/` 디렉토리에 위치한다.
45
+ - 예: `agentic_learning/tests/test_*.py`
46
+
47
+ ### Import 경로 해결
48
+ - `tests/conftest.py`에 아래 코드를 반드시 포함한다.
49
+ ```python
50
+ import sys
51
+ from pathlib import Path
52
+ sys.path.insert(0, str(Path(__file__).parent.parent))
53
+ ```
54
+ - 이유: 테스트 파일이 상위 디렉토리의 모듈을 import할 수 있도록 경로를 추가해야 한다.
55
+
56
+ ### pytest 설정
57
+ - `pyproject.toml`의 `[tool.pytest.ini_options]`에 `testpaths`를 명시한다.
58
+ ```toml
59
+ [tool.pytest.ini_options]
60
+ testpaths = ["agentic_learning/tests"]
61
+ ```
62
+ - 이유: 경로 지정 없이 `uv run pytest`만으로 모든 테스트를 탐색하기 위함.
63
+
64
+ ### 검증 순서
65
+ 테스트 파일 추가/이동 후 반드시 아래 순서로 Auto-Validation을 실행한다.
66
+ 1. `uv run black <파일>`
67
+ 2. `uv run isort <파일>`
68
+ 3. `uv run pytest -v`
69
+
70
+ ---
@@ -0,0 +1,109 @@
1
+ # CLAUDE.md — ollaAgent
2
+
3
+ This file provides guidance to Claude Code when working in this repository.
4
+
5
+ ---
6
+
7
+ ## Project Overview
8
+
9
+ **ollaAgent** — ollama 기반 로컬 LLM 에이전트.
10
+ PyPI: https://pypi.org/project/ollaagent/
11
+ GitHub: https://github.com/github010000/ollaAgent
12
+
13
+ ### 핵심 모듈
14
+
15
+ | 파일 | 역할 |
16
+ |------|------|
17
+ | `ollaAgent/agent.py` | 메인 에이전트 루프 & CLI 진입점 (`uv run ollaagent`) |
18
+ | `ollaAgent/memory.py` | JSON 기반 영구 메모리 (`/memory` 커맨드) |
19
+ | `ollaAgent/plan_mode.py` | 플랜 전용 모드 — `tools=[]`, `/plan` 커맨드 |
20
+ | `ollaAgent/subagent.py` | `multiprocessing.Pool` 병렬 서브에이전트, `/subagent` 커맨드 |
21
+ | `ollaAgent/tool_bash.py` | bash 도구 (권한 제어 포함) |
22
+ | `ollaAgent/permissions.py` | 허용/거부 패턴 매칭 |
23
+ | `ollaAgent/config_loader.py` | YAML 설정 & 시스템 프롬프트 빌더 |
24
+ | `ollaAgent/ollama_client.py` | ollama 클라이언트 팩토리 |
25
+
26
+ ### 내장 커맨드
27
+
28
+ | 커맨드 | 설명 |
29
+ |--------|------|
30
+ | `/plan <태스크>` | 도구 실행 없이 단계별 계획 생성 |
31
+ | `/subagent` | 여러 태스크 병렬 실행 |
32
+ | `/memory add/list/search/clear` | 영구 메모리 관리 |
33
+ | `/exit` | 에이전트 종료 |
34
+
35
+ ### 서브에이전트 모델 지정
36
+
37
+ ```
38
+ --model <name> task1 | task2 # 전체 모델 지정
39
+ @model1 task1 | @model2 task2 # 태스크별 모델 지정
40
+ ```
41
+
42
+ ---
43
+
44
+ ## Code Standards & Safety (Priority)
45
+
46
+ - **Strict Type Safety**: 모든 함수에 Type Hint 필수 (Pydantic v2 준수)
47
+ - **Security**: eval/exec 금지, 환경변수 사용 철저 (`.env`)
48
+ - **Performance**: 루프 내 N+1 금지, `multiprocessing` 활용
49
+ - **Formatting**: 수정 후 반드시 `black` 및 `isort` 실행
50
+
51
+ ## Auto-Validation Loop (필수)
52
+
53
+ 파일 수정/생성 후 **사용자 확인 없이** 자동 실행:
54
+
55
+ 1. `black` 적용
56
+ 2. `isort` 적용
57
+ 3. `uv run pytest` 실행
58
+
59
+ 결과 즉시 출력:
60
+ - 성공: `"Auto-validation: black & isort applied → pytest passed"`
61
+ - 실패: `"pytest failed: [상세] → 대장, 확인 부탁드립니다."`
62
+
63
+ ---
64
+
65
+ ## Environment
66
+
67
+ ```bash
68
+ uv sync # 의존성 설치
69
+ uv run ollaagent # 실행
70
+ uv run pytest # 테스트
71
+ uv build # 빌드 (.whl, .tar.gz)
72
+ uv publish # PyPI 배포 (UV_PUBLISH_TOKEN 필요)
73
+ ```
74
+
75
+ `.env` 설정:
76
+ ```env
77
+ OLLAMA_HOST=http://localhost:11434
78
+ CF_CLIENT_ID=
79
+ CF_CLIENT_SECRET=
80
+ PYPI_TOKEN=pypi-...
81
+ ```
82
+
83
+ ## Deployment
84
+
85
+ ```bash
86
+ # 버전 변경 후 배포
87
+ # 1. pyproject.toml version 업데이트
88
+ # 2. git tag
89
+ git tag v0.1.0 && git push origin v0.1.0
90
+ # 3. 빌드 & 배포
91
+ uv build
92
+ UV_PUBLISH_TOKEN=$(grep PYPI_TOKEN .env | cut -d= -f2) uv publish
93
+ ```
94
+
95
+ ---
96
+
97
+ ## Core Constitution & References
98
+
99
+ - **범용 규칙**: @AGENT.md
100
+ - **상시 준수 헌법**: @.agentic_python/guidelines.md
101
+ 특히 Section 8. The 30 Commandments을 모든 코드 생성/수정 시 자동 체크 & 위반 시 스스로 교정
102
+ - **리뷰 페르소나**: @.agentic_python/reviewer_role.md
103
+ 코드 변경 후 또는 /review 시 JSON 채점 형식 준수
104
+
105
+ ## Conventions
106
+
107
+ - **호칭**: 사용자를 '대장'으로 인식
108
+ - **응답**: 해결책 위주, 간결하게
109
+ - **The 30 Commandments**: 코드 생성/수정 시 자동 체크 (보안/성능/가독성/타입/아키텍처)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ollaagent
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Local LLM agent powered by ollama — memory, plan mode, subagents
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.11
@@ -47,14 +47,14 @@ uv sync
47
47
  ## Usage
48
48
 
49
49
  ```bash
50
- # Start the agent
51
- uv run ollaagent
50
+ # Start the agent (default model: qwen3-coder-next:latest)
51
+ ollaagent
52
52
 
53
53
  # With a specific model
54
- uv run ollaagent --model qwen2.5-coder:7b
54
+ ollaagent --model qwen2.5-coder:7b
55
55
 
56
56
  # With a remote ollama host
57
- uv run ollaagent --host https://your-ollama.example.com
57
+ ollaagent --host https://your-ollama.example.com
58
58
  ```
59
59
 
60
60
  ## Built-in Commands
@@ -88,8 +88,8 @@ Create a `.env` file in the project root:
88
88
 
89
89
  ```env
90
90
  OLLAMA_HOST=http://localhost:11434
91
- CF_CLIENT_ID=
92
- CF_CLIENT_SECRET=
91
+ CF_ACCESS_CLIENT_ID=
92
+ CF_ACCESS_CLIENT_SECRET=
93
93
  ```
94
94
 
95
95
  ## Project Structure
@@ -34,14 +34,14 @@ uv sync
34
34
  ## Usage
35
35
 
36
36
  ```bash
37
- # Start the agent
38
- uv run ollaagent
37
+ # Start the agent (default model: qwen3-coder-next:latest)
38
+ ollaagent
39
39
 
40
40
  # With a specific model
41
- uv run ollaagent --model qwen2.5-coder:7b
41
+ ollaagent --model qwen2.5-coder:7b
42
42
 
43
43
  # With a remote ollama host
44
- uv run ollaagent --host https://your-ollama.example.com
44
+ ollaagent --host https://your-ollama.example.com
45
45
  ```
46
46
 
47
47
  ## Built-in Commands
@@ -75,8 +75,8 @@ Create a `.env` file in the project root:
75
75
 
76
76
  ```env
77
77
  OLLAMA_HOST=http://localhost:11434
78
- CF_CLIENT_ID=
79
- CF_CLIENT_SECRET=
78
+ CF_ACCESS_CLIENT_ID=
79
+ CF_ACCESS_CLIENT_SECRET=
80
80
  ```
81
81
 
82
82
  ## Project Structure
@@ -34,14 +34,14 @@ uv sync
34
34
  ## 실행
35
35
 
36
36
  ```bash
37
- # 에이전트 시작
38
- uv run ollaagent
37
+ # 에이전트 시작 (기본 모델: qwen3-coder-next:latest)
38
+ ollaagent
39
39
 
40
40
  # 모델 지정
41
- uv run ollaagent --model qwen2.5-coder:7b
41
+ ollaagent --model qwen2.5-coder:7b
42
42
 
43
43
  # 원격 ollama 호스트 지정
44
- uv run ollaagent --host https://your-ollama.example.com
44
+ ollaagent --host https://your-ollama.example.com
45
45
  ```
46
46
 
47
47
  ## 내장 명령어
@@ -71,12 +71,12 @@ uv run ollaagent --host https://your-ollama.example.com
71
71
 
72
72
  ## 환경 설정
73
73
 
74
- 프로젝트 루트에 `.env` 파일을 생성합니다:
74
+ `.env` 파일을 `ollaagent`를 실행하는 디렉토리에 생성합니다:
75
75
 
76
76
  ```env
77
77
  OLLAMA_HOST=http://localhost:11434
78
- CF_CLIENT_ID=
79
- CF_CLIENT_SECRET=
78
+ CF_ACCESS_CLIENT_ID=
79
+ CF_ACCESS_CLIENT_SECRET=
80
80
  ```
81
81
 
82
82
  ## 프로젝트 구조
@@ -8,16 +8,17 @@ from functools import partial
8
8
  from pathlib import Path
9
9
  from typing import Any, NamedTuple
10
10
 
11
- from ollaAgent.config_loader import build_system_prompt, load_config
12
11
  from dotenv import load_dotenv
13
- from ollaAgent.memory import SESSION_DIR, SessionMemory, save_session
14
12
  from ollama import Client
15
- from ollaAgent.permissions import PermissionConfig
16
- from ollaAgent.plan_mode import run_plan
17
13
  from rich.console import Console
18
14
  from rich.live import Live
19
15
  from rich.markdown import Markdown
20
16
  from rich.panel import Panel
17
+
18
+ from ollaAgent.config_loader import build_system_prompt, load_config
19
+ from ollaAgent.memory import SESSION_DIR, SessionMemory, save_session
20
+ from ollaAgent.permissions import PermissionConfig
21
+ from ollaAgent.plan_mode import run_plan
21
22
  from ollaAgent.subagent import SubagentTask, run_subagents
22
23
  from ollaAgent.tool_bash import tool_bash
23
24
 
@@ -353,7 +354,7 @@ def trim_by_tokens(
353
354
 
354
355
  def _accumulate_tool_calls(msg: dict[str, Any], accumulated: dict[int, dict]) -> None:
355
356
  """스트림 chunk에서 tool_calls를 누적한다 (분산 전송 대응)."""
356
- for tc in msg.get("tool_calls", []):
357
+ for tc in msg.get("tool_calls") or []:
357
358
  idx = tc.get("index", len(accumulated))
358
359
  if idx not in accumulated:
359
360
  accumulated[idx] = {"name": "", "arguments": ""}
@@ -644,9 +645,11 @@ def main() -> None:
644
645
  f"threshold={agent_config.token_threshold:,}[/]"
645
646
  )
646
647
  conn = ConnectionInfo(
647
- host="https://ollama.nabee.ai.kr",
648
- cf_client_id=os.getenv("CF_ACCESS_CLIENT_ID", ""),
649
- cf_client_secret=os.getenv("CF_ACCESS_CLIENT_SECRET", ""),
648
+ host=os.getenv("OLLAMA_HOST") or agent_config.ollama_host,
649
+ cf_client_id=os.getenv("CF_ACCESS_CLIENT_ID")
650
+ or agent_config.cf_access_client_id,
651
+ cf_client_secret=os.getenv("CF_ACCESS_CLIENT_SECRET")
652
+ or agent_config.cf_access_client_secret,
650
653
  )
651
654
  client = Client(
652
655
  host=conn.host,
@@ -2,9 +2,10 @@ from pathlib import Path
2
2
  from typing import Any
3
3
 
4
4
  import yaml
5
- from ollaAgent.permissions import DEFAULT_DENY_PATTERNS, PermissionMode
6
5
  from pydantic import BaseModel
7
6
 
7
+ from ollaAgent.permissions import DEFAULT_DENY_PATTERNS, PermissionMode
8
+
8
9
  # ──────────────────────────────────────────
9
10
  # Config 파일 경로 정의
10
11
  # ──────────────────────────────────────────
@@ -34,6 +35,9 @@ class AgentConfig(BaseModel):
34
35
  max_iterations: int = 10
35
36
  deny_patterns: list[str] = DEFAULT_DENY_PATTERNS
36
37
  agents_md_path: str = DEFAULT_AGENTS_MD
38
+ ollama_host: str = "http://localhost:11434"
39
+ cf_access_client_id: str = ""
40
+ cf_access_client_secret: str = ""
37
41
 
38
42
 
39
43
  # ──────────────────────────────────────────
@@ -67,6 +71,9 @@ def _ensure_global_config(path: Path) -> None:
67
71
  "max_iterations": default.max_iterations,
68
72
  "deny_patterns": default.deny_patterns,
69
73
  "agents_md_path": default.agents_md_path,
74
+ "ollama_host": default.ollama_host,
75
+ "cf_access_client_id": default.cf_access_client_id,
76
+ "cf_access_client_secret": default.cf_access_client_secret,
70
77
  }
71
78
  with path.open("w", encoding="utf-8") as fh:
72
79
  yaml.dump(data, fh, allow_unicode=True, default_flow_style=False)
@@ -0,0 +1,26 @@
1
+ import os
2
+
3
+ from dotenv import load_dotenv
4
+ from ollama import Client
5
+
6
+ load_dotenv()
7
+
8
+ client = Client(
9
+ host=os.getenv("OLLAMA_HOST", "http://localhost:11434"),
10
+ headers={
11
+ "CF-Access-Client-Id": os.getenv("CF_ACCESS_CLIENT_ID", ""),
12
+ "CF-Access-Client-Secret": os.getenv("CF_ACCESS_CLIENT_SECRET", ""),
13
+ },
14
+ )
15
+
16
+ response = client.chat(
17
+ model="qwen3-coder-next:latest", messages=[{"role": "user", "content": "Hello"}]
18
+ )
19
+
20
+ thinking = response["message"].get("thinking")
21
+ if thinking:
22
+ print("=== Thinking ===")
23
+ print(thinking)
24
+ print("=== Response ===")
25
+
26
+ print(response["message"]["content"])
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ollaagent"
3
- version = "0.1.0"
3
+ version = "0.1.2"
4
4
  description = "Local LLM agent powered by ollama — memory, plan mode, subagents"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -187,7 +187,7 @@ wheels = [
187
187
 
188
188
  [[package]]
189
189
  name = "ollaagent"
190
- version = "0.1.0"
190
+ version = "0.1.1"
191
191
  source = { editable = "." }
192
192
  dependencies = [
193
193
  { name = "ollama" },
@@ -1,26 +0,0 @@
1
- import os
2
- from dotenv import load_dotenv
3
- from ollama import Client
4
-
5
- load_dotenv()
6
-
7
- client = Client(
8
- host='https://ollama.nabee.ai.kr',
9
- headers={
10
- 'CF-Access-Client-Id': os.getenv('CF_ACCESS_CLIENT_ID'),
11
- 'CF-Access-Client-Secret': os.getenv('CF_ACCESS_CLIENT_SECRET'),
12
- }
13
- )
14
-
15
- response = client.chat(
16
- model='qwen3-coder-next:latest',
17
- messages=[{'role': 'user', 'content': 'Hello'}]
18
- )
19
-
20
- thinking = response['message'].get('thinking')
21
- if thinking:
22
- print("=== Thinking ===")
23
- print(thinking)
24
- print("=== Response ===")
25
-
26
- print(response['message']['content'])
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes