nucleus-mcp 1.0.7 → 1.2.0

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 (135) hide show
  1. package/package.json +2 -4
  2. package/.github/workflows/ci.yml +0 -72
  3. package/.smithery/shttp/module.js +0 -3
  4. package/.smithery/shttp/module.js.map +0 -7
  5. package/.smithery/stdio/index.cjs +0 -74
  6. package/.smithery/stdio/index.cjs.map +0 -7
  7. package/CHANGELOG.md +0 -65
  8. package/CODE_OF_CONDUCT.md +0 -34
  9. package/COMPARISON.md +0 -20
  10. package/CONTRIBUTING.md +0 -137
  11. package/DEVELOPMENT.md +0 -109
  12. package/LICENSE +0 -21
  13. package/README.md +0 -319
  14. package/ROADMAP.md +0 -24
  15. package/SECURITY.md +0 -88
  16. package/docs/COMMUNITY_FAQ.md +0 -48
  17. package/docs/COMPETITIVE_ANALYSIS.md +0 -90
  18. package/docs/DEMO_SCRIPT.md +0 -86
  19. package/docs/ENTERPRISE.md +0 -169
  20. package/docs/FAQ.md +0 -228
  21. package/docs/QUICK_START.md +0 -155
  22. package/docs/README.md +0 -67
  23. package/docs/RECURSIVE_SNAP_DEMO.gif +0 -0
  24. package/docs/social-preview-hq.png +0 -0
  25. package/docs/social-preview.png +0 -0
  26. package/examples/basic_usage.py +0 -84
  27. package/package.json.real +0 -24
  28. package/pyproject.toml +0 -50
  29. package/registry-server.json +0 -20
  30. package/scripts/demo_governance.py +0 -109
  31. package/scripts/sse_bridge.py +0 -87
  32. package/scripts/verify_windows_paths.py +0 -48
  33. package/server.json +0 -20
  34. package/src/mcp_server_nucleus/__init__.py +0 -8583
  35. package/src/mcp_server_nucleus/__main__.py +0 -9
  36. package/src/mcp_server_nucleus/cli.py +0 -1225
  37. package/src/mcp_server_nucleus/commitment_core.py +0 -146
  38. package/src/mcp_server_nucleus/commitment_ledger.py +0 -841
  39. package/src/mcp_server_nucleus/core/__init__.py +0 -6
  40. package/src/mcp_server_nucleus/core/orchestrator.py +0 -9
  41. package/src/mcp_server_nucleus/core/tool_registration_impl.py +0 -99
  42. package/src/mcp_server_nucleus/daemon/safety/lock.py +0 -121
  43. package/src/mcp_server_nucleus/deployment/render_integration.py +0 -4
  44. package/src/mcp_server_nucleus/hypervisor/__init__.py +0 -0
  45. package/src/mcp_server_nucleus/hypervisor/injector.py +0 -83
  46. package/src/mcp_server_nucleus/hypervisor/locker.py +0 -130
  47. package/src/mcp_server_nucleus/hypervisor/watchdog.py +0 -71
  48. package/src/mcp_server_nucleus/runtime/__init__.py +0 -58
  49. package/src/mcp_server_nucleus/runtime/agent.py +0 -517
  50. package/src/mcp_server_nucleus/runtime/agent_pool.py +0 -797
  51. package/src/mcp_server_nucleus/runtime/agents/base.py +0 -34
  52. package/src/mcp_server_nucleus/runtime/agents/oracle/manifest.json +0 -28
  53. package/src/mcp_server_nucleus/runtime/auth.py +0 -98
  54. package/src/mcp_server_nucleus/runtime/autopilot.py +0 -1057
  55. package/src/mcp_server_nucleus/runtime/broker.py +0 -126
  56. package/src/mcp_server_nucleus/runtime/budget.py +0 -153
  57. package/src/mcp_server_nucleus/runtime/capabilities/base.py +0 -20
  58. package/src/mcp_server_nucleus/runtime/capabilities/brain_ops.py +0 -253
  59. package/src/mcp_server_nucleus/runtime/capabilities/code_ops.py +0 -192
  60. package/src/mcp_server_nucleus/runtime/capabilities/depth_tracker.py +0 -81
  61. package/src/mcp_server_nucleus/runtime/capabilities/feature_map.py +0 -274
  62. package/src/mcp_server_nucleus/runtime/capabilities/marketing_engine.py +0 -205
  63. package/src/mcp_server_nucleus/runtime/capabilities/memory_ops.py +0 -79
  64. package/src/mcp_server_nucleus/runtime/capabilities/proof_system.py +0 -127
  65. package/src/mcp_server_nucleus/runtime/capabilities/render_ops.py +0 -80
  66. package/src/mcp_server_nucleus/runtime/capabilities/render_poller_cap.py +0 -266
  67. package/src/mcp_server_nucleus/runtime/capabilities/self_healing.py +0 -110
  68. package/src/mcp_server_nucleus/runtime/capabilities/strategy.py +0 -138
  69. package/src/mcp_server_nucleus/runtime/capabilities/synthesizer.py +0 -134
  70. package/src/mcp_server_nucleus/runtime/capabilities/web_ops.py +0 -94
  71. package/src/mcp_server_nucleus/runtime/common.py +0 -134
  72. package/src/mcp_server_nucleus/runtime/context_manager.py +0 -342
  73. package/src/mcp_server_nucleus/runtime/context_rules.json +0 -86
  74. package/src/mcp_server_nucleus/runtime/crdt_task_store.py +0 -349
  75. package/src/mcp_server_nucleus/runtime/critic.py +0 -150
  76. package/src/mcp_server_nucleus/runtime/daemon.py +0 -142
  77. package/src/mcp_server_nucleus/runtime/dashboard.py +0 -1087
  78. package/src/mcp_server_nucleus/runtime/depth_ops.py +0 -339
  79. package/src/mcp_server_nucleus/runtime/event_ops.py +0 -103
  80. package/src/mcp_server_nucleus/runtime/event_stream.py +0 -213
  81. package/src/mcp_server_nucleus/runtime/export.py +0 -64
  82. package/src/mcp_server_nucleus/runtime/factory.py +0 -594
  83. package/src/mcp_server_nucleus/runtime/federation.py +0 -1040
  84. package/src/mcp_server_nucleus/runtime/fetcher.py +0 -92
  85. package/src/mcp_server_nucleus/runtime/file_monitor.py +0 -208
  86. package/src/mcp_server_nucleus/runtime/firestore_bridge.py +0 -91
  87. package/src/mcp_server_nucleus/runtime/gcloud_ops.py +0 -186
  88. package/src/mcp_server_nucleus/runtime/hooks.py +0 -246
  89. package/src/mcp_server_nucleus/runtime/identity/gatekeeper.py +0 -106
  90. package/src/mcp_server_nucleus/runtime/identity/keygen.py +0 -147
  91. package/src/mcp_server_nucleus/runtime/identity/manifest.py +0 -62
  92. package/src/mcp_server_nucleus/runtime/identity/trust.py +0 -27
  93. package/src/mcp_server_nucleus/runtime/inspector.py +0 -74
  94. package/src/mcp_server_nucleus/runtime/installer.py +0 -81
  95. package/src/mcp_server_nucleus/runtime/ipc_auth.py +0 -377
  96. package/src/mcp_server_nucleus/runtime/lifecycle.py +0 -129
  97. package/src/mcp_server_nucleus/runtime/llm_client.py +0 -408
  98. package/src/mcp_server_nucleus/runtime/llm_tiers.json +0 -88
  99. package/src/mcp_server_nucleus/runtime/locking.py +0 -228
  100. package/src/mcp_server_nucleus/runtime/loops/fixer.py +0 -110
  101. package/src/mcp_server_nucleus/runtime/memory.py +0 -158
  102. package/src/mcp_server_nucleus/runtime/mounter.py +0 -210
  103. package/src/mcp_server_nucleus/runtime/mounter_ops.py +0 -250
  104. package/src/mcp_server_nucleus/runtime/nuke_protocol.py +0 -147
  105. package/src/mcp_server_nucleus/runtime/orchestrator.py +0 -370
  106. package/src/mcp_server_nucleus/runtime/orchestrator_unified.py +0 -263
  107. package/src/mcp_server_nucleus/runtime/orchestrator_v3.py +0 -617
  108. package/src/mcp_server_nucleus/runtime/plugin_loader.py +0 -84
  109. package/src/mcp_server_nucleus/runtime/policy.py +0 -117
  110. package/src/mcp_server_nucleus/runtime/profiling.py +0 -219
  111. package/src/mcp_server_nucleus/runtime/prometheus.py +0 -286
  112. package/src/mcp_server_nucleus/runtime/proposals.py +0 -101
  113. package/src/mcp_server_nucleus/runtime/publisher.py +0 -109
  114. package/src/mcp_server_nucleus/runtime/pulse.py +0 -516
  115. package/src/mcp_server_nucleus/runtime/registry.py +0 -82
  116. package/src/mcp_server_nucleus/runtime/render_ops.py +0 -83
  117. package/src/mcp_server_nucleus/runtime/schema_gen.py +0 -140
  118. package/src/mcp_server_nucleus/runtime/session_ops.py +0 -224
  119. package/src/mcp_server_nucleus/runtime/stdio_server.py +0 -633
  120. package/src/mcp_server_nucleus/runtime/storage.py +0 -83
  121. package/src/mcp_server_nucleus/runtime/strategy.py +0 -91
  122. package/src/mcp_server_nucleus/runtime/swarm.py +0 -170
  123. package/src/mcp_server_nucleus/runtime/sync_ops.py +0 -878
  124. package/src/mcp_server_nucleus/runtime/task_ingestion.py +0 -1020
  125. package/src/mcp_server_nucleus/runtime/task_ops.py +0 -449
  126. package/src/mcp_server_nucleus/runtime/task_scheduler.py +0 -488
  127. package/src/mcp_server_nucleus/runtime/team.py +0 -59
  128. package/src/mcp_server_nucleus/runtime/triggers.py +0 -237
  129. package/src/mcp_server_nucleus/runtime/vector_store.py +0 -125
  130. package/src/mcp_server_nucleus/runtime/watcher.py +0 -112
  131. package/src/mcp_server_nucleus/tool_tiers.py +0 -243
  132. package/tests/__init__.py +0 -1
  133. package/tests/conftest.py +0 -42
  134. package/tests/test_core.py +0 -235
  135. package/tests/test_search.py +0 -69
@@ -1,408 +0,0 @@
1
- """
2
- Nucleus LLM Client
3
- ==================
4
- Multi-Tier LLM Client with intelligent routing.
5
- Primary: google-genai (v1.0+) with Vertex AI
6
- Fallback: google-generativeai (Legacy) or API Key
7
-
8
- MDR_010 Compliant: Ensures high availability and reliability.
9
- """
10
-
11
- import os
12
- import logging
13
- import json
14
- from pathlib import Path
15
- from datetime import datetime
16
- from typing import Optional, Dict, Any
17
- from enum import Enum
18
-
19
- # Configure logger
20
- logger = logging.getLogger("nucleus.llm")
21
-
22
- # ============================================================
23
- # SDK AVAILABILITY FLAGS & ENVIRONMENT CONTROL
24
- # ============================================================
25
- # Environment variable to force SDK selection:
26
- # USE_NEW_GENAI=true → Prefer google-genai (new SDK)
27
- # USE_NEW_GENAI=false → Prefer google.generativeai (legacy)
28
- # Default: Try new SDK first, fall back to legacy
29
- # ============================================================
30
-
31
- # Primary SDK: google-genai (v1.0+)
32
- try:
33
- from google import genai
34
- from google.genai import types
35
- HAS_GENAI = True
36
- logger.info("✅ SDK: google-genai (new) available")
37
- except ImportError:
38
- HAS_GENAI = False
39
- logger.error("❌ SDK: google-genai NOT installed! Please run 'pip install google-genai'")
40
-
41
- # Fallback SDK: google.generativeai (Legacy)
42
- try:
43
- import warnings
44
- with warnings.catch_warnings():
45
- warnings.filterwarnings("ignore", category=FutureWarning)
46
- import google.generativeai as genai_legacy
47
- HAS_LEGACY = True
48
- except ImportError:
49
- HAS_LEGACY = False
50
-
51
- def get_active_sdk() -> str:
52
- if HAS_GENAI:
53
- return "NEW"
54
- if HAS_LEGACY:
55
- return "LEGACY"
56
- return "NONE"
57
-
58
- _active = get_active_sdk()
59
- logger.info(f"🎯 SDK Selection: Using {_active}")
60
-
61
-
62
- # ============================================================
63
- # TIER ROUTER: Intelligent Multi-Tier LLM Selection
64
- # ============================================================
65
-
66
- class LLMTier(Enum):
67
- """Available LLM pricing/capability tiers."""
68
- PREMIUM = "premium" # gemini-3-pro, highest capability
69
- STANDARD = "standard" # gemini-2.5-flash, default production
70
- ECONOMY = "economy" # gemini-2.5-flash-lite, background tasks
71
- LOCAL_PAID = "local_paid" # API Key with billing
72
- LOCAL_FREE = "local_free" # API Key free tier (100 req/day)
73
-
74
-
75
- class TierRouter:
76
- """
77
- Intelligent router that selects the optimal LLM tier based on:
78
- - Job type (CRITICAL, RESEARCH, ORCHESTRATION, BACKGROUND, TESTING)
79
- - Budget mode (spartan, balanced, premium)
80
- - Quota availability (fallback on errors)
81
- """
82
-
83
- TIER_CONFIGS = {
84
- LLMTier.PREMIUM: {
85
- "model": "gemini-2.5-pro", # Note: gemini-3-pro not yet in Vertex AI
86
- "platform": "vertex",
87
- "cost_level": "high",
88
- "description": "Advanced reasoning, complex architecture"
89
- },
90
- LLMTier.STANDARD: {
91
- "model": "gemini-2.5-flash",
92
- "platform": "vertex",
93
- "cost_level": "medium",
94
- "description": "Default production, 95% of work"
95
- },
96
- LLMTier.ECONOMY: {
97
- "model": "gemini-2.5-flash-lite",
98
- "platform": "vertex",
99
- "cost_level": "low",
100
- "description": "Background tasks, batch jobs"
101
- },
102
- LLMTier.LOCAL_PAID: {
103
- "model": "gemini-2.5-flash",
104
- "platform": "api_key",
105
- "cost_level": "medium",
106
- "description": "Fallback when Vertex fails"
107
- },
108
- LLMTier.LOCAL_FREE: {
109
- "model": "gemini-2.0-flash",
110
- "platform": "api_key",
111
- "cost_level": "free",
112
- "description": "Testing only, 100 req/day"
113
- },
114
- }
115
-
116
- JOB_ROUTING = {
117
- "CRITICAL": LLMTier.PREMIUM,
118
- "RESEARCH": LLMTier.STANDARD,
119
- "ORCHESTRATION": LLMTier.STANDARD,
120
- "BACKGROUND": LLMTier.ECONOMY,
121
- "TESTING": LLMTier.LOCAL_FREE,
122
- }
123
-
124
- BUDGET_MODES = {
125
- "spartan": [LLMTier.LOCAL_FREE, LLMTier.ECONOMY, LLMTier.STANDARD],
126
- "balanced": [LLMTier.STANDARD, LLMTier.ECONOMY, LLMTier.LOCAL_PAID],
127
- "premium": [LLMTier.PREMIUM, LLMTier.STANDARD, LLMTier.ECONOMY],
128
- }
129
-
130
- FALLBACK_CHAIN = [
131
- LLMTier.PREMIUM,
132
- LLMTier.STANDARD,
133
- LLMTier.ECONOMY,
134
- LLMTier.LOCAL_PAID,
135
- LLMTier.LOCAL_FREE
136
- ]
137
-
138
- @classmethod
139
- def route(cls, job_type: str = "ORCHESTRATION", budget_mode: str = "balanced") -> LLMTier:
140
- """
141
- Route to optimal tier based on job type and budget.
142
-
143
- Args:
144
- job_type: CRITICAL, RESEARCH, ORCHESTRATION, BACKGROUND, TESTING
145
- budget_mode: spartan, balanced, premium
146
-
147
- Returns:
148
- The recommended LLMTier
149
- """
150
- # Check for forced tier (env var override)
151
- forced_tier = os.environ.get("NUCLEUS_LLM_TIER")
152
- if forced_tier:
153
- try:
154
- return LLMTier(forced_tier.lower())
155
- except ValueError:
156
- logger.warning(f"Invalid NUCLEUS_LLM_TIER: {forced_tier}")
157
-
158
- # Route based on job type
159
- job_upper = job_type.upper() if job_type else "ORCHESTRATION"
160
- base_tier = cls.JOB_ROUTING.get(job_upper, LLMTier.STANDARD)
161
-
162
- # CRITICAL jobs ALWAYS get their designated tier (premium)
163
- # Quality for important decisions overrides budget constraints
164
- if job_upper == "CRITICAL":
165
- logger.info("🎯 TierRouter: CRITICAL job - using premium tier regardless of budget")
166
- return LLMTier.PREMIUM
167
-
168
- # TESTING jobs ALWAYS use free tier to save costs
169
- if job_upper == "TESTING":
170
- return LLMTier.LOCAL_FREE
171
-
172
- # For other jobs, apply budget constraints
173
- budget_tiers = cls.BUDGET_MODES.get(budget_mode.lower(), cls.BUDGET_MODES["balanced"])
174
-
175
- # If base tier is in budget, use it; otherwise use first budget tier
176
- if base_tier in budget_tiers:
177
- return base_tier
178
- return budget_tiers[0]
179
-
180
- @classmethod
181
- def get_config(cls, tier: LLMTier) -> Dict[str, Any]:
182
- """Get configuration for a specific tier."""
183
- return cls.TIER_CONFIGS.get(tier, cls.TIER_CONFIGS[LLMTier.STANDARD])
184
-
185
- @classmethod
186
- def get_fallback(cls, current_tier: LLMTier) -> Optional[LLMTier]:
187
- """Get next tier in fallback chain."""
188
- try:
189
- idx = cls.FALLBACK_CHAIN.index(current_tier)
190
- if idx < len(cls.FALLBACK_CHAIN) - 1:
191
- return cls.FALLBACK_CHAIN[idx + 1]
192
- except ValueError:
193
- pass
194
- return None
195
-
196
- class DualEngineLLM:
197
- """
198
- Unified LLM Client wrapper with intelligent tier routing.
199
- Transparently falls back to legacy SDK if V1 is not available.
200
-
201
- Supports:
202
- - Explicit tier selection: DualEngineLLM(tier=LLMTier.PREMIUM)
203
- - Job-based routing: DualEngineLLM(job_type="CRITICAL")
204
- - Budget modes: "spartan", "balanced", "premium"
205
- """
206
-
207
- def __init__(
208
- self,
209
- model_name: Optional[str] = None,
210
- tier: Optional[LLMTier] = None,
211
- job_type: Optional[str] = None,
212
- budget_mode: str = "balanced",
213
- system_instruction: Optional[str] = None,
214
- api_key: Optional[str] = None
215
- ):
216
- # TIER ROUTING LOGIC
217
- self.tier = None
218
- self.tier_config = None
219
-
220
- if tier:
221
- # Explicit tier selection
222
- self.tier = tier
223
- self.tier_config = TierRouter.get_config(tier)
224
- model_name = self.tier_config["model"]
225
- logger.info(f"🎯 LLM: Using explicit tier '{tier.value}' → {model_name}")
226
- elif job_type:
227
- # Job-based routing
228
- self.tier = TierRouter.route(job_type, budget_mode)
229
- self.tier_config = TierRouter.get_config(self.tier)
230
- model_name = self.tier_config["model"]
231
- logger.info(f"🎯 LLM: Routed job '{job_type}' (budget={budget_mode}) → tier '{self.tier.value}' → {model_name}")
232
- else:
233
- # Default to standard tier
234
- self.tier = LLMTier.STANDARD
235
- self.tier_config = TierRouter.get_config(self.tier)
236
- model_name = model_name or self.tier_config["model"]
237
-
238
- self.model_name = model_name
239
- self.system_instruction = system_instruction
240
- self.api_key = api_key or os.environ.get("GEMINI_API_KEY")
241
- self.client = None
242
- self.engine = "NONE"
243
- self.budget_mode = budget_mode
244
-
245
- # Determine platform from tier config
246
- use_vertex = self.tier_config.get("platform", "vertex") == "vertex" if self.tier_config else True
247
- force_vertex_env = os.environ.get("FORCE_VERTEX", "1") == "1"
248
-
249
- # For local tiers, don't use vertex
250
- if self.tier in [LLMTier.LOCAL_PAID, LLMTier.LOCAL_FREE]:
251
- use_vertex = False
252
- else:
253
- use_vertex = use_vertex or force_vertex_env
254
-
255
- if not self.api_key and not use_vertex:
256
- raise ValueError("GEMINI_API_KEY is required for local tiers (or set FORCE_VERTEX=1).")
257
-
258
-
259
- # 1. Initialize google-genai (Primary)
260
- if HAS_GENAI:
261
- try:
262
- if use_vertex:
263
- project_id = os.environ.get("GCP_PROJECT_ID", os.environ.get("GOOGLE_CLOUD_PROJECT", "gen-lang-client-0894185576"))
264
- location = os.environ.get("GCP_LOCATION", "us-central1")
265
-
266
- logger.info(f"🏢 LLM Client: Vertex AI Mode ({project_id})")
267
- self.client = genai.Client(vertexai=True, project=project_id, location=location)
268
- else:
269
- logger.info("🔑 LLM Client: API Key Mode")
270
- # Use v1alpha for experimental features if needed, or stable v1
271
- self.client = genai.Client(api_key=self.api_key)
272
-
273
- self.engine = "NEW"
274
- return
275
- except Exception as e:
276
- logger.warning(f"⚠️ V1 Init failed: {e}")
277
-
278
- # 2. Try Legacy (Fallback)
279
- if HAS_LEGACY:
280
- try:
281
- genai_legacy.configure(api_key=self.api_key)
282
- # Map newer model names to legacy compatible ones if needed
283
- if "2.0" in model_name:
284
- logger.warning(f"⚠️ Legacy SDK may not support {model_name}. Using gemini-1.5-flash.")
285
- self.model_name = "gemini-1.5-flash"
286
-
287
- self.model = genai_legacy.GenerativeModel(
288
- model_name=self.model_name,
289
- system_instruction=system_instruction
290
- )
291
- self.engine = "LEGACY"
292
- logger.info(f"✅ LLM Client: Initialized google-generativeai (Legacy) for {self.model_name}")
293
- return
294
- except Exception as e:
295
- logger.error(f"❌ LLM Client: Legacy Init failed: {e}")
296
-
297
- if self.engine == "NONE":
298
- raise ImportError("Could not initialize any Gemini SDK. Install google-genai or google-generativeai.")
299
-
300
- def _log_interaction(self, prompt: str, response: Any):
301
- """
302
- Automatic Capture (Brain Consolidation - Phase 1).
303
- Saves the raw interaction to disk for later mining/consolidation.
304
- """
305
- try:
306
- brain_path = Path(os.environ.get("NUCLEAR_BRAIN_PATH", "/Users/lokeshgarg/ai-mvp-backend/.brain"))
307
- raw_path = brain_path / "raw"
308
- raw_path.mkdir(parents=True, exist_ok=True)
309
-
310
- timestamp = datetime.now().strftime("%Y%m%d_%H%M%S_%f")
311
- filename = raw_path / f"llm_interaction_{timestamp}.json"
312
-
313
- # Extract text from response (Best effort)
314
- response_text = "Unknown"
315
- if hasattr(response, 'text'):
316
- response_text = response.text
317
-
318
- data = {
319
- "timestamp": datetime.now().isoformat(),
320
- "engine": self.engine,
321
- "model": self.model_name,
322
- "prompt": str(prompt)[:5000], # Truncate massive prompts
323
- "response_text": response_text
324
- }
325
-
326
- with open(filename, 'w') as f:
327
- json.dump(data, f, indent=2)
328
-
329
- except Exception as e:
330
- logger.warning(f"Failed to log interaction: {e}")
331
-
332
- def generate_content(self, prompt: str, **kwargs) -> Any:
333
- try:
334
- if self.engine == "NEW":
335
- config_args = {}
336
- if self.system_instruction:
337
- config_args['system_instruction'] = self.system_instruction
338
-
339
- if 'tools' in kwargs:
340
- tools_raw = kwargs['tools']
341
- if isinstance(tools_raw, dict) and "function_declarations" in tools_raw:
342
- config_args['tools'] = [tools_raw]
343
- else:
344
- config_args['tools'] = tools_raw
345
-
346
- if 'tool_config' in kwargs:
347
- config_args['tool_config'] = kwargs['tool_config']
348
-
349
- config = types.GenerateContentConfig(**config_args)
350
-
351
- response = self.client.models.generate_content(
352
- model=self.model_name,
353
- contents=prompt,
354
- config=config
355
- )
356
- self._log_interaction(prompt, response)
357
- return response
358
-
359
- elif self.engine == "LEGACY":
360
- # Legacy SDK logic
361
- generation_config = {}
362
- # Legacy doesn't support tools same way here, basic text only for now or map tools manually
363
- # For Marketing Autopilot, we mostly use text.
364
-
365
- response = self.model.generate_content(prompt, generation_config=generation_config)
366
- self._log_interaction(prompt, response)
367
- return response
368
-
369
- except Exception as e:
370
- logger.error(f"❌ LLM Generate Content Failed ({self.engine}): {e}")
371
- raise
372
-
373
- def embed_content(self, text: str, task_type: str = "retrieval_document", title: Optional[str] = None) -> Dict[str, Any]:
374
- try:
375
- if self.engine == "NEW":
376
- normalized_task_type = task_type.replace("retrieval_", "RETRIEVAL_").upper()
377
- config = {'task_type': normalized_task_type}
378
- if title:
379
- config['title'] = title
380
-
381
- response = self.client.models.embed_content(
382
- model=self.model_name,
383
- contents=text,
384
- config=config
385
- )
386
- if hasattr(response, 'embeddings') and response.embeddings:
387
- return {'embedding': response.embeddings[0].values}
388
- return {'embedding': []}
389
-
390
- elif self.engine == "LEGACY":
391
- # Legacy SDK
392
- # task_type mapping
393
- # content
394
- result = genai_legacy.embed_content(
395
- model="models/text-embedding-004", # Hardcoded or passed in
396
- content=text,
397
- task_type=task_type,
398
- title=title
399
- )
400
- return result
401
-
402
- except Exception as e:
403
- logger.error(f"❌ LLM Embed Content Failed ({self.engine}): {e}")
404
- raise
405
-
406
- @property
407
- def active_engine(self):
408
- return self.engine
@@ -1,88 +0,0 @@
1
- {
2
- "tiers": {
3
- "premium": {
4
- "model": "gemini-2.5-pro",
5
- "platform": "vertex",
6
- "description": "Advanced reasoning, complex architecture, critical decisions",
7
- "cost_per_1m_tokens": {
8
- "input": 2.00,
9
- "output": 8.00
10
- },
11
- "max_context_tokens": 1000000
12
- },
13
- "standard": {
14
- "model": "gemini-2.5-flash",
15
- "platform": "vertex",
16
- "description": "Default production tier. 95% of agent work.",
17
- "cost_per_1m_tokens": {
18
- "input": 0.10,
19
- "output": 0.40
20
- },
21
- "max_context_tokens": 1000000
22
- },
23
- "economy": {
24
- "model": "gemini-2.5-flash-lite",
25
- "platform": "vertex",
26
- "description": "Background tasks, batch processing, digests",
27
- "cost_per_1m_tokens": {
28
- "input": 0.05,
29
- "output": 0.20
30
- },
31
- "max_context_tokens": 100000
32
- },
33
- "local_paid": {
34
- "model": "gemini-2.5-flash",
35
- "platform": "api_key",
36
- "description": "Fallback when Vertex/ADC fails. Requires GEMINI_API_KEY with billing.",
37
- "cost_per_1m_tokens": {
38
- "input": 0.10,
39
- "output": 0.40
40
- },
41
- "max_context_tokens": 32000
42
- },
43
- "local_free": {
44
- "model": "gemini-2.0-flash",
45
- "platform": "api_key",
46
- "description": "Testing only. 100 req/day limit. Do NOT use for production.",
47
- "cost_per_1m_tokens": {
48
- "input": 0,
49
- "output": 0
50
- },
51
- "max_context_tokens": 32000,
52
- "daily_limit": 100
53
- }
54
- },
55
- "job_routing": {
56
- "CRITICAL": "premium",
57
- "RESEARCH": "standard",
58
- "ORCHESTRATION": "standard",
59
- "BACKGROUND": "economy",
60
- "TESTING": "local_free"
61
- },
62
- "budget_modes": {
63
- "spartan": [
64
- "local_free",
65
- "economy",
66
- "standard"
67
- ],
68
- "balanced": [
69
- "standard",
70
- "economy",
71
- "local_paid"
72
- ],
73
- "premium": [
74
- "premium",
75
- "standard",
76
- "economy"
77
- ]
78
- },
79
- "fallback_chain": [
80
- "premium",
81
- "standard",
82
- "economy",
83
- "local_paid",
84
- "local_free"
85
- ],
86
- "default_tier": "standard",
87
- "default_budget_mode": "balanced"
88
- }