@vertesia/tools-sdk 1.6.0-dev.20261014.015055Z → 1.6.0-dev.20261022.120426Z

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.
@@ -4,7 +4,7 @@ import { type Context, Hono } from 'hono';
4
4
  import { HTTPException } from 'hono/http-exception';
5
5
  import type { SkillCollection } from '../SkillCollection.js';
6
6
  import type { SkillDefinition, ToolCollectionDefinition, ToolDefinition } from '../types.js';
7
- import { makeScriptUrl } from '../utils.js';
7
+ import { makeScriptUrl, makeSkillFileUrl } from '../utils.js';
8
8
  import type { ToolContext, ToolServerConfig } from './types.js';
9
9
 
10
10
  export function createSkillsRoute(app: Hono, basePath: string, config: ToolServerConfig) {
@@ -116,6 +116,32 @@ function createSkillEndpoints(coll: SkillCollection): Hono {
116
116
  });
117
117
  });
118
118
 
119
+ // Get the Agent Skills resource files (scripts/, references/, assets/) for a specific skill.
120
+ // Separate from /scripts so existing clients keep receiving only the flat scripts.
121
+ endpoint.get('/:name/files', (c: Context) => {
122
+ const name = c.req.param('name');
123
+ if (!name) {
124
+ throw new HTTPException(400, {
125
+ message: 'Skill name is required',
126
+ });
127
+ }
128
+ const skillName = name.startsWith('learn_') ? name.slice(6) : name;
129
+ const skill = coll.getSkill(skillName);
130
+ if (!skill) {
131
+ throw new HTTPException(404, {
132
+ message: `Skill not found: ${skillName}`,
133
+ });
134
+ }
135
+ const url = new URL(c.req.url);
136
+ return c.json({
137
+ skill_name: skill.name,
138
+ files: (skill.files ?? []).map((path) => ({
139
+ path,
140
+ url: makeSkillFileUrl(url.origin, skill.files_namespace ?? skill.name, path),
141
+ })),
142
+ });
143
+ });
144
+
119
145
  // Get a specific skill by name
120
146
  endpoint.get('/:name', (c: Context) => {
121
147
  const name = c.req.param('name');
@@ -50,6 +50,8 @@ export interface MCPProviderConfig {
50
50
  export interface ToolServerConfig {
51
51
  /** OAuth scopes requested by the app; project permissions must be explicitly declared. */
52
52
  oauth_scopes?: string[];
53
+ /** Declare exact standalone callbacks; installation provisions the public PKCE client. */
54
+ oauth_client?: { redirect_uris: string[] };
53
55
  /**
54
56
  * Server title for HTML pages (default: 'Tools Server')
55
57
  */
package/src/types.ts CHANGED
@@ -379,6 +379,32 @@ export interface SkillDefinition {
379
379
  * Scripts bundled with this skill (synced to sandbox when skill is used)
380
380
  */
381
381
  scripts?: string[];
382
+ /**
383
+ * Agent Skills resource files from the skill's `scripts/`, `references/` and `assets/` directories, as
384
+ * paths relative to the skill directory (e.g. `scripts/extract.py`). They are synced to the sandbox
385
+ * under the skill's directory with these relative paths.
386
+ */
387
+ files?: string[];
388
+ /** Build-time directory under `skill-files/`, independent of a runtime name override. Defaults to `name`. */
389
+ files_namespace?: string;
390
+ /**
391
+ * License from the Agent Skills `license` frontmatter field.
392
+ */
393
+ license?: string;
394
+ /**
395
+ * Environment requirements from the Agent Skills `compatibility` frontmatter field.
396
+ */
397
+ compatibility?: string;
398
+ /**
399
+ * Arbitrary key-value metadata from the Agent Skills `metadata` frontmatter field.
400
+ */
401
+ metadata?: Record<string, string>;
402
+ /**
403
+ * Tools named by the Agent Skills `allowed-tools` frontmatter field, which is experimental in the
404
+ * spec and not supported by Vertesia. Informational only: unlike `tools`, these names are not
405
+ * resolved and never unlock a tool.
406
+ */
407
+ allowed_tools?: string[];
382
408
  /**
383
409
  * The name of the widgets provided by this skill (if any)
384
410
  * The name will be used to load the widget dynamically from the agent chat
package/src/utils.ts CHANGED
@@ -25,6 +25,14 @@ export function makeScriptUrl(origin: string, script: string) {
25
25
  return join(origin, join('/scripts', script));
26
26
  }
27
27
 
28
+ /**
29
+ * URL of an Agent Skills resource file, which the build copies to `skill-files/<skill>/<path>`.
30
+ */
31
+ export function makeSkillFileUrl(origin: string, skillName: string, filePath: string) {
32
+ const encodedPath = filePath.split('/').map(encodeURIComponent).join('/');
33
+ return join(origin, `/skill-files/${encodeURIComponent(skillName)}/${encodedPath}`);
34
+ }
35
+
28
36
  export function join(left: string, right: string) {
29
37
  if (left.endsWith('/')) {
30
38
  if (right.startsWith('/')) {