updated jules code
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# Jules
|
# Jules
|
||||||
|
|
||||||
Jules is a cross-platform AI secretary with memory. It connects to Telegram, email, Viber, Discord, and MAX as a single persona — remembers facts about users, sets reminders, messages their contacts, and nudges them toward better habits.
|
Jules is a cross-platform AI secretary with memory. It connects to Telegram and email as a single persona — remembers facts, sets reminders, messages contacts, and nudges toward better habits.
|
||||||
|
|
||||||
## How it works
|
## How it works
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@ Every chat implements a minimal interface (`Send` / `Receive`). The engine pulls
|
|||||||
|
|
||||||
## Stack
|
## Stack
|
||||||
|
|
||||||
Go, PostgreSQL, DeepSeek (reasoner model), Brave Search API, production-grade test coverage (100% across all core packages).
|
Go, PostgreSQL, DeepSeek (reasoner model), Telegram API, Email SMTP daemon, production-grade test coverage (100% across all core packages).
|
||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -13,9 +13,9 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/chat"
|
|
||||||
"github.com/emersion/go-imap/v2"
|
"github.com/emersion/go-imap/v2"
|
||||||
"github.com/emersion/go-imap/v2/imapclient"
|
"github.com/emersion/go-imap/v2/imapclient"
|
||||||
|
"m8sh.su/d/jules/chat"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/chat"
|
|
||||||
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
||||||
"golang.org/x/net/proxy"
|
"golang.org/x/net/proxy"
|
||||||
|
"m8sh.su/d/jules/chat"
|
||||||
)
|
)
|
||||||
|
|
||||||
const BaseURL = tgbotapi.APIEndpoint
|
const BaseURL = tgbotapi.APIEndpoint
|
||||||
|
|||||||
+8
-8
@@ -8,14 +8,14 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/chat"
|
"m8sh.su/d/jules/chat"
|
||||||
"github.com/d1nch8g/jules/chat/email"
|
"m8sh.su/d/jules/chat/email"
|
||||||
"github.com/d1nch8g/jules/chat/telegram"
|
"m8sh.su/d/jules/chat/telegram"
|
||||||
"github.com/d1nch8g/jules/config"
|
"m8sh.su/d/jules/config"
|
||||||
"github.com/d1nch8g/jules/database/postgres"
|
"m8sh.su/d/jules/database/postgres"
|
||||||
"github.com/d1nch8g/jules/engine"
|
"m8sh.su/d/jules/engine"
|
||||||
"github.com/d1nch8g/jules/llm/deepseek"
|
"m8sh.su/d/jules/llm/deepseek"
|
||||||
"github.com/d1nch8g/jules/search/brave"
|
"m8sh.su/d/jules/search/brave"
|
||||||
|
|
||||||
"github.com/lmittmann/tint"
|
"github.com/lmittmann/tint"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/database"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"m8sh.su/d/jules/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Actions struct {
|
type Actions struct {
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/database"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/lib/pq"
|
"github.com/lib/pq"
|
||||||
|
"m8sh.su/d/jules/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Chats struct {
|
type Chats struct {
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/DATA-DOG/go-sqlmock"
|
"github.com/DATA-DOG/go-sqlmock"
|
||||||
"github.com/d1nch8g/jules/database"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"m8sh.su/d/jules/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestChats_Attach(t *testing.T) {
|
func TestChats_Attach(t *testing.T) {
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/database"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/lib/pq"
|
"github.com/lib/pq"
|
||||||
|
"m8sh.su/d/jules/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Contacts struct {
|
type Contacts struct {
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/DATA-DOG/go-sqlmock"
|
"github.com/DATA-DOG/go-sqlmock"
|
||||||
"github.com/d1nch8g/jules/database"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"m8sh.su/d/jules/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestContacts_Add(t *testing.T) {
|
func TestContacts_Add(t *testing.T) {
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/database"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"m8sh.su/d/jules/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Facts struct {
|
type Facts struct {
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/DATA-DOG/go-sqlmock"
|
"github.com/DATA-DOG/go-sqlmock"
|
||||||
"github.com/d1nch8g/jules/database"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"m8sh.su/d/jules/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFacts_Add(t *testing.T) {
|
func TestFacts_Add(t *testing.T) {
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/database"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"m8sh.su/d/jules/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Notifications struct {
|
type Notifications struct {
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/DATA-DOG/go-sqlmock"
|
"github.com/DATA-DOG/go-sqlmock"
|
||||||
"github.com/d1nch8g/jules/database"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"m8sh.su/d/jules/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNotifications_ConcurrentPop(t *testing.T) {
|
func TestNotifications_ConcurrentPop(t *testing.T) {
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/database"
|
|
||||||
_ "github.com/lib/pq" // postgres
|
_ "github.com/lib/pq" // postgres
|
||||||
|
"m8sh.su/d/jules/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DB struct {
|
type DB struct {
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/database"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"m8sh.su/d/jules/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Users struct {
|
type Users struct {
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/database"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"m8sh.su/d/jules/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
func setupTestUser(t *testing.T, db *DB) *database.User {
|
func setupTestUser(t *testing.T, db *DB) *database.User {
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/chat"
|
|
||||||
"github.com/d1nch8g/jules/database"
|
|
||||||
"github.com/d1nch8g/jules/engine/timeconv"
|
|
||||||
"github.com/d1nch8g/jules/engine/user"
|
|
||||||
"github.com/d1nch8g/jules/search"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
|
"m8sh.su/d/jules/chat"
|
||||||
|
"m8sh.su/d/jules/database"
|
||||||
|
"m8sh.su/d/jules/engine/timeconv"
|
||||||
|
"m8sh.su/d/jules/engine/user"
|
||||||
|
"m8sh.su/d/jules/search"
|
||||||
)
|
)
|
||||||
|
|
||||||
const ActionsPromptPart = `=== AVAILABLE ACTIONS ===
|
const ActionsPromptPart = `=== AVAILABLE ACTIONS ===
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/chat"
|
|
||||||
"github.com/d1nch8g/jules/database"
|
|
||||||
"github.com/d1nch8g/jules/engine/user"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"m8sh.su/d/jules/chat"
|
||||||
|
"m8sh.su/d/jules/database"
|
||||||
|
"m8sh.su/d/jules/engine/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TestDB struct {
|
type TestDB struct {
|
||||||
|
|||||||
+4
-4
@@ -8,10 +8,10 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/chat"
|
"m8sh.su/d/jules/chat"
|
||||||
"github.com/d1nch8g/jules/database"
|
"m8sh.su/d/jules/database"
|
||||||
"github.com/d1nch8g/jules/llm"
|
"m8sh.su/d/jules/llm"
|
||||||
"github.com/d1nch8g/jules/search"
|
"m8sh.su/d/jules/search"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Parameters struct {
|
type Parameters struct {
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/chat"
|
|
||||||
"github.com/d1nch8g/jules/database"
|
|
||||||
"github.com/d1nch8g/jules/llm"
|
|
||||||
"github.com/d1nch8g/jules/search"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"m8sh.su/d/jules/chat"
|
||||||
|
"m8sh.su/d/jules/database"
|
||||||
|
"m8sh.su/d/jules/llm"
|
||||||
|
"m8sh.su/d/jules/search"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mockChat struct {
|
type mockChat struct {
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/engine/actions"
|
"m8sh.su/d/jules/engine/actions"
|
||||||
"github.com/d1nch8g/jules/engine/timeconv"
|
"m8sh.su/d/jules/engine/timeconv"
|
||||||
"github.com/d1nch8g/jules/engine/user"
|
"m8sh.su/d/jules/engine/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/database"
|
|
||||||
"github.com/d1nch8g/jules/engine/actions"
|
|
||||||
"github.com/d1nch8g/jules/engine/user"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"m8sh.su/d/jules/database"
|
||||||
|
"m8sh.su/d/jules/engine/actions"
|
||||||
|
"m8sh.su/d/jules/engine/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newTestUser() *user.User {
|
func newTestUser() *user.User {
|
||||||
|
|||||||
+7
-7
@@ -3,13 +3,13 @@ package engine
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/chat"
|
"m8sh.su/d/jules/chat"
|
||||||
"github.com/d1nch8g/jules/database"
|
"m8sh.su/d/jules/database"
|
||||||
"github.com/d1nch8g/jules/engine/actions"
|
"m8sh.su/d/jules/engine/actions"
|
||||||
"github.com/d1nch8g/jules/engine/hooks"
|
"m8sh.su/d/jules/engine/hooks"
|
||||||
"github.com/d1nch8g/jules/engine/prompt"
|
"m8sh.su/d/jules/engine/prompt"
|
||||||
"github.com/d1nch8g/jules/engine/trace"
|
"m8sh.su/d/jules/engine/trace"
|
||||||
"github.com/d1nch8g/jules/engine/user"
|
"m8sh.su/d/jules/engine/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (e *Engine) defaultProcessMessage(ctx context.Context, msg chat.Message) {
|
func (e *Engine) defaultProcessMessage(ctx context.Context, msg chat.Message) {
|
||||||
|
|||||||
@@ -8,15 +8,15 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/chat"
|
|
||||||
"github.com/d1nch8g/jules/database"
|
|
||||||
"github.com/d1nch8g/jules/engine/actions"
|
|
||||||
"github.com/d1nch8g/jules/engine/trace"
|
|
||||||
"github.com/d1nch8g/jules/engine/user"
|
|
||||||
"github.com/d1nch8g/jules/llm"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"m8sh.su/d/jules/chat"
|
||||||
|
"m8sh.su/d/jules/database"
|
||||||
|
"m8sh.su/d/jules/engine/actions"
|
||||||
|
"m8sh.su/d/jules/engine/trace"
|
||||||
|
"m8sh.su/d/jules/engine/user"
|
||||||
|
"m8sh.su/d/jules/llm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TestDB struct {
|
type TestDB struct {
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/chat"
|
"m8sh.su/d/jules/chat"
|
||||||
"github.com/d1nch8g/jules/database"
|
"m8sh.su/d/jules/database"
|
||||||
"github.com/d1nch8g/jules/engine/actions"
|
"m8sh.su/d/jules/engine/actions"
|
||||||
"github.com/d1nch8g/jules/engine/timeconv"
|
"m8sh.su/d/jules/engine/timeconv"
|
||||||
"github.com/d1nch8g/jules/engine/user"
|
"m8sh.su/d/jules/engine/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RepeatOn string
|
type RepeatOn string
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/database"
|
|
||||||
"github.com/d1nch8g/jules/engine/user"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"m8sh.su/d/jules/database"
|
||||||
|
"m8sh.su/d/jules/engine/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newTestUser() *user.User {
|
func newTestUser() *user.User {
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import (
|
|||||||
"slices"
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/chat"
|
"m8sh.su/d/jules/chat"
|
||||||
"github.com/d1nch8g/jules/database"
|
"m8sh.su/d/jules/database"
|
||||||
"github.com/d1nch8g/jules/engine/actions"
|
"m8sh.su/d/jules/engine/actions"
|
||||||
"github.com/d1nch8g/jules/engine/user"
|
"m8sh.su/d/jules/engine/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Span struct {
|
type Span struct {
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ import (
|
|||||||
"log/slog"
|
"log/slog"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/chat"
|
|
||||||
"github.com/d1nch8g/jules/database"
|
|
||||||
"github.com/d1nch8g/jules/engine/actions"
|
|
||||||
"github.com/d1nch8g/jules/engine/user"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"m8sh.su/d/jules/chat"
|
||||||
|
"m8sh.su/d/jules/database"
|
||||||
|
"m8sh.su/d/jules/engine/actions"
|
||||||
|
"m8sh.su/d/jules/engine/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
func captureLog(fn func()) string {
|
func captureLog(fn func()) string {
|
||||||
|
|||||||
+2
-2
@@ -6,9 +6,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/chat"
|
|
||||||
"github.com/d1nch8g/jules/database"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"m8sh.su/d/jules/chat"
|
||||||
|
"m8sh.su/d/jules/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/d1nch8g/jules/chat"
|
|
||||||
"github.com/d1nch8g/jules/database"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"m8sh.su/d/jules/chat"
|
||||||
|
"m8sh.su/d/jules/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mockDB struct {
|
type mockDB struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user