Files
agentlens/packages/opencode-plugin/src/utils.ts
Vectry 5256bf005b feat: documentation pages and updated model pricing
- 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
2026-02-10 03:27:11 +00:00

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);
}