@oneciel-ai/claude-any 0.1.70 → 0.1.71
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/README.md +9 -1
- package/claude_any.py +80 -1
- package/docs/README.ja.md +9 -1
- package/docs/README.ko.md +9 -1
- package/docs/README.zh.md +9 -1
- package/docs/manual.md +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -68,7 +68,7 @@ arguments through unchanged.
|
|
|
68
68
|
|
|
69
69
|
Credits: One Ciel LLC
|
|
70
70
|
|
|
71
|
-
Current version: `0.1.
|
|
71
|
+
Current version: `0.1.71`
|
|
72
72
|
|
|
73
73
|
## Why This Exists
|
|
74
74
|
|
|
@@ -495,6 +495,14 @@ steps under that larger model's supervision.
|
|
|
495
495
|
|
|
496
496
|
## Changelog
|
|
497
497
|
|
|
498
|
+
### 0.1.71
|
|
499
|
+
|
|
500
|
+
- **MCP SSE channel initialization**: the channel bridge now handles MCP
|
|
501
|
+
`endpoint` events by sending `initialize` and `notifications/initialized`,
|
|
502
|
+
so AI-Net style push notifications can start flowing into Claude Any.
|
|
503
|
+
- **Channel SSE diagnostics**: connector status now reports the MCP endpoint,
|
|
504
|
+
initialization state, and last MCP initialization error.
|
|
505
|
+
|
|
498
506
|
### 0.1.70
|
|
499
507
|
|
|
500
508
|
- **Linux menu debug log fix**: key-debug logging now writes under the user's
|
package/claude_any.py
CHANGED
|
@@ -96,7 +96,7 @@ PROVIDER_LABELS = {
|
|
|
96
96
|
"self-hosted-nim": "Self Hosted NIM",
|
|
97
97
|
}
|
|
98
98
|
APP_NAME = "Claude Any"
|
|
99
|
-
VERSION = "0.1.
|
|
99
|
+
VERSION = "0.1.71"
|
|
100
100
|
CREDITS = "Credits: One Ciel LLC"
|
|
101
101
|
|
|
102
102
|
LOG_LEVELS = {"SILENT": 0, "ERROR": 1, "WARN": 2, "INFO": 3, "DEBUG": 4, "TRACE": 5}
|
|
@@ -4338,6 +4338,9 @@ def _channel_sse_status_public(name: str, state: dict[str, Any]) -> dict[str, An
|
|
|
4338
4338
|
"messages_received": int(state.get("messages_received") or 0),
|
|
4339
4339
|
"event_filter": state.get("event_filter") or [],
|
|
4340
4340
|
"read_timeout_seconds": state.get("read_timeout_seconds"),
|
|
4341
|
+
"mcp_endpoint": state.get("mcp_endpoint"),
|
|
4342
|
+
"mcp_initialized": bool(state.get("mcp_initialized")),
|
|
4343
|
+
"mcp_last_error": state.get("mcp_last_error"),
|
|
4341
4344
|
"last_error": state.get("last_error"),
|
|
4342
4345
|
}
|
|
4343
4346
|
|
|
@@ -4402,8 +4405,78 @@ def _sse_payload_to_chat_payload(data_text: str, event_name: str, defaults: dict
|
|
|
4402
4405
|
}
|
|
4403
4406
|
|
|
4404
4407
|
|
|
4408
|
+
def _channel_sse_set_state(name: str, **updates: Any) -> None:
|
|
4409
|
+
with _CHANNEL_SSE_LOCK:
|
|
4410
|
+
state = _CHANNEL_SSE_CONNECTIONS.get(name)
|
|
4411
|
+
if state:
|
|
4412
|
+
state.update(updates)
|
|
4413
|
+
|
|
4414
|
+
|
|
4415
|
+
def _channel_sse_absolute_endpoint(stream_url: str, endpoint: str) -> str:
|
|
4416
|
+
endpoint = (endpoint or "").strip()
|
|
4417
|
+
if endpoint.startswith(("http://", "https://")):
|
|
4418
|
+
return endpoint
|
|
4419
|
+
return urllib.parse.urljoin(stream_url, endpoint)
|
|
4420
|
+
|
|
4421
|
+
|
|
4422
|
+
def _mcp_sse_post_json(endpoint: str, headers: dict[str, str], payload: dict[str, Any], timeout: float) -> Any:
|
|
4423
|
+
request_headers = {**headers, "Content-Type": "application/json", "Accept": "application/json, text/event-stream"}
|
|
4424
|
+
req = urllib.request.Request(
|
|
4425
|
+
endpoint,
|
|
4426
|
+
data=json.dumps(payload, ensure_ascii=False).encode("utf-8"),
|
|
4427
|
+
headers=request_headers,
|
|
4428
|
+
method="POST",
|
|
4429
|
+
)
|
|
4430
|
+
with urllib.request.urlopen(req, timeout=timeout) as response:
|
|
4431
|
+
data = response.read()
|
|
4432
|
+
if not data:
|
|
4433
|
+
return None
|
|
4434
|
+
try:
|
|
4435
|
+
return json.loads(data.decode("utf-8"))
|
|
4436
|
+
except Exception:
|
|
4437
|
+
return data.decode("utf-8", errors="replace")
|
|
4438
|
+
|
|
4439
|
+
|
|
4440
|
+
def _channel_sse_maybe_initialize_mcp(name: str, endpoint_text: str) -> None:
|
|
4441
|
+
with _CHANNEL_SSE_LOCK:
|
|
4442
|
+
state = _CHANNEL_SSE_CONNECTIONS.get(name)
|
|
4443
|
+
if not state:
|
|
4444
|
+
return
|
|
4445
|
+
if not bool(state.get("mcp_enabled", True)):
|
|
4446
|
+
return
|
|
4447
|
+
if state.get("mcp_initialized"):
|
|
4448
|
+
return
|
|
4449
|
+
stream_url = str(state.get("url") or "")
|
|
4450
|
+
headers = dict(state.get("headers") or {})
|
|
4451
|
+
timeout = max(5.0, min(120.0, float(state.get("mcp_timeout_seconds") or 20.0)))
|
|
4452
|
+
protocol_version = str(state.get("mcp_protocol_version") or "2024-11-05")
|
|
4453
|
+
endpoint = _channel_sse_absolute_endpoint(stream_url, endpoint_text)
|
|
4454
|
+
try:
|
|
4455
|
+
initialize = {
|
|
4456
|
+
"jsonrpc": "2.0",
|
|
4457
|
+
"id": 1,
|
|
4458
|
+
"method": "initialize",
|
|
4459
|
+
"params": {
|
|
4460
|
+
"protocolVersion": protocol_version,
|
|
4461
|
+
"capabilities": {},
|
|
4462
|
+
"clientInfo": {"name": "claude-any-channel-bridge", "version": VERSION},
|
|
4463
|
+
},
|
|
4464
|
+
}
|
|
4465
|
+
_mcp_sse_post_json(endpoint, headers, initialize, timeout)
|
|
4466
|
+
initialized = {"jsonrpc": "2.0", "method": "notifications/initialized", "params": {}}
|
|
4467
|
+
_mcp_sse_post_json(endpoint, headers, initialized, timeout)
|
|
4468
|
+
_channel_sse_set_state(name, mcp_endpoint=endpoint, mcp_initialized=True, mcp_last_error=None)
|
|
4469
|
+
router_log("INFO", f"channel_sse_mcp_initialized name={name} endpoint={endpoint}")
|
|
4470
|
+
except Exception as exc:
|
|
4471
|
+
_channel_sse_set_state(name, mcp_endpoint=endpoint, mcp_initialized=False, mcp_last_error=f"{type(exc).__name__}: {exc}")
|
|
4472
|
+
router_log("WARN", f"channel_sse_mcp_initialize_failed name={name} endpoint={endpoint} error={type(exc).__name__}: {exc}")
|
|
4473
|
+
|
|
4474
|
+
|
|
4405
4475
|
def _channel_sse_dispatch(name: str, event_name: str, data_lines: list[str]) -> None:
|
|
4406
4476
|
data_text = "\n".join(data_lines)
|
|
4477
|
+
if (event_name or "").strip().lower() == "endpoint":
|
|
4478
|
+
_channel_sse_maybe_initialize_mcp(name, data_text)
|
|
4479
|
+
return
|
|
4407
4480
|
with _CHANNEL_SSE_LOCK:
|
|
4408
4481
|
state = _CHANNEL_SSE_CONNECTIONS.get(name)
|
|
4409
4482
|
if not state:
|
|
@@ -4511,6 +4584,12 @@ def start_channel_sse_connection(config: dict[str, Any]) -> dict[str, Any]:
|
|
|
4511
4584
|
"event_filter": event_filter,
|
|
4512
4585
|
"read_timeout_seconds": float(config.get("read_timeout_seconds") or config.get("timeout") or 300.0),
|
|
4513
4586
|
"retry_seconds": float(config.get("retry_seconds") or 5.0),
|
|
4587
|
+
"mcp_enabled": bool(config.get("mcp", config.get("mcp_enabled", True))),
|
|
4588
|
+
"mcp_endpoint": None,
|
|
4589
|
+
"mcp_initialized": False,
|
|
4590
|
+
"mcp_last_error": None,
|
|
4591
|
+
"mcp_protocol_version": str(config.get("mcp_protocol_version") or "2024-11-05"),
|
|
4592
|
+
"mcp_timeout_seconds": float(config.get("mcp_timeout_seconds") or 20.0),
|
|
4514
4593
|
}
|
|
4515
4594
|
_CHANNEL_SSE_CONNECTIONS[name] = state
|
|
4516
4595
|
thread = threading.Thread(target=_channel_sse_worker, args=(name,), daemon=True, name=f"claude-any-channel-sse-{name}")
|
package/docs/README.ja.md
CHANGED
|
@@ -61,7 +61,7 @@ vLLM、NVIDIA hosted、self-hosted NIM を選択し、通常の Claude Code 引
|
|
|
61
61
|
|
|
62
62
|
Credits: One Ciel LLC
|
|
63
63
|
|
|
64
|
-
現在のバージョン: `0.1.
|
|
64
|
+
現在のバージョン: `0.1.71`
|
|
65
65
|
|
|
66
66
|
## 作られた理由
|
|
67
67
|
|
|
@@ -365,6 +365,14 @@ Windows/Linux 管理、クリーンアップスクリプト、定期的なセキ
|
|
|
365
365
|
|
|
366
366
|
## 変更履歴
|
|
367
367
|
|
|
368
|
+
### 0.1.71
|
|
369
|
+
|
|
370
|
+
- **MCP SSE channel 初期化**: channel bridge は MCP `endpoint` event を受けると
|
|
371
|
+
`initialize` と `notifications/initialized` を自動送信し、AI-Net 型 push
|
|
372
|
+
notification が Claude Any に流れ始めるようになりました。
|
|
373
|
+
- **Channel SSE 診断情報**: connector status に MCP endpoint、初期化状態、
|
|
374
|
+
最後の MCP 初期化エラーを表示します。
|
|
375
|
+
|
|
368
376
|
### 0.1.70
|
|
369
377
|
|
|
370
378
|
- **Linux menu debug log 修正**: key-debug log は global `/tmp` ではなく
|
package/docs/README.ko.md
CHANGED
|
@@ -67,7 +67,7 @@ NVIDIA hosted, self-hosted NIM을 선택하고, Claude Code의 일반 인자는
|
|
|
67
67
|
|
|
68
68
|
Credits: One Ciel LLC
|
|
69
69
|
|
|
70
|
-
현재 버전: `0.1.
|
|
70
|
+
현재 버전: `0.1.71`
|
|
71
71
|
|
|
72
72
|
## 왜 만들었나
|
|
73
73
|
|
|
@@ -371,6 +371,14 @@ Windows 이벤트 로그 리뷰, 바이러스/랜섬웨어 침입 시도 정리,
|
|
|
371
371
|
|
|
372
372
|
## 변경 이력
|
|
373
373
|
|
|
374
|
+
### 0.1.71
|
|
375
|
+
|
|
376
|
+
- **MCP SSE channel 초기화**: channel bridge가 MCP `endpoint` 이벤트를 받으면
|
|
377
|
+
`initialize`와 `notifications/initialized`를 자동 전송하므로, AI-Net 스타일
|
|
378
|
+
push notification이 Claude Any로 흐를 수 있습니다.
|
|
379
|
+
- **Channel SSE 진단 정보**: connector 상태에 MCP endpoint, 초기화 여부, 마지막
|
|
380
|
+
MCP 초기화 오류를 표시합니다.
|
|
381
|
+
|
|
374
382
|
### 0.1.70
|
|
375
383
|
|
|
376
384
|
- **Linux 메뉴 디버그 로그 수정**: key-debug 로그를 전역 `/tmp`가 아니라 사용자
|
package/docs/README.zh.md
CHANGED
|
@@ -61,7 +61,7 @@ NIM,并把普通 Claude Code 参数原样传递。
|
|
|
61
61
|
|
|
62
62
|
Credits: One Ciel LLC
|
|
63
63
|
|
|
64
|
-
当前版本: `0.1.
|
|
64
|
+
当前版本: `0.1.71`
|
|
65
65
|
|
|
66
66
|
## 为什么存在
|
|
67
67
|
|
|
@@ -351,6 +351,14 @@ Hermes 格式模型或部分较旧的 Qwen tool template。
|
|
|
351
351
|
|
|
352
352
|
## 更新日志
|
|
353
353
|
|
|
354
|
+
### 0.1.71
|
|
355
|
+
|
|
356
|
+
- **MCP SSE channel 初始化**:channel bridge 收到 MCP `endpoint` 事件后会自动发送
|
|
357
|
+
`initialize` 与 `notifications/initialized`,让 AI-Net 风格的 push
|
|
358
|
+
notification 可以流入 Claude Any。
|
|
359
|
+
- **Channel SSE 诊断信息**:connector status 现在会显示 MCP endpoint、初始化状态
|
|
360
|
+
以及最后一次 MCP 初始化错误。
|
|
361
|
+
|
|
354
362
|
### 0.1.70
|
|
355
363
|
|
|
356
364
|
- **Linux 菜单调试日志修复**:key-debug 日志现在写入用户的 Claude Any config
|
package/docs/manual.md
CHANGED
package/package.json
CHANGED