openmates 0.15.0-alpha.7 → 0.15.0-alpha.8

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.
@@ -9683,6 +9683,3913 @@ import { basename as basename3, dirname as dirname3 } from "path";
9683
9683
  import { randomUUID as randomUUID7 } from "crypto";
9684
9684
  import WebSocket2 from "ws";
9685
9685
 
9686
+ // src/generated/appSkills.ts
9687
+ var APP_SKILL_METADATA = [
9688
+ {
9689
+ "app_id": "ai",
9690
+ "skill_id": "ask",
9691
+ "app_namespace_ts": "ai",
9692
+ "skill_method_ts": "ask",
9693
+ "app_namespace_py": "ai",
9694
+ "skill_method_py": "ask",
9695
+ "description_key": "ai.ask.description",
9696
+ "description": "Run this OpenMates app skill.",
9697
+ "schema": {
9698
+ "type": "object",
9699
+ "properties": {
9700
+ "prompt": {
9701
+ "type": "string",
9702
+ "description": "The question or task for the Workflow AI step."
9703
+ },
9704
+ "conversation": {
9705
+ "type": "string",
9706
+ "description": "Optional run-local conversation name for retaining previous Workflow AI context in the same run."
9707
+ }
9708
+ },
9709
+ "required": [
9710
+ "prompt"
9711
+ ]
9712
+ }
9713
+ },
9714
+ {
9715
+ "app_id": "books",
9716
+ "skill_id": "translate",
9717
+ "app_namespace_ts": "books",
9718
+ "skill_method_ts": "translate",
9719
+ "app_namespace_py": "books",
9720
+ "skill_method_py": "translate",
9721
+ "description_key": "books.translate.description",
9722
+ "description": "Run this OpenMates app skill.",
9723
+ "schema": {
9724
+ "type": "object",
9725
+ "properties": {}
9726
+ }
9727
+ },
9728
+ {
9729
+ "app_id": "code",
9730
+ "skill_id": "search_repos",
9731
+ "app_namespace_ts": "code",
9732
+ "skill_method_ts": "searchRepos",
9733
+ "app_namespace_py": "code",
9734
+ "skill_method_py": "search_repos",
9735
+ "description_key": "code.search_repos.description",
9736
+ "description": "Search GitHub repositories. Use this instead of web.search whenever the user asks to find GitHub repos, repositories, open-source libraries, starred repos, or repo examples by topic, language, framework, or project need. Returns licensed repository embeds. Costs 10 credits per search.",
9737
+ "schema": {
9738
+ "type": "object",
9739
+ "properties": {
9740
+ "requests": {
9741
+ "type": "array",
9742
+ "description": "Array of repository search requests. Each request searches GitHub for public licensed repositories matching the query.\n",
9743
+ "items": {
9744
+ "type": "object",
9745
+ "properties": {
9746
+ "query": {
9747
+ "type": "string",
9748
+ "description": 'Repository search query, e.g. "svelte markdown editor", "python cli framework", or "rust web server".\n'
9749
+ },
9750
+ "count": {
9751
+ "type": "integer",
9752
+ "minimum": 1,
9753
+ "maximum": 10,
9754
+ "default": 6,
9755
+ "description": "Number of repositories to return."
9756
+ }
9757
+ },
9758
+ "required": [
9759
+ "query"
9760
+ ]
9761
+ }
9762
+ }
9763
+ },
9764
+ "required": [
9765
+ "requests"
9766
+ ]
9767
+ }
9768
+ },
9769
+ {
9770
+ "app_id": "code",
9771
+ "skill_id": "get_docs",
9772
+ "app_namespace_ts": "code",
9773
+ "skill_method_ts": "getDocs",
9774
+ "app_namespace_py": "code",
9775
+ "skill_method_py": "get_docs",
9776
+ "description_key": "code.get_docs.description",
9777
+ "description": "Get latest documentation for programming libraries, frameworks, APIs, SDKs. Use for ANY programming-related query about a specific library or framework.",
9778
+ "schema": {
9779
+ "type": "object",
9780
+ "properties": {
9781
+ "library": {
9782
+ "type": "string",
9783
+ "description": 'Library name to search for (e.g., "Svelte 5", "React", "FastAPI", "Miro API", etc.).\n'
9784
+ },
9785
+ "question": {
9786
+ "type": "string",
9787
+ "description": 'Natural language question about the documentation needed\n(e.g., "How to use useState hook?", "How to setup routing?").\n'
9788
+ }
9789
+ },
9790
+ "required": [
9791
+ "library",
9792
+ "question"
9793
+ ]
9794
+ }
9795
+ },
9796
+ {
9797
+ "app_id": "code",
9798
+ "skill_id": "clean_repo",
9799
+ "app_namespace_ts": "code",
9800
+ "skill_method_ts": "cleanRepo",
9801
+ "app_namespace_py": "code",
9802
+ "skill_method_py": "clean_repo",
9803
+ "description_key": "code.clean_repo.description",
9804
+ "description": "Run this OpenMates app skill.",
9805
+ "schema": {
9806
+ "type": "object",
9807
+ "properties": {}
9808
+ }
9809
+ },
9810
+ {
9811
+ "app_id": "code",
9812
+ "skill_id": "get_issues",
9813
+ "app_namespace_ts": "code",
9814
+ "skill_method_ts": "getIssues",
9815
+ "app_namespace_py": "code",
9816
+ "skill_method_py": "get_issues",
9817
+ "description_key": "code.get_issues.description",
9818
+ "description": "Run this OpenMates app skill.",
9819
+ "schema": {
9820
+ "type": "object",
9821
+ "properties": {}
9822
+ }
9823
+ },
9824
+ {
9825
+ "app_id": "code",
9826
+ "skill_id": "add_issue",
9827
+ "app_namespace_ts": "code",
9828
+ "skill_method_ts": "addIssue",
9829
+ "app_namespace_py": "code",
9830
+ "skill_method_py": "add_issue",
9831
+ "description_key": "code.add_issue.description",
9832
+ "description": "Run this OpenMates app skill.",
9833
+ "schema": {
9834
+ "type": "object",
9835
+ "properties": {}
9836
+ }
9837
+ },
9838
+ {
9839
+ "app_id": "code",
9840
+ "skill_id": "remove_secrets",
9841
+ "app_namespace_ts": "code",
9842
+ "skill_method_ts": "removeSecrets",
9843
+ "app_namespace_py": "code",
9844
+ "skill_method_py": "remove_secrets",
9845
+ "description_key": "code.remove_secrets.description",
9846
+ "description": "Run this OpenMates app skill.",
9847
+ "schema": {
9848
+ "type": "object",
9849
+ "properties": {}
9850
+ }
9851
+ },
9852
+ {
9853
+ "app_id": "code",
9854
+ "skill_id": "get_project_overview",
9855
+ "app_namespace_ts": "code",
9856
+ "skill_method_ts": "getProjectOverview",
9857
+ "app_namespace_py": "code",
9858
+ "skill_method_py": "get_project_overview",
9859
+ "description_key": "code.get_project_overview.description",
9860
+ "description": "Run this OpenMates app skill.",
9861
+ "schema": {
9862
+ "type": "object",
9863
+ "properties": {}
9864
+ }
9865
+ },
9866
+ {
9867
+ "app_id": "electronics",
9868
+ "skill_id": "search_components",
9869
+ "app_namespace_ts": "electronics",
9870
+ "skill_method_ts": "searchComponents",
9871
+ "app_namespace_py": "electronics",
9872
+ "skill_method_py": "search_components",
9873
+ "description_key": "electronics.search_components.description",
9874
+ "description": "Use this skill when the user asks to find electronic components, especially power converters or voltage regulators matching input voltage, output voltage, output current, efficiency, BOM cost, footprint, or topology requirements. Currently supports category power_converters via Texas Instruments WEBENCH Power Designer.",
9875
+ "schema": {
9876
+ "type": "object",
9877
+ "properties": {
9878
+ "requests": {
9879
+ "type": "array",
9880
+ "description": "Component search requests. Use one request per distinct power rail or component category.\n",
9881
+ "items": {
9882
+ "type": "object",
9883
+ "properties": {
9884
+ "id": {
9885
+ "description": "Optional caller-supplied ID for correlating responses."
9886
+ },
9887
+ "category": {
9888
+ "type": "string",
9889
+ "enum": [
9890
+ "power_converters"
9891
+ ],
9892
+ "description": "Component category. Currently only power_converters is supported."
9893
+ },
9894
+ "input_voltage_min": {
9895
+ "type": "number",
9896
+ "description": "Minimum input voltage in volts. For fixed input voltage, use the same value as input_voltage_max."
9897
+ },
9898
+ "input_voltage_max": {
9899
+ "type": "number",
9900
+ "description": "Maximum input voltage in volts. For fixed input voltage, use the same value as input_voltage_min."
9901
+ },
9902
+ "output_voltage": {
9903
+ "type": "number",
9904
+ "description": "Target output voltage in volts."
9905
+ },
9906
+ "output_current_max": {
9907
+ "type": "number",
9908
+ "description": "Maximum output current in amps."
9909
+ },
9910
+ "supply_type": {
9911
+ "type": "string",
9912
+ "enum": [
9913
+ "dc",
9914
+ "ac"
9915
+ ],
9916
+ "default": "dc",
9917
+ "description": "dc for DC/DC converters, ac for AC/DC converters."
9918
+ },
9919
+ "isolated": {
9920
+ "type": "boolean",
9921
+ "default": false,
9922
+ "description": "Whether the design should be isolated."
9923
+ },
9924
+ "ambient_temp_c": {
9925
+ "type": "number",
9926
+ "default": 30,
9927
+ "description": "Maximum ambient temperature in degrees Celsius."
9928
+ },
9929
+ "optimization": {
9930
+ "type": "string",
9931
+ "enum": [
9932
+ "balanced",
9933
+ "low_cost",
9934
+ "high_efficiency",
9935
+ "small_footprint"
9936
+ ],
9937
+ "default": "balanced",
9938
+ "description": "Optimization goal for WEBENCH ranking."
9939
+ },
9940
+ "max_results": {
9941
+ "type": "integer",
9942
+ "default": 10,
9943
+ "description": "Maximum number of candidate components to return."
9944
+ }
9945
+ },
9946
+ "required": [
9947
+ "category",
9948
+ "input_voltage_min",
9949
+ "input_voltage_max",
9950
+ "output_voltage",
9951
+ "output_current_max"
9952
+ ]
9953
+ }
9954
+ }
9955
+ },
9956
+ "required": [
9957
+ "requests"
9958
+ ]
9959
+ }
9960
+ },
9961
+ {
9962
+ "app_id": "events",
9963
+ "skill_id": "search",
9964
+ "app_namespace_ts": "events",
9965
+ "skill_method_ts": "search",
9966
+ "app_namespace_py": "events",
9967
+ "skill_method_py": "search",
9968
+ "description_key": "events.search.description",
9969
+ "description": "Search for local or online events, meetups, hackathons, conferences, workshops, networking events, parties, concerts, or any community gathering. Use ONLY this skill for event searches \u2014 do NOT additionally call web.search or any other search skill for the same query. Sources: Meetup, Luma, Eventbrite, Google Events, Resident Advisor (electronic music/clubs), Siegess\xE4ule (Berlin LGBTQ+ events), Berlin Philharmonic (classical concerts in Berlin), and official event schedules for GPN24, 39C3, 38C3",
9970
+ "schema": {
9971
+ "type": "object",
9972
+ "properties": {
9973
+ "provider": {
9974
+ "type": "string",
9975
+ "description": "The event provider to use. 'auto' (default) queries all providers in parallel for best coverage. Use specific providers when the user asks about a particular platform/type: 'Eventbrite' for Eventbrite-only results, 'Resident Advisor' for electronic music/clubs, 'Siegess\xE4ule' for Berlin LGBTQ+ events, 'GPN24', '39C3', '38C3', or '37C3' for official schedules of those events.\n",
9976
+ "enum": [
9977
+ "auto",
9978
+ "Meetup",
9979
+ "Luma",
9980
+ "Eventbrite",
9981
+ "Google Events",
9982
+ "Resident Advisor",
9983
+ "Siegess\xE4ule",
9984
+ "Berlin Philharmonic",
9985
+ "GPN24",
9986
+ "39C3",
9987
+ "38C3",
9988
+ "37C3"
9989
+ ]
9990
+ },
9991
+ "requests": {
9992
+ "type": "array",
9993
+ "description": `REQUIRED: Array of event search request objects for parallel processing.
9994
+ This parameter is MANDATORY - you MUST always provide a 'requests' array, even for a single search.
9995
+ Example for single search: {"requests": [{"query": "AI", "location": "Berlin, Germany"}]}
9996
+ Example for multiple searches: {"requests": [{"query": "AI", "location": "Berlin"}, {"query": "Python", "location": "Munich"}]}
9997
+ Each object must contain 'query' and either 'location' (or lat/lon) for city searches,
9998
+ or 'conference' for GPN/Congress schedule searches. All other parameters are optional.
9999
+ Note: The 'id' field is auto-generated if not provided.
10000
+ `,
10001
+ "items": {
10002
+ "type": "object",
10003
+ "properties": {
10004
+ "query": {
10005
+ "type": "string",
10006
+ "description": "Topic or theme of events to search for (e.g. 'AI', 'Python', 'hackathon', 'startup', 'networking'). Do NOT include platform or app names such as 'meetup', 'luma', or 'eventbrite' \u2014 these are stripped automatically and reduce result quality.\n"
10007
+ },
10008
+ "location": {
10009
+ "type": "string",
10010
+ "description": "City name or 'city, country' string (e.g. 'Berlin, Germany', 'New York', 'Paris'). Used if lat/lon are not provided. Not required when using a GPN/Congress event schedule provider with a conference value."
10011
+ },
10012
+ "lat": {
10013
+ "type": "number",
10014
+ "description": "Latitude of search center (decimal degrees). Overrides location string if provided."
10015
+ },
10016
+ "lon": {
10017
+ "type": "number",
10018
+ "description": "Longitude of search center (decimal degrees). Overrides location string if provided."
10019
+ },
10020
+ "start_date": {
10021
+ "type": "string",
10022
+ "description": "Start of date range in ISO 8601 format. Include timezone if known (e.g. '2026-03-01T00:00:00+01:00[Europe/Berlin]'). If omitted, defaults to now."
10023
+ },
10024
+ "end_date": {
10025
+ "type": "string",
10026
+ "description": "End of date range in ISO 8601 format (same format as start_date). If omitted, no upper bound is applied."
10027
+ },
10028
+ "event_type": {
10029
+ "type": "string",
10030
+ "description": "Filter by event type. Use 'PHYSICAL' when user searches for events in a city (default for location-based searches). Use 'ONLINE' when user explicitly asks for virtual/online/remote events. Omit only when user wants both types.",
10031
+ "enum": [
10032
+ "PHYSICAL",
10033
+ "ONLINE"
10034
+ ]
10035
+ },
10036
+ "radius_miles": {
10037
+ "type": "number",
10038
+ "description": "Search radius in miles from the center coordinates (default: 25, ~40 km). Only applies to PHYSICAL events.",
10039
+ "default": 25
10040
+ },
10041
+ "count": {
10042
+ "type": "integer",
10043
+ "description": "Maximum number of events to return (default: 10, max: 50). Use 10 unless the user asks for more results.",
10044
+ "minimum": 1,
10045
+ "maximum": 50,
10046
+ "default": 10
10047
+ },
10048
+ "provider": {
10049
+ "type": "string",
10050
+ "description": "Provider for this request. Overrides the top-level provider when set.",
10051
+ "enum": [
10052
+ "auto",
10053
+ "Meetup",
10054
+ "Luma",
10055
+ "Eventbrite",
10056
+ "Google Events",
10057
+ "Resident Advisor",
10058
+ "Siegess\xE4ule",
10059
+ "Berlin Philharmonic",
10060
+ "GPN24",
10061
+ "39C3",
10062
+ "38C3",
10063
+ "37C3"
10064
+ ]
10065
+ },
10066
+ "providers": {
10067
+ "type": "array",
10068
+ "items": {
10069
+ "type": "string",
10070
+ "enum": [
10071
+ "Meetup",
10072
+ "Luma",
10073
+ "Eventbrite",
10074
+ "Google Events",
10075
+ "Resident Advisor",
10076
+ "Siegess\xE4ule",
10077
+ "Berlin Philharmonic",
10078
+ "GPN24",
10079
+ "39C3",
10080
+ "38C3",
10081
+ "37C3"
10082
+ ]
10083
+ },
10084
+ "description": "Specific providers for this request. Use only when the user asks to search multiple named event platforms."
10085
+ },
10086
+ "conference": {
10087
+ "type": "string",
10088
+ "description": "Known GPN/Congress schedule to search. Supported values: GPN24, 39C3, 38C3, 37C3.",
10089
+ "enum": [
10090
+ "GPN24",
10091
+ "39C3",
10092
+ "38C3",
10093
+ "37C3"
10094
+ ]
10095
+ },
10096
+ "past_events": {
10097
+ "type": "boolean",
10098
+ "description": "Default false. Set true only when the user explicitly asks to include past/completed conference sessions.",
10099
+ "default": false
10100
+ },
10101
+ "concert_tags": {
10102
+ "type": "array",
10103
+ "items": {
10104
+ "type": "string"
10105
+ },
10106
+ "description": "Optional tag filters for the Berlin Philharmonic provider. Use when the user asks about classical concerts in Berlin. Known values: Piano, Chamber Music, Jazz, Organ, Modern, Lunch Concerts, Singers, Children and Family, World. Ignored by all other providers.\n"
10107
+ }
10108
+ }
10109
+ }
10110
+ }
10111
+ },
10112
+ "required": [
10113
+ "requests"
10114
+ ]
10115
+ }
10116
+ },
10117
+ {
10118
+ "app_id": "fitness",
10119
+ "skill_id": "search_locations",
10120
+ "app_namespace_ts": "fitness",
10121
+ "skill_method_ts": "searchLocations",
10122
+ "app_namespace_py": "fitness",
10123
+ "skill_method_py": "search_locations",
10124
+ "description_key": "fitness.search_locations.description",
10125
+ "description": "Search Urban Sports Club public fitness locations. Use this when the user asks for gyms, studios, pools, or Urban Sports locations near a city, address, or radius. Do not use it for class availability; use fitness.search_classes for dated class searches.",
10126
+ "schema": {
10127
+ "type": "object",
10128
+ "properties": {
10129
+ "requests": {
10130
+ "type": "array",
10131
+ "items": {
10132
+ "type": "object",
10133
+ "properties": {
10134
+ "query": {
10135
+ "type": "string"
10136
+ },
10137
+ "city": {
10138
+ "type": "string"
10139
+ },
10140
+ "address": {
10141
+ "type": "string"
10142
+ },
10143
+ "lat": {
10144
+ "type": "number"
10145
+ },
10146
+ "lon": {
10147
+ "type": "number"
10148
+ },
10149
+ "radius_km": {
10150
+ "type": "number"
10151
+ },
10152
+ "plan": {
10153
+ "type": "string"
10154
+ },
10155
+ "category": {
10156
+ "type": "string"
10157
+ },
10158
+ "limit": {
10159
+ "type": "number"
10160
+ }
10161
+ }
10162
+ },
10163
+ "description": "Location search requests."
10164
+ }
10165
+ }
10166
+ }
10167
+ },
10168
+ {
10169
+ "app_id": "fitness",
10170
+ "skill_id": "search_classes",
10171
+ "app_namespace_ts": "fitness",
10172
+ "skill_method_ts": "searchClasses",
10173
+ "app_namespace_py": "fitness",
10174
+ "skill_method_py": "search_classes",
10175
+ "description_key": "fitness.search_classes.description",
10176
+ "description": "Search available Urban Sports Club public fitness classes. Use this when the user asks for dated fitness classes, course availability, free spots, on-site classes, online classes, or plan-filtered Urban Sports classes. Omit plan unless the user explicitly asks for Essential, Classic, Premium, or Max.",
10177
+ "schema": {
10178
+ "type": "object",
10179
+ "properties": {
10180
+ "requests": {
10181
+ "type": "array",
10182
+ "items": {
10183
+ "type": "object",
10184
+ "properties": {
10185
+ "query": {
10186
+ "type": "string"
10187
+ },
10188
+ "city": {
10189
+ "type": "string"
10190
+ },
10191
+ "address": {
10192
+ "type": "string"
10193
+ },
10194
+ "lat": {
10195
+ "type": "number"
10196
+ },
10197
+ "lon": {
10198
+ "type": "number"
10199
+ },
10200
+ "radius_km": {
10201
+ "type": "number"
10202
+ },
10203
+ "start_date": {
10204
+ "type": "string"
10205
+ },
10206
+ "end_date": {
10207
+ "type": "string"
10208
+ },
10209
+ "days": {
10210
+ "type": "number"
10211
+ },
10212
+ "plan": {
10213
+ "type": "string"
10214
+ },
10215
+ "attendance_mode": {
10216
+ "type": "string"
10217
+ },
10218
+ "min_spots": {
10219
+ "type": "number"
10220
+ },
10221
+ "category": {
10222
+ "type": "string"
10223
+ },
10224
+ "venue_id": {
10225
+ "type": "string"
10226
+ },
10227
+ "limit": {
10228
+ "type": "number"
10229
+ }
10230
+ }
10231
+ },
10232
+ "description": "Class search requests."
10233
+ }
10234
+ }
10235
+ }
10236
+ },
10237
+ {
10238
+ "app_id": "health",
10239
+ "skill_id": "search_appointments",
10240
+ "app_namespace_ts": "health",
10241
+ "skill_method_ts": "searchAppointments",
10242
+ "app_namespace_py": "health",
10243
+ "skill_method_py": "search_appointments",
10244
+ "description_key": "app_skills.health.search_appointments.description",
10245
+ "description": 'Search available medical appointments at German doctors/specialists by speciality and city. Covers any medical booking \u2014 general practitioners, specialists (e.g. dentist, dermatologist, gynecologist), scans and imaging (e.g. MRT/MRI, CT, R\xF6ntgen, Ultraschall), vaccinations, check-ups, blood tests, and other examinations. Note: "Termin" in a medical context means appointment, not event \u2014 route here instead of events-search. Sources: Doctolib, Jameda (Germany only).',
10246
+ "schema": {
10247
+ "type": "object",
10248
+ "properties": {
10249
+ "requests": {
10250
+ "type": "array",
10251
+ "description": "Array of appointment search requests. Each request searches for available doctor appointments for a given speciality and city.\n",
10252
+ "items": {
10253
+ "type": "object",
10254
+ "properties": {
10255
+ "speciality": {
10256
+ "type": "string",
10257
+ "description": 'Doctor speciality or type. Supports German and English names. Examples: "augenarzt", "hautarzt", "allgemeinmedizin", "zahnarzt", "gyn\xE4kologie", "kardiologie", "orthop\xE4die", "neurologie", "kinderarzt", "hno", "physiotherapie", "urologie", "ophthalmologist", "dermatologist", "general_practitioner", "dentist", "cardiologist", "neurologist", "pediatrician".\n'
10258
+ },
10259
+ "city": {
10260
+ "type": "string",
10261
+ "description": 'City where to search for appointments. Supports German and English city names. Examples: "Berlin", "M\xFCnchen", "Munich", "Hamburg", "K\xF6ln", "Frankfurt", "Stuttgart", "D\xFCsseldorf", "Dresden", "Leipzig", "Hannover", "N\xFCrnberg", "Bonn", "Heidelberg".\n'
10262
+ },
10263
+ "provider_platform": {
10264
+ "type": "string",
10265
+ "description": 'Booking platform to search. "both" (default) searches Doctolib and Jameda in parallel and merges results sorted by soonest slot. "doctolib_de" for Doctolib Germany only. "jameda" for Jameda Germany only (includes ratings, prices, direct booking URLs).\n',
10266
+ "enum": [
10267
+ "both",
10268
+ "doctolib_de",
10269
+ "jameda"
10270
+ ],
10271
+ "default": "both"
10272
+ },
10273
+ "insurance_sector": {
10274
+ "type": "string",
10275
+ "description": 'Insurance type filter. "public" for gesetzliche Krankenversicherung (GKV), "private" for private Krankenversicherung (PKV). Omit to show results for all insurance types.\n',
10276
+ "enum": [
10277
+ "public",
10278
+ "private"
10279
+ ]
10280
+ },
10281
+ "telehealth": {
10282
+ "type": "boolean",
10283
+ "description": "If true, only return doctors offering telehealth (video consultation) appointments. Defaults to false.\n",
10284
+ "default": false
10285
+ },
10286
+ "language": {
10287
+ "type": "string",
10288
+ "description": 'Filter for doctors who speak a specific language. Language codes: "de" (German), "gb" (English), "ru" (Russian), "tr" (Turkish), "ar" (Arabic), "fr" (French), "es" (Spanish), "it" (Italian), "pl" (Polish), "ro" (Romanian), "zh" (Chinese).\n'
10289
+ },
10290
+ "days_ahead": {
10291
+ "type": "integer",
10292
+ "description": "How many days ahead to search for appointments. Must be one of 1, 3, or 7 (Doctolib API caps availability queries at 7 days). Defaults to 7.\n",
10293
+ "enum": [
10294
+ 1,
10295
+ 3,
10296
+ 7
10297
+ ],
10298
+ "default": 7
10299
+ },
10300
+ "max_doctors": {
10301
+ "type": "integer",
10302
+ "description": "Maximum number of doctors to check for availability. Higher values return more results but take longer. Defaults to 10.\n",
10303
+ "default": 10
10304
+ },
10305
+ "visit_motive_category": {
10306
+ "type": "string",
10307
+ "description": 'Filter results by appointment type category. When set, the skill searches a larger pool of doctors and filters by the Doctolib visit motive name to return only relevant appointment types. "general" = consultation, acute visit, new patient examination. "checkup" = preventive screening, health check, cancer screening. "vaccination" = immunisation appointments. "followup" = follow-up visit, existing patient, check-up after treatment.\n',
10308
+ "enum": [
10309
+ "general",
10310
+ "checkup",
10311
+ "vaccination",
10312
+ "followup"
10313
+ ]
10314
+ }
10315
+ },
10316
+ "required": [
10317
+ "speciality",
10318
+ "city"
10319
+ ]
10320
+ }
10321
+ }
10322
+ },
10323
+ "required": [
10324
+ "requests"
10325
+ ]
10326
+ }
10327
+ },
10328
+ {
10329
+ "app_id": "health",
10330
+ "skill_id": "create_report",
10331
+ "app_namespace_ts": "health",
10332
+ "skill_method_ts": "createReport",
10333
+ "app_namespace_py": "health",
10334
+ "skill_method_py": "create_report",
10335
+ "description_key": "health.create_report.description",
10336
+ "description": "Run this OpenMates app skill.",
10337
+ "schema": {
10338
+ "type": "object",
10339
+ "properties": {}
10340
+ }
10341
+ },
10342
+ {
10343
+ "app_id": "home",
10344
+ "skill_id": "search",
10345
+ "app_namespace_ts": "home",
10346
+ "skill_method_ts": "search",
10347
+ "app_namespace_py": "home",
10348
+ "skill_method_py": "search",
10349
+ "description_key": "app_skills.home.search.description",
10350
+ "description": "Search for apartments, houses, and WG rooms in German cities. Searches ImmoScout24, Kleinanzeigen, and WG-Gesucht simultaneously. Returns listings with prices, sizes, rooms, addresses, and direct links. Costs 10 credits per search. Use when user asks about finding housing in Germany.",
10351
+ "schema": {
10352
+ "type": "object",
10353
+ "properties": {
10354
+ "requests": {
10355
+ "type": "array",
10356
+ "description": "Array of housing search requests. Each request searches for apartments and rooms in a German city across multiple platforms.\n",
10357
+ "items": {
10358
+ "type": "object",
10359
+ "properties": {
10360
+ "query": {
10361
+ "type": "string",
10362
+ "description": 'City or location name to search in, e.g. "Berlin", "Munich", "Hamburg".\n'
10363
+ },
10364
+ "listing_type": {
10365
+ "type": "string",
10366
+ "description": 'Type of listing. "rent" for rentals (default), "buy" for purchases. Note: WG-Gesucht only has rentals and is skipped for "buy".\n',
10367
+ "enum": [
10368
+ "rent",
10369
+ "buy"
10370
+ ],
10371
+ "default": "rent"
10372
+ },
10373
+ "providers": {
10374
+ "type": "array",
10375
+ "description": "Optional list of providers to search. Defaults to all three.\n",
10376
+ "items": {
10377
+ "type": "string",
10378
+ "enum": [
10379
+ "ImmoScout24",
10380
+ "Kleinanzeigen",
10381
+ "WG-Gesucht"
10382
+ ]
10383
+ }
10384
+ },
10385
+ "max_results": {
10386
+ "type": "integer",
10387
+ "description": "Maximum number of listings to return (1-20, default 10).",
10388
+ "default": 10,
10389
+ "minimum": 1,
10390
+ "maximum": 20
10391
+ }
10392
+ },
10393
+ "required": [
10394
+ "query"
10395
+ ]
10396
+ }
10397
+ }
10398
+ },
10399
+ "required": [
10400
+ "requests"
10401
+ ]
10402
+ }
10403
+ },
10404
+ {
10405
+ "app_id": "images",
10406
+ "skill_id": "generate",
10407
+ "app_namespace_ts": "images",
10408
+ "skill_method_ts": "generate",
10409
+ "app_namespace_py": "images",
10410
+ "skill_method_py": "generate",
10411
+ "description_key": "images.generate.description",
10412
+ "description": 'Generate high-quality images from text prompts and/or reference images (image-to-image editing). Also use for: mockups, design concepts, visual mockup creation, logo mockups, product mockups, illustration requests, visual design, concept art, posters, banners, thumbnails, or any request that implies creating a visual output. Use output_filetype="svg" for logos, icons, illustrations, and any other vector graphics that need to be scalable or editable. When the user provides uploaded images as refe',
10413
+ "schema": {
10414
+ "type": "object",
10415
+ "properties": {
10416
+ "requests": {
10417
+ "type": "array",
10418
+ "description": `REQUIRED: Array of image generation request objects for parallel processing (up to 5 requests).
10419
+ This parameter is MANDATORY - you MUST always provide a 'requests' array, even for a single image.
10420
+ Example for single image: {"requests": [{"prompt": "a cute cat"}]}
10421
+ Each object must contain 'prompt' (detailed description), and can include optional
10422
+ 'aspect_ratio', 'output_filetype', and 'quality'.
10423
+ `,
10424
+ "items": {
10425
+ "type": "object",
10426
+ "properties": {
10427
+ "prompt": {
10428
+ "type": "string",
10429
+ "description": "Detailed description of the image to generate"
10430
+ },
10431
+ "aspect_ratio": {
10432
+ "type": "string",
10433
+ "description": "Aspect ratio of the generated image",
10434
+ "enum": [
10435
+ "1:1",
10436
+ "16:9",
10437
+ "4:3",
10438
+ "3:2",
10439
+ "2:3",
10440
+ "9:16"
10441
+ ],
10442
+ "default": "1:1"
10443
+ },
10444
+ "output_filetype": {
10445
+ "type": "string",
10446
+ "description": 'Output file format. Use "svg" to generate a scalable vector graphic (SVG) via\nRecraft V4.1 \u2014 ideal for logos, icons, illustrations, and any graphic that needs\nto be scalable, editable in design tools, or used at any size without quality loss.\nUse "png" or "jpg" for photos, realistic scenes, and detailed raster images.\nWhen a Recraft model is selected, Recraft V4 is used for raster output as well.\n',
10447
+ "enum": [
10448
+ "png",
10449
+ "jpg",
10450
+ "svg"
10451
+ ],
10452
+ "default": "png"
10453
+ },
10454
+ "quality": {
10455
+ "type": "string",
10456
+ "description": 'Generation quality. Controls which model tier is used when Recraft is the provider.\nFor SVG output (output_filetype="svg"):\n "default" uses Recraft V4.1 Vector (100 credits \u2014 good for web/UI use).\n "max" uses Recraft V4.1 Pro Vector (300 credits \u2014 best for print, large-format,\n or highly detailed vector illustrations).\nFor raster output (output_filetype="png"/"jpg") with a Recraft model selected:\n "default" uses Recraft V4.1 (50 credits \u2014 fast, cost-effective).\n "max" uses Recraft V4.1 Pro (250 credits \u2014 high-resolution, print-ready).\nFor other raster models (Google Gemini, GPT Image 2, FLUX), quality may be handled by the provider.\n',
10457
+ "enum": [
10458
+ "default",
10459
+ "max"
10460
+ ],
10461
+ "default": "default"
10462
+ },
10463
+ "reference_images": {
10464
+ "type": "array",
10465
+ "description": 'Optional list of reference image filenames (embed_refs) to use as visual\nreferences for this generation. Pass the exact embed_ref values (original\nfilenames, e.g. "my_photo.jpg") from the toon blocks in the conversation.\nThe server resolves all cryptographic and storage details automatically.\nSupports up to 14 reference images. When provided, enables image-to-image\nediting/style-transfer mode (Google Gemini: same endpoint; FLUX: switches\nto the 4B edit model). Ignored for SVG/Recraft output.\n',
10466
+ "items": {
10467
+ "type": "string",
10468
+ "description": "Original filename (embed_ref) of an uploaded image"
10469
+ }
10470
+ }
10471
+ },
10472
+ "required": [
10473
+ "prompt"
10474
+ ]
10475
+ }
10476
+ }
10477
+ },
10478
+ "required": [
10479
+ "requests"
10480
+ ]
10481
+ }
10482
+ },
10483
+ {
10484
+ "app_id": "images",
10485
+ "skill_id": "generate_draft",
10486
+ "app_namespace_ts": "images",
10487
+ "skill_method_ts": "generateDraft",
10488
+ "app_namespace_py": "images",
10489
+ "skill_method_py": "generate_draft",
10490
+ "description_key": "images.generate_draft.description",
10491
+ "description": "Quickly generate a draft/preview image from a text prompt and/or reference images (image-to-image). Also use for: quick mockups, rough design concepts, draft illustrations, sketches, quick visual previews, or any request for a fast/rough image. When the user provides uploaded images as references (embed_refs), pass them via reference_images. Do not use this for scam, spam, fake-document, fake-endorsement, public-figure impersonation, or watermark/detection-evasion requests.",
10492
+ "schema": {
10493
+ "type": "object",
10494
+ "properties": {
10495
+ "requests": {
10496
+ "type": "array",
10497
+ "description": `REQUIRED: Array of image generation request objects for parallel processing (up to 5 requests).
10498
+ This parameter is MANDATORY - you MUST always provide a 'requests' array, even for a single image.
10499
+ Example for single image: {"requests": [{"prompt": "a cute cat"}]}
10500
+ Each object must contain 'prompt' (description of the image).
10501
+ `,
10502
+ "items": {
10503
+ "type": "object",
10504
+ "properties": {
10505
+ "prompt": {
10506
+ "type": "string",
10507
+ "description": "Description of the image to generate"
10508
+ },
10509
+ "reference_images": {
10510
+ "type": "array",
10511
+ "description": 'Optional list of reference image filenames (embed_refs) to use as visual\nreferences for this generation. Pass the exact embed_ref values (original\nfilenames, e.g. "my_photo.jpg") from the toon blocks in the conversation.\nThe server resolves all cryptographic and storage details automatically.\nSupports up to 4 reference images. When provided, automatically switches to\nthe FLUX.2 [klein] 4B edit model (image-to-image, 27 credits).\n',
10512
+ "items": {
10513
+ "type": "string",
10514
+ "description": "Original filename (embed_ref) of an uploaded image"
10515
+ }
10516
+ }
10517
+ },
10518
+ "required": [
10519
+ "prompt"
10520
+ ]
10521
+ }
10522
+ }
10523
+ },
10524
+ "required": [
10525
+ "requests"
10526
+ ]
10527
+ }
10528
+ },
10529
+ {
10530
+ "app_id": "mail",
10531
+ "skill_id": "search",
10532
+ "app_namespace_ts": "mail",
10533
+ "skill_method_ts": "search",
10534
+ "app_namespace_py": "mail",
10535
+ "skill_method_py": "search",
10536
+ "description_key": "app_skills.mail.search.description",
10537
+ "description": "Run this OpenMates app skill.",
10538
+ "schema": {
10539
+ "type": "object",
10540
+ "properties": {
10541
+ "requests": {
10542
+ "type": "array",
10543
+ "description": 'REQUIRED: Array of mail search request objects.\nThe query field is optional. If omitted or empty, newest emails are returned first.\nExample: {"requests": [{"query": "invoice", "limit": 10}]}\nExample recent-first: {"requests": [{"limit": 10}]}\n',
10544
+ "items": {
10545
+ "type": "object",
10546
+ "properties": {
10547
+ "id": {
10548
+ "type": [
10549
+ "string",
10550
+ "integer"
10551
+ ],
10552
+ "description": "Optional request id echoed in results"
10553
+ },
10554
+ "query": {
10555
+ "type": "string",
10556
+ "description": "Optional search text (subject/from/body). Empty means recent-first listing."
10557
+ },
10558
+ "mailbox": {
10559
+ "type": "string",
10560
+ "description": "Optional mailbox name (defaults to INBOX)"
10561
+ },
10562
+ "limit": {
10563
+ "type": "integer",
10564
+ "minimum": 1,
10565
+ "maximum": 50,
10566
+ "default": 10,
10567
+ "description": "Maximum number of email results to return"
10568
+ }
10569
+ }
10570
+ },
10571
+ "minItems": 1
10572
+ }
10573
+ },
10574
+ "required": [
10575
+ "requests"
10576
+ ],
10577
+ "additionalProperties": false
10578
+ }
10579
+ },
10580
+ {
10581
+ "app_id": "maps",
10582
+ "skill_id": "search",
10583
+ "app_namespace_ts": "maps",
10584
+ "skill_method_ts": "search",
10585
+ "app_namespace_py": "maps",
10586
+ "skill_method_py": "search",
10587
+ "description_key": "maps.search.description",
10588
+ "description": "Search for places, businesses, restaurants, directions, locations.",
10589
+ "schema": {
10590
+ "type": "object",
10591
+ "properties": {
10592
+ "requests": {
10593
+ "type": "array",
10594
+ "description": `REQUIRED: Array of search request objects for parallel processing (up to 5 requests).
10595
+ This parameter is MANDATORY - you MUST always provide a 'requests' array, even for a single search.
10596
+ Example for single search: {"requests": [{"query": "restaurants in Berlin"}]}
10597
+ Example for multiple searches: {"requests": [{"query": "restaurants in Berlin"}, {"query": "museums in Berlin"}]}
10598
+ Each object must contain 'query' (search query string), and can include optional parameters (pageSize, languageCode, locationBias, includedType, minRating, openNow, includeReviews).
10599
+ Note: The 'id' field is auto-generated if not provided - you don't need to include it.
10600
+ `,
10601
+ "items": {
10602
+ "type": "object",
10603
+ "properties": {
10604
+ "query": {
10605
+ "type": "string",
10606
+ "description": 'Text query string to search for places (e.g., "restaurants in Berlin", "museums near Times Square")'
10607
+ },
10608
+ "pageSize": {
10609
+ "type": "integer",
10610
+ "description": "Number of results to return per request (max 20)",
10611
+ "minimum": 1,
10612
+ "maximum": 20,
10613
+ "default": 10
10614
+ },
10615
+ "languageCode": {
10616
+ "type": "string",
10617
+ "description": "Language code for results (ISO 639-1, e.g., 'en', 'es', 'fr', 'de'). Defaults to 'en' if not specified.",
10618
+ "default": "en"
10619
+ },
10620
+ "locationBias": {
10621
+ "type": "object",
10622
+ "description": "Optional location bias to prioritize results near a specific area. Can be a circle (center + radius) or rectangle (viewport).",
10623
+ "properties": {
10624
+ "circle": {
10625
+ "type": "object",
10626
+ "properties": {
10627
+ "center": {
10628
+ "type": "object",
10629
+ "properties": {
10630
+ "latitude": {
10631
+ "type": "number"
10632
+ },
10633
+ "longitude": {
10634
+ "type": "number"
10635
+ }
10636
+ }
10637
+ },
10638
+ "radius": {
10639
+ "type": "number",
10640
+ "description": "Radius in meters (0.0 to 50000.0)"
10641
+ }
10642
+ }
10643
+ },
10644
+ "rectangle": {
10645
+ "type": "object",
10646
+ "properties": {
10647
+ "low": {
10648
+ "type": "object",
10649
+ "properties": {
10650
+ "latitude": {
10651
+ "type": "number"
10652
+ },
10653
+ "longitude": {
10654
+ "type": "number"
10655
+ }
10656
+ }
10657
+ },
10658
+ "high": {
10659
+ "type": "object",
10660
+ "properties": {
10661
+ "latitude": {
10662
+ "type": "number"
10663
+ },
10664
+ "longitude": {
10665
+ "type": "number"
10666
+ }
10667
+ }
10668
+ }
10669
+ }
10670
+ }
10671
+ }
10672
+ },
10673
+ "includedType": {
10674
+ "type": "string",
10675
+ "description": "Optional place type filter (e.g., 'restaurant', 'museum', 'pharmacy'). See Google Places API place types documentation for full list."
10676
+ },
10677
+ "minRating": {
10678
+ "type": "number",
10679
+ "description": "Minimum rating filter (0.0 to 5.0, increments of 0.5). Only places with rating >= minRating will be returned.",
10680
+ "minimum": 0,
10681
+ "maximum": 5
10682
+ },
10683
+ "openNow": {
10684
+ "type": "boolean",
10685
+ "description": "If true, return only places that are currently open. Defaults to false.",
10686
+ "default": false
10687
+ },
10688
+ "includeReviews": {
10689
+ "type": "boolean",
10690
+ "description": "If true, include user reviews in the response. Defaults to false to keep response size manageable. Reviews significantly increase response size.",
10691
+ "default": false
10692
+ }
10693
+ },
10694
+ "required": [
10695
+ "query"
10696
+ ]
10697
+ }
10698
+ }
10699
+ },
10700
+ "required": [
10701
+ "requests"
10702
+ ]
10703
+ }
10704
+ },
10705
+ {
10706
+ "app_id": "math",
10707
+ "skill_id": "calculate",
10708
+ "app_namespace_ts": "math",
10709
+ "skill_method_ts": "calculate",
10710
+ "app_namespace_py": "math",
10711
+ "skill_method_py": "calculate",
10712
+ "description_key": "math.calculate.description",
10713
+ "description": "MANDATORY: Use this skill for ALL mathematical calculations without exception. This includes simple arithmetic such as addition, subtraction, multiplication (written as *, x, or \xD7), division, and parenthesised expressions like (4x22x7)/2 or (100+50)*3/2. Also use for algebra, trigonometry, calculus, unit conversions, symbolic simplification, equation solving, derivatives, and integrals. NEVER attempt to compute a numeric result yourself \u2014 always call this skill so results are guaranteed to be ex",
10714
+ "schema": {
10715
+ "type": "object",
10716
+ "properties": {
10717
+ "title": {
10718
+ "type": "string",
10719
+ "description": 'A short human-readable title that explains why this calculation is being made. This is shown in the embed preview, so prefer concise context like "Bike time to the Moon" or "Monthly mortgage estimate".\n'
10720
+ },
10721
+ "expression": {
10722
+ "type": "string",
10723
+ "description": 'The mathematical expression, equation, or operation to evaluate. Examples: - Arithmetic: "3.14159 * (42.7)^2 / cos(0.3)" - Symbolic simplify: "simplify((x^2 - 1) / (x - 1))" - Solve equation: "solve(x^2 - 4*x + 3, x)" - Derivative: "diff(sin(x) * exp(x), x)" - Integral: "integrate(x^2 * log(x), x)" - Unit conversion: "convert(100, kg, lbs)" - With context vars: "E = m * c^2 where m=1, c=299792458"\n'
10724
+ },
10725
+ "mode": {
10726
+ "type": "string",
10727
+ "description": "Evaluation mode. 'auto' (default) detects the appropriate mode from the expression. 'numeric' forces numerical evaluation. 'symbolic' forces symbolic computation. 'solve' solves an equation for a variable. 'simplify' simplifies an algebraic expression. 'diff' computes derivative. 'integrate' computes integral. 'convert' converts units.\n",
10728
+ "enum": [
10729
+ "auto",
10730
+ "numeric",
10731
+ "symbolic",
10732
+ "solve",
10733
+ "simplify",
10734
+ "diff",
10735
+ "integrate",
10736
+ "convert"
10737
+ ],
10738
+ "default": "auto"
10739
+ },
10740
+ "variable": {
10741
+ "type": "string",
10742
+ "description": "The variable to differentiate or integrate with respect to, or to solve for. Defaults to 'x'. Only needed when mode is 'diff', 'integrate', or 'solve'.\n",
10743
+ "default": "x"
10744
+ },
10745
+ "precision": {
10746
+ "type": "integer",
10747
+ "description": "Number of significant digits for numeric results. Defaults to 15. Use higher values (e.g. 50) for high-precision calculations.\n",
10748
+ "default": 15,
10749
+ "minimum": 1,
10750
+ "maximum": 100
10751
+ }
10752
+ },
10753
+ "required": [
10754
+ "expression"
10755
+ ]
10756
+ }
10757
+ },
10758
+ {
10759
+ "app_id": "models3d",
10760
+ "skill_id": "search",
10761
+ "app_namespace_ts": "models3d",
10762
+ "skill_method_ts": "search",
10763
+ "app_namespace_py": "models3d",
10764
+ "skill_method_py": "search",
10765
+ "description_key": "app_skills.models3d.search.description",
10766
+ "description": "Search public 3D model catalogs for existing models. Use this when the user wants to find, browse, compare, or link to existing 3D-printable or downloadable 3D models. Do not use it to generate new models.",
10767
+ "schema": {
10768
+ "type": "object",
10769
+ "properties": {
10770
+ "requests": {
10771
+ "type": "array",
10772
+ "description": "Array of 3D model search requests. Each request searches public 3D model catalogs and returns preview-only result cards.\n",
10773
+ "items": {
10774
+ "type": "object",
10775
+ "properties": {
10776
+ "query": {
10777
+ "type": "string",
10778
+ "description": 'Search query, e.g. "benchy", "phone stand", or "desk cable clip".'
10779
+ },
10780
+ "providers": {
10781
+ "type": "array",
10782
+ "items": {
10783
+ "type": "string",
10784
+ "enum": [
10785
+ "Printables"
10786
+ ]
10787
+ },
10788
+ "description": "Optional provider filter. Defaults to Printables."
10789
+ },
10790
+ "count": {
10791
+ "type": "integer",
10792
+ "minimum": 1,
10793
+ "maximum": 20,
10794
+ "default": 10,
10795
+ "description": "Maximum total results to return after merging providers."
10796
+ },
10797
+ "sort": {
10798
+ "type": "string",
10799
+ "enum": [
10800
+ "best_match",
10801
+ "popular",
10802
+ "downloads",
10803
+ "newest"
10804
+ ],
10805
+ "default": "best_match",
10806
+ "description": "Sorting strategy applied after provider results are merged."
10807
+ },
10808
+ "free_only": {
10809
+ "type": "boolean",
10810
+ "default": false,
10811
+ "description": "Return only results that the provider marks as free."
10812
+ }
10813
+ },
10814
+ "required": [
10815
+ "query"
10816
+ ]
10817
+ }
10818
+ }
10819
+ },
10820
+ "required": [
10821
+ "requests"
10822
+ ]
10823
+ }
10824
+ },
10825
+ {
10826
+ "app_id": "music",
10827
+ "skill_id": "generate",
10828
+ "app_namespace_ts": "music",
10829
+ "skill_method_ts": "generate",
10830
+ "app_namespace_py": "music",
10831
+ "skill_method_py": "generate",
10832
+ "description_key": "app_skills.music.generate.description",
10833
+ "description": "Generate music from a text prompt, including full songs, instrumental tracks, background music, loops, jingles, lyric-based songs, and soundtrack cues. Use this when the user asks to create music or background music. Do not use this to imitate the voice, vocals, cadence, or persona of a real public figure, living artist, famous educator, or recognizable person. Use original voices and styles only, and reject scams, spam, or detection evasion.",
10834
+ "schema": {
10835
+ "type": "object",
10836
+ "properties": {
10837
+ "requests": {
10838
+ "type": "array",
10839
+ "description": "REQUIRED: Array of music generation request objects. Each object must\ninclude a prompt and can specify duration_seconds, mode, lyrics, style,\nnegative_prompt, seed, and model.\n",
10840
+ "items": {
10841
+ "type": "object",
10842
+ "properties": {
10843
+ "prompt": {
10844
+ "type": "string",
10845
+ "description": "Text description of the music to generate."
10846
+ },
10847
+ "mode": {
10848
+ "type": "string",
10849
+ "enum": [
10850
+ "song",
10851
+ "instrumental",
10852
+ "background",
10853
+ "loop",
10854
+ "jingle"
10855
+ ],
10856
+ "default": "background",
10857
+ "description": "Desired music type."
10858
+ },
10859
+ "lyrics": {
10860
+ "type": "string",
10861
+ "description": "Optional lyrics to include for vocal/song generation."
10862
+ },
10863
+ "style": {
10864
+ "type": "string",
10865
+ "description": "Optional genre, mood, instrumentation, tempo, or production style."
10866
+ },
10867
+ "duration_seconds": {
10868
+ "type": "integer",
10869
+ "minimum": 3,
10870
+ "maximum": 184,
10871
+ "default": 30,
10872
+ "description": "Target duration in seconds. Lyria 3 Clip is 30s; Lyria 3 Pro supports longer tracks in preview."
10873
+ },
10874
+ "negative_prompt": {
10875
+ "type": "string",
10876
+ "description": "Optional sounds, genres, instruments, or qualities to avoid."
10877
+ },
10878
+ "seed": {
10879
+ "type": "integer",
10880
+ "description": "Optional seed for more reproducible output when supported."
10881
+ },
10882
+ "model": {
10883
+ "type": "string",
10884
+ "enum": [
10885
+ "lyria-3-pro-preview",
10886
+ "lyria-3-clip-preview",
10887
+ "lyria-002"
10888
+ ],
10889
+ "default": "lyria-3-pro-preview",
10890
+ "description": "Google Lyria model. Prefer lyria-3-pro-preview for latest quality."
10891
+ }
10892
+ },
10893
+ "required": [
10894
+ "prompt"
10895
+ ]
10896
+ }
10897
+ }
10898
+ },
10899
+ "required": [
10900
+ "requests"
10901
+ ]
10902
+ }
10903
+ },
10904
+ {
10905
+ "app_id": "news",
10906
+ "skill_id": "search",
10907
+ "app_namespace_ts": "news",
10908
+ "skill_method_ts": "search",
10909
+ "app_namespace_py": "news",
10910
+ "skill_method_py": "search",
10911
+ "description_key": "news.search.description",
10912
+ "description": "Search for news articles, current events, headlines, announcements.",
10913
+ "schema": {
10914
+ "type": "object",
10915
+ "properties": {
10916
+ "requests": {
10917
+ "type": "array",
10918
+ "description": `REQUIRED: Array of search request objects for parallel processing (up to 5 requests).
10919
+ This parameter is MANDATORY - you MUST always provide a 'requests' array, even for a single search.
10920
+ Example for single search: {"requests": [{"query": "iPhone news"}]}
10921
+ Example for multiple searches: {"requests": [{"query": "iPhone news"}, {"query": "MacBook news"}]}
10922
+ Each object must contain 'query' (search query string), and can include optional parameters (count, country, search_lang, safesearch, freshness).
10923
+ Note: The 'id' field is auto-generated if not provided - you don't need to include it.
10924
+ `,
10925
+ "items": {
10926
+ "type": "object",
10927
+ "properties": {
10928
+ "query": {
10929
+ "type": "string",
10930
+ "description": "Search query string"
10931
+ },
10932
+ "count": {
10933
+ "type": "integer",
10934
+ "description": "Number of results for this request (max 20)",
10935
+ "minimum": 1,
10936
+ "maximum": 20,
10937
+ "default": 6
10938
+ },
10939
+ "country": {
10940
+ "type": "string",
10941
+ "description": "Country code for localized results. Must be one of: AR, AU, AT, BE, BR, CA, CL, DK, FI, FR, DE, GR, HK, IN, ID, IT, JP, KR, MY, MX, NL, NZ, NO, CN, PL, PT, PH, RU, SA, ZA, ES, SE, CH, TW, TR, GB, US, or ALL (case-insensitive). Defaults to 'us' if invalid.",
10942
+ "enum": [
10943
+ "AR",
10944
+ "AU",
10945
+ "AT",
10946
+ "BE",
10947
+ "BR",
10948
+ "CA",
10949
+ "CL",
10950
+ "DK",
10951
+ "FI",
10952
+ "FR",
10953
+ "DE",
10954
+ "GR",
10955
+ "HK",
10956
+ "IN",
10957
+ "ID",
10958
+ "IT",
10959
+ "JP",
10960
+ "KR",
10961
+ "MY",
10962
+ "MX",
10963
+ "NL",
10964
+ "NZ",
10965
+ "NO",
10966
+ "CN",
10967
+ "PL",
10968
+ "PT",
10969
+ "PH",
10970
+ "RU",
10971
+ "SA",
10972
+ "ZA",
10973
+ "ES",
10974
+ "SE",
10975
+ "CH",
10976
+ "TW",
10977
+ "TR",
10978
+ "GB",
10979
+ "US",
10980
+ "ALL",
10981
+ "ar",
10982
+ "au",
10983
+ "at",
10984
+ "be",
10985
+ "br",
10986
+ "ca",
10987
+ "cl",
10988
+ "dk",
10989
+ "fi",
10990
+ "fr",
10991
+ "de",
10992
+ "gr",
10993
+ "hk",
10994
+ "in",
10995
+ "id",
10996
+ "it",
10997
+ "jp",
10998
+ "kr",
10999
+ "my",
11000
+ "mx",
11001
+ "nl",
11002
+ "nz",
11003
+ "no",
11004
+ "cn",
11005
+ "pl",
11006
+ "pt",
11007
+ "ph",
11008
+ "ru",
11009
+ "sa",
11010
+ "za",
11011
+ "es",
11012
+ "se",
11013
+ "ch",
11014
+ "tw",
11015
+ "tr",
11016
+ "gb",
11017
+ "us",
11018
+ "all"
11019
+ ],
11020
+ "default": "us"
11021
+ },
11022
+ "search_lang": {
11023
+ "type": "string",
11024
+ "description": "Language code for search (ISO 639-1, e.g., 'en', 'es', 'fr')",
11025
+ "default": "en"
11026
+ },
11027
+ "safesearch": {
11028
+ "type": "string",
11029
+ "description": "Safe search level",
11030
+ "enum": [
11031
+ "off",
11032
+ "moderate",
11033
+ "strict"
11034
+ ],
11035
+ "default": "moderate"
11036
+ },
11037
+ "freshness": {
11038
+ "type": "string",
11039
+ "description": 'Filter by freshness - "pd" (past 24 hours), "pw" (past week), "pm" (past month), "py" (past year). Defaults to "pw" (past week) to prioritize recent news content.',
11040
+ "enum": [
11041
+ "pd",
11042
+ "pw",
11043
+ "pm",
11044
+ "py"
11045
+ ],
11046
+ "default": "pw"
11047
+ },
11048
+ "filter_tabloids": {
11049
+ "type": "boolean",
11050
+ "description": "Filter out tabloid/boulevard media sources (e.g., BILD, Daily Mail, TMZ, The Sun) from results. Enabled by default for quality news. Set to false ONLY if the user explicitly asks for tabloid sources.",
11051
+ "default": true
11052
+ }
11053
+ },
11054
+ "required": [
11055
+ "query"
11056
+ ]
11057
+ }
11058
+ }
11059
+ },
11060
+ "required": [
11061
+ "requests"
11062
+ ]
11063
+ }
11064
+ },
11065
+ {
11066
+ "app_id": "nutrition",
11067
+ "skill_id": "search_recipes",
11068
+ "app_namespace_ts": "nutrition",
11069
+ "skill_method_ts": "searchRecipes",
11070
+ "app_namespace_py": "nutrition",
11071
+ "skill_method_py": "search_recipes",
11072
+ "description_key": "app_skills.nutrition.search_recipes.description",
11073
+ "description": "Search Edamam for recipes by natural-language query and nutrition filters. Returns recipe details with ingredients, step-by-step instructions, images, source links, and nutrition metadata. Recipes without instructions are filtered out. Best for: recipe recommendations, meal planning, dietary filtering, and cooking guidance.",
11074
+ "schema": {
11075
+ "type": "object",
11076
+ "properties": {
11077
+ "requests": {
11078
+ "type": "array",
11079
+ "description": "Array of recipe search requests. Each request searches for recipes matching a free-text query and optional Edamam filters.\n",
11080
+ "items": {
11081
+ "type": "object",
11082
+ "properties": {
11083
+ "query": {
11084
+ "type": "string",
11085
+ "description": 'Free-text recipe query, e.g. "quick vegan pasta", "gluten-free pancakes", or "miso salmon".\n'
11086
+ },
11087
+ "health": {
11088
+ "type": "array",
11089
+ "description": "Optional Edamam health labels such as vegan, vegetarian, gluten-free, dairy-free, keto-friendly, peanut-free, tree-nut-free.\n",
11090
+ "items": {
11091
+ "type": "string"
11092
+ }
11093
+ },
11094
+ "diet": {
11095
+ "type": "array",
11096
+ "description": "Optional Edamam diet labels such as balanced, high-fiber, high-protein, low-carb, low-fat, low-sodium.\n",
11097
+ "items": {
11098
+ "type": "string"
11099
+ }
11100
+ },
11101
+ "time": {
11102
+ "type": "string",
11103
+ "description": 'Optional cooking/prep time range, e.g. "1-30".'
11104
+ },
11105
+ "calories": {
11106
+ "type": "string",
11107
+ "description": 'Optional calories range, e.g. "100-600".'
11108
+ },
11109
+ "cuisine_type": {
11110
+ "type": "array",
11111
+ "description": "Optional cuisine filters such as Italian, Japanese, Mexican.",
11112
+ "items": {
11113
+ "type": "string"
11114
+ }
11115
+ },
11116
+ "meal_type": {
11117
+ "type": "array",
11118
+ "description": "Optional meal filters such as Breakfast, Dinner, Lunch, Snack.",
11119
+ "items": {
11120
+ "type": "string"
11121
+ }
11122
+ },
11123
+ "dish_type": {
11124
+ "type": "array",
11125
+ "description": "Optional dish filters such as Main course, Soup, Salad, Pancake.",
11126
+ "items": {
11127
+ "type": "string"
11128
+ }
11129
+ },
11130
+ "excluded": {
11131
+ "type": "array",
11132
+ "description": "Optional ingredients or terms to exclude from recipes.",
11133
+ "items": {
11134
+ "type": "string"
11135
+ }
11136
+ },
11137
+ "ingredients": {
11138
+ "type": "string",
11139
+ "description": 'Optional ingredient-count range, e.g. "5-10".'
11140
+ },
11141
+ "max_results": {
11142
+ "type": "integer",
11143
+ "description": "Maximum number of recipes to return with full details (1-10, default 6). Each returned result includes ingredients, step-by-step instructions, image data, source attribution, and nutrition metadata.\n",
11144
+ "default": 6
11145
+ }
11146
+ },
11147
+ "required": [
11148
+ "query"
11149
+ ]
11150
+ }
11151
+ }
11152
+ },
11153
+ "required": [
11154
+ "requests"
11155
+ ]
11156
+ }
11157
+ },
11158
+ {
11159
+ "app_id": "openmates",
11160
+ "skill_id": "share-usecase",
11161
+ "app_namespace_ts": "openmates",
11162
+ "skill_method_ts": "shareUsecase",
11163
+ "app_namespace_py": "openmates",
11164
+ "skill_method_py": "share_usecase",
11165
+ "description_key": "openmates_app.share_usecase.description",
11166
+ "description": "Use when the user has explicitly agreed to anonymously share a summary of their intended use cases with the OpenMates team to help improve the product. NEVER call this without clear user consent.",
11167
+ "schema": {
11168
+ "type": "object",
11169
+ "properties": {
11170
+ "summary": {
11171
+ "type": "string",
11172
+ "description": "A brief summary (2-5 sentences) of what the user wants to use OpenMates for, as discussed in the conversation. Should capture the key use cases and interests.\n"
11173
+ },
11174
+ "language": {
11175
+ "type": "string",
11176
+ "description": "ISO 639-1 language code of the conversation (e.g., 'en', 'de')"
11177
+ }
11178
+ },
11179
+ "required": [
11180
+ "summary",
11181
+ "language"
11182
+ ]
11183
+ }
11184
+ },
11185
+ {
11186
+ "app_id": "openmates",
11187
+ "skill_id": "get-docs",
11188
+ "app_namespace_ts": "openmates",
11189
+ "skill_method_ts": "getDocs",
11190
+ "app_namespace_py": "openmates",
11191
+ "skill_method_py": "get_docs",
11192
+ "description_key": "openmates_app.get_docs.description",
11193
+ "description": "Use when the user shares an openmates.org/docs URL, or asks to read a specific OpenMates documentation page. Automatically triggered when an openmates docs URL is detected in the conversation.",
11194
+ "schema": {
11195
+ "type": "object",
11196
+ "properties": {
11197
+ "url": {
11198
+ "type": "string",
11199
+ "description": "An openmates.org/docs URL or a docs slug path (e.g., 'architecture/chats' or 'https://openmates.org/docs/architecture/chats')\n"
11200
+ }
11201
+ },
11202
+ "required": [
11203
+ "url"
11204
+ ]
11205
+ }
11206
+ },
11207
+ {
11208
+ "app_id": "openmates",
11209
+ "skill_id": "search-docs",
11210
+ "app_namespace_ts": "openmates",
11211
+ "skill_method_ts": "searchDocs",
11212
+ "app_namespace_py": "openmates",
11213
+ "skill_method_py": "search_docs",
11214
+ "description_key": "openmates_app.search_docs.description",
11215
+ "description": "Use when the user asks about OpenMates features, setup, architecture, or documentation. Searches across all OpenMates documentation to find relevant pages.",
11216
+ "schema": {
11217
+ "type": "object",
11218
+ "properties": {
11219
+ "query": {
11220
+ "type": "string",
11221
+ "description": "Search terms to find in OpenMates documentation"
11222
+ }
11223
+ },
11224
+ "required": [
11225
+ "query"
11226
+ ]
11227
+ }
11228
+ },
11229
+ {
11230
+ "app_id": "pdf",
11231
+ "skill_id": "read",
11232
+ "app_namespace_ts": "pdf",
11233
+ "skill_method_ts": "read",
11234
+ "app_namespace_py": "pdf",
11235
+ "skill_method_py": "read",
11236
+ "description_key": "pdf.read.description",
11237
+ "description": "Load and read the raw text content (markdown) of specific pages from an uploaded PDF document. Use when the user asks what a PDF says, wants you to summarise sections, or requests information that is likely textual (paragraphs, tables, headings). The embed TOON content includes a TOC and per-page token estimates \u2014 use them to select the most relevant pages. Limits output to 50 000 tokens; call again for remaining pages if needed. Pass the exact embed_ref (original filename) from the toon block \u2014",
11238
+ "schema": {
11239
+ "type": "object",
11240
+ "properties": {
11241
+ "file_path": {
11242
+ "type": "string",
11243
+ "description": 'The original filename of the PDF (e.g. "report.pdf"). Use the exact embed_ref value from the toon block. The server resolves all cryptographic and storage details from this filename automatically.\n'
11244
+ },
11245
+ "pages": {
11246
+ "type": "array",
11247
+ "description": "1-indexed page numbers to read (e.g. [1, 2, 3]). If omitted, reads from page 1 onwards up to the token budget.",
11248
+ "items": {
11249
+ "type": "integer"
11250
+ }
11251
+ }
11252
+ },
11253
+ "required": [
11254
+ "file_path"
11255
+ ]
11256
+ }
11257
+ },
11258
+ {
11259
+ "app_id": "pdf",
11260
+ "skill_id": "search",
11261
+ "app_namespace_ts": "pdf",
11262
+ "skill_method_ts": "search",
11263
+ "app_namespace_py": "pdf",
11264
+ "skill_method_py": "search",
11265
+ "description_key": "pdf.search.description",
11266
+ "description": "Search for specific text, keywords, or phrases across all pages of an uploaded PDF. Returns matching text blocks with surrounding context and page numbers. Use when the user asks to find where something is mentioned in the document, or when a targeted keyword search is faster than reading entire sections. No LLM call required \u2014 pure text search over the OCR data. Pass the exact embed_ref (original filename) from the toon block as file_path.",
11267
+ "schema": {
11268
+ "type": "object",
11269
+ "properties": {
11270
+ "file_path": {
11271
+ "type": "string",
11272
+ "description": "The original filename of the PDF. Use the exact embed_ref from the toon block. The server resolves all cryptographic and storage details automatically.\n"
11273
+ },
11274
+ "query": {
11275
+ "type": "string",
11276
+ "description": "The search query string (case-insensitive substring match)."
11277
+ },
11278
+ "context_chars": {
11279
+ "type": "integer",
11280
+ "description": "Number of characters of surrounding context to include per match (default: 200)."
11281
+ }
11282
+ },
11283
+ "required": [
11284
+ "file_path",
11285
+ "query"
11286
+ ]
11287
+ }
11288
+ },
11289
+ {
11290
+ "app_id": "pdf",
11291
+ "skill_id": "view",
11292
+ "app_namespace_ts": "pdf",
11293
+ "skill_method_ts": "view",
11294
+ "app_namespace_py": "pdf",
11295
+ "skill_method_py": "view",
11296
+ "description_key": "pdf.view.skill_description",
11297
+ "description": "View one or more page screenshots from an uploaded PDF and return them as multimodal image blocks so the main inference model can see the pages directly. Use when the user asks about the visual layout, diagrams, charts, figures, or images on specific pages. Also useful when text OCR may have been imperfect (e.g. complex tables, mathematical notation, handwriting). Up to 5 pages can be viewed per call. Pass the exact embed_ref (original filename) from the toon block as file_path \u2014 the server reso",
11298
+ "schema": {
11299
+ "type": "object",
11300
+ "properties": {
11301
+ "file_path": {
11302
+ "type": "string",
11303
+ "description": "The original filename of the PDF. Use the exact embed_ref from the toon block. The server resolves all cryptographic and storage details automatically.\n"
11304
+ },
11305
+ "pages": {
11306
+ "type": "array",
11307
+ "description": "1-indexed page numbers to view (max 5). Example: [1, 2].",
11308
+ "items": {
11309
+ "type": "integer"
11310
+ }
11311
+ },
11312
+ "query": {
11313
+ "type": "string",
11314
+ "description": "The user's question or instruction about the page(s)."
11315
+ }
11316
+ },
11317
+ "required": [
11318
+ "file_path",
11319
+ "pages",
11320
+ "query"
11321
+ ]
11322
+ }
11323
+ },
11324
+ {
11325
+ "app_id": "reminder",
11326
+ "skill_id": "set-reminder",
11327
+ "app_namespace_ts": "reminder",
11328
+ "skill_method_ts": "setReminder",
11329
+ "app_namespace_py": "reminder",
11330
+ "skill_method_py": "set_reminder",
11331
+ "description_key": "reminder.set_reminder.description",
11332
+ "description": 'Schedule, create, or set up reminders for the user. Handles one-time and recurring reminders (e.g., "every morning", "daily at 9am", "weekly", "monthly"). Use when user wants to be reminded, notified, or alerted about something at a specific time or on a recurring schedule. Also use for automating tasks like "get news every day" or "summarize updates weekly".',
11333
+ "schema": {
11334
+ "type": "object",
11335
+ "properties": {
11336
+ "prompt": {
11337
+ "type": "string",
11338
+ "description": "The reminder message/prompt that will be shown when the reminder fires"
11339
+ },
11340
+ "trigger_type": {
11341
+ "type": "string",
11342
+ "enum": [
11343
+ "specific",
11344
+ "random"
11345
+ ],
11346
+ "description": "'specific' for exact datetime, 'random' for random time within a window"
11347
+ },
11348
+ "trigger_datetime": {
11349
+ "type": "string",
11350
+ "description": "ISO 8601 datetime for specific trigger (e.g., '2026-02-05T14:30:00'). Required if trigger_type is 'specific'."
11351
+ },
11352
+ "random_start_date": {
11353
+ "type": "string",
11354
+ "description": "Start date for random window (YYYY-MM-DD). Required if trigger_type is 'random'."
11355
+ },
11356
+ "random_end_date": {
11357
+ "type": "string",
11358
+ "description": "End date for random window (YYYY-MM-DD). Required if trigger_type is 'random'."
11359
+ },
11360
+ "random_time_start": {
11361
+ "type": "string",
11362
+ "description": "Earliest time of day for random trigger (HH:MM, 24h format, e.g., '10:00'). Optional for random triggers."
11363
+ },
11364
+ "random_time_end": {
11365
+ "type": "string",
11366
+ "description": "Latest time of day for random trigger (HH:MM, 24h format, e.g., '14:00'). Optional for random triggers."
11367
+ },
11368
+ "timezone": {
11369
+ "type": "string",
11370
+ "description": "User's timezone (e.g., 'Europe/Berlin', 'America/New_York'). Required."
11371
+ },
11372
+ "target_type": {
11373
+ "type": "string",
11374
+ "enum": [
11375
+ "new_chat",
11376
+ "existing_chat",
11377
+ "embed"
11378
+ ],
11379
+ "default": "existing_chat",
11380
+ "description": "'existing_chat' sends a follow-up in the current chat and is the default for reminders requested from chat, 'new_chat' creates a new chat when the user explicitly asks for a new chat or standalone reminder thread, 'embed' opens a saved embed fullscreen"
11381
+ },
11382
+ "new_chat_title": {
11383
+ "type": "string",
11384
+ "description": "Title for the new chat. Required if target_type is 'new_chat'."
11385
+ },
11386
+ "target_embed_id": {
11387
+ "type": "string",
11388
+ "description": "Embed ID to open when target_type is 'embed'."
11389
+ },
11390
+ "target_embed_app_id": {
11391
+ "type": "string",
11392
+ "description": "App ID for the embed target. Optional; used by client display."
11393
+ },
11394
+ "target_embed_title": {
11395
+ "type": "string",
11396
+ "description": "Display title for the embed target. Optional; used by client display."
11397
+ },
11398
+ "response_type": {
11399
+ "type": "string",
11400
+ "enum": [
11401
+ "simple",
11402
+ "full"
11403
+ ],
11404
+ "default": "simple",
11405
+ "description": "'simple' = notification-only: no AI response is generated, just a notification, email, and a visual marker in the chat history. Use for passive nudges ('remind me about this', 'ping me tomorrow'). 'full' = action trigger: the AI executes a task when the reminder fires. Use ONLY when the user wants the AI to actively do something ('summarize the news every morning', 'give me an update on X'). Default is 'simple'."
11406
+ },
11407
+ "repeat": {
11408
+ "type": "object",
11409
+ "description": "Configuration for repeating reminders. Omit for one-time reminders.",
11410
+ "properties": {
11411
+ "type": {
11412
+ "type": "string",
11413
+ "enum": [
11414
+ "daily",
11415
+ "weekly",
11416
+ "monthly",
11417
+ "custom"
11418
+ ],
11419
+ "description": "Type of repeat schedule"
11420
+ },
11421
+ "interval": {
11422
+ "type": "integer",
11423
+ "minimum": 1,
11424
+ "description": "For custom type: repeat every N units"
11425
+ },
11426
+ "interval_unit": {
11427
+ "type": "string",
11428
+ "enum": [
11429
+ "days",
11430
+ "weeks",
11431
+ "months"
11432
+ ],
11433
+ "description": "For custom type: unit of the interval"
11434
+ },
11435
+ "day_of_week": {
11436
+ "type": "integer",
11437
+ "minimum": 0,
11438
+ "maximum": 6,
11439
+ "description": "For weekly type: 0=Monday, 6=Sunday"
11440
+ },
11441
+ "day_of_month": {
11442
+ "type": "integer",
11443
+ "minimum": 1,
11444
+ "maximum": 31,
11445
+ "description": "For monthly type: day of the month (1-31)"
11446
+ },
11447
+ "end_date": {
11448
+ "type": "string",
11449
+ "description": "Optional: stop repeating after this date (YYYY-MM-DD)"
11450
+ },
11451
+ "max_occurrences": {
11452
+ "type": "integer",
11453
+ "minimum": 1,
11454
+ "description": "Optional: maximum number of times to fire"
11455
+ }
11456
+ },
11457
+ "required": [
11458
+ "type"
11459
+ ]
11460
+ }
11461
+ },
11462
+ "required": [
11463
+ "prompt",
11464
+ "trigger_type",
11465
+ "timezone"
11466
+ ]
11467
+ }
11468
+ },
11469
+ {
11470
+ "app_id": "reminder",
11471
+ "skill_id": "list-reminders",
11472
+ "app_namespace_ts": "reminder",
11473
+ "skill_method_ts": "listReminders",
11474
+ "app_namespace_py": "reminder",
11475
+ "skill_method_py": "list_reminders",
11476
+ "description_key": "reminder.list_reminders.description",
11477
+ "description": "Show the user's existing scheduled reminders.",
11478
+ "schema": {
11479
+ "type": "object",
11480
+ "properties": {
11481
+ "status": {
11482
+ "type": "string",
11483
+ "enum": [
11484
+ "pending",
11485
+ "all"
11486
+ ],
11487
+ "default": "pending",
11488
+ "description": "Filter reminders by status. 'pending' shows only upcoming reminders."
11489
+ }
11490
+ }
11491
+ }
11492
+ },
11493
+ {
11494
+ "app_id": "reminder",
11495
+ "skill_id": "cancel-reminder",
11496
+ "app_namespace_ts": "reminder",
11497
+ "skill_method_ts": "cancelReminder",
11498
+ "app_namespace_py": "reminder",
11499
+ "skill_method_py": "cancel_reminder",
11500
+ "description_key": "reminder.cancel_reminder.description",
11501
+ "description": "Cancel or delete an existing reminder.",
11502
+ "schema": {
11503
+ "type": "object",
11504
+ "properties": {
11505
+ "reminder_id": {
11506
+ "type": "string",
11507
+ "description": "ID of the reminder to cancel"
11508
+ }
11509
+ },
11510
+ "required": [
11511
+ "reminder_id"
11512
+ ]
11513
+ }
11514
+ },
11515
+ {
11516
+ "app_id": "shopping",
11517
+ "skill_id": "search_products",
11518
+ "app_namespace_ts": "shopping",
11519
+ "skill_method_ts": "searchProducts",
11520
+ "app_namespace_py": "shopping",
11521
+ "skill_method_py": "search_products",
11522
+ "description_key": "app_skills.shopping.search_products.description",
11523
+ "description": "Search products on REWE, Amazon, or Stoffe.de with real-time prices. Use category to route groceries, marketplace products, fabrics, sewing supplies, and patterns to compatible providers. Invalid provider/category combinations are rejected.",
11524
+ "schema": {
11525
+ "type": "object",
11526
+ "properties": {
11527
+ "requests": {
11528
+ "type": "array",
11529
+ "description": "Array of product search requests. Each request searches for products matching a query on a compatible shopping provider.\n",
11530
+ "items": {
11531
+ "type": "object",
11532
+ "properties": {
11533
+ "query": {
11534
+ "type": "string",
11535
+ "description": 'Search query, e.g. "bio joghurt", "coffee grinder", "wireless mouse".\n'
11536
+ },
11537
+ "provider": {
11538
+ "type": "string",
11539
+ "description": "Product provider. If omitted, inferred from category: grocery routes to REWE, fabrics/sewing_supplies/patterns route to Stoffe.de, and marketplace categories route to Amazon. Invalid explicit provider/category combinations are rejected.\n",
11540
+ "enum": [
11541
+ "REWE",
11542
+ "Amazon",
11543
+ "Stoffe.de"
11544
+ ]
11545
+ },
11546
+ "category": {
11547
+ "type": "string",
11548
+ "description": "Product category used for routing and provider compatibility. Fabrics can be searched on Stoffe.de or Amazon. Groceries can be searched on REWE or Amazon. Marketplace categories are Amazon-only.\n",
11549
+ "enum": [
11550
+ "grocery",
11551
+ "fabrics",
11552
+ "sewing_supplies",
11553
+ "patterns",
11554
+ "general_marketplace",
11555
+ "electronics",
11556
+ "home",
11557
+ "fashion",
11558
+ "beauty",
11559
+ "books",
11560
+ "sports",
11561
+ "toys",
11562
+ "automotive",
11563
+ "health",
11564
+ "music",
11565
+ "movies",
11566
+ "tools",
11567
+ "office",
11568
+ "pet_supplies",
11569
+ "video_games",
11570
+ "baby"
11571
+ ]
11572
+ },
11573
+ "max_results": {
11574
+ "type": "integer",
11575
+ "description": "Maximum number of products to return (1-20, default 10).",
11576
+ "default": 10
11577
+ },
11578
+ "sort": {
11579
+ "type": "string",
11580
+ "description": "Sort order for results. REWE supports: relevance, price_asc, price_desc, new. Amazon supports: relevance, price_asc, price_desc, review_rank, newest, best_sellers. Stoffe.de supports: relevance, price_asc, price_desc, new.\n",
11581
+ "enum": [
11582
+ "relevance",
11583
+ "price_asc",
11584
+ "price_desc",
11585
+ "new",
11586
+ "review_rank",
11587
+ "newest",
11588
+ "best_sellers"
11589
+ ],
11590
+ "default": "relevance"
11591
+ },
11592
+ "service_type": {
11593
+ "type": "string",
11594
+ "description": 'REWE-only fulfilment type. "DELIVERY" for home delivery (default). "CLICK_AND_COLLECT" for store pickup. Ignored for Amazon and Stoffe.de.\n',
11595
+ "enum": [
11596
+ "DELIVERY",
11597
+ "CLICK_AND_COLLECT"
11598
+ ],
11599
+ "default": "DELIVERY"
11600
+ },
11601
+ "country": {
11602
+ "type": "string",
11603
+ "description": "Amazon-only marketplace country code. Example: us, uk, de, fr, it, es, ca, au, jp, in, br, mx, nl, sg, se, pl. If omitted, inferred from user language/locale with fallback to us.\n"
11604
+ },
11605
+ "department": {
11606
+ "type": "string",
11607
+ "description": "Amazon-only category filter. Example: electronics, computers, fashion, home, books, sports, toys, beauty, grocery, automotive, health, music, movies, tools, office, pet_supplies, video_games, baby.\n",
11608
+ "enum": [
11609
+ "electronics",
11610
+ "computers",
11611
+ "fashion",
11612
+ "home",
11613
+ "books",
11614
+ "sports",
11615
+ "toys",
11616
+ "beauty",
11617
+ "grocery",
11618
+ "automotive",
11619
+ "health",
11620
+ "music",
11621
+ "movies",
11622
+ "tools",
11623
+ "office",
11624
+ "pet_supplies",
11625
+ "video_games",
11626
+ "baby"
11627
+ ]
11628
+ },
11629
+ "min_price": {
11630
+ "type": "number",
11631
+ "description": "Amazon-only minimum price filter (client-side after fetch)."
11632
+ },
11633
+ "max_price": {
11634
+ "type": "number",
11635
+ "description": "Amazon-only maximum price filter (client-side after fetch)."
11636
+ }
11637
+ },
11638
+ "required": [
11639
+ "query"
11640
+ ]
11641
+ }
11642
+ }
11643
+ },
11644
+ "required": [
11645
+ "requests"
11646
+ ]
11647
+ }
11648
+ },
11649
+ {
11650
+ "app_id": "social_media",
11651
+ "skill_id": "get-posts",
11652
+ "app_namespace_ts": "socialMedia",
11653
+ "skill_method_ts": "getPosts",
11654
+ "app_namespace_py": "social_media",
11655
+ "skill_method_py": "get_posts",
11656
+ "description_key": "app_skills.social_media.get_posts.description",
11657
+ "description": "Fetch recent social media posts from one or more specific platform pages or profiles. Supports Reddit subreddits, Bluesky profile feeds, and Mastodon public profiles. Use for profile monitoring, community research, and finding conversations to review manually. Costs 10 credits per request.",
11658
+ "schema": {
11659
+ "type": "object",
11660
+ "properties": {
11661
+ "requests": {
11662
+ "type": "array",
11663
+ "description": "Array of social post fetch requests. For Reddit, page is the subreddit name without r/ (for example: privacy, selfhosted, buildinpublic). For Bluesky profile posts, page is the actor handle. For Mastodon, page is user@instance or a public profile URL.\n",
11664
+ "items": {
11665
+ "type": "object",
11666
+ "properties": {
11667
+ "id": {
11668
+ "description": "Optional caller-supplied ID for correlating responses."
11669
+ },
11670
+ "platform": {
11671
+ "type": "string",
11672
+ "description": "Social platform to fetch from.",
11673
+ "enum": [
11674
+ "bluesky",
11675
+ "mastodon",
11676
+ "reddit"
11677
+ ],
11678
+ "default": "reddit"
11679
+ },
11680
+ "page": {
11681
+ "type": "string",
11682
+ "description": "Platform page/profile identifier. For Reddit, this is the subreddit name. For Bluesky, this is an actor handle for profile feeds. For Mastodon, use user@instance or a profile URL."
11683
+ },
11684
+ "sort": {
11685
+ "type": "string",
11686
+ "description": "Post listing sort. Reddit supports new/hot/rising/top/comments. Comments means most discussed in the selected time range. Bluesky and Mastodon profile feeds ignore this value.",
11687
+ "enum": [
11688
+ "new",
11689
+ "hot",
11690
+ "rising",
11691
+ "top",
11692
+ "comments"
11693
+ ],
11694
+ "default": "new"
11695
+ },
11696
+ "time_range": {
11697
+ "type": "string",
11698
+ "description": "Reddit time filter for top/comments sorts.",
11699
+ "enum": [
11700
+ "hour",
11701
+ "day",
11702
+ "week",
11703
+ "month",
11704
+ "year",
11705
+ "all"
11706
+ ]
11707
+ },
11708
+ "limit": {
11709
+ "type": "integer",
11710
+ "description": "Number of posts to fetch per page.",
11711
+ "minimum": 1,
11712
+ "maximum": 25,
11713
+ "default": 10
11714
+ },
11715
+ "include_comments": {
11716
+ "type": "boolean",
11717
+ "description": "Whether to fetch comments/replies for returned posts when supported.",
11718
+ "default": true
11719
+ },
11720
+ "comments_limit": {
11721
+ "type": "integer",
11722
+ "description": "Number of comments/replies to fetch per post.",
11723
+ "minimum": 0,
11724
+ "maximum": 5,
11725
+ "default": 5
11726
+ },
11727
+ "comments_sort": {
11728
+ "type": "string",
11729
+ "description": "Reddit comment sort. Bluesky and Mastodon ignore this value.",
11730
+ "enum": [
11731
+ "confidence",
11732
+ "top",
11733
+ "new",
11734
+ "controversial",
11735
+ "old"
11736
+ ],
11737
+ "default": "top"
11738
+ },
11739
+ "min_score": {
11740
+ "type": "integer",
11741
+ "description": "Minimum Reddit score/upvotes to include.",
11742
+ "minimum": 0
11743
+ },
11744
+ "min_comments": {
11745
+ "type": "integer",
11746
+ "description": "Minimum Reddit comment count to include.",
11747
+ "minimum": 0
11748
+ },
11749
+ "exclude_stickied": {
11750
+ "type": "boolean",
11751
+ "description": "Exclude stickied Reddit posts.",
11752
+ "default": true
11753
+ },
11754
+ "exclude_nsfw": {
11755
+ "type": "boolean",
11756
+ "description": "Exclude NSFW Reddit posts.",
11757
+ "default": true
11758
+ },
11759
+ "include_self_posts": {
11760
+ "type": "boolean",
11761
+ "description": "Include Reddit text/self posts.",
11762
+ "default": true
11763
+ },
11764
+ "include_link_posts": {
11765
+ "type": "boolean",
11766
+ "description": "Include Reddit link/media posts.",
11767
+ "default": true
11768
+ }
11769
+ }
11770
+ }
11771
+ }
11772
+ },
11773
+ "required": [
11774
+ "requests"
11775
+ ]
11776
+ }
11777
+ },
11778
+ {
11779
+ "app_id": "social_media",
11780
+ "skill_id": "search",
11781
+ "app_namespace_ts": "socialMedia",
11782
+ "skill_method_ts": "search",
11783
+ "app_namespace_py": "social_media",
11784
+ "skill_method_py": "search",
11785
+ "description_key": "app_skills.social_media.search.description",
11786
+ "description": "Search supported social platforms for recent public posts around a topic. Use this for topic monitoring and broad discovery across pages/profiles, not for monitoring a known profile; use Get posts for profile/page posts. Omit platform to search every supported social platform. Costs 10 credits per request.",
11787
+ "schema": {
11788
+ "type": "object",
11789
+ "properties": {
11790
+ "requests": {
11791
+ "type": "array",
11792
+ "description": "Array of social post search requests. For Bluesky, query is the topic to search and author optionally restricts results to a specific handle. For Mastodon, mastodon.social is searched by default and mastodon_instances can add more public instances.\n",
11793
+ "items": {
11794
+ "type": "object",
11795
+ "properties": {
11796
+ "id": {
11797
+ "description": "Optional caller-supplied ID for correlating responses."
11798
+ },
11799
+ "platform": {
11800
+ "type": "string",
11801
+ "description": "Social platform to search. Omit or use all to search every supported provider.",
11802
+ "enum": [
11803
+ "all",
11804
+ "bluesky",
11805
+ "mastodon",
11806
+ "reddit"
11807
+ ],
11808
+ "default": "all"
11809
+ },
11810
+ "query": {
11811
+ "type": "string",
11812
+ "description": "Topic or search query to find posts around."
11813
+ },
11814
+ "page": {
11815
+ "type": "string",
11816
+ "description": "Optional subreddit/page to restrict Reddit search to, without r/. For Mastodon, optionally provide one extra instance such as fosstodon.org."
11817
+ },
11818
+ "mastodon_instances": {
11819
+ "type": "array",
11820
+ "description": "Optional additional Mastodon instances to search after mastodon.social, for example fosstodon.org or hachyderm.io.",
11821
+ "items": {
11822
+ "type": "string"
11823
+ }
11824
+ },
11825
+ "sort": {
11826
+ "type": "string",
11827
+ "description": "Search sort. Bluesky supports latest/top. Reddit supports relevance/hot/top/new/comments/latest. Mastodon public search returns instance-ranked recent results and ignores sort.",
11828
+ "enum": [
11829
+ "latest",
11830
+ "top",
11831
+ "new",
11832
+ "hot",
11833
+ "relevance",
11834
+ "comments"
11835
+ ],
11836
+ "default": "latest"
11837
+ },
11838
+ "time_range": {
11839
+ "type": "string",
11840
+ "description": "Reddit time filter for top/comments search.",
11841
+ "enum": [
11842
+ "hour",
11843
+ "day",
11844
+ "week",
11845
+ "month",
11846
+ "year",
11847
+ "all"
11848
+ ]
11849
+ },
11850
+ "limit": {
11851
+ "type": "integer",
11852
+ "description": "Number of posts to fetch per search.",
11853
+ "minimum": 1,
11854
+ "maximum": 25,
11855
+ "default": 10
11856
+ },
11857
+ "author": {
11858
+ "type": "string",
11859
+ "description": "Optional platform profile/handle filter. For Bluesky, this maps to the author filter."
11860
+ },
11861
+ "include_comments": {
11862
+ "type": "boolean",
11863
+ "description": "Whether to fetch comments/replies for returned posts when supported.",
11864
+ "default": false
11865
+ },
11866
+ "comments_limit": {
11867
+ "type": "integer",
11868
+ "description": "Number of comments/replies to fetch per returned post when supported.",
11869
+ "minimum": 0,
11870
+ "maximum": 5,
11871
+ "default": 0
11872
+ },
11873
+ "comments_sort": {
11874
+ "type": "string",
11875
+ "description": "Reddit comment sort.",
11876
+ "enum": [
11877
+ "confidence",
11878
+ "top",
11879
+ "new",
11880
+ "controversial",
11881
+ "old"
11882
+ ],
11883
+ "default": "top"
11884
+ },
11885
+ "min_score": {
11886
+ "type": "integer",
11887
+ "description": "Minimum Reddit score/upvotes to include.",
11888
+ "minimum": 0
11889
+ },
11890
+ "min_comments": {
11891
+ "type": "integer",
11892
+ "description": "Minimum Reddit comment count to include.",
11893
+ "minimum": 0
11894
+ },
11895
+ "exclude_stickied": {
11896
+ "type": "boolean",
11897
+ "description": "Exclude stickied Reddit posts.",
11898
+ "default": true
11899
+ },
11900
+ "exclude_nsfw": {
11901
+ "type": "boolean",
11902
+ "description": "Exclude NSFW Reddit posts.",
11903
+ "default": true
11904
+ }
11905
+ },
11906
+ "required": [
11907
+ "query"
11908
+ ]
11909
+ }
11910
+ }
11911
+ },
11912
+ "required": [
11913
+ "requests"
11914
+ ]
11915
+ }
11916
+ },
11917
+ {
11918
+ "app_id": "tasks",
11919
+ "skill_id": "create",
11920
+ "app_namespace_ts": "tasks",
11921
+ "skill_method_ts": "create",
11922
+ "app_namespace_py": "tasks",
11923
+ "skill_method_py": "create",
11924
+ "description_key": "tasks.skills.create.description",
11925
+ "description": "Create one or more user-visible tasks. Use this for planning, task capture, or breaking a request into trackable work. Default unclear assignees to the user.",
11926
+ "schema": {
11927
+ "type": "object",
11928
+ "properties": {
11929
+ "tasks": {
11930
+ "type": "array",
11931
+ "items": {
11932
+ "type": "object",
11933
+ "properties": {
11934
+ "title": {
11935
+ "type": "string"
11936
+ },
11937
+ "description": {
11938
+ "type": "string"
11939
+ },
11940
+ "assignee": {
11941
+ "type": "string",
11942
+ "enum": [
11943
+ "user",
11944
+ "openmates"
11945
+ ]
11946
+ },
11947
+ "status": {
11948
+ "type": "string",
11949
+ "enum": [
11950
+ "backlog",
11951
+ "todo",
11952
+ "in_progress",
11953
+ "blocked"
11954
+ ]
11955
+ }
11956
+ }
11957
+ }
11958
+ },
11959
+ "title": {
11960
+ "type": "string",
11961
+ "description": "Single-task title when not using tasks[]."
11962
+ },
11963
+ "description": {
11964
+ "type": "string"
11965
+ },
11966
+ "assignee": {
11967
+ "type": "string",
11968
+ "enum": [
11969
+ "user",
11970
+ "openmates"
11971
+ ]
11972
+ }
11973
+ },
11974
+ "required": []
11975
+ }
11976
+ },
11977
+ {
11978
+ "app_id": "tasks",
11979
+ "skill_id": "search",
11980
+ "app_namespace_ts": "tasks",
11981
+ "skill_method_ts": "search",
11982
+ "app_namespace_py": "tasks",
11983
+ "skill_method_py": "search",
11984
+ "description_key": "tasks.skills.search.description",
11985
+ "description": "Search the user's encrypted tasks through a connected capable client. Do not use server-visible metadata as a private task-content search fallback.",
11986
+ "schema": {
11987
+ "type": "object",
11988
+ "properties": {
11989
+ "query": {
11990
+ "type": "string",
11991
+ "description": "Private task text to search for on a connected client."
11992
+ }
11993
+ },
11994
+ "required": [
11995
+ "query"
11996
+ ]
11997
+ }
11998
+ },
11999
+ {
12000
+ "app_id": "travel",
12001
+ "skill_id": "search_connections",
12002
+ "app_namespace_ts": "travel",
12003
+ "skill_method_ts": "searchConnections",
12004
+ "app_namespace_py": "travel",
12005
+ "skill_method_py": "search_connections",
12006
+ "description_key": "app_skills.travel.search_connections.description",
12007
+ "description": 'Search for flight or train connections for a particular date with details (airlines/operators, times, stops, durations, prices). Use when user asks about flights, train connections, or travel between cities on a specific date. Set transport_methods to ["airplane"] for flights or ["train"] for trains. If the user names a provider, set providers to one or more of: google_flights, deutsche_bahn, flix. If no provider is specified, all providers for the selected transport method are searched. Add cou',
12008
+ "schema": {
12009
+ "type": "object",
12010
+ "properties": {
12011
+ "requests": {
12012
+ "type": "array",
12013
+ "description": "Array of connection search requests. Each request searches for transport connections for a complete trip (one-way, round trip, or multi-stop).\n",
12014
+ "items": {
12015
+ "type": "object",
12016
+ "properties": {
12017
+ "legs": {
12018
+ "type": "array",
12019
+ "description": "Ordered list of trip legs. One-way trip = 1 leg. Round trip = 2 legs (outbound + return). Multi-stop = N legs. Each leg specifies an origin, destination, and departure date.\n",
12020
+ "items": {
12021
+ "type": "object",
12022
+ "properties": {
12023
+ "origin": {
12024
+ "type": "string",
12025
+ "description": 'Origin city or location name (e.g. "Munich", "London Heathrow", "Berlin"). The system resolves this to airport codes or coordinates internally.\n'
12026
+ },
12027
+ "destination": {
12028
+ "type": "string",
12029
+ "description": "Destination city or location name."
12030
+ },
12031
+ "date": {
12032
+ "type": "string",
12033
+ "description": "Departure date in YYYY-MM-DD format."
12034
+ }
12035
+ },
12036
+ "required": [
12037
+ "origin",
12038
+ "destination",
12039
+ "date"
12040
+ ]
12041
+ }
12042
+ },
12043
+ "transport_methods": {
12044
+ "type": "array",
12045
+ "description": 'Transport types to search. Supported: "airplane" (worldwide via Google Flights), "train" (Germany + select European routes via Deutsche Bahn and FlixTrain). IMPORTANT: Set to ["train"] when user asks about trains, rail, or Deutsche Bahn.\n',
12046
+ "items": {
12047
+ "type": "string",
12048
+ "enum": [
12049
+ "airplane",
12050
+ "train",
12051
+ "bus",
12052
+ "boat"
12053
+ ]
12054
+ },
12055
+ "default": [
12056
+ "airplane"
12057
+ ]
12058
+ },
12059
+ "providers": {
12060
+ "type": "array",
12061
+ "description": 'Optional provider IDs to search. Use "google_flights" for flights, "deutsche_bahn" for Deutsche Bahn / ICE / Bahn.de / Sparpreis train searches, and "flix" for FlixBus / FlixTrain. If omitted, all providers for the selected transport method are used, then filtered by countries if provided.\n',
12062
+ "items": {
12063
+ "type": "string",
12064
+ "enum": [
12065
+ "google_flights",
12066
+ "deutsche_bahn",
12067
+ "flix"
12068
+ ]
12069
+ }
12070
+ },
12071
+ "countries": {
12072
+ "type": "array",
12073
+ "description": "ISO 3166-1 alpha-2 country codes involved in the route, inferred from origin, destination, and known stops. Country matching is OR: a provider is relevant when it supports at least one listed country. Google Flights is global and remains eligible for airplane searches in all countries.\n",
12074
+ "items": {
12075
+ "type": "string"
12076
+ }
12077
+ },
12078
+ "passengers": {
12079
+ "type": "integer",
12080
+ "description": "Number of adult passengers.",
12081
+ "default": 1
12082
+ },
12083
+ "travel_class": {
12084
+ "type": "string",
12085
+ "description": "Cabin class for flights.",
12086
+ "enum": [
12087
+ "economy",
12088
+ "premium_economy",
12089
+ "business",
12090
+ "first"
12091
+ ],
12092
+ "default": "economy"
12093
+ },
12094
+ "max_results": {
12095
+ "type": "integer",
12096
+ "description": "Maximum number of connection options to return per transport method.",
12097
+ "default": 6
12098
+ },
12099
+ "non_stop_only": {
12100
+ "type": "boolean",
12101
+ "description": "If true, only return direct/non-stop connections.",
12102
+ "default": false
12103
+ },
12104
+ "max_stops": {
12105
+ "type": "integer",
12106
+ "description": "Maximum number of stops allowed. Use 0 for direct/non-stop only, 1 for up to one stop, or 2 for up to two stops."
12107
+ },
12108
+ "max_price": {
12109
+ "type": "number",
12110
+ "description": "Maximum total price for the connection in the requested currency. Results above this price are filtered from strict matches."
12111
+ },
12112
+ "include_airlines": {
12113
+ "type": "array",
12114
+ "description": "Only show flights from these airlines. Use IATA carrier codes when known, such as LH, BA, VY, or FR.",
12115
+ "items": {
12116
+ "type": "string"
12117
+ }
12118
+ },
12119
+ "exclude_airlines": {
12120
+ "type": "array",
12121
+ "description": "Exclude flights from these airlines. Use IATA carrier codes when known. Do not combine with include_airlines.",
12122
+ "items": {
12123
+ "type": "string"
12124
+ }
12125
+ },
12126
+ "min_departure_time": {
12127
+ "type": "string",
12128
+ "description": "Earliest acceptable local departure time in HH:MM format."
12129
+ },
12130
+ "max_departure_time": {
12131
+ "type": "string",
12132
+ "description": "Latest acceptable local departure time in HH:MM format."
12133
+ },
12134
+ "min_arrival_time": {
12135
+ "type": "string",
12136
+ "description": "Earliest acceptable local arrival time in HH:MM format."
12137
+ },
12138
+ "max_arrival_time": {
12139
+ "type": "string",
12140
+ "description": "Latest acceptable local arrival time in HH:MM format."
12141
+ },
12142
+ "max_duration_minutes": {
12143
+ "type": "integer",
12144
+ "description": "Maximum total duration for the first leg, in minutes."
12145
+ },
12146
+ "max_layover_minutes": {
12147
+ "type": "integer",
12148
+ "description": "Maximum allowed layover or transfer duration, in minutes."
12149
+ },
12150
+ "avoid_overnight_layovers": {
12151
+ "type": "boolean",
12152
+ "description": "If true, remove connections with overnight layovers or transfers.",
12153
+ "default": false
12154
+ },
12155
+ "currency": {
12156
+ "type": "string",
12157
+ "description": "Preferred currency for prices (ISO 4217 code).",
12158
+ "default": "EUR"
12159
+ },
12160
+ "sort_by": {
12161
+ "type": "string",
12162
+ "description": 'How to sort the results. Options: "price_asc" (cheapest first, default), "price_desc" (most expensive first), "duration_asc" (shortest first), "duration_desc" (longest first), "departure_asc" (earliest departure first), "departure_desc" (latest departure first), "stops_asc" (fewest stops first), "stops_desc" (most stops first).\n',
12163
+ "enum": [
12164
+ "price_asc",
12165
+ "price_desc",
12166
+ "duration_asc",
12167
+ "duration_desc",
12168
+ "departure_asc",
12169
+ "departure_desc",
12170
+ "stops_asc",
12171
+ "stops_desc"
12172
+ ],
12173
+ "default": "price_asc"
12174
+ }
12175
+ },
12176
+ "required": [
12177
+ "legs"
12178
+ ]
12179
+ }
12180
+ }
12181
+ },
12182
+ "required": [
12183
+ "requests"
12184
+ ]
12185
+ }
12186
+ },
12187
+ {
12188
+ "app_id": "travel",
12189
+ "skill_id": "search_stays",
12190
+ "app_namespace_ts": "travel",
12191
+ "skill_method_ts": "searchStays",
12192
+ "app_namespace_py": "travel",
12193
+ "skill_method_py": "search_stays",
12194
+ "description_key": "app_skills.travel.search_stays.description",
12195
+ "description": "Run this OpenMates app skill.",
12196
+ "schema": {
12197
+ "type": "object",
12198
+ "properties": {
12199
+ "requests": {
12200
+ "type": "array",
12201
+ "description": "Array of stay search requests. Each request searches for accommodation at a specific destination for given dates.\n",
12202
+ "items": {
12203
+ "type": "object",
12204
+ "properties": {
12205
+ "query": {
12206
+ "type": "string",
12207
+ "description": 'Search query describing the destination or property (e.g. "Hotels in Paris", "Hostels near Eiffel Tower", "Barcelona beachfront hotel").\n'
12208
+ },
12209
+ "check_in_date": {
12210
+ "type": "string",
12211
+ "description": 'Check-in date in YYYY-MM-DD format (e.g. "2026-03-15").\n'
12212
+ },
12213
+ "check_out_date": {
12214
+ "type": "string",
12215
+ "description": 'Check-out date in YYYY-MM-DD format (e.g. "2026-03-18").\n'
12216
+ },
12217
+ "adults": {
12218
+ "type": "integer",
12219
+ "description": "Number of adult guests.",
12220
+ "default": 2
12221
+ },
12222
+ "children": {
12223
+ "type": "integer",
12224
+ "description": "Number of children.",
12225
+ "default": 0
12226
+ },
12227
+ "currency": {
12228
+ "type": "string",
12229
+ "description": 'Price currency (ISO 4217 code, e.g. "EUR", "USD").\n',
12230
+ "default": "EUR"
12231
+ },
12232
+ "sort_by": {
12233
+ "type": "string",
12234
+ "description": 'Sort order for results. Options: "relevance" (default), "price_asc" (lowest price first), "rating_desc" (highest rated first), "reviews_desc" (most reviewed).\n',
12235
+ "default": "relevance"
12236
+ },
12237
+ "min_price": {
12238
+ "type": "number",
12239
+ "description": "Minimum nightly price filter."
12240
+ },
12241
+ "max_price": {
12242
+ "type": "number",
12243
+ "description": "Maximum nightly price filter."
12244
+ },
12245
+ "hotel_class": {
12246
+ "type": "string",
12247
+ "description": 'Comma-separated star rating filter (e.g. "3,4,5" for 3-star and above).\n'
12248
+ },
12249
+ "max_results": {
12250
+ "type": "integer",
12251
+ "description": "Maximum number of results to return.",
12252
+ "default": 10
12253
+ }
12254
+ },
12255
+ "required": [
12256
+ "query",
12257
+ "check_in_date",
12258
+ "check_out_date"
12259
+ ]
12260
+ }
12261
+ }
12262
+ },
12263
+ "required": [
12264
+ "requests"
12265
+ ]
12266
+ }
12267
+ },
12268
+ {
12269
+ "app_id": "travel",
12270
+ "skill_id": "get_flight",
12271
+ "app_namespace_ts": "travel",
12272
+ "skill_method_ts": "getFlight",
12273
+ "app_namespace_py": "travel",
12274
+ "skill_method_py": "get_flight",
12275
+ "description_key": "app_skills.travel.get_flight.description",
12276
+ "description": "Fetch the real GPS flight track and actual departure/landing times for a specific completed/past flight. Use when the user asks to see how a flight actually went, the real flight path on a map, or actual timing and runway info. Requires the IATA flight number (e.g. 'LH2472') and the departure date. Costs 7 credits per lookup.",
12277
+ "schema": {
12278
+ "type": "object",
12279
+ "properties": {
12280
+ "flight_number": {
12281
+ "type": "string",
12282
+ "description": "IATA flight number including the carrier code prefix (e.g. 'LH2472', 'BA234', 'AF447'). Do NOT include spaces.\n"
12283
+ },
12284
+ "departure_date": {
12285
+ "type": "string",
12286
+ "description": "Departure date in YYYY-MM-DD format (e.g. '2026-03-05'). Must be a past/completed date \u2014 live tracking is not supported.\n"
12287
+ },
12288
+ "origin_iata": {
12289
+ "type": "string",
12290
+ "description": "Optional IATA code of the departure airport (e.g. 'MUC'). Used for disambiguation when a flight number has multiple legs.\n"
12291
+ },
12292
+ "destination_iata": {
12293
+ "type": "string",
12294
+ "description": "Optional IATA code of the destination airport (e.g. 'LHR'). Used for diversion detection.\n"
12295
+ }
12296
+ },
12297
+ "required": [
12298
+ "flight_number",
12299
+ "departure_date"
12300
+ ]
12301
+ }
12302
+ },
12303
+ {
12304
+ "app_id": "videos",
12305
+ "skill_id": "generate",
12306
+ "app_namespace_ts": "videos",
12307
+ "skill_method_ts": "generate",
12308
+ "app_namespace_py": "videos",
12309
+ "skill_method_py": "generate",
12310
+ "description_key": "app_skills.videos.generate.description",
12311
+ "description": "Generate short photorealistic or generative footage from text prompts using Google Veo. Use this when the user asks for cinematic footage, realistic scenes, camera movement, stylized animation, or non-deterministic video generation. Do not use this for exact text slides, product announcements, diagrams, charts, UI-like motion graphics, or branded videos where exact text and layout matter; those requests should use videos.create with an explicit ```remotion:Name.tsx fence instead. Do not use this",
12312
+ "schema": {
12313
+ "type": "object",
12314
+ "properties": {
12315
+ "requests": {
12316
+ "type": "array",
12317
+ "description": "REQUIRED array of video generation request objects.",
12318
+ "items": {
12319
+ "type": "object",
12320
+ "properties": {
12321
+ "prompt": {
12322
+ "type": "string",
12323
+ "description": "Detailed text description of the video to generate."
12324
+ },
12325
+ "aspect_ratio": {
12326
+ "type": "string",
12327
+ "enum": [
12328
+ "16:9",
12329
+ "9:16"
12330
+ ],
12331
+ "default": "16:9"
12332
+ },
12333
+ "duration_seconds": {
12334
+ "type": "integer",
12335
+ "enum": [
12336
+ 4,
12337
+ 6,
12338
+ 8
12339
+ ],
12340
+ "default": 8
12341
+ },
12342
+ "resolution": {
12343
+ "type": "string",
12344
+ "enum": [
12345
+ "720p",
12346
+ "1080p",
12347
+ "4k"
12348
+ ],
12349
+ "default": "720p"
12350
+ },
12351
+ "seed": {
12352
+ "type": "integer",
12353
+ "description": "Optional seed for more reproducible output when supported."
12354
+ },
12355
+ "model": {
12356
+ "type": "string",
12357
+ "enum": [
12358
+ "veo-3.1-generate-preview",
12359
+ "veo-3.1-fast-generate-preview",
12360
+ "veo-3.0-generate-001"
12361
+ ],
12362
+ "default": "veo-3.1-generate-preview"
12363
+ }
12364
+ },
12365
+ "required": [
12366
+ "prompt"
12367
+ ]
12368
+ }
12369
+ }
12370
+ },
12371
+ "required": [
12372
+ "requests"
12373
+ ]
12374
+ }
12375
+ },
12376
+ {
12377
+ "app_id": "videos",
12378
+ "skill_id": "create",
12379
+ "app_namespace_ts": "videos",
12380
+ "skill_method_ts": "create",
12381
+ "app_namespace_py": "videos",
12382
+ "skill_method_py": "create",
12383
+ "description_key": "app_skills.videos.create.description",
12384
+ "description": "Create deterministic code-backed videos with Remotion. Use this for text slides, product announcements, diagrams, charts, UI-like motion graphics, or branded videos where exact text and layout matter. The assistant must write an explicit ```remotion:Name.tsx fence; do not use this for photorealistic footage or generic TSX components.",
12385
+ "schema": {
12386
+ "type": "object",
12387
+ "properties": {
12388
+ "source": {
12389
+ "type": "string",
12390
+ "description": "Remotion TSX source code to render."
12391
+ },
12392
+ "filename": {
12393
+ "type": "string",
12394
+ "description": "Source filename, for example ProductAnnouncement.tsx."
12395
+ }
12396
+ },
12397
+ "required": [
12398
+ "source"
12399
+ ]
12400
+ }
12401
+ },
12402
+ {
12403
+ "app_id": "videos",
12404
+ "skill_id": "get_transcript",
12405
+ "app_namespace_ts": "videos",
12406
+ "skill_method_ts": "getTranscript",
12407
+ "app_namespace_py": "videos",
12408
+ "skill_method_py": "get_transcript",
12409
+ "description_key": "videos.get_transcript.description",
12410
+ "description": "Get the transcript/content of a specific YouTube video URL.",
12411
+ "schema": {
12412
+ "type": "object",
12413
+ "properties": {
12414
+ "requests": {
12415
+ "type": "array",
12416
+ "description": `REQUIRED: Array of transcript request objects for parallel processing.
12417
+ This parameter is MANDATORY - you MUST always provide a 'requests' array, even for a single transcript.
12418
+ Example for single transcript: {"requests": [{"url": "https://youtube.com/watch?v=abc123"}]}
12419
+ Example for multiple transcripts: {"requests": [{"url": "https://youtube.com/watch?v=abc123"}, {"url": "https://youtube.com/watch?v=def456"}]}
12420
+ Each object must contain 'url' (YouTube video URL), and can include optional parameters (languages).
12421
+ Note: The 'id' field is auto-generated if not provided - you don't need to include it.
12422
+ `,
12423
+ "items": {
12424
+ "type": "object",
12425
+ "properties": {
12426
+ "url": {
12427
+ "type": "string",
12428
+ "description": "YouTube video URL (supports youtube.com/watch?v= and youtu.be/ formats)"
12429
+ },
12430
+ "languages": {
12431
+ "type": "array",
12432
+ "description": "List of language codes to try for transcript (ISO 639-1, e.g., 'en', 'de', 'es', 'fr'). The API will use the first available language.",
12433
+ "items": {
12434
+ "type": "string"
12435
+ },
12436
+ "default": [
12437
+ "en",
12438
+ "de",
12439
+ "es",
12440
+ "fr"
12441
+ ]
12442
+ }
12443
+ },
12444
+ "required": [
12445
+ "url"
12446
+ ]
12447
+ }
12448
+ }
12449
+ },
12450
+ "required": [
12451
+ "requests"
12452
+ ]
12453
+ }
12454
+ },
12455
+ {
12456
+ "app_id": "videos",
12457
+ "skill_id": "search",
12458
+ "app_namespace_ts": "videos",
12459
+ "skill_method_ts": "search",
12460
+ "app_namespace_py": "videos",
12461
+ "skill_method_py": "search",
12462
+ "description_key": "videos.search.description",
12463
+ "description": "Search for videos, documentaries, tutorials, clips on the web.",
12464
+ "schema": {
12465
+ "type": "object",
12466
+ "properties": {
12467
+ "requests": {
12468
+ "type": "array",
12469
+ "description": `REQUIRED: Array of search request objects for parallel processing (up to 5 requests).
12470
+ This parameter is MANDATORY - you MUST always provide a 'requests' array, even for a single search.
12471
+ Example for single search: {"requests": [{"query": "Python tutorial"}]}
12472
+ Example for multiple searches: {"requests": [{"query": "Python tutorial"}, {"query": "FastAPI tutorial"}]}
12473
+ Each object must contain 'query' (search query string), and can include optional parameters (count, country, search_lang, safesearch).
12474
+ Note: The 'id' field is auto-generated if not provided - you don't need to include it.
12475
+ `,
12476
+ "items": {
12477
+ "type": "object",
12478
+ "properties": {
12479
+ "query": {
12480
+ "type": "string",
12481
+ "description": "Search query string"
12482
+ },
12483
+ "count": {
12484
+ "type": "integer",
12485
+ "description": "Number of results for this request (max 20)",
12486
+ "minimum": 1,
12487
+ "maximum": 20,
12488
+ "default": 6
12489
+ },
12490
+ "country": {
12491
+ "type": "string",
12492
+ "description": "Country code for localized results. Must be one of: AR, AU, AT, BE, BR, CA, CL, DK, FI, FR, DE, GR, HK, IN, ID, IT, JP, KR, MY, MX, NL, NZ, NO, CN, PL, PT, PH, RU, SA, ZA, ES, SE, CH, TW, TR, GB, US, or ALL (case-insensitive). Defaults to 'us' if invalid.",
12493
+ "enum": [
12494
+ "AR",
12495
+ "AU",
12496
+ "AT",
12497
+ "BE",
12498
+ "BR",
12499
+ "CA",
12500
+ "CL",
12501
+ "DK",
12502
+ "FI",
12503
+ "FR",
12504
+ "DE",
12505
+ "GR",
12506
+ "HK",
12507
+ "IN",
12508
+ "ID",
12509
+ "IT",
12510
+ "JP",
12511
+ "KR",
12512
+ "MY",
12513
+ "MX",
12514
+ "NL",
12515
+ "NZ",
12516
+ "NO",
12517
+ "CN",
12518
+ "PL",
12519
+ "PT",
12520
+ "PH",
12521
+ "RU",
12522
+ "SA",
12523
+ "ZA",
12524
+ "ES",
12525
+ "SE",
12526
+ "CH",
12527
+ "TW",
12528
+ "TR",
12529
+ "GB",
12530
+ "US",
12531
+ "ALL",
12532
+ "ar",
12533
+ "au",
12534
+ "at",
12535
+ "be",
12536
+ "br",
12537
+ "ca",
12538
+ "cl",
12539
+ "dk",
12540
+ "fi",
12541
+ "fr",
12542
+ "de",
12543
+ "gr",
12544
+ "hk",
12545
+ "in",
12546
+ "id",
12547
+ "it",
12548
+ "jp",
12549
+ "kr",
12550
+ "my",
12551
+ "mx",
12552
+ "nl",
12553
+ "nz",
12554
+ "no",
12555
+ "cn",
12556
+ "pl",
12557
+ "pt",
12558
+ "ph",
12559
+ "ru",
12560
+ "sa",
12561
+ "za",
12562
+ "es",
12563
+ "se",
12564
+ "ch",
12565
+ "tw",
12566
+ "tr",
12567
+ "gb",
12568
+ "us",
12569
+ "all"
12570
+ ],
12571
+ "default": "us"
12572
+ },
12573
+ "search_lang": {
12574
+ "type": "string",
12575
+ "description": "Language code for search (ISO 639-1, e.g., 'en', 'es', 'fr')",
12576
+ "default": "en"
12577
+ },
12578
+ "safesearch": {
12579
+ "type": "string",
12580
+ "description": "Safe search level",
12581
+ "enum": [
12582
+ "off",
12583
+ "moderate",
12584
+ "strict"
12585
+ ],
12586
+ "default": "moderate"
12587
+ }
12588
+ },
12589
+ "required": [
12590
+ "query"
12591
+ ]
12592
+ }
12593
+ }
12594
+ },
12595
+ "required": [
12596
+ "requests"
12597
+ ]
12598
+ }
12599
+ },
12600
+ {
12601
+ "app_id": "weather",
12602
+ "skill_id": "forecast",
12603
+ "app_namespace_ts": "weather",
12604
+ "skill_method_ts": "forecast",
12605
+ "app_namespace_py": "weather",
12606
+ "skill_method_py": "forecast",
12607
+ "description_key": "apps.weather.forecast.description",
12608
+ "description": "Get current and upcoming weather forecasts for a place, including daily weather, temperatures, rain likelihood, and hourly details stored in day embeds. Use this for weather questions, forecast requests, and trip/day planning involving weather.",
12609
+ "schema": {
12610
+ "type": "object",
12611
+ "properties": {
12612
+ "location": {
12613
+ "type": "string",
12614
+ "description": "Place name for the forecast, e.g. Berlin, Karlsruhe, Tokyo. Required unless latitude and longitude are provided."
12615
+ },
12616
+ "days": {
12617
+ "type": "integer",
12618
+ "description": "Number of forecast days to return. Defaults to 7. Maximum 14.",
12619
+ "minimum": 1,
12620
+ "maximum": 14,
12621
+ "default": 7
12622
+ },
12623
+ "latitude": {
12624
+ "type": "number",
12625
+ "description": "Optional latitude in decimal degrees. Use with longitude for exact coordinates."
12626
+ },
12627
+ "longitude": {
12628
+ "type": "number",
12629
+ "description": "Optional longitude in decimal degrees. Use with latitude for exact coordinates."
12630
+ },
12631
+ "timezone": {
12632
+ "type": "string",
12633
+ "description": "Optional IANA timezone. Defaults to provider/location timezone."
12634
+ },
12635
+ "units": {
12636
+ "type": "string",
12637
+ "description": "Unit system. Only metric is currently supported.",
12638
+ "enum": [
12639
+ "metric"
12640
+ ],
12641
+ "default": "metric"
12642
+ }
12643
+ },
12644
+ "required": [
12645
+ "location"
12646
+ ]
12647
+ }
12648
+ },
12649
+ {
12650
+ "app_id": "weather",
12651
+ "skill_id": "rain_radar",
12652
+ "app_namespace_ts": "weather",
12653
+ "skill_method_ts": "rainRadar",
12654
+ "app_namespace_py": "weather",
12655
+ "skill_method_py": "rain_radar",
12656
+ "description_key": "apps.weather.rain_radar.description",
12657
+ "description": 'Get nearby German rain radar with a timeline, including whether rain is visible now, whether rain is expected around the selected location in about 10 minutes, and compact frame-by-frame rain intensity metadata. Use this for rain radar, precipitation radar, and hyperlocal "will it rain here soon" questions in Germany.',
12658
+ "schema": {
12659
+ "type": "object",
12660
+ "properties": {
12661
+ "location": {
12662
+ "type": "string",
12663
+ "description": "German place name for the radar, e.g. Berlin, Hamburg, Munich. Required unless latitude and longitude are provided."
12664
+ },
12665
+ "latitude": {
12666
+ "type": "number",
12667
+ "description": "Optional latitude in decimal degrees. Use with longitude for exact coordinates. V1 supports Germany only."
12668
+ },
12669
+ "longitude": {
12670
+ "type": "number",
12671
+ "description": "Optional longitude in decimal degrees. Use with latitude for exact coordinates. V1 supports Germany only."
12672
+ },
12673
+ "radius_km": {
12674
+ "type": "integer",
12675
+ "description": "Radar radius around the location in kilometers. Defaults to 5 for a neighborhood/city-part view. Maximum 100.",
12676
+ "minimum": 1,
12677
+ "maximum": 100,
12678
+ "default": 5
12679
+ },
12680
+ "timezone": {
12681
+ "type": "string",
12682
+ "description": "Optional IANA timezone. Defaults to provider/location timezone."
12683
+ }
12684
+ },
12685
+ "required": [
12686
+ "location"
12687
+ ]
12688
+ }
12689
+ },
12690
+ {
12691
+ "app_id": "web",
12692
+ "skill_id": "search",
12693
+ "app_namespace_ts": "web",
12694
+ "skill_method_ts": "search",
12695
+ "app_namespace_py": "web",
12696
+ "skill_method_py": "search",
12697
+ "description_key": "app_skills.web.search.description",
12698
+ "description": "General web search for current information, prices, weather, facts, stocks, sports scores, etc. Use as a fallback when no specialized skill applies.",
12699
+ "schema": {
12700
+ "type": "object",
12701
+ "properties": {
12702
+ "requests": {
12703
+ "type": "array",
12704
+ "description": `REQUIRED: Array of search request objects for parallel processing (up to 5 requests).
12705
+ This parameter is MANDATORY - you MUST always provide a 'requests' array, even for a single search.
12706
+ Example for single search: {"requests": [{"query": "Python async"}]}
12707
+ Example for multiple searches: {"requests": [{"query": "Python async"}, {"query": "FastAPI best practices"}]}
12708
+ Each object must contain 'query' (search query string), and can include optional parameters (count, country, search_lang, safesearch).
12709
+ Note: The 'id' field is auto-generated if not provided - you don't need to include it.
12710
+ `,
12711
+ "items": {
12712
+ "type": "object",
12713
+ "properties": {
12714
+ "query": {
12715
+ "type": "string",
12716
+ "description": "Search query string"
12717
+ },
12718
+ "count": {
12719
+ "type": "integer",
12720
+ "description": "Number of results for this request (max 20)",
12721
+ "minimum": 1,
12722
+ "maximum": 20,
12723
+ "default": 6
12724
+ },
12725
+ "country": {
12726
+ "type": "string",
12727
+ "description": "Country code for localized results. Must be one of: AR, AU, AT, BE, BR, CA, CL, DK, FI, FR, DE, GR, HK, IN, ID, IT, JP, KR, MY, MX, NL, NZ, NO, CN, PL, PT, PH, RU, SA, ZA, ES, SE, CH, TW, TR, GB, US, or ALL (case-insensitive). Defaults to 'us' if invalid.",
12728
+ "enum": [
12729
+ "AR",
12730
+ "AU",
12731
+ "AT",
12732
+ "BE",
12733
+ "BR",
12734
+ "CA",
12735
+ "CL",
12736
+ "DK",
12737
+ "FI",
12738
+ "FR",
12739
+ "DE",
12740
+ "GR",
12741
+ "HK",
12742
+ "IN",
12743
+ "ID",
12744
+ "IT",
12745
+ "JP",
12746
+ "KR",
12747
+ "MY",
12748
+ "MX",
12749
+ "NL",
12750
+ "NZ",
12751
+ "NO",
12752
+ "CN",
12753
+ "PL",
12754
+ "PT",
12755
+ "PH",
12756
+ "RU",
12757
+ "SA",
12758
+ "ZA",
12759
+ "ES",
12760
+ "SE",
12761
+ "CH",
12762
+ "TW",
12763
+ "TR",
12764
+ "GB",
12765
+ "US",
12766
+ "ALL",
12767
+ "ar",
12768
+ "au",
12769
+ "at",
12770
+ "be",
12771
+ "br",
12772
+ "ca",
12773
+ "cl",
12774
+ "dk",
12775
+ "fi",
12776
+ "fr",
12777
+ "de",
12778
+ "gr",
12779
+ "hk",
12780
+ "in",
12781
+ "id",
12782
+ "it",
12783
+ "jp",
12784
+ "kr",
12785
+ "my",
12786
+ "mx",
12787
+ "nl",
12788
+ "nz",
12789
+ "no",
12790
+ "cn",
12791
+ "pl",
12792
+ "pt",
12793
+ "ph",
12794
+ "ru",
12795
+ "sa",
12796
+ "za",
12797
+ "es",
12798
+ "se",
12799
+ "ch",
12800
+ "tw",
12801
+ "tr",
12802
+ "gb",
12803
+ "us",
12804
+ "all"
12805
+ ],
12806
+ "default": "us"
12807
+ },
12808
+ "search_lang": {
12809
+ "type": "string",
12810
+ "description": "Language code for search (ISO 639-1, e.g., 'en', 'es', 'fr')",
12811
+ "default": "en"
12812
+ },
12813
+ "safesearch": {
12814
+ "type": "string",
12815
+ "description": "Safe search level",
12816
+ "enum": [
12817
+ "off",
12818
+ "moderate",
12819
+ "strict"
12820
+ ],
12821
+ "default": "moderate"
12822
+ },
12823
+ "filter_tabloids": {
12824
+ "type": "boolean",
12825
+ "description": "Filter out tabloid/boulevard media sources (e.g., BILD, Daily Mail, TMZ, The Sun) from results. Enabled by default for quality results. Set to false ONLY if the user explicitly asks for tabloid sources.",
12826
+ "default": true
12827
+ }
12828
+ },
12829
+ "required": [
12830
+ "query"
12831
+ ]
12832
+ }
12833
+ }
12834
+ },
12835
+ "required": [
12836
+ "requests"
12837
+ ]
12838
+ }
12839
+ },
12840
+ {
12841
+ "app_id": "web",
12842
+ "skill_id": "read",
12843
+ "app_namespace_ts": "web",
12844
+ "skill_method_ts": "read",
12845
+ "app_namespace_py": "web",
12846
+ "skill_method_py": "read",
12847
+ "description_key": "web.read.description",
12848
+ "description": "Read and extract content from a specific URL or webpage the user provided.",
12849
+ "schema": {
12850
+ "type": "object",
12851
+ "properties": {
12852
+ "requests": {
12853
+ "type": "array",
12854
+ "description": `REQUIRED: Array of read request objects for parallel processing (up to 5 requests).
12855
+ This parameter is MANDATORY - you MUST always provide a 'requests' array, even for a single URL.
12856
+ Example for single URL: {"requests": [{"id": 1, "url": "https://example.com/article"}]}
12857
+ Example for multiple URLs: {"requests": [{"id": 1, "url": "https://example.com/article1"}, {"id": 2, "url": "https://example.com/article2"}]}
12858
+ Each object must contain 'id' (unique identifier) and 'url' (webpage URL), and can include optional parameters (formats, only_main_content, max_age, timeout).
12859
+ `,
12860
+ "items": {
12861
+ "type": "object",
12862
+ "properties": {
12863
+ "url": {
12864
+ "type": "string",
12865
+ "description": "URL of the webpage to read/scrape"
12866
+ },
12867
+ "formats": {
12868
+ "type": "array",
12869
+ "description": "List of output formats to include (e.g., 'markdown', 'html', 'summary')",
12870
+ "items": {
12871
+ "type": "string"
12872
+ },
12873
+ "default": [
12874
+ "markdown"
12875
+ ]
12876
+ },
12877
+ "only_main_content": {
12878
+ "type": "boolean",
12879
+ "description": "Whether to return only main content (excluding headers, navs, footers, etc.)",
12880
+ "default": true
12881
+ },
12882
+ "max_age": {
12883
+ "type": "integer",
12884
+ "description": "Cache age in milliseconds (default: 172800000 = 2 days). Returns cached version if available."
12885
+ },
12886
+ "timeout": {
12887
+ "type": "integer",
12888
+ "description": "Timeout in milliseconds for the request"
12889
+ }
12890
+ },
12891
+ "required": [
12892
+ "url"
12893
+ ]
12894
+ }
12895
+ }
12896
+ },
12897
+ "required": [
12898
+ "requests"
12899
+ ]
12900
+ }
12901
+ },
12902
+ {
12903
+ "app_id": "workflows",
12904
+ "skill_id": "create-or-modify",
12905
+ "app_namespace_ts": "workflows",
12906
+ "skill_method_ts": "createOrModify",
12907
+ "app_namespace_py": "workflows",
12908
+ "skill_method_py": "create_or_modify",
12909
+ "description_key": "workflows.skills.create_or_modify.description",
12910
+ "description": "Create or modify exactly one workflow from chat. Do not batch multiple workflows into one skill call.",
12911
+ "schema": {
12912
+ "type": "object",
12913
+ "properties": {
12914
+ "workflow_id": {
12915
+ "type": "string",
12916
+ "description": "Existing workflow ID when modifying a workflow."
12917
+ },
12918
+ "title": {
12919
+ "type": "string",
12920
+ "description": "Short user-facing workflow title."
12921
+ },
12922
+ "graph": {
12923
+ "type": "object",
12924
+ "description": "Valid WorkflowGraph definition."
12925
+ }
12926
+ },
12927
+ "required": [
12928
+ "title"
12929
+ ]
12930
+ }
12931
+ },
12932
+ {
12933
+ "app_id": "workflows",
12934
+ "skill_id": "search",
12935
+ "app_namespace_ts": "workflows",
12936
+ "skill_method_ts": "search",
12937
+ "app_namespace_py": "workflows",
12938
+ "skill_method_py": "search",
12939
+ "description_key": "workflows.skills.search.description",
12940
+ "description": "Search the user's existing persisted workflows before proposing a new automation. Include temporary workflows only when the user explicitly asks about recent chat-created workflows.",
12941
+ "schema": {
12942
+ "type": "object",
12943
+ "properties": {
12944
+ "query": {
12945
+ "type": "string",
12946
+ "description": "Workflow title or intent text to search for."
12947
+ },
12948
+ "include_temporary": {
12949
+ "type": "boolean",
12950
+ "description": "Include temporary chat-created workflows in the search results."
12951
+ }
12952
+ }
12953
+ }
12954
+ }
12955
+ ];
12956
+ var AiAppSkills = class {
12957
+ runSkill;
12958
+ constructor(runSkill) {
12959
+ this.runSkill = runSkill;
12960
+ }
12961
+ /**
12962
+ * Run this OpenMates app skill.
12963
+ * Description key: ai.ask.description
12964
+ * Skill: ai/ask
12965
+ */
12966
+ async ask(input) {
12967
+ return this.runSkill("ai", "ask", input);
12968
+ }
12969
+ };
12970
+ var BooksAppSkills = class {
12971
+ runSkill;
12972
+ constructor(runSkill) {
12973
+ this.runSkill = runSkill;
12974
+ }
12975
+ /**
12976
+ * Run this OpenMates app skill.
12977
+ * Description key: books.translate.description
12978
+ * Skill: books/translate
12979
+ */
12980
+ async translate(input) {
12981
+ return this.runSkill("books", "translate", input);
12982
+ }
12983
+ };
12984
+ var CodeAppSkills = class {
12985
+ runSkill;
12986
+ constructor(runSkill) {
12987
+ this.runSkill = runSkill;
12988
+ }
12989
+ /**
12990
+ * Run this OpenMates app skill.
12991
+ * Description key: code.add_issue.description
12992
+ * Skill: code/add_issue
12993
+ */
12994
+ async addIssue(input) {
12995
+ return this.runSkill("code", "add_issue", input);
12996
+ }
12997
+ /**
12998
+ * Run this OpenMates app skill.
12999
+ * Description key: code.clean_repo.description
13000
+ * Skill: code/clean_repo
13001
+ */
13002
+ async cleanRepo(input) {
13003
+ return this.runSkill("code", "clean_repo", input);
13004
+ }
13005
+ /**
13006
+ * Get latest documentation for programming libraries, frameworks, APIs, SDKs. Use for ANY programming-related query about a specific library or framework.
13007
+ * Description key: code.get_docs.description
13008
+ * Skill: code/get_docs
13009
+ */
13010
+ async getDocs(input) {
13011
+ return this.runSkill("code", "get_docs", input);
13012
+ }
13013
+ /**
13014
+ * Run this OpenMates app skill.
13015
+ * Description key: code.get_issues.description
13016
+ * Skill: code/get_issues
13017
+ */
13018
+ async getIssues(input) {
13019
+ return this.runSkill("code", "get_issues", input);
13020
+ }
13021
+ /**
13022
+ * Run this OpenMates app skill.
13023
+ * Description key: code.get_project_overview.description
13024
+ * Skill: code/get_project_overview
13025
+ */
13026
+ async getProjectOverview(input) {
13027
+ return this.runSkill("code", "get_project_overview", input);
13028
+ }
13029
+ /**
13030
+ * Run this OpenMates app skill.
13031
+ * Description key: code.remove_secrets.description
13032
+ * Skill: code/remove_secrets
13033
+ */
13034
+ async removeSecrets(input) {
13035
+ return this.runSkill("code", "remove_secrets", input);
13036
+ }
13037
+ /**
13038
+ * Search GitHub repositories. Use this instead of web.search whenever the user asks to find GitHub repos, repositories, open-source libraries, starred repos, or repo examples by topic, language, framework, or project need. Returns licensed repository embeds. Costs 10 credits per search.
13039
+ * Description key: code.search_repos.description
13040
+ * Skill: code/search_repos
13041
+ */
13042
+ async searchRepos(input) {
13043
+ return this.runSkill("code", "search_repos", input);
13044
+ }
13045
+ };
13046
+ var ElectronicsAppSkills = class {
13047
+ runSkill;
13048
+ constructor(runSkill) {
13049
+ this.runSkill = runSkill;
13050
+ }
13051
+ /**
13052
+ * Use this skill when the user asks to find electronic components, especially power converters or voltage regulators matching input voltage, output voltage, output current, efficiency, BOM cost, footprint, or topology requirements. Currently supports category power_converters via Texas Instruments WEBENCH Power Designer.
13053
+ * Description key: electronics.search_components.description
13054
+ * Skill: electronics/search_components
13055
+ */
13056
+ async searchComponents(input) {
13057
+ return this.runSkill("electronics", "search_components", input);
13058
+ }
13059
+ };
13060
+ var EventsAppSkills = class {
13061
+ runSkill;
13062
+ constructor(runSkill) {
13063
+ this.runSkill = runSkill;
13064
+ }
13065
+ /**
13066
+ * Search for local or online events, meetups, hackathons, conferences, workshops, networking events, parties, concerts, or any community gathering. Use ONLY this skill for event searches — do NOT additionally call web.search or any other search skill for the same query. Sources: Meetup, Luma, Eventbrite, Google Events, Resident Advisor (electronic music/clubs), Siegessäule (Berlin LGBTQ+ events), Berlin Philharmonic (classical concerts in Berlin), and official event schedules for GPN24, 39C3, 38C3
13067
+ * Description key: events.search.description
13068
+ * Skill: events/search
13069
+ */
13070
+ async search(input) {
13071
+ return this.runSkill("events", "search", input);
13072
+ }
13073
+ };
13074
+ var FitnessAppSkills = class {
13075
+ runSkill;
13076
+ constructor(runSkill) {
13077
+ this.runSkill = runSkill;
13078
+ }
13079
+ /**
13080
+ * Search available Urban Sports Club public fitness classes. Use this when the user asks for dated fitness classes, course availability, free spots, on-site classes, online classes, or plan-filtered Urban Sports classes. Omit plan unless the user explicitly asks for Essential, Classic, Premium, or Max.
13081
+ * Description key: fitness.search_classes.description
13082
+ * Skill: fitness/search_classes
13083
+ */
13084
+ async searchClasses(input) {
13085
+ return this.runSkill("fitness", "search_classes", input);
13086
+ }
13087
+ /**
13088
+ * Search Urban Sports Club public fitness locations. Use this when the user asks for gyms, studios, pools, or Urban Sports locations near a city, address, or radius. Do not use it for class availability; use fitness.search_classes for dated class searches.
13089
+ * Description key: fitness.search_locations.description
13090
+ * Skill: fitness/search_locations
13091
+ */
13092
+ async searchLocations(input) {
13093
+ return this.runSkill("fitness", "search_locations", input);
13094
+ }
13095
+ };
13096
+ var HealthAppSkills = class {
13097
+ runSkill;
13098
+ constructor(runSkill) {
13099
+ this.runSkill = runSkill;
13100
+ }
13101
+ /**
13102
+ * Run this OpenMates app skill.
13103
+ * Description key: health.create_report.description
13104
+ * Skill: health/create_report
13105
+ */
13106
+ async createReport(input) {
13107
+ return this.runSkill("health", "create_report", input);
13108
+ }
13109
+ /**
13110
+ * Search available medical appointments at German doctors/specialists by speciality and city. Covers any medical booking — general practitioners, specialists (e.g. dentist, dermatologist, gynecologist), scans and imaging (e.g. MRT/MRI, CT, Röntgen, Ultraschall), vaccinations, check-ups, blood tests, and other examinations. Note: "Termin" in a medical context means appointment, not event — route here instead of events-search. Sources: Doctolib, Jameda (Germany only).
13111
+ * Description key: app_skills.health.search_appointments.description
13112
+ * Skill: health/search_appointments
13113
+ */
13114
+ async searchAppointments(input) {
13115
+ return this.runSkill("health", "search_appointments", input);
13116
+ }
13117
+ };
13118
+ var HomeAppSkills = class {
13119
+ runSkill;
13120
+ constructor(runSkill) {
13121
+ this.runSkill = runSkill;
13122
+ }
13123
+ /**
13124
+ * Search for apartments, houses, and WG rooms in German cities. Searches ImmoScout24, Kleinanzeigen, and WG-Gesucht simultaneously. Returns listings with prices, sizes, rooms, addresses, and direct links. Costs 10 credits per search. Use when user asks about finding housing in Germany.
13125
+ * Description key: app_skills.home.search.description
13126
+ * Skill: home/search
13127
+ */
13128
+ async search(input) {
13129
+ return this.runSkill("home", "search", input);
13130
+ }
13131
+ };
13132
+ var ImagesAppSkills = class {
13133
+ runSkill;
13134
+ constructor(runSkill) {
13135
+ this.runSkill = runSkill;
13136
+ }
13137
+ /**
13138
+ * Generate high-quality images from text prompts and/or reference images (image-to-image editing). Also use for: mockups, design concepts, visual mockup creation, logo mockups, product mockups, illustration requests, visual design, concept art, posters, banners, thumbnails, or any request that implies creating a visual output. Use output_filetype="svg" for logos, icons, illustrations, and any other vector graphics that need to be scalable or editable. When the user provides uploaded images as refe
13139
+ * Description key: images.generate.description
13140
+ * Skill: images/generate
13141
+ */
13142
+ async generate(input) {
13143
+ return this.runSkill("images", "generate", input);
13144
+ }
13145
+ /**
13146
+ * Quickly generate a draft/preview image from a text prompt and/or reference images (image-to-image). Also use for: quick mockups, rough design concepts, draft illustrations, sketches, quick visual previews, or any request for a fast/rough image. When the user provides uploaded images as references (embed_refs), pass them via reference_images. Do not use this for scam, spam, fake-document, fake-endorsement, public-figure impersonation, or watermark/detection-evasion requests.
13147
+ * Description key: images.generate_draft.description
13148
+ * Skill: images/generate_draft
13149
+ */
13150
+ async generateDraft(input) {
13151
+ return this.runSkill("images", "generate_draft", input);
13152
+ }
13153
+ };
13154
+ var MailAppSkills = class {
13155
+ runSkill;
13156
+ constructor(runSkill) {
13157
+ this.runSkill = runSkill;
13158
+ }
13159
+ /**
13160
+ * Run this OpenMates app skill.
13161
+ * Description key: app_skills.mail.search.description
13162
+ * Skill: mail/search
13163
+ */
13164
+ async search(input) {
13165
+ return this.runSkill("mail", "search", input);
13166
+ }
13167
+ };
13168
+ var MapsAppSkills = class {
13169
+ runSkill;
13170
+ constructor(runSkill) {
13171
+ this.runSkill = runSkill;
13172
+ }
13173
+ /**
13174
+ * Search for places, businesses, restaurants, directions, locations.
13175
+ * Description key: maps.search.description
13176
+ * Skill: maps/search
13177
+ */
13178
+ async search(input) {
13179
+ return this.runSkill("maps", "search", input);
13180
+ }
13181
+ };
13182
+ var MathAppSkills = class {
13183
+ runSkill;
13184
+ constructor(runSkill) {
13185
+ this.runSkill = runSkill;
13186
+ }
13187
+ /**
13188
+ * MANDATORY: Use this skill for ALL mathematical calculations without exception. This includes simple arithmetic such as addition, subtraction, multiplication (written as *, x, or ×), division, and parenthesised expressions like (4x22x7)/2 or (100+50)*3/2. Also use for algebra, trigonometry, calculus, unit conversions, symbolic simplification, equation solving, derivatives, and integrals. NEVER attempt to compute a numeric result yourself — always call this skill so results are guaranteed to be ex
13189
+ * Description key: math.calculate.description
13190
+ * Skill: math/calculate
13191
+ */
13192
+ async calculate(input) {
13193
+ return this.runSkill("math", "calculate", input);
13194
+ }
13195
+ };
13196
+ var Models3dAppSkills = class {
13197
+ runSkill;
13198
+ constructor(runSkill) {
13199
+ this.runSkill = runSkill;
13200
+ }
13201
+ /**
13202
+ * Search public 3D model catalogs for existing models. Use this when the user wants to find, browse, compare, or link to existing 3D-printable or downloadable 3D models. Do not use it to generate new models.
13203
+ * Description key: app_skills.models3d.search.description
13204
+ * Skill: models3d/search
13205
+ */
13206
+ async search(input) {
13207
+ return this.runSkill("models3d", "search", input);
13208
+ }
13209
+ };
13210
+ var MusicAppSkills = class {
13211
+ runSkill;
13212
+ constructor(runSkill) {
13213
+ this.runSkill = runSkill;
13214
+ }
13215
+ /**
13216
+ * Generate music from a text prompt, including full songs, instrumental tracks, background music, loops, jingles, lyric-based songs, and soundtrack cues. Use this when the user asks to create music or background music. Do not use this to imitate the voice, vocals, cadence, or persona of a real public figure, living artist, famous educator, or recognizable person. Use original voices and styles only, and reject scams, spam, or detection evasion.
13217
+ * Description key: app_skills.music.generate.description
13218
+ * Skill: music/generate
13219
+ */
13220
+ async generate(input) {
13221
+ return this.runSkill("music", "generate", input);
13222
+ }
13223
+ };
13224
+ var NewsAppSkills = class {
13225
+ runSkill;
13226
+ constructor(runSkill) {
13227
+ this.runSkill = runSkill;
13228
+ }
13229
+ /**
13230
+ * Search for news articles, current events, headlines, announcements.
13231
+ * Description key: news.search.description
13232
+ * Skill: news/search
13233
+ */
13234
+ async search(input) {
13235
+ return this.runSkill("news", "search", input);
13236
+ }
13237
+ };
13238
+ var NutritionAppSkills = class {
13239
+ runSkill;
13240
+ constructor(runSkill) {
13241
+ this.runSkill = runSkill;
13242
+ }
13243
+ /**
13244
+ * Search Edamam for recipes by natural-language query and nutrition filters. Returns recipe details with ingredients, step-by-step instructions, images, source links, and nutrition metadata. Recipes without instructions are filtered out. Best for: recipe recommendations, meal planning, dietary filtering, and cooking guidance.
13245
+ * Description key: app_skills.nutrition.search_recipes.description
13246
+ * Skill: nutrition/search_recipes
13247
+ */
13248
+ async searchRecipes(input) {
13249
+ return this.runSkill("nutrition", "search_recipes", input);
13250
+ }
13251
+ };
13252
+ var OpenmatesAppSkills = class {
13253
+ runSkill;
13254
+ constructor(runSkill) {
13255
+ this.runSkill = runSkill;
13256
+ }
13257
+ /**
13258
+ * Use when the user shares an openmates.org/docs URL, or asks to read a specific OpenMates documentation page. Automatically triggered when an openmates docs URL is detected in the conversation.
13259
+ * Description key: openmates_app.get_docs.description
13260
+ * Skill: openmates/get-docs
13261
+ */
13262
+ async getDocs(input) {
13263
+ return this.runSkill("openmates", "get-docs", input);
13264
+ }
13265
+ /**
13266
+ * Use when the user asks about OpenMates features, setup, architecture, or documentation. Searches across all OpenMates documentation to find relevant pages.
13267
+ * Description key: openmates_app.search_docs.description
13268
+ * Skill: openmates/search-docs
13269
+ */
13270
+ async searchDocs(input) {
13271
+ return this.runSkill("openmates", "search-docs", input);
13272
+ }
13273
+ /**
13274
+ * Use when the user has explicitly agreed to anonymously share a summary of their intended use cases with the OpenMates team to help improve the product. NEVER call this without clear user consent.
13275
+ * Description key: openmates_app.share_usecase.description
13276
+ * Skill: openmates/share-usecase
13277
+ */
13278
+ async shareUsecase(input) {
13279
+ return this.runSkill("openmates", "share-usecase", input);
13280
+ }
13281
+ };
13282
+ var PdfAppSkills = class {
13283
+ runSkill;
13284
+ constructor(runSkill) {
13285
+ this.runSkill = runSkill;
13286
+ }
13287
+ /**
13288
+ * Load and read the raw text content (markdown) of specific pages from an uploaded PDF document. Use when the user asks what a PDF says, wants you to summarise sections, or requests information that is likely textual (paragraphs, tables, headings). The embed TOON content includes a TOC and per-page token estimates — use them to select the most relevant pages. Limits output to 50 000 tokens; call again for remaining pages if needed. Pass the exact embed_ref (original filename) from the toon block —
13289
+ * Description key: pdf.read.description
13290
+ * Skill: pdf/read
13291
+ */
13292
+ async read(input) {
13293
+ return this.runSkill("pdf", "read", input);
13294
+ }
13295
+ /**
13296
+ * Search for specific text, keywords, or phrases across all pages of an uploaded PDF. Returns matching text blocks with surrounding context and page numbers. Use when the user asks to find where something is mentioned in the document, or when a targeted keyword search is faster than reading entire sections. No LLM call required — pure text search over the OCR data. Pass the exact embed_ref (original filename) from the toon block as file_path.
13297
+ * Description key: pdf.search.description
13298
+ * Skill: pdf/search
13299
+ */
13300
+ async search(input) {
13301
+ return this.runSkill("pdf", "search", input);
13302
+ }
13303
+ /**
13304
+ * View one or more page screenshots from an uploaded PDF and return them as multimodal image blocks so the main inference model can see the pages directly. Use when the user asks about the visual layout, diagrams, charts, figures, or images on specific pages. Also useful when text OCR may have been imperfect (e.g. complex tables, mathematical notation, handwriting). Up to 5 pages can be viewed per call. Pass the exact embed_ref (original filename) from the toon block as file_path — the server reso
13305
+ * Description key: pdf.view.skill_description
13306
+ * Skill: pdf/view
13307
+ */
13308
+ async view(input) {
13309
+ return this.runSkill("pdf", "view", input);
13310
+ }
13311
+ };
13312
+ var ReminderAppSkills = class {
13313
+ runSkill;
13314
+ constructor(runSkill) {
13315
+ this.runSkill = runSkill;
13316
+ }
13317
+ /**
13318
+ * Cancel or delete an existing reminder.
13319
+ * Description key: reminder.cancel_reminder.description
13320
+ * Skill: reminder/cancel-reminder
13321
+ */
13322
+ async cancelReminder(input) {
13323
+ return this.runSkill("reminder", "cancel-reminder", input);
13324
+ }
13325
+ /**
13326
+ * Show the user's existing scheduled reminders.
13327
+ * Description key: reminder.list_reminders.description
13328
+ * Skill: reminder/list-reminders
13329
+ */
13330
+ async listReminders(input) {
13331
+ return this.runSkill("reminder", "list-reminders", input);
13332
+ }
13333
+ /**
13334
+ * Schedule, create, or set up reminders for the user. Handles one-time and recurring reminders (e.g., "every morning", "daily at 9am", "weekly", "monthly"). Use when user wants to be reminded, notified, or alerted about something at a specific time or on a recurring schedule. Also use for automating tasks like "get news every day" or "summarize updates weekly".
13335
+ * Description key: reminder.set_reminder.description
13336
+ * Skill: reminder/set-reminder
13337
+ */
13338
+ async setReminder(input) {
13339
+ return this.runSkill("reminder", "set-reminder", input);
13340
+ }
13341
+ };
13342
+ var ShoppingAppSkills = class {
13343
+ runSkill;
13344
+ constructor(runSkill) {
13345
+ this.runSkill = runSkill;
13346
+ }
13347
+ /**
13348
+ * Search products on REWE, Amazon, or Stoffe.de with real-time prices. Use category to route groceries, marketplace products, fabrics, sewing supplies, and patterns to compatible providers. Invalid provider/category combinations are rejected.
13349
+ * Description key: app_skills.shopping.search_products.description
13350
+ * Skill: shopping/search_products
13351
+ */
13352
+ async searchProducts(input) {
13353
+ return this.runSkill("shopping", "search_products", input);
13354
+ }
13355
+ };
13356
+ var SocialMediaAppSkills = class {
13357
+ runSkill;
13358
+ constructor(runSkill) {
13359
+ this.runSkill = runSkill;
13360
+ }
13361
+ /**
13362
+ * Fetch recent social media posts from one or more specific platform pages or profiles. Supports Reddit subreddits, Bluesky profile feeds, and Mastodon public profiles. Use for profile monitoring, community research, and finding conversations to review manually. Costs 10 credits per request.
13363
+ * Description key: app_skills.social_media.get_posts.description
13364
+ * Skill: social_media/get-posts
13365
+ */
13366
+ async getPosts(input) {
13367
+ return this.runSkill("social_media", "get-posts", input);
13368
+ }
13369
+ /**
13370
+ * Search supported social platforms for recent public posts around a topic. Use this for topic monitoring and broad discovery across pages/profiles, not for monitoring a known profile; use Get posts for profile/page posts. Omit platform to search every supported social platform. Costs 10 credits per request.
13371
+ * Description key: app_skills.social_media.search.description
13372
+ * Skill: social_media/search
13373
+ */
13374
+ async search(input) {
13375
+ return this.runSkill("social_media", "search", input);
13376
+ }
13377
+ };
13378
+ var TasksAppSkills = class {
13379
+ runSkill;
13380
+ constructor(runSkill) {
13381
+ this.runSkill = runSkill;
13382
+ }
13383
+ /**
13384
+ * Create one or more user-visible tasks. Use this for planning, task capture, or breaking a request into trackable work. Default unclear assignees to the user.
13385
+ * Description key: tasks.skills.create.description
13386
+ * Skill: tasks/create
13387
+ */
13388
+ async create(input) {
13389
+ return this.runSkill("tasks", "create", input);
13390
+ }
13391
+ /**
13392
+ * Search the user's encrypted tasks through a connected capable client. Do not use server-visible metadata as a private task-content search fallback.
13393
+ * Description key: tasks.skills.search.description
13394
+ * Skill: tasks/search
13395
+ */
13396
+ async search(input) {
13397
+ return this.runSkill("tasks", "search", input);
13398
+ }
13399
+ };
13400
+ var TravelAppSkills = class {
13401
+ runSkill;
13402
+ constructor(runSkill) {
13403
+ this.runSkill = runSkill;
13404
+ }
13405
+ /**
13406
+ * Fetch the real GPS flight track and actual departure/landing times for a specific completed/past flight. Use when the user asks to see how a flight actually went, the real flight path on a map, or actual timing and runway info. Requires the IATA flight number (e.g. 'LH2472') and the departure date. Costs 7 credits per lookup.
13407
+ * Description key: app_skills.travel.get_flight.description
13408
+ * Skill: travel/get_flight
13409
+ */
13410
+ async getFlight(input) {
13411
+ return this.runSkill("travel", "get_flight", input);
13412
+ }
13413
+ /**
13414
+ * Search for flight or train connections for a particular date with details (airlines/operators, times, stops, durations, prices). Use when user asks about flights, train connections, or travel between cities on a specific date. Set transport_methods to ["airplane"] for flights or ["train"] for trains. If the user names a provider, set providers to one or more of: google_flights, deutsche_bahn, flix. If no provider is specified, all providers for the selected transport method are searched. Add cou
13415
+ * Description key: app_skills.travel.search_connections.description
13416
+ * Skill: travel/search_connections
13417
+ */
13418
+ async searchConnections(input) {
13419
+ return this.runSkill("travel", "search_connections", input);
13420
+ }
13421
+ /**
13422
+ * Run this OpenMates app skill.
13423
+ * Description key: app_skills.travel.search_stays.description
13424
+ * Skill: travel/search_stays
13425
+ */
13426
+ async searchStays(input) {
13427
+ return this.runSkill("travel", "search_stays", input);
13428
+ }
13429
+ };
13430
+ var VideosAppSkills = class {
13431
+ runSkill;
13432
+ constructor(runSkill) {
13433
+ this.runSkill = runSkill;
13434
+ }
13435
+ /**
13436
+ * Create deterministic code-backed videos with Remotion. Use this for text slides, product announcements, diagrams, charts, UI-like motion graphics, or branded videos where exact text and layout matter. The assistant must write an explicit ```remotion:Name.tsx fence; do not use this for photorealistic footage or generic TSX components.
13437
+ * Description key: app_skills.videos.create.description
13438
+ * Skill: videos/create
13439
+ */
13440
+ async create(input) {
13441
+ return this.runSkill("videos", "create", input);
13442
+ }
13443
+ /**
13444
+ * Generate short photorealistic or generative footage from text prompts using Google Veo. Use this when the user asks for cinematic footage, realistic scenes, camera movement, stylized animation, or non-deterministic video generation. Do not use this for exact text slides, product announcements, diagrams, charts, UI-like motion graphics, or branded videos where exact text and layout matter; those requests should use videos.create with an explicit ```remotion:Name.tsx fence instead. Do not use this
13445
+ * Description key: app_skills.videos.generate.description
13446
+ * Skill: videos/generate
13447
+ */
13448
+ async generate(input) {
13449
+ return this.runSkill("videos", "generate", input);
13450
+ }
13451
+ /**
13452
+ * Get the transcript/content of a specific YouTube video URL.
13453
+ * Description key: videos.get_transcript.description
13454
+ * Skill: videos/get_transcript
13455
+ */
13456
+ async getTranscript(input) {
13457
+ return this.runSkill("videos", "get_transcript", input);
13458
+ }
13459
+ /**
13460
+ * Search for videos, documentaries, tutorials, clips on the web.
13461
+ * Description key: videos.search.description
13462
+ * Skill: videos/search
13463
+ */
13464
+ async search(input) {
13465
+ return this.runSkill("videos", "search", input);
13466
+ }
13467
+ };
13468
+ var WeatherAppSkills = class {
13469
+ runSkill;
13470
+ constructor(runSkill) {
13471
+ this.runSkill = runSkill;
13472
+ }
13473
+ /**
13474
+ * Get current and upcoming weather forecasts for a place, including daily weather, temperatures, rain likelihood, and hourly details stored in day embeds. Use this for weather questions, forecast requests, and trip/day planning involving weather.
13475
+ * Description key: apps.weather.forecast.description
13476
+ * Skill: weather/forecast
13477
+ */
13478
+ async forecast(input) {
13479
+ return this.runSkill("weather", "forecast", input);
13480
+ }
13481
+ /**
13482
+ * Get nearby German rain radar with a timeline, including whether rain is visible now, whether rain is expected around the selected location in about 10 minutes, and compact frame-by-frame rain intensity metadata. Use this for rain radar, precipitation radar, and hyperlocal "will it rain here soon" questions in Germany.
13483
+ * Description key: apps.weather.rain_radar.description
13484
+ * Skill: weather/rain_radar
13485
+ */
13486
+ async rainRadar(input) {
13487
+ return this.runSkill("weather", "rain_radar", input);
13488
+ }
13489
+ };
13490
+ var WebAppSkills = class {
13491
+ runSkill;
13492
+ constructor(runSkill) {
13493
+ this.runSkill = runSkill;
13494
+ }
13495
+ /**
13496
+ * Read and extract content from a specific URL or webpage the user provided.
13497
+ * Description key: web.read.description
13498
+ * Skill: web/read
13499
+ */
13500
+ async read(input) {
13501
+ return this.runSkill("web", "read", input);
13502
+ }
13503
+ /**
13504
+ * General web search for current information, prices, weather, facts, stocks, sports scores, etc. Use as a fallback when no specialized skill applies.
13505
+ * Description key: app_skills.web.search.description
13506
+ * Skill: web/search
13507
+ */
13508
+ async search(input) {
13509
+ return this.runSkill("web", "search", input);
13510
+ }
13511
+ };
13512
+ var WorkflowsAppSkills = class {
13513
+ runSkill;
13514
+ constructor(runSkill) {
13515
+ this.runSkill = runSkill;
13516
+ }
13517
+ /**
13518
+ * Create or modify exactly one workflow from chat. Do not batch multiple workflows into one skill call.
13519
+ * Description key: workflows.skills.create_or_modify.description
13520
+ * Skill: workflows/create-or-modify
13521
+ */
13522
+ async createOrModify(input) {
13523
+ return this.runSkill("workflows", "create-or-modify", input);
13524
+ }
13525
+ /**
13526
+ * Search the user's existing persisted workflows before proposing a new automation. Include temporary workflows only when the user explicitly asks about recent chat-created workflows.
13527
+ * Description key: workflows.skills.search.description
13528
+ * Skill: workflows/search
13529
+ */
13530
+ async search(input) {
13531
+ return this.runSkill("workflows", "search", input);
13532
+ }
13533
+ };
13534
+ var GeneratedAppSkills = class {
13535
+ constructor(runSkill) {
13536
+ this.ai = new AiAppSkills(runSkill);
13537
+ this.books = new BooksAppSkills(runSkill);
13538
+ this.code = new CodeAppSkills(runSkill);
13539
+ this.electronics = new ElectronicsAppSkills(runSkill);
13540
+ this.events = new EventsAppSkills(runSkill);
13541
+ this.fitness = new FitnessAppSkills(runSkill);
13542
+ this.health = new HealthAppSkills(runSkill);
13543
+ this.home = new HomeAppSkills(runSkill);
13544
+ this.images = new ImagesAppSkills(runSkill);
13545
+ this.mail = new MailAppSkills(runSkill);
13546
+ this.maps = new MapsAppSkills(runSkill);
13547
+ this.math = new MathAppSkills(runSkill);
13548
+ this.models3d = new Models3dAppSkills(runSkill);
13549
+ this.music = new MusicAppSkills(runSkill);
13550
+ this.news = new NewsAppSkills(runSkill);
13551
+ this.nutrition = new NutritionAppSkills(runSkill);
13552
+ this.openmates = new OpenmatesAppSkills(runSkill);
13553
+ this.pdf = new PdfAppSkills(runSkill);
13554
+ this.reminder = new ReminderAppSkills(runSkill);
13555
+ this.shopping = new ShoppingAppSkills(runSkill);
13556
+ this.socialMedia = new SocialMediaAppSkills(runSkill);
13557
+ this.tasks = new TasksAppSkills(runSkill);
13558
+ this.travel = new TravelAppSkills(runSkill);
13559
+ this.videos = new VideosAppSkills(runSkill);
13560
+ this.weather = new WeatherAppSkills(runSkill);
13561
+ this.web = new WebAppSkills(runSkill);
13562
+ this.workflows = new WorkflowsAppSkills(runSkill);
13563
+ }
13564
+ ai;
13565
+ books;
13566
+ code;
13567
+ electronics;
13568
+ events;
13569
+ fitness;
13570
+ health;
13571
+ home;
13572
+ images;
13573
+ mail;
13574
+ maps;
13575
+ math;
13576
+ models3d;
13577
+ music;
13578
+ news;
13579
+ nutrition;
13580
+ openmates;
13581
+ pdf;
13582
+ reminder;
13583
+ shopping;
13584
+ socialMedia;
13585
+ tasks;
13586
+ travel;
13587
+ videos;
13588
+ weather;
13589
+ web;
13590
+ workflows;
13591
+ };
13592
+
9686
13593
  // ../secret-scanner/src/registry.ts
9687
13594
  import { createRequire as createRequire2 } from "module";
9688
13595
 
@@ -53742,6 +57649,281 @@ function printWorkflowCapabilityHelp(capability) {
53742
57649
  console.log(JSON.stringify(workflow.test_example_input, null, 2));
53743
57650
  }
53744
57651
  }
57652
+ var GENERATED_APP_SKILL_COMMANDS = APP_SKILL_METADATA;
57653
+ var APP_SKILL_COMMAND_EXAMPLES = {
57654
+ "code/get_docs": [
57655
+ 'openmates apps code get_docs --library React --question "How do I use useState?" --json'
57656
+ ],
57657
+ "code/search_repos": [
57658
+ 'openmates apps code search_repos "svelte markdown editor" --count 3 --json'
57659
+ ],
57660
+ "electronics/search_components": [
57661
+ "openmates apps electronics search_components --category power_converters --input-voltage-min 12 --input-voltage-max 12 --output-voltage 3.3 --output-current-max 3 --max-results 3 --json"
57662
+ ],
57663
+ "events/search": [
57664
+ 'openmates apps events search "technology meetup" --location Berlin --provider auto --json'
57665
+ ],
57666
+ "fitness/search_classes": [
57667
+ 'openmates apps fitness search_classes Yoga --address "Sorauer Str. 12, Berlin" --radius-km 3 --attendance-mode onsite --days 7 --limit 5 --json'
57668
+ ],
57669
+ "fitness/search_locations": [
57670
+ 'openmates apps fitness search_locations HIIT --address "Sorauer Str. 12, Berlin" --radius-km 2 --limit 5 --json'
57671
+ ],
57672
+ "health/search_appointments": [
57673
+ "openmates apps health search_appointments --speciality zahnarzt --city Berlin --json"
57674
+ ],
57675
+ "home/search": [
57676
+ "openmates apps home search Berlin --listing-type rent --json"
57677
+ ],
57678
+ "images/search": [
57679
+ 'openmates apps images search "sunset over ocean" --json'
57680
+ ],
57681
+ "maps/search": [
57682
+ 'openmates apps maps search "cafes in Berlin Mitte" --json'
57683
+ ],
57684
+ "math/calculate": [
57685
+ 'openmates apps math calculate "sqrt(144)" --mode numeric --precision 10 --json'
57686
+ ],
57687
+ "music/generate": [
57688
+ 'openmates apps music generate "A 30 second upbeat electronic test jingle" --mode jingle --duration-seconds 30 --json'
57689
+ ],
57690
+ "news/search": [
57691
+ 'openmates apps news search "artificial intelligence" --freshness pw --json'
57692
+ ],
57693
+ "shopping/search_products": [
57694
+ 'openmates apps shopping search_products "bio joghurt" --provider REWE --json'
57695
+ ],
57696
+ "travel/search_connections": [
57697
+ "openmates apps travel search_connections --origin Berlin --destination Munich --date 2026-08-01 --json",
57698
+ "openmates apps travel search_connections --origin Berlin --destination Munich --date 2026-08-01 --transport train --json"
57699
+ ],
57700
+ "travel/search_stays": [
57701
+ 'openmates apps travel search_stays "Hotels in Berlin" --check-in-date 2026-08-01 --check-out-date 2026-08-03 --json'
57702
+ ],
57703
+ "videos/get_transcript": [
57704
+ "openmates apps videos get_transcript --url https://www.youtube.com/watch?v=dQw4w9WgXcQ --json"
57705
+ ],
57706
+ "videos/search": [
57707
+ 'openmates apps videos search "python programming tutorial" --json'
57708
+ ],
57709
+ "weather/forecast": [
57710
+ "openmates apps weather forecast Berlin --days 2 --json"
57711
+ ],
57712
+ "web/read": [
57713
+ "openmates apps web read https://example.com --json"
57714
+ ],
57715
+ "web/search": [
57716
+ 'openmates apps web search "OpenMates AI assistant" --json'
57717
+ ]
57718
+ };
57719
+ function findGeneratedAppSkillCommand(appId, skillId) {
57720
+ if (!appId || !skillId) return void 0;
57721
+ return GENERATED_APP_SKILL_COMMANDS.find(
57722
+ (command) => command.app_id === appId && command.skill_id === skillId
57723
+ );
57724
+ }
57725
+ function appSkillInputShape(command) {
57726
+ const schema = command.schema ?? { type: "object", properties: {} };
57727
+ const requests = schema.properties?.requests;
57728
+ if (requests?.type === "array") {
57729
+ const itemSchema = requests.items ?? { type: "object", properties: {} };
57730
+ return {
57731
+ kind: "request-array",
57732
+ schema: itemSchema,
57733
+ properties: itemSchema.properties ?? {},
57734
+ required: itemSchema.required ?? []
57735
+ };
57736
+ }
57737
+ return {
57738
+ kind: "flat",
57739
+ schema,
57740
+ properties: schema.properties ?? {},
57741
+ required: schema.required ?? []
57742
+ };
57743
+ }
57744
+ async function handleGeneratedAppSkillCommand(client, command, positionals, flags, apiKey) {
57745
+ if (flags.help === true) {
57746
+ printGeneratedAppSkillCommandHelp(command);
57747
+ return;
57748
+ }
57749
+ const inputData = buildGeneratedAppSkillInput(command, positionals, flags);
57750
+ try {
57751
+ const result = await client.runSkill({
57752
+ app: command.app_id,
57753
+ skill: command.skill_id,
57754
+ inputData,
57755
+ apiKey
57756
+ });
57757
+ if (flags.json === true) {
57758
+ printJson2(result);
57759
+ } else {
57760
+ printSkillResult(command.app_id, command.skill_id, result);
57761
+ }
57762
+ } catch (err) {
57763
+ const msg = err instanceof Error ? err.message : String(err);
57764
+ console.error(`\x1B[31m\u2717 ${command.app_id}/${command.skill_id} failed:\x1B[0m ${msg}`);
57765
+ process.exit(1);
57766
+ }
57767
+ }
57768
+ function buildGeneratedAppSkillInput(command, positionals, flags) {
57769
+ if (typeof flags.input === "string") {
57770
+ try {
57771
+ const parsed = JSON.parse(flags.input);
57772
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
57773
+ throw new Error("input must be a JSON object");
57774
+ }
57775
+ return parsed;
57776
+ } catch (err) {
57777
+ const detail = err instanceof Error ? err.message : String(err);
57778
+ throw new Error(`Invalid --input JSON: ${detail}`);
57779
+ }
57780
+ }
57781
+ const shape = appSkillInputShape(command);
57782
+ const value = buildGeneratedAppSkillValue(command, shape, positionals, flags);
57783
+ if (shape.kind === "request-array") {
57784
+ return { requests: [value] };
57785
+ }
57786
+ return value;
57787
+ }
57788
+ function buildGeneratedAppSkillValue(command, shape, positionals, flags) {
57789
+ if (command.app_id === "travel" && command.skill_id === "search_connections") {
57790
+ return buildTravelConnectionsRequest(positionals, flags);
57791
+ }
57792
+ const value = {};
57793
+ const consumedPositionals = applyPrimaryPositionals(command, shape, value, positionals);
57794
+ for (const [name, schema] of Object.entries(shape.properties)) {
57795
+ if (value[name] !== void 0 || name === "requests") continue;
57796
+ const raw = readFlag(flags, name);
57797
+ if (raw === void 0) continue;
57798
+ value[name] = coerceAppSkillFlagValue(name, raw, schema);
57799
+ }
57800
+ const remainingPositionals = positionals.slice(consumedPositionals);
57801
+ if (remainingPositionals.length > 0) {
57802
+ throw new Error(
57803
+ `Unexpected argument(s): ${remainingPositionals.join(" ")}
57804
+
57805
+ Run: openmates apps ${command.app_id} ${command.skill_id} --help`
57806
+ );
57807
+ }
57808
+ const missing = shape.required.filter((name) => value[name] === void 0 || value[name] === "");
57809
+ if (missing.length > 0) {
57810
+ throw new Error(
57811
+ `Missing required option(s): ${missing.map((name) => `--${kebabCase(name)}`).join(", ")}
57812
+
57813
+ Run: openmates apps ${command.app_id} ${command.skill_id} --help`
57814
+ );
57815
+ }
57816
+ return value;
57817
+ }
57818
+ function buildTravelConnectionsRequest(positionals, flags) {
57819
+ const origin = stringFlag(flags, "origin") ?? positionals[0];
57820
+ const destination = stringFlag(flags, "destination") ?? positionals[1];
57821
+ const date = stringFlag(flags, "date") ?? positionals[2];
57822
+ if (!origin || !destination || !date) {
57823
+ throw new Error(
57824
+ "Missing travel route. Use --origin <place> --destination <place> --date <YYYY-MM-DD>.\n\nExample: openmates apps travel search_connections --origin Berlin --destination Munich --date 2026-08-01 --json"
57825
+ );
57826
+ }
57827
+ const request = {
57828
+ legs: [{ origin, destination, date }]
57829
+ };
57830
+ const transport = stringFlag(flags, "transport") ?? stringFlag(flags, "transport-method");
57831
+ if (transport) request.transport_methods = [transport];
57832
+ return request;
57833
+ }
57834
+ function applyPrimaryPositionals(command, shape, value, positionals) {
57835
+ if (positionals.length === 0) return 0;
57836
+ if (command.app_id === "code" && command.skill_id === "get_docs") {
57837
+ if (value.library === void 0) value.library = positionals[0];
57838
+ if (value.question === void 0 && positionals.length > 1) {
57839
+ value.question = positionals.slice(1).join(" ");
57840
+ }
57841
+ return positionals.length;
57842
+ }
57843
+ const primary = primaryPositionalProperty(shape.properties, shape.required);
57844
+ if (!primary || value[primary] !== void 0) return 0;
57845
+ value[primary] = positionals.join(" ");
57846
+ return positionals.length;
57847
+ }
57848
+ function primaryPositionalProperty(properties, required) {
57849
+ const preferred = ["query", "url", "location", "expression", "prompt", "speciality", "library"];
57850
+ for (const name of preferred) {
57851
+ if (properties[name]?.type === "string") return name;
57852
+ }
57853
+ return required.find((name) => properties[name]?.type === "string");
57854
+ }
57855
+ function readFlag(flags, name) {
57856
+ return flags[name] ?? flags[kebabCase(name)];
57857
+ }
57858
+ function stringFlag(flags, name) {
57859
+ const raw = readFlag(flags, name);
57860
+ return typeof raw === "string" && raw.trim() ? raw.trim() : void 0;
57861
+ }
57862
+ function coerceAppSkillFlagValue(name, raw, schema) {
57863
+ if (schema.type === "boolean") return raw === true || raw === "true";
57864
+ if (schema.type === "integer") {
57865
+ if (typeof raw !== "string") throw new Error(`--${kebabCase(name)} requires an integer value`);
57866
+ const parsed = Number.parseInt(raw, 10);
57867
+ if (!Number.isInteger(parsed)) throw new Error(`--${kebabCase(name)} must be an integer`);
57868
+ return parsed;
57869
+ }
57870
+ if (schema.type === "number") {
57871
+ if (typeof raw !== "string") throw new Error(`--${kebabCase(name)} requires a number value`);
57872
+ const parsed = Number(raw);
57873
+ if (!Number.isFinite(parsed)) throw new Error(`--${kebabCase(name)} must be a number`);
57874
+ return parsed;
57875
+ }
57876
+ if (schema.type === "array") {
57877
+ if (typeof raw !== "string") return [];
57878
+ return raw.split(/[,\n]/).map((value) => value.trim()).filter(Boolean);
57879
+ }
57880
+ return typeof raw === "string" ? raw : String(raw);
57881
+ }
57882
+ function printGeneratedAppSkillCommandHelp(command) {
57883
+ const shape = appSkillInputShape(command);
57884
+ header(`${capitalise(command.app_id)} \u203A ${command.skill_id}`);
57885
+ if (command.description) console.log(`
57886
+ ${command.description}
57887
+ `);
57888
+ console.log("Usage:");
57889
+ console.log(` openmates apps ${command.app_id} ${command.skill_id} [value] [options] [--json]`);
57890
+ console.log(` openmates apps ${command.app_id} ${command.skill_id} --input '<json>' [--json]`);
57891
+ console.log("\nOptions:");
57892
+ console.log(" --input <json> Full app-skill input object. Use this for advanced/nested payloads.");
57893
+ for (const [name, schema] of Object.entries(shape.properties)) {
57894
+ const required = shape.required.includes(name) ? " required" : "";
57895
+ const type = appSkillCliType(schema);
57896
+ const description = schema.description ? ` ${schema.description.replace(/\s+/g, " ").slice(0, 120)}` : "";
57897
+ console.log(` --${kebabCase(name)} <${type}>${required}${description}`);
57898
+ }
57899
+ if (command.app_id === "travel" && command.skill_id === "search_connections") {
57900
+ console.log(" --origin <place> Route origin for a typed connection search.");
57901
+ console.log(" --destination <place> Route destination for a typed connection search.");
57902
+ console.log(" --date <YYYY-MM-DD> Departure date for a typed connection search.");
57903
+ console.log(" --transport <mode> Optional transport mode, e.g. train or plane.");
57904
+ }
57905
+ console.log(" --api-key <key> Use an API key instead of a stored CLI session.");
57906
+ console.log(" --json Print the raw response envelope as JSON.");
57907
+ console.log("\nExamples:");
57908
+ const key = `${command.app_id}/${command.skill_id}`;
57909
+ const examples = APP_SKILL_COMMAND_EXAMPLES[key] ?? [buildGeneratedAppSkillExample(command, shape)];
57910
+ for (const example of examples) console.log(` ${example}`);
57911
+ console.log("\nInspect metadata:");
57912
+ console.log(` openmates apps skill-info ${command.app_id} ${command.skill_id}`);
57913
+ }
57914
+ function appSkillCliType(schema) {
57915
+ if (schema.enum && schema.enum.length > 0) return schema.enum.map(String).join("|");
57916
+ if (schema.type === "array") return "csv";
57917
+ return schema.type ?? "value";
57918
+ }
57919
+ function buildGeneratedAppSkillExample(command, shape) {
57920
+ const primary = primaryPositionalProperty(shape.properties, shape.required);
57921
+ const value = primary ? String(buildExampleValue(primary, shape.properties[primary]?.type ?? "string", shape.properties[primary]?.description ?? "")) : "<value>";
57922
+ return `openmates apps ${command.app_id} ${command.skill_id} ${JSON.stringify(value)} --json`;
57923
+ }
57924
+ function kebabCase(value) {
57925
+ return value.replace(/_/g, "-");
57926
+ }
53745
57927
  async function handleApps(client, subcommand, rest, flags) {
53746
57928
  const apiKey = resolveApiKey(flags) ?? void 0;
53747
57929
  if (!subcommand || subcommand === "help") {
@@ -53752,6 +57934,11 @@ async function handleApps(client, subcommand, rest, flags) {
53752
57934
  const potentialApp = subcommand;
53753
57935
  const potentialSkill = rest[0];
53754
57936
  if (potentialSkill) {
57937
+ const command = findGeneratedAppSkillCommand(potentialApp, potentialSkill);
57938
+ if (command) {
57939
+ printGeneratedAppSkillCommandHelp(command);
57940
+ return;
57941
+ }
53755
57942
  console.error(
53756
57943
  `Generic app-skill CLI execution is not supported.
53757
57944
 
@@ -53925,6 +58112,11 @@ The booking_token is shown in the output of:
53925
58112
  await handleModels3dSearch(client, flags, apiKey);
53926
58113
  return;
53927
58114
  }
58115
+ const generatedCommand = findGeneratedAppSkillCommand(subcommand, rest[0]);
58116
+ if (generatedCommand) {
58117
+ await handleGeneratedAppSkillCommand(client, generatedCommand, rest.slice(1), flags, apiKey);
58118
+ return;
58119
+ }
53928
58120
  const app = subcommand;
53929
58121
  const skill = rest[0];
53930
58122
  if (app && skill) {
@@ -58162,6 +62354,8 @@ function printAppsHelp() {
58162
62354
  openmates apps info <app-id> [--json] App info (explicit)
58163
62355
  openmates apps skill-info <app-id> <skill-id> [--json]
58164
62356
  openmates apps examples <app-id> [skill-id] [--json]
62357
+ openmates apps <app-id> <skill-id> [value] [options] [--json]
62358
+ openmates apps <app-id> <skill-id> --input '<json>' [--json]
58165
62359
  openmates apps code run --language python --code 'print("Hello")'
58166
62360
  openmates apps code run --entry main.py --file main.py [--file requirements.txt]
58167
62361
  openmates apps code run --entry main.py --dir ./project [--exclude node_modules]
@@ -58175,6 +62369,10 @@ Authentication:
58175
62369
  Examples:
58176
62370
  openmates apps list
58177
62371
  openmates apps web
62372
+ openmates apps web search "OpenMates AI assistant" --json
62373
+ openmates apps weather forecast Berlin --days 2 --json
62374
+ openmates apps math calculate "sqrt(144)" --mode numeric --json
62375
+ openmates apps code get_docs --library React --question "How do I use useState?" --json
58178
62376
  openmates apps examples travel search_connections
58179
62377
  openmates apps code run --language python --filename hello.py --code 'print("Hello from CLI")'
58180
62378
  openmates apps models3d search --query benchy --count 2 --providers Printables --json
@@ -58495,6 +62693,8 @@ export {
58495
62693
  MATE_NAMES,
58496
62694
  deriveAppUrl,
58497
62695
  OpenMatesClient,
62696
+ APP_SKILL_METADATA,
62697
+ GeneratedAppSkills,
58498
62698
  SUPPORT_URL,
58499
62699
  renderSupportInfo,
58500
62700
  defaultCloneBranchForVersion,