@proveanything/smartlinks 2.0.25 → 2.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-tools.d.ts +3 -0
- package/dist/ai-tools.js +9 -0
- package/dist/api/ai.d.ts +46 -1
- package/dist/api/ai.js +75 -0
- package/dist/docs/API_SUMMARY.md +186 -1
- package/dist/docs/agent-tools.md +28 -0
- package/dist/docs/server-functions.md +90 -0
- package/dist/openapi.yaml +346 -0
- package/dist/types/ai.d.ts +179 -1
- package/dist/types/appManifest.d.ts +28 -0
- package/docs/API_SUMMARY.md +186 -1
- package/docs/agent-tools.md +28 -0
- package/docs/server-functions.md +90 -0
- package/openapi.yaml +346 -0
- package/package.json +1 -1
package/dist/ai-tools.d.ts
CHANGED
|
@@ -26,6 +26,9 @@ export declare const AI_TOOL_NAMES: {
|
|
|
26
26
|
readonly PDF_CREATE: "pdf.create";
|
|
27
27
|
readonly PDF_FILL: "pdf.fill";
|
|
28
28
|
readonly PDF_MERGE: "pdf.merge";
|
|
29
|
+
readonly PDF_INSPECT: "pdf.inspect";
|
|
30
|
+
readonly PDF_RENDER: "pdf.render";
|
|
31
|
+
readonly PDF_EXTRACT: "pdf.extract";
|
|
29
32
|
readonly HTTP_REQUEST: "http.request";
|
|
30
33
|
readonly TRANSLATE: "translate";
|
|
31
34
|
};
|
package/dist/ai-tools.js
CHANGED
|
@@ -23,6 +23,9 @@ export const AI_TOOL_NAMES = {
|
|
|
23
23
|
PDF_CREATE: 'pdf.create',
|
|
24
24
|
PDF_FILL: 'pdf.fill',
|
|
25
25
|
PDF_MERGE: 'pdf.merge',
|
|
26
|
+
PDF_INSPECT: 'pdf.inspect',
|
|
27
|
+
PDF_RENDER: 'pdf.render',
|
|
28
|
+
PDF_EXTRACT: 'pdf.extract',
|
|
26
29
|
HTTP_REQUEST: 'http.request',
|
|
27
30
|
TRANSLATE: 'translate',
|
|
28
31
|
};
|
|
@@ -58,6 +61,12 @@ export const BUILTIN_AI_TOOLS = [
|
|
|
58
61
|
description: 'Fill an AcroForm PDF\'s fields from a { field: value } map → hosted URL.' },
|
|
59
62
|
{ name: 'pdf.merge', group: 'media', capabilities: ['media:pdf'],
|
|
60
63
|
description: 'Merge several PDFs (by URL) into one → hosted URL.' },
|
|
64
|
+
{ name: 'pdf.inspect', group: 'media', capabilities: ['web:read'],
|
|
65
|
+
description: 'Cheaply introspect a PDF before any AI call: page count/sizes, whether each page has an extractable text layer, whether a raster image is present, and a routing recommendation (text-native → cheap text pass; curve-only/raster → vision/OCR). Deterministic, no AI.' },
|
|
66
|
+
{ name: 'pdf.render', group: 'media', capabilities: ['web:read'],
|
|
67
|
+
description: 'Rasterize a single PDF page to a PNG at a controllable DPI (e.g. 300 for small print) and return a hosted image URL — feed to a vision call or screenshot a page.' },
|
|
68
|
+
{ name: 'pdf.extract', group: 'media', capabilities: ['web:read', 'ai:vision'],
|
|
69
|
+
description: 'Extract typed JSON from a PDF in one call given a schema and/or prompt. Auto-routes: text-layer pages use cheap text extraction; curve-only/raster pages are rendered and read with vision.' },
|
|
61
70
|
{ name: 'http.request', group: 'net', capabilities: ['net:http'],
|
|
62
71
|
description: 'SSRF-guarded outbound HTTP(S) request to a public URL; returns status/headers/body.' },
|
|
63
72
|
{ name: 'translate', group: 'text', capabilities: ['ai:text'],
|
package/dist/api/ai.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ContentPart, FunctionCall, ToolCall, ChatMessage, ToolDefinition, ResponseTool, ResponseInputItem, ResponsesRequest, ResponsesResult, ResponsesStreamEvent, ChatCompletionRequest, ChatCompletionChoice, ChatCompletionResponse, ChatCompletionChunk, AIModel, AIModelListParams, AIModelListResponse, AgentRunRequest, AgentRunResult, AgentToolsQuery, AgentToolsResponse, SkillsListResponse, CatalogResponse, DocumentChunk, IndexDocumentRequest, IndexDocumentResponse, ConfigureAssistantRequest, ConfigureAssistantResponse, PublicChatRequest, PublicChatResponse, Session, RateLimitStatus, SessionStatistics, AiSession, AiSessionCreate, AiUsageReport, VoiceSessionRequest, VoiceSessionResponse, EphemeralTokenRequest, EphemeralTokenResponse, TranscriptionResponse, TTSRequest, GeneratePodcastRequest, PodcastScript, GeneratePodcastResponse, PodcastStatus, AIGenerateContentRequest, AIGenerateContentCandidate, AIGenerateContentResponse, AIGenerateImageRequest, AIGenerateImageResponse, AIGeneratedImage, AISearchPhotosRequest, AISearchPhotosPhoto, AISearchPhotosResponse, AIUploadedFile, AICacheRef } from "../types/ai.js";
|
|
1
|
+
import type { ContentPart, FunctionCall, ToolCall, ChatMessage, ToolDefinition, ResponseTool, ResponseInputItem, ResponsesRequest, ResponsesResult, ResponsesStreamEvent, ChatCompletionRequest, ChatCompletionChoice, ChatCompletionResponse, ChatCompletionChunk, AIModel, AIModelListParams, AIModelListResponse, AgentRunRequest, AgentRunResult, AgentToolsQuery, AgentToolsResponse, ToolRunResult, AiToolName, AiToolArgsMap, PublicAgentRunRequest, ClientTool, RunWithClientToolsOptions, SkillsListResponse, CatalogResponse, DocumentChunk, IndexDocumentRequest, IndexDocumentResponse, ConfigureAssistantRequest, ConfigureAssistantResponse, PublicChatRequest, PublicChatResponse, Session, RateLimitStatus, SessionStatistics, AiSession, AiSessionCreate, AiUsageReport, VoiceSessionRequest, VoiceSessionResponse, EphemeralTokenRequest, EphemeralTokenResponse, TranscriptionResponse, TTSRequest, GeneratePodcastRequest, PodcastScript, GeneratePodcastResponse, PodcastStatus, AIGenerateContentRequest, AIGenerateContentCandidate, AIGenerateContentResponse, AIGenerateImageRequest, AIGenerateImageResponse, AIGeneratedImage, AISearchPhotosRequest, AISearchPhotosPhoto, AISearchPhotosResponse, AIUploadedFile, AICacheRef } from "../types/ai.js";
|
|
2
2
|
export type { ContentPart, FunctionCall, ToolCall, ChatMessage, ToolDefinition, ResponseTool, ResponseInputItem, ResponsesRequest, ResponsesResult, ResponsesStreamEvent, ChatCompletionRequest, ChatCompletionChoice, ChatCompletionResponse, ChatCompletionChunk, AIModel, AIModelListParams, AIModelListResponse, DocumentChunk, IndexDocumentRequest, IndexDocumentResponse, ConfigureAssistantRequest, ConfigureAssistantResponse, PublicChatRequest, PublicChatResponse, Session, RateLimitStatus, SessionStatistics, AiSession, AiSessionCreate, AiUsageReport, VoiceSessionRequest, VoiceSessionResponse, EphemeralTokenRequest, EphemeralTokenResponse, TranscriptionResponse, TTSRequest, GeneratePodcastRequest, PodcastScript, GeneratePodcastResponse, PodcastStatus, AIGenerateContentRequest, AIGenerateContentCandidate, AIGenerateContentResponse, AIGenerateImageRequest, AIGenerateImageResponse, AIGeneratedImage, AISearchPhotosRequest, AISearchPhotosPhoto, AISearchPhotosResponse, AIUploadedFile, AICacheRef, };
|
|
3
3
|
declare namespace aiInternal {
|
|
4
4
|
namespace chat {
|
|
@@ -34,6 +34,20 @@ declare namespace aiInternal {
|
|
|
34
34
|
*/
|
|
35
35
|
function listTools(collectionId: string, query?: AgentToolsQuery): Promise<AgentToolsResponse>;
|
|
36
36
|
}
|
|
37
|
+
namespace tools {
|
|
38
|
+
/**
|
|
39
|
+
* Invoke ONE built-in server tool directly — no model in the loop. This is the
|
|
40
|
+
* "direct code" caller of the orchestration-neutral tool registry: the SAME tools the
|
|
41
|
+
* agent loop and the Responses `server_tools` path run, but called as a plain, typed,
|
|
42
|
+
* deterministic API. A front end can use it two ways: (1) call a tool straight as an
|
|
43
|
+
* API (e.g. `pdf.render` / `pdf.extract` behind a PDF UX), or (2) drive its OWN agent
|
|
44
|
+
* loop and execute each model tool-call here. Capability-gated server-side to the
|
|
45
|
+
* caller's grants (same blast-radius rules as the agent loop).
|
|
46
|
+
* POST /admin/collection/:collectionId/ai/tools/:name/run
|
|
47
|
+
*/
|
|
48
|
+
function run<K extends AiToolName>(collectionId: string, name: K, args: AiToolArgsMap[K]): Promise<ToolRunResult>;
|
|
49
|
+
function run<T = any>(collectionId: string, name: string, args?: Record<string, any>): Promise<ToolRunResult<T>>;
|
|
50
|
+
}
|
|
37
51
|
namespace skills {
|
|
38
52
|
/** List the skills apps can invoke (name, description, input/output schema). */
|
|
39
53
|
function list(collectionId: string): Promise<SkillsListResponse>;
|
|
@@ -135,6 +149,14 @@ declare namespace aiInternal {
|
|
|
135
149
|
* Chat with product assistant (RAG)
|
|
136
150
|
*/
|
|
137
151
|
function chat(collectionId: string, request: PublicChatRequest): Promise<PublicChatResponse>;
|
|
152
|
+
/**
|
|
153
|
+
* Public agent loop — run the orchestration-neutral tool loop on the consumer surface. Exposes an
|
|
154
|
+
* app's PUBLIC server functions (`agent.tool:true`, `visibility:'public'`) to a consumer assistant;
|
|
155
|
+
* built-in tools are opt-in by explicit `server_tools[]` allowlist only. The caller runs as the
|
|
156
|
+
* signed-in consumer ('owner', send the authKit bearer) or anonymous ('public').
|
|
157
|
+
* POST /public/collection/:collectionId/ai/agent/run
|
|
158
|
+
*/
|
|
159
|
+
function agentRun(collectionId: string, body: PublicAgentRunRequest): Promise<AgentRunResult>;
|
|
138
160
|
/**
|
|
139
161
|
* Get session history
|
|
140
162
|
*/
|
|
@@ -218,6 +240,23 @@ declare namespace aiInternal {
|
|
|
218
240
|
* Create or warm a cache for AI (admin)
|
|
219
241
|
*/
|
|
220
242
|
function createCache(collectionId: string, params: any): Promise<AICacheRef>;
|
|
243
|
+
/**
|
|
244
|
+
* Declare a client tool + its browser-side handler. The `declaration` (name/description/input) is
|
|
245
|
+
* sent to the model; the `handler` runs in the page when the model calls it — so it can touch the
|
|
246
|
+
* DOM, the user's session, local state, etc. Pair with `runWithClientTools`.
|
|
247
|
+
*/
|
|
248
|
+
function defineClientTool(name: string, spec: {
|
|
249
|
+
description?: string;
|
|
250
|
+
input?: Record<string, any>;
|
|
251
|
+
}, handler: (args: Record<string, any>) => any | Promise<any>): ClientTool;
|
|
252
|
+
/**
|
|
253
|
+
* Run an agent conversation that can call CLIENT tools, resolving them in the browser automatically.
|
|
254
|
+
* Drives the suspend/resume loop: call the agent → if it suspends on a client tool
|
|
255
|
+
* (`status:'requires_action'`), run the matching handler(s), append their outputs, and resubmit —
|
|
256
|
+
* until a final answer. Built-ins + app functions ride along via `toolbelt`. Only declared tools run
|
|
257
|
+
* (a call for an unknown tool throws), and each runs with the user's own auth.
|
|
258
|
+
*/
|
|
259
|
+
function runWithClientTools(collectionId: string, opts: RunWithClientToolsOptions): Promise<AgentRunResult>;
|
|
221
260
|
}
|
|
222
261
|
export declare const ai: {
|
|
223
262
|
chat: {
|
|
@@ -251,6 +290,7 @@ export declare const ai: {
|
|
|
251
290
|
};
|
|
252
291
|
public: {
|
|
253
292
|
chat: typeof aiInternal.publicClient.chat;
|
|
293
|
+
agentRun: typeof aiInternal.publicClient.agentRun;
|
|
254
294
|
getSession: typeof aiInternal.publicClient.getSession;
|
|
255
295
|
clearSession: typeof aiInternal.publicClient.clearSession;
|
|
256
296
|
getRateLimit: typeof aiInternal.publicClient.getRateLimit;
|
|
@@ -265,6 +305,11 @@ export declare const ai: {
|
|
|
265
305
|
run: typeof aiInternal.agent.run;
|
|
266
306
|
listTools: typeof aiInternal.agent.listTools;
|
|
267
307
|
};
|
|
308
|
+
tools: {
|
|
309
|
+
run: typeof aiInternal.tools.run;
|
|
310
|
+
};
|
|
311
|
+
defineClientTool: typeof aiInternal.defineClientTool;
|
|
312
|
+
runWithClientTools: typeof aiInternal.runWithClientTools;
|
|
268
313
|
skills: {
|
|
269
314
|
list: typeof aiInternal.skills.list;
|
|
270
315
|
run: typeof aiInternal.skills.run;
|
package/dist/api/ai.js
CHANGED
|
@@ -90,6 +90,17 @@ var aiInternal;
|
|
|
90
90
|
agent.listTools = listTools;
|
|
91
91
|
})(agent = aiInternal.agent || (aiInternal.agent = {}));
|
|
92
92
|
// ============================================================================
|
|
93
|
+
// Tools (direct, deterministic single-tool invocation — no model loop)
|
|
94
|
+
// ============================================================================
|
|
95
|
+
let tools;
|
|
96
|
+
(function (tools) {
|
|
97
|
+
async function run(collectionId, name, args = {}) {
|
|
98
|
+
const path = `/admin/collection/${encodeURIComponent(collectionId)}/ai/tools/${encodeURIComponent(name)}/run`;
|
|
99
|
+
return post(path, args);
|
|
100
|
+
}
|
|
101
|
+
tools.run = run;
|
|
102
|
+
})(tools = aiInternal.tools || (aiInternal.tools = {}));
|
|
103
|
+
// ============================================================================
|
|
93
104
|
// Skills + Catalog (app-facing discovery)
|
|
94
105
|
// ============================================================================
|
|
95
106
|
let skills;
|
|
@@ -290,6 +301,18 @@ var aiInternal;
|
|
|
290
301
|
return post(path, request);
|
|
291
302
|
}
|
|
292
303
|
publicClient.chat = chat;
|
|
304
|
+
/**
|
|
305
|
+
* Public agent loop — run the orchestration-neutral tool loop on the consumer surface. Exposes an
|
|
306
|
+
* app's PUBLIC server functions (`agent.tool:true`, `visibility:'public'`) to a consumer assistant;
|
|
307
|
+
* built-in tools are opt-in by explicit `server_tools[]` allowlist only. The caller runs as the
|
|
308
|
+
* signed-in consumer ('owner', send the authKit bearer) or anonymous ('public').
|
|
309
|
+
* POST /public/collection/:collectionId/ai/agent/run
|
|
310
|
+
*/
|
|
311
|
+
async function agentRun(collectionId, body) {
|
|
312
|
+
const path = `/public/collection/${encodeURIComponent(collectionId)}/ai/agent/run`;
|
|
313
|
+
return post(path, body);
|
|
314
|
+
}
|
|
315
|
+
publicClient.agentRun = agentRun;
|
|
293
316
|
/**
|
|
294
317
|
* Get session history
|
|
295
318
|
*/
|
|
@@ -472,6 +495,52 @@ var aiInternal;
|
|
|
472
495
|
return post(path, params);
|
|
473
496
|
}
|
|
474
497
|
aiInternal.createCache = createCache;
|
|
498
|
+
// ============================================================================
|
|
499
|
+
// Client tools (kind c) — front-end tools the model calls, executed in the page
|
|
500
|
+
// ============================================================================
|
|
501
|
+
/**
|
|
502
|
+
* Declare a client tool + its browser-side handler. The `declaration` (name/description/input) is
|
|
503
|
+
* sent to the model; the `handler` runs in the page when the model calls it — so it can touch the
|
|
504
|
+
* DOM, the user's session, local state, etc. Pair with `runWithClientTools`.
|
|
505
|
+
*/
|
|
506
|
+
function defineClientTool(name, spec, handler) {
|
|
507
|
+
const declaration = { name, description: spec === null || spec === void 0 ? void 0 : spec.description, input: spec === null || spec === void 0 ? void 0 : spec.input };
|
|
508
|
+
return { declaration, handler };
|
|
509
|
+
}
|
|
510
|
+
aiInternal.defineClientTool = defineClientTool;
|
|
511
|
+
/**
|
|
512
|
+
* Run an agent conversation that can call CLIENT tools, resolving them in the browser automatically.
|
|
513
|
+
* Drives the suspend/resume loop: call the agent → if it suspends on a client tool
|
|
514
|
+
* (`status:'requires_action'`), run the matching handler(s), append their outputs, and resubmit —
|
|
515
|
+
* until a final answer. Built-ins + app functions ride along via `toolbelt`. Only declared tools run
|
|
516
|
+
* (a call for an unknown tool throws), and each runs with the user's own auth.
|
|
517
|
+
*/
|
|
518
|
+
async function runWithClientTools(collectionId, opts) {
|
|
519
|
+
const { tools, surface = 'admin', maxRounds = 8 } = opts;
|
|
520
|
+
const byName = new Map(tools.map((t) => [t.declaration.name, t]));
|
|
521
|
+
const clientTools = tools.map((t) => t.declaration);
|
|
522
|
+
const toolbelt = Object.assign(Object.assign({}, (opts.toolbelt || {})), { clientTools });
|
|
523
|
+
let input = opts.input;
|
|
524
|
+
for (let round = 0; round < maxRounds; round++) {
|
|
525
|
+
const body = { input, instructions: opts.instructions, model: opts.model, maxSteps: opts.maxSteps, toolbelt };
|
|
526
|
+
const res = surface === 'public'
|
|
527
|
+
? await publicClient.agentRun(collectionId, body)
|
|
528
|
+
: await agent.run(collectionId, body);
|
|
529
|
+
if (!res || res.status !== 'requires_action')
|
|
530
|
+
return res;
|
|
531
|
+
const outputs = [];
|
|
532
|
+
for (const call of (res.client_tool_calls || [])) {
|
|
533
|
+
const tool = byName.get(call.name);
|
|
534
|
+
if (!tool)
|
|
535
|
+
throw new Error(`runWithClientTools: model called undeclared client tool "${call.name}"`);
|
|
536
|
+
const out = await tool.handler(call.args || {});
|
|
537
|
+
outputs.push({ type: 'function_call_output', call_id: call.callId, output: typeof out === 'string' ? out : JSON.stringify(out !== null && out !== void 0 ? out : null) });
|
|
538
|
+
}
|
|
539
|
+
input = [...(res.items || []), ...outputs];
|
|
540
|
+
}
|
|
541
|
+
throw new Error('runWithClientTools: exceeded maxRounds without a final answer');
|
|
542
|
+
}
|
|
543
|
+
aiInternal.runWithClientTools = runWithClientTools;
|
|
475
544
|
})(aiInternal || (aiInternal = {}));
|
|
476
545
|
export const ai = {
|
|
477
546
|
chat: {
|
|
@@ -505,6 +574,7 @@ export const ai = {
|
|
|
505
574
|
},
|
|
506
575
|
public: {
|
|
507
576
|
chat: aiInternal.publicClient.chat,
|
|
577
|
+
agentRun: aiInternal.publicClient.agentRun,
|
|
508
578
|
getSession: aiInternal.publicClient.getSession,
|
|
509
579
|
clearSession: aiInternal.publicClient.clearSession,
|
|
510
580
|
getRateLimit: aiInternal.publicClient.getRateLimit,
|
|
@@ -519,6 +589,11 @@ export const ai = {
|
|
|
519
589
|
run: aiInternal.agent.run,
|
|
520
590
|
listTools: aiInternal.agent.listTools,
|
|
521
591
|
},
|
|
592
|
+
tools: {
|
|
593
|
+
run: aiInternal.tools.run,
|
|
594
|
+
},
|
|
595
|
+
defineClientTool: aiInternal.defineClientTool,
|
|
596
|
+
runWithClientTools: aiInternal.runWithClientTools,
|
|
522
597
|
skills: {
|
|
523
598
|
list: aiInternal.skills.list,
|
|
524
599
|
run: aiInternal.skills.run,
|
package/dist/docs/API_SUMMARY.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Smartlinks API Summary
|
|
2
2
|
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.28 | Generated: 2026-09-28T13:20:09.049Z
|
|
4
4
|
|
|
5
5
|
This is a concise summary of all available API functions and types.
|
|
6
6
|
|
|
@@ -594,6 +594,8 @@ interface ResponsesRequest {
|
|
|
594
594
|
only?: AiToolName[]
|
|
595
595
|
exclude?: AiToolName[]
|
|
596
596
|
maxSteps?: number
|
|
597
|
+
app_functions?: AgentAppFunctionsOption
|
|
598
|
+
toolbelt?: AgentToolbelt
|
|
597
599
|
}
|
|
598
600
|
```
|
|
599
601
|
|
|
@@ -1177,6 +1179,96 @@ interface AgentRunRequest {
|
|
|
1177
1179
|
allowCapabilities?: string[]
|
|
1178
1180
|
only?: string[]
|
|
1179
1181
|
exclude?: string[]
|
|
1182
|
+
appFunctions?: AgentAppFunctionsOption
|
|
1183
|
+
toolbelt?: AgentToolbelt
|
|
1184
|
+
}
|
|
1185
|
+
```
|
|
1186
|
+
|
|
1187
|
+
**AgentAppFunctionsOption** (interface)
|
|
1188
|
+
```typescript
|
|
1189
|
+
interface AgentAppFunctionsOption {
|
|
1190
|
+
appId: string
|
|
1191
|
+
channel?: string
|
|
1192
|
+
only?: string[]
|
|
1193
|
+
}
|
|
1194
|
+
```
|
|
1195
|
+
|
|
1196
|
+
**AgentToolbelt** (interface)
|
|
1197
|
+
```typescript
|
|
1198
|
+
interface AgentToolbelt {
|
|
1199
|
+
builtins?: boolean | AiToolName[]
|
|
1200
|
+
appFunctions?: AgentAppFunctionsOption | AgentAppFunctionsOption[]
|
|
1201
|
+
clientTools?: ClientToolDeclaration[]
|
|
1202
|
+
}
|
|
1203
|
+
```
|
|
1204
|
+
|
|
1205
|
+
**ClientToolDeclaration** (interface)
|
|
1206
|
+
```typescript
|
|
1207
|
+
interface ClientToolDeclaration {
|
|
1208
|
+
name: string
|
|
1209
|
+
description?: string
|
|
1210
|
+
input?: Record<string, any>
|
|
1211
|
+
}
|
|
1212
|
+
```
|
|
1213
|
+
|
|
1214
|
+
**ClientToolCall** (interface)
|
|
1215
|
+
```typescript
|
|
1216
|
+
interface ClientToolCall {
|
|
1217
|
+
callId: string
|
|
1218
|
+
name: string
|
|
1219
|
+
args: Record<string, any>
|
|
1220
|
+
}
|
|
1221
|
+
```
|
|
1222
|
+
|
|
1223
|
+
**RequiresActionResult** (interface)
|
|
1224
|
+
```typescript
|
|
1225
|
+
interface RequiresActionResult {
|
|
1226
|
+
status: 'requires_action'
|
|
1227
|
+
client_tool_calls: ClientToolCall[]
|
|
1228
|
+
items: any[]
|
|
1229
|
+
steps?: number
|
|
1230
|
+
toolResults?: AgentToolResult[]
|
|
1231
|
+
availableTools?: string[]
|
|
1232
|
+
}
|
|
1233
|
+
```
|
|
1234
|
+
|
|
1235
|
+
**ClientTool** (interface)
|
|
1236
|
+
```typescript
|
|
1237
|
+
interface ClientTool {
|
|
1238
|
+
declaration: ClientToolDeclaration
|
|
1239
|
+
handler: (args: Record<string, any>) => any | Promise<any>
|
|
1240
|
+
}
|
|
1241
|
+
```
|
|
1242
|
+
|
|
1243
|
+
**RunWithClientToolsOptions** (interface)
|
|
1244
|
+
```typescript
|
|
1245
|
+
interface RunWithClientToolsOptions {
|
|
1246
|
+
input: string
|
|
1247
|
+
tools: ClientTool[]
|
|
1248
|
+
surface?: 'admin' | 'public'
|
|
1249
|
+
instructions?: string
|
|
1250
|
+
model?: string
|
|
1251
|
+
maxSteps?: number
|
|
1252
|
+
toolbelt?: AgentToolbelt
|
|
1253
|
+
maxRounds?: number
|
|
1254
|
+
}
|
|
1255
|
+
```
|
|
1256
|
+
|
|
1257
|
+
**PublicAgentRunRequest** (interface)
|
|
1258
|
+
```typescript
|
|
1259
|
+
interface PublicAgentRunRequest {
|
|
1260
|
+
input?: string
|
|
1261
|
+
prompt?: string
|
|
1262
|
+
instructions?: string
|
|
1263
|
+
model?: string
|
|
1264
|
+
maxSteps?: number
|
|
1265
|
+
server_tools?: AiToolName[]
|
|
1266
|
+
only?: AiToolName[]
|
|
1267
|
+
exclude?: AiToolName[]
|
|
1268
|
+
allowCapabilities?: AiToolCapability[]
|
|
1269
|
+
appFunctions?: AgentAppFunctionsOption
|
|
1270
|
+
toolbelt?: AgentToolbelt
|
|
1271
|
+
userId?: string
|
|
1180
1272
|
}
|
|
1181
1273
|
```
|
|
1182
1274
|
|
|
@@ -1189,6 +1281,15 @@ interface AgentToolResult {
|
|
|
1189
1281
|
}
|
|
1190
1282
|
```
|
|
1191
1283
|
|
|
1284
|
+
**ToolRunResult<T = any>** (interface)
|
|
1285
|
+
```typescript
|
|
1286
|
+
interface ToolRunResult<T = any> {
|
|
1287
|
+
name: string
|
|
1288
|
+
isError: boolean
|
|
1289
|
+
result: T
|
|
1290
|
+
}
|
|
1291
|
+
```
|
|
1292
|
+
|
|
1192
1293
|
**AgentRunResult** (interface)
|
|
1193
1294
|
```typescript
|
|
1194
1295
|
interface AgentRunResult {
|
|
@@ -1367,6 +1468,27 @@ interface PdfMergeArgs {
|
|
|
1367
1468
|
}
|
|
1368
1469
|
```
|
|
1369
1470
|
|
|
1471
|
+
**PdfInspectArgs** (interface)
|
|
1472
|
+
```typescript
|
|
1473
|
+
interface PdfInspectArgs {
|
|
1474
|
+
url: string; maxPages?: number; minTextChars?: number
|
|
1475
|
+
}
|
|
1476
|
+
```
|
|
1477
|
+
|
|
1478
|
+
**PdfRenderArgs** (interface)
|
|
1479
|
+
```typescript
|
|
1480
|
+
interface PdfRenderArgs {
|
|
1481
|
+
url: string; page?: number; dpi?: number
|
|
1482
|
+
}
|
|
1483
|
+
```
|
|
1484
|
+
|
|
1485
|
+
**PdfExtractArgs** (interface)
|
|
1486
|
+
```typescript
|
|
1487
|
+
interface PdfExtractArgs {
|
|
1488
|
+
url: string; schema?: Record<string, any>; prompt?: string; maxPages?: number; dpi?: number
|
|
1489
|
+
}
|
|
1490
|
+
```
|
|
1491
|
+
|
|
1370
1492
|
**HttpRequestArgs** (interface)
|
|
1371
1493
|
```typescript
|
|
1372
1494
|
interface HttpRequestArgs {
|
|
@@ -1399,6 +1521,9 @@ interface AiToolArgsMap {
|
|
|
1399
1521
|
'pdf.create': PdfCreateArgs
|
|
1400
1522
|
'pdf.fill': PdfFillArgs
|
|
1401
1523
|
'pdf.merge': PdfMergeArgs
|
|
1524
|
+
'pdf.inspect': PdfInspectArgs
|
|
1525
|
+
'pdf.render': PdfRenderArgs
|
|
1526
|
+
'pdf.extract': PdfExtractArgs
|
|
1402
1527
|
'http.request': HttpRequestArgs
|
|
1403
1528
|
'translate': TranslateArgs
|
|
1404
1529
|
}
|
|
@@ -1467,6 +1592,34 @@ interface TranslateResult {
|
|
|
1467
1592
|
}
|
|
1468
1593
|
```
|
|
1469
1594
|
|
|
1595
|
+
**PdfInspectPage** (interface)
|
|
1596
|
+
```typescript
|
|
1597
|
+
interface PdfInspectPage {
|
|
1598
|
+
page: number; width: number; height: number; textChars: number; hasText: boolean; imageCount: number; likelyType: 'text-native' | 'text+raster' | 'raster-only' | 'curve-only'
|
|
1599
|
+
}
|
|
1600
|
+
```
|
|
1601
|
+
|
|
1602
|
+
**PdfInspectResult** (interface)
|
|
1603
|
+
```typescript
|
|
1604
|
+
interface PdfInspectResult {
|
|
1605
|
+
url: string; pageCount: number; inspectedPages: number; totalTextChars: number; isTextNative: boolean; isCurveOnly: boolean; recommendedPath: 'text' | 'vision'; note: string; pages: PdfInspectPage[]
|
|
1606
|
+
}
|
|
1607
|
+
```
|
|
1608
|
+
|
|
1609
|
+
**PdfRenderResult** (interface)
|
|
1610
|
+
```typescript
|
|
1611
|
+
interface PdfRenderResult {
|
|
1612
|
+
url: string | null; page: number; pageCount: number; dpi: number; width: number; height: number
|
|
1613
|
+
}
|
|
1614
|
+
```
|
|
1615
|
+
|
|
1616
|
+
**PdfExtractResult** (interface)
|
|
1617
|
+
```typescript
|
|
1618
|
+
interface PdfExtractResult {
|
|
1619
|
+
url: string; method: 'text' | 'vision'; pagesRead: number; fields: Record<string, any>
|
|
1620
|
+
}
|
|
1621
|
+
```
|
|
1622
|
+
|
|
1470
1623
|
**ResponsesAgentTrace** (interface)
|
|
1471
1624
|
```typescript
|
|
1472
1625
|
interface ResponsesAgentTrace {
|
|
@@ -2135,6 +2288,18 @@ interface AppFunctionDef {
|
|
|
2135
2288
|
dataScope?: 'collection' | 'global';
|
|
2136
2289
|
apiVersion?: string;
|
|
2137
2290
|
handler?: string;
|
|
2291
|
+
agent?: AppFunctionAgentExposure;
|
|
2292
|
+
}
|
|
2293
|
+
```
|
|
2294
|
+
|
|
2295
|
+
**AppFunctionAgentExposure** (interface)
|
|
2296
|
+
```typescript
|
|
2297
|
+
interface AppFunctionAgentExposure {
|
|
2298
|
+
tool: boolean;
|
|
2299
|
+
title?: string;
|
|
2300
|
+
description?: string;
|
|
2301
|
+
input?: Record<string, any>;
|
|
2302
|
+
approval?: 'auto' | 'require';
|
|
2138
2303
|
}
|
|
2139
2304
|
```
|
|
2140
2305
|
|
|
@@ -11250,6 +11415,10 @@ Get the active transfer/status for a proof (owner, collection admin, or the name
|
|
|
11250
11415
|
request: PublicChatRequest) → `Promise<PublicChatResponse>`
|
|
11251
11416
|
Chat with product assistant (RAG)
|
|
11252
11417
|
|
|
11418
|
+
**agentRun**(collectionId: string,
|
|
11419
|
+
body: PublicAgentRunRequest) → `Promise<AgentRunResult>`
|
|
11420
|
+
Public agent loop — run the orchestration-neutral tool loop on the consumer surface. Exposes an app's PUBLIC server functions (`agent.tool:true`, `visibility:'public'`) to a consumer assistant; built-in tools are opt-in by explicit `server_tools[]` allowlist only. The caller runs as the signed-in consumer ('owner', send the authKit bearer) or anonymous ('public'). POST /public/collection/:collectionId/ai/agent/run
|
|
11421
|
+
|
|
11253
11422
|
**getSession**(collectionId: string, sessionId: string) → `Promise<Session>`
|
|
11254
11423
|
Get session history
|
|
11255
11424
|
|
|
@@ -11483,6 +11652,22 @@ Reverse lookup by ref via POST (public). `POST /public/collection/:collectionId/
|
|
|
11483
11652
|
**renderSource**(collectionId: string,
|
|
11484
11653
|
body: TemplateRenderSourceRequest) → `Promise<TemplateRenderSourceResponse>`
|
|
11485
11654
|
|
|
11655
|
+
### tools
|
|
11656
|
+
|
|
11657
|
+
**run**(collectionId: string,
|
|
11658
|
+
name: K,
|
|
11659
|
+
args: AiToolArgsMap[K],) → `Promise<ToolRunResult>
|
|
11660
|
+
export async function run<T = any>(
|
|
11661
|
+
collectionId: string,
|
|
11662
|
+
name: string,
|
|
11663
|
+
args?: Record<string, any>,
|
|
11664
|
+
): Promise<ToolRunResult<T>>
|
|
11665
|
+
export async function run(
|
|
11666
|
+
collectionId: string,
|
|
11667
|
+
name: string,
|
|
11668
|
+
args: Record<string, any> =`
|
|
11669
|
+
Invoke ONE built-in server tool directly — no model in the loop. This is the "direct code" caller of the orchestration-neutral tool registry: the SAME tools the agent loop and the Responses `server_tools` path run, but called as a plain, typed, deterministic API. A front end can use it two ways: (1) call a tool straight as an API (e.g. `pdf.render` / `pdf.extract` behind a PDF UX), or (2) drive its OWN agent loop and execute each model tool-call here. Capability-gated server-side to the caller's grants (same blast-radius rules as the agent loop). POST /admin/collection/:collectionId/ai/tools/:name/run
|
|
11670
|
+
|
|
11486
11671
|
### translations
|
|
11487
11672
|
|
|
11488
11673
|
**hashText**(text: string, options?: TranslationHashOptions) → `Promise<string>`
|
package/dist/docs/agent-tools.md
CHANGED
|
@@ -69,6 +69,34 @@ The platform derives an **MCP tool list** from your manifest and drives the stan
|
|
|
69
69
|
→ `tools/call` → structured result — with streaming, cancellation, and approval layered on. You don't
|
|
70
70
|
implement the wire protocol; you declare tools and write handlers. (The live loop is the staged part.)
|
|
71
71
|
|
|
72
|
+
## Client tools (front-end)
|
|
73
|
+
|
|
74
|
+
For genuinely UI-coupled actions — read a field the user is editing, open a picker, update on-page
|
|
75
|
+
state — declare a **client tool**: the model calls it, but it runs in your page, not on the server.
|
|
76
|
+
Build each with `ai.defineClientTool` and drive the loop with `ai.runWithClientTools`, which resolves
|
|
77
|
+
every client call automatically (suspend → run handler → resubmit) until the assistant answers:
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
const pickDate = SL.ai.defineClientTool(
|
|
81
|
+
'ui.pickDate',
|
|
82
|
+
{ description: 'Open the date picker and return the chosen ISO date.',
|
|
83
|
+
input: { type: 'object', properties: { min: { type: 'string' } } } },
|
|
84
|
+
async ({ min }) => ({ date: await openDatePicker({ min }) }) // runs in the browser
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
const result = await SL.ai.runWithClientTools(collectionId, {
|
|
88
|
+
input: 'Book me the earliest slot next week',
|
|
89
|
+
tools: [pickDate],
|
|
90
|
+
toolbelt: { builtins: ['web.search'], appFunctions: [{ appId: 'booking' }] }, // mix all three kinds
|
|
91
|
+
// surface: 'public' // for a consumer assistant
|
|
92
|
+
})
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The handler runs with the user's own session (auto-scoped), and only tools you declared can be called
|
|
96
|
+
(a call for anything else throws). A client-tool name can never collide with a built-in or a server
|
|
97
|
+
function — those always win. This is the third tool **kind**, alongside built-in tools and app
|
|
98
|
+
functions, all declared together in one `toolbelt`.
|
|
99
|
+
|
|
72
100
|
## Security
|
|
73
101
|
|
|
74
102
|
Identical to server functions — nothing new to reason about:
|
|
@@ -271,6 +271,96 @@ name (a first-party builtin still wins). Always prefer an appId.
|
|
|
271
271
|
|
|
272
272
|
---
|
|
273
273
|
|
|
274
|
+
## Exposing a function to the AI agent
|
|
275
|
+
|
|
276
|
+
An `http` function can be offered to the AI agent as a **callable tool**, alongside the built-in
|
|
277
|
+
tools. The model calls it, the server runs it, and the result is fed back into the loop. Opt in from
|
|
278
|
+
the manifest with an `agent` block (full reference: [agent-tools.md](agent-tools.md)):
|
|
279
|
+
|
|
280
|
+
```jsonc
|
|
281
|
+
{
|
|
282
|
+
"name": "getLoyaltyBalance",
|
|
283
|
+
"trigger": { "type": "http" },
|
|
284
|
+
"visibility": "admin",
|
|
285
|
+
"authority": "caller",
|
|
286
|
+
"capabilities": ["sl:records:read"],
|
|
287
|
+
"agent": {
|
|
288
|
+
"tool": true,
|
|
289
|
+
"title": "Loyalty balance",
|
|
290
|
+
"description": "Look up a member's current loyalty points balance.",
|
|
291
|
+
"input": {
|
|
292
|
+
"type": "object",
|
|
293
|
+
"properties": { "memberId": { "type": "string" } },
|
|
294
|
+
"required": ["memberId"]
|
|
295
|
+
},
|
|
296
|
+
"approval": "auto" // 'require' = human confirms before each call
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
The agent becomes **just another caller surface** — your function's `visibility`, `authority`, and
|
|
302
|
+
`capabilities` are enforced exactly as on the http route. Nothing new is granted. The agent's tool
|
|
303
|
+
arguments arrive as the function's request `body`, and whatever you return becomes the tool result the
|
|
304
|
+
model sees. `approval: "require"` tools are held back from the autonomous server-side loop until the
|
|
305
|
+
human-approval UX ships.
|
|
306
|
+
|
|
307
|
+
Include your app's functions in an agent run:
|
|
308
|
+
|
|
309
|
+
```ts
|
|
310
|
+
// Agentic Responses:
|
|
311
|
+
await SL.ai.chat.responses.create(collectionId, {
|
|
312
|
+
model: 'balanced', input: 'What is member 42's balance?',
|
|
313
|
+
server_tools: true, // built-in tools
|
|
314
|
+
app_functions: { appId: 'my-loyalty-app' }, // + this app's ai.tool functions
|
|
315
|
+
})
|
|
316
|
+
|
|
317
|
+
// Or the one-shot agent loop:
|
|
318
|
+
await SL.ai.agent.run(collectionId, {
|
|
319
|
+
input: '…', appFunctions: { appId: 'my-loyalty-app' },
|
|
320
|
+
})
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
On the **consumer surface**, a `visibility: "public"` function reaches a public assistant via the
|
|
324
|
+
public agent loop — the caller runs as the signed-in consumer (`'owner'`, send the authKit bearer) or
|
|
325
|
+
anonymous (`'public'`):
|
|
326
|
+
|
|
327
|
+
```ts
|
|
328
|
+
await SL.ai.publicClient.agentRun(collectionId, {
|
|
329
|
+
input: '…',
|
|
330
|
+
appFunctions: { appId: 'my-app' }, // this app's public agent tools
|
|
331
|
+
server_tools: ['web.search'], // built-ins are an explicit allowlist on the public surface
|
|
332
|
+
})
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
`channel` (default `'stable'`, pass `'dev'` to test a dev build) and `only: string[]` narrow which
|
|
336
|
+
functions are exposed. Only `http` functions with `agent.tool: true` are eligible; `event`/`cron`
|
|
337
|
+
functions never are. A built-in tool of the same name wins the clash.
|
|
338
|
+
|
|
339
|
+
### One unified toolbelt
|
|
340
|
+
|
|
341
|
+
Rather than juggling `server_tools` + `app_functions`, declare everything in one `toolbelt` — built-in
|
|
342
|
+
tools, one **or several** apps' functions, and (reserved, staged) front-end client tools:
|
|
343
|
+
|
|
344
|
+
```ts
|
|
345
|
+
await SL.ai.chat.responses.create(collectionId, {
|
|
346
|
+
input: '…',
|
|
347
|
+
toolbelt: {
|
|
348
|
+
builtins: ['web.search', 'document.read'], // true = all, [names] = subset, omit = none
|
|
349
|
+
appFunctions: [{ appId: 'loyalty' }, { appId: 'catalog' }], // several apps at once
|
|
350
|
+
// clientTools: [ … ] // reserved — the client-tool bridge is staged
|
|
351
|
+
},
|
|
352
|
+
})
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
The same `toolbelt` works on `ai.agent.run` and `ai.publicClient.agentRun` (on the public surface
|
|
356
|
+
`builtins` is an explicit allowlist — `true` is treated as none). Precedence on a name clash: a
|
|
357
|
+
built-in wins, then earlier `appFunctions` sources win over later ones.
|
|
358
|
+
|
|
359
|
+
> Directly (no model): every function is also callable deterministically — `SL.functions.call` /
|
|
360
|
+
> `callAdmin` (above), the same way the built-in tools are callable via `SL.ai.tools.run`.
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
274
364
|
## Runtime — what your function can use
|
|
275
365
|
|
|
276
366
|
Your function runs in a **web-standard sandbox** (think Cloudflare Workers / Deno), **not
|