codebuff-agent 2.1.74__py3-none-any.whl
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.
- codebuff_agent-2.1.74.data/data/etc/jupyter/jupyter_server_config.d/codebuff_agent.json +7 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/package.json +157 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/104.2b8f20f9d1ac2c9db01b.js +1 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/150.39fa98117cc8ca590465.js +1 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/166.386ff9b2c37ac865fdee.js +1 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/216.25cf81131bf7274dabf4.js +1 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/353.581bd1cb00746399b62e.js +1 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/367.575f9621b63c9a641aa9.js +1 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/421.11dac223a2c2da1b09f5.js +1 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/432.8513b4c6cc1d1232d165.js +2 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/432.8513b4c6cc1d1232d165.js.LICENSE.txt +19 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/439.ba5b5ef70ec6de214b8c.js +2 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/439.ba5b5ef70ec6de214b8c.js.LICENSE.txt +8 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/481.cc2dec9fa869d66f1407.js +1 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/487.0796e931d6e651482c14.js +1 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/49.d326f554b6f9ccde6580.js +1 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/541.26897ea32845659e36be.js +1 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/579.e569d3edd8391fd8fbb3.js +1 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/58.eb7cc679f7535cc8a2f1.js +2 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/58.eb7cc679f7535cc8a2f1.js.LICENSE.txt +8 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/666.d9bfdb23f98489d0a188.js +1 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/677.d266c39dbed33bc388b3.js +2 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/677.d266c39dbed33bc388b3.js.LICENSE.txt +8 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/68.26b6f59c8454adb17f20.js +204 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/694.4ac443814260057e68f7.js +1 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/791.61affb8d3480d3d60e0d.js +1 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/848.4d2db09cfbb09374b299.js +2 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/848.4d2db09cfbb09374b299.js.LICENSE.txt +9 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/868.5cfe7e1a348ec5af1b8c.js +1 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/97.ea559a5b8a9a09f17c6b.js +1 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/remoteEntry.5292fc9c6df7e7920cc8.js +1 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/style.js +4 -0
- codebuff_agent-2.1.74.data/data/share/jupyter/labextensions/codebuff/static/third-party-licenses.json +724 -0
- codebuff_agent-2.1.74.dist-info/METADATA +142 -0
- codebuff_agent-2.1.74.dist-info/RECORD +217 -0
- codebuff_agent-2.1.74.dist-info/WHEEL +4 -0
- codebuff_agent-2.1.74.dist-info/licenses/LICENSE +21 -0
- codebuff_core/__init__.py +153 -0
- codebuff_core/codebuff_config_defaults.json +64 -0
- codebuff_core/core/__init__.py +35 -0
- codebuff_core/core/code_validator.py +1238 -0
- codebuff_core/core/error_classifier.py +579 -0
- codebuff_core/core/exceptions.py +49 -0
- codebuff_core/data/tiktoken_cache/9b5ad71b2ce5302211f9c61530b329a4922fc6a4 +100256 -0
- codebuff_core/directory_policy.py +32 -0
- codebuff_core/factory.py +155 -0
- codebuff_core/interfaces.py +197 -0
- codebuff_core/knowledge/__init__.py +31 -0
- codebuff_core/knowledge/chunking.py +375 -0
- codebuff_core/knowledge/loader.py +339 -0
- codebuff_core/knowledge/watchdog_service.py +354 -0
- codebuff_core/legacy_paths.py +69 -0
- codebuff_core/llm/__init__.py +13 -0
- codebuff_core/llm/service.py +407 -0
- codebuff_core/managers/__init__.py +22 -0
- codebuff_core/managers/config_manager.py +690 -0
- codebuff_core/managers/remote_config.py +673 -0
- codebuff_core/managers/remote_skills.py +539 -0
- codebuff_core/managers/session_manager.py +255 -0
- codebuff_core/middleware/__init__.py +3 -0
- codebuff_core/middleware/error_recovery.py +394 -0
- codebuff_core/middleware/logging_utils.py +33 -0
- codebuff_core/models/__init__.py +111 -0
- codebuff_core/models/agent.py +306 -0
- codebuff_core/models/chat.py +57 -0
- codebuff_core/models/common.py +82 -0
- codebuff_core/models/rag.py +300 -0
- codebuff_core/platform_rules.py +127 -0
- codebuff_core/prompts/__init__.py +44 -0
- codebuff_core/prompts/auto_agent_prompts.py +1278 -0
- codebuff_core/services/__init__.py +30 -0
- codebuff_core/services/agent_service.py +345 -0
- codebuff_core/services/analytics_aggregate.py +837 -0
- codebuff_core/services/chat_service.py +898 -0
- codebuff_core/services/context_condenser.py +306 -0
- codebuff_core/services/pii_guardrail.py +393 -0
- codebuff_core/services/rag_chat_agent.py +2993 -0
- codebuff_core/services/rag_collections.py +2740 -0
- codebuff_core/services/rag_manager.py +890 -0
- codebuff_core/services/rag_service.py +145 -0
- codebuff_core/services/retriever.py +260 -0
- codebuff_core/services/vllm_embedding_service.py +290 -0
- codebuff_core/tests/__init__.py +1 -0
- codebuff_core/tests/conftest.py +81 -0
- codebuff_core/tests/test_error_recovery.py +647 -0
- codebuff_core/tests/test_factory.py +135 -0
- codebuff_core/tests/test_services.py +150 -0
- jupyter_ext/__init__.py +266 -0
- jupyter_ext/_version.py +4 -0
- jupyter_ext/agent/__init__.py +49 -0
- jupyter_ext/agent/agent_factory.py +2270 -0
- jupyter_ext/agent/ast_tools.py +451 -0
- jupyter_ext/agent/autofix_middleware.py +481 -0
- jupyter_ext/agent/background_procs.py +372 -0
- jupyter_ext/agent/code_history_middleware.py +211 -0
- jupyter_ext/agent/codex_autofix.py +160 -0
- jupyter_ext/agent/codex_bridge.py +3339 -0
- jupyter_ext/agent/codex_hooks.py +320 -0
- jupyter_ext/agent/codex_slash.py +685 -0
- jupyter_ext/agent/codex_threads.py +114 -0
- jupyter_ext/agent/content_injection.py +377 -0
- jupyter_ext/agent/continuation_middleware.py +548 -0
- jupyter_ext/agent/custom_skills.py +335 -0
- jupyter_ext/agent/file_diffs.py +99 -0
- jupyter_ext/agent/git_history.py +188 -0
- jupyter_ext/agent/guardrail_middleware.py +421 -0
- jupyter_ext/agent/json_repair_utils.py +54 -0
- jupyter_ext/agent/langchain_tools.py +2673 -0
- jupyter_ext/agent/mermaid_fixer.py +289 -0
- jupyter_ext/agent/mermaid_middleware.py +135 -0
- jupyter_ext/agent/middleware.py +359 -0
- jupyter_ext/agent/middleware_prompts.py +53 -0
- jupyter_ext/agent/observability.py +334 -0
- jupyter_ext/agent/patch_tool_calls.py +57 -0
- jupyter_ext/agent/prompts.py +112 -0
- jupyter_ext/agent/skill_middleware.py +257 -0
- jupyter_ext/agent/skills/airflow_dag_development.md +36 -0
- jupyter_ext/agent/skills/anomaly_detection.md +12 -0
- jupyter_ext/agent/skills/athena_sql.md +156 -0
- jupyter_ext/agent/skills/bdp_table_search.md +33 -0
- jupyter_ext/agent/skills/bigquery.md +65 -0
- jupyter_ext/agent/skills/bigquery_oracle.md +231 -0
- jupyter_ext/agent/skills/bigquery_tuning.md +307 -0
- jupyter_ext/agent/skills/classification_evaluation.md +11 -0
- jupyter_ext/agent/skills/clustering_analysis.md +12 -0
- jupyter_ext/agent/skills/comprehensive_eda.md +11 -0
- jupyter_ext/agent/skills/data_analysis.md +236 -0
- jupyter_ext/agent/skills/data_cleaning_pipeline.md +12 -0
- jupyter_ext/agent/skills/data_loading.md +158 -0
- jupyter_ext/agent/skills/data_quality_report.md +13 -0
- jupyter_ext/agent/skills/dimensionality_reduction.md +12 -0
- jupyter_ext/agent/skills/emr_script_development.md +17 -0
- jupyter_ext/agent/skills/experiment_tracking.md +13 -0
- jupyter_ext/agent/skills/feature_importance_analysis.md +10 -0
- jupyter_ext/agent/skills/hyperparameter_tuning.md +12 -0
- jupyter_ext/agent/skills/hypothesis_testing.md +12 -0
- jupyter_ext/agent/skills/imbalanced_data_handling.md +12 -0
- jupyter_ext/agent/skills/inference.md +392 -0
- jupyter_ext/agent/skills/lambda_function_development.md +19 -0
- jupyter_ext/agent/skills/model_comparison.md +11 -0
- jupyter_ext/agent/skills/model_explainability.md +12 -0
- jupyter_ext/agent/skills/model_training.md +318 -0
- jupyter_ext/agent/skills/pyspark.md +352 -0
- jupyter_ext/agent/skills/python_code_quality.md +35 -0
- jupyter_ext/agent/skills/regression_evaluation.md +12 -0
- jupyter_ext/agent/skills/spring_java_development.md +35 -0
- jupyter_ext/agent/skills/text_preprocessing.md +12 -0
- jupyter_ext/agent/skills/time_series_analysis.md +13 -0
- jupyter_ext/agent/skills/unit_testing.md +203 -0
- jupyter_ext/agent/todo_prompts.py +57 -0
- jupyter_ext/agent/tool_report.py +45 -0
- jupyter_ext/analytics_ingest.py +599 -0
- jupyter_ext/etc/jupyter/jupyter_server_config.d/codebuff_agent.json +7 -0
- jupyter_ext/handlers/__init__.py +8 -0
- jupyter_ext/handlers/analytics_handler.py +170 -0
- jupyter_ext/handlers/benchmark_handler.py +794 -0
- jupyter_ext/handlers/eda_benchmark_handler.py +1328 -0
- jupyter_ext/handlers/rag_admin_handler.py +689 -0
- jupyter_ext/handlers/websocket.py +497 -0
- jupyter_ext/http_handlers.py +8744 -0
- jupyter_ext/idle_monitor.py +346 -0
- jupyter_ext/labextension/package.json +157 -0
- jupyter_ext/labextension/static/104.2b8f20f9d1ac2c9db01b.js +1 -0
- jupyter_ext/labextension/static/150.39fa98117cc8ca590465.js +1 -0
- jupyter_ext/labextension/static/166.386ff9b2c37ac865fdee.js +1 -0
- jupyter_ext/labextension/static/216.25cf81131bf7274dabf4.js +1 -0
- jupyter_ext/labextension/static/353.581bd1cb00746399b62e.js +1 -0
- jupyter_ext/labextension/static/367.575f9621b63c9a641aa9.js +1 -0
- jupyter_ext/labextension/static/421.11dac223a2c2da1b09f5.js +1 -0
- jupyter_ext/labextension/static/432.8513b4c6cc1d1232d165.js +2 -0
- jupyter_ext/labextension/static/432.8513b4c6cc1d1232d165.js.LICENSE.txt +19 -0
- jupyter_ext/labextension/static/439.ba5b5ef70ec6de214b8c.js +2 -0
- jupyter_ext/labextension/static/439.ba5b5ef70ec6de214b8c.js.LICENSE.txt +8 -0
- jupyter_ext/labextension/static/481.cc2dec9fa869d66f1407.js +1 -0
- jupyter_ext/labextension/static/487.0796e931d6e651482c14.js +1 -0
- jupyter_ext/labextension/static/49.d326f554b6f9ccde6580.js +1 -0
- jupyter_ext/labextension/static/541.26897ea32845659e36be.js +1 -0
- jupyter_ext/labextension/static/579.e569d3edd8391fd8fbb3.js +1 -0
- jupyter_ext/labextension/static/58.eb7cc679f7535cc8a2f1.js +2 -0
- jupyter_ext/labextension/static/58.eb7cc679f7535cc8a2f1.js.LICENSE.txt +8 -0
- jupyter_ext/labextension/static/666.d9bfdb23f98489d0a188.js +1 -0
- jupyter_ext/labextension/static/677.d266c39dbed33bc388b3.js +2 -0
- jupyter_ext/labextension/static/677.d266c39dbed33bc388b3.js.LICENSE.txt +8 -0
- jupyter_ext/labextension/static/68.26b6f59c8454adb17f20.js +204 -0
- jupyter_ext/labextension/static/694.4ac443814260057e68f7.js +1 -0
- jupyter_ext/labextension/static/791.61affb8d3480d3d60e0d.js +1 -0
- jupyter_ext/labextension/static/848.4d2db09cfbb09374b299.js +2 -0
- jupyter_ext/labextension/static/848.4d2db09cfbb09374b299.js.LICENSE.txt +9 -0
- jupyter_ext/labextension/static/868.5cfe7e1a348ec5af1b8c.js +1 -0
- jupyter_ext/labextension/static/97.ea559a5b8a9a09f17c6b.js +1 -0
- jupyter_ext/labextension/static/remoteEntry.5292fc9c6df7e7920cc8.js +1 -0
- jupyter_ext/labextension/static/style.js +4 -0
- jupyter_ext/labextension/static/third-party-licenses.json +724 -0
- jupyter_ext/log_paths.py +113 -0
- jupyter_ext/resource_usage.py +519 -0
- jupyter_ext/secrets_bootstrap.py +116 -0
- jupyter_ext/team_access.py +105 -0
- jupyter_ext/tests/__init__.py +1 -0
- jupyter_ext/tests/test_context.py +234 -0
- jupyter_ext/tests/test_factory.py +563 -0
- jupyter_ext/tests/test_file_finder.py +139 -0
- jupyter_ext/tests/test_handlers.py +58 -0
- jupyter_ext/tests/test_mcp_selftest.py +204 -0
- jupyter_ext/tests/test_mermaid_fixer.py +272 -0
- jupyter_ext/tests/test_resource_tiers.py +298 -0
- jupyter_ext/tools/__init__.py +15 -0
- jupyter_ext/tools/base.py +90 -0
- jupyter_ext/tools/context.py +268 -0
- jupyter_ext/tools/dir_complete.py +86 -0
- jupyter_ext/tools/file_finder.py +303 -0
- jupyter_ext/tools/file_tools.py +244 -0
- jupyter_ext/tools/jupyter_tools.py +296 -0
- jupyter_ext/tools/registry.py +159 -0
- jupyter_ext/tools/search_tools.py +230 -0
- jupyter_ext/tools/security_tools.py +657 -0
- jupyter_ext/tools/shell_tools.py +109 -0
- jupyter_ext/tools/user_tools.py +132 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spring_java_development
|
|
3
|
+
description: 'Java & Spring Development Workflow. 이런 요청에 쓴다: spring, spring boot, java, maven, gradle, junit, controller, 스프링, 자바, jdk, jvm, pom.xml, pom, mvn, jar, war, multi-module, 멀티모듈, gc, heap, jvm 옵션, jvm option, java record, sealed class'
|
|
4
|
+
---
|
|
5
|
+
## Java & Spring Development Workflow
|
|
6
|
+
1. **Java**: Records, Sealed Classes, Streams, CompletableFuture
|
|
7
|
+
2. **Spring Boot**: Controller -> Service -> Repository -> Entity
|
|
8
|
+
3. **Maven**: mvn clean compile / mvn test / profiles / multi-module
|
|
9
|
+
4. **JDK/JVM**: -Xmx, GC options, compiler settings
|
|
10
|
+
5. **Test**: JUnit 5 + Mockito
|
|
11
|
+
|
|
12
|
+
## Spring Boot
|
|
13
|
+
- Constructor injection 사용 (@RequiredArgsConstructor)
|
|
14
|
+
- @RestController, @Service, @Repository 계층 분리
|
|
15
|
+
- @Valid + DTO 패턴으로 입력 검증
|
|
16
|
+
- @Transactional(readOnly = true) 기본, 변경 메서드만 @Transactional
|
|
17
|
+
- Entity: @Getter, @NoArgsConstructor(access = PROTECTED), @Builder
|
|
18
|
+
- ResponseEntity로 HTTP 상태 코드 명시 반환
|
|
19
|
+
- 예외 처리: @ExceptionHandler 또는 @ControllerAdvice
|
|
20
|
+
- JUnit 5 + Mockito 테스트 생성 (MockMvc for Controller, @Mock for Service)
|
|
21
|
+
- 빌드 명령: mvn clean compile, mvn test
|
|
22
|
+
|
|
23
|
+
## Java General
|
|
24
|
+
- Java 17+ 기능 적극 활용 (Records, Sealed Classes, Pattern Matching)
|
|
25
|
+
- Stream API, Optional 적극 사용
|
|
26
|
+
- Effective Java 원칙 준수 (불변 객체, 방어적 복사 등)
|
|
27
|
+
|
|
28
|
+
## Maven & Build
|
|
29
|
+
- maven-compiler-plugin source/target 명시
|
|
30
|
+
- 적절한 dependency scope 사용 (provided, runtime, test)
|
|
31
|
+
- Multi-module 시 parent pom에 dependencyManagement 사용
|
|
32
|
+
|
|
33
|
+
## JDK/JVM
|
|
34
|
+
- JDK 17 기본 권장, 요구사항에 따라 11/21 제안
|
|
35
|
+
- 메모리/GC 옵션은 용도에 맞게 제안 (서버 vs 배치)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: text_preprocessing
|
|
3
|
+
description: 'Text Preprocessing Template. 이런 요청에 쓴다: tokenization, tf-idf, nlp, vectorization, 텍스트 전처리, 자연어'
|
|
4
|
+
---
|
|
5
|
+
## Text Preprocessing Template
|
|
6
|
+
1. **Cleaning**: Lowercase, remove HTML/URLs/special chars, strip whitespace
|
|
7
|
+
2. **Tokenization**: `nltk.word_tokenize()` or `spacy.load('en')` pipeline
|
|
8
|
+
3. **Stopword Removal**: `nltk.corpus.stopwords`, domain-specific additions
|
|
9
|
+
4. **Lemmatization/Stemming**: `WordNetLemmatizer()` or `PorterStemmer()`
|
|
10
|
+
5. **Vectorization**: `TfidfVectorizer(max_features=5000)` or `CountVectorizer`
|
|
11
|
+
6. **Embeddings**: Word2Vec, FastText, or Sentence-BERT for semantic vectors
|
|
12
|
+
7. **Validation**: Check vocabulary size, sparsity, sample transformed texts
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: time_series_analysis
|
|
3
|
+
description: 'Time Series Analysis Template. 이런 요청에 쓴다: time series, arima, forecast, prophet, 시계열, 예측 모델'
|
|
4
|
+
---
|
|
5
|
+
## Time Series Analysis Template
|
|
6
|
+
1. **Visualization**: Line plot with datetime index, check trend & seasonality
|
|
7
|
+
2. **Stationarity Test**: ADF test (`adfuller()`), KPSS test
|
|
8
|
+
3. **Decomposition**: `seasonal_decompose()` → trend, seasonal, residual
|
|
9
|
+
4. **ACF/PACF**: `plot_acf()`, `plot_pacf()` for lag analysis
|
|
10
|
+
5. **Modeling**: ARIMA/SARIMA (`pmdarima.auto_arima()`), Prophet, or Exponential Smoothing
|
|
11
|
+
6. **Forecast**: Generate future predictions with confidence intervals
|
|
12
|
+
7. **Evaluation**: RMSE, MAE, MAPE on hold-out test set
|
|
13
|
+
8. **Visualization**: Plot actual vs predicted with forecast horizon
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: unit-testing
|
|
3
|
+
description: pytest 유닛테스트 생성 가이드. 의존성 분석, 테스트 구조, fixture, mock, parametrize, 커버리지 패턴 제공.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Unit Testing Guide (pytest)
|
|
7
|
+
|
|
8
|
+
## 테스트 파일 구조
|
|
9
|
+
|
|
10
|
+
```python
|
|
11
|
+
"""Tests for <module_name>."""
|
|
12
|
+
import pytest
|
|
13
|
+
from <module> import <target_function_or_class>
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TestTargetFunction:
|
|
17
|
+
"""<target_function> 테스트."""
|
|
18
|
+
|
|
19
|
+
def test_basic_case(self):
|
|
20
|
+
"""정상 입력에 대한 기본 동작."""
|
|
21
|
+
result = target_function(valid_input)
|
|
22
|
+
assert result == expected
|
|
23
|
+
|
|
24
|
+
def test_edge_case_empty(self):
|
|
25
|
+
"""빈 입력 처리."""
|
|
26
|
+
result = target_function("")
|
|
27
|
+
assert result == default_or_empty
|
|
28
|
+
|
|
29
|
+
def test_error_case(self):
|
|
30
|
+
"""잘못된 입력 시 예외 발생."""
|
|
31
|
+
with pytest.raises(ValueError):
|
|
32
|
+
target_function(invalid_input)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Import 의존성 처리 패턴
|
|
36
|
+
|
|
37
|
+
### 내부 모듈 (프로젝트 내)
|
|
38
|
+
직접 import하여 통합 테스트. 실제 동작을 검증:
|
|
39
|
+
```python
|
|
40
|
+
from myproject.utils import parse_config
|
|
41
|
+
from myproject.models import User
|
|
42
|
+
|
|
43
|
+
def test_parse_config_integration():
|
|
44
|
+
result = parse_config({"name": "test"})
|
|
45
|
+
assert isinstance(result, User)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 외부 라이브러리 (third-party, 네트워크, DB)
|
|
49
|
+
mock/patch로 격리하여 단위 테스트:
|
|
50
|
+
```python
|
|
51
|
+
from unittest.mock import patch, MagicMock
|
|
52
|
+
|
|
53
|
+
def test_fetch_data():
|
|
54
|
+
with patch("mymodule.requests.get") as mock_get:
|
|
55
|
+
mock_get.return_value.json.return_value = {"data": [1, 2]}
|
|
56
|
+
result = fetch_data("http://api.example.com")
|
|
57
|
+
assert result == [1, 2]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 의존성 판별 기준
|
|
61
|
+
| 구분 | 예시 | 처리 |
|
|
62
|
+
|------|------|------|
|
|
63
|
+
| 내부 모듈 | `from .utils import helper` | 직접 import |
|
|
64
|
+
| 표준 라이브러리 | `import os, json, pathlib` | 직접 사용 |
|
|
65
|
+
| 외부 라이브러리 | `import requests, boto3, sqlalchemy` | mock/patch |
|
|
66
|
+
| 파일 I/O | `open(), Path.read_text()` | tmp_path fixture |
|
|
67
|
+
| 네트워크 | `requests.get, httpx.AsyncClient` | mock/patch |
|
|
68
|
+
| DB | `session.query(), cursor.execute()` | mock/patch |
|
|
69
|
+
|
|
70
|
+
## 핵심 패턴
|
|
71
|
+
|
|
72
|
+
### Fixture (공유 설정)
|
|
73
|
+
```python
|
|
74
|
+
@pytest.fixture
|
|
75
|
+
def sample_data():
|
|
76
|
+
return {"key": "value", "count": 42}
|
|
77
|
+
|
|
78
|
+
def test_with_fixture(sample_data):
|
|
79
|
+
assert sample_data["count"] == 42
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Parametrize (다중 입력 테스트)
|
|
83
|
+
```python
|
|
84
|
+
@pytest.mark.parametrize("input_val,expected", [
|
|
85
|
+
(1, 1),
|
|
86
|
+
(2, 4),
|
|
87
|
+
(3, 9),
|
|
88
|
+
(-1, 1),
|
|
89
|
+
(0, 0),
|
|
90
|
+
])
|
|
91
|
+
def test_square(input_val, expected):
|
|
92
|
+
assert square(input_val) == expected
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Mock (외부 의존성 격리)
|
|
96
|
+
```python
|
|
97
|
+
from unittest.mock import patch, MagicMock
|
|
98
|
+
|
|
99
|
+
def test_api_call():
|
|
100
|
+
with patch("module.requests.get") as mock_get:
|
|
101
|
+
mock_get.return_value.json.return_value = {"status": "ok"}
|
|
102
|
+
result = fetch_status()
|
|
103
|
+
assert result == "ok"
|
|
104
|
+
mock_get.assert_called_once()
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Async 테스트
|
|
108
|
+
```python
|
|
109
|
+
@pytest.mark.asyncio
|
|
110
|
+
async def test_async_function():
|
|
111
|
+
result = await async_fetch("url")
|
|
112
|
+
assert result is not None
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## 커버리지 체크리스트
|
|
116
|
+
|
|
117
|
+
테스트 생성 시 반드시 확인:
|
|
118
|
+
|
|
119
|
+
- [ ] **Public 함수/메서드**: 모든 public API에 최소 1개 테스트
|
|
120
|
+
- [ ] **분기 (if/else)**: 각 분기 경로별 테스트
|
|
121
|
+
- [ ] **예외 경로**: `raise`, `try/except` 블록 검증
|
|
122
|
+
- [ ] **경계값**: 0, 빈 문자열, None, 빈 리스트, 매우 큰 값
|
|
123
|
+
- [ ] **타입 변환**: 입력 타입이 다를 때의 동작
|
|
124
|
+
- [ ] **기본값**: 선택적 파라미터의 기본값 동작
|
|
125
|
+
|
|
126
|
+
## conftest.py 패턴
|
|
127
|
+
|
|
128
|
+
공유 fixture는 `conftest.py`에 정의:
|
|
129
|
+
```python
|
|
130
|
+
# conftest.py
|
|
131
|
+
import pytest
|
|
132
|
+
from pathlib import Path
|
|
133
|
+
|
|
134
|
+
@pytest.fixture
|
|
135
|
+
def sample_dir(tmp_path):
|
|
136
|
+
"""테스트용 디렉토리 구조 생성."""
|
|
137
|
+
(tmp_path / "data.csv").write_text("a,b\n1,2\n")
|
|
138
|
+
return tmp_path
|
|
139
|
+
|
|
140
|
+
@pytest.fixture
|
|
141
|
+
def mock_env(monkeypatch):
|
|
142
|
+
"""환경변수 설정."""
|
|
143
|
+
monkeypatch.setenv("API_KEY", "test-key")
|
|
144
|
+
monkeypatch.setenv("DEBUG", "true")
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## 테스트 대상별 가이드
|
|
148
|
+
|
|
149
|
+
### 순수 함수
|
|
150
|
+
- 입력/출력 쌍으로 parametrize
|
|
151
|
+
- 경계값: 0, 빈 문자열, None, 매우 큰 값
|
|
152
|
+
- 타입 에러 케이스
|
|
153
|
+
|
|
154
|
+
### 클래스
|
|
155
|
+
- `__init__` 파라미터 검증
|
|
156
|
+
- 메서드별 독립 테스트
|
|
157
|
+
- 상태 변경 추적 (before/after)
|
|
158
|
+
|
|
159
|
+
### 파일 I/O
|
|
160
|
+
- `tmp_path` fixture 사용
|
|
161
|
+
- 존재하지 않는 파일 처리
|
|
162
|
+
- 인코딩 에러 처리
|
|
163
|
+
|
|
164
|
+
### DataFrame 함수
|
|
165
|
+
```python
|
|
166
|
+
import pandas as pd
|
|
167
|
+
|
|
168
|
+
@pytest.fixture
|
|
169
|
+
def sample_df():
|
|
170
|
+
return pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})
|
|
171
|
+
|
|
172
|
+
def test_transform(sample_df):
|
|
173
|
+
result = transform_df(sample_df)
|
|
174
|
+
assert "new_col" in result.columns
|
|
175
|
+
assert len(result) == 3
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### .ipynb 노트북 코드
|
|
179
|
+
노트북에서 추출한 함수/클래스를 테스트:
|
|
180
|
+
1. 노트북의 함수 정의를 별도 .py 모듈로 추출하여 import
|
|
181
|
+
2. 또는 `%run notebook.ipynb`로 네임스페이스 로드 후 테스트
|
|
182
|
+
3. 전역 변수 의존성은 fixture로 대체
|
|
183
|
+
|
|
184
|
+
## 커버리지 실행 가이드
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
# 기본 커버리지 측정
|
|
188
|
+
pytest --cov=module_name --cov-report=term-missing
|
|
189
|
+
|
|
190
|
+
# HTML 리포트 생성
|
|
191
|
+
pytest --cov=module_name --cov-report=html
|
|
192
|
+
|
|
193
|
+
# 특정 파일만
|
|
194
|
+
pytest tests/test_utils.py --cov=utils --cov-report=term-missing
|
|
195
|
+
|
|
196
|
+
# 최소 커버리지 강제
|
|
197
|
+
pytest --cov=module_name --cov-fail-under=80
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## 네이밍 규칙
|
|
201
|
+
- 파일: `test_<원본파일명>.py`
|
|
202
|
+
- 클래스: `Test<대상클래스또는함수>`
|
|
203
|
+
- 메서드: `test_<동작>_<조건>` (예: `test_parse_empty_input`)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Data Science 특화 TodoListMiddleware 프롬프트.
|
|
2
|
+
|
|
3
|
+
TodoListMiddleware 의 tool_description 을 DS 코딩 에이전트에 맞게
|
|
4
|
+
커스터마이즈한 도구 설명. system_prompt 는 `prompts.todo_rules` 키다 (이슈 #218).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
DS_TODO_TOOL_DESCRIPTION = """Jupyter 노트북에서 데이터 사이언스 작업을 계획하고 추적하는 도구입니다.
|
|
8
|
+
|
|
9
|
+
## 사용 시점
|
|
10
|
+
여러 단계에 걸친 작업(분석 파이프라인·여러 셀에 걸친 변경 등)일 때만 계획을 세웁니다.
|
|
11
|
+
데이터 분석·EDA·모델링 요청은 사소한 작업이 아니라 여러 단계에 걸친 작업으로 봅니다.
|
|
12
|
+
- 데이터 분석, EDA, 모델링 요청
|
|
13
|
+
- 여러 단계로 이어지는 데이터 전처리, 정제, 변환
|
|
14
|
+
- 여러 차트가 포함된 시각화
|
|
15
|
+
- 접근법 비교가 필요한 실험
|
|
16
|
+
- 중간 결과가 다음 단계에 영향을 미치는 작업
|
|
17
|
+
- 사용자가 분석 작업 목록을 제공한 경우
|
|
18
|
+
|
|
19
|
+
## 사용하지 않는 경우
|
|
20
|
+
사소하거나 한두 번의 도구 호출로 끝나는 작업은 계획을 세우지 않습니다.
|
|
21
|
+
- 단순 대화형 질문 (예: "EDA가 뭔가요?")
|
|
22
|
+
- 한 줄로 끝나는 정보 조회 (예: "데이터 shape이 뭐야?")
|
|
23
|
+
- 셀 하나를 고치거나 실행하는 작업
|
|
24
|
+
- 한두 단계로 끝나는 계획
|
|
25
|
+
|
|
26
|
+
## DS 워크플로우 단계
|
|
27
|
+
계획 수립 시 해당되는 단계를 참고하세요:
|
|
28
|
+
1. **데이터 이해**: EDA, 스키마 확인, 결측값, 분포 분석
|
|
29
|
+
2. **데이터 전처리**: 정제, 타입 변환, null/이상값 처리
|
|
30
|
+
3. **피처 엔지니어링**: 피처 생성, 선택, 변환, 인코딩
|
|
31
|
+
4. **모델링**: 모델 선택, 학습, 하이퍼파라미터 튜닝
|
|
32
|
+
5. **평가**: 메트릭, 시각화, 비교, 오차 분석
|
|
33
|
+
6. **보고**: 요약 마크다운 셀, 주요 발견, 권장사항
|
|
34
|
+
|
|
35
|
+
## 작업 상태
|
|
36
|
+
- pending: 아직 시작하지 않음
|
|
37
|
+
- in_progress: 현재 진행 중 (작업 시작 전에 표시)
|
|
38
|
+
- completed: 결과가 검증된 완료 상태
|
|
39
|
+
|
|
40
|
+
## 작업 관리
|
|
41
|
+
- 계획을 만들 때 첫 번째 작업을 즉시 in_progress로 표시하세요
|
|
42
|
+
- 작업 완료 즉시 completed로 표시하세요 — 일괄 처리하지 마세요
|
|
43
|
+
- 모든 작업이 완료되지 않은 한 항상 하나 이상이 in_progress 상태여야 합니다
|
|
44
|
+
- 중간 결과에 따라 불필요해진 작업은 제거하세요
|
|
45
|
+
- 실험에서 예상치 못한 발견이 있으면 새 작업을 추가하세요
|
|
46
|
+
- 검증된 출력이 있을 때만 작업을 completed로 표시하세요
|
|
47
|
+
|
|
48
|
+
## DS 작업 팁
|
|
49
|
+
- 데이터 로드 후 모델링 전에 반드시 간단한 EDA 단계를 추가하세요
|
|
50
|
+
- 모델 비교 시 평가 기준을 먼저 계획하세요
|
|
51
|
+
- 모델링 접근법이 실패하면 무리하게 진행하지 말고 남은 작업을 수정하세요
|
|
52
|
+
|
|
53
|
+
## 할 일 내용 작성 규칙
|
|
54
|
+
- 각 할 일의 content는 **반드시 한국어**로 작성하세요.
|
|
55
|
+
- 간결하고 명확하게 작성하세요.
|
|
56
|
+
- 예시: "데이터 로드 및 기본 구조 확인", "결측값 처리", "모델 학습 및 평가"
|
|
57
|
+
"""
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""centri 에 보고할 에이전트 도구 정의 (이슈 #248).
|
|
2
|
+
|
|
3
|
+
두 엔진이 모델에 넘기는 도구 정의를 그대로 옮긴다 — 카탈로그를 따로 적으면 도구가
|
|
4
|
+
늘 때 보고만 조용히 낡는다. centri 계약에 맞추는 일은 보내는 쪽
|
|
5
|
+
(`codebuff_core.managers.remote_skills.clean_tools`)이 한다.
|
|
6
|
+
|
|
7
|
+
- codex: `CODEX_DYNAMIC_TOOLS` 전체. 승인은 `ask` 모드에서 승인을 받는 `GUARDED_POD_TOOLS`.
|
|
8
|
+
- langchain: `AgentFactory._create_all_tools()` 가 만드는 기본 도구. 승인은 HITL 대상
|
|
9
|
+
(`HITL_TOOL_NAMES`). 미들웨어가 붙이는 도구(read_file·grep 등)와 모드별 도구는 싣지 않는다.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from typing import Any, Dict, List
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def agent_tools_report() -> List[Dict[str, Any]]:
|
|
18
|
+
from .._version import __version__
|
|
19
|
+
from .agent_factory import HITL_TOOL_NAMES, AgentFactory
|
|
20
|
+
from .codex_bridge import CODEX_DYNAMIC_TOOLS, GUARDED_POD_TOOLS
|
|
21
|
+
|
|
22
|
+
entries: List[Dict[str, Any]] = [
|
|
23
|
+
{
|
|
24
|
+
"name": spec["name"],
|
|
25
|
+
"engine": "codex",
|
|
26
|
+
"codebuff_version": __version__,
|
|
27
|
+
"description": spec.get("description", ""),
|
|
28
|
+
"input_schema": spec.get("inputSchema") or {},
|
|
29
|
+
"approval": spec["name"] in GUARDED_POD_TOOLS,
|
|
30
|
+
}
|
|
31
|
+
for spec in CODEX_DYNAMIC_TOOLS
|
|
32
|
+
]
|
|
33
|
+
# 도구는 호출될 때만 노트북·워크스페이스를 본다 — 정의를 읽는 데는 둘 다 필요 없다
|
|
34
|
+
for tool in AgentFactory(None)._create_all_tools():
|
|
35
|
+
entries.append(
|
|
36
|
+
{
|
|
37
|
+
"name": tool.name,
|
|
38
|
+
"engine": "langchain",
|
|
39
|
+
"codebuff_version": __version__,
|
|
40
|
+
"description": tool.description,
|
|
41
|
+
"input_schema": tool.tool_call_schema.model_json_schema(),
|
|
42
|
+
"approval": tool.name in HITL_TOOL_NAMES,
|
|
43
|
+
}
|
|
44
|
+
)
|
|
45
|
+
return entries
|