confamnode 0.1.2__tar.gz → 0.1.3__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: confamnode
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: The Nigerian AI inference gateway
5
5
  Project-URL: Repository, https://github.com/confamnodeai/confamnode
6
6
  Project-URL: Bug Tracker, https://github.com/confamnodeai/confamnode/issues
@@ -85,7 +85,7 @@ pip install confamnode
85
85
  ```python
86
86
  from confamnode import ConfamNode
87
87
 
88
- client = ConfamNode(api_key="confam-sk-xxx")
88
+ client = ConfamNode(api_key="confam-xxx")
89
89
 
90
90
  ansa = client.gist(
91
91
  model="confam-speed",
@@ -93,9 +93,9 @@ ansa = client.gist(
93
93
  )
94
94
 
95
95
  print(ansa.text)
96
- print(f"Cost: ₦{ansa.cost.naira:.6f}")
96
+ print(f"Cost: ₦{ansa.cost.naira:.6f}")
97
97
  print(f"Tokens: {ansa.usage.total_tokens}")
98
- print(f"ID: {ansa.id}")
98
+ print(f"ID: {ansa.id}")
99
99
  ```
100
100
 
101
101
  ---
@@ -105,7 +105,7 @@ print(f"ID: {ansa.id}")
105
105
  ```python
106
106
  from confamnode import ConfamNode
107
107
 
108
- client = ConfamNode(api_key="confam-sk-xxx")
108
+ client = ConfamNode(api_key="confam-xxx")
109
109
 
110
110
  stream = client.gist(
111
111
  model="confam-speed",
@@ -121,9 +121,9 @@ for yarn in stream:
121
121
 
122
122
  # Get full Ansa after stream completes
123
123
  ansa = stream.get_ansa()
124
- print(f"\nModel: {ansa.model}")
124
+ print(f"\nModel: {ansa.model}")
125
125
  print(f"Tokens: {ansa.usage.total_tokens}")
126
- print(f"Cost: ₦{ansa.cost.naira:.6f}")
126
+ print(f"Cost: ₦{ansa.cost.naira:.6f}")
127
127
  if ansa.cost.dollars:
128
128
  print(f"${ansa.cost.dollars:.8f}")
129
129
  print(f"ID: {ansa.id}")
@@ -136,7 +136,7 @@ print(f"ID: {ansa.id}")
136
136
  Every `gist()` call returns an `Ansa` object:
137
137
 
138
138
  ```python
139
- ansa = client.gist(model="confam-speed", messages="How far?")
139
+ ansa = client.gist(model="confam-speed", messages="How you dey?")
140
140
 
141
141
  # Response
142
142
  ansa.text # response text
@@ -147,7 +147,7 @@ ansa.citations # citations (search models only)
147
147
  ansa.finish_reason # why generation stopped
148
148
 
149
149
  # Usage
150
- ansa.usage.prompt_tokens # input tokens used
150
+ ansa.usage.prompt_tokens # input tokens used (includes system message)
151
151
  ansa.usage.completion_tokens # output tokens used
152
152
  ansa.usage.total_tokens # total tokens used
153
153
 
@@ -161,9 +161,16 @@ ansa.cost.dollars # cost in USD (if available)
161
161
  ansa.is_local # True — runs on Nigerian hardware
162
162
  ansa.is_ngn_data_residency # True — data never leaves Nigeria
163
163
  ansa.id # unique request ID (confam-xxxx-xxxx)
164
- ansa.raw # original LiteLLM response
164
+
165
+ # Response metadata
166
+ ansa.raw # dict with id, finish_reason, usage
167
+ ansa.raw["id"] # provider response ID
168
+ ansa.raw["finish_reason"] # why generation stopped
169
+ ansa.raw["usage"] # prompt and completion token counts
165
170
  ```
166
171
 
172
+ > **Note:** `prompt_tokens` includes any system message tokens. This is standard behaviour across all LLM providers (OpenAI, Anthropic, etc.).
173
+
167
174
  ---
168
175
 
169
176
  ## Models
@@ -184,15 +191,14 @@ ansa.raw # original LiteLLM response
184
191
  | `confam-deep-reasoning` | Complex thinking, multi-step analysis | ₦234 | ₦468 | ₦0.234 | ₦0.468 |
185
192
  | `confam-code` | Coding assistance, 1M context | ₦234 | ₦468 | ₦0.234 | ₦0.468 |
186
193
 
187
- ### Local Models — Nigeria Data Residency
194
+ ### Local Models — Nigerian Data Residency
188
195
 
189
196
  | Model | Description | Input ₦/1M | Output ₦/1M | Input ₦/1K | Output ₦/1K |
190
197
  |---|---|---|---|---|---|
191
- | `confam-nano` | Qwen3.5 4B on Jetson Orin Nano | ₦500 | ₦1,500 | ₦0.500 | ₦1.500 |
198
+ | `confam-nano` | Local model data stays in Nigeria | ₦500 | ₦1,500 | ₦0.500 | ₦1.500 |
192
199
 
193
200
  Runs entirely on Nigerian hardware. Data never transmitted abroad.
194
-
195
- Data never leaves Nigeria. Ideal for banks, fintechs, hospitals, law firms, and government agencies.
201
+ Ideal for banks, fintechs, hospitals, law firms, and government agencies.
196
202
 
197
203
  More models coming soon. Contact [hello@confamnode.com](mailto:hello@confamnode.com) for early access.
198
204
 
@@ -259,9 +265,10 @@ Enable extended thinking for complex problems:
259
265
  ansa = client.gist(
260
266
  model="confam-reasoning",
261
267
  messages="One trader buy goods for ₦50,000 sell am for ₦75,000. After e pay ₦5,000 for transport and ₦3,000 for market, wetin be the real profit? Show how you calculate am.",
262
- # Explicit reasoning control
263
268
  allowed_openai_params=["reasoning_effort"],
264
- rreasoning_effort={"effort": "low", "summary": "detailed"} # effort can be "low", "mid", "high", or "xhigh". summary can be "detailed", or "concise"
269
+ reasoning_effort={"effort": "low", "summary": "detailed"}
270
+ # effort: "low", "medium", "high", or "xhigh"
271
+ # summary: "detailed" or "concise"
265
272
  )
266
273
 
267
274
  print(ansa.reasoning) # thinking trace
@@ -274,9 +281,8 @@ Also available on `confam-deep-reasoning` for more complex multi-step problems:
274
281
  ansa = client.gist(
275
282
  model="confam-deep-reasoning",
276
283
  messages="Analyse the financial risk of a Nigerian fintech expanding to Ghana...",
277
- # Explicit reasoning control
278
284
  allowed_openai_params=["reasoning_effort"],
279
- rreasoning_effort={"effort": "low", "summary": "detailed"} # effort can be "low", "mid", "high", or "xhigh". summary can be "detailed", or "concise"
285
+ reasoning_effort={"effort": "high", "summary": "detailed"}
280
286
  )
281
287
 
282
288
  print(ansa.reasoning) # full thinking trace
@@ -324,7 +330,7 @@ print(ansa.text)
324
330
  ## Environment Variable
325
331
 
326
332
  ```bash
327
- export CONFAMNODE_API_KEY="confam-sk-xxx"
333
+ export CONFAMNODE_API_KEY="confam-xxx"
328
334
  ```
329
335
 
330
336
  ```python
@@ -340,7 +346,7 @@ For enterprise clients running ConfamNode on private infrastructure:
340
346
 
341
347
  ```python
342
348
  client = ConfamNode(
343
- api_key="confam-sk-xxx",
349
+ api_key="confam-xxx",
344
350
  base_url="http://your-private-server:4000/v1"
345
351
  )
346
352
  ```
@@ -376,7 +382,7 @@ except ConfamNodeError as e:
376
382
 
377
383
  ## Private AI Deployment
378
384
 
379
- Need Data-residential private AI on your own infrastructure?
385
+ Need data-residential private AI on your own infrastructure?
380
386
 
381
387
  JoTeq the First offers:
382
388
  - On-premise deployment on Jetson devices and GPUs
@@ -391,6 +397,7 @@ Contact: [hello@confamnode.com](mailto:hello@confamnode.com)
391
397
 
392
398
  ## Links
393
399
 
400
+ - Website: [confamnode.com](https://confamnode.com)
394
401
  - PyPI: [pypi.org/project/confamnode](https://pypi.org/project/confamnode)
395
402
  - GitHub: [github.com/confamnodeai/confamnode](https://github.com/confamnodeai/confamnode)
396
403
  - General: [hello@confamnode.com](mailto:hello@confamnode.com)
@@ -403,4 +410,4 @@ Contact: [hello@confamnode.com](mailto:hello@confamnode.com)
403
410
 
404
411
  Apache 2.0
405
412
 
406
- ---
413
+ ---
@@ -61,7 +61,7 @@ pip install confamnode
61
61
  ```python
62
62
  from confamnode import ConfamNode
63
63
 
64
- client = ConfamNode(api_key="confam-sk-xxx")
64
+ client = ConfamNode(api_key="confam-xxx")
65
65
 
66
66
  ansa = client.gist(
67
67
  model="confam-speed",
@@ -69,9 +69,9 @@ ansa = client.gist(
69
69
  )
70
70
 
71
71
  print(ansa.text)
72
- print(f"Cost: ₦{ansa.cost.naira:.6f}")
72
+ print(f"Cost: ₦{ansa.cost.naira:.6f}")
73
73
  print(f"Tokens: {ansa.usage.total_tokens}")
74
- print(f"ID: {ansa.id}")
74
+ print(f"ID: {ansa.id}")
75
75
  ```
76
76
 
77
77
  ---
@@ -81,7 +81,7 @@ print(f"ID: {ansa.id}")
81
81
  ```python
82
82
  from confamnode import ConfamNode
83
83
 
84
- client = ConfamNode(api_key="confam-sk-xxx")
84
+ client = ConfamNode(api_key="confam-xxx")
85
85
 
86
86
  stream = client.gist(
87
87
  model="confam-speed",
@@ -97,9 +97,9 @@ for yarn in stream:
97
97
 
98
98
  # Get full Ansa after stream completes
99
99
  ansa = stream.get_ansa()
100
- print(f"\nModel: {ansa.model}")
100
+ print(f"\nModel: {ansa.model}")
101
101
  print(f"Tokens: {ansa.usage.total_tokens}")
102
- print(f"Cost: ₦{ansa.cost.naira:.6f}")
102
+ print(f"Cost: ₦{ansa.cost.naira:.6f}")
103
103
  if ansa.cost.dollars:
104
104
  print(f"${ansa.cost.dollars:.8f}")
105
105
  print(f"ID: {ansa.id}")
@@ -112,7 +112,7 @@ print(f"ID: {ansa.id}")
112
112
  Every `gist()` call returns an `Ansa` object:
113
113
 
114
114
  ```python
115
- ansa = client.gist(model="confam-speed", messages="How far?")
115
+ ansa = client.gist(model="confam-speed", messages="How you dey?")
116
116
 
117
117
  # Response
118
118
  ansa.text # response text
@@ -123,7 +123,7 @@ ansa.citations # citations (search models only)
123
123
  ansa.finish_reason # why generation stopped
124
124
 
125
125
  # Usage
126
- ansa.usage.prompt_tokens # input tokens used
126
+ ansa.usage.prompt_tokens # input tokens used (includes system message)
127
127
  ansa.usage.completion_tokens # output tokens used
128
128
  ansa.usage.total_tokens # total tokens used
129
129
 
@@ -137,9 +137,16 @@ ansa.cost.dollars # cost in USD (if available)
137
137
  ansa.is_local # True — runs on Nigerian hardware
138
138
  ansa.is_ngn_data_residency # True — data never leaves Nigeria
139
139
  ansa.id # unique request ID (confam-xxxx-xxxx)
140
- ansa.raw # original LiteLLM response
140
+
141
+ # Response metadata
142
+ ansa.raw # dict with id, finish_reason, usage
143
+ ansa.raw["id"] # provider response ID
144
+ ansa.raw["finish_reason"] # why generation stopped
145
+ ansa.raw["usage"] # prompt and completion token counts
141
146
  ```
142
147
 
148
+ > **Note:** `prompt_tokens` includes any system message tokens. This is standard behaviour across all LLM providers (OpenAI, Anthropic, etc.).
149
+
143
150
  ---
144
151
 
145
152
  ## Models
@@ -160,15 +167,14 @@ ansa.raw # original LiteLLM response
160
167
  | `confam-deep-reasoning` | Complex thinking, multi-step analysis | ₦234 | ₦468 | ₦0.234 | ₦0.468 |
161
168
  | `confam-code` | Coding assistance, 1M context | ₦234 | ₦468 | ₦0.234 | ₦0.468 |
162
169
 
163
- ### Local Models — Nigeria Data Residency
170
+ ### Local Models — Nigerian Data Residency
164
171
 
165
172
  | Model | Description | Input ₦/1M | Output ₦/1M | Input ₦/1K | Output ₦/1K |
166
173
  |---|---|---|---|---|---|
167
- | `confam-nano` | Qwen3.5 4B on Jetson Orin Nano | ₦500 | ₦1,500 | ₦0.500 | ₦1.500 |
174
+ | `confam-nano` | Local model data stays in Nigeria | ₦500 | ₦1,500 | ₦0.500 | ₦1.500 |
168
175
 
169
176
  Runs entirely on Nigerian hardware. Data never transmitted abroad.
170
-
171
- Data never leaves Nigeria. Ideal for banks, fintechs, hospitals, law firms, and government agencies.
177
+ Ideal for banks, fintechs, hospitals, law firms, and government agencies.
172
178
 
173
179
  More models coming soon. Contact [hello@confamnode.com](mailto:hello@confamnode.com) for early access.
174
180
 
@@ -235,9 +241,10 @@ Enable extended thinking for complex problems:
235
241
  ansa = client.gist(
236
242
  model="confam-reasoning",
237
243
  messages="One trader buy goods for ₦50,000 sell am for ₦75,000. After e pay ₦5,000 for transport and ₦3,000 for market, wetin be the real profit? Show how you calculate am.",
238
- # Explicit reasoning control
239
244
  allowed_openai_params=["reasoning_effort"],
240
- rreasoning_effort={"effort": "low", "summary": "detailed"} # effort can be "low", "mid", "high", or "xhigh". summary can be "detailed", or "concise"
245
+ reasoning_effort={"effort": "low", "summary": "detailed"}
246
+ # effort: "low", "medium", "high", or "xhigh"
247
+ # summary: "detailed" or "concise"
241
248
  )
242
249
 
243
250
  print(ansa.reasoning) # thinking trace
@@ -250,9 +257,8 @@ Also available on `confam-deep-reasoning` for more complex multi-step problems:
250
257
  ansa = client.gist(
251
258
  model="confam-deep-reasoning",
252
259
  messages="Analyse the financial risk of a Nigerian fintech expanding to Ghana...",
253
- # Explicit reasoning control
254
260
  allowed_openai_params=["reasoning_effort"],
255
- rreasoning_effort={"effort": "low", "summary": "detailed"} # effort can be "low", "mid", "high", or "xhigh". summary can be "detailed", or "concise"
261
+ reasoning_effort={"effort": "high", "summary": "detailed"}
256
262
  )
257
263
 
258
264
  print(ansa.reasoning) # full thinking trace
@@ -300,7 +306,7 @@ print(ansa.text)
300
306
  ## Environment Variable
301
307
 
302
308
  ```bash
303
- export CONFAMNODE_API_KEY="confam-sk-xxx"
309
+ export CONFAMNODE_API_KEY="confam-xxx"
304
310
  ```
305
311
 
306
312
  ```python
@@ -316,7 +322,7 @@ For enterprise clients running ConfamNode on private infrastructure:
316
322
 
317
323
  ```python
318
324
  client = ConfamNode(
319
- api_key="confam-sk-xxx",
325
+ api_key="confam-xxx",
320
326
  base_url="http://your-private-server:4000/v1"
321
327
  )
322
328
  ```
@@ -352,7 +358,7 @@ except ConfamNodeError as e:
352
358
 
353
359
  ## Private AI Deployment
354
360
 
355
- Need Data-residential private AI on your own infrastructure?
361
+ Need data-residential private AI on your own infrastructure?
356
362
 
357
363
  JoTeq the First offers:
358
364
  - On-premise deployment on Jetson devices and GPUs
@@ -367,6 +373,7 @@ Contact: [hello@confamnode.com](mailto:hello@confamnode.com)
367
373
 
368
374
  ## Links
369
375
 
376
+ - Website: [confamnode.com](https://confamnode.com)
370
377
  - PyPI: [pypi.org/project/confamnode](https://pypi.org/project/confamnode)
371
378
  - GitHub: [github.com/confamnodeai/confamnode](https://github.com/confamnodeai/confamnode)
372
379
  - General: [hello@confamnode.com](mailto:hello@confamnode.com)
@@ -379,4 +386,4 @@ Contact: [hello@confamnode.com](mailto:hello@confamnode.com)
379
386
 
380
387
  Apache 2.0
381
388
 
382
- ---
389
+ ---
@@ -8,7 +8,7 @@ from confamnode.exceptions import (
8
8
  from confamnode.ansa import Ansa, Usage, Cost
9
9
  from confamnode import models
10
10
 
11
- __version__ = "0.1.2"
11
+ __version__ = "0.1.3"
12
12
 
13
13
  __all__ = [
14
14
  "ConfamNode",
@@ -3,11 +3,12 @@ import litellm
3
3
 
4
4
  from typing import Union, List, Dict
5
5
 
6
- from confamnode import models
7
6
  from confamnode.ansa import Ansa, Usage, Cost
8
7
  from confamnode.prompts import CONFAMNODE_SYSTEM_MESSAGE
8
+ from confamnode.registry import VALID_MODELS, LOCAL_MODELS
9
+ from confamnode.utils import sanitize_raw, sanitize_stream_raw
9
10
  from confamnode.exceptions import ConfamAuthError, ConfamModelError
10
- from confamnode.registry import VALID_MODELS, LOCAL_MODELS, NGN_DATA_RESIDENCY_MODELS
11
+
11
12
 
12
13
  DEFAULT_BASE_URL = "https://api.confamnode.com/v1"
13
14
  DEFAULT_USD_TO_NAIRA = 1400.0
@@ -24,11 +25,11 @@ class ConfamNode:
24
25
  if not api_key:
25
26
  raise ValueError("api_key is required")
26
27
 
27
- if not api_key.startswith("confam-sk-"):
28
+ if not api_key.startswith("confam-"):
28
29
  raise ConfamAuthError()
29
30
 
30
31
  self.api_key = api_key
31
- self.litellm_key = api_key.removeprefix("confam-")
32
+ self.litellm_key = "sk-" + api_key.removeprefix("confam-")
32
33
  self.base_url = base_url or DEFAULT_BASE_URL
33
34
 
34
35
  def gist(
@@ -125,7 +126,7 @@ class ConfamNode:
125
126
  usage=usage,
126
127
  cost=cost,
127
128
  finish_reason=raw.choices[0].finish_reason,
128
- raw=raw,
129
+ raw=sanitize_raw(raw),
129
130
  is_local=model in LOCAL_MODELS,
130
131
  is_ngn_data_residency=model in LOCAL_MODELS
131
132
  )
@@ -177,7 +178,7 @@ class ConfamStream:
177
178
  usage=usage,
178
179
  cost=cost,
179
180
  finish_reason=finish_reason,
180
- raw=self._chunks,
181
+ raw=sanitize_stream_raw(self._chunks, finish_reason, getattr(last_chunk, "usage", None)),
181
182
  is_local=self._model in LOCAL_MODELS,
182
183
  is_ngn_data_residency=self._model in LOCAL_MODELS,
183
184
  )
@@ -0,0 +1,29 @@
1
+ def sanitize_raw(raw) -> dict:
2
+ """
3
+ Build sanitized raw dict.
4
+ """
5
+ return {
6
+ "id": getattr(raw, "id", None),
7
+ "finish_reason": getattr(
8
+ getattr(raw, "choices", [None])[0],
9
+ "finish_reason", None
10
+ ) if getattr(raw, "choices", None) else None,
11
+ "usage": {
12
+ "prompt_tokens": getattr(getattr(raw, "usage", None), "prompt_tokens", 0),
13
+ "completion_tokens": getattr(getattr(raw, "usage", None), "completion_tokens", 0),
14
+ }
15
+ }
16
+
17
+
18
+ def sanitize_stream_raw(chunks, finish_reason: str, usage) -> dict:
19
+ """
20
+ Build sanitized raw dict from streaming chunks.
21
+ """
22
+ return {
23
+ "id": getattr(chunks[0], "id", None) if chunks else None,
24
+ "finish_reason": finish_reason,
25
+ "usage": {
26
+ "prompt_tokens": getattr(usage, "prompt_tokens", 0),
27
+ "completion_tokens": getattr(usage, "completion_tokens", 0),
28
+ }
29
+ }
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "confamnode"
3
- version = "0.1.2"
3
+ version = "0.1.3"
4
4
  description = "The Nigerian AI inference gateway"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -273,4 +273,63 @@ def test_ansa_accepts_is_local_true():
273
273
  is_ngn_data_residency=True
274
274
  )
275
275
  assert ansa.is_local == True
276
- assert ansa.is_ngn_data_residency == True
276
+ assert ansa.is_ngn_data_residency == True
277
+
278
+
279
+ def test_ansa_raw_is_dict():
280
+ usage = Usage(prompt_tokens=10, completion_tokens=20, total_tokens=30)
281
+ cost = Cost(naira=1.23)
282
+ ansa = Ansa(
283
+ text="How you dey?",
284
+ model="confam-speed",
285
+ usage=usage,
286
+ cost=cost,
287
+ finish_reason="stop",
288
+ raw={
289
+ "id": "confam-resp-abc123",
290
+ "finish_reason": "stop",
291
+ "usage": {
292
+ "prompt_tokens": 10,
293
+ "completion_tokens": 20,
294
+ }
295
+ }
296
+ )
297
+ assert isinstance(ansa.raw, dict)
298
+
299
+
300
+ def test_ansa_raw_does_not_expose_model_routing():
301
+ usage = Usage(prompt_tokens=10, completion_tokens=20, total_tokens=30)
302
+ cost = Cost(naira=1.23)
303
+ raw = {
304
+ "id": "confam-resp-abc123",
305
+ "finish_reason": "stop",
306
+ "usage": {
307
+ "prompt_tokens": 10,
308
+ "completion_tokens": 20,
309
+ }
310
+ }
311
+ ansa = Ansa(
312
+ text="How you dey?",
313
+ model="confam-speed",
314
+ usage=usage,
315
+ cost=cost,
316
+ finish_reason="stop",
317
+ raw=raw
318
+ )
319
+ assert "model" not in ansa.raw
320
+ assert "openai" not in str(ansa.raw)
321
+ assert "_hidden_params" not in ansa.raw
322
+
323
+
324
+ def test_ansa_raw_has_id():
325
+ usage = Usage(prompt_tokens=10, completion_tokens=20, total_tokens=30)
326
+ cost = Cost(naira=1.23)
327
+ ansa = Ansa(
328
+ text="How you dey?",
329
+ model="confam-speed",
330
+ usage=usage,
331
+ cost=cost,
332
+ finish_reason="stop",
333
+ raw = {"id": "confam-resp-abc123", "finish_reason": "stop", "usage": {}}
334
+ )
335
+ assert ansa.raw["id"] == "confam-resp-abc123"
@@ -7,8 +7,8 @@ from confamnode.exceptions import ConfamAuthError
7
7
 
8
8
 
9
9
  def test_client_accepts_api_key():
10
- client = ConfamNode(api_key="confam-sk-abc123")
11
- assert client.api_key == "confam-sk-abc123"
10
+ client = ConfamNode(api_key="confam-abc123")
11
+ assert client.api_key == "confam-abc123"
12
12
 
13
13
 
14
14
  def test_client_raises_error_without_api_key():
@@ -22,35 +22,35 @@ def test_client_raises_error_on_invalid_key_format():
22
22
 
23
23
 
24
24
  def test_client_key_starts_with_confam_sk():
25
- client = ConfamNode(api_key="confam-sk-abc123")
26
- assert client.api_key.startswith("confam-sk-")
25
+ client = ConfamNode(api_key="confam-abc123")
26
+ assert client.api_key.startswith("confam-")
27
27
 
28
28
 
29
29
  def test_client_strips_confam_prefix_for_litellm():
30
- client = ConfamNode(api_key="confam-sk-abc123")
30
+ client = ConfamNode(api_key="confam-abc123")
31
31
  assert client.litellm_key == "sk-abc123"
32
32
 
33
33
 
34
34
  def test_client_has_default_base_url():
35
- client = ConfamNode(api_key="confam-sk-abc123")
35
+ client = ConfamNode(api_key="confam-abc123")
36
36
  assert client.base_url == "https://api.confamnode.com/v1"
37
37
 
38
38
 
39
39
  def test_client_accepts_custom_base_url():
40
40
  client = ConfamNode(
41
- api_key="confam-sk-abc123",
41
+ api_key="confam-abc123",
42
42
  base_url="http://192.168.1.100:4000/v1"
43
43
  )
44
44
  assert client.base_url == "http://192.168.1.100:4000/v1"
45
45
 
46
46
 
47
47
  def test_client_picks_up_api_key_from_environment():
48
- with patch.dict(os.environ, {"CONFAMNODE_API_KEY": "confam-sk-abc123"}):
48
+ with patch.dict(os.environ, {"CONFAMNODE_API_KEY": "confam-abc123"}):
49
49
  client = ConfamNode()
50
- assert client.api_key == "confam-sk-abc123"
50
+ assert client.api_key == "confam-abc123"
51
51
 
52
52
 
53
53
  def test_client_explicit_key_overrides_environment():
54
- with patch.dict(os.environ, {"CONFAMNODE_API_KEY": "confam-sk-env123"}):
55
- client = ConfamNode(api_key="confam-sk-explicit123")
56
- assert client.api_key == "confam-sk-explicit123"
54
+ with patch.dict(os.environ, {"CONFAMNODE_API_KEY": "confam-env123"}):
55
+ client = ConfamNode(api_key="confam-explicit123")
56
+ assert client.api_key == "confam-explicit123"
@@ -309,4 +309,16 @@ def test_gist_sets_is_local_true_for_nano(client, mock_litellm_response):
309
309
  messages="How you dey?"
310
310
  )
311
311
  assert ansa.is_local == True
312
- assert ansa.is_ngn_data_residency == True
312
+ assert ansa.is_ngn_data_residency == True
313
+
314
+
315
+ def test_gist_has_raw(client, mock_litellm_response):
316
+ with patch("confamnode.client.litellm.completion", return_value=mock_litellm_response):
317
+ ansa = client.gist(
318
+ model=models.SPEED,
319
+ messages="How you dey?"
320
+ )
321
+ assert isinstance(ansa.raw, dict)
322
+ assert "id" in ansa.raw
323
+ assert "_hidden_params" not in ansa.raw
324
+ assert "openai" not in str(ansa.raw)
@@ -352,7 +352,7 @@ wheels = [
352
352
 
353
353
  [[package]]
354
354
  name = "confamnode"
355
- version = "0.1.2"
355
+ version = "0.1.3"
356
356
  source = { editable = "." }
357
357
  dependencies = [
358
358
  { name = "litellm" },
File without changes
File without changes
File without changes
File without changes