codegnipy 0.0.1__tar.gz → 0.0.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.
- {codegnipy-0.0.1 → codegnipy-0.0.2}/PKG-INFO +3 -1
- {codegnipy-0.0.1 → codegnipy-0.0.2}/codegnipy/__init__.py +35 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/codegnipy/cli.py +10 -6
- {codegnipy-0.0.1 → codegnipy-0.0.2}/codegnipy/determinism.py +11 -27
- codegnipy-0.0.2/codegnipy/observability.py +903 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/codegnipy/providers.py +349 -1
- {codegnipy-0.0.1 → codegnipy-0.0.2}/codegnipy/runtime.py +21 -6
- {codegnipy-0.0.1 → codegnipy-0.0.2}/codegnipy/scheduler.py +5 -5
- {codegnipy-0.0.1 → codegnipy-0.0.2}/codegnipy/validation.py +4 -2
- {codegnipy-0.0.1 → codegnipy-0.0.2}/codegnipy.egg-info/PKG-INFO +3 -1
- {codegnipy-0.0.1 → codegnipy-0.0.2}/codegnipy.egg-info/SOURCES.txt +4 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/codegnipy.egg-info/requires.txt +3 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/pyproject.toml +4 -1
- codegnipy-0.0.2/tests/test_observability.py +672 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/tests/test_providers.py +205 -0
- codegnipy-0.0.2/tests/test_reflection.py +286 -0
- codegnipy-0.0.2/tests/test_runtime.py +247 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/LICENSE +0 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/README.md +0 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/codegnipy/decorator.py +0 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/codegnipy/memory.py +0 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/codegnipy/reflection.py +0 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/codegnipy/streaming.py +0 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/codegnipy/tools.py +0 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/codegnipy/transformer.py +0 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/codegnipy.egg-info/dependency_links.txt +0 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/codegnipy.egg-info/entry_points.txt +0 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/codegnipy.egg-info/top_level.txt +0 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/setup.cfg +0 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/tests/test_determinism.py +0 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/tests/test_memory.py +0 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/tests/test_scheduler.py +0 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/tests/test_streaming.py +0 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/tests/test_tools.py +0 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/tests/test_transformer.py +0 -0
- {codegnipy-0.0.1 → codegnipy-0.0.2}/tests/test_validation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codegnipy
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.2
|
|
4
4
|
Summary: AI 原生的 Python 语言扩展 - 让非确定性 AI 成为 Python 一等公民
|
|
5
5
|
Author: Codegnipy Team
|
|
6
6
|
License: MIT
|
|
@@ -27,6 +27,8 @@ Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
|
27
27
|
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
28
28
|
Provides-Extra: anthropic
|
|
29
29
|
Requires-Dist: anthropic>=0.18.0; extra == "anthropic"
|
|
30
|
+
Provides-Extra: http
|
|
31
|
+
Requires-Dist: aiohttp>=3.8.0; extra == "http"
|
|
30
32
|
Dynamic: license-file
|
|
31
33
|
|
|
32
34
|
# Codegnipy
|
|
@@ -88,6 +88,8 @@ from .providers import (
|
|
|
88
88
|
AnthropicProvider,
|
|
89
89
|
OllamaProvider,
|
|
90
90
|
TransformersProvider,
|
|
91
|
+
LlamaCppProvider,
|
|
92
|
+
QuantizationConfig,
|
|
91
93
|
ProviderFactory,
|
|
92
94
|
create_provider
|
|
93
95
|
)
|
|
@@ -104,6 +106,22 @@ from .validation import (
|
|
|
104
106
|
verify_claim,
|
|
105
107
|
verify_claim_async
|
|
106
108
|
)
|
|
109
|
+
from .observability import (
|
|
110
|
+
LogLevel,
|
|
111
|
+
MetricType,
|
|
112
|
+
SpanContext,
|
|
113
|
+
Metric,
|
|
114
|
+
CognitiveLogger,
|
|
115
|
+
MetricsCollector,
|
|
116
|
+
Tracer,
|
|
117
|
+
OpenTelemetryExporter,
|
|
118
|
+
ObservabilityManager,
|
|
119
|
+
traced,
|
|
120
|
+
logged,
|
|
121
|
+
metered,
|
|
122
|
+
get_default_manager,
|
|
123
|
+
configure_observability,
|
|
124
|
+
)
|
|
107
125
|
|
|
108
126
|
__all__ = [
|
|
109
127
|
# Core
|
|
@@ -173,6 +191,8 @@ __all__ = [
|
|
|
173
191
|
"AnthropicProvider",
|
|
174
192
|
"OllamaProvider",
|
|
175
193
|
"TransformersProvider",
|
|
194
|
+
"LlamaCppProvider",
|
|
195
|
+
"QuantizationConfig",
|
|
176
196
|
"ProviderFactory",
|
|
177
197
|
"create_provider",
|
|
178
198
|
# Validation
|
|
@@ -187,4 +207,19 @@ __all__ = [
|
|
|
187
207
|
"create_default_validator",
|
|
188
208
|
"verify_claim",
|
|
189
209
|
"verify_claim_async",
|
|
210
|
+
# Observability
|
|
211
|
+
"LogLevel",
|
|
212
|
+
"MetricType",
|
|
213
|
+
"SpanContext",
|
|
214
|
+
"Metric",
|
|
215
|
+
"CognitiveLogger",
|
|
216
|
+
"MetricsCollector",
|
|
217
|
+
"Tracer",
|
|
218
|
+
"OpenTelemetryExporter",
|
|
219
|
+
"ObservabilityManager",
|
|
220
|
+
"traced",
|
|
221
|
+
"logged",
|
|
222
|
+
"metered",
|
|
223
|
+
"get_default_manager",
|
|
224
|
+
"configure_observability",
|
|
190
225
|
]
|
|
@@ -43,6 +43,10 @@ def create_parser() -> argparse.ArgumentParser:
|
|
|
43
43
|
default="gpt-4o-mini",
|
|
44
44
|
help="使用的 LLM 模型"
|
|
45
45
|
)
|
|
46
|
+
repl_parser.add_argument(
|
|
47
|
+
"--api-key", "-k",
|
|
48
|
+
help="API 密钥(也可通过环境变量 OPENAI_API_KEY 设置)"
|
|
49
|
+
)
|
|
46
50
|
|
|
47
51
|
# version 命令
|
|
48
52
|
subparsers.add_parser("version", help="显示版本信息")
|
|
@@ -86,17 +90,17 @@ def run_file(filepath: str, model: str, api_key: Optional[str] = None):
|
|
|
86
90
|
sys.exit(1)
|
|
87
91
|
|
|
88
92
|
|
|
89
|
-
def start_repl(model: str):
|
|
93
|
+
def start_repl(model: str, api_key: Optional[str] = None):
|
|
90
94
|
"""启动交互式 REPL"""
|
|
91
95
|
import code
|
|
92
|
-
|
|
96
|
+
|
|
93
97
|
print("Codegnipy REPL")
|
|
94
98
|
print(f"模型: {model}")
|
|
95
99
|
print("输入 Python 代码,~\"prompt\" 语法将调用 LLM")
|
|
96
100
|
print("输入 exit() 或 Ctrl+D 退出\n")
|
|
97
|
-
|
|
101
|
+
|
|
98
102
|
# 创建上下文
|
|
99
|
-
ctx = CognitiveContext(model=model)
|
|
103
|
+
ctx = CognitiveContext(model=model, api_key=api_key)
|
|
100
104
|
ctx.__enter__()
|
|
101
105
|
|
|
102
106
|
# 准备 REPL 环境
|
|
@@ -137,11 +141,11 @@ def main():
|
|
|
137
141
|
"""主入口"""
|
|
138
142
|
parser = create_parser()
|
|
139
143
|
args = parser.parse_args()
|
|
140
|
-
|
|
144
|
+
|
|
141
145
|
if args.command == "run":
|
|
142
146
|
run_file(args.file, args.model, args.api_key)
|
|
143
147
|
elif args.command == "repl":
|
|
144
|
-
start_repl(args.model)
|
|
148
|
+
start_repl(args.model, getattr(args, 'api_key', None))
|
|
145
149
|
elif args.command == "version":
|
|
146
150
|
print(f"Codegnipy v{codegnipy.__version__}")
|
|
147
151
|
else:
|
|
@@ -558,54 +558,34 @@ class HallucinationDetector:
|
|
|
558
558
|
# ============ 确定性认知调用 ============
|
|
559
559
|
|
|
560
560
|
def deterministic_call(
|
|
561
|
-
|
|
562
561
|
prompt: str,
|
|
563
|
-
|
|
564
562
|
constraint: TypeConstraint,
|
|
565
|
-
|
|
566
563
|
context: Optional["CognitiveContext"] = None,
|
|
567
|
-
|
|
568
564
|
*,
|
|
569
|
-
|
|
570
565
|
max_attempts: int = 3,
|
|
571
|
-
|
|
572
566
|
use_reflection: bool = False,
|
|
573
|
-
|
|
574
567
|
simulator: Optional[Simulator] = None
|
|
575
|
-
|
|
576
568
|
) -> ValidationResult:
|
|
577
|
-
|
|
578
569
|
"""
|
|
579
|
-
|
|
580
570
|
带类型约束的确定性认知调用
|
|
581
571
|
|
|
582
|
-
|
|
583
|
-
|
|
584
572
|
参数:
|
|
585
|
-
|
|
586
573
|
prompt: 提示文本
|
|
587
|
-
|
|
588
574
|
constraint: 类型约束
|
|
589
|
-
|
|
590
575
|
context: 认知上下文
|
|
591
|
-
|
|
592
576
|
max_attempts: 最大尝试次数
|
|
593
|
-
|
|
594
577
|
use_reflection: 是否使用反思
|
|
595
|
-
|
|
596
578
|
simulator: 模拟器(用于测试)
|
|
597
579
|
|
|
598
580
|
返回:
|
|
599
|
-
|
|
600
581
|
ValidationResult 对象
|
|
601
|
-
|
|
602
582
|
"""
|
|
603
583
|
from .runtime import cognitive_call
|
|
604
584
|
from .reflection import with_reflection
|
|
605
|
-
|
|
585
|
+
|
|
606
586
|
# 构建带约束的提示
|
|
607
587
|
constrained_prompt = f"{prompt}\n\n约束: {constraint.to_prompt()}\n\n请严格按照约束要求回答。"
|
|
608
|
-
|
|
588
|
+
|
|
609
589
|
for attempt in range(max_attempts):
|
|
610
590
|
# 获取响应
|
|
611
591
|
if simulator and simulator.mode != SimulationMode.OFF:
|
|
@@ -616,16 +596,20 @@ def deterministic_call(
|
|
|
616
596
|
response = result.corrected_response or result.original_response
|
|
617
597
|
else:
|
|
618
598
|
response = cognitive_call(constrained_prompt, context)
|
|
619
|
-
|
|
599
|
+
|
|
620
600
|
# 验证响应
|
|
621
601
|
validation = constraint.validate(response)
|
|
622
|
-
|
|
602
|
+
|
|
623
603
|
if validation.status == ValidationStatus.VALID:
|
|
624
604
|
return validation
|
|
625
|
-
|
|
605
|
+
|
|
626
606
|
# 如果验证失败,添加反馈并重试
|
|
627
607
|
if attempt < max_attempts - 1:
|
|
628
608
|
error_feedback = "; ".join(validation.errors)
|
|
629
|
-
constrained_prompt =
|
|
630
|
-
|
|
609
|
+
constrained_prompt = (
|
|
610
|
+
f"{prompt}\n\n约束: {constraint.to_prompt()}\n\n"
|
|
611
|
+
f"上次的回答不符合要求,错误: {error_feedback}\n\n"
|
|
612
|
+
f"请修正后重新回答。"
|
|
613
|
+
)
|
|
614
|
+
|
|
631
615
|
return validation
|