-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathMakefile
More file actions
2271 lines (2027 loc) · 119 KB
/
Makefile
File metadata and controls
2271 lines (2027 loc) · 119 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Makefile for RAG Deployment
ifeq ($(NAMESPACE),)
ifneq (,$(filter namespace install uninstall helm-install-test helm-install-prod helm-install-demo helm-install-ticketing helm-export-demo helm-export-validate-demo ansible-apply-demo ansible-teardown-demo helm-uninstall helm-status helm-cleanup-eventing helm-cleanup-jobs deploy-email-server undeploy-email-server deploy-zammad undeploy-zammad zammad-set-token zammad-bootstrap-token zammad-trigger-autowizard zammad-update-embed-url print-urls verify-triggers jaeger-deploy jaeger-undeploy test-session-serialization-integration test-session-reclaim-integration test-session-background-reclaim-integration,$(MAKECMDGOALS)))
$(error NAMESPACE is not set)
endif
endif
# Auto-detect version based on git branch if VERSION is not explicitly set
# - main branch: uses base version (0.0.2) for stable builds
# - dev branch: uses '0.0.2-dev' tag (matches CI builds)
# - branches forked from dev: uses '0.0.2-dev' tag (dev builds)
# - all other branches: uses base version (0.0.2) for stable builds (default)
# Set VERSION explicitly to override this behavior (e.g., VERSION=latest)
BASE_VERSION := 0.0.12
DEV_VERSION := $(BASE_VERSION)-dev
GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
# Check if branch was forked from dev by comparing how close merge-bases are to branch tip
# If merge-base with dev is closer (fewer commits away) than merge-base with main, likely forked from dev
IS_FORKED_FROM_DEV := $(shell \
BRANCH="$(GIT_BRANCH)"; \
if [ -n "$$BRANCH" ] && [ "$$BRANCH" != "main" ] && [ "$$BRANCH" != "dev" ]; then \
if git rev-parse --verify main >/dev/null 2>&1 && git rev-parse --verify dev >/dev/null 2>&1; then \
MERGE_BASE_MAIN=$$(git merge-base $$BRANCH main 2>/dev/null); \
MERGE_BASE_DEV=$$(git merge-base $$BRANCH dev 2>/dev/null); \
if [ -n "$$MERGE_BASE_MAIN" ] && [ -n "$$MERGE_BASE_DEV" ]; then \
DISTANCE_FROM_MAIN=$$(git rev-list --count $$MERGE_BASE_MAIN..$$BRANCH 2>/dev/null || echo "999"); \
DISTANCE_FROM_DEV=$$(git rev-list --count $$MERGE_BASE_DEV..$$BRANCH 2>/dev/null || echo "999"); \
if [ "$$DISTANCE_FROM_DEV" -lt "$$DISTANCE_FROM_MAIN" ]; then \
echo "true"; \
else \
echo "false"; \
fi; \
elif [ -n "$$MERGE_BASE_DEV" ]; then \
echo "true"; \
elif [ -n "$$MERGE_BASE_MAIN" ]; then \
echo "false"; \
else \
echo "false"; \
fi; \
else \
echo "false"; \
fi; \
else \
echo "false"; \
fi \
)
# Only auto-detect if VERSION was not explicitly set by user (via env var or make arg)
ifeq ($(origin VERSION),undefined)
ifeq ($(GIT_BRANCH),main)
VERSION := $(BASE_VERSION)
else ifeq ($(GIT_BRANCH),dev)
VERSION := $(DEV_VERSION)
else ifeq ($(IS_FORKED_FROM_DEV),true)
# Branch was forked from dev, use dev version
VERSION := $(DEV_VERSION)
else
# Default: use stable version (includes branches forked from main, branches with no connection to either, etc.)
VERSION := $(BASE_VERSION)
endif
else
# VERSION was explicitly set by user, use it as-is
endif
# Replica count - can be set with REPLICA_COUNT=X to override all replica counts
# If not set, uses defaults from helm/values.yaml
REPLICA_COUNT ?=
CONTAINER_TOOL ?= podman
REGISTRY ?= quay.io/rh-ai-quickstart
PYTHON_VERSION ?= 3.12
ARCH ?= linux/amd64
# Pull policy: --policy=always for podman (pull newest); empty for docker (always pulls by default)
PULL_POLICY := $(if $(filter podman,$(CONTAINER_TOOL)),--policy=always,)
REQUEST_MGR_IMG ?= $(REGISTRY)/self-service-agent-request-manager:$(VERSION)
AGENT_SERVICE_IMG ?= $(REGISTRY)/self-service-agent-service:$(VERSION)
INTEGRATION_DISPATCHER_IMG ?= $(REGISTRY)/self-service-agent-integration-dispatcher:$(VERSION)
MCP_SNOW_IMG ?= $(REGISTRY)/self-service-agent-snow-mcp:$(VERSION)
MOCK_EVENTING_IMG ?= $(REGISTRY)/self-service-agent-mock-eventing:$(VERSION)
MOCK_SERVICENOW_IMG ?= $(REGISTRY)/self-service-agent-mock-servicenow:$(VERSION)
PROMPTGUARD_IMG ?= $(REGISTRY)/self-service-agent-promptguard:$(VERSION)
# For retag-all-images: tag from REGISTRY/VERSION to NEW_REGISTRY/NEW_VERSION (set both when retagging)
NEW_REGISTRY ?=
NEW_VERSION ?=
MAKEFLAGS += --no-print-directory
# Default values
POSTGRES_USER ?= postgres
POSTGRES_PASSWORD ?= rag_password
POSTGRES_DBNAME ?= rag_blueprint
# HF_TOKEN is only required if LLM_URL is not set
ifeq ($(LLM_URL),)
HF_TOKEN ?= $(shell bash -c 'read -r -p "Enter Hugging Face Token: " HF_TOKEN; echo $$HF_TOKEN')
else
HF_TOKEN ?=
endif
MAIN_CHART_NAME := self-service-agent
HELM_EXPORT_DIR ?= ansible/helm-export
TOLERATIONS_TEMPLATE=[{"key":"$(1)","effect":"NoSchedule","operator":"Exists"}]
INGRESS_PREFIX := ssa
# Slack Configuration - only when ENABLE_SLACK set to true
ifeq ($(ENABLE_SLACK),true)
ifndef SLACK_BOT_TOKEN
SLACK_BOT_TOKEN := $(shell bash -c 'read -r -p "Enter Slack Bot Token (xoxb-...): " TOKEN; echo $$TOKEN')
endif
ifndef SLACK_SIGNING_SECRET
SLACK_SIGNING_SECRET := $(shell bash -c 'read -r -p "Enter Slack Signing Secret: " SECRET; echo $$SECRET')
endif
endif
# Check if Slack should be enabled
SLACK_ENABLED := $(if $(and $(SLACK_BOT_TOKEN),$(SLACK_SIGNING_SECRET)),true,false)
# ServiceNow Configuration (use mocks by default)
SERVICENOW_INSTANCE_URL ?= http://self-service-agent-mock-servicenow:8080
SERVICENOW_API_KEY ?= now_mock_api_key
SERVICENOW_LAPTOP_REFRESH_ID ?= mock_laptop_refresh_id
SERVICENOW_LAPTOP_AVOID_DUPLICATES ?= false
SERVICENOW_LAPTOP_REQUEST_LIMITS ?=
TEST_USERS ?=
# ServiceNow Developer Portal Credentials (for waking up PDI)
SERVICENOW_DEV_PORTAL_USERNAME ?=
SERVICENOW_DEV_PORTAL_PASSWORD ?=
# PromptGuard Configuration
PROMPTGUARD_MODEL ?= llama-prompt-guard-2-86m
PROMPTGUARD_MODEL_ID ?= meta-llama/Llama-Prompt-Guard-2-86M
# LLM max output tokens (server-side; Responses API does not support per-request max_tokens yet).
# Set when enabling an LLM via LLM= so input + output stay within model context (e.g. 14k).
LLM_MAX_TOKENS ?= 2048
# Evaluation Configuration
# Enable full laptop details validation by default unless explicitly disabled
# Set VALIDATE_FULL_LAPTOP_DETAILS=false to disable validation
VALIDATE_FULL_LAPTOP_DETAILS ?= true
VALIDATE_LAPTOP_DETAILS_FLAG := $(if $(filter true,$(VALIDATE_FULL_LAPTOP_DETAILS)),--validate-full-laptop-details,--no-validate-full-laptop-details)
# Enable structured output mode for evaluations (default: false)
# Set USE_STRUCTURED_OUTPUT=true to enable Pydantic schema validation with retries
USE_STRUCTURED_OUTPUT ?= false
STRUCTURED_OUTPUT_FLAG := $(if $(filter true,$(USE_STRUCTURED_OUTPUT)),--use-structured-output,)
# Fault Injection Configuration (for testing)
FAULT_INJECTION_ENABLED ?=
FAULT_INJECTION_RATE ?=
FAULT_INJECTION_ERROR_TYPE ?=
FAULT_INJECTION_MAX_RETRIES ?=
# Export to shell so kubectl can access them
export SERVICENOW_INSTANCE_URL
export SERVICENOW_API_KEY
export SERVICENOW_LAPTOP_AVOID_DUPLICATES
export SERVICENOW_LAPTOP_REQUEST_LIMITS
export TEST_USERS
helm_pgvector_args = \
--set pgvector.secret.user=$(POSTGRES_USER) \
--set pgvector.secret.password=$(POSTGRES_PASSWORD) \
--set pgvector.secret.dbname=$(POSTGRES_DBNAME)
helm_llm_service_args = \
$(if $(HF_TOKEN),--set llm-service.secret.hf_token=$(HF_TOKEN),) \
$(if $(LLM),--set global.models.$(LLM).enabled=true,) \
$(if $(SAFETY),--set global.models.$(SAFETY).enabled=true,) \
$(if $(LLM_TOLERATION),--set-json global.models.$(LLM).tolerations='$(call TOLERATIONS_TEMPLATE,$(LLM_TOLERATION))',) \
$(if $(SAFETY_TOLERATION),--set-json global.models.$(SAFETY).tolerations='$(call TOLERATIONS_TEMPLATE,$(SAFETY_TOLERATION))',) \
$(if $(and $(LLM_URL),$(if $(SAFETY),,yes)),--set llm-service.enabled=false,)
helm_promptguard_args = \
$(if $(PROMPTGUARD_ENABLED),--set promptGuard.enabled=$(PROMPTGUARD_ENABLED) \
--set llama-stack.models.$(PROMPTGUARD_MODEL).enabled=$(PROMPTGUARD_ENABLED) \
--set llama-stack.models.$(PROMPTGUARD_MODEL).url="http://$(MAIN_CHART_NAME)-promptguard.$(NAMESPACE).svc.cluster.local:8000/v1" \
--set global.models.$(PROMPTGUARD_MODEL).enabled=$(PROMPTGUARD_ENABLED) \
--set global.models.$(PROMPTGUARD_MODEL).url="http://$(MAIN_CHART_NAME)-promptguard.$(NAMESPACE).svc.cluster.local:8000/v1",) \
$(if $(PROMPTGUARD_MODEL_ID),--set promptGuard.modelId='$(PROMPTGUARD_MODEL_ID)',) \
$(if $(HF_TOKEN),--set promptGuard.huggingfaceToken='$(HF_TOKEN)',)
helm_llama_stack_args = \
$(if $(LLM),--set global.models.$(LLM).enabled=true,) \
$(if $(SAFETY),--set global.models.$(SAFETY).enabled=true,) \
$(if $(SAFETY),--set global.models.$(SAFETY).registerShield=true,) \
$(if $(LLM_URL),--set global.models.$(LLM).url='$(LLM_URL)',) \
$(if $(LLM_ID),--set global.models.$(LLM).id='$(LLM_ID)',) \
$(if $(LLM),--set global.models.$(LLM).maxTokens=$(LLM_MAX_TOKENS),) \
$(if $(SAFETY_URL),--set global.models.$(SAFETY).url='$(SAFETY_URL)',) \
$(if $(SAFETY_ID),--set global.models.$(SAFETY).id='$(SAFETY_ID)',) \
$(if $(LLM_API_TOKEN),--set global.models.$(LLM).apiToken='$(LLM_API_TOKEN)',) \
$(if $(SAFETY_API_TOKEN),--set global.models.$(SAFETY).apiToken='$(SAFETY_API_TOKEN)',) \
$(if $(LLAMA_STACK_ENV),--set-json llama-stack.secrets='$(LLAMA_STACK_ENV)',) \
$(if $(LLAMASTACK_CLIENT_PORT),--set llamastack.port=$(LLAMASTACK_CLIENT_PORT),) \
$(if $(LLAMASTACK_API_KEY),--set llamastack.apiKey='$(LLAMASTACK_API_KEY)',) \
$(if $(LLAMASTACK_OPENAI_BASE_PATH),--set llamastack.openaiBasePath='$(LLAMASTACK_OPENAI_BASE_PATH)',) \
$(if $(LLAMASTACK_TIMEOUT),--set llamastack.timeout=$(LLAMASTACK_TIMEOUT),) \
$(helm_promptguard_args)
helm_request_management_args = \
$(if $(REQUEST_MANAGEMENT),--set requestManagement.enabled=$(REQUEST_MANAGEMENT),) \
$(if $(KNATIVE_EVENTING),--set requestManagement.knative.eventing.enabled=$(KNATIVE_EVENTING),) \
$(if $(MOCK_EVENTING),--set requestManagement.knative.mockEventing.enabled=$(MOCK_EVENTING),) \
$(if $(SLACK_SIGNING_SECRET),--set-string security.slack.signingSecret='$(SLACK_SIGNING_SECRET)',) \
$(if $(SNOW_API_KEY),--set-string security.apiKeys.snowIntegration='$(SNOW_API_KEY)',) \
$(if $(HR_API_KEY),--set-string security.apiKeys.hrSystem='$(HR_API_KEY)',)
helm_generic_args = \
$(if $(OTEL_EXPORTER_OTLP_ENDPOINT),--set otelExporter=$(OTEL_EXPORTER_OTLP_ENDPOINT),) \
$(if $(OTEL_EXPORTER_OTLP_ENDPOINT),--set llama-stack.otelExporter=$(OTEL_EXPORTER_OTLP_ENDPOINT),) \
$(if $(OTEL_EXPORTER_OTLP_ENDPOINT),--set-string llama-stack.secrets.OTEL_SERVICE_NAME=llamastack,) \
$(if $(findstring jaeger,$(OTEL_EXPORTER_OTLP_ENDPOINT)),--set-string llama-stack.secrets.OTEL_METRICS_EXPORTER=none,) \
$(if $(findstring jaeger,$(OTEL_EXPORTER_OTLP_ENDPOINT)),--set-string llama-stack.secrets.OTEL_LOGS_EXPORTER=none,) \
$(if $(findstring jaeger,$(OTEL_EXPORTER_OTLP_ENDPOINT)),--set-string llama-stack.secrets.OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf,) \
$(if $(OTEL_EXPORTER_OTLP_ENDPOINT),--set mcp-servers.mcp-servers.self-service-agent-snow.env.OTEL_EXPORTER_OTLP_ENDPOINT="$(OTEL_EXPORTER_OTLP_ENDPOINT)")
helm_replica_count_args = \
$(if $(REPLICA_COUNT),--set llamastack.postInitScaling.enabled=true,) \
$(if $(REPLICA_COUNT),--set llamastack.postInitScaling.targetReplicas=$(REPLICA_COUNT),) \
$(if $(REPLICA_COUNT),--set mcp-servers.mcp-servers.self-service-agent-snow.replicas=$(REPLICA_COUNT),) \
$(if $(REPLICA_COUNT),--set requestManagement.kafka.replicas=$(REPLICA_COUNT),) \
$(if $(REPLICA_COUNT),--set requestManagement.requestManager.replicas=$(REPLICA_COUNT),) \
$(if $(REPLICA_COUNT),--set requestManagement.integrationDispatcher.replicas=$(REPLICA_COUNT),) \
$(if $(REPLICA_COUNT),--set requestManagement.agentService.replicas=$(REPLICA_COUNT),)
helm_fault_injection_args = \
$(if $(FAULT_INJECTION_ENABLED),--set requestManagement.agentService.faultInjection.enabled=$(FAULT_INJECTION_ENABLED),) \
$(if $(FAULT_INJECTION_RATE),--set requestManagement.agentService.faultInjection.rate=$(FAULT_INJECTION_RATE),) \
$(if $(FAULT_INJECTION_ERROR_TYPE),--set requestManagement.agentService.faultInjection.errorType=$(FAULT_INJECTION_ERROR_TYPE),) \
$(if $(FAULT_INJECTION_MAX_RETRIES),--set requestManagement.agentService.faultInjection.maxRetries=$(FAULT_INJECTION_MAX_RETRIES),)
COMMA := ,
helm_test_users_args = \
$(if $(TEST_USERS),--set-string mockServiceNow.testUsers="$(subst $(COMMA),\$(COMMA),$(TEST_USERS))",)
# Demo: namespace-dependent hostnames (values-demo.yaml has the rest)
helm_demo_email_args = \
--set-string security.email.smtpHost=test-email-server-smtp.$(NAMESPACE).svc.cluster.local \
--set-string security.email.imapHost=test-email-server-imap.$(NAMESPACE).svc.cluster.local
# Ticketing: Zammad in-cluster URL and MCP secret wiring (exec bootstrap uses railsserver)
ZAMMAD_CREDENTIALS_SECRET ?= $(MAIN_CHART_NAME)-zammad-credentials
# Must match admin user in helm/values-zammad-deploy.yaml autoWizard.config (for zammad-bootstrap-token / UI login).
ZAMMAD_ADMIN_EMAIL ?= admin@zammad.local
ZAMMAD_ADMIN_PASSWORD ?= ZammadR0cks!
ZAMMAD_AUTOWIZARD_TOKEN ?= ssa-zammad-autowizard-9f3a2b1c
helm_ticketing_args = \
--set zammad.url=$(ZAMMAD_URL) \
--set mcp-servers.mcp-servers.zammad-mcp.envSecrets.ZAMMAD_URL.name=$(ZAMMAD_CREDENTIALS_SECRET) \
--set mcp-servers.mcp-servers.zammad-mcp.envSecrets.ZAMMAD_URL.key=zammad-url \
--set mcp-servers.mcp-servers.zammad-mcp.envSecrets.ZAMMAD_HTTP_TOKEN.name=$(ZAMMAD_CREDENTIALS_SECRET) \
--set mcp-servers.mcp-servers.zammad-mcp.envSecrets.ZAMMAD_HTTP_TOKEN.key=zammad-http-token
# Version target
.PHONY: version
version:
@echo $(VERSION)
# Default target
.PHONY: help
help:
@echo "Available targets:"
@echo ""
@echo "Build Commands:"
@echo " build-all-images - Build all container images (checks lockfiles first)"
@echo " build-agent-service-image - Build the agent service container image (checks lockfiles first)"
@echo " build-integration-dispatcher-image - Build the integration dispatcher container image (checks lockfiles first)"
@echo " build-mcp-snow-image - Build the snow MCP server container image (checks lockfiles first)"
@echo " build-mock-eventing-image - Build the mock eventing service container image (checks lockfiles first)"
@echo " build-mock-servicenow-image - Build the mock ServiceNow server container image (checks lockfiles first)"
@echo " build-promptguard-image - Build the PromptGuard service container image (checks lockfiles first)"
@echo " build-request-mgr-image - Build the request manager container image (checks lockfiles first)"
@echo " 💡 Tip: If you encounter QEMU issues on Mac M1/M2/M3, add USE_PIP_INSTALL=true"
@echo ""
@echo "Helm Commands:"
@echo " helm-install-test - Install with mock eventing service (testing/development/CI - default)"
@echo " helm-install-prod - Install with full Knative eventing (production)"
@echo " helm-install-demo - Install demo config (mock eventing, Greenmail, resource constraints)"
@echo " helm-install-ticketing - Install with ticketing channel (Zammad + MCP; one-shot deploy)"
@echo " helm-export-demo - Export demo manifests to ansible/helm-export/ (from NAMESPACE, VERSION, REGISTRY, SERVICENOW_*, etc.)"
@echo " helm-export-validate-demo - Export then validate with kubeconform (no cluster; CI)"
@echo " ansible-apply-demo - Export then apply demo via Ansible (requires ansible-playbook)"
@echo " ansible-teardown-demo - Teardown demo namespace via Ansible (requires ansible-playbook)"
@echo " check-ansible - Verify ansible-playbook is installed"
@echo " helm-cleanup-eventing - Manually clean up leftover Knative Eventing resources (Triggers, Brokers)"
@echo " helm-cleanup-jobs - Clean up leftover jobs from failed deployments"
@echo " helm-depend - Update Helm dependencies"
@echo " helm-list-models - List available models"
@echo " helm-status - Check status of the deployment"
@echo " helm-uninstall - Uninstall the RAG deployment and clean up resources"
@echo " install - Deploy to cluster (alias for helm-install; set INSTALL_MODE=test|demo|prod, default: test)"
@echo " uninstall - helm-uninstall + delete namespace"
@echo " verify-triggers - Verify all expected Knative triggers are deployed"
@echo ""
@echo "Dependency Commands (local dev):"
@echo " deps-all - Install dependencies for all projects"
@echo " deps - Install dependencies for self-service agent (root)"
@echo " deps-agent-service - Install dependencies for agent service"
@echo " deps-integration-dispatcher - Install dependencies for integration dispatcher"
@echo " deps-mcp-snow - Install dependencies for snow MCP server"
@echo " deps-request-manager - Install dependencies for request manager"
@echo " deps-shared-models - Install dependencies for shared models"
@echo " deps-shared-clients - Install dependencies for shared clients"
@echo " deps-servicenow-bootstrap - Install dependencies for ServiceNow automation scripts"
@echo " deps-mock-employee-data - Install dependencies for mock employee data"
@echo " deps-mock-servicenow - Install dependencies for mock ServiceNow"
@echo " deps-tracing-config - Install dependencies for tracing-config"
@echo " deps-promptguard - Install dependencies for PromptGuard"
@echo " deps-evaluations - Install dependencies for evaluations"
@echo ""
@echo "Reinstall Commands:"
@echo " reinstall-all - Force reinstall dependencies for all projects (uv sync --reinstall)"
@echo " reinstall - Force reinstall self-service agent dependencies (uv sync --reinstall)"
@echo " reinstall-agent-service - Force reinstall agent service dependencies"
@echo " reinstall-integration-dispatcher - Force reinstall integration dispatcher dependencies"
@echo " reinstall-mcp-snow - Force reinstall snow MCP dependencies"
@echo " reinstall-request-manager - Force reinstall request manager dependencies"
@echo " reinstall-shared-models - Force reinstall shared models dependencies"
@echo " reinstall-shared-clients - Force reinstall shared clients dependencies"
@echo " reinstall-servicenow-bootstrap - Force reinstall ServiceNow automation dependencies"
@echo " reinstall-mock-employee-data - Force reinstall mock employee data dependencies"
@echo " reinstall-mock-servicenow - Force reinstall mock ServiceNow dependencies"
@echo ""
@echo "Pull Commands (pull images at REGISTRY/VERSION with --platform=\$$(ARCH)):"
@echo " pull-all-images - Pull all container images"
@echo " pull-request-mgr-image - Pull request manager image"
@echo " pull-agent-service-image - Pull agent service image"
@echo " pull-integration-dispatcher-image - Pull integration dispatcher image"
@echo " pull-mcp-snow-image - Pull snow MCP image"
@echo " pull-mock-eventing-image - Pull mock eventing image"
@echo " pull-mock-servicenow-image - Pull mock ServiceNow image"
@echo " pull-promptguard-image - Pull PromptGuard image"
@echo ""
@echo "Retag Commands (pull at REGISTRY/VERSION then tag -> NEW_REGISTRY/NEW_VERSION; set both NEW_* vars):"
@echo " retag-all-images - Pull all images, then retag all to NEW_REGISTRY/NEW_VERSION"
@echo " retag-request-mgr-image - Retag request manager image"
@echo " retag-agent-service-image - Retag agent service image"
@echo " retag-integration-dispatcher-image - Retag integration dispatcher image"
@echo " retag-mcp-snow-image - Retag snow MCP image"
@echo " retag-mock-eventing-image - Retag mock eventing image"
@echo " retag-mock-servicenow-image - Retag mock ServiceNow image"
@echo " retag-promptguard-image - Retag PromptGuard image"
@echo ""
@echo "Push Commands:"
@echo " push-all-images - Push all container images to registry"
@echo " push-agent-service-image - Push the agent service container image to registry"
@echo " push-integration-dispatcher-image - Push the integration dispatcher container image to registry"
@echo " push-mcp-snow-image - Push the snow MCP server container image to registry"
@echo " push-mock-eventing-image - Push the mock eventing service container image to registry"
@echo " push-promptguard-image - Push the PromptGuard service container image to registry"
@echo " push-request-mgr-image - Push the request manager container image to registry"
@echo ""
@echo "Test Commands:"
@echo " test-all - Run tests for all projects"
@echo ""
@echo "ServiceNow PDI Commands:"
@echo " servicenow-wake-install - Install Playwright for ServiceNow PDI wake-up"
@echo " servicenow-wake - Wake up hibernating ServiceNow PDI"
@echo " servicenow-bootstrap - Run ServiceNow bootstrap setup with config file"
@echo " servicenow-bootstrap-validation - Run ServiceNow bootstrap validation checks"
@echo " servicenow-bootstrap-create-user - Create MCP agent user only"
@echo " servicenow-bootstrap-create-api-key - Create MCP agent API key only"
@echo " servicenow-bootstrap-create-catalog-item - Create PC refresh service catalog item only"
@echo " servicenow-bootstrap-create-evaluation-users - Create evaluation users only"
@echo ""
@echo "Test Email Server Commands:"
@echo " deploy-email-server - Deploy test email server (Greenmail with custom UI)"
@echo " undeploy-email-server - Remove test email server from namespace"
@echo " deploy-zammad - Deploy Zammad instance (prerequisite for ticketing channel)"
@echo " undeploy-zammad - Remove Zammad instance from namespace"
@echo " zammad-set-token - Set Zammad API token in secret and restart MCP (ZAMMAD_TOKEN=xxx, NAMESPACE=)"
@echo " zammad-bootstrap-token - Create API token via Zammad API (autoWizard admin); update secret and restart MCP"
@echo " zammad-trigger-autowizard - Trigger autoWizard via HTTP (run before bootstrap if 401)"
@echo " zammad-update-embed-url - Update embed page with Zammad Route URL (fixes YOUR-ZAMMAD-URL placeholder)"
@echo ""
@echo "Lockfile Management:"
@echo " check-lockfiles - Check if all uv.lock files are up-to-date"
@echo " check-requirements - Check if all requirements.txt files exist and are in sync with uv.lock"
@echo " check-uv-version - Check if local uv version matches CI requirement ($(UV_VERSION))"
@echo " update-lockfiles - Update all uv.lock files; export requirements.txt for dirs in REQUIREMENTS_DIRS"
@echo " export-requirements - Export requirements.txt for containerized services (REQUIREMENTS_DIRS only)"
@echo " check-lockfile-<service> - Check lockfile for specific service"
@echo " update-lockfile-<service> - Update lockfile for specific service"
@echo " test-agent-service - Run tests for agent service"
@echo " test-integration-dispatcher - Run tests for integration dispatcher"
@echo " test-mcp-snow - Run tests for snow MCP server"
@echo " test-request-manager - Run tests for request manager"
@echo " test-shared-models - Run tests for shared models"
@echo " test-servicenow-bootstrap - Run tests for ServiceNow automation scripts"
@echo " test-mock-employee-data - Run tests for mock employee data"
@echo " test-mock-servicenow - Run tests for mock ServiceNow"
@echo " test-short-resp-integration-request-mgr - Run short responses integration tests with Request Manager"
@echo " test-short-ticket-laptop-refresh - Run short responses integration tests for ticket-laptop-refresh flow"
@echo " test-long-resp-integration-request-mgr - Run long responses integration tests with Request Manager"
@echo " test-medium-resp-integration-request-mgr - Run medium responses integration tests with Request Manager (5 conversations)"
@echo " test-long-concurrent-integration-request-mgr - Run long concurrent responses integration tests with Request Manager (concurrency=4)"
@echo " test-session-serialization-integration - Run session serialization integration test (requires cluster, NAMESPACE=test)"
@echo " test-session-reclaim-integration - Run session reclaim integration test (on-demand reclaim of stuck processing)"
@echo " test-session-background-reclaim-integration - Run background reclaim integration test (~60s, requires cluster)"
@echo " generate-two-sessions - Generate two sessions: one for alice.johnson@company.com and one for ahmed.hassan@company.com"
@echo ""
@echo "Utility Commands:"
@echo " format - Run isort import sorting and Black formatting on entire codebase"
@echo " generate-lg-diagrams - Generate LangGraph visualization diagrams from YAML configs (outputs to docs/images/)"
@echo " lint - Run optimized linting (global isort/flake8 + per-directory mypy + logging patterns)"
@echo " lint-global-tools - Run isort and flake8 globally on all projects"
@echo " lint-mypy-per-directory - Run mypy on all projects with project-specific configs"
@echo " lint-<directory> - Run mypy on specific directory (e.g., lint-agent-service)"
@echo " check-logging - Check logging patterns (no direct imports, no print, structured logging)"
@echo " version - Print the current VERSION"
@echo ""
@echo "Configuration options (set via environment variables or make arguments):"
@echo ""
@echo " Core Configuration:"
@echo " CONTAINER_TOOL - Container build tool (default: podman)"
@echo " REGISTRY - Container registry (default: quay.io/rh-ai-quickstart)"
@echo " VERSION - Image version tag (auto-detected from git branch if not set)"
@echo " NEW_REGISTRY - Destination registry for retag-all-images (set with NEW_VERSION)"
@echo " NEW_VERSION - Destination tag for retag-all-images (set with NEW_REGISTRY)"
@echo " - main branch: uses base version '0.0.2' (stable builds)"
@echo " - dev branch: uses '0.0.2-dev' tag (latest dev builds)"
@echo " - branches forked from dev: uses '0.0.2-dev' tag (dev builds)"
@echo " - all other branches: uses base version '0.0.2' (stable builds, default)"
@echo " - Set explicitly to override (e.g., VERSION=latest for main)"
@echo " NAMESPACE - Target namespace (required, no default)"
@echo " REPLICA_COUNT - Number of replicas for scalable services (optional)"
@echo " If set, overrides defaults from helm/values.yaml"
@echo " If not set, uses defaults from helm/values.yaml"
@echo " Applies to: llama-stack, snow MCP, kafka,"
@echo " request-manager, integration-dispatcher, and agent-service"
@echo ""
@echo " Image Configuration:"
@echo " AGENT_SERVICE_IMG - Full agent service image name (default: \$${REGISTRY}/self-service-agent-service:\$${VERSION})"
@echo " INTEGRATION_DISPATCHER_IMG - Full integration dispatcher image name (default: \$${REGISTRY}/self-service-agent-integration-dispatcher:\$${VERSION})"
@echo " MCP_SNOW_IMG - Full snow MCP image name (default: \$${REGISTRY}/self-service-agent-snow-mcp:\$${VERSION})"
@echo " MOCK_SERVICENOW_IMG - Full mock ServiceNow image name (default: \$${REGISTRY}/self-service-agent-mock-servicenow:\$${VERSION})"
@echo " REQUEST_MGR_IMG - Full request manager image name (default: \$${REGISTRY}/self-service-agent-request-manager:\$${VERSION})"
@echo " USE_PIP_INSTALL - Use pip install from requirements.txt instead of uv sync (default: false)"
@echo " ⚠️ Troubleshooting: If you encounter QEMU segmentation faults when building"
@echo " Linux AMD64 containers on Mac M1/M2/M3, set this to 'true' as a workaround."
@echo " This is especially common when using QEMU emulation for cross-platform builds."
@echo " Example: make build-agent-service-image USE_PIP_INSTALL=true"
@echo " Note: Default (uv sync) is faster and more reliable on native Linux/CI environments."
@echo ""
@echo " Model Configuration:"
@echo " HF_TOKEN - Hugging Face Token (will prompt if not provided)"
@echo " LLM_ID - Model ID for LLM configuration"
@echo " {SAFETY,LLM} - Model id as defined in values (eg. llama-3-2-1b-instruct)"
@echo " {SAFETY,LLM}_URL - Model URL"
@echo " {SAFETY,LLM}_API_TOKEN - Model API token for remote models"
@echo " {SAFETY,LLM}_TOLERATION - Model pod toleration"
@echo " PROMPTGUARD_MODEL - PromptGuard model name (default: llama-prompt-guard-2-86m)"
@echo ""
@echo " Integration Configuration:"
@echo " ENABLE_SLACK - Set to 'true' to enable Slack integration and prompt for tokens"
@echo " HR_API_KEY - HR system integration API key"
@echo " SLACK_BOT_TOKEN - Slack Bot Token (xoxb-...) for Slack integration"
@echo " SLACK_SIGNING_SECRET - Slack Signing Secret for request verification"
@echo ""
@echo " ServiceNow Configuration:"
@echo " SERVICENOW_INSTANCE_URL - ServiceNow instance URL (default: http://self-service-agent-mock-servicenow:8080)"
@echo " SERVICENOW_API_KEY - ServiceNow API key (default: now_mock_api_key)"
@echo " SERVICENOW_API_KEY_HEADER - Custom header name (default: x-sn-apikey)"
@echo " SERVICENOW_LAPTOP_REFRESH_ID - ServiceNow catalog item ID for laptop refresh requests (default: mock_laptop_refresh_id)"
@echo " SERVICENOW_LAPTOP_AVOID_DUPLICATES - Whether to prevent creating duplicate laptop requests for the same model (default: false)"
@echo " SERVICENOW_LAPTOP_REQUEST_LIMITS - Maximum number of open laptop requests allowed per user (default: None)"
@echo " SERVICENOW_DEV_PORTAL_USERNAME - ServiceNow Developer Portal username for PDI wake-up (required for servicenow-wake)"
@echo " SERVICENOW_DEV_PORTAL_PASSWORD - ServiceNow Developer Portal password for PDI wake-up (required for servicenow-wake)"
@echo " TEST_USERS - Comma-separated list of email addresses to add to mock employee data for testing"
@echo ""
@echo " Request Management Layer:"
@echo " KNATIVE_EVENTING - Enable Knative Eventing (default: true)"
@echo " REQUEST_MANAGEMENT - Enable Request Management Layer (default: true)"
@echo ""
@echo " Agent Prompt Configuration:"
@echo " LG_PROMPT_<AGENT_NAME> - Override prompt config for any agent (generic pattern)"
@echo " Replace <AGENT_NAME> with uppercase agent name (use _ for -)"
@echo " Examples:"
@echo " LG_PROMPT_LAPTOP_REFRESH - Override laptop-refresh agent"
@echo " LG_PROMPT_ROUTING - Override routing agent"
@echo " LG_PROMPT_EMAIL_UPDATE - Override email-update agent"
@echo " Usage: make helm-install-test LG_PROMPT_LAPTOP_REFRESH=config/lg-prompts/custom.yaml"
@echo ""
@echo " Evaluation Configuration:"
@echo " VALIDATE_FULL_LAPTOP_DETAILS - Enable full laptop details validation (default: true)"
@echo " Set to 'false' to disable: VALIDATE_FULL_LAPTOP_DETAILS=false"
@echo " When enabled, integration tests validate all laptop specification fields"
@echo " USE_STRUCTURED_OUTPUT - Enable structured output mode for evaluations (default: false)"
@echo " Set to 'true' to enable: USE_STRUCTURED_OUTPUT=true"
@echo " Uses Pydantic schema validation with retries (recommended for Gemini)"
# Template build function: $(call build_template_image,IMAGE_NAME,DESCRIPTION,CONTAINERFILE,SERVICE_NAME,MODULE_NAME,BUILD_CONTEXT)
# Optional: Set USE_PIP_INSTALL=true to use pip install from requirements.txt instead of uv sync
# Optional: Set UV_VERSION=<version> to override uv version (default: $(UV_VERSION))
# Example: make build-agent-service-image USE_PIP_INSTALL=true
# Example: make build-agent-service-image UV_VERSION=0.9.27
define build_template_image
@echo "Building $(2) using template: $(1)"
$(CONTAINER_TOOL) build -t $(1) --platform=$(ARCH) \
-f $(3) \
--build-arg SERVICE_NAME=$(4) \
--build-arg MODULE_NAME=$(5) \
--build-arg USE_PIP_INSTALL=$(USE_PIP_INSTALL) \
--build-arg UV_VERSION=$(UV_VERSION) \
$(if $(6),$(6),.)
@echo "Successfully built $(1)"
endef
# Push function: $(call push_image,IMAGE_NAME,DESCRIPTION)
define push_image
@echo "Pushing $(2): $(1)"
$(CONTAINER_TOOL) push $(1)
@echo "Successfully pushed $(1)"
endef
# Pull with platform (and --policy=always for podman so we get newest build): $(call pull_image,IMAGE,DESCRIPTION)
define pull_image
@echo "Pulling $(2): $(1) (--platform=$(ARCH)$(if $(PULL_POLICY), $(PULL_POLICY),))"
$(CONTAINER_TOOL) pull --platform=$(ARCH) $(PULL_POLICY) $(1)
@echo "Successfully pulled $(2): $(1)"
endef
# Retag: $(call retag_image,IMAGE_STEM,DESCRIPTION) — tags REGISTRY/STEM:VERSION -> NEW_REGISTRY/STEM:NEW_VERSION
# Requires NEW_REGISTRY and NEW_VERSION to be set.
define retag_image
@[ -n "$(NEW_REGISTRY)" ] && [ -n "$(NEW_VERSION)" ] || (echo "Error: NEW_REGISTRY and NEW_VERSION must be set for retag targets" && exit 1)
@echo "Retagging $(2): $(REGISTRY)/$(1):$(VERSION) -> $(NEW_REGISTRY)/$(1):$(NEW_VERSION)"
$(CONTAINER_TOOL) tag $(REGISTRY)/$(1):$(VERSION) $(NEW_REGISTRY)/$(1):$(NEW_VERSION)
@echo "Successfully retagged $(2)"
endef
# Generic function to get external host for a service
define GET_EXTERNAL_HOST
if kubectl get route $(1) -n $(NAMESPACE) >/dev/null 2>&1; then \
kubectl get route $(1) -n $(NAMESPACE) -o jsonpath='{.spec.host}'; \
elif kubectl get ingress $(1) -n $(NAMESPACE) >/dev/null 2>&1; then \
kubectl get ingress $(1) -n $(NAMESPACE) -o jsonpath='{.spec.rules[0].host}'; \
fi
endef
# Generic function to print service URLs
define PRINT_SERVICE_URLS
@echo "--- Your $(1) URLs are: ---"
@sleep 10
@EXTERNAL_HOST=$$($(call GET_EXTERNAL_HOST,$(2))); \
if [ -n "$$EXTERNAL_HOST" ]; then \
echo " OpenAPI Schema: https://$$EXTERNAL_HOST/docs"; \
echo " Health: https://$$EXTERNAL_HOST/health"; \
$(3) \
else \
echo " External access not configured - using cluster-internal URLs:"; \
echo " OpenAPI Schema: http://$(MAIN_CHART_NAME)-$(4).$(NAMESPACE).svc.cluster.local/docs"; \
echo " Health: http://$(MAIN_CHART_NAME)-$(4).$(NAMESPACE).svc.cluster.local/health"; \
$(5) \
fi
endef
define PRINT_REQUEST_MANAGER_URL
$(call PRINT_SERVICE_URLS,Request Manager,$(INGRESS_PREFIX)-request-manager,,request-manager,)
endef
define PRINT_INTEGRATION_DISPATCHER_URL
@echo "--- Your Integration Dispatcher URLs are: ---"
@sleep 10
@EXTERNAL_HOST=$$($(call GET_EXTERNAL_HOST,$(INGRESS_PREFIX)-integration-dispatcher)); \
if [ -z "$$EXTERNAL_HOST" ]; then \
EXTERNAL_HOST=$$($(call GET_EXTERNAL_HOST,$(INGRESS_PREFIX)-integration-dispatcher)); \
fi; \
if [ -n "$$EXTERNAL_HOST" ]; then \
echo " OpenAPI Schema: http://$(MAIN_CHART_NAME)-integration-dispatcher.$(NAMESPACE).svc.cluster.local/docs"; \
echo " Health: http://$(MAIN_CHART_NAME)-integration-dispatcher.$(NAMESPACE).svc.cluster.local/health"; \
echo " Slack Events: https://$$EXTERNAL_HOST/slack/events"; \
echo " Slack Interactive: https://$$EXTERNAL_HOST/slack/interactive"; \
echo " Slack Commands: https://$$EXTERNAL_HOST/slack/commands"; \
else \
echo " External access not configured - using cluster-internal URLs:"; \
echo " OpenAPI Schema: http://$(MAIN_CHART_NAME)-integration-dispatcher.$(NAMESPACE).svc.cluster.local/docs"; \
echo " Health: http://$(MAIN_CHART_NAME)-integration-dispatcher.$(NAMESPACE).svc.cluster.local/health"; \
echo " Slack Events: http://$(MAIN_CHART_NAME)-integration-dispatcher.$(NAMESPACE).svc.cluster.local/slack/events"; \
echo " Slack Interactive: http://$(MAIN_CHART_NAME)-integration-dispatcher.$(NAMESPACE).svc.cluster.local/slack/interactive"; \
echo " Slack Commands: http://$(MAIN_CHART_NAME)-integration-dispatcher.$(NAMESPACE).svc.cluster.local/slack/commands"; \
fi
endef
# Template-specific dependency checks
# These check all common dependencies for each container template
.PHONY: check-deps-services-template
check-deps-services-template: check-lockfile-shared-models check-lockfile-shared-clients check-lockfile-agent-service check-lockfile-mock-employee-data
.PHONY: check-deps-mcp-template
check-deps-mcp-template: check-lockfile-shared-models
# Build container images
.PHONY: build-all-images
build-all-images: build-request-mgr-image build-agent-service-image build-integration-dispatcher-image build-mcp-snow-image build-mock-eventing-image build-mock-servicenow-image build-promptguard-image
@echo "All container images built successfully!"
.PHONY: build-request-mgr-image
build-request-mgr-image: check-lockfile-request-manager check-deps-services-template
$(call build_template_image,$(REQUEST_MGR_IMG),request manager image,Containerfile.services-template,request-manager,request_manager.main,.)
.PHONY: build-agent-service-image
build-agent-service-image: check-lockfile-agent-service check-deps-services-template
$(call build_template_image,$(AGENT_SERVICE_IMG),agent service image,Containerfile.services-template,agent-service,agent_service.main,.)
.PHONY: build-integration-dispatcher-image
build-integration-dispatcher-image: check-lockfile-integration-dispatcher check-deps-services-template
$(call build_template_image,$(INTEGRATION_DISPATCHER_IMG),integration dispatcher image,Containerfile.services-template,integration-dispatcher,integration_dispatcher.main,.)
.PHONY: build-promptguard-image
build-promptguard-image: check-lockfile-promptguard check-deps-services-template
$(call build_template_image,$(PROMPTGUARD_IMG),PromptGuard service image,Containerfile.services-template,promptguard-service,promptguard_service.server,.)
.PHONY: build-mcp-snow-image
build-mcp-snow-image: check-lockfile-mcp-snow check-deps-mcp-template
$(call build_template_image,$(MCP_SNOW_IMG),snow MCP image,Containerfile.mcp-template,mcp-servers/snow,snow.server,.)
.PHONY: build-mock-eventing-image
build-mock-eventing-image: check-lockfile-mock-eventing check-deps-services-template
$(call build_template_image,$(MOCK_EVENTING_IMG),mock eventing service image,Containerfile.services-template,mock-eventing-service,mock_eventing_service.main,.)
.PHONY: build-mock-servicenow-image
build-mock-servicenow-image: check-lockfile-mock-servicenow check-deps-services-template
$(call build_template_image,$(MOCK_SERVICENOW_IMG),mock ServiceNow server image,Containerfile.services-template,mock-service-now,mock_servicenow.server,.)
# Push container images
.PHONY: push-all-images
push-all-images: push-request-mgr-image push-agent-service-image push-integration-dispatcher-image push-mcp-snow-image push-mock-eventing-image push-mock-servicenow-image push-promptguard-image
@echo "All container images pushed successfully!"
.PHONY: push-request-mgr-image
push-request-mgr-image:
$(call push_image,$(REQUEST_MGR_IMG) $(PUSH_EXTRA_AGRS),request manager image)
.PHONY: push-agent-service-image
push-agent-service-image:
$(call push_image,$(AGENT_SERVICE_IMG) $(PUSH_EXTRA_AGRS),agent service image)
.PHONY: push-integration-dispatcher-image
push-integration-dispatcher-image:
$(call push_image,$(INTEGRATION_DISPATCHER_IMG) $(PUSH_EXTRA_AGRS),integration dispatcher image)
.PHONY: push-mcp-snow-image
push-mcp-snow-image:
$(call push_image,$(MCP_SNOW_IMG) $(PUSH_EXTRA_AGRS),snow MCP image)
.PHONY: push-mock-eventing-image
push-mock-eventing-image:
$(call push_image,$(MOCK_EVENTING_IMG) $(PUSH_EXTRA_AGRS),mock eventing service image)
.PHONY: push-mock-servicenow-image
push-mock-servicenow-image:
$(call push_image,$(MOCK_SERVICENOW_IMG) $(PUSH_EXTRA_AGRS),mock ServiceNow server image)
.PHONY: push-promptguard-image
push-promptguard-image:
$(call push_image,$(PROMPTGUARD_IMG) $(PUSH_EXTRA_AGRS),PromptGuard service image)
# Pull images at REGISTRY/VERSION with --platform=$(ARCH)
.PHONY: pull-all-images
pull-all-images: pull-request-mgr-image pull-agent-service-image pull-integration-dispatcher-image pull-mcp-snow-image pull-mock-eventing-image pull-mock-servicenow-image pull-promptguard-image
@echo "All images pulled successfully!"
.PHONY: pull-request-mgr-image
pull-request-mgr-image:
$(call pull_image,$(REQUEST_MGR_IMG),request manager image)
.PHONY: pull-agent-service-image
pull-agent-service-image:
$(call pull_image,$(AGENT_SERVICE_IMG),agent service image)
.PHONY: pull-integration-dispatcher-image
pull-integration-dispatcher-image:
$(call pull_image,$(INTEGRATION_DISPATCHER_IMG),integration dispatcher image)
.PHONY: pull-mcp-snow-image
pull-mcp-snow-image:
$(call pull_image,$(MCP_SNOW_IMG),snow MCP image)
.PHONY: pull-mock-eventing-image
pull-mock-eventing-image:
$(call pull_image,$(MOCK_EVENTING_IMG),mock eventing service image)
.PHONY: pull-mock-servicenow-image
pull-mock-servicenow-image:
$(call pull_image,$(MOCK_SERVICENOW_IMG),mock ServiceNow server image)
.PHONY: pull-promptguard-image
pull-promptguard-image:
$(call pull_image,$(PROMPTGUARD_IMG),PromptGuard service image)
# Retag images from REGISTRY/VERSION to NEW_REGISTRY/NEW_VERSION (both NEW_* must be set)
.PHONY: retag-all-images
retag-all-images: retag-request-mgr-image retag-agent-service-image retag-integration-dispatcher-image retag-mcp-snow-image retag-mock-eventing-image retag-mock-servicenow-image retag-promptguard-image
@echo "All images retagged to $(NEW_REGISTRY)/*:$(NEW_VERSION)"
.PHONY: retag-request-mgr-image
retag-request-mgr-image: pull-request-mgr-image
$(call retag_image,self-service-agent-request-manager,request manager image)
.PHONY: retag-agent-service-image
retag-agent-service-image: pull-agent-service-image
$(call retag_image,self-service-agent-service,agent service image)
.PHONY: retag-integration-dispatcher-image
retag-integration-dispatcher-image: pull-integration-dispatcher-image
$(call retag_image,self-service-agent-integration-dispatcher,integration dispatcher image)
.PHONY: retag-mcp-snow-image
retag-mcp-snow-image: pull-mcp-snow-image
$(call retag_image,self-service-agent-snow-mcp,snow MCP image)
.PHONY: retag-mock-eventing-image
retag-mock-eventing-image: pull-mock-eventing-image
$(call retag_image,self-service-agent-mock-eventing,mock eventing service image)
.PHONY: retag-mock-servicenow-image
retag-mock-servicenow-image: pull-mock-servicenow-image
$(call retag_image,self-service-agent-mock-servicenow,mock ServiceNow server image)
.PHONY: retag-promptguard-image
retag-promptguard-image: pull-promptguard-image
$(call retag_image,self-service-agent-promptguard,PromptGuard service image)
# Code quality
.PHONY: lint
lint: format lint-global-tools lint-mypy-per-directory check-logging
@echo "All directory linting completed successfully!"
# Global linting tools (isort and flake8) for projects with standard configurations
.PHONY: lint-global-tools
lint-global-tools:
@echo "Running global linting tools (flake8 and isort)..."
@echo "1. Running flake8 globally on all projects..."
@uv run flake8 .
@echo "2. Running isort globally on all projects..."
@uv run isort --check-only --diff .
@echo "✅ Global linting tools completed"
# Check logging patterns
.PHONY: check-logging
check-logging:
@echo "Checking logging patterns..."
@uv run python scripts/check_logging_patterns.py
@echo "✅ Logging pattern checks completed"
# Per-directory mypy linting (project-specific configurations)
.PHONY: lint-mypy-per-directory
lint-mypy-per-directory: lint-shared-models lint-shared-clients lint-agent-service lint-request-manager lint-integration-dispatcher lint-mcp-snow lint-mock-eventing lint-tracing-config lint-evaluations lint-servicenow-bootstrap lint-mock-employee-data lint-mock-servicenow
@echo "✅ All mypy linting completed"
# Common function for mypy linting
define lint_mypy
@echo "Running mypy on $(1)..."
@if [ -d "$(1)" ]; then \
cd $(1) && uv run --with mypy mypy --strict . && echo "✅ $(1) mypy completed"; \
else \
echo "⚠️ $(1) directory not found, skipping..."; \
fi
endef
# Individual directory linting targets (mypy with project-specific configurations)
.PHONY: lint-shared-models
lint-shared-models:
$(call lint_mypy,shared-models)
.PHONY: lint-shared-clients
lint-shared-clients:
$(call lint_mypy,shared-clients)
.PHONY: lint-agent-service
lint-agent-service:
$(call lint_mypy,agent-service)
.PHONY: lint-request-manager
lint-request-manager:
$(call lint_mypy,request-manager)
.PHONY: lint-integration-dispatcher
lint-integration-dispatcher:
$(call lint_mypy,integration-dispatcher)
.PHONY: lint-mcp-snow
lint-mcp-snow:
$(call lint_mypy,mcp-servers/snow)
.PHONY: lint-mock-eventing
lint-mock-eventing:
$(call lint_mypy,mock-eventing-service)
.PHONY: lint-tracing-config
lint-tracing-config:
$(call lint_mypy,tracing-config)
.PHONY: lint-evaluations
lint-evaluations:
$(call lint_mypy,evaluations)
.PHONY: lint-servicenow-bootstrap
lint-servicenow-bootstrap:
$(call lint_mypy,scripts/servicenow-bootstrap)
.PHONY: lint-mock-employee-data
lint-mock-employee-data:
$(call lint_mypy,mock-employee-data)
.PHONY: lint-mock-servicenow
lint-mock-servicenow:
$(call lint_mypy,mock-service-now)
.PHONY: format
format:
@echo "Running isort import sorting on entire codebase..."
uv run isort .
@echo "Running Black formatting on entire codebase..."
uv run black .
@echo "Formatting completed successfully!"
.PHONY: generate-lg-diagrams
generate-lg-diagrams:
@echo "Generating LangGraph visualizations..."
cd agent-service && uv run python ../scripts/create_langraph_graphs.py
@echo "LangGraph diagrams generated successfully in docs/images/"
# Deploy to cluster (install = helm install with configurable mode)
INSTALL_MODE ?= test
.PHONY: install
install:
@if [ "$(INSTALL_MODE)" != "test" ] && [ "$(INSTALL_MODE)" != "demo" ] && [ "$(INSTALL_MODE)" != "prod" ]; then \
echo "Error: INSTALL_MODE must be test, demo, or prod (got: $(INSTALL_MODE))"; \
exit 1; \
fi
$(MAKE) helm-install-$(INSTALL_MODE)
.PHONY: uninstall
uninstall: helm-uninstall
@echo "Removing namespace $(NAMESPACE)..."
@kubectl delete namespace $(NAMESPACE) --ignore-not-found --timeout=120s || true
@echo "Uninstall complete. Namespace $(NAMESPACE) removed."
# Install dependencies (local dev)
.PHONY: deps-all
deps-all: deps-shared-models deps-shared-clients deps-tracing-config deps deps-request-manager deps-agent-service deps-integration-dispatcher deps-mcp-snow deps-mock-eventing deps-mock-employee-data deps-mock-servicenow deps-promptguard deps-evaluations deps-servicenow-bootstrap
@echo "All dependencies installed successfully!"
.PHONY: deps-shared-models
deps-shared-models:
@echo "Installing shared models dependencies..."
cd shared-models && uv sync
@echo "Shared models dependencies installed successfully!"
.PHONY: deps-shared-clients
deps-shared-clients:
@echo "Installing shared clients dependencies..."
cd shared-clients && uv sync
@echo "Shared clients dependencies installed successfully!"
.PHONY: deps
deps:
@echo "Installing self-service agent dependencies..."
uv sync
@echo "Self-service agent dependencies installed successfully!"
.PHONY: reinstall
reinstall:
@echo "Force reinstalling all dependencies with latest code..."
@echo "Reinstalling all dependencies with uv sync..."
uv sync --reinstall
@echo "All dependencies reinstalled with latest code!"
.PHONY: reinstall-all
reinstall-all: reinstall-shared-models reinstall-shared-clients reinstall reinstall-request-manager reinstall-agent-service reinstall-integration-dispatcher reinstall-mcp-snow reinstall-mock-employee-data reinstall-mock-servicenow reinstall-promptguard reinstall-servicenow-bootstrap
@echo "All project dependencies reinstalled successfully!"
.PHONY: reinstall-request-manager
reinstall-request-manager:
@echo "Force reinstalling request manager dependencies..."
cd request-manager && uv sync --reinstall
@echo "Request manager dependencies reinstalled successfully!"
.PHONY: reinstall-agent-service
reinstall-agent-service:
@echo "Force reinstalling agent service dependencies..."
cd agent-service && uv sync --reinstall
@echo "Agent service dependencies reinstalled successfully!"
.PHONY: reinstall-integration-dispatcher
reinstall-integration-dispatcher:
@echo "Force reinstalling integration dispatcher dependencies..."
cd integration-dispatcher && uv sync --reinstall
@echo "Integration dispatcher dependencies reinstalled successfully!"
.PHONY: reinstall-mcp-snow
reinstall-mcp-snow:
@echo "Force reinstalling snow MCP dependencies..."
cd mcp-servers/snow && uv sync --reinstall
@echo "Snow MCP dependencies reinstalled successfully!"
.PHONY: reinstall-shared-models
reinstall-shared-models:
@echo "Force reinstalling shared models dependencies..."
cd shared-models && uv sync --reinstall
@echo "Shared models dependencies reinstalled successfully!"
.PHONY: reinstall-shared-clients
reinstall-shared-clients:
@echo "Force reinstalling shared clients dependencies..."
cd shared-clients && uv sync --reinstall
@echo "Shared clients dependencies reinstalled successfully!"
.PHONY: reinstall-servicenow-bootstrap
reinstall-servicenow-bootstrap:
@echo "Force reinstalling ServiceNow automation dependencies..."
cd scripts/servicenow-bootstrap && uv sync --reinstall
@echo "ServiceNow automation dependencies reinstalled successfully!"
.PHONY: reinstall-mock-employee-data
reinstall-mock-employee-data:
@echo "Force reinstalling mock employee data dependencies..."
cd mock-employee-data && uv sync --reinstall
@echo "Mock employee data dependencies reinstalled successfully!"
.PHONY: reinstall-mock-servicenow
reinstall-mock-servicenow:
@if echo "$(SERVICENOW_INSTANCE_URL)" | grep -q "self-service-agent-mock-servicenow"; then \
echo "Force reinstalling mock ServiceNow dependencies..."; \
cd mock-service-now && uv sync --reinstall; \
echo "Mock ServiceNow dependencies reinstalled successfully!"; \
else \
echo "Skipping mock ServiceNow reinstallation - SERVICENOW_INSTANCE_URL does not contain 'self-service-agent-mock-servicenow'"; \
echo "Current SERVICENOW_INSTANCE_URL: $(SERVICENOW_INSTANCE_URL)"; \
fi
.PHONY: reinstall-promptguard
reinstall-promptguard:
@echo "Force reinstalling PromptGuard service dependencies..."
cd promptguard-service && uv sync --reinstall
@echo "PromptGuard service dependencies force reinstalled successfully!"
.PHONY: deps-request-manager
deps-request-manager:
@echo "Installing request manager dependencies..."
cd request-manager && uv sync
@echo "Request manager dependencies installed successfully!"
.PHONY: deps-agent-service
deps-agent-service:
@echo "Installing agent service dependencies..."
cd agent-service && uv sync
@echo "Agent service dependencies installed successfully!"
.PHONY: deps-integration-dispatcher
deps-integration-dispatcher:
@echo "Installing integration dispatcher dependencies..."
cd integration-dispatcher && uv sync
@echo "Integration dispatcher dependencies installed successfully!"
.PHONY: deps-mcp-snow
deps-mcp-snow:
@echo "Installing snow MCP dependencies..."
cd mcp-servers/snow && uv sync
@echo "Snow MCP dependencies installed successfully!"
.PHONY: deps-mock-eventing
deps-mock-eventing:
@echo "Installing mock eventing service dependencies..."
cd mock-eventing-service && uv sync
@echo "Mock eventing service dependencies installed successfully!"
.PHONY: deps-mock-employee-data
deps-mock-employee-data:
@echo "Installing mock employee data dependencies..."
cd mock-employee-data && uv sync
@echo "Mock employee data dependencies installed successfully!"
.PHONY: deps-mock-servicenow
deps-mock-servicenow:
@if echo "$(SERVICENOW_INSTANCE_URL)" | grep -q "self-service-agent-mock-servicenow"; then \
echo "Installing mock ServiceNow dependencies..."; \
cd mock-service-now && uv sync; \
echo "Mock ServiceNow dependencies installed successfully!"; \
else \
echo "Skipping mock ServiceNow installation - SERVICENOW_INSTANCE_URL does not contain 'self-service-agent-mock-servicenow'"; \
echo "Current SERVICENOW_INSTANCE_URL: $(SERVICENOW_INSTANCE_URL)"; \
fi
.PHONY: deps-promptguard
deps-promptguard:
@echo "Installing PromptGuard service dependencies..."
cd promptguard-service && uv sync
@echo "PromptGuard service dependencies installed successfully!"