@convai/embody 0.4.1 → 0.4.2
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/CHANGELOG.md +26 -0
- package/README.md +59 -7
- package/dist/react/useCharacter.d.ts +6 -0
- package/dist/react/useCharacter.js +16 -4
- package/dist/resolve/resolver.d.ts +1 -1
- package/dist/resolve/resolver.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @convai/embody
|
|
2
2
|
|
|
3
|
+
## 0.4.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 532c49e: Swapping the body under a fixed character id now reaches the screen.
|
|
8
|
+
|
|
9
|
+
`useCharacter` rebuilt the character only when the character id, credentials
|
|
10
|
+
or base url changed. The **resolver** was not among them, and the effect read
|
|
11
|
+
its options from a ref — so an authoring tool that holds one avatar id and
|
|
12
|
+
swaps the block underneath (preview release 3, then release 4) got nothing:
|
|
13
|
+
the old GLB stayed on the canvas and it read as a stubborn cache. Nothing was
|
|
14
|
+
cached. The loader was never asked for the new url.
|
|
15
|
+
|
|
16
|
+
The resolver decides WHICH body a character id resolves to, so it belongs in
|
|
17
|
+
the rebuild set, and now is.
|
|
18
|
+
|
|
19
|
+
This makes the resolver's identity part of the contract: **memoize it**, and
|
|
20
|
+
change it exactly when the body should change. A resolver rebuilt inline on
|
|
21
|
+
every render would rebuild the character on every render. The README's new
|
|
22
|
+
"Swapping the body under a fixed character id" section shows the shape.
|
|
23
|
+
|
|
24
|
+
Also documented, unchanged in behaviour: the `orbit` prop (shipped in 0.4.0
|
|
25
|
+
and previously absent from the README), which backend each npm tag talks to,
|
|
26
|
+
and the correct release-branch names — the table named three branches that do
|
|
27
|
+
not exist.
|
|
28
|
+
|
|
3
29
|
## 0.4.1
|
|
4
30
|
|
|
5
31
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**Give a Convai character a body.**
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/@convai/embody)
|
|
6
6
|
[](https://www.typescriptlang.org/)
|
|
7
7
|
[](./LICENSE)
|
|
8
8
|
|
|
@@ -12,13 +12,21 @@ lipsync, gaze, breathing and blink. Layered on
|
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
|
-
> **Branch: `
|
|
16
|
-
>
|
|
15
|
+
> **Branch: `main`** — this branch defaults to the production backend and
|
|
16
|
+
> publishes the `latest` tag. `stg` targets staging, which has its own
|
|
17
|
+
> character database.
|
|
17
18
|
>
|
|
18
19
|
> **Status: early release.** The front door — a credential plus a
|
|
19
20
|
> `characterId` — is settled; what is still moving is listed in
|
|
20
21
|
> [Roadmap](#roadmap).
|
|
21
22
|
|
|
23
|
+
> **Which backend a build talks to is fixed at publish time.** The `latest`
|
|
24
|
+
> and `beta` tags point at `https://api.convai.com`; the `stg` tag points at
|
|
25
|
+
> `https://api-stg.convai.com`. Character ids are per-environment and not
|
|
26
|
+
> interchangeable — a staging id against production returns *"Character not
|
|
27
|
+
> found or doesn't belong to user"*, which reads like a permissions problem
|
|
28
|
+
> and is a wrong-host one. Override with `baseUrl` only if you know why.
|
|
29
|
+
|
|
22
30
|
## Install
|
|
23
31
|
|
|
24
32
|
```bash
|
|
@@ -58,6 +66,32 @@ For anything user-facing, mint a short-lived auth token server-side and pass
|
|
|
58
66
|
<ConvaiCharacter token={token} characterId={characterId} />
|
|
59
67
|
```
|
|
60
68
|
|
|
69
|
+
### Moving the camera
|
|
70
|
+
|
|
71
|
+
Drag to turn the character, scroll to move in and out. On by default — a 3D
|
|
72
|
+
character you cannot walk around is a picture of one.
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
<ConvaiCharacter apiKey={apiKey} characterId={characterId} orbit={false} />
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Pass an object to tune the limits instead of turning it off:
|
|
79
|
+
|
|
80
|
+
```tsx
|
|
81
|
+
<ConvaiCharacter
|
|
82
|
+
apiKey={apiKey}
|
|
83
|
+
characterId={characterId}
|
|
84
|
+
orbit={{ maxDistance: 6, autoRotate: true, autoRotateSpeed: 0.8 }}
|
|
85
|
+
/>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`minDistance`, `maxDistance`, `minPolarAngle`, `maxPolarAngle`, `enablePan`,
|
|
89
|
+
`enableZoom`, `autoRotate`, `autoRotateSpeed`. The defaults are tuned for one
|
|
90
|
+
subject — a standing human — not for a general scene viewer: panning is off
|
|
91
|
+
because it only ever slides the character out of frame, and the vertical sweep
|
|
92
|
+
stops just below eye level because orbiting under the floor shows the inside
|
|
93
|
+
of a head.
|
|
94
|
+
|
|
61
95
|
### In a scene you already have
|
|
62
96
|
|
|
63
97
|
`ConvaiCharacter` brings its own canvas. When the character should join a
|
|
@@ -174,6 +208,24 @@ The defaults cover the normal case; each of these exists for a specific one.
|
|
|
174
208
|
| `baseUrl` | A different backend environment. Defaults per release channel. |
|
|
175
209
|
| `queue` on `update()` | One client driving several bodies, when you are deciding which owns the current turn. |
|
|
176
210
|
|
|
211
|
+
### Swapping the body under a fixed character id
|
|
212
|
+
|
|
213
|
+
`resolver` is how an authoring tool previews a body that is not published — or
|
|
214
|
+
not even saved. Its **identity is part of the rebuild contract**: memoize it,
|
|
215
|
+
and change it exactly when the body should change.
|
|
216
|
+
|
|
217
|
+
```tsx
|
|
218
|
+
const resolver = useMemo(
|
|
219
|
+
() => ({ async resolve() { return bundle } }),
|
|
220
|
+
[bundle],
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
<ConvaiCharacter characterId={avatarId} resolver={resolver} connect={false} />
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Changing the resolver rebuilds the character; keeping it stable does not. A
|
|
227
|
+
resolver rebuilt inline on every render would reload the GLB on every render.
|
|
228
|
+
|
|
177
229
|
## Docs
|
|
178
230
|
|
|
179
231
|
Design, plan and decision history live in [`docs/`](./docs):
|
|
@@ -194,9 +246,9 @@ The backend host is a source constant, `DEFAULT_BASE_URL` in
|
|
|
194
246
|
|
|
195
247
|
| Branch | Host | npm tag |
|
|
196
248
|
|---|---|---|
|
|
197
|
-
| `
|
|
198
|
-
| `beta
|
|
199
|
-
| `stg
|
|
249
|
+
| `main` / `prod` | `https://api.convai.com` | `latest` |
|
|
250
|
+
| `beta` | `https://api.convai.com` | `beta` |
|
|
251
|
+
| `stg` | `https://api-stg.convai.com` | `stg` |
|
|
200
252
|
|
|
201
253
|
Beta points at **production** — it is the first line of testing against real
|
|
202
254
|
infrastructure, not a staging channel. Only `stg-release` targets staging,
|
|
@@ -217,7 +269,7 @@ pnpm check:hosts # auto-detects the current branch
|
|
|
217
269
|
|
|
218
270
|
```bash
|
|
219
271
|
pnpm install
|
|
220
|
-
pnpm test #
|
|
272
|
+
pnpm test # 220 tests
|
|
221
273
|
pnpm typecheck
|
|
222
274
|
pnpm check:tests # every src/ module has a named test — see docs/testing-spec.md
|
|
223
275
|
pnpm build # emits dist/ with .d.ts
|
|
@@ -7,6 +7,12 @@ export interface UseCharacterOptions extends CreateCharacterOptions {
|
|
|
7
7
|
*/
|
|
8
8
|
queue?: BlendshapeQueue;
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* NOTE ON `resolver` (inherited from CreateCharacterOptions): its identity is
|
|
12
|
+
* part of this hook's dependency set. Memoize it, and change it precisely
|
|
13
|
+
* when the body should change — an inline `{ resolve() {...} }` is a new
|
|
14
|
+
* object every render and would rebuild the character every render.
|
|
15
|
+
*/
|
|
10
16
|
export interface UseCharacterResult {
|
|
11
17
|
character: CharacterHandle | null;
|
|
12
18
|
/**
|
|
@@ -35,11 +35,23 @@ export function useCharacter(opts) {
|
|
|
35
35
|
setError(null);
|
|
36
36
|
}, (c) => setCharacter(c), (e) => setError(e));
|
|
37
37
|
return () => lifecycle.cancel();
|
|
38
|
-
// Re-create when the identity of the character
|
|
39
|
-
//
|
|
40
|
-
//
|
|
38
|
+
// Re-create when the identity of the character, the credentials, OR the
|
|
39
|
+
// resolver change.
|
|
40
|
+
//
|
|
41
|
+
// The resolver belongs here because it decides WHICH BODY this character
|
|
42
|
+
// id resolves to. An authoring tool holds the character id fixed and
|
|
43
|
+
// swaps the block underneath — preview release 3, then release 4 — and
|
|
44
|
+
// without this dependency none of that reached the screen: the effect
|
|
45
|
+
// never re-ran, so the old GLB stayed on the canvas and the change looked
|
|
46
|
+
// like a stubborn cache. Nothing was cached; the loader was simply never
|
|
47
|
+
// asked for the new url.
|
|
48
|
+
//
|
|
49
|
+
// This makes the resolver's IDENTITY part of the contract: pass a stable
|
|
50
|
+
// one (`useMemo`) and change it exactly when the body should change. A
|
|
51
|
+
// resolver rebuilt inline on every render would rebuild the character on
|
|
52
|
+
// every render.
|
|
41
53
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
42
|
-
}, [opts.characterId, opts.apiKey, opts.authToken, opts.token, opts.baseUrl]);
|
|
54
|
+
}, [opts.characterId, opts.apiKey, opts.authToken, opts.token, opts.baseUrl, opts.resolver]);
|
|
43
55
|
useEffect(() => {
|
|
44
56
|
if (character)
|
|
45
57
|
character.camera = camera;
|
|
@@ -53,7 +53,7 @@ export interface CharacterResolver {
|
|
|
53
53
|
* not pass `baseUrl` to the wrong backend, which is why it is checked rather
|
|
54
54
|
* than trusted.
|
|
55
55
|
*/
|
|
56
|
-
export declare const DEFAULT_BASE_URL = "https://api
|
|
56
|
+
export declare const DEFAULT_BASE_URL = "https://api.convai.com";
|
|
57
57
|
export interface HttpResolverOptions {
|
|
58
58
|
/** Base url of the embodiment backend. Defaults to the release branch's host. */
|
|
59
59
|
baseUrl?: string;
|
package/dist/resolve/resolver.js
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* not pass `baseUrl` to the wrong backend, which is why it is checked rather
|
|
21
21
|
* than trusted.
|
|
22
22
|
*/
|
|
23
|
-
export const DEFAULT_BASE_URL = 'https://api
|
|
23
|
+
export const DEFAULT_BASE_URL = 'https://api.convai.com';
|
|
24
24
|
/** Shared so `createCharacter` and the resolver cannot drift apart. */
|
|
25
25
|
export const MISSING_CREDENTIAL = '@convai/embody: a credential is required — pass `token` (recommended for ' +
|
|
26
26
|
'browsers) or `apiKey`. There is no anonymous access to Convai.';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@convai/embody",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Give a Convai character a body: resolve 3D characters by characterId and drive them with lipsync and animation. Layered on @convai/web-sdk.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Convai <support@convai.com>",
|