agentram 0.1.7 → 0.1.8

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.
package/agentram/cli.py CHANGED
@@ -825,6 +825,8 @@ def model_error_hint(message: str) -> str:
825
825
  return message + " | Fix: start your OpenAI-compatible server at base_url, or change --base-url."
826
826
  if "http 404" in lower or "404: not found" in lower:
827
827
  return message + " | Fix: verify base_url includes /v1, provider supports /chat/completions, and model name exists."
828
+ if "http 400" in lower and "not supported" in lower:
829
+ return message + " | Fix: this account/provider rejects that model. Bind a supported model name from your local endpoint."
828
830
  if "returned non-json" in lower or "expecting value" in lower:
829
831
  return message + " | Fix: endpoint returned empty/HTML/non-JSON. Check base_url, auth key, proxy, and server logs."
830
832
  if "missing api key env" in lower:
@@ -139,6 +139,9 @@ class MultiModelCodingOrchestrator:
139
139
  try:
140
140
  data = json.loads(raw)
141
141
  except json.JSONDecodeError as error:
142
+ streamed = parse_openai_sse(raw)
143
+ if streamed:
144
+ return streamed
142
145
  raise RuntimeError(f"OpenAI-compatible returned non-JSON at {url} | response={raw[:500]}") from error
143
146
  return str(data.get("choices", [{}])[0].get("message", {}).get("content", ""))
144
147
 
@@ -188,3 +191,32 @@ class MultiModelCodingOrchestrator:
188
191
  if process.returncode != 0:
189
192
  raise RuntimeError(error or f"claude command failed with exit code {process.returncode}")
190
193
  return output or error
194
+
195
+ def parse_openai_sse(raw: str) -> str:
196
+ parts: list[str] = []
197
+ for line in raw.splitlines():
198
+ stripped = line.strip()
199
+ if not stripped.startswith("data:"):
200
+ continue
201
+ payload = stripped[5:].strip()
202
+ if not payload or payload == "[DONE]":
203
+ continue
204
+ try:
205
+ item = json.loads(payload)
206
+ except json.JSONDecodeError:
207
+ continue
208
+ choices = item.get("choices", [])
209
+ if not choices or not isinstance(choices, list):
210
+ continue
211
+ choice = choices[0]
212
+ if not isinstance(choice, dict):
213
+ continue
214
+ delta = choice.get("delta", {})
215
+ if isinstance(delta, dict):
216
+ content = delta.get("content")
217
+ if content:
218
+ parts.append(str(content))
219
+ message = choice.get("message", {})
220
+ if isinstance(message, dict) and message.get("content"):
221
+ parts.append(str(message.get("content")))
222
+ return "".join(parts).strip()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentram",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Async, model-agnostic Working RAM for coding agents.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/trancongnghia/AGENT_RAM#readme",
package/pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "agentram"
7
- version = "0.1.7"
7
+ version = "0.1.8"
8
8
  description = "Async, model-agnostic RAM layer for agentic coding tools."
9
9
  readme = "README.md"
10
10
  license = "MIT"