@sena-ai/hooks 0.0.1
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/__tests__/fileContext.test.d.ts +2 -0
- package/dist/__tests__/fileContext.test.d.ts.map +1 -0
- package/dist/__tests__/fileContext.test.js +60 -0
- package/dist/__tests__/fileContext.test.js.map +1 -0
- package/dist/__tests__/schedule.test.d.ts +2 -0
- package/dist/__tests__/schedule.test.d.ts.map +1 -0
- package/dist/__tests__/schedule.test.js +34 -0
- package/dist/__tests__/schedule.test.js.map +1 -0
- package/dist/__tests__/traceLogger.test.d.ts +2 -0
- package/dist/__tests__/traceLogger.test.d.ts.map +1 -0
- package/dist/__tests__/traceLogger.test.js +41 -0
- package/dist/__tests__/traceLogger.test.js.map +1 -0
- package/dist/cronSchedule.d.ts +12 -0
- package/dist/cronSchedule.d.ts.map +1 -0
- package/dist/cronSchedule.js +14 -0
- package/dist/cronSchedule.js.map +1 -0
- package/dist/fileContext.d.ts +10 -0
- package/dist/fileContext.d.ts.map +1 -0
- package/dist/fileContext.js +49 -0
- package/dist/fileContext.js.map +1 -0
- package/dist/heartbeat.d.ts +11 -0
- package/dist/heartbeat.d.ts.map +1 -0
- package/dist/heartbeat.js +13 -0
- package/dist/heartbeat.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/traceLogger.d.ts +7 -0
- package/dist/traceLogger.d.ts.map +1 -0
- package/dist/traceLogger.js +22 -0
- package/dist/traceLogger.js.map +1 -0
- package/package.json +22 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileContext.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/fileContext.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { fileContext } from '../fileContext.js';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
const fixturesDir = join(import.meta.dirname, 'fixtures');
|
|
5
|
+
function mockContext(overrides) {
|
|
6
|
+
return {
|
|
7
|
+
turnId: 'turn-1',
|
|
8
|
+
agentName: 'test',
|
|
9
|
+
trigger: 'programmatic',
|
|
10
|
+
input: 'hello',
|
|
11
|
+
sessionId: null,
|
|
12
|
+
metadata: {},
|
|
13
|
+
...overrides,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
describe('fileContext', () => {
|
|
17
|
+
it('loads a single file', async () => {
|
|
18
|
+
const hook = fileContext({
|
|
19
|
+
path: join(fixturesDir, 'soul.md'),
|
|
20
|
+
as: 'system',
|
|
21
|
+
});
|
|
22
|
+
const fragments = await hook.execute(mockContext());
|
|
23
|
+
expect(fragments).toHaveLength(1);
|
|
24
|
+
expect(fragments[0].role).toBe('system');
|
|
25
|
+
expect(fragments[0].content).toContain('테스트 에이전트');
|
|
26
|
+
expect(fragments[0].source).toContain('soul.md');
|
|
27
|
+
});
|
|
28
|
+
it('loads directory with glob filter', async () => {
|
|
29
|
+
const hook = fileContext({
|
|
30
|
+
path: join(fixturesDir, 'memory'),
|
|
31
|
+
as: 'context',
|
|
32
|
+
glob: '*.md',
|
|
33
|
+
});
|
|
34
|
+
const fragments = await hook.execute(mockContext());
|
|
35
|
+
expect(fragments).toHaveLength(2);
|
|
36
|
+
expect(fragments.every(f => f.role === 'context')).toBe(true);
|
|
37
|
+
expect(fragments.every(f => !f.content.includes('무시'))).toBe(true);
|
|
38
|
+
});
|
|
39
|
+
it('respects when condition', async () => {
|
|
40
|
+
const hook = fileContext({
|
|
41
|
+
path: join(fixturesDir, 'soul.md'),
|
|
42
|
+
as: 'system',
|
|
43
|
+
when: (ctx) => ctx.trigger === 'schedule',
|
|
44
|
+
});
|
|
45
|
+
const fragments = await hook.execute(mockContext({ trigger: 'programmatic' }));
|
|
46
|
+
expect(fragments).toHaveLength(0);
|
|
47
|
+
const fragments2 = await hook.execute(mockContext({ trigger: 'schedule' }));
|
|
48
|
+
expect(fragments2).toHaveLength(1);
|
|
49
|
+
});
|
|
50
|
+
it('respects maxLength', async () => {
|
|
51
|
+
const hook = fileContext({
|
|
52
|
+
path: join(fixturesDir, 'soul.md'),
|
|
53
|
+
as: 'system',
|
|
54
|
+
maxLength: 10,
|
|
55
|
+
});
|
|
56
|
+
const fragments = await hook.execute(mockContext());
|
|
57
|
+
expect(fragments[0].content.length).toBeLessThanOrEqual(10);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
//# sourceMappingURL=fileContext.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileContext.test.js","sourceRoot":"","sources":["../../src/__tests__/fileContext.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/schedule.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { cronSchedule } from '../cronSchedule.js';
|
|
3
|
+
import { heartbeat } from '../heartbeat.js';
|
|
4
|
+
describe('cronSchedule', () => {
|
|
5
|
+
it('creates a cron schedule', () => {
|
|
6
|
+
const schedule = cronSchedule('0 * * * *', {
|
|
7
|
+
name: 'hourly-check',
|
|
8
|
+
prompt: 'Do the hourly check',
|
|
9
|
+
});
|
|
10
|
+
expect(schedule.name).toBe('hourly-check');
|
|
11
|
+
expect(schedule.type).toBe('cron');
|
|
12
|
+
expect(schedule.expression).toBe('0 * * * *');
|
|
13
|
+
expect(schedule.prompt).toBe('Do the hourly check');
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
describe('heartbeat', () => {
|
|
17
|
+
it('creates a heartbeat schedule', () => {
|
|
18
|
+
const schedule = heartbeat('15m', {
|
|
19
|
+
prompt: 'Check heartbeat',
|
|
20
|
+
});
|
|
21
|
+
expect(schedule.name).toBe('heartbeat:15m');
|
|
22
|
+
expect(schedule.type).toBe('heartbeat');
|
|
23
|
+
expect(schedule.expression).toBe('15m');
|
|
24
|
+
expect(schedule.prompt).toBe('Check heartbeat');
|
|
25
|
+
});
|
|
26
|
+
it('allows custom name', () => {
|
|
27
|
+
const schedule = heartbeat('30s', {
|
|
28
|
+
name: 'fast-poll',
|
|
29
|
+
prompt: 'Poll fast',
|
|
30
|
+
});
|
|
31
|
+
expect(schedule.name).toBe('fast-poll');
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
//# sourceMappingURL=schedule.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.test.js","sourceRoot":"","sources":["../../src/__tests__/schedule.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,QAAQ,GAAG,YAAY,CAAC,WAAW,EAAE;YACzC,IAAI,EAAE,cAAc;YACpB,MAAM,EAAE,qBAAqB;SAC9B,CAAC,CAAA;QAEF,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;QAC1C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAClC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QAC7C,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAA;IACrD,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,EAAE;YAChC,MAAM,EAAE,iBAAiB;SAC1B,CAAC,CAAA;QAEF,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;QAC3C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QACvC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACvC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;IACjD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAC5B,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,EAAE;YAChC,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE,WAAW;SACpB,CAAC,CAAA;QAEF,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IACzC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traceLogger.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/traceLogger.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { describe, it, expect, afterEach } from 'vitest';
|
|
2
|
+
import { traceLogger } from '../traceLogger.js';
|
|
3
|
+
import { readFile, rm, mkdir, readdir } from 'node:fs/promises';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { tmpdir } from 'node:os';
|
|
6
|
+
const testDir = join(tmpdir(), 'sena-trace-test-' + Date.now());
|
|
7
|
+
function mockContext() {
|
|
8
|
+
return {
|
|
9
|
+
turnId: 'turn-123',
|
|
10
|
+
agentName: 'test',
|
|
11
|
+
trigger: 'programmatic',
|
|
12
|
+
input: 'hello',
|
|
13
|
+
sessionId: null,
|
|
14
|
+
metadata: {},
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function mockResult() {
|
|
18
|
+
return {
|
|
19
|
+
text: 'response',
|
|
20
|
+
sessionId: 'sess-1',
|
|
21
|
+
durationMs: 100,
|
|
22
|
+
toolCalls: [],
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
describe('traceLogger', () => {
|
|
26
|
+
afterEach(async () => {
|
|
27
|
+
await rm(testDir, { recursive: true, force: true });
|
|
28
|
+
});
|
|
29
|
+
it('writes trace as JSON file', async () => {
|
|
30
|
+
await mkdir(testDir, { recursive: true });
|
|
31
|
+
const hook = traceLogger({ dir: testDir });
|
|
32
|
+
await hook.execute(mockContext(), mockResult());
|
|
33
|
+
const entries = await readdir(testDir);
|
|
34
|
+
expect(entries).toHaveLength(1);
|
|
35
|
+
expect(entries[0]).toMatch(/turn-123.*\.json$/);
|
|
36
|
+
const content = JSON.parse(await readFile(join(testDir, entries[0]), 'utf-8'));
|
|
37
|
+
expect(content.turnId).toBe('turn-123');
|
|
38
|
+
expect(content.result.text).toBe('response');
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
//# sourceMappingURL=traceLogger.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traceLogger.test.js","sourceRoot":"","sources":["../../src/__tests__/traceLogger.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAGhC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,kBAAkB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;AAE/D,SAAS,WAAW;IAClB,OAAO;QACL,MAAM,EAAE,UAAU;QAClB,SAAS,EAAE,MAAM;QACjB,OAAO,EAAE,cAAc;QACvB,KAAK,EAAE,OAAO;QACd,SAAS,EAAE,IAAI;QACf,QAAQ,EAAE,EAAE;KACb,CAAA;AACH,CAAC;AAED,SAAS,UAAU;IACjB,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,SAAS,EAAE,QAAQ;QACnB,UAAU,EAAE,GAAG;QACf,SAAS,EAAE,EAAE;KACd,CAAA;AACH,CAAC;AAED,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IACrD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,2BAA2B,EAAE,KAAK,IAAI,EAAE;QACzC,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACzC,MAAM,IAAI,GAAG,WAAW,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAA;QAE1C,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,UAAU,EAAE,CAAC,CAAA;QAE/C,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;QACtC,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;QAC/B,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAA;QAE/C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAA;QAC9E,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACvC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IAC9C,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Schedule } from '@sena-ai/core';
|
|
2
|
+
export type CronScheduleOptions = {
|
|
3
|
+
name: string;
|
|
4
|
+
prompt: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Creates a cron-based schedule.
|
|
8
|
+
* Expression uses 5-field cron format (minute hour day month weekday).
|
|
9
|
+
* Timezone defaults to Asia/Seoul.
|
|
10
|
+
*/
|
|
11
|
+
export declare function cronSchedule(expression: string, options: CronScheduleOptions): Schedule;
|
|
12
|
+
//# sourceMappingURL=cronSchedule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cronSchedule.d.ts","sourceRoot":"","sources":["../src/cronSchedule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAE7C,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,QAAQ,CAOvF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a cron-based schedule.
|
|
3
|
+
* Expression uses 5-field cron format (minute hour day month weekday).
|
|
4
|
+
* Timezone defaults to Asia/Seoul.
|
|
5
|
+
*/
|
|
6
|
+
export function cronSchedule(expression, options) {
|
|
7
|
+
return {
|
|
8
|
+
name: options.name,
|
|
9
|
+
type: 'cron',
|
|
10
|
+
expression,
|
|
11
|
+
prompt: options.prompt,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=cronSchedule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cronSchedule.js","sourceRoot":"","sources":["../src/cronSchedule.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,UAAkB,EAAE,OAA4B;IAC3E,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,IAAI,EAAE,MAAM;QACZ,UAAU;QACV,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { TurnStartHook, TurnContext } from '@sena-ai/core';
|
|
2
|
+
export type FileContextOptions = {
|
|
3
|
+
path: string;
|
|
4
|
+
as: 'system' | 'context';
|
|
5
|
+
glob?: string;
|
|
6
|
+
when?: (ctx: TurnContext) => boolean;
|
|
7
|
+
maxLength?: number;
|
|
8
|
+
};
|
|
9
|
+
export declare function fileContext(options: FileContextOptions): TurnStartHook;
|
|
10
|
+
//# sourceMappingURL=fileContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileContext.d.ts","sourceRoot":"","sources":["../src/fileContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAmB,MAAM,eAAe,CAAA;AAIhF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,QAAQ,GAAG,SAAS,CAAA;IACxB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,OAAO,CAAA;IACpC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,aAAa,CAmCtE"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { readFile, readdir, stat } from 'node:fs/promises';
|
|
2
|
+
import { join, basename } from 'node:path';
|
|
3
|
+
export function fileContext(options) {
|
|
4
|
+
const { path, as: role, glob, when, maxLength } = options;
|
|
5
|
+
return {
|
|
6
|
+
name: `fileContext:${path}`,
|
|
7
|
+
async execute(ctx) {
|
|
8
|
+
if (when && !when(ctx))
|
|
9
|
+
return [];
|
|
10
|
+
const info = await stat(path);
|
|
11
|
+
if (info.isFile()) {
|
|
12
|
+
const content = await readFile(path, 'utf-8');
|
|
13
|
+
return [makeFragment(path, role, content, maxLength)];
|
|
14
|
+
}
|
|
15
|
+
if (info.isDirectory()) {
|
|
16
|
+
const entries = await readdir(path);
|
|
17
|
+
const filtered = glob
|
|
18
|
+
? entries.filter(e => matchGlob(e, glob))
|
|
19
|
+
: entries;
|
|
20
|
+
const fragments = [];
|
|
21
|
+
for (const entry of filtered.sort()) {
|
|
22
|
+
const filePath = join(path, entry);
|
|
23
|
+
const fileStat = await stat(filePath);
|
|
24
|
+
if (!fileStat.isFile())
|
|
25
|
+
continue;
|
|
26
|
+
const content = await readFile(filePath, 'utf-8');
|
|
27
|
+
fragments.push(makeFragment(filePath, role, content, maxLength));
|
|
28
|
+
}
|
|
29
|
+
return fragments;
|
|
30
|
+
}
|
|
31
|
+
return [];
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function makeFragment(filePath, role, content, maxLength) {
|
|
36
|
+
const trimmed = maxLength ? content.slice(0, maxLength) : content;
|
|
37
|
+
return {
|
|
38
|
+
source: `file:${basename(filePath)}`,
|
|
39
|
+
role,
|
|
40
|
+
content: trimmed,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function matchGlob(filename, pattern) {
|
|
44
|
+
if (pattern.startsWith('*')) {
|
|
45
|
+
return filename.endsWith(pattern.slice(1));
|
|
46
|
+
}
|
|
47
|
+
return filename === pattern;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=fileContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileContext.js","sourceRoot":"","sources":["../src/fileContext.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAC1D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAU1C,MAAM,UAAU,WAAW,CAAC,OAA2B;IACrD,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,OAAO,CAAA;IAEzD,OAAO;QACL,IAAI,EAAE,eAAe,IAAI,EAAE;QAC3B,KAAK,CAAC,OAAO,CAAC,GAAgB;YAC5B,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;gBAAE,OAAO,EAAE,CAAA;YAEjC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAA;YAE7B,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;gBAClB,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;gBAC7C,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAA;YACvD,CAAC;YAED,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBACvB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;gBACnC,MAAM,QAAQ,GAAG,IAAI;oBACnB,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;oBACzC,CAAC,CAAC,OAAO,CAAA;gBAEX,MAAM,SAAS,GAAsB,EAAE,CAAA;gBACvC,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;oBACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;oBAClC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAA;oBACrC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;wBAAE,SAAQ;oBAChC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;oBACjD,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAA;gBAClE,CAAC;gBACD,OAAO,SAAS,CAAA;YAClB,CAAC;YAED,OAAO,EAAE,CAAA;QACX,CAAC;KACF,CAAA;AACH,CAAC;AAED,SAAS,YAAY,CACnB,QAAgB,EAChB,IAA0B,EAC1B,OAAe,EACf,SAAkB;IAElB,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;IACjE,OAAO;QACL,MAAM,EAAE,QAAQ,QAAQ,CAAC,QAAQ,CAAC,EAAE;QACpC,IAAI;QACJ,OAAO,EAAE,OAAO;KACjB,CAAA;AACH,CAAC;AAED,SAAS,SAAS,CAAC,QAAgB,EAAE,OAAe;IAClD,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IAC5C,CAAC;IACD,OAAO,QAAQ,KAAK,OAAO,CAAA;AAC7B,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Schedule } from '@sena-ai/core';
|
|
2
|
+
export type HeartbeatOptions = {
|
|
3
|
+
prompt: string;
|
|
4
|
+
name?: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Creates a fixed-interval heartbeat schedule.
|
|
8
|
+
* Interval format: '15m', '1h', '30s', etc.
|
|
9
|
+
*/
|
|
10
|
+
export declare function heartbeat(interval: string, options: HeartbeatOptions): Schedule;
|
|
11
|
+
//# sourceMappingURL=heartbeat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat.d.ts","sourceRoot":"","sources":["../src/heartbeat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAE7C,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,QAAQ,CAO/E"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a fixed-interval heartbeat schedule.
|
|
3
|
+
* Interval format: '15m', '1h', '30s', etc.
|
|
4
|
+
*/
|
|
5
|
+
export function heartbeat(interval, options) {
|
|
6
|
+
return {
|
|
7
|
+
name: options.name ?? `heartbeat:${interval}`,
|
|
8
|
+
type: 'heartbeat',
|
|
9
|
+
expression: interval,
|
|
10
|
+
prompt: options.prompt,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=heartbeat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../src/heartbeat.ts"],"names":[],"mappings":"AAOA;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,QAAgB,EAAE,OAAyB;IACnE,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,aAAa,QAAQ,EAAE;QAC7C,IAAI,EAAE,WAAW;QACjB,UAAU,EAAE,QAAQ;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAA;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const VERSION = "0.0.1";
|
|
2
|
+
export { fileContext } from './fileContext.js';
|
|
3
|
+
export type { FileContextOptions } from './fileContext.js';
|
|
4
|
+
export { traceLogger } from './traceLogger.js';
|
|
5
|
+
export type { TraceLoggerOptions } from './traceLogger.js';
|
|
6
|
+
export { cronSchedule } from './cronSchedule.js';
|
|
7
|
+
export type { CronScheduleOptions } from './cronSchedule.js';
|
|
8
|
+
export { heartbeat } from './heartbeat.js';
|
|
9
|
+
export type { HeartbeatOptions } from './heartbeat.js';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,UAAU,CAAA;AAE9B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAA;AAE9B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEhD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traceLogger.d.ts","sourceRoot":"","sources":["../src/traceLogger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAA2B,MAAM,eAAe,CAAA;AAIzE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,WAAW,CAqBpE"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { writeFile, mkdir } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
export function traceLogger(options) {
|
|
4
|
+
const { dir } = options;
|
|
5
|
+
return {
|
|
6
|
+
name: 'traceLogger',
|
|
7
|
+
async execute(context, result) {
|
|
8
|
+
await mkdir(dir, { recursive: true });
|
|
9
|
+
const filename = `${context.turnId}-${Date.now()}.json`;
|
|
10
|
+
const trace = {
|
|
11
|
+
turnId: context.turnId,
|
|
12
|
+
agentName: context.agentName,
|
|
13
|
+
trigger: context.trigger,
|
|
14
|
+
input: context.input,
|
|
15
|
+
timestamp: new Date().toISOString(),
|
|
16
|
+
result,
|
|
17
|
+
};
|
|
18
|
+
await writeFile(join(dir, filename), JSON.stringify(trace, null, 2), 'utf-8');
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=traceLogger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traceLogger.js","sourceRoot":"","sources":["../src/traceLogger.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAOhC,MAAM,UAAU,WAAW,CAAC,OAA2B;IACrD,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAA;IAEvB,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,KAAK,CAAC,OAAO,CAAC,OAAoB,EAAE,MAAkB;YACpD,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;YAErC,MAAM,QAAQ,GAAG,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,OAAO,CAAA;YACvD,MAAM,KAAK,GAAG;gBACZ,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,MAAM;aACP,CAAA;YAED,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;QAC/E,CAAC;KACF,CAAA;AACH,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sena-ai/hooks",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"import": "./dist/index.js"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"files": ["dist"],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc -b",
|
|
14
|
+
"dev": "tsc -b --watch"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@sena-ai/core": "workspace:*"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"typescript": "^5.8.0"
|
|
21
|
+
}
|
|
22
|
+
}
|