Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
4 changes: 2 additions & 2 deletions apps/docs/components/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8767,12 +8767,12 @@ export function LogfireIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg
{...props}
viewBox='0 0 138 120'
viewBox='0 0 750 750'
fill='currentColor'
role='img'
xmlns='http://www.w3.org/2000/svg'
>
<path d='M137.041 90.563 73.326 2.241c-2.005-2.757-6.628-2.757-8.613 0L.998 90.563A5.32 5.32 0 0 0 0 93.664a5.331 5.331 0 0 0 3.641 5.05l63.715 20.851h.01a5.306 5.306 0 0 0 3.292 0h.01l63.715-20.85a5.265 5.265 0 0 0 3.392-3.406 5.247 5.247 0 0 0-.749-4.746h.015ZM69.022 14.412 94.56 49.815l-23.882-7.813c-.185-.06-.38-.05-.564-.094a3.484 3.484 0 0 0-.548-.09c-.185-.025-.36-.095-.544-.095-.185 0-.354.07-.539.095-.184.02-.369.05-.548.09-.19.035-.384.035-.554.094L43.644 49.77l-.15.05L69.032 14.41h-.01ZM32.94 64.438l27.802-9.104 2.968-.967v52.838L13.86 90.887 32.94 64.438Zm41.399 42.757V54.367l30.77 10.071 19.079 26.434-49.854 16.323h.005Z' />
<path d='M 741.496094 539.726562 L 398.203125 63.890625 C 387.398438 49.039062 362.480469 49.039062 351.789062 63.890625 L 8.492188 539.726562 C 6.746094 542.160156 5.414062 544.804688 4.496094 547.65625 C 3.578125 550.511719 3.117188 553.4375 3.117188 556.433594 C 3.117188 557.929688 3.238281 559.414062 3.472656 560.890625 C 3.703125 562.371094 4.050781 563.820312 4.511719 565.242188 C 4.972656 566.664062 5.539062 568.042969 6.214844 569.378906 C 6.890625 570.710938 7.667969 571.984375 8.542969 573.199219 C 9.417969 574.410156 10.378906 575.550781 11.433594 576.613281 C 12.484375 577.675781 13.613281 578.648438 14.816406 579.535156 C 16.023438 580.421875 17.289062 581.207031 18.617188 581.898438 C 19.941406 582.585938 21.316406 583.167969 22.734375 583.640625 L 366.03125 695.972656 L 366.085938 695.972656 C 368.96875 696.914062 371.921875 697.382812 374.953125 697.382812 C 377.984375 697.382812 380.941406 696.914062 383.824219 695.972656 L 383.875 695.972656 L 727.175781 583.644531 C 729.316406 582.953125 731.347656 582.015625 733.265625 580.839844 C 735.183594 579.660156 736.941406 578.273438 738.527344 576.679688 C 740.117188 575.082031 741.496094 573.324219 742.667969 571.398438 C 743.835938 569.476562 744.765625 567.441406 745.449219 565.296875 C 746.15625 563.15625 746.601562 560.96875 746.785156 558.722656 C 746.96875 556.480469 746.882812 554.246094 746.53125 552.023438 C 746.183594 549.796875 745.574219 547.644531 744.710938 545.566406 C 743.84375 543.488281 742.746094 541.542969 741.414062 539.726562 Z M 375.011719 129.460938 L 512.605469 320.195312 L 383.929688 278.105469 C 382.941406 277.78125 381.882812 277.835938 380.894531 277.597656 C 379.917969 277.355469 378.933594 277.195312 377.933594 277.113281 C 376.945312 276.976562 376 276.601562 375.011719 276.601562 C 374.015625 276.601562 373.097656 276.976562 372.101562 277.113281 C 371.109375 277.21875 370.121094 277.382812 369.152344 277.597656 C 368.128906 277.785156 367.082031 277.785156 366.167969 278.105469 L 238.269531 319.953125 L 237.460938 320.222656 L 375.070312 129.453125 L 375.015625 129.453125 Z M 180.597656 398.976562 L 330.394531 349.929688 L 346.386719 344.71875 L 346.386719 629.386719 L 77.804688 541.472656 Z M 403.65625 629.332031 L 403.65625 344.71875 L 569.445312 398.976562 L 672.246094 541.390625 L 403.628906 629.332031 Z M 403.65625 629.332031 ' />
</svg>
)
}
8 changes: 5 additions & 3 deletions apps/docs/content/docs/en/integrations/logfire.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"

<BlockInfoCard
type="logfire"
color="#E520E9"
color="#000000"
/>

{/* MANUAL-CONTENT-START:intro */}
Expand Down Expand Up @@ -95,7 +95,7 @@ Search Logfire spans and logs using structured filters for message text, service
| ↳ `level` | string | Severity name, such as info, warn, or error |
| ↳ `message` | string | Human-readable message |
| ↳ `spanName` | string | Template label for similar records |
| ↳ `kind` | string | Record kind: span, log, or span_event |
| ↳ `kind` | string | Record kind: span, log, span_event, or pending_span |
| ↳ `serviceName` | string | Service that emitted the record |
| ↳ `deploymentEnvironment` | string | Deployment environment of the record |
| ↳ `traceId` | string | Trace this record belongs to |
Expand Down Expand Up @@ -134,7 +134,7 @@ Fetch every span and log belonging to a Logfire trace, ordered from earliest to
| ↳ `level` | string | Severity name, such as info, warn, or error |
| ↳ `message` | string | Human-readable message |
| ↳ `spanName` | string | Template label for similar records |
| ↳ `kind` | string | Record kind: span, log, or span_event |
| ↳ `kind` | string | Record kind: span, log, span_event, or pending_span |
| ↳ `serviceName` | string | Service that emitted the record |
| ↳ `deploymentEnvironment` | string | Deployment environment of the record |
| ↳ `traceId` | string | Trace this record belongs to |
Expand Down Expand Up @@ -164,5 +164,7 @@ Resolve which Logfire organization and project a read token belongs to. Useful f
| --------- | ---- | ----------- |
| `organizationName` | string | Logfire organization the read token belongs to |
| `projectName` | string | Logfire project the read token belongs to |
| `expiresAt` | string | When the read token expires. Null when it never expires. |
| `spendingCapReachedAt` | string | When the organization's spending cap was reached, which stops queries. Null when it has not been reached. |


73 changes: 62 additions & 11 deletions apps/sim/blocks/blocks/logfire.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ export const LogfireBlock: BlockConfig<LogfireResponse> = {
category: 'tools',
authMode: AuthMode.ApiKey,
integrationType: IntegrationType.Observability,
bgColor: '#E520E9',
iconColor: '#E520E9',
bgColor: '#000000',
iconColor: '#E620E9',
icon: LogfireIcon,
subBlocks: [
{
Expand Down Expand Up @@ -113,6 +113,7 @@ export const LogfireBlock: BlockConfig<LogfireResponse> = {
placeholder: 'https://logfire-us.pydantic.dev',
description:
'Base URL of your Logfire instance. Leave blank for Logfire Cloud — the region is read from your token. Set this for a self-hosted deployment.',
mode: 'advanced',
},
{
id: 'region',
Expand Down Expand Up @@ -291,7 +292,7 @@ Return ONLY the IANA timezone string - no explanations or quotes.`,
host: params.host,
}

const window = {
const timeWindow = {
minTimestamp: params.minTimestamp,
maxTimestamp: params.maxTimestamp,
limit: toNumber(params.limit),
Expand All @@ -301,7 +302,7 @@ Return ONLY the IANA timezone string - no explanations or quotes.`,
case 'logfire_query':
return {
...baseParams,
...window,
...timeWindow,
sql: params.sql,
timezone: params.timezone,
environment: params.environment,
Expand All @@ -310,7 +311,7 @@ Return ONLY the IANA timezone string - no explanations or quotes.`,
case 'logfire_get_trace':
return {
...baseParams,
...window,
...timeWindow,
traceId: params.traceId,
}

Expand All @@ -320,7 +321,7 @@ Return ONLY the IANA timezone string - no explanations or quotes.`,
default:
return {
...baseParams,
...window,
...timeWindow,
query: params.query,
service: params.service,
spanName: params.spanName,
Expand Down Expand Up @@ -355,12 +356,50 @@ Return ONLY the IANA timezone string - no explanations or quotes.`,
type: 'json',
description:
'Result rows. Raw SQL returns the query projection; Search Records and Get Trace return records (startTimestamp, endTimestamp, duration, level, message, spanName, kind, serviceName, deploymentEnvironment, traceId, spanId, parentSpanId, isException, exceptionType, exceptionMessage).',
condition: {
field: 'operation',
value: ['logfire_query', 'logfire_search_records', 'logfire_get_trace'],
},
},
rowCount: {
type: 'number',
description: 'Number of rows returned',
condition: {
field: 'operation',
value: ['logfire_query', 'logfire_search_records', 'logfire_get_trace'],
},
},
columns: {
type: 'json',
description: 'Column metadata (name, datatype, nullable)',
condition: { field: 'operation', value: 'logfire_query' },
},
sql: {
type: 'string',
description: 'SQL query that was executed against Logfire',
condition: { field: 'operation', value: ['logfire_search_records', 'logfire_get_trace'] },
},
organizationName: {
type: 'string',
description: 'Organization the read token belongs to',
condition: { field: 'operation', value: 'logfire_get_token_info' },
},
projectName: {
type: 'string',
description: 'Project the read token belongs to',
condition: { field: 'operation', value: 'logfire_get_token_info' },
},
expiresAt: {
type: 'string',
description: 'When the read token expires. Null when it never expires.',
condition: { field: 'operation', value: 'logfire_get_token_info' },
},
spendingCapReachedAt: {
type: 'string',
description:
"When the organization's spending cap was reached, which stops queries. Null when it has not been reached.",
condition: { field: 'operation', value: 'logfire_get_token_info' },
},
rowCount: { type: 'number', description: 'Number of rows returned' },
columns: { type: 'json', description: 'Column metadata (name, datatype, nullable)' },
sql: { type: 'string', description: 'SQL query that was executed against Logfire' },
organizationName: { type: 'string', description: 'Organization the read token belongs to' },
projectName: { type: 'string', description: 'Project the read token belongs to' },
},
}

Expand Down Expand Up @@ -467,5 +506,17 @@ export const LogfireBlockMeta = {
content:
'# Reconstruct Logfire Trace\n\nTurn a trace ID into a readable story of one request.\n\n## Steps\n1. Run Get Trace with the trace ID. Spans come back earliest first.\n2. Build the tree using spanId and parentSpanId to see which operations nested inside which.\n3. Note each span duration to find where time was spent, and flag any span where isException is true.\n4. If the trace is truncated, raise the limit and refetch.\n\n## Output\nAn ordered walkthrough of the request: the entry point, each significant nested operation with its duration, and where it failed or ended. Call out the single slowest span and the first exception.',
},
{
name: 'track-logfire-llm-cost',
description: 'Aggregate LLM token usage and spend per model from Logfire GenAI spans.',
content:
"# Track Logfire LLM Cost\n\nAttribute AI spend to models and services.\n\n## Steps\n1. Run a SQL Query against the records table reading the GenAI attributes Logfire records under OpenTelemetry conventions, for example: SELECT date_trunc('day', start_timestamp) AS day, attributes->>'gen_ai.request.model' AS model, sum((attributes->'gen_ai.usage.input_tokens')::numeric) AS input_tokens, sum((attributes->'gen_ai.usage.output_tokens')::numeric) AS output_tokens FROM records WHERE attributes ? 'gen_ai.request.model' GROUP BY day, model ORDER BY day DESC.\n2. Add sum((attributes->'operation.cost')::numeric) AS cost_usd when the instrumentation records cost.\n3. Slice by service_name or deployment_environment to attribute spend to a team or environment.\n4. Cast JSON attributes to numeric before any arithmetic — they are stored as JSON, not numbers.\n\n## Output\nSpend and token totals broken down by model and day, the biggest contributor, and any model whose cost per call moved materially.",
},
{
name: 'verify-logfire-token-target',
description: 'Confirm which Logfire organization and project a read token points at.',
content:
'# Verify Logfire Token Target\n\nCheck a credential before trusting the data it returns.\n\n## Steps\n1. Run Get Token Info to resolve the organization and project the read token belongs to.\n2. Compare them against the project the user expected to query.\n3. If they differ, stop and report the mismatch rather than querying — the token points at another project.\n4. When they match, proceed with Search Records or a SQL Query.\n\n## Output\nThe organization and project names behind the token, and a clear statement of whether they match the expected target.',
},
],
} as const satisfies BlockMeta
4 changes: 2 additions & 2 deletions apps/sim/components/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8918,12 +8918,12 @@ export function LogfireIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg
{...props}
viewBox='0 0 138 120'
viewBox='0 0 750 750'
fill='currentColor'
role='img'
xmlns='http://www.w3.org/2000/svg'
>
<path d='M137.041 90.563 73.326 2.241c-2.005-2.757-6.628-2.757-8.613 0L.998 90.563A5.32 5.32 0 0 0 0 93.664a5.331 5.331 0 0 0 3.641 5.05l63.715 20.851h.01a5.306 5.306 0 0 0 3.292 0h.01l63.715-20.85a5.265 5.265 0 0 0 3.392-3.406 5.247 5.247 0 0 0-.749-4.746h.015ZM69.022 14.412 94.56 49.815l-23.882-7.813c-.185-.06-.38-.05-.564-.094a3.484 3.484 0 0 0-.548-.09c-.185-.025-.36-.095-.544-.095-.185 0-.354.07-.539.095-.184.02-.369.05-.548.09-.19.035-.384.035-.554.094L43.644 49.77l-.15.05L69.032 14.41h-.01ZM32.94 64.438l27.802-9.104 2.968-.967v52.838L13.86 90.887 32.94 64.438Zm41.399 42.757V54.367l30.77 10.071 19.079 26.434-49.854 16.323h.005Z' />
<path d='M 741.496094 539.726562 L 398.203125 63.890625 C 387.398438 49.039062 362.480469 49.039062 351.789062 63.890625 L 8.492188 539.726562 C 6.746094 542.160156 5.414062 544.804688 4.496094 547.65625 C 3.578125 550.511719 3.117188 553.4375 3.117188 556.433594 C 3.117188 557.929688 3.238281 559.414062 3.472656 560.890625 C 3.703125 562.371094 4.050781 563.820312 4.511719 565.242188 C 4.972656 566.664062 5.539062 568.042969 6.214844 569.378906 C 6.890625 570.710938 7.667969 571.984375 8.542969 573.199219 C 9.417969 574.410156 10.378906 575.550781 11.433594 576.613281 C 12.484375 577.675781 13.613281 578.648438 14.816406 579.535156 C 16.023438 580.421875 17.289062 581.207031 18.617188 581.898438 C 19.941406 582.585938 21.316406 583.167969 22.734375 583.640625 L 366.03125 695.972656 L 366.085938 695.972656 C 368.96875 696.914062 371.921875 697.382812 374.953125 697.382812 C 377.984375 697.382812 380.941406 696.914062 383.824219 695.972656 L 383.875 695.972656 L 727.175781 583.644531 C 729.316406 582.953125 731.347656 582.015625 733.265625 580.839844 C 735.183594 579.660156 736.941406 578.273438 738.527344 576.679688 C 740.117188 575.082031 741.496094 573.324219 742.667969 571.398438 C 743.835938 569.476562 744.765625 567.441406 745.449219 565.296875 C 746.15625 563.15625 746.601562 560.96875 746.785156 558.722656 C 746.96875 556.480469 746.882812 554.246094 746.53125 552.023438 C 746.183594 549.796875 745.574219 547.644531 744.710938 545.566406 C 743.84375 543.488281 742.746094 541.542969 741.414062 539.726562 Z M 375.011719 129.460938 L 512.605469 320.195312 L 383.929688 278.105469 C 382.941406 277.78125 381.882812 277.835938 380.894531 277.597656 C 379.917969 277.355469 378.933594 277.195312 377.933594 277.113281 C 376.945312 276.976562 376 276.601562 375.011719 276.601562 C 374.015625 276.601562 373.097656 276.976562 372.101562 277.113281 C 371.109375 277.21875 370.121094 277.382812 369.152344 277.597656 C 368.128906 277.785156 367.082031 277.785156 366.167969 278.105469 L 238.269531 319.953125 L 237.460938 320.222656 L 375.070312 129.453125 L 375.015625 129.453125 Z M 180.597656 398.976562 L 330.394531 349.929688 L 346.386719 344.71875 L 346.386719 629.386719 L 77.804688 541.472656 Z M 403.65625 629.332031 L 403.65625 344.71875 L 569.445312 398.976562 L 672.246094 541.390625 L 403.628906 629.332031 Z M 403.65625 629.332031 ' />
</svg>
)
}
4 changes: 2 additions & 2 deletions apps/sim/lib/integrations/integrations.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"updatedAt": "2026-07-31",
"updatedAt": "2026-08-02",
"integrations": [
{
"type": "onepassword",
Expand Down Expand Up @@ -11665,7 +11665,7 @@
"name": "Logfire",
"description": "Query traces, logs, and metrics in Pydantic Logfire",
"longDescription": "Integrate Pydantic Logfire into workflows. Run SQL over your observability data, search spans and logs with structured filters, pull an entire trace by ID, and confirm which project a read token targets.",
"bgColor": "#E520E9",
"bgColor": "#000000",
"iconName": "LogfireIcon",
"docsUrl": "https://docs.sim.ai/integrations/logfire",
"operations": [
Expand Down
38 changes: 35 additions & 3 deletions apps/sim/tools/logfire/get_token_info.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,52 @@ describe('logfireGetTokenInfoTool request', () => {
describe('logfireGetTokenInfoTool transformResponse', () => {
it('maps the snake_case token info into the block outputs', async () => {
const response = new Response(
JSON.stringify({ organization_name: 'acme', project_name: 'backend' }),
JSON.stringify({
organization_name: 'acme',
project_name: 'backend',
expires_at: '2027-01-01T00:00:00Z',
spending_cap_reached_at: '2026-08-01T12:00:00Z',
}),
{ status: 200 }
)

const result = await logfireGetTokenInfoTool.transformResponse?.(response, baseParams)

expect(result?.success).toBe(true)
expect(result?.output).toEqual({ organizationName: 'acme', projectName: 'backend' })
expect(result?.output).toEqual({
organizationName: 'acme',
projectName: 'backend',
expiresAt: '2027-01-01T00:00:00Z',
spendingCapReachedAt: '2026-08-01T12:00:00Z',
})
})

it('keeps a non-expiring, under-cap token distinguishable from a missing field', async () => {
const response = new Response(
JSON.stringify({
organization_name: 'acme',
project_name: 'backend',
expires_at: null,
spending_cap_reached_at: null,
}),
{ status: 200 }
)

const result = await logfireGetTokenInfoTool.transformResponse?.(response, baseParams)

expect(result?.output.expiresAt).toBeNull()
expect(result?.output.spendingCapReachedAt).toBeNull()
})

it('nulls fields the API omitted', async () => {
const response = new Response(JSON.stringify({}), { status: 200 })
const result = await logfireGetTokenInfoTool.transformResponse?.(response, baseParams)

expect(result?.output).toEqual({ organizationName: null, projectName: null })
expect(result?.output).toEqual({
organizationName: null,
projectName: null,
expiresAt: null,
spendingCapReachedAt: null,
})
})
})
13 changes: 13 additions & 0 deletions apps/sim/tools/logfire/get_token_info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ export const logfireGetTokenInfoTool: ToolConfig<
output: {
organizationName: info.organization_name ?? null,
projectName: info.project_name ?? null,
expiresAt: info.expires_at ?? null,
spendingCapReachedAt: info.spending_cap_reached_at ?? null,
},
}
},
Expand All @@ -72,5 +74,16 @@ export const logfireGetTokenInfoTool: ToolConfig<
description: 'Logfire project the read token belongs to',
nullable: true,
},
expiresAt: {
type: 'string',
description: 'When the read token expires. Null when it never expires.',
nullable: true,
},
spendingCapReachedAt: {
type: 'string',
description:
"When the organization's spending cap was reached, which stops queries. Null when it has not been reached.",
nullable: true,
},
Comment thread
cursor[bot] marked this conversation as resolved.
},
}
Loading
Loading