packfs-core
Version:
Semantic filesystem operations for LLM agent frameworks with natural language understanding. See LLM_AGENT_GUIDE.md for copy-paste examples.
518 lines • 21.8 kB
JavaScript
;
/**
* KaibanJS integration for PackFS semantic filesystem
* KaibanJS: The JavaScript Framework for Building Multi-Agent Systems - https://www.kaibanjs.com/
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.KaibanSemanticFilesystemTool = void 0;
exports.createKaibanSemanticFilesystemTool = createKaibanSemanticFilesystemTool;
exports.createKaibanFileSystemActions = createKaibanFileSystemActions;
exports.createKaibanMultiAgentFileCoordinator = createKaibanMultiAgentFileCoordinator;
/**
* PackFS semantic filesystem tool for KaibanJS
* Integrated with KaibanJS's Redux-inspired state management
*/
class KaibanSemanticFilesystemTool {
createTool(config) {
return {
name: 'semantic_filesystem',
description: this.getToolDescription().description,
parameters: this.getKaibanParameters(),
handler: async (params, context) => {
const agentId = config.kaiban?.agentId || context?.agentId || 'unknown';
try {
// Pre-operation hook
config.kaiban?.stateHandlers?.onBeforeOperation?.(params.action || 'natural_query', params);
const result = await this.executeOperation(config, params, context);
// Post-operation hook
config.kaiban?.stateHandlers?.onAfterOperation?.(params.action || 'natural_query', result);
return this.formatKaibanResponse(result, agentId);
}
catch (error) {
// Error hook
const err = error instanceof Error ? error : new Error('Unknown error');
config.kaiban?.stateHandlers?.onError?.(params.action || 'natural_query', err);
throw err;
}
},
metadata: {
agentId: config.kaiban?.agentId,
category: 'filesystem',
permissions: ['read', 'write', 'search', 'organize'],
},
};
}
getToolDescription() {
return {
name: 'semantic_filesystem',
description: 'Multi-agent compatible filesystem operations with semantic understanding and state management. Supports collaborative file operations across agent teams.',
parameters: {
type: 'object',
properties: {
action: {
type: 'string',
description: 'Type of filesystem operation',
enum: [
'read',
'write',
'search',
'list',
'organize',
'delete',
'collaborate',
'natural_query',
],
},
query: {
type: 'string',
description: 'Natural language description of the operation for multi-agent understanding',
},
path: {
type: 'string',
description: 'File or directory path',
},
content: {
type: 'string',
description: 'Content for write operations',
},
searchQuery: {
type: 'string',
description: 'Search term or semantic query',
},
collaboration: {
type: 'object',
description: 'Multi-agent collaboration options',
},
options: {
type: 'object',
description: 'Operation-specific options',
},
},
required: [],
},
examples: [
{
input: '{"action": "natural_query", "query": "read the shared configuration file for agent coordination"}',
description: 'Natural language file access with agent context',
},
{
input: '{"action": "write", "path": "shared/team-notes.md", "content": "Meeting notes", "collaboration": {"shareWith": ["agent1", "agent2"], "notifyAgents": true}}',
description: 'Collaborative file writing with agent notification',
},
{
input: '{"action": "search", "searchQuery": "task assignments", "collaboration": {"taskId": "coordination-123"}}',
description: 'Search files related to specific multi-agent task',
},
],
};
}
validateParameters(params) {
const errors = [];
if (!params.action && !params.query) {
errors.push('Must provide either action or query');
}
// Validate collaboration-specific requirements
if (params.collaboration?.shareWith && !Array.isArray(params.collaboration.shareWith)) {
errors.push('shareWith must be an array of agent IDs');
}
return {
valid: errors.length === 0,
errors: errors.length > 0 ? errors : undefined,
};
}
getKaibanParameters() {
return {
type: 'object',
properties: {
action: {
type: 'string',
description: 'Type of filesystem operation',
enum: [
'read',
'write',
'search',
'list',
'organize',
'delete',
'collaborate',
'natural_query',
],
},
query: {
type: 'string',
description: 'Natural language description of the operation',
},
path: { type: 'string' },
content: { type: 'string' },
searchQuery: { type: 'string' },
collaboration: {
type: 'object',
properties: {
shareWith: { type: 'array', items: { type: 'string' } },
lockFile: { type: 'boolean' },
notifyAgents: { type: 'boolean' },
taskId: { type: 'string' },
},
},
options: { type: 'object' },
},
};
}
async executeOperation(config, params, context) {
const startTime = Date.now();
// Validate parameters
const validation = this.validateParameters(params);
if (!validation.valid) {
return {
success: false,
error: `Invalid parameters: ${validation.errors?.join(', ')}`,
};
}
try {
let result;
// Handle natural language queries or actions without specific structure
if (params.action === 'natural_query' || (params.query && !params.action)) {
result = await this.executeNaturalLanguageQuery(config, params.query, context);
}
else {
result = await this.executeKaibanAction(config, params, context);
}
// Handle collaboration features
if (params.collaboration) {
result = await this.handleCollaboration(config, params.collaboration, result, context);
}
// Check if the semantic operation was successful
const success = result.success !== false;
return {
success,
data: result,
error: success ? undefined : result.message || 'Operation failed',
metadata: {
executionTime: Date.now() - startTime,
operationType: params.action || 'natural_query',
agentId: context?.agentId || config.kaiban?.agentId,
taskId: context?.taskId || params.collaboration?.taskId,
},
};
}
catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error',
};
}
}
async executeNaturalLanguageQuery(config, query, context) {
// Ensure filesystem is initialized
if (!config.filesystem) {
throw new Error('Filesystem is not initialized. Please provide a valid filesystem or workingDirectory.');
}
const nlResult = await config.filesystem.interpretNaturalLanguage({
query,
context: {
workingDirectory: config.workingDirectory,
agentContext: {
...config.kaiban?.taskContext,
...context,
agentId: config.kaiban?.agentId,
},
},
});
if (!nlResult.success) {
throw new Error(`Failed to interpret query: ${nlResult.message}`);
}
// Execute the interpreted intent
const intent = nlResult.interpretedIntent;
if ('purpose' in intent) {
switch (intent.purpose) {
case 'read':
case 'preview':
case 'metadata':
case 'verify_exists':
case 'create_or_get':
// Ensure filesystem is initialized
if (!config.filesystem) {
throw new Error('Filesystem is not initialized. Please provide a valid filesystem or workingDirectory.');
}
return await config.filesystem.accessFile(intent);
case 'create':
case 'append':
case 'overwrite':
case 'merge':
case 'patch':
// Ensure filesystem is initialized
if (!config.filesystem) {
throw new Error('Filesystem is not initialized. Please provide a valid filesystem or workingDirectory.');
}
return await config.filesystem.updateContent(intent);
case 'create_directory':
case 'move':
case 'copy':
case 'group_semantic':
case 'group_keywords':
// Ensure filesystem is initialized
if (!config.filesystem) {
throw new Error('Filesystem is not initialized. Please provide a valid filesystem or workingDirectory.');
}
return await config.filesystem.organizeFiles(intent);
case 'list':
case 'find':
case 'search_content':
case 'search_semantic':
case 'search_integrated':
// Ensure filesystem is initialized
if (!config.filesystem) {
throw new Error('Filesystem is not initialized. Please provide a valid filesystem or workingDirectory.');
}
return await config.filesystem.discoverFiles(intent);
case 'delete_file':
case 'delete_directory':
case 'delete_by_criteria':
// Ensure filesystem is initialized
if (!config.filesystem) {
throw new Error('Filesystem is not initialized. Please provide a valid filesystem or workingDirectory.');
}
return await config.filesystem.removeFiles(intent);
}
}
// Handle workflow intents - only if it has workflow structure
if ('steps' in intent) {
// Ensure filesystem is initialized
if (!config.filesystem) {
throw new Error('Filesystem is not initialized. Please provide a valid filesystem or workingDirectory.');
}
return await config.filesystem.executeWorkflow(intent);
}
throw new Error('Unrecognized intent type');
}
async executeKaibanAction(config, params, context) {
switch (params.action) {
case 'read':
// Ensure filesystem is initialized
if (!config.filesystem) {
throw new Error('Filesystem is not initialized. Please provide a valid filesystem or workingDirectory.');
}
return await config.filesystem.accessFile({
purpose: 'read',
target: { path: params.path },
preferences: params.options,
});
case 'write':
// Ensure filesystem is initialized
if (!config.filesystem) {
throw new Error('Filesystem is not initialized. Please provide a valid filesystem or workingDirectory.');
}
return await config.filesystem.updateContent({
purpose: params.append ? 'append' : 'create',
target: { path: params.path },
content: params.content,
options: params.options,
});
case 'search':
// Ensure filesystem is initialized
if (!config.filesystem) {
throw new Error('Filesystem is not initialized. Please provide a valid filesystem or workingDirectory.');
}
return await config.filesystem.discoverFiles({
purpose: 'search_semantic',
target: { semanticQuery: params.searchQuery },
options: params.options,
});
case 'list':
// Ensure filesystem is initialized
if (!config.filesystem) {
throw new Error('Filesystem is not initialized. Please provide a valid filesystem or workingDirectory.');
}
return await config.filesystem.discoverFiles({
purpose: 'list',
target: { path: params.path || '.' },
options: params.options,
});
case 'organize':
// Ensure filesystem is initialized
if (!config.filesystem) {
throw new Error('Filesystem is not initialized. Please provide a valid filesystem or workingDirectory.');
}
return await config.filesystem.organizeFiles({
purpose: params.operation || 'move',
source: { path: params.source },
destination: { path: params.destination },
options: params.options,
});
case 'delete':
// Ensure filesystem is initialized
if (!config.filesystem) {
throw new Error('Filesystem is not initialized. Please provide a valid filesystem or workingDirectory.');
}
return await config.filesystem.removeFiles({
purpose: 'delete_file',
target: { path: params.path },
options: params.options,
});
case 'collaborate':
// Special KaibanJS action for multi-agent collaboration
return await this.handleCollaborativeOperation(config, params, context);
default:
throw new Error(`Unknown action: ${params.action}`);
}
}
async handleCollaboration(config, collaboration, result, context) {
// Add collaboration metadata to result
const collaborativeResult = {
...result,
collaboration: {
sharedWith: collaboration.shareWith || [],
locked: collaboration.lockFile || false,
notified: collaboration.notifyAgents || false,
taskId: collaboration.taskId,
agentId: config.kaiban?.agentId || context?.agentId,
timestamp: new Date().toISOString(),
},
};
// In a real implementation, this would:
// 1. Notify specified agents
// 2. Update shared state
// 3. Handle file locking
// 4. Coordinate with task management
return collaborativeResult;
}
async handleCollaborativeOperation(config, params, context) {
// Special handling for multi-agent collaboration scenarios
const agentId = config.kaiban?.agentId || context?.agentId;
return {
success: true,
message: `Collaborative operation initiated by agent ${agentId}`,
collaboration: {
agentId,
operation: params.operation,
participants: params.participants || [],
taskId: params.taskId || context?.taskId,
timestamp: new Date().toISOString(),
},
};
}
formatKaibanResponse(result, agentId) {
if (!result.success) {
return {
success: false,
error: result.error,
agentId,
timestamp: new Date().toISOString(),
};
}
return {
success: true,
data: result.data,
metadata: {
...result.metadata,
agentId,
timestamp: new Date().toISOString(),
},
};
}
}
exports.KaibanSemanticFilesystemTool = KaibanSemanticFilesystemTool;
/**
* Create a KaibanJS compatible semantic filesystem tool
*/
function createKaibanSemanticFilesystemTool(config) {
const adapter = new KaibanSemanticFilesystemTool();
return adapter.createTool(config);
}
/**
* Create KaibanJS task actions for file operations
* These can be dispatched through KaibanJS's Redux-style state management
*/
function createKaibanFileSystemActions(config) {
const agentId = config.kaiban?.agentId || 'unknown';
return {
readFile: (path, options) => ({
type: 'FILESYSTEM_READ',
payload: { path, options },
meta: {
agentId,
timestamp: Date.now(),
operationType: 'read',
},
}),
writeFile: (path, content, options) => ({
type: 'FILESYSTEM_WRITE',
payload: { path, content, options },
meta: {
agentId,
timestamp: Date.now(),
operationType: 'write',
},
}),
searchFiles: (query, options) => ({
type: 'FILESYSTEM_SEARCH',
payload: { query, options },
meta: {
agentId,
timestamp: Date.now(),
operationType: 'search',
},
}),
collaborateOnFile: (path, operation, agents) => ({
type: 'FILESYSTEM_COLLABORATE',
payload: { path, operation, agents },
meta: {
agentId,
timestamp: Date.now(),
operationType: 'collaborate',
},
}),
};
}
/**
* Create a specialized multi-agent file coordination tool
*/
function createKaibanMultiAgentFileCoordinator(config) {
return {
name: 'multi_agent_file_coordinator',
description: 'Coordinate file operations across multiple agents with conflict resolution and state synchronization',
parameters: {
type: 'object',
properties: {
operation: {
type: 'string',
enum: ['lock', 'unlock', 'sync', 'resolve_conflict', 'broadcast_change'],
description: 'Coordination operation',
},
path: { type: 'string', description: 'File path to coordinate' },
agentIds: {
type: 'array',
items: { type: 'string' },
description: 'Agents involved in coordination',
},
priority: { type: 'number', description: 'Operation priority for conflict resolution' },
taskId: { type: 'string', description: 'Associated task ID' },
},
required: ['operation', 'path'],
},
handler: async (params, context) => {
const agentId = config.kaiban?.agentId || context?.agentId;
// Simulate multi-agent coordination logic
// In a real implementation, this would integrate with KaibanJS's state management
return {
success: true,
coordination: {
operation: params.operation,
path: params.path,
coordinatingAgent: agentId,
participants: params.agentIds || [],
priority: params.priority || 1,
taskId: params.taskId,
timestamp: new Date().toISOString(),
status: 'coordinated',
},
};
},
metadata: {
agentId: config.kaiban?.agentId,
category: 'coordination',
permissions: ['coordinate', 'lock', 'sync'],
},
};
}
//# sourceMappingURL=kaiban-js.js.map