Skip to content

Commit 88f3648

Browse files
committed
Merge branch 'agentic'
2 parents d615749 + 45199d4 commit 88f3648

2 files changed

Lines changed: 290 additions & 12 deletions

File tree

mdl/backend/mock/mock_infrastructure.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
package mock
44

55
import (
6+
"fmt"
7+
68
"github.com/mendixlabs/mxcli/mdl/types"
79
"github.com/mendixlabs/mxcli/model"
810
"github.com/mendixlabs/mxcli/sdk/agenteditor"
@@ -164,82 +166,82 @@ func (m *MockBackend) ListAgentEditorModels() ([]*agenteditor.Model, error) {
164166
if m.ListAgentEditorModelsFunc != nil {
165167
return m.ListAgentEditorModelsFunc()
166168
}
167-
return nil, nil
169+
return nil, fmt.Errorf("MockBackend.ListAgentEditorModels not configured")
168170
}
169171

170172
func (m *MockBackend) ListAgentEditorKnowledgeBases() ([]*agenteditor.KnowledgeBase, error) {
171173
if m.ListAgentEditorKnowledgeBasesFunc != nil {
172174
return m.ListAgentEditorKnowledgeBasesFunc()
173175
}
174-
return nil, nil
176+
return nil, fmt.Errorf("MockBackend.ListAgentEditorKnowledgeBases not configured")
175177
}
176178

177179
func (m *MockBackend) ListAgentEditorConsumedMCPServices() ([]*agenteditor.ConsumedMCPService, error) {
178180
if m.ListAgentEditorConsumedMCPServicesFunc != nil {
179181
return m.ListAgentEditorConsumedMCPServicesFunc()
180182
}
181-
return nil, nil
183+
return nil, fmt.Errorf("MockBackend.ListAgentEditorConsumedMCPServices not configured")
182184
}
183185

184186
func (m *MockBackend) ListAgentEditorAgents() ([]*agenteditor.Agent, error) {
185187
if m.ListAgentEditorAgentsFunc != nil {
186188
return m.ListAgentEditorAgentsFunc()
187189
}
188-
return nil, nil
190+
return nil, fmt.Errorf("MockBackend.ListAgentEditorAgents not configured")
189191
}
190192

191193
func (m *MockBackend) CreateAgentEditorModel(model *agenteditor.Model) error {
192194
if m.CreateAgentEditorModelFunc != nil {
193195
return m.CreateAgentEditorModelFunc(model)
194196
}
195-
return nil
197+
return fmt.Errorf("MockBackend.CreateAgentEditorModel not configured")
196198
}
197199

198200
func (m *MockBackend) DeleteAgentEditorModel(id string) error {
199201
if m.DeleteAgentEditorModelFunc != nil {
200202
return m.DeleteAgentEditorModelFunc(id)
201203
}
202-
return nil
204+
return fmt.Errorf("MockBackend.DeleteAgentEditorModel not configured")
203205
}
204206

205207
func (m *MockBackend) CreateAgentEditorKnowledgeBase(kb *agenteditor.KnowledgeBase) error {
206208
if m.CreateAgentEditorKnowledgeBaseFunc != nil {
207209
return m.CreateAgentEditorKnowledgeBaseFunc(kb)
208210
}
209-
return nil
211+
return fmt.Errorf("MockBackend.CreateAgentEditorKnowledgeBase not configured")
210212
}
211213

212214
func (m *MockBackend) DeleteAgentEditorKnowledgeBase(id string) error {
213215
if m.DeleteAgentEditorKnowledgeBaseFunc != nil {
214216
return m.DeleteAgentEditorKnowledgeBaseFunc(id)
215217
}
216-
return nil
218+
return fmt.Errorf("MockBackend.DeleteAgentEditorKnowledgeBase not configured")
217219
}
218220

219221
func (m *MockBackend) CreateAgentEditorConsumedMCPService(svc *agenteditor.ConsumedMCPService) error {
220222
if m.CreateAgentEditorConsumedMCPServiceFunc != nil {
221223
return m.CreateAgentEditorConsumedMCPServiceFunc(svc)
222224
}
223-
return nil
225+
return fmt.Errorf("MockBackend.CreateAgentEditorConsumedMCPService not configured")
224226
}
225227

226228
func (m *MockBackend) DeleteAgentEditorConsumedMCPService(id string) error {
227229
if m.DeleteAgentEditorConsumedMCPServiceFunc != nil {
228230
return m.DeleteAgentEditorConsumedMCPServiceFunc(id)
229231
}
230-
return nil
232+
return fmt.Errorf("MockBackend.DeleteAgentEditorConsumedMCPService not configured")
231233
}
232234

233235
func (m *MockBackend) CreateAgentEditorAgent(a *agenteditor.Agent) error {
234236
if m.CreateAgentEditorAgentFunc != nil {
235237
return m.CreateAgentEditorAgentFunc(a)
236238
}
237-
return nil
239+
return fmt.Errorf("MockBackend.CreateAgentEditorAgent not configured")
238240
}
239241

240242
func (m *MockBackend) DeleteAgentEditorAgent(id string) error {
241243
if m.DeleteAgentEditorAgentFunc != nil {
242244
return m.DeleteAgentEditorAgentFunc(id)
243245
}
244-
return nil
246+
return fmt.Errorf("MockBackend.DeleteAgentEditorAgent not configured")
245247
}

mdl/executor/cmd_agenteditor_mock_test.go

Lines changed: 276 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,282 @@ import (
1111
"github.com/mendixlabs/mxcli/sdk/agenteditor"
1212
)
1313

14+
// ---------------------------------------------------------------------------
15+
// CREATE / DROP — Model
16+
// ---------------------------------------------------------------------------
17+
18+
func TestCreateAgentEditorModel_Mock(t *testing.T) {
19+
mod := mkModule("M")
20+
apiKey := mkConstant(mod.ID, "APIKey", "String", "")
21+
22+
h := mkHierarchy(mod)
23+
withContainer(h, apiKey.ContainerID, mod.ID)
24+
25+
called := false
26+
mb := &mock.MockBackend{
27+
IsConnectedFunc: func() bool { return true },
28+
ListModulesFunc: func() ([]*model.Module, error) { return []*model.Module{mod}, nil },
29+
ListAgentEditorModelsFunc: func() ([]*agenteditor.Model, error) { return nil, nil },
30+
ListConstantsFunc: func() ([]*model.Constant, error) { return []*model.Constant{apiKey}, nil },
31+
CreateAgentEditorModelFunc: func(m *agenteditor.Model) error {
32+
called = true
33+
return nil
34+
},
35+
}
36+
37+
ctx, buf := newMockCtx(t, withBackend(mb), withHierarchy(h))
38+
key := ast.QualifiedName{Module: "M", Name: "APIKey"}
39+
err := execCreateAgentEditorModel(ctx, &ast.CreateModelStmt{
40+
Name: ast.QualifiedName{Module: "M", Name: "GPT4"},
41+
Provider: "MxCloudGenAI",
42+
Key: &key,
43+
})
44+
assertNoError(t, err)
45+
assertContainsStr(t, buf.String(), "Created model: M.GPT4")
46+
if !called {
47+
t.Fatal("CreateAgentEditorModelFunc was not called")
48+
}
49+
}
50+
51+
func TestDropAgentEditorModel_Mock(t *testing.T) {
52+
mod := mkModule("M")
53+
m1 := &agenteditor.Model{
54+
BaseElement: model.BaseElement{ID: nextID("aem")},
55+
ContainerID: mod.ID,
56+
Name: "GPT4",
57+
}
58+
59+
h := mkHierarchy(mod)
60+
withContainer(h, m1.ContainerID, mod.ID)
61+
62+
called := false
63+
mb := &mock.MockBackend{
64+
IsConnectedFunc: func() bool { return true },
65+
ListAgentEditorModelsFunc: func() ([]*agenteditor.Model, error) { return []*agenteditor.Model{m1}, nil },
66+
DeleteAgentEditorModelFunc: func(id string) error {
67+
called = true
68+
return nil
69+
},
70+
}
71+
72+
ctx, buf := newMockCtx(t, withBackend(mb), withHierarchy(h))
73+
err := execDropAgentEditorModel(ctx, &ast.DropModelStmt{
74+
Name: ast.QualifiedName{Module: "M", Name: "GPT4"},
75+
})
76+
assertNoError(t, err)
77+
assertContainsStr(t, buf.String(), "Dropped model: M.GPT4")
78+
if !called {
79+
t.Fatal("DeleteAgentEditorModelFunc was not called")
80+
}
81+
}
82+
83+
// ---------------------------------------------------------------------------
84+
// CREATE / DROP — Consumed MCP Service
85+
// ---------------------------------------------------------------------------
86+
87+
func TestCreateConsumedMCPService_Mock(t *testing.T) {
88+
mod := mkModule("M")
89+
90+
called := false
91+
mb := &mock.MockBackend{
92+
IsConnectedFunc: func() bool { return true },
93+
ListModulesFunc: func() ([]*model.Module, error) { return []*model.Module{mod}, nil },
94+
ListAgentEditorConsumedMCPServicesFunc: func() ([]*agenteditor.ConsumedMCPService, error) { return nil, nil },
95+
CreateAgentEditorConsumedMCPServiceFunc: func(svc *agenteditor.ConsumedMCPService) error {
96+
called = true
97+
return nil
98+
},
99+
}
100+
101+
ctx, buf := newMockCtx(t, withBackend(mb))
102+
err := execCreateConsumedMCPService(ctx, &ast.CreateConsumedMCPServiceStmt{
103+
Name: ast.QualifiedName{Module: "M", Name: "WebSearch"},
104+
ProtocolVersion: "v2025_03_26",
105+
Version: "1.0",
106+
})
107+
assertNoError(t, err)
108+
assertContainsStr(t, buf.String(), "Created consumed MCP service: M.WebSearch")
109+
if !called {
110+
t.Fatal("CreateAgentEditorConsumedMCPServiceFunc was not called")
111+
}
112+
}
113+
114+
func TestDropConsumedMCPService_Mock(t *testing.T) {
115+
mod := mkModule("M")
116+
svc := &agenteditor.ConsumedMCPService{
117+
BaseElement: model.BaseElement{ID: nextID("aemcp")},
118+
ContainerID: mod.ID,
119+
Name: "WebSearch",
120+
}
121+
122+
h := mkHierarchy(mod)
123+
withContainer(h, svc.ContainerID, mod.ID)
124+
125+
called := false
126+
mb := &mock.MockBackend{
127+
IsConnectedFunc: func() bool { return true },
128+
ListAgentEditorConsumedMCPServicesFunc: func() ([]*agenteditor.ConsumedMCPService, error) { return []*agenteditor.ConsumedMCPService{svc}, nil },
129+
DeleteAgentEditorConsumedMCPServiceFunc: func(id string) error {
130+
called = true
131+
return nil
132+
},
133+
}
134+
135+
ctx, buf := newMockCtx(t, withBackend(mb), withHierarchy(h))
136+
err := execDropConsumedMCPService(ctx, &ast.DropConsumedMCPServiceStmt{
137+
Name: ast.QualifiedName{Module: "M", Name: "WebSearch"},
138+
})
139+
assertNoError(t, err)
140+
assertContainsStr(t, buf.String(), "Dropped consumed MCP service: M.WebSearch")
141+
if !called {
142+
t.Fatal("DeleteAgentEditorConsumedMCPServiceFunc was not called")
143+
}
144+
}
145+
146+
// ---------------------------------------------------------------------------
147+
// CREATE / DROP — Knowledge Base
148+
// ---------------------------------------------------------------------------
149+
150+
func TestCreateKnowledgeBase_Mock(t *testing.T) {
151+
mod := mkModule("M")
152+
kbKey := mkConstant(mod.ID, "KBKey", "String", "")
153+
154+
h := mkHierarchy(mod)
155+
withContainer(h, kbKey.ContainerID, mod.ID)
156+
157+
called := false
158+
mb := &mock.MockBackend{
159+
IsConnectedFunc: func() bool { return true },
160+
ListModulesFunc: func() ([]*model.Module, error) { return []*model.Module{mod}, nil },
161+
ListAgentEditorKnowledgeBasesFunc: func() ([]*agenteditor.KnowledgeBase, error) { return nil, nil },
162+
ListConstantsFunc: func() ([]*model.Constant, error) { return []*model.Constant{kbKey}, nil },
163+
CreateAgentEditorKnowledgeBaseFunc: func(kb *agenteditor.KnowledgeBase) error {
164+
called = true
165+
return nil
166+
},
167+
}
168+
169+
ctx, buf := newMockCtx(t, withBackend(mb), withHierarchy(h))
170+
key := ast.QualifiedName{Module: "M", Name: "KBKey"}
171+
err := execCreateKnowledgeBase(ctx, &ast.CreateKnowledgeBaseStmt{
172+
Name: ast.QualifiedName{Module: "M", Name: "ProductDocs"},
173+
Provider: "MxCloudGenAI",
174+
Key: &key,
175+
})
176+
assertNoError(t, err)
177+
assertContainsStr(t, buf.String(), "Created knowledge base: M.ProductDocs")
178+
if !called {
179+
t.Fatal("CreateAgentEditorKnowledgeBaseFunc was not called")
180+
}
181+
}
182+
183+
func TestDropKnowledgeBase_Mock(t *testing.T) {
184+
mod := mkModule("M")
185+
kb := &agenteditor.KnowledgeBase{
186+
BaseElement: model.BaseElement{ID: nextID("aekb")},
187+
ContainerID: mod.ID,
188+
Name: "ProductDocs",
189+
}
190+
191+
h := mkHierarchy(mod)
192+
withContainer(h, kb.ContainerID, mod.ID)
193+
194+
called := false
195+
mb := &mock.MockBackend{
196+
IsConnectedFunc: func() bool { return true },
197+
ListAgentEditorKnowledgeBasesFunc: func() ([]*agenteditor.KnowledgeBase, error) { return []*agenteditor.KnowledgeBase{kb}, nil },
198+
DeleteAgentEditorKnowledgeBaseFunc: func(id string) error {
199+
called = true
200+
return nil
201+
},
202+
}
203+
204+
ctx, buf := newMockCtx(t, withBackend(mb), withHierarchy(h))
205+
err := execDropKnowledgeBase(ctx, &ast.DropKnowledgeBaseStmt{
206+
Name: ast.QualifiedName{Module: "M", Name: "ProductDocs"},
207+
})
208+
assertNoError(t, err)
209+
assertContainsStr(t, buf.String(), "Dropped knowledge base: M.ProductDocs")
210+
if !called {
211+
t.Fatal("DeleteAgentEditorKnowledgeBaseFunc was not called")
212+
}
213+
}
214+
215+
// ---------------------------------------------------------------------------
216+
// CREATE / DROP — Agent
217+
// ---------------------------------------------------------------------------
218+
219+
func TestCreateAgent_Mock(t *testing.T) {
220+
mod := mkModule("M")
221+
mdl := &agenteditor.Model{
222+
BaseElement: model.BaseElement{ID: nextID("aem")},
223+
ContainerID: mod.ID,
224+
Name: "GPT4",
225+
}
226+
227+
h := mkHierarchy(mod)
228+
withContainer(h, mdl.ContainerID, mod.ID)
229+
230+
called := false
231+
mb := &mock.MockBackend{
232+
IsConnectedFunc: func() bool { return true },
233+
ListModulesFunc: func() ([]*model.Module, error) { return []*model.Module{mod}, nil },
234+
ListAgentEditorAgentsFunc: func() ([]*agenteditor.Agent, error) { return nil, nil },
235+
ListAgentEditorModelsFunc: func() ([]*agenteditor.Model, error) { return []*agenteditor.Model{mdl}, nil },
236+
CreateAgentEditorAgentFunc: func(a *agenteditor.Agent) error {
237+
called = true
238+
return nil
239+
},
240+
}
241+
242+
modelRef := ast.QualifiedName{Module: "M", Name: "GPT4"}
243+
ctx, buf := newMockCtx(t, withBackend(mb), withHierarchy(h))
244+
err := execCreateAgent(ctx, &ast.CreateAgentStmt{
245+
Name: ast.QualifiedName{Module: "M", Name: "Summarizer"},
246+
UsageType: "Task",
247+
Model: &modelRef,
248+
SystemPrompt: "Summarize in 3 sentences.",
249+
UserPrompt: "Enter text.",
250+
})
251+
assertNoError(t, err)
252+
assertContainsStr(t, buf.String(), "Created agent: M.Summarizer")
253+
if !called {
254+
t.Fatal("CreateAgentEditorAgentFunc was not called")
255+
}
256+
}
257+
258+
func TestDropAgent_Mock(t *testing.T) {
259+
mod := mkModule("M")
260+
a := &agenteditor.Agent{
261+
BaseElement: model.BaseElement{ID: nextID("aea")},
262+
ContainerID: mod.ID,
263+
Name: "Summarizer",
264+
}
265+
266+
h := mkHierarchy(mod)
267+
withContainer(h, a.ContainerID, mod.ID)
268+
269+
called := false
270+
mb := &mock.MockBackend{
271+
IsConnectedFunc: func() bool { return true },
272+
ListAgentEditorAgentsFunc: func() ([]*agenteditor.Agent, error) { return []*agenteditor.Agent{a}, nil },
273+
DeleteAgentEditorAgentFunc: func(id string) error {
274+
called = true
275+
return nil
276+
},
277+
}
278+
279+
ctx, buf := newMockCtx(t, withBackend(mb), withHierarchy(h))
280+
err := execDropAgent(ctx, &ast.DropAgentStmt{
281+
Name: ast.QualifiedName{Module: "M", Name: "Summarizer"},
282+
})
283+
assertNoError(t, err)
284+
assertContainsStr(t, buf.String(), "Dropped agent: M.Summarizer")
285+
if !called {
286+
t.Fatal("DeleteAgentEditorAgentFunc was not called")
287+
}
288+
}
289+
14290
func TestShowAgentEditorModels_Mock(t *testing.T) {
15291
mod := mkModule("M")
16292
m1 := &agenteditor.Model{

0 commit comments

Comments
 (0)