@alquimia-ai/tools 2.5.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +603 -23
- package/dist/actions/index.d.mts +1 -1
- package/dist/actions/index.d.ts +1 -1
- package/dist/adapters/fetch.d.mts +1 -0
- package/dist/adapters/fetch.d.ts +1 -0
- package/dist/adapters/fetch.js +4 -0
- package/dist/adapters/fetch.js.map +1 -1
- package/dist/adapters/fetch.mjs +4 -0
- package/dist/adapters/fetch.mjs.map +1 -1
- package/dist/adapters/index.d.mts +1 -0
- package/dist/adapters/index.d.ts +1 -0
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/next.d.mts +1 -0
- package/dist/adapters/next.d.ts +1 -0
- package/dist/adapters/next.js +4 -0
- package/dist/adapters/next.js.map +1 -1
- package/dist/adapters/next.mjs +4 -0
- package/dist/adapters/next.mjs.map +1 -1
- package/dist/approvals-CcnmqUkQ.d.ts +59 -0
- package/dist/approvals-dn4sd_Ot.d.mts +59 -0
- package/dist/hooks/index.d.mts +36 -5
- package/dist/hooks/index.d.ts +36 -5
- package/dist/hooks/index.js +269 -17
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +269 -17
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/next/index.d.mts +7 -0
- package/dist/next/index.d.ts +7 -0
- package/dist/next/index.js +56 -37
- package/dist/next/index.js.map +1 -1
- package/dist/next/index.mjs +56 -37
- package/dist/next/index.mjs.map +1 -1
- package/dist/providers/index.d.mts +3 -3
- package/dist/providers/index.d.ts +3 -3
- package/dist/{providers-b5_yMyMo.d.ts → providers-J_Z9rQ3Q.d.ts} +1 -1
- package/dist/{providers-DiR9cgyo.d.mts → providers-YKiEag2L.d.mts} +1 -1
- package/dist/proxy.d.mts +2 -0
- package/dist/proxy.d.ts +2 -0
- package/dist/proxy.js +47 -37
- package/dist/proxy.js.map +1 -1
- package/dist/proxy.mjs +47 -37
- package/dist/proxy.mjs.map +1 -1
- package/dist/sdk/index.d.mts +60 -5
- package/dist/sdk/index.d.ts +60 -5
- package/dist/sdk/index.js +115 -15
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/index.mjs +115 -15
- package/dist/sdk/index.mjs.map +1 -1
- package/dist/services/index.d.mts +1 -1
- package/dist/services/index.d.ts +1 -1
- package/dist/{type-xksRnBUW.d.ts → type-BFtGEEb4.d.ts} +45 -1
- package/dist/{type-DqX3-9QS.d.mts → type-C_sKpIM1.d.mts} +45 -1
- package/dist/types/index.d.mts +28 -5
- package/dist/types/index.d.ts +28 -5
- package/dist/types/index.js.map +1 -1
- package/dist/types/index.mjs.map +1 -1
- package/dist/{types-C-6fgK1_.d.mts → types-lOliroPw.d.mts} +1 -1
- package/dist/{types-C-6fgK1_.d.ts → types-lOliroPw.d.ts} +1 -1
- package/dist/utils/index.d.mts +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/worklog/index.d.mts +3 -2
- package/dist/worklog/index.d.ts +3 -2
- package/dist/worklog/index.js +94 -2
- package/dist/worklog/index.js.map +1 -1
- package/dist/worklog/index.mjs +94 -2
- package/dist/worklog/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/proxy.js
CHANGED
|
@@ -48,13 +48,56 @@ function pickTraceHeader(request) {
|
|
|
48
48
|
if (fromQuery) return { "x-trace-parent": fromQuery };
|
|
49
49
|
return {};
|
|
50
50
|
}
|
|
51
|
+
var DECISION_HEADER_NAMES = [
|
|
52
|
+
"taskid",
|
|
53
|
+
"parenttaskid",
|
|
54
|
+
"sessionid",
|
|
55
|
+
"userid",
|
|
56
|
+
"assistantid",
|
|
57
|
+
"agentspaceid",
|
|
58
|
+
"channelid",
|
|
59
|
+
"depth",
|
|
60
|
+
// Runtime v0.5.1: `CommonAttributes.version_tag` (alias `versiontag`)
|
|
61
|
+
// pins the decision to the agentspace version that ran the turn.
|
|
62
|
+
"versiontag"
|
|
63
|
+
];
|
|
51
64
|
function createAlquimiaProxyHandler(config) {
|
|
52
65
|
const baseUrl = config.assistantBaseUrl.replace(/\/$/, "");
|
|
53
66
|
const inferRoute = config.inferRoute ?? "event/infer";
|
|
54
67
|
const streamRoute = config.streamRoute ?? "event/stream";
|
|
55
68
|
const blobUploadRoute = config.blobUploadRoute ?? "context/blob/upload";
|
|
56
69
|
const toolCompletionRoute = config.toolCompletionRoute ?? "event/tool-completion";
|
|
70
|
+
const toolApprovalRoute = config.toolApprovalRoute ?? "event/tool-approval";
|
|
57
71
|
const authHeader = { Authorization: `Bearer ${config.apiKey}` };
|
|
72
|
+
async function forwardDecision(request, route, name) {
|
|
73
|
+
try {
|
|
74
|
+
const body = await request.text();
|
|
75
|
+
const headers = {
|
|
76
|
+
"Content-Type": "application/json",
|
|
77
|
+
...authHeader
|
|
78
|
+
};
|
|
79
|
+
for (const name2 of DECISION_HEADER_NAMES) {
|
|
80
|
+
const value = request.headers.get(name2);
|
|
81
|
+
if (value) headers[name2] = value;
|
|
82
|
+
}
|
|
83
|
+
Object.assign(headers, pickTraceHeader(request));
|
|
84
|
+
const response = await fetch(`${baseUrl}/${route}`, {
|
|
85
|
+
method: "POST",
|
|
86
|
+
headers,
|
|
87
|
+
body
|
|
88
|
+
});
|
|
89
|
+
return new Response(await response.text(), {
|
|
90
|
+
status: response.status,
|
|
91
|
+
headers: { "Content-Type": "application/json" }
|
|
92
|
+
});
|
|
93
|
+
} catch (error) {
|
|
94
|
+
console.error(`AlquimiaProxy ${name} exception:`, error);
|
|
95
|
+
return new Response(
|
|
96
|
+
JSON.stringify({ error: `Failed to forward ${name} request` }),
|
|
97
|
+
{ status: 500, headers: { "Content-Type": "application/json" } }
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
58
101
|
return {
|
|
59
102
|
async handleInfer(request, pathSuffix) {
|
|
60
103
|
try {
|
|
@@ -182,43 +225,10 @@ function createAlquimiaProxyHandler(config) {
|
|
|
182
225
|
}
|
|
183
226
|
},
|
|
184
227
|
async handleToolCompletion(request) {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
...authHeader
|
|
190
|
-
};
|
|
191
|
-
const CORRELATION_HEADERS = [
|
|
192
|
-
"taskid",
|
|
193
|
-
"parenttaskid",
|
|
194
|
-
"sessionid",
|
|
195
|
-
"userid",
|
|
196
|
-
"assistantid",
|
|
197
|
-
"agentspaceid",
|
|
198
|
-
"channelid",
|
|
199
|
-
"depth"
|
|
200
|
-
];
|
|
201
|
-
for (const name of CORRELATION_HEADERS) {
|
|
202
|
-
const value = request.headers.get(name);
|
|
203
|
-
if (value) headers[name] = value;
|
|
204
|
-
}
|
|
205
|
-
Object.assign(headers, pickTraceHeader(request));
|
|
206
|
-
const response = await fetch(`${baseUrl}/${toolCompletionRoute}`, {
|
|
207
|
-
method: "POST",
|
|
208
|
-
headers,
|
|
209
|
-
body
|
|
210
|
-
});
|
|
211
|
-
return new Response(await response.text(), {
|
|
212
|
-
status: response.status,
|
|
213
|
-
headers: { "Content-Type": "application/json" }
|
|
214
|
-
});
|
|
215
|
-
} catch (error) {
|
|
216
|
-
console.error("AlquimiaProxy handleToolCompletion exception:", error);
|
|
217
|
-
return new Response(
|
|
218
|
-
JSON.stringify({ error: "Failed to forward tool-completion request" }),
|
|
219
|
-
{ status: 500, headers: { "Content-Type": "application/json" } }
|
|
220
|
-
);
|
|
221
|
-
}
|
|
228
|
+
return forwardDecision(request, toolCompletionRoute, "tool-completion");
|
|
229
|
+
},
|
|
230
|
+
async handleToolApproval(request) {
|
|
231
|
+
return forwardDecision(request, toolApprovalRoute, "tool-approval");
|
|
222
232
|
}
|
|
223
233
|
};
|
|
224
234
|
}
|
package/dist/proxy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/proxy.ts"],"sourcesContent":["export interface ProxyConfig {\n assistantBaseUrl: string;\n apiKey: string;\n inferRoute?: string; // default: 'event/infer'\n streamRoute?: string; // default: 'event/stream'\n blobUploadRoute?: string; // default: 'context/blob/upload'\n toolCompletionRoute?: string; // default: 'event/tool-completion'\n}\n\nexport interface AlquimiaProxyHandler {\n handleInfer(_request: Request, _pathSuffix: string): Promise<Response>;\n handleStream(_request: Request, _pathSuffix: string): Promise<Response>;\n handleBlobUpload(_request: Request): Promise<Response>;\n handleToolCompletion(_request: Request): Promise<Response>;\n}\n\nconst IDENTITY_HEADER_NAMES = [\n 'task-id',\n 'parent-task-id',\n 'session-id',\n 'user-id',\n 'assistant-id',\n 'agentspace-id',\n 'channel-id',\n 'depth',\n] as const;\n\nfunction pickIdentityHeaders(request: Request): Record<string, string> {\n const out: Record<string, string> = {};\n for (const name of IDENTITY_HEADER_NAMES) {\n const value = request.headers.get(name);\n if (value) out[name] = value;\n }\n return out;\n}\n\n/**\n * Trace-context propagation. The proxy builds a fresh request against the\n * runtime, so anything the caller set is dropped unless it is copied over\n * explicitly — which is how `x-trace-parent` stopped reaching the runtime when\n * the direct-to-runtime client was replaced by this proxy.\n *\n * The header is the transport wherever the caller can set one. `EventSource`\n * cannot, so the stream route also accepts the same value as a `trace_parent`\n * query param.\n */\nfunction pickTraceHeader(request: Request): Record<string, string> {\n const fromHeader = request.headers.get('x-trace-parent');\n if (fromHeader) return { 'x-trace-parent': fromHeader };\n\n const fromQuery = new URL(request.url).searchParams.get('trace_parent');\n if (fromQuery) return { 'x-trace-parent': fromQuery };\n\n return {};\n}\n\nexport function createAlquimiaProxyHandler(config: ProxyConfig): AlquimiaProxyHandler {\n const baseUrl = config.assistantBaseUrl.replace(/\\/$/, '');\n const inferRoute = config.inferRoute ?? 'event/infer';\n const streamRoute = config.streamRoute ?? 'event/stream';\n const blobUploadRoute = config.blobUploadRoute ?? 'context/blob/upload';\n const toolCompletionRoute = config.toolCompletionRoute ?? 'event/tool-completion';\n const authHeader = { Authorization: `Bearer ${config.apiKey}` };\n\n return {\n async handleInfer(request: Request, pathSuffix: string): Promise<Response> {\n try {\n const body = await request.json();\n const url = new URL(request.url);\n const querySuffix = url.searchParams.toString()\n ? `?${url.searchParams.toString()}`\n : '';\n const slug = pathSuffix.replace(/^\\/+|\\/+$/g, '');\n const targetUrl = `${baseUrl}/${inferRoute}/${slug}${querySuffix}`;\n\n\n const response = await fetch(targetUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...authHeader,\n ...pickIdentityHeaders(request),\n ...pickTraceHeader(request),\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorJson = await response.json().catch(() => ({}));\n console.error('AlquimiaProxy handleInfer error:', {\n status: response.status,\n statusText: response.statusText,\n body: errorJson,\n });\n return new Response(\n JSON.stringify({\n status: response.status,\n statusText: response.statusText,\n ...errorJson,\n }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n return new Response(response.body, {\n status: 200,\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Content-Encoding',\n },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleInfer exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward infer request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleStream(request: Request, pathSuffix: string): Promise<Response> {\n try {\n const targetUrl = `${baseUrl}/${streamRoute}/${pathSuffix}`;\n\n const response = await fetch(targetUrl, {\n headers: {\n 'Content-Type': 'application/json',\n ...authHeader,\n ...pickIdentityHeaders(request),\n ...pickTraceHeader(request),\n },\n });\n\n if (!response.ok) {\n const errorJson = await response.json().catch(() => ({}));\n console.error('AlquimiaProxy handleStream error:', {\n status: response.status,\n statusText: response.statusText,\n body: errorJson,\n });\n return new Response(\n JSON.stringify({\n error: errorJson.message || response.statusText || 'Failed to forward stream',\n ...errorJson,\n }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n return new Response(response.body, {\n status: 200,\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleStream exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward stream request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleBlobUpload(request: Request): Promise<Response> {\n try {\n const targetUrl = `${baseUrl}/${blobUploadRoute}`;\n const contentType = request.headers.get('Content-Type') ?? '';\n\n const response = await fetch(targetUrl, {\n method: 'POST',\n headers: {\n ...authHeader,\n ...(contentType && { 'Content-Type': contentType }),\n ...pickIdentityHeaders(request),\n ...pickTraceHeader(request),\n },\n body: request.body,\n duplex: 'half',\n } as RequestInit);\n\n if (!response.ok) {\n return new Response(\n JSON.stringify({ error: 'Failed to upload blob', status: response.status }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const responseText = await response.text();\n return new Response(responseText, {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleBlobUpload exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward blob upload request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleToolCompletion(request: Request): Promise<Response> {\n try {\n const body = await request.text();\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...authHeader,\n };\n // Forward the runtime's tool-completion correlation headers verbatim\n // (non-hyphenated names, per the runtime OpenAPI). These route the\n // completion to the parked task so the SSE stream resumes.\n const CORRELATION_HEADERS = [\n 'taskid',\n 'parenttaskid',\n 'sessionid',\n 'userid',\n 'assistantid',\n 'agentspaceid',\n 'channelid',\n 'depth',\n ];\n for (const name of CORRELATION_HEADERS) {\n const value = request.headers.get(name);\n if (value) headers[name] = value;\n }\n Object.assign(headers, pickTraceHeader(request));\n\n const response = await fetch(`${baseUrl}/${toolCompletionRoute}`, {\n method: 'POST',\n headers,\n body,\n });\n\n return new Response(await response.text(), {\n status: response.status,\n headers: { 'Content-Type': 'application/json' },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleToolCompletion exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward tool-completion request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/proxy.ts"],"sourcesContent":["export interface ProxyConfig {\n assistantBaseUrl: string;\n apiKey: string;\n inferRoute?: string; // default: 'event/infer'\n streamRoute?: string; // default: 'event/stream'\n blobUploadRoute?: string; // default: 'context/blob/upload'\n toolCompletionRoute?: string; // default: 'event/tool-completion'\n toolApprovalRoute?: string; // default: 'event/tool-approval'\n}\n\nexport interface AlquimiaProxyHandler {\n handleInfer(_request: Request, _pathSuffix: string): Promise<Response>;\n handleStream(_request: Request, _pathSuffix: string): Promise<Response>;\n handleBlobUpload(_request: Request): Promise<Response>;\n handleToolCompletion(_request: Request): Promise<Response>;\n handleToolApproval(_request: Request): Promise<Response>;\n}\n\nconst IDENTITY_HEADER_NAMES = [\n 'task-id',\n 'parent-task-id',\n 'session-id',\n 'user-id',\n 'assistant-id',\n 'agentspace-id',\n 'channel-id',\n 'depth',\n] as const;\n\nfunction pickIdentityHeaders(request: Request): Record<string, string> {\n const out: Record<string, string> = {};\n for (const name of IDENTITY_HEADER_NAMES) {\n const value = request.headers.get(name);\n if (value) out[name] = value;\n }\n return out;\n}\n\n/**\n * Trace-context propagation. The proxy builds a fresh request against the\n * runtime, so anything the caller set is dropped unless it is copied over\n * explicitly — which is how `x-trace-parent` stopped reaching the runtime when\n * the direct-to-runtime client was replaced by this proxy.\n *\n * The header is the transport wherever the caller can set one. `EventSource`\n * cannot, so the stream route also accepts the same value as a `trace_parent`\n * query param.\n */\nfunction pickTraceHeader(request: Request): Record<string, string> {\n const fromHeader = request.headers.get('x-trace-parent');\n if (fromHeader) return { 'x-trace-parent': fromHeader };\n\n const fromQuery = new URL(request.url).searchParams.get('trace_parent');\n if (fromQuery) return { 'x-trace-parent': fromQuery };\n\n return {};\n}\n\n/**\n * Correlation headers for tool-completion and tool-approval. Both routes bind\n * them through the runtime's `CommonAttributes` header model, whose aliases\n * have no separator — not the kebab-case identity set infer/stream use. They\n * route the decision to the parked task so the SSE stream resumes, and\n * `agentspaceid` is what the runtime authorizes a non-admin caller against.\n */\nconst DECISION_HEADER_NAMES = [\n 'taskid',\n 'parenttaskid',\n 'sessionid',\n 'userid',\n 'assistantid',\n 'agentspaceid',\n 'channelid',\n 'depth',\n // Runtime v0.5.1: `CommonAttributes.version_tag` (alias `versiontag`)\n // pins the decision to the agentspace version that ran the turn.\n 'versiontag',\n] as const;\n\nexport function createAlquimiaProxyHandler(config: ProxyConfig): AlquimiaProxyHandler {\n const baseUrl = config.assistantBaseUrl.replace(/\\/$/, '');\n const inferRoute = config.inferRoute ?? 'event/infer';\n const streamRoute = config.streamRoute ?? 'event/stream';\n const blobUploadRoute = config.blobUploadRoute ?? 'context/blob/upload';\n const toolCompletionRoute = config.toolCompletionRoute ?? 'event/tool-completion';\n const toolApprovalRoute = config.toolApprovalRoute ?? 'event/tool-approval';\n const authHeader = { Authorization: `Bearer ${config.apiKey}` };\n\n /**\n * Forward a one-shot decision (tool completion or approval). The runtime's\n * status and body pass through untouched: the 409s on these routes differ\n * only in their `detail` text, and the caller needs that to tell \"already\n * decided\" from \"answer it on the original channel\".\n */\n async function forwardDecision(request: Request, route: string, name: string): Promise<Response> {\n try {\n const body = await request.text();\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...authHeader,\n };\n for (const name of DECISION_HEADER_NAMES) {\n const value = request.headers.get(name);\n if (value) headers[name] = value;\n }\n Object.assign(headers, pickTraceHeader(request));\n\n const response = await fetch(`${baseUrl}/${route}`, {\n method: 'POST',\n headers,\n body,\n });\n\n return new Response(await response.text(), {\n status: response.status,\n headers: { 'Content-Type': 'application/json' },\n });\n } catch (error) {\n console.error(`AlquimiaProxy ${name} exception:`, error);\n return new Response(\n JSON.stringify({ error: `Failed to forward ${name} request` }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n }\n\n return {\n async handleInfer(request: Request, pathSuffix: string): Promise<Response> {\n try {\n const body = await request.json();\n const url = new URL(request.url);\n const querySuffix = url.searchParams.toString()\n ? `?${url.searchParams.toString()}`\n : '';\n const slug = pathSuffix.replace(/^\\/+|\\/+$/g, '');\n const targetUrl = `${baseUrl}/${inferRoute}/${slug}${querySuffix}`;\n\n\n const response = await fetch(targetUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...authHeader,\n ...pickIdentityHeaders(request),\n ...pickTraceHeader(request),\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorJson = await response.json().catch(() => ({}));\n console.error('AlquimiaProxy handleInfer error:', {\n status: response.status,\n statusText: response.statusText,\n body: errorJson,\n });\n return new Response(\n JSON.stringify({\n status: response.status,\n statusText: response.statusText,\n ...errorJson,\n }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n return new Response(response.body, {\n status: 200,\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Content-Encoding',\n },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleInfer exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward infer request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleStream(request: Request, pathSuffix: string): Promise<Response> {\n try {\n const targetUrl = `${baseUrl}/${streamRoute}/${pathSuffix}`;\n\n const response = await fetch(targetUrl, {\n headers: {\n 'Content-Type': 'application/json',\n ...authHeader,\n ...pickIdentityHeaders(request),\n ...pickTraceHeader(request),\n },\n });\n\n if (!response.ok) {\n const errorJson = await response.json().catch(() => ({}));\n console.error('AlquimiaProxy handleStream error:', {\n status: response.status,\n statusText: response.statusText,\n body: errorJson,\n });\n return new Response(\n JSON.stringify({\n error: errorJson.message || response.statusText || 'Failed to forward stream',\n ...errorJson,\n }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n return new Response(response.body, {\n status: 200,\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleStream exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward stream request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleBlobUpload(request: Request): Promise<Response> {\n try {\n const targetUrl = `${baseUrl}/${blobUploadRoute}`;\n const contentType = request.headers.get('Content-Type') ?? '';\n\n const response = await fetch(targetUrl, {\n method: 'POST',\n headers: {\n ...authHeader,\n ...(contentType && { 'Content-Type': contentType }),\n ...pickIdentityHeaders(request),\n ...pickTraceHeader(request),\n },\n body: request.body,\n duplex: 'half',\n } as RequestInit);\n\n if (!response.ok) {\n return new Response(\n JSON.stringify({ error: 'Failed to upload blob', status: response.status }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const responseText = await response.text();\n return new Response(responseText, {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleBlobUpload exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward blob upload request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleToolCompletion(request: Request): Promise<Response> {\n return forwardDecision(request, toolCompletionRoute, 'tool-completion');\n },\n\n async handleToolApproval(request: Request): Promise<Response> {\n return forwardDecision(request, toolApprovalRoute, 'tool-approval');\n },\n };\n}\n"],"mappings":"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","names":["name"]}
|
package/dist/proxy.mjs
CHANGED
|
@@ -24,13 +24,56 @@ function pickTraceHeader(request) {
|
|
|
24
24
|
if (fromQuery) return { "x-trace-parent": fromQuery };
|
|
25
25
|
return {};
|
|
26
26
|
}
|
|
27
|
+
var DECISION_HEADER_NAMES = [
|
|
28
|
+
"taskid",
|
|
29
|
+
"parenttaskid",
|
|
30
|
+
"sessionid",
|
|
31
|
+
"userid",
|
|
32
|
+
"assistantid",
|
|
33
|
+
"agentspaceid",
|
|
34
|
+
"channelid",
|
|
35
|
+
"depth",
|
|
36
|
+
// Runtime v0.5.1: `CommonAttributes.version_tag` (alias `versiontag`)
|
|
37
|
+
// pins the decision to the agentspace version that ran the turn.
|
|
38
|
+
"versiontag"
|
|
39
|
+
];
|
|
27
40
|
function createAlquimiaProxyHandler(config) {
|
|
28
41
|
const baseUrl = config.assistantBaseUrl.replace(/\/$/, "");
|
|
29
42
|
const inferRoute = config.inferRoute ?? "event/infer";
|
|
30
43
|
const streamRoute = config.streamRoute ?? "event/stream";
|
|
31
44
|
const blobUploadRoute = config.blobUploadRoute ?? "context/blob/upload";
|
|
32
45
|
const toolCompletionRoute = config.toolCompletionRoute ?? "event/tool-completion";
|
|
46
|
+
const toolApprovalRoute = config.toolApprovalRoute ?? "event/tool-approval";
|
|
33
47
|
const authHeader = { Authorization: `Bearer ${config.apiKey}` };
|
|
48
|
+
async function forwardDecision(request, route, name) {
|
|
49
|
+
try {
|
|
50
|
+
const body = await request.text();
|
|
51
|
+
const headers = {
|
|
52
|
+
"Content-Type": "application/json",
|
|
53
|
+
...authHeader
|
|
54
|
+
};
|
|
55
|
+
for (const name2 of DECISION_HEADER_NAMES) {
|
|
56
|
+
const value = request.headers.get(name2);
|
|
57
|
+
if (value) headers[name2] = value;
|
|
58
|
+
}
|
|
59
|
+
Object.assign(headers, pickTraceHeader(request));
|
|
60
|
+
const response = await fetch(`${baseUrl}/${route}`, {
|
|
61
|
+
method: "POST",
|
|
62
|
+
headers,
|
|
63
|
+
body
|
|
64
|
+
});
|
|
65
|
+
return new Response(await response.text(), {
|
|
66
|
+
status: response.status,
|
|
67
|
+
headers: { "Content-Type": "application/json" }
|
|
68
|
+
});
|
|
69
|
+
} catch (error) {
|
|
70
|
+
console.error(`AlquimiaProxy ${name} exception:`, error);
|
|
71
|
+
return new Response(
|
|
72
|
+
JSON.stringify({ error: `Failed to forward ${name} request` }),
|
|
73
|
+
{ status: 500, headers: { "Content-Type": "application/json" } }
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
34
77
|
return {
|
|
35
78
|
async handleInfer(request, pathSuffix) {
|
|
36
79
|
try {
|
|
@@ -158,43 +201,10 @@ function createAlquimiaProxyHandler(config) {
|
|
|
158
201
|
}
|
|
159
202
|
},
|
|
160
203
|
async handleToolCompletion(request) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
...authHeader
|
|
166
|
-
};
|
|
167
|
-
const CORRELATION_HEADERS = [
|
|
168
|
-
"taskid",
|
|
169
|
-
"parenttaskid",
|
|
170
|
-
"sessionid",
|
|
171
|
-
"userid",
|
|
172
|
-
"assistantid",
|
|
173
|
-
"agentspaceid",
|
|
174
|
-
"channelid",
|
|
175
|
-
"depth"
|
|
176
|
-
];
|
|
177
|
-
for (const name of CORRELATION_HEADERS) {
|
|
178
|
-
const value = request.headers.get(name);
|
|
179
|
-
if (value) headers[name] = value;
|
|
180
|
-
}
|
|
181
|
-
Object.assign(headers, pickTraceHeader(request));
|
|
182
|
-
const response = await fetch(`${baseUrl}/${toolCompletionRoute}`, {
|
|
183
|
-
method: "POST",
|
|
184
|
-
headers,
|
|
185
|
-
body
|
|
186
|
-
});
|
|
187
|
-
return new Response(await response.text(), {
|
|
188
|
-
status: response.status,
|
|
189
|
-
headers: { "Content-Type": "application/json" }
|
|
190
|
-
});
|
|
191
|
-
} catch (error) {
|
|
192
|
-
console.error("AlquimiaProxy handleToolCompletion exception:", error);
|
|
193
|
-
return new Response(
|
|
194
|
-
JSON.stringify({ error: "Failed to forward tool-completion request" }),
|
|
195
|
-
{ status: 500, headers: { "Content-Type": "application/json" } }
|
|
196
|
-
);
|
|
197
|
-
}
|
|
204
|
+
return forwardDecision(request, toolCompletionRoute, "tool-completion");
|
|
205
|
+
},
|
|
206
|
+
async handleToolApproval(request) {
|
|
207
|
+
return forwardDecision(request, toolApprovalRoute, "tool-approval");
|
|
198
208
|
}
|
|
199
209
|
};
|
|
200
210
|
}
|
package/dist/proxy.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/proxy.ts"],"sourcesContent":["export interface ProxyConfig {\n assistantBaseUrl: string;\n apiKey: string;\n inferRoute?: string; // default: 'event/infer'\n streamRoute?: string; // default: 'event/stream'\n blobUploadRoute?: string; // default: 'context/blob/upload'\n toolCompletionRoute?: string; // default: 'event/tool-completion'\n}\n\nexport interface AlquimiaProxyHandler {\n handleInfer(_request: Request, _pathSuffix: string): Promise<Response>;\n handleStream(_request: Request, _pathSuffix: string): Promise<Response>;\n handleBlobUpload(_request: Request): Promise<Response>;\n handleToolCompletion(_request: Request): Promise<Response>;\n}\n\nconst IDENTITY_HEADER_NAMES = [\n 'task-id',\n 'parent-task-id',\n 'session-id',\n 'user-id',\n 'assistant-id',\n 'agentspace-id',\n 'channel-id',\n 'depth',\n] as const;\n\nfunction pickIdentityHeaders(request: Request): Record<string, string> {\n const out: Record<string, string> = {};\n for (const name of IDENTITY_HEADER_NAMES) {\n const value = request.headers.get(name);\n if (value) out[name] = value;\n }\n return out;\n}\n\n/**\n * Trace-context propagation. The proxy builds a fresh request against the\n * runtime, so anything the caller set is dropped unless it is copied over\n * explicitly — which is how `x-trace-parent` stopped reaching the runtime when\n * the direct-to-runtime client was replaced by this proxy.\n *\n * The header is the transport wherever the caller can set one. `EventSource`\n * cannot, so the stream route also accepts the same value as a `trace_parent`\n * query param.\n */\nfunction pickTraceHeader(request: Request): Record<string, string> {\n const fromHeader = request.headers.get('x-trace-parent');\n if (fromHeader) return { 'x-trace-parent': fromHeader };\n\n const fromQuery = new URL(request.url).searchParams.get('trace_parent');\n if (fromQuery) return { 'x-trace-parent': fromQuery };\n\n return {};\n}\n\nexport function createAlquimiaProxyHandler(config: ProxyConfig): AlquimiaProxyHandler {\n const baseUrl = config.assistantBaseUrl.replace(/\\/$/, '');\n const inferRoute = config.inferRoute ?? 'event/infer';\n const streamRoute = config.streamRoute ?? 'event/stream';\n const blobUploadRoute = config.blobUploadRoute ?? 'context/blob/upload';\n const toolCompletionRoute = config.toolCompletionRoute ?? 'event/tool-completion';\n const authHeader = { Authorization: `Bearer ${config.apiKey}` };\n\n return {\n async handleInfer(request: Request, pathSuffix: string): Promise<Response> {\n try {\n const body = await request.json();\n const url = new URL(request.url);\n const querySuffix = url.searchParams.toString()\n ? `?${url.searchParams.toString()}`\n : '';\n const slug = pathSuffix.replace(/^\\/+|\\/+$/g, '');\n const targetUrl = `${baseUrl}/${inferRoute}/${slug}${querySuffix}`;\n\n\n const response = await fetch(targetUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...authHeader,\n ...pickIdentityHeaders(request),\n ...pickTraceHeader(request),\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorJson = await response.json().catch(() => ({}));\n console.error('AlquimiaProxy handleInfer error:', {\n status: response.status,\n statusText: response.statusText,\n body: errorJson,\n });\n return new Response(\n JSON.stringify({\n status: response.status,\n statusText: response.statusText,\n ...errorJson,\n }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n return new Response(response.body, {\n status: 200,\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Content-Encoding',\n },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleInfer exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward infer request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleStream(request: Request, pathSuffix: string): Promise<Response> {\n try {\n const targetUrl = `${baseUrl}/${streamRoute}/${pathSuffix}`;\n\n const response = await fetch(targetUrl, {\n headers: {\n 'Content-Type': 'application/json',\n ...authHeader,\n ...pickIdentityHeaders(request),\n ...pickTraceHeader(request),\n },\n });\n\n if (!response.ok) {\n const errorJson = await response.json().catch(() => ({}));\n console.error('AlquimiaProxy handleStream error:', {\n status: response.status,\n statusText: response.statusText,\n body: errorJson,\n });\n return new Response(\n JSON.stringify({\n error: errorJson.message || response.statusText || 'Failed to forward stream',\n ...errorJson,\n }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n return new Response(response.body, {\n status: 200,\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleStream exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward stream request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleBlobUpload(request: Request): Promise<Response> {\n try {\n const targetUrl = `${baseUrl}/${blobUploadRoute}`;\n const contentType = request.headers.get('Content-Type') ?? '';\n\n const response = await fetch(targetUrl, {\n method: 'POST',\n headers: {\n ...authHeader,\n ...(contentType && { 'Content-Type': contentType }),\n ...pickIdentityHeaders(request),\n ...pickTraceHeader(request),\n },\n body: request.body,\n duplex: 'half',\n } as RequestInit);\n\n if (!response.ok) {\n return new Response(\n JSON.stringify({ error: 'Failed to upload blob', status: response.status }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const responseText = await response.text();\n return new Response(responseText, {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleBlobUpload exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward blob upload request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleToolCompletion(request: Request): Promise<Response> {\n try {\n const body = await request.text();\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...authHeader,\n };\n // Forward the runtime's tool-completion correlation headers verbatim\n // (non-hyphenated names, per the runtime OpenAPI). These route the\n // completion to the parked task so the SSE stream resumes.\n const CORRELATION_HEADERS = [\n 'taskid',\n 'parenttaskid',\n 'sessionid',\n 'userid',\n 'assistantid',\n 'agentspaceid',\n 'channelid',\n 'depth',\n ];\n for (const name of CORRELATION_HEADERS) {\n const value = request.headers.get(name);\n if (value) headers[name] = value;\n }\n Object.assign(headers, pickTraceHeader(request));\n\n const response = await fetch(`${baseUrl}/${toolCompletionRoute}`, {\n method: 'POST',\n headers,\n body,\n });\n\n return new Response(await response.text(), {\n status: response.status,\n headers: { 'Content-Type': 'application/json' },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleToolCompletion exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward tool-completion request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/proxy.ts"],"sourcesContent":["export interface ProxyConfig {\n assistantBaseUrl: string;\n apiKey: string;\n inferRoute?: string; // default: 'event/infer'\n streamRoute?: string; // default: 'event/stream'\n blobUploadRoute?: string; // default: 'context/blob/upload'\n toolCompletionRoute?: string; // default: 'event/tool-completion'\n toolApprovalRoute?: string; // default: 'event/tool-approval'\n}\n\nexport interface AlquimiaProxyHandler {\n handleInfer(_request: Request, _pathSuffix: string): Promise<Response>;\n handleStream(_request: Request, _pathSuffix: string): Promise<Response>;\n handleBlobUpload(_request: Request): Promise<Response>;\n handleToolCompletion(_request: Request): Promise<Response>;\n handleToolApproval(_request: Request): Promise<Response>;\n}\n\nconst IDENTITY_HEADER_NAMES = [\n 'task-id',\n 'parent-task-id',\n 'session-id',\n 'user-id',\n 'assistant-id',\n 'agentspace-id',\n 'channel-id',\n 'depth',\n] as const;\n\nfunction pickIdentityHeaders(request: Request): Record<string, string> {\n const out: Record<string, string> = {};\n for (const name of IDENTITY_HEADER_NAMES) {\n const value = request.headers.get(name);\n if (value) out[name] = value;\n }\n return out;\n}\n\n/**\n * Trace-context propagation. The proxy builds a fresh request against the\n * runtime, so anything the caller set is dropped unless it is copied over\n * explicitly — which is how `x-trace-parent` stopped reaching the runtime when\n * the direct-to-runtime client was replaced by this proxy.\n *\n * The header is the transport wherever the caller can set one. `EventSource`\n * cannot, so the stream route also accepts the same value as a `trace_parent`\n * query param.\n */\nfunction pickTraceHeader(request: Request): Record<string, string> {\n const fromHeader = request.headers.get('x-trace-parent');\n if (fromHeader) return { 'x-trace-parent': fromHeader };\n\n const fromQuery = new URL(request.url).searchParams.get('trace_parent');\n if (fromQuery) return { 'x-trace-parent': fromQuery };\n\n return {};\n}\n\n/**\n * Correlation headers for tool-completion and tool-approval. Both routes bind\n * them through the runtime's `CommonAttributes` header model, whose aliases\n * have no separator — not the kebab-case identity set infer/stream use. They\n * route the decision to the parked task so the SSE stream resumes, and\n * `agentspaceid` is what the runtime authorizes a non-admin caller against.\n */\nconst DECISION_HEADER_NAMES = [\n 'taskid',\n 'parenttaskid',\n 'sessionid',\n 'userid',\n 'assistantid',\n 'agentspaceid',\n 'channelid',\n 'depth',\n // Runtime v0.5.1: `CommonAttributes.version_tag` (alias `versiontag`)\n // pins the decision to the agentspace version that ran the turn.\n 'versiontag',\n] as const;\n\nexport function createAlquimiaProxyHandler(config: ProxyConfig): AlquimiaProxyHandler {\n const baseUrl = config.assistantBaseUrl.replace(/\\/$/, '');\n const inferRoute = config.inferRoute ?? 'event/infer';\n const streamRoute = config.streamRoute ?? 'event/stream';\n const blobUploadRoute = config.blobUploadRoute ?? 'context/blob/upload';\n const toolCompletionRoute = config.toolCompletionRoute ?? 'event/tool-completion';\n const toolApprovalRoute = config.toolApprovalRoute ?? 'event/tool-approval';\n const authHeader = { Authorization: `Bearer ${config.apiKey}` };\n\n /**\n * Forward a one-shot decision (tool completion or approval). The runtime's\n * status and body pass through untouched: the 409s on these routes differ\n * only in their `detail` text, and the caller needs that to tell \"already\n * decided\" from \"answer it on the original channel\".\n */\n async function forwardDecision(request: Request, route: string, name: string): Promise<Response> {\n try {\n const body = await request.text();\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...authHeader,\n };\n for (const name of DECISION_HEADER_NAMES) {\n const value = request.headers.get(name);\n if (value) headers[name] = value;\n }\n Object.assign(headers, pickTraceHeader(request));\n\n const response = await fetch(`${baseUrl}/${route}`, {\n method: 'POST',\n headers,\n body,\n });\n\n return new Response(await response.text(), {\n status: response.status,\n headers: { 'Content-Type': 'application/json' },\n });\n } catch (error) {\n console.error(`AlquimiaProxy ${name} exception:`, error);\n return new Response(\n JSON.stringify({ error: `Failed to forward ${name} request` }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n }\n\n return {\n async handleInfer(request: Request, pathSuffix: string): Promise<Response> {\n try {\n const body = await request.json();\n const url = new URL(request.url);\n const querySuffix = url.searchParams.toString()\n ? `?${url.searchParams.toString()}`\n : '';\n const slug = pathSuffix.replace(/^\\/+|\\/+$/g, '');\n const targetUrl = `${baseUrl}/${inferRoute}/${slug}${querySuffix}`;\n\n\n const response = await fetch(targetUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...authHeader,\n ...pickIdentityHeaders(request),\n ...pickTraceHeader(request),\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorJson = await response.json().catch(() => ({}));\n console.error('AlquimiaProxy handleInfer error:', {\n status: response.status,\n statusText: response.statusText,\n body: errorJson,\n });\n return new Response(\n JSON.stringify({\n status: response.status,\n statusText: response.statusText,\n ...errorJson,\n }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n return new Response(response.body, {\n status: 200,\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Content-Encoding',\n },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleInfer exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward infer request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleStream(request: Request, pathSuffix: string): Promise<Response> {\n try {\n const targetUrl = `${baseUrl}/${streamRoute}/${pathSuffix}`;\n\n const response = await fetch(targetUrl, {\n headers: {\n 'Content-Type': 'application/json',\n ...authHeader,\n ...pickIdentityHeaders(request),\n ...pickTraceHeader(request),\n },\n });\n\n if (!response.ok) {\n const errorJson = await response.json().catch(() => ({}));\n console.error('AlquimiaProxy handleStream error:', {\n status: response.status,\n statusText: response.statusText,\n body: errorJson,\n });\n return new Response(\n JSON.stringify({\n error: errorJson.message || response.statusText || 'Failed to forward stream',\n ...errorJson,\n }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n return new Response(response.body, {\n status: 200,\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleStream exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward stream request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleBlobUpload(request: Request): Promise<Response> {\n try {\n const targetUrl = `${baseUrl}/${blobUploadRoute}`;\n const contentType = request.headers.get('Content-Type') ?? '';\n\n const response = await fetch(targetUrl, {\n method: 'POST',\n headers: {\n ...authHeader,\n ...(contentType && { 'Content-Type': contentType }),\n ...pickIdentityHeaders(request),\n ...pickTraceHeader(request),\n },\n body: request.body,\n duplex: 'half',\n } as RequestInit);\n\n if (!response.ok) {\n return new Response(\n JSON.stringify({ error: 'Failed to upload blob', status: response.status }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const responseText = await response.text();\n return new Response(responseText, {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleBlobUpload exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward blob upload request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleToolCompletion(request: Request): Promise<Response> {\n return forwardDecision(request, toolCompletionRoute, 'tool-completion');\n },\n\n async handleToolApproval(request: Request): Promise<Response> {\n return forwardDecision(request, toolApprovalRoute, 'tool-approval');\n },\n };\n}\n"],"mappings":"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","names":["name"]}
|
package/dist/sdk/index.d.mts
CHANGED
|
@@ -1,10 +1,28 @@
|
|
|
1
|
-
import { W as WhisperProvider, S as StableDiffusionProvider, C as CharacterizationProvider, R as RatingsProvider, L as LoggerProvider } from '../providers-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { W as WhisperProvider, S as StableDiffusionProvider, C as CharacterizationProvider, R as RatingsProvider, L as LoggerProvider } from '../providers-YKiEag2L.mjs';
|
|
2
|
+
import { d as AttachmentPayload, T as TTSResult, C as Content, e as RuntimeBlob } from '../type-C_sKpIM1.mjs';
|
|
3
|
+
import { ToolApprovalResult } from '../types/index.mjs';
|
|
4
4
|
import { AlquimiaAdapter, AlquimiaSDKOptions } from '../adapters/index.mjs';
|
|
5
|
+
import { T as ToolExecutionResponse } from '../types-CMVbyEv8.mjs';
|
|
5
6
|
import '@elastic/apm-rum';
|
|
6
7
|
import 'ai';
|
|
8
|
+
import '../types-lOliroPw.mjs';
|
|
7
9
|
|
|
10
|
+
/** Per-turn options for {@link AlquimiaSDK.sendMessage}. */
|
|
11
|
+
interface SendMessageOptions {
|
|
12
|
+
/** W3C traceparent, so infer and stream share one trace. */
|
|
13
|
+
traceParent?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Audio input for this turn (runtime v0.5.1). Upload it with
|
|
16
|
+
* {@link AlquimiaSDK.uploadAttachment} first and pass the blob it returns.
|
|
17
|
+
* May be sent with or instead of `query`.
|
|
18
|
+
*/
|
|
19
|
+
inputAudio?: RuntimeBlob;
|
|
20
|
+
/**
|
|
21
|
+
* Set to `false` to force a text-only reply from an audio-enabled agent.
|
|
22
|
+
* The runtime defaults to `true`, so leaving this unset keeps its behaviour.
|
|
23
|
+
*/
|
|
24
|
+
outputAudio?: boolean;
|
|
25
|
+
}
|
|
8
26
|
declare class AlquimiaSDK {
|
|
9
27
|
private adapter;
|
|
10
28
|
private assistantId;
|
|
@@ -13,6 +31,8 @@ declare class AlquimiaSDK {
|
|
|
13
31
|
private sessionId;
|
|
14
32
|
private streamId;
|
|
15
33
|
private traceParent;
|
|
34
|
+
private versionTag;
|
|
35
|
+
private agentspaceId;
|
|
16
36
|
private tools;
|
|
17
37
|
private extraInstructions;
|
|
18
38
|
private assistantConfig;
|
|
@@ -37,10 +57,20 @@ declare class AlquimiaSDK {
|
|
|
37
57
|
withExtraInstructions(extraInstructions: Record<string, string>): AlquimiaSDK;
|
|
38
58
|
withAssistantConfig(assistantConfig: any): AlquimiaSDK;
|
|
39
59
|
withUserId(userId: string): AlquimiaSDK;
|
|
60
|
+
/**
|
|
61
|
+
* Pin inference to a cached registry version. Sent as the `version_tag`
|
|
62
|
+
* query parameter, which `POST /event/infer/{assistant_id}` accepts from
|
|
63
|
+
* **runtime v0.5.2** onward; older runtimes ignore it.
|
|
64
|
+
*
|
|
65
|
+
* Works on every version: pass a versioned assistant ref
|
|
66
|
+
* (`<agentspace>/<assistant>[:<tag>]`) as the `assistantId` instead — the
|
|
67
|
+
* runtime parses the tag out of the path itself.
|
|
68
|
+
*/
|
|
69
|
+
withVersionTag(versionTag: string): AlquimiaSDK;
|
|
40
70
|
getEnforceCharacterization(): boolean;
|
|
41
71
|
textToSpeech(text: string): Promise<TTSResult>;
|
|
42
72
|
speechToText(audio: string): Promise<string>;
|
|
43
|
-
sendMessage(query
|
|
73
|
+
sendMessage(query?: Content, options?: string | SendMessageOptions): Promise<AlquimiaSDK>;
|
|
44
74
|
/**
|
|
45
75
|
* Complete a pending client-tool execution (the missing "submit half" of the
|
|
46
76
|
* client-tool loop). POSTs a {@link ToolExecutionResponse} to the runtime's
|
|
@@ -50,6 +80,17 @@ declare class AlquimiaSDK {
|
|
|
50
80
|
* `context-metadata` header (taskid + sessionid).
|
|
51
81
|
*/
|
|
52
82
|
submitToolResult(response: ToolExecutionResponse): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* Answer a `HumanApprovalRequired` gate: POSTs a {@link ToolApprovalEvent} to
|
|
85
|
+
* the runtime's `/event/tool-approval`. `controlId` is the gate's own control
|
|
86
|
+
* id (the `HumanApprovalRequired` record's), not the parked tool call's.
|
|
87
|
+
*
|
|
88
|
+
* Never throws for a runtime refusal — each 409 means something different to
|
|
89
|
+
* the UI, so the answer comes back classified as a {@link ToolApprovalResult}.
|
|
90
|
+
* It does throw when the adapter has no approval route, which is a wiring bug
|
|
91
|
+
* rather than a runtime answer.
|
|
92
|
+
*/
|
|
93
|
+
submitToolApproval(controlId: string, approved: boolean, message?: string): Promise<ToolApprovalResult>;
|
|
53
94
|
generateImage(query: string): Promise<string>;
|
|
54
95
|
analyzeCharacterization(text: string): Promise<Record<string, any>>;
|
|
55
96
|
rate(data: any): Promise<Record<string, any>>;
|
|
@@ -61,16 +102,30 @@ declare class AlquimiaSDK {
|
|
|
61
102
|
* session via headers. Always returns `[]`; kept for source compatibility.
|
|
62
103
|
*/
|
|
63
104
|
getAttachmentResponses(): string[];
|
|
64
|
-
|
|
105
|
+
/**
|
|
106
|
+
* Upload a file into the session context. Returns the runtime {@link RuntimeBlob},
|
|
107
|
+
* which is what `sendMessage`'s `inputAudio` expects for audio inference.
|
|
108
|
+
*/
|
|
109
|
+
uploadAttachment(file: File, _attachmentId?: string): Promise<RuntimeBlob>;
|
|
65
110
|
/**
|
|
66
111
|
* Identity headers (kebab-case) required by `/context/blob/upload` and
|
|
67
112
|
* the rest of the runtime's internal endpoints introduced in v0.2.0→next.
|
|
68
113
|
*/
|
|
69
114
|
private buildIdentityHeaders;
|
|
115
|
+
/**
|
|
116
|
+
* Correlation headers for tool-completion and tool-approval: the runtime's
|
|
117
|
+
* `CommonAttributes` header aliases, with no separator. Not interchangeable
|
|
118
|
+
* with the kebab-case set in {@link buildIdentityHeaders}.
|
|
119
|
+
*/
|
|
120
|
+
private buildDecisionHeaders;
|
|
70
121
|
getUrlStream(): string;
|
|
71
122
|
getStreamId(): string | null;
|
|
72
123
|
/** Alias for {@link getStreamId} — same value as infer `taskid`. */
|
|
73
124
|
getTaskId(): string | null;
|
|
125
|
+
/** Registry version tag resolved by the runtime for the current task, if any. */
|
|
126
|
+
getVersionTag(): string | null;
|
|
127
|
+
/** Agentspace the runtime resolved for the current task, if any. */
|
|
128
|
+
getAgentspaceId(): string | null;
|
|
74
129
|
}
|
|
75
130
|
|
|
76
131
|
export { AlquimiaSDK };
|
package/dist/sdk/index.d.ts
CHANGED
|
@@ -1,10 +1,28 @@
|
|
|
1
|
-
import { W as WhisperProvider, S as StableDiffusionProvider, C as CharacterizationProvider, R as RatingsProvider, L as LoggerProvider } from '../providers-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { W as WhisperProvider, S as StableDiffusionProvider, C as CharacterizationProvider, R as RatingsProvider, L as LoggerProvider } from '../providers-J_Z9rQ3Q.js';
|
|
2
|
+
import { d as AttachmentPayload, T as TTSResult, C as Content, e as RuntimeBlob } from '../type-BFtGEEb4.js';
|
|
3
|
+
import { ToolApprovalResult } from '../types/index.js';
|
|
4
4
|
import { AlquimiaAdapter, AlquimiaSDKOptions } from '../adapters/index.js';
|
|
5
|
+
import { T as ToolExecutionResponse } from '../types-CMVbyEv8.js';
|
|
5
6
|
import '@elastic/apm-rum';
|
|
6
7
|
import 'ai';
|
|
8
|
+
import '../types-lOliroPw.js';
|
|
7
9
|
|
|
10
|
+
/** Per-turn options for {@link AlquimiaSDK.sendMessage}. */
|
|
11
|
+
interface SendMessageOptions {
|
|
12
|
+
/** W3C traceparent, so infer and stream share one trace. */
|
|
13
|
+
traceParent?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Audio input for this turn (runtime v0.5.1). Upload it with
|
|
16
|
+
* {@link AlquimiaSDK.uploadAttachment} first and pass the blob it returns.
|
|
17
|
+
* May be sent with or instead of `query`.
|
|
18
|
+
*/
|
|
19
|
+
inputAudio?: RuntimeBlob;
|
|
20
|
+
/**
|
|
21
|
+
* Set to `false` to force a text-only reply from an audio-enabled agent.
|
|
22
|
+
* The runtime defaults to `true`, so leaving this unset keeps its behaviour.
|
|
23
|
+
*/
|
|
24
|
+
outputAudio?: boolean;
|
|
25
|
+
}
|
|
8
26
|
declare class AlquimiaSDK {
|
|
9
27
|
private adapter;
|
|
10
28
|
private assistantId;
|
|
@@ -13,6 +31,8 @@ declare class AlquimiaSDK {
|
|
|
13
31
|
private sessionId;
|
|
14
32
|
private streamId;
|
|
15
33
|
private traceParent;
|
|
34
|
+
private versionTag;
|
|
35
|
+
private agentspaceId;
|
|
16
36
|
private tools;
|
|
17
37
|
private extraInstructions;
|
|
18
38
|
private assistantConfig;
|
|
@@ -37,10 +57,20 @@ declare class AlquimiaSDK {
|
|
|
37
57
|
withExtraInstructions(extraInstructions: Record<string, string>): AlquimiaSDK;
|
|
38
58
|
withAssistantConfig(assistantConfig: any): AlquimiaSDK;
|
|
39
59
|
withUserId(userId: string): AlquimiaSDK;
|
|
60
|
+
/**
|
|
61
|
+
* Pin inference to a cached registry version. Sent as the `version_tag`
|
|
62
|
+
* query parameter, which `POST /event/infer/{assistant_id}` accepts from
|
|
63
|
+
* **runtime v0.5.2** onward; older runtimes ignore it.
|
|
64
|
+
*
|
|
65
|
+
* Works on every version: pass a versioned assistant ref
|
|
66
|
+
* (`<agentspace>/<assistant>[:<tag>]`) as the `assistantId` instead — the
|
|
67
|
+
* runtime parses the tag out of the path itself.
|
|
68
|
+
*/
|
|
69
|
+
withVersionTag(versionTag: string): AlquimiaSDK;
|
|
40
70
|
getEnforceCharacterization(): boolean;
|
|
41
71
|
textToSpeech(text: string): Promise<TTSResult>;
|
|
42
72
|
speechToText(audio: string): Promise<string>;
|
|
43
|
-
sendMessage(query
|
|
73
|
+
sendMessage(query?: Content, options?: string | SendMessageOptions): Promise<AlquimiaSDK>;
|
|
44
74
|
/**
|
|
45
75
|
* Complete a pending client-tool execution (the missing "submit half" of the
|
|
46
76
|
* client-tool loop). POSTs a {@link ToolExecutionResponse} to the runtime's
|
|
@@ -50,6 +80,17 @@ declare class AlquimiaSDK {
|
|
|
50
80
|
* `context-metadata` header (taskid + sessionid).
|
|
51
81
|
*/
|
|
52
82
|
submitToolResult(response: ToolExecutionResponse): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* Answer a `HumanApprovalRequired` gate: POSTs a {@link ToolApprovalEvent} to
|
|
85
|
+
* the runtime's `/event/tool-approval`. `controlId` is the gate's own control
|
|
86
|
+
* id (the `HumanApprovalRequired` record's), not the parked tool call's.
|
|
87
|
+
*
|
|
88
|
+
* Never throws for a runtime refusal — each 409 means something different to
|
|
89
|
+
* the UI, so the answer comes back classified as a {@link ToolApprovalResult}.
|
|
90
|
+
* It does throw when the adapter has no approval route, which is a wiring bug
|
|
91
|
+
* rather than a runtime answer.
|
|
92
|
+
*/
|
|
93
|
+
submitToolApproval(controlId: string, approved: boolean, message?: string): Promise<ToolApprovalResult>;
|
|
53
94
|
generateImage(query: string): Promise<string>;
|
|
54
95
|
analyzeCharacterization(text: string): Promise<Record<string, any>>;
|
|
55
96
|
rate(data: any): Promise<Record<string, any>>;
|
|
@@ -61,16 +102,30 @@ declare class AlquimiaSDK {
|
|
|
61
102
|
* session via headers. Always returns `[]`; kept for source compatibility.
|
|
62
103
|
*/
|
|
63
104
|
getAttachmentResponses(): string[];
|
|
64
|
-
|
|
105
|
+
/**
|
|
106
|
+
* Upload a file into the session context. Returns the runtime {@link RuntimeBlob},
|
|
107
|
+
* which is what `sendMessage`'s `inputAudio` expects for audio inference.
|
|
108
|
+
*/
|
|
109
|
+
uploadAttachment(file: File, _attachmentId?: string): Promise<RuntimeBlob>;
|
|
65
110
|
/**
|
|
66
111
|
* Identity headers (kebab-case) required by `/context/blob/upload` and
|
|
67
112
|
* the rest of the runtime's internal endpoints introduced in v0.2.0→next.
|
|
68
113
|
*/
|
|
69
114
|
private buildIdentityHeaders;
|
|
115
|
+
/**
|
|
116
|
+
* Correlation headers for tool-completion and tool-approval: the runtime's
|
|
117
|
+
* `CommonAttributes` header aliases, with no separator. Not interchangeable
|
|
118
|
+
* with the kebab-case set in {@link buildIdentityHeaders}.
|
|
119
|
+
*/
|
|
120
|
+
private buildDecisionHeaders;
|
|
70
121
|
getUrlStream(): string;
|
|
71
122
|
getStreamId(): string | null;
|
|
72
123
|
/** Alias for {@link getStreamId} — same value as infer `taskid`. */
|
|
73
124
|
getTaskId(): string | null;
|
|
125
|
+
/** Registry version tag resolved by the runtime for the current task, if any. */
|
|
126
|
+
getVersionTag(): string | null;
|
|
127
|
+
/** Agentspace the runtime resolved for the current task, if any. */
|
|
128
|
+
getAgentspaceId(): string | null;
|
|
74
129
|
}
|
|
75
130
|
|
|
76
131
|
export { AlquimiaSDK };
|