├── chatbot-openai-code-migration-app └── src │ ├── main │ ├── resources │ │ ├── neo4j │ │ │ └── migrations │ │ │ │ ├── V1_0__Init.cypher │ │ │ │ ├── V3_0__index_textnode.cypher │ │ │ │ └── V2_0__index_filenode_astnode.cypher │ │ ├── application-local.example.properties │ │ ├── application-vertex.example.properties │ │ ├── logback-spring.xml │ │ ├── application.properties │ │ ├── application-azure.example.properties │ │ ├── application-bedrock.example.properties │ │ └── application-openai.example.properties │ └── java │ │ └── com │ │ └── telekom │ │ └── ai4coding │ │ └── chatbot │ │ ├── configuration │ │ ├── properties │ │ │ ├── LocalChatbotProperties.java │ │ │ ├── OpenaiCompletionsProperties.java │ │ │ ├── VertexProperties.java │ │ │ ├── AwsProperties.java │ │ │ ├── OpenaiProperties.java │ │ │ ├── AzureProperties.java │ │ │ └── AcaProperties.java │ │ ├── agent │ │ │ ├── OpenAiAgent.java │ │ │ ├── CodeContextVerifyAgent.java │ │ │ ├── HypotheticalDocumentGenerator.java │ │ │ └── GeneralAgent.java │ │ ├── OpenAiConfig.java │ │ ├── JacksonConfig.java │ │ ├── GitlabConfig.java │ │ └── GraphDbConfig.java │ │ ├── template │ │ └── cypher │ │ │ ├── Neo4JDatabaseCleanupTemplates.java │ │ │ └── StateMachineRetrievalCypherTemplates.java │ │ ├── utils │ │ ├── TokenCalculation.java │ │ ├── EmojiRegex.java │ │ ├── DoubleFormatter.java │ │ └── TitleGenerator.java │ │ ├── ChatbotCodeMigrationApplication.java │ │ ├── repository │ │ ├── ASTNodeRepository.java │ │ ├── FileNodeRepository.java │ │ ├── ConversationNodeRepository.java │ │ └── conversation │ │ │ ├── ToolExecutionRequestConverter.java │ │ │ ├── ToolExecutionResultMessageConverter.java │ │ │ └── ConversationNode.java │ │ ├── controller │ │ ├── openai │ │ │ ├── Neo4JDatabaseController.java │ │ │ ├── FilesController.java │ │ │ └── ChatCompletionsController.java │ │ ├── RepositoriesController.java │ │ └── ConversationController.java │ │ ├── service │ │ └── Neo4JDatabaseService.java │ │ ├── treesitter │ │ └── FileType.java │ │ ├── graph │ │ ├── TextNode.java │ │ └── ASTNode.java │ │ └── mapper │ │ └── ChatRequestMapper.java │ └── test │ ├── java │ └── com │ │ └── telekom │ │ └── ai4coding │ │ └── chatbot │ │ ├── ChatbotCodeMigrationApplicationTests.java │ │ ├── utils │ │ ├── TokenCalculationTest.java │ │ ├── TitleGeneratorTest.java │ │ ├── EmojiRegexTest.java │ │ └── FillingVesselAlgorithmTest.java │ │ ├── BaseIntegrationTest.java │ │ ├── repository │ │ └── conversation │ │ │ ├── ToolExecutionRequestConverterTest.java │ │ │ └── ToolExecutionResultMessageConverterTest.java │ │ ├── graph │ │ ├── KnowledgeGraphBatchInsertServiceTest.java │ │ ├── TextNodeTest.java │ │ ├── KnowledgeGraphTest.java │ │ └── ASTNodeTest.java │ │ ├── controller │ │ └── openai │ │ │ └── Neo4JDatabaseControllerIntegrationTest.java │ │ ├── service │ │ └── Neo4JDatabaseServiceIntegrationTest.java │ │ ├── mapper │ │ └── ChatMapperTest.java │ │ └── treesitter │ │ └── FileTypeTest.java │ └── resources │ └── application-test.properties ├── openai-api ├── bruno_collection │ └── OpenAI API │ │ ├── environments │ │ ├── local.bru │ │ └── lm_studio.bru │ │ ├── bruno.json │ │ ├── Conversations │ │ ├── Get all conversations.bru │ │ ├── Get conversation by id.bru │ │ ├── Delete conversation by id.bru │ │ ├── Get messages by conversation id.bru │ │ └── Rename conversation title by id.bru │ │ ├── Files │ │ ├── List Files.bru │ │ ├── Delete File.bru │ │ └── UPLOAD FILE.bru │ │ ├── Repository │ │ ├── Upload Local Repository.bru │ │ ├── Refresh Local Repository.bru │ │ ├── Upload Gitlab Repository.bru │ │ └── Refresh Gitlab Repository.bru │ │ └── Chat │ │ ├── OpenAI chat endpoint.bru │ │ └── Conversation Persistence.bru ├── src │ └── main │ │ └── java │ │ └── com │ │ └── telekom │ │ └── ai4coding │ │ └── openai │ │ ├── model │ │ ├── CreateCompletionRequestStop.java │ │ ├── CreateEmbeddingRequestInput.java │ │ ├── RunStepObjectStepDetails.java │ │ ├── AssistantObjectToolsInner.java │ │ ├── CreateCompletionRequestPrompt.java │ │ ├── CreateModerationRequestInput.java │ │ ├── MessageObjectContentInner.java │ │ ├── ChatCompletionRequestMessage.java │ │ ├── CreateChatCompletionRequestStop.java │ │ ├── ChatCompletionToolChoiceOption.java │ │ ├── FineTuningJobHyperparametersNEpochs.java │ │ ├── CreateThreadAndRunRequestToolsInner.java │ │ ├── ChatCompletionRequestMessageContentPart.java │ │ ├── ChatCompletionRequestUserMessageContent.java │ │ ├── CreateChatCompletionRequestFunctionCall.java │ │ ├── MessageContentTextObjectTextAnnotationsInner.java │ │ ├── RunStepDetailsToolCallsObjectToolCallsInner.java │ │ ├── CreateFineTuningJobRequestHyperparametersNEpochs.java │ │ ├── CreateFineTuningJobRequestHyperparametersBatchSize.java │ │ ├── CreateFineTuningJobRequestHyperparametersLearningRateMultiplier.java │ │ ├── RunStepDetailsToolCallsCodeObjectCodeInterpreterOutputsInner.java │ │ ├── ChatCompletionRole.java │ │ ├── CreateImageRequestModel.java │ │ ├── CreateSpeechRequestModel.java │ │ ├── CreateTranscriptionRequestModel.java │ │ ├── CreateImageEditRequestModel.java │ │ ├── CreateFineTuningJobRequestModel.java │ │ ├── CreateChatCompletionRequestModel.java │ │ ├── CreateEmbeddingRequestModel.java │ │ ├── CreateCompletionRequestModel.java │ │ ├── ErrorResponse.java │ │ ├── CreateTranslationResponse.java │ │ ├── CreateModerationRequestModel.java │ │ ├── CreateTranscriptionResponse.java │ │ ├── ChatCompletionNamedToolChoiceFunction.java │ │ ├── CreateAssistantFileRequest.java │ │ ├── MessageContentImageFileObjectImageFile.java │ │ ├── ChatCompletionFunctionCallOption.java │ │ ├── MessageContentTextAnnotationsFilePathObjectFilePath.java │ │ ├── RunStepDetailsToolCallsCodeOutputImageObjectImage.java │ │ ├── RunStepDetailsMessageCreationObjectMessageCreation.java │ │ ├── FineTuningJobHyperparameters.java │ │ ├── ModifyRunRequest.java │ │ ├── ModifyThreadRequest.java │ │ ├── ModifyMessageRequest.java │ │ ├── CreateModerationRequest.java │ │ ├── SubmitToolOutputsRunRequest.java │ │ ├── ImagesResponse.java │ │ ├── AssistantToolsCode.java │ │ ├── AssistantToolsRetrieval.java │ │ └── SubmitToolOutputsRunRequestToolOutputsInner.java │ │ └── completions │ │ └── ApiUtil.java └── pom.xml ├── readme-resources ├── pvlib-1.png ├── pvlib-2.png ├── pvlib-3.png ├── kibana_filters.png ├── release_assets.png ├── bruno_run_request.png ├── knowledge_graph.png ├── aca_overview.drawio.png ├── agentic_rag.drawio.png ├── kibana_filters_edit.png ├── kibana_filters_save.png ├── neo4j_conversation.png ├── bruno_open_collection.png ├── data_model_dichotomy.png ├── repository_ingestion.png ├── bruno_select_environment.png ├── state_machine_RAG.drawio.png ├── coding_assistant_flowchart.png ├── conversation_with_memory.drawio.png └── proprietary_headers_conversation_memory.png ├── logstash.conf ├── .gitignore ├── .run ├── ChatbotCodeMigrationApplication [local].run.xml ├── ChatbotCodeMigrationApplication [openai].run.xml ├── ChatbotCodeMigrationApplication [vertex].run.xml ├── ChatbotCodeMigrationApplication [azure].run.xml └── ChatbotCodeMigrationApplication [bedrock].run.xml ├── pom.xml └── docker-compose.yaml /chatbot-openai-code-migration-app/src/main/resources/neo4j/migrations/V1_0__Init.cypher: -------------------------------------------------------------------------------- 1 | RETURN 'Init Neo4j Migrations'; -------------------------------------------------------------------------------- /openai-api/bruno_collection/OpenAI API/environments/local.bru: -------------------------------------------------------------------------------- 1 | vars { 2 | openai_url: http://localhost:8152 3 | } 4 | -------------------------------------------------------------------------------- /openai-api/bruno_collection/OpenAI API/environments/lm_studio.bru: -------------------------------------------------------------------------------- 1 | vars { 2 | openai_url: http://localhost:1234 3 | } 4 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/resources/application-local.example.properties: -------------------------------------------------------------------------------- 1 | local.endpoint=http://localhost:1234/v1 2 | -------------------------------------------------------------------------------- /readme-resources/pvlib-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/telekom/advanced-coding-assistant-backend/HEAD/readme-resources/pvlib-1.png -------------------------------------------------------------------------------- /readme-resources/pvlib-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/telekom/advanced-coding-assistant-backend/HEAD/readme-resources/pvlib-2.png -------------------------------------------------------------------------------- /readme-resources/pvlib-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/telekom/advanced-coding-assistant-backend/HEAD/readme-resources/pvlib-3.png -------------------------------------------------------------------------------- /readme-resources/kibana_filters.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/telekom/advanced-coding-assistant-backend/HEAD/readme-resources/kibana_filters.png -------------------------------------------------------------------------------- /readme-resources/release_assets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/telekom/advanced-coding-assistant-backend/HEAD/readme-resources/release_assets.png -------------------------------------------------------------------------------- /readme-resources/bruno_run_request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/telekom/advanced-coding-assistant-backend/HEAD/readme-resources/bruno_run_request.png -------------------------------------------------------------------------------- /readme-resources/knowledge_graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/telekom/advanced-coding-assistant-backend/HEAD/readme-resources/knowledge_graph.png -------------------------------------------------------------------------------- /readme-resources/aca_overview.drawio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/telekom/advanced-coding-assistant-backend/HEAD/readme-resources/aca_overview.drawio.png -------------------------------------------------------------------------------- /readme-resources/agentic_rag.drawio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/telekom/advanced-coding-assistant-backend/HEAD/readme-resources/agentic_rag.drawio.png -------------------------------------------------------------------------------- /readme-resources/kibana_filters_edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/telekom/advanced-coding-assistant-backend/HEAD/readme-resources/kibana_filters_edit.png -------------------------------------------------------------------------------- /readme-resources/kibana_filters_save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/telekom/advanced-coding-assistant-backend/HEAD/readme-resources/kibana_filters_save.png -------------------------------------------------------------------------------- /readme-resources/neo4j_conversation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/telekom/advanced-coding-assistant-backend/HEAD/readme-resources/neo4j_conversation.png -------------------------------------------------------------------------------- /readme-resources/bruno_open_collection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/telekom/advanced-coding-assistant-backend/HEAD/readme-resources/bruno_open_collection.png -------------------------------------------------------------------------------- /readme-resources/data_model_dichotomy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/telekom/advanced-coding-assistant-backend/HEAD/readme-resources/data_model_dichotomy.png -------------------------------------------------------------------------------- /readme-resources/repository_ingestion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/telekom/advanced-coding-assistant-backend/HEAD/readme-resources/repository_ingestion.png -------------------------------------------------------------------------------- /readme-resources/bruno_select_environment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/telekom/advanced-coding-assistant-backend/HEAD/readme-resources/bruno_select_environment.png -------------------------------------------------------------------------------- /readme-resources/state_machine_RAG.drawio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/telekom/advanced-coding-assistant-backend/HEAD/readme-resources/state_machine_RAG.drawio.png -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/resources/neo4j/migrations/V3_0__index_textnode.cypher: -------------------------------------------------------------------------------- 1 | CREATE INDEX text_node_id_index IF NOT EXISTS FOR (n:TextNode) ON (n.id); -------------------------------------------------------------------------------- /readme-resources/coding_assistant_flowchart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/telekom/advanced-coding-assistant-backend/HEAD/readme-resources/coding_assistant_flowchart.png -------------------------------------------------------------------------------- /readme-resources/conversation_with_memory.drawio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/telekom/advanced-coding-assistant-backend/HEAD/readme-resources/conversation_with_memory.drawio.png -------------------------------------------------------------------------------- /readme-resources/proprietary_headers_conversation_memory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/telekom/advanced-coding-assistant-backend/HEAD/readme-resources/proprietary_headers_conversation_memory.png -------------------------------------------------------------------------------- /openai-api/bruno_collection/OpenAI API/bruno.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1", 3 | "name": "OpenAI API", 4 | "type": "collection", 5 | "ignore": [ 6 | "node_modules", 7 | ".git" 8 | ] 9 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/resources/neo4j/migrations/V2_0__index_filenode_astnode.cypher: -------------------------------------------------------------------------------- 1 | CREATE INDEX file_node_id_index IF NOT EXISTS FOR (n:FileNode) ON (n.id); 2 | CREATE INDEX ast_node_id_index IF NOT EXISTS FOR (n:ASTNode) ON (n.id); -------------------------------------------------------------------------------- /openai-api/bruno_collection/OpenAI API/Conversations/Get all conversations.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: Get all conversations 3 | type: http 4 | seq: 2 5 | } 6 | 7 | get { 8 | url: {{openai_url}}/v1/conversations 9 | body: none 10 | auth: none 11 | } 12 | -------------------------------------------------------------------------------- /openai-api/bruno_collection/OpenAI API/Files/List Files.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: List Files 3 | type: http 4 | seq: 3 5 | } 6 | 7 | get { 8 | url: {{openai_url}}/v1/files?purpose=Conversation id 9 | body: none 10 | auth: none 11 | } 12 | 13 | params:query { 14 | purpose: Conversation id 15 | } 16 | -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateCompletionRequestStop.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import jakarta.annotation.Generated; 4 | 5 | 6 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 7 | public interface CreateCompletionRequestStop { 8 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateEmbeddingRequestInput.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import jakarta.annotation.Generated; 4 | 5 | 6 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 7 | public interface CreateEmbeddingRequestInput { 8 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/RunStepObjectStepDetails.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | 4 | import jakarta.annotation.Generated; 5 | 6 | 7 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 8 | public interface RunStepObjectStepDetails { 9 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/test/java/com/telekom/ai4coding/chatbot/ChatbotCodeMigrationApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | class ChatbotCodeMigrationApplicationTests { 6 | 7 | @Test 8 | void contextLoads() { 9 | } 10 | 11 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/AssistantObjectToolsInner.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | 4 | import jakarta.annotation.Generated; 5 | 6 | 7 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 8 | public interface AssistantObjectToolsInner { 9 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateCompletionRequestPrompt.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import jakarta.annotation.Generated; 4 | 5 | 6 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 7 | public interface CreateCompletionRequestPrompt { 8 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateModerationRequestInput.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import jakarta.annotation.Generated; 4 | 5 | 6 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 7 | public interface CreateModerationRequestInput { 8 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/MessageObjectContentInner.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | 4 | import jakarta.annotation.Generated; 5 | 6 | 7 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 8 | public interface MessageObjectContentInner { 9 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/ChatCompletionRequestMessage.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | 4 | import jakarta.annotation.Generated; 5 | 6 | 7 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 8 | public interface ChatCompletionRequestMessage { 9 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateChatCompletionRequestStop.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import jakarta.annotation.Generated; 4 | 5 | 6 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 7 | public interface CreateChatCompletionRequestStop { 8 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/ChatCompletionToolChoiceOption.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | 4 | import jakarta.annotation.Generated; 5 | 6 | 7 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 8 | public interface ChatCompletionToolChoiceOption { 9 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/FineTuningJobHyperparametersNEpochs.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import jakarta.annotation.Generated; 4 | 5 | 6 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 7 | public interface FineTuningJobHyperparametersNEpochs { 8 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateThreadAndRunRequestToolsInner.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | 4 | import jakarta.annotation.Generated; 5 | 6 | 7 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 8 | public interface CreateThreadAndRunRequestToolsInner { 9 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/ChatCompletionRequestMessageContentPart.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | 4 | import jakarta.annotation.Generated; 5 | 6 | 7 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 8 | public interface ChatCompletionRequestMessageContentPart { 9 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/ChatCompletionRequestUserMessageContent.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | 4 | import jakarta.annotation.Generated; 5 | 6 | 7 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 8 | public interface ChatCompletionRequestUserMessageContent { 9 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateChatCompletionRequestFunctionCall.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | 4 | import jakarta.annotation.Generated; 5 | 6 | 7 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 8 | public interface CreateChatCompletionRequestFunctionCall { 9 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/MessageContentTextObjectTextAnnotationsInner.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | 4 | import jakarta.annotation.Generated; 5 | 6 | 7 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 8 | public interface MessageContentTextObjectTextAnnotationsInner { 9 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/RunStepDetailsToolCallsObjectToolCallsInner.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | 4 | import jakarta.annotation.Generated; 5 | 6 | 7 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 8 | public interface RunStepDetailsToolCallsObjectToolCallsInner { 9 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateFineTuningJobRequestHyperparametersNEpochs.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import jakarta.annotation.Generated; 4 | 5 | 6 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 7 | public interface CreateFineTuningJobRequestHyperparametersNEpochs { 8 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateFineTuningJobRequestHyperparametersBatchSize.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import jakarta.annotation.Generated; 4 | 5 | 6 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 7 | public interface CreateFineTuningJobRequestHyperparametersBatchSize { 8 | } -------------------------------------------------------------------------------- /openai-api/bruno_collection/OpenAI API/Files/Delete File.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: Delete File 3 | type: http 4 | seq: 3 5 | } 6 | 7 | delete { 8 | url: {{openai_url}}/v1/files/{{fileId}} 9 | body: multipartForm 10 | auth: none 11 | } 12 | 13 | auth:bearer { 14 | token: {{access_token}} 15 | } 16 | 17 | vars:pre-request { 18 | fileId: File Id 19 | } 20 | -------------------------------------------------------------------------------- /openai-api/bruno_collection/OpenAI API/Conversations/Get conversation by id.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: Get conversation by id 3 | type: http 4 | seq: 1 5 | } 6 | 7 | get { 8 | url: {{openai_url}}/v1/conversations/{{conversationId}} 9 | body: none 10 | auth: none 11 | } 12 | 13 | vars:pre-request { 14 | conversationId: 6ea2254d-8a9f-4547-90c2-6b068dd0369c 15 | } 16 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/configuration/properties/LocalChatbotProperties.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.configuration.properties; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | 5 | @ConfigurationProperties(prefix = "local") 6 | public record LocalChatbotProperties(String endpoint) {} 7 | -------------------------------------------------------------------------------- /openai-api/bruno_collection/OpenAI API/Conversations/Delete conversation by id.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: Delete conversation by id 3 | type: http 4 | seq: 4 5 | } 6 | 7 | delete { 8 | url: {{openai_url}}/v1/conversations/{{conversationId}} 9 | body: none 10 | auth: none 11 | } 12 | 13 | vars:pre-request { 14 | conversationId: 6ea2254d-8a9f-4547-90c2-6b068dd0369c 15 | } 16 | -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateFineTuningJobRequestHyperparametersLearningRateMultiplier.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import jakarta.annotation.Generated; 4 | 5 | 6 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 7 | public interface CreateFineTuningJobRequestHyperparametersLearningRateMultiplier { 8 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/RunStepDetailsToolCallsCodeObjectCodeInterpreterOutputsInner.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | 4 | import jakarta.annotation.Generated; 5 | 6 | 7 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 8 | public interface RunStepDetailsToolCallsCodeObjectCodeInterpreterOutputsInner { 9 | } -------------------------------------------------------------------------------- /openai-api/bruno_collection/OpenAI API/Conversations/Get messages by conversation id.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: Get messages by conversation id 3 | type: http 4 | seq: 3 5 | } 6 | 7 | get { 8 | url: {{openai_url}}/v1/conversations/{{conversationId}}/messages 9 | body: none 10 | auth: none 11 | } 12 | 13 | vars:pre-request { 14 | conversationId: 6ea2254d-8a9f-4547-90c2-6b068dd0369c 15 | } 16 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/template/cypher/Neo4JDatabaseCleanupTemplates.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.template.cypher; 2 | 3 | public class Neo4JDatabaseCleanupTemplates { 4 | private Neo4JDatabaseCleanupTemplates() { 5 | } 6 | 7 | public static final String DATABASE_CLEANUP_CYPHER = 8 | "MATCH (n)" + 9 | "DETACH DELETE n"; 10 | } 11 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/configuration/properties/OpenaiCompletionsProperties.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.configuration.properties; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | 5 | @ConfigurationProperties(prefix = "openai.completions") 6 | public record OpenaiCompletionsProperties(String endpoint, String openaiApiKey, String azureApiKey) { } 7 | -------------------------------------------------------------------------------- /openai-api/bruno_collection/OpenAI API/Conversations/Rename conversation title by id.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: Rename conversation title by id 3 | type: http 4 | seq: 5 5 | } 6 | 7 | patch { 8 | url: {{openai_url}}/v1/conversations/{{conversationId}}/rename?newTitle=New title 9 | body: none 10 | auth: none 11 | } 12 | 13 | params:query { 14 | newTitle: New title 15 | } 16 | 17 | vars:pre-request { 18 | conversationId: 6ea2254d-8a9f-4547-90c2-6b068dd0369c 19 | } 20 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/utils/TokenCalculation.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.utils; 2 | 3 | import opennlp.tools.tokenize.SimpleTokenizer; 4 | 5 | public class TokenCalculation { 6 | 7 | 8 | public static int calculateTokens(String message){ 9 | SimpleTokenizer tokenizer = SimpleTokenizer.INSTANCE; 10 | String[] tokens = tokenizer.tokenize(message); 11 | return tokens.length; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/ChatbotCodeMigrationApplication.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class ChatbotCodeMigrationApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(ChatbotCodeMigrationApplication.class, args); 11 | } 12 | 13 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/configuration/agent/OpenAiAgent.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.configuration.agent; 2 | 3 | import dev.langchain4j.service.SystemMessage; 4 | 5 | public interface OpenAiAgent { 6 | 7 | @SystemMessage({""" 8 | As a General Agent, your task is to assist users with their coding queries, providing detailed and personalized responses.\s 9 | """} 10 | ) 11 | String chat(String userMessages); 12 | } 13 | -------------------------------------------------------------------------------- /logstash.conf: -------------------------------------------------------------------------------- 1 | input { 2 | # Listen for logs on port 5001 using the TCP protocol 3 | tcp { 4 | port => 5001 5 | codec => json 6 | } 7 | } 8 | 9 | filter { 10 | # Parse the timestamp field as a date 11 | date { 12 | match => [ "timestamp", "ISO8601" ] 13 | } 14 | } 15 | 16 | output { 17 | # Send the logs to Elasticsearch 18 | elasticsearch { 19 | hosts => ["elasticsearch:9200"] 20 | index => "spring-boot-%{+YYYY.MM.dd}" 21 | } 22 | # Print the logs to the standard output (optional) 23 | stdout { 24 | codec => rubydebug 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/configuration/properties/VertexProperties.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.configuration.properties; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | 5 | @ConfigurationProperties(prefix = "google-vertex") 6 | public record VertexProperties( 7 | String project, 8 | String location, 9 | String modelName, 10 | Float temperature, 11 | Integer maxOutputTokens, 12 | Integer topK, 13 | Float topP, 14 | Integer maxRetries 15 | ) {} -------------------------------------------------------------------------------- /openai-api/bruno_collection/OpenAI API/Files/UPLOAD FILE.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: UPLOAD FILE 3 | type: http 4 | seq: 2 5 | } 6 | 7 | post { 8 | url: {{openai_url}}/v1/files?purpose=ConversationId 9 | body: multipartForm 10 | auth: none 11 | } 12 | 13 | params:query { 14 | purpose: ConversationId 15 | } 16 | 17 | body:multipart-form { 18 | file: @file(/Users/A200236717/Desktop/projects/Rust/advanced_coding_assistance/src/main.rs) 19 | createdAt: 20240312 20 | } 21 | 22 | docs { 23 | To Upload a File you will need to intiate a conversation first. 24 | Since conversation id is required for it 25 | } 26 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/repository/ASTNodeRepository.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.repository; 2 | 3 | import org.springframework.data.neo4j.repository.Neo4jRepository; 4 | import org.springframework.data.neo4j.repository.query.Query; 5 | 6 | import com.telekom.ai4coding.chatbot.graph.ASTNode; 7 | 8 | import java.util.List; 9 | 10 | public interface ASTNodeRepository extends Neo4jRepository { 11 | 12 | List findByText(String text); 13 | 14 | @Query("MATCH (n:ASTNode) RETURN DISTINCT n.type") 15 | List getAllDistinctTypes(); 16 | } 17 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/configuration/agent/CodeContextVerifyAgent.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.configuration.agent; 2 | 3 | import dev.langchain4j.service.UserMessage; 4 | import dev.langchain4j.service.V; 5 | 6 | public interface CodeContextVerifyAgent { 7 | 8 | @UserMessage(""" 9 | Is the following source code relevant to the user query? 10 | 11 | User query: 12 | {{userQuery}} 13 | 14 | codeContext: 15 | {{codeContext}} 16 | """) 17 | boolean isRelevant(@V("userQuery") String userQuery, @V("codeContext") String codeContext); 18 | } 19 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/configuration/properties/AwsProperties.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.configuration.properties; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | 5 | @ConfigurationProperties(prefix = "aws") 6 | public record AwsProperties( 7 | String accessKeyId, 8 | String secretKey, 9 | String region, 10 | Integer maxRetries, 11 | Integer maxTokens, 12 | Double temperature, 13 | Integer topK, 14 | String anthropicVersion, 15 | String model, 16 | Float topP, 17 | String[] stopSequences 18 | ) {} 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | !**/src/main/**/target/ 4 | !**/src/test/**/target/ 5 | 6 | ### STS ### 7 | .apt_generated 8 | .classpath 9 | .factorypath 10 | .project 11 | .settings 12 | .springBeans 13 | .sts4-cache 14 | 15 | ### IntelliJ IDEA ### 16 | .idea 17 | *.iws 18 | *.iml 19 | *.ipr 20 | 21 | ### NetBeans ### 22 | /nbproject/private/ 23 | /nbbuild/ 24 | /dist/ 25 | /nbdist/ 26 | /.nb-gradle/ 27 | build/ 28 | !**/src/main/**/build/ 29 | !**/src/test/**/build/ 30 | 31 | ### VS Code ### 32 | .vscode/ 33 | 34 | # Ignore local properties file 35 | application-local.properties 36 | 37 | # Ignore Data folder for neo4j 38 | data-neo4j/ 39 | 40 | # MacOS 41 | .DS_Store 42 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/configuration/OpenAiConfig.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.configuration; 2 | 3 | 4 | import com.telekom.ai4coding.chatbot.configuration.agent.OpenAiAgent; 5 | import dev.langchain4j.model.chat.ChatLanguageModel; 6 | import dev.langchain4j.service.AiServices; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | @Configuration 11 | public class OpenAiConfig { 12 | 13 | 14 | @Bean 15 | OpenAiAgent openAiAgent(ChatLanguageModel chatLanguageModel) { 16 | return AiServices.builder(OpenAiAgent.class).chatLanguageModel(chatLanguageModel).build(); 17 | } 18 | 19 | 20 | } 21 | -------------------------------------------------------------------------------- /openai-api/bruno_collection/OpenAI API/Repository/Upload Local Repository.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: Upload Local Repository 3 | type: http 4 | seq: 1 5 | } 6 | 7 | post { 8 | url: {{openai_url}}/v1/repositories/local 9 | body: text 10 | auth: none 11 | } 12 | 13 | body:text { 14 | /Users/A200236717/Desktop/projects/ai4coding-chatbot/chatbot-openai-code-migration-app 15 | } 16 | 17 | docs { 18 | **Upload File or Local Repository**: 19 | This API allows the upload of either a single file or a local repository by specifying the path in plain text. 20 | 21 | 22 | **Request Body**: 23 | The body must contain plain text representing either: 24 | The file path to the single file. 25 | The repository path to the local folder. 26 | } 27 | -------------------------------------------------------------------------------- /openai-api/bruno_collection/OpenAI API/Repository/Refresh Local Repository.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: Refresh Local Repository 3 | type: http 4 | seq: 4 5 | } 6 | 7 | put { 8 | url: {{openai_url}}/v1/repositories/local/refresh 9 | body: text 10 | auth: none 11 | } 12 | 13 | body:text { 14 | /Users/A200236717/Desktop/projects/ai4coding-chatbot/chatbot-openai-code-migration-app 15 | } 16 | 17 | docs { 18 | **Upload File or Local Repository**: 19 | This API allows the upload of either a single file or a local repository by specifying the path in plain text. 20 | 21 | 22 | **Request Body**: 23 | The body must contain plain text representing either: 24 | The file path to the single file. 25 | The repository path to the local folder. 26 | } 27 | -------------------------------------------------------------------------------- /openai-api/bruno_collection/OpenAI API/Repository/Upload Gitlab Repository.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: Upload Gitlab Repository 3 | type: http 4 | seq: 2 5 | } 6 | 7 | post { 8 | url: {{openai_url}}/v1/repositories/gitlab/{{projectId}} 9 | body: text 10 | auth: none 11 | } 12 | 13 | body:text { 14 | /Users/A200236717/Desktop/projects/ai4coding-chatbot/chatbot-openai-code-migration-app 15 | } 16 | 17 | docs { 18 | **Upload File or Local Repository**: 19 | This API allows the upload of either a single file or a local repository by specifying the path in plain text. 20 | 21 | 22 | **Request Body**: 23 | The body must contain plain text representing either: 24 | The file path to the single file. 25 | The repository path to the local folder. 26 | } 27 | -------------------------------------------------------------------------------- /openai-api/bruno_collection/OpenAI API/Repository/Refresh Gitlab Repository.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: Refresh Gitlab Repository 3 | type: http 4 | seq: 3 5 | } 6 | 7 | put { 8 | url: {{openai_url}}/v1/repositories/gitlab/{{projectId}}/refresh 9 | body: none 10 | auth: none 11 | } 12 | 13 | body:text { 14 | /Users/A200236717/Desktop/projects/ai4coding-chatbot/chatbot-openai-code-migration-app 15 | } 16 | 17 | docs { 18 | **Upload File or Local Repository**: 19 | This API allows the upload of either a single file or a local repository by specifying the path in plain text. 20 | 21 | 22 | **Request Body**: 23 | The body must contain plain text representing either: 24 | The file path to the single file. 25 | The repository path to the local folder. 26 | } 27 | -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/completions/ApiUtil.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.completions; 2 | 3 | import jakarta.servlet.http.HttpServletResponse; 4 | import org.springframework.web.context.request.NativeWebRequest; 5 | 6 | import java.io.IOException; 7 | 8 | public class ApiUtil { 9 | public static void setExampleResponse(NativeWebRequest req, String contentType, String example) { 10 | try { 11 | HttpServletResponse res = req.getNativeResponse(HttpServletResponse.class); 12 | res.setCharacterEncoding("UTF-8"); 13 | res.addHeader("Content-Type", contentType); 14 | res.getWriter().print(example); 15 | } catch (IOException e) { 16 | throw new RuntimeException(e); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /openai-api/bruno_collection/OpenAI API/Chat/OpenAI chat endpoint.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: OpenAI chat endpoint 3 | type: http 4 | seq: 1 5 | } 6 | 7 | post { 8 | url: {{openai_url}}/v1/chat/completions 9 | body: json 10 | auth: none 11 | } 12 | 13 | body:json { 14 | { 15 | "messages": [ 16 | { 17 | "role": "user", 18 | "content": "Can you give me a general overview of this repository?" 19 | } 20 | ], 21 | "model": "gpt-4-turbo-preview", 22 | "frequency_penalty": "0", 23 | "logit_bias": null, 24 | "max_tokens": 100, 25 | "n": 1, 26 | "presence_penalty": "", 27 | "stop": "", 28 | "stream": "", 29 | "temperature": "", 30 | "top_p": "", 31 | "user": "user1", 32 | "function_call": "", 33 | "functions": [] 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /.run/ChatbotCodeMigrationApplication [local].run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /.run/ChatbotCodeMigrationApplication [openai].run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /.run/ChatbotCodeMigrationApplication [vertex].run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/configuration/JacksonConfig.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.configuration; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.fasterxml.jackson.databind.cfg.CoercionAction; 5 | import com.fasterxml.jackson.databind.cfg.CoercionInputShape; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | @Configuration 10 | public class JacksonConfig { 11 | 12 | @Bean 13 | public ObjectMapper objectMapper() { 14 | ObjectMapper objectMapper = new ObjectMapper(); 15 | objectMapper.coercionConfigDefaults() 16 | .setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsNull); 17 | return objectMapper; 18 | } 19 | } -------------------------------------------------------------------------------- /.run/ChatbotCodeMigrationApplication [azure].run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | 17 | -------------------------------------------------------------------------------- /.run/ChatbotCodeMigrationApplication [bedrock].run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /openai-api/bruno_collection/OpenAI API/Chat/Conversation Persistence.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: Conversation Persistence 3 | type: http 4 | seq: 2 5 | } 6 | 7 | post { 8 | url: {{openai_url}}/v1/chat/completions 9 | body: json 10 | auth: none 11 | } 12 | 13 | headers { 14 | Persist-Conversation: true 15 | } 16 | 17 | body:json { 18 | { 19 | "messages": [ 20 | { 21 | "role": "user", 22 | "content": "Can you give me a general overview of this repository?" 23 | } 24 | ], 25 | "model": "gpt-4-turbo-preview", 26 | "frequency_penalty": "0", 27 | "logit_bias": null, 28 | "max_tokens": 100, 29 | "n": 1, 30 | "presence_penalty": "", 31 | "stop": "", 32 | "stream": "", 33 | "temperature": "", 34 | "top_p": "", 35 | "user": "user1", 36 | "function_call": "", 37 | "functions": [] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/configuration/GitlabConfig.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.configuration; 2 | 3 | import com.telekom.ai4coding.chatbot.configuration.properties.AcaProperties; 4 | import org.gitlab4j.api.GitLabApi; 5 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | @Configuration 10 | @EnableConfigurationProperties(AcaProperties.class) 11 | public class GitlabConfig { 12 | 13 | @Bean 14 | public GitLabApi gitLabApi(AcaProperties acaProperties){ 15 | GitLabApi gitlabapi = new GitLabApi("https://gitlab.devops.telekom.de", acaProperties.gitlab().token()); 16 | gitlabapi.setRequestTimeout(10000,100000); 17 | return gitlabapi; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/configuration/properties/OpenaiProperties.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.configuration.properties; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | 5 | import java.util.List; 6 | 7 | @ConfigurationProperties(prefix = "openai") 8 | public record OpenaiProperties( 9 | String baseUrl, 10 | String apiKey, 11 | String organizationId, 12 | String modelName, 13 | Double temperature, 14 | Double topP, 15 | List stop, 16 | Integer maxTokens, 17 | Double presencePenalty, 18 | Double frequencyPenalty, 19 | Integer seed, 20 | String user, 21 | Integer maxRetries, 22 | Integer timeout, 23 | Boolean logRequests, 24 | Boolean logResponses, 25 | String proxy 26 | ) {} 27 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/configuration/agent/HypotheticalDocumentGenerator.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.configuration.agent; 2 | 3 | import dev.langchain4j.service.SystemMessage; 4 | import dev.langchain4j.service.UserMessage; 5 | 6 | 7 | public interface HypotheticalDocumentGenerator { 8 | 9 | @SystemMessage({""" 10 | You are a software engineer. Generate a hypothetical code snippet 11 | that the user's query is looking for. Do not include text that are 12 | not code comments. 13 | """}) 14 | String getFakeCodeSnippet(@UserMessage String userMessage); 15 | 16 | @SystemMessage({""" 17 | You are a technical writer specializing in code documentation. 18 | Write a possible code documentation that could answer the user's query. 19 | """}) 20 | String getFakeCodeDocumentation(@UserMessage String userMessage); 21 | } 22 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/configuration/properties/AzureProperties.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.configuration.properties; 2 | import java.util.List; 3 | 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | 6 | @ConfigurationProperties(prefix = "azure") 7 | public record AzureProperties( 8 | String endpoint, 9 | String apiKey, 10 | String model, 11 | Integer timeout, 12 | Boolean logRequestsAndResponses, 13 | Integer maxTokens, 14 | Double temperature, 15 | Double topP, 16 | Double presencePenalty, 17 | String user, 18 | Integer n, 19 | List stop, 20 | Double frequencyPenalty, 21 | Long seed, 22 | String proxy 23 | ) {} 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/controller/openai/Neo4JDatabaseController.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.controller.openai; 2 | 3 | import com.telekom.ai4coding.chatbot.service.Neo4JDatabaseService; 4 | import lombok.RequiredArgsConstructor; 5 | import org.springframework.http.HttpStatus; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.*; 8 | 9 | @CrossOrigin 10 | @RestController 11 | @RequiredArgsConstructor 12 | @RequestMapping("/v1/graphdb") 13 | public class Neo4JDatabaseController { 14 | 15 | private final Neo4JDatabaseService databaseService; 16 | 17 | @DeleteMapping("/cleanup") 18 | public ResponseEntity cleanupDatabase() { 19 | try { 20 | databaseService.cleanupDatabase(); 21 | return ResponseEntity.ok().build(); 22 | } catch (RuntimeException e) { 23 | return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/resources/application-vertex.example.properties: -------------------------------------------------------------------------------- 1 | # ================================================== 2 | # === NECESSARY PROPERTIES. PLEASE SPECIFY THESE === 3 | # ================================================== 4 | 5 | google-vertex.project=PROJECT 6 | google-vertex.location=LOCATION 7 | google-vertex.modelName=MODEL_NAME 8 | 9 | # ================================================== 10 | # === OPTIONAL PROPERTIES. YOU MAY SPECIFY THESE === 11 | # ================================================== 12 | 13 | # Controls the randomness of the output. Double between 0 and 1. 14 | google-vertex.temperature= 15 | 16 | # The maximum number of output tokens. Integer. 17 | google-vertex.maxOutputTokens= 18 | 19 | # The number of top responses to consider when generating a response. Integer. 20 | google-vertex.topK= 21 | 22 | # Controls the nucleus sampling, a method of generating responses. Float between 0 and 1. 23 | google-vertex.topP= 24 | 25 | # The maximum number of retries. Integer. 26 | google.vertex.maxRetries= -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/utils/EmojiRegex.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.utils; 2 | 3 | import java.nio.charset.StandardCharsets; 4 | import java.util.regex.Matcher; 5 | import java.util.regex.Pattern; 6 | 7 | /** 8 | * We need to replace the standard emojis with different values, as the encoding can vary depending on the system 9 | * and can extra byte to it. 10 | */ 11 | public class EmojiRegex { 12 | private static final Pattern EMOJI_PATTERN = Pattern.compile("[\\x{1F600}-\\x{1F64F}\\x{1F300}-\\x{1F5FF}\\x{1F680}-\\x{1F6FF}\\x{1F700}-\\x{1F77F}\\x{1F780}-\\x{1F7FF}\\x{1F800}-\\x{1F8FF}\\x{1F900}-\\x{1F9FF}\\x{1FA00}-\\x{1FA6F}\\x{1FA70}-\\x{1FAFF}\\x{2600}-\\x{26FF}\\x{2700}-\\x{27BF}]+"); 13 | 14 | public static byte[] replaceEmojis(byte[] fileContent) { 15 | String fileContentString = new String(fileContent, StandardCharsets.UTF_8); 16 | Matcher matcher = EMOJI_PATTERN.matcher(fileContentString); 17 | return matcher.replaceAll("[Emoji]").getBytes(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/test/java/com/telekom/ai4coding/chatbot/utils/TokenCalculationTest.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.utils; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.assertEquals; 6 | 7 | public class TokenCalculationTest { 8 | 9 | 10 | @Test 11 | public void calculateTokens() { 12 | String message = "Hi, Create python function to add 2 nums."; 13 | int tokens = TokenCalculation.calculateTokens(message); 14 | assertEquals(10, tokens); 15 | } 16 | 17 | @Test 18 | public void calculateTokensReturnsZero() { 19 | String message = ""; 20 | int tokens = TokenCalculation.calculateTokens(message); 21 | assertEquals(0, tokens); 22 | } 23 | 24 | @Test 25 | public void calculateTokensWithLargeMessage() { 26 | String message = "Create a video that tells the story of a lost puppy finding its way back home."; 27 | int tokens = TokenCalculation.calculateTokens(message); 28 | assertEquals(17, tokens); 29 | } 30 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/test/java/com/telekom/ai4coding/chatbot/utils/TitleGeneratorTest.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.utils; 2 | 3 | import org.junit.Test; 4 | 5 | import static com.telekom.ai4coding.chatbot.utils.TitleGenerator.generateTitle; 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | 8 | public class TitleGeneratorTest { 9 | 10 | 11 | @Test 12 | public void generateTitleFromPrompt() { 13 | String prompt = "Hi, Create python function to add 2 nums."; 14 | String title = generateTitle(prompt); 15 | assertEquals("Create Python Function Add", title); 16 | } 17 | 18 | @Test 19 | public void generateTitleReturnsNewConversation() { 20 | String prompt = "Hi there!"; 21 | String title = generateTitle(prompt); 22 | assertEquals("New Conversation", title); 23 | } 24 | 25 | @Test 26 | public void generateTitleReturnsEmptyString() { 27 | String prompt = ""; 28 | String title = generateTitle(prompt); 29 | assertEquals("New Conversation", title); 30 | } 31 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/service/Neo4JDatabaseService.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.service; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.neo4j.driver.Driver; 6 | import org.neo4j.driver.Session; 7 | import org.springframework.stereotype.Service; 8 | 9 | import static com.telekom.ai4coding.chatbot.template.cypher.Neo4JDatabaseCleanupTemplates.DATABASE_CLEANUP_CYPHER; 10 | 11 | @Slf4j 12 | @RequiredArgsConstructor 13 | @Service 14 | public class Neo4JDatabaseService { 15 | 16 | private final Driver neo4jDriver; 17 | 18 | /** 19 | * Executes a delete operation for all nodes and relationships in the Neo4j database. 20 | * 21 | */ 22 | public void cleanupDatabase() { 23 | try (Session session = neo4jDriver.session()) { 24 | session.executeWrite(tx -> { 25 | tx.run(DATABASE_CLEANUP_CYPHER); 26 | return null; 27 | }); 28 | System.out.println("All nodes and relationships have been deleted."); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/template/cypher/StateMachineRetrievalCypherTemplates.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.template.cypher; 2 | 3 | public class StateMachineRetrievalCypherTemplates { 4 | private StateMachineRetrievalCypherTemplates() { 5 | } 6 | 7 | public static final String AST_KEYWORD_SEARCH_CYPHER = 8 | "UNWIND $keywords AS keyword " + 9 | "MATCH (file:FileNode)-[:HAS_AST*]->(ast:ASTNode) " + 10 | "WHERE ast.type IN ['program'] " + 11 | " AND toLower(ast.text) CONTAINS toLower(keyword) " + 12 | "RETURN keyword, file.relativePath as FilePath, ast.text as FileContent"; 13 | 14 | public static final String TEXT_KEYWORD_SEARCH_CYPHER = 15 | "UNWIND $keywords AS keyword " + 16 | "MATCH (file:FileNode)-[:HAS_TEXT]->(textNode:TextNode) " + 17 | "WHERE toLower(textNode.text) CONTAINS toLower(keyword) " + 18 | "RETURN " + 19 | "file.relativePath as FilePath, textNode.text as FileContent"; 20 | } 21 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | localhost:5001 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/ChatCompletionRole.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator; 4 | import com.fasterxml.jackson.annotation.JsonValue; 5 | import jakarta.annotation.Generated; 6 | 7 | /** 8 | * The role of the author of a message 9 | */ 10 | 11 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 12 | public enum ChatCompletionRole { 13 | 14 | SYSTEM("system"), 15 | 16 | USER("user"), 17 | 18 | ASSISTANT("assistant"), 19 | 20 | TOOL("tool"), 21 | 22 | FUNCTION("function"); 23 | 24 | private String value; 25 | 26 | ChatCompletionRole(String value) { 27 | this.value = value; 28 | } 29 | 30 | @JsonValue 31 | public String getValue() { 32 | return value; 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return String.valueOf(value); 38 | } 39 | 40 | @JsonCreator 41 | public static ChatCompletionRole fromValue(String value) { 42 | for (ChatCompletionRole b : ChatCompletionRole.values()) { 43 | if (b.value.equals(value)) { 44 | return b; 45 | } 46 | } 47 | throw new IllegalArgumentException("Unexpected value '" + value + "'"); 48 | } 49 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/utils/DoubleFormatter.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.utils; 2 | 3 | import java.text.DecimalFormat; 4 | import java.text.DecimalFormatSymbols; 5 | import java.util.Locale; 6 | 7 | /** 8 | * DoubleFormatter is a utility class for formatting double values to strings 9 | * with a specific decimal format. 10 | * 11 | * This class ensures that double values are always formatted with a period ('.') 12 | * as the decimal separator, regardless of the system's locale settings. 13 | * 14 | * The formatter is configured to always display two decimal places. 15 | * 16 | * Usage example: 17 | * double value = 3.14159; 18 | * String formattedValue = DoubleFormatter.format(value); // Returns "3.14" 19 | */ 20 | public class DoubleFormatter { 21 | private static final DecimalFormat df; 22 | 23 | static { 24 | DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.US); 25 | symbols.setDecimalSeparator('.'); 26 | df = new DecimalFormat("0.00", symbols); 27 | df.setMinimumFractionDigits(2); 28 | df.setMaximumFractionDigits(2); 29 | } 30 | 31 | public static String format(double value) { 32 | return df.format(value); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/configuration/properties/AcaProperties.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.configuration.properties; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | import org.springframework.lang.Nullable; 5 | 6 | @ConfigurationProperties(prefix = "aca") 7 | public record AcaProperties(GitlabProperties gitlab, 8 | KnowledgeGraphConstructionProperties knowledgeGraphConstruction, 9 | EmbeddingModelProperties embeddingModel, 10 | int fillingVesselAlgorithmMaxLength, 11 | int toolResultMaxToken) { 12 | 13 | public record GitlabProperties(String token) {} 14 | 15 | public record KnowledgeGraphConstructionProperties(int astMaxDepth, 16 | int textMaxChar, 17 | int textMaxOverlappingChar) {} 18 | 19 | public record EmbeddingModelProperties(boolean useCustomModel, 20 | @Nullable String modelClassPath, 21 | @Nullable String tokenizerClassPath, 22 | @Nullable String poolingMode) {} 23 | } 24 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.3.4 9 | 10 | 11 | com.telekom.ai4coding 12 | chatbot 13 | 0.0.2-SNAPSHOT 14 | pom 15 | chatbot 16 | AI4Coding Chatbot 17 | 18 | chatbot-openai-code-migration-app 19 | openai-api 20 | 21 | 22 | 21 23 | 1.1.2 24 | 25 | 26 | 27 | 28 | 29 | org.springframework.modulith 30 | spring-modulith-bom 31 | ${spring-modulith.version} 32 | pom 33 | import 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/repository/FileNodeRepository.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.repository; 2 | 3 | import org.springframework.data.neo4j.repository.Neo4jRepository; 4 | import org.springframework.data.neo4j.repository.query.Query; 5 | import org.springframework.data.repository.query.Param; 6 | 7 | import com.telekom.ai4coding.chatbot.graph.FileNode; 8 | 9 | import java.util.List; 10 | import java.util.Optional; 11 | 12 | public interface FileNodeRepository extends Neo4jRepository { 13 | 14 | Optional findByRelativePath(String relativePath); 15 | 16 | @Query("MATCH (n) WHERE n:ASTNode OR n:FileNode or n:TextNode DETACH DELETE n") 17 | void deleteCompleteCodeGraph(); 18 | 19 | @Query("MATCH (f:FileNode)-[:RELATED_TO]->(c:ConversationNode) WHERE c.id = $conversationNodeId RETURN f") 20 | Optional> getFileNodeByConversationNodeId(@Param("conversationNodeId") String conversationNodeId); 21 | 22 | @Query("MATCH (f:FileNode) WHERE id(f) = $id " + "OPTIONAL MATCH (f)-[:HAS_AST|TEXT_NODE*]->(child) " + "OPTIONAL MATCH (child)-[:NEXT_CHUNK|PARENT_OF*]->(related) " + "DETACH DELETE f, child, related") 23 | void deleteFileNodeAndItsChildrenById(@Param("id") Long id); 24 | 25 | @Query("MATCH (n:FileNode) RETURN n.relativePath") 26 | List getAllRelativePaths(); 27 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/test/resources/application-test.properties: -------------------------------------------------------------------------------- 1 | #Configuration for Test Environment 2 | chatbot.code-migration.openai-client.endpoint=https://test.api 3 | chatbot.code-migration.openai-client.model=gpt-4-turbo-preview 4 | chatbot.code-migration.openai-client.api-key=key 5 | 6 | azure.endpoint=https://test.api 7 | azure.model=AZURE_OPENAI_DEPLOYMENT_NAME 8 | azure.api-key=AZURE_OPENAI_KEY 9 | 10 | aws.accessKeyId=AWS_ACCESS_KEY_ID 11 | aws.secretKey=AWS_SECRET_ACCESS_KEY 12 | aws.region=AWS_REGION 13 | 14 | openai.apiKey=API_KEY 15 | 16 | google-vertex.project=PROJECT 17 | google-vertex.location=LOCATION 18 | google-vertex.modelName=MODEL_NAME 19 | 20 | local.endpoint=http://localhost:1234/v1 21 | 22 | chatbot.code-migration.cors.allowed-origins=http://localhost:3000,http://127.0.0.1:3000 23 | 24 | spring.neo4j.uri=bolt://localhost:7687 25 | spring.neo4j.authentication.username=neo4j 26 | spring.neo4j.authentication.password=neo4j.password 27 | 28 | org.neo4j.migrations.enabled=false 29 | 30 | aca.knowledge-graph-construction.ast-max-depth=999 31 | aca.knowledge-graph-construction.text-max-char=5000 32 | aca.knowledge-graph-construction.text-max-overlapping-char=1000 33 | aca.knowledge-graph-construction.git-ignore-project-directory-absolute-path= 34 | 35 | aca.embedding-model.use-custom-model=false 36 | aca.embedding-model.model-class-path= 37 | aca.embedding-model.tokenizer-class-path= 38 | aca.embedding-model.pooling-mode= -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/repository/ConversationNodeRepository.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.repository; 2 | 3 | import com.telekom.ai4coding.chatbot.repository.conversation.ConversationNode; 4 | import org.springframework.data.neo4j.repository.Neo4jRepository; 5 | import org.springframework.data.neo4j.repository.query.Query; 6 | import org.springframework.data.repository.query.Param; 7 | 8 | public interface ConversationNodeRepository extends Neo4jRepository { 9 | 10 | @Query("MATCH (c:ConversationNode {id: $id}) " + 11 | "OPTIONAL MATCH (c)-[r:HAS_MESSAGE]->(m:MessageNode) " + 12 | "DETACH DELETE c, m") 13 | void deleteConversationAndMessagesById(@Param("id") String id); 14 | 15 | @Query("MATCH (c:ConversationNode {id: $id}) " + 16 | "OPTIONAL MATCH (m:MessageNode)-[r:BELONGS_TO]->(c) " + 17 | "OPTIONAL MATCH (f:FileNode)-[:RELATED_TO]->(c) " + 18 | "OPTIONAL MATCH (f)-[:HAS_AST|TEXT_NODE*]->(child) " + 19 | "OPTIONAL MATCH (child)-[:NEXT_CHUNK|PARENT_OF*]->(related) " + 20 | "DETACH DELETE m, c, f, child, related") 21 | void deleteAllByConversationId(@Param("id") String id); 22 | 23 | @Query("MATCH (c:ConversationNode {id: $id}) SET c.title = $title RETURN c") 24 | ConversationNode updateTitleByConversationId(@Param("id") String id, @Param("title") String title); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=8152 2 | 3 | #logging.level.root=DEBUG 4 | logging.level.org.springframework.security=DEBUG 5 | 6 | #Spring profiles 7 | spring.profiles.default=azure 8 | 9 | # OpenAI for completions endpoint. Set either the OpenAI API key or the Azure API key. 10 | openai.completions.endpoint= 11 | openai.completions.openai-api-key= 12 | openai.completions.azure-api-key= 13 | 14 | #NEO4J 15 | spring.neo4j.uri=bolt://localhost:7687 16 | spring.neo4j.authentication.username=neo4j 17 | spring.neo4j.authentication.password=neo4j.password 18 | 19 | #Gitlab With enough permissions to clone the repository 20 | aca.gitlab.token= 21 | 22 | # only active with the state-machine profile 23 | aca.filling-vessel-algorithm-max-length=30000 24 | 25 | aca.tool-result-max-token=80000 26 | 27 | # Knowledge Graph Construction 28 | aca.knowledge-graph-construction.ast-max-depth=5 29 | aca.knowledge-graph-construction.text-max-char=5000 30 | aca.knowledge-graph-construction.text-max-overlapping-char=1000 31 | aca.embedding-model.use-custom-model=true 32 | aca.embedding-model.model-class-path=classpath:embedding/gte-base-en-v1.5_model_quantized.onnx 33 | aca.embedding-model.tokenizer-class-path=classpath:embedding/gte-base-en-v1.5_tokenizer.json 34 | aca.embedding-model.pooling-mode=CLS 35 | 36 | #Logging for LLM communication 37 | logging.level.org.neo4j.driver.internal.async.outbound=DEBUG 38 | logging.level.dev.langchain4j=DEBUG 39 | logging.level.com.azure.ai.openai=DEBUG -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateImageRequestModel.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonTypeName; 4 | import io.swagger.v3.oas.annotations.media.Schema; 5 | import jakarta.annotation.Generated; 6 | 7 | import java.util.Objects; 8 | 9 | /** 10 | * The model to use for image generation. 11 | */ 12 | 13 | @Schema(name = "CreateImageRequest_model", description = "The model to use for image generation.") 14 | @JsonTypeName("CreateImageRequest_model") 15 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 16 | public class CreateImageRequestModel { 17 | 18 | @Override 19 | public boolean equals(Object o) { 20 | if (this == o) { 21 | return true; 22 | } 23 | if (o == null || getClass() != o.getClass()) { 24 | return false; 25 | } 26 | return true; 27 | } 28 | 29 | @Override 30 | public int hashCode() { 31 | return Objects.hash(); 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | StringBuilder sb = new StringBuilder(); 37 | sb.append("class CreateImageRequestModel {\n"); 38 | sb.append("}"); 39 | return sb.toString(); 40 | } 41 | 42 | /** 43 | * Convert the given object to string with each line indented by 4 spaces 44 | * (except the first line). 45 | */ 46 | private String toIndentedString(Object o) { 47 | if (o == null) { 48 | return "null"; 49 | } 50 | return o.toString().replace("\n", "\n "); 51 | } 52 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/configuration/GraphDbConfig.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.configuration; 2 | 3 | import java.util.Set; 4 | import org.neo4j.cypherdsl.core.renderer.Dialect; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.core.convert.converter.GenericConverter; 8 | import org.springframework.data.neo4j.config.EnableNeo4jAuditing; 9 | import org.springframework.data.neo4j.core.convert.Neo4jConversions; 10 | 11 | import java.util.HashSet; 12 | 13 | import com.telekom.ai4coding.chatbot.repository.conversation.ToolExecutionRequestConverter; 14 | import com.telekom.ai4coding.chatbot.repository.conversation.ToolExecutionResultMessageConverter; 15 | 16 | @Configuration 17 | @EnableNeo4jAuditing 18 | public class GraphDbConfig { 19 | 20 | @Bean 21 | org.neo4j.cypherdsl.core.renderer.Configuration cypherDslConfiguration() { 22 | return org.neo4j.cypherdsl.core.renderer.Configuration.newConfig() 23 | .withDialect(Dialect.NEO4J_5).build(); 24 | } 25 | 26 | @Bean 27 | public Neo4jConversions neo4jConversions() { 28 | Set additionalConverters = new HashSet(); 29 | additionalConverters.add(new ToolExecutionRequestConverter()); 30 | additionalConverters.add(new ToolExecutionResultMessageConverter()); 31 | return new Neo4jConversions(additionalConverters); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/controller/openai/FilesController.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.controller.openai; 2 | 3 | import com.telekom.ai4coding.chatbot.service.FileService; 4 | import com.telekom.ai4coding.openai.completions.FilesApi; 5 | import com.telekom.ai4coding.openai.model.DeleteFileResponse; 6 | import com.telekom.ai4coding.openai.model.ListFilesResponse; 7 | import com.telekom.ai4coding.openai.model.OpenAIFile; 8 | import lombok.RequiredArgsConstructor; 9 | import org.springframework.http.ResponseEntity; 10 | import org.springframework.web.bind.annotation.*; 11 | import org.springframework.web.multipart.MultipartFile; 12 | 13 | 14 | @CrossOrigin 15 | @RestController 16 | @RequiredArgsConstructor 17 | @RequestMapping("/v1") 18 | public class FilesController implements FilesApi { 19 | 20 | private final FileService fileService; 21 | 22 | @Override 23 | public ResponseEntity createFile(MultipartFile file, 24 | @RequestParam(value = "purpose") String purpose) { 25 | return fileService.createFile(file, purpose); 26 | } 27 | 28 | @Override 29 | public ResponseEntity deleteFile(@PathVariable("file_id") String fileId) { 30 | return fileService.deleteFile(Long.valueOf(fileId)); 31 | } 32 | 33 | @Override 34 | public ResponseEntity listFiles(String purpose) { 35 | return fileService.getFilesByConversationId(purpose); 36 | } 37 | } -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | database: 3 | image: 'neo4j:5.20.0' 4 | ports: 5 | - '7474:7474' 6 | - '7687:7687' 7 | volumes: 8 | - './data-neo4j:/data' 9 | environment: 10 | - NEO4J_AUTH=neo4j/neo4j.password 11 | - NEO4J_apoc_export_file_enabled=true 12 | - NEO4J_apoc_import_file_enabled=true 13 | - NEO4J_apoc_import_file_use__neo4j__config=true 14 | - NEO4J_PLUGINS=["apoc"] 15 | 16 | healthcheck: 17 | test: ["CMD", "cypher-shell", "-u", "neo4j", "-p", "neo4j.password", "RETURN 1"] 18 | interval: 20s 19 | timeout: 5s 20 | retries: 3 21 | networks: 22 | - aca-network 23 | 24 | elasticsearch: 25 | image: docker.elastic.co/elasticsearch/elasticsearch:7.13.4 26 | container_name: elasticsearch 27 | environment: 28 | - discovery.type=single-node 29 | ports: 30 | - "9200:9200" 31 | - "9300:9300" 32 | networks: 33 | - aca-network 34 | 35 | logstash: 36 | image: docker.elastic.co/logstash/logstash:7.13.4 37 | container_name: logstash 38 | depends_on: 39 | - elasticsearch 40 | ports: 41 | - "5001:5001" 42 | - "9600:9600" 43 | volumes: 44 | - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf 45 | networks: 46 | - aca-network 47 | 48 | kibana: 49 | image: docker.elastic.co/kibana/kibana:7.13.4 50 | container_name: kibana 51 | depends_on: 52 | - elasticsearch 53 | ports: 54 | - "5601:5601" 55 | networks: 56 | - aca-network 57 | 58 | networks: 59 | aca-network: 60 | driver: bridge -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateSpeechRequestModel.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonTypeName; 4 | import io.swagger.v3.oas.annotations.media.Schema; 5 | import jakarta.annotation.Generated; 6 | 7 | import java.util.Objects; 8 | 9 | /** 10 | * One of the available [TTS models](/docs/models/tts): `tts-1` or `tts-1-hd` 11 | */ 12 | 13 | @Schema(name = "CreateSpeechRequest_model", description = "One of the available [TTS models](/docs/models/tts): `tts-1` or `tts-1-hd` ") 14 | @JsonTypeName("CreateSpeechRequest_model") 15 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 16 | public class CreateSpeechRequestModel { 17 | 18 | @Override 19 | public boolean equals(Object o) { 20 | if (this == o) { 21 | return true; 22 | } 23 | if (o == null || getClass() != o.getClass()) { 24 | return false; 25 | } 26 | return true; 27 | } 28 | 29 | @Override 30 | public int hashCode() { 31 | return Objects.hash(); 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | StringBuilder sb = new StringBuilder(); 37 | sb.append("class CreateSpeechRequestModel {\n"); 38 | sb.append("}"); 39 | return sb.toString(); 40 | } 41 | 42 | /** 43 | * Convert the given object to string with each line indented by 4 spaces 44 | * (except the first line). 45 | */ 46 | private String toIndentedString(Object o) { 47 | if (o == null) { 48 | return "null"; 49 | } 50 | return o.toString().replace("\n", "\n "); 51 | } 52 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateTranscriptionRequestModel.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonTypeName; 4 | import io.swagger.v3.oas.annotations.media.Schema; 5 | import jakarta.annotation.Generated; 6 | 7 | import java.util.Objects; 8 | 9 | /** 10 | * ID of the model to use. Only `whisper-1` is currently available. 11 | */ 12 | 13 | @Schema(name = "CreateTranscriptionRequest_model", description = "ID of the model to use. Only `whisper-1` is currently available. ") 14 | @JsonTypeName("CreateTranscriptionRequest_model") 15 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 16 | public class CreateTranscriptionRequestModel { 17 | 18 | @Override 19 | public boolean equals(Object o) { 20 | if (this == o) { 21 | return true; 22 | } 23 | if (o == null || getClass() != o.getClass()) { 24 | return false; 25 | } 26 | return true; 27 | } 28 | 29 | @Override 30 | public int hashCode() { 31 | return Objects.hash(); 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | StringBuilder sb = new StringBuilder(); 37 | sb.append("class CreateTranscriptionRequestModel {\n"); 38 | sb.append("}"); 39 | return sb.toString(); 40 | } 41 | 42 | /** 43 | * Convert the given object to string with each line indented by 4 spaces 44 | * (except the first line). 45 | */ 46 | private String toIndentedString(Object o) { 47 | if (o == null) { 48 | return "null"; 49 | } 50 | return o.toString().replace("\n", "\n "); 51 | } 52 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateImageEditRequestModel.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonTypeName; 4 | import io.swagger.v3.oas.annotations.media.Schema; 5 | import jakarta.annotation.Generated; 6 | 7 | import java.util.Objects; 8 | 9 | /** 10 | * The model to use for image generation. Only `dall-e-2` is supported at this time. 11 | */ 12 | 13 | @Schema(name = "CreateImageEditRequest_model", description = "The model to use for image generation. Only `dall-e-2` is supported at this time.") 14 | @JsonTypeName("CreateImageEditRequest_model") 15 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 16 | public class CreateImageEditRequestModel { 17 | 18 | @Override 19 | public boolean equals(Object o) { 20 | if (this == o) { 21 | return true; 22 | } 23 | if (o == null || getClass() != o.getClass()) { 24 | return false; 25 | } 26 | return true; 27 | } 28 | 29 | @Override 30 | public int hashCode() { 31 | return Objects.hash(); 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | StringBuilder sb = new StringBuilder(); 37 | sb.append("class CreateImageEditRequestModel {\n"); 38 | sb.append("}"); 39 | return sb.toString(); 40 | } 41 | 42 | /** 43 | * Convert the given object to string with each line indented by 4 spaces 44 | * (except the first line). 45 | */ 46 | private String toIndentedString(Object o) { 47 | if (o == null) { 48 | return "null"; 49 | } 50 | return o.toString().replace("\n", "\n "); 51 | } 52 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/resources/application-azure.example.properties: -------------------------------------------------------------------------------- 1 | # ================================================== 2 | # === NECESSARY PROPERTIES. PLEASE SPECIFY THESE === 3 | # ================================================== 4 | 5 | azure.endpoint=AZURE_OPENAI_ENDPOINT 6 | azure.model=AZURE_OPENAI_DEPLOYMENT_NAME 7 | azure.api-key=AZURE_OPENAI_KEY 8 | 9 | # ================================================== 10 | # === OPTIONAL PROPERTIES. YOU MAY SPECIFY THESE === 11 | # ================================================== 12 | 13 | # Azure service response wait time (in mins). Integer Value. 14 | azure.timeout= 15 | 16 | # Azure service requests and responses logging. Boolean. 17 | azure.logRequestsAndResponses= 18 | 19 | # The maximum number of tokens in the generated response. Integer Value. 20 | azure.maxTokens= 21 | 22 | # Controls the randomness of the output. Double between 0 and 1. 23 | azure.temperature= 24 | 25 | # The probability of the most likely tokens to include in the output. Double between 0 and 1. 26 | azure.topP= 27 | 28 | # The penalty for new tokens based on their presence in the input. Double between 0 and 1. 29 | azure.presencePenalty= 30 | 31 | # The user in the conversation. String. 32 | azure.user= 33 | 34 | # The number of best completions to return from the model. Integer. 35 | azure.n= 36 | 37 | # The sequences where the API will stop generating further tokens. Comma-separated strings. 38 | azure.stop= 39 | 40 | # The penalty for new tokens based on their frequency in the input. Double between 0 and 1. 41 | azure.frequencyPenalty= 42 | 43 | # The seed for deterministic output. Any Long. 44 | azure.seed= 45 | 46 | # The proxy that should be used 47 | azure.proxy= 48 | -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateFineTuningJobRequestModel.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonTypeName; 4 | import io.swagger.v3.oas.annotations.media.Schema; 5 | import jakarta.annotation.Generated; 6 | 7 | import java.util.Objects; 8 | 9 | /** 10 | * The name of the model to fine-tune. You can select one of the [supported models](/docs/guides/fine-tuning/what-models-can-be-fine-tuned). 11 | */ 12 | 13 | @Schema(name = "CreateFineTuningJobRequest_model", description = "The name of the model to fine-tune. You can select one of the [supported models](/docs/guides/fine-tuning/what-models-can-be-fine-tuned). ") 14 | @JsonTypeName("CreateFineTuningJobRequest_model") 15 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 16 | public class CreateFineTuningJobRequestModel { 17 | 18 | @Override 19 | public boolean equals(Object o) { 20 | if (this == o) { 21 | return true; 22 | } 23 | if (o == null || getClass() != o.getClass()) { 24 | return false; 25 | } 26 | return true; 27 | } 28 | 29 | @Override 30 | public int hashCode() { 31 | return Objects.hash(); 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | StringBuilder sb = new StringBuilder(); 37 | sb.append("class CreateFineTuningJobRequestModel {\n"); 38 | sb.append("}"); 39 | return sb.toString(); 40 | } 41 | 42 | /** 43 | * Convert the given object to string with each line indented by 4 spaces 44 | * (except the first line). 45 | */ 46 | private String toIndentedString(Object o) { 47 | if (o == null) { 48 | return "null"; 49 | } 50 | return o.toString().replace("\n", "\n "); 51 | } 52 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/resources/application-bedrock.example.properties: -------------------------------------------------------------------------------- 1 | # ================================================== 2 | # === NECESSARY PROPERTIES. PLEASE SPECIFY THESE === 3 | # ================================================== 4 | 5 | aws.accessKeyId=AWS_ACCESS_KEY_ID 6 | aws.secretKey=AWS_SECRET_ACCESS_KEY 7 | aws.region=AWS_REGION 8 | 9 | # ================================================== 10 | # === OPTIONAL PROPERTIES. YOU MAY SPECIFY THESE === 11 | # ================================================== 12 | 13 | # The model to use for generating responses. Value is model_string. Default is anthropic.claude-3-sonnet-20240229-v1:0. 14 | # Format: model_name -> model_string 15 | # 16 | # AnthropicClaudeInstantV1 -> anthropic.claude-instant-v1 17 | # AnthropicClaudeV2 -> anthropic.claude-v2 18 | # AnthropicClaudeV2_1 -> anthropic.claude-v2:1 19 | # AnthropicClaude3SonnetV1 -> anthropic.claude-3-sonnet-20240229-v1:0 20 | # AnthropicClaude3HaikuV1 -> anthropic.claude-3-haiku-20240307-v1:0 21 | aws.model=anthropic.claude-3-sonnet-20240229-v1:0 22 | 23 | # The number of top responses to consider when generating a response. Integer. 24 | aws.topK= 25 | 26 | # The version of the Anthropic model to use. String. 27 | aws.anthropicVersion= 28 | 29 | # The maximum number of tokens to generate for a response. Integer. 30 | aws.maxTokens= 31 | 32 | # Controls the randomness of the generated responses. Double between 0 and 1. 33 | aws.temperature= 34 | 35 | # Controls the nucleus sampling, a method of generating responses. Float between 0 and 1. 36 | aws.topP= 37 | 38 | # The sequences at which the generation of a response should stop. Comma-separated strings. 39 | aws.stopSequences= 40 | 41 | # The maximum number of retries when invoking the model. Integer. 42 | aws.maxRetries= -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateChatCompletionRequestModel.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonTypeName; 4 | import io.swagger.v3.oas.annotations.media.Schema; 5 | import jakarta.annotation.Generated; 6 | 7 | import java.util.Objects; 8 | 9 | /** 10 | * ID of the model to use. See the [model endpoint compatibility](/docs/models/model-endpoint-compatibility) table for details on which models work with the Chat API. 11 | */ 12 | 13 | @Schema(name = "CreateChatCompletionRequest_model", description = "ID of the model to use. See the [model endpoint compatibility](/docs/models/model-endpoint-compatibility) table for details on which models work with the Chat API.") 14 | @JsonTypeName("CreateChatCompletionRequest_model") 15 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 16 | public class CreateChatCompletionRequestModel { 17 | 18 | @Override 19 | public boolean equals(Object o) { 20 | if (this == o) { 21 | return true; 22 | } 23 | if (o == null || getClass() != o.getClass()) { 24 | return false; 25 | } 26 | return true; 27 | } 28 | 29 | @Override 30 | public int hashCode() { 31 | return Objects.hash(); 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | StringBuilder sb = new StringBuilder(); 37 | sb.append("class CreateChatCompletionRequestModel {\n"); 38 | sb.append("}"); 39 | return sb.toString(); 40 | } 41 | 42 | /** 43 | * Convert the given object to string with each line indented by 4 spaces 44 | * (except the first line). 45 | */ 46 | private String toIndentedString(Object o) { 47 | if (o == null) { 48 | return "null"; 49 | } 50 | return o.toString().replace("\n", "\n "); 51 | } 52 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/repository/conversation/ToolExecutionRequestConverter.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.repository.conversation; 2 | 3 | import java.util.Set; 4 | import java.util.HashSet; 5 | 6 | import org.neo4j.driver.Value; 7 | import org.neo4j.driver.Values; 8 | import org.springframework.core.convert.TypeDescriptor; 9 | import org.springframework.core.convert.converter.GenericConverter; 10 | 11 | import dev.langchain4j.agent.tool.ToolExecutionRequest; 12 | 13 | public class ToolExecutionRequestConverter implements GenericConverter { 14 | 15 | @Override 16 | public Set getConvertibleTypes() { 17 | Set convertiblePairs = new HashSet<>(); 18 | convertiblePairs.add(new ConvertiblePair(ToolExecutionRequest.class, Value.class)); 19 | convertiblePairs.add(new ConvertiblePair(Value.class, ToolExecutionRequest.class)); 20 | return convertiblePairs; 21 | } 22 | 23 | @Override 24 | public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { 25 | if (ToolExecutionRequest.class.isAssignableFrom(sourceType.getType())) { 26 | ToolExecutionRequest toolExecutionRequest = (ToolExecutionRequest) source; 27 | String toolExecutionRequestAttributes = ( 28 | toolExecutionRequest.id() + ";" + 29 | toolExecutionRequest.name() + ";" + 30 | toolExecutionRequest.arguments() 31 | ); 32 | return Values.value(toolExecutionRequestAttributes); 33 | } else { 34 | String[] toolExecutionRequestAttributes = ((Value) source).asString().split(";"); 35 | return ToolExecutionRequest.builder() 36 | .id(toolExecutionRequestAttributes[0]) 37 | .name(toolExecutionRequestAttributes[1]) 38 | .arguments(toolExecutionRequestAttributes[2]) 39 | .build(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateEmbeddingRequestModel.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonTypeName; 4 | import io.swagger.v3.oas.annotations.media.Schema; 5 | import jakarta.annotation.Generated; 6 | 7 | import java.util.Objects; 8 | 9 | /** 10 | * ID of the model to use. You can use the [List models](/docs/api-reference/models/list) API to see all of your available models, or see our [Model overview](/docs/models/overview) for descriptions of them. 11 | */ 12 | 13 | @Schema(name = "CreateEmbeddingRequest_model", description = "ID of the model to use. You can use the [List models](/docs/api-reference/models/list) API to see all of your available models, or see our [Model overview](/docs/models/overview) for descriptions of them. ") 14 | @JsonTypeName("CreateEmbeddingRequest_model") 15 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 16 | public class CreateEmbeddingRequestModel { 17 | 18 | @Override 19 | public boolean equals(Object o) { 20 | if (this == o) { 21 | return true; 22 | } 23 | if (o == null || getClass() != o.getClass()) { 24 | return false; 25 | } 26 | return true; 27 | } 28 | 29 | @Override 30 | public int hashCode() { 31 | return Objects.hash(); 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | StringBuilder sb = new StringBuilder(); 37 | sb.append("class CreateEmbeddingRequestModel {\n"); 38 | sb.append("}"); 39 | return sb.toString(); 40 | } 41 | 42 | /** 43 | * Convert the given object to string with each line indented by 4 spaces 44 | * (except the first line). 45 | */ 46 | private String toIndentedString(Object o) { 47 | if (o == null) { 48 | return "null"; 49 | } 50 | return o.toString().replace("\n", "\n "); 51 | } 52 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/resources/application-openai.example.properties: -------------------------------------------------------------------------------- 1 | # ================================================== 2 | # === NECESSARY PROPERTIES. PLEASE SPECIFY THESE === 3 | # ================================================== 4 | 5 | openai.apiKey=API_KEY 6 | 7 | # ================================================== 8 | # === OPTIONAL PROPERTIES. YOU MAY SPECIFY THESE === 9 | # ================================================== 10 | 11 | # The base URL of the OpenAI API. String. 12 | openai.baseUrl=https://api.openai.com/v1 13 | 14 | # The model name to use for generating responses. String. 15 | openai.modelName=gpt-4o 16 | 17 | # Controls the randomness of the generated responses. Double between 0 and 1. 18 | openai.temperature= 19 | 20 | # Controls the nucleus sampling, a method of generating responses. Float between 0 and 1. 21 | openai.topP= 22 | 23 | # The sequences where the API will stop generating further tokens. List of strings. 24 | openai.stop= 25 | 26 | # The maximum number of tokens in the generated response. Integer. 27 | openai.maxTokens= 28 | 29 | # The penalty for new tokens based on their presence in the input. Double between 0 and 1. 30 | openai.presencePenalty= 31 | 32 | # The penalty for new tokens based on their frequency in the input. Double between 0 and 1. 33 | openai.frequencyPenalty= 34 | 35 | # The seed for deterministic output. Integer. 36 | openai.seed= 37 | 38 | # The user in the conversation. String. 39 | openai.user= 40 | 41 | # The maximum number of retries. Integer. 42 | openai.maxRetries= 43 | 44 | # The timeout duration in seconds. Integer. 45 | openai.timeout= 46 | 47 | # The organization ID. String. 48 | openai.organizationId= 49 | 50 | # Whether to log requests. Boolean. 51 | openai.logRequests= 52 | 53 | # Whether to log responses. Boolean. 54 | openai.logResponses= 55 | 56 | # The proxy that should be used 57 | openai.proxy= -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/test/java/com/telekom/ai4coding/chatbot/BaseIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot; 2 | 3 | import dev.langchain4j.store.graph.neo4j.Neo4jGraph; 4 | import org.junit.jupiter.api.AfterAll; 5 | import org.junit.jupiter.api.BeforeAll; 6 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.boot.test.mock.mockito.MockBean; 9 | import org.springframework.test.annotation.DirtiesContext; 10 | import org.springframework.test.context.DynamicPropertyRegistry; 11 | import org.springframework.test.context.DynamicPropertySource; 12 | import org.springframework.test.context.TestPropertySource; 13 | import org.testcontainers.containers.Neo4jContainer; 14 | import org.testcontainers.containers.Neo4jLabsPlugin; 15 | import org.testcontainers.junit.jupiter.Container; 16 | import org.testcontainers.junit.jupiter.Testcontainers; 17 | 18 | @TestPropertySource(locations = "classpath:application-test.properties") 19 | @SpringBootTest 20 | @AutoConfigureMockMvc 21 | @Testcontainers 22 | @DirtiesContext 23 | public class BaseIntegrationTest { 24 | 25 | @MockBean 26 | private Neo4jGraph neo4jGraph; 27 | @Container 28 | private static Neo4jContainer neo4jContainer = new Neo4jContainer<>("neo4j:5.20.0") 29 | .withLabsPlugins(Neo4jLabsPlugin.APOC); 30 | 31 | @BeforeAll 32 | static void startContainer() { 33 | neo4jContainer.start(); 34 | } 35 | 36 | @AfterAll 37 | static void stopContainer() { 38 | neo4jContainer.stop(); 39 | } 40 | 41 | @DynamicPropertySource 42 | static void neo4jProperties(DynamicPropertyRegistry registry) { 43 | registry.add("spring.neo4j.uri", () -> neo4jContainer.getBoltUrl()); 44 | registry.add("spring.neo4j.authentication.username", () -> "neo4j"); 45 | registry.add("spring.neo4j.authentication.password", () -> neo4jContainer.getAdminPassword()); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/test/java/com/telekom/ai4coding/chatbot/repository/conversation/ToolExecutionRequestConverterTest.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.repository.conversation; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import org.junit.jupiter.api.BeforeEach; 6 | import org.junit.jupiter.api.Test; 7 | import org.neo4j.driver.Value; 8 | import org.neo4j.driver.Values; 9 | import org.springframework.core.convert.TypeDescriptor; 10 | 11 | import dev.langchain4j.agent.tool.ToolExecutionRequest; 12 | 13 | public class ToolExecutionRequestConverterTest { 14 | private ToolExecutionRequestConverter converter; 15 | 16 | @BeforeEach 17 | void setUp() { 18 | converter = new ToolExecutionRequestConverter(); 19 | } 20 | 21 | @Test 22 | void testConvertToolExecutionRequestToValue() { 23 | ToolExecutionRequest request = ToolExecutionRequest.builder() 24 | .id("123") 25 | .name("testTool") 26 | .arguments("arg1") 27 | .build(); 28 | TypeDescriptor sourceType = TypeDescriptor.valueOf(ToolExecutionRequest.class); 29 | TypeDescriptor targetType = TypeDescriptor.valueOf(Value.class); 30 | 31 | Value result = (Value) converter.convert(request, sourceType, targetType); 32 | 33 | assertEquals("123;testTool;arg1", result.asString()); 34 | } 35 | 36 | @Test 37 | void testConvertValueToToolExecutionRequest() { 38 | // Arrange 39 | Value value = Values.value("123;testTool;arg1"); 40 | TypeDescriptor sourceType = TypeDescriptor.valueOf(Value.class); 41 | TypeDescriptor targetType = TypeDescriptor.valueOf(ToolExecutionRequest.class); 42 | 43 | // Act 44 | ToolExecutionRequest result = (ToolExecutionRequest) converter.convert(value, sourceType, targetType); 45 | 46 | // Assert 47 | assertEquals("123", result.id()); 48 | assertEquals("testTool", result.name()); 49 | assertEquals("arg1", result.arguments()); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateCompletionRequestModel.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonTypeName; 4 | import io.swagger.v3.oas.annotations.media.Schema; 5 | import jakarta.annotation.Generated; 6 | 7 | import java.util.Objects; 8 | 9 | @Schema(name = "CreateCompletionRequest_model", description = "ID of the model to use. You can use the [List models](/docs/api-reference/models/list) API to see all of your available models, or see our [Model overview](/docs/models/overview) for descriptions of them. ") 10 | @JsonTypeName("CreateCompletionRequest_model") 11 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 12 | public class CreateCompletionRequestModel { 13 | 14 | private String modelId; 15 | 16 | public CreateCompletionRequestModel() { 17 | } 18 | 19 | public CreateCompletionRequestModel(String modelId) { 20 | this.modelId = modelId; 21 | } 22 | 23 | public String getModelId() { 24 | return modelId; 25 | } 26 | 27 | public void setModelId(String modelId) { 28 | this.modelId = modelId; 29 | } 30 | 31 | @Override 32 | public boolean equals(Object o) { 33 | if (this == o) return true; 34 | if (o == null || getClass() != o.getClass()) return false; 35 | CreateCompletionRequestModel that = (CreateCompletionRequestModel) o; 36 | return Objects.equals(modelId, that.modelId); 37 | } 38 | 39 | @Override 40 | public int hashCode() { 41 | return Objects.hash(modelId); 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | StringBuilder sb = new StringBuilder(); 47 | sb.append("class CreateCompletionRequestModel {\n"); 48 | sb.append(" modelId: ").append(toIndentedString(modelId)).append("\n"); 49 | sb.append("}"); 50 | return sb.toString(); 51 | } 52 | 53 | /** 54 | * Convert the given object to string with each line indented by 4 spaces 55 | * (except the first line). 56 | */ 57 | private String toIndentedString(Object o) { 58 | if (o == null) { 59 | return "null"; 60 | } 61 | return o.toString().replace("\n", "\n "); 62 | } 63 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/repository/conversation/ToolExecutionResultMessageConverter.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.repository.conversation; 2 | 3 | import java.util.Set; 4 | import java.util.HashSet; 5 | import java.util.List; 6 | 7 | import org.neo4j.driver.Value; 8 | import org.neo4j.driver.Values; 9 | import org.springframework.core.convert.TypeDescriptor; 10 | import org.springframework.core.convert.converter.GenericConverter; 11 | 12 | import dev.langchain4j.data.message.ToolExecutionResultMessage; 13 | 14 | public class ToolExecutionResultMessageConverter implements GenericConverter { 15 | 16 | @Override 17 | public Set getConvertibleTypes() { 18 | Set convertiblePairs = new HashSet<>(); 19 | convertiblePairs.add(new ConvertiblePair(ToolExecutionResultMessage.class, Value.class)); 20 | convertiblePairs.add(new ConvertiblePair(Value.class, ToolExecutionResultMessage.class)); 21 | return convertiblePairs; 22 | } 23 | 24 | @Override 25 | public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { 26 | if (ToolExecutionResultMessage.class.isAssignableFrom(sourceType.getType())) { 27 | ToolExecutionResultMessage toolExecutionResultMessage = (ToolExecutionResultMessage) source; 28 | String[] toolExecutionResultMessageArray = { 29 | toolExecutionResultMessage.id(), 30 | toolExecutionResultMessage.toolName(), 31 | toolExecutionResultMessage.text() 32 | }; 33 | return Values.value(toolExecutionResultMessageArray); 34 | } else { 35 | List toolExecutionResultMessageArray = ((Value) source).asList(obj -> { 36 | String str = String.valueOf(obj); 37 | if (str.startsWith("\"") && str.endsWith("\"")) { 38 | return str.substring(1, str.length() - 1); 39 | } 40 | return str; 41 | }); 42 | return new ToolExecutionResultMessage( 43 | toolExecutionResultMessageArray.get(0), 44 | toolExecutionResultMessageArray.get(1), 45 | toolExecutionResultMessageArray.get(2)); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/test/java/com/telekom/ai4coding/chatbot/repository/conversation/ToolExecutionResultMessageConverterTest.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.repository.conversation; 2 | 3 | import static org.junit.Assert.assertArrayEquals; 4 | import static org.junit.jupiter.api.Assertions.assertEquals; 5 | 6 | import org.junit.jupiter.api.BeforeEach; 7 | import org.junit.jupiter.api.Test; 8 | import org.neo4j.driver.Value; 9 | import org.neo4j.driver.Values; 10 | import org.springframework.core.convert.TypeDescriptor; 11 | 12 | import dev.langchain4j.data.message.ToolExecutionResultMessage; 13 | 14 | public class ToolExecutionResultMessageConverterTest { 15 | private ToolExecutionResultMessageConverter converter; 16 | 17 | @BeforeEach 18 | void setUp() { 19 | converter = new ToolExecutionResultMessageConverter(); 20 | } 21 | 22 | @Test 23 | void testConvertToolExecutionResultMessageToValue() { 24 | ToolExecutionResultMessage message = new ToolExecutionResultMessage( 25 | "id", "toolName", "text"); 26 | TypeDescriptor sourceType = TypeDescriptor.valueOf(ToolExecutionResultMessage.class); 27 | TypeDescriptor targetType = TypeDescriptor.valueOf(Value.class); 28 | 29 | Value result = (Value) converter.convert(message, sourceType, targetType); 30 | 31 | String[] expectedResult = {"id", "toolName", "text"}; 32 | assertArrayEquals(expectedResult, result.asList().toArray(String[]::new)); 33 | } 34 | 35 | @Test 36 | void testConvertValueToToolExecutionResultMessage() { 37 | String[] attributes = {"id", "toolName", "text"}; 38 | Value value = Values.value(attributes); 39 | TypeDescriptor sourceType = TypeDescriptor.valueOf(Value.class); 40 | TypeDescriptor targetType = TypeDescriptor.valueOf(ToolExecutionResultMessage.class); 41 | 42 | ToolExecutionResultMessage result = (ToolExecutionResultMessage) converter.convert(value, sourceType, targetType); 43 | 44 | assertEquals("id", result.id()); 45 | assertEquals("toolName", result.toolName()); 46 | assertEquals("text", result.text()); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/controller/openai/ChatCompletionsController.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.controller.openai; 2 | 3 | import com.telekom.ai4coding.chatbot.service.ChatCompletionsService; 4 | import com.telekom.ai4coding.openai.completions.ChatApi; 5 | import com.theokanning.openai.completion.chat.ChatCompletionRequest; 6 | import com.theokanning.openai.completion.chat.ChatCompletionResult; 7 | import jakarta.validation.Valid; 8 | import lombok.RequiredArgsConstructor; 9 | import org.springframework.data.util.Pair; 10 | import org.springframework.http.ResponseEntity; 11 | import org.springframework.web.bind.annotation.*; 12 | 13 | @CrossOrigin(exposedHeaders = "Conversation-Id") 14 | @RestController 15 | @RequiredArgsConstructor 16 | @RequestMapping("/v1") 17 | public class ChatCompletionsController implements ChatApi { 18 | 19 | private final ChatCompletionsService chatCompletionsService; 20 | 21 | @Override 22 | public ResponseEntity createChatCompletion( 23 | @Valid @RequestBody ChatCompletionRequest createChatCompletionRequest, 24 | @RequestHeader(value = "Persist-Conversation", required = false) Boolean persistConversation, 25 | @RequestHeader(value = "Conversation-Id", required = false) String conversationId) { 26 | 27 | ChatCompletionResult result; 28 | ResponseEntity.BodyBuilder responseBuilder = ResponseEntity.ok(); 29 | 30 | if ((persistConversation != null && persistConversation) || conversationId != null) { 31 | Pair chatCompletionResultLongPair = chatCompletionsService 32 | .chatWithPersistence(createChatCompletionRequest, conversationId); 33 | result = chatCompletionResultLongPair.getFirst(); 34 | 35 | String persistedConversationId = chatCompletionResultLongPair.getSecond(); 36 | 37 | responseBuilder.header("Conversation-Id", persistedConversationId); 38 | } else { 39 | return ResponseEntity.ok(chatCompletionsService.chatWithoutPersistence(createChatCompletionRequest)); 40 | } 41 | 42 | return responseBuilder.body(result); 43 | } 44 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/utils/TitleGenerator.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.utils; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | public class TitleGenerator { 8 | 9 | private static final List IGNORE_WORDS = 10 | Arrays.asList("the", "i", "you", "how", "can", "is", "hi","hello","hey", "in", "at", "of", "and", "a", 11 | "to", "it", "for", "on", "with", "as", "by", "an", "be", "this", "that", "which", "or", "from", 12 | "are", "was", "were", "will", "would", "should", "could", "has", "have", "had", "do", "does", 13 | "did", "but", "if", "then", "than", "so", "such", "not", "no", "yes", "he", "she", "they", 14 | "we", "us", "them", "his", "her", "their", "our", "my", "your", "its", "me", "him", "who", 15 | "whom", "whose", "what", "when", "where", "why", "how", "all", "any", "both", "each", "few", 16 | "many", "most", "some", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", 17 | "ten", "first", "second", "third", "about", "after", "again", "against", "between", "into", 18 | "through", "during", "before", "under", "over", "above", "below", "up", "down", "out", "off", 19 | "over", "under","there"); 20 | 21 | 22 | public static String generateTitle(String prompt) { 23 | String cleanedMessage = prompt.replaceAll("[^a-zA-Z0-9\\s]", "").toLowerCase(); 24 | 25 | List tokens = Arrays.asList(cleanedMessage.split("\\s+")); 26 | 27 | List keyPhrases = tokens.stream().filter(token -> !IGNORE_WORDS.contains(token)).toList(); 28 | 29 | String title = String.join(" ", keyPhrases); 30 | 31 | title = !title.isEmpty() ? 32 | Arrays.stream(title.split("\\s+")) 33 | .map(word -> word.substring(0, 1).toUpperCase() + word.substring(1)) 34 | .collect(Collectors.joining(" ")) 35 | : "New Conversation"; 36 | 37 | return title.substring(0, Math.min(title.length(), 27)).trim(); 38 | } 39 | } 40 | 41 | 42 | -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/ErrorResponse.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import io.swagger.v3.oas.annotations.media.Schema; 5 | import jakarta.annotation.Generated; 6 | import jakarta.validation.Valid; 7 | import jakarta.validation.constraints.NotNull; 8 | 9 | import java.util.Objects; 10 | 11 | /** 12 | * ErrorResponse 13 | */ 14 | 15 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 16 | public class ErrorResponse { 17 | 18 | private Error error; 19 | 20 | public ErrorResponse() { 21 | super(); 22 | } 23 | 24 | /** 25 | * Constructor with only required parameters 26 | */ 27 | public ErrorResponse(Error error) { 28 | this.error = error; 29 | } 30 | 31 | public ErrorResponse error(Error error) { 32 | this.error = error; 33 | return this; 34 | } 35 | 36 | /** 37 | * Get error 38 | * @return error 39 | */ 40 | @NotNull @Valid 41 | @Schema(name = "error", requiredMode = Schema.RequiredMode.REQUIRED) 42 | @JsonProperty("error") 43 | public Error getError() { 44 | return error; 45 | } 46 | 47 | public void setError(Error error) { 48 | this.error = error; 49 | } 50 | 51 | @Override 52 | public boolean equals(Object o) { 53 | if (this == o) { 54 | return true; 55 | } 56 | if (o == null || getClass() != o.getClass()) { 57 | return false; 58 | } 59 | ErrorResponse errorResponse = (ErrorResponse) o; 60 | return Objects.equals(this.error, errorResponse.error); 61 | } 62 | 63 | @Override 64 | public int hashCode() { 65 | return Objects.hash(error); 66 | } 67 | 68 | @Override 69 | public String toString() { 70 | StringBuilder sb = new StringBuilder(); 71 | sb.append("class ErrorResponse {\n"); 72 | sb.append(" error: ").append(toIndentedString(error)).append("\n"); 73 | sb.append("}"); 74 | return sb.toString(); 75 | } 76 | 77 | /** 78 | * Convert the given object to string with each line indented by 4 spaces 79 | * (except the first line). 80 | */ 81 | private String toIndentedString(Object o) { 82 | if (o == null) { 83 | return "null"; 84 | } 85 | return o.toString().replace("\n", "\n "); 86 | } 87 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/treesitter/FileType.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.treesitter; 2 | 3 | import java.nio.file.Paths; 4 | 5 | public enum FileType { 6 | OTHER, 7 | BASH(".sh"), 8 | C(".c"), 9 | COMMONLISP(".lisp", ".lsp", ".l", ".cl"), 10 | CSHARP(".cs"), 11 | DOCKERFILE("Dockerfile", ".dockerfile"), 12 | FORTRAN(".f"), 13 | GO(".go"), 14 | HTML(".html"), 15 | JAVA(".java"), 16 | JAVASCRIPT(".js", ".jsx"), 17 | MAKE("Makefile"), 18 | MARKDOWN(".md"), 19 | PERL(".pl"), 20 | PHP(".php"), 21 | PYTHON(".py"), 22 | R(".r"), 23 | RUST(".rs"), 24 | SQL(".sql"), 25 | SWIFT(".swift"), 26 | TYPESCRIPT(".ts",".tsx"), 27 | VISUALBASIC(".vb"), 28 | VBSCRIPT(".vbs"), 29 | YAML(".yaml", ".yml"), 30 | JSON(".json", ".map", ".topojson", ".geojson"); 31 | 32 | private final String[] extensions; 33 | 34 | FileType(String... extensions) { 35 | this.extensions = extensions; 36 | } 37 | 38 | public static FileType fromFileName(String filename) { 39 | if(filename == null){ 40 | return OTHER; 41 | } 42 | 43 | //Making sure we only use the base fileName even if the method is called wrongly with a file path instead of only the base filename 44 | String baseFilename = Paths.get(filename).getFileName().toString(); 45 | System.out.println(baseFilename); 46 | // Special cases for Dockerfile and Makefile: must match exactly "Dockerfile" or "Makefile" with case sensitivity 47 | if (baseFilename.equals("Dockerfile")) { 48 | return DOCKERFILE; 49 | } else if (baseFilename.equals("Makefile")) { 50 | return MAKE; 51 | } 52 | 53 | // For all other file types, check case-insensitively 54 | String lowerCaseFilename = baseFilename.toLowerCase(); 55 | for (FileType fileType : FileType.values()) { 56 | if (fileType == MAKE) { 57 | continue; 58 | } 59 | for (String extension : fileType.extensions) { 60 | if (lowerCaseFilename.endsWith(extension)) { 61 | return fileType; 62 | } 63 | } 64 | } 65 | return OTHER; 66 | } 67 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateTranslationResponse.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import io.swagger.v3.oas.annotations.media.Schema; 5 | import jakarta.annotation.Generated; 6 | import jakarta.validation.constraints.NotNull; 7 | 8 | import java.util.Objects; 9 | 10 | /** 11 | * CreateTranslationResponse 12 | */ 13 | 14 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 15 | public class CreateTranslationResponse { 16 | 17 | private String text; 18 | 19 | public CreateTranslationResponse() { 20 | super(); 21 | } 22 | 23 | /** 24 | * Constructor with only required parameters 25 | */ 26 | public CreateTranslationResponse(String text) { 27 | this.text = text; 28 | } 29 | 30 | public CreateTranslationResponse text(String text) { 31 | this.text = text; 32 | return this; 33 | } 34 | 35 | /** 36 | * Get text 37 | * @return text 38 | */ 39 | @NotNull 40 | @Schema(name = "text", requiredMode = Schema.RequiredMode.REQUIRED) 41 | @JsonProperty("text") 42 | public String getText() { 43 | return text; 44 | } 45 | 46 | public void setText(String text) { 47 | this.text = text; 48 | } 49 | 50 | @Override 51 | public boolean equals(Object o) { 52 | if (this == o) { 53 | return true; 54 | } 55 | if (o == null || getClass() != o.getClass()) { 56 | return false; 57 | } 58 | CreateTranslationResponse createTranslationResponse = (CreateTranslationResponse) o; 59 | return Objects.equals(this.text, createTranslationResponse.text); 60 | } 61 | 62 | @Override 63 | public int hashCode() { 64 | return Objects.hash(text); 65 | } 66 | 67 | @Override 68 | public String toString() { 69 | StringBuilder sb = new StringBuilder(); 70 | sb.append("class CreateTranslationResponse {\n"); 71 | sb.append(" text: ").append(toIndentedString(text)).append("\n"); 72 | sb.append("}"); 73 | return sb.toString(); 74 | } 75 | 76 | /** 77 | * Convert the given object to string with each line indented by 4 spaces 78 | * (except the first line). 79 | */ 80 | private String toIndentedString(Object o) { 81 | if (o == null) { 82 | return "null"; 83 | } 84 | return o.toString().replace("\n", "\n "); 85 | } 86 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/test/java/com/telekom/ai4coding/chatbot/utils/EmojiRegexTest.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.utils; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.nio.charset.StandardCharsets; 7 | 8 | public class EmojiRegexTest { 9 | 10 | 11 | @Test 12 | public void replaceEmojis_withEmojis() { 13 | String input = "Hello, this is a test 😊"; 14 | byte[] fileContent = input.getBytes(StandardCharsets.UTF_8); 15 | byte[] result = EmojiRegex.replaceEmojis(fileContent); 16 | String resultString = new String(result, StandardCharsets.UTF_8); 17 | Assertions.assertEquals("Hello, this is a test [Emoji]", resultString); 18 | } 19 | 20 | @Test 21 | public void replaceEmojis_withoutEmojis() { 22 | String input = "Hello, this is a test"; 23 | byte[] fileContent = input.getBytes(StandardCharsets.UTF_8); 24 | byte[] result = EmojiRegex.replaceEmojis(fileContent); 25 | String resultString = new String(result, StandardCharsets.UTF_8); 26 | Assertions.assertEquals(input, resultString); 27 | } 28 | 29 | @Test 30 | public void replaceEmojis_mixedContent() { 31 | String input = "Test 😊 and 😢 mixed"; 32 | byte[] fileContent = input.getBytes(StandardCharsets.UTF_8); 33 | byte[] result = EmojiRegex.replaceEmojis(fileContent); 34 | String resultString = new String(result, StandardCharsets.UTF_8); 35 | Assertions.assertEquals("Test [Emoji] and [Emoji] mixed", resultString); 36 | } 37 | 38 | @Test 39 | public void replaceEmojis_emptyString() { 40 | String input = ""; 41 | byte[] fileContent = input.getBytes(StandardCharsets.UTF_8); 42 | byte[] result = EmojiRegex.replaceEmojis(fileContent); 43 | String resultString = new String(result, StandardCharsets.UTF_8); 44 | Assertions.assertEquals(input, resultString); 45 | } 46 | 47 | @Test 48 | public void replaceEmojis_onlyEmojis() { 49 | String input = "😊😢😂"; 50 | byte[] fileContent = input.getBytes(StandardCharsets.UTF_8); 51 | byte[] result = EmojiRegex.replaceEmojis(fileContent); 52 | String resultString = new String(result, StandardCharsets.UTF_8); 53 | Assertions.assertEquals("[Emoji]", resultString); 54 | } 55 | 56 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateModerationRequestModel.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonTypeName; 4 | import io.swagger.v3.oas.annotations.media.Schema; 5 | import jakarta.annotation.Generated; 6 | 7 | import java.util.Objects; 8 | 9 | /** 10 | * Two content moderations models are available: `text-moderation-stable` and `text-moderation-latest`. The default is `text-moderation-latest` which will be automatically upgraded over time. This ensures you are always using our most accurate model. If you use `text-moderation-stable`, we will provide advanced notice before updating the model. Accuracy of `text-moderation-stable` may be slightly lower than for `text-moderation-latest`. 11 | */ 12 | 13 | @Schema(name = "CreateModerationRequest_model", description = "Two content moderations models are available: `text-moderation-stable` and `text-moderation-latest`. The default is `text-moderation-latest` which will be automatically upgraded over time. This ensures you are always using our most accurate model. If you use `text-moderation-stable`, we will provide advanced notice before updating the model. Accuracy of `text-moderation-stable` may be slightly lower than for `text-moderation-latest`. ") 14 | @JsonTypeName("CreateModerationRequest_model") 15 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 16 | public class CreateModerationRequestModel { 17 | 18 | @Override 19 | public boolean equals(Object o) { 20 | if (this == o) { 21 | return true; 22 | } 23 | if (o == null || getClass() != o.getClass()) { 24 | return false; 25 | } 26 | return true; 27 | } 28 | 29 | @Override 30 | public int hashCode() { 31 | return Objects.hash(); 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | StringBuilder sb = new StringBuilder(); 37 | sb.append("class CreateModerationRequestModel {\n"); 38 | sb.append("}"); 39 | return sb.toString(); 40 | } 41 | 42 | /** 43 | * Convert the given object to string with each line indented by 4 spaces 44 | * (except the first line). 45 | */ 46 | private String toIndentedString(Object o) { 47 | if (o == null) { 48 | return "null"; 49 | } 50 | return o.toString().replace("\n", "\n "); 51 | } 52 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateTranscriptionResponse.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import io.swagger.v3.oas.annotations.media.Schema; 5 | import jakarta.annotation.Generated; 6 | import jakarta.validation.constraints.NotNull; 7 | 8 | import java.util.Objects; 9 | 10 | /** 11 | * CreateTranscriptionResponse 12 | */ 13 | 14 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 15 | public class CreateTranscriptionResponse { 16 | 17 | private String text; 18 | 19 | public CreateTranscriptionResponse() { 20 | super(); 21 | } 22 | 23 | /** 24 | * Constructor with only required parameters 25 | */ 26 | public CreateTranscriptionResponse(String text) { 27 | this.text = text; 28 | } 29 | 30 | public CreateTranscriptionResponse text(String text) { 31 | this.text = text; 32 | return this; 33 | } 34 | 35 | /** 36 | * Get text 37 | * @return text 38 | */ 39 | @NotNull 40 | @Schema(name = "text", requiredMode = Schema.RequiredMode.REQUIRED) 41 | @JsonProperty("text") 42 | public String getText() { 43 | return text; 44 | } 45 | 46 | public void setText(String text) { 47 | this.text = text; 48 | } 49 | 50 | @Override 51 | public boolean equals(Object o) { 52 | if (this == o) { 53 | return true; 54 | } 55 | if (o == null || getClass() != o.getClass()) { 56 | return false; 57 | } 58 | CreateTranscriptionResponse createTranscriptionResponse = (CreateTranscriptionResponse) o; 59 | return Objects.equals(this.text, createTranscriptionResponse.text); 60 | } 61 | 62 | @Override 63 | public int hashCode() { 64 | return Objects.hash(text); 65 | } 66 | 67 | @Override 68 | public String toString() { 69 | StringBuilder sb = new StringBuilder(); 70 | sb.append("class CreateTranscriptionResponse {\n"); 71 | sb.append(" text: ").append(toIndentedString(text)).append("\n"); 72 | sb.append("}"); 73 | return sb.toString(); 74 | } 75 | 76 | /** 77 | * Convert the given object to string with each line indented by 4 spaces 78 | * (except the first line). 79 | */ 80 | private String toIndentedString(Object o) { 81 | if (o == null) { 82 | return "null"; 83 | } 84 | return o.toString().replace("\n", "\n "); 85 | } 86 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/test/java/com/telekom/ai4coding/chatbot/graph/KnowledgeGraphBatchInsertServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.graph; 2 | 3 | import lombok.SneakyThrows; 4 | import org.junit.jupiter.api.Test; 5 | import org.junit.jupiter.api.io.TempDir; 6 | import org.mockito.Mock; 7 | import org.neo4j.driver.Driver; 8 | import org.neo4j.driver.Session; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.test.mock.mockito.MockBean; 11 | 12 | import com.telekom.ai4coding.chatbot.BaseIntegrationTest; 13 | 14 | import dev.langchain4j.data.embedding.Embedding; 15 | import dev.langchain4j.model.embedding.EmbeddingModel; 16 | import dev.langchain4j.model.output.Response; 17 | 18 | import java.io.File; 19 | 20 | import static org.mockito.ArgumentMatchers.any; 21 | import static org.mockito.ArgumentMatchers.anyString; 22 | import static org.mockito.Mockito.times; 23 | import static org.mockito.Mockito.verify; 24 | import static org.mockito.Mockito.when; 25 | 26 | /** 27 | * This is a smoke test. Main integration test which tests the DB structure after graph creation 28 | * is in the {@link com.telekom.ai4coding.chatbot.tools.graph.GraphRetrievalTest} 29 | */ 30 | class KnowledgeGraphBatchInsertServiceTest extends BaseIntegrationTest { 31 | 32 | @TempDir 33 | static File tempDir; 34 | 35 | @MockBean 36 | private Driver mockDriver; 37 | 38 | @Mock 39 | private Session mockSession; 40 | 41 | @MockBean 42 | private EmbeddingModel embeddingModel; 43 | 44 | @Autowired 45 | private KnowledgeGraphBatchInsertService batchInsertService; 46 | 47 | @Autowired 48 | KnowledgeGraphBuilder knowledgeGraphBuilder; 49 | 50 | @SneakyThrows 51 | @Test 52 | void testBatchInsertFileStructure() { 53 | when(mockDriver.session()).thenReturn(mockSession).thenReturn(mockSession); 54 | when(mockSession.executeWrite(any())).thenReturn(null); 55 | Embedding mockEmbedding = Embedding.from(new float[]{0.5f, 0.5f}); 56 | Response mockResponse = Response.from(mockEmbedding); 57 | when(embeddingModel.embed(anyString())).thenReturn(mockResponse); 58 | 59 | batchInsertService.batchInsertFileStructure(KnowledgeGraphSetup.setup(knowledgeGraphBuilder, tempDir).getRootFileNode(), 1); 60 | 61 | verify(mockDriver, times(2)).session(); 62 | verify(mockSession, times(2)).executeWrite(any()); 63 | } 64 | 65 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/controller/RepositoriesController.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.controller; 2 | 3 | import com.telekom.ai4coding.chatbot.service.RepositoryService; 4 | import lombok.RequiredArgsConstructor; 5 | import org.springframework.http.ResponseEntity; 6 | import org.springframework.web.bind.annotation.*; 7 | 8 | 9 | @CrossOrigin 10 | @RestController 11 | @RequiredArgsConstructor 12 | @RequestMapping("/v1/repositories") 13 | public class RepositoriesController { 14 | 15 | public final RepositoryService repositoryService; 16 | 17 | /** 18 | * Uploads a GitLab repository identified by the project ID. 19 | * @param projectId the ID of the GitLab project to upload 20 | * @return ResponseEntity with the operation result 21 | */ 22 | @PostMapping("/gitlab/{projectId}") 23 | public ResponseEntity uploadGitlabRepository(@PathVariable String projectId) { 24 | return repositoryService.uploadGitlabRepository(projectId); 25 | } 26 | 27 | /** 28 | * Uploads a local repository identified by the local path. 29 | * @param localPath the path of the local repository to upload 30 | * @return ResponseEntity with the operation result 31 | * @consumes text/plain 32 | */ 33 | @PostMapping(value="/local", consumes = "text/plain") 34 | public ResponseEntity uploadLocalRepository(@RequestBody String localPath) { 35 | return repositoryService.uploadLocalRepository(localPath); 36 | } 37 | 38 | /** 39 | * Refreshes a GitLab repository identified by the project ID. 40 | * @param projectId the ID of the GitLab project to refresh 41 | * @return ResponseEntity with the operation result 42 | */ 43 | @PutMapping("/gitlab/{projectId}/refresh") 44 | public ResponseEntity refreshRepository(@PathVariable String projectId) { 45 | return repositoryService.refreshGitlabRepository(projectId); 46 | } 47 | 48 | /** 49 | * Refreshes a local repository identified by the local path. 50 | * @param localPath the path of the local repository to refresh 51 | * @return ResponseEntity with the operation result 52 | * @consumes text/plain 53 | */ 54 | @PutMapping(value="/local/refresh" , consumes = "text/plain") 55 | public ResponseEntity refreshLocalRepository(@RequestBody String localPath) { 56 | return repositoryService.refreshLocalRepository(localPath); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/test/java/com/telekom/ai4coding/chatbot/graph/TextNodeTest.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.graph; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | public class TextNodeTest { 8 | 9 | @Test 10 | public void testTextNodeCreationWithoutNextNode() { 11 | // Given 12 | String text = "Ich bin ein Test Text"; 13 | String metadata = "Test metadata"; 14 | 15 | // When 16 | TextNode textNode = TextNode.of(text, metadata, null); 17 | 18 | // Then 19 | assertThat(textNode.getText()).isEqualTo(text); 20 | assertThat(textNode.getMetadata()).isEqualTo(metadata); 21 | assertThat(textNode.getNextTextNode()).isNull(); 22 | } 23 | 24 | @Test 25 | public void testTextNodeCreationWithNextNode() { 26 | // Given 27 | String text1 = "Test Text 1"; 28 | String metadata1 = "Test metadata 1"; 29 | String text2 = "Test Text 2"; 30 | String metadata2 = "Test metadata 2"; 31 | 32 | TextNode nextNode = TextNode.of(text2, metadata2, null); 33 | 34 | // When 35 | TextNode textNode = TextNode.of(text1, metadata1, null, nextNode); 36 | 37 | // Then 38 | assertThat(textNode.getText()).isEqualTo(text1); 39 | assertThat(textNode.getMetadata()).isEqualTo(metadata1); 40 | assertThat(textNode.getNextTextNode()).isEqualTo(nextNode); 41 | } 42 | 43 | @Test 44 | public void testEqualsMethod() { 45 | // Given 46 | TextNode node1 = TextNode.of("Test Text", "Test Metadata", null); 47 | TextNode node2 = TextNode.of("Test Text", "Test Metadata", null); 48 | TextNode node3 = TextNode.of("Different Text", "Test Metadata", null); 49 | TextNode node4 = TextNode.of("Test Text", "Different Metadata", null); 50 | 51 | // Then 52 | assertThat(node1).isEqualTo(node2); 53 | assertThat(node1).isNotEqualTo(node3); 54 | assertThat(node1).isNotEqualTo(node4); 55 | } 56 | 57 | @Test 58 | public void testNextTextNodeSetter() { 59 | // Given 60 | TextNode node1 = TextNode.of("Test Text 1", "Test Metadata 1", null); 61 | TextNode node2 = TextNode.of("Test Text 2", "Test Metadata 2", null); 62 | 63 | // When 64 | node1.setNextTextNode(node2); // Accessible due to package-private access 65 | 66 | // Then 67 | assertThat(node1.getNextTextNode()).isEqualTo(node2); 68 | } 69 | } 70 | 71 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/graph/TextNode.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.graph; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | import org.springframework.data.neo4j.core.schema.GeneratedValue; 8 | import org.springframework.data.neo4j.core.schema.Id; 9 | import org.springframework.data.neo4j.core.schema.Node; 10 | import org.springframework.data.neo4j.core.schema.Relationship; 11 | 12 | 13 | /** 14 | * Represents a piece of text. 15 | */ 16 | @AllArgsConstructor 17 | @Getter 18 | @Node 19 | public class TextNode { 20 | @Id 21 | @GeneratedValue 22 | private final Long id; 23 | 24 | private final String text; 25 | private final String metadata; 26 | 27 | // A vector of numbers representing the semantic meaning of the TextNode generated 28 | // from an embedding model. 29 | // This has to be double, because float in neo4j is double in Java. 30 | // But the embedding model will generate float[] in Java, we need to convert them 31 | // into Java double[]. 32 | // https://neo4j.com/docs/java-reference/current/extending-neo4j/values-and-types/ 33 | private final double[] embedding; 34 | 35 | /** 36 | * An edge from a TextNode to the next TextNode that contains continuation of the text. 37 | * Mutating a Node for performance, but has to stay only package accessible! 38 | * https://docs.spring.io/spring-data/neo4j/reference/object-mapping/sdc-object-mapping.html#mapping.fundamentals.recommendations 39 | */ 40 | @Setter(AccessLevel.PACKAGE) 41 | @Relationship(type = "NEXT_CHUNK", direction = Relationship.Direction.OUTGOING) 42 | private TextNode nextTextNode; 43 | 44 | public static TextNode of(final String text, final String metadata, final double[] embedding, final TextNode nextTextNode) { 45 | return new TextNode(null, text, metadata, embedding, nextTextNode); 46 | } 47 | 48 | public static TextNode of(final String text, final String metadata, final double[] embedding) { 49 | return new TextNode(null, text, metadata, embedding, null); 50 | } 51 | 52 | 53 | @Override 54 | public boolean equals(Object obj) { 55 | if (this == obj) { 56 | return true; 57 | } 58 | 59 | if (obj == null || getClass() != obj.getClass()) { 60 | return false; 61 | } 62 | 63 | TextNode other = (TextNode) obj; 64 | return text.equals(other.text) && metadata.equals(other.metadata); 65 | } 66 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/configuration/agent/GeneralAgent.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.configuration.agent; 2 | 3 | import dev.langchain4j.service.MemoryId; 4 | import dev.langchain4j.service.SystemMessage; 5 | import dev.langchain4j.service.UserMessage; 6 | 7 | public interface GeneralAgent { 8 | @SystemMessage({""" 9 | You are an assistant for finding the right context to a user query from 10 | a codebase and answers the question. The codebase is pre-processed and 11 | stored as a graph in a Neo4J graph database. You have access to different 12 | tools that you must use to do a step by step traversal of the graph database 13 | until you found the right context. You should also look into related files or nodes 14 | to the relevanet files to ensure that you covers all the relevant context. 15 | 16 | The codebase graph stored in the Neo4J graph database is built by having 17 | FileNode representing a file, ASTNode representing a tree-sitter 18 | AST node, and TextNode representing a piece of text in a file that is most 19 | likely code documentation. FileNode has attribute (id, basename, relativePath), 20 | where id is a id that can uniquely identify a node, basename 21 | is the basename of the file (like 'foo.py' or 'src'), and relativePath 22 | is the relative path relative to the root (like 'foo/bar/baz.java'). 23 | ASTNode has attribute (id, type, startLine, endLine, text), 24 | where id is a id that can uniquely identify a node, type is the 25 | tree-sitter node type, startLine is the starting line number in the file 26 | for the node, endLine is the ending line number in the file for the node, 27 | and text is the corresponding source code of the node. TextNode has attribute 28 | (id, text, metadata), where id is a id that can uniquely identify a node, 29 | text is a piece of text, and metadata that is associated with the text. FileNode 30 | are connected to each other similar to a file system (FileNode of 'foo/bar/baz.java' 31 | and 'foo/bar/qux.cpp' will be children of FileNode of 'foo/bar'). ASTNode 32 | are connected to each other as the tree-sitter abstract syntax tree. TextNode 33 | are connected to each other in a chain in chronological order. FileNode 34 | that are source code will be connected to the root of the corresponding ASTNode 35 | (The root ASTNode for source code in 'foo/bar/baz.java' will be the children 36 | of FileNode of 'foo/bar/baz.java'). FileNode that does not contain source code 37 | can also be connected to TextNode if they contain code documentation. 38 | \s"""}) 39 | String chat(@MemoryId String memoryId, @UserMessage String userMessage); 40 | } 41 | -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/ChatCompletionNamedToolChoiceFunction.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.fasterxml.jackson.annotation.JsonTypeName; 5 | import io.swagger.v3.oas.annotations.media.Schema; 6 | import jakarta.annotation.Generated; 7 | import jakarta.validation.constraints.NotNull; 8 | 9 | import java.util.Objects; 10 | 11 | /** 12 | * ChatCompletionNamedToolChoiceFunction 13 | */ 14 | 15 | @JsonTypeName("ChatCompletionNamedToolChoice_function") 16 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 17 | public class ChatCompletionNamedToolChoiceFunction { 18 | 19 | private String name; 20 | 21 | public ChatCompletionNamedToolChoiceFunction() { 22 | super(); 23 | } 24 | 25 | /** 26 | * Constructor with only required parameters 27 | */ 28 | public ChatCompletionNamedToolChoiceFunction(String name) { 29 | this.name = name; 30 | } 31 | 32 | public ChatCompletionNamedToolChoiceFunction name(String name) { 33 | this.name = name; 34 | return this; 35 | } 36 | 37 | /** 38 | * The name of the function to call. 39 | * @return name 40 | */ 41 | @NotNull 42 | @Schema(name = "name", description = "The name of the function to call.", requiredMode = Schema.RequiredMode.REQUIRED) 43 | @JsonProperty("name") 44 | public String getName() { 45 | return name; 46 | } 47 | 48 | public void setName(String name) { 49 | this.name = name; 50 | } 51 | 52 | @Override 53 | public boolean equals(Object o) { 54 | if (this == o) { 55 | return true; 56 | } 57 | if (o == null || getClass() != o.getClass()) { 58 | return false; 59 | } 60 | ChatCompletionNamedToolChoiceFunction chatCompletionNamedToolChoiceFunction = (ChatCompletionNamedToolChoiceFunction) o; 61 | return Objects.equals(this.name, chatCompletionNamedToolChoiceFunction.name); 62 | } 63 | 64 | @Override 65 | public int hashCode() { 66 | return Objects.hash(name); 67 | } 68 | 69 | @Override 70 | public String toString() { 71 | StringBuilder sb = new StringBuilder(); 72 | sb.append("class ChatCompletionNamedToolChoiceFunction {\n"); 73 | sb.append(" name: ").append(toIndentedString(name)).append("\n"); 74 | sb.append("}"); 75 | return sb.toString(); 76 | } 77 | 78 | /** 79 | * Convert the given object to string with each line indented by 4 spaces 80 | * (except the first line). 81 | */ 82 | private String toIndentedString(Object o) { 83 | if (o == null) { 84 | return "null"; 85 | } 86 | return o.toString().replace("\n", "\n "); 87 | } 88 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/controller/ConversationController.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.controller; 2 | 3 | import com.telekom.ai4coding.chatbot.repository.conversation.ConversationNode; 4 | import com.telekom.ai4coding.chatbot.service.ConversationService; 5 | import lombok.RequiredArgsConstructor; 6 | import org.springframework.http.HttpStatus; 7 | import org.springframework.http.ResponseEntity; 8 | import org.springframework.util.StringUtils; 9 | import org.springframework.web.bind.annotation.*; 10 | 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | @CrossOrigin 15 | @RestController 16 | @RequiredArgsConstructor 17 | @RequestMapping("/v1/conversations") 18 | public class ConversationController { 19 | 20 | private final ConversationService conversationService; 21 | 22 | @GetMapping("/{conversationId}") 23 | public ResponseEntity> getConversation(@PathVariable String conversationId) { 24 | return ResponseEntity.ok(conversationService.getConversation(conversationId)); 25 | } 26 | 27 | @GetMapping 28 | public ResponseEntity>> getConversations() { 29 | return ResponseEntity.ok(conversationService.getAllConversations()); 30 | } 31 | 32 | @GetMapping("/{conversationId}/messages") 33 | public ResponseEntity>> getConversationMessages(@PathVariable String conversationId) { 34 | return ResponseEntity.ok(conversationService.getConversationMessages(conversationId)); 35 | } 36 | 37 | @DeleteMapping("/{conversationId}") 38 | public ResponseEntity deleteConversation(@PathVariable String conversationId) { 39 | conversationService.deleteConversation(conversationId); 40 | return ResponseEntity.ok().build(); 41 | } 42 | 43 | @PatchMapping("/{conversationId}/rename") 44 | public ResponseEntity renameConversation(@PathVariable String conversationId, @RequestParam("newTitle") String newTitle) { 45 | if (!StringUtils.hasText(newTitle)) { 46 | return ResponseEntity.badRequest().body("New title cannot be empty."); 47 | } else { 48 | try { 49 | String updatedTitle = conversationService.renameConversation(conversationId, newTitle); 50 | return ResponseEntity.ok(updatedTitle); 51 | } catch (IllegalArgumentException e) { 52 | return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage()); 53 | } catch (Exception e) { 54 | return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An error occurred while renaming the conversation."); 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateAssistantFileRequest.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import io.swagger.v3.oas.annotations.media.Schema; 5 | import jakarta.annotation.Generated; 6 | import jakarta.validation.constraints.NotNull; 7 | 8 | import java.util.Objects; 9 | 10 | /** 11 | * CreateAssistantFileRequest 12 | */ 13 | 14 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 15 | public class CreateAssistantFileRequest { 16 | 17 | private String fileId; 18 | 19 | public CreateAssistantFileRequest() { 20 | super(); 21 | } 22 | 23 | /** 24 | * Constructor with only required parameters 25 | */ 26 | public CreateAssistantFileRequest(String fileId) { 27 | this.fileId = fileId; 28 | } 29 | 30 | public CreateAssistantFileRequest fileId(String fileId) { 31 | this.fileId = fileId; 32 | return this; 33 | } 34 | 35 | /** 36 | * A [File](/docs/api-reference/files) ID (with `purpose=\"assistants\"`) that the assistant should use. Useful for tools like `retrieval` and `code_interpreter` that can access files. 37 | * @return fileId 38 | */ 39 | @NotNull 40 | @Schema(name = "file_id", description = "A [File](/docs/api-reference/files) ID (with `purpose=\"assistants\"`) that the assistant should use. Useful for tools like `retrieval` and `code_interpreter` that can access files.", requiredMode = Schema.RequiredMode.REQUIRED) 41 | @JsonProperty("file_id") 42 | public String getFileId() { 43 | return fileId; 44 | } 45 | 46 | public void setFileId(String fileId) { 47 | this.fileId = fileId; 48 | } 49 | 50 | @Override 51 | public boolean equals(Object o) { 52 | if (this == o) { 53 | return true; 54 | } 55 | if (o == null || getClass() != o.getClass()) { 56 | return false; 57 | } 58 | CreateAssistantFileRequest createAssistantFileRequest = (CreateAssistantFileRequest) o; 59 | return Objects.equals(this.fileId, createAssistantFileRequest.fileId); 60 | } 61 | 62 | @Override 63 | public int hashCode() { 64 | return Objects.hash(fileId); 65 | } 66 | 67 | @Override 68 | public String toString() { 69 | StringBuilder sb = new StringBuilder(); 70 | sb.append("class CreateAssistantFileRequest {\n"); 71 | sb.append(" fileId: ").append(toIndentedString(fileId)).append("\n"); 72 | sb.append("}"); 73 | return sb.toString(); 74 | } 75 | 76 | /** 77 | * Convert the given object to string with each line indented by 4 spaces 78 | * (except the first line). 79 | */ 80 | private String toIndentedString(Object o) { 81 | if (o == null) { 82 | return "null"; 83 | } 84 | return o.toString().replace("\n", "\n "); 85 | } 86 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/test/java/com/telekom/ai4coding/chatbot/controller/openai/Neo4JDatabaseControllerIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.controller.openai; 2 | 3 | import com.telekom.ai4coding.chatbot.service.Neo4JDatabaseService; 4 | import org.junit.jupiter.api.BeforeEach; 5 | import org.junit.jupiter.api.Test; 6 | import org.mockito.Mockito; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 9 | import org.springframework.boot.test.mock.mockito.MockBean; 10 | import org.springframework.http.MediaType; 11 | import org.springframework.test.web.servlet.MockMvc; 12 | 13 | import static org.mockito.Mockito.times; 14 | import static org.mockito.Mockito.verify; 15 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; 16 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 17 | 18 | @WebMvcTest(controllers = Neo4JDatabaseController.class) 19 | public class Neo4JDatabaseControllerIntegrationTest { 20 | 21 | @Autowired 22 | private MockMvc mockMvc; 23 | 24 | @MockBean 25 | private Neo4JDatabaseService neo4JDatabaseService; 26 | 27 | @BeforeEach 28 | void setUp() { 29 | // Reset mock before each test case to avoid side effects between tests 30 | Mockito.reset(neo4JDatabaseService); 31 | } 32 | 33 | @Test 34 | void givenValidRequest_whenCleanupDatabase_thenReturnStatusOk() throws Exception { 35 | // Given: No specific setup is needed here as the service will succeed 36 | 37 | // When: Performing the DELETE request to the /cleanup endpoint 38 | mockMvc.perform(delete("/v1/graphdb/cleanup") 39 | .contentType(MediaType.APPLICATION_JSON)) 40 | .andExpect(status().isOk()); 41 | 42 | // Then: Verify that the service method was called exactly once 43 | verify(neo4JDatabaseService, times(1)).cleanupDatabase(); 44 | } 45 | 46 | @Test 47 | void givenServiceThrowsException_whenCleanupDatabase_thenReturnServerError() throws Exception { 48 | // Given: The service throws a RuntimeException when cleanupDatabase is called 49 | Mockito.doThrow(new RuntimeException("Database error")).when(neo4JDatabaseService).cleanupDatabase(); 50 | 51 | // When: Performing the DELETE request to the /cleanup endpoint 52 | mockMvc.perform(delete("/v1/graphdb/cleanup") 53 | .contentType(MediaType.APPLICATION_JSON)) 54 | .andExpect(status().isInternalServerError()); 55 | 56 | // Then: Verify that the service method was still called exactly once 57 | verify(neo4JDatabaseService, times(1)).cleanupDatabase(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/MessageContentImageFileObjectImageFile.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.fasterxml.jackson.annotation.JsonTypeName; 5 | import io.swagger.v3.oas.annotations.media.Schema; 6 | import jakarta.annotation.Generated; 7 | import jakarta.validation.constraints.NotNull; 8 | 9 | import java.util.Objects; 10 | 11 | /** 12 | * MessageContentImageFileObjectImageFile 13 | */ 14 | 15 | @JsonTypeName("MessageContentImageFileObject_image_file") 16 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 17 | public class MessageContentImageFileObjectImageFile { 18 | 19 | private String fileId; 20 | 21 | public MessageContentImageFileObjectImageFile() { 22 | super(); 23 | } 24 | 25 | /** 26 | * Constructor with only required parameters 27 | */ 28 | public MessageContentImageFileObjectImageFile(String fileId) { 29 | this.fileId = fileId; 30 | } 31 | 32 | public MessageContentImageFileObjectImageFile fileId(String fileId) { 33 | this.fileId = fileId; 34 | return this; 35 | } 36 | 37 | /** 38 | * The [File](/docs/api-reference/files) ID of the image in the message content. 39 | * @return fileId 40 | */ 41 | @NotNull 42 | @Schema(name = "file_id", description = "The [File](/docs/api-reference/files) ID of the image in the message content.", requiredMode = Schema.RequiredMode.REQUIRED) 43 | @JsonProperty("file_id") 44 | public String getFileId() { 45 | return fileId; 46 | } 47 | 48 | public void setFileId(String fileId) { 49 | this.fileId = fileId; 50 | } 51 | 52 | @Override 53 | public boolean equals(Object o) { 54 | if (this == o) { 55 | return true; 56 | } 57 | if (o == null || getClass() != o.getClass()) { 58 | return false; 59 | } 60 | MessageContentImageFileObjectImageFile messageContentImageFileObjectImageFile = (MessageContentImageFileObjectImageFile) o; 61 | return Objects.equals(this.fileId, messageContentImageFileObjectImageFile.fileId); 62 | } 63 | 64 | @Override 65 | public int hashCode() { 66 | return Objects.hash(fileId); 67 | } 68 | 69 | @Override 70 | public String toString() { 71 | StringBuilder sb = new StringBuilder(); 72 | sb.append("class MessageContentImageFileObjectImageFile {\n"); 73 | sb.append(" fileId: ").append(toIndentedString(fileId)).append("\n"); 74 | sb.append("}"); 75 | return sb.toString(); 76 | } 77 | 78 | /** 79 | * Convert the given object to string with each line indented by 4 spaces 80 | * (except the first line). 81 | */ 82 | private String toIndentedString(Object o) { 83 | if (o == null) { 84 | return "null"; 85 | } 86 | return o.toString().replace("\n", "\n "); 87 | } 88 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/ChatCompletionFunctionCallOption.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import io.swagger.v3.oas.annotations.media.Schema; 5 | import jakarta.annotation.Generated; 6 | import jakarta.validation.constraints.NotNull; 7 | 8 | import java.util.Objects; 9 | 10 | /** 11 | * Specifying a particular function via `{\"name\": \"my_function\"}` forces the model to call that function. 12 | */ 13 | 14 | @Schema(name = "ChatCompletionFunctionCallOption", description = "Specifying a particular function via `{\"name\": \"my_function\"}` forces the model to call that function. ") 15 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 16 | public class ChatCompletionFunctionCallOption implements CreateChatCompletionRequestFunctionCall { 17 | 18 | private String name; 19 | 20 | public ChatCompletionFunctionCallOption() { 21 | super(); 22 | } 23 | 24 | /** 25 | * Constructor with only required parameters 26 | */ 27 | public ChatCompletionFunctionCallOption(String name) { 28 | this.name = name; 29 | } 30 | 31 | public ChatCompletionFunctionCallOption name(String name) { 32 | this.name = name; 33 | return this; 34 | } 35 | 36 | /** 37 | * The name of the function to call. 38 | * @return name 39 | */ 40 | @NotNull 41 | @Schema(name = "name", description = "The name of the function to call.", requiredMode = Schema.RequiredMode.REQUIRED) 42 | @JsonProperty("name") 43 | public String getName() { 44 | return name; 45 | } 46 | 47 | public void setName(String name) { 48 | this.name = name; 49 | } 50 | 51 | @Override 52 | public boolean equals(Object o) { 53 | if (this == o) { 54 | return true; 55 | } 56 | if (o == null || getClass() != o.getClass()) { 57 | return false; 58 | } 59 | ChatCompletionFunctionCallOption chatCompletionFunctionCallOption = (ChatCompletionFunctionCallOption) o; 60 | return Objects.equals(this.name, chatCompletionFunctionCallOption.name); 61 | } 62 | 63 | @Override 64 | public int hashCode() { 65 | return Objects.hash(name); 66 | } 67 | 68 | @Override 69 | public String toString() { 70 | StringBuilder sb = new StringBuilder(); 71 | sb.append("class ChatCompletionFunctionCallOption {\n"); 72 | sb.append(" name: ").append(toIndentedString(name)).append("\n"); 73 | sb.append("}"); 74 | return sb.toString(); 75 | } 76 | 77 | /** 78 | * Convert the given object to string with each line indented by 4 spaces 79 | * (except the first line). 80 | */ 81 | private String toIndentedString(Object o) { 82 | if (o == null) { 83 | return "null"; 84 | } 85 | return o.toString().replace("\n", "\n "); 86 | } 87 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/test/java/com/telekom/ai4coding/chatbot/graph/KnowledgeGraphTest.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.graph; 2 | 3 | import org.junit.jupiter.api.BeforeEach; 4 | import org.junit.jupiter.api.Test; 5 | import org.junit.jupiter.api.io.TempDir; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.mock.mockito.MockBean; 8 | 9 | import com.telekom.ai4coding.chatbot.BaseIntegrationTest; 10 | 11 | import dev.langchain4j.data.embedding.Embedding; 12 | import dev.langchain4j.model.embedding.EmbeddingModel; 13 | import dev.langchain4j.model.output.Response; 14 | 15 | import java.io.File; 16 | import java.io.IOException; 17 | 18 | import static org.junit.jupiter.api.Assertions.assertEquals; 19 | import static org.mockito.ArgumentMatchers.anyString; 20 | import static org.mockito.Mockito.when; 21 | 22 | 23 | public class KnowledgeGraphTest extends BaseIntegrationTest { 24 | @TempDir 25 | static File tempDir; 26 | 27 | KnowledgeGraph knowledgeGraph; 28 | 29 | @MockBean 30 | EmbeddingModel embeddingModel; 31 | 32 | @Autowired 33 | KnowledgeGraphBuilder knowledgeGraphBuilder; 34 | 35 | 36 | @BeforeEach 37 | void beforeEach() throws IOException { 38 | when(embeddingModel.dimension()).thenReturn(2); 39 | Embedding mockEmbedding = Embedding.from(new float[]{0.5f, 0.5f}); 40 | Response mockResponse = Response.from(mockEmbedding); 41 | when(embeddingModel.embed(anyString())).thenReturn(mockResponse); 42 | knowledgeGraph = KnowledgeGraphSetup.setup(knowledgeGraphBuilder, tempDir); 43 | } 44 | 45 | @Test 46 | public void testGetAllFileNodes() { 47 | assertEquals(9, knowledgeGraph.getAllFileNodes().size()); 48 | } 49 | 50 | @Test public void testGetAllAstNodes() { 51 | assertEquals(84, knowledgeGraph.getAllAstNodes().size()); 52 | } 53 | 54 | @Test public void testGetAllTextNodes() { 55 | assertEquals(2, knowledgeGraph.getAllTextNodes().size()); 56 | } 57 | 58 | @Test 59 | public void testGetFileTree() { 60 | String fileTree = knowledgeGraph.getFileTree(); 61 | String expectedFileTree = """ 62 | ├── foo 63 | │ ├── bar 64 | │ │ ├── test.c 65 | │ │ ├── test.java 66 | │ │ ├── test.pdf 67 | │ │ └── test.txt 68 | │ └── baz 69 | └── test.py"""; 70 | // We remove the first line because it contains the root directory name, 71 | // which is can be anything because we are using a temporary directory 72 | // in the test. 73 | fileTree = fileTree.substring(fileTree.indexOf('\n')+1); 74 | assertEquals(expectedFileTree, fileTree); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/repository/conversation/ConversationNode.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.repository.conversation; 2 | 3 | import lombok.Getter; 4 | import org.springframework.data.annotation.CreatedDate; 5 | import org.springframework.data.annotation.LastModifiedDate; 6 | import org.springframework.data.neo4j.core.schema.GeneratedValue; 7 | import org.springframework.data.neo4j.core.schema.Id; 8 | import org.springframework.data.neo4j.core.schema.Node; 9 | import org.springframework.data.neo4j.core.schema.Relationship; 10 | import org.springframework.data.neo4j.core.support.UUIDStringGenerator; 11 | 12 | import java.time.LocalDateTime; 13 | import java.util.List; 14 | 15 | @Getter 16 | @Node 17 | public class ConversationNode { 18 | 19 | @Id 20 | @GeneratedValue(UUIDStringGenerator.class) 21 | private final String id; 22 | 23 | @CreatedDate 24 | private LocalDateTime createdAt; 25 | 26 | @LastModifiedDate 27 | private LocalDateTime updatedAt; 28 | 29 | private final String title; 30 | 31 | @Relationship(type = "HAS_MESSAGE", direction = Relationship.Direction.OUTGOING) 32 | private final List childMessageNodes; 33 | 34 | private ConversationNode(String id, String title, LocalDateTime createdAt, LocalDateTime updatedAt, List childMessageNodes) { 35 | this.id = id; 36 | this.title = title; 37 | this.createdAt = createdAt; 38 | this.updatedAt = updatedAt; 39 | this.childMessageNodes = childMessageNodes; 40 | } 41 | 42 | public List getChildMessageNodes() { 43 | if(childMessageNodes == null) { 44 | return null; 45 | } 46 | 47 | // We have to sort the childMessageNodes becuase Neo4j does not 48 | // keep the relationship in order. But the order in childMessageNodes 49 | // is curcial since it is used for tools to dertermine if a tool is 50 | // executed or not. Also it is important to dertermine the order 51 | // between user and AI messages. 52 | return childMessageNodes.stream() 53 | .sorted((n1, n2) -> Integer.compare(n1.getIndex(), n2.getIndex())) 54 | .toList(); 55 | } 56 | 57 | public static ConversationNode of(String title) { 58 | return new ConversationNode(null, title, null, null, null); 59 | } 60 | 61 | public static ConversationNode of(String title, List childMessageNodes) { 62 | return new ConversationNode(null, title, null, null, childMessageNodes); 63 | } 64 | 65 | public static ConversationNode of(ConversationNode oldNode, List newChildMessageNodes) { 66 | return new ConversationNode( 67 | oldNode.getId(), oldNode.getTitle(), oldNode.getCreatedAt(), oldNode.getUpdatedAt(), newChildMessageNodes); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/MessageContentTextAnnotationsFilePathObjectFilePath.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import java.util.Objects; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import com.fasterxml.jackson.annotation.JsonTypeName; 6 | import jakarta.validation.constraints.*; 7 | import io.swagger.v3.oas.annotations.media.Schema; 8 | 9 | 10 | import jakarta.annotation.Generated; 11 | 12 | /** 13 | * MessageContentTextAnnotationsFilePathObjectFilePath 14 | */ 15 | 16 | @JsonTypeName("MessageContentTextAnnotationsFilePathObject_file_path") 17 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 18 | public class MessageContentTextAnnotationsFilePathObjectFilePath { 19 | 20 | private String fileId; 21 | 22 | public MessageContentTextAnnotationsFilePathObjectFilePath() { 23 | super(); 24 | } 25 | 26 | /** 27 | * Constructor with only required parameters 28 | */ 29 | public MessageContentTextAnnotationsFilePathObjectFilePath(String fileId) { 30 | this.fileId = fileId; 31 | } 32 | 33 | public MessageContentTextAnnotationsFilePathObjectFilePath fileId(String fileId) { 34 | this.fileId = fileId; 35 | return this; 36 | } 37 | 38 | /** 39 | * The ID of the file that was generated. 40 | * @return fileId 41 | */ 42 | @NotNull 43 | @Schema(name = "file_id", description = "The ID of the file that was generated.", requiredMode = Schema.RequiredMode.REQUIRED) 44 | @JsonProperty("file_id") 45 | public String getFileId() { 46 | return fileId; 47 | } 48 | 49 | public void setFileId(String fileId) { 50 | this.fileId = fileId; 51 | } 52 | 53 | @Override 54 | public boolean equals(Object o) { 55 | if (this == o) { 56 | return true; 57 | } 58 | if (o == null || getClass() != o.getClass()) { 59 | return false; 60 | } 61 | MessageContentTextAnnotationsFilePathObjectFilePath messageContentTextAnnotationsFilePathObjectFilePath = (MessageContentTextAnnotationsFilePathObjectFilePath) o; 62 | return Objects.equals(this.fileId, messageContentTextAnnotationsFilePathObjectFilePath.fileId); 63 | } 64 | 65 | @Override 66 | public int hashCode() { 67 | return Objects.hash(fileId); 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | StringBuilder sb = new StringBuilder(); 73 | sb.append("class MessageContentTextAnnotationsFilePathObjectFilePath {\n"); 74 | sb.append(" fileId: ").append(toIndentedString(fileId)).append("\n"); 75 | sb.append("}"); 76 | return sb.toString(); 77 | } 78 | 79 | /** 80 | * Convert the given object to string with each line indented by 4 spaces 81 | * (except the first line). 82 | */ 83 | private String toIndentedString(Object o) { 84 | if (o == null) { 85 | return "null"; 86 | } 87 | return o.toString().replace("\n", "\n "); 88 | } 89 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/RunStepDetailsToolCallsCodeOutputImageObjectImage.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import java.util.Objects; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import com.fasterxml.jackson.annotation.JsonTypeName; 6 | import jakarta.validation.constraints.*; 7 | import io.swagger.v3.oas.annotations.media.Schema; 8 | 9 | 10 | import jakarta.annotation.Generated; 11 | 12 | /** 13 | * RunStepDetailsToolCallsCodeOutputImageObjectImage 14 | */ 15 | 16 | @JsonTypeName("RunStepDetailsToolCallsCodeOutputImageObject_image") 17 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 18 | public class RunStepDetailsToolCallsCodeOutputImageObjectImage { 19 | 20 | private String fileId; 21 | 22 | public RunStepDetailsToolCallsCodeOutputImageObjectImage() { 23 | super(); 24 | } 25 | 26 | /** 27 | * Constructor with only required parameters 28 | */ 29 | public RunStepDetailsToolCallsCodeOutputImageObjectImage(String fileId) { 30 | this.fileId = fileId; 31 | } 32 | 33 | public RunStepDetailsToolCallsCodeOutputImageObjectImage fileId(String fileId) { 34 | this.fileId = fileId; 35 | return this; 36 | } 37 | 38 | /** 39 | * The [file](/docs/api-reference/files) ID of the image. 40 | * @return fileId 41 | */ 42 | @NotNull 43 | @Schema(name = "file_id", description = "The [file](/docs/api-reference/files) ID of the image.", requiredMode = Schema.RequiredMode.REQUIRED) 44 | @JsonProperty("file_id") 45 | public String getFileId() { 46 | return fileId; 47 | } 48 | 49 | public void setFileId(String fileId) { 50 | this.fileId = fileId; 51 | } 52 | 53 | @Override 54 | public boolean equals(Object o) { 55 | if (this == o) { 56 | return true; 57 | } 58 | if (o == null || getClass() != o.getClass()) { 59 | return false; 60 | } 61 | RunStepDetailsToolCallsCodeOutputImageObjectImage runStepDetailsToolCallsCodeOutputImageObjectImage = (RunStepDetailsToolCallsCodeOutputImageObjectImage) o; 62 | return Objects.equals(this.fileId, runStepDetailsToolCallsCodeOutputImageObjectImage.fileId); 63 | } 64 | 65 | @Override 66 | public int hashCode() { 67 | return Objects.hash(fileId); 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | StringBuilder sb = new StringBuilder(); 73 | sb.append("class RunStepDetailsToolCallsCodeOutputImageObjectImage {\n"); 74 | sb.append(" fileId: ").append(toIndentedString(fileId)).append("\n"); 75 | sb.append("}"); 76 | return sb.toString(); 77 | } 78 | 79 | /** 80 | * Convert the given object to string with each line indented by 4 spaces 81 | * (except the first line). 82 | */ 83 | private String toIndentedString(Object o) { 84 | if (o == null) { 85 | return "null"; 86 | } 87 | return o.toString().replace("\n", "\n "); 88 | } 89 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/mapper/ChatRequestMapper.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.mapper; 2 | 3 | import com.theokanning.openai.completion.chat.ChatMessage; 4 | import dev.ai4j.openai4j.chat.Message; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /* 10 | All messages are mapped from Theokanning -> OpenAi4J 11 | */ 12 | public class ChatRequestMapper { 13 | 14 | private ChatRequestMapper() { 15 | throw new IllegalStateException("Utility class"); 16 | } 17 | 18 | public static dev.ai4j.openai4j.chat.ChatCompletionRequest mapRequest( 19 | com.theokanning.openai.completion.chat.ChatCompletionRequest theokanningRequest) { 20 | return dev.ai4j.openai4j.chat.ChatCompletionRequest.builder() 21 | .model(theokanningRequest.getModel()) 22 | .messages(createMessages(theokanningRequest.getMessages())) 23 | .temperature(theokanningRequest.getTemperature()) 24 | .topP(theokanningRequest.getTopP()) 25 | .n(theokanningRequest.getN()) 26 | .stream(theokanningRequest.getStream()) 27 | .stop(theokanningRequest.getStop()) 28 | .maxTokens(theokanningRequest.getMaxTokens()) 29 | .presencePenalty(theokanningRequest.getPresencePenalty()) 30 | .frequencyPenalty(theokanningRequest.getFrequencyPenalty()) 31 | .logitBias(theokanningRequest.getLogitBias()) 32 | .user(theokanningRequest.getUser()) 33 | .build(); 34 | } 35 | 36 | private static List createMessages(List messagesToMap) { 37 | List openAI4JMessages = new ArrayList<>(); 38 | 39 | for (ChatMessage message : messagesToMap) { 40 | openAI4JMessages.add(createMessage(message)); 41 | } 42 | 43 | return openAI4JMessages; 44 | } 45 | 46 | private static Message createMessage(ChatMessage messageToMap) { 47 | 48 | if (messageToMap.getRole().equals("system")) { 49 | return dev.ai4j.openai4j.chat.SystemMessage.builder() 50 | .content(messageToMap.getContent()) 51 | .name(messageToMap.getName()) 52 | .build(); 53 | } else if (messageToMap.getRole().equals("assistant")) { 54 | return dev.ai4j.openai4j.chat.AssistantMessage.builder() 55 | .content(messageToMap.getContent()) 56 | .name(messageToMap.getName()) 57 | .build(); 58 | } else if (messageToMap.getRole().equals("user")) { 59 | return dev.ai4j.openai4j.chat.UserMessage.builder() 60 | .content(messageToMap.getContent()) 61 | .name(messageToMap.getName()) 62 | .build(); 63 | } else { 64 | return null; 65 | } 66 | } 67 | 68 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/RunStepDetailsMessageCreationObjectMessageCreation.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import java.util.Objects; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import com.fasterxml.jackson.annotation.JsonTypeName; 6 | import jakarta.validation.constraints.*; 7 | import io.swagger.v3.oas.annotations.media.Schema; 8 | 9 | 10 | import jakarta.annotation.Generated; 11 | 12 | /** 13 | * RunStepDetailsMessageCreationObjectMessageCreation 14 | */ 15 | 16 | @JsonTypeName("RunStepDetailsMessageCreationObject_message_creation") 17 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 18 | public class RunStepDetailsMessageCreationObjectMessageCreation { 19 | 20 | private String messageId; 21 | 22 | public RunStepDetailsMessageCreationObjectMessageCreation() { 23 | super(); 24 | } 25 | 26 | /** 27 | * Constructor with only required parameters 28 | */ 29 | public RunStepDetailsMessageCreationObjectMessageCreation(String messageId) { 30 | this.messageId = messageId; 31 | } 32 | 33 | public RunStepDetailsMessageCreationObjectMessageCreation messageId(String messageId) { 34 | this.messageId = messageId; 35 | return this; 36 | } 37 | 38 | /** 39 | * The ID of the message that was created by this run step. 40 | * @return messageId 41 | */ 42 | @NotNull 43 | @Schema(name = "message_id", description = "The ID of the message that was created by this run step.", requiredMode = Schema.RequiredMode.REQUIRED) 44 | @JsonProperty("message_id") 45 | public String getMessageId() { 46 | return messageId; 47 | } 48 | 49 | public void setMessageId(String messageId) { 50 | this.messageId = messageId; 51 | } 52 | 53 | @Override 54 | public boolean equals(Object o) { 55 | if (this == o) { 56 | return true; 57 | } 58 | if (o == null || getClass() != o.getClass()) { 59 | return false; 60 | } 61 | RunStepDetailsMessageCreationObjectMessageCreation runStepDetailsMessageCreationObjectMessageCreation = (RunStepDetailsMessageCreationObjectMessageCreation) o; 62 | return Objects.equals(this.messageId, runStepDetailsMessageCreationObjectMessageCreation.messageId); 63 | } 64 | 65 | @Override 66 | public int hashCode() { 67 | return Objects.hash(messageId); 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | StringBuilder sb = new StringBuilder(); 73 | sb.append("class RunStepDetailsMessageCreationObjectMessageCreation {\n"); 74 | sb.append(" messageId: ").append(toIndentedString(messageId)).append("\n"); 75 | sb.append("}"); 76 | return sb.toString(); 77 | } 78 | 79 | /** 80 | * Convert the given object to string with each line indented by 4 spaces 81 | * (except the first line). 82 | */ 83 | private String toIndentedString(Object o) { 84 | if (o == null) { 85 | return "null"; 86 | } 87 | return o.toString().replace("\n", "\n "); 88 | } 89 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/test/java/com/telekom/ai4coding/chatbot/service/Neo4JDatabaseServiceIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.service; 2 | 3 | import com.telekom.ai4coding.chatbot.BaseIntegrationTest; 4 | import org.assertj.core.api.Assertions; 5 | import org.junit.jupiter.api.BeforeEach; 6 | import org.junit.jupiter.api.Test; 7 | import org.neo4j.driver.Driver; 8 | import org.neo4j.driver.Session; 9 | import org.neo4j.driver.Transaction; 10 | import org.neo4j.driver.exceptions.Neo4jException; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | 13 | import static org.assertj.core.api.Assertions.assertThatThrownBy; 14 | import static org.mockito.Mockito.*; 15 | 16 | public class Neo4JDatabaseServiceIntegrationTest extends BaseIntegrationTest { 17 | 18 | @Autowired 19 | private Neo4JDatabaseService neo4JDatabaseService; 20 | 21 | @Autowired 22 | private Driver neo4jDriver; 23 | 24 | @BeforeEach 25 | void setup() { 26 | // Insert some test data in the database before each test 27 | try (Session session = neo4jDriver.session()) { 28 | session.run("CREATE (:TestNode {name: 'Test Node 1'})"); 29 | session.run("CREATE (:TestNode {name: 'Test Node 2'})"); 30 | } 31 | } 32 | 33 | @Test 34 | void whenCleanupDatabase_thenAllNodesAndRelationshipsShouldBeDeleted() { 35 | // Given: The database has test data (already inserted in @BeforeEach) 36 | 37 | // When: CleanupDatabase method is called 38 | neo4JDatabaseService.cleanupDatabase(); 39 | 40 | // Then: The database should be empty (no nodes or relationships) 41 | try (Session session = neo4jDriver.session()) { 42 | long nodeCount = session.run("MATCH (n) RETURN COUNT(n)").single().get(0).asLong(); 43 | Assertions.assertThat(nodeCount).isEqualTo(0); // Verify all nodes are deleted 44 | } 45 | } 46 | 47 | //Needs a mocked driver because using the real neo4j driver results in flawless execution, which means to error is thrown -> nothing to handle for the test 48 | @Test 49 | void whenDatabaseThrowsException_thenExceptionIsHandledGracefully() { 50 | // Given: A mock session that throws an exception 51 | Driver mockDriver = mock(Driver.class); 52 | Session mockSession = mock(Session.class); 53 | Transaction mockTransaction = mock(Transaction.class); 54 | 55 | // Mock session and transaction behavior 56 | when(mockDriver.session()).thenReturn(mockSession); 57 | when(mockSession.beginTransaction()).thenReturn(mockTransaction); 58 | when(mockSession.executeWrite(any())).thenThrow(Neo4jException.class); 59 | 60 | // Create service with the mocked driver 61 | Neo4JDatabaseService serviceWithMockedDriver = new Neo4JDatabaseService(mockDriver); 62 | 63 | // When & Then: Expect an exception when cleanupDatabase is called 64 | assertThatThrownBy(serviceWithMockedDriver::cleanupDatabase) 65 | .isInstanceOf(Neo4jException.class); 66 | } 67 | } 68 | 69 | -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/FineTuningJobHyperparameters.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.fasterxml.jackson.annotation.JsonTypeName; 5 | import io.swagger.v3.oas.annotations.media.Schema; 6 | import jakarta.annotation.Generated; 7 | import jakarta.validation.Valid; 8 | import jakarta.validation.constraints.NotNull; 9 | 10 | import java.util.Objects; 11 | 12 | /** 13 | * The hyperparameters used for the fine-tuning job. See the [fine-tuning guide](/docs/guides/fine-tuning) for more details. 14 | */ 15 | 16 | @Schema(name = "FineTuningJob_hyperparameters", description = "The hyperparameters used for the fine-tuning job. See the [fine-tuning guide](/docs/guides/fine-tuning) for more details.") 17 | @JsonTypeName("FineTuningJob_hyperparameters") 18 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 19 | public class FineTuningJobHyperparameters { 20 | 21 | // private FineTuningJobHyperparametersNEpochs nEpochs = auto; 22 | private FineTuningJobHyperparametersNEpochs nEpochs = null; 23 | 24 | public FineTuningJobHyperparameters() { 25 | super(); 26 | } 27 | 28 | /** 29 | * Constructor with only required parameters 30 | */ 31 | public FineTuningJobHyperparameters(FineTuningJobHyperparametersNEpochs nEpochs) { 32 | this.nEpochs = nEpochs; 33 | } 34 | 35 | public FineTuningJobHyperparameters nEpochs(FineTuningJobHyperparametersNEpochs nEpochs) { 36 | this.nEpochs = nEpochs; 37 | return this; 38 | } 39 | 40 | /** 41 | * Get nEpochs 42 | * @return nEpochs 43 | */ 44 | @NotNull @Valid 45 | @Schema(name = "n_epochs", requiredMode = Schema.RequiredMode.REQUIRED) 46 | @JsonProperty("n_epochs") 47 | public FineTuningJobHyperparametersNEpochs getnEpochs() { 48 | return nEpochs; 49 | } 50 | 51 | public void setnEpochs(FineTuningJobHyperparametersNEpochs nEpochs) { 52 | this.nEpochs = nEpochs; 53 | } 54 | 55 | @Override 56 | public boolean equals(Object o) { 57 | if (this == o) { 58 | return true; 59 | } 60 | if (o == null || getClass() != o.getClass()) { 61 | return false; 62 | } 63 | FineTuningJobHyperparameters fineTuningJobHyperparameters = (FineTuningJobHyperparameters) o; 64 | return Objects.equals(this.nEpochs, fineTuningJobHyperparameters.nEpochs); 65 | } 66 | 67 | @Override 68 | public int hashCode() { 69 | return Objects.hash(nEpochs); 70 | } 71 | 72 | @Override 73 | public String toString() { 74 | StringBuilder sb = new StringBuilder(); 75 | sb.append("class FineTuningJobHyperparameters {\n"); 76 | sb.append(" nEpochs: ").append(toIndentedString(nEpochs)).append("\n"); 77 | sb.append("}"); 78 | return sb.toString(); 79 | } 80 | 81 | /** 82 | * Convert the given object to string with each line indented by 4 spaces 83 | * (except the first line). 84 | */ 85 | private String toIndentedString(Object o) { 86 | if (o == null) { 87 | return "null"; 88 | } 89 | return o.toString().replace("\n", "\n "); 90 | } 91 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/ModifyRunRequest.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import java.util.Objects; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | 6 | import java.util.Arrays; 7 | import org.openapitools.jackson.nullable.JsonNullable; 8 | import io.swagger.v3.oas.annotations.media.Schema; 9 | 10 | 11 | import jakarta.annotation.Generated; 12 | 13 | /** 14 | * ModifyRunRequest 15 | */ 16 | 17 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 18 | public class ModifyRunRequest { 19 | 20 | private JsonNullable metadata = JsonNullable.undefined(); 21 | 22 | public ModifyRunRequest metadata(Object metadata) { 23 | this.metadata = JsonNullable.of(metadata); 24 | return this; 25 | } 26 | 27 | /** 28 | * Set of 16 key-value pairs that can be attached to an object. This can be useful for storing additional information about the object in a structured format. Keys can be a maximum of 64 characters long and values can be a maxium of 512 characters long. 29 | * @return metadata 30 | */ 31 | 32 | @Schema(name = "metadata", description = "Set of 16 key-value pairs that can be attached to an object. This can be useful for storing additional information about the object in a structured format. Keys can be a maximum of 64 characters long and values can be a maxium of 512 characters long. ", requiredMode = Schema.RequiredMode.NOT_REQUIRED) 33 | @JsonProperty("metadata") 34 | public JsonNullable getMetadata() { 35 | return metadata; 36 | } 37 | 38 | public void setMetadata(JsonNullable metadata) { 39 | this.metadata = metadata; 40 | } 41 | 42 | @Override 43 | public boolean equals(Object o) { 44 | if (this == o) { 45 | return true; 46 | } 47 | if (o == null || getClass() != o.getClass()) { 48 | return false; 49 | } 50 | ModifyRunRequest modifyRunRequest = (ModifyRunRequest) o; 51 | return equalsNullable(this.metadata, modifyRunRequest.metadata); 52 | } 53 | 54 | private static boolean equalsNullable(JsonNullable a, JsonNullable b) { 55 | return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); 56 | } 57 | 58 | @Override 59 | public int hashCode() { 60 | return Objects.hash(hashCodeNullable(metadata)); 61 | } 62 | 63 | private static int hashCodeNullable(JsonNullable a) { 64 | if (a == null) { 65 | return 1; 66 | } 67 | return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | StringBuilder sb = new StringBuilder(); 73 | sb.append("class ModifyRunRequest {\n"); 74 | sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); 75 | sb.append("}"); 76 | return sb.toString(); 77 | } 78 | 79 | /** 80 | * Convert the given object to string with each line indented by 4 spaces 81 | * (except the first line). 82 | */ 83 | private String toIndentedString(Object o) { 84 | if (o == null) { 85 | return "null"; 86 | } 87 | return o.toString().replace("\n", "\n "); 88 | } 89 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/ModifyThreadRequest.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import java.util.Objects; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | 6 | import java.util.Arrays; 7 | import org.openapitools.jackson.nullable.JsonNullable; 8 | import io.swagger.v3.oas.annotations.media.Schema; 9 | 10 | 11 | import jakarta.annotation.Generated; 12 | 13 | /** 14 | * ModifyThreadRequest 15 | */ 16 | 17 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 18 | public class ModifyThreadRequest { 19 | 20 | private JsonNullable metadata = JsonNullable.undefined(); 21 | 22 | public ModifyThreadRequest metadata(Object metadata) { 23 | this.metadata = JsonNullable.of(metadata); 24 | return this; 25 | } 26 | 27 | /** 28 | * Set of 16 key-value pairs that can be attached to an object. This can be useful for storing additional information about the object in a structured format. Keys can be a maximum of 64 characters long and values can be a maxium of 512 characters long. 29 | * @return metadata 30 | */ 31 | 32 | @Schema(name = "metadata", description = "Set of 16 key-value pairs that can be attached to an object. This can be useful for storing additional information about the object in a structured format. Keys can be a maximum of 64 characters long and values can be a maxium of 512 characters long. ", requiredMode = Schema.RequiredMode.NOT_REQUIRED) 33 | @JsonProperty("metadata") 34 | public JsonNullable getMetadata() { 35 | return metadata; 36 | } 37 | 38 | public void setMetadata(JsonNullable metadata) { 39 | this.metadata = metadata; 40 | } 41 | 42 | @Override 43 | public boolean equals(Object o) { 44 | if (this == o) { 45 | return true; 46 | } 47 | if (o == null || getClass() != o.getClass()) { 48 | return false; 49 | } 50 | ModifyThreadRequest modifyThreadRequest = (ModifyThreadRequest) o; 51 | return equalsNullable(this.metadata, modifyThreadRequest.metadata); 52 | } 53 | 54 | private static boolean equalsNullable(JsonNullable a, JsonNullable b) { 55 | return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); 56 | } 57 | 58 | @Override 59 | public int hashCode() { 60 | return Objects.hash(hashCodeNullable(metadata)); 61 | } 62 | 63 | private static int hashCodeNullable(JsonNullable a) { 64 | if (a == null) { 65 | return 1; 66 | } 67 | return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | StringBuilder sb = new StringBuilder(); 73 | sb.append("class ModifyThreadRequest {\n"); 74 | sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); 75 | sb.append("}"); 76 | return sb.toString(); 77 | } 78 | 79 | /** 80 | * Convert the given object to string with each line indented by 4 spaces 81 | * (except the first line). 82 | */ 83 | private String toIndentedString(Object o) { 84 | if (o == null) { 85 | return "null"; 86 | } 87 | return o.toString().replace("\n", "\n "); 88 | } 89 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/ModifyMessageRequest.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import java.util.Objects; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | 6 | import java.util.Arrays; 7 | import org.openapitools.jackson.nullable.JsonNullable; 8 | import io.swagger.v3.oas.annotations.media.Schema; 9 | 10 | 11 | import jakarta.annotation.Generated; 12 | 13 | /** 14 | * ModifyMessageRequest 15 | */ 16 | 17 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 18 | public class ModifyMessageRequest { 19 | 20 | private JsonNullable metadata = JsonNullable.undefined(); 21 | 22 | public ModifyMessageRequest metadata(Object metadata) { 23 | this.metadata = JsonNullable.of(metadata); 24 | return this; 25 | } 26 | 27 | /** 28 | * Set of 16 key-value pairs that can be attached to an object. This can be useful for storing additional information about the object in a structured format. Keys can be a maximum of 64 characters long and values can be a maxium of 512 characters long. 29 | * @return metadata 30 | */ 31 | 32 | @Schema(name = "metadata", description = "Set of 16 key-value pairs that can be attached to an object. This can be useful for storing additional information about the object in a structured format. Keys can be a maximum of 64 characters long and values can be a maxium of 512 characters long. ", requiredMode = Schema.RequiredMode.NOT_REQUIRED) 33 | @JsonProperty("metadata") 34 | public JsonNullable getMetadata() { 35 | return metadata; 36 | } 37 | 38 | public void setMetadata(JsonNullable metadata) { 39 | this.metadata = metadata; 40 | } 41 | 42 | @Override 43 | public boolean equals(Object o) { 44 | if (this == o) { 45 | return true; 46 | } 47 | if (o == null || getClass() != o.getClass()) { 48 | return false; 49 | } 50 | ModifyMessageRequest modifyMessageRequest = (ModifyMessageRequest) o; 51 | return equalsNullable(this.metadata, modifyMessageRequest.metadata); 52 | } 53 | 54 | private static boolean equalsNullable(JsonNullable a, JsonNullable b) { 55 | return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); 56 | } 57 | 58 | @Override 59 | public int hashCode() { 60 | return Objects.hash(hashCodeNullable(metadata)); 61 | } 62 | 63 | private static int hashCodeNullable(JsonNullable a) { 64 | if (a == null) { 65 | return 1; 66 | } 67 | return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | StringBuilder sb = new StringBuilder(); 73 | sb.append("class ModifyMessageRequest {\n"); 74 | sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); 75 | sb.append("}"); 76 | return sb.toString(); 77 | } 78 | 79 | /** 80 | * Convert the given object to string with each line indented by 4 spaces 81 | * (except the first line). 82 | */ 83 | private String toIndentedString(Object o) { 84 | if (o == null) { 85 | return "null"; 86 | } 87 | return o.toString().replace("\n", "\n "); 88 | } 89 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/main/java/com/telekom/ai4coding/chatbot/graph/ASTNode.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.graph; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import org.springframework.data.neo4j.core.schema.GeneratedValue; 6 | import org.springframework.data.neo4j.core.schema.Id; 7 | import org.springframework.data.neo4j.core.schema.Node; 8 | import org.springframework.data.neo4j.core.schema.Relationship; 9 | 10 | import java.util.LinkedList; 11 | import java.util.List; 12 | 13 | 14 | /** 15 | * Represents an AST node from tree-sitter. 16 | */ 17 | @AllArgsConstructor 18 | @Getter 19 | @Node 20 | public class ASTNode { 21 | @Id 22 | @GeneratedValue 23 | private final Long id; 24 | 25 | private final String type; 26 | private final String text; 27 | 28 | // The starting line number of this AST node in the source code, 1-indexed and inclusive. 29 | private final int startLine; 30 | // The ending line number of this AST node in the source code, 1-indexed and inclusive. 31 | private final int endLine; 32 | 33 | // A vector of numbers representing the semantic meaning of the ASTNode generated 34 | // from an embedding model. 35 | // This has to be double, because float in neo4j is double in Java. 36 | // But the embedding model will generate float[] in Java, we need to convert them 37 | // into Java double[]. 38 | // https://neo4j.com/docs/java-reference/current/extending-neo4j/values-and-types/ 39 | private final double[] embedding; 40 | 41 | /** 42 | * An edge from a ASTNode to an ASTNode, that connects the parent AST node to the child AST node. 43 | */ 44 | @Relationship(type = "PARENT_OF", direction = Relationship.Direction.OUTGOING) 45 | private List childASTNodes; 46 | 47 | public static ASTNode of(final String type, final String text, final int startLine, final int endLine, final double[] embedding) { 48 | return new ASTNode(null, type, text, startLine, endLine, embedding, null); 49 | } 50 | 51 | /** 52 | * Mutating a Node for performance, but has to stay only package accessible! 53 | * ... 54 | * 55 | * @param childASTNode 56 | */ 57 | void addChildASTNode(final ASTNode childASTNode) { 58 | if (this.childASTNodes == null) { 59 | this.childASTNodes = new LinkedList<>(); 60 | } 61 | childASTNodes.add(childASTNode); 62 | } 63 | 64 | ASTNode withId(final Long id) { 65 | if (this.id != null && this.id.equals(id)) { 66 | return this; 67 | } 68 | 69 | return new ASTNode(id, this.type, this.text, this.startLine, this.endLine, this.embedding, this.childASTNodes); 70 | } 71 | 72 | @Override 73 | public boolean equals(Object obj) { 74 | if (this == obj) { 75 | return true; 76 | } 77 | 78 | if (obj == null || getClass() != obj.getClass()) { 79 | return false; 80 | } 81 | 82 | ASTNode other = (ASTNode) obj; 83 | return type.equals(other.type) 84 | && text.equals(other.text) 85 | && startLine == other.startLine 86 | && endLine == other.endLine; 87 | } 88 | } -------------------------------------------------------------------------------- /openai-api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.telekom.ai4coding 8 | chatbot 9 | 0.0.2-SNAPSHOT 10 | 11 | 12 | com.telekom.ai4coding 13 | openai-api 14 | 0.0.2-SNAPSHOT 15 | 16 | 17 | 21 18 | 21 19 | UTF-8 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-web 26 | 27 | 28 | org.springframework.data 29 | spring-data-commons 30 | 31 | 32 | 33 | com.theokanning.openai-gpt3-java 34 | api 35 | 0.18.2 36 | 37 | 38 | 39 | 40 | com.google.code.findbugs 41 | jsr305 42 | 3.0.2 43 | 44 | 45 | com.fasterxml.jackson.dataformat 46 | jackson-dataformat-yaml 47 | 48 | 49 | com.fasterxml.jackson.datatype 50 | jackson-datatype-jsr310 51 | 52 | 53 | org.openapitools 54 | jackson-databind-nullable 55 | 0.2.6 56 | 57 | 58 | io.swagger.core.v3 59 | swagger-annotations 60 | 2.2.18 61 | 62 | 63 | 64 | jakarta.validation 65 | jakarta.validation-api 66 | 3.0.2 67 | 68 | 69 | org.hibernate 70 | hibernate-validator 71 | 8.0.1.Final 72 | 73 | 74 | com.fasterxml.jackson.core 75 | jackson-databind 76 | 77 | 78 | org.springframework.boot 79 | spring-boot-starter-test 80 | test 81 | 82 | 83 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/test/java/com/telekom/ai4coding/chatbot/mapper/ChatMapperTest.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.mapper; 2 | 3 | import com.theokanning.openai.completion.chat.ChatCompletionRequest; 4 | import com.theokanning.openai.completion.chat.ChatCompletionResult; 5 | import com.theokanning.openai.completion.chat.ChatMessage; 6 | import dev.ai4j.openai4j.chat.*; 7 | import dev.ai4j.openai4j.shared.Usage; 8 | import org.junit.Test; 9 | 10 | import java.util.Collections; 11 | import java.util.List; 12 | 13 | import static org.junit.jupiter.api.Assertions.assertEquals; 14 | import static org.junit.jupiter.api.Assertions.assertTrue; 15 | 16 | public class ChatMapperTest { 17 | @Test 18 | public void testRequestMapping() { 19 | ChatMessage chatMessage = new ChatMessage("user", "Tell me joke!"); 20 | List messages = Collections.singletonList(chatMessage); 21 | 22 | ChatCompletionRequest theokanningRequest = ChatCompletionRequest.builder() 23 | .model("gpt-3.5") 24 | .temperature(1.0) 25 | .topP(1.0) 26 | .n(1) 27 | .stream(false) 28 | .stop(Collections.singletonList("\n")) 29 | .maxTokens(50) 30 | .presencePenalty(0.0) 31 | .frequencyPenalty(0.0) 32 | .logitBias(Collections.emptyMap()) 33 | .user("user1") 34 | .messages(messages) 35 | .build(); 36 | 37 | dev.ai4j.openai4j.chat.ChatCompletionRequest translatedRequest = ChatRequestMapper.mapRequest(theokanningRequest); 38 | 39 | assertEquals("user1", translatedRequest.user()); 40 | assertEquals("gpt-3.5", translatedRequest.model()); 41 | assertEquals(Role.USER, translatedRequest.messages().get(0).role()); 42 | assertEquals(50, translatedRequest.maxTokens()); 43 | assertTrue(translatedRequest.messages().get(0) instanceof UserMessage); 44 | } 45 | 46 | @Test 47 | public void testResponseMapping() { 48 | AssistantMessage message = AssistantMessage.builder() 49 | .name("assistant") 50 | .content("joke") 51 | .build(); 52 | 53 | dev.ai4j.openai4j.chat.ChatCompletionChoice choice = ChatCompletionChoice.builder() 54 | .index(1) 55 | .message(message) 56 | .build(); 57 | 58 | dev.ai4j.openai4j.shared.Usage usage = Usage.builder() 59 | .totalTokens(10) 60 | .promptTokens(8) 61 | .completionTokens(2) 62 | .build(); 63 | 64 | ChatCompletionResponse openAIResponse = ChatCompletionResponse.builder() 65 | .id("id1") 66 | .created(1) 67 | .model("gpt-3.5") 68 | .choices(Collections.singletonList(choice)) 69 | .usage(usage) 70 | .systemFingerprint("dummyfingerpring") 71 | .build(); 72 | 73 | ChatCompletionResult chatCompletionResult = ChatResponseMapper.mapResponseToResult(openAIResponse); 74 | 75 | assertEquals("gpt-3.5", chatCompletionResult.getModel()); 76 | assertEquals("joke", chatCompletionResult.getChoices().get(0).getMessage().getContent()); 77 | assertEquals(10, chatCompletionResult.getUsage().getTotalTokens()); 78 | } 79 | 80 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/CreateModerationRequest.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import io.swagger.v3.oas.annotations.media.Schema; 5 | import jakarta.annotation.Generated; 6 | import jakarta.validation.Valid; 7 | import jakarta.validation.constraints.NotNull; 8 | 9 | import java.util.Objects; 10 | 11 | /** 12 | * CreateModerationRequest 13 | */ 14 | 15 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 16 | public class CreateModerationRequest { 17 | 18 | private CreateModerationRequestInput input; 19 | 20 | // private CreateModerationRequestModel model = text-moderation-latest; 21 | private CreateModerationRequestModel model = null; 22 | 23 | public CreateModerationRequest() { 24 | super(); 25 | } 26 | 27 | /** 28 | * Constructor with only required parameters 29 | */ 30 | public CreateModerationRequest(CreateModerationRequestInput input) { 31 | this.input = input; 32 | } 33 | 34 | public CreateModerationRequest input(CreateModerationRequestInput input) { 35 | this.input = input; 36 | return this; 37 | } 38 | 39 | /** 40 | * Get input 41 | * @return input 42 | */ 43 | @NotNull @Valid 44 | @Schema(name = "input", requiredMode = Schema.RequiredMode.REQUIRED) 45 | @JsonProperty("input") 46 | public CreateModerationRequestInput getInput() { 47 | return input; 48 | } 49 | 50 | public void setInput(CreateModerationRequestInput input) { 51 | this.input = input; 52 | } 53 | 54 | public CreateModerationRequest model(CreateModerationRequestModel model) { 55 | this.model = model; 56 | return this; 57 | } 58 | 59 | /** 60 | * Get model 61 | * @return model 62 | */ 63 | @Valid 64 | @Schema(name = "model", requiredMode = Schema.RequiredMode.NOT_REQUIRED) 65 | @JsonProperty("model") 66 | public CreateModerationRequestModel getModel() { 67 | return model; 68 | } 69 | 70 | public void setModel(CreateModerationRequestModel model) { 71 | this.model = model; 72 | } 73 | 74 | @Override 75 | public boolean equals(Object o) { 76 | if (this == o) { 77 | return true; 78 | } 79 | if (o == null || getClass() != o.getClass()) { 80 | return false; 81 | } 82 | CreateModerationRequest createModerationRequest = (CreateModerationRequest) o; 83 | return Objects.equals(this.input, createModerationRequest.input) && 84 | Objects.equals(this.model, createModerationRequest.model); 85 | } 86 | 87 | @Override 88 | public int hashCode() { 89 | return Objects.hash(input, model); 90 | } 91 | 92 | @Override 93 | public String toString() { 94 | StringBuilder sb = new StringBuilder(); 95 | sb.append("class CreateModerationRequest {\n"); 96 | sb.append(" input: ").append(toIndentedString(input)).append("\n"); 97 | sb.append(" model: ").append(toIndentedString(model)).append("\n"); 98 | sb.append("}"); 99 | return sb.toString(); 100 | } 101 | 102 | /** 103 | * Convert the given object to string with each line indented by 4 spaces 104 | * (except the first line). 105 | */ 106 | private String toIndentedString(Object o) { 107 | if (o == null) { 108 | return "null"; 109 | } 110 | return o.toString().replace("\n", "\n "); 111 | } 112 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/SubmitToolOutputsRunRequest.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import java.util.Objects; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import jakarta.validation.Valid; 10 | import jakarta.validation.constraints.*; 11 | import io.swagger.v3.oas.annotations.media.Schema; 12 | 13 | 14 | import jakarta.annotation.Generated; 15 | 16 | /** 17 | * SubmitToolOutputsRunRequest 18 | */ 19 | 20 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 21 | public class SubmitToolOutputsRunRequest { 22 | 23 | @Valid 24 | private List<@Valid SubmitToolOutputsRunRequestToolOutputsInner> toolOutputs = new ArrayList<>(); 25 | 26 | public SubmitToolOutputsRunRequest() { 27 | super(); 28 | } 29 | 30 | /** 31 | * Constructor with only required parameters 32 | */ 33 | public SubmitToolOutputsRunRequest(List<@Valid SubmitToolOutputsRunRequestToolOutputsInner> toolOutputs) { 34 | this.toolOutputs = toolOutputs; 35 | } 36 | 37 | public SubmitToolOutputsRunRequest toolOutputs(List<@Valid SubmitToolOutputsRunRequestToolOutputsInner> toolOutputs) { 38 | this.toolOutputs = toolOutputs; 39 | return this; 40 | } 41 | 42 | public SubmitToolOutputsRunRequest addToolOutputsItem(SubmitToolOutputsRunRequestToolOutputsInner toolOutputsItem) { 43 | if (this.toolOutputs == null) { 44 | this.toolOutputs = new ArrayList<>(); 45 | } 46 | this.toolOutputs.add(toolOutputsItem); 47 | return this; 48 | } 49 | 50 | /** 51 | * A list of tools for which the outputs are being submitted. 52 | * @return toolOutputs 53 | */ 54 | @NotNull @Valid 55 | @Schema(name = "tool_outputs", description = "A list of tools for which the outputs are being submitted.", requiredMode = Schema.RequiredMode.REQUIRED) 56 | @JsonProperty("tool_outputs") 57 | public List<@Valid SubmitToolOutputsRunRequestToolOutputsInner> getToolOutputs() { 58 | return toolOutputs; 59 | } 60 | 61 | public void setToolOutputs(List<@Valid SubmitToolOutputsRunRequestToolOutputsInner> toolOutputs) { 62 | this.toolOutputs = toolOutputs; 63 | } 64 | 65 | @Override 66 | public boolean equals(Object o) { 67 | if (this == o) { 68 | return true; 69 | } 70 | if (o == null || getClass() != o.getClass()) { 71 | return false; 72 | } 73 | SubmitToolOutputsRunRequest submitToolOutputsRunRequest = (SubmitToolOutputsRunRequest) o; 74 | return Objects.equals(this.toolOutputs, submitToolOutputsRunRequest.toolOutputs); 75 | } 76 | 77 | @Override 78 | public int hashCode() { 79 | return Objects.hash(toolOutputs); 80 | } 81 | 82 | @Override 83 | public String toString() { 84 | StringBuilder sb = new StringBuilder(); 85 | sb.append("class SubmitToolOutputsRunRequest {\n"); 86 | sb.append(" toolOutputs: ").append(toIndentedString(toolOutputs)).append("\n"); 87 | sb.append("}"); 88 | return sb.toString(); 89 | } 90 | 91 | /** 92 | * Convert the given object to string with each line indented by 4 spaces 93 | * (except the first line). 94 | */ 95 | private String toIndentedString(Object o) { 96 | if (o == null) { 97 | return "null"; 98 | } 99 | return o.toString().replace("\n", "\n "); 100 | } 101 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/ImagesResponse.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import io.swagger.v3.oas.annotations.media.Schema; 5 | import jakarta.annotation.Generated; 6 | import jakarta.validation.Valid; 7 | import jakarta.validation.constraints.NotNull; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | import java.util.Objects; 12 | 13 | /** 14 | * ImagesResponse 15 | */ 16 | 17 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 18 | public class ImagesResponse { 19 | 20 | private Integer created; 21 | 22 | @Valid 23 | private List<@Valid Image> data = new ArrayList<>(); 24 | 25 | public ImagesResponse() { 26 | super(); 27 | } 28 | 29 | /** 30 | * Constructor with only required parameters 31 | */ 32 | public ImagesResponse(Integer created, List<@Valid Image> data) { 33 | this.created = created; 34 | this.data = data; 35 | } 36 | 37 | public ImagesResponse created(Integer created) { 38 | this.created = created; 39 | return this; 40 | } 41 | 42 | /** 43 | * Get created 44 | * @return created 45 | */ 46 | @NotNull 47 | @Schema(name = "created", requiredMode = Schema.RequiredMode.REQUIRED) 48 | @JsonProperty("created") 49 | public Integer getCreated() { 50 | return created; 51 | } 52 | 53 | public void setCreated(Integer created) { 54 | this.created = created; 55 | } 56 | 57 | public ImagesResponse data(List<@Valid Image> data) { 58 | this.data = data; 59 | return this; 60 | } 61 | 62 | public ImagesResponse addDataItem(Image dataItem) { 63 | if (this.data == null) { 64 | this.data = new ArrayList<>(); 65 | } 66 | this.data.add(dataItem); 67 | return this; 68 | } 69 | 70 | /** 71 | * Get data 72 | * @return data 73 | */ 74 | @NotNull @Valid 75 | @Schema(name = "data", requiredMode = Schema.RequiredMode.REQUIRED) 76 | @JsonProperty("data") 77 | public List<@Valid Image> getData() { 78 | return data; 79 | } 80 | 81 | public void setData(List<@Valid Image> data) { 82 | this.data = data; 83 | } 84 | 85 | @Override 86 | public boolean equals(Object o) { 87 | if (this == o) { 88 | return true; 89 | } 90 | if (o == null || getClass() != o.getClass()) { 91 | return false; 92 | } 93 | ImagesResponse imagesResponse = (ImagesResponse) o; 94 | return Objects.equals(this.created, imagesResponse.created) && 95 | Objects.equals(this.data, imagesResponse.data); 96 | } 97 | 98 | @Override 99 | public int hashCode() { 100 | return Objects.hash(created, data); 101 | } 102 | 103 | @Override 104 | public String toString() { 105 | StringBuilder sb = new StringBuilder(); 106 | sb.append("class ImagesResponse {\n"); 107 | sb.append(" created: ").append(toIndentedString(created)).append("\n"); 108 | sb.append(" data: ").append(toIndentedString(data)).append("\n"); 109 | sb.append("}"); 110 | return sb.toString(); 111 | } 112 | 113 | /** 114 | * Convert the given object to string with each line indented by 4 spaces 115 | * (except the first line). 116 | */ 117 | private String toIndentedString(Object o) { 118 | if (o == null) { 119 | return "null"; 120 | } 121 | return o.toString().replace("\n", "\n "); 122 | } 123 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/AssistantToolsCode.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import com.fasterxml.jackson.annotation.JsonValue; 6 | import io.swagger.v3.oas.annotations.media.Schema; 7 | import jakarta.annotation.Generated; 8 | import jakarta.validation.constraints.NotNull; 9 | 10 | import java.util.Objects; 11 | 12 | /** 13 | * AssistantToolsCode 14 | */ 15 | 16 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 17 | public class AssistantToolsCode implements AssistantObjectToolsInner, CreateThreadAndRunRequestToolsInner { 18 | 19 | /** 20 | * The type of tool being defined: `code_interpreter` 21 | */ 22 | public enum TypeEnum { 23 | CODE_INTERPRETER("code_interpreter"); 24 | 25 | private String value; 26 | 27 | TypeEnum(String value) { 28 | this.value = value; 29 | } 30 | 31 | @JsonValue 32 | public String getValue() { 33 | return value; 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return String.valueOf(value); 39 | } 40 | 41 | @JsonCreator 42 | public static TypeEnum fromValue(String value) { 43 | for (TypeEnum b : TypeEnum.values()) { 44 | if (b.value.equals(value)) { 45 | return b; 46 | } 47 | } 48 | throw new IllegalArgumentException("Unexpected value '" + value + "'"); 49 | } 50 | } 51 | 52 | private TypeEnum type; 53 | 54 | public AssistantToolsCode() { 55 | super(); 56 | } 57 | 58 | /** 59 | * Constructor with only required parameters 60 | */ 61 | public AssistantToolsCode(TypeEnum type) { 62 | this.type = type; 63 | } 64 | 65 | public AssistantToolsCode type(TypeEnum type) { 66 | this.type = type; 67 | return this; 68 | } 69 | 70 | /** 71 | * The type of tool being defined: `code_interpreter` 72 | * @return type 73 | */ 74 | @NotNull 75 | @Schema(name = "type", description = "The type of tool being defined: `code_interpreter`", requiredMode = Schema.RequiredMode.REQUIRED) 76 | @JsonProperty("type") 77 | public TypeEnum getType() { 78 | return type; 79 | } 80 | 81 | public void setType(TypeEnum type) { 82 | this.type = type; 83 | } 84 | 85 | @Override 86 | public boolean equals(Object o) { 87 | if (this == o) { 88 | return true; 89 | } 90 | if (o == null || getClass() != o.getClass()) { 91 | return false; 92 | } 93 | AssistantToolsCode assistantToolsCode = (AssistantToolsCode) o; 94 | return Objects.equals(this.type, assistantToolsCode.type); 95 | } 96 | 97 | @Override 98 | public int hashCode() { 99 | return Objects.hash(type); 100 | } 101 | 102 | @Override 103 | public String toString() { 104 | StringBuilder sb = new StringBuilder(); 105 | sb.append("class AssistantToolsCode {\n"); 106 | sb.append(" type: ").append(toIndentedString(type)).append("\n"); 107 | sb.append("}"); 108 | return sb.toString(); 109 | } 110 | 111 | /** 112 | * Convert the given object to string with each line indented by 4 spaces 113 | * (except the first line). 114 | */ 115 | private String toIndentedString(Object o) { 116 | if (o == null) { 117 | return "null"; 118 | } 119 | return o.toString().replace("\n", "\n "); 120 | } 121 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/test/java/com/telekom/ai4coding/chatbot/utils/FillingVesselAlgorithmTest.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.utils; 2 | 3 | import com.telekom.ai4coding.chatbot.configuration.properties.AcaProperties; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | import static org.junit.jupiter.api.Assertions.assertTrue; 8 | 9 | class FillingVesselAlgorithmTest { 10 | 11 | 12 | private static final int MAX_LENGTH = 30_000; 13 | 14 | private final FillingVesselAlgorithm fillingVesselAlgorithm = 15 | new FillingVesselAlgorithm(new AcaProperties(null, null 16 | , null, MAX_LENGTH, 0)); 17 | 18 | @Test 19 | void testBothInputsWithinLimit() { 20 | String llm = "A".repeat(5000); 21 | String keywords = "B".repeat(5000); 22 | String result = fillingVesselAlgorithm.fillVessel(llm, keywords); 23 | assertEquals(10000, result.length()); 24 | assertTrue(result.startsWith(llm)); 25 | assertTrue(result.endsWith(keywords)); 26 | } 27 | 28 | @Test 29 | void testExactlyMaxLength() { 30 | String llm = "A".repeat(18000); 31 | String keywords = "B".repeat(12000); 32 | String result = fillingVesselAlgorithm.fillVessel(llm, keywords); 33 | assertEquals(MAX_LENGTH, result.length()); 34 | assertEquals(llm + keywords, result); 35 | } 36 | 37 | @Test 38 | void testKeywordsLessThanIdealLength() { 39 | String llm = "A".repeat(24000); 40 | String keywords = "B".repeat(10000); 41 | String result = fillingVesselAlgorithm.fillVessel(llm, keywords); 42 | assertEquals(MAX_LENGTH, result.length()); 43 | assertTrue(result.startsWith(keywords)); 44 | assertTrue(result.endsWith("A".repeat(20000))); 45 | } 46 | 47 | @Test 48 | void testLLMLessThanIdealLength() { 49 | String llm = "A".repeat(16000); 50 | String keywords = "B".repeat(20000); 51 | String result = fillingVesselAlgorithm.fillVessel(llm, keywords); 52 | assertEquals(MAX_LENGTH, result.length()); 53 | assertTrue(result.startsWith(llm)); 54 | assertTrue(result.endsWith("B".repeat(14000))); 55 | } 56 | 57 | @Test 58 | void testBothExceedIdealLength() { 59 | String llm = "A".repeat(20000); 60 | String keywords = "B".repeat(16000); 61 | String result = fillingVesselAlgorithm.fillVessel(llm, keywords); 62 | assertEquals(MAX_LENGTH, result.length()); 63 | assertTrue(result.startsWith("B".repeat(12000))); 64 | assertTrue(result.endsWith("A".repeat(18000))); 65 | } 66 | 67 | @Test 68 | void testEmptyLLM() { 69 | String llm = ""; 70 | String keywords = "B".repeat(40000); 71 | String result = fillingVesselAlgorithm.fillVessel(llm, keywords); 72 | assertEquals(MAX_LENGTH, result.length()); 73 | assertEquals("B".repeat(MAX_LENGTH), result); 74 | } 75 | 76 | @Test 77 | void testEmptyKeywords() { 78 | String llm = "A".repeat(40000); 79 | String keywords = ""; 80 | String result = fillingVesselAlgorithm.fillVessel(llm, keywords); 81 | assertEquals(MAX_LENGTH, result.length()); 82 | assertEquals("A".repeat(MAX_LENGTH), result); 83 | } 84 | 85 | @Test 86 | void testBothEmpty() { 87 | String result = fillingVesselAlgorithm.fillVessel("", ""); 88 | assertEquals(0, result.length()); 89 | } 90 | 91 | } -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/AssistantToolsRetrieval.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import com.fasterxml.jackson.annotation.JsonValue; 6 | import io.swagger.v3.oas.annotations.media.Schema; 7 | import jakarta.annotation.Generated; 8 | import jakarta.validation.constraints.NotNull; 9 | 10 | import java.util.Objects; 11 | 12 | /** 13 | * AssistantToolsRetrieval 14 | */ 15 | 16 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 17 | public class AssistantToolsRetrieval implements AssistantObjectToolsInner, CreateThreadAndRunRequestToolsInner { 18 | 19 | /** 20 | * The type of tool being defined: `retrieval` 21 | */ 22 | public enum TypeEnum { 23 | RETRIEVAL("retrieval"); 24 | 25 | private String value; 26 | 27 | TypeEnum(String value) { 28 | this.value = value; 29 | } 30 | 31 | @JsonValue 32 | public String getValue() { 33 | return value; 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return String.valueOf(value); 39 | } 40 | 41 | @JsonCreator 42 | public static TypeEnum fromValue(String value) { 43 | for (TypeEnum b : TypeEnum.values()) { 44 | if (b.value.equals(value)) { 45 | return b; 46 | } 47 | } 48 | throw new IllegalArgumentException("Unexpected value '" + value + "'"); 49 | } 50 | } 51 | 52 | private TypeEnum type; 53 | 54 | public AssistantToolsRetrieval() { 55 | super(); 56 | } 57 | 58 | /** 59 | * Constructor with only required parameters 60 | */ 61 | public AssistantToolsRetrieval(TypeEnum type) { 62 | this.type = type; 63 | } 64 | 65 | public AssistantToolsRetrieval type(TypeEnum type) { 66 | this.type = type; 67 | return this; 68 | } 69 | 70 | /** 71 | * The type of tool being defined: `retrieval` 72 | * @return type 73 | */ 74 | @NotNull 75 | @Schema(name = "type", description = "The type of tool being defined: `retrieval`", requiredMode = Schema.RequiredMode.REQUIRED) 76 | @JsonProperty("type") 77 | public TypeEnum getType() { 78 | return type; 79 | } 80 | 81 | public void setType(TypeEnum type) { 82 | this.type = type; 83 | } 84 | 85 | @Override 86 | public boolean equals(Object o) { 87 | if (this == o) { 88 | return true; 89 | } 90 | if (o == null || getClass() != o.getClass()) { 91 | return false; 92 | } 93 | AssistantToolsRetrieval assistantToolsRetrieval = (AssistantToolsRetrieval) o; 94 | return Objects.equals(this.type, assistantToolsRetrieval.type); 95 | } 96 | 97 | @Override 98 | public int hashCode() { 99 | return Objects.hash(type); 100 | } 101 | 102 | @Override 103 | public String toString() { 104 | StringBuilder sb = new StringBuilder(); 105 | sb.append("class AssistantToolsRetrieval {\n"); 106 | sb.append(" type: ").append(toIndentedString(type)).append("\n"); 107 | sb.append("}"); 108 | return sb.toString(); 109 | } 110 | 111 | /** 112 | * Convert the given object to string with each line indented by 4 spaces 113 | * (except the first line). 114 | */ 115 | private String toIndentedString(Object o) { 116 | if (o == null) { 117 | return "null"; 118 | } 119 | return o.toString().replace("\n", "\n "); 120 | } 121 | } -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/test/java/com/telekom/ai4coding/chatbot/treesitter/FileTypeTest.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.treesitter; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.*; 6 | 7 | class FileTypeTest { 8 | 9 | @Test 10 | void testFromFileName_withValidExtensions() { 11 | assertEquals(FileType.JAVA, FileType.fromFileName("MyClass.java")); 12 | assertEquals(FileType.PYTHON, FileType.fromFileName("script.py")); 13 | assertEquals(FileType.JAVASCRIPT, FileType.fromFileName("app.js")); 14 | assertEquals(FileType.CSHARP, FileType.fromFileName("program.cs")); 15 | assertEquals(FileType.MARKDOWN, FileType.fromFileName("README.md")); 16 | assertEquals(FileType.TYPESCRIPT, FileType.fromFileName("component.ts")); 17 | assertEquals(FileType.TYPESCRIPT, FileType.fromFileName("component.tsx")); 18 | assertEquals(FileType.HTML, FileType.fromFileName("index.html")); 19 | assertEquals(FileType.BASH, FileType.fromFileName("script.sh")); 20 | assertEquals(FileType.C, FileType.fromFileName("source.c")); 21 | assertEquals(FileType.SQL, FileType.fromFileName("query.sql")); 22 | assertEquals(FileType.YAML, FileType.fromFileName("config.yaml")); 23 | assertEquals(FileType.YAML, FileType.fromFileName("config.yml")); 24 | assertEquals(FileType.COMMONLISP, FileType.fromFileName("code.lisp")); 25 | assertEquals(FileType.COMMONLISP, FileType.fromFileName("code.lsp")); 26 | assertEquals(FileType.COMMONLISP, FileType.fromFileName("code.l")); 27 | assertEquals(FileType.COMMONLISP, FileType.fromFileName("code.cl")); 28 | assertEquals(FileType.JSON, FileType.fromFileName("config.json")); 29 | assertEquals(FileType.JSON, FileType.fromFileName("config.map")); 30 | assertEquals(FileType.JSON, FileType.fromFileName("config.topojson")); 31 | assertEquals(FileType.JSON, FileType.fromFileName("config.geojson")); 32 | assertEquals(FileType.DOCKERFILE, FileType.fromFileName("docker.dockerfile")); 33 | } 34 | 35 | @Test 36 | void testFromFileName_withoutStandardExtensions() { 37 | // special files that do not have an extension 38 | assertEquals(FileType.DOCKERFILE, FileType.fromFileName("Dockerfile")); 39 | assertEquals(FileType.MAKE, FileType.fromFileName("Makefile")); 40 | } 41 | 42 | @Test 43 | void testFromFileName_withNull() { 44 | assertEquals(FileType.OTHER, FileType.fromFileName(null)); 45 | } 46 | 47 | @Test 48 | void testFromFileName_withNoExtension() { 49 | assertEquals(FileType.OTHER, FileType.fromFileName("fileWithoutExtension")); 50 | } 51 | 52 | @Test 53 | void testFromFileName_withCaseSensitivity() { 54 | // file systems are typically case-insensitive, so making sure the comparison is as well, except "Dockerfile" and "Makefile" file types 55 | assertEquals(FileType.DOCKERFILE, FileType.fromFileName("Dockerfile")); 56 | assertNotEquals(FileType.DOCKERFILE, FileType.fromFileName("dockerfile")); 57 | assertNotEquals(FileType.DOCKERFILE, FileType.fromFileName("DOCKERFILE")); 58 | assertEquals(FileType.MAKE, FileType.fromFileName("Makefile")); 59 | assertNotEquals(FileType.MAKE, FileType.fromFileName("makefile")); 60 | assertNotEquals(FileType.MAKE, FileType.fromFileName("MAKEFILE")); 61 | assertEquals(FileType.PYTHON, FileType.fromFileName("SCRIPT.PY")); 62 | assertEquals(FileType.JAVA, FileType.fromFileName("MyClass.JAVA")); 63 | } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /chatbot-openai-code-migration-app/src/test/java/com/telekom/ai4coding/chatbot/graph/ASTNodeTest.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.chatbot.graph; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | import java.util.List; 7 | 8 | public class ASTNodeTest { 9 | 10 | @Test 11 | public void testASTNodeCreationWithoutChildren() { 12 | // Given 13 | String type = "node type"; 14 | String text = "node text"; 15 | int startLine = 1; 16 | int endLine = 2; 17 | 18 | // When 19 | ASTNode astNode = ASTNode.of(type, text, startLine, endLine, null); 20 | 21 | // Then 22 | assertThat(astNode.getType()).isEqualTo(type); 23 | assertThat(astNode.getText()).isEqualTo(text); 24 | assertThat(astNode.getStartLine()).isEqualTo(startLine); 25 | assertThat(astNode.getEndLine()).isEqualTo(endLine); 26 | assertThat(astNode.getChildASTNodes()).isNull(); 27 | } 28 | 29 | @Test 30 | public void testASTNodeCreationWithChildren() { 31 | // Given 32 | String parentType = "parent node type"; 33 | String childType = "child node type"; 34 | ASTNode childNode = ASTNode.of(childType, "child node text", 2, 3, null); 35 | 36 | // When 37 | ASTNode parentNode = new ASTNode(null, parentType, "parent node text", 1, 4, null, List.of(childNode)); 38 | 39 | // Then 40 | assertThat(parentNode.getChildASTNodes()).contains(childNode); 41 | assertThat(parentNode.getChildASTNodes()).hasSize(1); 42 | } 43 | 44 | @Test 45 | public void testAddChildASTNode() { 46 | // Given 47 | ASTNode parentNode = ASTNode.of("parent node type", "parent node text", 1, 4, null); 48 | ASTNode childNode1 = ASTNode.of("child node type 1", "child node text 1", 2, 3, null); 49 | ASTNode childNode2 = ASTNode.of("child node type 2", "child node text 2", 4, 5, null); 50 | 51 | // When 52 | parentNode.addChildASTNode(childNode1); 53 | parentNode.addChildASTNode(childNode2); 54 | 55 | // Then 56 | assertThat(parentNode.getChildASTNodes()).containsExactly(childNode1, childNode2); 57 | } 58 | 59 | @Test 60 | public void testWithId() { 61 | // Given 62 | ASTNode node = ASTNode.of("node type", "node text", 1, 2, null); 63 | Long newId = 100L; 64 | 65 | // When 66 | ASTNode nodeWithId = node.withId(newId); 67 | 68 | // Then 69 | assertThat(nodeWithId.getId()).isEqualTo(newId); 70 | assertThat(nodeWithId.getType()).isEqualTo(node.getType()); 71 | assertThat(nodeWithId.getText()).isEqualTo(node.getText()); 72 | assertThat(nodeWithId.getStartLine()).isEqualTo(node.getStartLine()); 73 | assertThat(nodeWithId.getEndLine()).isEqualTo(node.getEndLine()); 74 | } 75 | 76 | @Test 77 | public void testEqualsMethod() { 78 | // Given 79 | ASTNode node1 = ASTNode.of("node type", "node text", 1, 2, null); 80 | ASTNode node2 = ASTNode.of("node type", "node text", 1, 2, null); 81 | ASTNode node3 = ASTNode.of("different node type", "node text", 1, 2, null); 82 | ASTNode node4 = ASTNode.of("node type", "different node text", 1, 2, null); 83 | ASTNode node5 = ASTNode.of("node type", "node text", 3, 4, null); 84 | 85 | // Then 86 | assertThat(node1).isEqualTo(node2); 87 | assertThat(node1).isNotEqualTo(node3); 88 | assertThat(node1).isNotEqualTo(node4); 89 | assertThat(node1).isNotEqualTo(node5); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /openai-api/src/main/java/com/telekom/ai4coding/openai/model/SubmitToolOutputsRunRequestToolOutputsInner.java: -------------------------------------------------------------------------------- 1 | package com.telekom.ai4coding.openai.model; 2 | 3 | import java.util.Objects; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import com.fasterxml.jackson.annotation.JsonTypeName; 6 | import io.swagger.v3.oas.annotations.media.Schema; 7 | 8 | 9 | import jakarta.annotation.Generated; 10 | 11 | /** 12 | * SubmitToolOutputsRunRequestToolOutputsInner 13 | */ 14 | 15 | @JsonTypeName("SubmitToolOutputsRunRequest_tool_outputs_inner") 16 | @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") 17 | public class SubmitToolOutputsRunRequestToolOutputsInner { 18 | 19 | private String toolCallId; 20 | 21 | private String output; 22 | 23 | public SubmitToolOutputsRunRequestToolOutputsInner toolCallId(String toolCallId) { 24 | this.toolCallId = toolCallId; 25 | return this; 26 | } 27 | 28 | /** 29 | * The ID of the tool call in the `required_action` object within the run object the output is being submitted for. 30 | * @return toolCallId 31 | */ 32 | 33 | @Schema(name = "tool_call_id", description = "The ID of the tool call in the `required_action` object within the run object the output is being submitted for.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) 34 | @JsonProperty("tool_call_id") 35 | public String getToolCallId() { 36 | return toolCallId; 37 | } 38 | 39 | public void setToolCallId(String toolCallId) { 40 | this.toolCallId = toolCallId; 41 | } 42 | 43 | public SubmitToolOutputsRunRequestToolOutputsInner output(String output) { 44 | this.output = output; 45 | return this; 46 | } 47 | 48 | /** 49 | * The output of the tool call to be submitted to continue the run. 50 | * @return output 51 | */ 52 | 53 | @Schema(name = "output", description = "The output of the tool call to be submitted to continue the run.", requiredMode = Schema.RequiredMode.NOT_REQUIRED) 54 | @JsonProperty("output") 55 | public String getOutput() { 56 | return output; 57 | } 58 | 59 | public void setOutput(String output) { 60 | this.output = output; 61 | } 62 | 63 | @Override 64 | public boolean equals(Object o) { 65 | if (this == o) { 66 | return true; 67 | } 68 | if (o == null || getClass() != o.getClass()) { 69 | return false; 70 | } 71 | SubmitToolOutputsRunRequestToolOutputsInner submitToolOutputsRunRequestToolOutputsInner = (SubmitToolOutputsRunRequestToolOutputsInner) o; 72 | return Objects.equals(this.toolCallId, submitToolOutputsRunRequestToolOutputsInner.toolCallId) && 73 | Objects.equals(this.output, submitToolOutputsRunRequestToolOutputsInner.output); 74 | } 75 | 76 | @Override 77 | public int hashCode() { 78 | return Objects.hash(toolCallId, output); 79 | } 80 | 81 | @Override 82 | public String toString() { 83 | StringBuilder sb = new StringBuilder(); 84 | sb.append("class SubmitToolOutputsRunRequestToolOutputsInner {\n"); 85 | sb.append(" toolCallId: ").append(toIndentedString(toolCallId)).append("\n"); 86 | sb.append(" output: ").append(toIndentedString(output)).append("\n"); 87 | sb.append("}"); 88 | return sb.toString(); 89 | } 90 | 91 | /** 92 | * Convert the given object to string with each line indented by 4 spaces 93 | * (except the first line). 94 | */ 95 | private String toIndentedString(Object o) { 96 | if (o == null) { 97 | return "null"; 98 | } 99 | return o.toString().replace("\n", "\n "); 100 | } 101 | } --------------------------------------------------------------------------------