22
33from __future__ import annotations
44
5+ import logging
56import os
67import time
78from typing import Any , Optional , Sequence , Union
1112from .llm import recall_with_llm as _query_llm_func
1213from .types import (
1314 TinyHumanError ,
14- BASE_URL_ENV ,
1515 DEFAULT_BASE_URL ,
1616 DeleteMemoryResponse ,
1717 GetContextResponse ,
2222)
2323
2424
25+ logger = logging .getLogger ("tinyhumansai" )
26+
27+
2528def _validate_timestamp (value : Optional [float ], name : str ) -> None :
2629 """Validate a Unix timestamp (seconds).
2730
@@ -90,10 +93,17 @@ def __init__(
9093 raise ValueError ("token is required" )
9194 if not model_id or not model_id .strip ():
9295 raise ValueError ("model_id is required" )
93- resolved_base_url = base_url or os .environ .get (BASE_URL_ENV ) or DEFAULT_BASE_URL
96+ resolved_base_url = (
97+ base_url or os .environ .get ("TINYHUMANS_BASE_URL" ) or DEFAULT_BASE_URL
98+ )
9499 self ._base_url = resolved_base_url .rstrip ("/" )
95100 self ._token = token
96101 self ._model_id = model_id
102+ logger .debug (
103+ "Initializing TinyHumanMemoryClient base_url=%s model_id=%s" ,
104+ self ._base_url ,
105+ self ._model_id ,
106+ )
97107 self ._http = httpx .Client (
98108 base_url = self ._base_url ,
99109 headers = {
@@ -105,6 +115,7 @@ def __init__(
105115
106116 def close (self ) -> None :
107117 """Close the underlying HTTP client and release connections."""
118+ logger .debug ("Closing TinyHumanMemoryClient HTTP session" )
108119 self ._http .close ()
109120
110121 def __enter__ (self ) -> "TinyHumanMemoryClient" :
@@ -164,6 +175,7 @@ def ingest_memories(
164175 raise ValueError ("items must be a non-empty list" )
165176
166177 normalized : list [dict [str , Any ]] = []
178+ logger .debug ("Normalizing %d memory item(s) for ingest" , len (items ))
167179 for item in items :
168180 if isinstance (item , MemoryItem ):
169181 _validate_timestamps (item .created_at , item .updated_at )
@@ -199,6 +211,11 @@ def ingest_memories(
199211 raise TypeError ("items must be MemoryItem or dict" )
200212
201213 body = {"items" : normalized }
214+ logger .debug (
215+ "Sending ingest_memories request namespace(s)=%s count=%d" ,
216+ {i ["namespace" ] for i in normalized },
217+ len (normalized ),
218+ )
202219 data = self ._send ("POST" , "/memory" , body )
203220 return IngestMemoryResponse (
204221 ingested = data ["ingested" ],
@@ -247,6 +264,14 @@ def recall_memory(
247264 for k in keys :
248265 params .append (("keys[]" , k ))
249266
267+ logger .debug (
268+ "Recalling memory namespace=%s prompt=%s num_chunks=%d key=%s keys_count=%s" ,
269+ namespace ,
270+ (prompt [:100 ] + "…" ) if len (prompt ) > 100 else prompt ,
271+ num_chunks ,
272+ key ,
273+ len (keys ) if keys else 0 ,
274+ )
250275 data = self ._get ("/memory" , params )
251276 items = [
252277 ReadMemoryItem (
@@ -305,6 +330,13 @@ def delete_memory(
305330 if delete_all :
306331 body ["deleteAll" ] = True
307332
333+ logger .debug (
334+ "Deleting memory namespace=%s key=%s keys_count=%s delete_all=%s" ,
335+ namespace ,
336+ key ,
337+ len (keys ) if keys else 0 ,
338+ delete_all ,
339+ )
308340 data = self ._send ("DELETE" , "/memory" , body )
309341 return DeleteMemoryResponse (deleted = data ["deleted" ])
310342
@@ -369,6 +401,17 @@ def recall_with_llm(
369401 num_chunks = num_chunks ,
370402 )
371403 context = ctx .context
404+ logger .debug (
405+ "Calling recall_with_llm provider=%s model=%s namespace=%s "
406+ "has_context=%s max_tokens=%s temperature=%s url=%s" ,
407+ provider ,
408+ model ,
409+ namespace ,
410+ bool (context ),
411+ max_tokens ,
412+ temperature ,
413+ url ,
414+ )
372415 return _query_llm_func (
373416 prompt = prompt ,
374417 provider = provider ,
@@ -385,14 +428,19 @@ def recall_with_llm(
385428 # ------------------------------------------------------------------
386429
387430 def _get (self , path : str , params : list [tuple [str , str ]]) -> dict [str , Any ]:
431+ logger .debug ("HTTP GET %s params=%s" , path , params )
388432 response = self ._http .get (path , params = params )
389433 return self ._parse_response (response )
390434
391435 def _send (self , method : str , path : str , body : dict [str , Any ]) -> dict [str , Any ]:
436+ logger .debug ("HTTP %s %s json_keys=%s" , method , path , list (body .keys ()))
392437 response = self ._http .request (method , path , json = body )
393438 return self ._parse_response (response )
394439
395440 def _parse_response (self , response : httpx .Response ) -> dict [str , Any ]:
441+ logger .debug (
442+ "Parsing response status=%s url=%s" , response .status_code , response .url
443+ )
396444 try :
397445 payload = response .json ()
398446 except Exception :
0 commit comments