+
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions agents-cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@ import { listAgentsCommand } from './commands/list-agents';
import { pullProjectCommand } from './commands/pull';
import { pushCommand } from './commands/push';

// Get the current directory for ESM
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

// Read package.json to get version
const packageJsonPath = join(__dirname, '..', 'package.json');
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));

Expand All @@ -26,7 +24,6 @@ program
.description('CLI tool for Inkeep Agent Framework')
.version(packageJson.version);

// Add command
program
.command('add [template]')
.description('Add a new template to the project')
Expand All @@ -36,7 +33,6 @@ program
await addCommand({ template, ...options });
});

// Init command
program
.command('init [path]')
.description('Initialize a new Inkeep configuration file')
Expand All @@ -46,7 +42,6 @@ program
await initCommand({ path, ...options });
});

// Config command with subcommands
const configCommand = program.command('config').description('Manage Inkeep configuration');

configCommand
Expand All @@ -55,7 +50,6 @@ configCommand
.option('--config <path>', 'Path to configuration file')
.option('--config-file-path <path>', 'Path to configuration file (deprecated, use --config)')
.action(async (key, options) => {
// Support both --config and --config-file-path for backward compatibility
const config = options.config || options.configFilePath;
await configGetCommand(key, { config });
});
Expand All @@ -66,7 +60,6 @@ configCommand
.option('--config <path>', 'Path to configuration file')
.option('--config-file-path <path>', 'Path to configuration file (deprecated, use --config)')
.action(async (key, value, options) => {
// Support both --config and --config-file-path for backward compatibility
const config = options.config || options.configFilePath;
await configSetCommand(key, value, { config });
});
Expand All @@ -77,12 +70,10 @@ configCommand
.option('--config <path>', 'Path to configuration file')
.option('--config-file-path <path>', 'Path to configuration file (deprecated, use --config)')
.action(async (options) => {
// Support both --config and --config-file-path for backward compatibility
const config = options.config || options.configFilePath;
await configListCommand({ config });
});

// Push command
program
.command('push')
.description('Push a project configuration to the backend')
Expand All @@ -100,7 +91,6 @@ program
await pushCommand(options);
});

// Pull command (project-based)
program
.command('pull')
.description('Pull entire project configuration from backend and update local files')
Expand All @@ -117,7 +107,6 @@ program
await pullProjectCommand(options);
});

// Chat command
program
.command('chat [agent-id]')
.description(
Expand All @@ -129,14 +118,11 @@ program
.option('--config <path>', 'Path to configuration file')
.option('--config-file-path <path>', 'Path to configuration file (deprecated, use --config)')
.action(async (agentId, options) => {
// Import the enhanced version with autocomplete
const { chatCommandEnhanced } = await import('./commands/chat-enhanced.js');
// Support both --config and --config-file-path for backward compatibility
const config = options.config || options.configFilePath;
await chatCommandEnhanced(agentId, { ...options, config });
});

// List agent command
program
.command('list-agent')
.description('List all available agent for a specific project')
Expand All @@ -146,12 +132,10 @@ program
.option('--config <path>', 'Path to configuration file')
.option('--config-file-path <path>', 'Path to configuration file (deprecated, use --config)')
.action(async (options) => {
// Support both --config and --config-file-path for backward compatibility
const config = options.config || options.configFilePath;
await listAgentsCommand({ ...options, config });
});

// Dev command
program
.command('dev')
.description('Start the Inkeep dashboard server')
Expand All @@ -172,5 +156,4 @@ program
});
});

// Parse command line arguments
program.parse();
27 changes: 4 additions & 23 deletions agents-run-api/src/middleware/api-key-auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,13 @@ import { getLogger } from '../logger';
import { createExecutionContext } from '../types/execution-context';

const logger = getLogger('env-key-auth');
/**
* Middleware to authenticate API requests using Bearer token authentication
* First checks if token matches INKEEP_AGENTS_RUN_API_BYPASS_SECRET, then falls back to API key validation
* Extracts and validates API keys, then adds execution context to the request
*/

export const apiKeyAuth = () =>
createMiddleware<{
Variables: {
executionContext: ExecutionContext;
};
}>(async (c, next) => {
// Skip authentication for OPTIONS requests (CORS preflight)
if (c.req.method === 'OPTIONS') {
await next();
return;
Expand All @@ -41,7 +36,6 @@ export const apiKeyAuth = () =>
? `${reqUrl.protocol}//${host}`
: `${reqUrl.origin}`;

// Bypass authentication only for integration tests with specific header
if (process.env.ENVIRONMENT === 'development' || process.env.ENVIRONMENT === 'test') {
let executionContext: ExecutionContext;

Expand All @@ -51,7 +45,6 @@ export const apiKeyAuth = () =>
executionContext.subAgentId = subAgentId;
logger.info({}, 'Development/test environment - API key authenticated successfully');
} catch {
// If API key extraction fails, fallback to default context
executionContext = createExecutionContext({
apiKey: 'development',
tenantId: tenantId || 'test-tenant',
Expand All @@ -67,7 +60,6 @@ export const apiKeyAuth = () =>
);
}
} else {
// No API key provided, use default context
executionContext = createExecutionContext({
apiKey: 'development',
tenantId: tenantId || 'test-tenant',
Expand All @@ -87,27 +79,23 @@ export const apiKeyAuth = () =>
await next();
return;
}
// Check for Bearer token

if (!authHeader || !authHeader.startsWith('Bearer ')) {
throw new HTTPException(401, {
message: 'Missing or invalid authorization header. Expected: Bearer <api_key>',
});
}

const apiKey = authHeader.substring(7); // Remove 'Bearer ' prefix
const apiKey = authHeader.substring(7);

// If bypass secret is configured, allow bypass authentication or api key validation
if (env.INKEEP_AGENTS_RUN_API_BYPASS_SECRET) {
if (apiKey === env.INKEEP_AGENTS_RUN_API_BYPASS_SECRET) {
// Extract base URL from request

if (!tenantId || !projectId || !agentId) {
throw new HTTPException(401, {
message: 'Missing or invalid tenant, project, or agent ID',
});
}

// Create bypass execution context with default values
const executionContext = createExecutionContext({
apiKey: apiKey,
tenantId: tenantId,
Expand Down Expand Up @@ -135,15 +123,12 @@ export const apiKeyAuth = () =>
await next();
return;
} else {
// Bypass secret is set but token doesn't match - reject
throw new HTTPException(401, {
message: 'Invalid Token',
});
}
}

// No bypass secret configured - continue with normal API key validation
// Validate API key format (basic validation)
if (!apiKey || apiKey.length < 16) {
throw new HTTPException(401, {
message: 'Invalid API key format',
Expand All @@ -156,7 +141,6 @@ export const apiKeyAuth = () =>

c.set('executionContext', executionContext);

// Log successful authentication (without sensitive data)
logger.debug(
{
tenantId: executionContext.tenantId,
Expand All @@ -169,12 +153,10 @@ export const apiKeyAuth = () =>

await next();
} catch (error) {
// Re-throw HTTPException
if (error instanceof HTTPException) {
throw error;
}

// Log unexpected errors and return generic message
logger.error({ error }, 'API key authentication error');
throw new HTTPException(500, {
message: 'Authentication failed',
Expand All @@ -200,6 +182,7 @@ export const extractContextFromApiKey = async (apiKey: string, baseUrl?: string)
baseUrl: baseUrl,
});
};

/**
* Helper middleware for endpoints that optionally support API key authentication
* If no auth header is present, it continues without setting the executionContext
Expand All @@ -212,12 +195,10 @@ export const optionalAuth = () =>
}>(async (c, next) => {
const authHeader = c.req.header('Authorization');

// If no auth header, continue without authentication
if (!authHeader || !authHeader.startsWith('Bearer ')) {
await next();
return;
}

// If auth header exists, use the regular auth middleware
return apiKeyAuth()(c as any, next);
});
Loading
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载