Skip to main content
Glama

CI Tests Coverage Security Python Platforms License MCP Docs PRs welcome

العربية · English · الموقع التعريفي · المناقشات

ZYKO — منصة تنسيق الذكاء الاصطناعي الشاملة

النسخة 0.8.0 · توجيه متعدد المزوّدين بقرارات قابلة للتحقق · حوكمة Policy-as-Code · وكلاء أصليون بـ MCP · تتبّع مدمج يُصدَّر إلى أي خلفية OTLP · RAG محلي بلا اعتماديات

تعمل على: Linux · Windows · macOS · Android · Termux — بنية Python خالصة، لا شيء يُترجم إلزاميًا على أي منصة.


لماذا ZYKO؟

أربعة ركائز تميّز ZYKO عن كل البوابات الموجودة:

الركيزة

ماذا تعني عمليًا

توجيه قابل للتحقق

كل استجابة تحمل «إيصال توجيه»: ترتيب كامل للمرشحين بمكوّنات الدرجات (جودة/تكلفة/زمن) والأوزان المنشورة. أعد التحقق من أي قرار سابق دون اتصال.

جودة صادقة

درجات الجودة تأتي فقط من مقاييس مرجعية قابلة لإعادة الإنتاج (zyko bench) ببذور ثابتة ومصحّحات موضوعية — لا من جداول تسويقية.

حوكمة شيفرة-كسياسة

سقف إنفاق يومي، حجب PII حتمي، قوائم سماح للنماذج والأدوات، حدود معدل، وسجل تدقيق — كل ذلك في ملف YAML واحد مُطبَّق على كل نداء.

MCP أولًا

ZYKO يستهلك خوادم MCP كأدوات لوكلائه، ويعرض نفسه كخادم MCP (zyko mcp serve) لأي مضيف MCP.

Related MCP server: evav-gateway

من أين استلهم ZYKO؟ (أنماط المشاريع الكبيرة)

النمط المُعتمد

المصدر

محوّلات موحّدة بصيغة OpenAI، إعادة محاولة أُسّية، واحترام Retry-After من الخادم

LiteLLM

مزوّد فوق المزوّدين، تسمية provider/model، ورؤوس الإحالة (HTTP-Referer/X-Title)

OpenRouter

درجات جودة مشتقّة من مقاييس مرجعية قابلة لإعادة الإنتاج لا من جداول تسويقية

RouteLLM

الحوكمة كإعدادات مُعلنة: سقوف إنفاق، قوائم سماح، تدقيق

Portkey Gateway

بروتوكول مفتوح يوحّد أدوات الوكلاء (عميل + خادم)

Model Context Protocol

تميّز ZYKO ليس الاختراع من الصفر بل التحقق: إيصالات توجيه تُعاد من دون اتصال، دفتر جودة قابل لإعادة الإنتاج، وسياسة مُطبَّقة على كل نداء — على كل منصة.

ما الجديد في 0.8.0؟ (الإيصال أصبح قابلًا للتحقق فعلًا — أمر zyko verify)

كان الإيصال حتى 0.7 مُعلمًا لا قابلًا للتحقق: مستند JSON فيه الترتيب والمكوّنات والأوزان، لكن لا شيء يعيد حسابه. الآن:

zyko ask "hello" --demo --receipt r.json   # كل نداء يمكنه كتابة إيصاله
zyko verify r.json                         # إعادة حساب كاملة دون اتصال
zyko verify r.json --ledger ledger.json    # + مطابقة درجات الجودة بالدفتر
zyko verify r.json --json                  # تقرير للأنابيب والبرامج

zyko verify يعيد حساب كل total من الأوزان والمكوّنات المسجّلة، ويتحقق من أن الأوزان هي أوزان الاستراتيجية المنشورة بالضبط، وأن كل مكوّن داخل [0, 1]، وأن الترتيب تنازلي، وأن درجات الجودة تطابق دفتر الجودة المقدَّم (مع طابع ledger_updated) — ويخرج بالرمز 1 عند أي انحراف، فتصلح للمراقبة في CI.

خلل حقيقي اكتُشف بهذا المتحقق وأُصلح: كان نطاق تطبيع التكلفة يُحسب دائمًا على تقدير 800/400 رمز بينما تُقيَّم الطلبات القصيرة بتقديرها الفعلي، فخرج cost_score أحيانًا أكبر من 1.0 (مثال: 1.0441) وكسر ثابت «كل الدرجات في [0, 1]» الذي يعلنه الإيصال. الآن يُمرَّر التقدير نفسه إلى لقطة اللوحة، والنتيجة محصورة في [0, 1] دفاعيًا.

  • 14 اختبارًا جديدًا (tests/test_verify.py + اختبار انحدار للنطاق) — 579 اختبارًا ناجحًا.

  • اختبارات المنصة صارت واعية بـTermux (كانت تفترض Linux/Windows فقط).

ما الجديد في 0.7.0؟ (بوابة متعددة المستخدمين محكومة — هويات لا مجرد رمز)

بند قائمة ما قبل الإنتاج الواسع: حتى 0.6 كانت البوابة تعرف رمزًا حاملًا واحدًا فقط. الآن كل منشئ طلب هوية مُسمّاة بمفتاحها وأدوارها وحدّ معدلها وميزانيتها اليومية، من ملف مستخدمين تصريحي. التحقق بزمن ثابت (hmac.compare_digest على كل مدخل بلا خروج مبكر)؛ والمفاتيح يمكن تخزينها كسجلات scrypt قياسية (zyko hash-key) فلا يحمل الملف سرًا صالحًا؛ والحوكمة تُفرض لكل مستخدم لا عالميًا فقط، وكل إيصال استجابة يحل هوية منشئ الطلب.

# users.yaml
users:
  - name: alice
    key: zk-dev-only              # تطوير فقط
    roles: [chat]
    rpm: 60
  - name: ops
    key_hash: scrypt$16384$8$1$…$…   # من `zyko hash-key`
    roles: [chat, admin]
    daily_budget_usd: 5.0
zyko hash-key                          # يطبع سجل scrypt (الإدخال مخفي)
zyko serve --users users.yaml          # بوابة متعددة المستخدمين
curl -H 'Authorization: Bearer op-secret' localhost:8787/v1/users/me
  • حوكمة لكل مستخدم: ‏401 رمز غير صالح، ‏403 مستخدم معطّل، ‏429 تجاوز حد المعدل (zyko_rate_limit)، ‏429 تجاوز الميزانية اليومية (zyko_budget_exceeded)؛ وكل إيصال يحمل "user" والاستخدام اليومي (طلبات/توكنات/دولار مقدّر) يُخزَّن لكل مستخدم وينجو من إعادة التشغيل.

  • GET /v1/users/me: يفحص المستخدم هويته واستخدامه ومتبقّي ميزانيته — لا مادة سرية تترك المخزن أبدًا.

  • فشل مبكر مكتوب النوع: أسماء مكررة، أدوار مجهولة، rpm/ميزانية غير صالحة أو مفتاح ناقص ترفع GatewayAuthError (فرع من ConfigError) قبل ربط الخادم — ملف معطوب لا يُشغّل بوابة نصف جاهزة.

  • الأنماط القديمة كما هي: --api-key الرمز الواحد (أصبح بزمن ثابت أيضًا) والبوابة المفتوحة؛ إيصالاتها بلا مفتاح "user".

  • 28 اختبارًا جديدًا — 565 اختبارًا ناجحًا، bandit صفر، CI 14/14.

ما الجديد في 0.6.0؟ (طواقم متعددة الوكلاء — خط أنابيب تسلسلي بسياق مشترك — توازي CrewAI في البساطة، أقوى في الحوكمة)

الخطوة 4 من خارطة الصدارة: ZYKO الآن تنسّق طاقمًا من الوكلاء. قائمة خطوات مرتبة، كل خطوة وكيل مُهيّأ + قالب مهمة يحيل إلى مدخل الطاقم ({task}) أو مخرج الخطوة السابقة ({output}) أو أي output_key سابق. التنسيق آمن بنيويًا: المفاتيح المجهولة تبقى نصًا حرفيًا ({json} في نثر عادي نص لا انهيار)، القيم المُستبدلة لا تُعاد صياغتها أبدًا (JSON والأقواس تنجو من الرحلة ذهابًا وإيابًا)، والقوالب تُدقَّق عند البناء — فشل مبكر لا في منتصف التشغيل. الحوكمة أقوى: بلا مطالبات خفية — كل وكيل يحتفظ بنصه النظامي وأدواته وسياساته، وكل خطوة داخل span crew.step تحت crew.run، والنتيجة إيصال كامل قابل للتدقيق.

from zyko import Zyko

zk = Zyko()
crew = zk.crew("triage.yaml")  # YAML تصريحي: وكلاء مضمّنون أو ملفات
res = crew.run("فاتورتي متأخرة")
print(res.output)  # إجابة الوكيل الأخير
print(res.outputs["class"])  # مخرج أي خطوة مُعلنة
  • ثلاثة مراجع فقط في القوالب: {task} (مدخل الطاقم)، {output} (مخرج الخطوة السابقة)، {output_key} لأي خطوة سابقة. المجهول يبقى حرفيًا؛ المشوّه ({}، {0}) يرفع CrewError عند add() — فشل مبكر.

  • YAML تصريحي: خطوات تُحيل لملفات وكلاء أو تعريفات مضمّنة؛ ومن الطرفية zyko crew crew.yaml --input "..." [--json|--trace] — ووضع --json يطبع إيصال CrewResult وحده على stdout (عقد آلي نظيف).

  • إيصال قابل للتدقيق: CrewResult — output + outputs (بترتيب الإعلان) + سجل لكل خطوة (الوكيل/المفتاح/المهمة المملوءة/الخطوات/المقتطع/ الزمن) + مجموع التوكنات + trace_id، وكلها مرئية في zyko traces وأي خلفية OTLP.

  • أخطاء مكتوبة النوع: CrewError (طاقم فارغ، مفتاح مكرر، قالب مشوّه) من جذر zyko؛ وإخفاقات المزوّد تعبر خط الأنابيب بنوعها الحقيقي (ProviderError بعد استنفاد إعادة المحاولة) لا كسلاسل نصية.

  • 34 اختبارًا جديدًا — 537 اختبارًا ناجحًا، bandit صفر، CI 14/14.

ما الجديد في 0.5.0؟ (أساسيات RAG — اقتطاع ثم تمثيل ثم بحث ثم context= — أقل ما يرضي مستخدم LlamaIndex)

الخطوة 3 من خارطة الصدارة: ZYKO الآن ترسيخ الإجابات في مستنداتك. مقتطع نصوص، ثلاثة مُدمجات خلف عقد واحد، مخزن متجهات محلي تُخزّن ملفه JSON ملكك (فلسفة سجل التتبّع نفسها)، ووسيط context= على ask. المُدمج الافتراضي تجزئة سمات بلغة بايثون الخالصة — حتمي، بلا شبكة، يعمل على هاتفك — فتشتغل القصة كاملة بصفر مفاتيح وصفر اعتماديات جديدة؛ وبدّل إلى Ollama (محلي، دلالات حقيقية، بلا مفاتيح) أو OpenAI متى أردت:

from zyko import Zyko
from zyko.rag import HashingEmbedder, VectorStore

store = VectorStore(HashingEmbedder(), path="kb.json")
store.add(open("handbook.md").read(), meta={"source": "handbook"})
hits = store.search("سياسة الاسترداد", k=4)
answer = Zyko().ask("ما سياسة الاسترداد؟", context=[h.text for h in hits])
  • ثلاثة مُدمجات بعقد واحد: HashingEmbedder (تجزئة blake2b — حتمي عبر الأجهزة، مثالي للاختبارات والعروض وTermux)، OllamaEmbedder (‏nomic-embed-text محليًا — دلالات حقيقية بلا مفاتيح)، OpenAIEmbedder (‏text-embedding-3-small أو أي نقطة نهاية متوافقة).

  • VectorStore: فهرس جيب التمام في الذاكرة مع حفظ ذري (tmp + replace) بعد كل إضافة وتحميل تلقائي عند البناء؛ min_score=0.0 الافتراضي يُبقي المقاطع الموجبة الارتباط فقط؛ aadd/asearch نسختان غير متزامنتين.

  • أخطاء مُنمّطة: كل فشل embeddings يرفع EmbedderError الجديدة (مصدّرة من جذر zyko) — لا استثناء httpx خام أبدًا؛ عدم تطابق الأبعاد يُرفض بدل إفساد الفهرس؛ ملف مخزن تالف يبدأ فارغًا بدل الانهيار.

  • ask(prompt, context=[...]): السياق غير الفارغ يصبح رسالة نظام راسخة ("أجب من السياق، وقل صراحةً إن لم يكفِ") بعد أي system صريح وقبل سؤال المستخدم — ويعمل مع نصوص عادية بلا مخزن.

  • 26 اختبارًا جديدًا — 503 اختبارات ناجحة، bandit صفر، CI 14/14.

ما الجديد في 0.4.2؟ (جسر الملاحظة — spans تتدفق إلى Langfuse/Tempo/Jaeger دون اعتمادية جديدة)

خطوة 2 من خارطة الصدارة في docs/STRATEGY.md: spans كانت على قرصك (0.4.1)، والآن تتدفق إلى أي خلفية OTLP يتحدث بها فريقك. OtlpSink ينطق OTLP/HTTP-JSON — بروتوكول OpenTelemetry Collector القياسي — عبر httpx الموجود أصلًا، فيعمل مع Collector وLangfuse وGrafana Tempo وJaeger وHoneycomb وNew Relic وDatadog بصفر اعتماديات جديدة وصفر احتكار بائع. متغير بيئة واحد يشغّله:

ZYKO_OTLP_ENDPOINT=http://localhost:4318/v1/traces zyko ask "مرحبًا"
  • لا يُبطئ النداء أبدًا: الكتابة تضع في طابور وتعود فورًا؛ خيط خلفي واحد يجمع حتى 64 span لكل POST؛ امتلاء الطابور يهمل (ويعدّ) ولا يوقف.

  • معرّفات مطابقة للمواصفة حتميًا: 16 بايت trace / 8 بايت span مشتقة بـsha256 من معرّفات ZYKO، وروابط الأب باقية، والأصل كسمات zyko.trace_id/zyko.span_id — فحص zyko traces --trace <id> بلا فقدان.

  • وصفة Langfuse: نقطة النهاية https://cloud.langfuse.com/api/public/otel/v1/traces مع authorization: "Basic ${LANGFUSE_BASIC}" — ملفات الإعدادات تستبدل ${ENV_VARS} فلا يكتب السر على القرص.

  • zyko doctor يقول الآن حالة التتبّع وهدف الـOTLP في قسم Observability.

  • إكمال حتمية MCP: آخر زاوية من سباق macOS/py3.11 (0.3.7) — خادم يموت بعد ردّ initialize مباشرة كان قد يُفجّر start() نفسها. الإشعارات الآن إطلاق-ونسيان بعقد صريح (قارئ stdout يبقى مصدر الحقيقة؛ الطلبات تبقى ترفع MCPError المُنمّط) — start() حتمي على كل نظام، باختبار انحدار.

  • 14 اختبارًا جديدًا — 477 اختبارًا ناجحًا، bandit صفر، CI 14/14.

ما الجديد في 0.4.1؟ (تتبّع مدمج — ما يبيعه الآخرون خدمة مدفوعة نحن نقدّمه محليًا بلا اعتماديات)

كانت الملاحظة أكبر فجوة ميزات مقابل المنافسين: LangChain يبيعها LangSmith، وLangfuse/AgentOps تتطلب SDK خارجيًا وخدمة سحابية. ZYKO الآن تتتبّع كل نداء بـ spans على نمط OpenTelemetry (معرّفات trace/parent، مدد، حالات، سمات) — صفر اعتماديات جديدة، ملف JSONL ملكك على قرصك، وأمر فحص من نفس الـCLI:

from zyko import Zyko

zk = Zyko()
with zk.tracer.span("my-rag", corpus="support-docs"):  # span أبو لك
    zk.ask("لماذا تأخرت فاتورتي؟")  # span الموجّه يتداخل تلقائيًا
# لاحقًا: zyko traces --last 20   أو   --json   أو   --trace <id>
  • zyko traces — جدول زمني، --json دائمًا JSON صالح (عقد cost/cache)، --trace <id> لكل spans نداء واحد، --clear، و--file لمسار مخصص.

  • التتبّع لا يكسر النداء أبدًا: فشل الكتابة يتحوّل سطر تحذير واحد؛ التدفق المُهمَل (انقطاع العميل) يُغلق الـspan بحالة cancelled.

  • سجل دوار بحدّ (حالية + نسختان .1/.2) فلا يمتلئ القرص مهما طال تشغيل البوابة.

  • عطّله بـZYKO_TRACING=0 أو tracing.enabled: false — الواجهة نفسها بلا كتابة.

ما الجديد في 0.4.0؟ (المخرجات المنظمة — الميزة الأكثر تنافسية التي كانت لدى LangChain وCrewAI وAutoGen وينقصنا)

مراجعة قدرات مقابل LangChain (with_structured_output) وCrewAI (مخرجات Pydantic) وAutoGen (response_format) وLiteLLM (تمرير response_format) بيّنت أكبر فجوة متبقية: إجابات مقيّدة بمخطط (JSON Schema). تُرجع ZYKO الآن بيانات متحققًا منها أو خطأ مُنمّطًا — لا نصًا خامًا عليك أن تفكّه بنفسك — مع حلقة إصلاح تلقائية تُعيد أخطاء التحقق إلى النموذج. صفر اعتماديات إلزامية جديدة؛ Pydantic اختياري (zyko[structured]) لا شرط:

from zyko import Zyko

zk = Zyko()
out = zk.structured(
    "ما تفاصيل الطلب 42؟",
    schema={
        "type": "object",
        "properties": {
            "id": {"type": "integer"},
            "status": {"type": "string", "enum": ["open", "shipped"]},
        },
        "required": ["id", "status"],
    },
)
out.data  # {"id": 42, "status": "shipped"} — متحقق منه، أو خطأ مُنمّط StructuredOutputError
out.repaired  # هل لجأ الإصدار إلى جولة إصلاح؟
  • مُصادِق JSON Schema خالص من Python: أنواع، enum/const، حدود رقمية ونصية، pattern، تنسيقات أساسية، قوائم وكائنات متداخلة، allOf/anyOf/oneOf، وحلّ $ref/$defs المحلي بحماية من الدوران — ما تحتاجه مخططات Pydantic دائمًا. ولغة Python تلتقط الفخّ الكلاسيكي: True ليس عددًا صحيحًا هنا.

  • حلقة إصلاح تلقائية: عند فشل التحقق تُرسَل الأخطاء الفعلية (بمساراتها $.id…) إلى النموذج في جولة تصحيح واحدة قابلة للزيادة (max_repairs)، وبعدها خطأ مُنمّط يحمل errors وtext.

  • مستخرِج JSON مقاوم للفوضى: ينجو من النثر المحيط وأسيجة Markdown وكتل <think> (نمط DeepSeek).

  • وضع أصلي اختياري: native=True يرسل response_format: {"type": "json_schema", …} للمزوّدين الداعمين (OpenAI، Groq، Mistral، DeepSeek، OpenRouter، Together، xAI)، والبائع الذي يرفضها يسقط في التوجيه البديل تلقائيًا.

  • دعم عبر المزوّدين: Google يُرسَم إلى generationConfig.responseMimeType (+ responseSchema)؛ والبوابة المتوافقة مع OpenAI تقبل response_format في جسم الطلب وترفض غير الكائنات بـ 400.

  • سلامة الطبقات: مخطط مُعطّب = SchemaSpecError فوري (خطأ مُبرمِج)، بينما فشل النموذج = StructuredOutputError؛ ومفاتيح الذاكرة المؤقتة (basis v2) تشمل response_format فلا تُقدَّم إجابة نصية مخزّنة لطلب منظم.

63 اختبارًا جديدًا (tests/test_structured.py) — 438 اختبارًا ناجحًا.

ما الجديد في 0.3.9؟ (ذاكرة تخزين مؤقت للاستجابات — أكبر فجوة كانت أمام المنافسين)

مراجعة مقارنة ضد LiteLLM وPortkey أظهرت أن ZYKO يكافئهم في إعادة المحاولة الأُسّية والتحوّل التلقائي وقواطع الدائرة وسقوف الإنفاق وحجب PII — لكنه كان يفتقد ذاكرة تخزين للاستجابات. أُضيفت الآن خلف قسم سياسة واحد، مطفأة افتراضيًا:

# في ملف السياسة (Policy-as-Code):
cache:
  enabled: true
  ttl_s: 300        # مدة صلاحية الإجابة (ثانية)
  max_entries: 512  # حد LRU
  • مفتاح دقيق: SHA-256 على الحمولة الصادرة الكاملة (المزوّد، النموذج، الرسائل، الحرارة، الأدوات) — الإصابة تعني أن البائع كان سيجيب نفس الإجابة نفسها.

  • لكل مرشّح مفتاحه: إجابة openai/* المخزّنة لا تُقدَّم أبدًا لطلب وجّه إلى anthropic/*.

  • إيصال صادق: الإصابة تظهر كـ cache-hit و"cached": true — بلا نداء للبائع، بلا خصم من الميزانية، بلا كتابة في متعقّب الصحة.

  • آمنة للوكلاء: الردود التي تحمل tool_calls لا تُخزَّن أبدًا؛ البثّ يتجاوز الذاكرة في هذه النسخة.

  • تحكّم لكل طلب: metadata={"cache": "bypass"} يتجاوز الذاكرة، و"refresh" يعيد التحقق من نداء واحد.

  • رؤية كاملة: zyko cache يعرض الإدخالات ونسبة الإصابة (--json دائمًا JSON صالح)، و--clear يفرّغها.

20 اختبارًا جديدًا — 375 اختبارًا ناجحًا.

ما الجديد في 0.3.8؟ (+xAI وTogether AI — عشرة مزوّدين مسجّلين)

مزوّدان جديدان متوافقان مع OpenAI على نفس رافعة الفئة (~30 سطرًا)، كل حقول الكتالوج مأخوذة من التوثيق الرسمي لكل بائع (الـ slugs ونوافذ السياق والأسعار المعلنة):

  • xai (XAI_API_KEY) — grok-4.7 (سياق 500 ألف، $2/$6)، grok-4.3 (سياق مليون، $1.25/$2.50)، grok-build-0.1 (سياق 256 ألف، $1/$2).

  • together (TOGETHER_API_KEY) — Kimi-K3، GLM-5.3، GLM-5.3-Flash، DeepSeek-V4.1-Flash، gpt-oss-120b، Qwen3.5-9B — باب واحد لنماذج مفتوحة بأسعار منافسة وسياقات تصل مليون رمز.

8 اختبارات جديدة (شكل الطلب، سلامة الكتالوج، حلّ المفاتيح) — 355 اختبارًا ناجحًا.

ما الجديد في 0.3.7؟ (سباق موت خادم MCP أصبح مُنمّطًا على كل منصة)

التقطتها ذراع macOS/py3.11 في CI بعد 0.3.6: عندما يموت خادم MCP بين write() وdrain() لدى العميل، كان drain() يرمي ConnectionResetError خام في بعض المنصات بدلاً من MCPError الموثّقة. الآن يسلك المسارَان (_request و_notify) سلوكًا واحدًا حتميًا على Linux وmacOS وWindows: خطأ مُنمّط واحد MCPError("closed the stream")، مع تنظيف الطلب المعلّق فورًا (يزيل تحذير "Future exception was never retrieved"). 347 اختبارًا ناجحًا.

ما الجديد في 0.3.6؟ (امتثال التنسيق لأداة ruff 0.17)

جولة نظافة صفرية التأثير: أداة ruff 0.17 غيّرت سلوك التنسيق (وأصبحت تنسّق كتل الكود داخل Markdown أيضًا). أُصلحت أربعة ملفات خارج نطاق CI الحالي (README.md وdocs/API.md وdocs/PROVIDERS.md وexamples/04_agent_tools.py) حتى لا ينكسر الـ lint مستقبلًا عند توسيع النطاق أو ترقية الأداة. لا تغيير في أي سطر تحت src/ أو tests/ — 347 اختبارًا ناجحًا كما هي، وruff format --check . نقي الآن على كامل الشجرة (97 ملفًا).

ما الجديد في 0.3.5؟ (توثيق عميق للمطوّرين)

ثلاثة مستندات مرجعية جديدة، كل توقيع فيها مأخوذ حرفيًا من الكود (لا اختراع):

  • مرجع API — العميل Zyko، محرك التوجيه وإيصاله، المزوّدون العشرة، PolicyEngine، البوابة، MCP بالاتجاهين، الوكلاء، الإعدادات والمسارات، شجرة الاستثناءات، خريطة CLI الكاملة.

  • المعمارية — مخططات mermaid لدورة حياة الطلب، لماذا الإيصال قابل للتحقق بالبناء، جودة مُقاسة لا مُدّعاة، الحوكمة على كل نداء، وقابلية النقل بين المنصات.

  • دليل المزوّدين — الاكتشاف التلقائي، إعداد YAML، أي بائع متوافق مع OpenAI، تسعير يغذّي التوجيه، المرونة (إعادة المحاولة/القاطع/البدائل)، وسير العمل بلا مفاتيح.

ما الجديد في 0.3.4؟ (إصلاح CI الحقيقي: الأخضر على المنصات الثلاث)

جولة 0.3.3 أصلحت بوابة الأمان محليًا — لكن CI على GitHub كان ما يزال أحمر بثلاث مشاكل حقيقية لم يكشفها Linux وحده:

  • bandit: unrecognized arguments: --exit-zero-on-skipped — العلم أُزيل في bandit الحديث؛ حُذف من أمر CI.

  • اختبار علامة Termux كان يفترض أن sys.platform == linux — الآن إشارة PREFIX=com.termux حاسمة بذاتها على كل الأنظمة (إصلاح إنتاجي وليس اختباريًا فقط).

  • اختبار XDG كان يفترض سلوك Linux على macOS/Windows — يثبّت الآن فرع LINUX صراحةً كما يفعل اختبار macOS.

النتيجة: الأخضر على Ubuntu + macOS + Windows × Python 3.11/3.12/3.13 + بوابة أمان تعمل فعلًا.

ما الجديد في 0.3.3؟ (بوابة الأمان التي لم تكن تعمل أبدًا)

جولة 0.3.2 أضافت بوابة أمان في CI — لكنها كانت ستفشل عند أول تشغيل حقيقي: bandit لا يقرأ pyproject.toml أصلًا (حتى الإصدار 1.9.x)، فتُتجاهل الاستثناءات الموثّقة (B101/B311/B404) بصمت ويظهر 11 نتيجة LOW. الإصلاح: ملف .bandit.yml حقيقي بتعليقات التبرير، يستهلكه CI وmake security معًا، وحُذف قسم [tool.bandit] المضلل. إضافة إلى 10 اختبارات حوافّ جديدة (الإجمالي 347): ربط أخطاء 500 الداخلية في البوابة، رؤوس Content-Length الكاذبة، انقطاع العميل أثناء البث (RST) مع بقاء الخادم صحيًا، إظهار MCP للأخطاء غير المتوقعة كـ isError دون انهيار الحلقة، جولة zyko_chat مع إيصال التوجيه، ربط default_policy، نقطة دخول python -m zyko.mcp.server، تسوية التكلفة/الزمن Degenerate، وقفزات القاطع/السياسة في astream_route. التغطية 98% والأسطر غير المغطاة 84 → 69.

ما الجديد في 0.3.2؟ (جولة تقييم كاملة: تغطية + lint + أمان)

جولة جودة شاملة على كامل الشيفرة — تحليل تغطية، فحص lint، تدقيق أمني — مع إصلاح كل النتائج واختبارها:

الخلل الحقيقي المُكتشف

المعالجة

Settings.load() كان يلوّث الإعدادات الافتراضية العامّة: _deep_merge يشارك القواميس المتشعبة مع ثابت DEFAULTS، فأول استدعاء بمتغيرات ZYKO_* كان يُعيد كتابتها بشكل دائم — كل الاستدعاءات اللاحقة ترث بيئة أول استدعاء (تلوّث عمليات البوابة طويلة الأمد والاختبارات معًا)

نسخ عميق للافتراضيات عند كل تحميل + اختبار انحدار مخصص

policies_dir()/agents_dir(create=True) لا ينشئان المجلد المُعاد — الأب فقط

create=True يضمن الآن وجود المجلد الطرفي نفسه

PolicyEngine كان ينهار بـ AttributeError خام على أقسام سياسة تالفة (defaults/privacy/rate_limit/audit بقيمة غير قاموس) قبل أن تصل آلية التحذيرات

الأقسام التالفة تتحلل إلى التحذيرات الموثّقة بدل الانهيار

نتائج الجولة: التغطية 92% → 98% (3491 عبارة) · الاختبارات 230 → 337 (107 اختبارات جديدة: دورة حياة MCP كاملة، حوكمة البث وأثر التدقيق estimated: false، قافز الدائرة والسياسة، اكتشاف المنصات، مصفوفات المزوّدين، رموز خروج POSIX 130/141) · ruff check وruff format نظيفان على كامل الشجرة · بوابة أمان في CI: bandit (0 نتائج) + pip-audit على التبعيات المعلنة · سكربتات التثبيت عادت لجذر المستودع.

ما الجديد في 0.3.1؟ (تصلّب الـ CLI + جولة تغطية)

جولة تقييم مستهدفة شغّلت كل أمر CLI فعليًا (وضع العرض) وطاردت الأعطال التي لا تراها الاختبارات وحدها:

العطل المُكتشف

المعالجة

zyko cost --json كان يطبع نصًا لا JSON عند غياب سجل التدقيق → كل الأنابيب اللاحقة (| jq، خطوات CI) تنكسر

فراغ السجل يُصدر نفس مخطط JSON للتقرير الحقيقي؛ رسالة [INFO] بقت للأمر العادي فقط

zyko serve على منفذ مشغول كان ينهار بـ traceback خام (OSError: Address already in use)

ردّ ودّي [FAIL] cannot start gateway + تلميح عملي (جرّب --port 8788)

zyko doctor | head كان يطبع BrokenPipeError traceback

خروج هادئ بالرمز 141 (128+SIGPIPE) كأداة POSIX محترفة

ويندوز: كونسول cp1252 القديم كان ينهار على —/·/الحروف العربية

حارس ترميز عند الإقلاع (errors="replace") — الحرف يُستبدل بدل قتل الأمر

نتائج الجولة: التغطية 89% → 92% (بروتوكول MCP والنواة وأدوات الوكلاء 95–100%) · الاختبارات 203 → 230 (ملف tests/test_hardening.py: حواف الحاسبة، هروب مساحة العمل، خرائط أخطاء HTTP الكاملة، توقيتات MCP، تبديل نواة Rust) · تدقيق أمان أكّد أن أدوات الخطر (shell) تبقى مقفلة ما لم تُسمَّ صراحةً في tools.allow — حتى مع allow: ["*"].

ما الجديد في 0.3.0؟ (جولة تقييم وعلاج)

جولة إعادة تقييم كاملة كشفت وعالجت أربع ثغرات وظيفية حقيقية، وأضافت أوامر رؤية جديدة:

الثغرة المكتشفة

المعالجة

التثبيت الصريح للنموذج كان مُهمَلًا: zyko ask --model openai/gpt-4o كان يتجاهله الموجّه ويختار أفضل مرشّح!

candidates_for() تُلزم المسار بالنموذج المطلوب (provider/model أو model مجرد أو provider/*)، وتفشل فورًا برسالة مفيدة إن لم يتوفر، والإيصال يسجّل requested_model للتحقق اللاحق

رفض 401 كان يُفسد اتصالات keep-alive في البوابة: جسم الطلب غير المقروء يُفسَّر كسطر طلب تالٍ → 501

جسم الطلب يُستهلك قبل أي ردّ خطأ — اختبار HTTP حقيقي بمقبس فعلي يثبت الدورة الكاملة (401 ثم 200 على نفس الاتصال)

إطار JSON-RPC تالف كان يُسقط خادم MCP بالكامل

الرد بـ PARSE_ERROR (-32700) حسب مواصفة JSON-RPC والاستمرار في الخدمة؛ كما صار zyko_models يعرض النماذج المتاحة فعليًا (مُرشّحة بالسياسة) لا كتالوجًا ثابتًا

ذاكرة الجلسات كانت ميزة «ميتة»: SQLite كاملة بلا أي رؤية في CLI وتغطية 25%

أمر جديد zyko sessions list/show/rm/clear + تغطية 98%

إضافات: zyko cost — تقرير إنفاق وحوكمة من سجل التدقيق (حسب اليوم، حسب المرشّح، تقديري مقابل مُبلَّغ من المورّد، قواعد الحجب) · التغطية 81% → 89% · الاختبارات 133 → 203.

التثبيت

الطريق الأسرع — سكربتات جاهزة في جذر المستودع:

# Linux / macOS / Termux — يشغّل ZYKO فورًا (ينشئ بيئة معزولة عند أول استخدام)
./zyko.sh ask "مرحبًا" --demo

# أو تثبيت دائم ببيئة معزولة (~/.zyko/venv)
./install.sh            # أضف --dev لأدوات الاختبار

# Windows (PowerShell أو cmd أو مشغّل فوري)
powershell -ExecutionPolicy Bypass -File install.ps1
install.bat
zyko.cmd ask "hello" --demo

# Docker — بوابة متوافقة مع OpenAI بحاوية واحدة
docker build -t zyko . && docker run --rm -p 8787:8787 zyko

أو عبر pip مباشرة:

pip install git+https://github.com/tibatechapp-ship-it/zyko.git

# من المصدر (كل المنصات)
git clone https://github.com/tibatechapp-ship-it/zyko.git && cd zyko
pip install -e .[dev]

على Python 3.14 / Termux لا تتوفر عجلة pydantic-core، لذا يتخطّى .[dev] تثبيت pydantic تلقائيًا (وبنفس المنطق تُتخطّى اختبارات pydantic عبر pytest.importorskip) — بقية الحزمة والاختبارات تعمل كاملة.

للمطوّرين: make test · make coverage · make lint · make security · make bench-demo (راجع Makefile).

التبعيات الأساسية: httpx وPyYAML فقط — كلتاهما Python خالص، لذا لا شيء يُترجم على أي منصة، بما فيها Termux.

على أندرويد/Termux

pkg install -y git && git clone https://github.com/tibatechapp-ship-it/zyko.git
cd zyko/android && bash install-termux.sh

راجع android/README.md للنموذج المحلي عبر Ollama على الهاتف، وويدجت البوابة الدائمة، وواجهة Kivy.

ابدأ في 60 ثانية

# أسرع تجربة — بلا مفاتيح، بلا شبكة، وضع عرض حتمي:
zyko ask "مرحبًا يا زيكو" --demo --explain
zyko route "ملخص هذا الملف" --demo
zyko ask "مرحبًا" --demo --receipt r.json && zyko verify r.json   # إيصال يُتحقَّق منه دون اتصال

# ثم بمزوّد حقيقي:
export OPENAI_API_KEY=sk-...        # أو أنشئ ollama محليًا ليعمل بلا مفاتيح

zyko ask "اشرح MCP في سطر واحد" --explain   # إجابة + قرار التوجيه
zyko serve                                   # بوابة متوافقة مع OpenAI
zyko doctor                                  # تشخيص البيئة والمفاتيح

وبرمجيًا:

from zyko import Zyko

zk = Zyko()  # المفاتيح من البيئة
outcome = zk.ask("مرحبًا")
print(outcome.response.text)
print(outcome.receipt["chosen"])  # القرار المُوجَّه — قابل للتحقق

# وكيل بأدوات:
agent = zk.agent({"name": "calc", "tools": ["calculator"], "max_steps": 6})
print(agent.run_sync("كم 47 × 16 × 7؟").output)

سطر الأوامر

أمر

الوظيفة

zyko ask PROMPT

إكمال لمرة واحدة عبر الموجّه (مع --receipt و--explain)

zyko chat

محادثة تفاعلية بذاكرة جلسات (SQLite)

zyko route PROMPT

خطة التوجيه فقط — بلا أي نداء API

zyko verify RECEIPT

إعادة حساب إيصال توجيه دون اتصال: الأوزان، الدرجات، الترتيب، ودفتر الجودة — يعيد رمز خروج 1 عند أي انحراف

zyko models

كل النماذج المتاحة مع درجاتها وأسعارها

zyko policy check/show/redact

التحقق من السياسات وعرضها وتجربة الحجب

zyko run AGENT.yaml TASK

تشغيل وكيل من تعريف YAML (مع --trace)

zyko serve

بوابة /v1/chat/completions متوافقة مع OpenAI (بما فيها البث SSE) — وأصبحت متعددة المستخدمين (--users users.yaml: مفاتيح وأدوار وحدود وميزانيات لكل مستخدم)

zyko hash-key

يسجّل مفتاح API بـscrypt ليوضع في key_hash: بملف المستخدمين (الإدخال مخفي بلا --key)

zyko mcp serve

اعرض ZYKO نفسه كخادم MCP عبر stdio

zyko mcp tools -- CMD

فحص أدوات أي خادم MCP

zyko bench

المقياس المرجعي القابل لإعادة الإنتاج (--repeats N لوسائط أثبت، و--update-ledger يغذّي الموجّه)

zyko traces

سجل التتبّع المدمج: آخر spans، --trace <id> لكل نداء واحد، --json دائمًا صالح

--demo (مع أغلب الأوامر)

وضع عرض بدون مفاتيح ولا شبكة عبر مزوّد المحاكاة الحتمي — يمرّ بالمسار الحقيقي كله: توجيه، سياسة، إيصالات، بث

zyko doctor / zyko info / zyko version

تشخيص البيئة، المفاتيح، والمسارات

المزوّدون

OpenAI · Anthropic · Google Gemini · Groq · Mistral · DeepSeek · OpenRouter · Together AI · xAI (Grok) · Ollama (محلي/بلا مفاتيح) — والمعمارية موحّدة: إضافة مزوّد متوافق مع OpenAI = فئة من ~30 سطرًا.

التوثيق

المستند

ماذا يغطي

مرجع API

كل التوقيعات من الكود: Zyko، Router، السياسات، البوابة، MCP، الوكلاء، الاستثناءات، خريطة CLI

المعمارية

دورة حياة الطلب، إيصال التوجيه القابل للتحقق، الطبقات ونقاط الامتداد (مخططات mermaid)

دليل المزوّدين

كل المزوّدين، إعداد YAML، أي بائع متوافق مع OpenAI، التسعير والمرونة وسير العمل بلا مفاتيح

الخطة الاستراتيجية

قياس حي مقابل LangChain/CrewAI/AutoGen/LangGraph، جاهزية الإنتاج، عيوب المنافسين وخارطة الصدارة

السياسات (Policy-as-Code)

version: 1
name: strict
defaults:
  budget_usd_per_day: 2.0
  max_tokens_per_request: 2048
models:
  deny: ["*opus*"]
privacy:
  redact: [email, phone, credit_card, iban, ssn]
tools:
  deny: ["shell*"]
rate_limit:
  requests_per_minute: 30
zyko ask "..." --policy strict    # كل نداء يمر عبر السياسة: سقف، حجب، سماح، تدقيق

تجربة فورية: zyko policy redact "card 4111 1111 1111 1111 mail bob@corp.com"

النواة الاختيارية (Rust)

النواة النقية Python تُغطي كل الوظائف. لمن يريد سرعة إضافية، rust/zyko-kernel (PyO3) تُسرّع الحسابات الساخنة بنفس الدلالات تمامًا (مضمونة باختبار تعادل مخصص)، وتُبنى اختياريًا:

pip install maturin && maturin develop --release -m rust/zyko-kernel/Cargo.toml
zyko info   # kernel backend: rust

الاختبارات والجودة

pip install -e .[dev]
pytest -q            # 579 اختبارًا: توجيه، سياسات، MCP (بعمليات فرعية حقيقية)، بوابة، وكلاء، مزوّدون (HTTP مُحاكى)، تصلّب CLI، وضع العرض، مخرجات منظمة، تتبّع
pytest --cov=src/zyko   # تغطية 98%
ruff check src tests && ruff format --check src tests
make security        # bandit + pip-audit (نفس بوابة CI)

يعمل CI على ubuntu/windows/macos × Python 3.11/3.12/3.13 + فحص Rust + تجربة دخان للـCLI + وظيفة أمان (bandit + pip-audit) — ويعمل أول تشغيل بلا أي مفاتيح عبر التراجع التلقائي لمزوّد العرض المدمج.

الأمان

  • حوكمة مدمجة: أدوات الخطر (shell) تبقى مقفلة ما لم تُسمّى صراحةً في tools.allow — حتى مع allow: ["*"]؛ خادم MCP يُطلق عبر exec لا عبر shell؛ http_get يرفض المخططات غير HTTP؛ حجب PII حتمي (بفحص Luhn).

  • بوابة أمان في CI: bandit (0 نتائج؛ استثناء shell=True المقصود موثّق داخليًا بـ nosec مُحكوم) + pip-audit على التبعيات المعلنة.

بلّغ ثغرة أمنية خاصًة عبر SECURITY.md — لا تفتح issue عامًا للثغرات.

الاقتباس العلمي

إذا استخدمت ZYKO في بحث، اقتبسها عبر CITATION.cff (يدعمها GitHub في زر «Cite this repository»).

خارطة الطريق

انظر الخطة الاستراتيجية — قياس حي مقابل المنافسين + جاهزية الإنتاج + خطة 18–24 شهرًا. التالي: نشر PyPI، مُصدّر OpenTelemetry اختياري، مصادقة متعددة المستخدمين للبوابة، أساسيات RAG، ووكلاء متعددون بحوكمة.

الترخيص

Apache-2.0 — راجع LICENSE.


ZYKO — Universal AI Orchestration Platform (English)

v0.8.0 · Multi-provider routing with verifiable decisions · Policy-as-Code governance · MCP-native agents · built-in tracing that exports anywhere · local RAG with zero dependencies · sequential multi-agent crews · governed multi-user gateway — running on Linux, Windows, macOS, Android and Termux with a pure-Python core (only httpx + PyYAML).

What's new in 0.8.0 — the receipt becomes verifiable: zyko verify

Until 0.7 the receipt was informative, not verifiable: a JSON document with the ranking, score components and weights, but nothing recomputed it. Now:

zyko ask "hello" --demo --receipt r.json   # every call can write its receipt
zyko verify r.json                         # full offline recomputation
zyko verify r.json --ledger ledger.json    # + cross-check quality vs the ledger
zyko verify r.json --json                  # machine-readable report

zyko verify recomputes every total from the recorded weights and components, checks the weights are exactly the published strategy weights, that every component lives in [0, 1], that the ranking is sorted, and that quality scores match the supplied quality ledger (including its ledger_updated stamp) — exiting 1 on any drift, so it drops straight into CI and monitoring.

A real bug the verifier found and this release fixes: cost normalisation always built its board range from the 800/400-token default while short requests were scored with their own estimate, so cost_score could exceed 1.0 (observed: 1.0441) and break the "all components live in [0, 1]" invariant the receipt advertises. The estimate now flows into the board snapshot, and the normalisers clamp to [0, 1] as defence in depth.

  • 14 new tests (tests/test_verify.py + a range-invariant regression test) — 579 tests passing.

  • Platform tests are now Termux-aware (they assumed Linux/Windows only).

What's new in 0.7.0 — governed multi-user gateway: identities, not just a token

A pre-broad-production roadmap item: until 0.6 the gateway knew exactly one bearer token. Now every caller is a named identity with its own key, roles, rate limit and daily budget, from a declarative users file. Verification is constant-time (hmac.compare_digest over every entry, no early exit — request timing never reveals which key matched); keys can be stored as stdlib scrypt records (zyko hash-key) so the file never holds a usable secret; governance is enforced per user, not just globally; and every response receipt carries the caller's identity:

# users.yaml
users:
  - name: alice
    key: zk-dev-only              # dev only
    roles: [chat]
    rpm: 60
  - name: ops
    key_hash: scrypt$16384$8$1$…$…   # from `zyko hash-key`
    roles: [chat, admin]
    daily_budget_usd: 5.0
zyko hash-key                          # prints a scrypt record (input hidden)
zyko serve --users users.yaml          # multi-user gateway
curl -H 'Authorization: Bearer op-secret' localhost:8787/v1/users/me
  • Per-user governance: 401 invalid token, 403 disabled user, 429 zyko_rate_limit when the user's RPM bucket is empty, 429 zyko_budget_exceeded when the daily budget is spent; every receipt carries "user", and daily usage (requests, tokens, estimated USD) is persisted per user and survives restarts.

  • GET /v1/users/me: a user inspects their own identity, today's usage and remaining budget — no key material ever leaves the store.

  • Typed fail-fast: duplicate names, unknown roles, bad rpm/budget or a missing key raise the new GatewayAuthError (a ConfigError) before the server binds — a broken users file never half-starts a gateway.

  • Legacy modes unchanged: single --api-key (now constant-time too) and the open gateway behave exactly as before; legacy receipts carry no "user" key.

  • 28 new tests — 565 tests passing, bandit zero, CI 14/14.

What's new in 0.6.0 — multi-agent crews: a sequential pipeline with shared context — CrewAI-parity in simplicity, stronger in governance

Roadmap step 4: ZYKO now coordinates a crew of agents. An ordered list of steps, each step one configured agent plus a task template that may reference the crew input ({task}), the previous step's output ({output}) or any earlier output_key. Formatting is safe by construction — unknown placeholders stay literal, substituted values are never re-formatted (JSON and braces survive round-trips), and templates are validated when a step is added, so malformed tasks fail fast instead of mid-run. Governance is stronger: no hidden prompts — every agent keeps its own system prompt, tools and policy; every step is a crew.step span under crew.run; the result is a full auditable receipt:

from zyko import Zyko

zk = Zyko()
crew = zk.crew("triage.yaml")  # declarative YAML: inline or file agents
res = crew.run("my invoice is late")
print(res.output)  # final agent's answer
print(res.outputs["class"])  # any declared step output
  • Safe shared-context templates: only three references — {task}, {output}, {output_key}; unknown keys stay literal; positional or malformed placeholders ({}, {0}) raise the new typed CrewError (exported from the zyko root) at add() time.

  • Declarative YAML: steps reference agent files or inline agent mappings; CLI: zyko crew crew.yaml --input "..." [--json|--trace] — --json prints ONLY the CrewResult JSON on stdout (clean machine contract).

  • Auditable receipt: CrewResult — output, outputs (insertion ordered), per-step records (agent, key, filled task, output, agent steps, truncated, elapsed), aggregated token usage, trace_id — visible in zyko traces and any OTLP backend.

  • Typed failures end-to-end: crew bugs raise CrewError; provider outages propagate as their real typed error (ProviderError) after the router's retry budget — never a bare string.

  • 34 new tests — 537 tests passing, bandit zero, CI 14/14.

Roadmap step 3: ZYKO now grounds answers in your own documents. A chunker, three embedders behind one contract, a local vector store whose persistence is a JSON file you own, and a context= parameter on ask. The default embedder is pure-stdlib feature hashing — deterministic, offline, phone-capable — so the whole story runs with zero keys, zero network, zero new dependencies; swap in Ollama (local, real semantics, no keys) or OpenAI embeddings when you want them:

from zyko import Zyko
from zyko.rag import HashingEmbedder, VectorStore

store = VectorStore(HashingEmbedder(), path="kb.json")
store.add(open("handbook.md").read(), meta={"source": "handbook"})
hits = store.search("refund policy", k=4)
answer = Zyko().ask("what is the refund policy?", context=[h.text for h in hits])
  • Three embedders, one contract: HashingEmbedder (blake2b feature hashing — deterministic across machines), OllamaEmbedder (nomic-embed-text locally, no keys), OpenAIEmbedder (text-embedding-3-small or any compatible endpoint).

  • VectorStore: in-memory cosine index, atomic save (tmp + replace) after every add, auto-load on construction; min_score=0.0 default keeps only positively-correlated chunks; aadd/asearch async mirrors.

  • Typed errors: every embeddings failure raises the new EmbedderError (exported from the zyko root) — never a raw httpx exception; dim mismatches are rejected instead of corrupting the index; an unreadable store file starts empty instead of crashing.

  • ask(prompt, context=[...]): non-empty context becomes its own grounding system message ("answer from the context; say so if insufficient") after any explicit system, before the user prompt — plain strings work too, the store is optional.

  • 26 new tests — 503 tests passing, bandit zero, CI 14/14.

What's new in 0.4.2 — the observability bridge: spans flow to Langfuse, Tempo, Jaeger or any OTLP backend — still zero new dependencies

Roadmap step 2 from docs/STRATEGY.md: your spans already lived on your disk (0.4.1); now they flow into the stack your team already runs. OtlpSink speaks OTLP/HTTP with JSON encoding — the OpenTelemetry Collector's standard wire protocol — over the httpx ZYKO already ships, so OTel Collector, Langfuse, Grafana Tempo, Jaeger, Honeycomb, New Relic and Datadog all work with zero new dependencies and zero vendor lock-in. One environment variable turns it on:

ZYKO_OTLP_ENDPOINT=http://localhost:4318/v1/traces zyko ask "hello"
  • Never slows the request path: write() enqueues and returns; one daemon worker batches up to 64 spans per POST; a full queue drops (and counts) rather than blocks.

  • Spec-exact deterministic ids: 16-byte trace / 8-byte span ids derived via sha256 from ZYKO's ids, parent links survive, originals ride as zyko.trace_id/zyko.span_id attributes — zyko traces --trace <id> stays lossless.

  • Langfuse recipe: endpoint https://cloud.langfuse.com/api/public/otel/v1/traces with authorization: "Basic ${LANGFUSE_BASIC}" — config files interpolate ${ENV_VARS} so the secret never lands on disk.

  • zyko doctor now shows tracing state and the OTLP target in an Observability section.

  • MCP determinism, finished: the last corner of the macOS/py3.11 race (0.3.7) — a server dying right after the initialize reply could blow up start() itself. Notifications are now fire-and-forget by contract (the reader loop stays the single source of truth; requests keep raising the same typed MCPError) — start() is deterministic on every OS, pinned by a regression test.

  • 14 new tests — 477 tests passing, bandit zero, CI 14/14.

What's new in 0.4.1 — built-in tracing: what others sell as a hosted service, ZYKO ships locally with zero dependencies

Observability was the biggest remaining feature gap versus the competition: LangChain sells it as LangSmith; Langfuse/AgentOps require an external SDK and a cloud account. ZYKO now traces every routed call with OpenTelemetry-style spans (trace/parent ids, durations, statuses, attributes) — zero new required dependencies, a JSONL file you own on your disk, and an inspection command in the same CLI:

from zyko import Zyko

zk = Zyko()
with zk.tracer.span("my-rag", corpus="support-docs"):  # your parent span
    zk.ask("why is my invoice late?")  # router span nests automatically
# later: zyko traces --last 20   |   --json   |   --trace <id>
  • zyko traces — a time table, --json always valid JSON (the cost/cache contract), --trace <id> for every span of one request, plus --clear and --file.

  • Tracing can never break a request: sink write failures degrade to one log line; an abandoned stream (client disconnect) still closes its span as cancelled.

  • Bounded rotation (live file + two .1/.2 backups) so a long-lived gateway can never fill the disk.

  • Disable with ZYKO_TRACING=0 or tracing.enabled: false — the same API, just no writes.

25 new tests (tests/test_observability.py) — 463 tests passing.

What's new in 0.4.0 — structured output: the most-competitive feature LangChain/CrewAI/AutoGen had and ZYKO didn't

A capability review against LangChain (with_structured_output), CrewAI (Pydantic task outputs), AutoGen (response_format) and LiteLLM (response_format passthrough) found the biggest remaining gap: schema-constrained answers. ZYKO now returns validated data or a typed error — never a raw string you must json.loads by hand — with an automatic repair round that feeds the exact validation errors back to the model. Zero new required dependencies; Pydantic is optional (zyko[structured]), not a requirement:

from zyko import Zyko

zk = Zyko()
out = zk.structured(
    "order 42 details?",
    schema={
        "type": "object",
        "properties": {
            "id": {"type": "integer"},
            "status": {"type": "string", "enum": ["open", "shipped"]},
        },
        "required": ["id", "status"],
    },
)
out.data  # {"id": 42, "status": "shipped"} — validated, or a typed StructuredOutputError
out.repaired  # did a repair round kick in?
  • Pure-Python JSON Schema validator: types, enum/const, numeric/string bounds, pattern, basic formats, nested arrays/objects, allOf/anyOf/oneOf, and local $ref/$defs resolution with cycle guards — what Pydantic schemas always need. Python's classic trap is caught: True is not an integer here.

  • Automatic repair: on failure the real errors (with paths like $.id) go back to the model for one configurable repair round (max_repairs), then a typed error carries errors + text.

  • Mess-proof extractor: survives surrounding prose, markdown fences and <think> blocks (DeepSeek style).

  • Optional native mode: native=True sends response_format: {"type": "json_schema", …} to vendors that support it (OpenAI, Groq, Mistral, DeepSeek, OpenRouter, Together, xAI); a vendor that rejects it just falls through routing.

  • Cross-provider support: Google maps it to generationConfig.responseMimeType (+ responseSchema); the OpenAI-compatible gateway accepts response_format and 400s non-objects.

  • Layer-safe: malformed schema → immediate SchemaSpecError (caller bug); model failure → StructuredOutputError; cache keys (basis v2) include response_format so a cached free-text answer is never served for a structured call.

63 new tests (tests/test_structured.py) — 438 tests passing.

What's new in 0.3.9 — response cache: the #1 gap versus the competition

A competitive-matrix review against LiteLLM and Portkey showed ZYKO already matched their retries, failover, breakers, budgets and PII governance — but shipped no response cache. It now ships behind one policy section, off by default:

# in your policy file (Policy-as-Code):
cache:
  enabled: true
  ttl_s: 300        # seconds an answer stays valid
  max_entries: 512  # LRU bound
  • Exact key: SHA-256 over the full outbound payload (provider, model, messages, temperature, tools) — a hit means the vendor would have answered the same thing.

  • Per-candidate keys: a cached openai/* answer is never served for a request that routed to anthropic/*.

  • Honest receipts: hits surface as cache-hit attempts and "cached": true — no vendor call, no budget charge, no health write.

  • Agent-safe: tool_calls responses are never stored; streaming bypasses the cache in v1.

  • Per-call control: metadata={"cache": "bypass"} skips it; "refresh" revalidates a single call.

  • Full visibility: zyko cache shows entries and hit rate (--json is always valid JSON); --clear empties it.

20 new tests — 375 tests passing.

What's new in 0.3.8 — +xAI (Grok) and +Together AI: ten registered providers

Two new OpenAI-compatible vendors on the same ~30-line subclass lever. Every catalog fact comes from each vendor's official documentation (slugs, context windows, list prices):

  • xai (XAI_API_KEY) — grok-4.7 (500k ctx, $2/$6), grok-4.3 (1M ctx, $1.25/$2.50), grok-build-0.1 (256k ctx, $1/$2).

  • together (TOGETHER_API_KEY) — Kimi-K3, GLM-5.3, GLM-5.3-Flash, DeepSeek-V4.1-Flash, gpt-oss-120b, Qwen3.5-9B — one key to a deep open-model catalog with contexts up to 1M tokens.

8 new tests (request shape, catalog integrity, key-env resolution) — 355 tests passing.

What's new in 0.3.7 — MCP dead-server race now fails typed, on every OS

Caught by the macOS/py3.11 CI leg after 0.3.6: when an MCP server dies between the client's write() and drain(), drain() used to leak a raw ConnectionResetError on some platforms instead of the documented MCPError. Both paths (_request, _notify) now behave identically and deterministically on Linux, macOS and Windows — one typed MCPError("closed the stream"), with the pending future cleaned up immediately (also removing the "Future exception was never retrieved" warning). 347 tests passing.

What's new in 0.3.6 — ruff 0.17 format compliance

Zero-impact hygiene round: ruff 0.17 changed formatting behaviour (and now formats Python code blocks inside Markdown too). Four files outside CI's current scope were normalized — README.md, docs/API.md, docs/PROVIDERS.md, examples/04_agent_tools.py — so a future scope extension or toolchain upgrade cannot break lint. Not a single line under src/ or tests/ changed — 347 tests passing as before, and ruff format --check . is now clean across the whole tree (97 files).

What's new in 0.3.5 — deep developer documentation

Three new reference documents, every signature taken verbatim from the code (nothing invented):

  • API reference — the Zyko client, the router and its receipt, all ten providers, PolicyEngine, the gateway, MCP in both directions, agents, settings & paths, the exception tree, the full CLI map.

  • Architecture — mermaid diagrams of the request lifecycle, why the receipt is verifiable by construction, measured (not claimed) quality, governance on every call, and cross-platform portability.

  • Providers guide — auto-discovery, YAML config, any OpenAI-compatible vendor, pricing that feeds routing, resilience (retries/breaker/fallbacks), and keyless workflows.

What's new in 0.3.4 — the real CI fix: green on all three platforms

The 0.3.3 round fixed the security gate locally — but CI on GitHub was still red with three real issues Linux alone could never catch:

  • bandit: unrecognized arguments: --exit-zero-on-skipped — the flag was removed in modern bandit; dropped from the CI command.

  • the Termux-marker test assumed sys.platform == linux — a com.termux PREFIX is now definitive on every OS (a production fix, not just a test patch).

  • the XDG test assumed Linux behaviour on macOS/Windows — it now pins the LINUX branch explicitly, like the macOS test does.

Result: green on Ubuntu + macOS + Windows × Python 3.11/3.12/3.13 with a security gate that actually runs.

What's new in 0.3.3 — the security gate that never worked

The 0.3.2 round added a CI security job — but it would have failed on its first real run: bandit does not read pyproject.toml at all (through 1.9.x), so the documented suppressions (B101/B311/B404) were silently ignored and 11 LOW findings surfaced. Fixed with a real .bandit.yml (justification comments included) consumed by both CI and make security; the misleading [tool.bandit] section is gone. Plus 10 new edge-path tests (347 total): gateway 500 mapping for unexpected router exceptions, lying Content-Length headers, mid-stream client disconnect (RST) with the worker staying healthy, the MCP server surfacing unexpected exceptions as isError without crashing the loop, the zyko_chat round-trip with a routing receipt, default_policy wiring, the python -m zyko.mcp.server entrypoint, degenerate cost/latency normalisation, and breaker/policy skips in astream_route. Coverage holds at 98% with uncovered lines down 84 → 69.

What's new in 0.3.2 — full evaluation round (coverage + lint + security)

A complete quality round across the whole codebase, every finding fixed and regression-tested:

  • Settings.load() leaked overrides into module-level defaults. _deep_merge shared nested dicts with the DEFAULTS constant, so the first load() with ZYKO_* env vars (or YAML values) permanently rewrote the defaults for the whole process — later calls inherited the first call's environment, contaminating long-lived gateway processes and unrelated tests. Defaults are now deep-copied per call.

  • policies_dir() / agents_dir(create=True) did not create the returned directory — only its parent. create=True now guarantees the leaf exists.

  • PolicyEngine crashed with a raw AttributeError on malformed policy sections (defaults/privacy/rate_limit/audit holding a non-mapping value) before the schema-warnings machinery could report them. Malformed sections now degrade to the documented warnings.

Round results: coverage 92% → 98% · tests 230 → 337 (107 new: full MCP client lifecycle, streaming governance with vendor-usage audit estimated: false, breaker/policy routing paths, platform detection, provider payload matrices, POSIX exit codes 130/141) · ruff check + ruff format clean across the tree · a security gate in CI (bandit 0 findings + pip-audit on declared deps) · install scripts restored to the repo root (zyko.sh, zyko.cmd, install.sh/install.bat/install.ps1, Makefile, Dockerfile).

What's new in 0.3.1 — CLI robustness + coverage round

A targeted audit ran every CLI command for real (demo mode) and hunted the failures tests alone cannot see:

  • zyko cost --json printed [INFO] text instead of JSON when no audit log existed — breaking every downstream consumer (| jq, CI steps). The empty-log branch now emits the exact report schema; the friendly [INFO] stays for human mode.

  • zyko serve on a busy port crashed with a raw OSError traceback → now a friendly [FAIL] cannot start gateway with an actionable hint.

  • zyko doctor | head printed a BrokenPipeError traceback → the CLI now exits quietly with code 141 (128 + SIGPIPE), like every well-behaved POSIX tool.

  • Windows hardening: legacy cp1252 consoles can no longer crash on em-dashes, · separators, or Arabic output (errors="replace" guard at startup).

Round results: coverage 89% → 92% (MCP protocol, kernel swap and agent tools at 95–100%) · tests 203 → 230 (new tests/test_hardening.py: calculator edges, workspace escapes, full HTTP error maps, MCP timings, Rust-kernel swap) · a security audit re-confirmed danger tools (shell) stay locked unless explicitly named in tools.allow — even under allow: ["*"].

Four differentiators

  1. Verifiable routing — every response carries a routing receipt: the full candidate ranking with score components (quality/cost/latency) and published weights. Replay any past decision offline.

  2. Honest quality scores — ledger scores come only from the reproducible benchmark (zyko bench, fixed seed, objective graders), never vendor marketing tables. No data yet → neutral 0.5 for everyone.

  3. Policy-as-Code — daily USD budget, deterministic PII redaction (email/phone/card/IBAN/SSN with Luhn), model & tool allowlists, rate limits, JSONL audit trail — one YAML enforced on every call.

  4. MCP-first — ZYKO consumes MCP servers as agent tools and exposes itself as one (zyko mcp serve).

Design lineage — patterns from the big projects

Adopted pattern

Source

Unified OpenAI-format adapters, exponential-backoff retries, Retry-After honoring

LiteLLM

Meta-provider provider/model naming, attribution headers

OpenRouter

Routing quality derived from reproducible benchmarks, not marketing tables

RouteLLM

Config-as-code gateway governance (budgets, allowlists, audit)

Portkey Gateway

An open protocol unifying agent tooling (client + server)

Model Context Protocol

ZYKO's edge is not reinvention but verifiability: routing receipts you can replay offline, an honest reproducible quality ledger, and governance enforced on every call — on every platform.

Quickstart

# Linux / macOS / Termux — instant runner (isolated venv on first use):
./zyko.sh ask "hello" --demo
# Windows: zyko.cmd ask "hello" --demo   ·   Docker: docker build -t zyko . && docker run -p 8787:8787 zyko

# Or install permanently:
pip install git+https://github.com/tibatechapp-ship-it/zyko.git

# Fastest first run — no keys, no network (deterministic demo mode):
zyko ask "hello zyko" --demo --explain
zyko bench --demo
zyko ask "hello" --demo --receipt r.json && zyko verify r.json   # verify a receipt offline

# Then with a real provider:
export OPENAI_API_KEY=sk-...        # or run Ollama locally for a keyless setup
zyko ask "Explain MCP in one line" --explain
zyko serve                          # OpenAI-compatible gateway on :8787
from zyko import Zyko

outcome = Zyko().ask("hello")
print(outcome.response.text, "←", outcome.receipt["chosen"])

Highlights

  • CLI: ask · chat · route (planning-only) · verify (offline receipt replay) · models · policy · run (agents) · sessions (inspect SQLite memory) · cost (spend & governance report) · serve · mcp · bench · doctor — argparse-only, zero CLI dependencies. --demo runs the whole stack offline through a deterministic mock provider (no keys, no network). Explicit --model provider/name pins are enforced by the router, not ignored.

  • Gateway: stdlib HTTP server, streaming SSE included, zyko.receipt embedded in responses and chunks.

  • Agents: ReAct loop, builtin tools (calculator/file/http/shell-guarded), MCP tools namespaced as server__tool, SQLite session memory, step/timeout/policy guards.

  • Providers: OpenAI · Anthropic · Google · Groq · Mistral · DeepSeek · OpenRouter · Together AI · xAI (Grok) · Ollama(local). Retries with backoff, circuit breakers, latency EWMA.

  • Android/Termux: one-command installer, offline models via Ollama, widget shortcut for the gateway, optional Kivy UI. Nothing compiles.

  • Rust kernel (optional): PyO3 accelerator with enforced Python-parity; graceful fallback everywhere.

Documentation

Document

Covers

API reference

every signature from the code: Zyko, Router, policies, gateway, MCP, agents, exceptions, CLI map

Architecture

request lifecycle, the verifiable receipt, layers and extension points (mermaid diagrams)

Providers guide

all vendors, YAML config, any OpenAI-compatible endpoint, pricing & resilience, keyless workflows

Strategy

live benchmark vs LangChain/CrewAI/AutoGen/LangGraph, production-readiness audit, competitor weaknesses, roadmap to the top

Tests

pytest -q → 579 tests (98% coverage) covering routing (incl. snapshot/parity and explicit model pinning), policy (incl. schema warnings and malformed-document degradation), structured output (validation + repair + native mode), built-in tracing (spans, sinks, rotation, router + CLI integration), MCP over real subprocesses plus in-memory server frames and the full client lifecycle (timeouts, server errors, pagination, closed streams), the gateway over a real HTTP socket (auth + keep-alive integrity + 502 upstream errors), agents, every provider adapter against canned HTTP, session memory, the audit-based cost report, streaming cost accounting, Retry-After resilience, CLI robustness (broken pipes, busy ports, JSON-only --json), tool-loop failure modes, and the keyless demo mode. CI runs the matrix on Linux/Windows/macOS + Python 3.11/3.12/3.13, plus lint (ruff check + ruff format --check), a security job (bandit + pip-audit), and a Rust kernel check.

Security

  • Built-in governance: danger tools (shell) stay locked unless explicitly named in tools.allow — even under allow: ["*"]; the MCP client spawns servers via exec, never a shell; http_get rejects non-HTTP schemes; deterministic PII redaction with Luhn validation.

  • CI security gate: bandit -c .bandit.yml -r src/zyko (0 findings; the intentional, policy-gated shell=True is documented inline with a scoped # nosec) and pip-audit --skip-editable over the declared dependency surface (httpx, PyYAML — clean at release time).

Report a vulnerability privately via SECURITY.md — please do not open public issues for security reports.

License

Apache-2.0 — see LICENSE.


🚀 ملاحظة: تم إضافة هذا السطر مباشرة من Termux عبر GitHub API بدون تحميل المشروع.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    B
    maintenance
    A production-ready MCP gateway and control plane that provides credential vault, policy engine, audit logging, and managed runtime for routing tool calls between AI agents and downstream MCP servers.
    59
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Governed MCP gateway that lets AI agents call tools with policy enforcement, prompt-injection screening, a kill-switch, and tamper-evident signed audit logs.
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables developers to wrap existing MCP servers with a deterministic policy enforcement gate that intercepts tool discovery and tools/call requests over stdio, allowing only authorized calls to reach the downstream server. It supports dynamic tool exposure or hiding, allow/deny/approval-required decisions, configurable error disclosure modes, and Ed25519-signed retry credentials for approved workflows.
    Apache 2.0
  • F
    license
    A
    quality
    C
    maintenance
    An MCP server that exposes governance, trust-scoring, compliance, guardrail, cost, drift, and supply-chain scanning tools and resources to any MCP client over stdio, Streamable HTTP, or legacy HTTP+SSE. It lets agents route every tool call through a deterministic five-way decision (allow, redact, require approval, deny, or quarantine) with hash-chained evidence, human approval workflows, and in-agent trust gates for LangChain, LangGraph, and Google ADK.
    30
    -