thinkwork-cli 0.12.15 → 0.12.17

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 (152) hide show
  1. package/dist/{api-client-4VT3FWOH.js → api-client-JUBCQQDF.js} +1 -1
  2. package/dist/{chunk-H7AB42ES.js → chunk-STY44FQO.js} +13 -0
  3. package/dist/cli.js +1107 -10225
  4. package/dist/commands/enterprise/templates/deploy-repo/docs/runbook.md +3 -8
  5. package/dist/commands/enterprise/templates/deploy-repo/terraform/main.tf +1 -184
  6. package/dist/drizzle/0050_brain_v0_entity_subtype.sql +2 -2
  7. package/dist/drizzle/0051_brain_v0_tenant_entity_pages.sql +6 -6
  8. package/dist/drizzle/0052_brain_v0_external_refs.sql +2 -2
  9. package/dist/drizzle/0053_brain_v0_unresolved_mentions_subtype.sql +2 -2
  10. package/dist/drizzle/0145_knowledge_graph_thread_ingest.sql +14 -14
  11. package/dist/drizzle/0146_knowledge_graph_source_scope.sql +1 -1
  12. package/dist/drizzle/0157_knowledge_graph_observations_source.sql +2 -2
  13. package/dist/drizzle/0158_wiki_tenant_scope.sql +1 -1
  14. package/dist/drizzle/0165_plugin_premium_entitlements.sql +2 -2
  15. package/dist/drizzle/{0166_company_brain_substrate_contract.sql → 0166_brain_substrate_contract.sql} +9 -9
  16. package/dist/drizzle/{0167_company_brain_artifact_manifest_runtime.sql → 0167_brain_artifact_manifest_runtime.sql} +5 -5
  17. package/dist/drizzle/0168_eval_skill_gate.sql +1 -1
  18. package/dist/drizzle/0183_okf_artifact_manifests.sql +1 -1
  19. package/dist/drizzle/0197_rcm_context_columns.sql +28 -0
  20. package/dist/drizzle/0200_eval_results_execution_tier.sql +40 -0
  21. package/dist/drizzle/0201_brain_dream_runs.sql +72 -0
  22. package/dist/drizzle/0202_backfill_thread_participants_from_senders.sql +110 -0
  23. package/dist/drizzle/0203_threads_mode_override.sql +61 -0
  24. package/dist/drizzle/0204_thread_turns_triggering_message_id.sql +48 -0
  25. package/dist/drizzle/0205_routines_git_python.sql +185 -0
  26. package/dist/drizzle/0206_agent_loop_versions_routine_actions.sql +40 -0
  27. package/dist/drizzle/0207_tenant_credentials_github_repo_kind.sql +52 -0
  28. package/dist/drizzle/0208_knowledge_graph_neutral_identifiers.sql +253 -0
  29. package/dist/drizzle/0209_living_artifacts_schema.sql +109 -0
  30. package/dist/drizzle/0210_think137_automations_additive_schema.sql +113 -0
  31. package/dist/drizzle/0211_backfill_agent_loop_versions_target_spec.sql +120 -0
  32. package/dist/drizzle/0212_fold_webhooks_into_automations.sql +312 -0
  33. package/dist/drizzle/0213_agent_loop_versions_judge_evidence_nullable.sql +63 -0
  34. package/dist/drizzle/0214_think137_drop_judge_evidence_roi.sql +99 -0
  35. package/dist/drizzle/0215_agent_loop_versions_goal_worker_policy_nullable.sql +70 -0
  36. package/dist/drizzle/0216_drop_agent_loop_versions_goal_worker_policy.sql +81 -0
  37. package/dist/drizzle/0217_agents_capability_folder_dispatch.sql +12 -0
  38. package/dist/drizzle/0218_document_plates.sql +30 -0
  39. package/dist/drizzle/0219_document_section_waivers.sql +29 -0
  40. package/dist/drizzle/0220_artifacts_created_by_user.sql +21 -0
  41. package/dist/drizzle/0221_artifact_shares.sql +29 -0
  42. package/dist/drizzle/0221_workflow_interpreter_thin_slice.sql +71 -0
  43. package/dist/drizzle/0222_compliance_drainer_select_audit_events.sql +21 -0
  44. package/dist/drizzle/0223_document_conformance_reports.sql +38 -0
  45. package/dist/drizzle/0224_artifact_refresh_state.sql +11 -0
  46. package/dist/drizzle/0225_think216_agent_loop_convergence.sql +21 -0
  47. package/dist/drizzle/0226_drop_n8n_agent_step_runs.sql +6 -0
  48. package/dist/drizzle/0227_analyst_reader_role.sql +1055 -0
  49. package/dist/drizzle/0228_tenant_credentials_rds_iam_kind.sql +62 -0
  50. package/dist/drizzle/0229_analyst_reader_rds_iam_grant.sql +79 -0
  51. package/dist/drizzle/0230_analyst_rls.sql +1613 -0
  52. package/dist/drizzle/0231_cost_events_cache_write_enforcement_exempt.sql +11 -0
  53. package/dist/plugins/catalog/package.json +0 -1
  54. package/dist/plugins/catalog/src/__tests__/build-catalog.test.ts +0 -1
  55. package/dist/plugins/catalog/src/__tests__/catalog.test.ts +16 -8
  56. package/dist/plugins/catalog/src/__tests__/contracts.test.ts +56 -0
  57. package/dist/plugins/catalog/src/__tests__/plugin-package.test.ts +0 -2
  58. package/dist/plugins/catalog/src/__tests__/plugin-registry.test.ts +0 -5
  59. package/dist/plugins/catalog/src/contracts.ts +112 -0
  60. package/dist/plugins/catalog/src/registry/generated-first-party.ts +0 -6
  61. package/dist/plugins/n8n/README.md +4 -36
  62. package/dist/plugins/n8n/src/deployment/managed-app.ts +0 -17
  63. package/dist/plugins/n8n/src/manifest.ts +0 -5
  64. package/dist/plugins/n8n/terraform/n8n/main.tf +0 -26
  65. package/dist/plugins/n8n/terraform/n8n/outputs.tf +0 -5
  66. package/dist/plugins/n8n/terraform/n8n/variables.tf +0 -6
  67. package/dist/plugins/n8n/test/manifest.test.ts +0 -1
  68. package/dist/plugins/twenty/package.json +5 -0
  69. package/dist/plugins/twenty/scripts/lib/__tests__/load-records.test.ts +232 -0
  70. package/dist/plugins/twenty/scripts/lib/__tests__/mappers.test.ts +489 -0
  71. package/dist/plugins/twenty/scripts/lib/__tests__/members-ensure.test.ts +199 -0
  72. package/dist/plugins/twenty/scripts/lib/__tests__/provision-members-db.test.ts +43 -0
  73. package/dist/plugins/twenty/scripts/lib/__tests__/schema-ensure.test.ts +230 -0
  74. package/dist/plugins/twenty/scripts/lib/__tests__/twenty-client.test.ts +207 -0
  75. package/dist/plugins/twenty/scripts/lib/lastmile-reader.ts +282 -0
  76. package/dist/plugins/twenty/scripts/lib/load-attachments.ts +220 -0
  77. package/dist/plugins/twenty/scripts/lib/load-records.ts +680 -0
  78. package/dist/plugins/twenty/scripts/lib/mappers.ts +559 -0
  79. package/dist/plugins/twenty/scripts/lib/members-ensure.ts +381 -0
  80. package/dist/plugins/twenty/scripts/lib/provision-members-db.ts +191 -0
  81. package/dist/plugins/twenty/scripts/lib/schema-ensure.ts +425 -0
  82. package/dist/plugins/twenty/scripts/lib/twenty-client.ts +246 -0
  83. package/dist/plugins/twenty/scripts/migrate-lastmile.ts +610 -0
  84. package/dist/plugins/twenty/scripts/provision-twenty-members.ts +214 -0
  85. package/dist/plugins/twenty/src/manifest.ts +99 -0
  86. package/dist/plugins/twenty/terraform/twenty/README.md +1 -1
  87. package/dist/plugins/twenty/test/manifest.test.ts +12 -2
  88. package/dist/terraform/examples/greenfield/main.tf +90 -380
  89. package/dist/terraform/examples/greenfield/terraform.tfvars.example +0 -1
  90. package/dist/terraform/modules/app/agentcore-pi/README.md +1 -3
  91. package/dist/terraform/modules/app/agentcore-pi/main.tf +36 -32
  92. package/dist/terraform/modules/app/agentcore-pi/variables.tf +23 -15
  93. package/dist/terraform/modules/app/agentcore-runtime/main.tf +3 -3
  94. package/dist/terraform/modules/app/customer-domain/main.tf +16 -2
  95. package/dist/terraform/modules/app/deployment-control-plane/main.tf +5 -0
  96. package/dist/terraform/modules/app/deployment-control-plane/runner.py +85 -207
  97. package/dist/terraform/modules/app/deployment-control-plane/test_runner_bundle.py +56 -2
  98. package/dist/terraform/modules/app/hindsight-memory/main.tf +52 -4
  99. package/dist/terraform/modules/app/lambda-api/eval-fanout.tf +7 -0
  100. package/dist/terraform/modules/app/lambda-api/handlers.tf +493 -89
  101. package/dist/terraform/modules/app/lambda-api/iam-grouped.tf +215 -96
  102. package/dist/terraform/modules/app/lambda-api/main.tf +24 -5
  103. package/dist/terraform/modules/app/lambda-api/outputs.tf +19 -11
  104. package/dist/terraform/modules/app/lambda-api/variables.tf +94 -67
  105. package/dist/terraform/modules/app/ses-email/main.tf +14 -2
  106. package/dist/terraform/modules/app/workflow-interpreter-stepfunctions/main.tf +493 -0
  107. package/dist/terraform/modules/app/workflow-interpreter-stepfunctions/outputs.tf +34 -0
  108. package/dist/terraform/modules/app/workflow-interpreter-stepfunctions/variables.tf +32 -0
  109. package/dist/terraform/modules/data/aurora-postgres/main.tf +55 -0
  110. package/dist/terraform/modules/data/aurora-postgres/outputs.tf +15 -0
  111. package/dist/terraform/modules/data/s3-buckets/main.tf +26 -0
  112. package/dist/terraform/modules/thinkwork/README.md +0 -1
  113. package/dist/terraform/modules/thinkwork/main.tf +167 -446
  114. package/dist/terraform/modules/thinkwork/outputs.tf +2 -142
  115. package/dist/terraform/modules/thinkwork/variables.tf +55 -309
  116. package/dist/terraform/schema.graphql +4 -0
  117. package/dist/workspace-defaults/files/AGENTS.md +45 -31
  118. package/dist/workspace-defaults/files/CONTEXT.md +48 -4
  119. package/dist/workspace-defaults/files/GUARDRAILS.md +18 -0
  120. package/dist/workspace-defaults/files/MEMORY_GUIDE.md +32 -4
  121. package/dist/workspace-defaults/files/SPACE.md +34 -19
  122. package/dist/workspace-defaults/files/TOOLS.md +30 -0
  123. package/dist/workspace-defaults/files/skills/document-composer/SKILL.md +154 -0
  124. package/dist/workspace-defaults/files/skills/document-composer/references/authoring-rules.md +101 -0
  125. package/package.json +2 -1
  126. package/dist/plugins/company-brain/README.md +0 -37
  127. package/dist/plugins/company-brain/package.json +0 -33
  128. package/dist/plugins/company-brain/runtime/cognee/Dockerfile +0 -11
  129. package/dist/plugins/company-brain/smoke/cognee-managed-app-smoke.mjs +0 -458
  130. package/dist/plugins/company-brain/smoke/cognee-memory-cutover-smoke.mjs +0 -539
  131. package/dist/plugins/company-brain/smoke/company-brain-context-engine-smoke.mjs +0 -312
  132. package/dist/plugins/company-brain/smoke/company-brain-operations-smoke.mjs +0 -449
  133. package/dist/plugins/company-brain/smoke/company-brain-plugin-smoke.mjs +0 -655
  134. package/dist/plugins/company-brain/smoke/hindsight-memory-isolation-smoke.mjs +0 -474
  135. package/dist/plugins/company-brain/src/api/cognee-client.ts +0 -896
  136. package/dist/plugins/company-brain/src/api/cognee-cluster-identity.ts +0 -49
  137. package/dist/plugins/company-brain/src/api/cognee-memory-scope.ts +0 -84
  138. package/dist/plugins/company-brain/src/api/context-engine-provider.ts +0 -888
  139. package/dist/plugins/company-brain/src/api/migration.ts +0 -665
  140. package/dist/plugins/company-brain/src/deployment/cognee-managed-app.ts +0 -396
  141. package/dist/plugins/company-brain/src/index.ts +0 -62
  142. package/dist/plugins/company-brain/src/manifest.ts +0 -112
  143. package/dist/plugins/company-brain/terraform/cognee/README.md +0 -263
  144. package/dist/plugins/company-brain/terraform/cognee/main.tf +0 -766
  145. package/dist/plugins/company-brain/terraform/cognee/outputs.tf +0 -144
  146. package/dist/plugins/company-brain/terraform/cognee/variables.tf +0 -402
  147. package/dist/plugins/company-brain/test/api/cognee-client.test.ts +0 -562
  148. package/dist/plugins/company-brain/test/api/cognee-memory-scope.test.ts +0 -74
  149. package/dist/plugins/company-brain/test/api/context-engine-provider.test.ts +0 -447
  150. package/dist/plugins/company-brain/test/api/migration.test.ts +0 -465
  151. package/dist/plugins/company-brain/test/manifest.test.ts +0 -95
  152. package/dist/plugins/company-brain/tsconfig.json +0 -8
@@ -1,562 +0,0 @@
1
- import { describe, expect, it, vi } from "vitest";
2
- import { CogneeClient } from "../../src/api/cognee-client.js";
3
- import { buildCogneeMemoryScope } from "../../src/api/cognee-memory-scope.js";
4
-
5
- const ontology = {
6
- mechanism: "cognee_owl_ontology" as const,
7
- entityTypes: [],
8
- relationshipTypes: [],
9
- customPrompt: "Extract the graph.",
10
- ontologyKey: "thinkwork_tenant_abc123",
11
- ontologyOwlXml: "<rdf:RDF></rdf:RDF>",
12
- };
13
-
14
- function response(status: number, body: unknown) {
15
- return {
16
- ok: status >= 200 && status < 300,
17
- status,
18
- text: async () => JSON.stringify(body),
19
- } as Response;
20
- }
21
-
22
- function textResponse(status: number, body: string) {
23
- return {
24
- ok: status >= 200 && status < 300,
25
- status,
26
- text: async () => body,
27
- } as Response;
28
- }
29
-
30
- describe("CogneeClient", () => {
31
- it("uses remember and fetches a dataset graph", async () => {
32
- const fetchFn = vi
33
- .fn<typeof fetch>()
34
- .mockResolvedValueOnce(response(200, {}))
35
- .mockResolvedValueOnce(
36
- response(200, {
37
- uploaded_ontologies: [{ ontology_key: ontology.ontologyKey }],
38
- }),
39
- )
40
- .mockResolvedValueOnce(
41
- response(200, { dataset_id: "11111111-1111-4111-8111-111111111111" }),
42
- )
43
- .mockResolvedValueOnce(
44
- response(200, {
45
- nodes: [{ id: "n1", label: "Acme", type: "Company" }],
46
- edges: [{ source: "n1", target: "n1", label: "mentions" }],
47
- }),
48
- );
49
- const client = new CogneeClient({
50
- endpoint: "http://cognee.local/",
51
- token: "token",
52
- fetchFn,
53
- });
54
-
55
- const ingest = await client.ingestThread({
56
- tenantId: "tenant-1",
57
- threadId: "thread-1",
58
- datasetName: "thinkwork:t:thread:x",
59
- transcript: "Acme",
60
- ontology,
61
- });
62
- const graph = await client.fetchDatasetGraph(ingest.datasetId!);
63
-
64
- expect(ingest).toEqual(
65
- expect.objectContaining({
66
- datasetId: "11111111-1111-4111-8111-111111111111",
67
- mode: "remember",
68
- }),
69
- );
70
- expect(fetchFn.mock.calls.map((call) => String(call[0]))).toEqual([
71
- "http://cognee.local/api/v1/ontologies",
72
- "http://cognee.local/api/v1/ontologies",
73
- "http://cognee.local/api/v1/remember",
74
- "http://cognee.local/api/v1/datasets/11111111-1111-4111-8111-111111111111/graph",
75
- ]);
76
- const uploadBody = fetchFn.mock.calls[1]?.[1]?.body;
77
- expect(uploadBody).toBeInstanceOf(FormData);
78
- expect(Object.fromEntries(uploadBody as FormData)).toEqual(
79
- expect.objectContaining({
80
- ontology_key: ontology.ontologyKey,
81
- }),
82
- );
83
- const rememberBody = fetchFn.mock.calls[2]?.[1]?.body;
84
- expect(rememberBody).toBeInstanceOf(FormData);
85
- expect(Array.from((rememberBody as FormData).keys()).sort()).toEqual([
86
- "custom_prompt",
87
- "data",
88
- "datasetName",
89
- "node_set",
90
- "node_set",
91
- "node_set",
92
- "ontology_key",
93
- "run_in_background",
94
- ]);
95
- expect((rememberBody as FormData).getAll("node_set")).toEqual([
96
- "thinkwork_thread",
97
- "tenant_tenant_1",
98
- "thread_thread_1",
99
- ]);
100
- expect((rememberBody as FormData).get("ontology_key")).toBe(
101
- ontology.ontologyKey,
102
- );
103
- expect((rememberBody as FormData).get("run_in_background")).toBe("true");
104
- expect(graph.nodes).toEqual([
105
- {
106
- id: "n1",
107
- label: "Acme",
108
- type: "Company",
109
- properties: {},
110
- },
111
- ]);
112
- });
113
-
114
- it("posts user and space memory documents into separate Cognee scopes", async () => {
115
- const fetchFn = vi
116
- .fn<typeof fetch>()
117
- .mockResolvedValueOnce(response(200, { [ontology.ontologyKey]: {} }))
118
- .mockResolvedValueOnce(
119
- response(200, { dataset_id: "11111111-1111-4111-8111-111111111111" }),
120
- )
121
- .mockResolvedValueOnce(response(200, { [ontology.ontologyKey]: {} }))
122
- .mockResolvedValueOnce(
123
- response(200, { dataset_id: "22222222-2222-4222-8222-222222222222" }),
124
- );
125
- const client = new CogneeClient({
126
- endpoint: "http://cognee.local",
127
- fetchFn,
128
- });
129
- const userScope = buildCogneeMemoryScope({
130
- tenantId: "tenant-1",
131
- kind: "user",
132
- userId: "user-1",
133
- });
134
- const spaceScope = buildCogneeMemoryScope({
135
- tenantId: "tenant-1",
136
- kind: "space",
137
- spaceId: "space-1",
138
- });
139
-
140
- await client.ingestDocument({
141
- tenantId: userScope.tenantId,
142
- sourceKind: userScope.sourceKind,
143
- sourceRef: userScope.sourceRef,
144
- datasetName: userScope.datasetName,
145
- document: "User memory",
146
- filename: "thinkwork-user-memory.md",
147
- ontology,
148
- });
149
- await client.ingestDocument({
150
- tenantId: spaceScope.tenantId,
151
- sourceKind: spaceScope.sourceKind,
152
- sourceRef: spaceScope.sourceRef,
153
- datasetName: spaceScope.datasetName,
154
- document: "Space memory",
155
- filename: "thinkwork-space-memory.md",
156
- ontology,
157
- });
158
-
159
- const userBody = fetchFn.mock.calls[1]?.[1]?.body as FormData;
160
- const spaceBody = fetchFn.mock.calls[3]?.[1]?.body as FormData;
161
- expect(userBody.get("datasetName")).toBe(
162
- "thinkwork:memory:v1:tenant:tenant_1:user:user_1",
163
- );
164
- expect(userBody.getAll("node_set")).toEqual([
165
- "thinkwork_memory",
166
- "thinkwork_memory_v1",
167
- "thinkwork_user_memory",
168
- "tenant_tenant_1",
169
- "user_user_1",
170
- ]);
171
- expect(spaceBody.get("datasetName")).toBe(
172
- "thinkwork:memory:v1:tenant:tenant_1:space:space_1",
173
- );
174
- expect(spaceBody.getAll("node_set")).toEqual([
175
- "thinkwork_memory",
176
- "thinkwork_memory_v1",
177
- "thinkwork_space_memory",
178
- "tenant_tenant_1",
179
- "space_space_1",
180
- ]);
181
- });
182
-
183
- it("posts scoped Cognee search requests", async () => {
184
- const fetchFn = vi
185
- .fn<typeof fetch>()
186
- .mockResolvedValueOnce(
187
- response(200, { results: [{ text: "Use concise summaries." }] }),
188
- );
189
- const client = new CogneeClient({
190
- endpoint: "http://cognee.local",
191
- fetchFn,
192
- });
193
-
194
- const result = await client.search({
195
- query: "summary preference",
196
- searchType: "CHUNKS",
197
- datasets: ["thinkwork:memory:v1:tenant:tenant_1:user:user_1"],
198
- nodeNames: ["thinkwork_user_memory", "user_user_1"],
199
- nodeNameFilterOperator: "AND",
200
- topK: 25,
201
- onlyContext: true,
202
- includeReferences: true,
203
- systemPrompt: "Use memory only.",
204
- });
205
-
206
- expect(result).toEqual({
207
- results: [{ text: "Use concise summaries." }],
208
- });
209
- expect(fetchFn).toHaveBeenCalledWith(
210
- "http://cognee.local/api/v1/search",
211
- expect.objectContaining({
212
- method: "POST",
213
- body: JSON.stringify({
214
- query: "summary preference",
215
- search_type: "CHUNKS",
216
- datasets: ["thinkwork:memory:v1:tenant:tenant_1:user:user_1"],
217
- node_name: ["thinkwork_user_memory", "user_user_1"],
218
- node_name_filter_operator: "AND",
219
- top_k: 25,
220
- only_context: true,
221
- include_references: true,
222
- system_prompt: "Use memory only.",
223
- }),
224
- }),
225
- );
226
- });
227
-
228
- it("falls back to add plus cognify when remember is unsupported", async () => {
229
- const fetchFn = vi
230
- .fn<typeof fetch>()
231
- .mockResolvedValueOnce(response(200, { [ontology.ontologyKey]: {} }))
232
- .mockResolvedValueOnce(response(404, { detail: "missing" }))
233
- .mockResolvedValueOnce(response(200, {}))
234
- .mockResolvedValueOnce(
235
- response(200, { datasetId: "22222222-2222-4222-8222-222222222222" }),
236
- );
237
- const client = new CogneeClient({
238
- endpoint: "http://cognee.local",
239
- fetchFn,
240
- });
241
-
242
- const ingest = await client.ingestThread({
243
- tenantId: "tenant-1",
244
- threadId: "thread-1",
245
- datasetName: "thinkwork:t:thread:x",
246
- transcript: "Acme",
247
- ontology,
248
- });
249
-
250
- expect(ingest).toEqual(
251
- expect.objectContaining({
252
- datasetId: "22222222-2222-4222-8222-222222222222",
253
- mode: "add_cognify",
254
- }),
255
- );
256
- expect(fetchFn.mock.calls.map((call) => String(call[0]))).toEqual([
257
- "http://cognee.local/api/v1/ontologies",
258
- "http://cognee.local/api/v1/remember",
259
- "http://cognee.local/api/v1/add",
260
- "http://cognee.local/api/v1/cognify",
261
- ]);
262
- expect(JSON.parse(String(fetchFn.mock.calls[3]?.[1]?.body))).toEqual({
263
- datasets: ["thinkwork:t:thread:x"],
264
- run_in_background: true,
265
- custom_prompt: ontology.customPrompt,
266
- ontology_key: [ontology.ontologyKey],
267
- });
268
- });
269
-
270
- it("polls dataset status until Cognee indexing completes", async () => {
271
- const fetchFn = vi
272
- .fn<typeof fetch>()
273
- .mockResolvedValueOnce(
274
- response(200, {
275
- "11111111-1111-4111-8111-111111111111": "DATASET_PROCESSING_STARTED",
276
- }),
277
- )
278
- .mockResolvedValueOnce(
279
- response(200, {
280
- "11111111-1111-4111-8111-111111111111":
281
- "DATASET_PROCESSING_COMPLETED",
282
- }),
283
- );
284
-
285
- vi.stubEnv("COGNEE_INDEX_POLL_MS", "1");
286
- try {
287
- const client = new CogneeClient({
288
- endpoint: "http://cognee.local",
289
- fetchFn,
290
- retryDelayMs: 0,
291
- });
292
- const status = await client.waitForDatasetIndexing(
293
- "11111111-1111-4111-8111-111111111111",
294
- );
295
-
296
- expect(status).toEqual(
297
- expect.objectContaining({
298
- status: "completed",
299
- rawStatus: "DATASET_PROCESSING_COMPLETED",
300
- attempts: 2,
301
- }),
302
- );
303
- expect(status.samples.map((sample) => sample.status)).toEqual([
304
- "running",
305
- "completed",
306
- ]);
307
- } finally {
308
- vi.unstubAllEnvs();
309
- }
310
- });
311
-
312
- it("preserves Cognee ontology metadata from graph payloads", async () => {
313
- const fetchFn = vi.fn<typeof fetch>().mockResolvedValueOnce(
314
- response(200, {
315
- nodes: [
316
- {
317
- id: "n1",
318
- label: "Acme",
319
- type: "Entity",
320
- is_a: { name: "Company" },
321
- ontology_valid: true,
322
- },
323
- ],
324
- edges: [
325
- {
326
- id: "e1",
327
- source: "n1",
328
- target: "n1",
329
- relationship_type: "Uses",
330
- ontology_valid: true,
331
- },
332
- ],
333
- }),
334
- );
335
- const client = new CogneeClient({
336
- endpoint: "http://cognee.local",
337
- fetchFn,
338
- retryDelayMs: 0,
339
- });
340
-
341
- const graph = await client.fetchDatasetGraph(
342
- "11111111-1111-4111-8111-111111111111",
343
- );
344
-
345
- expect(graph.nodes).toEqual([
346
- expect.objectContaining({
347
- id: "n1",
348
- label: "Acme",
349
- type: "Entity",
350
- properties: {
351
- is_a: { name: "Company" },
352
- ontology_valid: true,
353
- },
354
- }),
355
- ]);
356
- expect(graph.edges).toEqual([
357
- expect.objectContaining({
358
- id: "e1",
359
- label: "Uses",
360
- type: "Uses",
361
- properties: { relationship_type: "Uses", ontology_valid: true },
362
- }),
363
- ]);
364
- });
365
-
366
- it("summarizes Cognee HTML errors without leaking markup", async () => {
367
- const fetchFn = vi
368
- .fn<typeof fetch>()
369
- .mockResolvedValueOnce(
370
- textResponse(
371
- 503,
372
- "<html><head><title>503 Service Temporarily Unavailable</title></head><body></body></html>",
373
- ),
374
- );
375
- const client = new CogneeClient({
376
- endpoint: "http://cognee.local",
377
- fetchFn,
378
- retryAttempts: 1,
379
- retryDelayMs: 0,
380
- });
381
-
382
- await expect(
383
- client.ingestThread({
384
- tenantId: "tenant-1",
385
- threadId: "thread-1",
386
- datasetName: "thinkwork:t:thread:x",
387
- transcript: "Acme",
388
- ontology,
389
- }),
390
- ).rejects.toThrow(
391
- "Cognee /api/v1/ontologies failed with 503: 503 Service Temporarily Unavailable",
392
- );
393
- });
394
-
395
- it("rides through a transient 503 on the status endpoint and completes", async () => {
396
- const fetchFn = vi
397
- .fn<typeof fetch>()
398
- .mockResolvedValueOnce(
399
- response(200, {
400
- "11111111-1111-4111-8111-111111111111": "DATASET_PROCESSING_STARTED",
401
- }),
402
- )
403
- .mockResolvedValueOnce(response(503, { detail: "Service Unavailable" }))
404
- .mockResolvedValueOnce(response(503, { detail: "Service Unavailable" }))
405
- .mockResolvedValueOnce(
406
- response(200, {
407
- "11111111-1111-4111-8111-111111111111":
408
- "DATASET_PROCESSING_COMPLETED",
409
- }),
410
- );
411
-
412
- vi.stubEnv("COGNEE_INDEX_POLL_MS", "1");
413
- try {
414
- const client = new CogneeClient({
415
- endpoint: "http://cognee.local",
416
- fetchFn,
417
- retryDelayMs: 0,
418
- retryAttempts: 1,
419
- });
420
- const status = await client.waitForDatasetIndexing(
421
- "11111111-1111-4111-8111-111111111111",
422
- );
423
- expect(status.status).toBe("completed");
424
- expect(status.rawStatus).toBe("DATASET_PROCESSING_COMPLETED");
425
- } finally {
426
- vi.unstubAllEnvs();
427
- }
428
- });
429
-
430
- it("falls back to a graph probe when status stays unavailable past timeout", async () => {
431
- // status endpoint always 503; the graph probe finds nodes (pipeline done)
432
- const fetchFn = vi.fn<typeof fetch>().mockImplementation(async (url) => {
433
- if (String(url).includes("/datasets/status")) {
434
- return response(503, { detail: "Service Unavailable" });
435
- }
436
- if (String(url).includes("/graph")) {
437
- return response(200, {
438
- nodes: [{ id: "n1", label: "Acme", type: "Company" }],
439
- edges: [],
440
- });
441
- }
442
- return response(200, {});
443
- });
444
-
445
- vi.stubEnv("COGNEE_INDEX_POLL_MS", "1");
446
- vi.stubEnv("COGNEE_INDEX_TIMEOUT_MS", "5");
447
- try {
448
- const client = new CogneeClient({
449
- endpoint: "http://cognee.local",
450
- fetchFn,
451
- retryDelayMs: 0,
452
- retryAttempts: 1,
453
- });
454
- const status = await client.waitForDatasetIndexing(
455
- "11111111-1111-4111-8111-111111111111",
456
- );
457
- expect(status.status).toBe("completed");
458
- expect(status.rawStatus).toBe("completed_via_graph_probe");
459
- } finally {
460
- vi.unstubAllEnvs();
461
- }
462
- });
463
-
464
- it("throws past timeout when status is unavailable AND the graph is empty", async () => {
465
- const fetchFn = vi.fn<typeof fetch>().mockImplementation(async (url) => {
466
- if (String(url).includes("/datasets/status")) {
467
- return response(503, { detail: "Service Unavailable" });
468
- }
469
- if (String(url).includes("/graph")) {
470
- return response(200, { nodes: [], edges: [] });
471
- }
472
- return response(200, {});
473
- });
474
-
475
- vi.stubEnv("COGNEE_INDEX_POLL_MS", "1");
476
- vi.stubEnv("COGNEE_INDEX_TIMEOUT_MS", "5");
477
- try {
478
- const client = new CogneeClient({
479
- endpoint: "http://cognee.local",
480
- fetchFn,
481
- retryDelayMs: 0,
482
- retryAttempts: 1,
483
- });
484
- await expect(
485
- client.waitForDatasetIndexing("11111111-1111-4111-8111-111111111111"),
486
- ).rejects.toThrow(/did not complete|failed with 503/);
487
- } finally {
488
- vi.unstubAllEnvs();
489
- }
490
- });
491
-
492
- it("deleteDatasetByName finds matching datasets and deletes them", async () => {
493
- const fetchFn = vi
494
- .fn<typeof fetch>()
495
- .mockResolvedValueOnce(
496
- response(200, {
497
- datasets: [
498
- { id: "ds-1", name: "thinkwork:t:observations" },
499
- { id: "ds-2", name: "thinkwork:t:thread:x" },
500
- { id: "ds-3", name: "thinkwork:t:observations" },
501
- ],
502
- }),
503
- )
504
- .mockResolvedValueOnce(response(200, {}))
505
- .mockResolvedValueOnce(response(200, {}));
506
- const client = new CogneeClient({
507
- endpoint: "http://cognee.local",
508
- fetchFn,
509
- retryDelayMs: 0,
510
- });
511
- const deleted = await client.deleteDatasetByName(
512
- "thinkwork:t:observations",
513
- );
514
- expect(deleted).toBe(2);
515
- const calls = fetchFn.mock.calls.map((c) => [String(c[0]), c[1]?.method]);
516
- expect(calls[0]).toEqual(["http://cognee.local/api/v1/datasets", "GET"]);
517
- expect(calls).toContainEqual([
518
- "http://cognee.local/api/v1/datasets/ds-1",
519
- "DELETE",
520
- ]);
521
- expect(calls).toContainEqual([
522
- "http://cognee.local/api/v1/datasets/ds-3",
523
- "DELETE",
524
- ]);
525
- // ds-2 (a thread dataset) must NOT be deleted
526
- expect(calls).not.toContainEqual([
527
- "http://cognee.local/api/v1/datasets/ds-2",
528
- "DELETE",
529
- ]);
530
- });
531
-
532
- it("deleteDatasetByName is a no-op when no dataset matches", async () => {
533
- const fetchFn = vi
534
- .fn<typeof fetch>()
535
- .mockResolvedValueOnce(
536
- response(200, { datasets: [{ id: "ds-2", name: "other" }] }),
537
- );
538
- const client = new CogneeClient({
539
- endpoint: "http://cognee.local",
540
- fetchFn,
541
- retryDelayMs: 0,
542
- });
543
- expect(await client.deleteDatasetByName("missing")).toBe(0);
544
- expect(fetchFn).toHaveBeenCalledTimes(1);
545
- });
546
-
547
- it("pruneAll POSTs to the prune endpoint", async () => {
548
- const fetchFn = vi
549
- .fn<typeof fetch>()
550
- .mockResolvedValueOnce(response(200, {}));
551
- const client = new CogneeClient({
552
- endpoint: "http://cognee.local",
553
- fetchFn,
554
- retryDelayMs: 0,
555
- });
556
- expect(await client.pruneAll()).toBe(true);
557
- expect(String(fetchFn.mock.calls[0][0])).toBe(
558
- "http://cognee.local/api/v1/prune",
559
- );
560
- expect(fetchFn.mock.calls[0][1]?.method).toBe("POST");
561
- });
562
- });
@@ -1,74 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
-
3
- import {
4
- buildCogneeMemoryScope,
5
- COGNEE_MEMORY_SCOPE_VERSION,
6
- } from "../../src/api/cognee-memory-scope.js";
7
-
8
- describe("buildCogneeMemoryScope", () => {
9
- it("builds a stable user memory scope", () => {
10
- const scope = buildCogneeMemoryScope({
11
- tenantId: "Tenant 1",
12
- kind: "user",
13
- userId: "User 1",
14
- });
15
-
16
- expect(scope).toEqual({
17
- version: COGNEE_MEMORY_SCOPE_VERSION,
18
- kind: "user",
19
- tenantId: "Tenant 1",
20
- ownerId: "User 1",
21
- sourceKind: "user_memory",
22
- sourceRef: "User 1",
23
- datasetName: "thinkwork:memory:v1:tenant:tenant_1:user:user_1",
24
- nodeSets: [
25
- "thinkwork_memory",
26
- "thinkwork_memory_v1",
27
- "thinkwork_user_memory",
28
- "tenant_tenant_1",
29
- "user_user_1",
30
- ],
31
- metadata: {
32
- memory_scope_version: "v1",
33
- memory_scope_kind: "user",
34
- tenant_id: "Tenant 1",
35
- owner_id: "User 1",
36
- },
37
- });
38
- });
39
-
40
- it("builds a separate stable space memory scope", () => {
41
- const scope = buildCogneeMemoryScope({
42
- tenantId: "Tenant 1",
43
- kind: "space",
44
- spaceId: "Space 1",
45
- });
46
-
47
- expect(scope).toEqual(
48
- expect.objectContaining({
49
- kind: "space",
50
- ownerId: "Space 1",
51
- sourceKind: "space_memory",
52
- sourceRef: "Space 1",
53
- datasetName: "thinkwork:memory:v1:tenant:tenant_1:space:space_1",
54
- nodeSets: [
55
- "thinkwork_memory",
56
- "thinkwork_memory_v1",
57
- "thinkwork_space_memory",
58
- "tenant_tenant_1",
59
- "space_space_1",
60
- ],
61
- }),
62
- );
63
- });
64
-
65
- it("rejects missing owner ids instead of collapsing memory scopes", () => {
66
- expect(() =>
67
- buildCogneeMemoryScope({
68
- tenantId: "tenant-1",
69
- kind: "space",
70
- spaceId: " ",
71
- }),
72
- ).toThrow("Cognee memory scope requires a non-empty spaceId");
73
- });
74
- });