@sashimo/lib v6.2.0
🌟 Sashi - Your Magical AI-Powered Admin Companion! 🤖
🚀 Welcome to the Enchanted World of Sashi
Sashi is the core TypeScript/JavaScript library that powers the Sashi workflow system. It runs inside your app or service and transforms complex admin tasks into simple conversations. With its AI-powered interface, you can perform admin tasks with the ease of a magical spell. 🪄
✨ Core Features
- 🔹 Function Registration Interface: Declaratively expose your backend functions
- 🔹 Workflow Execution Runtime: Run complex workflows with simple commands
- 🔹 UI Metadata Hooks: Auto-generate beautiful interfaces
- 🔹 SashiHub Integration: Connect with the external SashiHub API
- 🔹 AI-Powered Chat: Execute admin tasks with natural language
- 🔹 Secure & Reliable: Built-in support for sensitive function confirmation
🧩 Core Responsibilities
1. Function Registration
- Provides a
registerFunction()API to declare named functions, their parameters, and return types - Supports:
- Zod-based parameter schemas
- Sync and async functions
- Visualization functions (with metadata)
- Repository-scoped functions
2. Function Metadata
Functions are registered with:
- Name/ID
- Description (used for AI prompt/context)
- Input parameter schema (Zod)
- Return value type (for UI rendering)
- Optional visibility/config flags (e.g., hidden, inactive)
- Automatically generates metadata used by the AI layer and/or workflow editor
3. Workflow Execution
- Accepts a serialized workflow object (steps + parameters) and executes them in sequence
- Handles:
- Parameter chaining
- Type conversion
- Error catching and reporting
- Array mapping (* style execution)
- Optionally runs in debug mode for step-by-step inspection
4. UI Metadata & Type Hints
- Includes utility to infer UI types from data (e.g., table, badge, graph)
- Used by the LLM and front-end UI generator to create input/output forms
5. Communication with SashiHub (sashihub)
- Sends workflow save/load requests to sashihub via authenticated API calls
- Relies on the developer to provide an x-api-token
- Supports repository metadata sync via forward-call or metadata endpoints
🔒 Assumptions and Boundaries
- sashilib is frontend-safe if used in limited exposure contexts
- It does not persist workflows itself — all workflow state lives in sashihub
- It does not handle user auth or rate limiting — this is up to the surrounding app or sashihub
🛠️ Use Cases
- Register custom backend logic to be used in workflows
- Create a shared interface for internal tools or ops automation
- Power AI-driven workflows with securely validated parameters
- Chain local and remote function calls in one workflow
📦 Installation
npm install @usesashi/sashi-lib🔧 Basic Usage
import { createMiddleware, AIFunction } from "@usesashi/sashi-lib"
// Create a function
const getUsers = new AIFunction("get_users", "Get all users")
.args()
.returns({
name: "users",
type: "array",
description: "Array of user objects",
})
.implement(async () => {
return [
{ email: "user1@example.com", name: "User 1" },
{ email: "user2@example.com", name: "User 2" },
]
})
// Create middleware
const router = createMiddleware({
openAIKey: process.env.OPENAI_API_KEY,
sashiServerUrl: "https://your-server.com",
apiSecretKey: "your-secret-key",
})
// Use in Express app
app.use(router)🏷️ Advanced Examples
Basic Example
import {
AIArray,
AIFunction,
AIObject,
registerFunctionIntoAI,
} from "@sashimo/lib"
const UserObject = new AIObject("User", "a user in the system", true).field({
name: "email",
description: "the email of the user",
type: "string",
required: true,
})
const GetUserByIdFunction = new AIFunction("get_user_by_id", "get a user by id")
.args({
name: "userId",
description: "a user's id",
type: "number",
required: true,
})
.returns(UserObject)
.implement(async (userId: number) => {
const user = await getUserById(userId)
return user
})
registerFunctionIntoAI("get_user_by_id", GetUserByIdFunction)Advanced Example: Handling Multiple Objects
const ProductObject = new AIObject(
"Product",
"a product in the inventory",
true
)
.field({
name: "productId",
description: "the unique identifier for a product",
type: "number",
required: true,
})
.field({
name: "productName",
description: "the name of the product",
type: "string",
required: true,
})
const GetProductsFunction = new AIFunction(
"get_products",
"retrieve a list of products"
)
.returns(new AIArray(ProductObject))
.implement(async () => {
const products = await getAllProducts()
return products
})
registerFunctionIntoAI("get_products", GetProductsFunction)Example: Using Enums
import { AIFieldEnum, AIFunction, registerFunctionIntoAI } from "@sashimo/lib"
// Create a function that changes a user's role using an enum
const ChangeUserRoleFunction = new AIFunction(
"change_user_type",
"change a user type"
)
.args(
{
name: "userId",
description: "a users id",
type: "string",
required: true,
},
new AIFieldEnum(
"type",
"the type to change the user to",
["CASE_MANAGER", "COMMUNITY_ENGAGEMENT"],
true
)
)
.returns({
name: "userid",
description: "the user id",
type: "string",
})
.implement(async (userId: string, role: string) => {
// Implementation to change the user's role
console.log("Changing role for user", userId, "to", role)
return userId
})
registerFunctionIntoAI("change_user_type", ChangeUserRoleFunction)This example shows how to:
- Use
AIFieldEnumto create a dropdown selector in the UI - Define allowed values for the enum parameter
- Handle enum validation automatically
- Provide clear descriptions for the UI and AI
🛡️ Security
Protect your magical realm with robust security:
import { Request, Response, NextFunction } from "express"
import { createMiddleware } from "@sashimo/lib"
const verifySessionMiddleware = async (
req: Request,
res: Response,
next: NextFunction
) => {
const sessionToken = req.headers["x-sashi-session-token"]
if (!sessionToken) {
return res.status(401).send("Unauthorized")
}
if (sessionToken !== "userone-session-token") {
return res.status(401).send("Unauthorized")
}
next()
}
app.use(
"/sashi",
verifySessionMiddleware,
createMiddleware({
openAIKey: process.env.OPENAI_API_KEY || "",
getSession: async (req, res) => {
return "userone-session-token"
},
})
)🔍 API Reference
Middleware Options
interface MiddlewareOptions {
openAIKey: string
sashiServerUrl?: string // where the sashi server is hosted if you can't find it automatically
apiSecretKey?: string // used to validate requests from and to the hub
addStdLib?: boolean // add the standard library to the hub
langFuseInfo?: {
publicKey: string
secretKey: string
baseUrl: string
}
getSession?: (req: Request, res: Response) => Promise<string> // function to get the session id for a request
}📚 Documentation
For more spells and incantations, visit our Sashi documentation.
🤝 Join the Sashi Fellowship
Are you ready to make admin tasks a breeze? Join us on this magical journey! Check out our Contributing Guide.
⚖️ License
Sashi is released under the MIT License.
🔄 Workflow System
This update introduces a powerful workflow system that enables users to create automated sequences of your registered functions.
📊 How Workflows Work
Once you register your functions with Sashi, they automatically become available for use in workflows. Users can then:
- Create sequences of actions using your registered functions
- Pass data between steps - Output from one function becomes input to another
- Save and reuse workflows for common tasks
- Execute workflows with a single click instead of multiple manual steps
graph TD
A[Register Functions] --> B[Functions Available in Workflow System]
B --> C[Users Create Workflows]
C --> D[Workflows Executed When Needed]
D --> E[Results Displayed to User]
A1[Developer] --> A
C1[End User] --> C
style A fill:#a4c2f4
style B fill:#b6d7a8
style C fill:#f9d77e
style D fill:#d5a6bd
style E fill:#ea9999
style A1,C1 fill:#d9d9d9🔗 Function Integration in Workflows
Your registered functions become building blocks that users can connect together:
graph LR
A[Function: Get Users] --> B[Function: Filter Active Users]
B --> C[Function: Send Notification]
A1[Output: User List] --> B1[Input: Users]
B2[Output: Filtered Users] --> C1[Input: Recipients]
style A,B,C fill:#a4c2f4
style A1,B1,B2,C1 fill:#d5a6bd🌐 Data Flow Between Systems
The workflow system handles all the data flow between your registered functions and external systems without you needing to implement any additional code:
sequenceDiagram
participant Dev as Developer
participant Sashi as Sashi System
participant User as User
participant Ext as External Services
Dev->>Sashi: Register functions
User->>Sashi: Create workflows using functions
User->>Sashi: Execute workflow
Sashi->>Ext: Call external APIs if needed
Ext-->>Sashi: Return results
Sashi->>Sashi: Process data between steps
Sashi-->>User: Display final results📝 What You Need To Do
As a developer, you only need to:
- Register your functions using the AIFunction system (as shown in previous examples)
- Ensure proper input/output typing so the workflow system knows what data can be passed between steps
- Document your functions well so users understand what each function does
The workflow storage, execution, and visualization are all handled automatically by the Sashi system.
For more information on how users can use the workflows you enable, direct them to our Workflow Documentation.
5 months ago
5 months ago
5 months ago
6 months ago
6 months ago
6 months ago
6 months ago
5 months ago
5 months ago
5 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
6 months ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago