@canonmsg/agent-sdk 13.2.0 → 13.3.0
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/chunks/{chunk-5YKGDUJX.js → chunk-AVR7QCHK.js} +369 -416
- package/dist/chunks/{chunk-DTAWEQCM.js → chunk-BQGXOAIW.js} +2 -2
- package/dist/chunks/{chunk-5WPAB5MB.js → chunk-CUPSYLBV.js} +2041 -2049
- package/dist/chunks/{chunk-YJUPKU47.js → chunk-HFT75BNB.js} +2 -2
- package/dist/chunks/{chunk-YHDDOADK.js → chunk-NIORQKUI.js} +1 -1
- package/dist/chunks/{chunk-6FD6KFQN.js → chunk-ZT3TJZAV.js} +400 -270
- package/dist/chunks/{mls-crypto-NZVMSUFU.js → mls-crypto-AW7TY744.js} +2 -2
- package/dist/cli.js +141 -26
- package/dist/index.js +6 -6
- package/dist/internal/agent-tools/communication-tool.d.ts +80 -0
- package/dist/internal/agent-tools/index.d.ts +1 -0
- package/dist/internal/backend-contracts/endpoint.d.ts +25 -0
- package/dist/internal/backend-contracts/mlsDevKeyPackages.d.ts +4 -0
- package/dist/internal/core/client.d.ts +0 -4
- package/dist/internal/core/endpoint-client.d.ts +8 -0
- package/dist/internal/core/index.d.ts +1 -1
- package/dist/internal/core/registration-profile.d.ts +4 -1
- package/dist/internal/core/types.d.ts +3 -1
- package/dist/internal/endpoint/engine.d.ts +34 -9
- package/dist/internal/endpoint/events.d.ts +1 -2
- package/dist/internal/endpoint/index.d.ts +0 -5
- package/dist/internal/endpoint/media.d.ts +4 -63
- package/dist/internal/endpoint/mls-dev-groups.d.ts +9 -1
- package/dist/internal/endpoint/queue.d.ts +1 -3
- package/dist/media.js +4 -4
- package/dist/mls-wasm-host.js +3 -3
- package/dist/runner/mls.d.ts +12 -2
- package/dist/runner/runner.d.ts +5 -2
- package/package.json +2 -3
- package/dist/internal/endpoint/artifact-images.d.ts +0 -60
- package/dist/internal/endpoint/artifact-reducer.d.ts +0 -35
- package/dist/internal/endpoint/artifact-views.d.ts +0 -113
- package/dist/internal/endpoint/artifacts.d.ts +0 -75
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
createMlsDevCredentialVerifier,
|
|
3
3
|
mlsDevDeviceHttpConfiguration,
|
|
4
4
|
parseMlsDevClientConfiguration
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-NIORQKUI.js";
|
|
6
|
+
import "./chunk-CUPSYLBV.js";
|
|
7
7
|
export {
|
|
8
8
|
createMlsDevCredentialVerifier,
|
|
9
9
|
mlsDevDeviceHttpConfiguration,
|
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
MLS_SETUP_ACTIONS,
|
|
4
|
+
RUNNER_CLIENT,
|
|
4
5
|
acpDriver,
|
|
5
6
|
awaitErrand,
|
|
6
7
|
checkAcp,
|
|
@@ -25,28 +26,30 @@ import {
|
|
|
25
26
|
runMlsDevSetup,
|
|
26
27
|
startRelayChannel,
|
|
27
28
|
writeRelayCredential
|
|
28
|
-
} from "./chunks/chunk-
|
|
29
|
+
} from "./chunks/chunk-ZT3TJZAV.js";
|
|
29
30
|
import {
|
|
30
31
|
assertPrivateHome,
|
|
31
32
|
runnerLockName
|
|
32
|
-
} from "./chunks/chunk-
|
|
33
|
+
} from "./chunks/chunk-BQGXOAIW.js";
|
|
33
34
|
import {
|
|
34
35
|
CanonApiError,
|
|
35
36
|
CanonClient,
|
|
36
37
|
acquireLock,
|
|
38
|
+
clearPendingRegistration,
|
|
39
|
+
ensureAgentProfile,
|
|
37
40
|
isProfileLocked,
|
|
41
|
+
loadPendingRegistrations,
|
|
38
42
|
loadProfiles,
|
|
39
|
-
readCliPackageVersion,
|
|
40
43
|
resolveCanonRuntimeConnection,
|
|
41
44
|
runCli,
|
|
42
45
|
verifyCanonRuntimeConnection
|
|
43
|
-
} from "./chunks/chunk-
|
|
44
|
-
import "./chunks/chunk-
|
|
45
|
-
import "./chunks/chunk-
|
|
46
|
+
} from "./chunks/chunk-AVR7QCHK.js";
|
|
47
|
+
import "./chunks/chunk-HFT75BNB.js";
|
|
48
|
+
import "./chunks/chunk-NIORQKUI.js";
|
|
46
49
|
import {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
} from "./chunks/chunk-
|
|
50
|
+
AGENT_HOME_ELSEWHERE,
|
|
51
|
+
__name
|
|
52
|
+
} from "./chunks/chunk-CUPSYLBV.js";
|
|
50
53
|
|
|
51
54
|
// src/cli.ts
|
|
52
55
|
import { realpathSync } from "node:fs";
|
|
@@ -54,8 +57,23 @@ import { homedir, tmpdir } from "node:os";
|
|
|
54
57
|
import { dirname, join, resolve } from "node:path";
|
|
55
58
|
import { pathToFileURL } from "node:url";
|
|
56
59
|
import { parseArgs } from "node:util";
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
function exitCodeFor(error) {
|
|
61
|
+
return error?.code === AGENT_HOME_ELSEWHERE ? 0 : 1;
|
|
62
|
+
}
|
|
63
|
+
__name(exitCodeFor, "exitCodeFor");
|
|
64
|
+
function stopThenExit(stop, code, exit = process.exit, boundMs = 15e3) {
|
|
65
|
+
let done = false;
|
|
66
|
+
const finish = /* @__PURE__ */ __name(() => {
|
|
67
|
+
if (!done) {
|
|
68
|
+
done = true;
|
|
69
|
+
clearTimeout(bound);
|
|
70
|
+
exit(code);
|
|
71
|
+
}
|
|
72
|
+
}, "finish");
|
|
73
|
+
const bound = setTimeout(finish, boundMs);
|
|
74
|
+
void Promise.resolve().then(stop).catch(() => void 0).finally(finish);
|
|
75
|
+
}
|
|
76
|
+
__name(stopThenExit, "stopThenExit");
|
|
59
77
|
function once(handler) {
|
|
60
78
|
let called = false;
|
|
61
79
|
return (...args) => {
|
|
@@ -69,6 +87,8 @@ __name(once, "once");
|
|
|
69
87
|
var HELP = `canon-agent: run a Canon agent on the unified runner
|
|
70
88
|
|
|
71
89
|
Usage:
|
|
90
|
+
canon-agent run --driver <driver> --name <name> --owner-phone <+E.164> [--description <text>]
|
|
91
|
+
[--environment <id>] ... (the first run: registers the agent, then runs)
|
|
72
92
|
canon-agent run --driver code --module <path> [--profile <name>] [--environment <id>]
|
|
73
93
|
canon-agent run --driver claude [--cwd <dir>] [--model <id>] [--permission-mode <mode>]
|
|
74
94
|
[--claude-path <path>] [--profile <name>] [--environment <id>]
|
|
@@ -99,6 +119,19 @@ command also takes --mls-dev-config <path>, an operator's own custody instead. W
|
|
|
99
119
|
of these, the agent refuses every room, and where Canon encrypts every new conversation
|
|
100
120
|
it does not start.
|
|
101
121
|
|
|
122
|
+
First run: with --name and --owner-phone, a run whose profile (--profile, default the
|
|
123
|
+
name) has no key asks the owner to approve the agent in Canon, waits up to 30 minutes,
|
|
124
|
+
saves the profile and runs. A run whose saved key Canon refuses asks the owner for a
|
|
125
|
+
new key for the same agent the same way; the agent keeps its conversations, devices and
|
|
126
|
+
connections. The request stays open while nobody answers: run the command again to keep
|
|
127
|
+
waiting. A declined request ends the run.
|
|
128
|
+
|
|
129
|
+
One home: an agent answers from one place at a time. A run on a new machine, or with an
|
|
130
|
+
empty $CANON_HOME, takes it over at start, and the run it replaced stops and exits 0, so
|
|
131
|
+
a supervisor that restarts only on failure leaves it stopped. That run does not take the
|
|
132
|
+
home back by itself; start it with --take-over to move the agent back there. While the
|
|
133
|
+
agent's owner has Canon's relay on for its MCP connection, no run starts (exit 0).
|
|
134
|
+
|
|
102
135
|
Waking and sleeping: code, claude, codex and acp also take [--wake-config <path> |
|
|
103
136
|
--wake-off] [--idle-timeout <duration>]. With --wake-config the agent registers, at
|
|
104
137
|
each start, a public HTTPS callback for up to 32 rooms; Canon POSTs it a signed,
|
|
@@ -191,6 +224,8 @@ Flags:
|
|
|
191
224
|
with a signed challenge first; the agent does not start if
|
|
192
225
|
that fails. Without the flag a registration is left as it is.
|
|
193
226
|
--wake-off Remove the agent's wake callback at start.
|
|
227
|
+
--take-over Move the agent's home back to this machine after a run
|
|
228
|
+
elsewhere took it over.
|
|
194
229
|
--idle-timeout <d> Stop and exit 0 after this long with nothing to do: whole
|
|
195
230
|
seconds, or 90s, 10m, 1h. Typing in a room does not reach the
|
|
196
231
|
agent: a host that also receives typing hints decides itself
|
|
@@ -221,6 +256,9 @@ Flags:
|
|
|
221
256
|
1 unless it was accepted (a note kept, a post sent, an errand's
|
|
222
257
|
turn ended and any report it sent to --origin accepted).
|
|
223
258
|
--profile <name> A profile in $CANON_HOME/agents.json (key and endpoints).
|
|
259
|
+
--name <name> run: the agent's name, to register it (with --owner-phone).
|
|
260
|
+
--owner-phone <phone> run: the owner's phone number in Canon, international format.
|
|
261
|
+
--description <text> run: what the agent does, shown to its owner (default: the name).
|
|
224
262
|
--environment <id> canon-prod-v1 or canon-dev-v1 (default: CANON_ENVIRONMENT_ID).
|
|
225
263
|
--help, -h Show this help.
|
|
226
264
|
--version, -V Show the package version.
|
|
@@ -310,10 +348,11 @@ async function main() {
|
|
|
310
348
|
if (trustedAgents.some((id) => !/^[\w.:-]{1,200}$/.test(id))) throw new UsageError("--trust-agent takes an agent id.");
|
|
311
349
|
const instructions = values.instructions !== void 0 ? await loadInstructions(resolve(values.instructions)) : void 0;
|
|
312
350
|
const wake = values["wake-off"] ? null : values["wake-config"] !== void 0 ? await loadWakeConfiguration(resolve(values["wake-config"])) : void 0;
|
|
351
|
+
const registered = await ensureRegistered(values, values.driver);
|
|
352
|
+
if (registered) values.profile = registered;
|
|
313
353
|
const { environmentId, home, profile, apiKey } = await settings(values);
|
|
314
354
|
const mls = await mlsDevice(values, environmentId, home);
|
|
315
|
-
const baseUrl =
|
|
316
|
-
const streamUrl = process.env.CANON_STREAM_URL || profile?.streamUrl;
|
|
355
|
+
const { apiBaseUrl: baseUrl, streamUrl } = connectionFor(environmentId, profile);
|
|
317
356
|
let driver;
|
|
318
357
|
if (values.driver === "claude") {
|
|
319
358
|
driver = claudeDriver({
|
|
@@ -366,8 +405,8 @@ async function main() {
|
|
|
366
405
|
...team,
|
|
367
406
|
...trustedAgents.length ? { trustedAgents } : {},
|
|
368
407
|
...values["allow-session-for-destructive"] ? { sessionApprovalForDestructive: true } : {},
|
|
369
|
-
...RUNNER_CLIENT ? { client: RUNNER_CLIENT } : {},
|
|
370
408
|
...wake !== void 0 ? { wake } : {},
|
|
409
|
+
...values["take-over"] ? { takeOver: true } : {},
|
|
371
410
|
// Idle: a clean stop and exit 0, so a supervisor that restarts only on failure leaves the agent stopped until it is woken.
|
|
372
411
|
...idleTimeoutMs !== void 0 ? { idleTimeoutMs, onIdle: once(() => {
|
|
373
412
|
console.error(`canon-agent: nothing to do for ${values["idle-timeout"]}; stopping.`);
|
|
@@ -378,7 +417,7 @@ async function main() {
|
|
|
378
417
|
}) } : {},
|
|
379
418
|
onFatal: once((error) => {
|
|
380
419
|
console.error(`canon-agent: ${error.message}`);
|
|
381
|
-
|
|
420
|
+
stopThenExit(() => runner.stop(), exitCodeFor(error));
|
|
382
421
|
})
|
|
383
422
|
});
|
|
384
423
|
stopOnSignals(() => runner.stop());
|
|
@@ -394,8 +433,7 @@ __name(main, "main");
|
|
|
394
433
|
async function runRelay(values, team) {
|
|
395
434
|
const { environmentId, home, profile } = await settings(values, { key: false });
|
|
396
435
|
const relay = await loadRelayConfiguration(values["relay-config"], { environmentId });
|
|
397
|
-
const baseUrl =
|
|
398
|
-
const streamUrl = process.env.CANON_STREAM_URL || profile?.streamUrl;
|
|
436
|
+
const { apiBaseUrl: baseUrl, streamUrl } = connectionFor(environmentId, profile);
|
|
399
437
|
let current;
|
|
400
438
|
let latest;
|
|
401
439
|
let switching = Promise.resolve();
|
|
@@ -446,10 +484,12 @@ async function runRelay(values, team) {
|
|
|
446
484
|
relay: true,
|
|
447
485
|
installationId: stored2.installationId,
|
|
448
486
|
...team,
|
|
449
|
-
...RUNNER_CLIENT ? { client: RUNNER_CLIENT } : {},
|
|
450
487
|
onFatal: once((error) => {
|
|
451
488
|
console.error(`canon-agent: ${error.message}`);
|
|
452
|
-
|
|
489
|
+
stopThenExit(async () => {
|
|
490
|
+
await channel.close();
|
|
491
|
+
await runner.stop();
|
|
492
|
+
}, 1);
|
|
453
493
|
})
|
|
454
494
|
});
|
|
455
495
|
try {
|
|
@@ -522,11 +562,85 @@ function parse() {
|
|
|
522
562
|
cancel: { type: "string" },
|
|
523
563
|
"wake-config": { type: "string" },
|
|
524
564
|
"wake-off": { type: "boolean" },
|
|
525
|
-
"idle-timeout": { type: "string" }
|
|
565
|
+
"idle-timeout": { type: "string" },
|
|
566
|
+
"take-over": { type: "boolean" },
|
|
567
|
+
name: { type: "string" },
|
|
568
|
+
"owner-phone": { type: "string" },
|
|
569
|
+
description: { type: "string" }
|
|
526
570
|
}
|
|
527
571
|
});
|
|
528
572
|
}
|
|
529
573
|
__name(parse, "parse");
|
|
574
|
+
var REGISTRATION_WAIT_MS = 30 * 6e4;
|
|
575
|
+
var REGISTRATION_CLIENT_TYPES = { claude: "claude-code", codex: "codex" };
|
|
576
|
+
async function ensureRegistered(values, driver) {
|
|
577
|
+
const name = values.name?.trim(), ownerPhone = values["owner-phone"]?.trim();
|
|
578
|
+
if (!name && !ownerPhone && values.description === void 0) return void 0;
|
|
579
|
+
if (!name || !ownerPhone) throw new UsageError("--name and --owner-phone go together (and --description with them).");
|
|
580
|
+
if (process.env.CANON_API_KEY) throw new UsageError("--name and --owner-phone keep the agent's key in a profile: unset CANON_API_KEY.");
|
|
581
|
+
const environmentId = values.environment || process.env.CANON_ENVIRONMENT_ID;
|
|
582
|
+
if (!environmentId) throw new Error("CANON_ENVIRONMENT_ID (or --environment) is required.");
|
|
583
|
+
const home = resolve(process.env.CANON_HOME || join(homedir(), ".canon"));
|
|
584
|
+
await assertPrivateHome(home);
|
|
585
|
+
const profile = values.profile || name;
|
|
586
|
+
const saved = loadProfiles(home)[profile];
|
|
587
|
+
if (saved && saved.environmentId !== environmentId) throw new Error(`Profile "${profile}" belongs to ${saved.environmentId}, not ${environmentId}.`);
|
|
588
|
+
const connection = connectionFor(environmentId, saved);
|
|
589
|
+
const agentName = saved?.agentName ?? name;
|
|
590
|
+
const register = /* @__PURE__ */ __name(async (reconnect) => {
|
|
591
|
+
const pending = loadPendingRegistrations()[profile];
|
|
592
|
+
const ask = reconnect || pending?.requestedAgentId ? `a new key for ${agentName}` : agentName;
|
|
593
|
+
const waiting = /* @__PURE__ */ __name(() => console.error(`canon-agent: ask the owner of ${ownerPhone} to approve ${ask} in Canon. Waiting up to 30 minutes; the request stays open until they answer, and running this command again keeps waiting.`), "waiting");
|
|
594
|
+
if (pending && !pending.credentialAgentId) waiting();
|
|
595
|
+
const asked = reconnect || !!pending || !saved;
|
|
596
|
+
const progress = await ensureAgentProfile({
|
|
597
|
+
profile,
|
|
598
|
+
reconnect,
|
|
599
|
+
waitMs: REGISTRATION_WAIT_MS,
|
|
600
|
+
onSubmitted: waiting,
|
|
601
|
+
connection,
|
|
602
|
+
input: {
|
|
603
|
+
name,
|
|
604
|
+
description: values.description?.trim() || name,
|
|
605
|
+
ownerPhone,
|
|
606
|
+
clientType: REGISTRATION_CLIENT_TYPES[driver] ?? "generic",
|
|
607
|
+
developerInfo: `canon-agent run --driver ${driver}`
|
|
608
|
+
}
|
|
609
|
+
});
|
|
610
|
+
switch (progress.status) {
|
|
611
|
+
case "approved":
|
|
612
|
+
if (asked) console.error(`canon-agent: ${progress.agentName} is approved; its key is saved in profile "${profile}".`);
|
|
613
|
+
return progress.apiKey;
|
|
614
|
+
case "pending":
|
|
615
|
+
throw new Error(`Nobody has answered the request for ${ask} yet. It stays open: run this command again to keep waiting.`);
|
|
616
|
+
case "rejected":
|
|
617
|
+
clearPendingRegistration(profile);
|
|
618
|
+
throw new Error(`The owner declined ${ask}. Nothing was saved; run this command again to ask again.`);
|
|
619
|
+
case "credential-expired":
|
|
620
|
+
clearPendingRegistration(profile);
|
|
621
|
+
throw new Error(`The owner approved ${ask}, but its key was not collected within 48 hours and Canon removed it. Run this command again to ask again.`);
|
|
622
|
+
case "credential-delivered":
|
|
623
|
+
clearPendingRegistration(profile);
|
|
624
|
+
throw new Error(`The key for ${ask} was already collected elsewhere, so this run cannot have it. Run this command again to ask again.`);
|
|
625
|
+
}
|
|
626
|
+
}, "register");
|
|
627
|
+
const apiKey = await register(false);
|
|
628
|
+
try {
|
|
629
|
+
await new CanonClient(apiKey, resolveCanonRuntimeConnection(connection).apiBaseUrl).getAgentMe();
|
|
630
|
+
return profile;
|
|
631
|
+
} catch (error) {
|
|
632
|
+
if (!(error instanceof CanonApiError) || error.status !== 401) throw error;
|
|
633
|
+
}
|
|
634
|
+
console.error(`canon-agent: Canon no longer accepts ${agentName}'s saved key.`);
|
|
635
|
+
await register(true);
|
|
636
|
+
return profile;
|
|
637
|
+
}
|
|
638
|
+
__name(ensureRegistered, "ensureRegistered");
|
|
639
|
+
function connectionFor(environmentId, profile) {
|
|
640
|
+
const apiBaseUrl = process.env.CANON_BASE_URL || profile?.baseUrl, streamUrl = process.env.CANON_STREAM_URL || profile?.streamUrl;
|
|
641
|
+
return { environmentId, ...apiBaseUrl ? { apiBaseUrl } : {}, ...streamUrl ? { streamUrl } : {} };
|
|
642
|
+
}
|
|
643
|
+
__name(connectionFor, "connectionFor");
|
|
530
644
|
async function settings(values, { key = true } = {}) {
|
|
531
645
|
const environmentId = values.environment || process.env.CANON_ENVIRONMENT_ID;
|
|
532
646
|
if (!environmentId) throw new Error("CANON_ENVIRONMENT_ID (or --environment) is required.");
|
|
@@ -564,11 +678,7 @@ async function mlsSetup(values) {
|
|
|
564
678
|
let client;
|
|
565
679
|
let lock;
|
|
566
680
|
try {
|
|
567
|
-
const connection = resolveCanonRuntimeConnection(
|
|
568
|
-
environmentId,
|
|
569
|
-
apiBaseUrl: process.env.CANON_BASE_URL || profile?.baseUrl,
|
|
570
|
-
streamUrl: process.env.CANON_STREAM_URL || profile?.streamUrl
|
|
571
|
-
});
|
|
681
|
+
const connection = resolveCanonRuntimeConnection(connectionFor(environmentId, profile));
|
|
572
682
|
await verifyCanonRuntimeConnection(connection);
|
|
573
683
|
client = new CanonClient(apiKey, connection.apiBaseUrl, {
|
|
574
684
|
environmentId,
|
|
@@ -660,5 +770,10 @@ __name(stopOnSignals, "stopOnSignals");
|
|
|
660
770
|
runCli(import.meta.url, main, (error) => {
|
|
661
771
|
console.error(`canon-agent: ${error instanceof Error ? error.message : String(error)}`);
|
|
662
772
|
if (error instanceof UsageError) console.error(HELP.split("\n\nFlags:")[0]);
|
|
663
|
-
process.exit(1);
|
|
773
|
+
process.exit(error instanceof UsageError ? 1 : exitCodeFor(error));
|
|
664
774
|
}, { name: "canon-agent", help: HELP });
|
|
775
|
+
export {
|
|
776
|
+
ensureRegistered,
|
|
777
|
+
exitCodeFor,
|
|
778
|
+
stopThenExit
|
|
779
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -26,8 +26,8 @@ import {
|
|
|
26
26
|
runMlsDevSetup,
|
|
27
27
|
runtimeDescriptor,
|
|
28
28
|
startRelayChannel
|
|
29
|
-
} from "./chunks/chunk-
|
|
30
|
-
import "./chunks/chunk-
|
|
29
|
+
} from "./chunks/chunk-ZT3TJZAV.js";
|
|
30
|
+
import "./chunks/chunk-BQGXOAIW.js";
|
|
31
31
|
import {
|
|
32
32
|
CanonApiError,
|
|
33
33
|
DEFAULT_ANTHROPIC_REQUEST_HEADROOM_BYTES,
|
|
@@ -52,10 +52,10 @@ import {
|
|
|
52
52
|
toAnthropicImageBlock,
|
|
53
53
|
toAnthropicImageBlocksWithinBudget,
|
|
54
54
|
uploadMediaFile
|
|
55
|
-
} from "./chunks/chunk-
|
|
56
|
-
import "./chunks/chunk-
|
|
57
|
-
import "./chunks/chunk-
|
|
58
|
-
import "./chunks/chunk-
|
|
55
|
+
} from "./chunks/chunk-AVR7QCHK.js";
|
|
56
|
+
import "./chunks/chunk-HFT75BNB.js";
|
|
57
|
+
import "./chunks/chunk-NIORQKUI.js";
|
|
58
|
+
import "./chunks/chunk-CUPSYLBV.js";
|
|
59
59
|
export {
|
|
60
60
|
CanonApiError,
|
|
61
61
|
ConnectorRelayError,
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { type CanonClient, type CommunicateInput } from '../core/index.js';
|
|
2
|
+
export interface VerbToolDefinition {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
inputSchema: Record<string, unknown>;
|
|
6
|
+
}
|
|
7
|
+
export interface VerbToolResult {
|
|
8
|
+
content: Array<{
|
|
9
|
+
type: 'text';
|
|
10
|
+
text: string;
|
|
11
|
+
}>;
|
|
12
|
+
isError?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare const CANON_COMMUNICATE_TOOL_NAME = "communicate";
|
|
15
|
+
export declare const CANON_COMMUNICATE_DISCOVERY_MAX_RESULTS = 10;
|
|
16
|
+
/**
|
|
17
|
+
* What each action takes: the fields it needs, then those it may have. The legacy aliases (start_direct,
|
|
18
|
+
* create_group, manage_group_members) take their action's fields; the parser still accepts them, and no schema offers them.
|
|
19
|
+
*/
|
|
20
|
+
declare const ACTION_FIELDS: {
|
|
21
|
+
readonly list_conversations: {
|
|
22
|
+
readonly required: readonly [];
|
|
23
|
+
readonly optional: readonly ["limit"];
|
|
24
|
+
};
|
|
25
|
+
readonly discover_agents: {
|
|
26
|
+
readonly required: readonly [];
|
|
27
|
+
readonly optional: readonly ["query", "limit", "cursor"];
|
|
28
|
+
};
|
|
29
|
+
readonly message_existing: {
|
|
30
|
+
readonly required: readonly ["conversationId", "text"];
|
|
31
|
+
readonly optional: readonly ["messageId"];
|
|
32
|
+
};
|
|
33
|
+
readonly start_conversation: {
|
|
34
|
+
readonly required: readonly ["principalId", "text"];
|
|
35
|
+
readonly optional: readonly ["selection", "messageId"];
|
|
36
|
+
};
|
|
37
|
+
readonly create_conversation: {
|
|
38
|
+
readonly required: readonly ["memberIds"];
|
|
39
|
+
readonly optional: readonly ["name"];
|
|
40
|
+
};
|
|
41
|
+
readonly manage_participants: {
|
|
42
|
+
readonly required: readonly ["conversationId", "userId", "operation"];
|
|
43
|
+
readonly optional: readonly [];
|
|
44
|
+
};
|
|
45
|
+
readonly leave_conversation: {
|
|
46
|
+
readonly required: readonly ["conversationId"];
|
|
47
|
+
readonly optional: readonly [];
|
|
48
|
+
};
|
|
49
|
+
readonly forward_message: {
|
|
50
|
+
readonly required: readonly ["sourceConversationId", "targetConversationId", "messageId"];
|
|
51
|
+
readonly optional: readonly ["text"];
|
|
52
|
+
};
|
|
53
|
+
readonly share_contact: {
|
|
54
|
+
readonly required: readonly ["conversationId", "contactUserId"];
|
|
55
|
+
readonly optional: readonly ["text", "messageId"];
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
export type CanonCommunicateAction = keyof typeof ACTION_FIELDS;
|
|
59
|
+
/** The actions a binding offers, each with the fields it shows for it (an action's required fields always). */
|
|
60
|
+
export type CommunicateShape = Readonly<Partial<Record<CanonCommunicateAction, readonly string[]>>>;
|
|
61
|
+
/** Every action with every field: the complete communication surface. */
|
|
62
|
+
export declare const CANON_COMMUNICATE_SHAPE: CommunicateShape;
|
|
63
|
+
/**
|
|
64
|
+
* One flat object schema for `communicate`: `action` names the action, and every other field is optional and says which
|
|
65
|
+
* actions take it. Claude reads a tool's schema as one object, so a top-level `oneOf` showed it only its first
|
|
66
|
+
* alternative (the driver trial on Dev, 2026-11-09); the parser checks each combination instead.
|
|
67
|
+
*/
|
|
68
|
+
export declare function communicateInputSchema(shape: CommunicateShape, textMaxLength?: number | null): Record<string, unknown>;
|
|
69
|
+
/**
|
|
70
|
+
* The complete model-facing communication surface. It is exported separately
|
|
71
|
+
* from the in-conversation verb list so each runtime can opt into it.
|
|
72
|
+
*/
|
|
73
|
+
export declare function canonCommunicateToolDefinition(name?: string): VerbToolDefinition;
|
|
74
|
+
/**
|
|
75
|
+
* Runtime validation for bindings that dispatch directly. The schema is flat, so this is where a combination is checked:
|
|
76
|
+
* an action the binding does not offer, a field the action needs, or one it does not take, is refused by name.
|
|
77
|
+
*/
|
|
78
|
+
export declare function parseCommunicateToolInput(value: unknown, shape?: CommunicateShape): CommunicateInput;
|
|
79
|
+
export declare function executeCanonCommunicateTool(client: CanonClient, args: unknown, shape?: CommunicateShape): Promise<VerbToolResult>;
|
|
80
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CANON_COMMUNICATE_DISCOVERY_MAX_RESULTS, CANON_COMMUNICATE_SHAPE, CANON_COMMUNICATE_TOOL_NAME, canonCommunicateToolDefinition, communicateInputSchema, executeCanonCommunicateTool, parseCommunicateToolInput, type CanonCommunicateAction, type CommunicateShape, type VerbToolDefinition, type VerbToolResult, } from './communication-tool.js';
|
|
@@ -118,3 +118,28 @@ export declare const ENDPOINT_ID_PATTERN: RegExp;
|
|
|
118
118
|
export declare const ENDPOINT_ACTION_PATTERN: RegExp;
|
|
119
119
|
export declare function isEndpointOperationRequest(value: unknown): value is EndpointOperationRequest;
|
|
120
120
|
export declare function isEndpointOperationReceipt(value: unknown): value is EndpointOperationReceipt;
|
|
121
|
+
/**
|
|
122
|
+
* An agent answers from one home at a time: Canon's relay for its MCP connection while the owner has the relay on,
|
|
123
|
+
* otherwise its runner, the installation that started most recently (`initialize_endpoint` moves it there). Everything
|
|
124
|
+
* the other home sends is refused with `AGENT_HOME_ELSEWHERE`, so no message gets two answers. It is read from the
|
|
125
|
+
* agent's own document alone (`users/{agentId}`), so every hot path can check it without another read.
|
|
126
|
+
*
|
|
127
|
+
* `since` (ms, Canon's clock): this home answers for work from here, for its work floor and in the refusal's text. Nothing
|
|
128
|
+
* Canon accepted before it is that home's work, since the home before may have answered it. For the relay, its approval.
|
|
129
|
+
* For a runner, the later of `installedAt` and the relay's turn-off, after which the runner it replaced is the home again
|
|
130
|
+
* by itself. Despite its name, `installedAt` holds where its installation answers for work from (its baseline's cutover):
|
|
131
|
+
* a first installation's approval, a later one's take-over. Older markers hold a first installation's first start, and
|
|
132
|
+
* are read as they are.
|
|
133
|
+
*/
|
|
134
|
+
export declare const AGENT_HOME_ELSEWHERE = "AGENT_HOME_ELSEWHERE";
|
|
135
|
+
export type AgentHome = {
|
|
136
|
+
kind: 'connector';
|
|
137
|
+
since?: number;
|
|
138
|
+
} | {
|
|
139
|
+
kind: 'runner';
|
|
140
|
+
installationId?: string;
|
|
141
|
+
since?: number;
|
|
142
|
+
};
|
|
143
|
+
export declare function readAgentHome(agentConfig: unknown): AgentHome;
|
|
144
|
+
/** The one refusal both homes give the other: what is true now, and what the owner or operator can do. */
|
|
145
|
+
export declare function agentHomeElsewhereMessage(agentName: string | undefined, home: AgentHome): string;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
export declare const MLS_DEV_KEY_PACKAGES_MAX_BYTES = 32768;
|
|
2
2
|
export declare const MLS_DEV_KEY_PACKAGE_TLS_MAX_BYTES = 16384;
|
|
3
|
+
/** How long a claim holds its recipient's slot before another member's device may take it over (mls-rooms-by-default.md
|
|
4
|
+
* §2.4). On Dev from 2026-10-20 to 11-08, 113 Adds were accepted a median 2.4 s after their claim, 99% within 9.4 s, and
|
|
5
|
+
* the slowest in 61.5 s: two minutes is about twice the slowest, and a dead claimant holds a device off no longer. */
|
|
6
|
+
export declare const MLS_DEV_KEY_PACKAGE_CLAIM_LEASE_MS: number;
|
|
3
7
|
export interface MlsDevKeyPackagePublishRequest {
|
|
4
8
|
readonly version: 1;
|
|
5
9
|
readonly requestId: string;
|
|
@@ -8,10 +8,6 @@ export interface ResumableMediaUploadResult {
|
|
|
8
8
|
status?: 'processing' | 'ready' | 'failed';
|
|
9
9
|
attachment: MediaAttachment;
|
|
10
10
|
}
|
|
11
|
-
/**
|
|
12
|
-
* Agent-facing ergonomics over the shared endpoint engine. Authentication and
|
|
13
|
-
* operator registration remain outside the conversation protocol.
|
|
14
|
-
*/
|
|
15
11
|
export declare class CanonClient {
|
|
16
12
|
private baseUrl;
|
|
17
13
|
private apiKey;
|
|
@@ -30,6 +30,14 @@ export interface CanonClientEndpointOptions {
|
|
|
30
30
|
mediaDirectory?: string;
|
|
31
31
|
/** Operator inspection/import does not automatically publish queued operations. */
|
|
32
32
|
autoDrain?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* This client is the agent's runner, and its installation is the agent's home: a new installation takes the home at
|
|
35
|
+
* start; one that lost it to another refuses to start (`AGENT_HOME_ELSEWHERE`) unless `takeOver` moves it back, so two
|
|
36
|
+
* supervised machines never take it from each other in turn. Other clients (a script, a CLI step) never move the home.
|
|
37
|
+
*/
|
|
38
|
+
claimHome?: boolean;
|
|
39
|
+
/** With `claimHome`: move the home back to this installation after another one took it. */
|
|
40
|
+
takeOver?: boolean;
|
|
33
41
|
/** Replicated cloud hosts supply operator-owned durable byte storage. */
|
|
34
42
|
mediaBytes?: EndpointMediaBytes<string>;
|
|
35
43
|
/** Test seam for the client's out-of-protocol HTTP (identity, profile); production leaves it unset. */
|
|
@@ -55,5 +55,5 @@ export { handleCliMetadataRequest, isDirectExecution, readCliPackageVersion, run
|
|
|
55
55
|
export type { CliMetadata, RunCliMetadataOptions, } from './cli-metadata.js';
|
|
56
56
|
export { CANON_VERB_NAMES, CANON_VERB_NAMESPACE, CANON_VERBS_SCHEMA_ID, CANON_VERBS_SCHEMA_VERSION, CANON_VERB_WIRE_SCHEMA_ID, CANON_VERB_WIRE_SCHEMA_VERSION, CANON_CARD_SCHEMA_ID, VERB_LIMITS, VERB_RATE_LIMITS, VERB_WIRE_ENVELOPE_FIELDS, canonVerbToolName, findVerbByteLimitViolations, findVerbWireEnvelopeViolations, getVerbResultSchema, mergeVerbWireToIntent, normalizeVerbNativeMetadata, projectVerbIntentToWire, type CanonVerbName, type CanonVerbWireEnvelope, type CanonVerbWireRequest, type CanonVerbWireResponse, type CanonVerbJsonSchema, type SendToInput, type SendToResult, type VerbMessageOptions, type VerbNativeMetadata, type VerbWireAccepted, type VerbWireBody, } from '../backend-contracts/index.js';
|
|
57
57
|
export { DEFAULT_DISCOVER_AGENTS_LIMIT, MAX_DISCOVER_AGENTS_LIMIT, MAX_DISCOVER_AGENTS_QUERY_LENGTH, type CanonAgentDirectoryEntry, type DiscoverAgentsInput, type DiscoverAgentsResult, } from '../backend-contracts/index.js';
|
|
58
|
-
export { parseDirectConversationSelection, readCommunicationRule, type CommunicateInput, type CommunicateResult, type CommunicationRule, type DirectConversationSelection, type StartDirectInput, type StartDirectResult, } from '../backend-contracts/index.js';
|
|
58
|
+
export { MLS_DEV_TEXT_MAX_BYTES, parseDirectConversationSelection, readCommunicationRule, type CommunicateInput, type CommunicateResult, type CommunicationRule, type DirectConversationSelection, type StartDirectInput, type StartDirectResult, } from '../backend-contracts/index.js';
|
|
59
59
|
export { canonMediaDownloadUrl, sanitizeDownloadFileName, buildMediaContentDisposition, getStoredFileExtension } from '../backend-contracts/index.js';
|
|
@@ -3,7 +3,10 @@ export interface EnsureAgentProfileOptions extends Omit<ResumeRegistrationOption
|
|
|
3
3
|
/** The local profile store owns its stable localRegistrationId. */
|
|
4
4
|
input: Omit<ResumeRegistrationOptions['input'], 'localRegistrationId'>;
|
|
5
5
|
profile: string;
|
|
6
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* Ask the owner for a new key for this profile's agent (its saved agent ID, or `input.requestedAgentId`), even if a
|
|
8
|
+
* usable local credential exists. Approval only replaces the key: the agent keeps its rooms, devices and connections.
|
|
9
|
+
*/
|
|
7
10
|
reconnect?: boolean;
|
|
8
11
|
}
|
|
9
12
|
/** Reuse an environment-bound local profile, or resume its owner-approved registration. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentOrigin, AgentOriginDeclaration, ArtifactContext } from '../backend-contracts/index.js';
|
|
1
|
+
import type { AgentHome, AgentOrigin, AgentOriginDeclaration, ArtifactContext } from '../backend-contracts/index.js';
|
|
2
2
|
import type { CanonControlValue, CanonRuntimeStreamingMode, CanonRuntimeDetailTier, CanonRuntimeVisibility, CanonRuntimeCommandDescriptor } from '../backend-contracts/index.js';
|
|
3
3
|
export type { AgentOrigin, AgentOriginDeclaration, CanonControlValue, CanonRuntimeStreamingMode, CanonRuntimeDetailTier, CanonRuntimeVisibility, CanonRuntimeActionAvailability, CanonRuntimeActionPlacement, CanonRuntimeActionCategory, CanonRuntimePrimitiveId, CanonRuntimeCommandArgumentKind, CanonRuntimeCommandArgumentChoice, CanonRuntimeCommandArgumentDescriptor, CanonRuntimeActionDispatch, CanonRuntimeActionDescriptor, CanonRuntimeCommandDescriptor, } from '../backend-contracts/index.js';
|
|
4
4
|
import type { ExecutionEnvironmentMode } from './execution-environment-mode.js';
|
|
@@ -479,6 +479,8 @@ export interface AgentContext {
|
|
|
479
479
|
ownershipVersion: number;
|
|
480
480
|
/** Server-created new-principal marker; initialization still binds the installation atomically. */
|
|
481
481
|
endpointBootstrapEligible?: boolean;
|
|
482
|
+
/** Where the agent answers from: Canon's relay, or the runner installation that started last (absent from older Canon). */
|
|
483
|
+
home?: AgentHome;
|
|
482
484
|
canonContactId?: string;
|
|
483
485
|
displayName?: string;
|
|
484
486
|
avatarUrl?: string | null;
|
|
@@ -7,7 +7,7 @@ import { type EndpointSyncOptions, type EndpointSyncPage } from './sync.js';
|
|
|
7
7
|
import { type EndpointEventObserver, type EndpointTransportEvent } from './events.js';
|
|
8
8
|
import { type EndpointRecoveryOptions, type EndpointRecoveryBaseline } from './recovery.js';
|
|
9
9
|
import { type EndpointRecoveryMigration, type EndpointMigrationReceipt } from './migration.js';
|
|
10
|
-
import { type
|
|
10
|
+
import { type EndpointMediaBytes, type EndpointMediaPipeline } from './media.js';
|
|
11
11
|
import { type EndpointOrdering } from './queue.js';
|
|
12
12
|
import { type EndpointInboundHandoff, type EndpointInboundStartResult } from './handoff.js';
|
|
13
13
|
import { type EndpointCompletion } from './completions.js';
|
|
@@ -55,8 +55,6 @@ export interface EndpointOperation {
|
|
|
55
55
|
conversationId?: string;
|
|
56
56
|
messageId?: string;
|
|
57
57
|
agentId?: string;
|
|
58
|
-
/** Ordering scope for shared-work commands, retained after payload erasure. */
|
|
59
|
-
artifactId?: string;
|
|
60
58
|
status: EndpointLocalStatus;
|
|
61
59
|
fingerprint: string;
|
|
62
60
|
preconditions?: EndpointPreconditions;
|
|
@@ -74,6 +72,11 @@ export interface EndpointOperation {
|
|
|
74
72
|
/** Local-only binding of a withheld start's text; retained after the opener is sent or its payload is erased. */
|
|
75
73
|
openerFingerprint?: string;
|
|
76
74
|
receipt?: EndpointOperationReceipt;
|
|
75
|
+
/** A refused encrypted send this device encrypted again: the operation that replaced it, which retries and waits
|
|
76
|
+
* follow (mls-dev-groups.ts, resendText). */
|
|
77
|
+
resentAs?: string;
|
|
78
|
+
/** Local successor made after Canon refused an encrypted send, with readers and sender admission rechecked. */
|
|
79
|
+
automaticResend?: boolean;
|
|
77
80
|
attempts: number;
|
|
78
81
|
attempted: boolean;
|
|
79
82
|
nextAttemptAt?: number;
|
|
@@ -150,10 +153,15 @@ export interface Endpoint {
|
|
|
150
153
|
submit(intent: EndpointIntent, options?: EndpointExecuteOptions): Promise<EndpointOperation>;
|
|
151
154
|
execute<T = unknown>(intent: EndpointIntent, options?: EndpointExecuteOptions): Promise<EndpointOperationReceipt<T>>;
|
|
152
155
|
executeResult<T = unknown>(intent: EndpointIntent, options?: EndpointExecuteOptions): Promise<T>;
|
|
153
|
-
/** reconcileOnly reads the server receipt; it never dispatches
|
|
156
|
+
/** reconcileOnly reads and records the server receipt; it never dispatches or encrypts again. An operation encrypted
|
|
157
|
+
* again (`resentAs`) answers with the one that replaced it. An ordinary retry of a send Canon refused one change behind
|
|
158
|
+
* encrypts it again, by the rule its first refusal had, when a reconcile only recorded the refusal. */
|
|
154
159
|
retry<T = unknown>(operationId: string, options?: {
|
|
155
160
|
reconcileOnly?: boolean;
|
|
156
161
|
}): Promise<EndpointOperationReceipt<T>>;
|
|
162
|
+
/** A person's Retry of an encrypted message Canon refused: encrypts it again, from this device's copy, for its room as
|
|
163
|
+
* it is now, under a new operation that replaces the refused one. Returns the operation to retry. */
|
|
164
|
+
resend(operationId: string): Promise<EndpointOperation>;
|
|
157
165
|
drain(options?: {
|
|
158
166
|
limit?: number;
|
|
159
167
|
}): Promise<void>;
|
|
@@ -185,9 +193,7 @@ export interface Endpoint {
|
|
|
185
193
|
observeQuery<T>(query: string, parameters: Record<string, unknown>, listener: (value: T) => void, onError?: (error: unknown) => void): () => void;
|
|
186
194
|
refreshQueries(): void;
|
|
187
195
|
observeEvents(listener: (event: EndpointTransportEvent) => void, options?: EndpointEventObserver): () => void;
|
|
188
|
-
createMediaPipeline<Source>(bytes: EndpointMediaBytes<Source
|
|
189
|
-
background?: EndpointBackgroundMediaAdapter<Source>;
|
|
190
|
-
}): EndpointMediaPipeline<Source>;
|
|
196
|
+
createMediaPipeline<Source>(bytes: EndpointMediaBytes<Source>): EndpointMediaPipeline<Source>;
|
|
191
197
|
registerMessageGroup(input: EndpointMessageGroupInput, options?: {
|
|
192
198
|
signal?: AbortSignal;
|
|
193
199
|
}): Promise<EndpointOperation>;
|
|
@@ -196,8 +202,9 @@ export interface Endpoint {
|
|
|
196
202
|
cancelMessageGroup(id: string): Promise<void>;
|
|
197
203
|
/** Runtime-specific publication policy; closures are never serialized.
|
|
198
204
|
* Return false to defer, or throw a nonretryable EndpointError to retire an
|
|
199
|
-
* unsent operation. An attempted operation still needs its server receipt.
|
|
200
|
-
|
|
205
|
+
* unsent operation. An attempted operation still needs its server receipt.
|
|
206
|
+
* Automatic resends retain the policy; only an audience-specific check may use the revalidated resend context. */
|
|
207
|
+
registerDeliveryGuard(id: string, allow: EndpointDeliveryGuard): () => void;
|
|
201
208
|
/** Keep a start's opening line that Canon did not store, and send it once the room and the request allow (§2a.13). */
|
|
202
209
|
deferOpener(input: {
|
|
203
210
|
conversationId: string;
|
|
@@ -220,6 +227,21 @@ export interface Endpoint {
|
|
|
220
227
|
/** Immutable operator-reviewed or server-proven cutover for new rooms/admissions. */
|
|
221
228
|
configureRecoveryBaseline(config: EndpointRecoveryBaseline): Promise<void>;
|
|
222
229
|
getRecoveryBaseline(): Promise<EndpointRecoveryBaseline | undefined>;
|
|
230
|
+
/**
|
|
231
|
+
* Work here starts at `cutoverAt` (Canon's clock), where this installation's turn as its agent's home began: a
|
|
232
|
+
* take-over, or Canon's relay turned off. Every input Canon accepted before it is history, never work, whether it is
|
|
233
|
+
* already in the inbox or still to come off a room's feed, since the home before may have answered it. Only an input a
|
|
234
|
+
* journaled output answers keeps it. The floor only ever moves later.
|
|
235
|
+
*/
|
|
236
|
+
startWorkAt(cutoverAt: string): Promise<void>;
|
|
237
|
+
/**
|
|
238
|
+
* A runner moving its agent's home here, under a new `initialize_endpoint` operation each time, starts work from
|
|
239
|
+
* Canon's answer (`startWorkAt`). Only this call sends it. One that fails, or that a process left unanswered when it
|
|
240
|
+
* died, is never sent again (the latter is settled when the store next opens, before anything drains), so no later
|
|
241
|
+
* start makes a take-over without its operator. If Canon took the home all the same, the next start reads that from the
|
|
242
|
+
* agent's home and starts work from there.
|
|
243
|
+
*/
|
|
244
|
+
takeOverHome(): Promise<void>;
|
|
223
245
|
refreshRecovery(): Promise<void>;
|
|
224
246
|
planRecoveryMigration(baseline: EndpointRecoveryBaseline, conversationIds?: string[]): Promise<EndpointRecoveryMigration>;
|
|
225
247
|
importRecoveryMigration(manifest: EndpointRecoveryMigration, reviewedSha256: string): Promise<EndpointMigrationReceipt>;
|
|
@@ -270,5 +292,8 @@ export interface Endpoint {
|
|
|
270
292
|
logout(): Promise<void>;
|
|
271
293
|
close(): Promise<void>;
|
|
272
294
|
}
|
|
295
|
+
export type EndpointDeliveryGuard = (context: {
|
|
296
|
+
automaticResend: boolean;
|
|
297
|
+
}) => Promise<boolean>;
|
|
273
298
|
export declare function mergeConversationSnapshot<T extends EndpointConversation>(current: T | undefined, incoming: T): T;
|
|
274
299
|
export declare function createEndpoint(options: EndpointOptions): Endpoint;
|
|
@@ -4,8 +4,7 @@ export interface EndpointTransportEvent {
|
|
|
4
4
|
kind: string;
|
|
5
5
|
data: Record<string, unknown>;
|
|
6
6
|
}
|
|
7
|
-
|
|
8
|
-
export type EndpointEventFamily = 'messages' | 'contacts' | 'typing_presence' | 'runtime_turn' | 'voice' | 'artifacts';
|
|
7
|
+
export type EndpointEventFamily = 'messages' | 'contacts' | 'typing_presence' | 'runtime_turn' | 'voice';
|
|
9
8
|
export interface EndpointEventObserver {
|
|
10
9
|
families?: EndpointEventFamily[];
|
|
11
10
|
/** Explicit principal projections; room projections follow membership. */
|
|
@@ -12,12 +12,7 @@ export * from './media.js';
|
|
|
12
12
|
export * from './history.js';
|
|
13
13
|
export * from './ephemeral.js';
|
|
14
14
|
export * from './transient-publisher.js';
|
|
15
|
-
export { createArtifactClient, ArtifactRejectedError, type ArtifactClient, type ArtifactClientOptions, type ArtifactCreateOptions, type ArtifactLibrary, type ArtifactWriteResult, } from './artifacts.js';
|
|
16
|
-
export { createArtifactImageClient, type ArtifactImageAddInput, type ArtifactImageClient, type ArtifactImageGenerateInput, type ArtifactImageGenerateResult, type ArtifactImageRegion, } from './artifact-images.js';
|
|
17
15
|
export { isTerminalImageGenerationError } from './image-generation-errors.js';
|
|
18
|
-
export { describeArtifact, summarizeArtifact, type ArtifactChessMoveView, type ArtifactChessView, type ArtifactFormChangeView, type ArtifactFormFieldView, type ArtifactFormView, type ArtifactImageVariantView, type ArtifactImageView, type ArtifactPrincipalView, type ArtifactView, type ArtifactViewOptions, } from './artifact-views.js';
|
|
19
|
-
export { reduceArtifactRecord, replayArtifactPage, artifactCommandConflicts, artifactFormConflicts, type ArtifactConflict } from './artifact-reducer.js';
|
|
20
|
-
export type { ArtifactAsset, ArtifactChessMove, ArtifactChessPlayers, ArtifactChessState, ArtifactCommand, ArtifactCommandBody, ArtifactCommandRecord, ArtifactContext, ArtifactDefinition, ArtifactDomainOutcome, ArtifactFormChange, ArtifactFormColumn, ArtifactFormField, ArtifactFormFieldRemoval, ArtifactFormRow, ArtifactFormState, ArtifactFormTable, ArtifactFormValue, ArtifactImageState, ArtifactImageVariant, ArtifactJson, ArtifactKind, ArtifactOutcomeCode, ArtifactReadResult, ArtifactReference, ArtifactSelection, ArtifactSnapshot, } from '../backend-contracts/index.js';
|
|
21
16
|
export { eraseEndpointPlaintext } from './retention.js';
|
|
22
17
|
export type { EndpointOperationRequest, EndpointOperationReceipt, EndpointOperationError, EndpointPreconditions, EndpointEvent, EndpointQueryRequest, EndpointQueryResponse, } from '../backend-contracts/index.js';
|
|
23
18
|
export { CANON_ENDPOINT_PROTOCOL } from '../backend-contracts/index.js';
|