From e2769f2d2d391d0ddb938c286034b728f7ad96d7 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Thu, 20 Nov 2025 00:53:41 +0000 Subject: [PATCH] ai agent! --- core/__pycache__/views.cpython-311.pyc | Bin 16576 -> 17663 bytes core/views.py | 89 +++++++++++++++---------- 2 files changed, 54 insertions(+), 35 deletions(-) diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 2726ef65d74c84758f89458140a6ceb5f9f773ed..53fe095954643d42691694fc728d4b07f90e430e 100644 GIT binary patch delta 2736 zcmaJ=Z%iBK8GrBm4@|Iu*!cJp{2CjuA=vSj5>gTy(^7;=aYEV(lBMD5JMa+fOPvnL$+8`mquDXq)jVj(l+J8CPmwnoSCJdNKEOZOq$e5W@@&4n6y1- z$026PPUq*I_j%vv_xzsU^ZM3ziT`{^SU#<o+AfjRs2QtlRc4zU&i3lKn3Oyf zEQE3n@xmTC^6L8Ba9`ftV*`qc0{q zR*R&UDl|alwu&z|RHJ1YnJ&3;2?;-v8#PsHyEt@(g!W10r!Hq__pZ}M>2L)JAsKR8 zl%UVioN1DcOwU=!Lr5T*Jv_l!GJ7>aeNFP-{}uGv(*)vwC7W{fTC=T8t=z;|caI#7 zcr>u_7c|UgSILjC8%YOu$Sv%v_|lPzhtM49K|(iyG_>Gz(Pm)U{Kzs|(aoS`;(7D% zR%-(D@MUZo;9=YIE)Tx|#6mk1fWYaDy$ZN=SBIHi*{CprRX*Fzw%5q#02DK*&vPX z#H6tuf5ELBw>B&9>#X(zmvq(tofF6xRNnFZoLn{EF!a7=csWM%m=nb`i)k#f0>_Ft zHHTxVWRm6?5lbojE{oX}HkOuH22Pwyv%JL7iNty3WS}+6(y@5uG=>bkD5RD+22f}$ zuwptP`OV+lDAM!nEKUiSo|9Ox zI7zQ?$#ha9bqI41qa`lIi+;1YxA*N)#d#o_1#nJ$N}^QY#GBD$Sb~~m=8#dU?l<@2 z@p4(7g?6C3MOK(g2}zs;s@!4%WQdgtU@z;R_wUCv!vG737SER215CbD3RJ*=%1OTL z{wD%z^~%{5G9vcQ0>Bw9eRe;dWf@MYELbV#_u<}mSt!r;;7!7~~>jH*07|Ap~!h_cBimq(P+ zv9p-t;Y5i7ekGMoFy+}NXn~tMkC)@Lqy>5yoZ!yZu>hqdGpVp54t$UBDE}Ntn(i9} znxAKt*de;zAvl4ou&9}LG$U%}oMt{$9vqr%yiah#4`6xUL~~~(c12R&8g%xjwMad5 zMJFnv36rH*EX6Oef>^#>q61=B`Dn1GZXLWI!%wstmER10Ld+|%!)wH}^6$gz+2On` zQm{o-Tjb%s&Rp>0=}Xf^bjZF;Y?tgBu|;)UuDe*LdO|lFZw7z47aVx=RJcHeRVw_@ z-CuAYeSrO&xW8!7b$1kv$mQKO>AJne8r1E-ZoFBq23}J=W5qgSxV4DDY$Kzm?HkRk zWowEJ2zxKf7v-ztdFMdEIZ#CUmd>sA&dU=QCyEI5M#%;WAXXy=uE^Q{OtB zGj8FYPptRwzy=;rU!757=d!^1J!nkD1HjoeqHzWbQLqo(f$O0ScSLnZHa))FXi4=? zEkCo|G~N!Wfs^p&@u>nnrIy}DH87Ma_ytv52IM?mDc}_quWaJ3oMF2TxxPa@eq=$e zu7U#}{E}0h!$qWP>D)07m9K}KlTs@aoDSw_?Do{%*wRGdFBW5Bx0k`wFc&z=n9{u6y zNKMp8-Z7A{xMLau|1PNq|E_WH7-_g0(t)oM1o$c$Az+c$o2UA8c}ryPRJU%U+c4Fq g^oRaVtSfEdR^rNyfpCoId5Y40{{R3 delta 1712 zcmaJ=ZA=?w9DnYv<)w7AKwH|btPg#mYhlM|?PRnQS~eUTgKXdy+<2+nxs}1S++8;| zuUq_Jq90619zT!`T@xn~3ySJDJr#Gs!wDanj{)936u>=&Qh^Sj^w z{rUf&yT3mm*4`zmKi{`c1MvE5;y~Q*e^8x)7q&#da{NvlnKUYq%91qFzRRRkeiL)X$e5V=I1wip^8&d@0PrQ=g_W+Bs?m6D zz1>o(7p6p4(FcHx3H_=zs2FR(*|@*d`7U5=1q%w9bg0Q~qzN2?&Y4WFLJ56G%Ze{#6U@h^i9SZozPiwCbM!T6Vq54L;$9wwv}6y zbZI@KP1jTcF;J`pz@!z)Zc9}yw+ zNH`X~=CKUcNp)$xRK~cj;z$5^lF@PmQ=P8iY)&Bh_aY{3MJ{#}831pSF2GX+7zUi` zI+&$~!F2);?{K?Rv#eR9@L}*SECO(oIAypf1As$E(uR`3{Cinlj9W6?1s{`4)3T?~ zQ85UQ=%CnHl<>D=DD6^-dU<`@UQ3nXmVv8aKpMZ1$~Ro&E%i?u5$6jYiu@-dV0@BM zQj6VtI`PCFpLC$JIup7@>5R<_RB4NYz}tc}&7YC?D_0*h_o#JoK}fMM1}75J(=m=g zZEe<$xJYXPG=xJ}SSZ{OM0OhTteE0C0Xy=nkeU+VG%E7$Rak|A-&7X! zAj>gv?lP`ClVSx?DH-XdX&QC5@1SpvzDqdKv5slT{0)hfF3cQc# zP``(N5A$c`vG|zC&Wg`!F?rF+*hGR8Sx)3r*aLkSvZJ+-L1j{epF*Chc}zaSTkxq- zRro$JgjT}y#0k`U?C$N3tRa*$gk(c#%kItDk8az1n>KG=O*yRjGSJ}KDW@E+dps$jwn1cIT_gLZ&>xumj3q{c{E8PUiK%=DHWY6JDy!?)T^R`}3f|7$vvN2kvR_ zX!8IxohBb0eA@Cui+o`$dulv)YCI1(MO(1R$=Qvhw4Ri(c#Akm?f@`D^pejDuYykj zvBlD-7%*ZD#!W~6eEF8yzM$JM)9Yqh4xg1Tz9nBx$YwfgPUg%>*_^}#={rxW43;Q~ zMmyVY%QkVltzEX!n{MxXPhO>IaBsB+mT!LT$+kvwtOIKLh^FJBnR21av%(M;b~@c7y#`P{|aiA&kwNG>>%>EAy3y6if# z8H}urt_KI@;Na5G(vUnH%k=DC*xhm+%(>bhdS&PFJRlp~d$0{%8C715b-TN}e^%g& zSQyx_`PXfJx$6yiYzDXe4iO<`n;#FOA*u`mBi3SEt&3=gsPY?s2YZ^&(BMaH#L?FZ z9@7LC9=Dp#R8UXUB<4@b358d<6;5jgjMS6%NZo**da73s7|~Sp4`Lp@*=;30T}^dQ R5S}X}QJx3?hrAP){Rfx(zsvvt diff --git a/core/views.py b/core/views.py index 1bc3e9a..73e0364 100644 --- a/core/views.py +++ b/core/views.py @@ -210,14 +210,14 @@ def chat_view(request, conversation_id=None): **Execution Loop:** -1. You issue a command. -2. The system executes it. -3. The system returns a result message to you, like `[SYSTEM] Command 'add_task' executed successfully. New task ID: 5`. -4. You can then issue another command. +1. You can issue a series of commands to be executed sequentially. +2. The system executes each command and provides a result. +3. The loop will stop if you call `send_message` or after a maximum of 7 iterations. **VERY IMPORTANT:** -- To talk to the user, you MUST use the `send_message` command. -- ONLY use other commands if the user explicitly asks you to `add`, `edit`, or `delete` tasks. +- To talk to the user, you MUST use the `send_message` command. This command will STOP the execution loop. +- If you need to perform multiple actions (e.g., add a task and then comment on it), issue the action commands (`add_task`, `edit_task`, etc.) *before* using `send_message`. +- ONLY use commands other than `send_message` if the user explicitly asks you to `add`, `edit`, or `delete` tasks. **Examples:** @@ -259,20 +259,25 @@ def chat_view(request, conversation_id=None): "content": f"Here is the current list of tasks:\n{task_list_str}" } - logger.info("Sending request to AI...") - response = LocalAIApi.create_response({ - "input": [ - system_message, - tasks_context, - ] + history, - "text": {"format": {"type": "json_object"}}, - }) + logger.info("Starting AI processing loop...") - if not response.get("success"): - logger.error(f"AI API request failed with status {response.get('status')}. Full error: {response.get('response')}") - ai_text = "I couldn't process that. Please try again." - Message.objects.create(conversation=selected_conversation, content=ai_text, sender='ai') - else: + for i in range(7): # Loop up to 7 times + logger.info(f"AI loop iteration {i+1}") + + response = LocalAIApi.create_response({ + "input": [ + system_message, + tasks_context, + ] + history, + "text": {"format": {"type": "json_object"}}, + }) + + if not response.get("success"): + logger.error(f"AI API request failed with status {response.get('status')}. Full error: {response.get('response')}") + ai_text = "I couldn't process that. Please try again." + Message.objects.create(conversation=selected_conversation, content=ai_text, sender='ai') + break + logger.info(f"AI raw response: {response}") ai_text = LocalAIApi.extract_text(response) logger.info(f"Extracted AI text: {ai_text}") @@ -281,23 +286,37 @@ def chat_view(request, conversation_id=None): logger.warning("AI response was empty.") ai_text = "I couldn't process that. Please try again." Message.objects.create(conversation=selected_conversation, content=ai_text, sender='ai') - else: - ai_message_content = ai_text - sender = 'ai' - - try: - command_json = json.loads(ai_text) - if 'command' in command_json: - command_name = command_json.get('command', {}).get('name') - command_result = execute_command(command_json['command']) - - ai_message_content = command_result - sender = 'ai' if command_name == 'send_message' else 'system' - except (json.JSONDecodeError, TypeError): - # Not a JSON command, treat as a raw message. - pass + break + + try: + command_json = json.loads(ai_text) + if 'command' in command_json: + command_name = command_json.get('command', {}).get('name') + command_result = execute_command(command_json['command']) + + sender = 'ai' if command_name == 'send_message' else 'system' + Message.objects.create(conversation=selected_conversation, content=command_result, sender=sender) + + if command_name == 'send_message': + break # Exit loop if send_message is called + + # Add system message with command result to history for next iteration + history.append({"role": "user", "content": command_result}) - Message.objects.create(conversation=selected_conversation, content=ai_message_content, sender=sender) + else: + # If it's a JSON but not a command, save it as a message and break + Message.objects.create(conversation=selected_conversation, content=ai_text, sender='ai') + break + + except (json.JSONDecodeError, TypeError): + # Not a JSON command, treat as a raw message and break + Message.objects.create(conversation=selected_conversation, content=ai_text, sender='ai') + break + else: + # This block executes if the loop completes without a 'break' + logger.warning("AI loop finished after 7 iterations without sending a message.") + final_message = "I seem to be stuck in a loop. Could you clarify what you'd like me to do?" + Message.objects.create(conversation=selected_conversation, content=final_message, sender='ai') except Exception as e: logger.error(f"An unexpected error occurred: {e}", exc_info=True)