@minded-ai/mindedjs 1.0.19 → 1.0.21

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 (60) hide show
  1. package/dist/agent.js +13 -8
  2. package/dist/agent.js.map +1 -1
  3. package/dist/checkpointer/checkpointSaverFactory.d.ts +7 -0
  4. package/dist/checkpointer/checkpointSaverFactory.js +30 -0
  5. package/dist/checkpointer/checkpointSaverFactory.js.map +1 -0
  6. package/dist/edges/createPromptRouter.js +1 -1
  7. package/dist/edges/createPromptRouter.js.map +1 -1
  8. package/dist/platform/mindedCheckpointSaver.js +55 -10
  9. package/dist/platform/mindedCheckpointSaver.js.map +1 -1
  10. package/dist/platform/mindedConnection.d.ts +6 -1
  11. package/dist/platform/mindedConnection.js +92 -42
  12. package/dist/platform/mindedConnection.js.map +1 -1
  13. package/dist/platform/mindedConnectionTypes.d.ts +2 -0
  14. package/dist/platform/mindedConnectionTypes.js.map +1 -1
  15. package/dist/platform/mindedRequest.js +1 -1
  16. package/dist/platform/mindedRequest.js.map +1 -1
  17. package/docs/api-reference/classes/index.Agent.html +2 -2
  18. package/docs/api-reference/enums/index.EdgeType.html +2 -2
  19. package/docs/api-reference/enums/index.NodeType.html +2 -2
  20. package/docs/api-reference/enums/index.TriggerType.html +2 -2
  21. package/docs/api-reference/enums/index.events.html +2 -2
  22. package/docs/api-reference/hierarchy.html +1 -1
  23. package/docs/api-reference/index.html +3 -3
  24. package/docs/api-reference/interfaces/index.AppToolNode.html +2 -2
  25. package/docs/api-reference/interfaces/index.AppTriggerNode.html +2 -2
  26. package/docs/api-reference/interfaces/index.Flow.html +2 -2
  27. package/docs/api-reference/interfaces/index.JunctionNode.html +2 -2
  28. package/docs/api-reference/interfaces/index.LogicalConditionEdge.html +2 -2
  29. package/docs/api-reference/interfaces/index.ManualTriggerNode.html +2 -2
  30. package/docs/api-reference/interfaces/index.PromptConditionEdge.html +2 -2
  31. package/docs/api-reference/interfaces/index.PromptNode.html +2 -2
  32. package/docs/api-reference/interfaces/index.StepForwardEdge.html +2 -2
  33. package/docs/api-reference/interfaces/index.Tool.html +2 -2
  34. package/docs/api-reference/interfaces/index.ToolNode.html +2 -2
  35. package/docs/api-reference/modules/index-1.html +1 -1
  36. package/docs/api-reference/modules/index.html +1 -1
  37. package/docs/api-reference/modules.html +1 -1
  38. package/docs/api-reference/types/index.Edge.html +1 -1
  39. package/docs/api-reference/types/index.Node.html +1 -1
  40. package/docs/api-reference/types/index.TriggerNode.html +1 -1
  41. package/docs/examples/order-refund-flow.md +1 -1
  42. package/docs/getting-started/installation.md +3 -3
  43. package/examples/orderRefundAgent/flows/orderRefundFlow.yaml +3 -3
  44. package/examples/orderRefundAgent/orderRefundAgent.ts +9 -3
  45. package/package.json +4 -2
  46. package/src/agent.ts +15 -9
  47. package/src/checkpointer/checkpointSaverFactory.ts +31 -0
  48. package/src/edges/createPromptRouter.ts +1 -1
  49. package/src/platform/mindedCheckpointSaver.ts +75 -18
  50. package/src/platform/mindedConnection.ts +99 -55
  51. package/src/platform/mindedConnectionTypes.ts +4 -5
  52. package/src/platform/mindedRequest.ts +2 -1
  53. package/test/checkpoint-saver/minded-checkpoint-saver-list.test.ts +138 -0
  54. package/test/checkpoint-saver/minded-checkpoint-saver.test.ts +99 -0
  55. package/dist/analytics.d.ts +0 -6
  56. package/dist/analytics.js +0 -19
  57. package/dist/analytics.js.map +0 -1
  58. package/dist/infrastructure.ts/mindedRequest.d.ts +0 -8
  59. package/dist/infrastructure.ts/mindedRequest.js +0 -22
  60. package/dist/infrastructure.ts/mindedRequest.js.map +0 -1
@@ -0,0 +1,138 @@
1
+ import { expect } from 'chai';
2
+ import { describe, it, beforeEach, afterEach } from 'mocha';
3
+ import * as sinon from 'sinon';
4
+ import { MindedCheckpointSaver } from '../../src/platform/mindedCheckpointSaver';
5
+ import * as mindedRequestModule from '../../src/platform/mindedRequest';
6
+ import { Checkpoint, CheckpointTuple, CheckpointMetadata, emptyCheckpoint, CheckpointListOptions } from '@langchain/langgraph-checkpoint';
7
+ import { RunnableConfig } from '@langchain/core/runnables';
8
+ import { HumanMessage, AIMessage, SystemMessage } from '@langchain/core/messages';
9
+
10
+ describe('MindedCheckpointSaver - List Method', function () {
11
+ let checkpointSaver: MindedCheckpointSaver;
12
+ let mindedRequestStub: sinon.SinonStub;
13
+ const testToken = 'test-token-456';
14
+
15
+ beforeEach(() => {
16
+ checkpointSaver = new MindedCheckpointSaver(testToken);
17
+ mindedRequestStub = sinon.stub(mindedRequestModule, 'mindedRequest');
18
+ });
19
+
20
+ afterEach(() => {
21
+ sinon.restore();
22
+ });
23
+
24
+ describe('list', () => {
25
+ it('should deserialize multiple checkpoints with different message types', async () => {
26
+ // Create original checkpoints with proper class instances
27
+ const checkpoint1: Checkpoint = {
28
+ ...emptyCheckpoint(),
29
+ id: 'checkpoint-1',
30
+ channel_values: {
31
+ messages: [new HumanMessage('First message')],
32
+ },
33
+ };
34
+
35
+ const checkpoint2: Checkpoint = {
36
+ ...emptyCheckpoint(),
37
+ id: 'checkpoint-2',
38
+ channel_values: {
39
+ messages: [new SystemMessage('System prompt'), new AIMessage('AI response')],
40
+ },
41
+ };
42
+
43
+ const metadata1: CheckpointMetadata = {
44
+ source: 'input',
45
+ step: 1,
46
+ writes: {},
47
+ parents: {},
48
+ };
49
+
50
+ const metadata2: CheckpointMetadata = {
51
+ source: 'loop',
52
+ step: 2,
53
+ writes: {},
54
+ parents: {},
55
+ };
56
+
57
+ // Simulate JSON serialization (what happens during HTTP transport)
58
+ const jsonCheckpoint1 = JSON.parse(JSON.stringify(checkpoint1));
59
+ const jsonCheckpoint2 = JSON.parse(JSON.stringify(checkpoint2));
60
+ const jsonMetadata1 = JSON.parse(JSON.stringify(metadata1));
61
+ const jsonMetadata2 = JSON.parse(JSON.stringify(metadata2));
62
+
63
+ const mockServerResponse = {
64
+ checkpoints: [
65
+ {
66
+ config: { configurable: { thread_id: 'test-thread', checkpoint_id: 'checkpoint-1' } },
67
+ checkpoint: jsonCheckpoint1,
68
+ metadata: jsonMetadata1,
69
+ parentConfig: undefined,
70
+ },
71
+ {
72
+ config: { configurable: { thread_id: 'test-thread', checkpoint_id: 'checkpoint-2' } },
73
+ checkpoint: jsonCheckpoint2,
74
+ metadata: jsonMetadata2,
75
+ parentConfig: { configurable: { thread_id: 'test-thread', checkpoint_id: 'checkpoint-1' } },
76
+ },
77
+ ],
78
+ };
79
+
80
+ // Mock the HTTP response with JSON-serialized objects (no class info)
81
+ mindedRequestStub.resolves(mockServerResponse);
82
+
83
+ const config: RunnableConfig = { configurable: { thread_id: 'test-thread' } };
84
+ const options: CheckpointListOptions = { limit: 10 };
85
+
86
+ const results: CheckpointTuple[] = [];
87
+ for await (const tuple of checkpointSaver.list(config, options)) {
88
+ results.push(tuple);
89
+ }
90
+
91
+ // Verify the request was made correctly
92
+ expect(mindedRequestStub.calledOnce).to.equal(true);
93
+ expect(mindedRequestStub.firstCall.args[0]).to.deep.include({
94
+ path: '/sdk-checkpoints/list',
95
+ method: 'POST',
96
+ body: { config, options },
97
+ token: testToken,
98
+ });
99
+
100
+ // Verify we got the correct number of results
101
+ expect(results).to.have.length(2);
102
+
103
+ // Verify first checkpoint - JSON objects should be restored to proper classes
104
+ const result1 = results[0];
105
+ expect(result1.checkpoint.id).to.equal('checkpoint-1');
106
+ expect(result1.metadata?.source).to.equal('input');
107
+ const messages1 = result1.checkpoint.channel_values.messages as any[];
108
+ expect(messages1).to.have.length(1);
109
+ expect(messages1[0]).to.be.instanceOf(HumanMessage);
110
+ expect(messages1[0].content).to.equal('First message');
111
+
112
+ // Verify second checkpoint - JSON objects should be restored to proper classes
113
+ const result2 = results[1];
114
+ expect(result2.checkpoint.id).to.equal('checkpoint-2');
115
+ expect(result2.metadata?.source).to.equal('loop');
116
+ expect(result2.parentConfig).to.deep.equal({ configurable: { thread_id: 'test-thread', checkpoint_id: 'checkpoint-1' } });
117
+ const messages2 = result2.checkpoint.channel_values.messages as any[];
118
+ expect(messages2).to.have.length(2);
119
+ expect(messages2[0]).to.be.instanceOf(SystemMessage);
120
+ expect(messages2[1]).to.be.instanceOf(AIMessage);
121
+ expect(messages2[0].content).to.equal('System prompt');
122
+ expect(messages2[1].content).to.equal('AI response');
123
+ });
124
+
125
+ it('should handle empty checkpoint list', async () => {
126
+ mindedRequestStub.resolves({ checkpoints: [] });
127
+
128
+ const config: RunnableConfig = { configurable: { thread_id: 'empty-thread' } };
129
+
130
+ const results: CheckpointTuple[] = [];
131
+ for await (const tuple of checkpointSaver.list(config)) {
132
+ results.push(tuple);
133
+ }
134
+
135
+ expect(results).to.have.length(0);
136
+ });
137
+ });
138
+ });
@@ -0,0 +1,99 @@
1
+ import { expect } from 'chai';
2
+ import { describe, it, beforeEach, afterEach } from 'mocha';
3
+ import * as sinon from 'sinon';
4
+ import { MindedCheckpointSaver } from '../../src/platform/mindedCheckpointSaver';
5
+ import * as mindedRequestModule from '../../src/platform/mindedRequest';
6
+ import { Checkpoint, CheckpointMetadata, emptyCheckpoint } from '@langchain/langgraph-checkpoint';
7
+ import { RunnableConfig } from '@langchain/core/runnables';
8
+ import { HumanMessage, AIMessage } from '@langchain/core/messages';
9
+
10
+ describe('MindedCheckpointSaver', function () {
11
+ let checkpointSaver: MindedCheckpointSaver;
12
+ let mindedRequestStub: sinon.SinonStub;
13
+ const testToken = 'test-token-123';
14
+
15
+ beforeEach(() => {
16
+ checkpointSaver = new MindedCheckpointSaver(testToken);
17
+ mindedRequestStub = sinon.stub(mindedRequestModule, 'mindedRequest');
18
+ });
19
+
20
+ afterEach(() => {
21
+ sinon.restore();
22
+ });
23
+
24
+ describe('getTuple', () => {
25
+ it('should deserialize checkpoint and metadata correctly', async () => {
26
+ // First, let's create proper objects and see what the serializer produces
27
+ const originalHumanMessage = new HumanMessage('Hello');
28
+ const originalAIMessage = new AIMessage('Hi there!');
29
+
30
+ // Create a checkpoint with these messages
31
+ const originalCheckpoint: Checkpoint = {
32
+ ...emptyCheckpoint(),
33
+ id: 'test-checkpoint-id',
34
+ channel_values: {
35
+ messages: [originalHumanMessage, originalAIMessage],
36
+ },
37
+ };
38
+
39
+ const originalMetadata: CheckpointMetadata = {
40
+ source: 'input',
41
+ step: 1,
42
+ writes: {},
43
+ parents: {},
44
+ };
45
+
46
+ // Simulate what happens when these objects go through JSON serialization (HTTP transport)
47
+ // This is what the server would actually return - plain JSON objects without class info
48
+ const jsonSerializedCheckpoint = JSON.parse(JSON.stringify(originalCheckpoint));
49
+ const jsonSerializedMetadata = JSON.parse(JSON.stringify(originalMetadata));
50
+
51
+ const mockServerResponse = {
52
+ tuple: {
53
+ config: { configurable: { thread_id: 'test-thread' } },
54
+ checkpoint: jsonSerializedCheckpoint,
55
+ metadata: jsonSerializedMetadata,
56
+ parentConfig: undefined,
57
+ pendingWrites: [],
58
+ },
59
+ };
60
+
61
+ // Mock the HTTP response with JSON-serialized objects (no class info)
62
+ mindedRequestStub.resolves(mockServerResponse);
63
+
64
+ const config: RunnableConfig = { configurable: { thread_id: 'test-thread' } };
65
+ const result = await checkpointSaver.getTuple(config);
66
+
67
+ // Verify the request was made correctly
68
+ expect(mindedRequestStub.calledOnce).to.equal(true);
69
+ expect(mindedRequestStub.firstCall.args[0]).to.deep.include({
70
+ path: '/sdk-checkpoints/getTuple',
71
+ method: 'POST',
72
+ body: { config },
73
+ token: testToken,
74
+ });
75
+
76
+ // Verify the result structure
77
+ expect(result).to.not.equal(undefined);
78
+ expect(result!.config).to.deep.equal(mockServerResponse.tuple.config);
79
+ expect(result!.checkpoint.id).to.equal('test-checkpoint-id');
80
+
81
+ // This is the key test - the JSON objects should be restored to proper classes
82
+ const messages = result!.checkpoint.channel_values.messages as any[];
83
+ expect(messages).to.have.length(2);
84
+ expect(messages[0]).to.be.instanceOf(HumanMessage);
85
+ expect(messages[1]).to.be.instanceOf(AIMessage);
86
+ expect(messages[0].content).to.equal('Hello');
87
+ expect(messages[1].content).to.equal('Hi there!');
88
+ });
89
+
90
+ it('should return undefined when server returns no tuple', async () => {
91
+ mindedRequestStub.resolves({ tuple: undefined });
92
+
93
+ const config: RunnableConfig = { configurable: { thread_id: 'test-thread' } };
94
+ const result = await checkpointSaver.getTuple(config);
95
+
96
+ expect(result).to.equal(undefined);
97
+ });
98
+ });
99
+ });
@@ -1,6 +0,0 @@
1
- export declare const analyticsFactory: ({ token, sessionId }: {
2
- token: string;
3
- sessionId: string;
4
- }) => {
5
- track: <T>(event: string, data: T) => Promise<void>;
6
- };
package/dist/analytics.js DELETED
@@ -1,19 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.analyticsFactory = void 0;
4
- const mindedRequest_1 = require("./infrastructure.ts/mindedRequest");
5
- const track = async ({ event, data, token, sessionId }) => {
6
- await (0, mindedRequest_1.mindedRequest)({
7
- path: '/analytics/events',
8
- method: 'POST',
9
- body: { event, data, sessionId },
10
- token
11
- });
12
- };
13
- const analyticsFactory = ({ token, sessionId }) => {
14
- return {
15
- track: (event, data) => track({ event, data, token, sessionId })
16
- };
17
- };
18
- exports.analyticsFactory = analyticsFactory;
19
- //# sourceMappingURL=analytics.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"analytics.js","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":";;;AAAA,qEAAkE;AAElE,MAAM,KAAK,GAAG,KAAK,EAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAgE,EAAE,EAAE;IACzH,MAAM,IAAA,6BAAa,EAAC;QAClB,IAAI,EAAE,mBAAmB;QACzB,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE;QAChC,KAAK;KACN,CAAC,CAAC;AACL,CAAC,CAAA;AAEM,MAAM,gBAAgB,GAAG,CAAC,EAAE,KAAK,EAAE,SAAS,EAAwC,EAAE,EAAE;IAC7F,OAAO;QACL,KAAK,EAAE,CAAI,KAAa,EAAE,IAAO,EAAE,EAAE,CAAC,KAAK,CAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;KAClF,CAAA;AACH,CAAC,CAAA;AAJY,QAAA,gBAAgB,oBAI5B"}
@@ -1,8 +0,0 @@
1
- type Method = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
2
- export declare const mindedRequest: <Response, Request = object>({ path, method, body, token }: {
3
- path: string;
4
- method: Method;
5
- body: Request;
6
- token: string;
7
- }) => Promise<Response>;
8
- export {};
@@ -1,22 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.mindedRequest = void 0;
7
- const axios_1 = __importDefault(require("axios"));
8
- const baseUrl = 'https://api.minded.com/sdk';
9
- const mindedRequest = async ({ path, method, body, token }) => {
10
- const response = await (0, axios_1.default)({
11
- method,
12
- url: `${baseUrl}${path}`,
13
- data: body,
14
- headers: {
15
- 'Content-Type': 'application/json',
16
- 'Authorization': `Bearer ${token}`
17
- }
18
- });
19
- return response.data;
20
- };
21
- exports.mindedRequest = mindedRequest;
22
- //# sourceMappingURL=mindedRequest.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mindedRequest.js","sourceRoot":"","sources":["../../src/infrastructure.ts/mindedRequest.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAC1B,MAAM,OAAO,GAAG,4BAA4B,CAAA;AAIrC,MAAM,aAAa,GAAG,KAAK,EAA8B,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAkE,EAAqB,EAAE;IAClL,MAAM,QAAQ,GAAG,MAAM,IAAA,eAAK,EAAC;QAC3B,MAAM;QACN,GAAG,EAAE,GAAG,OAAO,GAAG,IAAI,EAAE;QACxB,IAAI,EAAE,IAAI;QACV,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,eAAe,EAAE,UAAU,KAAK,EAAE;SACnC;KACF,CAAC,CAAC;IAEH,OAAO,QAAQ,CAAC,IAAI,CAAC;AACvB,CAAC,CAAA;AAZY,QAAA,aAAa,iBAYzB"}