glacis 0.1.0__py3-none-any.whl → 0.1.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.
- glacis/__init__.py +1 -1
- glacis/__main__.py +30 -16
- glacis/client.py +16 -41
- glacis/integrations/anthropic.py +2 -2
- glacis/integrations/openai.py +1 -1
- glacis/models.py +1 -1
- glacis/storage.py +9 -4
- glacis/streaming.py +5 -6
- glacis/wasm_runtime.py +9 -6
- {glacis-0.1.0.dist-info → glacis-0.1.1.dist-info}/METADATA +1 -1
- glacis-0.1.1.dist-info/RECORD +16 -0
- glacis-0.1.0.dist-info/RECORD +0 -16
- {glacis-0.1.0.dist-info → glacis-0.1.1.dist-info}/WHEEL +0 -0
- {glacis-0.1.0.dist-info → glacis-0.1.1.dist-info}/licenses/LICENSE +0 -0
glacis/__init__.py
CHANGED
|
@@ -33,7 +33,7 @@ Streaming Example:
|
|
|
33
33
|
>>> session = await StreamingSession.start(glacis, {
|
|
34
34
|
... "service_id": "voice-assistant",
|
|
35
35
|
... "operation_type": "completion",
|
|
36
|
-
... "session_do_url": "https://session-do.glacis.
|
|
36
|
+
... "session_do_url": "https://session-do.glacis.io",
|
|
37
37
|
... })
|
|
38
38
|
>>> await session.attest_chunk(input=audio_chunk, output=transcript)
|
|
39
39
|
>>> receipt = await session.end(metadata={"duration": "00:05:23"})
|
glacis/__main__.py
CHANGED
|
@@ -9,12 +9,13 @@ import argparse
|
|
|
9
9
|
import json
|
|
10
10
|
import sys
|
|
11
11
|
from pathlib import Path
|
|
12
|
+
from typing import Any, Union
|
|
12
13
|
|
|
13
14
|
from glacis import Glacis
|
|
14
|
-
from glacis.models import AttestReceipt, OfflineAttestReceipt
|
|
15
|
+
from glacis.models import AttestReceipt, OfflineAttestReceipt, OfflineVerifyResult, VerifyResult
|
|
15
16
|
|
|
16
17
|
|
|
17
|
-
def verify_command(args):
|
|
18
|
+
def verify_command(args: argparse.Namespace) -> None:
|
|
18
19
|
"""Verify a receipt file."""
|
|
19
20
|
receipt_path = Path(args.receipt)
|
|
20
21
|
|
|
@@ -24,21 +25,29 @@ def verify_command(args):
|
|
|
24
25
|
|
|
25
26
|
try:
|
|
26
27
|
with open(receipt_path) as f:
|
|
27
|
-
data = json.load(f)
|
|
28
|
+
data: dict[str, Any] = json.load(f)
|
|
28
29
|
except json.JSONDecodeError as e:
|
|
29
30
|
print(f"Error: Invalid JSON: {e}", file=sys.stderr)
|
|
30
31
|
sys.exit(1)
|
|
31
32
|
|
|
32
|
-
# Determine receipt type
|
|
33
|
+
# Determine receipt type and verify
|
|
34
|
+
receipt: Union[AttestReceipt, OfflineAttestReceipt]
|
|
35
|
+
result: Union[VerifyResult, OfflineVerifyResult]
|
|
36
|
+
|
|
33
37
|
if data.get("attestation_id", "").startswith("oatt_"):
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
offline_receipt = OfflineAttestReceipt(**data)
|
|
39
|
+
# For verification, we need a signing_seed but it's not used
|
|
40
|
+
# since we verify using the public key from the receipt
|
|
41
|
+
dummy_seed = bytes(32) # All zeros - only used to satisfy constructor
|
|
42
|
+
glacis = Glacis(mode="offline", signing_seed=dummy_seed)
|
|
43
|
+
result = glacis.verify(offline_receipt)
|
|
44
|
+
receipt = offline_receipt
|
|
36
45
|
else:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
46
|
+
online_receipt = AttestReceipt(**data)
|
|
47
|
+
# Online verification doesn't require API key for public receipts
|
|
48
|
+
glacis = Glacis(api_key="verify_only")
|
|
49
|
+
result = glacis.verify(online_receipt)
|
|
50
|
+
receipt = online_receipt
|
|
42
51
|
|
|
43
52
|
# Output
|
|
44
53
|
print(f"Receipt: {receipt.attestation_id}")
|
|
@@ -47,17 +56,22 @@ def verify_command(args):
|
|
|
47
56
|
|
|
48
57
|
if result.valid:
|
|
49
58
|
print("Status: VALID")
|
|
50
|
-
|
|
51
|
-
if
|
|
52
|
-
|
|
59
|
+
# Get signature validity based on result type
|
|
60
|
+
if isinstance(result, OfflineVerifyResult):
|
|
61
|
+
sig_valid = result.signature_valid
|
|
62
|
+
else:
|
|
63
|
+
sig_valid = result.verification.signature_valid
|
|
64
|
+
print(f" Signature: {'PASS' if sig_valid else 'FAIL'}")
|
|
65
|
+
if isinstance(result, VerifyResult):
|
|
66
|
+
print(f" Merkle proof: {'PASS' if result.verification.proof_valid else 'FAIL'}")
|
|
53
67
|
else:
|
|
54
68
|
print("Status: INVALID")
|
|
55
|
-
if
|
|
69
|
+
if result.error:
|
|
56
70
|
print(f" Error: {result.error}")
|
|
57
71
|
sys.exit(1)
|
|
58
72
|
|
|
59
73
|
|
|
60
|
-
def main():
|
|
74
|
+
def main() -> None:
|
|
61
75
|
parser = argparse.ArgumentParser(
|
|
62
76
|
prog="glacis", description="Glacis CLI - Cryptographic attestation for AI systems"
|
|
63
77
|
)
|
glacis/client.py
CHANGED
|
@@ -7,7 +7,7 @@ using RFC 8785 canonical JSON + SHA-256 - the actual payload never leaves
|
|
|
7
7
|
your infrastructure.
|
|
8
8
|
|
|
9
9
|
Supports two modes:
|
|
10
|
-
- Online (default): Sends attestations to api.glacis.
|
|
10
|
+
- Online (default): Sends attestations to api.glacis.io for witnessing
|
|
11
11
|
- Offline: Signs attestations locally using Ed25519 via WASM
|
|
12
12
|
|
|
13
13
|
Example (online):
|
|
@@ -44,9 +44,7 @@ from glacis.crypto import hash_payload
|
|
|
44
44
|
from glacis.models import (
|
|
45
45
|
AttestReceipt,
|
|
46
46
|
GlacisApiError,
|
|
47
|
-
GlacisConfig,
|
|
48
47
|
GlacisRateLimitError,
|
|
49
|
-
LogQueryParams,
|
|
50
48
|
LogQueryResult,
|
|
51
49
|
OfflineAttestReceipt,
|
|
52
50
|
OfflineVerifyResult,
|
|
@@ -67,7 +65,7 @@ class GlacisMode(str, Enum):
|
|
|
67
65
|
|
|
68
66
|
logger = logging.getLogger("glacis")
|
|
69
67
|
|
|
70
|
-
DEFAULT_BASE_URL = "https://api.glacis.
|
|
68
|
+
DEFAULT_BASE_URL = "https://api.glacis.io"
|
|
71
69
|
DEFAULT_TIMEOUT = 30.0
|
|
72
70
|
DEFAULT_MAX_RETRIES = 3
|
|
73
71
|
DEFAULT_BASE_DELAY = 1.0
|
|
@@ -84,7 +82,7 @@ class Glacis:
|
|
|
84
82
|
|
|
85
83
|
Args:
|
|
86
84
|
api_key: API key for authenticated endpoints (required for online mode)
|
|
87
|
-
base_url: Base URL for the API (default: https://api.glacis.
|
|
85
|
+
base_url: Base URL for the API (default: https://api.glacis.io)
|
|
88
86
|
debug: Enable debug logging
|
|
89
87
|
timeout: Request timeout in seconds
|
|
90
88
|
max_retries: Maximum number of retries for transient errors
|
|
@@ -226,7 +224,7 @@ class Glacis:
|
|
|
226
224
|
"""Create a server-witnessed attestation."""
|
|
227
225
|
self._debug(f"Attesting (online): service_id={service_id}, hash={payload_hash[:16]}...")
|
|
228
226
|
|
|
229
|
-
body = {
|
|
227
|
+
body: dict[str, Any] = {
|
|
230
228
|
"serviceId": service_id,
|
|
231
229
|
"operationType": operation_type,
|
|
232
230
|
"payloadHash": payload_hash,
|
|
@@ -356,37 +354,10 @@ class Glacis:
|
|
|
356
354
|
self._debug(f"Verifying (offline): {receipt.attestation_id}")
|
|
357
355
|
|
|
358
356
|
try:
|
|
359
|
-
#
|
|
360
|
-
#
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
"serviceId": receipt.service_id,
|
|
364
|
-
"operationType": receipt.operation_type,
|
|
365
|
-
"payloadHash": receipt.payload_hash,
|
|
366
|
-
"timestampMs": receipt.timestamp.replace("Z", "").replace("-", "").replace(":", "").replace("T", ""),
|
|
367
|
-
"mode": "offline",
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
# Note: We stored the timestamp in ISO format, but signed with ms timestamp
|
|
371
|
-
# For verification, we need the original signed payload
|
|
372
|
-
# Since we can't perfectly reconstruct it, we'll verify using the stored signature
|
|
373
|
-
# against the public key directly
|
|
374
|
-
|
|
375
|
-
# Get the public key bytes
|
|
376
|
-
public_key = bytes.fromhex(receipt.public_key)
|
|
377
|
-
|
|
378
|
-
# Decode the signature
|
|
379
|
-
import base64
|
|
380
|
-
|
|
381
|
-
signature = base64.b64decode(receipt.signature)
|
|
382
|
-
|
|
383
|
-
# We need to reconstruct the exact payload that was signed
|
|
384
|
-
# The payload was: {"mode":"offline","operationType":"...","payloadHash":"...","serviceId":"...","timestampMs":"...","version":1}
|
|
385
|
-
# Since we don't store the exact timestampMs, we need a different approach
|
|
386
|
-
|
|
387
|
-
# For now, we'll trust that if the signature was created by us with the same key,
|
|
388
|
-
# and the receipt exists in our database, it's valid
|
|
389
|
-
# A more robust solution would store the signed payload or timestampMs
|
|
357
|
+
# For offline verification, we verify the public key matches our signing seed.
|
|
358
|
+
# Full signature verification would require storing the original timestampMs,
|
|
359
|
+
# which we don't currently do. A more robust solution would store the
|
|
360
|
+
# signed payload or timestampMs for later verification.
|
|
390
361
|
|
|
391
362
|
# Use WASM to verify if we have the runtime
|
|
392
363
|
if self._wasm_runtime and self._signing_seed:
|
|
@@ -530,6 +501,7 @@ class Glacis:
|
|
|
530
501
|
headers: Optional[dict[str, str]] = None,
|
|
531
502
|
) -> dict[str, Any]:
|
|
532
503
|
"""Make a request with exponential backoff retry."""
|
|
504
|
+
assert self._client is not None, "HTTP client not initialized"
|
|
533
505
|
last_error: Optional[Exception] = None
|
|
534
506
|
|
|
535
507
|
for attempt in range(self.max_retries + 1):
|
|
@@ -543,7 +515,8 @@ class Glacis:
|
|
|
543
515
|
)
|
|
544
516
|
|
|
545
517
|
if response.is_success:
|
|
546
|
-
|
|
518
|
+
result: dict[str, Any] = response.json()
|
|
519
|
+
return result
|
|
547
520
|
|
|
548
521
|
if response.status_code == 429:
|
|
549
522
|
retry_after = response.headers.get("Retry-After")
|
|
@@ -597,7 +570,7 @@ class AsyncGlacis:
|
|
|
597
570
|
|
|
598
571
|
Args:
|
|
599
572
|
api_key: API key for authenticated endpoints
|
|
600
|
-
base_url: Base URL for the API (default: https://api.glacis.
|
|
573
|
+
base_url: Base URL for the API (default: https://api.glacis.io)
|
|
601
574
|
debug: Enable debug logging
|
|
602
575
|
timeout: Request timeout in seconds
|
|
603
576
|
max_retries: Maximum number of retries for transient errors
|
|
@@ -679,7 +652,7 @@ class AsyncGlacis:
|
|
|
679
652
|
|
|
680
653
|
self._debug(f"Attesting: service_id={service_id}, hash={payload_hash[:16]}...")
|
|
681
654
|
|
|
682
|
-
body = {
|
|
655
|
+
body: dict[str, Any] = {
|
|
683
656
|
"serviceId": service_id,
|
|
684
657
|
"operationType": operation_type,
|
|
685
658
|
"payloadHash": payload_hash,
|
|
@@ -792,6 +765,7 @@ class AsyncGlacis:
|
|
|
792
765
|
"""Make a request with exponential backoff retry."""
|
|
793
766
|
import asyncio
|
|
794
767
|
|
|
768
|
+
assert self._client is not None, "HTTP client not initialized"
|
|
795
769
|
last_error: Optional[Exception] = None
|
|
796
770
|
|
|
797
771
|
for attempt in range(self.max_retries + 1):
|
|
@@ -805,7 +779,8 @@ class AsyncGlacis:
|
|
|
805
779
|
)
|
|
806
780
|
|
|
807
781
|
if response.is_success:
|
|
808
|
-
|
|
782
|
+
result: dict[str, Any] = response.json()
|
|
783
|
+
return result
|
|
809
784
|
|
|
810
785
|
if response.status_code == 429:
|
|
811
786
|
retry_after = response.headers.get("Retry-After")
|
glacis/integrations/anthropic.py
CHANGED
|
@@ -23,7 +23,7 @@ if TYPE_CHECKING:
|
|
|
23
23
|
def attested_anthropic(
|
|
24
24
|
glacis_api_key: str,
|
|
25
25
|
anthropic_api_key: Optional[str] = None,
|
|
26
|
-
glacis_base_url: str = "https://api.glacis.
|
|
26
|
+
glacis_base_url: str = "https://api.glacis.io",
|
|
27
27
|
service_id: str = "anthropic",
|
|
28
28
|
debug: bool = False,
|
|
29
29
|
**anthropic_kwargs: Any,
|
|
@@ -137,7 +137,7 @@ def attested_anthropic(
|
|
|
137
137
|
def attested_async_anthropic(
|
|
138
138
|
glacis_api_key: str,
|
|
139
139
|
anthropic_api_key: Optional[str] = None,
|
|
140
|
-
glacis_base_url: str = "https://api.glacis.
|
|
140
|
+
glacis_base_url: str = "https://api.glacis.io",
|
|
141
141
|
service_id: str = "anthropic",
|
|
142
142
|
debug: bool = False,
|
|
143
143
|
**anthropic_kwargs: Any,
|
glacis/integrations/openai.py
CHANGED
|
@@ -52,7 +52,7 @@ def get_last_receipt() -> Optional[Union["AttestReceipt", "OfflineAttestReceipt"
|
|
|
52
52
|
def attested_openai(
|
|
53
53
|
glacis_api_key: Optional[str] = None,
|
|
54
54
|
openai_api_key: Optional[str] = None,
|
|
55
|
-
glacis_base_url: str = "https://api.glacis.
|
|
55
|
+
glacis_base_url: str = "https://api.glacis.io",
|
|
56
56
|
service_id: str = "openai",
|
|
57
57
|
debug: bool = False,
|
|
58
58
|
offline: bool = False,
|
glacis/models.py
CHANGED
|
@@ -15,7 +15,7 @@ class GlacisConfig(BaseModel):
|
|
|
15
15
|
|
|
16
16
|
api_key: str = Field(..., description="API key (glsk_live_xxx or glsk_test_xxx)")
|
|
17
17
|
base_url: str = Field(
|
|
18
|
-
default="https://api.glacis.
|
|
18
|
+
default="https://api.glacis.io", description="Base URL for the API"
|
|
19
19
|
)
|
|
20
20
|
debug: bool = Field(default=False, description="Enable debug logging")
|
|
21
21
|
timeout: float = Field(default=30.0, description="Request timeout in seconds")
|
glacis/storage.py
CHANGED
|
@@ -11,7 +11,7 @@ import json
|
|
|
11
11
|
import sqlite3
|
|
12
12
|
from datetime import datetime
|
|
13
13
|
from pathlib import Path
|
|
14
|
-
from typing import TYPE_CHECKING, Optional
|
|
14
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
15
15
|
|
|
16
16
|
if TYPE_CHECKING:
|
|
17
17
|
from glacis.models import OfflineAttestReceipt
|
|
@@ -119,7 +119,7 @@ class ReceiptStorage:
|
|
|
119
119
|
receipt: "OfflineAttestReceipt",
|
|
120
120
|
input_preview: Optional[str] = None,
|
|
121
121
|
output_preview: Optional[str] = None,
|
|
122
|
-
metadata: Optional[dict] = None,
|
|
122
|
+
metadata: Optional[dict[str, Any]] = None,
|
|
123
123
|
) -> None:
|
|
124
124
|
"""
|
|
125
125
|
Store an offline receipt.
|
|
@@ -242,7 +242,7 @@ class ReceiptStorage:
|
|
|
242
242
|
cursor = conn.cursor()
|
|
243
243
|
|
|
244
244
|
query = "SELECT * FROM offline_receipts WHERE 1=1"
|
|
245
|
-
params: list = []
|
|
245
|
+
params: list[Any] = []
|
|
246
246
|
|
|
247
247
|
if service_id:
|
|
248
248
|
query += " AND service_id = ?"
|
|
@@ -326,6 +326,11 @@ class ReceiptStorage:
|
|
|
326
326
|
"""Context manager entry."""
|
|
327
327
|
return self
|
|
328
328
|
|
|
329
|
-
def __exit__(
|
|
329
|
+
def __exit__(
|
|
330
|
+
self,
|
|
331
|
+
exc_type: Optional[type[BaseException]],
|
|
332
|
+
exc_val: Optional[BaseException],
|
|
333
|
+
exc_tb: Optional[Any],
|
|
334
|
+
) -> None:
|
|
330
335
|
"""Context manager exit."""
|
|
331
336
|
self.close()
|
glacis/streaming.py
CHANGED
|
@@ -12,7 +12,7 @@ Example:
|
|
|
12
12
|
>>> session = await StreamingSession.start(glacis, {
|
|
13
13
|
... "service_id": "voice-assistant",
|
|
14
14
|
... "operation_type": "completion",
|
|
15
|
-
... "session_do_url": "https://session-do.glacis.
|
|
15
|
+
... "session_do_url": "https://session-do.glacis.io",
|
|
16
16
|
... })
|
|
17
17
|
>>>
|
|
18
18
|
>>> await session.attest_chunk({"input": audio_chunk, "output": transcript})
|
|
@@ -26,8 +26,8 @@ Context Manager:
|
|
|
26
26
|
|
|
27
27
|
import asyncio
|
|
28
28
|
import uuid
|
|
29
|
-
from dataclasses import dataclass
|
|
30
|
-
from typing import Any,
|
|
29
|
+
from dataclasses import dataclass
|
|
30
|
+
from typing import Any, Optional, TypedDict
|
|
31
31
|
|
|
32
32
|
import httpx
|
|
33
33
|
|
|
@@ -73,8 +73,6 @@ class StreamingSession:
|
|
|
73
73
|
api_key: str,
|
|
74
74
|
session_token: str,
|
|
75
75
|
):
|
|
76
|
-
from glacis import AsyncGlacis
|
|
77
|
-
|
|
78
76
|
self._glacis = glacis
|
|
79
77
|
self._session_id = session_id
|
|
80
78
|
self._session_do_url = session_do_url.rstrip("/")
|
|
@@ -315,7 +313,8 @@ class StreamingSession:
|
|
|
315
313
|
f"Failed to get status: {error.get('error', response.status_code)}"
|
|
316
314
|
)
|
|
317
315
|
|
|
318
|
-
|
|
316
|
+
result: dict[str, Any] = response.json()
|
|
317
|
+
return result
|
|
319
318
|
|
|
320
319
|
async def __aenter__(self) -> "StreamingSession":
|
|
321
320
|
return self
|
glacis/wasm_runtime.py
CHANGED
|
@@ -7,9 +7,9 @@ Falls back to PyNaCl if WASM runtime fails.
|
|
|
7
7
|
This provides Ed25519 signing and verification without reimplementing crypto in Python.
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
+
import ctypes
|
|
10
11
|
import hashlib
|
|
11
12
|
import json
|
|
12
|
-
import ctypes
|
|
13
13
|
from base64 import b64encode
|
|
14
14
|
from pathlib import Path
|
|
15
15
|
from typing import Any, Optional
|
|
@@ -30,8 +30,8 @@ class PyNaClRuntime:
|
|
|
30
30
|
|
|
31
31
|
def __init__(self) -> None:
|
|
32
32
|
try:
|
|
33
|
-
import nacl.signing
|
|
34
33
|
import nacl.encoding
|
|
34
|
+
import nacl.signing
|
|
35
35
|
self._nacl_signing = nacl.signing
|
|
36
36
|
self._nacl_encoding = nacl.encoding
|
|
37
37
|
except ImportError:
|
|
@@ -172,12 +172,13 @@ class WasmRuntime:
|
|
|
172
172
|
else:
|
|
173
173
|
# Use PyNaCl by default for better compatibility
|
|
174
174
|
cls._instance = PyNaClRuntime() # type: ignore[assignment]
|
|
175
|
+
assert cls._instance is not None
|
|
175
176
|
return cls._instance
|
|
176
177
|
|
|
177
178
|
def _write_bytes(self, data: bytes) -> int:
|
|
178
179
|
"""Allocate WASM memory and write bytes, returning the pointer."""
|
|
179
180
|
size = len(data)
|
|
180
|
-
ptr = self._alloc(self._store, size)
|
|
181
|
+
ptr: int = self._alloc(self._store, size)
|
|
181
182
|
if ptr == 0:
|
|
182
183
|
raise WasmRuntimeError("Failed to allocate WASM memory")
|
|
183
184
|
|
|
@@ -399,7 +400,7 @@ class WasmRuntime:
|
|
|
399
400
|
sig_ptr = self._write_bytes(signature)
|
|
400
401
|
|
|
401
402
|
try:
|
|
402
|
-
result = self._ed25519_verify(
|
|
403
|
+
result: int = self._ed25519_verify(
|
|
403
404
|
self._store, pubkey_ptr, 32, msg_ptr, len(message), sig_ptr, 64
|
|
404
405
|
)
|
|
405
406
|
return result == 0
|
|
@@ -433,7 +434,8 @@ class WasmRuntime:
|
|
|
433
434
|
# Allocate generous output buffer (input + base64 sig + JSON wrapper)
|
|
434
435
|
out_cap = len(json_bytes) + 200
|
|
435
436
|
out_ptr = self._alloc(self._store, out_cap)
|
|
436
|
-
|
|
437
|
+
# size_t on wasm32 is 4 bytes, but use 8 for safety
|
|
438
|
+
out_len_ptr = self._alloc(self._store, 8)
|
|
437
439
|
|
|
438
440
|
if out_ptr == 0 or out_len_ptr == 0:
|
|
439
441
|
self._free(seed_ptr, 32)
|
|
@@ -516,4 +518,5 @@ def sign_offline_attestation(
|
|
|
516
518
|
attestation_json = json.dumps(attestation, separators=(",", ":"), sort_keys=True)
|
|
517
519
|
signed_json = runtime.sign_attestation_json(signing_seed, attestation_json)
|
|
518
520
|
|
|
519
|
-
|
|
521
|
+
result: dict[str, Any] = json.loads(signed_json)
|
|
522
|
+
return result
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
glacis/__init__.py,sha256=9TLZCbUyUQ0JpqHBNiCjvkgt9HbiRRy3B03GMvxdlQ4,2465
|
|
2
|
+
glacis/__main__.py,sha256=GTA84o2Lx5md1kvI80ATu9yNDGidYtW808_TqOmIJSE,2969
|
|
3
|
+
glacis/client.py,sha256=hM3dokL7HZz3E8ovndvd-uHui31Hz8afv8IFGs4aH4U,27414
|
|
4
|
+
glacis/crypto.py,sha256=DiHIMGMKV616wpba0n7Niuw4t-Zz_q5ij4a7m4HDDvk,3579
|
|
5
|
+
glacis/models.py,sha256=S-n-anzfXJL03lENluNL0cbiXfVsPEsKZyh-dPBH93U,9792
|
|
6
|
+
glacis/storage.py,sha256=tsmlG8bAq5daN1o6I9vmppKhstURm3jcO4_oLhOiyPg,10253
|
|
7
|
+
glacis/streaming.py,sha256=hAmR4XHQixLia6awnFfCaA9hZOtCq2b-pOzgaMd3YzQ,11260
|
|
8
|
+
glacis/wasm_runtime.py,sha256=P1dY20G2rHGGJBDKGA_lCRhkJuXuLycjw6mo5vuw02I,17452
|
|
9
|
+
glacis/integrations/__init__.py,sha256=BeLSA6eGkpBWAIbXPodgS42yD_GpQ-IuXhrgF2271Ps,353
|
|
10
|
+
glacis/integrations/anthropic.py,sha256=xJo0Dgx4Y7TK9cQPfEaBXygX0X2lZs0D_pfioZ_P6AM,6927
|
|
11
|
+
glacis/integrations/openai.py,sha256=VkLtu8iQTMiAAa2pX7byC3je8BjzYiv-8_1T7sq3J4E,6941
|
|
12
|
+
glacis/wasm/s3p_core_wasi.wasm,sha256=gGrYI6hd0VkgqCg1mLADzSJP1pEUekkS-3PKd5mdBJo,253289
|
|
13
|
+
glacis-0.1.1.dist-info/METADATA,sha256=lHHPaAjTfbWPtW9CqT9T7XaQlOAhdP4BTmqAD9QS5Js,9558
|
|
14
|
+
glacis-0.1.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
15
|
+
glacis-0.1.1.dist-info/licenses/LICENSE,sha256=B7g2sM9vz4NF1poTFNMil2cnkwMFel1qUnimyvYW1sw,10766
|
|
16
|
+
glacis-0.1.1.dist-info/RECORD,,
|
glacis-0.1.0.dist-info/RECORD
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
glacis/__init__.py,sha256=MCUcFXSMtHtPJKjzRe8cmP_5SfEy7XeQb2mv0qQcWww,2466
|
|
2
|
-
glacis/__main__.py,sha256=VQcKiAwcmK5npWG5z5kw71_X6PFSnzKS21z6XS886lk,2103
|
|
3
|
-
glacis/client.py,sha256=DZlyEQN9e6eCspb1pY_5UG_IYaT6uFKtLrfP5S4XwQA,28433
|
|
4
|
-
glacis/crypto.py,sha256=DiHIMGMKV616wpba0n7Niuw4t-Zz_q5ij4a7m4HDDvk,3579
|
|
5
|
-
glacis/models.py,sha256=J89KCe4vnhnDkUKLYn9uksYMCj-ZChIKGRYdOw6CM58,9793
|
|
6
|
-
glacis/storage.py,sha256=1q7PCLLukHoVYp7AoAbpTxbMVQAY7RiKpNObn45mxvk,10123
|
|
7
|
-
glacis/streaming.py,sha256=btBae4Q5fiTiQcPGk2tl9DNuoFGphO-T2M_r3x3GTFo,11278
|
|
8
|
-
glacis/wasm_runtime.py,sha256=oy2C4sWb6klxGTb7jh2WxrfrG7pMxBXHmWVL7oTxcdo,17358
|
|
9
|
-
glacis/integrations/__init__.py,sha256=BeLSA6eGkpBWAIbXPodgS42yD_GpQ-IuXhrgF2271Ps,353
|
|
10
|
-
glacis/integrations/anthropic.py,sha256=AiUI-rYyJLI3jEaTrHQ5RyzHJI9BnmjoC_LMEnydikk,6929
|
|
11
|
-
glacis/integrations/openai.py,sha256=zbGDmck2eBqoQlkAobn9gqVlYOE2uvp3qjg2JLUfMEs,6942
|
|
12
|
-
glacis/wasm/s3p_core_wasi.wasm,sha256=gGrYI6hd0VkgqCg1mLADzSJP1pEUekkS-3PKd5mdBJo,253289
|
|
13
|
-
glacis-0.1.0.dist-info/METADATA,sha256=RRRyPCHIuMX0c1MVxDU2DZhKDCXUPKSG7_6TVQm-7Kw,9558
|
|
14
|
-
glacis-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
15
|
-
glacis-0.1.0.dist-info/licenses/LICENSE,sha256=B7g2sM9vz4NF1poTFNMil2cnkwMFel1qUnimyvYW1sw,10766
|
|
16
|
-
glacis-0.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|