jarvis-ai-assistant 0.1.213__py3-none-any.whl → 0.1.216__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.
- jarvis/__init__.py +1 -1
- jarvis/jarvis_agent/__init__.py +37 -0
- jarvis/jarvis_agent/builtin_input_handler.py +12 -1
- jarvis/jarvis_agent/edit_file_handler.py +44 -32
- jarvis/jarvis_agent/jarvis.py +17 -1
- jarvis/jarvis_code_agent/code_agent.py +18 -4
- jarvis/jarvis_platform/ai8.py +58 -6
- jarvis/jarvis_platform/base.py +37 -1
- jarvis/jarvis_platform/human.py +48 -3
- jarvis/jarvis_platform/kimi.py +54 -5
- jarvis/jarvis_platform/openai.py +48 -2
- jarvis/jarvis_platform/oyi.py +51 -1
- jarvis/jarvis_platform/registry.py +17 -7
- jarvis/jarvis_platform/tongyi.py +60 -3
- jarvis/jarvis_platform/yuanbao.py +51 -3
- jarvis/jarvis_platform_manager/main.py +65 -19
- jarvis/jarvis_platform_manager/service.py +66 -100
- jarvis/jarvis_utils/input.py +5 -3
- {jarvis_ai_assistant-0.1.213.dist-info → jarvis_ai_assistant-0.1.216.dist-info}/METADATA +1 -1
- {jarvis_ai_assistant-0.1.213.dist-info → jarvis_ai_assistant-0.1.216.dist-info}/RECORD +24 -24
- {jarvis_ai_assistant-0.1.213.dist-info → jarvis_ai_assistant-0.1.216.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.213.dist-info → jarvis_ai_assistant-0.1.216.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.213.dist-info → jarvis_ai_assistant-0.1.216.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.213.dist-info → jarvis_ai_assistant-0.1.216.dist-info}/top_level.txt +0 -0
@@ -180,7 +180,7 @@ def start_service(
|
|
180
180
|
request: ChatCompletionRequest,
|
181
181
|
) -> Response:
|
182
182
|
"""Create a chat completion in OpenAI-compatible format.
|
183
|
-
|
183
|
+
|
184
184
|
Returns:
|
185
185
|
Response: Either a JSONResponse or StreamingResponse depending on the request.
|
186
186
|
"""
|
@@ -233,7 +233,7 @@ def start_service(
|
|
233
233
|
if stream:
|
234
234
|
# Return streaming response
|
235
235
|
return StreamingResponse(
|
236
|
-
stream_chat_response(platform, message_text, model),
|
236
|
+
stream_chat_response(platform, message_text, model), # type: ignore
|
237
237
|
media_type="text/event-stream",
|
238
238
|
)
|
239
239
|
|
@@ -258,36 +258,36 @@ def start_service(
|
|
258
258
|
response_text,
|
259
259
|
)
|
260
260
|
|
261
|
-
return JSONResponse(
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
"
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
261
|
+
return JSONResponse(
|
262
|
+
{
|
263
|
+
"id": completion_id,
|
264
|
+
"object": "chat.completion",
|
265
|
+
"created": int(time.time()),
|
266
|
+
"model": model,
|
267
|
+
"choices": [
|
268
|
+
{
|
269
|
+
"index": 0,
|
270
|
+
"message": {"role": "assistant", "content": response_text},
|
271
|
+
"finish_reason": "stop",
|
272
|
+
}
|
273
|
+
],
|
274
|
+
"usage": {
|
275
|
+
"prompt_tokens": len(message_text) // 4,
|
276
|
+
"completion_tokens": len(response_text) // 4,
|
277
|
+
"total_tokens": (len(message_text) + len(response_text)) // 4,
|
278
|
+
},
|
279
|
+
}
|
280
|
+
)
|
279
281
|
except Exception as exc:
|
280
282
|
raise HTTPException(status_code=500, detail=str(exc))
|
281
283
|
|
282
|
-
async def stream_chat_response(
|
283
|
-
platform: Any, message: str, model_name: str
|
284
|
-
) -> Any:
|
284
|
+
async def stream_chat_response(platform: Any, message: str, model_name: str) -> Any:
|
285
285
|
"""Stream chat response in OpenAI-compatible format."""
|
286
286
|
completion_id = f"chatcmpl-{str(uuid.uuid4())}"
|
287
287
|
created_time = int(time.time())
|
288
288
|
conversation_id = str(uuid.uuid4())
|
289
289
|
|
290
|
-
#
|
290
|
+
# Send the initial chunk with the role
|
291
291
|
initial_data = {
|
292
292
|
"id": completion_id,
|
293
293
|
"object": "chat.completion.chunk",
|
@@ -300,21 +300,17 @@ def start_service(
|
|
300
300
|
yield f"data: {json.dumps(initial_data)}\n\n"
|
301
301
|
|
302
302
|
try:
|
303
|
-
#
|
304
|
-
|
303
|
+
# Use the streaming-capable chat method
|
304
|
+
response_generator = platform.chat(message)
|
305
305
|
|
306
|
-
# Record full response
|
307
306
|
full_response = ""
|
307
|
+
has_content = False
|
308
308
|
|
309
|
-
#
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
for i in range(0, len(response), chunk_size):
|
314
|
-
chunk = response[i : i + chunk_size]
|
309
|
+
# Iterate over the generator and stream chunks
|
310
|
+
for chunk in response_generator:
|
311
|
+
if chunk:
|
312
|
+
has_content = True
|
315
313
|
full_response += chunk
|
316
|
-
|
317
|
-
# Create and send chunk
|
318
314
|
chunk_data = {
|
319
315
|
"id": completion_id,
|
320
316
|
"object": "chat.completion.chunk",
|
@@ -328,13 +324,10 @@ def start_service(
|
|
328
324
|
}
|
329
325
|
],
|
330
326
|
}
|
331
|
-
|
332
327
|
yield f"data: {json.dumps(chunk_data)}\n\n"
|
333
328
|
|
334
|
-
|
335
|
-
|
336
|
-
else:
|
337
|
-
# If no output, send an empty content chunk
|
329
|
+
if not has_content:
|
330
|
+
no_response_message = "No response from model."
|
338
331
|
chunk_data = {
|
339
332
|
"id": completion_id,
|
340
333
|
"object": "chat.completion.chunk",
|
@@ -343,15 +336,15 @@ def start_service(
|
|
343
336
|
"choices": [
|
344
337
|
{
|
345
338
|
"index": 0,
|
346
|
-
"delta": {"content":
|
339
|
+
"delta": {"content": no_response_message},
|
347
340
|
"finish_reason": None,
|
348
341
|
}
|
349
342
|
],
|
350
343
|
}
|
351
344
|
yield f"data: {json.dumps(chunk_data)}\n\n"
|
352
|
-
full_response =
|
345
|
+
full_response = no_response_message
|
353
346
|
|
354
|
-
#
|
347
|
+
# Send the final chunk with finish_reason
|
355
348
|
final_data = {
|
356
349
|
"id": completion_id,
|
357
350
|
"object": "chat.completion.chunk",
|
@@ -361,72 +354,45 @@ def start_service(
|
|
361
354
|
}
|
362
355
|
yield f"data: {json.dumps(final_data)}\n\n"
|
363
356
|
|
364
|
-
# Send [DONE] marker
|
357
|
+
# Send the [DONE] marker
|
365
358
|
yield "data: [DONE]\n\n"
|
366
359
|
|
367
|
-
# Log
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
log_data = {
|
374
|
-
"conversation_id": conversation_id,
|
375
|
-
"timestamp": timestamp,
|
376
|
-
"model": model_name,
|
377
|
-
"message": message,
|
378
|
-
"response": full_response,
|
379
|
-
}
|
380
|
-
|
381
|
-
with open(log_file, "w", encoding="utf-8", errors="ignore") as f:
|
382
|
-
json.dump(log_data, f, ensure_ascii=False, indent=2)
|
383
|
-
|
384
|
-
PrettyOutput.print(
|
385
|
-
f"Stream conversation logged to {log_file}", OutputType.INFO
|
360
|
+
# Log the full conversation
|
361
|
+
log_conversation(
|
362
|
+
conversation_id,
|
363
|
+
[{"role": "user", "content": message}],
|
364
|
+
model_name,
|
365
|
+
full_response,
|
386
366
|
)
|
387
367
|
|
388
368
|
except Exception as exc:
|
389
|
-
|
390
|
-
error_msg
|
391
|
-
print(f"Streaming error: {error_msg}")
|
369
|
+
error_msg = f"Error during streaming: {str(exc)}"
|
370
|
+
PrettyOutput.print(error_msg, OutputType.ERROR)
|
392
371
|
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
"model": model_name,
|
399
|
-
"choices": [
|
400
|
-
{
|
401
|
-
"index": 0,
|
402
|
-
"delta": {"content": error_msg},
|
403
|
-
"finish_reason": "stop",
|
404
|
-
}
|
405
|
-
],
|
406
|
-
}
|
407
|
-
)
|
408
|
-
yield f"data: {res}\n\n"
|
409
|
-
yield f"data: {json.dumps({'error': {'message': error_msg, 'type': 'server_error'}})}\n\n"
|
410
|
-
yield "data: [DONE]\n\n"
|
411
|
-
|
412
|
-
# Log error to file
|
413
|
-
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
414
|
-
log_file = os.path.join(
|
415
|
-
logs_dir, f"stream_error_{conversation_id}_{timestamp}.json"
|
416
|
-
)
|
417
|
-
|
418
|
-
log_data = {
|
419
|
-
"conversation_id": conversation_id,
|
420
|
-
"timestamp": timestamp,
|
372
|
+
# Send error information in the stream
|
373
|
+
error_chunk = {
|
374
|
+
"id": completion_id,
|
375
|
+
"object": "chat.completion.chunk",
|
376
|
+
"created": created_time,
|
421
377
|
"model": model_name,
|
422
|
-
"
|
423
|
-
|
378
|
+
"choices": [
|
379
|
+
{
|
380
|
+
"index": 0,
|
381
|
+
"delta": {"content": error_msg},
|
382
|
+
"finish_reason": "stop",
|
383
|
+
}
|
384
|
+
],
|
424
385
|
}
|
386
|
+
yield f"data: {json.dumps(error_chunk)}\n\n"
|
387
|
+
yield "data: [DONE]\n\n"
|
425
388
|
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
389
|
+
# Log the error
|
390
|
+
log_conversation(
|
391
|
+
conversation_id,
|
392
|
+
[{"role": "user", "content": message}],
|
393
|
+
model_name,
|
394
|
+
response=f"ERROR: {error_msg}",
|
395
|
+
)
|
430
396
|
|
431
397
|
# Run the server
|
432
398
|
uvicorn.run(app, host=host, port=port)
|
jarvis/jarvis_utils/input.py
CHANGED
@@ -109,6 +109,7 @@ class FileCompleter(Completer):
|
|
109
109
|
(ot("Clear"), "清除历史"),
|
110
110
|
(ot("ToolUsage"), "工具使用说明"),
|
111
111
|
(ot("ReloadConfig"), "重新加载配置"),
|
112
|
+
(ot("SaveSession"), "保存当前会话"),
|
112
113
|
]
|
113
114
|
)
|
114
115
|
|
@@ -222,10 +223,11 @@ def get_multiline_input(tip: str) -> str:
|
|
222
223
|
if last_msg:
|
223
224
|
try:
|
224
225
|
# 使用xsel将内容复制到剪贴板
|
225
|
-
|
226
|
-
|
226
|
+
subprocess.run(
|
227
|
+
["xsel", "-b", "-i"], input=last_msg.encode("utf-8"), check=True
|
228
|
+
)
|
227
229
|
PrettyOutput.print("已将最后一条消息复制到剪贴板", OutputType.INFO)
|
228
|
-
except
|
230
|
+
except subprocess.CalledProcessError as e:
|
229
231
|
PrettyOutput.print(f"复制到剪贴板失败: {e}", OutputType.ERROR)
|
230
232
|
else:
|
231
233
|
PrettyOutput.print("没有可复制的消息", OutputType.INFO)
|
@@ -1,13 +1,13 @@
|
|
1
|
-
jarvis/__init__.py,sha256
|
2
|
-
jarvis/jarvis_agent/__init__.py,sha256=
|
3
|
-
jarvis/jarvis_agent/builtin_input_handler.py,sha256=
|
4
|
-
jarvis/jarvis_agent/edit_file_handler.py,sha256=
|
5
|
-
jarvis/jarvis_agent/jarvis.py,sha256=
|
1
|
+
jarvis/__init__.py,sha256=rTb7P5Us8MKb-Bgo5O9dZfaWM0pDjYYSSZCgb59Yois,75
|
2
|
+
jarvis/jarvis_agent/__init__.py,sha256=Ftod6FDMlGJ_DuueI2W19whAmpldVAsGYvlgbvqC55w,33260
|
3
|
+
jarvis/jarvis_agent/builtin_input_handler.py,sha256=lcw-VBm8-CVcblxEbGU4dVD6IixgXTLz9uBrv9Y6p20,2710
|
4
|
+
jarvis/jarvis_agent/edit_file_handler.py,sha256=vKx26I4yOQwiQHNfkqMJ44Ybf90n37mojTcXNQQy-hw,17382
|
5
|
+
jarvis/jarvis_agent/jarvis.py,sha256=4LBtAh9_AuQcjvqBFInqY19eyEJVJtGH4py32yu8olc,6287
|
6
6
|
jarvis/jarvis_agent/main.py,sha256=c6bQe-8LXvW2-NBn9Rn_yPYdrwnkJ8KQaSFY2cPvkxw,2775
|
7
7
|
jarvis/jarvis_agent/output_handler.py,sha256=P7oWpXBGFfOsWq7cIhS_z9crkQ19ES7qU5pM92KKjAs,1172
|
8
8
|
jarvis/jarvis_agent/shell_input_handler.py,sha256=zVaKNthIHJh1j4g8_-d3w5ahNH9aH-ZNRSOourQpHR4,1328
|
9
9
|
jarvis/jarvis_code_agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
|
-
jarvis/jarvis_code_agent/code_agent.py,sha256=
|
10
|
+
jarvis/jarvis_code_agent/code_agent.py,sha256=mQosGLngkM23sMAW9BJtl7XBPFmwOiIZUDG9tb7xAq8,18571
|
11
11
|
jarvis/jarvis_code_agent/lint.py,sha256=LZPsfyZPMo7Wm7LN4osZocuNJwZx1ojacO3MlF870x8,4009
|
12
12
|
jarvis/jarvis_code_analysis/code_review.py,sha256=uCCbGd4Y1RjDzhZoVE8JdN2avlwOfqimSDIrcM-KMew,30456
|
13
13
|
jarvis/jarvis_code_analysis/checklists/__init__.py,sha256=LIXAYa1sW3l7foP6kohLWnE98I_EQ0T7z5bYKHq6rJA,78
|
@@ -45,18 +45,18 @@ jarvis/jarvis_methodology/main.py,sha256=-PqsWvtpUJkkhiGgV-1JegEnEZBmv8SHnNMNNm_
|
|
45
45
|
jarvis/jarvis_multi_agent/__init__.py,sha256=sDd3sK88dS7_qAz2ywIAaEWdQ4iRVCiuBu2rQQmrKbU,4512
|
46
46
|
jarvis/jarvis_multi_agent/main.py,sha256=h7VUSwoPrES0XTK8z5kt3XLX1mmcm8UEuFEHQOUWPH4,1696
|
47
47
|
jarvis/jarvis_platform/__init__.py,sha256=WLQHSiE87PPket2M50_hHzjdMIgPIBx2VF8JfB_NNRk,105
|
48
|
-
jarvis/jarvis_platform/ai8.py,sha256=
|
49
|
-
jarvis/jarvis_platform/base.py,sha256
|
50
|
-
jarvis/jarvis_platform/human.py,sha256=
|
51
|
-
jarvis/jarvis_platform/kimi.py,sha256=
|
52
|
-
jarvis/jarvis_platform/openai.py,sha256=
|
53
|
-
jarvis/jarvis_platform/oyi.py,sha256=
|
54
|
-
jarvis/jarvis_platform/registry.py,sha256=
|
55
|
-
jarvis/jarvis_platform/tongyi.py,sha256=
|
56
|
-
jarvis/jarvis_platform/yuanbao.py,sha256=
|
48
|
+
jarvis/jarvis_platform/ai8.py,sha256=yi7xG8ld4Yrf7drz-uu_JT_XCGYRB0obhygt-jKik8o,10871
|
49
|
+
jarvis/jarvis_platform/base.py,sha256=-XegiAS8G_nzwsWPOVEAQ2iTxE33fxu5-TWV4c3Pz-g,8981
|
50
|
+
jarvis/jarvis_platform/human.py,sha256=quB5yMMoyU8w55IrVqa9F4ITOpF2TdM0GHQVD9zyWgk,4925
|
51
|
+
jarvis/jarvis_platform/kimi.py,sha256=OEiRNlC4Ao3PrO_yiogEwgMtTobehoEm_X4CMGT-Aas,15315
|
52
|
+
jarvis/jarvis_platform/openai.py,sha256=ccGqsU2cFfd5324P7SH1tSmFABpvto8fytmxQGkr3BA,6412
|
53
|
+
jarvis/jarvis_platform/oyi.py,sha256=GvVooV8ScRqDb9QxJdINtdZwsx6PUIdo1-bt9k0hmqY,12604
|
54
|
+
jarvis/jarvis_platform/registry.py,sha256=1bMy0YZUa8NLzuZlKfC4CBtpa0iniypTxUZk0Hv6g9Y,8415
|
55
|
+
jarvis/jarvis_platform/tongyi.py,sha256=vSK1b4NhTeHbNhTgGRj4PANXptwCAwitczwK8VXwWwU,22921
|
56
|
+
jarvis/jarvis_platform/yuanbao.py,sha256=W4yEsjkxnwi681UnAX0hV8vVPuNRmn6lRGZ3G-d74nw,23007
|
57
57
|
jarvis/jarvis_platform_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
58
|
-
jarvis/jarvis_platform_manager/main.py,sha256=
|
59
|
-
jarvis/jarvis_platform_manager/service.py,sha256=
|
58
|
+
jarvis/jarvis_platform_manager/main.py,sha256=LxlXSfIfmkYNcajOG_XvvlmwlSWSGb0DmbzIDSHHYOU,18330
|
59
|
+
jarvis/jarvis_platform_manager/service.py,sha256=hQGWQ2qAlzm_C_lNQDuLORQ4rmjR1P1-V3ou7l2Bv0s,13622
|
60
60
|
jarvis/jarvis_smart_shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
61
61
|
jarvis/jarvis_smart_shell/main.py,sha256=DbhRSP1sZfSIaTltP1YWVDSQOTYEsbiOnfO9kSYwcNs,6959
|
62
62
|
jarvis/jarvis_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -83,14 +83,14 @@ jarvis/jarvis_utils/file_processors.py,sha256=XiM248SHS7lLgQDCbORVFWqinbVDUawYxW
|
|
83
83
|
jarvis/jarvis_utils/git_utils.py,sha256=7AZblSD4b76vXxaDFkmZOy5rNkwvkwQQxGUy3NAusDQ,21641
|
84
84
|
jarvis/jarvis_utils/globals.py,sha256=WzZh_acNfHJj1LDulhyLQ7cojksBy0gdrITe0vH1XA0,3901
|
85
85
|
jarvis/jarvis_utils/http.py,sha256=Uqt1kcz0HWnAfXHHi1fNGwLb2lcVUqpbrG2Uk_-kcIU,4882
|
86
|
-
jarvis/jarvis_utils/input.py,sha256=
|
86
|
+
jarvis/jarvis_utils/input.py,sha256=XNnSOY7EEcqxA2DZcCQ40l0q30b1Lu7ijbfKjq6WWCA,8965
|
87
87
|
jarvis/jarvis_utils/methodology.py,sha256=-cvM6pwgJK7BXCYg2uVjIId_j3v5RUh2z2PBcK_2vj4,8155
|
88
88
|
jarvis/jarvis_utils/output.py,sha256=PRCgudPOB8gMEP3u-g0FGD2c6tBgJhLXUMqNPglfjV8,10813
|
89
89
|
jarvis/jarvis_utils/tag.py,sha256=f211opbbbTcSyzCDwuIK_oCnKhXPNK-RknYyGzY1yD0,431
|
90
90
|
jarvis/jarvis_utils/utils.py,sha256=BoRwLcixdf7mU3Tawe95ygGhQpkMffrFYLYhPwIvw8A,14498
|
91
|
-
jarvis_ai_assistant-0.1.
|
92
|
-
jarvis_ai_assistant-0.1.
|
93
|
-
jarvis_ai_assistant-0.1.
|
94
|
-
jarvis_ai_assistant-0.1.
|
95
|
-
jarvis_ai_assistant-0.1.
|
96
|
-
jarvis_ai_assistant-0.1.
|
91
|
+
jarvis_ai_assistant-0.1.216.dist-info/licenses/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
|
92
|
+
jarvis_ai_assistant-0.1.216.dist-info/METADATA,sha256=h2xfZU2lBL5kVLTBDEXchXrSf5iOo19QISqjp1E2V64,19564
|
93
|
+
jarvis_ai_assistant-0.1.216.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
94
|
+
jarvis_ai_assistant-0.1.216.dist-info/entry_points.txt,sha256=SF46ViTZcQVZEfbqzJDKKVc9TrN1x-P1mQ6wup7u2HY,875
|
95
|
+
jarvis_ai_assistant-0.1.216.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
|
96
|
+
jarvis_ai_assistant-0.1.216.dist-info/RECORD,,
|
File without changes
|
{jarvis_ai_assistant-0.1.213.dist-info → jarvis_ai_assistant-0.1.216.dist-info}/entry_points.txt
RENAMED
File without changes
|
{jarvis_ai_assistant-0.1.213.dist-info → jarvis_ai_assistant-0.1.216.dist-info}/licenses/LICENSE
RENAMED
File without changes
|
{jarvis_ai_assistant-0.1.213.dist-info → jarvis_ai_assistant-0.1.216.dist-info}/top_level.txt
RENAMED
File without changes
|