Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions apps/aevatar-console-web/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# Keep these in sync with the backend ports below if you change them.
AEVATAR_API_TARGET=http://127.0.0.1:5080
AEVATAR_CONFIGURATION_API_TARGET=http://127.0.0.1:6688
AEVATAR_STUDIO_API_TARGET=http://127.0.0.1:6690
AEVATAR_STUDIO_API_TARGET=http://127.0.0.1:5080

# NyxID login
# Register a public client in NyxID and keep redirect URI aligned with the frontend port.
Expand All @@ -27,12 +27,8 @@ NYXID_SCOPE="openid profile email roles groups"
# Optional. Defaults to the public Ornn instance when omitted.
ORNN_BASE_URL=https://ornn.chrono-ai.fun

# Local dev stack ports used by scripts/dev-stack.sh
# Local dev ports
# FRONTEND_PORT affects the dev server bind port.
# API/CONFIG ports affect backend startup only; update the proxy targets above too.
# API port affects backend startup only; update the proxy targets above too.
AEVATAR_CONSOLE_API_PORT=5080
AEVATAR_CONSOLE_CONFIG_PORT=6688
AEVATAR_CONSOLE_STUDIO_PORT=6690
AEVATAR_CONSOLE_FRONTEND_PORT=5173
AEVATAR_CONSOLE_SCOPE_ID=aevatar
AEVATAR_CONSOLE_STUDIO_NYXID_ENABLED=true
22 changes: 6 additions & 16 deletions apps/aevatar-console-web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ set +a

If you change backend ports, also keep `AEVATAR_API_TARGET` and `AEVATAR_STUDIO_API_TARGET` aligned with those ports.

When starting the Studio sidecar manually, set `Cli__App__ScopeId=aevatar` and keep `Cli__App__NyxId__Enabled=true` unless you intentionally want to disable protected Studio APIs. Chrono-storage backed connector and role catalogs require both the scope and a valid Studio NyxID session.

For NyxID login, also set these values in `.env.local`:

```bash
Expand Down Expand Up @@ -66,37 +64,29 @@ pnpm tsc

## Local stack

`aevatar-console-web` depends on two local backend services during development:
`aevatar-console-web` depends on the local Mainnet Host API during development.
Mainnet composes the runtime APIs and `Aevatar.Studio.Hosting`, including the
Team endpoints.

- `Mainnet Host API` on `http://127.0.0.1:5080`
- `Studio sidecar` on `http://127.0.0.1:6690`

The dedicated local configuration tool is still available when you need to edit
secrets, workflows, providers, MCP servers, or raw config files, but it is no
longer proxied through the console:

- `aevatar config ui --no-browser`

Start the required services in separate terminals:

```bash
env ASPNETCORE_URLS=http://127.0.0.1:5080 \
dotnet run --project src/Aevatar.Mainnet.Host.Api

env Cli__App__NyxId__Enabled=true Cli__App__ScopeId=aevatar \
dotnet run --project tools/Aevatar.Tools.Cli -- app --no-browser --port 6690 --api-base http://127.0.0.1:5080

cd apps/aevatar-console-web
AEVATAR_API_TARGET=http://127.0.0.1:5080 \
AEVATAR_STUDIO_API_TARGET=http://127.0.0.1:6690 \
AEVATAR_STUDIO_API_TARGET=http://127.0.0.1:5080 \
ORNN_BASE_URL=https://ornn.chrono-ai.fun \
pnpm dev
```

Current proxy split during local development:

- `/api/chat`, `/api/workflows/*`, `/api/actors/*`, `/api/runs/*`, `/api/primitives`, `/api/capabilities`, `/api/scopes/*` -> `Mainnet Host API`
- `/api/app/*`, `/api/auth/*`, `/api/workspace/*`, `/api/editor/*`, `/api/executions/*`, `/api/roles/*`, `/api/connectors/*`, `/api/settings/*` -> `Studio sidecar`
- `/api/chat`, `/api/workflows/*`, `/api/actors/*`, `/api/runs/*`, `/api/primitives`, `/api/capabilities`, most `/api/scopes/*` runtime routes -> `Mainnet Host API`
- `/api/app/*`, `/api/auth/*`, `/api/workspace/*`, `/api/editor/*`, `/api/executions/*`, `/api/roles/*`, `/api/connectors/*`, `/api/settings/*`, `/api/scopes/{scopeId}/teams*` -> `Studio Hosting API target`

## Current scope

Expand Down
2 changes: 2 additions & 0 deletions apps/aevatar-console-web/config/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ const studioProxyEntries = [
}, {});

const studioScopeProxyEntries = {
'^/api/scopes/[^/]+/teams(?:/.*)?$':
buildProxyTarget(studioApiTarget),
'^/api/scopes/[^/]+/scripts/draft-run$':
buildProxyTarget(studioApiTarget),
'^/api/scripts/validate$': buildProxyTarget(studioApiTarget),
Expand Down
7 changes: 7 additions & 0 deletions apps/aevatar-console-web/config/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ export default [
hideInMenu: true,
menuGroupKey: "teams",
},
{
path: "/teams/:scopeId/:teamId",
name: "Team Details",
component: "./teams/detail",
hideInMenu: true,
parentKeys: ["/teams"],
},
{
path: "/teams/:scopeId",
name: "Team Details",
Expand Down
28 changes: 14 additions & 14 deletions apps/aevatar-console-web/src/pages/runs/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,50 +141,50 @@ jest.mock("./components/RunsLaunchRail", () => {
const normalizePatch = (
value: Record<string, unknown> = {}
): Partial<MockRunFormValues> => ({
...(Object.prototype.hasOwnProperty.call(value, "actorId")
...(Object.hasOwn(value, "actorId")
? { actorId: normalizeValues({ actorId: value.actorId }).actorId }
: {}),
...(Object.prototype.hasOwnProperty.call(value, "endpointId")
...(Object.hasOwn(value, "endpointId")
? { endpointId: normalizeValues({ endpointId: value.endpointId }).endpointId }
: {}),
...(Object.prototype.hasOwnProperty.call(value, "endpointKind")
...(Object.hasOwn(value, "endpointKind")
? {
endpointKind: normalizeValues({
endpointKind: value.endpointKind,
}).endpointKind,
}
: {}),
...(Object.prototype.hasOwnProperty.call(value, "payloadBase64")
...(Object.hasOwn(value, "payloadBase64")
? {
payloadBase64: normalizeValues({
payloadBase64: value.payloadBase64,
}).payloadBase64,
}
: {}),
...(Object.prototype.hasOwnProperty.call(value, "payloadTypeUrl")
...(Object.hasOwn(value, "payloadTypeUrl")
? {
payloadTypeUrl: normalizeValues({
payloadTypeUrl: value.payloadTypeUrl,
}).payloadTypeUrl,
}
: {}),
...(Object.prototype.hasOwnProperty.call(value, "prompt")
...(Object.hasOwn(value, "prompt")
? { prompt: normalizeValues({ prompt: value.prompt }).prompt }
: {}),
...(Object.prototype.hasOwnProperty.call(value, "routeName")
...(Object.hasOwn(value, "routeName")
? { routeName: normalizeValues({ routeName: value.routeName }).routeName }
: {}),
...(Object.prototype.hasOwnProperty.call(value, "scopeId")
...(Object.hasOwn(value, "scopeId")
? { scopeId: normalizeValues({ scopeId: value.scopeId }).scopeId }
: {}),
...(Object.prototype.hasOwnProperty.call(value, "serviceOverrideId")
...(Object.hasOwn(value, "serviceOverrideId")
? {
serviceOverrideId: normalizeValues({
serviceOverrideId: value.serviceOverrideId,
}).serviceOverrideId,
}
: {}),
...(Object.prototype.hasOwnProperty.call(value, "transport")
...(Object.hasOwn(value, "transport")
? { transport: normalizeValues({ transport: value.transport }).transport }
: {}),
});
Expand Down Expand Up @@ -372,10 +372,10 @@ describe("RunsPage", () => {
await screen.findByRole("button", { name: "返回团队高级编辑" })
);

expect(window.location.pathname).toBe("/teams/scope-1");
expect(new URLSearchParams(window.location.search).get("tab")).toBe(
"advanced"
);
expect(window.location.pathname).toBe("/teams");
const params = new URLSearchParams(window.location.search);
expect(params.get("scopeId")).toBe("scope-1");
expect(params.get("tab")).toBeNull();
});

it("returns to the originating studio route when a return target is provided", async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ const topActionButtonStyle: React.CSSProperties = {
};

export const TeamDetailEmptyState: React.FC = () => (
<AevatarPageShell title="团队详情" content="请先进入一个具体团队,再查看详情。">
<AevatarPageShell title="团队详情" content="请先从团队列表选择一个具体团队,再查看详情。">
<AevatarPanel title="未选择团队">
<AevatarInspectorEmpty description="当前需要一个明确的 scope 才能渲染团队详情。" />
<AevatarInspectorEmpty description="当前链接只有工作区上下文,没有具体 Team 标识。返回团队列表后选择一个团队。" />
</AevatarPanel>
</AevatarPageShell>
);
Expand Down
Loading
Loading