mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
Merge remote-tracking branch 'upstream/develop' into feat/cleanup/dmg
This commit is contained in:
+73
-96
@@ -7,11 +7,11 @@ This document lists all available tools that AlphaHuman can use to interact with
|
||||
AlphaHuman has access to **25 tools** across **1 integrations**.
|
||||
|
||||
**Quick Statistics:**
|
||||
|
||||
- **Notion**: 25 tools
|
||||
|
||||
## Available Tools
|
||||
|
||||
|
||||
### Notion Tools
|
||||
|
||||
This skill provides 25 tools for notion integration.
|
||||
@@ -21,19 +21,18 @@ This skill provides 25 tools for notion integration.
|
||||
**Description**: Append child blocks to a page or block. Supports various block types.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **block_id** (string) **(required)**: The parent page or block ID
|
||||
- **blocks** (string) **(required)**: JSON string of blocks array. Example: [{"type":"paragraph","paragraph":{"rich_text":[{"text":{"content":"Hello"}}]}}]
|
||||
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "append-blocks",
|
||||
"parameters": {
|
||||
"block_id": "example_block_id",
|
||||
"blocks": "example_blocks"
|
||||
}
|
||||
"parameters": { "block_id": "example_block_id", "blocks": "example_blocks" }
|
||||
}
|
||||
```
|
||||
|
||||
@@ -44,6 +43,7 @@ This skill provides 25 tools for notion integration.
|
||||
**Description**: Append text content to a page or block. Use the page id (or block_id) from list-all-pages or get-page. Creates paragraph blocks with the given text.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **block_id** (string): The page or block ID to append to (use page id from list-all-pages)
|
||||
- **content** (string): Alias for text — the content to append to the page
|
||||
- **page_id** (string): Alias for block_id when appending to a page (same as block_id)
|
||||
@@ -52,6 +52,7 @@ This skill provides 25 tools for notion integration.
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "append-text",
|
||||
@@ -71,6 +72,7 @@ This skill provides 25 tools for notion integration.
|
||||
**Description**: Create a comment on a page or block, or reply to a discussion. Provide either page_id (new comment on page) or discussion_id (reply). Requires Notion integration to have insert comment capability.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **block_id** (string): Block ID to comment on (optional, use instead of page_id)
|
||||
- **discussion_id** (string): Discussion ID to reply to an existing thread (use instead of page_id)
|
||||
- **page_id** (string): Page ID to create a comment on (new discussion)
|
||||
@@ -79,6 +81,7 @@ This skill provides 25 tools for notion integration.
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "create-comment",
|
||||
@@ -98,6 +101,7 @@ This skill provides 25 tools for notion integration.
|
||||
**Description**: Create a new database in Notion. Specify parent page_id and title. Optionally provide properties schema as JSON.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **parent_page_id** (string) **(required)**: Parent page ID where the database will be created
|
||||
- **properties** (string): JSON string of properties schema. Example: {"Name":{"title":{}},"Status":{"select":{"options":[{"name":"Todo"},{"name":"Done"}]}}}
|
||||
- **title** (string) **(required)**: Database title
|
||||
@@ -105,6 +109,7 @@ This skill provides 25 tools for notion integration.
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "create-database",
|
||||
@@ -123,6 +128,7 @@ This skill provides 25 tools for notion integration.
|
||||
**Description**: Create a new page in Notion. Parent can be another page or a database. For database parents, properties must match the database schema.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **content** (string): Initial text content (creates a paragraph block)
|
||||
- **parent_id** (string) **(required)**: Parent page ID or database ID
|
||||
- **parent_type** (string): Type of parent (default: page_id)
|
||||
@@ -132,6 +138,7 @@ This skill provides 25 tools for notion integration.
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "create-page",
|
||||
@@ -152,18 +159,15 @@ This skill provides 25 tools for notion integration.
|
||||
**Description**: Delete a block. Permanently removes the block from Notion.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **block_id** (string) **(required)**: The block ID to delete
|
||||
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "delete-block",
|
||||
"parameters": {
|
||||
"block_id": "example_block_id"
|
||||
}
|
||||
}
|
||||
{ "tool": "delete-block", "parameters": { "block_id": "example_block_id" } }
|
||||
```
|
||||
|
||||
---
|
||||
@@ -173,18 +177,15 @@ This skill provides 25 tools for notion integration.
|
||||
**Description**: Delete (archive) a page. Archived pages can be restored from Notion's trash.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **page_id** (string) **(required)**: The page ID to delete/archive
|
||||
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "delete-page",
|
||||
"parameters": {
|
||||
"page_id": "example_page_id"
|
||||
}
|
||||
}
|
||||
{ "tool": "delete-page", "parameters": { "page_id": "example_page_id" } }
|
||||
```
|
||||
|
||||
---
|
||||
@@ -194,18 +195,15 @@ This skill provides 25 tools for notion integration.
|
||||
**Description**: Get a block by its ID. Returns the block's type and content.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **block_id** (string) **(required)**: The block ID
|
||||
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "get-block",
|
||||
"parameters": {
|
||||
"block_id": "example_block_id"
|
||||
}
|
||||
}
|
||||
{ "tool": "get-block", "parameters": { "block_id": "example_block_id" } }
|
||||
```
|
||||
|
||||
---
|
||||
@@ -215,20 +213,16 @@ This skill provides 25 tools for notion integration.
|
||||
**Description**: Get the children blocks of a block or page.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **block_id** (string) **(required)**: The parent block or page ID
|
||||
- **page_size** (number): Number of blocks (default 50, max 100)
|
||||
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "get-block-children",
|
||||
"parameters": {
|
||||
"block_id": "example_block_id",
|
||||
"page_size": 10
|
||||
}
|
||||
}
|
||||
{ "tool": "get-block-children", "parameters": { "block_id": "example_block_id", "page_size": 10 } }
|
||||
```
|
||||
|
||||
---
|
||||
@@ -238,18 +232,15 @@ This skill provides 25 tools for notion integration.
|
||||
**Description**: Get a database's schema and metadata. Shows all properties and their types.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **database_id** (string) **(required)**: The database ID
|
||||
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "get-database",
|
||||
"parameters": {
|
||||
"database_id": "example_database_id"
|
||||
}
|
||||
}
|
||||
{ "tool": "get-database", "parameters": { "database_id": "example_database_id" } }
|
||||
```
|
||||
|
||||
---
|
||||
@@ -259,18 +250,15 @@ This skill provides 25 tools for notion integration.
|
||||
**Description**: Get a page's metadata and properties by its ID. Use notion-get-page-content to get the actual content/blocks.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **page_id** (string) **(required)**: The page ID (UUID format, with or without dashes)
|
||||
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "get-page",
|
||||
"parameters": {
|
||||
"page_id": "example_page_id"
|
||||
}
|
||||
}
|
||||
{ "tool": "get-page", "parameters": { "page_id": "example_page_id" } }
|
||||
```
|
||||
|
||||
---
|
||||
@@ -280,6 +268,7 @@ This skill provides 25 tools for notion integration.
|
||||
**Description**: Get the content blocks of a page. Returns the text and structure of the page. Use recursive=true to also get nested blocks.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **page_id** (string) **(required)**: The page ID to get content from
|
||||
- **page_size** (number): Number of blocks to return (default 50, max 100)
|
||||
- **recursive** (string): Whether to fetch nested blocks (default: false)
|
||||
@@ -287,14 +276,11 @@ This skill provides 25 tools for notion integration.
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "get-page-content",
|
||||
"parameters": {
|
||||
"page_id": "example_page_id",
|
||||
"page_size": 10,
|
||||
"recursive": "example_recursive"
|
||||
}
|
||||
"parameters": { "page_id": "example_page_id", "page_size": 10, "recursive": "example_recursive" }
|
||||
}
|
||||
```
|
||||
|
||||
@@ -305,18 +291,15 @@ This skill provides 25 tools for notion integration.
|
||||
**Description**: Get a user by their ID.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **user_id** (string) **(required)**: The user ID
|
||||
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "get-user",
|
||||
"parameters": {
|
||||
"user_id": "example_user_id"
|
||||
}
|
||||
}
|
||||
{ "tool": "get-user", "parameters": { "user_id": "example_user_id" } }
|
||||
```
|
||||
|
||||
---
|
||||
@@ -326,18 +309,15 @@ This skill provides 25 tools for notion integration.
|
||||
**Description**: List all databases in the workspace that the integration has access to.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **page_size** (number): Number of results (default 20, max 100)
|
||||
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "list-all-databases",
|
||||
"parameters": {
|
||||
"page_size": 10
|
||||
}
|
||||
}
|
||||
{ "tool": "list-all-databases", "parameters": { "page_size": 10 } }
|
||||
```
|
||||
|
||||
---
|
||||
@@ -347,18 +327,15 @@ This skill provides 25 tools for notion integration.
|
||||
**Description**: List pages in the workspace (from last sync). Returns synced pages; run a sync in Settings to refresh.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **page_size** (number): Number of results to return (default 20, max 100)
|
||||
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "list-all-pages",
|
||||
"parameters": {
|
||||
"page_size": 10
|
||||
}
|
||||
}
|
||||
{ "tool": "list-all-pages", "parameters": { "page_size": 10 } }
|
||||
```
|
||||
|
||||
---
|
||||
@@ -368,20 +345,16 @@ This skill provides 25 tools for notion integration.
|
||||
**Description**: List comments on a block or page.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **block_id** (string) **(required)**: Block or page ID to get comments for
|
||||
- **page_size** (number): Number of results (default 20, max 100)
|
||||
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "list-comments",
|
||||
"parameters": {
|
||||
"block_id": "example_block_id",
|
||||
"page_size": 10
|
||||
}
|
||||
}
|
||||
{ "tool": "list-comments", "parameters": { "block_id": "example_block_id", "page_size": 10 } }
|
||||
```
|
||||
|
||||
---
|
||||
@@ -391,18 +364,15 @@ This skill provides 25 tools for notion integration.
|
||||
**Description**: List all users in the workspace that the integration can see.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **page_size** (number): Number of results (default 20, max 100)
|
||||
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "list-users",
|
||||
"parameters": {
|
||||
"page_size": 10
|
||||
}
|
||||
}
|
||||
{ "tool": "list-users", "parameters": { "page_size": 10 } }
|
||||
```
|
||||
|
||||
---
|
||||
@@ -412,6 +382,7 @@ This skill provides 25 tools for notion integration.
|
||||
**Description**: Query a database with optional filters and sorts. Returns database rows/pages. Automatically handles API version compatibility.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **database_id** (string) **(required)**: The database ID to query. Can be either a legacy database ID or a new data source ID - the tool will handle both automatically
|
||||
- **filter** (string): JSON string of filter object (Notion filter syntax)
|
||||
- **page_size** (number): Number of results (default 20, max 100)
|
||||
@@ -420,6 +391,7 @@ This skill provides 25 tools for notion integration.
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "query-database",
|
||||
@@ -439,6 +411,7 @@ This skill provides 25 tools for notion integration.
|
||||
**Description**: Search for pages and databases in your Notion workspace. Supports query, filter by object type (page or database), and sort by last_edited_time.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **filter** (string): Filter results by type: page or database
|
||||
- **page_size** (number): Number of results to return (default 20, max 100)
|
||||
- **query** (string): Search query (optional, returns recent if empty)
|
||||
@@ -447,6 +420,7 @@ This skill provides 25 tools for notion integration.
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "search",
|
||||
@@ -465,16 +439,14 @@ This skill provides 25 tools for notion integration.
|
||||
|
||||
**Description**: AI summarization of Notion pages is now handled by the backend server. Synced page content is submitted to the server which runs summarization.
|
||||
|
||||
**Parameters**: *None*
|
||||
**Parameters**: _None_
|
||||
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "summarize-pages",
|
||||
"parameters": {}
|
||||
}
|
||||
{ "tool": "summarize-pages", "parameters": {} }
|
||||
```
|
||||
|
||||
---
|
||||
@@ -483,16 +455,14 @@ This skill provides 25 tools for notion integration.
|
||||
|
||||
**Description**: Trigger an immediate Notion sync to refresh local data. Returns sync results including counts of synced pages and databases.
|
||||
|
||||
**Parameters**: *None*
|
||||
**Parameters**: _None_
|
||||
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "sync-now",
|
||||
"parameters": {}
|
||||
}
|
||||
{ "tool": "sync-now", "parameters": {} }
|
||||
```
|
||||
|
||||
---
|
||||
@@ -501,16 +471,14 @@ This skill provides 25 tools for notion integration.
|
||||
|
||||
**Description**: Get the current Notion sync status including last sync time, total synced pages/databases, sync progress, and any errors.
|
||||
|
||||
**Parameters**: *None*
|
||||
**Parameters**: _None_
|
||||
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "sync-status",
|
||||
"parameters": {}
|
||||
}
|
||||
{ "tool": "sync-status", "parameters": {} }
|
||||
```
|
||||
|
||||
---
|
||||
@@ -520,6 +488,7 @@ This skill provides 25 tools for notion integration.
|
||||
**Description**: Update a block's content. The structure depends on the block type.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **archived** (string): Set to true to archive the block
|
||||
- **block_id** (string) **(required)**: The block ID to update
|
||||
- **content** (string): JSON string of the block type content. Example for paragraph: {"paragraph":{"rich_text":[{"text":{"content":"Updated text"}}]}}
|
||||
@@ -527,6 +496,7 @@ This skill provides 25 tools for notion integration.
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "update-block",
|
||||
@@ -545,6 +515,7 @@ This skill provides 25 tools for notion integration.
|
||||
**Description**: Update a database's title or properties schema.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **database_id** (string) **(required)**: The database ID to update
|
||||
- **properties** (string): JSON string of properties to add or update
|
||||
- **title** (string): New title (optional)
|
||||
@@ -552,6 +523,7 @@ This skill provides 25 tools for notion integration.
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "update-database",
|
||||
@@ -570,6 +542,7 @@ This skill provides 25 tools for notion integration.
|
||||
**Description**: Update a page's properties. Can update title and other properties. Use notion-append-text to add content blocks.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- **archived** (string): Set to true to archive the page
|
||||
- **page_id** (string) **(required)**: The page ID to update
|
||||
- **properties** (string): JSON string of properties to update
|
||||
@@ -578,6 +551,7 @@ This skill provides 25 tools for notion integration.
|
||||
**Usage Context**: Available in all environments
|
||||
|
||||
**Example**:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "update-page",
|
||||
@@ -592,28 +566,31 @@ This skill provides 25 tools for notion integration.
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Tool Usage Guidelines
|
||||
|
||||
### Authentication
|
||||
|
||||
- All tools require proper authentication setup through the Skills system
|
||||
- OAuth credentials are managed securely and refreshed automatically
|
||||
- API keys are stored encrypted in the application keychain
|
||||
|
||||
### Rate Limiting
|
||||
|
||||
- Tools automatically respect API rate limits of external services
|
||||
- Intelligent retry logic handles temporary failures with exponential backoff
|
||||
|
||||
### Error Handling
|
||||
|
||||
- All tools return structured error responses with detailed information
|
||||
- Network failures trigger automatic retry with configurable attempts
|
||||
|
||||
---
|
||||
|
||||
**Tool Statistics**
|
||||
|
||||
- Total Tools: 25
|
||||
- Active Skills: 1
|
||||
- Last Updated: 2026-03-17T17:02:14.087Z
|
||||
|
||||
*This file was automatically generated when the app loaded.*
|
||||
*Tools are discovered from the running V8 skills runtime.*
|
||||
_This file was automatically generated when the app loaded._
|
||||
_Tools are discovered from the running V8 skills runtime._
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
type ModelInfo,
|
||||
type Tool,
|
||||
} from '../services/api/inferenceApi';
|
||||
import { type TeamUsage, creditsApi } from '../services/api/creditsApi';
|
||||
import { useAppDispatch, useAppSelector } from '../store/hooks';
|
||||
import type { NotionPageSummary, NotionSummary, NotionUserProfile } from '../store/notionSlice';
|
||||
import {
|
||||
@@ -141,6 +142,10 @@ const Conversations = () => {
|
||||
const [isLoadingModels, setIsLoadingModels] = useState(false);
|
||||
const [isSending, setIsSending] = useState(false);
|
||||
const [sendError, setSendError] = useState<string | null>(null);
|
||||
// Budget state
|
||||
const [teamUsage, setTeamUsage] = useState<TeamUsage | null>(null);
|
||||
const [isLoadingBudget, setIsLoadingBudget] = useState(false);
|
||||
|
||||
const isDragging = useRef(false);
|
||||
const messagesEndRef = useRef<HTMLDivElement>(null);
|
||||
const lastPanelWidthRef = useRef(panelWidth);
|
||||
@@ -219,6 +224,18 @@ const Conversations = () => {
|
||||
.finally(() => setIsLoadingModels(false));
|
||||
}, []);
|
||||
|
||||
// Fetch inference budget on mount
|
||||
useEffect(() => {
|
||||
setIsLoadingBudget(true);
|
||||
creditsApi
|
||||
.getTeamUsage()
|
||||
.then(data => setTeamUsage(data))
|
||||
.catch(() => {
|
||||
// Budget unavailable — silently ignore
|
||||
})
|
||||
.finally(() => setIsLoadingBudget(false));
|
||||
}, []);
|
||||
|
||||
// Remove thread fetching - threads are now loaded from Redux persist
|
||||
|
||||
// Sync URL → Redux: when URL has a threadId param, select that thread
|
||||
@@ -995,6 +1012,34 @@ const Conversations = () => {
|
||||
|
||||
{/* Message Input */}
|
||||
<div className="flex-shrink-0 border-t border-white/10 px-4 py-3">
|
||||
{/* Budget depleted banner — show top-up CTA */}
|
||||
{teamUsage && teamUsage.remainingUsd <= 0 && (
|
||||
<div className="mb-3 p-3 rounded-xl bg-coral-500/10 border border-coral-500/20 flex items-center justify-between gap-3">
|
||||
<div className="flex items-center gap-2 min-w-0">
|
||||
<svg
|
||||
className="w-4 h-4 text-coral-400 flex-shrink-0"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24">
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
|
||||
/>
|
||||
</svg>
|
||||
<p className="text-xs text-coral-300 truncate">
|
||||
Daily inference budget exhausted. Top up to continue.
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => navigate('/settings/billing')}
|
||||
className="flex-shrink-0 px-3 py-1.5 rounded-lg bg-coral-500 hover:bg-coral-400 text-white text-xs font-medium transition-colors">
|
||||
Top Up
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Show warning if another thread is active */}
|
||||
{activeThreadId && activeThreadId !== selectedThreadId && (
|
||||
<div className="mb-3 p-2 rounded-lg bg-amber-500/10 border border-amber-500/20">
|
||||
@@ -1004,7 +1049,7 @@ const Conversations = () => {
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
{/* Model selector */}
|
||||
{/* Model selector + budget indicator */}
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
{isLoadingModels ? (
|
||||
<span className="text-xs text-stone-600">Loading models…</span>
|
||||
@@ -1030,6 +1075,48 @@ const Conversations = () => {
|
||||
</select>
|
||||
</>
|
||||
)}
|
||||
<div className="flex-1" />
|
||||
{/* Budget indicator — circular */}
|
||||
{(isLoadingBudget || teamUsage) && (() => {
|
||||
const size = 22;
|
||||
const r = 9;
|
||||
const circ = 2 * Math.PI * r;
|
||||
const pct = teamUsage
|
||||
? Math.min(1, teamUsage.remainingUsd / teamUsage.cycleBudgetUsd)
|
||||
: 0;
|
||||
const dash = pct * circ;
|
||||
return (
|
||||
<div className="flex items-center gap-1.5" title={teamUsage ? `$${teamUsage.remainingUsd.toFixed(2)} of $${teamUsage.cycleBudgetUsd.toFixed(2)} remaining` : 'Loading budget…'}>
|
||||
<svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} className="-rotate-90">
|
||||
<circle cx={size / 2} cy={size / 2} r={r} fill="none" stroke="currentColor" strokeWidth="2.5" className="text-white/10" />
|
||||
{teamUsage ? (
|
||||
<circle
|
||||
cx={size / 2} cy={size / 2} r={r}
|
||||
fill="none" stroke="currentColor" strokeWidth="2.5"
|
||||
strokeDasharray={`${dash} ${circ}`}
|
||||
strokeLinecap="round"
|
||||
className={pct < 0.2 ? 'text-amber-500' : 'text-primary-500'}
|
||||
style={{ transition: 'stroke-dasharray 0.3s ease' }}
|
||||
/>
|
||||
) : (
|
||||
<circle
|
||||
cx={size / 2} cy={size / 2} r={r}
|
||||
fill="none" stroke="currentColor" strokeWidth="2.5"
|
||||
strokeDasharray={`${circ * 0.25} ${circ}`}
|
||||
strokeLinecap="round"
|
||||
className="text-stone-600 animate-spin origin-center"
|
||||
style={{ transformOrigin: `${size / 2}px ${size / 2}px` }}
|
||||
/>
|
||||
)}
|
||||
</svg>
|
||||
{teamUsage && (
|
||||
<span className="text-[10px] text-stone-500">
|
||||
${teamUsage.remainingUsd.toFixed(2)}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})()}
|
||||
</div>
|
||||
{sendError && (
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
|
||||
@@ -8,7 +8,6 @@ import { setOnboardedForUser } from '../../store/authSlice';
|
||||
import { useAppDispatch, useAppSelector } from '../../store/hooks';
|
||||
import FeaturesStep from './steps/FeaturesStep';
|
||||
import GetStartedStep from './steps/GetStartedStep';
|
||||
import InviteCodeStep from './steps/InviteCodeStep';
|
||||
import PrivacyStep from './steps/PrivacyStep';
|
||||
|
||||
const Onboarding = () => {
|
||||
@@ -16,14 +15,13 @@ const Onboarding = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const user = useAppSelector(state => state.user.user);
|
||||
const [currentStep, setCurrentStep] = useState(0);
|
||||
const totalSteps = 4;
|
||||
const totalSteps = 3;
|
||||
|
||||
// Lottie animation files for each step
|
||||
const stepAnimations = [
|
||||
'/lottie/trophy.json', // Step 1 - Invite Code
|
||||
'/lottie/wave.json', // Step 2 - Features
|
||||
'/lottie/safe3.json', // Step 3 - Privacy
|
||||
'/lottie/trophy.json', // Step 4 - Get Started
|
||||
'/lottie/wave.json', // Step 1 - Features
|
||||
'/lottie/safe3.json', // Step 2 - Privacy
|
||||
'/lottie/trophy.json', // Step 3 - Get Started
|
||||
];
|
||||
|
||||
const handleNext = () => {
|
||||
@@ -54,15 +52,11 @@ const Onboarding = () => {
|
||||
const renderStep = () => {
|
||||
switch (currentStep) {
|
||||
case 1:
|
||||
return <InviteCodeStep onNext={handleNext} />;
|
||||
case 2:
|
||||
return <FeaturesStep onNext={handleNext} />;
|
||||
case 3:
|
||||
return <PrivacyStep onNext={handleNext} />;
|
||||
case 4:
|
||||
case 2:
|
||||
return <GetStartedStep onComplete={handleComplete} />;
|
||||
default:
|
||||
return <InviteCodeStep onNext={handleNext} />;
|
||||
return <FeaturesStep onNext={handleNext} />;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user