authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-06-19 21:18:55-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-06-19 21:18:55-07:00
log01492ebd3b624e544e6375c12540b741c65256b9
treef9b802a8d8d83645996844a52fd21180763b21de
parent93fd9721086d4325794830a29a7df0592d120683
signature Signed by PGP key B5690EEEBB952194

[codex] Refactor agent awareness relay service (#3197)

Co-authored-by: codex <codex@users.noreply.github.com>

1 files changed, 23 insertions(+), 25 deletions(-)

apps/server/src/relay/AgentAwarenessRelay.ts+23-25
...@@ -1,8 +1,3 @@...@@ -1,8 +1,3 @@
1import {
2 RelayApi,
3 type RelayAgentActivityPublishProofPayload,
4 type RelayAgentActivityState,
5} from "@t3tools/contracts/relay";
6import type {1import type {
7 EnvironmentId,2 EnvironmentId,
8 OrchestrationEvent,3 OrchestrationEvent,
...@@ -10,13 +5,18 @@ import type {...@@ -10,13 +5,18 @@ import type {
10 OrchestrationThreadShell,5 OrchestrationThreadShell,
11 ThreadId,6 ThreadId,
12} from "@t3tools/contracts";7} from "@t3tools/contracts";
8import {
9 RelayApi,
10 type RelayAgentActivityPublishProofPayload,
11 type RelayAgentActivityState,
12} from "@t3tools/contracts/relay";
13import { projectThreadAwareness } from "@t3tools/shared/agentAwareness";13import { projectThreadAwareness } from "@t3tools/shared/agentAwareness";
14import { makeDrainableWorker } from "@t3tools/shared/DrainableWorker";14import { makeDrainableWorker } from "@t3tools/shared/DrainableWorker";
15import { withRelayClientTracing } from "@t3tools/shared/relayTracing";15import { withRelayClientTracing } from "@t3tools/shared/relayTracing";
16import {16import {
17 normalizeRelayIssuer,
17 RELAY_ACTIVITY_PUBLISH_TYP,18 RELAY_ACTIVITY_PUBLISH_TYP,
18 signRelayJwt,19 signRelayJwt,
19 normalizeRelayIssuer,
20} from "@t3tools/shared/relayJwt";20} from "@t3tools/shared/relayJwt";
21import * as Cause from "effect/Cause";21import * as Cause from "effect/Cause";
22import * as Context from "effect/Context";22import * as Context from "effect/Context";
...@@ -28,31 +28,29 @@ import * as Option from "effect/Option";...@@ -28,31 +28,29 @@ import * as Option from "effect/Option";
28import * as Ref from "effect/Ref";28import * as Ref from "effect/Ref";
29import type * as Scope from "effect/Scope";29import type * as Scope from "effect/Scope";
30import * as Stream from "effect/Stream";30import * as Stream from "effect/Stream";
31import { FetchHttpClient } from "effect/unstable/http";31import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient";
32import * as HttpClient from "effect/unstable/http/HttpClient";32import * as HttpClient from "effect/unstable/http/HttpClient";
33import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest";33import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest";
34import * as HttpApiClient from "effect/unstable/httpapi/HttpApiClient";34import * as HttpApiClient from "effect/unstable/httpapi/HttpApiClient";
3535
36import * as ServerSecretStore from "../auth/ServerSecretStore.ts";36import * as ServerSecretStore from "../auth/ServerSecretStore.ts";
37import { getOrCreateEnvironmentKeyPairFromSecretStore } from "../cloud/environmentKeys.ts";
38import {37import {
39 PUBLISH_AGENT_ACTIVITY_SECRET,38 PUBLISH_AGENT_ACTIVITY_SECRET,
40 RELAY_ENVIRONMENT_CREDENTIAL_SECRET,39 RELAY_ENVIRONMENT_CREDENTIAL_SECRET,
41 RELAY_ISSUER_SECRET,40 RELAY_ISSUER_SECRET,
42 RELAY_URL_SECRET,41 RELAY_URL_SECRET,
43} from "../cloud/config.ts";42} from "../cloud/config.ts";
44import { ServerEnvironment } from "../environment/Services/ServerEnvironment.ts";43import { getOrCreateEnvironmentKeyPairFromSecretStore } from "../cloud/environmentKeys.ts";
45import { OrchestrationEngineService } from "../orchestration/Services/OrchestrationEngine.ts";44import * as ServerEnvironment from "../environment/Services/ServerEnvironment.ts";
46import { ProjectionSnapshotQuery } from "../orchestration/Services/ProjectionSnapshotQuery.ts";45import * as OrchestrationEngine from "../orchestration/Services/OrchestrationEngine.ts";
4746import * as ProjectionSnapshotQuery from "../orchestration/Services/ProjectionSnapshotQuery.ts";
48export interface AgentAwarenessRelayShape {
49 readonly publishThread: (threadId: ThreadId) => Effect.Effect<void>;
50 readonly start: () => Effect.Effect<void, never, Scope.Scope>;
51}
5247
53export class AgentAwarenessRelay extends Context.Service<48export class AgentAwarenessRelay extends Context.Service<
54 AgentAwarenessRelay,49 AgentAwarenessRelay,
55 AgentAwarenessRelayShape50 {
51 readonly publishThread: (threadId: ThreadId) => Effect.Effect<void>;
52 readonly start: () => Effect.Effect<void, never, Scope.Scope>;
53 }
56>()("t3/relay/AgentAwarenessRelay") {}54>()("t3/relay/AgentAwarenessRelay") {}
5755
58export function eventThreadId(event: OrchestrationEvent): ThreadId | null {56export function eventThreadId(event: OrchestrationEvent): ThreadId | null {
...@@ -265,11 +263,11 @@ export function resolveAgentAwarenessRelayActiveThreadIds(input: {...@@ -265,11 +263,11 @@ export function resolveAgentAwarenessRelayActiveThreadIds(input: {
265 .map((thread) => thread.id);263 .map((thread) => thread.id);
266}264}
267265
268const make = Effect.gen(function* () {266export const make = Effect.gen(function* () {
269 const secrets = yield* ServerSecretStore.ServerSecretStore;267 const secrets = yield* ServerSecretStore.ServerSecretStore;
270 const serverEnvironment = yield* ServerEnvironment;268 const serverEnvironment = yield* ServerEnvironment.ServerEnvironment;
271 const snapshotQuery = yield* ProjectionSnapshotQuery;269 const snapshotQuery = yield* ProjectionSnapshotQuery.ProjectionSnapshotQuery;
272 const orchestrationEngine = yield* OrchestrationEngineService;270 const orchestrationEngine = yield* OrchestrationEngine.OrchestrationEngineService;
273 const crypto = yield* Crypto.Crypto;271 const crypto = yield* Crypto.Crypto;
274 const cloudLinkKeyPair = yield* getOrCreateEnvironmentKeyPairFromSecretStore(secrets);272 const cloudLinkKeyPair = yield* getOrCreateEnvironmentKeyPairFromSecretStore(secrets);
275 const activeSnapshotPublishedRef = yield* Ref.make(false);273 const activeSnapshotPublishedRef = yield* Ref.make(false);
...@@ -417,7 +415,7 @@ const make = Effect.gen(function* () {...@@ -417,7 +415,7 @@ const make = Effect.gen(function* () {
417 });415 });
418 });416 });
419417
420 const publishThread: AgentAwarenessRelayShape["publishThread"] = (threadId) =>418 const publishThread: AgentAwarenessRelay["Service"]["publishThread"] = (threadId) =>
421 publishThreadUnsafe(threadId).pipe(419 publishThreadUnsafe(threadId).pipe(
422 Effect.catchCause((cause) => {420 Effect.catchCause((cause) => {
423 return Effect.logWarning("agent activity publish failed", {421 return Effect.logWarning("agent activity publish failed", {
...@@ -480,7 +478,7 @@ const make = Effect.gen(function* () {...@@ -480,7 +478,7 @@ const make = Effect.gen(function* () {
480478
481 const worker = yield* makeDrainableWorker(publishThread);479 const worker = yield* makeDrainableWorker(publishThread);
482480
483 const start: AgentAwarenessRelayShape["start"] = Effect.fn("AgentAwarenessRelay.start")(481 const start: AgentAwarenessRelay["Service"]["start"] = Effect.fn("AgentAwarenessRelay.start")(
484 function* () {482 function* () {
485 const [relayConfig, publishEnabled] = yield* Effect.all([483 const [relayConfig, publishEnabled] = yield* Effect.all([
486 readRelayConfig.pipe(Effect.orElseSucceed(() => null)),484 readRelayConfig.pipe(Effect.orElseSucceed(() => null)),
...@@ -536,10 +534,10 @@ const make = Effect.gen(function* () {...@@ -536,10 +534,10 @@ const make = Effect.gen(function* () {
536 },534 },
537 );535 );
538536
539 return {537 return AgentAwarenessRelay.of({
540 publishThread,538 publishThread,
541 start,539 start,
542 } satisfies AgentAwarenessRelayShape;540 });
543});541});
544542
545export const layer = Layer.effect(AgentAwarenessRelay, make);543export const layer = Layer.effect(AgentAwarenessRelay, make);