Skip to content

Commit 86e1e70

Browse files
jwesleyeclaude
andcommitted
Bump version to 1.3.6
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 32794ef commit 86e1e70

6 files changed

Lines changed: 65 additions & 16 deletions

File tree

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [1.3.6] - 2024-12-24
11+
12+
### Fixed
13+
- **Harmony Auto-Detection** - Fixed harmony processor not auto-detecting gpt-oss models
14+
- Now properly calls `HarmonyProcessor.detect_harmony_agent()` during initialization
15+
- Enhanced detection to check direct string attributes on agent (model, model_id, model_name)
16+
- Updated agent_loader to handle agents where model is stored as direct string attribute
17+
- Added comprehensive debug logging to show detection process
18+
- Resolves issue where "openai/gpt-oss-120b" models weren't being auto-detected
19+
1020
## [1.3.5] - 2024-12-24
1121

1222
### Fixed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "basic-agent-chat-loop"
7-
version = "1.3.5"
7+
version = "1.3.6"
88
description = "Feature-rich interactive CLI for AI agents with token tracking, prompt templates, aliases, and configuration"
99
readme = "README.md"
1010
requires-python = ">=3.9"

src/basic_agent_chat_loop/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
agent aliases, and extensive configuration options.
55
"""
66

7-
__version__ = "1.3.5"
7+
__version__ = "1.3.6"
88

99
from .chat_config import ChatConfig
1010
from .chat_loop import ChatLoop

src/basic_agent_chat_loop/chat_loop.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,13 @@ def __init__(
603603
harmony_enabled_config_raw = (
604604
self.config.get("harmony.enabled", None) if self.config else None
605605
)
606-
uses_harmony = self.agent_metadata.get("uses_harmony", False)
606+
607+
# Auto-detect harmony support
608+
# Check both metadata (for loaded agents) and agent object itself
609+
# (for dynamic agents)
610+
uses_harmony_metadata = self.agent_metadata.get("uses_harmony", False)
611+
uses_harmony_detected = HarmonyProcessor.detect_harmony_agent(self.agent)
612+
uses_harmony = uses_harmony_metadata or uses_harmony_detected
607613

608614
# Normalize config value to handle string values from YAML
609615
# "auto"/None → None (auto-detect)
@@ -615,7 +621,9 @@ def __init__(
615621

616622
logger.debug(f"Harmony config value (raw): {harmony_enabled_config_raw!r}")
617623
logger.debug(f"Harmony config value (normalized): {harmony_enabled_config!r}")
618-
logger.debug(f"Auto-detected harmony: {uses_harmony}")
624+
logger.debug(f"Harmony from metadata: {uses_harmony_metadata}")
625+
logger.debug(f"Harmony from detection: {uses_harmony_detected}")
626+
logger.debug(f"Auto-detected harmony (combined): {uses_harmony}")
619627

620628
# Determine if harmony should be enabled
621629
# None = auto-detect, True = force enable, False = force disable

src/basic_agent_chat_loop/components/agent_loader.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -209,19 +209,27 @@ def extract_agent_metadata(agent: Any) -> dict[str, Any]:
209209
metadata["uses_harmony"] = HarmonyProcessor.detect_harmony_agent(agent)
210210

211211
# Try to extract model information
212-
if hasattr(agent, "model"):
213-
model = agent.model
212+
model_id = None
214213

215-
# Try multiple attribute names for model ID
216-
model_id = None
214+
# First check if agent.model, agent.model_id, or agent.model_name are direct strings
215+
for attr in ["model", "model_id", "model_name"]:
216+
if hasattr(agent, attr):
217+
value = getattr(agent, attr)
218+
if value and isinstance(value, str):
219+
model_id = value
220+
break
221+
222+
# If not found as direct string, check agent.model as an object
223+
if not model_id and hasattr(agent, "model"):
224+
model = agent.model
217225

218226
# Check for Strands-style config dict first
219227
if hasattr(model, "config") and isinstance(model.config, dict):
220228
model_id = model.config.get("model_id")
221229

222-
# Fall back to checking various attributes
230+
# Fall back to checking various attributes on the model object
223231
if not model_id:
224-
for attr in ["model_id", "model", "model_name", "_model_id", "name"]:
232+
for attr in ["model_id", "model", "model_name", "_model_id", "name", "id"]:
225233
if hasattr(model, attr):
226234
model_id = getattr(model, attr)
227235
if model_id and model_id != "Unknown":

src/basic_agent_chat_loop/components/harmony_processor.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,17 +107,33 @@ def detect_harmony_agent(agent: Any) -> bool:
107107

108108
# Strategy 3: Check model name/id for gpt-oss or harmony
109109
model_indicators = []
110+
111+
# Check direct string attributes on agent
112+
for attr in ["model", "model_id", "model_name"]:
113+
if hasattr(agent, attr):
114+
model_value = getattr(agent, attr)
115+
if model_value and isinstance(model_value, str):
116+
model_indicators.append(model_value.lower())
117+
logger.debug(f"Found model string on agent.{attr}: {model_value}")
118+
119+
# Check nested attributes on agent.model object
110120
if hasattr(agent, "model"):
111121
model = agent.model
112-
for attr in ["model_id", "model", "model_name", "name"]:
113-
if hasattr(model, attr):
114-
model_value = getattr(model, attr)
115-
if model_value:
116-
model_indicators.append(str(model_value).lower())
122+
# If model itself is a string, we already captured it above
123+
if not isinstance(model, str):
124+
for attr in ["model_id", "model", "model_name", "name", "id"]:
125+
if hasattr(model, attr):
126+
model_value = getattr(model, attr)
127+
if model_value:
128+
model_indicators.append(str(model_value).lower())
129+
logger.debug(
130+
f"Found model on agent.model.{attr}: {model_value}"
131+
)
117132

133+
# Check if any indicator contains gpt-oss or harmony
118134
for indicator in model_indicators:
119135
if "gpt-oss" in indicator or "harmony" in indicator:
120-
logger.info(f"Agent model contains harmony indicator: {indicator}")
136+
logger.info(f"Agent model contains harmony indicator: {indicator}")
121137
return True
122138

123139
# Strategy 4: Check agent class name
@@ -132,6 +148,13 @@ def detect_harmony_agent(agent: Any) -> bool:
132148
logger.info("Agent has harmony-specific methods")
133149
return True
134150

151+
# No harmony indicators found
152+
logger.debug(
153+
f"No harmony indicators found. Checked: "
154+
f"attributes (uses_harmony, harmony_encoding), "
155+
f"model indicators: {model_indicators}, "
156+
f"class: {agent.__class__.__name__}"
157+
)
135158
return False
136159

137160
def process_response(

0 commit comments

Comments
 (0)