byterover-cli 3.2.0 → 3.4.0

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.
Files changed (127) hide show
  1. package/.env.production +0 -4
  2. package/dist/agent/core/domain/swarm/types.d.ts +132 -0
  3. package/dist/agent/core/domain/swarm/types.js +128 -0
  4. package/dist/agent/core/domain/tools/constants.d.ts +2 -0
  5. package/dist/agent/core/domain/tools/constants.js +2 -0
  6. package/dist/agent/core/interfaces/i-memory-provider.d.ts +45 -0
  7. package/dist/agent/core/interfaces/i-memory-provider.js +1 -0
  8. package/dist/agent/core/interfaces/i-sandbox-service.d.ts +8 -0
  9. package/dist/agent/core/interfaces/i-swarm-coordinator.d.ts +127 -0
  10. package/dist/agent/core/interfaces/i-swarm-coordinator.js +1 -0
  11. package/dist/agent/infra/agent/service-initializer.js +48 -0
  12. package/dist/agent/infra/map/map-shared.d.ts +2 -2
  13. package/dist/agent/infra/sandbox/sandbox-service.d.ts +10 -0
  14. package/dist/agent/infra/sandbox/sandbox-service.js +13 -0
  15. package/dist/agent/infra/sandbox/tools-sdk.d.ts +25 -0
  16. package/dist/agent/infra/sandbox/tools-sdk.js +24 -1
  17. package/dist/agent/infra/swarm/adapters/byterover-adapter.d.ts +39 -0
  18. package/dist/agent/infra/swarm/adapters/byterover-adapter.js +62 -0
  19. package/dist/agent/infra/swarm/adapters/gbrain-adapter.d.ts +63 -0
  20. package/dist/agent/infra/swarm/adapters/gbrain-adapter.js +209 -0
  21. package/dist/agent/infra/swarm/adapters/local-markdown-adapter.d.ts +41 -0
  22. package/dist/agent/infra/swarm/adapters/local-markdown-adapter.js +256 -0
  23. package/dist/agent/infra/swarm/adapters/memory-wiki-adapter.d.ts +29 -0
  24. package/dist/agent/infra/swarm/adapters/memory-wiki-adapter.js +244 -0
  25. package/dist/agent/infra/swarm/adapters/obsidian-adapter.d.ts +37 -0
  26. package/dist/agent/infra/swarm/adapters/obsidian-adapter.js +201 -0
  27. package/dist/agent/infra/swarm/cli/query-renderer.d.ts +15 -0
  28. package/dist/agent/infra/swarm/cli/query-renderer.js +126 -0
  29. package/dist/agent/infra/swarm/config/swarm-config-loader.d.ts +14 -0
  30. package/dist/agent/infra/swarm/config/swarm-config-loader.js +82 -0
  31. package/dist/agent/infra/swarm/config/swarm-config-schema.d.ts +667 -0
  32. package/dist/agent/infra/swarm/config/swarm-config-schema.js +305 -0
  33. package/dist/agent/infra/swarm/provider-factory.d.ts +21 -0
  34. package/dist/agent/infra/swarm/provider-factory.js +67 -0
  35. package/dist/agent/infra/swarm/search-precision.d.ts +95 -0
  36. package/dist/agent/infra/swarm/search-precision.js +141 -0
  37. package/dist/agent/infra/swarm/swarm-coordinator.d.ts +59 -0
  38. package/dist/agent/infra/swarm/swarm-coordinator.js +436 -0
  39. package/dist/agent/infra/swarm/swarm-graph.d.ts +63 -0
  40. package/dist/agent/infra/swarm/swarm-graph.js +167 -0
  41. package/dist/agent/infra/swarm/swarm-merger.d.ts +29 -0
  42. package/dist/agent/infra/swarm/swarm-merger.js +66 -0
  43. package/dist/agent/infra/swarm/swarm-router.d.ts +12 -0
  44. package/dist/agent/infra/swarm/swarm-router.js +40 -0
  45. package/dist/agent/infra/swarm/swarm-write-router.d.ts +23 -0
  46. package/dist/agent/infra/swarm/swarm-write-router.js +45 -0
  47. package/dist/agent/infra/swarm/validation/config-validator.d.ts +16 -0
  48. package/dist/agent/infra/swarm/validation/config-validator.js +402 -0
  49. package/dist/agent/infra/swarm/validation/memory-swarm-validation-error.d.ts +33 -0
  50. package/dist/agent/infra/swarm/validation/memory-swarm-validation-error.js +27 -0
  51. package/dist/agent/infra/swarm/wizard/config-scaffolder.d.ts +36 -0
  52. package/dist/agent/infra/swarm/wizard/config-scaffolder.js +96 -0
  53. package/dist/agent/infra/swarm/wizard/provider-detector.d.ts +54 -0
  54. package/dist/agent/infra/swarm/wizard/provider-detector.js +153 -0
  55. package/dist/agent/infra/swarm/wizard/swarm-wizard.d.ts +61 -0
  56. package/dist/agent/infra/swarm/wizard/swarm-wizard.js +187 -0
  57. package/dist/agent/infra/system-prompt/contributors/index.d.ts +1 -0
  58. package/dist/agent/infra/system-prompt/contributors/index.js +1 -0
  59. package/dist/agent/infra/system-prompt/contributors/swarm-state-contributor.d.ts +15 -0
  60. package/dist/agent/infra/system-prompt/contributors/swarm-state-contributor.js +65 -0
  61. package/dist/agent/infra/tools/implementations/curate-tool.d.ts +14 -14
  62. package/dist/agent/infra/tools/implementations/curate-tool.js +2 -0
  63. package/dist/agent/infra/tools/implementations/search-knowledge-service.js +12 -2
  64. package/dist/agent/infra/tools/implementations/swarm-query-tool.d.ts +9 -0
  65. package/dist/agent/infra/tools/implementations/swarm-query-tool.js +44 -0
  66. package/dist/agent/infra/tools/implementations/swarm-store-tool.d.ts +9 -0
  67. package/dist/agent/infra/tools/implementations/swarm-store-tool.js +43 -0
  68. package/dist/agent/infra/tools/tool-provider.js +1 -0
  69. package/dist/agent/infra/tools/tool-registry.d.ts +3 -0
  70. package/dist/agent/infra/tools/tool-registry.js +25 -1
  71. package/dist/agent/resources/tools/code_exec.txt +2 -0
  72. package/dist/agent/resources/tools/swarm_query.txt +38 -0
  73. package/dist/agent/resources/tools/swarm_store.txt +35 -0
  74. package/dist/oclif/commands/curate/index.d.ts +1 -0
  75. package/dist/oclif/commands/curate/index.js +15 -1
  76. package/dist/oclif/commands/query.d.ts +1 -0
  77. package/dist/oclif/commands/query.js +17 -3
  78. package/dist/oclif/commands/search.d.ts +20 -0
  79. package/dist/oclif/commands/search.js +186 -0
  80. package/dist/oclif/commands/status.js +4 -0
  81. package/dist/oclif/commands/swarm/curate.d.ts +13 -0
  82. package/dist/oclif/commands/swarm/curate.js +81 -0
  83. package/dist/oclif/commands/swarm/onboard.d.ts +6 -0
  84. package/dist/oclif/commands/swarm/onboard.js +233 -0
  85. package/dist/oclif/commands/swarm/query.d.ts +14 -0
  86. package/dist/oclif/commands/swarm/query.js +84 -0
  87. package/dist/oclif/commands/swarm/status.d.ts +41 -0
  88. package/dist/oclif/commands/swarm/status.js +278 -0
  89. package/dist/oclif/lib/daemon-client.js +0 -1
  90. package/dist/oclif/lib/search-format.d.ts +10 -0
  91. package/dist/oclif/lib/search-format.js +25 -0
  92. package/dist/oclif/lib/task-client.d.ts +6 -0
  93. package/dist/oclif/lib/task-client.js +10 -3
  94. package/dist/server/constants.d.ts +3 -2
  95. package/dist/server/constants.js +10 -7
  96. package/dist/server/core/domain/errors/task-error.d.ts +2 -2
  97. package/dist/server/core/domain/errors/task-error.js +5 -4
  98. package/dist/server/core/domain/source/source-schema.d.ts +6 -6
  99. package/dist/server/core/domain/transport/schemas.d.ts +14 -14
  100. package/dist/server/core/domain/transport/schemas.js +3 -3
  101. package/dist/server/core/interfaces/executor/i-search-executor.d.ts +34 -0
  102. package/dist/server/core/interfaces/executor/i-search-executor.js +1 -0
  103. package/dist/server/core/interfaces/executor/index.d.ts +1 -0
  104. package/dist/server/core/interfaces/executor/index.js +1 -0
  105. package/dist/server/infra/daemon/agent-process.js +20 -7
  106. package/dist/server/infra/executor/search-executor.d.ts +17 -0
  107. package/dist/server/infra/executor/search-executor.js +30 -0
  108. package/dist/server/infra/http/provider-model-fetchers.js +1 -0
  109. package/dist/server/infra/process/feature-handlers.js +13 -0
  110. package/dist/server/infra/project/project-registry.js +13 -1
  111. package/dist/server/infra/transport/handlers/locations-handler.d.ts +2 -0
  112. package/dist/server/infra/transport/handlers/locations-handler.js +16 -1
  113. package/dist/server/infra/transport/handlers/pull-handler.js +3 -3
  114. package/dist/server/infra/transport/handlers/push-handler.js +3 -3
  115. package/dist/server/infra/transport/handlers/status-handler.js +25 -18
  116. package/dist/server/infra/transport/handlers/vc-handler.d.ts +0 -4
  117. package/dist/server/infra/transport/handlers/vc-handler.js +5 -16
  118. package/dist/server/templates/skill/SKILL.md +188 -5
  119. package/dist/server/utils/gitignore.d.ts +1 -0
  120. package/dist/server/utils/gitignore.js +36 -4
  121. package/dist/shared/transport/search-content.d.ts +28 -0
  122. package/dist/shared/transport/search-content.js +38 -0
  123. package/dist/shared/transport/types/dto.d.ts +1 -1
  124. package/dist/tui/features/status/utils/format-status.js +5 -0
  125. package/dist/tui/utils/error-messages.js +2 -2
  126. package/oclif.manifest.json +581 -317
  127. package/package.json +2 -2
package/.env.production CHANGED
@@ -1,7 +1,3 @@
1
- # ByteRover CLI - Environment Configuration
2
- # Copy this file to .env.development (for dev) or .env.production (for production)
3
- # and fill in the values for your environment.
4
-
5
1
  BRV_API_BASE_URL=https://iam.byterover.dev/api/v1
6
2
  BRV_AUTHORIZATION_URL=https://iam.byterover.dev/api/v1/oidc/authorize
7
3
  BRV_COGIT_API_BASE_URL=https://v3-cgit.byterover.dev/api/v1
@@ -0,0 +1,132 @@
1
+ /**
2
+ * All supported memory provider types.
3
+ */
4
+ export declare const PROVIDER_TYPES: readonly ["byterover", "honcho", "hindsight", "obsidian", "local-markdown", "gbrain", "memory-wiki"];
5
+ /**
6
+ * Union type of supported memory provider identifiers.
7
+ */
8
+ export type ProviderType = (typeof PROVIDER_TYPES)[number];
9
+ /**
10
+ * Query type classification for routing decisions.
11
+ */
12
+ export type QueryType = 'factual' | 'personal' | 'relational' | 'temporal';
13
+ /**
14
+ * Check if a provider type is local (no network required).
15
+ */
16
+ export declare function isLocalProvider(type: ProviderType): boolean;
17
+ /**
18
+ * Check if a provider type requires network/cloud access.
19
+ */
20
+ export declare function isCloudProvider(type: ProviderType): boolean;
21
+ /**
22
+ * Capabilities that a memory provider can expose.
23
+ */
24
+ export type ProviderCapabilities = {
25
+ /** Average response time in milliseconds */
26
+ avgLatencyMs: number;
27
+ /** Can follow entity links / graph edges */
28
+ graphTraversal: boolean;
29
+ /** BM25 / full-text search */
30
+ keywordSearch: boolean;
31
+ /** No network calls needed */
32
+ localOnly: boolean;
33
+ /** Context budget per query */
34
+ maxTokensPerQuery: number;
35
+ /** Vector similarity search */
36
+ semanticSearch: boolean;
37
+ /** Time-range filtering */
38
+ temporalQuery: boolean;
39
+ /** Psychological profiles / user preferences */
40
+ userModeling: boolean;
41
+ /** Can store new memories */
42
+ writeSupported: boolean;
43
+ };
44
+ /**
45
+ * A single memory entry stored in a provider.
46
+ */
47
+ export type MemoryEntry = {
48
+ content: string;
49
+ metadata: {
50
+ confidence?: number;
51
+ entities?: string[];
52
+ expiresAt?: number;
53
+ relations?: string[];
54
+ source: string;
55
+ tags?: string[];
56
+ timestamp: number;
57
+ };
58
+ };
59
+ /**
60
+ * Request to query a memory provider.
61
+ */
62
+ export type QueryRequest = {
63
+ /** Enrichment data from predecessor providers (for graph execution) */
64
+ enrichment?: {
65
+ context?: string;
66
+ entities?: string[];
67
+ excerpts?: string[];
68
+ };
69
+ /** Whether to return provenance info */
70
+ includeMetadata?: boolean;
71
+ /** Limit results */
72
+ maxResults?: number;
73
+ /** Token budget for this provider */
74
+ maxTokens?: number;
75
+ /** The natural language query */
76
+ query: string;
77
+ /** Restrict to subtree/namespace */
78
+ scope?: string;
79
+ /** Temporal filter */
80
+ timeRange?: {
81
+ after?: number;
82
+ before?: number;
83
+ };
84
+ /** Hint: factual, temporal, personal, relational */
85
+ type?: QueryType;
86
+ };
87
+ /**
88
+ * A single result from a memory provider query.
89
+ */
90
+ export type QueryResult = {
91
+ content: string;
92
+ id: string;
93
+ metadata: {
94
+ confidence?: number;
95
+ matchType: 'graph' | 'keyword' | 'profile' | 'semantic' | 'temporal';
96
+ path?: string;
97
+ source: string;
98
+ timestamp?: number;
99
+ };
100
+ provider: string;
101
+ providerType: ProviderType;
102
+ score: number;
103
+ };
104
+ /**
105
+ * Result from storing a memory entry.
106
+ */
107
+ export type StoreResult = {
108
+ id: string;
109
+ provider: string;
110
+ success: boolean;
111
+ };
112
+ /**
113
+ * Health status of a memory provider.
114
+ */
115
+ export type HealthStatus = {
116
+ available: boolean;
117
+ error?: string;
118
+ latencyMs?: number;
119
+ };
120
+ /**
121
+ * Cost estimate for executing a query against a provider.
122
+ */
123
+ export type CostEstimate = {
124
+ estimatedCostCents: number;
125
+ estimatedLatencyMs: number;
126
+ estimatedTokens: number;
127
+ };
128
+ /**
129
+ * Create default capabilities for a given provider type.
130
+ * Used for initialization before actual provider reports its capabilities.
131
+ */
132
+ export declare function createDefaultCapabilities(type: ProviderType): ProviderCapabilities;
@@ -0,0 +1,128 @@
1
+ /**
2
+ * All supported memory provider types.
3
+ */
4
+ export const PROVIDER_TYPES = [
5
+ 'byterover',
6
+ 'honcho',
7
+ 'hindsight',
8
+ 'obsidian',
9
+ 'local-markdown',
10
+ 'gbrain',
11
+ 'memory-wiki',
12
+ ];
13
+ /**
14
+ * Local providers that require no network calls.
15
+ */
16
+ const LOCAL_PROVIDERS = new Set(['byterover', 'local-markdown', 'memory-wiki', 'obsidian']);
17
+ /**
18
+ * Check if a provider type is local (no network required).
19
+ */
20
+ export function isLocalProvider(type) {
21
+ return LOCAL_PROVIDERS.has(type);
22
+ }
23
+ /**
24
+ * Check if a provider type requires network/cloud access.
25
+ */
26
+ export function isCloudProvider(type) {
27
+ return !LOCAL_PROVIDERS.has(type);
28
+ }
29
+ /* eslint-disable perfectionist/sort-switch-case */
30
+ /**
31
+ * Create default capabilities for a given provider type.
32
+ * Used for initialization before actual provider reports its capabilities.
33
+ */
34
+ export function createDefaultCapabilities(type) {
35
+ switch (type) {
36
+ case 'byterover': {
37
+ return {
38
+ avgLatencyMs: 50,
39
+ graphTraversal: false,
40
+ keywordSearch: true,
41
+ localOnly: true,
42
+ maxTokensPerQuery: 8000,
43
+ semanticSearch: false,
44
+ temporalQuery: false,
45
+ userModeling: false,
46
+ writeSupported: false,
47
+ };
48
+ }
49
+ case 'obsidian': {
50
+ return {
51
+ avgLatencyMs: 100,
52
+ graphTraversal: true,
53
+ keywordSearch: true,
54
+ localOnly: true,
55
+ maxTokensPerQuery: 8000,
56
+ semanticSearch: false,
57
+ temporalQuery: false,
58
+ userModeling: false,
59
+ writeSupported: false,
60
+ };
61
+ }
62
+ case 'local-markdown': {
63
+ return {
64
+ avgLatencyMs: 80,
65
+ graphTraversal: true,
66
+ keywordSearch: true,
67
+ localOnly: true,
68
+ maxTokensPerQuery: 6000,
69
+ semanticSearch: false,
70
+ temporalQuery: false,
71
+ userModeling: false,
72
+ writeSupported: true,
73
+ };
74
+ }
75
+ case 'honcho': {
76
+ return {
77
+ avgLatencyMs: 500,
78
+ graphTraversal: false,
79
+ keywordSearch: false,
80
+ localOnly: false,
81
+ maxTokensPerQuery: 16_000,
82
+ semanticSearch: true,
83
+ temporalQuery: true,
84
+ userModeling: true,
85
+ writeSupported: true,
86
+ };
87
+ }
88
+ case 'hindsight': {
89
+ return {
90
+ avgLatencyMs: 300,
91
+ graphTraversal: true,
92
+ keywordSearch: true,
93
+ localOnly: false,
94
+ maxTokensPerQuery: 12_000,
95
+ semanticSearch: true,
96
+ temporalQuery: true,
97
+ userModeling: false,
98
+ writeSupported: true,
99
+ };
100
+ }
101
+ case 'gbrain': {
102
+ return {
103
+ avgLatencyMs: 200,
104
+ graphTraversal: false,
105
+ keywordSearch: true,
106
+ localOnly: false,
107
+ maxTokensPerQuery: 10_000,
108
+ semanticSearch: true,
109
+ temporalQuery: true,
110
+ userModeling: false,
111
+ writeSupported: true,
112
+ };
113
+ }
114
+ case 'memory-wiki': {
115
+ return {
116
+ avgLatencyMs: 60,
117
+ graphTraversal: false,
118
+ keywordSearch: true,
119
+ localOnly: true,
120
+ maxTokensPerQuery: 8000,
121
+ semanticSearch: false,
122
+ temporalQuery: false,
123
+ userModeling: false,
124
+ writeSupported: true,
125
+ };
126
+ }
127
+ }
128
+ }
@@ -14,6 +14,8 @@ export declare const ToolName: {
14
14
  readonly LLM_MAP: 'llm_map';
15
15
  readonly READ_FILE: 'read_file';
16
16
  readonly SEARCH_KNOWLEDGE: 'search_knowledge';
17
+ readonly SWARM_QUERY: 'swarm_query';
18
+ readonly SWARM_STORE: 'swarm_store';
17
19
  readonly WRITE_FILE: 'write_file';
18
20
  };
19
21
  /**
@@ -14,5 +14,7 @@ export const ToolName = {
14
14
  LLM_MAP: 'llm_map',
15
15
  READ_FILE: 'read_file',
16
16
  SEARCH_KNOWLEDGE: 'search_knowledge',
17
+ SWARM_QUERY: 'swarm_query',
18
+ SWARM_STORE: 'swarm_store',
17
19
  WRITE_FILE: 'write_file',
18
20
  };
@@ -0,0 +1,45 @@
1
+ import type { CostEstimate, HealthStatus, MemoryEntry, ProviderCapabilities, ProviderType, QueryRequest, QueryResult, StoreResult } from '../domain/swarm/types.js';
2
+ /**
3
+ * Unified interface for memory providers.
4
+ * Every memory provider (ByteRover, Obsidian, Honcho, etc.) implements this contract.
5
+ * The swarm graph operates exclusively through this interface.
6
+ */
7
+ export interface IMemoryProvider {
8
+ /** Provider capabilities (search types, write support, latency) */
9
+ readonly capabilities: ProviderCapabilities;
10
+ /**
11
+ * Delete a memory entry.
12
+ * @throws if the entry doesn't exist or provider is read-only
13
+ */
14
+ delete(id: string): Promise<void>;
15
+ /**
16
+ * Estimate the cost of executing a query.
17
+ * Used by the router for budget-aware dispatching.
18
+ */
19
+ estimateCost(request: QueryRequest): CostEstimate;
20
+ /**
21
+ * Check if this provider is reachable and functional.
22
+ * Used by the control plane to skip unavailable providers.
23
+ */
24
+ healthCheck(): Promise<HealthStatus>;
25
+ /** Unique provider identifier */
26
+ readonly id: string;
27
+ /**
28
+ * Query this provider for relevant memories.
29
+ * The core operation — every provider MUST support this.
30
+ */
31
+ query(request: QueryRequest): Promise<QueryResult[]>;
32
+ /**
33
+ * Store a memory entry into this provider.
34
+ * Not all providers support writes (e.g., Obsidian may be read-only).
35
+ * @throws if the provider is read-only
36
+ */
37
+ store(entry: MemoryEntry): Promise<StoreResult>;
38
+ /** Provider type for routing decisions */
39
+ readonly type: ProviderType;
40
+ /**
41
+ * Update an existing memory entry.
42
+ * @throws if the entry doesn't exist or provider is read-only
43
+ */
44
+ update(id: string, entry: Partial<MemoryEntry>): Promise<void>;
45
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -5,6 +5,7 @@ import type { REPLResult, SandboxConfig } from '../domain/sandbox/types.js';
5
5
  import type { IContentGenerator } from './i-content-generator.js';
6
6
  import type { ICurateService } from './i-curate-service.js';
7
7
  import type { IFileSystem } from './i-file-system.js';
8
+ import type { ISwarmCoordinator } from './i-swarm-coordinator.js';
8
9
  /**
9
10
  * Service interface for code sandbox execution.
10
11
  * Provides isolated JavaScript/TypeScript code execution with security controls.
@@ -89,4 +90,11 @@ export interface ISandboxService {
89
90
  * @param sessionManager - Session manager instance
90
91
  */
91
92
  setSessionManager?(sessionManager: SessionManager): void;
93
+ /**
94
+ * Set the swarm coordinator for cross-provider query and store.
95
+ * When set, sandboxes will have access to `tools.swarmQuery()` and `tools.swarmStore()`.
96
+ *
97
+ * @param swarmCoordinator - Swarm coordinator instance
98
+ */
99
+ setSwarmCoordinator?(swarmCoordinator: ISwarmCoordinator): void;
92
100
  }
@@ -0,0 +1,127 @@
1
+ import type { ProviderCapabilities, ProviderType, QueryRequest, QueryResult, QueryType } from '../domain/swarm/types.js';
2
+ /**
3
+ * Metadata about a single provider's contribution to a swarm query.
4
+ */
5
+ export type ProviderQueryMeta = {
6
+ /** Which provider enriched this provider's query (if any) */
7
+ enrichedBy?: string;
8
+ /** Content excerpts injected via enrichment from predecessors */
9
+ enrichmentExcerpts?: string[];
10
+ /** Why this provider was excluded (only when selected=false) */
11
+ excludeReason?: string;
12
+ /** How long this provider took to respond */
13
+ latencyMs: number;
14
+ /** How many results this provider returned */
15
+ resultCount: number;
16
+ /** Whether this provider was selected for this query */
17
+ selected: boolean;
18
+ };
19
+ /**
20
+ * Metadata about the overall swarm query execution.
21
+ */
22
+ export type QueryMeta = {
23
+ /** Total monetary cost across all cloud providers */
24
+ costCents: number;
25
+ /** Per-provider execution metadata */
26
+ providers: Record<string, ProviderQueryMeta>;
27
+ /** How the query was classified */
28
+ queryType: QueryType;
29
+ /** End-to-end latency including routing, execution, and merging */
30
+ totalLatencyMs: number;
31
+ };
32
+ /**
33
+ * Complete result from a swarm query — results + execution metadata.
34
+ */
35
+ export type SwarmQueryResult = {
36
+ /** Execution metadata (providers used, latency, cost) */
37
+ meta: QueryMeta;
38
+ /** Ranked, fused results from all active providers */
39
+ results: QueryResult[];
40
+ };
41
+ /**
42
+ * Summary info about a registered provider (for status display).
43
+ */
44
+ export type ProviderInfo = {
45
+ /** Provider capabilities */
46
+ capabilities: ProviderCapabilities;
47
+ /** Whether the provider is currently reachable */
48
+ healthy: boolean;
49
+ /** Provider identifier */
50
+ id: string;
51
+ /** Provider type (local/cloud) */
52
+ type: ProviderType;
53
+ };
54
+ /**
55
+ * Presentation-oriented summary of the swarm state.
56
+ * Used by CLI status, system prompt contributor, and REPL commands.
57
+ */
58
+ export type SwarmSummary = {
59
+ /** Number of active (healthy + enabled) providers */
60
+ activeCount: number;
61
+ /** Average query latency in milliseconds */
62
+ avgLatencyMs: number;
63
+ /** Learning status */
64
+ learningStatus: 'cold-start' | 'converged' | 'learning';
65
+ /** Monthly budget cap in cents */
66
+ monthlyBudgetCents: number;
67
+ /** Monthly spend so far in cents */
68
+ monthlySpendCents: number;
69
+ /** Per-provider summaries */
70
+ providers: ProviderInfo[];
71
+ /** Total number of registered providers */
72
+ totalCount: number;
73
+ /** Total queries executed */
74
+ totalQueries: number;
75
+ };
76
+ /**
77
+ * Request to store knowledge via the swarm.
78
+ */
79
+ export type SwarmStoreRequest = {
80
+ /** The knowledge content to store */
81
+ content: string;
82
+ /** Optional write type hint — skips classification when provided */
83
+ contentType?: 'entity' | 'general' | 'note';
84
+ /** Explicit target provider ID — overrides classification */
85
+ provider?: string;
86
+ };
87
+ /**
88
+ * Result from a swarm store operation.
89
+ */
90
+ export type SwarmStoreResult = {
91
+ /** Error message if store failed */
92
+ error?: string;
93
+ /** True when content was routed to context tree as fallback (no external providers available) */
94
+ fallback?: boolean;
95
+ /** ID assigned by the target provider */
96
+ id: string;
97
+ /** Store latency in milliseconds */
98
+ latencyMs: number;
99
+ /** Provider that stored the content */
100
+ provider: string;
101
+ /** Whether the store succeeded */
102
+ success: boolean;
103
+ };
104
+ /**
105
+ * Central coordinator for the memory swarm.
106
+ * Routes queries to providers, executes the graph, and fuses results.
107
+ * Routes store operations to the best writable provider.
108
+ */
109
+ export interface ISwarmCoordinator {
110
+ /**
111
+ * Execute a swarm query — route, execute providers, fuse results.
112
+ */
113
+ execute(request: QueryRequest): Promise<SwarmQueryResult>;
114
+ /**
115
+ * Get info about all registered providers and their health status.
116
+ */
117
+ getActiveProviders(): ProviderInfo[];
118
+ /**
119
+ * Get a presentation-oriented summary of the swarm state.
120
+ */
121
+ getSummary(): SwarmSummary;
122
+ /**
123
+ * Store knowledge in the best writable provider.
124
+ * Routes by content type or explicit provider target.
125
+ */
126
+ store(request: SwarmStoreRequest): Promise<SwarmStoreResult>;
127
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -33,11 +33,17 @@ import { SandboxService } from '../sandbox/sandbox-service.js';
33
33
  import { FileKeyStorage } from '../storage/file-key-storage.js';
34
34
  import { GranularHistoryStorage } from '../storage/granular-history-storage.js';
35
35
  import { MessageStorageService } from '../storage/message-storage-service.js';
36
+ import { loadSwarmConfig } from '../swarm/config/swarm-config-loader.js';
37
+ import { buildProvidersFromConfig } from '../swarm/provider-factory.js';
38
+ import { SwarmCoordinator } from '../swarm/swarm-coordinator.js';
39
+ import { validateSwarmProviders } from '../swarm/validation/config-validator.js';
36
40
  import { ContextTreeStructureContributor } from '../system-prompt/contributors/context-tree-structure-contributor.js';
37
41
  import { MapSelectionContributor } from '../system-prompt/contributors/map-selection-contributor.js';
42
+ import { SwarmStateContributor } from '../system-prompt/contributors/swarm-state-contributor.js';
38
43
  import { SystemPromptManager } from '../system-prompt/system-prompt-manager.js';
39
44
  import { CoreToolScheduler } from '../tools/core-tool-scheduler.js';
40
45
  import { DEFAULT_POLICY_RULES } from '../tools/default-policy-rules.js';
46
+ import { createSearchKnowledgeService } from '../tools/implementations/search-knowledge-service.js';
41
47
  import { PolicyEngine } from '../tools/policy-engine.js';
42
48
  import { ToolDescriptionLoader } from '../tools/tool-description-loader.js';
43
49
  import { ToolManager } from '../tools/tool-manager.js';
@@ -133,6 +139,47 @@ export async function createCipherAgentServices(config, agentEventBus) {
133
139
  // Priority 16 — right after context tree structure, before memories
134
140
  const mapSelectionContributor = new MapSelectionContributor('mapSelection', 16);
135
141
  systemPromptManager.registerContributor(mapSelectionContributor);
142
+ // 6b. Swarm coordinator — try to load config and build providers.
143
+ // Missing config → fail-open (no swarm). Invalid config → warn but continue.
144
+ let swarmCoordinator;
145
+ try {
146
+ const swarmConfig = await loadSwarmConfig(workingDirectory);
147
+ // Validate enrichment topology — structural errors block swarm init.
148
+ // Provider-specific errors (bad paths, missing API keys) are handled
149
+ // by health checks, preserving degraded-mode semantics.
150
+ const swarmValidation = await validateSwarmProviders(swarmConfig);
151
+ const topologyErrors = swarmValidation.errors.filter((e) => e.provider === 'enrichment');
152
+ if (topologyErrors.length > 0) {
153
+ const messages = topologyErrors.map((e) => e.message);
154
+ throw new Error(`Invalid enrichment topology:\n ${messages.join('\n ')}`);
155
+ }
156
+ // Log provider-specific warnings/errors without blocking
157
+ for (const error of swarmValidation.errors.filter((e) => e.provider !== 'enrichment')) {
158
+ logger.warn(`Swarm provider issue: ${error.provider}: ${error.message}`);
159
+ }
160
+ const swarmProviders = buildProvidersFromConfig(swarmConfig, {
161
+ searchService: createSearchKnowledgeService(fileSystemService),
162
+ });
163
+ if (swarmProviders.length > 0) {
164
+ swarmCoordinator = new SwarmCoordinator(swarmProviders, swarmConfig);
165
+ // Run initial health checks so unhealthy providers are skipped from first query
166
+ await swarmCoordinator.refreshHealth();
167
+ }
168
+ }
169
+ catch (error) {
170
+ const message = error instanceof Error ? error.message : String(error);
171
+ const isConfigMissing = message.includes('not found');
172
+ if (!isConfigMissing) {
173
+ // Config exists but is invalid — warn so the user can diagnose
174
+ logger.warn(`Swarm disabled due to config error: ${message}`);
175
+ }
176
+ // Missing config is expected — silently skip
177
+ }
178
+ // Register swarm state contributor when multi-provider swarm is active
179
+ if (swarmCoordinator) {
180
+ const swarmStateContributor = new SwarmStateContributor('swarmState', 17, swarmCoordinator);
181
+ systemPromptManager.registerContributor(swarmStateContributor);
182
+ }
136
183
  // 7. Abstract generation queue (generator injected later via rebindCurateTools)
137
184
  const abstractQueue = new AbstractGenerationQueue(workingDirectory);
138
185
  // 8. Tool provider (depends on FileSystemService, ProcessService, MemoryManager, SystemPromptManager)
@@ -146,6 +193,7 @@ export async function createCipherAgentServices(config, agentEventBus) {
146
193
  memoryManager,
147
194
  processService,
148
195
  sandboxService,
196
+ swarmCoordinator,
149
197
  }, systemPromptManager, descriptionLoader);
150
198
  await toolProvider.initialize();
151
199
  // 9. Policy engine with default rules for autonomous execution
@@ -99,19 +99,19 @@ export declare const AgenticMapParametersSchema: z.ZodObject<{
99
99
  output_schema: Record<string, any>;
100
100
  input_path: string;
101
101
  output_path: string;
102
+ read_only?: boolean | undefined;
102
103
  max_attempts?: number | undefined;
103
104
  timeout_seconds?: number | undefined;
104
105
  max_depth?: number | undefined;
105
- read_only?: boolean | undefined;
106
106
  }, {
107
107
  prompt: string;
108
108
  output_schema: Record<string, any>;
109
109
  input_path: string;
110
110
  output_path: string;
111
+ read_only?: boolean | undefined;
111
112
  max_attempts?: number | undefined;
112
113
  timeout_seconds?: number | undefined;
113
114
  max_depth?: number | undefined;
114
- read_only?: boolean | undefined;
115
115
  }>;
116
116
  export type AgenticMapParameters = z.infer<typeof AgenticMapParametersSchema>;
117
117
  /**
@@ -4,6 +4,7 @@ import type { IContentGenerator } from '../../core/interfaces/i-content-generato
4
4
  import type { ICurateService } from '../../core/interfaces/i-curate-service.js';
5
5
  import type { IFileSystem } from '../../core/interfaces/i-file-system.js';
6
6
  import type { ISandboxService } from '../../core/interfaces/i-sandbox-service.js';
7
+ import type { ISwarmCoordinator } from '../../core/interfaces/i-swarm-coordinator.js';
7
8
  import type { SessionManager } from '../session/session-manager.js';
8
9
  import type { ISearchKnowledgeService } from './tools-sdk.js';
9
10
  /**
@@ -31,6 +32,8 @@ export declare class SandboxService implements ISandboxService {
31
32
  private searchKnowledgeService?;
32
33
  /** Session manager for sub-agent delegation via tools.agentQuery() */
33
34
  private sessionManager?;
35
+ /** Swarm coordinator for cross-provider query and store */
36
+ private swarmCoordinator?;
34
37
  /**
35
38
  * Clean up all resources (called on agent shutdown).
36
39
  */
@@ -110,6 +113,13 @@ export declare class SandboxService implements ISandboxService {
110
113
  * @param sessionManager - Session manager instance
111
114
  */
112
115
  setSessionManager(sessionManager: SessionManager): void;
116
+ /**
117
+ * Set the swarm coordinator for cross-provider query and store.
118
+ * When set, sandboxes will have access to `tools.swarmQuery()` and `tools.swarmStore()`.
119
+ *
120
+ * @param swarmCoordinator - Swarm coordinator instance
121
+ */
122
+ setSwarmCoordinator(swarmCoordinator: ISwarmCoordinator): void;
113
123
  /**
114
124
  * Build a Tools SDK instance for a specific session.
115
125
  * Includes `agentQuery` bound to the session's ID for sub-agent delegation.
@@ -26,6 +26,8 @@ export class SandboxService {
26
26
  searchKnowledgeService;
27
27
  /** Session manager for sub-agent delegation via tools.agentQuery() */
28
28
  sessionManager;
29
+ /** Swarm coordinator for cross-provider query and store */
30
+ swarmCoordinator;
29
31
  /**
30
32
  * Clean up all resources (called on agent shutdown).
31
33
  */
@@ -201,6 +203,16 @@ export class SandboxService {
201
203
  setSessionManager(sessionManager) {
202
204
  this.sessionManager = sessionManager;
203
205
  }
206
+ /**
207
+ * Set the swarm coordinator for cross-provider query and store.
208
+ * When set, sandboxes will have access to `tools.swarmQuery()` and `tools.swarmStore()`.
209
+ *
210
+ * @param swarmCoordinator - Swarm coordinator instance
211
+ */
212
+ setSwarmCoordinator(swarmCoordinator) {
213
+ this.swarmCoordinator = swarmCoordinator;
214
+ this.invalidateSandboxes();
215
+ }
204
216
  /**
205
217
  * Build a Tools SDK instance for a specific session.
206
218
  * Includes `agentQuery` bound to the session's ID for sub-agent delegation.
@@ -219,6 +231,7 @@ export class SandboxService {
219
231
  sandboxService: this,
220
232
  searchKnowledgeService: this.searchKnowledgeService,
221
233
  sessionManager: this.sessionManager,
234
+ swarmCoordinator: this.swarmCoordinator,
222
235
  });
223
236
  }
224
237
  /**