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
35 changes: 22 additions & 13 deletions scripts/functions-runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,20 @@ def normalize_project_selector(project: Any) -> tuple[str | None, str | None]:
return None, None


def project_selector_fields(project: Any) -> dict[str, str]:
project_id, project_name = normalize_project_selector(project)
if project_id:
return {"project_id": project_id}
if not project_name:
return {}
fields = {"project_name": project_name}
# braintrust.framework2.Project exposes `.project_group_name` on SDKs that support project groups.
project_group_name = getattr(project, "project_group_name", None)
if isinstance(project_group_name, str) and project_group_name.strip():
fields["project_group_name"] = project_group_name.strip()
return fields


def normalize_function_type(raw: Any) -> str | None:
if isinstance(raw, str):
value = raw.strip()
Expand Down Expand Up @@ -189,8 +203,6 @@ def collect_code_entries(functions_registry: Any) -> list[dict[str, Any]]:
if not isinstance(name, str) or not isinstance(slug, str) or not name or not slug:
continue

project_id, project_name = normalize_project_selector(getattr(item, "project", None))

entry: dict[str, Any] = {
"kind": "code",
"name": name,
Expand Down Expand Up @@ -232,10 +244,7 @@ def collect_code_entries(functions_registry: Any) -> list[dict[str, Any]]:
normalized_tags = [tag for tag in tags if isinstance(tag, str)]
if normalized_tags:
entry["tags"] = normalized_tags
if project_id:
entry["project_id"] = project_id
if project_name:
entry["project_name"] = project_name
entry.update(project_selector_fields(getattr(item, "project", None)))

preview = getattr(item, "preview", None)
if isinstance(preview, str):
Expand Down Expand Up @@ -275,13 +284,13 @@ async def collect_function_event_entries(prompts_registry: Any) -> list[dict[str
if isinstance(normalized, dict):
if normalized.get("if_exists") is None:
normalized.pop("if_exists", None)
project_id, project_name = normalize_project_selector(getattr(item, "project", None))
event_entry: dict[str, Any] = {"kind": "function_event", "event": normalized}
if project_id:
event_entry["project_id"] = project_id
if project_name:
event_entry["project_name"] = project_name
entries.append(event_entry)
entries.append(
{
"kind": "function_event",
"event": normalized,
**project_selector_fields(getattr(item, "project", None)),
}
)

return entries

Expand Down
5 changes: 5 additions & 0 deletions scripts/functions-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ type CodeEntry = {
kind: "code";
project_id?: string;
project_name?: string;
project_group_name?: string;
name: string;
slug: string;
description?: string;
Expand All @@ -72,6 +73,7 @@ type FunctionEventEntry = {
kind: "function_event";
project_id?: string;
project_name?: string;
project_group_name?: string;
event: JsonValue;
};

Expand Down Expand Up @@ -374,6 +376,7 @@ async function collectFunctionEvents(
kind: "function_event",
project_id: projectId,
project_name: projectName,
project_group_name: selector.project_group_name,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve groups for nested project references

When a prompt or function event references a different missing project—for example, a legacy tool whose project came from projects.create({ name, projectGroupName })—resolver.resolve() serializes that nested reference only as project_id: "name:...", while this field carries the group only for the event's owning project. Rust discovers the nested name via collect_project_name_placeholders_checked, but finds no corresponding group and calls create_project with None, so users who can create projects only within that group still cannot push this valid definition. Carry group metadata for every project passed through the resolver, rather than only for the top-level entry.

Useful? React with 👍 / 👎.

event: normalizedEvent,
});
}
Expand Down Expand Up @@ -439,6 +442,7 @@ async function collectLegacyPromptEvent(
kind: "function_event",
project_id: projectId,
project_name: projectName,
project_group_name: selector.project_group_name,
event,
};
}
Expand Down Expand Up @@ -526,6 +530,7 @@ function collectCodeEntries(items: CodeRegistryItem[]): CodeEntry[] {
typeof selector.project_name === "string"
? selector.project_name
: undefined,
project_group_name: selector.project_group_name,
name: item.name,
slug: item.slug,
description:
Expand Down
10 changes: 9 additions & 1 deletion scripts/runner-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ export type JsonValue = JsonPrimitive | JsonArray | JsonObject;
export type ProjectSelector = {
project_id?: string;
project_name?: string;
project_group_name?: string;
};

export type ProjectRef = {
id?: string;
name?: string;
projectGroupName?: string;
};

export function asProjectSelector(
Expand All @@ -25,7 +27,13 @@ export function asProjectSelector(
}

if (typeof project.name === "string" && project.name.trim().length > 0) {
return { project_name: project.name };
return typeof project.projectGroupName === "string" &&
project.projectGroupName.trim().length > 0
? {
project_name: project.name,
project_group_name: project.projectGroupName,
}
: { project_name: project.name };
}

return {};
Expand Down
2 changes: 1 addition & 1 deletion src/datasets/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1808,7 +1808,7 @@ async fn resolve_target_project(
if let Some(project) = get_project_by_name(client, project_name).await? {
Ok(project)
} else {
create_project(client, project_name)
create_project(client, project_name, None)
.await
.with_context(|| format!("project '{project_name}' not found, and creating it failed"))
}
Expand Down
Loading
Loading