mirror of
https://github.com/dograh-hq/dograh.git
synced 2026-06-16 08:25:18 +02:00
feat: set calculator as custom tool on demand
This commit is contained in:
parent
89fce77438
commit
f368fe5134
13 changed files with 265 additions and 157 deletions
60
ui/src/app/tools/[toolUuid]/components/BuiltinToolConfig.tsx
Normal file
60
ui/src/app/tools/[toolUuid]/components/BuiltinToolConfig.tsx
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
"use client";
|
||||
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
|
||||
export interface BuiltinToolConfigProps {
|
||||
name: string;
|
||||
onNameChange: (name: string) => void;
|
||||
description: string;
|
||||
onDescriptionChange: (description: string) => void;
|
||||
title: string;
|
||||
subtitle: string;
|
||||
}
|
||||
|
||||
export function BuiltinToolConfig({
|
||||
name,
|
||||
onNameChange,
|
||||
description,
|
||||
onDescriptionChange,
|
||||
title,
|
||||
subtitle,
|
||||
}: BuiltinToolConfigProps) {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>{title}</CardTitle>
|
||||
<CardDescription>{subtitle}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-6">
|
||||
{/* Tool Name */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="tool-name">Tool Name</Label>
|
||||
<Input
|
||||
id="tool-name"
|
||||
value={name}
|
||||
onChange={(e) => onNameChange(e.target.value)}
|
||||
placeholder="Tool name"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Tool Description */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="tool-description">Description</Label>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Provide a description which makes it easy for LLM to understand what this tool does
|
||||
</p>
|
||||
<Textarea
|
||||
id="tool-description"
|
||||
value={description}
|
||||
onChange={(e) => onDescriptionChange(e.target.value)}
|
||||
placeholder="Describe what this tool does..."
|
||||
rows={3}
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
export { BuiltinToolConfig, type BuiltinToolConfigProps } from "./BuiltinToolConfig";
|
||||
export { EndCallToolConfig, type EndCallToolConfigProps } from "./EndCallToolConfig";
|
||||
export { HttpApiToolConfig, type HttpApiToolConfigProps } from "./HttpApiToolConfig";
|
||||
export { TransferCallToolConfig, type TransferCallToolConfigProps } from "./TransferCallToolConfig";
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import {
|
|||
renderToolIcon,
|
||||
type ToolCategory,
|
||||
} from "../config";
|
||||
import { EndCallToolConfig, HttpApiToolConfig, TransferCallToolConfig } from "./components";
|
||||
import { BuiltinToolConfig, EndCallToolConfig, HttpApiToolConfig, TransferCallToolConfig } from "./components";
|
||||
|
||||
// Extended HttpApiConfig with parameters (until client types are regenerated)
|
||||
interface HttpApiConfigWithParams {
|
||||
|
|
@ -201,7 +201,9 @@ export default function ToolDetailPage() {
|
|||
if (!tool) return;
|
||||
|
||||
// Validation based on tool type
|
||||
if (tool.category === "transfer_call") {
|
||||
if (tool.category === "calculator") {
|
||||
// No validation needed for built-in tools
|
||||
} else if (tool.category === "transfer_call") {
|
||||
// Validate destination for Transfer Call tools (supports both E.164 and SIP endpoints)
|
||||
const e164Pattern = /^\+[1-9]\d{1,14}$/;
|
||||
const sipPattern = /^(PJSIP|SIP)\/[\w\-\.@]+$/i;
|
||||
|
|
@ -236,7 +238,17 @@ export default function ToolDetailPage() {
|
|||
|
||||
let requestBody;
|
||||
|
||||
if (tool.category === "end_call") {
|
||||
if (tool.category === "calculator") {
|
||||
// Built-in tool - only name/description, no config
|
||||
requestBody = {
|
||||
name,
|
||||
description: description || undefined,
|
||||
definition: {
|
||||
schema_version: 1,
|
||||
type: "calculator",
|
||||
},
|
||||
};
|
||||
} else if (tool.category === "end_call") {
|
||||
// Build end call request body
|
||||
requestBody = {
|
||||
name,
|
||||
|
|
@ -400,6 +412,7 @@ const data = await response.json();`;
|
|||
|
||||
const isEndCallTool = tool.category === "end_call";
|
||||
const isTransferCallTool = tool.category === "transfer_call";
|
||||
const isBuiltinTool = tool.category === "calculator";
|
||||
const categoryConfig = getCategoryConfig(tool.category as ToolCategory);
|
||||
|
||||
return (
|
||||
|
|
@ -435,7 +448,7 @@ const data = await response.json();`;
|
|||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
{!isEndCallTool && !isTransferCallTool && (
|
||||
{!isEndCallTool && !isTransferCallTool && !isBuiltinTool && (
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => setShowCodeDialog(true)}
|
||||
|
|
@ -458,7 +471,16 @@ const data = await response.json();`;
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{isEndCallTool ? (
|
||||
{isBuiltinTool ? (
|
||||
<BuiltinToolConfig
|
||||
name={name}
|
||||
onNameChange={setName}
|
||||
description={description}
|
||||
onDescriptionChange={setDescription}
|
||||
title="Calculator Configuration"
|
||||
subtitle="Built-in calculator for arithmetic operations. No additional configuration needed."
|
||||
/>
|
||||
) : isEndCallTool ? (
|
||||
<EndCallToolConfig
|
||||
name={name}
|
||||
onNameChange={setName}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,18 @@
|
|||
"use client";
|
||||
|
||||
import { Cog, Globe, type LucideIcon, PhoneForwarded, PhoneOff, Puzzle } from "lucide-react";
|
||||
import { Calculator, Cog, Globe, type LucideIcon, PhoneForwarded, PhoneOff, Puzzle } from "lucide-react";
|
||||
import { type ReactNode } from "react";
|
||||
|
||||
import type { EndCallConfig } from "@/client/types.gen";
|
||||
import type {
|
||||
CalculatorToolDefinition,
|
||||
EndCallConfig,
|
||||
EndCallToolDefinition,
|
||||
HttpApiToolDefinition,
|
||||
TransferCallConfig,
|
||||
TransferCallToolDefinition,
|
||||
} from "@/client/types.gen";
|
||||
|
||||
export type ToolCategory = "http_api" | "end_call" | "transfer_call" | "native" | "integration";
|
||||
export type ToolCategory = "http_api" | "end_call" | "transfer_call" | "calculator" | "native" | "integration";
|
||||
|
||||
export type EndCallMessageType = "none" | "custom";
|
||||
|
||||
|
|
@ -56,6 +63,18 @@ export const TOOL_CATEGORIES: ToolCategoryConfig[] = [
|
|||
description: "Transfer the caller to another phone number when requested",
|
||||
},
|
||||
},
|
||||
{
|
||||
value: "calculator",
|
||||
label: "Calculator",
|
||||
description: "Built-in calculator for arithmetic operations",
|
||||
icon: Calculator,
|
||||
iconName: "calculator",
|
||||
iconColor: "#F59E0B",
|
||||
autoFill: {
|
||||
name: "Calculator",
|
||||
description: "Perform arithmetic calculations (supports +, -, *, /, **, %, and parentheses)",
|
||||
},
|
||||
},
|
||||
{
|
||||
value: "native",
|
||||
label: "Native (Coming Soon)",
|
||||
|
|
@ -103,6 +122,8 @@ export function getToolTypeLabel(category: string): string {
|
|||
return "Transfer Call Tool";
|
||||
case "http_api":
|
||||
return "HTTP API Tool";
|
||||
case "calculator":
|
||||
return "Calculator Tool";
|
||||
case "native":
|
||||
return "Native Tool";
|
||||
case "integration":
|
||||
|
|
@ -121,14 +142,6 @@ export const DEFAULT_END_CALL_CONFIG: EndCallConfig = {
|
|||
endCallReason: false,
|
||||
};
|
||||
|
||||
// Transfer Call tool specific configuration
|
||||
export interface TransferCallConfig {
|
||||
destination: string;
|
||||
messageType: EndCallMessageType; // Reuse the same type
|
||||
customMessage?: string;
|
||||
timeout: number;
|
||||
}
|
||||
|
||||
export const DEFAULT_TRANSFER_CALL_CONFIG: TransferCallConfig = {
|
||||
destination: "",
|
||||
messageType: "none",
|
||||
|
|
@ -136,38 +149,7 @@ export const DEFAULT_TRANSFER_CALL_CONFIG: TransferCallConfig = {
|
|||
timeout: 30,
|
||||
};
|
||||
|
||||
// Tool definition types for different categories
|
||||
export interface HttpApiToolDefinition {
|
||||
schema_version: number;
|
||||
type: "http_api";
|
||||
config: {
|
||||
method: string;
|
||||
url: string;
|
||||
headers?: Record<string, string>;
|
||||
credential_uuid?: string;
|
||||
parameters?: Array<{
|
||||
name: string;
|
||||
type: string;
|
||||
description: string;
|
||||
required: boolean;
|
||||
}>;
|
||||
timeout_ms?: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface EndCallToolDefinition {
|
||||
schema_version: number;
|
||||
type: "end_call";
|
||||
config: EndCallConfig;
|
||||
}
|
||||
|
||||
export interface TransferCallToolDefinition {
|
||||
schema_version: number;
|
||||
type: "transfer_call";
|
||||
config: TransferCallConfig;
|
||||
}
|
||||
|
||||
export type ToolDefinition = HttpApiToolDefinition | EndCallToolDefinition | TransferCallToolDefinition;
|
||||
export type ToolDefinition = HttpApiToolDefinition | EndCallToolDefinition | TransferCallToolDefinition | CalculatorToolDefinition;
|
||||
|
||||
export function createEndCallDefinition(config: EndCallConfig): EndCallToolDefinition {
|
||||
return {
|
||||
|
|
@ -196,12 +178,21 @@ export function createHttpApiDefinition(): HttpApiToolDefinition {
|
|||
};
|
||||
}
|
||||
|
||||
export function createCalculatorDefinition(): CalculatorToolDefinition {
|
||||
return {
|
||||
schema_version: 1,
|
||||
type: "calculator",
|
||||
};
|
||||
}
|
||||
|
||||
export function createToolDefinition(category: ToolCategory): ToolDefinition {
|
||||
switch (category) {
|
||||
case "end_call":
|
||||
return createEndCallDefinition(DEFAULT_END_CALL_CONFIG);
|
||||
case "transfer_call":
|
||||
return createTransferCallDefinition(DEFAULT_TRANSFER_CALL_CONFIG);
|
||||
case "calculator":
|
||||
return createCalculatorDefinition();
|
||||
case "http_api":
|
||||
default:
|
||||
return createHttpApiDefinition();
|
||||
|
|
|
|||
|
|
@ -227,6 +227,8 @@ export default function ToolsPage() {
|
|||
return <Badge variant="default">HTTP API</Badge>;
|
||||
case "end_call":
|
||||
return <Badge variant="destructive">End Call</Badge>;
|
||||
case "calculator":
|
||||
return <Badge variant="secondary">Calculator</Badge>;
|
||||
case "native":
|
||||
return <Badge variant="secondary">Native</Badge>;
|
||||
case "integration":
|
||||
|
|
|
|||
|
|
@ -85,6 +85,20 @@ export type BodyTranscribeAudioApiV1WorkflowRecordingsTranscribePost = {
|
|||
language?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Tool definition for Calculator tools (no configuration needed).
|
||||
*/
|
||||
export type CalculatorToolDefinition = {
|
||||
/**
|
||||
* Schema version
|
||||
*/
|
||||
schema_version?: number;
|
||||
/**
|
||||
* Tool type
|
||||
*/
|
||||
type: 'calculator';
|
||||
};
|
||||
|
||||
export type CallDispositionCodes = {
|
||||
disposition_codes?: Array<string>;
|
||||
};
|
||||
|
|
@ -328,7 +342,9 @@ export type CreateToolRequest = {
|
|||
type?: 'end_call';
|
||||
} & EndCallToolDefinition) | ({
|
||||
type?: 'transfer_call';
|
||||
} & TransferCallToolDefinition);
|
||||
} & TransferCallToolDefinition) | ({
|
||||
type?: 'calculator';
|
||||
} & CalculatorToolDefinition);
|
||||
};
|
||||
|
||||
export type CreateWorkflowRequest = {
|
||||
|
|
@ -1290,7 +1306,9 @@ export type UpdateToolRequest = {
|
|||
type?: 'end_call';
|
||||
} & EndCallToolDefinition) | ({
|
||||
type?: 'transfer_call';
|
||||
} & TransferCallToolDefinition)) | null;
|
||||
} & TransferCallToolDefinition) | ({
|
||||
type?: 'calculator';
|
||||
} & CalculatorToolDefinition)) | null;
|
||||
status?: string | null;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue