@canonmsg/backend-contracts 5.0.0 → 5.2.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/README.md +3 -1
- package/dist/accessPolicy.d.ts +9 -0
- package/dist/accessPolicy.js +12 -0
- package/dist/agentBehaviorPolicy.d.ts +86 -15
- package/dist/agentBehaviorPolicy.js +103 -17
- package/dist/agentSearch.d.ts +17 -0
- package/dist/agentSearch.js +58 -0
- package/dist/canon-verb-wire.schema.json +4 -2
- package/dist/canon-verbs.limits.json +2 -1
- package/dist/canon-verbs.schema.json +34 -0
- package/dist/cjs/accessPolicy.js +15 -0
- package/dist/cjs/agentBehaviorPolicy.js +104 -17
- package/dist/cjs/agentSearch.js +64 -0
- package/dist/cjs/contactSources.js +45 -0
- package/dist/cjs/firestoreValues.js +27 -0
- package/dist/cjs/index.js +6 -0
- package/dist/cjs/moderation.js +12 -0
- package/dist/cjs/runtimeCardFields.js +30 -1
- package/dist/cjs/selfContext.js +33 -0
- package/dist/cjs/verbContract.js +18 -2
- package/dist/cjs/verbSchemas.js +26 -0
- package/dist/cjs/verbWire.js +8 -0
- package/dist/contactSources.d.ts +31 -0
- package/dist/contactSources.js +41 -0
- package/dist/firestoreValues.d.ts +9 -0
- package/dist/firestoreValues.js +23 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/moderation.d.ts +7 -0
- package/dist/moderation.js +9 -0
- package/dist/runtimeCardFields.d.ts +14 -2
- package/dist/runtimeCardFields.js +29 -0
- package/dist/selfContext.d.ts +9 -0
- package/dist/selfContext.js +29 -0
- package/dist/verbContract.d.ts +35 -2
- package/dist/verbContract.js +17 -1
- package/dist/verbSchemas.d.ts +32 -0
- package/dist/verbSchemas.js +26 -0
- package/dist/verbWire.d.ts +2 -2
- package/dist/verbWire.js +8 -0
- package/package.json +2 -2
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Normalizers for values read straight off a Firestore document. Callers pass
|
|
2
|
+
// plain doc-shaped data, never a Firestore handle — this package holds no I/O.
|
|
3
|
+
/** Trimmed string, or null when absent/empty. */
|
|
4
|
+
export function normalizeStoredString(value) {
|
|
5
|
+
if (typeof value !== 'string')
|
|
6
|
+
return null;
|
|
7
|
+
const trimmed = value.trim();
|
|
8
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Firestore Timestamp-like -> ISO 8601, or null. Accepts only objects exposing
|
|
12
|
+
* `toDate()`. A raw `Date` is deliberately NOT accepted: that matches both call
|
|
13
|
+
* sites this replaced. `message.ts` and `contactRequest.ts` keep their own
|
|
14
|
+
* Date-tolerant normalizers — a different contract, not this one.
|
|
15
|
+
*/
|
|
16
|
+
export function firestoreTimestampToISOString(value) {
|
|
17
|
+
if (!value || typeof value !== 'object')
|
|
18
|
+
return null;
|
|
19
|
+
const maybeTimestamp = value;
|
|
20
|
+
if (typeof maybeTimestamp.toDate !== 'function')
|
|
21
|
+
return null;
|
|
22
|
+
return maybeTimestamp.toDate().toISOString();
|
|
23
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,13 @@ export * from './runtimeCardFields.js';
|
|
|
6
6
|
export * from './runtimeCardStorage.js';
|
|
7
7
|
export * from './turnProtocol.js';
|
|
8
8
|
export * from './agentBehaviorPolicy.js';
|
|
9
|
+
export * from './agentSearch.js';
|
|
9
10
|
export * from './contactRequest.js';
|
|
11
|
+
export * from './contactSources.js';
|
|
10
12
|
export * from './verbContract.js';
|
|
11
13
|
export * from './verbSchemas.js';
|
|
12
14
|
export * from './verbWire.js';
|
|
15
|
+
export * from './accessPolicy.js';
|
|
16
|
+
export * from './firestoreValues.js';
|
|
17
|
+
export * from './moderation.js';
|
|
18
|
+
export * from './selfContext.js';
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,13 @@ export * from './runtimeCardFields.js';
|
|
|
6
6
|
export * from './runtimeCardStorage.js';
|
|
7
7
|
export * from './turnProtocol.js';
|
|
8
8
|
export * from './agentBehaviorPolicy.js';
|
|
9
|
+
export * from './agentSearch.js';
|
|
9
10
|
export * from './contactRequest.js';
|
|
11
|
+
export * from './contactSources.js';
|
|
10
12
|
export * from './verbContract.js';
|
|
11
13
|
export * from './verbSchemas.js';
|
|
12
14
|
export * from './verbWire.js';
|
|
15
|
+
export * from './accessPolicy.js';
|
|
16
|
+
export * from './firestoreValues.js';
|
|
17
|
+
export * from './moderation.js';
|
|
18
|
+
export * from './selfContext.js';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type ModerationStatus = 'active' | 'ejected';
|
|
2
|
+
/**
|
|
3
|
+
* The single definition of "this account is ejected", read off an
|
|
4
|
+
* already-fetched `moderationUsers/{id}` document. A missing document reads
|
|
5
|
+
* 'active'. Fetching is the caller's job — this package holds no Firestore handle.
|
|
6
|
+
*/
|
|
7
|
+
export declare function readModerationStatus(data: unknown): ModerationStatus;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single definition of "this account is ejected", read off an
|
|
3
|
+
* already-fetched `moderationUsers/{id}` document. A missing document reads
|
|
4
|
+
* 'active'. Fetching is the caller's job — this package holds no Firestore handle.
|
|
5
|
+
*/
|
|
6
|
+
export function readModerationStatus(data) {
|
|
7
|
+
const record = data;
|
|
8
|
+
return record?.status === 'ejected' ? 'ejected' : 'active';
|
|
9
|
+
}
|
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Canonical `canon.card.v1` action-field type vocabulary. The runtime array is
|
|
3
|
+
* the single source of truth and the type is derived from it, so a value and a
|
|
4
|
+
* type cannot drift.
|
|
5
|
+
*
|
|
6
|
+
* ORDER IS LOAD-BEARING: scripts/generate-skill-bundles.mjs renders this list
|
|
7
|
+
* verbatim (via @canonmsg/rich-cards) into two committed SKILL.md files, and
|
|
8
|
+
* `npm run check:skill-bundles` fails on a byte change.
|
|
9
|
+
*/
|
|
10
|
+
export declare const RUNTIME_CARD_FIELD_TYPES: readonly ["text", "textarea", "select", "multiSelect", "boolean", "date", "number", "currency", "searchSelect", "lineItems"];
|
|
11
|
+
export type RuntimeCardFieldType = (typeof RUNTIME_CARD_FIELD_TYPES)[number];
|
|
2
12
|
/**
|
|
3
13
|
* Caps shared across runtime-card normalizers, response validation, and
|
|
4
14
|
* authoring tools. Keep these backend-safe so Functions can import them.
|
|
@@ -15,7 +25,9 @@ export interface RuntimeCardFieldChoice {
|
|
|
15
25
|
description?: string;
|
|
16
26
|
preview?: string;
|
|
17
27
|
}
|
|
18
|
-
|
|
28
|
+
/** Column cell types allowed inside a `lineItems` field. */
|
|
29
|
+
export declare const RUNTIME_CARD_LINE_ITEM_COLUMN_TYPES: readonly ["text", "number", "currency", "date", "select"];
|
|
30
|
+
export type RuntimeCardLineItemColumnType = (typeof RUNTIME_CARD_LINE_ITEM_COLUMN_TYPES)[number];
|
|
19
31
|
export interface RuntimeCardLineItemColumn {
|
|
20
32
|
id: string;
|
|
21
33
|
label: string;
|
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical `canon.card.v1` action-field type vocabulary. The runtime array is
|
|
3
|
+
* the single source of truth and the type is derived from it, so a value and a
|
|
4
|
+
* type cannot drift.
|
|
5
|
+
*
|
|
6
|
+
* ORDER IS LOAD-BEARING: scripts/generate-skill-bundles.mjs renders this list
|
|
7
|
+
* verbatim (via @canonmsg/rich-cards) into two committed SKILL.md files, and
|
|
8
|
+
* `npm run check:skill-bundles` fails on a byte change.
|
|
9
|
+
*/
|
|
10
|
+
export const RUNTIME_CARD_FIELD_TYPES = [
|
|
11
|
+
'text',
|
|
12
|
+
'textarea',
|
|
13
|
+
'select',
|
|
14
|
+
'multiSelect',
|
|
15
|
+
'boolean',
|
|
16
|
+
'date',
|
|
17
|
+
'number',
|
|
18
|
+
'currency',
|
|
19
|
+
'searchSelect',
|
|
20
|
+
'lineItems',
|
|
21
|
+
];
|
|
1
22
|
/**
|
|
2
23
|
* Caps shared across runtime-card normalizers, response validation, and
|
|
3
24
|
* authoring tools. Keep these backend-safe so Functions can import them.
|
|
@@ -8,6 +29,14 @@ export const RUNTIME_CARD_LIMITS = {
|
|
|
8
29
|
lineItemColumns: 8,
|
|
9
30
|
searchSelectChoices: 100,
|
|
10
31
|
};
|
|
32
|
+
/** Column cell types allowed inside a `lineItems` field. */
|
|
33
|
+
export const RUNTIME_CARD_LINE_ITEM_COLUMN_TYPES = [
|
|
34
|
+
'text',
|
|
35
|
+
'number',
|
|
36
|
+
'currency',
|
|
37
|
+
'date',
|
|
38
|
+
'select',
|
|
39
|
+
];
|
|
11
40
|
const ISO_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
|
|
12
41
|
function isRecord(value) {
|
|
13
42
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Stored self-context id, or null when absent, empty, or path-like. */
|
|
2
|
+
export declare function normalizeStoredSelfContextId(value: unknown): string | null;
|
|
3
|
+
/**
|
|
4
|
+
* Agent-facing projection of an `agentSelfContexts` document; null for anything
|
|
5
|
+
* that is not a usable cross-session context. Ownership and conversation
|
|
6
|
+
* scoping stay with the CALLER — both consumers check them against their own
|
|
7
|
+
* Firestore handle before calling this.
|
|
8
|
+
*/
|
|
9
|
+
export declare function serializeSelfContext(id: string, data: Record<string, unknown>): Record<string, unknown> | null;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { SELF_CONTEXT_TYPE } from './verbContract.js';
|
|
2
|
+
import { firestoreTimestampToISOString, normalizeStoredString } from './firestoreValues.js';
|
|
3
|
+
/** Stored self-context id, or null when absent, empty, or path-like. */
|
|
4
|
+
export function normalizeStoredSelfContextId(value) {
|
|
5
|
+
const id = normalizeStoredString(value);
|
|
6
|
+
if (!id || id.includes('/'))
|
|
7
|
+
return null;
|
|
8
|
+
return id;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Agent-facing projection of an `agentSelfContexts` document; null for anything
|
|
12
|
+
* that is not a usable cross-session context. Ownership and conversation
|
|
13
|
+
* scoping stay with the CALLER — both consumers check them against their own
|
|
14
|
+
* Firestore handle before calling this.
|
|
15
|
+
*/
|
|
16
|
+
export function serializeSelfContext(id, data) {
|
|
17
|
+
if (data.type !== SELF_CONTEXT_TYPE)
|
|
18
|
+
return null;
|
|
19
|
+
const context = normalizeStoredString(data.context);
|
|
20
|
+
if (!context)
|
|
21
|
+
return null;
|
|
22
|
+
return {
|
|
23
|
+
id,
|
|
24
|
+
type: SELF_CONTEXT_TYPE,
|
|
25
|
+
context,
|
|
26
|
+
createdAt: firestoreTimestampToISOString(data.createdAt),
|
|
27
|
+
updatedAt: firestoreTimestampToISOString(data.updatedAt),
|
|
28
|
+
};
|
|
29
|
+
}
|
package/dist/verbContract.d.ts
CHANGED
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
*
|
|
16
16
|
* Deliberately NOT verbs: replying in the active conversation, streaming
|
|
17
17
|
* partials, typing, and read receipts stay host-mediated — the model talks
|
|
18
|
-
* and the platform delivers.
|
|
18
|
+
* and the platform delivers. `no_reply` is the deliberate exception: it is the
|
|
19
|
+
* ABSENCE of a reply, and only an intent can express that — silence has no
|
|
20
|
+
* host-mediated channel of its own. Still out of scope pending their own design
|
|
19
21
|
* pass: plan approval (the fourth runtime-interaction kind — coding-host
|
|
20
22
|
* concern today) and block/mute. Their REST surfaces remain directly
|
|
21
23
|
* callable.
|
|
@@ -159,6 +161,12 @@ export declare const VERB_LIMITS: {
|
|
|
159
161
|
* CREATE does not length-check today — treat as the authoring contract).
|
|
160
162
|
*/
|
|
161
163
|
readonly groupNameChars: 100;
|
|
164
|
+
/**
|
|
165
|
+
* `no_reply.reason` authoring cap. There is no server enforcement beyond the
|
|
166
|
+
* intent schema — the handler logs the reason's presence and nothing else —
|
|
167
|
+
* so this constant is the canonical figure.
|
|
168
|
+
*/
|
|
169
|
+
readonly noReplyReasonChars: 500;
|
|
162
170
|
};
|
|
163
171
|
/**
|
|
164
172
|
* Sender-side rate limits enforced by POST /messages/send
|
|
@@ -173,7 +181,7 @@ export declare const VERB_RATE_LIMITS: {
|
|
|
173
181
|
/** The one self-context type the platform accepts today. */
|
|
174
182
|
export declare const SELF_CONTEXT_TYPE = "cross_session";
|
|
175
183
|
/** Canonical verb names. */
|
|
176
|
-
export declare const CANON_VERB_NAMES: readonly ["send_to", "request_input", "request_approval", "check_approval", "send_card", "request_card", "share_contact", "react", "forward", "create_group", "add_member", "remove_member", "leave_conversation", "list_contacts", "list_contact_requests", "list_conversations"];
|
|
184
|
+
export declare const CANON_VERB_NAMES: readonly ["send_to", "request_input", "request_approval", "check_approval", "send_card", "request_card", "share_contact", "react", "forward", "create_group", "add_member", "remove_member", "leave_conversation", "list_contacts", "list_contact_requests", "list_conversations", "no_reply"];
|
|
177
185
|
export type CanonVerbName = (typeof CANON_VERB_NAMES)[number];
|
|
178
186
|
/** Private note-to-self attached to a cross-conversation send. */
|
|
179
187
|
export interface VerbSelfContext {
|
|
@@ -692,6 +700,25 @@ export interface VerbConversationSummary {
|
|
|
692
700
|
export interface ListConversationsResult {
|
|
693
701
|
conversations: VerbConversationSummary[];
|
|
694
702
|
}
|
|
703
|
+
/** Deliberate silence: end the turn without posting anything. */
|
|
704
|
+
export interface NoReplyInput {
|
|
705
|
+
/** Bindings default this to the active conversation when they have one. */
|
|
706
|
+
conversationId?: string;
|
|
707
|
+
/** Private rationale — logged only, never rendered. <= noReplyReasonChars. */
|
|
708
|
+
reason?: string;
|
|
709
|
+
}
|
|
710
|
+
export interface NoReplyResult {
|
|
711
|
+
status: 'acknowledged';
|
|
712
|
+
conversationId?: string;
|
|
713
|
+
note?: string;
|
|
714
|
+
}
|
|
715
|
+
/**
|
|
716
|
+
* The `note` the server returns on a `no_reply` ack — the model's closure
|
|
717
|
+
* sentence. It lives here, not in a host, because every binding surfaces the
|
|
718
|
+
* server's result verbatim and a runtime that answers `no_reply` locally must
|
|
719
|
+
* say the same thing.
|
|
720
|
+
*/
|
|
721
|
+
export declare const NO_REPLY_ACK_NOTE = "Acknowledged \u2014 nothing was posted to the conversation.";
|
|
695
722
|
/** Flat tool name for a verb on namespaced tool surfaces (e.g. `canon_send_to`). */
|
|
696
723
|
export declare function canonVerbToolName(verb: CanonVerbName): string;
|
|
697
724
|
export interface VerbLimitViolation {
|
|
@@ -791,6 +818,12 @@ export declare const CANON_VERB_LIMITS_ARTIFACT: {
|
|
|
791
818
|
* CREATE does not length-check today — treat as the authoring contract).
|
|
792
819
|
*/
|
|
793
820
|
readonly groupNameChars: 100;
|
|
821
|
+
/**
|
|
822
|
+
* `no_reply.reason` authoring cap. There is no server enforcement beyond the
|
|
823
|
+
* intent schema — the handler logs the reason's presence and nothing else —
|
|
824
|
+
* so this constant is the canonical figure.
|
|
825
|
+
*/
|
|
826
|
+
readonly noReplyReasonChars: 500;
|
|
794
827
|
};
|
|
795
828
|
readonly rateLimits: {
|
|
796
829
|
readonly senderMessagesPer5Min: 300;
|
package/dist/verbContract.js
CHANGED
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
*
|
|
16
16
|
* Deliberately NOT verbs: replying in the active conversation, streaming
|
|
17
17
|
* partials, typing, and read receipts stay host-mediated — the model talks
|
|
18
|
-
* and the platform delivers.
|
|
18
|
+
* and the platform delivers. `no_reply` is the deliberate exception: it is the
|
|
19
|
+
* ABSENCE of a reply, and only an intent can express that — silence has no
|
|
20
|
+
* host-mediated channel of its own. Still out of scope pending their own design
|
|
19
21
|
* pass: plan approval (the fourth runtime-interaction kind — coding-host
|
|
20
22
|
* concern today) and block/mute. Their REST surfaces remain directly
|
|
21
23
|
* callable.
|
|
@@ -159,6 +161,12 @@ export const VERB_LIMITS = {
|
|
|
159
161
|
* CREATE does not length-check today — treat as the authoring contract).
|
|
160
162
|
*/
|
|
161
163
|
groupNameChars: 100,
|
|
164
|
+
/**
|
|
165
|
+
* `no_reply.reason` authoring cap. There is no server enforcement beyond the
|
|
166
|
+
* intent schema — the handler logs the reason's presence and nothing else —
|
|
167
|
+
* so this constant is the canonical figure.
|
|
168
|
+
*/
|
|
169
|
+
noReplyReasonChars: 500,
|
|
162
170
|
};
|
|
163
171
|
/**
|
|
164
172
|
* Sender-side rate limits enforced by POST /messages/send
|
|
@@ -190,6 +198,7 @@ export const CANON_VERB_NAMES = [
|
|
|
190
198
|
'list_contacts',
|
|
191
199
|
'list_contact_requests',
|
|
192
200
|
'list_conversations',
|
|
201
|
+
'no_reply',
|
|
193
202
|
];
|
|
194
203
|
export const VERB_NATIVE_METADATA_KEYS = [
|
|
195
204
|
'runtime',
|
|
@@ -265,6 +274,13 @@ export const CREATE_GROUP_NO_ADDABLE_MEMBERS_CODE = 'CREATE_GROUP_NO_ADDABLE_MEM
|
|
|
265
274
|
* creates the group from the app instead).
|
|
266
275
|
*/
|
|
267
276
|
export const CREATE_GROUP_CREATOR_SETUP_REQUIRED_CODE = 'CREATE_GROUP_CREATOR_SETUP_REQUIRED';
|
|
277
|
+
/**
|
|
278
|
+
* The `note` the server returns on a `no_reply` ack — the model's closure
|
|
279
|
+
* sentence. It lives here, not in a host, because every binding surfaces the
|
|
280
|
+
* server's result verbatim and a runtime that answers `no_reply` locally must
|
|
281
|
+
* say the same thing.
|
|
282
|
+
*/
|
|
283
|
+
export const NO_REPLY_ACK_NOTE = 'Acknowledged — nothing was posted to the conversation.';
|
|
268
284
|
/** Flat tool name for a verb on namespaced tool surfaces (e.g. `canon_send_to`). */
|
|
269
285
|
export function canonVerbToolName(verb) {
|
|
270
286
|
return `${CANON_VERB_NAMESPACE}_${verb}`;
|
package/dist/verbSchemas.d.ts
CHANGED
|
@@ -1700,6 +1700,38 @@ export declare const CANON_VERBS_JSON_SCHEMA: {
|
|
|
1700
1700
|
};
|
|
1701
1701
|
};
|
|
1702
1702
|
};
|
|
1703
|
+
readonly no_reply_input: {
|
|
1704
|
+
readonly type: "object";
|
|
1705
|
+
readonly description: string;
|
|
1706
|
+
readonly additionalProperties: false;
|
|
1707
|
+
readonly properties: {
|
|
1708
|
+
readonly conversationId: {
|
|
1709
|
+
readonly type: "string";
|
|
1710
|
+
readonly pattern: "^[A-Za-z0-9_.:-]{1,160}$";
|
|
1711
|
+
};
|
|
1712
|
+
readonly reason: {
|
|
1713
|
+
readonly type: "string";
|
|
1714
|
+
readonly maxLength: 500;
|
|
1715
|
+
readonly description: "Never rendered; logged only.";
|
|
1716
|
+
};
|
|
1717
|
+
};
|
|
1718
|
+
};
|
|
1719
|
+
readonly no_reply_result: {
|
|
1720
|
+
readonly type: "object";
|
|
1721
|
+
readonly required: readonly ["status"];
|
|
1722
|
+
readonly additionalProperties: true;
|
|
1723
|
+
readonly properties: {
|
|
1724
|
+
readonly status: {
|
|
1725
|
+
readonly const: "acknowledged";
|
|
1726
|
+
};
|
|
1727
|
+
readonly conversationId: {
|
|
1728
|
+
readonly type: "string";
|
|
1729
|
+
};
|
|
1730
|
+
readonly note: {
|
|
1731
|
+
readonly type: "string";
|
|
1732
|
+
};
|
|
1733
|
+
};
|
|
1734
|
+
};
|
|
1703
1735
|
};
|
|
1704
1736
|
};
|
|
1705
1737
|
/** Pointer pair into the bundle for one verb. */
|
package/dist/verbSchemas.js
CHANGED
|
@@ -1053,6 +1053,30 @@ const list_conversations_result = {
|
|
|
1053
1053
|
},
|
|
1054
1054
|
},
|
|
1055
1055
|
};
|
|
1056
|
+
const no_reply_input = {
|
|
1057
|
+
type: 'object',
|
|
1058
|
+
description: 'End this turn without posting anything to the conversation. Nothing is '
|
|
1059
|
+
+ 'rendered and no other member or agent is triggered.',
|
|
1060
|
+
additionalProperties: false,
|
|
1061
|
+
properties: {
|
|
1062
|
+
conversationId: { type: 'string', pattern: VERB_ID_PATTERNS.runtimeId },
|
|
1063
|
+
reason: {
|
|
1064
|
+
type: 'string',
|
|
1065
|
+
maxLength: VERB_LIMITS.noReplyReasonChars,
|
|
1066
|
+
description: 'Never rendered; logged only.',
|
|
1067
|
+
},
|
|
1068
|
+
},
|
|
1069
|
+
};
|
|
1070
|
+
const no_reply_result = {
|
|
1071
|
+
type: 'object',
|
|
1072
|
+
required: ['status'],
|
|
1073
|
+
additionalProperties: true,
|
|
1074
|
+
properties: {
|
|
1075
|
+
status: { const: 'acknowledged' },
|
|
1076
|
+
conversationId: { type: 'string' },
|
|
1077
|
+
note: { type: 'string' },
|
|
1078
|
+
},
|
|
1079
|
+
};
|
|
1056
1080
|
// ---------------------------------------------------------------------------
|
|
1057
1081
|
// Bundle
|
|
1058
1082
|
// ---------------------------------------------------------------------------
|
|
@@ -1111,6 +1135,8 @@ export const CANON_VERBS_JSON_SCHEMA = {
|
|
|
1111
1135
|
list_contact_requests_result,
|
|
1112
1136
|
list_conversations_input,
|
|
1113
1137
|
list_conversations_result,
|
|
1138
|
+
no_reply_input,
|
|
1139
|
+
no_reply_result,
|
|
1114
1140
|
},
|
|
1115
1141
|
};
|
|
1116
1142
|
export const CANON_VERB_SCHEMA_REFS = Object.fromEntries(CANON_VERB_NAMES.map((name) => [
|
package/dist/verbWire.d.ts
CHANGED
|
@@ -137,7 +137,7 @@ export declare const CANON_VERB_WIRE_JSON_SCHEMA: {
|
|
|
137
137
|
readonly const: "canon.verb-wire.v1";
|
|
138
138
|
};
|
|
139
139
|
readonly verb: {
|
|
140
|
-
readonly enum: readonly ["send_to", "request_input", "request_approval", "check_approval", "send_card", "request_card", "share_contact", "react", "forward", "create_group", "add_member", "remove_member", "leave_conversation", "list_contacts", "list_contact_requests", "list_conversations"];
|
|
140
|
+
readonly enum: readonly ["send_to", "request_input", "request_approval", "check_approval", "send_card", "request_card", "share_contact", "react", "forward", "create_group", "add_member", "remove_member", "leave_conversation", "list_contacts", "list_contact_requests", "list_conversations", "no_reply"];
|
|
141
141
|
};
|
|
142
142
|
readonly envelope: {
|
|
143
143
|
readonly $ref: "#/$defs/envelope";
|
|
@@ -509,7 +509,7 @@ export declare const CANON_VERB_WIRE_JSON_SCHEMA: {
|
|
|
509
509
|
readonly const: "canon.verb-wire.v1";
|
|
510
510
|
};
|
|
511
511
|
readonly verb: {
|
|
512
|
-
readonly enum: readonly ["send_to", "request_input", "request_approval", "check_approval", "send_card", "request_card", "share_contact", "react", "forward", "create_group", "add_member", "remove_member", "leave_conversation", "list_contacts", "list_contact_requests", "list_conversations"];
|
|
512
|
+
readonly enum: readonly ["send_to", "request_input", "request_approval", "check_approval", "send_card", "request_card", "share_contact", "react", "forward", "create_group", "add_member", "remove_member", "leave_conversation", "list_contacts", "list_contact_requests", "list_conversations", "no_reply"];
|
|
513
513
|
};
|
|
514
514
|
readonly result: {
|
|
515
515
|
readonly $ref: "#/$defs/body";
|
package/dist/verbWire.js
CHANGED
|
@@ -112,6 +112,7 @@ export const VERB_WIRE_ENVELOPE_FIELDS = {
|
|
|
112
112
|
list_contacts: { required: [], optional: [] },
|
|
113
113
|
list_contact_requests: { required: [], optional: [] },
|
|
114
114
|
list_conversations: { required: [], optional: ['limit'] },
|
|
115
|
+
no_reply: { required: [], optional: ['conversationId'] },
|
|
115
116
|
};
|
|
116
117
|
// ---------------------------------------------------------------------------
|
|
117
118
|
// JSON Schema
|
|
@@ -470,6 +471,11 @@ export function projectVerbIntentToWire(verb, intent, options) {
|
|
|
470
471
|
envelope = compact({ limit: input.limit });
|
|
471
472
|
break;
|
|
472
473
|
}
|
|
474
|
+
case 'no_reply': {
|
|
475
|
+
envelope = compact({ conversationId: input.conversationId });
|
|
476
|
+
value = compact({ reason: input.reason });
|
|
477
|
+
break;
|
|
478
|
+
}
|
|
473
479
|
}
|
|
474
480
|
return {
|
|
475
481
|
wire: CANON_VERB_WIRE_SCHEMA_VERSION,
|
|
@@ -607,6 +613,8 @@ export function mergeVerbWireToIntent(request) {
|
|
|
607
613
|
return {};
|
|
608
614
|
case 'list_conversations':
|
|
609
615
|
return compact({ limit: envelope.limit });
|
|
616
|
+
case 'no_reply':
|
|
617
|
+
return compact({ conversationId: envelope.conversationId, reason: value.reason });
|
|
610
618
|
}
|
|
611
619
|
}
|
|
612
620
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonmsg/backend-contracts",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.2.0",
|
|
4
4
|
"description": "Canon backend contract helpers shared by Functions and stream-service",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/cjs/index.js",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"access": "public"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@canonmsg/rich-cards": "^0.
|
|
46
|
+
"@canonmsg/rich-cards": "^0.9.1",
|
|
47
47
|
"@types/node": "^22.0.0",
|
|
48
48
|
"ajv": "^8.20.0",
|
|
49
49
|
"typescript": "~5.7.0",
|