diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 77864b1d..813af374 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -33,7 +33,7 @@ val hsqldb_version = "2.7.2" dependencies { - implementation(group = "com.simiacryptus", name = "jo-penai", version = "1.1.9") + implementation(group = "com.simiacryptus", name = "jo-penai", version = "1.1.10") implementation(group = "org.hsqldb", name = "hsqldb", version = hsqldb_version) implementation("org.apache.commons:commons-text:1.11.0") @@ -103,7 +103,6 @@ tasks { } - val javadocJar by tasks.registering(Jar::class) { archiveClassifier.set("javadoc") from(tasks.javadoc) diff --git a/core/src/main/dev_documentation.md b/core/src/main/dev_documentation.md index 5845041b..f708f1e2 100644 --- a/core/src/main/dev_documentation.md +++ b/core/src/main/dev_documentation.md @@ -1,10 +1,9 @@ # kotlin\com\simiacryptus\skyenet\core\actors\BaseActor.kt - ## Developer Documentation for BaseActor Class -The `BaseActor` class serves as an abstract base for creating actors that interact with OpenAI's API to generate responses based on input. This class is designed to be extended for various types of actors that require different input types (`I`) and return types (`R`). - +The `BaseActor` class serves as an abstract base for creating actors that interact with OpenAI's API to generate responses based on input. This class is designed to be extended for +various types of actors that require different input types (`I`) and return types (`R`). ### Class Overview @@ -23,7 +22,6 @@ classDiagram } ``` - #### Properties - `prompt`: The initial prompt or context used for generating responses. @@ -31,35 +29,31 @@ classDiagram - `model`: The OpenAI model to be used for generating responses. This is specified using the `ChatModels` enum. - `temperature`: Controls the randomness of the response generation. A lower value makes the model more deterministic. - #### Methods - ##### `abstract fun respond(input: I, api: API, vararg messages: ApiModel.ChatMessage): R` -This abstract method must be implemented by subclasses to define how the actor responds to the given input and messages. It uses the provided API instance to interact with OpenAI's services. - +This abstract method must be implemented by subclasses to define how the actor responds to the given input and messages. It uses the provided API instance to interact with OpenAI's +services. ##### `open fun response(vararg input: ApiModel.ChatMessage, model: OpenAIModel = this.model, api: API): ChatResponse` Generates a response using the OpenAI API based on the provided chat messages. It allows overriding the model used for this specific response. - ##### `open fun answer(input: I, api: API): R` -A high-level method that generates a response based on the input. It internally calls `chatMessages` to convert the input into chat messages and then `respond` to generate the final response. - +A high-level method that generates a response based on the input. It internally calls `chatMessages` to convert the input into chat messages and then `respond` to generate the +final response. ##### `abstract fun chatMessages(questions: I): Array` -Converts the input into an array of `ApiModel.ChatMessage` instances. This method must be implemented by subclasses to define how input is transformed into a format suitable for the OpenAI API. - +Converts the input into an array of `ApiModel.ChatMessage` instances. This method must be implemented by subclasses to define how input is transformed into a format suitable for +the OpenAI API. ##### `abstract fun withModel(model: ChatModels): BaseActor` Creates a new instance of the actor with the specified model. This method allows changing the model used for response generation. - ### Usage To use the `BaseActor` class, you must extend it and implement the abstract methods. Here's a simplified example: @@ -80,36 +74,37 @@ class TextActor(prompt: String, model: ChatModels) : BaseActor(p } ``` -This class is designed to be flexible and extensible for various types of interactions with OpenAI's API, allowing developers to create sophisticated actors for different applications. +This class is designed to be flexible and extensible for various types of interactions with OpenAI's API, allowing developers to create sophisticated actors for different +applications. # kotlin\com\simiacryptus\skyenet\core\actors\ActorSystem.kt - ## ActorSystem Class Documentation -The `ActorSystem` class is a core component of the application that manages the lifecycle and interactions of various actors within the system. It is designed to be generic, supporting different types of actors identified by an enum (`T`). This class is responsible for initializing actors, managing their state, and providing a mechanism for actor interaction through interceptors. - +The `ActorSystem` class is a core component of the application that manages the lifecycle and interactions of various actors within the system. It is designed to be generic, +supporting different types of actors identified by an enum (`T`). This class is responsible for initializing actors, managing their state, and providing a mechanism for actor +interaction through interceptors. ### Overview -The `ActorSystem` class is structured to facilitate the management of actors in a session-based context, with support for user-specific data storage and session management. It leverages a pool of resources and a set of interceptors to enhance or modify the behavior of actors at runtime. - +The `ActorSystem` class is structured to facilitate the management of actors in a session-based context, with support for user-specific data storage and session management. It +leverages a pool of resources and a set of interceptors to enhance or modify the behavior of actors at runtime. ### Class Diagram ```mermaid classDiagram class ActorSystem { - -actors: Map - -dataStorage: StorageInterface - -user: User? - -session: Session - -sessionDir: File - -pool: ResourcePool - -actorMap: MutableMap - -wrapperMap: MutableMap - +getActor(T): BaseActor - -getWrapper(String): FunctionWrapper + -actors: Map + -dataStorage: StorageInterface + -user: User? + -session: Session + -sessionDir: File + -pool: ResourcePool + -actorMap: MutableMap + -wrapperMap: MutableMap + +getActor(T): BaseActor + -getWrapper(String): FunctionWrapper } ActorSystem --> "1" BaseActor: manages ActorSystem --> "1" StorageInterface: uses @@ -118,7 +113,6 @@ classDiagram ActorSystem --> "1" FunctionWrapper: creates ``` - ### Key Components - **actors**: A map of enum keys to `BaseActor` instances. This map defines the available actors within the system. @@ -128,19 +122,17 @@ classDiagram - **sessionDir**: A `File` instance pointing to the directory where session-specific data is stored. - **pool**: A lazy-initialized resource pool used by actors for executing tasks. - ### Methods - #### getActor(actor: T): BaseActor<*, *> -Retrieves an instance of `BaseActor` for the specified actor enum. If the actor instance does not exist in the `actorMap`, it is created using the corresponding entry in the `actors` map. The creation process involves wrapping the actor with an appropriate interceptor based on its type (e.g., `SimpleActorInterceptor`, `ParsedActorInterceptor`). - +Retrieves an instance of `BaseActor` for the specified actor enum. If the actor instance does not exist in the `actorMap`, it is created using the corresponding entry in the +`actors` map. The creation process involves wrapping the actor with an appropriate interceptor based on its type (e.g., `SimpleActorInterceptor`, `ParsedActorInterceptor`). #### getWrapper(name: String): FunctionWrapper -Retrieves or creates a `FunctionWrapper` instance for the specified actor name. This wrapper is used to intercept function calls within the actor, allowing for additional processing or logging. The wrapper is associated with a `JsonFunctionRecorder` that persists function call data to a file within the session directory. - +Retrieves or creates a `FunctionWrapper` instance for the specified actor name. This wrapper is used to intercept function calls within the actor, allowing for additional +processing or logging. The wrapper is associated with a `JsonFunctionRecorder` that persists function call data to a file within the session directory. ### Usage Example @@ -155,26 +147,25 @@ val myActor = actorSystem.getActor(MyActorEnum.SOME_ACTOR) myActor.performAction() ``` - ### Conclusion -The `ActorSystem` class provides a flexible and extensible framework for managing actors within an application. By abstracting actor initialization and providing support for function interception, it allows for sophisticated runtime behavior modifications and enhances the application's capabilities to handle complex workflows and data processing tasks. +The `ActorSystem` class provides a flexible and extensible framework for managing actors within an application. By abstracting actor initialization and providing support for +function interception, it allows for sophisticated runtime behavior modifications and enhances the application's capabilities to handle complex workflows and data processing tasks. # java\com\simiacryptus\skyenet\core\OutputInterceptor.java - ## OutputInterceptor Documentation -The `OutputInterceptor` class is a utility designed to intercept and redirect standard output (`System.out`) and error output (`System.err`) streams in Java applications. This functionality is particularly useful for capturing and analyzing console output for logging, debugging, or testing purposes. - +The `OutputInterceptor` class is a utility designed to intercept and redirect standard output (`System.out`) and error output (`System.err`) streams in Java applications. This +functionality is particularly useful for capturing and analyzing console output for logging, debugging, or testing purposes. ### Overview The class provides mechanisms to: + - Intercept and reroute output from `System.out` and `System.err` to custom `ByteArrayOutputStream` instances. - Retrieve and clear the captured output on both a per-thread basis and globally across all threads. - ### Setup To start intercepting output, call the `setupInterceptor` method. This method reroutes the standard and error output streams to internal mechanisms that capture the output. @@ -183,16 +174,13 @@ To start intercepting output, call the `setupInterceptor` method. This method re OutputInterceptor.setupInterceptor(); ``` - ### Usage - #### Capturing Output - **Thread-specific Output**: Output written by the current thread can be retrieved and cleared using `getThreadOutput` and `clearThreadOutput` methods, respectively. - **Global Output**: Output written by all threads can be accessed and cleared using `getGlobalOutput` and `clearGlobalOutput` methods, respectively. - #### Retrieving Captured Output - To get the output captured from the current thread: @@ -207,7 +195,6 @@ OutputInterceptor.setupInterceptor(); String globalOutput = OutputInterceptor.getGlobalOutput(); ``` - #### Clearing Captured Output - To clear the output captured from the current thread: @@ -222,10 +209,8 @@ OutputInterceptor.setupInterceptor(); OutputInterceptor.clearGlobalOutput(); ``` - ### Implementation Details - #### Class Diagram ```mermaid @@ -253,33 +238,33 @@ classDiagram OutputInterceptor --|> OutputStreamRouter : routes output ``` - #### Thread Safety -The `OutputInterceptor` class is designed to be thread-safe. It uses synchronization on a global lock object (`globalStreamLock`) for operations affecting the global output stream, and a `WeakHashMap` for thread-local output streams to ensure thread safety and avoid memory leaks. - +The `OutputInterceptor` class is designed to be thread-safe. It uses synchronization on a global lock object (`globalStreamLock`) for operations affecting the global output stream, +and a `WeakHashMap` for thread-local output streams to ensure thread safety and avoid memory leaks. #### Memory Management -To prevent excessive memory usage, the `OutputStreamRouter` class imposes limits on the maximum size of both global and thread-local output buffers. When these limits are exceeded, the buffers are automatically reset. - +To prevent excessive memory usage, the `OutputStreamRouter` class imposes limits on the maximum size of both global and thread-local output buffers. When these limits are exceeded, +the buffers are automatically reset. ### Conclusion -The `OutputInterceptor` class provides a powerful and flexible way to intercept, capture, and analyze output from Java applications. Its thread-safe design and memory management features make it suitable for use in a wide range of scenarios, from development and debugging to production logging and monitoring. +The `OutputInterceptor` class provides a powerful and flexible way to intercept, capture, and analyze output from Java applications. Its thread-safe design and memory management +features make it suitable for use in a wide range of scenarios, from development and debugging to production logging and monitoring. # kotlin\com\simiacryptus\skyenet\core\actors\CodingActor.kt - ## Developer Documentation for `CodingActor` -The `CodingActor` class is a sophisticated component designed to facilitate the translation of natural language instructions into executable code, leveraging the capabilities of AI models. It serves as an intermediary that understands both the user's intent expressed in natural language and the technical requirements to fulfill that intent through code execution. - +The `CodingActor` class is a sophisticated component designed to facilitate the translation of natural language instructions into executable code, leveraging the capabilities of AI +models. It serves as an intermediary that understands both the user's intent expressed in natural language and the technical requirements to fulfill that intent through code +execution. ### Overview -`CodingActor` extends `BaseActor` and specializes in handling code-related requests and responses. It integrates with an interpreter to execute the generated code and provides mechanisms for automatic error correction and code evaluation. - +`CodingActor` extends `BaseActor` and specializes in handling code-related requests and responses. It integrates with an interpreter to execute the generated code and provides +mechanisms for automatic error correction and code evaluation. #### Key Features @@ -289,56 +274,53 @@ The `CodingActor` class is a sophisticated component designed to facilitate the - **Customizable Code Formatting**: Supports customizable code formatting guidelines. - **Extensible Type Description**: Uses a `TypeDescriber` for detailed API descriptions. - ### Class Structure ```mermaid classDiagram BaseActor <|-- CodingActor - CodingActor : +interpreterClass KClass~Interpreter~ - CodingActor : +symbols Map~String, Any~ - CodingActor : +describer TypeDescriber - CodingActor : +details String? - CodingActor : +fallbackModel ChatModels - CodingActor : +runtimeSymbols Map~String, Any~ - CodingActor : +evalFormat Boolean - CodingActor : +language String - CodingActor : +prompt String - CodingActor : +apiDescription String - CodingActor : +execute(prefix String, code String) ExecutionResult - CodingActor : +respond(input CodeRequest, api API, messages ChatMessage) CodeResult - CodingActor : +withModel(model ChatModels) CodingActor - class BaseActor{ - <> - +prompt String - +name String? - +model ChatModels - +temperature Double - } - class CodeRequest{ - +messages List~Pair~String, Role~~ - +codePrefix String - +autoEvaluate Boolean - +fixIterations Int - +fixRetries Int - } - class CodeResult~interface~{ - <> - +code String - +status Status - +result ExecutionResult - +renderedResponse String? + CodingActor: +interpreterClass KClass~Interpreter~ + CodingActor: +symbols Map~String, Any~ + CodingActor: +describer TypeDescriber + CodingActor: +details String? + CodingActor: +fallbackModel ChatModels + CodingActor: +runtimeSymbols Map~String, Any~ + CodingActor: +evalFormat Boolean + CodingActor: +language String + CodingActor: +prompt String + CodingActor: +apiDescription String + CodingActor: +execute(prefix String, code String) ExecutionResult + CodingActor: +respond(input CodeRequest, api API, messages ChatMessage) CodeResult + CodingActor: +withModel(model ChatModels) CodingActor + class BaseActor { + <> + +prompt String + +name String? + +model ChatModels + +temperature Double + } + class CodeRequest { + +messages List~Pair~ String, Role~~ + +codePrefix String + +autoEvaluate Boolean + +fixIterations Int + +fixRetries Int + } + class CodeResult~interface~ { + <> + +code String + +status Status + +result ExecutionResult + +renderedResponse String? } - class ExecutionResult{ - +resultValue String - +resultOutput String + class ExecutionResult { + +resultValue String + +resultOutput String } ``` - ### Usage - #### Initialization To create an instance of `CodingActor`, you need to provide: @@ -348,7 +330,6 @@ To create an instance of `CodingActor`, you need to provide: - `describer`: An instance of `TypeDescriber` for API description. - Additional optional parameters such as `details`, `model`, `fallbackModel`, `temperature`, and `runtimeSymbols`. - #### Processing Requests To process a coding request, create an instance of `CodeRequest` with: @@ -356,13 +337,13 @@ To process a coding request, create an instance of `CodeRequest` with: - `messages`: A list of pairs containing the message and its role (`Role.system` or `Role.assistant`). - Optional parameters like `codePrefix`, `autoEvaluate`, `fixIterations`, and `fixRetries`. -Call the `respond` method with the `CodeRequest` instance and other required parameters. This method returns an instance of `CodeResult`, which contains the generated code, execution status, and result. - +Call the `respond` method with the `CodeRequest` instance and other required parameters. This method returns an instance of `CodeResult`, which contains the generated code, +execution status, and result. #### Execution and Error Handling -The `execute` method runs the generated code using the specified interpreter and handles errors. If `autoEvaluate` is true, `respond` will automatically attempt to execute and correct the code. - +The `execute` method runs the generated code using the specified interpreter and handles errors. If `autoEvaluate` is true, `respond` will automatically attempt to execute and +correct the code. ### Extending `CodingActor` @@ -371,27 +352,26 @@ To extend `CodingActor`: 1. Override necessary methods to customize behavior. 2. Use `withModel` to create a new instance with a different AI model. - ### Conclusion -`CodingActor` is a powerful tool for bridging the gap between natural language instructions and executable code. By leveraging AI models and an extensible architecture, it offers a flexible and efficient way to automate coding tasks. +`CodingActor` is a powerful tool for bridging the gap between natural language instructions and executable code. By leveraging AI models and an extensible architecture, it offers a +flexible and efficient way to automate coding tasks. # kotlin\com\simiacryptus\skyenet\core\actors\ImageActor.kt - ## ImageActor Class Documentation -The `ImageActor` class is a specialized actor designed to transform user requests into image generation prompts and subsequently generate images that align with the user's preferences. This class extends the `BaseActor` class and operates within the context of interacting with OpenAI's API for image generation, specifically targeting models like DALL-E 2. - +The `ImageActor` class is a specialized actor designed to transform user requests into image generation prompts and subsequently generate images that align with the user's +preferences. This class extends the `BaseActor` class and operates within the context of interacting with OpenAI's API for image generation, specifically targeting models like +DALL-E 2. ### Overview -The `ImageActor` class is structured to first interpret a textual prompt through a chat model and then use the interpreted prompt to generate an image using an image model. This process involves several key components and steps, which are detailed below. - +The `ImageActor` class is structured to first interpret a textual prompt through a chat model and then use the interpreted prompt to generate an image using an image model. This +process involves several key components and steps, which are detailed below. ### Class Structure - #### Constructor Parameters - `prompt`: The initial prompt used to guide the text generation process. @@ -402,7 +382,6 @@ The `ImageActor` class is structured to first interpret a textual prompt through - `width`: The width of the generated image. - `height`: The height of the generated image. - #### Methods - `chatMessages(questions: List)`: Prepares chat messages for interaction with the text model. @@ -410,17 +389,14 @@ The `ImageActor` class is structured to first interpret a textual prompt through - `respond(input: List, api: API, vararg messages: ChatMessage)`: Generates an `ImageResponse` based on the input questions and chat messages. - `withModel(model: ChatModels)`: Returns a new instance of `ImageActor` with the specified chat model. - #### Inner Classes - `ImageResponseImpl`: An implementation of the `ImageResponse` interface, encapsulating the text prompt and the generated image. - ### Interfaces - `ImageResponse`: An interface representing the response from the `ImageActor`, containing the text prompt and the generated image. - ### Usage Flow ```mermaid @@ -429,16 +405,14 @@ sequenceDiagram participant ImageActor participant OpenAIClient participant ImageModel - - User->>ImageActor: Request Image - ImageActor->>OpenAIClient: Send Text Prompt - OpenAIClient->>ImageActor: Return Interpreted Prompt - ImageActor->>ImageModel: Send Interpreted Prompt - ImageModel->>ImageActor: Return Image URL - ImageActor->>User: Return Image Response + User ->> ImageActor: Request Image + ImageActor ->> OpenAIClient: Send Text Prompt + OpenAIClient ->> ImageActor: Return Interpreted Prompt + ImageActor ->> ImageModel: Send Interpreted Prompt + ImageModel ->> ImageActor: Return Image URL + ImageActor ->> User: Return Image Response ``` - ### Example Usage ```kotlin @@ -459,27 +433,27 @@ val imageResponse = imageActor.respond(questions, api) // Display or process the imageResponse.image as needed ``` - ### Conclusion -The `ImageActor` class provides a powerful abstraction for generating images based on textual prompts. By leveraging OpenAI's API and models, it simplifies the process of creating visually appealing images that meet user specifications. +The `ImageActor` class provides a powerful abstraction for generating images based on textual prompts. By leveraging OpenAI's API and models, it simplifies the process of creating +visually appealing images that meet user specifications. # kotlin\com\simiacryptus\skyenet\core\actors\opt\Expectation.kt - ## Developer Documentation: Expectation Module -The `Expectation` module within the `com.simiacryptus.skyenet.core.actors.opt` package provides a framework for evaluating responses based on predefined criteria. This module is designed to work with the OpenAI API client, facilitating the embedding and comparison of text responses against specified expectations. It consists of an abstract class `Expectation` and two concrete implementations: `VectorMatch` and `ContainsMatch`. - +The `Expectation` module within the `com.simiacryptus.skyenet.core.actors.opt` package provides a framework for evaluating responses based on predefined criteria. This module is +designed to work with the OpenAI API client, facilitating the embedding and comparison of text responses against specified expectations. It consists of an abstract class +`Expectation` and two concrete implementations: `VectorMatch` and `ContainsMatch`. ### Overview -The `Expectation` class serves as the foundation, defining the structure and expectations for its subclasses. Each subclass implements specific logic to match and score responses based on different criteria: +The `Expectation` class serves as the foundation, defining the structure and expectations for its subclasses. Each subclass implements specific logic to match and score responses +based on different criteria: - `VectorMatch`: Evaluates responses by comparing the semantic similarity between the example text and the response text. - `ContainsMatch`: Checks if the response contains a specified pattern, supporting both critical and non-critical matches. - #### Class Diagram ```mermaid @@ -508,14 +482,12 @@ classDiagram Expectation <|-- ContainsMatch ``` - ### Usage - #### VectorMatch -`VectorMatch` compares the semantic similarity between an example text and a response text. It uses embeddings to calculate the distance (similarity) between texts, supporting different distance metrics. - +`VectorMatch` compares the semantic similarity between an example text and a response text. It uses embeddings to calculate the distance (similarity) between texts, supporting +different distance metrics. ##### Example Usage @@ -524,12 +496,10 @@ val vectorMatch = VectorMatch("Example text") val similarityScore = vectorMatch.score(apiClient, "Response text") ``` - #### ContainsMatch `ContainsMatch` checks if the response contains a specified regex pattern. It can be configured to treat matches as critical or non-critical. - ##### Example Usage ```kotlin @@ -537,26 +507,21 @@ val containsMatch = ContainsMatch(Regex("pattern"), critical = true) val matchResult = containsMatch.matches(apiClient, "Response text") ``` - ### Methods - #### Abstract Methods - `matches(api: OpenAIClient, response: String): Boolean`: Determines if the response matches the expectation. - `score(api: OpenAIClient, response: String): Double`: Calculates a score based on how well the response matches the expectation. - #### VectorMatch Specific - `createEmbedding(api: OpenAIClient, str: String)`: Generates an embedding for the given string using the OpenAI API. - #### ContainsMatch Specific - `_matches(response: String?): Boolean`: Helper method to check for regex pattern matches within the response. - ### Logging The module utilizes SLF4J for logging information, such as distance calculations in `VectorMatch` and pattern match failures in `ContainsMatch`. @@ -567,16 +532,16 @@ This documentation provides an overview of the `Expectation` module's capabiliti # kotlin\com\simiacryptus\skyenet\core\actors\opt\ActorOptimization.kt - ## Developer Documentation for ActorOptimization -The `ActorOptimization` class is designed to optimize actor responses using genetic algorithms. It leverages the OpenAI API to generate, mutate, and recombine prompts to improve the quality of responses based on defined test cases. - +The `ActorOptimization` class is designed to optimize actor responses using genetic algorithms. It leverages the OpenAI API to generate, mutate, and recombine prompts to improve +the quality of responses based on defined test cases. ### Overview -The optimization process involves generating a population of prompts, evaluating them against a set of test cases, and iteratively selecting, mutating, and recombining the best-performing prompts to produce a new generation of prompts. This process is repeated for a specified number of generations, with the goal of evolving prompts that yield the best responses from the actors. - +The optimization process involves generating a population of prompts, evaluating them against a set of test cases, and iteratively selecting, mutating, and recombining the +best-performing prompts to produce a new generation of prompts. This process is repeated for a specified number of generations, with the goal of evolving prompts that yield the +best responses from the actors. ### Key Components @@ -585,10 +550,8 @@ The optimization process involves generating a population of prompts, evaluating - **mutationRate**: The probability of mutating a recombined prompt. - **mutationTypes**: The types of mutations that can be applied to prompts, along with their associated probabilities. - ### Core Methods - #### runGeneticGenerations ```kotlin @@ -605,7 +568,6 @@ fun ,T:Any> runGeneticGenerations( Generates and evolves a population of prompts over a specified number of generations, evaluating their performance against a set of test cases. - #### regenerate ```kotlin @@ -614,7 +576,6 @@ open fun regenerate(progenetors: List, desiredCount: Int): List Generates a new population of prompts by selecting, mutating, and recombining the best-performing prompts from the previous generation. - #### recombine ```kotlin @@ -623,7 +584,6 @@ open fun recombine(a: String, b: String): String Combines two prompts to produce a new prompt, with an optional mutation step. - #### mutate ```kotlin @@ -632,18 +592,15 @@ open fun mutate(selected: String): String Applies a random mutation to a prompt, altering it based on the specified mutation types. - ### GeneticApi Interface Defines the methods for mutating and recombining prompts. - #### Methods - **mutate**: Applies a mutation to a prompt. - **recombine**: Combines two prompts into a new prompt. - ### Usage Flow The following diagram illustrates the basic flow of using the `ActorOptimization` class to optimize actor prompts: @@ -653,20 +610,19 @@ sequenceDiagram participant Developer participant ActorOptimization participant OpenAIClient - Developer->>ActorOptimization: Instantiate with OpenAIClient, model + Developer ->> ActorOptimization: Instantiate with OpenAIClient, model loop for each generation - ActorOptimization->>ActorOptimization: Generate population + ActorOptimization ->> ActorOptimization: Generate population loop for each prompt in population - ActorOptimization->>OpenAIClient: Evaluate prompt - OpenAIClient->>ActorOptimization: Return score + ActorOptimization ->> OpenAIClient: Evaluate prompt + OpenAIClient ->> ActorOptimization: Return score end - ActorOptimization->>ActorOptimization: Select best prompts - ActorOptimization->>ActorOptimization: Mutate and recombine + ActorOptimization ->> ActorOptimization: Select best prompts + ActorOptimization ->> ActorOptimization: Mutate and recombine end - ActorOptimization->>Developer: Return optimized prompts + ActorOptimization ->> Developer: Return optimized prompts ``` - ### Example ```kotlin @@ -674,9 +630,10 @@ val apiClient = OpenAIClient("your_api_key") val actorOptimization = ActorOptimization(apiClient, ChatModels.davinci) val optimizedPrompts = actorOptimization.runGeneticGenerations( prompts = listOf("Initial prompt"), - testCases = listOf(TestCase(...)), - actorFactory = { prompt -> YourActor(prompt) }, - resultMapper = { result -> result.toString() } + testCases = listOf(TestCase(...) +), +actorFactory = { prompt -> YourActor(prompt) }, +resultMapper = { result -> result.toString() } ) ``` @@ -684,31 +641,29 @@ This example demonstrates how to instantiate the `ActorOptimization` class, defi # kotlin\com\simiacryptus\skyenet\core\actors\ParsedActor.kt - ## ParsedActor Class Documentation -The `ParsedActor` class is a specialized actor designed for parsing user messages into JSON objects of a specified type. It extends the `BaseActor, ParsedResponse>` class, leveraging the OpenAI API to interpret and transform textual input into structured data. - +The `ParsedActor` class is a specialized actor designed for parsing user messages into JSON objects of a specified type. It extends the +`BaseActor, ParsedResponse>` class, leveraging the OpenAI API to interpret and transform textual input into structured data. ### Class Overview ```mermaid classDiagram - class ParsedActor~T~ { - -Class~T~ resultClass - -T exampleInstance - -ChatModels parsingModel - -int deserializerRetries - -TypeDescriber describer - +ParsedActor(Class~T~, T, String, String?, ChatModels, Double, ChatModels, Int, TypeDescriber) - +getParser(API) Function~String, T~ - +respond(List~String~, API, ApiModel.ChatMessage) ParsedResponse~T~ - +withModel(ChatModels) ParsedActor~T~ - } - ParsedActor~T~ --> "1" BaseActor : extends + class ParsedActor~T~ { + -Class~T~ resultClass + -T exampleInstance + -ChatModels parsingModel + -int deserializerRetries + -TypeDescriber describer + +ParsedActor(Class~T~, T, String, String?, ChatModels, Double, ChatModels, Int, TypeDescriber) + +getParser(API) Function~String, T~ + +respond(List~String~, API, ApiModel.ChatMessage) ParsedResponse~T~ + +withModel(ChatModels) ParsedActor~T~ + } + ParsedActor~T~ --> "1" BaseActor: extends ``` - ### Constructor Parameters - `resultClass`: The class type of the result. @@ -721,35 +676,33 @@ classDiagram - `deserializerRetries`: The number of retries for deserialization attempts. - `describer`: A `TypeDescriber` instance for describing the result class type. - ### Methods - #### getParser Returns a function that takes a string input and returns an instance of `T` by parsing the input using the OpenAI API. **Parameters:** -- `api`: The `API` instance to be used for making requests to OpenAI. +- `api`: The `API` instance to be used for making requests to OpenAI. #### respond Generates a `ParsedResponse` from a list of input strings and additional chat messages. **Parameters:** + - `input`: A list of input strings to be parsed. - `api`: The `API` instance to be used for making requests to OpenAI. - `messages`: Additional chat messages to be included in the request. - #### withModel Creates a new instance of `ParsedActor` with the specified OpenAI model. **Parameters:** -- `model`: The OpenAI model to be used. +- `model`: The OpenAI model to be used. ### Usage Example @@ -768,18 +721,17 @@ val result: MyClass = parsedResponse.obj This example demonstrates how to instantiate a `ParsedActor` for a hypothetical `MyClass`, use it to parse an input message, and retrieve the parsed object. - ### Note -The `ParsedActor` class is designed to work with the OpenAI API and requires a valid API key for operation. It is also important to handle exceptions and errors gracefully, especially considering the potential for parsing failures or API request limits. +The `ParsedActor` class is designed to work with the OpenAI API and requires a valid API key for operation. It is also important to handle exceptions and errors gracefully, +especially considering the potential for parsing failures or API request limits. # kotlin\com\simiacryptus\skyenet\core\actors\ParsedResponse.kt - ## Developer Documentation for `ParsedResponse` Class -The `ParsedResponse` class serves as an abstract base for handling parsed responses in the `com.simiacryptus.skyenet.core.actors` package. It is designed to encapsulate the response obtained from various sources, providing a structured way to access both the raw text and the parsed object of a specified type. - +The `ParsedResponse` class serves as an abstract base for handling parsed responses in the `com.simiacryptus.skyenet.core.actors` package. It is designed to encapsulate the +response obtained from various sources, providing a structured way to access both the raw text and the parsed object of a specified type. ### Class Overview @@ -793,28 +745,23 @@ abstract class ParsedResponse(val clazz: Class) { } ``` - #### Generics - `T`: The type parameter `T` represents the type of the object that the response text will be parsed into. This allows for flexibility in handling different types of parsed data. - #### Constructor Parameters - `clazz: Class`: This parameter is used to specify the class type of the parsed object. It is essential for runtime type checks and casting. - #### Properties - `text: String`: An abstract property that should be overridden to provide the raw text of the response. - `obj: T`: An abstract property that should be overridden to provide the parsed object derived from the response text. - #### Methods - `toString()`: Overrides the `toString` method to return the raw text of the response. This can be useful for debugging or logging purposes. - ### Usage Diagram To illustrate how the `ParsedResponse` class might be used within a system, consider the following mermaid.js diagram: @@ -833,42 +780,45 @@ classDiagram +obj: T } ParsedResponse <|-- SpecificResponse: Inherits - + class Client { +fetchData(): ParsedResponse } Client --> ParsedResponse: Uses - + class DataProcessor { +processData(ParsedResponse): void } DataProcessor --> ParsedResponse: Uses ``` - #### Explanation -- `SpecificResponse`: Represents a concrete implementation of `ParsedResponse` tailored to a specific type of data. It provides concrete implementations for the abstract properties `text` and `obj`. +- `SpecificResponse`: Represents a concrete implementation of `ParsedResponse` tailored to a specific type of data. It provides concrete implementations for the abstract properties + `text` and `obj`. - `Client`: A class that fetches data and returns a `ParsedResponse` or one of its subclasses, encapsulating the fetched data. -- `DataProcessor`: A class that takes a `ParsedResponse` as input for processing. It can work with any subclass of `ParsedResponse`, making it flexible to changes in the type of data being processed. - +- `DataProcessor`: A class that takes a `ParsedResponse` as input for processing. It can work with any subclass of `ParsedResponse`, making it flexible to changes in the type of + data being processed. ### Conclusion -The `ParsedResponse` class provides a robust foundation for handling and encapsulating parsed responses. By using generics and abstract properties, it offers a flexible and type-safe way to work with different kinds of data across the system. Implementing classes need to provide concrete details for the raw text and the parsed object, allowing for specific handling of various response types. +The `ParsedResponse` class provides a robust foundation for handling and encapsulating parsed responses. By using generics and abstract properties, it offers a flexible and +type-safe way to work with different kinds of data across the system. Implementing classes need to provide concrete details for the raw text and the parsed object, allowing for +specific handling of various response types. # kotlin\com\simiacryptus\skyenet\core\actors\record\CodingActorInterceptor.kt - ## Developer Documentation for `CodingActorInterceptor` -The `CodingActorInterceptor` class is designed to act as a decorator for instances of `CodingActor`, providing an interception layer for method calls related to code generation and execution. This allows for additional processing, such as logging, metrics collection, or modification of inputs and outputs, without modifying the original `CodingActor` implementation. - +The `CodingActorInterceptor` class is designed to act as a decorator for instances of `CodingActor`, providing an interception layer for method calls related to code generation and +execution. This allows for additional processing, such as logging, metrics collection, or modification of inputs and outputs, without modifying the original `CodingActor` +implementation. ### Overview -The `CodingActorInterceptor` extends `CodingActor` and requires an instance of `CodingActor` (`inner`) and a `FunctionWrapper` (`functionInterceptor`) upon instantiation. The `inner` object represents the original actor that is being decorated, while the `functionInterceptor` is used to wrap method calls, allowing for custom logic to be executed before and after the original method. - +The `CodingActorInterceptor` extends `CodingActor` and requires an instance of `CodingActor` (`inner`) and a `FunctionWrapper` (`functionInterceptor`) upon instantiation. The +`inner` object represents the original actor that is being decorated, while the `functionInterceptor` is used to wrap method calls, allowing for custom logic to be executed before +and after the original method. ### Class Diagram @@ -890,45 +840,47 @@ classDiagram class FunctionWrapper { +wrap(args: Any[], callback: Function) } - CodingActor <|-- CodingActorInterceptor : extends + CodingActor <|-- CodingActorInterceptor: extends ``` - ### Key Methods - #### `response` -Overrides the `response` method from `CodingActor`. It uses the `functionInterceptor` to wrap the original `response` method of the `inner` `CodingActor`, allowing for interception of the method call. +Overrides the `response` method from `CodingActor`. It uses the `functionInterceptor` to wrap the original `response` method of the `inner` `CodingActor`, allowing for interception +of the method call. **Parameters:** + - `input`: An array of `ChatMessage` objects representing the input messages. - `model`: The `OpenAIModel` to use for generating responses. - `api`: The `API` instance for interacting with external services. - #### `respond` -Overrides the `respond` method from `CodingActor`. It directly calls the `respond` method of the `inner` `CodingActor` but wraps the input and output through the `functionInterceptor`. +Overrides the `respond` method from `CodingActor`. It directly calls the `respond` method of the `inner` `CodingActor` but wraps the input and output through the +`functionInterceptor`. **Parameters:** + - `input`: A `CodeRequest` object representing the code generation request. - `api`: The `API` instance for interacting with external services. - `messages`: An array of `ChatMessage` objects representing additional context. - #### `execute` -Overrides the `execute` method from `CodingActor`. It uses the `functionInterceptor` to wrap the execution of code, allowing for interception and potential modification of the execution process. +Overrides the `execute` method from `CodingActor`. It uses the `functionInterceptor` to wrap the execution of code, allowing for interception and potential modification of the +execution process. **Parameters:** + - `prefix`: A `String` representing the prefix to be used in code execution. - `code`: The actual code `String` to be executed. - ### Usage Example -To use the `CodingActorInterceptor`, you first need an instance of `CodingActor` and a `FunctionWrapper` implementation. Then, you can create an instance of `CodingActorInterceptor` and use it in place of the original `CodingActor`. +To use the `CodingActorInterceptor`, you first need an instance of `CodingActor` and a `FunctionWrapper` implementation. Then, you can create an instance of +`CodingActorInterceptor` and use it in place of the original `CodingActor`. ```kotlin val originalActor: CodingActor = ... @@ -938,64 +890,63 @@ val interceptor = CodingActorInterceptor(originalActor, functionWrapper) // Now you can use `interceptor` in place of `originalActor` ``` -This setup allows you to intercept and augment the behavior of `CodingActor` methods transparently, enabling advanced use cases like logging, monitoring, or dynamic modification of inputs/outputs. +This setup allows you to intercept and augment the behavior of `CodingActor` methods transparently, enabling advanced use cases like logging, monitoring, or dynamic modification of +inputs/outputs. # kotlin\com\simiacryptus\skyenet\core\actors\record\ParsedActorInterceptor.kt - ## ParsedActorInterceptor Class Documentation -The `ParsedActorInterceptor` class is an extension of the `ParsedActor` class designed to intercept and modify responses from a parsed actor in a flexible manner. It is part of the `com.simiacryptus.skyenet.core.actors.record` package and is used to enhance or alter the behavior of an existing `ParsedActor` instance by applying custom logic to its responses. - +The `ParsedActorInterceptor` class is an extension of the `ParsedActor` class designed to intercept and modify responses from a parsed actor in a flexible manner. It is part of the +`com.simiacryptus.skyenet.core.actors.record` package and is used to enhance or alter the behavior of an existing `ParsedActor` instance by applying custom logic to its responses. ### Class Overview ```mermaid classDiagram ParsedActor <|-- ParsedActorInterceptor - ParsedActorInterceptor : +inner - ParsedActorInterceptor : +functionInterceptor - ParsedActorInterceptor : -respond(input, api, messages) - ParsedActorInterceptor : -response(input, model, api) + ParsedActorInterceptor: +inner + ParsedActorInterceptor: +functionInterceptor + ParsedActorInterceptor: -respond(input, api, messages) + ParsedActorInterceptor: -response(input, model, api) ``` - #### Constructor Parameters - `inner`: The `ParsedActor` instance that this interceptor wraps. This is the actor whose responses are to be intercepted. - `functionInterceptor`: An instance of `FunctionWrapper`, which provides the logic for intercepting and potentially modifying the responses. - #### Methods - ##### `respond` -Overrides the `respond` method from the `ParsedActor` class. It takes a list of input strings and additional parameters to generate a response. This method utilizes the `functionInterceptor` to apply custom logic to the response. +Overrides the `respond` method from the `ParsedActor` class. It takes a list of input strings and additional parameters to generate a response. This method utilizes the +`functionInterceptor` to apply custom logic to the response. **Parameters:** + - `input`: A list of input strings for the actor to respond to. - `api`: An instance of `API` to interact with external services. - `messages`: Vararg parameter of `com.simiacryptus.jopenai.ApiModel.ChatMessage`, representing additional context or messages. **Returns:** An instance of `ParsedResponse`, which contains the intercepted and potentially modified response. - ##### `response` Overrides the `response` method from the `ParsedActor` class. It is designed to handle responses based on chat messages, model, and API. **Parameters:** + - `input`: Vararg parameter of `com.simiacryptus.jopenai.ApiModel.ChatMessage`, representing the input messages. - `model`: An instance of `OpenAIModel` specifying the model to use for generating responses. - `api`: An instance of `API` for interacting with external services. **Returns:** The result of the intercepted response, as modified by the `functionInterceptor`. - ### Usage Example -To use the `ParsedActorInterceptor`, you first need an instance of a `ParsedActor` and a `FunctionWrapper` that defines how you want to intercept and modify the responses. Once you have these, you can create an instance of `ParsedActorInterceptor` and use it in place of the original `ParsedActor`. +To use the `ParsedActorInterceptor`, you first need an instance of a `ParsedActor` and a `FunctionWrapper` that defines how you want to intercept and modify the responses. Once you +have these, you can create an instance of `ParsedActorInterceptor` and use it in place of the original `ParsedActor`. ```kotlin val originalActor = ParsedActor( @@ -1018,16 +969,16 @@ This setup allows you to seamlessly modify the behavior of any `ParsedActor` ins # kotlin\com\simiacryptus\skyenet\core\actors\record\ImageActorInterceptor.kt - ## Developer Documentation for `ImageActorInterceptor` -The `ImageActorInterceptor` class is a part of the `com.simiacryptus.skyenet.core.actors.record` package, designed to intercept and potentially modify the behavior of an `ImageActor` instance. This class is particularly useful for debugging, logging, or applying custom transformations to the inputs or outputs of the `ImageActor` methods. - +The `ImageActorInterceptor` class is a part of the `com.simiacryptus.skyenet.core.actors.record` package, designed to intercept and potentially modify the behavior of an +`ImageActor` instance. This class is particularly useful for debugging, logging, or applying custom transformations to the inputs or outputs of the `ImageActor` methods. ### Overview -`ImageActorInterceptor` extends `ImageActor`, allowing it to seamlessly integrate into places where an `ImageActor` is expected. It wraps around an existing `ImageActor` instance, intercepting calls to the `response` and `render` methods. This interception is facilitated by a `FunctionWrapper` instance, which provides the mechanism to wrap and potentially modify the behavior of these methods. - +`ImageActorInterceptor` extends `ImageActor`, allowing it to seamlessly integrate into places where an `ImageActor` is expected. It wraps around an existing `ImageActor` instance, +intercepting calls to the `response` and `render` methods. This interception is facilitated by a `FunctionWrapper` instance, which provides the mechanism to wrap and potentially +modify the behavior of these methods. ### Class Diagram @@ -1048,22 +999,20 @@ classDiagram +wrap(input: Any, action: Function): Any } ImageActor <|-- ImageActorInterceptor - ImageActorInterceptor --> FunctionWrapper : uses + ImageActorInterceptor --> FunctionWrapper: uses ``` - ### Constructor Parameters - `inner: ImageActor`: The `ImageActor` instance that this interceptor wraps around. - `functionInterceptor: FunctionWrapper`: The `FunctionWrapper` instance used to intercept and potentially modify the behavior of the `inner` `ImageActor`'s methods. - ### Methods - #### `response` -Overrides the `response` method from `ImageActor`. It intercepts calls to the `inner` `ImageActor`'s `response` method, allowing for pre-processing of the input messages and/or post-processing of the output. +Overrides the `response` method from `ImageActor`. It intercepts calls to the `inner` `ImageActor`'s `response` method, allowing for pre-processing of the input messages and/or +post-processing of the output. **Parameters:** @@ -1073,10 +1022,10 @@ Overrides the `response` method from `ImageActor`. It intercepts calls to the `i **Returns:** The result of the `inner` `ImageActor`'s `response` method, potentially modified by the `functionInterceptor`. - #### `render` -Overrides the `render` method from `ImageActor`. It intercepts calls to the `inner` `ImageActor`'s `render` method, allowing for pre-processing of the input text and/or post-processing of the output image. +Overrides the `render` method from `ImageActor`. It intercepts calls to the `inner` `ImageActor`'s `render` method, allowing for pre-processing of the input text and/or +post-processing of the output image. **Parameters:** @@ -1085,7 +1034,6 @@ Overrides the `render` method from `ImageActor`. It intercepts calls to the `inn **Returns:** A `BufferedImage` generated by the `inner` `ImageActor`'s `render` method, potentially modified by the `functionInterceptor`. - ### Usage Example ```kotlin @@ -1101,57 +1049,55 @@ val interceptor = ImageActorInterceptor(originalActor, functionWrapper) // Now, use `interceptor` wherever an `ImageActor` is expected. ``` -This setup allows developers to inject custom logic before and after the execution of the `response` and `render` methods of an `ImageActor`, without modifying the original `ImageActor` implementation. +This setup allows developers to inject custom logic before and after the execution of the `response` and `render` methods of an `ImageActor`, without modifying the original +`ImageActor` implementation. # kotlin\com\simiacryptus\skyenet\core\actors\record\SimpleActorInterceptor.kt - ## Developer Documentation: SimpleActorInterceptor -The `SimpleActorInterceptor` class is designed to act as a decorator for instances of `SimpleActor`, allowing developers to intercept and potentially modify the behavior of the `SimpleActor`'s `response` method. This class is part of the `com.simiacryptus.skyenet.core.actors.record` package and leverages functionality from the `com.simiacryptus.jopenai` package for OpenAI model interactions. - +The `SimpleActorInterceptor` class is designed to act as a decorator for instances of `SimpleActor`, allowing developers to intercept and potentially modify the behavior of the +`SimpleActor`'s `response` method. This class is part of the `com.simiacryptus.skyenet.core.actors.record` package and leverages functionality from the `com.simiacryptus.jopenai` +package for OpenAI model interactions. ### Overview -The `SimpleActorInterceptor` extends `SimpleActor` and overrides its `response` method. It introduces an interception layer through which all calls to the `response` method are passed. This interception is facilitated by a `FunctionWrapper`, which can modify the input, output, or behavior of the `response` method dynamically at runtime. - +The `SimpleActorInterceptor` extends `SimpleActor` and overrides its `response` method. It introduces an interception layer through which all calls to the `response` method are +passed. This interception is facilitated by a `FunctionWrapper`, which can modify the input, output, or behavior of the `response` method dynamically at runtime. ### Class Diagram ```mermaid classDiagram SimpleActor <|-- SimpleActorInterceptor - SimpleActorInterceptor : +inner - SimpleActorInterceptor : +functionInterceptor - SimpleActorInterceptor : +response(input, model, api) - class SimpleActor{ - <> - +prompt - +name - +model - +temperature - +response(input, model, api) + SimpleActorInterceptor: +inner + SimpleActorInterceptor: +functionInterceptor + SimpleActorInterceptor: +response(input, model, api) + class SimpleActor { + <> + +prompt + +name + +model + +temperature + +response(input, model, api) } - class SimpleActorInterceptor{ - +inner SimpleActor - +functionInterceptor FunctionWrapper - +response(input, model, api) + class SimpleActorInterceptor { + +inner SimpleActor + +functionInterceptor FunctionWrapper + +response(input, model, api) } - class FunctionWrapper{ - +wrap(input, model, function) + class FunctionWrapper { + +wrap(input, model, function) } ``` - ### Constructor Parameters - `inner`: The `SimpleActor` instance that this interceptor wraps. - `functionInterceptor`: An instance of `FunctionWrapper` that defines how to intercept the `response` method calls. - ### Methods - #### response Overrides the `response` method from `SimpleActor`. It uses the `functionInterceptor` to potentially modify the behavior of the `inner` `SimpleActor`'s `response` method. @@ -1174,8 +1120,8 @@ override fun response( **Return Value:** -The return type is dependent on the implementation of the `functionInterceptor`'s `wrap` method, which could modify the return value of the `inner` `SimpleActor`'s `response` method. - +The return type is dependent on the implementation of the `functionInterceptor`'s `wrap` method, which could modify the return value of the `inner` `SimpleActor`'s `response` +method. ### Usage Example @@ -1191,34 +1137,33 @@ val simpleActorInterceptor = SimpleActorInterceptor(simpleActor, interceptor) simpleActorInterceptor.response(inputMessages, model, api) ``` -This documentation provides a comprehensive overview of the `SimpleActorInterceptor` class, its purpose, and how it can be utilized to intercept and modify the behavior of `SimpleActor` instances dynamically. +This documentation provides a comprehensive overview of the `SimpleActorInterceptor` class, its purpose, and how it can be utilized to intercept and modify the behavior of +`SimpleActor` instances dynamically. # kotlin\com\simiacryptus\skyenet\core\actors\SimpleActor.kt - ## SimpleActor Class Documentation -The `SimpleActor` class is a specialized actor designed for interacting with OpenAI's GPT models via the `com.simiacryptus.jopenai` API. It extends the `BaseActor` class, providing a simple interface for sending prompts to the model and receiving responses. - +The `SimpleActor` class is a specialized actor designed for interacting with OpenAI's GPT models via the `com.simiacryptus.jopenai` API. It extends the `BaseActor` class, providing +a simple interface for sending prompts to the model and receiving responses. ### Class Overview ```mermaid classDiagram BaseActor <|-- SimpleActor - BaseActor : +prompt - BaseActor : +name - BaseActor : +model - BaseActor : +temperature - BaseActor : +respond(input, api, messages) - BaseActor : +chatMessages(questions) - BaseActor : +withModel(model) - SimpleActor : +respond(input, api, messages) - SimpleActor : +chatMessages(questions) - SimpleActor : +withModel(model) + BaseActor: +prompt + BaseActor: +name + BaseActor: +model + BaseActor: +temperature + BaseActor: +respond(input, api, messages) + BaseActor: +chatMessages(questions) + BaseActor: +withModel(model) + SimpleActor: +respond(input, api, messages) + SimpleActor: +chatMessages(questions) + SimpleActor: +withModel(model) ``` - ### Constructor The `SimpleActor` class constructor initializes a new instance with the specified parameters. @@ -1227,12 +1172,11 @@ The `SimpleActor` class constructor initializes a new instance with the specifie SimpleActor( prompt: String, name: String? = null, - model: ChatModels, - temperature: Double = 0.3, +model: ChatModels, +temperature: Double = 0.3, ) ``` - #### Parameters - `prompt`: The initial prompt or question to be sent to the model. @@ -1240,10 +1184,8 @@ SimpleActor( - `model`: The GPT model to be used for generating responses. - `temperature`: Controls the randomness of the response. Lower values make responses more deterministic. - ### Methods - #### respond Generates a response based on the input and the specified messages. @@ -1252,24 +1194,20 @@ Generates a response based on the input and the specified messages. override fun respond(input: List, api: API, vararg messages: ApiModel.ChatMessage): String ``` - ##### Parameters - `input`: A list of strings representing the input for the model. - `api`: An instance of the `API` class to interact with the OpenAI API. - `messages`: Variable number of `ApiModel.ChatMessage` objects representing the conversation history. - ##### Returns - A `String` representing the model's response. - ##### Throws - `RuntimeException` if no response is received. - #### chatMessages Prepares the chat messages to be sent to the model based on the provided questions. @@ -1278,17 +1216,14 @@ Prepares the chat messages to be sent to the model based on the provided questio override fun chatMessages(questions: List): Array ``` - ##### Parameters - `questions`: A list of strings representing the questions to be sent to the model. - ##### Returns - An array of `ApiModel.ChatMessage` objects representing the formatted chat messages. - #### withModel Creates a new instance of `SimpleActor` with the specified model. @@ -1297,17 +1232,14 @@ Creates a new instance of `SimpleActor` with the specified model. override fun withModel(model: ChatModels): SimpleActor ``` - ##### Parameters - `model`: The GPT model to be used for generating responses. - ##### Returns - A new instance of `SimpleActor` configured with the specified model. - ### Usage Example ```kotlin @@ -1330,11 +1262,11 @@ This example demonstrates how to create an instance of `SimpleActor`, send a pro # kotlin\com\simiacryptus\skyenet\core\actors\record\TextToSpeechActorInterceptor.kt - ## Developer Documentation for `TextToSpeechActorInterceptor` -The `TextToSpeechActorInterceptor` class is designed to act as a decorator for instances of `TextToSpeechActor`, providing an interception mechanism for the `response` and `render` methods through a `FunctionWrapper`. This allows for additional processing, logging, or modification of inputs and outputs without altering the original `TextToSpeechActor` behavior. - +The `TextToSpeechActorInterceptor` class is designed to act as a decorator for instances of `TextToSpeechActor`, providing an interception mechanism for the `response` and `render` +methods through a `FunctionWrapper`. This allows for additional processing, logging, or modification of inputs and outputs without altering the original `TextToSpeechActor` +behavior. ### Class Overview @@ -1349,19 +1281,17 @@ classDiagram TextToSpeechActorInterceptor --|> TextToSpeechActor: Inherits ``` - #### Constructor Parameters - `inner`: The `TextToSpeechActor` instance that this interceptor will wrap. - `functionInterceptor`: A `FunctionWrapper` instance used to intercept calls to the `response` and `render` methods. - #### Methods - ##### `response` -Intercepts calls to the `response` method of the `TextToSpeechActor`. It allows for pre-processing or post-processing of the input messages and the model before delegating the call to the original `TextToSpeechActor` instance. +Intercepts calls to the `response` method of the `TextToSpeechActor`. It allows for pre-processing or post-processing of the input messages and the model before delegating the call +to the original `TextToSpeechActor` instance. **Parameters:** @@ -1371,10 +1301,10 @@ Intercepts calls to the `response` method of the `TextToSpeechActor`. It allows **Returns:** A `ByteArray` representing the audio data generated by the `TextToSpeechActor`. - ##### `render` -Intercepts calls to the `render` method of the `TextToSpeechActor`. It allows for pre-processing or post-processing of the input text before delegating the call to the original `TextToSpeechActor` instance. +Intercepts calls to the `render` method of the `TextToSpeechActor`. It allows for pre-processing or post-processing of the input text before delegating the call to the original +`TextToSpeechActor` instance. **Parameters:** @@ -1383,7 +1313,6 @@ Intercepts calls to the `render` method of the `TextToSpeechActor`. It allows fo **Returns:** A `ByteArray` representing the audio data generated by the `TextToSpeechActor`. - ### Usage Example ```kotlin @@ -1400,67 +1329,64 @@ val actorInterceptor = TextToSpeechActorInterceptor(originalActor, interceptor) val audioData = actorInterceptor.render("Hello, world!", apiInstance) ``` -This setup allows developers to inject custom logic, such as logging, metrics collection, or input/output modification, into the process of generating text-to-speech responses without modifying the core functionality of the `TextToSpeechActor`. +This setup allows developers to inject custom logic, such as logging, metrics collection, or input/output modification, into the process of generating text-to-speech responses +without modifying the core functionality of the `TextToSpeechActor`. # kotlin\com\simiacryptus\skyenet\core\actors\test\CodingActorTestBase.kt - ## Developer Documentation for `CodingActorTestBase` -The `CodingActorTestBase` class is an abstract base class designed for testing coding actors in the Skyenet framework. It extends the `ActorTestBase` class, specializing in handling code requests and results through the `CodingActor` class. This document provides an overview of its structure, usage, and key components. - +The `CodingActorTestBase` class is an abstract base class designed for testing coding actors in the Skyenet framework. It extends the `ActorTestBase` class, specializing in +handling code requests and results through the `CodingActor` class. This document provides an overview of its structure, usage, and key components. ### Overview -`CodingActorTestBase` facilitates the testing of coding actors, which are specialized actors designed to generate code based on given prompts. It leverages an interpreter (specified by the subclass) and a model (GPT-3.5 Turbo by default) to process coding requests and generate code snippets as responses. - +`CodingActorTestBase` facilitates the testing of coding actors, which are specialized actors designed to generate code based on given prompts. It leverages an interpreter ( +specified by the subclass) and a model (GPT-3.5 Turbo by default) to process coding requests and generate code snippets as responses. ### Class Diagram ```mermaid classDiagram ActorTestBase <|-- CodingActorTestBase - CodingActorTestBase : +interpreterClass KClass - CodingActorTestBase : +actorFactory(prompt String) CodingActor - CodingActorTestBase : +getPrompt(actor BaseActor) String - CodingActorTestBase : +resultMapper(result CodeResult) String - class ActorTestBase{ + CodingActorTestBase: +interpreterClass KClass + CodingActorTestBase: +actorFactory(prompt String) CodingActor + CodingActorTestBase: +getPrompt(actor BaseActor) String + CodingActorTestBase: +resultMapper(result CodeResult) String + class ActorTestBase { +actorFactory(prompt String) BaseActor +getPrompt(actor BaseActor) String +resultMapper(result Any) String } - class CodingActor{ + class CodingActor { -interpreterClass KClass -details String -model ChatModels } - class BaseActor{ + class BaseActor { } - class CodeResult{ + class CodeResult { +code String } ``` - ### Key Components - #### Properties - `abstract val interpreterClass: KClass`: Specifies the class of the interpreter to be used by the `CodingActor`. This must be provided by the subclass. - #### Methods -- `override fun actorFactory(prompt: String): CodingActor`: Creates an instance of `CodingActor` with the specified `interpreterClass`, `details` (prompt), and the model set to `OpenAIModels.GPT35Turbo`. +- `override fun actorFactory(prompt: String): CodingActor`: Creates an instance of `CodingActor` with the specified `interpreterClass`, `details` (prompt), and the model set to + `OpenAIModels.GPT35Turbo`. - `override fun getPrompt(actor: BaseActor): String`: Retrieves the prompt details from the given `CodingActor` instance. - `override fun resultMapper(result: CodeResult): String`: Maps the `CodeResult` to its `code` property, effectively extracting the generated code snippet. - ### Usage -To use `CodingActorTestBase`, a subclass must be created that provides a concrete implementation for the `interpreterClass` property. This subclass can then instantiate `CodingActor` instances tailored to specific testing scenarios, leveraging the provided model and interpreter for generating code based on prompts. - +To use `CodingActorTestBase`, a subclass must be created that provides a concrete implementation for the `interpreterClass` property. This subclass can then instantiate +`CodingActor` instances tailored to specific testing scenarios, leveraging the provided model and interpreter for generating code based on prompts. #### Example Subclass @@ -1472,23 +1398,24 @@ class MyCodingActorTest : CodingActorTestBase() { In this example, `MyCustomInterpreter` would be a class that extends `Interpreter`, tailored to the specific needs of the test scenarios being developed. - ### Conclusion -`CodingActorTestBase` provides a structured approach to testing coding actors within the Skyenet framework, abstracting away common functionalities such as actor instantiation and result mapping. By extending this class and providing an interpreter, developers can efficiently create robust tests for their coding actors, ensuring their functionality and reliability. +`CodingActorTestBase` provides a structured approach to testing coding actors within the Skyenet framework, abstracting away common functionalities such as actor instantiation and +result mapping. By extending this class and providing an interpreter, developers can efficiently create robust tests for their coding actors, ensuring their functionality and +reliability. # kotlin\com\simiacryptus\skyenet\core\actors\test\ActorTestBase.kt - ## Developer Documentation for `ActorTestBase` -The `ActorTestBase` class serves as an abstract base for testing actors within a system designed to interact with OpenAI's GPT models. It provides a structured way to optimize and test actors based on predefined test cases. - +The `ActorTestBase` class serves as an abstract base for testing actors within a system designed to interact with OpenAI's GPT models. It provides a structured way to optimize and +test actors based on predefined test cases. ### Overview -`ActorTestBase` is an abstract class that requires the implementation of several key components to facilitate the testing and optimization of actors. These components include the actor itself, a method to generate actors based on prompts, and a way to map the results to a string representation. Additionally, it integrates with the OpenAI API through the `OpenAIClient`. - +`ActorTestBase` is an abstract class that requires the implementation of several key components to facilitate the testing and optimization of actors. These components include the +actor itself, a method to generate actors based on prompts, and a way to map the results to a string representation. Additionally, it integrates with the OpenAI API through the +`OpenAIClient`. #### Key Components @@ -1497,15 +1424,14 @@ The `ActorTestBase` class serves as an abstract base for testing actors within a - **Actor Factory**: A method to create new instances of the actor based on a given prompt. - **Result Mapper**: A method to convert the actor's response into a string format for logging or comparison. - ### Workflow The testing and optimization process involves several steps, including setting up test cases, running optimizations, and executing tests to evaluate the actor's performance. - #### Optimization Process -The optimization process (`opt` method) utilizes a genetic algorithm approach to evolve the actor based on the provided test cases. It involves generating a population of actors, evaluating their performance, and selecting the best performers for the next generation. +The optimization process (`opt` method) utilizes a genetic algorithm approach to evolve the actor based on the provided test cases. It involves generating a population of actors, +evaluating their performance, and selecting the best performers for the next generation. ```mermaid flowchart TD @@ -1517,10 +1443,10 @@ flowchart TD E -->|Yes| F[End Optimization] ``` - #### Testing Process -The testing process (`testRun` method) iterates through the provided test cases, generating responses from the actor and logging the results. This allows for a manual review of the actor's performance in specific scenarios. +The testing process (`testRun` method) iterates through the provided test cases, generating responses from the actor and logging the results. This allows for a manual review of the +actor's performance in specific scenarios. ```mermaid flowchart TD @@ -1532,7 +1458,6 @@ flowchart TD E -->|No| F[End Testing] ``` - ### Implementation Requirements To utilize the `ActorTestBase` class, the following abstract members must be implemented: @@ -1543,79 +1468,75 @@ To utilize the `ActorTestBase` class, the following abstract members must be imp - `getPrompt(actor: BaseActor)`: A method to generate a prompt for the actor based on its current state. - `resultMapper(result: R)`: A method to convert the actor's response into a string format. - ### Usage -To use the `ActorTestBase`, extend this class with a concrete implementation that provides the necessary components. Then, call `testOptimize` to run the optimization process or `testRun` to execute the test cases. - +To use the `ActorTestBase`, extend this class with a concrete implementation that provides the necessary components. Then, call `testOptimize` to run the optimization process or +`testRun` to execute the test cases. ### Conclusion -The `ActorTestBase` class provides a structured approach to testing and optimizing actors within a system. By implementing the required abstract members and following the outlined processes, developers can efficiently evaluate and improve their actors' performance. +The `ActorTestBase` class provides a structured approach to testing and optimizing actors within a system. By implementing the required abstract members and following the outlined +processes, developers can efficiently evaluate and improve their actors' performance. # kotlin\com\simiacryptus\skyenet\core\actors\test\ImageActorTestBase.kt - ## Developer Documentation for `ImageActorTestBase` -The `ImageActorTestBase` class is an abstract class designed for testing image-based actors within the Skyenet framework. It extends the generic `ActorTestBase` class, specifying `List` as the input type and `ImageResponse` as the output type. This setup is tailored for testing actors that generate images based on textual prompts. - +The `ImageActorTestBase` class is an abstract class designed for testing image-based actors within the Skyenet framework. It extends the generic `ActorTestBase` class, specifying +`List` as the input type and `ImageResponse` as the output type. This setup is tailored for testing actors that generate images based on textual prompts. ### Overview -The purpose of `ImageActorTestBase` is to provide a foundational structure for testing implementations of `ImageActor`. It encapsulates the common logic required for initializing an `ImageActor` with a specific prompt and a designated text model. The class is abstract, indicating that it is intended to be extended by concrete test classes that implement specific test scenarios for image generation actors. - +The purpose of `ImageActorTestBase` is to provide a foundational structure for testing implementations of `ImageActor`. It encapsulates the common logic required for initializing +an `ImageActor` with a specific prompt and a designated text model. The class is abstract, indicating that it is intended to be extended by concrete test classes that implement +specific test scenarios for image generation actors. ### Class Diagram ```mermaid classDiagram ActorTestBase <|-- ImageActorTestBase - ImageActorTestBase : +actorFactory(prompt: String) ImageActor - ActorTestBase : +testActor(input: List~String~, expectedOutput: ImageResponse) - class ActorTestBase{ - <> - +actorFactory(prompt: String) - +testActor(input, expectedOutput) - } - class ImageActor{ - +prompt: String - +textModel: ChatModels - } - class ImageResponse{ - } + ImageActorTestBase: +actorFactory(prompt: String) ImageActor +ActorTestBase: +testActor(input: List~String~, expectedOutput: ImageResponse) +class ActorTestBase{ +<> ++actorFactory(prompt: String) ++testActor(input, expectedOutput) + } +class ImageActor{ ++prompt: String ++textModel: ChatModels + } +class ImageResponse{ + } ``` - ### Key Components - #### `ImageActorTestBase` - **Type Parameters**: Inherits `, ImageResponse>` from `ActorTestBase`, indicating it takes a list of strings as input and produces an `ImageResponse`. - **Methods**: - - `actorFactory(prompt: String)`: This abstract method is overridden to return an instance of `ImageActor` configured with the provided `prompt` and the `GPT35Turbo` model from `ChatModels`. - + - `actorFactory(prompt: String)`: This abstract method is overridden to return an instance of `ImageActor` configured with the provided `prompt` and the `GPT35Turbo` model from + `ChatModels`. #### `ActorTestBase` -- This is a generic abstract class that `ImageActorTestBase` extends. It defines the structure for testing actors by specifying an `actorFactory` method that must be implemented by subclasses and a `testActor` method for running tests. - +- This is a generic abstract class that `ImageActorTestBase` extends. It defines the structure for testing actors by specifying an `actorFactory` method that must be implemented by + subclasses and a `testActor` method for running tests. #### `ImageActor` - Represents an actor that generates images based on textual prompts. It is initialized with a `prompt` and a `textModel` for generating responses. - #### `ImageResponse` - A class representing the response from an `ImageActor`. It encapsulates the generated image data. - ### Usage -To use `ImageActorTestBase`, developers should create a subclass that implements specific tests for `ImageActor` implementations. The subclass must provide concrete logic for how tests are executed, including defining expected outputs and handling assertions. - +To use `ImageActorTestBase`, developers should create a subclass that implements specific tests for `ImageActor` implementations. The subclass must provide concrete logic for how +tests are executed, including defining expected outputs and handling assertions. #### Example @@ -1630,29 +1551,28 @@ class MyImageActorTest : ImageActorTestBase() { } ``` -In this example, `MyImageActorTest` extends `ImageActorTestBase` and implements a test method that specifies a prompt and an expected image response. The `testActor` method from `ActorTestBase` is used to run the test, which internally uses the `actorFactory` method to create an `ImageActor` instance for the test. - +In this example, `MyImageActorTest` extends `ImageActorTestBase` and implements a test method that specifies a prompt and an expected image response. The `testActor` method from +`ActorTestBase` is used to run the test, which internally uses the `actorFactory` method to create an `ImageActor` instance for the test. ### Conclusion -`ImageActorTestBase` provides a structured approach to testing image generation actors within the Skyenet framework. By extending this class and implementing specific test scenarios, developers can efficiently test and validate the functionality of `ImageActor` implementations. +`ImageActorTestBase` provides a structured approach to testing image generation actors within the Skyenet framework. By extending this class and implementing specific test +scenarios, developers can efficiently test and validate the functionality of `ImageActor` implementations. # kotlin\com\simiacryptus\skyenet\core\actors\TextToSpeechActor.kt - ## TextToSpeechActor Documentation -The `TextToSpeechActor` class is part of the `com.simiacryptus.skyenet.core.actors` package and is designed to convert text to speech using OpenAI's API. This document provides an overview of its functionality, usage, and key components. - +The `TextToSpeechActor` class is part of the `com.simiacryptus.skyenet.core.actors` package and is designed to convert text to speech using OpenAI's API. This document provides an +overview of its functionality, usage, and key components. ### Overview -`TextToSpeechActor` extends `BaseActor` and is specialized in handling text-to-speech (TTS) conversion. It leverages OpenAI's API to generate speech from text inputs. The class supports customization of the audio model, voice, and speed of the speech output. - +`TextToSpeechActor` extends `BaseActor` and is specialized in handling text-to-speech (TTS) conversion. It leverages OpenAI's API to generate speech from text inputs. The class +supports customization of the audio model, voice, and speed of the speech output. ### Key Components - #### Constructor Parameters - `name`: Optional name for the actor. @@ -1661,27 +1581,24 @@ The `TextToSpeechActor` class is part of the `com.simiacryptus.skyenet.core.acto - `speed`: The speed of the speech. Defaults to `1.0`. - `models`: The chat models to use for generating responses. - #### Methods - `chatMessages(questions: List)`: Converts a list of questions into an array of `ChatMessage` objects. - `render(text: String, api: API)`: Generates speech from text using the specified API. - `respond(input: List, api: API, vararg messages: ChatMessage)`: Processes the input text and generates a `SpeechResponse`. - #### Inner Classes - `SpeechResponseImpl`: Implementation of the `SpeechResponse` interface, holding the generated speech data. - #### Interfaces - `SpeechResponse`: Interface defining the structure for speech response objects. - ### Usage -To use `TextToSpeechActor`, you need to instantiate it with the desired configuration parameters. Then, you can call the `respond` method with a list of input strings and an API instance to generate speech. +To use `TextToSpeechActor`, you need to instantiate it with the desired configuration parameters. Then, you can call the `respond` method with a list of input strings and an API +instance to generate speech. ```kotlin val ttsActor = TextToSpeechActor( @@ -1698,10 +1615,8 @@ val speechResponse = ttsActor.respond(inputText, api) val mp3Data = speechResponse.mp3data ``` - ### Diagrams - #### TextToSpeechActor Workflow ```mermaid @@ -1709,33 +1624,32 @@ sequenceDiagram participant User participant TextToSpeechActor as TTS Actor participant OpenAIAPI as OpenAI API - - User->>TTS Actor: Instantiate with Config - User->>TTS Actor: Call respond(input, api) - TTS Actor->>OpenAIAPI: Generate Speech - OpenAIAPI-->>TTS Actor: Speech Data - TTS Actor-->>User: SpeechResponse + User ->> TTS Actor: Instantiate with Config + User ->> TTS Actor: Call respond(input, api) + TTS Actor ->> OpenAIAPI: Generate Speech + OpenAIAPI -->> TTS Actor: Speech Data + TTS Actor -->> User: SpeechResponse ``` -This diagram illustrates the basic workflow of using `TextToSpeechActor` to convert text to speech. The user instantiates the actor with the desired configuration, calls the `respond` method with input text, and the actor interacts with OpenAI's API to generate and return the speech data. - +This diagram illustrates the basic workflow of using `TextToSpeechActor` to convert text to speech. The user instantiates the actor with the desired configuration, calls the +`respond` method with input text, and the actor interacts with OpenAI's API to generate and return the speech data. ### Conclusion -The `TextToSpeechActor` class provides a convenient way to integrate text-to-speech functionality into applications using OpenAI's API. By customizing the audio model, voice, and speed, developers can generate speech that fits their specific needs. +The `TextToSpeechActor` class provides a convenient way to integrate text-to-speech functionality into applications using OpenAI's API. By customizing the audio model, voice, and +speed, developers can generate speech that fits their specific needs. # kotlin\com\simiacryptus\skyenet\core\platform\AwsPlatform.kt - ## AWS Platform Integration Documentation -The `AwsPlatform` class provides a seamless integration with AWS services, specifically Amazon S3 for object storage and AWS Key Management Service (KMS) for encryption and decryption of data. This document outlines the functionalities provided by the `AwsPlatform` class and how developers can utilize them in their projects. - +The `AwsPlatform` class provides a seamless integration with AWS services, specifically Amazon S3 for object storage and AWS Key Management Service (KMS) for encryption and +decryption of data. This document outlines the functionalities provided by the `AwsPlatform` class and how developers can utilize them in their projects. ### Overview -`AwsPlatform` implements the `CloudPlatformInterface`, providing methods to upload data to S3, and to encrypt and decrypt data using AWS KMS. It is designed to be easily integrated into projects requiring cloud storage and data encryption services. - +`AwsPlatform` implements the `CloudPlatformInterface`, providing methods to upload data to S3, and to encrypt and decrypt data using AWS KMS. It is designed to be easily integrated +into projects requiring cloud storage and data encryption services. ### Initialization @@ -1743,60 +1657,52 @@ The class is initialized with optional parameters for the S3 bucket name, the ba ```kotlin val awsPlatform = AwsPlatform( - bucket = "your-bucket-name", - shareBase = "https://your-base-url", - region = Region.US_EAST_1 + bucket = "your-bucket-name", + shareBase = "https://your-base-url", + region = Region.US_EAST_1 ) ``` - ### Configuration - #### S3 Client The S3 client is lazily initialized with the specified region. It is used for all interactions with Amazon S3. - #### KMS Client Similarly, the KMS client is lazily initialized and is used for encryption and decryption operations. It defaults to the US East (N. Virginia) region. - ### Functionalities - #### Upload to S3 The `upload` function is overloaded to support uploading either byte arrays or strings. It constructs the S3 object key from the provided path, ensuring it is properly formatted. ```kotlin val uploadPath = awsPlatform.upload( - path = "path/to/object", - contentType = "application/octet-stream", - bytes = yourByteArray + path = "path/to/object", + contentType = "application/octet-stream", + bytes = yourByteArray ) ``` - #### Encrypt and Decrypt Data -`encrypt` and `decrypt` functions utilize AWS KMS for data encryption and decryption, respectively. The `encrypt` function requires the key ID for the KMS key, while `decrypt` operates on the encrypted data. +`encrypt` and `decrypt` functions utilize AWS KMS for data encryption and decryption, respectively. The `encrypt` function requires the key ID for the KMS key, while `decrypt` +operates on the encrypted data. ```kotlin val encryptedData = awsPlatform.encrypt(fileBytes = yourData, keyId = "your-key-id") val decryptedData = awsPlatform.decrypt(encryptedData = yourEncryptedData) ``` - ### Error Handling The class includes a companion object with a logger and a static `get` method that initializes the `AwsPlatform` instance, logging any errors encountered during initialization. - ### Mermaid Diagrams - #### Upload Process Flow ```mermaid @@ -1804,13 +1710,12 @@ sequenceDiagram participant Developer participant AwsPlatform participant S3 - Developer->>AwsPlatform: upload(path, contentType, data) - AwsPlatform->>S3: PutObjectRequest - S3-->>AwsPlatform: Success/Failure - AwsPlatform-->>Developer: shareBase/path + Developer ->> AwsPlatform: upload(path, contentType, data) + AwsPlatform ->> S3: PutObjectRequest + S3 -->> AwsPlatform: Success/Failure + AwsPlatform -->> Developer: shareBase/path ``` - #### Encryption/Decryption Flow ```mermaid @@ -1818,25 +1723,24 @@ sequenceDiagram participant Developer participant AwsPlatform participant KMS - Developer->>AwsPlatform: encrypt(data, keyId) - AwsPlatform->>KMS: EncryptRequest - KMS-->>AwsPlatform: Encrypted Data - AwsPlatform-->>Developer: Base64 Encoded Data - Note over Developer,AwsPlatform: Decryption follows a similar flow + Developer ->> AwsPlatform: encrypt(data, keyId) + AwsPlatform ->> KMS: EncryptRequest + KMS -->> AwsPlatform: Encrypted Data + AwsPlatform -->> Developer: Base64 Encoded Data + Note over Developer, AwsPlatform: Decryption follows a similar flow ``` - ### Conclusion -The `AwsPlatform` class provides a convenient way to interact with AWS services for storing and securing data. By encapsulating the complexities of AWS SDK calls, it allows developers to focus on their application logic. +The `AwsPlatform` class provides a convenient way to interact with AWS services for storing and securing data. By encapsulating the complexities of AWS SDK calls, it allows +developers to focus on their application logic. # kotlin\com\simiacryptus\skyenet\core\platform\ApplicationServices.kt - ## Skyenet Core Platform Developer Documentation -The Skyenet Core Platform provides a comprehensive suite of services and interfaces for managing authentication, authorization, user settings, data storage, and cloud platform interactions. This document outlines the core components and their interactions to aid developers in understanding and extending the platform. - +The Skyenet Core Platform provides a comprehensive suite of services and interfaces for managing authentication, authorization, user settings, data storage, and cloud platform +interactions. This document outlines the core components and their interactions to aid developers in understanding and extending the platform. ### Overview @@ -1850,14 +1754,12 @@ The platform is designed around a central `ApplicationServices` object, which ac Additionally, the platform provides interfaces for managing sessions, users, and usage metrics. - ### Core Components - #### ApplicationServices -`ApplicationServices` is a singleton object that acts as a central registry for all the service interfaces. It ensures that the services are easily accessible throughout the application and enforces a locking mechanism to prevent changes after the application is fully initialized. - +`ApplicationServices` is a singleton object that acts as a central registry for all the service interfaces. It ensures that the services are easily accessible throughout the +application and enforces a locking mechanism to prevent changes after the application is fully initialized. ##### Key Properties @@ -1872,56 +1774,44 @@ Additionally, the platform provides interfaces for managing sessions, users, and - `seleniumFactory`: Factory method for creating Selenium instances. - `usageManager`: Manages usage metrics. - #### Interfaces - ##### AuthenticationInterface Manages user authentication, including retrieving and storing user information based on access tokens. - ##### AuthorizationInterface Defines operations for checking user authorization for various operations. - ##### StorageInterface Provides methods for storing and retrieving data, including session-specific data and user settings. - ##### UserSettingsInterface Manages user-specific settings, including API keys and base URLs for different API providers. - ##### UsageInterface Tracks and reports usage metrics for different models and API keys. - #### Data Models - ##### User Represents a user with properties such as email, name, ID, and picture. - ##### Session Represents a session with a unique session ID. - #### CloudPlatformInterface Defines methods for interacting with cloud platforms, including uploading files and encrypting/decrypting data. - ### Diagrams - #### ApplicationServices and Interfaces Interaction ```mermaid @@ -1932,65 +1822,65 @@ classDiagram ApplicationServices --|> StorageInterface ApplicationServices --|> UsageInterface ApplicationServices --|> CloudPlatformInterface - class ApplicationServices{ - +Boolean isLocked - +AuthorizationInterface authorizationManager - +UserSettingsInterface userSettingsManager - +AuthenticationInterface authenticationManager - +Function dataStorageFactory - +File dataStorageRoot - +ClientManager clientManager - +CloudPlatformInterface cloud - +Function seleniumFactory - +UsageInterface usageManager - } - class AuthenticationInterface{ - +getUser(String) - +putUser(String, User) - +logout(String, User) - } - class AuthorizationInterface{ - +isAuthorized(Class, User, OperationType) + class ApplicationServices { + +Boolean isLocked + +AuthorizationInterface authorizationManager + +UserSettingsInterface userSettingsManager + +AuthenticationInterface authenticationManager + +Function dataStorageFactory + +File dataStorageRoot + +ClientManager clientManager + +CloudPlatformInterface cloud + +Function seleniumFactory + +UsageInterface usageManager + } + class AuthenticationInterface { + +getUser(String) + +putUser(String, User) + +logout(String, User) + } + class AuthorizationInterface { + +isAuthorized(Class, User, OperationType) + } + class UserSettingsInterface { + +getUserSettings(User) + +updateUserSettings(User, UserSettings) + } + class StorageInterface { + +getJson(User, Session, String, Class) + +getMessages(User, Session) + +getSessionDir(User, Session) + +listSessions(User) + +setJson(User, Session, String, Any) + +updateMessage(User, Session, String, String) } - class UserSettingsInterface{ - +getUserSettings(User) - +updateUserSettings(User, UserSettings) - } - class StorageInterface{ - +getJson(User, Session, String, Class) - +getMessages(User, Session) - +getSessionDir(User, Session) - +listSessions(User) - +setJson(User, Session, String, Any) - +updateMessage(User, Session, String, String) - } - class UsageInterface{ - +incrementUsage(Session, User, OpenAIModel, ApiModel.Usage) - +getUserUsageSummary(User) - +getSessionUsageSummary(Session) - +clear() + class UsageInterface { + +incrementUsage(Session, User, OpenAIModel, ApiModel.Usage) + +getUserUsageSummary(User) + +getSessionUsageSummary(Session) + +clear() } - class CloudPlatformInterface{ - +upload(String, String, ByteArray) - +encrypt(ByteArray, String) - +decrypt(ByteArray) + class CloudPlatformInterface { + +upload(String, String, ByteArray) + +encrypt(ByteArray, String) + +decrypt(ByteArray) } ``` -This diagram illustrates the relationship between the `ApplicationServices` singleton and the various service interfaces it manages. It also shows the key methods provided by each interface. - +This diagram illustrates the relationship between the `ApplicationServices` singleton and the various service interfaces it manages. It also shows the key methods provided by each +interface. ### Conclusion -The Skyenet Core Platform provides a robust foundation for managing authentication, authorization, user settings, data storage, and cloud interactions. By understanding the core components and their interactions, developers can effectively extend and customize the platform to meet their specific needs. +The Skyenet Core Platform provides a robust foundation for managing authentication, authorization, user settings, data storage, and cloud interactions. By understanding the core +components and their interactions, developers can effectively extend and customize the platform to meet their specific needs. # kotlin\com\simiacryptus\skyenet\core\platform\file\AuthenticationManager.kt - ## AuthenticationManager Class Documentation -The `AuthenticationManager` class is a part of the `com.simiacryptus.skyenet.core.platform.file` package and is responsible for managing user authentication within the system. It implements the `AuthenticationInterface`, providing concrete implementations for user authentication, addition, and logout functionalities. - +The `AuthenticationManager` class is a part of the `com.simiacryptus.skyenet.core.platform.file` package and is responsible for managing user authentication within the system. It +implements the `AuthenticationInterface`, providing concrete implementations for user authentication, addition, and logout functionalities. ### Class Diagram @@ -2002,26 +1892,22 @@ classDiagram +putUser(String accessToken, User user) User +logout(String accessToken, User user) void } - AuthenticationInterface <|.. AuthenticationManager : implements + AuthenticationInterface <|.. AuthenticationManager: implements ``` - ### Class Members - #### Properties - `private val users: HashMap`: A private hashmap that stores user objects against their access tokens as keys. - #### Methods - ##### getUser(accessToken: String?): User? - **Description**: Retrieves a `User` object associated with the given access token. - **Parameters**: - - `accessToken: String?`: The access token used to identify the user. Can be `null`. + - `accessToken: String?`: The access token used to identify the user. Can be `null`. - **Returns**: The `User` object if found; otherwise, `null`. - **Usage Example**: @@ -2029,13 +1915,12 @@ classDiagram val user = authenticationManager.getUser("someAccessToken") ``` - ##### putUser(accessToken: String, user: User): User - **Description**: Adds or updates a user in the system with the given access token. - **Parameters**: - - `accessToken: String`: The access token to associate with the user. - - `user: User`: The user object to add or update. + - `accessToken: String`: The access token to associate with the user. + - `user: User`: The user object to add or update. - **Returns**: The `User` object that was added or updated. - **Usage Example**: @@ -2044,13 +1929,12 @@ val newUser = User("JohnDoe", "john@example.com") authenticationManager.putUser("newAccessToken", newUser) ``` - ##### logout(accessToken: String, user: User) - **Description**: Logs out a user from the system by removing the association between the user and the access token. - **Parameters**: - - `accessToken: String`: The access token of the user to log out. - - `user: User`: The user object to log out. + - `accessToken: String`: The access token of the user to log out. + - `user: User`: The user object to log out. - **Preconditions**: The user associated with the given access token must match the user object provided; otherwise, an exception is thrown. - **Usage Example**: @@ -2058,31 +1942,31 @@ authenticationManager.putUser("newAccessToken", newUser) authenticationManager.logout("existingAccessToken", existingUser) ``` - ### Sequence Diagram for User Logout ```mermaid sequenceDiagram participant Client participant AuthenticationManager - Client->>AuthenticationManager: logout(accessToken, user) + Client ->> AuthenticationManager: logout(accessToken, user) alt valid user and token - AuthenticationManager->>AuthenticationManager: remove user from users - AuthenticationManager-->>Client: success + AuthenticationManager ->> AuthenticationManager: remove user from users + AuthenticationManager -->> Client: success else invalid user or token - AuthenticationManager-->>Client: throw exception + AuthenticationManager -->> Client: throw exception end ``` -This documentation provides an overview of the `AuthenticationManager` class, its properties, methods, and how it interacts with other components for managing user authentication within the system. +This documentation provides an overview of the `AuthenticationManager` class, its properties, methods, and how it interacts with other components for managing user authentication +within the system. # kotlin\com\simiacryptus\skyenet\core\platform\ClientManager.kt - ## Developer Documentation for ClientManager -The `ClientManager` class is a core component designed to manage OpenAI client instances and thread pools for sessions and users within an application. It provides mechanisms to create and retrieve `OpenAIClient` instances and `ThreadPoolExecutor` instances based on session and user context. This document outlines the structure and functionality of the `ClientManager` class and its inner classes. - +The `ClientManager` class is a core component designed to manage OpenAI client instances and thread pools for sessions and users within an application. It provides mechanisms to +create and retrieve `OpenAIClient` instances and `ThreadPoolExecutor` instances based on session and user context. This document outlines the structure and functionality of the +`ClientManager` class and its inner classes. ### Overview @@ -2091,7 +1975,6 @@ The `ClientManager` class primarily deals with two types of resources: 1. **OpenAIClient Instances**: Handles communication with OpenAI's API, customized with user-specific API keys and logging configurations. 2. **ThreadPoolExecutor Instances**: Manages a pool of threads for executing tasks asynchronously, tailored for specific sessions and users. - ### Class Diagram ```mermaid @@ -2118,45 +2001,39 @@ classDiagram +authorize(request, apiProvider): void +onUsage(model, tokens): void } - ClientManager --> SessionKey : uses - ClientManager --> RecordingThreadFactory : uses - ClientManager --> MonitoredClient : creates + ClientManager --> SessionKey: uses + ClientManager --> RecordingThreadFactory: uses + ClientManager --> MonitoredClient: creates ``` - ### Key Components - #### ClientManager - **Purpose**: Manages `OpenAIClient` and `ThreadPoolExecutor` instances. - **Key Methods**: - - `getClient(session, user, dataStorage)`: Retrieves or creates an `OpenAIClient` instance. - - `getPool(session, user, dataStorage)`: Retrieves or creates a `ThreadPoolExecutor` instance. - + - `getClient(session, user, dataStorage)`: Retrieves or creates an `OpenAIClient` instance. + - `getPool(session, user, dataStorage)`: Retrieves or creates a `ThreadPoolExecutor` instance. #### SessionKey - **Purpose**: Acts as a unique identifier for caching clients and pools based on session and user. - **Fields**: - - `session`: The current session. - - `user`: The current user (optional). - + - `session`: The current session. + - `user`: The current user (optional). #### RecordingThreadFactory - **Purpose**: Custom `ThreadFactory` that names threads based on session and user, and keeps track of created threads. - **Key Method**: - - `newThread(r)`: Creates a new thread for the runnable `r`, names it, and adds it to the set of threads. - + - `newThread(r)`: Creates a new thread for the runnable `r`, names it, and adds it to the set of threads. #### MonitoredClient - **Purpose**: Extends `OpenAIClient` to add usage monitoring and budget enforcement based on session and user. - **Key Features**: - - Budget tracking and enforcement. - - Custom authorization and usage logging. - + - Budget tracking and enforcement. + - Custom authorization and usage logging. ### Usage Flow @@ -2165,65 +2042,59 @@ classDiagram 3. **Client Creation**: `createClient` may create a `MonitoredClient` instance, which is customized with user-specific API keys and logging configurations. 4. **Pool Creation**: `createPool` initializes a `ThreadPoolExecutor` with a `RecordingThreadFactory` to manage thread naming and tracking. - ### Conclusion -The `ClientManager` class provides a structured way to manage OpenAI client instances and thread pools within an application, ensuring that resources are efficiently reused and customized according to session and user contexts. +The `ClientManager` class provides a structured way to manage OpenAI client instances and thread pools within an application, ensuring that resources are efficiently reused and +customized according to session and user contexts. # kotlin\com\simiacryptus\skyenet\core\platform\file\AuthorizationManager.kt - ## AuthorizationManager Class Documentation -The `AuthorizationManager` class is an implementation of the `AuthorizationInterface` designed to manage user authorization for different operations within an application. It provides a mechanism to check if a user is authorized to perform a specific operation either globally or within the context of a specific application class. - +The `AuthorizationManager` class is an implementation of the `AuthorizationInterface` designed to manage user authorization for different operations within an application. It +provides a mechanism to check if a user is authorized to perform a specific operation either globally or within the context of a specific application class. ### Class Overview ```mermaid classDiagram AuthorizationInterface <|-- AuthorizationManager - AuthorizationManager : +isAuthorized(applicationClass, user, operationType) - AuthorizationManager : -isUserAuthorized(permissionPath, user) - AuthorizationManager : +matches(user, line) - AuthorizationManager : -log + AuthorizationManager: +isAuthorized(applicationClass, user, operationType) + AuthorizationManager: -isUserAuthorized(permissionPath, user) + AuthorizationManager: +matches(user, line) + AuthorizationManager: -log ``` - #### Methods - ##### `isAuthorized(applicationClass: Class<*>?, user: User?, operationType: AuthorizationInterface.OperationType): Boolean` Checks if a user is authorized to perform a specific operation. It first checks global permissions and then, if necessary, checks permissions specific to the application class. - **Parameters:** - - `applicationClass`: The class of the application for which the authorization is being checked. It can be `null` if the check is global. - - `user`: The user for whom the authorization is being checked. - - `operationType`: The type of operation for which authorization is being checked. + - `applicationClass`: The class of the application for which the authorization is being checked. It can be `null` if the check is global. + - `user`: The user for whom the authorization is being checked. + - `operationType`: The type of operation for which authorization is being checked. - **Returns:** `true` if the user is authorized, otherwise `false`. - ##### `isUserAuthorized(permissionPath: String, user: User?): Boolean` (Private) Checks if a user is authorized based on permissions defined in a file located at the specified path. - **Parameters:** - - `permissionPath`: The path to the permissions file. - - `user`: The user for whom the authorization is being checked. + - `permissionPath`: The path to the permissions file. + - `user`: The user for whom the authorization is being checked. - **Returns:** `true` if the user is found in the permissions file, otherwise `false`. - ##### `matches(user: User?, line: String): Boolean` (Open) Determines if a line from a permissions file matches the user's email or domain. - **Parameters:** - - `user`: The user for whom the match is being checked. - - `line`: A line from the permissions file. + - `user`: The user for whom the match is being checked. + - `line`: A line from the permissions file. - **Returns:** `true` if the line matches the user's email or domain, otherwise `false`. - #### Usage Example ```kotlin @@ -2238,86 +2109,80 @@ val isGloballyAuthorized = authorizationManager.isAuthorized(null, user, operati val isClassAuthorized = authorizationManager.isAuthorized(MyApplicationClass::class.java, user, operationType) ``` - #### Error Handling -The `isAuthorized` method is designed to catch and log any exceptions that occur during the authorization check process. If an exception is caught, the method will return `false`, indicating that the user is not authorized. - +The `isAuthorized` method is designed to catch and log any exceptions that occur during the authorization check process. If an exception is caught, the method will return `false`, +indicating that the user is not authorized. #### Logging The `AuthorizationManager` utilizes SLF4J for logging. It logs debug information about authorization checks and errors. - ### Conclusion -The `AuthorizationManager` class provides a flexible and extensible way to manage user authorizations. By leveraging permissions files, it allows for granular control over who can perform specific operations, either globally or within the context of a particular application class. +The `AuthorizationManager` class provides a flexible and extensible way to manage user authorizations. By leveraging permissions files, it allows for granular control over who can +perform specific operations, either globally or within the context of a particular application class. # kotlin\com\simiacryptus\skyenet\core\platform\file\DataStorage.kt - ## DataStorage Class Documentation -The `DataStorage` class is part of the `com.simiacryptus.skyenet.core.platform.file` package and implements the `StorageInterface`. It provides functionalities for managing session-based data storage, including operations for JSON data manipulation, message handling, and session management within a file system. - +The `DataStorage` class is part of the `com.simiacryptus.skyenet.core.platform.file` package and implements the `StorageInterface`. It provides functionalities for managing +session-based data storage, including operations for JSON data manipulation, message handling, and session management within a file system. ### Overview -The class is designed to work with a directory structure that segregates data by user and session. It supports operations such as reading and writing JSON data, listing and managing messages within sessions, and handling session directories and names. - +The class is designed to work with a directory structure that segregates data by user and session. It supports operations such as reading and writing JSON data, listing and +managing messages within sessions, and handling session directories and names. ### Class Diagram ```mermaid classDiagram StorageInterface <|-- DataStorage - StorageInterface : +getJson() - StorageInterface : +getMessages() - StorageInterface : +getSessionDir() - StorageInterface : +getSessionName() - StorageInterface : +getMessageIds() - StorageInterface : +setMessageIds() - StorageInterface : +getSessionTime() - StorageInterface : +listSessions() - StorageInterface : +setJson() - StorageInterface : +updateMessage() - StorageInterface : +deleteSession() - DataStorage : -dataDir File - DataStorage : +getJson() - DataStorage : -getJson() - DataStorage : +getMessages() - DataStorage : +getSessionDir() - DataStorage : +getSessionName() - DataStorage : +getMessageIds() - DataStorage : +setMessageIds() - DataStorage : +getSessionTime() - DataStorage : -messageFiles() - DataStorage : +listSessions() - DataStorage : +setJson() - DataStorage : +updateMessage() - DataStorage : +addMessageID() - DataStorage : +listSessions() - DataStorage : +userRoot() - DataStorage : +deleteSession() + StorageInterface: +getJson() + StorageInterface: +getMessages() + StorageInterface: +getSessionDir() + StorageInterface: +getSessionName() + StorageInterface: +getMessageIds() + StorageInterface: +setMessageIds() + StorageInterface: +getSessionTime() + StorageInterface: +listSessions() + StorageInterface: +setJson() + StorageInterface: +updateMessage() + StorageInterface: +deleteSession() + DataStorage: -dataDir File + DataStorage: +getJson() + DataStorage: -getJson() + DataStorage: +getMessages() + DataStorage: +getSessionDir() + DataStorage: +getSessionName() + DataStorage: +getMessageIds() + DataStorage: +setMessageIds() + DataStorage: +getSessionTime() + DataStorage: -messageFiles() + DataStorage: +listSessions() + DataStorage: +setJson() + DataStorage: +updateMessage() + DataStorage: +addMessageID() + DataStorage: +listSessions() + DataStorage: +userRoot() + DataStorage: +deleteSession() ``` - ### Key Methods - #### JSON Data Management - `getJson`: Retrieves a JSON object from a specified file within a session directory and deserializes it into the specified class type. - `setJson`: Serializes and saves a given object as JSON into a specified file within a session directory. - #### Message Handling - `getMessages`: Retrieves all messages for a given session as a `LinkedHashMap` where keys are message IDs and values are message contents. - `updateMessage`: Updates or creates a message with a given ID for a specified session. - `addMessageID`: Adds a new message ID to the list of message IDs for a given session. - #### Session Management - `getSessionDir`: Determines the directory path for a given session based on its ID and potentially the user. @@ -2327,16 +2192,15 @@ classDiagram - `getSessionTime`: Retrieves or calculates the time associated with a given session. - `listSessions`: Lists all sessions available within a specified directory or globally/user-specific based on the context. - #### Utility Methods - `userRoot`: Determines the root directory for a given user's data. - `deleteSession`: Deletes all data associated with a given session. - ### Usage Example -To use the `DataStorage` class, you must first instantiate it with a reference to the root directory where session data will be stored. From there, you can call its methods to manage session data as needed. +To use the `DataStorage` class, you must first instantiate it with a reference to the root directory where session data will be stored. From there, you can call its methods to +manage session data as needed. ```kotlin val dataStorage = DataStorage(File("/path/to/data")) @@ -2353,18 +2217,17 @@ dataStorage.updateMessage(user, session, "messageId", "Hello, World!") val messages = dataStorage.getMessages(user, session) ``` - ### Conclusion -The `DataStorage` class provides a comprehensive interface for managing session-based data storage in a file system, making it easier to handle user and session-specific data in a structured and organized manner. +The `DataStorage` class provides a comprehensive interface for managing session-based data storage in a file system, making it easier to handle user and session-specific data in a +structured and organized manner. # kotlin\com\simiacryptus\skyenet\core\platform\file\UserSettingsManager.kt - ## UserSettingsManager Class Documentation -The `UserSettingsManager` class is a part of the `com.simiacryptus.skyenet.core.platform.file` package and implements the `UserSettingsInterface`. It is designed to manage user settings, providing functionalities to retrieve and update settings for users. The settings are stored in JSON format in a designated directory on the file system. - +The `UserSettingsManager` class is a part of the `com.simiacryptus.skyenet.core.platform.file` package and implements the `UserSettingsInterface`. It is designed to manage user +settings, providing functionalities to retrieve and update settings for users. The settings are stored in JSON format in a designated directory on the file system. ### Class Overview @@ -2376,38 +2239,33 @@ classDiagram +getUserSettings(User) UserSettings +updateUserSettings(User, UserSettings) void } - UserSettingsManager ..|> UserSettingsInterface : implements + UserSettingsManager ..|> UserSettingsInterface: implements ``` - ### Properties - `userSettings`: A private HashMap that caches the user settings in memory to avoid frequent file system access. - `userConfigDirectory`: A private File object representing the directory where user settings files are stored. - ### Methods - #### getUserSettings ```kotlin fun getUserSettings(user: User): UserSettings ``` -Retrieves the `UserSettings` for a given `User`. If the settings for the user are not found in the cache (`userSettings`), it attempts to load them from a JSON file in the `userConfigDirectory`. If the file does not exist or an error occurs during loading, it creates and returns new default `UserSettings`. - +Retrieves the `UserSettings` for a given `User`. If the settings for the user are not found in the cache (`userSettings`), it attempts to load them from a JSON file in the +`userConfigDirectory`. If the file does not exist or an error occurs during loading, it creates and returns new default `UserSettings`. ##### Parameters - `user`: The `User` object for whom the settings are to be retrieved. - ##### Returns - `UserSettings`: The user settings for the specified user. - #### updateUserSettings ```kotlin @@ -2416,13 +2274,11 @@ fun updateUserSettings(user: User, settings: UserSettings) Updates the settings for a given user both in the cache (`userSettings`) and in the file system by writing the settings to a JSON file in the `userConfigDirectory`. - ##### Parameters - `user`: The `User` object for whom the settings are to be updated. - `settings`: The `UserSettings` object containing the new settings for the user. - ### Usage Example ```kotlin @@ -2433,15 +2289,15 @@ settings.someSetting = newValue // Modify settings as needed userManager.updateUserSettings(user, settings) // Updates the settings in memory and file ``` - ### File Structure -The user settings are stored in JSON files within the `.skyenet/users` directory. Each user has a separate file named after their username with a `.json` extension, e.g., `exampleUser.json`. - +The user settings are stored in JSON files within the `.skyenet/users` directory. Each user has a separate file named after their username with a `.json` extension, e.g., +`exampleUser.json`. ### Logging -The `UserSettingsManager` utilizes SLF4J for logging purposes. It logs information about loading, creating, and updating user settings, as well as warnings in case of errors during these operations. +The `UserSettingsManager` utilizes SLF4J for logging purposes. It logs information about loading, creating, and updating user settings, as well as warnings in case of errors during +these operations. --- @@ -2449,34 +2305,31 @@ This documentation provides a comprehensive overview of the `UserSettingsManager # kotlin\com\simiacryptus\skyenet\core\platform\file\UsageManager.kt - ## UsageManager Class Documentation -The `UsageManager` class is part of the `com.simiacryptus.skyenet.core.platform.file` package and implements the `UsageInterface`. It is designed to manage and track the usage of various OpenAI models by different users and sessions, logging this information for monitoring and billing purposes. - +The `UsageManager` class is part of the `com.simiacryptus.skyenet.core.platform.file` package and implements the `UsageInterface`. It is designed to manage and track the usage of +various OpenAI models by different users and sessions, logging this information for monitoring and billing purposes. ### Overview The class provides functionality to increment usage counters, retrieve usage summaries for users and sessions, and manage the persistence of this data through logging to files. - ### Class Diagram ```mermaid classDiagram UsageInterface <|-- UsageManager - UsageManager : +File root - UsageManager : -FileWriter txLogFileWriter - UsageManager : -ConcurrentHashMap usagePerSession - UsageManager : -ConcurrentHashMap sessionsByUser - UsageManager : -ConcurrentHashMap usersBySession - UsageManager : +incrementUsage(Session, String, OpenAIModel, ApiModel.Usage) - UsageManager : +getUserUsageSummary(String) Map - UsageManager : +getSessionUsageSummary(Session) Map - UsageManager : +clear() + UsageManager: +File root + UsageManager: -FileWriter txLogFileWriter + UsageManager: -ConcurrentHashMap usagePerSession + UsageManager: -ConcurrentHashMap sessionsByUser + UsageManager: -ConcurrentHashMap usersBySession + UsageManager: +incrementUsage(Session, String, OpenAIModel, ApiModel.Usage) + UsageManager: +getUserUsageSummary(String) Map + UsageManager: +getSessionUsageSummary(Session) Map + UsageManager: +clear() ``` - ### Key Components - **root**: The root directory where usage logs and other related files are stored. @@ -2485,50 +2338,47 @@ classDiagram - **sessionsByUser**: A concurrent hash map associating users with their sessions. - **usersBySession**: A concurrent hash map associating sessions with their users. - ### Methods - #### incrementUsage Increments the usage counters for a given session, user, and model. This method also logs the transaction to a CSV file. **Parameters:** + - `session`: The session for which usage is being incremented. - `apiKey`: The API key (or user identifier) associated with the usage. - `model`: The OpenAI model being used. - `tokens`: An instance of `com.simiacryptus.jopenai.ApiModel.Usage` detailing the usage metrics. - #### getUserUsageSummary Retrieves a summary of usage for a given user across all sessions. **Parameters:** + - `apiKey`: The API key (or user identifier) for which to retrieve the usage summary. **Returns:** A map of `OpenAIModel` to `com.simiacryptus.jopenai.ApiModel.Usage` summarizing the usage. - #### getSessionUsageSummary Retrieves a summary of usage for a given session. **Parameters:** + - `session`: The session for which to retrieve the usage summary. **Returns:** A map of `OpenAIModel` to `com.simiacryptus.jopenai.ApiModel.Usage` summarizing the usage. - #### clear Clears all usage counters and associated mappings, and logs the current state before clearing. - ### Persistence Mechanism -The `UsageManager` class employs a file-based logging mechanism to persist usage data. This includes a CSV file for transaction logs and a JSON file for counter states. The class also implements a scheduled task to periodically save the counters to disk. - +The `UsageManager` class employs a file-based logging mechanism to persist usage data. This includes a CSV file for transaction logs and a JSON file for counter states. The class +also implements a scheduled task to periodically save the counters to disk. ### Sequence Diagram for incrementUsage @@ -2537,12 +2387,11 @@ sequenceDiagram participant Client participant UsageManager participant FileWriter - Client->>UsageManager: incrementUsage(session, apiKey, model, tokens) - UsageManager->>FileWriter: Write transaction to log - FileWriter->>UsageManager: Flush to disk + Client ->> UsageManager: incrementUsage(session, apiKey, model, tokens) + UsageManager ->> FileWriter: Write transaction to log + FileWriter ->> UsageManager: Flush to disk ``` - ### Usage Example ```kotlin @@ -2560,19 +2409,18 @@ This documentation provides an overview of the `UsageManager` class, its key com # kotlin\com\simiacryptus\skyenet\core\platform\test\AuthorizationInterfaceTest.kt - ## Developer Documentation: AuthorizationInterfaceTest - ### Overview -The `AuthorizationInterfaceTest` class is designed to test the authorization functionalities provided by the `AuthorizationInterface`. It aims to ensure that the authorization checks behave as expected for different users and operations within the system. This documentation provides an overview of the `AuthorizationInterfaceTest` class, its structure, and how it is used to validate authorization logic. - +The `AuthorizationInterfaceTest` class is designed to test the authorization functionalities provided by the `AuthorizationInterface`. It aims to ensure that the authorization +checks behave as expected for different users and operations within the system. This documentation provides an overview of the `AuthorizationInterfaceTest` class, its structure, +and how it is used to validate authorization logic. ### Class Structure -The `AuthorizationInterfaceTest` class is an open class that requires an instance of `AuthorizationInterface` as a constructor parameter. This design allows for testing different implementations of the `AuthorizationInterface`. The class contains a predefined `user` object and a test method named `newUser has admin`. - +The `AuthorizationInterfaceTest` class is an open class that requires an instance of `AuthorizationInterface` as a constructor parameter. This design allows for testing different +implementations of the `AuthorizationInterface`. The class contains a predefined `user` object and a test method named `newUser has admin`. #### User Object @@ -2585,11 +2433,10 @@ The `user` object is an instance of the `User` class with predefined attributes: This user object represents a new user in the system and is used to test authorization checks. - #### Test Method: `newUser has admin` -The test method `newUser has admin` is designed to verify that a new user does not have administrative privileges by default. It uses the `assertFalse` assertion to ensure that the `isAuthorized` method of the `AuthorizationInterface` returns `false` when checking if the predefined `user` has `Admin` operation type access. - +The test method `newUser has admin` is designed to verify that a new user does not have administrative privileges by default. It uses the `assertFalse` assertion to ensure that the +`isAuthorized` method of the `AuthorizationInterface` returns `false` when checking if the predefined `user` has `Admin` operation type access. ### Sequence Diagram @@ -2599,12 +2446,11 @@ The following sequence diagram illustrates the flow of the `newUser has admin` t sequenceDiagram participant Test as AuthorizationInterfaceTest participant AuthInterface as AuthorizationInterface - Test->>AuthInterface: isAuthorized(this.javaClass, user, OperationType.Admin) - AuthInterface-->>Test: false - Test->>Test: assertFalse(result) + Test ->> AuthInterface: isAuthorized(this.javaClass, user, OperationType.Admin) + AuthInterface -->> Test: false + Test ->> Test: assertFalse(result) ``` - ### Usage To use the `AuthorizationInterfaceTest` class for testing, follow these steps: @@ -2614,23 +2460,23 @@ To use the `AuthorizationInterfaceTest` class for testing, follow these steps: 3. Create an instance of `AuthorizationInterfaceTest`, passing your `AuthorizationInterface` implementation to its constructor. 4. Run the `newUser has admin` test method to verify that new users do not have administrative privileges by default. - ### Conclusion -The `AuthorizationInterfaceTest` class is a crucial component for ensuring that the authorization logic in your application behaves as expected. By testing with predefined user objects and specific operation types, you can validate the security and correctness of your authorization checks. +The `AuthorizationInterfaceTest` class is a crucial component for ensuring that the authorization logic in your application behaves as expected. By testing with predefined user +objects and specific operation types, you can validate the security and correctness of your authorization checks. # kotlin\com\simiacryptus\skyenet\core\platform\test\AuthenticationInterfaceTest.kt - ## Authentication Interface Test Documentation -This documentation provides an overview of the `AuthenticationInterfaceTest` class, which is designed to test the functionality of an `AuthenticationInterface` implementation. The tests ensure that the interface correctly handles user authentication processes, including adding, retrieving, and removing users based on access tokens. - +This documentation provides an overview of the `AuthenticationInterfaceTest` class, which is designed to test the functionality of an `AuthenticationInterface` implementation. The +tests ensure that the interface correctly handles user authentication processes, including adding, retrieving, and removing users based on access tokens. ### Overview -The `AuthenticationInterfaceTest` class is an open class that requires an instance of `AuthenticationInterface` to be passed to its constructor. This design allows for testing different implementations of the `AuthenticationInterface`. The class includes several test methods annotated with `@Test`, each designed to verify a specific aspect of the authentication process. - +The `AuthenticationInterfaceTest` class is an open class that requires an instance of `AuthenticationInterface` to be passed to its constructor. This design allows for testing +different implementations of the `AuthenticationInterface`. The class includes several test methods annotated with `@Test`, each designed to verify a specific aspect of the +authentication process. ### Test Methods @@ -2641,132 +2487,121 @@ The class contains the following test methods: - `getUser should return User after putUser is called` - `logout should remove the user associated with the access token` - #### Diagram: Test Flow ```mermaid sequenceDiagram participant Test as Test Case participant Auth as AuthenticationInterface - Note over Test, Auth: getUser with no associated user - Test->>Auth: getUser(validAccessToken) - Auth-->>Test: null - + Test ->> Auth: getUser(validAccessToken) + Auth -->> Test: null Note over Test, Auth: putUser adds a new user - Test->>Auth: putUser(validAccessToken, newUser) - Auth-->>Test: newUser - + Test ->> Auth: putUser(validAccessToken, newUser) + Auth -->> Test: newUser Note over Test, Auth: getUser returns added user - Test->>Auth: getUser(validAccessToken) - Auth-->>Test: newUser - + Test ->> Auth: getUser(validAccessToken) + Auth -->> Test: newUser Note over Test, Auth: logout removes the user - Test->>Auth: logout(validAccessToken, newUser) - Test->>Auth: getUser(validAccessToken) - Auth-->>Test: null + Test ->> Auth: logout(validAccessToken, newUser) + Test ->> Auth: getUser(validAccessToken) + Auth -->> Test: null ``` - ### Test Setup Before running the tests, an instance of `AuthenticationInterface` must be provided. This instance is used to perform the actual authentication operations tested by the methods. - #### Key Variables - `validAccessToken`: A randomly generated UUID string used as a mock access token for testing. - `newUser`: A mock `User` object representing a new user to be added through the authentication interface. - ### Test Methods Explained - #### `getUser should return null when no user is associated with access token` This test verifies that the `getUser` method returns `null` when queried with an access token that has no associated user. - #### `putUser should add a new user and return the user` This test checks if the `putUser` method correctly adds a new user associated with a given access token and returns the added user object. - #### `getUser should return User after putUser is called` This test ensures that after a new user is added with `putUser`, the `getUser` method can retrieve the user object when provided with the same access token. - #### `logout should remove the user associated with the access token` This test confirms that the `logout` method removes the association between the user and the access token, resulting in `getUser` returning `null` for that token. - ### Conclusion -The `AuthenticationInterfaceTest` class provides a comprehensive suite of tests to ensure the correct behavior of implementations of the `AuthenticationInterface`. By following the test cases and ensuring all pass, developers can be confident in the reliability and correctness of their authentication processes. +The `AuthenticationInterfaceTest` class provides a comprehensive suite of tests to ensure the correct behavior of implementations of the `AuthenticationInterface`. By following the +test cases and ensuring all pass, developers can be confident in the reliability and correctness of their authentication processes. # kotlin\com\simiacryptus\skyenet\core\platform\test\UsageTest.kt - ## Developer Documentation for `UsageTest` Class -The `UsageTest` class is an abstract test suite designed to validate the functionality of implementations of the `UsageInterface`. This interface is crucial for tracking and managing the usage of resources by users, particularly in applications that involve session-based interactions and resource consumption tracking. - +The `UsageTest` class is an abstract test suite designed to validate the functionality of implementations of the `UsageInterface`. This interface is crucial for tracking and +managing the usage of resources by users, particularly in applications that involve session-based interactions and resource consumption tracking. ### Overview -The `UsageTest` class focuses on testing the ability of an implementation to accurately record and report usage statistics for individual sessions and users. It leverages a test user and predefined usage metrics to ensure that the `incrementUsage` method correctly updates the usage records. - +The `UsageTest` class focuses on testing the ability of an implementation to accurately record and report usage statistics for individual sessions and users. It leverages a test +user and predefined usage metrics to ensure that the `incrementUsage` method correctly updates the usage records. ### Class Diagram ```mermaid classDiagram class UsageTest { - -impl: UsageInterface - -testUser: User - +UsageTest(impl: UsageInterface) - +incrementUsage should increment usage for session(): void + -impl: UsageInterface + -testUser: User + +UsageTest(impl: UsageInterface) + +incrementUsage should increment usage for session(): void } class UsageInterface { - +incrementUsage(session: String, user: User, model: ApiModel, usage: ApiModel.Usage): void - +getSessionUsageSummary(session: String): Map~ApiModel, ApiModel.Usage~ - +getUserUsageSummary(user: User): Map~ApiModel, ApiModel.Usage~ + +incrementUsage(session: String, user: User, model: ApiModel, usage: ApiModel.Usage): void + +getSessionUsageSummary(session: String): Map~ApiModel, ApiModel.Usage~ + +getUserUsageSummary(user: User): Map~ApiModel, ApiModel.Usage~ } class User { - +email: String - +name: String - +id: String + +email: String + +name: String + +id: String } class ApiModel { - <> - GPT35Turbo + <> + GPT35Turbo } class ApiModel.Usage { - +prompt_tokens: Int - +completion_tokens: Int - +cost: Double - } - UsageTest --> UsageInterface : uses - UsageTest --> User : uses - UsageInterface --> ApiModel : uses - UsageInterface --> ApiModel.Usage : uses ++prompt_tokens: Int ++completion_tokens: Int ++cost: Double +} +UsageTest --> UsageInterface: uses +UsageTest --> User: uses +UsageInterface --> ApiModel: uses +UsageInterface --> ApiModel.Usage: uses ``` - ### Test Method: `incrementUsage should increment usage for session` This test method validates the functionality of the `incrementUsage` method within the `UsageInterface`. It follows these steps: -1. **Setup**: A test user is created with predefined attributes. A session ID is generated using `StorageInterface.newGlobalID()`. A predefined usage object is created to simulate the consumption of resources. +1. **Setup**: A test user is created with predefined attributes. A session ID is generated using `StorageInterface.newGlobalID()`. A predefined usage object is created to simulate + the consumption of resources. -2. **Action**: The `incrementUsage` method of the `UsageInterface` implementation is called with the session ID, test user, a model (in this case, `OpenAIModels.GPT35Turbo`), and the predefined usage object. +2. **Action**: The `incrementUsage` method of the `UsageInterface` implementation is called with the session ID, test user, a model (in this case, `OpenAIModels.GPT35Turbo`), and + the predefined usage object. 3. **Verification**: - - The method `getSessionUsageSummary` is called with the session ID to retrieve the usage summary for the session. The test verifies that the returned usage summary matches the predefined usage object. - - The method `getUserUsageSummary` is called with the test user to retrieve the user's usage summary. The test verifies that the returned usage summary for the user matches the predefined usage object. - + - The method `getSessionUsageSummary` is called with the session ID to retrieve the usage summary for the session. The test verifies that the returned usage summary matches the + predefined usage object. + - The method `getUserUsageSummary` is called with the test user to retrieve the user's usage summary. The test verifies that the returned usage summary for the user matches the + predefined usage object. ### Sequence Diagram for `incrementUsage should increment usage for session` @@ -2776,43 +2611,40 @@ sequenceDiagram participant Interface as UsageInterface participant Storage as StorageInterface participant Model as ApiModel - - Test->>Storage: newGlobalID() + Test ->> Storage: newGlobalID() Note over Test: Generate session ID - Test->>Interface: incrementUsage(session, testUser, GPT35Turbo, usage) + Test ->> Interface: incrementUsage(session, testUser, GPT35Turbo, usage) Note over Interface: Update usage records - Test->>Interface: getSessionUsageSummary(session) - Interface->>Test: Return usage summary for session - Test->>Interface: getUserUsageSummary(testUser) - Interface->>Test: Return usage summary for user + Test ->> Interface: getSessionUsageSummary(session) + Interface ->> Test: Return usage summary for session + Test ->> Interface: getUserUsageSummary(testUser) + Interface ->> Test: Return usage summary for user Note over Test: Verify usage summaries match predefined usage ``` - ### Conclusion -The `UsageTest` class provides a structured approach to validate the implementation of the `UsageInterface`. By ensuring that usage statistics are accurately recorded and reported, developers can maintain the integrity of resource management and usage tracking within their applications. +The `UsageTest` class provides a structured approach to validate the implementation of the `UsageInterface`. By ensuring that usage statistics are accurately recorded and reported, +developers can maintain the integrity of resource management and usage tracking within their applications. # kotlin\com\simiacryptus\skyenet\core\platform\test\UserSettingsTest.kt - ## Developer Documentation: UserSettingsTest -The `UserSettingsTest` class is designed to validate the functionality of user settings management within a platform. It ensures that custom settings for a user can be updated and retrieved accurately. This documentation provides an overview of the test cases and their significance in maintaining the integrity of the user settings feature. - +The `UserSettingsTest` class is designed to validate the functionality of user settings management within a platform. It ensures that custom settings for a user can be updated and +retrieved accurately. This documentation provides an overview of the test cases and their significance in maintaining the integrity of the user settings feature. ### Overview -`UserSettingsTest` is an abstract class that requires an implementation of `UserSettingsInterface` to be passed to its constructor. This design allows for testing different implementations of `UserSettingsInterface` with the same set of tests. - +`UserSettingsTest` is an abstract class that requires an implementation of `UserSettingsInterface` to be passed to its constructor. This design allows for testing different +implementations of `UserSettingsInterface` with the same set of tests. ### Test Cases - #### 1. `updateUserSettings should store custom settings for user` -This test verifies that the `updateUserSettings` method correctly stores custom settings for a user. It involves creating a test user, updating their settings, and then retrieving the settings to ensure they have been updated as expected. - +This test verifies that the `updateUserSettings` method correctly stores custom settings for a user. It involves creating a test user, updating their settings, and then retrieving +the settings to ensure they have been updated as expected. ##### Process Flow @@ -2820,18 +2652,17 @@ This test verifies that the `updateUserSettings` method correctly stores custom sequenceDiagram participant Test participant UserSettings - Test->>+UserSettings: updateUserSettings(testUser, newSettings) - UserSettings-->>-Test: Update Complete - Test->>+UserSettings: getUserSettings(testUser) - UserSettings-->>-Test: Return settings - Test->>Test: Assert settings are updated + Test ->>+ UserSettings: updateUserSettings(testUser, newSettings) + UserSettings -->>- Test: Update Complete + Test ->>+ UserSettings: getUserSettings(testUser) + UserSettings -->>- Test: Return settings + Test ->> Test: Assert settings are updated ``` - #### 2. `getUserSettings should return updated settings after updateUserSettings is called` -This test ensures that after updating a user's settings, the `getUserSettings` method returns the updated settings. It checks the initial state of a user's settings, updates the settings, and then verifies that the new settings are returned upon retrieval. - +This test ensures that after updating a user's settings, the `getUserSettings` method returns the updated settings. It checks the initial state of a user's settings, updates the +settings, and then verifies that the new settings are returned upon retrieval. ##### Process Flow @@ -2839,44 +2670,43 @@ This test ensures that after updating a user's settings, the `getUserSettings` m sequenceDiagram participant Test participant UserSettings - Test->>+UserSettings: getUserSettings(testUser) - UserSettings-->>-Test: Return initial settings - Test->>Test: Assert initial settings - Test->>+UserSettings: updateUserSettings(testUser, updatedSettings) - UserSettings-->>-Test: Update Complete - Test->>+UserSettings: getUserSettings(testUser) - UserSettings-->>-Test: Return updated settings - Test->>Test: Assert updated settings + Test ->>+ UserSettings: getUserSettings(testUser) + UserSettings -->>- Test: Return initial settings + Test ->> Test: Assert initial settings + Test ->>+ UserSettings: updateUserSettings(testUser, updatedSettings) + UserSettings -->>- Test: Update Complete + Test ->>+ UserSettings: getUserSettings(testUser) + UserSettings -->>- Test: Return updated settings + Test ->> Test: Assert updated settings ``` - ### Key Components - **User**: Represents a user in the system. Each user has an email, name, and ID. - **UserSettingsInterface**: An interface defining methods for updating and retrieving user settings. - - `updateUserSettings(User, UserSettings)`: Updates the settings for a given user. - - `getUserSettings(User)`: Retrieves the settings for a given user. + - `updateUserSettings(User, UserSettings)`: Updates the settings for a given user. + - `getUserSettings(User)`: Retrieves the settings for a given user. - **UserSettingsInterface.UserSettings**: A data class representing user settings. It includes a map of API keys associated with different API providers. - ### Conclusion -The `UserSettingsTest` class plays a crucial role in ensuring the reliability of the user settings management feature. By abstracting the `UserSettingsInterface`, it allows for flexible testing across different implementations, ensuring that user settings are correctly updated and retrieved across the platform. +The `UserSettingsTest` class plays a crucial role in ensuring the reliability of the user settings management feature. By abstracting the `UserSettingsInterface`, it allows for +flexible testing across different implementations, ensuring that user settings are correctly updated and retrieved across the platform. # kotlin\com\simiacryptus\skyenet\core\platform\test\StorageInterfaceTest.kt - ## StorageInterfaceTest Developer Documentation -The `StorageInterfaceTest` class is an abstract test suite designed to verify the functionality of implementations of the `StorageInterface`. This documentation provides an overview of the test methods available in the class and how they interact with the `StorageInterface`. - +The `StorageInterfaceTest` class is an abstract test suite designed to verify the functionality of implementations of the `StorageInterface`. This documentation provides an +overview of the test methods available in the class and how they interact with the `StorageInterface`. ### Overview -The `StorageInterface` is a critical component that abstracts storage operations for sessions, messages, and user-specific data. Implementations of this interface must provide mechanisms to handle data storage and retrieval in a consistent and reliable manner. - -The `StorageInterfaceTest` class ensures that any implementation of the `StorageInterface` adheres to the expected behavior through a series of unit tests. Each test is designed to validate specific functionalities such as session management, message handling, and JSON data operations. +The `StorageInterface` is a critical component that abstracts storage operations for sessions, messages, and user-specific data. Implementations of this interface must provide +mechanisms to handle data storage and retrieval in a consistent and reliable manner. +The `StorageInterfaceTest` class ensures that any implementation of the `StorageInterface` adheres to the expected behavior through a series of unit tests. Each test is designed to +validate specific functionalities such as session management, message handling, and JSON data operations. ### Test Methods @@ -2894,34 +2724,30 @@ Below is a summary of the test methods included in the `StorageInterfaceTest` cl - `testUserRoot()`: Verifies retrieval of the user's root directory. - `testDeleteSession()`: Ensures that a session can be deleted without errors. - ### Workflow Diagram -To better understand the interactions between the tests and the `StorageInterface`, the following Mermaid.js diagram illustrates a simplified workflow for a few selected test cases: +To better understand the interactions between the tests and the `StorageInterface`, the following Mermaid.js diagram illustrates a simplified workflow for a few selected test +cases: ```mermaid sequenceDiagram participant T as Test participant S as StorageInterface participant D as Data Storage - - T->>S: testGetJson() - S->>D: Fetch JSON - D-->>S: Return JSON - S-->>T: Assert NULL (non-existing) - - T->>S: testSetJson() - S->>D: Store JSON - D-->>S: Confirm - S-->>T: Assert Equal (settings) - - T->>S: testDeleteSession() - S->>D: Delete Session Data - D-->>S: Confirm Deletion - S-->>T: Assert No Exception + T ->> S: testGetJson() + S ->> D: Fetch JSON + D -->> S: Return JSON + S -->> T: Assert NULL (non-existing) + T ->> S: testSetJson() + S ->> D: Store JSON + D -->> S: Confirm + S -->> T: Assert Equal (settings) + T ->> S: testDeleteSession() + S ->> D: Delete Session Data + D -->> S: Confirm Deletion + S -->> T: Assert No Exception ``` - ### Testing Strategy Each test method follows a similar structure: @@ -2932,7 +2758,6 @@ Each test method follows a similar structure: This structure ensures that each test is isolated, focusing on a single behavior of the `StorageInterface`. - ### Extending Tests To extend the `StorageInterfaceTest` with additional tests for new methods in the `StorageInterface`, follow these steps: @@ -2944,34 +2769,33 @@ To extend the `StorageInterfaceTest` with additional tests for new methods in th Ensure that each new test method adheres to the testing strategy outlined above to maintain consistency and clarity in the test suite. - ### Conclusion -The `StorageInterfaceTest` class provides a comprehensive suite of tests to ensure the reliability and correctness of `StorageInterface` implementations. By following the testing strategy and extending the test suite as needed, developers can ensure that their storage solutions meet the required standards for functionality and robustness. +The `StorageInterfaceTest` class provides a comprehensive suite of tests to ensure the reliability and correctness of `StorageInterface` implementations. By following the testing +strategy and extending the test suite as needed, developers can ensure that their storage solutions meet the required standards for functionality and robustness. # kotlin\com\simiacryptus\skyenet\core\util\ClasspathRelationships.kt - ## ClasspathRelationships Module Documentation -The `ClasspathRelationships` module is part of the `com.simiacryptus.skyenet.core.util` package. It provides utilities for analyzing and managing relationships between classes within Java Archive (JAR) files. This documentation outlines the key functionalities provided by this module, including reading classes from JAR files, listing files within a JAR, and mapping class dependencies. - +The `ClasspathRelationships` module is part of the `com.simiacryptus.skyenet.core.util` package. It provides utilities for analyzing and managing relationships between classes +within Java Archive (JAR) files. This documentation outlines the key functionalities provided by this module, including reading classes from JAR files, listing files within a JAR, +and mapping class dependencies. ### Overview -The module consists of the `ClasspathRelationships` object, which contains methods for working with JAR files and a data class for representing references or relationships between classes. - +The module consists of the `ClasspathRelationships` object, which contains methods for working with JAR files and a data class for representing references or relationships between +classes. #### Key Components -- **Relation**: A sealed class representing a generic relationship between two methods. It has two open properties, `from_method` and `to_method`, which denote the source and target of the relationship, respectively. +- **Relation**: A sealed class representing a generic relationship between two methods. It has two open properties, `from_method` and `to_method`, which denote the source and + target of the relationship, respectively. - **Reference**: A data class that encapsulates a relationship between two classes (`from` and `to`) along with the specific `relation` between them. - **Utility Functions**: Functions for reading classes and files from JAR archives and for mapping class dependencies. - ### Functions - #### readJarClasses ```kotlin @@ -2980,17 +2804,14 @@ fun readJarClasses(jarPath: String): Map Reads and returns all classes from a specified JAR file. Each class is represented by its fully qualified name and its bytecode in the form of a `ByteArray`. - ##### Parameters - `jarPath`: The file system path to the JAR file. - ##### Returns - A `Map` where each key is a fully qualified class name and each value is the class's bytecode as a `ByteArray`. - #### readJarFiles ```kotlin @@ -2999,17 +2820,14 @@ fun readJarFiles(jarPath: String): Array Lists all files contained within a specified JAR file. - ##### Parameters - `jarPath`: The file system path to the JAR file. - ##### Returns - An `Array` of `String` containing the names of all files within the JAR file. - #### downstreamMap ```kotlin @@ -3018,22 +2836,18 @@ fun downstreamMap(dependencies: List): Map> Groups a list of `Reference` objects by their source class (`from`). - ##### Parameters - `dependencies`: A list of `Reference` objects representing class dependencies. - ##### Returns - A `Map` where each key is a class name and each value is a list of `Reference` objects originating from that class. - ### Diagrams To better understand the relationships and functionalities provided by this module, the following Mermaid.js diagrams can be used: - #### Class Relationships ```mermaid @@ -3053,7 +2867,6 @@ classDiagram This diagram illustrates the relationship between the `Relation` and `Reference` classes. `Reference` has a `Relation` indicating the type of relationship between two classes. - #### Functionality Overview ```mermaid @@ -3065,23 +2878,22 @@ graph LR This diagram shows how the main functions interact with JAR files and references between classes. - ### Conclusion -The `ClasspathRelationships` module provides essential utilities for analyzing class dependencies within JAR files, making it a valuable tool for developers working with Java applications. By leveraging the functionalities provided, developers can gain insights into the structure and relationships of classes in their applications. +The `ClasspathRelationships` module provides essential utilities for analyzing class dependencies within JAR files, making it a valuable tool for developers working with Java +applications. By leveraging the functionalities provided, developers can gain insights into the structure and relationships of classes in their applications. # kotlin\com\simiacryptus\skyenet\core\util\Ears.kt - ## Ears Class Documentation -The `Ears` class serves as the auditory interface for the SkyeNet system, facilitating audio input processing, command recognition, and dictation. It leverages the OpenAI API for audio transcription and command recognition. - +The `Ears` class serves as the auditory interface for the SkyeNet system, facilitating audio input processing, command recognition, and dictation. It leverages the OpenAI API for +audio transcription and command recognition. ### Overview -The `Ears` class is designed to capture audio input, transcribe it into text, and recognize specific commands within the transcribed text. It utilizes several components from the `com.simiacryptus.jopenai` package to achieve this functionality, including audio recording, loudness window buffering, and transcription processing. - +The `Ears` class is designed to capture audio input, transcribe it into text, and recognize specific commands within the transcribed text. It utilizes several components from the +`com.simiacryptus.jopenai` package to achieve this functionality, including audio recording, loudness window buffering, and transcription processing. ### Class Diagram @@ -3099,58 +2911,51 @@ classDiagram Ears --> "1" CommandRecognizer: Uses ``` - ### Key Components - #### CommandRecognizer Interface -Defines the structure for command recognition implementations. It includes a method `listenForCommand` that takes a `DictationBuffer` and returns a `CommandRecognized` object indicating whether a command was recognized and what the command was. - +Defines the structure for command recognition implementations. It includes a method `listenForCommand` that takes a `DictationBuffer` and returns a `CommandRecognized` object +indicating whether a command was recognized and what the command was. #### DictationBuffer Data Class Holds the transcribed text buffer for command recognition. - #### CommandRecognized Data Class Represents the outcome of command recognition, indicating whether a command was recognized and the recognized command text. - ### Key Methods - #### `listenForCommand` -Initiates listening for commands within the audio input. It captures audio, transcribes it to text, and checks the transcription for commands at intervals specified by `minCaptureMs`. +Initiates listening for commands within the audio input. It captures audio, transcribes it to text, and checks the transcription for commands at intervals specified by +`minCaptureMs`. - **Parameters:** - - `client`: The OpenAIClient instance for API interactions. - - `minCaptureMs`: Minimum milliseconds between command checks. - - `continueFn`: A function that returns `true` to continue listening or `false` to stop. - - `rawBuffer`: A deque holding raw audio data. - - `commandHandler`: A callback function that handles recognized commands. - + - `client`: The OpenAIClient instance for API interactions. + - `minCaptureMs`: Minimum milliseconds between command checks. + - `continueFn`: A function that returns `true` to continue listening or `false` to stop. + - `rawBuffer`: A deque holding raw audio data. + - `commandHandler`: A callback function that handles recognized commands. #### `startDictationListener` Starts the dictation listener that transcribes audio input to text. - **Parameters:** - - `client`: The OpenAIClient instance for API interactions. - - `continueFn`: A function that returns `true` to continue listening or `false` to stop. - - `rawBuffer`: A deque holding raw audio data. - - `textAppend`: A callback function that appends transcribed text. - + - `client`: The OpenAIClient instance for API interactions. + - `continueFn`: A function that returns `true` to continue listening or `false` to stop. + - `rawBuffer`: A deque holding raw audio data. + - `textAppend`: A callback function that appends transcribed text. #### `startAudioCapture` Begins capturing audio input and stores it in a `ConcurrentLinkedDeque`. - **Parameters:** - - `continueFn`: A function that returns `true` to continue capturing or `false` to stop. - + - `continueFn`: A function that returns `true` to continue capturing or `false` to stop. ### Usage Example @@ -3164,18 +2969,17 @@ ears.listenForCommand(apiClient) { command -> This example initializes the `Ears` class with an `OpenAIClient` instance and starts listening for commands. When a command is recognized, it prints the command to the console. - ### Conclusion -The `Ears` class provides a comprehensive solution for audio input processing and command recognition in the SkyeNet system. By leveraging the OpenAI API and custom audio processing components, it enables efficient and effective voice command functionality. +The `Ears` class provides a comprehensive solution for audio input processing and command recognition in the SkyeNet system. By leveraging the OpenAI API and custom audio +processing components, it enables efficient and effective voice command functionality. # kotlin\com\simiacryptus\skyenet\core\util\FunctionWrapper.kt - ## Developer Documentation for Function Interception and Recording -This documentation provides an overview of the function interception and recording mechanism implemented in the provided Kotlin code. The primary purpose of this mechanism is to intercept function calls, allowing for operations such as logging, modifying inputs or outputs, and recording function calls for debugging or auditing purposes. - +This documentation provides an overview of the function interception and recording mechanism implemented in the provided Kotlin code. The primary purpose of this mechanism is to +intercept function calls, allowing for operations such as logging, modifying inputs or outputs, and recording function calls for debugging or auditing purposes. ### Overview @@ -3186,7 +2990,6 @@ The codebase introduces several key components to achieve function interception - `NoopFunctionInterceptor`: A no-operation interceptor for cases where interception is not required. - `JsonFunctionRecorder`: An implementation of `FunctionInterceptor` that records function inputs and outputs as JSON files, useful for debugging and auditing. - ### Components Diagram ```mermaid @@ -3209,13 +3012,12 @@ classDiagram JsonFunctionRecorder : +operationDir() File ``` - ### Usage - #### Intercepting Functions -To intercept a function call, wrap the function call using an instance of `FunctionWrapper`, specifying the appropriate `FunctionInterceptor` implementation. For example, to record function calls as JSON: +To intercept a function call, wrap the function call using an instance of `FunctionWrapper`, specifying the appropriate `FunctionInterceptor` implementation. For example, to record +function calls as JSON: ```kotlin val recorder = JsonFunctionRecorder(File("/path/to/record")) @@ -3224,15 +3026,15 @@ val wrapper = FunctionWrapper(recorder) val result = wrapper.wrap { someFunctionCall() } ``` - #### Implementing Custom Interceptors -To implement a custom function interceptor, extend the `FunctionInterceptor` interface and override the `intercept` methods as needed. For example, a custom interceptor could modify the input parameters before passing them to the original function. - +To implement a custom function interceptor, extend the `FunctionInterceptor` interface and override the `intercept` methods as needed. For example, a custom interceptor could +modify the input parameters before passing them to the original function. #### Recording Function Calls -`JsonFunctionRecorder` is used to record function calls, inputs, and outputs as JSON files. This is particularly useful for debugging and auditing. To use it, instantiate `JsonFunctionRecorder` with a base directory for storing the records: +`JsonFunctionRecorder` is used to record function calls, inputs, and outputs as JSON files. This is particularly useful for debugging and auditing. To use it, instantiate +`JsonFunctionRecorder` with a base directory for storing the records: ```kotlin val recorder = JsonFunctionRecorder(File("/path/to/record")) @@ -3240,30 +3042,29 @@ val recorder = JsonFunctionRecorder(File("/path/to/record")) Wrap function calls using `FunctionWrapper` as shown in the previous section to record them. - ### Conclusion -The provided Kotlin code offers a flexible and powerful mechanism for intercepting and recording function calls. By leveraging `FunctionInterceptor` and its implementations, developers can easily add logging, debugging, and auditing capabilities to their applications. +The provided Kotlin code offers a flexible and powerful mechanism for intercepting and recording function calls. By leveraging `FunctionInterceptor` and its implementations, +developers can easily add logging, debugging, and auditing capabilities to their applications. # kotlin\com\simiacryptus\skyenet\core\util\LoggingInterceptor.kt - ## LoggingInterceptor Documentation -The `LoggingInterceptor` class is a utility designed to intercept and capture logging events from specified loggers within an application. This is particularly useful for debugging or testing purposes, where capturing the output of specific loggers can help diagnose issues or verify that certain conditions are being logged as expected. - +The `LoggingInterceptor` class is a utility designed to intercept and capture logging events from specified loggers within an application. This is particularly useful for debugging +or testing purposes, where capturing the output of specific loggers can help diagnose issues or verify that certain conditions are being logged as expected. ### Overview -The `LoggingInterceptor` extends `AppenderBase`, allowing it to be attached to SLF4J loggers (via Logback) and capture their logging events. It stores these events in a `StringBuffer`, which can then be retrieved and inspected. - +The `LoggingInterceptor` extends `AppenderBase`, allowing it to be attached to SLF4J loggers (via Logback) and capture their logging events. It stores these events +in a `StringBuffer`, which can then be retrieved and inspected. ### Usage - #### Basic Usage -To use the `LoggingInterceptor`, you typically wrap the code block you wish to capture logs from within a call to `LoggingInterceptor.withIntercept(...)`. This method temporarily attaches the `LoggingInterceptor` to the specified loggers, executes the code block, and then restores the original logger state. +To use the `LoggingInterceptor`, you typically wrap the code block you wish to capture logs from within a call to `LoggingInterceptor.withIntercept(...)`. This method temporarily +attaches the `LoggingInterceptor` to the specified loggers, executes the code block, and then restores the original logger state. ```kotlin val capturedLogs = StringBuffer() @@ -3273,15 +3074,12 @@ LoggingInterceptor.withIntercept(capturedLogs, "com.example.mylogger") { // Inspect capturedLogs here ``` - #### Advanced Usage For more control, you can directly instantiate and manage a `LoggingInterceptor` instance, though this requires manually managing the logger state. - ### Methods - #### `withIntercept` ```kotlin @@ -3295,13 +3093,12 @@ fun withIntercept( Captures logs from loggers with names starting with any of the specified prefixes, executing the provided function block, and then restores the original logger state. - **Parameters:** - - `stringBuffer`: The `StringBuffer` to capture logs to. - - `loggerPrefixes`: Vararg parameter specifying the logger name prefixes to intercept. - - `fn`: The function block to execute while capturing logs. + - `stringBuffer`: The `StringBuffer` to capture logs to. + - `loggerPrefixes`: Vararg parameter specifying the logger name prefixes to intercept. + - `fn`: The function block to execute while capturing logs. - **Returns:** The result of the function block `fn`. - #### `getStringBuffer` ```kotlin @@ -3310,24 +3107,20 @@ fun getStringBuffer(): StringBuffer Returns the `StringBuffer` containing the captured logs. - ### Internal Mechanics - #### Appender Attachment The `LoggingInterceptor` works by temporarily replacing the appenders of the specified loggers with itself. This allows it to capture all logging events directed to these loggers. - #### Log Capture When a logging event is received, the `LoggingInterceptor` appends the formatted message (and any associated throwable stack trace) to its internal `StringBuffer`. - #### Restoration -After the function block has executed, the original logger appenders and levels are restored, ensuring that the logger's original configuration is unaffected by the interception process. - +After the function block has executed, the original logger appenders and levels are restored, ensuring that the logger's original configuration is unaffected by the interception +process. ### Diagram: Logging Interception Flow @@ -3337,64 +3130,62 @@ sequenceDiagram participant LI as LoggingInterceptor participant Logger as Logger participant Appender as Original Appender - - Note over UserCode,LI: User initiates log capture - UserCode->>LI: withIntercept(...) - LI->>Logger: Detach Appender - LI->>Logger: Attach LoggingInterceptor - Note over UserCode,Logger: User code executes, logs captured - UserCode->>Logger: Log Event - Logger->>LI: Forward Log Event - LI->>UserCode: Capture Log to StringBuffer - Note over UserCode,LI: User code block ends - LI->>Logger: Detach LoggingInterceptor - LI->>Logger: Restore Original Appender + Note over UserCode, LI: User initiates log capture + UserCode ->> LI: withIntercept(...) + LI ->> Logger: Detach Appender + LI ->> Logger: Attach LoggingInterceptor + Note over UserCode, Logger: User code executes, logs captured + UserCode ->> Logger: Log Event + Logger ->> LI: Forward Log Event + LI ->> UserCode: Capture Log to StringBuffer + Note over UserCode, LI: User code block ends + LI ->> Logger: Detach LoggingInterceptor + LI ->> Logger: Restore Original Appender ``` This diagram illustrates the flow of control and data during the interception and capture of log events using the `LoggingInterceptor`. # kotlin\com\simiacryptus\skyenet\core\util\RuleTreeBuilder.kt - ## Developer Documentation for RuleTreeBuilder -The `RuleTreeBuilder` object in the `com.simiacryptus.skyenet.core.util` package is designed to generate Kotlin code expressions for matching and filtering strings based on sets of inclusion (`toMatch`) and exclusion (`doNotMatch`) criteria. This utility is particularly useful for dynamically generating rules for path matching, filtering collections, or any scenario where a set of string rules needs to be applied efficiently. - +The `RuleTreeBuilder` object in the `com.simiacryptus.skyenet.core.util` package is designed to generate Kotlin code expressions for matching and filtering strings based on sets of +inclusion (`toMatch`) and exclusion (`doNotMatch`) criteria. This utility is particularly useful for dynamically generating rules for path matching, filtering collections, or any +scenario where a set of string rules needs to be applied efficiently. ### Overview -The core functionality revolves around generating a `when` expression in Kotlin that evaluates to `true` or `false` based on whether a given string (`path`) matches the specified criteria. The criteria are defined by two sets of strings: `toMatch` (strings that should match) and `doNotMatch` (strings that should not match). The result is a compact, optimized Kotlin `when` expression that can be used in code to perform the matching. - +The core functionality revolves around generating a `when` expression in Kotlin that evaluates to `true` or `false` based on whether a given string (`path`) matches the specified +criteria. The criteria are defined by two sets of strings: `toMatch` (strings that should match) and `doNotMatch` (strings that should not match). The result is a compact, +optimized Kotlin `when` expression that can be used in code to perform the matching. ### Key Functions - #### `getRuleExpression` - **Description**: Generates the Kotlin `when` expression based on the provided sets of strings to match and not to match. - **Parameters**: - - `toMatch`: A `Set` containing the strings that should match. - - `doNotMatch`: A `SortedSet` containing the strings that should not match. - - `result`: A `Boolean` indicating the desired result when a match is found. + - `toMatch`: A `Set` containing the strings that should match. + - `doNotMatch`: A `SortedSet` containing the strings that should not match. + - `result`: A `Boolean` indicating the desired result when a match is found. - **Returns**: A `String` representing the Kotlin `when` expression. - #### `String Extensions` - **`escape`**: Escapes the dollar sign (`$`) in strings, which is necessary to avoid syntax errors in the generated Kotlin code. - **`safeSubstring`**: Safely extracts a substring, ensuring that the indices are within bounds and returning an empty string if not. - ### Internal Logic -The `getRuleExpression` function is the entry point for generating the rule expression. It internally calls `getRules` to construct the individual conditions of the `when` expression. The decision on whether to prioritize matching or not matching strings is made based on the size of the respective sets, aiming to optimize the resulting expression. - +The `getRuleExpression` function is the entry point for generating the rule expression. It internally calls `getRules` to construct the individual conditions of the `when` +expression. The decision on whether to prioritize matching or not matching strings is made based on the size of the respective sets, aiming to optimize the resulting expression. #### Optimization Strategies -1. **Prefix Matching**: The algorithm attempts to find common prefixes among the strings to match and not to match, optimizing the generated rules by grouping them based on these prefixes. -2. **Entropy Calculation**: For each potential prefix, an entropy value is calculated to determine the effectiveness of splitting the sets based on that prefix. The prefix with the best (lowest) entropy is chosen for splitting. - +1. **Prefix Matching**: The algorithm attempts to find common prefixes among the strings to match and not to match, optimizing the generated rules by grouping them based on these + prefixes. +2. **Entropy Calculation**: For each potential prefix, an entropy value is calculated to determine the effectiveness of splitting the sets based on that prefix. The prefix with the + best (lowest) entropy is chosen for splitting. ### Mermaid.js Diagram: Rule Generation Process @@ -3413,7 +3204,6 @@ graph TD; I --> F; ``` - ### Usage Example ```kotlin @@ -3425,18 +3215,17 @@ println(result) This will generate a Kotlin `when` expression that can be used to determine if a given path should be included or excluded based on the specified criteria. - ### Conclusion -The `RuleTreeBuilder` provides a powerful tool for dynamically generating optimized string matching rules in Kotlin. By leveraging prefix analysis and entropy calculations, it efficiently condenses complex sets of matching criteria into concise `when` expressions, suitable for a wide range of applications where dynamic string filtering is required. +The `RuleTreeBuilder` provides a powerful tool for dynamically generating optimized string matching rules in Kotlin. By leveraging prefix analysis and entropy calculations, it +efficiently condenses complex sets of matching criteria into concise `when` expressions, suitable for a wide range of applications where dynamic string filtering is required. # kotlin\com\simiacryptus\skyenet\core\util\Selenium.kt - ## Selenium Interface Documentation -The `Selenium` interface is part of the `com.simiacryptus.skyenet.core.util` package and is designed to provide an abstraction layer for web scraping and automation tasks using Selenium WebDriver. It extends the `AutoCloseable` interface, ensuring that resources are automatically released when no longer needed. - +The `Selenium` interface is part of the `com.simiacryptus.skyenet.core.util` package and is designed to provide an abstraction layer for web scraping and automation tasks using +Selenium WebDriver. It extends the `AutoCloseable` interface, ensuring that resources are automatically released when no longer needed. ### Interface Overview @@ -3454,24 +3243,21 @@ interface Selenium : AutoCloseable { } ``` - #### Methods - ##### `save` The `save` method is responsible for saving the content of a web page to a specified location on the disk. - **Parameters:** - - `url`: The URL of the web page to be saved. - - `currentFilename`: An optional filename to use for saving the page. If `null`, a default or generated filename may be used based on the implementation. - - `saveRoot`: The root directory where the web page will be saved. The method may create subdirectories within this root based on the URL or other criteria. + - `url`: The URL of the web page to be saved. + - `currentFilename`: An optional filename to use for saving the page. If `null`, a default or generated filename may be used based on the implementation. + - `saveRoot`: The root directory where the web page will be saved. The method may create subdirectories within this root based on the URL or other criteria. - **Returns:** This method does not return a value. - **Throws:** Implementations may throw exceptions to indicate errors such as invalid URLs, IO errors, or permission issues. - #### Diagram: Workflow of `save` Method To illustrate how the `save` method could be utilized within a system, consider the following sequence diagram created using Mermaid.js syntax: @@ -3492,8 +3278,8 @@ sequenceDiagram Selenium-->>-Client: Return ``` -This diagram demonstrates the basic flow when a client code calls the `save` method. Depending on whether `currentFilename` is provided, the implementation might either directly use it to create or overwrite a file at the specified `saveRoot` or generate a new filename based on its logic. - +This diagram demonstrates the basic flow when a client code calls the `save` method. Depending on whether `currentFilename` is provided, the implementation might either directly +use it to create or overwrite a file at the specified `saveRoot` or generate a new filename based on its logic. #### Usage Example @@ -3520,30 +3306,30 @@ fun main() { } ``` -In this example, `MySeleniumImpl` is a concrete implementation of the `Selenium` interface. The `main` function demonstrates how to use the `save` method to save the content of "http://example.com" to a specified path, and then it ensures that resources are properly released by calling `close`. - +In this example, `MySeleniumImpl` is a concrete implementation of the `Selenium` interface. The `main` function demonstrates how to use the `save` method to save the content +of "http://example.com" to a specified path, and then it ensures that resources are properly released by calling `close`. #### Conclusion -The `Selenium` interface provides a structured way to interact with web pages for the purpose of saving their content locally. By implementing this interface, developers can create flexible and reusable web scraping or automation tools that leverage the power of Selenium WebDriver while managing resources efficiently. +The `Selenium` interface provides a structured way to interact with web pages for the purpose of saving their content locally. By implementing this interface, developers can create +flexible and reusable web scraping or automation tools that leverage the power of Selenium WebDriver while managing resources efficiently. # kotlin\com\simiacryptus\skyenet\core\util\StringSplitter.kt - ## Developer Documentation for `StringSplitter` -The `StringSplitter` object in the `com.simiacryptus.skyenet.core.util` package provides a utility function for splitting a string based on a set of specified separators and their associated weights. This document outlines the functionality and usage of the `StringSplitter` object. - +The `StringSplitter` object in the `com.simiacryptus.skyenet.core.util` package provides a utility function for splitting a string based on a set of specified separators and their +associated weights. This document outlines the functionality and usage of the `StringSplitter` object. ### Overview -The `StringSplitter` object contains a single public function, `split`, which takes a string and a map of separators with their corresponding weights. It returns a pair of strings, representing the text split at the optimal point determined by the algorithm. - +The `StringSplitter` object contains a single public function, `split`, which takes a string and a map of separators with their corresponding weights. It returns a pair of strings, +representing the text split at the optimal point determined by the algorithm. #### Functionality -- **split**: Splits a given string into two parts based on the optimal separator found in the provided map. The optimality is calculated using a weighted scoring system that considers the position of the separator and its weight. - +- **split**: Splits a given string into two parts based on the optimal separator found in the provided map. The optimality is calculated using a weighted scoring system that + considers the position of the separator and its weight. #### Usage @@ -3561,7 +3347,6 @@ val result = StringSplitter.split( println(result.toList().joinToString("\n")) ``` - ### Algorithm The `split` function works as follows: @@ -3571,7 +3356,6 @@ The `split` function works as follows: 3. It selects the separator occurrence with the highest score as the split point. 4. The text is split at the selected point, and a pair of strings is returned. - #### Score Calculation The score for each separator occurrence is calculated using the formula: @@ -3581,11 +3365,11 @@ score = (b * log(a)) + (a * log(b)) / weight ``` where: + - `a` is the ratio of the separator's position to the text length, - `b` is `1 - a`, - `weight` is the weight of the separator from the input map. - ### Mermaid Diagram The following Mermaid diagram illustrates the process flow of the `split` function: @@ -3608,7 +3392,6 @@ graph TD K --> L[End] ``` - ### Example The `main` function in the `StringSplitter` object provides an example of how to use the `split` function: @@ -3630,23 +3413,22 @@ fun main(args: Array) { This example demonstrates splitting a sample text using periods, spaces, and commas as separators with specified weights. - ### Conclusion -The `StringSplitter` provides a flexible and efficient way to split strings based on weighted separators. Its algorithm ensures that the split point is chosen optimally, considering both the position of the separators and their assigned importance. +The `StringSplitter` provides a flexible and efficient way to split strings based on weighted separators. Its algorithm ensures that the split point is chosen optimally, +considering both the position of the separators and their assigned importance. # kotlin\com\simiacryptus\skyenet\interpreter\Interpreter.kt - ## Skyenet Interpreter Interface Documentation -The `Interpreter` interface is a core component of the Skyenet project, designed to provide a flexible foundation for implementing various programming language interpreters. This document outlines the structure, functionality, and usage of the `Interpreter` interface, along with a guide on extending it for custom implementations. - +The `Interpreter` interface is a core component of the Skyenet project, designed to provide a flexible foundation for implementing various programming language interpreters. This +document outlines the structure, functionality, and usage of the `Interpreter` interface, along with a guide on extending it for custom implementations. ### Interface Overview -The `Interpreter` interface defines a set of methods essential for interpreting code written in a specific programming language. Implementations of this interface are expected to provide the logic for executing code, validating syntax, and managing symbols within the language's scope. - +The `Interpreter` interface defines a set of methods essential for interpreting code written in a specific programming language. Implementations of this interface are expected to +provide the logic for executing code, validating syntax, and managing symbols within the language's scope. #### Key Methods @@ -3655,22 +3437,22 @@ The `Interpreter` interface defines a set of methods essential for interpreting - `run(code: String)`: Executes the given code string and returns the result. - `validate(code: String)`: Checks the given code string for syntax errors or other issues. Returns a `Throwable` if any issues are found, or `null` if the code is valid. - `wrapCode(code: String)`: Provides a default implementation that simply returns the input code. This method can be overridden to modify or preprocess code before execution. -- `wrapExecution(fn: java.util.function.Supplier)`: Executes the supplied function within a context or wrapper defined by the interpreter. This is useful for handling exceptions, logging, or other cross-cutting concerns. - +- `wrapExecution(fn: java.util.function.Supplier)`: Executes the supplied function within a context or wrapper defined by the interpreter. This is useful for handling + exceptions, logging, or other cross-cutting concerns. #### Companion Object The companion object of the `Interpreter` interface contains utility methods and classes for testing implementations of the interface. - ##### `test(factory: java.util.function.Function, Interpreter>)` -This static method facilitates testing of interpreter implementations. It uses a factory function to create instances of the interpreter with predefined symbols and then runs test cases to verify the implementation's correctness. - +This static method facilitates testing of interpreter implementations. It uses a factory function to create instances of the interpreter with predefined symbols and then runs test +cases to verify the implementation's correctness. #### Usage Example -Implementing a simple interpreter might involve extending the `Interpreter` interface and providing implementations for the abstract methods. Below is a hypothetical example of an interpreter for a simple scripting language: +Implementing a simple interpreter might involve extending the `Interpreter` interface and providing implementations for the abstract methods. Below is a hypothetical example of an +interpreter for a simple scripting language: ```kotlin class SimpleScriptInterpreter : Interpreter { @@ -3690,16 +3472,15 @@ class SimpleScriptInterpreter : Interpreter { } ``` - ### Extending the Interface -To create a custom interpreter, one must implement all abstract methods of the `Interpreter` interface. Additionally, the `wrapCode` and `wrapExecution` methods can be overridden to provide custom behavior for code preprocessing and execution wrapping, respectively. - +To create a custom interpreter, one must implement all abstract methods of the `Interpreter` interface. Additionally, the `wrapCode` and `wrapExecution` methods can be overridden +to provide custom behavior for code preprocessing and execution wrapping, respectively. ### Testing Interpreters -The companion object's `test` method provides a convenient way to test custom interpreter implementations. It automatically sets up test cases based on provided symbols and expected outcomes, simplifying the process of verifying the correctness of interpreter logic. - +The companion object's `test` method provides a convenient way to test custom interpreter implementations. It automatically sets up test cases based on provided symbols and +expected outcomes, simplifying the process of verifying the correctness of interpreter logic. ### Diagrams @@ -3728,20 +3509,20 @@ classDiagram Interpreter : +test(factory: Function~Map~String, Any~, Interpreter~) ``` -This diagram shows the `Interpreter` interface, its methods, and how it relates to test utilities provided within the companion object. Implementing classes or objects (`TestObject`, `TestInterface`) should provide concrete implementations of the interface's methods to fulfill the contract of an interpreter. - +This diagram shows the `Interpreter` interface, its methods, and how it relates to test utilities provided within the companion object. Implementing classes or objects ( +`TestObject`, `TestInterface`) should provide concrete implementations of the interface's methods to fulfill the contract of an interpreter. ### Conclusion -The `Interpreter` interface serves as a foundational component for building interpreters in the Skyenet project. By following the guidelines and utilizing the testing utilities provided, developers can create robust and flexible interpreters for various programming languages. +The `Interpreter` interface serves as a foundational component for building interpreters in the Skyenet project. By following the guidelines and utilizing the testing utilities +provided, developers can create robust and flexible interpreters for various programming languages. # kotlin\com\simiacryptus\skyenet\interpreter\InterpreterTestBase.kt - ## Interpreter Test Base Documentation -The `InterpreterTestBase` class serves as an abstract base for testing implementations of an interpreter. It provides a structured way to validate both the execution and validation capabilities of an interpreter with various inputs, including valid code, invalid code, and code that utilizes variables and tools. - +The `InterpreterTestBase` class serves as an abstract base for testing implementations of an interpreter. It provides a structured way to validate both the execution and validation +capabilities of an interpreter with various inputs, including valid code, invalid code, and code that utilizes variables and tools. ### Overview @@ -3751,15 +3532,13 @@ The `InterpreterTestBase` class includes a series of JUnit tests designed to ens - Validation of code correctness - Handling of variables and tools within the code - ### Key Methods -- `newInterpreter(map: Map): Interpreter` - An abstract method that should be implemented to return an instance of the interpreter to be tested, optionally initialized with a map of variables. - +- `newInterpreter(map: Map): Interpreter` - An abstract method that should be implemented to return an instance of the interpreter to be tested, optionally initialized + with a map of variables. ### Test Cases - #### Execution Tests 1. **Valid Code Execution**: Tests if the interpreter can correctly execute a simple arithmetic operation. @@ -3768,7 +3547,6 @@ The `InterpreterTestBase` class includes a series of JUnit tests designed to ens 4. **Execution with Tool**: Verifies the interpreter's ability to execute code that interacts with an object (referred to as a "tool"). 5. **Invalid Tool Usage**: Tests the interpreter's error handling when code attempts to call a non-existent method on a tool. - #### Validation Tests 1. **Valid Code Validation**: Confirms that the interpreter correctly identifies syntactically correct code as valid. @@ -3778,10 +3556,8 @@ The `InterpreterTestBase` class includes a series of JUnit tests designed to ens 5. **Invalid Tool Usage in Validation**: Tests the interpreter's validation logic when code attempts to call a non-existent method on a tool. 6. **Undefined Variable Validation**: Ensures the interpreter correctly flags code that uses undefined variables as invalid. - ### Diagrams - #### Test Flow Diagram ```mermaid @@ -3798,18 +3574,18 @@ flowchart TD F --> I[End Test] ``` -This diagram illustrates the general flow of tests in the `InterpreterTestBase` class. It highlights the decision points based on code validity and the use of variables or tools, leading to different paths for execution and validation. - +This diagram illustrates the general flow of tests in the `InterpreterTestBase` class. It highlights the decision points based on code validity and the use of variables or tools, +leading to different paths for execution and validation. ### Usage To use the `InterpreterTestBase` class, follow these steps: 1. **Extend the Class**: Create a new class that extends `InterpreterTestBase`. -2. **Implement `newInterpreter`**: Provide an implementation for the `newInterpreter` method to return an instance of your interpreter, optionally initialized with variables or tools. +2. **Implement `newInterpreter`**: Provide an implementation for the `newInterpreter` method to return an instance of your interpreter, optionally initialized with variables or + tools. 3. **Run Tests**: Execute the tests to validate your interpreter's functionality. - ### Example ```kotlin diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/ActorSystem.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/ActorSystem.kt index 2496c789..102ed9bc 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/ActorSystem.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/ActorSystem.kt @@ -2,8 +2,8 @@ package com.simiacryptus.skyenet.core.actors import com.simiacryptus.skyenet.core.platform.ApplicationServices import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.StorageInterface -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.StorageInterface +import com.simiacryptus.skyenet.core.platform.model.User open class ActorSystem>( val actors: Map>, diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/BaseActor.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/BaseActor.kt index 528edad9..be4c2845 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/BaseActor.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/BaseActor.kt @@ -1,17 +1,16 @@ package com.simiacryptus.skyenet.core.actors import com.simiacryptus.jopenai.API -import com.simiacryptus.jopenai.models.ApiModel import com.simiacryptus.jopenai.ChatClient -import com.simiacryptus.jopenai.OpenAIClient -import com.simiacryptus.jopenai.models.ChatModels +import com.simiacryptus.jopenai.models.ApiModel +import com.simiacryptus.jopenai.models.ChatModel import com.simiacryptus.jopenai.models.OpenAIModel -import com.simiacryptus.jopenai.models.OpenAITextModel +import com.simiacryptus.jopenai.models.TextModel abstract class BaseActor( open val prompt: String, val name: String? = null, - val model: OpenAITextModel, + val model: TextModel, val temperature: Double = 0.3, ) { abstract fun respond(input: I, api: API, vararg messages: ApiModel.ChatMessage): R @@ -28,5 +27,5 @@ abstract class BaseActor( open fun answer(input: I, api: API): R = respond(input = input, api = api, *chatMessages(input)) abstract fun chatMessages(questions: I): Array - abstract fun withModel(model: ChatModels): BaseActor + abstract fun withModel(model: ChatModel): BaseActor } \ No newline at end of file diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/CodingActor.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/CodingActor.kt index 4a0c9a6b..75db0881 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/CodingActor.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/CodingActor.kt @@ -1,14 +1,13 @@ package com.simiacryptus.skyenet.core.actors import com.simiacryptus.jopenai.API -import com.simiacryptus.jopenai.models.ApiModel.* import com.simiacryptus.jopenai.ChatClient import com.simiacryptus.jopenai.describe.AbbrevWhitelistTSDescriber -import com.simiacryptus.jopenai.describe.AbbrevWhitelistYamlDescriber import com.simiacryptus.jopenai.describe.TypeDescriber -import com.simiacryptus.jopenai.models.ChatModels +import com.simiacryptus.jopenai.models.ApiModel.* +import com.simiacryptus.jopenai.models.ChatModel import com.simiacryptus.jopenai.models.OpenAIModels -import com.simiacryptus.jopenai.models.OpenAITextModel +import com.simiacryptus.jopenai.models.TextModel import com.simiacryptus.jopenai.util.ClientUtil.toContentList import com.simiacryptus.skyenet.core.OutputInterceptor import com.simiacryptus.skyenet.interpreter.Interpreter @@ -16,7 +15,7 @@ import java.util.* import javax.script.ScriptException import kotlin.reflect.KClass -private const val TT = "`"+"`"+"`" +private const val TT = "`" + "`" + "`" typealias CodeInterceptor = (String) -> String @@ -29,8 +28,8 @@ open class CodingActor( ), name: String? = interpreterClass.simpleName, val details: String? = null, - model: OpenAITextModel = OpenAIModels.GPT4o, - val fallbackModel: ChatModels = OpenAIModels.GPT4o, + model: TextModel = OpenAIModels.GPT4o, + val fallbackModel: ChatModel = OpenAIModels.GPT4o, temperature: Double = 0.1, val runtimeSymbols: Map = mapOf(), var codeInterceptor: CodeInterceptor = { it } @@ -92,7 +91,7 @@ They are already defined for you. ${details ?: ""} """.trim() - } else """ + } else """ You are a coding assistant allowing users actions to be enacted using $language and the script context. Your role is to translate natural language instructions into code as well as interpret the results and converse with the user. Use $TT code blocks labeled with $language where appropriate. (i.e. ${TT}$language) @@ -247,7 +246,7 @@ ${details ?: ""} override val code: String = givenCode ?: implementation.first private fun implement( - model: OpenAITextModel, + model: TextModel, ): Pair { val request = ChatRequest(messages = ArrayList(this.messages.toList())) for (codingAttempt in 0..input.fixRetries) { @@ -322,7 +321,7 @@ ${TT} previousCode: String, error: Throwable, vararg promptMessages: ChatMessage, - model: OpenAITextModel + model: TextModel ): String = chat( api = api, request = ChatRequest( @@ -354,12 +353,12 @@ Correct the code and try again. model = model ) - private fun chat(api: ChatClient, request: ChatRequest, model: OpenAITextModel) = + private fun chat(api: ChatClient, request: ChatRequest, model: TextModel) = api.chat(request.copy(model = model.modelName, temperature = temperature), model) .choices.first().message?.content.orEmpty().trim() - override fun withModel(model: ChatModels): CodingActor = CodingActor( + override fun withModel(model: ChatModel): CodingActor = CodingActor( interpreterClass = interpreterClass, symbols = symbols, describer = describer, @@ -368,7 +367,7 @@ Correct the code and try again. model = model, fallbackModel = fallbackModel, temperature = temperature, - runtimeSymbols = runtimeSymbols, + runtimeSymbols = runtimeSymbols, codeInterceptor = codeInterceptor ) diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/ImageActor.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/ImageActor.kt index 7b4f920f..7e0669f7 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/ImageActor.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/ImageActor.kt @@ -1,13 +1,13 @@ package com.simiacryptus.skyenet.core.actors import com.simiacryptus.jopenai.API +import com.simiacryptus.jopenai.OpenAIClient import com.simiacryptus.jopenai.models.ApiModel import com.simiacryptus.jopenai.models.ApiModel.ChatMessage import com.simiacryptus.jopenai.models.ApiModel.ImageGenerationRequest -import com.simiacryptus.jopenai.OpenAIClient -import com.simiacryptus.jopenai.models.ChatModels +import com.simiacryptus.jopenai.models.ChatModel import com.simiacryptus.jopenai.models.ImageModels -import com.simiacryptus.jopenai.models.OpenAITextModel +import com.simiacryptus.jopenai.models.TextModel import com.simiacryptus.jopenai.util.ClientUtil.toChatMessage import com.simiacryptus.jopenai.util.ClientUtil.toContentList import java.awt.image.BufferedImage @@ -17,7 +17,7 @@ import javax.imageio.ImageIO open class ImageActor( prompt: String = "Transform the user request into an image generation prompt that the user will like", name: String? = null, - textModel: OpenAITextModel, + textModel: TextModel, val imageModel: ImageModels = ImageModels.DallE2, temperature: Double = 0.3, val width: Int = 1024, @@ -81,7 +81,7 @@ open class ImageActor( return ImageResponseImpl(text, api = this.openAI!!) } - override fun withModel(model: ChatModels): ImageActor = ImageActor( + override fun withModel(model: ChatModel): ImageActor = ImageActor( prompt = prompt, name = name, textModel = model, diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/ParsedActor.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/ParsedActor.kt index 944e69a8..e2cb3719 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/ParsedActor.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/ParsedActor.kt @@ -5,9 +5,9 @@ import com.simiacryptus.jopenai.ChatClient import com.simiacryptus.jopenai.describe.AbbrevWhitelistYamlDescriber import com.simiacryptus.jopenai.describe.TypeDescriber import com.simiacryptus.jopenai.models.ApiModel -import com.simiacryptus.jopenai.models.ChatModels +import com.simiacryptus.jopenai.models.ChatModel import com.simiacryptus.jopenai.models.OpenAIModels -import com.simiacryptus.jopenai.models.OpenAITextModel +import com.simiacryptus.jopenai.models.TextModel import com.simiacryptus.jopenai.util.ClientUtil.toContentList import com.simiacryptus.skyenet.core.util.MultiExeption import com.simiacryptus.util.JsonUtil @@ -19,9 +19,9 @@ open class ParsedActor( val exampleInstance: T? = resultClass?.getConstructor()?.newInstance(), prompt: String = "", name: String? = resultClass?.simpleName, - model: OpenAITextModel = OpenAIModels.GPT4o, + model: TextModel = OpenAIModels.GPT4o, temperature: Double = 0.3, - val parsingModel: OpenAITextModel = OpenAIModels.GPT4oMini, + val parsingModel: TextModel = OpenAIModels.GPT4oMini, val deserializerRetries: Int = 2, open val describer: TypeDescriber = object : AbbrevWhitelistYamlDescriber( "com.simiacryptus", "com.github.simiacryptus" @@ -145,7 +145,7 @@ open class ParsedActor( } } - override fun withModel(model: ChatModels): ParsedActor = ParsedActor( + override fun withModel(model: ChatModel): ParsedActor = ParsedActor( resultClass = resultClass, prompt = prompt, name = name, diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/SimpleActor.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/SimpleActor.kt index 86899cbb..606cf0dc 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/SimpleActor.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/SimpleActor.kt @@ -2,14 +2,14 @@ package com.simiacryptus.skyenet.core.actors import com.simiacryptus.jopenai.API import com.simiacryptus.jopenai.models.ApiModel -import com.simiacryptus.jopenai.models.ChatModels -import com.simiacryptus.jopenai.models.OpenAITextModel +import com.simiacryptus.jopenai.models.ChatModel +import com.simiacryptus.jopenai.models.TextModel import com.simiacryptus.jopenai.util.ClientUtil.toContentList open class SimpleActor( prompt: String, name: String? = null, - model: OpenAITextModel, + model: TextModel, temperature: Double = 0.3, ) : BaseActor, String>( prompt = prompt, @@ -33,7 +33,7 @@ open class SimpleActor( ) } - override fun withModel(model: ChatModels): SimpleActor = SimpleActor( + override fun withModel(model: ChatModel): SimpleActor = SimpleActor( prompt = prompt, name = name, model = model, diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/TextToSpeechActor.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/TextToSpeechActor.kt index 97bce168..fd412bbf 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/TextToSpeechActor.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/actors/TextToSpeechActor.kt @@ -1,11 +1,11 @@ package com.simiacryptus.skyenet.core.actors import com.simiacryptus.jopenai.API +import com.simiacryptus.jopenai.OpenAIClient import com.simiacryptus.jopenai.models.ApiModel import com.simiacryptus.jopenai.models.ApiModel.ChatMessage -import com.simiacryptus.jopenai.OpenAIClient import com.simiacryptus.jopenai.models.AudioModels -import com.simiacryptus.jopenai.models.ChatModels +import com.simiacryptus.jopenai.models.ChatModel import com.simiacryptus.jopenai.util.ClientUtil.toContentList open class TextToSpeechActor( @@ -13,7 +13,7 @@ open class TextToSpeechActor( val audioModel: AudioModels = AudioModels.TTS_HD, val voice: String = "alloy", val speed: Double = 1.0, - val models: ChatModels, + val models: ChatModel, ) : BaseActor, SpeechResponse>( prompt = "", name = name, @@ -59,7 +59,7 @@ open class TextToSpeechActor( ) - override fun withModel(model: ChatModels) = TextToSpeechActor(name, audioModel, voice, speed, model) + override fun withModel(model: ChatModel) = TextToSpeechActor(name, audioModel, voice, speed, model) .also { it.openAI = this.openAI } } diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/ApplicationServices.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/ApplicationServices.kt index 9f80a256..5bd95bbc 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/ApplicationServices.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/ApplicationServices.kt @@ -1,37 +1,20 @@ package com.simiacryptus.skyenet.core.platform -import com.fasterxml.jackson.annotation.JsonIgnore -import com.fasterxml.jackson.annotation.JsonProperty -import com.google.common.util.concurrent.AtomicDouble -import com.simiacryptus.jopenai.models.ApiModel -import com.simiacryptus.jopenai.models.APIProvider -import com.simiacryptus.jopenai.models.ChatModels -import com.simiacryptus.jopenai.models.OpenAIModel -import com.simiacryptus.skyenet.core.platform.ApplicationServicesConfig.dataStorageRoot -import com.simiacryptus.skyenet.core.platform.ApplicationServicesConfig.isLocked import com.simiacryptus.skyenet.core.platform.file.* +import com.simiacryptus.skyenet.core.platform.hsql.HSQLMetadataStorage +import com.simiacryptus.skyenet.core.platform.hsql.HSQLUsageManager +import com.simiacryptus.skyenet.core.platform.model.ApplicationServicesConfig.dataStorageRoot +import com.simiacryptus.skyenet.core.platform.model.ApplicationServicesConfig.isLocked +import com.simiacryptus.skyenet.core.platform.model.AuthenticationInterface +import com.simiacryptus.skyenet.core.platform.model.AuthorizationInterface +import com.simiacryptus.skyenet.core.platform.model.CloudPlatformInterface +import com.simiacryptus.skyenet.core.platform.model.MetadataStorageInterface +import com.simiacryptus.skyenet.core.platform.model.StorageInterface +import com.simiacryptus.skyenet.core.platform.model.UsageInterface +import com.simiacryptus.skyenet.core.platform.model.UserSettingsInterface import com.simiacryptus.skyenet.core.util.Selenium import java.io.File -import java.nio.ByteBuffer -import java.util.* import java.util.concurrent.ThreadPoolExecutor -import java.util.concurrent.atomic.AtomicInteger -import java.util.concurrent.atomic.AtomicLong -import kotlin.random.Random - -object ApplicationServicesConfig { - - var isLocked: Boolean = false - set(value) { - require(!isLocked) { "ApplicationServices is locked" } - field = value - } - var dataStorageRoot: File = File(System.getProperty("user.home"), ".skyenet") - set(value) { - require(!isLocked) { "ApplicationServices is locked" } - field = value - } -} object ApplicationServices { var authorizationManager: AuthorizationInterface = AuthorizationManager() @@ -54,6 +37,11 @@ object ApplicationServices { require(!isLocked) { "ApplicationServices is locked" } field = value } + var metadataStorageFactory: (File) -> MetadataStorageInterface = { HSQLMetadataStorage(it) } + set(value) { + require(!isLocked) { "ApplicationServices is locked" } + field = value + } var clientManager: ClientManager = ClientManager() set(value) { require(!isLocked) { "ApplicationServices is locked" } @@ -78,261 +66,4 @@ object ApplicationServices { field = value } -} - -interface AuthenticationInterface { - fun getUser(accessToken: String?): User? - - fun putUser(accessToken: String, user: User): User - fun logout(accessToken: String, user: User) - //fun removeToken(accessToken: String) - - companion object { - const val AUTH_COOKIE = "sessionId" - } -} - -interface AuthorizationInterface { - enum class OperationType { - Read, - Write, - Public, - Share, - Execute, - Delete, - Admin, - GlobalKey, - } - - fun isAuthorized( - applicationClass: Class<*>?, - user: User?, - operationType: OperationType, - ): Boolean -} - -interface StorageInterface { - - fun getMessages( - user: User?, - session: Session - ): LinkedHashMap - - fun getSessionDir( - user: User?, - session: Session - ): File - - fun getDataDir( - user: User?, - session: Session - ): File - - fun getSessionName( - user: User?, - session: Session - ): String - - fun getSessionTime( - user: User?, - session: Session - ): Date? - - fun listSessions( - user: User?, - path: String, - ): List - - fun setJson( - user: User?, - session: Session, - filename: String, - settings: T - ): T - - fun updateMessage( - user: User?, - session: Session, - messageId: String, - value: String - ) - - fun listSessions(dir: File, path: String): List - fun userRoot(user: User?): File - fun deleteSession(user: User?, session: Session) - fun getMessageIds( - user: User?, - session: Session - ): List - - fun setMessageIds( - user: User?, - session: Session, - ids: List - ) - - companion object { - - fun validateSessionId( - session: Session - ) { - if (!session.sessionId.matches("""([GU]-)?\d{8}-[\w+-.]{4}""".toRegex())) { - throw IllegalArgumentException("Invalid session ID: $session") - } - } - - fun newGlobalID(): Session { - val yyyyMMdd = java.time.LocalDate.now().toString().replace("-", "") - //log.debug("New ID: $yyyyMMdd-$uuid") - return Session("G-$yyyyMMdd-${id2()}") - } - - fun long64() = Base64.getEncoder().encodeToString(ByteBuffer.allocate(8).putLong(Random.nextLong()).array()) - .toString().replace("=", "").replace("/", ".").replace("+", "-") - - fun newUserID(): Session { - val yyyyMMdd = java.time.LocalDate.now().toString().replace("-", "") - //log.debug("New ID: $yyyyMMdd-$uuid") - return Session("U-$yyyyMMdd-${id2()}") - } - - private fun id2() = long64().filter { - when (it) { - in 'a'..'z' -> true - in 'A'..'Z' -> true - in '0'..'9' -> true - else -> false - } - }.take(4) - - fun parseSessionID(sessionID: String): Session { - val session = Session(sessionID) - validateSessionId(session) - return session - } - - } -} - -interface UserSettingsInterface { - data class UserSettings( - val apiKeys: Map = APIProvider.values().associateWith { "" }, - val apiBase: Map = APIProvider.values().associateWith { it.base ?: "" }, - ) - - fun getUserSettings(user: User): UserSettings - - fun updateUserSettings(user: User, settings: UserSettings) -} - - -interface UsageInterface { - fun incrementUsage(session: Session, user: User?, model: OpenAIModel, tokens: ApiModel.Usage) = incrementUsage( - session, when (user) { - null -> null - else -> { - val userSettings = ApplicationServices.userSettingsManager.getUserSettings(user) - userSettings.apiKeys[if (model is ChatModels) { - model.provider - } else { - APIProvider.OpenAI - }] - } - }, model, tokens - ) - - fun incrementUsage(session: Session, apiKey: String?, model: OpenAIModel, tokens: ApiModel.Usage) - - fun getUserUsageSummary(user: User): Map = getUserUsageSummary( - ApplicationServices.userSettingsManager.getUserSettings(user).apiKeys[APIProvider.OpenAI]!! // TODO: Support other providers - ) - - fun getUserUsageSummary(apiKey: String): Map - - fun getSessionUsageSummary(session: Session): Map - fun clear() - - data class UsageKey( - val session: Session, - val apiKey: String?, - val model: OpenAIModel, - ) - - class UsageValues( - val inputTokens: AtomicLong = AtomicLong(), - val outputTokens: AtomicLong = AtomicLong(), - val cost: AtomicDouble = AtomicDouble(), - ) { - fun addAndGet(tokens: ApiModel.Usage) { - inputTokens.addAndGet(tokens.prompt_tokens) - outputTokens.addAndGet(tokens.completion_tokens) - cost.addAndGet(tokens.cost ?: 0.0) - } - - fun toUsage() = ApiModel.Usage( - prompt_tokens = inputTokens.get(), - completion_tokens = outputTokens.get(), - cost = cost.get() - ) - } - - class UsageCounters( - val tokensPerModel: HashMap = HashMap(), - ) -} - - -data class User( - @get:JsonProperty("email") val email: String, - @get:JsonProperty("name") val name: String? = null, - @get:JsonProperty("id") val id: String? = null, - @get:JsonProperty("picture") val picture: String? = null, - @get:JsonIgnore val credential: Any? = null, -) { - override fun toString() = email - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as User - - return email == other.email - } - - override fun hashCode(): Int { - return email.hashCode() - } - -} - -data class Session( - val sessionId: String -) { - init { - StorageInterface.validateSessionId(this) - } - - override fun toString() = sessionId - fun isGlobal(): Boolean = sessionId.startsWith("G-") -} - - -interface CloudPlatformInterface { - val shareBase: String - - fun upload( - path: String, - contentType: String, - bytes: ByteArray - ): String - - fun upload( - path: String, - contentType: String, - request: String - ): String - - fun encrypt(fileBytes: ByteArray, keyId: String): String? - fun decrypt(encryptedData: ByteArray): String -} +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/AwsPlatform.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/AwsPlatform.kt index 947b930d..e728f385 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/AwsPlatform.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/AwsPlatform.kt @@ -1,7 +1,7 @@ package com.simiacryptus.skyenet.core.platform +import com.simiacryptus.skyenet.core.platform.model.CloudPlatformInterface import org.slf4j.LoggerFactory -import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider import software.amazon.awssdk.core.SdkBytes import software.amazon.awssdk.core.sync.RequestBody import software.amazon.awssdk.regions.Region diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/ClientManager.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/ClientManager.kt index af1418d5..0cf52cc9 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/ClientManager.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/ClientManager.kt @@ -9,8 +9,10 @@ import com.simiacryptus.jopenai.models.APIProvider import com.simiacryptus.jopenai.util.ClientUtil import com.simiacryptus.skyenet.core.platform.ApplicationServices.dataStorageFactory import com.simiacryptus.skyenet.core.platform.ApplicationServices.userSettingsManager -import com.simiacryptus.skyenet.core.platform.ApplicationServicesConfig.dataStorageRoot -import com.simiacryptus.skyenet.core.platform.AuthorizationInterface.OperationType +import com.simiacryptus.skyenet.core.platform.model.ApplicationServicesConfig.dataStorageRoot +import com.simiacryptus.skyenet.core.platform.model.AuthorizationInterface.OperationType +import com.simiacryptus.skyenet.core.platform.model.StorageInterface +import com.simiacryptus.skyenet.core.platform.model.User import org.slf4j.LoggerFactory import java.util.concurrent.* @@ -18,7 +20,6 @@ open class ClientManager { private data class SessionKey(val session: Session, val user: User?) - private val chatCache = mutableMapOf() fun getChatClient( session: Session, @@ -126,13 +127,6 @@ open class ClientManager { ) if (!canUseGlobalKey) throw RuntimeException("No API key") return (if (ClientUtil.keyMap.isNotEmpty()) { - /*MonitoredClient( - key = ClientUtil.keyMap.mapKeys { APIProvider.valueOf(it.key) }, - logfile = sessionDir.resolve("openai.log"), - session = session, - user = user, - workPool = getPool(session, user), - )*/ ChatClient( key = ClientUtil.keyMap.mapKeys { APIProvider.valueOf(it.key) }, workPool = getPool(session, user), @@ -156,15 +150,6 @@ open class ClientManager { val userSettings = userSettingsManager.getUserSettings(user) val userApi = if (userSettings.apiKeys.isNotEmpty()) { - /* - MonitoredClient( - key = userSettings.apiKeys, - apiBase = userSettings.apiBase, - logfile = sessionDir.resolve("openai.log"), - session = session, - user = user, - workPool = getPool(session, user), - )*/ OpenAIClient( key = userSettings.apiKeys, apiBase = userSettings.apiBase, @@ -182,13 +167,6 @@ open class ClientManager { ) if (!canUseGlobalKey) throw RuntimeException("No API key") return (if (ClientUtil.keyMap.isNotEmpty()) { - /*MonitoredClient( - key = ClientUtil.keyMap.mapKeys { APIProvider.valueOf(it.key) }, - logfile = sessionDir.resolve("openai.log"), - session = session, - user = user, - workPool = getPool(session, user), - )*/ OpenAIClient( key = ClientUtil.keyMap.mapKeys { APIProvider.valueOf(it.key) }, workPool = getPool(session, user), diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/Session.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/Session.kt new file mode 100644 index 00000000..21641dd2 --- /dev/null +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/Session.kt @@ -0,0 +1,58 @@ +package com.simiacryptus.skyenet.core.platform + + +import java.nio.ByteBuffer +import java.time.LocalDate +import java.util.Base64 +import kotlin.random.Random + +data class Session( + val sessionId: String +) { + init { + validateSessionId() + } + + override fun toString() = sessionId + fun isGlobal(): Boolean = sessionId.startsWith("G-") + + companion object { + fun long64() = Base64.getEncoder().encodeToString(ByteBuffer.allocate(8).putLong(Random.Default.nextLong()).array()) + .toString().replace("=", "").replace("/", ".").replace("+", "-") + + fun validateSessionId(session: Session) { + session.validateSessionId() + } + + fun newGlobalID(): Session { + val yyyyMMdd = LocalDate.now().toString().replace("-", "") + return Session("G-$yyyyMMdd-${id2()}") + } + + fun newUserID(): Session { + val yyyyMMdd = LocalDate.now().toString().replace("-", "") + return Session("U-$yyyyMMdd-${id2()}") + } + + private fun id2() = long64().filter { + when (it) { + in 'a'..'z' -> true + in 'A'..'Z' -> true + in '0'..'9' -> true + else -> false + } + }.take(4) + + fun parseSessionID(sessionID: String): Session { + val session = Session(sessionID) + session.validateSessionId() + return session + } + } + + private fun validateSessionId() { + if (!sessionId.matches("""([GU]-)?\d{8}-[\w+-.]{4}""".toRegex())) { + throw IllegalArgumentException("Invalid session ID: $this") + } + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/AuthenticationManager.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/AuthenticationManager.kt index b770f833..0c2da530 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/AuthenticationManager.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/AuthenticationManager.kt @@ -1,7 +1,7 @@ package com.simiacryptus.skyenet.core.platform.file -import com.simiacryptus.skyenet.core.platform.AuthenticationInterface -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.AuthenticationInterface +import com.simiacryptus.skyenet.core.platform.model.User open class AuthenticationManager : AuthenticationInterface { diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/AuthorizationManager.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/AuthorizationManager.kt index 01db5bd4..e999d810 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/AuthorizationManager.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/AuthorizationManager.kt @@ -1,7 +1,7 @@ package com.simiacryptus.skyenet.core.platform.file -import com.simiacryptus.skyenet.core.platform.AuthorizationInterface -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.AuthorizationInterface +import com.simiacryptus.skyenet.core.platform.model.User import java.util.* open class AuthorizationManager : AuthorizationInterface { diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/DataStorage.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/DataStorage.kt index f97f4a88..b533f7f5 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/DataStorage.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/DataStorage.kt @@ -1,18 +1,15 @@ package com.simiacryptus.skyenet.core.platform.file -import com.simiacryptus.util.JsonUtil +import com.simiacryptus.skyenet.core.platform.ApplicationServices import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.StorageInterface -import com.simiacryptus.skyenet.core.platform.StorageInterface.Companion.validateSessionId -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.StorageInterface +import com.simiacryptus.skyenet.core.platform.model.User +import com.simiacryptus.util.JsonUtil import java.io.File -import java.text.SimpleDateFormat import java.util.* -import kotlin.reflect.jvm.javaType -import kotlin.reflect.typeOf open class DataStorage( - private val dataDir: File + private val dataDir: File, ) : StorageInterface { init { @@ -23,7 +20,7 @@ open class DataStorage( user: User?, session: Session ): LinkedHashMap { - validateSessionId(session) + Session.validateSessionId(session) log.debug("Fetching messages for session: ${session.sessionId}, user: ${user?.email}") val messageDir = getDataDir(user, session).resolve("messages/") @@ -53,7 +50,7 @@ open class DataStorage( user: User?, session: Session ): File { - validateSessionId(session) + Session.validateSessionId(session) log.debug("Getting data directory for session: ${session.sessionId}, user: ${user?.email}") val parts = session.sessionId.split("-") return when (parts.size) { @@ -82,150 +79,14 @@ open class DataStorage( } } - override fun getSessionName( - user: User?, - session: Session - ): String { - validateSessionId(session) - log.debug("Fetching session name for session: ${session.sessionId}, user: ${user?.email}") - val sessionDir = getDataDir(user, session) - val settings = run { - val settingsFile = File(sessionDir, "settings.json") - if (!settingsFile.exists()) null else { - JsonUtil.objectMapper().readValue(settingsFile, Map::class.java) as Map<*, *> - } - } ?: mapOf() - if (settings.containsKey("name")) return settings["name"] as String - val userMessage = - messageFiles(session, user).entries.minByOrNull { it.key.lastModified() }?.value - return if (null != userMessage) { - setJson(sessionDir, "settings.json", settings.plus("name" to userMessage)) - log.debug("Session name for session: ${session.sessionId} is $userMessage") - userMessage - } else { - log.debug("Session ${session.sessionId} has no messages") - session.sessionId - } - } - - override fun getMessageIds( - user: User?, - session: Session - ): List { - validateSessionId(session) - log.debug("Fetching message IDs for session: ${session.sessionId}, user: ${user?.email}") - val sessionDir = getDataDir(user, session) - val settings = run { - val settingsFile = sessionDir.resolve("internal.json") - if (!settingsFile.exists()) null else { - JsonUtil.objectMapper().readValue(settingsFile, Map::class.java) as Map<*, *> - } - } ?: mapOf() - if (settings.containsKey("ids")) return settings["ids"].toString().split(",").toList() - val ids = messageFiles(session, user).entries.sortedBy { it.key.lastModified() } - .map { it.key.nameWithoutExtension }.toList() - setJson( - sessionDir, - "internal.json", - settings.plus("ids" to ids.joinToString(",")) - ) - log.debug("Message IDs for session: ${session.sessionId} are $ids") - return ids - } - - override fun setMessageIds( - user: User?, - session: Session, - ids: List - ) { - validateSessionId(session) - log.debug("Setting message IDs for session: ${session.sessionId}, user: ${user?.email} to $ids") - val sessionDir = getDataDir(user, session) - val settings = run { - val settingsFile = sessionDir.resolve("internal.json") - if (!settingsFile.exists()) null else { - JsonUtil.objectMapper().readValue(settingsFile, Map::class.java) as Map<*, *> - } - } ?: mapOf() - setJson( - sessionDir, - "internal.json", - settings.plus("ids" to ids.joinToString(",")) - ) - } - - override fun getSessionTime( - user: User?, - session: Session - ): Date? { - validateSessionId(session) - log.debug("Fetching session time for session: ${session.sessionId}, user: ${user?.email}") - val sessionDir = getDataDir(user, session) - val settingsFile = sessionDir.resolve("internal.json") - val settings = run { - if (!settingsFile.exists()) null else { - JsonUtil.objectMapper().readValue(settingsFile, Map::class.java) as Map<*, *> - } - } ?: mapOf() - val dateFormat = SimpleDateFormat.getDateTimeInstance() - if (settings.containsKey("time")) return dateFormat.parse(settings["time"] as String) - val messageFiles = messageFiles(session, user) - val file = messageFiles.entries.minByOrNull { it.key.lastModified() }?.key - return if (null != file) { - val date = Date(file.lastModified()) - setJson( - sessionDir, - "internal.json", - settings.plus("time" to dateFormat.format(date)) - ) - log.debug("Session time for session: ${session.sessionId} is $date") - date - } else { - log.debug("Session ${session.sessionId} has no messages") - null - } - } - - private fun messageFiles( - session: Session, - user: User?, - ): Map { - - return getDataDir(user, session).resolve("messages") - .apply { mkdirs() }.listFiles() - ?.filter { file -> file.isFile } - ?.map { messageFile -> - val fileText = messageFile.readText() - val split = fileText.split("

") - if (split.size < 2) { - log.debug("Session ${session.sessionId} has no messages in file ${messageFile.name}") - messageFile to "" - } else { - val stringList = split[1].split("

") - if (stringList.isEmpty()) { - log.debug("Session ${session.sessionId} has no messages in file ${messageFile.name}") - messageFile to "" - } else { - messageFile to stringList.first() - } - } - }?.filter { it.second.isNotEmpty() }?.toList()?.toMap() ?: mapOf() - } - override fun listSessions( user: User?, path: String ): List { log.debug("Listing sessions for user: ${user?.email}") val globalSessions = listSessions(dataDir.resolve("global"), path) - val userSessions = if (user == null) listOf() else listSessions( - dataDir.resolve("user-sessions").resolve( - if (user.email != null) { - user.email - } else { - throw IllegalArgumentException("User required for private session") - } - ).apply { mkdirs() }, path + val userSessions = if (user == null) listOf() else ApplicationServices.metadataStorageFactory(dataDir).listSessions( + path ) log.debug("Found ${globalSessions.size} global sessions and ${userSessions.size} user sessions for user: ${user?.email}") return ((globalSessions.map { @@ -263,7 +124,7 @@ open class DataStorage( messageId: String, value: String ) { - validateSessionId(session) + Session.validateSessionId(session) log.debug("Updating message for session: ${session.sessionId}, messageId: $messageId, user: ${user?.email}") val file = getDataDir(user, session).resolve("messages/$messageId.json") @@ -286,21 +147,6 @@ open class DataStorage( } } - override fun listSessions(dir: File, path: String): List { - log.debug("Listing sessions in directory: ${dir.absolutePath}") - val files = dir.listFiles() - ?.flatMap { it.listFiles()?.toList() ?: listOf() } - ?.filter { sessionDir -> - val resolve = sessionDir.resolve("info.json") - if (!resolve.exists()) return@filter false - val infoJson = resolve.readText() - val infoData = JsonUtil.fromJson>(infoJson, typeOf>().javaType) - path == infoData["path"] - }?.sortedBy { it.lastModified() } ?: listOf() - log.debug("Found ${files.size} sessions in directory: ${dir.absolutePath}") - return files.map { it.parentFile.name + "-" + it.name } - } - override fun userRoot(user: User?) = dataDir.resolve("users").resolve( if (user?.email != null) { user.email @@ -310,12 +156,36 @@ open class DataStorage( ).apply { mkdirs() } override fun deleteSession(user: User?, session: Session) { - validateSessionId(session) + Session.validateSessionId(session) log.debug("Deleting session: ${session.sessionId}, user: ${user?.email}") val sessionDir = getDataDir(user, session) + ApplicationServices.metadataStorageFactory(dataDir).deleteSession(user, session) sessionDir.deleteRecursively() } + override fun listSessions(dir: File, path: String): List = ApplicationServices.metadataStorageFactory(dataDir).listSessions(path) + + override fun getSessionName( + user: User?, + session: Session + ): String = ApplicationServices.metadataStorageFactory(dataDir).getSessionName(user, session) + + override fun getMessageIds( + user: User?, + session: Session + ): List = ApplicationServices.metadataStorageFactory(dataDir).getMessageIds(user, session) + + override fun setMessageIds( + user: User?, + session: Session, + ids: List + ) = ApplicationServices.metadataStorageFactory(dataDir).setMessageIds(user, session, ids) + + override fun getSessionTime( + user: User?, + session: Session + ): Date? = ApplicationServices.metadataStorageFactory(dataDir).getSessionTime(user, session) + companion object { val log = org.slf4j.LoggerFactory.getLogger(DataStorage::class.java) diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/MetadataStorage.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/MetadataStorage.kt new file mode 100644 index 00000000..9e9a0594 --- /dev/null +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/MetadataStorage.kt @@ -0,0 +1,140 @@ +package com.simiacryptus.skyenet.core.platform.file + +import com.simiacryptus.skyenet.core.platform.ApplicationServices +import com.simiacryptus.skyenet.core.platform.Session +import com.simiacryptus.skyenet.core.platform.model.MetadataStorageInterface +import com.simiacryptus.skyenet.core.platform.model.User +import com.simiacryptus.util.JsonUtil +import java.io.File +import java.text.SimpleDateFormat +import java.util.* +import kotlin.reflect.jvm.javaType +import kotlin.reflect.typeOf + + +class MetadataStorage(private val dataDir: File) : MetadataStorageInterface { + private val log = org.slf4j.LoggerFactory.getLogger(MetadataStorage::class.java) + + override fun getSessionName(user: User?, session: Session): String { + log.debug("Fetching session name for session: ${session.sessionId}, user: ${user?.email}") + val sessionDir: File = ApplicationServices.dataStorageFactory.invoke(dataDir).getDataDir(user, session) + val settings = getSettings(sessionDir, "settings.json") + if (settings.containsKey("name")) return settings["name"] as String + val userMessage = messageFiles(session, sessionDir).entries.minByOrNull { it.key.lastModified() }?.value + return if (null != userMessage) { + setJson(sessionDir, "settings.json", settings.plus("name" to userMessage)) + log.debug("Session name for session: ${session.sessionId} is $userMessage") + userMessage + } else { + log.debug("Session ${session.sessionId} has no messages") + session.sessionId + } + } + + override fun setSessionName(user: User?, session: Session, name: String) { + log.debug("Setting session name for session: ${session.sessionId}, user: ${user?.email} to $name") + val sessionDir: File = ApplicationServices.dataStorageFactory.invoke(dataDir).getDataDir(user, session) + val settings = getSettings(sessionDir, "settings.json") + setJson(sessionDir, "settings.json", settings.plus("name" to name)) + } + + + override fun getMessageIds(user: User?, session: Session): List { + log.debug("Fetching message IDs for session: ${session.sessionId}, user: ${user?.email}") + val sessionDir: File = ApplicationServices.dataStorageFactory.invoke(dataDir).getDataDir(user, session) + val settings = getSettings(sessionDir, "internal.json") + if (settings.containsKey("ids")) return settings["ids"].toString().split(",").toList() + val ids = messageFiles(session, sessionDir).entries.sortedBy { it.key.lastModified() } + .map { it.key.nameWithoutExtension }.toList() + setJson(sessionDir, "internal.json", settings.plus("ids" to ids.joinToString(","))) + log.debug("Message IDs for session: ${session.sessionId} are $ids") + return ids + } + + override fun setMessageIds(user: User?, session: Session, ids: List) { + log.debug("Setting message IDs for session: ${session.sessionId}, user: ${user?.email} to $ids") + val sessionDir: File = ApplicationServices.dataStorageFactory.invoke(dataDir).getDataDir(user, session) + val settings = getSettings(sessionDir, "internal.json") + setJson(sessionDir, "internal.json", settings.plus("ids" to ids.joinToString(","))) + } + + override fun getSessionTime(user: User?, session: Session): Date? { + log.debug("Fetching session time for session: ${session.sessionId}, user: ${user?.email}") + val sessionDir: File = ApplicationServices.dataStorageFactory.invoke(dataDir).getDataDir(user, session) + val settings = getSettings(sessionDir, "internal.json") + val dateFormat = SimpleDateFormat.getDateTimeInstance() + if (settings.containsKey("time")) return dateFormat.parse(settings["time"] as String) + val messageFiles = messageFiles(session, sessionDir) + val file = messageFiles.entries.minByOrNull { it.key.lastModified() }?.key + return if (null != file) { + val date = Date(file.lastModified()) + setJson(sessionDir, "internal.json", settings.plus("time" to dateFormat.format(date))) + log.debug("Session time for session: ${session.sessionId} is $date") + date + } else { + log.debug("Session ${session.sessionId} has no messages") + null + } + } + + override fun setSessionTime(user: User?, session: Session, time: Date) { + log.debug("Setting session time for session: ${session.sessionId}, user: ${user?.email} to $time") + val sessionDir: File = ApplicationServices.dataStorageFactory.invoke(dataDir).getDataDir(user, session) + val settings = getSettings(sessionDir, "internal.json") + val dateFormat = SimpleDateFormat.getDateTimeInstance() + setJson(sessionDir, "internal.json", settings.plus("time" to dateFormat.format(time))) + } + + + override fun listSessions(path: String): List { + log.debug("Listing sessions in dataDir.absolutePath}") + val files = dataDir.listFiles() + ?.flatMap { it.listFiles()?.toList() ?: listOf() } + ?.filter { sessionDir -> + val resolve = sessionDir.resolve("info.json") + if (!resolve.exists()) return@filter false + val infoJson = resolve.readText() + val infoData = JsonUtil.fromJson>(infoJson, typeOf>().javaType) + path == infoData["path"] + }?.sortedBy { it.lastModified() } ?: listOf() + log.debug("Found ${files.size} sessions in directory: ${dataDir.absolutePath}") + return files.map { it.parentFile.name + "-" + it.name } + } + + private fun getSettings(sessionDir: File, filename: String): Map<*, *> { + val settingsFile = sessionDir.resolve(filename) + return if (!settingsFile.exists()) mapOf() + else JsonUtil.objectMapper().readValue(settingsFile, Map::class.java) as Map<*, *> + } + + private fun setJson(sessionDir: File, filename: String, settings: T): T { + log.debug("Setting JSON for session directory: ${sessionDir.absolutePath}, filename: $filename") + val settingsFile = sessionDir.resolve(filename).apply { parentFile.mkdirs() } + JsonUtil.objectMapper().writeValue(settingsFile, settings) + return settings + } + + private fun messageFiles(session: Session, sessionDir: File): Map { + return sessionDir.resolve("messages") + .apply { mkdirs() }.listFiles() + ?.filter { file -> file.isFile } + ?.map { messageFile -> + val fileText = messageFile.readText() + val split = fileText.split("

") + if (split.size < 2) { + log.debug("Session ${session.sessionId} has no messages in file ${messageFile.name}") + messageFile to "" + } else { + val stringList = split[1].split("

") + if (stringList.isEmpty()) { + log.debug("Session ${session.sessionId} has no messages in file ${messageFile.name}") + messageFile to "" + } else { + messageFile to stringList.first() + } + } + }?.filter { it.second.isNotEmpty() }?.toList()?.toMap() ?: mapOf() + } + + override fun deleteSession(user: User?, session: Session) {} +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/UsageManager.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/UsageManager.kt index ebd0f306..bc649477 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/UsageManager.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/UsageManager.kt @@ -1,11 +1,11 @@ package com.simiacryptus.skyenet.core.platform.file import com.simiacryptus.jopenai.models.* -import com.simiacryptus.util.JsonUtil import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.UsageInterface -import com.simiacryptus.skyenet.core.platform.UsageInterface.* -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.UsageInterface +import com.simiacryptus.skyenet.core.platform.model.UsageInterface.* +import com.simiacryptus.skyenet.core.platform.model.User +import com.simiacryptus.util.JsonUtil import java.io.File import java.io.FileWriter import java.util.concurrent.ConcurrentHashMap @@ -38,7 +38,7 @@ open class UsageManager(val root: File) : UsageInterface { val (sessionId, user, model, value, direction) = line.split(",") try { val modelEnum = listOf( - ChatModels.values(), + ChatModel.values(), CompletionModels.values(), EditModels.values(), EmbeddingModels.values() diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/UserSettingsManager.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/UserSettingsManager.kt index de50a35f..5dd0df58 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/UserSettingsManager.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/file/UserSettingsManager.kt @@ -1,11 +1,10 @@ package com.simiacryptus.skyenet.core.platform.file +import com.simiacryptus.skyenet.core.platform.model.ApplicationServicesConfig.dataStorageRoot +import com.simiacryptus.skyenet.core.platform.model.User +import com.simiacryptus.skyenet.core.platform.model.UserSettingsInterface +import com.simiacryptus.skyenet.core.platform.model.UserSettingsInterface.UserSettings import com.simiacryptus.util.JsonUtil -import com.simiacryptus.skyenet.core.platform.ApplicationServices -import com.simiacryptus.skyenet.core.platform.ApplicationServicesConfig.dataStorageRoot -import com.simiacryptus.skyenet.core.platform.User -import com.simiacryptus.skyenet.core.platform.UserSettingsInterface -import com.simiacryptus.skyenet.core.platform.UserSettingsInterface.UserSettings import java.io.File open class UserSettingsManager : UserSettingsInterface { diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/hsql/HSQLMetadataStorage.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/hsql/HSQLMetadataStorage.kt new file mode 100644 index 00000000..8940c26b --- /dev/null +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/hsql/HSQLMetadataStorage.kt @@ -0,0 +1,175 @@ +package com.simiacryptus.skyenet.core.platform.hsql + +import com.simiacryptus.skyenet.core.platform.Session +import com.simiacryptus.skyenet.core.platform.model.MetadataStorageInterface +import com.simiacryptus.skyenet.core.platform.model.User +import org.slf4j.LoggerFactory +import java.io.File +import java.sql.Connection +import java.sql.DriverManager +import java.sql.Timestamp +import java.util.* + +class HSQLMetadataStorage(private val dbFile: File) : MetadataStorageInterface { + private val log = LoggerFactory.getLogger(HSQLMetadataStorage::class.java) + + private val connection: Connection by lazy { + log.info("Initializing HSQLMetadataStorage with database file: ${dbFile.absolutePath}") + Class.forName("org.hsqldb.jdbc.JDBCDriver") + val connection = DriverManager.getConnection("jdbc:hsqldb:file:${dbFile.absolutePath}/metadata;shutdown=true", "SA", "") + log.debug("Database connection established: $connection") + createSchema(connection) + connection + } + + private fun createSchema(connection: Connection) { + log.info("Creating database schema if not exists") + connection.createStatement().executeUpdate( + """ + CREATE TABLE IF NOT EXISTS metadata ( + session_id VARCHAR(255), + user_email VARCHAR(255), + key VARCHAR(255), + value LONGVARCHAR, + timestamp TIMESTAMP, + PRIMARY KEY (session_id, user_email, key) + ) + """ + ) + } + + override fun getSessionName(user: User?, session: Session): String { + log.debug("Fetching session name for session: ${session.sessionId}, user: ${user?.email}") + val statement = connection.prepareStatement( + "SELECT value FROM metadata WHERE session_id = ? AND user_email = ? AND key = 'name'" + ) + statement.setString(1, session.sessionId) + statement.setString(2, user?.email ?: "") + val resultSet = statement.executeQuery() + return if (resultSet.next()) { + resultSet.getString("value") + } else { + log.debug("Session ${session.sessionId} has no name") + session.sessionId + } + } + + override fun setSessionName(user: User?, session: Session, name: String) { + log.debug("Setting session name for session: ${session.sessionId}, user: ${user?.email} to $name") + val statement = connection.prepareStatement( + """ + MERGE INTO metadata USING (VALUES(?, ?, ?, ?, ?)) AS vals(session_id, user_email, key, value, timestamp) + ON metadata.session_id = vals.session_id AND metadata.user_email = vals.user_email AND metadata.key = vals.key + WHEN MATCHED THEN UPDATE SET metadata.value = vals.value, metadata.timestamp = vals.timestamp + WHEN NOT MATCHED THEN INSERT VALUES vals.session_id, vals.user_email, vals.key, vals.value, vals.timestamp + """ + ) + statement.setString(1, session.sessionId) + statement.setString(2, user?.email ?: "") + statement.setString(3, "name") + statement.setString(4, name) + statement.setTimestamp(5, Timestamp(System.currentTimeMillis())) + statement.executeUpdate() + } + + override fun getMessageIds(user: User?, session: Session): List { + log.debug("Fetching message IDs for session: ${session.sessionId}, user: ${user?.email}") + val statement = connection.prepareStatement( + "SELECT value FROM metadata WHERE session_id = ? AND user_email = ? AND key = 'message_ids'" + ) + statement.setString(1, session.sessionId) + statement.setString(2, user?.email ?: "") + val resultSet = statement.executeQuery() + return if (resultSet.next()) { + resultSet.getString("value").split(",") + } else { + emptyList() + } + } + + override fun setMessageIds(user: User?, session: Session, ids: List) { + log.debug("Setting message IDs for session: ${session.sessionId}, user: ${user?.email} to $ids") + val statement = connection.prepareStatement( + """ + MERGE INTO metadata USING (VALUES(?, ?, ?, ?, ?)) AS vals(session_id, user_email, key, value, timestamp) + ON metadata.session_id = vals.session_id AND metadata.user_email = vals.user_email AND metadata.key = vals.key + WHEN MATCHED THEN UPDATE SET metadata.value = vals.value, metadata.timestamp = vals.timestamp + WHEN NOT MATCHED THEN INSERT VALUES vals.session_id, vals.user_email, vals.key, vals.value, vals.timestamp + """ + ) + statement.setString(1, session.sessionId) + statement.setString(2, user?.email ?: "") + statement.setString(3, "message_ids") + statement.setString(4, ids.joinToString(",")) + statement.setTimestamp(5, Timestamp(System.currentTimeMillis())) + statement.executeUpdate() + } + + override fun getSessionTime(user: User?, session: Session): Date? { + log.debug("Fetching session time for session: ${session.sessionId}, user: ${user?.email}") + val statement = connection.prepareStatement( + "SELECT value, timestamp FROM metadata WHERE session_id = ? AND user_email = ? AND key = 'session_time'" + ) + statement.setString(1, session.sessionId) + statement.setString(2, user?.email ?: "") + val resultSet = statement.executeQuery() + return if (resultSet.next()) { + try { + Date(resultSet.getString("value").toLong()) + } catch (e: NumberFormatException) { + log.warn("Invalid session time value, falling back to timestamp") + resultSet.getTimestamp("timestamp") + } + } else { + log.debug("No session time found, returning current time") + Date() + } + } + + override fun setSessionTime(user: User?, session: Session, time: Date) { + log.debug("Setting session time for session: ${session.sessionId}, user: ${user?.email} to $time") + val statement = connection.prepareStatement( + """ + MERGE INTO metadata USING (VALUES(?, ?, ?, ?, ?)) AS vals(session_id, user_email, key, value, timestamp) + ON metadata.session_id = vals.session_id AND metadata.user_email = vals.user_email AND metadata.key = vals.key + WHEN MATCHED THEN UPDATE SET metadata.value = vals.value, metadata.timestamp = vals.timestamp + WHEN NOT MATCHED THEN INSERT VALUES vals.session_id, vals.user_email, vals.key, vals.value, vals.timestamp + """ + ) + statement.setString(1, session.sessionId) + statement.setString(2, user?.email ?: "") + statement.setString(3, "session_time") + statement.setString(4, time.time.toString()) + statement.setTimestamp(5, Timestamp(time.time)) + statement.executeUpdate() + } + + override fun listSessions(path: String): List { + log.debug("Listing sessions for path: $path") + val statement = connection.prepareStatement( + "SELECT DISTINCT session_id FROM metadata WHERE value = ? AND key = 'path'" + ) + statement.setString(1, path) + val resultSet = statement.executeQuery() + val sessions = mutableListOf() + while (resultSet.next()) { + sessions.add(resultSet.getString("session_id")) + } + log.debug("Found ${sessions.size} sessions for path: $path") + return sessions + } + + override fun deleteSession(user: User?, session: Session) { + log.debug("Deleting session: ${session.sessionId}, user: ${user?.email}") + val statement = connection.prepareStatement( + "DELETE FROM metadata WHERE session_id = ? AND user_email = ?" + ) + statement.setString(1, session.sessionId) + statement.setString(2, user?.email ?: "") + statement.executeUpdate() + } + + companion object { + private val log = LoggerFactory.getLogger(HSQLMetadataStorage::class.java) + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/HSQLUsageManager.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/hsql/HSQLUsageManager.kt similarity index 73% rename from core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/HSQLUsageManager.kt rename to core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/hsql/HSQLUsageManager.kt index 3ec0ac13..82a744ac 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/HSQLUsageManager.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/hsql/HSQLUsageManager.kt @@ -1,10 +1,11 @@ -package com.simiacryptus.skyenet.core.platform +package com.simiacryptus.skyenet.core.platform.hsql import com.google.common.util.concurrent.AtomicDouble import com.simiacryptus.jopenai.models.ApiModel -import com.simiacryptus.jopenai.models.ChatModels +import com.simiacryptus.jopenai.models.ChatModel import com.simiacryptus.jopenai.models.OpenAIModel -import org.slf4j.Logger +import com.simiacryptus.skyenet.core.platform.Session +import com.simiacryptus.skyenet.core.platform.model.UsageInterface import org.slf4j.LoggerFactory import java.io.File import java.sql.Connection @@ -16,17 +17,16 @@ import java.util.concurrent.atomic.AtomicLong class HSQLUsageManager(private val dbFile: File) : UsageInterface { private val connection: Connection by lazy { - logger.info("Initializing HSQLUsageManager with database file: ${dbFile.absolutePath}") + log.info("Initializing HSQLUsageManager with database file: ${dbFile.absolutePath}") Class.forName("org.hsqldb.jdbc.JDBCDriver") - val connection = DriverManager.getConnection("jdbc:hsqldb:file:${dbFile.absolutePath};shutdown=true", "SA", "") - logger.debug("Database connection established: $connection") + val connection = DriverManager.getConnection("jdbc:hsqldb:file:${dbFile.absolutePath}/usage;shutdown=true", "SA", "") + log.debug("Database connection established: $connection") createSchema(connection) connection } - private val logger: Logger = LoggerFactory.getLogger(HSQLUsageManager::class.java) private fun createSchema(connection: Connection) { - logger.info("Creating database schema if not exists") + log.info("Creating database schema if not exists") connection.createStatement().executeUpdate( """ CREATE TABLE IF NOT EXISTS usage ( @@ -45,31 +45,31 @@ class HSQLUsageManager(private val dbFile: File) : UsageInterface { private fun updateSchema() { - logger.info("Updating database schema if needed") + log.info("Updating database schema if needed") // Add schema update logic here if needed } private fun deleteSchema() { - logger.info("Deleting database schema if exists") + log.info("Deleting database schema if exists") connection.createStatement().executeUpdate("DROP TABLE IF EXISTS usage") - logger.debug("Schema deleted") + log.debug("Schema deleted") } override fun incrementUsage(session: Session, apiKey: String?, model: OpenAIModel, tokens: ApiModel.Usage) { try { - logger.debug("Incrementing usage for session: ${session.sessionId}, apiKey: $apiKey, model: ${model.modelName}") + log.debug("Incrementing usage for session: ${session.sessionId}, apiKey: $apiKey, model: ${model.modelName}") val usageKey = UsageInterface.UsageKey(session, apiKey, model) val usageValues = UsageInterface.UsageValues() //getUsageValues(usageKey) usageValues.addAndGet(tokens) saveUsageValues(usageKey, usageValues) - logger.debug("Usage incremented for session: ${session.sessionId}, apiKey: $apiKey, model: ${model.modelName}") + log.debug("Usage incremented for session: ${session.sessionId}, apiKey: $apiKey, model: ${model.modelName}") } catch (e: Exception) { - logger.error("Error incrementing usage", e) + log.error("Error incrementing usage", e) } } override fun getUserUsageSummary(apiKey: String): Map { - logger.debug("Executing SQL query to get user usage summary for apiKey: $apiKey") + log.debug("Executing SQL query to get user usage summary for apiKey: $apiKey") val statement = connection.prepareStatement( """ SELECT model, SUM(prompt_tokens), SUM(completion_tokens), SUM(cost) @@ -84,7 +84,7 @@ class HSQLUsageManager(private val dbFile: File) : UsageInterface { } override fun getSessionUsageSummary(session: Session): Map { - logger.info("Getting session usage summary for session: ${session.sessionId}") + log.info("Getting session usage summary for session: ${session.sessionId}") val statement = connection.prepareStatement( """ SELECT model, SUM(prompt_tokens), SUM(completion_tokens), SUM(cost) @@ -99,12 +99,12 @@ class HSQLUsageManager(private val dbFile: File) : UsageInterface { } override fun clear() { - logger.debug("Executing SQL statement to clear all usage data") + log.debug("Executing SQL statement to clear all usage data") connection.createStatement().executeUpdate("DELETE FROM usage") } private fun getUsageValues(usageKey: UsageInterface.UsageKey): UsageInterface.UsageValues { - logger.debug("Getting usage values for session: ${usageKey.session.sessionId}, apiKey: ${usageKey.apiKey}, model: ${usageKey.model.modelName}") + log.debug("Getting usage values for session: ${usageKey.session.sessionId}, apiKey: ${usageKey.apiKey}, model: ${usageKey.model.modelName}") val statement = connection.prepareStatement( """ SELECT COALESCE(SUM(prompt_tokens), 0), COALESCE(SUM(completion_tokens), 0), COALESCE(SUM(cost), 0) @@ -125,7 +125,7 @@ class HSQLUsageManager(private val dbFile: File) : UsageInterface { } private fun saveUsageValues(usageKey: UsageInterface.UsageKey, usageValues: UsageInterface.UsageValues) { - logger.debug("Saving usage values for session: ${usageKey.session.sessionId}, apiKey: ${usageKey.apiKey}, model: ${usageKey.model.modelName}") + log.debug("Saving usage values for session: ${usageKey.session.sessionId}, apiKey: ${usageKey.apiKey}, model: ${usageKey.model.modelName}") val statement = connection.prepareStatement( """ INSERT INTO usage (session_id, api_key, model, prompt_tokens, completion_tokens, cost, datetime) @@ -139,13 +139,13 @@ class HSQLUsageManager(private val dbFile: File) : UsageInterface { statement.setLong(5, usageValues.outputTokens.get()) statement.setDouble(6, usageValues.cost.get()) statement.setTimestamp(7, Timestamp(System.currentTimeMillis())) - logger.debug("Executing statement: $statement") - logger.debug("With parameters: ${usageKey.session.sessionId}, ${usageKey.apiKey}, ${usageKey.model.modelName}, ${usageValues.inputTokens.get()}, ${usageValues.outputTokens.get()}, ${usageValues.cost.get()}") + log.debug("Executing statement: $statement") + log.debug("With parameters: ${usageKey.session.sessionId}, ${usageKey.apiKey}, ${usageKey.model.modelName}, ${usageValues.inputTokens.get()}, ${usageValues.outputTokens.get()}, ${usageValues.cost.get()}") statement.executeUpdate() } private fun generateUsageSummary(resultSet: ResultSet): Map { - logger.debug("Generating usage summary from result set") + log.debug("Generating usage summary from result set") val summary = mutableMapOf() while (resultSet.next()) { val string = resultSet.getString(1) @@ -161,11 +161,11 @@ class HSQLUsageManager(private val dbFile: File) : UsageInterface { } private fun openAIModel(string: String): OpenAIModel? { - logger.debug("Retrieving OpenAI model for string: $string") - val model = ChatModels.values().filter { + log.debug("Retrieving OpenAI model for string: $string") + val model = ChatModel.values().filter { it.key == string || it.value.modelName == string || it.value.name == string }.toList().firstOrNull()?.second ?: return null - logger.debug("OpenAI model retrieved: $model") + log.debug("OpenAI model retrieved: $model") return model } diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/ApplicationServicesConfig.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/ApplicationServicesConfig.kt new file mode 100644 index 00000000..0febf3cf --- /dev/null +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/ApplicationServicesConfig.kt @@ -0,0 +1,17 @@ +package com.simiacryptus.skyenet.core.platform.model + +import java.io.File + +object ApplicationServicesConfig { + + var isLocked: Boolean = false + set(value) { + require(!isLocked) { "ApplicationServices is locked" } + field = value + } + var dataStorageRoot: File = File(System.getProperty("user.home"), ".skyenet") + set(value) { + require(!isLocked) { "ApplicationServices is locked" } + field = value + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/AuthenticationInterface.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/AuthenticationInterface.kt new file mode 100644 index 00000000..0f227dc3 --- /dev/null +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/AuthenticationInterface.kt @@ -0,0 +1,13 @@ +package com.simiacryptus.skyenet.core.platform.model + +interface AuthenticationInterface { + fun getUser(accessToken: String?): User? + + fun putUser(accessToken: String, user: User): User + fun logout(accessToken: String, user: User) + //fun removeToken(accessToken: String) + + companion object { + const val AUTH_COOKIE = "sessionId" + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/AuthorizationInterface.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/AuthorizationInterface.kt new file mode 100644 index 00000000..2c28a419 --- /dev/null +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/AuthorizationInterface.kt @@ -0,0 +1,20 @@ +package com.simiacryptus.skyenet.core.platform.model + +interface AuthorizationInterface { + enum class OperationType { + Read, + Write, + Public, + Share, + Execute, + Delete, + Admin, + GlobalKey, + } + + fun isAuthorized( + applicationClass: Class<*>?, + user: User?, + operationType: OperationType, + ): Boolean +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/CloudPlatformInterface.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/CloudPlatformInterface.kt new file mode 100644 index 00000000..2d4f05ef --- /dev/null +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/CloudPlatformInterface.kt @@ -0,0 +1,20 @@ +package com.simiacryptus.skyenet.core.platform.model + +interface CloudPlatformInterface { + val shareBase: String + + fun upload( + path: String, + contentType: String, + bytes: ByteArray + ): String + + fun upload( + path: String, + contentType: String, + request: String + ): String + + fun encrypt(fileBytes: ByteArray, keyId: String): String? + fun decrypt(encryptedData: ByteArray): String +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/MetadataStorageInterface.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/MetadataStorageInterface.kt new file mode 100644 index 00000000..a76d02ce --- /dev/null +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/MetadataStorageInterface.kt @@ -0,0 +1,15 @@ +package com.simiacryptus.skyenet.core.platform.model + +import com.simiacryptus.skyenet.core.platform.Session +import java.util.Date + +interface MetadataStorageInterface { + fun getSessionName(user: User?, session: Session): String + fun setSessionName(user: User?, session: Session, name: String) + fun getMessageIds(user: User?, session: Session): List + fun setMessageIds(user: User?, session: Session, ids: List) + fun getSessionTime(user: User?, session: Session): Date? + fun setSessionTime(user: User?, session: Session, time: Date) + fun listSessions(path: String): List + fun deleteSession(user: User?, session: Session) +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/StorageInterface.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/StorageInterface.kt new file mode 100644 index 00000000..0bf58723 --- /dev/null +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/StorageInterface.kt @@ -0,0 +1,97 @@ +package com.simiacryptus.skyenet.core.platform.model + +import com.simiacryptus.skyenet.core.platform.Session +import java.io.File +import java.util.Date +import java.util.LinkedHashMap + +interface StorageInterface { + + fun getMessages( + user: User?, + session: Session + ): LinkedHashMap + + fun getSessionDir( + user: User?, + session: Session + ): File + + fun getDataDir( + user: User?, + session: Session + ): File + + @Deprecated("Use metadataStorage instead") + fun getSessionName( + user: User?, + session: Session + ): String + + @Deprecated("Use metadataStorage instead") + fun getSessionTime( + user: User?, + session: Session + ): Date? + + fun listSessions( + user: User?, + path: String, + ): List + + fun setJson( + user: User?, + session: Session, + filename: String, + settings: T + ): T + + fun updateMessage( + user: User?, + session: Session, + messageId: String, + value: String + ) + + @Deprecated("Use metadataStorage instead") + fun listSessions(dir: File, path: String): List + fun userRoot(user: User?): File + fun deleteSession(user: User?, session: Session) + + @Deprecated("Use metadataStorage instead") + fun getMessageIds( + user: User?, + session: Session + ): List + + @Deprecated("Use metadataStorage instead") + fun setMessageIds( + user: User?, + session: Session, + ids: List + ) + + companion object { + @Deprecated("Use Session.long64() instead", ReplaceWith("Session.long64()")) + inline fun long64() = Session.long64() + + @Deprecated("Use Session.validateSessionId(session) instead", ReplaceWith("Session.validateSessionId(session)")) + inline fun validateSessionId(session: Session) = Session.validateSessionId(session) + + @Deprecated("Use Session.newGlobalID() instead", ReplaceWith("Session.newGlobalID()")) + inline fun newGlobalID(): Session = Session.newGlobalID() + + @Deprecated("Use Session.newUserID() instead", ReplaceWith("Session.newUserID()")) + inline fun newUserID(): Session = Session.newUserID() + + + @Deprecated("Use Session.parseSessionID(sessionID) instead", ReplaceWith("Session.parseSessionID(sessionID)")) + inline fun parseSessionID(sessionID: String): Session = Session.parseSessionID(sessionID) + + @Deprecated("Use Session.id2() instead") + private inline fun id2() = Session.long64().filter { + it in 'a'..'z' || it in 'A'..'Z' || it in '0'..'9' + }.take(4) + + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/UsageInterface.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/UsageInterface.kt new file mode 100644 index 00000000..dafae9bc --- /dev/null +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/UsageInterface.kt @@ -0,0 +1,65 @@ +package com.simiacryptus.skyenet.core.platform.model + +import com.google.common.util.concurrent.AtomicDouble +import com.simiacryptus.jopenai.models.APIProvider +import com.simiacryptus.jopenai.models.ApiModel +import com.simiacryptus.jopenai.models.ChatModel +import com.simiacryptus.jopenai.models.OpenAIModel +import com.simiacryptus.skyenet.core.platform.ApplicationServices +import com.simiacryptus.skyenet.core.platform.Session +import java.util.concurrent.atomic.AtomicLong + +interface UsageInterface { + fun incrementUsage(session: Session, user: User?, model: OpenAIModel, tokens: ApiModel.Usage) = incrementUsage( + session, when (user) { + null -> null + else -> { + val userSettings = ApplicationServices.userSettingsManager.getUserSettings(user) + userSettings.apiKeys[if (model is ChatModel) { + model.provider + } else { + APIProvider.Companion.OpenAI + }] + } + }, model, tokens + ) + + fun incrementUsage(session: Session, apiKey: String?, model: OpenAIModel, tokens: ApiModel.Usage) + + fun getUserUsageSummary(user: User): Map = getUserUsageSummary( + ApplicationServices.userSettingsManager.getUserSettings(user).apiKeys[APIProvider.Companion.OpenAI]!! // TODO: Support other providers + ) + + fun getUserUsageSummary(apiKey: String): Map + + fun getSessionUsageSummary(session: Session): Map + fun clear() + + data class UsageKey( + val session: Session, + val apiKey: String?, + val model: OpenAIModel, + ) + + class UsageValues( + val inputTokens: AtomicLong = AtomicLong(), + val outputTokens: AtomicLong = AtomicLong(), + val cost: AtomicDouble = AtomicDouble(), + ) { + fun addAndGet(tokens: ApiModel.Usage) { + inputTokens.addAndGet(tokens.prompt_tokens) + outputTokens.addAndGet(tokens.completion_tokens) + cost.addAndGet(tokens.cost ?: 0.0) + } + + fun toUsage() = ApiModel.Usage( + prompt_tokens = inputTokens.get(), + completion_tokens = outputTokens.get(), + cost = cost.get() + ) + } + + class UsageCounters( + val tokensPerModel: java.util.HashMap = HashMap(), + ) +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/User.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/User.kt new file mode 100644 index 00000000..f0ba412a --- /dev/null +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/User.kt @@ -0,0 +1,28 @@ +package com.simiacryptus.skyenet.core.platform.model + +import com.fasterxml.jackson.annotation.JsonIgnore +import com.fasterxml.jackson.annotation.JsonProperty + +data class User( + @get:JsonProperty("email") val email: String, + @get:JsonProperty("name") val name: String? = null, + @get:JsonProperty("id") val id: String? = null, + @get:JsonProperty("picture") val picture: String? = null, + @get:JsonIgnore val credential: Any? = null, +) { + override fun toString() = email + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as User + + return email == other.email + } + + override fun hashCode(): Int { + return email.hashCode() + } + +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/UserSettingsInterface.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/UserSettingsInterface.kt new file mode 100644 index 00000000..f49d886c --- /dev/null +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/model/UserSettingsInterface.kt @@ -0,0 +1,14 @@ +package com.simiacryptus.skyenet.core.platform.model + +import com.simiacryptus.jopenai.models.APIProvider + +interface UserSettingsInterface { + data class UserSettings( + val apiKeys: Map = APIProvider.Companion.values().associateWith { "" }, + val apiBase: Map = APIProvider.Companion.values().associateWith { it.base ?: "" }, + ) + + fun getUserSettings(user: User): UserSettings + + fun updateUserSettings(user: User, settings: UserSettings) +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/AuthenticationInterfaceTest.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/AuthenticationInterfaceTest.kt index 1da68fe1..6ef61fa9 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/AuthenticationInterfaceTest.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/AuthenticationInterfaceTest.kt @@ -1,5 +1,5 @@ -import com.simiacryptus.skyenet.core.platform.AuthenticationInterface -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.AuthenticationInterface +import com.simiacryptus.skyenet.core.platform.model.User import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test import java.util.* diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/AuthorizationInterfaceTest.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/AuthorizationInterfaceTest.kt index bf271eb8..b378aa1c 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/AuthorizationInterfaceTest.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/AuthorizationInterfaceTest.kt @@ -1,7 +1,6 @@ -import com.simiacryptus.skyenet.core.platform.AuthorizationInterface -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.AuthorizationInterface +import com.simiacryptus.skyenet.core.platform.model.User import org.junit.jupiter.api.Assertions.assertFalse -import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test open class AuthorizationInterfaceTest( diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/MetadataStorageInterfaceTest.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/MetadataStorageInterfaceTest.kt new file mode 100644 index 00000000..d299c464 --- /dev/null +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/MetadataStorageInterfaceTest.kt @@ -0,0 +1,126 @@ +package com.simiacryptus.skyenet.core.platform.test + +import com.simiacryptus.skyenet.core.platform.Session +import com.simiacryptus.skyenet.core.platform.model.MetadataStorageInterface +import com.simiacryptus.skyenet.core.platform.model.User +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test +import java.util.* + +abstract class MetadataStorageInterfaceTest(val storage: MetadataStorageInterface) { + + @Test + fun testGetSessionName() { + // Arrange + val user = User(email = "test@example.com") + val session = Session("G-20230101-1234") + + // Act + val sessionName = storage.getSessionName(user, session) + + // Assert + assertNotNull(sessionName) + assertTrue(sessionName is String) + } + + @Test + fun testSetSessionName() { + // Arrange + val user = User(email = "test@example.com") + val session = Session("G-20230101-1234") + val newName = "Test Session" + + // Act + storage.setSessionName(user, session, newName) + val retrievedName = storage.getSessionName(user, session) + + // Assert + assertEquals(newName, retrievedName) + } + + @Test + fun testGetMessageIds() { + // Arrange + val user = User(email = "test@example.com") + val session = Session("G-20230101-1234") + + // Act + val messageIds = storage.getMessageIds(user, session) + + // Assert + assertNotNull(messageIds) + assertTrue(messageIds is List<*>) + } + + @Test + fun testSetMessageIds() { + // Arrange + val user = User(email = "test@example.com") + val session = Session("G-20230101-1234") + val newIds = listOf("msg001", "msg002", "msg003") + + // Act + storage.setMessageIds(user, session, newIds) + val retrievedIds = storage.getMessageIds(user, session) + + // Assert + assertEquals(newIds, retrievedIds) + } + +// @Test + fun testGetSessionTime() { + // Arrange + val user = User(email = "test@example.com") + val session = Session("G-20230101-1234") + + // Act + val sessionTime = storage.getSessionTime(user, session) + + // Assert + assertNotNull(sessionTime) + assertTrue(sessionTime is Date) + } + + @Test + fun testSetSessionTime() { + // Arrange + val user = User(email = "test@example.com") + val session = Session("G-20230101-1234") + val newTime = Date() + + // Act + storage.setSessionTime(user, session, newTime) + val retrievedTime = storage.getSessionTime(user, session) + + // Assert + assertEquals(newTime.toString(), retrievedTime.toString()) + } + + @Test + fun testListSessions() { + // Arrange + val path = "" + + // Act + val sessions = storage.listSessions(path) + + // Assert + assertNotNull(sessions) + assertTrue(sessions is List<*>) + } + + @Test + fun testDeleteSession() { + // Arrange + val user = User(email = "test@example.com") + val session = Session("G-20230101-1234") + + // Act and Assert + try { + storage.deleteSession(user, session) + // If no exception is thrown, the test passes. + } catch (e: Exception) { + fail("Exception should not be thrown") + } + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/StorageInterfaceTest.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/StorageInterfaceTest.kt index 383c5c99..909b9e3f 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/StorageInterfaceTest.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/StorageInterfaceTest.kt @@ -1,9 +1,9 @@ package com.simiacryptus.skyenet.core.platform.test -import com.simiacryptus.util.JsonUtil import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.StorageInterface -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.StorageInterface +import com.simiacryptus.skyenet.core.platform.model.User +import com.simiacryptus.util.JsonUtil import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertTrue @@ -92,7 +92,7 @@ abstract class StorageInterfaceTest(val storage: StorageInterface) { val user = User(email = "test@example.com") // Act - val sessions = storage.listSessions(user, "",) + val sessions = storage.listSessions(user, "") // Assert Assertions.assertNotNull(sessions) diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/UsageTest.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/UsageTest.kt index f10016e5..6b2b6b29 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/UsageTest.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/UsageTest.kt @@ -1,11 +1,10 @@ package com.simiacryptus.skyenet.core.platform.test import com.simiacryptus.jopenai.models.ApiModel -import com.simiacryptus.jopenai.models.ChatModels import com.simiacryptus.jopenai.models.OpenAIModels -import com.simiacryptus.skyenet.core.platform.StorageInterface -import com.simiacryptus.skyenet.core.platform.UsageInterface -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.Session +import com.simiacryptus.skyenet.core.platform.model.UsageInterface +import com.simiacryptus.skyenet.core.platform.model.User import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -26,7 +25,7 @@ abstract class UsageTest(private val impl: UsageInterface) { @Test fun `incrementUsage should increment usage for session`() { val model = OpenAIModels.GPT4oMini - val session = StorageInterface.newGlobalID() + val session = Session.newGlobalID() val usage = ApiModel.Usage( prompt_tokens = 10, completion_tokens = 20, @@ -42,7 +41,7 @@ abstract class UsageTest(private val impl: UsageInterface) { @Test fun `getUserUsageSummary should return correct usage summary`() { val model = OpenAIModels.GPT4oMini - val session = StorageInterface.newGlobalID() + val session = Session.newGlobalID() val usage = ApiModel.Usage( prompt_tokens = 15, completion_tokens = 25, @@ -56,7 +55,7 @@ abstract class UsageTest(private val impl: UsageInterface) { @Test fun `clear should reset all usage data`() { val model = OpenAIModels.GPT4oMini - val session = StorageInterface.newGlobalID() + val session = Session.newGlobalID() val usage = ApiModel.Usage( prompt_tokens = 20, completion_tokens = 30, @@ -74,7 +73,7 @@ abstract class UsageTest(private val impl: UsageInterface) { fun `incrementUsage should handle multiple models correctly`() { val model1 = OpenAIModels.GPT4oMini val model2 = OpenAIModels.GPT4Turbo - val session = StorageInterface.newGlobalID() + val session = Session.newGlobalID() val usage1 = ApiModel.Usage( prompt_tokens = 10, completion_tokens = 20, @@ -98,7 +97,7 @@ abstract class UsageTest(private val impl: UsageInterface) { @Test fun `incrementUsage should accumulate usage for the same model`() { val model = OpenAIModels.GPT4oMini - val session = StorageInterface.newGlobalID() + val session = Session.newGlobalID() val usage1 = ApiModel.Usage( prompt_tokens = 10, completion_tokens = 20, @@ -124,7 +123,7 @@ abstract class UsageTest(private val impl: UsageInterface) { @Test fun `getSessionUsageSummary should return empty map for unknown session`() { - val session = StorageInterface.newGlobalID() + val session = Session.newGlobalID() val usageSummary = impl.getSessionUsageSummary(session) Assertions.assertTrue(usageSummary.isEmpty()) } diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/UserSettingsTest.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/UserSettingsTest.kt index 42b7045e..330f7b74 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/UserSettingsTest.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/platform/test/UserSettingsTest.kt @@ -1,8 +1,8 @@ package com.simiacryptus.skyenet.core.platform.test import com.simiacryptus.jopenai.models.APIProvider -import com.simiacryptus.skyenet.core.platform.User -import com.simiacryptus.skyenet.core.platform.UserSettingsInterface +import com.simiacryptus.skyenet.core.platform.model.User +import com.simiacryptus.skyenet.core.platform.model.UserSettingsInterface import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test import java.util.* diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/util/Ears.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/util/Ears.kt index 7ff6b551..b649c3dc 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/util/Ears.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/util/Ears.kt @@ -5,7 +5,6 @@ import com.simiacryptus.jopenai.OpenAIClient import com.simiacryptus.jopenai.audio.AudioRecorder import com.simiacryptus.jopenai.audio.LookbackLoudnessWindowBuffer import com.simiacryptus.jopenai.audio.TranscriptionProcessor -import com.simiacryptus.jopenai.models.ChatModels import com.simiacryptus.jopenai.models.OpenAIModels import com.simiacryptus.jopenai.proxy.ChatProxy import org.slf4j.LoggerFactory diff --git a/core/src/main/kotlin/com/simiacryptus/skyenet/core/util/FunctionWrapper.kt b/core/src/main/kotlin/com/simiacryptus/skyenet/core/util/FunctionWrapper.kt index dcd4c29b..f5b75c94 100644 --- a/core/src/main/kotlin/com/simiacryptus/skyenet/core/util/FunctionWrapper.kt +++ b/core/src/main/kotlin/com/simiacryptus/skyenet/core/util/FunctionWrapper.kt @@ -2,7 +2,7 @@ package com.simiacryptus.skyenet.core.util -import com.simiacryptus.jopenai.models.ChatModels +import com.simiacryptus.jopenai.models.ChatModel import com.simiacryptus.jopenai.models.EmbeddingModels import com.simiacryptus.jopenai.models.ImageModels import com.simiacryptus.jopenai.models.OpenAIModel @@ -176,7 +176,7 @@ class JsonFunctionRecorder(baseDir: File) : FunctionInterceptor, Closeable { } -fun getModel(modelName: String?): OpenAIModel? = ChatModels.values().values.find { it.modelName == modelName } +fun getModel(modelName: String?): OpenAIModel? = ChatModel.values().values.find { it.modelName == modelName } ?: EmbeddingModels.values().values.find { it.modelName == modelName } ?: ImageModels.values().find { it.modelName == modelName } diff --git a/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/HSQLUserSettingsManagerTest.kt b/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/HSQLUserSettingsManagerTest.kt deleted file mode 100644 index e7c070fc..00000000 --- a/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/HSQLUserSettingsManagerTest.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.simiacryptus.skyenet.core.platform - -import com.simiacryptus.skyenet.core.platform.file.UsageManager -import com.simiacryptus.skyenet.core.platform.file.UserSettingsManager -import com.simiacryptus.skyenet.core.platform.test.UsageTest -import com.simiacryptus.skyenet.core.platform.test.UserSettingsTest -import java.nio.file.Files - -class HSQLUsageManagerTest : UsageTest(HSQLUsageManager(Files.createTempDirectory("usageManager").toFile())) diff --git a/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/AuthenticationManagerTest.kt b/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/file/AuthenticationManagerTest.kt similarity index 50% rename from core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/AuthenticationManagerTest.kt rename to core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/file/AuthenticationManagerTest.kt index 1548252f..094f16f8 100644 --- a/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/AuthenticationManagerTest.kt +++ b/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/file/AuthenticationManagerTest.kt @@ -1,6 +1,5 @@ -package com.simiacryptus.skyenet.core.platform +package com.simiacryptus.skyenet.core.platform.file import AuthenticationInterfaceTest -import com.simiacryptus.skyenet.core.platform.file.AuthenticationManager class AuthenticationManagerTest : AuthenticationInterfaceTest(AuthenticationManager()) \ No newline at end of file diff --git a/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/AuthorizationManagerTest.kt b/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/file/AuthorizationManagerTest.kt similarity index 50% rename from core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/AuthorizationManagerTest.kt rename to core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/file/AuthorizationManagerTest.kt index ad47a3b0..23ef691f 100644 --- a/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/AuthorizationManagerTest.kt +++ b/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/file/AuthorizationManagerTest.kt @@ -1,6 +1,5 @@ -package com.simiacryptus.skyenet.core.platform +package com.simiacryptus.skyenet.core.platform.file import AuthorizationInterfaceTest -import com.simiacryptus.skyenet.core.platform.file.AuthorizationManager class AuthorizationManagerTest : AuthorizationInterfaceTest(AuthorizationManager()) \ No newline at end of file diff --git a/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/DataStorageTest.kt b/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/file/DataStorageTest.kt similarity index 66% rename from core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/DataStorageTest.kt rename to core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/file/DataStorageTest.kt index 402dfadd..efc6ce84 100644 --- a/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/DataStorageTest.kt +++ b/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/file/DataStorageTest.kt @@ -1,6 +1,5 @@ -package com.simiacryptus.skyenet.core.platform +package com.simiacryptus.skyenet.core.platform.file -import com.simiacryptus.skyenet.core.platform.file.DataStorage import com.simiacryptus.skyenet.core.platform.test.StorageInterfaceTest import java.nio.file.Files diff --git a/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/file/MetadataStorageTest.kt b/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/file/MetadataStorageTest.kt new file mode 100644 index 00000000..25f379b7 --- /dev/null +++ b/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/file/MetadataStorageTest.kt @@ -0,0 +1,6 @@ +package com.simiacryptus.skyenet.core.platform.file + +import com.simiacryptus.skyenet.core.platform.test.MetadataStorageInterfaceTest +import java.nio.file.Files + +class MetadataStorageTest : MetadataStorageInterfaceTest(MetadataStorage(Files.createTempDirectory("sessionMetadataTest").toFile())) \ No newline at end of file diff --git a/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/UsageManagerTest.kt b/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/file/UsageManagerTest.kt similarity index 63% rename from core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/UsageManagerTest.kt rename to core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/file/UsageManagerTest.kt index f29393c3..3dc1e2a4 100644 --- a/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/UsageManagerTest.kt +++ b/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/file/UsageManagerTest.kt @@ -1,6 +1,5 @@ -package com.simiacryptus.skyenet.core.platform +package com.simiacryptus.skyenet.core.platform.file -import com.simiacryptus.skyenet.core.platform.file.UsageManager import com.simiacryptus.skyenet.core.platform.test.UsageTest import java.nio.file.Files diff --git a/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/UserSettingsManagerTest.kt b/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/file/UserSettingsManagerTest.kt similarity index 54% rename from core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/UserSettingsManagerTest.kt rename to core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/file/UserSettingsManagerTest.kt index 0e7f5f66..2a645d3d 100644 --- a/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/UserSettingsManagerTest.kt +++ b/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/file/UserSettingsManagerTest.kt @@ -1,6 +1,5 @@ -package com.simiacryptus.skyenet.core.platform +package com.simiacryptus.skyenet.core.platform.file -import com.simiacryptus.skyenet.core.platform.file.UserSettingsManager import com.simiacryptus.skyenet.core.platform.test.UserSettingsTest class UserSettingsManagerTest : UserSettingsTest(UserSettingsManager()) \ No newline at end of file diff --git a/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/hsql/HSQLMetadataStorageTest.kt b/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/hsql/HSQLMetadataStorageTest.kt new file mode 100644 index 00000000..44cd0864 --- /dev/null +++ b/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/hsql/HSQLMetadataStorageTest.kt @@ -0,0 +1,6 @@ +package com.simiacryptus.skyenet.core.platform.hsql + +import com.simiacryptus.skyenet.core.platform.test.MetadataStorageInterfaceTest +import java.nio.file.Files + +class HSQLMetadataStorageTest : MetadataStorageInterfaceTest(HSQLMetadataStorage(Files.createTempDirectory("metadataStorage").toFile())) \ No newline at end of file diff --git a/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/HSQLUsageManagerTest.kt b/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/hsql/HSQLUsageManagerTest.kt similarity index 50% rename from core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/HSQLUsageManagerTest.kt rename to core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/hsql/HSQLUsageManagerTest.kt index cd48637c..93d0003f 100644 --- a/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/HSQLUsageManagerTest.kt +++ b/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/hsql/HSQLUsageManagerTest.kt @@ -1,7 +1,8 @@ -import com.simiacryptus.skyenet.core.platform.HSQLUsageManager +import com.simiacryptus.skyenet.core.platform.hsql.HSQLUsageManager import com.simiacryptus.skyenet.core.platform.test.UsageTest import org.junit.jupiter.api.TestInstance import java.nio.file.Files @TestInstance(TestInstance.Lifecycle.PER_CLASS) - class HSQLUsageManagerTest : UsageTest(HSQLUsageManager(Files.createTempDirectory("usageManager").toFile())) \ No newline at end of file +class HSQLUsageManagerTest : UsageTest(HSQLUsageManager(Files.createTempDirectory("usageManager").toFile())) + diff --git a/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/hsql/HSQLUserSettingsManagerTest.kt b/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/hsql/HSQLUserSettingsManagerTest.kt new file mode 100644 index 00000000..3970182a --- /dev/null +++ b/core/src/test/kotlin/com/simiacryptus/skyenet/core/platform/hsql/HSQLUserSettingsManagerTest.kt @@ -0,0 +1,6 @@ +package com.simiacryptus.skyenet.core.platform.hsql + +import com.simiacryptus.skyenet.core.platform.test.UsageTest +import java.nio.file.Files + +class HSQLUsageManagerTest : UsageTest(HSQLUsageManager(Files.createTempDirectory("usageManager").toFile())) diff --git a/docs/Document_Indexing.md b/docs/Document_Indexing.md index 95d0d981..8be6e954 100644 --- a/docs/Document_Indexing.md +++ b/docs/Document_Indexing.md @@ -1,28 +1,35 @@ # User Guide: Document Data Extraction and Query Index Creation -This guide covers two main features: Document Data Extraction and Query Index Creation. These tools are designed to help you extract structured data from various document types and create searchable indexes for efficient querying. +This guide covers two main features: Document Data Extraction and Query Index Creation. These tools are designed to help you extract structured data from various document types and +create searchable indexes for efficient querying. ## 1. Document Data Extraction ### Overview -The Document Data Extractor allows you to parse and extract structured information from PDF, TXT, MD, and HTML files. It uses AI to analyze the content and create a hierarchical JSON representation of the document's structure, entities, and metadata. + +The Document Data Extractor allows you to parse and extract structured information from PDF, TXT, MD, and HTML files. It uses AI to analyze the content and create a hierarchical +JSON representation of the document's structure, entities, and metadata. ### How to Use + 1. In your IDE, right-click on a supported file (PDF, TXT, MD, or HTML) in the project explorer. 2. Select the "Document Data Extractor" option from the context menu. 3. A configuration dialog will appear with the following options: - - DPI: Set the resolution for image rendering (for PDFs). - - Max Pages: Limit the number of pages to process. - - Output Format: Choose the format for saved images (PNG, JPEG, GIF, BMP). - - Pages Per Batch: Set how many pages to process in each batch. - - Show Images: Toggle whether to display rendered images in the results. - - Save Image Files: Choose to save rendered images to disk. - - Save Text Files: Choose to save extracted text to disk. - - Save Final JSON: Choose to save the final parsed JSON to disk. + +- DPI: Set the resolution for image rendering (for PDFs). +- Max Pages: Limit the number of pages to process. +- Output Format: Choose the format for saved images (PNG, JPEG, GIF, BMP). +- Pages Per Batch: Set how many pages to process in each batch. +- Show Images: Toggle whether to display rendered images in the results. +- Save Image Files: Choose to save rendered images to disk. +- Save Text Files: Choose to save extracted text to disk. +- Save Final JSON: Choose to save the final parsed JSON to disk. + 4. Click "OK" to start the extraction process. 5. A new browser window will open, showing the progress and results of the extraction. ### Output + - The extracted data will be displayed in the browser, organized by pages or batches. - If enabled, image files, text files, and the final JSON will be saved in an "output" directory next to the source file. - The final JSON file will have a ".parsed.json" extension. @@ -30,9 +37,12 @@ The Document Data Extractor allows you to parse and extract structured informati ## 2. Query Index Creation ### Overview -The Query Index Creator takes the parsed JSON files from the Document Data Extractor and creates a binary index file that can be efficiently searched using embedding-based similarity search. + +The Query Index Creator takes the parsed JSON files from the Document Data Extractor and creates a binary index file that can be efficiently searched using embedding-based +similarity search. ### How to Use + 1. In your IDE, select one or more ".parsed.json" files in the project explorer. 2. Right-click and choose the "Save As Query Index" option from the context menu. 3. A file chooser dialog will appear. Select the directory where you want to save the index file. @@ -40,14 +50,17 @@ The Query Index Creator takes the parsed JSON files from the Document Data Extra 5. A progress bar will show the status of the index creation. ### Output + - A binary index file named "document.index.data" will be created in the selected output directory. - This index file can be used for fast similarity searches on the extracted document data. ## Using the Query Index -Once you have created the query index, you can use it with the EmbeddingSearchTask to perform similarity searches on your document data. This allows you to quickly find relevant information across all your indexed documents. +Once you have created the query index, you can use it with the EmbeddingSearchTask to perform similarity searches on your document data. This allows you to quickly find relevant +information across all your indexed documents. To use the EmbeddingSearchTask: + 1. Set up your search query and parameters (e.g., distance type, number of results). 2. Point the task to your "document.index.data" file. 3. Run the search to get the most relevant results based on embedding similarity. diff --git a/docs/core_user_documentation.md b/docs/core_user_documentation.md index 2a735c38..99f59d2a 100644 --- a/docs/core_user_documentation.md +++ b/docs/core_user_documentation.md @@ -1,210 +1,214 @@ - + * [Skyenet Core Actors Package Documentation](#skyenet-core-actors-package-documentation) - * [Package Overview](#package-overview) - * [Core Classes](#core-classes) - * [Supporting Classes and Interfaces](#supporting-classes-and-interfaces) - * [Documentation and Testing Base Classes](#documentation-and-testing-base-classes) + * [Package Overview](#package-overview) + * [Core Classes](#core-classes) + * [Supporting Classes and Interfaces](#supporting-classes-and-interfaces) + * [Documentation and Testing Base Classes](#documentation-and-testing-base-classes) * [BaseActor.kt](#baseactorkt) - * [User Documentation for BaseActor Class](#user-documentation-for-baseactor-class) - * [Overview](#overview) - * [Key Features](#key-features) - * [Constructor Parameters](#constructor-parameters) - * [Methods](#methods) - * [`respond(input: I, api: API, vararg messages: ApiModel.ChatMessage): R`](#respondinput-i-api-api-vararg-messages-apimodelchatmessage-r) - * [`response(vararg input: ApiModel.ChatMessage, model: OpenAIModel = this.model, api: API): List`](#responsevararg-input-apimodelchatmessage-model-openaimodel--thismodel-api-api-listapimodelchatmessage) - * [`answer(input: I, api: API): R`](#answerinput-i-api-api-r) - * [`chatMessages(questions: I): Array`](#chatmessagesquestions-i-arrayapimodelchatmessage) - * [`withModel(model: ChatModels): BaseActor`](#withmodelmodel-chatmodels-baseactorir) - * [Usage Example](#usage-example) - * [Conclusion](#conclusion) + * [User Documentation for BaseActor Class](#user-documentation-for-baseactor-class) + * [Overview](#overview) + * [Key Features](#key-features) + * [Constructor Parameters](#constructor-parameters) + * [Methods](#methods) + * [`respond(input: I, api: API, vararg messages: ApiModel.ChatMessage): R`](#respondinput-i-api-api-vararg-messages-apimodelchatmessage-r) + * [ + `response(vararg input: ApiModel.ChatMessage, model: OpenAIModel = this.model, api: API): List`](#responsevararg-input-apimodelchatmessage-model-openaimodel--thismodel-api-api-listapimodelchatmessage) + * [`answer(input: I, api: API): R`](#answerinput-i-api-api-r) + * [`chatMessages(questions: I): Array`](#chatmessagesquestions-i-arrayapimodelchatmessage) + * [`withModel(model: ChatModels): BaseActor`](#withmodelmodel-chatmodels-baseactorir) + * [Usage Example](#usage-example) + * [Conclusion](#conclusion) * [CodingActor.kt](#codingactorkt) - * [CodingActor Documentation](#codingactor-documentation) - * [Overview](#overview-1) - * [Key Features](#key-features-1) - * [Usage](#usage) - * [Initialization](#initialization) - * [Processing Requests](#processing-requests) - * [Handling Results](#handling-results) - * [Advanced Features](#advanced-features) - * [Conclusion](#conclusion-1) + * [CodingActor Documentation](#codingactor-documentation) + * [Overview](#overview-1) + * [Key Features](#key-features-1) + * [Usage](#usage) + * [Initialization](#initialization) + * [Processing Requests](#processing-requests) + * [Handling Results](#handling-results) + * [Advanced Features](#advanced-features) + * [Conclusion](#conclusion-1) * [ImageActor.kt](#imageactorkt) - * [ImageActor Documentation](#imageactor-documentation) - * [Features](#features) - * [Usage](#usage-1) - * [Initialization](#initialization-1) - * [Generating Images](#generating-images) - * [Accessing the Generated Image](#accessing-the-generated-image) - * [Customizing the Actor](#customizing-the-actor) - * [Interfaces and Classes](#interfaces-and-classes) - * [Conclusion](#conclusion-2) + * [ImageActor Documentation](#imageactor-documentation) + * [Features](#features) + * [Usage](#usage-1) + * [Initialization](#initialization-1) + * [Generating Images](#generating-images) + * [Accessing the Generated Image](#accessing-the-generated-image) + * [Customizing the Actor](#customizing-the-actor) + * [Interfaces and Classes](#interfaces-and-classes) + * [Conclusion](#conclusion-2) * [ActorSystem.kt](#actorsystemkt) - * [ActorSystem Documentation](#actorsystem-documentation) - * [Overview](#overview-2) - * [Key Components](#key-components) - * [Features](#features-1) - * [Actor Retrieval](#actor-retrieval) - * [Interceptors](#interceptors) - * [Function Wrapping](#function-wrapping) - * [Usage](#usage-2) - * [Conclusion](#conclusion-3) + * [ActorSystem Documentation](#actorsystem-documentation) + * [Overview](#overview-2) + * [Key Components](#key-components) + * [Features](#features-1) + * [Actor Retrieval](#actor-retrieval) + * [Interceptors](#interceptors) + * [Function Wrapping](#function-wrapping) + * [Usage](#usage-2) + * [Conclusion](#conclusion-3) * [opt\Expectation.kt](#optexpectationkt) - * [Skyenet Core Expectation Module Documentation](#skyenet-core-expectation-module-documentation) - * [Overview](#overview-3) - * [VectorMatch Class](#vectormatch-class) - * [Parameters:](#parameters) - * [Methods:](#methods-1) - * [ContainsMatch Class](#containsmatch-class) - * [Parameters:](#parameters-1) - * [Methods:](#methods-2) - * [Usage](#usage-3) - * [Example](#example) + * [Skyenet Core Expectation Module Documentation](#skyenet-core-expectation-module-documentation) + * [Overview](#overview-3) + * [VectorMatch Class](#vectormatch-class) + * [Parameters:](#parameters) + * [Methods:](#methods-1) + * [ContainsMatch Class](#containsmatch-class) + * [Parameters:](#parameters-1) + * [Methods:](#methods-2) + * [Usage](#usage-3) + * [Example](#example) * [ParsedActor.kt](#parsedactorkt) - * [ParsedActor Class Documentation](#parsedactor-class-documentation) - * [Features](#features-2) - * [Constructor Parameters](#constructor-parameters-1) - * [Methods](#methods-3) - * [`chatMessages(questions: List)`](#chatmessagesquestions-liststring) - * [`getParser(api: API)`](#getparserapi-api) - * [`respond(input: List, api: API, vararg messages: ApiModel.ChatMessage)`](#respondinput-liststring-api-api-vararg-messages-apimodelchatmessage) - * [`withModel(model: ChatModels)`](#withmodelmodel-chatmodels) - * [Inner Classes](#inner-classes) - * [`ParsedResponseImpl`](#parsedresponseimpl) - * [Usage Example](#usage-example-1) + * [ParsedActor Class Documentation](#parsedactor-class-documentation) + * [Features](#features-2) + * [Constructor Parameters](#constructor-parameters-1) + * [Methods](#methods-3) + * [`chatMessages(questions: List)`](#chatmessagesquestions-liststring) + * [`getParser(api: API)`](#getparserapi-api) + * [`respond(input: List, api: API, vararg messages: ApiModel.ChatMessage)`](#respondinput-liststring-api-api-vararg-messages-apimodelchatmessage) + * [`withModel(model: ChatModels)`](#withmodelmodel-chatmodels) + * [Inner Classes](#inner-classes) + * [`ParsedResponseImpl`](#parsedresponseimpl) + * [Usage Example](#usage-example-1) * [ParsedResponse.kt](#parsedresponsekt) - * [User Documentation for ParsedResponse Class](#user-documentation-for-parsedresponse-class) - * [Overview](#overview-4) - * [Key Features](#key-features-2) - * [Properties](#properties) - * [Methods](#methods-4) - * [Usage](#usage-4) - * [Example](#example-1) - * [Conclusion](#conclusion-4) + * [User Documentation for ParsedResponse Class](#user-documentation-for-parsedresponse-class) + * [Overview](#overview-4) + * [Key Features](#key-features-2) + * [Properties](#properties) + * [Methods](#methods-4) + * [Usage](#usage-4) + * [Example](#example-1) + * [Conclusion](#conclusion-4) * [record\CodingActorInterceptor.kt](#recordcodingactorinterceptorkt) - * [CodingActorInterceptor Documentation](#codingactorinterceptor-documentation) - * [Features](#features-3) - * [Usage](#usage-5) - * [Initialization](#initialization-2) - * [Overridden Methods](#overridden-methods) - * [Example: Interception Logic](#example-interception-logic) - * [Integration](#integration) - * [Conclusion](#conclusion-5) + * [CodingActorInterceptor Documentation](#codingactorinterceptor-documentation) + * [Features](#features-3) + * [Usage](#usage-5) + * [Initialization](#initialization-2) + * [Overridden Methods](#overridden-methods) + * [Example: Interception Logic](#example-interception-logic) + * [Integration](#integration) + * [Conclusion](#conclusion-5) * [opt\ActorOptimization.kt](#optactoroptimizationkt) - * [ActorOptimization Class Documentation](#actoroptimization-class-documentation) - * [Features](#features-4) - * [Key Components](#key-components-1) - * [TestCase Class](#testcase-class) - * [GeneticApi Interface](#geneticapi-interface) - * [Main Methods](#main-methods) - * [runGeneticGenerations](#rungeneticgenerations) - * [regenerate](#regenerate) - * [Usage Example](#usage-example-2) - * [Customization](#customization) - * [Conclusion](#conclusion-6) + * [ActorOptimization Class Documentation](#actoroptimization-class-documentation) + * [Features](#features-4) + * [Key Components](#key-components-1) + * [TestCase Class](#testcase-class) + * [GeneticApi Interface](#geneticapi-interface) + * [Main Methods](#main-methods) + * [runGeneticGenerations](#rungeneticgenerations) + * [regenerate](#regenerate) + * [Usage Example](#usage-example-2) + * [Customization](#customization) + * [Conclusion](#conclusion-6) * [record\ImageActorInterceptor.kt](#recordimageactorinterceptorkt) - * [User Documentation for ImageActorInterceptor](#user-documentation-for-imageactorinterceptor) - * [Overview](#overview-5) - * [Key Features](#key-features-3) - * [Usage](#usage-6) - * [Initialization](#initialization-3) - * [Interception and Custom Processing](#interception-and-custom-processing) - * [Methods](#methods-5) - * [`response`](#response) - * [`render`](#render) - * [Conclusion](#conclusion-7) + * [User Documentation for ImageActorInterceptor](#user-documentation-for-imageactorinterceptor) + * [Overview](#overview-5) + * [Key Features](#key-features-3) + * [Usage](#usage-6) + * [Initialization](#initialization-3) + * [Interception and Custom Processing](#interception-and-custom-processing) + * [Methods](#methods-5) + * [`response`](#response) + * [`render`](#render) + * [Conclusion](#conclusion-7) * [record\ParsedActorInterceptor.kt](#recordparsedactorinterceptorkt) - * [ParsedActorInterceptor Documentation](#parsedactorinterceptor-documentation) - * [Features](#features-5) - * [Usage](#usage-7) - * [Initialization](#initialization-4) - * [Responding to Inputs](#responding-to-inputs) - * [Custom Response Processing](#custom-response-processing) - * [Key Methods](#key-methods) - * [Example](#example-2) - * [Conclusion](#conclusion-8) + * [ParsedActorInterceptor Documentation](#parsedactorinterceptor-documentation) + * [Features](#features-5) + * [Usage](#usage-7) + * [Initialization](#initialization-4) + * [Responding to Inputs](#responding-to-inputs) + * [Custom Response Processing](#custom-response-processing) + * [Key Methods](#key-methods) + * [Example](#example-2) + * [Conclusion](#conclusion-8) * [record\TextToSpeechActorInterceptor.kt](#recordtexttospeechactorinterceptorkt) - * [TextToSpeechActorInterceptor Documentation](#texttospeechactorinterceptor-documentation) - * [Features](#features-6) - * [Usage](#usage-8) - * [Initialization](#initialization-5) - * [Interception](#interception) - * [Response Interception](#response-interception) - * [Render Interception](#render-interception) - * [Customization](#customization-1) - * [Conclusion](#conclusion-9) + * [TextToSpeechActorInterceptor Documentation](#texttospeechactorinterceptor-documentation) + * [Features](#features-6) + * [Usage](#usage-8) + * [Initialization](#initialization-5) + * [Interception](#interception) + * [Response Interception](#response-interception) + * [Render Interception](#render-interception) + * [Customization](#customization-1) + * [Conclusion](#conclusion-9) * [record\SimpleActorInterceptor.kt](#recordsimpleactorinterceptorkt) - * [SimpleActorInterceptor Documentation](#simpleactorinterceptor-documentation) - * [Features](#features-7) - * [Usage](#usage-9) - * [Example](#example-3) - * [Parameters](#parameters-2) - * [Methods](#methods-6) - * [Conclusion](#conclusion-10) + * [SimpleActorInterceptor Documentation](#simpleactorinterceptor-documentation) + * [Features](#features-7) + * [Usage](#usage-9) + * [Example](#example-3) + * [Parameters](#parameters-2) + * [Methods](#methods-6) + * [Conclusion](#conclusion-10) * [test\ImageActorTestBase.kt](#testimageactortestbasekt) - * [User Documentation for ImageActorTestBase](#user-documentation-for-imageactortestbase) - * [Overview](#overview-6) - * [Key Features](#key-features-4) - * [Getting Started](#getting-started) - * [Example Usage](#example-usage) - * [Conclusion](#conclusion-11) + * [User Documentation for ImageActorTestBase](#user-documentation-for-imageactortestbase) + * [Overview](#overview-6) + * [Key Features](#key-features-4) + * [Getting Started](#getting-started) + * [Example Usage](#example-usage) + * [Conclusion](#conclusion-11) * [test\CodingActorTestBase.kt](#testcodingactortestbasekt) - * [CodingActorTestBase Documentation](#codingactortestbase-documentation) - * [Overview](#overview-7) - * [Key Components](#key-components-2) - * [Properties](#properties-1) - * [Methods](#methods-7) - * [Usage](#usage-10) - * [Example](#example-4) - * [Conclusion](#conclusion-12) + * [CodingActorTestBase Documentation](#codingactortestbase-documentation) + * [Overview](#overview-7) + * [Key Components](#key-components-2) + * [Properties](#properties-1) + * [Methods](#methods-7) + * [Usage](#usage-10) + * [Example](#example-4) + * [Conclusion](#conclusion-12) * [SimpleActor.kt](#simpleactorkt) - * [SimpleActor Class Documentation](#simpleactor-class-documentation) - * [Constructor Parameters](#constructor-parameters-2) - * [Methods](#methods-8) - * [respond](#respond) - * [chatMessages](#chatmessages) - * [withModel](#withmodel) - * [Usage Example](#usage-example-3) + * [SimpleActor Class Documentation](#simpleactor-class-documentation) + * [Constructor Parameters](#constructor-parameters-2) + * [Methods](#methods-8) + * [respond](#respond) + * [chatMessages](#chatmessages) + * [withModel](#withmodel) + * [Usage Example](#usage-example-3) * [test\ActorTestBase.kt](#testactortestbasekt) - * [ActorTestBase Documentation](#actortestbase-documentation) - * [Overview](#overview-8) - * [Key Components](#key-components-3) - * [Properties](#properties-2) - * [Methods](#methods-9) - * [`opt()`](#opt) - * [`testOptimize()`](#testoptimize) - * [`testRun()`](#testrun) - * [`answer()`](#answer) - * [Companion Object](#companion-object) - * [Usage](#usage-11) + * [ActorTestBase Documentation](#actortestbase-documentation) + * [Overview](#overview-8) + * [Key Components](#key-components-3) + * [Properties](#properties-2) + * [Methods](#methods-9) + * [`opt()`](#opt) + * [`testOptimize()`](#testoptimize) + * [`testRun()`](#testrun) + * [`answer()`](#answer) + * [Companion Object](#companion-object) + * [Usage](#usage-11) * [test\ParsedActorTestBase.kt](#testparsedactortestbasekt) - * [User Documentation for ParsedActorTestBase](#user-documentation-for-parsedactortestbase) - * [Overview](#overview-9) - * [Key Components](#key-components-4) - * [Constructor Parameters](#constructor-parameters-3) - * [Methods](#methods-10) - * [actorFactory](#actorfactory) - * [getPrompt](#getprompt) - * [resultMapper](#resultmapper) - * [Usage](#usage-12) - * [Example](#example-5) - * [Conclusion](#conclusion-13) + * [User Documentation for ParsedActorTestBase](#user-documentation-for-parsedactortestbase) + * [Overview](#overview-9) + * [Key Components](#key-components-4) + * [Constructor Parameters](#constructor-parameters-3) + * [Methods](#methods-10) + * [actorFactory](#actorfactory) + * [getPrompt](#getprompt) + * [resultMapper](#resultmapper) + * [Usage](#usage-12) + * [Example](#example-5) + * [Conclusion](#conclusion-13) * [TextToSpeechActor.kt](#texttospeechactorkt) - * [TextToSpeechActor Documentation](#texttospeechactor-documentation) - * [Features](#features-8) - * [Constructor Parameters](#constructor-parameters-4) - * [Methods](#methods-11) - * [`chatMessages(questions: List)`](#chatmessagesquestions-liststring-1) - * [`render(text: String, api: API)`](#rendertext-string-api-api) - * [`respond(input: List, api: API, vararg messages: ChatMessage)`](#respondinput-liststring-api-api-vararg-messages-chatmessage) - * [`withModel(model: AudioModels)`](#withmodelmodel-audiomodels) - * [Interfaces](#interfaces) - * [`SpeechResponse`](#speechresponse) - * [Usage Example](#usage-example-4) + * [TextToSpeechActor Documentation](#texttospeechactor-documentation) + * [Features](#features-8) + * [Constructor Parameters](#constructor-parameters-4) + * [Methods](#methods-11) + * [`chatMessages(questions: List)`](#chatmessagesquestions-liststring-1) + * [`render(text: String, api: API)`](#rendertext-string-api-api) + * [`respond(input: List, api: API, vararg messages: ChatMessage)`](#respondinput-liststring-api-api-vararg-messages-chatmessage) + * [`withModel(model: AudioModels)`](#withmodelmodel-audiomodels) + * [Interfaces](#interfaces) + * [`SpeechResponse`](#speechresponse) + * [Usage Example](#usage-example-4) + # Skyenet Core Actors Package Documentation -The Skyenet Core Actors package is a comprehensive framework designed to facilitate interaction with OpenAI's GPT models and other functionalities such as text-to-speech and image generation. This package is structured to provide a robust foundation for building applications that leverage OpenAI's capabilities, including conversational agents, code generators, and visual content creators. +The Skyenet Core Actors package is a comprehensive framework designed to facilitate interaction with OpenAI's GPT models and other functionalities such as text-to-speech and image +generation. This package is structured to provide a robust foundation for building applications that leverage OpenAI's capabilities, including conversational agents, code +generators, and visual content creators. ## Package Overview @@ -223,26 +227,25 @@ The package is organized into several key components, each serving a specific pu - **`ActorSystem`**: Manages and interacts with various types of actors within a session, applying specific interceptors based on the actor type. - **`ParsedResponse`**: Represents responses parsed from various sources in a structured manner. -- **Interceptors (`*Interceptor`)**: Specialized classes designed to intercept and potentially modify the behavior of actor instances (e.g., `CodingActorInterceptor`, `ImageActorInterceptor`). +- **Interceptors (`*Interceptor`)**: Specialized classes designed to intercept and potentially modify the behavior of actor instances (e.g., `CodingActorInterceptor`, + `ImageActorInterceptor`). ### Documentation and Testing Base Classes - **`ActorTestBase`**: An abstract class designed to facilitate the testing of actors within the system. - **`ParsedActorTestBase`, `CodingActorTestBase`, `ImageActorTestBase`**: Extend `ActorTestBase` to provide testing functionalities tailored to specific actor types. - # BaseActor.kt - ## User Documentation for BaseActor Class -The `BaseActor` class serves as an abstract foundation for creating actors that interact with OpenAI's GPT models via the `com.simiacryptus.jopenai` API. This class is designed to facilitate the development of applications that require conversational capabilities or complex decision-making processes based on the input provided to the model. - +The `BaseActor` class serves as an abstract foundation for creating actors that interact with OpenAI's GPT models via the `com.simiacryptus.jopenai` API. This class is designed to +facilitate the development of applications that require conversational capabilities or complex decision-making processes based on the input provided to the model. ### Overview -The `BaseActor` class abstracts the process of sending prompts to an OpenAI model and receiving responses. It is designed to be extended by more specific actor classes that define the logic for generating prompts based on input and processing the model's responses. - +The `BaseActor` class abstracts the process of sending prompts to an OpenAI model and receiving responses. It is designed to be extended by more specific actor classes that define +the logic for generating prompts based on input and processing the model's responses. ### Key Features @@ -250,7 +253,6 @@ The `BaseActor` class abstracts the process of sending prompts to an OpenAI mode - **Temperature Control:** Enables setting the temperature parameter to control the randomness of the model's responses. - **Convenient Response Handling:** Simplifies the process of sending requests to the OpenAI API and handling responses. - ### Constructor Parameters - `prompt`: The initial prompt or question to be sent to the model. @@ -258,35 +260,29 @@ The `BaseActor` class abstracts the process of sending prompts to an OpenAI mode - `model`: The OpenAI model to be used. Defaults to `OpenAIModels.GPT35Turbo`. - `temperature`: Controls the randomness of the model's responses. Lower values make responses more deterministic. - ### Methods - #### `respond(input: I, api: API, vararg messages: ApiModel.ChatMessage): R` An abstract method that must be implemented by subclasses. It defines how the actor should respond to a given input, using the specified API and any additional chat messages. - #### `response(vararg input: ApiModel.ChatMessage, model: OpenAIModel = this.model, api: API): List` Sends a chat request to the OpenAI API using the provided messages and returns the response. This method can be overridden if necessary. - #### `answer(input: I, api: API): R` Generates a response based on the input by internally calling `respond`. It automatically handles the conversion of input to chat messages. - #### `chatMessages(questions: I): Array` -An abstract method that subclasses must implement. It should convert the input into an array of `ApiModel.ChatMessage` instances, which are then used to generate the model's response. - +An abstract method that subclasses must implement. It should convert the input into an array of `ApiModel.ChatMessage` instances, which are then used to generate the model's +response. #### `withModel(model: ChatModels): BaseActor` An abstract method that should be implemented to return a new instance of the actor with the specified model. - ### Usage Example To use the `BaseActor` class, you must extend it and implement the abstract methods. Here's a simplified example: @@ -310,23 +306,23 @@ class SimpleActor(prompt: String) : BaseActor(prompt) { This example demonstrates a basic actor that sends a single message to the model and returns the concatenated text of the responses. - ### Conclusion -The `BaseActor` class provides a flexible and powerful foundation for building applications that interact with OpenAI's models. By extending this class and implementing its abstract methods, developers can create customized actors tailored to their specific needs. +The `BaseActor` class provides a flexible and powerful foundation for building applications that interact with OpenAI's models. By extending this class and implementing its +abstract methods, developers can create customized actors tailored to their specific needs. # CodingActor.kt - ## CodingActor Documentation -The `CodingActor` class is a versatile component designed to facilitate the interaction between natural language instructions and code execution within a specified programming language context. It leverages the capabilities of OpenAI's GPT models to translate instructions into executable code, evaluate the code, and provide feedback or corrections as necessary. This document provides an overview of the `CodingActor` class, its functionalities, and how to utilize it effectively. - +The `CodingActor` class is a versatile component designed to facilitate the interaction between natural language instructions and code execution within a specified programming +language context. It leverages the capabilities of OpenAI's GPT models to translate instructions into executable code, evaluate the code, and provide feedback or corrections as +necessary. This document provides an overview of the `CodingActor` class, its functionalities, and how to utilize it effectively. ### Overview -`CodingActor` extends the `BaseActor` class and specializes in processing coding requests (`CodeRequest`) and generating code results (`CodeResult`). It integrates with an interpreter to execute the generated code and handles the interaction with OpenAI's API for code generation and correction. - +`CodingActor` extends the `BaseActor` class and specializes in processing coding requests (`CodeRequest`) and generating code results (`CodeResult`). It integrates with an +interpreter to execute the generated code and handles the interaction with OpenAI's API for code generation and correction. #### Key Features @@ -336,10 +332,8 @@ The `CodingActor` class is a versatile component designed to facilitate the inte - **Customizable Code Formatting**: Supports customizable code formatting instructions. - **Extensible**: Allows for the specification of additional symbols and runtime context to be used during code generation and execution. - ### Usage - #### Initialization To create an instance of `CodingActor`, you need to provide the following parameters: @@ -366,10 +360,10 @@ val codingActor = CodingActor( ) ``` - #### Processing Requests -To process a coding request, create an instance of `CodeRequest` with the desired parameters, such as the list of messages (instructions and responses), code prefix, and whether to auto-evaluate the code. Then, call the `respond` method of your `CodingActor` instance with the request. +To process a coding request, create an instance of `CodeRequest` with the desired parameters, such as the list of messages (instructions and responses), code prefix, and whether to +auto-evaluate the code. Then, call the `respond` method of your `CodingActor` instance with the request. Example: @@ -382,7 +376,6 @@ val request = CodingActor.CodeRequest( val result = codingActor.respond(request, apiInstance) ``` - #### Handling Results The result of a coding request is an instance of `CodeResult`, which includes the generated code, its execution status, the execution result, and a rendered response. @@ -395,25 +388,23 @@ println("Generated Code: ${result.code}") println("Execution Result: ${result.result.resultValue}") ``` - ### Advanced Features - **Custom Type Describers**: Implement custom `TypeDescriber` to control how symbols are described in the prompt. - **Error Correction**: Utilize the error correction mechanism to automatically attempt to fix errors in the generated code. - **Execution Result**: Access detailed execution results, including output and returned values. - ### Conclusion -The `CodingActor` class provides a powerful interface for integrating natural language coding instructions with executable code, leveraging the capabilities of OpenAI's models. By customizing the interpreter, symbols, and other parameters, developers can tailor the coding actor to fit a wide range of coding tasks and workflows. +The `CodingActor` class provides a powerful interface for integrating natural language coding instructions with executable code, leveraging the capabilities of OpenAI's models. By +customizing the interpreter, symbols, and other parameters, developers can tailor the coding actor to fit a wide range of coding tasks and workflows. # ImageActor.kt - ## ImageActor Documentation -The `ImageActor` class is a powerful tool designed to transform textual prompts into visually compelling images using OpenAI's image generation models. This class is part of the `com.simiacryptus.skyenet.core.actors` package and leverages the OpenAI API to fulfill image generation requests based on user input. - +The `ImageActor` class is a powerful tool designed to transform textual prompts into visually compelling images using OpenAI's image generation models. This class is part of the +`com.simiacryptus.skyenet.core.actors` package and leverages the OpenAI API to fulfill image generation requests based on user input. ### Features @@ -423,10 +414,8 @@ The `ImageActor` class is a powerful tool designed to transform textual prompts - **Text-to-Image Transformation**: Converts user requests into image generation prompts and subsequently into images. - **Model Switching**: Provides methods to switch between different chat and image models while retaining other settings. - ### Usage - #### Initialization To create an instance of `ImageActor`, you can use the following constructor: @@ -443,7 +432,6 @@ val imageActor = ImageActor( ) ``` - #### Generating Images To generate an image based on a list of textual prompts, use the `respond` method: @@ -454,8 +442,8 @@ val inputPrompts: List = listOf("A futuristic cityscape", "under a purpl val imageResponse: ImageResponse = imageActor.respond(inputPrompts, api) ``` -The `respond` method processes the input prompts, interacts with the OpenAI API to generate a textual description for the image, and then generates the image based on this description. - +The `respond` method processes the input prompts, interacts with the OpenAI API to generate a textual description for the image, and then generates the image based on this +description. #### Accessing the Generated Image @@ -466,7 +454,6 @@ val description: String = imageResponse.text val image: BufferedImage = imageResponse.image ``` - #### Customizing the Actor You can customize the `ImageActor` by changing its model settings: @@ -485,29 +472,29 @@ val newImageModel: ImageModels = ImageModels.Craiyon val updatedActor = imageActor.withModel(newImageModel) ``` - ### Interfaces and Classes - **`ImageActor`**: The main class responsible for transforming text prompts into images. - **`ImageResponse`**: An interface representing the response from an image generation request, containing both the textual description and the generated image. - ### Conclusion -The `ImageActor` class offers a convenient and flexible way to integrate OpenAI's image generation capabilities into your applications. By customizing prompts, models, and image dimensions, you can tailor the image generation process to meet a wide range of creative needs. +The `ImageActor` class offers a convenient and flexible way to integrate OpenAI's image generation capabilities into your applications. By customizing prompts, models, and image +dimensions, you can tailor the image generation process to meet a wide range of creative needs. # ActorSystem.kt - ## ActorSystem Documentation -The `ActorSystem` class is a core component of the framework designed to manage and interact with various types of actors within a session. It provides a structured way to access and utilize actors, ensuring that the necessary interceptors and wrappers are applied for enhanced functionality and monitoring. This document outlines the key features and usage of the `ActorSystem` class. - +The `ActorSystem` class is a core component of the framework designed to manage and interact with various types of actors within a session. It provides a structured way to access +and utilize actors, ensuring that the necessary interceptors and wrappers are applied for enhanced functionality and monitoring. This document outlines the key features and usage +of the `ActorSystem` class. ### Overview -An `ActorSystem` is initialized with a collection of actors, data storage interface, an optional user, and a session. It facilitates the retrieval and interaction with different types of actors, applying specific interceptors based on the actor type. This system is designed to work within the context of a session, providing a seamless way to manage actors' lifecycle and their interactions. - +An `ActorSystem` is initialized with a collection of actors, data storage interface, an optional user, and a session. It facilitates the retrieval and interaction with different +types of actors, applying specific interceptors based on the actor type. This system is designed to work within the context of a session, providing a seamless way to manage actors' +lifecycle and their interactions. ### Key Components @@ -516,14 +503,12 @@ An `ActorSystem` is initialized with a collection of actors, data storage interf - **user**: An optional `User` instance representing the user interacting with the actors. - **session**: A `Session` instance representing the current session. - ### Features - #### Actor Retrieval -- **getActor(actor: T)**: Retrieves an instance of `BaseActor` for the specified actor identifier. If the actor has not been initialized yet, it applies the appropriate interceptor based on the actor's type and caches the result for future retrievals. - +- **getActor(actor: T)**: Retrieves an instance of `BaseActor` for the specified actor identifier. If the actor has not been initialized yet, it applies the appropriate interceptor + based on the actor's type and caches the result for future retrievals. #### Interceptors @@ -537,11 +522,10 @@ Depending on the actor type, one of the following interceptors is applied to enh These interceptors wrap the original actor to provide additional features such as logging, monitoring, or custom behavior modifications. - #### Function Wrapping -For each actor, a `FunctionWrapper` is associated to enable recording and monitoring of function calls. This is facilitated through a `JsonFunctionRecorder` which stores the function call data in a structured JSON format for later analysis or debugging. - +For each actor, a `FunctionWrapper` is associated to enable recording and monitoring of function calls. This is facilitated through a `JsonFunctionRecorder` which stores the +function call data in a structured JSON format for later analysis or debugging. ### Usage @@ -563,58 +547,60 @@ val actor = actorSystem.getActor(/* Actor identifier */) // Use the actor for its intended purpose ``` - ### Conclusion -The `ActorSystem` class provides a robust and flexible way to manage actors within a session. By abstracting the complexities of actor initialization and management, it allows developers to focus on the core logic and interactions of their application. +The `ActorSystem` class provides a robust and flexible way to manage actors within a session. By abstracting the complexities of actor initialization and management, it allows +developers to focus on the core logic and interactions of their application. # opt\Expectation.kt - ## Skyenet Core Expectation Module Documentation -The Skyenet Core Expectation module is a part of the Skyenet framework designed to facilitate the evaluation of responses from an AI model, specifically using the OpenAI API. This module provides a flexible way to define expectations for responses and score them based on different criteria. It includes two primary classes: `VectorMatch` and `ContainsMatch`, each serving a unique purpose in evaluating responses. - +The Skyenet Core Expectation module is a part of the Skyenet framework designed to facilitate the evaluation of responses from an AI model, specifically using the OpenAI API. This +module provides a flexible way to define expectations for responses and score them based on different criteria. It includes two primary classes: `VectorMatch` and `ContainsMatch`, +each serving a unique purpose in evaluating responses. ### Overview -The Expectation module is abstract and contains a companion object for logging purposes. It defines two abstract methods, `matches` and `score`, which must be implemented by subclasses to determine if a response meets a certain expectation and to assign a numerical score to the response, respectively. - +The Expectation module is abstract and contains a companion object for logging purposes. It defines two abstract methods, `matches` and `score`, which must be implemented by +subclasses to determine if a response meets a certain expectation and to assign a numerical score to the response, respectively. #### VectorMatch Class -The `VectorMatch` class is designed to compare the semantic similarity between a given example text and a response text using embeddings. It utilizes the OpenAI API to generate embeddings for both texts and calculates the distance between them based on a specified metric. - +The `VectorMatch` class is designed to compare the semantic similarity between a given example text and a response text using embeddings. It utilizes the OpenAI API to generate +embeddings for both texts and calculates the distance between them based on a specified metric. ##### Parameters: + - `example`: The example text to compare against. - `metric`: The distance metric to use for comparison. Defaults to `DistanceType.Cosine`. - ##### Methods: -- `matches(api: OpenAIClient, response: String)`: Always returns `true` as it is not used for matching but for scoring based on distance. -- `score(api: OpenAIClient, response: String)`: Calculates and returns the negative distance between the embeddings of the example text and the response text, effectively scoring the response based on its semantic similarity to the example. +- `matches(api: OpenAIClient, response: String)`: Always returns `true` as it is not used for matching but for scoring based on distance. +- `score(api: OpenAIClient, response: String)`: Calculates and returns the negative distance between the embeddings of the example text and the response text, effectively scoring + the response based on its semantic similarity to the example. #### ContainsMatch Class -The `ContainsMatch` class checks if a given pattern (regular expression) is contained within the response text. It is useful for scenarios where the presence of specific patterns or keywords is critical or of interest. - +The `ContainsMatch` class checks if a given pattern (regular expression) is contained within the response text. It is useful for scenarios where the presence of specific patterns +or keywords is critical or of interest. ##### Parameters: + - `pattern`: The regular expression pattern to search for within the response. - `critical`: A boolean indicating if the match is critical. If `false`, `matches` always returns `true`. Defaults to `true`. - ##### Methods: -- `matches(api: OpenAIClient, response: String)`: Returns `true` if the pattern is found in the response and `critical` is `true`, otherwise returns `true` or `false` based on the `critical` flag. -- `score(api: OpenAIClient, response: String)`: Returns `1.0` if the pattern matches the response, otherwise returns `0.0`. +- `matches(api: OpenAIClient, response: String)`: Returns `true` if the pattern is found in the response and `critical` is `true`, otherwise returns `true` or `false` based on the + `critical` flag. +- `score(api: OpenAIClient, response: String)`: Returns `1.0` if the pattern matches the response, otherwise returns `0.0`. ### Usage -To use the Expectation module, instantiate either `VectorMatch` or `ContainsMatch` with the appropriate parameters and call the `matches` and/or `score` methods with an instance of `OpenAIClient` and the response text to evaluate. - +To use the Expectation module, instantiate either `VectorMatch` or `ContainsMatch` with the appropriate parameters and call the `matches` and/or `score` methods with an instance of +`OpenAIClient` and the response text to evaluate. #### Example @@ -626,15 +612,16 @@ val score = expectation.score(apiClient, response) println("Score: $score") ``` -This module provides a powerful and flexible way to evaluate AI model responses, enabling developers to implement custom logic for scoring and matching responses based on semantic similarity or the presence of specific patterns. +This module provides a powerful and flexible way to evaluate AI model responses, enabling developers to implement custom logic for scoring and matching responses based on semantic +similarity or the presence of specific patterns. # ParsedActor.kt - ## ParsedActor Class Documentation -The `ParsedActor` class is a specialized actor designed to parse responses from chat models into specific data types. It extends the functionality of a base actor to not only interact with chat models but also to process the responses into a more structured format. This class is particularly useful when working with chat models to perform specific tasks that require structured output. - +The `ParsedActor` class is a specialized actor designed to parse responses from chat models into specific data types. It extends the functionality of a base actor to not only +interact with chat models but also to process the responses into a more structured format. This class is particularly useful when working with chat models to perform specific tasks +that require structured output. ### Features @@ -643,7 +630,6 @@ The `ParsedActor` class is a specialized actor designed to parse responses from - **Error Handling**: Implements retry logic for deserialization to handle potential parsing errors gracefully. - **Customizable Prompts**: Enables the use of custom prompts for initiating chat model conversations. - ### Constructor Parameters - `parserClass`: The class of the parser function used to convert chat model responses into the desired data type. @@ -654,32 +640,29 @@ The `ParsedActor` class is a specialized actor designed to parse responses from - `parsingModel`: The chat model to use specifically for parsing responses. Defaults to `OpenAIModels.GPT35Turbo`. - `deserializerRetries`: The number of retries for deserialization in case of parsing errors. Defaults to `2`. - ### Methods - #### `chatMessages(questions: List)` -Generates an array of chat messages to be sent to the chat model, including the initial system prompt and user questions. +Generates an array of chat messages to be sent to the chat model, including the initial system prompt and user questions. #### `getParser(api: API)` -Creates and returns a parser function based on the specified parser class and chat model settings. +Creates and returns a parser function based on the specified parser class and chat model settings. #### `respond(input: List, api: API, vararg messages: ApiModel.ChatMessage)` -Processes the given input questions and returns a `ParsedResponse` containing the parsed data type. +Processes the given input questions and returns a `ParsedResponse` containing the parsed data type. #### `withModel(model: ChatModels)` -Creates a new instance of `ParsedActor` with the specified chat model, retaining other settings. +Creates a new instance of `ParsedActor` with the specified chat model, retaining other settings. ### Inner Classes - #### `ParsedResponseImpl` -An implementation of `ParsedResponse` that holds the parsed object and the original text response from the chat model. +An implementation of `ParsedResponse` that holds the parsed object and the original text response from the chat model. ### Usage Example @@ -701,42 +684,43 @@ val parsedActor = ParsedActor( val response = parsedActor.respond(listOf("Question about X"), api) ``` -This documentation provides an overview of the `ParsedActor` class and its capabilities. For more detailed information on specific methods and parameters, refer to the source code documentation. +This documentation provides an overview of the `ParsedActor` class and its capabilities. For more detailed information on specific methods and parameters, refer to the source code +documentation. # ParsedResponse.kt - ## User Documentation for ParsedResponse Class - ### Overview -The `ParsedResponse` class is an abstract class designed to handle and represent responses parsed from various sources in a structured manner. It is part of the `com.simiacryptus.skyenet.core.actors` package. This class is generic and can be used to represent any type of parsed data by specifying the type parameter `T` during implementation. The class is designed to encapsulate both the raw text of the response and its parsed object representation. - +The `ParsedResponse` class is an abstract class designed to handle and represent responses parsed from various sources in a structured manner. It is part of the +`com.simiacryptus.skyenet.core.actors` package. This class is generic and can be used to represent any type of parsed data by specifying the type parameter `T` during +implementation. The class is designed to encapsulate both the raw text of the response and its parsed object representation. ### Key Features -- **Type-Safe Responses**: By specifying the type parameter `T`, users can ensure that the responses handled by instances of `ParsedResponse` are type-safe, making the code more robust and easier to maintain. -- **Dual Representation**: The class stores both the raw text of the response (`text`) and its object representation (`obj`), allowing users to access the data in the format most convenient for their needs. -- **Abstract Design**: Being an abstract class, `ParsedResponse` serves as a template for creating more specific response handlers tailored to particular data types or parsing requirements. - +- **Type-Safe Responses**: By specifying the type parameter `T`, users can ensure that the responses handled by instances of `ParsedResponse` are type-safe, making the code more + robust and easier to maintain. +- **Dual Representation**: The class stores both the raw text of the response (`text`) and its object representation (`obj`), allowing users to access the data in the format most + convenient for their needs. +- **Abstract Design**: Being an abstract class, `ParsedResponse` serves as a template for creating more specific response handlers tailored to particular data types or parsing + requirements. ### Properties -- `clazz: Class`: The class literal of the type parameter `T`. This property is used to specify the type of the parsed object and is essential for type safety and reflection-based operations. +- `clazz: Class`: The class literal of the type parameter `T`. This property is used to specify the type of the parsed object and is essential for type safety and + reflection-based operations. - `text: String`: An abstract property that should be overridden to return the raw text of the parsed response. - `obj: T`: An abstract property that should be overridden to return the object representation of the parsed response. - ### Methods - `toString()`: Overrides the `toString` method to return the raw text of the response. This method provides a convenient way to access the raw response as a string. - ### Usage -To use the `ParsedResponse` class, you need to extend it with a concrete implementation that specifies the type of the parsed object and provides implementations for the abstract properties `text` and `obj`. - +To use the `ParsedResponse` class, you need to extend it with a concrete implementation that specifies the type of the parsed object and provides implementations for the abstract +properties `text` and `obj`. #### Example @@ -744,39 +728,40 @@ To use the `ParsedResponse` class, you need to extend it with a concrete impleme class JsonResponse(parsedText: String) : ParsedResponse(JSONObject::class.java) { override val text: String = parsedText override val obj: JSONObject = JSONObject(parsedText) - + // Additional functionality specific to JSON responses can be added here } ``` -In this example, `JsonResponse` is a concrete implementation of `ParsedResponse` for handling JSON responses. It specifies `JSONObject` as the type parameter `T` and provides implementations for the `text` and `obj` properties. This class can now be used to handle JSON responses in a type-safe and structured manner. - +In this example, `JsonResponse` is a concrete implementation of `ParsedResponse` for handling JSON responses. It specifies `JSONObject` as the type parameter `T` and provides +implementations for the `text` and `obj` properties. This class can now be used to handle JSON responses in a type-safe and structured manner. ### Conclusion -The `ParsedResponse` class provides a flexible and type-safe framework for handling parsed responses. By extending this class, developers can create customized response handlers that encapsulate both the raw and object representations of responses, tailored to specific data types or parsing requirements. +The `ParsedResponse` class provides a flexible and type-safe framework for handling parsed responses. By extending this class, developers can create customized response handlers +that encapsulate both the raw and object representations of responses, tailored to specific data types or parsing requirements. # record\CodingActorInterceptor.kt - ## CodingActorInterceptor Documentation -The `CodingActorInterceptor` class is a specialized implementation of the `CodingActor` interface, designed to intercept and potentially modify the behavior of another `CodingActor` instance. This class is part of the `com.simiacryptus.skyenet.core.actors.record` package and is intended for use in scenarios where additional processing or logging of the interactions with a `CodingActor` is required. - +The `CodingActorInterceptor` class is a specialized implementation of the `CodingActor` interface, designed to intercept and potentially modify the behavior of another`CodingActor` +instance. This class is part of the `com.simiacryptus.skyenet.core.actors.record` package and is intended for use in scenarios where additional processing or logging of the +interactions with a `CodingActor` is required. ### Features - **Function Interception**: Allows for the interception and modification of the responses generated by the wrapped `CodingActor` instance. - **Compatibility**: Seamlessly integrates with existing `CodingActor` instances without requiring changes to their implementation. -- **Customizable Behavior**: Through the use of a `FunctionWrapper`, users can define custom behavior to be executed before or after the wrapped `CodingActor`'s methods are invoked. - +- **Customizable Behavior**: Through the use of a `FunctionWrapper`, users can define custom behavior to be executed before or after the wrapped `CodingActor`'s methods are + invoked. ### Usage - #### Initialization -To use the `CodingActorInterceptor`, you must first instantiate it with a reference to an existing `CodingActor` instance and a `FunctionWrapper` that defines the interception logic. +To use the `CodingActorInterceptor`, you must first instantiate it with a reference to an existing `CodingActor` instance and a `FunctionWrapper` that defines the interception +logic. ```kotlin val innerActor: CodingActor = // Initialize your CodingActor @@ -784,7 +769,6 @@ val functionInterceptor: FunctionWrapper = // Define your FunctionWrapper val interceptor = CodingActorInterceptor(innerActor, functionInterceptor) ``` - #### Overridden Methods The `CodingActorInterceptor` overrides several methods from the `CodingActor` interface, allowing it to intercept calls to these methods. The key methods are: @@ -793,7 +777,6 @@ The `CodingActorInterceptor` overrides several methods from the `CodingActor` in - `respond(...)`: Intercepts the generation of code responses to code requests. - `execute(...)`: Intercepts the execution of code. - #### Example: Interception Logic The interception logic is defined within the `FunctionWrapper` provided at initialization. This example demonstrates a simple logging wrapper: @@ -809,23 +792,23 @@ val functionInterceptor = FunctionWrapper { args, proceed -> This `FunctionWrapper` logs the arguments before the invocation of the wrapped method and the result after the invocation. - ### Integration -To integrate the `CodingActorInterceptor` into your system, replace direct references to the original `CodingActor` instance with references to the `CodingActorInterceptor` instance. This allows all interactions with the `CodingActor` to be intercepted according to the logic defined in your `FunctionWrapper`. - +To integrate the `CodingActorInterceptor` into your system, replace direct references to the original `CodingActor` instance with references to the `CodingActorInterceptor` +instance. This allows all interactions with the `CodingActor` to be intercepted according to the logic defined in your `FunctionWrapper`. ### Conclusion -The `CodingActorInterceptor` provides a powerful mechanism for augmenting the behavior of `CodingActor` instances, enabling scenarios such as logging, monitoring, and dynamic behavior modification. By leveraging the `FunctionWrapper`, developers can easily inject custom logic into the processing pipeline of a `CodingActor`, enhancing its capabilities and facilitating advanced use cases. +The `CodingActorInterceptor` provides a powerful mechanism for augmenting the behavior of `CodingActor` instances, enabling scenarios such as logging, monitoring, and dynamic +behavior modification. By leveraging the `FunctionWrapper`, developers can easily inject custom logic into the processing pipeline of a `CodingActor`, enhancing its capabilities +and facilitating advanced use cases. # opt\ActorOptimization.kt - ## ActorOptimization Class Documentation -The `ActorOptimization` class is designed to facilitate the optimization of actor responses using genetic algorithms and OpenAI's GPT models. This class allows for the generation, mutation, and recombination of prompts to produce optimized responses based on defined test cases and expectations. - +The `ActorOptimization` class is designed to facilitate the optimization of actor responses using genetic algorithms and OpenAI's GPT models. This class allows for the generation, +mutation, and recombination of prompts to produce optimized responses based on defined test cases and expectations. ### Features @@ -834,10 +817,8 @@ The `ActorOptimization` class is designed to facilitate the optimization of acto - **Customizable Mutation and Recombination**: Allows for the customization of mutation rates and types, as well as recombination logic. - **Test Case Evaluation**: Supports the definition of test cases with expectations to guide the optimization process. - ### Key Components - #### TestCase Class Represents a test case with user messages, expectations, and the number of retries. It is used to evaluate the effectiveness of a prompt. @@ -846,7 +827,6 @@ Represents a test case with user messages, expectations, and the number of retri - `expectations`: A list of expectations to evaluate the response. - `retries`: The number of retries allowed for the test case. - #### GeneticApi Interface Defines the operations for mutating and recombining prompts. @@ -854,15 +834,14 @@ Defines the operations for mutating and recombining prompts. - `mutate`: Mutates a given prompt based on a directive (e.g., Rephrase, Randomize). - `recombine`: Recombines two prompts to produce a new prompt. - #### Main Methods - ##### runGeneticGenerations Runs multiple generations of genetic optimization to improve prompts based on test cases. Parameters: + - `prompts`: Initial list of prompts to optimize. - `testCases`: List of `TestCase` instances to evaluate prompts. - `actorFactory`: Factory function to create actors based on prompts. @@ -872,20 +851,21 @@ Parameters: - `generations`: Number of generations to run. Returns: -- A list of optimized prompts. +- A list of optimized prompts. ##### regenerate Generates a new set of prompts based on progenitors through mutation or recombination. Parameters: + - `progenetors`: List of parent prompts. - `desiredCount`: Desired number of prompts in the new generation. Returns: -- A list of new prompts. +- A list of new prompts. ### Usage Example @@ -911,28 +891,27 @@ val optimizedPrompts = actorOptimization.runGeneticGenerations( println("Optimized Prompts: $optimizedPrompts") ``` - ### Customization You can customize the mutation rate and types by adjusting the `mutationRate` and `mutatonTypes` parameters during the instantiation of the `ActorOptimization` class. - ### Conclusion -The `ActorOptimization` class provides a powerful tool for optimizing conversational prompts using genetic algorithms and OpenAI's GPT models. By defining test cases and expectations, users can iteratively improve prompts to achieve desired responses. +The `ActorOptimization` class provides a powerful tool for optimizing conversational prompts using genetic algorithms and OpenAI's GPT models. By defining test cases and +expectations, users can iteratively improve prompts to achieve desired responses. # record\ImageActorInterceptor.kt - ## User Documentation for ImageActorInterceptor -The `ImageActorInterceptor` class is a specialized component designed to intercept and potentially modify the behavior of an `ImageActor` instance. This class is part of the `com.simiacryptus.skyenet.core.actors.record` package and is intended for advanced users who need to customize or extend the functionality of image generation or processing within a system that utilizes the Skyenet framework. - +The `ImageActorInterceptor` class is a specialized component designed to intercept and potentially modify the behavior of an `ImageActor` instance. This class is part of the +`com.simiacryptus.skyenet.core.actors.record` package and is intended for advanced users who need to customize or extend the functionality of image generation or processing within +a system that utilizes the Skyenet framework. ### Overview -`ImageActorInterceptor` acts as a wrapper around an existing `ImageActor` instance, allowing users to intercept and modify the inputs and outputs of the `ImageActor`'s methods. This is particularly useful for debugging, logging, or applying custom transformations to the data processed by the `ImageActor`. - +`ImageActorInterceptor` acts as a wrapper around an existing `ImageActor` instance, allowing users to intercept and modify the inputs and outputs of the `ImageActor`'s methods. +This is particularly useful for debugging, logging, or applying custom transformations to the data processed by the `ImageActor`. ### Key Features @@ -940,13 +919,12 @@ The `ImageActorInterceptor` class is a specialized component designed to interce - **Custom Processing**: Enables custom processing of inputs and outputs without modifying the original `ImageActor` code. - **Compatibility**: Seamlessly integrates with existing `ImageActor` instances, preserving their properties and behaviors. - ### Usage - #### Initialization -To use the `ImageActorInterceptor`, you must first have an instance of `ImageActor` that you wish to intercept. You then create an instance of `ImageActorInterceptor` by passing the `ImageActor` instance and a `FunctionWrapper` instance to its constructor. +To use the `ImageActorInterceptor`, you must first have an instance of `ImageActor` that you wish to intercept. You then create an instance of `ImageActorInterceptor` by passing +the `ImageActor` instance and a `FunctionWrapper` instance to its constructor. ```kotlin val originalImageActor = ImageActor(...) @@ -954,10 +932,10 @@ val functionInterceptor = FunctionWrapper(...) val imageActorInterceptor = ImageActorInterceptor(originalImageActor, functionInterceptor) ``` - #### Interception and Custom Processing -The `FunctionWrapper` provided during initialization is responsible for defining how the interception and potential modification of the `ImageActor`'s behavior occur. You must implement the `wrap` method of the `FunctionWrapper` to specify the custom processing logic. +The `FunctionWrapper` provided during initialization is responsible for defining how the interception and potential modification of the `ImageActor`'s behavior occur. You must +implement the `wrap` method of the `FunctionWrapper` to specify the custom processing logic. ```kotlin val functionInterceptor = object : FunctionWrapper { @@ -968,10 +946,8 @@ val functionInterceptor = object : FunctionWrapper { } ``` - #### Methods - ##### `response` Intercepts the `response` method calls of the `ImageActor`, allowing for custom processing of chat messages and model interactions. @@ -980,7 +956,6 @@ Intercepts the `response` method calls of the `ImageActor`, allowing for custom imageActorInterceptor.response(inputMessages, model, api) ``` - ##### `render` Intercepts the `render` method calls of the `ImageActor`, enabling custom processing of text inputs for image rendering. @@ -989,18 +964,18 @@ Intercepts the `render` method calls of the `ImageActor`, enabling custom proces val image = imageActorInterceptor.render(text, api) ``` - ### Conclusion -The `ImageActorInterceptor` provides a powerful mechanism for customizing the behavior of `ImageActor` instances in the Skyenet framework. By leveraging function interception, developers can implement custom logic for processing inputs and outputs, enhancing the flexibility and capabilities of their image generation and processing systems. +The `ImageActorInterceptor` provides a powerful mechanism for customizing the behavior of `ImageActor` instances in the Skyenet framework. By leveraging function interception, +developers can implement custom logic for processing inputs and outputs, enhancing the flexibility and capabilities of their image generation and processing systems. # record\ParsedActorInterceptor.kt - ## ParsedActorInterceptor Documentation -The `ParsedActorInterceptor` class is designed to act as a middleware that intercepts and modifies the behavior of a `ParsedActor` in a flexible manner. It allows for the interception and manipulation of responses generated by the `ParsedActor` through a custom `FunctionWrapper`. This class is part of the `com.simiacryptus.skyenet.core.actors.record` package. - +The `ParsedActorInterceptor` class is designed to act as a middleware that intercepts and modifies the behavior of a `ParsedActor` in a flexible manner. It allows for the +interception and manipulation of responses generated by the `ParsedActor` through a custom `FunctionWrapper`. This class is part of the`com.simiacryptus.skyenet.core.actors.record` +package. ### Features @@ -1009,13 +984,12 @@ The `ParsedActorInterceptor` class is designed to act as a middleware that inter - **Lazy Evaluation**: Employs lazy evaluation for response objects to optimize performance and resource utilization. - **Seamless Integration**: Designed to seamlessly integrate with existing `ParsedActor` instances without requiring significant modifications. - ### Usage - #### Initialization -To initialize a `ParsedActorInterceptor`, you need to provide an instance of `ParsedActor` and a `FunctionWrapper`. The `FunctionWrapper` is responsible for defining how the responses are intercepted and processed. +To initialize a `ParsedActorInterceptor`, you need to provide an instance of `ParsedActor` and a `FunctionWrapper`. The `FunctionWrapper` is responsible for defining how the +responses are intercepted and processed. ```kotlin val parsedActorInterceptor = ParsedActorInterceptor( @@ -1024,10 +998,10 @@ val parsedActorInterceptor = ParsedActorInterceptor( ) ``` - #### Responding to Inputs -The `ParsedActorInterceptor` overrides the `respond` method to intercept the response generation process. It utilizes the provided `FunctionWrapper` to modify or enhance the response based on custom logic. +The `ParsedActorInterceptor` overrides the `respond` method to intercept the response generation process. It utilizes the provided `FunctionWrapper` to modify or enhance the +response based on custom logic. ```kotlin val response = parsedActorInterceptor.respond( @@ -1036,17 +1010,16 @@ val response = parsedActorInterceptor.respond( ) ``` - #### Custom Response Processing -The interceptor uses a lazy evaluation strategy for processing response objects. The actual parsing and processing of the response text into the desired object format are deferred until the `obj` property is accessed. This approach optimizes performance by avoiding unnecessary computations. - +The interceptor uses a lazy evaluation strategy for processing response objects. The actual parsing and processing of the response text into the desired object format are deferred +until the `obj` property is accessed. This approach optimizes performance by avoiding unnecessary computations. ### Key Methods - **respond**: Intercepts the response generation process, allowing for custom processing of inputs and modification of the generated response. -- **response**: A method designed to wrap the response generation process, enabling the interception and modification of responses for a given set of input messages and a specified model. - +- **response**: A method designed to wrap the response generation process, enabling the interception and modification of responses for a given set of input messages and a specified + model. ### Example @@ -1074,18 +1047,18 @@ println(customResponse.text) println(customResponse.obj) ``` - ### Conclusion -The `ParsedActorInterceptor` provides a powerful mechanism for intercepting and modifying the behavior of `ParsedActor` instances. By leveraging custom function wrappers, developers can implement sophisticated logic to enhance and tailor the responses generated by their actors, enabling more dynamic and context-aware applications. +The `ParsedActorInterceptor` provides a powerful mechanism for intercepting and modifying the behavior of `ParsedActor` instances. By leveraging custom function wrappers, +developers can implement sophisticated logic to enhance and tailor the responses generated by their actors, enabling more dynamic and context-aware applications. # record\TextToSpeechActorInterceptor.kt - ## TextToSpeechActorInterceptor Documentation -The `TextToSpeechActorInterceptor` class is a part of the `com.simiacryptus.skyenet.core.actors.record` package, designed to intercept and modify the behavior of a `TextToSpeechActor` instance. This class allows for additional processing or modification of inputs and outputs to the `TextToSpeechActor` through a provided `FunctionWrapper`. It is particularly useful for debugging, logging, or applying custom transformations to the text-to-speech process. - +The `TextToSpeechActorInterceptor` class is a part of the `com.simiacryptus.skyenet.core.actors.record` package, designed to intercept and modify the behavior of a +`TextToSpeechActor` instance. This class allows for additional processing or modification of inputs and outputs to the `TextToSpeechActor` through a provided `FunctionWrapper`. It +is particularly useful for debugging, logging, or applying custom transformations to the text-to-speech process. ### Features @@ -1093,10 +1066,8 @@ The `TextToSpeechActorInterceptor` class is a part of the `com.simiacryptus.skye - **Function Wrapping**: Utilizes a `FunctionWrapper` to apply custom logic around the invocation of the `TextToSpeechActor`'s methods. - **Compatibility**: Seamlessly integrates with existing `TextToSpeechActor` instances without requiring modifications to their implementation. - ### Usage - #### Initialization To use the `TextToSpeechActorInterceptor`, you must first instantiate it with an existing `TextToSpeechActor` and a `FunctionWrapper` that defines the interception logic. @@ -1107,46 +1078,47 @@ val functionInterceptor = FunctionWrapper(/* custom interception logic here */) val interceptor = TextToSpeechActorInterceptor(originalActor, functionInterceptor) ``` - #### Interception -Once the interceptor is initialized, it can be used in place of the original `TextToSpeechActor`. Calls to `response` and `render` will be intercepted according to the logic defined in the `FunctionWrapper`. - +Once the interceptor is initialized, it can be used in place of the original `TextToSpeechActor`. Calls to `response` and `render` will be intercepted according to the logic +defined in the `FunctionWrapper`. ##### Response Interception -The `response` method allows for the interception of chat message processing. The custom logic can modify the input messages or the processing behavior before delegating to the original actor's `response` method. +The `response` method allows for the interception of chat message processing. The custom logic can modify the input messages or the processing behavior before delegating to the +original actor's `response` method. ```kotlin interceptor.response(inputMessages, model, api) ``` - ##### Render Interception -The `render` method enables the interception of text rendering to audio. The interception logic can modify the input text or the rendering behavior before calling the original actor's `render` method. +The `render` method enables the interception of text rendering to audio. The interception logic can modify the input text or the rendering behavior before calling the original +actor's `render` method. ```kotlin val audioBytes = interceptor.render(text, api) ``` - ### Customization -The behavior of the `TextToSpeechActorInterceptor` is largely determined by the `FunctionWrapper` provided during initialization. By implementing custom logic within this wrapper, users can achieve a wide range of effects, from simple logging to complex input/output transformations. - +The behavior of the `TextToSpeechActorInterceptor` is largely determined by the `FunctionWrapper` provided during initialization. By implementing custom logic within this wrapper, +users can achieve a wide range of effects, from simple logging to complex input/output transformations. ### Conclusion -The `TextToSpeechActorInterceptor` provides a powerful and flexible mechanism for augmenting the behavior of `TextToSpeechActor` instances. By leveraging function wrapping, it offers a seamless way to integrate custom logic into the text-to-speech process, making it an invaluable tool for developers looking to extend or customize the functionality of their text-to-speech applications. +The `TextToSpeechActorInterceptor` provides a powerful and flexible mechanism for augmenting the behavior of `TextToSpeechActor` instances. By leveraging function wrapping, it +offers a seamless way to integrate custom logic into the text-to-speech process, making it an invaluable tool for developers looking to extend or customize the functionality of +their text-to-speech applications. # record\SimpleActorInterceptor.kt - ## SimpleActorInterceptor Documentation -The `SimpleActorInterceptor` class is a part of the `com.simiacryptus.skyenet.core.actors.record` package, designed to act as a wrapper around instances of `SimpleActor`. This class allows for the interception and potential modification of function calls, specifically the `response` function of the `SimpleActor` class. It is particularly useful for scenarios where additional processing or logging is required for the inputs and outputs of the `response` function. - +The `SimpleActorInterceptor` class is a part of the `com.simiacryptus.skyenet.core.actors.record` package, designed to act as a wrapper around instances of `SimpleActor`. This +class allows for the interception and potential modification of function calls, specifically the `response` function of the `SimpleActor` class. It is particularly useful for +scenarios where additional processing or logging is required for the inputs and outputs of the `response` function. ### Features @@ -1154,11 +1126,10 @@ The `SimpleActorInterceptor` class is a part of the `com.simiacryptus.skyenet.co - **Custom Processing**: Through the use of a `FunctionWrapper`, custom logic can be applied to the inputs and outputs of the `response` function. - **Seamless Integration**: Inherits from `SimpleActor`, ensuring compatibility and ease of integration with existing systems that utilize `SimpleActor` instances. - ### Usage -To use the `SimpleActorInterceptor`, you must first have an instance of `SimpleActor` that you wish to wrap. You will also need to define or have a `FunctionWrapper` that specifies the custom logic to be applied during the interception. - +To use the `SimpleActorInterceptor`, you must first have an instance of `SimpleActor` that you wish to wrap. You will also need to define or have a `FunctionWrapper` that specifies +the custom logic to be applied during the interception. #### Example @@ -1181,13 +1152,13 @@ val simpleActor = SimpleActor( val functionInterceptor = FunctionWrapper { input, model, function -> // Custom pre-processing logic here println("Before calling response: $input") - + // Call the original function val result = function(input, model) - + // Custom post-processing logic here println("After calling response") - + // Return the result result } @@ -1199,52 +1170,51 @@ val interceptor = SimpleActorInterceptor(simpleActor, functionInterceptor) // The interceptor will apply your custom logic before and after calling the response function ``` - ### Parameters - `inner`: The `SimpleActor` instance that is being wrapped. - `functionInterceptor`: An instance of `FunctionWrapper` that defines the custom logic to be applied during the interception. - ### Methods -- `response(vararg input: com.simiacryptus.jopenai.ApiModel.ChatMessage, model: OpenAIModel, api: API)`: Overrides the `response` method of `SimpleActor` to apply the custom logic defined in `functionInterceptor` before and after the original `response` function is called. - +- `response(vararg input: com.simiacryptus.jopenai.ApiModel.ChatMessage, model: OpenAIModel, api: API)`: Overrides the `response` method of `SimpleActor` to apply the custom logic + defined in `functionInterceptor` before and after the original `response` function is called. ### Conclusion -The `SimpleActorInterceptor` class provides a powerful way to add custom processing logic to the inputs and outputs of the `response` function of `SimpleActor` instances. By leveraging the `FunctionWrapper`, developers can easily implement custom pre-processing and post-processing logic to enhance the functionality of their `SimpleActor` instances. +The `SimpleActorInterceptor` class provides a powerful way to add custom processing logic to the inputs and outputs of the `response` function of `SimpleActor` instances. By +leveraging the `FunctionWrapper`, developers can easily implement custom pre-processing and post-processing logic to enhance the functionality of their `SimpleActor` instances. # test\ImageActorTestBase.kt - ## User Documentation for ImageActorTestBase - ### Overview -The `ImageActorTestBase` class is part of the testing framework for the `ImageActor` component within the Skyenet project. This abstract class extends `ActorTestBase`, specifically tailored for testing actors that process a list of strings as input and produce an `ImageResponse`. It provides a foundational setup for creating and testing instances of `ImageActor` based on different prompts. - +The `ImageActorTestBase` class is part of the testing framework for the `ImageActor` component within the Skyenet project. This abstract class extends `ActorTestBase`, specifically +tailored for testing actors that process a list of strings as input and produce an `ImageResponse`. It provides a foundational setup for creating and testing instances of +`ImageActor` based on different prompts. ### Key Features - **Abstract Testing Framework**: Designed to facilitate the testing of `ImageActor` instances, ensuring they function as expected when given various prompts. - **Prompt-Based Actor Factory**: Implements a method to instantiate `ImageActor` objects using specific prompts, allowing for flexible testing scenarios. - ### Getting Started To utilize `ImageActorTestBase` in your testing suite, follow these steps: -1. **Extend `ImageActorTestBase`**: Since `ImageActorTestBase` is an abstract class, you'll need to create a concrete subclass that implements any abstract methods (if any exist beyond those implemented in `ActorTestBase`). +1. **Extend `ImageActorTestBase`**: Since `ImageActorTestBase` is an abstract class, you'll need to create a concrete subclass that implements any abstract methods (if any exist + beyond those implemented in `ActorTestBase`). -2. **Implement Required Methods**: Ensure all abstract methods inherited from `ActorTestBase` are implemented. In the case of `ImageActorTestBase`, the `actorFactory` method is already implemented, but you may need to provide implementations for other abstract methods depending on your specific testing needs. +2. **Implement Required Methods**: Ensure all abstract methods inherited from `ActorTestBase` are implemented. In the case of `ImageActorTestBase`, the `actorFactory` method is + already implemented, but you may need to provide implementations for other abstract methods depending on your specific testing needs. -3. **Define Test Cases**: Create test cases within your subclass that utilize the `actorFactory` method to generate `ImageActor` instances with various prompts. These instances can then be used to verify the actor's response to different inputs. +3. **Define Test Cases**: Create test cases within your subclass that utilize the `actorFactory` method to generate `ImageActor` instances with various prompts. These instances can + then be used to verify the actor's response to different inputs. 4. **Run Tests**: Execute your tests to validate the behavior of `ImageActor` instances. This can help identify any issues or unexpected behavior in the actor's implementation. - ### Example Usage Below is a hypothetical example of how one might extend `ImageActorTestBase` to create a specific test suite for `ImageActor`: @@ -1264,7 +1234,7 @@ class MyImageActorTests : ImageActorTestBase() { val prompt = "A sample prompt" val imageActor = actorFactory(prompt) val response = imageActor.process(listOf(prompt)) - + // Perform assertions on the response Assert.assertNotNull("The response should not be null", response) Assert.assertTrue("The response should be of type ImageResponse", response is ImageResponse) @@ -1273,47 +1243,49 @@ class MyImageActorTests : ImageActorTestBase() { } ``` -In this example, `MyImageActorTests` extends `ImageActorTestBase` and defines a test case that checks whether `ImageActor` produces a non-null response of the correct type when given a sample prompt. - +In this example, `MyImageActorTests` extends `ImageActorTestBase` and defines a test case that checks whether `ImageActor` produces a non-null response of the correct type when +given a sample prompt. ### Conclusion -`ImageActorTestBase` provides a structured approach to testing `ImageActor` instances within the Skyenet project. By extending this class and implementing specific test cases, developers can ensure their image processing actors behave as expected across a variety of scenarios. +`ImageActorTestBase` provides a structured approach to testing `ImageActor` instances within the Skyenet project. By extending this class and implementing specific test cases, +developers can ensure their image processing actors behave as expected across a variety of scenarios. # test\CodingActorTestBase.kt - ## CodingActorTestBase Documentation -The `CodingActorTestBase` class is an abstract base class designed for testing coding actors in the Skyenet framework. It extends the functionality of `ActorTestBase` by specifically catering to actors that generate or interpret code, providing a streamlined way to create, test, and evaluate coding actors. - +The `CodingActorTestBase` class is an abstract base class designed for testing coding actors in the Skyenet framework. It extends the functionality of `ActorTestBase` by +specifically catering to actors that generate or interpret code, providing a streamlined way to create, test, and evaluate coding actors. ### Overview -Coding actors are specialized actors within the Skyenet framework that deal with generating or interpreting code based on given prompts. The `CodingActorTestBase` class facilitates the testing of these actors by setting up a common testing infrastructure that includes creating actors, sending prompts, and evaluating the generated code. - +Coding actors are specialized actors within the Skyenet framework that deal with generating or interpreting code based on given prompts. The `CodingActorTestBase` class facilitates +the testing of these actors by setting up a common testing infrastructure that includes creating actors, sending prompts, and evaluating the generated code. ### Key Components - #### Properties -- `abstract val interpreterClass: KClass`: This abstract property must be implemented by subclasses to specify the class of the interpreter that the coding actor should use. The interpreter class must extend the `Interpreter` interface. - +- `abstract val interpreterClass: KClass`: This abstract property must be implemented by subclasses to specify the class of the interpreter that the coding actor + should use. The interpreter class must extend the `Interpreter` interface. #### Methods -- `actorFactory(prompt: String): CodingActor`: This method overrides the `actorFactory` method from `ActorTestBase`. It is responsible for creating an instance of `CodingActor` with the specified interpreter class and details (prompt). This allows for the dynamic creation of coding actors based on the test requirements. - -- `getPrompt(actor: BaseActor): String`: This method overrides the `getPrompt` method from `ActorTestBase`. It retrieves the prompt (details) from the given coding actor. This prompt is what the actor uses to generate or interpret code. +- `actorFactory(prompt: String): CodingActor`: This method overrides the `actorFactory` method from `ActorTestBase`. It is responsible for creating an instance of `CodingActor`with + the specified interpreter class and details (prompt). This allows for the dynamic creation of coding actors based on the test requirements. -- `resultMapper(result: CodeResult): String`: This method overrides the `resultMapper` method from `ActorTestBase`. It maps the `CodeResult` (the output of the coding actor) to a string representation of the code. This is useful for evaluating the actor's output or for further processing. +- `getPrompt(actor: BaseActor): String`: This method overrides the `getPrompt` method from `ActorTestBase`. It retrieves the prompt (details) + from the given coding actor. This prompt is what the actor uses to generate or interpret code. +- `resultMapper(result: CodeResult): String`: This method overrides the `resultMapper` method from `ActorTestBase`. It maps the `CodeResult` (the output of the coding actor) to a + string representation of the code. This is useful for evaluating the actor's output or for further processing. ### Usage -To use the `CodingActorTestBase`, you need to create a subclass that implements the `interpreterClass` property. This subclass will specify the interpreter that the coding actors should use during testing. Once the subclass is defined, you can create instances of your coding actors by providing prompts, and then use the provided methods to test and evaluate their code generation capabilities. - +To use the `CodingActorTestBase`, you need to create a subclass that implements the `interpreterClass` property. This subclass will specify the interpreter that the coding actors +should use during testing. Once the subclass is defined, you can create instances of your coding actors by providing prompts, and then use the provided methods to test and evaluate +their code generation capabilities. #### Example @@ -1330,20 +1302,20 @@ class MyCodingActorTest : CodingActorTestBase() { } ``` -In this example, `MyCodingActorTest` extends `CodingActorTestBase` and specifies `MyInterpreter` as the interpreter class. It includes a test method that creates a coding actor with a given prompt, generates code based on that prompt, and then prints the generated code. - +In this example, `MyCodingActorTest` extends `CodingActorTestBase` and specifies `MyInterpreter` as the interpreter class. It includes a test method that creates a coding actor +with a given prompt, generates code based on that prompt, and then prints the generated code. ### Conclusion -The `CodingActorTestBase` class provides a foundational framework for testing coding actors within the Skyenet framework. By abstracting common tasks such as actor creation, prompt handling, and result mapping, it simplifies the process of developing and testing coding actors. +The `CodingActorTestBase` class provides a foundational framework for testing coding actors within the Skyenet framework. By abstracting common tasks such as actor creation, prompt +handling, and result mapping, it simplifies the process of developing and testing coding actors. # SimpleActor.kt - ## SimpleActor Class Documentation -The `SimpleActor` class is part of the `com.simiacryptus.skyenet.core.actors` package and extends the functionality of the `BaseActor` class. It is designed to facilitate easy interaction with OpenAI's GPT models through the `com.simiacryptus.jopenai` API. This class simplifies the process of sending prompts to the model and receiving responses. - +The `SimpleActor` class is part of the `com.simiacryptus.skyenet.core.actors` package and extends the functionality of the `BaseActor` class. It is designed to facilitate easy +interaction with OpenAI's GPT models through the `com.simiacryptus.jopenai` API. This class simplifies the process of sending prompts to the model and receiving responses. ### Constructor Parameters @@ -1352,10 +1324,8 @@ The `SimpleActor` class is part of the `com.simiacryptus.skyenet.core.actors` pa - `model`: Specifies the model to be used for generating responses. It defaults to `OpenAIModels.GPT35Turbo`. - `temperature`: A `Double` value that controls the randomness of the model's responses. Lower values make the model more deterministic. It defaults to `0.3`. - ### Methods - #### respond ```kotlin @@ -1372,7 +1342,6 @@ Generates a response based on the provided input and messages. **Throws**: `RuntimeException` if no response is received from the model. - #### chatMessages ```kotlin @@ -1385,7 +1354,6 @@ Converts a list of questions into an array of `ApiModel.ChatMessage`, including **Returns**: An array of `ApiModel.ChatMessage` ready to be sent to the model. - #### withModel ```kotlin @@ -1398,7 +1366,6 @@ Creates a new instance of `SimpleActor` with the specified model while retaining **Returns**: A new instance of `SimpleActor` configured with the specified model. - ### Usage Example ```kotlin @@ -1419,20 +1386,18 @@ This example demonstrates how to create an instance of `SimpleActor`, initialize # test\ActorTestBase.kt - ## ActorTestBase Documentation -The `ActorTestBase` class is an abstract class designed to facilitate the testing of actors within a system. It provides a structured way to optimize and test actors through predefined test cases and optimization strategies. This class is part of the `com.simiacryptus.skyenet.core.actors.test` package. - +The `ActorTestBase` class is an abstract class designed to facilitate the testing of actors within a system. It provides a structured way to optimize and test actors through +predefined test cases and optimization strategies. This class is part of the `com.simiacryptus.skyenet.core.actors.test` package. ### Overview -The `ActorTestBase` class serves as a foundation for testing different types of actors. An actor, in this context, refers to a component that takes input, performs some processing, and produces output. The class is designed to be extended by concrete test classes that specify the behavior of the actors being tested. - +The `ActorTestBase` class serves as a foundation for testing different types of actors. An actor, in this context, refers to a component that takes input, performs some processing, +and produces output. The class is designed to be extended by concrete test classes that specify the behavior of the actors being tested. ### Key Components - #### Properties - `api`: An instance of `OpenAIClient` used for making API calls. It is initialized with a debug log level. @@ -1440,41 +1405,38 @@ The `ActorTestBase` class serves as a foundation for testing different types of - `actor`: An abstract property representing the actor being tested. - `actorFactory`: An abstract function that takes a prompt string and returns a new instance of the actor. - #### Methods - ##### `opt()` -This method runs the optimization process for the actor. It uses genetic algorithms to evolve the actor based on the provided test cases. The method parameters allow for customization of the optimization process, including specifying a different actor or test cases. +This method runs the optimization process for the actor. It uses genetic algorithms to evolve the actor based on the provided test cases. The method parameters allow for +customization of the optimization process, including specifying a different actor or test cases. Parameters: + - `actor`: The actor to optimize. Defaults to the actor defined in the class. - `testCases`: The test cases to use for optimization. Defaults to the test cases defined in the class. - `actorFactory`: A factory function to create new actor instances. Defaults to the `actorFactory` method defined in the class. - `resultMapper`: A function to map the actor's output to a string. Defaults to the `resultMapper` method defined in the class. - ##### `testOptimize()` A convenience method that calls the `opt()` method with default parameters. It starts the optimization process for the actor using the predefined test cases and actor factory. - ##### `testRun()` -This method iterates over the test cases and tests the actor's response to each case. It constructs the input messages for the actor, calls the `answer()` method to get the actor's response, and logs the result. - +This method iterates over the test cases and tests the actor's response to each case. It constructs the input messages for the actor, calls the `answer()` method to get the actor's +response, and logs the result. ##### `answer()` -Takes an array of `ApiModel.ChatMessage` objects as input and returns the actor's response. This method is responsible for converting the chat messages into the appropriate input format for the actor, calling the actor's `respond()` method, and returning the result. - +Takes an array of `ApiModel.ChatMessage` objects as input and returns the actor's response. This method is responsible for converting the chat messages into the appropriate input +format for the actor, calling the actor's `respond()` method, and returning the result. #### Companion Object Contains a logger instance for logging information related to the test execution. - ### Usage To use the `ActorTestBase` class, you need to extend it with a concrete class that specifies the actor and test cases. Here's a simplified example: @@ -1498,32 +1460,32 @@ class MyActorTest : ActorTestBase() { } ``` -In this example, you would replace `MyInputType` and `MyResultType` with the actual types used by your actor. You would also implement the abstract methods to provide the necessary functionality for testing your actor. +In this example, you would replace `MyInputType` and `MyResultType` with the actual types used by your actor. You would also implement the abstract methods to provide the necessary +functionality for testing your actor. # test\ParsedActorTestBase.kt - ## User Documentation for ParsedActorTestBase -The `ParsedActorTestBase` class is an abstract class designed to facilitate the testing of actors that parse responses using a specified parser. This class is part of the `com.simiacryptus.skyenet.core.actors.test` package and extends the functionality provided by `ActorTestBase`. It is tailored for use with actors that take a list of strings as input and produce a `ParsedResponse` object containing a generic type `T`. - +The `ParsedActorTestBase` class is an abstract class designed to facilitate the testing of actors that parse responses using a specified parser. This class is part of the +`com.simiacryptus.skyenet.core.actors.test` package and extends the functionality provided by `ActorTestBase`. It is tailored for use with actors that take a list of strings as +input and produce a `ParsedResponse` object containing a generic type `T`. ### Overview -The `ParsedActorTestBase` class is designed to streamline the process of testing parsed actors by providing a structured framework. It abstracts away common testing functionalities, allowing developers to focus on the specifics of their parsed actor implementations. The class requires specifying the type of parser to be used for parsing responses through the `parserClass` parameter. - +The `ParsedActorTestBase` class is designed to streamline the process of testing parsed actors by providing a structured framework. It abstracts away common testing +functionalities, allowing developers to focus on the specifics of their parsed actor implementations. The class requires specifying the type of parser to be used for parsing +responses through the `parserClass` parameter. ### Key Components - #### Constructor Parameters -- `parserClass`: This parameter expects a class that implements the `Function` interface. It defines the parser that will be used to parse the responses from the actor. The parser class should take a string as input and return an instance of type `T`. - +- `parserClass`: This parameter expects a class that implements the `Function` interface. It defines the parser that will be used to parse the responses from the actor. + The parser class should take a string as input and return an instance of type `T`. #### Methods - ##### actorFactory ```kotlin @@ -1532,22 +1494,20 @@ override fun actorFactory(prompt: String): ParsedActor - **Description**: Creates an instance of `ParsedActor` with the specified prompt and parser class. The parsing model is set to `OpenAIModels.GPT35Turbo` by default. - **Parameters**: - - `prompt`: A string representing the prompt to be used by the actor. + - `prompt`: A string representing the prompt to be used by the actor. - **Returns**: An instance of `ParsedActor` configured with the provided prompt and parser. - ##### getPrompt ```kotlin -override fun getPrompt(actor: BaseActor,ParsedResponse>): String +override fun getPrompt(actor: BaseActor, ParsedResponse>): String ``` - **Description**: Retrieves the prompt associated with the given actor. - **Parameters**: - - `actor`: The actor whose prompt is to be retrieved. + - `actor`: The actor whose prompt is to be retrieved. - **Returns**: The prompt string used by the specified actor. - ##### resultMapper ```kotlin @@ -1556,14 +1516,13 @@ override fun resultMapper(result: ParsedResponse): String - **Description**: Maps the `ParsedResponse` object to a string representation. This method is used to extract the text content from the `ParsedResponse` object. - **Parameters**: - - `result`: The `ParsedResponse` object containing the parsed result. + - `result`: The `ParsedResponse` object containing the parsed result. - **Returns**: A string representation of the parsed result. - ### Usage -To use the `ParsedActorTestBase` class, you need to extend it in your test class and specify the type of the parser class as well as the generic type `T` that your parser returns. You will also need to implement any abstract methods if required. - +To use the `ParsedActorTestBase` class, you need to extend it in your test class and specify the type of the parser class as well as the generic type `T` that your parser returns. +You will also need to implement any abstract methods if required. #### Example @@ -1573,20 +1532,20 @@ class MyActorTest : ParsedActorTestBase(MyResponseParser::class. } ``` -In this example, `MyResponseType` is the type returned by the parser, and `MyResponseParser` is the class that implements the `Function` interface to parse the actor's responses. - +In this example, `MyResponseType` is the type returned by the parser, and `MyResponseParser` is the class that implements the `Function` interface to parse +the actor's responses. ### Conclusion -The `ParsedActorTestBase` class provides a structured and efficient way to test actors that require response parsing. By abstracting common functionalities and providing a clear framework, it simplifies the testing process and allows developers to focus on the specifics of their actor implementations. +The `ParsedActorTestBase` class provides a structured and efficient way to test actors that require response parsing. By abstracting common functionalities and providing a clear +framework, it simplifies the testing process and allows developers to focus on the specifics of their actor implementations. # TextToSpeechActor.kt - ## TextToSpeechActor Documentation -The `TextToSpeechActor` class is a part of the `com.simiacryptus.skyenet.core.actors` package, designed to convert text into speech using OpenAI's API. This class extends the `BaseActor` class, allowing it to process lists of strings and generate speech responses. - +The `TextToSpeechActor` class is a part of the `com.simiacryptus.skyenet.core.actors` package, designed to convert text into speech using OpenAI's API. This class extends the +`BaseActor` class, allowing it to process lists of strings and generate speech responses. ### Features @@ -1594,7 +1553,6 @@ The `TextToSpeechActor` class is a part of the `com.simiacryptus.skyenet.core.ac - **Support for Different Audio Models**: The class supports various audio models provided by OpenAI. - **Lazy Loading of Speech Data**: The speech data is loaded lazily, meaning it's only processed when needed, optimizing resource usage. - ### Constructor Parameters - `name`: Optional. The name of the actor. @@ -1602,10 +1560,8 @@ The `TextToSpeechActor` class is a part of the `com.simiacryptus.skyenet.core.ac - `voice`: The voice to be used. Defaults to `"alloy"`. - `speed`: The speed of the speech. Defaults to `1.0`. - ### Methods - #### `chatMessages(questions: List)` Converts a list of questions into an array of `ChatMessage` objects, which are then used by the OpenAI API for processing. @@ -1613,28 +1569,25 @@ Converts a list of questions into an array of `ChatMessage` objects, which are t - **Parameters**: `questions` - A list of strings representing the questions or text to be converted into speech. - **Returns**: An array of `ChatMessage` objects. - #### `render(text: String, api: API)` Converts the given text into speech data using the specified OpenAI API client. - **Parameters**: - - `text`: The text to be converted into speech. - - `api`: The OpenAI API client to use for the conversion. + - `text`: The text to be converted into speech. + - `api`: The OpenAI API client to use for the conversion. - **Returns**: A byte array containing the speech data. - #### `respond(input: List, api: API, vararg messages: ChatMessage)` Processes the input text and generates a `SpeechResponse` containing the speech data. - **Parameters**: - - `input`: A list of strings to be processed. - - `api`: The OpenAI API client to use for processing. - - `messages`: Additional chat messages to consider in the processing. + - `input`: A list of strings to be processed. + - `api`: The OpenAI API client to use for processing. + - `messages`: Additional chat messages to consider in the processing. - **Returns**: A `SpeechResponseImpl` object containing the speech data. - #### `withModel(model: AudioModels)` Creates a new instance of `TextToSpeechActor` with the specified audio model. @@ -1642,17 +1595,14 @@ Creates a new instance of `TextToSpeechActor` with the specified audio model. - **Parameters**: `model` - The audio model to use. - **Returns**: A new instance of `TextToSpeechActor`. - ### Interfaces - #### `SpeechResponse` An interface representing the response from the text-to-speech conversion. - **Properties**: - - `mp3data`: A byte array containing the MP3 data of the converted speech. - + - `mp3data`: A byte array containing the MP3 data of the converted speech. ### Usage Example @@ -1666,5 +1616,6 @@ val speechResponse = ttsActor.respond(questions, apiClient) val mp3Data = speechResponse.mp3data ``` -This example demonstrates how to create an instance of `TextToSpeechActor`, process a list of questions, and access the generated speech data. Remember to replace `"your_api_key_here"` with your actual OpenAI API key. +This example demonstrates how to create an instance of `TextToSpeechActor`, process a list of questions, and access the generated speech data. Remember to replace +`"your_api_key_here"` with your actual OpenAI API key. diff --git a/docs/patch.md b/docs/patch.md index 60b7e7bb..98b5bb61 100644 --- a/docs/patch.md +++ b/docs/patch.md @@ -287,7 +287,6 @@ blocks and appends links that allow users to save the code to files. 3. **Save File**: Adds a link to save the code block to a file. If the file is saved successfully, updates the link text to "Saved ". - ## Patch Verification Process The patch verification process ensures that the applied diff is correct and consistent. It involves the following steps: diff --git a/docs/path_structure.md b/docs/path_structure.md index 77253e37..ae768b9c 100644 --- a/docs/path_structure.md +++ b/docs/path_structure.md @@ -2,7 +2,8 @@ Based on the provided code, here's a document detailing the servlet path layout # Servlet Path Layout -The application uses a hierarchical structure for its servlet paths, with different functionalities mapped to specific URLs. Below is a breakdown of the main servlet paths and their purposes: +The application uses a hierarchical structure for its servlet paths, with different functionalities mapped to specific URLs. Below is a breakdown of the main servlet paths and +their purposes: ## Root Level Paths @@ -46,9 +47,11 @@ Within each application-specific path, the following common servlets are typical ## Notes * The exact paths may vary depending on the specific implementation of each `ApplicationServer` instance. -* Some paths (like `/userInfo` and `/usage`) appear both at the root level and within application-specific contexts. The application-specific versions may provide more tailored information. +* Some paths (like `/userInfo` and `/usage`) appear both at the root level and within application-specific contexts. The application-specific versions may provide more tailored + information. * The application uses filters for Cross-Origin Resource Sharing (CORS) and authentication/authorization checks. * WebSocket support is configured for real-time communication. * The server is set up to handle both HTTP and HTTPS connections, with the latter being used when running in server mode. -This layout provides a comprehensive structure for handling various aspects of the application, from user management and authentication to application-specific functionalities and session handling. +This layout provides a comprehensive structure for handling various aspects of the application, from user management and authentication to application-specific functionalities and +session handling. diff --git a/docs/planning_agent.md b/docs/planning_agent.md index 115bef2f..f04c5f95 100644 --- a/docs/planning_agent.md +++ b/docs/planning_agent.md @@ -5,36 +5,38 @@ effectively utilizing and extending the functionality provided by the `com.simia guide covers everything from high-level overviews to detailed implementation insights. + * [**Plan Feature User and Developer Guide**](#plan-feature-user-and-developer-guide) - * [**Introduction**](#introduction) - * [**Features Overview**](#features-overview) - * [**User Guide**](#user-guide) - * [**Accessing the Plan Feature**](#accessing-the-plan-feature) - * [**Creating and Managing Plans**](#creating-and-managing-plans) - * [**Understanding Task Dependencies**](#understanding-task-dependencies) - * [**Viewing Execution Logs**](#viewing-execution-logs) - * [**Developer Guide**](#developer-guide) - * [**Architecture Overview**](#architecture-overview) - * [**Task Types**](#task-types) - * [**1. CommandAutoFixTask**](#1-commandautofixtask) - * [**2. InquiryTask**](#2-inquirytask) - * [**3. FileModificationTask**](#3-filemodificationtask) - * [**4. RunShellCommandTask**](#4-runshellcommandtask) - * [**5. RefactorTask**](#5-refactortask) - * [**6. SecurityAuditTask**](#6-securityaudittask) - * [**7. CodeOptimizationTask**](#7-codeoptimizationtask) - * [**8. CodeReviewTask**](#8-codereviewtask) - * [**9. DocumentationTask**](#9-documentationtask) - * [**10. TestGenerationTask**](#10-testgenerationtask) - * [**Adding New Task Types**](#adding-new-task-types) - * [**Configuring Plan Settings**](#configuring-plan-settings) - * [**Extending PlanCoordinator**](#extending-plancoordinator) - * [**Utilizing PlanUtil**](#utilizing-planutil) - * [**Handling Asynchronous Task Execution**](#handling-asynchronous-task-execution) - * [**Customizing Task Execution**](#customizing-task-execution) - * [**Best Practices**](#best-practices) - * [**Troubleshooting**](#troubleshooting) - * [**Frequently Asked Questions (FAQs)**](#frequently-asked-questions-faqs) + * [**Introduction**](#introduction) + * [**Features Overview**](#features-overview) + * [**User Guide**](#user-guide) + * [**Accessing the Plan Feature**](#accessing-the-plan-feature) + * [**Creating and Managing Plans**](#creating-and-managing-plans) + * [**Understanding Task Dependencies**](#understanding-task-dependencies) + * [**Viewing Execution Logs**](#viewing-execution-logs) + * [**Developer Guide**](#developer-guide) + * [**Architecture Overview**](#architecture-overview) + * [**Task Types**](#task-types) + * [**1. CommandAutoFixTask**](#1-commandautofixtask) + * [**2. InquiryTask**](#2-inquirytask) + * [**3. FileModificationTask**](#3-filemodificationtask) + * [**4. RunShellCommandTask**](#4-runshellcommandtask) + * [**5. RefactorTask**](#5-refactortask) + * [**6. SecurityAuditTask**](#6-securityaudittask) + * [**7. CodeOptimizationTask**](#7-codeoptimizationtask) + * [**8. CodeReviewTask**](#8-codereviewtask) + * [**9. DocumentationTask**](#9-documentationtask) + * [**10. TestGenerationTask**](#10-testgenerationtask) + * [**Adding New Task Types**](#adding-new-task-types) + * [**Configuring Plan Settings**](#configuring-plan-settings) + * [**Extending PlanCoordinator**](#extending-plancoordinator) + * [**Utilizing PlanUtil**](#utilizing-planutil) + * [**Handling Asynchronous Task Execution**](#handling-asynchronous-task-execution) + * [**Customizing Task Execution**](#customizing-task-execution) + * [**Best Practices**](#best-practices) + * [**Troubleshooting**](#troubleshooting) + * [**Frequently Asked Questions (FAQs)**](#frequently-asked-questions-faqs) + ## **Introduction** @@ -90,24 +92,24 @@ are exposed. This could be within a web UI or another integrated platform provid ### **Understanding Task Dependencies** * **Visual Representation:** - * The Plan feature utilizes Mermaid to render task dependency graphs. - * Access the "Task Dependency Graph" section to visualize how tasks interrelate. + * The Plan feature utilizes Mermaid to render task dependency graphs. + * Access the "Task Dependency Graph" section to visualize how tasks interrelate. * **Interpreting the Graph:** - * Nodes represent individual tasks. - * Arrows indicate dependencies; a task will only execute after its dependent tasks are completed. - * Styles (e.g., color-coding) indicate the state of each task (Pending, In Progress, Completed). + * Nodes represent individual tasks. + * Arrows indicate dependencies; a task will only execute after its dependent tasks are completed. + * Styles (e.g., color-coding) indicate the state of each task (Pending, In Progress, Completed). ### **Viewing Execution Logs** * **Accessing Logs:** - * Execution logs are automatically generated and can be accessed through the UI. - * Logs provide detailed information about each task's execution, including API interactions and any errors - encountered. + * Execution logs are automatically generated and can be accessed through the UI. + * Logs provide detailed information about each task's execution, including API interactions and any errors + encountered. * **Log Files:** - * Logs are stored in the `.logs` directory within your working directory. - * Each task execution generates a unique log file for traceability. + * Logs are stored in the `.logs` directory within your working directory. + * Each task execution generates a unique log file for traceability. --- @@ -143,23 +145,23 @@ associated with a specific constructor that defines how the task is instantiated * **Functionality:** - * **Command Execution:** Runs a user-specified command with provided arguments. - * **Automatic Fixing:** Analyzes the command's output and applies fixes if issues are detected. - * **Configurability:** Allows customization of available commands and auto-fix behavior through `PlanSettings`. - * **Logging and Notifications:** Logs the execution results and notifies users of successes or failures. + * **Command Execution:** Runs a user-specified command with provided arguments. + * **Automatic Fixing:** Analyzes the command's output and applies fixes if issues are detected. + * **Configurability:** Allows customization of available commands and auto-fix behavior through `PlanSettings`. + * **Logging and Notifications:** Logs the execution results and notifies users of successes or failures. * **Key Components:** - * **`planSettings.commandAutoFixCommands`:** A list of available commands that can be auto-fixed. - * **`CmdPatchApp`:** Utilized to execute the command and handle patching based on the output. - * **Semaphore Mechanism:** Ensures that the task waits for the command execution and auto-fixing process to complete - before proceeding. + * **`planSettings.commandAutoFixCommands`:** A list of available commands that can be auto-fixed. + * **`CmdPatchApp`:** Utilized to execute the command and handle patching based on the output. + * **Semaphore Mechanism:** Ensures that the task waits for the command execution and auto-fixing process to complete + before proceeding. * **Configuration:** - * **Available Commands:** Defined in `PlanSettings.kt` under `commandAutoFixCommands`. Developers can add or remove - commands as needed. - * **Auto-Fix Toggle:** Controlled via `planSettings.autoFix` to enable or disable automatic fixing. + * **Available Commands:** Defined in `PlanSettings.kt` under `commandAutoFixCommands`. Developers can add or remove + commands as needed. + * **Auto-Fix Toggle:** Controlled via `planSettings.autoFix` to enable or disable automatic fixing. **Implementation Details:** @@ -172,9 +174,9 @@ The `run` method orchestrates the execution by: * **Extending the Task:** - * **Adding New Commands:** Update `commandAutoFixCommands` in `PlanSettings.kt` with the new command paths. - * **Custom Fix Logic:** Modify the behavior within the `run` method or extend `CmdPatchApp` for specialized fixing - mechanisms. + * **Adding New Commands:** Update `commandAutoFixCommands` in `PlanSettings.kt` with the new command paths. + * **Custom Fix Logic:** Modify the behavior within the `run` method or extend `CmdPatchApp` for specialized fixing + mechanisms. --- @@ -188,42 +190,43 @@ The `run` method orchestrates the execution by: * **Functionality:** - * **Question Handling:** Processes user questions and objectives to generate meaningful answers. - * **Contextual Analysis:** Reads and analyzes input files to provide informed responses. - * **Markdown Rendering:** Formats the output in markdown for easy readability and discussion. - * **Blocking and Asynchronous Execution:** Supports both blocking and non-blocking modes based on configuration. + * **Question Handling:** Processes user questions and objectives to generate meaningful answers. + * **Contextual Analysis:** Reads and analyzes input files to provide informed responses. + * **Markdown Rendering:** Formats the output in markdown for easy readability and discussion. + * **Blocking and Asynchronous Execution:** Supports both blocking and non-blocking modes based on configuration. * **Key Components:** - * **`SimpleActor`:** Utilizes a prompt tailored to generate accurate and relevant information based on user inquiries. - * **`Discussable`:** Handles interactive discussions with the user, allowing for response revisions and approvals. - * **Semaphore Mechanism:** Ensures proper synchronization during the inquiry process. + * **`SimpleActor`:** Utilizes a prompt tailored to generate accurate and relevant information based on user inquiries. + * **`Discussable`:** Handles interactive discussions with the user, allowing for response revisions and approvals. + * **Semaphore Mechanism:** Ensures proper synchronization during the inquiry process. * **Configuration:** - * **Enabled Task Types:** Filters which task types are supported during the inquiry to align responses with system - capabilities. - * **Model Selection:** Determines which OpenAI model to use for generating responses, configurable via `PlanSettings`. + * **Enabled Task Types:** Filters which task types are supported during the inquiry to align responses with system + capabilities. + * **Model Selection:** Determines which OpenAI model to use for generating responses, configurable via `PlanSettings`. * **Implementation Details:** The `run` method executes by: - 1. **Preparing Input:** Combines user messages, plan details, prior code, and input files into a structured input. - 2. **Generating Response:** Leveraging `inquiryActor` to produce a detailed and formatted answer. - 3. **Handling Blocking Mode:** If enabled, facilitates an interactive discussion allowing user revisions; otherwise, - provides a direct response. - 4. **Updating Task State:** Stores the inquiry result in the processing state for record-keeping and further actions. + 1. **Preparing Input:** Combines user messages, plan details, prior code, and input files into a structured input. + 2. **Generating Response:** Leveraging `inquiryActor` to produce a detailed and formatted answer. + 3. **Handling Blocking Mode:** If enabled, facilitates an interactive discussion allowing user revisions; otherwise, + provides a direct response. + 4. **Updating Task State:** Stores the inquiry result in the processing state for record-keeping and further actions. * **Extending the Task:** - * **Custom Prompts:** Modify the prompt within `SimpleActor` to tailor the inquiry process. - * **Response Handling:** Adjust how responses are processed and displayed by altering the `outputFn` or integrating - additional formatting. + * **Custom Prompts:** Modify the prompt within `SimpleActor` to tailor the inquiry process. + * **Response Handling:** Adjust how responses are processed and displayed by altering the `outputFn` or integrating + additional formatting. --- ##### **3. FileModificationTask** + * **Description:** The `FileModificationTask` automates the process of modifying existing files or creating new ones based on specified @@ -232,50 +235,50 @@ The `run` method orchestrates the execution by: * **Functionality:** - * **Patch Generation:** Creates patches for existing files, highlighting additions and deletions. - * **New File Creation:** Generates new files with appropriate structuring and syntax highlighting. - * **Summary Reporting:** Provides a concise summary of all modifications made. - * **Auto-Application of Changes:** Depending on configuration, can automatically apply the generated patches or prompt - for user approval. + * **Patch Generation:** Creates patches for existing files, highlighting additions and deletions. + * **New File Creation:** Generates new files with appropriate structuring and syntax highlighting. + * **Summary Reporting:** Provides a concise summary of all modifications made. + * **Auto-Application of Changes:** Depending on configuration, can automatically apply the generated patches or prompt + for user approval. * **Key Components:** - * **`SimpleActor`:** Uses a detailed prompt to generate accurate file modifications or new file contents. - * **`CmdPatchApp`:** Manages the application of patches to existing files. - * **`addApplyFileDiffLinks`:** Integrates with the UI to allow users to apply or review changes interactively. + * **`SimpleActor`:** Uses a detailed prompt to generate accurate file modifications or new file contents. + * **`CmdPatchApp`:** Manages the application of patches to existing files. + * **`addApplyFileDiffLinks`:** Integrates with the UI to allow users to apply or review changes interactively. * **Configuration:** - * **Input and Output Files:** Defines which files are to be examined or created. - * **Auto-Fix Toggle:** Controlled via `planSettings.autoFix` to determine whether changes should be applied - automatically. - * **Language Specifications:** For new files, specifies the programming language to ensure correct syntax - highlighting. + * **Input and Output Files:** Defines which files are to be examined or created. + * **Auto-Fix Toggle:** Controlled via `planSettings.autoFix` to determine whether changes should be applied + automatically. + * **Language Specifications:** For new files, specifies the programming language to ensure correct syntax + highlighting. * **Implementation Details:** The `run` method operates by: - 1. **Validating Input Files:** Ensures that there are files specified for modification or creation. - 2. **Generating Code Changes:** Uses `fileModificationActor` to produce the necessary patches or new file contents. - 3. **Applying Changes:** Depending on `autoFix`, either applies changes automatically or provides links for user - approval. - 4. **Logging and Tracking:** Updates the task state with the results of the modifications for future reference. + 1. **Validating Input Files:** Ensures that there are files specified for modification or creation. + 2. **Generating Code Changes:** Uses `fileModificationActor` to produce the necessary patches or new file contents. + 3. **Applying Changes:** Depending on `autoFix`, either applies changes automatically or provides links for user + approval. + 4. **Logging and Tracking:** Updates the task state with the results of the modifications for future reference. * **Extending the Task:** - * **Custom Modification Logic:** Enhance the prompt within `SimpleActor` to define specific modification behaviors. - * **Integration with Additional Services:** Extend the task to interact with other systems or services as needed. - * **Advanced Patch Handling:** Modify how patches are applied or reviewed by customizing `addApplyFileDiffLinks` and - related methods. + * **Custom Modification Logic:** Enhance the prompt within `SimpleActor` to define specific modification behaviors. + * **Integration with Additional Services:** Extend the task to interact with other systems or services as needed. + * **Advanced Patch Handling:** Modify how patches are applied or reviewed by customizing `addApplyFileDiffLinks` and + related methods. --- - ##### **4. RunShellCommandTask** + * **Description:** - The `RunShellCommandTask` is designed to execute specified shell commands within a designated working directory. - It facilitates automation of system commands, ensuring outputs are captured and handled appropriately. + The `RunShellCommandTask` is designed to execute specified shell commands within a designated working directory. + It facilitates automation of system commands, ensuring outputs are captured and handled appropriately. * **Functionality:** * **Command Execution:** Executes user-specified shell commands with provided arguments in the configured working directory. * **Output Handling:** Captures and processes the standard output and error streams from command execution. @@ -292,14 +295,14 @@ The `run` method orchestrates the execution by: * **Environment Variables:** Set through `planSettings.env` to customize the execution environment. * **Implementation Details:** The `run` method orchestrates the execution by: - 1. **Preparing the Environment:** Sets up the working directory and environment variables as specified. - 2. **Executing the Command:** Uses `ProcessInterpreter` to run the specified shell command with provided arguments. - 3. **Handling Outputs:** Captures the output and error streams, processing them for logging and user notifications. - 4. **Managing Execution State:** Updates the task state based on the success or failure of the command execution. + 1. **Preparing the Environment:** Sets up the working directory and environment variables as specified. + 2. **Executing the Command:** Uses `ProcessInterpreter` to run the specified shell command with provided arguments. + 3. **Handling Outputs:** Captures the output and error streams, processing them for logging and user notifications. + 4. **Managing Execution State:** Updates the task state based on the success or failure of the command execution. * **Extending the Task:** - * **Adding New Commands:** Update the `command` list in `PlanSettings.kt` with new shell commands. - * **Custom Output Processing:** Modify the `displayFeedback` method to handle outputs differently or integrate with other systems. - * **Advanced Error Handling:** Enhance the `run` method to manage complex error scenarios or integrate with monitoring tools. + * **Adding New Commands:** Update the `command` list in `PlanSettings.kt` with new shell commands. + * **Custom Output Processing:** Modify the `displayFeedback` method to handle outputs differently or integrate with other systems. + * **Advanced Error Handling:** Enhance the `run` method to manage complex error scenarios or integrate with monitoring tools. ##### **5. RefactorTask** @@ -309,36 +312,37 @@ The `run` method orchestrates the execution by: * **Functionality:** - * **Code Analysis:** Examines the provided code files to identify areas for improvement. - * **Refactoring Suggestions:** Provides detailed recommendations for refactoring, including code reorganization, reducing duplication, and applying design patterns where appropriate. - * **Change Application:** Utilizes diff patches to implement the suggested refactoring changes. - * **Logging and Reporting:** Logs the refactoring process and results, providing traceability and auditability. + * **Code Analysis:** Examines the provided code files to identify areas for improvement. + * **Refactoring Suggestions:** Provides detailed recommendations for refactoring, including code reorganization, reducing duplication, and applying design patterns where + appropriate. + * **Change Application:** Utilizes diff patches to implement the suggested refactoring changes. + * **Logging and Reporting:** Logs the refactoring process and results, providing traceability and auditability. * **Key Components:** - * **`actorName` and `actorPrompt`:** Define the behavior and instructions for the refactoring analysis. - * **`AbstractAnalysisTask`:** Provides the foundational structure for the task execution logic. - * **`CommandPatchApp`:** Handles the application of generated refactoring patches. - * **Semaphore Mechanism:** Ensures synchronization and proper task execution flow. + * **`actorName` and `actorPrompt`:** Define the behavior and instructions for the refactoring analysis. + * **`AbstractAnalysisTask`:** Provides the foundational structure for the task execution logic. + * **`CommandPatchApp`:** Handles the application of generated refactoring patches. + * **Semaphore Mechanism:** Ensures synchronization and proper task execution flow. * **Configuration:** - * **Refactoring Focus Areas:** Specify particular aspects to focus on during refactoring, such as modularity or naming conventions. - * **Auto-Fix Toggle:** Controlled via `planSettings.autoFix` to enable or disable automatic application of refactoring suggestions. + * **Refactoring Focus Areas:** Specify particular aspects to focus on during refactoring, such as modularity or naming conventions. + * **Auto-Fix Toggle:** Controlled via `planSettings.autoFix` to enable or disable automatic application of refactoring suggestions. * **Implementation Details:** The `run` method orchestrates the refactoring process by: - 1. **Analyzing Code:** Uses `analysisActor` to generate refactoring suggestions based on the current codebase. - 2. **Generating Patches:** Creates diff patches representing the suggested changes. - 3. **Applying Changes:** Applies patches automatically if `autoFix` is enabled or prompts the user for approval. - 4. **Logging Results:** Updates logs and task states based on the outcome of the refactoring process. + 1. **Analyzing Code:** Uses `analysisActor` to generate refactoring suggestions based on the current codebase. + 2. **Generating Patches:** Creates diff patches representing the suggested changes. + 3. **Applying Changes:** Applies patches automatically if `autoFix` is enabled or prompts the user for approval. + 4. **Logging Results:** Updates logs and task states based on the outcome of the refactoring process. * **Extending the Task:** - * **Custom Refactoring Logic:** Modify the prompt to target specific refactoring goals or integrate additional analysis tools. - * **Integration with Development Tools:** Enhance `CommandPatchApp` to interact with other systems or IDEs. + * **Custom Refactoring Logic:** Modify the prompt to target specific refactoring goals or integrate additional analysis tools. + * **Integration with Development Tools:** Enhance `CommandPatchApp` to interact with other systems or IDEs. ##### **6. SecurityAuditTask** @@ -348,36 +352,36 @@ The `run` method orchestrates the execution by: * **Functionality:** - * **Vulnerability Detection:** Scans code for potential security issues such as injection attacks, insecure data handling, and authentication flaws. - * **Compliance Checking:** Ensures code adheres to established security standards and guidelines. - * **Recommendations:** Provides specific recommendations to address identified security vulnerabilities. - * **Reporting:** Generates detailed audit reports with actionable insights. + * **Vulnerability Detection:** Scans code for potential security issues such as injection attacks, insecure data handling, and authentication flaws. + * **Compliance Checking:** Ensures code adheres to established security standards and guidelines. + * **Recommendations:** Provides specific recommendations to address identified security vulnerabilities. + * **Reporting:** Generates detailed audit reports with actionable insights. * **Key Components:** - * **`actorName` and `actorPrompt`:** Tailor the analysis behavior for security auditing. - * **`AbstractAnalysisTask`:** Provides the foundational structure for the task execution logic. - * **`CommandPatchApp`:** Facilitates the application of security fixes. - * **Semaphore Mechanism:** Ensures synchronization during the audit process. + * **`actorName` and `actorPrompt`:** Tailor the analysis behavior for security auditing. + * **`AbstractAnalysisTask`:** Provides the foundational structure for the task execution logic. + * **`CommandPatchApp`:** Facilitates the application of security fixes. + * **Semaphore Mechanism:** Ensures synchronization during the audit process. * **Configuration:** - * **Audit Focus Areas:** Specify particular security aspects to prioritize during audits. - * **Auto-Fix Toggle:** Controlled via `planSettings.autoFix` to enable or disable automatic application of security fixes. + * **Audit Focus Areas:** Specify particular security aspects to prioritize during audits. + * **Auto-Fix Toggle:** Controlled via `planSettings.autoFix` to enable or disable automatic application of security fixes. * **Implementation Details:** The `run` method manages the security auditing by: - 1. **Analyzing Code:** Uses `analysisActor` to identify security vulnerabilities in the codebase. - 2. **Generating Fixes:** Creates diff patches to address the identified security issues. - 3. **Applying Changes:** Applies patches automatically if `autoFix` is enabled or prompts the user for approval otherwise. - 4. **Logging Results:** Updates logs and task states based on the outcome of the audit. + 1. **Analyzing Code:** Uses `analysisActor` to identify security vulnerabilities in the codebase. + 2. **Generating Fixes:** Creates diff patches to address the identified security issues. + 3. **Applying Changes:** Applies patches automatically if `autoFix` is enabled or prompts the user for approval otherwise. + 4. **Logging Results:** Updates logs and task states based on the outcome of the audit. * **Extending the Task:** - * **Custom Security Rules:** Modify or extend the audit criteria to include additional security checks. - * **Integration with Security Tools:** Enhance `CommandPatchApp` to work with external security scanning or fixing tools. + * **Custom Security Rules:** Modify or extend the audit criteria to include additional security checks. + * **Integration with Security Tools:** Enhance `CommandPatchApp` to work with external security scanning or fixing tools. ##### **7. CodeOptimizationTask** @@ -387,36 +391,36 @@ The `run` method orchestrates the execution by: * **Functionality:** - * **Performance Analysis:** Identifies performance bottlenecks and inefficient code patterns. - * **Optimization Suggestions:** Recommends specific code changes to improve efficiency and performance. - * **Code Refactoring:** Applies optimized changes using diff patches. - * **Impact Assessment:** Evaluates the potential benefits and trade-offs of suggested optimizations. + * **Performance Analysis:** Identifies performance bottlenecks and inefficient code patterns. + * **Optimization Suggestions:** Recommends specific code changes to improve efficiency and performance. + * **Code Refactoring:** Applies optimized changes using diff patches. + * **Impact Assessment:** Evaluates the potential benefits and trade-offs of suggested optimizations. * **Key Components:** - * **`actorName` and `actorPrompt`:** Define the behavior and instructions for code optimization analysis. - * **`AbstractAnalysisTask`:** Provides the foundational structure for the task execution logic. - * **`CommandPatchApp`:** Facilitates the application of optimization changes. - * **Semaphore Mechanism:** Manages synchronization during the optimization process. + * **`actorName` and `actorPrompt`:** Define the behavior and instructions for code optimization analysis. + * **`AbstractAnalysisTask`:** Provides the foundational structure for the task execution logic. + * **`CommandPatchApp`:** Facilitates the application of optimization changes. + * **Semaphore Mechanism:** Manages synchronization during the optimization process. * **Configuration:** - * **Optimization Targets:** Define areas of focus, such as memory usage, execution speed, or algorithm efficiency. - * **Auto-Fix Toggle:** Controlled via `planSettings.autoFix` to enable or disable automatic application of optimizations. + * **Optimization Targets:** Define areas of focus, such as memory usage, execution speed, or algorithm efficiency. + * **Auto-Fix Toggle:** Controlled via `planSettings.autoFix` to enable or disable automatic application of optimizations. * **Implementation Details:** The `run` method orchestrates the optimization process by: - 1. **Analyzing Code:** Utilizes `analysisActor` to identify optimization opportunities within the codebase. - 2. **Generating Patches:** Creates diff patches representing the suggested optimizations. - 3. **Applying Changes:** Applies patches automatically if `autoFix` is enabled or prompts the user for approval. - 4. **Logging Results:** Updates logs and task states based on the outcome of the optimization process. + 1. **Analyzing Code:** Utilizes `analysisActor` to identify optimization opportunities within the codebase. + 2. **Generating Patches:** Creates diff patches representing the suggested optimizations. + 3. **Applying Changes:** Applies patches automatically if `autoFix` is enabled or prompts the user for approval. + 4. **Logging Results:** Updates logs and task states based on the outcome of the optimization process. * **Extending the Task:** - * **Custom Optimization Criteria:** Modify the prompt to target specific optimization goals or integrate performance profiling tools. - * **Advanced Patch Handling:** Enhance how patches are applied to support more complex optimization scenarios. + * **Custom Optimization Criteria:** Modify the prompt to target specific optimization goals or integrate performance profiling tools. + * **Advanced Patch Handling:** Enhance how patches are applied to support more complex optimization scenarios. ##### **8. CodeReviewTask** @@ -426,36 +430,36 @@ The `run` method orchestrates the execution by: * **Functionality:** - * **Quality Assessment:** Evaluates code for readability, maintainability, and adherence to coding standards. - * **Issue Identification:** Detects potential bugs, logical errors, and performance issues within the codebase. - * **Best Practices Enforcement:** Ensures that code follows industry best practices and organizational guidelines. - * **Recommendations:** Provides actionable suggestions for improving code quality and resolving identified issues. + * **Quality Assessment:** Evaluates code for readability, maintainability, and adherence to coding standards. + * **Issue Identification:** Detects potential bugs, logical errors, and performance issues within the codebase. + * **Best Practices Enforcement:** Ensures that code follows industry best practices and organizational guidelines. + * **Recommendations:** Provides actionable suggestions for improving code quality and resolving identified issues. * **Key Components:** - * **`actorName` and `actorPrompt`:** Tailor the analysis behavior for code reviews. - * **`AbstractAnalysisTask`:** Provides the foundational structure for the task execution logic. - * **`CommandPatchApp`:** Facilitates the application of code review suggestions. - * **Semaphore Mechanism:** Ensures synchronization during the review process. + * **`actorName` and `actorPrompt`:** Tailor the analysis behavior for code reviews. + * **`AbstractAnalysisTask`:** Provides the foundational structure for the task execution logic. + * **`CommandPatchApp`:** Facilitates the application of code review suggestions. + * **Semaphore Mechanism:** Ensures synchronization during the review process. * **Configuration:** - * **Review Scope:** Define which aspects of the code (e.g., security, performance) to prioritize during the review. - * **Auto-Fix Toggle:** Controlled via `planSettings.autoFix` to enable or disable automatic application of review suggestions. + * **Review Scope:** Define which aspects of the code (e.g., security, performance) to prioritize during the review. + * **Auto-Fix Toggle:** Controlled via `planSettings.autoFix` to enable or disable automatic application of review suggestions. * **Implementation Details:** The `run` method manages the code review by: - 1. **Analyzing Code:** Uses `analysisActor` to assess code quality and identify issues. - 2. **Generating Suggestions:** Creates diff patches with recommended code changes to improve quality. - 3. **Applying Changes:** Applies patches automatically if `autoFix` is enabled or prompts the user for approval. - 4. **Logging Results:** Updates logs and task states based on the outcome of the code review. + 1. **Analyzing Code:** Uses `analysisActor` to assess code quality and identify issues. + 2. **Generating Suggestions:** Creates diff patches with recommended code changes to improve quality. + 3. **Applying Changes:** Applies patches automatically if `autoFix` is enabled or prompts the user for approval. + 4. **Logging Results:** Updates logs and task states based on the outcome of the code review. * **Extending the Task:** - * **Custom Review Criteria:** Modify the prompt to focus on specific review aspects or integrate additional analysis tools. - * **Integration with CI/CD Pipelines:** Enhance `CommandPatchApp` to work seamlessly with continuous integration systems. + * **Custom Review Criteria:** Modify the prompt to focus on specific review aspects or integrate additional analysis tools. + * **Integration with CI/CD Pipelines:** Enhance `CommandPatchApp` to work seamlessly with continuous integration systems. ##### **9. DocumentationTask** @@ -465,35 +469,35 @@ The `run` method orchestrates the execution by: * **Functionality:** - * **Automatic Documentation Generation:** Creates detailed documentation covering code purpose, functionality, inputs, outputs, and usage examples. - * **Structured Formatting:** Ensures that documentation is organized in a consistent and readable format. - * **Code Examples:** Includes code snippets to illustrate usage and functionality. - * **Update Tracking:** Monitors changes in code to automatically update relevant documentation sections. + * **Automatic Documentation Generation:** Creates detailed documentation covering code purpose, functionality, inputs, outputs, and usage examples. + * **Structured Formatting:** Ensures that documentation is organized in a consistent and readable format. + * **Code Examples:** Includes code snippets to illustrate usage and functionality. + * **Update Tracking:** Monitors changes in code to automatically update relevant documentation sections. * **Key Components:** - * **`documentationGeneratorActor`:** Generates the documentation content based on provided code files. - * **`MarkdownUtil`:** Formats the generated documentation into markdown for consistency and readability. - * **Semaphore Mechanism:** Manages synchronization during the documentation generation process. + * **`documentationGeneratorActor`:** Generates the documentation content based on provided code files. + * **`MarkdownUtil`:** Formats the generated documentation into markdown for consistency and readability. + * **Semaphore Mechanism:** Manages synchronization during the documentation generation process. * **Configuration:** - * **Documentation Scope:** Define which aspects of the code to document, such as functions, classes, and modules. - * **Auto-Fix Toggle:** Controlled via `planSettings.autoFix` to enable or disable automatic acceptance of generated documentation. + * **Documentation Scope:** Define which aspects of the code to document, such as functions, classes, and modules. + * **Auto-Fix Toggle:** Controlled via `planSettings.autoFix` to enable or disable automatic acceptance of generated documentation. * **Implementation Details:** The `run` method orchestrates the documentation generation by: - 1. **Generating Documentation:** Utilizes `documentationGeneratorActor` to create detailed documentation based on the codebase. - 2. **Formatting Output:** Formats the documentation using `MarkdownUtil` for integration into the UI. - 3. **Applying or Approving Documentation:** Automatically accepts the documentation if `autoFix` is enabled, or provides an interface for user approval. - 4. **Logging Results:** Updates task states and logs based on the outcome of the documentation process. + 1. **Generating Documentation:** Utilizes `documentationGeneratorActor` to create detailed documentation based on the codebase. + 2. **Formatting Output:** Formats the documentation using `MarkdownUtil` for integration into the UI. + 3. **Applying or Approving Documentation:** Automatically accepts the documentation if `autoFix` is enabled, or provides an interface for user approval. + 4. **Logging Results:** Updates task states and logs based on the outcome of the documentation process. * **Extending the Task:** - * **Custom Documentation Templates:** Modify the prompt to generate documentation in specific formats or styles. - * **Integration with Documentation Systems:** Enhance the task to integrate with existing documentation platforms or tools. + * **Custom Documentation Templates:** Modify the prompt to generate documentation in specific formats or styles. + * **Integration with Documentation Systems:** Enhance the task to integrate with existing documentation platforms or tools. ##### **10. TestGenerationTask** @@ -503,37 +507,37 @@ The `run` method orchestrates the execution by: * **Functionality:** - * **Unit Test Creation:** Produces unit tests covering all public methods and functions, including positive, negative, and edge cases. - * **Framework Integration:** Utilizes appropriate testing frameworks and assertion libraries based on the target language. - * **Setup and Teardown:** Includes necessary setup and teardown methods to prepare the testing environment. - * **Commenting:** Adds comments explaining the purpose and functionality of each test case. + * **Unit Test Creation:** Produces unit tests covering all public methods and functions, including positive, negative, and edge cases. + * **Framework Integration:** Utilizes appropriate testing frameworks and assertion libraries based on the target language. + * **Setup and Teardown:** Includes necessary setup and teardown methods to prepare the testing environment. + * **Commenting:** Adds comments explaining the purpose and functionality of each test case. * **Key Components:** - * **`actorName` and `actorPrompt`:** Define the behavior and instructions for test generation analysis. - * **`AbstractAnalysisTask`:** Provides the foundational structure for the task execution logic. - * **`CommandPatchApp`:** Facilitates the creation and application of test files. - * **Semaphore Mechanism:** Manages synchronization during the test generation process. + * **`actorName` and `actorPrompt`:** Define the behavior and instructions for test generation analysis. + * **`AbstractAnalysisTask`:** Provides the foundational structure for the task execution logic. + * **`CommandPatchApp`:** Facilitates the creation and application of test files. + * **Semaphore Mechanism:** Manages synchronization during the test generation process. * **Configuration:** - * **Test Coverage Targets:** Define the desired code coverage levels and test case types (e.g., boundary cases). - * **Auto-Fix Toggle:** Controlled via `planSettings.autoFix` to enable or disable automatic creation of test files. + * **Test Coverage Targets:** Define the desired code coverage levels and test case types (e.g., boundary cases). + * **Auto-Fix Toggle:** Controlled via `planSettings.autoFix` to enable or disable automatic creation of test files. * **Implementation Details:** The `run` method manages the test generation process by: - 1. **Generating Tests:** Utilizes `analysisActor` to generate unit tests based on the provided code files. - 2. **Creating Test Files:** Formats and structures generated tests into runnable code files using appropriate testing frameworks. - 3. **Applying Tests:** Automatically creates test files if `autoFix` is enabled or prompts the user for approval. - 4. **Logging Results:** Updates logs and task states based on the outcome of the test generation process. + 1. **Generating Tests:** Utilizes `analysisActor` to generate unit tests based on the provided code files. + 2. **Creating Test Files:** Formats and structures generated tests into runnable code files using appropriate testing frameworks. + 3. **Applying Tests:** Automatically creates test files if `autoFix` is enabled or prompts the user for approval. + 4. **Logging Results:** Updates logs and task states based on the outcome of the test generation process. * **Extending the Task:** - * **Custom Test Case Logic:** Modify the prompt to generate specific types of tests or integrate with additional testing tools. - * **Integration with CI/CD Pipelines:** Enhance `CommandPatchApp` to work with continuous integration systems and testing frameworks. - + * **Custom Test Case Logic:** Modify the prompt to generate specific types of tests or integrate with additional testing tools. + * **Integration with CI/CD Pipelines:** Enhance `CommandPatchApp` to work with continuous integration systems and testing frameworks. + #### **Adding New Task Types** To introduce a new task type: @@ -584,85 +588,85 @@ To introduce a new task type: `PlanSettings.kt` allows for extensive configuration of how tasks are planned and executed. * **Default and Parsing Models:** - * Define which OpenAI models to use for default operations and parsing tasks. + * Define which OpenAI models to use for default operations and parsing tasks. * **Command Environment:** - * Configure the command-line environment, such as using `bash` or `powershell` based on the operating system. + * Configure the command-line environment, such as using `bash` or `powershell` based on the operating system. * **Temperature and Budget:** - * Adjust the creativity (`temperature`) and resource allocation (`budget`) for task planning. + * Adjust the creativity (`temperature`) and resource allocation (`budget`) for task planning. * **Task-Specific Settings:** - * Enable or disable specific task types and assign models to them. - * Example: - ```kotlin - val taskSettings: MutableMap = TaskType.values().associateWith { taskType -> - TaskSettings( - when (taskType) { - TaskType.FileModification, TaskType.Inquiry -> true - else -> false - } - ) - }.toMutableMap() - ``` + * Enable or disable specific task types and assign models to them. + * Example: + ```kotlin + val taskSettings: MutableMap = TaskType.values().associateWith { taskType -> + TaskSettings( + when (taskType) { + TaskType.FileModification, TaskType.Inquiry -> true + else -> false + } + ) + }.toMutableMap() + ``` * **Auto-Fix and Blocking Behavior:** - * Configure whether the system should attempt to auto-fix issues and whether to allow blocking operations. + * Configure whether the system should attempt to auto-fix issues and whether to allow blocking operations. ### **Extending PlanCoordinator** `PlanCoordinator.kt` is pivotal in managing the lifecycle of plans and their tasks. * **Initialization:** - * Handles the initial breakdown of tasks based on user input. - * Utilizes `PlanUtil` for filtering and organizing tasks. + * Handles the initial breakdown of tasks based on user input. + * Utilizes `PlanUtil` for filtering and organizing tasks. * **Task Execution:** - * Manages threading and asynchronous task execution using `ThreadPoolExecutor`. - * Handles dependencies to ensure tasks execute in the correct order. + * Manages threading and asynchronous task execution using `ThreadPoolExecutor`. + * Handles dependencies to ensure tasks execute in the correct order. * **Logging and Error Handling:** - * Integrates logging for monitoring task executions. - * Captures and logs errors to assist in debugging. + * Integrates logging for monitoring task executions. + * Captures and logs errors to assist in debugging. **Extending Functionality:** * **Custom Execution Strategies:** - * Modify how tasks are queued and executed by overriding methods in `PlanCoordinator`. + * Modify how tasks are queued and executed by overriding methods in `PlanCoordinator`. * **Enhancing Logging:** - * Implement additional logging mechanisms or integrate with external monitoring systems. + * Implement additional logging mechanisms or integrate with external monitoring systems. ### **Utilizing PlanUtil** `PlanUtil.kt` provides utility functions essential for task management and visualization. * **Diagram Generation:** - * Uses Mermaid to create visual representations of task dependencies. + * Uses Mermaid to create visual representations of task dependencies. * **Rendering Plans:** - * Provides functions to render plans in various formats (Text, JSON, Diagram). + * Provides functions to render plans in various formats (Text, JSON, Diagram). * **Plan Filtering:** - * Filters out invalid or circular dependencies in task plans. + * Filters out invalid or circular dependencies in task plans. **Custom Utilities:** * **Extend `PlanUtil` with Additional Helpers:** - * Implement new utility functions as needed to support extended features. + * Implement new utility functions as needed to support extended features. ### **Handling Asynchronous Task Execution** The system leverages a `ThreadPoolExecutor` to manage task execution asynchronously. * **Concurrency Management:** - * Configure the thread pool size and behavior based on system capabilities and workload. + * Configure the thread pool size and behavior based on system capabilities and workload. * **Task Dependencies:** - * Ensure tasks wait for their dependencies to complete before execution. + * Ensure tasks wait for their dependencies to complete before execution. * **Error Propagation:** - * Implement mechanisms to handle exceptions in asynchronous tasks gracefully. + * Implement mechanisms to handle exceptions in asynchronous tasks gracefully. ### **Customizing Task Execution** @@ -685,19 +689,19 @@ Developers can customize how individual tasks execute by: ## **Best Practices** * **Modular Design:** - * Keep task implementations modular to facilitate easy maintenance and extension. + * Keep task implementations modular to facilitate easy maintenance and extension. * **Robust Error Handling:** - * Implement comprehensive error handling within tasks to ensure the system remains stable. + * Implement comprehensive error handling within tasks to ensure the system remains stable. * **Efficient Dependency Management:** - * Clearly define task dependencies to avoid circular dependencies and ensure smooth execution. + * Clearly define task dependencies to avoid circular dependencies and ensure smooth execution. * **Logging and Monitoring:** - * Maintain detailed logs for all task executions to aid in monitoring and troubleshooting. + * Maintain detailed logs for all task executions to aid in monitoring and troubleshooting. * **Security Considerations:** - * Ensure that executing shell commands or modifying files does not introduce security vulnerabilities. + * Ensure that executing shell commands or modifying files does not introduce security vulnerabilities. --- diff --git a/docs/planning_agent_bespoke.html b/docs/planning_agent_bespoke.html index 2c7ca62f..7c42c4cd 100644 --- a/docs/planning_agent_bespoke.html +++ b/docs/planning_agent_bespoke.html @@ -1,106 +1,128 @@ - - - Plan Feature User and Developer Guide - - + + + Plan Feature User and Developer Guide + +
-
-

Plan Feature User and Developer Guide

-
- -
-

Introduction

-

The Plan feature is a sophisticated system designed to break down high-level user requests into manageable, actionable tasks. It leverages OpenAI's capabilities to automate task planning, execution, and management, ensuring efficient workflow and seamless integration with existing systems.

-
- -
-

Features Overview

-
    -
  • Dynamic Task Breakdown
  • -
  • Task Execution
  • -
  • Dependency Management
  • -
  • Asynchronous Processing
  • -
  • Customizable Settings
  • -
  • Extensible Architecture
  • -
-
- -
-

User Guide

-

Accessing the Plan Feature

-

Navigate to the application interface where task planning and management functionalities are exposed.

-
- -
-

Creating and Managing Plans

-
    -
  1. Initiate a New Plan
  2. -
  3. Task Breakdown
  4. -
  5. Review Generated Tasks
  6. -
  7. Execute the Plan
  8. -
-
- -
-

Understanding Task Dependencies

-
    -
  • Visual Representation using Mermaid
  • -
  • Interpreting the Graph
  • -
-
- -
-

Viewing Execution Logs

-
    -
  • Accessing Logs through UI
  • -
  • Log Files stored in .logs directory
  • -
-
- -
-

Developer Guide

-

Architecture Overview

-
    -
  • TaskType
  • -
  • PlanSettings
  • -
  • PlanCoordinator
  • -
  • PlanUtil
  • -
  • PlanningTask
  • -
  • AbstractTask
  • -
-
- -
-

Task Types

-
    -
  1. CommandAutoFixTask
  2. -
  3. InquiryTask
  4. -
  5. FileModificationTask
  6. -
  7. RunShellCommandTask
  8. -
  9. RefactorTask
  10. -
  11. SecurityAuditTask
  12. -
  13. CodeOptimizationTask
  14. -
  15. CodeReviewTask
  16. -
  17. DocumentationTask
  18. -
  19. TestGenerationTask
  20. -
-
- -
-

Adding New Task Types

-

+  
+

Plan Feature User and Developer Guide

+
+ +
+

Introduction

+

The Plan feature is a sophisticated system designed to break down high-level user requests into manageable, actionable tasks. It leverages OpenAI's + capabilities to automate task planning, execution, and management, ensuring efficient workflow and seamless integration with existing systems.

+
+ +
+

Features Overview

+
    +
  • Dynamic Task Breakdown
  • +
  • Task Execution
  • +
  • Dependency Management
  • +
  • Asynchronous Processing
  • +
  • Customizable Settings
  • +
  • Extensible Architecture
  • +
+
+ +
+

User Guide

+

Accessing the Plan Feature

+

Navigate to the application interface where task planning and management functionalities are exposed.

+
+ +
+

Creating and Managing Plans

+
    +
  1. Initiate a New Plan
  2. +
  3. Task Breakdown
  4. +
  5. Review Generated Tasks
  6. +
  7. Execute the Plan
  8. +
+
+ +
+

Understanding Task Dependencies

+
    +
  • Visual Representation using Mermaid
  • +
  • Interpreting the Graph
  • +
+
+ +
+

Viewing Execution Logs

+
    +
  • Accessing Logs through UI
  • +
  • Log Files stored in .logs directory
  • +
+
+ +
+

Developer Guide

+

Architecture Overview

+
    +
  • TaskType
  • +
  • PlanSettings
  • +
  • PlanCoordinator
  • +
  • PlanUtil
  • +
  • PlanningTask
  • +
  • AbstractTask
  • +
+
+ +
+

Task Types

+
    +
  1. CommandAutoFixTask
  2. +
  3. InquiryTask
  4. +
  5. FileModificationTask
  6. +
  7. RunShellCommandTask
  8. +
  9. RefactorTask
  10. +
  11. SecurityAuditTask
  12. +
  13. CodeOptimizationTask
  14. +
  15. CodeReviewTask
  16. +
  17. DocumentationTask
  18. +
  19. TestGenerationTask
  20. +
+
+ +
+

Adding New Task Types

+

 val NewTaskType = TaskType("NewTaskType")
 
 class NewTaskTypeTask(settings: PlanSettings, task: PlanningTask.PlanTask) : AbstractTask(settings, task) {
@@ -121,85 +143,85 @@ 

Adding New Task Types

} }
-
- -
-

Configuring Plan Settings

-
    -
  • Default and Parsing Models
  • -
  • Command Environment
  • -
  • Temperature and Budget
  • -
  • Task-Specific Settings
  • -
  • Auto-Fix and Blocking Behavior
  • -
-
- -
-

Extending PlanCoordinator

-
    -
  • Initialization
  • -
  • Task Execution
  • -
  • Logging and Error Handling
  • -
-
- -
-

Utilizing PlanUtil

-
    -
  • Diagram Generation
  • -
  • Rendering Plans
  • -
  • Plan Filtering
  • -
-
- -
-

Handling Asynchronous Task Execution

-
    -
  • Concurrency Management
  • -
  • Task Dependencies
  • -
  • Error Propagation
  • -
-
- -
-

Customizing Task Execution

-
    -
  1. Overriding the `run` Method
  2. -
  3. Integrating with External Systems
  4. -
  5. Enhancing the Execution Flow
  6. -
-
- -
-

Best Practices

-
    -
  • Modular Design
  • -
  • Robust Error Handling
  • -
  • Efficient Dependency Management
  • -
  • Logging and Monitoring
  • -
  • Security Considerations
  • -
-
- -
-

Troubleshooting

-
    -
  1. Circular Dependency Detected
  2. -
  3. Unknown Task Type Error
  4. -
  5. API Errors
  6. -
  7. File Reading Errors
  8. -
  9. Task Execution Failures
  10. -
-
- -
-

Frequently Asked Questions (FAQs)

-

Q1: How do I enable or disable specific task types?

-

Q2: Can I add custom commands for shell tasks?

-

Q3: How are task dependencies managed?

-

Q4: Is it possible to log API interactions for auditing purposes?

-

Q5: How can I visualize the task execution flow?

-
+
+ +
+

Configuring Plan Settings

+
    +
  • Default and Parsing Models
  • +
  • Command Environment
  • +
  • Temperature and Budget
  • +
  • Task-Specific Settings
  • +
  • Auto-Fix and Blocking Behavior
  • +
+
+ +
+

Extending PlanCoordinator

+
    +
  • Initialization
  • +
  • Task Execution
  • +
  • Logging and Error Handling
  • +
+
+ +
+

Utilizing PlanUtil

+
    +
  • Diagram Generation
  • +
  • Rendering Plans
  • +
  • Plan Filtering
  • +
+
+ +
+

Handling Asynchronous Task Execution

+
    +
  • Concurrency Management
  • +
  • Task Dependencies
  • +
  • Error Propagation
  • +
+
+ +
+

Customizing Task Execution

+
    +
  1. Overriding the `run` Method
  2. +
  3. Integrating with External Systems
  4. +
  5. Enhancing the Execution Flow
  6. +
+
+ +
+

Best Practices

+
    +
  • Modular Design
  • +
  • Robust Error Handling
  • +
  • Efficient Dependency Management
  • +
  • Logging and Monitoring
  • +
  • Security Considerations
  • +
+
+ +
+

Troubleshooting

+
    +
  1. Circular Dependency Detected
  2. +
  3. Unknown Task Type Error
  4. +
  5. API Errors
  6. +
  7. File Reading Errors
  8. +
  9. Task Execution Failures
  10. +
+
+ +
+

Frequently Asked Questions (FAQs)

+

Q1: How do I enable or disable specific task types?

+

Q2: Can I add custom commands for shell tasks?

+

Q3: How are task dependencies managed?

+

Q4: Is it possible to log API interactions for auditing purposes?

+

Q5: How can I visualize the task execution flow?

+
diff --git a/docs/planning_agent_deck.html b/docs/planning_agent_deck.html index 1bcbc3d4..044a1329 100644 --- a/docs/planning_agent_deck.html +++ b/docs/planning_agent_deck.html @@ -1,221 +1,225 @@ + - - - - - Plan Feature User and Developer Guide - - - - - - - - - -
-

Plan Feature User and Developer Guide

-
- -
-

Introduction

-

The Plan feature is a sophisticated system designed to break down high-level user requests into manageable, actionable tasks. It leverages OpenAI's capabilities to automate task planning, execution, and management, ensuring efficient workflow and seamless integration with existing systems.

-
- -
-

Features Overview

-
    -
  • Dynamic Task Breakdown
  • -
  • Task Execution
  • -
  • Dependency Management
  • -
  • Asynchronous Processing
  • -
  • Customizable Settings
  • -
  • Extensible Architecture
  • -
-
- -
-

User Guide

-

Accessing the Plan Feature

-

Navigate to the application interface where task planning and management functionalities are exposed.

-
- -
-

Creating and Managing Plans

-
    -
  1. Initiate a New Plan
  2. -
  3. Task Breakdown
  4. -
  5. Review Generated Tasks
  6. -
  7. Execute the Plan
  8. -
-
- -
-

Understanding Task Dependencies

-
    -
  • Visual Representation using Mermaid
  • -
  • Interpreting the Graph
  • -
-
- -
-

Viewing Execution Logs

-
    -
  • Accessing Logs through UI
  • -
  • Log Files stored in .logs directory
  • -
-
- -
-

Developer Guide

-

Architecture Overview

-
    -
  • TaskType
  • -
  • PlanSettings
  • -
  • PlanCoordinator
  • -
  • PlanUtil
  • -
  • PlanningTask
  • -
  • AbstractTask
  • -
-
- -
-

Task Types

-
    -
  1. CommandAutoFixTask
  2. -
  3. InquiryTask
  4. -
  5. FileModificationTask
  6. -
  7. RunShellCommandTask
  8. -
  9. RefactorTask
  10. -
-
- -
-

Task Types (continued)

-
    -
  1. SecurityAuditTask
  2. -
  3. CodeOptimizationTask
  4. -
  5. CodeReviewTask
  6. -
  7. DocumentationTask
  8. -
  9. TestGenerationTask
  10. -
-
- -
-

Adding New Task Types

-
    -
  1. Define the Task Type
  2. -
  3. Create the Task Class
  4. -
  5. Register the Task Type
  6. -
  7. Update PlanSettings
  8. -
-
- -
-

Configuring Plan Settings

-
    -
  • Default and Parsing Models
  • -
  • Command Environment
  • -
  • Temperature and Budget
  • -
  • Task-Specific Settings
  • -
  • Auto-Fix and Blocking Behavior
  • -
-
- -
-

Extending PlanCoordinator

-
    -
  • Initialization
  • -
  • Task Execution
  • -
  • Logging and Error Handling
  • -
-
- -
-

Utilizing PlanUtil

-
    -
  • Diagram Generation
  • -
  • Rendering Plans
  • -
  • Plan Filtering
  • -
-
- -
-

Handling Asynchronous Task Execution

-
    -
  • Concurrency Management
  • -
  • Task Dependencies
  • -
  • Error Propagation
  • -
-
- -
-

Customizing Task Execution

-
    -
  1. Overriding the run Method
  2. -
  3. Integrating with External Systems
  4. -
  5. Enhancing the Execution Flow
  6. -
-
- -
-

Best Practices

-
    -
  • Modular Design
  • -
  • Robust Error Handling
  • -
  • Efficient Dependency Management
  • -
  • Logging and Monitoring
  • -
  • Security Considerations
  • -
-
- -
-

Troubleshooting

-
    -
  1. Circular Dependency Detected
  2. -
  3. Unknown Task Type Error
  4. -
  5. API Errors
  6. -
  7. File Reading Errors
  8. -
  9. Task Execution Failures
  10. -
-
- -
-

Frequently Asked Questions (FAQs)

-
    -
  • How do I enable or disable specific task types?
  • -
  • Can I add custom commands for shell tasks?
  • -
  • How are task dependencies managed?
  • -
  • Is it possible to log API interactions for auditing purposes?
  • -
  • How can I visualize the task execution flow?
  • -
-
- - - - - - - - - - + + + + + Plan Feature User and Developer Guide + + + + + + + + + +
+

Plan Feature User and Developer Guide

+
+ +
+

Introduction

+

The Plan feature is a sophisticated system designed to break down high-level user requests into manageable, actionable tasks. It leverages OpenAI's + capabilities to automate task planning, execution, and management, ensuring efficient workflow and seamless integration with existing systems.

+
+ +
+

Features Overview

+
    +
  • Dynamic Task Breakdown
  • +
  • Task Execution
  • +
  • Dependency Management
  • +
  • Asynchronous Processing
  • +
  • Customizable Settings
  • +
  • Extensible Architecture
  • +
+
+ +
+

User Guide

+

Accessing the Plan Feature

+

Navigate to the application interface where task planning and management functionalities are exposed.

+
+ +
+

Creating and Managing Plans

+
    +
  1. Initiate a New Plan
  2. +
  3. Task Breakdown
  4. +
  5. Review Generated Tasks
  6. +
  7. Execute the Plan
  8. +
+
+ +
+

Understanding Task Dependencies

+
    +
  • Visual Representation using Mermaid
  • +
  • Interpreting the Graph
  • +
+
+ +
+

Viewing Execution Logs

+
    +
  • Accessing Logs through UI
  • +
  • Log Files stored in .logs directory
  • +
+
+ +
+

Developer Guide

+

Architecture Overview

+
    +
  • TaskType
  • +
  • PlanSettings
  • +
  • PlanCoordinator
  • +
  • PlanUtil
  • +
  • PlanningTask
  • +
  • AbstractTask
  • +
+
+ +
+

Task Types

+
    +
  1. CommandAutoFixTask
  2. +
  3. InquiryTask
  4. +
  5. FileModificationTask
  6. +
  7. RunShellCommandTask
  8. +
  9. RefactorTask
  10. +
+
+ +
+

Task Types (continued)

+
    +
  1. SecurityAuditTask
  2. +
  3. CodeOptimizationTask
  4. +
  5. CodeReviewTask
  6. +
  7. DocumentationTask
  8. +
  9. TestGenerationTask
  10. +
+
+ +
+

Adding New Task Types

+
    +
  1. Define the Task Type
  2. +
  3. Create the Task Class
  4. +
  5. Register the Task Type
  6. +
  7. Update PlanSettings
  8. +
+
+ +
+

Configuring Plan Settings

+
    +
  • Default and Parsing Models
  • +
  • Command Environment
  • +
  • Temperature and Budget
  • +
  • Task-Specific Settings
  • +
  • Auto-Fix and Blocking Behavior
  • +
+
+ +
+

Extending PlanCoordinator

+
    +
  • Initialization
  • +
  • Task Execution
  • +
  • Logging and Error Handling
  • +
+
+ +
+

Utilizing PlanUtil

+
    +
  • Diagram Generation
  • +
  • Rendering Plans
  • +
  • Plan Filtering
  • +
+
+ +
+

Handling Asynchronous Task Execution

+
    +
  • Concurrency Management
  • +
  • Task Dependencies
  • +
  • Error Propagation
  • +
+
+ +
+

Customizing Task Execution

+
    +
  1. Overriding the run Method
  2. +
  3. Integrating with External Systems
  4. +
  5. Enhancing the Execution Flow
  6. +
+
+ +
+

Best Practices

+
    +
  • Modular Design
  • +
  • Robust Error Handling
  • +
  • Efficient Dependency Management
  • +
  • Logging and Monitoring
  • +
  • Security Considerations
  • +
+
+ +
+

Troubleshooting

+
    +
  1. Circular Dependency Detected
  2. +
  3. Unknown Task Type Error
  4. +
  5. API Errors
  6. +
  7. File Reading Errors
  8. +
  9. Task Execution Failures
  10. +
+
+ +
+

Frequently Asked Questions (FAQs)

+
    +
  • How do I enable or disable specific task types?
  • +
  • Can I add custom commands for shell tasks?
  • +
  • How are task dependencies managed?
  • +
  • Is it possible to log API interactions for auditing purposes?
  • +
  • How can I visualize the task execution flow?
  • +
+
+ + + + + + + + + + diff --git a/docs/planning_agent_impress.html b/docs/planning_agent_impress.html index 540fc96b..a0d8d3fe 100644 --- a/docs/planning_agent_impress.html +++ b/docs/planning_agent_impress.html @@ -1,151 +1,155 @@ - - - Plan Feature User and Developer Guide - - + + + Plan Feature User and Developer Guide + +
-
-

Plan Feature User and Developer Guide

-

Welcome to the comprehensive guide for the Plan feature, designed to assist both end-users and developers.

-
- -
-

Introduction

-

The Plan feature is a sophisticated system designed to break down high-level user requests into manageable, actionable tasks.

-
- -
-

Features Overview

-
    -
  • Dynamic Task Breakdown
  • -
  • Task Execution
  • -
  • Dependency Management
  • -
  • Asynchronous Processing
  • -
  • Customizable Settings
  • -
  • Extensible Architecture
  • -
-
- -
-

User Guide

-

Accessing the Plan Feature

-

Navigate to the application interface where task planning and management functionalities are exposed.

-
- -
-

Creating and Managing Plans

-
    -
  1. Initiate a New Plan
  2. -
  3. Task Breakdown
  4. -
  5. Review Generated Tasks
  6. -
  7. Execute the Plan
  8. -
-
- -
-

Understanding Task Dependencies

-

The Plan feature utilizes Mermaid to render task dependency graphs.

-
- -
-

Viewing Execution Logs

-

Execution logs are automatically generated and can be accessed through the UI.

-
- -
-

Developer Guide

-

Architecture Overview

-

The Plan feature is built around several core components: TaskType, PlanSettings, PlanCoordinator, PlanUtil, PlanningTask, and AbstractTask.

-
- -
-

Task Types

-

Various task types are defined, including CommandAutoFixTask, InquiryTask, FileModificationTask, and more.

-
- -
-

Adding New Task Types

-

To introduce a new task type:

-
    -
  1. Define the Task Type
  2. -
  3. Create the Task Class
  4. -
  5. Register the Task Type
  6. -
  7. Update PlanSettings
  8. -
-
- -
-

Configuring Plan Settings

-

PlanSettings.kt allows for extensive configuration of how tasks are planned and executed.

-
- -
-

Extending PlanCoordinator

-

PlanCoordinator.kt is pivotal in managing the lifecycle of plans and their tasks.

-
- -
-

Utilizing PlanUtil

-

PlanUtil.kt provides utility functions essential for task management and visualization.

-
- -
-

Handling Asynchronous Task Execution

-

The system leverages a ThreadPoolExecutor to manage task execution asynchronously.

-
- -
-

Customizing Task Execution

-

Developers can customize how individual tasks execute by overriding methods and integrating with external systems.

-
- -
-

Best Practices

-
    -
  • Modular Design
  • -
  • Robust Error Handling
  • -
  • Efficient Dependency Management
  • -
  • Logging and Monitoring
  • -
  • Security Considerations
  • -
-
- -
-

Troubleshooting

-

Common issues and their solutions are provided, including circular dependencies, unknown task types, API errors, file reading errors, and task execution failures.

-
- -
-

Frequently Asked Questions (FAQs)

-

Answers to common questions about enabling/disabling task types, adding custom commands, managing dependencies, logging API interactions, and visualizing task execution flow.

-
+
+

Plan Feature User and Developer Guide

+

Welcome to the comprehensive guide for the Plan feature, designed to assist both end-users and developers.

+
+ +
+

Introduction

+

The Plan feature is a sophisticated system designed to break down high-level user requests into manageable, actionable tasks.

+
+ +
+

Features Overview

+
    +
  • Dynamic Task Breakdown
  • +
  • Task Execution
  • +
  • Dependency Management
  • +
  • Asynchronous Processing
  • +
  • Customizable Settings
  • +
  • Extensible Architecture
  • +
+
+ +
+

User Guide

+

Accessing the Plan Feature

+

Navigate to the application interface where task planning and management functionalities are exposed.

+
+ +
+

Creating and Managing Plans

+
    +
  1. Initiate a New Plan
  2. +
  3. Task Breakdown
  4. +
  5. Review Generated Tasks
  6. +
  7. Execute the Plan
  8. +
+
+ +
+

Understanding Task Dependencies

+

The Plan feature utilizes Mermaid to render task dependency graphs.

+
+ +
+

Viewing Execution Logs

+

Execution logs are automatically generated and can be accessed through the UI.

+
+ +
+

Developer Guide

+

Architecture Overview

+

The Plan feature is built around several core components: TaskType, PlanSettings, PlanCoordinator, PlanUtil, PlanningTask, and AbstractTask.

+
+ +
+

Task Types

+

Various task types are defined, including CommandAutoFixTask, InquiryTask, FileModificationTask, and more.

+
+ +
+

Adding New Task Types

+

To introduce a new task type:

+
    +
  1. Define the Task Type
  2. +
  3. Create the Task Class
  4. +
  5. Register the Task Type
  6. +
  7. Update PlanSettings
  8. +
+
+ +
+

Configuring Plan Settings

+

PlanSettings.kt allows for extensive configuration of how tasks are planned and executed.

+
+ +
+

Extending PlanCoordinator

+

PlanCoordinator.kt is pivotal in managing the lifecycle of plans and their tasks.

+
+ +
+

Utilizing PlanUtil

+

PlanUtil.kt provides utility functions essential for task management and visualization.

+
+ +
+

Handling Asynchronous Task Execution

+

The system leverages a ThreadPoolExecutor to manage task execution asynchronously.

+
+ +
+

Customizing Task Execution

+

Developers can customize how individual tasks execute by overriding methods and integrating with external systems.

+
+ +
+

Best Practices

+
    +
  • Modular Design
  • +
  • Robust Error Handling
  • +
  • Efficient Dependency Management
  • +
  • Logging and Monitoring
  • +
  • Security Considerations
  • +
+
+ +
+

Troubleshooting

+

Common issues and their solutions are provided, including circular dependencies, unknown task types, API errors, file reading errors, and task execution failures.

+
+ +
+

Frequently Asked Questions (FAQs)

+

Answers to common questions about enabling/disabling task types, adding custom commands, managing dependencies, logging API interactions, and visualizing task execution + flow.

+
diff --git a/docs/planning_agent_reveal.html b/docs/planning_agent_reveal.html index 7bf55048..2fd66669 100644 --- a/docs/planning_agent_reveal.html +++ b/docs/planning_agent_reveal.html @@ -1,153 +1,154 @@ + - - - - + + + + - Plan Feature User and Developer Guide + Plan Feature User and Developer Guide - - - + + + - - - - -
-
-
-

Plan Feature User and Developer Guide

-
+ + + + +
+
+
+

Plan Feature User and Developer Guide

+
-
-

Introduction

-

The Plan feature is a sophisticated system designed to break down high-level user requests into manageable, actionable tasks. It leverages OpenAI's capabilities to automate task planning, execution, and management, ensuring efficient workflow and seamless integration with existing systems.

-
+
+

Introduction

+

The Plan feature is a sophisticated system designed to break down high-level user requests into manageable, actionable tasks. It leverages OpenAI's + capabilities to automate task planning, execution, and management, ensuring efficient workflow and seamless integration with existing systems.

+
-
-

Features Overview

-
    -
  • Dynamic Task Breakdown
  • -
  • Task Execution
  • -
  • Dependency Management
  • -
  • Asynchronous Processing
  • -
  • Customizable Settings
  • -
  • Extensible Architecture
  • -
-
+
+

Features Overview

+
    +
  • Dynamic Task Breakdown
  • +
  • Task Execution
  • +
  • Dependency Management
  • +
  • Asynchronous Processing
  • +
  • Customizable Settings
  • +
  • Extensible Architecture
  • +
+
-
-

User Guide

-
-

Accessing the Plan Feature

-

Navigate to the application interface where task planning and management functionalities are exposed.

-
-
-

Creating and Managing Plans

-
    -
  1. Initiate a New Plan
  2. -
  3. Task Breakdown
  4. -
  5. Review Generated Tasks
  6. -
  7. Execute the Plan
  8. -
-
-
-

Understanding Task Dependencies

-

The Plan feature utilizes Mermaid to render task dependency graphs.

-
-
-

Viewing Execution Logs

-

Execution logs are automatically generated and can be accessed through the UI.

-
-
+
+

User Guide

+
+

Accessing the Plan Feature

+

Navigate to the application interface where task planning and management functionalities are exposed.

+
+
+

Creating and Managing Plans

+
    +
  1. Initiate a New Plan
  2. +
  3. Task Breakdown
  4. +
  5. Review Generated Tasks
  6. +
  7. Execute the Plan
  8. +
+
+
+

Understanding Task Dependencies

+

The Plan feature utilizes Mermaid to render task dependency graphs.

+
+
+

Viewing Execution Logs

+

Execution logs are automatically generated and can be accessed through the UI.

+
+
-
-

Developer Guide

-
-

Architecture Overview

-
    -
  • TaskType
  • -
  • PlanSettings
  • -
  • PlanCoordinator
  • -
  • PlanUtil
  • -
  • PlanningTask
  • -
  • AbstractTask
  • -
-
-
-

Task Types

-
    -
  1. CommandAutoFixTask
  2. -
  3. InquiryTask
  4. -
  5. FileModificationTask
  6. -
  7. RunShellCommandTask
  8. -
  9. RefactorTask
  10. -
  11. SecurityAuditTask
  12. -
  13. CodeOptimizationTask
  14. -
  15. CodeReviewTask
  16. -
  17. DocumentationTask
  18. -
  19. TestGenerationTask
  20. -
-
-
-

Adding New Task Types

-
    -
  1. Define the Task Type
  2. -
  3. Create the Task Class
  4. -
  5. Register the Task Type
  6. -
  7. Update PlanSettings
  8. -
-
-
+
+

Developer Guide

+
+

Architecture Overview

+
    +
  • TaskType
  • +
  • PlanSettings
  • +
  • PlanCoordinator
  • +
  • PlanUtil
  • +
  • PlanningTask
  • +
  • AbstractTask
  • +
+
+
+

Task Types

+
    +
  1. CommandAutoFixTask
  2. +
  3. InquiryTask
  4. +
  5. FileModificationTask
  6. +
  7. RunShellCommandTask
  8. +
  9. RefactorTask
  10. +
  11. SecurityAuditTask
  12. +
  13. CodeOptimizationTask
  14. +
  15. CodeReviewTask
  16. +
  17. DocumentationTask
  18. +
  19. TestGenerationTask
  20. +
+
+
+

Adding New Task Types

+
    +
  1. Define the Task Type
  2. +
  3. Create the Task Class
  4. +
  5. Register the Task Type
  6. +
  7. Update PlanSettings
  8. +
+
+
-
-

Best Practices

-
    -
  • Modular Design
  • -
  • Robust Error Handling
  • -
  • Efficient Dependency Management
  • -
  • Logging and Monitoring
  • -
  • Security Considerations
  • -
-
+
+

Best Practices

+
    +
  • Modular Design
  • +
  • Robust Error Handling
  • +
  • Efficient Dependency Management
  • +
  • Logging and Monitoring
  • +
  • Security Considerations
  • +
+
-
-

Troubleshooting

-
    -
  1. Circular Dependency Detected
  2. -
  3. Unknown Task Type Error
  4. -
  5. API Errors
  6. -
  7. File Reading Errors
  8. -
  9. Task Execution Failures
  10. -
-
+
+

Troubleshooting

+
    +
  1. Circular Dependency Detected
  2. +
  3. Unknown Task Type Error
  4. +
  5. API Errors
  6. +
  7. File Reading Errors
  8. +
  9. Task Execution Failures
  10. +
+
-
-

Frequently Asked Questions (FAQs)

-

Q1: How do I enable or disable specific task types?

-

Q2: Can I add custom commands for shell tasks?

-

Q3: How are task dependencies managed?

-

Q4: Is it possible to log API interactions for auditing purposes?

-

Q5: How can I visualize the task execution flow?

-
-
-
+
+

Frequently Asked Questions (FAQs)

+

Q1: How do I enable or disable specific task types?

+

Q2: Can I add custom commands for shell tasks?

+

Q3: How are task dependencies managed?

+

Q4: Is it possible to log API interactions for auditing purposes?

+

Q5: How can I visualize the task execution flow?

+
+
+
- - - - - + + + + - - + // Learn about plugins: https://revealjs.com/plugins/ + plugins: [RevealMarkdown, RevealHighlight, RevealNotes] + }); + + + diff --git a/docs/prompts/project_info.md b/docs/prompts/project_info.md index 02cade69..45bbcdfe 100644 --- a/docs/prompts/project_info.md +++ b/docs/prompts/project_info.md @@ -6,7 +6,8 @@ Skyenet LLM Agent Platform 2. **Project Description:** - The Skyenet LLM Agent Platform is designed to facilitate the integration and utilization of large language models (LLMs) in various applications. It provides a framework for managing LLM interactions, handling user inputs, and displaying dynamic content. + The Skyenet LLM Agent Platform is designed to facilitate the integration and utilization of large language models (LLMs) in various applications. It provides a framework for + managing LLM interactions, handling user inputs, and displaying dynamic content. 3. **Project Objectives:** * To create a robust and flexible platform that supports real-time LLM interactions. @@ -30,7 +31,8 @@ providing a real-time, interactive UI framework. 2. **Scope:** - The project includes the development of an LLM agent platform that supports real-time interactions using large language models, dynamic content updates, and integration with various backend processes. + The project includes the development of an LLM agent platform that supports real-time interactions using large language models, dynamic content updates, and integration with + various backend processes. 3. **Deliverables:** * An LLM-based agent platform. @@ -88,7 +90,9 @@ 1. **System Architecture:** * Overview of the system architecture: - The Skyenet LLM Agent Platform is designed with a modular architecture to support real-time, interactive applications leveraging large language models. The core components include the LLM manager, session management, and dynamic content rendering. The system leverages LLMs for real-time interaction between the client and server, ensuring low latency and high + The Skyenet LLM Agent Platform is designed with a modular architecture to support real-time, interactive applications leveraging large language models. The core components + include the LLM manager, session management, and dynamic content rendering. The system leverages LLMs for real-time interaction between the client and server, ensuring low + latency and high responsiveness. The architecture is divided into several layers: the presentation layer (UI components), the application layer (session and task management), and the data layer (storage and retrieval of user data and settings). @@ -100,17 +104,17 @@ * What design patterns are used? The Skyenet LLM Agent Platform employs several design patterns to ensure a robust and maintainable codebase: - **Observer Pattern**: Used in the LLM manager to handle real-time updates and notifications. - **Factory Pattern**: Utilized for creating instances of various components like session tasks and UI elements. - **Singleton Pattern**: Ensures a single instance of core managers like `ApplicationServices` - - **Observer Pattern**: Used in the WebSocket manager to handle real-time updates and notifications. - - **Factory Pattern**: Utilized for creating instances of various components like session tasks and UI elements. - - **Singleton Pattern**: Ensures a single instance of core managers like `ApplicationServices` - and `SocketManagerBase`. - **Strategy Pattern**: Allows for flexible implementation of different retry mechanisms in the `Retryable` class. - **Decorator Pattern**: Used to extend the functionality of UI components dynamically. - - **Strategy Pattern**: Allows for flexible implementation of different retry mechanisms in the `Retryable` class. - - **Decorator Pattern**: Used to extend the functionality of UI components dynamically. +**Observer Pattern**: Used in the LLM manager to handle real-time updates and notifications. +**Factory Pattern**: Utilized for creating instances of various components like session tasks and UI elements. +**Singleton Pattern**: Ensures a single instance of core managers like `ApplicationServices` +- **Observer Pattern**: Used in the WebSocket manager to handle real-time updates and notifications. +- **Factory Pattern**: Utilized for creating instances of various components like session tasks and UI elements. +- **Singleton Pattern**: Ensures a single instance of core managers like `ApplicationServices` +and `SocketManagerBase`. +**Strategy Pattern**: Allows for flexible implementation of different retry mechanisms in the `Retryable` class. +**Decorator Pattern**: Used to extend the functionality of UI components dynamically. +- **Strategy Pattern**: Allows for flexible implementation of different retry mechanisms in the `Retryable` class. +- **Decorator Pattern**: Used to extend the functionality of UI components dynamically. * Why were they chosen? These design patterns were chosen to promote code reusability, flexibility, and separation of concerns. The @@ -126,20 +130,23 @@ - **Backend**: Kotlin for server-side logic, leveraging Ktor for building asynchronous servers and managing LLM interactions. - **LLMs**: Used for real-time interaction between the client and server. - **Database**: HSQLDB for usage tracking, data storage, and managing LLM interactions. - **Cloud Services**: AWS S3 for file storage, AWS KMS for encryption. - **CI/CD**: GitHub Actions for continuous integration and deployment, Docker for containerization. + **Cloud Services**: AWS S3 for file storage, AWS KMS for encryption. + **CI/CD**: GitHub Actions for continuous integration and deployment, Docker for containerization. - **Cloud Services**: AWS S3 for file storage, AWS KMS for encryption. - **CI/CD**: GitHub Actions for continuous integration and deployment, Docker for containerization. * Reasons for choosing these technologies: - The chosen technologies and frameworks provide a balance of performance, scalability, and developer productivity. Kotlin is used for both frontend and backend development to ensure consistency and leverage its modern language features. Ktor is selected for its lightweight and asynchronous capabilities, making it suitable for real-time LLM interactions. LLMs are essential for maintaining low-latency communication. HSQLDB is chosen for its + The chosen technologies and frameworks provide a balance of performance, scalability, and developer productivity. Kotlin is used for both frontend and backend development to + ensure consistency and leverage its modern language features. Ktor is selected for its lightweight and asynchronous capabilities, making it suitable for real-time LLM + interactions. LLMs are essential for maintaining low-latency communication. HSQLDB is chosen for its simplicity and ease of integration. AWS services are utilized for their reliability, security, and scalability. GitHub Actions and Docker streamline the CI/CD process, ensuring efficient and reliable deployments. ## Components and Modules 1. **Component Overview:** - * **LLMManagerBase**: Manages LLM interactions, message queuing, and broadcasting. It handles the core LLM functionality, ensuring reliable communication between the client and server. + * **LLMManagerBase**: Manages LLM interactions, message queuing, and broadcasting. It handles the core LLM functionality, ensuring reliable communication between the client and + server. * **ApplicationInterface**: Provides methods to create interactive HTML elements and manage tasks. It acts as a bridge between the task management logic and the LLM communication layer. * **SessionTask**: Represents a task that can display progress and messages. It allows for dynamic updates to the UI diff --git a/docs/prompts/project_info_template2.md b/docs/prompts/project_info_template2.md index 334bc5f3..cca8486d 100644 --- a/docs/prompts/project_info_template2.md +++ b/docs/prompts/project_info_template2.md @@ -4,49 +4,49 @@ 1. **Project Name:** 2. **Project Description:** - - What problem does this project solve? - - What are the key features and functionalities? + - What problem does this project solve? + - What are the key features and functionalities? 3. **Project Objectives:** - - What are the short-term and long-term goals? - - How will success be measured? + - What are the short-term and long-term goals? + - How will success be measured? 4. **Target Audience:** - - Who are the primary users? - - What are their needs and pain points? + - Who are the primary users? + - What are their needs and pain points? 5. **Scope:** - - What are the boundaries of the project? - - What will not be included in this project? + - What are the boundaries of the project? + - What will not be included in this project? ## Developer Documentation 1. **Code Repository:** - - Repository URL: - - Branching strategy: - - Contribution guidelines: + - Repository URL: + - Branching strategy: + - Contribution guidelines: 2. **Development Setup:** - - Prerequisites: - - Installation steps: - - Configuration details: - - How to run the project locally: - - How to run tests: + - Prerequisites: + - Installation steps: + - Configuration details: + - How to run the project locally: + - How to run tests: ## Architecture and Design - 1. **System Architecture:** +1. **System Architecture:** - Overview of the system architecture: - Diagrams (if any): - 2. **Design Patterns:** +2. **Design Patterns:** - What design patterns are used? - Why were they chosen? - 3. **Technology Stack:** +3. **Technology Stack:** - List of technologies and frameworks used: - Reasons for choosing these technologies: ## Components and Modules - 1. **Component Overview:** +1. **Component Overview:** - List of main components/modules: - Brief description of each component/module: - 2. **Inter-component Communication:** +2. **Inter-component Communication:** - How do components/modules interact with each other? - Data flow between components/modules: diff --git a/docs/ui/task_ui.md b/docs/ui/task_ui.md index 864b0892..906e5e8b 100644 --- a/docs/ui/task_ui.md +++ b/docs/ui/task_ui.md @@ -49,7 +49,7 @@ Displays a final message in the task output and hides the spinner, indicating th message is provided, only the spinner will be hidden without any additional text. ### Placeholder Mechanism - + Each `SessionTask` instance generates a unique placeholder in the UI, represented by an HTML `div` element with an `id` attribute set to the task's `operationID`. This placeholder serves as a dynamic container where task-related updates and outputs are rendered in real-time. This mechanism is crucial for maintaining a responsive and interactive user interface diff --git a/docs/webui_documentation.md b/docs/webui_documentation.md index 111e148d..520be049 100644 --- a/docs/webui_documentation.md +++ b/docs/webui_documentation.md @@ -90,743 +90,745 @@ building web applications, processing multimedia, or developing custom AI models need to bring your projects to life. + * [Skyenet Project Documentation](#skyenet-project-documentation) - * [Overview](#overview) - * [Key Components](#key-components) - * [Core Actors](#core-actors) - * [Actor System](#actor-system) - * [Platform Integration](#platform-integration) - * [Utility Classes](#utility-classes) - * [Development Guide](#development-guide) - * [Setting Up the Development Environment](#setting-up-the-development-environment) - * [Extending Skyenet](#extending-skyenet) - * [Testing](#testing) - * [Deployment](#deployment) - * [Contributing](#contributing) - * [Conclusion](#conclusion) + * [Overview](#overview) + * [Key Components](#key-components) + * [Core Actors](#core-actors) + * [Actor System](#actor-system) + * [Platform Integration](#platform-integration) + * [Utility Classes](#utility-classes) + * [Development Guide](#development-guide) + * [Setting Up the Development Environment](#setting-up-the-development-environment) + * [Extending Skyenet](#extending-skyenet) + * [Testing](#testing) + * [Deployment](#deployment) + * [Contributing](#contributing) + * [Conclusion](#conclusion) * [kotlin\com\simiacryptus\skyenet\apps\coding\ShellToolAgent.kt](#kotlincomsimiacryptusskyenetappscodingshelltoolagentkt) - * [ShellToolAgent Class Documentation](#shelltoolagent-class-documentation) - * [Key Features:](#key-features) - * [Core Components:](#core-components) - * [Usage:](#usage) - * [Key Methods:](#key-methods) - * [Extensibility:](#extensibility) - * [Error Handling:](#error-handling) - * [Conclusion](#conclusion-1) + * [ShellToolAgent Class Documentation](#shelltoolagent-class-documentation) + * [Key Features:](#key-features) + * [Core Components:](#core-components) + * [Usage:](#usage) + * [Key Methods:](#key-methods) + * [Extensibility:](#extensibility) + * [Error Handling:](#error-handling) + * [Conclusion](#conclusion-1) * [kotlin\com\simiacryptus\skyenet\apps\coding\CodingAgent.kt](#kotlincomsimiacryptusskyenetappscodingcodingagentkt) - * [CodingAgent Class Documentation](#codingagent-class-documentation) - * [Overview](#overview-1) - * [Key Components](#key-components-1) - * [Constructor Parameters](#constructor-parameters) - * [Methods](#methods) - * [start(userMessage: String)](#startusermessage-string) - * [displayCode(task: SessionTask, codeRequest: CodingActor.CodeRequest)](#displaycodetask-sessiontask-coderequest-codingactorcoderequest) - * [displayFeedback(task: SessionTask, request: CodingActor.CodeRequest, response: CodeResult)](#displayfeedbacktask-sessiontask-request-codingactorcoderequest-response-coderesult) - * [execute(task: SessionTask, response: CodeResult, request: CodingActor.CodeRequest)](#executetask-sessiontask-response-coderesult-request-codingactorcoderequest) - * [Usage Example](#usage-example) - * [Conclusion](#conclusion-2) + * [CodingAgent Class Documentation](#codingagent-class-documentation) + * [Overview](#overview-1) + * [Key Components](#key-components-1) + * [Constructor Parameters](#constructor-parameters) + * [Methods](#methods) + * [start(userMessage: String)](#startusermessage-string) + * [displayCode(task: SessionTask, codeRequest: CodingActor.CodeRequest)](#displaycodetask-sessiontask-coderequest-codingactorcoderequest) + * [displayFeedback(task: SessionTask, request: CodingActor.CodeRequest, response: CodeResult)](#displayfeedbacktask-sessiontask-request-codingactorcoderequest-response-coderesult) + * [execute(task: SessionTask, response: CodeResult, request: CodingActor.CodeRequest)](#executetask-sessiontask-response-coderesult-request-codingactorcoderequest) + * [Usage Example](#usage-example) + * [Conclusion](#conclusion-2) * [kotlin\com\github\simiacryptus\aicoder\util\SimpleDiffUtil.kt](#kotlincomgithubsimiacryptusaicoderutilsimplediffutilkt) - * [SimpleDiffUtil and SocketManagerBase Extensions Documentation](#simplediffutil-and-socketmanagerbase-extensions-documentation) - * [Overview](#overview-2) - * [SimpleDiffUtil](#simplediffutil) - * [Functionality](#functionality) - * [Methods](#methods-1) - * [Internal Mechanics](#internal-mechanics) - * [SocketManagerBase Extension Functions](#socketmanagerbase-extension-functions) - * [Functionality](#functionality-1) - * [Methods](#methods-2) - * [Usage Scenarios](#usage-scenarios) - * [Conclusion](#conclusion-3) + * [SimpleDiffUtil and SocketManagerBase Extensions Documentation](#simplediffutil-and-socketmanagerbase-extensions-documentation) + * [Overview](#overview-2) + * [SimpleDiffUtil](#simplediffutil) + * [Functionality](#functionality) + * [Methods](#methods-1) + * [Internal Mechanics](#internal-mechanics) + * [SocketManagerBase Extension Functions](#socketmanagerbase-extension-functions) + * [Functionality](#functionality-1) + * [Methods](#methods-2) + * [Usage Scenarios](#usage-scenarios) + * [Conclusion](#conclusion-3) * [kotlin\com\simiacryptus\skyenet\apps\general\WebDevApp.kt](#kotlincomsimiacryptusskyenetappsgeneralwebdevappkt) - * [Web Development Assistant Application Documentation](#web-development-assistant-application-documentation) - * [Overview](#overview-3) - * [Key Components](#key-components-2) - * [WebDevApp Class](#webdevapp-class) - * [Key Methods](#key-methods-1) - * [WebDevAgent Class](#webdevagent-class) - * [Key Methods](#key-methods-2) - * [Actors](#actors) - * [Usage](#usage-1) - * [Example](#example) - * [Conclusion](#conclusion-4) + * [Web Development Assistant Application Documentation](#web-development-assistant-application-documentation) + * [Overview](#overview-3) + * [Key Components](#key-components-2) + * [WebDevApp Class](#webdevapp-class) + * [Key Methods](#key-methods-1) + * [WebDevAgent Class](#webdevagent-class) + * [Key Methods](#key-methods-2) + * [Actors](#actors) + * [Usage](#usage-1) + * [Example](#example) + * [Conclusion](#conclusion-4) * [kotlin\com\simiacryptus\skyenet\apps\coding\ToolAgent.kt](#kotlincomsimiacryptusskyenetappscodingtoolagentkt) - * [ToolAgent Class Documentation](#toolagent-class-documentation) - * [Overview](#overview-4) - * [Key Components](#key-components-3) - * [Constructor Parameters](#constructor-parameters-1) - * [Methods](#methods-3) - * [`displayFeedback`](#displayfeedback) - * [`createToolButton`](#createtoolbutton) - * [`openAPIParsedActor`](#openapiparsedactor) - * [`servletActor`](#servletactor) - * [`schemaActor`](#schemaactor) - * [`displayCodeFeedback`](#displaycodefeedback) - * [`buildTestPage`](#buildtestpage) - * [`getInterpreterString`](#getinterpreterstring) - * [Utility Methods](#utility-methods) - * [Usage](#usage-2) - * [Example](#example-1) + * [ToolAgent Class Documentation](#toolagent-class-documentation) + * [Overview](#overview-4) + * [Key Components](#key-components-3) + * [Constructor Parameters](#constructor-parameters-1) + * [Methods](#methods-3) + * [`displayFeedback`](#displayfeedback) + * [`createToolButton`](#createtoolbutton) + * [`openAPIParsedActor`](#openapiparsedactor) + * [`servletActor`](#servletactor) + * [`schemaActor`](#schemaactor) + * [`displayCodeFeedback`](#displaycodefeedback) + * [`buildTestPage`](#buildtestpage) + * [`getInterpreterString`](#getinterpreterstring) + * [Utility Methods](#utility-methods) + * [Usage](#usage-2) + * [Example](#example-1) * [kotlin\com\simiacryptus\skyenet\AgentPatterns.kt](#kotlincomsimiacryptusskyenetagentpatternskt) - * [AgentPatterns Module Documentation](#agentpatterns-module-documentation) - * [Overview](#overview-5) - * [1. retryable Function](#1-retryable-function) - * [Parameters:](#parameters) - * [Returns:](#returns) - * [Usage Example:](#usage-example-1) - * [2. iterate Function](#2-iterate-function) - * [Parameters:](#parameters-1) - * [Returns:](#returns-1) - * [Usage Example:](#usage-example-2) - * [3. iterate Function (Overloaded Version)](#3-iterate-function-overloaded-version) - * [Parameters:](#parameters-2) - * [Returns:](#returns-2) - * [Usage Example:](#usage-example-3) - * [Conclusion](#conclusion-5) + * [AgentPatterns Module Documentation](#agentpatterns-module-documentation) + * [Overview](#overview-5) + * [1. retryable Function](#1-retryable-function) + * [Parameters:](#parameters) + * [Returns:](#returns) + * [Usage Example:](#usage-example-1) + * [2. iterate Function](#2-iterate-function) + * [Parameters:](#parameters-1) + * [Returns:](#returns-1) + * [Usage Example:](#usage-example-2) + * [3. iterate Function (Overloaded Version)](#3-iterate-function-overloaded-version) + * [Parameters:](#parameters-2) + * [Returns:](#returns-2) + * [Usage Example:](#usage-example-3) + * [Conclusion](#conclusion-5) * [kotlin\com\simiacryptus\skyenet\interpreter\ProcessInterpreter.kt](#kotlincomsimiacryptusskyenetinterpreterprocessinterpreterkt) - * [ProcessInterpreter Class Documentation](#processinterpreter-class-documentation) - * [Constructor](#constructor) - * [ProcessInterpreter](#processinterpreter) - * [Properties](#properties) - * [command](#command) - * [Methods](#methods-4) - * [getLanguage](#getlanguage) - * [getSymbols](#getsymbols) - * [validate](#validate) - * [run](#run) - * [Usage Example](#usage-example-4) - * [Notes](#notes) + * [ProcessInterpreter Class Documentation](#processinterpreter-class-documentation) + * [Constructor](#constructor) + * [ProcessInterpreter](#processinterpreter) + * [Properties](#properties) + * [command](#command) + * [Methods](#methods-4) + * [getLanguage](#getlanguage) + * [getSymbols](#getsymbols) + * [validate](#validate) + * [run](#run) + * [Usage Example](#usage-example-4) + * [Notes](#notes) * [kotlin\com\simiacryptus\skyenet\webui\application\ApplicationInterface.kt](#kotlincomsimiacryptusskyenetwebuiapplicationapplicationinterfacekt) - * [ApplicationInterface Documentation](#applicationinterface-documentation) - * [Constructor](#constructor-1) - * [ApplicationInterface(SocketManagerBase socketManager)](#applicationinterfacesocketmanagerbase-socketmanager) - * [Methods](#methods-5) - * [hrefLink](#hreflink) - * [textInput](#textinput) - * [newTask](#newtask) - * [Companion Object Methods](#companion-object-methods) - * [oneAtATime](#oneatatime) - * [Usage Example](#usage-example-5) + * [ApplicationInterface Documentation](#applicationinterface-documentation) + * [Constructor](#constructor-1) + * [ApplicationInterface(SocketManagerBase socketManager)](#applicationinterfacesocketmanagerbase-socketmanager) + * [Methods](#methods-5) + * [hrefLink](#hreflink) + * [textInput](#textinput) + * [newTask](#newtask) + * [Companion Object Methods](#companion-object-methods) + * [oneAtATime](#oneatatime) + * [Usage Example](#usage-example-5) * [kotlin\com\simiacryptus\skyenet\webui\application\ApplicationDirectory.kt](#kotlincomsimiacryptusskyenetwebuiapplicationapplicationdirectorykt) - * [Developer Documentation for `ApplicationDirectory` Class](#developer-documentation-for-applicationdirectory-class) - * [Overview](#overview-6) - * [Key Components](#key-components-4) - * [Properties](#properties-1) - * [Inner Classes](#inner-classes) - * [Methods](#methods-6) - * [Abstract and Open Methods](#abstract-and-open-methods) - * [Protected Methods](#protected-methods) - * [Companion Object](#companion-object) - * [Usage](#usage-3) - * [Conclusion](#conclusion-6) + * [Developer Documentation for `ApplicationDirectory` Class](#developer-documentation-for-applicationdirectory-class) + * [Overview](#overview-6) + * [Key Components](#key-components-4) + * [Properties](#properties-1) + * [Inner Classes](#inner-classes) + * [Methods](#methods-6) + * [Abstract and Open Methods](#abstract-and-open-methods) + * [Protected Methods](#protected-methods) + * [Companion Object](#companion-object) + * [Usage](#usage-3) + * [Conclusion](#conclusion-6) * [kotlin\com\simiacryptus\skyenet\webui\application\ApplicationServer.kt](#kotlincomsimiacryptusskyenetwebuiapplicationapplicationserverkt) - * [Developer Documentation for ApplicationServer](#developer-documentation-for-applicationserver) - * [Overview](#overview-7) - * [Key Components](#key-components-5) - * [Fields and Properties](#fields-and-properties) - * [Servlets and Filters](#servlets-and-filters) - * [Session Management](#session-management) - * [Settings Management](#settings-management) - * [Utility Methods](#utility-methods-1) - * [Usage](#usage-4) - * [Example](#example-2) - * [Conclusion](#conclusion-7) + * [Developer Documentation for ApplicationServer](#developer-documentation-for-applicationserver) + * [Overview](#overview-7) + * [Key Components](#key-components-5) + * [Fields and Properties](#fields-and-properties) + * [Servlets and Filters](#servlets-and-filters) + * [Session Management](#session-management) + * [Settings Management](#settings-management) + * [Utility Methods](#utility-methods-1) + * [Usage](#usage-4) + * [Example](#example-2) + * [Conclusion](#conclusion-7) * [kotlin\com\simiacryptus\skyenet\webui\application\ApplicationSocketManager.kt](#kotlincomsimiacryptusskyenetwebuiapplicationapplicationsocketmanagerkt) - * [ApplicationSocketManager Class Documentation](#applicationsocketmanager-class-documentation) - * [Overview](#overview-8) - * [Constructor](#constructor-2) - * [Key Methods and Properties](#key-methods-and-properties) - * [onRun](#onrun) - * [userMessage](#usermessage) - * [applicationInterface](#applicationinterface) - * [Companion Object](#companion-object-1) - * [spinner](#spinner) - * [Usage](#usage-5) - * [Conclusion](#conclusion-8) + * [ApplicationSocketManager Class Documentation](#applicationsocketmanager-class-documentation) + * [Overview](#overview-8) + * [Constructor](#constructor-2) + * [Key Methods and Properties](#key-methods-and-properties) + * [onRun](#onrun) + * [userMessage](#usermessage) + * [applicationInterface](#applicationinterface) + * [Companion Object](#companion-object-1) + * [spinner](#spinner) + * [Usage](#usage-5) + * [Conclusion](#conclusion-8) * [kotlin\com\simiacryptus\skyenet\webui\chat\ChatServer.kt](#kotlincomsimiacryptusskyenetwebuichatchatserverkt) - * [ChatServer Class Documentation](#chatserver-class-documentation) - * [Overview](#overview-9) - * [Key Components](#key-components-6) - * [Properties](#properties-2) - * [Inner Classes](#inner-classes-1) - * [WebSocketHandler](#websockethandler) - * [Key Methods](#key-methods-3) - * [Abstract Methods](#abstract-methods) - * [Open Properties](#open-properties) - * [Methods](#methods-7) - * [Usage](#usage-6) - * [Companion Object](#companion-object-2) - * [Properties](#properties-3) - * [Extension Functions](#extension-functions) - * [Conclusion](#conclusion-9) + * [ChatServer Class Documentation](#chatserver-class-documentation) + * [Overview](#overview-9) + * [Key Components](#key-components-6) + * [Properties](#properties-2) + * [Inner Classes](#inner-classes-1) + * [WebSocketHandler](#websockethandler) + * [Key Methods](#key-methods-3) + * [Abstract Methods](#abstract-methods) + * [Open Properties](#open-properties) + * [Methods](#methods-7) + * [Usage](#usage-6) + * [Companion Object](#companion-object-2) + * [Properties](#properties-3) + * [Extension Functions](#extension-functions) + * [Conclusion](#conclusion-9) * [kotlin\com\simiacryptus\skyenet\webui\chat\ChatSocket.kt](#kotlincomsimiacryptusskyenetwebuichatchatsocketkt) - * [ChatSocket Class Documentation](#chatsocket-class-documentation) - * [Dependencies](#dependencies) - * [Class Overview](#class-overview) - * [Usage](#usage-7) - * [Example](#example-3) - * [Conclusion](#conclusion-10) + * [ChatSocket Class Documentation](#chatsocket-class-documentation) + * [Dependencies](#dependencies) + * [Class Overview](#class-overview) + * [Usage](#usage-7) + * [Example](#example-3) + * [Conclusion](#conclusion-10) * [kotlin\com\simiacryptus\skyenet\webui\chat\ChatSocketManager.kt](#kotlincomsimiacryptusskyenetwebuichatchatsocketmanagerkt) - * [ChatSocketManager Class Documentation](#chatsocketmanager-class-documentation) - * [Constructor](#constructor-3) - * [Parameters](#parameters-3) - * [Methods](#methods-8) - * [onRun](#onrun-1) - * [Parameters](#parameters-4) - * [renderResponse](#renderresponse) - * [Parameters](#parameters-5) - * [Returns](#returns-3) - * [onResponse](#onresponse) - * [Parameters](#parameters-6) - * [Properties](#properties-4) - * [Companion Object](#companion-object-3) - * [Usage](#usage-8) - * [Error Handling](#error-handling-1) + * [ChatSocketManager Class Documentation](#chatsocketmanager-class-documentation) + * [Constructor](#constructor-3) + * [Parameters](#parameters-3) + * [Methods](#methods-8) + * [onRun](#onrun-1) + * [Parameters](#parameters-4) + * [renderResponse](#renderresponse) + * [Parameters](#parameters-5) + * [Returns](#returns-3) + * [onResponse](#onresponse) + * [Parameters](#parameters-6) + * [Properties](#properties-4) + * [Companion Object](#companion-object-3) + * [Usage](#usage-8) + * [Error Handling](#error-handling-1) * [kotlin\com\simiacryptus\skyenet\webui\servlet\ApiKeyServlet.kt](#kotlincomsimiacryptusskyenetwebuiservletapikeyservletkt) - * [API Key Servlet Documentation](#api-key-servlet-documentation) - * [Overview](#overview-10) - * [Data Model](#data-model) - * [ApiKeyRecord](#apikeyrecord) - * [Supported Operations](#supported-operations) - * [Handling GET Requests](#handling-get-requests) - * [Handling POST Requests](#handling-post-requests) - * [Interacting with the Servlet](#interacting-with-the-servlet) - * [Editing an API Key Record](#editing-an-api-key-record) - * [Deleting an API Key Record](#deleting-an-api-key-record) - * [Creating a New API Key Record](#creating-a-new-api-key-record) - * [Inviting a User to Use an API Key](#inviting-a-user-to-use-an-api-key) - * [Utility Methods](#utility-methods-2) - * [Storage](#storage) - * [Conclusion](#conclusion-11) + * [API Key Servlet Documentation](#api-key-servlet-documentation) + * [Overview](#overview-10) + * [Data Model](#data-model) + * [ApiKeyRecord](#apikeyrecord) + * [Supported Operations](#supported-operations) + * [Handling GET Requests](#handling-get-requests) + * [Handling POST Requests](#handling-post-requests) + * [Interacting with the Servlet](#interacting-with-the-servlet) + * [Editing an API Key Record](#editing-an-api-key-record) + * [Deleting an API Key Record](#deleting-an-api-key-record) + * [Creating a New API Key Record](#creating-a-new-api-key-record) + * [Inviting a User to Use an API Key](#inviting-a-user-to-use-an-api-key) + * [Utility Methods](#utility-methods-2) + * [Storage](#storage) + * [Conclusion](#conclusion-11) * [kotlin\com\simiacryptus\skyenet\webui\servlet\AppInfoServlet.kt](#kotlincomsimiacryptusskyenetwebuiservletappinfoservletkt) - * [AppInfoServlet Class Documentation](#appinfoservlet-class-documentation) - * [Generics](#generics) - * [Constructor](#constructor-4) - * [Methods](#methods-9) - * [`doGet(HttpServletRequest req, HttpServletResponse resp)`](#dogethttpservletrequest-req-httpservletresponse-resp) - * [Usage](#usage-9) - * [Dependencies](#dependencies-1) - * [Conclusion](#conclusion-12) + * [AppInfoServlet Class Documentation](#appinfoservlet-class-documentation) + * [Generics](#generics) + * [Constructor](#constructor-4) + * [Methods](#methods-9) + * [`doGet(HttpServletRequest req, HttpServletResponse resp)`](#dogethttpservletrequest-req-httpservletresponse-resp) + * [Usage](#usage-9) + * [Dependencies](#dependencies-1) + * [Conclusion](#conclusion-12) * [kotlin\com\simiacryptus\skyenet\webui\servlet\CancelThreadsServlet.kt](#kotlincomsimiacryptusskyenetwebuiservletcancelthreadsservletkt) - * [CancelThreadsServlet Documentation](#cancelthreadsservlet-documentation) - * [Class Overview](#class-overview-1) - * [Constructor](#constructor-5) - * [`CancelThreadsServlet(ApplicationServer server)`](#cancelthreadsservletapplicationserver-server) - * [Methods](#methods-10) - * [`doGet(HttpServletRequest req, HttpServletResponse resp)`](#dogethttpservletrequest-req-httpservletresponse-resp-1) - * [`doPost(HttpServletRequest req, HttpServletResponse resp)`](#doposthttpservletrequest-req-httpservletresponse-resp) - * [Usage](#usage-10) - * [Security Considerations](#security-considerations) - * [Error Handling](#error-handling-2) - * [Conclusion](#conclusion-13) + * [CancelThreadsServlet Documentation](#cancelthreadsservlet-documentation) + * [Class Overview](#class-overview-1) + * [Constructor](#constructor-5) + * [`CancelThreadsServlet(ApplicationServer server)`](#cancelthreadsservletapplicationserver-server) + * [Methods](#methods-10) + * [`doGet(HttpServletRequest req, HttpServletResponse resp)`](#dogethttpservletrequest-req-httpservletresponse-resp-1) + * [`doPost(HttpServletRequest req, HttpServletResponse resp)`](#doposthttpservletrequest-req-httpservletresponse-resp) + * [Usage](#usage-10) + * [Security Considerations](#security-considerations) + * [Error Handling](#error-handling-2) + * [Conclusion](#conclusion-13) * [kotlin\com\simiacryptus\skyenet\webui\servlet\CorsFilter.kt](#kotlincomsimiacryptusskyenetwebuiservletcorsfilterkt) - * [CorsFilter Class Documentation](#corsfilter-class-documentation) - * [Features](#features) - * [Usage](#usage-11) - * [Configuration](#configuration) - * [Methods](#methods-11) - * [CORS Headers Added](#cors-headers-added) - * [Example](#example-4) - * [Logging](#logging) - * [Conclusion](#conclusion-14) + * [CorsFilter Class Documentation](#corsfilter-class-documentation) + * [Features](#features) + * [Usage](#usage-11) + * [Configuration](#configuration) + * [Methods](#methods-11) + * [CORS Headers Added](#cors-headers-added) + * [Example](#example-4) + * [Logging](#logging) + * [Conclusion](#conclusion-14) * [kotlin\com\simiacryptus\skyenet\webui\servlet\FileServlet.kt](#kotlincomsimiacryptusskyenetwebuiservletfileservletkt) - * [FileServlet Class Documentation](#fileservlet-class-documentation) - * [Constructor](#constructor-6) - * [Methods](#methods-12) - * [Public Methods](#public-methods) - * [Private Methods](#private-methods) - * [Utility Methods](#utility-methods-3) - * [Companion Object](#companion-object-4) - * [Cache Configuration](#cache-configuration) - * [Exception Handling](#exception-handling) - * [Usage](#usage-12) - * [Example](#example-5) + * [FileServlet Class Documentation](#fileservlet-class-documentation) + * [Constructor](#constructor-6) + * [Methods](#methods-12) + * [Public Methods](#public-methods) + * [Private Methods](#private-methods) + * [Utility Methods](#utility-methods-3) + * [Companion Object](#companion-object-4) + * [Cache Configuration](#cache-configuration) + * [Exception Handling](#exception-handling) + * [Usage](#usage-12) + * [Example](#example-5) * [kotlin\com\simiacryptus\skyenet\webui\servlet\DeleteSessionServlet.kt](#kotlincomsimiacryptusskyenetwebuiservletdeletesessionservletkt) - * [DeleteSessionServlet Documentation](#deletesessionservlet-documentation) - * [Overview](#overview-11) - * [Usage](#usage-13) - * [Initialization](#initialization) - * [Handling GET Requests](#handling-get-requests-1) - * [Handling POST Requests](#handling-post-requests-1) - * [Security Considerations](#security-considerations-1) - * [Dependencies](#dependencies-2) - * [Conclusion](#conclusion-15) + * [DeleteSessionServlet Documentation](#deletesessionservlet-documentation) + * [Overview](#overview-11) + * [Usage](#usage-13) + * [Initialization](#initialization) + * [Handling GET Requests](#handling-get-requests-1) + * [Handling POST Requests](#handling-post-requests-1) + * [Security Considerations](#security-considerations-1) + * [Dependencies](#dependencies-2) + * [Conclusion](#conclusion-15) * [kotlin\com\simiacryptus\skyenet\webui\servlet\OAuthBase.kt](#kotlincomsimiacryptusskyenetwebuiservletoauthbasekt) - * [OAuthBase Class Documentation](#oauthbase-class-documentation) - * [Overview](#overview-12) - * [Usage](#usage-14) - * [Parameters](#parameters-7) - * [Methods](#methods-13) - * [`configure`](#configure) - * [Parameters:](#parameters-8) - * [Returns:](#returns-4) - * [Example](#example-6) - * [Conclusion](#conclusion-16) + * [OAuthBase Class Documentation](#oauthbase-class-documentation) + * [Overview](#overview-12) + * [Usage](#usage-14) + * [Parameters](#parameters-7) + * [Methods](#methods-13) + * [`configure`](#configure) + * [Parameters:](#parameters-8) + * [Returns:](#returns-4) + * [Example](#example-6) + * [Conclusion](#conclusion-16) * [kotlin\com\simiacryptus\skyenet\webui\servlet\LogoutServlet.kt](#kotlincomsimiacryptusskyenetwebuiservletlogoutservletkt) - * [LogoutServlet Documentation](#logoutservlet-documentation) - * [Overview](#overview-13) - * [Usage](#usage-15) - * [Key Methods](#key-methods-4) - * [Logout Process](#logout-process) - * [Error Handling](#error-handling-3) - * [Example Deployment Descriptor Configuration](#example-deployment-descriptor-configuration) - * [Conclusion](#conclusion-17) + * [LogoutServlet Documentation](#logoutservlet-documentation) + * [Overview](#overview-13) + * [Usage](#usage-15) + * [Key Methods](#key-methods-4) + * [Logout Process](#logout-process) + * [Error Handling](#error-handling-3) + * [Example Deployment Descriptor Configuration](#example-deployment-descriptor-configuration) + * [Conclusion](#conclusion-17) * [kotlin\com\simiacryptus\skyenet\webui\servlet\OAuthGoogle.kt](#kotlincomsimiacryptusskyenetwebuiservletoauthgooglekt) - * [OAuthGoogle Class Documentation](#oauthgoogle-class-documentation) - * [Overview](#overview-14) - * [Key Components](#key-components-7) - * [Usage](#usage-16) - * [Configuration Parameters](#configuration-parameters) - * [Example](#example-7) - * [Dependencies](#dependencies-3) - * [Important Notes](#important-notes) + * [OAuthGoogle Class Documentation](#oauthgoogle-class-documentation) + * [Overview](#overview-14) + * [Key Components](#key-components-7) + * [Usage](#usage-16) + * [Configuration Parameters](#configuration-parameters) + * [Example](#example-7) + * [Dependencies](#dependencies-3) + * [Important Notes](#important-notes) * [kotlin\com\simiacryptus\skyenet\webui\servlet\NewSessionServlet.kt](#kotlincomsimiacryptusskyenetwebuiservletnewsessionservletkt) - * [NewSessionServlet Documentation](#newsessionservlet-documentation) - * [Usage](#usage-17) - * [Implementation Details](#implementation-details) - * [Import Statements](#import-statements) - * [Class Definition](#class-definition) - * [doGet Method](#doget-method) - * [Parameters](#parameters-9) - * [Implementation](#implementation) - * [Example Usage](#example-usage) - * [Conclusion](#conclusion-18) + * [NewSessionServlet Documentation](#newsessionservlet-documentation) + * [Usage](#usage-17) + * [Implementation Details](#implementation-details) + * [Import Statements](#import-statements) + * [Class Definition](#class-definition) + * [doGet Method](#doget-method) + * [Parameters](#parameters-9) + * [Implementation](#implementation) + * [Example Usage](#example-usage) + * [Conclusion](#conclusion-18) * [kotlin\com\simiacryptus\skyenet\webui\servlet\SessionIdFilter.kt](#kotlincomsimiacryptusskyenetwebuiservletsessionidfilterkt) - * [SessionIdFilter Class Documentation](#sessionidfilter-class-documentation) - * [Package](#package) - * [Imports](#imports) - * [Constructor](#constructor-7) - * [Methods](#methods-14) - * [init](#init) - * [doFilter](#dofilter) - * [destroy](#destroy) - * [Usage Example](#usage-example-6) - * [Conclusion](#conclusion-19) + * [SessionIdFilter Class Documentation](#sessionidfilter-class-documentation) + * [Package](#package) + * [Imports](#imports) + * [Constructor](#constructor-7) + * [Methods](#methods-14) + * [init](#init) + * [doFilter](#dofilter) + * [destroy](#destroy) + * [Usage Example](#usage-example-6) + * [Conclusion](#conclusion-19) * [kotlin\com\simiacryptus\skyenet\webui\servlet\ProxyHttpServlet.kt](#kotlincomsimiacryptusskyenetwebuiservletproxyhttpservletkt) - * [ProxyHttpServlet Developer Documentation](#proxyhttpservlet-developer-documentation) - * [Overview](#overview-15) - * [Setup](#setup) - * [Key Components](#key-components-8) - * [Fields](#fields) - * [Methods](#methods-15) - * [`service(HttpServletRequest req, HttpServletResponse resp)`](#servicehttpservletrequest-req-httpservletresponse-resp) - * [`getProxyRequest(HttpServletRequest req)`](#getproxyrequesthttpservletrequest-req) - * [`onResponse(...)`](#onresponse-1) - * [`onRequest(HttpServletRequest req, ByteArray bytes)`](#onrequesthttpservletrequest-req-bytearray-bytes) - * [Usage Example](#usage-example-7) - * [Extending `ProxyHttpServlet`](#extending-proxyhttpservlet) - * [Conclusion](#conclusion-20) + * [ProxyHttpServlet Developer Documentation](#proxyhttpservlet-developer-documentation) + * [Overview](#overview-15) + * [Setup](#setup) + * [Key Components](#key-components-8) + * [Fields](#fields) + * [Methods](#methods-15) + * [`service(HttpServletRequest req, HttpServletResponse resp)`](#servicehttpservletrequest-req-httpservletresponse-resp) + * [`getProxyRequest(HttpServletRequest req)`](#getproxyrequesthttpservletrequest-req) + * [`onResponse(...)`](#onresponse-1) + * [`onRequest(HttpServletRequest req, ByteArray bytes)`](#onrequesthttpservletrequest-req-bytearray-bytes) + * [Usage Example](#usage-example-7) + * [Extending `ProxyHttpServlet`](#extending-proxyhttpservlet) + * [Conclusion](#conclusion-20) * [kotlin\com\simiacryptus\skyenet\webui\servlet\SessionSettingsServlet.kt](#kotlincomsimiacryptusskyenetwebuiservletsessionsettingsservletkt) - * [SessionSettingsServlet Documentation](#sessionsettingsservlet-documentation) - * [Overview](#overview-16) - * [Dependencies](#dependencies-4) - * [Constructor](#constructor-8) - * [Fields](#fields-1) - * [HTTP Methods](#http-methods) - * [doGet(HttpServletRequest req, HttpServletResponse resp)](#dogethttpservletrequest-req-httpservletresponse-resp-2) - * [Process Flow](#process-flow) - * [doPost(HttpServletRequest req, HttpServletResponse resp)](#doposthttpservletrequest-req-httpservletresponse-resp-1) - * [Process Flow](#process-flow-1) - * [Usage Example](#usage-example-8) + * [SessionSettingsServlet Documentation](#sessionsettingsservlet-documentation) + * [Overview](#overview-16) + * [Dependencies](#dependencies-4) + * [Constructor](#constructor-8) + * [Fields](#fields-1) + * [HTTP Methods](#http-methods) + * [doGet(HttpServletRequest req, HttpServletResponse resp)](#dogethttpservletrequest-req-httpservletresponse-resp-2) + * [Process Flow](#process-flow) + * [doPost(HttpServletRequest req, HttpServletResponse resp)](#doposthttpservletrequest-req-httpservletresponse-resp-1) + * [Process Flow](#process-flow-1) + * [Usage Example](#usage-example-8) * [kotlin\com\simiacryptus\skyenet\webui\servlet\SessionListServlet.kt](#kotlincomsimiacryptusskyenetwebuiservletsessionlistservletkt) - * [SessionListServlet Class Documentation](#sessionlistservlet-class-documentation) - * [Dependencies](#dependencies-5) - * [Constructor Parameters](#constructor-parameters-2) - * [Key Methods](#key-methods-5) - * [doGet(HttpServletRequest req, HttpServletResponse resp)](#dogethttpservletrequest-req-httpservletresponse-resp-3) - * [Parameters](#parameters-10) - * [Functionality](#functionality-2) - * [Usage Example](#usage-example-9) - * [Notes](#notes-1) + * [SessionListServlet Class Documentation](#sessionlistservlet-class-documentation) + * [Dependencies](#dependencies-5) + * [Constructor Parameters](#constructor-parameters-2) + * [Key Methods](#key-methods-5) + * [doGet(HttpServletRequest req, HttpServletResponse resp)](#dogethttpservletrequest-req-httpservletresponse-resp-3) + * [Parameters](#parameters-10) + * [Functionality](#functionality-2) + * [Usage Example](#usage-example-9) + * [Notes](#notes-1) * [kotlin\com\simiacryptus\skyenet\webui\servlet\SessionShareServlet.kt](#kotlincomsimiacryptusskyenetwebuiservletsessionshareservletkt) - * [SessionShareServlet Documentation](#sessionshareservlet-documentation) - * [Overview](#overview-17) - * [Key Components](#key-components-9) - * [Dependencies](#dependencies-6) - * [Main Methods](#main-methods) - * [doGet(HttpServletRequest req, HttpServletResponse resp)](#dogethttpservletrequest-req-httpservletresponse-resp-4) - * [Helper Methods](#helper-methods) - * [Usage](#usage-18) - * [Error Handling](#error-handling-4) - * [Security Considerations](#security-considerations-2) - * [Conclusion](#conclusion-21) + * [SessionShareServlet Documentation](#sessionshareservlet-documentation) + * [Overview](#overview-17) + * [Key Components](#key-components-9) + * [Dependencies](#dependencies-6) + * [Main Methods](#main-methods) + * [doGet(HttpServletRequest req, HttpServletResponse resp)](#dogethttpservletrequest-req-httpservletresponse-resp-4) + * [Helper Methods](#helper-methods) + * [Usage](#usage-18) + * [Error Handling](#error-handling-4) + * [Security Considerations](#security-considerations-2) + * [Conclusion](#conclusion-21) * [kotlin\com\simiacryptus\skyenet\webui\servlet\SessionThreadsServlet.kt](#kotlincomsimiacryptusskyenetwebuiservletsessionthreadsservletkt) - * [SessionThreadsServlet Documentation](#sessionthreadsservlet-documentation) - * [Overview](#overview-18) - * [Usage](#usage-19) - * [Request Parameters](#request-parameters) - * [Response](#response) - * [Example Request](#example-request) - * [Implementation Details](#implementation-details-1) - * [Key Components](#key-components-10) - * [HTML Response Generation](#html-response-generation) - * [Error Handling](#error-handling-5) - * [Security Considerations](#security-considerations-3) - * [Conclusion](#conclusion-22) + * [SessionThreadsServlet Documentation](#sessionthreadsservlet-documentation) + * [Overview](#overview-18) + * [Usage](#usage-19) + * [Request Parameters](#request-parameters) + * [Response](#response) + * [Example Request](#example-request) + * [Implementation Details](#implementation-details-1) + * [Key Components](#key-components-10) + * [HTML Response Generation](#html-response-generation) + * [Error Handling](#error-handling-5) + * [Security Considerations](#security-considerations-3) + * [Conclusion](#conclusion-22) * [kotlin\com\simiacryptus\skyenet\webui\servlet\ToolServlet.kt](#kotlincomsimiacryptusskyenetwebuiservlettoolservletkt) - * [ToolServlet Developer Documentation](#toolservlet-developer-documentation) - * [Overview](#overview-19) - * [Key Components](#key-components-11) - * [Tool Data Class](#tool-data-class) - * [Main Methods](#main-methods-1) - * [doGet(HttpServletRequest?, HttpServletResponse?)](#dogethttpservletrequest-httpservletresponse) - * [doPost(HttpServletRequest?, HttpServletResponse?)](#doposthttpservletrequest-httpservletresponse) - * [service(HttpServletRequest?, HttpServletResponse?)](#servicehttpservletrequest-httpservletresponse) - * [Utility Methods](#utility-methods-4) - * [indexPage(): String](#indexpage-string) - * [toolDetailsPage(tool: Tool): String](#tooldetailspagetool-tool-string) - * [serveEditPage(HttpServletRequest, HttpServletResponse, Tool)](#serveeditpagehttpservletrequest-httpservletresponse-tool) - * [Security](#security) - * [Extensibility](#extensibility-1) - * [Example Usage](#example-usage-1) - * [Conclusion](#conclusion-23) + * [ToolServlet Developer Documentation](#toolservlet-developer-documentation) + * [Overview](#overview-19) + * [Key Components](#key-components-11) + * [Tool Data Class](#tool-data-class) + * [Main Methods](#main-methods-1) + * [doGet(HttpServletRequest?, HttpServletResponse?)](#dogethttpservletrequest-httpservletresponse) + * [doPost(HttpServletRequest?, HttpServletResponse?)](#doposthttpservletrequest-httpservletresponse) + * [service(HttpServletRequest?, HttpServletResponse?)](#servicehttpservletrequest-httpservletresponse) + * [Utility Methods](#utility-methods-4) + * [indexPage(): String](#indexpage-string) + * [toolDetailsPage(tool: Tool): String](#tooldetailspagetool-tool-string) + * [serveEditPage(HttpServletRequest, HttpServletResponse, Tool)](#serveeditpagehttpservletrequest-httpservletresponse-tool) + * [Security](#security) + * [Extensibility](#extensibility-1) + * [Example Usage](#example-usage-1) + * [Conclusion](#conclusion-23) * [kotlin\com\simiacryptus\skyenet\webui\servlet\UserSettingsServlet.kt](#kotlincomsimiacryptusskyenetwebuiservletusersettingsservletkt) - * [UserSettingsServlet Documentation](#usersettingsservlet-documentation) - * [Overview](#overview-20) - * [Functionality](#functionality-3) - * [doGet(HttpServletRequest req, HttpServletResponse resp)](#dogethttpservletrequest-req-httpservletresponse-resp-5) - * [doPost(HttpServletRequest req, HttpServletResponse resp)](#doposthttpservletrequest-req-httpservletresponse-resp-2) - * [Security Considerations](#security-considerations-4) - * [Usage](#usage-20) - * [Conclusion](#conclusion-24) + * [UserSettingsServlet Documentation](#usersettingsservlet-documentation) + * [Overview](#overview-20) + * [Functionality](#functionality-3) + * [doGet(HttpServletRequest req, HttpServletResponse resp)](#dogethttpservletrequest-req-httpservletresponse-resp-5) + * [doPost(HttpServletRequest req, HttpServletResponse resp)](#doposthttpservletrequest-req-httpservletresponse-resp-2) + * [Security Considerations](#security-considerations-4) + * [Usage](#usage-20) + * [Conclusion](#conclusion-24) * [kotlin\com\simiacryptus\skyenet\webui\servlet\WelcomeServlet.kt](#kotlincomsimiacryptusskyenetwebuiservletwelcomeservletkt) - * [WelcomeServlet Class Documentation](#welcomeservlet-class-documentation) - * [Constructor](#constructor-9) - * [Methods](#methods-16) - * [doGet(HttpServletRequest req, HttpServletResponse resp)](#dogethttpservletrequest-req-httpservletresponse-resp-6) - * [doPost(HttpServletRequest req, HttpServletResponse resp)](#doposthttpservletrequest-req-httpservletresponse-resp-3) - * [homepage(User user)](#homepageuser-user) - * [appRow(ApplicationDirectory.ChildWebApp app, User user)](#approwapplicationdirectorychildwebapp-app-user-user) - * [Fields](#fields-2) - * [Usage](#usage-21) - * [Security](#security-1) + * [WelcomeServlet Class Documentation](#welcomeservlet-class-documentation) + * [Constructor](#constructor-9) + * [Methods](#methods-16) + * [doGet(HttpServletRequest req, HttpServletResponse resp)](#dogethttpservletrequest-req-httpservletresponse-resp-6) + * [doPost(HttpServletRequest req, HttpServletResponse resp)](#doposthttpservletrequest-req-httpservletresponse-resp-3) + * [homepage(User user)](#homepageuser-user) + * [appRow(ApplicationDirectory.ChildWebApp app, User user)](#approwapplicationdirectorychildwebapp-app-user-user) + * [Fields](#fields-2) + * [Usage](#usage-21) + * [Security](#security-1) * [kotlin\com\simiacryptus\skyenet\webui\servlet\UserInfoServlet.kt](#kotlincomsimiacryptusskyenetwebuiservletuserinfoservletkt) - * [UserInfoServlet Documentation](#userinfoservlet-documentation) - * [Package](#package-1) - * [Dependencies](#dependencies-7) - * [Class Overview](#class-overview-2) - * [UserInfoServlet](#userinfoservlet) - * [Methods](#methods-17) - * [Usage](#usage-22) - * [Example Response](#example-response) - * [Security Considerations](#security-considerations-5) - * [Conclusion](#conclusion-25) + * [UserInfoServlet Documentation](#userinfoservlet-documentation) + * [Package](#package-1) + * [Dependencies](#dependencies-7) + * [Class Overview](#class-overview-2) + * [UserInfoServlet](#userinfoservlet) + * [Methods](#methods-17) + * [Usage](#usage-22) + * [Example Response](#example-response) + * [Security Considerations](#security-considerations-5) + * [Conclusion](#conclusion-25) * [kotlin\com\simiacryptus\skyenet\webui\servlet\UsageServlet.kt](#kotlincomsimiacryptusskyenetwebuiservletusageservletkt) - * [UsageServlet Documentation](#usageservlet-documentation) - * [Overview](#overview-21) - * [Key Methods](#key-methods-6) - * [doGet(HttpServletRequest req, HttpServletResponse resp)](#dogethttpservletrequest-req-httpservletresponse-resp-7) - * [serve(HttpServletResponse resp, Map usage)](#servehttpservletresponse-resp-mapopenaimodel-apimodelusage-usage) - * [Usage Example](#usage-example-10) - * [Security Considerations](#security-considerations-6) - * [Dependencies](#dependencies-8) + * [UsageServlet Documentation](#usageservlet-documentation) + * [Overview](#overview-21) + * [Key Methods](#key-methods-6) + * [doGet(HttpServletRequest req, HttpServletResponse resp)](#dogethttpservletrequest-req-httpservletresponse-resp-7) + * [serve(HttpServletResponse resp, Map usage)](#servehttpservletresponse-resp-mapopenaimodel-apimodelusage-usage) + * [Usage Example](#usage-example-10) + * [Security Considerations](#security-considerations-6) + * [Dependencies](#dependencies-8) * [kotlin\com\simiacryptus\skyenet\webui\servlet\ZipServlet.kt](#kotlincomsimiacryptusskyenetwebuiservletzipservletkt) - * [ZipServlet Class Documentation](#zipservlet-class-documentation) - * [Dependencies](#dependencies-9) - * [Constructor](#constructor-10) - * [Public Methods](#public-methods-1) - * [`doGet(HttpServletRequest req, HttpServletResponse resp)`](#dogethttpservletrequest-req-httpservletresponse-resp-8) - * [Private Methods](#private-methods-1) - * [`write(basePath: File, file: File, zip: ZipOutputStream)`](#writebasepath-file-file-file-zip-zipoutputstream) - * [Usage Example](#usage-example-11) - * [Security Considerations](#security-considerations-7) + * [ZipServlet Class Documentation](#zipservlet-class-documentation) + * [Dependencies](#dependencies-9) + * [Constructor](#constructor-10) + * [Public Methods](#public-methods-1) + * [`doGet(HttpServletRequest req, HttpServletResponse resp)`](#dogethttpservletrequest-req-httpservletresponse-resp-8) + * [Private Methods](#private-methods-1) + * [`write(basePath: File, file: File, zip: ZipOutputStream)`](#writebasepath-file-file-file-zip-zipoutputstream) + * [Usage Example](#usage-example-11) + * [Security Considerations](#security-considerations-7) * [kotlin\com\simiacryptus\skyenet\webui\session\SocketManager.kt](#kotlincomsimiacryptusskyenetwebuisessionsocketmanagerkt) - * [SocketManager Interface Documentation](#socketmanager-interface-documentation) - * [Interface Overview](#interface-overview) - * [Methods](#methods-18) - * [`removeSocket(socket: ChatSocket)`](#removesocketsocket-chatsocket) - * [`addSocket(socket: ChatSocket, session: Session)`](#addsocketsocket-chatsocket-session-session) - * [`getReplay(): List`](#getreplay-liststring) - * [`onWebSocketText(socket: ChatSocket, message: String)`](#onwebsockettextsocket-chatsocket-message-string) - * [Usage Example](#usage-example-12) - * [Conclusion](#conclusion-26) + * [SocketManager Interface Documentation](#socketmanager-interface-documentation) + * [Interface Overview](#interface-overview) + * [Methods](#methods-18) + * [`removeSocket(socket: ChatSocket)`](#removesocketsocket-chatsocket) + * [`addSocket(socket: ChatSocket, session: Session)`](#addsocketsocket-chatsocket-session-session) + * [`getReplay(): List`](#getreplay-liststring) + * [`onWebSocketText(socket: ChatSocket, message: String)`](#onwebsockettextsocket-chatsocket-message-string) + * [Usage Example](#usage-example-12) + * [Conclusion](#conclusion-26) * [kotlin\com\simiacryptus\skyenet\webui\session\SocketManagerBase.kt](#kotlincomsimiacryptusskyenetwebuisessionsocketmanagerbasekt) - * [SocketManagerBase Class Documentation](#socketmanagerbase-class-documentation) - * [Overview](#overview-22) - * [Key Components](#key-components-12) - * [Fields](#fields-3) - * [Constructor](#constructor-11) - * [Methods](#methods-19) - * [Public](#public) - * [Protected](#protected) - * [Private](#private) - * [Inner Classes](#inner-classes-2) - * [Utility Functions](#utility-functions) - * [Usage](#usage-23) - * [Example](#example-8) + * [SocketManagerBase Class Documentation](#socketmanagerbase-class-documentation) + * [Overview](#overview-22) + * [Key Components](#key-components-12) + * [Fields](#fields-3) + * [Constructor](#constructor-11) + * [Methods](#methods-19) + * [Public](#public) + * [Protected](#protected) + * [Private](#private) + * [Inner Classes](#inner-classes-2) + * [Utility Functions](#utility-functions) + * [Usage](#usage-23) + * [Example](#example-8) * [kotlin\com\simiacryptus\skyenet\webui\test\ImageActorTestApp.kt](#kotlincomsimiacryptusskyenetwebuitestimageactortestappkt) - * [ImageActorTestApp Developer Documentation](#imageactortestapp-developer-documentation) - * [Overview](#overview-23) - * [Key Components](#key-components-13) - * [Constructor](#constructor-12) - * [Settings Data Class](#settings-data-class) - * [Overridden Methods](#overridden-methods) - * [initSettings](#initsettings) - * [userMessage](#usermessage-1) - * [Companion Object](#companion-object-5) - * [Usage](#usage-24) - * [Error Handling](#error-handling-6) - * [Conclusion](#conclusion-27) + * [ImageActorTestApp Developer Documentation](#imageactortestapp-developer-documentation) + * [Overview](#overview-23) + * [Key Components](#key-components-13) + * [Constructor](#constructor-12) + * [Settings Data Class](#settings-data-class) + * [Overridden Methods](#overridden-methods) + * [initSettings](#initsettings) + * [userMessage](#usermessage-1) + * [Companion Object](#companion-object-5) + * [Usage](#usage-24) + * [Error Handling](#error-handling-6) + * [Conclusion](#conclusion-27) * [kotlin\com\simiacryptus\skyenet\webui\test\CodingActorTestApp.kt](#kotlincomsimiacryptusskyenetwebuitestcodingactortestappkt) - * [CodingActorTestApp Class Documentation](#codingactortestapp-class-documentation) - * [Constructor](#constructor-13) - * [Parameters:](#parameters-11) - * [Methods](#methods-20) - * [userMessage](#usermessage-2) - * [Parameters:](#parameters-12) - * [Usage](#usage-25) - * [Companion Object](#companion-object-6) - * [Example](#example-9) - * [Note](#note) + * [CodingActorTestApp Class Documentation](#codingactortestapp-class-documentation) + * [Constructor](#constructor-13) + * [Parameters:](#parameters-11) + * [Methods](#methods-20) + * [userMessage](#usermessage-2) + * [Parameters:](#parameters-12) + * [Usage](#usage-25) + * [Companion Object](#companion-object-6) + * [Example](#example-9) + * [Note](#note) * [kotlin\com\simiacryptus\skyenet\webui\test\ParsedActorTestApp.kt](#kotlincomsimiacryptusskyenetwebuitestparsedactortestappkt) - * [ParsedActorTestApp Class Documentation](#parsedactortestapp-class-documentation) - * [Overview](#overview-24) - * [Constructor](#constructor-14) - * [Parameters](#parameters-13) - * [Methods](#methods-21) - * [userMessage](#usermessage-3) - * [Parameters](#parameters-14) - * [Companion Object](#companion-object-7) - * [Properties](#properties-5) - * [Usage Example](#usage-example-13) - * [Conclusion](#conclusion-28) + * [ParsedActorTestApp Class Documentation](#parsedactortestapp-class-documentation) + * [Overview](#overview-24) + * [Constructor](#constructor-14) + * [Parameters](#parameters-13) + * [Methods](#methods-21) + * [userMessage](#usermessage-3) + * [Parameters](#parameters-14) + * [Companion Object](#companion-object-7) + * [Properties](#properties-5) + * [Usage Example](#usage-example-13) + * [Conclusion](#conclusion-28) * [kotlin\com\simiacryptus\skyenet\webui\test\SimpleActorTestApp.kt](#kotlincomsimiacryptusskyenetwebuitestsimpleactortestappkt) - * [SimpleActorTestApp Documentation](#simpleactortestapp-documentation) - * [Overview](#overview-25) - * [Key Components](#key-components-14) - * [Constructor](#constructor-15) - * [Settings Data Class](#settings-data-class-1) - * [User Message Handling](#user-message-handling) - * [Logging](#logging-1) - * [Usage](#usage-26) - * [Conclusion](#conclusion-29) + * [SimpleActorTestApp Documentation](#simpleactortestapp-documentation) + * [Overview](#overview-25) + * [Key Components](#key-components-14) + * [Constructor](#constructor-15) + * [Settings Data Class](#settings-data-class-1) + * [User Message Handling](#user-message-handling) + * [Logging](#logging-1) + * [Usage](#usage-26) + * [Conclusion](#conclusion-29) * [kotlin\com\simiacryptus\skyenet\webui\util\MarkdownUtil.kt](#kotlincomsimiacryptusskyenetwebuiutilmarkdownutilkt) - * [MarkdownUtil Documentation](#markdownutil-documentation) - * [Functions](#functions) - * [renderMarkdown](#rendermarkdown) - * [Parameters:](#parameters-15) - * [Returns:](#returns-5) - * [Usage Example:](#usage-example-14) - * [defaultOptions](#defaultoptions) - * [Returns:](#returns-6) - * [Implementation Details](#implementation-details-2) - * [Notes](#notes-2) + * [MarkdownUtil Documentation](#markdownutil-documentation) + * [Functions](#functions) + * [renderMarkdown](#rendermarkdown) + * [Parameters:](#parameters-15) + * [Returns:](#returns-5) + * [Usage Example:](#usage-example-14) + * [defaultOptions](#defaultoptions) + * [Returns:](#returns-6) + * [Implementation Details](#implementation-details-2) + * [Notes](#notes-2) * [kotlin\com\simiacryptus\skyenet\webui\session\SessionTask.kt](#kotlincomsimiacryptusskyenetwebuisessionsessiontaskkt) - * [SessionTask Class Documentation](#sessiontask-class-documentation) - * [Overview](#overview-26) - * [Properties](#properties-6) - * [Methods](#methods-22) - * [Abstract Methods](#abstract-methods-1) - * [Public Methods](#public-methods-2) - * [Companion Object](#companion-object-8) - * [Usage](#usage-27) - * [Example](#example-10) + * [SessionTask Class Documentation](#sessiontask-class-documentation) + * [Overview](#overview-26) + * [Properties](#properties-6) + * [Methods](#methods-22) + * [Abstract Methods](#abstract-methods-1) + * [Public Methods](#public-methods-2) + * [Companion Object](#companion-object-8) + * [Usage](#usage-27) + * [Example](#example-10) * [kotlin\com\simiacryptus\skyenet\webui\util\EncryptFiles.kt](#kotlincomsimiacryptusskyenetwebuiutilencryptfileskt) - * [EncryptFiles Utility Documentation](#encryptfiles-utility-documentation) - * [Overview](#overview-27) - * [Usage](#usage-28) - * [Prerequisites](#prerequisites) - * [Encrypting and Writing Data](#encrypting-and-writing-data) - * [Extension Functions](#extension-functions-1) - * [Example](#example-11) - * [Conclusion](#conclusion-30) + * [EncryptFiles Utility Documentation](#encryptfiles-utility-documentation) + * [Overview](#overview-27) + * [Usage](#usage-28) + * [Prerequisites](#prerequisites) + * [Encrypting and Writing Data](#encrypting-and-writing-data) + * [Extension Functions](#extension-functions-1) + * [Example](#example-11) + * [Conclusion](#conclusion-30) * [kotlin\com\simiacryptus\skyenet\webui\util\OpenAPI.kt](#kotlincomsimiacryptusskyenetwebuiutilopenapikt) - * [Skyenet WebUI Util - OpenAPI Data Classes Documentation](#skyenet-webui-util---openapi-data-classes-documentation) - * [Overview](#overview-28) - * [OpenAPI](#openapi) - * [Info](#info) - * [Contact](#contact) - * [License](#license) - * [PathItem](#pathitem) - * [Operation](#operation) - * [Response](#response-1) - * [Components](#components) - * [Schema](#schema) - * [Parameter](#parameter) - * [Example, RequestBody, Header, SecurityScheme, Link, Callback, MediaType](#example-requestbody-header-securityscheme-link-callback-mediatype) + * [Skyenet WebUI Util - OpenAPI Data Classes Documentation](#skyenet-webui-util---openapi-data-classes-documentation) + * [Overview](#overview-28) + * [OpenAPI](#openapi) + * [Info](#info) + * [Contact](#contact) + * [License](#license) + * [PathItem](#pathitem) + * [Operation](#operation) + * [Response](#response-1) + * [Components](#components) + * [Schema](#schema) + * [Parameter](#parameter) + * [Example, RequestBody, Header, SecurityScheme, Link, Callback, MediaType](#example-requestbody-header-securityscheme-link-callback-mediatype) * [kotlin\com\simiacryptus\skyenet\webui\util\TensorflowProjector.kt](#kotlincomsimiacryptusskyenetwebuiutiltensorflowprojectorkt) - * [TensorflowProjector Class Documentation](#tensorflowprojector-class-documentation) - * [Constructor](#constructor-16) - * [Methods](#methods-23) - * [`toVectorMap(vararg words: String): Map`](#tovectormapvararg-words-string-mapstring-doublearray) - * [`writeTensorflowEmbeddingProjectorHtml(vararg words: String): String`](#writetensorflowembeddingprojectorhtmlvararg-words-string-string) - * [Usage Example](#usage-example-15) - * [Notes](#notes-3) + * [TensorflowProjector Class Documentation](#tensorflowprojector-class-documentation) + * [Constructor](#constructor-16) + * [Methods](#methods-23) + * [`toVectorMap(vararg words: String): Map`](#tovectormapvararg-words-string-mapstring-doublearray) + * [`writeTensorflowEmbeddingProjectorHtml(vararg words: String): String`](#writetensorflowembeddingprojectorhtmlvararg-words-string-string) + * [Usage Example](#usage-example-15) + * [Notes](#notes-3) * [kotlin\com\simiacryptus\skyenet\webui\util\Selenium2S3.kt](#kotlincomsimiacryptusskyenetwebuiutilselenium2s3kt) - * [Developer Documentation for Selenium2S3 Class](#developer-documentation-for-selenium2s3-class) - * [Overview](#overview-29) - * [Key Features](#key-features-1) - * [Initialization](#initialization-1) - * [Core Methods](#core-methods) - * [save](#save) - * [process](#process) - * [getHtml, getJson, getMedia](#gethtml-getjson-getmedia) - * [saveJS, saveHTML](#savejs-savehtml) - * [Utility Methods](#utility-methods-5) - * [Closing Resources](#closing-resources) - * [Companion Object](#companion-object-9) - * [chromeDriver](#chromedriver) - * [setCookies](#setcookies) - * [Usage Example](#usage-example-16) + * [Developer Documentation for Selenium2S3 Class](#developer-documentation-for-selenium2s3-class) + * [Overview](#overview-29) + * [Key Features](#key-features-1) + * [Initialization](#initialization-1) + * [Core Methods](#core-methods) + * [save](#save) + * [process](#process) + * [getHtml, getJson, getMedia](#gethtml-getjson-getmedia) + * [saveJS, saveHTML](#savejs-savehtml) + * [Utility Methods](#utility-methods-5) + * [Closing Resources](#closing-resources) + * [Companion Object](#companion-object-9) + * [chromeDriver](#chromedriver) + * [setCookies](#setcookies) + * [Usage Example](#usage-example-16) * [resources\application\chat.js](#resourcesapplicationchatjs) - * [WebSocket Communication Module](#websocket-communication-module) - * [Functions](#functions-1) - * [getSessionId()](#getsessionid) - * [send(message)](#sendmessage) - * [connect(sessionId, customReceiveFunction)](#connectsessionid-customreceivefunction) - * [showDisconnectedOverlay(show)](#showdisconnectedoverlayshow) - * [Usage Example](#usage-example-17) + * [WebSocket Communication Module](#websocket-communication-module) + * [Functions](#functions-1) + * [getSessionId()](#getsessionid) + * [send(message)](#sendmessage) + * [connect(sessionId, customReceiveFunction)](#connectsessionid-customreceivefunction) + * [showDisconnectedOverlay(show)](#showdisconnectedoverlayshow) + * [Usage Example](#usage-example-17) * [resources\application\index.html](#resourcesapplicationindexhtml) - * [WebSocket Client Web Application Documentation](#websocket-client-web-application-documentation) - * [Overview](#overview-30) - * [Dependencies](#dependencies-10) - * [External Libraries and Stylesheets](#external-libraries-and-stylesheets) - * [HTML Structure](#html-structure) - * [Head Section](#head-section) - * [Body Section](#body-section) - * [Toolbar](#toolbar) - * [Namebar](#namebar) - * [Session](#session) - * [Modal](#modal) - * [Footer](#footer) - * [Functionality](#functionality-4) - * [Scripts](#scripts) - * [Prism.js](#prismjs) - * [Mermaid.js](#mermaidjs) - * [Application Scripts](#application-scripts) - * [Conclusion](#conclusion-31) + * [WebSocket Client Web Application Documentation](#websocket-client-web-application-documentation) + * [Overview](#overview-30) + * [Dependencies](#dependencies-10) + * [External Libraries and Stylesheets](#external-libraries-and-stylesheets) + * [HTML Structure](#html-structure) + * [Head Section](#head-section) + * [Body Section](#body-section) + * [Toolbar](#toolbar) + * [Namebar](#namebar) + * [Session](#session) + * [Modal](#modal) + * [Footer](#footer) + * [Functionality](#functionality-4) + * [Scripts](#scripts) + * [Prism.js](#prismjs) + * [Mermaid.js](#mermaidjs) + * [Application Scripts](#application-scripts) + * [Conclusion](#conclusion-31) * [resources\application\main.js](#resourcesapplicationmainjs) - * [Developer Documentation](#developer-documentation) - * [Overview](#overview-31) - * [Functions](#functions-2) - * [showModal(endpoint, useSession = true)](#showmodalendpoint-usesession--true) - * [closeModal()](#closemodal) - * [async fetchData(endpoint, useSession = true)](#async-fetchdataendpoint-usesession--true) - * [onWebSocketText(event)](#onwebsockettextevent) - * [updateTabs()](#updatetabs) - * [toggleVerbose()](#toggleverbose) - * [refreshReplyForms()](#refreshreplyforms) - * [refreshVerbose()](#refreshverbose) - * [Event Listeners](#event-listeners) - * [Theme Change](#theme-change) - * [Modal Triggers](#modal-triggers) - * [Form Submission](#form-submission) - * [Input Field Auto-Resize](#input-field-auto-resize) - * [Fetch User Information](#fetch-user-information) - * [Privacy and Terms Links](#privacy-and-terms-links) - * [Conclusion](#conclusion-32) + * [Developer Documentation](#developer-documentation) + * [Overview](#overview-31) + * [Functions](#functions-2) + * [showModal(endpoint, useSession = true)](#showmodalendpoint-usesession--true) + * [closeModal()](#closemodal) + * [async fetchData(endpoint, useSession = true)](#async-fetchdataendpoint-usesession--true) + * [onWebSocketText(event)](#onwebsockettextevent) + * [updateTabs()](#updatetabs) + * [toggleVerbose()](#toggleverbose) + * [refreshReplyForms()](#refreshreplyforms) + * [refreshVerbose()](#refreshverbose) + * [Event Listeners](#event-listeners) + * [Theme Change](#theme-change) + * [Modal Triggers](#modal-triggers) + * [Form Submission](#form-submission) + * [Input Field Auto-Resize](#input-field-auto-resize) + * [Fetch User Information](#fetch-user-information) + * [Privacy and Terms Links](#privacy-and-terms-links) + * [Conclusion](#conclusion-32) * [resources\shared\schemes\_alien_spaceship.scss](#resourcessharedschemes_alien_spaceshipscss) - * [Alien Spaceship Theme - Developer Documentation](#alien-spaceship-theme---developer-documentation) - * [Base Colors](#base-colors) - * [Derived Colors](#derived-colors) - * [Usage](#usage-29) - * [Buttons](#buttons) - * [Messages](#messages) - * [Modals](#modals) - * [Conclusion](#conclusion-33) + * [Alien Spaceship Theme - Developer Documentation](#alien-spaceship-theme---developer-documentation) + * [Base Colors](#base-colors) + * [Derived Colors](#derived-colors) + * [Usage](#usage-29) + * [Buttons](#buttons) + * [Messages](#messages) + * [Modals](#modals) + * [Conclusion](#conclusion-33) * [resources\shared\schemes\_forest.scss](#resourcessharedschemes_forestscss) - * [Forest Canopy Theme - Developer Documentation](#forest-canopy-theme---developer-documentation) - * [Importing the Theme](#importing-the-theme) - * [Typography Variables](#typography-variables) - * [Base Colors](#base-colors-1) - * [Derived Colors](#derived-colors-1) - * [Buttons](#buttons-1) - * [Forms](#forms) - * [Messages and Modals](#messages-and-modals) - * [Customization](#customization) - * [Conclusion](#conclusion-34) + * [Forest Canopy Theme - Developer Documentation](#forest-canopy-theme---developer-documentation) + * [Importing the Theme](#importing-the-theme) + * [Typography Variables](#typography-variables) + * [Base Colors](#base-colors-1) + * [Derived Colors](#derived-colors-1) + * [Buttons](#buttons-1) + * [Forms](#forms) + * [Messages and Modals](#messages-and-modals) + * [Customization](#customization) + * [Conclusion](#conclusion-34) * [resources\shared\schemes\_night.scss](#resourcessharedschemes_nightscss) - * [Nighttime Theme Color Scheme Documentation](#nighttime-theme-color-scheme-documentation) - * [Base Colors](#base-colors-2) - * [Derived Colors](#derived-colors-2) - * [Component Styling](#component-styling) - * [Buttons](#buttons-2) - * [Forms](#forms-1) - * [Messages and Modals](#messages-and-modals-1) - * [Utility Variables](#utility-variables) - * [Usage](#usage-30) + * [Nighttime Theme Color Scheme Documentation](#nighttime-theme-color-scheme-documentation) + * [Base Colors](#base-colors-2) + * [Derived Colors](#derived-colors-2) + * [Component Styling](#component-styling) + * [Buttons](#buttons-2) + * [Forms](#forms-1) + * [Messages and Modals](#messages-and-modals-1) + * [Utility Variables](#utility-variables) + * [Usage](#usage-30) * [resources\shared\schemes\_normal.scss](#resourcessharedschemes_normalscss) - * [Developer Documentation: UI Theme Variables](#developer-documentation-ui-theme-variables) - * [Typography Variables](#typography-variables-1) - * [Base Colors](#base-colors-3) - * [Derived Colors](#derived-colors-3) - * [Buttons](#buttons-3) - * [Forms](#forms-2) - * [Messages and Modals](#messages-and-modals-2) + * [Developer Documentation: UI Theme Variables](#developer-documentation-ui-theme-variables) + * [Typography Variables](#typography-variables-1) + * [Base Colors](#base-colors-3) + * [Derived Colors](#derived-colors-3) + * [Buttons](#buttons-3) + * [Forms](#forms-2) + * [Messages and Modals](#messages-and-modals-2) * [resources\shared\schemes\_pony.scss](#resourcessharedschemes_ponyscss) - * [Developer Documentation: Theme Customization](#developer-documentation-theme-customization) - * [Typography Variables](#typography-variables-2) - * [Base Colors](#base-colors-4) - * [Derived Colors](#derived-colors-4) - * [Buttons](#buttons-4) - * [Forms](#forms-3) - * [Messages and Modals](#messages-and-modals-3) - * [Usage](#usage-31) + * [Developer Documentation: Theme Customization](#developer-documentation-theme-customization) + * [Typography Variables](#typography-variables-2) + * [Base Colors](#base-colors-4) + * [Derived Colors](#derived-colors-4) + * [Buttons](#buttons-4) + * [Forms](#forms-3) + * [Messages and Modals](#messages-and-modals-3) + * [Usage](#usage-31) * [resources\application\favicon.svg](#resourcesapplicationfaviconsvg) - * [Developer Documentation: SVG Graphic Implementation](#developer-documentation-svg-graphic-implementation) - * [Overview](#overview-32) - * [SVG Graphic Description](#svg-graphic-description) - * [File Information](#file-information) - * [Implementation Guide](#implementation-guide) - * [Conclusion](#conclusion-35) + * [Developer Documentation: SVG Graphic Implementation](#developer-documentation-svg-graphic-implementation) + * [Overview](#overview-32) + * [SVG Graphic Description](#svg-graphic-description) + * [File Information](#file-information) + * [Implementation Guide](#implementation-guide) + * [Conclusion](#conclusion-35) * [resources\shared\_main.scss](#resourcesshared_mainscss) - * [Developer Documentation: SCSS Mixins and Styles](#developer-documentation-scss-mixins-and-styles) - * [Mixins](#mixins) - * [1. `typography`](#1-typography) - * [2. `flex-container`](#2-flex-container) - * [3. `fixed-full`](#3-fixed-full) - * [4. `link-hover-transition`](#4-link-hover-transition) - * [5. `message-style`](#5-message-style) - * [Key Styling Sections](#key-styling-sections) - * [Body](#body) - * [Messages Container](#messages-container) - * [Input Fields](#input-fields) - * [Disconnected Overlay](#disconnected-overlay) - * [Buttons](#buttons-5) - * [Keyframes](#keyframes) + * [Developer Documentation: SCSS Mixins and Styles](#developer-documentation-scss-mixins-and-styles) + * [Mixins](#mixins) + * [1. `typography`](#1-typography) + * [2. `flex-container`](#2-flex-container) + * [3. `fixed-full`](#3-fixed-full) + * [4. `link-hover-transition`](#4-link-hover-transition) + * [5. `message-style`](#5-message-style) + * [Key Styling Sections](#key-styling-sections) + * [Body](#body) + * [Messages Container](#messages-container) + * [Input Fields](#input-fields) + * [Disconnected Overlay](#disconnected-overlay) + * [Buttons](#buttons-5) + * [Keyframes](#keyframes) * [resources\welcome\index.html](#resourceswelcomeindexhtml) - * [Developer Documentation: HTML Page Auto-Redirect](#developer-documentation-html-page-auto-redirect) - * [Overview](#overview-33) - * [Implementation](#implementation-1) - * [HTML Structure](#html-structure-1) - * [Meta Refresh Tag](#meta-refresh-tag) - * [Fallback Link](#fallback-link) - * [Usage](#usage-32) - * [Considerations](#considerations) - * [Conclusion](#conclusion-36) + * [Developer Documentation: HTML Page Auto-Redirect](#developer-documentation-html-page-auto-redirect) + * [Overview](#overview-33) + * [Implementation](#implementation-1) + * [HTML Structure](#html-structure-1) + * [Meta Refresh Tag](#meta-refresh-tag) + * [Fallback Link](#fallback-link) + * [Usage](#usage-32) + * [Considerations](#considerations) + * [Conclusion](#conclusion-36) * [resources\welcome\main.js](#resourceswelcomemainjs) - * [Developer Documentation](#developer-documentation-1) - * [Overview](#overview-34) - * [Functions](#functions-3) - * [showModal(endpoint)](#showmodalendpoint) - * [closeModal()](#closemodal-1) - * [async fetchData(endpoint)](#async-fetchdataendpoint) - * [updateTabs()](#updatetabs-1) - * [Event Listeners Setup](#event-listeners-setup) - * [Usage](#usage-33) - * [Conclusion](#conclusion-37) + * [Developer Documentation](#developer-documentation-1) + * [Overview](#overview-34) + * [Functions](#functions-3) + * [showModal(endpoint)](#showmodalendpoint) + * [closeModal()](#closemodal-1) + * [async fetchData(endpoint)](#async-fetchdataendpoint) + * [updateTabs()](#updatetabs-1) + * [Event Listeners Setup](#event-listeners-setup) + * [Usage](#usage-33) + * [Conclusion](#conclusion-37) * [resources\welcome\main.scss](#resourceswelcomemainscss) * [Developer Documentation: App Type Styles](#developer-documentation-app-type-styles) - * [Import Statements](#import-statements-1) - * [`.app-type` Class Definition](#app-type-class-definition) - * [Usage](#usage-34) - * [Example](#example-12) + * [Import Statements](#import-statements-1) + * [`.app-type` Class Definition](#app-type-class-definition) + * [Usage](#usage-34) + * [Example](#example-12) * [resources\welcome\favicon.svg](#resourceswelcomefaviconsvg) - * [Developer Documentation for SVG Illustration](#developer-documentation-for-svg-illustration) - * [Overview](#overview-35) - * [Styles](#styles) - * [Paths](#paths) - * [Understanding Path Coordinates](#understanding-path-coordinates) - * [Modifying the SVG](#modifying-the-svg) - * [Reusability](#reusability) - * [Conclusion](#conclusion-38) + * [Developer Documentation for SVG Illustration](#developer-documentation-for-svg-illustration) + * [Overview](#overview-35) + * [Styles](#styles) + * [Paths](#paths) + * [Understanding Path Coordinates](#understanding-path-coordinates) + * [Modifying the SVG](#modifying-the-svg) + * [Reusability](#reusability) + * [Conclusion](#conclusion-38) * [resources\welcome\favicon.png](#resourceswelcomefaviconpng) - * [Developer Documentation](#developer-documentation-2) - * [Overview](#overview-36) - * [System Requirements](#system-requirements) - * [Setup Instructions](#setup-instructions) - * [Key Functionalities](#key-functionalities) - * [Contributing](#contributing-1) - * [Support](#support) + * [Developer Documentation](#developer-documentation-2) + * [Overview](#overview-36) + * [System Requirements](#system-requirements) + * [Setup Instructions](#setup-instructions) + * [Key Functionalities](#key-functionalities) + * [Contributing](#contributing-1) + * [Support](#support) + # kotlin\com\simiacryptus\skyenet\apps\coding\ShellToolAgent.kt @@ -2200,7 +2202,7 @@ utilizes the `JsonUtil` class for JSON serialization. the servlet. | Parameter | Type | Description | - |-----------|------|-------------| + |-----------|------|-------------| | info | `T` | The information of type `T` that this servlet will return when handling GET requests. | ### Methods diff --git a/gradle.properties b/gradle.properties index 1b54b4ff..56c9942c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ # Gradle Releases -> https://github.com/gradle/gradle/releases -libraryGroup = com.simiacryptus.skyenet -libraryVersion = 1.2.11 -gradleVersion = 7.6.1 +libraryGroup=com.simiacryptus.skyenet +libraryVersion=1.2.11 +gradleVersion=7.6.1 kotlin.daemon.jvmargs=-Xmx4g diff --git a/kotlin/build.gradle.kts b/kotlin/build.gradle.kts index 916f23aa..f6a54db8 100644 --- a/kotlin/build.gradle.kts +++ b/kotlin/build.gradle.kts @@ -83,7 +83,6 @@ tasks { } - val javadocJar by tasks.registering(Jar::class) { archiveClassifier.set("javadoc") from(tasks.javadoc) diff --git a/kotlin/src/test/resources/logback.xml b/kotlin/src/test/resources/logback.xml index c755da68..f86454fe 100644 --- a/kotlin/src/test/resources/logback.xml +++ b/kotlin/src/test/resources/logback.xml @@ -6,9 +6,9 @@ - + - + \ No newline at end of file diff --git a/skyenet.svg b/skyenet.svg index 52fa3b90..799ca6be 100644 --- a/skyenet.svg +++ b/skyenet.svg @@ -74,11 +74,11 @@ .st64{fill:#0F5916;} .st65{fill:#212E18;} - - + - - - - - - - - - - - - - - - - - + + + - - - - - - - + - - - - - - + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - + - - - - - - + + - - - - - - - - - - - + + + + + + + + + + - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - + + + - - + - - - - + + + - - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + - - - + + - - + - - - - - - - - - - - - + + + + + + + + + + + - - - - - + - - - - - - - - - - - - - - - - - - - + + + + - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - + + + - - - - - - - - - + + - - + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - + - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + - - - - - - - - + + + + + + + - - - - - + + + - - - - - - - - - - - + + + + + + + + + + - - - + + - - - - - - - + + + + + + - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - + + + + + + + + + + + - - - - - + + + + - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + - - - + + - - - - + + - - - - - - - - - - - - + - - - + - - - - - - - - - - + + + + + + + - - - - - - + + + + + - - - - - + + + + - - - - - - + + + + - - - - - - - - - - - - + + + + + - - - - - - - - - - + + + + + + + + + - - - - - - - - + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - + - - - - + + - - - - - - - - - - - - - - - - + + + + - - - - - - - + + - - - - - - - - - - - + + + + + + + + + - - + - - - - - + + + + - - - - - + - - - - - - - + + + + + - - - - + + + - - - - + + - - - - + + + - - - + + - - - - - - - - - - - - - - - - - + - - - - + - - - - - - - + + + - - + - - + - - - + - - - + + - - - - - - + + + + - - + - - - - + + + - - - - - + + + + - - - + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - + + + - - - - - - - - - - - - - - - - - - - + + - - - - - + + + + - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - + + + + - - - - + + + - - - - - + + + + - - - - - - - - - - - - + + + + + + + + + + - - - - - - - + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - + - - - - + + + - - - + + - - - + - - + - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + - - - - - - - - + + + + + + + - - - - - - - - - - + + + + + + + + - - - - - + - - + - - - - - - - - + + - - - - - - + + + + - - - - - - + + + + + - - - - + - - - - - - - + + + + + + - - - - - - + + + - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + - - + - - - - + + + - - - + + - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - + - - - - - - - - - - + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + - - - + + - - - - - - - - - - + + + + + + + + + - - - - - - - - + + + + - - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + - - - - - + + + + - - + - - - - - - - + + + + - - - + - - - - + + - - + - - - - + + - - - - + + + - - - + + - - - - + - - - - - - - - + + + + + + - - - - - - - - + + + + + + + - - - + + diff --git a/webui/build.gradle.kts b/webui/build.gradle.kts index 0d54a113..70e01c6d 100644 --- a/webui/build.gradle.kts +++ b/webui/build.gradle.kts @@ -36,7 +36,7 @@ val jackson_version = "2.17.2" dependencies { - implementation(group = "com.simiacryptus", name = "jo-penai", version = "1.1.9") { + implementation(group = "com.simiacryptus", name = "jo-penai", version = "1.1.10") { exclude(group = "org.slf4j") } diff --git a/webui/src/compiled_documentation.md b/webui/src/compiled_documentation.md index 9168fe6b..98cbfd71 100644 --- a/webui/src/compiled_documentation.md +++ b/webui/src/compiled_documentation.md @@ -1,5 +1,3 @@ - - # main\kotlin\com\simiacryptus\skyenet\apps\coding\CodingApp.kt ## CodingApp Class Documentation diff --git a/webui/src/main/kotlin/com/simiacryptus/diff/AddApplyDiffLinks.kt b/webui/src/main/kotlin/com/simiacryptus/diff/AddApplyDiffLinks.kt index 6899cb05..7123ff9e 100644 --- a/webui/src/main/kotlin/com/simiacryptus/diff/AddApplyDiffLinks.kt +++ b/webui/src/main/kotlin/com/simiacryptus/diff/AddApplyDiffLinks.kt @@ -2,10 +2,10 @@ package com.simiacryptus.diff import com.simiacryptus.skyenet.AgentPatterns.displayMapInTabs import com.simiacryptus.skyenet.set +import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown import com.simiacryptus.skyenet.webui.application.ApplicationInterface import com.simiacryptus.skyenet.webui.session.SessionTask import com.simiacryptus.skyenet.webui.session.SocketManagerBase -import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown fun SocketManagerBase.addApplyDiffLinks( code: () -> String, diff --git a/webui/src/main/kotlin/com/simiacryptus/diff/AddApplyFileDiffLinks.kt b/webui/src/main/kotlin/com/simiacryptus/diff/AddApplyFileDiffLinks.kt index dbd519a0..f0807caa 100644 --- a/webui/src/main/kotlin/com/simiacryptus/diff/AddApplyFileDiffLinks.kt +++ b/webui/src/main/kotlin/com/simiacryptus/diff/AddApplyFileDiffLinks.kt @@ -7,9 +7,9 @@ import com.simiacryptus.jopenai.models.OpenAIModels import com.simiacryptus.skyenet.AgentPatterns.displayMapInTabs import com.simiacryptus.skyenet.core.actors.SimpleActor import com.simiacryptus.skyenet.set +import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown import com.simiacryptus.skyenet.webui.application.ApplicationInterface import com.simiacryptus.skyenet.webui.session.SocketManagerBase -import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown import java.io.File import java.nio.file.Path import kotlin.io.path.readText @@ -468,7 +468,8 @@ ${echoDiff} ``` ${e.stackTraceToString()} ``` -""", ui = ui) +""", ui = ui + ) } newCode2TaskSB?.set( renderMarkdown( diff --git a/webui/src/main/kotlin/com/simiacryptus/diff/AddShellExecutionLinks.kt b/webui/src/main/kotlin/com/simiacryptus/diff/AddShellExecutionLinks.kt index bd532da5..54d1a440 100644 --- a/webui/src/main/kotlin/com/simiacryptus/diff/AddShellExecutionLinks.kt +++ b/webui/src/main/kotlin/com/simiacryptus/diff/AddShellExecutionLinks.kt @@ -1,23 +1,23 @@ package com.simiacryptus.diff - import com.simiacryptus.skyenet.webui.application.ApplicationInterface - import com.simiacryptus.skyenet.webui.session.SocketManagerBase - import com.simiacryptus.skyenet.util.MarkdownUtil - import java.util.* +import com.simiacryptus.skyenet.util.MarkdownUtil +import com.simiacryptus.skyenet.webui.application.ApplicationInterface +import com.simiacryptus.skyenet.webui.session.SocketManagerBase import java.io.BufferedReader import java.io.InputStreamReader +import java.util.* - fun SocketManagerBase.addShellExecutionLinks( - response: String, +fun SocketManagerBase.addShellExecutionLinks( + response: String, ui: ApplicationInterface ): String { val shellCodePattern = """(?s)(? val shellCode = matchResult.groupValues[1] val executionId = UUID.randomUUID().toString() - val executionTask = ui.newTask(false) - val executeButton = hrefLink("Execute", classname = "href-link cmd-button") { - try { + val executionTask = ui.newTask(false) + val executeButton = hrefLink("Execute", classname = "href-link cmd-button") { + try { val process = Runtime.getRuntime().exec(arrayOf("sh", "-c", shellCode)) val reader = BufferedReader(InputStreamReader(process.inputStream)) val errorReader = BufferedReader(InputStreamReader(process.errorStream)) @@ -32,9 +32,9 @@ import java.io.InputStreamReader val exitCode = process.waitFor() output.append("Exit code: $exitCode") executionTask.complete(MarkdownUtil.renderMarkdown("```\n$output\n```", ui = ui)) - } catch (e: Throwable) { - executionTask.error(null, e) - } + } catch (e: Throwable) { + executionTask.error(null, e) + } } """ ```shell diff --git a/webui/src/main/kotlin/com/simiacryptus/diff/DiffUtil.kt b/webui/src/main/kotlin/com/simiacryptus/diff/DiffUtil.kt index 91668832..bcd86141 100644 --- a/webui/src/main/kotlin/com/simiacryptus/diff/DiffUtil.kt +++ b/webui/src/main/kotlin/com/simiacryptus/diff/DiffUtil.kt @@ -28,8 +28,8 @@ data class PatchLine( } object DiffUtil { - // ... (previous code remains unchanged) - + // ... (previous code remains unchanged) + private val log = LoggerFactory.getLogger(DiffUtil::class.java) /** @@ -65,7 +65,7 @@ object DiffUtil { if (originalIndex != null && modifiedIndex != null) { log.debug("Both indices found. Choosing shorter path.") - if (originalIndex - i < modifiedIndex - j) { + if (originalIndex - i < modifiedIndex - j) { while (i < originalIndex) { patchLines.add(PatchLine(Deleted, originalLines[i].lineNumber, original[i])) i++ @@ -129,9 +129,10 @@ object DiffUtil { log.debug("Starting diff formatting. Total lines: ${patchLines.size}, Context lines: $contextLines") patchLines.forEachIndexed { index, lineDiff -> - if (lineDiff.type != Unchanged || + if (lineDiff.type != Unchanged || (index > 0 && patchLines[index - 1].type != Unchanged) || - (index < patchLines.size - 1 && patchLines[index + 1].type != Unchanged)) { + (index < patchLines.size - 1 && patchLines[index + 1].type != Unchanged) + ) { // Print context lines before the change val contextStart = maxOf(lastPrintedLine + 1, index - contextLines) diff --git a/webui/src/main/kotlin/com/simiacryptus/diff/FileValidationUtils.kt b/webui/src/main/kotlin/com/simiacryptus/diff/FileValidationUtils.kt index e1adcdc2..cbdd8a6d 100644 --- a/webui/src/main/kotlin/com/simiacryptus/diff/FileValidationUtils.kt +++ b/webui/src/main/kotlin/com/simiacryptus/diff/FileValidationUtils.kt @@ -69,7 +69,7 @@ class FileValidationUtils { return count % 2 == 0 } - fun filteredWalk(file: File, fn: (File) -> Boolean) : List { + fun filteredWalk(file: File, fn: (File) -> Boolean): List { val result = mutableListOf() if (fn(file)) { if (file.isDirectory) { @@ -83,7 +83,7 @@ class FileValidationUtils { return result } - fun isLLMIncludable(file: File) : Boolean { + fun isLLMIncludable(file: File): Boolean { return when { !file.exists() -> false file.isDirectory -> false @@ -101,6 +101,7 @@ class FileValidationUtils { "ico", "stl" ) -> false + else -> true } } @@ -113,6 +114,7 @@ class FileValidationUtils { it.length() > 1e6 -> arrayOf() it.extension.lowercase(Locale.getDefault()) in setOf("jar", "zip", "class", "png", "jpg", "jpeg", "gif", "ico") -> arrayOf() + it.isDirectory -> expandFileList(*it.listFiles() ?: arrayOf()) else -> arrayOf(it) }).toList() diff --git a/webui/src/main/kotlin/com/simiacryptus/diff/IterativePatchUtil.kt b/webui/src/main/kotlin/com/simiacryptus/diff/IterativePatchUtil.kt index 84f3d8b7..2cdcb4d2 100644 --- a/webui/src/main/kotlin/com/simiacryptus/diff/IterativePatchUtil.kt +++ b/webui/src/main/kotlin/com/simiacryptus/diff/IterativePatchUtil.kt @@ -156,7 +156,7 @@ object IterativePatchUtil { while (nextNewLine.matchingLine == null || nextNewLine.type == ADD) { nextNewLine = nextNewLine.nextLine ?: break } - if(nextNewLine.matchingLine == null || nextNewLine.type == ADD) break + if (nextNewLine.matchingLine == null || nextNewLine.type == ADD) break // Get the corresponding line in the source code val sourceLine = newLine.matchingLine!! log.debug("Processing patch line ${newLine.index} with matching source line ${sourceLine.index}") @@ -172,7 +172,7 @@ object IterativePatchUtil { } nextSourceLine = nextSourceLine.nextLine ?: break } - if(nextSourceLine.matchingLine == null || nextSourceLine.type == DELETE) break + if (nextSourceLine.matchingLine == null || nextSourceLine.type == DELETE) break // If the next matching lines in source and new don't correspond, // it means there's a moved block of code while (nextNewLine.matchingLine != nextSourceLine) { @@ -194,9 +194,9 @@ object IterativePatchUtil { // Safeguard to prevent infinite loop if (++iterationCount > maxIterations) { log.error("Exceeded maximum iterations in markMovedLines") - newLine = nextNewLine + newLine = nextNewLine // Move to the next line to process in the outer loop - // newLine = nextNewLine + // newLine = nextNewLine } } } else { @@ -256,8 +256,8 @@ object IterativePatchUtil { when { line.type != CONTEXT -> { // Start of a change, add buffered context - if(contextSize*2 < contextBuffer.size) { - if(truncatedDiff.isNotEmpty()) { + if (contextSize * 2 < contextBuffer.size) { + if (truncatedDiff.isNotEmpty()) { truncatedDiff.addAll(contextBuffer.take(contextSize)) truncatedDiff.add(LineRecord(-1, "...", type = CONTEXT)) } @@ -274,10 +274,10 @@ object IterativePatchUtil { } } } - if(truncatedDiff.isEmpty()) { + if (truncatedDiff.isEmpty()) { return truncatedDiff } - if(contextSize < contextBuffer.size) { + if (contextSize < contextBuffer.size) { truncatedDiff.addAll(contextBuffer.take(contextSize)) } else { truncatedDiff.addAll(contextBuffer) @@ -295,6 +295,7 @@ object IterativePatchUtil { private fun normalizeLine(line: String): String { return line.replace(whitespaceRegex, "") } + private val whitespaceRegex = "\\s".toRegex() private fun link( @@ -339,57 +340,57 @@ object IterativePatchUtil { } } -private fun generatePatchedText( - sourceLines: List, - patchLines: List, - ): List { - log.debug("Starting to generate patched text") - val patchedText: MutableList = mutableListOf() - val usedPatchLines = mutableSetOf() - var sourceIndex = -1 - var lastMatchedPatchIndex = -1 - while (sourceIndex < sourceLines.size - 1) { - val codeLine = sourceLines[++sourceIndex] - when { - codeLine.matchingLine?.type == DELETE -> { - val patchLine = codeLine.matchingLine!! - log.debug("Deleting line: {}", codeLine) - // Delete the line -- do not add to patched text - usedPatchLines.add(patchLine) - checkAfterForInserts(patchLine, usedPatchLines, patchedText) - lastMatchedPatchIndex = patchLine.index - } - - codeLine.matchingLine != null -> { - val patchLine: LineRecord = codeLine.matchingLine!! - log.debug("Patching line: {} <-> {}", codeLine, patchLine) - checkBeforeForInserts(patchLine, usedPatchLines, patchedText) - usedPatchLines.add(patchLine) + private fun generatePatchedText( + sourceLines: List, + patchLines: List, + ): List { + log.debug("Starting to generate patched text") + val patchedText: MutableList = mutableListOf() + val usedPatchLines = mutableSetOf() + var sourceIndex = -1 + var lastMatchedPatchIndex = -1 + while (sourceIndex < sourceLines.size - 1) { + val codeLine = sourceLines[++sourceIndex] + when { + codeLine.matchingLine?.type == DELETE -> { + val patchLine = codeLine.matchingLine!! + log.debug("Deleting line: {}", codeLine) + // Delete the line -- do not add to patched text + usedPatchLines.add(patchLine) + checkAfterForInserts(patchLine, usedPatchLines, patchedText) + lastMatchedPatchIndex = patchLine.index + } + + codeLine.matchingLine != null -> { + val patchLine: LineRecord = codeLine.matchingLine!! + log.debug("Patching line: {} <-> {}", codeLine, patchLine) + checkBeforeForInserts(patchLine, usedPatchLines, patchedText) + usedPatchLines.add(patchLine) // Use the source line if it matches the patch line (ignoring whitespace) if (normalizeLine(codeLine.line ?: "") == normalizeLine(patchLine.line ?: "")) { patchedText.add(codeLine.line ?: "") } else { patchedText.add(patchLine.line ?: "") } - checkAfterForInserts(patchLine, usedPatchLines, patchedText) - lastMatchedPatchIndex = patchLine.index - } - - else -> { - log.debug("Added unmatched source line: {}", codeLine) - patchedText.add(codeLine.line ?: "") - } - - } - } - if (lastMatchedPatchIndex == -1) patchLines.filter { it.type == ADD && !usedPatchLines.contains(it) } - .forEach { line -> - log.debug("Added patch line: {}", line) - patchedText.add(line.line ?: "") - } - log.debug("Generated patched text with ${patchedText.size} lines") - return patchedText - } + checkAfterForInserts(patchLine, usedPatchLines, patchedText) + lastMatchedPatchIndex = patchLine.index + } + + else -> { + log.debug("Added unmatched source line: {}", codeLine) + patchedText.add(codeLine.line ?: "") + } + + } + } + if (lastMatchedPatchIndex == -1) patchLines.filter { it.type == ADD && !usedPatchLines.contains(it) } + .forEach { line -> + log.debug("Added patch line: {}", line) + patchedText.add(line.line ?: "") + } + log.debug("Generated patched text with ${patchedText.size} lines") + return patchedText + } private fun checkBeforeForInserts( patchLine: LineRecord, @@ -421,8 +422,9 @@ private fun generatePatchedText( while (null != nextPatchLine) { while (nextPatchLine != null && ( normalizeLine(nextPatchLine.line ?: "").isEmpty() || - (nextPatchLine.matchingLine == null && nextPatchLine.type == CONTEXT) - )) { + (nextPatchLine.matchingLine == null && nextPatchLine.type == CONTEXT) + ) + ) { nextPatchLine = nextPatchLine.nextLine } if (nextPatchLine == null) break diff --git a/webui/src/main/kotlin/com/simiacryptus/diff/IterativePatchUtil.md b/webui/src/main/kotlin/com/simiacryptus/diff/IterativePatchUtil.md index 2c8c8739..8d3cf111 100644 --- a/webui/src/main/kotlin/com/simiacryptus/diff/IterativePatchUtil.md +++ b/webui/src/main/kotlin/com/simiacryptus/diff/IterativePatchUtil.md @@ -1,4 +1,6 @@ -The `IterativePatchUtil` Kotlin object implements a sophisticated algorithm for generating and applying patches between two versions of textual content, such as source code files. This algorithm is designed to identify differences, categorize them, and efficiently apply those differences to produce the updated text. Below is a comprehensive breakdown of how this patching algorithm operates, including its key components and step-by-step processes. +The `IterativePatchUtil` Kotlin object implements a sophisticated algorithm for generating and applying patches between two versions of textual content, such as source code files. +This algorithm is designed to identify differences, categorize them, and efficiently apply those differences to produce the updated text. Below is a comprehensive breakdown of how +this patching algorithm operates, including its key components and step-by-step processes. ## **1. Overview** @@ -7,29 +9,30 @@ The `IterativePatchUtil` serves two primary functions: 1. **Generating a Patch**: Comparing an original ("old") version of text with a modified ("new") version to produce a patch that encapsulates the differences. 2. **Applying a Patch**: Taking an original text and a patch to produce the updated text by applying the changes encapsulated in the patch. -The algorithm emphasizes maintaining the structural integrity of the text, especially regarding bracket nesting (parentheses, square brackets, curly braces), and optimizes the patch by minimizing unnecessary changes. +The algorithm emphasizes maintaining the structural integrity of the text, especially regarding bracket nesting (parentheses, square brackets, curly braces), and optimizes the +patch by minimizing unnecessary changes. ## **2. Core Components** ### **a. Data Structures** - **`LineType` Enum**: Categorizes each line as one of three types: - - `CONTEXT`: Lines that are unchanged between versions. - - `ADD`: Lines that have been added in the new version. - - `DELETE`: Lines that have been removed from the old version. + - `CONTEXT`: Lines that are unchanged between versions. + - `ADD`: Lines that have been added in the new version. + - `DELETE`: Lines that have been removed from the old version. - **`LineMetrics` Data Class**: Tracks the nesting depth of different types of brackets within a line: - - `parenthesesDepth`: Depth of `()` brackets. - - `squareBracketsDepth`: Depth of `[]` brackets. - - `curlyBracesDepth`: Depth of `{}` brackets. + - `parenthesesDepth`: Depth of `()` brackets. + - `squareBracketsDepth`: Depth of `[]` brackets. + - `curlyBracesDepth`: Depth of `{}` brackets. - **`LineRecord` Data Class**: Represents a single line in either the source or patch text, containing: - - `index`: Line number. - - `line`: The actual text of the line. - - `previousLine` & `nextLine`: Pointers to adjacent lines. - - `matchingLine`: Links to the corresponding `LineRecord` in the other version. - - `type`: Categorization (`CONTEXT`, `ADD`, `DELETE`). - - `metrics`: Bracket nesting metrics for the line. + - `index`: Line number. + - `line`: The actual text of the line. + - `previousLine` & `nextLine`: Pointers to adjacent lines. + - `matchingLine`: Links to the corresponding `LineRecord` in the other version. + - `type`: Categorization (`CONTEXT`, `ADD`, `DELETE`). + - `metrics`: Bracket nesting metrics for the line. ### **b. Logging** @@ -42,67 +45,67 @@ The `generatePatch` function orchestrates the creation of a patch by comparing t ### **Step 1: Parsing the Texts** - **`parseLines` Function**: - - Splits the input text into individual lines. - - Creates `LineRecord` instances for each line. - - Establishes `previousLine` and `nextLine` links between consecutive lines. - - Calculates bracket metrics (`parenthesesDepth`, `squareBracketsDepth`, `curlyBracesDepth`) for each line using the `calculateLineMetrics` function. + - Splits the input text into individual lines. + - Creates `LineRecord` instances for each line. + - Establishes `previousLine` and `nextLine` links between consecutive lines. + - Calculates bracket metrics (`parenthesesDepth`, `squareBracketsDepth`, `curlyBracesDepth`) for each line using the `calculateLineMetrics` function. ### **Step 2: Linking Lines Between Source and New Texts** - **`link` Function**: - - **Step 1: Linking Unique Exact Matches** (`linkUniqueMatchingLines`): - - Groups lines from both source and new texts based on their normalized content (whitespace removed). - - Identifies lines that appear uniquely and match exactly between both versions. - - Links such lines by setting their `matchingLine` references. + - **Step 1: Linking Unique Exact Matches** (`linkUniqueMatchingLines`): + - Groups lines from both source and new texts based on their normalized content (whitespace removed). + - Identifies lines that appear uniquely and match exactly between both versions. + - Links such lines by setting their `matchingLine` references. - - **Step 2: Linking Adjacent Exact Matches** (`linkAdjacentMatchingLines`): - - Iteratively scans for lines adjacent to already linked lines that match exactly. - - Links these adjacent lines to extend the set of matching lines. + - **Step 2: Linking Adjacent Exact Matches** (`linkAdjacentMatchingLines`): + - Iteratively scans for lines adjacent to already linked lines that match exactly. + - Links these adjacent lines to extend the set of matching lines. - - **Step 3: Subsequence Linking** (`subsequenceLinking`): - - Recursively attempts to link remaining unmatched lines, potentially using Levenshtein distance for lines that are similar but not identical. - - This step ensures that even moved blocks or slightly altered lines are recognized and correctly linked. + - **Step 3: Subsequence Linking** (`subsequenceLinking`): + - Recursively attempts to link remaining unmatched lines, potentially using Levenshtein distance for lines that are similar but not identical. + - This step ensures that even moved blocks or slightly altered lines are recognized and correctly linked. ### **Step 3: Marking Moved Lines** - **`markMovedLines` Function**: - - Iterates through the new lines to identify lines that have been moved rather than added or deleted. - - Detects discrepancies in the order of linked lines between source and new texts. - - Marks such lines appropriately by changing their `LineType` to `ADD` or `DELETE` to reflect the movement. + - Iterates through the new lines to identify lines that have been moved rather than added or deleted. + - Detects discrepancies in the order of linked lines between source and new texts. + - Marks such lines appropriately by changing their `LineType` to `ADD` or `DELETE` to reflect the movement. ### **Step 4: Generating the Diff** - **`newToPatch` Function**: - - Traverses through the new lines to construct a preliminary list of differences (`diff`), categorizing each as `ADD`, `DELETE`, or `CONTEXT`. - - For lines with no matching counterpart in the source, marks them as `ADD`. - - For matched lines, checks surrounding lines to identify any `DELETE` operations required. + - Traverses through the new lines to construct a preliminary list of differences (`diff`), categorizing each as `ADD`, `DELETE`, or `CONTEXT`. + - For lines with no matching counterpart in the source, marks them as `ADD`. + - For matched lines, checks surrounding lines to identify any `DELETE` operations required. ### **Step 5: Truncating Context** - **`truncateContext` Function**: - - Limits the number of unchanged (`CONTEXT`) lines around changes to reduce patch size and improve readability. - - Uses a `contextSize` parameter (set to 3) to determine how many context lines to retain before and after changes. - - If there are more context lines than the specified `contextSize`, replaces the excess with an ellipsis (`...`). + - Limits the number of unchanged (`CONTEXT`) lines around changes to reduce patch size and improve readability. + - Uses a `contextSize` parameter (set to 3) to determine how many context lines to retain before and after changes. + - If there are more context lines than the specified `contextSize`, replaces the excess with an ellipsis (`...`). ### **Step 6: Fixing Patch Line Order** - **`fixPatchLineOrder` Function**: - - Ensures that `DELETE` lines precede `ADD` lines when they are adjacent in the diff. - - Iteratively swaps lines in the diff to maintain this order, which is essential for properly applying the patch. + - Ensures that `DELETE` lines precede `ADD` lines when they are adjacent in the diff. + - Iteratively swaps lines in the diff to maintain this order, which is essential for properly applying the patch. ### **Step 7: Annihilating No-Op Line Pairs** - **`annihilateNoopLinePairs` Function**: - - Removes pairs of lines where a line is deleted and then immediately added without any actual change in content. - - Helps in cleaning up the diff by eliminating unnecessary operations that cancel each other out. + - Removes pairs of lines where a line is deleted and then immediately added without any actual change in content. + - Helps in cleaning up the diff by eliminating unnecessary operations that cancel each other out. ### **Step 8: Generating the Final Patch Text** - Iterates through the processed `shortDiff` list to build the final patch string. - Formats each line based on its `LineType`: - - `CONTEXT`: Prefixes the line with two spaces (` `). - - `ADD`: Prefixes the line with a plus sign (`+`). - - `DELETE`: Prefixes the line with a minus sign (`-`). + - `CONTEXT`: Prefixes the line with two spaces (` `). + - `ADD`: Prefixes the line with a plus sign (`+`). + - `DELETE`: Prefixes the line with a minus sign (`-`). - Joins all lines into a single string, trimming any trailing whitespace. ## **4. Patch Application Process (`applyPatch`)** @@ -112,22 +115,22 @@ The `applyPatch` function applies a previously generated patch to an original te ### **Step 1: Parsing the Source and Patch Texts** - **Parsing Source Text**: - - Uses `parseLines` to parse the original text into `LineRecord` instances, similar to the patch generation process. + - Uses `parseLines` to parse the original text into `LineRecord` instances, similar to the patch generation process. - **Parsing Patch Text**: - - Uses `parsePatchLines` to parse the patch. - - **`parsePatchLines` Function**: - - Splits the patch into lines. - - Identifies the type of each line (`ADD`, `DELETE`, `CONTEXT`) based on prefixes (`+`, `-`, or none). - - Filters out metadata lines (e.g., lines starting with `+++`, `---`, `@@`). - - Establishes `previousLine` and `nextLine` links. - - Calculates bracket metrics. + - Uses `parsePatchLines` to parse the patch. + - **`parsePatchLines` Function**: + - Splits the patch into lines. + - Identifies the type of each line (`ADD`, `DELETE`, `CONTEXT`) based on prefixes (`+`, `-`, or none). + - Filters out metadata lines (e.g., lines starting with `+++`, `---`, `@@`). + - Establishes `previousLine` and `nextLine` links. + - Calculates bracket metrics. ### **Step 2: Linking Source and Patch Lines** - **`link` Function**: - - Links lines from the source and patch texts using the same linking steps as in the patch generation process. - - In this context, it uses the `LevenshteinDistance` algorithm to accommodate minor differences between lines, aiding in more accurate linking. + - Links lines from the source and patch texts using the same linking steps as in the patch generation process. + - In this context, it uses the `LevenshteinDistance` algorithm to accommodate minor differences between lines, aiding in more accurate linking. ### **Step 3: Filtering Patch Lines** @@ -136,57 +139,57 @@ The `applyPatch` function applies a previously generated patch to an original te ### **Step 4: Generating the Patched Text** - **`generatePatchedText` Function**: - - Iterates through the source lines and applies changes based on the linked patch lines. - - Handles different scenarios: - - **Deletion**: Skips lines marked as `DELETE`. - - **Addition**: Inserts lines marked as `ADD`. - - **Context**: Retains lines that haven't changed. - - Ensures that inserted lines are placed correctly by checking for inserts before and after matched lines. - - Reconstructs the updated text by compiling the processed lines into a final string. + - Iterates through the source lines and applies changes based on the linked patch lines. + - Handles different scenarios: + - **Deletion**: Skips lines marked as `DELETE`. + - **Addition**: Inserts lines marked as `ADD`. + - **Context**: Retains lines that haven't changed. + - Ensures that inserted lines are placed correctly by checking for inserts before and after matched lines. + - Reconstructs the updated text by compiling the processed lines into a final string. ## **5. Supporting Functions and Utilities** ### **a. Normalization** - **`normalizeLine` Function**: - - Removes all whitespace characters from a line to facilitate accurate comparison between lines. - - Helps in identifying lines that are functionally the same but may differ in formatting. + - Removes all whitespace characters from a line to facilitate accurate comparison between lines. + - Helps in identifying lines that are functionally the same but may differ in formatting. ### **b. Line Linking and Matching** - **`linkUniqueMatchingLines` Function**: - - Links lines that are uniquely identical between source and patch texts. - - Prevents multiple matches by ensuring that only lines with the same count in both texts are linked. + - Links lines that are uniquely identical between source and patch texts. + - Prevents multiple matches by ensuring that only lines with the same count in both texts are linked. - **`linkAdjacentMatchingLines` Function**: - - Extends existing links by connecting adjacent lines that match, enhancing the continuity of matched blocks. + - Extends existing links by connecting adjacent lines that match, enhancing the continuity of matched blocks. - **`isMatch` Function**: - - Determines if two lines match exactly or are similar based on the Levenshtein distance. - - Allows for minor discrepancies, improving the algorithm's robustness. + - Determines if two lines match exactly or are similar based on the Levenshtein distance. + - Allows for minor discrepancies, improving the algorithm's robustness. ### **c. Bracket Metrics Calculation** - **`calculateLineMetrics` Function**: - - Analyzes each line to determine the nesting depth of different brackets. - - Useful for understanding the structural context of code or text, aiding in more intelligent patching decisions. + - Analyzes each line to determine the nesting depth of different brackets. + - Useful for understanding the structural context of code or text, aiding in more intelligent patching decisions. - **`lineMetrics` Extension Function**: - - Provides a convenient way to calculate bracket metrics for individual strings. + - Provides a convenient way to calculate bracket metrics for individual strings. ## **6. Handling Edge Cases and Optimizations** - **Recursion Depth Control**: - - The `subsequenceLinking` function limits recursion depth to prevent excessive processing (`depth > 10`), ensuring the algorithm remains efficient. + - The `subsequenceLinking` function limits recursion depth to prevent excessive processing (`depth > 10`), ensuring the algorithm remains efficient. - **Preventing Infinite Loops**: - - Utilizes `require` statements to ensure that lines are not inadvertently linked to themselves, safeguarding against potential infinite loops during linking. + - Utilizes `require` statements to ensure that lines are not inadvertently linked to themselves, safeguarding against potential infinite loops during linking. - **Context Truncation**: - - By limiting the number of context lines, the algorithm reduces patch size and focuses on relevant changes, enhancing readability and manageability. + - By limiting the number of context lines, the algorithm reduces patch size and focuses on relevant changes, enhancing readability and manageability. - **No-Op Pair Removal**: - - Eliminates redundant add-delete pairs, streamlining the patch and avoiding unnecessary modifications. + - Eliminates redundant add-delete pairs, streamlining the patch and avoiding unnecessary modifications. ## **7. Logging and Debugging** @@ -194,14 +197,16 @@ Throughout the algorithm, extensive logging is implemented to track the progress - **Informational Logs** (`log.info`): Indicate the commencement and completion of major processes like patch generation and application. -- **Debug Logs** (`log.debug`): Provide detailed insights into intermediate steps, such as the number of lines parsed, linked, matched, and any modifications made during processing. +- **Debug Logs** (`log.debug`): Provide detailed insights into intermediate steps, such as the number of lines parsed, linked, matched, and any modifications made during + processing. - **Error Logs** (`log.error`): Capture and report any exceptions or critical issues encountered during execution, aiding in troubleshooting. ## **8. Summary of Workflow** 1. **Parsing**: Both the original and new texts are parsed into line-by-line `LineRecord` objects with bracket metrics calculated. -2. **Linking**: The algorithm attempts to link corresponding lines between the original and new texts using exact matches, adjacency, and subsequence strategies, incorporating Levenshtein distance for similar lines. +2. **Linking**: The algorithm attempts to link corresponding lines between the original and new texts using exact matches, adjacency, and subsequence strategies, incorporating + Levenshtein distance for similar lines. 3. **Marking Movements**: Detects and marks lines that have been moved rather than added or deleted. 4. **Generating Diff**: Creates a preliminary diff list categorizing each line as `ADD`, `DELETE`, or `CONTEXT`. 5. **Optimizing Patch**: Truncates excess context, fixes the order of add/delete operations, and removes no-op pairs to refine the patch. @@ -222,7 +227,6 @@ fun add(a: Int, b: Int): Int {
- ### **Modified (`newCode`)** ```kotlin @@ -238,13 +242,15 @@ fun addNumbers(a: Int, b: Int): Int { **Patch Generation (`generatePatch`)** would perform the following: 1. **Identify Changes**: - - Function name changed from `add` to `addNumbers` (`CONTEXT` vs. `ADD`). - - Added a new line declaring `val sum`. - - Modified the return statement to `return sum` (`DELETE` and `ADD`). + +- Function name changed from `add` to `addNumbers` (`CONTEXT` vs. `ADD`). +- Added a new line declaring `val sum`. +- Modified the return statement to `return sum` (`DELETE` and `ADD`). 2. **Generate Diff**: - - Categorize each line accordingly. - - Truncate any excessive unchanged lines for brevity. + +- Categorize each line accordingly. +- Truncate any excessive unchanged lines for brevity. 3. **Produce Patch**: ```diff @@ -271,9 +277,13 @@ fun addNumbers(a: Int, b: Int): Int { ### **Considerations**: - **Complexity**: The algorithm's multiple steps and recursive linking can introduce complexity, making it essential to thoroughly test and debug. -- **Performance**: For very large files, the recursive `subsequenceLinking` and extensive logging might impact performance. Optimizations or limitations on recursion depth help mitigate this. +- **Performance**: For very large files, the recursive `subsequenceLinking` and extensive logging might impact performance. Optimizations or limitations on recursion depth help + mitigate this. - **Whitespace Sensitivity**: Normalizing lines by removing all whitespace may lead to unintended matches if significant changes are solely based on formatting. ## **Conclusion** -The `IterativePatchUtil` implements a comprehensive and intelligent patching algorithm that meticulously compares and applies changes between two versions of text. Its multi-faceted approach, incorporating exact matches, adjacency analysis, subsequence linking, bracket metrics, and Levenshtein distance, ensures high accuracy and efficiency in generating and applying patches. While its complexity necessitates careful management and testing, the algorithm offers robust capabilities for handling nuanced changes in textual content, making it highly suitable for applications like version control systems, code editors, and collaborative document editing tools. \ No newline at end of file +The `IterativePatchUtil` implements a comprehensive and intelligent patching algorithm that meticulously compares and applies changes between two versions of text. Its +multi-faceted approach, incorporating exact matches, adjacency analysis, subsequence linking, bracket metrics, and Levenshtein distance, ensures high accuracy and efficiency in +generating and applying patches. While its complexity necessitates careful management and testing, the algorithm offers robust capabilities for handling nuanced changes in textual +content, making it highly suitable for applications like version control systems, code editors, and collaborative document editing tools. \ No newline at end of file diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/Discussable.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/Discussable.kt index fa8fbdb4..d935531a 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/Discussable.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/Discussable.kt @@ -214,10 +214,12 @@ ${textInput(design, tabContent, history, task, feedbackSB, feedbackTask = this)} log.info("Returning result from Discussable") return atomicRef.get() } catch (e: Exception) { - log.warn(""" + log.warn( + """ Error in Discussable ${e.message} -""", e) +""", e + ) task.error(ui, e) return null as T } diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/TabbedDisplay.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/TabbedDisplay.kt index c27c7221..036ecbac 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/TabbedDisplay.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/TabbedDisplay.kt @@ -14,7 +14,7 @@ open class TabbedDisplay( } val size: Int get() = tabs.size - open fun render() = if(tabs.isEmpty()) "" else """ + open fun render() = if (tabs.isEmpty()) "" else """
${renderTabButtons()} ${ @@ -24,10 +24,10 @@ ${
""" - val container: StringBuilder by lazy { + val container: StringBuilder by lazy { log.debug("Initializing container with rendered content") - task.add(render())!! - } + task.add(render())!! + } open fun renderTabButtons() = """
${ diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/coding/CodingAgent.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/coding/CodingAgent.kt index 0b5f6cd2..565922b4 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/coding/CodingAgent.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/coding/CodingAgent.kt @@ -3,21 +3,21 @@ package com.simiacryptus.skyenet.apps.coding import com.simiacryptus.jopenai.API import com.simiacryptus.jopenai.ChatClient import com.simiacryptus.jopenai.models.ApiModel -import com.simiacryptus.jopenai.models.OpenAITextModel +import com.simiacryptus.jopenai.models.TextModel import com.simiacryptus.jopenai.proxy.ValidatedObject import com.simiacryptus.skyenet.Retryable import com.simiacryptus.skyenet.core.actors.ActorSystem import com.simiacryptus.skyenet.core.actors.CodingActor import com.simiacryptus.skyenet.core.actors.CodingActor.CodeResult import com.simiacryptus.skyenet.core.platform.ApplicationServices -import com.simiacryptus.skyenet.core.platform.AuthorizationInterface.OperationType import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.StorageInterface -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.AuthorizationInterface.OperationType +import com.simiacryptus.skyenet.core.platform.model.StorageInterface +import com.simiacryptus.skyenet.core.platform.model.User import com.simiacryptus.skyenet.interpreter.Interpreter +import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown import com.simiacryptus.skyenet.webui.application.ApplicationInterface import com.simiacryptus.skyenet.webui.session.SessionTask -import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown import org.slf4j.LoggerFactory import java.util.* import java.util.concurrent.TimeUnit @@ -34,7 +34,7 @@ open class CodingAgent( val symbols: Map, temperature: Double = 0.1, val details: String? = null, - val model: OpenAITextModel, + val model: TextModel, private val mainTask: SessionTask, val actorMap: Map = mapOf( ActorTypes.CodingActor to CodingActor( diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/coding/ShellToolAgent.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/coding/ShellToolAgent.kt index 63cc314e..d6b52aa3 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/coding/ShellToolAgent.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/coding/ShellToolAgent.kt @@ -1,26 +1,27 @@ package com.simiacryptus.skyenet.apps.coding import com.simiacryptus.jopenai.API -import com.simiacryptus.jopenai.models.ApiModel import com.simiacryptus.jopenai.ChatClient -import com.simiacryptus.jopenai.OpenAIClient import com.simiacryptus.jopenai.describe.AbbrevWhitelistYamlDescriber import com.simiacryptus.jopenai.describe.TypeDescriber -import com.simiacryptus.jopenai.models.ChatModels -import com.simiacryptus.util.JsonUtil +import com.simiacryptus.jopenai.models.ApiModel +import com.simiacryptus.jopenai.models.ChatModel import com.simiacryptus.skyenet.core.actors.CodingActor import com.simiacryptus.skyenet.core.actors.CodingActor.CodeResult -import com.simiacryptus.skyenet.core.actors.CodingActor.Companion.indent import com.simiacryptus.skyenet.core.actors.CodingActor.Companion.sortCode import com.simiacryptus.skyenet.core.actors.ParsedActor import com.simiacryptus.skyenet.core.actors.SimpleActor import com.simiacryptus.skyenet.core.platform.* +import com.simiacryptus.skyenet.core.platform.model.AuthorizationInterface +import com.simiacryptus.skyenet.core.platform.model.StorageInterface +import com.simiacryptus.skyenet.core.platform.model.User import com.simiacryptus.skyenet.interpreter.Interpreter import com.simiacryptus.skyenet.kotlin.KotlinInterpreter -import com.simiacryptus.skyenet.webui.application.ApplicationInterface -import com.simiacryptus.skyenet.webui.session.SessionTask import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown import com.simiacryptus.skyenet.util.OpenAPI +import com.simiacryptus.skyenet.webui.application.ApplicationInterface +import com.simiacryptus.skyenet.webui.session.SessionTask +import com.simiacryptus.util.JsonUtil import jakarta.servlet.http.HttpServlet import jakarta.servlet.http.HttpServletRequest import jakarta.servlet.http.HttpServletResponse @@ -50,7 +51,7 @@ abstract class ShellToolAgent( symbols: Map, temperature: Double = 0.1, details: String? = null, - model: ChatModels, + model: ChatModel, actorMap: Map = mapOf( ActorTypes.CodingActor to CodingActor( interpreter, @@ -235,16 +236,16 @@ abstract class ShellToolAgent( AuthorizationInterface.OperationType.Admin ) ) { -/* - ToolServlet.addTool( - ToolServlet.Tool( - path = openAPI.paths?.entries?.first()?.key?.removePrefix(toolsPrefix) ?: "unknown", - openApiDescription = openAPI, - interpreterString = getInterpreterString(), - servletCode = servletImpl - ) - ) -*/ + /* + ToolServlet.addTool( + ToolServlet.Tool( + path = openAPI.paths?.entries?.first()?.key?.removePrefix(toolsPrefix) ?: "unknown", + openApiDescription = openAPI, + interpreterString = getInterpreterString(), + servletCode = servletImpl + ) + ) + */ } buildTestPage(openAPI, servletImpl, task) } diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/CmdPatchApp.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/CmdPatchApp.kt index bd392cc2..a172a431 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/CmdPatchApp.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/CmdPatchApp.kt @@ -3,7 +3,7 @@ package com.simiacryptus.skyenet.apps.general import com.simiacryptus.diff.FileValidationUtils import com.simiacryptus.jopenai.ChatClient -import com.simiacryptus.jopenai.models.OpenAITextModel +import com.simiacryptus.jopenai.models.TextModel import com.simiacryptus.skyenet.core.platform.Session import com.simiacryptus.skyenet.set import com.simiacryptus.skyenet.webui.session.SessionTask @@ -18,7 +18,7 @@ class CmdPatchApp( settings: Settings, api: ChatClient, val files: Array?, - model: OpenAITextModel + model: TextModel ) : PatchApp(root.toFile(), session, settings, api, model) { companion object { private val log = LoggerFactory.getLogger(CmdPatchApp::class.java) diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/CommandPatchApp.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/CommandPatchApp.kt index 85485c20..3b265d38 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/CommandPatchApp.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/CommandPatchApp.kt @@ -2,7 +2,7 @@ package com.simiacryptus.skyenet.apps.general import com.simiacryptus.diff.FileValidationUtils import com.simiacryptus.jopenai.ChatClient -import com.simiacryptus.jopenai.models.OpenAITextModel +import com.simiacryptus.jopenai.models.TextModel import com.simiacryptus.skyenet.core.platform.Session import com.simiacryptus.skyenet.webui.session.SessionTask import java.io.File @@ -13,7 +13,7 @@ class CommandPatchApp( session: Session, settings: Settings, api: ChatClient, - model: OpenAITextModel, + model: TextModel, private val files: Array?, val command: String, ) : PatchApp(root, session, settings, api, model) { diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/PatchApp.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/PatchApp.kt index a2c5fcad..e2013b11 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/PatchApp.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/PatchApp.kt @@ -4,20 +4,20 @@ import com.simiacryptus.diff.FileValidationUtils import com.simiacryptus.diff.addApplyFileDiffLinks import com.simiacryptus.jopenai.ChatClient import com.simiacryptus.jopenai.describe.Description -import com.simiacryptus.jopenai.models.OpenAITextModel -import com.simiacryptus.util.JsonUtil +import com.simiacryptus.jopenai.models.TextModel import com.simiacryptus.skyenet.AgentPatterns import com.simiacryptus.skyenet.Retryable import com.simiacryptus.skyenet.core.actors.ParsedActor import com.simiacryptus.skyenet.core.actors.SimpleActor import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.User +import com.simiacryptus.skyenet.util.MarkdownUtil import com.simiacryptus.skyenet.webui.application.ApplicationInterface import com.simiacryptus.skyenet.webui.application.ApplicationServer import com.simiacryptus.skyenet.webui.application.ApplicationSocketManager import com.simiacryptus.skyenet.webui.session.SessionTask import com.simiacryptus.skyenet.webui.session.SocketManager -import com.simiacryptus.skyenet.util.MarkdownUtil +import com.simiacryptus.util.JsonUtil import org.slf4j.LoggerFactory import java.io.File import java.nio.file.Path @@ -27,7 +27,7 @@ abstract class PatchApp( val session: Session, val settings: Settings, val api: ChatClient, - val model: OpenAITextModel, + val model: TextModel, val promptPrefix: String = """The following command was run and produced an error:""" ) : ApplicationServer( applicationName = "Magic Code Fixer", @@ -47,7 +47,7 @@ abstract class PatchApp( abstract fun searchFiles(searchStrings: List): Set override val singleInput = true override val stickyInput = false - override fun newSession(user: User?, session: Session ): SocketManager { + override fun newSession(user: User?, session: Session): SocketManager { val socketManager = super.newSession(user, session) val ui = (socketManager as ApplicationSocketManager).applicationInterface val task = ui.newTask() diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/PlanAheadApp.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/PlanAheadApp.kt index bd2d22d1..c67c4ca1 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/PlanAheadApp.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/PlanAheadApp.kt @@ -2,19 +2,19 @@ package com.simiacryptus.skyenet.apps.general import com.simiacryptus.jopenai.API import com.simiacryptus.jopenai.ChatClient -import com.simiacryptus.jopenai.models.OpenAITextModel -import com.simiacryptus.util.JsonUtil +import com.simiacryptus.jopenai.models.TextModel import com.simiacryptus.skyenet.apps.plan.PlanCoordinator import com.simiacryptus.skyenet.apps.plan.PlanCoordinator.Companion.initialPlan import com.simiacryptus.skyenet.apps.plan.PlanSettings import com.simiacryptus.skyenet.apps.plan.PlanUtil -import com.simiacryptus.skyenet.core.platform.ApplicationServicesConfig.dataStorageRoot import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.ApplicationServicesConfig.dataStorageRoot +import com.simiacryptus.skyenet.core.platform.model.User import com.simiacryptus.skyenet.webui.application.ApplicationInterface import com.simiacryptus.skyenet.webui.application.ApplicationServer import com.simiacryptus.skyenet.webui.application.ApplicationSocketManager import com.simiacryptus.skyenet.webui.session.SocketManager +import com.simiacryptus.util.JsonUtil import org.slf4j.LoggerFactory import java.io.File @@ -22,9 +22,9 @@ open class PlanAheadApp( applicationName: String = "Task Planning v1.1", path: String = "/taskDev", val planSettings: PlanSettings, - val model: OpenAITextModel, - val parsingModel: OpenAITextModel, - val domainName : String = "localhost", + val model: TextModel, + val parsingModel: TextModel, + val domainName: String = "localhost", showMenubar: Boolean = true, val initialPlan: PlanUtil.TaskBreakdownWithPrompt? = null, val api: API? = null, @@ -39,7 +39,7 @@ open class PlanAheadApp( @Suppress("UNCHECKED_CAST") override fun initSettings(session: Session): T = planSettings.let { if (null == root) it.copy(workingDir = root.absolutePath) else - it + it } as T override fun newSession(user: User?, session: Session): SocketManager { diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/PlanChatApp.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/PlanChatApp.kt index ef1af580..87334ca2 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/PlanChatApp.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/PlanChatApp.kt @@ -2,11 +2,11 @@ package com.simiacryptus.skyenet.apps.general import com.simiacryptus.jopenai.API import com.simiacryptus.jopenai.ChatClient -import com.simiacryptus.jopenai.models.OpenAITextModel +import com.simiacryptus.jopenai.models.TextModel import com.simiacryptus.skyenet.apps.plan.* import com.simiacryptus.skyenet.apps.plan.file.InquiryTask.InquiryTaskData import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.User import com.simiacryptus.skyenet.util.MarkdownUtil import com.simiacryptus.skyenet.webui.application.ApplicationInterface import org.slf4j.LoggerFactory @@ -17,8 +17,8 @@ open class PlanChatApp( applicationName: String = "Task Planning Chat v1.0", path: String = "/taskChat", planSettings: PlanSettings, - model: OpenAITextModel, - parsingModel: OpenAITextModel, + model: TextModel, + parsingModel: TextModel, domainName: String = "localhost", showMenubar: Boolean = true, initialPlan: PlanUtil.TaskBreakdownWithPrompt? = null, @@ -111,11 +111,11 @@ open class PlanChatApp( ) val modifiedPlan = addRespondToChatTask(plan.plan) val planProcessingState = coordinator.executePlan( - plan = modifiedPlan, - task = sessionTask, - userMessage = userMessage, - api = api - ) + plan = modifiedPlan, + task = sessionTask, + userMessage = userMessage, + api = api + ) val response = planProcessingState.taskResult["respond_to_chat"] as? String if (response != null) { mainTask.add(MarkdownUtil.renderMarkdown(response, ui = ui)) diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/StressTestApp.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/StressTestApp.kt index 0344a4f9..d9641799 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/StressTestApp.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/StressTestApp.kt @@ -3,11 +3,11 @@ package com.simiacryptus.skyenet.apps.general import com.simiacryptus.jopenai.API import com.simiacryptus.skyenet.TabbedDisplay import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.User +import com.simiacryptus.skyenet.util.MarkdownUtil import com.simiacryptus.skyenet.webui.application.ApplicationInterface import com.simiacryptus.skyenet.webui.application.ApplicationServer import com.simiacryptus.skyenet.webui.session.SessionTask -import com.simiacryptus.skyenet.util.MarkdownUtil import org.slf4j.LoggerFactory import kotlin.random.Random @@ -27,8 +27,8 @@ class StressTestApp( api: API ) { val task = ui.newTask() - task.add(MarkdownUtil.renderMarkdown("# UI Stress Test", ui=ui)) - + task.add(MarkdownUtil.renderMarkdown("# UI Stress Test", ui = ui)) + // Create nested tabs createNestedTabs(task, ui, 3) @@ -74,13 +74,13 @@ class StressTestApp( B ---->|No| E[End] ``` """.trimIndent() - - task.add(MarkdownUtil.renderMarkdown("## Complex Diagram\n$mermaidDiagram", ui=ui)) + + task.add(MarkdownUtil.renderMarkdown("## Complex Diagram\n$mermaidDiagram", ui = ui)) } private fun createAndUpdatePlaceholders(task: SessionTask, ui: ApplicationInterface) { val placeholders = (1..5).map { ui.newTask(false) } - + placeholders.forEach { placeholder -> task.add(placeholder.placeholder) } @@ -88,7 +88,7 @@ class StressTestApp( repeat(10) { iteration -> placeholders.forEach { placeholder -> val content = "Placeholder content: Iteration $iteration, Random: ${Random.nextInt(100)}" - placeholder.add(MarkdownUtil.renderMarkdown(content, ui=ui)) + placeholder.add(MarkdownUtil.renderMarkdown(content, ui = ui)) //Thread.sleep(50) } } diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/WebDevApp.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/WebDevApp.kt index 2d542868..2ac65f1e 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/WebDevApp.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/general/WebDevApp.kt @@ -2,27 +2,27 @@ package com.simiacryptus.skyenet.apps.general import com.simiacryptus.diff.addApplyFileDiffLinks import com.simiacryptus.jopenai.API -import com.simiacryptus.jopenai.models.ApiModel -import com.simiacryptus.jopenai.models.ApiModel.Role import com.simiacryptus.jopenai.ChatClient import com.simiacryptus.jopenai.describe.Description -import com.simiacryptus.jopenai.models.ChatModels +import com.simiacryptus.jopenai.models.ApiModel +import com.simiacryptus.jopenai.models.ApiModel.Role +import com.simiacryptus.jopenai.models.ChatModel import com.simiacryptus.jopenai.models.ImageModels import com.simiacryptus.jopenai.models.OpenAIModels import com.simiacryptus.jopenai.proxy.ValidatedObject import com.simiacryptus.jopenai.util.ClientUtil.toContentList -import com.simiacryptus.util.JsonUtil import com.simiacryptus.skyenet.AgentPatterns import com.simiacryptus.skyenet.Discussable import com.simiacryptus.skyenet.TabbedDisplay import com.simiacryptus.skyenet.core.actors.* import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.StorageInterface -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.StorageInterface +import com.simiacryptus.skyenet.core.platform.model.User +import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown import com.simiacryptus.skyenet.webui.application.ApplicationInterface import com.simiacryptus.skyenet.webui.application.ApplicationServer import com.simiacryptus.skyenet.webui.session.SessionTask -import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown +import com.simiacryptus.util.JsonUtil import org.intellij.lang.annotations.Language import java.io.ByteArrayOutputStream import java.io.File @@ -67,8 +67,8 @@ open class WebDevApp( data class Settings( val budget: Double? = 2.00, val tools: List = emptyList(), - val model: ChatModels = OpenAIModels.GPT4o, - val parsingModel: ChatModels = OpenAIModels.GPT4oMini, + val model: ChatModel = OpenAIModels.GPT4o, + val parsingModel: ChatModel = OpenAIModels.GPT4oMini, ) override val settingsClass: Class<*> get() = Settings::class.java @@ -83,8 +83,8 @@ class WebDevAgent( session: Session, user: User?, val ui: ApplicationInterface, - val model: ChatModels, - val parsingModel: ChatModels, + val model: ChatModel, + val parsingModel: ChatModel, val tools: List = emptyList(), @Language("Markdown") val actorMap: Map> = mapOf( ActorTypes.ArchitectureDiscussionActor to ParsedActor( diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/ActorDesigner.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/ActorDesigner.kt index 82012145..f080762b 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/ActorDesigner.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/ActorDesigner.kt @@ -1,11 +1,11 @@ package com.simiacryptus.skyenet.apps.meta -import com.simiacryptus.jopenai.models.ChatModels +import com.simiacryptus.jopenai.models.ChatModel import com.simiacryptus.jopenai.models.OpenAIModels import com.simiacryptus.skyenet.core.actors.ParsedActor class ActorDesigner( - model: ChatModels, + model: ChatModel, temperature: Double ) : ParsedActor( resultClass = AgentActorDesign::class.java, diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/CodingActorDesigner.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/CodingActorDesigner.kt index e3844314..3311f4fc 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/CodingActorDesigner.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/CodingActorDesigner.kt @@ -1,6 +1,6 @@ package com.simiacryptus.skyenet.apps.meta -import com.simiacryptus.jopenai.models.ChatModels +import com.simiacryptus.jopenai.models.ChatModel import com.simiacryptus.skyenet.apps.meta.FlowStepDesigner.Companion.fixups import com.simiacryptus.skyenet.core.actors.CodingActor import com.simiacryptus.skyenet.interpreter.Interpreter @@ -9,7 +9,7 @@ import kotlin.reflect.KClass class CodingActorDesigner( interpreterClass: KClass, symbols: Map, - model: ChatModels, + model: ChatModel, temperature: Double ) : CodingActor( interpreterClass = interpreterClass, diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/DetailDesigner.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/DetailDesigner.kt index 07b9ecf7..e1042e32 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/DetailDesigner.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/DetailDesigner.kt @@ -1,11 +1,11 @@ package com.simiacryptus.skyenet.apps.meta -import com.simiacryptus.jopenai.models.ChatModels +import com.simiacryptus.jopenai.models.ChatModel import com.simiacryptus.jopenai.models.OpenAIModels import com.simiacryptus.skyenet.core.actors.ParsedActor class DetailDesigner( - model: ChatModels, + model: ChatModel, temperature: Double ) : ParsedActor( resultClass = AgentFlowDesign::class.java, diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/FlowStepDesigner.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/FlowStepDesigner.kt index cf478a8d..8bc6fad8 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/FlowStepDesigner.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/FlowStepDesigner.kt @@ -1,6 +1,6 @@ package com.simiacryptus.skyenet.apps.meta -import com.simiacryptus.jopenai.models.ChatModels +import com.simiacryptus.jopenai.models.ChatModel import com.simiacryptus.skyenet.core.actors.CodingActor import com.simiacryptus.skyenet.interpreter.Interpreter import org.slf4j.LoggerFactory @@ -9,7 +9,7 @@ import kotlin.reflect.KClass class FlowStepDesigner( interpreterClass: KClass, symbols: Map, - model: ChatModels, + model: ChatModel, temperature: Double ) : CodingActor( interpreterClass = interpreterClass, diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/HighLevelDesigner.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/HighLevelDesigner.kt index 72e4cf6d..c5ff4a3a 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/HighLevelDesigner.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/HighLevelDesigner.kt @@ -1,10 +1,10 @@ package com.simiacryptus.skyenet.apps.meta -import com.simiacryptus.jopenai.models.ChatModels +import com.simiacryptus.jopenai.models.ChatModel import com.simiacryptus.skyenet.core.actors.SimpleActor class HighLevelDesigner( - model: ChatModels, + model: ChatModel, temperature: Double ) : SimpleActor( model = model, diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/ImageActorDesigner.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/ImageActorDesigner.kt index b23f4ae4..040c621c 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/ImageActorDesigner.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/ImageActorDesigner.kt @@ -1,6 +1,6 @@ package com.simiacryptus.skyenet.apps.meta -import com.simiacryptus.jopenai.models.ChatModels +import com.simiacryptus.jopenai.models.ChatModel import com.simiacryptus.skyenet.apps.meta.FlowStepDesigner.Companion.fixups import com.simiacryptus.skyenet.core.actors.CodingActor import com.simiacryptus.skyenet.interpreter.Interpreter @@ -9,7 +9,7 @@ import kotlin.reflect.KClass class ImageActorDesigner( interpreterClass: KClass, symbols: Map, - model: ChatModels, + model: ChatModel, temperature: Double ) : CodingActor( interpreterClass = interpreterClass, diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/MetaAgentApp.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/MetaAgentApp.kt index 0f6fa627..aa079761 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/MetaAgentApp.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/MetaAgentApp.kt @@ -2,14 +2,13 @@ package com.simiacryptus.skyenet.apps.meta import com.simiacryptus.jopenai.API import com.simiacryptus.jopenai.ChatClient +import com.simiacryptus.jopenai.describe.Description import com.simiacryptus.jopenai.models.ApiModel import com.simiacryptus.jopenai.models.ApiModel.Role -import com.simiacryptus.jopenai.describe.Description -import com.simiacryptus.jopenai.models.ChatModels +import com.simiacryptus.jopenai.models.ChatModel import com.simiacryptus.jopenai.models.OpenAIModels import com.simiacryptus.jopenai.proxy.ValidatedObject import com.simiacryptus.jopenai.util.ClientUtil.toContentList -import com.simiacryptus.util.JsonUtil import com.simiacryptus.skyenet.Discussable import com.simiacryptus.skyenet.Retryable import com.simiacryptus.skyenet.apps.meta.MetaAgentActors.Companion.notIn @@ -24,21 +23,21 @@ import com.simiacryptus.skyenet.core.actors.ParsedResponse import com.simiacryptus.skyenet.core.actors.PoolSystem import com.simiacryptus.skyenet.core.platform.ApplicationServices import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.StorageInterface -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.StorageInterface +import com.simiacryptus.skyenet.core.platform.model.User import com.simiacryptus.skyenet.interpreter.Interpreter import com.simiacryptus.skyenet.kotlin.KotlinInterpreter +import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown import com.simiacryptus.skyenet.webui.application.ApplicationInterface import com.simiacryptus.skyenet.webui.application.ApplicationServer import com.simiacryptus.skyenet.webui.session.SessionTask -import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown +import com.simiacryptus.util.JsonUtil import org.eclipse.jetty.webapp.WebAppClassLoader import org.intellij.lang.annotations.Language import org.slf4j.LoggerFactory import java.io.IOException import java.net.SocketTimeoutException import java.util.* -import kotlin.collections.HashMap import kotlin.reflect.KClass open class MetaAgentApp( @@ -69,7 +68,7 @@ open class MetaAgentApp( }
" data class Settings( - val model: ChatModels = OpenAIModels.GPT4o, + val model: ChatModel = OpenAIModels.GPT4o, val validateCode: Boolean = true, val temperature: Double = 0.2, val budget: Double = 2.0, @@ -139,7 +138,7 @@ open class MetaAgentAgent( dataStorage: StorageInterface, val ui: ApplicationInterface, val api: API, - model: ChatModels = OpenAIModels.GPT4oMini, + model: ChatModel = OpenAIModels.GPT4oMini, var autoEvaluate: Boolean = true, temperature: Double = 0.3, ) : PoolSystem( @@ -621,7 +620,7 @@ open class MetaAgentAgent( class MetaAgentActors( val symbols: Map = mapOf(), - val model: ChatModels = OpenAIModels.GPT4o, + val model: ChatModel = OpenAIModels.GPT4o, val temperature: Double = 0.3, ) { diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/ParsedActorDesigner.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/ParsedActorDesigner.kt index 74978eac..412376e9 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/ParsedActorDesigner.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/ParsedActorDesigner.kt @@ -1,6 +1,6 @@ package com.simiacryptus.skyenet.apps.meta -import com.simiacryptus.jopenai.models.ChatModels +import com.simiacryptus.jopenai.models.ChatModel import com.simiacryptus.jopenai.models.OpenAIModels import com.simiacryptus.skyenet.apps.meta.FlowStepDesigner.Companion.fixups import com.simiacryptus.skyenet.core.actors.CodingActor @@ -11,7 +11,7 @@ import kotlin.reflect.KClass class ParsedActorDesigner( interpreterClass: KClass = KotlinInterpreter::class, symbols: Map = mapOf(), - model: ChatModels = OpenAIModels.GPT4o, + model: ChatModel = OpenAIModels.GPT4o, temperature: Double = 0.3, ) : CodingActor( interpreterClass = interpreterClass, diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/SimpleActorDesigner.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/SimpleActorDesigner.kt index f0479c64..d5b54aca 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/SimpleActorDesigner.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/meta/SimpleActorDesigner.kt @@ -1,6 +1,6 @@ package com.simiacryptus.skyenet.apps.meta -import com.simiacryptus.jopenai.models.ChatModels +import com.simiacryptus.jopenai.models.ChatModel import com.simiacryptus.skyenet.apps.meta.FlowStepDesigner.Companion.fixups import com.simiacryptus.skyenet.core.actors.CodingActor import com.simiacryptus.skyenet.interpreter.Interpreter @@ -9,7 +9,7 @@ import kotlin.reflect.KClass class SimpleActorDesigner( interpreterClass: KClass, symbols: Map, - model: ChatModels, + model: ChatModel, temperature: Double ) : CodingActor( interpreterClass = interpreterClass, diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/parsers/CodeParsingModel.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/parsers/CodeParsingModel.kt index 691d4747..a0a040c9 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/parsers/CodeParsingModel.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/parsers/CodeParsingModel.kt @@ -2,11 +2,11 @@ package com.simiacryptus.skyenet.apps.parsers import com.simiacryptus.jopenai.API import com.simiacryptus.jopenai.describe.Description -import com.simiacryptus.jopenai.models.ChatModels +import com.simiacryptus.jopenai.models.ChatModel import com.simiacryptus.skyenet.core.actors.ParsedActor open class CodeParsingModel( - private val parsingModel: ChatModels, + private val parsingModel: ChatModel, private val temperature: Double ) : ParsingModel { diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/parsers/DocumentParserApp.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/parsers/DocumentParserApp.kt index 6f0e73d4..30603403 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/parsers/DocumentParserApp.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/parsers/DocumentParserApp.kt @@ -2,16 +2,16 @@ package com.simiacryptus.skyenet.apps.parsers import com.simiacryptus.jopenai.API import com.simiacryptus.jopenai.ChatClient -import com.simiacryptus.util.JsonUtil import com.simiacryptus.skyenet.TabbedDisplay import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.User +import com.simiacryptus.skyenet.util.MarkdownUtil import com.simiacryptus.skyenet.webui.application.ApplicationInterface import com.simiacryptus.skyenet.webui.application.ApplicationServer import com.simiacryptus.skyenet.webui.application.ApplicationSocketManager import com.simiacryptus.skyenet.webui.session.SessionTask import com.simiacryptus.skyenet.webui.session.SocketManager -import com.simiacryptus.skyenet.util.MarkdownUtil +import com.simiacryptus.util.JsonUtil import org.intellij.lang.annotations.Language import java.awt.image.BufferedImage import java.io.File @@ -156,7 +156,7 @@ open class DocumentParserApp( @Language("Markdown") val jsonResult = parsingModel.getParser(api).let { it(promptList.toList().joinToString("\n\n")) } - if(settings.saveTextFiles) { + if (settings.saveTextFiles) { val jsonFile = outputDir.resolve("pages_${batchStart + 1}_to_${batchEnd}_content.json") jsonFile.writeText(JsonUtil.toJson(jsonResult)) } diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/parsers/DocumentParsingModel.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/parsers/DocumentParsingModel.kt index 61190375..77986592 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/parsers/DocumentParsingModel.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/parsers/DocumentParsingModel.kt @@ -2,12 +2,12 @@ package com.simiacryptus.skyenet.apps.parsers import com.simiacryptus.jopenai.API import com.simiacryptus.jopenai.describe.Description -import com.simiacryptus.jopenai.models.ChatModels +import com.simiacryptus.jopenai.models.ChatModel import com.simiacryptus.skyenet.core.actors.ParsedActor open class DocumentParsingModel( - private val parsingModel: ChatModels, + private val parsingModel: ChatModel, private val temperature: Double ) : ParsingModel { diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/parsers/ParsingModel.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/parsers/ParsingModel.kt index 480c42c0..96309507 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/parsers/ParsingModel.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/parsers/ParsingModel.kt @@ -14,6 +14,7 @@ interface ParsingModel { val content: List? val tags: List? } + interface DocumentData { val id: String? val content: List? diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/parsers/TextReader.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/parsers/TextReader.kt index c0780a18..b1e9fa84 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/parsers/TextReader.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/parsers/TextReader.kt @@ -7,7 +7,7 @@ import kotlin.math.abs class TextReader(private val textFile: File) : DocumentParserApp.DocumentReader { private val pages: List = splitIntoPages(textFile.readLines().joinToString("\n")) - override fun getPageCount(): Int = pages.size + override fun getPageCount(): Int = pages.size override fun getText(startPage: Int, endPage: Int): String { return pages.subList(startPage, endPage.coerceAtMost(pages.size)).joinToString("\n") @@ -20,6 +20,7 @@ class TextReader(private val textFile: File) : DocumentParserApp.DocumentReader override fun close() { // No resources to close for text files } + private fun splitIntoPages(text: String, maxChars: Int = 16000): List { if (text.length <= maxChars) return listOf(text) val lines = text.split("\n") diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/CommandAutoFixTask.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/CommandAutoFixTask.kt index 66f4bbff..030c7d7b 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/CommandAutoFixTask.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/CommandAutoFixTask.kt @@ -31,6 +31,7 @@ class CommandAutoFixTask( task_dependencies = task_dependencies, state = state ) + data class CommandWithWorkingDir( @Description("The command to be executed") val command: List, @@ -104,21 +105,23 @@ ${planSettings.commandAutoFixCommands?.joinToString("\n") { " * ${File(it).na hasError.set(true) } task.add(MarkdownUtil.renderMarkdown("## Command Auto Fix Result for Command ${index + 1}\n", ui = agent.ui, tabs = false)) - task.add(if (outputResult.exitCode == 0) { - if (agent.planSettings.autoFix) { - MarkdownUtil.renderMarkdown("Auto-applied Command Auto Fix\n", ui = agent.ui, tabs = false) + task.add( + if (outputResult.exitCode == 0) { + if (agent.planSettings.autoFix) { + MarkdownUtil.renderMarkdown("Auto-applied Command Auto Fix\n", ui = agent.ui, tabs = false) + } else { + MarkdownUtil.renderMarkdown( + "Command Auto Fix Result\n", + ui = agent.ui, tabs = false + ) + } } else { MarkdownUtil.renderMarkdown( - "Command Auto Fix Result\n", + "Command Auto Fix Failed\n", ui = agent.ui, tabs = false ) } - } else { - MarkdownUtil.renderMarkdown( - "Command Auto Fix Failed\n", - ui = agent.ui, tabs = false - ) - }) + ) } resultFn("All Command Auto Fix tasks completed") task.add(if (!hasError.get()) { diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/ForeachTask.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/ForeachTask.kt index e5c0bd1c..7b1e04eb 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/ForeachTask.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/ForeachTask.kt @@ -51,7 +51,7 @@ ForeachTask - Execute a task for each item in a list val subTasks = planTask.foreach_subplan ?: throw RuntimeException("No subTasks specified for ForeachTask") val subPlanTask = agent.ui.newTask(false) task.add(subPlanTask.placeholder) - + items.forEachIndexed { index, item -> val itemSubTasks = subTasks.mapValues { (_, subTaskPlan) -> subTaskPlan.task_description = "${subTaskPlan.task_description} - Item $index: $item" diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/PlanCoordinator.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/PlanCoordinator.kt index 074395c9..4a29693e 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/PlanCoordinator.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/PlanCoordinator.kt @@ -15,8 +15,8 @@ import com.simiacryptus.skyenet.apps.plan.TaskType.Companion.getImpl import com.simiacryptus.skyenet.core.actors.ParsedResponse import com.simiacryptus.skyenet.core.platform.ApplicationServices import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.StorageInterface -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.StorageInterface +import com.simiacryptus.skyenet.core.platform.model.User import com.simiacryptus.skyenet.set import com.simiacryptus.skyenet.util.MarkdownUtil import com.simiacryptus.skyenet.webui.application.ApplicationInterface @@ -67,14 +67,16 @@ class PlanCoordinator( } task.add( MarkdownUtil.renderMarkdown( - """ + """ |## Executing TaskBreakdownWithPrompt |Prompt: ${taskBreakdownWithPrompt.prompt} |Plan Text: |``` |${taskBreakdownWithPrompt.planText} |``` - """.trimMargin(), ui = ui)) + """.trimMargin(), ui = ui + ) + ) executePlan(plan ?: emptyMap(), task, taskBreakdownWithPrompt.prompt, api) } catch (e: Exception) { task.error(ui, e) diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/PlanSettings.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/PlanSettings.kt index c0168ee7..5a4e8820 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/PlanSettings.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/PlanSettings.kt @@ -1,24 +1,24 @@ package com.simiacryptus.skyenet.apps.plan import com.simiacryptus.jopenai.describe.AbbrevWhitelistYamlDescriber -import com.simiacryptus.jopenai.models.OpenAITextModel +import com.simiacryptus.jopenai.models.TextModel import com.simiacryptus.skyenet.apps.plan.CommandAutoFixTask.CommandAutoFixTaskData -import com.simiacryptus.skyenet.apps.plan.file.FileModificationTask.FileModificationTaskData import com.simiacryptus.skyenet.apps.plan.PlanUtil.isWindows import com.simiacryptus.skyenet.apps.plan.PlanningTask.PlanningTaskData import com.simiacryptus.skyenet.apps.plan.PlanningTask.TaskBreakdownResult import com.simiacryptus.skyenet.apps.plan.TaskType.Companion.getAvailableTaskTypes import com.simiacryptus.skyenet.apps.plan.TaskType.Companion.getImpl +import com.simiacryptus.skyenet.apps.plan.file.FileModificationTask.FileModificationTaskData import com.simiacryptus.skyenet.core.actors.ParsedActor data class TaskSettings( var enabled: Boolean = false, - var model: OpenAITextModel? = null + var model: TextModel? = null ) open class PlanSettings( - var defaultModel: OpenAITextModel, - var parsingModel: OpenAITextModel, + var defaultModel: TextModel, + var parsingModel: TextModel, val command: List = listOf(if (isWindows) "powershell" else "bash"), var temperature: Double = 0.2, val budget: Double = 2.0, @@ -46,8 +46,8 @@ open class PlanSettings( } fun copy( - model: OpenAITextModel = this.defaultModel, - parsingModel: OpenAITextModel = this.parsingModel, + model: TextModel = this.defaultModel, + parsingModel: TextModel = this.parsingModel, command: List = this.command, temperature: Double = this.temperature, budget: Double = this.budget, @@ -98,11 +98,14 @@ open class PlanSettings( val parserPrompt = """ Task Subtype Schema: -${getAvailableTaskTypes(this).joinToString("\n\n") { taskType -> """ +${ + getAvailableTaskTypes(this).joinToString("\n\n") { taskType -> + """ ${taskType.name}: ${describer.describe(taskType.taskDataClass).replace("\n", "\n ")} """.trim() - }} + } + } """.trimIndent() return ParsedActor( name = "TaskBreakdown", diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/PlanUtil.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/PlanUtil.kt index 1fa4dd40..300d66d4 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/PlanUtil.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/PlanUtil.kt @@ -14,7 +14,7 @@ object PlanUtil { ui: ApplicationInterface, taskMap: Map ) = MarkdownUtil.renderMarkdown( - """ + """ |## Sub-Plan Task Dependency Graph |${TRIPLE_TILDE}mermaid |${buildMermaidGraph(taskMap)} @@ -54,9 +54,11 @@ object PlanUtil { val taskMap = tasks.toMutableMap() while (taskMap.isNotEmpty()) { val nextTasks = - taskMap.filter { (_, task) -> task.task_dependencies?.filter { entry -> - entry in tasks.keys - }?.all { taskIds.contains(it) } ?: true } + taskMap.filter { (_, task) -> + task.task_dependencies?.filter { entry -> + entry in tasks.keys + }?.all { taskIds.contains(it) } ?: true + } if (nextTasks.isEmpty()) { throw RuntimeException("Circular dependency detected in task breakdown") } diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/PlanningTask.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/PlanningTask.kt index 033ca03a..4590d173 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/PlanningTask.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/PlanningTask.kt @@ -68,6 +68,7 @@ class PlanningTask( getPriorCode(planProcessingState), s ).filter { it.isNotBlank() } + val subPlan = if (planSettings.allowBlocking && !planSettings.autoFix) { createSubPlanDiscussable(newTask, userMessage, ::toInput, api, agent.ui).call().obj } else { diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/TaskType.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/TaskType.kt index 4cfe64c1..7d35a4bb 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/TaskType.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/TaskType.kt @@ -8,18 +8,18 @@ import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver import com.fasterxml.jackson.databind.jsontype.impl.TypeIdResolverBase import com.simiacryptus.jopenai.describe.Description import com.simiacryptus.skyenet.apps.plan.AbstractTask.TaskState +import com.simiacryptus.skyenet.apps.plan.CommandAutoFixTask.CommandAutoFixTaskData +import com.simiacryptus.skyenet.apps.plan.ForeachTask.ForeachTaskData +import com.simiacryptus.skyenet.apps.plan.PlanningTask.PlanningTaskData +import com.simiacryptus.skyenet.apps.plan.RunShellCommandTask.RunShellCommandTaskData +import com.simiacryptus.skyenet.apps.plan.file.* import com.simiacryptus.skyenet.apps.plan.file.CodeOptimizationTask.CodeOptimizationTaskData import com.simiacryptus.skyenet.apps.plan.file.CodeReviewTask.CodeReviewTaskData -import com.simiacryptus.skyenet.apps.plan.CommandAutoFixTask.CommandAutoFixTaskData import com.simiacryptus.skyenet.apps.plan.file.DocumentationTask.DocumentationTaskData import com.simiacryptus.skyenet.apps.plan.file.FileModificationTask.FileModificationTaskData -import com.simiacryptus.skyenet.apps.plan.ForeachTask.ForeachTaskData import com.simiacryptus.skyenet.apps.plan.file.InquiryTask.InquiryTaskData import com.simiacryptus.skyenet.apps.plan.file.PerformanceAnalysisTask.PerformanceAnalysisTaskData -import com.simiacryptus.skyenet.apps.plan.PlanningTask.PlanningTaskData import com.simiacryptus.skyenet.apps.plan.file.RefactorTask.RefactorTaskData -import com.simiacryptus.skyenet.apps.plan.RunShellCommandTask.RunShellCommandTaskData -import com.simiacryptus.skyenet.apps.plan.file.* import com.simiacryptus.skyenet.apps.plan.file.SecurityAuditTask.SecurityAuditTaskData import com.simiacryptus.skyenet.apps.plan.file.TestGenerationTask.TestGenerationTaskData import com.simiacryptus.util.DynamicEnum @@ -75,7 +75,7 @@ class TaskType( taskType: TaskType, constructor: (PlanSettings, T?) -> AbstractTask ) { - taskConstructors[taskType] = { settings : PlanSettings, task : PlanTaskBase? -> + taskConstructors[taskType] = { settings: PlanSettings, task: PlanTaskBase? -> constructor(settings, task as T?) } register(taskType) diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/file/DocumentationTask.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/file/DocumentationTask.kt index c164e6ba..7d0a300b 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/file/DocumentationTask.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/file/DocumentationTask.kt @@ -1,4 +1,5 @@ package com.simiacryptus.skyenet.apps.plan.file + import com.simiacryptus.diff.addApplyFileDiffLinks import com.simiacryptus.jopenai.API diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/file/EmbeddingSearchTask.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/file/EmbeddingSearchTask.kt index 40c5b95e..d699a91d 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/file/EmbeddingSearchTask.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/file/EmbeddingSearchTask.kt @@ -62,12 +62,14 @@ EmbeddingSearch - Search for similar embeddings in index files and provide top r } private fun performEmbeddingSearch(api: OpenAIClient): List { - val queryEmbedding = api.createEmbedding(ApiModel.EmbeddingRequest( - input = planTask?.search_query ?: "", - model = (planSettings.getTaskSettings(TaskType.EmbeddingSearch).model - ?: planSettings.defaultModel).modelName + val queryEmbedding = api.createEmbedding( + ApiModel.EmbeddingRequest( + input = planTask?.search_query ?: "", + model = (planSettings.getTaskSettings(TaskType.EmbeddingSearch).model + ?: planSettings.defaultModel).modelName - )).data[0].embedding + ) + ).data[0].embedding val distanceType = planTask?.distance_type ?: DistanceType.Cosine return (planTask?.input_files ?: listOf()) diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/file/InquiryTask.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/file/InquiryTask.kt index 6c56a0f2..85d12e1c 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/file/InquiryTask.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/file/InquiryTask.kt @@ -61,8 +61,8 @@ class InquiryTask( When generating insights, consider the existing project context and focus on information that is directly relevant and applicable. Focus on generating insights and information that support the task types available in the system (${ - planSettings.taskSettings.filter { it.value.enabled }.keys.joinToString(", ") - }). + planSettings.taskSettings.filter { it.value.enabled }.keys.joinToString(", ") + }). This will ensure that the inquiries are tailored to assist in the planning and execution of tasks within the system's framework. """.trimMargin(), model = planSettings.getTaskSettings(TaskType.valueOf(planTask?.task_type!!)).model ?: planSettings.defaultModel, diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/file/PerformanceAnalysisTask.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/file/PerformanceAnalysisTask.kt index 4b5924a2..138caee2 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/file/PerformanceAnalysisTask.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/file/PerformanceAnalysisTask.kt @@ -54,6 +54,7 @@ PerformanceAnalysis - Analyze code for performance issues and suggest improvemen ** Optionally provide specific areas of focus for the analysis (e.g., time complexity, memory usage, I/O operations) """.trimMargin() } + fun getFiles(): List { return planTask?.files_to_analyze ?: emptyList() } diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/file/SecurityAuditTask.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/file/SecurityAuditTask.kt index 5b6e22f7..63a83c93 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/file/SecurityAuditTask.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/apps/plan/file/SecurityAuditTask.kt @@ -45,6 +45,7 @@ Provide a detailed audit report with specific examples and recommendations for e Format the response as a markdown document with appropriate headings and code snippets. Use diff format to show the proposed security fixes clearly. """.trimIndent() + override fun getAnalysisInstruction(): String = "Perform a security audit on the following code" override fun promptSegment(): String { diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/util/MarkdownUtil.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/util/MarkdownUtil.kt index f51892ed..e5127f8b 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/util/MarkdownUtil.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/util/MarkdownUtil.kt @@ -32,7 +32,7 @@ object MarkdownUtil { val fixedMermaidCode = fixupMermaidCode(mermaidCode) var mermaidDiagramHTML = """
$fixedMermaidCode
""" try { - if(true){ + if (true) { val svg = renderMermaidToSVG(fixedMermaidCode) if (null != ui) { val newTask = ui.newTask(false) diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/util/OpenAPI.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/util/OpenAPI.kt index ba0c27c2..e6d2759b 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/util/OpenAPI.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/util/OpenAPI.kt @@ -1,8 +1,6 @@ package com.simiacryptus.skyenet.util import com.fasterxml.jackson.annotation.JsonInclude -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue // OpenAPI root document data class OpenAPI( diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/util/TensorflowProjector.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/util/TensorflowProjector.kt index c38df47b..03a1f525 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/util/TensorflowProjector.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/util/TensorflowProjector.kt @@ -2,15 +2,14 @@ package com.simiacryptus.skyenet.util import com.simiacryptus.jopenai.API import com.simiacryptus.jopenai.OpenAIClient -import com.simiacryptus.jopenai.models.ApiModel import com.simiacryptus.jopenai.models.ApiModel.EmbeddingRequest import com.simiacryptus.jopenai.models.EmbeddingModels -import com.simiacryptus.util.JsonUtil import com.simiacryptus.skyenet.core.platform.ApplicationServices.cloud import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.StorageInterface -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.StorageInterface +import com.simiacryptus.skyenet.core.platform.model.User import com.simiacryptus.skyenet.webui.application.ApplicationInterface +import com.simiacryptus.util.JsonUtil class TensorflowProjector( val api: API, diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/application/ApplicationDirectory.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/application/ApplicationDirectory.kt index 8381541f..6ad09dba 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/application/ApplicationDirectory.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/application/ApplicationDirectory.kt @@ -5,7 +5,7 @@ import com.simiacryptus.jopenai.util.ClientUtil import com.simiacryptus.util.JsonUtil import com.simiacryptus.skyenet.core.OutputInterceptor import com.simiacryptus.skyenet.core.platform.ApplicationServices -import com.simiacryptus.skyenet.core.platform.ApplicationServicesConfig.isLocked +import com.simiacryptus.skyenet.core.platform.model.ApplicationServicesConfig.isLocked import com.simiacryptus.skyenet.webui.chat.ChatServer import com.simiacryptus.skyenet.webui.servlet.* import com.simiacryptus.skyenet.util.Selenium2S3 @@ -80,7 +80,7 @@ abstract class ApplicationDirectory( log.info("Starting application with args: ${args.joinToString(", ")}") setupPlatform() init(args.contains("--server")) - if(ClientUtil.keyTxt.isEmpty()) ClientUtil.keyTxt = run { + if (ClientUtil.keyTxt.isEmpty()) ClientUtil.keyTxt = run { try { val encryptedData = javaClass.classLoader.getResourceAsStream("openai.key.json.kms")?.readAllBytes() ?: throw RuntimeException("Unable to load resource: ${"openai.key.json.kms"}") @@ -117,7 +117,7 @@ abstract class ApplicationDirectory( open fun webAppContexts() = listOfNotNull( newWebAppContext("/logout", logoutServlet), newWebAppContext("/proxy", proxyHttpServlet), - // toolServlet?.let { newWebAppContext("/tools", it) }, + // toolServlet?.let { newWebAppContext("/tools", it) }, newWebAppContext("/userInfo", userInfoServlet).let { authenticatedWebsite()?.configure(it, true) ?: it }, @@ -205,8 +205,11 @@ abstract class ApplicationDirectory( context.baseResource = baseResource log.debug("New WebAppContext created for path: $path") context.contextPath = path +// context.resourceBase = resourceBase context.welcomeFiles = arrayOf("index.html") if (indexServlet != null) { + context.addServlet(ServletHolder("$path/index", indexServlet), "/") +// context.addServlet(ServletHolder("$path/index", indexServlet), "/*") context.addServlet(ServletHolder("$path/index", indexServlet), "/index.html") } return context diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/application/ApplicationServer.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/application/ApplicationServer.kt index a9fe8020..f30af0b6 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/application/ApplicationServer.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/application/ApplicationServer.kt @@ -4,12 +4,12 @@ import com.simiacryptus.jopenai.API import com.simiacryptus.skyenet.core.platform.ApplicationServices.authenticationManager import com.simiacryptus.skyenet.core.platform.ApplicationServices.authorizationManager import com.simiacryptus.skyenet.core.platform.ApplicationServices.dataStorageFactory -import com.simiacryptus.skyenet.core.platform.ApplicationServicesConfig.dataStorageRoot -import com.simiacryptus.skyenet.core.platform.AuthenticationInterface -import com.simiacryptus.skyenet.core.platform.AuthorizationInterface.OperationType import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.StorageInterface -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.ApplicationServicesConfig.dataStorageRoot +import com.simiacryptus.skyenet.core.platform.model.AuthenticationInterface +import com.simiacryptus.skyenet.core.platform.model.AuthorizationInterface.OperationType +import com.simiacryptus.skyenet.core.platform.model.StorageInterface +import com.simiacryptus.skyenet.core.platform.model.User import com.simiacryptus.skyenet.webui.chat.ChatServer import com.simiacryptus.skyenet.webui.servlet.* import com.simiacryptus.skyenet.webui.session.SocketManager @@ -44,9 +44,11 @@ abstract class ApplicationServer( final override val dataStorage: StorageInterface by lazy { dataStorageFactory(dataStorageRoot) } - protected open val appInfoServlet by lazy { ServletHolder("appInfo", AppInfoServlet { session -> - appInfo(Session(session!!)) - }) } + protected open val appInfoServlet by lazy { + ServletHolder("appInfo", AppInfoServlet { session -> + appInfo(Session(session!!)) + }) + } protected open val userInfo by lazy { ServletHolder("userInfo", UserInfoServlet()) } protected open val usageServlet by lazy { ServletHolder("usage", UsageServlet()) } protected open val fileZip by lazy { ServletHolder("fileZip", ZipServlet(dataStorage)) } @@ -58,12 +60,14 @@ abstract class ApplicationServer( protected open val cancelSessionServlet by lazy { ServletHolder("cancel", CancelThreadsServlet(this)) } override fun newSession(user: User?, session: Session): SocketManager { - dataStorage.setJson(user, session, "info.json", mapOf( - "session" to session.toString(), - "application" to applicationName, - "path" to path, - "startTime" to System.currentTimeMillis(), - )) + dataStorage.setJson( + user, session, "info.json", mapOf( + "session" to session.toString(), + "application" to applicationName, + "path" to path, + "startTime" to System.currentTimeMillis(), + ) + ) return object : ApplicationSocketManager( session = session, owner = user, @@ -104,13 +108,13 @@ abstract class ApplicationServer( @Suppress("UNCHECKED_CAST") clazz: Class = settingsClass as Class ): T? { val settingsFile = getSettingsFile(session, userId) - var settings: T? = if(settingsFile.exists()) JsonUtil.fromJson(settingsFile.readText(), clazz) else null + var settings: T? = if (settingsFile.exists()) JsonUtil.fromJson(settingsFile.readText(), clazz) else null if (null == settings) { val initSettings = initSettings(session) if (null != initSettings) { settingsFile.writeText(JsonUtil.toJson(initSettings)) } - if(settingsFile.exists()) { + if (settingsFile.exists()) { settings = JsonUtil.fromJson(settingsFile.readText(), clazz) } } diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/application/ApplicationSocketManager.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/application/ApplicationSocketManager.kt index 14f8a898..57678efd 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/application/ApplicationSocketManager.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/application/ApplicationSocketManager.kt @@ -3,8 +3,8 @@ package com.simiacryptus.skyenet.webui.application import com.simiacryptus.jopenai.API import com.simiacryptus.skyenet.core.platform.ApplicationServices import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.StorageInterface -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.StorageInterface +import com.simiacryptus.skyenet.core.platform.model.User import com.simiacryptus.skyenet.webui.chat.ChatSocket import com.simiacryptus.skyenet.webui.session.SocketManagerBase diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/chat/ChatServer.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/chat/ChatServer.kt index 1f087211..e208bd67 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/chat/ChatServer.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/chat/ChatServer.kt @@ -1,10 +1,10 @@ package com.simiacryptus.skyenet.webui.chat import com.simiacryptus.skyenet.core.platform.ApplicationServices.authenticationManager -import com.simiacryptus.skyenet.core.platform.AuthenticationInterface import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.StorageInterface -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.AuthenticationInterface +import com.simiacryptus.skyenet.core.platform.model.StorageInterface +import com.simiacryptus.skyenet.core.platform.model.User import com.simiacryptus.skyenet.webui.servlet.NewSessionServlet import com.simiacryptus.skyenet.webui.session.SocketManager import org.eclipse.jetty.servlet.DefaultServlet diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/chat/ChatSocketManager.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/chat/ChatSocketManager.kt index 5b358411..9f26436a 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/chat/ChatSocketManager.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/chat/ChatSocketManager.kt @@ -1,22 +1,22 @@ package com.simiacryptus.skyenet.webui.chat -import com.simiacryptus.jopenai.models.ApiModel import com.simiacryptus.jopenai.ChatClient -import com.simiacryptus.jopenai.models.ChatModels +import com.simiacryptus.jopenai.models.ApiModel +import com.simiacryptus.jopenai.models.ChatModel import com.simiacryptus.jopenai.util.ClientUtil.toContentList import com.simiacryptus.skyenet.Retryable import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.StorageInterface +import com.simiacryptus.skyenet.core.platform.model.StorageInterface +import com.simiacryptus.skyenet.util.MarkdownUtil import com.simiacryptus.skyenet.webui.application.ApplicationInterface import com.simiacryptus.skyenet.webui.application.ApplicationServer import com.simiacryptus.skyenet.webui.session.SessionTask import com.simiacryptus.skyenet.webui.session.SocketManagerBase -import com.simiacryptus.skyenet.util.MarkdownUtil import java.util.* open class ChatSocketManager( session: Session, - val model: ChatModels, + val model: ChatModel, val userInterfacePrompt: String, open val initialAssistantPrompt: String = "", open val systemPrompt: String, diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/ApiKeyServlet.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/ApiKeyServlet.kt index 423fdd3f..b205dfbc 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/ApiKeyServlet.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/ApiKeyServlet.kt @@ -1,14 +1,14 @@ package com.simiacryptus.skyenet.webui.servlet -import com.simiacryptus.jopenai.models.ApiModel import com.simiacryptus.jopenai.models.APIProvider +import com.simiacryptus.jopenai.models.ApiModel import com.simiacryptus.jopenai.models.OpenAIModel -import com.simiacryptus.util.JsonUtil import com.simiacryptus.skyenet.core.platform.ApplicationServices import com.simiacryptus.skyenet.core.platform.ApplicationServices.userSettingsManager -import com.simiacryptus.skyenet.core.platform.ApplicationServicesConfig.dataStorageRoot -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.ApplicationServicesConfig.dataStorageRoot +import com.simiacryptus.skyenet.core.platform.model.User import com.simiacryptus.skyenet.webui.application.ApplicationServer.Companion.getCookie +import com.simiacryptus.util.JsonUtil import jakarta.servlet.http.HttpServlet import jakarta.servlet.http.HttpServletRequest import jakarta.servlet.http.HttpServletResponse @@ -118,7 +118,7 @@ class ApiKeyServlet : HttpServlet() { ) resp.sendRedirect("/") // Redirect to a success page or another relevant page } - } else if (record != null && budget != null && user != null) { // Ensure user is not null before proceeding + } else if (record != null && budget != null && user == null) { // Ensure user is not null before proceeding apiKeyRecords.remove(record) apiKeyRecords.add( record.copy( diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/CancelThreadsServlet.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/CancelThreadsServlet.kt index 648342e5..b7f48b4d 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/CancelThreadsServlet.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/CancelThreadsServlet.kt @@ -3,9 +3,9 @@ package com.simiacryptus.skyenet.webui.servlet import com.simiacryptus.skyenet.core.platform.ApplicationServices import com.simiacryptus.skyenet.core.platform.ApplicationServices.authenticationManager import com.simiacryptus.skyenet.core.platform.ApplicationServices.clientManager -import com.simiacryptus.skyenet.core.platform.AuthorizationInterface import com.simiacryptus.skyenet.core.platform.ClientManager.RecordingThreadFactory import com.simiacryptus.skyenet.core.platform.Session +import com.simiacryptus.skyenet.core.platform.model.AuthorizationInterface import com.simiacryptus.skyenet.webui.application.ApplicationServer import com.simiacryptus.skyenet.webui.application.ApplicationServer.Companion.getCookie import jakarta.servlet.http.HttpServlet diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/DeleteSessionServlet.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/DeleteSessionServlet.kt index 54d143eb..5a2e3d78 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/DeleteSessionServlet.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/DeleteSessionServlet.kt @@ -1,10 +1,9 @@ package com.simiacryptus.skyenet.webui.servlet -import com.simiacryptus.util.JsonUtil import com.simiacryptus.skyenet.core.platform.ApplicationServices import com.simiacryptus.skyenet.core.platform.ApplicationServices.authorizationManager -import com.simiacryptus.skyenet.core.platform.AuthorizationInterface.OperationType import com.simiacryptus.skyenet.core.platform.Session +import com.simiacryptus.skyenet.core.platform.model.AuthorizationInterface.OperationType import com.simiacryptus.skyenet.webui.application.ApplicationServer import com.simiacryptus.skyenet.webui.application.ApplicationServer.Companion.getCookie import jakarta.servlet.http.HttpServlet diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/FileServlet.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/FileServlet.kt index 47d6324f..ca9e441a 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/FileServlet.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/FileServlet.kt @@ -4,11 +4,11 @@ import com.google.common.cache.CacheBuilder import com.google.common.cache.CacheLoader import com.google.common.cache.LoadingCache import com.google.common.cache.RemovalListener -import com.simiacryptus.skyenet.webui.application.ApplicationServer import jakarta.servlet.WriteListener import jakarta.servlet.http.HttpServlet import jakarta.servlet.http.HttpServletRequest import jakarta.servlet.http.HttpServletResponse +import org.eclipse.jetty.http.MimeTypes import org.slf4j.LoggerFactory import java.io.File import java.nio.ByteBuffer @@ -19,8 +19,8 @@ import java.nio.file.StandardOpenOption abstract class FileServlet : HttpServlet() { abstract fun getDir( - req: HttpServletRequest, - ) : File + req: HttpServletRequest, + ): File override fun doGet(req: HttpServletRequest, resp: HttpServletResponse) { log.info("Received GET request for path: ${req.pathInfo ?: req.servletPath}") @@ -97,7 +97,7 @@ abstract class FileServlet : HttpServlet() { private fun writeSmall(channel: FileChannel, resp: HttpServletResponse, file: File, req: HttpServletRequest) { log.info("Writing small file: ${file.absolutePath}") - resp.contentType = ApplicationServer.getMimeType(file.name) + resp.contentType = getMimeType(file.name) resp.status = HttpServletResponse.SC_OK val async = req.startAsync() resp.outputStream.apply { @@ -134,7 +134,7 @@ abstract class FileServlet : HttpServlet() { ) { log.info("Writing large file: ${file.absolutePath}") val mappedByteBuffer: MappedByteBuffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()) - resp.contentType = ApplicationServer.getMimeType(file.name) + resp.contentType = getMimeType(file.name) resp.status = HttpServletResponse.SC_OK val async = req.startAsync() resp.outputStream.apply { @@ -165,10 +165,19 @@ abstract class FileServlet : HttpServlet() { } } + private fun getMimeType(fileName: String): String { + return when { + fileName.endsWith(".js") -> "application/javascript" + fileName.endsWith(".mjs") -> "application/javascript" + else -> MimeTypes.getDefaultMimeByExtension(fileName) ?: "application/octet-stream" + } + } + + open fun getZipLink( req: HttpServletRequest, filePath: String - ) : String = "" + ): String = "" private fun directoryHTML(zipLink: String, folders: String, files: String) = """ | @@ -232,7 +241,7 @@ abstract class FileServlet : HttpServlet() { | | |

Archive

- |${if(zipLink.isNullOrBlank()) "" else """ZIP"""} + |${if (zipLink.isNullOrBlank()) "" else """ZIP"""} |

Folders

|
|$folders diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/NewSessionServlet.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/NewSessionServlet.kt index b522a1a5..10b0f171 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/NewSessionServlet.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/NewSessionServlet.kt @@ -1,13 +1,13 @@ package com.simiacryptus.skyenet.webui.servlet -import com.simiacryptus.skyenet.core.platform.StorageInterface +import com.simiacryptus.skyenet.core.platform.Session import jakarta.servlet.http.HttpServlet import jakarta.servlet.http.HttpServletRequest import jakarta.servlet.http.HttpServletResponse class NewSessionServlet : HttpServlet() { override fun doGet(req: HttpServletRequest, resp: HttpServletResponse) { - val sessionId = StorageInterface.newGlobalID() + val sessionId = Session.newGlobalID() resp.contentType = "text/plain" resp.status = HttpServletResponse.SC_OK resp.writer.write(sessionId.toString()) diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/OAuthGoogle.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/OAuthGoogle.kt index 6dd8f790..3d760e96 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/OAuthGoogle.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/OAuthGoogle.kt @@ -7,8 +7,8 @@ import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport import com.google.api.client.json.gson.GsonFactory import com.google.api.services.oauth2.Oauth2 import com.simiacryptus.skyenet.core.platform.ApplicationServices -import com.simiacryptus.skyenet.core.platform.AuthenticationInterface -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.AuthenticationInterface +import com.simiacryptus.skyenet.core.platform.model.User import jakarta.servlet.DispatcherType import jakarta.servlet.http.Cookie import jakarta.servlet.http.HttpServlet diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/ProxyHttpServlet.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/ProxyHttpServlet.kt index 9629499a..4fbbe6a1 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/ProxyHttpServlet.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/ProxyHttpServlet.kt @@ -1,7 +1,7 @@ package com.simiacryptus.skyenet.webui.servlet -import com.simiacryptus.util.JsonUtil import com.simiacryptus.skyenet.core.platform.ApplicationServices +import com.simiacryptus.util.JsonUtil import jakarta.servlet.http.HttpServlet import jakarta.servlet.http.HttpServletRequest import jakarta.servlet.http.HttpServletResponse diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/SessionFileServlet.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/SessionFileServlet.kt index 20d04119..baf29b78 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/SessionFileServlet.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/SessionFileServlet.kt @@ -2,7 +2,7 @@ package com.simiacryptus.skyenet.webui.servlet import com.simiacryptus.skyenet.core.platform.ApplicationServices import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.StorageInterface +import com.simiacryptus.skyenet.core.platform.model.StorageInterface import com.simiacryptus.skyenet.webui.application.ApplicationServer.Companion.getCookie import jakarta.servlet.http.HttpServletRequest import java.io.File diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/SessionListServlet.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/SessionListServlet.kt index 9b0550fe..e0225423 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/SessionListServlet.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/SessionListServlet.kt @@ -2,7 +2,7 @@ package com.simiacryptus.skyenet.webui.servlet import com.simiacryptus.skyenet.core.actors.CodingActor.Companion.indent import com.simiacryptus.skyenet.core.platform.ApplicationServices.authenticationManager -import com.simiacryptus.skyenet.core.platform.StorageInterface +import com.simiacryptus.skyenet.core.platform.model.StorageInterface import com.simiacryptus.skyenet.webui.application.ApplicationServer import com.simiacryptus.skyenet.webui.application.ApplicationServer.Companion.getCookie import jakarta.servlet.http.HttpServlet diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/SessionSettingsServlet.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/SessionSettingsServlet.kt index 104b6f6b..7ca3cfdf 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/SessionSettingsServlet.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/SessionSettingsServlet.kt @@ -1,10 +1,10 @@ package com.simiacryptus.skyenet.webui.servlet -import com.simiacryptus.util.JsonUtil import com.simiacryptus.skyenet.core.platform.ApplicationServices.authenticationManager import com.simiacryptus.skyenet.core.platform.Session import com.simiacryptus.skyenet.webui.application.ApplicationServer import com.simiacryptus.skyenet.webui.application.ApplicationServer.Companion.getCookie +import com.simiacryptus.util.JsonUtil import jakarta.servlet.http.HttpServlet import jakarta.servlet.http.HttpServletRequest import jakarta.servlet.http.HttpServletResponse diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/SessionShareServlet.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/SessionShareServlet.kt index 953cc5e3..b2eb2fb5 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/SessionShareServlet.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/SessionShareServlet.kt @@ -1,32 +1,31 @@ package com.simiacryptus.skyenet.webui.servlet -import com.simiacryptus.util.JsonUtil +import com.google.zxing.BarcodeFormat +import com.google.zxing.client.j2se.MatrixToImageWriter +import com.google.zxing.qrcode.QRCodeWriter import com.simiacryptus.skyenet.core.platform.ApplicationServices import com.simiacryptus.skyenet.core.platform.ApplicationServices.authenticationManager import com.simiacryptus.skyenet.core.platform.ApplicationServices.authorizationManager import com.simiacryptus.skyenet.core.platform.ApplicationServices.cloud -import com.simiacryptus.skyenet.core.platform.ApplicationServicesConfig.dataStorageRoot -import com.simiacryptus.skyenet.core.platform.AuthorizationInterface.OperationType -import com.simiacryptus.skyenet.core.platform.StorageInterface -import com.simiacryptus.skyenet.core.platform.StorageInterface.Companion.long64 -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.Session +import com.simiacryptus.skyenet.core.platform.model.ApplicationServicesConfig.dataStorageRoot +import com.simiacryptus.skyenet.core.platform.model.AuthorizationInterface.OperationType +import com.simiacryptus.skyenet.core.platform.model.User import com.simiacryptus.skyenet.core.util.Selenium +import com.simiacryptus.skyenet.util.Selenium2S3 import com.simiacryptus.skyenet.webui.application.ApplicationServer import com.simiacryptus.skyenet.webui.application.ApplicationServer.Companion.getCookie -import com.simiacryptus.skyenet.util.Selenium2S3 +import com.simiacryptus.util.JsonUtil import jakarta.servlet.http.HttpServlet import jakarta.servlet.http.HttpServletRequest import jakarta.servlet.http.HttpServletResponse import org.apache.http.client.HttpClient import org.apache.http.impl.client.HttpClients +import java.io.ByteArrayOutputStream import java.net.URI +import java.util.Base64 import kotlin.reflect.jvm.javaType import kotlin.reflect.typeOf -import com.google.zxing.BarcodeFormat -import com.google.zxing.qrcode.QRCodeWriter -import com.google.zxing.client.j2se.MatrixToImageWriter -import java.io.ByteArrayOutputStream -import java.util.Base64 class SessionShareServlet( private val server: ApplicationServer, @@ -61,7 +60,7 @@ class SessionShareServlet( require(acceptHost(user, host)) { "Invalid url: $url" } val storageInterface = ApplicationServices.dataStorageFactory(dataStorageRoot) - val session = StorageInterface.parseSessionID(sessionID) + val session = Session.parseSessionID(sessionID) val pool = ApplicationServices.clientManager.getPool(session, user) val infoFile = storageInterface.getDataDir(user, session).resolve("info.json").apply { parentFile.mkdirs() } val json = if (infoFile.exists()) JsonUtil.fromJson>( @@ -70,7 +69,7 @@ class SessionShareServlet( ) else mapOf() val sessionSettings = (json as? Map)?.toMutableMap() ?: mutableMapOf() val previousShare = sessionSettings["shareId"] - var shareURL = url(appName, previousShare ?: long64()) + var shareURL = url(appName, previousShare ?: Session.long64()) var qrCodeDataURL = generateQRCodeDataURL(shareURL) when { null != previousShare && validateUrl(shareURL) -> { @@ -106,7 +105,7 @@ class SessionShareServlet( } else -> { - val shareId = long64() + val shareId = Session.long64() currentlyProcessing.add(shareId) pool.submit { try { diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/UserInfoServlet.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/UserInfoServlet.kt index f9d120ad..4fd55513 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/UserInfoServlet.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/UserInfoServlet.kt @@ -1,9 +1,9 @@ package com.simiacryptus.skyenet.webui.servlet -import com.simiacryptus.util.JsonUtil import com.simiacryptus.skyenet.core.platform.ApplicationServices -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.User import com.simiacryptus.skyenet.webui.application.ApplicationServer.Companion.getCookie +import com.simiacryptus.util.JsonUtil import jakarta.servlet.http.HttpServlet import jakarta.servlet.http.HttpServletRequest import jakarta.servlet.http.HttpServletResponse diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/UserSettingsServlet.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/UserSettingsServlet.kt index 34373d0e..d3c33a51 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/UserSettingsServlet.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/UserSettingsServlet.kt @@ -1,11 +1,10 @@ package com.simiacryptus.skyenet.webui.servlet import com.simiacryptus.jopenai.models.APIProvider -import com.simiacryptus.jopenai.models.ChatModels -import com.simiacryptus.util.JsonUtil import com.simiacryptus.skyenet.core.platform.ApplicationServices -import com.simiacryptus.skyenet.core.platform.UserSettingsInterface.UserSettings +import com.simiacryptus.skyenet.core.platform.model.UserSettingsInterface.UserSettings import com.simiacryptus.skyenet.webui.application.ApplicationServer.Companion.getCookie +import com.simiacryptus.util.JsonUtil import jakarta.servlet.http.HttpServlet import jakarta.servlet.http.HttpServletRequest import jakarta.servlet.http.HttpServletResponse @@ -60,7 +59,8 @@ class UserSettingsServlet : HttpServlet() { } catch (e: Exception) { resp.status = HttpServletResponse.SC_INTERNAL_SERVER_ERROR // HTML error page - resp.writer.write(""" + resp.writer.write( + """ | | | Error @@ -71,7 +71,8 @@ class UserSettingsServlet : HttpServlet() { |
${e.message}
| | - """.trimIndent()) + """.trimIndent() + ) resp } } diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/WelcomeServlet.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/WelcomeServlet.kt index abbefee1..8311818b 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/WelcomeServlet.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/WelcomeServlet.kt @@ -4,12 +4,13 @@ import com.fasterxml.jackson.databind.SerializationFeature import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.simiacryptus.skyenet.core.platform.ApplicationServices import com.simiacryptus.skyenet.core.platform.ApplicationServices.authorizationManager -import com.simiacryptus.skyenet.core.platform.AuthorizationInterface.OperationType +import com.simiacryptus.skyenet.core.platform.model.AuthorizationInterface.OperationType import com.simiacryptus.skyenet.webui.application.ApplicationDirectory import com.simiacryptus.skyenet.webui.application.ApplicationServer.Companion.getCookie import jakarta.servlet.http.HttpServlet import jakarta.servlet.http.HttpServletRequest import jakarta.servlet.http.HttpServletResponse +import org.eclipse.jetty.http.MimeTypes import org.intellij.lang.annotations.Language import org.slf4j.LoggerFactory import java.nio.file.NoSuchFileException @@ -86,8 +87,11 @@ open class WelcomeServlet(private val parent: ApplicationDirectory) : } else -> try { + resp ?: throw IllegalStateException("Response is null") + resp.contentType = MimeTypes.getDefaultMimeByExtension(requestURI.split("/").last()) + log.info("Serving resource: $requestURI as ${resp.contentType}") val inputStream = parent.welcomeResources.addPath(requestURI)?.inputStream - inputStream?.copyTo(resp?.outputStream!!) + inputStream?.copyTo(resp.outputStream!!) } catch (e: NoSuchFileException) { resp?.sendError(404) } diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/ZipServlet.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/ZipServlet.kt index 812807ca..72a1b7d5 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/ZipServlet.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/servlet/ZipServlet.kt @@ -2,7 +2,7 @@ package com.simiacryptus.skyenet.webui.servlet import com.simiacryptus.skyenet.core.platform.ApplicationServices import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.StorageInterface +import com.simiacryptus.skyenet.core.platform.model.StorageInterface import com.simiacryptus.skyenet.webui.application.ApplicationServer.Companion.getCookie import jakarta.servlet.http.HttpServlet import jakarta.servlet.http.HttpServletRequest diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/session/SessionTask.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/session/SessionTask.kt index b9851bda..3e8bfe17 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/session/SessionTask.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/session/SessionTask.kt @@ -3,9 +3,9 @@ package com.simiacryptus.skyenet.webui.session import com.simiacryptus.jopenai.describe.Description import com.simiacryptus.jopenai.proxy.ValidatedObject import com.simiacryptus.skyenet.core.actors.CodingActor -import com.simiacryptus.skyenet.core.platform.StorageInterface.Companion.long64 -import com.simiacryptus.skyenet.webui.application.ApplicationInterface +import com.simiacryptus.skyenet.core.platform.Session import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown +import com.simiacryptus.skyenet.webui.application.ApplicationInterface import org.slf4j.LoggerFactory import java.awt.image.BufferedImage import java.io.File @@ -187,7 +187,7 @@ abstract class SessionTask( fun image( @Description("The image to display") image: BufferedImage - ) = add("""""") + ) = add("""""") companion object { val log = LoggerFactory.getLogger(SessionTask::class.java) diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/session/SocketManagerBase.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/session/SocketManagerBase.kt index 0070719c..0ca22e58 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/session/SocketManagerBase.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/session/SocketManagerBase.kt @@ -2,9 +2,12 @@ package com.simiacryptus.skyenet.webui.session import com.simiacryptus.skyenet.core.platform.* import com.simiacryptus.skyenet.core.platform.ApplicationServices.clientManager -import com.simiacryptus.skyenet.core.platform.AuthorizationInterface.OperationType -import com.simiacryptus.skyenet.webui.chat.ChatSocket +import com.simiacryptus.skyenet.core.platform.model.AuthenticationInterface +import com.simiacryptus.skyenet.core.platform.model.AuthorizationInterface.OperationType +import com.simiacryptus.skyenet.core.platform.model.StorageInterface +import com.simiacryptus.skyenet.core.platform.model.User import com.simiacryptus.skyenet.util.MarkdownUtil +import com.simiacryptus.skyenet.webui.chat.ChatSocket import org.slf4j.LoggerFactory import java.io.File import java.net.URLDecoder diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/test/CodingActorTestApp.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/test/CodingActorTestApp.kt index 13b2efe3..4e0f9d64 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/test/CodingActorTestApp.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/test/CodingActorTestApp.kt @@ -1,18 +1,16 @@ package com.simiacryptus.skyenet.webui.test import com.simiacryptus.jopenai.API -import com.simiacryptus.jopenai.models.ApiModel import com.simiacryptus.jopenai.ChatClient +import com.simiacryptus.jopenai.models.ApiModel import com.simiacryptus.skyenet.core.actors.CodingActor -import com.simiacryptus.skyenet.core.actors.CodingActor.Companion.indent import com.simiacryptus.skyenet.core.platform.ApplicationServices -import com.simiacryptus.skyenet.core.platform.AuthorizationInterface.OperationType -import com.simiacryptus.skyenet.core.platform.ClientManager import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.AuthorizationInterface.OperationType +import com.simiacryptus.skyenet.core.platform.model.User +import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown import com.simiacryptus.skyenet.webui.application.ApplicationInterface import com.simiacryptus.skyenet.webui.application.ApplicationServer -import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown import org.slf4j.LoggerFactory import java.util.* diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/test/FilePatchTestApp.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/test/FilePatchTestApp.kt index 47bc4954..a827579c 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/test/FilePatchTestApp.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/test/FilePatchTestApp.kt @@ -2,24 +2,15 @@ package com.simiacryptus.skyenet.webui.test import com.simiacryptus.diff.addApplyFileDiffLinks import com.simiacryptus.jopenai.API -import com.simiacryptus.jopenai.models.ApiModel import com.simiacryptus.jopenai.OpenAIClient -import com.simiacryptus.skyenet.core.actors.CodingActor -import com.simiacryptus.skyenet.core.actors.CodingActor.Companion.indent -import com.simiacryptus.skyenet.core.platform.ApplicationServices -import com.simiacryptus.skyenet.core.platform.AuthorizationInterface.OperationType -import com.simiacryptus.skyenet.core.platform.ClientManager import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.User -import com.simiacryptus.skyenet.webui.application.ApplicationInterface +import com.simiacryptus.skyenet.core.platform.model.User +import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown import com.simiacryptus.skyenet.webui.application.ApplicationServer import com.simiacryptus.skyenet.webui.application.ApplicationSocketManager import com.simiacryptus.skyenet.webui.session.SocketManager -import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown import org.slf4j.LoggerFactory -import java.awt.Desktop import java.nio.file.Files -import java.util.* open class FilePatchTestApp( applicationName: String = "FilePatchTestApp", diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/test/ImageActorTestApp.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/test/ImageActorTestApp.kt index f306835f..09a6e5bd 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/test/ImageActorTestApp.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/test/ImageActorTestApp.kt @@ -3,12 +3,11 @@ package com.simiacryptus.skyenet.webui.test import com.simiacryptus.jopenai.API import com.simiacryptus.jopenai.ChatClient import com.simiacryptus.skyenet.core.actors.ImageActor -import com.simiacryptus.skyenet.core.platform.ClientManager import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.User +import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown import com.simiacryptus.skyenet.webui.application.ApplicationInterface import com.simiacryptus.skyenet.webui.application.ApplicationServer -import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown import org.slf4j.LoggerFactory open class ImageActorTestApp( @@ -25,6 +24,7 @@ open class ImageActorTestApp( ) override val settingsClass: Class<*> get() = Settings::class.java + @Suppress("UNCHECKED_CAST") override fun initSettings(session: Session): T? = Settings(actor = actor) as T diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/test/ParsedActorTestApp.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/test/ParsedActorTestApp.kt index e39a15ea..3f6d990e 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/test/ParsedActorTestApp.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/test/ParsedActorTestApp.kt @@ -2,14 +2,13 @@ package com.simiacryptus.skyenet.webui.test import com.simiacryptus.jopenai.API import com.simiacryptus.jopenai.ChatClient -import com.simiacryptus.util.JsonUtil import com.simiacryptus.skyenet.core.actors.ParsedActor -import com.simiacryptus.skyenet.core.platform.ClientManager import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.User +import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown import com.simiacryptus.skyenet.webui.application.ApplicationInterface import com.simiacryptus.skyenet.webui.application.ApplicationServer -import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown +import com.simiacryptus.util.JsonUtil import org.slf4j.LoggerFactory open class ParsedActorTestApp( diff --git a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/test/SimpleActorTestApp.kt b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/test/SimpleActorTestApp.kt index af95ece3..9800f242 100644 --- a/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/test/SimpleActorTestApp.kt +++ b/webui/src/main/kotlin/com/simiacryptus/skyenet/webui/test/SimpleActorTestApp.kt @@ -3,12 +3,11 @@ package com.simiacryptus.skyenet.webui.test import com.simiacryptus.jopenai.API import com.simiacryptus.jopenai.ChatClient import com.simiacryptus.skyenet.core.actors.SimpleActor -import com.simiacryptus.skyenet.core.platform.ClientManager import com.simiacryptus.skyenet.core.platform.Session -import com.simiacryptus.skyenet.core.platform.User +import com.simiacryptus.skyenet.core.platform.model.User +import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown import com.simiacryptus.skyenet.webui.application.ApplicationInterface import com.simiacryptus.skyenet.webui.application.ApplicationServer -import com.simiacryptus.skyenet.util.MarkdownUtil.renderMarkdown import org.slf4j.LoggerFactory open class SimpleActorTestApp( @@ -25,6 +24,7 @@ open class SimpleActorTestApp( ) override val settingsClass: Class<*> get() = Settings::class.java + @Suppress("UNCHECKED_CAST") override fun initSettings(session: Session): T? = Settings(actor = actor) as T diff --git a/webui/src/main/resources/application/index.html b/webui/src/main/resources/application/index.html index f67282f2..c162accd 100644 --- a/webui/src/main/resources/application/index.html +++ b/webui/src/main/resources/application/index.html @@ -1,118 +1,118 @@ - WebSocket Client - - - - - - - - - - - - - - - - - + WebSocket Client + + + + + + + + + + + + + + + + +
- - - - - - - - + + + + + + + + mermaid.initialize({startOnLoad: true}); + window.mermaid = mermaid; // Make mermaid globally accessible + -
-
- Home - - - - + -
- +
+ +
-
- - -
-
+
+ + +
+
diff --git a/webui/src/main/resources/shared/_main.scss b/webui/src/main/resources/shared/_main.scss index 52aab999..7470f955 100644 --- a/webui/src/main/resources/shared/_main.scss +++ b/webui/src/main/resources/shared/_main.scss @@ -101,19 +101,6 @@ body { border: none; border-radius: $border-radius; cursor: pointer; - transition: background-color 0.3s ease, transform 0.2s ease, box-shadow 0.3s ease, color 0.3s ease; - font-weight: $font-weight-bold; - - &:hover { - background-color: darken($button-bg-color, 10%); - transform: translateY(-2px); - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); - color: lighten($button-text-color, 10%); - } - - &:active { - transform: translateY(0); - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); transition: background-color 0.3s ease, transform 0.2s ease, box-shadow 0.3s ease, color 0.3s ease; font-weight: $font-weight-bold; @@ -127,18 +114,32 @@ body { &:active { transform: translateY(0); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); - } + transition: background-color 0.3s ease, transform 0.2s ease, box-shadow 0.3s ease, color 0.3s ease; + font-weight: $font-weight-bold; - &:disabled { - opacity: 0.6; - cursor: not-allowed; - box-shadow: none; - } + &:hover { + background-color: darken($button-bg-color, 10%); + transform: translateY(-2px); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + color: lighten($button-text-color, 10%); + } + + &:active { + transform: translateY(0); + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + } + + &:disabled { + opacity: 0.6; + cursor: not-allowed; + box-shadow: none; + } + + &:focus { + outline: 2px solid $link-color; + outline-offset: 2px; + } - &:focus { - outline: 2px solid $link-color; - outline-offset: 2px; - } box-shadow: none; } @@ -157,6 +158,7 @@ body { border-radius: $border-radius; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); transition: box-shadow 0.3s ease, background-color 0.3s ease; + &:hover { box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); } @@ -186,12 +188,12 @@ pre { text-decoration: none; color: $link-color; @include link-hover-transition; - + &:focus { outline: 2px solid $link-color; outline-offset: 2px; } - + &:focus { outline: 2px solid $link-color; outline-offset: 2px; @@ -583,6 +585,7 @@ pre.response-message { } margin-bottom: 5px; + &:focus { outline: 2px solid $link-color; outline-offset: 2px; diff --git a/webui/src/main/resources/welcome/favicon.svg b/webui/src/main/resources/welcome/favicon.svg index 1777362f..06534d85 100644 --- a/webui/src/main/resources/welcome/favicon.svg +++ b/webui/src/main/resources/welcome/favicon.svg @@ -1,7 +1,7 @@ - + - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + - - - - - - + + - - - - + + + - - - + + - - - - - - - + + + + + + - - - - - - + + + + - - - - - - - - - - - - + - - - - - - - - - - + + + + + + + - - - - - - + + + + + - - - - - + + - - - - - + - - diff --git a/webui/src/main/resources/welcome/index.html b/webui/src/main/resources/welcome/index.html index a5c836c9..e0787c1b 100644 --- a/webui/src/main/resources/welcome/index.html +++ b/webui/src/main/resources/welcome/index.html @@ -1,7 +1,7 @@ - +

If you are not redirected, click here.

diff --git a/webui/src/main/resources/welcome/tabs.js b/webui/src/main/resources/welcome/tabs.js index b3c7d079..b826c1d5 100644 --- a/webui/src/main/resources/welcome/tabs.js +++ b/webui/src/main/resources/welcome/tabs.js @@ -1,7 +1,7 @@ function updateTabs() { document.querySelectorAll('.tab-button').forEach(button => { // console.log(`Adding click event listener to tab button: ${button.getAttribute('data-for-tab')}`); - button.addEventListener('click', (event) => { + button.addEventListener('click', (event) => { // console.log(`Tab button clicked: ${button.getAttribute('data-for-tab')}`); event.stopPropagation(); const forTab = button.getAttribute('data-for-tab'); diff --git a/webui/src/main/resources/welcome/welcome.html b/webui/src/main/resources/welcome/welcome.html index 70bdbc93..e645c937 100644 --- a/webui/src/main/resources/welcome/welcome.html +++ b/webui/src/main/resources/welcome/welcome.html @@ -1,81 +1,81 @@ - - - SimiaCryptus Skyenet Apps - - - - - - - - - + + + SimiaCryptus Skyenet Apps + + + + + + + + + -