This is an automated email from the ASF dual-hosted git repository.
xuetaoli pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-go-samples.git
The following commit(s) were added to refs/heads/main by this push:
new 7ac030e0 feat: add search capability for book-flight-ai-agent (#1061)
7ac030e0 is described below
commit 7ac030e0b90e74ca6f6c6a7ee705c3cb56fdd725
Author: Harry33t <[email protected]>
AuthorDate: Sun Apr 12 21:03:09 2026 +0800
feat: add search capability for book-flight-ai-agent (#1061)
* feat: add search capability for book-flight-ai-agent
* chore: remove unrelated markdown file from PR
* feat: add flight search capability and fix related bugs
---
book-flight-ai-agent/go-server/actions/action.go | 22 +-
.../go-server/conf/bookflight_prompt.yml | 4 +-
.../go-server/model/llm_utility.go | 8 +-
.../go-server/tools/bookingflight/booking_tools.go | 89 ++-----
.../go-server/tools/bookingflight/mock_data.go | 287 +++++++++++++++++++++
5 files changed, 334 insertions(+), 76 deletions(-)
diff --git a/book-flight-ai-agent/go-server/actions/action.go
b/book-flight-ai-agent/go-server/actions/action.go
index b886664a..8745982f 100644
--- a/book-flight-ai-agent/go-server/actions/action.go
+++ b/book-flight-ai-agent/go-server/actions/action.go
@@ -20,6 +20,7 @@ package actions
import (
"encoding/json"
"regexp"
+ "strings"
)
import (
@@ -29,12 +30,23 @@ import (
type Action mcp.RequestRPC
func NewAction(text string) Action {
- re := regexp.MustCompile("```json[^`]*```")
- matches := re.FindAllString(text, -1)
action := Action{}
- if len(matches) > 0 {
- match := matches[0][7 : len(matches[0])-3]
- json.Unmarshal([]byte(match), &action)
+
+ // Try to extract from ```json ... ``` code fence
+ re := regexp.MustCompile("```json([^`]*)```")
+ matches := re.FindStringSubmatch(text)
+ if len(matches) > 1 {
+ jsonStr := strings.ReplaceAll(matches[1], `\n`, "\n")
+ if json.Unmarshal([]byte(jsonStr), &action) == nil {
+ return action
+ }
+ }
+
+ // Fallback: find raw JSON object in text
+ re2 := regexp.MustCompile(`\{[^{}]*\}`)
+ raw := re2.FindString(text)
+ if raw != "" {
+ json.Unmarshal([]byte(raw), &action)
}
return action
}
diff --git a/book-flight-ai-agent/go-server/conf/bookflight_prompt.yml
b/book-flight-ai-agent/go-server/conf/bookflight_prompt.yml
index 8d54714a..b6c0bccd 100644
--- a/book-flight-ai-agent/go-server/conf/bookflight_prompt.yml
+++ b/book-flight-ai-agent/go-server/conf/bookflight_prompt.yml
@@ -1,4 +1,4 @@
-reactPrompt: "
+reactPrompt: "/no_think
当前的任务执行记录:
{memory}
@@ -73,7 +73,7 @@ summary_prompt: "
请分析上述对话,特别关注 Human 的关键信息,简要用一句话总结用户的问题或购买机票的真实任务需求,只需要输出总结内容。"
formatInstructions: '
-```json\n\n
+```json
{
"method": "Name of the tool/action",
"params": {
diff --git a/book-flight-ai-agent/go-server/model/llm_utility.go
b/book-flight-ai-agent/go-server/model/llm_utility.go
index 44db034b..20598670 100644
--- a/book-flight-ai-agent/go-server/model/llm_utility.go
+++ b/book-flight-ai-agent/go-server/model/llm_utility.go
@@ -22,12 +22,8 @@ import (
)
func RemoveThink(text string) string {
- re := regexp.MustCompile(`<think>[\s\S]*</think>`)
- matches := re.FindAllString(text, -1)
- if len(matches) > 0 {
- text = text[len(matches[0]):]
- }
- return text
+ re := regexp.MustCompile(`(?s)<think>.*?</think>\s*`)
+ return re.ReplaceAllString(text, "")
}
func MergeMaps[K comparable, V any](m1, m2 map[K]V) map[K]V {
diff --git
a/book-flight-ai-agent/go-server/tools/bookingflight/booking_tools.go
b/book-flight-ai-agent/go-server/tools/bookingflight/booking_tools.go
index a26f85ed..f37154ef 100644
--- a/book-flight-ai-agent/go-server/tools/bookingflight/booking_tools.go
+++ b/book-flight-ai-agent/go-server/tools/bookingflight/booking_tools.go
@@ -54,13 +54,35 @@ func (stt *SearchFlightTicketTool) Call(ctx
context.Context, input string) (stri
}
func (stt *SearchFlightTicketTool) searchFlightTicket() (string, error) {
- // Only the departure point is verified here, and other information is
not verified
- if stt.Origin != "北京" {
+ date = stt.Date
+ all := flightInformation()
+
+ var rst []map[string]string
+ for _, info := range all {
+ if stt.Origin != "" && info["origin"] != stt.Origin {
+ continue
+ }
+ if stt.Destination != "" && info["destination"] !=
stt.Destination {
+ continue
+ }
+ // departure_time format: "date HH:MM", extract last 5 chars
for time range filter
+ dep_time := ""
+ if t := info["departure_time"]; len(t) >= 5 {
+ dep_time = t[len(t)-5:]
+ }
+ if stt.DepartureTimeStart != "" && dep_time <
stt.DepartureTimeStart {
+ continue
+ }
+ if stt.DepartureTimeEnd != "" && dep_time >
stt.DepartureTimeEnd {
+ continue
+ }
+ rst = append(rst, info)
+ }
+
+ if len(rst) == 0 {
return "No relevant content was found", nil
}
- date = stt.Date
- rst := flightInformation()
rst_json, err := json.Marshal(rst)
return string(rst_json), err
}
@@ -94,62 +116,3 @@ func (ptt *PurchaseFlightTicketTool) purchaseFlightTicket()
(string, error) {
return fmt.Sprintf("The flight was not found: %v", ptt.FlightNumber),
nil
}
-
-func flightInformation() []map[string]string {
- return []map[string]string{
- {
- "flight_number": "MU5100",
- "origin": "北京",
- "destination": "上海",
- "departure_time": fmt.Sprintf("%v 07:00", date),
- "arrival_time": fmt.Sprintf("%v 09:15", date),
- "price": "900.00",
- "seat_type": "头等舱",
- },
- {
- "flight_number": "MU6865",
- "origin": "北京",
- "destination": "上海",
- "departure_time": fmt.Sprintf("%v 07:20", date),
- "arrival_time": fmt.Sprintf("%v 09:25", date),
- "price": "1160.00",
- "seat_type": "头等舱",
- },
- {
- "flight_number": "HM7601",
- "origin": "北京",
- "destination": "上海",
- "departure_time": fmt.Sprintf("%v 07:30", date),
- "arrival_time": fmt.Sprintf("%v 09:55", date),
- "price": "1080.00",
- "seat_type": "普通舱",
- },
- {
- "flight_number": "CA1515",
- "origin": "北京",
- "destination": "上海",
- "departure_time": fmt.Sprintf("%v 15:45", date),
- "arrival_time": fmt.Sprintf("%v 17:55", date),
- "price": "1080.00",
- "seat_type": "普通舱",
- },
- {
- "flight_number": "GS9012",
- "origin": "北京",
- "destination": "上海",
- "departure_time": fmt.Sprintf("%v 19:00", date),
- "arrival_time": fmt.Sprintf("%v 23:00", date),
- "price": "1250.00",
- "seat_type": "头等舱",
- },
- {
- "flight_number": "GS9013",
- "origin": "北京",
- "destination": "上海",
- "departure_time": fmt.Sprintf("%v 18:30", date),
- "arrival_time": fmt.Sprintf("%v 22:00", date),
- "price": "1200.00",
- "seat_type": "头等舱",
- },
- }
-}
diff --git a/book-flight-ai-agent/go-server/tools/bookingflight/mock_data.go
b/book-flight-ai-agent/go-server/tools/bookingflight/mock_data.go
new file mode 100644
index 00000000..faa28711
--- /dev/null
+++ b/book-flight-ai-agent/go-server/tools/bookingflight/mock_data.go
@@ -0,0 +1,287 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package bookingflight
+
+import (
+ "fmt"
+)
+
+func flightInformation() []map[string]string {
+ return []map[string]string{
+ // 北京 → 上海
+ {
+ "flight_number": "MU5100",
+ "origin": "北京",
+ "destination": "上海",
+ "departure_time": fmt.Sprintf("%v 07:00", date),
+ "arrival_time": fmt.Sprintf("%v 09:15", date),
+ "price": "900.00",
+ "seat_type": "头等舱",
+ },
+ {
+ "flight_number": "MU6865",
+ "origin": "北京",
+ "destination": "上海",
+ "departure_time": fmt.Sprintf("%v 07:20", date),
+ "arrival_time": fmt.Sprintf("%v 09:25", date),
+ "price": "1160.00",
+ "seat_type": "头等舱",
+ },
+ {
+ "flight_number": "HM7601",
+ "origin": "北京",
+ "destination": "上海",
+ "departure_time": fmt.Sprintf("%v 10:30", date),
+ "arrival_time": fmt.Sprintf("%v 12:55", date),
+ "price": "1080.00",
+ "seat_type": "普通舱",
+ },
+ {
+ "flight_number": "CA1515",
+ "origin": "北京",
+ "destination": "上海",
+ "departure_time": fmt.Sprintf("%v 15:45", date),
+ "arrival_time": fmt.Sprintf("%v 17:55", date),
+ "price": "980.00",
+ "seat_type": "普通舱",
+ },
+ {
+ "flight_number": "GS9012",
+ "origin": "北京",
+ "destination": "上海",
+ "departure_time": fmt.Sprintf("%v 19:00", date),
+ "arrival_time": fmt.Sprintf("%v 21:15", date),
+ "price": "1250.00",
+ "seat_type": "头等舱",
+ },
+ {
+ "flight_number": "GS9013",
+ "origin": "北京",
+ "destination": "上海",
+ "departure_time": fmt.Sprintf("%v 21:30", date),
+ "arrival_time": fmt.Sprintf("%v 23:45", date),
+ "price": "850.00",
+ "seat_type": "普通舱",
+ },
+ // 上海 → 北京
+ {
+ "flight_number": "MU5101",
+ "origin": "上海",
+ "destination": "北京",
+ "departure_time": fmt.Sprintf("%v 08:00", date),
+ "arrival_time": fmt.Sprintf("%v 10:20", date),
+ "price": "850.00",
+ "seat_type": "普通舱",
+ },
+ {
+ "flight_number": "CA1800",
+ "origin": "上海",
+ "destination": "北京",
+ "departure_time": fmt.Sprintf("%v 12:30", date),
+ "arrival_time": fmt.Sprintf("%v 14:45", date),
+ "price": "920.00",
+ "seat_type": "普通舱",
+ },
+ {
+ "flight_number": "MU7788",
+ "origin": "上海",
+ "destination": "北京",
+ "departure_time": fmt.Sprintf("%v 17:00", date),
+ "arrival_time": fmt.Sprintf("%v 19:20", date),
+ "price": "1100.00",
+ "seat_type": "头等舱",
+ },
+ {
+ "flight_number": "CZ6601",
+ "origin": "上海",
+ "destination": "北京",
+ "departure_time": fmt.Sprintf("%v 20:15", date),
+ "arrival_time": fmt.Sprintf("%v 22:30", date),
+ "price": "980.00",
+ "seat_type": "普通舱",
+ },
+ // 北京 → 广州
+ {
+ "flight_number": "CZ3001",
+ "origin": "北京",
+ "destination": "广州",
+ "departure_time": fmt.Sprintf("%v 08:10", date),
+ "arrival_time": fmt.Sprintf("%v 11:20", date),
+ "price": "1350.00",
+ "seat_type": "普通舱",
+ },
+ {
+ "flight_number": "CZ3002",
+ "origin": "北京",
+ "destination": "广州",
+ "departure_time": fmt.Sprintf("%v 13:00", date),
+ "arrival_time": fmt.Sprintf("%v 16:10", date),
+ "price": "1420.00",
+ "seat_type": "头等舱",
+ },
+ {
+ "flight_number": "CA1301",
+ "origin": "北京",
+ "destination": "广州",
+ "departure_time": fmt.Sprintf("%v 18:45", date),
+ "arrival_time": fmt.Sprintf("%v 21:55", date),
+ "price": "1300.00",
+ "seat_type": "普通舱",
+ },
+ // 广州 → 北京
+ {
+ "flight_number": "CZ3101",
+ "origin": "广州",
+ "destination": "北京",
+ "departure_time": fmt.Sprintf("%v 07:50", date),
+ "arrival_time": fmt.Sprintf("%v 11:05", date),
+ "price": "1280.00",
+ "seat_type": "普通舱",
+ },
+ {
+ "flight_number": "CZ3102",
+ "origin": "广州",
+ "destination": "北京",
+ "departure_time": fmt.Sprintf("%v 14:20", date),
+ "arrival_time": fmt.Sprintf("%v 17:35", date),
+ "price": "1380.00",
+ "seat_type": "头等舱",
+ },
+ {
+ "flight_number": "CA1302",
+ "origin": "广州",
+ "destination": "北京",
+ "departure_time": fmt.Sprintf("%v 19:30", date),
+ "arrival_time": fmt.Sprintf("%v 22:40", date),
+ "price": "1250.00",
+ "seat_type": "普通舱",
+ },
+ // 上海 → 广州
+ {
+ "flight_number": "MU2301",
+ "origin": "上海",
+ "destination": "广州",
+ "departure_time": fmt.Sprintf("%v 09:00", date),
+ "arrival_time": fmt.Sprintf("%v 11:30", date),
+ "price": "780.00",
+ "seat_type": "普通舱",
+ },
+ {
+ "flight_number": "CZ8801",
+ "origin": "上海",
+ "destination": "广州",
+ "departure_time": fmt.Sprintf("%v 16:00", date),
+ "arrival_time": fmt.Sprintf("%v 18:25", date),
+ "price": "860.00",
+ "seat_type": "普通舱",
+ },
+ {
+ "flight_number": "MU2302",
+ "origin": "上海",
+ "destination": "广州",
+ "departure_time": fmt.Sprintf("%v 20:30", date),
+ "arrival_time": fmt.Sprintf("%v 22:55", date),
+ "price": "920.00",
+ "seat_type": "头等舱",
+ },
+ // 广州 → 上海
+ {
+ "flight_number": "CZ8802",
+ "origin": "广州",
+ "destination": "上海",
+ "departure_time": fmt.Sprintf("%v 08:30", date),
+ "arrival_time": fmt.Sprintf("%v 11:00", date),
+ "price": "800.00",
+ "seat_type": "普通舱",
+ },
+ {
+ "flight_number": "MU2401",
+ "origin": "广州",
+ "destination": "上海",
+ "departure_time": fmt.Sprintf("%v 13:45", date),
+ "arrival_time": fmt.Sprintf("%v 16:10", date),
+ "price": "870.00",
+ "seat_type": "普通舱",
+ },
+ {
+ "flight_number": "CZ8803",
+ "origin": "广州",
+ "destination": "上海",
+ "departure_time": fmt.Sprintf("%v 19:00", date),
+ "arrival_time": fmt.Sprintf("%v 21:20", date),
+ "price": "950.00",
+ "seat_type": "头等舱",
+ },
+ // 北京 → 成都
+ {
+ "flight_number": "CA4101",
+ "origin": "北京",
+ "destination": "成都",
+ "departure_time": fmt.Sprintf("%v 09:20", date),
+ "arrival_time": fmt.Sprintf("%v 12:05", date),
+ "price": "1180.00",
+ "seat_type": "普通舱",
+ },
+ {
+ "flight_number": "SC4201",
+ "origin": "北京",
+ "destination": "成都",
+ "departure_time": fmt.Sprintf("%v 14:00", date),
+ "arrival_time": fmt.Sprintf("%v 16:50", date),
+ "price": "1260.00",
+ "seat_type": "头等舱",
+ },
+ {
+ "flight_number": "CA4102",
+ "origin": "北京",
+ "destination": "成都",
+ "departure_time": fmt.Sprintf("%v 19:30", date),
+ "arrival_time": fmt.Sprintf("%v 22:15", date),
+ "price": "1150.00",
+ "seat_type": "普通舱",
+ },
+ // 成都 → 北京
+ {
+ "flight_number": "CA4201",
+ "origin": "成都",
+ "destination": "北京",
+ "departure_time": fmt.Sprintf("%v 08:00", date),
+ "arrival_time": fmt.Sprintf("%v 10:45", date),
+ "price": "1150.00",
+ "seat_type": "普通舱",
+ },
+ {
+ "flight_number": "SC4301",
+ "origin": "成都",
+ "destination": "北京",
+ "departure_time": fmt.Sprintf("%v 13:30", date),
+ "arrival_time": fmt.Sprintf("%v 16:20", date),
+ "price": "1230.00",
+ "seat_type": "头等舱",
+ },
+ {
+ "flight_number": "CA4202",
+ "origin": "成都",
+ "destination": "北京",
+ "departure_time": fmt.Sprintf("%v 18:50", date),
+ "arrival_time": fmt.Sprintf("%v 21:35", date),
+ "price": "1100.00",
+ "seat_type": "普通舱",
+ },
+ }
+}