@vertesia/tools-sdk 0.78.0-dev-28b447d → 0.79.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/lib/cjs/ToolCollection.js +96 -0
- package/lib/cjs/ToolCollection.js.map +1 -0
- package/lib/cjs/ToolRegistry.js +44 -0
- package/lib/cjs/ToolRegistry.js.map +1 -0
- package/lib/cjs/auth.js +84 -0
- package/lib/cjs/auth.js.map +1 -0
- package/lib/cjs/build/validate.js +7 -0
- package/lib/cjs/build/validate.js.map +1 -0
- package/lib/cjs/index.js +24 -0
- package/lib/cjs/index.js.map +1 -0
- package/lib/cjs/package.json +3 -0
- package/lib/cjs/types.js +3 -0
- package/lib/cjs/types.js.map +1 -0
- package/lib/esm/ToolCollection.js +92 -0
- package/lib/esm/ToolCollection.js.map +1 -0
- package/lib/esm/ToolRegistry.js +39 -0
- package/lib/esm/ToolRegistry.js.map +1 -0
- package/lib/esm/auth.js +77 -0
- package/lib/esm/auth.js.map +1 -0
- package/lib/esm/build/validate.js +4 -0
- package/lib/esm/build/validate.js.map +1 -0
- package/lib/esm/index.js +5 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/types.js +2 -0
- package/lib/esm/types.js.map +1 -0
- package/lib/types/ToolCollection.d.ts +74 -0
- package/lib/types/ToolCollection.d.ts.map +1 -0
- package/lib/types/ToolRegistry.d.ts +15 -0
- package/lib/types/ToolRegistry.d.ts.map +1 -0
- package/lib/types/auth.d.ts +20 -0
- package/lib/types/auth.d.ts.map +1 -0
- package/lib/types/build/validate.d.ts +2 -0
- package/lib/types/build/validate.d.ts.map +1 -0
- package/lib/types/index.d.ts +5 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/types.d.ts +88 -0
- package/lib/types/types.d.ts.map +1 -0
- package/package.json +37 -42
- package/src/ToolCollection.ts +1 -1
- package/src/auth.ts +7 -12
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ToolCollection = void 0;
|
|
4
|
+
const http_exception_1 = require("hono/http-exception");
|
|
5
|
+
const auth_js_1 = require("./auth.js");
|
|
6
|
+
const ToolRegistry_js_1 = require("./ToolRegistry.js");
|
|
7
|
+
/**
|
|
8
|
+
* Implements a tools collection endpoint
|
|
9
|
+
*/
|
|
10
|
+
class ToolCollection {
|
|
11
|
+
/**
|
|
12
|
+
* A kebab case collection name. Must only contains alphanumeric and dash characters,
|
|
13
|
+
* The name can be used to generate the path where the collection is exposed.
|
|
14
|
+
* Example: my-collection
|
|
15
|
+
*/
|
|
16
|
+
name;
|
|
17
|
+
/**
|
|
18
|
+
* Optional title for UI display.
|
|
19
|
+
* If not provided the title will be generated form the kebab case name by replacing - with spaces and upper casing first letter in words.
|
|
20
|
+
*/
|
|
21
|
+
title;
|
|
22
|
+
/**
|
|
23
|
+
* Optional icon for UI display
|
|
24
|
+
*/
|
|
25
|
+
icon;
|
|
26
|
+
/**
|
|
27
|
+
* A short description
|
|
28
|
+
*/
|
|
29
|
+
description;
|
|
30
|
+
/**
|
|
31
|
+
* The tool registry
|
|
32
|
+
*/
|
|
33
|
+
tools;
|
|
34
|
+
constructor({ name, title, icon, description, tools }) {
|
|
35
|
+
this.name = name;
|
|
36
|
+
this.title = title || kebabCaseToTitle(name);
|
|
37
|
+
this.icon = icon;
|
|
38
|
+
this.description = description;
|
|
39
|
+
this.tools = new ToolRegistry_js_1.ToolRegistry(tools);
|
|
40
|
+
}
|
|
41
|
+
[Symbol.iterator]() {
|
|
42
|
+
let index = 0;
|
|
43
|
+
const tools = this.tools.getTools();
|
|
44
|
+
return {
|
|
45
|
+
next() {
|
|
46
|
+
if (index < tools.length) {
|
|
47
|
+
return { value: tools[index++], done: false };
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
return { done: true, value: undefined };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
map(callback) {
|
|
56
|
+
return this.tools.getTools().map(callback);
|
|
57
|
+
}
|
|
58
|
+
async execute(ctx) {
|
|
59
|
+
let payload;
|
|
60
|
+
try {
|
|
61
|
+
payload = await readPayload(ctx);
|
|
62
|
+
const session = await (0, auth_js_1.authorize)(ctx);
|
|
63
|
+
const r = await this.tools.runTool(payload, session);
|
|
64
|
+
return ctx.json({
|
|
65
|
+
...r,
|
|
66
|
+
tool_use_id: payload.tool_use.id
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
catch (err) { // HTTPException ?
|
|
70
|
+
const status = err.status || 500;
|
|
71
|
+
return ctx.json({
|
|
72
|
+
tool_use_id: payload?.tool_use.id || "undefined",
|
|
73
|
+
error: err.message || "Error executing tool",
|
|
74
|
+
status
|
|
75
|
+
}, status);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
getToolDefinitions() {
|
|
79
|
+
return this.tools.getDefinitions();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
exports.ToolCollection = ToolCollection;
|
|
83
|
+
async function readPayload(ctx) {
|
|
84
|
+
try {
|
|
85
|
+
return await ctx.req.json();
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
throw new http_exception_1.HTTPException(500, {
|
|
89
|
+
message: "Failed to load execution request payload: " + err.message
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function kebabCaseToTitle(name) {
|
|
94
|
+
return name.split('-').map(p => p[0].toUpperCase() + p.substring(1)).join(' ');
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=ToolCollection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToolCollection.js","sourceRoot":"","sources":["../../src/ToolCollection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ToolNotFoundError = exports.ToolRegistry = void 0;
|
|
4
|
+
const http_exception_1 = require("hono/http-exception");
|
|
5
|
+
class ToolRegistry {
|
|
6
|
+
registry = {};
|
|
7
|
+
constructor(tools = []) {
|
|
8
|
+
for (const tool of tools) {
|
|
9
|
+
this.registry[tool.name] = tool;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
getDefinitions() {
|
|
13
|
+
return Object.values(this.registry).map(tool => ({
|
|
14
|
+
name: tool.name,
|
|
15
|
+
description: tool.description,
|
|
16
|
+
input_schema: tool.input_schema
|
|
17
|
+
}));
|
|
18
|
+
}
|
|
19
|
+
getTool(name) {
|
|
20
|
+
const tool = this.registry[name];
|
|
21
|
+
if (tool === undefined) {
|
|
22
|
+
throw new ToolNotFoundError(name);
|
|
23
|
+
}
|
|
24
|
+
return tool;
|
|
25
|
+
}
|
|
26
|
+
getTools() {
|
|
27
|
+
return Object.values(this.registry);
|
|
28
|
+
}
|
|
29
|
+
registerTool(tool) {
|
|
30
|
+
this.registry[tool.name] = tool;
|
|
31
|
+
}
|
|
32
|
+
runTool(payload, context) {
|
|
33
|
+
return this.getTool(payload.tool_use.tool_name).run(payload, context);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.ToolRegistry = ToolRegistry;
|
|
37
|
+
class ToolNotFoundError extends http_exception_1.HTTPException {
|
|
38
|
+
constructor(name) {
|
|
39
|
+
super(404, { message: "Tool function not found: " + name });
|
|
40
|
+
this.name = "ToolNotFoundError";
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.ToolNotFoundError = ToolNotFoundError;
|
|
44
|
+
//# sourceMappingURL=ToolRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToolRegistry.js","sourceRoot":"","sources":["../../src/ToolRegistry.ts"],"names":[],"mappings":";;;AAAA,wDAAoD;AAEpD,MAAa,YAAY;IAErB,QAAQ,GAA8B,EAAE,CAAC;IAEzC,YAAY,QAAqB,EAAE;QAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QACpC,CAAC;IACL,CAAC;IAED,cAAc;QACV,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC7C,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,YAAY,EAAE,IAAI,CAAC,YAAY;SAClC,CAAC,CAAC,CAAC;IACR,CAAC;IAED,OAAO,CAAsC,IAAY;QACrD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;QAChC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACrB,MAAM,IAAI,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,QAAQ;QACJ,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,YAAY,CAAsC,IAAmB;QACjE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACpC,CAAC;IAED,OAAO,CAAsC,OAAsC,EAAE,OAA6B;QAC9G,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC1E,CAAC;CAEJ;AAtCD,oCAsCC;AAGD,MAAa,iBAAkB,SAAQ,8BAAa;IAChD,YAAY,IAAY;QACpB,KAAK,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,2BAA2B,GAAG,IAAI,EAAE,CAAC,CAAC;QAC5D,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IACpC,CAAC;CACJ;AALD,8CAKC"}
|
package/lib/cjs/auth.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AuthSession = void 0;
|
|
4
|
+
exports.getJwks = getJwks;
|
|
5
|
+
exports.verifyToken = verifyToken;
|
|
6
|
+
exports.authorize = authorize;
|
|
7
|
+
const client_1 = require("@vertesia/client");
|
|
8
|
+
const http_exception_1 = require("hono/http-exception");
|
|
9
|
+
const jose_1 = require("jose");
|
|
10
|
+
const cache = {};
|
|
11
|
+
async function getJwks(url) {
|
|
12
|
+
if (!cache.url) {
|
|
13
|
+
console.log('JWKS cache miss for: ', url);
|
|
14
|
+
const jwks = await fetch(url).then(r => {
|
|
15
|
+
if (r.ok) {
|
|
16
|
+
return r.json();
|
|
17
|
+
}
|
|
18
|
+
throw new Error("Fetching jwks failed with code: " + r.status);
|
|
19
|
+
}).catch(err => {
|
|
20
|
+
throw new Error("Failed to fetch jwks: " + err.message);
|
|
21
|
+
});
|
|
22
|
+
cache.url = (0, jose_1.createLocalJWKSet)(jwks);
|
|
23
|
+
}
|
|
24
|
+
return cache.url;
|
|
25
|
+
}
|
|
26
|
+
async function verifyToken(token) {
|
|
27
|
+
const decodedJwt = (0, jose_1.decodeJwt)(token);
|
|
28
|
+
const { studio } = (0, client_1.decodeEndpoints)(decodedJwt.endpoints);
|
|
29
|
+
if (!studio) {
|
|
30
|
+
throw new Error("No studio endpoint found in JWT");
|
|
31
|
+
}
|
|
32
|
+
const jwks = await getJwks(`${studio}/.well-known/jwks`);
|
|
33
|
+
return await (0, jose_1.jwtVerify)(token, jwks);
|
|
34
|
+
}
|
|
35
|
+
async function authorize(ctx) {
|
|
36
|
+
const auth = ctx.req.header('Authorization');
|
|
37
|
+
if (!auth) {
|
|
38
|
+
throw new http_exception_1.HTTPException(401, {
|
|
39
|
+
message: `Missing Authorization header'`
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const [scheme, value] = auth.trim().split(' ');
|
|
43
|
+
if (scheme.toLowerCase() !== 'bearer') {
|
|
44
|
+
throw new http_exception_1.HTTPException(401, {
|
|
45
|
+
message: `Authorization scheme ${scheme} is not supported`
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
if (!value) {
|
|
49
|
+
throw new http_exception_1.HTTPException(401, {
|
|
50
|
+
message: `Missing bearer token value`
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
const { payload } = await verifyToken(value);
|
|
55
|
+
const session = new AuthSession(value, payload);
|
|
56
|
+
ctx.set("auth", session);
|
|
57
|
+
return session;
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
throw new http_exception_1.HTTPException(401, {
|
|
61
|
+
message: err.message,
|
|
62
|
+
cause: err
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
class AuthSession {
|
|
67
|
+
token;
|
|
68
|
+
payload;
|
|
69
|
+
_client;
|
|
70
|
+
endpoints;
|
|
71
|
+
constructor(token, payload) {
|
|
72
|
+
this.token = token;
|
|
73
|
+
this.payload = payload;
|
|
74
|
+
this.endpoints = (0, client_1.decodeEndpoints)(payload.endpoints);
|
|
75
|
+
}
|
|
76
|
+
async getClient() {
|
|
77
|
+
if (!this._client) {
|
|
78
|
+
this._client = await client_1.VertesiaClient.fromAuthToken(this.token, this.payload);
|
|
79
|
+
}
|
|
80
|
+
return this._client;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
exports.AuthSession = AuthSession;
|
|
84
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/build/validate.ts"],"names":[],"mappings":";;AAAA,4BAEC;AAFD,SAAgB,QAAQ;IACpB,MAAM;AACV,CAAC"}
|
package/lib/cjs/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.authorize = exports.AuthSession = void 0;
|
|
18
|
+
__exportStar(require("./ToolCollection.js"), exports);
|
|
19
|
+
__exportStar(require("./ToolRegistry.js"), exports);
|
|
20
|
+
__exportStar(require("./types.js"), exports);
|
|
21
|
+
var auth_js_1 = require("./auth.js");
|
|
22
|
+
Object.defineProperty(exports, "AuthSession", { enumerable: true, get: function () { return auth_js_1.AuthSession; } });
|
|
23
|
+
Object.defineProperty(exports, "authorize", { enumerable: true, get: function () { return auth_js_1.authorize; } });
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,sDAAoC;AACpC,oDAAkC;AAClC,6CAA2B;AAC3B,qCAAmD;AAA1C,sGAAA,WAAW,OAAA;AAAE,oGAAA,SAAS,OAAA"}
|
package/lib/cjs/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { HTTPException } from "hono/http-exception";
|
|
2
|
+
import { authorize } from "./auth.js";
|
|
3
|
+
import { ToolRegistry } from "./ToolRegistry.js";
|
|
4
|
+
/**
|
|
5
|
+
* Implements a tools collection endpoint
|
|
6
|
+
*/
|
|
7
|
+
export class ToolCollection {
|
|
8
|
+
/**
|
|
9
|
+
* A kebab case collection name. Must only contains alphanumeric and dash characters,
|
|
10
|
+
* The name can be used to generate the path where the collection is exposed.
|
|
11
|
+
* Example: my-collection
|
|
12
|
+
*/
|
|
13
|
+
name;
|
|
14
|
+
/**
|
|
15
|
+
* Optional title for UI display.
|
|
16
|
+
* If not provided the title will be generated form the kebab case name by replacing - with spaces and upper casing first letter in words.
|
|
17
|
+
*/
|
|
18
|
+
title;
|
|
19
|
+
/**
|
|
20
|
+
* Optional icon for UI display
|
|
21
|
+
*/
|
|
22
|
+
icon;
|
|
23
|
+
/**
|
|
24
|
+
* A short description
|
|
25
|
+
*/
|
|
26
|
+
description;
|
|
27
|
+
/**
|
|
28
|
+
* The tool registry
|
|
29
|
+
*/
|
|
30
|
+
tools;
|
|
31
|
+
constructor({ name, title, icon, description, tools }) {
|
|
32
|
+
this.name = name;
|
|
33
|
+
this.title = title || kebabCaseToTitle(name);
|
|
34
|
+
this.icon = icon;
|
|
35
|
+
this.description = description;
|
|
36
|
+
this.tools = new ToolRegistry(tools);
|
|
37
|
+
}
|
|
38
|
+
[Symbol.iterator]() {
|
|
39
|
+
let index = 0;
|
|
40
|
+
const tools = this.tools.getTools();
|
|
41
|
+
return {
|
|
42
|
+
next() {
|
|
43
|
+
if (index < tools.length) {
|
|
44
|
+
return { value: tools[index++], done: false };
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
return { done: true, value: undefined };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
map(callback) {
|
|
53
|
+
return this.tools.getTools().map(callback);
|
|
54
|
+
}
|
|
55
|
+
async execute(ctx) {
|
|
56
|
+
let payload;
|
|
57
|
+
try {
|
|
58
|
+
payload = await readPayload(ctx);
|
|
59
|
+
const session = await authorize(ctx);
|
|
60
|
+
const r = await this.tools.runTool(payload, session);
|
|
61
|
+
return ctx.json({
|
|
62
|
+
...r,
|
|
63
|
+
tool_use_id: payload.tool_use.id
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
catch (err) { // HTTPException ?
|
|
67
|
+
const status = err.status || 500;
|
|
68
|
+
return ctx.json({
|
|
69
|
+
tool_use_id: payload?.tool_use.id || "undefined",
|
|
70
|
+
error: err.message || "Error executing tool",
|
|
71
|
+
status
|
|
72
|
+
}, status);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
getToolDefinitions() {
|
|
76
|
+
return this.tools.getDefinitions();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async function readPayload(ctx) {
|
|
80
|
+
try {
|
|
81
|
+
return await ctx.req.json();
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
throw new HTTPException(500, {
|
|
85
|
+
message: "Failed to load execution request payload: " + err.message
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function kebabCaseToTitle(name) {
|
|
90
|
+
return name.split('-').map(p => p[0].toUpperCase() + p.substring(1)).join(' ');
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=ToolCollection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToolCollection.js","sourceRoot":"","sources":["../../src/ToolCollection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { HTTPException } from "hono/http-exception";
|
|
2
|
+
export class ToolRegistry {
|
|
3
|
+
registry = {};
|
|
4
|
+
constructor(tools = []) {
|
|
5
|
+
for (const tool of tools) {
|
|
6
|
+
this.registry[tool.name] = tool;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
getDefinitions() {
|
|
10
|
+
return Object.values(this.registry).map(tool => ({
|
|
11
|
+
name: tool.name,
|
|
12
|
+
description: tool.description,
|
|
13
|
+
input_schema: tool.input_schema
|
|
14
|
+
}));
|
|
15
|
+
}
|
|
16
|
+
getTool(name) {
|
|
17
|
+
const tool = this.registry[name];
|
|
18
|
+
if (tool === undefined) {
|
|
19
|
+
throw new ToolNotFoundError(name);
|
|
20
|
+
}
|
|
21
|
+
return tool;
|
|
22
|
+
}
|
|
23
|
+
getTools() {
|
|
24
|
+
return Object.values(this.registry);
|
|
25
|
+
}
|
|
26
|
+
registerTool(tool) {
|
|
27
|
+
this.registry[tool.name] = tool;
|
|
28
|
+
}
|
|
29
|
+
runTool(payload, context) {
|
|
30
|
+
return this.getTool(payload.tool_use.tool_name).run(payload, context);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export class ToolNotFoundError extends HTTPException {
|
|
34
|
+
constructor(name) {
|
|
35
|
+
super(404, { message: "Tool function not found: " + name });
|
|
36
|
+
this.name = "ToolNotFoundError";
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=ToolRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToolRegistry.js","sourceRoot":"","sources":["../../src/ToolRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,OAAO,YAAY;IAErB,QAAQ,GAA8B,EAAE,CAAC;IAEzC,YAAY,QAAqB,EAAE;QAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QACpC,CAAC;IACL,CAAC;IAED,cAAc;QACV,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC7C,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,YAAY,EAAE,IAAI,CAAC,YAAY;SAClC,CAAC,CAAC,CAAC;IACR,CAAC;IAED,OAAO,CAAsC,IAAY;QACrD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;QAChC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACrB,MAAM,IAAI,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,QAAQ;QACJ,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,YAAY,CAAsC,IAAmB;QACjE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACpC,CAAC;IAED,OAAO,CAAsC,OAAsC,EAAE,OAA6B;QAC9G,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC1E,CAAC;CAEJ;AAGD,MAAM,OAAO,iBAAkB,SAAQ,aAAa;IAChD,YAAY,IAAY;QACpB,KAAK,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,2BAA2B,GAAG,IAAI,EAAE,CAAC,CAAC;QAC5D,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IACpC,CAAC;CACJ"}
|
package/lib/esm/auth.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { decodeEndpoints, VertesiaClient } from "@vertesia/client";
|
|
2
|
+
import { HTTPException } from "hono/http-exception";
|
|
3
|
+
import { createLocalJWKSet, decodeJwt, jwtVerify } from "jose";
|
|
4
|
+
const cache = {};
|
|
5
|
+
export async function getJwks(url) {
|
|
6
|
+
if (!cache.url) {
|
|
7
|
+
console.log('JWKS cache miss for: ', url);
|
|
8
|
+
const jwks = await fetch(url).then(r => {
|
|
9
|
+
if (r.ok) {
|
|
10
|
+
return r.json();
|
|
11
|
+
}
|
|
12
|
+
throw new Error("Fetching jwks failed with code: " + r.status);
|
|
13
|
+
}).catch(err => {
|
|
14
|
+
throw new Error("Failed to fetch jwks: " + err.message);
|
|
15
|
+
});
|
|
16
|
+
cache.url = createLocalJWKSet(jwks);
|
|
17
|
+
}
|
|
18
|
+
return cache.url;
|
|
19
|
+
}
|
|
20
|
+
export async function verifyToken(token) {
|
|
21
|
+
const decodedJwt = decodeJwt(token);
|
|
22
|
+
const { studio } = decodeEndpoints(decodedJwt.endpoints);
|
|
23
|
+
if (!studio) {
|
|
24
|
+
throw new Error("No studio endpoint found in JWT");
|
|
25
|
+
}
|
|
26
|
+
const jwks = await getJwks(`${studio}/.well-known/jwks`);
|
|
27
|
+
return await jwtVerify(token, jwks);
|
|
28
|
+
}
|
|
29
|
+
export async function authorize(ctx) {
|
|
30
|
+
const auth = ctx.req.header('Authorization');
|
|
31
|
+
if (!auth) {
|
|
32
|
+
throw new HTTPException(401, {
|
|
33
|
+
message: `Missing Authorization header'`
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
const [scheme, value] = auth.trim().split(' ');
|
|
37
|
+
if (scheme.toLowerCase() !== 'bearer') {
|
|
38
|
+
throw new HTTPException(401, {
|
|
39
|
+
message: `Authorization scheme ${scheme} is not supported`
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
if (!value) {
|
|
43
|
+
throw new HTTPException(401, {
|
|
44
|
+
message: `Missing bearer token value`
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
const { payload } = await verifyToken(value);
|
|
49
|
+
const session = new AuthSession(value, payload);
|
|
50
|
+
ctx.set("auth", session);
|
|
51
|
+
return session;
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
throw new HTTPException(401, {
|
|
55
|
+
message: err.message,
|
|
56
|
+
cause: err
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export class AuthSession {
|
|
61
|
+
token;
|
|
62
|
+
payload;
|
|
63
|
+
_client;
|
|
64
|
+
endpoints;
|
|
65
|
+
constructor(token, payload) {
|
|
66
|
+
this.token = token;
|
|
67
|
+
this.payload = payload;
|
|
68
|
+
this.endpoints = decodeEndpoints(payload.endpoints);
|
|
69
|
+
}
|
|
70
|
+
async getClient() {
|
|
71
|
+
if (!this._client) {
|
|
72
|
+
this._client = await VertesiaClient.fromAuthToken(this.token, this.payload);
|
|
73
|
+
}
|
|
74
|
+
return this._client;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/build/validate.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,QAAQ;IACpB,MAAM;AACV,CAAC"}
|
package/lib/esm/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC"}
|
package/lib/esm/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { Context } from "hono";
|
|
2
|
+
import { ToolRegistry } from "./ToolRegistry.js";
|
|
3
|
+
import type { Tool, ToolDefinition } from "./types.js";
|
|
4
|
+
export interface ToolCollectionProperties {
|
|
5
|
+
/**
|
|
6
|
+
* A kebab case collection name. Must only contains alphanumeric and dash characters,
|
|
7
|
+
* The name can be used to generate the path where the collection is exposed.
|
|
8
|
+
* Example: my-collection
|
|
9
|
+
*/
|
|
10
|
+
name: string;
|
|
11
|
+
/**
|
|
12
|
+
* Optional title for UI display.
|
|
13
|
+
* If not provided the pascal case version of the name will be used
|
|
14
|
+
*/
|
|
15
|
+
title?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Optional icon for UI display
|
|
18
|
+
*/
|
|
19
|
+
icon?: string;
|
|
20
|
+
/**
|
|
21
|
+
* A short description
|
|
22
|
+
*/
|
|
23
|
+
description: string;
|
|
24
|
+
/**
|
|
25
|
+
* The tools
|
|
26
|
+
*/
|
|
27
|
+
tools: Tool<any>[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Implements a tools collection endpoint
|
|
31
|
+
*/
|
|
32
|
+
export declare class ToolCollection implements Iterable<Tool<any>> {
|
|
33
|
+
/**
|
|
34
|
+
* A kebab case collection name. Must only contains alphanumeric and dash characters,
|
|
35
|
+
* The name can be used to generate the path where the collection is exposed.
|
|
36
|
+
* Example: my-collection
|
|
37
|
+
*/
|
|
38
|
+
name: string;
|
|
39
|
+
/**
|
|
40
|
+
* Optional title for UI display.
|
|
41
|
+
* If not provided the title will be generated form the kebab case name by replacing - with spaces and upper casing first letter in words.
|
|
42
|
+
*/
|
|
43
|
+
title?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Optional icon for UI display
|
|
46
|
+
*/
|
|
47
|
+
icon?: string;
|
|
48
|
+
/**
|
|
49
|
+
* A short description
|
|
50
|
+
*/
|
|
51
|
+
description: string;
|
|
52
|
+
/**
|
|
53
|
+
* The tool registry
|
|
54
|
+
*/
|
|
55
|
+
tools: ToolRegistry;
|
|
56
|
+
constructor({ name, title, icon, description, tools }: ToolCollectionProperties);
|
|
57
|
+
[Symbol.iterator](): Iterator<Tool<any>>;
|
|
58
|
+
map<U>(callback: (tool: Tool<any>, index: number) => U): U[];
|
|
59
|
+
execute(ctx: Context): Promise<(Response & import("hono").TypedResponse<{
|
|
60
|
+
tool_use_id: string;
|
|
61
|
+
meta?: {
|
|
62
|
+
[x: string]: any;
|
|
63
|
+
} | undefined;
|
|
64
|
+
content: string;
|
|
65
|
+
is_error: boolean;
|
|
66
|
+
files?: string[] | undefined;
|
|
67
|
+
}, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
|
|
68
|
+
tool_use_id: string;
|
|
69
|
+
error: any;
|
|
70
|
+
status: any;
|
|
71
|
+
}, any, "json">)>;
|
|
72
|
+
getToolDefinitions(): ToolDefinition[];
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=ToolCollection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToolCollection.d.ts","sourceRoot":"","sources":["../../src/ToolCollection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAG/B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,cAAc,EAA2E,MAAM,YAAY,CAAC;AAEhI,MAAM,WAAW,wBAAwB;IACrC;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;CACtB;AAED;;GAEG;AACH,qBAAa,cAAe,YAAW,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEtD;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,KAAK,EAAE,YAAY,CAAC;gBAER,EACR,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EACxC,EAAE,wBAAwB;IAQ3B,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAexC,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,EAAE;IAItD,OAAO,CAAC,GAAG,EAAE,OAAO;;;;;;;;;;;;;IAoB1B,kBAAkB,IAAI,cAAc,EAAE;CAIzC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { HTTPException } from "hono/http-exception";
|
|
2
|
+
import { Tool, ToolDefinition, ToolExecutionContext, ToolExecutionPayload, ToolExecutionResult } from "./types.js";
|
|
3
|
+
export declare class ToolRegistry {
|
|
4
|
+
registry: Record<string, Tool<any>>;
|
|
5
|
+
constructor(tools?: Tool<any>[]);
|
|
6
|
+
getDefinitions(): ToolDefinition[];
|
|
7
|
+
getTool<ParamsT extends Record<string, any>>(name: string): Tool<ParamsT>;
|
|
8
|
+
getTools(): Tool<any>[];
|
|
9
|
+
registerTool<ParamsT extends Record<string, any>>(tool: Tool<ParamsT>): void;
|
|
10
|
+
runTool<ParamsT extends Record<string, any>>(payload: ToolExecutionPayload<ParamsT>, context: ToolExecutionContext): Promise<ToolExecutionResult>;
|
|
11
|
+
}
|
|
12
|
+
export declare class ToolNotFoundError extends HTTPException {
|
|
13
|
+
constructor(name: string);
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=ToolRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToolRegistry.d.ts","sourceRoot":"","sources":["../../src/ToolRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACnH,qBAAa,YAAY;IAErB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAM;gBAE7B,KAAK,GAAE,IAAI,CAAC,GAAG,CAAC,EAAO;IAMnC,cAAc,IAAI,cAAc,EAAE;IAQlC,OAAO,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;IAQzE,QAAQ;IAIR,YAAY,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI;IAI5E,OAAO,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,oBAAoB,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAIpJ;AAGD,qBAAa,iBAAkB,SAAQ,aAAa;gBACpC,IAAI,EAAE,MAAM;CAI3B"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { VertesiaClient } from "@vertesia/client";
|
|
2
|
+
import { AuthTokenPayload } from "@vertesia/common";
|
|
3
|
+
import { Context } from "hono";
|
|
4
|
+
import { JWTVerifyGetKey } from "jose";
|
|
5
|
+
import { ToolExecutionContext } from "./types.js";
|
|
6
|
+
export declare function getJwks(url: string): Promise<JWTVerifyGetKey>;
|
|
7
|
+
export declare function verifyToken(token: string): Promise<import("jose").JWTVerifyResult<AuthTokenPayload> & import("jose").ResolvedKey>;
|
|
8
|
+
export declare function authorize(ctx: Context): Promise<AuthSession>;
|
|
9
|
+
export declare class AuthSession implements ToolExecutionContext {
|
|
10
|
+
token: string;
|
|
11
|
+
payload: AuthTokenPayload;
|
|
12
|
+
_client: VertesiaClient | undefined;
|
|
13
|
+
endpoints: {
|
|
14
|
+
studio: string;
|
|
15
|
+
store: string;
|
|
16
|
+
};
|
|
17
|
+
constructor(token: string, payload: AuthTokenPayload);
|
|
18
|
+
getClient(): Promise<VertesiaClient>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,OAAO,EAA0D,eAAe,EAAE,MAAM,MAAM,CAAC;AAC/F,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAGlD,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,4BAcxC;AAED,wBAAsB,WAAW,CAAC,KAAK,EAAE,MAAM,0FAQ9C;AAID,wBAAsB,SAAS,CAAC,GAAG,EAAE,OAAO,wBA6B3C;AAED,qBAAa,WAAY,YAAW,oBAAoB;IAOjC,KAAK,EAAE,MAAM;IAAS,OAAO,EAAE,gBAAgB;IANlE,OAAO,EAAE,cAAc,GAAG,SAAS,CAAC;IACpC,SAAS,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;KACjB,CAAC;gBAEiB,KAAK,EAAE,MAAM,EAAS,OAAO,EAAE,gBAAgB;IAM5D,SAAS;CAMlB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/build/validate.ts"],"names":[],"mappings":"AAAA,wBAAgB,QAAQ,SAEvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { ToolDefinition, ToolUse } from "@llumiverse/common";
|
|
2
|
+
import { VertesiaClient } from "@vertesia/client";
|
|
3
|
+
import { AuthTokenPayload, ToolResult, ToolResultContent } from "@vertesia/common";
|
|
4
|
+
export interface ToolExecutionContext {
|
|
5
|
+
/**
|
|
6
|
+
* The raw JWT token to the tool execution request
|
|
7
|
+
*/
|
|
8
|
+
token: string;
|
|
9
|
+
/**
|
|
10
|
+
* The decoded JWT token
|
|
11
|
+
*/
|
|
12
|
+
payload: AuthTokenPayload;
|
|
13
|
+
/**
|
|
14
|
+
* Vertesia client factory using the current auth token.
|
|
15
|
+
* @returns a vertesia client instance
|
|
16
|
+
*/
|
|
17
|
+
getClient: () => Promise<VertesiaClient>;
|
|
18
|
+
}
|
|
19
|
+
export interface ToolExecutionResult extends ToolResultContent {
|
|
20
|
+
/**
|
|
21
|
+
* Medata can be used to return more info on the tool execution like stats or user messages.
|
|
22
|
+
*/
|
|
23
|
+
meta?: Record<string, any>;
|
|
24
|
+
}
|
|
25
|
+
export interface ToolExecutionResponse extends ToolExecutionResult, ToolResult {
|
|
26
|
+
/**
|
|
27
|
+
* The tool use id of the tool use request. For traceability.
|
|
28
|
+
*/
|
|
29
|
+
tool_use_id: string;
|
|
30
|
+
}
|
|
31
|
+
export interface ToolExecutionResponseError {
|
|
32
|
+
/**
|
|
33
|
+
* The tool use id of the tool use request. For traceability.
|
|
34
|
+
*/
|
|
35
|
+
tool_use_id: string;
|
|
36
|
+
/**
|
|
37
|
+
* The http status code
|
|
38
|
+
*/
|
|
39
|
+
status: number;
|
|
40
|
+
/**
|
|
41
|
+
* the error message
|
|
42
|
+
*/
|
|
43
|
+
error: string;
|
|
44
|
+
/**
|
|
45
|
+
* Additional context information
|
|
46
|
+
*/
|
|
47
|
+
data?: Record<string, any>;
|
|
48
|
+
}
|
|
49
|
+
export interface ToolExecutionPayload<ParamsT extends Record<string, any>> {
|
|
50
|
+
tool_use: ToolUse<ParamsT>;
|
|
51
|
+
/**
|
|
52
|
+
* Optional metadata related to the current execution request
|
|
53
|
+
*/
|
|
54
|
+
metadata?: Record<string, any>;
|
|
55
|
+
}
|
|
56
|
+
export type ToolFn<ParamsT extends Record<string, any>> = (payload: ToolExecutionPayload<ParamsT>, context: ToolExecutionContext) => Promise<ToolExecutionResult>;
|
|
57
|
+
export interface Tool<ParamsT extends Record<string, any>> extends ToolDefinition {
|
|
58
|
+
run: ToolFn<ParamsT>;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The interface that should be return when requesting a collection endpoint using a GET
|
|
62
|
+
*/
|
|
63
|
+
export interface ToolCollectionDefinition {
|
|
64
|
+
title: string;
|
|
65
|
+
description: string;
|
|
66
|
+
src: string;
|
|
67
|
+
tools: ToolDefinition[];
|
|
68
|
+
}
|
|
69
|
+
export type { ToolDefinition };
|
|
70
|
+
/**
|
|
71
|
+
* The details of a connection to a MCP server - including the server URL and an authentication token
|
|
72
|
+
*/
|
|
73
|
+
export interface MCPConnectionDetails {
|
|
74
|
+
/**
|
|
75
|
+
* The mcp server name. It will be used to prefix tool names.
|
|
76
|
+
*/
|
|
77
|
+
name: string;
|
|
78
|
+
/**
|
|
79
|
+
* The target mcp server URL
|
|
80
|
+
*/
|
|
81
|
+
url: string;
|
|
82
|
+
/**
|
|
83
|
+
* The bearer authentication token to use when connecting to the mcp server.
|
|
84
|
+
* If an empty string no authentication will be done
|
|
85
|
+
*/
|
|
86
|
+
token: string;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEnF,MAAM,WAAW,oBAAoB;IACjC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,OAAO,EAAE,gBAAgB,CAAC;IAC1B;;;OAGG;IACH,SAAS,EAAE,MAAM,OAAO,CAAC,cAAc,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;IAC1D;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAsB,SAAQ,mBAAmB,EAAE,UAAU;IAC1E;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,0BAA0B;IACvC;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,oBAAoB,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IACrE,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3B;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAClC;AAED,MAAM,MAAM,MAAM,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,oBAAoB,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAElK,MAAM,WAAW,IAAI,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAE,SAAQ,cAAc;IAC7E,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,cAAc,EAAE,CAAC;CAC3B;AAED,YAAY,EAAE,cAAc,EAAE,CAAC;AAE/B;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;CACjB"}
|
package/package.json
CHANGED
|
@@ -1,44 +1,39 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
"name": "@vertesia/tools-sdk",
|
|
3
|
+
"version": "0.79.0",
|
|
4
|
+
"description": "Tools SDK - utilities for building remote tools",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"types": "./lib/types/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"lib",
|
|
9
|
+
"src"
|
|
10
|
+
],
|
|
11
|
+
"license": "Apache-2.0",
|
|
12
|
+
"exports": {
|
|
6
13
|
"types": "./lib/types/index.d.ts",
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"dependencies": {
|
|
34
|
-
"@llumiverse/common": "workspace:*",
|
|
35
|
-
"@vertesia/client": "workspace:*",
|
|
36
|
-
"@vertesia/common": "workspace:*",
|
|
37
|
-
"jose": "^6.0.11"
|
|
38
|
-
},
|
|
39
|
-
"repository": {
|
|
40
|
-
"type": "git",
|
|
41
|
-
"url": "https://github.com/vertesia/composableai.git",
|
|
42
|
-
"directory": "packages/tools-sdk"
|
|
43
|
-
}
|
|
44
|
-
}
|
|
14
|
+
"import": "./lib/esm/index.js",
|
|
15
|
+
"require": "./lib/cjs/index.js"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"ts-dual-module": "^0.6.3",
|
|
19
|
+
"typescript": "^5.0.2",
|
|
20
|
+
"vitest": "^3.0.9"
|
|
21
|
+
},
|
|
22
|
+
"ts_dual_module": {
|
|
23
|
+
"outDir": "lib"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"hono": "^4.0.0"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"jose": "^6.0.11",
|
|
30
|
+
"@llumiverse/common": "0.22.0",
|
|
31
|
+
"@vertesia/client": "0.79.0",
|
|
32
|
+
"@vertesia/common": "0.79.0"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"test": "vitest run",
|
|
36
|
+
"build": "pnpm exec tsmod build",
|
|
37
|
+
"clean": "rimraf ./node_modules ./lib ./tsconfig.tsbuildinfo"
|
|
38
|
+
}
|
|
39
|
+
}
|
package/src/ToolCollection.ts
CHANGED
|
@@ -89,7 +89,7 @@ export class ToolCollection implements Iterable<Tool<any>> {
|
|
|
89
89
|
return this.tools.getTools().map(callback);
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
async execute(ctx: Context)
|
|
92
|
+
async execute(ctx: Context) {
|
|
93
93
|
let payload: ToolExecutionPayload<any> | undefined;
|
|
94
94
|
try {
|
|
95
95
|
payload = await readPayload(ctx);
|
package/src/auth.ts
CHANGED
|
@@ -24,22 +24,21 @@ export async function getJwks(url: string) {
|
|
|
24
24
|
|
|
25
25
|
export async function verifyToken(token: string) {
|
|
26
26
|
const decodedJwt = decodeJwt(token);
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
const { studio } = decodeEndpoints(decodedJwt.endpoints as any);
|
|
28
|
+
if (!studio) {
|
|
29
|
+
throw new Error("No studio endpoint found in JWT");
|
|
29
30
|
}
|
|
30
|
-
|
|
31
|
-
throw new Error("Issuer is not allowed: " + decodedJwt.iss);
|
|
32
|
-
}
|
|
33
|
-
const jwks = await getJwks(`${decodedJwt.iss}/.well-known/jwks`);
|
|
31
|
+
const jwks = await getJwks(`${studio}/.well-known/jwks`);
|
|
34
32
|
return await jwtVerify<AuthTokenPayload>(token, jwks);
|
|
35
33
|
}
|
|
36
34
|
|
|
37
35
|
|
|
36
|
+
|
|
38
37
|
export async function authorize(ctx: Context) {
|
|
39
38
|
const auth = ctx.req.header('Authorization');
|
|
40
39
|
if (!auth) {
|
|
41
40
|
throw new HTTPException(401, {
|
|
42
|
-
message: `Missing Authorization header`
|
|
41
|
+
message: `Missing Authorization header'`
|
|
43
42
|
});
|
|
44
43
|
}
|
|
45
44
|
const [scheme, value] = auth.trim().split(' ');
|
|
@@ -85,8 +84,4 @@ export class AuthSession implements ToolExecutionContext {
|
|
|
85
84
|
}
|
|
86
85
|
return this._client;
|
|
87
86
|
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function isAllowedIssuer(iss: string) {
|
|
91
|
-
return iss.endsWith(".vertesia.io") || iss.endsWith(".becomposable.com");
|
|
92
|
-
}
|
|
87
|
+
}
|