Skip to content

Commit

Permalink
Merge branch 'main' into agent-design
Browse files Browse the repository at this point in the history
  • Loading branch information
SverreNystad authored Nov 25, 2024
2 parents 546681e + f5269bd commit 5a739be
Show file tree
Hide file tree
Showing 42 changed files with 904 additions and 99 deletions.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 Sverre Nystad, Magnus Giverin, Maurice Wegerif, Johanne Eide Omland, Artemis Kjøllmoen Aarø, Andreas Lilleby Hjulstad, KartAI

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Start by going into the `/webapp` folder, making a copy of the `.env.example` fi
To run the project, you can use the following commands:

```bash
docker compose --env-file ./webapp/.env up --build -d
docker compose --env-file ./webapp/.env --env-file ./backend/.env up --build -d
```

This command will build the Docker images (if necessary) and run the containers in the background. You can access the clientside code at [http://localhost:3000](http://localhost:3000) and the API at [http://localhost:8000](http://localhost:8000).
Expand All @@ -35,6 +35,8 @@ To stop the containers, you can use the following command:
docker compose down
```

**Important:** In order to achieve the full functionality of the application, the AI models from the KartAI project must also be running. In our development we have ran them as docker containers locally on our machines. Though in the future, these will hopefully be available as public APIs.

## Documentation

- [Developer Setup](/docs/manuals/developer_setup.md)
Expand Down
2 changes: 1 addition & 1 deletion backend/src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def plan_prat(question: PlanPratRequest) -> PlanPratResponse:
question (PlanPratRequest): The query to PlanPrat.
Returns:
PlanPratResponse: The PlanPrat response.
backend/src/main.py
"""

logger.info(f"Query: {question}")
Expand Down
9 changes: 9 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ services:
environment:
- ARKIVGPT_URL=http://host.docker.internal:80/api # Overrides the URLs set in .env to use host.docker.internal instead of localhost
- PLANPRAT_URL=http://host.docker.internal:8000/plan-prat/
- CADAID_URL=${CADAID_URL}
- DATABASE_URL=${DATABASE_URL}
- NEXTAUTH_URL=${NEXTAUTH_URL}
extra_hosts:
Expand All @@ -26,3 +27,11 @@ services:
- "8000:8000"
volumes:
- ./backend:/code
environment:
- AZURE_OPENAI_API_KEY=${AZURE_OPENAI_API_KEY}
- AZURE_OPENAI_API_BASE=${AZURE_OPENAI_API_BASE}
- AZURE_OPENAI_DEPLOYMENT_NAME=${AZURE_OPENAI_DEPLOYMENT_NAME}
- API_VERSION=${API_VERSION}
- ARKIVGPT_URL=${ARKIVGPT_URL}
- CADAID_URL=${CADAID_URL}

26 changes: 26 additions & 0 deletions docs/diagrams/deployment.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@startuml
node "Client Device (User's Browser)" as ClientDevice {
[React Application (Web App Frontend)] as ReactApp
}

node "Server Machine" as ServerMachine {
node "Web Application" <<Docker Container>> as WebAppContainer {
[Next.js Application (Web App Backend)] as NextJSApp
[tRPC Module] as tRPCModule
}

node "AI Assistant" <<Docker Container>> as AIDockerContainer {
[Python Application (AI Summary Assistant API)] as PythonApp
}

artifact "Database" <<Docker Volume>> as DockerVolume {
[Database (e.g., PostgreSQL)] as Database
}

WebAppContainer -[#red,thickness=2]-> DockerVolume : Docker Network Bridge
}

ClientDevice -[#blue,thickness=2]-> WebAppContainer : HTTP
WebAppContainer -[#green,thickness=2]-> AIDockerContainer : HTTP (REST API)

@enduml
49 changes: 49 additions & 0 deletions docs/diagrams/package-diagram.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
@startuml
!define RECTANGLE_BACK_COLOR #EEEEEE
skinparam shadowing false
skinparam rectangle {
BackgroundColor RECTANGLE_BACK_COLOR
BorderColor #333333
FontStyle bold
FontSize 13
}

rectangle "AI Assistant API" {
rectangle "Endpoints" {
[Summarize Endpoint]
[PlanChat Endpoint]
}

rectangle "Services" {
rectangle "Document Reader" {
[Reader] <|-- [PdfReader]
[Reader] <|-- [XmlReader]
[Reader] <|-- [OCRReader]

[create_reader] --> [Reader] : "Create Reader Instance <<Factory Pattern>>"
[extract_text] --> [create_reader] : "Read File and Extract Text"

' Adding a note to Reader
note right of Reader
<<Strategy Pattern>>
Defines the strategy for reading different document types
end note
}

rectangle "AI Agent Services" {
[invoke_agent]
[invoke_plan_agent]
}
rectangle "External AI Models" {
[query_cad_aid]
[query_arkivgpt]
}
}
}

[Summarize Endpoint] --> [extract_text] : "Trigger Text Extraction"
[Summarize Endpoint] --> [External AI Models] : "Send Data to External AI Models"
[Summarize Endpoint] --> [invoke_agent] : "Invoke Agent Chain with Extracted Text"
[PlanChat Endpoint] --> [invoke_plan_agent] : "Invoke Plan Agent Chain with User Query"

@enduml
21 changes: 21 additions & 0 deletions docs/diagrams/webapp-sequence.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@startuml
actor User

participant "React Application" as ReactApp
participant "tRPC Module" as tRPC
participant "Prisma ORM" as Prisma
participant "MySQL Database" as Database
participant "External AI Model" as AIModel

User -> ReactApp : Interacts with UI (e.g., Submit Form)
ReactApp -> tRPC : Call tRPC Procedure
tRPC --> AIModel : API Request (HTTP)
AIModel --> tRPC : AI Model Response (HTTP)
tRPC --> Prisma : Save Response (Prisma ORM Create)
Prisma --> Database : SQL Insert Query
Database -> Prisma : Data Confirmation
Prisma -> tRPC : Success Message
tRPC --> ReactApp : Data Response
ReactApp --> User : Display AI Model Results

@enduml
5 changes: 3 additions & 2 deletions docs/manuals/developer_setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Before you start, make sure the following tools are installed on your system:

Start by making a copy of the `.env.example` file and renaming it to `.env`. This file contains the environment variables that the application needs to run. You can change the values of the variables to match your environment.

Run the following command in the `webapp/`
Run the following command in the `/webapp`
folder to copy the `.env.example` file:

```bash
Expand All @@ -39,7 +39,8 @@ ln -s ../../scripts/pre-commit .git/hooks/pre-commit

## Usage

To run the project, you can use the following commands:
To run the project, you can use the following commands in the `/webapp`
folder:

```bash
npm install; npm run dev
Expand Down
11 changes: 7 additions & 4 deletions webapp/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,18 @@ DATABASE_URL="mysql://root:password@localhost:3306/ntnu-kpro-ai-assistant"
# You can generate a new secret on the command line with:
# openssl rand -base64 32
# https://next-auth.js.org/configuration/options#secret
# NEXTAUTH_SECRET=""
NEXTAUTH_SECRET=""
NEXTAUTH_URL="http://localhost:3000"

# Planprat API
PLANPRAT_URL="http://localhost:8000/plan-prat"

# Next Auth Discord Provider
DISCORD_CLIENT_ID=""
DISCORD_CLIENT_SECRET=""

# ArkivGPT API
ARKIVGPT_URL="http://localhost:80/api"

# CADAID API
CADAID_URL="http://localhost:5001/detect/"

# Planprat API
PLANPRAT_URL="http://localhost:8000/plan-prat"
102 changes: 102 additions & 0 deletions webapp/cypress/e2e/pages/userDashbord.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
describe("for-soknad-dashbord e2e Tests", () => {
const ROUTES = ["for-soknad/byggeideer/dashbord", "for-soknad/byggeideer/dashbord"]

ROUTES.forEach((route) => {
describe(`Route: ${route}`, () => {
beforeEach(() => {
// Visit the UserDashboard page before each test
cy.visit(`/${route}`);
cy.clearLocalStorage();
});

it("should render content", () => {
cy.get('[data-cy="title"]').should("be.visible");
cy.get('[data-cy="pick-address"]').should("be.visible");
cy.get('[data-cy="todo-list"]').should("be.visible");
cy.get('[data-cy="planprat"]').should("be.visible");
cy.get('[data-cy="cadaid-widget"]').should("be.visible");
cy.get('[data-cy="digital-tiltaksdata-widget"]').should("be.visible");
cy.get('[data-cy="3d-visning-widget"]').should("be.visible");
cy.get('[data-cy="document-overview"]').should("be.visible");
cy.get('[data-cy="arkiv-gpt"]').should("be.visible");
cy.get('[data-cy="start-application-button"]').should("be.visible");
});

it("should have navigation to correct cadaid page", () => {
cy.get('[data-cy="cadaid-widget"]').click();
cy.url().should("include", route + "/cadaid");
});

it("should have navigationg to correct arkivGPT page", () => {
cy.get('[data-cy="arkiv-gpt"]').click();
cy.url().should("include", route + "/arkivgpt");
})

it("should be able to open and close pick address overlay whitout changing anyting", () => {
cy.contains("Ingen addresse valgt").should("be.visible");
cy.contains("Ingen tomt valgt").should("be.visible");
cy.contains("Velg adresse og eiendom").click();
cy.get('[data-cy="overlay-cancel-button"]').click();
cy.get('[data-cy="pick-address-overlay"]').should("not.exist");
cy.contains("Ingen addresse valgt").should("be.visible");
cy.contains("Ingen tomt valgt").should("be.visible");
})

it("should be able to choose adress and property", () => {
cy.contains("Ingen addresse valgt").should("be.visible");
cy.contains("Ingen tomt valgt").should("be.visible");
cy.contains("Velg adresse og eiendom").click();
cy.get('[data-cy="pick-address-overlay"]').should("be.visible")
cy.get('[data-cy="input-address"]').clear().type('TestAdresse');
cy.get('[data-cy="input-bnr"]').clear().type('TestBnr');
cy.get('[data-cy="input-gnr"]').clear().type('TestGnr');
cy.get('[data-cy="overlay-confirm-button"').click();
cy.contains("TestAdresse").should("be.visible");
cy.contains("Gnr. TestGnr, Bnr. TestBnr").should("be.visible")
})

it("should be able to close popup for analyze build area without any data being saved to local storage", () => {
cy.get('[data-cy="digital-tiltaksdata-widget"]').click();
cy.get('[data-cy="cancel-3d-widget"]').click();
cy.window().then((window) => {
const data = window.localStorage.getItem('hasInputDigitalTiltaksdataWidget');
cy.wrap(data).should('be.null');
});
})

it("should be able to pick building area and receive feedback", () => {
cy.get('[data-cy="map-feedback"]').should("not.exist");
cy.get('[data-cy="digital-tiltaksdata-widget"]').click();
cy.get('[data-cy="mock-map"]').click();
cy.get('[data-cy="map-feedback"]').should("be.visible");
})

it('"Gjøremål" should change accoring to actions taken by user', () => {
cy.get('[data-cy="address-text"]').should("be.visible");
cy.get('[data-cy="cadaid-text"]').should("be.visible");
cy.get('[data-cy="digital-tilraksdata-text"]').should("be.visible");
cy.get('[data-cy="three-d-visning-text"]').should("be.visible");
cy.get('[data-cy="planprat-text"]').should("be.visible");
cy.get('[data-cy="cadaid-widget"]').click();
cy.visit(`/${route}`);
cy.get('[data-cy="cadaid-text"]').should('not.exist');
cy.contains("Velg adresse og eiendom").click();
cy.get('[data-cy="input-address"]').clear().type('TestAdresse');
cy.get('[data-cy="input-bnr"]').clear().type('TestBnr');
cy.get('[data-cy="input-gnr"]').clear().type('TestGnr');
cy.get('[data-cy="overlay-confirm-button"').click();
cy.get('[data-cy="address-text"]').should("not.exist");
cy.get('[data-cy="arkivgpt-text"]').should("be.visible");
cy.get('[data-cy="3d-visning-widget"]').click();
cy.get('[data-cy="apply-3d-url-button"]').click();
cy.get('[data-cy="three-d-visning-text"]').should("not.exist");
cy.get('[data-cy="digital-tiltaksdata-widget"]').click();
cy.get('[data-cy="mock-map"]').click();
cy.get('[data-cy="digital-tilraksdata-text"]').should("not.exist");
})



});
});
});
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added webapp/public/actionMap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 2 additions & 4 deletions webapp/src/app/data/shortcuts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ const shortcuts: ShortcutLink[] = [
{ label: 'CADAiD', url: '/for-soknad/cadaid', text: "Verifiser plantegningene dine" },
{ label: 'ArkivGPT', url: '/for-soknad/arkivgpt', text: "Snakk med byggesaksarkivet" },
{ label: 'Planchat', url: '/for-soknad/planprat', text: "Få oversikt over hva du har lov å gjøre med denne chatbotten" },
{ label: 'Tiltakskart', url: '/for-soknad/tiltakskart', text: "Se tiltakene rundt deg"},
{ label: '3D-situasjonsmodell', url: '/for-soknad/3d-situasjon', text: "Se ditt tiltak i 3D kart" },
{ label: 'Min byggeidé', url: '/for-soknad/byggeideer/dashbord', text: "Organiser informasjonen rundt din byggesøknad" },
],
},
{
Expand All @@ -52,10 +52,8 @@ const shortcuts: ShortcutLink[] = [
{ label: 'CADAiD', url: '/under-soknad/cadaid', text: "Verifiser plantegningene dine" },
{ label: 'ArkivGPT', url: '/under-soknad/arkivgpt', text: "Snakk med byggesaksarkivet" },
{ label: 'Planchat', url: '/under-soknad/planprat', text: "Få oversikt over hva du har lov å gjøre med denne chatbotten"},
{ label: 'Søknadsinformasjon', url: '/for-soknad/soknadsinfo', text: "Se detaljert analyse av, og informasjon rundt, din byggesøknad" },
{ label: 'Tiltakskart', url: '/under-soknad/tiltakskart', text: "Se tiltakene rundt deg" },
{ label: 'Søknadsinformasjon', url: '/under-soknad/byggeideer/dashbord', text: "Se detaljert analyse av, og informasjon rundt, din byggesøknad" },
{ label: '3D-situasjonsmodell', url: '/under-soknad/3d-situasjon', text: "Se ditt tiltak i 3D kart" },
{ label: 'Saken oppsummert', url: '/under-soknad/oppsummering', text: "Få totaloversikt over søknaden din" },
],
},
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import ArkivGPTPage from "~/components/ArkivGPT";

export default async function ArkivGPT() {
return (
<ArkivGPTPage/>
);
}
9 changes: 9 additions & 0 deletions webapp/src/app/for-soknad/byggeideer/dashbord/cadaid/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import CadaidPage from "~/components/CADAiD";

export default async function PlantegningsAnalyse() {
return (
<CadaidPage/>
);
}


10 changes: 10 additions & 0 deletions webapp/src/app/for-soknad/byggeideer/dashbord/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"use client";
import UserDashboard from "~/components/UserDashboard";

export default function Dashboard() {
const BASE_URL = "/for-soknad/byggeideer/dashbord";
return(
<UserDashboard BASE_URL={BASE_URL}/>
);

}
4 changes: 2 additions & 2 deletions webapp/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import Navbar from "../components/Navbar";
import Footer from "../components/Footer";

export const metadata: Metadata = {
title: "Create T3 App",
description: "Generated by create-t3-app",
title: "KartAI AI-modeller",
description: "Dette er en tjeneste som viser hvordan de ulike KI-assistentene til Norkart kan brukes til å effektivisere og hjelpe innbyggere og saksbehandlere med byggesøknader.",
icons: [{ rel: "icon", url: "/favicon.ico" }],
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import ArkivGPTPage from "~/components/ArkivGPT";

export default async function ArkivGPT() {
return (
<ArkivGPTPage />
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import CadaidPage from "~/components/CADAiD";

export default async function PlantegningsAnalyse() {
return (
<CadaidPage />
);
}
Loading

0 comments on commit 5a739be

Please sign in to comment.