@copilotkit/channels 0.1.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.
Files changed (156) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +204 -0
  3. package/dist/action-registry.d.ts +59 -0
  4. package/dist/action-registry.d.ts.map +1 -0
  5. package/dist/action-registry.js +217 -0
  6. package/dist/action-registry.test.d.ts +2 -0
  7. package/dist/action-registry.test.d.ts.map +1 -0
  8. package/dist/action-registry.test.js +115 -0
  9. package/dist/action-store.d.ts +21 -0
  10. package/dist/action-store.d.ts.map +1 -0
  11. package/dist/action-store.js +23 -0
  12. package/dist/action-store.test.d.ts +2 -0
  13. package/dist/action-store.test.d.ts.map +1 -0
  14. package/dist/action-store.test.js +27 -0
  15. package/dist/codec.d.ts +25 -0
  16. package/dist/codec.d.ts.map +1 -0
  17. package/dist/codec.js +1 -0
  18. package/dist/commands.d.ts +73 -0
  19. package/dist/commands.d.ts.map +1 -0
  20. package/dist/commands.js +38 -0
  21. package/dist/commands.test.d.ts +2 -0
  22. package/dist/commands.test.d.ts.map +1 -0
  23. package/dist/commands.test.js +23 -0
  24. package/dist/create-bot.d.ts +171 -0
  25. package/dist/create-bot.d.ts.map +1 -0
  26. package/dist/create-bot.foundations.test.d.ts +2 -0
  27. package/dist/create-bot.foundations.test.d.ts.map +1 -0
  28. package/dist/create-bot.foundations.test.js +147 -0
  29. package/dist/create-bot.js +576 -0
  30. package/dist/create-bot.test.d.ts +2 -0
  31. package/dist/create-bot.test.d.ts.map +1 -0
  32. package/dist/create-bot.test.js +936 -0
  33. package/dist/index.d.ts +26 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +32 -0
  36. package/dist/mint-id.d.ts +3 -0
  37. package/dist/mint-id.d.ts.map +1 -0
  38. package/dist/mint-id.js +20 -0
  39. package/dist/mint-id.test.d.ts +2 -0
  40. package/dist/mint-id.test.d.ts.map +1 -0
  41. package/dist/mint-id.test.js +16 -0
  42. package/dist/modal-submit.test.d.ts +2 -0
  43. package/dist/modal-submit.test.d.ts.map +1 -0
  44. package/dist/modal-submit.test.js +68 -0
  45. package/dist/platform-adapter.d.ts +312 -0
  46. package/dist/platform-adapter.d.ts.map +1 -0
  47. package/dist/platform-adapter.js +1 -0
  48. package/dist/platform-adapter.test.d.ts +2 -0
  49. package/dist/platform-adapter.test.d.ts.map +1 -0
  50. package/dist/platform-adapter.test.js +40 -0
  51. package/dist/reactions.test.d.ts +2 -0
  52. package/dist/reactions.test.d.ts.map +1 -0
  53. package/dist/reactions.test.js +197 -0
  54. package/dist/run-loop.d.ts +41 -0
  55. package/dist/run-loop.d.ts.map +1 -0
  56. package/dist/run-loop.js +102 -0
  57. package/dist/run-loop.test.d.ts +2 -0
  58. package/dist/run-loop.test.d.ts.map +1 -0
  59. package/dist/run-loop.test.js +125 -0
  60. package/dist/standard-schema.d.ts +52 -0
  61. package/dist/standard-schema.d.ts.map +1 -0
  62. package/dist/standard-schema.js +66 -0
  63. package/dist/state/duration.d.ts +3 -0
  64. package/dist/state/duration.d.ts.map +1 -0
  65. package/dist/state/duration.js +16 -0
  66. package/dist/state/duration.test.d.ts +2 -0
  67. package/dist/state/duration.test.d.ts.map +1 -0
  68. package/dist/state/duration.test.js +13 -0
  69. package/dist/state/kv-action-store.d.ts +7 -0
  70. package/dist/state/kv-action-store.d.ts.map +1 -0
  71. package/dist/state/kv-action-store.js +9 -0
  72. package/dist/state/kv-action-store.test.d.ts +2 -0
  73. package/dist/state/kv-action-store.test.d.ts.map +1 -0
  74. package/dist/state/kv-action-store.test.js +21 -0
  75. package/dist/state/memory-store.d.ts +41 -0
  76. package/dist/state/memory-store.d.ts.map +1 -0
  77. package/dist/state/memory-store.js +110 -0
  78. package/dist/state/memory-store.test.d.ts +2 -0
  79. package/dist/state/memory-store.test.d.ts.map +1 -0
  80. package/dist/state/memory-store.test.js +22 -0
  81. package/dist/state/state-conversation-store.d.ts +14 -0
  82. package/dist/state/state-conversation-store.d.ts.map +1 -0
  83. package/dist/state/state-conversation-store.js +22 -0
  84. package/dist/state/state-conversation-store.test.d.ts +2 -0
  85. package/dist/state/state-conversation-store.test.d.ts.map +1 -0
  86. package/dist/state/state-conversation-store.test.js +58 -0
  87. package/dist/state/state-store.d.ts +63 -0
  88. package/dist/state/state-store.d.ts.map +1 -0
  89. package/dist/state/state-store.js +1 -0
  90. package/dist/telemetry/bot-telemetry.d.ts +31 -0
  91. package/dist/telemetry/bot-telemetry.d.ts.map +1 -0
  92. package/dist/telemetry/bot-telemetry.js +70 -0
  93. package/dist/telemetry/bot-telemetry.test.d.ts +2 -0
  94. package/dist/telemetry/bot-telemetry.test.d.ts.map +1 -0
  95. package/dist/telemetry/bot-telemetry.test.js +56 -0
  96. package/dist/telemetry/create-bot-telemetry.test.d.ts +2 -0
  97. package/dist/telemetry/create-bot-telemetry.test.d.ts.map +1 -0
  98. package/dist/telemetry/create-bot-telemetry.test.js +71 -0
  99. package/dist/telemetry/e2e-telemetry.test.d.ts +2 -0
  100. package/dist/telemetry/e2e-telemetry.test.d.ts.map +1 -0
  101. package/dist/telemetry/e2e-telemetry.test.js +56 -0
  102. package/dist/telemetry/events-catalog.test.d.ts +2 -0
  103. package/dist/telemetry/events-catalog.test.d.ts.map +1 -0
  104. package/dist/telemetry/events-catalog.test.js +8 -0
  105. package/dist/telemetry/install-id.d.ts +8 -0
  106. package/dist/telemetry/install-id.d.ts.map +1 -0
  107. package/dist/telemetry/install-id.js +43 -0
  108. package/dist/telemetry/install-id.test.d.ts +2 -0
  109. package/dist/telemetry/install-id.test.d.ts.map +1 -0
  110. package/dist/telemetry/install-id.test.js +43 -0
  111. package/dist/telemetry/platform-allowlist-coverage.test.d.ts +2 -0
  112. package/dist/telemetry/platform-allowlist-coverage.test.d.ts.map +1 -0
  113. package/dist/telemetry/platform-allowlist-coverage.test.js +45 -0
  114. package/dist/telemetry/sanitize-error.d.ts +3 -0
  115. package/dist/telemetry/sanitize-error.d.ts.map +1 -0
  116. package/dist/telemetry/sanitize-error.js +31 -0
  117. package/dist/telemetry/sanitize-error.test.d.ts +2 -0
  118. package/dist/telemetry/sanitize-error.test.d.ts.map +1 -0
  119. package/dist/telemetry/sanitize-error.test.js +33 -0
  120. package/dist/testing/fake-adapter.d.ts +137 -0
  121. package/dist/testing/fake-adapter.d.ts.map +1 -0
  122. package/dist/testing/fake-adapter.js +273 -0
  123. package/dist/testing/fake-agent.d.ts +28 -0
  124. package/dist/testing/fake-agent.d.ts.map +1 -0
  125. package/dist/testing/fake-agent.js +36 -0
  126. package/dist/testing/state-store-conformance.d.ts +4 -0
  127. package/dist/testing/state-store-conformance.d.ts.map +1 -0
  128. package/dist/testing/state-store-conformance.js +117 -0
  129. package/dist/thread-capabilities.test.d.ts +2 -0
  130. package/dist/thread-capabilities.test.d.ts.map +1 -0
  131. package/dist/thread-capabilities.test.js +77 -0
  132. package/dist/thread-ephemeral.test.d.ts +2 -0
  133. package/dist/thread-ephemeral.test.d.ts.map +1 -0
  134. package/dist/thread-ephemeral.test.js +45 -0
  135. package/dist/thread-reactions.test.d.ts +2 -0
  136. package/dist/thread-reactions.test.d.ts.map +1 -0
  137. package/dist/thread-reactions.test.js +38 -0
  138. package/dist/thread.d.ts +152 -0
  139. package/dist/thread.d.ts.map +1 -0
  140. package/dist/thread.js +329 -0
  141. package/dist/thread.test.d.ts +2 -0
  142. package/dist/thread.test.d.ts.map +1 -0
  143. package/dist/thread.test.js +83 -0
  144. package/dist/tools.d.ts +67 -0
  145. package/dist/tools.d.ts.map +1 -0
  146. package/dist/tools.js +38 -0
  147. package/dist/tools.test.d.ts +2 -0
  148. package/dist/tools.test.d.ts.map +1 -0
  149. package/dist/tools.test.js +31 -0
  150. package/dist/transcripts.d.ts +52 -0
  151. package/dist/transcripts.d.ts.map +1 -0
  152. package/dist/transcripts.js +67 -0
  153. package/dist/transcripts.test.d.ts +2 -0
  154. package/dist/transcripts.test.d.ts.map +1 -0
  155. package/dist/transcripts.test.js +108 -0
  156. package/package.json +72 -0
@@ -0,0 +1,26 @@
1
+ export { createBot } from "./create-bot.js";
2
+ export type { Bot, CreateBotOptions, BotHandler, ThreadStartHandler, ReactionEvent, ReactionHandler, ModalSubmitEvent, ModalSubmitHandler, ModalCloseEvent, ModalCloseHandler, StoreConfig, LockConflictDecision, StatefulThread, BotComponent, } from "./create-bot.js";
3
+ export { Thread } from "./thread.js";
4
+ export type { ThreadDeps } from "./thread.js";
5
+ export type { PlatformAdapter, AdapterStartContext, RunRenderer, IngressSink, IncomingTurn, InteractionEvent, IncomingCommand, IncomingThreadStart, IncomingReaction, IncomingModalSubmit, IncomingModalClose, ModalSubmitResult, SurfaceCapabilities, ReplyTarget, ConversationStore, AgentSession, CapturedToolCall, CapturedInterrupt, UserQuery, NativePayload, } from "./platform-adapter.js";
6
+ export { defineBotCommand, normalizeCommandName, toCommandSpec, } from "./commands.js";
7
+ export type { BotCommand, CommandContext, CommandSpec } from "./commands.js";
8
+ export { InMemoryActionStore } from "./action-store.js";
9
+ export type { ActionStore, ActionSnapshot } from "./action-store.js";
10
+ export { ActionRegistry, ActionExpiredError } from "./action-registry.js";
11
+ export type { StateStore } from "./state/state-store.js";
12
+ export { MemoryStore } from "./state/memory-store.js";
13
+ export { parseDuration } from "./state/duration.js";
14
+ export { createStateBackedConversationStore } from "./state/state-conversation-store.js";
15
+ export { Transcripts } from "./transcripts.js";
16
+ export type { TranscriptEntry, Identity, TranscriptsConfig, } from "./transcripts.js";
17
+ export { toAgentToolDescriptors, parseToolArgs, stringifyHandlerResult, defineBotTool, } from "./tools.js";
18
+ export type { BotTool, ObjectSchema, BotToolContext, ContextEntry, AgentToolDescriptor, } from "./tools.js";
19
+ export { mintId, stableStringify } from "./mint-id.js";
20
+ export { runAgentLoop } from "./run-loop.js";
21
+ export type { RunLoopArgs } from "./run-loop.js";
22
+ export type { PlatformCodec } from "./codec.js";
23
+ export { FakeAdapter, makeFakeRunRenderer } from "./testing/fake-adapter.js";
24
+ export { FakeAgent } from "./testing/fake-agent.js";
25
+ export * from "@copilotkit/channels-ui";
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EACV,GAAG,EACH,gBAAgB,EAChB,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,oBAAoB,EACpB,cAAc,EACd,YAAY,GACb,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,WAAW,EACX,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,EACT,aAAa,GACd,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGrE,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG1E,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAMtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,kCAAkC,EAAE,MAAM,qCAAqC,CAAC;AAGzF,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EACV,eAAe,EACf,QAAQ,EACR,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,sBAAsB,EACtB,aAAa,EACb,sBAAsB,EACtB,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,OAAO,EACP,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAKjD,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAGpD,cAAc,yBAAyB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,32 @@
1
+ // Public API for @copilotkit/channels.
2
+ // Bot orchestration
3
+ export { createBot } from "./create-bot.js";
4
+ // Thread
5
+ export { Thread } from "./thread.js";
6
+ // Slash commands
7
+ export { defineBotCommand, normalizeCommandName, toCommandSpec, } from "./commands.js";
8
+ // Action store
9
+ export { InMemoryActionStore } from "./action-store.js";
10
+ // Action registry
11
+ export { ActionRegistry, ActionExpiredError } from "./action-registry.js";
12
+ export { MemoryStore } from "./state/memory-store.js";
13
+ // NOTE: `runStateStoreConformance` is intentionally NOT re-exported here. It
14
+ // pulls in `vitest`, so re-exporting it from the package entry would drag a
15
+ // test framework into every consumer's runtime module graph (a bare
16
+ // `import ... from "@copilotkit/channels"` would fail unless vitest is installed).
17
+ // It is published under the `@copilotkit/channels/testing` subpath instead.
18
+ export { parseDuration } from "./state/duration.js";
19
+ export { createStateBackedConversationStore } from "./state/state-conversation-store.js";
20
+ // Transcripts
21
+ export { Transcripts } from "./transcripts.js";
22
+ // Tools & context
23
+ export { toAgentToolDescriptors, parseToolArgs, stringifyHandlerResult, defineBotTool, } from "./tools.js";
24
+ // Id / serialization helpers
25
+ export { mintId, stableStringify } from "./mint-id.js";
26
+ // Run loop
27
+ export { runAgentLoop } from "./run-loop.js";
28
+ // Test utilities (also surfaces them for downstream adapter packages' tests).
29
+ export { FakeAdapter, makeFakeRunRenderer } from "./testing/fake-adapter.js";
30
+ export { FakeAgent } from "./testing/fake-agent.js";
31
+ // Re-export the bot-ui component vocabulary + types for convenience.
32
+ export * from "@copilotkit/channels-ui";
@@ -0,0 +1,3 @@
1
+ export declare function stableStringify(v: unknown): string;
2
+ export declare function mintId(componentName: string, path: (string | number)[], props: unknown): string;
3
+ //# sourceMappingURL=mint-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mint-id.d.ts","sourceRoot":"","sources":["../src/mint-id.ts"],"names":[],"mappings":"AAEA,wBAAgB,eAAe,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAYlD;AAED,wBAAgB,MAAM,CACpB,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EACzB,KAAK,EAAE,OAAO,GACb,MAAM,CAKR"}
@@ -0,0 +1,20 @@
1
+ import { createHash } from "node:crypto";
2
+ export function stableStringify(v) {
3
+ if (v === null || typeof v !== "object")
4
+ return JSON.stringify(v) ?? "null";
5
+ if (Array.isArray(v))
6
+ return "[" + v.map(stableStringify).join(",") + "]";
7
+ const obj = v;
8
+ const keys = Object.keys(obj).sort();
9
+ return ("{" +
10
+ keys
11
+ .map((k) => JSON.stringify(k) + ":" + stableStringify(obj[k]))
12
+ .join(",") +
13
+ "}");
14
+ }
15
+ export function mintId(componentName, path, props) {
16
+ const h = createHash("sha1")
17
+ .update(`${componentName}|${path.join(".")}|${stableStringify(props)}`)
18
+ .digest("hex");
19
+ return "ck:" + h.slice(0, 16);
20
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=mint-id.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mint-id.test.d.ts","sourceRoot":"","sources":["../src/mint-id.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { mintId, stableStringify } from "./mint-id.js";
3
+ describe("mintId", () => {
4
+ it("is content-stable for same component/path/props", () => {
5
+ const a = mintId("Flight", [0, "onClick"], { id: "f1" });
6
+ const b = mintId("Flight", [0, "onClick"], { id: "f1" });
7
+ expect(a).toBe(b);
8
+ expect(a.startsWith("ck:")).toBe(true);
9
+ });
10
+ it("differs when props differ", () => {
11
+ expect(mintId("Flight", [0], { id: "f1" })).not.toBe(mintId("Flight", [0], { id: "f2" }));
12
+ });
13
+ it("stableStringify sorts keys", () => {
14
+ expect(stableStringify({ b: 1, a: 2 })).toBe(stableStringify({ a: 2, b: 1 }));
15
+ });
16
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=modal-submit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modal-submit.test.d.ts","sourceRoot":"","sources":["../src/modal-submit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,68 @@
1
+ // packages/channels/src/modal-submit.test.ts
2
+ import { describe, it, expect } from "vitest";
3
+ import { createBot } from "./create-bot.js";
4
+ import { FakeAdapter } from "./testing/fake-adapter.js";
5
+ describe("bot.onModalSubmit / onModalClose", () => {
6
+ it("routes a submission by callbackId and parses values; thread present when conversation context exists", async () => {
7
+ const fake = new FakeAdapter();
8
+ const bot = createBot({ adapters: [fake] });
9
+ const seen = [];
10
+ bot.onModalSubmit("triage", (evt) => {
11
+ seen.push({
12
+ values: evt.values,
13
+ user: evt.user?.id,
14
+ cb: evt.callbackId,
15
+ hasThread: !!evt.thread,
16
+ });
17
+ });
18
+ await bot.start();
19
+ const res = await fake.emitModalSubmit({
20
+ callbackId: "triage",
21
+ values: { summary: "boom", prio: "high" },
22
+ user: { id: "U1" },
23
+ conversationKey: "c",
24
+ replyTarget: {},
25
+ });
26
+ expect(res).toBeUndefined(); // no errors → closes
27
+ expect(seen).toEqual([
28
+ {
29
+ values: { summary: "boom", prio: "high" },
30
+ user: "U1",
31
+ cb: "triage",
32
+ hasThread: true,
33
+ },
34
+ ]);
35
+ });
36
+ it("returns the handler's field errors so the adapter can keep the modal open", async () => {
37
+ const fake = new FakeAdapter();
38
+ const bot = createBot({ adapters: [fake] });
39
+ bot.onModalSubmit("triage", (evt) => evt.values.summary ? undefined : { errors: { summary: "Required" } });
40
+ await bot.start();
41
+ const res = await fake.emitModalSubmit({
42
+ callbackId: "triage",
43
+ values: {},
44
+ });
45
+ expect(res).toEqual({ errors: { summary: "Required" } });
46
+ });
47
+ it("ignores submissions with no registered handler", async () => {
48
+ const fake = new FakeAdapter();
49
+ const bot = createBot({ adapters: [fake] });
50
+ await bot.start();
51
+ const res = await fake.emitModalSubmit({
52
+ callbackId: "unknown",
53
+ values: {},
54
+ });
55
+ expect(res).toBeUndefined();
56
+ });
57
+ it("routes a close by callbackId", async () => {
58
+ const fake = new FakeAdapter();
59
+ const bot = createBot({ adapters: [fake] });
60
+ const closed = [];
61
+ bot.onModalClose("triage", (evt) => {
62
+ closed.push(evt.callbackId);
63
+ });
64
+ await bot.start();
65
+ await fake.emitModalClose({ callbackId: "triage", user: { id: "U2" } });
66
+ expect(closed).toEqual(["triage"]);
67
+ });
68
+ });
@@ -0,0 +1,312 @@
1
+ import type { AgentSubscriber, AbstractAgent } from "@ag-ui/client";
2
+ import type { AgentContentPart, BotNode, EmojiValue, EphemeralResult, MessageRef, PlatformUser, ThreadMessage } from "@copilotkit/channels-ui";
3
+ import type { CommandSpec } from "./commands.js";
4
+ import type { StateStore } from "./state/state-store.js";
5
+ /** Opaque to the bot core — created by an adapter during ingress and passed back to post/createRunRenderer. */
6
+ export type ReplyTarget = unknown;
7
+ /** Opaque native payload produced by an adapter's render(). */
8
+ export type NativePayload = unknown;
9
+ export interface SurfaceCapabilities {
10
+ supportsModals: boolean;
11
+ supportsTyping: boolean;
12
+ supportsReactions: boolean;
13
+ supportsStreaming: boolean;
14
+ maxBlocksPerMessage?: number;
15
+ /** Pinned prompt chips on a conversation surface (Slack assistant pane). */
16
+ supportsSuggestedPrompts?: boolean;
17
+ /** Nameable conversations (Slack assistant-thread titles). */
18
+ supportsThreadTitle?: boolean;
19
+ /** Native ephemeral messages (Slack). When false, `postEphemeral` still works via DM fallback. */
20
+ supportsEphemeral?: boolean;
21
+ [k: string]: unknown;
22
+ }
23
+ export interface CapturedToolCall {
24
+ toolCallId: string;
25
+ toolCallName: string;
26
+ toolCallArgs: Record<string, unknown>;
27
+ }
28
+ export interface CapturedInterrupt {
29
+ eventName: string;
30
+ value: unknown;
31
+ }
32
+ /** A per-run handle: the AG-UI subscriber to stream into, plus capture accessors the run-loop reads after each runAgent. */
33
+ export interface RunRenderer {
34
+ subscriber: AgentSubscriber;
35
+ markInterrupted(): Promise<void>;
36
+ getCapturedToolCalls(): readonly CapturedToolCall[];
37
+ getPendingInterrupt(): CapturedInterrupt | undefined;
38
+ clearPendingInterrupt(): void;
39
+ /**
40
+ * Optional turn-end hook. Called once after the run-loop resolves normally
41
+ * (no more tool calls, or an interrupt was acked), so a renderer that keeps a
42
+ * turn-scoped resource open across `runAgent` iterations — e.g. a single
43
+ * native streaming message that interleaves text and tool-progress — can
44
+ * finalize it. Symmetric with {@link markInterrupted}; renderers whose
45
+ * streams self-terminate per message simply omit it. Must be a no-op if the
46
+ * run was already interrupted.
47
+ */
48
+ finish?(): Promise<void>;
49
+ }
50
+ /**
51
+ * Fields shared by every ingress event routed through the {@link IngressSink}:
52
+ * the conversation it belongs to, the opaque target to reply on, and the user
53
+ * who triggered it (when the platform reports one).
54
+ */
55
+ export interface IngressEventBase {
56
+ conversationKey: string;
57
+ replyTarget: ReplyTarget;
58
+ user?: PlatformUser;
59
+ }
60
+ /**
61
+ * Idempotency ids carried by turn/command/interaction ingress. Set on the
62
+ * managed (Intelligence-delivered) path; local adapters omit them.
63
+ */
64
+ export interface IngressIds {
65
+ /** Stable platform event id for idempotency; omit if the platform provides none. */
66
+ eventId?: string;
67
+ /** Stable per-turn id (managed/Intelligence path); local adapters omit it. */
68
+ turnId?: string;
69
+ /** Lease/delivery id (managed/Intelligence path); local adapters omit it. */
70
+ deliveryId?: string;
71
+ }
72
+ export interface IncomingTurn extends IngressEventBase, IngressIds {
73
+ userText: string;
74
+ /**
75
+ * Optional multimodal content parts built by the adapter (e.g. inbound
76
+ * image/file attachments). Carried through to `IncomingMessage.contentParts`.
77
+ */
78
+ contentParts?: AgentContentPart[];
79
+ platform: string;
80
+ }
81
+ export interface InteractionEvent extends IngressEventBase, IngressIds {
82
+ id: string;
83
+ value?: unknown;
84
+ /** The message the interaction occurred on (the picker), so handlers can update it in place. */
85
+ messageRef?: MessageRef;
86
+ /** Opaque platform trigger for opening a modal (Slack `trigger_id`; Discord interaction id). */
87
+ triggerId?: string;
88
+ }
89
+ /** A slash-command invocation normalized by an adapter. */
90
+ export interface IncomingCommand extends IngressEventBase, IngressIds {
91
+ /** Command name as invoked (a leading slash and case are normalized by the engine). */
92
+ command: string;
93
+ /** Raw argument string after the command name (the form text-only surfaces deliver). */
94
+ text: string;
95
+ /** Structured, pre-parsed options when the surface delivers them (e.g. Discord). */
96
+ rawOptions?: Record<string, unknown>;
97
+ platform: string;
98
+ /** Opaque platform trigger for opening a modal (Slack `trigger_id`; Discord interaction id). */
99
+ triggerId?: string;
100
+ }
101
+ /**
102
+ * A "conversation opened" lifecycle event (Slack: `assistant_thread_started`).
103
+ * Adapters without the concept never emit it.
104
+ */
105
+ export interface IncomingThreadStart extends IngressEventBase {
106
+ platform: string;
107
+ }
108
+ /** A reaction added/removed on a message. Adapters that can't observe reactions never emit it. */
109
+ export interface IncomingReaction extends IngressEventBase {
110
+ /** Platform-native emoji token (Slack shortcode, Unicode, Discord custom). */
111
+ rawEmoji: string;
112
+ /** true = added, false = removed. */
113
+ added: boolean;
114
+ /** Id of the reacted-to message. */
115
+ messageId: string;
116
+ /**
117
+ * Update-capable ref to the reacted message (the platform-specific shape the
118
+ * adapter's `update`/`delete` accept). Lets a `<Message onReaction>` handler
119
+ * swap the message's UI in place. Adapters that can edit messages should set
120
+ * this; the engine falls back to `{ id: messageId }` when omitted.
121
+ */
122
+ messageRef?: MessageRef;
123
+ /** Containing thread/conversation id, when distinct from the message. */
124
+ threadId?: string;
125
+ /** Native payload. */
126
+ raw: unknown;
127
+ }
128
+ /** A modal submission. Adapters without modals never emit it. */
129
+ export interface IncomingModalSubmit {
130
+ callbackId: string;
131
+ /** Field id → value (text string, selected option value, etc.). */
132
+ values: Record<string, unknown>;
133
+ user?: PlatformUser;
134
+ privateMetadata?: string;
135
+ /** Present when the submission carries a conversation context (so the engine can build a Thread). */
136
+ conversationKey?: string;
137
+ replyTarget?: ReplyTarget;
138
+ platform: string;
139
+ raw: unknown;
140
+ }
141
+ /** A modal dismissal (Slack `view_closed`; requires `notifyOnClose`). */
142
+ export interface IncomingModalClose {
143
+ callbackId: string;
144
+ user?: PlatformUser;
145
+ privateMetadata?: string;
146
+ /** Present when the dismissal carries a conversation context (so the engine can build a Thread). */
147
+ conversationKey?: string;
148
+ replyTarget?: ReplyTarget;
149
+ platform: string;
150
+ raw: unknown;
151
+ }
152
+ /** What a submit handler may return to keep the modal open with per-field errors. */
153
+ export interface ModalSubmitResult {
154
+ errors?: Record<string, string>;
155
+ }
156
+ export interface IngressSink {
157
+ onTurn(turn: IncomingTurn): void | Promise<void>;
158
+ onInteraction(evt: InteractionEvent): void | Promise<void>;
159
+ /** A slash command fired. Routed to the matching `bot.onCommand` handler (ignored if none). */
160
+ onCommand(cmd: IncomingCommand): void | Promise<void>;
161
+ /** A conversation surface opened. Adapters without the concept never call it. */
162
+ onThreadStarted(evt: IncomingThreadStart): void | Promise<void>;
163
+ /** A reaction was added/removed. Adapters that can't observe reactions never call it. */
164
+ onReaction(evt: IncomingReaction): void | Promise<void>;
165
+ /**
166
+ * A modal was submitted. Returns the handler's result so the adapter can ack
167
+ * with per-field errors (Slack `response_action: "errors"`). Adapters without
168
+ * modals never call it.
169
+ */
170
+ onModalSubmit(evt: IncomingModalSubmit): Promise<ModalSubmitResult | void>;
171
+ /** A modal was dismissed. Adapters without `view_closed` never call it. */
172
+ onModalClose(evt: IncomingModalClose): void | Promise<void>;
173
+ }
174
+ export interface UserQuery {
175
+ query: string;
176
+ }
177
+ /** A resolved agent session for a conversation (the adapter may build the agent's history from its own state). */
178
+ export interface AgentSession {
179
+ agent: AbstractAgent;
180
+ }
181
+ /** Adapter-owned conversation state; the adapter resolves (or creates) the agent session for a conversation. */
182
+ export interface ConversationStore {
183
+ getOrCreate(conversationKey: string, replyTarget: ReplyTarget, makeAgent: (threadId: string) => AbstractAgent): Promise<AgentSession>;
184
+ }
185
+ /**
186
+ * Optional context bot core passes to {@link PlatformAdapter.start}. Carries
187
+ * the bot's declared identity so a transport that must announce itself (e.g.
188
+ * the managed Intelligence adapter's heartbeat) can do so without separate
189
+ * config. Local adapters ignore it.
190
+ */
191
+ export interface AdapterStartContext {
192
+ /** The bot's declared name (`createBot({ name })`), when set. */
193
+ botName?: string;
194
+ }
195
+ export interface PlatformAdapter {
196
+ readonly platform: string;
197
+ readonly capabilities: SurfaceCapabilities;
198
+ readonly ackDeadlineMs: number;
199
+ start(sink: IngressSink, ctx?: AdapterStartContext): Promise<void>;
200
+ stop(): Promise<void>;
201
+ render(ir: BotNode[]): NativePayload;
202
+ post(target: ReplyTarget, ir: BotNode[]): Promise<MessageRef>;
203
+ update(ref: MessageRef, ir: BotNode[]): Promise<void>;
204
+ stream(target: ReplyTarget, chunks: AsyncIterable<string>): Promise<MessageRef>;
205
+ delete(ref: MessageRef): Promise<void>;
206
+ createRunRenderer(target: ReplyTarget): RunRenderer;
207
+ decodeInteraction(raw: unknown): InteractionEvent | undefined;
208
+ lookupUser(q: UserQuery): Promise<PlatformUser | undefined>;
209
+ readonly conversationStore: ConversationStore;
210
+ /**
211
+ * Optional persistence backend supplied by the adapter. `createBot` uses it
212
+ * only when no explicit `store.adapter` is configured; if more than one
213
+ * adapter provides one, `createBot` warns and uses the first. Distinct from
214
+ * {@link conversationStore}.
215
+ */
216
+ readonly stateStore?: StateStore;
217
+ /** @internal Marks the managed adapter; bot core uses it for the V1 exclusivity guard. */
218
+ readonly __managed?: boolean;
219
+ /**
220
+ * When true, bot core skips its ingress dedup for events from this adapter.
221
+ * Set by at-least-once transports (managed delivery) that enforce
222
+ * idempotency at egress instead — dropping a redelivery at ingress would lose
223
+ * a legitimate retry.
224
+ */
225
+ readonly skipIngressDedup?: boolean;
226
+ /**
227
+ * Optional conversation-history read. Backs the capability-gated
228
+ * `Thread.getMessages()`; adapters that can't read history simply omit this,
229
+ * and `Thread.getMessages()` returns `[]`.
230
+ */
231
+ getMessages?(target: ReplyTarget): Promise<ThreadMessage[]>;
232
+ /**
233
+ * Optional platform file upload. Threads expose `postFile` unconditionally;
234
+ * adapters that can't upload simply omit this, and `Thread.postFile` returns
235
+ * a capability-gated `{ ok: false, error }`.
236
+ */
237
+ postFile?(target: ReplyTarget, args: {
238
+ bytes: Uint8Array;
239
+ filename: string;
240
+ title?: string;
241
+ altText?: string;
242
+ }): Promise<{
243
+ ok: boolean;
244
+ fileId?: string;
245
+ error?: string;
246
+ }>;
247
+ /**
248
+ * Optional slash-command support. Called once on `start()` with the bot's
249
+ * declared commands, so a surface that registers commands up front (e.g.
250
+ * Discord's application-command API) can publish them. Surfaces that match
251
+ * commands dynamically (e.g. Slack, which forwards every `/command` to
252
+ * `sink.onCommand`) need not implement this; adapters that don't support
253
+ * commands at all simply omit it and command handlers never fire there.
254
+ */
255
+ registerCommands?(commands: readonly CommandSpec[]): void | Promise<void>;
256
+ /**
257
+ * Optional: pin suggested prompts on a conversation surface (backs the
258
+ * capability-gated `Thread.setSuggestedPrompts`). Adapters without the
259
+ * concept omit this, and `Thread.setSuggestedPrompts` returns
260
+ * `{ ok: false, error }` without throwing.
261
+ */
262
+ setSuggestedPrompts?(target: ReplyTarget, prompts: ReadonlyArray<{
263
+ title: string;
264
+ message: string;
265
+ }>, opts?: {
266
+ title?: string;
267
+ }): Promise<{
268
+ ok: boolean;
269
+ error?: string;
270
+ }>;
271
+ /**
272
+ * Optional: set the conversation's display title (backs `Thread.setTitle`).
273
+ * Adapters without the concept omit this, and `Thread.setTitle` returns
274
+ * `{ ok: false, error }` without throwing.
275
+ */
276
+ setThreadTitle?(target: ReplyTarget, title: string): Promise<{
277
+ ok: boolean;
278
+ error?: string;
279
+ }>;
280
+ /**
281
+ * Optional reactions egress (backs `Thread.react`/`unreact`). Adapters without
282
+ * reactions omit these; the Thread methods then return `{ ok: false, error }`.
283
+ */
284
+ addReaction?(target: ReplyTarget, messageRef: MessageRef, emoji: EmojiValue): Promise<{
285
+ ok: boolean;
286
+ error?: string;
287
+ }>;
288
+ removeReaction?(target: ReplyTarget, messageRef: MessageRef, emoji: EmojiValue): Promise<{
289
+ ok: boolean;
290
+ error?: string;
291
+ }>;
292
+ /**
293
+ * Optional ephemeral post (backs `Thread.postEphemeral`). The adapter decides
294
+ * native vs DM fallback based on `opts.fallbackToDM` and returns
295
+ * `{ ok, usedFallback }` or `null` (native unsupported and no fallback).
296
+ */
297
+ postEphemeral?(target: ReplyTarget, user: PlatformUser | string, ir: BotNode[], opts: {
298
+ fallbackToDM: boolean;
299
+ }): Promise<EphemeralResult | null>;
300
+ /** Optional modal render (pure; backs `openModal`). Throws `ModalRenderError` on unsupported elements. */
301
+ renderModal?(ir: BotNode[]): NativePayload;
302
+ /**
303
+ * Optional modal open (backs context `openModal`). Renders `ir` and opens it
304
+ * against the platform `triggerId`. Returns `{ ok: false }` on failure
305
+ * (expired trigger, unsupported elements) — never throws.
306
+ */
307
+ openModal?(target: ReplyTarget, triggerId: string, ir: BotNode[]): Promise<{
308
+ ok: boolean;
309
+ error?: string;
310
+ }>;
311
+ }
312
+ //# sourceMappingURL=platform-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-adapter.d.ts","sourceRoot":"","sources":["../src/platform-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=platform-adapter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-adapter.test.d.ts","sourceRoot":"","sources":["../src/platform-adapter.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,40 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { FakeAdapter } from "./testing/fake-adapter.js";
3
+ describe("FakeAdapter", () => {
4
+ it("records posts and drives ingress", async () => {
5
+ const a = new FakeAdapter();
6
+ let got;
7
+ await a.start({
8
+ onTurn: (t) => {
9
+ got = t.userText;
10
+ },
11
+ onInteraction: () => { },
12
+ onCommand: () => { },
13
+ onThreadStarted: () => { },
14
+ onReaction: () => { },
15
+ onModalSubmit: async () => { },
16
+ onModalClose: () => { },
17
+ });
18
+ a.emitTurn({ userText: "hi" });
19
+ expect(got).toBe("hi");
20
+ await a.post({}, [{ type: "text", props: { value: "x" } }]);
21
+ expect(a.posted.length).toBe(1);
22
+ });
23
+ it("delivers interactions to the sink", async () => {
24
+ const a = new FakeAdapter();
25
+ let id;
26
+ await a.start({
27
+ onTurn: () => { },
28
+ onInteraction: (e) => {
29
+ id = e.id;
30
+ },
31
+ onCommand: () => { },
32
+ onThreadStarted: () => { },
33
+ onReaction: () => { },
34
+ onModalSubmit: async () => { },
35
+ onModalClose: () => { },
36
+ });
37
+ a.emitInteraction({ id: "ck:abc" });
38
+ expect(id).toBe("ck:abc");
39
+ });
40
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=reactions.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reactions.test.d.ts","sourceRoot":"","sources":["../src/reactions.test.ts"],"names":[],"mappings":""}