@proveanything/smartlinks 1.16.7 → 1.17.4

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.
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.16.7 | Generated: 2026-09-09T11:29:21.917Z
3
+ Version: 1.17.4 | Generated: 2026-09-13T17:10:55.335Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -57,6 +57,8 @@ For detailed guides on specific features:
57
57
  - **[Analytics](analytics.md)** - Web analytics, link-click tracking, QR/tag scan telemetry, and event reporting
58
58
  - **[Analytics Metadata Conventions](analytics-metadata-conventions.md)** - Standard recommended keys and conventions for analytics metadata fields
59
59
  - **[Loyalty: Points, Members & Earning Rules](loyalty.md)** - Loyalty schemes, automatic point earning via interaction rules, member balances, transaction history, and manual adjustments
60
+ - **[Integrations](integrations.md)** - Inbound/outbound integration flows + the sealed-secret store; triggers (manual/event/schedule), field mappings, and the Syndigo/Event Hub outbound path
61
+ - **[AI Tools & Skills](ai-tools-and-skills.md)** - The AI capability catalog: skills apps invoke by name (e.g. research.brand), the tools the AI reaches for (web fetch/screenshot/brand assets/image gen), the agent loop, and how apps discover them
60
62
  - **[Deep Link Discovery](deep-link-discovery.md)** - Registering and discovering navigable app states for portal menus and AI orchestration
61
63
  - **[AI-Native App Manifests](manifests.md)** - How AI workflows discover, configure, and import apps via structured manifests and prose guides
62
64
  - **[AI Guide Template](ai-guide-template.md)** - A sample for an app on how to build an AI setup guide
@@ -134,6 +136,7 @@ The Smartlinks SDK is organized into the following namespaces:
134
136
  - **containers** - Functions for containers operations
135
137
  - **facets** - Functions for facets operations
136
138
  - **http** - Functions for http operations
139
+ - **integrations** - Functions for integrations operations
137
140
  - **jobs** - Functions for jobs operations
138
141
  - **journeysAnalytics** - Functions for journeysAnalytics operations
139
142
  - **location** - Functions for location operations
@@ -142,6 +145,8 @@ The Smartlinks SDK is organized into the following namespaces:
142
145
  - **order** - Functions for order operations
143
146
  - **products** - Functions for products operations
144
147
  - **realtime** - Functions for realtime operations
148
+ - **research** - Functions for research operations
149
+ - **secrets** - Functions for secrets operations
145
150
  - **tags** - Functions for tags operations
146
151
  - **template** - Functions for template operations
147
152
  - **translations** - Functions for translations operations
@@ -1009,6 +1014,92 @@ interface AISearchPhotosPhoto {
1009
1014
  }
1010
1015
  ```
1011
1016
 
1017
+ **AgentRunRequest** (interface)
1018
+ ```typescript
1019
+ interface AgentRunRequest {
1020
+ input?: string
1021
+ prompt?: string
1022
+ instructions?: string
1023
+ model?: string
1024
+ maxSteps?: number
1025
+ allowCapabilities?: string[]
1026
+ only?: string[]
1027
+ exclude?: string[]
1028
+ }
1029
+ ```
1030
+
1031
+ **AgentToolResult** (interface)
1032
+ ```typescript
1033
+ interface AgentToolResult {
1034
+ name: string
1035
+ isError: boolean
1036
+ result: any
1037
+ }
1038
+ ```
1039
+
1040
+ **AgentRunResult** (interface)
1041
+ ```typescript
1042
+ interface AgentRunResult {
1043
+ finalText: string | null
1044
+ steps: number
1045
+ maxStepsReached: boolean
1046
+ toolResults: AgentToolResult[]
1047
+ availableTools: string[]
1048
+ }
1049
+ ```
1050
+
1051
+ **AgentToolDefinition** (interface)
1052
+ ```typescript
1053
+ interface AgentToolDefinition {
1054
+ name: string
1055
+ description: string
1056
+ capabilities: string[]
1057
+ parameters: any
1058
+ }
1059
+ ```
1060
+
1061
+ **AgentToolsResponse** (interface)
1062
+ ```typescript
1063
+ interface AgentToolsResponse {
1064
+ tools: AgentToolDefinition[]
1065
+ }
1066
+ ```
1067
+
1068
+ **AgentToolsQuery** (interface)
1069
+ ```typescript
1070
+ interface AgentToolsQuery {
1071
+ allowCapabilities?: string
1072
+ only?: string
1073
+ exclude?: string
1074
+ }
1075
+ ```
1076
+
1077
+ **SkillDescriptor** (interface)
1078
+ ```typescript
1079
+ interface SkillDescriptor {
1080
+ name: string
1081
+ description: string
1082
+ inputSchema: any
1083
+ outputSchema: any
1084
+ capabilities: string[]
1085
+ }
1086
+ ```
1087
+
1088
+ **SkillsListResponse** (interface)
1089
+ ```typescript
1090
+ interface SkillsListResponse {
1091
+ skills: SkillDescriptor[]
1092
+ }
1093
+ ```
1094
+
1095
+ **CatalogResponse** (interface)
1096
+ ```typescript
1097
+ interface CatalogResponse {
1098
+ tools: AgentToolDefinition[]
1099
+ skills: SkillDescriptor[]
1100
+ }
1101
+ ```
1102
+
1012
1103
  ### analytics
1013
1104
 
1014
1105
  **AnalyticsLocation** (interface)
@@ -5768,6 +5859,195 @@ interface UploadDoneMessage {
5768
5859
 
5769
5860
  **UploadMessage** = ``
5770
5861
 
5862
+ ### integrations
5863
+
5864
+ **FieldMapping** (interface)
5865
+ ```typescript
5866
+ interface FieldMapping {
5867
+ targetPath: string
5868
+ sourcePath?: string
5869
+ transformType: TransformType
5870
+ transformExpression?: string
5871
+ }
5872
+ ```
5873
+
5874
+ **FlowConnectionAuth** (interface)
5875
+ ```typescript
5876
+ interface FlowConnectionAuth {
5877
+ method: FlowAuthMethod
5878
+ headerName?: string
5879
+ credentialRef?: string
5880
+ }
5881
+ ```
5882
+
5883
+ **FlowConnection** (interface)
5884
+ ```typescript
5885
+ interface FlowConnection {
5886
+ baseUrl?: string
5887
+ sendEndpoint?: string
5888
+ fetchEndpoint?: string
5889
+ defaultHeaders?: Record<string, string>
5890
+ auth?: FlowConnectionAuth
5891
+ }
5892
+ ```
5893
+
5894
+ **IntegrationFlowConfig** (interface)
5895
+ ```typescript
5896
+ interface IntegrationFlowConfig {
5897
+ connection?: FlowConnection
5898
+ fieldMappings?: FieldMapping[]
5899
+ [key: string]: any
5900
+ }
5901
+ ```
5902
+
5903
+ **IntegrationFlow** (interface)
5904
+ ```typescript
5905
+ interface IntegrationFlow {
5906
+ id: string
5907
+ orgId: string
5908
+ collectionId: string
5909
+ appId: string
5910
+ direction: FlowDirection
5911
+ name: string
5912
+ status: FlowStatus
5913
+ eventTypes: string[]
5914
+ schedule: string | null
5915
+ sourceEntity: string | null
5916
+ targetEntity: string | null
5917
+ config: IntegrationFlowConfig
5918
+ createdBy: string | null
5919
+ createdAt: string
5920
+ updatedAt: string
5921
+ deletedAt?: string | null
5922
+ lastRunAt?: string | null
5923
+ lastRunStatus?: string | null
5924
+ lastRunError?: string | null
5925
+ lastRunCount?: number | null
5926
+ lastPollAt?: string | null
5927
+ lastCursor?: string | null
5928
+ totalSynced?: number | null
5929
+ }
5930
+ ```
5931
+
5932
+ **CreateFlowInput** (interface)
5933
+ ```typescript
5934
+ interface CreateFlowInput {
5935
+ appId: string
5936
+ direction: FlowDirection
5937
+ name: string
5938
+ status?: FlowStatus
5939
+ eventTypes?: string[]
5940
+ schedule?: string | null
5941
+ sourceEntity?: string | null
5942
+ targetEntity?: string | null
5943
+ config?: IntegrationFlowConfig
5944
+ }
5945
+ ```
5946
+
5947
+ **ListFlowsQuery** (interface)
5948
+ ```typescript
5949
+ interface ListFlowsQuery {
5950
+ direction?: FlowDirection
5951
+ status?: FlowStatus
5952
+ appId?: string
5953
+ }
5954
+ ```
5955
+
5956
+ **FlowList** (interface)
5957
+ ```typescript
5958
+ interface FlowList {
5959
+ flows: IntegrationFlow[]
5960
+ }
5961
+ ```
5962
+
5963
+ **RunFlowInput** (interface)
5964
+ ```typescript
5965
+ interface RunFlowInput {
5966
+ entityId?: string
5967
+ }
5968
+ ```
5969
+
5970
+ **RunFlowSummary** (interface)
5971
+ ```typescript
5972
+ interface RunFlowSummary {
5973
+ flowId: string
5974
+ direction: FlowDirection
5975
+ records: number
5976
+ sent: number
5977
+ failed: number
5978
+ status: RunStatus
5979
+ }
5980
+ ```
5981
+
5982
+ **RunFlowEnqueued** (interface)
5983
+ ```typescript
5984
+ interface RunFlowEnqueued {
5985
+ enqueued: true
5986
+ flowId: string
5987
+ entityId: string | null
5988
+ }
5989
+ ```
5990
+
5991
+ **SecretMeta** (interface)
5992
+ ```typescript
5993
+ interface SecretMeta {
5994
+ ref: string
5995
+ name: string | null
5996
+ purpose: string
5997
+ hint: string
5998
+ keyVersion: number
5999
+ createdBy: string | null
6000
+ createdAt: string
6001
+ updatedAt: string
6002
+ rotatedAt?: string | null
6003
+ }
6004
+ ```
6005
+
6006
+ **SecretList** (interface)
6007
+ ```typescript
6008
+ interface SecretList {
6009
+ secrets: SecretMeta[]
6010
+ }
6011
+ ```
6012
+
6013
+ **SetSecretInput** (interface)
6014
+ ```typescript
6015
+ interface SetSecretInput {
6016
+ value: string
6017
+ name?: string
6018
+ purpose?: string
6019
+ }
6020
+ ```
6021
+
6022
+ **SetSecretResult** (interface)
6023
+ ```typescript
6024
+ interface SetSecretResult {
6025
+ ref: string
6026
+ hint: string
6027
+ }
6028
+ ```
6029
+
6030
+ **ListSecretsQuery** (interface)
6031
+ ```typescript
6032
+ interface ListSecretsQuery {
6033
+ purpose?: string
6034
+ }
6035
+ ```
6036
+
6037
+ **FlowDirection** = `'inbound' | 'outbound'`
6038
+
6039
+ **FlowStatus** = `'draft' | 'active' | 'paused' | 'error'`
6040
+
6041
+ **RunStatus** = `'success' | 'partial' | 'error'`
6042
+
6043
+ **TransformType** = `'direct' | 'static' | 'template' | 'jsonata' | 'ai'`
6044
+
6045
+ **FlowAuthMethod** = `'api_key' | 'bearer' | 'basic' | 'webhook' | 'oauth2' | 'none'`
6046
+
6047
+ **UpdateFlowInput** = `Partial<Omit<CreateFlowInput, 'direction'>> & {`
6048
+
6049
+ **RunFlowResult** = `RunFlowSummary | RunFlowEnqueued`
6050
+
5771
6051
  ### interaction
5772
6052
 
5773
6053
  **AdminInteractionsQueryRequest** (interface)
@@ -7766,6 +8046,33 @@ interface AblyTokenRequest {
7766
8046
 
7767
8047
  **RealtimeChannelPattern** = `string`
7768
8048
 
8049
+ ### research
8050
+
8051
+ **ResearchFetchRequest** (interface)
8052
+ ```typescript
8053
+ interface ResearchFetchRequest {
8054
+ url: string
8055
+ type?: string
8056
+ schemaType?: string
8057
+ forceRefresh?: boolean
8058
+ }
8059
+ ```
8060
+
8061
+ **ResearchFetchResult** (interface)
8062
+ ```typescript
8063
+ interface ResearchFetchResult {
8064
+ provider: 'firecrawl' | 'web'
8065
+ status: number | null
8066
+ markdown?: string | null
8067
+ html?: string | null
8068
+ metadata?: Record<string, any> | null
8069
+ schemas: any[]
8070
+ url: string
8071
+ cached: boolean
8072
+ fetchedAt?: string
8073
+ }
8074
+ ```
8075
+
7769
8076
  ### segments
7770
8077
 
7771
8078
  **InteractionFilterValue** (interface)
@@ -8604,6 +8911,14 @@ interface Gs1DigitalLinkParams {
8604
8911
 
8605
8912
  ## API Functions
8606
8913
 
8914
+ ### agent
8915
+
8916
+ **run**(collectionId: string, body: AgentRunRequest) → `Promise<AgentRunResult>`
8917
+ Run the server-side AI agent loop once: assembles the tool set, runs the model, executes tool calls, and returns the final text + the tool trace. POST /admin/collection/:collectionId/ai/agent/run
8918
+
8919
+ **listTools**(collectionId: string, query: AgentToolsQuery = {}) → `Promise<AgentToolsResponse>`
8920
+ List the tools the agent can use (optionally scoped by capability / name). GET /admin/collection/:collectionId/ai/agent/tools
8921
+
8607
8922
  ### analytics.admin
8608
8923
 
8609
8924
  **summary**(collectionId: string,
@@ -9921,6 +10236,34 @@ Perform a PATCH request to any API endpoint.
9921
10236
  **del**(path: string) → `Promise<T>`
9922
10237
  Perform a DELETE request to any API endpoint.
9923
10238
 
10239
+ ### integrations
10240
+
10241
+ **listFlows**(collectionId: string, query: ListFlowsQuery = {}) → `Promise<FlowList>`
10242
+ List flows in a collection. GET /integrations/flows
10243
+
10244
+ **createFlow**(collectionId: string, input: CreateFlowInput) → `Promise<IntegrationFlow>`
10245
+ Create a flow. POST /integrations/flows
10246
+
10247
+ **getFlow**(collectionId: string, id: string) → `Promise<IntegrationFlow>`
10248
+ Get one flow. GET /integrations/flows/:id
10249
+
10250
+ **updateFlow**(collectionId: string, id: string, input: UpdateFlowInput) → `Promise<IntegrationFlow>`
10251
+ Update whitelisted fields. PUT /integrations/flows/:id
10252
+
10253
+ **deleteFlow**(collectionId: string, id: string) → `Promise<`
10254
+ Soft-delete a flow. DELETE /integrations/flows/:id
10255
+
10256
+ **runFlow**(collectionId: string,
10257
+ id: string,
10258
+ options: RunFlowInput & { async?: boolean } = {}) → `Promise<RunFlowResult>`
10259
+ Run a flow now. POST /integrations/flows/:id/run - inline (default): resolves and returns the run summary. - options.async: enqueue on the worker, returns { enqueued: true }. Pass options.entityId to run for a single source entity.
10260
+
10261
+ **isRunSummary**(r: RunFlowResult) → `r is RunFlowSummary`
10262
+ Type guard: the run executed inline and returned a summary.
10263
+
10264
+ **isRunEnqueued**(r: RunFlowResult) → `r is RunFlowEnqueued`
10265
+ Type guard: the run was enqueued (async).
10266
+
9924
10267
  ### interactions
9925
10268
 
9926
10269
  **query**(collectionId: string,
@@ -10613,6 +10956,28 @@ Get an Ably token for public (user-scoped) real-time communication. This endpoin
10613
10956
  **getAdminToken**() → `Promise<AblyTokenRequest>`
10614
10957
  Get an Ably token for admin real-time communication. This endpoint returns an Ably TokenRequest that can be used to initialize an Ably client with admin permissions to receive system notifications and alerts. Admin users get subscribe-only (read-only) access to the interaction:{userId} channel pattern. Requires admin authentication (Bearer token). ```ts const tokenRequest = await realtime.getAdminToken() // Use with Ably const ably = new Ably.Realtime.Promise({ authCallback: async (data, callback) => { callback(null, tokenRequest) } }) // Subscribe to admin interaction channel const userId = 'my-user-id' const channel = ably.channels.get(`interaction:${userId}`) await channel.subscribe((message) => { console.log('Admin notification:', message.data) }) ```
10615
10958
 
10959
+ ### research
10960
+
10961
+ **fetch**(collectionId: string, body: ResearchFetchRequest) → `Promise<ResearchFetchResult>`
10962
+ Fetch + extract a web page: clean markdown, page metadata, and any schema.org JSON-LD (filtered by `type` when given). Firecrawl-primary, cached per collection. POST /admin/collection/:collectionId/research/fetch
10963
+
10964
+ ### secrets
10965
+
10966
+ **list**(collectionId: string, query: ListSecretsQuery = {}) → `Promise<SecretList>`
10967
+ List secrets as refs + masked hints + metadata (never values). GET /secrets
10968
+
10969
+ **set**(collectionId: string, input: SetSecretInput) → `Promise<SetSecretResult>`
10970
+ Create a secret. POST /secrets → { ref, hint }. Store the ref on a flow.
10971
+
10972
+ **get**(collectionId: string, ref: string) → `Promise<SecretMeta>`
10973
+ Metadata for one secret (never the value). GET /secrets/:ref
10974
+
10975
+ **rotate**(collectionId: string, ref: string, input: SetSecretInput) → `Promise<SetSecretResult>`
10976
+ Rotate/update a secret's value (and optionally name/purpose). PUT /secrets/:ref → { ref, hint }
10977
+
10978
+ **remove**(collectionId: string, ref: string) → `Promise<`
10979
+ Soft-delete a secret. DELETE /secrets/:ref
10980
+
10616
10981
  ### segments
10617
10982
 
10618
10983
  **create**(collectionId: string,
@@ -10643,6 +11008,14 @@ Get an Ably token for admin real-time communication. This endpoint returns an Ab
10643
11008
  **stats**(collectionId: string) → `Promise<SessionStatistics>`
10644
11009
  Get session statistics
10645
11010
 
11011
+ ### skills
11012
+
11013
+ **list**(collectionId: string) → `Promise<SkillsListResponse>`
11014
+ List the skills apps can invoke (name, description, input/output schema).
11015
+
11016
+ **run**(collectionId: string, name: string, input: Record<string, any> = {}) → `Promise<T>`
11017
+ Invoke a skill by name with structured input — the app-facing verb; no prompt-shaping. POST /admin/collection/:collectionId/ai/skills/:name/run
11018
+
10646
11019
  ### tags
10647
11020
 
10648
11021
  **create**(collectionId: string,
@@ -0,0 +1,168 @@
1
+ # AI Tools & Skills
2
+
3
+ The platform's AI can research the web, extract structured data, screenshot pages, and
4
+ generate images — through a **capability registry**. This page is the catalog: what the
5
+ AI can do, and how an app reaches for it. You should not need to call an API to find
6
+ this out — it's documented here so that when you build an app (or an AI assistant helps
7
+ you), you *know* these capabilities exist and can shape your app to use them.
8
+
9
+ ## Two layers: tools vs skills
10
+
11
+ - **Skills** are the app-facing verbs — named, composed capabilities with the
12
+ orchestration and prompt **baked in**. You invoke a skill by name with structured
13
+ input and get structured output back. **You never write a prompt.** Example:
14
+ `research.brand`.
15
+ - **Tools** are the atomic building blocks (fetch a page, generate an image). The AI
16
+ reaches for these *itself* during a skill or agent run — you rarely call them directly.
17
+
18
+ Rule of thumb: **if a skill exists for what you want, call the skill.** Drop to the
19
+ agent loop (below) only for open-ended tasks with no matching skill.
20
+
21
+ ## Using a skill
22
+
23
+ ```ts
24
+ import { ai } from '@proveanything/smartlinks'
25
+
26
+ // Research a client's brand from their website — no prompt, just input.
27
+ const { profile, sources } = await ai.skills.run(collectionId, 'research.brand', {
28
+ url: 'https://acme.com',
29
+ })
30
+ // profile → { name, description, tagline, palette:[{hex}], logoUrl, tone, keyProducts, socials }
31
+ // sources → which signals were available (markdown, branding, schema.org)
32
+
33
+ // Discover skills at runtime too (this catalog, live):
34
+ const { skills } = await ai.skills.list(collectionId)
35
+ ```
36
+
37
+ ## Deterministic extraction (no AI)
38
+
39
+ For structured pages, skip the LLM entirely — `research.fetch` returns schema.org
40
+ JSON-LD deterministically:
41
+
42
+ ```ts
43
+ const res = await ai./* research */ // see the `research` namespace
44
+ // or the tool directly inside an agent run: web.extractSchema
45
+ ```
46
+ (See the **Integrations / research** doc for `research.fetch`, used e.g. by the Recipes
47
+ app to pull a recipe's schema.org data without any AI.)
48
+
49
+ ## Open-ended tasks: the agent loop
50
+
51
+ When no skill fits, run the agent — it's given the tool catalog and reaches for tools
52
+ as your prompt warrants:
53
+
54
+ ```ts
55
+ const result = await ai.agent.run(collectionId, {
56
+ prompt: 'Research acme.com and draft a one-paragraph brand summary with 3 hero image ideas.',
57
+ allowCapabilities: ['web:read', 'ai:image'], // cap blast radius to these capabilities
58
+ })
59
+ // result.finalText + result.toolResults (the trace of tools the AI called)
60
+
61
+ const { tools } = await ai.agent.listTools(collectionId) // what the AI could reach for
62
+ ```
63
+
64
+ `allowCapabilities` gates which tools a run may use (e.g. omit `ai:image` to forbid
65
+ image generation). Capability tags are listed against each tool below.
66
+
67
+ ## How the AI discovers tools
68
+
69
+ Within a skill or `ai.agent.run`, the tool definitions (names, descriptions, JSON
70
+ schemas) are passed to the model, so it discovers and calls them automatically. Outside
71
+ a run — e.g. the plain chat endpoints — tools are **not** auto-injected; use a skill or
72
+ the agent loop to give the AI tool access.
73
+
74
+ ---
75
+
76
+ <!-- The section below is GENERATED from the server registry (single source of truth),
77
+ also served live at GET /admin/collection/:collectionId/ai/catalog.
78
+ Regenerate with `node scripts/gen-ai-catalog.js` in prove/server. -->
79
+
80
+ ## Skills
81
+
82
+ Named, composed capabilities an app invokes **by name** with structured input — no prompt-shaping. Call `SL.ai.skills.run(collectionId, name, input)`.
83
+
84
+ ### `research.brand`
85
+
86
+ Research a brand or company from its website URL into a structured brand profile (name, description, palette, logo, tone, key products, socials). Gathers page content + schema.org + branding deterministically, then synthesises with AI.
87
+
88
+ _Capabilities: web:read, ai:text_
89
+
90
+ **Input**
91
+ - `url` _(required)_ — string: The brand's website URL (https).
92
+ - `instructions` — string: Optional extra guidance for the researcher.
93
+
94
+ ## Tools
95
+
96
+ Atomic building blocks the AI reaches for **during** an agent/skill run — you rarely call these directly. Enumerable via `SL.ai.agent.listTools(collectionId)`; capability tags cap what a run may use.
97
+
98
+ ### `web.fetchPage`
99
+
100
+ Fetch a web page by URL and return clean markdown, page metadata, and any structured schema.org/JSON-LD data. Use to research a brand or product website.
101
+
102
+ _Capabilities: web:read_
103
+
104
+ **Parameters**
105
+ - `url` _(required)_ — string: Absolute URL to fetch (https).
106
+ - `type` — string: Optional schema.org @type filter for the returned JSON-LD, e.g. "Product" or "Recipe".
107
+ - `forceRefresh` — boolean: Bypass the cache and re-fetch.
108
+
109
+ ### `web.extractSchema`
110
+
111
+ Fetch a URL and return only its schema.org structured data (JSON-LD) of the given @type, e.g. "Recipe" or "Product". Deterministic — no AI.
112
+
113
+ _Capabilities: web:read_
114
+
115
+ **Parameters**
116
+ - `url` _(required)_ — string: Absolute URL to fetch (https).
117
+ - `schemaType` — string: schema.org @type to extract, e.g. "Recipe" or "Product".
118
+ - `forceRefresh` — boolean
119
+
120
+ ### `web.screenshot`
121
+
122
+ Capture a screenshot of a web page. Returns a stable hosted image URL (screenshotUrl) you can then read with image.describe.
123
+
124
+ _Capabilities: web:read_
125
+
126
+ **Parameters**
127
+ - `url` _(required)_ — string: Absolute URL to screenshot (https).
128
+
129
+ ### `image.describe`
130
+
131
+ Describe an image at a URL, or read text from it (image-to-text / vision). Use on a screenshot or photo to extract what it shows or says.
132
+
133
+ _Capabilities: ai:vision_
134
+
135
+ **Parameters**
136
+ - `imageUrl` _(required)_ — string: URL of the image to analyse.
137
+ - `prompt` — string: What to extract or describe (default: describe + transcribe visible text).
138
+
139
+ ### `brand.assets`
140
+
141
+ Extract a website's brand elements — logo, colours, design — plus page metadata. Use to research a brand's visual identity.
142
+
143
+ _Capabilities: web:read_
144
+
145
+ **Parameters**
146
+ - `url` _(required)_ — string: The brand's website URL (https).
147
+
148
+ ### `image.generate`
149
+
150
+ Generate a new image from a text prompt. Returns the generated image (url or base64).
151
+
152
+ _Capabilities: ai:image_
153
+
154
+ **Parameters**
155
+ - `prompt` _(required)_ — string: Description of the image to generate.
156
+ - `size` — string: e.g. "1024x1024".
157
+ - `provider` — `openai` | `gemini`: Image model provider.
158
+
159
+ ### `image.searchStock`
160
+
161
+ Search stock photography (Unsplash) for real photos matching a query. Returns candidate image URLs.
162
+
163
+ _Capabilities: web:read_
164
+
165
+ **Parameters**
166
+ - `query` _(required)_ — string: What to search for.
167
+ - `per_page` — number: How many results (default 10).
168
+ - `orientation` — `landscape` | `portrait` | `squarish`