Backend — pipeline 패키지 - xxriny/KNU-PROJECT GitHub Wiki
1. backend/pipeline/init.py
| 라인 | 코드 | 설명 |
|---|---|---|
| — | (빈 파일) | 패키지 초기화 |
2. backend/pipeline/action_type.py
| 라인 | 코드 | 설명 |
|---|---|---|
| 3 | ANALYSIS_ACTION_TYPES |
{"CREATE","UPDATE","REVERSE_ENGINEER"} 집합 |
| 5–8 | normalize_action_type() |
.upper() 후 집합 포함 검증, 미포함 시 예외 |
3. backend/pipeline/state.py
| 라인 | 코드 | 설명 |
|---|---|---|
| 1–15 | import | TypedDict, Annotated, typing |
| 17–21 | _merge_thinking_logs() |
리스트 누적 리듀서 — 여러 노드의 thinking_log 병합 |
| 24–28 | _keep_last_step() |
마지막 current_step 값 유지 리듀서 |
| 32–37 | _BaseState |
api_key, model, run_id, error, thinking_log(Annotated), current_step(Annotated) |
| 40–70 | _AnalysisFields |
input_idea, project_context, source_dir, action_type, requirements_rtm, semantic_graph, context_spec, sa_phase1~sa_phase8, sa_artifacts, sa_output 등 분석 단계 필드 |
| 73–77 | _ChatFields |
user_request, chat_history, agent_reply, previous_result — 수정 모드 필드 |
| 80–84 | _IdeaFields |
idea_ready, idea_summary, suggested_mode — 아이디어 발산 필드 |
| 88–92 | PipelineState |
_BaseState + _AnalysisFields + _ChatFields + _IdeaFields 통합 TypedDict |
| 102–109 | sget() |
안전한 state 딕셔너리 접근 헬퍼(KeyError 방지, 기본값 반환) |
| 112–118 | make_sget() |
curried sget 반환 — 노드 상단에서 sget = make_sget(state) 패턴 |
4. backend/pipeline/node_base.py
| 라인 | 코드 | 설명 |
|---|---|---|
| 14–22 | NodeContext 데이터클래스 |
state, sget, api_key, model, node_name — 노드 공통 실행 문맥 |
| 24–26 | thinking_log property |
thinking_log 리스트 반환 |
| 29–89 | @pipeline_node 데코레이터 |
(1) sget 자동 초기화, (2) api_key/model 추출, (3) thinking_log 누적, (4) try-except 안전망 → 에러 시 {"error": msg, "current_step": "error"} 반환 |
5. backend/pipeline/graph.py
| 라인 | 코드 | 설명 |
|---|---|---|
| 25–36 | _PipelineRegistry |
싱글턴 캐시 — 파이프라인 그래프 재생성 방지 |
| 68 | SA_EARLY_TERMINATION_STATUSES |
{"Error"} — SA 조기 종료 조건 |
| 71 | PM_INPUT_READINESS_FAILURE_STATUSES |
{"Needs_Clarification","Error","Completed_with_errors"} |
| 72–92 | _check_status() |
조기 종료 라우터 — SA Error→END, PM 실패→END |
| 95–110 | _add_all_analysis_nodes() |
모든 분석 노드(atomizer~sa_phase8+reverse) 등록 |
| 113–121 | _wire_linear_pipeline() |
순차 파이프라인 배선(START→chain→END) + 조건부 라우팅 |
| 137 | _CREATE_CHAIN |
12개 노드 튜플(atomizer→prioritizer→rtm_builder→semantic_indexer→context_spec→sa_phase3→sa_phase4→sa_phase5→sa_phase6→sa_phase7→sa_phase8→sa_reverse_context) |
| 142 | _UPDATE_CHAIN |
15개 노드 튜플(sa_phase1→PM 5단계→sa_phase2~sa_phase8) |
| 147 | _REVERSE_CHAIN |
8개 노드 튜플(sa_phase1→sa_phase3→sa_phase4→sa_phase5→sa_phase6→sa_phase7→sa_phase8) |
| 151–174 | 파이프라인 빌더 | _build_analysis_pipeline(), _get_create_pipeline(), get_update_sa_pipeline(), get_reverse_sa_pipeline() |
| 177–215 | 공개 API | get_analysis_pipeline(action_type), get_revision_pipeline(), get_idea_pipeline() — StateGraph 빌드 |
| 234–266 | 라우팅 맵 | get_pipeline_routing_map(), get_revision_routing_map(), get_idea_chat_routing_map() |
6. backend/pipeline/ast_scanner.py
| 라인 | 코드 | 설명 |
|---|---|---|
| 8–21 | 상수 | _PYTHON_EXTS, _JS_EXTS, _MAX_FILE_BYTES(5MB), _SKIP_DIRS, _JS_IMPORT_RE |
| 34–36 | _should_skip_dir() |
__pycache__, node_modules 등 무시 판정 |
| 41–67 | _parse_python_file() |
Python AST 파싱 → 함수/메서드 시그니처 추출 |
| 70–95 | _collect_python_imports() |
Python import 구문 추출 |
| 108–136 | _parse_js_file() / _collect_js_imports() |
JS/TS 정규식 기반 함수/import 추출 |
| 139–167 | _enumerate_source_files() / _language_for_suffix() / _entrypoint_hint() |
소스 파일 열거, 언어 판정, 진입점 감지 |
| 176–251 | 내부 임포트 해석 | Python/JS import 후보 경로 생성 → 내부 import 필터링 |
| 256–286 | extract_functions() |
공개 API — 소스 함수 목록 추출(최대 300개 토큰 제한) |
| 289–324 | extract_file_inventory() |
공개 API — 파일 인벤토리 + 내부 import 관계 반환 |
| 327–345 | summarize_for_llm() |
공개 API — 함수 목록을 LLM 프롬프트용 텍스트 변환 |
7. backend/pipeline/utils.py
| 라인 | 코드 | 설명 |
|---|---|---|
| 16 | _CACHE_LIMIT |
32개 LRU 캐시 제한 |
| 21–25 | LLMResult 데이터클래스 |
parsed, usage, thinking — LLM 호출 결과 |
| 28–37 | 캐시 유틸 | _make_llm_cache_key(), _remember_cache_entry() — (key:model:temp) 키 LRU |
| 39–59 | _get_effective_key() |
인자 우선 → os.environ["GEMINI_API_KEY"] 폴백 → 예외 |
| 65–83 | get_llm() |
ChatGoogleGenerativeAI 싱글턴 캐싱(threading.Lock 보호) |
| 86–117 | _retry_loop() |
Self-Correction 재시도 루프(MAX_LLM_RETRIES회, validator 콜백) |
| 121–165 | call_structured() |
공개 API — with_structured_output() 호출 → LLMResult[T] 반환 |
| 168–195 | call_structured_with_usage() / call_structured_with_thinking() |
하위 호환 래퍼 |
| 200–240 | _get_raw_client() / call_gemini() |
google.genai 직접 API 호출(비구조화 텍스트) |
| 243–269 | JSON/thinking 추출 | extract_json_block(), parse_json_safe(), extract_thinking() |
| 272–286 | to_serializable() |
Pydantic/set/Enum 등 재귀 직렬화 변환 |
8. backend/pipeline/chroma_client.py
| 라인 | 코드 | 설명 |
|---|---|---|
| 8 | CHROMA_DB_PATH |
backend/Data/chroma_db |
| 11–12 | 싱글턴 | _client, _collection — Optional 전역 변수 |
| 15–24 | _init_chroma() |
PersistentClient 초기화, 컬렉션 pm_agent_knowledge |
| 27–56 | add_knowledge() |
REQ_ID↔소스코드 매핑 벡터 저장, run_id 메타데이터 |
| 59–78 | delete_by_run_id() |
특정 실행 결과 삭제 |
| 81–115 | search_similar() |
코사인 유사도 검색(top_k=5) |
| 118–125 | get_collection_stats() |
컬렉션 문서 수 반환 |