Skip to content

Commit

Permalink
wip implementation of wake-word->intent->transcripts flow
Browse files Browse the repository at this point in the history
  • Loading branch information
Jef808 committed Feb 9, 2024
1 parent 7ee2b92 commit 7280e4e
Show file tree
Hide file tree
Showing 33 changed files with 1,107 additions and 475 deletions.
1 change: 1 addition & 0 deletions data/LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
A copy of license terms is available at https://picovoice.ai/docs/terms-of-use/
71 changes: 71 additions & 0 deletions data/computer-commands.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
context:
expressions:
getScript:
- "@promptOpenAI (me) [a, an] ($programmingLanguage:language) script"
answerQuestion:
- "@promptOpenAI (me) [an, the, the following] answer to [this, that, the,
the following] question"
- Answer (me) [this, the, the following, that] question
simplyTranscribe:
- Write [this, that, the following, what follows]
- Transcribe
changeContext:
- "[go to, focus, switch to] the [$pv.SingleDigitOrdinal:windowNumber,
$windowName:windowName] window"
- "[go to, focus, switch to] the [$pv.SingleDigitOrdinal:contextIndex, $contextType:contextType]"
openWindow:
- "[open, launch] $windowName:windowName"
- "[open, launch] [a, an] (new) $windowName:windowName window"
setVolume:
- $volumeSetting:volumeSetting (the volume)
- (Set) (the) [volume, sound] (to) $pv.Percent:percentage
slots:
programmingLanguage:
- javascript
- emacs
- shell
- python
contextType:
- window
- emacs workspace
- stump workspace
contextName:
- home j f a
- home directory
- emacs
- browser
promptType:
- question
- script
windowName:
- internet
- web
- google search
- sound control
- sound
- chrome
- fire fox
- kitty
- browser
- emacs
- shell
volumeSetting:
- unmute
- mute
macros:
promptOpenAI:
- I need
- I want
- generate
- give
- write
articlesAndDemonstratives:
- that
- this
- the
- an
- a
generate:
- give
- write
- generate
Binary file added data/computer-commands_en_linux_v3_0_0.rhn
Binary file not shown.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions echo_crafter/listener/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__all__ = ['handle_intent']
136 changes: 136 additions & 0 deletions echo_crafter/listener/handle_intent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
#!/usr/bin/env python3

import contextlib
import importlib
import os
from pathlib import Path
import subprocess
import yaml

PROJECT_ROOT = Path(os.getenv('PROJECT_ROOT'))


def send_to_keyboard(content):
"""Send the content to the keyboard."""
subprocess.Popen(
['xdotool', 'type', '--clearmodifiers', '--delay', '0', content]
)


def set_volume(volume, percentage=None, volume_setting=None):
"""Set the volume to the given value."""
if volume_setting is not None:
mute = '0' if volume_setting == 'unmute' else '1'
subprocess.Popen(
['pactl', 'set-sink-mute', '@DEFAULT_SINK@', mute]
)
elif percentage is not None:
subprocess.Popen(
['pactl', 'set-sink-volume', '@DEFAULT_SINK@', f'{percentage}%']
)
else:
raise ValueError('Either percentage or volume_setting must be provided')


def prompt_openai(transcript, *, language=None, ask_question=False):
"""Prompt openai using the script appropriate for the given language."""
if ask_question:
name = '.prompt_openai'
package = 'echo_crafter.prompts'
elif language == 'shell':
name = '.prompt_shell'
package = 'echo_crafter.prompts'
elif language == 'emacs':
name = '.prompt_elisp'
package = 'echo_crafter.prompts'
else:
name = '.prompt_python'
package = 'echo_crafter.prompts'

module = importlib.import_module(name, package)
try:
response = module.main(transcript)
return response
except Exception as e:
print(e)


def focus_window(*, window_number=None, window_name=None):
"""Focus the window with the given name."""
import re

if window_number is not None:
m = re.match(r'\d+', window_number)
if m is not None:
try:
number = int(m.group(0))
subprocess.Popen(
['stumpish', 'select-window-by-number', number]
)
except ValueError:
pass
elif window_name is not None:
print(f"focusing window {window_name}")
subprocess.Popen(
['xdotool', 'search', '--onlyvisible', '--class', window_name, 'windowactivate']
)


def open_window(*, window_name):
"""Open a window with the given name."""
if window_name in ['terminal', 'shell', 'kitty']:
subprocess.Popen(
['stumpish', 'open-window', window_name]
)
subprocess.Popen(
['stumpish', 'open-window', window_name]
)


class TranscriptHandler:
"""Handle speech transcripts according to a given intent."""

class PartialTranscriptHandler:
"""Handle partial transcripts according to a given intent."""

def __init__(self, intent_list):
"""Initialize a PartialTranscriptHandler instance."""


def __enter__(self):
"""Enter the context manager."""
pass

def __exit__(self, exc_type, exc_value, traceback):
"""Exit the context manager."""
pass

class FinalTranscriptHandler:
"""Handle final transcripts according to a given intent."""

def __init__(self, intent):
"""Initialize a FinalTranscriptHandler instance."""
self.intent = intent

def __enter__(self):
"""Enter the context manager."""
pass

def __exit__(self, exc_type, exc_value, traceback):
"""Exit the context manager."""
pass

def __init__(self, intent_config_file):
"""Initialize an IntentHandler instance."""
with open(intent_config_file, 'r') as file:
self.intent_config = yaml.safe_load(file)

@contextlib.contextmanager
def partial_transcript_handler(self, intent):
"""Handle a partial transcript according to the given intent."""
pass

@contextlib.contextmanager
def final_transcript_handler(self, intent):
"""Handle a final transcript according to the given intent."""
pass
Loading

0 comments on commit 7280e4e

Please sign in to comment.