- Add 13 documentation pages under /docs (getting-started, concepts, SDK refs, integrations, API reference, self-hosting, OpenCode plugin) - Shared docs layout with collapsible sidebar navigation - Update model pricing across all SDKs: add GPT-5.x, GPT-4.1, o3/o4-mini, Claude 4.5 series, claude-opus-4-6 - Update trace-analytics context window lookup with current models
117 lines
3.3 KiB
TypeScript
117 lines
3.3 KiB
TypeScript
import type { JsonValue } from "agentlens-sdk";
|
|
|
|
export function truncate(str: string, maxLength: number): string {
|
|
if (str.length <= maxLength) return str;
|
|
return str.slice(0, maxLength) + "... [truncated]";
|
|
}
|
|
|
|
export function extractToolMetadata(
|
|
tool: string,
|
|
args: unknown,
|
|
): Record<string, unknown> {
|
|
const a = args as Record<string, unknown> | null | undefined;
|
|
if (!a || typeof a !== "object") return {};
|
|
|
|
switch (tool) {
|
|
case "read":
|
|
case "mcp_read":
|
|
return { filePath: a["filePath"] };
|
|
|
|
case "write":
|
|
case "mcp_write":
|
|
return { filePath: a["filePath"] };
|
|
|
|
case "edit":
|
|
case "mcp_edit":
|
|
return { filePath: a["filePath"] };
|
|
|
|
case "bash":
|
|
case "mcp_bash":
|
|
return {
|
|
command: truncate(String(a["command"] ?? ""), 200),
|
|
};
|
|
|
|
case "glob":
|
|
case "mcp_glob":
|
|
return { pattern: a["pattern"] };
|
|
|
|
case "grep":
|
|
case "mcp_grep":
|
|
return { pattern: a["pattern"], path: a["path"] };
|
|
|
|
case "task":
|
|
case "mcp_task":
|
|
return {
|
|
category: a["category"],
|
|
description: a["description"],
|
|
};
|
|
|
|
default:
|
|
return {};
|
|
}
|
|
}
|
|
|
|
const MODEL_COSTS: Record<string, { input: number; output: number }> = {
|
|
"gpt-5.2": { input: 1.75, output: 14 },
|
|
"gpt-5.1": { input: 1.25, output: 10 },
|
|
"gpt-5": { input: 1.25, output: 10 },
|
|
"gpt-5-mini": { input: 0.25, output: 2 },
|
|
"gpt-5-nano": { input: 0.05, output: 0.4 },
|
|
"gpt-4.1": { input: 2, output: 8 },
|
|
"gpt-4.1-mini": { input: 0.4, output: 1.6 },
|
|
"gpt-4.1-nano": { input: 0.1, output: 0.4 },
|
|
"o3": { input: 2, output: 8 },
|
|
"o3-mini": { input: 1.1, output: 4.4 },
|
|
"o4-mini": { input: 1.1, output: 4.4 },
|
|
"o1": { input: 15, output: 60 },
|
|
"gpt-4o": { input: 2.5, output: 10 },
|
|
"gpt-4o-mini": { input: 0.15, output: 0.6 },
|
|
"gpt-4-turbo": { input: 10, output: 30 },
|
|
"gpt-4": { input: 30, output: 60 },
|
|
"claude-opus-4-6": { input: 5, output: 25 },
|
|
"claude-opus-4-20250514": { input: 15, output: 75 },
|
|
"claude-sonnet-4-20250514": { input: 3, output: 15 },
|
|
"claude-4.5-opus": { input: 5, output: 25 },
|
|
"claude-4.5-sonnet": { input: 3, output: 15 },
|
|
"claude-4.5-haiku": { input: 1, output: 5 },
|
|
"claude-3-5-sonnet": { input: 3, output: 15 },
|
|
"claude-3-5-haiku": { input: 0.8, output: 4 },
|
|
"claude-3-opus": { input: 15, output: 75 },
|
|
"claude-3-haiku": { input: 0.25, output: 1.25 },
|
|
};
|
|
|
|
export function getModelCost(
|
|
modelId: string,
|
|
): { input: number; output: number } | undefined {
|
|
const direct = MODEL_COSTS[modelId];
|
|
if (direct) return direct;
|
|
|
|
for (const [key, cost] of Object.entries(MODEL_COSTS)) {
|
|
if (modelId.includes(key)) return cost;
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
/** Coerce arbitrary values into SDK-compatible `JsonValue`, stringifying unknowns. */
|
|
export function safeJsonValue(value: unknown): JsonValue {
|
|
if (value === null || value === undefined) return null;
|
|
if (
|
|
typeof value === "string" ||
|
|
typeof value === "number" ||
|
|
typeof value === "boolean"
|
|
) {
|
|
return value;
|
|
}
|
|
if (Array.isArray(value)) {
|
|
return value.map((v) => safeJsonValue(v));
|
|
}
|
|
if (typeof value === "object") {
|
|
const result: Record<string, JsonValue> = {};
|
|
for (const [k, v] of Object.entries(value as Record<string, unknown>)) {
|
|
result[k] = safeJsonValue(v);
|
|
}
|
|
return result;
|
|
}
|
|
return String(value);
|
|
}
|