@oneie/sdk 0.13.2 → 0.13.4
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/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/receivers.d.ts +755 -0
- package/dist/receivers.d.ts.map +1 -1
- package/dist/receivers.js +606 -0
- package/dist/receivers.js.map +1 -1
- package/dist/templates.d.ts +4 -0
- package/dist/templates.d.ts.map +1 -0
- package/dist/templates.js +154 -0
- package/dist/templates.js.map +1 -0
- package/dist/types.d.ts +174 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +25 -0
- package/dist/types.js.map +1 -1
- package/package.json +5 -1
package/dist/receivers.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { AgentActionResponseSchema, AgentStatusResponseSchema, CapabilityItemSchema, PayResponseSchema, RegisterResponseSchema, StatsSchema, StepKind, WorkflowDiffSchema, } from "./schemas.js";
|
|
3
|
+
import { ResourceTypeSchema } from "./types.js";
|
|
3
4
|
/**
|
|
4
5
|
* Declare a receiver contract. Identity at runtime — its only job is to pin the
|
|
5
6
|
* `Req`/`Res` generics so the catalog infers payload + outcome types.
|
|
@@ -197,6 +198,22 @@ export const RECEIVERS = {
|
|
|
197
198
|
request: z.object({ aid: z.string(), name: z.string().optional(), tags: z.array(z.string()).optional(), prompt: z.string().optional(), model: z.string().optional() }),
|
|
198
199
|
response: ok, effect: "ask", auth: "manage_actors",
|
|
199
200
|
}),
|
|
201
|
+
"visitor:promote": receiver({
|
|
202
|
+
receiver: "visitor:promote",
|
|
203
|
+
summary: "Promote a tracked anonymous visitor to a TypeDB actor (anon:<hash12>) so it surfaces in People; binds rung-1 visitor_hash→aid. Idempotent.",
|
|
204
|
+
request: z.object({ visitorHash: z.string() }),
|
|
205
|
+
response: z.object({
|
|
206
|
+
ok: z.boolean(),
|
|
207
|
+
aid: z.string().optional(),
|
|
208
|
+
promoted: z.boolean().optional(),
|
|
209
|
+
region: z.string().optional(),
|
|
210
|
+
reason: z.string().optional(),
|
|
211
|
+
}),
|
|
212
|
+
effect: "ask",
|
|
213
|
+
auth: "manage_actors",
|
|
214
|
+
idempotent: true,
|
|
215
|
+
examples: [{ visitorHash: "9f2a1c7b4e0d8a3f5c6b" }],
|
|
216
|
+
}),
|
|
200
217
|
"world:update-contact": receiver({
|
|
201
218
|
receiver: "world:update-contact",
|
|
202
219
|
summary: "Update an actor's contact/profile attributes — identity, contact details, professional, personal, CRM metrics",
|
|
@@ -279,6 +296,12 @@ export const RECEIVERS = {
|
|
|
279
296
|
summary: "Revoke an API key",
|
|
280
297
|
request: z.object({ keyId: z.string() }), response: ok, effect: "ask", auth: "member", reversible: false,
|
|
281
298
|
}),
|
|
299
|
+
"world:declare-types": receiver({
|
|
300
|
+
receiver: "world:declare-types",
|
|
301
|
+
summary: "Persist a resource-type manifest for the caller's workspace; pass a template name (e.g. ecommerce) to seed from a built-in, or explicit types",
|
|
302
|
+
request: z.object({ group: z.string(), types: z.array(ResourceTypeSchema).optional(), template: z.string().optional() }),
|
|
303
|
+
response: z.object({ ok: z.literal(true), count: z.number() }), effect: "ask", auth: "manage_things",
|
|
304
|
+
}),
|
|
282
305
|
"world:create-thing": receiver({
|
|
283
306
|
receiver: "world:create-thing",
|
|
284
307
|
summary: "Create a thing (skill, token, product) in the world",
|
|
@@ -296,6 +319,13 @@ export const RECEIVERS = {
|
|
|
296
319
|
summary: "Delete a thing",
|
|
297
320
|
request: z.object({ tid: z.string() }), response: ok, effect: "ask", auth: "manage_things", reversible: false,
|
|
298
321
|
}),
|
|
322
|
+
"world:list-things": receiver({
|
|
323
|
+
receiver: "world:list-things",
|
|
324
|
+
summary: "List things of a given type in a workspace — used by relation-field pickers",
|
|
325
|
+
request: z.object({ group: z.string(), type: z.string() }),
|
|
326
|
+
response: z.object({ items: z.array(z.object({ tid: z.string(), name: z.string() })) }),
|
|
327
|
+
effect: "ask", auth: "member", cost: "free", idempotent: true,
|
|
328
|
+
}),
|
|
299
329
|
"world:freeze-path": receiver({
|
|
300
330
|
receiver: "world:freeze-path",
|
|
301
331
|
summary: "Freeze a path so decay cannot weaken it",
|
|
@@ -740,6 +770,16 @@ export const RECEIVERS = {
|
|
|
740
770
|
}),
|
|
741
771
|
effect: "ask", cost: "free", idempotent: true,
|
|
742
772
|
}),
|
|
773
|
+
"meta:types": receiver({
|
|
774
|
+
receiver: "meta:types",
|
|
775
|
+
summary: "Read the resource-type manifest for the caller's workspace, plus the built-in industry templates",
|
|
776
|
+
request: z.object({}),
|
|
777
|
+
response: z.object({
|
|
778
|
+
types: z.array(ResourceTypeSchema),
|
|
779
|
+
templates: z.record(z.string(), z.array(ResourceTypeSchema)),
|
|
780
|
+
}),
|
|
781
|
+
effect: "ask", cost: "free", idempotent: true,
|
|
782
|
+
}),
|
|
743
783
|
// ── actor discovery + messaging ──────────────────────────────────────────
|
|
744
784
|
"actors:find": receiver({
|
|
745
785
|
receiver: "actors:find",
|
|
@@ -764,6 +804,130 @@ export const RECEIVERS = {
|
|
|
764
804
|
response: z.object({ ok: z.boolean(), id: z.string().optional(), ts: z.number().optional(), to: z.string().optional(), from: z.string().optional(), error: z.string().optional() }),
|
|
765
805
|
effect: "ask", idempotent: false,
|
|
766
806
|
}),
|
|
807
|
+
"notify": receiver({
|
|
808
|
+
receiver: "notify",
|
|
809
|
+
summary: "Notify any actor (human or agent) by uid — channels routes the door (Telegram/Discord/peer inbox), mirrors into the web inbox, and nudges an open client live. One verb, both actor kinds.",
|
|
810
|
+
request: z.object({
|
|
811
|
+
receiver: z.string(),
|
|
812
|
+
kind: z.string().optional(),
|
|
813
|
+
body: z.union([z.string(), z.record(z.string(), z.unknown())]).optional(),
|
|
814
|
+
content: z.string().optional(),
|
|
815
|
+
}),
|
|
816
|
+
response: z.object({
|
|
817
|
+
ok: z.boolean(),
|
|
818
|
+
id: z.string().optional(),
|
|
819
|
+
ts: z.number().optional(),
|
|
820
|
+
to: z.string().optional(),
|
|
821
|
+
from: z.string().optional(),
|
|
822
|
+
kind: z.string().optional(),
|
|
823
|
+
delivered: z.array(z.string()).optional(),
|
|
824
|
+
error: z.string().optional(),
|
|
825
|
+
}),
|
|
826
|
+
effect: "ask", idempotent: false,
|
|
827
|
+
}),
|
|
828
|
+
"notify:count": receiver({
|
|
829
|
+
receiver: "notify:count",
|
|
830
|
+
summary: "Unread thread count for the caller's inbox (a thread is unread when its last message is newer than the caller's read marker).",
|
|
831
|
+
request: z.object({}),
|
|
832
|
+
response: z.object({ unread: z.number() }),
|
|
833
|
+
effect: "ask", idempotent: true,
|
|
834
|
+
}),
|
|
835
|
+
"notify:list": receiver({
|
|
836
|
+
receiver: "notify:list",
|
|
837
|
+
summary: "The caller's unread threads, newest first, each with a short preview.",
|
|
838
|
+
request: z.object({ limit: z.number().optional() }),
|
|
839
|
+
response: z.object({ unread: z.array(z.object({ id: z.string(), ts: z.number(), preview: z.string() })) }),
|
|
840
|
+
effect: "ask", idempotent: true,
|
|
841
|
+
}),
|
|
842
|
+
"notify:read": receiver({
|
|
843
|
+
receiver: "notify:read",
|
|
844
|
+
summary: "Mark one thread (threadId) or all of the caller's threads (all:true) as read; nudges the inbox live.",
|
|
845
|
+
request: z.object({ threadId: z.string().optional(), id: z.string().optional(), all: z.boolean().optional() }),
|
|
846
|
+
response: z.object({ ok: z.boolean(), ts: z.number().optional(), error: z.string().optional() }),
|
|
847
|
+
effect: "ask", idempotent: true,
|
|
848
|
+
}),
|
|
849
|
+
"thread:append": receiver({
|
|
850
|
+
receiver: "thread:append",
|
|
851
|
+
summary: "Gateway-callable write into web threads — carries tags into entity_tags so slug/in renders every channel by tag. Called by the channels bridge after every inbound signal.",
|
|
852
|
+
request: z.object({
|
|
853
|
+
slug: z.string(),
|
|
854
|
+
group: z.string(),
|
|
855
|
+
sender: z.string(),
|
|
856
|
+
label: z.string().optional(),
|
|
857
|
+
chatName: z.string().optional(),
|
|
858
|
+
content: z.string(),
|
|
859
|
+
ts: z.number().optional(),
|
|
860
|
+
tags: z.array(z.string()).optional(),
|
|
861
|
+
}),
|
|
862
|
+
response: z.object({
|
|
863
|
+
ok: z.boolean(),
|
|
864
|
+
threadId: z.string().optional(),
|
|
865
|
+
error: z.string().optional(),
|
|
866
|
+
}),
|
|
867
|
+
effect: "ask",
|
|
868
|
+
idempotent: false,
|
|
869
|
+
}),
|
|
870
|
+
"space:post": receiver({
|
|
871
|
+
receiver: "space:post",
|
|
872
|
+
summary: "Post a message to a Space — authenticated member or public Space; stamps space:<slug> tag so the message appears in the Space's thread on slug/in alongside every channel's conversation",
|
|
873
|
+
request: z.object({
|
|
874
|
+
space: z.string(),
|
|
875
|
+
content: z.string(),
|
|
876
|
+
tags: z.array(z.string()).optional(),
|
|
877
|
+
replyTo: z.string().optional(), // parent message id → cascading reply (channels persists the edge)
|
|
878
|
+
}),
|
|
879
|
+
response: z.object({
|
|
880
|
+
ok: z.boolean(),
|
|
881
|
+
id: z.string().optional(),
|
|
882
|
+
ts: z.number().optional(),
|
|
883
|
+
error: z.string().optional(),
|
|
884
|
+
}),
|
|
885
|
+
effect: "ask",
|
|
886
|
+
idempotent: false,
|
|
887
|
+
}),
|
|
888
|
+
"space:create": receiver({
|
|
889
|
+
receiver: "space:create",
|
|
890
|
+
summary: "Create a new Space — registers the channel_link inbox door in channels so every inbound signal is mirrored to the workspace thread read model; private flag restricts posting to members",
|
|
891
|
+
request: z.object({
|
|
892
|
+
slug: z.string(),
|
|
893
|
+
name: z.string().optional(),
|
|
894
|
+
private: z.boolean().optional(),
|
|
895
|
+
}),
|
|
896
|
+
response: z.object({
|
|
897
|
+
ok: z.boolean(),
|
|
898
|
+
space: z.string().optional(),
|
|
899
|
+
error: z.string().optional(),
|
|
900
|
+
}),
|
|
901
|
+
effect: "ask",
|
|
902
|
+
idempotent: false,
|
|
903
|
+
}),
|
|
904
|
+
"space:join": receiver({
|
|
905
|
+
receiver: "space:join",
|
|
906
|
+
summary: "Join a public Space — caller begins receiving its signals and their posts are stamped with the space tag",
|
|
907
|
+
request: z.object({ space: z.string() }),
|
|
908
|
+
response: z.object({
|
|
909
|
+
ok: z.boolean(),
|
|
910
|
+
error: z.string().optional(),
|
|
911
|
+
}),
|
|
912
|
+
effect: "ask",
|
|
913
|
+
idempotent: true,
|
|
914
|
+
}),
|
|
915
|
+
"space:invite": receiver({
|
|
916
|
+
receiver: "space:invite",
|
|
917
|
+
summary: "Invite an actor to a private Space — grants membership so they can read and post; requires the caller to be a member or admin of the Space",
|
|
918
|
+
request: z.object({
|
|
919
|
+
space: z.string(),
|
|
920
|
+
who: z.string(),
|
|
921
|
+
role: z.string().optional(),
|
|
922
|
+
}),
|
|
923
|
+
response: z.object({
|
|
924
|
+
ok: z.boolean(),
|
|
925
|
+
verdict: z.string().optional(),
|
|
926
|
+
error: z.string().optional(),
|
|
927
|
+
}),
|
|
928
|
+
effect: "ask",
|
|
929
|
+
idempotent: false,
|
|
930
|
+
}),
|
|
767
931
|
"chat:send": receiver({
|
|
768
932
|
receiver: "chat:send",
|
|
769
933
|
summary: "Send a message to a group the caller is a member of — sender is always the authenticated caller",
|
|
@@ -776,7 +940,449 @@ export const RECEIVERS = {
|
|
|
776
940
|
response: z.object({ ok: z.boolean(), reply: z.string().optional(), error: z.string().optional() }),
|
|
777
941
|
effect: "ask", auth: "member",
|
|
778
942
|
}),
|
|
943
|
+
// ── chat-context — the threaded #staff fabric: grade · context · harden · lens
|
|
944
|
+
// (text/chat-context.md). `space:post` (the post verb) is declared above. Handlers
|
|
945
|
+
// in resolvers/{messaging,entity}.ts; all IDOR-gated off ctx.ownerSlug. ──────────
|
|
946
|
+
// chat:context — the agent skin: a budget-bounded context pack for one message in
|
|
947
|
+
// a thread (spine + pins + budget-filled siblings + summary tail), returned both
|
|
948
|
+
// structured and serialized for a model. What an agent reads instead of the thread.
|
|
949
|
+
"chat:context": receiver({
|
|
950
|
+
receiver: "chat:context",
|
|
951
|
+
summary: "Assemble a budget-bounded context pack (spine + pins + siblings + summary) for a thread message — structured + serialized for an agent",
|
|
952
|
+
request: z.object({
|
|
953
|
+
entityId: z.string().optional(), // thread id (alias: id)
|
|
954
|
+
targetId: z.string().optional(), // anchor message (default: latest)
|
|
955
|
+
maxTokens: z.number().int().optional(), // budget, clamped 1..8000 (default 1500)
|
|
956
|
+
asActor: z.string().optional(), // serialize from this actor's vantage
|
|
957
|
+
}),
|
|
958
|
+
response: z.object({
|
|
959
|
+
ok: z.boolean(),
|
|
960
|
+
pack: z.object({
|
|
961
|
+
spine: z.array(z.unknown()),
|
|
962
|
+
pins: z.array(z.unknown()),
|
|
963
|
+
siblings: z.array(z.unknown()),
|
|
964
|
+
summary: z.string(),
|
|
965
|
+
}).optional(),
|
|
966
|
+
serialized: z.string().optional(),
|
|
967
|
+
error: z.string().optional(),
|
|
968
|
+
}),
|
|
969
|
+
effect: "ask", cost: "free", reversible: true, idempotent: true, auth: "member",
|
|
970
|
+
}),
|
|
971
|
+
// chat:grade — reinforcement on a message (1..5). Persists the score and closes
|
|
972
|
+
// the loop onto the locked verbs: mark(>=4) strengthens the responder's path,
|
|
973
|
+
// warn(<=2) adds resistance, 3 neutral. Re-grading the same score is a no-op.
|
|
974
|
+
"chat:grade": receiver({
|
|
975
|
+
receiver: "chat:grade",
|
|
976
|
+
summary: "Grade a chat message 1..5 — mark(>=4)/warn(<=2) the responder's path so routing learns who answers well",
|
|
977
|
+
request: z.object({
|
|
978
|
+
messageId: z.string(), // alias: id
|
|
979
|
+
score: z.number().int().min(1).max(5),
|
|
980
|
+
}),
|
|
981
|
+
response: z.object({
|
|
982
|
+
ok: z.boolean(),
|
|
983
|
+
score: z.number().optional(),
|
|
984
|
+
reinforced: z.string().optional(), // 'mark' | 'warn' | 'unchanged' | undefined (neutral)
|
|
985
|
+
target: z.string().optional(),
|
|
986
|
+
error: z.string().optional(),
|
|
987
|
+
}),
|
|
988
|
+
effect: "ask", cost: "free", reversible: false, idempotent: true, auth: "member",
|
|
989
|
+
}),
|
|
990
|
+
// chat:harden — crystallise a resolved thread (#decision or grade>=4 #answer) into
|
|
991
|
+
// a dim-6 learning. Composes assertHypothesis; marks the spine. Refuses unresolved.
|
|
992
|
+
"chat:harden": receiver({
|
|
993
|
+
receiver: "chat:harden",
|
|
994
|
+
summary: "Harden a resolved thread into a dim-6 learning — talk → grade → harden → knowledge; refuses an unresolved thread",
|
|
995
|
+
request: z.object({
|
|
996
|
+
entityId: z.string().optional(), // thread id (alias: id)
|
|
997
|
+
claim: z.string().optional(), // explicit statement; else derived from the thread
|
|
998
|
+
}),
|
|
999
|
+
response: z.object({
|
|
1000
|
+
ok: z.boolean(),
|
|
1001
|
+
hid: z.string().optional(), // hypothesis id
|
|
1002
|
+
statement: z.string().optional(),
|
|
1003
|
+
error: z.string().optional(), // 'not_resolved' if no decision/answer to harden
|
|
1004
|
+
}),
|
|
1005
|
+
effect: "ask", cost: "free", reversible: false, idempotent: false, auth: "member",
|
|
1006
|
+
}),
|
|
1007
|
+
// lens:run — browse a thread's forest by tag (AND / not) + recency or salience.
|
|
1008
|
+
"lens:run": receiver({
|
|
1009
|
+
receiver: "lens:run",
|
|
1010
|
+
summary: "Browse a thread's forest by tag query (tags AND, not exclude) ordered by recency or salience",
|
|
1011
|
+
request: z.object({
|
|
1012
|
+
entityId: z.string().optional(), // thread id (alias: id)
|
|
1013
|
+
tags: z.array(z.string()).optional(), // AND-match
|
|
1014
|
+
not: z.array(z.string()).optional(), // exclude
|
|
1015
|
+
order: z.enum(["recency", "salience"]).optional(),
|
|
1016
|
+
limit: z.number().int().optional(),
|
|
1017
|
+
}),
|
|
1018
|
+
response: z.object({ ok: z.boolean(), count: z.number().optional(), messages: z.array(z.unknown()).optional(), error: z.string().optional() }),
|
|
1019
|
+
effect: "ask", cost: "free", reversible: true, idempotent: true, auth: "member",
|
|
1020
|
+
}),
|
|
1021
|
+
// lens:save — persist a named tag-query for the workspace (upsert by name), so a
|
|
1022
|
+
// frequent browse becomes a one-name re-run / a feed to follow.
|
|
1023
|
+
"lens:save": receiver({
|
|
1024
|
+
receiver: "lens:save",
|
|
1025
|
+
summary: "Save a named tag-query lens for the workspace (upsert by name) — a reusable browse / followable feed",
|
|
1026
|
+
request: z.object({
|
|
1027
|
+
name: z.string(),
|
|
1028
|
+
tags: z.array(z.string()).optional(),
|
|
1029
|
+
not: z.array(z.string()).optional(),
|
|
1030
|
+
order: z.enum(["recency", "salience"]).optional(),
|
|
1031
|
+
limit: z.number().int().optional(),
|
|
1032
|
+
}),
|
|
1033
|
+
response: z.object({ ok: z.boolean(), lens: z.unknown().optional(), count: z.number().optional(), error: z.string().optional() }),
|
|
1034
|
+
effect: "ask", cost: "free", reversible: true, idempotent: true, auth: "member",
|
|
1035
|
+
}),
|
|
1036
|
+
// lens:list — the workspace's saved lenses.
|
|
1037
|
+
"lens:list": receiver({
|
|
1038
|
+
receiver: "lens:list",
|
|
1039
|
+
summary: "List the workspace's saved lenses",
|
|
1040
|
+
request: z.object({}),
|
|
1041
|
+
response: z.object({ ok: z.boolean(), lenses: z.array(z.unknown()).optional(), error: z.string().optional() }),
|
|
1042
|
+
effect: "ask", cost: "free", reversible: true, idempotent: true, auth: "member",
|
|
1043
|
+
}),
|
|
1044
|
+
// lens:delete — remove a saved lens by name.
|
|
1045
|
+
"lens:delete": receiver({
|
|
1046
|
+
receiver: "lens:delete",
|
|
1047
|
+
summary: "Delete a saved lens by name",
|
|
1048
|
+
request: z.object({ name: z.string() }),
|
|
1049
|
+
response: z.object({ ok: z.boolean(), removed: z.number().optional(), error: z.string().optional() }),
|
|
1050
|
+
effect: "ask", cost: "free", reversible: false, idempotent: true, auth: "member",
|
|
1051
|
+
}),
|
|
1052
|
+
// ── entity (inbox collaboration) — operate on one conversation/entity: reply,
|
|
1053
|
+
// tag/stage-move, profile meta, person link, rename, participants
|
|
1054
|
+
// (text/inbox-collaboration-plan.md). Handlers in resolvers/entity.ts; all
|
|
1055
|
+
// IDOR-gated off ctx.ownerSlug and re-check the row's workspace. ────────────────
|
|
1056
|
+
// entity:reply — the single outbound send. Persists an operator/agent reply, mirrors
|
|
1057
|
+
// it to the customer's channel when the thread isn't web, supersedes a pending draft.
|
|
1058
|
+
// kind='note' stays internal (no egress). replyTo cascades within the thread only.
|
|
1059
|
+
"entity:reply": receiver({
|
|
1060
|
+
receiver: "entity:reply",
|
|
1061
|
+
summary: "Reply to a conversation — persists the message, delivers to the customer's channel (telegram/discord) when not web, clears the pending draft; kind:'note' stays internal",
|
|
1062
|
+
request: z.object({
|
|
1063
|
+
entityId: z.string(), // conv/session/thread id (alias: id)
|
|
1064
|
+
content: z.string(),
|
|
1065
|
+
kind: z.enum(["send", "note"]).optional(), // 'send' (default, egresses) | 'note' (internal)
|
|
1066
|
+
author: z.enum(["staff", "agent"]).optional(), // who speaks (default 'staff')
|
|
1067
|
+
replyTo: z.string().optional(), // parent message id — must be in this thread
|
|
1068
|
+
tags: z.array(z.string()).optional(), // ride the message for the forest's salience axis (≤16)
|
|
1069
|
+
}),
|
|
1070
|
+
response: z.object({
|
|
1071
|
+
ok: z.boolean(),
|
|
1072
|
+
delivered: z.string().optional(), // 'web' | 'telegram' | 'discord' | 'failed'
|
|
1073
|
+
kind: z.string().optional(),
|
|
1074
|
+
error: z.string().optional(),
|
|
1075
|
+
}),
|
|
1076
|
+
effect: "ask", cost: "free", reversible: false, idempotent: false, auth: "member",
|
|
1077
|
+
}),
|
|
1078
|
+
// entity:tag — add/remove free tags, or move an entity between lifecycle stages
|
|
1079
|
+
// (the single stage_transition writer — emits move/rejected/failed receipts).
|
|
1080
|
+
"entity:tag": receiver({
|
|
1081
|
+
receiver: "entity:tag",
|
|
1082
|
+
summary: "Tag a conversation/entity (add/remove) or move it between lifecycle stages — the sole stage_transition writer",
|
|
1083
|
+
request: z.object({
|
|
1084
|
+
id: z.string(),
|
|
1085
|
+
add: z.array(z.string()).optional(),
|
|
1086
|
+
remove: z.array(z.string()).optional(),
|
|
1087
|
+
move: z.object({
|
|
1088
|
+
lifecycle: z.string(),
|
|
1089
|
+
from: z.string().optional(),
|
|
1090
|
+
to: z.string(),
|
|
1091
|
+
by: z.string().optional(),
|
|
1092
|
+
source: z.string().optional(),
|
|
1093
|
+
}).optional(),
|
|
1094
|
+
}),
|
|
1095
|
+
response: z.object({
|
|
1096
|
+
ok: z.boolean(),
|
|
1097
|
+
tags: z.array(z.string()).optional(),
|
|
1098
|
+
moved: z.object({ lifecycle: z.string(), from: z.string().optional(), to: z.string() }).optional(),
|
|
1099
|
+
error: z.string().optional(),
|
|
1100
|
+
}),
|
|
1101
|
+
effect: "ask", cost: "free", reversible: true, idempotent: false, auth: "member",
|
|
1102
|
+
}),
|
|
1103
|
+
// entity:meta — editable profile fields for an entity (website, industry, location, …).
|
|
1104
|
+
"entity:meta": receiver({
|
|
1105
|
+
receiver: "entity:meta",
|
|
1106
|
+
summary: "Patch an entity's profile fields (website, industry, location, city, country, size, description, phone, email) — empty value clears the field",
|
|
1107
|
+
request: z.object({ id: z.string(), meta: z.record(z.string(), z.unknown()) }),
|
|
1108
|
+
response: z.object({ ok: z.boolean(), meta: z.record(z.string(), z.string()).optional(), error: z.string().optional() }),
|
|
1109
|
+
effect: "ask", cost: "free", reversible: true, idempotent: true, auth: "member",
|
|
1110
|
+
}),
|
|
1111
|
+
// entity:connect — link/unlink an inbox entity to one known person (omit person → unlink).
|
|
1112
|
+
"entity:connect": receiver({
|
|
1113
|
+
receiver: "entity:connect",
|
|
1114
|
+
summary: "Link an inbox conversation to a known person (by uid or label); omit both to unlink",
|
|
1115
|
+
request: z.object({ id: z.string(), personUid: z.string().optional(), personLabel: z.string().optional() }),
|
|
1116
|
+
response: z.object({ ok: z.boolean(), personUid: z.string().nullable().optional(), personLabel: z.string().optional(), error: z.string().optional() }),
|
|
1117
|
+
effect: "ask", cost: "free", reversible: true, idempotent: true, auth: "member",
|
|
1118
|
+
}),
|
|
1119
|
+
// entity:rename — set/clear an inbox entity's subject line (empty → clear).
|
|
1120
|
+
"entity:rename": receiver({
|
|
1121
|
+
receiver: "entity:rename",
|
|
1122
|
+
summary: "Set or clear a conversation's subject line (≤140 chars; empty clears)",
|
|
1123
|
+
request: z.object({ id: z.string(), subject: z.string().optional() }),
|
|
1124
|
+
response: z.object({ ok: z.boolean(), subject: z.string().nullable().optional(), error: z.string().optional() }),
|
|
1125
|
+
effect: "ask", cost: "free", reversible: true, idempotent: true, auth: "member",
|
|
1126
|
+
}),
|
|
1127
|
+
// entity:participant — add/remove an actor on one conversation (remove by uid).
|
|
1128
|
+
"entity:participant": receiver({
|
|
1129
|
+
receiver: "entity:participant",
|
|
1130
|
+
summary: "Add or remove an actor on a conversation (pass remove:<uid> to remove, or uid/kind/label to add)",
|
|
1131
|
+
request: z.object({
|
|
1132
|
+
id: z.string(),
|
|
1133
|
+
uid: z.string().optional(),
|
|
1134
|
+
kind: z.string().optional(),
|
|
1135
|
+
label: z.string().optional(),
|
|
1136
|
+
remove: z.string().optional(),
|
|
1137
|
+
}),
|
|
1138
|
+
response: z.object({
|
|
1139
|
+
ok: z.boolean(),
|
|
1140
|
+
participant: z.object({ uid: z.string(), kind: z.string(), label: z.string() }).optional(),
|
|
1141
|
+
removed: z.string().optional(),
|
|
1142
|
+
error: z.string().optional(),
|
|
1143
|
+
}),
|
|
1144
|
+
effect: "ask", cost: "free", reversible: true, idempotent: true, auth: "member",
|
|
1145
|
+
}),
|
|
1146
|
+
// ── Deliberately NOT contracted (internal plumbing, not an agent capability):
|
|
1147
|
+
// reply:web · reply:telegram · reply:discord — channel egress fan-out, driven by
|
|
1148
|
+
// entity:reply, never called directly by an agent.
|
|
1149
|
+
// conversation:autonomy — read by the channels worker per inbound turn (send vs
|
|
1150
|
+
// draft), not an operator/agent verb.
|
|
1151
|
+
// member:invited — an internal event hook, not a callable capability.
|
|
1152
|
+
// ui:campaigns:compile · ui:campaigns:approve — UI build-pipeline steps.
|
|
1153
|
+
// These have live resolvers but no RECEIVERS entry by design — keep it that way.
|
|
1154
|
+
// ── commerce (storefront products) — handlers in resolvers/commerce.ts ─────────
|
|
1155
|
+
"products:create": receiver({
|
|
1156
|
+
receiver: "products:create",
|
|
1157
|
+
summary: "Create a storefront product with one or more prices",
|
|
1158
|
+
request: z.object({
|
|
1159
|
+
slug: z.string(),
|
|
1160
|
+
name: z.string(),
|
|
1161
|
+
prices: z.array(z.object({
|
|
1162
|
+
unit_amount: z.number(),
|
|
1163
|
+
currency: z.string().optional(),
|
|
1164
|
+
price_type: z.string().optional(),
|
|
1165
|
+
interval: z.string().optional(),
|
|
1166
|
+
})),
|
|
1167
|
+
description: z.string().optional(),
|
|
1168
|
+
images: z.array(z.string()).optional(),
|
|
1169
|
+
product_type: z.string().optional(), // default 'one_time'
|
|
1170
|
+
collection: z.string().optional(),
|
|
1171
|
+
}),
|
|
1172
|
+
response: z.object({ pid: z.string().optional(), ppid: z.string().optional(), name: z.string().optional(), workspace: z.string().optional(), error: z.string().optional() }),
|
|
1173
|
+
effect: "ask", cost: "free", reversible: true, idempotent: false, auth: "member",
|
|
1174
|
+
}),
|
|
1175
|
+
"products:update": receiver({
|
|
1176
|
+
receiver: "products:update",
|
|
1177
|
+
summary: "Update a product's name, description, images, or collection",
|
|
1178
|
+
request: z.object({ slug: z.string(), pid: z.string(), name: z.string().optional(), description: z.string().optional(), images: z.array(z.string()).optional(), collection: z.string().optional() }),
|
|
1179
|
+
response: z.object({ pid: z.string().optional(), workspace: z.string().optional(), error: z.string().optional() }),
|
|
1180
|
+
effect: "ask", cost: "free", reversible: false, idempotent: true, auth: "member",
|
|
1181
|
+
}),
|
|
1182
|
+
"products:list": receiver({
|
|
1183
|
+
receiver: "products:list",
|
|
1184
|
+
summary: "List a workspace's storefront products with their prices (public)",
|
|
1185
|
+
request: z.object({ slug: z.string().optional() }),
|
|
1186
|
+
response: z.object({ products: z.array(z.record(z.string(), z.unknown())).optional(), error: z.string().optional() }),
|
|
1187
|
+
effect: "ask", cost: "free", reversible: true, idempotent: true, auth: "public",
|
|
1188
|
+
}),
|
|
1189
|
+
"products:archive": receiver({
|
|
1190
|
+
receiver: "products:archive",
|
|
1191
|
+
summary: "Archive a product (reversible via products:update)",
|
|
1192
|
+
request: z.object({ slug: z.string(), pid: z.string() }),
|
|
1193
|
+
response: z.object({ pid: z.string().optional(), workspace: z.string().optional(), status: z.string().optional(), error: z.string().optional() }),
|
|
1194
|
+
effect: "ask", cost: "free", reversible: true, idempotent: true, auth: "member",
|
|
1195
|
+
}),
|
|
1196
|
+
"storefront:stats": receiver({
|
|
1197
|
+
receiver: "storefront:stats",
|
|
1198
|
+
summary: "Storefront funnel stats — views, checkouts, purchases, revenue, per-product breakdown",
|
|
1199
|
+
request: z.object({ slug: z.string().optional() }),
|
|
1200
|
+
response: z.object({
|
|
1201
|
+
views: z.number().optional(),
|
|
1202
|
+
checkouts: z.number().optional(),
|
|
1203
|
+
purchases: z.number().optional(),
|
|
1204
|
+
revenue_cents: z.number().optional(),
|
|
1205
|
+
byProduct: z.array(z.record(z.string(), z.unknown())).optional(),
|
|
1206
|
+
error: z.string().optional(),
|
|
1207
|
+
}),
|
|
1208
|
+
effect: "ask", cost: "free", reversible: true, idempotent: true, auth: "member",
|
|
1209
|
+
}),
|
|
1210
|
+
// ── pages + workspace settings — handlers in resolvers/pages.ts ────────────────
|
|
1211
|
+
"pages:create": receiver({
|
|
1212
|
+
receiver: "pages:create",
|
|
1213
|
+
summary: "Create a workspace page (draft) from a title + sections",
|
|
1214
|
+
request: z.object({ slug: z.string(), title: z.string(), sections: z.record(z.string(), z.unknown()), pageSlug: z.string().optional() }),
|
|
1215
|
+
response: z.object({ ok: z.boolean(), slug: z.string().optional(), title: z.string().optional(), url: z.string().optional(), status: z.string().optional(), error: z.string().optional() }),
|
|
1216
|
+
effect: "ask", cost: "free", reversible: true, idempotent: false, auth: "member",
|
|
1217
|
+
}),
|
|
1218
|
+
"pages:edit": receiver({
|
|
1219
|
+
receiver: "pages:edit",
|
|
1220
|
+
summary: "Edit a workspace page's title or sections",
|
|
1221
|
+
request: z.object({ slug: z.string(), page: z.string(), title: z.string().optional(), sections: z.record(z.string(), z.unknown()).optional() }),
|
|
1222
|
+
response: z.object({ ok: z.boolean(), slug: z.string().optional(), title: z.string().optional(), url: z.string().optional(), status: z.string().optional(), error: z.string().optional() }),
|
|
1223
|
+
effect: "ask", cost: "free", reversible: true, idempotent: false, auth: "member",
|
|
1224
|
+
}),
|
|
1225
|
+
"pages:list": receiver({
|
|
1226
|
+
receiver: "pages:list",
|
|
1227
|
+
summary: "List a workspace's pages with status",
|
|
1228
|
+
request: z.object({ slug: z.string() }),
|
|
1229
|
+
response: z.object({ pages: z.array(z.object({ slug: z.string(), title: z.string(), status: z.string() })) }),
|
|
1230
|
+
effect: "ask", cost: "free", reversible: true, idempotent: true, auth: "member",
|
|
1231
|
+
}),
|
|
1232
|
+
"pages:publish": receiver({
|
|
1233
|
+
receiver: "pages:publish",
|
|
1234
|
+
summary: "Publish a workspace page",
|
|
1235
|
+
request: z.object({ slug: z.string(), page: z.string() }),
|
|
1236
|
+
response: z.object({ ok: z.boolean(), slug: z.string().optional(), title: z.string().optional(), url: z.string().optional(), status: z.string().optional(), error: z.string().optional() }),
|
|
1237
|
+
effect: "ask", cost: "free", reversible: true, idempotent: true, auth: "member",
|
|
1238
|
+
}),
|
|
1239
|
+
"settings:write": receiver({
|
|
1240
|
+
receiver: "settings:write",
|
|
1241
|
+
summary: "Write a workspace setting value (caller or authorized descendant)",
|
|
1242
|
+
request: z.object({ slug: z.string().optional(), name: z.string().optional(), description: z.string().optional(), value: z.string() }),
|
|
1243
|
+
response: z.object({ ok: z.boolean(), slug: z.string().optional(), message: z.string().optional(), error: z.string().optional() }),
|
|
1244
|
+
effect: "ask", cost: "free", reversible: true, idempotent: false, auth: "member",
|
|
1245
|
+
}),
|
|
1246
|
+
"domain:set": receiver({
|
|
1247
|
+
receiver: "domain:set",
|
|
1248
|
+
summary: "Bind a custom domain to a workspace — returns the verification TXT/CNAME records to add",
|
|
1249
|
+
request: z.object({ slug: z.string(), actorId: z.string(), host: z.string() }),
|
|
1250
|
+
response: z.object({ ok: z.boolean(), intent: z.string().optional(), host: z.string().optional(), verifyToken: z.string().optional(), txtRecord: z.string().optional(), cnameTarget: z.string().optional(), reason: z.string().optional() }),
|
|
1251
|
+
effect: "ask", cost: "free", reversible: true, idempotent: false, auth: "verify_domain",
|
|
1252
|
+
}),
|
|
1253
|
+
// ── courses + playbook — handlers in resolvers/courses.ts ──────────────────────
|
|
1254
|
+
"course:save": receiver({
|
|
1255
|
+
receiver: "course:save",
|
|
1256
|
+
summary: "Create or update a course (upsert by courseId)",
|
|
1257
|
+
request: z.object({ courseId: z.string(), title: z.string().optional(), description: z.string().optional(), published: z.boolean().optional(), price_cents: z.number().optional() }),
|
|
1258
|
+
response: z.object({ ok: z.boolean(), courseId: z.string().optional() }),
|
|
1259
|
+
effect: "ask", cost: "free", reversible: false, idempotent: true, auth: "member",
|
|
1260
|
+
}),
|
|
1261
|
+
"course:get": receiver({
|
|
1262
|
+
receiver: "course:get",
|
|
1263
|
+
summary: "Get a course with its lessons (lesson bodies redacted unless enrolled or owner)",
|
|
1264
|
+
request: z.object({ workspace: z.string().optional(), slug: z.string().optional(), courseId: z.string() }),
|
|
1265
|
+
response: z.object({ course: z.record(z.string(), z.unknown()).optional(), lessons: z.array(z.record(z.string(), z.unknown())).optional(), enrolled: z.boolean().optional() }),
|
|
1266
|
+
effect: "ask", cost: "free", reversible: true, idempotent: true, auth: "public",
|
|
1267
|
+
}),
|
|
1268
|
+
"course:list": receiver({
|
|
1269
|
+
receiver: "course:list",
|
|
1270
|
+
summary: "List a workspace's courses (published for others, all for the owner)",
|
|
1271
|
+
request: z.object({ workspace: z.string().optional(), slug: z.string().optional() }),
|
|
1272
|
+
response: z.object({ courses: z.array(z.record(z.string(), z.unknown())).optional() }),
|
|
1273
|
+
effect: "ask", cost: "free", reversible: true, idempotent: true, auth: "public",
|
|
1274
|
+
}),
|
|
1275
|
+
"course:enroll": receiver({
|
|
1276
|
+
receiver: "course:enroll",
|
|
1277
|
+
summary: "Enroll the caller in a course (payment_required if priced and not comped)",
|
|
1278
|
+
request: z.object({ workspace: z.string().optional(), slug: z.string().optional(), courseId: z.string() }),
|
|
1279
|
+
response: z.object({ ok: z.boolean(), enrolled: z.boolean().optional() }),
|
|
1280
|
+
effect: "ask", cost: "variable", reversible: false, idempotent: true, auth: "member",
|
|
1281
|
+
}),
|
|
1282
|
+
"course:lessons-save": receiver({
|
|
1283
|
+
receiver: "course:lessons-save",
|
|
1284
|
+
summary: "Upsert one or more lessons on a course",
|
|
1285
|
+
request: z.object({ courseId: z.string(), lessons: z.union([z.array(z.record(z.string(), z.unknown())), z.record(z.string(), z.unknown())]) }),
|
|
1286
|
+
response: z.object({ ok: z.boolean(), saved: z.number().optional() }),
|
|
1287
|
+
effect: "ask", cost: "free", reversible: false, idempotent: true, auth: "member",
|
|
1288
|
+
}),
|
|
1289
|
+
"playbook:save": receiver({
|
|
1290
|
+
receiver: "playbook:save",
|
|
1291
|
+
summary: "Save a learner's playbook entry for a course lesson (upsert)",
|
|
1292
|
+
request: z.object({ course: z.string(), lesson: z.string(), content: z.string().optional() }),
|
|
1293
|
+
response: z.object({ ok: z.boolean() }),
|
|
1294
|
+
effect: "ask", cost: "free", reversible: true, idempotent: true, auth: "public",
|
|
1295
|
+
}),
|
|
1296
|
+
"playbook:get": receiver({
|
|
1297
|
+
receiver: "playbook:get",
|
|
1298
|
+
summary: "Get the caller's playbook entries (optionally scoped to one course)",
|
|
1299
|
+
request: z.object({ course: z.string().optional() }),
|
|
1300
|
+
response: z.object({ entries: z.array(z.record(z.string(), z.unknown())).optional() }),
|
|
1301
|
+
effect: "ask", cost: "free", reversible: true, idempotent: true, auth: "public",
|
|
1302
|
+
}),
|
|
1303
|
+
"playbook:promote": receiver({
|
|
1304
|
+
receiver: "playbook:promote",
|
|
1305
|
+
summary: "Promote a completed playbook into a reusable skill in the workspace's content repo",
|
|
1306
|
+
request: z.object({ course: z.string() }),
|
|
1307
|
+
response: z.object({ ok: z.boolean(), skillRef: z.string().optional() }),
|
|
1308
|
+
effect: "ask", cost: "free", reversible: true, idempotent: false, auth: "member",
|
|
1309
|
+
}),
|
|
1310
|
+
// ── social + crawl — handlers in resolvers/social.ts ───────────────────────────
|
|
1311
|
+
"social:publish": receiver({
|
|
1312
|
+
receiver: "social:publish",
|
|
1313
|
+
summary: "Publish a drafted social post to its platform",
|
|
1314
|
+
request: z.object({ slug: z.string(), actorId: z.string(), id: z.string() }),
|
|
1315
|
+
response: z.object({ ok: z.boolean(), id: z.string().optional(), status: z.string().optional(), reason: z.string().optional() }),
|
|
1316
|
+
effect: "ask", cost: "variable", reversible: false, idempotent: false, auth: "update_group",
|
|
1317
|
+
}),
|
|
1318
|
+
"social:news-to-drafts": receiver({
|
|
1319
|
+
receiver: "social:news-to-drafts",
|
|
1320
|
+
summary: "Turn fresh news items into platform-specific social post drafts",
|
|
1321
|
+
request: z.object({ groupId: z.string().optional(), maxItems: z.number().int().max(10).optional(), platforms: z.array(z.string()).optional() }),
|
|
1322
|
+
response: z.object({ ok: z.boolean(), draftsCreated: z.number().optional(), total: z.number().optional(), fresh: z.number().optional() }),
|
|
1323
|
+
effect: "ask", cost: "variable", reversible: false, idempotent: false, auth: "member",
|
|
1324
|
+
}),
|
|
1325
|
+
"web:crawl": receiver({
|
|
1326
|
+
receiver: "web:crawl",
|
|
1327
|
+
summary: "Fetch a URL and extract domain, name, description, and readable text (public)",
|
|
1328
|
+
request: z.object({ url: z.string() }),
|
|
1329
|
+
response: z.object({ ok: z.boolean(), url: z.string().optional(), domain: z.string().optional(), name: z.string().optional(), description: z.string().optional(), text: z.string().optional(), error: z.string().optional() }),
|
|
1330
|
+
effect: "ask", cost: "free", reversible: true, idempotent: true, auth: "public",
|
|
1331
|
+
}),
|
|
1332
|
+
// ── people / companies / conversation — handlers in resolvers/groups.ts ────────
|
|
1333
|
+
"people:create": receiver({
|
|
1334
|
+
receiver: "people:create",
|
|
1335
|
+
summary: "Create a person actor in the workspace",
|
|
1336
|
+
request: z.object({ name: z.string(), email: z.string().optional() }),
|
|
1337
|
+
response: z.object({ ok: z.boolean(), aid: z.string().optional(), name: z.string().optional(), error: z.string().optional() }),
|
|
1338
|
+
effect: "ask", cost: "free", reversible: true, idempotent: false, auth: "member",
|
|
1339
|
+
}),
|
|
1340
|
+
"companies:create": receiver({
|
|
1341
|
+
receiver: "companies:create",
|
|
1342
|
+
summary: "Create a company group in the workspace",
|
|
1343
|
+
request: z.object({ name: z.string() }),
|
|
1344
|
+
response: z.object({ ok: z.boolean(), gid: z.string().optional(), name: z.string().optional(), error: z.string().optional() }),
|
|
1345
|
+
effect: "ask", cost: "free", reversible: true, idempotent: false, auth: "member",
|
|
1346
|
+
}),
|
|
1347
|
+
"conversation:start": receiver({
|
|
1348
|
+
receiver: "conversation:start",
|
|
1349
|
+
summary: "Start a new conversation thread (optionally seeded with a message, function lens, or recipient)",
|
|
1350
|
+
request: z.object({ message: z.string().optional(), fn: z.string().optional(), actorId: z.string().optional(), to: z.string().optional() }),
|
|
1351
|
+
response: z.object({ ok: z.boolean(), threadId: z.string().optional(), error: z.string().optional() }),
|
|
1352
|
+
effect: "ask", cost: "free", reversible: false, idempotent: false, auth: "member",
|
|
1353
|
+
}),
|
|
1354
|
+
// ── billing — handlers in resolvers/market.ts ──────────────────────────────────
|
|
1355
|
+
"billing:plan": receiver({
|
|
1356
|
+
receiver: "billing:plan",
|
|
1357
|
+
summary: "Change a workspace's plan — returns a checkout URL to complete the upgrade",
|
|
1358
|
+
request: z.object({ slug: z.string(), actorId: z.string(), plan: z.enum(["pro", "agency", "scale"]) }),
|
|
1359
|
+
response: z.object({ ok: z.boolean(), intent: z.string().optional(), checkoutUrl: z.string().optional(), plan: z.string().optional(), reason: z.string().optional() }),
|
|
1360
|
+
effect: "ask", cost: "free", reversible: false, idempotent: false, auth: "update_group",
|
|
1361
|
+
}),
|
|
1362
|
+
"billing:topup": receiver({
|
|
1363
|
+
receiver: "billing:topup",
|
|
1364
|
+
summary: "Top up workspace AI credits — returns a checkout URL for the amount",
|
|
1365
|
+
request: z.object({ slug: z.string(), actorId: z.string(), amount: z.number(), currency: z.string().optional() }),
|
|
1366
|
+
response: z.object({ ok: z.boolean(), intent: z.string().optional(), checkoutUrl: z.string().optional(), amount: z.number().optional(), currency: z.string().optional(), reason: z.string().optional() }),
|
|
1367
|
+
effect: "ask", cost: "free", reversible: false, idempotent: false, auth: "update_group",
|
|
1368
|
+
}),
|
|
1369
|
+
// ── video — handler in resolvers/video.ts ──────────────────────────────────────
|
|
1370
|
+
"video:ensure-defaults": receiver({
|
|
1371
|
+
receiver: "video:ensure-defaults",
|
|
1372
|
+
summary: "Ensure a workspace's default video rooms exist — returns which were created vs already present",
|
|
1373
|
+
request: z.object({ workspace: z.string().optional(), slug: z.string().optional() }),
|
|
1374
|
+
response: z.object({ ok: z.boolean(), created: z.array(z.string()).optional(), existing: z.array(z.string()).optional(), error: z.string().optional() }),
|
|
1375
|
+
effect: "ask", cost: "free", reversible: true, idempotent: true, auth: "member",
|
|
1376
|
+
}),
|
|
779
1377
|
// ── booking — one calendar, two doors (text/booking-plan.md §5) ───────────────
|
|
1378
|
+
// booking:confirm-payment (public) finalises a paid booking by payment ref.
|
|
1379
|
+
"booking:confirm-payment": receiver({
|
|
1380
|
+
receiver: "booking:confirm-payment",
|
|
1381
|
+
summary: "Confirm a booking after payment settles, by payment reference (public)",
|
|
1382
|
+
request: z.object({ paymentRef: z.string() }),
|
|
1383
|
+
response: z.object({ ok: z.boolean(), error: z.string().optional() }),
|
|
1384
|
+
effect: "ask", cost: "free", reversible: true, idempotent: true, auth: "public",
|
|
1385
|
+
}),
|
|
780
1386
|
// Both public-bookable: a customer with no account books a slot. The provider
|
|
781
1387
|
// side (configure a service) is the separate, gated booking:configure.
|
|
782
1388
|
"booking:list-slots": receiver({
|