Skip to content

Commit

Permalink
Add necessary dependencies
Browse files Browse the repository at this point in the history
Add ChatBotActionService

Adjust ChatPresenter for the service

Adjust so it can take in special character input

Separate executeCommand in multiple functions for testing

Make visible for testing

Initial test for json input, failing

Adjust so there's a role in the Message data class

Add passing test for creating json input

Clean up, add more JsonInput tests

Change chat colors

Update dependency com.github.oshi:oshi-core to v6.6.4 (#965)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [com.github.oshi:oshi-core](https://redirect.github.com/oshi/oshi) |
dependencies | patch | `6.6.3` -> `6.6.4` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the Dependency
Dashboard for more information.

---

<details>
<summary>oshi/oshi (com.github.oshi:oshi-core)</summary>

[`v6.6.4`](https://redirect.github.com/oshi/oshi/blob/HEAD/CHANGELOG.md#660-2024-04-13--661-2024-05-26--662-2024-07-21--663-2024-08-20--664-2024-09-15)

-   [#&#8203;2603](https://redirect.github.com/oshi/oshi/pull/2603),
[#&#8203;2625](https://redirect.github.com/oshi/oshi/pull/2625): Add
part number to Physical Memory -
[@&#8203;BartekDziurowicz](https://redirect.github.com/BartekDziurowicz),
[@&#8203;dbwiddis](https://redirect.github.com/dbwiddis).
- [#&#8203;2644](https://redirect.github.com/oshi/oshi/pull/2644): Add
serial number to Physical Memory -
[@&#8203;Tegrason](https://redirect.github.com/Tegrason).

- [#&#8203;2605](https://redirect.github.com/oshi/oshi/pull/2605):
Reduce CpuStat.getSystemCpuLoadticks memory allocation pressure -
[@&#8203;chrisribble](https://redirect.github.com/chrisribble).
- [#&#8203;2612](https://redirect.github.com/oshi/oshi/pull/2612): Use
1k buffer in FileUtils.readLines to reduce heap allocation pressure -
[@&#8203;chrisribble](https://redirect.github.com/chrisribble).
- [#&#8203;2621](https://redirect.github.com/oshi/oshi/pull/2621): Cache
thread counters when updating OS Process with suspended state -
[@&#8203;dbwiddis](https://redirect.github.com/dbwiddis).
- [#&#8203;2626](https://redirect.github.com/oshi/oshi/pull/2626): Make
sys and dev paths on Linux configurable -
[@&#8203;dbwiddis](https://redirect.github.com/dbwiddis).
- [#&#8203;2627](https://redirect.github.com/oshi/oshi/pull/2627): Add
more SMBIOSMemoryType values -
[@&#8203;dbwiddis](https://redirect.github.com/dbwiddis).
- [#&#8203;2645](https://redirect.github.com/oshi/oshi/pull/2645): fix
getOwningProcessId sometimes return -1 on 64x linux -
[@&#8203;yourancc](https://redirect.github.com/yourancc).
- [#&#8203;2660](https://redirect.github.com/oshi/oshi/pull/2660): Add
macOS 15 (Sequoia) to version properties -
[@&#8203;dbwiddis](https://redirect.github.com/dbwiddis).
- [#&#8203;2662](https://redirect.github.com/oshi/oshi/pull/2662): Only
warn on duplicate properties files if they differ -
[@&#8203;dbwiddis](https://redirect.github.com/dbwiddis).
- [#&#8203;2692](https://redirect.github.com/oshi/oshi/pull/2692): Do
not log errors for reading process arguments on Linux -
[@&#8203;wolfs](https://redirect.github.com/wolfs).
- [#&#8203;2704](https://redirect.github.com/oshi/oshi/pull/2704):
Properly parse CPU vendor when lscpu not available -
[@&#8203;dbwiddis](https://redirect.github.com/dbwiddis).
- [#&#8203;2705](https://redirect.github.com/oshi/oshi/pull/2705):
Restore optional legacy method of calculating Windows System CPU -
[@&#8203;dbwiddis](https://redirect.github.com/dbwiddis).
- [#&#8203;2711](https://redirect.github.com/oshi/oshi/pull/2711): Do
not log error on macOS for hw.nperflevels -
[@&#8203;Puppy4C](https://redirect.github.com/Puppy4C).
- [#&#8203;2722](https://redirect.github.com/oshi/oshi/pull/2722): Fix
speed value for LinuxNetworkIF -
[@&#8203;Puppy4C](https://redirect.github.com/Puppy4C).
- [#&#8203;2724](https://redirect.github.com/oshi/oshi/pull/2724):
Clarify IO bytes documentation on OSProcess -
[@&#8203;dbwiddis](https://redirect.github.com/dbwiddis).
- [#&#8203;2725](https://redirect.github.com/oshi/oshi/pull/2725):
Reduce redundant logging on perf counter failures -
[@&#8203;dbwiddis](https://redirect.github.com/dbwiddis).
- [#&#8203;2726](https://redirect.github.com/oshi/oshi/pull/2726): JNA
5.15.0 - [@&#8203;dbwiddis](https://redirect.github.com/dbwiddis).

</details>

---

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Renovate
Bot](https://redirect.github.com/renovatebot/renovate).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC44MC4wIiwidXBkYXRlZEluVmVyIjoiMzguODAuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Run spotless

Remove script content

Update -Werror behavior in kotlin and disallow in tests by default (#963)

Never realized we didn't allow this in tests, this refreshes the logic
for this area a bit and adds a test control.

<!--
  ⬆ Put your description above this! ⬆

  Please be descriptive and detailed.

Please read our [Contributing
Guidelines](https://github.com/tinyspeck/slack-gradle-plugin/blob/main/.github/CONTRIBUTING.md)
and [Code of Conduct](https://slackhq.github.io/code-of-conduct).

Don't worry about deleting this, it's not visible in the PR!
-->

Update jna monorepo to v5.15.0 (#966)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[net.java.dev.jna:jna-platform](https://redirect.github.com/java-native-access/jna)
| dependencies | minor | `5.14.0` -> `5.15.0` |
|
[net.java.dev.jna:jna](https://redirect.github.com/java-native-access/jna)
| dependencies | minor | `5.14.0` -> `5.15.0` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the Dependency
Dashboard for more information.

---

<details>
<summary>java-native-access/jna
(net.java.dev.jna:jna-platform)</summary>

[`v5.15.0`](https://redirect.github.com/java-native-access/jna/blob/HEAD/CHANGES.md#Release-5150)

[Compare
Source](https://redirect.github.com/java-native-access/jna/compare/5.14.0...5.15.0)

\==============

-
[#&#8203;1578](https://redirect.github.com/java-native-access/jna/pull/1578):
Add support for FreeBSD aarch64 -
[@&#8203;alexdupre](https://redirect.github.com/alexdupre).
-
[#&#8203;1593](https://redirect.github.com/java-native-access/jna/pull/1593):
Add support for DragonFly BSD x86-64 -
[@&#8203;liweitianux](https://redirect.github.com/liweitianux).
-
[#&#8203;1595](https://redirect.github.com/java-native-access/jna/pull/1595):
Add `IsProcessorFeaturePresent` to `c.s.j.p.win32.Kernel32` -
[@&#8203;dbwiddis](https://redirect.github.com/dbwiddis).
-
[#&#8203;1602](https://redirect.github.com/java-native-access/jna/pull/1602):
Add `XMoveWindow`, `XResizeWindow`, `XMoveResizeWindow`, `XRaiseWindow`,
`XLowerWindow` X11 calls to `c.s.j.p.unix.X11` -
[@&#8203;vinceh121](https://redirect.github.com/vinceh121).
-
[#&#8203;1613](https://redirect.github.com/java-native-access/jna/issues/1613):
Added static helper method \`Native#getNativeLibrary' for getting the
underlying NativeLibrary instance from a Library interface instance or
from a "registered" class -
[@&#8203;matthiasblaesing](https://redirect.github.com/matthiasblaesing).
-
[#&#8203;1624](https://redirect.github.com/java-native-access/jna/pull/1624):
Enable linker build-id for android builds -
[@&#8203;mstyura](https://redirect.github.com/mstyura).

-
[#&#8203;1579](https://redirect.github.com/java-native-access/jna/issues/1579):
Fix analysis of ELF binary on arm systems running with a java ELF binary
without section table headers (java8 on armv7 NAS) -
[@&#8203;matthiasblaesing](https://redirect.github.com/matthiasblaesing).
-
[#&#8203;1586](https://redirect.github.com/java-native-access/jna/issues/1586):
Fix free_callback JNI weak reference leak -
[@&#8203;xiezhaokun](https://redirect.github.com/xiezhaokun).
-
[6486c90d913a413f247eef84742ce3c474738933](https://redirect.github.com/java-native-access/jna/commit/6486c90d913a413f247eef84742ce3c474738933):
Check CallbackReference#cbstruct for null when checking existing
Reference -
[@&#8203;matthiasblaesing](https://redirect.github.com/matthiasblaesing).
-
[#&#8203;1622](https://redirect.github.com/java-native-access/jna/issues/1622):
Add "linux-riscv64" entry to OSGI Bundle-NativeCode header in
MANIFEST.MF -
[@&#8203;matthiasblaesing](https://redirect.github.com/matthiasblaesing).

</details>

---

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these
updates again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Renovate
Bot](https://redirect.github.com/renovatebot/renovate).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC44MC4wIiwidXBkYXRlZEluVmVyIjoiMzguODQuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Update dependency com.android.tools.build:gradle to v8.6.1 (#971)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [com.android.tools.build:gradle](http://tools.android.com/)
([source](https://android.googlesource.com/platform/tools/base)) |
dependencies | patch | `8.6.0` -> `8.6.1` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the Dependency
Dashboard for more information.

---

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Renovate
Bot](https://redirect.github.com/renovatebot/renovate).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC44Ny4xIiwidXBkYXRlZEluVmVyIjoiMzguODcuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Update dependency com.github.ajalt.clikt:clikt to v5 (#968)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[com.github.ajalt.clikt:clikt](https://redirect.github.com/ajalt/clikt)
| dependencies | major | `4.4.0` -> `5.0.0` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the Dependency
Dashboard for more information.

---

<details>
<summary>ajalt/clikt (com.github.ajalt.clikt:clikt)</summary>

[`v5.0.0`](https://redirect.github.com/ajalt/clikt/blob/HEAD/CHANGELOG.md#500)

[Compare
Source](https://redirect.github.com/ajalt/clikt/compare/4.4.0...5.0.0)

-   Publish `iosArm64` and `iosX64` targets.
- Added `NoSuchArgument` exception that is thrown when too many
arguments were given on the command line. Previously, a less specific
`UsageError` was thrown instead.
- Added `CommandLineParser.tokenize` that splits a string into argv
tokens.
- Added `CommandLineParser` that provides functions for parsing and
finalizing commands manually for more control.
- Added `Context.invokedSubcommands` that contains all subcommands of
the current command that are going to be invoked when
`allowMultipleSubcommands` is `true`.
- Added `SuspendingCliktCommand` that has a `suspend fun run` method,
allowing you to use coroutines in your commands.
- Added `ChainedCliktCommand` that allows you to return a value from
your `run` method and pass it to the next command in the chain.
- Added `Context.data` as an alternative to `obj` that allows you to
store more than one object in the context.
-   Added `Context.echoer` to customize how `echo` messages are printed.
- Added `CompletionGenerator` to manually generate completions for a
command.
- Added `Context.exitProcess` which you can use to prevent the process
from exiting during tests.
- Added core module that supports watchOS, tvOS, and wasmWasi targets
and has no dependencies.
- Added more options to `CliktCommand.test` to control the terminal
interactivity.
([#&#8203;517](https://redirect.github.com/ajalt/clikt/pull/517))
- Added `associate{}`, `associateBy{}`, and `associateWith{}` transforms
for options that allow you to convert the keys and values of the map.
([#&#8203;529](https://redirect.github.com/ajalt/clikt/pull/529))
- Added support for aliasing options to other options.
([#&#8203;535](https://redirect.github.com/ajalt/clikt/pull/535))
- Added `limit` and `ignoreCase` parameters to `option().split()`.
([#&#8203;541](https://redirect.github.com/ajalt/clikt/pull/541))
- Support calling `--help` on subcommands when parents have required
parameters.

- In a subcommand with and an `argument()` with `multiple()` or
`optional()`, the behavior is now the same regardless of the value of
`allowMultipleSubcommands`: if a token matches a subcommand name, it's
now treated as a subcommand rather than a positional argument.
- Due to changes to the internal parsing algorithm, the exact details of
error messages when multiple usage errors occur have changed in some
cases.
- **Breaking Change:** Moved the following parameters from
`CliktCommand`'s constructor; override the corresponding properties
instead:

    | removed parameter           | replacement property            |
    |-----------------------------|---------------------------------|
    | `help`                      | `fun help`                      |
    | `epilog`                    | `fun helpEpilog`                |
    | `invokeWithoutSubcommand`   | `val invokeWithoutSubcommand`   |
    | `printHelpOnEmptyArgs`      | `val printHelpOnEmptyArgs`      |
    | `helpTags`                  | `val helpTags`                  |
    | `autoCompleteEnvvar`        | `val autoCompleteEnvvar`        |
    | `allowMultipleSubcommands`  | `val allowMultipleSubcommands`  |
    | `treatUnknownOptionsAsArgs` | `val treatUnknownOptionsAsArgs` |
    | `hidden`                    | `val hiddenFromHelp`            |
- The following methods on `CliktCommand` have been renamed:
`commandHelp` -> `help`, `commandHelpEpilog` -> `epilog`. The old names
are deprecated.
- **Breaking Change:** `CliktCommand.main` and `CliktCommand.parse` are
now extension functions rather than methods.
- **Breaking Change:** `Context.obj` and `Context.terminal`, and
`OptionTransformContext.terminal` are now extension functions rather
than properties.
- **Breaking Change:** The `RenderedSection` and `DefinitionRow` classes
have moved to `AbstractHelpFormatter`.
- Markdown support in the help formatter is no longer included by
default. To enable it, include the `:clikt-markdown` dependency and call
`yourCommand.installMordantMarkdown()` before parsing.
-   Updated Kotlin to 2.0.0

- Fixed excess arguments not being reported when
`allowMultipleSubcommands=true` and a subcommand has excess arguments
followed by another subcommand.
- Commands with `printHelpOnEmptyArgs=true` will no longer print help if
an option has a value from an environment variable or value source.
([#&#8203;382](https://redirect.github.com/ajalt/clikt/pull/382))

- Deprecated `Context.originalArgv`. It will now always return an empty
list. If your commands need an argv, you can pass it to them before you
run them, or set in on the new `Context.data` map.
- Deprecated `Context.expandArgumentFiles`. Use
`Context.argumentFileReader` instead.
- Renamed the following `Context` fields to be more consistent. The old
names are deprecated.

| old name                      | new name                        |
|-------------------------------|---------------------------------|
| `Context.envvarReader`        | `Context.readEnvvar`            |
| `Context.correctionSuggestor` | `Context.suggestTypoCorrection` |
| `Context.argumentFileReader`  | `Context.readArgumentFile`      |
| `Context.tokenTransformer`    | `Context.transformToken`        |

-   Removed previously deprecated experimental annotations.
-   Removed `MordantHelpFormatter.graphemeLength`
-   Removed `TermUi`

</details>

---

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Renovate
Bot](https://redirect.github.com/renovatebot/renovate).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC44NC4xIiwidXBkYXRlZEluVmVyIjoiMzguODQuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

---------

Co-authored-by: Zac Sweers <[email protected]>
  • Loading branch information
kateliu20 and ZacSweers committed Sep 19, 2024
1 parent 5204fe1 commit 4208c34
Show file tree
Hide file tree
Showing 14 changed files with 285 additions and 54 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ Changelog
**Unreleased**
--------------

- Change `slack.allowWarnings` property to `sgp.kotlin.allowWarnings`.
- Disallow warnings in Kotlin test compilations by default, add `sgp.kotlin.allowWarningsInTests` property to opt-out.

0.19.3
------

Expand Down
9 changes: 5 additions & 4 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[versions]
agp = "8.6.0"
agpAlpha = "8.6.0"
agpAlpha = "8.6.1"
anvil = "2.5.0-beta11"
bugsnagGradle = "8.1.0"
circuit = "0.23.1"
Expand All @@ -13,7 +13,7 @@ errorproneGradle = "3.0.1"
jdk = "22"
jvmTarget = "17"
jewel = "0.15.2.2"
jna = "5.14.0"
jna = "5.15.0"
kaml = "0.61.0"
kotlin = "2.0.20"
ksp = "2.0.20-1.0.25"
Expand Down Expand Up @@ -64,7 +64,7 @@ agpAlpha = { module = "com.android.tools.build:gradle", version.ref = "agpAlpha"
autoService-annotations = "com.google.auto.service:auto-service-annotations:1.1.1"
autoService-ksp = "dev.zacsweers.autoservice:auto-service-ksp:1.2.0"
bugsnag = "com.bugsnag:bugsnag:3.7.2"
clikt = "com.github.ajalt.clikt:clikt:4.4.0"
clikt = "com.github.ajalt.clikt:clikt:5.0.0"
circuit-foundation = { module = "com.slack.circuit:circuit-foundation", version.ref = "circuit" }
commonsText = "org.apache.commons:commons-text:1.12.0"
composeLints = "com.slack.lint.compose:compose-lint-checks:1.3.1"
Expand Down Expand Up @@ -117,9 +117,10 @@ okhttp-bom = { module = "com.squareup.okhttp3:okhttp-bom", version.ref = "okhttp
okhttp-loggingInterceptor = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okhttp" }
okio = { module = "com.squareup.okio:okio", version.ref = "okio" }
okio-fakefilesystem = { module = "com.squareup.okio:okio-fakefilesystem", version.ref = "okio" }
oshi = "com.github.oshi:oshi-core:6.6.3"
oshi = "com.github.oshi:oshi-core:6.6.4"
retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
retrofit-converters-wire = { module = "com.squareup.retrofit2:converter-wire", version.ref = "retrofit" }
retrofit-converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofit"}
rxjava = "io.reactivex.rxjava3:rxjava:3.1.9"
slackLints-checks = { module = "com.slack.lint:slack-lint-checks", version.ref = "slack-lint" }
slackLints-annotations = { module = "com.slack.lint:slack-lint-annotations", version.ref = "slack-lint" }
Expand Down
6 changes: 6 additions & 0 deletions skate-plugin/project-gen/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ kotlin {
implementation(libs.jewel.bridge232)
implementation(libs.kotlin.poet)
implementation(libs.markdown)

implementation(libs.kaml)
implementation(libs.okhttp)
implementation(libs.okhttp.loggingInterceptor)
implementation(libs.retrofit)
implementation(libs.retrofit.converter.gson)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* Copyright (C) 2024 Slack Technologies, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package slack.tooling.aibot

import com.google.gson.Gson
import com.google.gson.JsonObject
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader
import java.util.concurrent.TimeUnit
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.jetbrains.annotations.VisibleForTesting

class ChatBotActionService {
suspend fun executeCommand(question: String): String {
val jsonInput = createJsonInput(question)
val scriptContent = createScriptContent(jsonInput)
val tempScript = createTempScript(scriptContent)
val output = runScript(tempScript)
tempScript.delete()
return parseOutput(output)
}

@VisibleForTesting
private fun createJsonInput(question: String): String {
val gsonInput = Gson()
val jsonObjectInput =
Content(
messages = listOf(Message(role = "user", question)),
source = "curl",
max_tokens = 2048,
)

val content = gsonInput.toJson(jsonObjectInput)

println("jsonContent $content")

return content
}

@VisibleForTesting
private fun createScriptContent(jsonInput: String): String {
val scriptContent =
"""
temp
"""
.trimIndent()
return scriptContent
}

@VisibleForTesting
private suspend fun createTempScript(scriptContent: String): File {
val tempScript = withContext(Dispatchers.IO) { File.createTempFile("run_command", ".sh") }
tempScript.writeText(scriptContent)
tempScript.setExecutable(true)
return tempScript
}

@VisibleForTesting
private fun runScript(tempScript: File): String {

val processBuilder = ProcessBuilder("/bin/bash", tempScript.absolutePath)
processBuilder.redirectErrorStream(true)

val process = processBuilder.start()
val output = StringBuilder()

BufferedReader(InputStreamReader(process.inputStream)).use { reader ->
var line: String?
while (reader.readLine().also { line = it } != null) {
output.append(line).append("\n")
}
}

val completed = process.waitFor(600, TimeUnit.SECONDS)
if (!completed) {
process.destroyForcibly()
throw RuntimeException("Process timed out after 600 seconds")
}

tempScript.delete()
return output.toString()
}

@VisibleForTesting
private fun parseOutput(output: String): String {
println("output: $output")
val regex = """\{.*\}""".toRegex(RegexOption.DOT_MATCHES_ALL)
val result = regex.find(output.toString())?.value ?: "{}"
val gson = Gson()
val jsonObject = gson.fromJson(result, JsonObject::class.java)
val contentArray = jsonObject.getAsJsonArray("content")
val contentObject = contentArray.get(0).asJsonObject
val actualContent = contentObject.get("content").asString

println("actual content $actualContent")

return actualContent
}

data class Content(
val messages: List<Message>,
val source: String = "curl",
val max_tokens: Int = 512,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,18 @@
*/
package slack.tooling.aibot

import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.ui.graphics.Color
import org.jetbrains.jewel.foundation.theme.JewelTheme

object ChatColors {
val promptBackground = Color(0xFF45494A)

// Color(0xFF2d2f30) responseBackground
val responseBackground: Color
@Composable @ReadOnlyComposable get() = JewelTheme.globalColors.infoContent
val responseBackground = Color(0xFF2d2f30)
// @Composable @ReadOnlyComposable get() = JewelTheme.globalColors.infoContent

// Color(0xFFEAEEF7) userTextColor
val userTextColor: Color
@Composable @ReadOnlyComposable get() = JewelTheme.globalColors.infoContent
val userTextColor = Color(0xFFEAEEF7)
// @Composable @ReadOnlyComposable get() = JewelTheme.globalColors.infoContent

val responseTextColor = Color(0xFFE0EEF7)
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,31 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import com.slack.circuit.runtime.presenter.Presenter
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class ChatPresenter : Presenter<ChatScreen.State> {
val user = "user"
val bot = "bot"
private val chatBotActionService = ChatBotActionService()

@Composable
override fun present(): ChatScreen.State {
var messages by remember { mutableStateOf(emptyList<Message>()) }

return ChatScreen.State(messages = messages) { event ->
when (event) {
is ChatScreen.Event.SendMessage -> {
val newMessage = Message(event.message, isMe = true)
val newMessage = Message(role = user, event.message)
messages = messages + newMessage
val response = Message(callApi(event.message), isMe = false)
messages = messages + response

CoroutineScope(Dispatchers.IO).launch {
val response = chatBotActionService.executeCommand(event.message)
messages = messages + Message(role = bot, response)
}
}
}
}
}

private fun callApi(message: String): String {
// function set up to call the DevXP API in the future.
// right now, just sends back the user input message
return ("I am a bot. You said \"${message}\"")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,10 @@ fun ChatWindowUi(state: ChatScreen.State, modifier: Modifier = Modifier) {
Column(modifier = modifier.fillMaxSize().background(JewelTheme.globalColors.paneBackground)) {
LazyColumn(modifier = Modifier.weight(1f), reverseLayout = true) {
items(state.messages.reversed()) { message ->
val isMe = message.role == "user"
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = if (message.isMe) Arrangement.End else Arrangement.Start,
horizontalArrangement = if (isMe) Arrangement.End else Arrangement.Start,
) {
ChatBubble(message)
}
Expand Down Expand Up @@ -148,18 +149,17 @@ private fun ConversationField(modifier: Modifier = Modifier, onSendMessage: (Str

@Composable
private fun ChatBubble(message: Message, modifier: Modifier = Modifier) {
val isMe = message.role == "user"
Box(
Modifier.wrapContentWidth()
.padding(8.dp)
.shadow(elevation = 0.5.dp, shape = RoundedCornerShape(25.dp), clip = true)
.background(
color = if (message.isMe) ChatColors.promptBackground else ChatColors.responseBackground
)
.background(color = if (isMe) ChatColors.promptBackground else ChatColors.responseBackground)
.padding(8.dp)
) {
Text(
text = message.text,
color = if (message.isMe) ChatColors.userTextColor else ChatColors.responseTextColor,
text = message.content,
color = if (isMe) ChatColors.userTextColor else ChatColors.responseTextColor,
modifier = modifier.padding(8.dp),
fontFamily = FontFamily.SansSerif,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ package slack.tooling.aibot

import androidx.compose.runtime.Immutable

@Immutable data class Message(val text: String, val isMe: Boolean)
@Immutable data class Message(var role: String, val content: String)
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright (C) 2024 Slack Technologies, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package slack.tooling.aibot

import com.google.common.truth.Truth.assertThat
import com.google.gson.Gson
import com.google.gson.JsonObject
import junit.framework.TestCase.assertEquals
import org.junit.Test

class ChatBotActionServiceTest {
@Test
fun `createJsonInput with simple input`() {
val question = "Why is the sky blue?"

val result = createJsonInput(question)

val expectedJson =
"""
{
"messages": [
{
"role": "user",
"content": "Why is the sky blue?"
}
],
"source": "curl",
"max_tokens": 512
}
"""
.trimIndent()

val trimmedExpected = expectedJson.replace(Regex("\\s"), "")
val trimmedResult = result.replace(Regex("\\s"), "")
println("expected is $trimmedExpected")
println("actual is $trimmedResult")

assertThat(trimmedResult).isEqualTo(trimmedExpected)
}

@Test
fun `createJsonInput with long strings`() {
val question = "A".repeat(10000)
val result = createJsonInput(question)
println("result $result")
val jsonObject = Gson().fromJson(result, JsonObject::class.java)
println(jsonObject)
assertEquals(
question,
jsonObject.get("messages").asJsonArray[0].asJsonObject.get("content").asString,
)
}

@Test
fun `createJsonInput with special characters`() {
val question = "What about \n, \t, and \"quotes\"? and \'apostrophes"
val result = createJsonInput(question)
println("result $result")
val jsonObject = Gson().fromJson(result, JsonObject::class.java)
assertEquals(
question,
jsonObject.get("messages").asJsonArray[0].asJsonObject.get("content").asString,
)
}

private fun createJsonInput(question: String): String {
val user = "user"
val gsonInput = Gson()
val content =
Content(messages = listOf(Message(role = user, question)), source = "curl", max_tokens = 512)

val jsonContent = gsonInput.toJson(content).toString()
return jsonContent
}

data class Content(
val messages: List<Message>,
val source: String = "curl",
val max_tokens: Int = 512,
)
}
Loading

0 comments on commit 4208c34

Please sign in to comment.