@portel/photon-core 2.6.0 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audit.d.ts +150 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +364 -0
- package/dist/audit.js.map +1 -0
- package/dist/base.d.ts +60 -0
- package/dist/base.d.ts.map +1 -1
- package/dist/base.js +81 -0
- package/dist/base.js.map +1 -1
- package/dist/design-system/tokens.d.ts +18 -10
- package/dist/design-system/tokens.d.ts.map +1 -1
- package/dist/design-system/tokens.js +53 -19
- package/dist/design-system/tokens.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/memory.d.ts +100 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +213 -0
- package/dist/memory.js.map +1 -0
- package/dist/schema-extractor.d.ts +5 -0
- package/dist/schema-extractor.d.ts.map +1 -1
- package/dist/schema-extractor.js +10 -1
- package/dist/schema-extractor.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
- package/src/audit.ts +446 -0
- package/src/base.ts +93 -0
- package/src/design-system/tokens.ts +56 -20
- package/src/index.ts +18 -0
- package/src/memory.ts +241 -0
- package/src/schema-extractor.ts +11 -1
- package/src/types.ts +2 -0
package/dist/audit.d.ts
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Execution Audit Trail
|
|
3
|
+
*
|
|
4
|
+
* Automatic observability for photon tool executions.
|
|
5
|
+
* Records every tool call with input, output, timing, and errors
|
|
6
|
+
* in append-only JSONL files at ~/.photon/logs/{photonId}/executions.jsonl
|
|
7
|
+
*
|
|
8
|
+
* Zero effort for developers — the runtime records everything.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* // Query via API
|
|
13
|
+
* const audit = new AuditTrail();
|
|
14
|
+
* const recent = await audit.query('todo-list'); // last 20
|
|
15
|
+
* const adds = await audit.query('todo-list', { method: 'add' }); // filter by method
|
|
16
|
+
* const entry = await audit.get('exec_abc123'); // single execution
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* A single execution record
|
|
21
|
+
*/
|
|
22
|
+
export interface ExecutionRecord {
|
|
23
|
+
/** Unique execution ID */
|
|
24
|
+
id: string;
|
|
25
|
+
/** Photon name (kebab-case) */
|
|
26
|
+
photon: string;
|
|
27
|
+
/** Method/tool name that was called */
|
|
28
|
+
method: string;
|
|
29
|
+
/** Input parameters */
|
|
30
|
+
input: Record<string, any>;
|
|
31
|
+
/** Output result (null if error) */
|
|
32
|
+
output: any;
|
|
33
|
+
/** Execution duration in milliseconds */
|
|
34
|
+
duration_ms: number;
|
|
35
|
+
/** ISO 8601 timestamp */
|
|
36
|
+
timestamp: string;
|
|
37
|
+
/** Parent execution ID (for cross-photon calls) */
|
|
38
|
+
parent_id: string | null;
|
|
39
|
+
/** Error message (null if success) */
|
|
40
|
+
error: string | null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Query options for filtering execution history
|
|
44
|
+
*/
|
|
45
|
+
export interface AuditQueryOptions {
|
|
46
|
+
/** Filter by method name */
|
|
47
|
+
method?: string;
|
|
48
|
+
/** Maximum number of results (default: 20) */
|
|
49
|
+
limit?: number;
|
|
50
|
+
/** Only return executions after this ISO timestamp */
|
|
51
|
+
after?: string;
|
|
52
|
+
/** Only return executions before this ISO timestamp */
|
|
53
|
+
before?: string;
|
|
54
|
+
/** Only return failed executions */
|
|
55
|
+
errorsOnly?: boolean;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Generate a unique execution ID
|
|
59
|
+
*/
|
|
60
|
+
export declare function generateExecutionId(): string;
|
|
61
|
+
/**
|
|
62
|
+
* Execution Audit Trail
|
|
63
|
+
*
|
|
64
|
+
* Records and queries photon tool executions.
|
|
65
|
+
* Append-only JSONL storage for reliability.
|
|
66
|
+
*/
|
|
67
|
+
export declare class AuditTrail {
|
|
68
|
+
/** Write counter for auto-prune scheduling */
|
|
69
|
+
private _writeCount;
|
|
70
|
+
/** How often to auto-prune (every N writes) */
|
|
71
|
+
private _pruneInterval;
|
|
72
|
+
/**
|
|
73
|
+
* Record a tool execution
|
|
74
|
+
*
|
|
75
|
+
* Called by the runtime before/after every tool call.
|
|
76
|
+
* Uses append to avoid read-modify-write races.
|
|
77
|
+
* Auto-prunes records older than 30 days every 100 writes.
|
|
78
|
+
*/
|
|
79
|
+
record(entry: ExecutionRecord): void;
|
|
80
|
+
/**
|
|
81
|
+
* Start an execution — returns a finish function
|
|
82
|
+
*
|
|
83
|
+
* Convenience method for the runtime to wrap around tool calls:
|
|
84
|
+
* ```typescript
|
|
85
|
+
* const finish = audit.start('todo-list', 'add', { text: 'Buy milk' });
|
|
86
|
+
* try {
|
|
87
|
+
* const result = await executeTool(...);
|
|
88
|
+
* finish(result);
|
|
89
|
+
* } catch (err) {
|
|
90
|
+
* finish(null, err);
|
|
91
|
+
* }
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
start(photon: string, method: string, input: Record<string, any>, parentId?: string): {
|
|
95
|
+
id: string;
|
|
96
|
+
finish: (output: any, error?: Error | string | null) => ExecutionRecord;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Query execution history for a photon
|
|
100
|
+
*/
|
|
101
|
+
query(photonId: string, options?: AuditQueryOptions): Promise<ExecutionRecord[]>;
|
|
102
|
+
/**
|
|
103
|
+
* Get a single execution by ID
|
|
104
|
+
*/
|
|
105
|
+
get(executionId: string, photonId?: string): Promise<ExecutionRecord | null>;
|
|
106
|
+
/**
|
|
107
|
+
* Get execution trace — an execution and all its children
|
|
108
|
+
*/
|
|
109
|
+
trace(executionId: string): Promise<ExecutionRecord[]>;
|
|
110
|
+
/**
|
|
111
|
+
* List all photons that have execution logs
|
|
112
|
+
*/
|
|
113
|
+
listPhotons(): string[];
|
|
114
|
+
/**
|
|
115
|
+
* Prune records older than retention period
|
|
116
|
+
*
|
|
117
|
+
* Rewrites log files keeping only records within the retention window.
|
|
118
|
+
* Called automatically on every 100th record() call, or manually.
|
|
119
|
+
*
|
|
120
|
+
* @param retentionMs Max age in ms (default: 30 days)
|
|
121
|
+
* @param photonId Prune a specific photon, or all if omitted
|
|
122
|
+
* @returns Number of records removed
|
|
123
|
+
*/
|
|
124
|
+
prune(retentionMs?: number, photonId?: string): number;
|
|
125
|
+
/**
|
|
126
|
+
* Clear execution logs for a photon (or all)
|
|
127
|
+
*/
|
|
128
|
+
clear(photonId?: string): void;
|
|
129
|
+
/**
|
|
130
|
+
* Sanitize input to avoid logging sensitive data
|
|
131
|
+
*/
|
|
132
|
+
private sanitizeInput;
|
|
133
|
+
/**
|
|
134
|
+
* Truncate large outputs to keep log files manageable
|
|
135
|
+
*/
|
|
136
|
+
private truncateOutput;
|
|
137
|
+
/**
|
|
138
|
+
* Find a record by ID in a specific log file
|
|
139
|
+
*/
|
|
140
|
+
private findInLog;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Get the default audit trail instance
|
|
144
|
+
*/
|
|
145
|
+
export declare function getAuditTrail(): AuditTrail;
|
|
146
|
+
/**
|
|
147
|
+
* Set a custom audit trail (for testing or custom storage)
|
|
148
|
+
*/
|
|
149
|
+
export declare function setAuditTrail(trail: AuditTrail): void;
|
|
150
|
+
//# sourceMappingURL=audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAOH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,oCAAoC;IACpC,MAAM,EAAE,GAAG,CAAC;IACZ,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,sCAAsC;IACtC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,4BAA4B;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAKD;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAkBD;;;;;GAKG;AACH,qBAAa,UAAU;IACrB,8CAA8C;IAC9C,OAAO,CAAC,WAAW,CAAK;IAExB,+CAA+C;IAC/C,OAAO,CAAC,cAAc,CAAO;IAE7B;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAuBpC;;;;;;;;;;;;;OAaG;IACH,KAAK,CACH,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,QAAQ,CAAC,EAAE,MAAM,GAChB;QACD,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,IAAI,KAAK,eAAe,CAAC;KACzE;IA6BD;;OAEG;IACG,KAAK,CACT,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,eAAe,EAAE,CAAC;IAkC7B;;OAEG;IACG,GAAG,CACP,WAAW,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAsBlC;;OAEG;IACG,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAqC5D;;OAEG;IACH,WAAW,IAAI,MAAM,EAAE;IAUvB;;;;;;;;;OASG;IACH,KAAK,CAAC,WAAW,GAAE,MAA6B,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM;IAyC5E;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAgB9B;;OAEG;IACH,OAAO,CAAC,aAAa;IAarB;;OAEG;IACH,OAAO,CAAC,cAAc;IAUtB;;OAEG;IACH,OAAO,CAAC,SAAS;CAkBlB;AAKD;;GAEG;AACH,wBAAgB,aAAa,IAAI,UAAU,CAK1C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAErD"}
|
package/dist/audit.js
ADDED
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Execution Audit Trail
|
|
3
|
+
*
|
|
4
|
+
* Automatic observability for photon tool executions.
|
|
5
|
+
* Records every tool call with input, output, timing, and errors
|
|
6
|
+
* in append-only JSONL files at ~/.photon/logs/{photonId}/executions.jsonl
|
|
7
|
+
*
|
|
8
|
+
* Zero effort for developers — the runtime records everything.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* // Query via API
|
|
13
|
+
* const audit = new AuditTrail();
|
|
14
|
+
* const recent = await audit.query('todo-list'); // last 20
|
|
15
|
+
* const adds = await audit.query('todo-list', { method: 'add' }); // filter by method
|
|
16
|
+
* const entry = await audit.get('exec_abc123'); // single execution
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
import * as fs from 'fs';
|
|
20
|
+
import * as path from 'path';
|
|
21
|
+
import * as os from 'os';
|
|
22
|
+
import * as crypto from 'crypto';
|
|
23
|
+
/** Default retention period: 30 days in milliseconds */
|
|
24
|
+
const DEFAULT_RETENTION_MS = 30 * 24 * 60 * 60 * 1000;
|
|
25
|
+
/**
|
|
26
|
+
* Generate a unique execution ID
|
|
27
|
+
*/
|
|
28
|
+
export function generateExecutionId() {
|
|
29
|
+
return `exec_${crypto.randomBytes(8).toString('hex')}`;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get the logs directory for a photon
|
|
33
|
+
*/
|
|
34
|
+
function getLogDir(photonId) {
|
|
35
|
+
const safeName = photonId.replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
36
|
+
const baseDir = process.env.PHOTON_LOG_DIR || path.join(os.homedir(), '.photon', 'logs');
|
|
37
|
+
return path.join(baseDir, safeName);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get the executions log file path
|
|
41
|
+
*/
|
|
42
|
+
function getLogPath(photonId) {
|
|
43
|
+
return path.join(getLogDir(photonId), 'executions.jsonl');
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Execution Audit Trail
|
|
47
|
+
*
|
|
48
|
+
* Records and queries photon tool executions.
|
|
49
|
+
* Append-only JSONL storage for reliability.
|
|
50
|
+
*/
|
|
51
|
+
export class AuditTrail {
|
|
52
|
+
/** Write counter for auto-prune scheduling */
|
|
53
|
+
_writeCount = 0;
|
|
54
|
+
/** How often to auto-prune (every N writes) */
|
|
55
|
+
_pruneInterval = 100;
|
|
56
|
+
/**
|
|
57
|
+
* Record a tool execution
|
|
58
|
+
*
|
|
59
|
+
* Called by the runtime before/after every tool call.
|
|
60
|
+
* Uses append to avoid read-modify-write races.
|
|
61
|
+
* Auto-prunes records older than 30 days every 100 writes.
|
|
62
|
+
*/
|
|
63
|
+
record(entry) {
|
|
64
|
+
const logPath = getLogPath(entry.photon);
|
|
65
|
+
const logDir = path.dirname(logPath);
|
|
66
|
+
if (!fs.existsSync(logDir)) {
|
|
67
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
68
|
+
}
|
|
69
|
+
const line = JSON.stringify(entry) + '\n';
|
|
70
|
+
fs.appendFileSync(logPath, line);
|
|
71
|
+
// Auto-prune on schedule (non-blocking, best-effort)
|
|
72
|
+
this._writeCount++;
|
|
73
|
+
if (this._writeCount >= this._pruneInterval) {
|
|
74
|
+
this._writeCount = 0;
|
|
75
|
+
try {
|
|
76
|
+
this.prune(DEFAULT_RETENTION_MS, entry.photon);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// Prune is best-effort — never fail a record() because of it
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Start an execution — returns a finish function
|
|
85
|
+
*
|
|
86
|
+
* Convenience method for the runtime to wrap around tool calls:
|
|
87
|
+
* ```typescript
|
|
88
|
+
* const finish = audit.start('todo-list', 'add', { text: 'Buy milk' });
|
|
89
|
+
* try {
|
|
90
|
+
* const result = await executeTool(...);
|
|
91
|
+
* finish(result);
|
|
92
|
+
* } catch (err) {
|
|
93
|
+
* finish(null, err);
|
|
94
|
+
* }
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
start(photon, method, input, parentId) {
|
|
98
|
+
const id = generateExecutionId();
|
|
99
|
+
const startTime = Date.now();
|
|
100
|
+
const timestamp = new Date().toISOString();
|
|
101
|
+
return {
|
|
102
|
+
id,
|
|
103
|
+
finish: (output, error) => {
|
|
104
|
+
const entry = {
|
|
105
|
+
id,
|
|
106
|
+
photon,
|
|
107
|
+
method,
|
|
108
|
+
input: this.sanitizeInput(input),
|
|
109
|
+
output: error ? null : this.truncateOutput(output),
|
|
110
|
+
duration_ms: Date.now() - startTime,
|
|
111
|
+
timestamp,
|
|
112
|
+
parent_id: parentId || null,
|
|
113
|
+
error: error
|
|
114
|
+
? typeof error === 'string'
|
|
115
|
+
? error
|
|
116
|
+
: error.message
|
|
117
|
+
: null,
|
|
118
|
+
};
|
|
119
|
+
this.record(entry);
|
|
120
|
+
return entry;
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Query execution history for a photon
|
|
126
|
+
*/
|
|
127
|
+
async query(photonId, options = {}) {
|
|
128
|
+
const logPath = getLogPath(photonId);
|
|
129
|
+
const limit = options.limit ?? 20;
|
|
130
|
+
if (!fs.existsSync(logPath)) {
|
|
131
|
+
return [];
|
|
132
|
+
}
|
|
133
|
+
const content = fs.readFileSync(logPath, 'utf-8');
|
|
134
|
+
const lines = content.trim().split('\n').filter(Boolean);
|
|
135
|
+
// Parse all records (bottom-up for most recent first)
|
|
136
|
+
let records = [];
|
|
137
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
138
|
+
try {
|
|
139
|
+
const record = JSON.parse(lines[i]);
|
|
140
|
+
// Apply filters
|
|
141
|
+
if (options.method && record.method !== options.method)
|
|
142
|
+
continue;
|
|
143
|
+
if (options.errorsOnly && !record.error)
|
|
144
|
+
continue;
|
|
145
|
+
if (options.after && record.timestamp < options.after)
|
|
146
|
+
continue;
|
|
147
|
+
if (options.before && record.timestamp > options.before)
|
|
148
|
+
continue;
|
|
149
|
+
records.push(record);
|
|
150
|
+
if (records.length >= limit)
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
// Skip malformed lines
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return records;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Get a single execution by ID
|
|
161
|
+
*/
|
|
162
|
+
async get(executionId, photonId) {
|
|
163
|
+
// If photonId provided, search only that photon's log
|
|
164
|
+
if (photonId) {
|
|
165
|
+
return this.findInLog(getLogPath(photonId), executionId);
|
|
166
|
+
}
|
|
167
|
+
// Otherwise, search all photon logs
|
|
168
|
+
const baseDir = process.env.PHOTON_LOG_DIR || path.join(os.homedir(), '.photon', 'logs');
|
|
169
|
+
if (!fs.existsSync(baseDir))
|
|
170
|
+
return null;
|
|
171
|
+
const dirs = fs.readdirSync(baseDir, { withFileTypes: true })
|
|
172
|
+
.filter(d => d.isDirectory())
|
|
173
|
+
.map(d => d.name);
|
|
174
|
+
for (const dir of dirs) {
|
|
175
|
+
const found = this.findInLog(path.join(baseDir, dir, 'executions.jsonl'), executionId);
|
|
176
|
+
if (found)
|
|
177
|
+
return found;
|
|
178
|
+
}
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Get execution trace — an execution and all its children
|
|
183
|
+
*/
|
|
184
|
+
async trace(executionId) {
|
|
185
|
+
const root = await this.get(executionId);
|
|
186
|
+
if (!root)
|
|
187
|
+
return [];
|
|
188
|
+
const result = [root];
|
|
189
|
+
// Find all children across all photon logs
|
|
190
|
+
const baseDir = process.env.PHOTON_LOG_DIR || path.join(os.homedir(), '.photon', 'logs');
|
|
191
|
+
if (!fs.existsSync(baseDir))
|
|
192
|
+
return result;
|
|
193
|
+
const dirs = fs.readdirSync(baseDir, { withFileTypes: true })
|
|
194
|
+
.filter(d => d.isDirectory())
|
|
195
|
+
.map(d => d.name);
|
|
196
|
+
for (const dir of dirs) {
|
|
197
|
+
const logPath = path.join(baseDir, dir, 'executions.jsonl');
|
|
198
|
+
if (!fs.existsSync(logPath))
|
|
199
|
+
continue;
|
|
200
|
+
const content = fs.readFileSync(logPath, 'utf-8');
|
|
201
|
+
const lines = content.trim().split('\n').filter(Boolean);
|
|
202
|
+
for (const line of lines) {
|
|
203
|
+
try {
|
|
204
|
+
const record = JSON.parse(line);
|
|
205
|
+
if (record.parent_id === executionId) {
|
|
206
|
+
result.push(record);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
// Skip
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
// Sort by timestamp
|
|
215
|
+
return result.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* List all photons that have execution logs
|
|
219
|
+
*/
|
|
220
|
+
listPhotons() {
|
|
221
|
+
const baseDir = process.env.PHOTON_LOG_DIR || path.join(os.homedir(), '.photon', 'logs');
|
|
222
|
+
if (!fs.existsSync(baseDir))
|
|
223
|
+
return [];
|
|
224
|
+
return fs.readdirSync(baseDir, { withFileTypes: true })
|
|
225
|
+
.filter(d => d.isDirectory())
|
|
226
|
+
.filter(d => fs.existsSync(path.join(baseDir, d.name, 'executions.jsonl')))
|
|
227
|
+
.map(d => d.name);
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Prune records older than retention period
|
|
231
|
+
*
|
|
232
|
+
* Rewrites log files keeping only records within the retention window.
|
|
233
|
+
* Called automatically on every 100th record() call, or manually.
|
|
234
|
+
*
|
|
235
|
+
* @param retentionMs Max age in ms (default: 30 days)
|
|
236
|
+
* @param photonId Prune a specific photon, or all if omitted
|
|
237
|
+
* @returns Number of records removed
|
|
238
|
+
*/
|
|
239
|
+
prune(retentionMs = DEFAULT_RETENTION_MS, photonId) {
|
|
240
|
+
const cutoff = new Date(Date.now() - retentionMs).toISOString();
|
|
241
|
+
let totalRemoved = 0;
|
|
242
|
+
const photons = photonId ? [photonId] : this.listPhotons();
|
|
243
|
+
for (const id of photons) {
|
|
244
|
+
const logPath = getLogPath(id);
|
|
245
|
+
if (!fs.existsSync(logPath))
|
|
246
|
+
continue;
|
|
247
|
+
const content = fs.readFileSync(logPath, 'utf-8');
|
|
248
|
+
const lines = content.trim().split('\n').filter(Boolean);
|
|
249
|
+
const kept = [];
|
|
250
|
+
for (const line of lines) {
|
|
251
|
+
try {
|
|
252
|
+
const record = JSON.parse(line);
|
|
253
|
+
if (record.timestamp >= cutoff) {
|
|
254
|
+
kept.push(line);
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
totalRemoved++;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
catch {
|
|
261
|
+
// Drop malformed lines during prune
|
|
262
|
+
totalRemoved++;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
if (kept.length === 0) {
|
|
266
|
+
// Remove empty log file and directory
|
|
267
|
+
fs.unlinkSync(logPath);
|
|
268
|
+
const dir = path.dirname(logPath);
|
|
269
|
+
try {
|
|
270
|
+
fs.rmdirSync(dir);
|
|
271
|
+
}
|
|
272
|
+
catch { /* not empty, fine */ }
|
|
273
|
+
}
|
|
274
|
+
else if (kept.length < lines.length) {
|
|
275
|
+
fs.writeFileSync(logPath, kept.join('\n') + '\n');
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return totalRemoved;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Clear execution logs for a photon (or all)
|
|
282
|
+
*/
|
|
283
|
+
clear(photonId) {
|
|
284
|
+
if (photonId) {
|
|
285
|
+
const logPath = getLogPath(photonId);
|
|
286
|
+
if (fs.existsSync(logPath)) {
|
|
287
|
+
fs.unlinkSync(logPath);
|
|
288
|
+
}
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
// Clear all
|
|
292
|
+
const baseDir = process.env.PHOTON_LOG_DIR || path.join(os.homedir(), '.photon', 'logs');
|
|
293
|
+
if (fs.existsSync(baseDir)) {
|
|
294
|
+
fs.rmSync(baseDir, { recursive: true, force: true });
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Sanitize input to avoid logging sensitive data
|
|
299
|
+
*/
|
|
300
|
+
sanitizeInput(input) {
|
|
301
|
+
const sanitized = {};
|
|
302
|
+
for (const [key, value] of Object.entries(input)) {
|
|
303
|
+
// Redact common sensitive field names
|
|
304
|
+
if (/password|secret|token|apikey|api_key|credential/i.test(key)) {
|
|
305
|
+
sanitized[key] = '[REDACTED]';
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
sanitized[key] = value;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return sanitized;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Truncate large outputs to keep log files manageable
|
|
315
|
+
*/
|
|
316
|
+
truncateOutput(output) {
|
|
317
|
+
if (output === undefined || output === null)
|
|
318
|
+
return output;
|
|
319
|
+
const str = typeof output === 'string' ? output : JSON.stringify(output);
|
|
320
|
+
if (str.length > 10_000) {
|
|
321
|
+
return { _truncated: true, preview: str.slice(0, 1000), length: str.length };
|
|
322
|
+
}
|
|
323
|
+
return output;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Find a record by ID in a specific log file
|
|
327
|
+
*/
|
|
328
|
+
findInLog(logPath, executionId) {
|
|
329
|
+
if (!fs.existsSync(logPath))
|
|
330
|
+
return null;
|
|
331
|
+
const content = fs.readFileSync(logPath, 'utf-8');
|
|
332
|
+
const lines = content.trim().split('\n').filter(Boolean);
|
|
333
|
+
// Search from end (most recent) for efficiency
|
|
334
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
335
|
+
try {
|
|
336
|
+
const record = JSON.parse(lines[i]);
|
|
337
|
+
if (record.id === executionId)
|
|
338
|
+
return record;
|
|
339
|
+
}
|
|
340
|
+
catch {
|
|
341
|
+
// Skip
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
return null;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
// Default singleton instance
|
|
348
|
+
let _defaultAuditTrail = null;
|
|
349
|
+
/**
|
|
350
|
+
* Get the default audit trail instance
|
|
351
|
+
*/
|
|
352
|
+
export function getAuditTrail() {
|
|
353
|
+
if (!_defaultAuditTrail) {
|
|
354
|
+
_defaultAuditTrail = new AuditTrail();
|
|
355
|
+
}
|
|
356
|
+
return _defaultAuditTrail;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Set a custom audit trail (for testing or custom storage)
|
|
360
|
+
*/
|
|
361
|
+
export function setAuditTrail(trail) {
|
|
362
|
+
_defaultAuditTrail = trail;
|
|
363
|
+
}
|
|
364
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"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"}
|
package/dist/base.d.ts
CHANGED
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
* ```
|
|
40
40
|
*/
|
|
41
41
|
import { MCPClient, MCPClientFactory } from '@portel/mcp';
|
|
42
|
+
import { MemoryProvider } from './memory.js';
|
|
42
43
|
/**
|
|
43
44
|
* Simple base class for creating Photon MCPs
|
|
44
45
|
*
|
|
@@ -53,6 +54,38 @@ export declare class PhotonMCP {
|
|
|
53
54
|
* @internal
|
|
54
55
|
*/
|
|
55
56
|
_photonName?: string;
|
|
57
|
+
/**
|
|
58
|
+
* Scoped memory provider - lazy-initialized on first access
|
|
59
|
+
* @internal
|
|
60
|
+
*/
|
|
61
|
+
private _memory?;
|
|
62
|
+
/**
|
|
63
|
+
* Session ID for session-scoped memory - set by runtime
|
|
64
|
+
* @internal
|
|
65
|
+
*/
|
|
66
|
+
_sessionId?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Scoped key-value storage for photon data
|
|
69
|
+
*
|
|
70
|
+
* Provides persistent storage with 3 scopes:
|
|
71
|
+
* - `photon` (default): Private to this photon
|
|
72
|
+
* - `session`: Per-user session
|
|
73
|
+
* - `global`: Shared across all photons
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* // Store and retrieve data
|
|
78
|
+
* await this.memory.set('items', [{ id: '1', text: 'Buy milk' }]);
|
|
79
|
+
* const items = await this.memory.get<Item[]>('items');
|
|
80
|
+
*
|
|
81
|
+
* // Global scope (shared across photons)
|
|
82
|
+
* await this.memory.set('theme', 'dark', 'global');
|
|
83
|
+
*
|
|
84
|
+
* // Atomic update
|
|
85
|
+
* await this.memory.update<number>('count', n => (n ?? 0) + 1);
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
get memory(): MemoryProvider;
|
|
56
89
|
/**
|
|
57
90
|
* Emit an event/progress update
|
|
58
91
|
*
|
|
@@ -75,6 +108,33 @@ export declare class PhotonMCP {
|
|
|
75
108
|
* ```
|
|
76
109
|
*/
|
|
77
110
|
protected emit(data: any): void;
|
|
111
|
+
/**
|
|
112
|
+
* Cross-photon call handler - injected by runtime
|
|
113
|
+
* @internal
|
|
114
|
+
*/
|
|
115
|
+
_callHandler?: (photon: string, method: string, params: Record<string, any>) => Promise<any>;
|
|
116
|
+
/**
|
|
117
|
+
* Call another photon's method through the daemon
|
|
118
|
+
*
|
|
119
|
+
* Routes the call through the daemon for cross-process execution.
|
|
120
|
+
* The target photon must be installed and loaded by the daemon.
|
|
121
|
+
*
|
|
122
|
+
* @param target Dot-separated target: 'photonName.methodName'
|
|
123
|
+
* @param params Parameters to pass to the method
|
|
124
|
+
* @returns The method's return value
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```typescript
|
|
128
|
+
* // Call billing photon's generate method
|
|
129
|
+
* const invoice = await this.call('billing.generate', { orderId: '123' });
|
|
130
|
+
*
|
|
131
|
+
* // Call shipping photon
|
|
132
|
+
* const label = await this.call('shipping.createLabel', { orderId: '123' });
|
|
133
|
+
* ```
|
|
134
|
+
*
|
|
135
|
+
* @throws Error if call handler is not set or target format is invalid
|
|
136
|
+
*/
|
|
137
|
+
protected call(target: string, params?: Record<string, any>): Promise<any>;
|
|
78
138
|
/**
|
|
79
139
|
* MCP client factory - injected by runtime
|
|
80
140
|
* @internal
|
package/dist/base.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAkB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAkB,MAAM,aAAa,CAAC;AAI1E,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C;;;;;;GAMG;AACH,qBAAa,SAAS;IACpB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,OAAO,CAAC,OAAO,CAAC,CAAiB;IAEjC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,IAAI,MAAM,IAAI,cAAc,CAU3B;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI;IA+B/B;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAE7F;;;;;;;;;;;;;;;;;;;;OAoBG;cACa,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAoBpF;;;OAGG;IACH,SAAS,CAAC,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAEzC;;;OAGG;IACH,OAAO,CAAC,WAAW,CAAsF;IAEzG;;;OAGG;IACH,MAAM,CAAC,UAAU,IAAI,MAAM;IAQ3B;;;OAGG;IACH,MAAM,CAAC,cAAc,IAAI,MAAM,EAAE;IAiCjC;;OAEG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAkBrH;;OAEG;IACG,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;IAC9B,UAAU,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;IAElC;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAoBhF;;;;;OAKG;IACH,aAAa,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI;IAM9C;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAOzC;;;;;;;;;;;;;;;;;;;;;OAqBG;cACa,QAAQ,CAAC,CAAC,EACxB,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,CAAC,CAAC;CAGd"}
|