diff --git a/pulsar-core/pulsar-agentic/src/main/kotlin/ai/platon/pulsar/agentic/ai/tta/SourceCodeToToolCallSpec.kt b/pulsar-core/pulsar-agentic/src/main/kotlin/ai/platon/pulsar/agentic/ai/tta/SourceCodeToToolCallSpec.kt index 8e8e9347a..223ee67bc 100644 --- a/pulsar-core/pulsar-agentic/src/main/kotlin/ai/platon/pulsar/agentic/ai/tta/SourceCodeToToolCallSpec.kt +++ b/pulsar-core/pulsar-agentic/src/main/kotlin/ai/platon/pulsar/agentic/ai/tta/SourceCodeToToolCallSpec.kt @@ -2,8 +2,18 @@ package ai.platon.pulsar.agentic.ai.tta import ai.platon.pulsar.common.ResourceLoader import ai.platon.pulsar.common.Strings +import ai.platon.pulsar.common.code.ProjectUtils import ai.platon.pulsar.skeleton.ai.ToolCallSpec import ai.platon.pulsar.skeleton.common.llm.LLMUtils +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.databind.SerializationFeature +import java.nio.file.Files +import java.nio.file.StandardOpenOption +import kotlin.reflect.KClass +import kotlin.reflect.KFunction +import kotlin.reflect.full.declaredFunctions +import kotlin.reflect.full.findAnnotation +import kotlin.reflect.jvm.javaMethod object SourceCodeToToolCallSpec { @@ -45,6 +55,155 @@ object SourceCodeToToolCallSpec { return toolCallSpecs } + /** + * Generate ToolCallSpec list from a Kotlin interface using reflection. + * + * This method uses Kotlin reflection to inspect the methods of the given interface class, + * extracting method signatures, parameters, return types, and documentation. + * The generated list is then saved as a JSON file in the PROJECT_UTILS.CODE_RESOURCE_DIR directory. + * + * @param domain The domain name for the tool call specs (e.g., "driver") + * @param interfaceClass The Kotlin class representing the interface to inspect + * @param outputFileName The name of the output JSON file (without path) + * @return List of ToolCallSpec objects generated from the interface + */ + fun generateFromReflection( + domain: String, + interfaceClass: KClass<*>, + outputFileName: String = "webdriver-toolcall-specs.json" + ): List { + val toolCallSpecs = mutableListOf() + + // Get all declared functions from the interface + val functions = interfaceClass.declaredFunctions + + for (function in functions) { + // Skip private, internal, or deprecated functions if needed + // For now, we'll include all declared functions + + val methodName = function.name + val arguments = mutableListOf() + + // Extract parameters + for (param in function.parameters) { + // Skip the instance parameter (this) + if (param.kind == kotlin.reflect.KParameter.Kind.INSTANCE) { + continue + } + + val paramName = param.name ?: "arg${param.index}" + val paramType = extractTypeName(param.type.toString()) + + // Check if parameter has a default value + val defaultValue = if (param.isOptional) { + // Try to extract default value from parameter + // Note: Reflection doesn't give us the actual default value, + // so we'll use null as a marker for optional parameters + extractDefaultValue(param) + } else { + null + } + + arguments.add(ToolCallSpec.Arg(paramName, paramType, defaultValue)) + } + + // Extract return type + val returnType = extractTypeName(function.returnType.toString()) + + // Extract KDoc if available + val description = extractKDoc(function) + + toolCallSpecs.add(ToolCallSpec(domain, methodName, arguments, returnType, description)) + } + + // Save to JSON file in CODE_RESOURCE_DIR + saveToJsonFile(toolCallSpecs, outputFileName) + + return toolCallSpecs + } + + /** + * Extract a simple type name from a full qualified type string. + * For example: "kotlin.String?" -> "String" + */ + private fun extractTypeName(typeString: String): String { + // Remove package names and keep just the class name + val cleaned = typeString + .replace("kotlin.", "") + .replace("java.lang.", "") + .replace("ai.platon.pulsar.", "") + + // Handle nullable types + return cleaned.trim() + } + + /** + * Extract default value for optional parameters. + * Since Kotlin reflection doesn't provide actual default values, + * we return a placeholder or null. + */ + private fun extractDefaultValue(param: kotlin.reflect.KParameter): String? { + // For optional parameters, we can't get the actual default value via reflection + // We'll return null to indicate it has a default but we don't know what it is + return if (param.isOptional) { + // Return a type-appropriate default marker + when { + param.type.toString().contains("Int") -> "0" + param.type.toString().contains("Boolean") -> "false" + param.type.toString().contains("String") -> "\"\"" + else -> null + } + } else { + null + } + } + + /** + * Extract KDoc documentation from a function. + * Note: KDoc is not available through Kotlin reflection at runtime, + * so this will return null. For proper documentation, use source code parsing. + */ + private fun extractKDoc(function: KFunction<*>): String? { + // KDoc is not available via reflection at runtime + // To get KDoc, we would need to parse the source file + // For now, return null or try to get from annotations + + // Try to get from Deprecated annotation as an example + val deprecated = function.findAnnotation() + return deprecated?.message + } + + /** + * Save ToolCallSpec list to a JSON file in the CODE_RESOURCE_DIR. + */ + private fun saveToJsonFile(toolCallSpecs: List, fileName: String): Boolean { + val rootDir = ProjectUtils.findProjectRootDir() ?: return false + val destPath = rootDir.resolve(ProjectUtils.CODE_RESOURCE_DIR) + + // Ensure directory exists + Files.createDirectories(destPath) + + val targetFile = destPath.resolve(fileName) + + // Configure ObjectMapper for pretty printing + val objectMapper = ObjectMapper().apply { + enable(SerializationFeature.INDENT_OUTPUT) + } + + // Serialize to JSON + val jsonContent = objectMapper.writeValueAsString(toolCallSpecs) + + // Write to file + Files.writeString( + targetFile, + jsonContent, + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING + ) + + return true + } + // Helper types and parsers for SourceCodeToToolCall private data class ParamSig(val name: String, val type: String, val defaultValue: String?) private data class FuncSig(val name: String, val params: List, val returnType: String, val kdoc: String?) diff --git a/pulsar-core/pulsar-agentic/src/main/kotlin/ai/platon/pulsar/agentic/tools/executors/AbstractToolExecutor.kt b/pulsar-core/pulsar-agentic/src/main/kotlin/ai/platon/pulsar/agentic/tools/executors/AbstractToolExecutor.kt index 8227aa7ce..1fd618ef4 100644 --- a/pulsar-core/pulsar-agentic/src/main/kotlin/ai/platon/pulsar/agentic/tools/executors/AbstractToolExecutor.kt +++ b/pulsar-core/pulsar-agentic/src/main/kotlin/ai/platon/pulsar/agentic/tools/executors/AbstractToolExecutor.kt @@ -45,7 +45,7 @@ abstract class AbstractToolExecutor : ToolExecutor { override suspend fun execute(expression: String, target: Any): TcEvaluate { val (objectName, functionName, args) = simpleParser.parseFunctionExpression(expression) - ?: return TcEvaluate(expression = expression, cause = IllegalArgumentException("Illegal expression")) + ?: return TcEvaluate(expression, IllegalArgumentException("Illegal expression"), "Illegal expression") val tc = ToolCall(objectName, functionName, args) return execute(tc, target) diff --git a/pulsar-core/pulsar-agentic/src/main/kotlin/ai/platon/pulsar/agentic/tools/executors/BrowserToolExecutor.kt b/pulsar-core/pulsar-agentic/src/main/kotlin/ai/platon/pulsar/agentic/tools/executors/BrowserToolExecutor.kt index bd1bec9fa..00775794e 100644 --- a/pulsar-core/pulsar-agentic/src/main/kotlin/ai/platon/pulsar/agentic/tools/executors/BrowserToolExecutor.kt +++ b/pulsar-core/pulsar-agentic/src/main/kotlin/ai/platon/pulsar/agentic/tools/executors/BrowserToolExecutor.kt @@ -26,7 +26,7 @@ class BrowserToolExecutor: AbstractToolExecutor() { return driver } - return TcEvaluate(expression, IllegalArgumentException("Unknown expression: $expression, domain: browser")) + return TcEvaluate(expression, IllegalArgumentException("Unknown expression: $expression, domain: browser"), "Unknown expression") } /** diff --git a/pulsar-core/pulsar-agentic/src/test/kotlin/ai/platon/pulsar/agentic/ai/tta/GenerateWebDriverToolCallSpecs.kt b/pulsar-core/pulsar-agentic/src/test/kotlin/ai/platon/pulsar/agentic/ai/tta/GenerateWebDriverToolCallSpecs.kt new file mode 100644 index 000000000..cf6578dcd --- /dev/null +++ b/pulsar-core/pulsar-agentic/src/test/kotlin/ai/platon/pulsar/agentic/ai/tta/GenerateWebDriverToolCallSpecs.kt @@ -0,0 +1,34 @@ +package ai.platon.pulsar.agentic.ai.tta + +import ai.platon.pulsar.skeleton.crawl.fetch.driver.WebDriver + +/** + * A simple application to generate ToolCallSpec JSON file from WebDriver interface. + * + * This can be run manually to generate the webdriver-toolcall-specs.json file + * in the CODE_RESOURCE_DIR directory. + */ +fun main() { + println("Generating ToolCallSpec from WebDriver interface using reflection...") + + val specs = SourceCodeToToolCallSpec.generateFromReflection( + domain = "driver", + interfaceClass = WebDriver::class, + outputFileName = "webdriver-toolcall-specs.json" + ) + + println("✓ Generated ${specs.size} tool call specs") + println("✓ Saved to: pulsar-core/pulsar-resources/src/main/resources/code-mirror/webdriver-toolcall-specs.json") + println() + println("Sample of generated specs:") + specs.take(5).forEach { spec -> + val args = spec.arguments.joinToString(", ") { arg -> + if (arg.defaultValue != null) { + "${arg.name}: ${arg.type} = ${arg.defaultValue}" + } else { + "${arg.name}: ${arg.type}" + } + } + println(" - ${spec.domain}.${spec.method}($args): ${spec.returnType}") + } +} diff --git a/pulsar-core/pulsar-agentic/src/test/kotlin/ai/platon/pulsar/agentic/ai/tta/SourceCodeToToolCallTest.kt b/pulsar-core/pulsar-agentic/src/test/kotlin/ai/platon/pulsar/agentic/ai/tta/SourceCodeToToolCallTest.kt index 7342d61e2..1f6d978d3 100644 --- a/pulsar-core/pulsar-agentic/src/test/kotlin/ai/platon/pulsar/agentic/ai/tta/SourceCodeToToolCallTest.kt +++ b/pulsar-core/pulsar-agentic/src/test/kotlin/ai/platon/pulsar/agentic/ai/tta/SourceCodeToToolCallTest.kt @@ -1,8 +1,12 @@ package ai.platon.pulsar.agentic.ai.tta import ai.platon.pulsar.common.ResourceLoader +import ai.platon.pulsar.common.code.ProjectUtils +import ai.platon.pulsar.skeleton.crawl.fetch.driver.WebDriver import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test +import java.nio.file.Files +import kotlin.io.path.exists class SourceCodeToToolCallTest { @Test @@ -14,4 +18,76 @@ class SourceCodeToToolCallTest { assertNotNull(click, "Should contain driver.click method") assertTrue(click!!.arguments.map { it.name }.contains("selector"), "click should have selector argument") } + + @Test + fun `generate ToolCallSpec from WebDriver using reflection`() { + // Generate ToolCallSpec list from WebDriver interface using reflection + val toolSpecs = SourceCodeToToolCallSpec.generateFromReflection( + domain = "driver", + interfaceClass = WebDriver::class, + outputFileName = "webdriver-toolcall-specs-test.json" + ) + + // Verify the list is not empty + assertTrue(toolSpecs.isNotEmpty(), "Generated tool spec list should not be empty") + + // Verify the JSON file was created + val rootDir = ProjectUtils.findProjectRootDir() + if (rootDir != null) { + val jsonFile = rootDir.resolve(ProjectUtils.CODE_RESOURCE_DIR) + .resolve("webdriver-toolcall-specs-test.json") + assertTrue(jsonFile.exists(), "JSON file should be created in CODE_RESOURCE_DIR") + + // Verify file has content + val fileSize = Files.size(jsonFile) + assertTrue(fileSize > 0, "JSON file should have content") + + // Clean up test file + Files.deleteIfExists(jsonFile) + } + + // Verify some expected methods exist + val navigateTo = toolSpecs.firstOrNull { it.method == "navigateTo" } + assertNotNull(navigateTo, "Should contain navigateTo method") + + val click = toolSpecs.firstOrNull { it.method == "click" } + assertNotNull(click, "Should contain click method") + assertTrue(click!!.arguments.isNotEmpty(), "click should have arguments") + + val currentUrl = toolSpecs.firstOrNull { it.method == "currentUrl" } + assertNotNull(currentUrl, "Should contain currentUrl method") + + // Verify domain is set correctly + toolSpecs.forEach { spec -> + assertEquals("driver", spec.domain, "All specs should have domain 'driver'") + } + } + + @Test + fun `generate and save permanent JSON file for WebDriver`() { + // Generate the actual JSON file that should be committed + val toolSpecs = SourceCodeToToolCallSpec.generateFromReflection( + domain = "driver", + interfaceClass = WebDriver::class, + outputFileName = "webdriver-toolcall-specs.json" + ) + + // Verify the list is not empty + assertTrue(toolSpecs.isNotEmpty(), "Generated tool spec list should not be empty") + println("Generated ${toolSpecs.size} tool call specs from WebDriver interface") + + // Verify the JSON file was created + val rootDir = ProjectUtils.findProjectRootDir() + assertNotNull(rootDir, "Project root directory should be found") + + val jsonFile = rootDir!!.resolve(ProjectUtils.CODE_RESOURCE_DIR) + .resolve("webdriver-toolcall-specs.json") + assertTrue(jsonFile.exists(), "JSON file should be created in CODE_RESOURCE_DIR") + + // Verify file has content + val fileSize = Files.size(jsonFile) + assertTrue(fileSize > 100, "JSON file should have substantial content (at least 100 bytes)") + println("JSON file created at: ${jsonFile.toAbsolutePath()}") + println("File size: $fileSize bytes") + } } diff --git a/pulsar-core/pulsar-resources/src/main/resources/code-mirror/webdriver-toolcall-specs.json b/pulsar-core/pulsar-resources/src/main/resources/code-mirror/webdriver-toolcall-specs.json new file mode 100644 index 000000000..dbdf1f8fe --- /dev/null +++ b/pulsar-core/pulsar-resources/src/main/resources/code-mirror/webdriver-toolcall-specs.json @@ -0,0 +1,1207 @@ +[ { + "domain" : "driver", + "method" : "addBlockedURLs", + "arguments" : [ { + "name" : "urlPatterns", + "type" : "collections.List", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "addInitScript", + "arguments" : [ { + "name" : "script", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "baseURI", + "arguments" : [ ], + "returnType" : "String", + "description" : null +}, { + "domain" : "driver", + "method" : "boundingBox", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "common.math.geometric.RectD?", + "description" : null +}, { + "domain" : "driver", + "method" : "bringToFront", + "arguments" : [ ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "captureScreenshot", + "arguments" : [ { + "name" : "fullPage", + "type" : "Boolean", + "defaultValue" : "false" + } ], + "returnType" : "String?", + "description" : null +}, { + "domain" : "driver", + "method" : "captureScreenshot", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "String?", + "description" : null +}, { + "domain" : "driver", + "method" : "captureScreenshot", + "arguments" : [ { + "name" : "rect", + "type" : "common.math.geometric.RectD", + "defaultValue" : null + } ], + "returnType" : "String?", + "description" : null +}, { + "domain" : "driver", + "method" : "chat", + "arguments" : [ { + "name" : "prompt", + "type" : "String", + "defaultValue" : null + }, { + "name" : "selector", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "external.ModelResponse", + "description" : null +}, { + "domain" : "driver", + "method" : "check", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "clearBrowserCookies", + "arguments" : [ ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "click", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "count", + "type" : "Int", + "defaultValue" : "0" + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "click", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "modifier", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "clickMatches", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "attrName", + "type" : "String", + "defaultValue" : null + }, { + "name" : "pattern", + "type" : "String", + "defaultValue" : null + }, { + "name" : "count", + "type" : "Int", + "defaultValue" : "0" + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "clickNthAnchor", + "arguments" : [ { + "name" : "n", + "type" : "Int", + "defaultValue" : null + }, { + "name" : "rootSelector", + "type" : "String", + "defaultValue" : "\"\"" + } ], + "returnType" : "String?", + "description" : null +}, { + "domain" : "driver", + "method" : "clickTextMatches", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "pattern", + "type" : "String", + "defaultValue" : null + }, { + "name" : "count", + "type" : "Int", + "defaultValue" : "0" + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "clickablePoint", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "common.math.geometric.PointD?", + "description" : null +}, { + "domain" : "driver", + "method" : "currentUrl", + "arguments" : [ ], + "returnType" : "String", + "description" : null +}, { + "domain" : "driver", + "method" : "delay", + "arguments" : [ { + "name" : "millis", + "type" : "Long", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "delay", + "arguments" : [ { + "name" : "duration", + "type" : "java.time.Duration", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "delay", + "arguments" : [ { + "name" : "duration", + "type" : "time.Duration", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "deleteCookies", + "arguments" : [ { + "name" : "name", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : "Use deleteCookies(name, url, domain, path) instead.[deleteCookies] (3/5) | code: -32602, At least one of the url and domain needs to be specified" +}, { + "domain" : "driver", + "method" : "deleteCookies", + "arguments" : [ { + "name" : "name", + "type" : "String", + "defaultValue" : null + }, { + "name" : "url", + "type" : "String?", + "defaultValue" : "\"\"" + }, { + "name" : "domain", + "type" : "String?", + "defaultValue" : "\"\"" + }, { + "name" : "path", + "type" : "String?", + "defaultValue" : "\"\"" + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "documentURI", + "arguments" : [ ], + "returnType" : "String", + "description" : null +}, { + "domain" : "driver", + "method" : "dragAndDrop", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "deltaX", + "type" : "Int", + "defaultValue" : null + }, { + "name" : "deltaY", + "type" : "Int", + "defaultValue" : "0" + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "evaluate", + "arguments" : [ { + "name" : "expression", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Any?", + "description" : null +}, { + "domain" : "driver", + "method" : "evaluate", + "arguments" : [ { + "name" : "expression", + "type" : "String", + "defaultValue" : null + }, { + "name" : "defaultValue", + "type" : "T", + "defaultValue" : null + } ], + "returnType" : "T", + "description" : null +}, { + "domain" : "driver", + "method" : "evaluateDetail", + "arguments" : [ { + "name" : "expression", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "skeleton.crawl.fetch.driver.JsEvaluation?", + "description" : null +}, { + "domain" : "driver", + "method" : "evaluateValue", + "arguments" : [ { + "name" : "expression", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Any?", + "description" : null +}, { + "domain" : "driver", + "method" : "evaluateValue", + "arguments" : [ { + "name" : "expression", + "type" : "String", + "defaultValue" : null + }, { + "name" : "defaultValue", + "type" : "T", + "defaultValue" : null + } ], + "returnType" : "T", + "description" : null +}, { + "domain" : "driver", + "method" : "evaluateValue", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "functionDeclaration", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Any?", + "description" : null +}, { + "domain" : "driver", + "method" : "evaluateValueDetail", + "arguments" : [ { + "name" : "expression", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "skeleton.crawl.fetch.driver.JsEvaluation?", + "description" : null +}, { + "domain" : "driver", + "method" : "exists", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Boolean", + "description" : null +}, { + "domain" : "driver", + "method" : "extract", + "arguments" : [ { + "name" : "fields", + "type" : "collections.Map", + "defaultValue" : null + } ], + "returnType" : "collections.Map", + "description" : null +}, { + "domain" : "driver", + "method" : "fill", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "text", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "focus", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "getCookies", + "arguments" : [ ], + "returnType" : "collections.List>", + "description" : null +}, { + "domain" : "driver", + "method" : "goBack", + "arguments" : [ ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "goForward", + "arguments" : [ ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "isChecked", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Boolean", + "description" : null +}, { + "domain" : "driver", + "method" : "isHidden", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Boolean", + "description" : null +}, { + "domain" : "driver", + "method" : "isVisible", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Boolean", + "description" : null +}, { + "domain" : "driver", + "method" : "jvm", + "arguments" : [ ], + "returnType" : "skeleton.crawl.fetch.driver.JvmWebDriver", + "description" : null +}, { + "domain" : "driver", + "method" : "loadJsoupResource", + "arguments" : [ { + "name" : "url", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "org.jsoup.Connection.Response", + "description" : null +}, { + "domain" : "driver", + "method" : "loadResource", + "arguments" : [ { + "name" : "url", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "browser.driver.chrome.NetworkResourceResponse", + "description" : null +}, { + "domain" : "driver", + "method" : "mouseWheelDown", + "arguments" : [ { + "name" : "count", + "type" : "Int", + "defaultValue" : "0" + }, { + "name" : "deltaX", + "type" : "Double", + "defaultValue" : null + }, { + "name" : "deltaY", + "type" : "Double", + "defaultValue" : null + }, { + "name" : "delayMillis", + "type" : "Long", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "mouseWheelUp", + "arguments" : [ { + "name" : "count", + "type" : "Int", + "defaultValue" : "0" + }, { + "name" : "deltaX", + "type" : "Double", + "defaultValue" : null + }, { + "name" : "deltaY", + "type" : "Double", + "defaultValue" : null + }, { + "name" : "delayMillis", + "type" : "Long", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "moveMouseTo", + "arguments" : [ { + "name" : "x", + "type" : "Double", + "defaultValue" : null + }, { + "name" : "y", + "type" : "Double", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "moveMouseTo", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "deltaX", + "type" : "Int", + "defaultValue" : null + }, { + "name" : "deltaY", + "type" : "Int", + "defaultValue" : "0" + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "nanoDOMTree", + "arguments" : [ ], + "returnType" : "browser.driver.chrome.dom.model.NanoDOMTree? /* = browser.driver.chrome.dom.model.NanoDOMTreeNode? */", + "description" : null +}, { + "domain" : "driver", + "method" : "navigateTo", + "arguments" : [ { + "name" : "url", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "navigateTo", + "arguments" : [ { + "name" : "entry", + "type" : "skeleton.crawl.fetch.driver.NavigateEntry", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "newJsoupSession", + "arguments" : [ ], + "returnType" : "org.jsoup.Connection", + "description" : null +}, { + "domain" : "driver", + "method" : "open", + "arguments" : [ { + "name" : "url", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "outerHTML", + "arguments" : [ ], + "returnType" : "String?", + "description" : null +}, { + "domain" : "driver", + "method" : "outerHTML", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "String?", + "description" : null +}, { + "domain" : "driver", + "method" : "pageSource", + "arguments" : [ ], + "returnType" : "String?", + "description" : null +}, { + "domain" : "driver", + "method" : "pause", + "arguments" : [ ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "press", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "key", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "referrer", + "arguments" : [ ], + "returnType" : "String", + "description" : null +}, { + "domain" : "driver", + "method" : "reload", + "arguments" : [ ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "scrollBy", + "arguments" : [ { + "name" : "pixels", + "type" : "Double", + "defaultValue" : null + }, { + "name" : "smooth", + "type" : "Boolean", + "defaultValue" : "false" + } ], + "returnType" : "Double", + "description" : null +}, { + "domain" : "driver", + "method" : "scrollDown", + "arguments" : [ { + "name" : "count", + "type" : "Int", + "defaultValue" : "0" + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "scrollTo", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "scrollToBottom", + "arguments" : [ ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "scrollToMiddle", + "arguments" : [ { + "name" : "ratio", + "type" : "Double", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "scrollToScreen", + "arguments" : [ { + "name" : "screenNumber", + "type" : "Double", + "defaultValue" : null + } ], + "returnType" : "Double", + "description" : "Inappropriate name" +}, { + "domain" : "driver", + "method" : "scrollToTop", + "arguments" : [ ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "scrollToViewport", + "arguments" : [ { + "name" : "n", + "type" : "Double", + "defaultValue" : null + }, { + "name" : "smooth", + "type" : "Boolean", + "defaultValue" : "false" + } ], + "returnType" : "Double", + "description" : null +}, { + "domain" : "driver", + "method" : "scrollUp", + "arguments" : [ { + "name" : "count", + "type" : "Int", + "defaultValue" : "0" + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "selectAnchors", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "offset", + "type" : "Int", + "defaultValue" : "0" + }, { + "name" : "limit", + "type" : "Int", + "defaultValue" : "0" + } ], + "returnType" : "collections.List", + "description" : null +}, { + "domain" : "driver", + "method" : "selectAttributeAll", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "attrName", + "type" : "String", + "defaultValue" : null + }, { + "name" : "start", + "type" : "Int", + "defaultValue" : "0" + }, { + "name" : "limit", + "type" : "Int", + "defaultValue" : "0" + } ], + "returnType" : "collections.List", + "description" : null +}, { + "domain" : "driver", + "method" : "selectAttributes", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "collections.Map", + "description" : null +}, { + "domain" : "driver", + "method" : "selectFirstAttributeOrNull", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "attrName", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "String?", + "description" : null +}, { + "domain" : "driver", + "method" : "selectFirstPropertyValueOrNull", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "propName", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "String?", + "description" : null +}, { + "domain" : "driver", + "method" : "selectFirstTextOrNull", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "String?", + "description" : null +}, { + "domain" : "driver", + "method" : "selectHyperlinks", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "offset", + "type" : "Int", + "defaultValue" : "0" + }, { + "name" : "limit", + "type" : "Int", + "defaultValue" : "0" + } ], + "returnType" : "collections.List", + "description" : null +}, { + "domain" : "driver", + "method" : "selectImages", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "offset", + "type" : "Int", + "defaultValue" : "0" + }, { + "name" : "limit", + "type" : "Int", + "defaultValue" : "0" + } ], + "returnType" : "collections.List", + "description" : null +}, { + "domain" : "driver", + "method" : "selectPropertyValueAll", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "propName", + "type" : "String", + "defaultValue" : null + }, { + "name" : "start", + "type" : "Int", + "defaultValue" : "0" + }, { + "name" : "limit", + "type" : "Int", + "defaultValue" : "0" + } ], + "returnType" : "collections.List", + "description" : null +}, { + "domain" : "driver", + "method" : "selectTextAll", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "collections.List", + "description" : null +}, { + "domain" : "driver", + "method" : "setAttribute", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "attrName", + "type" : "String", + "defaultValue" : null + }, { + "name" : "attrValue", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "setAttributeAll", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "attrName", + "type" : "String", + "defaultValue" : null + }, { + "name" : "attrValue", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "setProperty", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "propName", + "type" : "String", + "defaultValue" : null + }, { + "name" : "propValue", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "setPropertyAll", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "propName", + "type" : "String", + "defaultValue" : null + }, { + "name" : "propValue", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "stop", + "arguments" : [ ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "textContent", + "arguments" : [ ], + "returnType" : "String?", + "description" : null +}, { + "domain" : "driver", + "method" : "type", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "text", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "uncheck", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Unit", + "description" : null +}, { + "domain" : "driver", + "method" : "url", + "arguments" : [ ], + "returnType" : "String", + "description" : null +}, { + "domain" : "driver", + "method" : "visible", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "Boolean", + "description" : "Use isVisible instead" +}, { + "domain" : "driver", + "method" : "waitForNavigation", + "arguments" : [ { + "name" : "oldUrl", + "type" : "String", + "defaultValue" : "\"\"" + } ], + "returnType" : "java.time.Duration", + "description" : null +}, { + "domain" : "driver", + "method" : "waitForNavigation", + "arguments" : [ { + "name" : "oldUrl", + "type" : "String", + "defaultValue" : "\"\"" + }, { + "name" : "timeoutMillis", + "type" : "Long", + "defaultValue" : null + } ], + "returnType" : "Long", + "description" : null +}, { + "domain" : "driver", + "method" : "waitForNavigation", + "arguments" : [ { + "name" : "oldUrl", + "type" : "String", + "defaultValue" : "\"\"" + }, { + "name" : "timeout", + "type" : "java.time.Duration", + "defaultValue" : null + } ], + "returnType" : "java.time.Duration", + "description" : null +}, { + "domain" : "driver", + "method" : "waitForPage", + "arguments" : [ { + "name" : "url", + "type" : "String", + "defaultValue" : null + }, { + "name" : "timeout", + "type" : "java.time.Duration", + "defaultValue" : null + } ], + "returnType" : "skeleton.crawl.fetch.driver.WebDriver?", + "description" : null +}, { + "domain" : "driver", + "method" : "waitForSelector", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + } ], + "returnType" : "java.time.Duration", + "description" : null +}, { + "domain" : "driver", + "method" : "waitForSelector", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "timeoutMillis", + "type" : "Long", + "defaultValue" : null + } ], + "returnType" : "Long", + "description" : null +}, { + "domain" : "driver", + "method" : "waitForSelector", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "timeout", + "type" : "java.time.Duration", + "defaultValue" : null + } ], + "returnType" : "java.time.Duration", + "description" : null +}, { + "domain" : "driver", + "method" : "waitForSelector", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "action", + "type" : "???", + "defaultValue" : null + } ], + "returnType" : "java.time.Duration", + "description" : null +}, { + "domain" : "driver", + "method" : "waitForSelector", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "timeoutMillis", + "type" : "Long", + "defaultValue" : null + }, { + "name" : "action", + "type" : "???", + "defaultValue" : null + } ], + "returnType" : "Long", + "description" : null +}, { + "domain" : "driver", + "method" : "waitForSelector", + "arguments" : [ { + "name" : "selector", + "type" : "String", + "defaultValue" : null + }, { + "name" : "timeout", + "type" : "java.time.Duration", + "defaultValue" : null + }, { + "name" : "action", + "type" : "???", + "defaultValue" : null + } ], + "returnType" : "java.time.Duration", + "description" : null +}, { + "domain" : "driver", + "method" : "waitUntil", + "arguments" : [ { + "name" : "predicate", + "type" : "???", + "defaultValue" : null + } ], + "returnType" : "java.time.Duration", + "description" : null +}, { + "domain" : "driver", + "method" : "waitUntil", + "arguments" : [ { + "name" : "timeoutMillis", + "type" : "Long", + "defaultValue" : null + }, { + "name" : "predicate", + "type" : "???", + "defaultValue" : null + } ], + "returnType" : "Long", + "description" : null +}, { + "domain" : "driver", + "method" : "waitUntil", + "arguments" : [ { + "name" : "timeout", + "type" : "java.time.Duration", + "defaultValue" : null + }, { + "name" : "predicate", + "type" : "???", + "defaultValue" : null + } ], + "returnType" : "java.time.Duration", + "description" : null +} ] \ No newline at end of file