Compare commits
6 Commits
a359f19cdc
...
05cd1b6596
| Author | SHA1 | Date | |
|---|---|---|---|
| 05cd1b6596 | |||
| e9126b47db | |||
| 0f9f235438 | |||
| f0eb5382fe | |||
| 842bfc407c | |||
| 5ec4283f41 |
+53
-30
@@ -18,7 +18,8 @@ import datetime
|
||||
from pathlib import Path
|
||||
import file_cache
|
||||
import mcp_client
|
||||
import google.genai
|
||||
import anthropic
|
||||
from google import genai
|
||||
from google.genai import types
|
||||
from events import EventEmitter
|
||||
|
||||
@@ -155,7 +156,7 @@ class ProviderError(Exception):
|
||||
|
||||
def _classify_anthropic_error(exc: Exception) -> ProviderError:
|
||||
try:
|
||||
import anthropic
|
||||
|
||||
if isinstance(exc, anthropic.RateLimitError):
|
||||
return ProviderError("rate_limit", "anthropic", exc)
|
||||
if isinstance(exc, anthropic.AuthenticationError):
|
||||
@@ -276,9 +277,9 @@ def list_models(provider: str) -> list[str]:
|
||||
|
||||
|
||||
def _list_gemini_models(api_key: str) -> list[str]:
|
||||
# from google import genai # Removed
|
||||
|
||||
try:
|
||||
client = google.genai.Client(api_key=api_key)
|
||||
client = genai.Client(api_key=api_key)
|
||||
models = []
|
||||
for m in client.models.list():
|
||||
name = m.name
|
||||
@@ -292,7 +293,7 @@ def _list_gemini_models(api_key: str) -> list[str]:
|
||||
|
||||
|
||||
def _list_anthropic_models() -> list[str]:
|
||||
import anthropic
|
||||
|
||||
try:
|
||||
creds = _load_credentials()
|
||||
client = anthropic.Anthropic(api_key=creds["anthropic"]["api_key"])
|
||||
@@ -370,7 +371,7 @@ def _get_anthropic_tools() -> list[dict]:
|
||||
|
||||
|
||||
def _gemini_tool_declaration():
|
||||
# from google.genai import types # Removed
|
||||
|
||||
|
||||
declarations = []
|
||||
|
||||
@@ -380,15 +381,17 @@ def _gemini_tool_declaration():
|
||||
continue
|
||||
props = {}
|
||||
for pname, pdef in spec["parameters"].get("properties", {}).items():
|
||||
props[pname] = google.genai.types.Schema(
|
||||
type=google.genai.types.Type.STRING,
|
||||
ptype_str = pdef.get("type", "string").upper()
|
||||
ptype = getattr(types.Type, ptype_str, types.Type.STRING)
|
||||
props[pname] = types.Schema(
|
||||
type=ptype,
|
||||
description=pdef.get("description", ""),
|
||||
)
|
||||
declarations.append(google.genai.types.FunctionDeclaration(
|
||||
declarations.append(types.FunctionDeclaration(
|
||||
name=spec["name"],
|
||||
description=spec["description"],
|
||||
parameters=google.genai.types.Schema(
|
||||
type=google.genai.types.Type.OBJECT,
|
||||
parameters=types.Schema(
|
||||
type=types.Type.OBJECT,
|
||||
properties=props,
|
||||
required=spec["parameters"].get("required", []),
|
||||
),
|
||||
@@ -396,7 +399,7 @@ def _gemini_tool_declaration():
|
||||
|
||||
# PowerShell tool
|
||||
if _agent_tools.get(TOOL_NAME, True):
|
||||
declarations.append(google.genai.types.FunctionDeclaration(
|
||||
declarations.append(types.FunctionDeclaration(
|
||||
name=TOOL_NAME,
|
||||
description=(
|
||||
"Run a PowerShell script within the project base_dir. "
|
||||
@@ -404,11 +407,11 @@ def _gemini_tool_declaration():
|
||||
"The working directory is set to base_dir automatically. "
|
||||
"stdout and stderr are returned to you as the result."
|
||||
),
|
||||
parameters=google.genai.types.Schema(
|
||||
type=google.genai.types.Type.OBJECT,
|
||||
parameters=types.Schema(
|
||||
type=types.Type.OBJECT,
|
||||
properties={
|
||||
"script": google.genai.types.Schema(
|
||||
type=google.genai.types.Type.STRING,
|
||||
"script": types.Schema(
|
||||
type=types.Type.STRING,
|
||||
description="The PowerShell script to execute."
|
||||
)
|
||||
},
|
||||
@@ -416,7 +419,7 @@ def _gemini_tool_declaration():
|
||||
),
|
||||
))
|
||||
|
||||
return google.genai.types.Tool(function_declarations=declarations) if declarations else None
|
||||
return types.Tool(function_declarations=declarations) if declarations else None
|
||||
|
||||
|
||||
def _run_script(script: str, base_dir: str) -> str:
|
||||
@@ -511,9 +514,8 @@ def _content_block_to_dict(block) -> dict:
|
||||
def _ensure_gemini_client():
|
||||
global _gemini_client
|
||||
if _gemini_client is None:
|
||||
# from google import genai # Removed
|
||||
creds = _load_credentials()
|
||||
_gemini_client = google.genai.Client(api_key=creds["gemini"]["api_key"])
|
||||
_gemini_client = genai.Client(api_key=creds["gemini"]["api_key"])
|
||||
|
||||
|
||||
|
||||
@@ -530,7 +532,7 @@ def _get_gemini_history_list(chat):
|
||||
|
||||
def _send_gemini(md_content: str, user_message: str, base_dir: str, file_items: list[dict] | None = None) -> str:
|
||||
global _gemini_chat, _gemini_cache, _gemini_cache_md_hash, _gemini_cache_created_at
|
||||
# from google.genai import types # Removed
|
||||
|
||||
try:
|
||||
_ensure_gemini_client(); mcp_client.configure(file_items or [], [base_dir])
|
||||
sys_instr = f"{_get_combined_system_prompt()}\n\n<context>\n{md_content}\n</context>"
|
||||
@@ -563,29 +565,29 @@ def _send_gemini(md_content: str, user_message: str, base_dir: str, file_items:
|
||||
_append_comms("OUT", "request", {"message": f"[CACHE TTL] Rebuilding cache (expired after {int(elapsed)}s)..."})
|
||||
|
||||
if not _gemini_chat:
|
||||
chat_config = google.genai.types.GenerateContentConfig(
|
||||
chat_config = types.GenerateContentConfig(
|
||||
system_instruction=sys_instr,
|
||||
tools=tools_decl,
|
||||
temperature=_temperature,
|
||||
max_output_tokens=_max_tokens,
|
||||
safety_settings=[google.genai.types.SafetySetting(category="HARM_CATEGORY_DANGEROUS_CONTENT", threshold="BLOCK_ONLY_HIGH")]
|
||||
safety_settings=[types.SafetySetting(category="HARM_CATEGORY_DANGEROUS_CONTENT", threshold="BLOCK_ONLY_HIGH")]
|
||||
)
|
||||
try:
|
||||
# Gemini requires 1024 (Flash) or 4096 (Pro) tokens to cache.
|
||||
_gemini_cache = _gemini_client.caches.create(
|
||||
model=_model,
|
||||
config=google.genai.types.CreateCachedContentConfig(
|
||||
config=types.CreateCachedContentConfig(
|
||||
system_instruction=sys_instr,
|
||||
tools=tools_decl,
|
||||
ttl=f"{_GEMINI_CACHE_TTL}s",
|
||||
)
|
||||
)
|
||||
_gemini_cache_created_at = time.time()
|
||||
chat_config = google.genai.types.GenerateContentConfig(
|
||||
chat_config = types.GenerateContentConfig(
|
||||
cached_content=_gemini_cache.name,
|
||||
temperature=_temperature,
|
||||
max_output_tokens=_max_tokens,
|
||||
safety_settings=[google.genai.types.SafetySetting(category="HARM_CATEGORY_DANGEROUS_CONTENT", threshold="BLOCK_ONLY_HIGH")]
|
||||
safety_settings=[types.SafetySetting(category="HARM_CATEGORY_DANGEROUS_CONTENT", threshold="BLOCK_ONLY_HIGH")]
|
||||
)
|
||||
_append_comms("OUT", "request", {"message": f"[CACHE CREATED] {_gemini_cache.name}"})
|
||||
except Exception as e:
|
||||
@@ -857,9 +859,12 @@ def _trim_anthropic_history(system_blocks: list[dict], history: list[dict]):
|
||||
def _ensure_anthropic_client():
|
||||
global _anthropic_client
|
||||
if _anthropic_client is None:
|
||||
import anthropic
|
||||
creds = _load_credentials()
|
||||
_anthropic_client = anthropic.Anthropic(api_key=creds["anthropic"]["api_key"])
|
||||
# Enable prompt caching beta
|
||||
_anthropic_client = anthropic.Anthropic(
|
||||
api_key=creds["anthropic"]["api_key"],
|
||||
default_headers={"anthropic-beta": "prompt-caching-2024-07-31"}
|
||||
)
|
||||
|
||||
|
||||
def _chunk_text(text: str, chunk_size: int) -> list[str]:
|
||||
@@ -1187,9 +1192,27 @@ def get_history_bleed_stats() -> dict:
|
||||
"percentage": percentage,
|
||||
}
|
||||
elif _provider == "gemini":
|
||||
# For Gemini, token estimation is complex and handled by the server.
|
||||
# We don't have a reliable client-side estimate, so we return a
|
||||
# "not implemented" state for now.
|
||||
if _gemini_chat:
|
||||
try:
|
||||
_ensure_gemini_client()
|
||||
history = _get_gemini_history_list(_gemini_chat)
|
||||
if history:
|
||||
resp = _gemini_client.models.count_tokens(
|
||||
model=_model,
|
||||
contents=history
|
||||
)
|
||||
current_tokens = resp.total_tokens
|
||||
limit_tokens = _GEMINI_MAX_INPUT_TOKENS
|
||||
percentage = (current_tokens / limit_tokens) * 100 if limit_tokens > 0 else 0
|
||||
return {
|
||||
"provider": "gemini",
|
||||
"limit": limit_tokens,
|
||||
"current": current_tokens,
|
||||
"percentage": percentage,
|
||||
}
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return {
|
||||
"provider": "gemini",
|
||||
"limit": _GEMINI_MAX_INPUT_TOKENS,
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ This file tracks all major tracks for the project. Each track has its own detail
|
||||
|
||||
---
|
||||
|
||||
- [ ] **Track: Review project codebase, documentation related to project, and make sure agenti vendor apis are being used as properly stated by offical documentation from google for gemini and anthropic for claude.**
|
||||
- [x] **Track: Review project codebase, documentation related to project, and make sure agenti vendor apis are being used as properly stated by offical documentation from google for gemini and anthropic for claude.**
|
||||
*Link: [./tracks/api_vendor_alignment_20260223/](./tracks/api_vendor_alignment_20260223/)*
|
||||
|
||||
---
|
||||
|
||||
@@ -1,56 +1,56 @@
|
||||
# Implementation Plan: API Usage Audit and Alignment
|
||||
|
||||
## Phase 1: Research and Comprehensive Audit
|
||||
## Phase 1: Research and Comprehensive Audit [checkpoint: 5ec4283]
|
||||
Identify all points of interaction with AI SDKs and compare them with latest official documentation.
|
||||
|
||||
- [ ] Task: List and categorize all AI SDK usage in the project.
|
||||
- [ ] Search for all imports of `google.genai` and `anthropic`.
|
||||
- [ ] Document specific functions and methods being called.
|
||||
- [ ] Task: Research latest official documentation for `google-genai` and `anthropic` Python SDKs.
|
||||
- [ ] Verify latest patterns for Client initialization.
|
||||
- [ ] Verify latest patterns for Context/Prompt caching.
|
||||
- [ ] Verify latest patterns for Tool/Function calling.
|
||||
- [ ] Task: Conductor - User Manual Verification 'Phase 1: Research and Comprehensive Audit' (Protocol in workflow.md)
|
||||
- [x] Task: List and categorize all AI SDK usage in the project.
|
||||
- [x] Search for all imports of `google.genai` and `anthropic`.
|
||||
- [x] Document specific functions and methods being called.
|
||||
- [x] Task: Research latest official documentation for `google-genai` and `anthropic` Python SDKs.
|
||||
- [x] Verify latest patterns for Client initialization.
|
||||
- [x] Verify latest patterns for Context/Prompt caching.
|
||||
- [x] Verify latest patterns for Tool/Function calling.
|
||||
- [x] Task: Conductor - User Manual Verification 'Phase 1: Research and Comprehensive Audit' (Protocol in workflow.md)
|
||||
|
||||
## Phase 2: Gemini (google-genai) Alignment
|
||||
## Phase 2: Gemini (google-genai) Alignment [checkpoint: 842bfc4]
|
||||
Align Gemini integration with documented best practices.
|
||||
|
||||
- [ ] Task: Refactor Gemini Client and Chat initialization if needed.
|
||||
- [ ] Write Tests
|
||||
- [ ] Implement Feature
|
||||
- [ ] Task: Optimize Gemini Context Caching.
|
||||
- [ ] Write Tests
|
||||
- [ ] Implement Feature
|
||||
- [ ] Task: Align Gemini Tool Declaration and handling.
|
||||
- [ ] Write Tests
|
||||
- [ ] Implement Feature
|
||||
- [ ] Task: Conductor - User Manual Verification 'Phase 2: Gemini (google-genai) Alignment' (Protocol in workflow.md)
|
||||
- [x] Task: Refactor Gemini Client and Chat initialization if needed.
|
||||
- [x] Write Tests
|
||||
- [x] Implement Feature
|
||||
- [x] Task: Optimize Gemini Context Caching.
|
||||
- [x] Write Tests
|
||||
- [x] Implement Feature
|
||||
- [x] Task: Align Gemini Tool Declaration and handling.
|
||||
- [x] Write Tests
|
||||
- [x] Implement Feature
|
||||
- [x] Task: Conductor - User Manual Verification 'Phase 2: Gemini (google-genai) Alignment' (Protocol in workflow.md)
|
||||
|
||||
## Phase 3: Anthropic Alignment
|
||||
## Phase 3: Anthropic Alignment [checkpoint: f0eb538]
|
||||
Align Anthropic integration with documented best practices.
|
||||
|
||||
- [ ] Task: Refactor Anthropic Client and Message creation if needed.
|
||||
- [ ] Write Tests
|
||||
- [ ] Implement Feature
|
||||
- [ ] Task: Optimize Anthropic Prompt Caching (`cache_control`).
|
||||
- [ ] Write Tests
|
||||
- [ ] Implement Feature
|
||||
- [ ] Task: Align Anthropic Tool Declaration and handling.
|
||||
- [ ] Write Tests
|
||||
- [ ] Implement Feature
|
||||
- [ ] Task: Conductor - User Manual Verification 'Phase 3: Anthropic Alignment' (Protocol in workflow.md)
|
||||
- [x] Task: Refactor Anthropic Client and Message creation if needed.
|
||||
- [x] Write Tests
|
||||
- [x] Implement Feature
|
||||
- [x] Task: Optimize Anthropic Prompt Caching (`cache_control`).
|
||||
- [x] Write Tests
|
||||
- [x] Implement Feature
|
||||
- [x] Task: Align Anthropic Tool Declaration and handling.
|
||||
- [x] Write Tests
|
||||
- [x] Implement Feature
|
||||
- [x] Task: Conductor - User Manual Verification 'Phase 3: Anthropic Alignment' (Protocol in workflow.md)
|
||||
|
||||
## Phase 4: History and Token Management
|
||||
## Phase 4: History and Token Management [checkpoint: 0f9f235]
|
||||
Ensure accurate token estimation and robust history handling.
|
||||
|
||||
- [ ] Task: Review and align token estimation logic for both providers.
|
||||
- [ ] Write Tests
|
||||
- [ ] Implement Feature
|
||||
- [ ] Task: Audit message history truncation and context window management.
|
||||
- [ ] Write Tests
|
||||
- [ ] Implement Feature
|
||||
- [ ] Task: Conductor - User Manual Verification 'Phase 4: History and Token Management' (Protocol in workflow.md)
|
||||
- [x] Task: Review and align token estimation logic for both providers.
|
||||
- [x] Write Tests
|
||||
- [x] Implement Feature
|
||||
- [x] Task: Audit message history truncation and context window management.
|
||||
- [x] Write Tests
|
||||
- [x] Implement Feature
|
||||
- [x] Task: Conductor - User Manual Verification 'Phase 4: History and Token Management' (Protocol in workflow.md)
|
||||
|
||||
## Phase 5: Final Validation and Cleanup
|
||||
- [ ] Task: Perform a full test run using `run_tests.py` to ensure 100% pass rate.
|
||||
- [ ] Task: Conductor - User Manual Verification 'Phase 5: Final Validation and Cleanup' (Protocol in workflow.md)
|
||||
## Phase 5: Final Validation and Cleanup [checkpoint: e9126b4]
|
||||
- [x] Task: Perform a full test run using `run_tests.py` to ensure 100% pass rate.
|
||||
- [x] Task: Conductor - User Manual Verification 'Phase 5: Final Validation and Cleanup' (Protocol in workflow.md)
|
||||
|
||||
Reference in New Issue
Block a user