codent 0.3.4__tar.gz → 0.3.6__tar.gz
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.
- {codent-0.3.4 → codent-0.3.6}/PKG-INFO +1 -1
- {codent-0.3.4 → codent-0.3.6}/codent.egg-info/PKG-INFO +1 -1
- {codent-0.3.4 → codent-0.3.6}/core/context_utils.py +3 -0
- {codent-0.3.4 → codent-0.3.6}/core/identity.py +14 -88
- {codent-0.3.4 → codent-0.3.6}/core/init_cmd.py +67 -1
- {codent-0.3.4 → codent-0.3.6}/core/prompts.py +44 -126
- {codent-0.3.4 → codent-0.3.6}/core/tool_helpers.py +3 -3
- {codent-0.3.4 → codent-0.3.6}/pyproject.toml +1 -1
- {codent-0.3.4 → codent-0.3.6}/codent.egg-info/SOURCES.txt +0 -0
- {codent-0.3.4 → codent-0.3.6}/codent.egg-info/dependency_links.txt +0 -0
- {codent-0.3.4 → codent-0.3.6}/codent.egg-info/entry_points.txt +0 -0
- {codent-0.3.4 → codent-0.3.6}/codent.egg-info/requires.txt +0 -0
- {codent-0.3.4 → codent-0.3.6}/codent.egg-info/top_level.txt +0 -0
- {codent-0.3.4 → codent-0.3.6}/cont.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/cont_ui/__init__.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/cont_ui/frontend.html +0 -0
- {codent-0.3.4 → codent-0.3.6}/cont_ui/server.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/cont_watcher.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/__init__.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/adaptive_prompt.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/advanced_overnight.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/anomaly_tools.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/app.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/auto_eval.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/automations.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/benchmark.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/bridge_server.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/browser.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/browser_agent.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/budget_committee.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/cc_auditor.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/cleaning_tools.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/cli.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/curriculum_runner.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/daemon.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/data_tools.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/decomposer.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/domain_tools.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/endpoint_discovery.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/env_snapshot.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/episodic.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/escalation.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/events.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/feedback_training.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/file_context.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/fitness.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/formatters.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/genesis.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/golden_test_runner.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/guardian.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/hive_recall.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/intent_detection.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/intent_gate.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/learning_loop.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/lmstudio.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/local_llm.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/memory_eviction.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/memory_gate.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/memory_store.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/ml_tools.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/model.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/model_routing.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/network_audit.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/ocr.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/overfit_test.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/overnight_training.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/path_resolution.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/postprocess.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/prefetch.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/prompt_patches.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/provider_router.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/quick_overfit_test.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/recipe_factory.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/recipe_feedback.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/recipe_learner.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/recipes.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/relation_discovery.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/relay.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/repl.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/router.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/rpc.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/run_logger.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/runtime.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/safety.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/scheduler.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/scratchpad.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/self_improve.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/spreading_activation.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/sql_guard.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/sticky_config.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/structured_output.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/system_executor.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/system_map.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/task_classifier.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/task_utils.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/teacher.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/tool_budget.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/tool_schemas.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/tools.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/trace.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/types.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/utils.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/verification.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/verify_minions.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/vocabulary.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/voice.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/web.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/core/yis_deep_training.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/setup.cfg +0 -0
- {codent-0.3.4 → codent-0.3.6}/tests/test_auto_eval.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/tests/test_browser.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/tests/test_browser_agent.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/tests/test_commands_and_teach.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/tests/test_cont.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/tests/test_corpus_parser.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/tests/test_episodic.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/tests/test_eviction.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/tests/test_formatters.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/tests/test_golden.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/tests/test_health_report_valid_json.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/tests/test_integrity_and_memory_gate.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/tests/test_known_bugs.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/tests/test_model_agnostic.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/tests/test_new_tools.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/tests/test_provider_router.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/tests/test_recipes.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/tests/test_teacher.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/tests/test_verification.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/tests/test_web_fetch.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/vendor/__init__.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/vendor/bin/__init__.py +0 -0
- {codent-0.3.4 → codent-0.3.6}/vendor/bin/ollama +0 -0
- {codent-0.3.4 → codent-0.3.6}/vendor/wheels/__init__.py +0 -0
|
@@ -447,93 +447,19 @@ def get_current_state() -> dict:
|
|
|
447
447
|
return {"_fresh": False}
|
|
448
448
|
|
|
449
449
|
def get_startup_context() -> str:
|
|
450
|
-
"""Build startup context
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
450
|
+
"""Build minimal per-turn startup context (location only).
|
|
451
|
+
|
|
452
|
+
ADIM 2: Memory/learning/automation stats kaldırıldı.
|
|
453
|
+
Bunlar on-demand:
|
|
454
|
+
- Hafıza → memory_gate proaktif inject
|
|
455
|
+
- Recipes/vocabulary → recall tool
|
|
456
|
+
- Automations → list_automations tool
|
|
457
|
+
- Live state → where_am_i tool
|
|
458
|
+
"""
|
|
454
459
|
cont_home = get_cont_home()
|
|
455
460
|
cwd = Path.cwd()
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
-
|
|
460
|
-
|
|
461
|
-
- In my home: {cwd.resolve() == cont_home.resolve()}
|
|
462
|
-
""")
|
|
463
|
-
|
|
464
|
-
# 2. Current state (if watcher is running)
|
|
465
|
-
state = get_current_state()
|
|
466
|
-
if state:
|
|
467
|
-
context_parts.append("## Live System State")
|
|
468
|
-
|
|
469
|
-
if "recent_files" in state:
|
|
470
|
-
recent = state["recent_files"][:5]
|
|
471
|
-
if recent:
|
|
472
|
-
context_parts.append("Recent file changes:")
|
|
473
|
-
for f in recent:
|
|
474
|
-
context_parts.append(f" - {f.get('action', '?')}: {f.get('path', '?')} ({f.get('time', '?')})")
|
|
475
|
-
|
|
476
|
-
if "recent_commands" in state:
|
|
477
|
-
recent = state["recent_commands"][:5]
|
|
478
|
-
if recent:
|
|
479
|
-
context_parts.append("Recent commands:")
|
|
480
|
-
for c in recent:
|
|
481
|
-
context_parts.append(f" - {c.get('cmd', '?')} ({c.get('time', '?')})")
|
|
482
|
-
|
|
483
|
-
if "git_status" in state:
|
|
484
|
-
git = state["git_status"]
|
|
485
|
-
context_parts.append(f"Git: branch={git.get('branch', '?')}, uncommitted={git.get('uncommitted_changes', 0)}")
|
|
486
|
-
|
|
487
|
-
# 3. Key memories (lazy import to avoid circular deps)
|
|
488
|
-
try:
|
|
489
|
-
from core.memory_store import memory_get_context
|
|
490
|
-
key_memories = memory_get_context(limit=5)
|
|
491
|
-
if key_memories:
|
|
492
|
-
context_parts.append("\n## Key Memories")
|
|
493
|
-
for mem in key_memories:
|
|
494
|
-
context_parts.append(f"- [{mem['memory_type']}] {mem['content']}")
|
|
495
|
-
except Exception:
|
|
496
|
-
pass
|
|
497
|
-
|
|
498
|
-
# 4. Learning system stats (lazy imports)
|
|
499
|
-
try:
|
|
500
|
-
from core.vocabulary import get_vocabulary_stats
|
|
501
|
-
from core.recipes import load_recipes
|
|
502
|
-
from core.prompt_patches import load_file_patches
|
|
503
|
-
learning_parts = []
|
|
504
|
-
# Vocabulary
|
|
505
|
-
vstats = get_vocabulary_stats()
|
|
506
|
-
if vstats.get("total", 0) > 0:
|
|
507
|
-
learning_parts.append(f"Vocabulary: {vstats['commands']} commands, {vstats['context_words']} context words")
|
|
508
|
-
# Recipes
|
|
509
|
-
recipes = load_recipes()
|
|
510
|
-
if recipes:
|
|
511
|
-
learning_parts.append(f"Recipes: {len(recipes)} loaded")
|
|
512
|
-
# File patches
|
|
513
|
-
patches = load_file_patches()
|
|
514
|
-
if patches:
|
|
515
|
-
active = sum(1 for p in patches if p.get("active", True))
|
|
516
|
-
learning_parts.append(f"Patches: {active} active")
|
|
517
|
-
|
|
518
|
-
if learning_parts:
|
|
519
|
-
context_parts.append("\n## Learning System")
|
|
520
|
-
for lp in learning_parts:
|
|
521
|
-
context_parts.append(f"- {lp}")
|
|
522
|
-
except Exception:
|
|
523
|
-
pass
|
|
524
|
-
|
|
525
|
-
# 5. Automation system stats (lazy import)
|
|
526
|
-
try:
|
|
527
|
-
from core.automations import load_automations
|
|
528
|
-
autos = load_automations()
|
|
529
|
-
if autos:
|
|
530
|
-
enabled = sum(1 for a in autos if a.get("enabled", True))
|
|
531
|
-
context_parts.append(f"\n## Automations")
|
|
532
|
-
context_parts.append(f"- {enabled}/{len(autos)} automations enabled")
|
|
533
|
-
enabled_names = [a["name"] for a in autos if a.get("enabled", True)]
|
|
534
|
-
if enabled_names:
|
|
535
|
-
context_parts.append(f"- Active: {', '.join(enabled_names[:5])}")
|
|
536
|
-
except Exception:
|
|
537
|
-
pass
|
|
538
|
-
|
|
539
|
-
return "\n".join(context_parts)
|
|
461
|
+
return (
|
|
462
|
+
f"## Current Location\n"
|
|
463
|
+
f"- My home: {cont_home}\n"
|
|
464
|
+
f"- CWD: {cwd}\n"
|
|
465
|
+
)
|
|
@@ -109,13 +109,79 @@ def _model_exists(ollama_bin: str, model_name: str) -> bool:
|
|
|
109
109
|
return False
|
|
110
110
|
|
|
111
111
|
|
|
112
|
+
_QWEN3_CODER_TEMPLATE = '''{{- if .Messages }}
|
|
113
|
+
{{- if or .System .Tools }}<|im_start|>system
|
|
114
|
+
{{- if .System }}
|
|
115
|
+
{{ .System }}
|
|
116
|
+
{{- end }}
|
|
117
|
+
{{- if .Tools }}
|
|
118
|
+
|
|
119
|
+
# Tools
|
|
120
|
+
|
|
121
|
+
You may call one or more functions to assist with the user query.
|
|
122
|
+
|
|
123
|
+
You are provided with function signatures within <tools></tools> XML tags:
|
|
124
|
+
<tools>
|
|
125
|
+
{{- range .Tools }}
|
|
126
|
+
{"type": "function", "function": {{ .Function }}}
|
|
127
|
+
{{- end }}
|
|
128
|
+
</tools>
|
|
129
|
+
|
|
130
|
+
For each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:
|
|
131
|
+
<tool_call>
|
|
132
|
+
{"name": <function-name>, "arguments": <args-json-object>}
|
|
133
|
+
</tool_call>
|
|
134
|
+
{{- end }}<|im_end|>
|
|
135
|
+
{{ end }}
|
|
136
|
+
{{- range $i, $_ := .Messages }}
|
|
137
|
+
{{- $last := eq (len (slice $.Messages $i)) 1 -}}
|
|
138
|
+
{{- if eq .Role "user" }}<|im_start|>user
|
|
139
|
+
{{ .Content }}<|im_end|>
|
|
140
|
+
{{ else if eq .Role "assistant" }}<|im_start|>assistant
|
|
141
|
+
{{ if .Content }}{{ .Content }}
|
|
142
|
+
{{- else if .ToolCalls }}<tool_call>
|
|
143
|
+
{{ range .ToolCalls }}{"name": "{{ .Function.Name }}", "arguments": {{ .Function.Arguments }}}
|
|
144
|
+
{{ end }}</tool_call>
|
|
145
|
+
{{- end }}{{ if not $last }}<|im_end|>
|
|
146
|
+
{{ end }}
|
|
147
|
+
{{- else if eq .Role "tool" }}<|im_start|>user
|
|
148
|
+
<tool_response>
|
|
149
|
+
{{ .Content }}
|
|
150
|
+
</tool_response><|im_end|>
|
|
151
|
+
{{ end }}
|
|
152
|
+
{{- if and (ne .Role "assistant") $last }}<|im_start|>assistant
|
|
153
|
+
{{ end }}
|
|
154
|
+
{{- end }}
|
|
155
|
+
{{- else }}
|
|
156
|
+
{{- if .System }}<|im_start|>system
|
|
157
|
+
{{ .System }}<|im_end|>
|
|
158
|
+
{{ end }}{{ if .Prompt }}<|im_start|>user
|
|
159
|
+
{{ .Prompt }}<|im_end|>
|
|
160
|
+
{{ end }}<|im_start|>assistant
|
|
161
|
+
{{ end }}{{ .Response }}{{ if .Response }}<|im_end|>{{ end }}'''
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def _build_modelfile(gguf_path: Path) -> str:
|
|
165
|
+
"""Qwen3-Coder tool-calling template + parameters."""
|
|
166
|
+
return (
|
|
167
|
+
f"FROM {gguf_path}\n\n"
|
|
168
|
+
f'TEMPLATE """{_QWEN3_CODER_TEMPLATE}"""\n\n'
|
|
169
|
+
'PARAMETER num_ctx 10000\n'
|
|
170
|
+
'PARAMETER temperature 0.1\n'
|
|
171
|
+
'PARAMETER stop "<|im_start|>"\n'
|
|
172
|
+
'PARAMETER stop "<|im_end|>"\n'
|
|
173
|
+
'PARAMETER stop "<|endoftext|>"\n\n'
|
|
174
|
+
'SYSTEM """You are a helpful coding assistant."""\n'
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
|
|
112
178
|
def _create_model_from_gguf(ollama_bin: str, gguf_path: Path,
|
|
113
179
|
model_name: str = "cont-local") -> bool:
|
|
114
180
|
"""Generate Modelfile + run `ollama create`."""
|
|
115
181
|
print(f"[*] {model_name} modeli {gguf_path.name} GGUF'undan oluşturuluyor...")
|
|
116
182
|
modelfile = Path.home() / ".cache" / "cont" / "Modelfile.cont"
|
|
117
183
|
modelfile.parent.mkdir(parents=True, exist_ok=True)
|
|
118
|
-
modelfile.write_text(
|
|
184
|
+
modelfile.write_text(_build_modelfile(gguf_path), encoding="utf-8")
|
|
119
185
|
|
|
120
186
|
try:
|
|
121
187
|
subprocess.run(
|
|
@@ -34,95 +34,13 @@ def _get_identity_context():
|
|
|
34
34
|
return "", "", ""
|
|
35
35
|
|
|
36
36
|
EVIDENCE_RULES = """
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
1. CITE YOUR SOURCE: Every factual claim must reference a specific tool call.
|
|
40
|
-
BAD: "The file contains a function called main()"
|
|
41
|
-
GOOD: "read_file('app.py') returned content showing line 15: 'def main():'"
|
|
42
|
-
|
|
43
|
-
2. DISTINGUISH VERIFIED vs UNVERIFIED:
|
|
44
|
-
- VERIFIED: Information from tool calls THIS session
|
|
45
|
-
- UNVERIFIED: Your training knowledge (mark with "[FROM KNOWLEDGE]")
|
|
46
|
-
|
|
47
|
-
3. FORBIDDEN PHRASES (will trigger verification failure):
|
|
48
|
-
- "I assume..."
|
|
49
|
-
- "Typically..."
|
|
50
|
-
- "Usually..."
|
|
51
|
-
- "The file probably..."
|
|
52
|
-
- "Standard practice suggests..."
|
|
53
|
-
- "It should have..."
|
|
54
|
-
- "Most likely..."
|
|
55
|
-
|
|
56
|
-
4. MANDATORY VERIFICATION after file operations:
|
|
57
|
-
- After write_file -> read_file to confirm
|
|
58
|
-
- After run_shell -> check exit code, parse output
|
|
59
|
-
- After repo_fetch -> list_dir on returned path
|
|
60
|
-
|
|
61
|
-
5. WHEN UNCERTAIN: Say "I did not verify this" or ask for clarification.
|
|
62
|
-
|
|
63
|
-
6. EMPTY/ERROR RESULTS: If a tool returns empty or error:
|
|
64
|
-
- Report exactly what happened
|
|
65
|
-
- Do NOT invent alternative results
|
|
66
|
-
- Do NOT guess what "should" be there
|
|
37
|
+
EVIDENCE: Tool sonucu olmadan tablo/kolon/satır/sayı iddia etme. Her iddia bu session'daki bir tool çıktısına dayanmalı. Tool boş döndüyse "boş döndü" de — alternatif uydurma. Bilmiyorsan "bilmiyorum" veya "doğrulamadım" de.
|
|
67
38
|
"""
|
|
68
39
|
|
|
69
|
-
STRUCTURED_RESPONSE_FORMAT = ""
|
|
70
|
-
FORMAT YOUR FINAL RESPONSE AS:
|
|
71
|
-
|
|
72
|
-
## Verified Facts
|
|
73
|
-
List each fact with its source tool call:
|
|
74
|
-
- [read_file('path')] Found: <exact content snippet>
|
|
75
|
-
- [list_dir('path')] Contents: <actual listing>
|
|
76
|
-
- [run_shell('cmd')] Exit code: X, Output: <summary>
|
|
77
|
-
|
|
78
|
-
## Actions Taken
|
|
79
|
-
List each action with verification:
|
|
80
|
-
- [write_file('path')] Created/Modified file
|
|
81
|
-
- [VERIFIED via read_file: content matches]
|
|
82
|
-
- [run_shell('cmd')] Executed command
|
|
83
|
-
- [VERIFIED: exit code 0, output shows success]
|
|
84
|
-
|
|
85
|
-
## Unverified Information (if any)
|
|
86
|
-
- [FROM KNOWLEDGE] <information from training, not tools>
|
|
87
|
-
|
|
88
|
-
## Answer
|
|
89
|
-
<Your actual response to the user>
|
|
90
|
-
"""
|
|
40
|
+
STRUCTURED_RESPONSE_FORMAT = "" # ADIM 3: silindi (Cont kullanıcıya bu şablonu göstermiyordu zaten)
|
|
91
41
|
|
|
92
42
|
MEMORY_INSTRUCTIONS = """
|
|
93
|
-
MEMORY
|
|
94
|
-
You have persistent memory across conversations. Use it wisely:
|
|
95
|
-
|
|
96
|
-
1. PROACTIVE REMEMBERING: When you learn something important about the user or project,
|
|
97
|
-
use the 'remember' tool immediately. Don't wait to be asked.
|
|
98
|
-
- User mentions their name, role, preferences -> remember
|
|
99
|
-
- Project details, tech stack, conventions -> remember
|
|
100
|
-
- User corrects you or gives feedback -> remember as preference
|
|
101
|
-
|
|
102
|
-
2. PROACTIVE RECALL: Before making assumptions, check your memory:
|
|
103
|
-
- Starting a task? recall("project context")
|
|
104
|
-
- User asks about preferences? recall("user preference")
|
|
105
|
-
- Unsure about something discussed before? recall relevant terms
|
|
106
|
-
|
|
107
|
-
3. MEMORY TYPES:
|
|
108
|
-
- fact: Objective info ("User's name is Sertan", "Project uses FastAPI")
|
|
109
|
-
- preference: Likes/dislikes ("User prefers short answers", "Dislikes verbose output")
|
|
110
|
-
- context: Situational ("Working on RAG project", "Debugging auth module")
|
|
111
|
-
- skill: Learned capabilities ("User taught me to use pytest this way")
|
|
112
|
-
|
|
113
|
-
4. IMPORTANCE LEVELS:
|
|
114
|
-
- 0.9: Critical (name, key preferences, project identity)
|
|
115
|
-
- 0.7: Important (tech choices, patterns, frequent requests)
|
|
116
|
-
- 0.5: Normal (general context, one-time info)
|
|
117
|
-
- 0.3: Low (temporary context, might change)
|
|
118
|
-
|
|
119
|
-
5. EXAMPLES:
|
|
120
|
-
User: "I'm Sertan and I prefer Turkish responses"
|
|
121
|
-
-> remember("User's name is Sertan", "fact", 0.9)
|
|
122
|
-
-> remember("User prefers responses in Turkish", "preference", 0.8)
|
|
123
|
-
|
|
124
|
-
User: "Show me the config"
|
|
125
|
-
-> recall("config preference") first to check if user has display preferences
|
|
43
|
+
MEMORY: remember(content, type, importance) ile önemli bilgileri kaydet (importance 0.1-1.0; isim/tercih=0.9, normal=0.5). Soru gelince recall(query) ile ara. Proaktif kaydet, sorulunca hatırla.
|
|
126
44
|
"""
|
|
127
45
|
|
|
128
46
|
ANTI_LOOP_RULES = """
|
|
@@ -203,48 +121,23 @@ You are running in WSL (Windows Subsystem for Linux). Users may give paths in va
|
|
|
203
121
|
"""
|
|
204
122
|
|
|
205
123
|
CONVERSATION_CONTEXT_RULES = """
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
1. REFERENCE RESOLUTION:
|
|
209
|
-
- "that file" -> Look at previous turns, find mentioned file
|
|
210
|
-
- "search better" -> Use same target, improve search strategy
|
|
211
|
-
- "do it" -> Execute the action you suggested
|
|
212
|
-
- "there" / "that folder" -> Location from previous context
|
|
213
|
-
|
|
214
|
-
2. CONTINUITY:
|
|
215
|
-
- Remember paths, files, and targets from earlier turns
|
|
216
|
-
- If user gives partial info, combine with previous context
|
|
217
|
-
- Don't ask for info that was already provided
|
|
218
|
-
|
|
219
|
-
3. CONTEXT PRIORITY:
|
|
220
|
-
- Current request > Recent turns > Older turns
|
|
221
|
-
- If conflict, ask for clarification
|
|
222
|
-
|
|
223
|
-
4. EXAMPLES:
|
|
224
|
-
Turn 1: "find PDF at /path/to/data"
|
|
225
|
-
Turn 2: "search in html folder too"
|
|
226
|
-
-> Combine: search /path/to/data AND /path/to/html
|
|
227
|
-
|
|
228
|
-
Turn 1: "list files in project"
|
|
229
|
-
Turn 2: "open the config one"
|
|
230
|
-
-> Find config file from Turn 1 results, open it
|
|
124
|
+
CONTEXT: Kullanıcı "o dosya / şunu yap / devam et / orada" derse önceki turn'deki dosya/tool/görev referansını kullan. Daha önce verilen bilgiyi tekrar sorma.
|
|
231
125
|
"""
|
|
232
126
|
|
|
233
127
|
QUICK_ANSWER_RULES = """
|
|
234
128
|
VERİMLİLİK KURALLARI / EFFICIENCY RULES:
|
|
235
|
-
1. "list dir" veya "klasörü listele" = SADECE list_dir
|
|
236
|
-
2. Basit komutlar (list, show, find, bul, göster) için
|
|
129
|
+
1. "list dir" veya "klasörü listele" / "dosyaları listele" = SADECE list_dir tool'unu çağır (path="."). İzin sorma, JSON gösterme — DİREKT ÇAĞIR.
|
|
130
|
+
2. Basit komutlar (list, show, find, bul, göster, oku, aç, listele) için TEK tool çağrısı yap. Sonra cevap ver.
|
|
237
131
|
3. İlk tool sonucu yeterliyse HEMEN cevap ver, ekstra arama yapma.
|
|
238
|
-
4. "
|
|
239
|
-
5.
|
|
240
|
-
6.
|
|
241
|
-
7.
|
|
242
|
-
Do NOT over-search.
|
|
243
|
-
|
|
244
|
-
SELF-REFERENCE SHORTCUTS
|
|
245
|
-
- "cont log"
|
|
246
|
-
- "cont klasörü" = workspace root
|
|
247
|
-
- "kendi logların" = logs/cont_runs/ altında.
|
|
132
|
+
4. "show file" / "dosyayı göster" / "oku" → ONE read_file call, then answer.
|
|
133
|
+
5. "X loglarını aç" = system_search ile "X" + "log" ara, sonra open_file ile aç.
|
|
134
|
+
6. KULLANICIYA İZİN SORMA — kullanıcı zaten istedi. Tool'u çağır, sonucu ver.
|
|
135
|
+
7. JSON tool çağrısını cevap metninde GÖSTERME — gerçekten çağır (tool_calls).
|
|
136
|
+
Do NOT over-search. Do NOT ask permission. CALL the tool, return result.
|
|
137
|
+
|
|
138
|
+
SELF-REFERENCE SHORTCUTS:
|
|
139
|
+
- "cont log" / "cont loglarını" / "loglarım" = logs/cont_runs/. open_in_explorer ile aç.
|
|
140
|
+
- "cont klasörü" / "kendin" = workspace root.
|
|
248
141
|
"""
|
|
249
142
|
|
|
250
143
|
WORKFLOW_RULES = """
|
|
@@ -257,8 +150,30 @@ WORKFLOW:
|
|
|
257
150
|
SAFETY: Stay inside repo root. Dangerous commands are blocked.
|
|
258
151
|
"""
|
|
259
152
|
|
|
153
|
+
_SYSTEM_PROMPT_CACHE: dict = {}
|
|
154
|
+
_SYSTEM_PROMPT_CACHE_TS: float = 0.0
|
|
155
|
+
_SYSTEM_PROMPT_CACHE_TTL = 300.0 # 5 dakika
|
|
156
|
+
|
|
157
|
+
|
|
260
158
|
def build_system_prompt(repo_root: str, tool_budget: int, strict_mode: bool = True) -> str:
|
|
261
|
-
"""Build the complete system prompt with identity and context.
|
|
159
|
+
"""Build the complete system prompt with identity and context.
|
|
160
|
+
|
|
161
|
+
ADIM 4: 5 dakikalık TTL cache.
|
|
162
|
+
Key: (repo_root, cwd, tool_budget, strict_mode).
|
|
163
|
+
İlk çağrı I/O yapar (~700ms cold), sonrakiler <1ms.
|
|
164
|
+
"""
|
|
165
|
+
import time
|
|
166
|
+
from pathlib import Path
|
|
167
|
+
global _SYSTEM_PROMPT_CACHE_TS
|
|
168
|
+
|
|
169
|
+
cache_key = (repo_root, str(Path.cwd()), tool_budget, strict_mode)
|
|
170
|
+
now = time.time()
|
|
171
|
+
if (now - _SYSTEM_PROMPT_CACHE_TS) > _SYSTEM_PROMPT_CACHE_TTL:
|
|
172
|
+
_SYSTEM_PROMPT_CACHE.clear()
|
|
173
|
+
_SYSTEM_PROMPT_CACHE_TS = now
|
|
174
|
+
cached = _SYSTEM_PROMPT_CACHE.get(cache_key)
|
|
175
|
+
if cached is not None:
|
|
176
|
+
return cached
|
|
262
177
|
|
|
263
178
|
# Get identity
|
|
264
179
|
try:
|
|
@@ -297,12 +212,15 @@ TOOL BUDGET: {tool_budget} calls maximum. Plan efficiently.
|
|
|
297
212
|
base += "\n" + EVIDENCE_RULES
|
|
298
213
|
base += "\n" + STRUCTURED_RESPONSE_FORMAT
|
|
299
214
|
|
|
300
|
-
|
|
215
|
+
# ADIM 1: Duplikasyonlar silindi (runtime garantili)
|
|
216
|
+
# ANTI_LOOP_RULES — tool_budget + cooldown set
|
|
217
|
+
# WRITE_PROTECTION_RULES — safety.py TIER kontrolleri
|
|
218
|
+
# PATH_RESOLUTION_RULES — path normalize otomatik
|
|
219
|
+
# BASE_CAPABILITIES — Ollama tools schema bloğu
|
|
301
220
|
base += "\n" + MEMORY_INSTRUCTIONS
|
|
302
|
-
base += "\n" + WRITE_PROTECTION_RULES
|
|
303
|
-
base += "\n" + PATH_RESOLUTION_RULES
|
|
304
221
|
base += "\n" + CONVERSATION_CONTEXT_RULES
|
|
305
222
|
base += "\n" + QUICK_ANSWER_RULES
|
|
306
223
|
base += "\n" + WORKFLOW_RULES
|
|
307
224
|
|
|
225
|
+
_SYSTEM_PROMPT_CACHE[cache_key] = base
|
|
308
226
|
return base
|
|
@@ -97,9 +97,9 @@ def extract_fenced_tool_requests(text: str) -> list:
|
|
|
97
97
|
|
|
98
98
|
# b2) <tools>...</tools> wrapper (Qwen3-Coder bare emit) — may contain
|
|
99
99
|
# one or more JSON objects, possibly without closing </tools> tag.
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
wrapper_match = re.search(r'
|
|
100
|
+
# Also catches <.tools>, <tool>, <Tool>, <.tool> variants.
|
|
101
|
+
if re.search(r'<\.?tools?>', text, re.IGNORECASE):
|
|
102
|
+
wrapper_match = re.search(r'<\.?tools?>\s*(.*?)(?:</\.?tools?>|$)', text, re.DOTALL | re.IGNORECASE)
|
|
103
103
|
if wrapper_match:
|
|
104
104
|
inner = wrapper_match.group(1).strip()
|
|
105
105
|
# Try parse as single dict, list, or multiple concatenated dicts
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|