ziya 0.1.8__tar.gz → 0.1.9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ziya might be problematic. Click here for more details.

Files changed (40) hide show
  1. {ziya-0.1.8 → ziya-0.1.9}/PKG-INFO +2 -1
  2. {ziya-0.1.8 → ziya-0.1.9}/app/agents/agent.py +55 -34
  3. {ziya-0.1.8 → ziya-0.1.9}/app/agents/prompts.py +3 -1
  4. {ziya-0.1.8 → ziya-0.1.9}/app/main.py +0 -5
  5. ziya-0.1.9/app/server.py +88 -0
  6. {ziya-0.1.8 → ziya-0.1.9}/app/utils/directory_util.py +14 -9
  7. {ziya-0.1.8 → ziya-0.1.9}/app/utils/gitignore_parser.py +1 -3
  8. {ziya-0.1.8 → ziya-0.1.9}/pyproject.toml +7 -5
  9. ziya-0.1.9/scripts.py +42 -0
  10. ziya-0.1.9/templates/.DS_Store +0 -0
  11. ziya-0.1.9/templates/asset-manifest.json +21 -0
  12. ziya-0.1.9/templates/index.html +1 -0
  13. ziya-0.1.9/templates/static/css/main.85c755f1.css +8 -0
  14. ziya-0.1.9/templates/static/css/main.85c755f1.css.map +1 -0
  15. ziya-0.1.9/templates/static/js/main.d47d0f10.js +3 -0
  16. ziya-0.1.9/templates/static/js/main.d47d0f10.js.LICENSE.txt +39 -0
  17. ziya-0.1.9/templates/static/js/main.d47d0f10.js.map +1 -0
  18. ziya-0.1.9/templates/static/media/fa-brands-400.455ea818179b4def0c43.woff2 +0 -0
  19. ziya-0.1.9/templates/static/media/fa-brands-400.60127e352b7a11f7f1bc.ttf +0 -0
  20. ziya-0.1.9/templates/static/media/fa-regular-400.21cb8f55d8e0c5b89751.woff2 +0 -0
  21. ziya-0.1.9/templates/static/media/fa-regular-400.eb91f7b948a42799f678.ttf +0 -0
  22. ziya-0.1.9/templates/static/media/fa-solid-900.4d986b00ff9ca3828fbd.woff2 +0 -0
  23. ziya-0.1.9/templates/static/media/fa-solid-900.bacd5de623fb563b961a.ttf +0 -0
  24. ziya-0.1.9/templates/static/media/fa-v4compatibility.c8e090db312b0bea2aa2.ttf +0 -0
  25. ziya-0.1.9/templates/static/media/fa-v4compatibility.cf7f5903d06b79ad60f1.woff2 +0 -0
  26. ziya-0.1.8/app/server.py +0 -22
  27. ziya-0.1.8/static/app.js +0 -158
  28. ziya-0.1.8/static/sendPayload.js +0 -62
  29. ziya-0.1.8/static/ziya.css +0 -88
  30. ziya-0.1.8/templates/index.html +0 -19
  31. {ziya-0.1.8 → ziya-0.1.9}/LICENSE +0 -0
  32. {ziya-0.1.8 → ziya-0.1.9}/README.md +0 -0
  33. {ziya-0.1.8 → ziya-0.1.9}/app/__init__.py +0 -0
  34. {ziya-0.1.8 → ziya-0.1.9}/app/agents/__init__.py +0 -0
  35. {ziya-0.1.8 → ziya-0.1.9}/app/utils/__init__.py +0 -0
  36. {ziya-0.1.8 → ziya-0.1.9}/app/utils/langchain_validation_util.py +0 -0
  37. {ziya-0.1.8 → ziya-0.1.9}/app/utils/logging_utils.py +0 -0
  38. {ziya-0.1.8 → ziya-0.1.9}/app/utils/print_tree_util.py +0 -0
  39. {ziya-0.1.8 → ziya-0.1.9}/app/utils/version_util.py +0 -0
  40. {ziya-0.1.8/static → ziya-0.1.9/templates}/favicon.ico +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ziya
3
- Version: 0.1.8
3
+ Version: 0.1.9
4
4
  Summary:
5
5
  Author: Vishnu Krishnaprasad
6
6
  Author-email: vishnukool@gmail.com
@@ -18,6 +18,7 @@ Requires-Dist: langchain-aws (>=0.1.0,<0.2.0)
18
18
  Requires-Dist: langchain-cli (>=0.0.15)
19
19
  Requires-Dist: langchainhub (>=0.1.15)
20
20
  Requires-Dist: pydantic (<2)
21
+ Requires-Dist: pydevd-pycharm (>=241.15989.57,<242.0.0)
21
22
  Requires-Dist: tiktoken (>=0.6.0,<0.7.0)
22
23
  Requires-Dist: uvicorn (>=0.23.2,<0.24.0)
23
24
  Description-Content-Type: text/markdown
@@ -1,8 +1,7 @@
1
1
  import os
2
- import botocore
3
-
4
- from typing import Generator, List, Tuple, Set, Union
2
+ from typing import List, Tuple, Set, Union
5
3
 
4
+ import botocore
6
5
  import tiktoken
7
6
  from langchain.agents import AgentExecutor
8
7
  from langchain.agents.format_scratchpad import format_xml
@@ -12,12 +11,12 @@ from langchain_core.messages import AIMessage, HumanMessage
12
11
  from langchain_core.pydantic_v1 import BaseModel, Field
13
12
 
14
13
  from app.agents.prompts import conversational_prompt, parse_output
15
- from app.utils.directory_util import get_ignored_patterns, get_complete_file_list
16
14
  from app.utils.logging_utils import logger
17
15
  from app.utils.print_tree_util import print_file_tree
18
16
 
19
17
 
20
18
  def _format_chat_history(chat_history: List[Tuple[str, str]]) -> List[Union[HumanMessage, AIMessage]]:
19
+ logger.info("Formatting chat history")
21
20
  buffer = []
22
21
  for human, ai in chat_history:
23
22
  buffer.append(HumanMessage(content=human))
@@ -46,32 +45,20 @@ model = ChatBedrock(
46
45
  )
47
46
 
48
47
 
49
- def get_combined_document_contents() -> str:
50
- user_codebase_dir: str = os.environ["ZIYA_USER_CODEBASE_DIR"]
51
- print(f"Reading user's current codebase: {user_codebase_dir}")
52
-
48
+ def get_combined_docs_from_files(files) -> str:
53
49
  combined_contents: str = ""
54
- ignored_patterns: List[str] = get_ignored_patterns(user_codebase_dir)
55
- included_relative_dirs = [pattern.strip() for pattern in os.environ.get("ZIYA_ADDITIONAL_INCLUDE_DIRS", "").split(',')]
56
- all_files: List[str] = get_complete_file_list(user_codebase_dir, ignored_patterns, included_relative_dirs)
57
-
58
- print_file_tree(all_files)
59
-
60
- seen_dirs: Set[str] = set()
61
- for file_path in all_files:
50
+ print_file_tree(files)
51
+ user_codebase_dir: str = os.environ["ZIYA_USER_CODEBASE_DIR"]
52
+ for file_path in files:
62
53
  try:
63
- docs = TextLoader(file_path).load()
54
+ full_file_path = os.path.join(user_codebase_dir, file_path)
55
+ docs = TextLoader(full_file_path).load()
64
56
  for doc in docs:
65
57
  combined_contents += f"File: {file_path}\n{doc.page_content}\n\n"
66
- dir_path = os.path.dirname(file_path)
67
- if dir_path not in seen_dirs:
68
- seen_dirs.add(dir_path)
58
+
69
59
  except Exception as e:
70
- print(f"Skipping file {file_path} due to error: {e}")
60
+ print(f"Skipping file {full_file_path} due to error: {e}")
71
61
 
72
- print("--------------------------------------------------------")
73
- print(f"Ignoring following paths based on gitIgnore and other defaults: {ignored_patterns}")
74
- print("--------------------------------------------------------")
75
62
  print(f"Codebase word count: {len(combined_contents.split()):,}")
76
63
  token_count = len(tiktoken.get_encoding("cl100k_base").encode(combined_contents))
77
64
  print(f"Codebase token count: {token_count:,}")
@@ -79,24 +66,57 @@ def get_combined_document_contents() -> str:
79
66
  print("--------------------------------------------------------")
80
67
  return combined_contents
81
68
 
82
- def get_child_paths(directory: str) -> Generator[str, None, None]:
83
- for entry in os.listdir(directory):
84
- child_path = os.path.join(directory, entry)
85
- yield child_path
86
-
87
-
88
- prompt = conversational_prompt.partial(
89
- codebase=get_combined_document_contents,
90
- )
69
+ # def get_combined_document_contents_from_included_dirs(included_relative_dirs) -> str:
70
+ # user_codebase_dir: str = os.environ["ZIYA_USER_CODEBASE_DIR"]
71
+ # print(f"Reading user's current codebase: {user_codebase_dir}")
72
+ #
73
+ # combined_contents: str = ""
74
+ # ignored_patterns: List[str] = get_ignored_patterns(user_codebase_dir)
75
+ # all_files: List[str] = get_complete_file_list(user_codebase_dir, ignored_patterns, included_relative_dirs)
76
+ # print("all_files")
77
+ # print(all_files)
78
+ #
79
+ # print_file_tree(all_files)
80
+ #
81
+ # seen_dirs: Set[str] = set()
82
+ # for file_path in all_files:
83
+ # try:
84
+ # docs = TextLoader(file_path).load()
85
+ # for doc in docs:
86
+ # combined_contents += f"File: {file_path}\n{doc.page_content}\n\n"
87
+ # dir_path = os.path.dirname(file_path)
88
+ # if dir_path not in seen_dirs:
89
+ # seen_dirs.add(dir_path)
90
+ # except Exception as e:
91
+ # print(f"Skipping file {file_path} due to error: {e}")
92
+ #
93
+ # print("--------------------------------------------------------")
94
+ # print(f"Ignoring following paths based on gitIgnore and other defaults: {ignored_patterns}")
95
+ # print("--------------------------------------------------------")
96
+ # print(f"Codebase word count: {len(combined_contents.split()):,}")
97
+ # token_count = len(tiktoken.get_encoding("cl100k_base").encode(combined_contents))
98
+ # print(f"Codebase token count: {token_count:,}")
99
+ # print(f"Max Claude Token limit: 200,000")
100
+ # print("--------------------------------------------------------")
101
+ # return combined_contents
102
+
103
+ # prompt = conversational_prompt.partial(
104
+ # # codebase=get_combined_document_contents()
105
+ # )
91
106
  llm_with_stop = model.bind(stop=["</tool_input>"])
92
107
 
108
+ def extract_codebase(x):
109
+ # return get_combined_docs_from_files(x["config"].get("include_dirs", ['./']))
110
+ return get_combined_docs_from_files(x["config"].get("files", []))
111
+
93
112
  agent = (
94
113
  {
114
+ "codebase": lambda x: extract_codebase(x),
95
115
  "question": lambda x: x["question"],
96
116
  "agent_scratchpad": lambda x: format_xml(x["intermediate_steps"]),
97
117
  "chat_history": lambda x: _format_chat_history(x["chat_history"]),
98
118
  }
99
- | prompt
119
+ | conversational_prompt
100
120
  | llm_with_stop
101
121
  | parse_output
102
122
  )
@@ -104,6 +124,7 @@ agent = (
104
124
 
105
125
  class AgentInput(BaseModel):
106
126
  question: str
127
+ config: dict = Field({})
107
128
  chat_history: List[Tuple[str, str]] = Field(..., extra={"widget": {"type": "chat"}})
108
129
 
109
130
 
@@ -2,7 +2,8 @@ from langchain_core.agents import AgentFinish
2
2
  from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
3
3
  # import pydevd_pycharm
4
4
 
5
- template = """You are an excellent coder. Help the user with their coding tasks. You are given the entire codebase
5
+ template = """
6
+ You are an excellent coder. Help the user with their coding tasks. You are given the entire codebase
6
7
  of the user in your context. It is in the format like below where first line has the File path and then the content follows.
7
8
 
8
9
  File: <filepath>
@@ -16,6 +17,7 @@ Now below is the current codebase of the user:
16
17
  conversational_prompt = ChatPromptTemplate.from_messages(
17
18
  [
18
19
  ("system", template),
20
+ # ("system", "You are a helpful AI bot. Your name is {name}."),
19
21
  MessagesPlaceholder(variable_name="chat_history"),
20
22
  ("user", "{question}"),
21
23
  ("ai", "{agent_scratchpad}"),
@@ -15,8 +15,6 @@ def parse_arguments():
15
15
  parser = argparse.ArgumentParser(description="Run with custom options")
16
16
  parser.add_argument("--exclude", default=[], type=lambda x: x.split(','),
17
17
  help="List of files or directories to exclude (e.g., --exclude 'tst,build,*.py')")
18
- parser.add_argument("--include", default=[], type=lambda x: x.split(','),
19
- help="List of directories to include (e.g., --include 'src,static'). Only directories for now")
20
18
  parser.add_argument("--profile", type=str, default=None,
21
19
  help="AWS profile to use (e.g., --profile ziya)")
22
20
  parser.add_argument("--model", type=str, choices=["sonnet", "haiku", "opus"], default="sonnet",
@@ -34,9 +32,6 @@ def setup_environment(args):
34
32
  additional_excluded_dirs = ','.join(args.exclude)
35
33
  os.environ["ZIYA_ADDITIONAL_EXCLUDE_DIRS"] = additional_excluded_dirs
36
34
 
37
- additional_included_dirs = ','.join(args.include)
38
- os.environ["ZIYA_ADDITIONAL_INCLUDE_DIRS"] = additional_included_dirs
39
-
40
35
  if args.profile:
41
36
  os.environ["ZIYA_AWS_PROFILE"] = args.profile
42
37
  if args.model:
@@ -0,0 +1,88 @@
1
+ import os
2
+ from typing import Dict, Any, List, Tuple
3
+
4
+ import tiktoken
5
+ from fastapi import FastAPI, Request
6
+ from fastapi.staticfiles import StaticFiles
7
+ from fastapi.templating import Jinja2Templates
8
+ from langserve import add_routes
9
+ from app.agents.agent import agent_executor
10
+ from fastapi.responses import FileResponse
11
+
12
+ # import pydevd_pycharm
13
+ import uvicorn
14
+
15
+ from app.utils.directory_util import get_ignored_patterns
16
+ from app.utils.gitignore_parser import parse_gitignore_patterns
17
+
18
+ app = FastAPI()
19
+ app.mount("/static", StaticFiles(directory="../templates/static"), name="static")
20
+ templates = Jinja2Templates(directory="../templates")
21
+
22
+ # Add a route for the frontend
23
+ add_routes(app, agent_executor, disabled_endpoints=["playground"], path="/ziya")
24
+
25
+
26
+ @app.get("/")
27
+ async def root(request: Request):
28
+ return templates.TemplateResponse("index.html", {"request": request})
29
+
30
+
31
+ @app.get("/favicon.ico", include_in_schema=False)
32
+ async def favicon():
33
+ return FileResponse('../templates/favicon.ico')
34
+
35
+
36
+ def get_folder_structure(directory: str, ignored_patterns: List[Tuple[str, str]], max_depth: int = 99) -> Dict[str, Any]:
37
+ should_ignore_fn = parse_gitignore_patterns(ignored_patterns)
38
+
39
+ def count_tokens(file_path: str) -> int:
40
+ try:
41
+ with open(file_path, 'r') as file:
42
+ content = file.read()
43
+ return len(tiktoken.get_encoding("cl100k_base").encode(content))
44
+ except Exception as e:
45
+ print(f"Skipping file {file_path} due to error: {e}")
46
+ return 0
47
+
48
+ def get_structure(current_dir: str, current_depth: int):
49
+ if current_depth > max_depth:
50
+ return None
51
+
52
+ current_structure = {}
53
+ for entry in os.listdir(current_dir):
54
+ if entry.startswith('.'): # Skip hidden files/folders
55
+ continue
56
+ entry_path = os.path.join(current_dir, entry)
57
+ if os.path.isdir(entry_path):
58
+ if not should_ignore_fn(entry_path):
59
+ sub_structure = get_structure(entry_path, current_depth + 1)
60
+ if sub_structure is not None:
61
+ token_count = sum(sub_structure[key]['token_count'] for key in sub_structure)
62
+ current_structure[entry] = {'token_count': token_count, 'children': sub_structure}
63
+ else:
64
+ if not should_ignore_fn(entry_path):
65
+ token_count = count_tokens(entry_path)
66
+ current_structure[entry] = {'token_count': token_count}
67
+
68
+ return current_structure
69
+
70
+ folder_structure = get_structure(directory, 1)
71
+ return folder_structure
72
+
73
+
74
+ @app.get("/api/folders")
75
+ async def get_folders():
76
+ # pydevd_pycharm.settrace('localhost', port=59939, stdoutToServer=True, stderrToServer=True)
77
+ user_codebase_dir = os.environ["ZIYA_USER_CODEBASE_DIR"]
78
+ ignored_patterns: List[Tuple[str, str]] = get_ignored_patterns(user_codebase_dir)
79
+ return get_folder_structure(user_codebase_dir, ignored_patterns)
80
+
81
+
82
+ @app.get('/api/default-included-folders')
83
+ def get_default_included_folders():
84
+ return {'defaultIncludedFolders': []}
85
+
86
+
87
+ if __name__ == "__main__":
88
+ uvicorn.run(app, host="0.0.0.0", port=8000)
@@ -1,6 +1,6 @@
1
1
  import glob
2
2
  import os
3
- from typing import List, Set, Tuple
3
+ from typing import List, Set, Tuple, Dict
4
4
 
5
5
  from app.utils.gitignore_parser import parse_gitignore_patterns
6
6
 
@@ -41,20 +41,25 @@ def get_ignored_patterns(directory: str) -> List[Tuple[str, str]]:
41
41
  return ignored_patterns
42
42
 
43
43
 
44
- def get_complete_file_list(user_codebase_dir: str, ignored_patterns: List[str], included_relative_dirs: List[str]) -> List[str]:
45
- should_ignore = parse_gitignore_patterns(ignored_patterns, base_dir=user_codebase_dir)
46
- file_set: Set[str] = set()
44
+ def get_complete_file_list(user_codebase_dir: str, ignored_patterns: List[str], included_relative_dirs: List[str]) -> Dict[str, Dict]:
45
+ should_ignore_fn = parse_gitignore_patterns(ignored_patterns)
46
+ file_dict: Dict[str, Dict] = {}
47
47
  for pattern in included_relative_dirs:
48
48
  for root, dirs, files in os.walk(os.path.normpath(os.path.join(user_codebase_dir, pattern))):
49
- # Filter out ignored directories
50
- dirs[:] = [d for d in dirs if not should_ignore(os.path.join(root, d))]
49
+ # Filter out ignored directories and hidden directories
50
+ dirs[:] = [d for d in dirs if not should_ignore_fn(os.path.join(root, d)) and not d.startswith('.')]
51
51
 
52
52
  for file in files:
53
53
  file_path = os.path.join(root, file)
54
- if not should_ignore(file_path) and not is_image_file(file_path):
55
- file_set.add(file_path)
54
+ if not should_ignore_fn(file_path) and not is_image_file(file_path) and not file.startswith('.'):
55
+ file_dict[file_path] = {}
56
56
 
57
- return list(file_set)
57
+ for dir in dirs:
58
+ dir_path = os.path.join(root, dir)
59
+ if not should_ignore_fn(dir_path):
60
+ file_dict[dir_path] = {}
61
+
62
+ return file_dict
58
63
 
59
64
  def is_image_file(file_path: str) -> bool:
60
65
  image_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.svg', '.ico']
@@ -14,9 +14,7 @@ def handle_negation(file_path, rules: Reversible["IgnoreRule"]):
14
14
  return False
15
15
 
16
16
 
17
- def parse_gitignore_patterns(patterns: List[Tuple[str, str]], base_dir=None):
18
- if base_dir is None:
19
- base_dir = os.getcwd()
17
+ def parse_gitignore_patterns(patterns: List[Tuple[str, str]]):
20
18
  rules = []
21
19
  for counter, (pattern, directory) in enumerate(patterns, start=1):
22
20
  rule = rule_from_pattern(pattern, base_path=_normalize_path(directory),
@@ -1,10 +1,10 @@
1
1
  [tool.poetry]
2
2
  name = "ziya"
3
- version = "0.1.8"
3
+ version = "0.1.9"
4
4
  description = ""
5
5
  authors = ["Vishnu Krishnaprasad <vishnukool@gmail.com>"]
6
6
  readme = "README.md"
7
- include = ["static/**/*", "templates/**/*", "pyproject.toml"]
7
+ include = ["templates/**/*", "pyproject.toml" ,"scripts.py"]
8
8
  packages = [
9
9
  { include = "app" },
10
10
  ]
@@ -21,8 +21,6 @@ langchain = "^0.1"
21
21
  langchainhub = ">=0.1.15"
22
22
  langchain-anthropic = "^0.1.4"
23
23
  langchain-cli = ">=0.0.15"
24
-
25
- [tool.poetry.group.dev.dependencies]
26
24
  pydevd-pycharm = "^241.15989.57"
27
25
 
28
26
  [build-system]
@@ -30,4 +28,8 @@ requires = ["poetry-core"]
30
28
  build-backend = "poetry.core.masonry.api"
31
29
 
32
30
  [tool.poetry.scripts]
33
- ziya = 'app.main:main'
31
+ ziya = 'scripts:ziya'
32
+ dev = 'scripts:dev'
33
+ finstall = "scripts:frontend_install"
34
+ fstart = "scripts:frontend_start"
35
+ fbuild = "scripts:frontend_build"
ziya-0.1.9/scripts.py ADDED
@@ -0,0 +1,42 @@
1
+ import threading
2
+ import subprocess
3
+ import signal
4
+ import sys
5
+
6
+ from app.main import main
7
+
8
+
9
+ def frontend_start():
10
+ subprocess.run(["npm", "run", "start"], cwd="frontend")
11
+
12
+
13
+ def frontend_install():
14
+ subprocess.run(["npm", "install"], cwd="frontend")
15
+
16
+
17
+ def frontend_build():
18
+ subprocess.run(["npm", "run", "build"], cwd="frontend")
19
+
20
+
21
+ def ziya():
22
+ # frontend_build()
23
+ main()
24
+
25
+
26
+ def signal_handler(sig, frame):
27
+ print('Interrupt received, shutting down...')
28
+ sys.exit(0)
29
+
30
+
31
+ def dev():
32
+ frontend_thread = threading.Thread(target=frontend_start)
33
+ signal.signal(signal.SIGINT, signal_handler)
34
+
35
+ frontend_thread.start()
36
+ try:
37
+ print("Camme to main")
38
+ main()
39
+ except KeyboardInterrupt:
40
+ print("Main process interrupted.")
41
+ finally:
42
+ frontend_thread.join()
Binary file
@@ -0,0 +1,21 @@
1
+ {
2
+ "files": {
3
+ "main.css": "/static/css/main.85c755f1.css",
4
+ "main.js": "/static/js/main.d47d0f10.js",
5
+ "static/media/fa-solid-900.ttf": "/static/media/fa-solid-900.bacd5de623fb563b961a.ttf",
6
+ "static/media/fa-brands-400.ttf": "/static/media/fa-brands-400.60127e352b7a11f7f1bc.ttf",
7
+ "static/media/fa-solid-900.woff2": "/static/media/fa-solid-900.4d986b00ff9ca3828fbd.woff2",
8
+ "static/media/fa-brands-400.woff2": "/static/media/fa-brands-400.455ea818179b4def0c43.woff2",
9
+ "static/media/fa-regular-400.ttf": "/static/media/fa-regular-400.eb91f7b948a42799f678.ttf",
10
+ "static/media/fa-regular-400.woff2": "/static/media/fa-regular-400.21cb8f55d8e0c5b89751.woff2",
11
+ "static/media/fa-v4compatibility.ttf": "/static/media/fa-v4compatibility.c8e090db312b0bea2aa2.ttf",
12
+ "static/media/fa-v4compatibility.woff2": "/static/media/fa-v4compatibility.cf7f5903d06b79ad60f1.woff2",
13
+ "index.html": "/index.html",
14
+ "main.85c755f1.css.map": "/static/css/main.85c755f1.css.map",
15
+ "main.d47d0f10.js.map": "/static/js/main.d47d0f10.js.map"
16
+ },
17
+ "entrypoints": [
18
+ "static/css/main.85c755f1.css",
19
+ "static/js/main.d47d0f10.js"
20
+ ]
21
+ }
@@ -0,0 +1 @@
1
+ <!doctype html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Ziya - Code Assistant</title><link rel="icon" href="/favicon.ico" type="image/x-icon"><script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script><script defer="defer" src="/static/js/main.d47d0f10.js"></script><link href="/static/css/main.85c755f1.css" rel="stylesheet"></head><body><div id="root"></div></body></html>