Skip to content

Commit 424baf0

Browse files
committed
refactor: standardize environment variable naming for base URL across SDKs
- Replaced `BASE_URL_ENV` with `TINYHUMANS_BASE_URL` in Python, C++, Java, and Rust SDKs to maintain consistency. - Updated related code to ensure proper retrieval of the base URL from environment variables. - Enhanced logging in the Python SDK for better debugging and tracking of memory client operations.
1 parent 44fec2e commit 424baf0

12 files changed

Lines changed: 140 additions & 46 deletions

File tree

packages/plugin-agno/neocortex_agno/tools.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313

1414
DEFAULT_BASE_URL = "https://staging-api.alphahuman.xyz"
15-
BASE_URL_ENV = "ALPHAHUMAN_BASE_URL"
15+
TINYHUMANS_BASE_URL = "ALPHAHUMAN_BASE_URL"
1616

1717

1818
class AlphahumanError(Exception):
@@ -36,7 +36,7 @@ class AlphahumanMemoryClient:
3636
def __init__(self, token: str, base_url: Optional[str] = None) -> None:
3737
if not token or not token.strip():
3838
raise ValueError("token is required")
39-
resolved = base_url or os.getenv(BASE_URL_ENV) or DEFAULT_BASE_URL
39+
resolved = base_url or os.getenv(TINYHUMANS_BASE_URL) or DEFAULT_BASE_URL
4040
self._base_url = resolved.rstrip("/")
4141
self._token = token
4242
self._http = httpx.Client(

packages/plugin-livekit/neocortex_livekit/tools.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212

1313
DEFAULT_BASE_URL = "https://staging-api.alphahuman.xyz"
14-
BASE_URL_ENV = "ALPHAHUMAN_BASE_URL"
14+
TINYHUMANS_BASE_URL = "ALPHAHUMAN_BASE_URL"
1515

1616

1717
class AlphahumanError(Exception):
@@ -29,7 +29,7 @@ class AlphahumanMemoryClient:
2929
def __init__(self, token: str, base_url: Optional[str] = None) -> None:
3030
if not token or not token.strip():
3131
raise ValueError("token is required")
32-
resolved = base_url or os.getenv(BASE_URL_ENV) or DEFAULT_BASE_URL
32+
resolved = base_url or os.getenv(TINYHUMANS_BASE_URL) or DEFAULT_BASE_URL
3333
self._base_url = resolved.rstrip("/")
3434
self._token = token
3535
self._http = httpx.Client(

packages/sdk-cpp/src/memory_client.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
namespace alphahuman {
99

1010
static const char* DEFAULT_BASE_URL = "https://staging-api.alphahuman.xyz";
11-
static const char* BASE_URL_ENV = "ALPHAHUMAN_BASE_URL";
11+
static const char* TINYHUMANS_BASE_URL = "ALPHAHUMAN_BASE_URL";
1212

1313
static void global_curl_init() {
1414
static std::once_flag flag;
@@ -37,7 +37,7 @@ AlphahumanMemoryClient::AlphahumanMemoryClient(const std::string& token, const s
3737
// Resolve base URL
3838
std::string resolved = base_url;
3939
if (resolved.empty()) {
40-
const char* env = std::getenv(BASE_URL_ENV);
40+
const char* env = std::getenv(TINYHUMANS_BASE_URL);
4141
if (env && env[0] != '\0') {
4242
resolved = env;
4343
}

packages/sdk-java/src/main/java/xyz/alphahuman/sdk/AlphahumanMemoryClient.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
public class AlphahumanMemoryClient implements AutoCloseable {
1818

1919
private static final String DEFAULT_BASE_URL = "https://staging-api.alphahuman.xyz";
20-
private static final String BASE_URL_ENV = "ALPHAHUMAN_BASE_URL";
20+
private static final String TINYHUMANS_BASE_URL = "ALPHAHUMAN_BASE_URL";
2121

2222
private final String baseUrl;
2323
private final String token;
@@ -35,7 +35,7 @@ public AlphahumanMemoryClient(String token, String baseUrl) {
3535

3636
String resolved = baseUrl;
3737
if (resolved == null || resolved.isEmpty()) {
38-
resolved = System.getenv(BASE_URL_ENV);
38+
resolved = System.getenv(TINYHUMANS_BASE_URL);
3939
}
4040
if (resolved == null || resolved.isEmpty()) {
4141
resolved = DEFAULT_BASE_URL;

packages/sdk-python/README.md

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,25 @@ import tinyhumansai as api
4040
client = api.TinyHumanMemoryClient("YOUR_APIKEY_HERE")
4141

4242
# Store a single memory
43-
client.ingest_memory({
44-
"key": "user-preference-theme",
45-
"content": "User prefers dark mode",
46-
"namespace": "preferences",
47-
"metadata": {"source": "onboarding"},
48-
})
49-
50-
# Ask a LLM something from the memory
43+
client.ingest_memory(
44+
item={
45+
"key": "user-preference-theme",
46+
"content": "User prefers dark mode",
47+
"namespace": "preferences",
48+
"metadata": {"source": "onboarding"},
49+
}
50+
)
51+
52+
# Fetch relevant memory context, then ask a LLM something from it
53+
ctx = client.recall_memory(
54+
namespace="preferences",
55+
prompt="What is the user's preference for theme?",
56+
)
57+
5158
response = client.recall_with_llm(
5259
prompt="What is the user's preference for theme?",
53-
api_key="OPENAI_API_KEY"
60+
api_key="OPENAI_API_KEY",
61+
context=ctx.context,
5462
)
5563
print(response.text) # The user prefers dark mode
5664
```

packages/sdk-python/example.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
# Ingest (upsert) a single memory
2020
result = client.ingest_memory(
21-
{
21+
item={
2222
"key": "user-preference-theme",
2323
"content": "User prefers dark mode",
2424
"namespace": "preferences",
@@ -42,11 +42,11 @@
4242
# (Optional) Query LLM with context (use your own API key from the provider)
4343
# Built-in providers: "openai", "anthropic", "google"
4444
response = client.recall_with_llm(
45-
"What is the user's preference for theme?",
46-
"openai",
47-
"gpt-4o-mini",
48-
os.environ["OPENAI_API_KEY"],
49-
ctx.context,
45+
prompt="What is the user's preference for theme?",
46+
provider="openai",
47+
model="gpt-4o-mini",
48+
api_key=os.environ["OPENAI_API_KEY"],
49+
context=ctx.context,
5050
)
5151
print(response.text)
5252

packages/sdk-python/tinyhumansai/__init__.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
"""TinyHumans Python SDK."""
22

3+
from __future__ import annotations
4+
5+
import logging
6+
import os
7+
38
from .client import TinyHumanMemoryClient
49
from .llm import SUPPORTED_LLM_PROVIDERS
510
from .types import (
@@ -12,6 +17,13 @@
1217
ReadMemoryItem,
1318
)
1419

20+
logger = logging.getLogger("tinyhumansai")
21+
22+
_level = os.environ.get("TINYHUMANSAI_LOG_LEVEL")
23+
if _level:
24+
# Optional, env-driven log level for easier debugging in apps and notebooks.
25+
logger.setLevel(_level.upper())
26+
1527
__all__ = [
1628
"TinyHumanMemoryClient",
1729
"TinyHumanError",
@@ -22,4 +34,5 @@
2234
"GetContextResponse",
2335
"ReadMemoryItem",
2436
"SUPPORTED_LLM_PROVIDERS",
37+
"logger",
2538
]

packages/sdk-python/tinyhumansai/client.py

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from __future__ import annotations
44

5+
import logging
56
import os
67
import time
78
from typing import Any, Optional, Sequence, Union
@@ -11,7 +12,6 @@
1112
from .llm import recall_with_llm as _query_llm_func
1213
from .types import (
1314
TinyHumanError,
14-
BASE_URL_ENV,
1515
DEFAULT_BASE_URL,
1616
DeleteMemoryResponse,
1717
GetContextResponse,
@@ -22,6 +22,9 @@
2222
)
2323

2424

25+
logger = logging.getLogger("tinyhumansai")
26+
27+
2528
def _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

Comments
 (0)