Skip to content
Open
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: 4 additions & 2 deletions api/oss/tests/pytest/unit/services/test_db_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ def _patch_core_session(monkeypatch, memberships):


@pytest.mark.asyncio
async def test_get_default_workspace_id_prefers_owner_membership(monkeypatch):
async def test_get_default_workspace_id_ignores_owner_role(monkeypatch):
# Owner-role is NOT preferred: under multi-org an invitee owns their own
# empty personal workspace, so the oldest membership wins regardless of role.
owner_workspace_id = uuid4()
editor_workspace_id = uuid4()

Expand All @@ -77,7 +79,7 @@ async def test_get_default_workspace_id_prefers_owner_membership(monkeypatch):

workspace_id = await db_manager.get_default_workspace_id(str(uuid4()))

assert workspace_id == str(owner_workspace_id)
assert workspace_id == str(editor_workspace_id)


@pytest.mark.asyncio
Expand Down
2 changes: 1 addition & 1 deletion api/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "api"
version = "0.104.0"
version = "0.104.1"
description = "Agenta API"
requires-python = ">=3.11,<3.14"
authors = [
Expand Down
6 changes: 3 additions & 3 deletions api/uv.lock

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

2 changes: 1 addition & 1 deletion clients/python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "agenta-client"
version = "0.104.0"
version = "0.104.1"
description = "Fern-generated Python client for the Agenta API."
requires-python = ">=3.11,<3.14"
authors = [
Expand Down
2 changes: 1 addition & 1 deletion clients/python/uv.lock

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

4 changes: 2 additions & 2 deletions hosting/kubernetes/helm/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ apiVersion: v2
name: agenta
description: A Helm chart for deploying Agenta (OSS or EE) on Kubernetes
type: application
version: 0.104.0
appVersion: "v0.104.0"
version: 0.104.1
appVersion: "v0.104.1"
keywords:
- agenta
- llm
Expand Down
5 changes: 4 additions & 1 deletion sdks/python/agenta/sdk/engines/running/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2220,7 +2220,10 @@ async def chat_v0(

message = response.choices[0].message # type: ignore

return message.model_dump(exclude_none=True) # type: ignore
# Normalize to the canonical Message shape (drops provider-specific fields).
return Message.model_validate(message.model_dump(exclude_none=True)).model_dump(
exclude_none=True
)


@instrument(ignore_inputs=["parameters"])
Expand Down
2 changes: 1 addition & 1 deletion sdks/python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "agenta"
version = "0.104.0"
version = "0.104.1"
description = "The SDK for agenta is an open-source LLMOps platform."
readme = "README.md"
requires-python = ">=3.11,<3.14"
Expand Down
4 changes: 2 additions & 2 deletions sdks/python/uv.lock

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

2 changes: 1 addition & 1 deletion services/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "services"
version = "0.104.0"
version = "0.104.1"
description = "Agenta Services (Chat & Completion)"
requires-python = ">=3.11,<3.14"
authors = [
Expand Down
6 changes: 3 additions & 3 deletions services/uv.lock

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

2 changes: 1 addition & 1 deletion web/ee/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@agenta/ee",
"version": "0.104.0",
"version": "0.104.1",
"private": true,
"engines": {
"node": "24.x"
Expand Down
2 changes: 1 addition & 1 deletion web/oss/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@agenta/oss",
"version": "0.104.0",
"version": "0.104.1",
"private": true,
"engines": {
"node": "24.x"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ interface TraceDrawerContentProps {
}

const SessionDrawerContent = ({onClose, onToggleWidth, isExpanded}: TraceDrawerContentProps) => {
const [selected, setSelected] = useState<string>("")
// Default-select the "Session" root node so the tree opens with a selection
// instead of nothing highlighted. The root node's key is always "root", and
// selecting it is a no-op in handleSelect (it early-returns for "root").
const [selected, setSelected] = useState<string>("root")
const {isLoading} = useSessionDrawer()
if (isLoading) {
return (
Expand Down
18 changes: 17 additions & 1 deletion web/oss/src/components/SidebarBanners/state/atoms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ export const PRIORITY_ORDER: Record<BannerType, number> = {
trial: 3, // Lowest priority - show after other banners are dismissed
}

/**
* Maximum number of dismissible sidebar banners a user should have to clear.
* Apply this before dismissal filtering so older changelog entries do not
* backfill the sidebar after each close.
*/
export const MAX_DISMISSIBLE_SIDEBAR_BANNERS = 2

/**
* Persisted atom for dismissed banner IDs.
* Uses localStorage to remember which banners the user has dismissed.
Expand Down Expand Up @@ -107,8 +114,17 @@ export const activeBannersAtom = atom((get) => {
export const visibleBannersAtom = atom((get) => {
const allBanners = get(activeBannersAtom)
const dismissedIds = get(dismissedBannerIdsAtom)
const sortedBanners = [...allBanners].sort(
(a, b) => PRIORITY_ORDER[a.type] - PRIORITY_ORDER[b.type],
)

const cappedDismissibleBanners = sortedBanners
.filter((banner) => banner.dismissible)
.slice(0, MAX_DISMISSIBLE_SIDEBAR_BANNERS)

const nonDismissibleBanners = sortedBanners.filter((banner) => !banner.dismissible)

return allBanners
return [...cappedDismissibleBanners, ...nonDismissibleBanners]
.filter((banner) => !dismissedIds.includes(banner.id))
.sort((a, b) => PRIORITY_ORDER[a.type] - PRIORITY_ORDER[b.type])
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import {Tag} from "antd"
export const SessionIdCell = ({sessionId}: {sessionId: string}) => {
return (
<TooltipWithCopyAction copyText={sessionId || ""} title="Copy session id">
<Tag className="font-mono bg-[var(--ag-c-0517290F)] w-fit truncate" bordered={false}>
<Tag
className="font-mono bg-[var(--ag-c-0517290F)] max-w-full truncate inline-block align-middle"
bordered={false}
>
# {sessionId}
</Tag>
</TooltipWithCopyAction>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {useCallback, useEffect, useMemo, useState} from "react"

import {InfiniteVirtualTableFeatureShell} from "@agenta/ui/table"
import type {TableFeaturePagination, TableScopeConfig} from "@agenta/ui/table"
import {useAtomValue, useSetAtom} from "jotai"
import {useAtomValue, useSetAtom, useStore} from "jotai"
import dynamic from "next/dynamic"

import {SessionDrawer} from "@/oss/components/SharedDrawers/SessionDrawer"
Expand Down Expand Up @@ -49,6 +49,14 @@ const SessionsTable: React.FC = () => {
resetSessionPages,
} = useSessions()

// The per-session cells (Traces count, First input, metrics, …) read their
// data from page-level atoms keyed by session id (e.g. `sessionsSpansAtom`).
// Without this, the table mounts its rows inside an isolated Jotai store
// (`useIsolatedStore` when no `store` is passed), where those atoms are empty
// — so every cell renders 0/"-" even though the data is loaded in the page
// store. Sharing the page store lets the cells resolve the real data.
const store = useStore()

const isNewUser = useAtomValue(isNewUserAtom)
const onboardingStorageUserId = useAtomValue(onboardingStorageUserIdAtom)
const openDrawer = useSetAtom(openSessionDrawerWithUrlAtom)
Expand Down Expand Up @@ -111,7 +119,7 @@ const SessionsTable: React.FC = () => {
const isEmptyState = sessionIds.length === 0 && !isLoading

return (
<div className="flex flex-col gap-6">
<div className="flex flex-col h-full gap-2 min-h-0">
<ObservabilityHeader
columns={columns}
componentType="sessions"
Expand All @@ -128,11 +136,11 @@ const SessionsTable: React.FC = () => {
<EmptySessions showOnboarding={showOnboarding} />
) : (
<InfiniteVirtualTableFeatureShell<SessionRow>
store={store}
tableScope={tableScope}
columns={columns}
rowKey="session_id"
pagination={pagination}
autoHeight={false}
resizableColumns
enableExport={false}
useSettingsDropdown={false}
Expand Down
13 changes: 8 additions & 5 deletions web/oss/src/state/newObservability/atoms/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -509,15 +509,18 @@ export const sessionTraceCountAtomFamily = atomFamily((sessionId: string) =>
}),
)

// Sorted traces are required for time-based metrics (Start/End/Duration)
// We memoize this to avoid re-sorting for every time-related cell
// Sorted traces are required for time-based metrics (Start/End/Duration) and for
// the First input / Last output cells. Sort by `start_time` (falling back to
// `created_at`) to match the Session drawer's tree ordering
// (SessionTree sorts its "Trace N" nodes by start_time). Sorting by a different
// key here made the table's first/last trace diverge from the drawer's.
const sessionSortedTracesAtomFamily = atomFamily((sessionId: string) =>
atom((get) => {
const traces = get(sessionTracesAtomFamily(sessionId))
if (!traces.length) return []
return [...traces].sort(
(a, b) => new Date(a.created_at || 0).getTime() - new Date(b.created_at || 0).getTime(),
)
const sortKey = (t: (typeof traces)[number]) =>
new Date(t.start_time || t.created_at || 0).getTime()
return [...traces].sort((a, b) => sortKey(a) - sortKey(b))
}),
)

Expand Down
2 changes: 1 addition & 1 deletion web/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "agenta-web",
"version": "0.104.0",
"version": "0.104.1",
"workspaces": [
"ee",
"oss",
Expand Down
2 changes: 1 addition & 1 deletion web/packages/agenta-api-client/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@agentaai/api-client",
"version": "0.104.0",
"version": "0.104.1",
"private": true,
"type": "module",
"main": "./dist/index.js",
Expand Down
Loading