تخطَّ إلى المحتوى
kazma.
EN نجمة 7 ابدأ الآن

واجهة البرمجة (API) ونقاط التوسعة

سطح HTTP/SSE لواجهة كاظمة على الويب، وعقد أحداث SSE، والأماكن الملموسة لتوسعة الإطار (الأدوات، المزوّدون، المُكيّفات، المهارات، MCP).


تُحمَّل جميع نقاط النهاية بواسطة KazmaAppBuilder في kazma-ui/kazma_ui/app.py:615-709. المُوجِّهات:

المُوجِّهالبادئة/النطاقالمصدر
health_router/health/*health.py
chat_routerمسارات الصفحات (/chat, …)chat.py
settings_router/settingssettings.py
skills_routerالمهاراتمسارات skills
mcp_routerMCPمسارات mcp
agents_routerالوكلاءمسارات agents
providers_router/api/providersمسارات providers
sse_router/api/chat/*sse_chat.py
telemetry_routerالقياس عن بُعدمسارات telemetry
dashboard_router/api/dashboard/*dashboard.py
models_routerالنماذجمسارات models
workspace_routerمساحة العملمسارات workspace
swarm_router/api/swarm/*swarm_panel/
monitor_routerالمراقبةمسارات monitor
metrics_routerالمقاييسمسارات metrics

بالإضافة إلى مسارات مباشرة في routes_direct.py وخطّاف ويب (webhook) مشروط لـ Telegram عند /api/webhooks/telegram (app.py:365).


2. نقاط النهاية الرئيسية (مُتحقَّق منها)

Section titled “2. نقاط النهاية الرئيسية (مُتحقَّق منها)”
الطريقةالمسارالغرض
POST/api/chat/streamنقل الدردشة الأساسي. الجسم \{message, session_id, model\}. يُرجع text/event-stream. (sse_chat.py:353)
GET/api/chat/sessionsسرد الجلسات. (السطر 547)
DELETE/api/chat/sessions/\{session_id\}حذف جلسة. (السطر 555)
GET/api/chat/sessions/\{session_id\}/messagesسجل الجلسة. (السطر 561)

قديم (Legacy): GET /ws/chat يُرجع 410 Gone (chat.py:4). لا تستخدمه.

الطريقةالمسارالغرض
GET/api/provider/activeالمزوّد/النموذج النشط. (السطر 583)
GET/api/providersسرد المزوّدين. (السطر 601)
POST/api/provider/switchتبديل المزوّد/النموذج النشط. (السطر 607)
الطريقةالمسارالغرض
GET/api/pending-approvalsموافقات HITL المعلّقة. (hitl_approval.py:146)
POST/api/approve/\{thread_id\}الموافقة/الرفض على أداة موقوفة. الجسم `{action: “approve"
الطريقةالمسارالغرض
GET/api/dashboard/statusنظرة عامة على لوحة التحكم. (dashboard.py:177)
GET/api/sessionsقائمة الجلسات. (السطر 221)
POST/api/sessions/clear-allمسح الجلسات. (السطر 330)
الطريقةالمسارالغرض
GET/api/swarm/statusحالة السرب.
GET/POST/DELETE/api/swarm/workers[/\{name\}]CRUD للعمّال.
POST/api/swarm/dispatchإرسال مهمة (كل الأنماط عبر type).
GET/api/swarm/tasks[/\{id\}]قائمة المهام / التفاصيل.
POST/api/swarm/tasks/\{id\}/approveالموافقة على نقطة تفتيش خط المعالجة. (routes_tasks.py:612)
POST/api/swarm/tasks/\{id\}/rejectرفض نقطة تفتيش خط المعالجة. (السطر 657)
GET/api/swarm/workers/\{name\}/metricsمقاييس العامل.
GET/api/swarm/circuit-breakersحالات القواطع.

2.6 الذاكرة (المحرك المعرفي V2)

Section titled “2.6 الذاكرة (المحرك المعرفي V2)”

V2 هي مكدّس الذاكرة الوحيد بعد التحوّل من V1 إلى V2 (memory.v2.use_new_stack: true). مسارات V2 تُرجِع JSON مُشكَّلًا عند الخطأ (لا 500 مكشوف أبدًا)؛ المعاملات غير الرقمية تُرجِع FastAPI 422. يُرجِع /api/system/status حقل memory_stack ("v2") plus كتلة KPI لـ V2 حتى تُظهر لوحة القيادة أعداد V2. انظر الذاكرة وRAG لنموذج المكدّس.

مسارات V2 (routes_direct.py):

الطريقةالمسارالغرض
GET/api/memory/v2/healthلقطة صحة V2 — أعداد المعتقدات النشطة/المُستبدَلة/المؤرشفة، إحصاءات الحلقات/الكيانات/الإجرائية، عمق الطابور. تشغّل شبكة KPI في لوحة القيادة (pollV2Health، كل 5 ثوانٍ).
GET/api/memory/v2/beliefsقائمة المعتقدات النشطة. ?q= فلتر FTS، ?limit= (افتراضي 50، محصور 1–200).
GET/api/memory/v2/graphرسم المعتقدات \{nodes, links, stats\} للـ canvas. معاملات الزمن الثنائي + الفلترة: ?at=<unix_ts> (مسح نقطة زمنية؛ المعتقدات المُستبدَلة موسومة superseded=true?type= (functional/set/state?entity_type= (person/tool/concept/…)، ?limit= (افتراضي 200). الروابط التي تُترَك مصدرها أو هدفها خارج الفلترة تُحذَف عند الانبعاث — الحمولة دائمًا متّسقة ذاتيًا (لا حواف معلّقة).

أُزيلت: نقاط نهاية V1 /api/memory/graph* (رسم الخصائص L2) وتحقيقات L1–L4 من build_memory_health حُذفت مع مكدّس V1. لم تبقَ سوى مسارات V2 أعلاه. لا يزال /api/system/status موجودًا لكنه يُبلّغ الآن عن كتلة مؤشرات V2 بدلًا من صحة الطبقات L1–L4.

الطريقةالمسارالغرض
GET/health/liveالحيوية (Liveness). (health.py:94)
GET/health/readyالجاهزية (Readiness). (السطر 104)
GET/health/detailsصحة مفصّلة. (السطر 148)
GET/api/gateway/statusحالة البوابة/المُكيّف.

3. عقد أحداث SSE {#sse-event-contract}

Section titled “3. عقد أحداث SSE {#sse-event-contract}”

POST /api/chat/stream يُرجع بثًّا من أحداث Server-Sent Events. لكل حدث سطر event: مُنمَّط وحمولة JSON في data: (sse_chat.py:8-13).

event:المعنىحقول الحمولة الرئيسية
tokenجزء بث من LLM.content
tool_callأداة بدأت.tool, args
tool_resultأداة انتهت.tool, result, is_error
approval_requiredظهور وقفة HITL — يجب أن تستدعي الواجهة الأمامية POST /api/approve/\{thread_id\}. (الأسطر 199-207)thread_id, tool, args
doneاكتمال الدورة.tokens, cost_usd, duration_ms
errorخطأ قاتل.message

انتهاء صلاحية موافقة HITL: إذا نقر المستخدم موافقة/رفض على بطاقة انتهت مهلتها أو استُؤنفت مسبقًا، فإن POST /api/approve/{thread_id} يُرجع HTTP 409 مع {"status": "expired", "error": "No pending approval for this thread (already resumed or expired)."}. تكتشف الواجهة الأمامية (hitl_approval.js) ذلك وتنقل البطاقة إلى “Expired or already resumed” ثم تزيلها.

3.1 مثال من جانب العميل (JavaScript)

Section titled “3.1 مثال من جانب العميل (JavaScript)”
// chat.js uses KS.sse('/api/chat/stream', {...}); the raw shape is:
const resp = await fetch('/api/chat/stream', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: 'Hello', session_id: sess, model: 'gpt-4o-mini' }),
});
const reader = resp.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
while (true) {
const { value, done } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
// SSE events are separated by blank lines
let idx;
while ((idx = buffer.indexOf('\n\n')) !== -1) {
const block = buffer.slice(0, idx);
buffer = buffer.slice(idx + 2);
const eventType = (block.match(/^event: (.+)$/m) || [])[1];
const data = JSON.parse(((block.match(/^data: (.+)$/m) || [])[1]) || '{}');
handleEvent(eventType, data);
}
}
function handleEvent(type, data) {
switch (type) {
case 'token': appendToken(data.content); break;
case 'tool_call': showToolCall(data.tool, data.args); break;
case 'tool_result': showToolResult(data.tool, data.result); break;
case 'approval_required': promptApproval(data.thread_id, data.tool); break;
case 'done': finishTurn(data.tokens, data.cost_usd); break;
case 'error': showError(data.message); break;
}
}

3.2 الموافقة عبر الواجهة البرمجية (Python)

Section titled “3.2 الموافقة عبر الواجهة البرمجية (Python)”
import httpx
resp = httpx.post(
"http://127.0.0.1:8000/api/approve/<thread_id>",
headers={"X-Kazma-Secret": KAZMA_SECRET}, # required if KAZMA_SECRET is set
json={"action": "approve", "reason": "looks safe"},
)
print(resp.status_code, resp.json())

سجِّل دالة عبر ToolRegistry:

from kazma_core.agent.tool_registry import register_tool
@register_tool(
name="weather_lookup",
description="Look up current weather for a city.",
danger=False, # True → triggers HITL
)
async def weather_lookup(city: str) -> str:
...
return f"Weather in {city}: sunny, 25C"

سجِّل أثناء الإقلاع (أو عبر نقطة دخول مهارة). يعرضها المُشرف للـ LLM تلقائيًا.

المزوّدون إدخالات ConfigStore تحت providers.list. الإعدادات المسبقة العشرة المدمجة في kazma_core/providers.py:13-84. لإضافة نقطة نهاية مخصّصة متوافقة مع OpenAI:

from kazma_core.config_store import get_config_store
from kazma_core.model_registry import get_model_registry
store = get_config_store()
reg = get_model_registry()
# Option A: use the 'custom' preset shape
reg.upsert_provider(
name="my-endpoint",
display_name="My Inference Server",
base_url="https://infer.example.com/v1",
api_key="sk-...",
enabled=True,
)
# Option B: switch active provider/model
reg.set_active_provider("my-endpoint")
reg.set_active_model("my-model-id")

أي نقطة نهاية متوافقة مع OpenAI تعمل (vLLM، Together، Groq، Fireworks، …). لمخططات مصادقة غير OpenAI، لاحظ أن LLMProvider.chat() يُرسل دائمًا Authorization: Bearer — مرِّر عبر وكيل متوافق مع OpenAI إذا احتاج المصدر ترويسة مختلفة.

ورِّث من BaseAdapter (kazma-gateway/kazma_gateway/gateway.py:239)، نفِّذ الاستقبال/الإرسال، أنتج IncomingMessage، وسجِّله. لـ HITL السرب على المنصة الجديدة، ورِّث أيضًا من BusAdapter (kazma_core/swarm/bus.py:66) واربطه في كتلة bus-singleton في app.py.

انظر المهارات وMCP والأدوات ← إضافة مهارة مخصّصة. وقِّعها بـ kazma hub sign.

انظر المهارات وMCP والأدوات ← إعداد خادم MCP. تُكتشف الأدوات وقت التشغيل وتُصنَّف بـ classify_mcp_tool.

Terminal window
kazma swarm worker add researcher --model deepseek-chat --provider deepseek --type in_process --role researcher

أو عبر الواجهة البرمجية:

import httpx
httpx.post("http://127.0.0.1:8000/api/swarm/workers", json={
"name": "researcher",
"model": "deepseek-chat",
"provider": "deepseek",
"worker_type": "in_process",
"roles": ["researcher"],
})

4.7 الاستفادة من مكدّس ذاكرة V2

Section titled “4.7 الاستفادة من مكدّس ذاكرة V2”

محرك V2 المعرفي هو الافتراضي للدردشة (استدعاء لكل دورة، أدوات، تخزين تلقائي، ضغط) ويُستخدم أيضًا للتحسين الذاتي / دليل الأسماء (phonebook). (أُزيل UnifiedMemoryAdapter (V1) في التحوّل من V1 إلى V2.) كود مخصّص:

from kazma_core.memory.recall import recall
from kazma_core.paths import primary_memory_db
import sqlite3
conn = sqlite3.connect(primary_memory_db(), check_same_thread=False)
conn.row_factory = sqlite3.Row
result = recall("what does the user prefer?", conn=conn, limit=5)
# result.beliefs -> list[RecallHit] of currently-valid beliefs
# result.episodes -> list[RecallHit] of ranked episodes (FTS5 + dense + PPR, RRF-fused)

كتابة معتقد (المسندات الوظيفية تُستبدل؛ مسندات المجموعة تُلحق):

from kazma_core.memory.belief_mutation import mutate_belief
from kazma_core.paths import primary_memory_db, ops_memory_db
primary = sqlite3.connect(primary_memory_db(), check_same_thread=False)
ops = sqlite3.connect(ops_memory_db(), check_same_thread=False)
mutate_belief(
primary, "user", "prefers", "dark mode",
ops_conn=ops, predicate_type="set",
extraction_method="custom", source_session="my-integration",
)

انظر الذاكرة وRAG.


5. نقاط نهاية القياس عن بُعد والمراقبة

Section titled “5. نقاط نهاية القياس عن بُعد والمراقبة”
  • /api/telemetry/* (telemetry_router) — قياس زمن التشغيل عن بُعد.
  • /api/dashboard/status — نظرة عامة للوحة التحكم.
  • مقاييس السرب عند /api/swarm/workers/\{name\}/metrics.

نقطة Prometheus /metrics غير موجودة. حزم OTel مُعلَنة لكن تتبّع كاظمة مُصدِر spans داخلي. انظر البنية المعمارية ← المراقبة.


  • نقطة دردشة WebSocket ميتة (410 Gone). على كل مستهلكي الواجهة البرمجية استخدام SSE.
  • حدث SSE approval_required هو الطريقة المعيارية لعرض وقفات HITL في الواجهات الأمامية؛ اقرنه بـ POST /api/approve/\{thread_id\}.
  • فرض ملكية /api/approve (403 عبر المستخدمين) يعني أن رموز الموافقة لكل مستخدم — لا يمكن للمسؤول الموافقة على مهمة مستخدم آخر دون تطابق حقول الهوية.
  • V2 هي مكدّس الذاكرة الوحيد — استدعاء كل دورة، والأدوات، والتخزين التلقائي، والضغط كلها تستخدم recall() من memory/recall.py. أُزيل مُكيّف الطبقات الأربع (V1، get_adapter()) في التحوّل من V1 إلى V2.