Expose new telemetry and recon toolkit to OpenClaw agents.

Wire telegram_osint, malware, cyber, and SCM into search/slow-tier helpers; add osint_lookup, entity_expand, and osint_sweep commands; update README and skill docs.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
BigBodyCobain
2026-06-08 22:44:16 -06:00
parent af9b3d08cc
commit 1583fd5715
9 changed files with 793 additions and 44 deletions
@@ -28,6 +28,10 @@ def sample_store():
"weather_alerts": list(latest_data.get("weather_alerts") or []),
"gps_jamming": list(latest_data.get("gps_jamming") or []),
"military_bases": list(latest_data.get("military_bases") or []),
"telegram_osint": dict(latest_data.get("telegram_osint") or {}),
"malware_threats": dict(latest_data.get("malware_threats") or {}),
"cyber_threats": dict(latest_data.get("cyber_threats") or {}),
"scm_suppliers": dict(latest_data.get("scm_suppliers") or {}),
}
latest_data["tracked_flights"] = [
{
@@ -188,6 +192,66 @@ def sample_store():
"lng": -76.87,
}
]
latest_data["telegram_osint"] = {
"posts": [
{
"id": "tg-1",
"title": "Missile strike reported near Kyiv overnight",
"description": "OSINT channel reports explosions near Kyiv",
"channel": "osintdefender",
"source": "t.me/osintdefender",
"link": "https://t.me/osintdefender/123",
"published": "2026-06-02T12:00:00+00:00",
"risk_score": 0.8,
"coords": [50.45, 30.52],
}
],
"total": 1,
"geolocated": 1,
}
latest_data["malware_threats"] = {
"threats": [
{
"id": "feodo-1",
"ip": "203.0.113.10",
"malware": "Emotet",
"country": "US",
"threat_type": "botnet_c2",
"lat": 38.95,
"lng": -77.45,
}
],
"total": 1,
}
latest_data["cyber_threats"] = {
"threats": [
{
"id": "CVE-2026-1234",
"name": "Example Vendor RCE",
"vendor": "Example Vendor",
"product": "Example Product",
"severity": "CRITICAL",
"source": "CISA KEV",
}
],
"stats": {"active_cves": 1},
}
latest_data["scm_suppliers"] = {
"suppliers": [
{
"id": "sup-tsmc-hsinchu",
"name": "TSMC Fab 12 (Tier 1)",
"city": "Hsinchu",
"country": "Taiwan",
"category": "Semiconductor",
"risk_level": "NORMAL",
"lat": 24.774,
"lng": 120.992,
}
],
"total": 1,
"critical_count": 0,
}
try:
yield
@@ -475,6 +539,89 @@ def test_correlate_entity_returns_evidence_pack_near_aircraft(sample_store, monk
assert result["recommended_next"]
def test_get_slow_telemetry_includes_new_osint_layers(sample_store, monkeypatch):
import services.telemetry as telemetry
monkeypatch.setattr(telemetry, "get_data_version", lambda: 210)
result = telemetry.get_cached_slow_telemetry()
assert "telegram_osint" in result
assert result["telegram_osint"]["total"] == 1
assert "malware_threats" in result
assert result["malware_threats"]["total"] == 1
assert "scm_suppliers" in result
assert result["scm_suppliers"]["total"] == 1
def test_get_layer_slice_accepts_telegram_alias(sample_store, monkeypatch):
import services.telemetry as telemetry
monkeypatch.setattr(telemetry, "get_data_version", lambda: 211)
result = telemetry.get_layer_slice(layers=["telegram"], limit_per_layer=10)
assert result["requested_layers"] == ["telegram_osint"]
assert result["layers"]["telegram_osint"]["posts"][0]["channel"] == "osintdefender"
def test_get_telemetry_summary_counts_nested_layer_items(sample_store, monkeypatch):
import services.telemetry as telemetry
monkeypatch.setattr(telemetry, "get_data_version", lambda: 212)
result = telemetry.get_telemetry_summary()
assert result["counts"]["telegram_osint"] == 1
assert result["counts"]["malware_threats"] == 1
assert result["counts"]["scm_suppliers"] == 1
assert "telegram_osint" in result["non_empty_layers"]
assert result["layer_aliases"]["telegram"] == "telegram_osint"
assert result["layer_aliases"]["scm"] == "scm_suppliers"
def test_search_news_matches_telegram_osint(sample_store, monkeypatch):
import services.telemetry as telemetry
monkeypatch.setattr(telemetry, "get_data_version", lambda: 213)
result = telemetry.search_news(query="kyiv missile", limit=10, include_telegram=True)
assert result["results"]
assert result["results"][0]["source_layer"] == "telegram_osint"
assert result["results"][0]["lat"] == 50.45
def test_search_telemetry_finds_telegram_malware_and_scm(sample_store, monkeypatch):
import services.telemetry as telemetry
monkeypatch.setattr(telemetry, "get_data_version", lambda: 214)
telegram = telemetry.search_telemetry(query="osintdefender kyiv", limit=10)
assert any(item["source_layer"] == "telegram_osint" for item in telegram["results"])
malware = telemetry.search_telemetry(query="emotet", limit=10)
assert any(item["source_layer"] == "malware_threats" for item in malware["results"])
scm = telemetry.search_telemetry(query="tsmc hsinchu", limit=10)
assert any(item["source_layer"] == "scm_suppliers" for item in scm["results"])
cve = telemetry.search_telemetry(query="CVE-2026-1234", limit=10)
assert any(item["source_layer"] == "cyber_threats" for item in cve["results"])
def test_entities_near_finds_telegram_and_malware(sample_store, monkeypatch):
import services.telemetry as telemetry
monkeypatch.setattr(telemetry, "get_data_version", lambda: 215)
result = telemetry.entities_near(
lat=38.95,
lng=-77.45,
radius_km=50,
entity_types=["telegram", "malware"],
limit=10,
)
layers = {item["source_layer"] for item in result["results"]}
assert "malware_threats" in layers
def test_openclaw_correlate_entity_command(sample_store, monkeypatch):
import services.telemetry as telemetry
from services.openclaw_channel import _dispatch_command
+98
View File
@@ -0,0 +1,98 @@
"""Tests for OpenClaw recon / OSINT command dispatch."""
import pytest
def test_osint_tools_lists_supported_lookups():
from services.osint.openclaw_recon import osint_tool_help
help_data = osint_tool_help()
assert "ip" in help_data["tools"]
assert "sanctions" in help_data["tools"]
assert "aircraft" in help_data["entity_types"]
def test_osint_lookup_ip(monkeypatch):
from services.osint import openclaw_recon
monkeypatch.setattr(
openclaw_recon.lookups,
"lookup_ip",
lambda ip: {"ip": ip, "geo": {"country": "US"}},
)
result = openclaw_recon.run_osint_lookup("ip", {"ip": "8.8.8.8"})
assert result["ip"] == "8.8.8.8"
assert result["geo"]["country"] == "US"
def test_osint_lookup_sanctions_passes_schema(monkeypatch):
from services.osint import openclaw_recon
captured = {}
def fake_sanctions(query, *, schema=None, limit=25):
captured["query"] = query
captured["schema"] = schema
captured["limit"] = limit
return {"query": query, "results": []}
monkeypatch.setattr(openclaw_recon.lookups, "lookup_sanctions", fake_sanctions)
openclaw_recon.run_osint_lookup(
"sanctions",
{"query": "Example Corp", "schema": "Company", "limit": 10},
)
assert captured["query"] == "Example Corp"
assert captured["schema"] == "Company"
assert captured["limit"] == 10
def test_osint_lookup_rejects_unknown_tool():
from services.osint.openclaw_recon import run_osint_lookup
with pytest.raises(ValueError, match="Unknown OSINT tool"):
run_osint_lookup("not_a_tool", {})
def test_openclaw_osint_lookup_command(monkeypatch):
from services import openclaw_channel
monkeypatch.setattr(
"services.osint.openclaw_recon.run_osint_lookup",
lambda tool, args: {"ip": args["ip"], "tool": tool},
)
result = openclaw_channel._dispatch_command(
"osint_lookup",
{"tool": "ip", "ip": "1.1.1.1"},
)
assert result["ok"] is True
assert result["data"]["ip"] == "1.1.1.1"
def test_openclaw_entity_expand_command(monkeypatch):
from services import openclaw_channel
monkeypatch.setattr(
"services.osint.openclaw_recon.run_entity_expand",
lambda args: {"nodes": [{"id": "ip:1.1.1.1"}], "links": []},
)
result = openclaw_channel._dispatch_command(
"entity_expand",
{"type": "ip", "id": "1.1.1.1"},
)
assert result["ok"] is True
assert result["data"]["nodes"][0]["id"] == "ip:1.1.1.1"
def test_osint_sweep_requires_full_tier_for_restricted():
from services.openclaw_channel import WRITE_COMMANDS, allowed_commands
assert "osint_sweep" in WRITE_COMMANDS
assert "osint_sweep" not in allowed_commands("restricted")
assert "osint_sweep" in allowed_commands("full")
def test_osint_lookup_available_on_restricted_tier():
from services.openclaw_channel import allowed_commands
assert "osint_lookup" in allowed_commands("restricted")
assert "entity_expand" in allowed_commands("restricted")