@tidblink/server 0.0.0-stage → 0.4.0-rc.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/LICENSE +201 -0
- package/README.md +1182 -2
- package/dist/audio.d.ts +72 -0
- package/dist/audio.d.ts.map +1 -0
- package/dist/audio.js +168 -0
- package/dist/audio.js.map +1 -0
- package/dist/backend-connection.d.ts +89 -0
- package/dist/backend-connection.d.ts.map +1 -0
- package/dist/backend-connection.js +300 -0
- package/dist/backend-connection.js.map +1 -0
- package/dist/backend-pool.d.ts +93 -0
- package/dist/backend-pool.d.ts.map +1 -0
- package/dist/backend-pool.js +419 -0
- package/dist/backend-pool.js.map +1 -0
- package/dist/client-tool-executor.d.ts +31 -0
- package/dist/client-tool-executor.d.ts.map +1 -0
- package/dist/client-tool-executor.js +190 -0
- package/dist/client-tool-executor.js.map +1 -0
- package/dist/client-tools.d.ts +21 -0
- package/dist/client-tools.d.ts.map +1 -0
- package/dist/client-tools.js +48 -0
- package/dist/client-tools.js.map +1 -0
- package/dist/connector-callback.d.ts +92 -0
- package/dist/connector-callback.d.ts.map +1 -0
- package/dist/connector-callback.js +155 -0
- package/dist/connector-callback.js.map +1 -0
- package/dist/connectors.d.ts +66 -0
- package/dist/connectors.d.ts.map +1 -0
- package/dist/connectors.js +71 -0
- package/dist/connectors.js.map +1 -0
- package/dist/control.d.ts +17 -0
- package/dist/control.d.ts.map +1 -0
- package/dist/control.js +52 -0
- package/dist/control.js.map +1 -0
- package/dist/errors.d.ts +103 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +115 -0
- package/dist/errors.js.map +1 -0
- package/dist/events.d.ts +158 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +110 -0
- package/dist/events.js.map +1 -0
- package/dist/files.d.ts +129 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +388 -0
- package/dist/files.js.map +1 -0
- package/dist/history.d.ts +279 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +91 -0
- package/dist/history.js.map +1 -0
- package/dist/http.d.ts +88 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +302 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/organization.d.ts +87 -0
- package/dist/organization.d.ts.map +1 -0
- package/dist/organization.js +112 -0
- package/dist/organization.js.map +1 -0
- package/dist/realtime.d.ts +90 -0
- package/dist/realtime.d.ts.map +1 -0
- package/dist/realtime.js +111 -0
- package/dist/realtime.js.map +1 -0
- package/dist/session-connection.d.ts +144 -0
- package/dist/session-connection.d.ts.map +1 -0
- package/dist/session-connection.js +334 -0
- package/dist/session-connection.js.map +1 -0
- package/dist/session-send.d.ts +49 -0
- package/dist/session-send.d.ts.map +1 -0
- package/dist/session-send.js +179 -0
- package/dist/session-send.js.map +1 -0
- package/dist/session.d.ts +165 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +253 -0
- package/dist/session.js.map +1 -0
- package/dist/skills.d.ts +103 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +98 -0
- package/dist/skills.js.map +1 -0
- package/dist/sse.d.ts +10 -0
- package/dist/sse.d.ts.map +1 -0
- package/dist/sse.js +50 -0
- package/dist/sse.js.map +1 -0
- package/dist/template-switch.d.ts +51 -0
- package/dist/template-switch.d.ts.map +1 -0
- package/dist/template-switch.js +81 -0
- package/dist/template-switch.js.map +1 -0
- package/dist/templates.d.ts +129 -0
- package/dist/templates.d.ts.map +1 -0
- package/dist/templates.js +92 -0
- package/dist/templates.js.map +1 -0
- package/dist/turn.d.ts +47 -0
- package/dist/turn.d.ts.map +1 -0
- package/dist/turn.js +210 -0
- package/dist/turn.js.map +1 -0
- package/dist/usage.d.ts +278 -0
- package/dist/usage.d.ts.map +1 -0
- package/dist/usage.js +22 -0
- package/dist/usage.js.map +1 -0
- package/dist/user.d.ts +55 -0
- package/dist/user.d.ts.map +1 -0
- package/dist/user.js +52 -0
- package/dist/user.js.map +1 -0
- package/examples/control-turn.mjs +53 -0
- package/examples/create-session.mjs +82 -0
- package/examples/http-connector.mjs +127 -0
- package/examples/lamp-backend.mjs +175 -0
- package/examples/prepare-realtime-connection.mjs +72 -0
- package/examples/read-usage.mjs +44 -0
- package/examples/send-message.mjs +48 -0
- package/examples/submit-audio.mjs +57 -0
- package/examples/upload-file.mjs +58 -0
- package/package.json +59 -4
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { BackendConnectionClosedError, BackendRequestError, TiDBLinkError, } from "./errors.js";
|
|
2
|
+
const OUTPUT_MAX = 65_536;
|
|
3
|
+
const ERROR_MAX = 4_096;
|
|
4
|
+
/** How long a settled callId is remembered to ignore late duplicates. */
|
|
5
|
+
const SETTLED_MEMORY_MS = 60_000;
|
|
6
|
+
/**
|
|
7
|
+
* Raised through `onError` when the core did not accept a Client Tool
|
|
8
|
+
* result. `reason` is the core's: `call_settled` (the call already had an
|
|
9
|
+
* outcome, for example its deadline passed), `not_claimed` or
|
|
10
|
+
* `call_not_found`.
|
|
11
|
+
*/
|
|
12
|
+
export class ClientToolResultRefusedError extends TiDBLinkError {
|
|
13
|
+
callId;
|
|
14
|
+
reason;
|
|
15
|
+
constructor(callId, reason) {
|
|
16
|
+
super(`The core did not accept the result of Client Tool call ${callId}: ${reason}`);
|
|
17
|
+
this.callId = callId;
|
|
18
|
+
this.reason = reason;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const isString = (value) => typeof value === "string" && value !== "";
|
|
22
|
+
const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23
|
+
const parseCall = (params) => isString(params.callId) &&
|
|
24
|
+
isString(params.sessionId) &&
|
|
25
|
+
isString(params.userId) &&
|
|
26
|
+
isString(params.turnId) &&
|
|
27
|
+
isString(params.name) &&
|
|
28
|
+
isObject(params.arguments) &&
|
|
29
|
+
isString(params.claimBy) &&
|
|
30
|
+
isString(params.deadlineAt) &&
|
|
31
|
+
Number.isFinite(Date.parse(params.deadlineAt))
|
|
32
|
+
? params
|
|
33
|
+
: undefined;
|
|
34
|
+
const truncate = (text, max) => text.length <= max ? text : `${text.slice(0, max - 1)}…`;
|
|
35
|
+
/** The text the model receives for a handler's return value. */
|
|
36
|
+
const outputOf = (value) => {
|
|
37
|
+
let output;
|
|
38
|
+
try {
|
|
39
|
+
output = typeof value === "string" ? value : value === undefined ? "" : JSON.stringify(value);
|
|
40
|
+
}
|
|
41
|
+
catch (cause) {
|
|
42
|
+
return { error: { message: `The tool returned a value that is not JSON: ${String(cause)}` } };
|
|
43
|
+
}
|
|
44
|
+
if (output === undefined)
|
|
45
|
+
return { error: { message: "The tool returned a value that is not JSON" } };
|
|
46
|
+
if (output.length > OUTPUT_MAX)
|
|
47
|
+
return {
|
|
48
|
+
error: { message: `The tool output exceeds ${OUTPUT_MAX} characters` },
|
|
49
|
+
};
|
|
50
|
+
return { output };
|
|
51
|
+
};
|
|
52
|
+
const errorOf = (error) => {
|
|
53
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
54
|
+
return { error: { message: truncate(message || "The tool failed", ERROR_MAX) } };
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Executes the Client Tool calls an executing Session connection receives:
|
|
58
|
+
* claim first, run only after `claimed: true`, then submit the result over any
|
|
59
|
+
* Backend Connection until the call's deadline. Each callId runs at most once.
|
|
60
|
+
*/
|
|
61
|
+
export class ClientToolExecutor {
|
|
62
|
+
#pool;
|
|
63
|
+
#sessionId;
|
|
64
|
+
#handlers;
|
|
65
|
+
#report;
|
|
66
|
+
#calls = new Map();
|
|
67
|
+
constructor(input) {
|
|
68
|
+
this.#pool = input.pool;
|
|
69
|
+
this.#sessionId = input.sessionId;
|
|
70
|
+
this.#handlers = input.handlers;
|
|
71
|
+
this.#report = input.report;
|
|
72
|
+
}
|
|
73
|
+
/** Handle one `tool.call` from the connection that delivered it. */
|
|
74
|
+
receive(params, link) {
|
|
75
|
+
const call = parseCall(params);
|
|
76
|
+
if (!call || call.sessionId !== this.#sessionId) {
|
|
77
|
+
this.#report(new TiDBLinkError("Received an invalid Client Tool call"));
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
// The core may send a call again after a reconnect; it runs once.
|
|
81
|
+
if (this.#calls.has(call.callId))
|
|
82
|
+
return;
|
|
83
|
+
// Never sent: the core sends it again to the next attachment while unclaimed.
|
|
84
|
+
if (!link.open)
|
|
85
|
+
return;
|
|
86
|
+
this.#calls.set(call.callId, "claiming");
|
|
87
|
+
void this.#claimAndRun(call, link);
|
|
88
|
+
}
|
|
89
|
+
async #claimAndRun(call, link) {
|
|
90
|
+
let answer;
|
|
91
|
+
try {
|
|
92
|
+
answer = await link.request("tool.claim", { callId: call.callId });
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
if (error instanceof BackendConnectionClosedError ||
|
|
96
|
+
(error instanceof BackendRequestError && error.code === -32603)) {
|
|
97
|
+
// The claim may have been granted; the call must not run, so close it as failed.
|
|
98
|
+
await this.#submit(call, {
|
|
99
|
+
error: {
|
|
100
|
+
message: "The Application Server lost the claim's answer and did not execute the call",
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
this.#calls.set(call.callId, "settled");
|
|
106
|
+
this.#forget(call);
|
|
107
|
+
this.#report(error);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (!answer || answer.claimed !== true) {
|
|
111
|
+
if (answer?.reason === "superseded") {
|
|
112
|
+
// Another generation holds the Session; this process may receive it again there.
|
|
113
|
+
this.#calls.delete(call.callId);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
this.#calls.set(call.callId, "settled");
|
|
117
|
+
this.#forget(call);
|
|
118
|
+
}
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
this.#calls.set(call.callId, "running");
|
|
122
|
+
await this.#submit(call, await this.#execute(call));
|
|
123
|
+
}
|
|
124
|
+
async #execute(call) {
|
|
125
|
+
const handler = Object.hasOwn(this.#handlers, call.name)
|
|
126
|
+
? this.#handlers[call.name]
|
|
127
|
+
: undefined;
|
|
128
|
+
if (!handler)
|
|
129
|
+
return {
|
|
130
|
+
error: {
|
|
131
|
+
message: `Client Tool ${call.name} has no handler in this Application Server`,
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
const deadlineAt = new Date(call.deadlineAt);
|
|
135
|
+
const controller = new AbortController();
|
|
136
|
+
let timer;
|
|
137
|
+
const expired = new Promise((resolve) => {
|
|
138
|
+
timer = setTimeout(() => {
|
|
139
|
+
controller.abort(new TiDBLinkError("The Client Tool call reached its deadline"));
|
|
140
|
+
resolve({ error: { message: "The tool did not finish before its deadline" } });
|
|
141
|
+
}, Math.max(0, deadlineAt.getTime() - Date.now()));
|
|
142
|
+
});
|
|
143
|
+
const context = {
|
|
144
|
+
callId: call.callId,
|
|
145
|
+
sessionId: call.sessionId,
|
|
146
|
+
userId: call.userId,
|
|
147
|
+
turnId: call.turnId,
|
|
148
|
+
name: call.name,
|
|
149
|
+
deadlineAt,
|
|
150
|
+
signal: controller.signal,
|
|
151
|
+
};
|
|
152
|
+
const run = (async () => {
|
|
153
|
+
try {
|
|
154
|
+
return outputOf(await handler.run(call.arguments, context));
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
return errorOf(error);
|
|
158
|
+
}
|
|
159
|
+
})();
|
|
160
|
+
try {
|
|
161
|
+
return await Promise.race([run, expired]);
|
|
162
|
+
}
|
|
163
|
+
finally {
|
|
164
|
+
clearTimeout(timer);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
async #submit(call, result) {
|
|
168
|
+
try {
|
|
169
|
+
const answer = await this.#pool.request("tool.result", { callId: call.callId, ...result }, { retryUntil: Date.parse(call.deadlineAt) });
|
|
170
|
+
if (answer?.accepted !== true) {
|
|
171
|
+
if (answer?.reason === "not_claimed") {
|
|
172
|
+
// The lost claim never took effect: the call may arrive again and run then.
|
|
173
|
+
this.#calls.delete(call.callId);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
this.#report(new ClientToolResultRefusedError(call.callId, answer?.reason ?? "unknown"));
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
this.#report(error);
|
|
181
|
+
}
|
|
182
|
+
this.#calls.set(call.callId, "settled");
|
|
183
|
+
this.#forget(call);
|
|
184
|
+
}
|
|
185
|
+
#forget(call) {
|
|
186
|
+
const timer = setTimeout(() => this.#calls.delete(call.callId), Math.max(0, Date.parse(call.deadlineAt) - Date.now()) + SETTLED_MEMORY_MS);
|
|
187
|
+
timer.unref?.();
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=client-tool-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-tool-executor.js","sourceRoot":"","sources":["../src/client-tool-executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { HttpClient } from "./http.js";
|
|
2
|
+
import type { RequestOptions } from "./organization.js";
|
|
3
|
+
export interface ClientToolDeclaration {
|
|
4
|
+
type: "function";
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
parameters: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
export interface ClientToolSet {
|
|
10
|
+
revision: number;
|
|
11
|
+
tools: ClientToolDeclaration[];
|
|
12
|
+
/** Pass this exact value when replacing the complete set. */
|
|
13
|
+
etag: string;
|
|
14
|
+
}
|
|
15
|
+
export interface ReplaceClientToolsOptions extends RequestOptions {
|
|
16
|
+
ifMatch: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function validateClientTools(tools: readonly ClientToolDeclaration[]): void;
|
|
19
|
+
export declare function getClientTools(http: HttpClient, sessionId: string, options?: RequestOptions): Promise<ClientToolSet>;
|
|
20
|
+
export declare function replaceClientTools(http: HttpClient, sessionId: string, tools: readonly ClientToolDeclaration[], options: ReplaceClientToolsOptions): Promise<ClientToolSet>;
|
|
21
|
+
//# sourceMappingURL=client-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-tools.d.ts","sourceRoot":"","sources":["../src/client-tools.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,UAAU,EAKX,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,qBAAqB,EAAE,CAAC;IAC/B,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,yBAA0B,SAAQ,cAAc;IAC/D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,SAAS,qBAAqB,EAAE,GACtC,IAAI,CAuBN;AAkBD,wBAAsB,cAAc,CAClC,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,aAAa,CAAC,CAQxB;AAED,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,SAAS,qBAAqB,EAAE,EACvC,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,aAAa,CAAC,CAqBxB"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { requireInteraction } from "./history.js";
|
|
2
|
+
import { OutcomeUnknownError, TiDBLinkError } from "./errors.js";
|
|
3
|
+
import { HttpClient, requireEtag, requireKnownKeys, requireCreationKey, } from "./http.js";
|
|
4
|
+
export function validateClientTools(tools) {
|
|
5
|
+
if (!Array.isArray(tools) || tools.length > 64)
|
|
6
|
+
throw new TypeError("tools must be an array of at most 64 declarations");
|
|
7
|
+
for (const tool of tools) {
|
|
8
|
+
requireKnownKeys(tool, ["type", "name", "description", "parameters"], "Client Tool declaration");
|
|
9
|
+
if (tool.type !== "function" ||
|
|
10
|
+
typeof tool.name !== "string" ||
|
|
11
|
+
!tool.name ||
|
|
12
|
+
typeof tool.description !== "string" ||
|
|
13
|
+
!tool.description ||
|
|
14
|
+
typeof tool.parameters !== "object" ||
|
|
15
|
+
tool.parameters === null ||
|
|
16
|
+
Array.isArray(tool.parameters))
|
|
17
|
+
throw new TypeError("Client Tools require a function name, description and JSON Schema parameters");
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const toolSet = (result) => {
|
|
21
|
+
if (!Number.isSafeInteger(result.data?.revision) ||
|
|
22
|
+
result.data.revision < 0 ||
|
|
23
|
+
!Array.isArray(result.data.tools))
|
|
24
|
+
throw new TiDBLinkError("TiDB Link returned an invalid Client Tool set", {
|
|
25
|
+
requestId: result.requestId,
|
|
26
|
+
});
|
|
27
|
+
return { ...result.data, etag: requireEtag(result) };
|
|
28
|
+
};
|
|
29
|
+
const toolsPath = (sessionId) => `/sessions/${encodeURIComponent(sessionId)}/tools`;
|
|
30
|
+
export async function getClientTools(http, sessionId, options) {
|
|
31
|
+
if (options)
|
|
32
|
+
requireKnownKeys(options, ["signal", "requestId"], "Client Tool read options");
|
|
33
|
+
return toolSet(await http.getResponse(toolsPath(sessionId), options));
|
|
34
|
+
}
|
|
35
|
+
export async function replaceClientTools(http, sessionId, tools, options) {
|
|
36
|
+
validateClientTools(tools);
|
|
37
|
+
requireKnownKeys(options, ["ifMatch", "signal", "requestId"], "Client Tool replacement options");
|
|
38
|
+
if (typeof options.ifMatch !== "string" || !options.ifMatch)
|
|
39
|
+
throw new TypeError("Client Tool replacement requires ifMatch");
|
|
40
|
+
const result = await http.response(toolsPath(sessionId), { method: "PUT", body: { tools }, outcomeUnknown: true, ...options });
|
|
41
|
+
try {
|
|
42
|
+
return toolSet(result);
|
|
43
|
+
}
|
|
44
|
+
catch (cause) {
|
|
45
|
+
throw new OutcomeUnknownError("Client Tool replacement returned no usable receipt; read the current set before retrying", { sessionId, requestId: result.requestId, cause });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=client-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-tools.js","sourceRoot":"","sources":["../src/client-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { TiDBLinkError } from "./errors.js";
|
|
2
|
+
import type { FetchFunction } from "./http.js";
|
|
3
|
+
export declare const CONNECTOR_CALLBACK_ISSUER = "tidb-link/connector-callback/v1";
|
|
4
|
+
export declare const CONNECTOR_CALLBACK_AUDIENCE = "tidb-link/connector";
|
|
5
|
+
/** The `params._meta` key of the Call Context on every Connector `tools/call`. */
|
|
6
|
+
export declare const CONNECTOR_CALL_CONTEXT_KEY = "tidb-link/context";
|
|
7
|
+
/** A public Ed25519 key that signs Connector callback tokens. */
|
|
8
|
+
export interface ConnectorVerificationKey {
|
|
9
|
+
kty: "OKP";
|
|
10
|
+
crv: "Ed25519";
|
|
11
|
+
x: string;
|
|
12
|
+
kid: string;
|
|
13
|
+
alg: "EdDSA";
|
|
14
|
+
use: "sig";
|
|
15
|
+
}
|
|
16
|
+
/** The verified claims of a Connector callback token. */
|
|
17
|
+
export interface ConnectorCallbackClaims {
|
|
18
|
+
iss: typeof CONNECTOR_CALLBACK_ISSUER;
|
|
19
|
+
aud: typeof CONNECTOR_CALLBACK_AUDIENCE;
|
|
20
|
+
organizationId: string;
|
|
21
|
+
connectorId: string;
|
|
22
|
+
iat: number;
|
|
23
|
+
exp: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Who a Connector tool call is for, written by the platform from the
|
|
27
|
+
* Session's persisted owner. Model arguments cannot override it.
|
|
28
|
+
*/
|
|
29
|
+
export interface ConnectorCallContext {
|
|
30
|
+
/** Globally unique; deduplicate side effects by it. */
|
|
31
|
+
callId: string;
|
|
32
|
+
sessionId: string;
|
|
33
|
+
organizationId: string;
|
|
34
|
+
/** The Session owner's End User ID. Map it to your own account. */
|
|
35
|
+
userId: string;
|
|
36
|
+
/** When the platform stops waiting. Abandon the work after it. */
|
|
37
|
+
deadline: string;
|
|
38
|
+
/** Always 1: the platform never retries a call. */
|
|
39
|
+
attempt: 1;
|
|
40
|
+
}
|
|
41
|
+
/** A Connector callback was refused: bad signature, wrong scope or expired. */
|
|
42
|
+
export declare class ConnectorAuthError extends TiDBLinkError {
|
|
43
|
+
}
|
|
44
|
+
export interface ConnectorKeySetOptions {
|
|
45
|
+
/** Your trusted TiDB Link deployment, for example `https://api.example.com`. */
|
|
46
|
+
baseUrl: string;
|
|
47
|
+
fetch?: FetchFunction;
|
|
48
|
+
/** How long fetched keys are reused. Default 10 minutes. */
|
|
49
|
+
maxAgeMs?: number;
|
|
50
|
+
/** Minimum time between refreshes for an unknown key ID. Default 30 seconds. */
|
|
51
|
+
minRefreshIntervalMs?: number;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Caches the deployment's public verification keys from
|
|
55
|
+
* `GET /api/v1/connectors/jwks`. Fetch keys only from your trusted deployment
|
|
56
|
+
* URL, never from a URL a token names.
|
|
57
|
+
*/
|
|
58
|
+
export declare class ConnectorKeySet {
|
|
59
|
+
#private;
|
|
60
|
+
constructor(options: ConnectorKeySetOptions);
|
|
61
|
+
/** The key for `kid`, refreshing the cache when it is stale or the key is new. */
|
|
62
|
+
key(kid: string): Promise<CryptoKey | undefined>;
|
|
63
|
+
/** Fetch the keys now. Concurrent callers share one request. */
|
|
64
|
+
refresh(): Promise<void>;
|
|
65
|
+
}
|
|
66
|
+
export interface VerifyConnectorCallbackOptions {
|
|
67
|
+
keys: ConnectorKeySet;
|
|
68
|
+
/** Your Organization; tokens for another are refused. */
|
|
69
|
+
organizationId: string;
|
|
70
|
+
/** This Connector; tokens for another are refused. */
|
|
71
|
+
connectorId: string;
|
|
72
|
+
/** Allowed clock difference with the platform. Default 5 seconds. */
|
|
73
|
+
clockToleranceSec?: number;
|
|
74
|
+
/** Override the current time, in milliseconds since the epoch. */
|
|
75
|
+
now?: number;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Verify the `Authorization` header of a request the platform sends to your
|
|
79
|
+
* HTTP Connector (initialization, tool discovery and tool calls). Returns the
|
|
80
|
+
* claims, or throws ConnectorAuthError. A token may be reused within its
|
|
81
|
+
* scope until it expires, so verification needs no per-request state.
|
|
82
|
+
*/
|
|
83
|
+
export declare function verifyConnectorCallback(authorization: string | null | undefined, options: VerifyConnectorCallbackOptions): Promise<ConnectorCallbackClaims>;
|
|
84
|
+
/**
|
|
85
|
+
* Read the Call Context from a `tools/call` request's `params._meta`. Throws
|
|
86
|
+
* ConnectorAuthError when it is missing, malformed or for another
|
|
87
|
+
* Organization. Initialization and tool discovery carry no Call Context.
|
|
88
|
+
*/
|
|
89
|
+
export declare function readConnectorCallContext(meta: unknown, options: {
|
|
90
|
+
organizationId: string;
|
|
91
|
+
}): ConnectorCallContext;
|
|
92
|
+
//# sourceMappingURL=connector-callback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector-callback.d.ts","sourceRoot":"","sources":["../src/connector-callback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C,eAAO,MAAM,yBAAyB,oCAAoC,CAAC;AAC3E,eAAO,MAAM,2BAA2B,wBAAwB,CAAC;AACjE,kFAAkF;AAClF,eAAO,MAAM,0BAA0B,sBAAsB,CAAC;AAE9D,iEAAiE;AACjE,MAAM,WAAW,wBAAwB;IACvC,GAAG,EAAE,KAAK,CAAC;IACX,GAAG,EAAE,SAAS,CAAC;IACf,CAAC,EAAE,MAAM,CAAC;IACV,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,KAAK,CAAC;CACZ;AAED,yDAAyD;AACzD,MAAM,WAAW,uBAAuB;IACtC,GAAG,EAAE,OAAO,yBAAyB,CAAC;IACtC,GAAG,EAAE,OAAO,2BAA2B,CAAC;IACxC,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,OAAO,EAAE,CAAC,CAAC;CACZ;AAED,+EAA+E;AAC/E,qBAAa,kBAAmB,SAAQ,aAAa;CAAG;AAExD,MAAM,WAAW,sBAAsB;IACrC,gFAAgF;IAChF,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gFAAgF;IAChF,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;;;GAIG;AACH,qBAAa,eAAe;;gBASd,OAAO,EAAE,sBAAsB;IAU3C,kFAAkF;IAC5E,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAUtD,gEAAgE;IAChE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAmDzB;AAED,MAAM,WAAW,8BAA8B;IAC7C,IAAI,EAAE,eAAe,CAAC;IACtB,yDAAyD;IACzD,cAAc,EAAE,MAAM,CAAC;IACvB,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kEAAkE;IAClE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAaD;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACxC,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,uBAAuB,CAAC,CAuDlC;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,OAAO,EACb,OAAO,EAAE;IAAE,cAAc,EAAE,MAAM,CAAA;CAAE,GAClC,oBAAoB,CAkBtB"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { TiDBLinkError } from "./errors.js";
|
|
2
|
+
export const CONNECTOR_CALLBACK_ISSUER = "tidb-link/connector-callback/v1";
|
|
3
|
+
export const CONNECTOR_CALLBACK_AUDIENCE = "tidb-link/connector";
|
|
4
|
+
/** The `params._meta` key of the Call Context on every Connector `tools/call`. */
|
|
5
|
+
export const CONNECTOR_CALL_CONTEXT_KEY = "tidb-link/context";
|
|
6
|
+
/** A Connector callback was refused: bad signature, wrong scope or expired. */
|
|
7
|
+
export class ConnectorAuthError extends TiDBLinkError {
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Caches the deployment's public verification keys from
|
|
11
|
+
* `GET /api/v1/connectors/jwks`. Fetch keys only from your trusted deployment
|
|
12
|
+
* URL, never from a URL a token names.
|
|
13
|
+
*/
|
|
14
|
+
export class ConnectorKeySet {
|
|
15
|
+
#url;
|
|
16
|
+
#fetch;
|
|
17
|
+
#maxAgeMs;
|
|
18
|
+
#minRefreshIntervalMs;
|
|
19
|
+
#keys = new Map();
|
|
20
|
+
#fetchedAt = -Infinity;
|
|
21
|
+
#loading;
|
|
22
|
+
constructor(options) {
|
|
23
|
+
const base = new URL(options.baseUrl);
|
|
24
|
+
if (base.protocol !== "https:" && base.protocol !== "http:")
|
|
25
|
+
throw new TypeError("baseUrl must be an HTTP(S) URL");
|
|
26
|
+
this.#url = new URL("/api/v1/connectors/jwks", base);
|
|
27
|
+
this.#fetch = options.fetch ?? ((url, init) => fetch(url, init));
|
|
28
|
+
this.#maxAgeMs = options.maxAgeMs ?? 600_000;
|
|
29
|
+
this.#minRefreshIntervalMs = options.minRefreshIntervalMs ?? 30_000;
|
|
30
|
+
}
|
|
31
|
+
/** The key for `kid`, refreshing the cache when it is stale or the key is new. */
|
|
32
|
+
async key(kid) {
|
|
33
|
+
const age = Date.now() - this.#fetchedAt;
|
|
34
|
+
if (age > this.#maxAgeMs ||
|
|
35
|
+
(!this.#keys.has(kid) && age > this.#minRefreshIntervalMs))
|
|
36
|
+
await this.refresh();
|
|
37
|
+
return this.#keys.get(kid);
|
|
38
|
+
}
|
|
39
|
+
/** Fetch the keys now. Concurrent callers share one request. */
|
|
40
|
+
refresh() {
|
|
41
|
+
this.#loading ??= this.#load().finally(() => {
|
|
42
|
+
this.#loading = undefined;
|
|
43
|
+
});
|
|
44
|
+
return this.#loading;
|
|
45
|
+
}
|
|
46
|
+
async #load() {
|
|
47
|
+
let response;
|
|
48
|
+
try {
|
|
49
|
+
response = await this.#fetch(this.#url, {
|
|
50
|
+
headers: { accept: "application/json" },
|
|
51
|
+
redirect: "error",
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
catch (cause) {
|
|
55
|
+
throw new TiDBLinkError("Connector verification keys are unreachable", { cause });
|
|
56
|
+
}
|
|
57
|
+
if (!response.ok) {
|
|
58
|
+
await response.body?.cancel();
|
|
59
|
+
throw new TiDBLinkError(`Connector verification keys are unavailable (status ${response.status})`);
|
|
60
|
+
}
|
|
61
|
+
const body = (await response.json());
|
|
62
|
+
if (!Array.isArray(body?.keys))
|
|
63
|
+
throw new TiDBLinkError("Connector verification keys are malformed");
|
|
64
|
+
const keys = new Map();
|
|
65
|
+
for (const key of body.keys) {
|
|
66
|
+
if (key?.kty !== "OKP" ||
|
|
67
|
+
key.crv !== "Ed25519" ||
|
|
68
|
+
key.alg !== "EdDSA" ||
|
|
69
|
+
key.use !== "sig" ||
|
|
70
|
+
typeof key.kid !== "string" ||
|
|
71
|
+
typeof key.x !== "string")
|
|
72
|
+
continue;
|
|
73
|
+
keys.set(key.kid, await crypto.subtle.importKey("jwk", { kty: "OKP", crv: "Ed25519", x: key.x }, { name: "Ed25519" }, false, ["verify"]));
|
|
74
|
+
}
|
|
75
|
+
this.#keys = keys;
|
|
76
|
+
this.#fetchedAt = Date.now();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const base64UrlBytes = (part) => Uint8Array.from(atob(part.replace(/-/g, "+").replace(/_/g, "/")), (c) => c.charCodeAt(0));
|
|
80
|
+
const decodeJson = (part) => {
|
|
81
|
+
const value = JSON.parse(new TextDecoder().decode(base64UrlBytes(part)));
|
|
82
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
83
|
+
throw new Error("not an object");
|
|
84
|
+
return value;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Verify the `Authorization` header of a request the platform sends to your
|
|
88
|
+
* HTTP Connector (initialization, tool discovery and tool calls). Returns the
|
|
89
|
+
* claims, or throws ConnectorAuthError. A token may be reused within its
|
|
90
|
+
* scope until it expires, so verification needs no per-request state.
|
|
91
|
+
*/
|
|
92
|
+
export async function verifyConnectorCallback(authorization, options) {
|
|
93
|
+
const refuse = (reason) => {
|
|
94
|
+
throw new ConnectorAuthError(`Connector callback refused: ${reason}`);
|
|
95
|
+
};
|
|
96
|
+
const bearer = /^Bearer ([A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+)$/i.exec(authorization ?? "");
|
|
97
|
+
if (!bearer)
|
|
98
|
+
return refuse("missing or malformed bearer token");
|
|
99
|
+
const [headerPart, payloadPart, signaturePart] = bearer[1].split(".");
|
|
100
|
+
let header;
|
|
101
|
+
let claims;
|
|
102
|
+
try {
|
|
103
|
+
header = decodeJson(headerPart);
|
|
104
|
+
claims = decodeJson(payloadPart);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return refuse("undecodable token");
|
|
108
|
+
}
|
|
109
|
+
if (header.alg !== "EdDSA" || typeof header.kid !== "string")
|
|
110
|
+
return refuse("unsupported algorithm");
|
|
111
|
+
const key = await options.keys.key(header.kid);
|
|
112
|
+
if (!key)
|
|
113
|
+
return refuse("unknown signing key");
|
|
114
|
+
const valid = await crypto.subtle.verify({ name: "Ed25519" }, key, base64UrlBytes(signaturePart), new TextEncoder().encode(`${headerPart}.${payloadPart}`));
|
|
115
|
+
if (!valid)
|
|
116
|
+
return refuse("invalid signature");
|
|
117
|
+
const now = (options.now ?? Date.now()) / 1000;
|
|
118
|
+
const tolerance = options.clockToleranceSec ?? 5;
|
|
119
|
+
const { iat, exp } = claims;
|
|
120
|
+
if (claims.iss !== CONNECTOR_CALLBACK_ISSUER ||
|
|
121
|
+
claims.aud !== CONNECTOR_CALLBACK_AUDIENCE)
|
|
122
|
+
return refuse("wrong issuer or audience");
|
|
123
|
+
if (claims.organizationId !== options.organizationId ||
|
|
124
|
+
claims.connectorId !== options.connectorId)
|
|
125
|
+
return refuse("issued for another Organization or Connector");
|
|
126
|
+
if (!Number.isSafeInteger(iat) ||
|
|
127
|
+
!Number.isSafeInteger(exp) ||
|
|
128
|
+
exp <= iat ||
|
|
129
|
+
exp - iat > 60 ||
|
|
130
|
+
iat > now + tolerance ||
|
|
131
|
+
exp <= now - tolerance)
|
|
132
|
+
return refuse("expired or not yet valid");
|
|
133
|
+
return claims;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Read the Call Context from a `tools/call` request's `params._meta`. Throws
|
|
137
|
+
* ConnectorAuthError when it is missing, malformed or for another
|
|
138
|
+
* Organization. Initialization and tool discovery carry no Call Context.
|
|
139
|
+
*/
|
|
140
|
+
export function readConnectorCallContext(meta, options) {
|
|
141
|
+
const context = meta?.[CONNECTOR_CALL_CONTEXT_KEY];
|
|
142
|
+
const text = (value) => typeof value === "string" && value.length > 0;
|
|
143
|
+
if (!context ||
|
|
144
|
+
!text(context.callId) ||
|
|
145
|
+
!text(context.sessionId) ||
|
|
146
|
+
!text(context.userId) ||
|
|
147
|
+
!text(context.deadline) ||
|
|
148
|
+
!Number.isFinite(Date.parse(context.deadline)) ||
|
|
149
|
+
context.attempt !== 1)
|
|
150
|
+
throw new ConnectorAuthError("Connector call has no valid Call Context");
|
|
151
|
+
if (context.organizationId !== options.organizationId)
|
|
152
|
+
throw new ConnectorAuthError("Connector call is for another Organization");
|
|
153
|
+
return context;
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=connector-callback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector-callback.js","sourceRoot":"","sources":["../src/connector-callback.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { HttpClient } from "./http.js";
|
|
2
|
+
import type { RequestOptions } from "./organization.js";
|
|
3
|
+
export type ConnectorTransport = "streamable_http" | "tunnel";
|
|
4
|
+
/** An Organization-owned MCP tool server that Agents can call. */
|
|
5
|
+
export interface Connector {
|
|
6
|
+
connectorId: string;
|
|
7
|
+
organizationId: string;
|
|
8
|
+
displayName: string;
|
|
9
|
+
/** The HTTPS MCP endpoint of a `streamable_http` Connector. */
|
|
10
|
+
endpointUrl: string;
|
|
11
|
+
endpointVersion: number;
|
|
12
|
+
transport: ConnectorTransport;
|
|
13
|
+
status: "inactive" | "active";
|
|
14
|
+
/** Pass this as `expectedConnectorVersion` to change the registration. */
|
|
15
|
+
connectorVersion: number;
|
|
16
|
+
createdAt: string;
|
|
17
|
+
updatedAt: string;
|
|
18
|
+
/** What activation discovered at the endpoint. */
|
|
19
|
+
observation?: {
|
|
20
|
+
era: "modern" | "legacy";
|
|
21
|
+
protocolVersion: string;
|
|
22
|
+
endpointVersion: number;
|
|
23
|
+
probedAt: string;
|
|
24
|
+
expiresAt: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export interface RegisterConnectorInput extends RequestOptions {
|
|
28
|
+
/** Unique within the Organization. */
|
|
29
|
+
displayName: string;
|
|
30
|
+
/** Defaults to `streamable_http`. */
|
|
31
|
+
transport?: ConnectorTransport;
|
|
32
|
+
/** Required for `streamable_http`: an HTTPS URL without credentials. */
|
|
33
|
+
endpointUrl?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface UpdateConnectorInput {
|
|
36
|
+
displayName?: string;
|
|
37
|
+
endpointUrl?: string;
|
|
38
|
+
}
|
|
39
|
+
export interface ConnectorVersionOptions extends RequestOptions {
|
|
40
|
+
/** The `connectorVersion` you read. A changed registration is refused with ConflictError. */
|
|
41
|
+
expectedConnectorVersion: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Organization Connector registrations. Register a Connector, then activate
|
|
45
|
+
* it: activation connects to the endpoint and discovers its tools. Edit only
|
|
46
|
+
* an inactive Connector.
|
|
47
|
+
*/
|
|
48
|
+
export declare class Connectors {
|
|
49
|
+
#private;
|
|
50
|
+
constructor(http: HttpClient);
|
|
51
|
+
list(options?: RequestOptions): Promise<Connector[]>;
|
|
52
|
+
get(connectorId: string, options?: RequestOptions): Promise<Connector>;
|
|
53
|
+
/**
|
|
54
|
+
* Register an inactive Connector. Registration is not retried; after an
|
|
55
|
+
* OutcomeUnknownError, list the Connectors and match the display name, which
|
|
56
|
+
* is unique in the Organization.
|
|
57
|
+
*/
|
|
58
|
+
register(input: RegisterConnectorInput): Promise<Connector>;
|
|
59
|
+
/** Edit an inactive Connector. */
|
|
60
|
+
update(connectorId: string, input: UpdateConnectorInput, options: ConnectorVersionOptions): Promise<Connector>;
|
|
61
|
+
/** Discover the endpoint's tools and activate the Connector. */
|
|
62
|
+
activate(connectorId: string, options: ConnectorVersionOptions): Promise<Connector>;
|
|
63
|
+
/** Stop new calls to the Connector. */
|
|
64
|
+
deactivate(connectorId: string, options: ConnectorVersionOptions): Promise<Connector>;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=connectors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connectors.d.ts","sourceRoot":"","sources":["../src/connectors.ts"],"names":[],"mappings":"AACA,OAAO,EACL,UAAU,EAIX,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,GAAG,QAAQ,CAAC;AAE9D,kEAAkE;AAClE,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,kBAAkB,CAAC;IAC9B,MAAM,EAAE,UAAU,GAAG,QAAQ,CAAC;IAC9B,0EAA0E;IAC1E,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,WAAW,CAAC,EAAE;QACZ,GAAG,EAAE,QAAQ,GAAG,QAAQ,CAAC;QACzB,eAAe,EAAE,MAAM,CAAC;QACxB,eAAe,EAAE,MAAM,CAAC;QACxB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,sBAAuB,SAAQ,cAAc;IAC5D,sCAAsC;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,qCAAqC;IACrC,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,uBAAwB,SAAQ,cAAc;IAC7D,6FAA6F;IAC7F,wBAAwB,EAAE,MAAM,CAAC;CAClC;AA0BD;;;;GAIG;AACH,qBAAa,UAAU;;gBAGT,IAAI,EAAE,UAAU;IAItB,IAAI,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAQ1D,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC;IAItE;;;;OAIG;IACG,QAAQ,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,SAAS,CAAC;IAkBjE,kCAAkC;IAC5B,MAAM,CACV,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,oBAAoB,EAC3B,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,SAAS,CAAC;IAarB,gEAAgE;IAChE,QAAQ,CACN,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,SAAS,CAAC;IAIrB,uCAAuC;IACvC,UAAU,CACR,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,SAAS,CAAC;CAoBtB"}
|