Spaces:
Sleeping
Sleeping
File size: 7,450 Bytes
1ea26af |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
#!/usr/bin/env python3
# NOTICE: This file is adapted from Tencent's CognitiveKernel-Pro (https://github.com/Tencent/CognitiveKernel-Pro).
# Modifications in this fork (2025) are for academic research and educational use only; no commercial use.
# Original rights belong to the original authors and Tencent; see upstream license for details.
"""
Clean CLI interface for CognitiveKernel-Pro
Simple, direct interface for reasoning tasks.
Following Linus principles:
- Do one thing well
- Fail fast
- Simple interfaces
- No magic
"""
import argparse
import sys
import time
from pathlib import Path
from typing import Iterator, Dict, Any, Optional
try:
from .core import CognitiveKernel, ReasoningResult
from .agents.utils import rprint
from .config.settings import Settings
except ImportError:
# Direct execution fallback
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent))
from ck_pro.core import CognitiveKernel, ReasoningResult
from ck_pro.agents.utils import rprint
from ck_pro.config.settings import Settings
def get_args():
"""Parse command line arguments - simple and direct"""
parser = argparse.ArgumentParser(
prog="ck-pro",
description="CognitiveKernel-Pro: Clean reasoning interface"
)
# Core arguments
parser.add_argument(
"-c", "--config",
type=str,
default="config.toml",
help="Configuration file path (default: config.toml)"
)
# Input/Output
parser.add_argument(
"question",
nargs="?",
help="Single question to reason about"
)
parser.add_argument(
"-i", "--input",
type=str,
help="Input file (text/questions) for batch processing"
)
parser.add_argument(
"-o", "--output",
type=str,
help="Output file for results (JSON format)"
)
# Behavior
parser.add_argument(
"--interactive",
action="store_true",
help="Interactive mode - prompt for questions"
)
parser.add_argument(
"--verbose", "-v",
action="store_true",
help="Verbose output with timing and step information"
)
parser.add_argument(
"--max-steps",
type=int,
help="Maximum reasoning steps (overrides config)"
)
parser.add_argument(
"--timeout",
type=int,
help="Timeout in seconds (overrides config)"
)
return parser.parse_args()
def read_questions(input_source: Optional[str]) -> Iterator[Dict[str, Any]]:
"""
Read questions from various sources.
Args:
input_source: File path, question string, or None for interactive
Yields:
Dict with 'id', 'question'
"""
if not input_source:
# Interactive mode
idx = 0
while True:
try:
question = input("Question: ").strip()
if not question or question.lower() in ['quit', 'exit', '__END__']:
break
yield {
'id': f"interactive_{idx:04d}",
'question': question
}
idx += 1
except (KeyboardInterrupt, EOFError):
break
elif Path(input_source).exists():
# File input - read plain text file with one question per line
idx = 0
with open(input_source, 'r') as f:
for line_num, line in enumerate(f, 1):
question = line.strip()
if not question:
continue
yield {
'id': f"file_{idx:04d}",
'question': question
}
idx += 1
else:
# Treat as single question string
yield {
'id': 'single_question',
'question': input_source
}
def write_result(result_data: Dict[str, Any], output_file: Optional[str] = None):
"""Write result to output file or stdout"""
if output_file:
with open(output_file, 'a') as f:
f.write(result_data['answer'] + '\n')
else:
# Pretty print to stdout
if 'answer' in result_data:
print(f"Answer: {result_data['answer']}")
if 'reasoning_steps' in result_data:
print(f"Steps: {result_data['reasoning_steps']}")
if 'execution_time' in result_data:
print(f"Time: {result_data['execution_time']:.2f}s")
def main():
"""Main CLI entry point"""
args = get_args()
try:
# Create kernel (supports env-only when no TOML file)
settings = Settings.load(args.config)
kernel = CognitiveKernel(settings)
if args.verbose:
if Path(args.config).exists():
rprint(f"[blue]Loaded configuration from {args.config}[/blue]")
else:
rprint("[blue]No config file found; using environment variables (if set) or built-in defaults[/blue]")
# Prepare output file
if args.output:
# Clear output file
Path(args.output).write_text('')
# Process questions
total_questions = 0
successful_answers = 0
total_time = 0.0
# Build reasoning kwargs
reasoning_kwargs = {}
if args.max_steps:
reasoning_kwargs['max_steps'] = args.max_steps
if args.timeout:
reasoning_kwargs['max_time_limit'] = args.timeout
if args.verbose:
reasoning_kwargs['include_session'] = True
# Determine input source: positional argument, --input flag, or interactive
input_source = args.question or args.input
if not input_source and not args.interactive:
rprint("[red]Error: No question provided. Use a positional argument, --input, or --interactive[/red]")
sys.exit(1)
for question_data in read_questions(input_source):
total_questions += 1
question = question_data['question']
try:
# Reason about the question
result = kernel.reason(question, **reasoning_kwargs)
# Write result
reasoning_steps = len(result.session.steps) if result.session else 0
result_data = {
'answer': result.answer,
'reasoning_steps': reasoning_steps,
'execution_time': result.execution_time
}
write_result(result_data, args.output)
successful_answers += 1
total_time += result.execution_time
except Exception as e:
raise RuntimeError(f"Processing failed: {e}") from e
# Summary
if total_questions > 1:
rprint(f"\n[blue]Summary:[/blue]")
rprint(f" Total questions: {total_questions}")
rprint(f" Successful: {successful_answers}")
rprint(f" Failed: {total_questions - successful_answers}")
rprint(f" Total time: {total_time:.2f}s")
if successful_answers > 0:
rprint(f" Average time: {total_time/successful_answers:.2f}s")
except KeyboardInterrupt:
rprint("\n[yellow]Interrupted by user[/yellow]")
sys.exit(1)
except Exception as e:
rprint(f"[red]Fatal error: {e}[/red]")
sys.exit(1)
if __name__ == "__main__":
main()
|