File size: 5,616 Bytes
59d7151
36b4c92
 
59d7151
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36b4c92
59d7151
 
 
 
 
 
 
 
 
 
 
36b4c92
 
59d7151
 
 
 
 
 
36b4c92
59d7151
 
 
 
 
 
 
 
 
 
36b4c92
 
c3ef9a9
59d7151
c3ef9a9
 
36b4c92
c3ef9a9
 
36b4c92
c3ef9a9
 
 
 
36b4c92
 
 
 
 
 
0935ca1
36b4c92
0935ca1
 
 
36b4c92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59d7151
 
 
 
 
 
 
 
 
 
 
 
 
36b4c92
59d7151
 
 
 
36b4c92
 
59d7151
 
 
 
 
 
c3ef9a9
 
59d7151
 
 
36b4c92
59d7151
36b4c92
59d7151
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import os
import re
from bs4 import BeautifulSoup
import getpass
from quart import Quart, request
from prompts import *
from langchain_openai import ChatOpenAI
from typing_extensions import TypedDict
from typing import Annotated
from langgraph.graph.message import add_messages
from typing import List, Tuple, Annotated, TypedDict, Dict
import operator
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field
import aiohttp
import json
from typing import Literal
from langgraph.graph import StateGraph
import asyncio
from sugar import timeit
from config import load_config_to_env
from graph_base import Plan, GraphState

load_config_to_env()

config = {"recursion_limit": 500}
model = ChatOpenAI(
    model="gpt-4o",
    temperature=0
)
SMODIN_HEADERS = {
    "Host": "api.smodin.io",
    "X-Api-Key": os.environ.get("SMODIN_API_KEY"), "accept": "application/json",
    "content-type": "application/json"
}

absract_planner = absract_plan_prompt | model.with_structured_output(Plan)
# pre_planner = pre_plan_prompt | model.with_structured_output(Plan)
designer_model = designer_prompt | model
no_conclusion_model = designer_prompt | model


async def abstract_plan_step(state: GraphState):
    abstract = await absract_planner.ainvoke({"messages": [("user", state["input"])]})
    return {"plan": abstract.steps}


async def deliver(state: GraphState):
    i = state["time"]
    messages = state["plan"]
    return {"messages": [messages[i]]}


async def designer(state: GraphState):
    messages = []
    messages.append(state["messages"][-1])
    response = await designer_model.ainvoke({"messages": [("user", f"Previous history{messages[-2]},Outline of this section{messages[-1]}")]})
    response = response.content.replace('<h2>Introduction: ', '')


    Introduction_title_pattern = r'<h2>Introduction:.*?</h2>|<h2>Introduction</h2>'
    conclusion_pattern = re.compile(r'^\s*<h2>Conclusion</h2>', re.IGNORECASE)

    response = re.sub(Introduction_title_pattern, '', response)
    if not conclusion_pattern.match(response):
        pattern1 = r'\b(<p>Overall|<p>Ultimately).*?</p>'
        pattern2 = re.compile(r'<h3>Conclusion.*?</p>', re.IGNORECASE | re.DOTALL)
        response = re.sub(pattern1, '', response).strip()
        response = re.sub(pattern2, '', response).strip()

    soup = BeautifulSoup(response, 'html.parser')
    paragraphs = soup.find_all('p')

    for p in paragraphs:
        original_text = p.get_text()
        payload = {"language": "en",
                   "text": original_text,
                   "strength": 4,
                   }
        async with aiohttp.ClientSession() as session:
            async with session.post(os.environ.get("SMODIN_BASE_URL"), headers=SMODIN_HEADERS, json=payload) as res:
                if res.status == 201:
                    result = await res.json()
                    rewritten_text = result["rewrites"][0]["rewrite"]
                    #             '''AI去除总结'''
                    #             # rewritten_text = await no_conclusion_model.ainvoke(
                    #             #     {"messages": [("user", rewritten_text["rewrites"][0]["rewrite"])]})

                    p.string = rewritten_text
                #             # if not conclusion_pattern.match(rewritten_text["rewrites"][0]["rewrite"]):
                #             #     rewritten_text = re.sub(pattern, '', rewritten_text["rewrites"][0]["rewrite"], flags=re.IGNORECASE | re.DOTALL)
                else:
                    print("Error:", res.status, await res.text())
                    return {"messages": []}


# def route(state: GraphState) -> Literal["__end__", "action"]:
#     # If there is no function call, then we finish
#     if state["time"] < len(state["plan"]):
#         return "action"
#     else:
#         return "__end__"


def should_end(state: GraphState) -> Literal["__end__", "deliver"]:
    # If there is no function call, then we finish
    if state["time"] < len(state["plan"]):
        return "deliver"
    else:
        return "__end__"


# Define a new graph
workflow = StateGraph(GraphState)
workflow.add_node("abstract_planner", abstract_plan_step)
# workflow.add_node("planner", plan_step)
workflow.add_node("action", designer)
workflow.add_node("deliver", deliver)
workflow.set_entry_point("abstract_planner")
workflow.add_conditional_edges("action", should_end)
workflow.add_edge("abstract_planner", "deliver")
# workflow.add_edge("planner", "deliver")
workflow.add_edge("deliver", "action")
app = workflow.compile()


async def write(inputs):
    messages = ''
    pattern = r"标题:(.*?)(?=,)"
    messages += re.search(pattern, inputs["input"])
    async for event in app.astream(inputs, config=config):
        for k, v in event.items():
            if k == "action":
                # messages = messages.replace('\n\n', '\n')
                messages += v["messages"][0]
                # messages += '\n\n'
                # print(v["messages"])
    return messages


if __name__ == "__main__":
    def get_user_input():
        # title = input("请输入标题: ")
        title = "iPhone"
        # core_keywords = input("请输入核心关键词: ")
        core_keywords = "Apple"
        # related_keywords = input("请输入相关关键词: ")
        related_keywords = "Jobs"
        inputs = {
            "time": 0,
            "input": f"标题:{title},核心关键词:{core_keywords},相关关键词:{related_keywords}"
        }
        return inputs

    result = asyncio.run(write(get_user_input()))
    print(result)