Spaces:
Build error
Build error
Commit
·
4e9c1aa
1
Parent(s):
9fd3be8
Add automatic indexed links
Browse files- .gitignore +1 -0
- app/api/api_file.py +1 -1
- app/handlers/webhook_handler.py +4 -4
- app/main.py +14 -3
- app/services/message.py +36 -34
- app/utils/system_prompt.py +10 -12
- indexed_links.txt +55 -5
.gitignore
CHANGED
@@ -8,5 +8,6 @@ document*.txt
|
|
8 |
model/
|
9 |
llamma-duo/
|
10 |
fine*.py
|
|
|
11 |
|
12 |
|
|
|
8 |
model/
|
9 |
llamma-duo/
|
10 |
fine*.py
|
11 |
+
venv/
|
12 |
|
13 |
|
app/api/api_file.py
CHANGED
@@ -244,7 +244,7 @@ async def load_file_with_markdown_function(filepaths: List[str],
|
|
244 |
snippet = document.text_content[:100].replace('\n', ' ').replace('\r', ' ')
|
245 |
# Ensure 'doc_logger' is defined; if not, use 'logger' or define 'doc_logger'
|
246 |
# doc_logger(f"ID: {doc_id}, Snippet: {snippet}")
|
247 |
-
|
248 |
|
249 |
except Exception as e:
|
250 |
logger.error(f"Error processing URL {path}: {str(e)}")
|
|
|
244 |
snippet = document.text_content[:100].replace('\n', ' ').replace('\r', ' ')
|
245 |
# Ensure 'doc_logger' is defined; if not, use 'logger' or define 'doc_logger'
|
246 |
# doc_logger(f"ID: {doc_id}, Snippet: {snippet}")
|
247 |
+
indexed_links_logger.info(f"{doc_id}_{path}")
|
248 |
|
249 |
except Exception as e:
|
250 |
logger.error(f"Error processing URL {path}: {str(e)}")
|
app/handlers/webhook_handler.py
CHANGED
@@ -22,21 +22,21 @@ class WebhookHandler:
|
|
22 |
request_id = f"req_{int(time.time()*1000)}"
|
23 |
results = []
|
24 |
|
25 |
-
self.logger.info(f"Processing webhook request {payload}")
|
26 |
|
27 |
try:
|
28 |
entries = payload.get("entry", [])
|
29 |
for entry in entries:
|
30 |
entry_id = entry.get("id")
|
31 |
-
self.logger.info(f"Processing entry_id: {entry_id}")
|
32 |
|
33 |
changes = entry.get("changes", [])
|
34 |
for change in changes:
|
35 |
messages = change.get("value", {}).get("messages", [])
|
36 |
-
self.logger.info(f"message length: {len(messages)}")
|
37 |
for message in messages:
|
38 |
|
39 |
-
self.logger.info(f"Processing message: {message}")
|
40 |
response = await self.message_handler.handle(
|
41 |
raw_message=message,
|
42 |
whatsapp_token=whatsapp_token,
|
|
|
22 |
request_id = f"req_{int(time.time()*1000)}"
|
23 |
results = []
|
24 |
|
25 |
+
# self.logger.info(f"Processing webhook request {payload}")
|
26 |
|
27 |
try:
|
28 |
entries = payload.get("entry", [])
|
29 |
for entry in entries:
|
30 |
entry_id = entry.get("id")
|
31 |
+
# self.logger.info(f"Processing entry_id: {entry_id}")
|
32 |
|
33 |
changes = entry.get("changes", [])
|
34 |
for change in changes:
|
35 |
messages = change.get("value", {}).get("messages", [])
|
36 |
+
# self.logger.info(f"message length: {len(messages)}")
|
37 |
for message in messages:
|
38 |
|
39 |
+
# self.logger.info(f"Processing message: {message}")
|
40 |
response = await self.message_handler.handle(
|
41 |
raw_message=message,
|
42 |
whatsapp_token=whatsapp_token,
|
app/main.py
CHANGED
@@ -12,6 +12,7 @@ from prometheus_client import Counter, Histogram, start_http_server
|
|
12 |
from pydantic import BaseModel, ValidationError
|
13 |
from app.services.message import generate_reply, send_reply
|
14 |
import logging
|
|
|
15 |
from datetime import datetime
|
16 |
from sentence_transformers import SentenceTransformer
|
17 |
from app.search.rag_pipeline import RAGSystem
|
@@ -24,9 +25,10 @@ from app.handlers.media_handler import WhatsAppMediaHandler
|
|
24 |
from app.services.cache import MessageCache
|
25 |
from app.services.chat_manager import ChatManager
|
26 |
from app.api.api_prompt import prompt_router
|
27 |
-
from app.api.api_file import file_router
|
28 |
from app.utils.load_env import ACCESS_TOKEN, WHATSAPP_API_URL, GEMINI_API
|
29 |
|
|
|
30 |
from markitdown import MarkItDown
|
31 |
|
32 |
# Configure logging
|
@@ -41,6 +43,13 @@ logger = logging.getLogger(__name__)
|
|
41 |
message_handler = None
|
42 |
webhook_handler = None
|
43 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
|
45 |
async def setup_message_handler():
|
46 |
logger = logging.getLogger(__name__)
|
@@ -48,6 +57,7 @@ async def setup_message_handler():
|
|
48 |
chat_manager = ChatManager()
|
49 |
media_handler = WhatsAppMediaHandler()
|
50 |
|
|
|
51 |
return MessageHandler(
|
52 |
message_cache=message_cache,
|
53 |
chat_manager=chat_manager,
|
@@ -67,7 +77,7 @@ async def lifespan(app: FastAPI):
|
|
67 |
|
68 |
try:
|
69 |
# await init_db()
|
70 |
-
|
71 |
logger.info("Connected to the MongoDB database!")
|
72 |
rag_system = await setup_rag_system()
|
73 |
|
@@ -78,6 +88,7 @@ async def lifespan(app: FastAPI):
|
|
78 |
webhook_handler = WebhookHandler(message_handler)
|
79 |
# collections = app.database.list_collection_names()
|
80 |
# print(f"Collections in {db_name}: {collections}")
|
|
|
81 |
yield
|
82 |
except Exception as e:
|
83 |
logger.error(e)
|
@@ -107,7 +118,7 @@ class WebhookPayload(BaseModel):
|
|
107 |
entry: List[Dict]
|
108 |
|
109 |
@app.post("/webhook")
|
110 |
-
@limiter.limit("20/minute")
|
111 |
async def webhook(request: Request, background_tasks: BackgroundTasks):
|
112 |
try:
|
113 |
payload = await request.json()
|
|
|
12 |
from pydantic import BaseModel, ValidationError
|
13 |
from app.services.message import generate_reply, send_reply
|
14 |
import logging
|
15 |
+
import httpx
|
16 |
from datetime import datetime
|
17 |
from sentence_transformers import SentenceTransformer
|
18 |
from app.search.rag_pipeline import RAGSystem
|
|
|
25 |
from app.services.cache import MessageCache
|
26 |
from app.services.chat_manager import ChatManager
|
27 |
from app.api.api_prompt import prompt_router
|
28 |
+
from app.api.api_file import file_router, load_file_with_markdown_function
|
29 |
from app.utils.load_env import ACCESS_TOKEN, WHATSAPP_API_URL, GEMINI_API
|
30 |
|
31 |
+
|
32 |
from markitdown import MarkItDown
|
33 |
|
34 |
# Configure logging
|
|
|
43 |
message_handler = None
|
44 |
webhook_handler = None
|
45 |
|
46 |
+
indexed_links = ["https://sswalfa.surabaya.go.id/info/detail/izin-pengumpulan-sumbangan-bencana",
|
47 |
+
"https://sswalfa.surabaya.go.id/info/detail/izin-pemakaian-ruang-terbuka-hijau",
|
48 |
+
"https://sswalfa.surabaya.go.id/info/detail/pengganti-ipt",
|
49 |
+
"https://sswalfa.surabaya.go.id/info/detail/arahan-sistem-drainase",
|
50 |
+
"https://sswalfa.surabaya.go.id/info/detail/rangkaian-pelayanan-surat-pernyataan-belum-menikah-lagi-bagi-jandaduda"
|
51 |
+
]
|
52 |
+
|
53 |
|
54 |
async def setup_message_handler():
|
55 |
logger = logging.getLogger(__name__)
|
|
|
57 |
chat_manager = ChatManager()
|
58 |
media_handler = WhatsAppMediaHandler()
|
59 |
|
60 |
+
|
61 |
return MessageHandler(
|
62 |
message_cache=message_cache,
|
63 |
chat_manager=chat_manager,
|
|
|
77 |
|
78 |
try:
|
79 |
# await init_db()
|
80 |
+
|
81 |
logger.info("Connected to the MongoDB database!")
|
82 |
rag_system = await setup_rag_system()
|
83 |
|
|
|
88 |
webhook_handler = WebhookHandler(message_handler)
|
89 |
# collections = app.database.list_collection_names()
|
90 |
# print(f"Collections in {db_name}: {collections}")
|
91 |
+
await load_file_with_markdown_function(rag_system=rag_system, filepaths=indexed_links)
|
92 |
yield
|
93 |
except Exception as e:
|
94 |
logger.error(e)
|
|
|
118 |
entry: List[Dict]
|
119 |
|
120 |
@app.post("/webhook")
|
121 |
+
# @limiter.limit("20/minute")
|
122 |
async def webhook(request: Request, background_tasks: BackgroundTasks):
|
123 |
try:
|
124 |
payload = await request.json()
|
app/services/message.py
CHANGED
@@ -12,7 +12,7 @@ import google.generativeai as genai
|
|
12 |
import PIL.Image
|
13 |
from typing import List, Dict, Any, Optional
|
14 |
|
15 |
-
from app.utils.load_env import ACCESS_TOKEN, WHATSAPP_API_URL, GEMINI_API
|
16 |
from app.utils.system_prompt import system_prompt
|
17 |
|
18 |
from app.services.search_engine import google_search
|
@@ -44,7 +44,7 @@ function_declarations = [
|
|
44 |
]
|
45 |
|
46 |
genai.configure(api_key=GEMINI_API)
|
47 |
-
client = AsyncOpenAI(api_key = OPENAI_API)
|
48 |
# Configure logging
|
49 |
logging.basicConfig(
|
50 |
level=logging.INFO,
|
@@ -142,8 +142,10 @@ async def generate_response_from_gemini(
|
|
142 |
logger.info(f"Generating response for sender: {sender}")
|
143 |
|
144 |
# Initialize the model
|
145 |
-
|
146 |
-
model = genai.GenerativeModel("gemini-1.5-flash", system_instruction= system_prompt)
|
|
|
|
|
147 |
# Start chat with history
|
148 |
chat = model.start_chat(history=history)
|
149 |
|
@@ -151,7 +153,7 @@ async def generate_response_from_gemini(
|
|
151 |
if rag_system:
|
152 |
keywords = extract_keywords_async(content)
|
153 |
# keywords = []
|
154 |
-
logger.info(f"Extracted Keywords: {keywords}")
|
155 |
# Implement RAG: Retrieve relevant documents
|
156 |
retrieved_docs = await rag_system.adv_query(content, keywords=keywords, top_k=5)
|
157 |
if retrieved_docs:
|
@@ -161,7 +163,7 @@ async def generate_response_from_gemini(
|
|
161 |
# Option 1: Append to history as a system message
|
162 |
history.append({"role": "user", "parts": f"Relevant documents:\n{context}"})
|
163 |
|
164 |
-
logger.info(f"History: {history}")
|
165 |
# Reinitialize chat with updated history
|
166 |
chat = model.start_chat(history=history)
|
167 |
|
@@ -321,40 +323,40 @@ async def handle_function_call(chat):
|
|
321 |
# return "Sorry, I couldn't generate a response at this time."
|
322 |
|
323 |
|
324 |
-
async def generate_response_from_chatgpt(sender: str, content: str, timestamp: str, history: str) -> str:
|
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 |
# async def generate_response_from_chatgpt(
|
|
|
12 |
import PIL.Image
|
13 |
from typing import List, Dict, Any, Optional
|
14 |
|
15 |
+
from app.utils.load_env import ACCESS_TOKEN, WHATSAPP_API_URL, GEMINI_API
|
16 |
from app.utils.system_prompt import system_prompt
|
17 |
|
18 |
from app.services.search_engine import google_search
|
|
|
44 |
]
|
45 |
|
46 |
genai.configure(api_key=GEMINI_API)
|
47 |
+
# client = AsyncOpenAI(api_key = OPENAI_API)
|
48 |
# Configure logging
|
49 |
logging.basicConfig(
|
50 |
level=logging.INFO,
|
|
|
142 |
logger.info(f"Generating response for sender: {sender}")
|
143 |
|
144 |
# Initialize the model
|
145 |
+
model = genai.GenerativeModel("gemini-1.5-pro-002", system_instruction= system_prompt)
|
146 |
+
# model = genai.GenerativeModel("gemini-1.5-flash", system_instruction= system_prompt)
|
147 |
+
# model = genai.GenerativeModel("gemini-exp-1206", system_instruction= system_prompt)
|
148 |
+
|
149 |
# Start chat with history
|
150 |
chat = model.start_chat(history=history)
|
151 |
|
|
|
153 |
if rag_system:
|
154 |
keywords = extract_keywords_async(content)
|
155 |
# keywords = []
|
156 |
+
# logger.info(f"Extracted Keywords: {keywords}")
|
157 |
# Implement RAG: Retrieve relevant documents
|
158 |
retrieved_docs = await rag_system.adv_query(content, keywords=keywords, top_k=5)
|
159 |
if retrieved_docs:
|
|
|
163 |
# Option 1: Append to history as a system message
|
164 |
history.append({"role": "user", "parts": f"Relevant documents:\n{context}"})
|
165 |
|
166 |
+
# logger.info(f"History: {history}")
|
167 |
# Reinitialize chat with updated history
|
168 |
chat = model.start_chat(history=history)
|
169 |
|
|
|
323 |
# return "Sorry, I couldn't generate a response at this time."
|
324 |
|
325 |
|
326 |
+
# async def generate_response_from_chatgpt(sender: str, content: str, timestamp: str, history: str) -> str:
|
327 |
+
# """
|
328 |
+
# Generate a reply using OpenAI's ChatGPT API.
|
329 |
+
# """
|
330 |
+
# try:
|
331 |
+
# # # Initialize chat history if not provided
|
332 |
+
# # chat_history = chat_history or []
|
333 |
|
334 |
+
# # # Append the current user message to the chat history
|
335 |
+
# # chat_history.append({"role": "user", "content": f"From {sender} at {timestamp}: {content}"})
|
336 |
|
337 |
+
# messages = [
|
338 |
+
# {"role": "system", "content": "You're an investor, a serial founder, and you've sold many startups. You understand nothing but business."},
|
339 |
+
# {"role": "system", "content": f"Message History: {history}"},
|
340 |
+
# {"role": "user", "content": f"From {sender} at {timestamp}: {content}"}
|
341 |
+
# ]
|
342 |
|
343 |
+
# print(f"Messages: {messages}")
|
344 |
|
345 |
+
# response = await client.chat.completions.create(
|
346 |
+
# model="gpt-3.5-turbo",
|
347 |
+
# messages=messages,
|
348 |
+
# max_tokens=200,
|
349 |
+
# temperature=0.5
|
350 |
+
# )
|
351 |
|
352 |
+
# chatgpt_response = response.choices[0].message.content.strip()
|
353 |
+
# # Append the assistant's response to the chat history
|
354 |
+
# # chat_history.append({"role": "assistant", "content": chatgpt_response})
|
355 |
+
# return chatgpt_response
|
356 |
|
357 |
+
# except Exception as e:
|
358 |
+
# print("Error generating reply:", e)
|
359 |
+
# return "Sorry, I couldn't generate a response at this time."
|
360 |
|
361 |
|
362 |
# async def generate_response_from_chatgpt(
|
app/utils/system_prompt.py
CHANGED
@@ -1,20 +1,17 @@
|
|
1 |
system_prompt = """
|
2 |
Role and Purpose:
|
3 |
-
You are a
|
4 |
-
|
5 |
-
Knowledge and Sources:
|
6 |
-
You have access to general historical and contextual knowledge about Surabaya, as well as current city developments up to the latest available data. When answering questions, always strive to be accurate, clear, and helpful. If you are unsure about certain details, provide general information and encourage the user to verify with official government sources.
|
7 |
|
8 |
Tone and Style:
|
9 |
-
|
10 |
|
11 |
Content Guidelines:
|
12 |
-
When asked about
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
Always Include Sources: When your response is based on information provided from external sources, include the source link explicitly. For example: "Informasi ini berasal dari www.indosource.com
|
18 |
|
19 |
Example Interactions:
|
20 |
|
@@ -22,9 +19,10 @@ Example Interactions:
|
|
22 |
If a user says, “I heard there will be a community festival next month, can you tell me more?” you might reply: “Yes, the city's annual cultural festival will be held in [location] starting from [date]. It will feature traditional dance performances, local food vendors, and art exhibitions. For a detailed schedule, please visit the city's official cultural events portal.”
|
23 |
If a user asks, “Are there any issues with the city government's policies?” respond factually: “I can provide details on the policies that have been implemented and their stated goals, but I do not offer critiques. To learn more about specific policies and their expected outcomes, you may refer to the official government publications or verified local news outlets.”
|
24 |
|
25 |
-
By
|
26 |
"""
|
27 |
|
|
|
28 |
agentic_prompt = """ You are a helpful assistant and have capabilities to search the web.
|
29 |
When you the links are given, you should summarize the content of the link and give a short summary.
|
30 |
You should also include the source of the link in the summary.
|
|
|
1 |
system_prompt = """
|
2 |
Role and Purpose:
|
3 |
+
You are a virtual assistant focused exclusively on Surabaya, Indonesia. Your primary role is to provide accurate information regarding the permit document provided in the Relevant Document. If you cannot find anything in the Relevant Document, state that you are unsure and direct the user to this website: https://sswalfa.surabaya.go.id/ without bracket or parentheses. You respond only in Bahasa Indonesia. You can reply in Javanese or Maduranese, only if the user talks to you in that language.
|
|
|
|
|
|
|
4 |
|
5 |
Tone and Style:
|
6 |
+
Maintain a polite, neutral, and factual tone. Be professional and represent Surabaya's information accurately without criticism or bias. Always ensure your communication is courteous and focused on providing clear and reliable information.
|
7 |
|
8 |
Content Guidelines:
|
9 |
+
When asked about your origins or creator, state that you were created by Vidavox.
|
10 |
+
Context-Driven Responses: Provide answers solely based on the provided Relevant Document context.
|
11 |
+
Focus on Public Services: Prioritize queries on transportation, health, education, permits, safety, and cultural events.
|
12 |
+
Professional Representation: Avoid personal opinions, judgments, or critiques of the local government. If asked for opinions, explain that your role is to provide factual information rather than subjective viewpoints.
|
13 |
+
Encourage Verification: For unresolved queries, recommend users consult official resources such as the provided website link.
|
14 |
+
Always Include Sources: When your response is based on information provided from external sources or Relevant Document, include the source link explicitly without brackets or parentheses at the end of the response. For example: "Informasi ini berasal dari www.indosource.com (without bracket or parentheses) Anda dapat mengunjungi tautan tersebut untuk detail lebih lanjut."
|
15 |
|
16 |
Example Interactions:
|
17 |
|
|
|
19 |
If a user says, “I heard there will be a community festival next month, can you tell me more?” you might reply: “Yes, the city's annual cultural festival will be held in [location] starting from [date]. It will feature traditional dance performances, local food vendors, and art exhibitions. For a detailed schedule, please visit the city's official cultural events portal.”
|
20 |
If a user asks, “Are there any issues with the city government's policies?” respond factually: “I can provide details on the policies that have been implemented and their stated goals, but I do not offer critiques. To learn more about specific policies and their expected outcomes, you may refer to the official government publications or verified local news outlets.”
|
21 |
|
22 |
+
By adhering to these principles, you will ensure professional and reliable communication about Surabaya's permit processes while respecting local languages and cultural nuances.
|
23 |
"""
|
24 |
|
25 |
+
|
26 |
agentic_prompt = """ You are a helpful assistant and have capabilities to search the web.
|
27 |
When you the links are given, you should summarize the content of the link and give a short summary.
|
28 |
You should also include the source of the link in the summary.
|
indexed_links.txt
CHANGED
@@ -1,5 +1,55 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
2025-01-02 09:49:36,018 - INFO - 7d4efdfd-82bd-4a05-98b3-c70de9c16e0b_https://sswalfa.surabaya.go.id/info/detail/izin-pengumpulan-sumbangan-bencana
|
2 |
+
2025-01-02 09:49:36,486 - INFO - d804a237-9b3e-4c83-8871-2aae6ca1d73d_https://sswalfa.surabaya.go.id/info/detail/izin-pemakaian-ruang-terbuka-hijau
|
3 |
+
2025-01-02 09:49:37,089 - INFO - 820b8df1-2492-4ac6-9230-650bbb875122_https://sswalfa.surabaya.go.id/info/detail/pengganti-ipt
|
4 |
+
2025-01-02 09:49:37,666 - INFO - 82da1b85-5bc3-42ed-80ee-e9b7d8e44123_https://sswalfa.surabaya.go.id/info/detail/arahan-sistem-drainase
|
5 |
+
2025-01-02 09:49:38,270 - INFO - d18fa576-c9cc-4be3-a2b4-7ab46a392f2b_https://sswalfa.surabaya.go.id/info/detail/rangkaian-pelayanan-surat-pernyataan-belum-menikah-lagi-bagi-jandaduda
|
6 |
+
2025-01-02 09:58:45,530 - INFO - b05153a2-968c-4e08-9113-07b51df51d2e_https://sswalfa.surabaya.go.id/info/detail/izin-pengumpulan-sumbangan-bencana
|
7 |
+
2025-01-02 09:58:46,083 - INFO - 35884a24-4095-4ecd-b1c3-10c88947e12b_https://sswalfa.surabaya.go.id/info/detail/izin-pemakaian-ruang-terbuka-hijau
|
8 |
+
2025-01-02 09:58:46,693 - INFO - 8087024d-1e08-4cae-a336-dfe591ae27ce_https://sswalfa.surabaya.go.id/info/detail/pengganti-ipt
|
9 |
+
2025-01-02 09:58:47,195 - INFO - 9bdd88b3-4ed8-4f89-9abb-e2bc49b4da0f_https://sswalfa.surabaya.go.id/info/detail/arahan-sistem-drainase
|
10 |
+
2025-01-02 09:58:47,592 - INFO - ff0a3e9f-cd5a-4977-9ab6-721179f41a9b_https://sswalfa.surabaya.go.id/info/detail/rangkaian-pelayanan-surat-pernyataan-belum-menikah-lagi-bagi-jandaduda
|
11 |
+
2025-01-02 10:02:56,391 - INFO - 7fad3aab-6cbf-40ba-91d6-1213a113e4cc_https://sswalfa.surabaya.go.id/info/detail/izin-pengumpulan-sumbangan-bencana
|
12 |
+
2025-01-02 10:02:56,993 - INFO - 38ac11a0-fd15-438d-985f-3bbe670f60cf_https://sswalfa.surabaya.go.id/info/detail/izin-pemakaian-ruang-terbuka-hijau
|
13 |
+
2025-01-02 10:02:57,542 - INFO - 58a96911-2ee0-438b-adc6-62de8c6ef8c0_https://sswalfa.surabaya.go.id/info/detail/pengganti-ipt
|
14 |
+
2025-01-02 10:02:58,086 - INFO - 87436ad6-0d9a-4374-91b6-1a95c8a623e5_https://sswalfa.surabaya.go.id/info/detail/arahan-sistem-drainase
|
15 |
+
2025-01-02 10:02:58,853 - INFO - cf72c268-2bed-4ab3-b1de-3371c9a540fa_https://sswalfa.surabaya.go.id/info/detail/rangkaian-pelayanan-surat-pernyataan-belum-menikah-lagi-bagi-jandaduda
|
16 |
+
2025-01-02 14:05:00,442 - INFO - 5bf4bf35-ebc1-418a-a14b-f2c536983b33_https://sswalfa.surabaya.go.id/info/detail/izin-pengumpulan-sumbangan-bencana
|
17 |
+
2025-01-02 14:05:01,488 - INFO - afaa8e05-d2c4-4b4f-96b2-894bd873ac7c_https://sswalfa.surabaya.go.id/info/detail/izin-pemakaian-ruang-terbuka-hijau
|
18 |
+
2025-01-02 14:05:02,011 - INFO - 10a2becc-d166-4a4a-b81f-f8f52e8da3a2_https://sswalfa.surabaya.go.id/info/detail/pengganti-ipt
|
19 |
+
2025-01-02 14:05:02,462 - INFO - 7da6b309-accf-4370-9877-3852fa0eb1ad_https://sswalfa.surabaya.go.id/info/detail/arahan-sistem-drainase
|
20 |
+
2025-01-02 14:05:03,041 - INFO - 5c3904bf-f805-4710-9184-24d5871c0687_https://sswalfa.surabaya.go.id/info/detail/rangkaian-pelayanan-surat-pernyataan-belum-menikah-lagi-bagi-jandaduda
|
21 |
+
2025-01-02 15:10:46,920 - INFO - ad2b962e-ff55-4a90-b33e-f8a79628a0e6_https://sswalfa.surabaya.go.id/info/detail/izin-pengumpulan-sumbangan-bencana
|
22 |
+
2025-01-02 15:10:48,607 - INFO - 4d9d2b38-c5bc-4525-bbb1-3f9fb7974156_https://sswalfa.surabaya.go.id/info/detail/izin-pemakaian-ruang-terbuka-hijau
|
23 |
+
2025-01-02 15:10:49,220 - INFO - 4884a10b-505b-4c8b-9fd8-53e9f8d959d2_https://sswalfa.surabaya.go.id/info/detail/pengganti-ipt
|
24 |
+
2025-01-02 15:10:49,841 - INFO - 4e62d8fc-cde4-4e59-874c-bd5b86b208bb_https://sswalfa.surabaya.go.id/info/detail/arahan-sistem-drainase
|
25 |
+
2025-01-02 15:10:50,745 - INFO - e6e37e7f-525d-435c-b860-58f719995032_https://sswalfa.surabaya.go.id/info/detail/rangkaian-pelayanan-surat-pernyataan-belum-menikah-lagi-bagi-jandaduda
|
26 |
+
2025-01-02 15:12:11,852 - INFO - 7b8f7a8a-b10a-4d2b-b8af-33d871c6883f_https://sswalfa.surabaya.go.id/info/detail/izin-pengumpulan-sumbangan-bencana
|
27 |
+
2025-01-02 15:12:12,247 - INFO - 8d6d7eed-cf50-4dd0-9196-b2b04df9aa25_https://sswalfa.surabaya.go.id/info/detail/izin-pemakaian-ruang-terbuka-hijau
|
28 |
+
2025-01-02 15:12:12,789 - INFO - 2f0997a8-26e4-4459-95d1-f022b75058cc_https://sswalfa.surabaya.go.id/info/detail/pengganti-ipt
|
29 |
+
2025-01-02 15:12:13,822 - INFO - 73b52f33-9dbf-47a6-8fd6-7c70b0839265_https://sswalfa.surabaya.go.id/info/detail/arahan-sistem-drainase
|
30 |
+
2025-01-02 15:12:14,609 - INFO - 6bf5a433-637f-480a-b801-cc7a66f92e71_https://sswalfa.surabaya.go.id/info/detail/rangkaian-pelayanan-surat-pernyataan-belum-menikah-lagi-bagi-jandaduda
|
31 |
+
2025-01-07 14:14:02,625 - INFO - 363bdd80-43d5-40fe-84b6-a2e89d58e1cf_https://sswalfa.surabaya.go.id/info/detail/izin-pengumpulan-sumbangan-bencana
|
32 |
+
2025-01-07 14:14:04,956 - INFO - 319b2118-5c37-47e9-a15a-56a1ba28f533_https://sswalfa.surabaya.go.id/info/detail/izin-pemakaian-ruang-terbuka-hijau
|
33 |
+
2025-01-07 14:14:05,658 - INFO - 5ce111cb-2cca-4f16-8712-19adf801193d_https://sswalfa.surabaya.go.id/info/detail/pengganti-ipt
|
34 |
+
2025-01-07 14:14:06,171 - INFO - d2688d0d-c09a-427d-97b2-5a6073ef9c06_https://sswalfa.surabaya.go.id/info/detail/arahan-sistem-drainase
|
35 |
+
2025-01-07 14:14:06,767 - INFO - dfa4ed93-a644-4431-81a3-3916924df457_https://sswalfa.surabaya.go.id/info/detail/rangkaian-pelayanan-surat-pernyataan-belum-menikah-lagi-bagi-jandaduda
|
36 |
+
2025-01-07 14:18:34,502 - INFO - 9468b228-0fcc-4942-9a0c-559253683f5d_https://sswalfa.surabaya.go.id/info/detail/izin-pengumpulan-sumbangan-bencana
|
37 |
+
2025-01-07 14:18:36,034 - INFO - b390676d-9e05-4e4e-8018-815265d44cba_https://sswalfa.surabaya.go.id/info/detail/izin-pemakaian-ruang-terbuka-hijau
|
38 |
+
2025-01-07 14:18:37,236 - INFO - f20259fd-f923-4c0c-9cf0-956a8f7c438e_https://sswalfa.surabaya.go.id/info/detail/pengganti-ipt
|
39 |
+
2025-01-07 14:18:40,388 - INFO - ad6cbcf3-9662-48e0-88d8-6e4eca796842_https://sswalfa.surabaya.go.id/info/detail/arahan-sistem-drainase
|
40 |
+
2025-01-07 14:18:41,380 - INFO - b4df84cf-55f5-46d2-b9cb-f8039fb102e7_https://sswalfa.surabaya.go.id/info/detail/rangkaian-pelayanan-surat-pernyataan-belum-menikah-lagi-bagi-jandaduda
|
41 |
+
2025-02-12 12:58:48,544 - INFO - a3d8ff96-c21b-46ae-a6f5-d3d7b9952e01_https://sswalfa.surabaya.go.id/info/detail/izin-pengumpulan-sumbangan-bencana
|
42 |
+
2025-02-12 12:58:49,147 - INFO - 9100ac6e-2da9-4b23-8560-d0e0f2129100_https://sswalfa.surabaya.go.id/info/detail/izin-pemakaian-ruang-terbuka-hijau
|
43 |
+
2025-02-12 12:58:49,574 - INFO - d8c6373e-2de0-4c22-bb4f-394a66dcf397_https://sswalfa.surabaya.go.id/info/detail/pengganti-ipt
|
44 |
+
2025-02-12 12:58:50,396 - INFO - 67e0bd19-4dca-4666-ac82-2c161482df43_https://sswalfa.surabaya.go.id/info/detail/arahan-sistem-drainase
|
45 |
+
2025-02-12 12:58:50,966 - INFO - 37c33e40-db31-430d-9e80-5062fd0c5b6a_https://sswalfa.surabaya.go.id/info/detail/rangkaian-pelayanan-surat-pernyataan-belum-menikah-lagi-bagi-jandaduda
|
46 |
+
2025-02-12 13:03:18,154 - INFO - f6aa8d0a-ea7d-46ef-92f5-39506ecd439c_https://sswalfa.surabaya.go.id/info/detail/izin-pengumpulan-sumbangan-bencana
|
47 |
+
2025-02-12 13:03:18,609 - INFO - 7ebd203f-717c-43e0-90b3-d8de87207c5c_https://sswalfa.surabaya.go.id/info/detail/izin-pemakaian-ruang-terbuka-hijau
|
48 |
+
2025-02-12 13:03:19,892 - INFO - 8410df14-2343-49c5-b810-e9c974d3a1b4_https://sswalfa.surabaya.go.id/info/detail/pengganti-ipt
|
49 |
+
2025-02-12 13:03:24,692 - INFO - dc571c48-21ec-4cc7-a845-cc89254f82bb_https://sswalfa.surabaya.go.id/info/detail/arahan-sistem-drainase
|
50 |
+
2025-02-12 13:03:27,569 - INFO - dd340448-b640-4ffa-8735-8b984bde825f_https://sswalfa.surabaya.go.id/info/detail/rangkaian-pelayanan-surat-pernyataan-belum-menikah-lagi-bagi-jandaduda
|
51 |
+
2025-02-12 13:07:30,320 - INFO - e162050f-e78d-424b-94c1-67225d392763_https://sswalfa.surabaya.go.id/info/detail/izin-pengumpulan-sumbangan-bencana
|
52 |
+
2025-02-12 13:07:30,753 - INFO - 7d64ed75-53a7-41c7-9b64-5767f95e780a_https://sswalfa.surabaya.go.id/info/detail/izin-pemakaian-ruang-terbuka-hijau
|
53 |
+
2025-02-12 13:07:44,452 - INFO - a9ccda4f-470a-4d0b-b6b1-2a993a30b62a_https://sswalfa.surabaya.go.id/info/detail/pengganti-ipt
|
54 |
+
2025-02-12 13:07:49,413 - INFO - 6cec7f22-f829-4ebc-a4e3-fcf07d12e264_https://sswalfa.surabaya.go.id/info/detail/arahan-sistem-drainase
|
55 |
+
2025-02-12 13:07:49,730 - INFO - ab810981-4182-4b53-9b2e-de0423980e64_https://sswalfa.surabaya.go.id/info/detail/rangkaian-pelayanan-surat-pernyataan-belum-menikah-lagi-bagi-jandaduda
|