code-puppy 0.0.365__py3-none-any.whl → 0.0.367__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.
- code_puppy/gemini_model.py +706 -0
- code_puppy/http_utils.py +6 -3
- code_puppy/model_factory.py +42 -16
- code_puppy/plugins/antigravity_oauth/antigravity_model.py +128 -165
- code_puppy/plugins/antigravity_oauth/transport.py +235 -45
- {code_puppy-0.0.365.dist-info → code_puppy-0.0.367.dist-info}/METADATA +3 -3
- {code_puppy-0.0.365.dist-info → code_puppy-0.0.367.dist-info}/RECORD +12 -11
- {code_puppy-0.0.365.data → code_puppy-0.0.367.data}/data/code_puppy/models.json +0 -0
- {code_puppy-0.0.365.data → code_puppy-0.0.367.data}/data/code_puppy/models_dev_api.json +0 -0
- {code_puppy-0.0.365.dist-info → code_puppy-0.0.367.dist-info}/WHEEL +0 -0
- {code_puppy-0.0.365.dist-info → code_puppy-0.0.367.dist-info}/entry_points.txt +0 -0
- {code_puppy-0.0.365.dist-info → code_puppy-0.0.367.dist-info}/licenses/LICENSE +0 -0
|
@@ -23,20 +23,78 @@ from .constants import (
|
|
|
23
23
|
logger = logging.getLogger(__name__)
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
def
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
def _flatten_union_to_object(union_items: list, defs: dict, resolve_fn) -> dict:
|
|
27
|
+
"""Flatten a union of object types into a single object with all properties.
|
|
28
|
+
|
|
29
|
+
For discriminated unions like EditFilePayload (ContentPayload | ReplacementsPayload | DeleteSnippetPayload),
|
|
30
|
+
we merge all object types into one with all properties marked as optional.
|
|
31
|
+
"""
|
|
32
|
+
merged_properties = {}
|
|
33
|
+
has_string_type = False
|
|
34
|
+
|
|
35
|
+
for item in union_items:
|
|
36
|
+
if not isinstance(item, dict):
|
|
37
|
+
continue
|
|
38
|
+
|
|
39
|
+
# Resolve $ref first
|
|
40
|
+
if "$ref" in item:
|
|
41
|
+
ref_path = item["$ref"]
|
|
42
|
+
ref_name = None
|
|
43
|
+
if ref_path.startswith("#/$defs/"):
|
|
44
|
+
ref_name = ref_path[8:]
|
|
45
|
+
elif ref_path.startswith("#/definitions/"):
|
|
46
|
+
ref_name = ref_path[14:]
|
|
47
|
+
if ref_name and ref_name in defs:
|
|
48
|
+
item = copy.deepcopy(defs[ref_name])
|
|
49
|
+
else:
|
|
50
|
+
continue
|
|
51
|
+
|
|
52
|
+
# Check for string type (common fallback)
|
|
53
|
+
if item.get("type") == "string":
|
|
54
|
+
has_string_type = True
|
|
55
|
+
continue
|
|
56
|
+
|
|
57
|
+
# Skip null types
|
|
58
|
+
if item.get("type") == "null":
|
|
59
|
+
continue
|
|
60
|
+
|
|
61
|
+
# Merge properties from object types
|
|
62
|
+
if item.get("type") == "object" or "properties" in item:
|
|
63
|
+
props = item.get("properties", {})
|
|
64
|
+
for prop_name, prop_schema in props.items():
|
|
65
|
+
if prop_name not in merged_properties:
|
|
66
|
+
# Resolve the property schema
|
|
67
|
+
merged_properties[prop_name] = resolve_fn(
|
|
68
|
+
copy.deepcopy(prop_schema)
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
if not merged_properties:
|
|
72
|
+
# No object properties found, return string type as fallback
|
|
73
|
+
return {"type": "string"} if has_string_type else {"type": "object"}
|
|
74
|
+
|
|
75
|
+
# Build merged object - no required fields since any subset is valid
|
|
76
|
+
result = {
|
|
77
|
+
"type": "object",
|
|
78
|
+
"properties": merged_properties,
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return result
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def _inline_refs(schema: dict, simplify_unions: bool = False) -> dict:
|
|
29
85
|
"""Inline $ref references and transform schema for Antigravity compatibility.
|
|
30
86
|
|
|
31
87
|
- Inlines $ref references
|
|
32
88
|
- Removes $defs, definitions, $schema, $id
|
|
33
|
-
- Optionally converts anyOf/oneOf/allOf to any_of/one_of/all_of (only for Gemini)
|
|
34
89
|
- Removes unsupported fields like 'default', 'examples', 'const'
|
|
35
|
-
-
|
|
90
|
+
- When simplify_unions=True: flattens anyOf/oneOf unions:
|
|
91
|
+
- For unions of objects: merges into single object with all properties
|
|
92
|
+
- For simple unions (string | null): picks first non-null type
|
|
93
|
+
(required for both Gemini AND Claude - neither supports union types in function schemas!)
|
|
36
94
|
|
|
37
95
|
Args:
|
|
38
|
-
|
|
39
|
-
|
|
96
|
+
simplify_unions: If True, simplify anyOf/oneOf unions.
|
|
97
|
+
Required for Gemini and Claude models.
|
|
40
98
|
"""
|
|
41
99
|
if not isinstance(schema, dict):
|
|
42
100
|
return schema
|
|
@@ -47,31 +105,73 @@ def _inline_refs(
|
|
|
47
105
|
# Extract $defs for reference resolution
|
|
48
106
|
defs = schema.pop("$defs", schema.pop("definitions", {}))
|
|
49
107
|
|
|
50
|
-
def resolve_refs(
|
|
51
|
-
obj, convert_unions=convert_unions, simplify_for_claude=simplify_for_claude
|
|
52
|
-
):
|
|
108
|
+
def resolve_refs(obj, simplify_unions=simplify_unions):
|
|
53
109
|
"""Recursively resolve $ref references and transform schema."""
|
|
54
110
|
if isinstance(obj, dict):
|
|
55
|
-
#
|
|
56
|
-
if
|
|
111
|
+
# Handle anyOf/oneOf unions
|
|
112
|
+
if simplify_unions:
|
|
57
113
|
for union_key in ["anyOf", "oneOf"]:
|
|
58
114
|
if union_key in obj:
|
|
59
115
|
union = obj[union_key]
|
|
60
116
|
if isinstance(union, list):
|
|
61
|
-
#
|
|
117
|
+
# Check if this is a complex union of objects (discriminated union)
|
|
118
|
+
# vs a simple nullable type (string | null)
|
|
119
|
+
object_count = 0
|
|
120
|
+
has_refs = False
|
|
121
|
+
for item in union:
|
|
122
|
+
if isinstance(item, dict):
|
|
123
|
+
if "$ref" in item:
|
|
124
|
+
has_refs = True
|
|
125
|
+
object_count += 1
|
|
126
|
+
elif (
|
|
127
|
+
item.get("type") == "object"
|
|
128
|
+
or "properties" in item
|
|
129
|
+
):
|
|
130
|
+
object_count += 1
|
|
131
|
+
|
|
132
|
+
# If multiple objects or has refs, flatten to single object
|
|
133
|
+
if object_count > 1 or has_refs:
|
|
134
|
+
flattened = _flatten_union_to_object(
|
|
135
|
+
union, defs, resolve_refs
|
|
136
|
+
)
|
|
137
|
+
# Keep description if present
|
|
138
|
+
if "description" in obj:
|
|
139
|
+
flattened["description"] = obj["description"]
|
|
140
|
+
return flattened
|
|
141
|
+
|
|
142
|
+
# Simple union - pick first non-null type
|
|
62
143
|
for item in union:
|
|
63
144
|
if (
|
|
64
145
|
isinstance(item, dict)
|
|
65
146
|
and item.get("type") != "null"
|
|
66
147
|
):
|
|
67
|
-
# Replace the whole object with this type
|
|
68
148
|
result = dict(item)
|
|
69
|
-
# Keep description if present
|
|
70
149
|
if "description" in obj:
|
|
71
150
|
result["description"] = obj["description"]
|
|
72
|
-
return resolve_refs(
|
|
73
|
-
|
|
74
|
-
|
|
151
|
+
return resolve_refs(result, simplify_unions)
|
|
152
|
+
|
|
153
|
+
# Also handle allOf by merging all schemas
|
|
154
|
+
if simplify_unions and "allOf" in obj:
|
|
155
|
+
all_of = obj["allOf"]
|
|
156
|
+
if isinstance(all_of, list):
|
|
157
|
+
merged = {}
|
|
158
|
+
merged_properties = {}
|
|
159
|
+
for item in all_of:
|
|
160
|
+
if isinstance(item, dict):
|
|
161
|
+
resolved_item = resolve_refs(item, simplify_unions)
|
|
162
|
+
# Deep merge properties dicts
|
|
163
|
+
if "properties" in resolved_item:
|
|
164
|
+
merged_properties.update(
|
|
165
|
+
resolved_item.pop("properties")
|
|
166
|
+
)
|
|
167
|
+
merged.update(resolved_item)
|
|
168
|
+
if merged_properties:
|
|
169
|
+
merged["properties"] = merged_properties
|
|
170
|
+
# Keep other fields from original object (except allOf)
|
|
171
|
+
for k, v in obj.items():
|
|
172
|
+
if k != "allOf":
|
|
173
|
+
merged[k] = v
|
|
174
|
+
return resolve_refs(merged, simplify_unions)
|
|
75
175
|
|
|
76
176
|
# Check for $ref
|
|
77
177
|
if "$ref" in obj:
|
|
@@ -111,34 +211,23 @@ def _inline_refs(
|
|
|
111
211
|
):
|
|
112
212
|
continue
|
|
113
213
|
|
|
114
|
-
#
|
|
115
|
-
if
|
|
214
|
+
# Skip additionalProperties (not supported by Gemini or Claude)
|
|
215
|
+
if simplify_unions and key == "additionalProperties":
|
|
116
216
|
continue
|
|
117
217
|
|
|
118
|
-
#
|
|
119
|
-
|
|
120
|
-
if
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
new_key = "one_of"
|
|
125
|
-
elif key == "allOf":
|
|
126
|
-
new_key = "all_of"
|
|
127
|
-
elif key == "additionalProperties":
|
|
128
|
-
new_key = "additional_properties"
|
|
129
|
-
|
|
130
|
-
result[new_key] = resolve_refs(
|
|
131
|
-
value, convert_unions, simplify_for_claude
|
|
132
|
-
)
|
|
218
|
+
# Skip any remaining union type keys that weren't simplified above
|
|
219
|
+
# (This shouldn't happen normally, but just in case)
|
|
220
|
+
if simplify_unions and key in ("anyOf", "oneOf", "allOf"):
|
|
221
|
+
continue
|
|
222
|
+
|
|
223
|
+
result[key] = resolve_refs(value, simplify_unions)
|
|
133
224
|
return result
|
|
134
225
|
elif isinstance(obj, list):
|
|
135
|
-
return [
|
|
136
|
-
resolve_refs(item, convert_unions, simplify_for_claude) for item in obj
|
|
137
|
-
]
|
|
226
|
+
return [resolve_refs(item, simplify_unions) for item in obj]
|
|
138
227
|
else:
|
|
139
228
|
return obj
|
|
140
229
|
|
|
141
|
-
return resolve_refs(schema,
|
|
230
|
+
return resolve_refs(schema, simplify_unions)
|
|
142
231
|
|
|
143
232
|
|
|
144
233
|
class UnwrappedResponse(httpx.Response):
|
|
@@ -264,17 +353,91 @@ class UnwrappedSSEResponse(httpx.Response):
|
|
|
264
353
|
|
|
265
354
|
|
|
266
355
|
class AntigravityClient(httpx.AsyncClient):
|
|
267
|
-
"""Custom httpx client that handles Antigravity request/response wrapping.
|
|
356
|
+
"""Custom httpx client that handles Antigravity request/response wrapping.
|
|
357
|
+
|
|
358
|
+
Supports proactive token refresh to prevent expiry during long sessions.
|
|
359
|
+
"""
|
|
268
360
|
|
|
269
361
|
def __init__(
|
|
270
362
|
self,
|
|
271
363
|
project_id: str = "",
|
|
272
364
|
model_name: str = "",
|
|
365
|
+
refresh_token: str = "",
|
|
366
|
+
expires_at: Optional[float] = None,
|
|
367
|
+
on_token_refreshed: Optional[Any] = None,
|
|
273
368
|
**kwargs: Any,
|
|
274
369
|
):
|
|
275
370
|
super().__init__(**kwargs)
|
|
276
371
|
self.project_id = project_id
|
|
277
372
|
self.model_name = model_name
|
|
373
|
+
self._refresh_token = refresh_token
|
|
374
|
+
self._expires_at = expires_at
|
|
375
|
+
self._on_token_refreshed = on_token_refreshed
|
|
376
|
+
self._refresh_lock = None # Lazy init for async lock
|
|
377
|
+
|
|
378
|
+
async def _ensure_valid_token(self) -> None:
|
|
379
|
+
"""Proactively refresh the access token if it's expired or about to expire.
|
|
380
|
+
|
|
381
|
+
This prevents 401 errors during long-running sessions by checking and
|
|
382
|
+
refreshing the token BEFORE making requests, not after they fail.
|
|
383
|
+
"""
|
|
384
|
+
import asyncio
|
|
385
|
+
|
|
386
|
+
from .token import is_token_expired, refresh_access_token
|
|
387
|
+
|
|
388
|
+
# Skip if no refresh token configured
|
|
389
|
+
if not self._refresh_token:
|
|
390
|
+
return
|
|
391
|
+
|
|
392
|
+
# Check if token needs refresh (includes 60-second buffer)
|
|
393
|
+
if not is_token_expired(self._expires_at):
|
|
394
|
+
return
|
|
395
|
+
|
|
396
|
+
# Lazy init the async lock
|
|
397
|
+
if self._refresh_lock is None:
|
|
398
|
+
self._refresh_lock = asyncio.Lock()
|
|
399
|
+
|
|
400
|
+
async with self._refresh_lock:
|
|
401
|
+
# Double-check after acquiring lock (another coroutine may have refreshed)
|
|
402
|
+
if not is_token_expired(self._expires_at):
|
|
403
|
+
return
|
|
404
|
+
|
|
405
|
+
logger.debug("Proactively refreshing Antigravity access token...")
|
|
406
|
+
|
|
407
|
+
try:
|
|
408
|
+
# Run the synchronous refresh in a thread pool to avoid blocking
|
|
409
|
+
loop = asyncio.get_event_loop()
|
|
410
|
+
new_tokens = await loop.run_in_executor(
|
|
411
|
+
None, refresh_access_token, self._refresh_token
|
|
412
|
+
)
|
|
413
|
+
|
|
414
|
+
if new_tokens:
|
|
415
|
+
# Update internal state
|
|
416
|
+
new_access_token = new_tokens.access_token
|
|
417
|
+
self._expires_at = new_tokens.expires_at
|
|
418
|
+
self._refresh_token = new_tokens.refresh_token
|
|
419
|
+
|
|
420
|
+
# Update the Authorization header
|
|
421
|
+
self.headers["Authorization"] = f"Bearer {new_access_token}"
|
|
422
|
+
|
|
423
|
+
logger.info(
|
|
424
|
+
"Proactively refreshed Antigravity token (expires in %ds)",
|
|
425
|
+
int(self._expires_at - __import__("time").time()),
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
# Notify callback (e.g., to persist updated tokens)
|
|
429
|
+
if self._on_token_refreshed:
|
|
430
|
+
try:
|
|
431
|
+
self._on_token_refreshed(new_tokens)
|
|
432
|
+
except Exception as e:
|
|
433
|
+
logger.warning("Token refresh callback failed: %s", e)
|
|
434
|
+
else:
|
|
435
|
+
logger.warning(
|
|
436
|
+
"Failed to proactively refresh token - request may fail with 401"
|
|
437
|
+
)
|
|
438
|
+
|
|
439
|
+
except Exception as e:
|
|
440
|
+
logger.warning("Proactive token refresh error: %s", e)
|
|
278
441
|
|
|
279
442
|
def _wrap_request(self, content: bytes, url: str) -> tuple[bytes, str, str, bool]:
|
|
280
443
|
"""Wrap request body in Antigravity envelope and transform URL.
|
|
@@ -331,15 +494,14 @@ class AntigravityClient(httpx.AsyncClient):
|
|
|
331
494
|
)
|
|
332
495
|
|
|
333
496
|
# Inline $refs and remove $defs from parameters
|
|
334
|
-
#
|
|
335
|
-
#
|
|
497
|
+
# Simplify union types (anyOf/oneOf/allOf) for BOTH Gemini and Claude
|
|
498
|
+
# Neither API supports union types in function schemas!
|
|
336
499
|
if "parameters" in func_decl:
|
|
337
500
|
is_gemini = "gemini" in model.lower()
|
|
338
501
|
is_claude = "claude" in model.lower()
|
|
339
502
|
func_decl["parameters"] = _inline_refs(
|
|
340
503
|
func_decl["parameters"],
|
|
341
|
-
|
|
342
|
-
simplify_for_claude=is_claude,
|
|
504
|
+
simplify_unions=(is_gemini or is_claude),
|
|
343
505
|
)
|
|
344
506
|
|
|
345
507
|
# Fix generationConfig for Antigravity compatibility
|
|
@@ -425,6 +587,9 @@ class AntigravityClient(httpx.AsyncClient):
|
|
|
425
587
|
"""Override send to intercept at the lowest level with endpoint fallback."""
|
|
426
588
|
import asyncio
|
|
427
589
|
|
|
590
|
+
# Proactively refresh token BEFORE making the request
|
|
591
|
+
await self._ensure_valid_token()
|
|
592
|
+
|
|
428
593
|
# Transform POST requests to Antigravity format
|
|
429
594
|
if request.method == "POST" and request.content:
|
|
430
595
|
new_content, new_path, new_query, is_claude_thinking = self._wrap_request(
|
|
@@ -638,14 +803,36 @@ class AntigravityClient(httpx.AsyncClient):
|
|
|
638
803
|
return None
|
|
639
804
|
|
|
640
805
|
|
|
806
|
+
# Type alias for token refresh callback
|
|
807
|
+
TokenRefreshCallback = Any # Callable[[OAuthTokens], None]
|
|
808
|
+
|
|
809
|
+
|
|
641
810
|
def create_antigravity_client(
|
|
642
811
|
access_token: str,
|
|
643
812
|
project_id: str = "",
|
|
644
813
|
model_name: str = "",
|
|
645
814
|
base_url: str = "https://daily-cloudcode-pa.sandbox.googleapis.com",
|
|
646
815
|
headers: Optional[Dict[str, str]] = None,
|
|
816
|
+
refresh_token: str = "",
|
|
817
|
+
expires_at: Optional[float] = None,
|
|
818
|
+
on_token_refreshed: Optional[TokenRefreshCallback] = None,
|
|
647
819
|
) -> AntigravityClient:
|
|
648
|
-
"""Create an httpx client configured for Antigravity API.
|
|
820
|
+
"""Create an httpx client configured for Antigravity API.
|
|
821
|
+
|
|
822
|
+
Args:
|
|
823
|
+
access_token: The OAuth access token for authentication
|
|
824
|
+
project_id: The GCP project ID
|
|
825
|
+
model_name: The model name being used
|
|
826
|
+
base_url: The API base URL
|
|
827
|
+
headers: Additional headers to include
|
|
828
|
+
refresh_token: The OAuth refresh token for proactive token refresh
|
|
829
|
+
expires_at: Unix timestamp when the access token expires
|
|
830
|
+
on_token_refreshed: Callback called when token is proactively refreshed,
|
|
831
|
+
receives OAuthTokens object to persist the new tokens
|
|
832
|
+
|
|
833
|
+
Returns:
|
|
834
|
+
An AntigravityClient configured for API requests with proactive token refresh
|
|
835
|
+
"""
|
|
649
836
|
# Start with Antigravity-specific headers
|
|
650
837
|
default_headers = {
|
|
651
838
|
"Authorization": f"Bearer {access_token}",
|
|
@@ -659,6 +846,9 @@ def create_antigravity_client(
|
|
|
659
846
|
return AntigravityClient(
|
|
660
847
|
project_id=project_id,
|
|
661
848
|
model_name=model_name,
|
|
849
|
+
refresh_token=refresh_token,
|
|
850
|
+
expires_at=expires_at,
|
|
851
|
+
on_token_refreshed=on_token_refreshed,
|
|
662
852
|
base_url=base_url,
|
|
663
853
|
headers=default_headers,
|
|
664
854
|
timeout=httpx.Timeout(180.0, connect=30.0),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-puppy
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.367
|
|
4
4
|
Summary: Code generation agent
|
|
5
5
|
Project-URL: repository, https://github.com/mpfaffenberger/code_puppy
|
|
6
6
|
Project-URL: HomePage, https://github.com/mpfaffenberger/code_puppy
|
|
@@ -17,7 +17,6 @@ Classifier: Topic :: Software Development :: Code Generators
|
|
|
17
17
|
Requires-Python: <3.14,>=3.11
|
|
18
18
|
Requires-Dist: dbos>=2.5.0
|
|
19
19
|
Requires-Dist: fastapi>=0.109.0
|
|
20
|
-
Requires-Dist: google-genai>=1.20.0
|
|
21
20
|
Requires-Dist: httpx[http2]>=0.24.1
|
|
22
21
|
Requires-Dist: json-repair>=0.46.2
|
|
23
22
|
Requires-Dist: mcp>=1.9.4
|
|
@@ -25,11 +24,12 @@ Requires-Dist: openai>=1.99.1
|
|
|
25
24
|
Requires-Dist: pillow>=10.0.0
|
|
26
25
|
Requires-Dist: playwright>=1.40.0
|
|
27
26
|
Requires-Dist: prompt-toolkit>=3.0.52
|
|
28
|
-
Requires-Dist: pydantic-ai-slim[anthropic,
|
|
27
|
+
Requires-Dist: pydantic-ai-slim[anthropic,openai]==1.26.0
|
|
29
28
|
Requires-Dist: pydantic>=2.4.0
|
|
30
29
|
Requires-Dist: pyfiglet>=0.8.post1
|
|
31
30
|
Requires-Dist: python-dotenv>=1.0.0
|
|
32
31
|
Requires-Dist: rapidfuzz>=3.13.0
|
|
32
|
+
Requires-Dist: requests>=2.28.0
|
|
33
33
|
Requires-Dist: rich>=13.4.2
|
|
34
34
|
Requires-Dist: ripgrep==14.1.0
|
|
35
35
|
Requires-Dist: tenacity>=8.2.0
|
|
@@ -7,10 +7,11 @@ code_puppy/cli_runner.py,sha256=w5CLKgQYYaT7My3Cga2StXYol-u6DBxNzzUuhhsfhsA,3495
|
|
|
7
7
|
code_puppy/config.py,sha256=blowBU3bBOdQSuLYKBUrb7f7CxHH_e25a_A4lQGsjgk,53494
|
|
8
8
|
code_puppy/error_logging.py,sha256=a80OILCUtJhexI6a9GM-r5LqIdjvSRzggfgPp2jv1X0,3297
|
|
9
9
|
code_puppy/gemini_code_assist.py,sha256=KGS7sO5OLc83nDF3xxS-QiU6vxW9vcm6hmzilu79Ef8,13867
|
|
10
|
-
code_puppy/
|
|
10
|
+
code_puppy/gemini_model.py,sha256=i8XXmx9s1eWEXpJ8U288w0yayTt6Nq8V-hxpUHhti4s,25984
|
|
11
|
+
code_puppy/http_utils.py,sha256=SAH6EOdbR6Cbfmi-4EtHDqRDBUV5bWtGc-5nr44F0Is,10418
|
|
11
12
|
code_puppy/keymap.py,sha256=IvMkTlB_bIqOWpbTpmftkdyjhtD5todXuEIw1zCZ4u0,3584
|
|
12
13
|
code_puppy/main.py,sha256=82r3vZy_XcyEsenLn82BnUusaoyL3Bpm_Th_jKgqecE,273
|
|
13
|
-
code_puppy/model_factory.py,sha256=
|
|
14
|
+
code_puppy/model_factory.py,sha256=854Bo8wx59dOirAMhH0YuSXVHs-IxQBT_yrJGyVjKcA,39924
|
|
14
15
|
code_puppy/model_utils.py,sha256=55TKNnGTXQlHJNqejL2PfQqQmChXfzOjJg-hlarfR7w,5551
|
|
15
16
|
code_puppy/models.json,sha256=FMQdE_yvP_8y0xxt3K918UkFL9cZMYAqW1SfXcQkU_k,3105
|
|
16
17
|
code_puppy/models_dev_api.json,sha256=wHjkj-IM_fx1oHki6-GqtOoCrRMR0ScK0f-Iz0UEcy8,548187
|
|
@@ -147,7 +148,7 @@ code_puppy/plugins/__init__.py,sha256=gWgrXWoFpl-3Mxz2DAvxKW6SkCWrOnw-hKsY9O7nHc
|
|
|
147
148
|
code_puppy/plugins/oauth_puppy_html.py,sha256=Wpa-V_NlRiBAvo_OXHuR7wvOH_jSt8L9HSFGiab6xI0,13058
|
|
148
149
|
code_puppy/plugins/antigravity_oauth/__init__.py,sha256=1miHihSqRNXO20Vh_Gn9M3Aa2szh0gtdSCaKKj9nq0Q,362
|
|
149
150
|
code_puppy/plugins/antigravity_oauth/accounts.py,sha256=GQit2-K24bsopmTZyscFUq3M0cAEO5WutHWnipVdgz8,14304
|
|
150
|
-
code_puppy/plugins/antigravity_oauth/antigravity_model.py,sha256=
|
|
151
|
+
code_puppy/plugins/antigravity_oauth/antigravity_model.py,sha256=ZFarvPYgYixQxEmEylIIbsSl7fmL8bYD8RXL_9wzDRA,26281
|
|
151
152
|
code_puppy/plugins/antigravity_oauth/config.py,sha256=BoQgqf5I2XoHWnBBo9vhCIc_XwPj9Mbp0Z95ygWwt78,1362
|
|
152
153
|
code_puppy/plugins/antigravity_oauth/constants.py,sha256=qsrA10JJvzNuY0OobvvwCQcoGpILBninllcUUMKkUrQ,4644
|
|
153
154
|
code_puppy/plugins/antigravity_oauth/oauth.py,sha256=ZHXJtZP63l6brOpX1WdLfuUClIleA79-4y36YUJc6Wo,15137
|
|
@@ -155,7 +156,7 @@ code_puppy/plugins/antigravity_oauth/register_callbacks.py,sha256=uKIvfzH-dXj1g_
|
|
|
155
156
|
code_puppy/plugins/antigravity_oauth/storage.py,sha256=LW1DkY6Z-GRbBDrIitT6glKemZptp3NzldIrLRqTAK0,8971
|
|
156
157
|
code_puppy/plugins/antigravity_oauth/test_plugin.py,sha256=n0kjFG8Vt2n1j0GgTRSdSyhF0t9xxE8Ht60SH5CSwzw,11027
|
|
157
158
|
code_puppy/plugins/antigravity_oauth/token.py,sha256=WbiFCkrZvChpGXvwIYsJMgqU9xdJ81KwR062lFlnL3U,5038
|
|
158
|
-
code_puppy/plugins/antigravity_oauth/transport.py,sha256=
|
|
159
|
+
code_puppy/plugins/antigravity_oauth/transport.py,sha256=XgeG2Ys_Ui0_9cnrYWN7nENehFv76Rr2_QPAcIbPROI,35723
|
|
159
160
|
code_puppy/plugins/antigravity_oauth/utils.py,sha256=mXHRv0l07r27VjtSsIy9rlpkUheP88RaM4x4M0O1mMY,5401
|
|
160
161
|
code_puppy/plugins/chatgpt_oauth/__init__.py,sha256=Kjc6Hsz1sWvMD2OdAlWZvJRiKJSj4fx22boa-aVFKjA,189
|
|
161
162
|
code_puppy/plugins/chatgpt_oauth/config.py,sha256=H_wAH9Duyn8WH2Kq8oe72uda-_4qu1uXLPun_SDdtsk,2023
|
|
@@ -207,10 +208,10 @@ code_puppy/tools/browser/chromium_terminal_manager.py,sha256=w1thQ_ACb6oV45L93TS
|
|
|
207
208
|
code_puppy/tools/browser/terminal_command_tools.py,sha256=9byOZku-dwvTtCl532xt7Lumed_jTn0sLvUe_X75XCQ,19068
|
|
208
209
|
code_puppy/tools/browser/terminal_screenshot_tools.py,sha256=J_21YO_495NvYgNFu9KQP6VYg2K_f8CtSdZuF94Yhnw,18448
|
|
209
210
|
code_puppy/tools/browser/terminal_tools.py,sha256=F5LjVH3udSCFHmqC3O1UJLoLozZFZsEdX42jOmkqkW0,17853
|
|
210
|
-
code_puppy-0.0.
|
|
211
|
-
code_puppy-0.0.
|
|
212
|
-
code_puppy-0.0.
|
|
213
|
-
code_puppy-0.0.
|
|
214
|
-
code_puppy-0.0.
|
|
215
|
-
code_puppy-0.0.
|
|
216
|
-
code_puppy-0.0.
|
|
211
|
+
code_puppy-0.0.367.data/data/code_puppy/models.json,sha256=FMQdE_yvP_8y0xxt3K918UkFL9cZMYAqW1SfXcQkU_k,3105
|
|
212
|
+
code_puppy-0.0.367.data/data/code_puppy/models_dev_api.json,sha256=wHjkj-IM_fx1oHki6-GqtOoCrRMR0ScK0f-Iz0UEcy8,548187
|
|
213
|
+
code_puppy-0.0.367.dist-info/METADATA,sha256=fgyQYowvJcFxYCStXVQwHncMqvLo1JBztvtaAl2U7Yg,27600
|
|
214
|
+
code_puppy-0.0.367.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
215
|
+
code_puppy-0.0.367.dist-info/entry_points.txt,sha256=Tp4eQC99WY3HOKd3sdvb22vZODRq0XkZVNpXOag_KdI,91
|
|
216
|
+
code_puppy-0.0.367.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
|
|
217
|
+
code_puppy-0.0.367.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|