Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 3 additions & 3 deletions desktop/src-tauri/src/commands/personas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,11 +371,11 @@ mod tests {
use super::*;

#[test]
fn parse_persona_files_accepts_plain_md_with_avatar_ref() {
fn parse_persona_files_carries_opaque_avatar_ref() {
let md = br#"---
name: fizz
display_name: Fizz
avatar: app-avatar:persona-12
avatar: https://example.com/avatars/fizz.png
runtime: goose
---
You are Fizz.
Expand All @@ -388,7 +388,7 @@ You are Fizz.
assert_eq!(result.personas[0].display_name, "Fizz");
assert_eq!(
result.personas[0].avatar_ref.as_deref(),
Some("app-avatar:persona-12")
Some("https://example.com/avatars/fizz.png")
);
assert_eq!(result.personas[0].source_file, "fizz.md");
}
Expand Down
20 changes: 13 additions & 7 deletions desktop/src-tauri/src/managed_agents/persona_card_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,12 +404,12 @@ fn parse_json_malformed() {
}

#[test]
fn parse_md_persona_preserves_app_avatar_ref() {
fn parse_md_persona_preserves_avatar_ref() {
let md = br#"---
name: goosey
display_name: Goosey
description: Goose internal agent.
avatar: app-avatar:persona-19
avatar: https://example.com/avatars/goosey.png
model: anthropic:claude-sonnet-4
runtime: goose
---
Expand All @@ -418,7 +418,10 @@ You are Goosey.
let result = parse_md_persona(md).unwrap();
assert_eq!(result.display_name, "Goosey");
assert_eq!(result.avatar_data_url, None);
assert_eq!(result.avatar_ref.as_deref(), Some("app-avatar:persona-19"));
assert_eq!(
result.avatar_ref.as_deref(),
Some("https://example.com/avatars/goosey.png")
);
assert_eq!(result.model.as_deref(), Some("claude-sonnet-4"));
assert_eq!(result.provider.as_deref(), Some("anthropic"));
assert_eq!(result.runtime.as_deref(), Some("goose"));
Expand Down Expand Up @@ -446,15 +449,18 @@ fn parse_md_persona_accepts_goose_internal_frontmatter() {
let md = br#"---
name: block.md
description: Opinionated guide to Block's intelligence operating model.
avatar: app-avatar:persona-19
avatar: https://avatars.example.com/block-md.png
metadata:
gooseInternalBundled: true
---
You are block.md.
"#;
let result = parse_md_persona(md).unwrap();
assert_eq!(result.display_name, "block.md");
assert_eq!(result.avatar_ref.as_deref(), Some("app-avatar:persona-19"));
assert_eq!(
result.avatar_ref.as_deref(),
Some("https://avatars.example.com/block-md.png")
);
assert_eq!(result.system_prompt, "You are block.md.\n");
}

Expand Down Expand Up @@ -495,7 +501,7 @@ fn parse_zip_with_plain_md_persona_preserves_avatar_ref() {
name: fizz
display_name: Fizz
description: Engineering agent.
avatar: app-avatar:persona-12
avatar: https://avatars.example.com/fizz.png
runtime: goose
model: anthropic:claude-sonnet-4
---
Expand All @@ -508,7 +514,7 @@ You are Fizz.
assert_eq!(result.personas[0].display_name, "Fizz");
assert_eq!(
result.personas[0].avatar_ref.as_deref(),
Some("app-avatar:persona-12")
Some("https://avatars.example.com/fizz.png")
);
assert_eq!(result.personas[0].source_file, "fizz.md");
}
Expand Down
27 changes: 26 additions & 1 deletion desktop/src/features/agents/ui/personaDialogState.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,36 @@
import type { ParsePersonaFilesResult } from "@/shared/api/tauriPersonas";
import { resolveImportedPersonaAvatarUrl } from "@/shared/avatars/gooseAppAvatarRefs";
import type {
AgentPersona,
CreatePersonaInput,
UpdatePersonaInput,
} from "@/shared/api/types";

function isPersistableAvatarUrl(value: string): boolean {
return /^(?:https?:|data:image\/|blob:)/i.test(value);
}

/**
* Picks an avatar URL to seed the import dialog with. Only persistable
* http(s)/data/blob URLs survive; anything else (e.g. a bare filename or an
* unrenderable symbolic ref) is dropped so the dialog starts blank rather than
* carrying a value the app can't display.
*/
function resolveImportedPersonaAvatarUrl({
avatarDataUrl,
avatarRef,
}: {
avatarDataUrl?: string | null;
avatarRef?: string | null;
}): string | null {
for (const candidate of [avatarRef, avatarDataUrl]) {
const trimmed = candidate?.trim();
if (trimmed && isPersistableAvatarUrl(trimmed)) {
return trimmed;
}
}
return null;
}

export type PersonaDialogState = {
description: string;
initialValues: CreatePersonaInput | UpdatePersonaInput;
Expand Down
5 changes: 1 addition & 4 deletions desktop/src/features/profile/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import type {
UsersBatchResponse,
} from "@/shared/api/types";
import { useIdentityQuery } from "@/shared/api/hooks";
import { isGooseAppAvatarRef } from "@/shared/avatars/gooseAppAvatarRefs";
import { getAvatarSnapshotUrl } from "@/shared/lib/animatedAvatar";
import { rewriteRelayUrl } from "@/shared/lib/mediaUrl";
import {
Expand Down Expand Up @@ -56,9 +55,7 @@ async function persistSelfProfile(
profile: Profile,
): Promise<void> {
const existing = readSelfProfileCache(relayUrl, pubkey);
const avatarSnapshotUrl = isGooseAppAvatarRef(profile.avatarUrl)
? null
: getAvatarSnapshotUrl(profile.avatarUrl);
const avatarSnapshotUrl = getAvatarSnapshotUrl(profile.avatarUrl);
const fetched =
shouldFetchAvatar(profile.avatarUrl, existing) && avatarSnapshotUrl !== null
? await fetchAvatarDataUrl(rewriteRelayUrl(avatarSnapshotUrl))
Expand Down
58 changes: 0 additions & 58 deletions desktop/src/shared/avatars/gooseAppAvatarRefs.test.mjs

This file was deleted.

69 changes: 0 additions & 69 deletions desktop/src/shared/avatars/gooseAppAvatarRefs.ts

This file was deleted.

Loading