diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentSearch/NIP90ContentSearchRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentSearch/NIP90ContentSearchRequestEvent.kt index e4c9dbfe66..6ea427fab9 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentSearch/NIP90ContentSearchRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/contentSearch/NIP90ContentSearchRequestEvent.kt @@ -26,6 +26,8 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip90Dvms.tags.inputText +import com.vitorpamplona.quartz.nip90Dvms.tags.param import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -42,10 +44,20 @@ class NIP90ContentSearchRequestEvent( const val ALT = "NIP90 Content Search request" fun build( + searchQuery: String, + users: String? = null, + since: Long? = null, + until: Long? = null, + maxResults: Int? = null, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { alt(ALT) + inputText(searchQuery) + users?.let { param("users", it) } + since?.let { param("since", it.toString()) } + until?.let { param("until", it.toString()) } + maxResults?.let { param("max_results", it.toString()) } initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventCount/NIP90EventCountRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventCount/NIP90EventCountRequestEvent.kt index 88856680e3..3bbed29c76 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventCount/NIP90EventCountRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventCount/NIP90EventCountRequestEvent.kt @@ -26,6 +26,8 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip90Dvms.tags.inputText +import com.vitorpamplona.quartz.nip90Dvms.tags.param import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -42,10 +44,17 @@ class NIP90EventCountRequestEvent( const val ALT = "NIP90 Event Count request" fun build( + inputs: List = emptyList(), + relays: List, + groups: List = emptyList(), + filterJson: String = "", createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, - ) = eventTemplate(KIND, "", createdAt) { + ) = eventTemplate(KIND, filterJson, createdAt) { alt(ALT) + inputs.forEach { inputText(it) } + relays.forEach { param("relay", it) } + groups.forEach { param("group", it) } initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPowDelegation/NIP90EventPowDelegationRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPowDelegation/NIP90EventPowDelegationRequestEvent.kt index fcffe69d0c..3e4842255f 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPowDelegation/NIP90EventPowDelegationRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPowDelegation/NIP90EventPowDelegationRequestEvent.kt @@ -26,6 +26,8 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip90Dvms.tags.inputText +import com.vitorpamplona.quartz.nip90Dvms.tags.param import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -42,10 +44,14 @@ class NIP90EventPowDelegationRequestEvent( const val ALT = "NIP90 Event PoW Delegation request" fun build( + eventJson: String, + pow: Int, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { alt(ALT) + inputText(eventJson) + param("pow", pow.toString()) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPublishSchedule/NIP90EventPublishScheduleRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPublishSchedule/NIP90EventPublishScheduleRequestEvent.kt index 23a6490fdf..072d6d77b0 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPublishSchedule/NIP90EventPublishScheduleRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventPublishSchedule/NIP90EventPublishScheduleRequestEvent.kt @@ -26,6 +26,8 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip90Dvms.tags.inputText +import com.vitorpamplona.quartz.nip90Dvms.tags.param import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -42,10 +44,16 @@ class NIP90EventPublishScheduleRequestEvent( const val ALT = "NIP90 Event Publish Schedule request" fun build( + eventJson: String, + relays: List = emptyList(), createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { alt(ALT) + inputText(eventJson) + if (relays.isNotEmpty()) { + param("relays", *relays.toTypedArray()) + } initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventTimestamping/NIP90EventTimestampingRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventTimestamping/NIP90EventTimestampingRequestEvent.kt index faf65d8621..b48d49aa1c 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventTimestamping/NIP90EventTimestampingRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/eventTimestamping/NIP90EventTimestampingRequestEvent.kt @@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip90Dvms.tags.inputEvent import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -42,10 +43,12 @@ class NIP90EventTimestampingRequestEvent( const val ALT = "NIP90 Event Timestamping request" fun build( + eventId: HexKey, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { alt(ALT) + inputEvent(eventId) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageGeneration/NIP90ImageGenerationRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageGeneration/NIP90ImageGenerationRequestEvent.kt index 1b5d1240fb..22d4887e24 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageGeneration/NIP90ImageGenerationRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageGeneration/NIP90ImageGenerationRequestEvent.kt @@ -26,6 +26,9 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip90Dvms.tags.inputText +import com.vitorpamplona.quartz.nip90Dvms.tags.inputUrl +import com.vitorpamplona.quartz.nip90Dvms.tags.param import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -42,10 +45,24 @@ class NIP90ImageGenerationRequestEvent( const val ALT = "NIP90 Image Generation request" fun build( + prompt: String, + sourceImageUrl: String? = null, + model: String? = null, + lora: String? = null, + ratio: String? = null, + size: String? = null, + negativePrompt: String? = null, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { alt(ALT) + sourceImageUrl?.let { inputUrl(it) } + inputText(prompt) + model?.let { param("model", it) } + lora?.let { param("lora", it) } + size?.let { param("size", it) } + ratio?.let { param("ratio", it) } + negativePrompt?.let { param("negative_prompt", it) } initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageToVideo/NIP90ImageToVideoRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageToVideo/NIP90ImageToVideoRequestEvent.kt index f0aa0d025d..597f533022 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageToVideo/NIP90ImageToVideoRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/imageToVideo/NIP90ImageToVideoRequestEvent.kt @@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip90Dvms.tags.inputUrl import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -42,10 +43,12 @@ class NIP90ImageToVideoRequestEvent( const val ALT = "NIP90 Image-to-Video request" fun build( + imageUrl: String, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { alt(ALT) + inputUrl(imageUrl) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/malwareScanning/NIP90MalwareScanRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/malwareScanning/NIP90MalwareScanRequestEvent.kt index bdf548deb3..9eacb7522f 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/malwareScanning/NIP90MalwareScanRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/malwareScanning/NIP90MalwareScanRequestEvent.kt @@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip90Dvms.tags.inputUrl import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -42,10 +43,12 @@ class NIP90MalwareScanRequestEvent( const val ALT = "NIP90 Malware Scan request" fun build( + fileUrl: String, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { alt(ALT) + inputUrl(fileUrl) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/opReturn/NIP90OpReturnRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/opReturn/NIP90OpReturnRequestEvent.kt index f148e98679..2482045c81 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/opReturn/NIP90OpReturnRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/opReturn/NIP90OpReturnRequestEvent.kt @@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip90Dvms.tags.inputText import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -40,12 +41,15 @@ class NIP90OpReturnRequestEvent( companion object { const val KIND = 5901 const val ALT = "NIP90 OP_RETURN Creation request" + const val MAX_OP_RETURN_BYTES = 80 fun build( + text: String, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { alt(ALT) + inputText(text) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/peopleSearch/NIP90PeopleSearchRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/peopleSearch/NIP90PeopleSearchRequestEvent.kt index 53a638dad3..55e988d5fb 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/peopleSearch/NIP90PeopleSearchRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/peopleSearch/NIP90PeopleSearchRequestEvent.kt @@ -26,6 +26,8 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip90Dvms.tags.inputText +import com.vitorpamplona.quartz.nip90Dvms.tags.param import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -42,10 +44,14 @@ class NIP90PeopleSearchRequestEvent( const val ALT = "NIP90 People Search request" fun build( + searchQuery: String, + maxResults: Int? = null, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { alt(ALT) + inputText(searchQuery) + maxResults?.let { param("max_results", it.toString()) } initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/summarization/NIP90SummarizationRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/summarization/NIP90SummarizationRequestEvent.kt index 7a7277c0b0..99efffd41e 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/summarization/NIP90SummarizationRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/summarization/NIP90SummarizationRequestEvent.kt @@ -26,6 +26,9 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip90Dvms.tags.inputEvent +import com.vitorpamplona.quartz.nip90Dvms.tags.output +import com.vitorpamplona.quartz.nip90Dvms.tags.param import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -42,10 +45,16 @@ class NIP90SummarizationRequestEvent( const val ALT = "NIP90 Summarization request" fun build( + eventIds: List, + length: String? = null, + outputMimeType: String? = null, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { alt(ALT) + eventIds.forEach { inputEvent(it) } + length?.let { param("length", it) } + outputMimeType?.let { output(it) } initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/tags/InputTag.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/tags/InputTag.kt new file mode 100644 index 0000000000..c745d86962 --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/tags/InputTag.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip90Dvms.tags + +import androidx.compose.runtime.Stable +import com.vitorpamplona.quartz.nip01Core.core.has +import com.vitorpamplona.quartz.utils.ensure + +@Stable +class InputTag( + val value: String, + val type: String, + val relay: String? = null, + val marker: String? = null, +) { + companion object { + const val TAG_NAME = "i" + + fun parse(tag: Array): InputTag? { + ensure(tag.has(2)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + ensure(tag[1].isNotEmpty()) { return null } + val relay = if (tag.has(3) && tag[3].isNotBlank()) tag[3] else null + val marker = if (tag.has(4) && tag[4].isNotBlank()) tag[4] else null + return InputTag(tag[1], tag[2], relay, marker) + } + + fun assembleUrl(url: String) = arrayOf(TAG_NAME, url, "url") + + fun assembleText(text: String) = arrayOf(TAG_NAME, text, "text") + + fun assembleEvent(eventId: String) = arrayOf(TAG_NAME, eventId, "event") + + fun assembleJob(jobId: String) = arrayOf(TAG_NAME, jobId, "job") + + fun assemblePrompt(prompt: String) = arrayOf(TAG_NAME, prompt, "prompt") + } +} diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/tags/OutputTag.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/tags/OutputTag.kt new file mode 100644 index 0000000000..84953ae4fc --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/tags/OutputTag.kt @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip90Dvms.tags + +import com.vitorpamplona.quartz.nip01Core.core.has +import com.vitorpamplona.quartz.utils.ensure + +class OutputTag( + val mimeType: String, +) { + companion object { + const val TAG_NAME = "output" + + fun parse(tag: Array): OutputTag? { + ensure(tag.has(1)) { return null } + ensure(tag[0] == TAG_NAME) { return null } + ensure(tag[1].isNotEmpty()) { return null } + return OutputTag(tag[1]) + } + + fun assemble(mimeType: String) = arrayOf(TAG_NAME, mimeType) + } +} diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/tags/TagArrayBuilderExt.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/tags/TagArrayBuilderExt.kt new file mode 100644 index 0000000000..5a86ae6174 --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/tags/TagArrayBuilderExt.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip90Dvms.tags + +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder + +fun TagArrayBuilder.inputUrl(url: String) = add(InputTag.assembleUrl(url)) + +fun TagArrayBuilder.inputText(text: String) = add(InputTag.assembleText(text)) + +fun TagArrayBuilder.inputEvent(eventId: HexKey) = add(InputTag.assembleEvent(eventId)) + +fun TagArrayBuilder.inputJob(jobId: HexKey) = add(InputTag.assembleJob(jobId)) + +fun TagArrayBuilder.inputPrompt(prompt: String) = add(InputTag.assemblePrompt(prompt)) + +fun TagArrayBuilder.output(mimeType: String) = addUnique(OutputTag.assemble(mimeType)) + +fun TagArrayBuilder.param( + key: String, + value: String, +) = add(arrayOf("param", key, value)) + +fun TagArrayBuilder.param( + key: String, + vararg values: String, +) = add(arrayOf("param", key) + values) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/tags/TagArrayExt.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/tags/TagArrayExt.kt new file mode 100644 index 0000000000..48219735b3 --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/tags/TagArrayExt.kt @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip90Dvms.tags + +import com.vitorpamplona.quartz.nip01Core.core.TagArray + +fun TagArray.inputs() = mapNotNull(InputTag::parse) + +fun TagArray.outputMimeType() = firstNotNullOfOrNull(OutputTag::parse)?.mimeType diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textExtraction/NIP90TextExtractionRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textExtraction/NIP90TextExtractionRequestEvent.kt index 00b1b69a51..12eb9b8295 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textExtraction/NIP90TextExtractionRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textExtraction/NIP90TextExtractionRequestEvent.kt @@ -26,6 +26,9 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip90Dvms.tags.inputUrl +import com.vitorpamplona.quartz.nip90Dvms.tags.output +import com.vitorpamplona.quartz.nip90Dvms.tags.param import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -42,10 +45,21 @@ class NIP90TextExtractionRequestEvent( const val ALT = "NIP90 Text Extraction request" fun build( + inputUrl: String, + outputMimeType: String? = null, + rangeStart: String? = null, + rangeEnd: String? = null, + alignment: String? = null, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { alt(ALT) + inputUrl(inputUrl) + outputMimeType?.let { output(it) } + if (rangeStart != null && rangeEnd != null) { + param("range", rangeStart, rangeEnd) + } + alignment?.let { param("alignment", it) } initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textGeneration/NIP90TextGenerationRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textGeneration/NIP90TextGenerationRequestEvent.kt index dab1c0d79d..9f56509981 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textGeneration/NIP90TextGenerationRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textGeneration/NIP90TextGenerationRequestEvent.kt @@ -26,6 +26,9 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip90Dvms.tags.inputPrompt +import com.vitorpamplona.quartz.nip90Dvms.tags.output +import com.vitorpamplona.quartz.nip90Dvms.tags.param import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -42,10 +45,26 @@ class NIP90TextGenerationRequestEvent( const val ALT = "NIP90 Text Generation request" fun build( + prompt: String, + model: String? = null, + maxTokens: Int? = null, + temperature: Double? = null, + topK: Int? = null, + topP: Double? = null, + frequencyPenalty: Double? = null, + outputMimeType: String? = null, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { alt(ALT) + inputPrompt(prompt) + model?.let { param("model", it) } + maxTokens?.let { param("max_tokens", it.toString()) } + temperature?.let { param("temperature", it.toString()) } + topK?.let { param("top_k", it.toString()) } + topP?.let { param("top_p", it.toString()) } + frequencyPenalty?.let { param("frequency_penalty", it.toString()) } + outputMimeType?.let { output(it) } initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textToSpeech/NIP90TextToSpeechRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textToSpeech/NIP90TextToSpeechRequestEvent.kt index 5fe03ec104..ee842cb4cf 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textToSpeech/NIP90TextToSpeechRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/textToSpeech/NIP90TextToSpeechRequestEvent.kt @@ -26,6 +26,8 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip90Dvms.tags.inputText +import com.vitorpamplona.quartz.nip90Dvms.tags.param import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -42,10 +44,14 @@ class NIP90TextToSpeechRequestEvent( const val ALT = "NIP90 Text-to-Speech request" fun build( + text: String, + language: String? = null, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { alt(ALT) + inputText(text) + language?.let { param("language", it) } initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/translation/NIP90TranslationRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/translation/NIP90TranslationRequestEvent.kt index a8327dc000..167060cebf 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/translation/NIP90TranslationRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/translation/NIP90TranslationRequestEvent.kt @@ -26,6 +26,8 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip90Dvms.tags.inputEvent +import com.vitorpamplona.quartz.nip90Dvms.tags.param import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -42,10 +44,14 @@ class NIP90TranslationRequestEvent( const val ALT = "NIP90 Translation request" fun build( + eventIds: List, + language: String, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { alt(ALT) + eventIds.forEach { inputEvent(it) } + param("language", language) initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoConversion/NIP90VideoConversionRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoConversion/NIP90VideoConversionRequestEvent.kt index c1da0736b9..17efb7342a 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoConversion/NIP90VideoConversionRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoConversion/NIP90VideoConversionRequestEvent.kt @@ -26,6 +26,9 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip90Dvms.tags.inputUrl +import com.vitorpamplona.quartz.nip90Dvms.tags.output +import com.vitorpamplona.quartz.nip90Dvms.tags.param import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -42,10 +45,19 @@ class NIP90VideoConversionRequestEvent( const val ALT = "NIP90 Video Conversion request" fun build( + videoUrl: String, + outputMimeType: String? = null, + rangeStart: String? = null, + rangeEnd: String? = null, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { alt(ALT) + inputUrl(videoUrl) + outputMimeType?.let { output(it) } + if (rangeStart != null && rangeEnd != null) { + param("range", rangeStart, rangeEnd) + } initializer() } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoTranslation/NIP90VideoTranslationRequestEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoTranslation/NIP90VideoTranslationRequestEvent.kt index 019f0606c5..d1fcbd0c6d 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoTranslation/NIP90VideoTranslationRequestEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip90Dvms/videoTranslation/NIP90VideoTranslationRequestEvent.kt @@ -26,6 +26,9 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip31Alts.alt +import com.vitorpamplona.quartz.nip90Dvms.tags.inputUrl +import com.vitorpamplona.quartz.nip90Dvms.tags.output +import com.vitorpamplona.quartz.nip90Dvms.tags.param import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -42,10 +45,23 @@ class NIP90VideoTranslationRequestEvent( const val ALT = "NIP90 Video Translation request" fun build( + videoUrl: String, + language: String, + subtitle: String? = null, + rangeStart: String? = null, + rangeEnd: String? = null, + outputFormat: String? = null, createdAt: Long = TimeUtils.now(), initializer: TagArrayBuilder.() -> Unit = {}, ) = eventTemplate(KIND, "", createdAt) { alt(ALT) + inputUrl(videoUrl) + param("language", language) + subtitle?.let { param("subtitle", it) } + if (rangeStart != null && rangeEnd != null) { + param("range", rangeStart, rangeEnd) + } + outputFormat?.let { output(it) } initializer() } }