windopper commited on
Commit
7bee6d4
ยท
1 Parent(s): cf91caa

remove nav_bridge.py and update dependencies in pyproject.toml and README.md to reflect changes in navigation API endpoints and session management

Browse files
README.md CHANGED
@@ -27,15 +27,17 @@ uvicorn server:app --reload
27
  API ๋ฌธ์„œ๋Š” `http://localhost:8000/docs`์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
28
 
29
  ## API ์—”๋“œํฌ์ธํŠธ
30
- ### POST `/api/navigation/step`
31
-
32
- ๋„ค๋น„๊ฒŒ์ด์…˜ ๋‹จ๊ณ„๋ณ„ ์•ˆ๋‚ด๋ฅผ ์š”์ฒญ
33
 
34
- **์š”์ฒญ:**
35
- - `request_text` (Form): ์ž์—ฐ์–ด ์š”์ฒญ ํ…์ŠคํŠธ
36
- - `image` (File): ํ˜„์žฅ ์ด๋ฏธ์ง€ ํŒŒ์ผ
 
37
 
38
- **์‘๋‹ต ์˜ˆ์‹œ:**
 
 
 
 
39
  ```json
40
  {
41
  "schema_version": 1,
@@ -55,6 +57,28 @@ API ๋ฌธ์„œ๋Š” `http://localhost:8000/docs`์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
55
  }
56
  ```
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  ## ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ
59
 
60
  ```
@@ -64,3 +88,4 @@ caanip-backend/
64
  โ”œโ”€โ”€ pyproject.toml # ํ”„๋กœ์ ํŠธ ์„ค์ • ๋ฐ ์˜์กด์„ฑ
65
  โ””โ”€โ”€ README.md # ํ”„๋กœ์ ํŠธ ๋ฌธ์„œ
66
  ```
 
 
27
  API ๋ฌธ์„œ๋Š” `http://localhost:8000/docs`์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
28
 
29
  ## API ์—”๋“œํฌ์ธํŠธ
 
 
 
30
 
31
+ ### POST `/api/navigation/start`
32
+ - ์ž์—ฐ์–ด ์š”์ฒญ๊ณผ ์‹œ์ž‘ ๋ฐฉ, ํ˜„์žฅ ์ด๋ฏธ์ง€๋ฅผ ๋ฐ›์•„ ๋„ค๋น„๊ฒŒ์ด์…˜ ์„ธ์…˜์„ ์ƒ์„ฑํ•˜๊ณ  ์ฒซ ์•ˆ๋‚ด๋ฅผ ๋ฐ˜ํ™˜
33
+ - Form ๋ฐ์ดํ„ฐ: `request_text`(์ž์—ฐ์–ด ์š”์ฒญ), `start_room`(์‹œ์ž‘ ๋ฐฉ ๋ฒˆํ˜ธ), File: `image`(ํ˜„์žฅ ์ด๋ฏธ์ง€)
34
+ - ์‘๋‹ต: ์ฒซ ๋„ค๋น„๊ฒŒ์ด์…˜ ์•ˆ๋‚ด(JSON). ์„ธ์…˜ ์ƒํƒœ๊ฐ€ `CAAINP-NAVIGATION-COOKIE`์— ์ €์žฅ๋จ.
35
 
36
+ ### POST `/api/navigation/step`
37
+ - ์ฟ ํ‚ค์— ์ €์žฅ๋œ ์„ธ์…˜ ์ƒํƒœ(plan, prev_node)๋ฅผ ์‚ฌ์šฉํ•ด ๋‹ค์Œ ๋‹จ๊ณ„ ์•ˆ๋‚ด๋ฅผ ๋ฐ˜ํ™˜
38
+ - File: `image`(ํ˜„์žฅ ์ด๋ฏธ์ง€)
39
+ - ์„ธ์…˜์ด ์—†์œผ๋ฉด `{ "status": "error", "message": "/api/navigation/start๋ฅผ ๋จผ์ € ํ˜ธ์ถœํ•˜์„ธ์š”." }` ๋ฐ˜ํ™˜
40
+ - ์‘๋‹ต ์˜ˆ์‹œ:
41
  ```json
42
  {
43
  "schema_version": 1,
 
57
  }
58
  ```
59
 
60
+ ### POST `/api/navigation/reset`
61
+ - ์ €์žฅ๋œ ๋„ค๋น„๊ฒŒ์ด์…˜ ์ฟ ํ‚ค ์‚ญ์ œ ํ›„ ์„ธ์…˜ ์ดˆ๊ธฐํ™”
62
+ - ์‘๋‹ต: `{ "status": "success", "message": "๋„ค๋น„๊ฒŒ์ด์…˜ ์„ธ์…˜์ด ์ดˆ๊ธฐํ™”๋˜์—ˆ์Šต๋‹ˆ๋‹ค." }`
63
+
64
+ ### POST `/api/navigation/mock`
65
+ - ์‹ค์ œ ์—”์ง„ ๋Œ€์‹  ๋ชจ์˜ ์‘๋‹ต ๋ฐ˜ํ™˜(๋””๋ฒ„๊น…/ํ”„๋ก ํŠธ์—”๋“œ ์—ฐ๋™์šฉ)
66
+ - Form: `request_text`, File: `image`
67
+ - ์‘๋‹ต: ๋ชจ์˜ ๋„ค๋น„๊ฒŒ์ด์…˜ JSON
68
+
69
+ ### GET `/api/cookie/get`
70
+ - ํ˜„์žฌ ์š”์ฒญ์˜ `CAAINP-NAVIGATION-COOKIE` ๊ฐ’์„ ์กฐํšŒ
71
+ - ์‘๋‹ต: `{ "cookie": {plan, prev_node} | null }`
72
+
73
+ ### GET `/api/cookie/delete`
74
+ - ๋„ค๋น„๊ฒŒ์ด์…˜ ์ฟ ํ‚ค ์‚ญ์ œ
75
+ - ์‘๋‹ต: `{ "status": "success", "message": "์ฟ ํ‚ค๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์‚ญ์ œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค." }`
76
+
77
+ ## ํ…Œ์ŠคํŠธ
78
+ ```bash
79
+ uv run tests/navigation_test.py
80
+ ```
81
+
82
  ## ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ
83
 
84
  ```
 
88
  โ”œโ”€โ”€ pyproject.toml # ํ”„๋กœ์ ํŠธ ์„ค์ • ๋ฐ ์˜์กด์„ฑ
89
  โ””โ”€โ”€ README.md # ํ”„๋กœ์ ํŠธ ๋ฌธ์„œ
90
  ```
91
+
core/cookie.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import Request, Response
2
+ from caainp_csm.plan_csm import PlanState, Constraints, Step
3
+ import json
4
+
5
+ COOKIE_KEY = "CAAINP-NAVIGATION-COOKIE"
6
+
7
+
8
+ def plan_to_dict(plan: PlanState) -> dict:
9
+ """PlanState๋ฅผ JSON ์ง๋ ฌํ™” ๊ฐ€๋Šฅํ•œ dict๋กœ ๋ณ€ํ™˜"""
10
+ return {
11
+ "constraints": {
12
+ "use_elevator_only": plan.constraints.use_elevator_only,
13
+ "avoid_stairs": plan.constraints.avoid_stairs,
14
+ "forbidden_nodes": plan.constraints.forbidden_nodes,
15
+ "via_rooms": plan.constraints.via_rooms,
16
+ },
17
+ "steps": [
18
+ {
19
+ "step_id": s.step_id,
20
+ "goal_type": s.goal_type,
21
+ "goal_room": s.goal_room,
22
+ "allowed_moves": s.allowed_moves,
23
+ "description_ko": s.description_ko,
24
+ "target_nodes": s.target_nodes,
25
+ "route_nodes": s.route_nodes,
26
+ }
27
+ for s in plan.steps
28
+ ],
29
+ "current_step": plan.current_step,
30
+ "steps_status": plan.steps_status,
31
+ "step_targets": {str(k): v for k, v in plan.step_targets.items()},
32
+ "in_target_count": plan.in_target_count,
33
+ }
34
+
35
+
36
+ def dict_to_plan(data: dict) -> PlanState:
37
+ """dict๋ฅผ PlanState ๊ฐ์ฒด๋กœ ๋ณต์›"""
38
+ constraints = Constraints(
39
+ use_elevator_only=data["constraints"]["use_elevator_only"],
40
+ avoid_stairs=data["constraints"]["avoid_stairs"],
41
+ forbidden_nodes=data["constraints"]["forbidden_nodes"],
42
+ via_rooms=data["constraints"]["via_rooms"],
43
+ )
44
+
45
+ steps = [
46
+ Step(
47
+ step_id=s["step_id"],
48
+ goal_type=s["goal_type"],
49
+ goal_room=s["goal_room"],
50
+ allowed_moves=s["allowed_moves"],
51
+ description_ko=s["description_ko"],
52
+ target_nodes=s["target_nodes"],
53
+ route_nodes=s["route_nodes"],
54
+ )
55
+ for s in data["steps"]
56
+ ]
57
+
58
+ # steps_status์˜ ํ‚ค๋ฅผ int๋กœ ๋ณต์›
59
+ steps_status = {int(k): v for k, v in data["steps_status"].items()}
60
+ # step_targets์˜ ํ‚ค๋ฅผ int๋กœ ๋ณต์›
61
+ step_targets = {int(k): v for k, v in data["step_targets"].items()}
62
+
63
+ return PlanState(
64
+ constraints=constraints,
65
+ steps=steps,
66
+ current_step=data["current_step"],
67
+ steps_status=steps_status,
68
+ step_targets=step_targets,
69
+ in_target_count=data["in_target_count"],
70
+ )
71
+
72
+
73
+ def get_nav_state_from_cookie(request: Request) -> tuple[PlanState, int] | None:
74
+ """์ฟ ํ‚ค์—์„œ ๋„ค๋น„๊ฒŒ์ด์…˜ ์ƒํƒœ๋ฅผ ์ฝ์–ด์„œ ๋ฐ˜ํ™˜"""
75
+ cookies = dict(request.cookies)
76
+ nav_state_cookie = cookies.get(COOKIE_KEY)
77
+
78
+ if not nav_state_cookie:
79
+ return None
80
+
81
+ try:
82
+ nav_state = json.loads(nav_state_cookie)
83
+ plan_dict = nav_state.get("plan")
84
+ prev_node = nav_state.get("prev_node")
85
+ plan = dict_to_plan(plan_dict)
86
+ return plan, prev_node
87
+ except (json.JSONDecodeError, KeyError, TypeError):
88
+ return None
89
+
90
+
91
+ def save_nav_state_to_cookie(response: Response, plan: PlanState, prev_node: int) -> None:
92
+ """๋„ค๋น„๊ฒŒ์ด์…˜ ์ƒํƒœ(plan, prev_node)๋ฅผ ์ฟ ํ‚ค์— ์ €์žฅ"""
93
+ nav_state = {
94
+ "plan": plan_to_dict(plan),
95
+ "prev_node": prev_node,
96
+ }
97
+ response.set_cookie(
98
+ key=COOKIE_KEY,
99
+ value=json.dumps(nav_state),
100
+ max_age=3600,
101
+ httponly=True,
102
+ samesite="lax"
103
+ )
104
+
105
+
106
+ def clear_nav_cookie(response: Response) -> None:
107
+ """๋„ค๋น„๊ฒŒ์ด์…˜ ์ฟ ํ‚ค ์‚ญ์ œ"""
108
+ response.delete_cookie(COOKIE_KEY)
109
+
core/navigation.py ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from caainp_csm.plan_csm import PlanState
2
+ from caainp_cvm.nav_engine import init_plan, compute_nav_output, _get_csv_path
3
+
4
+ CSV_PATH = _get_csv_path()
5
+
6
+ # ๋„ค๋น„๊ฒŒ์ด์…˜ ์‹œ์ž‘
7
+ def start_navigation(user_text: str, start_room: int, image_path: str):
8
+ plan, _ = init_plan(
9
+ user_text=user_text,
10
+ start_room=start_room,
11
+ )
12
+
13
+ out = compute_nav_output(
14
+ image_path=str(image_path),
15
+ plan=plan,
16
+ prev_node=None,
17
+ csv_path=str(CSV_PATH),
18
+ )
19
+
20
+ nav_output = out["nav_output"]
21
+ plan = out["plan"]
22
+ prev_node = nav_output["current_node"]
23
+
24
+ return plan, nav_output, prev_node
25
+
26
+ # ์ฟ ํ‚ค ๊ฐ’์— ์ €์žฅ๋œ plan, prev_node์ด ์žˆ๋‹ค๋ฉด compute_nav_output ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋„ค๋น„๊ฒŒ์ด์…˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜
27
+ def navigation_step(plan, prev_node, image_path: str):
28
+ out = compute_nav_output(
29
+ image_path=str(image_path),
30
+ plan=plan,
31
+ prev_node=prev_node,
32
+ csv_path=str(CSV_PATH),
33
+ )
34
+
35
+ nav_output = out["nav_output"]
36
+ plan = out["plan"]
37
+ prev_node = nav_output["current_node"]
38
+
39
+ return plan, nav_output, prev_node
pyproject.toml CHANGED
@@ -8,4 +8,11 @@ dependencies = [
8
  "fastapi>=0.123.10",
9
  "uvicorn>=0.38.0",
10
  "python-multipart>=0.0.6",
 
 
11
  ]
 
 
 
 
 
 
8
  "fastapi>=0.123.10",
9
  "uvicorn>=0.38.0",
10
  "python-multipart>=0.0.6",
11
+ "caainp-csm",
12
+ "caainp-cvm",
13
  ]
14
+
15
+ [tool.uv.sources]
16
+ caainp-csm = { git = "https://github.com/caainp/caainp-csm.git" }
17
+ caainp-cvm = { git = "https://github.com/caainp/caainp-cvm.git" }
18
+
routes/cookie.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, Request, Response
2
+ from core.cookie import (
3
+ get_nav_state_from_cookie,
4
+ save_nav_state_to_cookie,
5
+ clear_nav_cookie,
6
+ COOKIE_KEY,
7
+ )
8
+
9
+ router = APIRouter(prefix="/api/cookie", tags=["cookie"])
10
+
11
+ @router.get("/get")
12
+ async def cookie_get(request: Request):
13
+ """์ฟ ํ‚ค ์ฝ๊ธฐ ํ…Œ์ŠคํŠธ ์—”๋“œํฌ์ธํŠธ"""
14
+ cookies = dict(request.cookies)
15
+ return {
16
+ "cookie": cookies.get(COOKIE_KEY)
17
+ }
18
+
19
+ @router.get("/delete")
20
+ async def cookie_delete(request: Request, response: Response):
21
+ """์ฟ ํ‚ค ์‚ญ์ œ ํ…Œ์ŠคํŠธ ์—”๋“œํฌ์ธํŠธ"""
22
+ clear_nav_cookie(response)
23
+ return {
24
+ "status": "success",
25
+ "message": "์ฟ ํ‚ค๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์‚ญ์ œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค."
26
+ }
routes/navigation.py ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, UploadFile, File, Form, Request, Response
2
+ from core.navigation import start_navigation, navigation_step as nav_step
3
+ from core.cookie import (
4
+ get_nav_state_from_cookie,
5
+ save_nav_state_to_cookie,
6
+ clear_nav_cookie,
7
+ )
8
+ from mock_responses import generate_mock_navigation_response
9
+ import tempfile
10
+ import os
11
+
12
+ router = APIRouter(prefix="/api/navigation", tags=["navigation"])
13
+
14
+
15
+ @router.post("/step")
16
+ async def navigation_step_route(
17
+ request: Request,
18
+ response: Response,
19
+ image: UploadFile = File(..., description="์ด๋ฏธ์ง€"),
20
+ ):
21
+ # ์ฟ ํ‚ค์—์„œ plan๊ณผ prev_node ์ฝ๊ธฐ
22
+ nav_state = get_nav_state_from_cookie(request)
23
+
24
+ if not nav_state:
25
+ return {
26
+ "status": "error",
27
+ "message": "๋„ค๋น„๊ฒŒ์ด์…˜ ์„ธ์…˜์ด ์—†์Šต๋‹ˆ๋‹ค. /api/navigation/start๋ฅผ ๋จผ์ € ํ˜ธ์ถœํ•˜์„ธ์š”."
28
+ }
29
+
30
+ plan, prev_node = nav_state
31
+
32
+ # ์ด๋ฏธ์ง€๋ฅผ ์ž„์‹œ ํŒŒ์ผ๋กœ ์ €์žฅ
33
+ image_content = await image.read()
34
+ with tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(image.filename)[1]) as tmp_file:
35
+ tmp_file.write(image_content)
36
+ tmp_path = tmp_file.name
37
+
38
+ try:
39
+ # navigation_step ํ˜ธ์ถœ
40
+ plan, nav_output, prev_node = nav_step(
41
+ plan=plan,
42
+ prev_node=prev_node,
43
+ image_path=tmp_path,
44
+ )
45
+
46
+ # ์ฟ ํ‚ค์— ์ƒํƒœ ์ €์žฅ
47
+ save_nav_state_to_cookie(response, plan, prev_node)
48
+
49
+ return nav_output
50
+ finally:
51
+ # ์ž„์‹œ ํŒŒ์ผ ์‚ญ์ œ
52
+ if os.path.exists(tmp_path):
53
+ os.unlink(tmp_path)
54
+
55
+
56
+ @router.post("/start")
57
+ async def navigation_start_route(
58
+ response: Response,
59
+ request_text: str = Form(..., description="์ž์—ฐ์–ด ์š”์ฒญ"),
60
+ start_room: int = Form(..., description="์‹œ์ž‘ ๋ฐฉ"),
61
+ image: UploadFile = File(..., description="์ด๋ฏธ์ง€"),
62
+ ):
63
+ # ๊ธฐ์กด ์ฟ ํ‚ค ์ดˆ๊ธฐํ™” (์ƒˆ ์„ธ์…˜ ์‹œ์ž‘)
64
+ clear_nav_cookie(response)
65
+
66
+ # ์ด๋ฏธ์ง€๋ฅผ ์ž„์‹œ ํŒŒ์ผ๋กœ ์ €์žฅ
67
+ image_content = await image.read()
68
+ with tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(image.filename)[1]) as tmp_file:
69
+ tmp_file.write(image_content)
70
+ tmp_path = tmp_file.name
71
+
72
+ try:
73
+ # start_navigation ํ˜ธ์ถœ
74
+ plan, nav_output, prev_node = start_navigation(
75
+ user_text=request_text,
76
+ start_room=start_room,
77
+ image_path=tmp_path,
78
+ )
79
+
80
+ # ์ฟ ํ‚ค์— ์ƒํƒœ ์ €์žฅ
81
+ save_nav_state_to_cookie(response, plan, prev_node)
82
+
83
+ return nav_output
84
+ finally:
85
+ # ์ž„์‹œ ํŒŒ์ผ ์‚ญ์ œ
86
+ if os.path.exists(tmp_path):
87
+ os.unlink(tmp_path)
88
+
89
+
90
+ @router.post("/reset")
91
+ async def navigation_reset_route(
92
+ response: Response,
93
+ ):
94
+ clear_nav_cookie(response)
95
+ return {
96
+ "status": "success",
97
+ "message": "๋„ค๋น„๊ฒŒ์ด์…˜ ์„ธ์…˜์ด ์ดˆ๊ธฐํ™”๋˜์—ˆ์Šต๋‹ˆ๋‹ค."
98
+ }
99
+
100
+ @router.post("/mock")
101
+ async def navigation_mock(
102
+ request_text: str = Form(..., description="์ž์—ฐ์–ด ์š”์ฒญ"),
103
+ image: UploadFile = File(..., description="์ด๋ฏธ์ง€"),
104
+ ):
105
+ await image.read()
106
+ response = generate_mock_navigation_response()
107
+ return response
108
+
server.py CHANGED
@@ -1,22 +1,19 @@
1
- from fastapi import FastAPI, UploadFile, File, Form
2
  from datetime import datetime
3
- from mock_responses import generate_mock_navigation_response
 
 
4
 
5
  app = FastAPI()
6
 
 
 
 
 
7
  @app.get("/api/health")
8
  def health_check():
9
  return {
10
  "status": "healthy",
11
  "timestamp": datetime.now().isoformat(),
12
  "service": "caanip-backend"
13
- }
14
-
15
- @app.post("/api/navigation/step")
16
- async def navigation_step(
17
- request_text: str = Form(..., description="์ž์—ฐ์–ด ์š”์ฒญ"),
18
- image: UploadFile = File(..., description="์ด๋ฏธ์ง€"),
19
- ):
20
- await image.read()
21
- response = generate_mock_navigation_response()
22
- return response
 
1
+ from fastapi import FastAPI, Request, Response
2
  from datetime import datetime
3
+ from routes.navigation import router as navigation_router
4
+ from routes.cookie import router as cookie_router
5
+ import uuid
6
 
7
  app = FastAPI()
8
 
9
+ # ๋ผ์šฐํ„ฐ ๋“ฑ๋ก
10
+ app.include_router(navigation_router)
11
+ app.include_router(cookie_router)
12
+
13
  @app.get("/api/health")
14
  def health_check():
15
  return {
16
  "status": "healthy",
17
  "timestamp": datetime.now().isoformat(),
18
  "service": "caanip-backend"
19
+ }
 
 
 
 
 
 
 
 
 
nav_bridge.py โ†’ tests/navigation_test.py RENAMED
@@ -4,43 +4,26 @@ import sys
4
  # ํ˜„์žฌ ํŒŒ์ผ ์œ„์น˜: .../nav/caanip-backend/nav_bridge.py
5
  THIS_DIR = Path(__file__).resolve().parent
6
  BACKEND_ROOT = THIS_DIR # .../caanip-backend
7
- NAV_ROOT = BACKEND_ROOT.parent # .../nav (caainp-csm, caainp-cvm, caanip-backend ์ƒ์œ„ ๋””๋ ‰ํ† ๋ฆฌ)
8
 
9
- # 1) CSM(src) / CVM(nav_engine) ๊ฒฝ๋กœ๋ฅผ ํŒŒ์ด์ฌ ๋ชจ๋“ˆ ๊ฒ€์ƒ‰ ๊ฒฝ๋กœ์— ์ถ”๊ฐ€
10
- CSM_SRC = NAV_ROOT / "caainp-csm" / "src"
11
- CVM_ROOT = NAV_ROOT / "caainp-cvm"
12
-
13
- sys.path.append(str(CSM_SRC))
14
- sys.path.append(str(CVM_ROOT))
15
-
16
- # 2) CSM ๋ชจ๋“ˆ์„ nav_engine๊ณผ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ์ง์ ‘ import
17
- from graph_4f import Graph4F
18
- from plan_csm import (
19
- Constraints,
20
- Step,
21
- PlanState,
22
- create_simple_plan,
23
- update_state_with_node,
24
- )
25
-
26
- # 3) CVM ์ชฝ nav_engine์—์„œ ์—”์ง„ ํ•จ์ˆ˜ import
27
- from nav_engine import init_plan, compute_nav_output
28
 
 
29
 
30
  def quick_test():
31
  """
32
  backend ๋ ˆํฌ์—์„œ CSM + CVM + nav_engine์ด ์ œ๋Œ€๋กœ ์—ฐ๊ฒฐ๋˜๋Š”์ง€ ํ™•์ธ์šฉ.
33
  ์‹ค์ œ FastAPI ์ฝ”๋“œ์—์„œ๋Š” init_plan / compute_nav_output๋งŒ ๊ฐ€์ ธ๋‹ค ์“ฐ๋ฉด ๋จ.
34
  """
35
- # 1) ํ”Œ๋žœ ์ดˆ๊ธฐํ™” (CSM)
36
- plan, csv_path = init_plan(
37
  user_text="401์—์„œ 410ํ˜ธ๊นŒ์ง€ ์ด๋™",
38
  start_room=401,
39
  )
40
 
41
- # 2) CVM ์ด๋ฏธ์ง€ ๊ฒฝ๋กœ ์„ค์ • (caainp-cvm/nav_engine.py์—์„œ ์“ฐ๋˜ node_images ๊ธฐ์ค€)
42
- node_images_dir = CVM_ROOT / "node_images" / "node_images"
43
- img_seq = ["401.jpg", "4102.jpg", "4201.jpg"]
44
 
45
  prev_node = None
46
 
@@ -51,7 +34,7 @@ def quick_test():
51
  image_path=str(image_path),
52
  plan=plan, # PlanState ๊ฐ์ฒด (์šฐ๋ฆฌ๊ฐ€ nav_engine์—์„œ ์“ฐ๋Š” ๋ฒ„์ „ ๊ธฐ์ค€)
53
  prev_node=prev_node,
54
- csv_path=str(csv_path),
55
  )
56
 
57
  nav_output = out["nav_output"]
@@ -62,6 +45,5 @@ def quick_test():
62
  print(f"\n[IMAGE] {img_name}")
63
  pprint(nav_output)
64
 
65
-
66
  if __name__ == "__main__":
67
  quick_test()
 
4
  # ํ˜„์žฌ ํŒŒ์ผ ์œ„์น˜: .../nav/caanip-backend/nav_bridge.py
5
  THIS_DIR = Path(__file__).resolve().parent
6
  BACKEND_ROOT = THIS_DIR # .../caanip-backend
 
7
 
8
+ from caainp_csm.graph_4f import Graph4F
9
+ from caainp_csm.plan_csm import (Constraints, Step, PlanState, create_simple_plan, update_state_with_node)
10
+ from caainp_cvm.nav_engine import init_plan, compute_nav_output, _get_csv_path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
+ CSV_PATH = _get_csv_path()
13
 
14
  def quick_test():
15
  """
16
  backend ๋ ˆํฌ์—์„œ CSM + CVM + nav_engine์ด ์ œ๋Œ€๋กœ ์—ฐ๊ฒฐ๋˜๋Š”์ง€ ํ™•์ธ์šฉ.
17
  ์‹ค์ œ FastAPI ์ฝ”๋“œ์—์„œ๋Š” init_plan / compute_nav_output๋งŒ ๊ฐ€์ ธ๋‹ค ์“ฐ๋ฉด ๋จ.
18
  """
19
+
20
+ plan = init_plan(
21
  user_text="401์—์„œ 410ํ˜ธ๊นŒ์ง€ ์ด๋™",
22
  start_room=401,
23
  )
24
 
25
+ node_images_dir = BACKEND_ROOT / "images"
26
+ img_seq = ["401(1).jpg", "403(3).jpg", "410(1).jpg"]
 
27
 
28
  prev_node = None
29
 
 
34
  image_path=str(image_path),
35
  plan=plan, # PlanState ๊ฐ์ฒด (์šฐ๋ฆฌ๊ฐ€ nav_engine์—์„œ ์“ฐ๋Š” ๋ฒ„์ „ ๊ธฐ์ค€)
36
  prev_node=prev_node,
37
+ csv_path=str(CSV_PATH),
38
  )
39
 
40
  nav_output = out["nav_output"]
 
45
  print(f"\n[IMAGE] {img_name}")
46
  pprint(nav_output)
47
 
 
48
  if __name__ == "__main__":
49
  quick_test()
uv.lock CHANGED
The diff for this file is too large to render. See raw diff