@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.
- package/dist/agent.js +13 -8
- package/dist/agent.js.map +1 -1
- package/dist/checkpointer/checkpointSaverFactory.d.ts +7 -0
- package/dist/checkpointer/checkpointSaverFactory.js +30 -0
- package/dist/checkpointer/checkpointSaverFactory.js.map +1 -0
- package/dist/edges/createPromptRouter.js +1 -1
- package/dist/edges/createPromptRouter.js.map +1 -1
- package/dist/platform/mindedCheckpointSaver.js +55 -10
- package/dist/platform/mindedCheckpointSaver.js.map +1 -1
- package/dist/platform/mindedConnection.d.ts +6 -1
- package/dist/platform/mindedConnection.js +92 -42
- package/dist/platform/mindedConnection.js.map +1 -1
- package/dist/platform/mindedConnectionTypes.d.ts +2 -0
- package/dist/platform/mindedConnectionTypes.js.map +1 -1
- package/dist/platform/mindedRequest.js +1 -1
- package/dist/platform/mindedRequest.js.map +1 -1
- package/docs/api-reference/classes/index.Agent.html +2 -2
- package/docs/api-reference/enums/index.EdgeType.html +2 -2
- package/docs/api-reference/enums/index.NodeType.html +2 -2
- package/docs/api-reference/enums/index.TriggerType.html +2 -2
- package/docs/api-reference/enums/index.events.html +2 -2
- package/docs/api-reference/hierarchy.html +1 -1
- package/docs/api-reference/index.html +3 -3
- package/docs/api-reference/interfaces/index.AppToolNode.html +2 -2
- package/docs/api-reference/interfaces/index.AppTriggerNode.html +2 -2
- package/docs/api-reference/interfaces/index.Flow.html +2 -2
- package/docs/api-reference/interfaces/index.JunctionNode.html +2 -2
- package/docs/api-reference/interfaces/index.LogicalConditionEdge.html +2 -2
- package/docs/api-reference/interfaces/index.ManualTriggerNode.html +2 -2
- package/docs/api-reference/interfaces/index.PromptConditionEdge.html +2 -2
- package/docs/api-reference/interfaces/index.PromptNode.html +2 -2
- package/docs/api-reference/interfaces/index.StepForwardEdge.html +2 -2
- package/docs/api-reference/interfaces/index.Tool.html +2 -2
- package/docs/api-reference/interfaces/index.ToolNode.html +2 -2
- package/docs/api-reference/modules/index-1.html +1 -1
- package/docs/api-reference/modules/index.html +1 -1
- package/docs/api-reference/modules.html +1 -1
- package/docs/api-reference/types/index.Edge.html +1 -1
- package/docs/api-reference/types/index.Node.html +1 -1
- package/docs/api-reference/types/index.TriggerNode.html +1 -1
- package/docs/examples/order-refund-flow.md +1 -1
- package/docs/getting-started/installation.md +3 -3
- package/examples/orderRefundAgent/flows/orderRefundFlow.yaml +3 -3
- package/examples/orderRefundAgent/orderRefundAgent.ts +9 -3
- package/package.json +4 -2
- package/src/agent.ts +15 -9
- package/src/checkpointer/checkpointSaverFactory.ts +31 -0
- package/src/edges/createPromptRouter.ts +1 -1
- package/src/platform/mindedCheckpointSaver.ts +75 -18
- package/src/platform/mindedConnection.ts +99 -55
- package/src/platform/mindedConnectionTypes.ts +4 -5
- package/src/platform/mindedRequest.ts +2 -1
- package/test/checkpoint-saver/minded-checkpoint-saver-list.test.ts +138 -0
- package/test/checkpoint-saver/minded-checkpoint-saver.test.ts +99 -0
- package/dist/analytics.d.ts +0 -6
- package/dist/analytics.js +0 -19
- package/dist/analytics.js.map +0 -1
- package/dist/infrastructure.ts/mindedRequest.d.ts +0 -8
- package/dist/infrastructure.ts/mindedRequest.js +0 -22
- 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
|
+
});
|
package/dist/analytics.d.ts
DELETED
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
|
package/dist/analytics.js.map
DELETED
|
@@ -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"}
|