@cef-ai/widget-runtime 2.2.1 → 2.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/dist/entry.js +9 -13
- package/dist/index.d.ts +1 -1
- package/dist/runtime.js +1 -1
- package/dist/types.d.ts +13 -1
- package/dist/vault-client.d.ts +22 -2
- package/dist/vault-client.js +46 -33
- package/dist/widget-runtime.js +77 -74
- package/package.json +2 -2
package/dist/entry.js
CHANGED
|
@@ -7,7 +7,7 @@ import { createCefWalletGate } from './cef-wallet.js';
|
|
|
7
7
|
import { autoSignIn } from './sign-in-ui.js';
|
|
8
8
|
import { currentLinkContext } from './share-link.js';
|
|
9
9
|
import { createIdentityResolver } from './resolve-identity.js';
|
|
10
|
-
import { createVaultClient } from './vault-client.js';
|
|
10
|
+
import { createVaultClient, openHostVault } from './vault-client.js';
|
|
11
11
|
import { toVaultSdkConfig } from './vault-sdk-config.js';
|
|
12
12
|
import { createWidgetRuntime } from './runtime.js';
|
|
13
13
|
import { captureAndUploadAudio, createVaultObjectUploader } from './audio/capture-upload.js';
|
|
@@ -155,19 +155,15 @@ function boot() {
|
|
|
155
155
|
const id = await resolveSigningIdentity();
|
|
156
156
|
const vaultSdkSigner = toVaultSdkSigner(id.publicKey, id.sigType, id.sign);
|
|
157
157
|
// Same delegation preference as the vault client: an upload that signs
|
|
158
|
-
// per chunk on a keyless session is a ceremony per chunk.
|
|
159
|
-
//
|
|
160
|
-
//
|
|
161
|
-
// the vault-delegate grant step too.
|
|
158
|
+
// per chunk on a keyless session is a ceremony per chunk. Same config
|
|
159
|
+
// builder too — in particular the same `chainUrl`, which the `ensure()`
|
|
160
|
+
// branch of `openHostVault` needs for its vault-delegate grant.
|
|
162
161
|
const sdk = new VaultSDK(toVaultSdkConfig(manifest.endpoints, vaultSdkSigner, id.token, id.renewToken));
|
|
163
|
-
//
|
|
164
|
-
//
|
|
165
|
-
//
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
...(id.token ? { delegationToken: id.token } : {}),
|
|
169
|
-
});
|
|
170
|
-
return createVaultObjectUploader({ objects: ensuredVault.scope(manifest.scope).objects });
|
|
162
|
+
// The same vault the reader opened: the job runs where the event was
|
|
163
|
+
// published, so audio uploaded anywhere else is a URL into a database
|
|
164
|
+
// the agent is not in.
|
|
165
|
+
const uploadVault = await openHostVault(sdk.vault, id.context?.vaultId, id.token);
|
|
166
|
+
return createVaultObjectUploader({ objects: uploadVault.scope(manifest.scope).objects });
|
|
171
167
|
})().catch((err) => { uploaderP = null; throw err; });
|
|
172
168
|
return uploaderP;
|
|
173
169
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { buildWidgetManifest, type BuildManifestInput } from './manifest.js';
|
|
2
2
|
export { injectWidgetBridge, type BridgeInput } from './bridge.js';
|
|
3
|
-
export type { WidgetManifest, WidgetRuntimeApi, Identity, QueryResult } from './types.js';
|
|
3
|
+
export type { WidgetManifest, WidgetRuntimeApi, Identity, QueryResult, PublishOptions } from './types.js';
|
|
4
4
|
export { AgentNotConnectedError } from './types.js';
|
|
5
5
|
export { validateConfig } from './validate-config.js';
|
|
6
6
|
export { mountKind } from './mount.js';
|
package/dist/runtime.js
CHANGED
|
@@ -37,7 +37,7 @@ export function createWidgetRuntime(manifest, deps) {
|
|
|
37
37
|
}
|
|
38
38
|
return {
|
|
39
39
|
async query(ref, params) { return (await ensureClient()).query(ref, params); },
|
|
40
|
-
async publish(type, payload, context) { return (await ensureClient()).publish(type, payload, context); },
|
|
40
|
+
async publish(type, payload, context, options) { return (await ensureClient()).publish(type, payload, context, options); },
|
|
41
41
|
async identity() {
|
|
42
42
|
await ensureClient();
|
|
43
43
|
return { publicKey, status, ...(context ? { context } : {}) };
|
package/dist/types.d.ts
CHANGED
|
@@ -108,9 +108,21 @@ export interface QueryResult {
|
|
|
108
108
|
rowCount: number;
|
|
109
109
|
};
|
|
110
110
|
}
|
|
111
|
+
export interface PublishOptions {
|
|
112
|
+
/** The one agent this event is for, `<asPubkey>:<name>`. */
|
|
113
|
+
target?: string;
|
|
114
|
+
}
|
|
111
115
|
export interface WidgetRuntimeApi {
|
|
112
116
|
query(ref: string, params?: unknown[]): Promise<QueryResult>;
|
|
113
|
-
|
|
117
|
+
/**
|
|
118
|
+
* Publish an event into the widget's scope.
|
|
119
|
+
*
|
|
120
|
+
* `target` addresses one agent (`<asPubkey>:<name>`). A workflow is started
|
|
121
|
+
* this way: its manifest handles the runner's fixed set (`workflow.start`,
|
|
122
|
+
* …), never the trigger's own event type, so an untargeted `workflow.start`
|
|
123
|
+
* would start every workflow connected in the scope.
|
|
124
|
+
*/
|
|
125
|
+
publish(type: string, payload: unknown, context?: string, options?: PublishOptions): Promise<{
|
|
114
126
|
eventId: string;
|
|
115
127
|
}>;
|
|
116
128
|
identity(): Promise<Identity>;
|
package/dist/vault-client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type QueryResult, type WidgetManifest } from './types.js';
|
|
1
|
+
import { type QueryResult, type WidgetManifest, type PublishOptions } from './types.js';
|
|
2
2
|
export interface VaultSdkLike {
|
|
3
3
|
vault: {
|
|
4
4
|
ensure: (opts?: {
|
|
@@ -41,6 +41,26 @@ export declare class WidgetVaultUnreachableError extends Error {
|
|
|
41
41
|
readonly reason: string;
|
|
42
42
|
constructor(vaultId: string, cause?: unknown);
|
|
43
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* THE VAULT A WIDGET WORKS IN — the one the host named, else the caller's.
|
|
46
|
+
*
|
|
47
|
+
* There is deliberately no third branch. A named vault that will not open is an
|
|
48
|
+
* error, never a quiet fall-through to `ensure()`: the fall-through is
|
|
49
|
+
* indistinguishable from an empty result, and being indistinguishable from an
|
|
50
|
+
* empty result is the bug.
|
|
51
|
+
*
|
|
52
|
+
* Shared by the reader and the audio uploader, which each used to decide this
|
|
53
|
+
* for themselves — and only one of them knew about `context.vaultId`.
|
|
54
|
+
*
|
|
55
|
+
* Generic so both `VaultLike` and the real vault-sdk handle fit without `any`.
|
|
56
|
+
*/
|
|
57
|
+
export declare function openHostVault<V>(vaultNs: {
|
|
58
|
+
ensure: (opts?: {
|
|
59
|
+
onboard?: boolean;
|
|
60
|
+
delegationToken?: string;
|
|
61
|
+
}) => Promise<V>;
|
|
62
|
+
byId?: (vaultId: string) => Promise<V>;
|
|
63
|
+
}, hostVaultId: string | undefined, hostToken?: string): Promise<V>;
|
|
44
64
|
interface VaultLike {
|
|
45
65
|
id: string;
|
|
46
66
|
agents: {
|
|
@@ -95,7 +115,7 @@ interface AgentHandleLike {
|
|
|
95
115
|
}
|
|
96
116
|
export interface VaultClient {
|
|
97
117
|
query(ref: string, params?: unknown[]): Promise<QueryResult>;
|
|
98
|
-
publish(type: string, payload: unknown, context?: string): Promise<{
|
|
118
|
+
publish(type: string, payload: unknown, context?: string, options?: PublishOptions): Promise<{
|
|
99
119
|
eventId: string;
|
|
100
120
|
}>;
|
|
101
121
|
connectAgent(): Promise<void>;
|
package/dist/vault-client.js
CHANGED
|
@@ -29,6 +29,41 @@ export class WidgetVaultUnreachableError extends Error {
|
|
|
29
29
|
this.reason = reason;
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* THE VAULT A WIDGET WORKS IN — the one the host named, else the caller's.
|
|
34
|
+
*
|
|
35
|
+
* There is deliberately no third branch. A named vault that will not open is an
|
|
36
|
+
* error, never a quiet fall-through to `ensure()`: the fall-through is
|
|
37
|
+
* indistinguishable from an empty result, and being indistinguishable from an
|
|
38
|
+
* empty result is the bug.
|
|
39
|
+
*
|
|
40
|
+
* Shared by the reader and the audio uploader, which each used to decide this
|
|
41
|
+
* for themselves — and only one of them knew about `context.vaultId`.
|
|
42
|
+
*
|
|
43
|
+
* Generic so both `VaultLike` and the real vault-sdk handle fit without `any`.
|
|
44
|
+
*/
|
|
45
|
+
export async function openHostVault(vaultNs, hostVaultId, hostToken) {
|
|
46
|
+
if (!hostVaultId) {
|
|
47
|
+
// `onboard: false` preserves the old lightweight ensure(): claim the vault
|
|
48
|
+
// with a wallet-built delegation token, skipping the gateway onboarding
|
|
49
|
+
// status/bootstrap round-trip (widgets assume a provisioned wallet).
|
|
50
|
+
return vaultNs.ensure({
|
|
51
|
+
onboard: false,
|
|
52
|
+
...(hostToken ? { delegationToken: hostToken } : {}),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (typeof vaultNs.byId !== 'function') {
|
|
56
|
+
throw new WidgetVaultUnreachableError(hostVaultId);
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
return await vaultNs.byId(hostVaultId);
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
// Not found, no access, network — all one answer to the reader: this is
|
|
63
|
+
// not your vault and nothing here can show you what is in it.
|
|
64
|
+
throw new WidgetVaultUnreachableError(hostVaultId, err);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
32
67
|
/**
|
|
33
68
|
* Normalise the raw result from cubbies.query into a uniform QueryResult.
|
|
34
69
|
* The platform returns `{columns: string[], rows: unknown[][]}` (positional).
|
|
@@ -90,37 +125,10 @@ hostVaultId) {
|
|
|
90
125
|
let sdk;
|
|
91
126
|
let vaultP;
|
|
92
127
|
const getSdk = () => (sdk ?? (sdk = makeSdk()));
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
* an error, never a quiet fall-through to `ensure()`: the fall-through is
|
|
98
|
-
* indistinguishable from an empty result, and being indistinguishable from an
|
|
99
|
-
* empty result is the bug.
|
|
100
|
-
*/
|
|
101
|
-
const openVault = async () => {
|
|
102
|
-
if (!hostVaultId) {
|
|
103
|
-
// `onboard: false` preserves the old lightweight ensure(): claim the vault
|
|
104
|
-
// with a wallet-built delegation token, skipping the gateway onboarding
|
|
105
|
-
// status/bootstrap round-trip (widgets assume a provisioned wallet).
|
|
106
|
-
return getSdk().vault.ensure({
|
|
107
|
-
onboard: false,
|
|
108
|
-
...(hostToken ? { delegationToken: hostToken } : {}),
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
const vaultNs = getSdk().vault;
|
|
112
|
-
if (typeof vaultNs.byId !== 'function') {
|
|
113
|
-
throw new WidgetVaultUnreachableError(hostVaultId);
|
|
114
|
-
}
|
|
115
|
-
try {
|
|
116
|
-
return await vaultNs.byId(hostVaultId);
|
|
117
|
-
}
|
|
118
|
-
catch (err) {
|
|
119
|
-
// Not found, no access, network — all one answer to the reader: this is
|
|
120
|
-
// not your vault and nothing here can show you what is in it.
|
|
121
|
-
throw new WidgetVaultUnreachableError(hostVaultId, err);
|
|
122
|
-
}
|
|
123
|
-
};
|
|
128
|
+
// `async` so a synchronous throw from `makeSdk()` lands as a rejected promise
|
|
129
|
+
// rather than in the caller's frame — `getVault()` is only ever awaited today,
|
|
130
|
+
// but the `vaultP` memo below assumes a promise either way.
|
|
131
|
+
const openVault = async () => openHostVault(getSdk().vault, hostVaultId, hostToken);
|
|
124
132
|
const getVault = () => {
|
|
125
133
|
vaultP ?? (vaultP = openVault().catch((err) => {
|
|
126
134
|
vaultP = undefined;
|
|
@@ -210,9 +218,14 @@ hostVaultId) {
|
|
|
210
218
|
}
|
|
211
219
|
return normaliseQueryResult(await queryService(decl ?? { id: ref, label: ref, sql: ref }, params ?? []));
|
|
212
220
|
},
|
|
213
|
-
async publish(type, payload, context) {
|
|
221
|
+
async publish(type, payload, context, options) {
|
|
214
222
|
const vault = await getVault();
|
|
215
|
-
return vault.scope(manifest.scope).publish({
|
|
223
|
+
return vault.scope(manifest.scope).publish({
|
|
224
|
+
type,
|
|
225
|
+
context: context ?? '',
|
|
226
|
+
payload,
|
|
227
|
+
...(options?.target ? { target: options.target } : {}),
|
|
228
|
+
});
|
|
216
229
|
},
|
|
217
230
|
async connectAgent() {
|
|
218
231
|
const vault = await getVault();
|