Releases: eddmpython/dartlab
Releases · eddmpython/dartlab
v0.9.25
내부 안정화 작업.
Changed
- AI 가 한 번에 여러 도구를 동시에 호출할 수 있어 종합 분석 응답 시간 단축. "삼성전자 전체 분석" 같은 다축 질문이 끊김 없이 완료.
- 같은 종목코드 하나로
c.show("BS")·c.show("IS", freq="Y")·c.story()·c.credit()·c.analysis(...)일관되게 호출되도록 진입점 정리. - 동일 보고서 두 진입점 노출 (
c.review/c.story) 같은 중복 제거. 이제c.story()가 유일 보고서 빌더.
Fixed
- 일부 AI 응답에서 다축 분석이 중간에 끊기던 문제 해결.
- 노트북 가이드 출력에서 안내한 일부 단축 진입점이 실제로는 동작하지 않던 문제 해결 (
c.show("inventory")등 통합 진입점으로 안내 통일).
Internal
- 같은 데이터에 두 가지 import 경로가 있던 호환 모듈 제거. 사용자 코드 영향 없음 (사용자 진입점은
Company·dartlab.ask· 엔진 함수 그대로 유지).
v0.9.21
quant 엔진 안정화 + 대시보드 재설계 + 접근성 회귀 해소.
Fixed
- EDGAR 종목에서 일부 L2 분석 축이 None 이던 문제 — snakeId alias 양방향 확장으로 인텔·애플 등 EDGAR 기업에서 이전에 비어있던 재무 지표가 값을 반환하도록 복구.
/lab하위 페이지 내부 링크 깨짐 — GitHub Pages base path prefix 누락으로 배포 prerender 에러가 발생하던 문제. brand href 전수 보정.- 블로그 2 편 parse 에러 해소 —
silicon2·taihan-cable포스트의<·SGA < 15%표현이 mdsvex 에서 HTML 태그로 오인되던 문제.
Changed
- quant 엔진 팩터 계산 안정화 — accruals · altman · BAB · beneish · earningsSurprise · fundamentalMomentum · piotroski · qFactor · QMJ 9 개 alpha 정비 + factorBuild · spec 일관화. 팩터 반환값 품질 개선.
- 대시보드 페이지 재설계 —
/dashboard/{stockCode}를 v2 디자인 토큰 기반으로 단순화, 로드 속도·가독성 개선. - review 해석 문장 확장 — narrate 함수가 현금흐름·부채·매출성장 등에서 더 세밀한 조건 분기로 해석 생성.
v0.9.20
내부 안정화 + 버그 수정.
Fixed
dartlab.ask()가 ECOS / FRED 등 API 키 필요 축을 호출할 때 사용자에게 키 설정 안내가 전달되지 않던 문제 — 이전엔 서버 터미널에만 "키 필요" 로그가 출력돼 landing UI 등에서 호출한 사용자는 원인을 알 수 없었다. 이제 AI 응답 본문에 발급 URL +.env설정법이 직접 포함된다.- Windows 터미널에서 한글 로그·가이드 출력이 깨지던 문제 — 기본 인코딩이
cp949인 환경에서UnicodeEncodeError또는 가독성 저하.import dartlab시점에 stdout/stderr 를 UTF-8 로 자동 재구성한다. dartlab channel실행 직후 host 로그 스레드 크래시 — devtunnel stdout 중계 스레드가TypeError로 즉시 사망해[dt] Connect via browser: ...URL 출력이 끊기던 문제.
Changed
- 종목 오타 시 유사 종목 제안 —
Company('삼성전제')처럼 오타 입력 시 에러 메시지에 KRX 상장 종목 기반 fuzzy 매칭 top-3 을 함께 안내한다 (초성·편집거리·부분일치 지원). - 공시 검색 delta 인덱스 · Industry Map · Data Sync 등 일일 데이터 파이프라인 갱신 안정화 — 외부 데이터셋 저장소 업로드 경합으로 간헐적으로 실행이 취소되던 문제 해소. 이제 일일 cron 이 안정적으로 완료된다.
Added
ops/credit.md— 독립 신용등급 엔진 공개 문서. 7축 구조,override키, 실패 시나리오 정리.
v0.9.19
질적 안정 Q3.1 tail + Q4 효율성 + Q5 dead code 제거. 정식 1.0.0 아님 — 외부 venv 종합 검증 및 사용자 최종 승인 후에만 1.0.0 릴리즈.
Changed
- F/E-rank 복잡도 감축 (Q3.1 tail):
_calcTwoStageDcfCC 63→5 (7 sub-helper 로 분할 — wacc 해결, 고성장률, phase config, terminal growth, baseFcf, normalized FCF, netDebt+shares). E/F-rank (CC≥30) 함수 수 197 → 149 (-24%) 달성. - 효율성 — hotpath lru_cache (Q4.1):
mapSectionTitle/normalizeSectionTitle/loadSectionProfileTable@lru_cache적용. O(n²) 파이프라인 섹션 매핑 루프에서 동일 title 반복 조회 캐시 재사용. - 효율성 — regex 모듈 상수화 (Q4.2): 함수 내부
re.compile(...)15건 → 모듈 레벨 상수.providers/dart/company._QUARTER_COL_RE,providers/dart/_table_horizontalizer._UNIT_ONLY_RE/_DATE_ONLY_RE,providers/dart/docs/finance/boardOfDirectors/parser._MEETING_DATE_RE등 8 파일. 호출당 재컴파일 비용 제거.
Removed
- Dead code 제거 (Q5, 8,201줄 삭감):
analysis/financial/research/narrative.py(3,106줄),research/orchestrator.py(1,123줄),research/thesis.py · sectorKpi · spec · quality(685줄) —generateResearch()는 export 됐으나 외부 호출 경로 0건.research/scoring.py,research/types.py는 scorecard 에서 실사용하므로 유지.providers/dart/finance/mapperData/_backup/sortOrder.json(3,231줄) — 과거 snapshot, 현 sortOrder.json 이 SSoT.
Fixed
forecastCalcs.calcStructuralBreakimport 복구: 기존from dartlab.analysis.financial.research.predictionSignals import calcStructuralBreak는 존재하지 않는 경로.try/except ImportError가 silent 하게 삼켰고structuralBreak는 항상 None 이었음 (Chow Test 신호 실종).dartlab.analysis.financial.predictionSignals로 정상 경로 복구.
Migration
- 제거된
research.generateResearch·research.sectorKpi.calcSectorKpis·research.thesis·research.quality·research.narrative.buildNarrative는 외부 호출 경로가 없던 미공개 API — 외부 사용자 영향 없음. from dartlab.analysis.financial.research import calcPiotroski는 계속 유지.
v0.9.18
Fixed
c.show()라우팅 ValueError 제거:c.show("bond")/show("business")/show("fundraising")/show("companyOverviewDetail")등 registry 에는 등록됐으나 특정 회사에 데이터가 없는 topic 에서ValueError: 'topic 을 찾을 수 없습니다'로 크래시하던 문제. 이제 registered-but-empty 는None리턴, truly-unknown 만 warning +None.scan("debt")ComputeError 수정: polars schema inference 한도(기본 100행)를 넘는 큰 금액 값에서could not append value 1.2e11 ... schema mismatch로 크래시.pl.DataFrame(..., infer_schema_length=None)로 전체 행 스캔 후 schema 결정.
Added
tests/test_showRouting.py(38 parametrize 테스트): registry 의 report/disclosure topic 전수 iterate 해show()가 ValueError 없이 DataFrame or None 리턴 확인._showImpl라우팅 회귀 구조적 차단.
Changed
- quality gate baseline:
ef_count196 → 197 (_showImplregistered-but-empty 분기 추가로 복잡도 +1, 기능적 가치 대비 수용).
v0.9.17
Fixed
- PyPI wheel 에
src/dartlab/core/data/누락 재발 방지:.gitignore의 루트-미지정data/패턴이src/dartlab/core/data/까지 매치해python -m build가 해당 디렉토리를 wheel 에서 제외하던 문제..gitignore를/data/로 루트-스코프 제한하고,pyproject.toml의[tool.hatch.build.targets.wheel]에include명시를 추가해 다중 방어. - wheel-smoke 검증 대상과 publish wheel 일치: 기존에는 wheel-smoke 가 별도로 빌드한 wheel 을 검증하고 publish 는 재빌드한 wheel 을 올려 둘이 달라질 수 있었음.
publish.yml의build잡이python -m build직후 생성된 wheel 의 zip 목록과 격리 venv 설치 런타임을 직접 검증하도록 변경.
Added
tests/test_wheelPackaging.py(6 테스트):python -m build로 실제 wheel 을 빌드한 후 git-tracked 번들 리소스가 모두 zip 목록에 존재하는지 전수 대조. 핵심 JSON/parquet 개별 확인. 격리 venv 설치 후loadSections()런타임 체인까지 실행 (heavy 마커 — wheel-smoke job 에서 실행).publish.yml내부 검증 단계 2종: (1) 빌드 직후 wheel zip 에 필수 리소스 13건 포함 확인 (2) 격리 venv 에 방금 빌드된 wheel 설치 후loadSections()["chapterByMajor"]비어있지 않음 확인. 실패 시 PyPI 업로드 중단.
Changed
scripts/build/testWheelSmoke.sh빌드 도구 통일:uv build --wheel→python -m build로 변경해 publish.yml 과 동일 빌드 경로 사용. CI/publish 환경 간 wheel 차이 제거.
v0.9.16
Fixed
Company.sections접근 안정화:_SectionsSource.raw가 None 일 때.columns속성 접근으로 이어지지 않도록 명시적 가드 추가. 데이터가 비어있는 경우 None 을 그대로 반환.c.select(...).render("html")기간 컬럼 표시: HTML 렌더의 Console width 를 고정값(120) 대신 컬럼 수에 비례해 동적으로 계산. 기간 컬럼이 많은 재무제표에서도 모든 컬럼이 표시됨.c.facts속성 참조 수정:_profile_accessor에서 내부_report대신 존재하지 않는report를 참조하던 부분 교정.
Changed
- 필수 매핑 JSON 로더 — 조용한
{}대신 명시적 예외:parserMapper.loadSections/loadAffiliate/loadCostByNature,core/finance/labels._load_account_mappings,dart/edgar/edinet의sections/mapper.loadSectionMappings총 5개 로더가 번들 파일 부재 시FileNotFoundError와 함께 복구 명령(pip install -U --force-reinstall dartlab) 을 포함한 메시지를 발생. 기존에는 빈 dict 반환으로 상위 파이프라인이 원인 불명의 동작을 했음.
Added
tests/test_bundledResources.py(20 unit): 패키지에 포함돼야 하는 JSON/parquet 13건 존재 확인 + 핵심 키(chapterByMajor,detailTopicMap) 내용 계약 + 런타임 로더(loadSections,loadAffiliate,loadCostByNature,chapterFromMajorNum(1~9)) 반환값 검증. PR 마다 실행 (~3초).tests/realData/스위트: 엔진별 공개 API 를 parametrize 로 전수 iterate. Company 인스턴스 59 공개 속성, analysis 22 axis, scan 20 axis, credit 7 axis, macro 12 axis, gather 8 axis, 최상위 심볼 30+. 각 entry 가 독립 pytest 노드이므로 회귀 시 어떤 항목이 깨졌는지 즉시 특정.scripts/build/testWheelSmoke.sh: 현재 소스로 wheel 빌드 → 격리 venv 에 설치 → 번들 리소스 존재 +loadSections()["chapterByMajor"]런타임 비어있지 않음 검증.publish.yml의build잡이 이 스크립트 통과에 의존하도록 wire — wheel 이 비어있는 상태로 PyPI 에 올라가지 않도록 차단.scripts/dev/test-realdata.sh: realData 스위트를 파일별 독립 pytest 프로세스로 실행 (Polars 네이티브 메모리 격리 목적).- CI 잡 3종:
fixture-integration—test_fixture_*_real.py3건을 단일 worker 로 순차 실행 (메모리 격리)realdata-suite— realData 스위트 실행 (fixture 데이터 사용)wheel-smoke— 격리 venv wheel 설치 스모크
- pytest 마커 2종:
realData(엔진 공개 API 실데이터 스모크),freshInstall(cold 캐시 재현)
v0.9.15
Changed
- AI 분석 정확도 향상: AI 가 각 도구의 반환 구조(키, 타입, 단위)를 호출 전에 파악. 기존 런타임 에러 해소.
- 도구 설명 자동화: docstring Args/Returns → tool schema + 시스템 프롬프트 자동 반영. 새 함수 추가 시 docstring 만 작성하면 AI 즉시 인식.
- 내부 모듈 구조 정리: 중복 헬퍼 단일 출처화. memory/ → persistence/ 통합.
Removed
- 미사용 레퍼런스/실험 코드 삭제 (-49파일, -22,828줄)
- 미사용 모듈 삭제: fallback.py, readiness.py, EdgarCompany.reviewer()
Fixed
- AI 도구 호출 에러 수정 (pastInsight 빈 호출 crash, show scope/freq 혼동)
- 시스템 프롬프트 과잉 규제 제거 (숫자 강제 삭제, AI 자율 판단 복원)
- 중복 함수 통합 (_getFirst → safe.getFirst SSOT)
```bash
pip install dartlab==0.9.15
```
v0.9.13
Added
- P8 Tool Zero 응답 금지 (
ai/context/intent.py::classifyCategory): 질문을 META / FINANCE / OUT_OF_SCOPE 3범주로 분류. FINANCE 범주는 tool 최소 1회 호출 필수 (시스템 프롬프트 블록 +tool_choice="any"첫 라운드 API 강제 + 런타임 가드 3중 방어). META 는 tool 불필요 (CAPABILITIES 로 즉답), OUT_OF_SCOPE 는 "dartlab 전문 영역 아님" 명시 + 금융 질문 예시 제시 후 종료. dartlab 엔진 경유 없이 일반 ChatGPT 답변 생산 불가. - 매크로 톱다운 intent 분기 (
ai/runtime/core.py::_mandatoryForOutlook): "최근 경제 어때" 같은 시장 레벨 질문에서macro() + gather(axis='news')조합 강제. 수치 + 최근 이슈 교차 인과 해석. 이전act_all로 잘못 분류되어 일반론 답변되던 문제 해결. pastInsight(stockCode)/sectorInsights(sector)공개 API:dartlab.__all__에 노출 → AI tool 자동 등록 경로 (_autoDiscover) 진입. 사용자도dartlab.pastInsight("005930")직접 호출 가능.ai/context/intent.py::Categoryenum: META / FINANCE / OUT_OF_SCOPE 상위 범주. 기존 8 intent (act1~6 / compare / concept) 와 병렬.- provider
tool_choice파라미터:BaseProvider.complete_with_tools/stream_with_tools에tool_choice: str | None추가. "any"/"none"/"auto" 매핑. FINANCE 첫 라운드에만 "any" 강제 후 auto 로 환원.
Changed
ai/runtime/core.py::analyze→runAsk/_analyze_inner→_runAskInner. 구 "떠먹이기 시대" 이름 제거.dartlab.ask()진입점 단일 (P1) 을 내부 이름으로도 선언.analysis/financial/insight/pipeline.py::analyze→analyzeFinancial: AI 엔진runAsk와 이름 충돌 해소. 인사이트 엔진 코어 함수 의미 명확화.analyze는 호환 alias 로 1 릴리즈 유지.- AI tool 자동 등록 우선순위: module-level > Company-bound (이전 반대). 같은 이름 존재 시
dartlab.search(시장 전체) 가Company.search(이 회사 공시) 보다 AI tool 로 유용. Company-bound 는 module 에 없는 것만 등록. _splitKwargs자동 시그니처 추출: 기존_MODULE_CORE수동 whitelist (scan/macro/search/searchName) 제거.inspect.signature(fn)으로 자동 추출 → pastInsight/sectorInsights 포함 모든 module-level tool 일관 처리.Company.gather시그니처target: str | None = None명시: 이전**kwargs에 숨어 tool schema 누락. AI 가gather(axis='news', target='한국 경제')로 시장 레벨 뉴스 검색 가능해짐.- ops/ai.md P8 섹션 신설: 3범주 분류 + 3중 방어선 단일 출처.
Removed
ai/superfeature/폴더 전체 (480줄, 4파일) —getSuperMaster호출 0건 (내부 순환만). 완전 dead code.ai/runtime/standalone.py::analyze_full:list(analyze(...))래퍼, 사용처 0.ai/tools/_builtin.py: pastInsight/sectorInsights 수동 AITool 생성 파일._autoDiscover자동 경로로 일원화.review/presets.py:reportTypes.py로 통합된 deprecated re-export shim, import 0건.core/engines_DEV.md: dev 문서가 src 안에 있던 것.ai/runtime/standalone.py에서from dartlab.ai.runtime.core import analyze등 낡은 import 15곳 갱신 (CLI, stdio, server/streaming, scripts/audit, scripts/eval).
Fixed
- AI 가 매크로 질문에서 tool 0회 일반론 답변: v0.9.12 에서 "최근 경제 어때" 질문에
macro()호출 없이 학습 지식으로 답한 사고 — P8 3중 방어선으로 구조적 불가능화.dartlab.ask("최근 경제")재현 테스트: tool 3회 (macro summary + gather news × 2), CLI/M2/기준금리/공포탐욕/uncertainty 실측 수치 기반 답변 확인. Company.gathertarget파라미터 AI schema 누락:**kwargs에 숨어 AI 가 시장 레벨 뉴스 검색 인자 못 넣음. 시그니처 명시로 해결._builtin.py가_MODULE_CORE경로 밖이라 라이브 호출 시 stockCode 누락:_splitKwargs자동 시그니처로 근본 해결.
v0.9.12
Added
- 엔진 자가 의심 flags (
core/overrides.py::detectExtremeFlags): WACC>15%/<6%, Kd>12%, terminalGrowth>4%/≤0, debtRatio>200%, ICR<1.5, cycle contraction-trough 룰을 엔진이 자동 검사 →{flag, reason, suggestedRetry}리스트로 결과에 박음. AI 가 verbal 시뮬로 도망가지 않고 구체 JSON 복사 수준으로 override 재호출. - autoEnrich
[엔진가정]한 줄 자동 주입: 모든 tool_result_summary끝에[엔진가정] WACC=10.4% · g=3.0% · Kd=15.0% ...줄 자동 추가. flag 가 있으면⚠ {reason} → 다음 호출 실행 권장: overrides={"wacc":9.0}JSON 동봉. - 4엔진 결과 표준
assumptions필드: analysis (FORECAST + VALUATION + ANALYSIS) / credit / macro / quant 결과에 엔진이 쓴 가정값을 표준 키(wacc,terminalGrowth,debtRatio,cyclePhase등)로 통합. AI 가 흩어진discountRate/baseWacc/assumedWacc추측 불필요. pastInsight(stockCode)/sectorInsights(sector)AI tool: KnowledgeDB 경험 조회 — 블로그(검증 프리미엄) 우선, 없으면 AI 축적. 떠먹이기가 아니라 AI 자율 호출. 식품 업종 분석 시 불닭 OPM 21.8% 같은 과거 인사이트 자동 인용.- AI tool 자동 등록 (
_autoDiscover):dartlab.__all__+ Company_xxxImpl/ public method 자동 순회 + 블랙리스트. 수동_TOOLSdict 제거. quant 누락 해결, 새 엔진 추가 시 자동 등록. core/overrides.py확장:ANALYSIS_KEYS/QUANT_KEYS신설,CREDIT_KEYS/MACRO_KEYS확장 (currentRatio/quickRatio/ocfToDebt/scenarioStress, rateScenario/fxScenario 등).ENGINE_KEYSdict 으로 엔진별 허용 키 명시.describeOverrides(engine)— tool schema description 자동 생성./insights자동 인사이트 랭킹 페이지 (랜딩): 5종 랭킹 (집중도/분산/허브/다양성/의존도)./compare?a=X&b=Y2사 비교 페이지: 공급망/재무/AI verdict 나란히./industry/[id]공정 흐름 + 랭킹 + 공급망 엣지 페이지.- 회사 페이지 풀스택 (
/map/company/[code]): AI 인사이트 + 공급망 + 재무 + 블로그. - Cosmograph WebGL 산업 지도 (
/map): 살아있는 산업 생태계. - L3 Egograph 공급망 시각화: 회사별 공급망 그래프.
- 네이버 글로벌 API 도입 (gather): US 주가 Yahoo → Naver Global 전환, 호출 간 2~4초 강제 딜레이.
- 원재료 테이블 파싱: 실제 공급망 엣지 261건 추출, revenue 2,469사 join, edges/summary/timeline API.
- DART 데이터셋 자동 수집 구조 블로그: Actions 리듬 + HF 단일 소스 + 사용자 한 줄 경험.
- 블로그 #34 LG전자, #35 Under Armour.
- 빠른 품질 audit 스크립트 (
scripts/audit/quickQualityAudit.py): tool 다양성 + override 자발 호출 + pastInsight 활용 4 시나리오 검증.
Changed
- 모든 엔진
_Impl시그니처 통일 —overrides: dict | None = None명시. credit/quant/macro 추가 (이전엔 analysis 만 수용). - ops/ai.md 전면 재작성 (596줄 →
280줄): 4축 사상 + 7+1 원칙 (P1P7 + P4.5) + override 매커니즘 + 경험 자산화 순환 단일 출처. 메모리 (MEMORY.md, ai_identity.md) 는 포인터만. - 시스템 프롬프트 — override 재호출 예시 명확화, "verbal stress 금지, 반드시 overrides 인자로 재호출" 명시.
- macro 모듈 callable 패치 — import 순서 무관 callable 보장.
- Node.js 24 대응 — actions 메이저 버전 일괄 bump (checkout@v5, setup-python@v6, setup-node@v5, upload-artifact@v5, attest-build-provenance@v3).
- ruff format 92개 파일 적용.
Fixed
- CRITICAL:
memoized_calc가overrides를 silent drop — 모든 valuation/credit/quant calc 함수에서 override 가 캐시 래퍼에 의해 무음 무시되던 버그. 이제 override 가 실제 calc 함수에 전달되고, override 있을 때 캐시 우회. override 매커니즘이 이번 릴리즈부터 처음으로 실제 작동. calcDcfterminalGrowthRatevsterminalGrowth키명 오타 — innerdcfValuation()은terminalGrowth받는데 래퍼가terminalGrowthRate로 넘김 → TypeError silent swallow → DCF None 반환되던 버그.- analysis tool axis enum 누락 — docstring 파싱이 14 financial 축만 뽑아
가치평가/매출전망/매크로민감도등이 enum 에서 빠짐 → AI 가 호출 자체 불가._AXIS_REGISTRY전체 22축으로 교체. - 시스템 프롬프트
{{"wacc":9.0}}이중중괄호 — Python format string 흔적이 AI 에게 그대로 노출 → AI 가sub="{...}"에 JSON 문자열 욱여넣음. 깔끔한 JSON 예시 + "sub 에 절대 쑤셔 넣지 마라" 지시 추가. - EDGAR 전면 점검: stmt 분류 + STMT_OVERRIDES 확장, 한국어 100% 로드, analysis/valuation/credit RuntimeError catch, CI 항목 7개 IS→CI stmt 수정, EQ/NT canonStmt 필터, getAccountStmt alias 역참조, dividends_common_stock EQ 수정. 7종목 42케이스 전부 OK.
- EDGAR
show()항목 한국어 근본 개선 — standardAccounts korName 로딩 + Title Case fallback 제거. - review Section UnboundLocalError (pyodide 환경 순환 참조).
- landing basePath/handleHttpError: BASE_PATH prefix 고려, peer 링크 prerender 통과.
- map 필터 실시간 반영 + 회사명 라벨 + Cosmograph API 정정.
- kindlist 워크플로우 시크릿 이름 불일치 —
DART_API_KEYS에서 첫 키 추출. - 블로그 데이터셋 글 내부 링크 — slug 번호 없이.
Removed
- AI tool 수동
_TOOLSdict —_autoDiscover()자동 등록으로 대체. - 폐기 기능 유령 테스트 — sector 호환 partial source / 지주사 skip / repr 정리.