Skip to content
Merged
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.ai.assistance.operit.core.tools.packTool.ToolPkgComposeDslNode
import com.ai.assistance.operit.core.tools.packTool.uidsl.ToolPkgComposeDslNode
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Rule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ class ToolCardStreamBoundaryAndroidTest {
@get:Rule val composeRule = createComposeRule()

private fun chars(text: String): Stream<Char> = stream { text.forEach { emit(it) } }
// XML 属性含双引号,使用原始字符串避免测试样例被误解析为 Kotlin 代码。
private fun tool(value: String): String =
"<tool name="create_file"><param name="new">$value</param></tool>"
"""<tool name="create_file"><param name="new">$value</param></tool>"""

private fun render(prefix: String?, tail: String): StreamMarkdownRendererState {
val state = StreamMarkdownRendererState()
Expand All @@ -52,13 +53,13 @@ class ToolCardStreamBoundaryAndroidTest {

@Test fun closedToolPrefixKeepsFollowingRequestAndResultSeparate() {
val first = tool("首次")
val result = "<tool_result name="create_file" status="success"><content>已创建</content></tool_result>"
val result = """<tool_result name="create_file" status="success"><content>已创建</content></tool_result>"""
val next = tool("第二次")
assertBlocks(render(first, result + next), listOf(first, result, next))
}

@Test fun unfinishedToolContinuesOnceAndNewToolsStartNewCards() {
val prefix = "<tool name="create_file"><param name="new">开始"
val prefix = """<tool name="create_file"><param name="new">开始"""
val close = "继续</param></tool>"
val next = listOf(tool("第二次"), tool("第三次"))
assertBlocks(render(prefix, close + next.joinToString("")), listOf(prefix + close) + next)
Expand Down Expand Up @@ -96,7 +97,7 @@ class ToolCardStreamBoundaryAndroidTest {
}

@Test fun xmlReplayIncludesRestoredPrefixAndEndsBeforeMessageCompletion() {
val prefix = "<tool name="create_file"><param name="new">开始"
val prefix = """<tool name="create_file"><param name="new">开始"""
val body = "继续"
val end = "</param></tool>"
val source = MutableSharedStreamImpl<Char>(replay = Int.MAX_VALUE)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.ai.assistance.operit.ui.features.conversation.chat.components.timeline
package com.ai.assistance.operit.ui.features.conversation.chat.modules.messages.timeline

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.MaterialTheme
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.ai.assistance.operit.ui.features.conversation.chat.webview.workspace.editor
package com.ai.assistance.operit.ui.features.conversation.workspace.editor

import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Assert.*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.ai.assistance.operit.ui.features.conversation.chat.webview.workspace.editor
package com.ai.assistance.operit.ui.features.conversation.workspace.editor

import android.view.inputmethod.EditorInfo
import androidx.compose.material3.MaterialTheme
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const {
runSuite,
} = require('./common');

const AndroidShellExecutor = Java.com.ai.assistance.operit.core.tools.system.AndroidShellExecutor;
const AndroidShellExecutor = Java.com.ai.assistance.operit.core.tools.system.shell.AndroidShellExecutor;
const StandardActionListener = Java.com.ai.assistance.operit.core.tools.system.action.StandardActionListener;
const StreamBuildersKt = Java.type('com.ai.assistance.operit.util.stream.StreamBuildersKt');

Expand All @@ -28,7 +28,7 @@ function assertCommandResultProxy(result, label) {
assert(result && typeof result === 'object', (label || 'result') + ' should be an object');
assertEq(
String(result.className),
'com.ai.assistance.operit.core.tools.system.AndroidShellExecutor$CommandResult',
'com.ai.assistance.operit.core.tools.system.shell.AndroidShellExecutor$CommandResult',
(label || 'result') + ' className mismatch'
);
assertEq(typeof result.success, 'boolean', (label || 'result') + ' success should be boolean');
Expand All @@ -51,7 +51,7 @@ exports.run = async function run() {
test('Java.callSuspend awaits companion suspend method and returns proxy result', async () => {
const result = await withTimeout(
Java.callSuspend(
'com.ai.assistance.operit.core.tools.system.AndroidShellExecutor',
'com.ai.assistance.operit.core.tools.system.shell.AndroidShellExecutor',
'executeShellCommand',
'echo bridge-contract-suspend-top-level'
),
Expand Down
8 changes: 4 additions & 4 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,15 @@
tools:node="remove" />

<activity
android:name=".core.tools.defaultTool.websession.browser.WebSessionPermissionRequestActivity"
android:name=".core.tools.builtin.web.session.browser.WebSessionPermissionRequestActivity"
android:excludeFromRecents="true"
android:exported="false"
android:finishOnTaskLaunch="true"
android:noHistory="true"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />

<activity
android:name=".core.tools.defaultTool.websession.userscript.install.UserscriptImportPickerActivity"
android:name=".core.tools.builtin.web.session.userscript.install.UserscriptImportPickerActivity"
android:excludeFromRecents="true"
android:exported="false"
android:finishOnTaskLaunch="true"
Expand Down Expand Up @@ -314,7 +314,7 @@
</activity>

<activity
android:name=".core.tools.system.ScreenCaptureActivity"
android:name=".core.tools.system.capture.ScreenCaptureActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:excludeFromRecents="true"
android:exported="false" />
Expand All @@ -327,7 +327,7 @@
android:foregroundServiceType="dataSync" />

<service
android:name=".core.tools.system.ScreenCaptureService"
android:name=".core.tools.system.capture.ScreenCaptureService"
android:enabled="true"
android:exported="false"
android:foregroundServiceType="mediaProjection" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ import com.ai.assistance.operit.core.chat.hooks.mergeAdjacentTurns
import com.ai.assistance.operit.core.chat.hooks.toPromptTurns
import com.ai.assistance.operit.core.chat.hooks.toRoleContentPairs
import com.ai.assistance.operit.core.application.ActivityLifecycleManager
import com.ai.assistance.operit.core.tools.AIToolHandler
import com.ai.assistance.operit.core.tools.runtime.AIToolHandler
import com.ai.assistance.operit.core.tools.StringResultData
import com.ai.assistance.operit.core.tools.climode.CliToolModeSupport
import com.ai.assistance.operit.core.tools.climode.ToolExposureMode
import com.ai.assistance.operit.core.tools.packTool.PackageManager
import com.ai.assistance.operit.core.tools.packTool.runtime.PackageManager
import com.ai.assistance.operit.core.tools.permissions.PermissionCapabilitySession
import com.ai.assistance.operit.data.model.FunctionType
import com.ai.assistance.operit.data.model.InputProcessingState
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ import com.ai.assistance.operit.plugins.lifecycle.AppLifecycleEvent
import com.ai.assistance.operit.plugins.lifecycle.AppLifecycleHookParams
import com.ai.assistance.operit.plugins.lifecycle.AppLifecycleHookPluginRegistry
import com.ai.assistance.operit.core.config.SystemPromptConfig
import com.ai.assistance.operit.core.tools.AIToolHandler
import com.ai.assistance.operit.core.tools.system.AndroidShellExecutor
import com.ai.assistance.operit.core.tools.system.Terminal
import com.ai.assistance.operit.core.tools.runtime.AIToolHandler
import com.ai.assistance.operit.core.tools.system.shell.AndroidShellExecutor
import com.ai.assistance.operit.core.tools.system.terminal.Terminal
import com.ai.assistance.operit.core.workflow.WorkflowSchedulerInitializer
import com.ai.assistance.operit.data.backup.RoomDatabaseBackupPreferences
import com.ai.assistance.operit.data.backup.RoomDatabaseBackupScheduler
Expand All @@ -43,8 +43,8 @@ import com.ai.assistance.operit.data.preferences.initUserPreferencesManager
import com.ai.assistance.operit.data.preferences.preferencesManager
import com.ai.assistance.operit.data.repository.CustomEmojiRepository
import com.ai.assistance.operit.data.stats.TokenUsageRepository
import com.ai.assistance.operit.ui.features.conversation.chat.webview.LocalWebServer
import com.ai.assistance.operit.ui.features.conversation.chat.webview.workspace.editor.language.LanguageFactory
import com.ai.assistance.operit.ui.features.conversation.workspace.preview.LocalWebServer
import com.ai.assistance.operit.ui.features.conversation.workspace.editor.language.LanguageFactory
import com.ai.assistance.operit.core.diagnostics.GlobalExceptionHandler
import com.ai.assistance.operit.util.media.ImagePoolManager
import com.ai.assistance.operit.util.android.LocaleUtils
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ import com.ai.assistance.operit.core.chat.hooks.PromptTurnKind
import com.ai.assistance.operit.core.chat.plugins.MessageProcessingController
import com.ai.assistance.operit.core.chat.plugins.MessageProcessingHookParams
import com.ai.assistance.operit.core.chat.plugins.MessageProcessingPluginRegistry
import com.ai.assistance.operit.core.tools.AIToolHandler
import com.ai.assistance.operit.core.tools.runtime.AIToolHandler
import com.ai.assistance.operit.core.tools.MemoryQueryResultData
import com.ai.assistance.operit.core.tools.packTool.PackageManager
import com.ai.assistance.operit.core.tools.packTool.runtime.PackageManager
import com.ai.assistance.operit.data.model.AITool
import com.ai.assistance.operit.data.model.AttachmentInfo
import com.ai.assistance.operit.data.model.ChatMessage
Expand All @@ -36,8 +36,8 @@ import com.ai.assistance.operit.data.model.ChatMessageTimestampAllocator
import com.ai.assistance.operit.data.model.ToolParameter
import com.ai.assistance.operit.data.model.PromptFunctionType
import com.ai.assistance.operit.data.preferences.ApiPreferences
import com.ai.assistance.operit.ui.features.conversation.chat.webview.workspace.process.WorkspaceAttachmentProcessor
import com.ai.assistance.operit.ui.features.conversation.chat.webview.workspace.process.WorkspaceChangeTracker
import com.ai.assistance.operit.ui.features.conversation.workspace.process.WorkspaceAttachmentProcessor
import com.ai.assistance.operit.ui.features.conversation.workspace.process.WorkspaceChangeTracker
import com.ai.assistance.operit.util.media.ImagePoolManager
import com.ai.assistance.operit.util.media.MediaPoolManager
import com.ai.assistance.operit.core.chat.context.ChatUtils
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import com.ai.assistance.operit.core.chat.hooks.toPromptTurns
import com.ai.assistance.operit.core.config.SystemPromptConfig
import com.ai.assistance.operit.core.tools.climode.ToolExposureMode
import com.ai.assistance.operit.R
import com.ai.assistance.operit.core.tools.AIToolHandler
import com.ai.assistance.operit.core.tools.packTool.PackageManager
import com.ai.assistance.operit.core.tools.runtime.AIToolHandler
import com.ai.assistance.operit.core.tools.packTool.runtime.PackageManager
import com.ai.assistance.operit.data.model.AITool
import com.ai.assistance.operit.data.model.ConversationSummaryConfig
import com.ai.assistance.operit.data.model.FunctionType
Expand All @@ -47,7 +47,7 @@ import com.ai.assistance.operit.util.stream.TextStreamEventType
import com.ai.assistance.operit.util.stream.TextStreamRevisionTracker
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import com.ai.assistance.operit.core.tools.ToolProgressBus
import com.ai.assistance.operit.core.tools.runtime.ToolProgressBus
import com.ai.assistance.operit.util.streamnative.NativeXmlSplitter
import com.github.difflib.DiffUtils
import com.github.difflib.UnifiedDiffUtils
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.ai.assistance.operit.core.chat.protocol
import android.content.Context
import com.ai.assistance.operit.R
import com.ai.assistance.operit.core.chat.media.MediaLinkParser
import com.ai.assistance.operit.core.tools.ToolExecutionLimits
import com.ai.assistance.operit.core.tools.runtime.ToolExecutionLimits
import com.ai.assistance.operit.core.chat.protocol.ChatMarkupRegex
import com.ai.assistance.operit.util.media.ImagePoolManager
import com.ai.assistance.operit.data.model.ToolResult
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ import com.ai.assistance.operit.ui.common.a2ui.CardFences
import android.content.Context
import com.ai.assistance.operit.R
import com.ai.assistance.operit.util.logging.AppLogger
import com.ai.assistance.operit.core.tools.AIToolHandler
import com.ai.assistance.operit.core.tools.AIToolHookDecision
import com.ai.assistance.operit.core.tools.runtime.AIToolHandler
import com.ai.assistance.operit.core.tools.runtime.AIToolHookDecision
import com.ai.assistance.operit.core.chat.protocol.toolFailurePayload
import com.ai.assistance.operit.core.tools.StringResultData
import com.ai.assistance.operit.core.tools.ToolExecutor
import com.ai.assistance.operit.core.tools.runtime.ToolExecutor
import com.ai.assistance.operit.core.tools.climode.CliToolModeSupport
import com.ai.assistance.operit.core.tools.climode.ToolExposureMode
import com.ai.assistance.operit.data.model.ToolInvocation
import com.ai.assistance.operit.data.model.ToolResult
import com.ai.assistance.operit.core.tools.packTool.PackageManager
import com.ai.assistance.operit.core.tools.packTool.runtime.PackageManager
import com.ai.assistance.operit.core.tools.permissions.PermissionCapabilityResolver
import com.ai.assistance.operit.core.tools.permissions.PermissionCapabilitySession
import com.ai.assistance.operit.util.stream.StreamCollector
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import com.ai.assistance.operit.core.chat.hooks.PromptHookContext
import com.ai.assistance.operit.core.chat.hooks.PromptHookRegistry
import com.ai.assistance.operit.core.tools.climode.CliToolModeSupport
import com.ai.assistance.operit.core.tools.climode.ToolExposureMode
import com.ai.assistance.operit.core.tools.packTool.PackageManager
import com.ai.assistance.operit.core.tools.packTool.runtime.PackageManager
import com.ai.assistance.operit.data.preferences.ApiPreferences
import com.ai.assistance.operit.data.skill.SkillRepository
import com.ai.assistance.operit.ui.features.conversation.chat.webview.workspace.process.WorkspaceRuleFileReader
import com.ai.assistance.operit.ui.features.conversation.workspace.process.WorkspaceRuleFileReader
import com.ai.assistance.operit.util.android.LocaleUtils

object SystemPromptConfig {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import com.ai.assistance.operit.core.chat.hooks.PromptHookRegistry
import com.ai.assistance.operit.data.model.SystemToolPromptCategory
import com.ai.assistance.operit.data.model.ToolPrompt
import com.ai.assistance.operit.data.model.ToolParameterSchema
import com.ai.assistance.operit.core.tools.defaultTool.a2ui.A2uiToolDefinitions
import com.ai.assistance.operit.core.tools.builtin.a2ui.A2uiToolDefinitions

/**
* 系统工具提示词管理器
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.ai.assistance.operit.core.files.transfer

import java.util.UUID
import java.util.concurrent.ConcurrentHashMap

internal class FileCopyObserver(
val onProgress: (FileCopyProgress) -> Unit,
val checkCancelled: () -> Unit,
)

/** 工具执行跨越同步入口和 IO 协程;用一次性令牌关联进度,避免并行粘贴串到同一个全局状态。 */
internal object FileCopyObservers {
const val PARAMETER = "__workspace_copy_id"
private val observers = ConcurrentHashMap<String, FileCopyObserver>()

fun register(observer: FileCopyObserver): String = UUID.randomUUID().toString().also { observers[it] = observer }

fun find(id: String?): FileCopyObserver? = id?.let(observers::get)

fun remove(id: String) { observers.remove(id) }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.ai.assistance.operit.core.files.transfer

import android.content.Context
import com.ai.assistance.operit.terminal.provider.filesystem.PRootMountMapping
import java.io.File

/** 与终端共用软挂载映射,不能把 /sdcard 简单拼接到 Ubuntu rootfs 下。 */
internal object LocalTransferPaths {
fun resolve(context: Context, path: String, environment: String): File {
if (environment.equals("android", ignoreCase = true)) return File(path)
require(environment.equals("linux", ignoreCase = true)) { "Not a local file environment: $environment" }
val expanded = when {
path == "~" -> "/root"
path.startsWith("~/") -> "/root/" + path.substring(2)
else -> path
}
return File(PRootMountMapping.mapLinuxPathToHostPath(
linuxPath = expanded,
ubuntuRoot = File(context.filesDir, "usr/var/lib/proot-distro/installed-rootfs/ubuntu"),
homeDir = context.filesDir.absolutePath,
appDataDir = context.applicationInfo.dataDir,
packageName = context.packageName,
chrootEnabled = context.getSharedPreferences("terminal_settings", Context.MODE_PRIVATE)
.getBoolean("chroot_enabled", false),
))
}
}
Loading