-
Notifications
You must be signed in to change notification settings - Fork 18
/
watoolV2.py
executable file
·188 lines (154 loc) · 6.7 KB
/
watoolV2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# Copyright 2017-2018 IBM Corp. All Rights Reserved.
# See LICENSE for details.
#
# Author: Henrik Loeser
#
# Converse with your assistant based on IBM Watson Assistant service on IBM Cloud.
# See the README for documentation.
#
import json, argparse, importlib
from os.path import join, dirname
from ibm_watson import AssistantV2
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator
privcontext=None
assistantService=None
def loadAndInit(confFile=None):
# Credentials are read from a file
with open(confFile) as confFile:
config = json.load(confFile)
configWA = config['credentials']
global assistantService
# Initialize the Watson Assistant client, use API V2
if 'apikey' in configWA:
# Authentication via IAM
authenticator = IAMAuthenticator(configWA['apikey'])
assistantService = AssistantV2(
authenticator=authenticator,
version=configWA['versionV2'])
assistantService.set_service_url(configWA['url'])
else:
print('Expected apikey in credentials.')
exit
# Define parameters that we want to catch and some basic command help
def initParser(args=None):
parser = argparse.ArgumentParser(description='Watson Assistant tool',
prog='watoolV2.py',
usage='%(prog)s [-h | -dialog ] [options]')
parser.add_argument("-dialog",dest='dialog', action='store_true', help='have dialog')
parser.add_argument("-outputonly",dest='outputOnly', action='store_true', help='print dialog output only')
parser.add_argument("-id",dest='assistantID', help='Assistant ID')
parser.add_argument("-actionmodule",dest='actionModule', help='Module for client action handling')
parser.add_argument("-context",dest='context', help='context file')
parser.add_argument("-config",dest='confFile', default='config.json', help='configuration file')
return parser
# Start a dialog and converse with Watson
def converse(assistantID, outputOnly=None, contextFile=None):
contextFile="session_contextV2.json"
print ("Starting a conversation, stop by Ctrl+C or saying 'bye'")
print ("======================================================")
# Start with an empty context object
context={}
first=True
## Load conversation context on start or not?
contextStart = input("Start with empty context? (Y/n)\n")
if (contextStart == "n" or contextStart == "N"):
print ("loading old session context...")
with open(contextFile) as jsonFile:
context=json.load(jsonFile)
jsonFile.close()
# create a new session
response = assistantService.create_session(assistant_id=assistantID).get_result()
sessionID = response['session_id']
print('Session created!\n')
# Now loop to chat
while True:
# get some input
minput = input("\nPlease enter your input message:\n")
# if we catch a "bye" then exit after deleting the session
if (minput == "bye"):
response = assistantService.delete_session(
assistant_id=assistantID,
session_id=sessionID).get_result()
print('Session deleted. Bye...')
break
# Read the session context from file if we are not entering the loop
# for the first time
if not first:
try:
with open(contextFile) as jsonFile:
context=json.load(jsonFile)
except IOError:
# do nothing
print ("ignoring")
else:
jsonFile.close()
else:
first=False
# Process IBM Cloud Function credentials if present
if privcontext is not None:
context.update(privcontext)
# send the input to Watson Assistant
# Set alternate_intents to False for less output
resp=assistantService.message(assistant_id=assistantID,
session_id=sessionID,
input={'text': minput,
'options': {'alternate_intents': True, 'return_context': True, 'debug': True}}
).get_result()
#print(json.dumps(resp, indent=2))
# Save returned context for next round of conversation
if ('context' in resp):
context=resp['context']
respOutput=resp['output']
if ('actions' in respOutput and len(respOutput['actions']) and respOutput['actions'][0]['type']=='client'):
# Dump the returned answer
if not outputOnly:
print ("")
print ("Full response object of intermediate step:")
print ("------------------------------------------")
print(json.dumps(resp, indent=2))
if (hca is not None):
contextNew=hca.handleClientActions(context,respOutput['actions'], resp)
# call Watson Assistant with result from client action(s)
resp=assistantService.message(assistant_id=assistantID,
session_id=sessionID,
input={'text': minput,
'options': {'alternate_intents': True, 'return_context': True, 'debug': True}},
intents=respOutput['intents'],
context=contextNew).get_result()
context=resp['context']
respOutput=resp['output']
else:
print("\n\nplease use -actionmodule to define module to handle client actions")
break
# Dump the returned answer
if (outputOnly):
print ("Response:")
print(json.dumps(respOutput['generic'], indent=2))
else:
print ("")
print ("Full response object:")
print ("---------------------")
print(json.dumps(resp, indent=2))
# Persist the current context object to file.
with open(contextFile,'w') as jsonFile:
json.dump(context, jsonFile, indent=2)
jsonFile.close()
#
# Main program, for now just detect what function to call and invoke it
#
if __name__ == '__main__':
# Assume no module for client actions
hca=None
# initialize parser
parser = initParser()
parms = parser.parse_args()
# enable next line to print parameters
# print parms
# load configuration and initialize Watson
loadAndInit(confFile=parms.confFile)
if (parms.dialog and parms.assistantID):
if parms.actionModule:
hca=importlib.import_module(parms.actionModule)
converse(parms.assistantID, parms.outputOnly)
else:
parser.print_usage()