python-infrakit-dev 0.1.0__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.
- infrakit/__init__.py +0 -0
- infrakit/cli/__init__.py +1 -0
- infrakit/cli/commands/__init__.py +1 -0
- infrakit/cli/commands/deps.py +530 -0
- infrakit/cli/commands/init.py +129 -0
- infrakit/cli/commands/llm.py +295 -0
- infrakit/cli/commands/logger.py +160 -0
- infrakit/cli/commands/module.py +342 -0
- infrakit/cli/commands/time.py +81 -0
- infrakit/cli/main.py +65 -0
- infrakit/core/__init__.py +0 -0
- infrakit/core/config/__init__.py +0 -0
- infrakit/core/config/converter.py +480 -0
- infrakit/core/config/exporter.py +304 -0
- infrakit/core/config/loader.py +713 -0
- infrakit/core/config/validator.py +389 -0
- infrakit/core/logger/__init__.py +21 -0
- infrakit/core/logger/formatters.py +143 -0
- infrakit/core/logger/handlers.py +322 -0
- infrakit/core/logger/retention.py +176 -0
- infrakit/core/logger/setup.py +314 -0
- infrakit/deps/__init__.py +239 -0
- infrakit/deps/clean.py +141 -0
- infrakit/deps/depfile.py +405 -0
- infrakit/deps/health.py +357 -0
- infrakit/deps/optimizer.py +642 -0
- infrakit/deps/scanner.py +550 -0
- infrakit/llm/__init__.py +35 -0
- infrakit/llm/batch.py +165 -0
- infrakit/llm/client.py +575 -0
- infrakit/llm/key_manager.py +728 -0
- infrakit/llm/llm_readme.md +306 -0
- infrakit/llm/models.py +148 -0
- infrakit/llm/providers/__init__.py +5 -0
- infrakit/llm/providers/base.py +112 -0
- infrakit/llm/providers/gemini.py +164 -0
- infrakit/llm/providers/openai.py +168 -0
- infrakit/llm/rate_limiter.py +54 -0
- infrakit/scaffolder/__init__.py +31 -0
- infrakit/scaffolder/ai.py +508 -0
- infrakit/scaffolder/backend.py +555 -0
- infrakit/scaffolder/cli_tool.py +386 -0
- infrakit/scaffolder/generator.py +338 -0
- infrakit/scaffolder/pipeline.py +562 -0
- infrakit/scaffolder/registry.py +121 -0
- infrakit/time/__init__.py +60 -0
- infrakit/time/profiler.py +511 -0
- python_infrakit_dev-0.1.0.dist-info/METADATA +124 -0
- python_infrakit_dev-0.1.0.dist-info/RECORD +51 -0
- python_infrakit_dev-0.1.0.dist-info/WHEEL +4 -0
- python_infrakit_dev-0.1.0.dist-info/entry_points.txt +3 -0
infrakit/llm/batch.py
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"""
|
|
2
|
+
infrakit.llm.batch
|
|
3
|
+
------------------
|
|
4
|
+
Batch processing engine for multiple prompts.
|
|
5
|
+
|
|
6
|
+
Two modes (chosen at LLMClient init):
|
|
7
|
+
- async : asyncio with a semaphore-based concurrency cap
|
|
8
|
+
- threaded: concurrent.futures.ThreadPoolExecutor
|
|
9
|
+
|
|
10
|
+
Results are always returned in input order.
|
|
11
|
+
Progress bar via tqdm (optional — gracefully degrades if not installed).
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import asyncio
|
|
17
|
+
import time
|
|
18
|
+
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
19
|
+
from typing import Any, Callable, Optional, Type
|
|
20
|
+
|
|
21
|
+
from pydantic import BaseModel
|
|
22
|
+
|
|
23
|
+
from .models import BatchResult, LLMResponse, Prompt
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
from tqdm import tqdm as _tqdm
|
|
27
|
+
from tqdm.asyncio import tqdm as _async_tqdm
|
|
28
|
+
_HAS_TQDM = True
|
|
29
|
+
except ImportError:
|
|
30
|
+
_HAS_TQDM = False
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# ── async batch ────────────────────────────────────────────────────────────
|
|
34
|
+
|
|
35
|
+
async def async_batch(
|
|
36
|
+
generate_fn: Callable[..., Any], # LLMClient._async_single_generate
|
|
37
|
+
prompts: list[Prompt],
|
|
38
|
+
response_model: Optional[Type[BaseModel]],
|
|
39
|
+
schema_retries: int,
|
|
40
|
+
provider: str,
|
|
41
|
+
max_concurrent: int,
|
|
42
|
+
show_progress: bool,
|
|
43
|
+
extra_kwargs: dict,
|
|
44
|
+
) -> BatchResult:
|
|
45
|
+
"""
|
|
46
|
+
Run *generate_fn* over all prompts with bounded concurrency.
|
|
47
|
+
Returns results in the same order as prompts.
|
|
48
|
+
"""
|
|
49
|
+
semaphore = asyncio.Semaphore(max_concurrent)
|
|
50
|
+
results: list[Optional[LLMResponse]] = [None] * len(prompts)
|
|
51
|
+
|
|
52
|
+
async def _run(idx: int, prompt: Prompt) -> None:
|
|
53
|
+
async with semaphore:
|
|
54
|
+
try:
|
|
55
|
+
result = await generate_fn(
|
|
56
|
+
prompt=prompt,
|
|
57
|
+
response_model=response_model,
|
|
58
|
+
schema_retries=schema_retries,
|
|
59
|
+
provider=provider,
|
|
60
|
+
**extra_kwargs,
|
|
61
|
+
)
|
|
62
|
+
except Exception as exc:
|
|
63
|
+
result = _error_response(prompt, provider, str(exc))
|
|
64
|
+
results[idx] = result
|
|
65
|
+
|
|
66
|
+
tasks = [_run(i, p) for i, p in enumerate(prompts)]
|
|
67
|
+
|
|
68
|
+
if show_progress and _HAS_TQDM:
|
|
69
|
+
await _async_tqdm.gather(*tasks, desc="Batch", total=len(tasks), unit="prompt")
|
|
70
|
+
else:
|
|
71
|
+
if show_progress and not _HAS_TQDM:
|
|
72
|
+
print("[infrakit.llm] tqdm not installed — install it for progress bars.")
|
|
73
|
+
await asyncio.gather(*tasks)
|
|
74
|
+
|
|
75
|
+
return _aggregate(results)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
# ── threaded batch ─────────────────────────────────────────────────────────
|
|
79
|
+
|
|
80
|
+
def threaded_batch(
|
|
81
|
+
generate_fn: Callable[..., Any], # LLMClient._sync_single_generate
|
|
82
|
+
prompts: list[Prompt],
|
|
83
|
+
response_model: Optional[Type[BaseModel]],
|
|
84
|
+
schema_retries: int,
|
|
85
|
+
provider: str,
|
|
86
|
+
max_concurrent: int,
|
|
87
|
+
show_progress: bool,
|
|
88
|
+
extra_kwargs: dict,
|
|
89
|
+
) -> BatchResult:
|
|
90
|
+
"""
|
|
91
|
+
Run *generate_fn* over all prompts using a thread pool.
|
|
92
|
+
Returns results in the same order as prompts.
|
|
93
|
+
"""
|
|
94
|
+
results: list[Optional[LLMResponse]] = [None] * len(prompts)
|
|
95
|
+
futures_map: dict[Any, int] = {}
|
|
96
|
+
|
|
97
|
+
bar = None
|
|
98
|
+
if show_progress:
|
|
99
|
+
if _HAS_TQDM:
|
|
100
|
+
bar = _tqdm(total=len(prompts), desc="Batch", unit="prompt")
|
|
101
|
+
else:
|
|
102
|
+
print("[infrakit.llm] tqdm not installed — install it for progress bars.")
|
|
103
|
+
|
|
104
|
+
with ThreadPoolExecutor(max_workers=max_concurrent) as executor:
|
|
105
|
+
for idx, prompt in enumerate(prompts):
|
|
106
|
+
future = executor.submit(
|
|
107
|
+
generate_fn,
|
|
108
|
+
prompt=prompt,
|
|
109
|
+
response_model=response_model,
|
|
110
|
+
schema_retries=schema_retries,
|
|
111
|
+
provider=provider,
|
|
112
|
+
**extra_kwargs,
|
|
113
|
+
)
|
|
114
|
+
futures_map[future] = idx
|
|
115
|
+
|
|
116
|
+
for future in as_completed(futures_map):
|
|
117
|
+
idx = futures_map[future]
|
|
118
|
+
try:
|
|
119
|
+
results[idx] = future.result()
|
|
120
|
+
except Exception as exc:
|
|
121
|
+
results[idx] = _error_response(prompts[idx], provider, str(exc))
|
|
122
|
+
if bar:
|
|
123
|
+
bar.update(1)
|
|
124
|
+
|
|
125
|
+
if bar:
|
|
126
|
+
bar.close()
|
|
127
|
+
|
|
128
|
+
return _aggregate(results)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
# ── helpers ────────────────────────────────────────────────────────────────
|
|
132
|
+
|
|
133
|
+
def _error_response(prompt: Prompt, provider: str, error: str) -> LLMResponse:
|
|
134
|
+
return LLMResponse(
|
|
135
|
+
content="",
|
|
136
|
+
parsed=None,
|
|
137
|
+
schema_matched=False,
|
|
138
|
+
provider=provider,
|
|
139
|
+
model="",
|
|
140
|
+
key_id="",
|
|
141
|
+
input_tokens=0,
|
|
142
|
+
output_tokens=0,
|
|
143
|
+
total_tokens=0,
|
|
144
|
+
latency_ms=0.0,
|
|
145
|
+
error=error,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def _aggregate(results: list[Optional[LLMResponse]]) -> BatchResult:
|
|
150
|
+
total_in = sum(r.input_tokens for r in results if r)
|
|
151
|
+
total_out = sum(r.output_tokens for r in results if r)
|
|
152
|
+
total_tok = sum(r.total_tokens for r in results if r)
|
|
153
|
+
total_lat = sum(r.latency_ms for r in results if r)
|
|
154
|
+
success = sum(1 for r in results if r and not r.error)
|
|
155
|
+
failure = sum(1 for r in results if r and r.error)
|
|
156
|
+
|
|
157
|
+
return BatchResult(
|
|
158
|
+
results=results,
|
|
159
|
+
total_input_tokens=total_in,
|
|
160
|
+
total_output_tokens=total_out,
|
|
161
|
+
total_tokens=total_tok,
|
|
162
|
+
total_latency_ms=total_lat,
|
|
163
|
+
success_count=success,
|
|
164
|
+
failure_count=failure,
|
|
165
|
+
)
|