pythonclaw 0.2.0__tar.gz → 0.2.1__tar.gz
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.
- {pythonclaw-0.2.0/pythonclaw.egg-info → pythonclaw-0.2.1}/PKG-INFO +5 -2
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/README.md +4 -1
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pyproject.toml +1 -1
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/__init__.py +1 -1
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/onboard.py +48 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/web/static/index.html +84 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1/pythonclaw.egg-info}/PKG-INFO +5 -2
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/LICENSE +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/__main__.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/channels/discord_bot.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/channels/telegram_bot.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/config.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/__init__.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/agent.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/compaction.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/knowledge/rag.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/llm/anthropic_client.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/llm/base.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/llm/gemini_client.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/llm/openai_compatible.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/llm/response.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/memory/manager.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/memory/storage.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/persistent_agent.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/retrieval/__init__.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/retrieval/chunker.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/retrieval/dense.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/retrieval/fusion.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/retrieval/reranker.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/retrieval/retriever.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/retrieval/sparse.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/session_store.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/skill_loader.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/skillhub.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/tools.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/core/utils.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/daemon.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/init.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/main.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/scheduler/cron.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/scheduler/heartbeat.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/server.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/session_manager.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/persona/demo_persona.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/communication/CATEGORY.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/communication/email/SKILL.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/communication/email/__pycache__/send_email.cpython-311.pyc +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/communication/email/send_email.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/CATEGORY.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/csv_analyzer/SKILL.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/csv_analyzer/__pycache__/analyze.cpython-311.pyc +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/csv_analyzer/analyze.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/finance/SKILL.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/finance/__pycache__/fetch_quote.cpython-311.pyc +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/finance/fetch_quote.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/news/SKILL.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/news/__pycache__/search_news.cpython-311.pyc +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/news/search_news.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/pdf_reader/SKILL.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/pdf_reader/__pycache__/read_pdf.cpython-311.pyc +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/pdf_reader/read_pdf.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/scraper/SKILL.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/scraper/__pycache__/scrape.cpython-311.pyc +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/scraper/scrape.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/weather/SKILL.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/weather/__pycache__/weather.cpython-311.pyc +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/weather/weather.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/youtube/SKILL.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/youtube/__pycache__/youtube_info.cpython-311.pyc +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/youtube/youtube_info.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/dev/CATEGORY.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/dev/code_runner/SKILL.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/dev/code_runner/__pycache__/run_code.cpython-311.pyc +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/dev/code_runner/run_code.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/dev/github/SKILL.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/dev/github/__pycache__/gh.cpython-311.pyc +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/dev/github/gh.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/dev/http_request/SKILL.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/dev/http_request/__pycache__/request.cpython-311.pyc +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/dev/http_request/request.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/google/CATEGORY.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/google/workspace/SKILL.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/google/workspace/check_setup.sh +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/meta/CATEGORY.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/meta/skill_creator/SKILL.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/system/CATEGORY.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/system/change_persona/SKILL.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/system/change_setting/SKILL.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/system/change_setting/__pycache__/update_config.cpython-311.pyc +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/system/change_setting/update_config.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/system/change_soul/SKILL.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/system/onboarding/SKILL.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/system/onboarding/__pycache__/write_identity.cpython-311.pyc +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/system/onboarding/write_identity.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/system/random/SKILL.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/system/random/__pycache__/random_util.cpython-311.pyc +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/system/random/random_util.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/system/time/SKILL.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/system/time/__pycache__/time_util.cpython-311.pyc +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/system/time/time_util.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/text/CATEGORY.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/text/translator/SKILL.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/text/translator/__pycache__/translate.cpython-311.pyc +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/text/translator/translate.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/web/CATEGORY.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/web/tavily/SKILL.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/soul/SOUL.md +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/web/__init__.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/web/app.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/web/static/favicon.png +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/web/static/logo.png +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw.egg-info/SOURCES.txt +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw.egg-info/dependency_links.txt +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw.egg-info/entry_points.txt +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw.egg-info/requires.txt +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw.egg-info/top_level.txt +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/setup.cfg +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/tests/test_compaction.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/tests/test_persistence.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/tests/test_rag_hybrid.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/tests/test_skills.py +0 -0
- {pythonclaw-0.2.0 → pythonclaw-0.2.1}/tests/test_soul.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pythonclaw
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: OpenClaw reimagined in pure Python — autonomous AI agent with memory, RAG, skills, web dashboard, and multi-channel support.
|
|
5
5
|
Author-email: Eric Wang <wangchen2007915@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -76,7 +76,10 @@ Dynamic: license-file
|
|
|
76
76
|
<a href="https://github.com/ericwang915/PythonClaw/actions/workflows/ci.yml">
|
|
77
77
|
<img src="https://github.com/ericwang915/PythonClaw/actions/workflows/ci.yml/badge.svg" alt="CI">
|
|
78
78
|
</a>
|
|
79
|
-
<
|
|
79
|
+
<a href="https://pypi.org/project/pythonclaw/">
|
|
80
|
+
<img src="https://img.shields.io/pypi/v/pythonclaw?color=blue" alt="PyPI">
|
|
81
|
+
</a>
|
|
82
|
+
<img src="https://img.shields.io/pypi/pyversions/pythonclaw" alt="Python">
|
|
80
83
|
<a href="LICENSE">
|
|
81
84
|
<img src="https://img.shields.io/github/license/ericwang915/PythonClaw" alt="MIT License">
|
|
82
85
|
</a>
|
|
@@ -13,7 +13,10 @@
|
|
|
13
13
|
<a href="https://github.com/ericwang915/PythonClaw/actions/workflows/ci.yml">
|
|
14
14
|
<img src="https://github.com/ericwang915/PythonClaw/actions/workflows/ci.yml/badge.svg" alt="CI">
|
|
15
15
|
</a>
|
|
16
|
-
<
|
|
16
|
+
<a href="https://pypi.org/project/pythonclaw/">
|
|
17
|
+
<img src="https://img.shields.io/pypi/v/pythonclaw?color=blue" alt="PyPI">
|
|
18
|
+
</a>
|
|
19
|
+
<img src="https://img.shields.io/pypi/pyversions/pythonclaw" alt="Python">
|
|
17
20
|
<a href="LICENSE">
|
|
18
21
|
<img src="https://img.shields.io/github/license/ericwang915/PythonClaw" alt="MIT License">
|
|
19
22
|
</a>
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pythonclaw"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.1"
|
|
8
8
|
description = "OpenClaw reimagined in pure Python — autonomous AI agent with memory, RAG, skills, web dashboard, and multi-channel support."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
@@ -214,6 +214,54 @@ def _optional_keys(cfg: dict) -> None:
|
|
|
214
214
|
print(" → SkillHub key set")
|
|
215
215
|
|
|
216
216
|
print()
|
|
217
|
+
_channel_keys(cfg)
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def _channel_keys(cfg: dict) -> None:
|
|
221
|
+
print(_c(" Channels (press Enter to skip):", _DIM))
|
|
222
|
+
print()
|
|
223
|
+
|
|
224
|
+
channels = cfg.setdefault("channels", {})
|
|
225
|
+
|
|
226
|
+
# Telegram
|
|
227
|
+
tg = channels.setdefault("telegram", {"token": "", "allowedUsers": []})
|
|
228
|
+
tg_existing = tg.get("token", "")
|
|
229
|
+
if tg_existing:
|
|
230
|
+
masked = tg_existing[:6] + "****" + tg_existing[-4:] if len(tg_existing) > 10 else "****"
|
|
231
|
+
print(f" Telegram Bot Token (current: {masked}, press Enter to keep)")
|
|
232
|
+
token = input(" Telegram Bot Token: ").strip()
|
|
233
|
+
if token:
|
|
234
|
+
tg["token"] = token
|
|
235
|
+
print(" → Telegram token set")
|
|
236
|
+
elif tg_existing:
|
|
237
|
+
print(" → Keeping existing Telegram token")
|
|
238
|
+
|
|
239
|
+
allowed = input(" Telegram Allowed User IDs (comma-separated, or Enter to allow all): ").strip()
|
|
240
|
+
if allowed:
|
|
241
|
+
tg["allowedUsers"] = [uid.strip() for uid in allowed.split(",") if uid.strip()]
|
|
242
|
+
print(f" → {len(tg['allowedUsers'])} user(s) whitelisted")
|
|
243
|
+
|
|
244
|
+
print()
|
|
245
|
+
|
|
246
|
+
# Discord
|
|
247
|
+
dc = channels.setdefault("discord", {"token": "", "allowedUsers": [], "allowedChannels": []})
|
|
248
|
+
dc_existing = dc.get("token", "")
|
|
249
|
+
if dc_existing:
|
|
250
|
+
masked = dc_existing[:6] + "****" + dc_existing[-4:] if len(dc_existing) > 10 else "****"
|
|
251
|
+
print(f" Discord Bot Token (current: {masked}, press Enter to keep)")
|
|
252
|
+
dc_token = input(" Discord Bot Token: ").strip()
|
|
253
|
+
if dc_token:
|
|
254
|
+
dc["token"] = dc_token
|
|
255
|
+
print(" → Discord token set")
|
|
256
|
+
elif dc_existing:
|
|
257
|
+
print(" → Keeping existing Discord token")
|
|
258
|
+
|
|
259
|
+
dc_channels = input(" Discord Allowed Channel IDs (comma-separated, or Enter to allow all): ").strip()
|
|
260
|
+
if dc_channels:
|
|
261
|
+
dc["allowedChannels"] = [ch.strip() for ch in dc_channels.split(",") if ch.strip()]
|
|
262
|
+
print(f" → {len(dc['allowedChannels'])} channel(s) whitelisted")
|
|
263
|
+
|
|
264
|
+
print()
|
|
217
265
|
|
|
218
266
|
|
|
219
267
|
def _validate_key(cfg: dict, provider: dict) -> None:
|
|
@@ -266,6 +266,18 @@
|
|
|
266
266
|
</div>
|
|
267
267
|
</div>
|
|
268
268
|
|
|
269
|
+
<!-- Memory -->
|
|
270
|
+
<div class="section-card mb-6">
|
|
271
|
+
<h3 class="text-[.8125rem] font-semibold text-white mb-3 flex items-center gap-2">
|
|
272
|
+
<svg class="w-4 h-4 text-cyan-400" fill="none" stroke="currentColor" stroke-width="1.75" viewBox="0 0 24 24"><path d="M12 2a10 10 0 100 20 10 10 0 000-20z"/><path d="M12 6v6l4 2"/></svg>
|
|
273
|
+
Memory
|
|
274
|
+
<span id="memory-badge" class="text-[.625rem] text-gray-500 font-normal ml-1">0 entries</span>
|
|
275
|
+
</h3>
|
|
276
|
+
<div id="memory-content" class="max-h-[260px] overflow-y-auto chat-scroll">
|
|
277
|
+
<span class="text-[.75rem] text-gray-600 italic">No memories stored yet.</span>
|
|
278
|
+
</div>
|
|
279
|
+
</div>
|
|
280
|
+
|
|
269
281
|
<!-- Tools & Quick Actions Row -->
|
|
270
282
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-4">
|
|
271
283
|
<!-- Tools List -->
|
|
@@ -479,6 +491,29 @@
|
|
|
479
491
|
</div>
|
|
480
492
|
</div>
|
|
481
493
|
|
|
494
|
+
<!-- Channels -->
|
|
495
|
+
<div class="cfg-section">
|
|
496
|
+
<h3 class="cfg-title">Channels</h3>
|
|
497
|
+
<div class="grid grid-cols-1 sm:grid-cols-2 gap-x-6 gap-y-4">
|
|
498
|
+
<div class="sm:col-span-2">
|
|
499
|
+
<label class="block text-xs text-gray-500 mb-1.5">Telegram Bot Token</label>
|
|
500
|
+
<input id="cfg-tg-token" type="password" class="input-field">
|
|
501
|
+
</div>
|
|
502
|
+
<div>
|
|
503
|
+
<label class="block text-xs text-gray-500 mb-1.5">Telegram Allowed Users</label>
|
|
504
|
+
<input id="cfg-tg-users" type="text" placeholder="Comma-separated user IDs (blank = allow all)" class="input-field">
|
|
505
|
+
</div>
|
|
506
|
+
<div class="sm:col-span-2 mt-2">
|
|
507
|
+
<label class="block text-xs text-gray-500 mb-1.5">Discord Bot Token</label>
|
|
508
|
+
<input id="cfg-dc-token" type="password" class="input-field">
|
|
509
|
+
</div>
|
|
510
|
+
<div>
|
|
511
|
+
<label class="block text-xs text-gray-500 mb-1.5">Discord Allowed Channels</label>
|
|
512
|
+
<input id="cfg-dc-channels" type="text" placeholder="Comma-separated channel IDs (blank = allow all)" class="input-field">
|
|
513
|
+
</div>
|
|
514
|
+
</div>
|
|
515
|
+
</div>
|
|
516
|
+
|
|
482
517
|
<!-- Web Dashboard -->
|
|
483
518
|
<div class="cfg-section">
|
|
484
519
|
<h3 class="cfg-title">Web Dashboard</h3>
|
|
@@ -653,6 +688,29 @@ async function refreshDashboard() {
|
|
|
653
688
|
`).join('');
|
|
654
689
|
}
|
|
655
690
|
} catch (e) { console.error('Identity fetch:', e); }
|
|
691
|
+
|
|
692
|
+
try {
|
|
693
|
+
const res3 = await fetch('/api/memories');
|
|
694
|
+
const mem = await res3.json();
|
|
695
|
+
const container = document.getElementById('memory-content');
|
|
696
|
+
const badge = document.getElementById('memory-badge');
|
|
697
|
+
const entries = mem.memories || {};
|
|
698
|
+
const keys = Object.keys(entries);
|
|
699
|
+
badge.textContent = keys.length + ' entries';
|
|
700
|
+
|
|
701
|
+
if (keys.length === 0) {
|
|
702
|
+
container.innerHTML = '<span class="text-[.75rem] text-gray-600 italic">No memories stored yet. Chat with the agent to build memory.</span>';
|
|
703
|
+
} else {
|
|
704
|
+
container.innerHTML = '<div class="space-y-2">' + keys.map(k => {
|
|
705
|
+
const val = escapeHtml(String(entries[k]));
|
|
706
|
+
const preview = val.length > 200 ? val.substring(0, 200) + '...' : val;
|
|
707
|
+
return `<div class="px-3 py-2 rounded-lg bg-surface-800/50 border border-surface-700/30">
|
|
708
|
+
<div class="text-[.6875rem] text-cyan-400 font-medium mb-1">${escapeHtml(k)}</div>
|
|
709
|
+
<div class="text-[.75rem] text-gray-400 leading-relaxed whitespace-pre-wrap">${preview}</div>
|
|
710
|
+
</div>`;
|
|
711
|
+
}).join('') + '</div>';
|
|
712
|
+
}
|
|
713
|
+
} catch (e) { console.error('Memories fetch:', e); }
|
|
656
714
|
}
|
|
657
715
|
|
|
658
716
|
// ── Identity Editor ──────────────────────────────────────────────────────────
|
|
@@ -1008,6 +1066,19 @@ async function loadConfig() {
|
|
|
1008
1066
|
ghTokenField.placeholder = secretsSet['skills.github.token']
|
|
1009
1067
|
? '(token is set — leave blank to keep)' : 'ghp_xxxxxxxxxx';
|
|
1010
1068
|
|
|
1069
|
+
const channels = _rawConfig.channels || {};
|
|
1070
|
+
const tgCfg = channels.telegram || {};
|
|
1071
|
+
const tgTokenField = document.getElementById('cfg-tg-token');
|
|
1072
|
+
tgTokenField.value = '';
|
|
1073
|
+
tgTokenField.placeholder = secretsSet['channels.telegram.token'] ? '(token is set — leave blank to keep)' : 'Enter Telegram bot token';
|
|
1074
|
+
document.getElementById('cfg-tg-users').value = (tgCfg.allowedUsers || []).join(', ');
|
|
1075
|
+
|
|
1076
|
+
const dcCfg = channels.discord || {};
|
|
1077
|
+
const dcTokenField = document.getElementById('cfg-dc-token');
|
|
1078
|
+
dcTokenField.value = '';
|
|
1079
|
+
dcTokenField.placeholder = secretsSet['channels.discord.token'] ? '(token is set — leave blank to keep)' : 'Enter Discord bot token';
|
|
1080
|
+
document.getElementById('cfg-dc-channels').value = (dcCfg.allowedChannels || []).join(', ');
|
|
1081
|
+
|
|
1011
1082
|
const web = _rawConfig.web || {};
|
|
1012
1083
|
document.getElementById('cfg-web-host').value = web.host || '0.0.0.0';
|
|
1013
1084
|
document.getElementById('cfg-web-port').value = web.port || 7788;
|
|
@@ -1090,6 +1161,19 @@ async function saveConfig() {
|
|
|
1090
1161
|
const ghToken = document.getElementById('cfg-github-token').value.trim();
|
|
1091
1162
|
if (ghToken) cfg.skills.github.token = ghToken;
|
|
1092
1163
|
|
|
1164
|
+
if (!cfg.channels) cfg.channels = {};
|
|
1165
|
+
if (!cfg.channels.telegram) cfg.channels.telegram = {};
|
|
1166
|
+
const tgToken = document.getElementById('cfg-tg-token').value.trim();
|
|
1167
|
+
if (tgToken) cfg.channels.telegram.token = tgToken;
|
|
1168
|
+
const tgUsers = document.getElementById('cfg-tg-users').value.trim();
|
|
1169
|
+
cfg.channels.telegram.allowedUsers = tgUsers ? tgUsers.split(',').map(s => s.trim()).filter(Boolean) : [];
|
|
1170
|
+
|
|
1171
|
+
if (!cfg.channels.discord) cfg.channels.discord = {};
|
|
1172
|
+
const dcToken = document.getElementById('cfg-dc-token').value.trim();
|
|
1173
|
+
if (dcToken) cfg.channels.discord.token = dcToken;
|
|
1174
|
+
const dcChannels = document.getElementById('cfg-dc-channels').value.trim();
|
|
1175
|
+
cfg.channels.discord.allowedChannels = dcChannels ? dcChannels.split(',').map(s => s.trim()).filter(Boolean) : [];
|
|
1176
|
+
|
|
1093
1177
|
if (!cfg.web) cfg.web = {};
|
|
1094
1178
|
cfg.web.host = document.getElementById('cfg-web-host').value.trim() || '0.0.0.0';
|
|
1095
1179
|
cfg.web.port = parseInt(document.getElementById('cfg-web-port').value) || 7788;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pythonclaw
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: OpenClaw reimagined in pure Python — autonomous AI agent with memory, RAG, skills, web dashboard, and multi-channel support.
|
|
5
5
|
Author-email: Eric Wang <wangchen2007915@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -76,7 +76,10 @@ Dynamic: license-file
|
|
|
76
76
|
<a href="https://github.com/ericwang915/PythonClaw/actions/workflows/ci.yml">
|
|
77
77
|
<img src="https://github.com/ericwang915/PythonClaw/actions/workflows/ci.yml/badge.svg" alt="CI">
|
|
78
78
|
</a>
|
|
79
|
-
<
|
|
79
|
+
<a href="https://pypi.org/project/pythonclaw/">
|
|
80
|
+
<img src="https://img.shields.io/pypi/v/pythonclaw?color=blue" alt="PyPI">
|
|
81
|
+
</a>
|
|
82
|
+
<img src="https://img.shields.io/pypi/pyversions/pythonclaw" alt="Python">
|
|
80
83
|
<a href="LICENSE">
|
|
81
84
|
<img src="https://img.shields.io/github/license/ericwang915/PythonClaw" alt="MIT License">
|
|
82
85
|
</a>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/communication/email/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
{pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/communication/email/send_email.py
RENAMED
|
File without changes
|
|
File without changes
|
{pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/csv_analyzer/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
{pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/csv_analyzer/analyze.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/finance/fetch_quote.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/pdf_reader/read_pdf.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/data/youtube/youtube_info.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/dev/code_runner/run_code.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/dev/http_request/request.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/google/workspace/check_setup.sh
RENAMED
|
File without changes
|
|
File without changes
|
{pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/meta/skill_creator/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
{pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/system/change_persona/SKILL.md
RENAMED
|
File without changes
|
{pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/system/change_setting/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/system/change_soul/SKILL.md
RENAMED
|
File without changes
|
{pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/system/onboarding/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/system/random/random_util.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pythonclaw-0.2.0 → pythonclaw-0.2.1}/pythonclaw/templates/skills/text/translator/translate.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|