Canvas: Implement Agent Sketch node, update dodo-app.jsonschema

- Add Gemini API key to the project
- Update dodo schema to support Gemini API key
- Update dodo schema to support Agent Sketch node

Change-Id: I6a96186f86ad169152ca0021b38130e485ebbf14
diff --git a/apps/canvas/front/src/lib/config.ts b/apps/canvas/front/src/lib/config.ts
index 39db5b4..f6dee32 100644
--- a/apps/canvas/front/src/lib/config.ts
+++ b/apps/canvas/front/src/lib/config.ts
@@ -34,7 +34,11 @@
 			return 4;
 		case "gateway-https":
 			return 5;
-		case undefined:
+		case "gateway-tcp":
+			return 7;
+		case "network":
+			return 8;
+		case undefined: // For NANode
 			return 100;
 	}
 }
@@ -153,6 +157,7 @@
 			}),
 		);
 	const noSource = apps
+		.filter((n) => n.data.type !== "sketch:latest")
 		.filter((n) => n.data == null || n.data.repository == null || n.data.repository.repoNodeId === "")
 		.map(
 			(n): Message => ({
@@ -194,44 +199,46 @@
 				onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
 			}),
 		);
-	const noIngress = apps.flatMap((n): Message[] => {
-		if (n.data == null) {
-			return [];
-		}
-		return (n.data.ports || [])
-			.filter(
-				(p) =>
-					!nodes
-						.filter((i) => i.type === "gateway-https")
-						.some((i) => {
-							if (
-								i.data &&
-								i.data.https &&
-								i.data.https.serviceId === n.id &&
-								i.data.https.portId === p.id
-							) {
-								return true;
-							}
-							return false;
-						}),
-			)
-			.map(
-				(p): Message => ({
-					id: `${n.id}-${p.id}-no-ingress`,
-					type: "WARNING",
-					nodeId: n.id,
-					message: `Connect to gateway: ${p.name} - ${p.value}`,
-					onHighlight: (store) => {
-						store.updateNode(n.id, { selected: true });
-						store.setHighlightCategory("gateways", true);
-					},
-					onLooseHighlight: (store) => {
-						store.updateNode(n.id, { selected: false });
-						store.setHighlightCategory("gateways", false);
-					},
-				}),
-			);
-	});
+	const noIngress = apps
+		.filter((n) => n.data.type !== "sketch:latest")
+		.flatMap((n): Message[] => {
+			if (n.data == null) {
+				return [];
+			}
+			return (n.data.ports || [])
+				.filter(
+					(p) =>
+						!nodes
+							.filter((i) => i.type === "gateway-https")
+							.some((i) => {
+								if (
+									i.data &&
+									i.data.https &&
+									i.data.https.serviceId === n.id &&
+									i.data.https.portId === p.id
+								) {
+									return true;
+								}
+								return false;
+							}),
+				)
+				.map(
+					(p): Message => ({
+						id: `${n.id}-${p.id}-no-ingress`,
+						type: "WARNING",
+						nodeId: n.id,
+						message: `Connect to gateway: ${p.name} - ${p.value}`,
+						onHighlight: (store) => {
+							store.updateNode(n.id, { selected: true });
+							store.setHighlightCategory("gateways", true);
+						},
+						onLooseHighlight: (store) => {
+							store.updateNode(n.id, { selected: false });
+							store.setHighlightCategory("gateways", false);
+						},
+					}),
+				);
+		});
 	const multipleIngress = apps
 		.filter((n) => n.data != null && n.data.ports != null)
 		.flatMap((n) =>