oomi-ai 0.2.50 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +224 -507
- package/agent_instructions.md +264 -253
- package/bin/oomi-ai.js +4036 -5791
- package/bin/sessionBridgeState.js +78 -78
- package/lib/openclawPaths.js +70 -71
- package/lib/openclawProfile.js +216 -216
- package/lib/personaApiClient.js +142 -303
- package/lib/spokenMetadata.js +137 -137
- package/openclaw.extension.js +341 -341
- package/openclaw.plugin.json +17 -17
- package/package.json +59 -59
- package/persona-app/README.md +33 -0
- package/persona-app/registry/v1.json +85 -0
- package/persona-app/schema/persona-app.v1.schema.json +90 -0
- package/skills/oomi/SKILL.md +182 -182
- package/skills/oomi/agent_instructions.md +117 -80
- package/lib/channelPluginClient.js +0 -119
- package/lib/openclawDevGateway.js +0 -384
- package/lib/personaJobExecutor.js +0 -139
- package/lib/personaJobPoller.js +0 -112
- package/lib/personaPortAllocator.js +0 -36
- package/lib/personaRuntimeManager.js +0 -496
- package/lib/personaRuntimeProcess.js +0 -924
- package/lib/personaRuntimeRegistry.js +0 -67
- package/lib/personaRuntimeSupervisor.js +0 -330
- package/lib/scaffold.js +0 -108
- package/lib/template.js +0 -45
- package/skills/oomi/config.json +0 -3
- package/skills/oomi/scripts/get_avatar_capabilities.py +0 -40
- package/skills/oomi/scripts/get_data.py +0 -49
- package/skills/oomi/scripts/install_agent_instructions.py +0 -78
- package/skills/oomi/scripts/send_goal.py +0 -53
- package/skills/oomi/scripts/sync.py +0 -46
- package/skills/oomi/setup.py +0 -41
- package/templates/persona-app/.env.example +0 -8
- package/templates/persona-app/README.md +0 -58
- package/templates/persona-app/eslint.config.js +0 -28
- package/templates/persona-app/index.html +0 -18
- package/templates/persona-app/oomi.runtime.json +0 -13
- package/templates/persona-app/package.json +0 -44
- package/templates/persona-app/persona/brief.md +0 -14
- package/templates/persona-app/persona.json +0 -14
- package/templates/persona-app/public/manifest.webmanifest +0 -8
- package/templates/persona-app/public/oomi.health.json +0 -6
- package/templates/persona-app/src/App.css +0 -379
- package/templates/persona-app/src/App.tsx +0 -17
- package/templates/persona-app/src/index.css +0 -53
- package/templates/persona-app/src/main.tsx +0 -23
- package/templates/persona-app/src/pages/HomePage.tsx +0 -127
- package/templates/persona-app/src/pages/ScenePage.tsx +0 -158
- package/templates/persona-app/src/persona/config.ts +0 -6
- package/templates/persona-app/src/persona/notes.ts +0 -10
- package/templates/persona-app/src/spatial.ts +0 -82
- package/templates/persona-app/src/vite-env.d.ts +0 -3
- package/templates/persona-app/template.json +0 -13
- package/templates/persona-app/tsconfig.app.json +0 -23
- package/templates/persona-app/tsconfig.json +0 -7
- package/templates/persona-app/tsconfig.node.json +0 -21
- package/templates/persona-app/vendor/webspatial/FORK.md +0 -6
- package/templates/persona-app/vendor/webspatial/core-sdk/LICENSE +0 -21
- package/templates/persona-app/vendor/webspatial/core-sdk/dist/iife/index.d.ts +0 -906
- package/templates/persona-app/vendor/webspatial/core-sdk/dist/iife/index.global.js +0 -75
- package/templates/persona-app/vendor/webspatial/core-sdk/dist/iife/index.global.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/core-sdk/dist/index.d.ts +0 -906
- package/templates/persona-app/vendor/webspatial/core-sdk/dist/index.js +0 -3131
- package/templates/persona-app/vendor/webspatial/core-sdk/dist/index.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/core-sdk/package.json +0 -45
- package/templates/persona-app/vendor/webspatial/react-sdk/LICENSE +0 -21
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/default/index.d.ts +0 -365
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/default/index.js +0 -4167
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/default/index.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.d.ts +0 -82
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.js +0 -66
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.web.d.ts +0 -2
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.web.js +0 -18
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.web.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.d.ts +0 -5
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.js +0 -66
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.web.d.ts +0 -1
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.web.js +0 -18
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.web.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/web/index.d.ts +0 -365
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/web/index.js +0 -4207
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/web/index.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/react-sdk/package.json +0 -94
- package/templates/persona-app/vite.config.ts +0 -31
package/lib/personaApiClient.js
CHANGED
|
@@ -1,313 +1,152 @@
|
|
|
1
|
-
function trimString(value) {
|
|
2
|
-
return typeof value === 'string' ? value.trim() : '';
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
function stripTrailingSlash(value) {
|
|
6
|
-
return trimString(value).replace(/\/+$/, '');
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
async function readJsonResponse(response) {
|
|
10
|
-
return response.json().catch(() => ({}));
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
async function getJson({ fetchImpl, backendUrl, path, deviceToken }) {
|
|
14
|
-
const baseUrl = stripTrailingSlash(backendUrl);
|
|
15
|
-
if (!baseUrl) {
|
|
16
|
-
throw new Error('Backend URL is required.');
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const headers = {};
|
|
20
|
-
const token = trimString(deviceToken);
|
|
21
|
-
if (token) {
|
|
22
|
-
headers.Authorization = `Bearer ${token}`;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const response = await fetchImpl(`${baseUrl}${path}`, {
|
|
26
|
-
method: 'GET',
|
|
27
|
-
headers,
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
const payload = await readJsonResponse(response);
|
|
31
|
-
if (!response.ok) {
|
|
32
|
-
const errorMessage =
|
|
33
|
-
trimString(payload?.error) ||
|
|
34
|
-
trimString(payload?.message) ||
|
|
35
|
-
`Persona API request failed (${response.status})`;
|
|
36
|
-
const error = new Error(errorMessage);
|
|
37
|
-
error.status = response.status;
|
|
38
|
-
error.payload = payload;
|
|
39
|
-
throw error;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return payload;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
async function postJson({ fetchImpl, backendUrl, path, deviceToken, body }) {
|
|
46
|
-
const baseUrl = stripTrailingSlash(backendUrl);
|
|
47
|
-
if (!baseUrl) {
|
|
48
|
-
throw new Error('Backend URL is required.');
|
|
49
|
-
}
|
|
50
|
-
const token = trimString(deviceToken);
|
|
51
|
-
if (!token) {
|
|
52
|
-
throw new Error('Device token is required.');
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const response = await fetchImpl(`${baseUrl}${path}`, {
|
|
56
|
-
method: 'POST',
|
|
57
|
-
headers: {
|
|
58
|
-
'Content-Type': 'application/json',
|
|
59
|
-
Authorization: `Bearer ${token}`,
|
|
60
|
-
},
|
|
61
|
-
body: JSON.stringify(body),
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
const payload = await readJsonResponse(response);
|
|
65
|
-
if (!response.ok) {
|
|
66
|
-
const errorMessage =
|
|
67
|
-
trimString(payload?.error) ||
|
|
68
|
-
trimString(payload?.message) ||
|
|
69
|
-
`Persona API request failed (${response.status})`;
|
|
70
|
-
const error = new Error(errorMessage);
|
|
71
|
-
error.status = response.status;
|
|
72
|
-
error.payload = payload;
|
|
73
|
-
throw error;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return payload;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export function createPersonaApiClient({
|
|
80
|
-
backendUrl,
|
|
81
|
-
deviceToken,
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
const resolvedDeviceId = trimString(deviceId);
|
|
92
|
-
|
|
93
|
-
function withDevice(body = {}) {
|
|
94
|
-
if (!resolvedDeviceId) {
|
|
95
|
-
return body;
|
|
96
|
-
}
|
|
97
|
-
return {
|
|
98
|
-
...body,
|
|
99
|
-
deviceId: resolvedDeviceId,
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
|
|
1
|
+
function trimString(value) {
|
|
2
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
function stripTrailingSlash(value) {
|
|
6
|
+
return trimString(value).replace(/\/+$/, '');
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
async function readJsonResponse(response) {
|
|
10
|
+
return response.json().catch(() => ({}));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async function getJson({ fetchImpl, backendUrl, path, deviceToken }) {
|
|
14
|
+
const baseUrl = stripTrailingSlash(backendUrl);
|
|
15
|
+
if (!baseUrl) {
|
|
16
|
+
throw new Error('Backend URL is required.');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const headers = {};
|
|
20
|
+
const token = trimString(deviceToken);
|
|
21
|
+
if (token) {
|
|
22
|
+
headers.Authorization = `Bearer ${token}`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const response = await fetchImpl(`${baseUrl}${path}`, {
|
|
26
|
+
method: 'GET',
|
|
27
|
+
headers,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const payload = await readJsonResponse(response);
|
|
31
|
+
if (!response.ok) {
|
|
32
|
+
const errorMessage =
|
|
33
|
+
trimString(payload?.error) ||
|
|
34
|
+
trimString(payload?.message) ||
|
|
35
|
+
`Persona API request failed (${response.status})`;
|
|
36
|
+
const error = new Error(errorMessage);
|
|
37
|
+
error.status = response.status;
|
|
38
|
+
error.payload = payload;
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return payload;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function postJson({ fetchImpl, backendUrl, path, deviceToken, body }) {
|
|
46
|
+
const baseUrl = stripTrailingSlash(backendUrl);
|
|
47
|
+
if (!baseUrl) {
|
|
48
|
+
throw new Error('Backend URL is required.');
|
|
49
|
+
}
|
|
50
|
+
const token = trimString(deviceToken);
|
|
51
|
+
if (!token) {
|
|
52
|
+
throw new Error('Device token is required.');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const response = await fetchImpl(`${baseUrl}${path}`, {
|
|
56
|
+
method: 'POST',
|
|
57
|
+
headers: {
|
|
58
|
+
'Content-Type': 'application/json',
|
|
59
|
+
Authorization: `Bearer ${token}`,
|
|
60
|
+
},
|
|
61
|
+
body: JSON.stringify(body),
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const payload = await readJsonResponse(response);
|
|
65
|
+
if (!response.ok) {
|
|
66
|
+
const errorMessage =
|
|
67
|
+
trimString(payload?.error) ||
|
|
68
|
+
trimString(payload?.message) ||
|
|
69
|
+
`Persona API request failed (${response.status})`;
|
|
70
|
+
const error = new Error(errorMessage);
|
|
71
|
+
error.status = response.status;
|
|
72
|
+
error.payload = payload;
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return payload;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function createPersonaApiClient({
|
|
80
|
+
backendUrl,
|
|
81
|
+
deviceToken,
|
|
82
|
+
fetchImpl = globalThis.fetch,
|
|
83
|
+
}) {
|
|
84
|
+
if (typeof fetchImpl !== 'function') {
|
|
85
|
+
throw new Error('fetch implementation is required.');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const resolvedBackendUrl = stripTrailingSlash(backendUrl);
|
|
89
|
+
const resolvedDeviceToken = trimString(deviceToken);
|
|
90
|
+
|
|
103
91
|
return {
|
|
104
|
-
|
|
92
|
+
listPersonaApps() {
|
|
93
|
+
return getJson({
|
|
94
|
+
fetchImpl,
|
|
95
|
+
backendUrl: resolvedBackendUrl,
|
|
96
|
+
deviceToken: resolvedDeviceToken,
|
|
97
|
+
path: '/v1/persona_apps',
|
|
98
|
+
});
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
getPersonaApp({
|
|
102
|
+
slug,
|
|
103
|
+
}) {
|
|
104
|
+
const safeSlug = trimString(slug);
|
|
105
|
+
if (!safeSlug) {
|
|
106
|
+
throw new Error('Persona app slug is required.');
|
|
107
|
+
}
|
|
108
|
+
|
|
105
109
|
return getJson({
|
|
106
110
|
fetchImpl,
|
|
107
111
|
backendUrl: resolvedBackendUrl,
|
|
108
112
|
deviceToken: resolvedDeviceToken,
|
|
109
|
-
path:
|
|
113
|
+
path: `/v1/persona_apps/${encodeURIComponent(safeSlug)}`,
|
|
110
114
|
});
|
|
111
115
|
},
|
|
112
116
|
|
|
113
|
-
|
|
117
|
+
applyPersonaAppAction({
|
|
114
118
|
slug,
|
|
119
|
+
actionId,
|
|
120
|
+
payload = {},
|
|
115
121
|
}) {
|
|
116
|
-
const safeSlug = trimString(slug);
|
|
117
|
-
if (!safeSlug) {
|
|
118
|
-
throw new Error('Persona slug is required.');
|
|
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
|
-
const safeSlug = trimString(slug);
|
|
148
|
-
if (safeSlug) {
|
|
149
|
-
body.slug = safeSlug;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return postJson({
|
|
153
|
-
fetchImpl,
|
|
154
|
-
backendUrl: resolvedBackendUrl,
|
|
155
|
-
deviceToken: resolvedDeviceToken,
|
|
156
|
-
path: '/v1/personas/managed_create',
|
|
157
|
-
body,
|
|
158
|
-
});
|
|
159
|
-
},
|
|
160
|
-
|
|
161
|
-
registerRuntime({
|
|
162
|
-
slug,
|
|
163
|
-
endpoint,
|
|
164
|
-
healthcheckUrl,
|
|
165
|
-
transport = 'local',
|
|
166
|
-
localPort,
|
|
167
|
-
startedAt,
|
|
168
|
-
}) {
|
|
169
|
-
const safeSlug = trimString(slug);
|
|
170
|
-
if (!safeSlug) {
|
|
171
|
-
throw new Error('Persona slug is required.');
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
return postJson({
|
|
175
|
-
fetchImpl,
|
|
176
|
-
backendUrl: resolvedBackendUrl,
|
|
177
|
-
deviceToken: resolvedDeviceToken,
|
|
178
|
-
path: `/v1/personas/${encodeURIComponent(safeSlug)}/runtime_register`,
|
|
179
|
-
body: withDevice({
|
|
180
|
-
endpoint,
|
|
181
|
-
healthcheckUrl,
|
|
182
|
-
transport,
|
|
183
|
-
localPort,
|
|
184
|
-
startedAt,
|
|
185
|
-
}),
|
|
186
|
-
});
|
|
187
|
-
},
|
|
188
|
-
|
|
189
|
-
heartbeatRuntime({
|
|
190
|
-
slug,
|
|
191
|
-
endpoint,
|
|
192
|
-
healthcheckUrl,
|
|
193
|
-
transport = 'local',
|
|
194
|
-
localPort,
|
|
195
|
-
observedAt,
|
|
196
|
-
}) {
|
|
197
|
-
const safeSlug = trimString(slug);
|
|
198
|
-
if (!safeSlug) {
|
|
199
|
-
throw new Error('Persona slug is required.');
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
return postJson({
|
|
203
|
-
fetchImpl,
|
|
204
|
-
backendUrl: resolvedBackendUrl,
|
|
205
|
-
deviceToken: resolvedDeviceToken,
|
|
206
|
-
path: `/v1/personas/${encodeURIComponent(safeSlug)}/heartbeat`,
|
|
207
|
-
body: withDevice({
|
|
208
|
-
endpoint,
|
|
209
|
-
healthcheckUrl,
|
|
210
|
-
transport,
|
|
211
|
-
localPort,
|
|
212
|
-
observedAt,
|
|
213
|
-
}),
|
|
214
|
-
});
|
|
215
|
-
},
|
|
216
|
-
|
|
217
|
-
failRuntime({
|
|
218
|
-
slug,
|
|
219
|
-
code,
|
|
220
|
-
message,
|
|
221
|
-
}) {
|
|
222
|
-
const safeSlug = trimString(slug);
|
|
223
|
-
if (!safeSlug) {
|
|
224
|
-
throw new Error('Persona slug is required.');
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
return postJson({
|
|
228
|
-
fetchImpl,
|
|
229
|
-
backendUrl: resolvedBackendUrl,
|
|
230
|
-
deviceToken: resolvedDeviceToken,
|
|
231
|
-
path: `/v1/personas/${encodeURIComponent(safeSlug)}/fail`,
|
|
232
|
-
body: withDevice({
|
|
233
|
-
code,
|
|
234
|
-
message,
|
|
235
|
-
}),
|
|
236
|
-
});
|
|
237
|
-
},
|
|
238
|
-
|
|
239
|
-
startJob({
|
|
240
|
-
jobId,
|
|
241
|
-
startedAt,
|
|
242
|
-
}) {
|
|
243
|
-
const safeJobId = trimString(jobId);
|
|
244
|
-
if (!safeJobId) {
|
|
245
|
-
throw new Error('Persona job id is required.');
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
return postJson({
|
|
249
|
-
fetchImpl,
|
|
250
|
-
backendUrl: resolvedBackendUrl,
|
|
251
|
-
deviceToken: resolvedDeviceToken,
|
|
252
|
-
path: `/v1/persona_jobs/${encodeURIComponent(safeJobId)}/start`,
|
|
253
|
-
body: withDevice({
|
|
254
|
-
startedAt,
|
|
255
|
-
}),
|
|
256
|
-
});
|
|
257
|
-
},
|
|
258
|
-
|
|
259
|
-
succeedJob({
|
|
260
|
-
jobId,
|
|
261
|
-
workspacePath,
|
|
262
|
-
localPort,
|
|
263
|
-
transport = 'local',
|
|
264
|
-
endpoint,
|
|
265
|
-
healthcheckUrl,
|
|
266
|
-
completedAt,
|
|
267
|
-
}) {
|
|
268
|
-
const safeJobId = trimString(jobId);
|
|
269
|
-
if (!safeJobId) {
|
|
270
|
-
throw new Error('Persona job id is required.');
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
return postJson({
|
|
274
|
-
fetchImpl,
|
|
275
|
-
backendUrl: resolvedBackendUrl,
|
|
276
|
-
deviceToken: resolvedDeviceToken,
|
|
277
|
-
path: `/v1/persona_jobs/${encodeURIComponent(safeJobId)}/succeed`,
|
|
278
|
-
body: withDevice({
|
|
279
|
-
workspacePath,
|
|
280
|
-
localPort,
|
|
281
|
-
transport,
|
|
282
|
-
endpoint,
|
|
283
|
-
healthcheckUrl,
|
|
284
|
-
completedAt,
|
|
285
|
-
}),
|
|
286
|
-
});
|
|
287
|
-
},
|
|
288
|
-
|
|
289
|
-
failJob({
|
|
290
|
-
jobId,
|
|
291
|
-
code,
|
|
292
|
-
message,
|
|
293
|
-
completedAt,
|
|
294
|
-
}) {
|
|
295
|
-
const safeJobId = trimString(jobId);
|
|
296
|
-
if (!safeJobId) {
|
|
297
|
-
throw new Error('Persona job id is required.');
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
return postJson({
|
|
301
|
-
fetchImpl,
|
|
302
|
-
backendUrl: resolvedBackendUrl,
|
|
303
|
-
deviceToken: resolvedDeviceToken,
|
|
304
|
-
path: `/v1/persona_jobs/${encodeURIComponent(safeJobId)}/fail`,
|
|
305
|
-
body: withDevice({
|
|
306
|
-
code,
|
|
307
|
-
message,
|
|
308
|
-
completedAt,
|
|
309
|
-
}),
|
|
310
|
-
});
|
|
311
|
-
},
|
|
312
|
-
};
|
|
313
|
-
}
|
|
122
|
+
const safeSlug = trimString(slug);
|
|
123
|
+
if (!safeSlug) {
|
|
124
|
+
throw new Error('Persona app slug is required.');
|
|
125
|
+
}
|
|
126
|
+
const safeActionId = trimString(actionId);
|
|
127
|
+
if (!safeActionId) {
|
|
128
|
+
throw new Error('Persona app action id is required.');
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return postJson({
|
|
132
|
+
fetchImpl,
|
|
133
|
+
backendUrl: resolvedBackendUrl,
|
|
134
|
+
deviceToken: resolvedDeviceToken,
|
|
135
|
+
path: `/v1/persona_apps/${encodeURIComponent(safeSlug)}/actions`,
|
|
136
|
+
body: {
|
|
137
|
+
actionId: safeActionId,
|
|
138
|
+
payload: payload && typeof payload === 'object' ? payload : {},
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
getHealthContext() {
|
|
144
|
+
return getJson({
|
|
145
|
+
fetchImpl,
|
|
146
|
+
backendUrl: resolvedBackendUrl,
|
|
147
|
+
deviceToken: resolvedDeviceToken,
|
|
148
|
+
path: '/v1/context/health',
|
|
149
|
+
});
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
}
|