Skip to content

Commit 62f911c

Browse files
author
ChidcGithub
committed
Fix mypy type errors across all modules
- Add Optional type annotations for parameters with None defaults - Fix union-attr errors with assertions after initialization - Fix attr-defined errors with type: ignore comments - Rename ToolParameter.type to param_type to avoid shadowing builtin - Fix return value type for optional content fields - Fix indentation issues in reflection.py and determinism.py - Update tests to use renamed param_type field All 103 tests passing.
1 parent bc10c7a commit 62f911c

File tree

11 files changed

+222
-198
lines changed

11 files changed

+222
-198
lines changed

cognipy/cli.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import argparse
88
import sys
99
from pathlib import Path
10+
from typing import Optional
1011

1112
from .transformer import transform_code
1213
from .runtime import CognitiveContext
@@ -49,7 +50,7 @@ def create_parser() -> argparse.ArgumentParser:
4950
return parser
5051

5152

52-
def run_file(filepath: str, model: str, api_key: str = None):
53+
def run_file(filepath: str, model: str, api_key: Optional[str] = None):
5354
"""运行 CogniPy 文件"""
5455
path = Path(filepath)
5556

cognipy/decorator.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,23 @@
1111
from .runtime import cognitive_call
1212

1313

14-
def cognitive(func: Callable = None, *, model: Optional[str] = None) -> Callable:
14+
def cognitive(func: Optional[Callable] = None, *, model: Optional[str] = None) -> Callable:
1515
"""
1616
Decorator: Mark a function as cognitive, implemented by LLM.
17-
17+
1818
The function's docstring serves as prompt template,
1919
and the signature is used for input validation and output parsing.
20-
20+
2121
Args:
2222
func: The function to decorate
2323
model: Specify the model to use (optional)
24-
24+
2525
Examples:
2626
@cognitive
2727
def summarize(text: str) -> str:
2828
'''Summarize the key points of this text in no more than 3 sentences.'''
2929
pass
30-
30+
3131
@cognitive(model="gpt-4")
3232
def translate(text: str, target_lang: str = "English") -> str:
3333
'''Translate the text to {target_lang}.'''
@@ -38,30 +38,30 @@ def decorator(fn: Callable) -> Callable:
3838
sig = inspect.signature(fn)
3939
hints = get_type_hints(fn) if hasattr(fn, '__annotations__') else {}
4040
docstring = fn.__doc__ or f"执行函数 {fn.__name__}"
41-
41+
4242
@wraps(fn)
4343
def wrapper(*args, **kwargs):
4444
# 绑定参数
4545
bound = sig.bind(*args, **kwargs)
4646
bound.apply_defaults()
47-
47+
4848
# 构建提示
4949
prompt = _build_prompt(docstring, bound.arguments)
50-
50+
5151
# 调用 LLM
5252
result = cognitive_call(prompt, model=model)
53-
53+
5454
# 类型转换(如果指定了返回类型)
5555
return_type = hints.get('return')
5656
if return_type and return_type is not str:
5757
result = _convert_result(result, return_type)
58-
58+
5959
return result
60-
60+
6161
# 标记为认知函数
62-
wrapper._is_cognitive = True
63-
wrapper._original_func = fn
64-
62+
wrapper._is_cognitive = True # type: ignore[attr-defined]
63+
wrapper._original_func = fn # type: ignore[attr-defined]
64+
6565
return wrapper
6666

6767
# 支持 @cognitive 和 @cognitive(...) 两种用法

cognipy/determinism.py

Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from dataclasses import dataclass, field
1111
from enum import Enum
1212
from typing import (
13-
Any, List, Dict, Type, TypeVar, TYPE_CHECKING
13+
Any, List, Dict, Type, TypeVar, Optional, TYPE_CHECKING
1414
)
1515
from pydantic import BaseModel, ValidationError as PydanticValidationError
1616

@@ -72,11 +72,11 @@ def __init__(self, expected_type: Type, min_value=None, max_value=None,
7272
self.min_length = min_length
7373
self.max_length = max_length
7474
self.pattern = pattern
75-
75+
7676
def validate(self, value: Any) -> ValidationResult:
77-
errors = []
78-
warnings = []
79-
77+
errors: List[str] = []
78+
warnings: List[str] = []
79+
8080
# 类型检查
8181
if not isinstance(value, self.expected_type):
8282
# 尝试类型转换
@@ -222,16 +222,16 @@ def to_prompt(self) -> str:
222222

223223
class ListConstraint(TypeConstraint):
224224
"""列表约束"""
225-
226-
def __init__(self, item_constraint: TypeConstraint = None, min_length=None, max_length=None):
225+
226+
def __init__(self, item_constraint: Optional[TypeConstraint] = None, min_length=None, max_length=None):
227227
self.item_constraint = item_constraint
228228
self.min_length = min_length
229229
self.max_length = max_length
230-
230+
231231
def validate(self, value: Any) -> ValidationResult:
232-
errors = []
233-
warnings = []
234-
232+
errors: List[str] = []
233+
warnings: List[str] = []
234+
235235
# 解析 JSON 字符串
236236
if isinstance(value, str):
237237
try:
@@ -290,7 +290,7 @@ class MockResponse:
290290
"""模拟响应"""
291291
prompt: str
292292
response: str
293-
metadata: Dict[str, Any] = field(default_factory=dict)
293+
metadata: Optional[Dict[str, Any]] = field(default_factory=dict)
294294

295295

296296
class Simulator:
@@ -345,7 +345,7 @@ def _get_replay_response(self, prompt: str) -> str:
345345

346346
raise ValueError(f"未找到匹配的回放响应: {prompt[:50]}...")
347347

348-
def record(self, prompt: str, response: str, metadata: Dict[str, Any] = None):
348+
def record(self, prompt: str, response: str, metadata: Optional[Dict[str, Any]] = None):
349349
"""记录响应"""
350350
self._recordings.append(MockResponse(
351351
prompt=prompt,
@@ -387,10 +387,10 @@ class HallucinationCheck:
387387
class HallucinationDetector:
388388
"""
389389
幻觉检测器
390-
390+
391391
检测 LLM 输出中可能存在的幻觉内容。
392392
"""
393-
393+
394394
def __init__(self):
395395
self._patterns = [
396396
# 常见幻觉模式
@@ -400,56 +400,55 @@ def __init__(self):
400400
(r'研究表明|研究显示|据统计', "未引用具体来源的声明"),
401401
(r'众所周知|显然|毫无疑问', "可能缺乏证据支持的断言"),
402402
]
403-
404-
def check(self, response: str, context: Dict[str, Any] = None) -> HallucinationCheck:
403+
404+
def check(self, response: str, context: Optional[Dict[str, Any]] = None) -> HallucinationCheck:
405405
"""
406406
检查响应中的幻觉
407-
407+
408408
参数:
409409
response: LLM 响应文本
410410
context: 可选的上下文信息
411-
412411
返回:
413412
HallucinationCheck 对象
414413
"""
415-
reasons = []
416-
suggestions = []
414+
reasons: List[str] = []
415+
suggestions: List[str] = []
417416
hallucination_score = 0.0
418-
417+
419418
# 模式检查
420419
for pattern, description in self._patterns:
421420
matches = re.findall(pattern, response)
422421
if matches:
423422
reasons.append(f"{description}: 发现 {len(matches)} 处")
424423
hallucination_score += 0.2 * len(matches)
425-
424+
426425
# 数值一致性检查
427426
numbers = re.findall(r'\b\d+(?:\.\d+)?\b', response)
428427
if len(numbers) > 5:
429428
reasons.append("包含大量数字,请验证准确性")
430429
hallucination_score += 0.1
431-
430+
432431
# 引用检查
433432
if '引用' in response or '参考' in response:
434433
if not re.search(r'\[\d+\]|\(\d{4}\)|"([^"]+)"', response):
435434
reasons.append("提到引用但未提供具体引用格式")
436435
hallucination_score += 0.15
437-
436+
438437
# 计算置信度
439438
confidence = min(hallucination_score, 1.0)
440439
is_hallucination = confidence > 0.3
441-
440+
442441
if is_hallucination:
443442
suggestions.append("建议验证响应中的具体细节")
444443
suggestions.append("考虑使用反思循环进行二次确认")
445-
444+
446445
return HallucinationCheck(
447446
is_hallucination=is_hallucination,
448447
confidence=confidence,
449448
reasons=reasons,
450449
suggestions=suggestions
451450
)
452-
451+
453452
def add_pattern(self, pattern: str, description: str):
454453
"""添加自定义幻觉检测模式"""
455454
self._patterns.append((pattern, description))
@@ -458,27 +457,47 @@ def add_pattern(self, pattern: str, description: str):
458457
# ============ 确定性认知调用 ============
459458

460459
def deterministic_call(
460+
461461
prompt: str,
462+
462463
constraint: TypeConstraint,
463-
context: "CognitiveContext" = None,
464+
465+
context: Optional["CognitiveContext"] = None,
466+
464467
*,
468+
465469
max_attempts: int = 3,
470+
466471
use_reflection: bool = False,
467-
simulator: Simulator = None
472+
473+
simulator: Optional[Simulator] = None
474+
468475
) -> ValidationResult:
476+
469477
"""
478+
470479
带类型约束的确定性认知调用
471-
480+
481+
482+
472483
参数:
484+
473485
prompt: 提示文本
486+
474487
constraint: 类型约束
488+
475489
context: 认知上下文
490+
476491
max_attempts: 最大尝试次数
492+
477493
use_reflection: 是否使用反思
494+
478495
simulator: 模拟器(用于测试)
479-
496+
480497
返回:
498+
481499
ValidationResult 对象
500+
482501
"""
483502
from .runtime import cognitive_call
484503
from .reflection import with_reflection

cognipy/providers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ async def call_async(
6666
pass
6767

6868
@abstractmethod
69-
async def stream_async(
69+
def stream_async(
7070
self,
7171
messages: List[Dict[str, str]],
7272
**kwargs

0 commit comments

Comments
 (0)