=====================
 Narval User Stories
=====================

:Author: Nicolas Chauvat
:Date: $Date$
:Revision: $Revision$
:Description: executable specification of Narval's features

.. contents:: Table of contents

A Narval agent can connect to a jabber server to exchange messages
and presence information using XMPP_. Here are user stories describing the
interaction between a Narval and a user.

.. _XMPP: http://www.jabber.org/protocol/


Engine control
==============

shut down
---------
One can shut down one's assistant by asking it to shut down.

noTest ::

    DIALOG(jean,narvabot)

    jean: shut down
    [narvabot is disconnected]


There are other synonyms, like die.

:use-recipe: active-commands.narval-shutdown


start a plan
------------

One can ask one's assistant to start an arbitrary plan. This is a
low-level action intended to help an advanced user make its assistant
do things or debug.

Test ::

    DIALOG(jean,narvabot)

    jean: start-plan Chat.say-hello
    narvabot: hello

:use-recipe: active-commands.narval-start-plan


reschedule a plan
-----------------

A running plan can be rescheduled to a later time. This is a way to
delay the execution of plans.

Test ::

    DIALOG(jean,narvabot)

    jean: start-plan Chat.say-hello
    narvabot:{re} started plan with eid (\d+)
    jean: reschedule plan \1 +3
    narvabot:{re} plan \1 rescheduled (new eid (\d+))

:use-recipe: active-commands.narval-reschedule-plan


inspect memory
--------------

One can use an arbitrary python expression to inspect narval's memory.


Test ::
    
    DIALOG(jean,narvabot)

    jean: inspect elmt.jabberid == 'jean'
    narvabot:{re}\* MasterInformationsElement: .*

:use-recipe: active-commands.narval-introspection


reload AIL rules
----------------

One can modify the pseudo-natural language processing rules of an agent while it
is running. These rules are defined in the file pointed to by URL element named
"uri:memory:rules". To test the changes, just tell the agent to reload its
"ail brain".

Test ::

    DIALOG(jean,narvabot)

    jean: reload ail brain
    narvabot: ail brain reloaded

:use-recipe: active-commands.chat-reload-ail-brain


permissions on actions
----------------------

distinction between public/protected/private action

depending on permissions(?) of requester, allow action execution or
not. Should handle groups.

:see: element bot-configuration in memory



Introspection
=============

log plans
---------

As an example of instrospection, one can log the state of the plans that are in
memory.  The corresponding recipe will not try to log itself in order
to avoid infinite loop.

To try it, define a "uri:memory:planslog" URL element and start plan
narval-log-started-plan.

Another recipe, narval-log-ended-plan, will write to a file the plans that are
in the state failed or done.

log execution of plans: add a new recipe that will append a line to a
file each time a plan is started and completed or failed

:use-recipe: active-commands.log-started-plans
:use-recipe: active-commands.log-ended-plans


dynamic help generation
-----------------------

generate chatbot help for available commands by introspecting active
plan. look at existing active plan (and at chatbot.ail file ?!) and
generate a help message

Test ::

    DIALOG(jean,narvabot)

    jean: help
    narvabot:{re} active plans:.*
    jean: help narval-start-plan
    narvabot:{re} help for plans matching u'narval-start-plan':.*

:use-recipe: active-commands.narval-help

statement of what is allowed to be done
---------------------------------------

lists active plans available to user. 

noTest ::

     DIALOG(jean, narvabot)
     
     jean: what can I do?
     narvabot: this and that


  
generate documentation as docbook
---------------------------------

The recipe narval-generate-docbook will look at all the available recipes and
generate a docbook/xml file that can be turned into a PDF file.

Test ::

    DIALOG(jean,narvabot)

    jean: generate recipe docbook
    narvabot: ok


Generated files should be found in the home directory.

:use-recipe: active-commands.narval-generate-docbook



Instant messaging
=================

add a user to jabber roster
---------------------------

One can ask his assistant to add a known jabber id to its personal roster. The
agent will then send a jabber request message to the user who will have to
accept the subcription for the agent to be able to actually receive the user's
presence messages.
  
Test ::

    DIALOG(jean,narvabot)

    jean: subscribe toto
    narvabot: sent subscription request to toto

:use-recipe: active-commands.chat-subscribe

  
determine nature of contacts
----------------------------

detect if a user is a narval on incoming presence elements

when an unknown user send a presence to a narval, this one asks the new
user if he is a narval agent or not, and add the answer to his
knowledge base.  
  
Narval can ask all jabber users if they are a Narval

FIXME: duplique l'histoire au dessus, non ?
Narval asks if other jabber users are a Narval implementation.

a Narval agent will answer yes, while human being and others programs
are supposed to answer no to the "are you a narval?" question

acceptance test: A narval can enter a conference room and answer the
question if there are any other Narval users.

add jabber user information to the knowledge base

:use-recipe: active-commands.kb-respond-to-presence
:use-recipe: active-commands.kb-state-you-are-a-narval
:use-recipe: active-commands.kb-register-user-type


multiple agents in one forum
----------------------------

as agents know whether other participants are Narval agents or not,
they take care to ignore the messages sent in forums by other
agents. this is to avoid witnessing endless and useless
agent-to-agent conversations.

:see: recipe chat.handle-commands



Conferences
===========

setup a conference
------------------

Jean asks his agent to set up a jabber meeting with a list of
participants. Narval opens a forum and invites participants. 

One can instruct his agent to leave a conference room.

Test ::

     DIALOG(jean,narvabot)

     jean: setup conf agents narvabot jean

     
     FORUM(agents,jean,narvabot)
     [narvabot invites jean to forum agents]
     [jean accepts invitation to forum agents]
     [narvabot is present in forum agents]
     jean: narvabot: thanks
     narvabot: jean: you are welcome
     jean: narvabot: leave
     narvabot: byebye everyone...
     [narvabot quits forum agents]

:use-recipe: active-commands.chat-conf-setup
:use-recipe: active-commands.chat-conf-kickout


setup a conference later
------------------------

Such conferences can also be scheduled ahead.

noTest ::

     DIALOG(jean,narvabot)

     jean: setup conf in 5 minutes in room agents with narvabot jean
     narvabot: ok

:use-recipe: active-commands.chat-delayed-conf-setup


Conversational interface
========================


predefined answers
------------------

automatically transfert some predefined answers to some input sentences.
Let us begin with the simplest example of all. We have an agent named narvabot
and a user named Jean.

Test ::

    DIALOG(jean,narvabot)
    
    jean: hello
    narvabot: hi

:use-recipe: active-commands.chat-filtered-response


introductions
-------------

narval gives some information about himself

Test ::

    DIALOG(jean, narvabot)
    
    jean: introduce yourself
    narvabot: Hello, my name is narvabot. I'm jean's Narval.


turing test
-----------

a narval knows he is one

Test ::
     DIALOG(jean, narvabot)
     
     jean: are you a narval?
     narvabot: I'm jean's narval

find out who's the narval of someone
------------------------------------

Ask a narval what is the name of someone's narval. 

Test ::
     DIALOG(jean, narvabot)
     
     jean: who is the narval of jean?
     narvabot: narvabot narval_of jean.

fill some data into a xml file, governed by a template
------------------------------------------------------

To write a new template, take a look at foaf.template or
example.template. Simply replace the gaps you want to fill with the
variable %s. 

Test ::
     
     DIALOG(jean, narvabot)

     jean: fill template example
     narvabot: you need to specify a filename
     jean: fill template asdf test.xml
     narvabot: no such template 'asdf'
     jean: fill template example test.xml
     narvabot: id :
     jean: crater
     narvabot: cpu :
     jean: 15000
     narvabot: memory :
     jean: 500Mo
     narvabot: operating_system :
     jean: debian
     narvabot: open_ports :
     jean: 22,80,153
     narvabot:{re} process completed, file written to .*/.narval_test/data/test.xml


:use-recipe: active-commands.chat-start-templated-discussion
:use-recipe: active-commands.chat-continue-templated-discussion
:see: file foaf.template in the narval home


template filling - cancel the operation
---------------------------------------

The user might want to cancel the process of filling in a
template. Keyword: *cancel*.

Test ::

     DIALOG(jean, narvabot)

     jean: fill template example test.xml
     narvabot: id :
     jean: test_0087
     narvabot: cpu :
     jean: cancel
     narvabot: input canceled


reference a subject present in KB
---------------------------------

was creating a meeting in several sentences: "meeting on 2004-09-28
1:00 duration is 40 min", "meeting on 2004-09-28 1:00 start at 14:00".


predicts presence based on previous observations
------------------------------------------------

narval agent analyzes presence informations of people in its roster to
be able to answer the following question : "when'll paul master be
back ?".

an agent should also be able to answer to the question "when will your
master be back?"

Test ::
     DIALOG(jean, narvabot)
     
     jean: when will bob be back? 
     narvabot:  I don't have any presence information for bob@jabber.logilab.org
     jean: when will jean be back?
     narvabot: jean@jabber.logilab.org is present
     jean: when will asdf be back?
     narvabot:  I don't have any presence information for asdf@jabber.logilab.org
     jean: when will arthur be back?
     narvabot:{re} [should be back.*|.*is present|should already be there.*]

:use-recipe: active-commands.chat-when-user-will-be-back



Agent-to-agent communication
============================


Agent asks another agent a question
-----------------------------------

A user enters a conference room with his personal agent. The personal
agent asks other agents for their public KB via RDF export.

:use-recipe: active-commands.kb-rdf-extract
:use-recipe: active-commands.kb-rdf-export
:use-recipe: active-commands.kb-rdf-import



Agent acting as secretary / representative
==========================================

tell your master that
---------------------

when user is off-line but agent is on-line, tell the agent to tell
something to its master. agent will then figure out what to do. keep
the message until the user logs on, send an SMS, send e-mail, make
phone call, etc. (yes, we can start with something simple :-)

forward a message to master via phone, email or instant messaging

:use-recipe: active-commands.comm-tell-master
:use-recipe: active-commands.comm-shtoom-tell-master



Knowledge base
==============

Adding and querying
-------------------

add and search statements
~~~~~~~~~~~~~~~~~~~~~~~~~

One can add facts to the knowledge base of his agent.

One can ask his agent about something and have it search its own knowledge base
for the information. 

Test ::

    DIALOG(jean,narvabot)

    jean: jean likes agents.
    jean: who likes agents?
    narvabot: jean likes agents.
       
:use-recipe: active-commands.kb-add-stmts
:use-recipe: active-commands.kb-search


add a rule
~~~~~~~~~~

One can add rules to the knowledge base of his agent.

Test ::

    DIALOG(jean,narvabot)

    jean: bob child joe.
    jean: joe child jack.
    jean: rule: X grandchild Y if X child Z and Z child Y
    jean: who grandchild jack?
    narvabot: bob grandchild jack.

:use-recipe: active-commands.kb-add-rule

  
RDQL queries
~~~~~~~~~~~~

Narval agents can store some information as RDF. One can then ask an agent
a question formatted as an RDQL query.

Test ::

    DIALOG(jean,narvabot)

    jean: tell me about narval
    narvabot: narval is an agent platform.
  
:use-recipe: active-commands.kb-rdql-query
:note: needs the redland kb backend


XML RDF
-------

RDF import
~~~~~~~~~~
one can import some XML-RDF to the knowledge base

Knowledge exchanged to Narvals as a RDF triple in the form (the
subject, the object, the predicate) can be placed into Narvals KB

acceptance test: the RDF statement for "tony eats pizza." can be
captured and exported as rdf triples and end up in another Narvals KB.

:use-recipe: active-commands.kb-rdf-import


RDF export
~~~~~~~~~~

one can export the knowledge base's content as XML-RDF

Knowledge captured in Narvals KB as a RDF triple in the form (the subject, the object, the predicate)

:Example: 

   the english statement "jean eats pizza." can be captured and exported to rdf
   triples. (sentence "todays meeting was created yesterday" is not parsed in a
   generic way yet).

Test ::

     DIALOG(jean,narvabot)

     jean: paul eats pizza.
     jean: who eats pizza?     
     narvabot: paul eats pizza.

:use-recipe: active-commands.kb-rdf-export


agent-to-agent RDF exchange
~~~~~~~~~~~~~~~~~~~~~~~~~~~

export the knowledge base's content as XML-RDF, formatted to be given to another agent

:see: `Agent asks another agent a question`_


XML FOAF (Friend-Of-A-Friend)
-----------------------------
  
import foaf data
~~~~~~~~~~~~~~~~

import FOAF data into knowledge base

Test ::

     DIALOG(jean, narvabot)
     
     jean: foaf:http://crater/~arthur/bob.foaf
     narvabot: imported http://crater/~arthur/bob.foaf

:use-recipe: active-commands.kb-foaf-import

  
query FOAF data
~~~~~~~~~~~~~~~

query the FOAF data previously imported as in "who does <foaf:name> <foaf:know>"

Test ::
     
     DIALOG(jean, narvabot)

     jean: what's Bob Dover's nick?
     narvabot:  (nick) : (bobby)
     jean: who does Bob Dover know?
     narvabot:  (name) : (John Doe)
     jean: who do i know?
     narvabot:  Sorry, no result found 
     jean: in what is Bob Dover interested?
     narvabot: (t) : ([http://www.w3.org/Metadata/]);(t) : ([http://python.org/])

:use-recipe: active-commands.kb-rdql-query


asking for FOAF information
~~~~~~~~~~~~~~~~~~~~~~~~~~~

Asking the FOAFbot for information. This would mean that we would set
up the redland framework and wrap the existing bot to appear as a
narval. since the FOAFbot alread knows FOAF and RDF Query language we
can leverage that

:???: !!!


  
add Bulk FOAF information
~~~~~~~~~~~~~~~~~~~~~~~~~

Use the FOAFbot to add bulk information. This would mean that a
foaf.rdf document would need to be constructed and then inform the
FOAFbot of the link so that it can be read by and consumed by the bot.

:???: !!!


add incremental FOAF information
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Use the FOAFbot to add incremental information. This would mean using
(subject, predicate, object) triples to add information to the FOAF
redland framework.

:???: !!!


generate FOAF file via dialog
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Have an agent ask its user about missing information to generate a
simple FOAF file and/or Observe forum discussion and if user talks
with someone a lot, offer to add that person as a foaf:knows.

The vocabulary should be parsed allowing the dialog presented to the
user to not be tightly coupled to the RDFS vocabulary. This loose
coupling would allow new schema and other templates to be used to
proactively receive input from the user.

Test ::
     
     DIALOG(jean, narvabot)

     jean: new foaf jean_foaf_test
     narvabot: add a new foaf:Person ?
     jean: yes
     narvabot: rdf:about for foaf:Person :
     jean: me
     narvabot: foaf:name for foaf:Person :
     jean: Jean Dupont
     narvabot: rdf:resource for foaf:Person/foaf:mbox :
     jean: jean@dupont.org
     narvabot: foaf:nick for foaf:Person :
     jean: jean
     narvabot: rdf:resource for foaf:Person/foaf:homepage :
     jean: http://www.dupont.org
     narvabot: add a new foaf:interest to foaf:Person ?
     jean: yes
     narvabot: rdf:resource for foaf:Person/foaf:interest :
     jean: python
     narvabot: add a new foaf:interest to foaf:Person ?
     jean: yes
     narvabot: rdf:resource for foaf:Person/foaf:interest :
     jean: agents
     narvabot: add a new foaf:interest to foaf:Person ?
     jean: no
     narvabot: add a new foaf:currentProject to foaf:Person ?
     jean: no
     narvabot: add a new foaf:knows to foaf:Person ?
     jean: yes
     narvabot: rdf:resource for foaf:Person/foaf:knows :
     jean: John Doe
     narvabot: add a new foaf:knows to foaf:Person ?
     jean: no
     narvabot: add a new foaf:Person ?
     jean: no
     narvabot:{re} process completed, file written to .*/data/jean_foaf_test


:see: `fill some data into a xml file, governed by a template`_


export FOAF related data from the knowledge base
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:use-recipe: active-commands.kb-foaf-export

  
import some FOAF data to the knowledge base
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:use-recipe: active-commands.kb-foaf-import

  
agent-to-agent FOAF exchange
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

export the knowledge base's content as FOAF XML-RDF, formatted to be given to another agent
:use-recipe: active-commands.kb-foaf-extract
:use-recipe: active-commands.kb-foaf-export
:use-recipe: active-commands.kb-foaf-import



Metalog
-------

Metalog_ is a semantic web research tool that includes Pseudo Natural
Language pre-processing and insertion/querying of RDF triples.
Metalog was wrapped as a Narval component and can be used in place of the
other pseudo natural language and knowledge manipulation tools.

.. _Metalog: http://www.w3.org/RDF/Metalog/

noTest ::

     DIALOG(jean, narvabot)

     jean: metalog
     narvabot: switching personnalities
     jean: NARVAL represents "Narval" from "http://www.logilab.org/projects/".
     jean: IS represents "is" from "http://www.relationships.net/verbs".
     jean: NARVAL IS "agent platform".
     jean: NARVAL IS SOMETHING ?
     narvabot: NARVAL IS "agent platform"

Pluging-in Metalog contributed to proving the extensibility of the
platform, but Metalog in itself is not of very high quality in its
current version and tends to generate a lot of usage problems.

:use-recipe: active-commands.metalog-categorize



Entertainment
=============

agent queries imdb, allocine and xmltv
--------------------------------------

Once can ask its agent to query on-line databases about movies, theaters and TV shows.

XMLTV is a tool to query TV programs. IMDB is the Internet Movide
Database and Allocine is a french web site that knows everything about
movies and theaters.

Test ::

     DIALOG(jean,narvabot)

     jean: what nice movies are playing in my neighborhood ?
     narvabot: "I, Robots" is showing at 19:30 at Montparnasse.

:use-recipe: active-commands.entertainment




Time-sheets / activity reports
==============================

Notify daily activity
---------------------

This command is used to enter a daily ratio for an activity. An email is sent
when the sum of ratios of all activities reaches 1. Notification can use
positive or negative ratio, the agent will increment or decrement the existing
value (if existing). If the total ratio goes under 0, the activity is deleted.

:Syntax:

    ([+-]?\d/\d)\s+(.+)$
    ([+-]?\d([.,]\d\d?)?|[+-]?[.,]\d\d?)\s+(.+)$

:Example:

    1/2 narval
        assigns half of the working load of the day on the narval project
    +0.2 redaction
        assign 20% of the working load to an activity called redaction
    -0.1 narval
        decrement load on narval by 10%
    .4 meeting
        Fill daily load with 40% of the time spent in a reunion

Watch out

An email is sent as soon as the sum of all activities comes up to 1. All the
same, activities may still be notified and will generate other notification
mails as long as the sum remains over 1 Restriction

Restrictions weight on the ratio exclusively, meaning the user is free to use any name for his activity.

    * ratio must be parseable into a float (or an integer)
    * -1 <= ratio <= 1


Test ::

     DIALOG(jean,narvabot)

     jean: delete all activities
     narvabot: Activity report reset
     jean: 1/2 narval
     narvabot: you have only specified 0.50 of your daily activity, please complete (now or later today)
     jean: +0.2 redaction
     narvabot: you have only specified 0.70 of your daily activity, please complete (now or later today)
     jean: -0.1 narval
     narvabot: you have only specified 0.60 of your daily activity, please complete (now or later today)
     jean: .4 meeting
     narvabot: your daily activity report has been sent to hr@somedomain.com
     jean: -.2 redaction
     narvabot: activity deleted (ratio 0.00)
     jean: .2 narval
     narvabot: your daily activity report has been sent to hr@somedomain.com
     jean: 2.3 narval
     narvabot: ratio 2.30 out of range (-1 <= ratio <= 1)
     jean: -2 narval
     narvabot: ratio -2.00 out of range (-1 <= ratio <= 1)


wait for daily activity notification and generate daily report if the full day activity has been reported

:use-recipe: active-commands.activity-notify
:use-recipe: active-commands.activity-wait

Reset activity report
---------------------

Reset the current report of activity

:Syntax:

    RESET CURRENT ACTIVITY( REPORT)?
    (DELETE)|(FLUSH)( ALL)? ACTIVITIES
    FLUSH
    
:Example:

    flush
    reset current activity report
    delete all activities

Any of the above will delete all daily activities entered so far.


Watch out

The effect is this command is irreversible. All activities entered for this day will be removed

Test ::

     DIALOG(jean,narvabot)

     jean: delete all activities
     narvabot: Activity report reset
     jean: .5 narval
     narvabot: you have only specified 0.50 of your daily activity, please complete (now or later today)
     jean: flush
     narvabot: Activity report reset
     jean: .2 redaction
     narvabot: you have only specified 0.20 of your daily activity, please complete (now or later today)
     jean:  .4 meeting 
     narvabot: you have only specified 0.60 of your daily activity, please complete (now or later today)
     jean: delete all activities
     narvabot: Activity report reset
     jean: reset current activity report
     narvabot: Activity report reset
     jean: .1 narval
     narvabot: you have only specified 0.10 of your daily activity, please complete (now or later today)

:use-recipe: active-commands.activity-flush


Print activity report
---------------------

Print the current report of activity

:Syntax:

    WHAT ARE MY ACTIVITIES( SO FAR)?\?
    PRINT MY ACTIVITY REPORT
    ACTIVITIES    
    
:Example:

    activities
    print my activity report
    what are my activities

Any of the above will print the current report of activity for the current day.

Test ::

     DIALOG(jean,narvabot)

     jean: delete all activities
     narvabot: Activity report reset
     jean: .5 narval
     narvabot: you have only specified 0.50 of your daily activity, please complete (now or later today)
     jean: print my activity report
     narvabot:{re} activity report for .* 0.50 narval
     jean: .25 meeting
     narvabot: you have only specified 0.75 of your daily activity, please complete (now or later today)
     jean: activities
     narvabot:{re} activity report for .*0.50 narval.*0.25 meeting

:use-recipe: active-commands.activity-report

  
