chore: move /agent to /apps/agent

This commit is contained in:
Acbox
2026-03-06 17:32:12 +08:00
parent 4109a141f9
commit 47a425baf5
23 changed files with 59 additions and 72 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ bin = "./tmp/memoh-server"
args_bin = ["serve"]
include_ext = ["go", "toml"]
include_dir = ["cmd", "internal", "conf"]
exclude_dir = ["tmp", "vendor", "node_modules", "packages", "agent", "docs", "devenv", "docker", "scripts", "db/migrations"]
exclude_dir = ["tmp", "vendor", "node_modules", "packages", "apps", "docs", "devenv", "docker", "scripts", "db/migrations"]
exclude_regex = ["_test\\.go$"]
delay = 1000
stop_on_error = true
+3 -2
View File
@@ -100,7 +100,8 @@ Memoh/
│ ├── storage/ # Storage provider interface (filesystem, container FS)
│ ├── subagent/ # Sub-agent management (CRUD)
│ └── version/ # Build-time version information
├── agent/ # Agent Gateway service (Bun/Elysia)
├── apps/ # Application services
│ └── agent/ # Agent Gateway (Bun/Elysia)
│ └── src/
│ ├── index.ts # Elysia server entry point
│ ├── modules/ # Route modules (chat, stream, trigger)
@@ -213,7 +214,7 @@ Migrations live in `db/migrations/` and follow a dual-update convention:
### Agent Development
- The core agent logic lives in `packages/agent/` (`@memoh/agent`), providing reusable agent streaming, tool execution, and prompt management.
- The Agent Gateway (`agent/`) is a thin Elysia HTTP service that uses `@memoh/agent` for processing.
- The Agent Gateway (`apps/agent/`) is a thin Elysia HTTP service that uses `@memoh/agent` for processing.
- AI model providers (Anthropic, OpenAI, Google) are integrated via Vercel AI SDK.
- Tools (MCP, web search, subagent, skill) are defined in `packages/agent/src/tools/`.
- Prompt templates (system, heartbeat, schedule, subagent) are in `packages/agent/src/prompts/`.
+1
View File
@@ -64,6 +64,7 @@ devenv/ — Dev environment (docker-compose, dev Dockerfiles, app.dev.toml,
docker/ — Production Docker build & runtime (Dockerfiles, entrypoints)
cmd/ — Go application entry points
internal/ — Go backend core code
apps/ — Application services (Agent Gateway, etc.)
agent/ — Agent Gateway (Bun/Elysia)
packages/ — Frontend monorepo (web, ui, sdk, cli, config)
db/ — Database migrations and queries
@@ -6,7 +6,7 @@ import { loadConfig, getBaseUrl as getBaseUrlByConfig } from '@memoh/config'
import { AgentAuthContext, AuthFetcher } from '@memoh/agent'
const configuredPath = process.env.MEMOH_CONFIG_PATH?.trim() || process.env.CONFIG_PATH?.trim()
const configPath = configuredPath && configuredPath.length > 0 ? configuredPath : '../config.toml'
const configPath = configuredPath && configuredPath.length > 0 ? configuredPath : '../../config.toml'
const config = loadConfig(configPath)
export const getBaseUrl = () => {
+1 -1
View File
@@ -104,7 +104,7 @@ services:
agent:
image: oven/bun:1-alpine
container_name: memoh-dev-agent
working_dir: /workspace/agent
working_dir: /workspace/apps/agent
command: ["bun", "run", "--watch", "src/index.ts"]
volumes:
- ..:/workspace
+8 -8
View File
@@ -4,21 +4,21 @@ FROM --platform=$BUILDPLATFORM oven/bun:1 AS builder
WORKDIR /build
# Set up workspace structure so bun can resolve workspace deps (@memoh/config, @memoh/agent)
COPY agent/package.json agent/bun.lock* ./agent/
COPY apps/agent/package.json apps/agent/bun.lock* ./apps/agent/
COPY packages/config/package.json ./packages/config/package.json
COPY packages/agent/package.json ./packages/agent/package.json
# Create root package.json with workspace config
RUN echo '{"name":"@memoh/monorepo","private":true,"workspaces":["agent","packages/*"]}' > package.json
RUN echo '{"name":"@memoh/monorepo","private":true,"workspaces":["apps/*","packages/*"]}' > package.json
RUN cd agent && bun install
RUN cd apps/agent && bun install
# Copy source files
COPY packages/config/ ./packages/config/
COPY packages/agent/ ./packages/agent/
COPY agent/ ./agent/
COPY apps/agent/ ./apps/agent/
RUN cd agent && bun run build
RUN cd apps/agent && bun run build
FROM oven/bun:1-alpine
@@ -26,9 +26,9 @@ WORKDIR /app
RUN apk add --no-cache ca-certificates wget
COPY --from=builder /build/agent/dist /app/dist
COPY --from=builder /build/agent/node_modules /app/node_modules
COPY --from=builder /build/agent/package.json /app/package.json
COPY --from=builder /build/apps/agent/dist /app/dist
COPY --from=builder /build/apps/agent/node_modules /app/node_modules
COPY --from=builder /build/apps/agent/package.json /app/package.json
COPY --from=builder /build/node_modules /node_modules
EXPOSE 8081
+2 -2
View File
@@ -8,7 +8,7 @@ export default [
...vue.configs['flat/recommended'],
{ ignores: ['**/node_modules/**', '**/dist/**', '**/cache/**', 'packages/sdk/src/**'] },
{
files: ['packages/**/*.{js,jsx,ts,tsx}', 'agent/**/*.{js,jsx,ts,tsx}'],
files: ['packages/**/*.{js,jsx,ts,tsx}', 'apps/**/*.{js,jsx,ts,tsx}'],
languageOptions: {
parserOptions: {
ecmaVersion: 2022,
@@ -22,7 +22,7 @@ export default [
},
},
{
files: ['packages/**/*.vue', 'agent/**/*.vue'],
files: ['packages/**/*.vue', 'apps/**/*.vue'],
languageOptions: {
parser: vueParser,
parserOptions: {
+29 -44
View File
@@ -46,23 +46,23 @@ importers:
specifier: ^10.2.0
version: 10.2.0(eslint@9.39.2(jiti@2.6.1))
agent:
apps/agent:
dependencies:
'@elysiajs/bearer':
specifier: ^1.4.2
version: 1.4.2(elysia@1.4.25(@sinclair/typebox@0.34.47)(@types/bun@1.3.9)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3))
version: 1.4.2(elysia@1.4.27(@sinclair/typebox@0.34.47)(@types/bun@1.3.9)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3))
'@elysiajs/cors':
specifier: ^1.4.1
version: 1.4.1(elysia@1.4.25(@sinclair/typebox@0.34.47)(@types/bun@1.3.9)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3))
version: 1.4.1(elysia@1.4.27(@sinclair/typebox@0.34.47)(@types/bun@1.3.9)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3))
'@memoh/agent':
specifier: workspace:*
version: link:../packages/agent
version: link:../../packages/agent
'@memoh/config':
specifier: workspace:*
version: link:../packages/config
version: link:../../packages/config
'@modelcontextprotocol/sdk':
specifier: ^1.25.2
version: 1.25.2(@cfworker/json-schema@4.1.1)(hono@4.11.4)(zod@4.3.5)
version: 1.25.2(@cfworker/json-schema@4.1.1)(hono@4.11.4)(zod@4.3.6)
'@mozilla/readability':
specifier: ^0.6.0
version: 0.6.0
@@ -71,10 +71,10 @@ importers:
version: 5.0.6
ai:
specifier: ^6.0.25
version: 6.0.25(zod@4.3.5)
version: 6.0.25(zod@4.3.6)
elysia:
specifier: latest
version: 1.4.25(@sinclair/typebox@0.34.47)(@types/bun@1.3.9)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3)
version: 1.4.27(@sinclair/typebox@0.34.47)(@types/bun@1.3.9)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3)
toml:
specifier: ^3.0.0
version: 3.0.0
@@ -83,11 +83,11 @@ importers:
version: 7.2.2
zod:
specifier: ^4.3.5
version: 4.3.5
version: 4.3.6
devDependencies:
bun-types:
specifier: latest
version: 1.3.9
version: 1.3.10
docs:
devDependencies:
@@ -2686,6 +2686,9 @@ packages:
engines: {node: '>=18'}
hasBin: true
bun-types@1.3.10:
resolution: {integrity: sha512-tcpfCCl6XWo6nCVnpcVrxQ+9AYN1iqMIzgrSKYMB/fjLtV2eyAVEg7AxQJuCq/26R6HpKWykQXuSOq/21RYcbg==}
bun-types@1.3.9:
resolution: {integrity: sha512-+UBWWOakIP4Tswh0Bt0QD0alpTY8cb5hvgiYeWCMet9YukHbzuruIEeXC2D7nMJPB12kbh8C7XJykSexEqGKJg==}
@@ -3175,8 +3178,8 @@ packages:
electron-to-chromium@1.5.267:
resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==}
elysia@1.4.25:
resolution: {integrity: sha512-liKjavH99Gpzrv9cDil6uYWmPuqESfPFV1FIaFSd3iNqo3y7e29sN43VxFIK8tWWnyi6eDAmi2SZk8hNAMQMyg==}
elysia@1.4.27:
resolution: {integrity: sha512-2UlmNEjPJVA/WZVPYKy+KdsrfFwwNlqSBW1lHz6i2AHc75k7gV4Rhm01kFeotH7PDiHIX2G8X3KnRPc33SGVIg==}
peerDependencies:
'@sinclair/typebox': '>= 0.34.0 < 1'
'@types/bun': '>= 1.2.0'
@@ -5273,13 +5276,6 @@ snapshots:
'@ai-sdk/provider-utils': 4.0.4(zod@4.3.6)
zod: 4.3.6
'@ai-sdk/gateway@3.0.10(zod@4.3.5)':
dependencies:
'@ai-sdk/provider': 3.0.2
'@ai-sdk/provider-utils': 4.0.4(zod@4.3.5)
'@vercel/oidc': 3.1.0
zod: 4.3.5
'@ai-sdk/gateway@3.0.10(zod@4.3.6)':
dependencies:
'@ai-sdk/provider': 3.0.2
@@ -5319,13 +5315,6 @@ snapshots:
eventsource-parser: 3.0.6
zod: 4.3.6
'@ai-sdk/provider-utils@4.0.4(zod@4.3.5)':
dependencies:
'@ai-sdk/provider': 3.0.2
'@standard-schema/spec': 1.1.0
eventsource-parser: 3.0.6
zod: 4.3.5
'@ai-sdk/provider-utils@4.0.4(zod@4.3.6)':
dependencies:
'@ai-sdk/provider': 3.0.2
@@ -5755,13 +5744,13 @@ snapshots:
'@drizzle-team/brocli@0.10.2': {}
'@elysiajs/bearer@1.4.2(elysia@1.4.25(@sinclair/typebox@0.34.47)(@types/bun@1.3.9)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3))':
'@elysiajs/bearer@1.4.2(elysia@1.4.27(@sinclair/typebox@0.34.47)(@types/bun@1.3.9)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3))':
dependencies:
elysia: 1.4.25(@sinclair/typebox@0.34.47)(@types/bun@1.3.9)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3)
elysia: 1.4.27(@sinclair/typebox@0.34.47)(@types/bun@1.3.9)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3)
'@elysiajs/cors@1.4.1(elysia@1.4.25(@sinclair/typebox@0.34.47)(@types/bun@1.3.9)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3))':
'@elysiajs/cors@1.4.1(elysia@1.4.27(@sinclair/typebox@0.34.47)(@types/bun@1.3.9)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3))':
dependencies:
elysia: 1.4.25(@sinclair/typebox@0.34.47)(@types/bun@1.3.9)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3)
elysia: 1.4.27(@sinclair/typebox@0.34.47)(@types/bun@1.3.9)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3)
'@esbuild-kit/core-utils@3.3.2':
dependencies:
@@ -6473,7 +6462,7 @@ snapshots:
'@mixmark-io/domino@2.2.0': {}
'@modelcontextprotocol/sdk@1.25.2(@cfworker/json-schema@4.1.1)(hono@4.11.4)(zod@4.3.5)':
'@modelcontextprotocol/sdk@1.25.2(@cfworker/json-schema@4.1.1)(hono@4.11.4)(zod@4.3.6)':
dependencies:
'@hono/node-server': 1.19.9(hono@4.11.4)
ajv: 8.17.1
@@ -6489,8 +6478,8 @@ snapshots:
json-schema-typed: 8.0.2
pkce-challenge: 5.0.1
raw-body: 3.0.2
zod: 4.3.5
zod-to-json-schema: 3.25.1(zod@4.3.5)
zod: 4.3.6
zod-to-json-schema: 3.25.1(zod@4.3.6)
optionalDependencies:
'@cfworker/json-schema': 4.1.1
transitivePeerDependencies:
@@ -7409,14 +7398,6 @@ snapshots:
agent-base@7.1.4:
optional: true
ai@6.0.25(zod@4.3.5):
dependencies:
'@ai-sdk/gateway': 3.0.10(zod@4.3.5)
'@ai-sdk/provider': 3.0.2
'@ai-sdk/provider-utils': 4.0.4(zod@4.3.5)
'@opentelemetry/api': 1.9.0
zod: 4.3.5
ai@6.0.25(zod@4.3.6):
dependencies:
'@ai-sdk/gateway': 3.0.10(zod@4.3.6)
@@ -7592,6 +7573,10 @@ snapshots:
transitivePeerDependencies:
- magicast
bun-types@1.3.10:
dependencies:
'@types/node': 24.10.4
bun-types@1.3.9:
dependencies:
'@types/node': 24.10.4
@@ -8078,7 +8063,7 @@ snapshots:
electron-to-chromium@1.5.267: {}
elysia@1.4.25(@sinclair/typebox@0.34.47)(@types/bun@1.3.9)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3):
elysia@1.4.27(@sinclair/typebox@0.34.47)(@types/bun@1.3.9)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3):
dependencies:
'@sinclair/typebox': 0.34.47
cookie: 1.1.1
@@ -10240,9 +10225,9 @@ snapshots:
yoctocolors-cjs@2.1.3: {}
zod-to-json-schema@3.25.1(zod@4.3.5):
zod-to-json-schema@3.25.1(zod@4.3.6):
dependencies:
zod: 4.3.5
zod: 4.3.6
zod@3.25.76: {}
+1 -1
View File
@@ -1,7 +1,7 @@
packages:
- 'packages/*'
- 'apps/*'
- 'docs'
- 'agent'
onlyBuiltDependencies:
- sqlite3
+4 -4
View File
@@ -133,7 +133,7 @@ prepare_assets() {
patch_jsdom_style_loader_for_compile
trap 'restore_jsdom_style_loader_patch' RETURN
(
cd "$ROOT_DIR/agent"
cd "$ROOT_DIR/apps/agent"
bun build src/index.ts --compile --target "$bun_compile_target" --outfile "$AGENT_DIR/$agent_bin_name"
)
restore_jsdom_style_loader_patch
@@ -151,9 +151,9 @@ JSDOM_XHR_IMPL_BACKUP=""
patch_jsdom_style_loader_for_compile() {
local css_path css_json
JSDOM_STYLE_RULES_FILE="$(node -e "try{process.stdout.write(require.resolve('jsdom/lib/jsdom/living/helpers/style-rules.js',{paths:['$ROOT_DIR/agent']}))}catch{process.exit(1)}" 2>/dev/null || true)"
css_path="$(node -e "try{process.stdout.write(require.resolve('jsdom/lib/jsdom/browser/default-stylesheet.css',{paths:['$ROOT_DIR/agent']}))}catch{process.exit(1)}" 2>/dev/null || true)"
JSDOM_XHR_IMPL_FILE="$(node -e "try{process.stdout.write(require.resolve('jsdom/lib/jsdom/living/xhr/XMLHttpRequest-impl.js',{paths:['$ROOT_DIR/agent']}))}catch{process.exit(1)}" 2>/dev/null || true)"
JSDOM_STYLE_RULES_FILE="$(node -e "try{process.stdout.write(require.resolve('jsdom/lib/jsdom/living/helpers/style-rules.js',{paths:['$ROOT_DIR/apps/agent']}))}catch{process.exit(1)}" 2>/dev/null || true)"
css_path="$(node -e "try{process.stdout.write(require.resolve('jsdom/lib/jsdom/browser/default-stylesheet.css',{paths:['$ROOT_DIR/apps/agent']}))}catch{process.exit(1)}" 2>/dev/null || true)"
JSDOM_XHR_IMPL_FILE="$(node -e "try{process.stdout.write(require.resolve('jsdom/lib/jsdom/living/xhr/XMLHttpRequest-impl.js',{paths:['$ROOT_DIR/apps/agent']}))}catch{process.exit(1)}" 2>/dev/null || true)"
if [[ -z "$JSDOM_STYLE_RULES_FILE" || -z "$css_path" || -z "$JSDOM_XHR_IMPL_FILE" ]]; then
log "skip jsdom patch (jsdom sources not resolved)"
+1 -1
View File
@@ -15,6 +15,6 @@
"skipDefaultLibCheck": true,
"skipLibCheck": true,
},
"include": ["packages/**/*.ts", "packages/**/*/src/*", "packages/**/*/src/**/*"],
"include": ["packages/**/*.ts", "packages/**/*/src/*", "packages/**/*/src/**/*", "apps/**/*.ts", "apps/**/*/src/*", "apps/**/*/src/**/*"],
"exclude": ["node_modules", "dist"]
}