@lupaflow/plugins 0.1.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/package.json +31 -0
- package/src/hooks.ts +61 -0
- package/src/index.ts +10 -0
- package/src/interface.ts +18 -0
- package/src/loader.ts +67 -0
- package/tsconfig.json +8 -0
- package/tsup.config.ts +9 -0
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lupaflow/plugins",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"module": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"require": "./dist/index.js",
|
|
16
|
+
"import": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsup",
|
|
21
|
+
"dev": "tsup --watch"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@lupaflow/core": "workspace:*",
|
|
25
|
+
"@lupaflow/types": "workspace:*"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"tsup": "^8.3.0",
|
|
29
|
+
"typescript": "^5.6.0"
|
|
30
|
+
}
|
|
31
|
+
}
|
package/src/hooks.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { pluginManager } from "./loader"
|
|
2
|
+
|
|
3
|
+
export function runBeforeAgentRunHooks(config: Record<string, unknown>): Record<string, unknown> {
|
|
4
|
+
let result = { ...config }
|
|
5
|
+
for (const plugin of pluginManager.list()) {
|
|
6
|
+
if (plugin.hooks?.beforeAgentRun) {
|
|
7
|
+
result = plugin.hooks.beforeAgentRun(result)
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
return result
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function runAfterAgentRunHooks(result: unknown): unknown {
|
|
14
|
+
let output = result
|
|
15
|
+
for (const plugin of pluginManager.list()) {
|
|
16
|
+
if (plugin.hooks?.afterAgentRun) {
|
|
17
|
+
output = plugin.hooks.afterAgentRun(output)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return output
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function runBeforeToolCallHooks(tool: string, args: Record<string, unknown>): Record<string, unknown> {
|
|
24
|
+
let result = { ...args }
|
|
25
|
+
for (const plugin of pluginManager.list()) {
|
|
26
|
+
if (plugin.hooks?.beforeToolCall) {
|
|
27
|
+
result = plugin.hooks.beforeToolCall(tool, result)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return result
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function runAfterToolCallHooks(result: unknown): unknown {
|
|
34
|
+
let output = result
|
|
35
|
+
for (const plugin of pluginManager.list()) {
|
|
36
|
+
if (plugin.hooks?.afterToolCall) {
|
|
37
|
+
output = plugin.hooks.afterToolCall(output)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return output
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function runBeforeProviderCallHooks(provider: string, request: Record<string, unknown>): Record<string, unknown> {
|
|
44
|
+
let result = { ...request }
|
|
45
|
+
for (const plugin of pluginManager.list()) {
|
|
46
|
+
if (plugin.hooks?.beforeProviderCall) {
|
|
47
|
+
result = plugin.hooks.beforeProviderCall(provider, result)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return result
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function runAfterProviderCallHooks(response: Record<string, unknown>): Record<string, unknown> {
|
|
54
|
+
let result = { ...response }
|
|
55
|
+
for (const plugin of pluginManager.list()) {
|
|
56
|
+
if (plugin.hooks?.afterProviderCall) {
|
|
57
|
+
result = plugin.hooks.afterProviderCall(result)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return result
|
|
61
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { pluginManager } from "./loader"
|
|
2
|
+
export type { LupaPlugin } from "./interface"
|
|
3
|
+
export {
|
|
4
|
+
runBeforeAgentRunHooks,
|
|
5
|
+
runAfterAgentRunHooks,
|
|
6
|
+
runBeforeToolCallHooks,
|
|
7
|
+
runAfterToolCallHooks,
|
|
8
|
+
runBeforeProviderCallHooks,
|
|
9
|
+
runAfterProviderCallHooks,
|
|
10
|
+
} from "./hooks"
|
package/src/interface.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { LupaEvent } from "@lupaflow/types"
|
|
2
|
+
|
|
3
|
+
export interface LupaPlugin {
|
|
4
|
+
name: string
|
|
5
|
+
version: string
|
|
6
|
+
description?: string
|
|
7
|
+
onLoad?: () => void | Promise<void>
|
|
8
|
+
onUnload?: () => void | Promise<void>
|
|
9
|
+
onEvent?: (event: LupaEvent) => void | Promise<void>
|
|
10
|
+
hooks?: {
|
|
11
|
+
beforeAgentRun?: (config: Record<string, unknown>) => Record<string, unknown>
|
|
12
|
+
afterAgentRun?: (result: unknown) => unknown
|
|
13
|
+
beforeToolCall?: (tool: string, args: Record<string, unknown>) => Record<string, unknown>
|
|
14
|
+
afterToolCall?: (result: unknown) => unknown
|
|
15
|
+
beforeProviderCall?: (provider: string, request: Record<string, unknown>) => Record<string, unknown>
|
|
16
|
+
afterProviderCall?: (response: Record<string, unknown>) => Record<string, unknown>
|
|
17
|
+
}
|
|
18
|
+
}
|
package/src/loader.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { readdir } from "fs/promises"
|
|
2
|
+
import { join } from "path"
|
|
3
|
+
import type { LupaPlugin } from "./interface"
|
|
4
|
+
import { globalEventBus } from "@lupaflow/core"
|
|
5
|
+
|
|
6
|
+
class PluginManager {
|
|
7
|
+
private plugins: Map<string, LupaPlugin> = new Map()
|
|
8
|
+
private loaded = false
|
|
9
|
+
|
|
10
|
+
async load(plugin: LupaPlugin): Promise<void> {
|
|
11
|
+
if (this.plugins.has(plugin.name)) {
|
|
12
|
+
throw new Error(`Plugin "${plugin.name}" is already loaded`)
|
|
13
|
+
}
|
|
14
|
+
this.plugins.set(plugin.name, plugin)
|
|
15
|
+
|
|
16
|
+
if (plugin.onEvent) {
|
|
17
|
+
globalEventBus.onAny((event) => plugin.onEvent!(event))
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (plugin.onLoad) {
|
|
21
|
+
await plugin.onLoad()
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async unload(name: string): Promise<void> {
|
|
26
|
+
const plugin = this.plugins.get(name)
|
|
27
|
+
if (!plugin) throw new Error(`Plugin "${name}" not found`)
|
|
28
|
+
if (plugin.onUnload) await plugin.onUnload()
|
|
29
|
+
this.plugins.delete(name)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async loadFromDirectory(dir: string): Promise<void> {
|
|
33
|
+
try {
|
|
34
|
+
const files = await readdir(dir)
|
|
35
|
+
for (const file of files) {
|
|
36
|
+
if (file.endsWith(".js") || file.endsWith(".mjs")) {
|
|
37
|
+
try {
|
|
38
|
+
const mod = await import(join(dir, file))
|
|
39
|
+
if (mod.default && mod.default.name) {
|
|
40
|
+
await this.load(mod.default)
|
|
41
|
+
}
|
|
42
|
+
} catch { /* ignore */ }
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
} catch { /* ignore */ }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
get(name: string): LupaPlugin | undefined {
|
|
49
|
+
return this.plugins.get(name)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
list(): LupaPlugin[] {
|
|
53
|
+
return Array.from(this.plugins.values())
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
isLoaded(name: string): boolean {
|
|
57
|
+
return this.plugins.has(name)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async unloadAll(): Promise<void> {
|
|
61
|
+
for (const [name] of this.plugins) {
|
|
62
|
+
await this.unload(name)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export const pluginManager = new PluginManager()
|
package/tsconfig.json
ADDED