diff --git a/.pdd b/.pdd index b8e356c4..01440098 100644 --- a/.pdd +++ b/.pdd @@ -1,6 +1,6 @@ --source=. --verbose ---exclude src/pdd-prompt.ts +--exclude src/prompts/pdd-prompt.ts --exclude target/** --exclude xargs/** --rule min-words:20 diff --git a/README.md b/README.md index 7ac053e8..da59dd63 100644 --- a/README.md +++ b/README.md @@ -134,10 +134,26 @@ format using [JSON Packing Method](#json-packing-method): #### Cap Top 3 Some analysis results contains many problems. +Consider this example: + +```json +{ + "size": 6, + "problems": [ + "1. Lack of a clear description: The report lacks a clear and concise description of the problem. It simply states there are typos but does not specify what the typos are or how they impact the system.", + "2. Missing steps to reproduce: There are no steps provided to reproduce the issue. This makes it difficult for developers to identify if they have fixed the issue correctly.", + "3. No severity level: The severity level of the issue is not stated. This is important information for developers to prioritize how soon the issue should be resolved.", + "4. Lack of environment details: The report does not mention which environment this issue occurs in (e.g., which version of the software, which operating system).", + "5. Use of shorthand: The term 'take a look here' is used, which is not clear or professional. It is best to avoid using shorthand or colloquial language in formal documentation.", + "6. Incomplete code block: The code block is not complete (it is cut off after the relevant lines). This makes it difficult for developers to understand the context of the issue." + ] +} +``` + In order to make programmers not ignore the feedback reports by this action, we **minimize** amount of problems to just 3 or less. LLM at this stage picks the most important problems from previous analysis -and adds them into new response: +and adds them into new response: ```json { @@ -223,16 +239,16 @@ them into JSON object: } ``` +In the [UML](https://en.wikipedia.org/wiki/Unified_Modeling_Language) notation, the full process looks like this: + +![method.svg](/doc/method.svg) + #### JSON Packing Method LLMs often produce suboptimal results when directly prompted to output in JSON format. That's why we let LLM "think" in English and ask to summarize JSON only at the final step of the operation. At this stage we pack previous LLM response to JSON object format. -In the [UML](https://en.wikipedia.org/wiki/Unified_Modeling_Language) notation, the process internals look like this: - -![method.svg](/doc/method.svg) - ### Puzzle (PDD) Analysis This action supports analysis not only for issues created manually, but also for puzzles, a.k.a `todo` in your code. @@ -247,7 +263,7 @@ Issue is treated as puzzle if it satisfies the following regex: The puzzle `(.+)` from #(\d+) has to be resolved:.+ ``` -Then we are parsing the issue to find a tree path where puzzle is hidden. +Then we parse the issue to find a tree path where puzzle is hidden. This one ```text diff --git a/src/chat-gpt.ts b/src/chat-gpt.ts index 69bb98d7..1e816e8b 100644 --- a/src/chat-gpt.ts +++ b/src/chat-gpt.ts @@ -32,16 +32,12 @@ export class ChatGpt implements Model { * Ctor. * @param open Open AI * @param model Model name - * @param system System prompt - * @param prompt User prompt * @param temperature Temperature * @param max Max new tokens */ constructor( private readonly open: OpenAI, private readonly model: string, - private readonly system: Scalar, - private readonly prompt: Scalar, private readonly temperature: number, private readonly max: number ) { @@ -49,21 +45,26 @@ export class ChatGpt implements Model { this.model = model; } - async analyze() { + async analyze(system: Scalar, user: Scalar) { const response = await this.open.chat.completions.create({ model: this.model, - temperature: 0.5, + temperature: this.temperature, + max_tokens: this.max, messages: [ { role: "system", - content: this.system.value() + content: system.value() }, { role: "user", - content: this.prompt.value() + content: user.value() } ] }); return response.choices[0].message.content?.trim(); } + + name(): string { + return this.model; + } } diff --git a/src/context-expert.ts b/src/context-expert.ts deleted file mode 100644 index 514df320..00000000 --- a/src/context-expert.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2023-2024 Tracehub.git - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * Context expert. - */ -export class ContextExpert implements Scalar { - - value(): string { - return "You are a software quality analysis expert tasked with combining quality problems formulations with the bug report context, enhancing the context information about the quality problems." - } -} diff --git a/src/context-prompt.ts b/src/context-prompt.ts deleted file mode 100644 index 1f574bbc..00000000 --- a/src/context-prompt.ts +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Prompt to enhance problems formulation. - */ -export class ContextPrompt implements Scalar { - - /** - * Ctor. - * @param problems Problems - * @param report Report - */ - constructor( - private readonly problems: any, - private readonly report: string - ) { - } - - value(): string { - return ` - Transform existing problem statements into more context-specific statements, - related to the provided bug report. - Please strictly adhere the provided response template. - Don't generate any other info. - Response example: - [ - "...", - "...", - "...", - "...", - "..." - ] - Problems: -${this.problems} - - Bug report: -${this.report} - `; - } -} diff --git a/src/deep-infra.ts b/src/deep-infra.ts index 9e195c1f..83ec628b 100644 --- a/src/deep-infra.ts +++ b/src/deep-infra.ts @@ -31,22 +31,18 @@ export class DeepInfra implements Model { * Ctor. * @param token Token * @param model Model - * @param system System prompt - * @param prompt User prompt * @param temperature Temperature * @param max Max new tokens */ constructor( private readonly token: string, private readonly model: string, - private readonly system: Scalar, - private readonly prompt: Scalar, private readonly temperature: number, private readonly max: number ) { } - async analyze() { + async analyze(system: Scalar, prompt: Scalar) { const response = await fetch( 'https://api.deepinfra.com/v1/openai/chat/completions', { method: 'POST', @@ -57,11 +53,11 @@ export class DeepInfra implements Model { messages: [ { role: "system", - content: this.system.value() + content: system.value() }, { role: "user", - content: this.prompt.value() + content: prompt.value() } ], }), @@ -76,4 +72,8 @@ export class DeepInfra implements Model { ); return answer.choices[0].message.content; } + + name(): string { + return this.model; + } } diff --git a/src/feedback.ts b/src/feedback.ts index 37842014..f87e574a 100644 --- a/src/feedback.ts +++ b/src/feedback.ts @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -import {Comment} from "./comment"; +import {Comment} from "./github/comment"; import {Covered} from "./covered"; import {WithSummary} from "./with-summary"; import * as core from "@actions/core"; diff --git a/src/comment.ts b/src/github/comment.ts similarity index 100% rename from src/comment.ts rename to src/github/comment.ts diff --git a/src/label.ts b/src/github/label.ts similarity index 100% rename from src/label.ts rename to src/github/label.ts diff --git a/src/smart-issue.ts b/src/github/smart-issue.ts similarity index 100% rename from src/smart-issue.ts rename to src/github/smart-issue.ts diff --git a/src/example.ts b/src/goal.ts similarity index 86% rename from src/example.ts rename to src/goal.ts index 51eb5c94..43c80053 100644 --- a/src/example.ts +++ b/src/goal.ts @@ -23,18 +23,12 @@ */ /** - * Example of analysis summary. + * Goal. */ -export class Example { +export interface Goal { /** - * Example of analysis summary as string. + * Execute the goal. */ - value(): string { - return ` - * <...> - * <...> - * <...> - `; - } + exec(): Promise; } diff --git a/src/goals/named-goal.ts b/src/goals/named-goal.ts new file mode 100644 index 00000000..9340580b --- /dev/null +++ b/src/goals/named-goal.ts @@ -0,0 +1,58 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023-2024 Tracehub.git + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +import {Goal} from "../goal"; + +/** + * Simple named goal. + */ +export class NamedGoal implements Goal { + + /** + * Ctor. + * @param name Name of the goal + * @param model Model + * @param system System + * @param user User + */ + constructor( + private readonly name: string, + private readonly model: Model, + private readonly system: Scalar, + private readonly user: Scalar + ) { + } + + async exec(): Promise { + console.log( + `Running ${this.name} goal` + ); + const response = await this.model.analyze(this.system, this.user); + console.log( + `${this.name} completed, response from ${this.model.name()}: + ${response} + ` + ); + return response; + } +} diff --git a/src/cap-prompt.ts b/src/goals/top-goal.ts similarity index 56% rename from src/cap-prompt.ts rename to src/goals/top-goal.ts index fd19ddbd..e6441621 100644 --- a/src/cap-prompt.ts +++ b/src/goals/top-goal.ts @@ -21,40 +21,58 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ +import {Goal} from "../goal"; +import {Default} from "../prompts/default"; +import {MdUnbox} from "../md-unbox"; +import {Top} from "../prompts/top"; +import {NamedGoal} from "./named-goal"; +import {Polish} from "../prompts/polish"; /** - * Prompt to cap bug report problems. + * Cap top problems goal. */ -export class CapPrompt implements Scalar { +export class TopGoal implements Goal { /** * Ctor. + * @param model Model * @param report Report * @param problems Problems */ constructor( + private readonly model: Model, private readonly report: string, private readonly problems: any ) { } - value(): string { - return ` - Please limit the list of the quality problems for the following bug report - to just three. Pick the most important problems for this bug report and move them into the new array. - Don't edit or rephrase a problem formulations at all. Only pick the most important problems. - Response example: - [ - "...", - "...", - "..." - ]. - Don't generate any other info. - Problems: -${this.problems} - - Bug report: -${this.report} - `; + async exec(): Promise { + console.log( + `Running top goal` + ); + const amount = JSON.parse(new MdUnbox(this.problems).value()).size; + let candidate; + if (amount > 3) { + console.log( + "Amount of problems is more than 3, capping problems..." + ); + const top = await this.model.analyze( + new Default(), + new Top(this.problems, this.report) + ); + console.log( + `Top problems: + ${top}` + ); + candidate = await new NamedGoal( + "polish", + this.model, + new Default(), + new Polish(top) + ).exec(); + } else { + candidate = this.problems; + } + return candidate; } } diff --git a/src/main.ts b/src/main.ts index db963868..d07ae906 100644 --- a/src/main.ts +++ b/src/main.ts @@ -23,28 +23,31 @@ */ import * as core from "@actions/core"; import {Octokit} from "@octokit/rest"; -import {SmartIssue} from "./smart-issue"; -import {Comment} from "./comment"; +import {SmartIssue} from "./github/smart-issue"; +import {Comment} from "./github/comment"; import {DeepInfra} from "./deep-infra"; import {Feedback} from "./feedback"; import {Titled} from "./titled"; import {Excluded} from "./excluded"; -import {Puzzled} from "./puzzled"; -import {Pdd} from "./pdd"; -import {QualityExpert} from "./quality-expert"; -import {AnalysisPrompt} from "./analysis-prompt"; -import {ValidatePrompt} from "./validate-prompt"; -import {Default} from "./default"; -import {JsonFormat} from "./json-format"; -import {Top} from "./top"; -import {PolishJson} from "./polish-json"; -import {Suggestions} from "./suggestions"; -import {SuggestionsJson} from "./suggestions-json"; +import {Puzzled} from "./pdd/puzzled"; +import {Pdd} from "./pdd/pdd"; +import {QualityExpert} from "./prompts/quality-expert"; +import {Analyze} from "./prompts/analyze"; +import {Validate} from "./prompts/validate"; +import {Default} from "./prompts/default"; +import {JsonProblems} from "./prompts/json-problems"; +import {Top} from "./prompts/top"; +import {Polish} from "./prompts/polish"; +import {Suggestions} from "./prompts/suggestions"; +import {SuggestionsJson} from "./prompts/suggestions-json"; import {FormattedSummary} from "./formatted-summary"; import {MdObjects} from "./md-objects"; import {MdUnbox} from "./md-unbox"; import {ChatGpt} from "./chat-gpt"; import OpenAI from "openai"; +import {NamedGoal} from "./goals/named-goal"; +import {TopGoal} from "./goals/top-goal"; +import {Models} from "./models"; export let github: { context: { @@ -149,244 +152,52 @@ async function run() { } ).run(); } else { - /** - * @todo #69:90min Resolve huge code duplication when proceeding chain-of-thought. - * For now we have absolute the same code for both LLMs: ChatGPT and DeepInfra. - * Would be good to resolve this code duplication at this level in order to make this piece - * of code a bit more maintainable and logic-scalable. - */ + const report = new Titled(smart.title, body).asString(); + let llm; + let validator; if ("openai" === type) { const model = core.getInput("openai_model"); - const report = new Titled(smart.title, body).asString(); const open = new OpenAI({apiKey: openai}); - const problems = await new ChatGpt( + llm = new ChatGpt( open, model, - new QualityExpert(), - new AnalysisPrompt(report), 0.7, 512 - ).analyze(); - console.log( - `Analysis found problems: - ${problems} - This list can have fake or falsy problems that bug report does not have. - Running self-validation... - ` ); - const validated = await new ChatGpt( + validator = new ChatGpt( open, model, - new Default(), - new ValidatePrompt(report, problems), 1.0, 1024 - ).analyze(); - console.log( - `Problems were validated, updated list of them: - ${validated} - ` ); - const vformatted = await new ChatGpt( - open, - model, - new Default(), - new JsonFormat(validated), - 0.7, - 512 - ).analyze(); - console.log( - `Packed into JSON: - ${validated} - -> - ${vformatted} - ` - ); - let candidate; - const amount = JSON.parse(new MdUnbox(vformatted).value()).size; - if (amount > 3) { - console.log("Amount of problems is more than 3, running top goal") - const top = await new ChatGpt( - open, - model, - new Default(), - new Top(vformatted, report), - 0.7, - 512 - ).analyze(); - console.log( - `Top problems: - ${top} - ` - ); - candidate = await new ChatGpt( - open, - model, - new Default(), - new PolishJson(top), - 0.7, - 512 - ).analyze(); - } else { - candidate = vformatted; - } - console.log( - `Candidate problems for suggestions: - ${candidate} - ` - ); - const json = await new ChatGpt( - open, - model, - new Default(), - new SuggestionsJson( - await new ChatGpt( - open, - model, - new Default(), - new Suggestions(report, candidate), - 0.7, - 512 - ).analyze() - ), - 0.7, - 512 - ).analyze(); - console.log( - `Packed suggestions into JSON: - ${json} - ` - ); - await new Feedback( - new FormattedSummary( - new MdObjects(JSON.parse(new MdUnbox(candidate).value()).problems), - new MdObjects(JSON.parse(new MdUnbox(json).value()).suggestions) - ), - octokit, - issue, - smart.user?.login, - model - ).post(); } else if ("deepinfra" === type) { const model = core.getInput("deepinfra_model"); - const report = new Titled(smart.title, body).asString(); - const problems = await new DeepInfra( + llm = new DeepInfra( deep, model, - new QualityExpert(), - new AnalysisPrompt( - report - ), 0.7, 512 - ).analyze(); - console.log( - `Analysis found problems: - ${problems} - This list can have fake or falsy problems that bug report does not have. - Running self-validation... - ` ); - const validated = await new DeepInfra( + validator = new DeepInfra( deep, model, - new Default(), - new ValidatePrompt( - report, - problems - ), 1.0, 1024 - ).analyze(); - console.log( - `Problems were validated, updated list of them: - ${validated} - ` ); - const vformatted = await new DeepInfra( - deep, - model, - new Default(), - new JsonFormat(validated), - 0.7, - 512 - ).analyze(); - console.log( - `Packed into JSON: - ${validated} - -> - ${vformatted} - ` - ); - let candidate; - const amount = JSON.parse(new MdUnbox(vformatted).value()).size; - if (amount > 3) { - console.log("Amount of problems is more than 3, running top goal") - const top = await new DeepInfra( - deep, - model, - new Default(), - new Top( - vformatted, - report - ), - 0.7, - 512 - ).analyze(); - console.log( - `Top problems: - ${top} - ` - ); - candidate = await new DeepInfra( - deep, - model, - new Default(), - new PolishJson(top), - 0.7, - 512 - ).analyze(); - } else { - candidate = vformatted; - } - console.log( - `Candidate problems for suggestions: - ${candidate} - ` - ); - const json = await new DeepInfra( - deep, - model, - new Default(), - new SuggestionsJson( - await new DeepInfra( - deep, - model, - new Default(), - new Suggestions(report, candidate), - 0.7, - 512 - ).analyze() - ), - 0.7, - 512 - ).analyze(); - console.log( - `Packed suggestions into JSON: - ${json} - ` - ); - await new Feedback( - new FormattedSummary( - new MdObjects(JSON.parse(new MdUnbox(candidate).value()).problems), - new MdObjects(JSON.parse(new MdUnbox(json).value()).suggestions) - ), - octokit, - issue, - smart.user?.login, - model - ).post(); } + const composed = await new Models( + llm!!, validator!! + ).compose(report); + await new Feedback( + new FormattedSummary( + new MdObjects(JSON.parse(new MdUnbox(composed.problems).value()).problems), + new MdObjects(JSON.parse(new MdUnbox(composed.suggestions).value()).suggestions) + ), + octokit, + issue, + smart.user?.login, + llm!!.name() + ).post(); } } } else { diff --git a/src/md-unbox.ts b/src/md-unbox.ts index 343eaa83..5d873d50 100644 --- a/src/md-unbox.ts +++ b/src/md-unbox.ts @@ -39,12 +39,18 @@ export class MdUnbox implements Scalar { const trimmed = this.response.trim(); const start = 7; if (trimmed.endsWith("```")) { + console.log("Response is in markdown format, unboxing it..."); const index = trimmed.lastIndexOf("```"); const sliced = trimmed.slice(0, index) + trimmed.slice(index + 3); result = sliced.slice(start).trim(); } else { result = this.response; } + console.log( + `Unboxed JSON response: + ${result} + ` + ); return result; } } diff --git a/src/model.ts b/src/model.ts index 4246dd65..4b782e89 100644 --- a/src/model.ts +++ b/src/model.ts @@ -31,5 +31,11 @@ interface Model { * Analyze. * @returns Promise */ - analyze(): Promise; + analyze(system: Scalar, user: Scalar): Promise; + + /** + * Name of the model. + * @returns Model name + */ + name(): string; } diff --git a/src/models.ts b/src/models.ts new file mode 100644 index 00000000..5b108de0 --- /dev/null +++ b/src/models.ts @@ -0,0 +1,97 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023-2024 Tracehub.git + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +import {TopGoal} from "./goals/top-goal"; +import {NamedGoal} from "./goals/named-goal"; +import {Default} from "./prompts/default"; +import {JsonProblems} from "./prompts/json-problems"; +import {Validate} from "./prompts/validate"; +import {QualityExpert} from "./prompts/quality-expert"; +import {Analyze} from "./prompts/analyze"; +import {SuggestionsJson} from "./prompts/suggestions-json"; +import {Suggestions} from "./prompts/suggestions"; + +/** + * Models. + */ +export class Models { + + /** + * Ctor. + * @param def Default model + * @param validator Model for validation + */ + constructor( + private readonly def: Model, + private readonly validator: Model + ) { + } + + async compose(report: string) { + const candidate = await new TopGoal( + this.def, + report, + await new NamedGoal( + "json-validate", + this.def, + new Default(), + new JsonProblems( + await new NamedGoal( + "validate", + this.validator, + new Default(), + new Validate( + report, + await new NamedGoal( + "analyze", + this.def, + new QualityExpert(), + new Analyze(report) + ).exec() + ) + ).exec() + ) + ).exec(), + ).exec(); + const suggestions = await new NamedGoal( + "json-suggestions", + this.def, + new Default(), + new SuggestionsJson( + await new NamedGoal( + "suggestions", + this.def, + new Default(), + new Suggestions( + report, + candidate + ) + ).exec() + ) + ).exec(); + return { + problems: candidate, + suggestions: suggestions + } + } +} diff --git a/src/non-relevant.ts b/src/non-relevant.ts index 17ad851a..1dbfc564 100644 --- a/src/non-relevant.ts +++ b/src/non-relevant.ts @@ -22,8 +22,8 @@ * SOFTWARE. */ import {Octokit} from "@octokit/rest"; -import {Comment} from "./comment"; -import {Label} from "./label"; +import {Comment} from "./github/comment"; +import {Label} from "./github/label"; /** * Non Relevant bug report. diff --git a/src/blob-path.ts b/src/pdd/blob-path.ts similarity index 100% rename from src/blob-path.ts rename to src/pdd/blob-path.ts diff --git a/src/blob.ts b/src/pdd/blob.ts similarity index 100% rename from src/blob.ts rename to src/pdd/blob.ts diff --git a/src/hash-split.ts b/src/pdd/hash-split.ts similarity index 100% rename from src/hash-split.ts rename to src/pdd/hash-split.ts diff --git a/src/lines.ts b/src/pdd/lines.ts similarity index 100% rename from src/lines.ts rename to src/pdd/lines.ts diff --git a/src/pdd-model.ts b/src/pdd/pdd-model.ts similarity index 80% rename from src/pdd-model.ts rename to src/pdd/pdd-model.ts index 4bec4516..59b63b7f 100644 --- a/src/pdd-model.ts +++ b/src/pdd/pdd-model.ts @@ -21,10 +21,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -import {DeepInfra} from "./deep-infra"; -import {ChatGpt} from "./chat-gpt"; +import {DeepInfra} from "../deep-infra"; +import {ChatGpt} from "../chat-gpt"; import OpenAI from "openai"; -import {TodoReviewer} from "./todo-reviewer"; /** * PDD model. @@ -36,38 +35,35 @@ export class PddModel implements Model { * @param type Type * @param token Token * @param model Model name - * @param prompt Prompt */ constructor( private readonly type: string, private readonly token: string, - private readonly model: string, - private readonly prompt: Scalar + private readonly model: string ) { } - async analyze(): Promise { + async analyze(system: Scalar, user: Scalar): Promise { let answer; if (this.type === "openai") { answer = await new ChatGpt( new OpenAI({apiKey: this.token}), this.model, - new TodoReviewer(), - this.prompt, 0.7, 512 - ).analyze(); + ).analyze(system, user); } else { - console.log(this.prompt.value()); answer = await new DeepInfra( this.token, this.model, - new TodoReviewer(), - this.prompt, 0.7, 512 - ).analyze(); + ).analyze(system, user); } return answer; } + + name(): string { + return this.model; + } } diff --git a/src/pdd.ts b/src/pdd/pdd.ts similarity index 93% rename from src/pdd.ts rename to src/pdd/pdd.ts index 73d84232..4d08ee58 100644 --- a/src/pdd.ts +++ b/src/pdd/pdd.ts @@ -28,9 +28,10 @@ import {BlobPath} from "./blob-path"; import {Lines} from "./lines"; import {HashSplit} from "./hash-split"; import {Split} from "./split"; -import {Feedback} from "./feedback"; +import {Feedback} from "../feedback"; import {PddModel} from "./pdd-model"; -import {PddPrompt} from "./pdd-prompt"; +import {PddPrompt} from "../prompts/pdd-prompt"; +import {TodoReviewer} from "./todo-reviewer"; /** * PDD routine. @@ -72,12 +73,14 @@ export class Pdd { this.type, this.pair.token, this.pair.model, + ).analyze( + new TodoReviewer(), new PddPrompt( puzzle, full.value()!!, content ) - ).analyze(), + ), this.github, this.issue, this.username, diff --git a/src/puzzled.ts b/src/pdd/puzzled.ts similarity index 100% rename from src/puzzled.ts rename to src/pdd/puzzled.ts diff --git a/src/ranged.ts b/src/pdd/ranged.ts similarity index 100% rename from src/ranged.ts rename to src/pdd/ranged.ts diff --git a/src/split.ts b/src/pdd/split.ts similarity index 100% rename from src/split.ts rename to src/pdd/split.ts diff --git a/src/todo-reviewer.ts b/src/pdd/todo-reviewer.ts similarity index 100% rename from src/todo-reviewer.ts rename to src/pdd/todo-reviewer.ts diff --git a/src/analysis-prompt.ts b/src/prompts/analyze.ts similarity index 96% rename from src/analysis-prompt.ts rename to src/prompts/analyze.ts index 9f70ed37..48c66ff5 100644 --- a/src/analysis-prompt.ts +++ b/src/prompts/analyze.ts @@ -25,7 +25,7 @@ /** * Quality analysis prompt. */ -export class AnalysisPrompt implements Scalar { +export class Analyze implements Scalar { constructor(private readonly report: string) { } diff --git a/src/default.ts b/src/prompts/default.ts similarity index 100% rename from src/default.ts rename to src/prompts/default.ts diff --git a/src/json-format.ts b/src/prompts/json-problems.ts similarity index 96% rename from src/json-format.ts rename to src/prompts/json-problems.ts index c4482312..89c071d3 100644 --- a/src/json-format.ts +++ b/src/prompts/json-problems.ts @@ -25,7 +25,7 @@ /** * Format to JSON prompt. */ -export class JsonFormat implements Scalar { +export class JsonProblems implements Scalar { /** * Ctor. diff --git a/src/pdd-prompt.ts b/src/prompts/pdd-prompt.ts similarity index 100% rename from src/pdd-prompt.ts rename to src/prompts/pdd-prompt.ts diff --git a/src/polish-json.ts b/src/prompts/polish.ts similarity index 96% rename from src/polish-json.ts rename to src/prompts/polish.ts index d8ccf36a..0749c931 100644 --- a/src/polish-json.ts +++ b/src/prompts/polish.ts @@ -25,7 +25,7 @@ /** * Prompt to polish JSON. */ -export class PolishJson implements Scalar { +export class Polish implements Scalar { /** * Ctor. diff --git a/src/quality-expert.ts b/src/prompts/quality-expert.ts similarity index 100% rename from src/quality-expert.ts rename to src/prompts/quality-expert.ts diff --git a/src/suggestions-json.ts b/src/prompts/suggestions-json.ts similarity index 100% rename from src/suggestions-json.ts rename to src/prompts/suggestions-json.ts diff --git a/src/suggestions.ts b/src/prompts/suggestions.ts similarity index 100% rename from src/suggestions.ts rename to src/prompts/suggestions.ts diff --git a/src/top.ts b/src/prompts/top.ts similarity index 100% rename from src/top.ts rename to src/prompts/top.ts diff --git a/src/validate-prompt.ts b/src/prompts/validate.ts similarity index 96% rename from src/validate-prompt.ts rename to src/prompts/validate.ts index 17221ac1..7882d3fe 100644 --- a/src/validate-prompt.ts +++ b/src/prompts/validate.ts @@ -25,7 +25,7 @@ /** * Prompt for self-validation. */ -export class ValidatePrompt implements Scalar { +export class Validate implements Scalar { /** * Ctor. diff --git a/src/user-prompt.ts b/src/user-prompt.ts deleted file mode 100644 index bfd376ff..00000000 --- a/src/user-prompt.ts +++ /dev/null @@ -1,60 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2023-2024 Tracehub.git - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * User prompt. - */ -export class UserPrompt { - - /** - * Ctor. - * - * @param report Bug report - */ - constructor( - private readonly report: string | null | undefined - ) { - this.report = report; - } - - /** - * Build user prompt. - */ - value(): string { - return ` - Please strictly review the following bug report and generate a summary with quality problems related to this report formulation. - The summary must include only star (*), no indent bullet points with quality problems that only this report has and tips on how to fix them, so author of this report can improve it. - Maximum number of suggestions must be 3 bullet points. - Don't suggest how to fix the bug, instead focus only on problems with bug report formulation. - If you see that bug report don't have quality problems with it's formulation, then just say "Quality is awesome". - Don't generate any other info. - Summary example: - * <> - * <> - * <> - Bug report: - ${this.report} - `; - } -} diff --git a/tests/blob-path.test.ts b/tests/pdd/blob-path.test.ts similarity index 97% rename from tests/blob-path.test.ts rename to tests/pdd/blob-path.test.ts index 43dd2a9b..3c14670e 100644 --- a/tests/blob-path.test.ts +++ b/tests/pdd/blob-path.test.ts @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -import {BlobPath} from "../src/blob-path"; +import {BlobPath} from "../../src/pdd/blob-path"; /** * Test cases for BlobPath. diff --git a/tests/hash-split.test.ts b/tests/pdd/hash-split.test.ts similarity index 96% rename from tests/hash-split.test.ts rename to tests/pdd/hash-split.test.ts index ad4f4031..6526451a 100644 --- a/tests/hash-split.test.ts +++ b/tests/pdd/hash-split.test.ts @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -import {HashSplit} from "../src/hash-split"; +import {HashSplit} from "../../src/pdd/hash-split"; /** * Test cases for HashSplit. diff --git a/tests/lines.test.ts b/tests/pdd/lines.test.ts similarity index 97% rename from tests/lines.test.ts rename to tests/pdd/lines.test.ts index f0877e8a..f4b51140 100644 --- a/tests/lines.test.ts +++ b/tests/pdd/lines.test.ts @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -import {Lines} from "../src/lines"; +import {Lines} from "../../src/pdd/lines"; /** * Test cases for Lines. diff --git a/tests/ranged.test.ts b/tests/pdd/ranged.test.ts similarity index 98% rename from tests/ranged.test.ts rename to tests/pdd/ranged.test.ts index 8f8d74eb..52776616 100644 --- a/tests/ranged.test.ts +++ b/tests/pdd/ranged.test.ts @@ -1,6 +1,6 @@ -import {Ranged} from "../src/ranged"; -import {Split} from "../src/split"; -import {Lines} from "../src/lines"; +import {Ranged} from "../../src/pdd/ranged"; +import {Split} from "../../src/pdd/split"; +import {Lines} from "../../src/pdd/lines"; /** * Test cases for BlobPath. diff --git a/tests/split.test.ts b/tests/pdd/split.test.ts similarity index 97% rename from tests/split.test.ts rename to tests/pdd/split.test.ts index 22ef8279..558820b1 100644 --- a/tests/split.test.ts +++ b/tests/pdd/split.test.ts @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -import {Split} from "../src/split"; +import {Split} from "../../src/pdd/split"; /** * Test cases for Split.