Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
369 changes: 226 additions & 143 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vlmrun",
"version": "1.0.12",
"version": "1.1.0",
"description": "The official TypeScript library for the VlmRun API",
"author": "VlmRun <support@vlmrun.com>",
"main": "dist/index.js",
Expand Down
176 changes: 176 additions & 0 deletions src/client/skills.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/**
* VLM Run API Skills resource.
*/

import { json } from "stream/consumers";
import { Client, APIRequestor } from "./base_requestor";
import {
SkillInfo,
SkillDownloadResponse,
SkillCreateParams,
SkillUpdateParams,
SkillGetParams,
} from "./types";

export class Skills {
/**
* Skills resource for VLM Run API.
*
* Provides methods to list, lookup, create, update, and download skills.
*/
private client: Client;
private requestor: APIRequestor;

constructor(client: Client) {
/**
* Initialize Skills resource with VLMRun instance.
*
* @param client - VLM Run API instance
*/
this.client = client;
this.requestor = new APIRequestor(client);
}

/**
* List all available skills.
*
* @returns List of SkillInfo objects
*/
async list(): Promise<SkillInfo[]> {
const [response] = await this.requestor.request<SkillInfo[]>(
"GET",
"skills",
);

if (!Array.isArray(response)) {
throw new TypeError("Expected array response");
}

return response;
}

/**
* Lookup a skill by name, ID, or name + version.
*
* If `id` is provided, fetches the skill directly by ID via GET /v1/skills/{skill_id}.
* Otherwise, looks up by `name` (and optional `version`) via POST /v1/skills/lookup.
*
* @param params - Skill lookup parameters
* @returns Skill information
*/
async get(params: SkillGetParams): Promise<SkillInfo> {
const { name, id, version } = params;

if (id && !name) {
const [response] = await this.requestor.request<SkillInfo>(
"GET",
`skills/${id}`,
);

if (typeof response !== "object") {
throw new TypeError("Expected object response");
}

return response;
} else if (name) {
const data: Record<string, any> = { name };
if (version) {
data.version = version;
}

const [response] = await this.requestor.request<SkillInfo>(
"POST",
"skills/lookup",
undefined,
data,
);

if (typeof response !== "object") {
throw new TypeError("Expected object response");
}

return response;
} else {
throw new Error("Either `name` or `id` must be provided.");
}
}

/**
* Create a new skill.
*
* Skills can be created from a prompt (with optional JSON schema),
* from a chat session, or from an uploaded skill zip file.
*
* @param params - Skill creation parameters
* @returns Created skill information
*/
async create(params: SkillCreateParams): Promise<SkillInfo> {
const data: Record<string, any> = {};

if (params.prompt !== undefined) data.prompt = params.prompt;
if (params.jsonSchema !== undefined) data.json_schema = params.jsonSchema;
if (params.sessionId !== undefined) data.session_id = params.sessionId;
if (params.fileId !== undefined) data.file_id = params.fileId;
if (params.name !== undefined) data.name = params.name;
if (params.description !== undefined) data.description = params.description;

const [response] = await this.requestor.request<SkillInfo>(
"POST",
"skills/create",
undefined,
data,
);

if (typeof response !== "object") {
throw new TypeError("Expected object response");
}

return response;
}

/**
* Update an existing skill (creates a new version).
*
* @param params - Skill update parameters
* @returns Updated skill information
*/
async update(params: SkillUpdateParams): Promise<SkillInfo> {
const { skillId, ...rest } = params;
const data: Record<string, any> = {};

if (rest.fileId !== undefined) data.file_id = rest.fileId;
if (rest.description !== undefined) data.description = rest.description;

const [response] = await this.requestor.request<SkillInfo>(
"POST",
`skills/${skillId}/update`,
undefined,
data,
);

if (typeof response !== "object") {
throw new TypeError("Expected object response");
}

return response;
}

/**
* Get a presigned download URL for a skill zip.
*
* @param params - Object with skillId
* @returns Download URL and expiry information
*/
async download(params: { skillId: string }): Promise<SkillDownloadResponse> {
const [response] = await this.requestor.request<SkillDownloadResponse>(
"GET",
`skills/${params.skillId}/download`,
);

if (typeof response !== "object") {
throw new TypeError("Expected object response");
}

return response;
}
}
45 changes: 45 additions & 0 deletions src/client/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -659,3 +659,48 @@ export interface AgentExecuteParamsNew {
metadata?: RequestMetadataInput;
callbackUrl?: string;
}

// --- Skills types ---

export interface SkillInfo {
id: string;
name: string;
description?: string;
version?: string;
created_at?: string;
updated_at?: string;
status?: JobStatus;
}

export interface SkillDownloadResponse {
download_url: string;
expires_in?: number;
}

export interface SkillGetParams {
name?: string;
id?: string;
version?: string;
}

export interface SkillCreateParams {
prompt?: string;
jsonSchema?: Record<string, any>;
sessionId?: string;
fileId?: string;
name?: string;
description?: string;
}

export interface SkillUpdateParams {
skillId: string;
fileId?: string;
description?: string;
}

export interface AgentSkill {
skillName?: string;
skillId?: string;
version?: string;
type?: string;
}
4 changes: 4 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Finetuning } from "./client/fine_tuning";
import { Datasets } from "./client/datasets";
import { Hub } from "./client/hub";
import { Agent } from "./client/agent";
import { Skills } from "./client/skills";
import { Executions } from "./client/executions";
import { Domains } from "./client/domains";
import { Artifacts } from "./client/artifacts";
Expand All @@ -27,6 +28,7 @@ export * from "./client/feedback";
export * from "./client/fine_tuning";
export * from "./client/exceptions";
export * from "./client/agent";
export * from "./client/skills";
export * from "./client/executions";
export * from "./client/artifacts";

Expand Down Expand Up @@ -55,6 +57,7 @@ export class VlmRun {
readonly dataset: Datasets;
readonly hub: Hub;
readonly agent: Agent;
readonly skills: Skills;
readonly executions: Executions;
readonly domains: Domains;
readonly artifacts: Artifacts;
Expand All @@ -81,6 +84,7 @@ export class VlmRun {
this.dataset = new Datasets(this.client);
this.hub = new Hub(this.client);
this.agent = new Agent(this.client);
this.skills = new Skills(this.client);
this.executions = new Executions(this.client);
this.domains = new Domains(this.client);
this.artifacts = new Artifacts(this.client);
Expand Down
Loading