@swarmclawai/swarmclaw 1.3.3 → 1.3.4
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 +4 -0
- package/package.json +1 -1
- package/src/lib/providers/cli-utils.ts +3 -4
- package/src/lib/providers/index.ts +12 -22
- package/src/lib/providers/openclaw.ts +1 -2
- package/src/lib/server/agents/subagent-swarm.ts +2 -7
- package/src/lib/server/chat-execution/chat-turn-finalization.ts +2 -5
- package/src/lib/server/chat-execution/prompt-builder.ts +4 -6
- package/src/lib/server/connectors/openclaw.ts +1 -2
- package/src/lib/server/provider-health.ts +2 -7
- package/src/lib/server/storage.ts +1 -1
package/README.md
CHANGED
|
@@ -204,6 +204,10 @@ Read the full setup guide in [`SWARMDOCK.md`](./SWARMDOCK.md), browse the public
|
|
|
204
204
|
|
|
205
205
|
## Release Notes
|
|
206
206
|
|
|
207
|
+
### v1.3.4 Highlights
|
|
208
|
+
|
|
209
|
+
- **Bug fix — custom provider loading under Turbopack (#32)**: converted all CommonJS `require()` calls across the codebase to ES module imports, fixing "Unknown provider: custom-\<id\>" errors and other potential Turbopack compatibility issues. Affected modules: providers, provider health, subagent swarm, prompt builder, chat finalization, CLI utils, and OpenClaw connectors. Thanks to @psywolf85 for the initial fix.
|
|
210
|
+
|
|
207
211
|
### v1.3.3 Highlights
|
|
208
212
|
|
|
209
213
|
- **Bug fix — stale connector status after auto-restart (#31)**: connectors that auto-restart via the daemon health monitor now show "Starting" instead of a stale "Stopped" or "Error" status in the UI until the daemon reports runtime state. Added `starting` to the `ConnectorStatus` type and updated both the connector list and detail views.
|
package/package.json
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import fs from 'fs'
|
|
10
10
|
import os from 'os'
|
|
11
|
+
import { findBinaryOnPath } from '../server/session-tools/context'
|
|
11
12
|
import path from 'path'
|
|
12
13
|
import { spawnSync, type ChildProcess } from 'child_process'
|
|
13
14
|
import { log } from '../server/logger'
|
|
@@ -63,10 +64,8 @@ function getNvmBinaryPaths(name: string): string[] {
|
|
|
63
64
|
* then falls back to known paths + nvm paths.
|
|
64
65
|
*/
|
|
65
66
|
export function resolveCliBinary(name: string, extraPaths?: string[]): string | null {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const { findBinaryOnPath } = require('../server/session-tools/context')
|
|
69
|
-
const fromPath = findBinaryOnPath(name) as string | null
|
|
67
|
+
const fromPath = findBinaryOnPath(name)
|
|
68
|
+
|
|
70
69
|
if (fromPath) return fromPath
|
|
71
70
|
|
|
72
71
|
const paths = [
|
|
@@ -11,6 +11,8 @@ import { errorMessage, sleep, jitteredBackoff } from '@/lib/shared-utils'
|
|
|
11
11
|
import { classifyProviderError } from './error-classification'
|
|
12
12
|
import { log } from '@/lib/server/logger'
|
|
13
13
|
import type { ProviderInfo, ProviderConfig as CustomProviderConfig, ProviderType, ProviderId } from '../../types'
|
|
14
|
+
import { loadProviderConfigs, loadModelOverrides, loadStoredItem, loadCredentials, decryptKey } from '@/lib/server/storage'
|
|
15
|
+
import { getExtensionManager } from '@/lib/server/extensions'
|
|
14
16
|
|
|
15
17
|
const TAG = 'providers'
|
|
16
18
|
|
|
@@ -289,8 +291,6 @@ export const PROVIDERS: Record<string, BuiltinProviderConfig> = {
|
|
|
289
291
|
/** Merge built-in providers with custom providers from storage */
|
|
290
292
|
function getCustomProviders(): Record<string, CustomProviderConfig> {
|
|
291
293
|
try {
|
|
292
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
293
|
-
const { loadProviderConfigs } = require('../server/storage') as typeof import('@/lib/server/storage')
|
|
294
294
|
const configs = loadProviderConfigs() as Record<string, CustomProviderConfig>
|
|
295
295
|
return Object.fromEntries(
|
|
296
296
|
Object.entries(configs).filter(([, config]) => config?.type === 'custom'),
|
|
@@ -303,8 +303,6 @@ function getCustomProviders(): Record<string, CustomProviderConfig> {
|
|
|
303
303
|
|
|
304
304
|
function getModelOverrides(): Record<string, string[]> {
|
|
305
305
|
try {
|
|
306
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
307
|
-
const { loadModelOverrides } = require('../server/storage') as typeof import('@/lib/server/storage')
|
|
308
306
|
return loadModelOverrides()
|
|
309
307
|
} catch {
|
|
310
308
|
return {}
|
|
@@ -342,17 +340,15 @@ export function getProviderList(): ProviderInfo[] {
|
|
|
342
340
|
|
|
343
341
|
let extensionProviders: ProviderInfo[] = []
|
|
344
342
|
try {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
requiresEndpoint: Boolean(p.requiresEndpoint),
|
|
355
|
-
defaultEndpoint: p.defaultEndpoint as string | undefined,
|
|
343
|
+
extensionProviders = getExtensionManager().getProviders().map((p) => ({
|
|
344
|
+
id: p.id as ProviderId,
|
|
345
|
+
name: p.name,
|
|
346
|
+
models: p.models,
|
|
347
|
+
defaultModels: p.models,
|
|
348
|
+
supportsModelDiscovery: false,
|
|
349
|
+
requiresApiKey: p.requiresApiKey,
|
|
350
|
+
requiresEndpoint: p.requiresEndpoint,
|
|
351
|
+
defaultEndpoint: p.defaultEndpoint,
|
|
356
352
|
}))
|
|
357
353
|
} catch { /* ignore if running somewhere extensions aren't available */ }
|
|
358
354
|
|
|
@@ -391,8 +387,6 @@ export function getProvider(id: string): BuiltinProviderConfig | null {
|
|
|
391
387
|
// Fallback: direct single-item DB lookup for custom-* providers
|
|
392
388
|
if (id.startsWith('custom-') && !custom) {
|
|
393
389
|
try {
|
|
394
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
395
|
-
const { loadStoredItem } = require('../server/storage') as typeof import('@/lib/server/storage')
|
|
396
390
|
const directConfig = loadStoredItem('provider_configs', id) as CustomProviderConfig | null
|
|
397
391
|
if (directConfig?.type === 'custom' && directConfig.isEnabled) {
|
|
398
392
|
log.info(TAG, `Resolved custom provider '${id}' via direct DB lookup (batch load missed it)`)
|
|
@@ -405,10 +399,8 @@ export function getProvider(id: string): BuiltinProviderConfig | null {
|
|
|
405
399
|
|
|
406
400
|
// Check Extension Providers
|
|
407
401
|
try {
|
|
408
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
409
|
-
const { getExtensionManager } = require('../server/extensions')
|
|
410
402
|
const extensionProviders = getExtensionManager().getProviders()
|
|
411
|
-
const found = extensionProviders.find((p
|
|
403
|
+
const found = extensionProviders.find((p) => p.id === id)
|
|
412
404
|
if (found) {
|
|
413
405
|
return {
|
|
414
406
|
id: found.id as ProviderId,
|
|
@@ -455,8 +447,6 @@ export async function streamChatWithFailover(
|
|
|
455
447
|
let apiKey: string | null = opts.apiKey || null
|
|
456
448
|
if (credId && i > 0) {
|
|
457
449
|
// Need to decrypt fallback credential
|
|
458
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
459
|
-
const { loadCredentials, decryptKey } = require('../server/storage') as typeof import('@/lib/server/storage')
|
|
460
450
|
const creds = loadCredentials()
|
|
461
451
|
const cred = creds[credId]
|
|
462
452
|
if (cred?.encryptedKey) {
|
|
@@ -8,6 +8,7 @@ import type { Agent } from '@/types'
|
|
|
8
8
|
import { deriveOpenClawWsUrl } from '@/lib/openclaw/openclaw-endpoint'
|
|
9
9
|
import { normalizeOpenClawAgentId } from '@/lib/openclaw/openclaw-agent-id'
|
|
10
10
|
import { loadAgents } from '../server/storage'
|
|
11
|
+
import { getSharedDeviceToken } from '../server/openclaw/sync'
|
|
11
12
|
import {
|
|
12
13
|
resolveOpenClawGatewayAgentIdFromList,
|
|
13
14
|
type OpenClawGatewayAgentSummary,
|
|
@@ -74,8 +75,6 @@ function tryLoadIdentityFile(filePath: string): DeviceIdentity | null {
|
|
|
74
75
|
function loadOrCreateDeviceIdentity(): DeviceIdentity {
|
|
75
76
|
// 0. Check shared device token for cross-synced identity
|
|
76
77
|
try {
|
|
77
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
78
|
-
const { getSharedDeviceToken } = require('../server/openclaw/sync')
|
|
79
78
|
const sharedToken = getSharedDeviceToken()
|
|
80
79
|
if (sharedToken) {
|
|
81
80
|
// Shared token exists — the connector has already paired.
|
|
@@ -17,6 +17,7 @@ import { logActivity } from '@/lib/server/activity/activity-log'
|
|
|
17
17
|
import { createNotification } from '@/lib/server/create-notification'
|
|
18
18
|
import { notify } from '@/lib/server/ws-hub'
|
|
19
19
|
import { loadAgents } from '@/lib/server/agents/agent-repository'
|
|
20
|
+
import { upsertStoredItem, loadStoredItem, loadCollection } from '../storage'
|
|
20
21
|
import {
|
|
21
22
|
spawnSubagent,
|
|
22
23
|
type SubagentContext,
|
|
@@ -159,8 +160,6 @@ function notifySwarmChanged() {
|
|
|
159
160
|
|
|
160
161
|
function persistSwarmSnapshot(swarm: SwarmHandle): void {
|
|
161
162
|
try {
|
|
162
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
163
|
-
const { upsertStoredItem } = require('../storage')
|
|
164
163
|
upsertStoredItem('swarm_snapshots', swarm.swarmId, {
|
|
165
164
|
swarmId: swarm.swarmId,
|
|
166
165
|
parentSessionId: swarm.parentSessionId,
|
|
@@ -549,8 +548,6 @@ export function getSwarmSnapshot(swarmId: string): SwarmSnapshot | null {
|
|
|
549
548
|
if (swarm) return buildSwarmSnapshot(swarm)
|
|
550
549
|
// Fallback to persisted store for swarms from previous process lifetimes
|
|
551
550
|
try {
|
|
552
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
553
|
-
const { loadStoredItem } = require('../storage')
|
|
554
551
|
const persisted = loadStoredItem('swarm_snapshots', swarmId)
|
|
555
552
|
return persisted ? (persisted as SwarmSnapshot) : null
|
|
556
553
|
} catch { return null }
|
|
@@ -640,9 +637,7 @@ function buildSwarmSnapshot(swarm: SwarmHandle): SwarmSnapshot {
|
|
|
640
637
|
*/
|
|
641
638
|
export function restoreSwarmRegistry(): number {
|
|
642
639
|
try {
|
|
643
|
-
|
|
644
|
-
const { loadCollection, upsertStoredItem } = require('../storage')
|
|
645
|
-
const persisted = loadCollection('swarm_snapshots') as Record<string, SwarmSnapshot>
|
|
640
|
+
const persisted = loadCollection('swarm_snapshots') as unknown as Record<string, SwarmSnapshot>
|
|
646
641
|
let lost = 0
|
|
647
642
|
for (const [id, record] of Object.entries(persisted)) {
|
|
648
643
|
if (swarmRegistry.has(id)) continue
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Message, MessageToolEvent, SSEEvent, Session, UsageRecord } from '@/types'
|
|
2
|
+
import { sendConnectorMessage } from '../connectors/manager'
|
|
2
3
|
import { applyExactOutputContract, classifyExactOutputContract, type ExactOutputContract } from '@/lib/server/chat-execution/exact-output-contract'
|
|
3
4
|
import { stripMainLoopMetaForPersistence } from '@/lib/server/agents/main-agent-loop'
|
|
4
5
|
import { shouldSuppressHiddenControlText, stripHiddenControlTokens } from '@/lib/server/agents/assistant-control'
|
|
@@ -478,8 +479,6 @@ export async function finalizeChatTurn(params: {
|
|
|
478
479
|
&& heartbeatConfig.target !== 'none'
|
|
479
480
|
) {
|
|
480
481
|
try {
|
|
481
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
482
|
-
const { sendConnectorMessage } = require('../connectors/manager')
|
|
483
482
|
let connectorId: string | undefined
|
|
484
483
|
let channelId: string | undefined
|
|
485
484
|
if (heartbeatConfig.target === 'last') {
|
|
@@ -527,9 +526,7 @@ export async function finalizeChatTurn(params: {
|
|
|
527
526
|
: ''
|
|
528
527
|
if (!recentInbound && channelId) {
|
|
529
528
|
try {
|
|
530
|
-
|
|
531
|
-
const { sendConnectorMessage: sendMsg } = require('../connectors/manager')
|
|
532
|
-
sendMsg({ connectorId: connectorId || undefined, channelId, text: nextAssistantMessage.text }).catch((err: unknown) => {
|
|
529
|
+
sendConnectorMessage({ connectorId: connectorId || undefined, channelId, text: nextAssistantMessage.text }).catch((err: unknown) => {
|
|
533
530
|
log.warn('connector', 'Auto-route connector delivery failed', {
|
|
534
531
|
connectorId,
|
|
535
532
|
channelId,
|
|
@@ -11,6 +11,8 @@ import {
|
|
|
11
11
|
collectCapabilityOperatingGuidance,
|
|
12
12
|
} from '@/lib/server/native-capabilities'
|
|
13
13
|
import { getExtensionManager } from '@/lib/server/extensions'
|
|
14
|
+
import { loadAgents } from '../storage'
|
|
15
|
+
import { resolveTeam } from '../agents/team-resolution'
|
|
14
16
|
import {
|
|
15
17
|
getEnabledToolPlanningView,
|
|
16
18
|
getToolsForCapability,
|
|
@@ -44,12 +46,8 @@ function buildExtensionCapabilityLines(enabledExtensions: string[], opts?: { del
|
|
|
44
46
|
// CLI team hint — if teammates run CLI providers, mention their strengths
|
|
45
47
|
if (opts.agentId) {
|
|
46
48
|
try {
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
50
|
-
const { resolveTeam } = require('../agents/team-resolution')
|
|
51
|
-
const agents = loadAgents() as Record<string, Record<string, unknown>>
|
|
52
|
-
const team = resolveTeam(opts.agentId, agents)
|
|
49
|
+
const agents = loadAgents()
|
|
50
|
+
const team = resolveTeam(opts.agentId, agents as Record<string, import('@/types').Agent>)
|
|
53
51
|
if (team.mode === 'team') {
|
|
54
52
|
const cliTeammates: string[] = []
|
|
55
53
|
const allMembers = [...(team.coordinator ? [team.coordinator] : []), ...team.peers, ...team.directReports]
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
type GatewayResponseFrame,
|
|
14
14
|
} from '../gateway/protocol'
|
|
15
15
|
import { log } from '@/lib/server/logger'
|
|
16
|
+
import { setSharedDeviceToken } from '../openclaw/sync'
|
|
16
17
|
|
|
17
18
|
const TAG = 'openclaw'
|
|
18
19
|
|
|
@@ -830,8 +831,6 @@ const openclaw: PlatformConnector = {
|
|
|
830
831
|
// Cross-sync device token for provider identity resolution
|
|
831
832
|
if (normalized) {
|
|
832
833
|
try {
|
|
833
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
834
|
-
const { setSharedDeviceToken } = require('../openclaw/sync')
|
|
835
834
|
setSharedDeviceToken(normalized)
|
|
836
835
|
} catch { /* openclaw-sync not available */ }
|
|
837
836
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { spawnSync } from 'child_process'
|
|
2
2
|
import { errorMessage, hmrSingleton, jitteredBackoff } from '@/lib/shared-utils'
|
|
3
|
+
import { upsertStoredItem, loadCollection } from './storage'
|
|
3
4
|
|
|
4
5
|
type DelegateTool = 'delegate_to_claude_code' | 'delegate_to_codex_cli' | 'delegate_to_opencode_cli' | 'delegate_to_gemini_cli'
|
|
5
6
|
|
|
@@ -70,8 +71,6 @@ export function markProviderFailure(providerId: string, error: string, credentia
|
|
|
70
71
|
cooldownUntil: now + cooldownMsForFailures(failures),
|
|
71
72
|
})
|
|
72
73
|
try {
|
|
73
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
74
|
-
const { upsertStoredItem } = require('./storage')
|
|
75
74
|
upsertStoredItem('provider_health', key, states.get(key)!)
|
|
76
75
|
} catch {}
|
|
77
76
|
}
|
|
@@ -88,8 +87,6 @@ export function markProviderSuccess(providerId: string, credentialId?: string |
|
|
|
88
87
|
cooldownUntil: undefined,
|
|
89
88
|
})
|
|
90
89
|
try {
|
|
91
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
92
|
-
const { upsertStoredItem } = require('./storage')
|
|
93
90
|
upsertStoredItem('provider_health', key, states.get(key)!)
|
|
94
91
|
} catch {}
|
|
95
92
|
}
|
|
@@ -187,9 +184,7 @@ export function getProviderHealthSnapshot(): Record<string, ProviderHealthState
|
|
|
187
184
|
|
|
188
185
|
export function restoreProviderHealthState(): number {
|
|
189
186
|
try {
|
|
190
|
-
|
|
191
|
-
const { loadCollection } = require('./storage')
|
|
192
|
-
const persisted = loadCollection('provider_health') as Record<string, ProviderHealthState>
|
|
187
|
+
const persisted = loadCollection('provider_health') as unknown as Record<string, ProviderHealthState>
|
|
193
188
|
let restored = 0
|
|
194
189
|
for (const [id, record] of Object.entries(persisted)) {
|
|
195
190
|
if (states.has(id)) continue
|
|
@@ -242,7 +242,7 @@ function loadCollectionWithNormalizationState(table: string): {
|
|
|
242
242
|
return { result, normalizedCount }
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
-
function loadCollection(table: string): Record<string, StoredObject> {
|
|
245
|
+
export function loadCollection(table: string): Record<string, StoredObject> {
|
|
246
246
|
const { result, normalizedCount } = loadCollectionWithNormalizationState(table)
|
|
247
247
|
if (normalizedCount > 0) saveCollection(table, result)
|
|
248
248
|
return result
|