تخطَّ إلى المحتوى
kazma.
البحث في كاظمه والتوثيق
EN

واجهة البرمجة (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المهاراتمسارات المهارات
mcp_routerMCPمسارات MCP
agents_routerالوكلاءمسارات الوكلاء
providers_router/api/providersمسارات المزوّدين
sse_router/api/chat/*sse_chat/
telemetry_routerالقياس عن بعدمسارات القياس عن بعد
dashboard_router/api/dashboard/*dashboard.py
models_routerالنماذجمسارات النماذج
workspace_routerمساحة العملمسارات مساحة العمل
swarm_router/api/swarm/*swarm_panel/
monitor_routerالمراقبةمسارات المراقبة
metrics_routerالمقاييسمسارات المقاييس

إضافة إلى مسارات مباشرة في routes_direct/ وwebhook تيليجرام شرطي على /api/webhooks/telegram ‏(app.py).


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

Section titled “2. نقاط النهاية الرئيسية (مُتحقَّق منها)”
الطريقةالمسارالغرض
POST/api/chat/streamنقل الدردشة الأساسي. الجسم \{message, session_id, model\}. يعيد text/event-stream. ‏(sse_chat/__init__.py)
POST/api/chat/sessionsربط جلسة فارغة بالمستدعي المصادَق عليه قبل فتح مقبس قياسها عن بعد. يتطلب حماية CSRF.

| GET | /api/chat/sessions | عرض الجلسات. (السطر 547) | | DELETE | /api/chat/sessions/\{session_id\} | حذف الجلسة. (السطر 555) | | GET | /api/chat/sessions/\{session_id\}/messages | سجل الجلسة. (السطر 561) |

نقل الرسم البياني: ‏POST /api/chat/stream. ‏/ws/chat/{session_id} هو ناقل القياس عن بعد / المؤشر: لا يشغّل أي دور ولا يقبل التحكم في الأدوار (الإرسال والموافقة والإيقاف والتوجيه والإلغاء عبر HTTP/SSE؛ ويرفضها المقبس مع ذكر المسار).

الطريقةالمسارالغرض
GET/api/provider/activeالمزوّد/النموذج النشط.
POST/api/provider/switchتبديل المزوّد/النموذج النشط.
GET/api/providersعرض المزوّدين، مع مفاتيح مقنَّعة ونماذج مكتشفة وcapabilities معلَنة.
POST/api/providersإضافة مزوّد أو تحديثه. المفتاح المقنَّع **** يعني «أبقِ المخزَّن».
DELETE/api/providers/{name}إزالة مزوّد.
POST/api/providers/{name}/toggleتمكين أو تعطيل.
POST/api/providers/{name}/testفحص صحة — انظر أدناه.
POST/api/providers/{name}/discoverجلب قائمة نماذج المزوّد.

‏/api/providers/* هي السطح الوحيد للمزوّدين. وُجد مسار موازٍ /api/settings/providers/* بنفس العمليات الست وحُذف: مساران لمفهوم واحد هو كيف ينحرفان، وقد انحرف هذا الزوج بما يكفي حتى شُحن إصلاح في المسار الذي لم يستدعه أحد.

ما يعيده …/test. «قابل للوصول» و«يعمل» ادعاءان مختلفان، لذا الاستجابة تحملهما معًا:

الحقلالمعنى
reachableأجابت قائمة النماذج. ليس ادعاءً بأن المزوّد يعمل.
chat_okعاد إكمال حقيقي على POST /chat/completions.
chat_ms, chat_modelزمن استجابة ذلك الإكمال، والنموذج الذي يقول المزوّد أنه خدمه.
successكلاهما أعلاه.

يحل الفحص مفتاحه عبر ModelRegistry.resolve_provider_credentials ونموذجه عبر ModelRegistry.probe_model_for — نفس المسارات التي تستخدمها رسالة حقيقية. لا يحل شيئًا يدويًا، ولا يكتب.

تذكر إخفاقات الفحص حالة HTTP وإرشادًا عمليًا. تُستبعد أجسام الاستجابات البعيدة وعناوين الطلبات التي تحمل بيانات اعتماد من التشخيصات.

الطريقةالمسارالغرض
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الموافقة على نقطة تفتيش خط الأنابيب: 202 بمجرد تسجيل التشغيل المستأنَف؛ ويظهر التقدّم في تدفق المهمة. للمسؤول.
POST/api/swarm/tasks/\{id\}/rejectرفض نقطة تفتيش خط الأنابيب. للمسؤول.
GET/api/swarm/workers/\{name\}/metricsمقاييس العامل.
GET/api/swarm/circuit-breakersحالات قواطع الدارة.
الطريقةالمسارالغرض
GET/health/liveالحياة. ‏(health.py:94)
GET/health/readyالجهوزية. (السطر 104)
GET/health/detailsصحة مفصلة. (السطر 148)
GET/api/gateway/statusحالة البوابة/المُكيّف.

2.7 توافق الذاكرة وواجهات المشغّل

Section titled “2.7 توافق الذاكرة وواجهات المشغّل”
الطريقةالمسارالعقد الحالي
GET/api/memory/graphHTTP 410؛ استخدم /api/memory/v2/graph.
GET/api/memory/graph/statsHTTP 410؛ استخدم /api/memory/v2/health.
GET/api/memory/graph/exportHTTP 410؛ استخدم سطح الرسم V2.
GET/api/memory/graph/searchبحث توافقي تدعمه معتقدات V2.
POST/api/memory/graph/clearيحتاج تأكيدًا وتفويض المستأجر؛ يبطل المعتقدات الحالية مع حفظ التاريخ والحلقات.

قد لا يكون لتشخيصات المشغّل ونقاط التكامل العامة مستدعٍ في المتصفح عمدًا. يحتوي tests/test_api_route_callers.py جردها المعتمد وأسباب المستدعين؛ وليس الغياب من الواجهة معيارًا للحذف. تبقى الاستعادة متاحة عبر python -m kazma_core.backup.restore؛ انظر التعافي من الكوارث.

يعيد POST /api/chat/stream أحداثًا مرسلة من الخادم (Server-Sent Events): سطر event: يسمّي الإطار، وسطر data: واحد يحمل كائن JSON. المصدر: kazma-ui/kazma_ui/sse_chat/ (المسار ومُرسِل الدور _streaming.py) وسجل الدور kazma-ui/kazma_ui/delivery.py؛ ويقرؤه المتصفح عبر dispatch في static/js/streaming.js.

إطارات الدور تُسجَّل أولًا. يُكتب كل إطار في سجل المحادثة قبل إرساله، فيحمل سطر id:، وتحمل بياناته seq (الرقم نفسه) وturn_id. والعميل الذي ينقطع تدفقه يعيد الطلب وفيه last_event_id (أو last_seq) بدل رسالة: فيصله إطار resumed، ثم كل إطار فاته، ثم الدور الجاري. والإطار المُعاد عرضه سجلًّا يحمل replay: true؛ ولا تُعرض موافقة معلّقة فيه إلا بعد أن يؤكد سجل البوابات أنها ما زالت مفتوحة. ولا يُعاد عرض إطارات error وcapacity وuser_message وthread_rewound، ولا أي إطار تقول بياناته capacity: true. وفي أثناء الصمت يرسل التدفق أسطر تعليق : keepalive.

event:متىحقول data
resumedأول إطار في كل تدفق يتبع دورًا: رسالة جديدة، وإعادة اتصال، والانتظار بعد موافقة. لا يُسجَّل.from، وto (أحدث seq في السجل)، وcount (الإطارات المُعاد عرضها)، وgap، وrunning، وsession_id، وthread_id
tokenجزء من الإجابة يُلحق بالترتيب: قطعة متدفقة، أو فاصل فقرة بين استدعاءين للنموذج، أو النص النهائي مقروءًا من نقطة الحفظ حين لم يتدفق شيء، أو إشعار (توقف الدور دون بطاقة موافقة، أو انتهى بلا نص، أو فشل قبل الرد).content
tool_callتبدأ أداة.tool_name، وtool_call_id (هو نفسه في tool_result الخاص بها)، وinputs (نص JSON، ‏2,000 حرف على الأكثر)
tool_resultانتهت الأداة.tool_name، وtool_call_id، وresult (‏5,000 حرف على الأكثر)
memory_explainأُعطي المشرف ذكريات لهذا السؤال؛ ويحفظ الدور السجل نفسه.query، وempty، وdetail، وbeliefs، وepisodes، وweekly_summaries، وknowledge (لكل عنصر: id، وkind، وcontent، وscore، وsources)، وsummary (الأعداد)
turn_heartbeatكل 10 ثوانٍ تقريبًا دون إطار آخر (كل 8 حين يُستأنف الدور بعد موافقة).phase (llm أو supervisor أو tool أو resuming)، وcurrent (الأداة)، وdetail، وstep، وelapsed_s
status_updateبلغ المخطط نهايته وتُكتب الإجابة (status: "synthesizing"، وactive_node: "Respond"). أو مؤشر العميل ليس في السجل (status: "resync"، وseq): فهو أقدم مما يحفظه السجل، أو متقدم عليه بعد إعادة تشغيل الخادم أو ساعة من الخمول، حين يبدأ السجل من جديد عند 1. ينتهي التدفق هنا. ويعيد العميل تحميل المحادثة من المخزن ويأخذ seq مؤشرًا جديدًا له (وإطار resumed يحمل gap يعني الشيء نفسه).status، ثم active_node أو seq
statusوصل استئناف ثانٍ إلى دور يعمل أصلًا؛ ويتبع هذا التدفق ذلك الدور.content، وstatus (thinking)
context_compactedقلّص هذا الدور سياق النموذج أو طوى مخرجات أدوات قديمة.detail، مع أعداد مثل stubbed_segments، وdropped_user، وdropped_assistant
approval_requiredتوقف المخطط مؤقتًا لطلب موافقة. لا يتبعه done: يبقى التدفق مفتوحًا، ويستمر الدور فيه بعد POST /api/approve/{thread_id}.thread_id، وinterrupt_id، وkind، وtool، وargs، وtools، وitems، وmessage، وyolo_allowed، وalways_ask (أداة تطلب الموافقة دائمًا مثل عملية كتابة في X: موافقة لمرة واحدة أو رفض فقط، دون منح للجلسة)، وapproval_deadline، وview وgate_views من سجل البوابات
hitlحُسمت موافقة، في هذا التبويب أو تبويب آخر أو تطبيق محادثة.state (approved أو denied أو timeout)، وinterrupt_id، وtool، وthread_id، وturn_id، وactor، وview، وgate_views
approval_timeoutلم يُجب أحد في الوقت: لا تُشغَّل الأداة، ويُبلَّغ النموذج بأن الموافقة انتهت صلاحيتها (لا بأنها رُفضت)، وينتهي الدور بإجابته.thread_id، وinterrupt_id، وtool، وturn_id، وmessage
capacity‏/long أو /plan أو /yolo، يُجاب عنها دون النموذج؛ ويتبعها done فيه capacity: true.action، وreply، وlong_active وyolo_active، أو plan_active
errorفشل الطلب أو الدور. قبل أن يبدأ الدور (محتوى ليس JSON، أو رسالة تتجاوز 512,000 حرف، أو رسالة فارغة، أو لا مفتاح API لمزوّد سحابي، أو نفاد ميزانية الجلسة) يكون الإطار الوحيد.content (بلا تفاصيل داخلية)
doneانتهى الدور. content هو الإجابة، ويحل محل ما بنته إطارات token.content، وtokens، وcost، وduration_ms، وinterrupted، وempty، وmodel، وturn_id، وsession_tokens، وsession_cost، وgate_views
turn_completeبعد done مباشرة، بالبيانات نفسها.كما في done
snapshotبعد done، حين حفظ «السفر عبر الزمن» هذه الخطوة.snapshot_id، وiteration، وmodel
user_messageبدأ تبويب آخر دورًا في هذه المحادثة. لا يصل إلا إلى التدفقات المتصلة بالمحادثة أصلًا، ولا يصل إلى تدفق المُرسِل نفسه، ولا يُعاد عرضه؛ وتأخذه صفحة المحادثة من WebSocket الخاص بها، الذي يحمل السجل نفسه.content، وturn_id، وclient_msg_id، وsession_id، وts
thread_rewoundاستُعيدت المحادثة إلى خطوة من «السفر عبر الزمن» (من أي واجهة). يعيد كل تبويب مفتوح تحميل المحادثة من المخزن؛ ولا يُعاد عرضه أبدًا.thread_id، وsession_id، وsnapshot_id، وturn_index، وmessage_count

ردود دون النموذج. تجيب /reset و/compact واستعمال /swarm المجرد بإطار token وإطار done يحمل content وtokens وcost وduration_ms، ولا تُسجَّل. ويرسل استعمال /research و/replay و/fork الإطارين نفسيهما مع capacity: true، مسجَّلين لتراهما تبويبات المحادثة الأخرى. وينتهي التدفق المتصل بعد done أو turn_complete (إلا إن كان interrupted)، أو بعد error.

انتهاء صلاحية موافقة HITL: إذا نقر المستخدم على موافقة/رفض على بطاقة انتهت مهلتها أو استُؤنفت بالفعل، يعيد POST /api/approve/{thread_id} ‏HTTP 409 مع {"status": "expired", "error": "No pending approval for this thread (already resumed or expired)."}. تكشف الواجهة الأمامية (hitl_approval.js) ذلك وتنقل البطاقة إلى «منتهية أو مستأنفة بالفعل» ثم تزيلها. والقرار الذي يسمّي بوابة (interrupt_id) حُسمت من قبل، أو بوابة لمحادثة أخرى، يُرَدّ عليه أيضًا بـ 409: reason: "not_pending"، مع hitl_state (inflight أو settled أو foreign)، وregistry_state، وinterrupt_id البوابة.

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_name, data.inputs); break;
case 'tool_result': showToolResult(data.tool_name, data.result); break;
case 'approval_required': promptApproval(data.thread_id, data.interrupt_id, data.tool); break;
case 'done': finishTurn(data.content, data.tokens, data.cost); break;
case 'error': showError(data.content); break;
}
}

3.2 الموافقة عبر API ‏(Python)

Section titled “3.2 الموافقة عبر API ‏(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 تلقائيًا. تُولَّد المخططات من تلميحات الأنواع مع additionalProperties: false. تبقى المعاملات الاختيارية اختيارية ما لم يكن KAZMA_STRICT_TOOLS=1. لرد JSON لمرة واحدة (ليس استدعاء أداة)، مرّر response_format= إلى LLMProvider.chat — لا تضعه في كل دورة مشرف.

4.1b خطاطيف الأدوات (PreToolUse / PostToolUse)

Section titled “4.1b خطاطيف الأدوات (PreToolUse / PostToolUse)”
from kazma_core.agent.tool_hooks import register_pre_tool_hook, ToolHookDecision
def block_shell(event):
cmd = str((event.tool_input or {}).get("command") or "")
if "rm -rf" in cmd:
return ToolHookDecision(decision="deny", reason="blocked pattern")
return None
register_pre_tool_hook(block_shell, matcher="shell_exec")

أو YAML ‏(agent.hooks.pre_tool / post_tool): كل مدخل هو {matcher, command, timeout_seconds?}. يستقبل الأمر JSON على stdin ‏(hook_event_name، tool_name، tool_input، وبعد التنفيذ tool_response) وقد يطبع JSON ‏(decision، tool_input / updatedInput، reason، extra) أو يخرج بـ 2 للرفض. الخطاطيف لا تستطيع الموافقة تلقائيًا على HITL. مفتاح الإيقاف: KAZMA_TOOL_HOOKS=0.

المزوّدون مدخلات 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) وصله في كتلة الفرادى للناقل في app.py.

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

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

نافذة طرفيّة
kazma swarm worker add researcher --model deepseek-chat --provider deepseek --type in_process --role researcher

أو عبر API:

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 هو الافتراضي للدردشة (استرجاع لكل دور، أدوات، تخزين تلقائي، دمج) ويُستخدم أيضًا من التحسين الذاتي / دفتر الهاتف. (حُذف 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], ranked by evidence (meaning above the question's
# background + content words covered); empty when nothing clears the threshold

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

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 معلَنة لكن تتبع كاظمه باعث نطاقات داخلي الصنع. انظر البنية ← القابلية للمراقبة.


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