@llmbridge/plugin-logging 0.0.3

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.
@@ -0,0 +1,28 @@
1
+ import { LLMBridge } from '@llmbridge/core';
2
+
3
+ interface LoggingPluginOptions {
4
+ folder: string;
5
+ }
6
+ declare function generateRandomDigits(length: number): string;
7
+ declare class LoggingPlugin implements LLMBridge.Plugin<void, string, void, void> {
8
+ private options;
9
+ constructor(options: LoggingPluginOptions);
10
+ beforeRun(context: LLMBridge.PluginCompletionContext): Promise<void>;
11
+ afterRun({ response }: {
12
+ response: any;
13
+ }): Promise<void>;
14
+ beforeExec(params: any): Promise<string>;
15
+ afterExec({ beforeResponse, response }: {
16
+ beforeResponse: string;
17
+ response: any;
18
+ }): Promise<void>;
19
+ beforeToolExec(tool: LLMBridge.Tool, counter: number, input: any, context: LLMBridge.PluginCompletionContext): Promise<void>;
20
+ afterToolExec({ response }: {
21
+ response: any;
22
+ }): Promise<void>;
23
+ createLogFiles(requestId: string, type: 'request' | 'response', data: any): void;
24
+ createTxtFile(filePath: string, data: any): void;
25
+ objectToTxt(obj: any, prefix?: string): string;
26
+ }
27
+
28
+ export { LoggingPlugin, type LoggingPluginOptions, generateRandomDigits };
@@ -0,0 +1,28 @@
1
+ import { LLMBridge } from '@llmbridge/core';
2
+
3
+ interface LoggingPluginOptions {
4
+ folder: string;
5
+ }
6
+ declare function generateRandomDigits(length: number): string;
7
+ declare class LoggingPlugin implements LLMBridge.Plugin<void, string, void, void> {
8
+ private options;
9
+ constructor(options: LoggingPluginOptions);
10
+ beforeRun(context: LLMBridge.PluginCompletionContext): Promise<void>;
11
+ afterRun({ response }: {
12
+ response: any;
13
+ }): Promise<void>;
14
+ beforeExec(params: any): Promise<string>;
15
+ afterExec({ beforeResponse, response }: {
16
+ beforeResponse: string;
17
+ response: any;
18
+ }): Promise<void>;
19
+ beforeToolExec(tool: LLMBridge.Tool, counter: number, input: any, context: LLMBridge.PluginCompletionContext): Promise<void>;
20
+ afterToolExec({ response }: {
21
+ response: any;
22
+ }): Promise<void>;
23
+ createLogFiles(requestId: string, type: 'request' | 'response', data: any): void;
24
+ createTxtFile(filePath: string, data: any): void;
25
+ objectToTxt(obj: any, prefix?: string): string;
26
+ }
27
+
28
+ export { LoggingPlugin, type LoggingPluginOptions, generateRandomDigits };
package/dist/index.js ADDED
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ LoggingPlugin: () => LoggingPlugin,
34
+ generateRandomDigits: () => generateRandomDigits
35
+ });
36
+ module.exports = __toCommonJS(index_exports);
37
+
38
+ // src/logging.ts
39
+ var import_path = __toESM(require("path"));
40
+ var import_fs = __toESM(require("fs"));
41
+ var import_crypto = require("crypto");
42
+ var import_moment = __toESM(require("moment"));
43
+ function generateRandomDigits(length) {
44
+ return (0, import_crypto.randomBytes)(Math.ceil(length / 2)).toString("hex").slice(0, length);
45
+ }
46
+ var LoggingPlugin = class {
47
+ constructor(options) {
48
+ this.options = options;
49
+ }
50
+ async beforeRun(context) {
51
+ console.log("run", context.model);
52
+ }
53
+ async afterRun({ response }) {
54
+ const lastResponsePath = import_path.default.join(this.options.folder, "last_response.json");
55
+ import_fs.default.writeFileSync(lastResponsePath, JSON.stringify(response, null, 2));
56
+ }
57
+ async beforeExec(params) {
58
+ const requestId = generateRandomDigits(4);
59
+ this.createLogFiles(requestId, "request", params);
60
+ return requestId;
61
+ }
62
+ async afterExec({ beforeResponse, response }) {
63
+ this.createLogFiles(beforeResponse, "response", response);
64
+ }
65
+ async beforeToolExec(tool, counter, input, context) {
66
+ console.log(`run (${counter + 1}/${context.options.tools?.usesLimit}) tool ${tool.name}`, input);
67
+ }
68
+ async afterToolExec({ response }) {
69
+ console.log(`tool response`, response);
70
+ }
71
+ createLogFiles(requestId, type, data) {
72
+ const currentDate = (0, import_moment.default)();
73
+ const dateString = currentDate.format("YYYY_MM_DD");
74
+ const timeString = currentDate.format("YYYY_MM_DD_HH_mm_ss");
75
+ const dailyDir = import_path.default.join(this.options.folder, dateString);
76
+ if (!import_fs.default.existsSync(dailyDir)) {
77
+ import_fs.default.mkdirSync(dailyDir, { recursive: true });
78
+ }
79
+ const fileName = `${timeString}_${requestId}.${type}.json`;
80
+ const filePath = import_path.default.join(dailyDir, fileName);
81
+ import_fs.default.writeFileSync(filePath, JSON.stringify(data, null, 2));
82
+ if (type === "request") {
83
+ this.createTxtFile(filePath, data);
84
+ }
85
+ }
86
+ createTxtFile(filePath, data) {
87
+ const txtContent = this.objectToTxt(data);
88
+ const txtFilePath = filePath.replace(".json", ".txt");
89
+ import_fs.default.writeFileSync(txtFilePath, txtContent);
90
+ }
91
+ objectToTxt(obj, prefix = "") {
92
+ let result = "";
93
+ for (const [key, value] of Object.entries(obj)) {
94
+ const newPrefix = prefix ? `${prefix}${key}` : key;
95
+ if (typeof value === "object" && value !== null) {
96
+ result += `[${newPrefix}]
97
+ ${this.objectToTxt(value, `${newPrefix}.`)}
98
+ `;
99
+ } else {
100
+ result += `[${newPrefix}]
101
+ ${value}
102
+
103
+ `;
104
+ }
105
+ }
106
+ return result;
107
+ }
108
+ };
109
+ // Annotate the CommonJS export names for ESM import in node:
110
+ 0 && (module.exports = {
111
+ LoggingPlugin,
112
+ generateRandomDigits
113
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,75 @@
1
+ // src/logging.ts
2
+ import path from "path";
3
+ import fs from "fs";
4
+ import { randomBytes } from "crypto";
5
+ import moment from "moment";
6
+ function generateRandomDigits(length) {
7
+ return randomBytes(Math.ceil(length / 2)).toString("hex").slice(0, length);
8
+ }
9
+ var LoggingPlugin = class {
10
+ constructor(options) {
11
+ this.options = options;
12
+ }
13
+ async beforeRun(context) {
14
+ console.log("run", context.model);
15
+ }
16
+ async afterRun({ response }) {
17
+ const lastResponsePath = path.join(this.options.folder, "last_response.json");
18
+ fs.writeFileSync(lastResponsePath, JSON.stringify(response, null, 2));
19
+ }
20
+ async beforeExec(params) {
21
+ const requestId = generateRandomDigits(4);
22
+ this.createLogFiles(requestId, "request", params);
23
+ return requestId;
24
+ }
25
+ async afterExec({ beforeResponse, response }) {
26
+ this.createLogFiles(beforeResponse, "response", response);
27
+ }
28
+ async beforeToolExec(tool, counter, input, context) {
29
+ console.log(`run (${counter + 1}/${context.options.tools?.usesLimit}) tool ${tool.name}`, input);
30
+ }
31
+ async afterToolExec({ response }) {
32
+ console.log(`tool response`, response);
33
+ }
34
+ createLogFiles(requestId, type, data) {
35
+ const currentDate = moment();
36
+ const dateString = currentDate.format("YYYY_MM_DD");
37
+ const timeString = currentDate.format("YYYY_MM_DD_HH_mm_ss");
38
+ const dailyDir = path.join(this.options.folder, dateString);
39
+ if (!fs.existsSync(dailyDir)) {
40
+ fs.mkdirSync(dailyDir, { recursive: true });
41
+ }
42
+ const fileName = `${timeString}_${requestId}.${type}.json`;
43
+ const filePath = path.join(dailyDir, fileName);
44
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2));
45
+ if (type === "request") {
46
+ this.createTxtFile(filePath, data);
47
+ }
48
+ }
49
+ createTxtFile(filePath, data) {
50
+ const txtContent = this.objectToTxt(data);
51
+ const txtFilePath = filePath.replace(".json", ".txt");
52
+ fs.writeFileSync(txtFilePath, txtContent);
53
+ }
54
+ objectToTxt(obj, prefix = "") {
55
+ let result = "";
56
+ for (const [key, value] of Object.entries(obj)) {
57
+ const newPrefix = prefix ? `${prefix}${key}` : key;
58
+ if (typeof value === "object" && value !== null) {
59
+ result += `[${newPrefix}]
60
+ ${this.objectToTxt(value, `${newPrefix}.`)}
61
+ `;
62
+ } else {
63
+ result += `[${newPrefix}]
64
+ ${value}
65
+
66
+ `;
67
+ }
68
+ }
69
+ return result;
70
+ }
71
+ };
72
+ export {
73
+ LoggingPlugin,
74
+ generateRandomDigits
75
+ };
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@llmbridge/plugin-logging",
3
+ "version": "0.0.3",
4
+ "description": "Logging plugin for LLMBridge",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "scripts": {
9
+ "build": "pnpm clean && tsup src/index.ts --format cjs,esm --dts",
10
+ "test": "vitest run",
11
+ "clean": "rm -rf dist"
12
+ },
13
+ "keywords": [
14
+ "llm",
15
+ "ai",
16
+ "logging"
17
+ ],
18
+ "files": [
19
+ "dist",
20
+ "README.md"
21
+ ],
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "dependencies": {
26
+ },
27
+ "peerDependencies": {
28
+ "@llmbridge/core": "^0.0.3",
29
+ "moment": "^2.29.0"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^18.11.9",
33
+ "typescript": "^5.7.3",
34
+ "tsup": "^8.4.0",
35
+ "vitest": "^3.0.7"
36
+ },
37
+ "author": "",
38
+ "license": "MIT"
39
+ }