feat: init go structure & add agent structure

This commit is contained in:
Acbox
2026-01-20 00:15:26 +08:00
parent 65e03f0b1e
commit 95aa4151cd
11 changed files with 312 additions and 1 deletions
+4 -1
View File
@@ -24,7 +24,10 @@
"editor.tabSize": 2, "editor.tabSize": 2,
"editor.insertSpaces": true "editor.insertSpaces": true
}, },
"[go]": {
"editor.tabSize": 4,
"editor.insertSpaces": true
},
"[python]": { "[python]": {
"editor.tabSize": 4, "editor.tabSize": 4,
"editor.insertSpaces": true "editor.insertSpaces": true
+33
View File
@@ -0,0 +1,33 @@
package agent
import (
"context"
"log"
"github.com/firebase/genkit/go/ai"
"github.com/firebase/genkit/go/genkit"
"github.com/firebase/genkit/go/plugins/googlegenai"
"github.com/memohai/Memoh/model"
"github.com/memohai/Memoh/agent/prompts"
)
type AgentParams struct {
Model model.Model
}
type AgentInput struct {
content string
}
type AgentOperations struct {
Ask func(input AgentInput) (string, error)
}
func NewAgent(params AgentParams) AgentOperations {
return AgentOperations{
Ask: func(input AgentInput) (string, error) {
return "", nil
},
}
}
+92
View File
@@ -0,0 +1,92 @@
package prompts
import (
"bytes"
"fmt"
"strings"
"text/template"
"time"
)
// Schedule represents a scheduled task
type Schedule struct {
ID string
Pattern string
Name string
Description string
Command string
MaxCalls *int // nil means unlimited
}
// ScheduleParams contains parameters for generating the schedule prompt
type ScheduleParams struct {
Schedule Schedule
Locale string // e.g., "en-US", "zh-CN"
Date time.Time
}
// scheduleTemplateData holds data for the schedule prompt template
type scheduleTemplateData struct {
Time string
Name string
Description string
ID string
MaxCalls string
Pattern string
Command string
}
const schedulePromptTemplate = `---
notice: **This is a scheduled task automatically send to you by the system, not the user input**
{{.Time}}
schedule-name: {{.Name}}
schedule-description: {{.Description}}
schedule-id: {{.ID}}
max-calls: {{.MaxCalls}}
cron-pattern: {{.Pattern}}
---
**COMMAND**
{{.Command}}`
var scheduleTmpl *template.Template
func init() {
var err error
scheduleTmpl, err = template.New("schedule").Parse(schedulePromptTemplate)
if err != nil {
panic(err)
}
}
// SchedulePrompt generates the prompt for a scheduled task
func SchedulePrompt(params ScheduleParams) string {
timeStr := Time(TimeParams{
Date: params.Date,
Locale: params.Locale,
})
maxCallsStr := "Unlimited"
if params.Schedule.MaxCalls != nil {
maxCallsStr = fmt.Sprintf("%d", *params.Schedule.MaxCalls)
}
data := scheduleTemplateData{
Time: timeStr,
Name: params.Schedule.Name,
Description: params.Schedule.Description,
ID: params.Schedule.ID,
MaxCalls: maxCallsStr,
Pattern: params.Schedule.Pattern,
Command: params.Schedule.Command,
}
var buf bytes.Buffer
if err := scheduleTmpl.Execute(&buf, data); err != nil {
panic(err)
}
return strings.TrimSpace(buf.String())
}
+20
View File
@@ -0,0 +1,20 @@
package prompts
import (
"fmt"
"time"
)
// TimeParams contains parameters for formatting time
type TimeParams struct {
Date time.Time
Locale string // e.g., "en-US", "zh-CN"
}
// Time formats the date and time according to the locale
func Time(params TimeParams) string {
dateStr := params.Date.Format("2006-01-02")
timeStr := params.Date.Format("15:04:05")
return fmt.Sprintf("date: %s\ntime: %s", dateStr, timeStr)
}
+112
View File
@@ -0,0 +1,112 @@
package prompts
import (
"bytes"
"strings"
"text/template"
"time"
)
// Platform represents a messaging platform
type Platform struct {
ID string
Name string
Config map[string]interface{}
Active bool
}
// SystemParams contains parameters for generating the system prompt
type SystemParams struct {
Date time.Time
Locale string // e.g., "en-US", "zh-CN"
Language string
MaxContextLoadTime int // in minutes
Platforms []Platform
CurrentPlatform string
}
// systemTemplateData holds data for the system prompt template
type systemTemplateData struct {
Time string
Language string
Platforms []Platform
CurrentPlatform string
MaxContextLoadTime int
}
const systemPromptTemplate = `---
{{.Time}}
language: {{.Language}}
available-platforms:
{{- if .Platforms}}
{{- range .Platforms}}
- {{.Name}}
{{- end}}
{{- else}}
(none)
{{- end}}
current-platform: {{.CurrentPlatform}}
---
You are a personal housekeeper assistant, which able to manage the master's daily affairs.
Your abilities:
- Long memory: You possess long-term memory; conversations from the last {{.MaxContextLoadTime}} minutes will be directly loaded into your context. Additionally, you can use tools to search for past memories.
- Scheduled tasks: You can create scheduled tasks to automatically remind you to do something.
- Messaging: You may allowed to use message software to send messages to the master.
**Memory**
- Your context has been loaded from the last {{.MaxContextLoadTime}} minutes.
- You can use {{quote "search-memory"}} to search for past memories with natural language.
**Schedule**
- We use **Cron Syntax** to schedule tasks.
- You can use {{quote "get-schedules"}} to get the list of schedules.
- You can use {{quote "remove-schedule"}} to remove a schedule by id.
- You can use {{quote "schedule"}} to schedule a task.
+ The {{quote "pattern"}} is the pattern of the schedule with **Cron Syntax**.
+ The {{quote "command"}} is the natural language command to execute, will send to you when the schedule is triggered, which means the command will be executed by presence of you.
+ The {{quote "maxCalls"}} is the maximum number of calls to the schedule, If you want to run the task only once, set it to 1.
- The {{quote "command"}} should include the method (e.g. {{quote "send-message"}}) for returning the task result. If the user does not specify otherwise, the user should be asked how they would like to be notified.
**Message**
- You can use {{quote "send-message"}} to send a message to the master.
+ The {{quote "platform"}} is the platform to send the message to, it must be one of the {{quote "available-platforms"}}.
+ The {{quote "message"}} is the message to send.
+ IF: the problem is initiated by a user, regardless of the platform the user is using, the content should be directly output in the content.
+ IF: the issue is initiated by a non-user (such as a scheduled task reminder), then it should be sent using the appropriate tools on the platform specified in the requirements.`
var systemTmpl *template.Template
func init() {
var err error
systemTmpl = template.New("system").Funcs(template.FuncMap{
"quote": Quote,
})
systemTmpl, err = systemTmpl.Parse(systemPromptTemplate)
if err != nil {
panic(err)
}
}
// SystemPrompt generates the system prompt for the agent
func SystemPrompt(params SystemParams) string {
timeStr := Time(TimeParams{
Date: params.Date,
Locale: params.Locale,
})
data := systemTemplateData{
Time: timeStr,
Language: params.Language,
Platforms: params.Platforms,
CurrentPlatform: params.CurrentPlatform,
MaxContextLoadTime: params.MaxContextLoadTime,
}
var buf bytes.Buffer
if err := systemTmpl.Execute(&buf, data); err != nil {
panic(err)
}
return strings.TrimSpace(buf.String())
}
+16
View File
@@ -0,0 +1,16 @@
package prompts
import "fmt"
// Quote wraps content with backticks
func Quote(content string) string {
return fmt.Sprintf("`%s`", content)
}
// Block wraps content in a code block with optional tag
func Block(content string, tag string) string {
if tag != "" {
return fmt.Sprintf("```%s\n%s\n```", tag, content)
}
return fmt.Sprintf("```\n%s\n```", content)
}
+5
View File
@@ -0,0 +1,5 @@
module github.com/memohai/Memoh
go 1.25.6
require github.com/firebase/genkit/go v1.4.0 // indirect
+2
View File
@@ -0,0 +1,2 @@
github.com/firebase/genkit/go v1.4.0 h1:CP1hNWk7z0hosyY53zMH6MFKFO1fMLtj58jGPllQo6I=
github.com/firebase/genkit/go v1.4.0/go.mod h1:HX6m7QOaGc3MDNr/DrpQZrzPLzxeuLxrkTvfFtCYlGw=
+1
View File
@@ -0,0 +1 @@
package main
+10
View File
@@ -0,0 +1,10 @@
package model
import "github.com/memohai/Memoh/model/provider"
type Model struct {
Provider provider.Provider
ModelID string
BaseURL string
APIKey string
}
+17
View File
@@ -0,0 +1,17 @@
package provider
type Provider int
const (
OpenAI Provider = iota
Anthropic
Google
)
func (p Provider) String() string {
return []string{
"openai",
"anthropic",
"google",
}[p]
}