refactor: replace exportName with name throughout codebase
- Update TpmjsToolDefinitionSchema to only use 'name' field - Add 'sandbox' as valid category for sprites tools - Update all package.json files to use 'name' instead of 'exportName' - Update documentation and source files accordingly - Add 11 new sprites tools for sandbox/code-execution
This commit is contained in:
parent
b1dd3371cd
commit
2cd2b10cd0
91 changed files with 4019 additions and 195 deletions
|
|
@ -22,11 +22,11 @@
|
|||
],
|
||||
"tools": [
|
||||
{
|
||||
"exportName": "textToEmoji",
|
||||
"name": "textToEmoji",
|
||||
"description": "Convert text into emoji representations - perfect for making messages more expressive!"
|
||||
},
|
||||
{
|
||||
"exportName": "emojiMood",
|
||||
"name": "emojiMood",
|
||||
"description": "Detect the mood/sentiment and suggest appropriate emojis for the text"
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
],
|
||||
"tools": [
|
||||
{
|
||||
"exportName": "helloWorldTool",
|
||||
"name": "helloWorldTool",
|
||||
"description": "Returns a simple 'Hello, World!' greeting with optional timestamp and customizable message",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"exportName": "helloNameTool",
|
||||
"name": "helloNameTool",
|
||||
"description": "Returns a personalized greeting with the provided name",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -22,11 +22,11 @@
|
|||
],
|
||||
"tools": [
|
||||
{
|
||||
"exportName": "markdownToPlainText",
|
||||
"name": "markdownToPlainText",
|
||||
"description": "Convert markdown to plain text by removing all formatting"
|
||||
},
|
||||
{
|
||||
"exportName": "formatMarkdownTable",
|
||||
"name": "formatMarkdownTable",
|
||||
"description": "Format and align markdown table columns for better readability"
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
],
|
||||
"tools": [
|
||||
{
|
||||
"exportName": "audiencePersonaTool",
|
||||
"name": "audiencePersonaTool",
|
||||
"description": "Creates detailed audience persona profiles from demographic and behavioral data. Generates personas with demographics, psychographics, goals, pain points, behaviors, and actionable marketing implications.",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -330,6 +330,37 @@ domain:
|
|||
fields: [effect, standardError, assumptions, parallel]
|
||||
description: "Difference-in-differences result"
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Sandbox & execution entities
|
||||
# -------------------------------------------------------------------------
|
||||
sprite:
|
||||
fields: [name, status, createdAt, runtime, filesystem]
|
||||
description: "Isolated Linux sandbox environment"
|
||||
|
||||
sprite_list:
|
||||
fields: [sprites, count]
|
||||
description: "Collection of sprites with metadata"
|
||||
|
||||
exec_result:
|
||||
fields: [exitCode, stdout, stderr, duration]
|
||||
description: "Command execution result from a sprite"
|
||||
|
||||
exec_session:
|
||||
fields: [id, status, startedAt, command]
|
||||
description: "Active execution session in a sprite"
|
||||
|
||||
checkpoint:
|
||||
fields: [id, name, createdAt, size]
|
||||
description: "Point-in-time snapshot of sprite state"
|
||||
|
||||
checkpoint_list:
|
||||
fields: [checkpoints, count]
|
||||
description: "Collection of checkpoints for a sprite"
|
||||
|
||||
network_policy:
|
||||
fields: [mode, allowedDomains, rules]
|
||||
description: "DNS-based network filtering configuration"
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Agent & workflow entities
|
||||
# -------------------------------------------------------------------------
|
||||
|
|
@ -521,10 +552,9 @@ domain:
|
|||
severity: warning
|
||||
|
||||
# =============================================================================
|
||||
# DOMAIN RULES - Enforce code quality across all blocks
|
||||
# DOMAIN RULES - Enforce code quality across all blocks (documentation only)
|
||||
# =============================================================================
|
||||
blocks:
|
||||
domain_rules:
|
||||
domain_rules:
|
||||
# -------------------------------------------------------------------------
|
||||
# Core implementation rules (apply to ALL tools)
|
||||
# -------------------------------------------------------------------------
|
||||
|
|
@ -794,10 +824,10 @@ blocks:
|
|||
- Handle missing/extra items
|
||||
- Report confidence in scores
|
||||
|
||||
# ===========================================================================
|
||||
# BLOCK DEFINITIONS - All 100 tools organized by category
|
||||
# ===========================================================================
|
||||
|
||||
# ===========================================================================
|
||||
# BLOCK DEFINITIONS - All 100 tools organized by category
|
||||
# ===========================================================================
|
||||
blocks:
|
||||
# ---------------------------------------------------------------------------
|
||||
# A) Web Research & Evidence (15 tools)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
@ -4494,6 +4524,260 @@ blocks:
|
|||
description: "Standards to activities mapping"
|
||||
measures: [working_implementation, valid_output_structure, readme_documentation]
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# K) Sandbox & Code Execution - Sprites API (11 tools)
|
||||
# ---------------------------------------------------------------------------
|
||||
sprites.createSprite:
|
||||
description: "Creates a new isolated Linux sandbox environment (sprite) with persistent filesystem using the Sprites API"
|
||||
path: "sprites-create"
|
||||
domain_rules:
|
||||
- id: api_integration
|
||||
description: |
|
||||
Must call Sprites API POST /sprites endpoint:
|
||||
- Use fetch with Authorization Bearer header
|
||||
- Send name in request body
|
||||
- Handle API errors with meaningful messages
|
||||
- id: auth_handling
|
||||
description: "Must use SPRITES_TOKEN environment variable for authentication"
|
||||
inputs:
|
||||
- name: name
|
||||
type: string
|
||||
description: "Unique name for the sprite (must be lowercase alphanumeric with hyphens)"
|
||||
outputs:
|
||||
- name: sprite
|
||||
type: Sprite
|
||||
description: "Created sprite with name, status, and metadata"
|
||||
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance, readme_documentation]
|
||||
|
||||
sprites.listSprites:
|
||||
description: "Lists all sprites in the account with their current status and metadata"
|
||||
path: "sprites-list"
|
||||
domain_rules:
|
||||
- id: api_integration
|
||||
description: "Must call Sprites API GET /sprites endpoint"
|
||||
- id: auth_handling
|
||||
description: "Must use SPRITES_TOKEN environment variable for authentication"
|
||||
inputs: []
|
||||
outputs:
|
||||
- name: sprites
|
||||
type: Sprite[]
|
||||
description: "Array of sprites with name, status, and metadata"
|
||||
- name: count
|
||||
type: number
|
||||
description: "Total number of sprites"
|
||||
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance, readme_documentation]
|
||||
|
||||
sprites.getSprite:
|
||||
description: "Retrieves details of a specific sprite by name including status and configuration"
|
||||
path: "sprites-get"
|
||||
domain_rules:
|
||||
- id: api_integration
|
||||
description: "Must call Sprites API GET /sprites/{name} endpoint"
|
||||
- id: error_handling
|
||||
description: "Must handle 404 for non-existent sprites gracefully"
|
||||
inputs:
|
||||
- name: name
|
||||
type: string
|
||||
description: "Name of the sprite to retrieve"
|
||||
outputs:
|
||||
- name: sprite
|
||||
type: Sprite
|
||||
description: "Sprite details including status and metadata"
|
||||
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance, readme_documentation]
|
||||
|
||||
sprites.deleteSprite:
|
||||
description: "Deletes a sprite and all its associated data including checkpoints"
|
||||
path: "sprites-delete"
|
||||
domain_rules:
|
||||
- id: api_integration
|
||||
description: "Must call Sprites API DELETE /sprites/{name} endpoint"
|
||||
- id: confirmation
|
||||
description: "Returns success status after deletion"
|
||||
inputs:
|
||||
- name: name
|
||||
type: string
|
||||
description: "Name of the sprite to delete"
|
||||
outputs:
|
||||
- name: deleted
|
||||
type: boolean
|
||||
description: "Whether the sprite was successfully deleted"
|
||||
- name: name
|
||||
type: string
|
||||
description: "Name of the deleted sprite"
|
||||
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance, readme_documentation]
|
||||
|
||||
sprites.execCommand:
|
||||
description: "Executes a command inside a sprite and returns the output. Supports stdin input for interactive commands."
|
||||
path: "sprites-exec"
|
||||
domain_rules:
|
||||
- id: api_integration
|
||||
description: |
|
||||
Must call Sprites API POST /sprites/{name}/exec endpoint:
|
||||
- Send cmd and optional stdin in request body
|
||||
- Handle command execution timeout
|
||||
- Return stdout, stderr, and exit code
|
||||
- id: timeout_handling
|
||||
description: "Must implement configurable timeout (default 60s)"
|
||||
inputs:
|
||||
- name: name
|
||||
type: string
|
||||
description: "Name of the sprite to execute command in"
|
||||
- name: cmd
|
||||
type: string
|
||||
description: "Command to execute (e.g., 'ls -la', 'python script.py')"
|
||||
- name: stdin
|
||||
type: string
|
||||
optional: true
|
||||
description: "Optional stdin input to pass to the command"
|
||||
- name: timeoutMs
|
||||
type: number
|
||||
optional: true
|
||||
description: "Execution timeout in milliseconds (default: 60000)"
|
||||
outputs:
|
||||
- name: exitCode
|
||||
type: number
|
||||
description: "Command exit code (0 for success)"
|
||||
- name: stdout
|
||||
type: string
|
||||
description: "Standard output from the command"
|
||||
- name: stderr
|
||||
type: string
|
||||
description: "Standard error output from the command"
|
||||
- name: duration
|
||||
type: number
|
||||
description: "Execution duration in milliseconds"
|
||||
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance, readme_documentation]
|
||||
|
||||
sprites.listSessions:
|
||||
description: "Lists active execution sessions for a sprite"
|
||||
path: "sprites-sessions"
|
||||
domain_rules:
|
||||
- id: api_integration
|
||||
description: "Must call Sprites API GET /sprites/{name}/exec/sessions endpoint"
|
||||
inputs:
|
||||
- name: name
|
||||
type: string
|
||||
description: "Name of the sprite to list sessions for"
|
||||
outputs:
|
||||
- name: sessions
|
||||
type: ExecSession[]
|
||||
description: "Array of active execution sessions"
|
||||
- name: count
|
||||
type: number
|
||||
description: "Total number of active sessions"
|
||||
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance, readme_documentation]
|
||||
|
||||
sprites.createCheckpoint:
|
||||
description: "Creates a point-in-time snapshot (checkpoint) of a sprite's filesystem state for later restoration"
|
||||
path: "sprites-checkpoint-create"
|
||||
domain_rules:
|
||||
- id: api_integration
|
||||
description: "Must call Sprites API POST /sprites/{name}/checkpoints endpoint"
|
||||
- id: checkpoint_metadata
|
||||
description: "Must return checkpoint ID and creation timestamp"
|
||||
inputs:
|
||||
- name: name
|
||||
type: string
|
||||
description: "Name of the sprite to checkpoint"
|
||||
- name: checkpointName
|
||||
type: string
|
||||
optional: true
|
||||
description: "Optional human-readable name for the checkpoint"
|
||||
outputs:
|
||||
- name: checkpoint
|
||||
type: Checkpoint
|
||||
description: "Created checkpoint with ID and metadata"
|
||||
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance, readme_documentation]
|
||||
|
||||
sprites.listCheckpoints:
|
||||
description: "Lists all checkpoints for a sprite ordered by creation time"
|
||||
path: "sprites-checkpoint-list"
|
||||
domain_rules:
|
||||
- id: api_integration
|
||||
description: "Must call Sprites API GET /sprites/{name}/checkpoints endpoint"
|
||||
inputs:
|
||||
- name: name
|
||||
type: string
|
||||
description: "Name of the sprite to list checkpoints for"
|
||||
outputs:
|
||||
- name: checkpoints
|
||||
type: Checkpoint[]
|
||||
description: "Array of checkpoints with IDs and metadata"
|
||||
- name: count
|
||||
type: number
|
||||
description: "Total number of checkpoints"
|
||||
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance, readme_documentation]
|
||||
|
||||
sprites.restoreCheckpoint:
|
||||
description: "Restores a sprite to a previous checkpoint state, reverting all filesystem changes since that checkpoint"
|
||||
path: "sprites-checkpoint-restore"
|
||||
domain_rules:
|
||||
- id: api_integration
|
||||
description: "Must call Sprites API POST /sprites/{name}/checkpoints/{id}/restore endpoint"
|
||||
- id: state_verification
|
||||
description: "Must verify restoration completed successfully"
|
||||
inputs:
|
||||
- name: name
|
||||
type: string
|
||||
description: "Name of the sprite to restore"
|
||||
- name: checkpointId
|
||||
type: string
|
||||
description: "ID of the checkpoint to restore to"
|
||||
outputs:
|
||||
- name: restored
|
||||
type: boolean
|
||||
description: "Whether the restoration was successful"
|
||||
- name: checkpointId
|
||||
type: string
|
||||
description: "ID of the restored checkpoint"
|
||||
- name: sprite
|
||||
type: Sprite
|
||||
description: "Sprite status after restoration"
|
||||
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance, readme_documentation]
|
||||
|
||||
sprites.getPolicy:
|
||||
description: "Retrieves the current network policy for a sprite including allowed domains and filtering rules"
|
||||
path: "sprites-policy-get"
|
||||
domain_rules:
|
||||
- id: api_integration
|
||||
description: "Must call Sprites API GET /sprites/{name}/policies endpoint"
|
||||
inputs:
|
||||
- name: name
|
||||
type: string
|
||||
description: "Name of the sprite to get policy for"
|
||||
outputs:
|
||||
- name: policy
|
||||
type: NetworkPolicy
|
||||
description: "Current network policy with allowed domains and rules"
|
||||
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance, readme_documentation]
|
||||
|
||||
sprites.setPolicy:
|
||||
description: "Updates the network policy for a sprite to control outbound network access with DNS-based filtering"
|
||||
path: "sprites-policy-set"
|
||||
domain_rules:
|
||||
- id: api_integration
|
||||
description: "Must call Sprites API POST /sprites/{name}/policies endpoint"
|
||||
- id: policy_validation
|
||||
description: "Must validate policy format before sending"
|
||||
inputs:
|
||||
- name: name
|
||||
type: string
|
||||
description: "Name of the sprite to update policy for"
|
||||
- name: mode
|
||||
type: "'allow' | 'deny'"
|
||||
description: "Policy mode - 'allow' blocks all except listed, 'deny' allows all except listed"
|
||||
- name: domains
|
||||
type: string[]
|
||||
description: "List of domains to allow or deny based on mode"
|
||||
outputs:
|
||||
- name: policy
|
||||
type: NetworkPolicy
|
||||
description: "Updated network policy"
|
||||
- name: applied
|
||||
type: boolean
|
||||
description: "Whether the policy was successfully applied"
|
||||
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance, readme_documentation]
|
||||
|
||||
# =============================================================================
|
||||
# VALIDATORS - Which validators to run against each block
|
||||
# =============================================================================
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
],
|
||||
"tools": [
|
||||
{
|
||||
"exportName": "churnRiskScoreTool",
|
||||
"name": "churnRiskScoreTool",
|
||||
"description": "Scores customer churn risk based on usage, engagement, and support signals. Provides risk score (0-100) with detailed contributing factors and recommendations.",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
],
|
||||
"tools": [
|
||||
{
|
||||
"exportName": "contentCalendarPlanTool",
|
||||
"name": "contentCalendarPlanTool",
|
||||
"description": "Generates a structured content calendar with posting schedule, themes, topics, and content types. Organizes content by date, channel, and theme while maintaining consistent posting frequency.",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
],
|
||||
"tools": [
|
||||
{
|
||||
"exportName": "createBlogPostTool",
|
||||
"name": "createBlogPostTool",
|
||||
"description": "Creates structured blog posts with customizable frontmatter, content sections, and SEO metadata. Supports multiple output formats including Markdown and MDX.",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
],
|
||||
"tools": [
|
||||
{
|
||||
"exportName": "emailSubjectScoreTool",
|
||||
"name": "emailSubjectScoreTool",
|
||||
"description": "Scores email subject lines for open rate potential based on length, clarity, urgency, curiosity, and personalization. Provides detailed feedback and improvement suggestions.",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
],
|
||||
"tools": [
|
||||
{
|
||||
"exportName": "feedbackThemesTool",
|
||||
"name": "feedbackThemesTool",
|
||||
"description": "Extracts themes and sentiment from customer feedback text. Identifies recurring themes, scores sentiment per theme, and provides frequency counts.",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
],
|
||||
"tools": [
|
||||
{
|
||||
"exportName": "npsAnalysisTool",
|
||||
"name": "npsAnalysisTool",
|
||||
"description": "Analyzes NPS survey responses to categorize by promoter/passive/detractor and extract themes from comments. Provides NPS score, distribution, and actionable insights.",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
],
|
||||
"tools": [
|
||||
{
|
||||
"exportName": "pricingPageCopyTool",
|
||||
"name": "pricingPageCopyTool",
|
||||
"description": "Generates comprehensive pricing page copy with tier names, headlines, benefit-oriented feature lists, CTAs, FAQs, and trust signals. Frames features as benefits and clearly differentiates tiers.",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
],
|
||||
"tools": [
|
||||
{
|
||||
"exportName": "reconciliationMatchTool",
|
||||
"name": "reconciliationMatchTool",
|
||||
"description": "Matches bank transactions to ledger entries for reconciliation. Uses amount, date proximity, and description similarity to identify matches with confidence scoring.",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
],
|
||||
"tools": [
|
||||
{
|
||||
"exportName": "socialPostDraftTool",
|
||||
"name": "socialPostDraftTool",
|
||||
"description": "Drafts social media posts optimized for specific platforms (Twitter, LinkedIn, Instagram, Facebook) with appropriate hashtags, CTAs, and platform-specific best practices. Respects character limits and engagement patterns.",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
"name": "@tpmjs/tools-sprites-checkpoint-create",
|
||||
"version": "0.1.1",
|
||||
"description": "Create a point-in-time snapshot of a sprite's filesystem state for later restoration",
|
||||
"type": "module",
|
||||
"keywords": [
|
||||
"tpmjs",
|
||||
"sprites",
|
||||
"sandbox",
|
||||
"checkpoint",
|
||||
"snapshot",
|
||||
"ai"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"dev": "tsup --watch",
|
||||
"type-check": "tsc --noEmit",
|
||||
"clean": "rm -rf dist .turbo"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tpmjs/tsconfig": "workspace:*",
|
||||
"tsup": "^8.5.1",
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/anthropics/tpmjs.git",
|
||||
"directory": "packages/tools/official/sprites-checkpoint-create"
|
||||
},
|
||||
"homepage": "https://tpmjs.com",
|
||||
"license": "MIT",
|
||||
"tpmjs": {
|
||||
"category": "sandbox",
|
||||
"frameworks": [
|
||||
"vercel-ai"
|
||||
],
|
||||
"tools": [
|
||||
{
|
||||
"name": "spritesCheckpointCreateTool",
|
||||
"description": "Create a point-in-time snapshot of a sprite's filesystem state for later restoration",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string",
|
||||
"description": "Name of the sprite to checkpoint",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "checkpointName",
|
||||
"type": "string",
|
||||
"description": "Optional name for the checkpoint",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"returns": {
|
||||
"type": "Checkpoint",
|
||||
"description": "Created checkpoint with ID and metadata"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"ai": "6.0.23"
|
||||
}
|
||||
}
|
||||
124
packages/tools/official/sprites-checkpoint-create/src/index.ts
Normal file
124
packages/tools/official/sprites-checkpoint-create/src/index.ts
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
/**
|
||||
* Sprites Checkpoint Create Tool for TPMJS
|
||||
* Creates a point-in-time snapshot of a sprite's filesystem state for later restoration.
|
||||
*
|
||||
* @requires SPRITES_TOKEN environment variable
|
||||
*/
|
||||
|
||||
import { jsonSchema, tool } from 'ai';
|
||||
|
||||
const SPRITES_API_BASE = 'https://api.sprites.dev/v1';
|
||||
|
||||
export interface Checkpoint {
|
||||
id: string;
|
||||
name?: string;
|
||||
createdAt: string;
|
||||
size?: number;
|
||||
}
|
||||
|
||||
type SpritesCheckpointCreateInput = {
|
||||
name: string;
|
||||
checkpointName?: string;
|
||||
};
|
||||
|
||||
function getSpritesToken(): string {
|
||||
const token = process.env.SPRITES_TOKEN;
|
||||
if (!token) {
|
||||
throw new Error(
|
||||
'SPRITES_TOKEN environment variable is required. Get your token from https://sprites.dev'
|
||||
);
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
export const spritesCheckpointCreateTool = tool({
|
||||
description:
|
||||
"Create a point-in-time snapshot (checkpoint) of a sprite's filesystem state for later restoration. Useful for saving state before risky operations.",
|
||||
inputSchema: jsonSchema<SpritesCheckpointCreateInput>({
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
description: 'Name of the sprite to checkpoint',
|
||||
},
|
||||
checkpointName: {
|
||||
type: 'string',
|
||||
description: 'Optional human-readable name for the checkpoint',
|
||||
},
|
||||
},
|
||||
required: ['name'],
|
||||
additionalProperties: false,
|
||||
}),
|
||||
async execute({ name, checkpointName }): Promise<Checkpoint> {
|
||||
if (!name || typeof name !== 'string') {
|
||||
throw new Error('Sprite name is required and must be a string');
|
||||
}
|
||||
|
||||
const token = getSpritesToken();
|
||||
|
||||
let response: Response;
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 120000); // 2 min for checkpoints
|
||||
|
||||
const body: Record<string, unknown> = {};
|
||||
if (checkpointName) {
|
||||
body.name = checkpointName;
|
||||
}
|
||||
|
||||
response = await fetch(
|
||||
`${SPRITES_API_BASE}/sprites/${encodeURIComponent(name)}/checkpoints`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
'User-Agent': 'TPMJS/1.0',
|
||||
},
|
||||
body: JSON.stringify(body),
|
||||
signal: controller.signal,
|
||||
}
|
||||
);
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
if (error.name === 'AbortError') {
|
||||
throw new Error(`Request to create checkpoint for sprite "${name}" timed out`);
|
||||
}
|
||||
throw new Error(`Failed to create checkpoint for sprite "${name}": ${error.message}`);
|
||||
}
|
||||
throw new Error(`Failed to create checkpoint for sprite "${name}": Unknown network error`);
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
if (response.status === 404) {
|
||||
throw new Error(`Sprite "${name}" not found`);
|
||||
}
|
||||
if (response.status === 401) {
|
||||
throw new Error('Invalid SPRITES_TOKEN. Check your API token at https://sprites.dev');
|
||||
}
|
||||
const errorText = await response.text().catch(() => 'Unknown error');
|
||||
throw new Error(
|
||||
`Failed to create checkpoint for sprite "${name}": HTTP ${response.status} - ${errorText}`
|
||||
);
|
||||
}
|
||||
|
||||
let data: Record<string, unknown>;
|
||||
try {
|
||||
data = (await response.json()) as Record<string, unknown>;
|
||||
} catch {
|
||||
throw new Error('Failed to parse response from Sprites API');
|
||||
}
|
||||
|
||||
return {
|
||||
id: (data.id as string) || '',
|
||||
name: (data.name as string) || checkpointName,
|
||||
createdAt:
|
||||
(data.createdAt as string) || (data.created_at as string) || new Date().toISOString(),
|
||||
size: data.size as number | undefined,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default spritesCheckpointCreateTool;
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"extends": "@tpmjs/tsconfig/base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"incremental": false,
|
||||
"composite": false
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import { defineConfig } from 'tsup';
|
||||
|
||||
export default defineConfig({
|
||||
entry: ['src/index.ts'],
|
||||
format: ['esm'],
|
||||
dts: true,
|
||||
clean: true,
|
||||
treeshake: true,
|
||||
splitting: false,
|
||||
});
|
||||
71
packages/tools/official/sprites-checkpoint-list/package.json
Normal file
71
packages/tools/official/sprites-checkpoint-list/package.json
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
{
|
||||
"name": "@tpmjs/tools-sprites-checkpoint-list",
|
||||
"version": "0.1.1",
|
||||
"description": "List all checkpoints for a sprite ordered by creation time",
|
||||
"type": "module",
|
||||
"keywords": [
|
||||
"tpmjs",
|
||||
"sprites",
|
||||
"sandbox",
|
||||
"checkpoint",
|
||||
"snapshot",
|
||||
"ai"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"dev": "tsup --watch",
|
||||
"type-check": "tsc --noEmit",
|
||||
"clean": "rm -rf dist .turbo"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tpmjs/tsconfig": "workspace:*",
|
||||
"tsup": "^8.5.1",
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/anthropics/tpmjs.git",
|
||||
"directory": "packages/tools/official/sprites-checkpoint-list"
|
||||
},
|
||||
"homepage": "https://tpmjs.com",
|
||||
"license": "MIT",
|
||||
"tpmjs": {
|
||||
"category": "sandbox",
|
||||
"frameworks": [
|
||||
"vercel-ai"
|
||||
],
|
||||
"tools": [
|
||||
{
|
||||
"name": "spritesCheckpointListTool",
|
||||
"description": "List all checkpoints for a sprite ordered by creation time",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string",
|
||||
"description": "Name of the sprite to list checkpoints for",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"returns": {
|
||||
"type": "{ checkpoints: Checkpoint[], count: number }",
|
||||
"description": "Array of checkpoints with count"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"ai": "6.0.23"
|
||||
}
|
||||
}
|
||||
127
packages/tools/official/sprites-checkpoint-list/src/index.ts
Normal file
127
packages/tools/official/sprites-checkpoint-list/src/index.ts
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
/**
|
||||
* Sprites Checkpoint List Tool for TPMJS
|
||||
* Lists all checkpoints for a sprite ordered by creation time.
|
||||
*
|
||||
* @requires SPRITES_TOKEN environment variable
|
||||
*/
|
||||
|
||||
import { jsonSchema, tool } from 'ai';
|
||||
|
||||
const SPRITES_API_BASE = 'https://api.sprites.dev/v1';
|
||||
|
||||
export interface Checkpoint {
|
||||
id: string;
|
||||
name?: string;
|
||||
createdAt: string;
|
||||
size?: number;
|
||||
}
|
||||
|
||||
export interface SpritesCheckpointListResult {
|
||||
checkpoints: Checkpoint[];
|
||||
count: number;
|
||||
}
|
||||
|
||||
type SpritesCheckpointListInput = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
function getSpritesToken(): string {
|
||||
const token = process.env.SPRITES_TOKEN;
|
||||
if (!token) {
|
||||
throw new Error(
|
||||
'SPRITES_TOKEN environment variable is required. Get your token from https://sprites.dev'
|
||||
);
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
export const spritesCheckpointListTool = tool({
|
||||
description:
|
||||
'List all checkpoints for a sprite ordered by creation time. Use this to find checkpoint IDs for restoration.',
|
||||
inputSchema: jsonSchema<SpritesCheckpointListInput>({
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
description: 'Name of the sprite to list checkpoints for',
|
||||
},
|
||||
},
|
||||
required: ['name'],
|
||||
additionalProperties: false,
|
||||
}),
|
||||
async execute({ name }): Promise<SpritesCheckpointListResult> {
|
||||
if (!name || typeof name !== 'string') {
|
||||
throw new Error('Sprite name is required and must be a string');
|
||||
}
|
||||
|
||||
const token = getSpritesToken();
|
||||
|
||||
let response: Response;
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 30000);
|
||||
|
||||
response = await fetch(
|
||||
`${SPRITES_API_BASE}/sprites/${encodeURIComponent(name)}/checkpoints`,
|
||||
{
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'User-Agent': 'TPMJS/1.0',
|
||||
},
|
||||
signal: controller.signal,
|
||||
}
|
||||
);
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
if (error.name === 'AbortError') {
|
||||
throw new Error(`Request to list checkpoints for sprite "${name}" timed out`);
|
||||
}
|
||||
throw new Error(`Failed to list checkpoints for sprite "${name}": ${error.message}`);
|
||||
}
|
||||
throw new Error(`Failed to list checkpoints for sprite "${name}": Unknown network error`);
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
if (response.status === 404) {
|
||||
throw new Error(`Sprite "${name}" not found`);
|
||||
}
|
||||
if (response.status === 401) {
|
||||
throw new Error('Invalid SPRITES_TOKEN. Check your API token at https://sprites.dev');
|
||||
}
|
||||
const errorText = await response.text().catch(() => 'Unknown error');
|
||||
throw new Error(
|
||||
`Failed to list checkpoints for sprite "${name}": HTTP ${response.status} - ${errorText}`
|
||||
);
|
||||
}
|
||||
|
||||
let data: unknown;
|
||||
try {
|
||||
data = (await response.json()) as Record<string, unknown>;
|
||||
} catch {
|
||||
throw new Error('Failed to parse response from Sprites API');
|
||||
}
|
||||
|
||||
const checkpointsArray = Array.isArray(data)
|
||||
? data
|
||||
: (data as Record<string, unknown>).checkpoints;
|
||||
|
||||
const checkpoints: Checkpoint[] = (Array.isArray(checkpointsArray) ? checkpointsArray : []).map(
|
||||
(c: Record<string, unknown>) => ({
|
||||
id: c.id as string,
|
||||
name: c.name as string | undefined,
|
||||
createdAt: (c.createdAt as string) || (c.created_at as string) || '',
|
||||
size: c.size as number | undefined,
|
||||
})
|
||||
);
|
||||
|
||||
return {
|
||||
checkpoints,
|
||||
count: checkpoints.length,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default spritesCheckpointListTool;
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"extends": "@tpmjs/tsconfig/base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"incremental": false,
|
||||
"composite": false
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import { defineConfig } from 'tsup';
|
||||
|
||||
export default defineConfig({
|
||||
entry: ['src/index.ts'],
|
||||
format: ['esm'],
|
||||
dts: true,
|
||||
clean: true,
|
||||
treeshake: true,
|
||||
splitting: false,
|
||||
});
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
"name": "@tpmjs/tools-sprites-checkpoint-restore",
|
||||
"version": "0.1.1",
|
||||
"description": "Restore a sprite to a previous checkpoint state",
|
||||
"type": "module",
|
||||
"keywords": [
|
||||
"tpmjs",
|
||||
"sprites",
|
||||
"sandbox",
|
||||
"checkpoint",
|
||||
"restore",
|
||||
"ai"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"dev": "tsup --watch",
|
||||
"type-check": "tsc --noEmit",
|
||||
"clean": "rm -rf dist .turbo"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tpmjs/tsconfig": "workspace:*",
|
||||
"tsup": "^8.5.1",
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/anthropics/tpmjs.git",
|
||||
"directory": "packages/tools/official/sprites-checkpoint-restore"
|
||||
},
|
||||
"homepage": "https://tpmjs.com",
|
||||
"license": "MIT",
|
||||
"tpmjs": {
|
||||
"category": "sandbox",
|
||||
"frameworks": [
|
||||
"vercel-ai"
|
||||
],
|
||||
"tools": [
|
||||
{
|
||||
"name": "spritesCheckpointRestoreTool",
|
||||
"description": "Restore a sprite to a previous checkpoint state, reverting all filesystem changes",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string",
|
||||
"description": "Name of the sprite to restore",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "checkpointId",
|
||||
"type": "string",
|
||||
"description": "ID of the checkpoint to restore to",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"returns": {
|
||||
"type": "{ restored: boolean, checkpointId: string, sprite: Sprite }",
|
||||
"description": "Restoration result with sprite status"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"ai": "6.0.23"
|
||||
}
|
||||
}
|
||||
135
packages/tools/official/sprites-checkpoint-restore/src/index.ts
Normal file
135
packages/tools/official/sprites-checkpoint-restore/src/index.ts
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/**
|
||||
* Sprites Checkpoint Restore Tool for TPMJS
|
||||
* Restores a sprite to a previous checkpoint state, reverting all filesystem changes.
|
||||
*
|
||||
* @requires SPRITES_TOKEN environment variable
|
||||
*/
|
||||
|
||||
import { jsonSchema, tool } from 'ai';
|
||||
|
||||
const SPRITES_API_BASE = 'https://api.sprites.dev/v1';
|
||||
|
||||
export interface Sprite {
|
||||
name: string;
|
||||
status: 'creating' | 'running' | 'stopped' | 'error';
|
||||
createdAt: string;
|
||||
runtime?: string;
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface SpritesCheckpointRestoreResult {
|
||||
restored: boolean;
|
||||
checkpointId: string;
|
||||
sprite: Sprite;
|
||||
}
|
||||
|
||||
type SpritesCheckpointRestoreInput = {
|
||||
name: string;
|
||||
checkpointId: string;
|
||||
};
|
||||
|
||||
function getSpritesToken(): string {
|
||||
const token = process.env.SPRITES_TOKEN;
|
||||
if (!token) {
|
||||
throw new Error(
|
||||
'SPRITES_TOKEN environment variable is required. Get your token from https://sprites.dev'
|
||||
);
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
export const spritesCheckpointRestoreTool = tool({
|
||||
description:
|
||||
'Restore a sprite to a previous checkpoint state, reverting all filesystem changes since that checkpoint. Use this to undo changes or recover from errors.',
|
||||
inputSchema: jsonSchema<SpritesCheckpointRestoreInput>({
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
description: 'Name of the sprite to restore',
|
||||
},
|
||||
checkpointId: {
|
||||
type: 'string',
|
||||
description: 'ID of the checkpoint to restore to',
|
||||
},
|
||||
},
|
||||
required: ['name', 'checkpointId'],
|
||||
additionalProperties: false,
|
||||
}),
|
||||
async execute({ name, checkpointId }): Promise<SpritesCheckpointRestoreResult> {
|
||||
if (!name || typeof name !== 'string') {
|
||||
throw new Error('Sprite name is required and must be a string');
|
||||
}
|
||||
if (!checkpointId || typeof checkpointId !== 'string') {
|
||||
throw new Error('Checkpoint ID is required and must be a string');
|
||||
}
|
||||
|
||||
const token = getSpritesToken();
|
||||
|
||||
let response: Response;
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 120000); // 2 min for restore
|
||||
|
||||
response = await fetch(
|
||||
`${SPRITES_API_BASE}/sprites/${encodeURIComponent(name)}/checkpoints/${encodeURIComponent(checkpointId)}/restore`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
'User-Agent': 'TPMJS/1.0',
|
||||
},
|
||||
signal: controller.signal,
|
||||
}
|
||||
);
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
if (error.name === 'AbortError') {
|
||||
throw new Error(`Request to restore checkpoint "${checkpointId}" timed out`);
|
||||
}
|
||||
throw new Error(`Failed to restore checkpoint "${checkpointId}": ${error.message}`);
|
||||
}
|
||||
throw new Error(`Failed to restore checkpoint "${checkpointId}": Unknown network error`);
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
if (response.status === 404) {
|
||||
throw new Error(`Sprite "${name}" or checkpoint "${checkpointId}" not found`);
|
||||
}
|
||||
if (response.status === 401) {
|
||||
throw new Error('Invalid SPRITES_TOKEN. Check your API token at https://sprites.dev');
|
||||
}
|
||||
const errorText = await response.text().catch(() => 'Unknown error');
|
||||
throw new Error(
|
||||
`Failed to restore checkpoint "${checkpointId}": HTTP ${response.status} - ${errorText}`
|
||||
);
|
||||
}
|
||||
|
||||
let data: Record<string, unknown>;
|
||||
try {
|
||||
data = (await response.json()) as Record<string, unknown>;
|
||||
} catch {
|
||||
// If no JSON response, assume success
|
||||
data = {};
|
||||
}
|
||||
|
||||
const spriteData = (data.sprite as Record<string, unknown>) || data;
|
||||
|
||||
return {
|
||||
restored: true,
|
||||
checkpointId,
|
||||
sprite: {
|
||||
name: (spriteData.name as string) || name,
|
||||
status: (spriteData.status as Sprite['status']) || 'running',
|
||||
createdAt: (spriteData.createdAt as string) || '',
|
||||
runtime: spriteData.runtime as string | undefined,
|
||||
metadata: spriteData.metadata as Record<string, unknown> | undefined,
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default spritesCheckpointRestoreTool;
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"extends": "@tpmjs/tsconfig/base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"incremental": false,
|
||||
"composite": false
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import { defineConfig } from 'tsup';
|
||||
|
||||
export default defineConfig({
|
||||
entry: ['src/index.ts'],
|
||||
format: ['esm'],
|
||||
dts: true,
|
||||
clean: true,
|
||||
treeshake: true,
|
||||
splitting: false,
|
||||
});
|
||||
70
packages/tools/official/sprites-create/package.json
Normal file
70
packages/tools/official/sprites-create/package.json
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
{
|
||||
"name": "@tpmjs/tools-sprites-create",
|
||||
"version": "0.1.1",
|
||||
"description": "Create a new isolated Linux sandbox environment (sprite) with persistent filesystem using the Sprites API",
|
||||
"type": "module",
|
||||
"keywords": [
|
||||
"tpmjs",
|
||||
"sprites",
|
||||
"sandbox",
|
||||
"code-execution",
|
||||
"ai"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"dev": "tsup --watch",
|
||||
"type-check": "tsc --noEmit",
|
||||
"clean": "rm -rf dist .turbo"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tpmjs/tsconfig": "workspace:*",
|
||||
"tsup": "^8.5.1",
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/anthropics/tpmjs.git",
|
||||
"directory": "packages/tools/official/sprites-create"
|
||||
},
|
||||
"homepage": "https://tpmjs.com",
|
||||
"license": "MIT",
|
||||
"tpmjs": {
|
||||
"category": "sandbox",
|
||||
"frameworks": [
|
||||
"vercel-ai"
|
||||
],
|
||||
"tools": [
|
||||
{
|
||||
"name": "spritesCreateTool",
|
||||
"description": "Create a new isolated Linux sandbox environment (sprite) with persistent filesystem using the Sprites API",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string",
|
||||
"description": "Unique name for the sprite (must be lowercase alphanumeric with hyphens)",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"returns": {
|
||||
"type": "Sprite",
|
||||
"description": "Created sprite with name, status, and metadata"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"ai": "6.0.23"
|
||||
}
|
||||
}
|
||||
141
packages/tools/official/sprites-create/src/index.ts
Normal file
141
packages/tools/official/sprites-create/src/index.ts
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/**
|
||||
* Sprites Create Tool for TPMJS
|
||||
* Creates a new isolated Linux sandbox environment (sprite) with persistent filesystem
|
||||
* using the Sprites API.
|
||||
*
|
||||
* @requires SPRITES_TOKEN environment variable
|
||||
*/
|
||||
|
||||
import { jsonSchema, tool } from 'ai';
|
||||
|
||||
const SPRITES_API_BASE = 'https://api.sprites.dev/v1';
|
||||
|
||||
/**
|
||||
* Output interface for a sprite
|
||||
*/
|
||||
export interface Sprite {
|
||||
name: string;
|
||||
status: 'creating' | 'running' | 'stopped' | 'error';
|
||||
createdAt: string;
|
||||
runtime?: string;
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
type SpritesCreateInput = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Validates that a sprite name is valid
|
||||
* Must be lowercase alphanumeric with hyphens, 3-63 characters
|
||||
*/
|
||||
function isValidSpriteName(name: string): boolean {
|
||||
return /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/.test(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Sprites API token from environment
|
||||
*/
|
||||
function getSpritesToken(): string {
|
||||
const token = process.env.SPRITES_TOKEN;
|
||||
if (!token) {
|
||||
throw new Error(
|
||||
'SPRITES_TOKEN environment variable is required. Get your token from https://sprites.dev'
|
||||
);
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sprites Create Tool
|
||||
* Creates a new sprite sandbox environment
|
||||
*/
|
||||
export const spritesCreateTool = tool({
|
||||
description:
|
||||
'Create a new isolated Linux sandbox environment (sprite) with persistent filesystem using the Sprites API. Sprites are lightweight VMs for running code securely.',
|
||||
inputSchema: jsonSchema<SpritesCreateInput>({
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
description:
|
||||
'Unique name for the sprite (must be lowercase alphanumeric with hyphens, 3-63 characters)',
|
||||
},
|
||||
},
|
||||
required: ['name'],
|
||||
additionalProperties: false,
|
||||
}),
|
||||
async execute({ name }): Promise<Sprite> {
|
||||
// Validate input
|
||||
if (!name || typeof name !== 'string') {
|
||||
throw new Error('Sprite name is required and must be a string');
|
||||
}
|
||||
|
||||
if (!isValidSpriteName(name)) {
|
||||
throw new Error(
|
||||
`Invalid sprite name: ${name}. Must be lowercase alphanumeric with hyphens, 3-63 characters.`
|
||||
);
|
||||
}
|
||||
|
||||
const token = getSpritesToken();
|
||||
|
||||
// Create the sprite via API
|
||||
let response: Response;
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 60000); // 60s timeout for creation
|
||||
|
||||
response = await fetch(`${SPRITES_API_BASE}/sprites`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
'User-Agent': 'TPMJS/1.0',
|
||||
},
|
||||
body: JSON.stringify({ name }),
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
if (error.name === 'AbortError') {
|
||||
throw new Error(`Request to create sprite "${name}" timed out after 60 seconds`);
|
||||
}
|
||||
throw new Error(`Failed to create sprite "${name}": ${error.message}`);
|
||||
}
|
||||
throw new Error(`Failed to create sprite "${name}": Unknown network error`);
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text().catch(() => 'Unknown error');
|
||||
if (response.status === 401) {
|
||||
throw new Error('Invalid SPRITES_TOKEN. Check your API token at https://sprites.dev');
|
||||
}
|
||||
if (response.status === 409) {
|
||||
throw new Error(`Sprite "${name}" already exists. Choose a different name.`);
|
||||
}
|
||||
throw new Error(`Failed to create sprite "${name}": HTTP ${response.status} - ${errorText}`);
|
||||
}
|
||||
|
||||
// Parse response
|
||||
let data: Record<string, unknown>;
|
||||
try {
|
||||
data = (await response.json()) as Record<string, unknown>;
|
||||
} catch {
|
||||
throw new Error(`Failed to parse response from Sprites API`);
|
||||
}
|
||||
|
||||
const sprite: Sprite = {
|
||||
name: (data.name as string) || name,
|
||||
status: (data.status as Sprite['status']) || 'creating',
|
||||
createdAt: (data.createdAt as string) || new Date().toISOString(),
|
||||
runtime: data.runtime as string | undefined,
|
||||
metadata: data.metadata as Record<string, unknown> | undefined,
|
||||
};
|
||||
|
||||
return sprite;
|
||||
},
|
||||
});
|
||||
|
||||
export default spritesCreateTool;
|
||||
11
packages/tools/official/sprites-create/tsconfig.json
Normal file
11
packages/tools/official/sprites-create/tsconfig.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"extends": "@tpmjs/tsconfig/base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"incremental": false,
|
||||
"composite": false
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
10
packages/tools/official/sprites-create/tsup.config.ts
Normal file
10
packages/tools/official/sprites-create/tsup.config.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { defineConfig } from 'tsup';
|
||||
|
||||
export default defineConfig({
|
||||
entry: ['src/index.ts'],
|
||||
format: ['esm'],
|
||||
dts: true,
|
||||
clean: true,
|
||||
treeshake: true,
|
||||
splitting: false,
|
||||
});
|
||||
70
packages/tools/official/sprites-delete/package.json
Normal file
70
packages/tools/official/sprites-delete/package.json
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
{
|
||||
"name": "@tpmjs/tools-sprites-delete",
|
||||
"version": "0.1.1",
|
||||
"description": "Delete a sprite and all its associated data including checkpoints",
|
||||
"type": "module",
|
||||
"keywords": [
|
||||
"tpmjs",
|
||||
"sprites",
|
||||
"sandbox",
|
||||
"code-execution",
|
||||
"ai"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"dev": "tsup --watch",
|
||||
"type-check": "tsc --noEmit",
|
||||
"clean": "rm -rf dist .turbo"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tpmjs/tsconfig": "workspace:*",
|
||||
"tsup": "^8.5.1",
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/anthropics/tpmjs.git",
|
||||
"directory": "packages/tools/official/sprites-delete"
|
||||
},
|
||||
"homepage": "https://tpmjs.com",
|
||||
"license": "MIT",
|
||||
"tpmjs": {
|
||||
"category": "sandbox",
|
||||
"frameworks": [
|
||||
"vercel-ai"
|
||||
],
|
||||
"tools": [
|
||||
{
|
||||
"name": "spritesDeleteTool",
|
||||
"description": "Delete a sprite and all its associated data including checkpoints",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string",
|
||||
"description": "Name of the sprite to delete",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"returns": {
|
||||
"type": "{ deleted: boolean, name: string }",
|
||||
"description": "Deletion result with success status"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"ai": "6.0.23"
|
||||
}
|
||||
}
|
||||
95
packages/tools/official/sprites-delete/src/index.ts
Normal file
95
packages/tools/official/sprites-delete/src/index.ts
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/**
|
||||
* Sprites Delete Tool for TPMJS
|
||||
* Deletes a sprite and all its associated data including checkpoints.
|
||||
*
|
||||
* @requires SPRITES_TOKEN environment variable
|
||||
*/
|
||||
|
||||
import { jsonSchema, tool } from 'ai';
|
||||
|
||||
const SPRITES_API_BASE = 'https://api.sprites.dev/v1';
|
||||
|
||||
export interface SpritesDeleteResult {
|
||||
deleted: boolean;
|
||||
name: string;
|
||||
}
|
||||
|
||||
type SpritesDeleteInput = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
function getSpritesToken(): string {
|
||||
const token = process.env.SPRITES_TOKEN;
|
||||
if (!token) {
|
||||
throw new Error(
|
||||
'SPRITES_TOKEN environment variable is required. Get your token from https://sprites.dev'
|
||||
);
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
export const spritesDeleteTool = tool({
|
||||
description:
|
||||
'Delete a sprite and all its associated data including checkpoints. This action is irreversible.',
|
||||
inputSchema: jsonSchema<SpritesDeleteInput>({
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
description: 'Name of the sprite to delete',
|
||||
},
|
||||
},
|
||||
required: ['name'],
|
||||
additionalProperties: false,
|
||||
}),
|
||||
async execute({ name }): Promise<SpritesDeleteResult> {
|
||||
if (!name || typeof name !== 'string') {
|
||||
throw new Error('Sprite name is required and must be a string');
|
||||
}
|
||||
|
||||
const token = getSpritesToken();
|
||||
|
||||
let response: Response;
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 30000);
|
||||
|
||||
response = await fetch(`${SPRITES_API_BASE}/sprites/${encodeURIComponent(name)}`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'User-Agent': 'TPMJS/1.0',
|
||||
},
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
if (error.name === 'AbortError') {
|
||||
throw new Error(`Request to delete sprite "${name}" timed out after 30 seconds`);
|
||||
}
|
||||
throw new Error(`Failed to delete sprite "${name}": ${error.message}`);
|
||||
}
|
||||
throw new Error(`Failed to delete sprite "${name}": Unknown network error`);
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
if (response.status === 404) {
|
||||
throw new Error(`Sprite "${name}" not found`);
|
||||
}
|
||||
if (response.status === 401) {
|
||||
throw new Error('Invalid SPRITES_TOKEN. Check your API token at https://sprites.dev');
|
||||
}
|
||||
const errorText = await response.text().catch(() => 'Unknown error');
|
||||
throw new Error(`Failed to delete sprite "${name}": HTTP ${response.status} - ${errorText}`);
|
||||
}
|
||||
|
||||
return {
|
||||
deleted: true,
|
||||
name,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default spritesDeleteTool;
|
||||
11
packages/tools/official/sprites-delete/tsconfig.json
Normal file
11
packages/tools/official/sprites-delete/tsconfig.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"extends": "@tpmjs/tsconfig/base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"incremental": false,
|
||||
"composite": false
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
10
packages/tools/official/sprites-delete/tsup.config.ts
Normal file
10
packages/tools/official/sprites-delete/tsup.config.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { defineConfig } from 'tsup';
|
||||
|
||||
export default defineConfig({
|
||||
entry: ['src/index.ts'],
|
||||
format: ['esm'],
|
||||
dts: true,
|
||||
clean: true,
|
||||
treeshake: true,
|
||||
splitting: false,
|
||||
});
|
||||
88
packages/tools/official/sprites-exec/package.json
Normal file
88
packages/tools/official/sprites-exec/package.json
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
{
|
||||
"name": "@tpmjs/tools-sprites-exec",
|
||||
"version": "0.1.1",
|
||||
"description": "Execute a command inside a sprite and return the output with exit code",
|
||||
"type": "module",
|
||||
"keywords": [
|
||||
"tpmjs",
|
||||
"sprites",
|
||||
"sandbox",
|
||||
"code-execution",
|
||||
"ai"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"dev": "tsup --watch",
|
||||
"type-check": "tsc --noEmit",
|
||||
"clean": "rm -rf dist .turbo"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tpmjs/tsconfig": "workspace:*",
|
||||
"tsup": "^8.5.1",
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/anthropics/tpmjs.git",
|
||||
"directory": "packages/tools/official/sprites-exec"
|
||||
},
|
||||
"homepage": "https://tpmjs.com",
|
||||
"license": "MIT",
|
||||
"tpmjs": {
|
||||
"category": "sandbox",
|
||||
"frameworks": [
|
||||
"vercel-ai"
|
||||
],
|
||||
"tools": [
|
||||
{
|
||||
"name": "spritesExecTool",
|
||||
"description": "Execute a command inside a sprite and return the output with exit code",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string",
|
||||
"description": "Name of the sprite to execute command in",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "cmd",
|
||||
"type": "string",
|
||||
"description": "Command to execute",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "stdin",
|
||||
"type": "string",
|
||||
"description": "Optional stdin input",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "timeoutMs",
|
||||
"type": "number",
|
||||
"description": "Execution timeout in milliseconds",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"returns": {
|
||||
"type": "ExecResult",
|
||||
"description": "Command output with exitCode, stdout, stderr, and duration"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"ai": "6.0.23"
|
||||
}
|
||||
}
|
||||
138
packages/tools/official/sprites-exec/src/index.ts
Normal file
138
packages/tools/official/sprites-exec/src/index.ts
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/**
|
||||
* Sprites Exec Tool for TPMJS
|
||||
* Executes a command inside a sprite and returns the output.
|
||||
* Supports stdin input for interactive commands.
|
||||
*
|
||||
* @requires SPRITES_TOKEN environment variable
|
||||
*/
|
||||
|
||||
import { jsonSchema, tool } from 'ai';
|
||||
|
||||
const SPRITES_API_BASE = 'https://api.sprites.dev/v1';
|
||||
|
||||
export interface ExecResult {
|
||||
exitCode: number;
|
||||
stdout: string;
|
||||
stderr: string;
|
||||
duration: number;
|
||||
}
|
||||
|
||||
type SpritesExecInput = {
|
||||
name: string;
|
||||
cmd: string;
|
||||
stdin?: string;
|
||||
timeoutMs?: number;
|
||||
};
|
||||
|
||||
function getSpritesToken(): string {
|
||||
const token = process.env.SPRITES_TOKEN;
|
||||
if (!token) {
|
||||
throw new Error(
|
||||
'SPRITES_TOKEN environment variable is required. Get your token from https://sprites.dev'
|
||||
);
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
export const spritesExecTool = tool({
|
||||
description:
|
||||
'Execute a command inside a sprite and return the output. Supports stdin input for interactive commands. Returns exit code, stdout, stderr, and execution duration.',
|
||||
inputSchema: jsonSchema<SpritesExecInput>({
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
description: 'Name of the sprite to execute command in',
|
||||
},
|
||||
cmd: {
|
||||
type: 'string',
|
||||
description: "Command to execute (e.g., 'ls -la', 'python script.py')",
|
||||
},
|
||||
stdin: {
|
||||
type: 'string',
|
||||
description: 'Optional stdin input to pass to the command',
|
||||
},
|
||||
timeoutMs: {
|
||||
type: 'number',
|
||||
description: 'Execution timeout in milliseconds (default: 60000)',
|
||||
},
|
||||
},
|
||||
required: ['name', 'cmd'],
|
||||
additionalProperties: false,
|
||||
}),
|
||||
async execute({ name, cmd, stdin, timeoutMs }): Promise<ExecResult> {
|
||||
if (!name || typeof name !== 'string') {
|
||||
throw new Error('Sprite name is required and must be a string');
|
||||
}
|
||||
if (!cmd || typeof cmd !== 'string') {
|
||||
throw new Error('Command is required and must be a string');
|
||||
}
|
||||
|
||||
const token = getSpritesToken();
|
||||
const timeout = timeoutMs || 60000;
|
||||
const startTime = Date.now();
|
||||
|
||||
let response: Response;
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
||||
|
||||
const body: Record<string, unknown> = { cmd };
|
||||
if (stdin) {
|
||||
body.stdin = stdin;
|
||||
}
|
||||
|
||||
response = await fetch(`${SPRITES_API_BASE}/sprites/${encodeURIComponent(name)}/exec`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
'User-Agent': 'TPMJS/1.0',
|
||||
},
|
||||
body: JSON.stringify(body),
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
if (error.name === 'AbortError') {
|
||||
throw new Error(`Command execution in sprite "${name}" timed out after ${timeout}ms`);
|
||||
}
|
||||
throw new Error(`Failed to execute command in sprite "${name}": ${error.message}`);
|
||||
}
|
||||
throw new Error(`Failed to execute command in sprite "${name}": Unknown network error`);
|
||||
}
|
||||
|
||||
const duration = Date.now() - startTime;
|
||||
|
||||
if (!response.ok) {
|
||||
if (response.status === 404) {
|
||||
throw new Error(`Sprite "${name}" not found`);
|
||||
}
|
||||
if (response.status === 401) {
|
||||
throw new Error('Invalid SPRITES_TOKEN. Check your API token at https://sprites.dev');
|
||||
}
|
||||
const errorText = await response.text().catch(() => 'Unknown error');
|
||||
throw new Error(
|
||||
`Failed to execute command in sprite "${name}": HTTP ${response.status} - ${errorText}`
|
||||
);
|
||||
}
|
||||
|
||||
let data: Record<string, unknown>;
|
||||
try {
|
||||
data = (await response.json()) as Record<string, unknown>;
|
||||
} catch {
|
||||
throw new Error('Failed to parse response from Sprites API');
|
||||
}
|
||||
|
||||
return {
|
||||
exitCode: (data.exitCode as number) ?? (data.exit_code as number) ?? 0,
|
||||
stdout: (data.stdout as string) || '',
|
||||
stderr: (data.stderr as string) || '',
|
||||
duration: (data.duration as number) || duration,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default spritesExecTool;
|
||||
11
packages/tools/official/sprites-exec/tsconfig.json
Normal file
11
packages/tools/official/sprites-exec/tsconfig.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"extends": "@tpmjs/tsconfig/base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"incremental": false,
|
||||
"composite": false
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
10
packages/tools/official/sprites-exec/tsup.config.ts
Normal file
10
packages/tools/official/sprites-exec/tsup.config.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { defineConfig } from 'tsup';
|
||||
|
||||
export default defineConfig({
|
||||
entry: ['src/index.ts'],
|
||||
format: ['esm'],
|
||||
dts: true,
|
||||
clean: true,
|
||||
treeshake: true,
|
||||
splitting: false,
|
||||
});
|
||||
70
packages/tools/official/sprites-get/package.json
Normal file
70
packages/tools/official/sprites-get/package.json
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
{
|
||||
"name": "@tpmjs/tools-sprites-get",
|
||||
"version": "0.1.1",
|
||||
"description": "Retrieve details of a specific sprite by name including status and configuration",
|
||||
"type": "module",
|
||||
"keywords": [
|
||||
"tpmjs",
|
||||
"sprites",
|
||||
"sandbox",
|
||||
"code-execution",
|
||||
"ai"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"dev": "tsup --watch",
|
||||
"type-check": "tsc --noEmit",
|
||||
"clean": "rm -rf dist .turbo"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tpmjs/tsconfig": "workspace:*",
|
||||
"tsup": "^8.5.1",
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/anthropics/tpmjs.git",
|
||||
"directory": "packages/tools/official/sprites-get"
|
||||
},
|
||||
"homepage": "https://tpmjs.com",
|
||||
"license": "MIT",
|
||||
"tpmjs": {
|
||||
"category": "sandbox",
|
||||
"frameworks": [
|
||||
"vercel-ai"
|
||||
],
|
||||
"tools": [
|
||||
{
|
||||
"name": "spritesGetTool",
|
||||
"description": "Retrieve details of a specific sprite by name including status and configuration",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string",
|
||||
"description": "Name of the sprite to retrieve",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"returns": {
|
||||
"type": "Sprite",
|
||||
"description": "Sprite details including status and metadata"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"ai": "6.0.23"
|
||||
}
|
||||
}
|
||||
108
packages/tools/official/sprites-get/src/index.ts
Normal file
108
packages/tools/official/sprites-get/src/index.ts
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/**
|
||||
* Sprites Get Tool for TPMJS
|
||||
* Retrieves details of a specific sprite by name including status and configuration.
|
||||
*
|
||||
* @requires SPRITES_TOKEN environment variable
|
||||
*/
|
||||
|
||||
import { jsonSchema, tool } from 'ai';
|
||||
|
||||
const SPRITES_API_BASE = 'https://api.sprites.dev/v1';
|
||||
|
||||
export interface Sprite {
|
||||
name: string;
|
||||
status: 'creating' | 'running' | 'stopped' | 'error';
|
||||
createdAt: string;
|
||||
runtime?: string;
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
type SpritesGetInput = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
function getSpritesToken(): string {
|
||||
const token = process.env.SPRITES_TOKEN;
|
||||
if (!token) {
|
||||
throw new Error(
|
||||
'SPRITES_TOKEN environment variable is required. Get your token from https://sprites.dev'
|
||||
);
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
export const spritesGetTool = tool({
|
||||
description:
|
||||
'Retrieve details of a specific sprite by name including status and configuration. Use this to check if a sprite exists and get its current state.',
|
||||
inputSchema: jsonSchema<SpritesGetInput>({
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
description: 'Name of the sprite to retrieve',
|
||||
},
|
||||
},
|
||||
required: ['name'],
|
||||
additionalProperties: false,
|
||||
}),
|
||||
async execute({ name }): Promise<Sprite> {
|
||||
if (!name || typeof name !== 'string') {
|
||||
throw new Error('Sprite name is required and must be a string');
|
||||
}
|
||||
|
||||
const token = getSpritesToken();
|
||||
|
||||
let response: Response;
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 30000);
|
||||
|
||||
response = await fetch(`${SPRITES_API_BASE}/sprites/${encodeURIComponent(name)}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'User-Agent': 'TPMJS/1.0',
|
||||
},
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
if (error.name === 'AbortError') {
|
||||
throw new Error(`Request to get sprite "${name}" timed out after 30 seconds`);
|
||||
}
|
||||
throw new Error(`Failed to get sprite "${name}": ${error.message}`);
|
||||
}
|
||||
throw new Error(`Failed to get sprite "${name}": Unknown network error`);
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
if (response.status === 404) {
|
||||
throw new Error(`Sprite "${name}" not found`);
|
||||
}
|
||||
if (response.status === 401) {
|
||||
throw new Error('Invalid SPRITES_TOKEN. Check your API token at https://sprites.dev');
|
||||
}
|
||||
const errorText = await response.text().catch(() => 'Unknown error');
|
||||
throw new Error(`Failed to get sprite "${name}": HTTP ${response.status} - ${errorText}`);
|
||||
}
|
||||
|
||||
let data: Record<string, unknown>;
|
||||
try {
|
||||
data = (await response.json()) as Record<string, unknown>;
|
||||
} catch {
|
||||
throw new Error('Failed to parse response from Sprites API');
|
||||
}
|
||||
|
||||
return {
|
||||
name: (data.name as string) || name,
|
||||
status: (data.status as Sprite['status']) || 'running',
|
||||
createdAt: (data.createdAt as string) || '',
|
||||
runtime: data.runtime as string | undefined,
|
||||
metadata: data.metadata as Record<string, unknown> | undefined,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default spritesGetTool;
|
||||
11
packages/tools/official/sprites-get/tsconfig.json
Normal file
11
packages/tools/official/sprites-get/tsconfig.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"extends": "@tpmjs/tsconfig/base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"incremental": false,
|
||||
"composite": false
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
10
packages/tools/official/sprites-get/tsup.config.ts
Normal file
10
packages/tools/official/sprites-get/tsup.config.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { defineConfig } from 'tsup';
|
||||
|
||||
export default defineConfig({
|
||||
entry: ['src/index.ts'],
|
||||
format: ['esm'],
|
||||
dts: true,
|
||||
clean: true,
|
||||
treeshake: true,
|
||||
splitting: false,
|
||||
});
|
||||
63
packages/tools/official/sprites-list/package.json
Normal file
63
packages/tools/official/sprites-list/package.json
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"name": "@tpmjs/tools-sprites-list",
|
||||
"version": "0.1.1",
|
||||
"description": "List all sprites in the account with their current status and metadata",
|
||||
"type": "module",
|
||||
"keywords": [
|
||||
"tpmjs",
|
||||
"sprites",
|
||||
"sandbox",
|
||||
"code-execution",
|
||||
"ai"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"dev": "tsup --watch",
|
||||
"type-check": "tsc --noEmit",
|
||||
"clean": "rm -rf dist .turbo"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tpmjs/tsconfig": "workspace:*",
|
||||
"tsup": "^8.5.1",
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/anthropics/tpmjs.git",
|
||||
"directory": "packages/tools/official/sprites-list"
|
||||
},
|
||||
"homepage": "https://tpmjs.com",
|
||||
"license": "MIT",
|
||||
"tpmjs": {
|
||||
"category": "sandbox",
|
||||
"frameworks": [
|
||||
"vercel-ai"
|
||||
],
|
||||
"tools": [
|
||||
{
|
||||
"name": "spritesListTool",
|
||||
"description": "List all sprites in the account with their current status and metadata",
|
||||
"parameters": [],
|
||||
"returns": {
|
||||
"type": "{ sprites: Sprite[], count: number }",
|
||||
"description": "Array of sprites with count"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"ai": "6.0.23"
|
||||
}
|
||||
}
|
||||
118
packages/tools/official/sprites-list/src/index.ts
Normal file
118
packages/tools/official/sprites-list/src/index.ts
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/**
|
||||
* Sprites List Tool for TPMJS
|
||||
* Lists all sprites in the account with their current status and metadata.
|
||||
*
|
||||
* @requires SPRITES_TOKEN environment variable
|
||||
*/
|
||||
|
||||
import { jsonSchema, tool } from 'ai';
|
||||
|
||||
const SPRITES_API_BASE = 'https://api.sprites.dev/v1';
|
||||
|
||||
export interface Sprite {
|
||||
name: string;
|
||||
status: 'creating' | 'running' | 'stopped' | 'error';
|
||||
createdAt: string;
|
||||
runtime?: string;
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface SpritesListResult {
|
||||
sprites: Sprite[];
|
||||
count: number;
|
||||
}
|
||||
|
||||
function getSpritesToken(): string {
|
||||
const token = process.env.SPRITES_TOKEN;
|
||||
if (!token) {
|
||||
throw new Error(
|
||||
'SPRITES_TOKEN environment variable is required. Get your token from https://sprites.dev'
|
||||
);
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
export const spritesListTool = tool({
|
||||
description:
|
||||
'List all sprites in the account with their current status and metadata. Returns an array of sprites with their names, statuses, and creation times.',
|
||||
inputSchema: jsonSchema<Record<string, never>>({
|
||||
type: 'object',
|
||||
properties: {},
|
||||
additionalProperties: false,
|
||||
}),
|
||||
async execute(): Promise<SpritesListResult> {
|
||||
const token = getSpritesToken();
|
||||
|
||||
let response: Response;
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 30000);
|
||||
|
||||
response = await fetch(`${SPRITES_API_BASE}/sprites`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'User-Agent': 'TPMJS/1.0',
|
||||
},
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
if (error.name === 'AbortError') {
|
||||
throw new Error('Request to list sprites timed out after 30 seconds');
|
||||
}
|
||||
throw new Error(`Failed to list sprites: ${error.message}`);
|
||||
}
|
||||
throw new Error('Failed to list sprites: Unknown network error');
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text().catch(() => 'Unknown error');
|
||||
if (response.status === 401) {
|
||||
throw new Error('Invalid SPRITES_TOKEN. Check your API token at https://sprites.dev');
|
||||
}
|
||||
throw new Error(`Failed to list sprites: HTTP ${response.status} - ${errorText}`);
|
||||
}
|
||||
|
||||
let data: unknown;
|
||||
try {
|
||||
data = (await response.json()) as Record<string, unknown>;
|
||||
} catch {
|
||||
throw new Error('Failed to parse response from Sprites API');
|
||||
}
|
||||
|
||||
// Handle both array response and object with sprites property
|
||||
const spritesArray = Array.isArray(data) ? data : (data as Record<string, unknown>).sprites;
|
||||
|
||||
if (!Array.isArray(spritesArray)) {
|
||||
throw new Error('Invalid response from Sprites API: expected an array of sprites');
|
||||
}
|
||||
|
||||
const sprites: Sprite[] = spritesArray.map((s: unknown) => {
|
||||
const sprite = s as Record<string, unknown>;
|
||||
const status = sprite.status as string | undefined;
|
||||
|
||||
// Validate status is a known value
|
||||
if (status && !['creating', 'running', 'stopped', 'error'].includes(status)) {
|
||||
throw new Error(`Invalid sprite status: ${status}`);
|
||||
}
|
||||
|
||||
return {
|
||||
name: sprite.name as string,
|
||||
status: (status as Sprite['status']) || 'running',
|
||||
createdAt: (sprite.createdAt as string) || '',
|
||||
runtime: sprite.runtime as string | undefined,
|
||||
metadata: sprite.metadata as Record<string, unknown> | undefined,
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
sprites,
|
||||
count: sprites.length,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default spritesListTool;
|
||||
11
packages/tools/official/sprites-list/tsconfig.json
Normal file
11
packages/tools/official/sprites-list/tsconfig.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"extends": "@tpmjs/tsconfig/base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"incremental": false,
|
||||
"composite": false
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
10
packages/tools/official/sprites-list/tsup.config.ts
Normal file
10
packages/tools/official/sprites-list/tsup.config.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { defineConfig } from 'tsup';
|
||||
|
||||
export default defineConfig({
|
||||
entry: ['src/index.ts'],
|
||||
format: ['esm'],
|
||||
dts: true,
|
||||
clean: true,
|
||||
treeshake: true,
|
||||
splitting: false,
|
||||
});
|
||||
71
packages/tools/official/sprites-policy-get/package.json
Normal file
71
packages/tools/official/sprites-policy-get/package.json
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
{
|
||||
"name": "@tpmjs/tools-sprites-policy-get",
|
||||
"version": "0.1.1",
|
||||
"description": "Retrieve the current network policy for a sprite including allowed domains",
|
||||
"type": "module",
|
||||
"keywords": [
|
||||
"tpmjs",
|
||||
"sprites",
|
||||
"sandbox",
|
||||
"network",
|
||||
"policy",
|
||||
"ai"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"dev": "tsup --watch",
|
||||
"type-check": "tsc --noEmit",
|
||||
"clean": "rm -rf dist .turbo"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tpmjs/tsconfig": "workspace:*",
|
||||
"tsup": "^8.5.1",
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/anthropics/tpmjs.git",
|
||||
"directory": "packages/tools/official/sprites-policy-get"
|
||||
},
|
||||
"homepage": "https://tpmjs.com",
|
||||
"license": "MIT",
|
||||
"tpmjs": {
|
||||
"category": "sandbox",
|
||||
"frameworks": [
|
||||
"vercel-ai"
|
||||
],
|
||||
"tools": [
|
||||
{
|
||||
"name": "spritesPolicyGetTool",
|
||||
"description": "Retrieve the current network policy for a sprite including allowed domains",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string",
|
||||
"description": "Name of the sprite to get policy for",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"returns": {
|
||||
"type": "NetworkPolicy",
|
||||
"description": "Current network policy with allowed domains and rules"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"ai": "6.0.23"
|
||||
}
|
||||
}
|
||||
106
packages/tools/official/sprites-policy-get/src/index.ts
Normal file
106
packages/tools/official/sprites-policy-get/src/index.ts
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/**
|
||||
* Sprites Policy Get Tool for TPMJS
|
||||
* Retrieves the current network policy for a sprite including allowed domains.
|
||||
*
|
||||
* @requires SPRITES_TOKEN environment variable
|
||||
*/
|
||||
|
||||
import { jsonSchema, tool } from 'ai';
|
||||
|
||||
const SPRITES_API_BASE = 'https://api.sprites.dev/v1';
|
||||
|
||||
export interface NetworkPolicy {
|
||||
mode: 'allow' | 'deny';
|
||||
domains: string[];
|
||||
rules?: Record<string, unknown>[];
|
||||
}
|
||||
|
||||
type SpritesPolicyGetInput = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
function getSpritesToken(): string {
|
||||
const token = process.env.SPRITES_TOKEN;
|
||||
if (!token) {
|
||||
throw new Error(
|
||||
'SPRITES_TOKEN environment variable is required. Get your token from https://sprites.dev'
|
||||
);
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
export const spritesPolicyGetTool = tool({
|
||||
description:
|
||||
'Retrieve the current network policy for a sprite including allowed domains and filtering rules. Use this to understand what network access a sprite has.',
|
||||
inputSchema: jsonSchema<SpritesPolicyGetInput>({
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
description: 'Name of the sprite to get policy for',
|
||||
},
|
||||
},
|
||||
required: ['name'],
|
||||
additionalProperties: false,
|
||||
}),
|
||||
async execute({ name }): Promise<NetworkPolicy> {
|
||||
if (!name || typeof name !== 'string') {
|
||||
throw new Error('Sprite name is required and must be a string');
|
||||
}
|
||||
|
||||
const token = getSpritesToken();
|
||||
|
||||
let response: Response;
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 30000);
|
||||
|
||||
response = await fetch(`${SPRITES_API_BASE}/sprites/${encodeURIComponent(name)}/policies`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'User-Agent': 'TPMJS/1.0',
|
||||
},
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
if (error.name === 'AbortError') {
|
||||
throw new Error(`Request to get policy for sprite "${name}" timed out`);
|
||||
}
|
||||
throw new Error(`Failed to get policy for sprite "${name}": ${error.message}`);
|
||||
}
|
||||
throw new Error(`Failed to get policy for sprite "${name}": Unknown network error`);
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
if (response.status === 404) {
|
||||
throw new Error(`Sprite "${name}" not found`);
|
||||
}
|
||||
if (response.status === 401) {
|
||||
throw new Error('Invalid SPRITES_TOKEN. Check your API token at https://sprites.dev');
|
||||
}
|
||||
const errorText = await response.text().catch(() => 'Unknown error');
|
||||
throw new Error(
|
||||
`Failed to get policy for sprite "${name}": HTTP ${response.status} - ${errorText}`
|
||||
);
|
||||
}
|
||||
|
||||
let data: Record<string, unknown>;
|
||||
try {
|
||||
data = (await response.json()) as Record<string, unknown>;
|
||||
} catch {
|
||||
throw new Error('Failed to parse response from Sprites API');
|
||||
}
|
||||
|
||||
return {
|
||||
mode: (data.mode as NetworkPolicy['mode']) || 'deny',
|
||||
domains: (data.domains as string[]) || (data.allowedDomains as string[]) || [],
|
||||
rules: data.rules as Record<string, unknown>[] | undefined,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default spritesPolicyGetTool;
|
||||
11
packages/tools/official/sprites-policy-get/tsconfig.json
Normal file
11
packages/tools/official/sprites-policy-get/tsconfig.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"extends": "@tpmjs/tsconfig/base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"incremental": false,
|
||||
"composite": false
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
10
packages/tools/official/sprites-policy-get/tsup.config.ts
Normal file
10
packages/tools/official/sprites-policy-get/tsup.config.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { defineConfig } from 'tsup';
|
||||
|
||||
export default defineConfig({
|
||||
entry: ['src/index.ts'],
|
||||
format: ['esm'],
|
||||
dts: true,
|
||||
clean: true,
|
||||
treeshake: true,
|
||||
splitting: false,
|
||||
});
|
||||
83
packages/tools/official/sprites-policy-set/package.json
Normal file
83
packages/tools/official/sprites-policy-set/package.json
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
{
|
||||
"name": "@tpmjs/tools-sprites-policy-set",
|
||||
"version": "0.1.1",
|
||||
"description": "Update the network policy for a sprite to control outbound network access",
|
||||
"type": "module",
|
||||
"keywords": [
|
||||
"tpmjs",
|
||||
"sprites",
|
||||
"sandbox",
|
||||
"network",
|
||||
"policy",
|
||||
"ai"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"dev": "tsup --watch",
|
||||
"type-check": "tsc --noEmit",
|
||||
"clean": "rm -rf dist .turbo"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tpmjs/tsconfig": "workspace:*",
|
||||
"tsup": "^8.5.1",
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/anthropics/tpmjs.git",
|
||||
"directory": "packages/tools/official/sprites-policy-set"
|
||||
},
|
||||
"homepage": "https://tpmjs.com",
|
||||
"license": "MIT",
|
||||
"tpmjs": {
|
||||
"category": "sandbox",
|
||||
"frameworks": [
|
||||
"vercel-ai"
|
||||
],
|
||||
"tools": [
|
||||
{
|
||||
"name": "spritesPolicySetTool",
|
||||
"description": "Update the network policy for a sprite to control outbound network access",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string",
|
||||
"description": "Name of the sprite to update policy for",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "mode",
|
||||
"type": "'allow' | 'deny'",
|
||||
"description": "Policy mode",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "domains",
|
||||
"type": "string[]",
|
||||
"description": "List of domains to allow or deny",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"returns": {
|
||||
"type": "{ policy: NetworkPolicy, applied: boolean }",
|
||||
"description": "Updated policy and application status"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"ai": "6.0.23"
|
||||
}
|
||||
}
|
||||
136
packages/tools/official/sprites-policy-set/src/index.ts
Normal file
136
packages/tools/official/sprites-policy-set/src/index.ts
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/**
|
||||
* Sprites Policy Set Tool for TPMJS
|
||||
* Updates the network policy for a sprite to control outbound network access.
|
||||
*
|
||||
* @requires SPRITES_TOKEN environment variable
|
||||
*/
|
||||
|
||||
import { jsonSchema, tool } from 'ai';
|
||||
|
||||
const SPRITES_API_BASE = 'https://api.sprites.dev/v1';
|
||||
|
||||
export interface NetworkPolicy {
|
||||
mode: 'allow' | 'deny';
|
||||
domains: string[];
|
||||
rules?: Record<string, unknown>[];
|
||||
}
|
||||
|
||||
export interface SpritesPolicySetResult {
|
||||
policy: NetworkPolicy;
|
||||
applied: boolean;
|
||||
}
|
||||
|
||||
type SpritesPolicySetInput = {
|
||||
name: string;
|
||||
mode: 'allow' | 'deny';
|
||||
domains: string[];
|
||||
};
|
||||
|
||||
function getSpritesToken(): string {
|
||||
const token = process.env.SPRITES_TOKEN;
|
||||
if (!token) {
|
||||
throw new Error(
|
||||
'SPRITES_TOKEN environment variable is required. Get your token from https://sprites.dev'
|
||||
);
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
export const spritesPolicySetTool = tool({
|
||||
description:
|
||||
"Update the network policy for a sprite to control outbound network access with DNS-based filtering. Use 'allow' mode to block all traffic except listed domains, or 'deny' mode to allow all traffic except listed domains.",
|
||||
inputSchema: jsonSchema<SpritesPolicySetInput>({
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
description: 'Name of the sprite to update policy for',
|
||||
},
|
||||
mode: {
|
||||
type: 'string',
|
||||
enum: ['allow', 'deny'],
|
||||
description:
|
||||
"Policy mode - 'allow' blocks all except listed domains, 'deny' allows all except listed domains",
|
||||
},
|
||||
domains: {
|
||||
type: 'array',
|
||||
items: { type: 'string' },
|
||||
description: 'List of domains to allow or deny based on mode',
|
||||
},
|
||||
},
|
||||
required: ['name', 'mode', 'domains'],
|
||||
additionalProperties: false,
|
||||
}),
|
||||
async execute({ name, mode, domains }): Promise<SpritesPolicySetResult> {
|
||||
if (!name || typeof name !== 'string') {
|
||||
throw new Error('Sprite name is required and must be a string');
|
||||
}
|
||||
if (mode !== 'allow' && mode !== 'deny') {
|
||||
throw new Error("Mode must be 'allow' or 'deny'");
|
||||
}
|
||||
if (!Array.isArray(domains)) {
|
||||
throw new Error('Domains must be an array of strings');
|
||||
}
|
||||
|
||||
const token = getSpritesToken();
|
||||
|
||||
let response: Response;
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 30000);
|
||||
|
||||
response = await fetch(`${SPRITES_API_BASE}/sprites/${encodeURIComponent(name)}/policies`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
'User-Agent': 'TPMJS/1.0',
|
||||
},
|
||||
body: JSON.stringify({ mode, domains }),
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
if (error.name === 'AbortError') {
|
||||
throw new Error(`Request to set policy for sprite "${name}" timed out`);
|
||||
}
|
||||
throw new Error(`Failed to set policy for sprite "${name}": ${error.message}`);
|
||||
}
|
||||
throw new Error(`Failed to set policy for sprite "${name}": Unknown network error`);
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
if (response.status === 404) {
|
||||
throw new Error(`Sprite "${name}" not found`);
|
||||
}
|
||||
if (response.status === 401) {
|
||||
throw new Error('Invalid SPRITES_TOKEN. Check your API token at https://sprites.dev');
|
||||
}
|
||||
const errorText = await response.text().catch(() => 'Unknown error');
|
||||
throw new Error(
|
||||
`Failed to set policy for sprite "${name}": HTTP ${response.status} - ${errorText}`
|
||||
);
|
||||
}
|
||||
|
||||
let data: Record<string, unknown>;
|
||||
try {
|
||||
data = (await response.json()) as Record<string, unknown>;
|
||||
} catch {
|
||||
// If no JSON response, assume policy was applied with our input
|
||||
data = { mode, domains };
|
||||
}
|
||||
|
||||
return {
|
||||
policy: {
|
||||
mode: (data.mode as NetworkPolicy['mode']) || mode,
|
||||
domains: (data.domains as string[]) || domains,
|
||||
rules: data.rules as Record<string, unknown>[] | undefined,
|
||||
},
|
||||
applied: true,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default spritesPolicySetTool;
|
||||
11
packages/tools/official/sprites-policy-set/tsconfig.json
Normal file
11
packages/tools/official/sprites-policy-set/tsconfig.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"extends": "@tpmjs/tsconfig/base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"incremental": false,
|
||||
"composite": false
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
10
packages/tools/official/sprites-policy-set/tsup.config.ts
Normal file
10
packages/tools/official/sprites-policy-set/tsup.config.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { defineConfig } from 'tsup';
|
||||
|
||||
export default defineConfig({
|
||||
entry: ['src/index.ts'],
|
||||
format: ['esm'],
|
||||
dts: true,
|
||||
clean: true,
|
||||
treeshake: true,
|
||||
splitting: false,
|
||||
});
|
||||
70
packages/tools/official/sprites-sessions/package.json
Normal file
70
packages/tools/official/sprites-sessions/package.json
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
{
|
||||
"name": "@tpmjs/tools-sprites-sessions",
|
||||
"version": "0.1.1",
|
||||
"description": "List active execution sessions for a sprite",
|
||||
"type": "module",
|
||||
"keywords": [
|
||||
"tpmjs",
|
||||
"sprites",
|
||||
"sandbox",
|
||||
"code-execution",
|
||||
"ai"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"dev": "tsup --watch",
|
||||
"type-check": "tsc --noEmit",
|
||||
"clean": "rm -rf dist .turbo"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tpmjs/tsconfig": "workspace:*",
|
||||
"tsup": "^8.5.1",
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/anthropics/tpmjs.git",
|
||||
"directory": "packages/tools/official/sprites-sessions"
|
||||
},
|
||||
"homepage": "https://tpmjs.com",
|
||||
"license": "MIT",
|
||||
"tpmjs": {
|
||||
"category": "sandbox",
|
||||
"frameworks": [
|
||||
"vercel-ai"
|
||||
],
|
||||
"tools": [
|
||||
{
|
||||
"name": "spritesSessionsTool",
|
||||
"description": "List active execution sessions for a sprite",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string",
|
||||
"description": "Name of the sprite to list sessions for",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"returns": {
|
||||
"type": "{ sessions: ExecSession[], count: number }",
|
||||
"description": "Array of active execution sessions with count"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"ai": "6.0.23"
|
||||
}
|
||||
}
|
||||
125
packages/tools/official/sprites-sessions/src/index.ts
Normal file
125
packages/tools/official/sprites-sessions/src/index.ts
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
/**
|
||||
* Sprites Sessions Tool for TPMJS
|
||||
* Lists active execution sessions for a sprite.
|
||||
*
|
||||
* @requires SPRITES_TOKEN environment variable
|
||||
*/
|
||||
|
||||
import { jsonSchema, tool } from 'ai';
|
||||
|
||||
const SPRITES_API_BASE = 'https://api.sprites.dev/v1';
|
||||
|
||||
export interface ExecSession {
|
||||
id: string;
|
||||
status: 'active' | 'completed' | 'terminated';
|
||||
startedAt: string;
|
||||
command?: string;
|
||||
}
|
||||
|
||||
export interface SpritesSessionsResult {
|
||||
sessions: ExecSession[];
|
||||
count: number;
|
||||
}
|
||||
|
||||
type SpritesSessionsInput = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
function getSpritesToken(): string {
|
||||
const token = process.env.SPRITES_TOKEN;
|
||||
if (!token) {
|
||||
throw new Error(
|
||||
'SPRITES_TOKEN environment variable is required. Get your token from https://sprites.dev'
|
||||
);
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
export const spritesSessionsTool = tool({
|
||||
description:
|
||||
'List active execution sessions for a sprite. Useful for monitoring running commands or attaching to existing sessions.',
|
||||
inputSchema: jsonSchema<SpritesSessionsInput>({
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
description: 'Name of the sprite to list sessions for',
|
||||
},
|
||||
},
|
||||
required: ['name'],
|
||||
additionalProperties: false,
|
||||
}),
|
||||
async execute({ name }): Promise<SpritesSessionsResult> {
|
||||
if (!name || typeof name !== 'string') {
|
||||
throw new Error('Sprite name is required and must be a string');
|
||||
}
|
||||
|
||||
const token = getSpritesToken();
|
||||
|
||||
let response: Response;
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 30000);
|
||||
|
||||
response = await fetch(
|
||||
`${SPRITES_API_BASE}/sprites/${encodeURIComponent(name)}/exec/sessions`,
|
||||
{
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'User-Agent': 'TPMJS/1.0',
|
||||
},
|
||||
signal: controller.signal,
|
||||
}
|
||||
);
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
if (error.name === 'AbortError') {
|
||||
throw new Error(`Request to list sessions for sprite "${name}" timed out`);
|
||||
}
|
||||
throw new Error(`Failed to list sessions for sprite "${name}": ${error.message}`);
|
||||
}
|
||||
throw new Error(`Failed to list sessions for sprite "${name}": Unknown network error`);
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
if (response.status === 404) {
|
||||
throw new Error(`Sprite "${name}" not found`);
|
||||
}
|
||||
if (response.status === 401) {
|
||||
throw new Error('Invalid SPRITES_TOKEN. Check your API token at https://sprites.dev');
|
||||
}
|
||||
const errorText = await response.text().catch(() => 'Unknown error');
|
||||
throw new Error(
|
||||
`Failed to list sessions for sprite "${name}": HTTP ${response.status} - ${errorText}`
|
||||
);
|
||||
}
|
||||
|
||||
let data: unknown;
|
||||
try {
|
||||
data = (await response.json()) as Record<string, unknown>;
|
||||
} catch {
|
||||
throw new Error('Failed to parse response from Sprites API');
|
||||
}
|
||||
|
||||
const sessionsArray = Array.isArray(data) ? data : (data as Record<string, unknown>).sessions;
|
||||
|
||||
const sessions: ExecSession[] = (Array.isArray(sessionsArray) ? sessionsArray : []).map(
|
||||
(s: Record<string, unknown>) => ({
|
||||
id: s.id as string,
|
||||
status: (s.status as ExecSession['status']) || 'active',
|
||||
startedAt: (s.startedAt as string) || (s.started_at as string) || '',
|
||||
command: s.command as string | undefined,
|
||||
})
|
||||
);
|
||||
|
||||
return {
|
||||
sessions,
|
||||
count: sessions.length,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default spritesSessionsTool;
|
||||
11
packages/tools/official/sprites-sessions/tsconfig.json
Normal file
11
packages/tools/official/sprites-sessions/tsconfig.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"extends": "@tpmjs/tsconfig/base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"incremental": false,
|
||||
"composite": false
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
10
packages/tools/official/sprites-sessions/tsup.config.ts
Normal file
10
packages/tools/official/sprites-sessions/tsup.config.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { defineConfig } from 'tsup';
|
||||
|
||||
export default defineConfig({
|
||||
entry: ['src/index.ts'],
|
||||
format: ['esm'],
|
||||
dts: true,
|
||||
clean: true,
|
||||
treeshake: true,
|
||||
splitting: false,
|
||||
});
|
||||
|
|
@ -48,7 +48,7 @@
|
|||
],
|
||||
"tools": [
|
||||
{
|
||||
"exportName": "ticketCategorizeTool",
|
||||
"name": "ticketCategorizeTool",
|
||||
"description": "Categorizes support tickets by type, priority, and product area. Suggests routing based on category and identifies urgent issues requiring immediate attention.",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ Execute a tool from the TPMJS registry by its toolId.
|
|||
|
||||
| Name | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `toolId` | string | Yes | Tool identifier (format: `package::exportName`) |
|
||||
| `toolId` | string | Yes | Tool identifier (format: `package::name`) |
|
||||
| `params` | object | Yes | Parameters to pass to the tool |
|
||||
| `env` | object | No | Environment variables (API keys) if required |
|
||||
|
||||
|
|
|
|||
|
|
@ -44,13 +44,13 @@
|
|||
],
|
||||
"tools": [
|
||||
{
|
||||
"exportName": "registryExecuteTool",
|
||||
"name": "registryExecuteTool",
|
||||
"description": "Execute a tool from the TPMJS registry by toolId. Use registrySearchTool first to find toolIds.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "toolId",
|
||||
"type": "string",
|
||||
"description": "Tool identifier from registrySearchTool (format: 'package::exportName')",
|
||||
"description": "Tool identifier from registrySearchTool (format: 'package::name')",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
],
|
||||
"tools": [
|
||||
{
|
||||
"exportName": "registrySearchTool",
|
||||
"name": "registrySearchTool",
|
||||
"description": "Search the TPMJS tool registry to find AI SDK tools. Returns tool metadata including toolId for use with registryExecuteTool.",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -68,7 +68,7 @@
|
|||
],
|
||||
"returns": {
|
||||
"type": "object",
|
||||
"description": "Search results with tool metadata including toolId, packageName, exportName, description, requiredEnvVars"
|
||||
"description": "Search results with tool metadata including toolId, packageName, name, description, requiredEnvVars"
|
||||
},
|
||||
"aiAgent": {
|
||||
"useCase": "Use when you need to find a tool for a specific task. Search returns toolIds that can be executed with registryExecuteTool.",
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
],
|
||||
"tools": [
|
||||
{
|
||||
"exportName": "searchTpmjsToolsTool",
|
||||
"name": "searchTpmjsToolsTool",
|
||||
"description": "Search the TPMJS tool registry to find AI SDK tools by keyword, category, or description. Returns tool metadata for dynamic loading.",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -54,7 +54,7 @@
|
|||
],
|
||||
"returns": {
|
||||
"type": "object",
|
||||
"description": "Search results with tool metadata including packageName, exportName, version, importUrl"
|
||||
"description": "Search results with tool metadata including packageName, name, version, importUrl"
|
||||
},
|
||||
"aiAgent": {
|
||||
"useCase": "Use when you need a tool that isn't currently available. Search for tools by keyword or domain.",
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@
|
|||
],
|
||||
"tools": [
|
||||
{
|
||||
"exportName": "executeCode",
|
||||
"name": "executeCode",
|
||||
"description": "Execute code synchronously in a secure sandbox. Supports 42+ languages including Python, JavaScript, TypeScript, Go, Rust, and more.",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -99,7 +99,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"exportName": "executeCodeAsync",
|
||||
"name": "executeCodeAsync",
|
||||
"description": "Execute code asynchronously in a secure sandbox. Returns a job_id immediately for tracking.",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -128,7 +128,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"exportName": "runCode",
|
||||
"name": "runCode",
|
||||
"description": "Execute code with automatic language detection from shebang line (e.g., #!/usr/bin/env python3).",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -151,7 +151,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"exportName": "runCodeAsync",
|
||||
"name": "runCodeAsync",
|
||||
"description": "Execute code asynchronously with automatic language detection from shebang.",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -173,7 +173,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"exportName": "listJobs",
|
||||
"name": "listJobs",
|
||||
"description": "List all active jobs for your API key. Jobs are retained for 3 minutes after completion.",
|
||||
"parameters": [],
|
||||
"returns": {
|
||||
|
|
@ -188,7 +188,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"exportName": "getJob",
|
||||
"name": "getJob",
|
||||
"description": "Get status and results of a specific async job.",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -210,7 +210,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"exportName": "cancelJob",
|
||||
"name": "cancelJob",
|
||||
"description": "Cancel a running or pending async job.",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -232,7 +232,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"exportName": "listLanguages",
|
||||
"name": "listLanguages",
|
||||
"description": "List all 42+ supported programming languages and their aliases.",
|
||||
"parameters": [],
|
||||
"returns": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@tpmjs/types",
|
||||
"version": "0.2.0",
|
||||
"version": "0.2.1",
|
||||
"description": "Shared TypeScript types and Zod schemas for TPMJS",
|
||||
"author": "TPMJS",
|
||||
"license": "MIT",
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ export const TPMJS_CATEGORIES = [
|
|||
'statistics',
|
||||
'ops',
|
||||
'agent',
|
||||
'sandbox',
|
||||
'utilities',
|
||||
'html',
|
||||
'compliance',
|
||||
|
|
@ -101,44 +102,23 @@ export type TpmjsAiAgent = z.infer<typeof TpmjsAiAgentSchema>;
|
|||
* Optional fields (auto-extracted if not provided):
|
||||
* - description: A description of what the tool does (20-500 chars) - auto-extracted from tool
|
||||
*
|
||||
* @deprecated fields (now auto-extracted, kept for backward compatibility):
|
||||
* @deprecated fields (now auto-extracted):
|
||||
* - parameters: Tool input parameters - auto-extracted from inputSchema
|
||||
* - returns: Tool return type - auto-extracted from tool
|
||||
* - aiAgent: AI agent guidance - auto-extracted from tool
|
||||
* - exportName: Renamed to 'name' - kept for backward compatibility with published packages
|
||||
*/
|
||||
export const TpmjsToolDefinitionSchema = z
|
||||
.object({
|
||||
// Required: The export name of the tool from the package
|
||||
// Accepts both 'name' and legacy 'exportName' field
|
||||
name: z.string().min(1).optional(),
|
||||
// @deprecated - renamed to 'name', kept for backward compatibility
|
||||
exportName: z.string().min(1).optional(),
|
||||
// Optional - auto-extracted from tool if not provided
|
||||
description: z
|
||||
.string()
|
||||
.min(20, 'Description must be at least 20 characters')
|
||||
.max(500)
|
||||
.optional(),
|
||||
// @deprecated - now auto-extracted from tool's inputSchema
|
||||
parameters: z.array(TpmjsParameterSchema).optional(),
|
||||
// @deprecated - now auto-extracted from tool
|
||||
returns: TpmjsReturnsSchema.optional(),
|
||||
// @deprecated - now auto-extracted from tool
|
||||
aiAgent: TpmjsAiAgentSchema.optional(),
|
||||
})
|
||||
.transform((data) => ({
|
||||
// Transform exportName to name for backward compatibility
|
||||
name: data.name || data.exportName || '',
|
||||
description: data.description,
|
||||
parameters: data.parameters,
|
||||
returns: data.returns,
|
||||
aiAgent: data.aiAgent,
|
||||
}))
|
||||
.refine((data) => data.name.length > 0, {
|
||||
message: 'Either name or exportName is required',
|
||||
path: ['name'],
|
||||
});
|
||||
export const TpmjsToolDefinitionSchema = z.object({
|
||||
// Required: The export name of the tool from the package
|
||||
name: z.string().min(1, 'Tool name is required'),
|
||||
// Optional - auto-extracted from tool if not provided
|
||||
description: z.string().min(20, 'Description must be at least 20 characters').max(500).optional(),
|
||||
// @deprecated - now auto-extracted from tool's inputSchema
|
||||
parameters: z.array(TpmjsParameterSchema).optional(),
|
||||
// @deprecated - now auto-extracted from tool
|
||||
returns: TpmjsReturnsSchema.optional(),
|
||||
// @deprecated - now auto-extracted from tool
|
||||
aiAgent: TpmjsAiAgentSchema.optional(),
|
||||
});
|
||||
|
||||
export type TpmjsToolDefinition = z.infer<typeof TpmjsToolDefinitionSchema>;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue