1
1
mirror of https://github.com/leon-ai/leon.git synced 2024-10-04 05:07:12 +03:00

feat(skill/timer): add check_timer action

This commit is contained in:
louistiti 2024-08-21 09:32:07 +08:00
parent ff83e272c0
commit c695aadfbe
8 changed files with 160 additions and 101 deletions

View File

@ -48,6 +48,16 @@ export default function renderAuroraComponent(
})
}
// TODO: now!
// TODO: if onFetch, then set new values here, send generic fetch request to get skill -> widget id?
// TODO: need to create a standard on_fetch skill action that will be executed?
/*if (component.props.onFetch) {
console.log('component', component)
if (component.props.initialTime) {
component.props.initialTime = 0
}
}*/
return createElement(reactComponent, component.props)
}
}

View File

@ -52,6 +52,64 @@
"route": "/api/action/games/rochambeau/rematch",
"params": []
},
{
"method": "POST",
"route": "/api/action/news/github_trends/run",
"params": ["number", "daterange"],
"entitiesType": "builtIn"
},
{
"method": "GET",
"route": "/api/action/news/product_hunt_trends/run",
"params": []
},
{
"method": "POST",
"route": "/api/action/productivity/todo_list/create_list",
"params": ["list"],
"entitiesType": "trim"
},
{
"method": "GET",
"route": "/api/action/productivity/todo_list/view_lists",
"params": []
},
{
"method": "POST",
"route": "/api/action/productivity/todo_list/view_list",
"params": ["list"],
"entitiesType": "trim"
},
{
"method": "POST",
"route": "/api/action/productivity/todo_list/rename_list",
"params": ["old_list", "new_list"],
"entitiesType": "trim"
},
{
"method": "POST",
"route": "/api/action/productivity/todo_list/delete_list",
"params": ["list"],
"entitiesType": "trim"
},
{
"method": "POST",
"route": "/api/action/productivity/todo_list/add_todos",
"params": ["todos", "list"],
"entitiesType": "trim"
},
{
"method": "POST",
"route": "/api/action/productivity/todo_list/complete_todos",
"params": ["todos", "list"],
"entitiesType": "trim"
},
{
"method": "POST",
"route": "/api/action/productivity/todo_list/uncheck_todos",
"params": ["todos", "list"],
"entitiesType": "trim"
},
{
"method": "GET",
"route": "/api/action/leon/age/run",
@ -127,89 +185,6 @@
"route": "/api/action/leon/thanks/run",
"params": []
},
{
"method": "POST",
"route": "/api/action/news/github_trends/run",
"params": ["number", "daterange"],
"entitiesType": "builtIn"
},
{
"method": "GET",
"route": "/api/action/news/product_hunt_trends/run",
"params": []
},
{
"method": "POST",
"route": "/api/action/productivity/todo_list/create_list",
"params": ["list"],
"entitiesType": "trim"
},
{
"method": "GET",
"route": "/api/action/productivity/todo_list/view_lists",
"params": []
},
{
"method": "POST",
"route": "/api/action/productivity/todo_list/view_list",
"params": ["list"],
"entitiesType": "trim"
},
{
"method": "POST",
"route": "/api/action/productivity/todo_list/rename_list",
"params": ["old_list", "new_list"],
"entitiesType": "trim"
},
{
"method": "POST",
"route": "/api/action/productivity/todo_list/delete_list",
"params": ["list"],
"entitiesType": "trim"
},
{
"method": "POST",
"route": "/api/action/productivity/todo_list/add_todos",
"params": ["todos", "list"],
"entitiesType": "trim"
},
{
"method": "POST",
"route": "/api/action/productivity/todo_list/complete_todos",
"params": ["todos", "list"],
"entitiesType": "trim"
},
{
"method": "POST",
"route": "/api/action/productivity/todo_list/uncheck_todos",
"params": ["todos", "list"],
"entitiesType": "trim"
},
{
"method": "GET",
"route": "/api/action/social_communication/conversation/setup",
"params": []
},
{
"method": "GET",
"route": "/api/action/social_communication/conversation/chit_chat",
"params": []
},
{
"method": "GET",
"route": "/api/action/social_communication/conversation/converse",
"params": []
},
{
"method": "GET",
"route": "/api/action/social_communication/mbti/setup",
"params": []
},
{
"method": "GET",
"route": "/api/action/social_communication/mbti/quiz",
"params": []
},
{
"method": "GET",
"route": "/api/action/unknown/widget-playground/run",
@ -305,6 +280,31 @@
"method": "GET",
"route": "/api/action/utilities/translator-poc/translate",
"params": []
},
{
"method": "GET",
"route": "/api/action/social_communication/conversation/setup",
"params": []
},
{
"method": "GET",
"route": "/api/action/social_communication/conversation/chit_chat",
"params": []
},
{
"method": "GET",
"route": "/api/action/social_communication/conversation/converse",
"params": []
},
{
"method": "GET",
"route": "/api/action/social_communication/mbti/setup",
"params": []
},
{
"method": "GET",
"route": "/api/action/social_communication/mbti/quiz",
"params": []
}
]
}

View File

@ -197,6 +197,7 @@ export default class SocketServer {
} else if (method.methodName === 'run_skill_action') {
this.socket?.emit('widget-run-skill-action', method.methodParams)
} else if (method.methodName === 'fetch_widget_data') {
console.log('method.methodParams', method.methodParams)
// TODO: get memory from domain:skill:action
// TODO: grab new data from the widget. E.g. initialTime
// TODO: get memory timestamp of the timer creation + initialTime

View File

@ -58,7 +58,8 @@
"unit_not_supported": [
"Sorry, I can't set a timer for this unit. Use %hours%, %minutes% or %seconds% instead.",
"I can't set a timer for this duration. Use %hours%, %minutes% or %seconds% instead."
]
],
"no_timer_set": ["No timer is set.", "There is no timer set."]
},
"widget_contents": {
"second_unit": "second",

View File

@ -0,0 +1,31 @@
import type { ActionFunction } from '@sdk/types'
import { leon } from '@sdk/leon'
import { TimerWidget } from '../widgets/timer-widget'
import { getNewestTimerMemory } from '../lib/memory'
export const run: ActionFunction = async function () {
const timerMemory = await getNewestTimerMemory()
if (!timerMemory) {
return await leon.answer({ key: 'no_timer_set' })
}
const { widgetId, interval, finishedAt, duration } = timerMemory
const remainingTime = finishedAt - Math.floor(Date.now() / 1_000)
if (remainingTime <= 0) {
return await leon.answer({ key: 'no_timer_set' })
}
const timerWidget = new TimerWidget({
params: {
id: widgetId,
seconds: remainingTime,
initialDuration: duration,
interval
}
})
await leon.answer({ widget: timerWidget })
}

View File

@ -1,9 +1,8 @@
import type { ActionFunction, BuiltInDurationEntity } from '@sdk/types'
import { leon } from '@sdk/leon'
import { Memory } from '@sdk/memory'
import { TimerWidget } from '../widgets/timer'
import { createTimerMemory } from '@@/skills/utilities/timer/src/lib/memory'
import { TimerWidget } from '../widgets/timer-widget'
import { createTimerMemory } from '../lib/memory'
export const run: ActionFunction = async function (params) {
const supportedUnits = ['hours', 'minutes', 'seconds']
@ -23,14 +22,15 @@ export const run: ActionFunction = async function (params) {
const { value: durationValue } = duration
const seconds = Number(durationValue)
const interval = 1_000
const timerWidget = new TimerWidget({
params: {
seconds
seconds,
interval
}
})
await createTimerMemory(timerWidget.id, seconds)
await createTimerMemory(timerWidget.id, seconds, interval)
// TODO: return a speech without new utterance
/*await leon.answer({

View File

@ -3,6 +3,7 @@ import { Memory } from '@sdk/memory'
export interface TimerMemory {
widgetId: string
duration: number
interval: number
createdAt: number
finishedAt: number
}
@ -14,13 +15,16 @@ const TIMERS_MEMORY = new Memory<TimerMemory[]>({
export async function createTimerMemory(
widgetId: string,
duration: number
duration: number,
interval: number
): Promise<TimerMemory> {
const createdAt = Math.floor(Date.now() / 1_000)
const newTimerMemory: TimerMemory = {
duration,
widgetId,
createdAt: Date.now(),
finishedAt: Date.now() + duration
interval,
createdAt,
finishedAt: createdAt + duration
}
const timersMemory = await TIMERS_MEMORY.read()
@ -28,3 +32,9 @@ export async function createTimerMemory(
return newTimerMemory
}
export async function getNewestTimerMemory(): Promise<TimerMemory | null> {
const timersMemory = await TIMERS_MEMORY.read()
return timersMemory[timersMemory.length - 1] || null
}

View File

@ -5,11 +5,18 @@ import { Timer } from './components/timer'
interface Params {
seconds: number
interval: number
initialDuration?: number
id?: string
}
export class TimerWidget extends Widget<Params> {
constructor(options: WidgetOptions<Params>) {
super(options)
if (options.params.id) {
this.id = options.params.id
}
}
/**
@ -25,15 +32,16 @@ export class TimerWidget extends Widget<Params> {
// TODO: <Loader isLoading={isFetching}>content...</Loader>
public render(): WidgetComponent {
const { seconds } = this.params
const { seconds, interval, initialDuration } = this.params
const secondUnitContent = this.content('second_unit')
const secondsUnitContent = this.content('seconds_unit')
const minuteUnitContent = this.content('minute_unit')
const minutesUnitContent = this.content('minutes_unit')
const totalTime = initialDuration || seconds
let totalTimeContent = ''
if (seconds >= 60) {
const minutes = seconds / 60
if (totalTime >= 60) {
const minutes = totalTime / 60
totalTimeContent = this.content('total_time', {
value: minutes % 1 === 0 ? minutes : minutes.toFixed(2),
@ -41,14 +49,14 @@ export class TimerWidget extends Widget<Params> {
})
} else {
totalTimeContent = this.content('total_time', {
value: seconds,
unit: seconds > 1 ? secondsUnitContent : secondUnitContent
value: totalTime,
unit: totalTime > 1 ? secondsUnitContent : secondUnitContent
})
}
return new Timer({
initialTime: seconds,
interval: 1_000,
interval,
totalTimeContent,
onFetch: (): WidgetEventMethod => {
return this.fetchWidgetData(['initialTime'])
@ -60,6 +68,4 @@ export class TimerWidget extends Widget<Params> {
}
})
}
public fetch(dataToSet: string[]): WidgetEventMethod {}
}