@indemn/cli 1.5.0 → 1.7.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 (311) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/.claude-plugin/plugin.json +9 -4
  3. package/.github/workflows/ci.yml +10 -0
  4. package/.github/workflows/publish.yml +2 -2
  5. package/.mcp.json +1 -4
  6. package/CONTRIBUTING.md +3 -1
  7. package/README.md +69 -176
  8. package/dist/cli/agents.d.ts.map +1 -1
  9. package/dist/cli/agents.js +226 -18
  10. package/dist/cli/agents.js.map +1 -1
  11. package/dist/cli/analytics.d.ts +3 -0
  12. package/dist/cli/analytics.d.ts.map +1 -0
  13. package/dist/cli/analytics.js +133 -0
  14. package/dist/cli/analytics.js.map +1 -0
  15. package/dist/cli/auth.d.ts.map +1 -1
  16. package/dist/cli/auth.js +62 -17
  17. package/dist/cli/auth.js.map +1 -1
  18. package/dist/cli/billing.d.ts +3 -0
  19. package/dist/cli/billing.d.ts.map +1 -0
  20. package/dist/cli/billing.js +23 -0
  21. package/dist/cli/billing.js.map +1 -0
  22. package/dist/cli/campaigns.d.ts +3 -0
  23. package/dist/cli/campaigns.d.ts.map +1 -0
  24. package/dist/cli/campaigns.js +34 -0
  25. package/dist/cli/campaigns.js.map +1 -0
  26. package/dist/cli/chat.d.ts.map +1 -1
  27. package/dist/cli/chat.js +69 -102
  28. package/dist/cli/chat.js.map +1 -1
  29. package/dist/cli/config.d.ts.map +1 -1
  30. package/dist/cli/config.js +71 -27
  31. package/dist/cli/config.js.map +1 -1
  32. package/dist/cli/conversations.d.ts +3 -0
  33. package/dist/cli/conversations.d.ts.map +1 -0
  34. package/dist/cli/conversations.js +129 -0
  35. package/dist/cli/conversations.js.map +1 -0
  36. package/dist/cli/distribution.d.ts +3 -0
  37. package/dist/cli/distribution.d.ts.map +1 -0
  38. package/dist/cli/distribution.js +122 -0
  39. package/dist/cli/distribution.js.map +1 -0
  40. package/dist/cli/eval.d.ts.map +1 -1
  41. package/dist/cli/eval.js +315 -71
  42. package/dist/cli/eval.js.map +1 -1
  43. package/dist/cli/functions.d.ts.map +1 -1
  44. package/dist/cli/functions.js +125 -35
  45. package/dist/cli/functions.js.map +1 -1
  46. package/dist/cli/index.js +63 -54
  47. package/dist/cli/index.js.map +1 -1
  48. package/dist/cli/init.d.ts +27 -0
  49. package/dist/cli/init.d.ts.map +1 -0
  50. package/dist/cli/init.js +152 -0
  51. package/dist/cli/init.js.map +1 -0
  52. package/dist/cli/kb.d.ts.map +1 -1
  53. package/dist/cli/kb.js +141 -15
  54. package/dist/cli/kb.js.map +1 -1
  55. package/dist/cli/link.d.ts +21 -0
  56. package/dist/cli/link.d.ts.map +1 -0
  57. package/dist/cli/link.js +112 -0
  58. package/dist/cli/link.js.map +1 -0
  59. package/dist/cli/org.d.ts.map +1 -1
  60. package/dist/cli/org.js +79 -67
  61. package/dist/cli/org.js.map +1 -1
  62. package/dist/cli/platform.d.ts +3 -0
  63. package/dist/cli/platform.d.ts.map +1 -0
  64. package/dist/cli/platform.js +133 -0
  65. package/dist/cli/platform.js.map +1 -0
  66. package/dist/cli/tickets.d.ts +3 -0
  67. package/dist/cli/tickets.d.ts.map +1 -0
  68. package/dist/cli/tickets.js +125 -0
  69. package/dist/cli/tickets.js.map +1 -0
  70. package/dist/cli/utils/output.d.ts +15 -9
  71. package/dist/cli/utils/output.d.ts.map +1 -1
  72. package/dist/cli/utils/output.js +53 -46
  73. package/dist/cli/utils/output.js.map +1 -1
  74. package/dist/cli/voice.d.ts +3 -0
  75. package/dist/cli/voice.d.ts.map +1 -0
  76. package/dist/cli/voice.js +206 -0
  77. package/dist/cli/voice.js.map +1 -0
  78. package/dist/core/diff.d.ts +16 -0
  79. package/dist/core/diff.d.ts.map +1 -0
  80. package/dist/core/diff.js +57 -0
  81. package/dist/core/diff.js.map +1 -0
  82. package/dist/core/org-resolver.d.ts +37 -0
  83. package/dist/core/org-resolver.d.ts.map +1 -0
  84. package/dist/core/org-resolver.js +73 -0
  85. package/dist/core/org-resolver.js.map +1 -0
  86. package/dist/core/runtime.d.ts +36 -0
  87. package/dist/core/runtime.d.ts.map +1 -0
  88. package/dist/core/runtime.js +62 -0
  89. package/dist/core/runtime.js.map +1 -0
  90. package/dist/core/scope.d.ts +33 -0
  91. package/dist/core/scope.d.ts.map +1 -0
  92. package/dist/core/scope.js +37 -0
  93. package/dist/core/scope.js.map +1 -0
  94. package/dist/mcp/registry.d.ts +67 -0
  95. package/dist/mcp/registry.d.ts.map +1 -0
  96. package/dist/mcp/registry.js +195 -0
  97. package/dist/mcp/registry.js.map +1 -0
  98. package/dist/mcp/server.d.ts +9 -0
  99. package/dist/mcp/server.d.ts.map +1 -1
  100. package/dist/mcp/server.js +87 -2
  101. package/dist/mcp/server.js.map +1 -1
  102. package/dist/mcp/tool-meta.d.ts +21 -0
  103. package/dist/mcp/tool-meta.d.ts.map +1 -0
  104. package/dist/mcp/tool-meta.js +203 -0
  105. package/dist/mcp/tool-meta.js.map +1 -0
  106. package/dist/mcp/tools.d.ts +2 -1
  107. package/dist/mcp/tools.d.ts.map +1 -1
  108. package/dist/mcp/tools.js +1462 -215
  109. package/dist/mcp/tools.js.map +1 -1
  110. package/dist/sdk/agent-bundle.d.ts +99 -0
  111. package/dist/sdk/agent-bundle.d.ts.map +1 -0
  112. package/dist/sdk/agent-bundle.js +211 -0
  113. package/dist/sdk/agent-bundle.js.map +1 -0
  114. package/dist/sdk/agents.d.ts +54 -1
  115. package/dist/sdk/agents.d.ts.map +1 -1
  116. package/dist/sdk/agents.js +59 -5
  117. package/dist/sdk/agents.js.map +1 -1
  118. package/dist/sdk/analytics.d.ts +158 -0
  119. package/dist/sdk/analytics.d.ts.map +1 -0
  120. package/dist/sdk/analytics.js +185 -0
  121. package/dist/sdk/analytics.js.map +1 -0
  122. package/dist/sdk/auth.d.ts +34 -12
  123. package/dist/sdk/auth.d.ts.map +1 -1
  124. package/dist/sdk/auth.js +60 -77
  125. package/dist/sdk/auth.js.map +1 -1
  126. package/dist/sdk/billing.d.ts +25 -0
  127. package/dist/sdk/billing.d.ts.map +1 -0
  128. package/dist/sdk/billing.js +61 -0
  129. package/dist/sdk/billing.js.map +1 -0
  130. package/dist/sdk/campaigns.d.ts +35 -0
  131. package/dist/sdk/campaigns.d.ts.map +1 -0
  132. package/dist/sdk/campaigns.js +59 -0
  133. package/dist/sdk/campaigns.js.map +1 -0
  134. package/dist/sdk/chat.d.ts +25 -2
  135. package/dist/sdk/chat.d.ts.map +1 -1
  136. package/dist/sdk/chat.js +37 -10
  137. package/dist/sdk/chat.js.map +1 -1
  138. package/dist/sdk/client.d.ts +93 -5
  139. package/dist/sdk/client.d.ts.map +1 -1
  140. package/dist/sdk/client.js +362 -100
  141. package/dist/sdk/client.js.map +1 -1
  142. package/dist/sdk/config-change.d.ts +74 -0
  143. package/dist/sdk/config-change.d.ts.map +1 -0
  144. package/dist/sdk/config-change.js +117 -0
  145. package/dist/sdk/config-change.js.map +1 -0
  146. package/dist/sdk/config.d.ts.map +1 -1
  147. package/dist/sdk/config.js +2 -1
  148. package/dist/sdk/config.js.map +1 -1
  149. package/dist/sdk/conversations.d.ts +101 -0
  150. package/dist/sdk/conversations.d.ts.map +1 -0
  151. package/dist/sdk/conversations.js +155 -0
  152. package/dist/sdk/conversations.js.map +1 -0
  153. package/dist/sdk/credentials.d.ts +25 -0
  154. package/dist/sdk/credentials.d.ts.map +1 -0
  155. package/dist/sdk/credentials.js +44 -0
  156. package/dist/sdk/credentials.js.map +1 -0
  157. package/dist/sdk/distribution.d.ts +94 -0
  158. package/dist/sdk/distribution.d.ts.map +1 -0
  159. package/dist/sdk/distribution.js +100 -0
  160. package/dist/sdk/distribution.js.map +1 -0
  161. package/dist/sdk/eval.d.ts +81 -0
  162. package/dist/sdk/eval.d.ts.map +1 -1
  163. package/dist/sdk/eval.js +117 -0
  164. package/dist/sdk/eval.js.map +1 -1
  165. package/dist/sdk/functions.d.ts +14 -1
  166. package/dist/sdk/functions.d.ts.map +1 -1
  167. package/dist/sdk/functions.js +48 -5
  168. package/dist/sdk/functions.js.map +1 -1
  169. package/dist/sdk/index.d.ts +2 -0
  170. package/dist/sdk/index.d.ts.map +1 -1
  171. package/dist/sdk/index.js +2 -0
  172. package/dist/sdk/index.js.map +1 -1
  173. package/dist/sdk/jarvis-chat.d.ts +28 -0
  174. package/dist/sdk/jarvis-chat.d.ts.map +1 -0
  175. package/dist/sdk/jarvis-chat.js +117 -0
  176. package/dist/sdk/jarvis-chat.js.map +1 -0
  177. package/dist/sdk/kb.d.ts +69 -1
  178. package/dist/sdk/kb.d.ts.map +1 -1
  179. package/dist/sdk/kb.js +111 -24
  180. package/dist/sdk/kb.js.map +1 -1
  181. package/dist/sdk/orgs.d.ts +13 -0
  182. package/dist/sdk/orgs.d.ts.map +1 -0
  183. package/dist/sdk/orgs.js +59 -0
  184. package/dist/sdk/orgs.js.map +1 -0
  185. package/dist/sdk/platform.d.ts +62 -0
  186. package/dist/sdk/platform.d.ts.map +1 -0
  187. package/dist/sdk/platform.js +95 -0
  188. package/dist/sdk/platform.js.map +1 -0
  189. package/dist/sdk/session.d.ts +25 -0
  190. package/dist/sdk/session.d.ts.map +1 -0
  191. package/dist/sdk/session.js +69 -0
  192. package/dist/sdk/session.js.map +1 -0
  193. package/dist/sdk/skills.d.ts +46 -0
  194. package/dist/sdk/skills.d.ts.map +1 -0
  195. package/dist/sdk/skills.js +203 -0
  196. package/dist/sdk/skills.js.map +1 -0
  197. package/dist/sdk/test-chat.d.ts +52 -0
  198. package/dist/sdk/test-chat.d.ts.map +1 -0
  199. package/dist/sdk/test-chat.js +134 -0
  200. package/dist/sdk/test-chat.js.map +1 -0
  201. package/dist/sdk/tickets.d.ts +98 -0
  202. package/dist/sdk/tickets.d.ts.map +1 -0
  203. package/dist/sdk/tickets.js +91 -0
  204. package/dist/sdk/tickets.js.map +1 -0
  205. package/dist/sdk/types.d.ts +91 -6
  206. package/dist/sdk/types.d.ts.map +1 -1
  207. package/dist/sdk/voice.d.ts +147 -0
  208. package/dist/sdk/voice.d.ts.map +1 -0
  209. package/dist/sdk/voice.js +236 -0
  210. package/dist/sdk/voice.js.map +1 -0
  211. package/package.json +22 -3
  212. package/scripts/check-skills.mjs +25 -0
  213. package/skills/agent-builder/SKILL.md +89 -252
  214. package/skills/evaluations/SKILL.md +23 -234
  215. package/skills/evaluations/references/analysis.md +95 -0
  216. package/skills/evaluations/references/cli-reference.md +28 -0
  217. package/skills/evaluations/references/json-formats.md +100 -0
  218. package/src/cli/agents.ts +202 -22
  219. package/src/cli/analytics.ts +138 -0
  220. package/src/cli/auth.ts +56 -18
  221. package/src/cli/billing.ts +25 -0
  222. package/src/cli/campaigns.ts +33 -0
  223. package/src/cli/chat.ts +66 -115
  224. package/src/cli/config.ts +65 -31
  225. package/src/cli/conversations.ts +133 -0
  226. package/src/cli/distribution.ts +116 -0
  227. package/src/cli/eval.ts +254 -70
  228. package/src/cli/functions.ts +122 -36
  229. package/src/cli/index.ts +58 -55
  230. package/src/cli/init.ts +154 -0
  231. package/src/cli/kb.ts +120 -17
  232. package/src/cli/link.ts +117 -0
  233. package/src/cli/org.ts +81 -75
  234. package/src/cli/platform.ts +128 -0
  235. package/src/cli/tickets.ts +130 -0
  236. package/src/cli/utils/output.ts +51 -42
  237. package/src/cli/voice.ts +204 -0
  238. package/src/core/diff.ts +52 -0
  239. package/src/core/org-resolver.ts +113 -0
  240. package/src/core/runtime.ts +73 -0
  241. package/src/core/scope.ts +64 -0
  242. package/src/mcp/registry.ts +236 -0
  243. package/src/mcp/server.ts +84 -2
  244. package/src/mcp/tool-meta.ts +241 -0
  245. package/src/mcp/tools.ts +1529 -265
  246. package/src/sdk/agent-bundle.ts +245 -0
  247. package/src/sdk/agents.ts +74 -5
  248. package/src/sdk/analytics.ts +220 -0
  249. package/src/sdk/auth.ts +87 -107
  250. package/src/sdk/billing.ts +59 -0
  251. package/src/sdk/campaigns.ts +60 -0
  252. package/src/sdk/chat.ts +44 -10
  253. package/src/sdk/client.ts +373 -102
  254. package/src/sdk/config-change.ts +148 -0
  255. package/src/sdk/config.ts +2 -1
  256. package/src/sdk/conversations.ts +199 -0
  257. package/src/sdk/credentials.ts +53 -0
  258. package/src/sdk/distribution.ts +132 -0
  259. package/src/sdk/eval.ts +140 -0
  260. package/src/sdk/functions.ts +52 -6
  261. package/src/sdk/index.ts +2 -0
  262. package/src/sdk/jarvis-chat.ts +112 -0
  263. package/src/sdk/kb.ts +116 -29
  264. package/src/sdk/orgs.ts +62 -0
  265. package/src/sdk/platform.ts +115 -0
  266. package/src/sdk/session.ts +90 -0
  267. package/src/sdk/skills.ts +188 -0
  268. package/src/sdk/test-chat.ts +151 -0
  269. package/src/sdk/tickets.ts +120 -0
  270. package/src/sdk/types.ts +88 -6
  271. package/src/sdk/voice.ts +262 -0
  272. package/test/cli/entry.test.ts +34 -0
  273. package/test/cli/init.test.ts +66 -0
  274. package/test/cli/link.test.ts +57 -0
  275. package/test/core/org-resolver.test.ts +92 -0
  276. package/test/core/runtime.test.ts +30 -0
  277. package/test/core/scope.test.ts +93 -0
  278. package/test/harness.test.ts +24 -0
  279. package/test/helpers/config-home.ts +22 -0
  280. package/test/helpers/fake-middleware.ts +56 -0
  281. package/test/helpers/fetch-recorder.ts +75 -0
  282. package/test/helpers/jwt.ts +9 -0
  283. package/test/helpers/mcp-pair.ts +38 -0
  284. package/test/mcp/__snapshots__/tools-snapshot.test.ts.snap +145 -0
  285. package/test/mcp/askers.test.ts +60 -0
  286. package/test/mcp/elicit-timeout.test.ts +29 -0
  287. package/test/mcp/registry.test.ts +169 -0
  288. package/test/mcp/shaping.test.ts +41 -0
  289. package/test/mcp/tools-snapshot.test.ts +42 -0
  290. package/test/sdk/agents.test.ts +232 -0
  291. package/test/sdk/analytics.test.ts +89 -0
  292. package/test/sdk/auth.test.ts +70 -0
  293. package/test/sdk/billing.test.ts +47 -0
  294. package/test/sdk/campaigns.test.ts +43 -0
  295. package/test/sdk/client.test.ts +80 -0
  296. package/test/sdk/config-change.test.ts +142 -0
  297. package/test/sdk/conversations.test.ts +80 -0
  298. package/test/sdk/credentials.test.ts +33 -0
  299. package/test/sdk/distribution.test.ts +55 -0
  300. package/test/sdk/eval.test.ts +155 -0
  301. package/test/sdk/kb-upload.test.ts +50 -0
  302. package/test/sdk/kb.test.ts +95 -0
  303. package/test/sdk/orgs.test.ts +48 -0
  304. package/test/sdk/platform.test.ts +89 -0
  305. package/test/sdk/renewal.test.ts +115 -0
  306. package/test/sdk/session.test.ts +60 -0
  307. package/test/sdk/skills.test.ts +235 -0
  308. package/test/sdk/test-chat.test.ts +112 -0
  309. package/test/sdk/tickets.test.ts +42 -0
  310. package/test/sdk/voice.test.ts +147 -0
  311. package/vitest.config.ts +11 -0
@@ -0,0 +1,95 @@
1
+ import { CliError, EXIT } from '../core/runtime.js';
2
+ /** Which of them the CLI may change. Components and connectors are a global catalog with no auth on Darwin: read-only here. */
3
+ const WRITABLE = ['agents', 'templates', 'connector-bindings', 'scenarios'];
4
+ function assertWritable(resource) {
5
+ if (!WRITABLE.includes(resource)) {
6
+ throw new CliError(`${resource} is a shared catalog on the V2 platform; the CLI only reads it.`, EXIT.NEEDS_INPUT);
7
+ }
8
+ }
9
+ /** The V2 platform (Darwin): V2 agents, templates, scenarios, simulations and Jarvis jobs, all checked by Darwin against your org and role. */
10
+ export class PlatformSDK {
11
+ client;
12
+ constructor(client) {
13
+ this.client = client;
14
+ }
15
+ list(resource, query) {
16
+ return this.client.platformRequest('GET', `/${resource}`, { query });
17
+ }
18
+ get(resource, id) {
19
+ return this.client.platformRequest('GET', `/${resource}/${encodeURIComponent(id)}`);
20
+ }
21
+ async create(resource, body) {
22
+ assertWritable(resource);
23
+ return this.client.platformRequest('POST', `/${resource}`, { body });
24
+ }
25
+ async update(resource, id, body) {
26
+ assertWritable(resource);
27
+ return this.client.platformRequest('PUT', `/${resource}/${encodeURIComponent(id)}`, { body });
28
+ }
29
+ async remove(resource, id) {
30
+ assertWritable(resource);
31
+ return this.client.platformRequest('DELETE', `/${resource}/${encodeURIComponent(id)}`);
32
+ }
33
+ /** Checks a template's graph: components exist and edges point at real nodes. */
34
+ validateTemplate(id) {
35
+ return this.client.platformRequest('POST', `/templates/${encodeURIComponent(id)}/validate`);
36
+ }
37
+ /** Validates input against a connector's schema and previews the request; never calls the connector. */
38
+ testConnector(id, input) {
39
+ return this.client.platformRequest('POST', `/connectors/${encodeURIComponent(id)}/test`, { body: { test_input: input } });
40
+ }
41
+ /** Run scenarios against a V2 agent. Darwin does not check the agent's org here, so the agent is read first (that read is org-checked). */
42
+ async runSimulation(agentId, scenarioIds = []) {
43
+ await this.get('agents', agentId);
44
+ return this.client.platformRequest('POST', '/simulations/run', { body: { agent_id: agentId, scenario_ids: scenarioIds, triggered_by: 'user' } });
45
+ }
46
+ simulationJobs(filter = {}) {
47
+ const q = {};
48
+ if (filter.agentId)
49
+ q.agent_id = filter.agentId;
50
+ if (filter.status)
51
+ q.status = filter.status;
52
+ return this.client.platformRequest('GET', '/simulations/jobs', { query: q });
53
+ }
54
+ simulationJob(id) {
55
+ return this.client.platformRequest('GET', `/simulations/jobs/${encodeURIComponent(id)}`);
56
+ }
57
+ simulationResults(filter = {}) {
58
+ if (filter.resultId)
59
+ return this.client.platformRequest('GET', `/simulations/results/${encodeURIComponent(filter.resultId)}`);
60
+ const q = { limit: String(Math.min(filter.limit ?? 10, 100)) };
61
+ if (filter.agentId)
62
+ q.agent_id = filter.agentId;
63
+ return this.client.platformRequest('GET', '/simulations/results', { query: q });
64
+ }
65
+ /** Which agents of the org have a baseline evaluation, and which are stale. */
66
+ orgEvaluations() {
67
+ return this.client.platformRequest('GET', '/org-evaluations');
68
+ }
69
+ /** Ask Jarvis to generate baseline evaluations for up to 50 agents (Darwin checks they are in the org). */
70
+ createJarvisJob(botIds) {
71
+ if (botIds.length < 1 || botIds.length > 50)
72
+ throw new CliError('Give 1 to 50 agent ids.', EXIT.NEEDS_INPUT);
73
+ return this.client.platformRequest('POST', '/jarvis/jobs', { body: { job_type: 'baseline_generation', bot_ids: botIds } });
74
+ }
75
+ jarvisJobs(status) {
76
+ return this.client.platformRequest('GET', '/jarvis/jobs', { query: status ? { status } : undefined });
77
+ }
78
+ jarvisJob(id) {
79
+ return this.client.platformRequest('GET', `/jarvis/jobs/${encodeURIComponent(id)}`);
80
+ }
81
+ /** Poll a Jarvis job until it completes (Darwin never marks jobs failed; per-agent failures are in progress.results). */
82
+ async waitForJarvisJob(id, opts = {}) {
83
+ const started = Date.now();
84
+ for (;;) {
85
+ const job = await this.jarvisJob(id);
86
+ opts.onProgress?.(job);
87
+ if (job.status === 'completed' || job.status === 'failed')
88
+ return job;
89
+ if (Date.now() - started > (opts.timeoutMs ?? 30 * 60_000))
90
+ throw new CliError(`Jarvis job ${id} is still ${job.status}.`);
91
+ await new Promise((r) => setTimeout(r, opts.intervalMs ?? 5_000));
92
+ }
93
+ }
94
+ }
95
+ //# sourceMappingURL=platform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.js","sourceRoot":"","sources":["../../src/sdk/platform.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { Environment, StoredSession } from './types.js';
2
+ export type { StoredSession };
3
+ export type UnauthPost = <T>(path: string, body: unknown, headers?: Record<string, string>) => Promise<T>;
4
+ /** Expiry from the JWT `exp` claim, or null when the token has none. */
5
+ export declare function tokenExpiry(token: string): Date | null;
6
+ /** Renew when less than `windowMs` (default one hour) of life is left. Unknown expiry never renews. */
7
+ export declare function needsRenewal(session: StoredSession, now?: Date, windowMs?: number): boolean;
8
+ /** Trade the Firebase refresh token for a fresh Firebase ID token (Google secure-token API). */
9
+ export declare function refreshIdToken(env: Environment, refreshToken: string): Promise<{
10
+ idToken: string;
11
+ refreshToken: string;
12
+ }>;
13
+ /**
14
+ * Exchange a Firebase ID token for a copilot session, exactly as the dashboard
15
+ * does. Accounts with MFA get an emailed code; without a way to ask for it the
16
+ * caller must log in interactively.
17
+ */
18
+ export declare function exchangeIdToken(post: UnauthPost, idToken: string, askMfaCode?: () => Promise<string>): Promise<{
19
+ token: string;
20
+ userId: string;
21
+ email?: string;
22
+ }>;
23
+ /** Package a copilot token for storage. */
24
+ export declare function toStoredSession(token: string, refreshToken?: string): StoredSession;
25
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/sdk/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE7D,YAAY,EAAE,aAAa,EAAE,CAAC;AAM9B,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;AAI1G,wEAAwE;AACxE,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAStD;AAED,uGAAuG;AACvG,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,GAAE,IAAiB,EAAE,QAAQ,SAAiB,GAAG,OAAO,CAI/G;AAED,gGAAgG;AAChG,wBAAsB,cAAc,CAAC,GAAG,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CAc/H;AAMD;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GACjC,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAsB5D;AAED,2CAA2C;AAC3C,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,aAAa,CAGnF"}
@@ -0,0 +1,69 @@
1
+ import { SessionExpiredError } from '../core/runtime.js';
2
+ import { FIREBASE_CONFIGS } from './auth.js';
3
+ const SECURE_TOKEN_URL = 'https://securetoken.googleapis.com/v1/token';
4
+ const RELOGIN = 'Run `indemn login` in a terminal, then retry.';
5
+ /** Expiry from the JWT `exp` claim, or null when the token has none. */
6
+ export function tokenExpiry(token) {
7
+ const payload = token.split('.')[1];
8
+ if (!payload)
9
+ return null;
10
+ try {
11
+ const claims = JSON.parse(Buffer.from(payload, 'base64url').toString('utf8'));
12
+ return typeof claims.exp === 'number' ? new Date(claims.exp * 1000) : null;
13
+ }
14
+ catch {
15
+ return null;
16
+ }
17
+ }
18
+ /** Renew when less than `windowMs` (default one hour) of life is left. Unknown expiry never renews. */
19
+ export function needsRenewal(session, now = new Date(), windowMs = 60 * 60 * 1000) {
20
+ const expiry = session.expires_at ? new Date(session.expires_at) : tokenExpiry(session.token);
21
+ if (!expiry || Number.isNaN(expiry.getTime()))
22
+ return false;
23
+ return expiry.getTime() - now.getTime() < windowMs;
24
+ }
25
+ /** Trade the Firebase refresh token for a fresh Firebase ID token (Google secure-token API). */
26
+ export async function refreshIdToken(env, refreshToken) {
27
+ const url = `${SECURE_TOKEN_URL}?key=${encodeURIComponent(FIREBASE_CONFIGS[env].apiKey)}`;
28
+ const res = await fetch(url, {
29
+ method: 'POST',
30
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
31
+ body: new URLSearchParams({ grant_type: 'refresh_token', refresh_token: refreshToken }).toString(),
32
+ });
33
+ if (!res.ok) {
34
+ // Revoked, password changed or account disabled: a real login is the right answer.
35
+ throw new SessionExpiredError(`Session expired and could not be renewed. ${RELOGIN}`);
36
+ }
37
+ const json = await res.json();
38
+ if (!json.id_token)
39
+ throw new SessionExpiredError(`Session renewal returned no token. ${RELOGIN}`);
40
+ return { idToken: json.id_token, refreshToken: json.refresh_token || refreshToken };
41
+ }
42
+ function stripScheme(token) {
43
+ return token.replace(/^JWT\s+/i, '');
44
+ }
45
+ /**
46
+ * Exchange a Firebase ID token for a copilot session, exactly as the dashboard
47
+ * does. Accounts with MFA get an emailed code; without a way to ask for it the
48
+ * caller must log in interactively.
49
+ */
50
+ export async function exchangeIdToken(post, idToken, askMfaCode) {
51
+ const signin = await post('/auth/firebase/signin', { idToken });
52
+ if (signin.requiresMfa) {
53
+ if (!askMfaCode) {
54
+ throw new SessionExpiredError(`Your account needs an MFA code to renew the session. ${RELOGIN}`);
55
+ }
56
+ const code = (await askMfaCode()).trim();
57
+ const verified = await post('/auth/firebase/mfa/verify', { sessionId: signin.mfaSessionId, code });
58
+ return { token: stripScheme(verified.token), userId: verified.user._id, email: verified.user.email };
59
+ }
60
+ if (!signin.token || !signin.user)
61
+ throw new SessionExpiredError(`Sign-in returned no session. ${RELOGIN}`);
62
+ return { token: stripScheme(signin.token), userId: signin.user._id, email: signin.user.email };
63
+ }
64
+ /** Package a copilot token for storage. */
65
+ export function toStoredSession(token, refreshToken) {
66
+ const expiry = tokenExpiry(token);
67
+ return { token, expires_at: expiry?.toISOString(), refresh_token: refreshToken };
68
+ }
69
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/sdk/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * copilot's name skeleton (utils/stringUtil.js skillNameKey), reproduced so a
3
+ * clash is reported before anything is sent. "FAQs Retriever",
4
+ * "FQ retrievers" and "F.A.Q. retrieval tool" all become "fqrtrv".
5
+ */
6
+ export declare function skillNameKey(name: string): string;
7
+ /** Throw the same error copilot would, before any request, when a name imitates a built-in skill. */
8
+ export declare function assertSkillNameAllowed(name: string | undefined, type?: string): void;
9
+ /**
10
+ * A secret passed to a flag, kept out of shell history when possible:
11
+ * "@path" reads a file, "env:NAME" reads an environment variable, "-" reads
12
+ * stdin. A plain value still works but prints a warning.
13
+ */
14
+ export declare function resolveSecretArg(flag: string, value: string | undefined, warn?: (msg: string) => void): string | undefined;
15
+ /** Find the list of proposed skills in a generate-from-doc answer. */
16
+ /**
17
+ * A skill's configurationSchema from plain fields, laid over `base` (the saved one on update,
18
+ * since copilot replaces it whole). copilot needs an authorization type on rest_api skills;
19
+ * unauthenticated APIs get no-auth.
20
+ */
21
+ /**
22
+ * A call-transfer destination the way the dashboard saves it: phoneNumber (+ intlTelObj) or sipUri
23
+ * (+ sipHeaders). Older skills say handoffNumber, and some exports carry the runtime's
24
+ * {"action":"transfer","payload":{"to":...}} as payload. copilot reads sipUri, then phoneNumber, then
25
+ * handoffNumber, so a new destination in `patch` must replace the saved one of either kind.
26
+ */
27
+ export declare function transferDestination(base: Record<string, unknown>, patch?: Record<string, unknown>): Record<string, unknown>;
28
+ /**
29
+ * The dashboard's REST form quotes a bare {{parameter}} before saving (rest-api-form.tsx quoteBareMentions):
30
+ * `"guests": {{guests}}` becomes `"guests": "{{guests}}"`, so the body is the valid JSON copilot requires.
31
+ */
32
+ export declare function quoteBareMentions(payload: string): string;
33
+ /** A REST body as copilot saves it: JSON text with bare placeholders quoted; refused when it is still not JSON. */
34
+ export declare function requestBody(payload: unknown): string;
35
+ export declare function skillConfiguration(type: string, f: {
36
+ url?: string;
37
+ method?: string;
38
+ payload?: unknown;
39
+ response_field?: string;
40
+ output_instructions?: string;
41
+ craft_response?: boolean;
42
+ configuration?: Record<string, unknown>;
43
+ transfer_to?: string;
44
+ }, base?: Record<string, unknown>): Record<string, unknown> | undefined;
45
+ export declare function proposedSkills(res: unknown): Array<Record<string, unknown>> | null;
46
+ //# sourceMappingURL=skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/sdk/skills.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAWjD;AAED,qGAAqG;AACrG,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CASpF;AAQD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAA4C,GAAG,MAAM,GAAG,SAAS,CAkBjK;AAED,sEAAsE;AACtE;;;;GAIG;AACH;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA2B/H;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAwBzD;AAED,mHAAmH;AACnH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAUpD;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,CAAC,EAAE;IACD,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAC1E,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChG,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,EACD,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACjC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAerC;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,CAUlF"}
@@ -0,0 +1,203 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { CliError, EXIT } from '../core/runtime.js';
3
+ const FILLER_WORDS = new Set(['tool', 'tools', 'skill', 'skills', 'function', 'functions']);
4
+ /** Built-in skills a user skill must not imitate (copilot utils/constants.js INTERNAL_FUNCTIONS_LIST). */
5
+ const INTERNAL_SKILLS = ['faqs-retriever'];
6
+ /**
7
+ * copilot's name skeleton (utils/stringUtil.js skillNameKey), reproduced so a
8
+ * clash is reported before anything is sent. "FAQs Retriever",
9
+ * "FQ retrievers" and "F.A.Q. retrieval tool" all become "fqrtrv".
10
+ */
11
+ export function skillNameKey(name) {
12
+ const joined = String(name || '')
13
+ .replace(/[.']/g, '')
14
+ .replace(/([a-z])([A-Z])/g, '$1 $2')
15
+ .toLowerCase()
16
+ .split(/[^a-z]+/)
17
+ .filter((word) => word && !FILLER_WORDS.has(word))
18
+ .map((word) => (word.length > 4 ? word.replace(/(ers|er|als|al|ings|ing|e)$/, '') : word))
19
+ .sort()
20
+ .join('');
21
+ return joined.charAt(0) + joined.slice(1).replace(/[aeious]/g, '');
22
+ }
23
+ /** Throw the same error copilot would, before any request, when a name imitates a built-in skill. */
24
+ export function assertSkillNameAllowed(name, type) {
25
+ if (!name || (type && INTERNAL_SKILLS.includes(type)))
26
+ return;
27
+ const key = skillNameKey(name);
28
+ if (INTERNAL_SKILLS.some((reserved) => skillNameKey(reserved) === key)) {
29
+ throw new CliError(`"${name}" is too similar to the built-in skill "${INTERNAL_SKILLS.join('", "')}", which every agent already has. Choose a different name.`, EXIT.NEEDS_INPUT);
30
+ }
31
+ }
32
+ let stdinCache;
33
+ function readStdin() {
34
+ if (stdinCache === undefined)
35
+ stdinCache = readFileSync(0, 'utf8');
36
+ return stdinCache;
37
+ }
38
+ /**
39
+ * A secret passed to a flag, kept out of shell history when possible:
40
+ * "@path" reads a file, "env:NAME" reads an environment variable, "-" reads
41
+ * stdin. A plain value still works but prints a warning.
42
+ */
43
+ export function resolveSecretArg(flag, value, warn = (m) => process.stderr.write(m + '\n')) {
44
+ if (value === undefined)
45
+ return undefined;
46
+ if (value === '-')
47
+ return readStdin().trim();
48
+ if (value.startsWith('@')) {
49
+ try {
50
+ return readFileSync(value.slice(1), 'utf8').trim();
51
+ }
52
+ catch {
53
+ throw new CliError(`${flag}: cannot read ${value.slice(1)}.`);
54
+ }
55
+ }
56
+ if (value.startsWith('env:')) {
57
+ const name = value.slice(4);
58
+ const v = process.env[name];
59
+ if (v === undefined || v === '')
60
+ throw new CliError(`${flag}: environment variable ${name} is not set.`);
61
+ return v;
62
+ }
63
+ warn(`Warning: ${flag} was typed on the command line and is now in your shell history. Next time use ${flag} @file, ${flag} env:NAME or ${flag} - (stdin).`);
64
+ return value;
65
+ }
66
+ /** Find the list of proposed skills in a generate-from-doc answer. */
67
+ /**
68
+ * A skill's configurationSchema from plain fields, laid over `base` (the saved one on update,
69
+ * since copilot replaces it whole). copilot needs an authorization type on rest_api skills;
70
+ * unauthenticated APIs get no-auth.
71
+ */
72
+ /**
73
+ * A call-transfer destination the way the dashboard saves it: phoneNumber (+ intlTelObj) or sipUri
74
+ * (+ sipHeaders). Older skills say handoffNumber, and some exports carry the runtime's
75
+ * {"action":"transfer","payload":{"to":...}} as payload. copilot reads sipUri, then phoneNumber, then
76
+ * handoffNumber, so a new destination in `patch` must replace the saved one of either kind.
77
+ */
78
+ export function transferDestination(base, patch = {}) {
79
+ const str = (v) => (typeof v === 'string' && v ? v : undefined);
80
+ const legacyTo = (c) => {
81
+ if (typeof c.payload !== 'string')
82
+ return undefined;
83
+ try {
84
+ const p = JSON.parse(c.payload);
85
+ return p?.action === 'transfer' ? str(p.payload?.to) : undefined;
86
+ }
87
+ catch {
88
+ return undefined;
89
+ }
90
+ };
91
+ const pick = (c) => {
92
+ const to = legacyTo(c);
93
+ const sip = str(c.sipUri) ?? (to?.startsWith('sip:') ? to : undefined);
94
+ const phone = str(c.phoneNumber) ?? str(c.handoffNumber) ?? (to && !to.startsWith('sip:') ? to : undefined);
95
+ return sip ? { sip, headers: c.sipHeaders } : phone ? { phone } : undefined;
96
+ };
97
+ const dest = pick(patch) ?? pick(base);
98
+ const out = { ...base, ...patch };
99
+ if (legacyTo(out) !== undefined) {
100
+ delete out.payload;
101
+ delete out.payloadOps;
102
+ }
103
+ for (const k of ['sipUri', 'sipHeaders', 'phoneNumber', 'intlTelObj', 'handoffNumber'])
104
+ delete out[k];
105
+ if (dest && 'sip' in dest) {
106
+ out.sipUri = dest.sip;
107
+ if (dest.headers && typeof dest.headers === 'object' && Object.keys(dest.headers).length)
108
+ out.sipHeaders = dest.headers;
109
+ }
110
+ else if (dest?.phone) {
111
+ out.phoneNumber = dest.phone;
112
+ out.intlTelObj = { number: dest.phone, e164Number: dest.phone };
113
+ }
114
+ return out;
115
+ }
116
+ /**
117
+ * The dashboard's REST form quotes a bare {{parameter}} before saving (rest-api-form.tsx quoteBareMentions):
118
+ * `"guests": {{guests}}` becomes `"guests": "{{guests}}"`, so the body is the valid JSON copilot requires.
119
+ */
120
+ export function quoteBareMentions(payload) {
121
+ let out = '';
122
+ let inString = false;
123
+ for (let i = 0; i < payload.length; i++) {
124
+ const ch = payload[i];
125
+ if (inString) {
126
+ out += ch;
127
+ if (ch === '\\')
128
+ out += payload[++i] ?? '';
129
+ else if (ch === '"')
130
+ inString = false;
131
+ continue;
132
+ }
133
+ if (ch === '"') {
134
+ inString = true;
135
+ }
136
+ else if (ch === '{' && payload[i + 1] === '{') {
137
+ const close = payload.indexOf('}}', i + 2);
138
+ if (close !== -1) {
139
+ out += JSON.stringify(payload.slice(i, close + 2));
140
+ i = close + 1;
141
+ continue;
142
+ }
143
+ }
144
+ out += ch;
145
+ }
146
+ return out;
147
+ }
148
+ /** A REST body as copilot saves it: JSON text with bare placeholders quoted; refused when it is still not JSON. */
149
+ export function requestBody(payload) {
150
+ if (typeof payload !== 'string')
151
+ return JSON.stringify(payload);
152
+ if (!payload.trim())
153
+ return payload;
154
+ const body = quoteBareMentions(payload);
155
+ try {
156
+ JSON.parse(body);
157
+ }
158
+ catch (err) {
159
+ throw new CliError(`The request body is not valid JSON (${err instanceof Error ? err.message : String(err)}). Nothing was saved. Send it as JSON text, e.g. {"event_date": "{{event_date}}"}.`, EXIT.ERROR);
160
+ }
161
+ return body;
162
+ }
163
+ export function skillConfiguration(type, f, base = {}) {
164
+ const patch = { ...(f.configuration ?? {}) };
165
+ if (f.url !== undefined)
166
+ patch.endpoint = f.url;
167
+ if (f.method !== undefined)
168
+ patch.method = f.method.toUpperCase();
169
+ if (f.payload !== undefined)
170
+ patch.payload = f.payload;
171
+ if (patch.payload !== undefined)
172
+ patch.payload = requestBody(patch.payload);
173
+ if (f.response_field !== undefined)
174
+ patch.responseField = f.response_field;
175
+ if (f.output_instructions !== undefined)
176
+ patch.outputInstructions = f.output_instructions;
177
+ if (f.craft_response !== undefined)
178
+ patch.craftResponse = f.craft_response;
179
+ if (f.transfer_to !== undefined)
180
+ patch[f.transfer_to.startsWith('sip:') ? 'sipUri' : 'phoneNumber'] = f.transfer_to;
181
+ if (!Object.keys(patch).length)
182
+ return undefined;
183
+ if (type === 'transfer_call')
184
+ return transferDestination(base, patch);
185
+ const merged = { ...base, ...patch };
186
+ if (type === 'rest_api' && merged.authorization === undefined)
187
+ merged.authorization = { type: 'no-auth' };
188
+ return merged;
189
+ }
190
+ export function proposedSkills(res) {
191
+ if (Array.isArray(res))
192
+ return res;
193
+ if (res && typeof res === 'object') {
194
+ const r = res;
195
+ for (const key of ['functions', 'skills', 'tools', 'data', 'result']) {
196
+ const found = proposedSkills(r[key]);
197
+ if (found)
198
+ return found;
199
+ }
200
+ }
201
+ return null;
202
+ }
203
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/sdk/skills.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import { IndemnClient } from './client.js';
2
+ import { ChatSession } from './chat.js';
3
+ import type { Agent } from './types.js';
4
+ /** Who is testing: the login email, else the email inside a host-supplied session token. */
5
+ export declare function testerIdentity(client: IndemnClient): string | null;
6
+ /**
7
+ * The dashboard's "Talk to agent" preview record for this person and agent.
8
+ * Reused when it exists (never overwritten, it may hold context they saved in
9
+ * the dashboard); created empty otherwise. Optional: failure only means the
10
+ * dashboard cannot show the tester card.
11
+ */
12
+ export declare function ensurePreview(client: IndemnClient, agentId: string): Promise<string | null>;
13
+ export interface OpenedTestChat {
14
+ session: ChatSession;
15
+ sessionId: string;
16
+ agent: Agent;
17
+ orgId: string;
18
+ projectId: string;
19
+ url: string;
20
+ tester: string | null;
21
+ preview: string | null;
22
+ resumed: boolean;
23
+ /** Every complete agent message so far, greeting included. */
24
+ transcript: string[];
25
+ /** True while the agent is streaming a message. */
26
+ isReceiving: () => boolean;
27
+ }
28
+ /**
29
+ * Open a chat that is guaranteed to be a test conversation in the chosen org:
30
+ * the agent is fetched through copilot (which refuses an agent from another
31
+ * org), the session is opened with isTestMode, and the stored conversation is
32
+ * read back before the caller may send anything.
33
+ */
34
+ export declare function openTestChat(client: IndemnClient, agentId: string, opts?: {
35
+ sessionId?: string;
36
+ verifyTimeoutMs?: number;
37
+ onSession?: (session: ChatSession) => void;
38
+ }): Promise<OpenedTestChat>;
39
+ /**
40
+ * Send one message and collect the reply. A new conversation first waits for
41
+ * the greeting. The reply is complete when the agent has been quiet for
42
+ * `settleMs` after its last message.
43
+ */
44
+ export declare function exchange(chat: OpenedTestChat, message: string, opts?: {
45
+ greetingWaitMs?: number;
46
+ timeoutMs?: number;
47
+ settleMs?: number;
48
+ }): Promise<{
49
+ greeting: string;
50
+ response: string;
51
+ }>;
52
+ //# sourceMappingURL=test-chat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-chat.d.ts","sourceRoot":"","sources":["../../src/sdk/test-chat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,4FAA4F;AAC5F,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAelE;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAUjG;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,WAAW,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,8DAA8D;IAC9D,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,mDAAmD;IACnD,WAAW,EAAE,MAAM,OAAO,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAA;CAAO,GACtG,OAAO,CAAC,cAAc,CAAC,CAyCzB;AAcD;;;;GAIG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE;IAAE,cAAc,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5E,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAiBjD"}