From a3867d25bb05c8c7320e8ecf0836d9a605d7dc0b Mon Sep 17 00:00:00 2001 From: yumoqing Date: Fri, 27 Mar 2026 18:30:05 +0800 Subject: [PATCH] bugfix --- llmage/llmclient.py | 46 +++++++++++++++++++++++++++++++++++-------- models/llmusage.xlsx | Bin 18801 -> 18801 bytes 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/llmage/llmclient.py b/llmage/llmclient.py index d3e65b1..ad1f758 100644 --- a/llmage/llmclient.py +++ b/llmage/llmclient.py @@ -110,7 +110,7 @@ async def get_llm(llmid): sql = """select x.*, z.input_fields from ( -select a.*, e.ioid, e.stream +select a.*, e.ioid, e.callbackurl, e.stream from llm a, upapp c, uapiset d, uapi e where a.upappid = c.id and c.apisetid = d.id @@ -176,15 +176,19 @@ async def uapi_request(request, llm, sor, callerid, callerorgid, params_kw=None) txt = '' luid = getID() try: - t1 = time.time() - t2 = t1 - t3 = t1 + start_timestamp = time.time() + responsed_seconds = None + finish_seconds = None + t2 = start_timestamp + t3 = start_timestamp first = True + usage = None async for l in uapi.stream_linify(llm.upappid, llm.apiname, userid, params=params_kw): if first: first = False t2 = time.time() + responsed_seconds = t2 - start_timestamp if isinstance(l, bytes): l = l.decode('utf-8') if l[-1] == '\n': @@ -205,13 +209,17 @@ async def uapi_request(request, llm, sor, callerid, callerorgid, params_kw=None) if d.get('content'): txt = txt + d['content'] yield_it = True + if d.get('usage'): + usage = d['usage'] d['llmusageid'] = luid outlines.append(d) yield json.dumps(d) + '\n' - usage = outlines[-1].get('usage',{}) + if usage is None: + error(f'{llm=} response has not usage') t3 = time.time() - usage['response_time'] = t2 - t1 - usage['finish_time'] = t3 - t1 + finish_seconds = t3 - start_timestamp + if responsed_seconds is None: + responsed_seconds = finish_seconds if not usage.get('completion_tokens'): usage['completion_tokens'] = len(txt) if not usage.get('prompt_tokens'): @@ -221,7 +229,29 @@ async def uapi_request(request, llm, sor, callerid, callerorgid, params_kw=None) if params_kw.negitive_prompt: cnt += len(params_kw.negitive_promot) usage['prompt_tokens'] = cnt - u = await write_llmusage(luid, llm, callerid, usage, params_kw, outlines, sor) + llmusage = DictObject() + llmusage.id = luid + llmusage.llmid = llm.id + llmusage.use_date = curDateString() + llmusage.use_time = timestampstr() + llmusage.userid = callerid + llmusage.usage = json.dumps(usage) + llmusage.ioinfo = json.dumps({ + "input": params_kw, + "output": outlines + }) + llmusage.transno = params_kw.transno + llmusage.responsed_seconds = responsed_seconds + llmusage.finish_seconds = finish_seconds + llmusage.status = 'SUCCEEDED' + if llm.ppid and callerorgid: + chargings = await llm_query_price(llm.ppid, usage) + else: + llmusage.amount = 0 + llmusage.cost = 0 + llmusage.userorgid = callerorgid + llmusage.ownerid = llm.orgid + await sor.C('llmusage', llmusage) if llm.ppid and callerorgid != llm.ownerid: debug(f'{usage=},{llm.ownerid=},{callerorgid=}') await llm_accounting(request, llm.id, usage, callerorgid, callerid) diff --git a/models/llmusage.xlsx b/models/llmusage.xlsx index 9de815aa77e1866cd4cd1edb182ef287ded34376..3b504c57a0463be12e773ebe648402ab711972d9 100644 GIT binary patch delta 4265 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 qxx<-Is;c}ri6~E1Ih