Governed data.Plain English.Visible SQL.
An independent open-source .NET client, terminal application and automation toolkit for Databricks Genie Agents. Genie lives in the Databricks web UI. This puts it in your terminal, your scripts and your C#.
Generated SQL can be wrong in ways that read as correct. LakeSpeak keeps the statement, its bound values and the message ids, so you can check the answer yourself.
dotnet tool install --global LakeSpeak.Clidotnet add package LakeSpeak.GenieYou need a Genie Agent that already exists in your workspace and is shared with you. LakeSpeak cannot create one.
A terminal that
keeps the receipts
Real output, captured from the CLI against a live Databricks workspace. All three frames are on the page, so switching works with scripting off.
Six calls, four id types, one polling loop
- 01databricks genie list-spaces
- 02databricks genie start-conversation <space-id> "question"
- 03databricks genie get-message <space-id> <conversation-id> <message-id>
- 04databricks genie get-message-attachment-query-result ...
- 05databricks genie generate-download-full-query-result ...
- 06databricks genie get-download-full-query-result ...
lakespeak ask--agent sales "How did revenue change last month?"This is a narrow tool. It is not a Databricks SDK for .NET, and Databricks already ships managed MCP endpoints for Genie. What you could not do before was hold a conversation from C#, or run a set of questions on a schedule and get a document back.
Down goes the question
What it actually does
Stateful conversations
chat keeps context, so “and break that down by quarter” works. Slash commands cover /sql, /result and /export.
Six output formats
text, table, markdown, json, jsonl and csv. Results on stdout, progress and errors on stderr.
The SQL, preserved
The statement, the values bound into it and the message ids are all kept, so a person can check an answer instead of trusting it.
No credential ever stored
Short-lived OAuth tokens are brokered through the Databricks CLI and held in memory for the life of the process.
Question Packs
A YAML pack turns a set of business questions into a version-controlled Markdown report, runnable on a schedule.
Contractual exit codes
0 success, 1 unexpected, 2 bad input, 3 auth, 4 permission, 5 not found, 6 Genie could not answer, 7 timeout, 8 partial pack failure, 9 malformed response.
Typed failures in C#
Every error surfaces as GenieException with a GenieFailureKind you can branch on.
Unity Catalog, untouched
You see exactly what your Databricks identity is permitted to see. LakeSpeak has no way to widen that.
Questions under version control
A Question Pack turns a set of business questions into a reviewable report. Declare them once, run the pack on a schedule, then read the Markdown in a pull request.
validate reports every problem at once, so you fix a pack in one pass.
apiVersion: lakespeak.dev/v1alpha1
kind: QuestionPack
metadata:
name: daily-platform-brief
description: Daily summary of Databricks platform health
spec:
agent: platform-operations
questions:
- id: failed-jobs
title: Failed production jobs
ask: >
Which production jobs failed during the
last 24 hours? Include job name, failure
time, and latest error category.
- id: expensive-queries
title: Most expensive queries
ask: Which queries consumed the most compute yesterday?
output:
format: markdown
path: reports/daily-platform-brief.md
behavior:
continueOnQuestionFailure: true
includeGeneratedSql: false
includeTimings: true
The keys and values are those of the real example file inexamples/question-packs/, wrapped to fit this column.
Failures you can branch on
The client validates its configuration when you first resolve it, not on the first call. Failures arrive as a GenieException carrying aGenieFailureKind you can switch on.
Cells reach you as strings, exactly as Databricks returned them. A DECIMAL never goes through a double on the way.
- Authentication
- Authorization
- AgentNotFound
- ConversationNotFound
- MessageFailed
- MessageCancelled
- PollingTimeout
- RateLimited
- QueryResultExpired
- QueryExecutionFailed
- MalformedResponse
- UnsupportedResult
- Network
- Unexpected
using LakeSpeak.Genie;
using Microsoft.Extensions.DependencyInjection;
services.AddLakeSpeak(options => options.Profile = "production");
var genie = provider.GetRequiredService<IGenieClient>();
try
{
var response = await genie.AskAsync(
agentId: salesAgentId,
question: "Which customers had the largest revenue decline?",
cancellationToken: cancellationToken);
Console.WriteLine(response.Text);
// The SQL, so a human can check the answer.
if (response.Query is { Sql: { } sql })
{
Console.WriteLine(sql);
}
}
catch (GenieException ex) when (ex.Kind == GenieFailureKind.Authorization)
{
// Fixed with a Databricks grant, not in code.
}
Compiled against LakeSpeak.Genie from nuget.org on every pull request, so this cannot quietly stop being real code.
What it does not do
It does not bypass Unity Catalog. You see exactly what your Databricks identity is permitted to see, and LakeSpeak has no way to widen that.
It does not guarantee a Genie answer is correct. Generated SQL can be wrong in ways that read as plausible, which is why the SQL, the source metadata and the message ids are preserved.
It does not execute arbitrary SQL, edit generated SQL, or modify Genie Agent definitions.
It does not store your questions, answers or query results anywhere except files you explicitly export.
Read the source, not the pitch
Six libraries, six test projects, sixteen documents and two runnable examples, all Apache 2.0 in one repository. Every claim on this page traces to a file you can open.
The examples are part of the solution, so CI builds them. An example that no longer compiles is worse than no example.
git clone https://github.com/ivanvyd/LakeSpeak.NET.gitIssues beat guesses
Good first issues →Issues and pull requests are welcome. The roadmap is a guess about what people want, so an issue arguing for something else is the most useful thing you can send.
Good first issues are labelled as such. Core authentication and security work is not labelled that way, on purpose.
Setup, style, the test projects, and what a reviewable pull request looks like here.
Who decides, how, and what is deliberately out of scope. Read before proposing something large.
Four decision records cover the load-bearing choices. Disagreement is best expressed against one of them.
Not in an issue. The threat model says where the boundaries actually are.
Short, and enforced. SUPPORT.md covers where questions go instead of the issue tracker.
Nothing to a working answer in ten minutes
Install, log in with the Databricks CLI, find your Agent, ask something. Longer if someone else still has to create the Agent for you.