divi 0.0.1.dev19__tar.gz → 0.0.1.dev23__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/PKG-INFO +1 -1
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/graphql/package.json +1 -1
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/graphql/src/datasources/datapark-api.ts +18 -1
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/graphql/src/resolvers.ts +13 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/graphql/src/schema.graphql +22 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/graphql/src/types/types.d.ts +41 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/@modal/(.)traces/[id]/page.tsx +1 -1
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/api-keys/actions.ts +3 -2
- divi-0.0.1.dev23/apps/web/app/dashboard/api-keys/layout.tsx +29 -0
- {divi-0.0.1.dev19/apps/web → divi-0.0.1.dev23/apps/web/app/dashboard}/components/app-sidebar.tsx +9 -10
- {divi-0.0.1.dev19/apps/web → divi-0.0.1.dev23/apps/web/app/dashboard}/components/nav-secondary.tsx +1 -2
- {divi-0.0.1.dev19/apps/web → divi-0.0.1.dev23/apps/web/app/dashboard}/components/nav-user.tsx +0 -1
- {divi-0.0.1.dev19/apps/web → divi-0.0.1.dev23/apps/web/app/dashboard}/components/site-header.tsx +1 -1
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/layout.tsx +5 -6
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/settings/account/page.tsx +1 -1
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/settings/appearance/page.tsx +1 -1
- {divi-0.0.1.dev19/apps/web → divi-0.0.1.dev23/apps/web/app/dashboard/settings}/components/sidebar-nav.tsx +0 -1
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/settings/layout.tsx +1 -2
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/settings/page.tsx +1 -1
- divi-0.0.1.dev23/apps/web/app/dashboard/traces/(children)/[id]/components/Span.tsx +161 -0
- {divi-0.0.1.dev19/apps/web → divi-0.0.1.dev23/apps/web/app/dashboard/traces/(children)/[id]}/components/responsive-resizable.tsx +9 -2
- {divi-0.0.1.dev19/apps/web → divi-0.0.1.dev23/apps/web/app/dashboard/traces/(children)/[id]}/components/trace-board.tsx +2 -5
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/traces/(children)/[id]/page.tsx +1 -1
- divi-0.0.1.dev23/apps/web/app/dashboard/traces/(overview)/layout.tsx +26 -0
- divi-0.0.1.dev23/apps/web/app/dashboard/usages/actions.ts +73 -0
- divi-0.0.1.dev23/apps/web/app/dashboard/usages/components/usage-board.tsx +74 -0
- divi-0.0.1.dev23/apps/web/app/dashboard/usages/components/usage-chart.tsx +205 -0
- divi-0.0.1.dev23/apps/web/app/dashboard/usages/layout.tsx +26 -0
- divi-0.0.1.dev23/apps/web/app/dashboard/usages/page.tsx +29 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/home/components/home-header.tsx +2 -2
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/login/page.tsx +2 -2
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/signup/page.tsx +1 -1
- divi-0.0.1.dev23/apps/web/components/Highter.tsx +19 -0
- divi-0.0.1.dev23/apps/web/components/calendar.tsx +84 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/components/data-table-view-options.tsx +2 -1
- divi-0.0.1.dev23/apps/web/components/date-picker.tsx +101 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/lib/server/openai.ts +1 -1
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/lib/types/span.d.ts +1 -1
- divi-0.0.1.dev23/apps/web/lib/types/usage.d.ts +9 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/middleware.ts +1 -1
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/package.json +9 -5
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/__init__.py +1 -1
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/decorators/obs_openai.py +0 -1
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/decorators/observable.py +11 -32
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/services/datapark/datapark.py +19 -7
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/session/session.py +3 -3
- divi-0.0.1.dev23/divi/session/setup.py +45 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/signals/trace/trace.py +18 -18
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/go.work.sum +1 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/package.json +2 -2
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/pnpm-lock.yaml +715 -581
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/pnpm-workspace.yaml +2 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/go.mod +5 -5
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/go.sum +10 -10
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/internal/app/datapark/handler/metric.go +3 -1
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/internal/app/datapark/handler/openai.go +48 -2
- divi-0.0.1.dev23/services/internal/app/datapark/handler/usage.go +127 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/internal/app/datapark/router/router.go +4 -0
- divi-0.0.1.dev23/services/internal/pkg/model/usage.go +46 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/uv.lock +0 -2
- divi-0.0.1.dev19/apps/web/app/dashboard/api-keys/layout.tsx +0 -26
- divi-0.0.1.dev19/apps/web/app/dashboard/page.tsx +0 -15
- divi-0.0.1.dev19/apps/web/app/dashboard/traces/(overview)/layout.tsx +0 -23
- divi-0.0.1.dev19/apps/web/app/dashboard/usages/page.tsx +0 -15
- divi-0.0.1.dev19/apps/web/components/chart-area-interactive.tsx +0 -292
- divi-0.0.1.dev19/apps/web/components/section-cards.tsx +0 -102
- divi-0.0.1.dev19/divi/session/setup.py +0 -62
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/.air.toml +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/.dockerignore +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/.github/dependabot.yml +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/.gitignore +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/LICENSE +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/README.md +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/README.md +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/docs/README.md +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/docs/concepts/session.mdx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/docs/development/roadmap.mdx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/docs/docs.json +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/docs/favicon.ico +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/docs/images/researcher-angel.png +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/docs/images/scholar-angel.png +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/docs/introduction.mdx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/docs/package.json +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/docs/quickstart/trace.mdx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/docs/snippets/snippet-intro.mdx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/docs/tutorials/openai.mdx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/graphql/Dockerfile +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/graphql/README.md +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/graphql/codegen.ts +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/graphql/src/datasources/auth-api.ts +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/graphql/src/index.ts +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/graphql/src/types/context.d.ts +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/graphql/src/types/response.d.ts +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/graphql/tsconfig.json +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/.gitignore +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/README.md +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/@modal/default.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/api-keys/components/columns.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/api-keys/components/create-dialog.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/api-keys/components/data-table-cell-viewer.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/api-keys/components/data-table-toolbar.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/api-keys/components/data-table.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/api-keys/components/delete-dialog.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/api-keys/data/data.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/api-keys/data/schema.ts +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/api-keys/page.tsx +0 -0
- {divi-0.0.1.dev19/apps/web → divi-0.0.1.dev23/apps/web/app/dashboard}/components/nav-main.tsx +0 -0
- {divi-0.0.1.dev19/apps/web → divi-0.0.1.dev23/apps/web/app/dashboard/settings/account}/components/account-form.tsx +0 -0
- {divi-0.0.1.dev19/apps/web → divi-0.0.1.dev23/apps/web/app/dashboard/settings/appearance}/components/appearance-form.tsx +0 -0
- {divi-0.0.1.dev19/apps/web → divi-0.0.1.dev23/apps/web/app/dashboard/settings}/components/profile-form.tsx +0 -0
- {divi-0.0.1.dev19/apps/web → divi-0.0.1.dev23/apps/web/app/dashboard/traces/(children)/[id]}/components/trace-chart.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/traces/(overview)/components/columns.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/traces/(overview)/components/data-table-row-action.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/traces/(overview)/components/data-table-toolbar.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/traces/(overview)/components/data-table.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/traces/(overview)/data/data.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/traces/(overview)/data/schema.ts +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/dashboard/traces/(overview)/page.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/favicon.ico +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/home/components/home-hero.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/home/page.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/layout.tsx +0 -0
- {divi-0.0.1.dev19/apps/web → divi-0.0.1.dev23/apps/web/app/login}/components/login-form.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/app/page.tsx +0 -0
- {divi-0.0.1.dev19/apps/web → divi-0.0.1.dev23/apps/web/app/signup}/components/signup-form.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/components/ApolloWrapper.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/components/Modal.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/components/data-table-column-header.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/components/data-table-faceted-filter.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/components/data-table-pagination.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/components/data-table-row.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/components/mode-switcher.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/components/theme-provider.tsx +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/components.json +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/hooks/actionState.ts +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/hooks/apolloClient.ts +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/lib/callback/toast-callback.ts +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/lib/callback/with-callback.ts +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/lib/server/README.md +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/lib/server/auth.ts +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/lib/server/cookies.ts +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/lib/server/span.ts +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/lib/types/state.d.ts +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/lib/utils.ts +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/next-env.d.ts +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/next.config.ts +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/postcss.config.mjs +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/public/peeking-angel.png +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/public/thinking-angel.png +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/tsconfig.json +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/apps/web/vercel.json +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/biome.json +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/compose-dev.yml +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/config/config.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/decorators/__init__.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/proto/common/v1/common.proto +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/proto/common/v1/common_pb2.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/proto/common/v1/common_pb2.pyi +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/proto/core/health/v1/health_service.proto +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/proto/core/health/v1/health_service_pb2.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/proto/core/health/v1/health_service_pb2.pyi +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/proto/core/health/v1/health_service_pb2_grpc.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/proto/metric/v1/metric.proto +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/proto/metric/v1/metric_pb2.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/proto/metric/v1/metric_pb2.pyi +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/proto/trace/v1/trace.proto +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/proto/trace/v1/trace_pb2.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/proto/trace/v1/trace_pb2.pyi +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/services/__init__.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/services/auth/__init__.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/services/auth/auth.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/services/auth/init.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/services/auth/tokman.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/services/core/__init__.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/services/core/core.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/services/core/finish.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/services/core/init.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/services/datapark/__init__.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/services/datapark/init.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/services/finish.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/services/init.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/services/service.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/session/__init__.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/session/teardown.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/signals/__init__.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/signals/trace/__init__.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/divi/utils.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/docker-compose.yml +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/docs/README.md +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/docs/developer_tools.md +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/docs/images/architecture.svg +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/docs/images/favicon.ico +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/docs/images/og-image.png +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/docs/images/storage.svg +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/docs/package_readme.md +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/go.work +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/hatch.toml +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/packages/README.md +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/pyproject.toml +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/scripts/README.md +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/scripts/hatch_build.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/scripts/key_build.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/scripts/proto_build.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/README.md +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/internal/app/auth/handler/api.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/internal/app/auth/handler/api_key.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/internal/app/auth/handler/auth.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/internal/app/auth/handler/user.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/internal/app/auth/router/router.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/internal/app/core/.keep +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/internal/app/datapark/handler/api.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/internal/app/datapark/handler/session.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/internal/app/datapark/handler/trace.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/internal/pkg/auth/auth.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/internal/pkg/auth/middleware.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/internal/pkg/config/config.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/internal/pkg/database/connect.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/internal/pkg/database/database.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/internal/pkg/model/api_key.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/internal/pkg/model/openai.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/internal/pkg/model/session.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/internal/pkg/model/trace.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/internal/pkg/model/user.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/pb/common.pb.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/pb/health_service.pb.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/pb/health_service_grpc.pb.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/pb/metric.pb.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/services/pb/trace.pb.go +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/tests/__init__.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/tests/unit_tests/decorators/test_obs_openai.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/tests/unit_tests/decorators/test_observable.py +0 -0
- {divi-0.0.1.dev19 → divi-0.0.1.dev23}/turbo.json +0 -0
@@ -1,5 +1,5 @@
|
|
1
1
|
import type { FetchResponse } from '@/types/response';
|
2
|
-
import type { ChatInput, Span, Trace } from '@/types/types';
|
2
|
+
import type { ChatInput, Span, Trace, UsageResult } from '@/types/types';
|
3
3
|
import { type AugmentedRequest, RESTDataSource } from '@apollo/datasource-rest';
|
4
4
|
import type { KeyValueCache } from '@apollo/utils.keyvaluecache';
|
5
5
|
|
@@ -35,4 +35,21 @@ export class DataParkAPI extends RESTDataSource {
|
|
35
35
|
`/api/v1/chat/completions/${spanId}/input`
|
36
36
|
);
|
37
37
|
}
|
38
|
+
|
39
|
+
async getCompletionUsage(
|
40
|
+
startTime: number,
|
41
|
+
endTime: number | undefined,
|
42
|
+
groupBy: string | undefined
|
43
|
+
) {
|
44
|
+
return await this.get<FetchResponse<UsageResult[]>>(
|
45
|
+
'/api/usage/completions',
|
46
|
+
{
|
47
|
+
params: {
|
48
|
+
start_time: startTime.toString(),
|
49
|
+
end_time: endTime?.toString(),
|
50
|
+
group_by: groupBy,
|
51
|
+
},
|
52
|
+
}
|
53
|
+
);
|
54
|
+
}
|
38
55
|
}
|
@@ -29,6 +29,19 @@ export const resolvers: Resolvers = {
|
|
29
29
|
chat_input: async (_, { span_id }, { dataSources }) => {
|
30
30
|
return (await dataSources.dataparkAPI.getChatInput(span_id)).data;
|
31
31
|
},
|
32
|
+
completion_usage: async (
|
33
|
+
_,
|
34
|
+
{ start_time, end_time, group_by },
|
35
|
+
{ dataSources }
|
36
|
+
) => {
|
37
|
+
return (
|
38
|
+
await dataSources.dataparkAPI.getCompletionUsage(
|
39
|
+
start_time,
|
40
|
+
end_time ?? undefined,
|
41
|
+
group_by ?? undefined
|
42
|
+
)
|
43
|
+
).data;
|
44
|
+
},
|
32
45
|
},
|
33
46
|
Mutation: {
|
34
47
|
createAPIKey: async (_, { name }, { dataSources }) => {
|
@@ -14,6 +14,18 @@ type Query {
|
|
14
14
|
spans(trace_id: ID!): [Span!]
|
15
15
|
"Fetch openai input by span id"
|
16
16
|
chat_input(span_id: ID!): ChatInput
|
17
|
+
"Fetch completion usages"
|
18
|
+
completion_usage(
|
19
|
+
start_time: Int!
|
20
|
+
end_time: Int
|
21
|
+
group_by: GroupingKey
|
22
|
+
): [UsageResult!]
|
23
|
+
}
|
24
|
+
|
25
|
+
"GroupingKey is an enum that represents the key used to group usage results"
|
26
|
+
enum GroupingKey {
|
27
|
+
date
|
28
|
+
model
|
17
29
|
}
|
18
30
|
|
19
31
|
"NullTime is a custom scalar type that represents a time value that can be null"
|
@@ -54,6 +66,7 @@ type Trace {
|
|
54
66
|
session_id: ID!
|
55
67
|
}
|
56
68
|
|
69
|
+
"Kind is an enum that represents the type of span"
|
57
70
|
enum Kind {
|
58
71
|
SPAN_KIND_FUNCTION
|
59
72
|
SPAN_KIND_LLM
|
@@ -91,6 +104,15 @@ type MessageInput {
|
|
91
104
|
name: String
|
92
105
|
}
|
93
106
|
|
107
|
+
"UsageResult is the result of a usage query"
|
108
|
+
type UsageResult {
|
109
|
+
input_tokens: Int!
|
110
|
+
output_tokens: Int!
|
111
|
+
total_tokens: Int!
|
112
|
+
model: String
|
113
|
+
date: Int
|
114
|
+
}
|
115
|
+
|
94
116
|
"Mutation is a collection of mutations that can be made to the API"
|
95
117
|
type Mutation {
|
96
118
|
"Auth Mutations"
|
@@ -77,6 +77,12 @@ export type DeleteUserResponse = MutationResponse & {
|
|
77
77
|
success: Scalars['Boolean']['output'];
|
78
78
|
};
|
79
79
|
|
80
|
+
/** GroupingKey is an enum that represents the key used to group usage results */
|
81
|
+
export enum GroupingKey {
|
82
|
+
Date = 'date',
|
83
|
+
Model = 'model'
|
84
|
+
}
|
85
|
+
|
80
86
|
/** KeyValue is a key-value pair */
|
81
87
|
export type KeyValue = {
|
82
88
|
__typename?: 'KeyValue';
|
@@ -84,6 +90,7 @@ export type KeyValue = {
|
|
84
90
|
value: Scalars['String']['output'];
|
85
91
|
};
|
86
92
|
|
93
|
+
/** Kind is an enum that represents the type of span */
|
87
94
|
export enum Kind {
|
88
95
|
SpanKindFunction = 'SPAN_KIND_FUNCTION',
|
89
96
|
SpanKindLlm = 'SPAN_KIND_LLM'
|
@@ -190,6 +197,8 @@ export type Query = {
|
|
190
197
|
api_keys?: Maybe<Array<ApiKey>>;
|
191
198
|
/** Fetch openai input by span id */
|
192
199
|
chat_input?: Maybe<ChatInput>;
|
200
|
+
/** Fetch completion usages */
|
201
|
+
completion_usage?: Maybe<Array<UsageResult>>;
|
193
202
|
/** Fetch current user */
|
194
203
|
me: User;
|
195
204
|
/** Fetch all spans by trace id */
|
@@ -207,6 +216,14 @@ export type QueryChat_InputArgs = {
|
|
207
216
|
};
|
208
217
|
|
209
218
|
|
219
|
+
/** Query is a collection of queries that can be made to the API */
|
220
|
+
export type QueryCompletion_UsageArgs = {
|
221
|
+
end_time?: InputMaybe<Scalars['Int']['input']>;
|
222
|
+
group_by?: InputMaybe<GroupingKey>;
|
223
|
+
start_time: Scalars['Int']['input'];
|
224
|
+
};
|
225
|
+
|
226
|
+
|
210
227
|
/** Query is a collection of queries that can be made to the API */
|
211
228
|
export type QuerySpansArgs = {
|
212
229
|
trace_id: Scalars['ID']['input'];
|
@@ -274,6 +291,16 @@ export type UpdateUserResponse = MutationResponse & {
|
|
274
291
|
success: Scalars['Boolean']['output'];
|
275
292
|
};
|
276
293
|
|
294
|
+
/** UsageResult is the result of a usage query */
|
295
|
+
export type UsageResult = {
|
296
|
+
__typename?: 'UsageResult';
|
297
|
+
date?: Maybe<Scalars['Int']['output']>;
|
298
|
+
input_tokens: Scalars['Int']['output'];
|
299
|
+
model?: Maybe<Scalars['String']['output']>;
|
300
|
+
output_tokens: Scalars['Int']['output'];
|
301
|
+
total_tokens: Scalars['Int']['output'];
|
302
|
+
};
|
303
|
+
|
277
304
|
/** User is a registered user of the application */
|
278
305
|
export type User = {
|
279
306
|
__typename?: 'User';
|
@@ -367,6 +394,7 @@ export type ResolversTypes = {
|
|
367
394
|
CreateUserResponse: ResolverTypeWrapper<Omit<CreateUserResponse, 'data'> & { data?: Maybe<ResolversTypes['User']> }>;
|
368
395
|
DeleteUserResponse: ResolverTypeWrapper<DeleteUserResponse>;
|
369
396
|
Float: ResolverTypeWrapper<Scalars['Float']['output']>;
|
397
|
+
GroupingKey: GroupingKey;
|
370
398
|
ID: ResolverTypeWrapper<Scalars['ID']['output']>;
|
371
399
|
Int: ResolverTypeWrapper<Scalars['Int']['output']>;
|
372
400
|
KeyValue: ResolverTypeWrapper<KeyValue>;
|
@@ -382,6 +410,7 @@ export type ResolversTypes = {
|
|
382
410
|
Trace: ResolverTypeWrapper<Trace>;
|
383
411
|
UpdateAPIKeyResponse: ResolverTypeWrapper<Omit<UpdateApiKeyResponse, 'data'> & { data?: Maybe<ResolversTypes['APIKey']> }>;
|
384
412
|
UpdateUserResponse: ResolverTypeWrapper<Omit<UpdateUserResponse, 'data'> & { data?: Maybe<ResolversTypes['User']> }>;
|
413
|
+
UsageResult: ResolverTypeWrapper<UsageResult>;
|
385
414
|
User: ResolverTypeWrapper<UserModel>;
|
386
415
|
};
|
387
416
|
|
@@ -409,6 +438,7 @@ export type ResolversParentTypes = {
|
|
409
438
|
Trace: Trace;
|
410
439
|
UpdateAPIKeyResponse: Omit<UpdateApiKeyResponse, 'data'> & { data?: Maybe<ResolversParentTypes['APIKey']> };
|
411
440
|
UpdateUserResponse: Omit<UpdateUserResponse, 'data'> & { data?: Maybe<ResolversParentTypes['User']> };
|
441
|
+
UsageResult: UsageResult;
|
412
442
|
User: UserModel;
|
413
443
|
};
|
414
444
|
|
@@ -504,6 +534,7 @@ export type QueryResolvers<ContextType = DataSourceContext, ParentType extends R
|
|
504
534
|
all_traces?: Resolver<Maybe<Array<ResolversTypes['Trace']>>, ParentType, ContextType>;
|
505
535
|
api_keys?: Resolver<Maybe<Array<ResolversTypes['APIKey']>>, ParentType, ContextType>;
|
506
536
|
chat_input?: Resolver<Maybe<ResolversTypes['ChatInput']>, ParentType, ContextType, RequireFields<QueryChat_InputArgs, 'span_id'>>;
|
537
|
+
completion_usage?: Resolver<Maybe<Array<ResolversTypes['UsageResult']>>, ParentType, ContextType, RequireFields<QueryCompletion_UsageArgs, 'start_time'>>;
|
507
538
|
me?: Resolver<ResolversTypes['User'], ParentType, ContextType>;
|
508
539
|
spans?: Resolver<Maybe<Array<ResolversTypes['Span']>>, ParentType, ContextType, RequireFields<QuerySpansArgs, 'trace_id'>>;
|
509
540
|
traces?: Resolver<Maybe<Array<ResolversTypes['Trace']>>, ParentType, ContextType, RequireFields<QueryTracesArgs, 'session_id'>>;
|
@@ -555,6 +586,15 @@ export type UpdateUserResponseResolvers<ContextType = DataSourceContext, ParentT
|
|
555
586
|
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
556
587
|
};
|
557
588
|
|
589
|
+
export type UsageResultResolvers<ContextType = DataSourceContext, ParentType extends ResolversParentTypes['UsageResult'] = ResolversParentTypes['UsageResult']> = {
|
590
|
+
date?: Resolver<Maybe<ResolversTypes['Int']>, ParentType, ContextType>;
|
591
|
+
input_tokens?: Resolver<ResolversTypes['Int'], ParentType, ContextType>;
|
592
|
+
model?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
|
593
|
+
output_tokens?: Resolver<ResolversTypes['Int'], ParentType, ContextType>;
|
594
|
+
total_tokens?: Resolver<ResolversTypes['Int'], ParentType, ContextType>;
|
595
|
+
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
596
|
+
};
|
597
|
+
|
558
598
|
export type UserResolvers<ContextType = DataSourceContext, ParentType extends ResolversParentTypes['User'] = ResolversParentTypes['User']> = {
|
559
599
|
api_keys?: Resolver<Maybe<Array<ResolversTypes['APIKey']>>, ParentType, ContextType>;
|
560
600
|
email?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
|
@@ -582,6 +622,7 @@ export type Resolvers<ContextType = DataSourceContext> = {
|
|
582
622
|
Trace?: TraceResolvers<ContextType>;
|
583
623
|
UpdateAPIKeyResponse?: UpdateApiKeyResponseResolvers<ContextType>;
|
584
624
|
UpdateUserResponse?: UpdateUserResponseResolvers<ContextType>;
|
625
|
+
UsageResult?: UsageResultResolvers<ContextType>;
|
585
626
|
User?: UserResolvers<ContextType>;
|
586
627
|
};
|
587
628
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { ResponsiveDrawer } from '@/components/Modal';
|
2
|
-
import { TraceBoard } from '@/components/trace-board';
|
2
|
+
import { TraceBoard } from '@/app/dashboard/traces/(children)/[id]/components/trace-board';
|
3
3
|
import { getTraceChartData } from '@/lib/server/span';
|
4
4
|
|
5
5
|
interface TraceModalPageProps {
|
@@ -13,12 +13,13 @@ import {
|
|
13
13
|
import { GetMyApiKeysDocument } from '@workspace/graphql-client/src/auth/api-keys.generated';
|
14
14
|
import type { ApiKey } from '@workspace/graphql-client/src/types.generated';
|
15
15
|
import { revalidatePath } from 'next/cache';
|
16
|
+
import { cache } from 'react';
|
16
17
|
|
17
18
|
/**
|
18
19
|
* getAPIKeys action with graphql query
|
19
20
|
* @description get current user's API keys
|
20
21
|
*/
|
21
|
-
export
|
22
|
+
export const getAPIKeys = cache(async () => {
|
22
23
|
const context = await getAuthContext();
|
23
24
|
if (!context) {
|
24
25
|
return null;
|
@@ -28,7 +29,7 @@ export async function getAPIKeys() {
|
|
28
29
|
context,
|
29
30
|
});
|
30
31
|
return data?.api_keys;
|
31
|
-
}
|
32
|
+
});
|
32
33
|
|
33
34
|
/**
|
34
35
|
* createAPIKey action with graphql mutation
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import { ScrollArea } from '@workspace/ui/components/scroll-area';
|
2
|
+
import { Separator } from '@workspace/ui/components/separator';
|
3
|
+
import type React from 'react';
|
4
|
+
import { CreateDialog } from './components/create-dialog';
|
5
|
+
|
6
|
+
interface APIKeysLayoutProps {
|
7
|
+
children: React.ReactNode;
|
8
|
+
}
|
9
|
+
|
10
|
+
export default function APIKeysLayout({ children }: APIKeysLayoutProps) {
|
11
|
+
return (
|
12
|
+
<div className="h-full space-y-3 overflow-y-auto py-3">
|
13
|
+
<ScrollArea className="max-h-full">
|
14
|
+
<div className="flex items-center justify-between px-6">
|
15
|
+
<h1 className=" text-xl tracking-tight">API Keys</h1>
|
16
|
+
<CreateDialog />
|
17
|
+
</div>
|
18
|
+
<Separator className="my-3" />
|
19
|
+
<div className="px-6">
|
20
|
+
<p className="text-muted-foreground text-sm">
|
21
|
+
As a owner of this account, you can view and manage all API keys in
|
22
|
+
this account.
|
23
|
+
</p>
|
24
|
+
<div className="my-6">{children}</div>
|
25
|
+
</div>
|
26
|
+
</ScrollArea>
|
27
|
+
</div>
|
28
|
+
);
|
29
|
+
}
|
{divi-0.0.1.dev19/apps/web → divi-0.0.1.dev23/apps/web/app/dashboard}/components/app-sidebar.tsx
RENAMED
@@ -1,13 +1,9 @@
|
|
1
1
|
'use client';
|
2
2
|
|
3
|
-
import { NavMain } from '@/components/nav-main';
|
4
|
-
import { NavSecondary } from '@/components/nav-secondary';
|
5
|
-
import { NavUser } from '@/components/nav-user';
|
6
3
|
import {
|
7
4
|
IconBinaryTree,
|
8
5
|
IconBook,
|
9
6
|
IconCurrencyDollar,
|
10
|
-
IconDashboard,
|
11
7
|
IconKey,
|
12
8
|
IconSettings,
|
13
9
|
} from '@tabler/icons-react';
|
@@ -23,6 +19,9 @@ import {
|
|
23
19
|
} from '@workspace/ui/components/sidebar';
|
24
20
|
import Link from 'next/link';
|
25
21
|
import type * as React from 'react';
|
22
|
+
import { NavMain } from './nav-main';
|
23
|
+
import { NavSecondary } from './nav-secondary';
|
24
|
+
import { NavUser } from './nav-user';
|
26
25
|
|
27
26
|
const data = {
|
28
27
|
user: {
|
@@ -31,11 +30,11 @@ const data = {
|
|
31
30
|
avatar: '/thinking-angel.png',
|
32
31
|
},
|
33
32
|
navMain: [
|
34
|
-
{
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
},
|
33
|
+
// {
|
34
|
+
// title: 'Overview',
|
35
|
+
// url: '/dashboard',
|
36
|
+
// icon: IconDashboard,
|
37
|
+
// },
|
39
38
|
{
|
40
39
|
title: 'Trace',
|
41
40
|
url: '/dashboard/traces',
|
@@ -82,7 +81,7 @@ export function AppSidebar({
|
|
82
81
|
asChild
|
83
82
|
className="data-[slot=sidebar-menu-button]:!p-1.5"
|
84
83
|
>
|
85
|
-
<Link href="/">
|
84
|
+
<Link href="/home">
|
86
85
|
<span className="text-xl">😇</span>
|
87
86
|
<span className="font-semibold text-base">Divine Agent</span>
|
88
87
|
</Link>
|
{divi-0.0.1.dev19/apps/web → divi-0.0.1.dev23/apps/web/app/dashboard}/components/nav-secondary.tsx
RENAMED
@@ -1,6 +1,5 @@
|
|
1
1
|
import type { Icon } from '@tabler/icons-react';
|
2
2
|
import type * as React from 'react';
|
3
|
-
|
4
3
|
import {
|
5
4
|
SidebarGroup,
|
6
5
|
SidebarGroupContent,
|
@@ -27,7 +26,7 @@ export function NavSecondary({
|
|
27
26
|
{items.map((item) => (
|
28
27
|
<SidebarMenuItem key={item.title}>
|
29
28
|
<SidebarMenuButton asChild>
|
30
|
-
<Link href={item.url}>
|
29
|
+
<Link href={item.url} passHref>
|
31
30
|
<item.icon />
|
32
31
|
<span>{item.title}</span>
|
33
32
|
</Link>
|
{divi-0.0.1.dev19/apps/web → divi-0.0.1.dev23/apps/web/app/dashboard}/components/site-header.tsx
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
import { SiGithub } from '@icons-pack/react-simple-icons';
|
2
2
|
import { SidebarTrigger } from '@workspace/ui/components/sidebar';
|
3
|
-
import { ModeSwitcher } from '
|
3
|
+
import { ModeSwitcher } from '@/components/mode-switcher';
|
4
4
|
|
5
5
|
export function SiteHeader() {
|
6
6
|
return (
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import { AppSidebar } from '
|
2
|
-
import { SiteHeader } from '
|
1
|
+
import { AppSidebar } from './components/app-sidebar';
|
2
|
+
import { SiteHeader } from './components/site-header';
|
3
3
|
import { getCurrentUser } from '@/lib/server/auth';
|
4
4
|
import { deleteSessionTokenCookie } from '@/lib/server/cookies';
|
5
5
|
import {
|
@@ -38,6 +38,7 @@ export default async function DashboardLayout({
|
|
38
38
|
return (
|
39
39
|
<SidebarProvider
|
40
40
|
defaultOpen={defaultOpen}
|
41
|
+
className="max-h-screen"
|
41
42
|
style={
|
42
43
|
{
|
43
44
|
'--sidebar-width': 'calc(var(--spacing) * 58)',
|
@@ -47,10 +48,8 @@ export default async function DashboardLayout({
|
|
47
48
|
<AppSidebar variant="inset" user={user} signoutAction={signout} />
|
48
49
|
<SidebarInset>
|
49
50
|
<SiteHeader />
|
50
|
-
|
51
|
-
|
52
|
-
{children}
|
53
|
-
</div>
|
51
|
+
{modal}
|
52
|
+
{children}
|
54
53
|
</SidebarInset>
|
55
54
|
</SidebarProvider>
|
56
55
|
);
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { AccountForm } from '
|
1
|
+
import { AccountForm } from './components/account-form';
|
2
2
|
import { getClient } from '@/hooks/apolloClient';
|
3
3
|
import { getCurrentUser } from '@/lib/server/auth';
|
4
4
|
import { getAuthContext } from '@/lib/server/auth';
|
@@ -0,0 +1,161 @@
|
|
1
|
+
import type { ExtendedSpan } from '@/lib/types/span';
|
2
|
+
import { formatDate } from '@/lib/utils';
|
3
|
+
import {
|
4
|
+
Accordion,
|
5
|
+
AccordionContent,
|
6
|
+
AccordionItem,
|
7
|
+
AccordionTrigger,
|
8
|
+
} from '@workspace/ui/components/accordion';
|
9
|
+
import { Badge } from '@workspace/ui/components/badge';
|
10
|
+
import {
|
11
|
+
Card,
|
12
|
+
CardContent,
|
13
|
+
CardDescription,
|
14
|
+
CardHeader,
|
15
|
+
CardTitle,
|
16
|
+
} from '@workspace/ui/components/card';
|
17
|
+
import { Timer } from 'lucide-react';
|
18
|
+
import type * as React from 'react';
|
19
|
+
import Highlighter from '@/components/Highter';
|
20
|
+
|
21
|
+
interface SpanProps {
|
22
|
+
span: ExtendedSpan;
|
23
|
+
}
|
24
|
+
|
25
|
+
export function Span({ span }: SpanProps) {
|
26
|
+
const messages = span.input?.messages ?? [];
|
27
|
+
const choices = span.completion?.choices ?? [];
|
28
|
+
return (
|
29
|
+
<>
|
30
|
+
<GeneralInfo span={span} />
|
31
|
+
<Accordion
|
32
|
+
type="multiple"
|
33
|
+
defaultValue={['properties', 'Input', 'Output']}
|
34
|
+
>
|
35
|
+
<AccordionProperties span={span} />
|
36
|
+
<AccordionJsonCards name="Input" datas={messages} />
|
37
|
+
<AccordionJsonCards name="Output" datas={choices} />
|
38
|
+
</Accordion>
|
39
|
+
</>
|
40
|
+
);
|
41
|
+
}
|
42
|
+
|
43
|
+
function GeneralInfo({ span }: SpanProps) {
|
44
|
+
return (
|
45
|
+
<div className="flex flex-col gap-3 border-b p-4">
|
46
|
+
<div className="flex items-center justify-between text-text-primary">
|
47
|
+
<span className="font-medium">{span.name}</span>
|
48
|
+
</div>
|
49
|
+
<div className="flex gap-3">
|
50
|
+
<Badge variant="secondary">{span.kind}</Badge>
|
51
|
+
<Badge variant="outline">
|
52
|
+
<Timer />
|
53
|
+
{span.duration} ms
|
54
|
+
</Badge>
|
55
|
+
</div>
|
56
|
+
</div>
|
57
|
+
);
|
58
|
+
}
|
59
|
+
|
60
|
+
function AccordionProperties({ span }: SpanProps) {
|
61
|
+
// TODO select the properties to show
|
62
|
+
const startTime = formatDate(span.start_time);
|
63
|
+
const endTime = formatDate(span.end_time);
|
64
|
+
const usage = span.completion?.usage;
|
65
|
+
// input should pop messages
|
66
|
+
const { messages, ...inputs } = span.input ?? {};
|
67
|
+
// input parameters display standard: key not starting with __ and value not null or undefined
|
68
|
+
const filteredInputs = Object.entries(inputs).filter(
|
69
|
+
([key, value]) =>
|
70
|
+
value !== null && value !== undefined && !key.startsWith('__')
|
71
|
+
);
|
72
|
+
|
73
|
+
return (
|
74
|
+
<AccordionItem className="px-4" value="properties">
|
75
|
+
<AccordionTrigger className="hover:no-underline">
|
76
|
+
Properties
|
77
|
+
</AccordionTrigger>
|
78
|
+
<AccordionContent>
|
79
|
+
<div className="flex flex-col gap-2">
|
80
|
+
{filteredInputs.length > 0 && (
|
81
|
+
<PropertyCard title="Patameters">
|
82
|
+
{filteredInputs.map(([key, value]) => (
|
83
|
+
<PropertyItem key={key} label={key} value={value} />
|
84
|
+
))}
|
85
|
+
</PropertyCard>
|
86
|
+
)}
|
87
|
+
{usage && (
|
88
|
+
<PropertyCard title="Usages">
|
89
|
+
<PropertyItem label="Prompt Tokens" value={usage.prompt_tokens} />
|
90
|
+
<PropertyItem
|
91
|
+
label="Completion Tokens"
|
92
|
+
value={usage.completion_tokens}
|
93
|
+
/>
|
94
|
+
<PropertyItem label="Total Tokens" value={usage.total_tokens} />
|
95
|
+
</PropertyCard>
|
96
|
+
)}
|
97
|
+
<PropertyCard title="Metadatas">
|
98
|
+
<PropertyItem label="Start Time" value={startTime} />
|
99
|
+
<PropertyItem label="End Time" value={endTime} />
|
100
|
+
</PropertyCard>
|
101
|
+
</div>
|
102
|
+
</AccordionContent>
|
103
|
+
</AccordionItem>
|
104
|
+
);
|
105
|
+
}
|
106
|
+
|
107
|
+
function PropertyCard({
|
108
|
+
title,
|
109
|
+
description,
|
110
|
+
children,
|
111
|
+
}: { title: string; description?: string; children: React.ReactNode }) {
|
112
|
+
return (
|
113
|
+
<Card className="w-full">
|
114
|
+
<CardHeader>
|
115
|
+
<CardTitle>{title}</CardTitle>
|
116
|
+
{description && <CardDescription> {description}</CardDescription>}
|
117
|
+
</CardHeader>
|
118
|
+
<CardContent className="flex flex-col gap-2">{children}</CardContent>
|
119
|
+
</Card>
|
120
|
+
);
|
121
|
+
}
|
122
|
+
|
123
|
+
function PropertyItem({
|
124
|
+
label,
|
125
|
+
value,
|
126
|
+
}: {
|
127
|
+
label: string;
|
128
|
+
value: string | number | boolean | null;
|
129
|
+
}) {
|
130
|
+
return (
|
131
|
+
<div className="flex items-center justify-between">
|
132
|
+
<span className="text-sm">{label}</span>
|
133
|
+
<span className="truncate font-light text-sm">{String(value)}</span>
|
134
|
+
</div>
|
135
|
+
);
|
136
|
+
}
|
137
|
+
|
138
|
+
interface AccordionCardsProps<T> {
|
139
|
+
name: string;
|
140
|
+
datas: T[];
|
141
|
+
}
|
142
|
+
|
143
|
+
function AccordionJsonCards<T>({ name, datas }: AccordionCardsProps<T>) {
|
144
|
+
return (
|
145
|
+
<AccordionItem value={name} className="px-4">
|
146
|
+
<AccordionTrigger className="hover:no-underline">{name}</AccordionTrigger>
|
147
|
+
<AccordionContent className="flex flex-col gap-3">
|
148
|
+
{datas.map((data, index) => (
|
149
|
+
<Card key={index}>
|
150
|
+
<CardContent>
|
151
|
+
<Highlighter
|
152
|
+
content={JSON.stringify(data, null, 2)}
|
153
|
+
language="json"
|
154
|
+
/>
|
155
|
+
</CardContent>
|
156
|
+
</Card>
|
157
|
+
))}
|
158
|
+
</AccordionContent>
|
159
|
+
</AccordionItem>
|
160
|
+
);
|
161
|
+
}
|
@@ -5,6 +5,7 @@ import {
|
|
5
5
|
ResizablePanel,
|
6
6
|
ResizablePanelGroup,
|
7
7
|
} from '@workspace/ui/components/resizable';
|
8
|
+
import { ScrollArea } from '@workspace/ui/components/scroll-area';
|
8
9
|
import { useIsMobile } from '@workspace/ui/hooks/use-mobile';
|
9
10
|
import type { ReactNode } from 'react';
|
10
11
|
|
@@ -28,10 +29,16 @@ export function ResponsiveResizable({
|
|
28
29
|
return (
|
29
30
|
<ResizablePanelGroup direction={_direction}>
|
30
31
|
<ResizablePanel defaultSize={50} minSize={25}>
|
31
|
-
|
32
|
+
<div className="h-full overflow-y-auto">
|
33
|
+
<ScrollArea className="max-h-full">{first}</ScrollArea>
|
34
|
+
</div>
|
32
35
|
</ResizablePanel>
|
33
36
|
<ResizableHandle />
|
34
|
-
<ResizablePanel defaultSize={50}>
|
37
|
+
<ResizablePanel defaultSize={50}>
|
38
|
+
<div className="h-full overflow-y-auto">
|
39
|
+
<ScrollArea className="max-h-full">{second}</ScrollArea>
|
40
|
+
</div>
|
41
|
+
</ResizablePanel>
|
35
42
|
</ResizablePanelGroup>
|
36
43
|
);
|
37
44
|
}
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
import type { ExtendedSpan } from '@/lib/types/span';
|
4
4
|
import { useState } from 'react';
|
5
|
+
import { Span } from './Span';
|
5
6
|
import { ResponsiveResizable } from './responsive-resizable';
|
6
7
|
import { TraceWaterfallChart } from './trace-chart';
|
7
8
|
|
@@ -25,11 +26,7 @@ export function TraceBoard({ spans, direction }: TraceBoardProps) {
|
|
25
26
|
selectAction={selectAction}
|
26
27
|
/>
|
27
28
|
}
|
28
|
-
second={
|
29
|
-
<span className="font-semibold">
|
30
|
-
{JSON.stringify(spans[index ?? 0])}
|
31
|
-
</span>
|
32
|
-
}
|
29
|
+
second={<Span span={spans[index ?? 0]} />}
|
33
30
|
direction={direction}
|
34
31
|
/>
|
35
32
|
);
|