Kdeps is an all-in-one AI framework for building Dockerized full-stack AI applications (FE and BE) that includes open-source LLM models out-of-the-box.
Kdeps is loaded with features to streamline full-stack AI app development:
π§© Low-code/no-code capabilities
Build operational full-stack AI apps, enabling accessible development for non-technical users.// workflow.pkl
Name = "ticketResolutionAgent"
Description = "Automates customer support ticket resolution with LLM responses."
Version = "1.0.0"
TargetActionID = "responseResource"
Settings {
APIServerMode = true
APIServer {
HostIP = "127.0.0.1"
PortNum = 3000
Routes {
new { Path = "/api/v1/ticket"; Methods { "POST" } }
}
CORS { EnableCORS = true; AllowOrigins { "http://localhost:8080" } }
}
AgentSettings {
Timezone = "Etc/UTC"
Models { "llama3.2:1b" }
OllamaImageTag = "0.6.8"
}
}// resources/fetch_data.pkl
ActionID = "httpFetchResource"
Name = "CRM Fetch"
Description = "Fetches ticket data via CRM API."
run {
RestrictToHTTPMethods { "POST" }
RestrictToRoutes { "/api/v1/ticket" }
PreflightCheck {
Validations { "@(request.data().ticket_id)" != "" }
}
HTTPClient {
Method = "GET"
Url = "https://crm.example.com/api/ticket/@(request.data().ticket_id)"
Headers { ["Authorization"] = "Bearer @(session.getRecord('crm_token'))" }
TimeoutDuration = 30.s
}
}// resources/llm.pkl
ActionID = "llmResource"
Name = "LLM Ticket Response"
Description = "Generates responses for customer tickets."
Requires { "httpFetchResource" }
run {
RestrictToHTTPMethods { "POST" }
RestrictToRoutes { "/api/v1/ticket" }
Chat {
Model = "llama3.2:1b"
Role = "assistant"
Prompt = "Provide a professional response to the customer query: @(request.data().query)"
Scenario {
new { Role = "system"; Prompt = "You are a customer support assistant. Be polite and concise." }
new { Role = "system"; Prompt = "Ticket data: @(client.responseBody("httpFetchResource"))" }
}
JSONResponse = true
JSONResponseKeys { "response_text" }
TimeoutDuration = 60.s
}
}// resources/response.pkl
ActionID = "responseResource"
Name = "API Response"
Description = "Returns ticket resolution response."
Requires { "llmResource" }
run {
RestrictToHTTPMethods { "POST" }
RestrictToRoutes { "/api/v1/ticket" }
APIResponse {
Success = true
Response {
Data { "@(llm.response('llmResource'))" }
}
Meta { Headers { ["Content-Type"] = "application/json" } }
}
}π³ Dockerized full-stack AI apps
Build applications with batteries included for seamless development and deployment, as detailed in the AI agent settings.# Creating a Docker image of the kdeps AI agent is easy!
# First, package the AI agent project.
$ kdeps package tickets-ai/
INFO kdeps package created package-file=tickets-ai-1.0.0.kdeps
# Then build a docker image and run.
$ kdeps run tickets-ai-1.0.0.kdeps
# It also creates a Docker compose configuration file.# docker-compose.yml
version: '3.8'
services:
kdeps-tickets-ai-cpu:
image: kdeps-tickets-ai:1.0.0
ports:
- "127.0.0.1:3000"
restart: on-failure
volumes:
- ollama:/root/.ollama
- kdeps:/.kdeps
volumes:
ollama:
external:
name: ollama
kdeps:
external:
name: kdepsπΌοΈ Support for vision or multimodal LLMs
Process text, images, and other data types in a single workflow with vision or multimodal LLMs.// workflow.pkl
Name = "visualTicketAnalyzer"
Description = "Analyzes images in support tickets for defects using a vision model."
Version = "1.0.0"
TargetActionID = "responseResource"
Settings {
APIServerMode = true
APIServer {
HostIP = "127.0.0.1"
PortNum = 3000
Routes {
new { Path = "/api/v1/visual-ticket"; Methods { "POST" } }
}
CORS { EnableCORS = true; AllowOrigins { "http://localhost:8080" } }
}
AgentSettings {
Timezone = "Etc/UTC"
Models { "llama3.2-vision" }
OllamaImageTag = "0.6.8"
}
}// resources/fetch_data.pkl
ActionID = "httpFetchResource"
Name = "CRM Fetch"
Description = "Fetches ticket data via CRM API."
run {
RestrictToHTTPMethods { "POST" }
RestrictToRoutes { "/api/v1/ticket" }
PreflightCheck {
Validations { "@(request.data().ticket_id)" != "" }
}
HTTPClient {
Method = "GET"
Url = "https://crm.example.com/api/ticket/@(request.data().ticket_id)"
Headers { ["Authorization"] = "Bearer @(session.getRecord('crm_token'))" }
TimeoutDuration = 30.s
}
}// resources/llm.pkl
ActionID = "llmResource"
Name = "Visual Defect Analyzer"
Description = "Analyzes ticket images for defects."
Requires { "httpFetchResource" }
run {
RestrictToHTTPMethods { "POST" }
RestrictToRoutes { "/api/v1/visual-ticket" }
PreflightCheck {
Validations { "@(request.filecount())" > 0 }
}
Chat {
Model = "llama3.2-vision"
Role = "assistant"
Prompt = "Analyze the image for product defects and describe any issues found."
Files { "@(request.files()[0])" }
Scenario {
new { Role = "system"; Prompt = "You are a support assistant specializing in visual defect detection." }
new { Role = "system"; Prompt = "Ticket data: @(client.responseBody("httpFetchResource"))" }
}
JSONResponse = true
JSONResponseKeys { "defect_description"; "severity" }
TimeoutDuration = 60.s
}
}// resources/response.pkl
ActionID = "responseResource"
Name = "API Response"
Description = "Returns defect analysis result."
Requires { "llmResource" }
run {
RestrictToHTTPMethods { "POST" }
RestrictToRoutes { "/api/v1/visual-ticket" }
APIResponse {
Success = true
Response {
Data { "@(llm.response('llmResource'))" }
}
Meta { Headers { ["Content-Type"] = "application/json" } }
}
}π Create custom AI APIs
Serve open-source LLMs through custom AI APIs for robust AI-driven applications.π Pair APIs with frontend apps
Integrate with frontend apps like Streamlit, NodeJS, and more for interactive AI-driven user interfaces, as outlined in web server settings.// workflow.pkl
Name = "frontendAIApp"
Description = "Pairs an AI API with a Streamlit frontend for text summarization."
Version = "1.0.0"
TargetActionID = "responseResource"
Settings {
APIServerMode = true
WebServerMode = true
APIServer {
HostIP = "127.0.0.1"
PortNum = 3000
Routes {
new { Path = "/api/v1/summarize"; Methods { "POST" } }
}
}
WebServer {
HostIP = "127.0.0.1"
PortNum = 8501
Routes {
new {
Path = "/app"
PublicPath = "/fe/1.0.0/web/"
ServerType = "app"
AppPort = 8501
Command = "streamlit run app.py"
}
}
}
AgentSettings {
Timezone = "Etc/UTC"
PythonPackages { "streamlit" }
Models { "llama3.2:1b" }
OllamaImageTag = "0.6.8"
}
}// data/fe/web/app.py (Streamlit frontend)
import streamlit as st
import requests
st.title("Text Summarizer")
text = st.text_area("Enter text to summarize")
if st.button("Summarize"):
response = requests.post("http://localhost:3000/api/v1/summarize", json={"text": text})
if response.ok:
st.write(response.json()['response']['data']['summary'])
else:
st.error("Error summarizing text")// resources/llm.pkl
ActionID = "llmResource"
Name = "Text Summarizer"
Description = "Summarizes input text using an LLM."
run {
RestrictToHTTPMethods { "POST" }
RestrictToRoutes { "/api/v1/summarize" }
Chat {
Model = "llama3.2:1b"
Role = "assistant"
Prompt = "Summarize this text in 50 words or less: @(request.data().text)"
JSONResponse = true
JSONResponseKeys { "summary" }
TimeoutDuration = 60.s
}
}π οΈ Let LLMs run tools automatically (aka MCP or A2A)
Enhance functionality through scripts and sequential tool pipelines with external tools and chained tool workflows.// workflow.pkl
Name = "toolChainingAgent"
Description = "Uses LLM to query a database and generate a report via tools."
Version = "1.0.0"
TargetActionID = "responseResource"
Settings {
APIServerMode = true
APIServer {
HostIP = "127.0.0.1"
PortNum = 3000
Routes {
new { Path = "/api/v1/report"; Methods { "POST" } }
}
}
AgentSettings {
Timezone = "Etc/UTC"
Models { "llama3.2:1b" }
OllamaImageTag = "0.6.8"
}
}// resources/llm.pkl
ActionID = "llmResource"
Name = "Report Generator"
Description = "Generates a report using a database query tool."
run {
RestrictToHTTPMethods { "POST" }
RestrictToRoutes { "/api/v1/report" }
Chat {
Model = "llama3.2:1b"
Role = "assistant"
Prompt = "Generate a sales report based on database query results. Date range: @(request.params("date_range"))"
Tools {
new {
Name = "query_sales_db"
Script = "@(data.filepath('tools/1.0.0', 'query_sales.py'))"
Description = "Queries the sales database for recent transactions"
Parameters {
["date_range"] { Required = true; Type = "string"; Description = "Date range for query (e.g., '2025-01-01:2025-05-01')" }
}
}
}
JSONResponse = true
JSONResponseKeys { "report" }
TimeoutDuration = 60.s
}
}// data/tools/query_sales.py
import sqlite3
import sys
def query_sales(date_range):
start, end = date_range.split(':')
conn = sqlite3.connect('sales.db')
cursor = conn.execute("SELECT * FROM transactions WHERE date BETWEEN ? AND ?", (start, end))
results = cursor.fetchall()
conn.close()
return results
print(query_sales(sys.argv[1]))π Context-aware RAG workflows
Enable accurate, knowledge-intensive tasks with RAG workflows.π Generate structured outputs
Create consistent, machine-readable responses from LLMs, as described in the chat block documentation.// workflow.pkl
Name = "structuredOutputAgent"
Description = "Generates structured JSON responses from LLM."
Version = "1.0.0"
TargetActionID = "responseResource"
Settings {
APIServerMode = true
APIServer {
HostIP = "127.0.0.1"
PortNum = 3000
Routes {
new { Path = "/api/v1/structured"; Methods { "POST" } }
}
}
AgentSettings {
Timezone = "Etc/UTC"
Models { "llama3.2:1b" }
OllamaImageTag = "0.6.8"
}
}// resources/llm.pkl
ActionID = "llmResource"
Name = "Structured Response Generator"
Description = "Generates structured JSON output."
run {
RestrictToHTTPMethods { "POST" }
RestrictToRoutes { "/api/v1/structured" }
Chat {
Model = "llama3.2:1b"
Role = "assistant"
Prompt = "Analyze this text and return a structured response: @(request.data().text)"
JSONResponse = true
JSONResponseKeys { "summary"; "keywords" }
TimeoutDuration = 60.s
}
}π Items iteration
Iterate over multiple items in a resource to process them sequentially, using items iteration with `item.current()`, `item.prev()`, and `item.next()`.// workflow.pkl
Name = "mtvScenarioGenerator"
Description = "Generates MTV video scenarios based on song lyrics."
Version = "1.0.0"
TargetActionID = "responseResource"
Settings {
APIServerMode = true
APIServer {
HostIP = "127.0.0.1"
PortNum = 3000
Routes {
new { Path = "/api/v1/mtv-scenarios"; Methods { "GET" } }
}
CORS { EnableCORS = true; AllowOrigins { "http://localhost:8080" } }
}
AgentSettings {
Timezone = "Etc/UTC"
Models { "llama3.2:1b" }
OllamaImageTag = "0.6.8"
}
}// resources/llm.pkl
ActionID = "llmResource"
Name = "MTV Scenario Generator"
Description = "Generates MTV video scenarios for song lyrics."
Items {
"A long, long time ago"
"I can still remember"
"How that music used to make me smile"
"And I knew if I had my chance"
}
run {
RestrictToHTTPMethods { "GET" }
RestrictToRoutes { "/api/v1/mtv-scenarios" }
SkipCondition {
"@(item.current())" == "And I knew if I had my chance" // Skip this lyric
}
Chat {
Model = "llama3.2:1b"
Role = "assistant"
Prompt = """
Based on the lyric @(item.current()) from the song "American Pie," generate a suitable scenario for an MTV music video. The scenario should include a vivid setting, key visual elements, and a mood that matches the lyric's tone.
"""
Scenario {
new { Role = "system"; Prompt = "You are a creative director specializing in music video production." }
}
JSONResponse = true
JSONResponseKeys { "setting"; "visual_elements"; "mood" }
TimeoutDuration = 60.s
}
}// resources/response.pkl
ActionID = "responseResource"
Name = "API Response"
Description = "Returns MTV video scenarios."
Requires { "llmResource" }
run {
RestrictToHTTPMethods { "GET" }
RestrictToRoutes { "/api/v1/mtv-scenarios" }
APIResponse {
Success = true
Response {
Data { "@(llm.response('llmResource'))" }
}
Meta { Headers { ["Content-Type"] = "application/json" } }
}
}π€ Leverage multiple open-source LLMs
Use LLMs from Ollama and Huggingface for diverse AI capabilities.// workflow.pkl
Models {
"tinydolphin"
"llama3.3"
"llama3.2-vision"
"llama3.2:1b"
"mistral"
"gemma"
"mistral"
}ποΈ Upload documents or files
Process documents for LLM analysis, ideal for document analysis tasks, as shown in the file upload tutorial.// workflow.pkl
Name = "docAnalysisAgent"
Description = "Analyzes uploaded documents with LLM."
Version = "1.0.0"
TargetActionID = "responseResource"
Settings {
APIServerMode = true
APIServer {
HostIP = "127.0.0.1"
PortNum = 3000
Routes {
new { Path = "/api/v1/doc-analyze"; Methods { "POST" } }
}
}
AgentSettings {
Timezone = "Etc/UTC"
Models { "llama3.2-vision" }
OllamaImageTag = "0.6.8"
}
}// resources/llm.pkl
ActionID = "llmResource"
Name = "Document Analyzer"
Description = "Extracts text from uploaded documents."
run {
RestrictToHTTPMethods { "POST" }
RestrictToRoutes { "/api/v1/doc-analyze" }
PreflightCheck {
Validations { "@(request.filecount())" > 0 }
}
Chat {
Model = "llama3.2-vision"
Role = "assistant"
Prompt = "Extract key information from this document."
Files { "@(request.files()[0])" }
JSONResponse = true
JSONResponseKeys { "key_info" }
TimeoutDuration = 60.s
}
}π Reusable AI agents
Create flexible workflows with reusable AI agents.// workflow.pkl
Name = "docAnalysisAgent"
Description = "Analyzes uploaded documents with LLM."
Version = "1.0.0"
TargetActionID = "responseResource"
Workflows { "@ticketResolutionAgent" }
Settings {
APIServerMode = true
APIServer {
HostIP = "127.0.0.1"
PortNum = 3000
Routes {
new { Path = "/api/v1/doc-analyze"; Methods { "POST" } }
}
}
AgentSettings {
Timezone = "Etc/UTC"
Models { "llama3.2-vision" }
OllamaImageTag = "0.6.8"
}
}// resources/response.pkl
ActionID = "responseResource"
Name = "API Response"
Description = "Returns defect analysis result."
Requires {
"llmResource"
"@ticketResolutionAgent/llmResource:1.0.0"
}
run {
RestrictToHTTPMethods { "POST" }
RestrictToRoutes { "/api/v1/doc-analyze" }
APIResponse {
Success = true
Response {
Data {
"@(llm.response("llmResource"))"
"@(llm.response('@ticketResolutionAgent/llmResource:1.0.0'))"
}
}
Meta { Headers { ["Content-Type"] = "application/json" } }
}
}π Execute Python in isolated environments
Run Python code securely using Anaconda in isolated environments.// resources/python.pkl
ActionID = "pythonResource"
Name = "Data Formatter"
Description = "Formats extracted data for storage."
run {
RestrictToHTTPMethods { "POST" }
RestrictToRoutes { "/api/v1/scan-document" }
Python {
Script = """
import pandas as pd
def format_data(data):
df = pd.DataFrame([data])
return df.to_json()
print(format_data(@(llm.response('llmResource'))))
"""
TimeoutDuration = 60.s
}
}π Make API calls
Perform API calls directly from configuration, as detailed in the client documentation.// resources/http_client.pkl
ActionID = "httpResource"
Name = "DMS Submission"
Description = "Submits extracted data to document management system."
run {
RestrictToHTTPMethods { "POST" }
RestrictToRoutes { "/api/v1/scan-document" }
HTTPClient {
Method = "POST"
Url = "https://dms.example.com/api/documents"
Data { "@(python.stdout('pythonResource'))" }
Headers { ["Authorization"] = "Bearer @(session.getRecord('dms_token'))" }
TimeoutDuration = 30.s
}
}β Built-in validations and checks
Utilize API request validations, custom validation checks, and skip conditions for robust workflows.RestrictToHTTPMethods { "POST" }
RestrictToRoutes { "/api/v1/scan-document" }
PreflightCheck {
Validations { "@(request.filetype('document'))" == "image/jpeg" }
}
SkipCondition { "@(request.data().query.length)" < 5 }π Serve static websites or reverse-proxied apps
Host static websites or reverse-proxied apps directly.// workflow.pkl
Name = "frontendAIApp"
Description = "Pairs an AI API with a Streamlit frontend for text summarization."
Version = "1.0.0"
TargetActionID = "responseResource"
Settings {
APIServerMode = true
WebServerMode = true
APIServer {
HostIP = "127.0.0.1"
PortNum = 3000
Routes {
new { Path = "/api/v1/summarize"; Methods { "POST" } }
}
}
WebServer {
HostIP = "127.0.0.1"
PortNum = 8501
Routes {
new {
Path = "/app"
ServerType = "app"
AppPort = 8501
Command = "streamlit run app.py"
}
}
}
AgentSettings {
Timezone = "Etc/UTC"
PythonPackages { "streamlit" }
Models { "llama3.2:1b" }
OllamaImageTag = "0.6.8"
}
}πΎ Manage state with memory operations
Store, retrieve, and clear persistent data using memory operations.expr {
"@(memory.setRecord('user_data', request.data().data))"
}
local user_data = "@(memory.getRecord('user_data'))"π Configure CORS rules
Set CORS rules directly in the workflow for secure API access.// workflow.pkl
CORS {
EnableCORS = true
AllowOrigins { "https://example.com" }
AllowMethods { "GET"; "POST" }
}π‘οΈ Set trusted proxies
Enhance API and frontend security with trusted proxies.// workflow.pkl
APIServerMode = true
APIServer {
HostIP = "127.0.0.1"
PortNum = 3000
Routes {
new { Path = "/api/v1/proxy"; Methods { "GET" } }
}
TrustedProxies { "192.168.1.1"; "10.0.0.0/8" }
}π₯οΈ Run shell scripts
Execute shell scripts seamlessly within workflows.// resources/exec.pkl
ActionID = "execResource"
Name = "Shell Script Runner"
Description = "Runs a shell script."
run {
Exec {
Command = """
echo "Processing request at $(date)"
"""
TimeoutDuration = 60.s
}
}π¦ Install Ubuntu packages
Install Ubuntu packages via configuration for customized environments.// workflow.pkl
AgentSettings {
Timezone = "Etc/UTC"
Packages {
"tesseract-ocr"
"poppler-utils"
"npm"
"ffmpeg"
}
OllamaImageTag = "0.6.8"
}π Define Ubuntu repositories or PPAs
Configure Ubuntu repositories or PPAs for additional package sources.// workflow.pkl
Repositories {
"ppa:alex-p/tesseract-ocr-devel"
}β‘ Written in high-performance Golang
Benefit from the speed and efficiency of Golang for high-performance applications.π₯ Easy to install
Install and use Kdeps with a single command, as outlined in the installation guide.# On macOS
brew install kdeps/tap/kdeps
# Windows, Linux, and macOS
curl -LsSf https://raw.githubusercontent.com/kdeps/kdeps/refs/heads/main/install.sh | shReady to explore Kdeps? Install it with a single command: Installation Guide.
Check out practical examples to jumpstart your projects.