@vertesia/tools-sdk 0.78.0-dev-28b447d → 0.78.0-dev.1

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.
@@ -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"}
@@ -0,0 +1,89 @@
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
+ if (!decodedJwt.iss) {
29
+ throw new Error("No issuer URL found in JWT");
30
+ }
31
+ if (!isAllowedIssuer(decodedJwt.iss)) {
32
+ throw new Error("Issuer is not allowed: " + decodedJwt.iss);
33
+ }
34
+ const jwks = await getJwks(`${decodedJwt.iss}/.well-known/jwks`);
35
+ return await (0, jose_1.jwtVerify)(token, jwks);
36
+ }
37
+ async function authorize(ctx) {
38
+ const auth = ctx.req.header('Authorization');
39
+ if (!auth) {
40
+ throw new http_exception_1.HTTPException(401, {
41
+ message: `Missing Authorization header`
42
+ });
43
+ }
44
+ const [scheme, value] = auth.trim().split(' ');
45
+ if (scheme.toLowerCase() !== 'bearer') {
46
+ throw new http_exception_1.HTTPException(401, {
47
+ message: `Authorization scheme ${scheme} is not supported`
48
+ });
49
+ }
50
+ if (!value) {
51
+ throw new http_exception_1.HTTPException(401, {
52
+ message: `Missing bearer token value`
53
+ });
54
+ }
55
+ try {
56
+ const { payload } = await verifyToken(value);
57
+ const session = new AuthSession(value, payload);
58
+ ctx.set("auth", session);
59
+ return session;
60
+ }
61
+ catch (err) {
62
+ throw new http_exception_1.HTTPException(401, {
63
+ message: err.message,
64
+ cause: err
65
+ });
66
+ }
67
+ }
68
+ class AuthSession {
69
+ token;
70
+ payload;
71
+ _client;
72
+ endpoints;
73
+ constructor(token, payload) {
74
+ this.token = token;
75
+ this.payload = payload;
76
+ this.endpoints = (0, client_1.decodeEndpoints)(payload.endpoints);
77
+ }
78
+ async getClient() {
79
+ if (!this._client) {
80
+ this._client = await client_1.VertesiaClient.fromAuthToken(this.token, this.payload);
81
+ }
82
+ return this._client;
83
+ }
84
+ }
85
+ exports.AuthSession = AuthSession;
86
+ function isAllowedIssuer(iss) {
87
+ return iss.endsWith(".vertesia.io") || iss.endsWith(".becomposable.com");
88
+ }
89
+ //# 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,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validate = validate;
4
+ function validate() {
5
+ //TODO
6
+ }
7
+ //# sourceMappingURL=validate.js.map
@@ -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"}
@@ -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"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -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"}
@@ -0,0 +1,82 @@
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
+ if (!decodedJwt.iss) {
23
+ throw new Error("No issuer URL found in JWT");
24
+ }
25
+ if (!isAllowedIssuer(decodedJwt.iss)) {
26
+ throw new Error("Issuer is not allowed: " + decodedJwt.iss);
27
+ }
28
+ const jwks = await getJwks(`${decodedJwt.iss}/.well-known/jwks`);
29
+ return await jwtVerify(token, jwks);
30
+ }
31
+ export async function authorize(ctx) {
32
+ const auth = ctx.req.header('Authorization');
33
+ if (!auth) {
34
+ throw new HTTPException(401, {
35
+ message: `Missing Authorization header`
36
+ });
37
+ }
38
+ const [scheme, value] = auth.trim().split(' ');
39
+ if (scheme.toLowerCase() !== 'bearer') {
40
+ throw new HTTPException(401, {
41
+ message: `Authorization scheme ${scheme} is not supported`
42
+ });
43
+ }
44
+ if (!value) {
45
+ throw new HTTPException(401, {
46
+ message: `Missing bearer token value`
47
+ });
48
+ }
49
+ try {
50
+ const { payload } = await verifyToken(value);
51
+ const session = new AuthSession(value, payload);
52
+ ctx.set("auth", session);
53
+ return session;
54
+ }
55
+ catch (err) {
56
+ throw new HTTPException(401, {
57
+ message: err.message,
58
+ cause: err
59
+ });
60
+ }
61
+ }
62
+ export class AuthSession {
63
+ token;
64
+ payload;
65
+ _client;
66
+ endpoints;
67
+ constructor(token, payload) {
68
+ this.token = token;
69
+ this.payload = payload;
70
+ this.endpoints = decodeEndpoints(payload.endpoints);
71
+ }
72
+ async getClient() {
73
+ if (!this._client) {
74
+ this._client = await VertesiaClient.fromAuthToken(this.token, this.payload);
75
+ }
76
+ return this._client;
77
+ }
78
+ }
79
+ function isAllowedIssuer(iss) {
80
+ return iss.endsWith(".vertesia.io") || iss.endsWith(".becomposable.com");
81
+ }
82
+ //# 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,4 @@
1
+ export function validate() {
2
+ //TODO
3
+ }
4
+ //# sourceMappingURL=validate.js.map
@@ -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"}
@@ -0,0 +1,5 @@
1
+ export * from "./ToolCollection.js";
2
+ export * from "./ToolRegistry.js";
3
+ export * from "./types.js";
4
+ export { AuthSession, authorize } from "./auth.js";
5
+ //# sourceMappingURL=index.js.map
@@ -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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,62 @@
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>;
60
+ getToolDefinitions(): ToolDefinition[];
61
+ }
62
+ //# 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,GAAG,OAAO,CAAC,QAAQ,CAAC;IAoB9C,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,0FAU9C;AAGD,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,2 @@
1
+ export declare function validate(): void;
2
+ //# sourceMappingURL=validate.d.ts.map
@@ -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,5 @@
1
+ export * from "./ToolCollection.js";
2
+ export * from "./ToolRegistry.js";
3
+ export * from "./types.js";
4
+ export { AuthSession, authorize } from "./auth.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -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,44 @@
1
1
  {
2
- "name": "@vertesia/tools-sdk",
3
- "version": "0.78.0-dev-28b447d",
4
- "description": "Tools SDK - utilities for building remote tools",
5
- "type": "module",
2
+ "name": "@vertesia/tools-sdk",
3
+ "version": "0.78.0-dev.1",
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
- "files": [
8
- "lib",
9
- "src"
10
- ],
11
- "license": "Apache-2.0",
12
- "scripts": {
13
- "test": "vitest run",
14
- "build": "pnpm exec tsmod build",
15
- "clean": "rimraf ./node_modules ./lib ./tsconfig.tsbuildinfo"
16
- },
17
- "exports": {
18
- "types": "./lib/types/index.d.ts",
19
- "import": "./lib/esm/index.js",
20
- "require": "./lib/cjs/index.js"
21
- },
22
- "devDependencies": {
23
- "ts-dual-module": "^0.6.3",
24
- "typescript": "^5.0.2",
25
- "vitest": "^3.0.9"
26
- },
27
- "ts_dual_module": {
28
- "outDir": "lib"
29
- },
30
- "peerDependencies": {
31
- "hono": "^4.9.6"
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.9.6"
27
+ },
28
+ "dependencies": {
29
+ "jose": "^6.0.11",
30
+ "@llumiverse/common": "0.22.0-dev.1",
31
+ "@vertesia/client": "0.78.0-dev.1",
32
+ "@vertesia/common": "0.78.0-dev.1"
33
+ },
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "https://github.com/vertesia/composableai.git",
37
+ "directory": "packages/tools-sdk"
38
+ },
39
+ "scripts": {
40
+ "test": "vitest run",
41
+ "build": "pnpm exec tsmod build",
42
+ "clean": "rimraf ./node_modules ./lib ./tsconfig.tsbuildinfo"
43
+ }
44
+ }