From 9f1f399c1e99fe14ce56e3891fc3c6dd8cebe1de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?batuhan=20i=C3=A7=C3=B6z?= Date: Sat, 31 Jan 2026 21:40:04 +0100 Subject: [PATCH 1/4] Add AI bridge config and update websocket bridges Introduces ai.tpl.yaml for AI bridge network configuration and adds 'beeper-ai' to the list of websocket bridges in bridgeutil.go. --- bridgeconfig/ai.tpl.yaml | 32 ++++++++++++++++++++++++++++++++ cmd/bbctl/bridgeutil.go | 1 + 2 files changed, 33 insertions(+) create mode 100644 bridgeconfig/ai.tpl.yaml diff --git a/bridgeconfig/ai.tpl.yaml b/bridgeconfig/ai.tpl.yaml new file mode 100644 index 0000000..9812a0c --- /dev/null +++ b/bridgeconfig/ai.tpl.yaml @@ -0,0 +1,32 @@ +# AI Bridge network configuration +network: + # Per-provider default models + providers: + openai: + default_model: "gpt-5-nano" + gemini: + default_model: "gemini-2.0-flash" + anthropic: + default_model: "claude-sonnet-4-5-20250929" + openrouter: + default_model: "openai/gpt-4o-mini" + + # Global settings + default_system_prompt: | + You are a helpful AI assistant. + model_cache_duration: 6h + + bridge: + command_prefix: "!ai" + + beeper: + base_url: {{ .HungryAddress }} + token: {{ .ProvisioningSecret }} + +{{ setfield . "CommandPrefix" "!ai" -}} +{{ setfield . "DatabaseFileName" "ai" -}} +{{ setfield . "BridgeName" "ai" -}} +{{ setfield . "BridgeTypeName" "AI" -}} +{{ setfield . "BridgeTypeIcon" "mxc://maunium.net/HPiAFz2uVH54camzatoorkWY" -}} +{{ setfield . "DefaultPickleKey" "go.beeper.ai" -}} +{{ template "bridgev2.tpl.yaml" . }} diff --git a/cmd/bbctl/bridgeutil.go b/cmd/bbctl/bridgeutil.go index 4a7eaf8..548c6cd 100644 --- a/cmd/bbctl/bridgeutil.go +++ b/cmd/bbctl/bridgeutil.go @@ -49,6 +49,7 @@ var websocketBridges = map[string]bool{ "imessagego": true, "signal": true, "bridgev2": true, + "beeper-ai": true, "meta": true, "twitter": true, "bluesky": true, From 43736fc7a8997fa96689567f8b4ea4fae6ca649c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?batuhan=20i=C3=A7=C3=B6z?= Date: Sat, 31 Jan 2026 22:21:08 +0100 Subject: [PATCH 2/4] Add support for AI bridge in bbctl and config This commit introduces support for the 'ai' bridge across build, configuration, and utility files. It updates bridge lists, repository URLs, and configuration templates to properly recognize and handle the AI bridge. --- api/gitlab/build.go | 3 ++- bridgeconfig/ai.tpl.yaml | 23 +++++++++-------------- cmd/bbctl/bridgeutil.go | 3 ++- cmd/bbctl/run.go | 6 +++++- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/api/gitlab/build.go b/api/gitlab/build.go index 5eb51a8..6b68549 100644 --- a/api/gitlab/build.go +++ b/api/gitlab/build.go @@ -70,7 +70,8 @@ func getRefFromBridge(bridge string) (string, error) { case "imessage": return "master", nil case "whatsapp", "discord", "slack", "gmessages", "gvoice", "signal", - "imessagego", "meta", "twitter", "bluesky", "linkedin", "telegramgo": + "imessagego", "meta", "twitter", "bluesky", "linkedin", "telegramgo", + "ai": return "main", nil default: return "", fmt.Errorf("unknown bridge %s", bridge) diff --git a/bridgeconfig/ai.tpl.yaml b/bridgeconfig/ai.tpl.yaml index 9812a0c..2dcc6c1 100644 --- a/bridgeconfig/ai.tpl.yaml +++ b/bridgeconfig/ai.tpl.yaml @@ -1,28 +1,23 @@ -# AI Bridge network configuration network: - # Per-provider default models + beeper: + base_url: {{ .HungryAddress }} + token: {{ .ProvisioningSecret }} + providers: + beeper: + default_model: "openai/gpt-5.2" openai: - default_model: "gpt-5-nano" - gemini: - default_model: "gemini-2.0-flash" - anthropic: - default_model: "claude-sonnet-4-5-20250929" - openrouter: default_model: "openai/gpt-4o-mini" + openrouter: + default_model: "openrouter/openai/gpt-4o-mini" - # Global settings default_system_prompt: | - You are a helpful AI assistant. + You are a helpful assistant. model_cache_duration: 6h bridge: command_prefix: "!ai" - beeper: - base_url: {{ .HungryAddress }} - token: {{ .ProvisioningSecret }} - {{ setfield . "CommandPrefix" "!ai" -}} {{ setfield . "DatabaseFileName" "ai" -}} {{ setfield . "BridgeName" "ai" -}} diff --git a/cmd/bbctl/bridgeutil.go b/cmd/bbctl/bridgeutil.go index 548c6cd..1e34981 100644 --- a/cmd/bbctl/bridgeutil.go +++ b/cmd/bbctl/bridgeutil.go @@ -21,6 +21,7 @@ type bridgeTypeToNames struct { } var officialBridges = []bridgeTypeToNames{ + {"ai", []string{"ai"}}, {"discord", []string{"discord"}}, {"meta", []string{"meta", "instagram", "facebook"}}, {"googlechat", []string{"googlechat", "gchat"}}, @@ -49,7 +50,7 @@ var websocketBridges = map[string]bool{ "imessagego": true, "signal": true, "bridgev2": true, - "beeper-ai": true, + "ai": true, "meta": true, "twitter": true, "bluesky": true, diff --git a/cmd/bbctl/run.go b/cmd/bbctl/run.go index 408c28f..8c26d31 100644 --- a/cmd/bbctl/run.go +++ b/cmd/bbctl/run.go @@ -134,6 +134,8 @@ func compileGoBridge(ctx context.Context, buildDir, binaryPath, bridgeType strin repo := fmt.Sprintf("https://github.com/mautrix/%s.git", bridgeType) if bridgeType == "imessagego" { repo = "https://github.com/beeper/imessage.git" + } else if bridgeType == "ai" { + repo = "https://github.com/beeper/ai-bridge.git" } log.Printf("Cloning [cyan]%s[reset] to [cyan]%s[reset]", repo, buildDir) err = makeCmd(ctx, buildDirParent, "git", "clone", repo, buildDir).Run() @@ -309,7 +311,7 @@ func runBridge(ctx *cli.Context) error { var needsWebsocketProxy bool switch cfg.BridgeType { case "imessage", "imessagego", "whatsapp", "discord", "slack", "gmessages", "gvoice", - "signal", "meta", "twitter", "bluesky", "linkedin", "telegram": + "signal", "meta", "twitter", "bluesky", "linkedin", "telegram", "ai": ciBridgeType := cfg.BridgeType binaryName := fmt.Sprintf("mautrix-%s", cfg.BridgeType) ciV2 := false @@ -319,6 +321,8 @@ func runBridge(ctx *cli.Context) error { ciBridgeType = "telegramgo" case "imessagego": binaryName = "beeper-imessage" + case "ai": + binaryName = "ai" } bridgeCmd = filepath.Join(dataDir, "binaries", binaryName) if localDev && overrideBridgeCmd == "" { From aae520bcc996c95b9e9669fc34f768edd6465fd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?batuhan=20i=C3=A7=C3=B6z?= Date: Sat, 31 Jan 2026 22:23:08 +0100 Subject: [PATCH 3/4] Refactor AI bridge handling in bbctl run Moved 'ai' bridge type to its own case in runBridge, with specific logic for binary selection and compilation. Removed 'ai' from shared bridge lists in both build.go and run.go to improve maintainability and clarity. --- api/gitlab/build.go | 3 +-- cmd/bbctl/run.go | 27 ++++++++++++++++++++++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/api/gitlab/build.go b/api/gitlab/build.go index 6b68549..5eb51a8 100644 --- a/api/gitlab/build.go +++ b/api/gitlab/build.go @@ -70,8 +70,7 @@ func getRefFromBridge(bridge string) (string, error) { case "imessage": return "master", nil case "whatsapp", "discord", "slack", "gmessages", "gvoice", "signal", - "imessagego", "meta", "twitter", "bluesky", "linkedin", "telegramgo", - "ai": + "imessagego", "meta", "twitter", "bluesky", "linkedin", "telegramgo": return "main", nil default: return "", fmt.Errorf("unknown bridge %s", bridge) diff --git a/cmd/bbctl/run.go b/cmd/bbctl/run.go index 8c26d31..2f93094 100644 --- a/cmd/bbctl/run.go +++ b/cmd/bbctl/run.go @@ -311,7 +311,7 @@ func runBridge(ctx *cli.Context) error { var needsWebsocketProxy bool switch cfg.BridgeType { case "imessage", "imessagego", "whatsapp", "discord", "slack", "gmessages", "gvoice", - "signal", "meta", "twitter", "bluesky", "linkedin", "telegram", "ai": + "signal", "meta", "twitter", "bluesky", "linkedin", "telegram": ciBridgeType := cfg.BridgeType binaryName := fmt.Sprintf("mautrix-%s", cfg.BridgeType) ciV2 := false @@ -321,8 +321,6 @@ func runBridge(ctx *cli.Context) error { ciBridgeType = "telegramgo" case "imessagego": binaryName = "beeper-imessage" - case "ai": - binaryName = "ai" } bridgeCmd = filepath.Join(dataDir, "binaries", binaryName) if localDev && overrideBridgeCmd == "" { @@ -371,6 +369,29 @@ func runBridge(ctx *cli.Context) error { } heisenHomeserverURL := strings.Replace(cfg.HomeserverURL, "https://", "wss://", 1) bridgeArgs = []string{"-m", "heisenbridge", "-c", configFileName, "-o", cfg.YourUserID.String(), heisenHomeserverURL} + case "ai": + if !localDev && !compile && overrideBridgeCmd == "" { + return UserError{"AI bridge binaries are not available in CI. Use --local-dev or --compile mode."} + } + binaryName := "ai" + bridgeCmd = filepath.Join(dataDir, "binaries", binaryName) + if localDev && overrideBridgeCmd == "" { + bridgeCmd = filepath.Join(bridgeDir, binaryName) + buildScript := "./build.sh" + log.Printf("Compiling [cyan]%s[reset] with %s", binaryName, buildScript) + err = makeCmd(ctx.Context, bridgeDir, buildScript).Run() + if err != nil { + return fmt.Errorf("failed to compile bridge: %w", err) + } + } else if compile && overrideBridgeCmd == "" { + buildDir := filepath.Join(dataDir, "compile", binaryName) + bridgeCmd = filepath.Join(buildDir, binaryName) + err = compileGoBridge(ctx.Context, buildDir, bridgeCmd, "ai", ctx.Bool("no-update")) + if err != nil { + return fmt.Errorf("failed to compile bridge: %w", err) + } + } + bridgeArgs = []string{"-c", configFileName} default: if overrideBridgeCmd == "" { return UserError{"Unsupported bridge type for bbctl run"} From f7d2bc5b98f122670da37978f3b5c47cbc7e7356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?batuhan=20i=C3=A7=C3=B6z?= Date: Sat, 31 Jan 2026 22:30:50 +0100 Subject: [PATCH 4/4] Update ai.tpl.yaml --- bridgeconfig/ai.tpl.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/bridgeconfig/ai.tpl.yaml b/bridgeconfig/ai.tpl.yaml index 2dcc6c1..002c62d 100644 --- a/bridgeconfig/ai.tpl.yaml +++ b/bridgeconfig/ai.tpl.yaml @@ -20,7 +20,6 @@ network: {{ setfield . "CommandPrefix" "!ai" -}} {{ setfield . "DatabaseFileName" "ai" -}} -{{ setfield . "BridgeName" "ai" -}} {{ setfield . "BridgeTypeName" "AI" -}} {{ setfield . "BridgeTypeIcon" "mxc://maunium.net/HPiAFz2uVH54camzatoorkWY" -}} {{ setfield . "DefaultPickleKey" "go.beeper.ai" -}}