Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 37 additions & 9 deletions lib/Controller/ChattyLLMController.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

#[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)]
class ChattyLLMController extends Controller {
private array $agencyActionNames;
private array $agencyActionData;

public function __construct(
string $appName,
Expand All @@ -51,19 +51,47 @@ public function __construct(
private ?string $userId,
) {
parent::__construct($appName, $request);
$this->agencyActionNames = [
'send_message_to_conversation' => $this->l10n->t('Send a message to a Talk conversation'),
'list_talk_conversations' => $this->l10n->t('List Talk conversations'),
'list_messages_in_conversation' => $this->l10n->t('List messages in a Talk conversation'),
'schedule_event' => $this->l10n->t('Schedule a calendar event'),
'list_calendars' => $this->l10n->t('List calendars'),
$this->agencyActionData = [
// talk
'send_message_to_conversation' => [
'title' => $this->l10n->t('Send a message to a Talk conversation'),
'icon' => 'Send',
],
'create_public_conversation' => [
'title' => $this->l10n->t('Create a conversation'),
'icon' => 'ChatPlus',
],
// mail
'send_email' => [
'title' => $this->l10n->t('Send an email'),
'icon' => 'EmailPlus',
],
// calendar
'schedule_event' => [
'title' => $this->l10n->t('Schedule a calendar event'),
'icon' => 'CalendarPlus',
],
'add_task' => [
'title' => $this->l10n->t('Add a calendar task'),
'icon' => 'CalendarCheck',
],
// deck
'add_card' => [
'title' => $this->l10n->t('Create a Deck card'),
'icon' => 'CardPlus',
],
];
}

private function improveAgencyActionNames(array $actions): array {
return array_map(function ($action) {
if (isset($action->name) && isset($this->agencyActionNames[$action->name])) {
$action->name = $this->agencyActionNames[$action->name];
if (isset($action->name, $this->agencyActionData[$action->name])) {
if (isset($this->agencyActionData[$action->name]['icon'])) {
$action->icon = $this->agencyActionData[$action->name]['icon'];
}
if (isset($this->agencyActionData[$action->name]['title'])) {
$action->name = $this->agencyActionData[$action->name]['title'];
}
}
return $action;
}, $actions);
Expand Down
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"npm": "^10.0.0"
},
"dependencies": {
"@mdi/js": "^7.4.47",
"@mdi/svg": "^7.4.47",
"@nextcloud/auth": "^2.0.0",
"@nextcloud/axios": "^2.0.0",
Expand Down
96 changes: 76 additions & 20 deletions src/components/ChattyLLM/AgencyAction.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,47 @@
-->
<template>
<div class="agency-action">
<NcChip type="primary"
:no-close="true"
:text="action.name.replace(/_/g, ' ')">
<template #icon>
<ToolsIcon :size="16" />
</template>
</NcChip>
<NcChip v-for="(argValue, argName) in action.args"
<div class="action-title">
<NcIconSvgWrapper :path="iconPath" :name="action.name" />
<strong>
{{ action.name }}
</strong>
</div>
<span v-for="(argValue, argName) in actionArguments"
:key="argName + argValue"
class="param"
:no-close="true"
:text="getParamText(argName, argValue)"
:title="getParamText(argName, argValue)">
{{ getParamText(argName, argValue) }}
</span>
<NcButton v-if="needsExpand"
class="expand"
@click="expanded = !expanded">
{{ expanded ? t('assistant', 'Less') : t('assistant', 'More') }}
<template #icon>
<CogIcon :size="16" />
<ChevronDoubleUpIcon v-if="expanded" />
<ChevronDoubleDownIcon v-else />
</template>
</NcChip>
</NcButton>
</div>
</template>

<script>
import ToolsIcon from 'vue-material-design-icons/Tools.vue'
import CogIcon from 'vue-material-design-icons/Cog.vue'
import ChevronDoubleDownIcon from 'vue-material-design-icons/ChevronDoubleDown.vue'
import ChevronDoubleUpIcon from 'vue-material-design-icons/ChevronDoubleUp.vue'

import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'

import NcChip from '@nextcloud/vue/dist/Components/NcChip.js'
const maxDisplayedArgs = 3

export default {
name: 'AgencyAction',

components: {
NcChip,
ToolsIcon,
CogIcon,
NcIconSvgWrapper,
NcButton,
ChevronDoubleDownIcon,
ChevronDoubleUpIcon,
},

props: {
Expand All @@ -46,23 +54,71 @@ export default {
},
},

data: () => {
return {
iconPath: null,
expanded: false,
}
},

computed: {
needsExpand() {
return Object.keys(this.action.args).length > maxDisplayedArgs
},
actionArguments() {
if (this.needsExpand && !this.expanded) {
const keys = Object.keys(this.action.args).slice(0, maxDisplayedArgs)
return keys.reduce((acc, val) => {
acc[val] = this.action.args[val]
return acc
}, {})
}
return this.action.args
},
},

mounted() {
this.getIcon()
},

methods: {
getParamText(argName, argValue) {
return argName.replace(/_/g, ' ') + ': ' + argValue
},
async getIcon() {
const { ['mdi' + (this.action.icon ?? 'Tools')]: icon } = await import('@mdi/js')
this.iconPath = icon
},
},
}
</script>

<style lang="scss" scoped>
.agency-action {
display: flex;
flex-direction: column;
align-items: start;
gap: 4px;
flex-wrap: wrap;

border-radius: var(--border-radius-large);
background-color: var(--color-primary-element-light-hover);
padding: 8px;

.action-title {
display: flex;
align-items: center;
gap: 4px;
}

.param {
max-width: 300px;
white-space: nowrap;
text-overflow: ellipsis;
width: 100%;
overflow: hidden;
}

.expand {
align-self: center;
}
}
</style>
13 changes: 9 additions & 4 deletions src/components/ChattyLLM/AgencyActions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
<div class="agency-actions">
<AgencyAction v-for="action in actions"
:key="action.id"
:action="action" />
:action="action"
class="action" />
</div>
</template>

Expand All @@ -32,8 +33,12 @@ export default {
<style lang="scss" scoped>
.agency-actions {
display: flex;
flex-direction: column;
align-items: start;
gap: 4px;
flex-wrap: wrap;
align-items: stretch;
gap: 8px;

.action {
max-width: 300px;
}
}
</style>
18 changes: 9 additions & 9 deletions src/components/ChattyLLM/AgencyConfirmation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
<NcNoteCard type="warning"
<NcNoteCard type="info"
class="agency-confirmation">
<div class="notecard-content">
<span>
Expand All @@ -18,20 +18,20 @@
<InformationOutlineIcon :size="20" />
</template>
</NcButton>
<NcButton type="success"
@click="$emit('confirm')">
{{ t('assistant', 'Confirm those actions') }}
<template #icon>
<AssistantIcon :size="20" />
</template>
</NcButton>
<NcButton type="error"
<NcButton type="secondary"
@click="$emit('reject')">
{{ t('assistant', 'Cancel') }}
<template #icon>
<CloseIcon :size="20" />
</template>
</NcButton>
<NcButton type="primary"
@click="$emit('confirm')">
{{ t('assistant', 'Confirm those actions') }}
<template #icon>
<AssistantIcon :size="20" />
</template>
</NcButton>
</div>
</div>
</NcNoteCard>
Expand Down
Loading