@mseep/wanderlog-mcp 0.3.1
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.
- package/LICENSE +21 -0
- package/README.md +282 -0
- package/dist/cache/trip-cache.js +87 -0
- package/dist/cache/trip-cache.js.map +1 -0
- package/dist/config.js +38 -0
- package/dist/config.js.map +1 -0
- package/dist/context.js +12 -0
- package/dist/context.js.map +1 -0
- package/dist/errors.js +93 -0
- package/dist/errors.js.map +1 -0
- package/dist/formatters/trip-summary.js +296 -0
- package/dist/formatters/trip-summary.js.map +1 -0
- package/dist/http.js +165 -0
- package/dist/http.js.map +1 -0
- package/dist/index.js +48 -0
- package/dist/index.js.map +1 -0
- package/dist/ot/apply.js +282 -0
- package/dist/ot/apply.js.map +1 -0
- package/dist/resolvers/day.js +83 -0
- package/dist/resolvers/day.js.map +1 -0
- package/dist/resolvers/place-ref.js +194 -0
- package/dist/resolvers/place-ref.js.map +1 -0
- package/dist/server.js +164 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/add-checklist.js +59 -0
- package/dist/tools/add-checklist.js.map +1 -0
- package/dist/tools/add-expense.js +127 -0
- package/dist/tools/add-expense.js.map +1 -0
- package/dist/tools/add-hotel.js +92 -0
- package/dist/tools/add-hotel.js.map +1 -0
- package/dist/tools/add-note.js +63 -0
- package/dist/tools/add-note.js.map +1 -0
- package/dist/tools/add-place.js +151 -0
- package/dist/tools/add-place.js.map +1 -0
- package/dist/tools/annotate-place.js +114 -0
- package/dist/tools/annotate-place.js.map +1 -0
- package/dist/tools/create-trip.js +85 -0
- package/dist/tools/create-trip.js.map +1 -0
- package/dist/tools/edit-note.js +217 -0
- package/dist/tools/edit-note.js.map +1 -0
- package/dist/tools/get-guide.js +42 -0
- package/dist/tools/get-guide.js.map +1 -0
- package/dist/tools/get-trip-url.js +52 -0
- package/dist/tools/get-trip-url.js.map +1 -0
- package/dist/tools/get-trip.js +43 -0
- package/dist/tools/get-trip.js.map +1 -0
- package/dist/tools/list-trips.js +32 -0
- package/dist/tools/list-trips.js.map +1 -0
- package/dist/tools/remove-note.js +107 -0
- package/dist/tools/remove-note.js.map +1 -0
- package/dist/tools/remove-place.js +95 -0
- package/dist/tools/remove-place.js.map +1 -0
- package/dist/tools/rename-day.js +64 -0
- package/dist/tools/rename-day.js.map +1 -0
- package/dist/tools/search-guides.js +172 -0
- package/dist/tools/search-guides.js.map +1 -0
- package/dist/tools/search-places.js +81 -0
- package/dist/tools/search-places.js.map +1 -0
- package/dist/tools/shared.js +216 -0
- package/dist/tools/shared.js.map +1 -0
- package/dist/tools/update-trip-dates.js +211 -0
- package/dist/tools/update-trip-dates.js.map +1 -0
- package/dist/transport/rest.js +152 -0
- package/dist/transport/rest.js.map +1 -0
- package/dist/transport/sharedb.js +323 -0
- package/dist/transport/sharedb.js.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-guide.js","sourceRoot":"","sources":["../../src/tools/get-guide.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,2FAA2F,CAC5F;IACH,GAAG,EAAE,CAAC;SACH,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACP,kFAAkF,CACnF;IACH,eAAe,EAAE,CAAC;SACf,IAAI,CAAC,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;SAC7B,OAAO,CAAC,SAAS,CAAC;SAClB,QAAQ,CACP,uGAAuG,CACxG;CACJ,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;CAKlC,CAAC,IAAI,EAAE,CAAC;AAQT,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,GAAe,EACf,IAAkB;IAElB,IAAI,CAAC;QACH,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1D,MAAM,IAAI,wBAAwB,CAAC,uBAAuB,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC9D,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,IAAI,SAAS,EAAE,GAAG,CAAC,CAAC;QACtE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAC/C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,GACL,GAAG,YAAY,cAAc;YAC3B,CAAC,CAAC,GAAG,CAAC,aAAa,EAAE;YACrB,CAAC,CAAC,qBAAsB,GAAa,CAAC,OAAO,EAAE,CAAC;QACpD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACjE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { WanderlogError } from "../errors.js";
|
|
3
|
+
export const getTripUrlInputSchema = {
|
|
4
|
+
trip_key: z
|
|
5
|
+
.string()
|
|
6
|
+
.min(1)
|
|
7
|
+
.describe("The trip key from wanderlog_list_trips."),
|
|
8
|
+
mode: z
|
|
9
|
+
.enum(["edit", "view", "suggest"])
|
|
10
|
+
.default("edit")
|
|
11
|
+
.describe("Which link variant to return. 'edit' (default) is the primary link with full permissions. 'view' is a read-only share link. 'suggest' is a suggest-mode share link where collaborators can propose changes."),
|
|
12
|
+
};
|
|
13
|
+
export const getTripUrlDescription = `
|
|
14
|
+
Returns the wanderlog.com URL for a trip so the user can open it in a browser.
|
|
15
|
+
|
|
16
|
+
Three link variants are available via the mode parameter:
|
|
17
|
+
- edit (default) — full-permission link for the owner
|
|
18
|
+
- view — read-only link that's safe to share with anyone
|
|
19
|
+
- suggest — suggest-mode link where collaborators can propose changes
|
|
20
|
+
|
|
21
|
+
If you don't know which mode the user wants, default to edit.
|
|
22
|
+
`.trim();
|
|
23
|
+
export function pickKey(trip, mode) {
|
|
24
|
+
if (mode === "view")
|
|
25
|
+
return trip.viewKey ?? trip.editKey ?? trip.key;
|
|
26
|
+
if (mode === "suggest")
|
|
27
|
+
return trip.suggestKey ?? trip.editKey ?? trip.key;
|
|
28
|
+
return trip.editKey ?? trip.key;
|
|
29
|
+
}
|
|
30
|
+
export function buildTripUrl(trip, mode, baseUrl = "https://wanderlog.com") {
|
|
31
|
+
return `${baseUrl}/plan/${pickKey(trip, mode)}`;
|
|
32
|
+
}
|
|
33
|
+
export async function getTripUrl(ctx, args) {
|
|
34
|
+
try {
|
|
35
|
+
const trip = await ctx.tripCache.get(args.trip_key);
|
|
36
|
+
const mode = args.mode ?? "edit";
|
|
37
|
+
const url = buildTripUrl(trip, mode, ctx.config.baseUrl);
|
|
38
|
+
const suffix = mode === "view"
|
|
39
|
+
? "\n(Read-only link — safe to share.)"
|
|
40
|
+
: mode === "suggest"
|
|
41
|
+
? "\n(Suggest-mode link — collaborators can propose changes.)"
|
|
42
|
+
: "";
|
|
43
|
+
return { content: [{ type: "text", text: `${url}${suffix}` }] };
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
const msg = err instanceof WanderlogError
|
|
47
|
+
? err.toUserMessage()
|
|
48
|
+
: `Unexpected error: ${err.message}`;
|
|
49
|
+
return { content: [{ type: "text", text: msg }], isError: true };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=get-trip-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-trip-url.js","sourceRoot":"","sources":["../../src/tools/get-trip-url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9C,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CAAC,yCAAyC,CAAC;IACtD,IAAI,EAAE,CAAC;SACJ,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;SACjC,OAAO,CAAC,MAAM,CAAC;SACf,QAAQ,CACP,6MAA6M,CAC9M;CACJ,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;CASpC,CAAC,IAAI,EAAE,CAAC;AAOT,MAAM,UAAU,OAAO,CAAC,IAAc,EAAE,IAAiC;IACvE,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC;IACrE,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC;IAC3E,OAAO,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,IAAc,EACd,IAAiC,EACjC,OAAO,GAAG,uBAAuB;IAEjC,OAAO,GAAG,OAAO,SAAS,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,GAAe,EACf,IAAU;IAEV,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC;QACjC,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEzD,MAAM,MAAM,GACV,IAAI,KAAK,MAAM;YACb,CAAC,CAAC,qCAAqC;YACvC,CAAC,CAAC,IAAI,KAAK,SAAS;gBAClB,CAAC,CAAC,4DAA4D;gBAC9D,CAAC,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,GAAG,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;IAClE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GACP,GAAG,YAAY,cAAc;YAC3B,CAAC,CAAC,GAAG,CAAC,aAAa,EAAE;YACrB,CAAC,CAAC,qBAAsB,GAAa,CAAC,OAAO,EAAE,CAAC;QACpD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACnE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { WanderlogError } from "../errors.js";
|
|
3
|
+
import { formatTrip } from "../formatters/trip-summary.js";
|
|
4
|
+
import { resolveDay } from "../resolvers/day.js";
|
|
5
|
+
export const getTripInputSchema = {
|
|
6
|
+
trip_key: z
|
|
7
|
+
.string()
|
|
8
|
+
.min(1)
|
|
9
|
+
.describe("The unique trip key from wanderlog_list_trips (e.g. 'vzyrsyhgxvonvxcz'). Required."),
|
|
10
|
+
day: z
|
|
11
|
+
.string()
|
|
12
|
+
.optional()
|
|
13
|
+
.describe("Optional filter to a single day. Accepts 'day 2', 'May 4', or ISO '2026-05-04'. Omit to return the whole trip."),
|
|
14
|
+
response_format: z
|
|
15
|
+
.enum(["concise", "detailed"])
|
|
16
|
+
.default("concise")
|
|
17
|
+
.describe("Output verbosity. 'concise' (default) is a readable summary grouped by day; 'detailed' adds addresses, phone numbers, ratings, and check-in dates."),
|
|
18
|
+
};
|
|
19
|
+
export const getTripDescription = `
|
|
20
|
+
Returns the itinerary for one Wanderlog trip: the hotels list, the "places to visit" list, and
|
|
21
|
+
each day's scheduled places.
|
|
22
|
+
|
|
23
|
+
Use concise format for summarizing or answering questions about a trip in natural language.
|
|
24
|
+
Use detailed format when the user asks for specific info like addresses, phone numbers, or
|
|
25
|
+
hotel check-in/out dates.
|
|
26
|
+
|
|
27
|
+
If you don't know the trip_key, call wanderlog_list_trips first to find it.
|
|
28
|
+
`.trim();
|
|
29
|
+
export async function getTrip(ctx, args) {
|
|
30
|
+
try {
|
|
31
|
+
const trip = await ctx.tripCache.get(args.trip_key);
|
|
32
|
+
const daySection = args.day ? resolveDay(trip, args.day) : undefined;
|
|
33
|
+
const text = formatTrip(trip, args.response_format ?? "concise", daySection);
|
|
34
|
+
return { content: [{ type: "text", text }] };
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
const e = err instanceof WanderlogError
|
|
38
|
+
? err.toUserMessage()
|
|
39
|
+
: `Unexpected error: ${err.message}`;
|
|
40
|
+
return { content: [{ type: "text", text: e }], isError: true };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=get-trip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-trip.js","sourceRoot":"","sources":["../../src/tools/get-trip.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,oFAAoF,CACrF;IACH,GAAG,EAAE,CAAC;SACH,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACP,gHAAgH,CACjH;IACH,eAAe,EAAE,CAAC;SACf,IAAI,CAAC,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;SAC7B,OAAO,CAAC,SAAS,CAAC;SAClB,QAAQ,CACP,oJAAoJ,CACrJ;CACJ,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;CASjC,CAAC,IAAI,EAAE,CAAC;AAQT,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,GAAe,EACf,IAAU;IAEV,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACrE,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,IAAI,SAAS,EAAE,UAAU,CAAC,CAAC;QAC7E,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAC/C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,GACL,GAAG,YAAY,cAAc;YAC3B,CAAC,CAAC,GAAG,CAAC,aAAa,EAAE;YACrB,CAAC,CAAC,qBAAsB,GAAa,CAAC,OAAO,EAAE,CAAC;QACpD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACjE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { WanderlogError } from "../errors.js";
|
|
3
|
+
import { formatTripList } from "../formatters/trip-summary.js";
|
|
4
|
+
export const listTripsInputSchema = {
|
|
5
|
+
response_format: z
|
|
6
|
+
.enum(["concise", "detailed"])
|
|
7
|
+
.default("concise")
|
|
8
|
+
.describe("Output verbosity. 'concise' (default) gives a one-line summary per trip; 'detailed' includes key, owner, and last-edited time."),
|
|
9
|
+
};
|
|
10
|
+
export const listTripsDescription = `
|
|
11
|
+
Lists all Wanderlog trips in the authenticated user's account (owned and shared-with-you).
|
|
12
|
+
|
|
13
|
+
Returns a compact list with title, dates, place count, and trip_key. Use this tool first when
|
|
14
|
+
the user mentions a trip by name but you don't have its trip_key yet — the key is required by
|
|
15
|
+
wanderlog_get_trip and wanderlog_search_places.
|
|
16
|
+
|
|
17
|
+
Each line includes a [key: ...] suffix — extract that key for downstream tool calls.
|
|
18
|
+
`.trim();
|
|
19
|
+
export async function listTrips(ctx, args) {
|
|
20
|
+
try {
|
|
21
|
+
const trips = await ctx.rest.listTrips();
|
|
22
|
+
const text = formatTripList(trips, args.response_format ?? "concise");
|
|
23
|
+
return { content: [{ type: "text", text }] };
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
const e = err instanceof WanderlogError
|
|
27
|
+
? err.toUserMessage()
|
|
28
|
+
: `Unexpected error: ${err.message}`;
|
|
29
|
+
return { content: [{ type: "text", text: e }], isError: true };
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=list-trips.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-trips.js","sourceRoot":"","sources":["../../src/tools/list-trips.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,eAAe,EAAE,CAAC;SACf,IAAI,CAAC,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;SAC7B,OAAO,CAAC,SAAS,CAAC;SAClB,QAAQ,CACP,gIAAgI,CACjI;CACJ,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;CAQnC,CAAC,IAAI,EAAE,CAAC;AAIT,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,GAAe,EACf,IAAU;IAEV,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QACzC,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,IAAI,SAAS,CAAC,CAAC;QACtE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAC/C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,GAAG,GAAG,YAAY,cAAc;YACrC,CAAC,CAAC,GAAG,CAAC,aAAa,EAAE;YACrB,CAAC,CAAC,qBAAsB,GAAa,CAAC,OAAO,EAAE,CAAC;QAClD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACjE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { WanderlogError, WanderlogNotFoundError } from "../errors.js";
|
|
3
|
+
import { resolveDay } from "../resolvers/day.js";
|
|
4
|
+
import { findDaySectionByDate, submitOp } from "./shared.js";
|
|
5
|
+
export const removeNoteInputSchema = {
|
|
6
|
+
trip_key: z.string().min(1).describe("The trip to remove from."),
|
|
7
|
+
text: z
|
|
8
|
+
.string()
|
|
9
|
+
.min(1)
|
|
10
|
+
.describe("Substring to match against note content (case-insensitive)."),
|
|
11
|
+
day: z
|
|
12
|
+
.string()
|
|
13
|
+
.optional()
|
|
14
|
+
.describe("Optional day to search. Accepts 'day 2', 'May 4', or ISO '2026-05-04'. Omit to search the entire trip."),
|
|
15
|
+
};
|
|
16
|
+
export const removeNoteDescription = `
|
|
17
|
+
Removes a note block from a Wanderlog trip by matching a substring of its text content.
|
|
18
|
+
|
|
19
|
+
The match is case-insensitive. If exactly one note matches, it is deleted. If no notes match,
|
|
20
|
+
an error is returned. If multiple notes match, a list of previews is returned — supply a more
|
|
21
|
+
specific substring to narrow to one.
|
|
22
|
+
|
|
23
|
+
Use the optional 'day' filter to limit the search to a specific day.
|
|
24
|
+
`.trim();
|
|
25
|
+
export function extractDeltaText(delta) {
|
|
26
|
+
const ops = delta?.ops ?? [];
|
|
27
|
+
return ops.map((op) => (typeof op.insert === "string" ? op.insert : "")).join("");
|
|
28
|
+
}
|
|
29
|
+
export function extractPlainText(block) {
|
|
30
|
+
return extractDeltaText(block.text);
|
|
31
|
+
}
|
|
32
|
+
export function findNoteMatches(trip, query, day) {
|
|
33
|
+
const lowerQuery = query.toLowerCase();
|
|
34
|
+
const sections = trip.itinerary.sections;
|
|
35
|
+
const matches = [];
|
|
36
|
+
let sectionIndices;
|
|
37
|
+
if (day) {
|
|
38
|
+
const resolved = resolveDay(trip, day);
|
|
39
|
+
const found = findDaySectionByDate(trip, resolved.date);
|
|
40
|
+
if (!found)
|
|
41
|
+
return [];
|
|
42
|
+
sectionIndices = [found.index];
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
sectionIndices = Array.from({ length: sections.length }, (_, i) => i);
|
|
46
|
+
}
|
|
47
|
+
for (const sectionIndex of sectionIndices) {
|
|
48
|
+
const section = sections[sectionIndex];
|
|
49
|
+
for (let blockIndex = 0; blockIndex < section.blocks.length; blockIndex++) {
|
|
50
|
+
const block = section.blocks[blockIndex];
|
|
51
|
+
if (block.type !== "note")
|
|
52
|
+
continue;
|
|
53
|
+
const noteBlock = block;
|
|
54
|
+
const plainText = extractPlainText(noteBlock);
|
|
55
|
+
if (plainText.toLowerCase().includes(lowerQuery)) {
|
|
56
|
+
matches.push({ sectionIndex, blockIndex, plainText, block: noteBlock });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return matches;
|
|
61
|
+
}
|
|
62
|
+
function notePreview(plainText) {
|
|
63
|
+
const flat = plainText.replace(/\n/g, " ").trim();
|
|
64
|
+
return flat.length > 60 ? `${flat.slice(0, 57)}…` : flat;
|
|
65
|
+
}
|
|
66
|
+
export async function removeNote(ctx, args) {
|
|
67
|
+
try {
|
|
68
|
+
const trip = await ctx.tripCache.get(args.trip_key);
|
|
69
|
+
const matches = findNoteMatches(trip, args.text, args.day);
|
|
70
|
+
if (matches.length === 0) {
|
|
71
|
+
throw new WanderlogNotFoundError("Note", args.text);
|
|
72
|
+
}
|
|
73
|
+
if (matches.length > 1) {
|
|
74
|
+
const lines = matches
|
|
75
|
+
.slice(0, 5)
|
|
76
|
+
.map((m, i) => ` ${i + 1}. "${notePreview(m.plainText)}"`)
|
|
77
|
+
.join("\n");
|
|
78
|
+
const suffix = matches.length > 5 ? `\n (${matches.length - 5} more…)` : "";
|
|
79
|
+
return {
|
|
80
|
+
content: [
|
|
81
|
+
{
|
|
82
|
+
type: "text",
|
|
83
|
+
text: `"${args.text}" matches ${matches.length} notes:\n${lines}${suffix}\n\nCall again with a more specific substring to identify the one you want.`,
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
isError: true,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const { sectionIndex, blockIndex, block, plainText } = matches[0];
|
|
90
|
+
const ops = [
|
|
91
|
+
{
|
|
92
|
+
p: ["itinerary", "sections", sectionIndex, "blocks", blockIndex],
|
|
93
|
+
ld: block,
|
|
94
|
+
},
|
|
95
|
+
];
|
|
96
|
+
await submitOp(ctx, args.trip_key, ops);
|
|
97
|
+
const text = `Removed note "${notePreview(plainText)}" from "${trip.title}".`;
|
|
98
|
+
return { content: [{ type: "text", text }] };
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
const msg = err instanceof WanderlogError
|
|
102
|
+
? err.toUserMessage()
|
|
103
|
+
: `Unexpected error: ${err.message}`;
|
|
104
|
+
return { content: [{ type: "text", text: msg }], isError: true };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=remove-note.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remove-note.js","sourceRoot":"","sources":["../../src/tools/remove-note.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { WanderlogError, WanderlogNotFoundError } from "../errors.js";
|
|
3
|
+
import { resolvePlaceRef } from "../resolvers/place-ref.js";
|
|
4
|
+
import { isPlaceBlock } from "../types.js";
|
|
5
|
+
import { submitOp } from "./shared.js";
|
|
6
|
+
export const removePlaceInputSchema = {
|
|
7
|
+
trip_key: z.string().min(1).describe("The trip to remove from."),
|
|
8
|
+
place_ref: z
|
|
9
|
+
.string()
|
|
10
|
+
.min(1)
|
|
11
|
+
.describe("Natural-language reference to the place you want to remove. Examples: 'Queenstown Gardens', 'the hotel', 'the sushi place on day 3'. Supports ordinal prefixes for duplicates: '1st Queenstown Gardens', 'second Queenstown Gardens', 'last Queenstown Gardens'. Supports day filters via ' on ': 'Queenstown Gardens on May 4'. Ordinals and day filters can be combined: '2nd Queenstown Gardens on May 4'."),
|
|
12
|
+
};
|
|
13
|
+
export const removePlaceDescription = `
|
|
14
|
+
Removes a place (or flight, train, hotel — any block) from a Wanderlog trip based on a
|
|
15
|
+
natural-language reference.
|
|
16
|
+
|
|
17
|
+
Supported reference forms:
|
|
18
|
+
- Exact or partial name: "Queenstown Gardens", "Gardens"
|
|
19
|
+
- Role keywords: "the hotel", "the flight", "the train"
|
|
20
|
+
- Day filter: "Queenstown Gardens on May 4" or "... on day 3"
|
|
21
|
+
- Ordinal prefix (for duplicates): "1st Queenstown Gardens", "second X", "last X"
|
|
22
|
+
- Combined: "2nd Queenstown Gardens on May 4"
|
|
23
|
+
|
|
24
|
+
If the reference is ambiguous (multiple places match), the tool returns a numbered list of
|
|
25
|
+
candidates and does NOT make any change. Re-call with an ordinal prefix ("1st X", "2nd X") or
|
|
26
|
+
a more specific filter to pick the one you want.
|
|
27
|
+
`.trim();
|
|
28
|
+
export async function removePlace(ctx, args) {
|
|
29
|
+
try {
|
|
30
|
+
const trip = await ctx.tripCache.get(args.trip_key);
|
|
31
|
+
const result = resolvePlaceRef(trip, args.place_ref);
|
|
32
|
+
if (result.kind === "none") {
|
|
33
|
+
throw new WanderlogNotFoundError("Place", args.place_ref);
|
|
34
|
+
}
|
|
35
|
+
if (result.kind === "ambiguous") {
|
|
36
|
+
const lines = result.candidates
|
|
37
|
+
.slice(0, 10)
|
|
38
|
+
.map((c, i) => {
|
|
39
|
+
const name = isPlaceBlock(c.block)
|
|
40
|
+
? c.block.place.name
|
|
41
|
+
: `${c.block.type} block`;
|
|
42
|
+
const where = formatLocation(c.section);
|
|
43
|
+
const ordinal = ordinalLabel(i + 1);
|
|
44
|
+
return ` ${i + 1}. ${name} — ${where} (${ordinal})`;
|
|
45
|
+
})
|
|
46
|
+
.join("\n");
|
|
47
|
+
const firstCandidateName = isPlaceBlock(result.candidates[0].block)
|
|
48
|
+
? result.candidates[0].block.place.name
|
|
49
|
+
: "the block";
|
|
50
|
+
const retryHint = `Call this tool again with an ordinal to pick one, e.g. place_ref: "1st ${firstCandidateName}" or "last ${firstCandidateName}". You can also combine with a day filter, e.g. "2nd ${firstCandidateName} on day 2".`;
|
|
51
|
+
return {
|
|
52
|
+
content: [
|
|
53
|
+
{
|
|
54
|
+
type: "text",
|
|
55
|
+
text: `"${args.place_ref}" matches ${result.candidates.length} places:\n${lines}\n\n${retryHint}`,
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
isError: true,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const { sectionIndex, blockIndex, block, section } = result.match;
|
|
62
|
+
const ops = [
|
|
63
|
+
{
|
|
64
|
+
p: ["itinerary", "sections", sectionIndex, "blocks", blockIndex],
|
|
65
|
+
ld: block,
|
|
66
|
+
},
|
|
67
|
+
];
|
|
68
|
+
await submitOp(ctx, args.trip_key, ops);
|
|
69
|
+
const removedName = isPlaceBlock(block)
|
|
70
|
+
? block.place.name
|
|
71
|
+
: `${block.type} block`;
|
|
72
|
+
const text = `Removed ${removedName} from ${formatLocation(section)} in "${trip.title}".`;
|
|
73
|
+
return { content: [{ type: "text", text }] };
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
const msg = err instanceof WanderlogError
|
|
77
|
+
? err.toUserMessage()
|
|
78
|
+
: `Unexpected error: ${err.message}`;
|
|
79
|
+
return { content: [{ type: "text", text: msg }], isError: true };
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function formatLocation(section) {
|
|
83
|
+
if (section.mode === "dayPlan" && section.date) {
|
|
84
|
+
return `day ${section.date}`;
|
|
85
|
+
}
|
|
86
|
+
if (section.heading)
|
|
87
|
+
return `"${section.heading}"`;
|
|
88
|
+
return `"${section.type ?? "section"}"`;
|
|
89
|
+
}
|
|
90
|
+
function ordinalLabel(n) {
|
|
91
|
+
const suffix = ["th", "st", "nd", "rd"];
|
|
92
|
+
const v = n % 100;
|
|
93
|
+
return `${n}${suffix[(v - 20) % 10] ?? suffix[v] ?? suffix[0]}`;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=remove-place.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remove-place.js","sourceRoot":"","sources":["../../src/tools/remove-place.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { WanderlogError, WanderlogValidationError } from "../errors.js";
|
|
3
|
+
import { resolveDay } from "../resolvers/day.js";
|
|
4
|
+
import { findDaySectionByDate, submitOp } from "./shared.js";
|
|
5
|
+
export const renameDayInputSchema = {
|
|
6
|
+
trip_key: z.string().min(1).describe("The trip containing the day to rename."),
|
|
7
|
+
day: z
|
|
8
|
+
.string()
|
|
9
|
+
.min(1)
|
|
10
|
+
.describe('Which day to rename. Accepts "day 3", "May 4", or "2026-05-04".'),
|
|
11
|
+
heading: z
|
|
12
|
+
.string()
|
|
13
|
+
.describe('New heading for the day. Use "" (empty string) to clear the heading back to the auto-generated default.'),
|
|
14
|
+
};
|
|
15
|
+
export const renameDayDescription = `
|
|
16
|
+
Renames the heading/subheading of a specific day in a Wanderlog trip.
|
|
17
|
+
|
|
18
|
+
Day headings appear in the itinerary as the title for each day section (e.g. "Barcelona",
|
|
19
|
+
"Ronda + Malaga"). Use this tool to replace them with more descriptive titles.
|
|
20
|
+
|
|
21
|
+
Pass an empty string for "heading" to reset the day back to Wanderlog's auto-generated heading.
|
|
22
|
+
`.trim();
|
|
23
|
+
export async function renameDay(ctx, args) {
|
|
24
|
+
try {
|
|
25
|
+
const entry = await ctx.tripCache.getEntry(args.trip_key);
|
|
26
|
+
const trip = entry.snapshot;
|
|
27
|
+
const daySection = resolveDay(trip, args.day);
|
|
28
|
+
const found = findDaySectionByDate(trip, daySection.date);
|
|
29
|
+
if (!found) {
|
|
30
|
+
throw new WanderlogValidationError(`Day ${args.day} not found in trip`);
|
|
31
|
+
}
|
|
32
|
+
const oldHeading = found.section.heading;
|
|
33
|
+
const newHeading = args.heading;
|
|
34
|
+
if (oldHeading === newHeading) {
|
|
35
|
+
return {
|
|
36
|
+
content: [
|
|
37
|
+
{
|
|
38
|
+
type: "text",
|
|
39
|
+
text: `Day ${daySection.date} heading is already "${newHeading}" — no change made.`,
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const ops = [
|
|
45
|
+
{
|
|
46
|
+
p: ["itinerary", "sections", found.index, "heading"],
|
|
47
|
+
od: oldHeading,
|
|
48
|
+
oi: newHeading,
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
await submitOp(ctx, args.trip_key, ops);
|
|
52
|
+
const oldLabel = oldHeading || "(auto-generated)";
|
|
53
|
+
const newLabel = newHeading || "(auto-generated)";
|
|
54
|
+
const text = `Renamed day ${daySection.date} in "${trip.title}": "${oldLabel}" → "${newLabel}"`;
|
|
55
|
+
return { content: [{ type: "text", text }] };
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
const msg = err instanceof WanderlogError
|
|
59
|
+
? err.toUserMessage()
|
|
60
|
+
: `Unexpected error: ${err.message}`;
|
|
61
|
+
return { content: [{ type: "text", text: msg }], isError: true };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=rename-day.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rename-day.js","sourceRoot":"","sources":["../../src/tools/rename-day.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAExE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE7D,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,wCAAwC,CAAC;IAC9E,GAAG,EAAE,CAAC;SACH,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,iEAAiE,CAClE;IACH,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,QAAQ,CACP,yGAAyG,CAC1G;CACJ,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;CAOnC,CAAC,IAAI,EAAE,CAAC;AAQT,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,GAAe,EACf,IAAU;IAEV,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1D,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC;QAE5B,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9C,MAAM,KAAK,GAAG,oBAAoB,CAAC,IAAI,EAAE,UAAU,CAAC,IAAK,CAAC,CAAC;QAC3D,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,wBAAwB,CAAC,OAAO,IAAI,CAAC,GAAG,oBAAoB,CAAC,CAAC;QAC1E,CAAC;QAED,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QACzC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC;QAEhC,IAAI,UAAU,KAAK,UAAU,EAAE,CAAC;YAC9B,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,OAAO,UAAU,CAAC,IAAI,wBAAwB,UAAU,qBAAqB;qBACpF;iBACF;aACF,CAAC;QACJ,CAAC;QAED,MAAM,GAAG,GAAc;YACrB;gBACE,CAAC,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC;gBACpD,EAAE,EAAE,UAAU;gBACd,EAAE,EAAE,UAAU;aACf;SACF,CAAC;QAEF,MAAM,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAExC,MAAM,QAAQ,GAAG,UAAU,IAAI,kBAAkB,CAAC;QAClD,MAAM,QAAQ,GAAG,UAAU,IAAI,kBAAkB,CAAC;QAClD,MAAM,IAAI,GAAG,eAAe,UAAU,CAAC,IAAI,QAAQ,IAAI,CAAC,KAAK,OAAO,QAAQ,QAAQ,QAAQ,GAAG,CAAC;QAChG,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAC/C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GACP,GAAG,YAAY,cAAc;YAC3B,CAAC,CAAC,GAAG,CAAC,aAAa,EAAE;YACrB,CAAC,CAAC,qBAAsB,GAAa,CAAC,OAAO,EAAE,CAAC;QACpD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACnE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { WanderlogError, WanderlogNotFoundError, WanderlogValidationError, } from "../errors.js";
|
|
3
|
+
export const searchGuidesInputSchema = {
|
|
4
|
+
destination: z
|
|
5
|
+
.string()
|
|
6
|
+
.min(1)
|
|
7
|
+
.optional()
|
|
8
|
+
.describe("Free-text destination (e.g. 'Vietnam', 'Kyoto'). Resolved via geoAutocomplete; multi-match auto-picks the highest-popularity geo and surfaces up to 2 candidates in 'alternative_geos'."),
|
|
9
|
+
geo_id: z
|
|
10
|
+
.number()
|
|
11
|
+
.int()
|
|
12
|
+
.positive()
|
|
13
|
+
.optional()
|
|
14
|
+
.describe("Explicit Wanderlog geo id (from a prior response's 'geo' or 'alternative_geos')."),
|
|
15
|
+
response_format: z
|
|
16
|
+
.enum(["concise", "detailed"])
|
|
17
|
+
.default("concise")
|
|
18
|
+
.describe("Output verbosity. 'concise' (default) returns guide_key, title, author, place_count, view_count. 'detailed' adds blurb, like_count, edited_at, distinction, profile_picture_url, header_image_url."),
|
|
19
|
+
};
|
|
20
|
+
export const searchGuidesDescription = `
|
|
21
|
+
Lists user-written Wanderlog travel guides for a destination — long-form recommendations and
|
|
22
|
+
itineraries other travellers have published. Use this when the user asks for inspiration, an
|
|
23
|
+
itinerary they can copy, or "what guides exist for X".
|
|
24
|
+
|
|
25
|
+
Specify exactly one of destination or geo_id. For free-text destinations the highest-popularity
|
|
26
|
+
match is picked; up to 2 candidates appear in 'alternative_geos' as a soft hint. When the
|
|
27
|
+
destination has no curated guides yet, the response carries 'alternative_geos_with_guides'
|
|
28
|
+
with the top 5 nearby destinations that do.
|
|
29
|
+
|
|
30
|
+
Pass the returned guide_key to wanderlog_get_guide to read the full content of one guide.
|
|
31
|
+
`.trim();
|
|
32
|
+
export function validateArgs(args) {
|
|
33
|
+
const modesSet = [args.destination !== undefined, args.geo_id !== undefined].filter(Boolean).length;
|
|
34
|
+
if (modesSet !== 1) {
|
|
35
|
+
throw new WanderlogValidationError("Pass exactly one of destination or geo_id.");
|
|
36
|
+
}
|
|
37
|
+
return { ...args, response_format: args.response_format ?? "concise" };
|
|
38
|
+
}
|
|
39
|
+
export async function resolveGeo(ctx, args) {
|
|
40
|
+
if (args.geo_id !== undefined) {
|
|
41
|
+
// Trust the caller's geo_id. The canonical name/country/subcategory will
|
|
42
|
+
// be filled in by getGuidesForGeo's embedded geo (or left as a stub if
|
|
43
|
+
// the geo has no guides at all).
|
|
44
|
+
return {
|
|
45
|
+
geo: {
|
|
46
|
+
geo_id: args.geo_id,
|
|
47
|
+
name: "",
|
|
48
|
+
country: null,
|
|
49
|
+
subcategory: null,
|
|
50
|
+
},
|
|
51
|
+
alternative_geos: [],
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
const candidates = await ctx.rest.geoAutocomplete(args.destination);
|
|
55
|
+
if (candidates.length === 0) {
|
|
56
|
+
throw new WanderlogError(`No geo found matching "${args.destination}"`, "destination_not_found", {
|
|
57
|
+
hint: "Try a more specific name (include the country) or pass an explicit geo_id from a prior search.",
|
|
58
|
+
followUps: [
|
|
59
|
+
"Retry wanderlog_search_guides with a more specific destination (include the country or region).",
|
|
60
|
+
],
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
const ranked = [...candidates].sort((a, b) => (b.popularity ?? 0) - (a.popularity ?? 0));
|
|
64
|
+
const top = ranked[0];
|
|
65
|
+
const alternatives = ranked.slice(1, 3).map((c) => ({
|
|
66
|
+
geo_id: c.id,
|
|
67
|
+
name: c.name,
|
|
68
|
+
country: c.countryName ?? null,
|
|
69
|
+
subcategory: null,
|
|
70
|
+
}));
|
|
71
|
+
return {
|
|
72
|
+
geo: {
|
|
73
|
+
geo_id: top.id,
|
|
74
|
+
name: top.name,
|
|
75
|
+
country: top.countryName ?? null,
|
|
76
|
+
subcategory: null,
|
|
77
|
+
},
|
|
78
|
+
alternative_geos: alternatives,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
const IMAGE_BASE = "https://wanderlog.com/image/upload";
|
|
82
|
+
let cachedGoodGuides = null;
|
|
83
|
+
export function __resetCacheForTests() {
|
|
84
|
+
cachedGoodGuides = null;
|
|
85
|
+
}
|
|
86
|
+
export function loadGoodGuides(ctx) {
|
|
87
|
+
if (!cachedGoodGuides) {
|
|
88
|
+
cachedGoodGuides = ctx.rest.listGoodGuides().catch((err) => {
|
|
89
|
+
cachedGoodGuides = null;
|
|
90
|
+
throw err;
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
return cachedGoodGuides;
|
|
94
|
+
}
|
|
95
|
+
function imageUrl(key) {
|
|
96
|
+
return key ? `${IMAGE_BASE}/${key}` : null;
|
|
97
|
+
}
|
|
98
|
+
export function projectGuide(g, format) {
|
|
99
|
+
const base = {
|
|
100
|
+
guide_key: g.key,
|
|
101
|
+
title: g.title,
|
|
102
|
+
author: g.user.username,
|
|
103
|
+
place_count: g.placeCount ?? null,
|
|
104
|
+
view_count: g.viewCount ?? null,
|
|
105
|
+
like_count: g.likeCount ?? null,
|
|
106
|
+
blurb: g.authorBlurb ?? null,
|
|
107
|
+
url: `https://wanderlog.com/view/${g.key}`,
|
|
108
|
+
edited_at: g.editedAt ?? null,
|
|
109
|
+
};
|
|
110
|
+
if (format === "concise")
|
|
111
|
+
return base;
|
|
112
|
+
return {
|
|
113
|
+
...base,
|
|
114
|
+
author_name: g.user.name,
|
|
115
|
+
profile_picture_url: imageUrl(g.user.profilePictureKey),
|
|
116
|
+
distinction: g.distinction ?? null,
|
|
117
|
+
header_image_url: imageUrl(g.headerImageKey),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
export function geoRef(g) {
|
|
121
|
+
return {
|
|
122
|
+
geo_id: g.id,
|
|
123
|
+
name: g.name,
|
|
124
|
+
country: g.countryName ?? null,
|
|
125
|
+
subcategory: g.subcategory ?? null,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
export async function searchGuides(ctx, args) {
|
|
129
|
+
try {
|
|
130
|
+
const norm = validateArgs(args);
|
|
131
|
+
const { geo: stub, alternative_geos } = await resolveGeo(ctx, norm);
|
|
132
|
+
let guidesResp = null;
|
|
133
|
+
try {
|
|
134
|
+
guidesResp = await ctx.rest.getGuidesForGeo(stub.geo_id);
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
if (!(err instanceof WanderlogNotFoundError))
|
|
138
|
+
throw err;
|
|
139
|
+
}
|
|
140
|
+
if (!guidesResp || guidesResp.guides.length === 0) {
|
|
141
|
+
const good = await loadGoodGuides(ctx);
|
|
142
|
+
const top5 = [...good]
|
|
143
|
+
.sort((a, b) => (b.popularity ?? 0) - (a.popularity ?? 0))
|
|
144
|
+
.slice(0, 5)
|
|
145
|
+
.map(geoRef);
|
|
146
|
+
const resolved_geo = guidesResp?.geo ? geoRef(guidesResp.geo) : stub;
|
|
147
|
+
const body = {
|
|
148
|
+
kind: "no_guides",
|
|
149
|
+
resolved_geo,
|
|
150
|
+
alternative_geos_with_guides: top5,
|
|
151
|
+
};
|
|
152
|
+
return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }] };
|
|
153
|
+
}
|
|
154
|
+
const projected = guidesResp.guides.map((g) => projectGuide(g, norm.response_format));
|
|
155
|
+
const body = {
|
|
156
|
+
kind: "guides",
|
|
157
|
+
geo: geoRef(guidesResp.geo),
|
|
158
|
+
alternative_geos,
|
|
159
|
+
returned: projected.length,
|
|
160
|
+
total: projected.length,
|
|
161
|
+
guides: projected,
|
|
162
|
+
};
|
|
163
|
+
return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }] };
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
const e = err instanceof WanderlogError
|
|
167
|
+
? err.toUserMessage()
|
|
168
|
+
: `Unexpected error: ${err.message}`;
|
|
169
|
+
return { content: [{ type: "text", text: e }], isError: true };
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=search-guides.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-guides.js","sourceRoot":"","sources":["../../src/tools/search-guides.ts"],"names":[],"mappings":"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"}
|