Docs menuSnowflake

Snowflake

Example query and read-only user for a custom agent on Snowflake.

Updated 3 October 2026

This query assumes an example schema: agent_turns, with one row per question; app_users; and agent_queries, agent_reasoning, agent_messages and agent_tool_calls, with one row per step, keyed by turn_id. Replace the names with your own, and drop any column your agent doesn’t record.

ARRAY_AGG returns an empty array when there are no rows.

Connection string

snowflake://benchouse_read:TOKEN@ACCOUNT?warehouse=WH&role=BENCHOUSE_READ

Query

SELECT
    t.id            AS turn_id,
    t.created_at    AS asked_at,
    t.updated_at    AS updated_at,
    t.finished_at   AS completed_at,
    t.question      AS question_text,
    t.answer        AS answer_text,
    t.status        AS outcome,
    t.error         AS error_message,
    t.chat_id       AS conversation_id,
    t.user_id       AS user_id,
    u.email         AS user_email,
    t.model         AS model_name,
    t.input_tokens  AS input_tokens,
    t.output_tokens AS output_tokens,
    (SELECT ARRAY_AGG(OBJECT_CONSTRUCT(
                'sql', q.sql_text, 'status', q.status, 'error', q.error,
                'rows', q.row_count, 'started_at', q.started_at,
                'ended_at', q.ended_at, 'is_answer', q.is_final))
            WITHIN GROUP (ORDER BY q.started_at)
       FROM agent_queries q WHERE q.turn_id = t.id) AS statements,
    (SELECT ARRAY_AGG(OBJECT_CONSTRUCT('label', r.kind, 'text', r.content))
            WITHIN GROUP (ORDER BY r.seq)
       FROM agent_reasoning r WHERE r.turn_id = t.id) AS reasoning,
    (SELECT ARRAY_AGG(OBJECT_CONSTRUCT('kind', m.kind, 'text', m.content))
            WITHIN GROUP (ORDER BY m.seq)
       FROM agent_messages m WHERE m.turn_id = t.id) AS messages,
    (SELECT ARRAY_AGG(OBJECT_CONSTRUCT(
                'name', c.tool, 'input', c.input, 'output', c.output,
                'status', c.status, 'started_at', c.started_at, 'ended_at', c.ended_at))
            WITHIN GROUP (ORDER BY c.seq)
       FROM agent_tool_calls c WHERE c.turn_id = t.id) AS tool_calls
FROM agent_turns t
LEFT JOIN app_users u ON u.id = t.user_id

Save the query as a view, agent_logs.public.benchouse_turns, and give

Benchouse that view and nothing else. The query you enter is then SELECT * FROM agent_logs.public.benchouse_turns.

Read-only role, user and token

CREATE ROLE benchouse_read;
GRANT USAGE ON WAREHOUSE eval_wh TO ROLE benchouse_read;
GRANT USAGE ON DATABASE agent_logs TO ROLE benchouse_read;
GRANT USAGE ON SCHEMA agent_logs.public TO ROLE benchouse_read;
GRANT SELECT ON VIEW agent_logs.public.benchouse_turns TO ROLE benchouse_read;
CREATE USER benchouse_read TYPE = SERVICE_AGENT DEFAULT_ROLE = benchouse_read;
GRANT ROLE benchouse_read TO USER benchouse_read;
ALTER USER benchouse_read ADD PROGRAMMATIC ACCESS TOKEN benchouse_read ROLE_RESTRICTION = 'BENCHOUSE_READ';