python-fastllm 0.0.51__py3-none-any.whl → 0.0.53__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.
fastllm/__init__.py CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  - `fastllm.responses`: Provider-independent Responses resources and streaming over FastLLM"""
4
4
 
5
- __version__ = "0.0.51"
5
+ __version__ = "0.0.53"
fastllm/_modidx.py CHANGED
@@ -274,6 +274,17 @@ d = { 'settings': { 'branch': 'main',
274
274
  'fastllm.responses.ResponseState': ('responses.html#responsestate', 'fastllm/responses.py'),
275
275
  'fastllm.responses.ResponseState.__init__': ( 'responses.html#responsestate.__init__',
276
276
  'fastllm/responses.py'),
277
+ 'fastllm.responses.ResponseState.from_dict': ( 'responses.html#responsestate.from_dict',
278
+ 'fastllm/responses.py'),
279
+ 'fastllm.responses.ResponseState.to_dict': ( 'responses.html#responsestate.to_dict',
280
+ 'fastllm/responses.py'),
281
+ 'fastllm.responses.ResponseStore': ('responses.html#responsestore', 'fastllm/responses.py'),
282
+ 'fastllm.responses.ResponseStore.__init__': ( 'responses.html#responsestore.__init__',
283
+ 'fastllm/responses.py'),
284
+ 'fastllm.responses.ResponseStore.dump': ('responses.html#responsestore.dump', 'fastllm/responses.py'),
285
+ 'fastllm.responses.ResponseStore.get': ('responses.html#responsestore.get', 'fastllm/responses.py'),
286
+ 'fastllm.responses.ResponseStore.load': ('responses.html#responsestore.load', 'fastllm/responses.py'),
287
+ 'fastllm.responses.ResponseStore.put': ('responses.html#responsestore.put', 'fastllm/responses.py'),
277
288
  'fastllm.responses.ResponseTurn': ('responses.html#responseturn', 'fastllm/responses.py'),
278
289
  'fastllm.responses.ResponseTurn.__init__': ( 'responses.html#responseturn.__init__',
279
290
  'fastllm/responses.py'),
fastllm/responses.py CHANGED
@@ -12,7 +12,7 @@ Every request is streamed. `_ResponseStream` only tracks the standard event gram
12
12
 
13
13
  # %% auto #0
14
14
  __all__ = ['ResponsesError', 'response_input', 'normalize_call_ids', 'response_output', 'response_usage', 'response_object',
15
- 'ResponseState', 'ResponseTurn', 'AsyncResponses', 'response_event', 'pending_response']
15
+ 'ResponseState', 'ResponseStore', 'ResponseTurn', 'AsyncResponses', 'response_event', 'pending_response']
16
16
 
17
17
  # %% ../nbs/06a_responses.ipynb #e16fc24e
18
18
  import asyncio, copy, json, secrets, time
@@ -22,7 +22,7 @@ from fasttransport.errors import APIError
22
22
 
23
23
  from .acomplete import acomplete
24
24
  from .streaming import Status
25
- from aidialog.msg_parts import Msg, Text, ToolUse, ToolResult, InputImage, InputFile, Completion, tool_text
25
+ from aidialog.msg_parts import Msg, Text, ToolUse, ToolResult, InputImage, InputFile, Completion, tool_text, msg2dict, dict2msg
26
26
 
27
27
  # %% ../nbs/06a_responses.ipynb #f904c16f
28
28
  class ResponsesError(Exception):
@@ -145,6 +145,43 @@ class ResponseState(BasicRepr):
145
145
  "Canonical history and optional provider continuation metadata."
146
146
  def __init__(self, id, model, history, provider_response_id=None): store_attr()
147
147
 
148
+ # %% ../nbs/06a_responses.ipynb #b28fa30d
149
+ @patch
150
+ def to_dict(self:ResponseState):
151
+ "This state as a JSON-ready dict"
152
+ return dict(id=self.id, model=self.model, history=[msg2dict(m) for m in self.history], provider_response_id=self.provider_response_id)
153
+
154
+ @patch(cls_method=True)
155
+ def from_dict(cls:ResponseState, d):
156
+ "The state `to_dict` produced `d` from"
157
+ return cls(d['id'], d['model'], tuple(dict2msg(m) for m in d['history']), d['provider_response_id'])
158
+
159
+ # %% ../nbs/06a_responses.ipynb #74e09d18
160
+ class ResponseStore:
161
+ "Continuation states kept for `ttl` seconds; override `dump` and `load` to keep them outside this process"
162
+ def __init__(self, ttl=3600): self.ttl,self.items = ttl,{}
163
+
164
+ async def dump(self, rid, data):
165
+ "Keep JSON-ready `data` under `rid` for `ttl` seconds"
166
+ now = time.time()
167
+ self.items = {k:v for k,v in self.items.items() if v[0] > now}
168
+ self.items[rid] = (now+self.ttl, data)
169
+
170
+ async def load(self, rid):
171
+ "The data kept under `rid`, or `None` once it has expired"
172
+ exp,data = self.items.get(rid, (0, None))
173
+ return data if exp > time.time() else None
174
+
175
+ async def put(self, state, **meta):
176
+ "Store `state` with the host's `meta` about it"
177
+ await self.dump(state.id, dict(state=state.to_dict(), **meta))
178
+
179
+ async def get(self, rid):
180
+ "The `(state, meta)` stored under `rid`, or `None`"
181
+ data = await self.load(rid)
182
+ if data is None: return None
183
+ return ResponseState.from_dict(data['state']),{k:v for k,v in data.items() if k != 'state'}
184
+
148
185
  # %% ../nbs/06a_responses.ipynb #c9ca3744
149
186
  class ResponseTurn(BasicRepr):
150
187
  "A prepared Responses request for one provider call."
@@ -337,7 +374,7 @@ async def events(self:AsyncResponses, turn, finalize=None, stream=None):
337
374
  comp.message,comp.usage = Msg('assistant', texts + comp.message.content),usage
338
375
  for event in state.done_events(comp): yield event
339
376
  response = response_object(first.id, first.body, comp, first.previous.id if first.previous else None, first.created_at)
340
- if finalize: await finalize(next_state, comp)
377
+ if finalize and (extra := await finalize(next_state, comp)): response['usage'].update(extra)
341
378
  name = 'response.incomplete' if response['status'] == 'incomplete' else 'response.completed'
342
379
  yield state.event(name, response=response)
343
380
  except asyncio.CancelledError: raise
fastllm/types.py CHANGED
@@ -365,6 +365,7 @@ def tier_rate(meta, key, tier):
365
365
  # %% ../nbs/00_types.ipynb #8bfca02d
366
366
  @patch(as_prop=True)
367
367
  def cost(self:Completion):
368
+ if self.usage and 'cost' in self.usage.raw: return self.usage.raw['cost']
368
369
  meta = dict2obj(get_model_info(self.model, self.vendor_name))
369
370
  if not meta: return 0.0 # unregistered model (e.g. a custom base_url server): no pricing metadata
370
371
  api = api_registry[self.api_name]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-fastllm
3
- Version: 0.0.51
3
+ Version: 0.0.53
4
4
  Author-email: Kerem Turgutlu <keremturgutlu@gmail.com>
5
5
  License: Apache-2.0
6
6
  Project-URL: Repository, https://github.com/AnswerDotAI/fastllm
@@ -10,7 +10,7 @@ Classifier: Programming Language :: Python :: 3 :: Only
10
10
  Requires-Python: >=3.10
11
11
  Description-Content-Type: text/markdown
12
12
  Requires-Dist: fastcore>=2.1.18
13
- Requires-Dist: aidialog>=0.0.25
13
+ Requires-Dist: aidialog>=0.0.26
14
14
  Requires-Dist: fasttransport>=0.0.2
15
15
  Requires-Dist: pillow
16
16
 
@@ -1,5 +1,5 @@
1
- fastllm/__init__.py,sha256=9Ir0J8R-z0_JnZDe2PsJohUmaNENqlehYHPTO3403g8,131
2
- fastllm/_modidx.py,sha256=fQ6pg5H_5Pp8l7k12Fb5ca6uWmQewKtGtZBDi8hCuFg,44277
1
+ fastllm/__init__.py,sha256=p94hx8eEtzJ2eou5yZY7R3C9ab8YAXbWNrFNQoK6S-s,131
2
+ fastllm/_modidx.py,sha256=5WI8_unIttNYqjHBQBHf33C1OVgMgCcdO2SbdOk04Io,45637
3
3
  fastllm/acomplete.py,sha256=aP1ff9a7WKNhBd1kwKE2TJ-YyihLcdhd9-1Izi4wQP4,10772
4
4
  fastllm/anthropic.py,sha256=k0QeuRnl_CalfCq74WXN6llRQqRiAQ9d8ohn_0YYC7A,18386
5
5
  fastllm/chat.py,sha256=klji3SOYs5xyzrSFbNhy3uoQ2TSZ3a-8HTjvdRtaG5Q,25036
@@ -7,11 +7,11 @@ fastllm/codex.py,sha256=r6auZ8egia83aGkWcF4132AzW4SsBvKeDwg_CxyXj9E,5808
7
7
  fastllm/gemini.py,sha256=zbxNmI1cMUJJ10xIfBqPqh38hAQ0exsFKkhTXvG2-eE,16281
8
8
  fastllm/openai_chat.py,sha256=n5INfDCsAZIiKUImWeaX6SJ_OAJ_uMhw20HUkgFgdgM,12379
9
9
  fastllm/openai_responses.py,sha256=zsaOjkQUZ-7iuGPc-UpvnM6oAyqW09BDYwZ_ma4-1Qo,14346
10
- fastllm/responses.py,sha256=mFFaBpKNsq85sJjXIK5rYKb6WO7nlImEfowqDPf_yzA,19633
10
+ fastllm/responses.py,sha256=ASTWk_dghOfJozQAm6QAZ8VnkGFA-sBLGVeS60DfP3E,21303
11
11
  fastllm/streaming.py,sha256=i_FU_Mt-3F2lBEImYav8I5pEjUSKYk3JFIW3lkiXEb8,8813
12
- fastllm/types.py,sha256=BIZHwlzsbkZELjAib2oSFRab8gKBa216DNNeE_P68go,19525
13
- python_fastllm-0.0.51.dist-info/METADATA,sha256=Btmnr0P4mLlxL6J39LJEBg6Zw4KkTLu1-1o4ulP3RFY,18537
14
- python_fastllm-0.0.51.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
15
- python_fastllm-0.0.51.dist-info/entry_points.txt,sha256=WkWd04F3xVYFP5bsexaQe9Se6uelwE5ULoTtHWreO0s,133
16
- python_fastllm-0.0.51.dist-info/top_level.txt,sha256=F8qodL7nEGUHGmzzqfhNKCTIr1i0D6cvudOnm3z7o0Y,8
17
- python_fastllm-0.0.51.dist-info/RECORD,,
12
+ fastllm/types.py,sha256=q4rZHTD9sghHI8j5cNQRWmrQW_NO8zYa0KEibKGiSyI,19603
13
+ python_fastllm-0.0.53.dist-info/METADATA,sha256=5mJQJPAsu4tKE4Icowyjc1HaZCEE8xNRH7F1kUJVkKY,18537
14
+ python_fastllm-0.0.53.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
15
+ python_fastllm-0.0.53.dist-info/entry_points.txt,sha256=WkWd04F3xVYFP5bsexaQe9Se6uelwE5ULoTtHWreO0s,133
16
+ python_fastllm-0.0.53.dist-info/top_level.txt,sha256=F8qodL7nEGUHGmzzqfhNKCTIr1i0D6cvudOnm3z7o0Y,8
17
+ python_fastllm-0.0.53.dist-info/RECORD,,