From 2502d2f66385f4a4b749815d5b09e48d02b14c04 Mon Sep 17 00:00:00 2001 From: liubiren Date: Mon, 14 Sep 2026 20:02:11 +0800 Subject: [PATCH] 1 --- agent/application/pages/conversation.py | 6 ++---- agent/application/states/conversation.py | 16 +++++---------- agent/application/workshop/book_flight.py | 24 +++++++++++++++------- agent/database.db | Bin 147456 -> 159744 bytes 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/agent/application/pages/conversation.py b/agent/application/pages/conversation.py index 554a0fb..236cd77 100644 --- a/agent/application/pages/conversation.py +++ b/agent/application/pages/conversation.py @@ -431,12 +431,10 @@ def tool_call(item: MessageHistoryItem) -> rx.Component: "square-function", width="14px", height="14px", - color="var(--prismui-color-3)", ), rx.text( item.title, font_size="var(--prismui-font-size-1)", - color="var(--prismui-color-3)", class_name=rx.cond(item.is_running, "is_running", None), ), align_items="center", @@ -451,13 +449,12 @@ def tool_call(item: MessageHistoryItem) -> rx.Component: margin="4px 0", line_height="1.6", font_size="var(--prismui-font-size-1)", - color="var(--prismui-color-3)", ), # 审批 rx.cond( item.has_approval, rx.hstack( - rx.input( + rx.text_area( placeholder="请输入", # 值绑定审批用户提示词 value=item.approval_user_prompt, @@ -495,6 +492,7 @@ def tool_call(item: MessageHistoryItem) -> rx.Component: ), rx.fragment(), ), + width="100%", ) diff --git a/agent/application/states/conversation.py b/agent/application/states/conversation.py index aee44fa..75cd840 100644 --- a/agent/application/states/conversation.py +++ b/agent/application/states/conversation.py @@ -187,18 +187,12 @@ class ConversationState(rx.State): if not conversation: return [] message_history: list[MessageHistoryItem] = [] - has_approval = False - approval_user_prompt = "" for message in conversation.messages.values(): - approval = message.approval - if isinstance(approval, Approval): - has_approval = True - approval_user_prompt = approval.user_prompt message_history.append( MessageHistoryItem( **message.model_dump(), - has_approval=has_approval, - approval_user_prompt=approval_user_prompt, + has_approval=isinstance(approval := message.approval, Approval), + approval_user_prompt=getattr(approval, "user_prompt", ""), ) ) return message_history @@ -464,9 +458,9 @@ class ConversationState(rx.State): ] message.is_running = False message.title = f"{tool_name}已完成" - message.content = cast( - str, content - ) # 约定工具返回分片内容必为字符串 + # 若内容非空字符串则更新 + if content := message.content: + message.content = content yield # 通知前端更新渲染 messages.append(message) diff --git a/agent/application/workshop/book_flight.py b/agent/application/workshop/book_flight.py index db92140..d7280ae 100644 --- a/agent/application/workshop/book_flight.py +++ b/agent/application/workshop/book_flight.py @@ -220,7 +220,7 @@ async def book_flight(ctx: RunContext[Deps]) -> Flight | NoResult: raise ModelRetry("必须先使用 search_flights 查询航班") if not ctx.tool_call_approved: - raise ApprovalRequired(metadata={"content": "您要预定哪班航班?"}) + raise ApprovalRequired(metadata={"content": "请输入航班号:\n\n"}) # 提取到的航班号 extracted_flight_number = ( @@ -235,7 +235,11 @@ async def book_flight(ctx: RunContext[Deps]) -> Flight | NoResult: return NoResult() if extracted_flight_number not in flight_numbers: - raise ModelRetry(f"提取到的航班号 {extracted_flight_number} 不在查询到的航班中") + raise ApprovalRequired( + metadata={ + "content": f"提取到的航班号 {extracted_flight_number} 不在查询到的航班中。请确认后重新输入。" + } + ) # 预定到的航班 ctx.deps.booked_flight = next( flight @@ -329,7 +333,14 @@ async def run_stream_events( event.part.content += f"{searched_flight.number} {searched_flight.airfare}$ 于 {searched_flight.date.strftime('%Y-%m-%d')} 从 {searched_flight.origin_airport_code} 到 {searched_flight.destination_airport_code}\n\n" yield event - # 预定航班无需业务定义 + case "预定航班": + if isinstance(deps.booked_flight, Flight): + event.part.content = "" + else: + event.part.content = ( + "未提取到航班号,请检查后重试\n\n" + ) + yield event case AgentRunResultEvent(result=result): match result: @@ -337,11 +348,10 @@ async def run_stream_events( match output: case Flight(): yield AgentPromptEvent( - content=f"已预定航班:\n\n{output.number} {output.airfare}$ 于 {output.date.strftime('%Y-%m-%d')} 从 {output.origin_airport_code} 到 {output.destination_airport_code}\n\n" + content=f"已成功预定:\n\n{output.number} {output.airfare}$ 于 {output.date.strftime('%Y-%m-%d')} 从 {output.origin_airport_code} 到 {output.destination_airport_code}\n\n本次会话结束。" ) case NoResult(): yield AgentPromptEvent( - content="未提取到航班号,请检查后重试" + content="预定失败\n\n本次会话结束。" ) - case DeferredToolRequests(): - yield event + yield event diff --git a/agent/database.db b/agent/database.db index 53f8c0659eb94e100a81ec87ac92d2597992f5d1..a2ea2dde7818f54ad895b900a1c1f337a8d08eea 100644 GIT binary patch delta 10532 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 delta 3552 zcmb_fYit}>72cWM^&`94u^~=ek~o{SExFC!^_`jf8UqEZ5|q|yp_MBYSUGoICT$WY z#(^erVpmB~Beiv+kunH@Na zbzzs5;_-~{&YpYjIp_P%!_$9kot|zzwRyc4i^Y22-U4^xbRSQ8vBJ~;m~+27mR8fH zSmxn$srk3fZ_T&2T~5yb_26+ONFFM#Ke;QuZg_axV9W8*XIjHUS+ysSvpvCuV;wnb zfY1SA6%0lw6Gw8p_w7G8F)}gssJHK{xdCdJR(N1h$p^nY(h;Y^3_f-EM4Oe*O^l80 z8FA#EJs@NTLtozk=RDFhsAD~s4{kp8K#$x#?#pp6H(*eFG=C(w@8DkB8_x~o9{kMx zXz*U$Fe`#|MbHGnVm@b&!P)MJzi0R8S0-`;H9PNn_%1ZGdPHVrXLQ8T;4g=}r*e@= zBiLo!$2PUG~qh@ z2El|74>k~A=%!z*#a;Cc3cfsv2&?XG|^6HyL4uWgDjNV~SVJkzp~bZn?XePIY@~apg*d|!N#@!}Qi)B+^E^(B-24lZc{NTA5gyp7prC!K zBcWTA0tFt4Gin8MkKLxQU~cNcw5rXmazO1#dmO=|63s{Xt7yy9OkWblb%C~Dg~P!9sjaX)zs!Y(!H@Fn$O>uJqP+&}%^>)|ieLkF zeGCM9Z(o(frV9Wtfo$P3oO~xC$93IQ6+maQ>qO?wy9V^E>SvI}0 zEE`u@M#tY?UMjZ*von43ul+&9yPC91@IIE){;B<4yQckFyQ*E%7Pa5N^{VzNMEIRl z=_6lOO7TvR>Q2Fb1K%H8Ld)*WJa}A=2GU)<*Nhq{B3Tj3P|Ai8wVW5|E}yNZ)fHm6+jqf&cCu zU(kvxp^w0HA(M2jLnaXid6Y`wc!nc9o&iHwBM&(Wf&{cm;X~wYP6%_DZrfIH@!iS3 z8ezx|lTpMCpCe09FvjJsk9{UgCW9xICf~Q`;muzt*<{(h3J7h%fyKV$y2ynJKxHG# z%kW}GnM_1xR7AB%G`yfG56vg=t^U)WPm~g$R&I@DK_vQ#!@V8uEZk9#$Swcvo;&+{ zwRH2GQb_kdKHSv;oj||q@f|hcty=@4g9k(JxPmv;DJJ1hjw{<=d__s(Wb4UT>q)?P zsx|-AL|bxr_?us;d{XV`tXB}jpAV@U!manJz2WqAr76V+ zbXwrpV1kC%ex~T*PZyNJ+OI6a!uA%Gu6b(;T@PP>LE+oVg@u?Nu+;Q)Ez+p`{D50{4e^q!$&RYRUk-XQr0Z zxnYs5z}xOBn?CWz%&99gXRbW?{MB!rc=O30U7dOE%1kL+9pkc>7oNWI?H|7J?DyZC zJy$DqdEvQSKHNK`ZV5LmC>@*XjA7yH3rc4>6S8ao(}Kw@p<7>s>1V$jpBQ;`_dXXU zopEns{7~3FtZr9aVzC#&v{I!1r}`V1|j8^u4q zwhuKN!&drGe`nnQmbI$RTCEmpFtgQYtvBmO?G0!D+kXs^qC$Ab3FX|fX#JtCk{)eO SD0i2NJ?i;XNqI+E(*6Y|%JD$}