teragent 0.0.1__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.
Files changed (102) hide show
  1. teragent/__init__.py +794 -0
  2. teragent/agent_loop.py +1065 -0
  3. teragent/config/__init__.py +151 -0
  4. teragent/config/agent_loop_config.py +221 -0
  5. teragent/config/api_key_security.py +751 -0
  6. teragent/config/circuit_breaker_config.py +102 -0
  7. teragent/config/context_management_config.py +44 -0
  8. teragent/config/coordination_config.py +36 -0
  9. teragent/config/driver_config.py +114 -0
  10. teragent/config/execution_pipeline_config.py +45 -0
  11. teragent/config/file_safety_config.py +32 -0
  12. teragent/config/hooks_config.py +55 -0
  13. teragent/config/loader.py +616 -0
  14. teragent/config/model_fallback_config.py +32 -0
  15. teragent/config/permission_config.py +57 -0
  16. teragent/config/recovery_config.py +32 -0
  17. teragent/config/session_config.py +36 -0
  18. teragent/config/streaming_config.py +32 -0
  19. teragent/config/teragent_config.py +454 -0
  20. teragent/config/tools_config.py +40 -0
  21. teragent/context/__init__.py +109 -0
  22. teragent/context/auto_compact.py +313 -0
  23. teragent/context/code_indexer.py +831 -0
  24. teragent/context/context_window.py +187 -0
  25. teragent/context/dependency_reporter.py +156 -0
  26. teragent/context/memory.py +126 -0
  27. teragent/context/microcompactor.py +279 -0
  28. teragent/context/reference_graph.py +204 -0
  29. teragent/context/vector_indexer.py +209 -0
  30. teragent/coordination/__init__.py +27 -0
  31. teragent/coordination/message_bus.py +301 -0
  32. teragent/coordination/sub_agent_manager.py +720 -0
  33. teragent/core/__init__.py +19 -0
  34. teragent/core/adapter.py +138 -0
  35. teragent/core/adapters/__init__.py +32 -0
  36. teragent/core/adapters/anthropic_native.py +656 -0
  37. teragent/core/adapters/mock.py +222 -0
  38. teragent/core/adapters/openai_compatible.py +519 -0
  39. teragent/core/compiler.py +218 -0
  40. teragent/core/compilers/__init__.py +32 -0
  41. teragent/core/compilers/anthropic.py +75 -0
  42. teragent/core/compilers/deepseek.py +75 -0
  43. teragent/core/compilers/default.py +57 -0
  44. teragent/core/compilers/glm.py +122 -0
  45. teragent/core/prompts/__init__.py +174 -0
  46. teragent/core/prompts/chat.py +135 -0
  47. teragent/core/prompts/design.py +102 -0
  48. teragent/core/prompts/execute.py +18 -0
  49. teragent/core/prompts/plan.py +131 -0
  50. teragent/core/prompts/review.py +86 -0
  51. teragent/core/prompts/sub_agent.py +41 -0
  52. teragent/core/provider.py +402 -0
  53. teragent/core/tap.py +170 -0
  54. teragent/core/types.py +462 -0
  55. teragent/event_bus.py +352 -0
  56. teragent/hooks/__init__.py +56 -0
  57. teragent/hooks/builtin/__init__.py +14 -0
  58. teragent/hooks/builtin/audit_hook.py +184 -0
  59. teragent/hooks/builtin/dangerous_command_hook.py +226 -0
  60. teragent/hooks/manager.py +607 -0
  61. teragent/intent/__init__.py +15 -0
  62. teragent/intent/classifier.py +240 -0
  63. teragent/intent/confirmation.py +205 -0
  64. teragent/pipeline/__init__.py +26 -0
  65. teragent/pipeline/checklist.py +411 -0
  66. teragent/pipeline/extractor.py +206 -0
  67. teragent/pipeline/prompt_builder.py +168 -0
  68. teragent/pipeline/retry.py +75 -0
  69. teragent/pipeline/subagent_worker.py +349 -0
  70. teragent/pipeline/tracing.py +1026 -0
  71. teragent/py.typed +0 -0
  72. teragent/reliability/__init__.py +56 -0
  73. teragent/reliability/budget.py +70 -0
  74. teragent/reliability/circuit_breaker.py +1175 -0
  75. teragent/reliability/recovery.py +371 -0
  76. teragent/security/__init__.py +37 -0
  77. teragent/security/ai_permission_classifier.py +746 -0
  78. teragent/security/audit.py +413 -0
  79. teragent/security/file_state.py +504 -0
  80. teragent/security/file_writer.py +413 -0
  81. teragent/security/firecracker_sandbox.py +279 -0
  82. teragent/security/permission.py +982 -0
  83. teragent/security/sandbox.py +567 -0
  84. teragent/session/__init__.py +31 -0
  85. teragent/session/persistence.py +715 -0
  86. teragent/streaming/__init__.py +37 -0
  87. teragent/streaming/stream_events.py +594 -0
  88. teragent/streaming/streaming_executor.py +539 -0
  89. teragent/tools/__init__.py +24 -0
  90. teragent/tools/base.py +272 -0
  91. teragent/tools/orchestrator.py +416 -0
  92. teragent/tools/registry.py +238 -0
  93. teragent/utils/__init__.py +14 -0
  94. teragent/utils/exceptions.py +52 -0
  95. teragent/utils/text.py +46 -0
  96. teragent/utils/token_counter.py +117 -0
  97. teragent/utils/tracing.py +183 -0
  98. teragent-0.0.1.dist-info/METADATA +40 -0
  99. teragent-0.0.1.dist-info/RECORD +102 -0
  100. teragent-0.0.1.dist-info/WHEEL +5 -0
  101. teragent-0.0.1.dist-info/licenses/LICENSE +201 -0
  102. teragent-0.0.1.dist-info/top_level.txt +1 -0
teragent/__init__.py ADDED
@@ -0,0 +1,794 @@
1
+ """teragent — Terminal AI Agent Library
2
+
3
+ TAP IR + Model-Specific Compilation — Apache-2.0 Licensed
4
+
5
+ Quick start:
6
+ import teragent
7
+
8
+ # Method 1: Create a provider from DriverConfig (recommended)
9
+ from teragent.config import DriverConfig
10
+ driver_cfg = DriverConfig(
11
+ adapter="openai_compatible",
12
+ identity="glm",
13
+ base_url="https://open.bigmodel.cn/api/paas/v4",
14
+ api_key_env="GLM_API_KEY",
15
+ model="glm-5.1",
16
+ compiler="glm",
17
+ )
18
+ provider = teragent.create_provider_from_config(driver_cfg)
19
+
20
+ # Method 2: Create a provider manually (Compiler + Adapter auto-combined)
21
+ provider = teragent.create_provider(
22
+ compiler="glm",
23
+ adapter="openai_compatible",
24
+ model="glm-5.1",
25
+ base_url="https://open.bigmodel.cn/api/paas/v4",
26
+ api_key_env="GLM_API_KEY",
27
+ )
28
+
29
+ # Method 3: Load from config file
30
+ full_config = teragent.load_full_config()
31
+ drivers = full_config["drivers"]
32
+ provider = teragent.create_provider_from_config(drivers["openai_compatible.glm"])
33
+
34
+ # Execute a TAP request
35
+ response = await provider.execute_tap(teragent.TAPRequest(
36
+ meta={"task_id": "1.1", "intent": "code_generation"},
37
+ instruction="实现用户登录模块",
38
+ constraints=["Python 3.10+"],
39
+ output_format_hint="<file path='...'>完整代码</file>",
40
+ ))
41
+
42
+ # Extract files from response
43
+ files = teragent.extract_files_from_response(response.raw_text, task_id="1.1")
44
+
45
+ # Run deterministic code checks
46
+ task_list = [teragent.TaskInfo(id="1.1", title="Login module", status="completed")]
47
+ report, data = teragent.run_deterministic_checks("/project", task_list)
48
+
49
+ # Build prompt with custom template
50
+ messages = teragent.build_prompt(
51
+ system_template="You are {role}. Task: {task}",
52
+ context={"role": "engineer", "task": "implement login"},
53
+ )
54
+
55
+ # Retry with exponential backoff
56
+ result = await teragent.retry_with_backoff(
57
+ fn=lambda: provider.chat(messages=[...]),
58
+ max_retries=3,
59
+ validate=lambda r: [] if r else ["empty response"],
60
+ )
61
+
62
+ # Self-RL data constitution — TAP tracing + DPO pairs
63
+ tracer = teragent.TAPTracer(trace_dir="/project/.agent/traces")
64
+ provider.set_tracer(tracer) # Auto-trace all TAP calls
65
+
66
+ # After running deterministic checks, record the result
67
+ await tracer.record_checklist("1.1", checklist_data)
68
+
69
+ # Export DPO preference pairs for fine-tuning
70
+ pairs = tracer.export_dpo_pairs()
71
+ tracer.export_dpo_pairs_jsonl() # Write to file
72
+
73
+ Optional dependencies:
74
+ Some components require extra packages that are not installed by default.
75
+ Install them with pip extras:
76
+
77
+ - teragent[vector] — VectorIndexer (LanceDB + numpy)
78
+ - teragent[ast] — CodeIndexer (tree-sitter)
79
+ - teragent[graph] — ReferenceGraph (networkx)
80
+ - teragent[all] — All optional dependencies
81
+
82
+ These components are lazily imported and will raise ImportError only
83
+ when actually used without the corresponding extra installed.
84
+ """
85
+
86
+ from __future__ import annotations
87
+
88
+ import logging
89
+ from typing import Any
90
+
91
+ logger = logging.getLogger(__name__)
92
+
93
+ # ============================================================================
94
+ # Core data types
95
+ # ============================================================================
96
+
97
+ from teragent.core.tap import TAPRequest, TAPResponse, TAPCostRecord, CompiledPrompt
98
+
99
+ # Compiler ABC + Registry
100
+ from teragent.core.compiler import TAPCompiler, TAPCompilerRegistry
101
+
102
+ # Adapter ABC + Registry
103
+ from teragent.core.adapter import TAPAdapter, TAPAdapterRegistry
104
+
105
+ # ModelProvider (Compiler + Adapter composition)
106
+ from teragent.core.provider import ModelProvider
107
+
108
+ # Core types
109
+ from teragent.core.types import ToolSafety
110
+ from teragent.core.types import Message, MessageRole, MessageType, messages_to_api_format, messages_from_dicts
111
+
112
+ # ============================================================================
113
+ # Config layer
114
+ # ============================================================================
115
+
116
+ from teragent.config.driver_config import DriverConfig
117
+ from teragent.config.loader import (
118
+ load_driver_configs,
119
+ load_pipeline_config,
120
+ load_full_config,
121
+ create_provider_from_config,
122
+ get_driver_config,
123
+ resolve_api_key,
124
+ resolve_api_key_detailed,
125
+ infer_compiler,
126
+ load_typed_config,
127
+ audit_config_security,
128
+ )
129
+
130
+ # API Key security
131
+ from teragent.config.api_key_security import (
132
+ ApiKeyVault,
133
+ ResolvedKey,
134
+ SecurityFinding,
135
+ SecuritySeverity,
136
+ SecurityError,
137
+ mask_api_key,
138
+ detect_api_key_provider,
139
+ audit_config_security as audit_api_key_security,
140
+ audit_env_file,
141
+ get_vault,
142
+ )
143
+
144
+ # Typed configuration dataclasses
145
+ from teragent.config.teragent_config import TerAgentConfig, AgentdSectionConfig
146
+ from teragent.config.agent_loop_config import AgentLoopConfig
147
+ from teragent.config.circuit_breaker_config import (
148
+ CircuitBreakerConfig,
149
+ BudgetConfig,
150
+ FailureBreakerConfig,
151
+ LatencyBreakerConfig,
152
+ ProgressDetectorConfig,
153
+ )
154
+ from teragent.config.context_management_config import ContextManagementConfig
155
+ from teragent.config.tools_config import ToolsConfig
156
+ from teragent.config.file_safety_config import FileSafetyConfig
157
+ from teragent.config.session_config import SessionConfig
158
+ from teragent.config.permission_config import PermissionConfig
159
+ from teragent.config.hooks_config import HooksConfig
160
+ from teragent.config.recovery_config import RecoveryConfig
161
+ from teragent.config.streaming_config import StreamingConfig
162
+ from teragent.config.coordination_config import CoordinationConfig
163
+ from teragent.config.execution_pipeline_config import ExecutionPipelineConfig
164
+ from teragent.config.model_fallback_config import ModelFallbackConfig
165
+
166
+ # ============================================================================
167
+ # Pipeline primitives
168
+ # ============================================================================
169
+
170
+ from teragent.pipeline.extractor import extract_files_from_response
171
+ from teragent.pipeline.prompt_builder import (
172
+ build_prompt,
173
+ build_subagent_prompt,
174
+ validate_prompt_tokens,
175
+ DEFAULT_SYSTEM_TEMPLATE,
176
+ )
177
+ from teragent.pipeline.checklist import (
178
+ run_deterministic_checks,
179
+ TaskInfo,
180
+ check_code_quality,
181
+ check_requirements,
182
+ check_runnable,
183
+ check_file_conflicts,
184
+ check_fallback_files,
185
+ )
186
+ from teragent.pipeline.retry import retry_with_backoff
187
+
188
+ # TAP Tracing + DPO pair generation
189
+ from teragent.pipeline.tracing import (
190
+ TAPTracer,
191
+ TraceRecord,
192
+ DPOPair,
193
+ DataConstitution,
194
+ TraceStats,
195
+ )
196
+
197
+ # ============================================================================
198
+ # Prompt selection
199
+ # ============================================================================
200
+
201
+ from teragent.core.prompts import get_system_prompt_for_intent as _get_system_prompt_for_intent
202
+ from teragent.core.prompts import list_intents, list_compiler_types
203
+
204
+ def get_system_prompt_for_intent(
205
+ intent: str,
206
+ compiler_type: str = "default",
207
+ ) -> str:
208
+ """Get the system prompt for a given intent and compiler type.
209
+
210
+ Centralized prompt management.
211
+ All prompts are managed through teragent/core/prompts/ and selected
212
+ based on intent (design, plan, replan, execute, review, chat,
213
+ chat_friendly, sub_agent) and compiler type (default, glm,
214
+ anthropic, deepseek).
215
+
216
+ Args:
217
+ intent: One of: design | plan | replan | execute | review |
218
+ chat | chat_friendly | sub_agent | code_generation
219
+ compiler_type: One of: default | glm | anthropic | deepseek
220
+
221
+ Returns:
222
+ System prompt string for the given intent and compiler type.
223
+ Falls back to "default" compiler if specific one not found.
224
+ Returns empty string if intent is not recognized.
225
+
226
+ Examples:
227
+ # Get GLM-optimized design prompt
228
+ prompt = teragent.get_system_prompt_for_intent("design", "glm")
229
+
230
+ # Get default chat prompt
231
+ prompt = teragent.get_system_prompt_for_intent("chat")
232
+
233
+ # Different compilers produce different prompts for the same intent
234
+ default_prompt = teragent.get_system_prompt_for_intent("review", "default")
235
+ anthropic_prompt = teragent.get_system_prompt_for_intent("review", "anthropic")
236
+ # anthropic_prompt uses XML tags, default_prompt uses plain text
237
+ """
238
+ return _get_system_prompt_for_intent(intent, compiler_type=compiler_type)
239
+
240
+
241
+ # Prompt templates
242
+ from teragent.core.prompts import (
243
+ DESIGN_PROMPT_DEFAULT, DESIGN_PROMPT_GLM, DESIGN_PROMPT_ANTHROPIC, DESIGN_PROMPT_DEEPSEEK,
244
+ PLAN_PROMPT_DEFAULT, PLAN_PROMPT_GLM, PLAN_PROMPT_ANTHROPIC, PLAN_PROMPT_DEEPSEEK,
245
+ REPLAN_PROMPT_DEFAULT, REPLAN_PROMPT_GLM, REPLAN_PROMPT_ANTHROPIC, REPLAN_PROMPT_DEEPSEEK,
246
+ REVIEW_PROMPT_DEFAULT, REVIEW_PROMPT_GLM, REVIEW_PROMPT_ANTHROPIC, REVIEW_PROMPT_DEEPSEEK,
247
+ AGENT_PROMPT_DEFAULT, AGENT_PROMPT_GLM, AGENT_PROMPT_ANTHROPIC, AGENT_PROMPT_DEEPSEEK,
248
+ CHAT_PROMPT_DEFAULT, CHAT_PROMPT_GLM, CHAT_PROMPT_ANTHROPIC, CHAT_PROMPT_DEEPSEEK,
249
+ SUB_AGENT_PROMPT_DEFAULT, SUB_AGENT_PROMPT_GLM, SUB_AGENT_PROMPT_ANTHROPIC, SUB_AGENT_PROMPT_DEEPSEEK,
250
+ EXECUTE_PROMPT_DEFAULT, EXECUTE_PROMPT_GLM, EXECUTE_PROMPT_ANTHROPIC, EXECUTE_PROMPT_DEEPSEEK,
251
+ )
252
+
253
+ # ============================================================================
254
+ # Security architecture
255
+ # ============================================================================
256
+
257
+ from teragent.security.permission import (
258
+ PermissionManager,
259
+ PermissionLevel,
260
+ EnhancedPermissionManager,
261
+ PermissionRule,
262
+ PermissionEffect,
263
+ )
264
+ from teragent.security.file_state import FileStateTracker
265
+ from teragent.security.file_writer import write_files_safely, atomic_write_file
266
+ from teragent.security.ai_permission_classifier import AIPermissionClassifier
267
+ from teragent.security.sandbox import execute_in_sandbox, check_command_safety
268
+ from teragent.security.audit import AuditLogger
269
+ from teragent.security.firecracker_sandbox import FirecrackerSandbox
270
+
271
+ # ============================================================================
272
+ # Context management — core components always available
273
+ # ============================================================================
274
+
275
+ from teragent.context.context_window import ContextWindow
276
+ from teragent.context.microcompactor import Microcompactor
277
+ from teragent.context.auto_compact import AutoCompactor
278
+ from teragent.context.memory import (
279
+ load_agent_md,
280
+ save_agent_md,
281
+ merge_agent_md,
282
+ extract_rules,
283
+ )
284
+ # DependencyReporter moved to lazy import (requires optional deps)
285
+
286
+ # ============================================================================
287
+ # Reliability
288
+ # ============================================================================
289
+
290
+ from teragent.reliability.circuit_breaker import (
291
+ CircuitBreakerManager,
292
+ CostBudgetTracker,
293
+ CostBudgetConfig,
294
+ BudgetCheckResult,
295
+ BreakerState,
296
+ ConsecutiveFailureBreaker,
297
+ LatencyBreaker,
298
+ ProgressDetector,
299
+ )
300
+ from teragent.reliability.budget import StepBudget, DEFAULT_MAX_STEPS
301
+ from teragent.reliability.recovery import (
302
+ RecoveryType,
303
+ RecoveryStats,
304
+ RecoveryManagerConfig,
305
+ RecoveryManager,
306
+ is_context_overflow_error,
307
+ is_retryable_error,
308
+ )
309
+
310
+ # ============================================================================
311
+ # EventBus
312
+ # ============================================================================
313
+
314
+ from teragent.event_bus import EventBus
315
+
316
+ # ============================================================================
317
+ # Coordination
318
+ # ============================================================================
319
+
320
+ from teragent.coordination.message_bus import AgentMessageBus, AgentMessage
321
+ from teragent.coordination.sub_agent_manager import (
322
+ SubAgentManager,
323
+ AgentMode,
324
+ SubAgentStatus,
325
+ SubAgentInfo,
326
+ )
327
+
328
+ # ============================================================================
329
+ # Intent
330
+ # ============================================================================
331
+
332
+ from teragent.intent.classifier import IntentClassifier, IntentType
333
+ from teragent.intent.confirmation import ConfirmationGate
334
+
335
+ # ============================================================================
336
+ # Hooks
337
+ # ============================================================================
338
+
339
+ from teragent.hooks.manager import (
340
+ HookEvent,
341
+ HookDecision,
342
+ HookContext,
343
+ HookResult,
344
+ Hook,
345
+ ShellHook,
346
+ PythonHook,
347
+ HookManager,
348
+ )
349
+ from teragent.hooks.builtin.audit_hook import AuditHook
350
+ from teragent.hooks.builtin.dangerous_command_hook import DangerousCommandHook
351
+
352
+ # ============================================================================
353
+ # Session
354
+ # ============================================================================
355
+
356
+ from teragent.session.persistence import SessionPersistence, SessionData, SessionInfo
357
+
358
+ # ============================================================================
359
+ # Streaming
360
+ # ============================================================================
361
+
362
+ from teragent.streaming.stream_events import (
363
+ StreamEventType,
364
+ StreamEvent,
365
+ ToolCallAccumulator,
366
+ StreamingChatResult,
367
+ OpenAIStreamParser,
368
+ AnthropicStreamParser,
369
+ )
370
+ from teragent.streaming.streaming_executor import (
371
+ StreamingToolExecutor,
372
+ StreamingExecutionStats,
373
+ )
374
+
375
+ # ============================================================================
376
+ # Tools — base abstractions for tool system
377
+ # ============================================================================
378
+
379
+ from teragent.tools.base import BaseTool, ToolResult
380
+ from teragent.tools.registry import ToolRegistry
381
+ from teragent.tools.orchestrator import ToolOrchestrator, MAX_CONCURRENT_TOOLS
382
+
383
+ # ============================================================================
384
+ # AgentLoop — central orchestration class
385
+ # ============================================================================
386
+
387
+ from teragent.agent_loop import AgentLoop
388
+
389
+ # ============================================================================
390
+ # Trigger compiler/adapter registration
391
+ # ============================================================================
392
+
393
+ import teragent.core.compilers # noqa: F401 — registers: default, glm, anthropic, deepseek
394
+ import teragent.core.adapters # noqa: F401 — registers: openai_compatible, anthropic_native, mock
395
+
396
+
397
+ # ============================================================================
398
+ # Lazy imports for optional-dependency components
399
+ # ============================================================================
400
+
401
+ def __getattr__(name: str):
402
+ """Lazy-load components that require optional dependencies.
403
+
404
+ This allows ``import teragent`` to succeed even when optional
405
+ dependencies (lancedb, tree-sitter, networkx) are not installed.
406
+ The components will only raise ImportError when actually accessed.
407
+
408
+ Optional extras:
409
+ - teragent[vector] — VectorIndexer
410
+ - teragent[ast] — CodeIndexer
411
+ - teragent[graph] — ReferenceGraph
412
+ """
413
+ if name == "DependencyReporter":
414
+ from teragent.context.dependency_reporter import DependencyReporter
415
+ return DependencyReporter
416
+ if name == "TaskProtocol":
417
+ from teragent.context.dependency_reporter import TaskProtocol
418
+ return TaskProtocol
419
+ if name == "CodeIndexer":
420
+ from teragent.context.code_indexer import CodeIndexer
421
+ return CodeIndexer
422
+ if name == "ReferenceGraph":
423
+ from teragent.context.reference_graph import ReferenceGraph
424
+ return ReferenceGraph
425
+ if name == "VectorIndexer":
426
+ from teragent.context.vector_indexer import VectorIndexer
427
+ return VectorIndexer
428
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
429
+
430
+
431
+ # ============================================================================
432
+ # Factory function
433
+ # ============================================================================
434
+
435
+ def create_provider(
436
+ compiler: str | TAPCompiler,
437
+ adapter: str | TAPAdapter,
438
+ model: str,
439
+ base_url: str = "",
440
+ api_key: str = "",
441
+ api_key_env: str = "",
442
+ timeout: float = 300.0,
443
+ extra_headers: dict | None = None,
444
+ enable_fake_tools: bool = False,
445
+ fallback: ModelProvider | None = None,
446
+ circuit_breaker: Any | None = None,
447
+ tracer: Any | None = None,
448
+ **kwargs,
449
+ ) -> ModelProvider:
450
+ """Factory function to create a ModelProvider from Registry
451
+
452
+ Automatically creates Compiler and Adapter instances from the registry,
453
+ then combines them into a ModelProvider.
454
+
455
+ API key resolution:
456
+ - If api_key_env is provided, resolves from environment variable
457
+ (with .env file fallback via python-dotenv)
458
+ - If only api_key is provided, uses it directly
459
+ (logs an info message recommending api_key_env instead)
460
+ - Recommended: use api_key_env for security
461
+
462
+ Args:
463
+ compiler: Compiler name (str) or TAPCompiler instance
464
+ Available names: "default", "glm", "anthropic", "deepseek"
465
+ adapter: Adapter name (str) or TAPAdapter instance
466
+ Available names: "openai_compatible", "anthropic_native", "mock"
467
+ model: Model identifier string (e.g., "glm-5.1", "claude-sonnet-4-20250514")
468
+ base_url: API base URL (required for non-mock adapters)
469
+ api_key: API key string (direct, not recommended for production)
470
+ api_key_env: Environment variable name for API key (recommended)
471
+ timeout: HTTP request timeout in seconds (default 300.0)
472
+ extra_headers: Additional HTTP headers for the adapter
473
+ enable_fake_tools: Whether to inject fake tools for distillation detection
474
+ fallback: Fallback ModelProvider for automatic degradation
475
+ circuit_breaker: CircuitBreakerManager for cost/failure tracking
476
+ tracer: TAPTracer for auto-tracing TAP calls
477
+ **kwargs: Additional arguments passed to Adapter constructor
478
+
479
+ Returns:
480
+ ModelProvider instance with Compiler + Adapter composed
481
+
482
+ Raises:
483
+ ValueError: If compiler or adapter name is not registered
484
+
485
+ Examples:
486
+ # GLM via OpenAI-compatible protocol (recommended: api_key_env)
487
+ provider = create_provider(
488
+ compiler="glm",
489
+ adapter="openai_compatible",
490
+ model="glm-5.1",
491
+ base_url="https://open.bigmodel.cn/api/paas/v4",
492
+ api_key_env="GLM_API_KEY",
493
+ )
494
+
495
+ # Claude via OpenRouter (OpenAI protocol + Anthropic compiler)
496
+ provider = create_provider(
497
+ compiler="anthropic",
498
+ adapter="openai_compatible",
499
+ model="anthropic/claude-sonnet-4-20250514",
500
+ base_url="https://openrouter.ai/api/v1",
501
+ api_key_env="OPENROUTER_API_KEY",
502
+ )
503
+
504
+ # Claude via Anthropic native protocol
505
+ provider = create_provider(
506
+ compiler="anthropic",
507
+ adapter="anthropic_native",
508
+ model="claude-sonnet-4-20250514",
509
+ base_url="https://api.anthropic.com/v1",
510
+ api_key_env="ANTHROPIC_API_KEY",
511
+ )
512
+
513
+ # Mock for testing
514
+ provider = create_provider(
515
+ compiler="default",
516
+ adapter="mock",
517
+ model="mock-model",
518
+ )
519
+
520
+ # From DriverConfig
521
+ from teragent.config import DriverConfig
522
+ cfg = DriverConfig(adapter="openai_compatible", identity="glm",
523
+ model="glm-5.1", compiler="glm",
524
+ base_url="...", api_key_env="GLM_API_KEY")
525
+ provider = create_provider(**cfg.to_create_provider_kwargs())
526
+ """
527
+ # Resolve Compiler
528
+ if isinstance(compiler, str):
529
+ compiler_instance = TAPCompilerRegistry.create(compiler)
530
+ else:
531
+ compiler_instance = compiler
532
+
533
+ # Resolve API key (centralized via ApiKeyVault)
534
+ from teragent.config.api_key_security import ApiKeyVault, mask_api_key as _mask
535
+ vault = ApiKeyVault()
536
+
537
+ resolved_api_key = ""
538
+ if api_key_env:
539
+ # Preferred path: resolve from environment variable
540
+ resolved = vault.resolve(api_key_env)
541
+ resolved_api_key = resolved.key
542
+ if not resolved.found:
543
+ logger.warning(f"API key not found for env var: {api_key_env}")
544
+ elif api_key:
545
+ # Fallback: direct key (store in vault for tracking, no deprecation
546
+ # warning here since this is a programmatic call, not config)
547
+ resolved = vault.store_direct(api_key, name=f"create_provider:{model}")
548
+ resolved_api_key = resolved.key
549
+ logger.info(
550
+ f"Using directly provided API key for model '{model}' "
551
+ f"(masked: {_mask(resolved_api_key)}). "
552
+ f"Consider using api_key_env for better security."
553
+ )
554
+
555
+ # Resolve Adapter
556
+ if isinstance(adapter, str):
557
+ adapter_kwargs: dict[str, Any] = {}
558
+ if adapter == "openai_compatible":
559
+ adapter_kwargs = {
560
+ "base_url": base_url,
561
+ "api_key": resolved_api_key,
562
+ "timeout": timeout,
563
+ "extra_headers": extra_headers,
564
+ "enable_fake_tools": enable_fake_tools,
565
+ }
566
+ elif adapter == "anthropic_native":
567
+ adapter_kwargs = {
568
+ "base_url": base_url,
569
+ "api_key": resolved_api_key,
570
+ "timeout": timeout,
571
+ "enable_fake_tools": enable_fake_tools,
572
+ }
573
+ elif adapter == "mock":
574
+ adapter_kwargs = {}
575
+ else:
576
+ adapter_kwargs = kwargs
577
+
578
+ adapter_instance = TAPAdapterRegistry.create(adapter, **adapter_kwargs)
579
+ else:
580
+ adapter_instance = adapter
581
+
582
+ return ModelProvider(
583
+ compiler=compiler_instance,
584
+ adapter=adapter_instance,
585
+ model=model,
586
+ fallback=fallback,
587
+ circuit_breaker=circuit_breaker,
588
+ tracer=tracer,
589
+ )
590
+
591
+
592
+ # ============================================================================
593
+ # Version
594
+ # ============================================================================
595
+
596
+ __version__ = "0.0.1"
597
+
598
+
599
+ # ============================================================================
600
+ # Public API
601
+ # ============================================================================
602
+
603
+ __all__ = [
604
+ # Version
605
+ "__version__",
606
+ # Core types
607
+ "TAPRequest",
608
+ "TAPResponse",
609
+ "TAPCostRecord",
610
+ "CompiledPrompt",
611
+ # ABC + Registry
612
+ "TAPCompiler",
613
+ "TAPCompilerRegistry",
614
+ "TAPAdapter",
615
+ "TAPAdapterRegistry",
616
+ # Provider
617
+ "ModelProvider",
618
+ # Factory
619
+ "create_provider",
620
+ # Core types
621
+ "ToolSafety",
622
+ "Message",
623
+ "MessageRole",
624
+ "MessageType",
625
+ "messages_to_api_format",
626
+ "messages_from_dicts",
627
+ # Config layer
628
+ "DriverConfig",
629
+ "load_driver_configs",
630
+ "load_pipeline_config",
631
+ "load_full_config",
632
+ "create_provider_from_config",
633
+ "get_driver_config",
634
+ "resolve_api_key",
635
+ "resolve_api_key_detailed",
636
+ "infer_compiler",
637
+ "audit_config_security",
638
+ # API Key Security
639
+ "ApiKeyVault",
640
+ "ResolvedKey",
641
+ "SecurityFinding",
642
+ "SecuritySeverity",
643
+ "SecurityError",
644
+ "mask_api_key",
645
+ "detect_api_key_provider",
646
+ "audit_api_key_security",
647
+ "audit_env_file",
648
+ "get_vault",
649
+ # Typed config
650
+ "TerAgentConfig",
651
+ "AgentdSectionConfig",
652
+ "AgentLoopConfig",
653
+ "CircuitBreakerConfig",
654
+ "BudgetConfig",
655
+ "FailureBreakerConfig",
656
+ "LatencyBreakerConfig",
657
+ "ProgressDetectorConfig",
658
+ "ContextManagementConfig",
659
+ "ToolsConfig",
660
+ "FileSafetyConfig",
661
+ "SessionConfig",
662
+ "PermissionConfig",
663
+ "HooksConfig",
664
+ "RecoveryConfig",
665
+ "StreamingConfig",
666
+ "CoordinationConfig",
667
+ "ExecutionPipelineConfig",
668
+ "ModelFallbackConfig",
669
+ "load_typed_config",
670
+ # Pipeline primitives
671
+ "extract_files_from_response",
672
+ "build_prompt",
673
+ "build_subagent_prompt",
674
+ "validate_prompt_tokens",
675
+ "DEFAULT_SYSTEM_TEMPLATE",
676
+ "run_deterministic_checks",
677
+ "TaskInfo",
678
+ "check_code_quality",
679
+ "check_requirements",
680
+ "check_runnable",
681
+ "check_file_conflicts",
682
+ "check_fallback_files",
683
+ "retry_with_backoff",
684
+ # TAP Tracing + DPO pair generation
685
+ "TAPTracer",
686
+ "TraceRecord",
687
+ "DPOPair",
688
+ "DataConstitution",
689
+ "TraceStats",
690
+ # Prompt selection
691
+ "get_system_prompt_for_intent",
692
+ "list_intents",
693
+ "list_compiler_types",
694
+ # Prompt templates
695
+ "DESIGN_PROMPT_DEFAULT", "DESIGN_PROMPT_GLM", "DESIGN_PROMPT_ANTHROPIC", "DESIGN_PROMPT_DEEPSEEK",
696
+ "PLAN_PROMPT_DEFAULT", "PLAN_PROMPT_GLM", "PLAN_PROMPT_ANTHROPIC", "PLAN_PROMPT_DEEPSEEK",
697
+ "REPLAN_PROMPT_DEFAULT", "REPLAN_PROMPT_GLM", "REPLAN_PROMPT_ANTHROPIC", "REPLAN_PROMPT_DEEPSEEK",
698
+ "REVIEW_PROMPT_DEFAULT", "REVIEW_PROMPT_GLM", "REVIEW_PROMPT_ANTHROPIC", "REVIEW_PROMPT_DEEPSEEK",
699
+ "AGENT_PROMPT_DEFAULT", "AGENT_PROMPT_GLM", "AGENT_PROMPT_ANTHROPIC", "AGENT_PROMPT_DEEPSEEK",
700
+ "CHAT_PROMPT_DEFAULT", "CHAT_PROMPT_GLM", "CHAT_PROMPT_ANTHROPIC", "CHAT_PROMPT_DEEPSEEK",
701
+ "SUB_AGENT_PROMPT_DEFAULT", "SUB_AGENT_PROMPT_GLM", "SUB_AGENT_PROMPT_ANTHROPIC", "SUB_AGENT_PROMPT_DEEPSEEK",
702
+ "EXECUTE_PROMPT_DEFAULT", "EXECUTE_PROMPT_GLM", "EXECUTE_PROMPT_ANTHROPIC", "EXECUTE_PROMPT_DEEPSEEK",
703
+ # Security
704
+ "PermissionManager",
705
+ "PermissionLevel",
706
+ "EnhancedPermissionManager",
707
+ "PermissionRule",
708
+ "PermissionEffect",
709
+ "FileStateTracker",
710
+ "write_files_safely",
711
+ "atomic_write_file",
712
+ "AIPermissionClassifier",
713
+ "execute_in_sandbox",
714
+ "check_command_safety",
715
+ "AuditLogger",
716
+ "FirecrackerSandbox",
717
+ # Context management — core always available
718
+ "ContextWindow",
719
+ "Microcompactor",
720
+ "AutoCompactor",
721
+ "DependencyReporter",
722
+ "TaskProtocol",
723
+ "load_agent_md",
724
+ "save_agent_md",
725
+ "merge_agent_md",
726
+ "extract_rules",
727
+ # Context management — optional (lazy-loaded)
728
+ "CodeIndexer",
729
+ "ReferenceGraph",
730
+ "VectorIndexer",
731
+ # Reliability
732
+ "CircuitBreakerManager",
733
+ "CostBudgetTracker",
734
+ "CostBudgetConfig",
735
+ "BudgetCheckResult",
736
+ "BreakerState",
737
+ "ConsecutiveFailureBreaker",
738
+ "LatencyBreaker",
739
+ "ProgressDetector",
740
+ "StepBudget",
741
+ "DEFAULT_MAX_STEPS",
742
+ # Reliability — Recovery
743
+ "RecoveryType",
744
+ "RecoveryStats",
745
+ "RecoveryManagerConfig",
746
+ "RecoveryManager",
747
+ "is_context_overflow_error",
748
+ "is_retryable_error",
749
+ # EventBus
750
+ "EventBus",
751
+ # Coordination
752
+ "AgentMessageBus",
753
+ "AgentMessage",
754
+ "SubAgentManager",
755
+ "AgentMode",
756
+ "SubAgentStatus",
757
+ "SubAgentInfo",
758
+ # Intent
759
+ "IntentClassifier",
760
+ "IntentType",
761
+ "ConfirmationGate",
762
+ # Hooks
763
+ "HookEvent",
764
+ "HookDecision",
765
+ "HookContext",
766
+ "HookResult",
767
+ "Hook",
768
+ "ShellHook",
769
+ "PythonHook",
770
+ "HookManager",
771
+ "AuditHook",
772
+ "DangerousCommandHook",
773
+ # Session
774
+ "SessionPersistence",
775
+ "SessionData",
776
+ "SessionInfo",
777
+ # Streaming
778
+ "StreamEventType",
779
+ "StreamEvent",
780
+ "ToolCallAccumulator",
781
+ "StreamingChatResult",
782
+ "OpenAIStreamParser",
783
+ "AnthropicStreamParser",
784
+ "StreamingToolExecutor",
785
+ "StreamingExecutionStats",
786
+ # Tools — base abstractions
787
+ "BaseTool",
788
+ "ToolResult",
789
+ "ToolRegistry",
790
+ "ToolOrchestrator",
791
+ "MAX_CONCURRENT_TOOLS",
792
+ # AgentLoop — central orchestration
793
+ "AgentLoop",
794
+ ]