diff --git a/internal/web/uploads.go b/internal/web/uploads.go
index 836b493..921a42f 100644
--- a/internal/web/uploads.go
+++ b/internal/web/uploads.go
@@ -275,20 +275,24 @@ func titleFromFilename(name string) string {
// definition the start-up validation uses, not a second string match here (#52).
//
// The endpoint is one alias, except for the two-engine path (ADR-034), which writes
-// " + , reconciled by ". Every word of it that is not that format's own
-// connector is judged as an alias, so a composite of local models is local, and anything
-// else (a cloud alias, one with no provider prefix, one with a space in it) is not.
+// " + , reconciled by " (ensemble.go). That shape is taken apart exactly
+// and each alias is judged whole, so a composite of local models is local, and anything
+// else (a cloud alias, one with no provider prefix, one with a space or a connector word in
+// it) is not. A string that is not that shape is one alias.
func cloudProvider(endpoint string) (string, bool) {
- for _, tok := range strings.Fields(endpoint) {
- tok = strings.Trim(tok, ",")
- switch tok {
- case "", "+", "reconciled", "by":
- continue
- }
- if !config.IsLocalModel(tok) {
- provider, _, _ := strings.Cut(tok, "/")
- if provider == "" {
- provider = tok
+ endpoint = strings.TrimSpace(endpoint)
+ if endpoint == "" {
+ return "", false
+ }
+ aliases := []string{endpoint}
+ if engines, reconciler, ok := strings.Cut(endpoint, ", reconciled by "); ok {
+ aliases = append(strings.Split(engines, " + "), reconciler)
+ }
+ for _, a := range aliases {
+ if a = strings.TrimSpace(a); !config.IsLocalModel(a) {
+ provider, _, _ := strings.Cut(a, "/")
+ if provider = strings.TrimSpace(provider); provider == "" {
+ provider = a
}
return provider, true
}
diff --git a/internal/web/uploads_cloud_note_test.go b/internal/web/uploads_cloud_note_test.go
index f703e76..82fcd42 100644
--- a/internal/web/uploads_cloud_note_test.go
+++ b/internal/web/uploads_cloud_note_test.go
@@ -103,3 +103,38 @@ func TestUploadStatus_AReconciledEndpointWithAnUnprefixedAliasIsNotCalledLocal(t
})
}
}
+
+// "by", "reconciled" and "+" are connectors only inside the composite format. As a whole
+// endpoint, or as an alias within the composite, they are model names and are judged.
+func TestUploadStatus_AConnectorWordUsedAsAModelNameIsStillJudged(t *testing.T) {
+ for _, endpoint := range []string{
+ "by",
+ "reconciled",
+ "+",
+ "iguana/kb-whisper + by, reconciled by iguana/gemma4-26b",
+ "iguana/kb-whisper + reconciled, reconciled by iguana/gemma4-26b",
+ "iguana/kb-whisper + +, reconciled by iguana/gemma4-26b",
+ "/x", // no provider at all: the note must still name something
+ } {
+ t.Run(endpoint, func(t *testing.T) {
+ app, _ := newUploadApp(t, audioOK, 200<<20)
+ id := seedUpload(t, userID, "m", "done", "Synthetic transcript text.")
+ setEndpoint(t, id, endpoint)
+
+ b := body(t, do(t, app, get("/uploads/"+id+"/status")))
+
+ assert.Contains(t, b, "left the homelab")
+ assert.NotContains(t, b, "cloud service ()")
+ })
+ }
+}
+
+func TestUploadStatus_AReconcilerThatIsNotLocalNamesTheCloudProvider(t *testing.T) {
+ app, _ := newUploadApp(t, audioOK, 200<<20)
+ id := seedUpload(t, userID, "m", "done", "Synthetic transcript text.")
+ setEndpoint(t, id, "iguana/kb-whisper + koala/whisper, reconciled by berget/mistral-large")
+
+ b := body(t, do(t, app, get("/uploads/"+id+"/status")))
+
+ assert.Contains(t, b, "cloud service (berget)")
+}