Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
9c99622
CLI Anything added
korivi-CraftOS Apr 13, 2026
5d121ea
Added name character limit to 20
korivi-CraftOS Apr 13, 2026
f85346b
Add CLI-Anything integration to crafbot
korivi-CraftOS Apr 13, 2026
139eae8
Grok KV caching issue fixed!
korivi-CraftOS Apr 14, 2026
26da4b9
Delete craftbot.pid
korivi-CraftOS Apr 14, 2026
403398f
Delete craftbot.log
korivi-CraftOS Apr 14, 2026
25f21c1
feat: add OCR and video analysis actions (#155)
AlanAAG Apr 14, 2026
5feaa80
CLI SKILLS Improvements
korivi-CraftOS Apr 15, 2026
7df6625
Merge branch 'feature/CLI' of https://github.com/CraftOS-dev/CraftBot…
korivi-CraftOS Apr 15, 2026
c49fe56
cli anything help guid added
korivi-CraftOS Apr 15, 2026
ec3dc67
CLI Skill updated
korivi-CraftOS Apr 16, 2026
fa0284e
improvement: use Gemini native video API as primary path in understan…
AlanAAG Apr 16, 2026
77d4d87
Major Issues are fixed
korivi-CraftOS Apr 16, 2026
6915894
fix(vlm): remove response_format json_object from byteplus, re-raise …
AlanAAG Apr 16, 2026
125cff4
fix(actions): split action_sets string into proper list in perform_oc…
AlanAAG Apr 16, 2026
247ee92
fix: wire independent VLM provider/model/key resolution and add avail…
AlanAAG Apr 16, 2026
f00ae32
refactor(vlm): unify multimodal, deduplicate OCR path, dynamic video …
AlanAAG Apr 17, 2026
53fa35c
Merge pull request #203 from CraftOS-dev/V1.2.3
ahmad-ajmal Apr 17, 2026
748c44f
Merge pull request #204 from CraftOS-dev/dev
ahmad-ajmal Apr 17, 2026
3d987b3
Merge pull request #205 from CraftOS-dev/staging
ahmad-ajmal Apr 17, 2026
9c5b41a
Merge branch 'main' into feature/CLI
ahmad-ajmal Apr 17, 2026
74aebad
Merge pull request #201 from CraftOS-dev/feature/CLI
ahmad-ajmal Apr 17, 2026
3fbe092
name limit on craftbot
ahmad-ajmal Apr 17, 2026
a17980b
Update settings.json
zfoong Apr 17, 2026
866601e
merge(vlm): resolve conflicts with dev branch, unify VLM providers an…
AlanAAG Apr 21, 2026
6c0b2c2
chore: remove test files from PR
AlanAAG Apr 21, 2026
670e5f0
update test deletion and future annotations for tests, prepared for f…
AlanAAG Apr 21, 2026
fdf9171
fix: unify mime-type to image/jpeg in generate_multimodal
AlanAAG Apr 21, 2026
29ee8a5
chore(config): revert personal dev config changes from settings, mcp_…
AlanAAG Apr 21, 2026
9552308
chore(actions): remove unused execute alias from perform_ocr and unde…
AlanAAG Apr 21, 2026
5e0a957
refactor(vlm): merge _openai_describe_bytes_plain into _openai_descri…
AlanAAG Apr 21, 2026
c97536e
fix(decorators): restore correct position of from __future__ import a…
AlanAAG Apr 21, 2026
932faad
chore: restore from __future__ import annotations across all files (r…
AlanAAG Apr 21, 2026
76e8c29
chore: remove temporary restore script
AlanAAG Apr 21, 2026
b71dee2
add comment on understand_video.py explaining dual path execution ins…
AlanAAG Apr 22, 2026
ecac851
add video to the action sets and define video in the DEFAULT_ST_DESCR…
AlanAAG Apr 22, 2026
2448bf6
modify import from google.generativeai to the new supported google.genai
AlanAAG Apr 22, 2026
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
2 changes: 2 additions & 0 deletions agent_core/core/embedding_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
- GOOGLE_API_KEY (for provider="gemini")
"""

from __future__ import annotations

import os
from typing import List, Optional

Expand Down
2 changes: 2 additions & 0 deletions agent_core/core/impl/action/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
based on user queries using LLM reasoning.
"""

from __future__ import annotations

import json
import ast
from typing import Optional, List, Dict, Any, Tuple
Expand Down
1 change: 1 addition & 0 deletions agent_core/core/impl/llm/cache/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from __future__ import annotations


import os
from dataclasses import dataclass
from typing import Optional
Expand Down
1 change: 1 addition & 0 deletions agent_core/core/impl/llm/cache/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from __future__ import annotations


import logging
from dataclasses import dataclass
from typing import Dict, Optional
Expand Down
1 change: 1 addition & 0 deletions agent_core/core/impl/llm/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from __future__ import annotations


from typing import Optional

# Import provider exception types
Expand Down
34 changes: 21 additions & 13 deletions agent_core/core/impl/llm/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -1184,9 +1184,10 @@ def _generate_openai(
# Always enforce JSON output format
request_kwargs["response_format"] = {"type": "json_object"}

# Add prompt_cache_key when call_type is provided for better cache routing
# This helps when alternating between different call types (reasoning, action_selection)
if call_type and system_prompt and len(system_prompt) >= config.min_cache_tokens:
# Add prompt_cache_key for OpenAI/DeepSeek cache routing.
# Grok (xAI) does not support prompt_cache_key — it uses automatic
# prefix caching and ignores this parameter, so skip it for Grok.
if self.provider != "grok" and call_type and system_prompt and len(system_prompt) >= config.min_cache_tokens:
prompt_hash = hashlib.sha256(system_prompt.encode()).hexdigest()[:16]
cache_key = f"{call_type}_{prompt_hash}"
request_kwargs["extra_body"] = {"prompt_cache_key": cache_key}
Expand All @@ -1197,21 +1198,26 @@ def _generate_openai(
token_count_input = response.usage.prompt_tokens
token_count_output = response.usage.completion_tokens

# Extract cached tokens from prompt_tokens_details (OpenAI automatic caching)
# Available for prompts ≥1024 tokens
prompt_tokens_details = getattr(response.usage, "prompt_tokens_details", None)
if prompt_tokens_details:
cached_tokens = getattr(prompt_tokens_details, "cached_tokens", 0) or 0
# Extract cached tokens — field name differs by provider:
# - OpenAI: response.usage.prompt_tokens_details.cached_tokens
# - Grok (xAI): response.usage.prompt_cache_hit_tokens
if self.provider == "grok":
cached_tokens = getattr(response.usage, "prompt_cache_hit_tokens", 0) or 0
else:
prompt_tokens_details = getattr(response.usage, "prompt_tokens_details", None)
if prompt_tokens_details:
cached_tokens = getattr(prompt_tokens_details, "cached_tokens", 0) or 0

# Record cache metrics
provider_label = self.provider # "openai", "grok", "deepseek", etc.
metrics = get_cache_metrics()
if cached_tokens > 0:
logger.info(f"[CACHE] OpenAI {cache_type} cache hit: {cached_tokens}/{token_count_input} tokens from cache")
metrics.record_hit("openai", cache_type, cached_tokens=cached_tokens, total_tokens=token_count_input)
logger.info(f"[CACHE] {provider_label} {cache_type} cache hit: {cached_tokens}/{token_count_input} tokens from cache")
metrics.record_hit(provider_label, cache_type, cached_tokens=cached_tokens, total_tokens=token_count_input)
elif system_prompt and len(system_prompt) >= config.min_cache_tokens:
# Caching should have been attempted (prompt long enough)
# This is a miss - either first call or cache expired
metrics.record_miss("openai", cache_type, total_tokens=token_count_input)
metrics.record_miss(provider_label, cache_type, total_tokens=token_count_input)

status = "success"
except Exception as exc:
Expand Down Expand Up @@ -1262,22 +1268,24 @@ def _generate_ollama(self, system_prompt: str | None, user_prompt: str) -> Dict[
try:
payload = {
"model": self.model,
"system": system_prompt,
"prompt": user_prompt,
"stream": False,
"format": "json",
"options": {
"temperature": self.temperature,
}
}
if system_prompt:
payload["system"] = system_prompt
url: str = f"{self.remote_url.rstrip('/')}/api/generate"
response = requests.post(url, json=payload, timeout=600)
response.raise_for_status()
result = response.json()

content = result.get("response", "").strip()
total_tokens = result.get("usage", {}).get("total_tokens", 0)
token_count_input = result.get("prompt_eval_count", 0)
token_count_output = result.get("eval_count", 0)
total_tokens = token_count_input + token_count_output
status = "success"
except Exception as exc:
exc_obj = exc
Expand Down
1 change: 1 addition & 0 deletions agent_core/core/impl/llm/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from __future__ import annotations


from enum import Enum


Expand Down
Loading