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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,13 @@ INSTANCE_SECRET=0516d5cddc8b9bbc01238b8696f13c711983f45f6dc4dbf9dc66ba42fc16f504
#
# METRICS_BEARER_TOKEN=

# ============================================================================
# OPTIONAL: Provider Secrets Encryption
# ============================================================================
# Age secret key used by SOPS to decrypt provider secret files (*.secrets.json).
# Auto-generated by tale init, or generate manually with: age-keygen
# SOPS_AGE_KEY=

# ============================================================================
# OPTIONAL: Operator Service (Browser Automation)
# ============================================================================
Expand Down
13 changes: 12 additions & 1 deletion bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,8 @@ services:
- caddy-data:/caddy-data:ro
# Development: mount local agents directory to override defaults
# - ./examples/agents:/app/data/agents
# Development: mount local provider configs
# - ./examples/providers:/app/data/providers

# Environment file
# Create a .env file in the project root with your configuration
Expand Down
2 changes: 1 addition & 1 deletion examples/agents/chat-agent.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"document_find",
"document_write"
],
"modelPreset": "standard",
"supportedModels": ["moonshotai/kimi-k2.5", "deepseek/deepseek-v3.2"],
"knowledgeMode": "tool",
"includeOrgKnowledge": true,
"structuredResponsesEnabled": true,
Expand Down
3 changes: 1 addition & 2 deletions examples/agents/crm-assistant.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
"description": "Looks up customer and product information",
"displayName": "Sales Assistant",
"maxSteps": 10,
"modelId": "anthropic/claude-opus-4.6",
"modelPreset": "advanced",
"supportedModels": ["anthropic/claude-opus-4.6", "openai/gpt-5.2"],
"outputReserve": 2048,
"structuredResponsesEnabled": false,
"systemInstructions": "You are a CRM assistant specialized in retrieving customer and product data.\n\n**KNOWLEDGE SCOPE**\nYou access ONLY the organization's internal customer and product database.\nFor data from external systems (Shopify, Salesforce, PMS, etc.), the user needs the Integration Assistant — integrations are configured in [Settings > Integrations]({{site_url}}/dashboard/{{organization.id}}/settings/integrations).\n\n**AVAILABLE TOOLS**\n- customer_read: Read customer data (get_by_id, get_by_email, list operations)\n- product_read: Read product data (get_by_id, list operations)\n\n**ACTION-FIRST PRINCIPLE**\nSearch first, but STOP and ask when multiple matches are found.\n\nALWAYS search first:\n• User mentions a name → search by name/email, don't ask for ID\n• User says \"the customer\" → check conversation context for who they mean\n• Partial info given → use it to search, then proceed\n\n**CRITICAL - MULTIPLE MATCHES:**\nWhen you find 2 or more matching records and the user's request implies ONE specific target:\n1. DO NOT pick one arbitrarily or proceed with all\n2. Return the list of matches with minimal distinguishing details (name, status, source) to help the user identify the correct record\n3. Ask the user to clarify which one they mean\n\nDo NOT ask:\n• For IDs when you have a name to search\n• About scope for simple queries (just return results)\n• For confirmation on obvious single-match requests\n\n**CUSTOMER OPERATIONS**\n- get_by_id: Use when you have a specific customer ID\n- get_by_email: Use when searching by email address\n- list: Use for browsing, filtering, or bulk operations\n\n**PRODUCT OPERATIONS**\n- get_by_id: Use when you have a specific product ID\n- list: Use for browsing the catalog or bulk operations\n\n**BEST PRACTICES**\n1. ALWAYS specify the 'fields' parameter to minimize response size\n2. Avoid 'metadata' field unless specifically requested - it can be very large\n3. Use pagination (cursor) for large datasets instead of fetching all at once\n4. Default numItems is 200; reduce if selecting many fields\n5. If hasMore is true, continue with the returned cursor to fetch more data\n\n**FIELD SELECTION GUIDE**\nCustomer common fields: _id, name, email, status, source, locale\nProduct common fields: _id, name, description, price, currency, status, category\n\nHeavy fields (avoid unless needed):\n- Customer: metadata, address\n- Product: metadata, translations\n\n**RESPONSE GUIDELINES**\n- Present data in clear, structured format (tables for lists)\n- Include pagination info when relevant (hasMore, cursor)\n- Summarize large datasets rather than dumping raw data\n- If data not found, say so clearly\n- Never expose internal IDs unless specifically requested",
Expand Down
2 changes: 1 addition & 1 deletion examples/agents/file-assistant.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"request_human_input",
"request_user_location"
],
"modelPreset": "fast",
"supportedModels": ["qwen/qwen3-next-80b-a3b-instruct", "qwen/qwen3.5-35b-a3b"],
"knowledgeMode": "tool",
"includeTeamKnowledge": false,
"maxSteps": 15,
Expand Down
2 changes: 1 addition & 1 deletion examples/agents/integration-assistant.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
"maxSteps": 20,
"timeoutMs": 180000,
"outputReserve": 2048,
"modelPreset": "fast",
"supportedModels": ["qwen/qwen3-next-80b-a3b-instruct", "qwen/qwen3.5-35b-a3b"],
"roleRestriction": "admin_developer"
}
2 changes: 1 addition & 1 deletion examples/agents/web-assistant.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"toolNames": [
"web"
],
"modelPreset": "fast",
"supportedModels": ["qwen/qwen3-next-80b-a3b-instruct", "qwen/qwen3.5-35b-a3b"],
"structuredResponsesEnabled": false,
"maxSteps": 5,
"timeoutMs": 300000,
Expand Down
2 changes: 1 addition & 1 deletion examples/agents/workflow-assistant.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"integration_introspect",
"run_workflow"
],
"modelPreset": "advanced",
"supportedModels": ["anthropic/claude-opus-4.6", "openai/gpt-5.2"],
"maxSteps": 30,
"timeoutMs": 240000,
"outputReserve": 2048,
Expand Down
68 changes: 68 additions & 0 deletions examples/providers/openrouter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"displayName": "OpenRouter",
"description": "Multi-model AI gateway with access to leading LLM providers",
"baseUrl": "https://openrouter.ai/api/v1",
"supportsStructuredOutputs": true,
"models": [
{
"id": "moonshotai/kimi-k2.5",
"displayName": "Kimi K2.5",
"description": "High-performance general-purpose model",
"tags": ["chat"],
"default": true
},
{
"id": "deepseek/deepseek-v3.2",
"displayName": "DeepSeek V3.2",
"description": "Strong reasoning and general capabilities",
"tags": ["chat"]
},
{
"id": "qwen/qwen3-next-80b-a3b-instruct",
"displayName": "Qwen3 Next 80B",
"description": "Fast and efficient instruction-following model",
"tags": ["chat"]
},
{
"id": "qwen/qwen3.5-35b-a3b",
"displayName": "Qwen3.5 35B",
"description": "Compact and fast model",
"tags": ["chat"]
},
{
"id": "anthropic/claude-opus-4.6",
"displayName": "Claude Opus 4.6",
"description": "Most capable model for complex reasoning and coding",
"tags": ["chat", "vision"]
},
{
"id": "openai/gpt-5.2",
"displayName": "GPT-5.2",
"description": "OpenAI's latest flagship model",
"tags": ["chat", "vision"]
},
{
"id": "qwen/qwen3-vl-32b-instruct",
"displayName": "Qwen3 VL 32B",
"description": "Vision-language model for image understanding",
"tags": ["chat", "vision"]
},
{
"id": "qwen/qwen3-embedding-4b",
"displayName": "Qwen3 Embedding 4B",
"description": "Text embedding model for semantic search",
"tags": ["embedding"],
"dimensions": 1536
}
],
"i18n": {
"de": {
"description": "Multi-Modell-KI-Gateway mit Zugang zu fuhrenden LLM-Anbietern",
"models": {
"anthropic/claude-opus-4.6": {
"description": "Leistungsstarkstes Modell fur komplexe Aufgaben und Programmierung"
Comment on lines +60 to +63

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

German localization strings contain spelling errors.

Please fix "fuhrenden""führenden" and "fur""für".

✍️ Suggested patch
-      "description": "Multi-Modell-KI-Gateway mit Zugang zu fuhrenden LLM-Anbietern",
+      "description": "Multi-Modell-KI-Gateway mit Zugang zu führenden LLM-Anbietern",
@@
-          "description": "Leistungsstarkstes Modell fur komplexe Aufgaben und Programmierung"
+          "description": "Leistungsstarkstes Modell für komplexe Aufgaben und Programmierung"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"description": "Multi-Modell-KI-Gateway mit Zugang zu fuhrenden LLM-Anbietern",
"models": {
"anthropic/claude-opus-4.6": {
"description": "Leistungsstarkstes Modell fur komplexe Aufgaben und Programmierung"
"description": "Multi-Modell-KI-Gateway mit Zugang zu führenden LLM-Anbietern",
"models": {
"anthropic/claude-opus-4.6": {
"description": "Leistungsstarkstes Modell für komplexe Aufgaben und Programmierung"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/providers/openrouter.json` around lines 60 - 63, Update the German
localization strings by correcting the spelling mistakes in the description
values: change "fuhrenden" to "führenden" and "fur" to "für" (specifically in
the top-level "description" value "Multi-Modell-KI-Gateway mit Zugang zu
fuhrenden LLM-Anbietern" and in the model description for
"anthropic/claude-opus-4.6" where "fur" appears); ensure the corrected UTF-8
characters are used so the strings read "führenden" and "für".

}
}
}
}
}
20 changes: 20 additions & 0 deletions examples/providers/openrouter.secrets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"apiKey": "ENC[AES256_GCM,data:5t/po/UofoTQMn/Cgz6ju3Ij6YbuAdOqBmAK/b0SoVGfu7BNKXaJPBJZNC8GGw8OQeMzhDl+DamCM5hl3hd4HFJOdwDwdplFZQ==,iv:9jD1tqi60JYJkb+cY0nY6QNHdnZPQ4F6sQeing5QJ9E=,tag:hdps/EHR4LHUhwzH76mXag==,type:str]",
"sops": {
"kms": null,
"gcp_kms": null,
"azure_kv": null,
"hc_vault": null,
"age": [
{
"recipient": "age1xsc5y9x0dref9kd6fwv2356pw2zl5s7gp5v6jam9h4q7mv6fm9aqumvqhj",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4aCtrT1U2SHJiRE9LZjNi\nWUVuZ1JCbGJOUmRiUDBpR3NDTklBUjJxeDNRClEwbDBnY0ErQmM1SzEyM2tsMEJJ\nRVZYQjJ5bGhBMnBvM1RRQmFIV25XWWcKLS0tIEszVUZuaEN1Y3pQWlZodjQzMFJE\nVHlaR3hHRXJwTGh0Vk1KU1JuWkprWnMK/7HmxFH5ciZqhgtfzGyzYhnU08hESOnM\nC1F7mP6UrJ6kyWKFNEdluayhFkTnixTGJ6GrL72tClvrQRAyGuKAEA==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2026-04-03T02:55:08Z",
"mac": "ENC[AES256_GCM,data:CAoKo2SqAUL7iVjWylNxhecEhJfBNQAUFqCEMLmBqBRERxCj7nsclIBmyA9KpJR14qrWM8vF7u3aNC95Wwzww1xh17pC31VYPcIdF8bxmbQ/Djkx0/BBPHaXXZcjBnObKsDhfltNZx8G+IBrRshY07CWYqYRzm9ogrkzfFHgIL8=,iv:AnitQlvUD+/Yahxx6HTa/qnlklHYOt4Bwv5WtUgaFsA=,tag:bSA7cW4N1s9FKHh/Sf0QyA==,type:str]",
"pgp": null,
"unencrypted_suffix": "_unencrypted",
"version": "3.9.4"
}
}
16 changes: 15 additions & 1 deletion packages/tale_shared/src/tale_shared/config/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
"""Configuration utilities."""

from .base import BaseServiceSettings
from .providers import (
ProviderConfig,
get_chat_model,
get_embedding_model,
get_vision_model,
load_providers,
)

__all__ = ["BaseServiceSettings"]
__all__ = [
"BaseServiceSettings",
"ProviderConfig",
"get_chat_model",
"get_embedding_model",
"get_vision_model",
"load_providers",
]
Loading