Skip to content

Commit d168a87

Browse files
committed
Merge pull request #53 from watson-developer-cloud/feature-29-conversationAbstraction
Feature 29 conversation abstraction
2 parents 6b40028 + 3f7cd7d commit d168a87

File tree

7 files changed

+1083
-0
lines changed

7 files changed

+1083
-0
lines changed

Config.json.enc

0 Bytes
Binary file not shown.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* Copyright 2015 IBM Corp. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
18+
using UnityEngine;
19+
using System.Collections;
20+
using IBM.Watson.DeveloperCloud.Services.Conversation.v1;
21+
22+
public class ExampleConversation : MonoBehaviour
23+
{
24+
private Conversation m_Conversation = new Conversation();
25+
private string m_WorkspaceID = "car_demo_1";
26+
private string m_Input = "Can you unlock the door?";
27+
28+
void Start () {
29+
Debug.Log("User: " + m_Input);
30+
m_Conversation.Message(m_WorkspaceID, m_Input, OnMessage);
31+
}
32+
33+
void OnMessage (DataModels.MessageResponse resp)
34+
{
35+
foreach(DataModels.MessageIntent mi in resp.intents)
36+
Debug.Log("intent: " + mi.intent + ", confidence: " + mi.confidence);
37+
38+
Debug.Log("response: " + resp.output.text);
39+
}
40+
}

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Use this SDK to build Watson-powered applications in Unity. It comes with a set
1616
* [Natural Language Classifier](#natural-language-classifier)
1717
* [Tone Analyzer](#tone-analyzer)
1818
* [Tradeoff Analytics](#tradeoff-analytics)
19+
* [Conversation](#conversation)
1920
* [Visual Recognition](#visual-recognition)
2021
* [Developing a basic application in one minute](#developing-a-basic-application-in-one-minute)
2122
* [Documentation](#documentation)
@@ -327,6 +328,29 @@ void Start () {
327328
}
328329
```
329330

331+
### Conversation
332+
<!-- conversation description here: Change link below -->
333+
334+
```cs
335+
private Conversation m_Conversation = new Conversation();
336+
private string m_WorkspaceID = "car_demo_1";
337+
private string m_Input = "Can you unlock the door?";
338+
339+
void Start () {
340+
Debug.Log("User: " + m_Input);
341+
m_Conversation.Message(m_WorkspaceID, m_Input, OnMessage);
342+
}
343+
344+
void OnMessage (DataModels.MessageResponse resp)
345+
{
346+
foreach(DataModels.MessageIntent mi in resp.intents)
347+
Debug.Log("intent: " + mi.intent + ", confidence: " + mi.confidence);
348+
349+
Debug.Log("response: " + resp.output.text);
350+
}
351+
```
352+
353+
330354
### Visual Recognition
331355
Use the [Visual Recognition][visual_recognition] service to classify an image against a default or custom trained classifier. In addition, the service can detect faces and text in an image.
332356

Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
/**
2+
* Copyright 2015 IBM Corp. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
18+
using System;
19+
using System.Text;
20+
using System.Collections.Generic;
21+
using FullSerializer;
22+
using MiniJSON;
23+
using IBM.Watson.DeveloperCloud.Utilities;
24+
using IBM.Watson.DeveloperCloud.Connection;
25+
using IBM.Watson.DeveloperCloud.Logging;
26+
27+
namespace IBM.Watson.DeveloperCloud.Services.Conversation.v1
28+
{
29+
/// <summary>
30+
/// This class wraps the Watson Conversation service.
31+
/// <a href="http://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/conversation.html">Conversation Service</a>
32+
/// </summary>
33+
public class Conversation : IWatsonService
34+
{
35+
#region Public Types
36+
/// <summary>
37+
/// The callback for GetWorkspaces().
38+
/// </summary>
39+
public delegate void OnGetWorkspaces(DataModels.Workspaces workspaces);
40+
/// <summary>
41+
/// The callback for Message().
42+
/// </summary>
43+
/// <param name="success"></param>
44+
public delegate void OnMessageCallback(bool success);
45+
/// <summary>
46+
/// The callback delegate for the Converse() function.
47+
/// </summary>
48+
/// <param name="resp">The response object to a call to Converse().</param>
49+
public delegate void OnMessage(DataModels.MessageResponse resp);
50+
51+
#endregion
52+
53+
#region Public Properties
54+
#endregion
55+
56+
#region Private Data
57+
private const string SERVICE_ID = "ConversationV1";
58+
private static fsSerializer sm_Serializer = new fsSerializer();
59+
#endregion
60+
61+
#region Workspaces
62+
/// <summary>
63+
/// Gets the available workspaces for the Conversation service
64+
/// </summary>
65+
/// <returns>Returns true if request has been sent.</returns>
66+
/// <param name="callback">Callback.</param>
67+
public bool GetWorkspaces(OnGetWorkspaces callback)
68+
{
69+
if(callback == null)
70+
throw new ArgumentNullException("callback");
71+
72+
RESTConnector connector = RESTConnector.GetConnector(SERVICE_ID, "/v2/rest/workspaces");
73+
if(connector == null)
74+
return false;
75+
76+
GetWorkspacesReq req = new GetWorkspacesReq();
77+
req.Callback = callback;
78+
req.OnResponse = OnGetWorkspacesResp;
79+
80+
return connector.Send(req);
81+
}
82+
83+
private class GetWorkspacesReq : RESTConnector.Request
84+
{
85+
public OnGetWorkspaces Callback { get; set; }
86+
}
87+
88+
private void OnGetWorkspacesResp(RESTConnector.Request req, RESTConnector.Response resp)
89+
{
90+
DataModels.Workspaces workspaces= new DataModels.Workspaces();
91+
if (resp.Success)
92+
{
93+
try
94+
{
95+
fsData data = null;
96+
fsResult r = fsJsonParser.Parse(Encoding.UTF8.GetString(resp.Data), out data);
97+
if (!r.Succeeded)
98+
throw new WatsonException(r.FormattedMessages);
99+
100+
object obj = workspaces;
101+
r = sm_Serializer.TryDeserialize(data, obj.GetType(), ref obj);
102+
if (!r.Succeeded)
103+
throw new WatsonException(r.FormattedMessages);
104+
}
105+
catch (Exception e)
106+
{
107+
Log.Error("Conversation", "GetWorkspaces Exception: {0}", e.ToString());
108+
resp.Success = false;
109+
}
110+
}
111+
112+
if (((GetWorkspacesReq)req).Callback != null)
113+
((GetWorkspacesReq)req).Callback(resp.Success ? workspaces : null);
114+
}
115+
#endregion
116+
117+
#region Message
118+
/// <summary>
119+
/// Message the specified workspaceId, input and callback.
120+
/// </summary>
121+
/// <param name="workspaceId">Workspace identifier.</param>
122+
/// <param name="input">Input.</param>
123+
/// <param name="callback">Callback.</param>
124+
public bool Message(string workspaceId, string input, OnMessage callback)
125+
{
126+
if(string.IsNullOrEmpty(workspaceId))
127+
throw new ArgumentNullException("workspaceId");
128+
if(string.IsNullOrEmpty(input))
129+
throw new ArgumentNullException("input");
130+
if(callback == null)
131+
throw new ArgumentNullException("callback");
132+
133+
RESTConnector connector = RESTConnector.GetConnector(SERVICE_ID, "/v2/rest/workspaces");
134+
if(connector == null)
135+
return false;
136+
137+
string reqJson = "{{\"input\": {{\"text\": \"{0}\"}}}}";
138+
string reqString = string.Format(reqJson, input);
139+
140+
MessageReq req = new MessageReq();
141+
req.Callback = callback;
142+
req.Headers["Content-Type"] = "application/json";
143+
req.Function = "/" + workspaceId + "/message";
144+
req.Send = Encoding.UTF8.GetBytes(reqString);
145+
req.OnResponse = MessageResp;
146+
147+
return connector.Send(req);
148+
}
149+
150+
private class MessageReq : RESTConnector.Request
151+
{
152+
public OnMessage Callback { get; set; }
153+
}
154+
155+
private void MessageResp(RESTConnector.Request req, RESTConnector.Response resp)
156+
{
157+
DataModels.MessageResponse response = new DataModels.MessageResponse();
158+
if (resp.Success)
159+
{
160+
try
161+
{
162+
fsData data = null;
163+
fsResult r = fsJsonParser.Parse(Encoding.UTF8.GetString(resp.Data), out data);
164+
if (!r.Succeeded)
165+
throw new WatsonException(r.FormattedMessages);
166+
167+
object obj = response;
168+
r = sm_Serializer.TryDeserialize(data, obj.GetType(), ref obj);
169+
if (!r.Succeeded)
170+
throw new WatsonException(r.FormattedMessages);
171+
}
172+
catch (Exception e)
173+
{
174+
Log.Error("Conversation", "MessageResp Exception: {0}", e.ToString());
175+
resp.Success = false;
176+
}
177+
}
178+
179+
if (((MessageReq)req).Callback != null)
180+
((MessageReq)req).Callback(resp.Success ? response : null);
181+
}
182+
#endregion
183+
184+
#region Intents
185+
#endregion
186+
187+
#region Entities
188+
#endregion
189+
190+
#region Dialog Nodes
191+
#endregion
192+
193+
#region IWatsonService implementation
194+
195+
public string GetServiceID()
196+
{
197+
return SERVICE_ID;
198+
}
199+
200+
public void GetServiceStatus(ServiceStatus callback)
201+
{
202+
if (Config.Instance.FindCredentials(SERVICE_ID) != null)
203+
new CheckServiceStatus(this, callback);
204+
else
205+
{
206+
if (callback != null && callback.Target != null)
207+
{
208+
callback(SERVICE_ID, false);
209+
}
210+
}
211+
}
212+
213+
private class CheckServiceStatus
214+
{
215+
private Conversation m_Service = null;
216+
private ServiceStatus m_Callback = null;
217+
private int m_ConversationCount = 0;
218+
219+
public CheckServiceStatus(Conversation service, ServiceStatus callback)
220+
{
221+
m_Service = service;
222+
m_Callback = callback;
223+
224+
string customServiceID = Config.Instance.GetVariableValue(SERVICE_ID + "_ID");
225+
226+
//If custom classifierID is defined then we are using it to check the service health
227+
if (!string.IsNullOrEmpty(customServiceID))
228+
{
229+
230+
if (!m_Service.Message(customServiceID, "Hello", OnMessage))
231+
OnFailure("Failed to invoke Converse().");
232+
else
233+
m_ConversationCount += 1;
234+
}
235+
else
236+
{
237+
if (!m_Service.GetWorkspaces(OnGetWorkspaces))
238+
OnFailure("Failed to invoke GetDialogs().");
239+
}
240+
}
241+
242+
private void OnGetWorkspaces(DataModels.Workspaces workspaces)
243+
{
244+
if (m_Callback != null)
245+
{
246+
foreach (DataModels.Workspace workspace in workspaces.workspaces)
247+
{
248+
if (!m_Service.Message(workspace.workspace_id, "Hello", OnMessage))
249+
OnFailure("Failed to invoke Message().");
250+
else
251+
m_ConversationCount += 1;
252+
}
253+
}
254+
else
255+
OnFailure("GetMessages() failed.");
256+
}
257+
258+
private void OnMessage(DataModels.MessageResponse resp)
259+
{
260+
if (m_ConversationCount > 0)
261+
{
262+
m_ConversationCount -= 1;
263+
if (resp != null)
264+
{
265+
if (m_ConversationCount == 0 && m_Callback != null && m_Callback.Target != null)
266+
m_Callback(SERVICE_ID, true);
267+
}
268+
else
269+
OnFailure("ConverseResponse is null.");
270+
}
271+
}
272+
273+
private void OnFailure(string msg)
274+
{
275+
Log.Error("Dialog", msg);
276+
m_Callback(SERVICE_ID, false);
277+
m_ConversationCount = 0;
278+
}
279+
};
280+
#endregion
281+
}
282+
}

0 commit comments

Comments
 (0)