Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
e3b225c
feat(agents): prototype a Goose agent type over ACP
salman1993 Oct 13, 2026
9706e74
feat(goose): provider setup, session transcripts, and plain-text replies
salman1993 Oct 13, 2026
fa10b07
feat(agents): add Pi agents on Pi durable
salman1993 Oct 14, 2026
3bf4c9a
Merge remote-tracking branch 'origin/main' into claude/pi-durable-age…
salman1993 Oct 14, 2026
2d266d5
refactor(pi): read the agent's community through AgentReads
salman1993 Oct 14, 2026
ec9b366
feat(pi): ship Pi turned off until enabled in Settings
salman1993 Oct 14, 2026
11b1f99
fix(pi): keep a sign-in when an auth.json change returns nothing
salman1993 Oct 14, 2026
9714eb3
Merge remote-tracking branch 'origin/main' into claude/pi-durable-age…
salman1993 Oct 14, 2026
9fd2000
Merge origin/main into sm/goose-agent-plugin
salman1993 Oct 14, 2026
fbb4018
fix(pi): settle steers of failed runs, keep steers to their own pick,…
salman1993 Oct 14, 2026
55e1c54
Merge remote-tracking branch 'origin/main' into claude/pi-durable-age…
salman1993 Oct 14, 2026
b42b557
fix(pi): choose Pi's model in New agent's Model field
salman1993 Oct 14, 2026
2b606cd
feat(agents): add goose agentType plugin, serve buzz tools over HTTP …
salman1993 Oct 14, 2026
9d230e7
Merge remote-tracking branch 'origin/claude/pi-durable-agent-plugin-e…
salman1993 Oct 14, 2026
098e6ad
feat(providers): share a Databricks connection with Goose agents
salman1993 Oct 14, 2026
5044735
fix(goose): keep goose's thinking effort off the Databricks Chat route
salman1993 Oct 14, 2026
688abb7
feat(goose): offer verified Databricks models over the Responses route
salman1993 Oct 14, 2026
faf21b4
fix(goose): put goose's model in New agent's Model field
salman1993 Oct 14, 2026
fda7465
feat(providers): report each Databricks model's gateway routes
salman1993 Oct 14, 2026
a509755
feat(pi): run Pi agents on the shared Databricks connection
salman1993 Oct 14, 2026
db09d64
docs(providers): describe the Pi slice of shared Databricks
salman1993 Oct 14, 2026
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
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions crates/plugin-manager/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ pub struct HostGrants {
/// a process takes stdin and the caller appends its own arguments.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub processes: Vec<HostProcess>,
/// The plugin may serve MCP servers on loopback HTTP to the agents it
/// runs, answering their messages itself.
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub mcp: bool,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
Expand Down Expand Up @@ -168,6 +172,10 @@ pub fn bundled_manifests() -> Vec<Manifest> {
});
vec![
builderlab,
serde_json::from_str(include_str!(
"../../../src/bundled/databricks/manifest.json"
))
.expect("databricks manifest"),
serde_json::from_str(include_str!("../../../src/bundled/pairing/manifest.json"))
.expect("valid pairing manifest"),
serde_json::from_str(include_str!("../../../src/bundled/todos/manifest.json"))
Expand Down Expand Up @@ -222,6 +230,10 @@ pub fn bundled_manifests() -> Vec<Manifest> {
.expect("claude manifest"),
serde_json::from_str(include_str!("../../../src/bundled/codex/manifest.json"))
.expect("codex manifest"),
serde_json::from_str(include_str!("../../../src/bundled/goose/manifest.json"))
.expect("goose manifest"),
serde_json::from_str(include_str!("../../../src/bundled/pi/manifest.json"))
.expect("pi manifest"),
serde_json::from_str(include_str!("../../../src/bundled/workflows/manifest.json"))
.expect("workflows manifest"),
serde_json::from_str(include_str!("../../../src/bundled/feedback/manifest.json"))
Expand Down Expand Up @@ -263,6 +275,8 @@ fn enabled_by_default(id: &str) -> bool {
| "buzz.agents"
| "buzz.claude-code"
| "buzz.codex"
| "buzz.goose"
| "buzz.databricks"
| "buzz.workflows"
| "buzz.sessions"
| "block.hosted-communities"
Expand Down
2 changes: 1 addition & 1 deletion crates/plugin-manager/tests/management.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,7 @@ fn bundled_defaults_preserve_saved_choices_and_only_channels_is_required() {
.any(|plugin| plugin.manifest.id == "buzz.me"));
for plugin in &catalog.plugins {
let id = plugin.manifest.id.as_str();
let default = !matches!(id, "buzz.bestie" | "buzz.todos");
let default = !matches!(id, "buzz.bestie" | "buzz.pi" | "buzz.todos");
assert_eq!(plugin.enabled, default, "{id}");
if id == "buzz.channels" {
assert!(manager.change("disable", id).is_err());
Expand Down
53 changes: 53 additions & 0 deletions docs/provider-plugins-exploration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Shared provider plugins for Goose and Pi

Goose and Pi can use several inference providers. Their credentials belong to the selected provider, rather than a single harness account such as the one used by Codex or Claude. A shared provider plugin would let a user configure Databricks or OpenRouter once and use that connection from either agent type.

## Motivation

In the Buzz discussions, Mic asked how general-purpose harnesses could share providers, and baxen proposed configuring credentials once for Goose and Pi. The proposed scope became credentials plus model discovery. This would avoid separate logins and duplicate configuration while giving Buzz one model picker across configured providers. See the [provider registry discussion](buzz://message?channel=099e2481-9499-48d6-adad-fa89a15163a0&id=385f6dae4cdf5e455a3ca506e8c96ee270b86198b053547d47a87587534f2514) and [shared provider proposal](buzz://message?channel=099e2481-9499-48d6-adad-fa89a15163a0&id=0cba713c360bf4b5310cd717df4868e8e6e0b644dfcf69f424645b64da8960ae).

## Scope

Provider integration involves three kinds of work:

1. **Authentication and configuration:** credentials, endpoints, login, and token refresh.

2. **Model discovery:** model IDs, aliases, available API routes, and capabilities.

3. **Inference:** request formatting, streaming, thinking controls, and conversation replay.

Share the first two. Leave inference to each agent plugin’s harness integration. Goose and Pi have different request and history representations; their existing adapters already translate those into provider APIs. The [Pi Databricks extension](https://github.com/squareup/pi-extensions/tree/main/packages/pi-databricks) also contains Pi-specific compatibility fixes that a shared catalog cannot replace.

## Databricks example and boundaries

A user configures **Work Databricks**, signs in once, and chooses a model. The shared plugin supplies the connection and catalog. The Pi integration registers a provider with the routes and compatibility settings of Pi’s Databricks extension; the Goose integration configures a supported Goose provider adapter. Each uses a supported API route and obtains current access tokens from the shared authentication owner.

| Shared Databricks plugin owns | Each agent plugin integration owns |
| --- | --- |
| Workspace configuration and connection identity | Binding an agent to a connection and served model ID |
| Login, credential storage, and token refresh | Obtaining fresh access tokens while sessions remain running |
| Endpoint and alias discovery | Registering the catalog with its harness |
| Available API routes and provider capability facts | Filtering unsupported routes and mapping model and effort choices |
| Shared authentication and discovery status | Request formatting, streaming, history replay, and harness-specific compatibility fixes |

The picker can lead with the model and show “via Work Databricks” underneath. Save the exact connection and served model ID. A model appearing in the shared catalog does not imply that both harnesses support it; each integration must check compatibility.

## First slice: Databricks for Goose

Add one shared connection to Block’s Databricks workspace, with browser login, private local credential storage, token refresh, and discovery. Goose selects that connection and an exact served model ID. Pi follows in the next slice; OpenRouter can follow after that.

Goose’s native Databricks adapter does not accept an external credential callback. For this slice, the Goose integration generates a custom OpenAI adapter configuration with command auth. A small Buzz native helper supplies current access tokens; refresh tokens stay in the provider’s private local storage. File locking serializes refresh across Goose processes. Request formatting and streaming remain in Goose.

Goose uses the gateway’s Responses route. Its Chat route rejects reasoning effort alongside tools for GPT-6 models, and GPT-6.1 Sol always requires reasoning effort. Goose offers a short list of ready, tool-capable endpoints that were verified with its tools: GPT-6 and 6.1, Claude Opus, Sonnet, and Haiku 5.5, GLM 5.3, and Grok 4.7. Gemini rejects Goose’s streaming options, and Gemma rejects a tool-schema keyword. Other models, aliases, workspace configuration, and per-agent thinking controls are deferred; Goose’s own thinking-effort setting applies.

The generated Goose configuration contains no tokens and uses its usual history store. Cancellation applies while waiting for the browser. Once the callback has been accepted, the UI shows “Completing sign-in…” while native code saves the connection.

Try it by enabling Databricks and Goose, opening **Settings → Providers → Databricks**, signing in, then choosing **Databricks in Buzz** in a Goose agent’s provider dialog. Verify a tool-bearing conversation, two agents using the same connection, history after restart, and continued work after token refresh.

## Second slice: Databricks for Pi

The catalog lists every gateway route a ready, tool-capable endpoint serves, and the shared plugin gives agent plugins the helper command that prints a current access token. Pi’s provider list leads with **Databricks in Buzz**; its sign-in is the shared connection, not a key in Pi’s `auth.json`.

Buzz does not load Pi packages, so Pi’s host registers the provider itself instead of loading the Databricks extension. The Pi plugin chooses each model’s route the way the extension does: Anthropic Messages for Claude, OpenAI Responses for other families, and neither for Gemini or models with only a Chat route. The host asks the plugin for that binding when it first needs the provider and again when listing its models, then registers it with pi-ai. Context windows, output limits, and thinking levels come from Pi’s built-in model with the same name, and the extension’s gateway compatibility settings apply. Each request runs the token helper, reusing its answer for 30 seconds. Request formatting, streaming, and history stay in Pi.

Try it by enabling Databricks and Pi, signing in under **Settings → Providers → Databricks** or from the Pi provider dialog, then choosing **Databricks in Buzz** and a Claude and a GPT model in two Pi agents. Verify tool-bearing turns on both routes, a goose and a Pi agent on the same connection, and continued work after token refresh.
4 changes: 4 additions & 0 deletions scripts/design-system/check-icons.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ const nonIconDependencies = new Set([
"@buzz/author",
"@deepseek-ai/cordis",
"@dnd-kit/core", // Pointer drag and drop for sidebar channel moves.
"@earendil-works/chord", // The Pi host's packages, which pi.sh installs.
"@earendil-works/pi-ai",
"@earendil-works/pi-durable",
"@emoji-mart/data",
"@fontsource-variable/inter",
"@fontsource/jetbrains-mono",
Expand Down Expand Up @@ -53,6 +56,7 @@ const nonIconDependencies = new Set([
"motion",
"nostr-tools",
"postcss",
"proper-lockfile", // The Pi host's lock on each agent's storage.
"prosemirror-commands",
"prosemirror-history",
"prosemirror-model",
Expand Down
3 changes: 3 additions & 0 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ sha2 = "0.10"
hmac = "0.12"
base64 = "0.22"
reqwest = { version = "0.13", default-features = false, features = ["rustls", "stream"] }
hyper = { version = "1", features = ["server", "http1"] }
hyper-util = { version = "0.1", features = ["tokio"] }
http-body-util = "0.1"
bytes = "1"
url = "2"
percent-encoding = "2"
Expand Down
4 changes: 4 additions & 0 deletions src-tauri/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,13 @@ fn main() {
"plugin_host_process_spawn",
"plugin_host_process_write",
"plugin_host_process_kill",
"plugin_host_mcp_serve",
"plugin_host_mcp_reply",
"plugin_host_mcp_close",
"oauth_callback_begin",
"oauth_callback_wait",
"oauth_callback_cancel",
"databricks_provider",
"app_agent_list",
"app_agent_create",
"app_agent_portable",
Expand Down
4 changes: 4 additions & 0 deletions src-tauri/capabilities/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,13 @@
"allow-plugin-host-process-spawn",
"allow-plugin-host-process-write",
"allow-plugin-host-process-kill",
"allow-plugin-host-mcp-serve",
"allow-plugin-host-mcp-reply",
"allow-plugin-host-mcp-close",
"allow-oauth-callback-begin",
"allow-oauth-callback-wait",
"allow-oauth-callback-cancel",
"allow-databricks-provider",
"allow-app-agent-list",
"allow-app-agent-create",
"allow-app-agent-portable",
Expand Down
3 changes: 3 additions & 0 deletions src-tauri/src/browser_permissions_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ fn native_command_permissions_allow_only_main_webview() {
"plugin_host_process_spawn",
"plugin_host_process_write",
"plugin_host_process_kill",
"plugin_host_mcp_serve",
"plugin_host_mcp_reply",
"plugin_host_mcp_close",
"oauth_callback_begin",
"oauth_callback_wait",
"oauth_callback_cancel",
Expand Down
Loading