diff --git a/apps/sim/executor/constants.ts b/apps/sim/executor/constants.ts
index 364ee2c1f0..99d0b5b164 100644
--- a/apps/sim/executor/constants.ts
+++ b/apps/sim/executor/constants.ts
@@ -273,8 +273,8 @@ export function supportsHandles(blockType: string | undefined): boolean {
export function getDefaultTokens() {
return {
- prompt: DEFAULTS.TOKENS.PROMPT,
- completion: DEFAULTS.TOKENS.COMPLETION,
+ input: DEFAULTS.TOKENS.PROMPT,
+ output: DEFAULTS.TOKENS.COMPLETION,
total: DEFAULTS.TOKENS.TOTAL,
}
}
diff --git a/apps/sim/executor/execution/edge-manager.test.ts b/apps/sim/executor/execution/edge-manager.test.ts
index 3470c2d67e..14c7c7cc5e 100644
--- a/apps/sim/executor/execution/edge-manager.test.ts
+++ b/apps/sim/executor/execution/edge-manager.test.ts
@@ -129,7 +129,7 @@ describe('EdgeManager', () => {
const output = {
result: { data: 'test' },
content: 'Hello world',
- tokens: { prompt: 10, completion: 20, total: 30 },
+ tokens: { input: 10, output: 20, total: 30 },
}
const readyNodes = edgeManager.processOutgoingEdges(sourceNode, output)
diff --git a/apps/sim/executor/handlers/agent/agent-handler.test.ts b/apps/sim/executor/handlers/agent/agent-handler.test.ts
index 273be0936c..e6e5e95e92 100644
--- a/apps/sim/executor/handlers/agent/agent-handler.test.ts
+++ b/apps/sim/executor/handlers/agent/agent-handler.test.ts
@@ -31,7 +31,7 @@ vi.mock('@/providers/utils', () => ({
create: vi.fn().mockResolvedValue({
content: 'Mocked response content',
model: 'mock-model',
- tokens: { prompt: 10, completion: 20, total: 30 },
+ tokens: { input: 10, output: 20, total: 30 },
toolCalls: [],
cost: 0.001,
timing: { total: 100 },
@@ -53,7 +53,7 @@ vi.mock('@/providers', () => ({
executeProviderRequest: vi.fn().mockResolvedValue({
content: 'Mocked response content',
model: 'mock-model',
- tokens: { prompt: 10, completion: 20, total: 30 },
+ tokens: { input: 10, output: 20, total: 30 },
toolCalls: [],
cost: 0.001,
timing: { total: 100 },
@@ -134,7 +134,7 @@ describe('AgentBlockHandler', () => {
Promise.resolve({
content: 'Mocked response content',
model: 'mock-model',
- tokens: { prompt: 10, completion: 20, total: 30 },
+ tokens: { input: 10, output: 20, total: 30 },
toolCalls: [],
cost: 0.001,
timing: { total: 100 },
@@ -211,7 +211,7 @@ describe('AgentBlockHandler', () => {
const expectedOutput = {
content: 'Mocked response content',
model: 'mock-model',
- tokens: { prompt: 10, completion: 20, total: 30 },
+ tokens: { input: 10, output: 20, total: 30 },
toolCalls: { list: [], count: 0 },
providerTiming: { total: 100 },
cost: 0.001,
@@ -253,7 +253,7 @@ describe('AgentBlockHandler', () => {
Promise.resolve({
content: 'Using tools to respond',
model: 'mock-model',
- tokens: { prompt: 10, completion: 20, total: 30 },
+ tokens: { input: 10, output: 20, total: 30 },
toolCalls: [
{
name: 'auto_tool',
@@ -591,7 +591,7 @@ describe('AgentBlockHandler', () => {
const expectedOutput = {
content: 'Mocked response content',
model: 'mock-model',
- tokens: { prompt: 10, completion: 20, total: 30 },
+ tokens: { input: 10, output: 20, total: 30 },
toolCalls: { list: [], count: 0 }, // Assuming no tool calls in this mock response
providerTiming: { total: 100 },
cost: 0.001,
@@ -672,7 +672,7 @@ describe('AgentBlockHandler', () => {
Promise.resolve({
content: '{"result": "Success", "score": 0.95}',
model: 'mock-model',
- tokens: { prompt: 10, completion: 20, total: 30 },
+ tokens: { input: 10, output: 20, total: 30 },
timing: { total: 100 },
toolCalls: [],
cost: undefined,
@@ -693,7 +693,7 @@ describe('AgentBlockHandler', () => {
expect(result).toEqual({
result: 'Success',
score: 0.95,
- tokens: { prompt: 10, completion: 20, total: 30 },
+ tokens: { input: 10, output: 20, total: 30 },
toolCalls: { list: [], count: 0 },
providerTiming: { total: 100 },
cost: undefined,
@@ -715,7 +715,7 @@ describe('AgentBlockHandler', () => {
Promise.resolve({
content: 'Regular text response',
model: 'mock-model',
- tokens: { prompt: 10, completion: 20, total: 30 },
+ tokens: { input: 10, output: 20, total: 30 },
timing: { total: 100 },
}),
})
@@ -733,7 +733,7 @@ describe('AgentBlockHandler', () => {
expect(result).toEqual({
content: 'Regular text response',
model: 'mock-model',
- tokens: { prompt: 10, completion: 20, total: 30 },
+ tokens: { input: 10, output: 20, total: 30 },
toolCalls: { list: [], count: 0 },
providerTiming: { total: 100 },
cost: undefined,
@@ -755,7 +755,7 @@ describe('AgentBlockHandler', () => {
Promise.resolve({
content: 'Regular text response',
model: 'mock-model',
- tokens: { prompt: 10, completion: 20, total: 30 },
+ tokens: { input: 10, output: 20, total: 30 },
timing: { total: 100 },
toolCalls: [],
cost: undefined,
@@ -776,7 +776,7 @@ describe('AgentBlockHandler', () => {
expect(result).toEqual({
content: 'Regular text response',
model: 'mock-model',
- tokens: { prompt: 10, completion: 20, total: 30 },
+ tokens: { input: 10, output: 20, total: 30 },
toolCalls: { list: [], count: 0 },
providerTiming: { total: 100 },
cost: undefined,
@@ -798,7 +798,7 @@ describe('AgentBlockHandler', () => {
Promise.resolve({
content: 'Regular text response',
model: 'mock-model',
- tokens: { prompt: 10, completion: 20, total: 30 },
+ tokens: { input: 10, output: 20, total: 30 },
timing: { total: 100 },
toolCalls: [],
cost: undefined,
@@ -819,7 +819,7 @@ describe('AgentBlockHandler', () => {
expect(result).toEqual({
content: 'Regular text response',
model: 'mock-model',
- tokens: { prompt: 10, completion: 20, total: 30 },
+ tokens: { input: 10, output: 20, total: 30 },
toolCalls: { list: [], count: 0 },
providerTiming: { total: 100 },
cost: undefined,
@@ -907,7 +907,7 @@ describe('AgentBlockHandler', () => {
output: {
content: '',
model: 'mock-model',
- tokens: { prompt: 10, completion: 20, total: 30 },
+ tokens: { input: 10, output: 20, total: 30 },
},
logs: [
{
@@ -988,7 +988,7 @@ describe('AgentBlockHandler', () => {
output: {
content: 'Test streaming content',
model: 'gpt-4o',
- tokens: { prompt: 10, completion: 5, total: 15 },
+ tokens: { input: 10, output: 5, total: 15 },
},
logs: [],
metadata: {
@@ -1414,7 +1414,7 @@ describe('AgentBlockHandler', () => {
Promise.resolve({
content: 'I will use MCP tools to help you.',
model: 'gpt-4o',
- tokens: { prompt: 15, completion: 25, total: 40 },
+ tokens: { input: 15, output: 25, total: 40 },
toolCalls: [
{
name: 'mcp-server1-list_files',
@@ -1525,7 +1525,7 @@ describe('AgentBlockHandler', () => {
Promise.resolve({
content: 'Let me try to use this tool.',
model: 'gpt-4o',
- tokens: { prompt: 10, completion: 15, total: 25 },
+ tokens: { input: 10, output: 15, total: 25 },
toolCalls: [
{
name: 'mcp-server1-failing_tool',
@@ -1630,7 +1630,7 @@ describe('AgentBlockHandler', () => {
Promise.resolve({
content: 'Used MCP tools successfully',
model: 'gpt-4o',
- tokens: { prompt: 20, completion: 30, total: 50 },
+ tokens: { input: 20, output: 30, total: 50 },
toolCalls: [],
timing: { total: 200 },
}),
@@ -1679,7 +1679,7 @@ describe('AgentBlockHandler', () => {
Promise.resolve({
content: 'Using MCP tool',
model: 'gpt-4o',
- tokens: { prompt: 10, completion: 10, total: 20 },
+ tokens: { input: 10, output: 10, total: 20 },
toolCalls: [{ name: 'mcp-test-tool', arguments: {} }],
timing: { total: 50 },
}),
@@ -1734,7 +1734,7 @@ describe('AgentBlockHandler', () => {
Promise.resolve({
content: 'Used MCP tool successfully',
model: 'gpt-4o',
- tokens: { prompt: 10, completion: 10, total: 20 },
+ tokens: { input: 10, output: 10, total: 20 },
toolCalls: [],
timing: { total: 50 },
}),
@@ -1811,7 +1811,7 @@ describe('AgentBlockHandler', () => {
Promise.resolve({
content: 'Tool executed',
model: 'gpt-4o',
- tokens: { prompt: 10, completion: 10, total: 20 },
+ tokens: { input: 10, output: 10, total: 20 },
toolCalls: [
{
name: 'search_files',
@@ -1901,7 +1901,7 @@ describe('AgentBlockHandler', () => {
Promise.resolve({
content: 'Used tools',
model: 'gpt-4o',
- tokens: { prompt: 10, completion: 10, total: 20 },
+ tokens: { input: 10, output: 10, total: 20 },
toolCalls: [],
timing: { total: 50 },
}),
@@ -2008,7 +2008,7 @@ describe('AgentBlockHandler', () => {
Promise.resolve({
content: 'Used legacy tool',
model: 'gpt-4o',
- tokens: { prompt: 10, completion: 10, total: 20 },
+ tokens: { input: 10, output: 10, total: 20 },
toolCalls: [],
timing: { total: 50 },
}),
diff --git a/apps/sim/executor/handlers/agent/agent-handler.ts b/apps/sim/executor/handlers/agent/agent-handler.ts
index a358685efe..2f4a36332a 100644
--- a/apps/sim/executor/handlers/agent/agent-handler.ts
+++ b/apps/sim/executor/handlers/agent/agent-handler.ts
@@ -1317,15 +1317,15 @@ export class AgentBlockHandler implements BlockHandler {
}
private createResponseMetadata(result: {
- tokens?: { prompt?: number; completion?: number; total?: number }
+ tokens?: { input?: number; output?: number; total?: number }
toolCalls?: Array
timing?: any
cost?: any
}) {
return {
tokens: result.tokens || {
- prompt: DEFAULTS.TOKENS.PROMPT,
- completion: DEFAULTS.TOKENS.COMPLETION,
+ input: DEFAULTS.TOKENS.PROMPT,
+ output: DEFAULTS.TOKENS.COMPLETION,
total: DEFAULTS.TOKENS.TOTAL,
},
toolCalls: {
diff --git a/apps/sim/executor/handlers/evaluator/evaluator-handler.test.ts b/apps/sim/executor/handlers/evaluator/evaluator-handler.test.ts
index 0acdcc41c5..498412aaf3 100644
--- a/apps/sim/executor/handlers/evaluator/evaluator-handler.test.ts
+++ b/apps/sim/executor/handlers/evaluator/evaluator-handler.test.ts
@@ -60,7 +60,7 @@ describe('EvaluatorBlockHandler', () => {
Promise.resolve({
content: JSON.stringify({ score1: 5, score2: 8 }),
model: 'mock-model',
- tokens: { prompt: 50, completion: 10, total: 60 },
+ tokens: { input: 50, output: 10, total: 60 },
cost: 0.002,
timing: { total: 200 },
}),
@@ -121,7 +121,7 @@ describe('EvaluatorBlockHandler', () => {
expect(result).toEqual({
content: 'This is the content to evaluate.',
model: 'mock-model',
- tokens: { prompt: 50, completion: 10, total: 60 },
+ tokens: { input: 50, output: 10, total: 60 },
cost: {
input: 0,
output: 0,
diff --git a/apps/sim/executor/handlers/evaluator/evaluator-handler.ts b/apps/sim/executor/handlers/evaluator/evaluator-handler.ts
index 2e97298818..694cf885c5 100644
--- a/apps/sim/executor/handlers/evaluator/evaluator-handler.ts
+++ b/apps/sim/executor/handlers/evaluator/evaluator-handler.ts
@@ -124,19 +124,18 @@ export class EvaluatorBlockHandler implements BlockHandler {
const metricScores = this.extractMetricScores(parsedContent, inputs.metrics)
- const costCalculation = calculateCost(
- result.model,
- result.tokens?.prompt || DEFAULTS.TOKENS.PROMPT,
- result.tokens?.completion || DEFAULTS.TOKENS.COMPLETION,
- false
- )
+ const inputTokens = result.tokens?.input || result.tokens?.prompt || DEFAULTS.TOKENS.PROMPT
+ const outputTokens =
+ result.tokens?.output || result.tokens?.completion || DEFAULTS.TOKENS.COMPLETION
+
+ const costCalculation = calculateCost(result.model, inputTokens, outputTokens, false)
return {
content: inputs.content,
model: result.model,
tokens: {
- prompt: result.tokens?.prompt || DEFAULTS.TOKENS.PROMPT,
- completion: result.tokens?.completion || DEFAULTS.TOKENS.COMPLETION,
+ input: inputTokens,
+ output: outputTokens,
total: result.tokens?.total || DEFAULTS.TOKENS.TOTAL,
},
cost: {
diff --git a/apps/sim/executor/handlers/generic/generic-handler.test.ts b/apps/sim/executor/handlers/generic/generic-handler.test.ts
index 042592b81f..dfbe364802 100644
--- a/apps/sim/executor/handlers/generic/generic-handler.test.ts
+++ b/apps/sim/executor/handlers/generic/generic-handler.test.ts
@@ -186,8 +186,8 @@ describe('GenericBlockHandler', () => {
output: 0,
total: 0.00001042,
tokens: {
- prompt: 521,
- completion: 0,
+ input: 521,
+ output: 0,
total: 521,
},
model: 'text-embedding-3-small',
@@ -215,8 +215,8 @@ describe('GenericBlockHandler', () => {
total: 0.00001042,
},
tokens: {
- prompt: 521,
- completion: 0,
+ input: 521,
+ output: 0,
total: 521,
},
model: 'text-embedding-3-small',
@@ -253,8 +253,8 @@ describe('GenericBlockHandler', () => {
output: 0,
total: 0.00000521,
tokens: {
- prompt: 260,
- completion: 0,
+ input: 260,
+ output: 0,
total: 260,
},
model: 'text-embedding-3-small',
@@ -286,8 +286,8 @@ describe('GenericBlockHandler', () => {
total: 0.00000521,
},
tokens: {
- prompt: 260,
- completion: 0,
+ input: 260,
+ output: 0,
total: 260,
},
model: 'text-embedding-3-small',
@@ -340,7 +340,7 @@ describe('GenericBlockHandler', () => {
input: 0.001,
output: 0.002,
total: 0.003,
- tokens: { prompt: 100, completion: 50, total: 150 },
+ tokens: { input: 100, output: 50, total: 150 },
model: 'some-model',
},
},
@@ -357,7 +357,7 @@ describe('GenericBlockHandler', () => {
output: 0.002,
total: 0.003,
},
- tokens: { prompt: 100, completion: 50, total: 150 },
+ tokens: { input: 100, output: 50, total: 150 },
model: 'some-model',
})
}
diff --git a/apps/sim/executor/handlers/router/router-handler.test.ts b/apps/sim/executor/handlers/router/router-handler.test.ts
index eb3cc73337..b57367f73d 100644
--- a/apps/sim/executor/handlers/router/router-handler.test.ts
+++ b/apps/sim/executor/handlers/router/router-handler.test.ts
@@ -87,7 +87,7 @@ describe('RouterBlockHandler', () => {
Promise.resolve({
content: 'target-block-1',
model: 'mock-model',
- tokens: { prompt: 100, completion: 5, total: 105 },
+ tokens: { input: 100, output: 5, total: 105 },
cost: 0.003,
timing: { total: 300 },
}),
@@ -160,7 +160,7 @@ describe('RouterBlockHandler', () => {
expect(result).toEqual({
prompt: 'Choose the best option.',
model: 'mock-model',
- tokens: { prompt: 100, completion: 5, total: 105 },
+ tokens: { input: 100, output: 5, total: 105 },
cost: {
input: 0,
output: 0,
diff --git a/apps/sim/executor/handlers/router/router-handler.ts b/apps/sim/executor/handlers/router/router-handler.ts
index 327d490f35..59c5e8291a 100644
--- a/apps/sim/executor/handlers/router/router-handler.ts
+++ b/apps/sim/executor/handlers/router/router-handler.ts
@@ -82,15 +82,15 @@ export class RouterBlockHandler implements BlockHandler {
}
const tokens = result.tokens || {
- prompt: DEFAULTS.TOKENS.PROMPT,
- completion: DEFAULTS.TOKENS.COMPLETION,
+ input: DEFAULTS.TOKENS.PROMPT,
+ output: DEFAULTS.TOKENS.COMPLETION,
total: DEFAULTS.TOKENS.TOTAL,
}
const cost = calculateCost(
result.model,
- tokens.prompt || DEFAULTS.TOKENS.PROMPT,
- tokens.completion || DEFAULTS.TOKENS.COMPLETION,
+ tokens.input || DEFAULTS.TOKENS.PROMPT,
+ tokens.output || DEFAULTS.TOKENS.COMPLETION,
false
)
@@ -98,8 +98,8 @@ export class RouterBlockHandler implements BlockHandler {
prompt: inputs.prompt,
model: result.model,
tokens: {
- prompt: tokens.prompt || DEFAULTS.TOKENS.PROMPT,
- completion: tokens.completion || DEFAULTS.TOKENS.COMPLETION,
+ input: tokens.input || DEFAULTS.TOKENS.PROMPT,
+ output: tokens.output || DEFAULTS.TOKENS.COMPLETION,
total: tokens.total || DEFAULTS.TOKENS.TOTAL,
},
cost: {
diff --git a/apps/sim/executor/types.ts b/apps/sim/executor/types.ts
index 4c52fb0d7e..f565fad55a 100644
--- a/apps/sim/executor/types.ts
+++ b/apps/sim/executor/types.ts
@@ -69,8 +69,8 @@ export interface NormalizedBlockOutput {
content?: string
model?: string
tokens?: {
- prompt?: number
- completion?: number
+ input?: number
+ output?: number
total?: number
}
toolCalls?: {
diff --git a/apps/sim/lib/billing/core/usage-log.ts b/apps/sim/lib/billing/core/usage-log.ts
index 478fc3bc8f..cfbf1a1057 100644
--- a/apps/sim/lib/billing/core/usage-log.ts
+++ b/apps/sim/lib/billing/core/usage-log.ts
@@ -154,7 +154,7 @@ export interface LogWorkflowUsageBatchParams {
string,
{
total: number
- tokens: { prompt: number; completion: number }
+ tokens: { input: number; output: number }
}
>
}
@@ -205,8 +205,8 @@ export async function logWorkflowUsageBatch(params: LogWorkflowUsageBatchParams)
source: 'workflow',
description: modelName,
metadata: {
- inputTokens: modelData.tokens.prompt,
- outputTokens: modelData.tokens.completion,
+ inputTokens: modelData.tokens.input,
+ outputTokens: modelData.tokens.output,
},
cost: modelData.total.toString(),
workspaceId: params.workspaceId ?? null,
diff --git a/apps/sim/lib/copilot/tools/server/workflow/get-workflow-console.ts b/apps/sim/lib/copilot/tools/server/workflow/get-workflow-console.ts
index 4adf279edc..3aa6ba245c 100644
--- a/apps/sim/lib/copilot/tools/server/workflow/get-workflow-console.ts
+++ b/apps/sim/lib/copilot/tools/server/workflow/get-workflow-console.ts
@@ -27,7 +27,7 @@ interface BlockExecution {
input: number
output: number
model?: string
- tokens?: { total: number; prompt: number; completion: number }
+ tokens?: { total: number; input: number; output: number }
}
}
diff --git a/apps/sim/lib/logs/execution/logger.ts b/apps/sim/lib/logs/execution/logger.ts
index 613ff9bf19..962eff8195 100644
--- a/apps/sim/lib/logs/execution/logger.ts
+++ b/apps/sim/lib/logs/execution/logger.ts
@@ -59,8 +59,12 @@ export class ExecutionLogger implements IExecutionLoggerService {
output: (merged[model].output || 0) + (costs.output || 0),
total: (merged[model].total || 0) + (costs.total || 0),
tokens: {
- prompt: (merged[model].tokens?.prompt || 0) + (costs.tokens?.prompt || 0),
- completion: (merged[model].tokens?.completion || 0) + (costs.tokens?.completion || 0),
+ input:
+ (merged[model].tokens?.input || merged[model].tokens?.prompt || 0) +
+ (costs.tokens?.input || costs.tokens?.prompt || 0),
+ output:
+ (merged[model].tokens?.output || merged[model].tokens?.completion || 0) +
+ (costs.tokens?.output || costs.tokens?.completion || 0),
total: (merged[model].tokens?.total || 0) + (costs.tokens?.total || 0),
},
}
@@ -195,7 +199,7 @@ export class ExecutionLogger implements IExecutionLoggerService {
input: number
output: number
total: number
- tokens: { prompt: number; completion: number; total: number }
+ tokens: { input: number; output: number; total: number }
}
>
}
@@ -269,8 +273,12 @@ export class ExecutionLogger implements IExecutionLoggerService {
input: (existingCost.input || 0) + costSummary.totalInputCost,
output: (existingCost.output || 0) + costSummary.totalOutputCost,
tokens: {
- prompt: (existingCost.tokens?.prompt || 0) + costSummary.totalPromptTokens,
- completion: (existingCost.tokens?.completion || 0) + costSummary.totalCompletionTokens,
+ input:
+ (existingCost.tokens?.input || existingCost.tokens?.prompt || 0) +
+ costSummary.totalPromptTokens,
+ output:
+ (existingCost.tokens?.output || existingCost.tokens?.completion || 0) +
+ costSummary.totalCompletionTokens,
total: (existingCost.tokens?.total || 0) + costSummary.totalTokens,
},
models: this.mergeCostModels(existingCost.models || {}, costSummary.models),
@@ -280,8 +288,8 @@ export class ExecutionLogger implements IExecutionLoggerService {
input: costSummary.totalInputCost,
output: costSummary.totalOutputCost,
tokens: {
- prompt: costSummary.totalPromptTokens,
- completion: costSummary.totalCompletionTokens,
+ input: costSummary.totalPromptTokens,
+ output: costSummary.totalCompletionTokens,
total: costSummary.totalTokens,
},
models: costSummary.models,
@@ -307,9 +315,9 @@ export class ExecutionLogger implements IExecutionLoggerService {
executionData: {
traceSpans: redactedTraceSpans,
finalOutput: redactedFinalOutput,
- tokenBreakdown: {
- prompt: mergedCost.tokens.prompt,
- completion: mergedCost.tokens.completion,
+ tokens: {
+ input: mergedCost.tokens.input,
+ output: mergedCost.tokens.output,
total: mergedCost.tokens.total,
},
models: mergedCost.models,
@@ -508,7 +516,7 @@ export class ExecutionLogger implements IExecutionLoggerService {
input: number
output: number
total: number
- tokens: { prompt: number; completion: number; total: number }
+ tokens: { input: number; output: number; total: number }
}
>
},
diff --git a/apps/sim/lib/logs/execution/logging-factory.ts b/apps/sim/lib/logs/execution/logging-factory.ts
index c09f4b2ec4..d56048554d 100644
--- a/apps/sim/lib/logs/execution/logging-factory.ts
+++ b/apps/sim/lib/logs/execution/logging-factory.ts
@@ -62,7 +62,7 @@ export function calculateCostSummary(traceSpans: any[]): {
input: number
output: number
total: number
- tokens: { prompt: number; completion: number; total: number }
+ tokens: { input: number; output: number; total: number }
}
>
} {
@@ -110,7 +110,7 @@ export function calculateCostSummary(traceSpans: any[]): {
input: number
output: number
total: number
- tokens: { prompt: number; completion: number; total: number }
+ tokens: { input: number; output: number; total: number }
}
> = {}
@@ -129,14 +129,14 @@ export function calculateCostSummary(traceSpans: any[]): {
input: 0,
output: 0,
total: 0,
- tokens: { prompt: 0, completion: 0, total: 0 },
+ tokens: { input: 0, output: 0, total: 0 },
}
}
models[model].input += span.cost.input || 0
models[model].output += span.cost.output || 0
models[model].total += span.cost.total || 0
- models[model].tokens.prompt += span.tokens?.input ?? span.tokens?.prompt ?? 0
- models[model].tokens.completion += span.tokens?.output ?? span.tokens?.completion ?? 0
+ models[model].tokens.input += span.tokens?.input ?? span.tokens?.prompt ?? 0
+ models[model].tokens.output += span.tokens?.output ?? span.tokens?.completion ?? 0
models[model].tokens.total += span.tokens?.total || 0
}
}
diff --git a/apps/sim/lib/logs/execution/trace-spans/trace-spans.test.ts b/apps/sim/lib/logs/execution/trace-spans/trace-spans.test.ts
index 379fe4eacf..829f8cad63 100644
--- a/apps/sim/lib/logs/execution/trace-spans/trace-spans.test.ts
+++ b/apps/sim/lib/logs/execution/trace-spans/trace-spans.test.ts
@@ -23,7 +23,7 @@ describe('buildTraceSpans', () => {
output: {
content: 'Agent response',
model: 'gpt-4o',
- tokens: { prompt: 10, completion: 20, total: 30 },
+ tokens: { input: 10, output: 20, total: 30 },
providerTiming: {
duration: 8000,
startTime: '2024-01-01T10:00:00.000Z',
@@ -138,7 +138,7 @@ describe('buildTraceSpans', () => {
output: {
content: 'Agent response',
model: 'gpt-4o',
- tokens: { prompt: 10, completion: 20, total: 30 },
+ tokens: { input: 10, output: 20, total: 30 },
providerTiming: {
duration: 4000,
startTime: '2024-01-01T10:00:00.500Z',
@@ -427,8 +427,8 @@ describe('buildTraceSpans', () => {
output: {
content: 'Based on my research using multiple sources...',
model: 'gpt-4o',
- tokens: { prompt: 50, completion: 200, total: 250 },
- cost: { total: 0.0025, prompt: 0.001, completion: 0.0015 },
+ tokens: { input: 50, output: 200, total: 250 },
+ cost: { total: 0.0025, input: 0.001, output: 0.0015 },
providerTiming: {
duration: 15000,
startTime: '2024-01-01T10:00:00.000Z',
diff --git a/apps/sim/lib/logs/types.ts b/apps/sim/lib/logs/types.ts
index d10f4dce5c..3fa807a637 100644
--- a/apps/sim/lib/logs/types.ts
+++ b/apps/sim/lib/logs/types.ts
@@ -15,8 +15,8 @@ export interface PricingInfo {
}
export interface TokenUsage {
- prompt: number
- completion: number
+ input: number
+ output: number
total: number
}
@@ -102,6 +102,17 @@ export interface WorkflowExecutionLog {
environment?: ExecutionEnvironment
trigger?: ExecutionTrigger
traceSpans?: TraceSpan[]
+ tokens?: { input?: number; output?: number; total?: number }
+ models?: Record<
+ string,
+ {
+ input?: number
+ output?: number
+ total?: number
+ tokens?: { input?: number; output?: number; total?: number }
+ }
+ >
+ finalOutput?: any
errorDetails?: {
blockId: string
blockName: string
@@ -114,14 +125,14 @@ export interface WorkflowExecutionLog {
input?: number
output?: number
total?: number
- tokens?: { prompt?: number; completion?: number; total?: number }
+ tokens?: { input?: number; output?: number; total?: number }
models?: Record<
string,
{
input?: number
output?: number
total?: number
- tokens?: { prompt?: number; completion?: number; total?: number }
+ tokens?: { input?: number; output?: number; total?: number }
}
>
}
diff --git a/apps/sim/lib/tokenization/calculators.ts b/apps/sim/lib/tokenization/calculators.ts
index 9b0d0a2d4e..e22aa1302d 100644
--- a/apps/sim/lib/tokenization/calculators.ts
+++ b/apps/sim/lib/tokenization/calculators.ts
@@ -57,8 +57,8 @@ export function calculateStreamingCost(
// Create token usage object
const tokens: TokenUsage = {
- prompt: totalPromptTokens,
- completion: completionTokens,
+ input: totalPromptTokens,
+ output: completionTokens,
total: totalTokens,
}
diff --git a/apps/sim/lib/tokenization/types.ts b/apps/sim/lib/tokenization/types.ts
index 10566f9e0a..221bb31646 100644
--- a/apps/sim/lib/tokenization/types.ts
+++ b/apps/sim/lib/tokenization/types.ts
@@ -14,10 +14,10 @@ export interface TokenEstimate {
}
export interface TokenUsage {
- /** Number of prompt/input tokens */
- prompt: number
- /** Number of completion/output tokens */
- completion: number
+ /** Number of input tokens */
+ input: number
+ /** Number of output tokens */
+ output: number
/** Total number of tokens */
total: number
}
diff --git a/apps/sim/lib/tokenization/utils.ts b/apps/sim/lib/tokenization/utils.ts
index 3f1866a8f7..c1a2600ef2 100644
--- a/apps/sim/lib/tokenization/utils.ts
+++ b/apps/sim/lib/tokenization/utils.ts
@@ -57,7 +57,7 @@ export function isTokenizableBlockType(blockType?: string): boolean {
*/
export function hasRealTokenData(tokens?: TokenUsage): boolean {
if (!tokens) return false
- return tokens.total > 0 || tokens.prompt > 0 || tokens.completion > 0
+ return tokens.total > 0 || tokens.input > 0 || tokens.output > 0
}
/**
diff --git a/apps/sim/providers/anthropic/index.ts b/apps/sim/providers/anthropic/index.ts
index 16c92ef846..0ad50fa90f 100644
--- a/apps/sim/providers/anthropic/index.ts
+++ b/apps/sim/providers/anthropic/index.ts
@@ -227,8 +227,8 @@ export const anthropicProvider: ProviderConfig = {
stream: createReadableStreamFromAnthropicStream(streamResponse, (content, usage) => {
streamingResult.execution.output.content = content
streamingResult.execution.output.tokens = {
- prompt: usage.input_tokens,
- completion: usage.output_tokens,
+ input: usage.input_tokens,
+ output: usage.output_tokens,
total: usage.input_tokens + usage.output_tokens,
}
@@ -260,7 +260,7 @@ export const anthropicProvider: ProviderConfig = {
output: {
content: '',
model: request.model,
- tokens: { prompt: 0, completion: 0, total: 0 },
+ tokens: { input: 0, output: 0, total: 0 },
toolCalls: undefined,
providerTiming: {
startTime: providerStartTimeISO,
@@ -320,8 +320,8 @@ export const anthropicProvider: ProviderConfig = {
}
const tokens = {
- prompt: currentResponse.usage?.input_tokens || 0,
- completion: currentResponse.usage?.output_tokens || 0,
+ input: currentResponse.usage?.input_tokens || 0,
+ output: currentResponse.usage?.output_tokens || 0,
total:
(currentResponse.usage?.input_tokens || 0) +
(currentResponse.usage?.output_tokens || 0),
@@ -547,8 +547,8 @@ export const anthropicProvider: ProviderConfig = {
modelTime += thisModelTime
if (currentResponse.usage) {
- tokens.prompt += currentResponse.usage.input_tokens || 0
- tokens.completion += currentResponse.usage.output_tokens || 0
+ tokens.input += currentResponse.usage.input_tokens || 0
+ tokens.output += currentResponse.usage.output_tokens || 0
tokens.total +=
(currentResponse.usage.input_tokens || 0) +
(currentResponse.usage.output_tokens || 0)
@@ -561,7 +561,7 @@ export const anthropicProvider: ProviderConfig = {
throw error
}
- const accumulatedCost = calculateCost(request.model, tokens.prompt, tokens.completion)
+ const accumulatedCost = calculateCost(request.model, tokens.input, tokens.output)
const streamingPayload = {
...payload,
@@ -578,8 +578,8 @@ export const anthropicProvider: ProviderConfig = {
(streamContent, usage) => {
streamingResult.execution.output.content = streamContent
streamingResult.execution.output.tokens = {
- prompt: tokens.prompt + usage.input_tokens,
- completion: tokens.completion + usage.output_tokens,
+ input: tokens.input + usage.input_tokens,
+ output: tokens.output + usage.output_tokens,
total: tokens.total + usage.input_tokens + usage.output_tokens,
}
@@ -610,8 +610,8 @@ export const anthropicProvider: ProviderConfig = {
content: '',
model: request.model,
tokens: {
- prompt: tokens.prompt,
- completion: tokens.completion,
+ input: tokens.input,
+ output: tokens.output,
total: tokens.total,
},
toolCalls:
@@ -692,8 +692,8 @@ export const anthropicProvider: ProviderConfig = {
}
const tokens = {
- prompt: currentResponse.usage?.input_tokens || 0,
- completion: currentResponse.usage?.output_tokens || 0,
+ input: currentResponse.usage?.input_tokens || 0,
+ output: currentResponse.usage?.output_tokens || 0,
total:
(currentResponse.usage?.input_tokens || 0) + (currentResponse.usage?.output_tokens || 0),
}
@@ -923,8 +923,8 @@ export const anthropicProvider: ProviderConfig = {
modelTime += thisModelTime
if (currentResponse.usage) {
- tokens.prompt += currentResponse.usage.input_tokens || 0
- tokens.completion += currentResponse.usage.output_tokens || 0
+ tokens.input += currentResponse.usage.input_tokens || 0
+ tokens.output += currentResponse.usage.output_tokens || 0
tokens.total +=
(currentResponse.usage.input_tokens || 0) + (currentResponse.usage.output_tokens || 0)
@@ -965,8 +965,8 @@ export const anthropicProvider: ProviderConfig = {
stream: createReadableStreamFromAnthropicStream(streamResponse, (content, usage) => {
streamingResult.execution.output.content = content
streamingResult.execution.output.tokens = {
- prompt: tokens.prompt + usage.input_tokens,
- completion: tokens.completion + usage.output_tokens,
+ input: tokens.input + usage.input_tokens,
+ output: tokens.output + usage.output_tokens,
total: tokens.total + usage.input_tokens + usage.output_tokens,
}
@@ -992,8 +992,8 @@ export const anthropicProvider: ProviderConfig = {
content: '',
model: request.model,
tokens: {
- prompt: tokens.prompt,
- completion: tokens.completion,
+ input: tokens.input,
+ output: tokens.output,
total: tokens.total,
},
toolCalls:
diff --git a/apps/sim/providers/azure-openai/index.ts b/apps/sim/providers/azure-openai/index.ts
index 2d63967c7e..3964971697 100644
--- a/apps/sim/providers/azure-openai/index.ts
+++ b/apps/sim/providers/azure-openai/index.ts
@@ -165,8 +165,8 @@ export const azureOpenAIProvider: ProviderConfig = {
stream: createReadableStreamFromAzureOpenAIStream(streamResponse, (content, usage) => {
streamingResult.execution.output.content = content
streamingResult.execution.output.tokens = {
- prompt: usage.prompt_tokens,
- completion: usage.completion_tokens,
+ input: usage.prompt_tokens,
+ output: usage.completion_tokens,
total: usage.total_tokens,
}
@@ -202,7 +202,7 @@ export const azureOpenAIProvider: ProviderConfig = {
output: {
content: '',
model: request.model,
- tokens: { prompt: 0, completion: 0, total: 0 },
+ tokens: { input: 0, output: 0, total: 0 },
toolCalls: undefined,
providerTiming: {
startTime: providerStartTimeISO,
@@ -242,8 +242,8 @@ export const azureOpenAIProvider: ProviderConfig = {
let content = currentResponse.choices[0]?.message?.content || ''
const tokens = {
- prompt: currentResponse.usage?.prompt_tokens || 0,
- completion: currentResponse.usage?.completion_tokens || 0,
+ input: currentResponse.usage?.prompt_tokens || 0,
+ output: currentResponse.usage?.completion_tokens || 0,
total: currentResponse.usage?.total_tokens || 0,
}
const toolCalls = []
@@ -445,8 +445,8 @@ export const azureOpenAIProvider: ProviderConfig = {
}
if (currentResponse.usage) {
- tokens.prompt += currentResponse.usage.prompt_tokens || 0
- tokens.completion += currentResponse.usage.completion_tokens || 0
+ tokens.input += currentResponse.usage.prompt_tokens || 0
+ tokens.output += currentResponse.usage.completion_tokens || 0
tokens.total += currentResponse.usage.total_tokens || 0
}
@@ -456,7 +456,7 @@ export const azureOpenAIProvider: ProviderConfig = {
if (request.stream) {
logger.info('Using streaming for final response after tool processing')
- const accumulatedCost = calculateCost(request.model, tokens.prompt, tokens.completion)
+ const accumulatedCost = calculateCost(request.model, tokens.input, tokens.output)
const streamingParams: ChatCompletionCreateParamsStreaming = {
...payload,
@@ -471,8 +471,8 @@ export const azureOpenAIProvider: ProviderConfig = {
stream: createReadableStreamFromAzureOpenAIStream(streamResponse, (content, usage) => {
streamingResult.execution.output.content = content
streamingResult.execution.output.tokens = {
- prompt: tokens.prompt + usage.prompt_tokens,
- completion: tokens.completion + usage.completion_tokens,
+ input: tokens.input + usage.prompt_tokens,
+ output: tokens.output + usage.completion_tokens,
total: tokens.total + usage.total_tokens,
}
@@ -493,8 +493,8 @@ export const azureOpenAIProvider: ProviderConfig = {
content: '',
model: request.model,
tokens: {
- prompt: tokens.prompt,
- completion: tokens.completion,
+ input: tokens.input,
+ output: tokens.output,
total: tokens.total,
},
toolCalls:
diff --git a/apps/sim/providers/cerebras/index.ts b/apps/sim/providers/cerebras/index.ts
index 131aad5451..7fb5c04f9c 100644
--- a/apps/sim/providers/cerebras/index.ts
+++ b/apps/sim/providers/cerebras/index.ts
@@ -125,8 +125,8 @@ export const cerebrasProvider: ProviderConfig = {
stream: createReadableStreamFromCerebrasStream(streamResponse, (content, usage) => {
streamingResult.execution.output.content = content
streamingResult.execution.output.tokens = {
- prompt: usage.prompt_tokens,
- completion: usage.completion_tokens,
+ input: usage.prompt_tokens,
+ output: usage.completion_tokens,
total: usage.total_tokens,
}
@@ -146,7 +146,7 @@ export const cerebrasProvider: ProviderConfig = {
output: {
content: '',
model: request.model,
- tokens: { prompt: 0, completion: 0, total: 0 },
+ tokens: { input: 0, output: 0, total: 0 },
toolCalls: undefined,
providerTiming: {
startTime: providerStartTimeISO,
@@ -183,8 +183,8 @@ export const cerebrasProvider: ProviderConfig = {
let content = currentResponse.choices[0]?.message?.content || ''
const tokens = {
- prompt: currentResponse.usage?.prompt_tokens || 0,
- completion: currentResponse.usage?.completion_tokens || 0,
+ input: currentResponse.usage?.prompt_tokens || 0,
+ output: currentResponse.usage?.completion_tokens || 0,
total: currentResponse.usage?.total_tokens || 0,
}
const toolCalls = []
@@ -384,8 +384,8 @@ export const cerebrasProvider: ProviderConfig = {
content = finalResponse.choices[0].message.content
}
if (finalResponse.usage) {
- tokens.prompt += finalResponse.usage.prompt_tokens || 0
- tokens.completion += finalResponse.usage.completion_tokens || 0
+ tokens.input += finalResponse.usage.prompt_tokens || 0
+ tokens.output += finalResponse.usage.completion_tokens || 0
tokens.total += finalResponse.usage.total_tokens || 0
}
@@ -416,8 +416,8 @@ export const cerebrasProvider: ProviderConfig = {
modelTime += thisModelTime
if (currentResponse.usage) {
- tokens.prompt += currentResponse.usage.prompt_tokens || 0
- tokens.completion += currentResponse.usage.completion_tokens || 0
+ tokens.input += currentResponse.usage.prompt_tokens || 0
+ tokens.output += currentResponse.usage.completion_tokens || 0
tokens.total += currentResponse.usage.total_tokens || 0
}
@@ -444,14 +444,14 @@ export const cerebrasProvider: ProviderConfig = {
const streamResponse: any = await client.chat.completions.create(streamingPayload)
- const accumulatedCost = calculateCost(request.model, tokens.prompt, tokens.completion)
+ const accumulatedCost = calculateCost(request.model, tokens.input, tokens.output)
const streamingResult = {
stream: createReadableStreamFromCerebrasStream(streamResponse, (content, usage) => {
streamingResult.execution.output.content = content
streamingResult.execution.output.tokens = {
- prompt: tokens.prompt + usage.prompt_tokens,
- completion: tokens.completion + usage.completion_tokens,
+ input: tokens.input + usage.prompt_tokens,
+ output: tokens.output + usage.completion_tokens,
total: tokens.total + usage.total_tokens,
}
@@ -472,8 +472,8 @@ export const cerebrasProvider: ProviderConfig = {
content: '',
model: request.model,
tokens: {
- prompt: tokens.prompt,
- completion: tokens.completion,
+ input: tokens.input,
+ output: tokens.output,
total: tokens.total,
},
toolCalls:
diff --git a/apps/sim/providers/deepseek/index.ts b/apps/sim/providers/deepseek/index.ts
index c82809dd39..f645c9ea2d 100644
--- a/apps/sim/providers/deepseek/index.ts
+++ b/apps/sim/providers/deepseek/index.ts
@@ -124,8 +124,8 @@ export const deepseekProvider: ProviderConfig = {
(content, usage) => {
streamingResult.execution.output.content = content
streamingResult.execution.output.tokens = {
- prompt: usage.prompt_tokens,
- completion: usage.completion_tokens,
+ input: usage.prompt_tokens,
+ output: usage.completion_tokens,
total: usage.total_tokens,
}
@@ -146,7 +146,7 @@ export const deepseekProvider: ProviderConfig = {
output: {
content: '',
model: request.model,
- tokens: { prompt: 0, completion: 0, total: 0 },
+ tokens: { input: 0, output: 0, total: 0 },
toolCalls: undefined,
providerTiming: {
startTime: providerStartTimeISO,
@@ -193,8 +193,8 @@ export const deepseekProvider: ProviderConfig = {
}
const tokens = {
- prompt: currentResponse.usage?.prompt_tokens || 0,
- completion: currentResponse.usage?.completion_tokens || 0,
+ input: currentResponse.usage?.prompt_tokens || 0,
+ output: currentResponse.usage?.completion_tokens || 0,
total: currentResponse.usage?.total_tokens || 0,
}
const toolCalls = []
@@ -413,8 +413,8 @@ export const deepseekProvider: ProviderConfig = {
}
if (currentResponse.usage) {
- tokens.prompt += currentResponse.usage.prompt_tokens || 0
- tokens.completion += currentResponse.usage.completion_tokens || 0
+ tokens.input += currentResponse.usage.prompt_tokens || 0
+ tokens.output += currentResponse.usage.completion_tokens || 0
tokens.total += currentResponse.usage.total_tokens || 0
}
@@ -440,7 +440,7 @@ export const deepseekProvider: ProviderConfig = {
const streamResponse = await deepseek.chat.completions.create(streamingPayload)
- const accumulatedCost = calculateCost(request.model, tokens.prompt, tokens.completion)
+ const accumulatedCost = calculateCost(request.model, tokens.input, tokens.output)
const streamingResult = {
stream: createReadableStreamFromDeepseekStream(
@@ -448,8 +448,8 @@ export const deepseekProvider: ProviderConfig = {
(content, usage) => {
streamingResult.execution.output.content = content
streamingResult.execution.output.tokens = {
- prompt: tokens.prompt + usage.prompt_tokens,
- completion: tokens.completion + usage.completion_tokens,
+ input: tokens.input + usage.prompt_tokens,
+ output: tokens.output + usage.completion_tokens,
total: tokens.total + usage.total_tokens,
}
@@ -471,8 +471,8 @@ export const deepseekProvider: ProviderConfig = {
content: '',
model: request.model,
tokens: {
- prompt: tokens.prompt,
- completion: tokens.completion,
+ input: tokens.input,
+ output: tokens.output,
total: tokens.total,
},
toolCalls:
diff --git a/apps/sim/providers/gemini/core.ts b/apps/sim/providers/gemini/core.ts
index f7cff4bacd..08ee02cff2 100644
--- a/apps/sim/providers/gemini/core.ts
+++ b/apps/sim/providers/gemini/core.ts
@@ -53,8 +53,8 @@ function createInitialState(
return {
contents,
tokens: {
- prompt: initialUsage.promptTokenCount,
- completion: initialUsage.candidatesTokenCount,
+ input: initialUsage.promptTokenCount,
+ output: initialUsage.candidatesTokenCount,
total: initialUsage.totalTokenCount,
},
cost: initialCost,
@@ -192,8 +192,8 @@ function updateStateWithResponse(
return {
...state,
tokens: {
- prompt: state.tokens.prompt + usage.promptTokenCount,
- completion: state.tokens.completion + usage.candidatesTokenCount,
+ input: state.tokens.input + usage.promptTokenCount,
+ output: state.tokens.output + usage.candidatesTokenCount,
total: state.tokens.total + usage.totalTokenCount,
},
cost: {
@@ -263,7 +263,7 @@ function createStreamingResult(
output: {
content: '',
model: '',
- tokens: state?.tokens ?? { prompt: 0, completion: 0, total: 0 },
+ tokens: state?.tokens ?? { input: 0, output: 0, total: 0 },
toolCalls: state?.toolCalls.length
? { list: state.toolCalls, count: state.toolCalls.length }
: undefined,
@@ -447,8 +447,8 @@ export async function executeGeminiRequest(
(content: string, usage: GeminiUsage) => {
streamingResult.execution.output.content = content
streamingResult.execution.output.tokens = {
- prompt: usage.promptTokenCount,
- completion: usage.candidatesTokenCount,
+ input: usage.promptTokenCount,
+ output: usage.candidatesTokenCount,
total: usage.totalTokenCount,
}
@@ -592,8 +592,8 @@ export async function executeGeminiRequest(
(streamContent: string, usage: GeminiUsage) => {
streamingResult.execution.output.content = streamContent
streamingResult.execution.output.tokens = {
- prompt: accumulatedTokens.prompt + usage.promptTokenCount,
- completion: accumulatedTokens.completion + usage.candidatesTokenCount,
+ input: accumulatedTokens.input + usage.promptTokenCount,
+ output: accumulatedTokens.output + usage.candidatesTokenCount,
total: accumulatedTokens.total + usage.totalTokenCount,
}
diff --git a/apps/sim/providers/gemini/types.ts b/apps/sim/providers/gemini/types.ts
index 02592d09b6..7216086cb6 100644
--- a/apps/sim/providers/gemini/types.ts
+++ b/apps/sim/providers/gemini/types.ts
@@ -23,7 +23,7 @@ export interface ParsedFunctionCall {
*/
export interface ExecutionState {
contents: Content[]
- tokens: { prompt: number; completion: number; total: number }
+ tokens: { input: number; output: number; total: number }
cost: { input: number; output: number; total: number; pricing: ModelPricing }
toolCalls: FunctionCallResponse[]
toolResults: Record[]
diff --git a/apps/sim/providers/groq/index.ts b/apps/sim/providers/groq/index.ts
index 58ff64197d..b61cd5fd49 100644
--- a/apps/sim/providers/groq/index.ts
+++ b/apps/sim/providers/groq/index.ts
@@ -126,8 +126,8 @@ export const groqProvider: ProviderConfig = {
stream: createReadableStreamFromGroqStream(streamResponse as any, (content, usage) => {
streamingResult.execution.output.content = content
streamingResult.execution.output.tokens = {
- prompt: usage.prompt_tokens,
- completion: usage.completion_tokens,
+ input: usage.prompt_tokens,
+ output: usage.completion_tokens,
total: usage.total_tokens,
}
@@ -147,7 +147,7 @@ export const groqProvider: ProviderConfig = {
output: {
content: '',
model: request.model,
- tokens: { prompt: 0, completion: 0, total: 0 },
+ tokens: { input: 0, output: 0, total: 0 },
toolCalls: undefined,
providerTiming: {
startTime: providerStartTimeISO,
@@ -189,8 +189,8 @@ export const groqProvider: ProviderConfig = {
let content = currentResponse.choices[0]?.message?.content || ''
const tokens = {
- prompt: currentResponse.usage?.prompt_tokens || 0,
- completion: currentResponse.usage?.completion_tokens || 0,
+ input: currentResponse.usage?.prompt_tokens || 0,
+ output: currentResponse.usage?.completion_tokens || 0,
total: currentResponse.usage?.total_tokens || 0,
}
const toolCalls = []
@@ -373,8 +373,8 @@ export const groqProvider: ProviderConfig = {
}
if (currentResponse.usage) {
- tokens.prompt += currentResponse.usage.prompt_tokens || 0
- tokens.completion += currentResponse.usage.completion_tokens || 0
+ tokens.input += currentResponse.usage.prompt_tokens || 0
+ tokens.output += currentResponse.usage.completion_tokens || 0
tokens.total += currentResponse.usage.total_tokens || 0
}
@@ -396,14 +396,14 @@ export const groqProvider: ProviderConfig = {
const streamResponse = await groq.chat.completions.create(streamingPayload)
- const accumulatedCost = calculateCost(request.model, tokens.prompt, tokens.completion)
+ const accumulatedCost = calculateCost(request.model, tokens.input, tokens.output)
const streamingResult = {
stream: createReadableStreamFromGroqStream(streamResponse as any, (content, usage) => {
streamingResult.execution.output.content = content
streamingResult.execution.output.tokens = {
- prompt: tokens.prompt + usage.prompt_tokens,
- completion: tokens.completion + usage.completion_tokens,
+ input: tokens.input + usage.prompt_tokens,
+ output: tokens.output + usage.completion_tokens,
total: tokens.total + usage.total_tokens,
}
@@ -424,8 +424,8 @@ export const groqProvider: ProviderConfig = {
content: '',
model: request.model,
tokens: {
- prompt: tokens.prompt,
- completion: tokens.completion,
+ input: tokens.input,
+ output: tokens.output,
total: tokens.total,
},
toolCalls:
diff --git a/apps/sim/providers/index.ts b/apps/sim/providers/index.ts
index 6c4fa15c9c..6825af2851 100644
--- a/apps/sim/providers/index.ts
+++ b/apps/sim/providers/index.ts
@@ -85,7 +85,7 @@ export async function executeProviderRequest(
}
if (response.tokens) {
- const { prompt: promptTokens = 0, completion: completionTokens = 0 } = response.tokens
+ const { input: promptTokens = 0, output: completionTokens = 0 } = response.tokens
const useCachedInput = !!request.context && request.context.length > 0
if (shouldBillModelUsage(response.model)) {
diff --git a/apps/sim/providers/mistral/index.ts b/apps/sim/providers/mistral/index.ts
index 9cfda86f1f..1a5d2b5585 100644
--- a/apps/sim/providers/mistral/index.ts
+++ b/apps/sim/providers/mistral/index.ts
@@ -149,8 +149,8 @@ export const mistralProvider: ProviderConfig = {
stream: createReadableStreamFromMistralStream(streamResponse, (content, usage) => {
streamingResult.execution.output.content = content
streamingResult.execution.output.tokens = {
- prompt: usage.prompt_tokens,
- completion: usage.completion_tokens,
+ input: usage.prompt_tokens,
+ output: usage.completion_tokens,
total: usage.total_tokens,
}
@@ -186,7 +186,7 @@ export const mistralProvider: ProviderConfig = {
output: {
content: '',
model: request.model,
- tokens: { prompt: 0, completion: 0, total: 0 },
+ tokens: { input: 0, output: 0, total: 0 },
toolCalls: undefined,
providerTiming: {
startTime: providerStartTimeISO,
@@ -247,8 +247,8 @@ export const mistralProvider: ProviderConfig = {
let content = currentResponse.choices[0]?.message?.content || ''
const tokens = {
- prompt: currentResponse.usage?.prompt_tokens || 0,
- completion: currentResponse.usage?.completion_tokens || 0,
+ input: currentResponse.usage?.prompt_tokens || 0,
+ output: currentResponse.usage?.completion_tokens || 0,
total: currentResponse.usage?.total_tokens || 0,
}
const toolCalls = []
@@ -434,8 +434,8 @@ export const mistralProvider: ProviderConfig = {
}
if (currentResponse.usage) {
- tokens.prompt += currentResponse.usage.prompt_tokens || 0
- tokens.completion += currentResponse.usage.completion_tokens || 0
+ tokens.input += currentResponse.usage.prompt_tokens || 0
+ tokens.output += currentResponse.usage.completion_tokens || 0
tokens.total += currentResponse.usage.total_tokens || 0
}
@@ -445,7 +445,7 @@ export const mistralProvider: ProviderConfig = {
if (request.stream) {
logger.info('Using streaming for final response after tool processing')
- const accumulatedCost = calculateCost(request.model, tokens.prompt, tokens.completion)
+ const accumulatedCost = calculateCost(request.model, tokens.input, tokens.output)
const streamingParams: ChatCompletionCreateParamsStreaming = {
...payload,
@@ -460,8 +460,8 @@ export const mistralProvider: ProviderConfig = {
stream: createReadableStreamFromMistralStream(streamResponse, (content, usage) => {
streamingResult.execution.output.content = content
streamingResult.execution.output.tokens = {
- prompt: tokens.prompt + usage.prompt_tokens,
- completion: tokens.completion + usage.completion_tokens,
+ input: tokens.input + usage.prompt_tokens,
+ output: tokens.output + usage.completion_tokens,
total: tokens.total + usage.total_tokens,
}
@@ -482,8 +482,8 @@ export const mistralProvider: ProviderConfig = {
content: '',
model: request.model,
tokens: {
- prompt: tokens.prompt,
- completion: tokens.completion,
+ input: tokens.input,
+ output: tokens.output,
total: tokens.total,
},
toolCalls:
diff --git a/apps/sim/providers/ollama/index.ts b/apps/sim/providers/ollama/index.ts
index 1838443c18..467cd5b141 100644
--- a/apps/sim/providers/ollama/index.ts
+++ b/apps/sim/providers/ollama/index.ts
@@ -178,8 +178,8 @@ export const ollamaProvider: ProviderConfig = {
}
streamingResult.execution.output.tokens = {
- prompt: usage.prompt_tokens,
- completion: usage.completion_tokens,
+ input: usage.prompt_tokens,
+ output: usage.completion_tokens,
total: usage.total_tokens,
}
@@ -215,7 +215,7 @@ export const ollamaProvider: ProviderConfig = {
output: {
content: '',
model: request.model,
- tokens: { prompt: 0, completion: 0, total: 0 },
+ tokens: { input: 0, output: 0, total: 0 },
toolCalls: undefined,
providerTiming: {
startTime: providerStartTimeISO,
@@ -258,8 +258,8 @@ export const ollamaProvider: ProviderConfig = {
}
const tokens = {
- prompt: currentResponse.usage?.prompt_tokens || 0,
- completion: currentResponse.usage?.completion_tokens || 0,
+ input: currentResponse.usage?.prompt_tokens || 0,
+ output: currentResponse.usage?.completion_tokens || 0,
total: currentResponse.usage?.total_tokens || 0,
}
const toolCalls = []
@@ -429,8 +429,8 @@ export const ollamaProvider: ProviderConfig = {
}
if (currentResponse.usage) {
- tokens.prompt += currentResponse.usage.prompt_tokens || 0
- tokens.completion += currentResponse.usage.completion_tokens || 0
+ tokens.input += currentResponse.usage.prompt_tokens || 0
+ tokens.output += currentResponse.usage.completion_tokens || 0
tokens.total += currentResponse.usage.total_tokens || 0
}
@@ -440,7 +440,7 @@ export const ollamaProvider: ProviderConfig = {
if (request.stream) {
logger.info('Using streaming for final response after tool processing')
- const accumulatedCost = calculateCost(request.model, tokens.prompt, tokens.completion)
+ const accumulatedCost = calculateCost(request.model, tokens.input, tokens.output)
const streamingParams: ChatCompletionCreateParamsStreaming = {
...payload,
@@ -462,8 +462,8 @@ export const ollamaProvider: ProviderConfig = {
}
streamingResult.execution.output.tokens = {
- prompt: tokens.prompt + usage.prompt_tokens,
- completion: tokens.completion + usage.completion_tokens,
+ input: tokens.input + usage.prompt_tokens,
+ output: tokens.output + usage.completion_tokens,
total: tokens.total + usage.total_tokens,
}
@@ -484,8 +484,8 @@ export const ollamaProvider: ProviderConfig = {
content: '',
model: request.model,
tokens: {
- prompt: tokens.prompt,
- completion: tokens.completion,
+ input: tokens.input,
+ output: tokens.output,
total: tokens.total,
},
toolCalls:
diff --git a/apps/sim/providers/openai/index.ts b/apps/sim/providers/openai/index.ts
index 700dc6aa67..74d8d5d712 100644
--- a/apps/sim/providers/openai/index.ts
+++ b/apps/sim/providers/openai/index.ts
@@ -144,8 +144,8 @@ export const openaiProvider: ProviderConfig = {
stream: createReadableStreamFromOpenAIStream(streamResponse, (content, usage) => {
streamingResult.execution.output.content = content
streamingResult.execution.output.tokens = {
- prompt: usage.prompt_tokens,
- completion: usage.completion_tokens,
+ input: usage.prompt_tokens,
+ output: usage.completion_tokens,
total: usage.total_tokens,
}
@@ -181,7 +181,7 @@ export const openaiProvider: ProviderConfig = {
output: {
content: '',
model: request.model,
- tokens: { prompt: 0, completion: 0, total: 0 },
+ tokens: { input: 0, output: 0, total: 0 },
toolCalls: undefined,
providerTiming: {
startTime: providerStartTimeISO,
@@ -245,8 +245,8 @@ export const openaiProvider: ProviderConfig = {
let content = currentResponse.choices[0]?.message?.content || ''
const tokens = {
- prompt: currentResponse.usage?.prompt_tokens || 0,
- completion: currentResponse.usage?.completion_tokens || 0,
+ input: currentResponse.usage?.prompt_tokens || 0,
+ output: currentResponse.usage?.completion_tokens || 0,
total: currentResponse.usage?.total_tokens || 0,
}
const toolCalls = []
@@ -433,8 +433,8 @@ export const openaiProvider: ProviderConfig = {
modelTime += thisModelTime
if (currentResponse.usage) {
- tokens.prompt += currentResponse.usage.prompt_tokens || 0
- tokens.completion += currentResponse.usage.completion_tokens || 0
+ tokens.input += currentResponse.usage.prompt_tokens || 0
+ tokens.output += currentResponse.usage.completion_tokens || 0
tokens.total += currentResponse.usage.total_tokens || 0
}
@@ -444,7 +444,7 @@ export const openaiProvider: ProviderConfig = {
if (request.stream) {
logger.info('Using streaming for final response after tool processing')
- const accumulatedCost = calculateCost(request.model, tokens.prompt, tokens.completion)
+ const accumulatedCost = calculateCost(request.model, tokens.input, tokens.output)
const streamingParams: ChatCompletionCreateParamsStreaming = {
...payload,
@@ -459,8 +459,8 @@ export const openaiProvider: ProviderConfig = {
stream: createReadableStreamFromOpenAIStream(streamResponse, (content, usage) => {
streamingResult.execution.output.content = content
streamingResult.execution.output.tokens = {
- prompt: tokens.prompt + usage.prompt_tokens,
- completion: tokens.completion + usage.completion_tokens,
+ input: tokens.input + usage.prompt_tokens,
+ output: tokens.output + usage.completion_tokens,
total: tokens.total + usage.total_tokens,
}
@@ -481,8 +481,8 @@ export const openaiProvider: ProviderConfig = {
content: '',
model: request.model,
tokens: {
- prompt: tokens.prompt,
- completion: tokens.completion,
+ input: tokens.input,
+ output: tokens.output,
total: tokens.total,
},
toolCalls:
diff --git a/apps/sim/providers/openrouter/index.ts b/apps/sim/providers/openrouter/index.ts
index abaf25a96d..ac2357656c 100644
--- a/apps/sim/providers/openrouter/index.ts
+++ b/apps/sim/providers/openrouter/index.ts
@@ -160,8 +160,8 @@ export const openRouterProvider: ProviderConfig = {
stream: createReadableStreamFromOpenAIStream(streamResponse, (content, usage) => {
streamingResult.execution.output.content = content
streamingResult.execution.output.tokens = {
- prompt: usage.prompt_tokens,
- completion: usage.completion_tokens,
+ input: usage.prompt_tokens,
+ output: usage.completion_tokens,
total: usage.total_tokens,
}
@@ -193,7 +193,7 @@ export const openRouterProvider: ProviderConfig = {
output: {
content: '',
model: requestedModel,
- tokens: { prompt: 0, completion: 0, total: 0 },
+ tokens: { input: 0, output: 0, total: 0 },
toolCalls: undefined,
providerTiming: {
startTime: providerStartTimeISO,
@@ -233,8 +233,8 @@ export const openRouterProvider: ProviderConfig = {
let content = currentResponse.choices[0]?.message?.content || ''
const tokens = {
- prompt: currentResponse.usage?.prompt_tokens || 0,
- completion: currentResponse.usage?.completion_tokens || 0,
+ input: currentResponse.usage?.prompt_tokens || 0,
+ output: currentResponse.usage?.completion_tokens || 0,
total: currentResponse.usage?.total_tokens || 0,
}
const toolCalls = [] as any[]
@@ -420,15 +420,15 @@ export const openRouterProvider: ProviderConfig = {
content = currentResponse.choices[0].message.content
}
if (currentResponse.usage) {
- tokens.prompt += currentResponse.usage.prompt_tokens || 0
- tokens.completion += currentResponse.usage.completion_tokens || 0
+ tokens.input += currentResponse.usage.prompt_tokens || 0
+ tokens.output += currentResponse.usage.completion_tokens || 0
tokens.total += currentResponse.usage.total_tokens || 0
}
iterationCount++
}
if (request.stream) {
- const accumulatedCost = calculateCost(requestedModel, tokens.prompt, tokens.completion)
+ const accumulatedCost = calculateCost(requestedModel, tokens.input, tokens.output)
const streamingParams: ChatCompletionCreateParamsStreaming & { provider?: any } = {
model: payload.model,
@@ -459,8 +459,8 @@ export const openRouterProvider: ProviderConfig = {
stream: createReadableStreamFromOpenAIStream(streamResponse, (content, usage) => {
streamingResult.execution.output.content = content
streamingResult.execution.output.tokens = {
- prompt: tokens.prompt + usage.prompt_tokens,
- completion: tokens.completion + usage.completion_tokens,
+ input: tokens.input + usage.prompt_tokens,
+ output: tokens.output + usage.completion_tokens,
total: tokens.total + usage.total_tokens,
}
@@ -480,7 +480,7 @@ export const openRouterProvider: ProviderConfig = {
output: {
content: '',
model: requestedModel,
- tokens: { prompt: tokens.prompt, completion: tokens.completion, total: tokens.total },
+ tokens: { input: tokens.input, output: tokens.output, total: tokens.total },
toolCalls:
toolCalls.length > 0
? {
@@ -553,8 +553,8 @@ export const openRouterProvider: ProviderConfig = {
content = finalResponse.choices[0].message.content
}
if (finalResponse.usage) {
- tokens.prompt += finalResponse.usage.prompt_tokens || 0
- tokens.completion += finalResponse.usage.completion_tokens || 0
+ tokens.input += finalResponse.usage.prompt_tokens || 0
+ tokens.output += finalResponse.usage.completion_tokens || 0
tokens.total += finalResponse.usage.total_tokens || 0
}
}
diff --git a/apps/sim/providers/types.ts b/apps/sim/providers/types.ts
index 9d83ec4581..df0e4b1f85 100644
--- a/apps/sim/providers/types.ts
+++ b/apps/sim/providers/types.ts
@@ -28,8 +28,8 @@ export interface ModelPricing {
export type ModelPricingMap = Record
export interface TokenInfo {
- prompt?: number
- completion?: number
+ input?: number
+ output?: number
total?: number
}
@@ -74,8 +74,8 @@ export interface ProviderResponse {
content: string
model: string
tokens?: {
- prompt?: number
- completion?: number
+ input?: number
+ output?: number
total?: number
}
toolCalls?: FunctionCallResponse[]
diff --git a/apps/sim/providers/vllm/index.ts b/apps/sim/providers/vllm/index.ts
index 6fe2734ded..4984d8cec0 100644
--- a/apps/sim/providers/vllm/index.ts
+++ b/apps/sim/providers/vllm/index.ts
@@ -198,8 +198,8 @@ export const vllmProvider: ProviderConfig = {
streamingResult.execution.output.content = cleanContent
streamingResult.execution.output.tokens = {
- prompt: usage.prompt_tokens,
- completion: usage.completion_tokens,
+ input: usage.prompt_tokens,
+ output: usage.completion_tokens,
total: usage.total_tokens,
}
@@ -235,7 +235,7 @@ export const vllmProvider: ProviderConfig = {
output: {
content: '',
model: request.model,
- tokens: { prompt: 0, completion: 0, total: 0 },
+ tokens: { input: 0, output: 0, total: 0 },
toolCalls: undefined,
providerTiming: {
startTime: providerStartTimeISO,
@@ -301,8 +301,8 @@ export const vllmProvider: ProviderConfig = {
}
const tokens = {
- prompt: currentResponse.usage?.prompt_tokens || 0,
- completion: currentResponse.usage?.completion_tokens || 0,
+ input: currentResponse.usage?.prompt_tokens || 0,
+ output: currentResponse.usage?.completion_tokens || 0,
total: currentResponse.usage?.total_tokens || 0,
}
const toolCalls = []
@@ -497,8 +497,8 @@ export const vllmProvider: ProviderConfig = {
}
if (currentResponse.usage) {
- tokens.prompt += currentResponse.usage.prompt_tokens || 0
- tokens.completion += currentResponse.usage.completion_tokens || 0
+ tokens.input += currentResponse.usage.prompt_tokens || 0
+ tokens.output += currentResponse.usage.completion_tokens || 0
tokens.total += currentResponse.usage.total_tokens || 0
}
@@ -508,7 +508,7 @@ export const vllmProvider: ProviderConfig = {
if (request.stream) {
logger.info('Using streaming for final response after tool processing')
- const accumulatedCost = calculateCost(request.model, tokens.prompt, tokens.completion)
+ const accumulatedCost = calculateCost(request.model, tokens.input, tokens.output)
const streamingParams: ChatCompletionCreateParamsStreaming = {
...payload,
@@ -528,8 +528,8 @@ export const vllmProvider: ProviderConfig = {
streamingResult.execution.output.content = cleanContent
streamingResult.execution.output.tokens = {
- prompt: tokens.prompt + usage.prompt_tokens,
- completion: tokens.completion + usage.completion_tokens,
+ input: tokens.input + usage.prompt_tokens,
+ output: tokens.output + usage.completion_tokens,
total: tokens.total + usage.total_tokens,
}
@@ -550,8 +550,8 @@ export const vllmProvider: ProviderConfig = {
content: '',
model: request.model,
tokens: {
- prompt: tokens.prompt,
- completion: tokens.completion,
+ input: tokens.input,
+ output: tokens.output,
total: tokens.total,
},
toolCalls:
diff --git a/apps/sim/providers/xai/index.ts b/apps/sim/providers/xai/index.ts
index d57f282816..4d86efbd2b 100644
--- a/apps/sim/providers/xai/index.ts
+++ b/apps/sim/providers/xai/index.ts
@@ -119,8 +119,8 @@ export const xAIProvider: ProviderConfig = {
stream: createReadableStreamFromXAIStream(streamResponse, (content, usage) => {
streamingResult.execution.output.content = content
streamingResult.execution.output.tokens = {
- prompt: usage.prompt_tokens,
- completion: usage.completion_tokens,
+ input: usage.prompt_tokens,
+ output: usage.completion_tokens,
total: usage.total_tokens,
}
@@ -140,7 +140,7 @@ export const xAIProvider: ProviderConfig = {
output: {
content: '',
model: request.model,
- tokens: { prompt: 0, completion: 0, total: 0 },
+ tokens: { input: 0, output: 0, total: 0 },
toolCalls: undefined,
providerTiming: {
startTime: providerStartTimeISO,
@@ -202,8 +202,8 @@ export const xAIProvider: ProviderConfig = {
let content = currentResponse.choices[0]?.message?.content || ''
const tokens = {
- prompt: currentResponse.usage?.prompt_tokens || 0,
- completion: currentResponse.usage?.completion_tokens || 0,
+ input: currentResponse.usage?.prompt_tokens || 0,
+ output: currentResponse.usage?.completion_tokens || 0,
total: currentResponse.usage?.total_tokens || 0,
}
const toolCalls = []
@@ -441,8 +441,8 @@ export const xAIProvider: ProviderConfig = {
}
if (currentResponse.usage) {
- tokens.prompt += currentResponse.usage.prompt_tokens || 0
- tokens.completion += currentResponse.usage.completion_tokens || 0
+ tokens.input += currentResponse.usage.prompt_tokens || 0
+ tokens.output += currentResponse.usage.completion_tokens || 0
tokens.total += currentResponse.usage.total_tokens || 0
}
@@ -479,14 +479,14 @@ export const xAIProvider: ProviderConfig = {
const streamResponse = await xai.chat.completions.create(finalStreamingPayload as any)
- const accumulatedCost = calculateCost(request.model, tokens.prompt, tokens.completion)
+ const accumulatedCost = calculateCost(request.model, tokens.input, tokens.output)
const streamingResult = {
stream: createReadableStreamFromXAIStream(streamResponse as any, (content, usage) => {
streamingResult.execution.output.content = content
streamingResult.execution.output.tokens = {
- prompt: tokens.prompt + usage.prompt_tokens,
- completion: tokens.completion + usage.completion_tokens,
+ input: tokens.input + usage.prompt_tokens,
+ output: tokens.output + usage.completion_tokens,
total: tokens.total + usage.total_tokens,
}
@@ -507,8 +507,8 @@ export const xAIProvider: ProviderConfig = {
content: '',
model: request.model,
tokens: {
- prompt: tokens.prompt,
- completion: tokens.completion,
+ input: tokens.input,
+ output: tokens.output,
total: tokens.total,
},
toolCalls:
diff --git a/apps/sim/stores/logs/filters/types.ts b/apps/sim/stores/logs/filters/types.ts
index ca949a8190..72f18e5ead 100644
--- a/apps/sim/stores/logs/filters/types.ts
+++ b/apps/sim/stores/logs/filters/types.ts
@@ -29,6 +29,8 @@ export interface CostMetadata {
output: number
total: number
tokens?: {
+ input?: number
+ output?: number
prompt?: number
completion?: number
total?: number
@@ -39,6 +41,8 @@ export interface CostMetadata {
output?: number
total?: number
tokens?: {
+ input?: number
+ output?: number
prompt?: number
completion?: number
total?: number
diff --git a/apps/sim/stores/panel/copilot/store.ts b/apps/sim/stores/panel/copilot/store.ts
index 290c46327e..d273debd95 100644
--- a/apps/sim/stores/panel/copilot/store.ts
+++ b/apps/sim/stores/panel/copilot/store.ts
@@ -53,6 +53,8 @@ import { ManageMcpToolClientTool } from '@/lib/copilot/tools/client/workflow/man
import { RunWorkflowClientTool } from '@/lib/copilot/tools/client/workflow/run-workflow'
import { SetGlobalWorkflowVariablesClientTool } from '@/lib/copilot/tools/client/workflow/set-global-workflow-variables'
import { createLogger } from '@/lib/logs/console/logger'
+import { getQueryClient } from '@/app/_shell/providers/query-provider'
+import { subscriptionKeys } from '@/hooks/queries/subscription'
import type {
ChatContext,
CopilotMessage,
@@ -2663,6 +2665,12 @@ export const useCopilotStore = create()(
// Fetch context usage after response completes
logger.info('[Context Usage] Stream completed, fetching usage')
await get().fetchContextUsage()
+
+ // Invalidate subscription queries to update usage
+ setTimeout(() => {
+ const queryClient = getQueryClient()
+ queryClient.invalidateQueries({ queryKey: subscriptionKeys.user() })
+ }, 1000)
} finally {
clearTimeout(timeoutId)
}