@clawpump/claw-agent 0.1.8 → 0.1.11
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/agent/.mailmap +4 -0
- package/agent/apps/desktop/README.md +3 -3
- package/agent/apps/desktop/assets/icon.icns +0 -0
- package/agent/apps/desktop/assets/icon.ico +0 -0
- package/agent/apps/desktop/assets/icon.png +0 -0
- package/agent/apps/desktop/electron/backend-ready.cjs +2 -2
- package/agent/apps/desktop/electron/dashboard-token.cjs +3 -3
- package/agent/apps/desktop/electron/hardening.cjs +1 -1
- package/agent/apps/desktop/electron/main.cjs +67 -67
- package/agent/apps/desktop/index.html +1 -1
- package/agent/apps/desktop/package.json +16 -16
- package/agent/apps/desktop/public/apple-touch-icon.png +0 -0
- package/agent/apps/desktop/public/claw-mark.png +0 -0
- package/agent/apps/desktop/scripts/after-pack.cjs +1 -1
- package/agent/apps/desktop/scripts/set-exe-identity.cjs +2 -2
- package/agent/apps/desktop/scripts/test-desktop.mjs +3 -3
- package/agent/apps/desktop/src/app/chat/composer/controls.tsx +2 -0
- package/agent/apps/desktop/src/app/chat/composer/index.tsx +10 -0
- package/agent/apps/desktop/src/app/chat/composer/pod-credits.tsx +49 -0
- package/agent/apps/desktop/src/app/chat/index.tsx +1 -1
- package/agent/apps/desktop/src/app/chat/sidebar/index.tsx +4 -2
- package/agent/apps/desktop/src/app/desktop-controller.tsx +18 -0
- package/agent/apps/desktop/src/app/gateway/hooks/use-gateway-request.ts +1 -1
- package/agent/apps/desktop/src/app/messaging/index.tsx +5 -5
- package/agent/apps/desktop/src/app/routes.ts +9 -1
- package/agent/apps/desktop/src/app/session/hooks/use-message-stream.ts +3 -3
- package/agent/apps/desktop/src/app/settings/constants.ts +5 -5
- package/agent/apps/desktop/src/app/settings/model-settings.tsx +1 -1
- package/agent/apps/desktop/src/app/settings/providers-settings.tsx +46 -1
- package/agent/apps/desktop/src/app/settings/uninstall-section.tsx +5 -5
- package/agent/apps/desktop/src/app/types.ts +9 -1
- package/agent/apps/desktop/src/app/wallet/index.tsx +244 -0
- package/agent/apps/desktop/src/app/x402/index.tsx +162 -0
- package/agent/apps/desktop/src/components/assistant-ui/thread.tsx +1 -1
- package/agent/apps/desktop/src/components/brand-mark.tsx +2 -2
- package/agent/apps/desktop/src/components/chat/intro-copy.jsonl +6 -6
- package/agent/apps/desktop/src/components/chat/intro.tsx +4 -4
- package/agent/apps/desktop/src/components/model-picker.tsx +64 -4
- package/agent/apps/desktop/src/components/pod-setup-dialog.tsx +227 -0
- package/agent/apps/desktop/src/hermes.ts +109 -3
- package/agent/apps/desktop/src/i18n/en.ts +80 -78
- package/agent/apps/desktop/src/i18n/ja.ts +82 -82
- package/agent/apps/desktop/src/i18n/runtime.test.ts +2 -2
- package/agent/apps/desktop/src/i18n/zh-hant.ts +82 -82
- package/agent/apps/desktop/src/i18n/zh.ts +87 -87
- package/agent/apps/desktop/src/lib/desktop-fs.ts +1 -1
- package/agent/apps/desktop/src/lib/desktop-slash-commands.ts +4 -4
- package/agent/apps/desktop/src/store/composer.ts +7 -0
- package/agent/apps/desktop/src/store/onboarding.ts +5 -5
- package/agent/apps/desktop/src/themes/presets.ts +54 -54
- package/agent/cli.py +184 -10
- package/agent/hermes_cli/distribution.py +188 -8
- package/agent/hermes_cli/gui_uninstall.py +11 -6
- package/agent/hermes_cli/main.py +9 -4
- package/agent/hermes_cli/providers.py +29 -0
- package/agent/hermes_cli/web_server.py +180 -2
- package/agent/plugins/model-providers/usepod/__init__.py +7 -1
- package/agent/scripts/install.sh +3 -1
- package/agent/scripts/release.py +1 -0
- package/agent/web/src/components/ChatSidebar.tsx +5 -0
- package/agent/web/src/components/ModelPickerDialog.tsx +28 -1
- package/agent/web/src/components/PodCredits.tsx +57 -0
- package/agent/web/src/components/PodSetupDialog.tsx +240 -0
- package/agent/web/src/lib/api.ts +23 -0
- package/package.json +1 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hermes",
|
|
3
|
-
"productName": "
|
|
3
|
+
"productName": "Claw Agent",
|
|
4
4
|
"private": true,
|
|
5
5
|
"version": "0.15.1",
|
|
6
|
-
"description": "
|
|
7
|
-
"author": "Nous Research",
|
|
6
|
+
"description": "Claw Agent by ClawPump — native desktop app for Solana agents, built on Hermes Agent by Nous Research.",
|
|
7
|
+
"author": "ClawPump (built on Hermes by Nous Research)",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"main": "electron/main.cjs",
|
|
10
10
|
"engines": {
|
|
@@ -136,8 +136,8 @@
|
|
|
136
136
|
"build": {
|
|
137
137
|
"electronVersion": "40.10.2",
|
|
138
138
|
"appId": "com.nousresearch.hermes",
|
|
139
|
-
"productName": "
|
|
140
|
-
"executableName": "
|
|
139
|
+
"productName": "Claw Agent",
|
|
140
|
+
"executableName": "Claw Agent",
|
|
141
141
|
"protocols": [
|
|
142
142
|
{
|
|
143
143
|
"name": "Hermes Protocol",
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
]
|
|
147
147
|
}
|
|
148
148
|
],
|
|
149
|
-
"artifactName": "
|
|
149
|
+
"artifactName": "Claw-Agent-${version}-${os}-${arch}.${ext}",
|
|
150
150
|
"icon": "assets/icon",
|
|
151
151
|
"directories": {
|
|
152
152
|
"output": "release"
|
|
@@ -187,11 +187,11 @@
|
|
|
187
187
|
"entitlements": "electron/entitlements.mac.plist",
|
|
188
188
|
"entitlementsInherit": "electron/entitlements.mac.inherit.plist",
|
|
189
189
|
"extendInfo": {
|
|
190
|
-
"CFBundleDisplayName": "
|
|
191
|
-
"CFBundleExecutable": "
|
|
192
|
-
"CFBundleName": "
|
|
193
|
-
"NSAudioCaptureUsageDescription": "
|
|
194
|
-
"NSMicrophoneUsageDescription": "
|
|
190
|
+
"CFBundleDisplayName": "Claw Agent",
|
|
191
|
+
"CFBundleExecutable": "Claw Agent",
|
|
192
|
+
"CFBundleName": "Claw Agent",
|
|
193
|
+
"NSAudioCaptureUsageDescription": "Claw Agent uses audio capture for voice conversations.",
|
|
194
|
+
"NSMicrophoneUsageDescription": "Claw Agent uses the microphone for voice input and voice conversations."
|
|
195
195
|
},
|
|
196
196
|
"gatekeeperAssess": false,
|
|
197
197
|
"hardenedRuntime": true,
|
|
@@ -201,7 +201,7 @@
|
|
|
201
201
|
]
|
|
202
202
|
},
|
|
203
203
|
"dmg": {
|
|
204
|
-
"title": "Install
|
|
204
|
+
"title": "Install Claw Agent",
|
|
205
205
|
"backgroundColor": "#f5f5f7",
|
|
206
206
|
"iconSize": 96,
|
|
207
207
|
"window": {
|
|
@@ -223,7 +223,7 @@
|
|
|
223
223
|
]
|
|
224
224
|
},
|
|
225
225
|
"win": {
|
|
226
|
-
"legalTrademarks": "
|
|
226
|
+
"legalTrademarks": "Claw Agent",
|
|
227
227
|
"target": [
|
|
228
228
|
"nsis",
|
|
229
229
|
"msi"
|
|
@@ -233,7 +233,7 @@
|
|
|
233
233
|
"linux": {
|
|
234
234
|
"category": "Development",
|
|
235
235
|
"maintainer": "Nous Research <support@nousresearch.com>",
|
|
236
|
-
"synopsis": "
|
|
236
|
+
"synopsis": "Claw Agent by ClawPump — Solana agents desktop app, built on Hermes.",
|
|
237
237
|
"target": [
|
|
238
238
|
"AppImage",
|
|
239
239
|
"deb",
|
|
@@ -244,8 +244,8 @@
|
|
|
244
244
|
"oneClick": false,
|
|
245
245
|
"allowToChangeInstallationDirectory": true,
|
|
246
246
|
"perMachine": false,
|
|
247
|
-
"shortcutName": "
|
|
248
|
-
"uninstallDisplayName": "
|
|
247
|
+
"shortcutName": "Claw Agent",
|
|
248
|
+
"uninstallDisplayName": "Claw Agent",
|
|
249
249
|
"warningsAsErrors": false
|
|
250
250
|
}
|
|
251
251
|
}
|
|
Binary file
|
|
Binary file
|
|
@@ -28,7 +28,7 @@ exports.default = async function afterPack(context) {
|
|
|
28
28
|
return
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
const productName = context.packager?.appInfo?.productFilename || '
|
|
31
|
+
const productName = context.packager?.appInfo?.productFilename || 'Claw Agent'
|
|
32
32
|
const exe = path.join(context.appOutDir, `${productName}.exe`)
|
|
33
33
|
const desktopRoot = path.resolve(__dirname, '..')
|
|
34
34
|
|
|
@@ -68,8 +68,8 @@ async function stampExeIdentity(exe, desktopRoot = path.resolve(__dirname, '..')
|
|
|
68
68
|
await rcedit(exe, {
|
|
69
69
|
icon,
|
|
70
70
|
'version-string': {
|
|
71
|
-
ProductName: '
|
|
72
|
-
FileDescription: '
|
|
71
|
+
ProductName: 'Claw Agent',
|
|
72
|
+
FileDescription: 'Claw Agent',
|
|
73
73
|
CompanyName: 'Nous Research',
|
|
74
74
|
LegalCopyright: 'Copyright (c) 2026 Nous Research'
|
|
75
75
|
}
|
|
@@ -18,10 +18,10 @@ const PLATFORM = process.platform
|
|
|
18
18
|
// launch via install.ps1 / install.sh, per the Phase 1 thin-installer flow).
|
|
19
19
|
const APP = (() => {
|
|
20
20
|
if (PLATFORM === 'darwin') {
|
|
21
|
-
const appPath = path.join(RELEASE_ROOT, `mac-${ARCH}`, '
|
|
21
|
+
const appPath = path.join(RELEASE_ROOT, `mac-${ARCH}`, 'Claw Agent.app')
|
|
22
22
|
return {
|
|
23
23
|
appPath,
|
|
24
|
-
binary: path.join(appPath, 'Contents', 'MacOS', '
|
|
24
|
+
binary: path.join(appPath, 'Contents', 'MacOS', 'Claw Agent'),
|
|
25
25
|
resourcesPath: path.join(appPath, 'Contents', 'Resources'),
|
|
26
26
|
asarPath: path.join(appPath, 'Contents', 'Resources', 'app.asar'),
|
|
27
27
|
unpackedDistIndex: path.join(appPath, 'Contents', 'Resources', 'app.asar.unpacked', 'dist', 'index.html')
|
|
@@ -31,7 +31,7 @@ const APP = (() => {
|
|
|
31
31
|
const unpacked = path.join(RELEASE_ROOT, 'win-unpacked')
|
|
32
32
|
return {
|
|
33
33
|
appPath: unpacked,
|
|
34
|
-
binary: path.join(unpacked, '
|
|
34
|
+
binary: path.join(unpacked, 'Claw Agent.exe'),
|
|
35
35
|
resourcesPath: path.join(unpacked, 'resources'),
|
|
36
36
|
asarPath: path.join(unpacked, 'resources', 'app.asar'),
|
|
37
37
|
unpackedDistIndex: path.join(unpacked, 'resources', 'app.asar.unpacked', 'dist', 'index.html')
|
|
@@ -10,6 +10,7 @@ import { cn } from '@/lib/utils'
|
|
|
10
10
|
|
|
11
11
|
import type { ConversationStatus } from './hooks/use-voice-conversation'
|
|
12
12
|
import { ModelPill } from './model-pill'
|
|
13
|
+
import { PodCredits } from './pod-credits'
|
|
13
14
|
import type { ChatBarState, VoiceStatus } from './types'
|
|
14
15
|
|
|
15
16
|
export const ICON_BTN = 'size-(--composer-control-size) shrink-0 rounded-md'
|
|
@@ -83,6 +84,7 @@ export function ComposerControls({
|
|
|
83
84
|
|
|
84
85
|
return (
|
|
85
86
|
<div className="ml-auto flex shrink-0 items-center gap-(--composer-control-gap)">
|
|
87
|
+
<PodCredits provider={state.model.provider} />
|
|
86
88
|
<ModelPill disabled={disabled} model={state.model} />
|
|
87
89
|
{/* While the agent runs and the user is typing, steer takes over the mic's
|
|
88
90
|
slot rather than crowding the row with an extra button. */}
|
|
@@ -27,6 +27,7 @@ import { triggerHaptic } from '@/lib/haptics'
|
|
|
27
27
|
import { cn } from '@/lib/utils'
|
|
28
28
|
import {
|
|
29
29
|
$composerAttachments,
|
|
30
|
+
$pendingChatPrompt,
|
|
30
31
|
clearComposerAttachments,
|
|
31
32
|
clearSessionDraft,
|
|
32
33
|
type ComposerAttachment,
|
|
@@ -1228,6 +1229,15 @@ export function ChatBar({
|
|
|
1228
1229
|
const { attachments, text } = takeSessionDraft(activeQueueSessionKey)
|
|
1229
1230
|
loadIntoComposer(text, attachments)
|
|
1230
1231
|
|
|
1232
|
+
// One-shot prompt from a "send to chat" flow (x402 "Use in chat", wallet
|
|
1233
|
+
// "Tokenize") that navigated to a fresh chat. Drain it AFTER the session
|
|
1234
|
+
// draft load so it isn't overwritten; append if there's already a draft.
|
|
1235
|
+
const pending = $pendingChatPrompt.get()
|
|
1236
|
+
if (pending) {
|
|
1237
|
+
$pendingChatPrompt.set(null)
|
|
1238
|
+
loadIntoComposer(text.trim() ? `${text.trimEnd()}\n\n${pending}` : pending, attachments)
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1231
1241
|
return () => {
|
|
1232
1242
|
const editing = queueEditRef.current
|
|
1233
1243
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { useQuery } from '@tanstack/react-query'
|
|
2
|
+
|
|
3
|
+
import { getPodStatus } from '@/hermes'
|
|
4
|
+
import { Tip } from '@/components/ui/tooltip'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Compact "Pod $X.XX" credits pill, shown in the composer control row only when
|
|
8
|
+
* the active provider is UsePod (Pod). Reads the live pod balance from
|
|
9
|
+
* /api/clawpump/pod/status. Click-through is intentionally none — it's a glance
|
|
10
|
+
* indicator; top-ups go through the Set up Pod flow.
|
|
11
|
+
*/
|
|
12
|
+
export function PodCredits({ provider }: { provider: string }) {
|
|
13
|
+
const isPod = provider === 'usepod'
|
|
14
|
+
const status = useQuery({
|
|
15
|
+
queryKey: ['pod-status'],
|
|
16
|
+
queryFn: getPodStatus,
|
|
17
|
+
enabled: isPod,
|
|
18
|
+
staleTime: 30_000,
|
|
19
|
+
refetchInterval: 60_000,
|
|
20
|
+
// Keep the last result while a refetch is in flight so the credits readout
|
|
21
|
+
// never flickers from "$0.94" back to a bare "Pod".
|
|
22
|
+
placeholderData: prev => prev
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
if (!isPod || !status.data?.connected) {
|
|
26
|
+
return null
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const bal = status.data.balance_usdc
|
|
30
|
+
const low = bal != null && bal < 0.5
|
|
31
|
+
// bal is null only before the very first successful fetch (the backend caches
|
|
32
|
+
// the last good value thereafter) — show a loading dash, not a bare "Pod".
|
|
33
|
+
const text = bal != null ? `$${bal.toFixed(2)}` : '$…'
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<Tip label={bal != null ? `Pod credits: $${bal.toFixed(4)} USDC` : 'Pod connected — fetching balance…'}>
|
|
37
|
+
<span
|
|
38
|
+
className={`inline-flex shrink-0 items-center gap-1 rounded-md border px-1.5 py-0.5 text-[0.6875rem] font-medium ${
|
|
39
|
+
low
|
|
40
|
+
? 'border-amber-500/40 bg-amber-500/10 text-amber-400'
|
|
41
|
+
: 'border-emerald-500/30 bg-emerald-500/10 text-emerald-400'
|
|
42
|
+
}`}
|
|
43
|
+
>
|
|
44
|
+
<img alt="" className="size-3 rounded-sm" src="/claw-mark.png" />
|
|
45
|
+
{text}
|
|
46
|
+
</span>
|
|
47
|
+
</Tip>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
@@ -349,7 +349,7 @@ export function ChatView({
|
|
|
349
349
|
}
|
|
350
350
|
|
|
351
351
|
if (!gateway) {
|
|
352
|
-
throw new Error('
|
|
352
|
+
throw new Error('Claw Agent gateway unavailable')
|
|
353
353
|
}
|
|
354
354
|
|
|
355
355
|
return gateway.request<ModelOptionsResponse>('model.options', { session_id: activeSessionId })
|
|
@@ -95,7 +95,7 @@ import {
|
|
|
95
95
|
sessionPinId
|
|
96
96
|
} from '@/store/session'
|
|
97
97
|
|
|
98
|
-
import { type AppView, ARTIFACTS_ROUTE, MESSAGING_ROUTE, SKILLS_ROUTE } from '../../routes'
|
|
98
|
+
import { type AppView, ARTIFACTS_ROUTE, MESSAGING_ROUTE, SKILLS_ROUTE, WALLET_ROUTE, X402_ROUTE } from '../../routes'
|
|
99
99
|
import { SidebarPanelLabel } from '../../shell/sidebar-label'
|
|
100
100
|
import type { SidebarNavItem } from '../../types'
|
|
101
101
|
|
|
@@ -131,7 +131,9 @@ const SIDEBAR_NAV: SidebarNavItem[] = [
|
|
|
131
131
|
route: SKILLS_ROUTE
|
|
132
132
|
},
|
|
133
133
|
{ id: 'messaging', label: '', icon: props => <Codicon name="comment" {...props} />, route: MESSAGING_ROUTE },
|
|
134
|
-
{ id: 'artifacts', label: '', icon: props => <Codicon name="files" {...props} />, route: ARTIFACTS_ROUTE }
|
|
134
|
+
{ id: 'artifacts', label: '', icon: props => <Codicon name="files" {...props} />, route: ARTIFACTS_ROUTE },
|
|
135
|
+
{ id: 'wallet', label: 'Wallet', icon: props => <Codicon name="credit-card" {...props} />, route: WALLET_ROUTE },
|
|
136
|
+
{ id: 'x402', label: 'x402', icon: props => <Codicon name="zap" {...props} />, route: X402_ROUTE }
|
|
135
137
|
]
|
|
136
138
|
|
|
137
139
|
const WORKSPACE_PAGE = 5
|
|
@@ -137,6 +137,8 @@ const MessagingView = lazy(async () => ({ default: (await import('./messaging'))
|
|
|
137
137
|
const ProfilesView = lazy(async () => ({ default: (await import('./profiles')).ProfilesView }))
|
|
138
138
|
const SettingsView = lazy(async () => ({ default: (await import('./settings')).SettingsView }))
|
|
139
139
|
const SkillsView = lazy(async () => ({ default: (await import('./skills')).SkillsView }))
|
|
140
|
+
const WalletView = lazy(async () => ({ default: (await import('./wallet')).WalletView }))
|
|
141
|
+
const X402View = lazy(async () => ({ default: (await import('./x402')).X402View }))
|
|
140
142
|
|
|
141
143
|
// Latest cron-job sessions surfaced in the collapsed "Cron jobs" section. The
|
|
142
144
|
// Cron sessions are written by a background scheduler tick (the desktop
|
|
@@ -1185,6 +1187,22 @@ export function DesktopController() {
|
|
|
1185
1187
|
}
|
|
1186
1188
|
path="artifacts"
|
|
1187
1189
|
/>
|
|
1190
|
+
<Route
|
|
1191
|
+
element={
|
|
1192
|
+
<Suspense fallback={null}>
|
|
1193
|
+
<WalletView setStatusbarItemGroup={setStatusbarItemGroup} />
|
|
1194
|
+
</Suspense>
|
|
1195
|
+
}
|
|
1196
|
+
path="wallet"
|
|
1197
|
+
/>
|
|
1198
|
+
<Route
|
|
1199
|
+
element={
|
|
1200
|
+
<Suspense fallback={null}>
|
|
1201
|
+
<X402View setStatusbarItemGroup={setStatusbarItemGroup} />
|
|
1202
|
+
</Suspense>
|
|
1203
|
+
}
|
|
1204
|
+
path="x402"
|
|
1205
|
+
/>
|
|
1188
1206
|
<Route element={null} path="cron" />
|
|
1189
1207
|
<Route element={null} path="profiles" />
|
|
1190
1208
|
<Route element={null} path="settings" />
|
|
@@ -514,11 +514,11 @@ const PLATFORM_INTRO: Record<string, string> = {
|
|
|
514
514
|
'On your Mattermost server, create a bot account or personal access token, then paste the server URL and token here.',
|
|
515
515
|
matrix: 'Sign in to your homeserver with the bot account, then copy the access token, user ID, and homeserver URL.',
|
|
516
516
|
signal:
|
|
517
|
-
'Run a signal-cli REST bridge somewhere reachable, then point
|
|
517
|
+
'Run a signal-cli REST bridge somewhere reachable, then point Claw Agent at the URL and the registered phone number.',
|
|
518
518
|
whatsapp:
|
|
519
|
-
'Start the WhatsApp bridge that ships with
|
|
519
|
+
'Start the WhatsApp bridge that ships with Claw Agent, scan the QR code on first run, then enable the platform.',
|
|
520
520
|
bluebubbles:
|
|
521
|
-
'Run BlueBubbles Server on a Mac with iMessage, expose its API, then point
|
|
521
|
+
'Run BlueBubbles Server on a Mac with iMessage, expose its API, then point Claw Agent at the URL with the server password.',
|
|
522
522
|
homeassistant:
|
|
523
523
|
'In Home Assistant, open your profile and create a long-lived access token. Paste it here along with your HA URL.',
|
|
524
524
|
email:
|
|
@@ -532,10 +532,10 @@ const PLATFORM_INTRO: Record<string, string> = {
|
|
|
532
532
|
wecom_callback:
|
|
533
533
|
'Set up a WeCom self-built app, expose its callback URL, and provide the corp ID, secret, agent ID, and AES key.',
|
|
534
534
|
weixin:
|
|
535
|
-
'Run `hermes gateway setup`, select Weixin, then scan and confirm the QR code with a personal WeChat account.
|
|
535
|
+
'Run `hermes gateway setup`, select Weixin, then scan and confirm the QR code with a personal WeChat account. Claw Agent connects through Tencent\'s iLink Bot API and saves the credentials.',
|
|
536
536
|
qqbot: 'Register an app on the QQ Open Platform (q.qq.com) and copy the App ID and Client Secret.',
|
|
537
537
|
api_server:
|
|
538
|
-
'Expose
|
|
538
|
+
'Expose Claw Agent as an OpenAI-compatible API. Set an auth key, then point Open WebUI / LobeChat / etc. at the host:port.',
|
|
539
539
|
webhook:
|
|
540
540
|
'Run an HTTP server that other tools (GitHub, GitLab, custom apps) can POST to. Use the secret to verify signatures.'
|
|
541
541
|
}
|
|
@@ -8,6 +8,8 @@ export const ARTIFACTS_ROUTE = '/artifacts'
|
|
|
8
8
|
export const CRON_ROUTE = '/cron'
|
|
9
9
|
export const PROFILES_ROUTE = '/profiles'
|
|
10
10
|
export const AGENTS_ROUTE = '/agents'
|
|
11
|
+
export const WALLET_ROUTE = '/wallet'
|
|
12
|
+
export const X402_ROUTE = '/x402'
|
|
11
13
|
|
|
12
14
|
export type AppView =
|
|
13
15
|
| 'agents'
|
|
@@ -19,6 +21,8 @@ export type AppView =
|
|
|
19
21
|
| 'profiles'
|
|
20
22
|
| 'settings'
|
|
21
23
|
| 'skills'
|
|
24
|
+
| 'wallet'
|
|
25
|
+
| 'x402'
|
|
22
26
|
|
|
23
27
|
export type AppRouteId =
|
|
24
28
|
| 'agents'
|
|
@@ -30,6 +34,8 @@ export type AppRouteId =
|
|
|
30
34
|
| 'profiles'
|
|
31
35
|
| 'settings'
|
|
32
36
|
| 'skills'
|
|
37
|
+
| 'wallet'
|
|
38
|
+
| 'x402'
|
|
33
39
|
|
|
34
40
|
export interface AppRoute {
|
|
35
41
|
id: AppRouteId
|
|
@@ -46,7 +52,9 @@ export const APP_ROUTES = [
|
|
|
46
52
|
{ id: 'artifacts', path: ARTIFACTS_ROUTE, view: 'artifacts' },
|
|
47
53
|
{ id: 'cron', path: CRON_ROUTE, view: 'cron' },
|
|
48
54
|
{ id: 'profiles', path: PROFILES_ROUTE, view: 'profiles' },
|
|
49
|
-
{ id: 'agents', path: AGENTS_ROUTE, view: 'agents' }
|
|
55
|
+
{ id: 'agents', path: AGENTS_ROUTE, view: 'agents' },
|
|
56
|
+
{ id: 'wallet', path: WALLET_ROUTE, view: 'wallet' },
|
|
57
|
+
{ id: 'x402', path: X402_ROUTE, view: 'x402' }
|
|
50
58
|
] as const satisfies readonly AppRoute[]
|
|
51
59
|
|
|
52
60
|
const APP_VIEW_BY_PATH = new Map<string, AppView>(APP_ROUTES.map(route => [route.path, route.view]))
|
|
@@ -671,7 +671,7 @@ export function useMessageStream({
|
|
|
671
671
|
const streamId = state.streamId ?? `assistant-error-${Date.now()}`
|
|
672
672
|
const groupId = state.pendingBranchGroup ?? undefined
|
|
673
673
|
const prev = state.messages
|
|
674
|
-
const error = errorMessage.trim() || '
|
|
674
|
+
const error = errorMessage.trim() || 'Claw Agent reported an error'
|
|
675
675
|
|
|
676
676
|
const nextMessages = prev.some(m => m.id === streamId)
|
|
677
677
|
? prev.map(message =>
|
|
@@ -1108,7 +1108,7 @@ export function useMessageStream({
|
|
|
1108
1108
|
}))
|
|
1109
1109
|
}
|
|
1110
1110
|
} else if (event.type === 'error') {
|
|
1111
|
-
const errorMessage = payload?.message || '
|
|
1111
|
+
const errorMessage = payload?.message || 'Claw Agent reported an error'
|
|
1112
1112
|
const looksLikeProviderSetup = isProviderSetupErrorMessage(errorMessage)
|
|
1113
1113
|
|
|
1114
1114
|
// A turn that errors out has also ended — drop any open blocking prompt
|
|
@@ -1137,7 +1137,7 @@ export function useMessageStream({
|
|
|
1137
1137
|
notify({
|
|
1138
1138
|
id: `gateway-error:${errorMessage}`,
|
|
1139
1139
|
kind: 'error',
|
|
1140
|
-
title: '
|
|
1140
|
+
title: 'Claw Agent error',
|
|
1141
1141
|
message: errorMessage
|
|
1142
1142
|
})
|
|
1143
1143
|
}
|
|
@@ -435,10 +435,10 @@ export const FIELD_DESCRIPTIONS: Record<string, string> = defineFieldCopy({
|
|
|
435
435
|
personality: 'Default assistant style for new sessions.',
|
|
436
436
|
showReasoning: 'Show reasoning sections when the backend provides them.'
|
|
437
437
|
},
|
|
438
|
-
timezone: 'Used when
|
|
438
|
+
timezone: 'Used when Claw Agent needs local time context. Blank uses the system timezone.',
|
|
439
439
|
agent: {
|
|
440
440
|
imageInputMode: 'Controls how image attachments are sent to the model.',
|
|
441
|
-
maxTurns: 'Upper bound for tool-calling turns before
|
|
441
|
+
maxTurns: 'Upper bound for tool-calling turns before Claw Agent stops a run.'
|
|
442
442
|
},
|
|
443
443
|
terminal: {
|
|
444
444
|
cwd: 'Default project folder for tool and terminal work.',
|
|
@@ -452,9 +452,9 @@ export const FIELD_DESCRIPTIONS: Record<string, string> = defineFieldCopy({
|
|
|
452
452
|
codeExecution: {
|
|
453
453
|
mode: 'How strictly code execution is scoped to the current project.'
|
|
454
454
|
},
|
|
455
|
-
fileReadMaxChars: 'Maximum characters
|
|
455
|
+
fileReadMaxChars: 'Maximum characters Claw Agent can read from one file request.',
|
|
456
456
|
approvals: {
|
|
457
|
-
mode: 'How
|
|
457
|
+
mode: 'How Claw Agent handles commands that need explicit approval.',
|
|
458
458
|
timeout: 'How long approval prompts wait before timing out.'
|
|
459
459
|
},
|
|
460
460
|
security: {
|
|
@@ -493,7 +493,7 @@ export const FIELD_DESCRIPTIONS: Record<string, string> = defineFieldCopy({
|
|
|
493
493
|
},
|
|
494
494
|
updates: {
|
|
495
495
|
nonInteractiveLocalChanges:
|
|
496
|
-
'When
|
|
496
|
+
'When Claw Agent updates itself from the app (no terminal prompt), keep local source edits (stash) or throw them away (discard). Terminal updates always ask.'
|
|
497
497
|
}
|
|
498
498
|
})
|
|
499
499
|
|
|
@@ -489,7 +489,7 @@ export function ModelSettings({ onMainModelChanged }: ModelSettingsProps) {
|
|
|
489
489
|
<p className="mt-2 text-xs text-muted-foreground">
|
|
490
490
|
{selectedProviderRow?.auth_type === 'api_key'
|
|
491
491
|
? `${selectedProviderRow?.name} needs an API key — set it up to choose a model.`
|
|
492
|
-
: `${selectedProviderRow?.name} signs in through your browser —
|
|
492
|
+
: `${selectedProviderRow?.name} signs in through your browser — Claw Agent runs the flow for you.`}
|
|
493
493
|
</p>
|
|
494
494
|
)}
|
|
495
495
|
{config && mainModel && (reasoningSupported || fastSupported) && (
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useStore } from '@nanostores/react'
|
|
2
|
+
import { useQuery } from '@tanstack/react-query'
|
|
2
3
|
import type { ReactNode } from 'react'
|
|
3
4
|
import { useCallback, useEffect, useMemo, useState } from 'react'
|
|
4
5
|
|
|
@@ -11,9 +12,10 @@ import {
|
|
|
11
12
|
providerTitle,
|
|
12
13
|
sortProviders
|
|
13
14
|
} from '@/components/desktop-onboarding-overlay'
|
|
15
|
+
import { PodSetupDialog } from '@/components/pod-setup-dialog'
|
|
14
16
|
import { Button } from '@/components/ui/button'
|
|
15
17
|
import { SearchField } from '@/components/ui/search-field'
|
|
16
|
-
import { disconnectOAuthProvider, listOAuthProviders } from '@/hermes'
|
|
18
|
+
import { disconnectOAuthProvider, getPodStatus, listOAuthProviders } from '@/hermes'
|
|
17
19
|
import { useI18n } from '@/i18n'
|
|
18
20
|
import { Check, ChevronDown, ChevronRight, KeyRound, Loader2, Terminal, Trash2 } from '@/lib/icons'
|
|
19
21
|
import { cn } from '@/lib/utils'
|
|
@@ -299,6 +301,12 @@ export function ProvidersSettings({ onClose, onViewChange, view }: ProvidersSett
|
|
|
299
301
|
const { rowProps, vars } = useEnvCredentials()
|
|
300
302
|
const [oauthProviders, setOauthProviders] = useState<OAuthProvider[]>([])
|
|
301
303
|
const [openProvider, setOpenProvider] = useState<null | string>(null)
|
|
304
|
+
// ClawPump: "Pod" is set up by funding it from an agent wallet, not an OAuth
|
|
305
|
+
// sign-in — so it gets a promoted card in Accounts that opens the fund dialog.
|
|
306
|
+
const [podOpen, setPodOpen] = useState(false)
|
|
307
|
+
const podStatus = useQuery({ queryKey: ['pod-status'], queryFn: getPodStatus, staleTime: 30_000 })
|
|
308
|
+
const podConnected = podStatus.data?.connected ?? false
|
|
309
|
+
const podBalance = podStatus.data?.balance_usdc
|
|
302
310
|
const [disconnecting, setDisconnecting] = useState<null | string>(null)
|
|
303
311
|
// Free-text filter for the API-keys view (provider name / env-var key / desc).
|
|
304
312
|
const [keyQuery, setKeyQuery] = useState('')
|
|
@@ -443,6 +451,35 @@ export function ProvidersSettings({ onClose, onViewChange, view }: ProvidersSett
|
|
|
443
451
|
|
|
444
452
|
return (
|
|
445
453
|
<SettingsContent>
|
|
454
|
+
<button
|
|
455
|
+
className="mb-4 flex w-full items-center gap-3 rounded-lg border border-border bg-card px-3 py-2.5 text-left transition-colors hover:border-primary/50"
|
|
456
|
+
onClick={() => setPodOpen(true)}
|
|
457
|
+
type="button"
|
|
458
|
+
>
|
|
459
|
+
<span className="grid size-9 shrink-0 place-items-center rounded-md bg-primary/15">
|
|
460
|
+
<img alt="" className="size-5 rounded-sm" src="/claw-mark.png" />
|
|
461
|
+
</span>
|
|
462
|
+
<span className="flex min-w-0 flex-1 flex-col">
|
|
463
|
+
<span className="text-sm font-semibold">Pod</span>
|
|
464
|
+
<span className="truncate text-xs text-muted-foreground">
|
|
465
|
+
{podConnected
|
|
466
|
+
? podBalance != null
|
|
467
|
+
? `Connected · $${podBalance.toFixed(2)} USDC left · click to top up`
|
|
468
|
+
: 'Connected — your inference provider'
|
|
469
|
+
: 'Pay-as-you-go inference — fund from your ClawPump wallet'}
|
|
470
|
+
</span>
|
|
471
|
+
</span>
|
|
472
|
+
{podConnected ? (
|
|
473
|
+
<span className="shrink-0 rounded-md border border-emerald-500/40 px-2 py-1 text-[0.62rem] font-medium uppercase tracking-wide text-emerald-400">
|
|
474
|
+
✓ Connected
|
|
475
|
+
</span>
|
|
476
|
+
) : (
|
|
477
|
+
<span className="shrink-0 rounded-md border border-primary/40 px-2 py-1 text-[0.62rem] font-medium uppercase tracking-wide text-primary">
|
|
478
|
+
Set up
|
|
479
|
+
</span>
|
|
480
|
+
)}
|
|
481
|
+
</button>
|
|
482
|
+
|
|
446
483
|
<OAuthPicker
|
|
447
484
|
disconnecting={disconnecting}
|
|
448
485
|
onDisconnect={provider => void handleDisconnect(provider)}
|
|
@@ -450,6 +487,14 @@ export function ProvidersSettings({ onClose, onViewChange, view }: ProvidersSett
|
|
|
450
487
|
onWantApiKey={() => onViewChange('keys')}
|
|
451
488
|
providers={oauthProviders}
|
|
452
489
|
/>
|
|
490
|
+
|
|
491
|
+
<PodSetupDialog
|
|
492
|
+
onOpenChange={setPodOpen}
|
|
493
|
+
// The dialog shows its own "Pod ready" view + toast and its Done button
|
|
494
|
+
// closes it; nothing extra to do here.
|
|
495
|
+
onProvisioned={() => undefined}
|
|
496
|
+
open={podOpen}
|
|
497
|
+
/>
|
|
453
498
|
</SettingsContent>
|
|
454
499
|
)
|
|
455
500
|
}
|
|
@@ -21,22 +21,22 @@ const OPTIONS: ModeOption[] = [
|
|
|
21
21
|
{
|
|
22
22
|
mode: 'gui',
|
|
23
23
|
title: 'Uninstall Chat GUI only',
|
|
24
|
-
description: 'Remove this desktop app. The
|
|
24
|
+
description: 'Remove this desktop app. The Claw Agent, your config, and chats all stay.',
|
|
25
25
|
consequence: 'the desktop Chat GUI (this app and its data)',
|
|
26
26
|
needsAgent: false
|
|
27
27
|
},
|
|
28
28
|
{
|
|
29
29
|
mode: 'lite',
|
|
30
30
|
title: 'Uninstall GUI + agent, keep my data',
|
|
31
|
-
description: 'Remove the app and the
|
|
32
|
-
consequence: 'the Chat GUI and the
|
|
31
|
+
description: 'Remove the app and the Claw Agent, but keep config, chats, and secrets for a future reinstall.',
|
|
32
|
+
consequence: 'the Chat GUI and the Claw Agent (config, chats, and secrets are kept)',
|
|
33
33
|
needsAgent: true
|
|
34
34
|
},
|
|
35
35
|
{
|
|
36
36
|
mode: 'full',
|
|
37
37
|
title: 'Uninstall everything',
|
|
38
38
|
description: 'Remove the app, the agent, and all user data — config, chats, scheduled jobs, secrets, logs.',
|
|
39
|
-
consequence: 'EVERYTHING — the Chat GUI, the
|
|
39
|
+
consequence: 'EVERYTHING — the Chat GUI, the Claw Agent, and all of your config, chats, secrets, and logs',
|
|
40
40
|
// full removes the agent (and user data), so it's an agent-removing option:
|
|
41
41
|
// hide it on a lite client with no local agent, same as lite. A lite client
|
|
42
42
|
// connecting to a remote backend has no local agent OR local user data the
|
|
@@ -151,7 +151,7 @@ export function UninstallSection() {
|
|
|
151
151
|
</div>
|
|
152
152
|
) : (
|
|
153
153
|
<div className="flex flex-col gap-2">
|
|
154
|
-
<p className="text-sm font-medium">Uninstall
|
|
154
|
+
<p className="text-sm font-medium">Uninstall Claw Agent</p>
|
|
155
155
|
<p className="text-xs text-muted-foreground">
|
|
156
156
|
Choose how much to remove. The app closes to finish the job; reopen the installer any time to come back.
|
|
157
157
|
</p>
|
|
@@ -122,7 +122,15 @@ export type CommandDispatchResponse =
|
|
|
122
122
|
| SendCommandDispatchResponse
|
|
123
123
|
| PrefillCommandDispatchResponse
|
|
124
124
|
|
|
125
|
-
export type SidebarNavId =
|
|
125
|
+
export type SidebarNavId =
|
|
126
|
+
| 'artifacts'
|
|
127
|
+
| 'command-center'
|
|
128
|
+
| 'messaging'
|
|
129
|
+
| 'new-session'
|
|
130
|
+
| 'settings'
|
|
131
|
+
| 'skills'
|
|
132
|
+
| 'wallet'
|
|
133
|
+
| 'x402'
|
|
126
134
|
|
|
127
135
|
export interface SidebarNavItem {
|
|
128
136
|
id: SidebarNavId
|