mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-12 03:00:50 +08:00
重构仓库目录为统一的 runtime 分层并清理历史 openclaw 残留。
本次迁移将网关/通道/工具/技能/脚本与协议资源集中到新结构,统一路径常量与脚本转发机制,减少顶层噪音并保证运行与测试行为一致。 Made-with: Cursor
This commit is contained in:
parent
ba3836f00f
commit
4a23b715a2
498 changed files with 2760 additions and 2200 deletions
4
runtime/tools/experts/productivity/__init__.py
Normal file
4
runtime/tools/experts/productivity/__init__.py
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
from __future__ import annotations
|
||||
|
||||
__all__ = []
|
||||
|
||||
96
runtime/tools/experts/productivity/kb_tools.py
Normal file
96
runtime/tools/experts/productivity/kb_tools.py
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
from typing import Any
|
||||
|
||||
from oclaw.platform.config.paths import db_path
|
||||
from oclaw.platform.embeddings.embedding_client import build_default_embedding_client
|
||||
from oclaw.platform.persistence.sqlite_store import SqliteStore
|
||||
from oclaw.runtime.tools.base import ToolSpec
|
||||
|
||||
|
||||
def _chunk_id(source: str, text: str) -> str:
|
||||
raw = f"{source}\n{text}".encode("utf-8", errors="ignore")
|
||||
return hashlib.sha1(raw).hexdigest()
|
||||
|
||||
|
||||
def kb_add_tool() -> ToolSpec:
|
||||
def handler(args: dict[str, Any]) -> dict[str, Any]:
|
||||
try:
|
||||
tenant_id = str(args.get("tenant_id") or "").strip()
|
||||
user_id = str(args.get("user_id") or "").strip()
|
||||
text = str(args.get("text") or "").strip()
|
||||
title = str(args.get("title") or "").strip()
|
||||
if not tenant_id or not user_id or not text:
|
||||
return {"ok": False, "error": "tenant_id, user_id, text are required"}
|
||||
source = f"builtin:tenant:{tenant_id}:kb"
|
||||
if title:
|
||||
source = f"{source}:{title[:48]}"
|
||||
cid = _chunk_id(source, text)
|
||||
store = SqliteStore(db_path())
|
||||
store.upsert_knowledge_chunk(
|
||||
chunk_id=cid,
|
||||
source=source,
|
||||
content=text,
|
||||
metadata={"tenant_id": tenant_id, "user_id": user_id, "title": title, "source": source},
|
||||
)
|
||||
client = build_default_embedding_client()
|
||||
emb = client.embed(text[:8000])
|
||||
store.upsert_knowledge_embedding(chunk_id=cid, model=emb.model, vector=emb.vector)
|
||||
return {"ok": True, "chunk_id": cid, "source": source, "embedding_model": emb.model}
|
||||
except Exception as e:
|
||||
return {"ok": False, "error": f"{type(e).__name__}: {e}"}
|
||||
|
||||
return ToolSpec(
|
||||
name="kb_add",
|
||||
description="Add a knowledge snippet for a tenant into the vector knowledge base.",
|
||||
parameters={
|
||||
"type": "object",
|
||||
"properties": {"tenant_id": {"type": "string"}, "user_id": {"type": "string"}, "title": {"type": "string", "description": "Optional title/label."}, "text": {"type": "string", "description": "Knowledge content to store."}},
|
||||
"required": ["tenant_id", "user_id", "text"],
|
||||
"additionalProperties": False,
|
||||
},
|
||||
handler=handler,
|
||||
tags=frozenset({"productivity", "rag", "write"}),
|
||||
)
|
||||
|
||||
|
||||
def kb_search_tool() -> ToolSpec:
|
||||
def handler(args: dict[str, Any]) -> dict[str, Any]:
|
||||
try:
|
||||
tenant_id = str(args.get("tenant_id") or "").strip()
|
||||
query = str(args.get("query") or "").strip()
|
||||
limit = int(args.get("limit") or 3)
|
||||
if not tenant_id or not query:
|
||||
return {"ok": False, "error": "tenant_id and query are required"}
|
||||
store = SqliteStore(db_path())
|
||||
from oclaw.runtime.orchestration.memory import retrieve_context
|
||||
|
||||
rows = retrieve_context(store, query, limit=max(1, min(limit, 6)))
|
||||
filtered = [r for r in rows if str(r.get("source") or "").startswith(f"builtin:tenant:{tenant_id}:")]
|
||||
hits = filtered[: max(1, min(limit, 6))]
|
||||
if not hits:
|
||||
like_rows = store.search_knowledge(query=query, limit=max(1, min(limit, 6)))
|
||||
hits = [r for r in like_rows if str(r.get("source") or "").startswith(f"builtin:tenant:{tenant_id}:")][: max(1, min(limit, 6))]
|
||||
refs = []
|
||||
for h in hits:
|
||||
refs.append({"source": str(h.get("source") or ""), "snippet": str(h.get("content") or "")[:240]})
|
||||
return {"ok": True, "hits": refs}
|
||||
except Exception as e:
|
||||
return {"ok": False, "error": f"{type(e).__name__}: {e}"}
|
||||
|
||||
return ToolSpec(
|
||||
name="kb_search",
|
||||
description="Search tenant knowledge base and return citations/snippets.",
|
||||
parameters={
|
||||
"type": "object",
|
||||
"properties": {"tenant_id": {"type": "string"}, "query": {"type": "string"}, "limit": {"type": "integer", "default": 3}},
|
||||
"required": ["tenant_id", "query"],
|
||||
"additionalProperties": False,
|
||||
},
|
||||
handler=handler,
|
||||
tags=frozenset({"productivity", "rag"}),
|
||||
)
|
||||
|
||||
|
||||
__all__ = ["kb_add_tool", "kb_search_tool"]
|
||||
146
runtime/tools/experts/productivity/todo_tools.py
Normal file
146
runtime/tools/experts/productivity/todo_tools.py
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from oclaw.platform.config.paths import db_path
|
||||
from oclaw.platform.persistence.sqlite_store import SqliteStore
|
||||
from oclaw.runtime.tools.base import ToolSpec
|
||||
|
||||
|
||||
def _require(s: str, name: str) -> str:
|
||||
v = (s or "").strip()
|
||||
if not v:
|
||||
raise ValueError(f"{name} is required")
|
||||
return v
|
||||
|
||||
|
||||
def todo_create_tool() -> ToolSpec:
|
||||
def handler(args: dict[str, Any]) -> dict[str, Any]:
|
||||
try:
|
||||
tenant_id = _require(str(args.get("tenant_id") or ""), "tenant_id")
|
||||
owner_user_id = _require(str(args.get("owner_user_id") or ""), "owner_user_id")
|
||||
title = _require(str(args.get("title") or ""), "title")
|
||||
due_at = str(args.get("due_at") or "").strip() or None
|
||||
assignee_user_id = str(args.get("assignee_user_id") or "").strip() or None
|
||||
store = SqliteStore(db_path())
|
||||
row = store.todo_create(
|
||||
tenant_id=tenant_id,
|
||||
owner_user_id=owner_user_id,
|
||||
title=title,
|
||||
due_at=due_at,
|
||||
assignee_user_id=assignee_user_id,
|
||||
)
|
||||
return {"ok": True, "todo": row}
|
||||
except Exception as e:
|
||||
return {"ok": False, "error": f"{type(e).__name__}: {e}"}
|
||||
|
||||
return ToolSpec(
|
||||
name="todo_create",
|
||||
description="Create a todo item for a tenant/user.",
|
||||
parameters={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"tenant_id": {"type": "string"},
|
||||
"owner_user_id": {"type": "string"},
|
||||
"title": {"type": "string"},
|
||||
"due_at": {"type": "string", "description": "Optional ISO timestamp or natural text."},
|
||||
"assignee_user_id": {"type": "string", "description": "Optional user id to assign."},
|
||||
},
|
||||
"required": ["tenant_id", "owner_user_id", "title"],
|
||||
"additionalProperties": False,
|
||||
},
|
||||
handler=handler,
|
||||
tags=frozenset({"productivity", "write"}),
|
||||
)
|
||||
|
||||
|
||||
def todo_list_tool() -> ToolSpec:
|
||||
def handler(args: dict[str, Any]) -> dict[str, Any]:
|
||||
try:
|
||||
tenant_id = _require(str(args.get("tenant_id") or ""), "tenant_id")
|
||||
assignee_user_id = str(args.get("assignee_user_id") or "").strip() or None
|
||||
status = str(args.get("status") or "open").strip() or None
|
||||
limit = int(args.get("limit") or 50)
|
||||
store = SqliteStore(db_path())
|
||||
rows = store.todo_list(
|
||||
tenant_id=tenant_id,
|
||||
assignee_user_id=assignee_user_id,
|
||||
status=status,
|
||||
limit=limit,
|
||||
)
|
||||
return {"ok": True, "items": rows}
|
||||
except Exception as e:
|
||||
return {"ok": False, "error": f"{type(e).__name__}: {e}"}
|
||||
|
||||
return ToolSpec(
|
||||
name="todo_list",
|
||||
description="List todo items by tenant (optionally by assignee and status).",
|
||||
parameters={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"tenant_id": {"type": "string"},
|
||||
"assignee_user_id": {"type": "string"},
|
||||
"status": {"type": "string", "default": "open"},
|
||||
"limit": {"type": "integer", "default": 50},
|
||||
},
|
||||
"required": ["tenant_id"],
|
||||
"additionalProperties": False,
|
||||
},
|
||||
handler=handler,
|
||||
tags=frozenset({"productivity"}),
|
||||
)
|
||||
|
||||
|
||||
def todo_done_tool() -> ToolSpec:
|
||||
def handler(args: dict[str, Any]) -> dict[str, Any]:
|
||||
try:
|
||||
tenant_id = _require(str(args.get("tenant_id") or ""), "tenant_id")
|
||||
todo_id = _require(str(args.get("todo_id") or ""), "todo_id")
|
||||
store = SqliteStore(db_path())
|
||||
ok = store.todo_set_status(tenant_id=tenant_id, todo_id=todo_id, status="done")
|
||||
return {"ok": bool(ok), "todo_id": todo_id}
|
||||
except Exception as e:
|
||||
return {"ok": False, "error": f"{type(e).__name__}: {e}"}
|
||||
|
||||
return ToolSpec(
|
||||
name="todo_done",
|
||||
description="Mark a todo item as done.",
|
||||
parameters={
|
||||
"type": "object",
|
||||
"properties": {"tenant_id": {"type": "string"}, "todo_id": {"type": "string"}},
|
||||
"required": ["tenant_id", "todo_id"],
|
||||
"additionalProperties": False,
|
||||
},
|
||||
handler=handler,
|
||||
tags=frozenset({"productivity", "write"}),
|
||||
)
|
||||
|
||||
|
||||
def todo_assign_tool() -> ToolSpec:
|
||||
def handler(args: dict[str, Any]) -> dict[str, Any]:
|
||||
try:
|
||||
tenant_id = _require(str(args.get("tenant_id") or ""), "tenant_id")
|
||||
todo_id = _require(str(args.get("todo_id") or ""), "todo_id")
|
||||
assignee_user_id = _require(str(args.get("assignee_user_id") or ""), "assignee_user_id")
|
||||
store = SqliteStore(db_path())
|
||||
ok = store.todo_assign(tenant_id=tenant_id, todo_id=todo_id, assignee_user_id=assignee_user_id)
|
||||
return {"ok": bool(ok), "todo_id": todo_id, "assignee_user_id": assignee_user_id}
|
||||
except Exception as e:
|
||||
return {"ok": False, "error": f"{type(e).__name__}: {e}"}
|
||||
|
||||
return ToolSpec(
|
||||
name="todo_assign",
|
||||
description="Assign a todo item to a user.",
|
||||
parameters={
|
||||
"type": "object",
|
||||
"properties": {"tenant_id": {"type": "string"}, "todo_id": {"type": "string"}, "assignee_user_id": {"type": "string"}},
|
||||
"required": ["tenant_id", "todo_id", "assignee_user_id"],
|
||||
"additionalProperties": False,
|
||||
},
|
||||
handler=handler,
|
||||
tags=frozenset({"productivity", "write"}),
|
||||
)
|
||||
|
||||
|
||||
__all__ = ["todo_create_tool", "todo_list_tool", "todo_done_tool", "todo_assign_tool"]
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue