Skip to content

אחסון

כל הנתונים בעלי מצב ב-Triggerfish זורמים דרך הפשטת StorageProvider מאוחדת. אף מודול לא יוצר מנגנון אחסון משלו -- כל רכיב שצריך התמדה מקבל StorageProvider כתלות. עיצוב זה מאפשר החלפת תשתיות ללא נגיעה בלוגיקה עסקית ושומר על כל הבדיקות מהירות ודטרמיניסטיות.

ממשק StorageProvider

typescript
interface StorageProvider {
  /** אחזור ערך לפי מפתח. מחזיר null אם לא נמצא. */
  get(key: string): Promise<StorageValue | null>;

  /** אחסון ערך במפתח. דורס כל ערך קיים. */
  set(key: string, value: StorageValue): Promise<void>;

  /** מחיקת מפתח. ללא פעולה אם המפתח לא קיים. */
  delete(key: string): Promise<void>;

  /** רישום כל המפתחות התואמים לקידומת אופציונלית. */
  list(prefix?: string): Promise<string[]>;

  /** מחיקת כל המפתחות. השתמשו בזהירות. */
  clear(): Promise<void>;
}

StorageValue הוא מחרוזת. כל הנתונים המובנים (סשנים, רשומות שושלת,

הגדרות) מומרים ל-JSON לפני אחסון ומומרים חזרה בקריאה. זה שומר על הממשק פשוט ובלתי תלוי בתשתית. :::

מימושים

תשתיתשימושהתמדההגדרה
MemoryStorageProviderבדיקות, סשנים זמנייםללא (אובדת בהפעלה מחדש)ללא צורך בהגדרה
SqliteStorageProviderברירת מחדל לרמה אישיתSQLite WAL ב-~/.triggerfish/data/triggerfish.dbללא הגדרה
תשתיות ארגוניותרמה ארגוניתמנוהלות לקוחPostgres, S3 או תשתיות אחרות

MemoryStorageProvider

משמש בכל הבדיקות למהירות ודטרמיניסטיות. נתונים קיימים רק בזיכרון ואובדים כאשר התהליך מסתיים. כל סדרת בדיקות יוצרת MemoryStorageProvider טרי, מה שמבטיח שבדיקות מבודדות וניתנות לשחזור.

SqliteStorageProvider

ברירת המחדל לפריסות ברמה אישית. משתמש ב-SQLite במצב WAL (Write-Ahead Logging) לגישת קריאה מקבילית ובטיחות קריסה. מסד הנתונים נמצא ב:

~/.triggerfish/data/triggerfish.db

SQLite לא דורש הגדרה, לא תהליך שרת ולא רשת. קובץ בודד מאחסן את כל מצב Triggerfish. חבילת Deno @db/sqlite מספקת את החיבור, שדורש הרשאת --allow-ffi.

מצב SQLite WAL מאפשר לקוראים מרובים לגשת למסד הנתונים בו-זמנית עם כותב

בודד. זה חשוב ל-Gateway, שעשוי לקרוא מצב סשן בזמן שהסוכן כותב תוצאות כלים. :::

תשתיות ארגוניות

פריסות ארגוניות יכולות לחבר תשתיות אחסון חיצוניות (Postgres, S3 וכו') ללא שינויי קוד. כל מימוש של ממשק StorageProvider עובד. התשתית מוגדרת ב-triggerfish.yaml.

מפתחות עם מרחבי שמות

כל המפתחות במערכת האחסון מוצמדים עם קידומת שמזהה את סוג הנתונים. זה מונע התנגשויות ומאפשר שאילתה, שמירה ומחיקה של נתונים לפי קטגוריה.

מרחב שמותדפוס מפתחתיאור
sessions:sessions:sess_abc123מצב סשן (היסטוריית שיחה, מטא-נתונים)
taint:taint:sess_abc123רמת Taint של סשן
lineage:lineage:lin_789xyzרשומות שושלת נתונים (מעקב מקור)
audit:audit:2025-01-29T10:23:45Z:hook_pre_outputרשומות יומן ביקורת
cron:cron:job_daily_reportמצב משימות Cron והיסטוריית הרצות
notifications:notifications:notif_456תור התראות
exec:exec:run_789היסטוריית סביבת הרצת סוכן
skills:skills:skill_weatherמטא-נתונים של Skills מותקנים
config:config:v3תמונות הגדרות

מדיניות שמירה

לכל מרחב שמות יש מדיניות שמירה כברירת מחדל. פריסות ארגוניות יכולות להתאים אלו.

מרחב שמותשמירה בברירת מחדלנימוק
sessions:30 ימיםהיסטוריית שיחה מתיישנת
taint:תואם לשמירת סשןTaint חסר משמעות ללא הסשן שלו
lineage:90 ימיםמונע ציות, נתיב ביקורת
audit:שנהמונע ציות, משפטי ורגולטורי
cron:30 ימיםהיסטוריית הרצות לניפוי באגים
notifications:עד מסירה + 7 ימיםהתראות שלא נמסרו חייבות להתמיד
exec:30 ימיםארטיפקטי הרצה לניפוי באגים
skills:קבועמטא-נתונים של Skills מותקנים לא צריכים לפוג
config:10 גרסאותהיסטוריית הגדרות מתגלגלת לשחזור

עקרונות תכנון

כל המודולים משתמשים ב-StorageProvider

אף מודול ב-Triggerfish לא יוצר מנגנון אחסון משלו. ניהול סשנים, מעקב Taint, רישום שושלת, רישום ביקורת, מצב Cron, תורי התראות, היסטוריית הרצות והגדרות -- הכול זורם דרך StorageProvider.

משמעות הדבר:

  • החלפת תשתיות דורשת שינוי בנקודת הזרקת תלות אחת
  • בדיקות משתמשות ב-MemoryStorageProvider למהירות -- ללא הגדרת SQLite, ללא מערכת קבצים
  • יש מקום אחד בדיוק למימוש הצפנה בהתמדה, גיבוי או שכפול

סריאליזציה

כל הנתונים המובנים מומרים למחרוזות JSON לפני אחסון. שכבת הסריאליזציה/דה-סריאליזציה מטפלת ב:

  • אובייקטי Date (מומרים למחרוזות ISO 8601 דרך toISOString(), מפוענחים דרך new Date())
  • טיפוסים ממותגים (מומרים כערך המחרוזת הבסיסי שלהם)
  • אובייקטים ומערכים מקוננים
typescript
// אחסון סשן
const session = {
  id: "sess_abc",
  taint: "CONFIDENTIAL",
  createdAt: new Date(),
};
await storage.set("sessions:sess_abc", JSON.stringify(session));

// אחזור סשן
const raw = await storage.get("sessions:sess_abc");
if (raw) {
  const session = JSON.parse(raw);
  session.createdAt = new Date(session.createdAt); // שחזור Date
}

אי-שינוי

פעולות סשן הן בלתי ניתנות לשינוי. קריאת סשן, שינויו וכתיבתו מחדש תמיד מייצרים אובייקט חדש. פונקציות לעולם לא משנות את האובייקט המאוחסן במקום. זה עולה בקנה אחד עם העיקרון הרחב של Triggerfish שפונקציות מחזירות אובייקטים חדשים ולעולם לא משנות.

מבנה תיקיות

~/.triggerfish/
  config/          # הגדרות סוכן, SPINE.md, TRIGGER.md
  data/            # triggerfish.db (SQLite)
  workspace/       # סביבת הרצת סוכן
    <agent-id>/    # סביבת עבודה לכל סוכן (מתמידה)
    background/    # סביבות עבודה של סשני רקע
  skills/          # Skills מותקנים
  logs/            # יומני ביקורת
  secrets/         # מאגר פרטי הזדהות מוצפנים

אבטחה תיקיית secrets/ מכילה פרטי הזדהות מוצפנים המנוהלים על ידי

אינטגרציית ה-OS keychain. לעולם אל תאחסנו סודות בקבצי הגדרות או ב-StorageProvider. השתמשו ב-OS keychain (רמה אישית) או אינטגרציית vault (רמה ארגונית). :::