feat: generate dumb web page from input
This commit is contained in:
@@ -1,26 +1,9 @@
|
|||||||
// take in web source, parse primary actions and action text
|
|
||||||
|
|
||||||
// GOAL: lower cognitive load
|
|
||||||
// phases:
|
|
||||||
// a. generate a list of <a> tags, and <button> tags
|
|
||||||
// b. generate a summary of what activity I'm doing (e.g. browsing, reading blog, etc) - max 5 words
|
|
||||||
// c. generate new html with the dumbed down version of the website, without any garbage
|
|
||||||
|
|
||||||
/// e.g. could even be google.com or facebook or anything
|
|
||||||
|
|
||||||
// either
|
|
||||||
// 1. generate a special keypad for the current website
|
|
||||||
// 2. create a new webpage for minimalists
|
|
||||||
|
|
||||||
// We can hit our llama server (hosted in asus) and run a pipeline of requests to
|
|
||||||
// 1. return structured list of items that are important
|
|
||||||
// 2. Generate a new webpage with key actions (using tailwind and ion-icons)
|
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"errors"
|
||||||
"golang.org/x/net/html"
|
"golang.org/x/net/html"
|
||||||
"golang.org/x/net/html/atom"
|
"golang.org/x/net/html/atom"
|
||||||
"io"
|
"io"
|
||||||
@@ -28,8 +11,25 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"encoding/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type AiMessage struct {
|
||||||
|
Role string `json:"role"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
}
|
||||||
|
type AiRequest struct {
|
||||||
|
Messages []AiMessage `json:"messages"`
|
||||||
|
}
|
||||||
|
type AiChoice struct {
|
||||||
|
Message AiMessage `json:"message"`
|
||||||
|
}
|
||||||
|
type AiResponse struct {
|
||||||
|
Choices []AiChoice `json:"choices"`
|
||||||
|
}
|
||||||
|
|
||||||
|
const llamaServerUrl = "http://asus:5050/v1/chat/completions"
|
||||||
|
|
||||||
type Action struct {
|
type Action struct {
|
||||||
Node *html.Node
|
Node *html.Node
|
||||||
Href string
|
Href string
|
||||||
@@ -54,11 +54,74 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bodyContents := string(body)
|
bodyContents := string(body)
|
||||||
|
actionsOutput, err := generateActionsOutput(bodyContents, website)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.WriteFile("result.html", []byte(actionsOutput), fs.ModeAppend)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dumbWebOutput, err := generateDumbOutput(bodyContents)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.WriteFile("result2.html", []byte(dumbWebOutput), fs.ModeAppend)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateDumbOutput(bodyContents string) (string, error) {
|
||||||
|
request := AiRequest{
|
||||||
|
Messages: []AiMessage{
|
||||||
|
{
|
||||||
|
Role: "developer",
|
||||||
|
Content: "Your goal is to convert given html content into a simplistic version of the web page provided. This means it should look so essentialist and use tailwind and simple components without any bloat of the original provided content. Only return ready to use HTML.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Role: "user",
|
||||||
|
Content: bodyContents,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
data, err := json.Marshal(request)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
responseData, err := http.Post(llamaServerUrl, "application/json", bytes.NewBuffer(data))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer responseData.Body.Close()
|
||||||
|
responseBody, err := io.ReadAll(responseData.Body)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var response AiResponse
|
||||||
|
err = json.Unmarshal(responseBody, &response)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(response.Choices) == 0 {
|
||||||
|
return "", errors.New("no choices in response from ai server")
|
||||||
|
}
|
||||||
|
|
||||||
|
outputHtml := response.Choices[0].Message.Content
|
||||||
|
fmt.Printf("Here is the result html: %s\n", outputHtml)
|
||||||
|
return outputHtml, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateActionsOutput(bodyContents string, website string) (string, error) {
|
||||||
// parse the specific <a> tags with html stdlib and button
|
// parse the specific <a> tags with html stdlib and button
|
||||||
doc, err := html.Parse(strings.NewReader(bodyContents))
|
doc, err := html.Parse(strings.NewReader(bodyContents))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the descendants that are <a>, find hrefs
|
// find the descendants that are <a>, find hrefs
|
||||||
@@ -104,12 +167,7 @@ func main() {
|
|||||||
output += `</a>`
|
output += `</a>`
|
||||||
}
|
}
|
||||||
output += `</div></html>`
|
output += `</div></html>`
|
||||||
fmt.Printf("output: %s", output)
|
return output, nil
|
||||||
|
|
||||||
err = os.WriteFile("result.html", []byte(output), fs.ModeAppend)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Traverse all children of node until Data is of type text
|
// Traverse all children of node until Data is of type text
|
||||||
|
|||||||
Reference in New Issue
Block a user