אחסון
כל הנתונים בעלי מצב ב-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.dbSQLite לא דורש הגדרה, לא תהליך שרת ולא רשת. קובץ בודד מאחסן את כל מצב 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 (רמה ארגונית). :::
