@swarmclawai/swarmclaw 1.9.35 → 1.9.38
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.
- package/README.md +53 -1
- package/package.json +3 -3
- package/src/app/api/chats/[id]/context-status/route.ts +2 -0
- package/src/app/api/chats/context-status-route.test.ts +59 -0
- package/src/app/api/openclaw/history/route.ts +11 -6
- package/src/app/api/preview-server/route.ts +20 -12
- package/src/app/api/search/route.test.ts +63 -0
- package/src/app/api/search/route.ts +3 -2
- package/src/app/api/settings/route.ts +5 -1
- package/src/app/api/settings/settings-route.test.ts +38 -0
- package/src/app/api/setup/check-provider/route.test.ts +12 -0
- package/src/app/api/setup/check-provider/route.ts +6 -0
- package/src/app/api/usage/live/route.ts +2 -2
- package/src/app/globals.css +158 -0
- package/src/app/layout.tsx +12 -9
- package/src/app/protocols/builder/[templateId]/page.tsx +5 -5
- package/src/components/layout/dashboard-shell.tsx +9 -0
- package/src/components/protocols/builder/protocol-builder-canvas.tsx +106 -15
- package/src/components/providers/theme-provider.tsx +16 -0
- package/src/features/protocols/builder/hooks/use-template-sync.ts +5 -0
- package/src/features/protocols/builder/protocol-builder-store.ts +4 -4
- package/src/features/protocols/builder/utils/builder-template-access.test.ts +30 -0
- package/src/features/protocols/builder/utils/builder-template-access.ts +5 -0
- package/src/lib/providers/index.ts +23 -0
- package/src/lib/server/context-manager.ts +4 -0
- package/src/lib/server/messages/message-repository.test.ts +122 -0
- package/src/lib/server/messages/message-repository.ts +67 -11
- package/src/lib/server/openrouter-model-context.test.ts +205 -0
- package/src/lib/server/openrouter-model-context.ts +169 -0
- package/src/lib/server/provider-health.ts +1 -0
- package/src/lib/server/runtime/devserver-launch.ts +7 -4
- package/src/lib/setup-defaults.test.ts +10 -1
- package/src/lib/setup-defaults.ts +20 -0
- package/src/lib/theme-mode.ts +5 -0
- package/src/types/app-settings.ts +2 -0
- package/src/types/provider.ts +1 -1
- package/src/views/settings/section-theme.tsx +41 -1
|
@@ -86,6 +86,19 @@ export const SETUP_PROVIDERS: SetupProviderOption[] = [
|
|
|
86
86
|
icon: 'R',
|
|
87
87
|
modelLibraryUrl: 'https://openrouter.ai/models',
|
|
88
88
|
},
|
|
89
|
+
{
|
|
90
|
+
id: 'tokenmix',
|
|
91
|
+
name: 'TokenMix',
|
|
92
|
+
description: 'One OpenAI-compatible API relay for Claude, OpenAI, Gemini, DeepSeek, Qwen, and other hosted models.',
|
|
93
|
+
requiresKey: true,
|
|
94
|
+
supportsEndpoint: false,
|
|
95
|
+
defaultEndpoint: 'https://api.tokenmix.ai/v1',
|
|
96
|
+
keyUrl: 'https://tokenmix.ai',
|
|
97
|
+
keyLabel: 'tokenmix.ai',
|
|
98
|
+
badge: 'Catalog',
|
|
99
|
+
icon: 'T',
|
|
100
|
+
modelLibraryUrl: 'https://tokenmix.ai/models',
|
|
101
|
+
},
|
|
89
102
|
{
|
|
90
103
|
id: 'openclaw',
|
|
91
104
|
name: 'OpenClaw',
|
|
@@ -781,6 +794,13 @@ export const DEFAULT_AGENTS = {
|
|
|
781
794
|
model: 'anthropic/claude-sonnet-4.6',
|
|
782
795
|
tools: STARTER_AGENT_TOOLS,
|
|
783
796
|
},
|
|
797
|
+
tokenmix: {
|
|
798
|
+
name: 'TokenMix Agent',
|
|
799
|
+
description: 'A helpful assistant powered through TokenMix.',
|
|
800
|
+
systemPrompt: SWARMCLAW_ASSISTANT_PROMPT,
|
|
801
|
+
model: 'claude-sonnet-4-6',
|
|
802
|
+
tools: STARTER_AGENT_TOOLS,
|
|
803
|
+
},
|
|
784
804
|
google: {
|
|
785
805
|
name: 'Gemini',
|
|
786
806
|
description: 'A helpful Gemini-powered assistant.',
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { SessionResetMode } from './session'
|
|
2
2
|
import type { ExtensionManagedLocalFolderDeclaration } from './extension'
|
|
3
|
+
import type { ThemeMode } from '@/lib/theme-mode'
|
|
3
4
|
|
|
4
5
|
// --- App Settings ---
|
|
5
6
|
export type LoopMode = 'bounded' | 'ongoing'
|
|
@@ -134,6 +135,7 @@ export interface AppSettings {
|
|
|
134
135
|
defaultAgentId?: string | null
|
|
135
136
|
// Theme
|
|
136
137
|
themeHue?: string
|
|
138
|
+
themeMode?: ThemeMode
|
|
137
139
|
// Web search provider
|
|
138
140
|
webSearchProvider?: 'duckduckgo' | 'google' | 'bing' | 'searxng' | 'tavily' | 'brave' | 'exa'
|
|
139
141
|
searxngUrl?: string
|
package/src/types/provider.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type ProviderType = 'claude-cli' | 'codex-cli' | 'opencode-cli' | 'opencode-web' | 'gemini-cli' | 'copilot-cli' | 'droid-cli' | 'cursor-cli' | 'qwen-code-cli' | 'goose' | 'aider-cli' | 'amp-cli' | 'augment-cli' | 'adal-cli' | 'bob-cli' | 'cline-cli' | 'codebuddy-cli' | 'command-code-cli' | 'continue-cli' | 'cortex-cli' | 'crush-cli' | 'deepagents-cli' | 'firebender-cli' | 'iflow-cli' | 'junie-cli' | 'kilo-code-cli' | 'kimi-cli' | 'kode-cli' | 'mcpjam-cli' | 'mistral-vibe-cli' | 'mux-cli' | 'neovate-cli' | 'openhands-cli' | 'pochi-cli' | 'qoder-cli' | 'replit-cli' | 'roo-code-cli' | 'trae-cn-cli' | 'warp-cli' | 'windsurf-cli' | 'zencoder-cli' | 'openai' | 'openrouter' | 'ollama' | 'anthropic' | 'openclaw' | 'hermes' | 'lmstudio' | 'google' | 'deepseek' | 'groq' | 'together' | 'mistral' | 'xai' | 'fireworks' | 'nebius' | 'deepinfra'
|
|
1
|
+
export type ProviderType = 'claude-cli' | 'codex-cli' | 'opencode-cli' | 'opencode-web' | 'gemini-cli' | 'copilot-cli' | 'droid-cli' | 'cursor-cli' | 'qwen-code-cli' | 'goose' | 'aider-cli' | 'amp-cli' | 'augment-cli' | 'adal-cli' | 'bob-cli' | 'cline-cli' | 'codebuddy-cli' | 'command-code-cli' | 'continue-cli' | 'cortex-cli' | 'crush-cli' | 'deepagents-cli' | 'firebender-cli' | 'iflow-cli' | 'junie-cli' | 'kilo-code-cli' | 'kimi-cli' | 'kode-cli' | 'mcpjam-cli' | 'mistral-vibe-cli' | 'mux-cli' | 'neovate-cli' | 'openhands-cli' | 'pochi-cli' | 'qoder-cli' | 'replit-cli' | 'roo-code-cli' | 'trae-cn-cli' | 'warp-cli' | 'windsurf-cli' | 'zencoder-cli' | 'openai' | 'openrouter' | 'tokenmix' | 'ollama' | 'anthropic' | 'openclaw' | 'hermes' | 'lmstudio' | 'google' | 'deepseek' | 'groq' | 'together' | 'mistral' | 'xai' | 'fireworks' | 'nebius' | 'deepinfra'
|
|
2
2
|
export type ProviderId = ProviderType | (string & {})
|
|
3
3
|
|
|
4
4
|
export interface ProviderInfo {
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
3
|
import { useState } from 'react'
|
|
4
|
+
import { Monitor, Moon, Sun } from 'lucide-react'
|
|
5
|
+
import { useTheme } from 'next-themes'
|
|
4
6
|
import { toast } from 'sonner'
|
|
7
|
+
import { normalizeThemeMode, type ThemeMode } from '@/lib/theme-mode'
|
|
5
8
|
import type { SettingsSectionProps } from './types'
|
|
6
9
|
|
|
7
10
|
const PRESETS = [
|
|
@@ -13,12 +16,26 @@ const PRESETS = [
|
|
|
13
16
|
{ label: 'Rose', color: '#2e1a24' },
|
|
14
17
|
]
|
|
15
18
|
|
|
19
|
+
const THEME_MODES: Array<{ id: ThemeMode; label: string; Icon: typeof Sun }> = [
|
|
20
|
+
{ id: 'light', label: 'Light', Icon: Sun },
|
|
21
|
+
{ id: 'dark', label: 'Dark', Icon: Moon },
|
|
22
|
+
{ id: 'system', label: 'System', Icon: Monitor },
|
|
23
|
+
]
|
|
24
|
+
|
|
16
25
|
export function ThemeSection({ appSettings, patchSettings, inputClass }: SettingsSectionProps) {
|
|
26
|
+
const { setTheme } = useTheme()
|
|
17
27
|
const currentHue = appSettings.themeHue || PRESETS[0].color
|
|
28
|
+
const currentMode = normalizeThemeMode(appSettings.themeMode)
|
|
18
29
|
const [customHex, setCustomHex] = useState(
|
|
19
30
|
PRESETS.some((p) => p.color === currentHue) ? '' : currentHue,
|
|
20
31
|
)
|
|
21
32
|
|
|
33
|
+
const applyMode = (mode: ThemeMode) => {
|
|
34
|
+
setTheme(mode)
|
|
35
|
+
patchSettings({ themeMode: mode })
|
|
36
|
+
toast.success('Theme updated')
|
|
37
|
+
}
|
|
38
|
+
|
|
22
39
|
const applyHue = (color: string) => {
|
|
23
40
|
patchSettings({ themeHue: color })
|
|
24
41
|
document.documentElement.style.setProperty('--neutral-tint', color)
|
|
@@ -38,9 +55,32 @@ export function ThemeSection({ appSettings, patchSettings, inputClass }: Setting
|
|
|
38
55
|
Theme
|
|
39
56
|
</h3>
|
|
40
57
|
<p className="text-[12px] text-text-3 mb-5">
|
|
41
|
-
|
|
58
|
+
Choose a color scheme and shift the UI palette with a preset or custom hex color.
|
|
42
59
|
</p>
|
|
43
60
|
|
|
61
|
+
<div className="inline-grid grid-cols-3 rounded-[8px] border border-white/[0.08] bg-white/[0.03] p-1 mb-5">
|
|
62
|
+
{THEME_MODES.map(({ id, label, Icon }) => {
|
|
63
|
+
const isActive = currentMode === id
|
|
64
|
+
return (
|
|
65
|
+
<button
|
|
66
|
+
key={id}
|
|
67
|
+
type="button"
|
|
68
|
+
onClick={() => applyMode(id)}
|
|
69
|
+
aria-pressed={isActive}
|
|
70
|
+
className={`h-9 px-3 rounded-[6px] flex items-center justify-center gap-2 text-[12px] font-600 transition-colors ${
|
|
71
|
+
isActive
|
|
72
|
+
? 'bg-accent text-white'
|
|
73
|
+
: 'text-text-3 hover:text-text hover:bg-white/[0.05]'
|
|
74
|
+
}`}
|
|
75
|
+
title={label}
|
|
76
|
+
>
|
|
77
|
+
<Icon className="w-4 h-4" aria-hidden="true" />
|
|
78
|
+
<span>{label}</span>
|
|
79
|
+
</button>
|
|
80
|
+
)
|
|
81
|
+
})}
|
|
82
|
+
</div>
|
|
83
|
+
|
|
44
84
|
{/* Preset swatches */}
|
|
45
85
|
<div className="flex flex-wrap gap-3 mb-4">
|
|
46
86
|
{PRESETS.map((preset) => {
|