imprint-mcp 0.5.1 → 0.6.0
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/examples/google-hotels/README.md +40 -15
- package/examples/google-hotels/get_hotel_details/backends.json +16 -0
- package/examples/google-hotels/get_hotel_details/index.ts +122 -0
- package/examples/google-hotels/get_hotel_details/parser.ts +275 -0
- package/examples/google-hotels/get_hotel_details/playbook.yaml +40 -0
- package/examples/google-hotels/get_hotel_details/request-transform.ts +67 -0
- package/examples/google-hotels/get_hotel_details/workflow.json +67 -0
- package/examples/google-hotels/get_hotel_photos/backends.json +16 -0
- package/examples/google-hotels/get_hotel_photos/index.ts +90 -0
- package/examples/google-hotels/get_hotel_photos/parser.ts +75 -0
- package/examples/google-hotels/get_hotel_photos/playbook.yaml +23 -0
- package/examples/google-hotels/get_hotel_photos/request-transform.ts +27 -0
- package/examples/google-hotels/get_hotel_photos/workflow.json +44 -0
- package/examples/google-hotels/get_hotel_reviews/backends.json +16 -0
- package/examples/google-hotels/get_hotel_reviews/index.ts +14 -17
- package/examples/google-hotels/get_hotel_reviews/parser.ts +177 -105
- package/examples/google-hotels/get_hotel_reviews/playbook.yaml +9 -54
- package/examples/google-hotels/get_hotel_reviews/workflow.json +10 -13
- package/examples/google-hotels/get_travel_area_boundaries/backends.json +16 -0
- package/examples/google-hotels/get_travel_area_boundaries/index.ts +104 -0
- package/examples/google-hotels/get_travel_area_boundaries/package.json +9 -0
- package/examples/google-hotels/get_travel_area_boundaries/parser.ts +127 -0
- package/examples/google-hotels/get_travel_area_boundaries/playbook.yaml +38 -0
- package/examples/google-hotels/get_travel_area_boundaries/request-transform.ts +52 -0
- package/examples/google-hotels/get_travel_area_boundaries/workflow.json +54 -0
- package/examples/google-hotels/list_hotel_booking_options/backends.json +16 -0
- package/examples/google-hotels/list_hotel_booking_options/index.ts +123 -0
- package/examples/google-hotels/list_hotel_booking_options/package.json +9 -0
- package/examples/google-hotels/list_hotel_booking_options/parser.ts +308 -0
- package/examples/google-hotels/list_hotel_booking_options/playbook.yaml +95 -0
- package/examples/google-hotels/list_hotel_booking_options/request-transform.ts +77 -0
- package/examples/google-hotels/list_hotel_booking_options/workflow.json +67 -0
- package/examples/google-hotels/search_hotel_web_links/backends.json +16 -0
- package/examples/google-hotels/search_hotel_web_links/index.ts +90 -0
- package/examples/google-hotels/search_hotel_web_links/package.json +9 -0
- package/examples/google-hotels/search_hotel_web_links/parser.ts +96 -0
- package/examples/google-hotels/search_hotel_web_links/playbook.yaml +53 -0
- package/examples/google-hotels/search_hotel_web_links/request-transform.ts +17 -0
- package/examples/google-hotels/search_hotel_web_links/workflow.json +43 -0
- package/examples/google-hotels/search_hotels/backends.json +16 -0
- package/examples/google-hotels/search_hotels/index.ts +32 -102
- package/examples/google-hotels/search_hotels/parser.ts +237 -216
- package/examples/google-hotels/search_hotels/playbook.yaml +177 -42
- package/examples/google-hotels/search_hotels/request-transform.ts +101 -170
- package/examples/google-hotels/search_hotels/workflow.json +24 -73
- package/examples/google-hotels/suggest_hotel_destinations/backends.json +16 -0
- package/examples/google-hotels/{autocomplete_hotel_location → suggest_hotel_destinations}/index.ts +30 -19
- package/examples/google-hotels/suggest_hotel_destinations/package.json +9 -0
- package/examples/google-hotels/suggest_hotel_destinations/parser.ts +138 -0
- package/examples/google-hotels/suggest_hotel_destinations/playbook.yaml +47 -0
- package/examples/google-hotels/suggest_hotel_destinations/request-transform.ts +33 -0
- package/examples/google-hotels/suggest_hotel_destinations/workflow.json +44 -0
- package/examples/southwest/README.md +31 -70
- package/examples/southwest/get_account_details/backends.json +22 -0
- package/examples/southwest/get_account_details/credentials.manifest.json +17 -0
- package/examples/southwest/get_account_details/index.ts +138 -0
- package/examples/{google-hotels/_shared → southwest/get_account_details}/package.json +2 -2
- package/examples/southwest/get_account_details/parser.ts +136 -0
- package/examples/southwest/get_account_details/playbook.yaml +19 -0
- package/examples/southwest/get_account_details/workflow.json +93 -0
- package/examples/southwest/get_flight_status/backends.json +21 -0
- package/examples/southwest/get_flight_status/index.ts +130 -0
- package/examples/southwest/get_flight_status/package.json +9 -0
- package/examples/southwest/get_flight_status/parser.ts +138 -0
- package/examples/southwest/get_flight_status/playbook.yaml +58 -0
- package/examples/southwest/get_flight_status/workflow.json +77 -0
- package/examples/southwest/get_low_fare_calendar/backends.json +21 -0
- package/examples/southwest/get_low_fare_calendar/index.ts +134 -0
- package/examples/southwest/get_low_fare_calendar/package.json +9 -0
- package/examples/southwest/get_low_fare_calendar/parser.ts +107 -0
- package/examples/southwest/get_low_fare_calendar/playbook.yaml +41 -0
- package/examples/southwest/get_low_fare_calendar/workflow.json +81 -0
- package/examples/southwest/list_upcoming_trips/backends.json +22 -0
- package/examples/southwest/list_upcoming_trips/credentials.manifest.json +17 -0
- package/examples/southwest/list_upcoming_trips/index.ts +123 -0
- package/examples/southwest/list_upcoming_trips/package.json +9 -0
- package/examples/southwest/list_upcoming_trips/parser.ts +160 -0
- package/examples/southwest/list_upcoming_trips/playbook.yaml +24 -0
- package/examples/southwest/list_upcoming_trips/workflow.json +78 -0
- package/examples/southwest/search_flights/backends.json +21 -0
- package/examples/southwest/search_flights/index.ts +150 -0
- package/examples/southwest/search_flights/package.json +9 -0
- package/examples/southwest/search_flights/parser.ts +214 -0
- package/examples/southwest/search_flights/playbook.yaml +52 -0
- package/examples/southwest/search_flights/workflow.json +88 -0
- package/package.json +1 -1
- package/prompts/audit-agent.md +1 -0
- package/prompts/build-planning.md +19 -0
- package/prompts/compile-agent.md +6 -2
- package/prompts/tool-planning.md +2 -0
- package/src/imprint/audit.ts +34 -13
- package/src/imprint/backend-cache.ts +114 -0
- package/src/imprint/backend-ladder.ts +74 -24
- package/src/imprint/build-plan.ts +273 -58
- package/src/imprint/cdp-browser-fetch.ts +75 -30
- package/src/imprint/codex-cli-compile.ts +13 -2
- package/src/imprint/compile-agent.ts +1 -0
- package/src/imprint/compile-tools.ts +548 -136
- package/src/imprint/compile.ts +28 -6
- package/src/imprint/concurrency.ts +26 -3
- package/src/imprint/cron.ts +0 -3
- package/src/imprint/llm-url.ts +69 -0
- package/src/imprint/llm.ts +366 -47
- package/src/imprint/mcp-compile-server.ts +1 -0
- package/src/imprint/mcp-server.ts +48 -13
- package/src/imprint/probe-backends.ts +21 -115
- package/src/imprint/request-capture.ts +2 -1
- package/src/imprint/session-diff.ts +14 -1
- package/src/imprint/stealth-fetch.ts +27 -1
- package/src/imprint/stealth-token-cache.ts +2 -2
- package/src/imprint/teach-plan.ts +2 -0
- package/src/imprint/teach-state.ts +14 -9
- package/src/imprint/teach.ts +39 -2
- package/src/imprint/telemetry.ts +3 -0
- package/src/imprint/tool-candidates.ts +6 -3
- package/src/imprint/tool-plan.ts +29 -3
- package/src/imprint/tracing.ts +18 -2
- package/examples/google-hotels/_shared/batchexecute.ts +0 -73
- package/examples/google-hotels/_shared/freq.ts +0 -158
- package/examples/google-hotels/autocomplete_hotel_location/parser.ts +0 -71
- package/examples/google-hotels/autocomplete_hotel_location/playbook.yaml +0 -36
- package/examples/google-hotels/autocomplete_hotel_location/request-transform.ts +0 -37
- package/examples/google-hotels/autocomplete_hotel_location/workflow.json +0 -36
- package/examples/google-hotels/get_hotel_booking_options/index.ts +0 -143
- package/examples/google-hotels/get_hotel_booking_options/parser.ts +0 -271
- package/examples/google-hotels/get_hotel_booking_options/playbook.yaml +0 -154
- package/examples/google-hotels/get_hotel_booking_options/request-transform.ts +0 -154
- package/examples/google-hotels/get_hotel_booking_options/workflow.json +0 -84
- package/examples/google-hotels/get_hotel_reviews/request-transform.ts +0 -42
- package/examples/southwest/search_southwest_flights/backends.json +0 -23
- package/examples/southwest/search_southwest_flights/cron.json +0 -19
- package/examples/southwest/search_southwest_flights/index.ts +0 -128
- package/examples/southwest/search_southwest_flights/playbook.yaml +0 -46
- package/examples/southwest/search_southwest_flights/workflow.json +0 -72
- /package/examples/google-hotels/{autocomplete_hotel_location → get_hotel_details}/package.json +0 -0
- /package/examples/google-hotels/{get_hotel_booking_options → get_hotel_photos}/package.json +0 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"probedAt": "2026-07-09T03:02:19.472Z",
|
|
3
|
+
"imprintVersion": "0.5.1",
|
|
4
|
+
"schemaVersion": 2,
|
|
5
|
+
"workflowHash": "945631843ae5dd9c796ec5408b2d3ca44d3e4a54d353e234a1c37227413d3075",
|
|
6
|
+
"capabilityHash": "d0891f676244406c38af43944a1d24d32c068a9d1a75986d260a63bffd29e1b2",
|
|
7
|
+
"preferredOrder": [
|
|
8
|
+
"fetch"
|
|
9
|
+
],
|
|
10
|
+
"results": {
|
|
11
|
+
"fetch": {
|
|
12
|
+
"outcome": "ok",
|
|
13
|
+
"durationMs": 199
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED by `imprint emit` — DO NOT EDIT BY HAND.
|
|
3
|
+
*
|
|
4
|
+
* Tool: get_hotel_photos
|
|
5
|
+
* Site: google-hotels
|
|
6
|
+
* Intent: Fetch photo thumbnail URLs for a selected Google Hotels result.
|
|
7
|
+
*
|
|
8
|
+
* To regenerate: imprint emit ~/.imprint/google-hotels/get_hotel_photos/workflow.json --force
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { fileURLToPath } from 'node:url';
|
|
12
|
+
import { dirname, join } from 'node:path';
|
|
13
|
+
import {
|
|
14
|
+
executeWorkflow,
|
|
15
|
+
type CredentialStore,
|
|
16
|
+
} from 'imprint/runtime';
|
|
17
|
+
import type { ToolResult, Workflow } from 'imprint/types';
|
|
18
|
+
|
|
19
|
+
const WORKFLOW: Workflow = {
|
|
20
|
+
"toolName": "get_hotel_photos",
|
|
21
|
+
"intent": {
|
|
22
|
+
"description": "Fetch photo thumbnail URLs for a selected Google Hotels result.",
|
|
23
|
+
"userSaid": "clicked one of hte offerings, saw booking options"
|
|
24
|
+
},
|
|
25
|
+
"parameters": [
|
|
26
|
+
{
|
|
27
|
+
"name": "hotel_token",
|
|
28
|
+
"type": "string",
|
|
29
|
+
"description": "Google Hotels selected hotel token.",
|
|
30
|
+
"verified": false,
|
|
31
|
+
"verifyNote": "annotated"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"name": "image_size",
|
|
35
|
+
"type": "number",
|
|
36
|
+
"description": "Requested square thumbnail size in pixels.",
|
|
37
|
+
"default": 152,
|
|
38
|
+
"verified": false,
|
|
39
|
+
"verifyNote": "annotated"
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"requests": [
|
|
43
|
+
{
|
|
44
|
+
"method": "POST",
|
|
45
|
+
"url": "https://www.google.com/_/TravelFrontendUi/data/batchexecute?rpcids=zM1L7d&source-path=%2Ftravel%2Fsearch&f.sid=7513562915459271421&bl=boq_travel-frontend-ui_20260527.01_p0&hl=en-US&soc-app=162&soc-platform=1&soc-device=1&_reqid=3452256&rt=c",
|
|
46
|
+
"headers": {
|
|
47
|
+
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
|
|
48
|
+
"X-Same-Domain": "1",
|
|
49
|
+
"x-goog-ext-190139975-jspb": "[\"US\",\"ZZ\",\"x6c25Q==\"]",
|
|
50
|
+
"x-goog-ext-259736195-jspb": "[\"en-US\",\"US\",\"USD\",2,null,[420],null,null,7,[]]",
|
|
51
|
+
"Referer": "https://www.google.com/travel/search?q=chicago%20loop&qs=CAEgACgAMiRDaGNJNzgtbHVvWGRob2FJQVJvS0wyMHZNREoyY0dkbk1SQUI4DUgA&ved=0CAAQ5JsGahcKEwjg5tj6uN-UAxUAAAAAHQAAAAAQWg&ts=CAESCgoCCAMKAggDEAAaOwodEhkKCS9tLzBnejQ2OToMQ2hpY2FnbyBMb29wGgASGhIUCgcI6g8QBxgDEgcI6g8QBxgGGAMyAggBKgkKBToDVVNEGgA&ap=MAA",
|
|
52
|
+
"Accept-Language": "en-US,en;q=0.9"
|
|
53
|
+
},
|
|
54
|
+
"body": "f.req=[[ [\"zM1L7d\",\"[null,null,null,[${param.image_size},${param.image_size}],\\\"${param.hotel_token}\\\"]\",null,\"1\"] ]]",
|
|
55
|
+
"effect": "safe"
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
"site": "google-hotels",
|
|
59
|
+
"parserModule": "./parser.ts",
|
|
60
|
+
"requestTransformModule": "./request-transform.ts",
|
|
61
|
+
"liveVerified": true
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export interface GetHotelPhotosInput {
|
|
65
|
+
/** Google Hotels selected hotel token. */
|
|
66
|
+
hotel_token: string;
|
|
67
|
+
/** Requested square thumbnail size in pixels. */
|
|
68
|
+
image_size?: number;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export async function getHotelPhotos(
|
|
72
|
+
input: GetHotelPhotosInput,
|
|
73
|
+
opts: { credentials?: CredentialStore; fetchImpl?: typeof fetch; initialState?: Record<string, unknown> } = {},
|
|
74
|
+
): Promise<ToolResult> {
|
|
75
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
76
|
+
const params: Record<string, string | number | boolean> = {
|
|
77
|
+
image_size: input.image_size ?? 152,
|
|
78
|
+
hotel_token: input.hotel_token,
|
|
79
|
+
};
|
|
80
|
+
return executeWorkflow({
|
|
81
|
+
workflow: WORKFLOW,
|
|
82
|
+
params,
|
|
83
|
+
credentials: opts.credentials,
|
|
84
|
+
fetchImpl: opts.fetchImpl,
|
|
85
|
+
initialState: opts.initialState,
|
|
86
|
+
workflowPath: join(__dirname, 'workflow.json'),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export { WORKFLOW };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
type BatchedFrame = unknown[];
|
|
2
|
+
|
|
3
|
+
type Photo = {
|
|
4
|
+
category: number | null;
|
|
5
|
+
order: number | null;
|
|
6
|
+
photoId: number | null;
|
|
7
|
+
urls: string[];
|
|
8
|
+
requestedWidth: number | null;
|
|
9
|
+
requestedHeight: number | null;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
function parseJsonMaybe(value: unknown): unknown {
|
|
13
|
+
if (typeof value !== 'string') return value;
|
|
14
|
+
return JSON.parse(value);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function unwrapBatchedResponse(rawResponse: unknown): unknown {
|
|
18
|
+
if (Array.isArray(rawResponse)) return rawResponse;
|
|
19
|
+
if (typeof rawResponse !== 'string') return rawResponse;
|
|
20
|
+
|
|
21
|
+
const lines = rawResponse.split('\n').filter((line) => line.trim() && line.trim() !== ")]}'");
|
|
22
|
+
for (const line of lines) {
|
|
23
|
+
const trimmed = line.trim();
|
|
24
|
+
if (/^\d+$/.test(trimmed)) continue;
|
|
25
|
+
try {
|
|
26
|
+
const parsed = JSON.parse(trimmed) as BatchedFrame[];
|
|
27
|
+
if (Array.isArray(parsed)) {
|
|
28
|
+
const frame = parsed.find((entry) => entry?.[0] === 'wrb.fr' && entry?.[1] === 'zM1L7d');
|
|
29
|
+
if (frame && typeof frame[2] === 'string') return JSON.parse(frame[2]);
|
|
30
|
+
}
|
|
31
|
+
} catch {
|
|
32
|
+
// Batchexecute responses can contain trailing non-target frames; keep scanning.
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function parseSizeFromUrl(url: string): { width: number | null; height: number | null } {
|
|
39
|
+
const match = url.match(/[=\-]w(\d+)-h(\d+)/);
|
|
40
|
+
return {
|
|
41
|
+
width: match ? Number(match[1]) : null,
|
|
42
|
+
height: match ? Number(match[2]) : null,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function isPhotoEntry(value: unknown): value is unknown[] {
|
|
47
|
+
return Array.isArray(value) && Array.isArray(value[4]) && value[4].some((item) => typeof item === 'string');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function extract(
|
|
51
|
+
rawResponse: unknown,
|
|
52
|
+
context?: { params: Record<string, string | number | boolean>; responses: unknown[] },
|
|
53
|
+
): unknown {
|
|
54
|
+
const payload = parseJsonMaybe(unwrapBatchedResponse(rawResponse));
|
|
55
|
+
const entries = Array.isArray(payload) && Array.isArray(payload[0]) ? payload[0] : [];
|
|
56
|
+
const requestedFallback = Number(context?.params?.image_size ?? 0) || null;
|
|
57
|
+
|
|
58
|
+
const photos: Photo[] = entries.filter(isPhotoEntry).map((entry) => {
|
|
59
|
+
const urls = (entry[4] as unknown[]).filter((url): url is string => typeof url === 'string' && url.length > 0);
|
|
60
|
+
const size = parseSizeFromUrl(urls[0] ?? '');
|
|
61
|
+
return {
|
|
62
|
+
category: typeof entry[0] === 'number' ? entry[0] : null,
|
|
63
|
+
order: typeof entry[1] === 'number' ? entry[1] : null,
|
|
64
|
+
photoId: typeof entry[3] === 'number' ? entry[3] : null,
|
|
65
|
+
urls,
|
|
66
|
+
requestedWidth: size.width ?? requestedFallback,
|
|
67
|
+
requestedHeight: size.height ?? requestedFallback,
|
|
68
|
+
};
|
|
69
|
+
}).filter((photo) => photo.photoId !== null || photo.urls.length > 0);
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
photos,
|
|
73
|
+
count: photos.length,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
toolName: get_hotel_photos
|
|
2
|
+
summary: Fetch photo thumbnail URLs for a selected Google Hotels property.
|
|
3
|
+
parameters:
|
|
4
|
+
- name: hotel_token
|
|
5
|
+
type: string
|
|
6
|
+
description: Google Hotels selected hotel token.
|
|
7
|
+
- name: image_size
|
|
8
|
+
type: number
|
|
9
|
+
description: Requested thumbnail/image size in pixels when configurable.
|
|
10
|
+
default: 152
|
|
11
|
+
steps:
|
|
12
|
+
- action: navigate
|
|
13
|
+
url: "https://www.google.com/travel/search?qs=${hotel_token}"
|
|
14
|
+
wait_for: networkidle
|
|
15
|
+
- action: wait
|
|
16
|
+
wait_for:
|
|
17
|
+
xhr: "rpcids=zM1L7d"
|
|
18
|
+
result:
|
|
19
|
+
source: xhr
|
|
20
|
+
url_pattern: "rpcids=zM1L7d"
|
|
21
|
+
extract: "0[].2"
|
|
22
|
+
return_as: photo_payloads
|
|
23
|
+
notes: "The zM1L7d batchexecute response wraps the actual photo entries as a stringified JSON payload; each entry contains category/order fields, an internal photo id/count, and thumbnail URLs sized by Google's session-bound request state."
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
type Params = Record<string, string | number | boolean>;
|
|
2
|
+
|
|
3
|
+
function asNumber(value: string | number | boolean | undefined, fallback: number): number {
|
|
4
|
+
const parsed = Number(value ?? fallback);
|
|
5
|
+
if (!Number.isFinite(parsed) || parsed <= 0) return fallback;
|
|
6
|
+
return Math.round(parsed);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function asString(value: string | number | boolean | undefined, name: string): string {
|
|
10
|
+
const text = String(value ?? '').trim();
|
|
11
|
+
if (!text) throw new Error(`${name} is required`);
|
|
12
|
+
return text;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function transform(
|
|
16
|
+
_method: string,
|
|
17
|
+
url: string,
|
|
18
|
+
_responses: unknown[],
|
|
19
|
+
params?: Params,
|
|
20
|
+
): { url: string; body?: string } {
|
|
21
|
+
const imageSize = asNumber(params?.image_size, 152);
|
|
22
|
+
const hotelToken = asString(params?.hotel_token, 'hotel_token');
|
|
23
|
+
const innerPayload = JSON.stringify([null, null, null, [imageSize, imageSize], hotelToken]);
|
|
24
|
+
const outerPayload = [[['zM1L7d', innerPayload, null, '1']]];
|
|
25
|
+
const body = new URLSearchParams({ 'f.req': JSON.stringify(outerPayload) }).toString() + '&';
|
|
26
|
+
return { url, body };
|
|
27
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"toolName": "get_hotel_photos",
|
|
3
|
+
"site": "google-hotels",
|
|
4
|
+
"intent": {
|
|
5
|
+
"description": "Fetch photo thumbnail URLs for a selected Google Hotels result.",
|
|
6
|
+
"userSaid": "clicked one of hte offerings, saw booking options"
|
|
7
|
+
},
|
|
8
|
+
"parameters": [
|
|
9
|
+
{
|
|
10
|
+
"name": "hotel_token",
|
|
11
|
+
"type": "string",
|
|
12
|
+
"description": "Google Hotels selected hotel token.",
|
|
13
|
+
"verified": false,
|
|
14
|
+
"verifyNote": "annotated"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"name": "image_size",
|
|
18
|
+
"type": "number",
|
|
19
|
+
"description": "Requested square thumbnail size in pixels.",
|
|
20
|
+
"default": 152,
|
|
21
|
+
"verified": false,
|
|
22
|
+
"verifyNote": "annotated"
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"requests": [
|
|
26
|
+
{
|
|
27
|
+
"method": "POST",
|
|
28
|
+
"url": "https://www.google.com/_/TravelFrontendUi/data/batchexecute?rpcids=zM1L7d&source-path=%2Ftravel%2Fsearch&f.sid=7513562915459271421&bl=boq_travel-frontend-ui_20260527.01_p0&hl=en-US&soc-app=162&soc-platform=1&soc-device=1&_reqid=3452256&rt=c",
|
|
29
|
+
"headers": {
|
|
30
|
+
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
|
|
31
|
+
"X-Same-Domain": "1",
|
|
32
|
+
"x-goog-ext-190139975-jspb": "[\"US\",\"ZZ\",\"x6c25Q==\"]",
|
|
33
|
+
"x-goog-ext-259736195-jspb": "[\"en-US\",\"US\",\"USD\",2,null,[420],null,null,7,[]]",
|
|
34
|
+
"Referer": "https://www.google.com/travel/search?q=chicago%20loop&qs=CAEgACgAMiRDaGNJNzgtbHVvWGRob2FJQVJvS0wyMHZNREoyY0dkbk1SQUI4DUgA&ved=0CAAQ5JsGahcKEwjg5tj6uN-UAxUAAAAAHQAAAAAQWg&ts=CAESCgoCCAMKAggDEAAaOwodEhkKCS9tLzBnejQ2OToMQ2hpY2FnbyBMb29wGgASGhIUCgcI6g8QBxgDEgcI6g8QBxgGGAMyAggBKgkKBToDVVNEGgA&ap=MAA",
|
|
35
|
+
"Accept-Language": "en-US,en;q=0.9"
|
|
36
|
+
},
|
|
37
|
+
"body": "f.req=[[ [\"zM1L7d\",\"[null,null,null,[${param.image_size},${param.image_size}],\\\"${param.hotel_token}\\\"]\",null,\"1\"] ]]",
|
|
38
|
+
"effect": "safe"
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"parserModule": "./parser.ts",
|
|
42
|
+
"requestTransformModule": "./request-transform.ts",
|
|
43
|
+
"liveVerified": true
|
|
44
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"probedAt": "2026-07-09T03:01:50.799Z",
|
|
3
|
+
"imprintVersion": "0.5.1",
|
|
4
|
+
"schemaVersion": 2,
|
|
5
|
+
"workflowHash": "316c91bd5b43d53580234a1211581141ab3c7d9942280b04f12bc0ea31d51ce1",
|
|
6
|
+
"capabilityHash": "d0891f676244406c38af43944a1d24d32c068a9d1a75986d260a63bffd29e1b2",
|
|
7
|
+
"preferredOrder": [
|
|
8
|
+
"fetch"
|
|
9
|
+
],
|
|
10
|
+
"results": {
|
|
11
|
+
"fetch": {
|
|
12
|
+
"outcome": "ok",
|
|
13
|
+
"durationMs": 393
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Tool: get_hotel_reviews
|
|
5
5
|
* Site: google-hotels
|
|
6
|
-
* Intent: Fetch
|
|
6
|
+
* Intent: Fetch review data for a selected Google Hotels hotel token.
|
|
7
7
|
*
|
|
8
8
|
* To regenerate: imprint emit ~/.imprint/google-hotels/get_hotel_reviews/workflow.json --force
|
|
9
9
|
*/
|
|
@@ -19,44 +19,41 @@ import type { ToolResult, Workflow } from 'imprint/types';
|
|
|
19
19
|
const WORKFLOW: Workflow = {
|
|
20
20
|
"toolName": "get_hotel_reviews",
|
|
21
21
|
"intent": {
|
|
22
|
-
"description": "Fetch
|
|
23
|
-
"userSaid": "clicked one of
|
|
22
|
+
"description": "Fetch review data for a selected Google Hotels hotel token.",
|
|
23
|
+
"userSaid": "clicked one of hte offerings, saw booking options"
|
|
24
24
|
},
|
|
25
25
|
"parameters": [
|
|
26
26
|
{
|
|
27
|
-
"name": "
|
|
27
|
+
"name": "hotel_token",
|
|
28
28
|
"type": "string",
|
|
29
|
-
"description": "
|
|
30
|
-
"verified": true
|
|
31
|
-
"sourcedFrom": {
|
|
32
|
-
"tool": "search_hotels",
|
|
33
|
-
"field": "hotel_id"
|
|
34
|
-
}
|
|
29
|
+
"description": "Google Hotels selected hotel token returned by a hotel search result.",
|
|
30
|
+
"verified": true
|
|
35
31
|
}
|
|
36
32
|
],
|
|
37
33
|
"requests": [
|
|
38
34
|
{
|
|
39
35
|
"method": "POST",
|
|
40
|
-
"url": "https://www.google.com/_/TravelFrontendUi/data/batchexecute?rpcids=ocp93e&source-path=%2Ftravel%2Fsearch&f.sid=7513562915459271421&bl=boq_travel-frontend-ui_20260527.01_p0&hl=en-US&soc-app=162&soc-platform=1&soc-device=1&_reqid
|
|
36
|
+
"url": "https://www.google.com/_/TravelFrontendUi/data/batchexecute?rpcids=ocp93e&source-path=%2Ftravel%2Fsearch&f.sid=7513562915459271421&bl=boq_travel-frontend-ui_20260527.01_p0&hl=en-US&soc-app=162&soc-platform=1&soc-device=1&_reqid=${generated.epoch_ms}&rt=c",
|
|
41
37
|
"headers": {
|
|
42
38
|
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
|
|
39
|
+
"Accept-Language": "en-US,en;q=0.9",
|
|
43
40
|
"X-Same-Domain": "1",
|
|
44
|
-
"
|
|
41
|
+
"x-goog-ext-190139975-jspb": "[\"US\",\"ZZ\",\"x6c25Q==\"]",
|
|
42
|
+
"x-goog-ext-259736195-jspb": "[\"en-US\",\"US\",\"USD\",2,null,[420],null,null,7,[]]",
|
|
45
43
|
"Referer": "https://www.google.com/travel/search"
|
|
46
44
|
},
|
|
47
|
-
"body": "f.req=%5B%5B%5B%22ocp93e%22%2C%22%5Bnull%2Cnull%2Cnull%2Cnull%2Cnull%2Cnull%2Cnull%2Cnull%2C%5C%22${param.
|
|
45
|
+
"body": "f.req=%5B%5B%5B%22ocp93e%22%2C%22%5Bnull%2Cnull%2Cnull%2Cnull%2Cnull%2Cnull%2Cnull%2Cnull%2C%5C%22${param.hotel_token}%5C%22%2Cnull%2Cnull%2C%5B%5B%5D%5D%5D%22%2Cnull%2C%221%22%5D%5D%5D&",
|
|
48
46
|
"effect": "safe"
|
|
49
47
|
}
|
|
50
48
|
],
|
|
51
49
|
"site": "google-hotels",
|
|
52
50
|
"parserModule": "./parser.ts",
|
|
53
|
-
"requestTransformModule": "./request-transform.ts",
|
|
54
51
|
"liveVerified": true
|
|
55
52
|
};
|
|
56
53
|
|
|
57
54
|
export interface GetHotelReviewsInput {
|
|
58
|
-
/**
|
|
59
|
-
|
|
55
|
+
/** Google Hotels selected hotel token returned by a hotel search result. */
|
|
56
|
+
hotel_token: string;
|
|
60
57
|
}
|
|
61
58
|
|
|
62
59
|
export async function getHotelReviews(
|
|
@@ -65,7 +62,7 @@ export async function getHotelReviews(
|
|
|
65
62
|
): Promise<ToolResult> {
|
|
66
63
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
67
64
|
const params: Record<string, string | number | boolean> = {
|
|
68
|
-
|
|
65
|
+
hotel_token: input.hotel_token,
|
|
69
66
|
|
|
70
67
|
};
|
|
71
68
|
return executeWorkflow({
|