Skip to content
Merged

wip #37

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 28 additions & 3 deletions core/src/main/kotlin/com/simiacryptus/cognotik/input/PDFReader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,29 @@ import org.apache.pdfbox.pdmodel.PDDocument
import org.apache.pdfbox.rendering.PDFRenderer
import org.apache.pdfbox.text.PDFTextStripper
import java.awt.image.BufferedImage
import java.io.File
import java.io.File
import javax.imageio.ImageIO
import javax.imageio.spi.IIORegistry
import javax.imageio.spi.ImageReaderSpi
import javax.imageio.spi.ImageWriterSpi
import java.util.ServiceLoader

class PDFReader(pdfFile: File) : PaginatedDocumentReader, RenderableDocumentReader {
class PDFReader(pdfFile: File) : PaginatedDocumentReader, RenderableDocumentReader {
private val document: PDDocument = Loader.loadPDF(pdfFile)
private val renderer: PDFRenderer = PDFRenderer(document)
companion object {
init {
val registry = IIORegistry.getDefaultInstance()
val loader = PDFReader::class.java.classLoader
ServiceLoader.load(ImageReaderSpi::class.java, loader).forEach {
registry.registerServiceProvider(it)
}
ServiceLoader.load(ImageWriterSpi::class.java, loader).forEach {
registry.registerServiceProvider(it)
}
}
}

override fun getText(): String {
val stripper = PDFTextStripper().apply { sortByPosition = true }
return stripper.getText(document)
Expand All @@ -27,7 +45,14 @@ class PDFReader(pdfFile: File) : PaginatedDocumentReader, RenderableDocumentRead
}

override fun renderImage(pageIndex: Int, dpi: Float): BufferedImage {
return renderer.renderImageWithDPI(pageIndex, dpi)
val currentThread = Thread.currentThread()
val originalClassLoader = currentThread.contextClassLoader
try {
currentThread.contextClassLoader = this::class.java.classLoader
return renderer.renderImageWithDPI(pageIndex, dpi)
} finally {
currentThread.contextClassLoader = originalClassLoader
}
}

override fun close() {
Expand Down
70 changes: 54 additions & 16 deletions desktop/src/main/resources/welcome/modules/task-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,20 @@ class TaskConfigManager {
category: 'File Operations',
configFields: []
},
{
id: 'TableCompilation',
name: 'Table Compilation',
description: 'Compile data into tables',
category: 'File Operations',
configFields: []
},
{
id: 'ImageTable',
name: 'Image Table',
description: 'Generate tables containing images',
category: 'File Operations',
configFields: []
},
{
id: 'VectorSearch',
name: 'Vector Search Task',
Expand Down Expand Up @@ -610,13 +624,6 @@ class TaskConfigManager {
}
]
},
{
id: 'NarrativeReasoning',
name: 'Narrative Reasoning',
description: 'Understand and analyze narrative structures',
category: 'Writing',
configFields: []
},
{
id: 'NarrativeGeneration',
name: 'Narrative Generation',
Expand All @@ -631,6 +638,20 @@ class TaskConfigManager {
category: 'Reasoning',
configFields: []
},
{
id: 'MathematicalReasoning',
name: 'Mathematical Reasoning',
description: 'Solve mathematical problems and proofs',
category: 'Reasoning',
configFields: []
},
{
id: 'NeuralNetworkLayer',
name: 'Neural Network Layer',
description: 'Simulate or design neural network layers',
category: 'Reasoning',
configFields: []
},
{
id: 'EthicalReasoning',
name: 'Ethical Reasoning',
Expand Down Expand Up @@ -715,20 +736,27 @@ class TaskConfigManager {
category: 'Writing',
configFields: []
},
{
id: 'SoftwareDesignDocument',
name: 'Software Design Document',
description: 'Generate software design documentation',
category: 'Writing',
configFields: []
},
{
id: 'ComicBookGeneration',
name: 'Comic Book Generation',
description: 'Generate comic book pages and stories',
category: 'Writing',
configFields: []
},
{
id: 'GenerateImage',
name: 'Generate Image',
description: 'Generate images using AI image generation',
category: 'File Operations',
configFields: []
},
{
id: 'CommandSession',
name: 'Command Session Task',
description: 'Execute a series of commands in a session',
category: 'Execution & Automation',
configFields: []
},
{
id: 'SubPlanning',
name: 'Sub-Planning',
Expand Down Expand Up @@ -814,6 +842,13 @@ class TaskConfigManager {
description: 'Add illustrations and visual elements to documents',
category: 'File Operations',
configFields: []
},
{
id: 'GenerateQRImage',
name: 'Generate QR Image',
description: 'Generate QR codes',
category: 'File Operations',
configFields: []
}
];
}
Expand Down Expand Up @@ -946,7 +981,7 @@ class TaskConfigManager {

// Populate model dropdown
this.populateTaskModelDropdown(modal, configModel);

// Set up sub-tasks event handlers if this is a SubPlanning task
if (taskType.id === 'SubPlanning') {
this.setupSubTasksHandlers(modal, existingConfig);
Expand Down Expand Up @@ -1053,6 +1088,7 @@ class TaskConfigManager {
</div>
`;
}

// Set up event handlers for sub-tasks management
setupSubTasksHandlers(modal, existingConfig) {
// Initialize sub-tasks data on modal
Expand Down Expand Up @@ -1085,6 +1121,7 @@ class TaskConfigManager {
this.attachSubTaskItemHandlers(modal, item);
});
}

// Attach event handlers to a sub-task item
attachSubTaskItemHandlers(modal, item) {
const key = item.dataset.key;
Expand Down Expand Up @@ -1128,6 +1165,7 @@ class TaskConfigManager {
});
}
}

// Show task type selection dialog
showTaskTypeSelectionDialog() {
return new Promise((resolve, reject) => {
Expand Down Expand Up @@ -1322,6 +1360,6 @@ class TaskConfigManager {
}
}

if (typeof module !== 'undefined' && module.exports) {
if (typeof module !== 'undefined' && module.exports) {
module.exports = {TaskConfigManager};
}
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
pluginName=Cognotik - Open Source Agentic Power Tools
pluginRepositoryUrl=https://github.com/SimiaCryptus/Cognotik
libraryGroup=com.simiacryptus
libraryVersion=2.0.30
libraryVersion=2.0.31
# Maven Central Publishing
cognotikGroup=com.cognotik
cognotikVersion=2.0.30
cognotikVersion=2.0.31
# Signing (set these in ~/.gradle/gradle.properties or as environment variables)
# signing.keyId=<last 8 chars of key>
# signing.password=<key password>
Expand Down
4 changes: 4 additions & 0 deletions intellij/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ dependencies {
implementation(libs.slf4j.api)
implementation(libs.logback.classic)

implementation("com.github.jai-imageio:jai-imageio-core:1.4.0")
implementation("com.github.jai-imageio:jai-imageio-jpeg2000:1.4.0")
implementation("org.apache.pdfbox:jbig2-imageio:3.0.4")

testImplementation(platform(libs.junit.bom))
testImplementation(libs.junit.jupiter.api)
testRuntimeOnly(libs.junit.jupiter.engine)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ class GenericChatAction : BaseAction() {
)
SessionProxyServer.agents[session] = ChatSocketManager(
session = session,
model = AppSettingsState.instance.smartChatClient,
parsingModel = AppSettingsState.instance.fastChatClient,
smartModel = AppSettingsState.instance.smartChatClient,
fastModel = AppSettingsState.instance.fastChatClient,
systemPrompt = systemPrompt,
applicationClass = ApplicationServer::class.java,
storage = ApplicationServices.fileApplicationServices().dataStorageFactory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ class ImageChatAction : BaseAction() {
private val codeFiles: Set<Path>
) : ChatSocketManager(
session = session,
model = model,
parsingModel = parsingModel,
smartModel = model,
fastModel = parsingModel,
systemPrompt = "",
applicationClass = ApplicationServer::class.java,
storage = ApplicationServices.fileApplicationServices().dataStorageFactory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ open class ModifyFilesAction(
private val showLineNumbers: Boolean = false
) : ChatSocketManager(
session = session,
model = model,
parsingModel = parsingModel,
smartModel = model,
fastModel = parsingModel,
systemPrompt = "",
applicationClass = ApplicationServer::class.java,
storage = ApplicationServices.fileApplicationServices().dataStorageFactory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ class MultiCodeChatAction : BaseAction() {
private val codeFiles: Set<Path>
) : ChatSocketManager(
session = session,
model = model,
parsingModel = parsingModel,
smartModel = model,
fastModel = parsingModel,
systemPrompt = "",
applicationClass = ApplicationServer::class.java,
storage = ApplicationServices.fileApplicationServices().dataStorageFactory,
Expand Down
86 changes: 86 additions & 0 deletions intellij/src/main/kotlin/cognotik/actions/chat/SmartChatAction.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package cognotik.actions.chat

import cognotik.actions.BaseAction
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.application.ApplicationManager
import com.simiacryptus.cognotik.CognotikAppServer
import com.simiacryptus.cognotik.config.AppSettingsState
import com.simiacryptus.cognotik.platform.ApplicationServices
import com.simiacryptus.cognotik.platform.Session
import com.simiacryptus.cognotik.util.BrowseUtil.browse
import com.simiacryptus.cognotik.util.LoggerFactory
import com.simiacryptus.cognotik.util.SessionProxyServer
import com.simiacryptus.cognotik.util.UITools
import com.simiacryptus.cognotik.webui.application.AppInfoData
import com.simiacryptus.cognotik.webui.application.ApplicationServer
import com.simiacryptus.cognotik.webui.chat.SmartChatSocketManager
import java.text.SimpleDateFormat

/**
* Smart Chat Action that provides enhanced chat functionality with:
* - Automatic history summarization when conversation gets too long
* - Query elevation from fast model to smart model for complex queries
*/
class SmartChatAction : BaseAction() {
override fun getActionUpdateThread() = ActionUpdateThread.BGT

private val systemPrompt = """
You are a helpful AI assistant with expertise in software development, coding, and technical problem-solving.
You provide clear, accurate, and well-structured responses.
When discussing code, you explain your reasoning and suggest best practices.
""".trimIndent()

override fun handle(e: AnActionEvent) {
val project = e.project ?: return

try {
UITools.runAsync(project, "Initializing Smart Chat", true) { progress ->
progress.isIndeterminate = true
progress.text = "Setting up smart chat session..."

val session = Session.newGlobalID()
SessionProxyServer.metadataStorage.setSessionName(
null,
session,
"Smart Chat @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}"
)
SessionProxyServer.agents[session] = SmartChatSocketManager(
session = session,
smartModel = AppSettingsState.instance.smartChatClient,
fastModel = AppSettingsState.instance.fastChatClient,
systemPrompt = systemPrompt,
applicationClass = ApplicationServer::class.java,
storage = ApplicationServices.fileApplicationServices().dataStorageFactory,
budget = 2.0,
maxHistoryTokens = 4000,
targetSummaryTokens = 1000,
preserveRecentMessages = 4
)
ApplicationServer.appInfoMap[session] = AppInfoData(
applicationName = "Smart Chat",
inputCnt = 0,
stickyInput = true,
loadImages = false,
showMenubar = false
)

val uri = CognotikAppServer.getServer().server.uri.resolve("/#$session")
ApplicationManager.getApplication().executeOnPooledThread {
try {
BaseAction.log.info("Opening browser to $uri")
browse(uri)
} catch (e: Throwable) {
UITools.error(log, "Failed to open browser", e)
}
}
}
} catch (e: Throwable) {
log.warn("Error opening browser", e)
}
}

companion object {
private val log = LoggerFactory.getLogger(SmartChatAction::class.java)
}
}
Loading
Loading