forked from Alishahryar1/free-claude-code
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprovider.py
More file actions
89 lines (80 loc) · 3 KB
/
Copy pathprovider.py
File metadata and controls
89 lines (80 loc) · 3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
"""Shared Google behavior for OpenAI-compatible Gemini endpoints."""
from collections.abc import Mapping
from copy import deepcopy
from typing import Any
from free_claude_code.core.inference import InferenceRequest
from free_claude_code.core.reasoning import (
DEFAULT_REASONING_POLICY,
ReasoningPolicy,
)
from free_claude_code.providers.admission import ProviderAdmissionController
from free_claude_code.providers.base import ProviderConfig
from free_claude_code.providers.openai_chat import (
OpenAIAsyncCredentialProvider,
OpenAIChatProfile,
OpenAIChatProvider,
build_openai_chat_request_body,
)
from free_claude_code.providers.openai_compat import (
OpenAIToolNameCodec,
openai_replay_scope,
)
from .thought_signatures import apply_google_thought_signatures
_MAX_TOOL_CALL_EXTRA_CONTENT_CACHE = 4096
class GoogleOpenAIProvider(OpenAIChatProvider):
"""Shared thought-signature and request behavior for Google Gemini APIs."""
def __init__(
self,
config: ProviderConfig,
*,
profile: OpenAIChatProfile,
admission: ProviderAdmissionController,
api_key_provider: OpenAIAsyncCredentialProvider | None = None,
default_headers: Mapping[str, str] | None = None,
) -> None:
super().__init__(
config,
profile=profile,
admission=admission,
api_key_provider=api_key_provider,
default_headers=default_headers,
)
self._tool_call_extra_content_by_id: dict[str, dict[str, Any]] = {}
def _record_tool_call_extra_content(
self, tool_call_id: str, extra_content: dict[str, Any]
) -> None:
if (
tool_call_id not in self._tool_call_extra_content_by_id
and len(self._tool_call_extra_content_by_id)
>= _MAX_TOOL_CALL_EXTRA_CONTENT_CACHE
):
self._tool_call_extra_content_by_id.pop(
next(iter(self._tool_call_extra_content_by_id))
)
self._tool_call_extra_content_by_id[tool_call_id] = deepcopy(extra_content)
def _build_request_body(
self,
request: InferenceRequest,
*,
provider_model: str,
reasoning: ReasoningPolicy = DEFAULT_REASONING_POLICY,
) -> dict[str, Any]:
return build_openai_chat_request_body(
request,
provider_model=provider_model,
reasoning=reasoning,
policy=self._profile.request_policy,
tool_names=OpenAIToolNameCodec.from_request(request),
replay_scope=openai_replay_scope(
self._provider_name,
provider_model,
replay_format="chat-completions",
),
postprocessors=(
lambda body, _request_data, _policy: apply_google_thought_signatures(
body,
tool_call_extra_content_by_id=(self._tool_call_extra_content_by_id),
),
*self._profile.request_postprocessors,
),
)