diff --git a/src/backend/src/filesystem/FSNodeContext.js b/src/backend/src/filesystem/FSNodeContext.js index b2ce41d9b..ad80f4778 100644 --- a/src/backend/src/filesystem/FSNodeContext.js +++ b/src/backend/src/filesystem/FSNodeContext.js @@ -841,7 +841,7 @@ module.exports = class FSNodeContext { const info = this.services.get('information'); if ( !this.uid && !this.entry.uuid ) { - this.log.noticeme(`whats even happening!?!? ${ + console.warn(`Potential Error in getSafeEntry with no uid or entry.uuid ${ this.selector.describe() } ${ JSON.stringify(this.entry, null, ' ')}`); } diff --git a/src/backend/src/filesystem/hl_operations/hl_readdir.js b/src/backend/src/filesystem/hl_operations/hl_readdir.js index 9b37b00ad..748d717d6 100644 --- a/src/backend/src/filesystem/hl_operations/hl_readdir.js +++ b/src/backend/src/filesystem/hl_operations/hl_readdir.js @@ -76,7 +76,6 @@ class HLReadDir extends HLFilesystemOperation { await subject.getUserPart() !== user.username && await subject.isUserDirectory() ) { - this.log.noticeme('THIS HAPPEN'); const ll_readshares = new LLReadShares(); children = await ll_readshares.run(this.values); } else { diff --git a/src/backend/src/filesystem/hl_operations/hl_write.js b/src/backend/src/filesystem/hl_operations/hl_write.js index acc1e7cf3..589538a66 100644 --- a/src/backend/src/filesystem/hl_operations/hl_write.js +++ b/src/backend/src/filesystem/hl_operations/hl_write.js @@ -141,7 +141,6 @@ class HLWrite extends HLFilesystemOperation { }); } const path = parent.selector.value; - this.log.noticeme('EXPECTED PATH', { path }); const tree_op = new MkTree(); await tree_op.run({ parent: await fs.node(new RootNodeSelector()), diff --git a/src/backend/src/helpers.js b/src/backend/src/helpers.js index 078be44c1..a9785187e 100644 --- a/src/backend/src/helpers.js +++ b/src/backend/src/helpers.js @@ -399,8 +399,7 @@ async function change_username (user_id, new_username) { 'WHERE `user_id` = ? AND parent_uid IS NULL LIMIT 1', [new_username, `/${ new_username}`, user_id]); - const log = services.get('log-service').create('change_username'); - log.noticeme(`User ${old_username} changed username to ${new_username}`); + console.log(`User ${old_username} changed username to ${new_username}`); await services.get('filesystem').update_child_paths(`/${old_username}`, `/${new_username}`, user_id); invalidate_cached_user_by_id(user_id); @@ -734,8 +733,6 @@ async function getDescendantsHelper (path, user, depth, return_thumbnail = false let rows = await db.read(`SELECT root_dir_id FROM subdomains WHERE root_dir_id IN (${qmarks}) AND user_id=?`, [...ids, user.id]); - log.debug('rows???', rows); - const websiteMap = {}; for ( const row of rows ) websiteMap[row.root_dir_id] = true; diff --git a/src/backend/src/modules/apps/RecommendedAppsService.js b/src/backend/src/modules/apps/RecommendedAppsService.js index 3e072ea0c..828bbfcb8 100644 --- a/src/backend/src/modules/apps/RecommendedAppsService.js +++ b/src/backend/src/modules/apps/RecommendedAppsService.js @@ -80,7 +80,7 @@ class RecommendedAppsService extends BaseService { svc_event.on('apps.invalidate', (_, { app }) => { const sizes = svc_appIcon.get_sizes(); - this.log.noticeme('Invalidating recommended apps', { app, sizes }); + console.log('Invalidating recommended apps', { app, sizes }); // If it's a single-app invalidation, only invalidate if the // app is in the list of recommended apps diff --git a/src/backend/src/modules/broadcast/BroadcastService.js b/src/backend/src/modules/broadcast/BroadcastService.js index 0cbdadafa..a7fd23c43 100644 --- a/src/backend/src/modules/broadcast/BroadcastService.js +++ b/src/backend/src/modules/broadcast/BroadcastService.js @@ -85,7 +85,7 @@ class BroadcastService extends BaseService { conn.channels.message.on(({ key, data, meta }) => { if ( meta.from_outside ) { - this.log.noticeme('possible over-sending'); + console.warn('possible over-sending'); return; } diff --git a/src/backend/src/modules/core/LogService.js b/src/backend/src/modules/core/LogService.js index 221b90e94..f6b01a03c 100644 --- a/src/backend/src/modules/core/LogService.js +++ b/src/backend/src/modules/core/LogService.js @@ -478,6 +478,7 @@ class LogService extends BaseService { levels: WINSTON_LEVELS, transports: [ new winston.transports.DailyRotateFile({ + level: 'http', filename: `${this.log_directory}/%DATE%.log`, datePattern: 'YYYY-MM-DD', maxSize: '20m', diff --git a/src/backend/src/modules/dns/DNSService.js b/src/backend/src/modules/dns/DNSService.js index 8505c41bf..3fa60c1e4 100644 --- a/src/backend/src/modules/dns/DNSService.js +++ b/src/backend/src/modules/dns/DNSService.js @@ -93,7 +93,6 @@ class DNSService extends BaseService { server.on('close', () => { console.log('Fake DNS server closed'); - this.log.noticeme('Fake DNS server closed'); }); server.on('request', (request, response, rinfo) => { diff --git a/src/backend/src/services/ReferralCodeService.js b/src/backend/src/services/ReferralCodeService.js index 33a9bf296..bd3da382c 100644 --- a/src/backend/src/services/ReferralCodeService.js +++ b/src/backend/src/services/ReferralCodeService.js @@ -90,7 +90,7 @@ class ReferralCodeService extends BaseService { let last_error = null; for ( let i = 0 ; i < TRIES; i++ ) { - this.log.noticeme(`trying referral code ${referral_code}`); + this.log.debug(`trying referral code ${referral_code}`); if ( i > 0 ) { rng = seedrandom(`gen1-${user.id}-${++iteration}`); referral_code = generate_random_code(8, { rng }); diff --git a/src/backend/src/services/UserService.js b/src/backend/src/services/UserService.js index c99154ff7..217505c32 100644 --- a/src/backend/src/services/UserService.js +++ b/src/backend/src/services/UserService.js @@ -57,8 +57,6 @@ class UserService extends BaseService { // used to be called: generate_system_fsentries async generate_default_fsentries ({ user }) { - this.log.noticeme('YES THIS WAS USED'); - // Note: The comment below is outdated as we now do parallel writes for // all filesystem operations. However, there may still be some // performance hit so this requires further investigation. diff --git a/src/backend/src/services/WispService.js b/src/backend/src/services/WispService.js index 1fb0d8d3f..06bc53fa8 100644 --- a/src/backend/src/services/WispService.js +++ b/src/backend/src/services/WispService.js @@ -103,7 +103,6 @@ class WispService extends BaseService { }; await svc_event.emit('wisp.get-policy', event); if ( ! event.allow ) { - this.log.noticeme('here'); throw svc_apiError.create('forbidden'); } diff --git a/src/backend/src/services/database/SqliteDatabaseAccessService.js b/src/backend/src/services/database/SqliteDatabaseAccessService.js index 313eb51bb..dcb683f02 100644 --- a/src/backend/src/services/database/SqliteDatabaseAccessService.js +++ b/src/backend/src/services/database/SqliteDatabaseAccessService.js @@ -199,15 +199,14 @@ class SqliteDatabaseAccessService extends BaseDatabaseAccessService { } if ( upgrade_files.length > 0 ) { - this.log.noticeme(`Database out of date: ${this.config.path}`); - this.log.noticeme(`UPGRADING DATABASE: ${user_version} -> ${TARGET_VERSION}`); - this.log.noticeme(`${upgrade_files.length} .sql files to apply`); + console.debug(`Database out of date: ${this.config.path}`); + console.debug(`UPGRADING DATABASE: ${user_version} -> ${TARGET_VERSION}`); + console.debug(`${upgrade_files.length} .sql files to apply`); const sql_files = upgrade_files.map(p => path_.join(__dirname, 'sqlite_setup', p)); const fs = require('fs'); for ( const filename of sql_files ) { const basename = path_.basename(filename); - this.log.noticeme(`applying ${basename}`); const contents = fs.readFileSync(filename, 'utf8'); switch ( path_.extname(filename) ) { case '.sql': diff --git a/src/backend/src/services/drivers/CoercionService.js b/src/backend/src/services/drivers/CoercionService.js index 95e5eccd1..91605abef 100644 --- a/src/backend/src/services/drivers/CoercionService.js +++ b/src/backend/src/services/drivers/CoercionService.js @@ -64,7 +64,7 @@ class CoercionService extends BaseService { content_type: 'image', }, coerce: async typed_value => { - this.log.noticeme('coercion is running!'); + console.debug('coercion is running!'); const response = await (async () => { try { @@ -129,8 +129,6 @@ class CoercionService extends BaseService { content_type: 'image', }, coerce: async typed_value => { - this.log.noticeme('data URL coercion is running!'); - const data_url = typed_value.value; const data = data_url.split(',')[1]; const buffer = Buffer.from(data, 'base64'); diff --git a/src/backend/src/services/file-cache/FileCacheService.js b/src/backend/src/services/file-cache/FileCacheService.js index 954f0ee09..e58b30bd9 100644 --- a/src/backend/src/services/file-cache/FileCacheService.js +++ b/src/backend/src/services/file-cache/FileCacheService.js @@ -198,13 +198,10 @@ class FileCacheService extends BaseService { } if ( tracker.phase === FileTracker.PHASE_PRECACHE ) { - this.log.noticeme('obtained from precache'); return this.precache.get(await fsNode.get('uid')); } if ( tracker.phase === FileTracker.PHASE_DISK ) { - this.log.noticeme('obtained from disk'); - const { fs } = this.modules; const path = this._get_path(await fsNode.get('uid')); try { diff --git a/src/backend/src/services/thumbnails/HTTPThumbnailService.js b/src/backend/src/services/thumbnails/HTTPThumbnailService.js index 1450d9091..66777b6ef 100644 --- a/src/backend/src/services/thumbnails/HTTPThumbnailService.js +++ b/src/backend/src/services/thumbnails/HTTPThumbnailService.js @@ -206,7 +206,6 @@ class HTTPThumbnailService extends BaseService { * It uses axios to make a ping request to the thumbnail service. */ svc_serverHealth.add_check('thumbnail-ping', async () => { - this.log.noticeme('THUMBNAIL PING'); await axios.request({ method: 'get', url: `${this.host_}/ping`, @@ -351,8 +350,8 @@ class HTTPThumbnailService extends BaseService { const results = resp.data; - this.log.noticeme('response?', { resp }); - this.log.noticeme('data?', { data: resp.data }); + console.debug('response?', { resp }); + console.debug('data?', { data: resp.data }); if ( results.length !== queue.length ) { this.log.error('Thumbnail service returned wrong number of results'); @@ -362,8 +361,6 @@ class HTTPThumbnailService extends BaseService { for ( let i = 0 ; i < queue.length ; i++ ) { const result = results[i]; const job = queue[i]; - - this.log.noticeme('result?', { result }); job.resolve(result.encoded && `data:image/png;base64,${result.encoded}`); } diff --git a/src/puter-js/src/lib/filesystem/CacheFS.js b/src/puter-js/src/lib/filesystem/CacheFS.js index 3370a50af..fdb5bfd99 100644 --- a/src/puter-js/src/lib/filesystem/CacheFS.js +++ b/src/puter-js/src/lib/filesystem/CacheFS.js @@ -186,7 +186,6 @@ export class CachedFilesystem extends ProxyFilesystem { l.unlock(); } - console.log('STATS????', stats); if ( stats ) { return stats; } diff --git a/tools/comment-writer/main.js b/tools/comment-writer/main.js index b618d835e..7aacd661c 100644 --- a/tools/comment-writer/main.js +++ b/tools/comment-writer/main.js @@ -1,18 +1,18 @@ /* * Copyright (C) 2024-present Puter Technologies Inc. - * + * * This file is part of Puter. - * + * * Puter is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. - * + * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ @@ -70,20 +70,16 @@ const models_to_try = [ // } ]; - const axi = axios.create({ - httpsAgent: new https.Agent({ - rejectUnauthorized: false - }) + httpsAgent: new https.Agent({ + rejectUnauthorized: false, + }), }); const cwd = process.cwd(); const context = {}; -context.config = JSON.parse( - fs.readFileSync('config.json') -); - +context.config = JSON.parse(fs.readFileSync('config.json')); /** * @class AI @@ -96,16 +92,15 @@ class AI { constructor (context) { // } - /** * Sends a chat completion request to the Puter API and returns the response message. - * + * * @param {Object} params - The parameters for the completion request * @param {Array} params.messages - Array of message objects to send to the API * @param {Object} params.driver_params - Additional parameters for the driver interface * @returns {Promise} The response message from the API - * + * * Makes a POST request to the configured API endpoint with the provided messages and * driver parameters. Authenticates using the configured auth token and returns the * message content from the response. @@ -120,12 +115,12 @@ class AI { }, }, { headers: { - "Content-Type": "application/json", + 'Content-Type': 'application/json', Origin: 'https://puter.local', Authorization: `Bearer ${context.config.auth_token}`, }, }); - + return response.data.result.message; } } @@ -142,7 +137,7 @@ const ai_message_to_lines = text => { } } return text.split('\n'); -} +}; /** * @class JavascriptFileProcessor @@ -157,7 +152,7 @@ class JavascriptFileProcessor { this.context = context; this.parameters = parameters; } - + process (lines) { const definitions = []; // Collect definitions by iterating through each line @@ -206,7 +201,7 @@ const js_processor = new JavascriptFileProcessor(context, { name, parent, }; - } + }, }, { name: 'if', @@ -221,7 +216,7 @@ const js_processor = new JavascriptFileProcessor(context, { */ handler: () => { return { type: 'if' }; - } + }, }, { name: 'while', @@ -236,7 +231,7 @@ const js_processor = new JavascriptFileProcessor(context, { */ handler: () => { return { type: 'while' }; - } + }, }, { name: 'for', @@ -248,7 +243,7 @@ const js_processor = new JavascriptFileProcessor(context, { */ handler: () => { return { type: 'for' }; - } + }, }, { name: 'method', @@ -260,7 +255,7 @@ const js_processor = new JavascriptFileProcessor(context, { type: 'method', name, }; - } + }, }, { name: 'method', @@ -279,7 +274,7 @@ const js_processor = new JavascriptFileProcessor(context, { type: 'method', name, }; - } + }, }, { name: 'function', @@ -291,7 +286,7 @@ const js_processor = new JavascriptFileProcessor(context, { scope: 'function', name, }; - } + }, }, { name: 'function', @@ -304,7 +299,7 @@ const js_processor = new JavascriptFileProcessor(context, { name, args: (args ?? '').split(',').map(arg => arg.trim()), }; - } + }, }, { name: 'const', @@ -317,12 +312,11 @@ const js_processor = new JavascriptFileProcessor(context, { name, value, }; - } - } + }, + }, ], }); - /** * Creates a limited view of the code file by showing specific ranges around key lines. * Takes an array of lines and key places (anchors with context ranges) and returns @@ -339,19 +333,19 @@ const create_limited_view = (lines, key_places) => { const b_start = Math.max(0, b.anchor - b.lines_above); return a_start - b_start; }); - + const visible_ranges = []; - + // Create visible ranges for each key place // Create visible ranges for each key place in the limited view for ( const key_place of key_places ) { const anchor = key_place.anchor; const lines_above = key_place.lines_above; const lines_below = key_place.lines_below; - + const start = Math.max(0, anchor - lines_above); const end = Math.min(lines.length, anchor + lines_below); - + visible_ranges.push({ anchor: key_place.anchor, comment: key_place.comment, @@ -359,15 +353,15 @@ const create_limited_view = (lines, key_places) => { end, }); } - + // Merge overlapping visible ranges const merged_ranges = []; - + // Iterate through each visible range and merge overlapping ones for ( const range of visible_ranges ) { range.comments = [{ anchor: range.anchor, - text: range.comment + text: range.comment, }]; // If no merged ranges exist yet, add this range as the first one @@ -375,31 +369,31 @@ const create_limited_view = (lines, key_places) => { merged_ranges.push(range); continue; } - + const last_range = merged_ranges[merged_ranges.length - 1]; - + // Check if the current range overlaps with the last range in merged_ranges if ( last_range.end >= range.start ) { last_range.end = Math.max(last_range.end, range.end); last_range.comments.push({ anchor: range.anchor, - text: range.comment + text: range.comment, }); } else { merged_ranges.push(range); } } - + // Create the limited view, adding line numbers and comments let limited_view = ''; - + let previous_visible_range = null; // Iterate through visible ranges and add line numbers and comments for ( let i = 0 ; i < lines.length ; i++ ) { const line = lines[i]; - + let visible_range = null; - + if ( i === 22 ) debugger; // Iterate through merged ranges to find which range contains the current line @@ -410,14 +404,14 @@ const create_limited_view = (lines, key_places) => { break; } } - + // console.log('visible_range', visible_range, i); - + // Check if this line is visible in the current range if ( visible_range === null ) { continue; } - + // Check if visible range is different from previous range if ( visible_range !== previous_visible_range ) { if ( i !== 0 ) limited_view += '\n'; @@ -433,12 +427,12 @@ const create_limited_view = (lines, key_places) => { } } } - + previous_visible_range = visible_range; - + limited_view += `${i + 1}: ${line}\n`; } - + return limited_view; }; @@ -446,7 +440,7 @@ const create_limited_view = (lines, key_places) => { * Inject comments into lines * @param {*} lines - Array of original file lines * @param {*} comments - Array of comment objects - * + * * Comment object structure: * { * position: 0, // Position in lines array @@ -463,25 +457,24 @@ const create_limited_view = (lines, key_places) => { const inject_comments = (lines, comments) => { // Sort comments in reverse order comments.sort((a, b) => b.position - a.position); - + // Inject comments into lines // Inject comments into lines array based on comment objects for ( const comment of comments ) { // AI might have been stupid and added a comment above a blank line, // despite that we told it not to do that. So we need to adjust the position. // Adjust comment position if it would be above a blank line - while ( comment.position < lines.length && ! lines[comment.position].trim() ) { + while ( comment.position < lines.length && !lines[comment.position].trim() ) { comment.position++; } - + const indentation = lines[comment.position].match(/^\s*/)[0]; - console.log('????', comment.position, lines[comment.position], '|' + indentation + '|'); const comment_lines = comment.lines.map(line => `${indentation}${line}`); lines.splice(comment.position, 0, ...comment_lines); - + // If the first line of the comment lines starts with '/*`, ensure there is // a blank line above it. - + // Check if comment starts with '/*' to ensure proper spacing above JSDoc comments if ( comment_lines[0].trim().startsWith('/*') ) { // Check if comment starts with JSDoc style to add blank line above @@ -490,19 +483,18 @@ const inject_comments = (lines, comments) => { } } } -} +}; const textutil = {}; textutil.format = text => { return wrap(dedent(text), { width: 80, - indent: '| ' + indent: '| ', }); }; context.ai = new AI(context); - /** * Creates a new AI instance for handling chat completions * @param {Object} context - The application context object @@ -530,22 +522,22 @@ const main = async () => { Hello! I am the Puter Comment Writer, an AI designed to enhance your code files with meaningful comments. As you walk through your source files, I will provide insights, explanations, and clarifications tailored to the specific content of each file. You can choose to accept my comments, request edits for more clarity or detail, or even reject them if they don't meet your needs. Each time we move to a new file, I'll start fresh with a clean context, ready to help you improve your code documentation. Let's get started! `); console.log(intro); - + console.log(`Enter a path relative to: ${process.cwd()}`); console.log('arg?', process.argv[2]); let rootpath = process.argv[2] ? { path: process.argv[2] } : await enq.prompt({ type: 'input', name: 'path', - message: 'Enter path:' + message: 'Enter path:', }); - + rootpath = path_.resolve(rootpath.path); console.log('rootpath:', rootpath); const walk_iter = walk({ excludes: FILE_EXCLUDES, }, rootpath); - + let i = 0, limit = undefined; for await ( const value of walk_iter ) { if ( limit !== undefined && i >= limit ) break; @@ -562,7 +554,7 @@ const main = async () => { } console.log('file:', value.path); const lines = fs.readFileSync(value.path, 'utf8').split('\n'); - + let metadata, has_metadata_line = false; // Check if metadata line exists and parse it if ( lines[0].startsWith('// METADATA // ') ) { @@ -574,14 +566,14 @@ const main = async () => { continue; } } else metadata = {}; - + let refs = null; // Check if there are any references in the metadata if ( metadata['ai-refs'] ) { const relative_file_paths = metadata['ai-refs']; // name of file is the key, value is the contents const references = {}; - + let n = 0; // Iterate through each relative file path in the metadata for ( const relative_file_path of relative_file_paths ) { @@ -590,28 +582,28 @@ const main = async () => { const ref_text = fs.readFileSync(full_path, 'utf8'); references[relative_file_path] = ref_text; } - + // Check if there are any references in the metadata and process them if ( n === 1 ) { refs = dedent(` The following documentation contains relevant information about the code. The code will follow after this documentation. `); - - refs += '\n\n' + dedent(references[Object.keys(references)[0]]); + + refs += `\n\n${ dedent(references[Object.keys(references)[0]])}`; } else if ( n > 2 ) { refs = dedent(` The following documentation contains relevant information about the code. The code will follow after a number of documentation files. `); - + // Iterate through each key in the references object for ( const key of Object.keys(references) ) { - refs += '\n\n' + dedent(references[key]); + refs += `\n\n${ dedent(references[key])}`; } } } - + const action = limit === undefined ? await enq.prompt({ type: 'select', name: 'action', @@ -622,15 +614,15 @@ const main = async () => { 'all', 'limit', 'exit', - ] + ], }) : 'generate'; // const action = 'generate'; - + // Check if user wants to exit the program if ( action.action === 'exit' ) { break; } - + // Skip if user chose to exit if ( action.action === 'skip' ) { continue; @@ -640,7 +632,7 @@ const main = async () => { limit = await enq.prompt({ type: 'input', name: 'limit', - message: 'Enter limit:' + message: 'Enter limit:', }); i = 1; limit = Number(limit.limit); @@ -657,13 +649,13 @@ const main = async () => { anchor: 0, lines_above: 2, lines_below: 200, - comment: `Top of file: ${value.path}` + comment: `Top of file: ${value.path}`, }); key_places.push({ anchor: lines.length - 1, lines_above: 200, lines_below: 2, - comment: `Bottom of ${value.name}` + comment: `Bottom of ${value.name}`, }); // Iterate through each definition and add comments based on its type for ( const definition of definitions ) { @@ -671,13 +663,13 @@ const main = async () => { anchor: definition.line, lines_above: 40, lines_below: 40, - comment: `${definition.type}.` + comment: `${definition.type}.`, }); } let limited_view = create_limited_view(lines, key_places); console.log('--- view ---'); console.log(limited_view); - + const comments = []; // comments.push({ // position: 0, @@ -688,7 +680,7 @@ const main = async () => { // definition, // }); // } - + // This was worth a try but the LLM is very bad at this /* const message = await context.ai.complete({ @@ -713,7 +705,7 @@ const main = async () => { console.log('Invalid number:', n); continue; } - + comments.push({ position: n - 1, }); @@ -724,7 +716,7 @@ const main = async () => { for ( const def of definitions ) { console.log('def?', def); let instruction = ''; - + // Check if the line starts with an if statement and has curly braces if ( def.type === 'class' ) { instruction = dedent(` @@ -750,7 +742,7 @@ const main = async () => { notes about its behavior, and any parameters or return values. `); } - + // Check if comment is for a constant definition and set appropriate instruction if ( def.type === 'const' ) { instruction = dedent(` @@ -759,7 +751,7 @@ const main = async () => { The comment should be only one or two lines long, and should use line comments. `); } - + comments.push({ position: def.line, instruction: instruction, @@ -768,7 +760,7 @@ const main = async () => { const driver_params = metadata['ai-params'] ?? models_to_try[Math.floor(Math.random() * models_to_try.length)]; - + // Iterate through each comment object to add comments to the code for ( const comment of comments ) { // This doesn't work very well yet @@ -780,9 +772,9 @@ const main = async () => { content: dedent(` Please only respond with comma-separated number ranges in this format with no surrounding text: 11-21, 25-30, 35-40 - + You may also respond with "none". - + A comment will be added above line ${comment.position} in the code which follows. You are seeing a limited view of the code that includes chunks around interesting lines. Please specify ranges of lines that might provide useful context for this comment. @@ -792,14 +784,14 @@ const main = async () => { } ] }); - + // Check if the comment lines start with '/*' and ensure there's a blank line above it if ( ranges_message.content.trim() !== 'none' ) { const ranges = ranges_message.content.split(',').map(range => { const [ start, end ] = range.split('-').map(n => Number(n)); return { start, end }; }); - + // Iterate through ranges and add key places for each range for ( const range of ranges ) { key_places.push({ @@ -809,79 +801,79 @@ const main = async () => { comment: `Requested range by AI agent: ${range.start}-${range.end}` }); } - + limited_view = create_limited_view(lines, key_places); console.log('--- updated view ---'); console.log(limited_view); } */ - + const prompt = - dedent(` + `${dedent(` Please write a comment to be added above line ${comment.position}. Do not write any surrounding text; just the comment itself. Please include comment markers. If the comment is on a class, function, or method, please use jsdoc style. The code is written in JavaScript. `).trim() + - (refs ? '\n\n' + dedent(refs) : '') + - (comment.instruction ? '\n\n' + dedent(comment.instruction) : '') + - '\n\n' + limited_view + (refs ? `\n\n${ dedent(refs)}` : '') + + (comment.instruction ? `\n\n${ dedent(comment.instruction)}` : '') + }\n\n${ limited_view}` ; - + // console.log('prompt:', prompt); - + const message = await context.ai.complete({ messages: [ { role: 'user', - content: prompt - } + content: prompt, + }, ], driver_params, }); console.log('message:', message); comment.lines = ai_message_to_lines(message.content); - + // Remove leading and trailing blank lines // Remove leading and trailing blank lines from comment lines array - while ( comment.lines.length && ! comment.lines[0].trim() ) { + while ( comment.lines.length && !comment.lines[0].trim() ) { comment.lines.shift(); } // Remove trailing blank lines from comment lines array - while ( comment.lines.length && ! comment.lines[comment.lines.length - 1].trim() ) { + while ( comment.lines.length && !comment.lines[comment.lines.length - 1].trim() ) { comment.lines.pop(); } - + // Remove leading "```" or "```" lines // Remove leading "```" or "```" lines if ( comment.lines[0].startsWith('```') ) { comment.lines.shift(); } - + // Remove trailing "```" lines // Remove trailing "```" lines if present if ( comment.lines[comment.lines.length - 1].startsWith('```') ) { comment.lines.pop(); } - + comment.lines = dedent(comment.lines.join('\n')).split('\n'); } inject_comments(lines, comments); - + console.log('--- lines ---'); console.log(lines); - + // Check if file has metadata line and remove it before adding new metadata if ( has_metadata_line ) { lines.shift(); } - - lines.unshift('// METADATA // ' + JSON.stringify({ + + lines.unshift(`// METADATA // ${ JSON.stringify({ ...metadata, 'ai-commented': driver_params, - })); - + })}`); + // Write the modified file fs.writeFileSync(value.path, lines.join('\n')); }