Agent Skills
› opensquilla/opensquilla
› meta-travel-planner
meta-travel-planner
GitHub用于生成多技能编排的旅行计划、行程或出差安排。通过整合偏好推断、天气、地点搜索及约束提取,提供完整行程方案及变体选项。
Trigger Scenarios
用户需要制定旅行计划或行程表
用户需要商务出差日程安排
用户请求按天划分的旅行简报
Install
npx skills add opensquilla/opensquilla --skill meta-travel-planner -g -y
SKILL.md
Frontmatter
{
"kind": "meta",
"name": "meta-travel-planner",
"always": false,
"triggers": [
"travel plan",
"trip plan",
"trip itinerary",
"travel itinerary",
"day-by-day travel",
"days in",
"day in",
"plan my trip",
"plan our trip",
"plan a trip",
"itinerary for",
"旅游计划",
"出差行程",
"行程安排",
"规划行程",
"帮我安排",
"怎么玩",
"做个行程"
],
"provenance": {
"origin": "opensquilla-original",
"license": "Apache-2.0"
},
"composition": {
"steps": [
{
"id": "trip_collect",
"kind": "llm_chat",
"with": {
"task": "Extract a structured trip brief from the original user request.\nDo NOT ask the user to confirm details that are already stated or\nsafely inferable. If a value is missing, make a conservative\nassumption and mark it as ASSUMED, except only when destination or trip length is absent.\nIn that case set NEEDS_CLARIFICATION: yes so the next step can pause\nand ask for the missing critical details.\n\nDo not invent exact calendar dates, weekdays, booking status, or\nweather probabilities from vague timing such as \"late June\" or\n\"sometime next year\". Preserve the user's wording when the year or\nexact dates are absent.\n\nOriginal user request:\n{{ inputs.user_message | xml_escape | truncate(1400) }}\n\nReturn exactly:\nDESTINATION: <city\/region, or ASSUMED: ...>\nDAYS: <integer or ASSUMED: ...>\nDATES: <date range\/season, or ASSUMED: ...>\nPARTY: <party size\/type, or ASSUMED: ...>\nBUDGET: <budget|mid|premium, or ASSUMED: mid>\nPACE: <relaxed|balanced|packed>\nINTERESTS:\n - <interest>\nMUST_INCLUDE:\n - <explicit user requirement>\nNEEDS_CLARIFICATION: <yes|no>\nMISSING_FIELDS:\n - <destination|days|none>\nCLARIFY_REASON: <one concise reason, or none>\nASSUMPTIONS:\n - <assumption>\n",
"system": "You extract travel requirements without asking a follow-up unless the destination or trip length is genuinely absent."
}
},
{
"id": "trip_clarify",
"kind": "user_input",
"when": "'NEEDS_CLARIFICATION: yes' in outputs.trip_collect",
"clarify": {
"mode": "form",
"intro": "行程关键条件还不完整。请补齐目的地和天数;如果已有信息不变,可以重复填写。\n",
"fields": [
{
"name": "destination",
"type": "string",
"prompt": "目的地 \/ Destination",
"required": true,
"max_chars": 120
},
{
"max": 60,
"min": 1,
"name": "days",
"type": "int",
"prompt": "旅行天数 \/ Number of days",
"required": true
},
{
"name": "dates",
"type": "string",
"prompt": "日期或季节 \/ Dates or season",
"max_chars": 120
},
{
"name": "party",
"type": "string",
"prompt": "同行人和人数 \/ Party size",
"max_chars": 120
},
{
"name": "must_include",
"type": "string",
"prompt": "必须包含或避开的事项 \/ Must include or avoid",
"max_chars": 300
}
],
"nl_extract": true,
"timeout_hours": 24,
"cancel_keywords": [
"算了",
"取消",
"cancel",
"stop",
"abort"
]
},
"depends_on": [
"trip_collect"
]
},
{
"id": "trip_preferences",
"kind": "llm_chat",
"with": {
"task": "Expand the extracted travel facts into a full planning contract.\nNever return a clarification question. If facts are uncertain, keep\nthe assumption explicit and continue with a practical default.\nPrefer explicit clarification answers over first-pass assumptions.\n\nExtracted facts:\n{{ outputs.trip_collect | truncate(1200) }}\n\nClarification answers (may be empty when not needed):\n{{ inputs.get('collected', {}).get('trip_clarify', {}) | tojson }}\n\nOriginal user request:\n{{ inputs.user_message | xml_escape | truncate(1200) }}\n\nReturn exactly:\nDESTINATION: <city\/region>\nDATES: <duration, date range, season, or ASSUMED value>\nPARTY: <party size\/type>\nBUDGET: <budget level>\nPACE: <relaxed|balanced|packed>\nINTERESTS:\n - <interest>\nCONSTRAINTS:\n - <constraint or assumption>\n",
"system": "You expand extracted travel facts into a structured planning contract."
},
"depends_on": [
"trip_collect",
"trip_clarify"
]
},
{
"id": "weather",
"kind": "skill_exec",
"with": {
"days": 3,
"location": "{{ outputs.trip_preferences | truncate(512) }}",
"max_chars": 2200
},
"skill": "weather",
"depends_on": [
"trip_preferences"
]
},
{
"id": "poi",
"kind": "skill_exec",
"with": {
"query": "{{ outputs.trip_preferences | truncate(512) }} sights restaurants transport hours neighborhoods",
"engines": [
"brave",
"duckduckgo"
],
"max_results": 15
},
"skill": "multi-search-engine",
"depends_on": [
"trip_preferences"
]
},
{
"id": "constraints",
"kind": "llm_chat",
"with": {
"task": "Extract itinerary constraints from weather and POI results: opening\nhours, transit time assumptions, weather risks, neighborhoods to\ngroup together, and any likely booking constraints.\n\nEvidence boundary:\n- Weather tools often return short-range\/current forecasts. If the\n trip timing is vague, seasonal, or outside the forecast window, do\n not convert current weather into trip-day probabilities. Use\n seasonal risk language and mark exact forecast as unavailable.\n- If POI search is thin or missing, do not list restaurants, opening\n hours, events, or booking requirements as verified.\n- Preserve explicit mobility, dietary, fixed-booking, budget, and\n rest constraints before adding optional attractions.\n\nPreferences:\n{{ outputs.trip_preferences | truncate(1200) }}\n\nWeather:\n{{ outputs.weather | truncate(2000) }}\n\nPOI search:\n{{ outputs.poi | truncate(6000) }}\n",
"system": "You convert weather and search results into itinerary constraints."
},
"depends_on": [
"weather",
"poi"
]
},
{
"id": "itinerary",
"kind": "llm_chat",
"with": {
"task": "Build the primary day-by-day itinerary. It must be complete enough\nto use without reading any later step.\n\nInclude:\n- assumptions\n- one section per day with morning \/ afternoon \/ evening\n- neighborhood grouping and transit notes\n- food suggestions\n- rain-aware risks and substitutions\n- rough budget notes\n\nTrip preferences:\n{{ outputs.trip_preferences | truncate(1200) }}\n\nWeather forecast:\n{{ outputs.weather | truncate(2000) }}\n\nPOI search:\n{{ outputs.poi | truncate(5000) }}\n\nConstraints:\n{{ outputs.constraints | truncate(3000) }}\n",
"system": "You write complete, practical travel itineraries. Return only the itinerary."
},
"depends_on": [
"constraints"
]
},
{
"id": "final_plan",
"kind": "llm_chat",
"with": {
"task": "Assemble the complete travel product. Do not return only variants.\nDo not include process commentary.\nReturn every required section. Keep the whole answer compact enough\nto fit in one model response: 4,500-6,500 characters is preferred.\nIf space is tight, shorten day descriptions before omitting the\nvariants, evidence, next-step, or artifact sections.\n\nRequired sections:\n1. Assumptions\n2. Primary itinerary matching the requested or inferred trip length\n3. Weather-aware risks and rain backups\n4. Variants\n5. Budget and booking notes\n6. Evidence and source notes\n7. Next steps\n\nPreserve concrete timings, neighborhoods, transit grouping, food\nideas, weather constraints, and budget constraints. Do not open with\n\"I researched\" or imply live verification unless a tool result is\nshown in the evidence notes. Do not invent exact trip calendar dates,\nweekdays, or daily rain percentages from vague timing such as\n\"late June\" unless the user supplied exact dates and weather evidence\ncovers those dates. If weather evidence is short-range\/current but\nthe trip is future or seasonal, say \"seasonal planning assumption\"\nrather than \"forecast\". Keep each day to 5-7 highly actionable\nbullets or a compact schedule. Include:\n- a Route spine line for each day, e.g. Neighborhood A -> B -> C\n- no more than 2-3 main anchors per day unless the user requested a\n packed pace\n- an explicit pacing note: relaxed\/balanced\/packed and what to skip\n if tired\n- one rest block or pacing reset per day for balanced\/relaxed trips\n- transit-coherent neighborhood adjacency; avoid cross-city zigzags\n- relaxed version\n- efficient\/packed version\n- bad-weather backup\n- weather switch points: if rain\/heavy heat, swap X for Y, framed as\n seasonal risk unless exact forecast evidence covers the trip dates\n- rough daily budget notes as ranges and flex levers, not false\n precision\n- specific checks before booking, including opening-hours checks,\n timed-entry reservations, and transit-pass choice\n- mark specific restaurants, opening hours, and seasonal events as\n \"verify before booking\" unless they came from explicit search\n evidence in this run\n- omit artifact generation suggestions unless the user explicitly\n asked for an artifact or file\n\nIf search or weather evidence is thin, state assumptions plainly\ninstead of inventing sources. Include map\/search links only as\nplain URLs when useful. Use the words Evidence, Source notes,\nReference checks, Next steps, Verify, HTML, and Report\nonly where they fit naturally in the final sections.\n\nItinerary:\n{{ outputs.itinerary | truncate(7000) }}\n\nConstraint notes:\n{{ outputs.constraints | truncate(2500) }}\n\nWeather evidence:\n{{ outputs.weather | truncate(1600) }}\n\nPOI\/source notes:\n{{ outputs.poi | truncate(2000) }}",
"system": "You assemble complete travel plans for users. Return only the final answer."
},
"depends_on": [
"itinerary",
"constraints",
"weather",
"poi"
]
}
]
},
"description": "Use this meta-skill instead of answering directly when the user needs a trip plan, travel itinerary, business-trip schedule, or day-by-day travel brief that benefits from multi-skill orchestration across preference inference, weather, place search, constraint extraction, itinerary drafting, variants, and optional artifact guidance.",
"meta_priority": 50,
"final_text_mode": "step:final_plan"
}
Travel Planner (Meta-Skill)
Weather + POI/restaurant/transport search + constraints + a complete itinerary with variants. The default answer is a complete travel plan; HTML export is an optional handoff when the user explicitly asks for a file.
Fallback
Manually call weather, multi-search-engine, summarize. If the user explicitly
asks for HTML export, ask the LLM to write a styled travel-itinerary.html
and publish_artifact it.
Version History
- 7f72a32 Current 2026-07-05 18:41


