mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-22 01:24:52 +02:00
[Haik]: ckpt, updated readmes
This commit is contained in:
@@ -13,22 +13,15 @@ export interface ClipboardCard {
|
||||
}
|
||||
|
||||
let clipboardCards: ClipboardCard[] = [];
|
||||
let clipboardTimestamp = 0;
|
||||
|
||||
export function setClipboardCards(cards: ClipboardCard[]): void {
|
||||
clipboardCards = cards;
|
||||
clipboardTimestamp = Date.now();
|
||||
}
|
||||
|
||||
export function getClipboardCards(): ClipboardCard[] {
|
||||
return clipboardCards;
|
||||
}
|
||||
|
||||
export function getClipboardTimestamp(): number {
|
||||
return clipboardTimestamp;
|
||||
}
|
||||
|
||||
export function clearClipboard(): void {
|
||||
clipboardCards = [];
|
||||
clipboardTimestamp = 0;
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
.under_construction_overlay {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: transparent;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
// z-index: 1000;
|
||||
text-align: center;
|
||||
font-family: Arial, sans-serif;
|
||||
color: white;
|
||||
// box-sizing: border-box;
|
||||
}
|
||||
|
||||
.under_construction_overlay img {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.under_construction_overlay h2 {
|
||||
font-size: 24px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.under_construction_overlay p {
|
||||
font-size: 18px;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
|
||||
import React from 'react';
|
||||
import styles from './UnderConstruction.module.scss'; // CSS for styling the overlay
|
||||
|
||||
const UnderConstruction = () => {
|
||||
return (
|
||||
<div className={styles.under_construction_overlay}>
|
||||
<img src="/hammer-icon.png" alt="Console Icon" />
|
||||
<h2>Under Construction</h2>
|
||||
<p>This feature is coming soon!</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export { UnderConstruction };
|
||||
@@ -1,82 +0,0 @@
|
||||
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
|
||||
import { API_BASE } from '@/shared/config';
|
||||
|
||||
const ANALYTICS_API = `${API_BASE}/analytics`;
|
||||
|
||||
export interface UsageSummary {
|
||||
total_sessions: number;
|
||||
total_cost_usd: number;
|
||||
total_messages: number;
|
||||
total_tool_calls: number;
|
||||
avg_duration_seconds: number;
|
||||
avg_cost_per_session: number;
|
||||
completion_rate: number;
|
||||
models_used: Record<string, number>;
|
||||
providers_used: Record<string, number>;
|
||||
top_tools: Record<string, number>;
|
||||
status_breakdown: Record<string, number>;
|
||||
// 9Router enrichment
|
||||
total_prompt_tokens: number;
|
||||
total_completion_tokens: number;
|
||||
cost_by_model: Record<string, { cost: number; requests: number; prompt_tokens: number; completion_tokens: number }>;
|
||||
cost_by_provider: Record<string, { cost: number; requests: number }>;
|
||||
cost_source: ' 9router' | 'sdk' | 'none';
|
||||
nine_router_available: boolean;
|
||||
total_requests: number;
|
||||
}
|
||||
|
||||
export interface CostBreakdown {
|
||||
available: boolean;
|
||||
period: string;
|
||||
total_cost: number;
|
||||
total_requests: number;
|
||||
total_prompt_tokens: number;
|
||||
total_completion_tokens: number;
|
||||
by_model: Record<string, any>;
|
||||
by_provider: Record<string, any>;
|
||||
}
|
||||
|
||||
interface AnalyticsState {
|
||||
summary: UsageSummary | null;
|
||||
costBreakdown: CostBreakdown | null;
|
||||
loading: boolean;
|
||||
}
|
||||
|
||||
const initialState: AnalyticsState = {
|
||||
summary: null,
|
||||
costBreakdown: null,
|
||||
loading: false,
|
||||
};
|
||||
|
||||
export const fetchAnalyticsSummary = createAsyncThunk('analytics/fetchSummary', async () => {
|
||||
const res = await fetch(`${ANALYTICS_API}/usage-summary`);
|
||||
return (await res.json()) as UsageSummary;
|
||||
});
|
||||
|
||||
export const fetchCostBreakdown = createAsyncThunk(
|
||||
'analytics/fetchCostBreakdown',
|
||||
async (period: string = '7d') => {
|
||||
const res = await fetch(`${ANALYTICS_API}/cost-breakdown?period=${period}`);
|
||||
return (await res.json()) as CostBreakdown;
|
||||
},
|
||||
);
|
||||
|
||||
const analyticsSlice = createSlice({
|
||||
name: 'analytics',
|
||||
initialState,
|
||||
reducers: {},
|
||||
extraReducers: (builder) => {
|
||||
builder
|
||||
.addCase(fetchAnalyticsSummary.pending, (state) => { state.loading = true; })
|
||||
.addCase(fetchAnalyticsSummary.fulfilled, (state, action) => {
|
||||
state.loading = false;
|
||||
state.summary = action.payload;
|
||||
})
|
||||
.addCase(fetchAnalyticsSummary.rejected, (state) => { state.loading = false; })
|
||||
.addCase(fetchCostBreakdown.fulfilled, (state, action) => {
|
||||
state.costBreakdown = action.payload;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default analyticsSlice.reducer;
|
||||
@@ -47,16 +47,6 @@ export function buildServeUrl(
|
||||
return `${SERVE_BASE}/${outputId}/serve/index.html?_d=${encodeURIComponent(encoded)}`;
|
||||
}
|
||||
|
||||
export function buildWorkspaceServeUrl(
|
||||
workspaceId: string,
|
||||
inputData: Record<string, any> = {},
|
||||
backendResult: Record<string, any> | null = null,
|
||||
): string {
|
||||
const dataPayload = JSON.stringify({ i: inputData, r: backendResult });
|
||||
const encoded = btoa(unescape(encodeURIComponent(dataPayload)));
|
||||
return `${SERVE_BASE}/workspace/${workspaceId}/serve/index.html?_d=${encodeURIComponent(encoded)}`;
|
||||
}
|
||||
|
||||
export interface OutputExecuteResult {
|
||||
output_id: string;
|
||||
output_name: string;
|
||||
|
||||
@@ -12,7 +12,6 @@ import outputsReducer from './outputsSlice';
|
||||
import dashboardLayoutReducer from './dashboardLayoutSlice';
|
||||
import dashboardsReducer from './dashboardsSlice';
|
||||
import updateReducer from './updateSlice';
|
||||
import analyticsReducer from './analyticsSlice';
|
||||
import modelsReducer from './modelsSlice';
|
||||
|
||||
export const store = configureStore({
|
||||
@@ -30,7 +29,6 @@ export const store = configureStore({
|
||||
dashboardLayout: dashboardLayoutReducer,
|
||||
dashboards: dashboardsReducer,
|
||||
update: updateReducer,
|
||||
analytics: analyticsReducer,
|
||||
models: modelsReducer,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,39 +1,25 @@
|
||||
// store/tempStateSlice.ts
|
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||
|
||||
interface TempState {
|
||||
temp_state: string | null;
|
||||
pendingBrowserUrl: string | null;
|
||||
pendingFocusAgentId: string | null;
|
||||
lastDashboardId: string | null;
|
||||
}
|
||||
|
||||
const initialState: TempState = {
|
||||
temp_state: null,
|
||||
pendingBrowserUrl: null,
|
||||
pendingFocusAgentId: null,
|
||||
lastDashboardId: null,
|
||||
};
|
||||
|
||||
const tempStateSlice = createSlice({
|
||||
name: 'tempState',
|
||||
initialState,
|
||||
reducers: {
|
||||
setTempState(state, action: PayloadAction<string | null>) {
|
||||
state.temp_state = action.payload;
|
||||
},
|
||||
resetTempState(state) {
|
||||
state.temp_state = null;
|
||||
},
|
||||
setPendingBrowserUrl(state, action: PayloadAction<string>) {
|
||||
state.pendingBrowserUrl = action.payload;
|
||||
},
|
||||
clearPendingBrowserUrl(state) {
|
||||
state.pendingBrowserUrl = null;
|
||||
},
|
||||
setLastDashboardId(state, action: PayloadAction<string>) {
|
||||
state.lastDashboardId = action.payload;
|
||||
},
|
||||
setPendingFocusAgentId(state, action: PayloadAction<string>) {
|
||||
state.pendingFocusAgentId = action.payload;
|
||||
},
|
||||
@@ -44,11 +30,8 @@ const tempStateSlice = createSlice({
|
||||
});
|
||||
|
||||
export const {
|
||||
setTempState,
|
||||
resetTempState,
|
||||
setPendingBrowserUrl,
|
||||
clearPendingBrowserUrl,
|
||||
setLastDashboardId,
|
||||
setPendingFocusAgentId,
|
||||
clearPendingFocusAgentId,
|
||||
} = tempStateSlice.actions;
|
||||
|
||||
@@ -73,19 +73,6 @@ export const deleteTemplate = createAsyncThunk('templates/delete', async (id: st
|
||||
return id;
|
||||
});
|
||||
|
||||
export const renderTemplate = createAsyncThunk(
|
||||
'templates/render',
|
||||
async ({ templateId, values }: { templateId: string; values: Record<string, any> }) => {
|
||||
const res = await fetch(`${TEMPLATES_API}/render`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ template_id: templateId, values }),
|
||||
});
|
||||
const data = await res.json();
|
||||
return data.rendered as string;
|
||||
}
|
||||
);
|
||||
|
||||
const templatesSlice = createSlice({
|
||||
name: 'templates',
|
||||
initialState,
|
||||
|
||||
@@ -57,11 +57,6 @@ const updateSlice = createSlice({
|
||||
state.status = 'error';
|
||||
state.error = action.payload;
|
||||
},
|
||||
resetUpdateStatus(state) {
|
||||
state.status = 'idle';
|
||||
state.error = null;
|
||||
state.downloadPercent = 0;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -73,7 +68,6 @@ export const {
|
||||
setDownloading,
|
||||
setUpdateDownloaded,
|
||||
setUpdateError,
|
||||
resetUpdateStatus,
|
||||
} = updateSlice.actions;
|
||||
|
||||
export default updateSlice.reducer;
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
@use '@/shared/styles/utils.module.scss' as utils;
|
||||
|
||||
$text-map: (
|
||||
'light-1': #F0F0F0,
|
||||
'light-2': #D9D9D9,
|
||||
'light-3': #BDBDBD,
|
||||
'light-4': #999999,
|
||||
);
|
||||
@function text($mode: 'light-1') {
|
||||
@return utils.get-style(
|
||||
$function-map: $text-map,
|
||||
$mode: $mode
|
||||
);
|
||||
}
|
||||
|
||||
$background-color-map: (
|
||||
'dark-1': #232323,
|
||||
'dark-2': #151515,
|
||||
'dark-3': #0A0A0A,
|
||||
);
|
||||
@function background-color($mode: 'dark-1') {
|
||||
@return utils.get-style(
|
||||
$function-map: $background-color-map,
|
||||
$mode: $mode
|
||||
);
|
||||
}
|
||||
|
||||
@mixin gradient-1() {
|
||||
$mask-color: rgba(0, 0, 0, 0.623);
|
||||
$gradient-color: rgba(62, 139, 241, 0.20);
|
||||
$background-color: #151515;
|
||||
background:
|
||||
linear-gradient(0deg, $mask-color 0%, $mask-color 100%),
|
||||
radial-gradient(102.16% 48.94% at 49.58% 47.09%, rgba(6, 14, 25, 0.00) 0%, rgba(62, 139, 241, 0.20) 100%),
|
||||
#151515;
|
||||
}
|
||||
|
||||
$glass-map: (
|
||||
'default': (
|
||||
border-radius: 10px,
|
||||
border: 1px solid rgba(255, 255, 255, 0.075),
|
||||
background: rgba(38, 38, 38, 0.184),
|
||||
background-blend-mode: luminosity,
|
||||
backdrop-filter: blur(50px),
|
||||
),
|
||||
'light-05': (
|
||||
border-radius: 10px,
|
||||
border: 1px solid rgba(255, 255, 255, 0.095),
|
||||
background: rgba(160, 160, 160, 0.048),
|
||||
background-blend-mode: luminosity,
|
||||
backdrop-filter: blur(50px),
|
||||
),
|
||||
'light-075': (
|
||||
border-radius: 10px,
|
||||
border: 1px solid rgba(255, 255, 255, 0.095),
|
||||
background: rgba(160, 160, 160, 0.075),
|
||||
background-blend-mode: luminosity,
|
||||
backdrop-filter: blur(50px),
|
||||
),
|
||||
'light-1': (
|
||||
border-radius: 10px,
|
||||
border: 1px solid rgba(255, 255, 255, 0.095),
|
||||
background: rgba(160, 160, 160, 0.154),
|
||||
background-blend-mode: luminosity,
|
||||
backdrop-filter: blur(50px),
|
||||
),
|
||||
'light-2': (
|
||||
border-radius: 10px,
|
||||
border: 1px solid rgba(255, 255, 255, 0.178),
|
||||
background: rgba(160, 160, 160, 0.46),
|
||||
background-blend-mode: luminosity,
|
||||
backdrop-filter: blur(50px),
|
||||
),
|
||||
'light-3': (
|
||||
border-radius: 10px,
|
||||
border: 1px solid rgba(255, 255, 255, 0.178),
|
||||
background: rgba(0, 0, 0, 0.247),
|
||||
background-blend-mode: luminosity,
|
||||
backdrop-filter: blur(50px),
|
||||
),
|
||||
);
|
||||
@mixin glass($mode: 'default') {
|
||||
@include utils.apply-style-map(
|
||||
$mixin-map: $glass-map,
|
||||
$mode: $mode
|
||||
);
|
||||
}
|
||||
|
||||
$glow-map: (
|
||||
'default': (
|
||||
border: 1px solid #0099ff71,
|
||||
box-shadow: 0 0 24px #0099ff71,
|
||||
),
|
||||
'dark-1': (
|
||||
border: 1px solid #3e8cf13e,
|
||||
box-shadow: 0 0 24px #3e8cf12b,
|
||||
),
|
||||
'light-1': (
|
||||
border: 1px solid #ab19ff47,
|
||||
box-shadow: 0 0 44px #c259ff8a,
|
||||
),
|
||||
'source-1': (
|
||||
border: 1px solid #ff000071,
|
||||
box-shadow: 0 0 44px #ff000071,
|
||||
),
|
||||
);
|
||||
@mixin glow($mode: 'default') {
|
||||
@include utils.apply-style-map(
|
||||
$mixin-map: $glow-map,
|
||||
$mode: $mode
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
$accent-map: (
|
||||
'blue-1': #3E8BF1,
|
||||
'blue-2': #3e8cf1c7,
|
||||
'blue-3': #3e8cf15b,
|
||||
'blue-grey-1': #77a7e5c7,
|
||||
'red-1': #F56868,
|
||||
'red-2': #f568681a,
|
||||
);
|
||||
@function accent($mode: 'blue-1') {
|
||||
@return utils.get-style(
|
||||
$function-map: $accent-map,
|
||||
$mode: $mode
|
||||
);
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
export const getStyleValue = (className: string, property: string, defaultValue: string = "none"): string => {
|
||||
if (typeof document !== 'undefined') {
|
||||
const element = document.createElement("div");
|
||||
element.setAttribute("class", className);
|
||||
document.body.appendChild(element);
|
||||
const style = window.getComputedStyle(element);
|
||||
const value = style.getPropertyValue(property);
|
||||
document.body.removeChild(element);
|
||||
return value || defaultValue;
|
||||
}
|
||||
return defaultValue; // Return default value if not in a browser environment
|
||||
};
|
||||
@@ -1,62 +0,0 @@
|
||||
@use '@/shared/styles/utils.module.scss' as utils;
|
||||
|
||||
$flex-map: (
|
||||
'vert': (
|
||||
flex-direction: column,
|
||||
),
|
||||
'horz': (
|
||||
flex-direction: row,
|
||||
),
|
||||
);
|
||||
@mixin flex($direction: 'vert') {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
@include utils.apply-style-map(
|
||||
$mixin-map: $flex-map,
|
||||
$mode: $direction
|
||||
);
|
||||
}
|
||||
|
||||
$flex-hug-map: (
|
||||
'default': (
|
||||
width: fit-content,
|
||||
height: fit-content,
|
||||
),
|
||||
'full-width': (
|
||||
width: 100%,
|
||||
),
|
||||
'full-height': (
|
||||
height: 100%,
|
||||
),
|
||||
);
|
||||
@mixin flex-hug($mode: 'default') {
|
||||
@include flex('horz');
|
||||
@include utils.apply-style-map(
|
||||
$mixin-map: $flex-hug-map,
|
||||
$mode: $mode
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
$scroll-map: (
|
||||
'hidden': (
|
||||
"&::-webkit-scrollbar": (
|
||||
display: none
|
||||
),
|
||||
-ms-overflow-style: none, /* IE and Edge */
|
||||
scrollbar-width: none, /* Firefox */
|
||||
),
|
||||
);
|
||||
@mixin scroll-bar($mode: 'hidden') {
|
||||
@include utils.apply-style-map(
|
||||
$mixin-map: $scroll-map,
|
||||
$mode: $mode
|
||||
);
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
@use '@/shared/styles/color.module.scss' as g-color;
|
||||
@use '@/shared/styles/utils.module.scss' as utils;
|
||||
|
||||
|
||||
$font-map: (
|
||||
'default': 'Inter',
|
||||
'secondary': 'Times New Roman'
|
||||
);
|
||||
@function font($mode: 'default') {
|
||||
@return utils.get-style(
|
||||
$function-map: $font-map,
|
||||
$mode: $mode
|
||||
);
|
||||
}
|
||||
|
||||
$size-map: (
|
||||
'small': 12px,
|
||||
'small-medium': 14px,
|
||||
'medium': 16px,
|
||||
'large': 20px,
|
||||
'title': 30px,
|
||||
);
|
||||
@function size($mode: 'default') {
|
||||
@return utils.get-style(
|
||||
$function-map: $size-map,
|
||||
$mode: $mode
|
||||
);
|
||||
}
|
||||
|
||||
$weight-map: (
|
||||
'small': 400,
|
||||
'medium': 500,
|
||||
'large': 600,
|
||||
'title': 700,
|
||||
);
|
||||
@function weight($mode: 'default') {
|
||||
@return utils.get-style(
|
||||
$function-map: $weight-map,
|
||||
$mode: $mode
|
||||
);
|
||||
}
|
||||
|
||||
$text-map: (
|
||||
'default': (
|
||||
font-family: 'Inter',
|
||||
font-size: 16px,
|
||||
font-weight: 400,
|
||||
color: g-color.text('light-1'),
|
||||
),
|
||||
'title': (
|
||||
font-family: 'Inter',
|
||||
font-size: 40px,
|
||||
font-weight: 700,
|
||||
color: g-color.accent('blue-1'),
|
||||
line-height: 100%,
|
||||
)
|
||||
);
|
||||
@mixin text($mode: 'default') {
|
||||
@include utils.apply-style-map(
|
||||
$mixin-map: $text-map,
|
||||
$mode: $mode
|
||||
);
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
@use "sass:map";
|
||||
@use "sass:meta";
|
||||
|
||||
// NOTE: Example map input:
|
||||
// $text-map: (
|
||||
// 'default': (
|
||||
// font-family: 'Inter',
|
||||
// font-size: 16px,
|
||||
// font-weight: 400,
|
||||
// ),
|
||||
// 'secondary': (∂
|
||||
// font-family: 'Times New Roman',
|
||||
// font-size: 16px,
|
||||
// font-weight: 400,
|
||||
// )
|
||||
// );
|
||||
@function construct-styles($mixin-map, $mode) {
|
||||
$styles: map.get($mixin-map, $mode);
|
||||
@if $styles == null {
|
||||
$available-modes: map.keys($styles);
|
||||
@error "Invalid style mode: '#{$mode}' -> Available modes are: #{$available-modes}.";
|
||||
}
|
||||
@return $styles;
|
||||
}
|
||||
@mixin apply-style-map($mixin-map, $mode) {
|
||||
$styles: construct-styles($mixin-map, $mode);
|
||||
@each $property, $value in $styles {
|
||||
@if meta.type-of($value) == map {
|
||||
// This is a nested selector
|
||||
#{$property} {
|
||||
@each $nested-property, $nested-value in $value {
|
||||
#{$nested-property}: $nested-value;
|
||||
}
|
||||
}
|
||||
} @else {
|
||||
// This is a normal property-value pair
|
||||
#{$property}: $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// NOTE: Example map input:
|
||||
// $font-map: (
|
||||
// 'default': 'Inter',
|
||||
// 'secondary': 'Times New Roman',
|
||||
// )
|
||||
// );
|
||||
@function construct-style($function-map, $mode) {
|
||||
// Check if the mode exists in the map
|
||||
$style-value: map.get($function-map, $mode);
|
||||
@if $style-value == null {
|
||||
$available-modes: map.keys($function-map);
|
||||
@error "Invalid style mode: '#{$mode}' -> Available modes are: #{$available-modes}.";
|
||||
}
|
||||
|
||||
// Return the style value
|
||||
@return $style-value;
|
||||
}
|
||||
@function get-style($function-map, $mode) {
|
||||
$style: construct-style($function-map, $mode);
|
||||
@return $style;
|
||||
}
|
||||
Reference in New Issue
Block a user