@olane/o-lane 0.7.12-alpha.76 → 0.7.12
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/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -2
- package/dist/src/prompts/agent.prompt.d.ts +11 -0
- package/dist/src/prompts/agent.prompt.d.ts.map +1 -1
- package/dist/src/prompts/agent.prompt.js +14 -3
- package/dist/src/prompts/configure.prompt.d.ts +7 -0
- package/dist/src/prompts/configure.prompt.d.ts.map +1 -1
- package/dist/src/prompts/configure.prompt.js +8 -1
- package/dist/src/prompts/custom.prompt.d.ts +7 -0
- package/dist/src/prompts/custom.prompt.d.ts.map +1 -1
- package/dist/src/prompts/custom.prompt.js +77 -0
- package/dist/src/storage/index.d.ts +8 -0
- package/dist/src/storage/index.d.ts.map +1 -0
- package/dist/src/storage/index.js +12 -0
- package/dist/src/storage/interfaces/prompt-storage.interface.d.ts +102 -0
- package/dist/src/storage/interfaces/prompt-storage.interface.d.ts.map +1 -0
- package/dist/src/storage/methods/prompt-storage.methods.d.ts +9 -0
- package/dist/src/storage/methods/prompt-storage.methods.d.ts.map +1 -0
- package/dist/src/storage/methods/prompt-storage.methods.js +338 -0
- package/dist/src/storage/prompt-loader.d.ts +40 -0
- package/dist/src/storage/prompt-loader.d.ts.map +1 -0
- package/dist/src/storage/prompt-loader.js +126 -0
- package/dist/src/storage/prompt-schema.d.ts +42 -0
- package/dist/src/storage/prompt-schema.d.ts.map +1 -0
- package/dist/src/storage/prompt-schema.js +29 -0
- package/dist/src/storage/prompt-seeder.d.ts +42 -0
- package/dist/src/storage/prompt-seeder.d.ts.map +1 -0
- package/dist/src/storage/prompt-seeder.js +141 -0
- package/dist/src/storage/prompt-storage-provider.tool.d.ts +99 -0
- package/dist/src/storage/prompt-storage-provider.tool.d.ts.map +1 -0
- package/dist/src/storage/prompt-storage-provider.tool.js +320 -0
- package/dist/test/prompt-seeder.spec.d.ts +2 -0
- package/dist/test/prompt-seeder.spec.d.ts.map +1 -0
- package/dist/test/prompt-seeder.spec.js +254 -0
- package/dist/test/prompt-storage-provider.spec.d.ts +2 -0
- package/dist/test/prompt-storage-provider.spec.d.ts.map +1 -0
- package/dist/test/prompt-storage-provider.spec.js +456 -0
- package/package.json +10 -7
- package/dist/src/ag-ui/ag-ui-constants.d.ts +0 -90
- package/dist/src/ag-ui/ag-ui-constants.d.ts.map +0 -1
- package/dist/src/ag-ui/ag-ui-constants.js +0 -113
- package/dist/src/ag-ui/ag-ui-event-mapper.d.ts +0 -88
- package/dist/src/ag-ui/ag-ui-event-mapper.d.ts.map +0 -1
- package/dist/src/ag-ui/ag-ui-event-mapper.js +0 -487
- package/dist/src/ag-ui/ag-ui-olane.tool.d.ts +0 -45
- package/dist/src/ag-ui/ag-ui-olane.tool.d.ts.map +0 -1
- package/dist/src/ag-ui/ag-ui-olane.tool.js +0 -257
- package/dist/src/ag-ui/ag-ui-stream-manager.d.ts +0 -99
- package/dist/src/ag-ui/ag-ui-stream-manager.d.ts.map +0 -1
- package/dist/src/ag-ui/ag-ui-stream-manager.js +0 -160
- package/dist/src/ag-ui/ag-ui-utils.d.ts +0 -50
- package/dist/src/ag-ui/ag-ui-utils.d.ts.map +0 -1
- package/dist/src/ag-ui/ag-ui-utils.js +0 -287
- package/dist/src/ag-ui/index.d.ts +0 -17
- package/dist/src/ag-ui/index.d.ts.map +0 -1
- package/dist/src/ag-ui/index.js +0 -21
- package/dist/src/ag-ui/transports/ag-ui-transport.interface.d.ts +0 -44
- package/dist/src/ag-ui/transports/ag-ui-transport.interface.d.ts.map +0 -1
- package/dist/src/ag-ui/transports/ag-ui-transport.interface.js +0 -26
- package/dist/src/ag-ui/transports/callback-transport.d.ts +0 -13
- package/dist/src/ag-ui/transports/callback-transport.d.ts.map +0 -1
- package/dist/src/ag-ui/transports/callback-transport.js +0 -26
- package/dist/src/ag-ui/transports/console-transport.d.ts +0 -14
- package/dist/src/ag-ui/transports/console-transport.d.ts.map +0 -1
- package/dist/src/ag-ui/transports/console-transport.js +0 -63
- package/dist/src/ag-ui/transports/index.d.ts +0 -5
- package/dist/src/ag-ui/transports/index.d.ts.map +0 -1
- package/dist/src/ag-ui/transports/index.js +0 -4
- package/dist/src/ag-ui/transports/onode-transport.d.ts +0 -34
- package/dist/src/ag-ui/transports/onode-transport.d.ts.map +0 -1
- package/dist/src/ag-ui/transports/onode-transport.js +0 -83
- package/dist/src/ag-ui/types/ag-ui-config.interface.d.ts +0 -105
- package/dist/src/ag-ui/types/ag-ui-config.interface.d.ts.map +0 -1
- package/dist/src/ag-ui/types/ag-ui-event.types.d.ts +0 -266
- package/dist/src/ag-ui/types/ag-ui-event.types.d.ts.map +0 -1
- package/dist/src/ag-ui/types/ag-ui-event.types.js +0 -6
- package/dist/src/ag-ui/types/index.d.ts +0 -3
- package/dist/src/ag-ui/types/index.d.ts.map +0 -1
- package/dist/src/ag-ui/types/index.js +0 -2
- package/dist/test/ai.spec.d.ts +0 -2
- package/dist/test/ai.spec.d.ts.map +0 -1
- package/dist/test/ai.spec.js +0 -19
- /package/dist/src/{ag-ui/types/ag-ui-config.interface.js → storage/interfaces/prompt-storage.interface.js} +0 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt Seeder
|
|
3
|
+
*
|
|
4
|
+
* Seeds the PromptStorageProvider with prompt templates from prompts/ folder
|
|
5
|
+
*/
|
|
6
|
+
import { PROMPT_KEYS, PROMPT_IDS, PROMPT_VERSION, } from './prompt-schema.js';
|
|
7
|
+
import { BASE_TEMPLATE_SEED } from '../prompts/custom.prompt.js';
|
|
8
|
+
import { CYCLE_INSTRUCTIONS_SEED, OUTPUT_INSTRUCTIONS_SEED, } from '../prompts/agent.prompt.js';
|
|
9
|
+
import { CONFIGURE_INSTRUCTIONS_SEED } from '../prompts/configure.prompt.js';
|
|
10
|
+
/**
|
|
11
|
+
* Seeds the prompt storage with default prompt templates
|
|
12
|
+
*/
|
|
13
|
+
export class PromptSeeder {
|
|
14
|
+
constructor(storage) {
|
|
15
|
+
this.storage = storage;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Seed all default prompts into storage
|
|
19
|
+
*/
|
|
20
|
+
async seedAll() {
|
|
21
|
+
await this.seedBaseTemplate();
|
|
22
|
+
await this.seedCycleInstructions();
|
|
23
|
+
await this.seedOutputInstructions();
|
|
24
|
+
await this.seedConfigureInstructions();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Seed the base template from custom.prompt.ts
|
|
28
|
+
*/
|
|
29
|
+
async seedBaseTemplate() {
|
|
30
|
+
const template = {
|
|
31
|
+
content: BASE_TEMPLATE_SEED,
|
|
32
|
+
metadata: {
|
|
33
|
+
version: PROMPT_VERSION,
|
|
34
|
+
description: 'Base agent prompt template structure',
|
|
35
|
+
lastModified: Date.now(),
|
|
36
|
+
source: 'prompts/custom.prompt.ts (BASE_TEMPLATE_SEED)',
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
await this.storage.use(this.storage.address, {
|
|
40
|
+
method: 'put',
|
|
41
|
+
params: {
|
|
42
|
+
promptId: PROMPT_IDS.AGENT,
|
|
43
|
+
key: PROMPT_KEYS.BASE_TEMPLATE,
|
|
44
|
+
value: template,
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Seed cycle instructions from agent.prompt.ts
|
|
50
|
+
*/
|
|
51
|
+
async seedCycleInstructions() {
|
|
52
|
+
const template = {
|
|
53
|
+
content: CYCLE_INSTRUCTIONS_SEED,
|
|
54
|
+
metadata: {
|
|
55
|
+
version: PROMPT_VERSION,
|
|
56
|
+
description: 'Agent cycle workflow instructions (6 steps)',
|
|
57
|
+
lastModified: Date.now(),
|
|
58
|
+
source: 'prompts/agent.prompt.ts (CYCLE_INSTRUCTIONS_SEED)',
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
await this.storage.use(this.storage.address, {
|
|
62
|
+
method: 'put',
|
|
63
|
+
params: {
|
|
64
|
+
promptId: PROMPT_IDS.AGENT,
|
|
65
|
+
key: PROMPT_KEYS.CYCLE_INSTRUCTIONS,
|
|
66
|
+
value: template,
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Seed output instructions from agent.prompt.ts
|
|
72
|
+
*/
|
|
73
|
+
async seedOutputInstructions() {
|
|
74
|
+
const template = {
|
|
75
|
+
content: OUTPUT_INSTRUCTIONS_SEED,
|
|
76
|
+
metadata: {
|
|
77
|
+
version: PROMPT_VERSION,
|
|
78
|
+
description: 'Agent return format instructions',
|
|
79
|
+
lastModified: Date.now(),
|
|
80
|
+
source: 'prompts/agent.prompt.ts (OUTPUT_INSTRUCTIONS_SEED)',
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
await this.storage.use(this.storage.address, {
|
|
84
|
+
method: 'put',
|
|
85
|
+
params: {
|
|
86
|
+
promptId: PROMPT_IDS.AGENT,
|
|
87
|
+
key: PROMPT_KEYS.OUTPUT_INSTRUCTIONS,
|
|
88
|
+
value: template,
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Seed configure instructions from configure.prompt.ts
|
|
94
|
+
*/
|
|
95
|
+
async seedConfigureInstructions() {
|
|
96
|
+
const template = {
|
|
97
|
+
content: CONFIGURE_INSTRUCTIONS_SEED,
|
|
98
|
+
metadata: {
|
|
99
|
+
version: PROMPT_VERSION,
|
|
100
|
+
description: 'Configure capability specific instructions',
|
|
101
|
+
lastModified: Date.now(),
|
|
102
|
+
source: 'prompts/configure.prompt.ts (CONFIGURE_INSTRUCTIONS_SEED)',
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
await this.storage.use(this.storage.address, {
|
|
106
|
+
method: 'put',
|
|
107
|
+
params: {
|
|
108
|
+
promptId: PROMPT_IDS.AGENT,
|
|
109
|
+
key: PROMPT_KEYS.CONFIGURE_INSTRUCTIONS,
|
|
110
|
+
value: template,
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Check if prompts are already seeded
|
|
116
|
+
*/
|
|
117
|
+
async isSeeded() {
|
|
118
|
+
const response = await this.storage.use(this.storage.address, {
|
|
119
|
+
method: 'has',
|
|
120
|
+
params: {
|
|
121
|
+
promptId: PROMPT_IDS.AGENT,
|
|
122
|
+
key: PROMPT_KEYS.BASE_TEMPLATE,
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
if (!response.result.success) {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
return response.result?.data?.exists === true;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Clear all seeded prompts
|
|
132
|
+
*/
|
|
133
|
+
async clearAll() {
|
|
134
|
+
await this.storage.use(this.storage.address, {
|
|
135
|
+
method: 'clear_prompt',
|
|
136
|
+
params: {
|
|
137
|
+
promptId: PROMPT_IDS.AGENT,
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { ToolResult } from '@olane/o-tool';
|
|
2
|
+
import { StorageProviderTool } from '@olane/o-storage';
|
|
3
|
+
import { oRequest } from '@olane/o-core';
|
|
4
|
+
import { GetDataResponse } from '@olane/o-storage';
|
|
5
|
+
import { PromptStorageConfig, PromptStats, ListPromptsResponse, PromptKeysResponse, ClearPromptResponse } from './interfaces/prompt-storage.interface.js';
|
|
6
|
+
import { oNodeAddress } from '@olane/o-node';
|
|
7
|
+
/**
|
|
8
|
+
* Prompt-specific storage provider that isolates data per prompt/conversation
|
|
9
|
+
* Extends StorageProviderTool to provide namespace isolation by promptId
|
|
10
|
+
*
|
|
11
|
+
* Features:
|
|
12
|
+
* - Isolated storage namespaces per promptId
|
|
13
|
+
* - Standard CRUD operations (put, get, delete, has)
|
|
14
|
+
* - Prompt management (list, clear, stats)
|
|
15
|
+
* - Optional TTL-based cleanup for inactive prompts
|
|
16
|
+
* - Memory-efficient nested Map structure
|
|
17
|
+
*/
|
|
18
|
+
export declare class PromptStorageProvider extends StorageProviderTool {
|
|
19
|
+
readonly config: PromptStorageConfig;
|
|
20
|
+
/**
|
|
21
|
+
* Node address (inherited from base class)
|
|
22
|
+
*/
|
|
23
|
+
readonly address: oNodeAddress;
|
|
24
|
+
/**
|
|
25
|
+
* Nested storage: Map<promptId, Map<key, value>>
|
|
26
|
+
* Provides O(1) access with automatic namespace isolation
|
|
27
|
+
*/
|
|
28
|
+
private storage;
|
|
29
|
+
/**
|
|
30
|
+
* Metadata tracking per prompt for stats and cleanup
|
|
31
|
+
*/
|
|
32
|
+
private metadata;
|
|
33
|
+
/**
|
|
34
|
+
* Cleanup interval timer
|
|
35
|
+
*/
|
|
36
|
+
private cleanupTimer?;
|
|
37
|
+
constructor(config: PromptStorageConfig);
|
|
38
|
+
/**
|
|
39
|
+
* Initialize background cleanup task if TTL is configured
|
|
40
|
+
*/
|
|
41
|
+
hookStartFinished(): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Store data in a prompt-specific namespace
|
|
44
|
+
* ✅ Throws errors for validation failures
|
|
45
|
+
* ✅ Returns raw data (base class wraps it)
|
|
46
|
+
*/
|
|
47
|
+
_tool_put(request: oRequest): Promise<ToolResult>;
|
|
48
|
+
/**
|
|
49
|
+
* Retrieve data from a prompt-specific namespace
|
|
50
|
+
* ✅ Throws errors for validation failures
|
|
51
|
+
* ✅ Returns raw data with null for missing keys
|
|
52
|
+
*/
|
|
53
|
+
_tool_get(request: oRequest): Promise<GetDataResponse>;
|
|
54
|
+
/**
|
|
55
|
+
* Delete a specific key from a prompt namespace
|
|
56
|
+
* ✅ Throws errors for validation failures
|
|
57
|
+
* ✅ Returns raw data
|
|
58
|
+
*/
|
|
59
|
+
_tool_delete(request: oRequest): Promise<ToolResult>;
|
|
60
|
+
/**
|
|
61
|
+
* Check if a key exists in a prompt namespace
|
|
62
|
+
* ✅ Throws errors for validation failures
|
|
63
|
+
* ✅ Returns raw data
|
|
64
|
+
*/
|
|
65
|
+
_tool_has(request: oRequest): Promise<ToolResult>;
|
|
66
|
+
/**
|
|
67
|
+
* List all prompt IDs with active storage
|
|
68
|
+
*/
|
|
69
|
+
_tool_list_prompts(_request: oRequest): Promise<ListPromptsResponse>;
|
|
70
|
+
/**
|
|
71
|
+
* Clear all data for a specific prompt namespace
|
|
72
|
+
*/
|
|
73
|
+
_tool_clear_prompt(request: oRequest): Promise<ClearPromptResponse>;
|
|
74
|
+
/**
|
|
75
|
+
* Get all keys stored in a specific prompt namespace
|
|
76
|
+
*/
|
|
77
|
+
_tool_get_prompt_keys(request: oRequest): Promise<PromptKeysResponse>;
|
|
78
|
+
/**
|
|
79
|
+
* Get statistics for a specific prompt namespace
|
|
80
|
+
*/
|
|
81
|
+
_tool_get_prompt_stats(request: oRequest): Promise<PromptStats>;
|
|
82
|
+
/**
|
|
83
|
+
* Cleanup resources on stop
|
|
84
|
+
*/
|
|
85
|
+
stop(): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* Update last accessed timestamp for a prompt
|
|
88
|
+
*/
|
|
89
|
+
private updateLastAccessed;
|
|
90
|
+
/**
|
|
91
|
+
* Clean up prompts that haven't been accessed within TTL
|
|
92
|
+
*/
|
|
93
|
+
private cleanupExpiredPrompts;
|
|
94
|
+
/**
|
|
95
|
+
* Evict the oldest prompt when max limit is reached
|
|
96
|
+
*/
|
|
97
|
+
private evictOldestPrompt;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=prompt-storage-provider.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-storage-provider.tool.d.ts","sourceRoot":"","sources":["../../../src/storage/prompt-storage-provider.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAY,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EAEpB,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C;;;;;;;;;;GAUG;AACH,qBAAa,qBAAsB,SAAQ,mBAAmB;IAuBhD,QAAQ,CAAC,MAAM,EAAE,mBAAmB;IAtBhD;;OAEG;IACH,SAAgB,OAAO,EAAG,YAAY,CAAC;IAEvC;;;OAGG;IACH,OAAO,CAAC,OAAO,CAAmC;IAElD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAA8B;IAG9C;;OAEG;IACH,OAAO,CAAC,YAAY,CAAC,CAAiB;gBAEjB,MAAM,EAAE,mBAAmB;IAgBhD;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBxC;;;;OAIG;IACG,SAAS,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAwCvD;;;;OAIG;IACG,SAAS,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,eAAe,CAAC;IA+B5D;;;;OAIG;IACG,YAAY,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAoC1D;;;;OAIG;IACG,SAAS,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAyBvD;;OAEG;IACG,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAS1E;;OAEG;IACG,kBAAkB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA4BzE;;OAEG;IACG,qBAAqB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAyB3E;;OAEG;IACG,sBAAsB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC;IA+BrE;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAO1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAyB7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAqB1B"}
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import { StorageProviderTool } from '@olane/o-storage';
|
|
2
|
+
import { oAddress } from '@olane/o-core';
|
|
3
|
+
import { PROMPT_STORAGE_METHODS } from './methods/prompt-storage.methods.js';
|
|
4
|
+
/**
|
|
5
|
+
* Prompt-specific storage provider that isolates data per prompt/conversation
|
|
6
|
+
* Extends StorageProviderTool to provide namespace isolation by promptId
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Isolated storage namespaces per promptId
|
|
10
|
+
* - Standard CRUD operations (put, get, delete, has)
|
|
11
|
+
* - Prompt management (list, clear, stats)
|
|
12
|
+
* - Optional TTL-based cleanup for inactive prompts
|
|
13
|
+
* - Memory-efficient nested Map structure
|
|
14
|
+
*/
|
|
15
|
+
export class PromptStorageProvider extends StorageProviderTool {
|
|
16
|
+
constructor(config) {
|
|
17
|
+
const finalConfig = {
|
|
18
|
+
...config,
|
|
19
|
+
address: config.address || new oAddress('o://prompt-storage'),
|
|
20
|
+
methods: PROMPT_STORAGE_METHODS,
|
|
21
|
+
description: 'Prompt-specific storage provider with isolated namespaces per conversation',
|
|
22
|
+
};
|
|
23
|
+
super(finalConfig);
|
|
24
|
+
this.config = config;
|
|
25
|
+
this.config = finalConfig;
|
|
26
|
+
this.storage = new Map();
|
|
27
|
+
this.metadata = new Map();
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Initialize background cleanup task if TTL is configured
|
|
31
|
+
*/
|
|
32
|
+
async hookStartFinished() {
|
|
33
|
+
if (this.config.promptTTL) {
|
|
34
|
+
const interval = this.config.cleanupInterval || 60000; // Default 1 minute
|
|
35
|
+
this.cleanupTimer = setInterval(() => {
|
|
36
|
+
this.cleanupExpiredPrompts();
|
|
37
|
+
}, interval);
|
|
38
|
+
this.logger.info('Prompt storage cleanup enabled', {
|
|
39
|
+
ttl: this.config.promptTTL,
|
|
40
|
+
interval,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
await super.hookStartFinished();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Store data in a prompt-specific namespace
|
|
47
|
+
* ✅ Throws errors for validation failures
|
|
48
|
+
* ✅ Returns raw data (base class wraps it)
|
|
49
|
+
*/
|
|
50
|
+
async _tool_put(request) {
|
|
51
|
+
const { promptId, key, value } = request.params;
|
|
52
|
+
// Validate required parameters
|
|
53
|
+
if (!promptId || typeof promptId !== 'string') {
|
|
54
|
+
throw new Error('promptId is required and must be a string');
|
|
55
|
+
}
|
|
56
|
+
if (!key || typeof key !== 'string') {
|
|
57
|
+
throw new Error('key is required and must be a string');
|
|
58
|
+
}
|
|
59
|
+
if (value === undefined || value === null) {
|
|
60
|
+
throw new Error('value is required');
|
|
61
|
+
}
|
|
62
|
+
// Ensure prompt namespace exists
|
|
63
|
+
if (!this.storage.has(promptId)) {
|
|
64
|
+
this.storage.set(promptId, new Map());
|
|
65
|
+
this.metadata.set(promptId, {
|
|
66
|
+
createdAt: Date.now(),
|
|
67
|
+
lastAccessed: Date.now(),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
// Store value and update metadata
|
|
71
|
+
const promptStorage = this.storage.get(promptId);
|
|
72
|
+
promptStorage.set(key, String(value));
|
|
73
|
+
this.updateLastAccessed(promptId);
|
|
74
|
+
// Check max prompts limit
|
|
75
|
+
if (this.config.maxPrompts && this.storage.size > this.config.maxPrompts) {
|
|
76
|
+
this.evictOldestPrompt();
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
success: true,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Retrieve data from a prompt-specific namespace
|
|
84
|
+
* ✅ Throws errors for validation failures
|
|
85
|
+
* ✅ Returns raw data with null for missing keys
|
|
86
|
+
*/
|
|
87
|
+
async _tool_get(request) {
|
|
88
|
+
const { promptId, key } = request.params;
|
|
89
|
+
// Validate required parameters
|
|
90
|
+
if (!promptId || typeof promptId !== 'string') {
|
|
91
|
+
throw new Error('promptId is required and must be a string');
|
|
92
|
+
}
|
|
93
|
+
if (!key || typeof key !== 'string') {
|
|
94
|
+
throw new Error('key is required and must be a string');
|
|
95
|
+
}
|
|
96
|
+
// Check if prompt exists
|
|
97
|
+
const promptStorage = this.storage.get(promptId);
|
|
98
|
+
if (!promptStorage) {
|
|
99
|
+
return {
|
|
100
|
+
value: null,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
// Get value and update metadata
|
|
104
|
+
const value = promptStorage.get(key);
|
|
105
|
+
if (value !== undefined) {
|
|
106
|
+
this.updateLastAccessed(promptId);
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
value: value ?? null,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Delete a specific key from a prompt namespace
|
|
114
|
+
* ✅ Throws errors for validation failures
|
|
115
|
+
* ✅ Returns raw data
|
|
116
|
+
*/
|
|
117
|
+
async _tool_delete(request) {
|
|
118
|
+
const { promptId, key } = request.params;
|
|
119
|
+
// Validate required parameters
|
|
120
|
+
if (!promptId || typeof promptId !== 'string') {
|
|
121
|
+
throw new Error('promptId is required and must be a string');
|
|
122
|
+
}
|
|
123
|
+
if (!key || typeof key !== 'string') {
|
|
124
|
+
throw new Error('key is required and must be a string');
|
|
125
|
+
}
|
|
126
|
+
// Get prompt storage
|
|
127
|
+
const promptStorage = this.storage.get(promptId);
|
|
128
|
+
if (!promptStorage) {
|
|
129
|
+
// Not an error - deleting non-existent key is idempotent
|
|
130
|
+
return {
|
|
131
|
+
success: true,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
// Delete key and update metadata
|
|
135
|
+
promptStorage.delete(key);
|
|
136
|
+
this.updateLastAccessed(promptId);
|
|
137
|
+
// Clean up empty prompt namespace
|
|
138
|
+
if (promptStorage.size === 0) {
|
|
139
|
+
this.storage.delete(promptId);
|
|
140
|
+
this.metadata.delete(promptId);
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
success: true,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Check if a key exists in a prompt namespace
|
|
148
|
+
* ✅ Throws errors for validation failures
|
|
149
|
+
* ✅ Returns raw data
|
|
150
|
+
*/
|
|
151
|
+
async _tool_has(request) {
|
|
152
|
+
const { promptId, key } = request.params;
|
|
153
|
+
// Validate required parameters
|
|
154
|
+
if (!promptId || typeof promptId !== 'string') {
|
|
155
|
+
throw new Error('promptId is required and must be a string');
|
|
156
|
+
}
|
|
157
|
+
if (!key || typeof key !== 'string') {
|
|
158
|
+
throw new Error('key is required and must be a string');
|
|
159
|
+
}
|
|
160
|
+
// Check existence
|
|
161
|
+
const promptStorage = this.storage.get(promptId);
|
|
162
|
+
const exists = promptStorage ? promptStorage.has(key) : false;
|
|
163
|
+
if (exists) {
|
|
164
|
+
this.updateLastAccessed(promptId);
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
success: exists,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* List all prompt IDs with active storage
|
|
172
|
+
*/
|
|
173
|
+
async _tool_list_prompts(_request) {
|
|
174
|
+
const promptIds = Array.from(this.storage.keys());
|
|
175
|
+
return {
|
|
176
|
+
promptIds,
|
|
177
|
+
count: promptIds.length,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Clear all data for a specific prompt namespace
|
|
182
|
+
*/
|
|
183
|
+
async _tool_clear_prompt(request) {
|
|
184
|
+
const { promptId } = request.params;
|
|
185
|
+
// Validate required parameter
|
|
186
|
+
if (!promptId || typeof promptId !== 'string') {
|
|
187
|
+
throw new Error('promptId is required and must be a string');
|
|
188
|
+
}
|
|
189
|
+
const promptStorage = this.storage.get(promptId);
|
|
190
|
+
if (!promptStorage) {
|
|
191
|
+
return {
|
|
192
|
+
success: true,
|
|
193
|
+
keysDeleted: 0,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
const keysDeleted = promptStorage.size;
|
|
197
|
+
// Clear storage and metadata
|
|
198
|
+
this.storage.delete(promptId);
|
|
199
|
+
this.metadata.delete(promptId);
|
|
200
|
+
return {
|
|
201
|
+
success: true,
|
|
202
|
+
keysDeleted,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Get all keys stored in a specific prompt namespace
|
|
207
|
+
*/
|
|
208
|
+
async _tool_get_prompt_keys(request) {
|
|
209
|
+
const { promptId } = request.params;
|
|
210
|
+
// Validate required parameter
|
|
211
|
+
if (!promptId || typeof promptId !== 'string') {
|
|
212
|
+
throw new Error('promptId is required and must be a string');
|
|
213
|
+
}
|
|
214
|
+
const promptStorage = this.storage.get(promptId);
|
|
215
|
+
if (!promptStorage) {
|
|
216
|
+
return {
|
|
217
|
+
keys: [],
|
|
218
|
+
count: 0,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
const keys = Array.from(promptStorage.keys());
|
|
222
|
+
this.updateLastAccessed(promptId);
|
|
223
|
+
return {
|
|
224
|
+
keys,
|
|
225
|
+
count: keys.length,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Get statistics for a specific prompt namespace
|
|
230
|
+
*/
|
|
231
|
+
async _tool_get_prompt_stats(request) {
|
|
232
|
+
const { promptId } = request.params;
|
|
233
|
+
// Validate required parameter
|
|
234
|
+
if (!promptId || typeof promptId !== 'string') {
|
|
235
|
+
throw new Error('promptId is required and must be a string');
|
|
236
|
+
}
|
|
237
|
+
const promptStorage = this.storage.get(promptId);
|
|
238
|
+
const meta = this.metadata.get(promptId);
|
|
239
|
+
if (!promptStorage || !meta) {
|
|
240
|
+
return {
|
|
241
|
+
promptId,
|
|
242
|
+
keyCount: 0,
|
|
243
|
+
lastAccessed: 0,
|
|
244
|
+
exists: false,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
this.updateLastAccessed(promptId);
|
|
248
|
+
return {
|
|
249
|
+
promptId,
|
|
250
|
+
keyCount: promptStorage.size,
|
|
251
|
+
lastAccessed: meta.lastAccessed,
|
|
252
|
+
exists: true,
|
|
253
|
+
createdAt: meta.createdAt,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Cleanup resources on stop
|
|
258
|
+
*/
|
|
259
|
+
async stop() {
|
|
260
|
+
if (this.cleanupTimer) {
|
|
261
|
+
clearInterval(this.cleanupTimer);
|
|
262
|
+
this.cleanupTimer = undefined;
|
|
263
|
+
}
|
|
264
|
+
await super.stop();
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Update last accessed timestamp for a prompt
|
|
268
|
+
*/
|
|
269
|
+
updateLastAccessed(promptId) {
|
|
270
|
+
const meta = this.metadata.get(promptId);
|
|
271
|
+
if (meta) {
|
|
272
|
+
meta.lastAccessed = Date.now();
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Clean up prompts that haven't been accessed within TTL
|
|
277
|
+
*/
|
|
278
|
+
cleanupExpiredPrompts() {
|
|
279
|
+
if (!this.config.promptTTL)
|
|
280
|
+
return;
|
|
281
|
+
const now = Date.now();
|
|
282
|
+
const expiredPrompts = [];
|
|
283
|
+
for (const [promptId, meta] of this.metadata.entries()) {
|
|
284
|
+
if (now - meta.lastAccessed > this.config.promptTTL) {
|
|
285
|
+
expiredPrompts.push(promptId);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
if (expiredPrompts.length > 0) {
|
|
289
|
+
for (const promptId of expiredPrompts) {
|
|
290
|
+
this.storage.delete(promptId);
|
|
291
|
+
this.metadata.delete(promptId);
|
|
292
|
+
}
|
|
293
|
+
this.logger.info('Cleaned up expired prompts', {
|
|
294
|
+
count: expiredPrompts.length,
|
|
295
|
+
promptIds: expiredPrompts,
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Evict the oldest prompt when max limit is reached
|
|
301
|
+
*/
|
|
302
|
+
evictOldestPrompt() {
|
|
303
|
+
let oldestPromptId;
|
|
304
|
+
let oldestTime = Infinity;
|
|
305
|
+
for (const [promptId, meta] of this.metadata.entries()) {
|
|
306
|
+
if (meta.lastAccessed < oldestTime) {
|
|
307
|
+
oldestTime = meta.lastAccessed;
|
|
308
|
+
oldestPromptId = promptId;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
if (oldestPromptId) {
|
|
312
|
+
this.storage.delete(oldestPromptId);
|
|
313
|
+
this.metadata.delete(oldestPromptId);
|
|
314
|
+
this.logger.info('Evicted oldest prompt', {
|
|
315
|
+
promptId: oldestPromptId,
|
|
316
|
+
lastAccessed: oldestTime,
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-seeder.spec.d.ts","sourceRoot":"","sources":["../../test/prompt-seeder.spec.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC"}
|