mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
feat: isolate Chord context API
This commit is contained in:
parent
6ec57e6e5f
commit
e6dc574d1b
27 changed files with 88 additions and 155 deletions
|
|
@ -1,19 +1,28 @@
|
|||
import type { Context, ContextKey } from "@earendil-works/chord";
|
||||
import {
|
||||
awaitWithContext,
|
||||
BACKGROUND_CONTEXT,
|
||||
type Context,
|
||||
type ContextKey,
|
||||
INTERNAL_CONTEXT_OPERATIONS,
|
||||
createContextKey,
|
||||
TODO_CONTEXT,
|
||||
withAbortSignal,
|
||||
withCancel,
|
||||
withContextValue,
|
||||
withoutAbortSignal,
|
||||
} from "@earendil-works/chord/context";
|
||||
import { NOOP_TELEMETRY_CONTEXT, type TelemetryContext } from "@earendil-works/pi-telemetry";
|
||||
|
||||
export { BACKGROUND_CONTEXT, type Context, type ContextKey, TODO_CONTEXT };
|
||||
export const awaitWithContext = INTERNAL_CONTEXT_OPERATIONS.awaitWithContext;
|
||||
export const createContextKey = INTERNAL_CONTEXT_OPERATIONS.createContextKey;
|
||||
export const withAbortSignal = INTERNAL_CONTEXT_OPERATIONS.withAbortSignal;
|
||||
export const withCancel = INTERNAL_CONTEXT_OPERATIONS.withCancel;
|
||||
export const withContextValue = INTERNAL_CONTEXT_OPERATIONS.withContextValue;
|
||||
export const withoutAbortSignal = INTERNAL_CONTEXT_OPERATIONS.withoutAbortSignal;
|
||||
export {
|
||||
awaitWithContext,
|
||||
BACKGROUND_CONTEXT,
|
||||
type Context,
|
||||
type ContextKey,
|
||||
createContextKey,
|
||||
TODO_CONTEXT,
|
||||
withAbortSignal,
|
||||
withCancel,
|
||||
withContextValue,
|
||||
withoutAbortSignal,
|
||||
};
|
||||
|
||||
const TELEMETRY_CONTEXT_KEY = createContextKey<TelemetryContext>("pi.telemetryContext");
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { JsonValue } from "@earendil-works/chord/types";
|
||||
import type { JsonValue } from "@earendil-works/chord";
|
||||
import type { AssistantMessage, StopReason, Usage } from "@earendil-works/pi-ai";
|
||||
import type { AgentMessage, QueueMode, ThinkingLevel } from "../../types.ts";
|
||||
import type { BranchPreparation } from "../compaction/branch-summarization.ts";
|
||||
|
|
@ -7,7 +7,7 @@ import type { Context } from "../context.ts";
|
|||
import type { AgentHarnessStreamOptions } from "../types.ts";
|
||||
import type { ListElement, ListReadOptions, ListWrite, StoredValue, Value, ValueList, ValueWrite } from "./values.ts";
|
||||
|
||||
export type { JsonValue } from "@earendil-works/chord/types";
|
||||
export type { JsonValue } from "@earendil-works/chord";
|
||||
|
||||
export type SettledAssistantMessage = AssistantMessage & {
|
||||
stopReason: Exclude<StopReason, "pending">;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { JsonValue } from "@earendil-works/chord/types";
|
||||
import type { JsonValue } from "@earendil-works/chord";
|
||||
import type { TelemetryContext } from "@earendil-works/pi-telemetry";
|
||||
import type { AnthropicOptions } from "./api/anthropic-messages.ts";
|
||||
import type { AzureOpenAIResponsesOptions } from "./api/azure-openai-responses.ts";
|
||||
|
|
@ -405,7 +405,7 @@ export interface Usage {
|
|||
|
||||
export type StopReason = "pending" | "stop" | "length" | "toolUse" | "error" | "aborted" | "deferred";
|
||||
|
||||
export type { JsonValue } from "@earendil-works/chord/types";
|
||||
export type { JsonValue } from "@earendil-works/chord";
|
||||
|
||||
export interface DeferredHandle {
|
||||
provider: string;
|
||||
|
|
|
|||
|
|
@ -583,10 +583,10 @@ This is a planning aid, not a requirement to create all files immediately.
|
|||
packages/chord/
|
||||
src/
|
||||
index.ts platform-neutral public API
|
||||
api.ts public functions
|
||||
types.ts public types, including strict JSON values
|
||||
api.ts root-exported functions
|
||||
types.ts root-exported types, including strict JSON values
|
||||
context/
|
||||
index.ts invocation context internals and compatibility entry
|
||||
index.ts invocation context constants and functions
|
||||
errors.ts lifecycle, service, and RPC errors
|
||||
services/
|
||||
types.ts tokens, contracts, modes, snapshots
|
||||
|
|
|
|||
|
|
@ -48,9 +48,10 @@ The design has a few connected pieces:
|
|||
|
||||
The current runtime exports service tokens, singleton and keyed providers,
|
||||
remote bindings, replicated state, facet hosts, and facet loaders from
|
||||
`@earendil-works/chord`. All public functions are collected in
|
||||
`@earendil-works/chord/api`, while all public types are collected in
|
||||
`@earendil-works/chord/types`; both are re-exported from the main entry point.
|
||||
`@earendil-works/chord`. Import public types and general runtime APIs from the
|
||||
package root. Context constants and functions live in
|
||||
`@earendil-works/chord/context` because their generic names should not pollute
|
||||
the root API.
|
||||
Chord-owned identifiers use the `chord.*` namespace and its reserved service
|
||||
prefix is `$chord.*`.
|
||||
|
||||
|
|
|
|||
|
|
@ -11,21 +11,11 @@
|
|||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js"
|
||||
},
|
||||
"./api": {
|
||||
"source": "./src/api.ts",
|
||||
"types": "./dist/api.d.ts",
|
||||
"import": "./dist/api.js"
|
||||
},
|
||||
"./context": {
|
||||
"source": "./src/context/index.ts",
|
||||
"types": "./dist/context/index.d.ts",
|
||||
"import": "./dist/context/index.js"
|
||||
},
|
||||
"./types": {
|
||||
"source": "./src/types.ts",
|
||||
"types": "./dist/types.d.ts",
|
||||
"import": "./dist/types.js"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"sideEffects": false,
|
||||
|
|
|
|||
|
|
@ -1,19 +1,10 @@
|
|||
import {
|
||||
deriveCancellableContext,
|
||||
deriveContextValue,
|
||||
deriveContextWithAbortSignal,
|
||||
deriveContextWithoutAbortSignal,
|
||||
waitWithContext,
|
||||
} from "./context/index.ts";
|
||||
import { FacetKernel } from "./facets/host.ts";
|
||||
import { disposeLoadedFacets } from "./facets/loader.ts";
|
||||
import { RemoteServiceBindingImpl } from "./services/consumer.ts";
|
||||
import { lookupServiceInstanceKey } from "./services/instances.ts";
|
||||
import type { RemoteServiceProvider } from "./services/provider.ts";
|
||||
import { createDeliveryContext, MutableReplicatedStateImpl } from "./services/state.ts";
|
||||
import { MutableReplicatedStateImpl, serviceDeliveryContext } from "./services/state.ts";
|
||||
import type {
|
||||
Context,
|
||||
ContextKey,
|
||||
Facet,
|
||||
FacetHost,
|
||||
FacetLoader,
|
||||
|
|
@ -27,44 +18,6 @@ import type {
|
|||
Service,
|
||||
} from "./types.ts";
|
||||
|
||||
export function createContextKey<T>(description: string): ContextKey<T> {
|
||||
return Object.freeze({ token: Symbol(description) });
|
||||
}
|
||||
|
||||
/** Derive a context containing one additional or replaced value. */
|
||||
export function withContextValue<T>(key: ContextKey<T>, value: T, parent: Context): Context {
|
||||
return deriveContextValue(key, value, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive a context cancelled by either the parent signal or the supplied signal.
|
||||
* The parent context remains unchanged.
|
||||
*/
|
||||
export function withAbortSignal(signal: AbortSignal, context: Context): Context {
|
||||
return deriveContextWithAbortSignal(signal, context);
|
||||
}
|
||||
|
||||
/** Derive a context retaining all values except caller cancellation. Intended for mandatory cleanup only. */
|
||||
export function withoutAbortSignal(context: Context): Context {
|
||||
return deriveContextWithoutAbortSignal(context);
|
||||
}
|
||||
|
||||
/** Derive an independently cancellable child context. */
|
||||
export function withCancel(context: Context): {
|
||||
readonly context: Context;
|
||||
readonly cancel: (reason?: unknown) => void;
|
||||
} {
|
||||
return deriveCancellableContext(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Observe a promise until it settles or the invocation is cancelled.
|
||||
* Cancellation rejects only this waiter; it does not cancel the underlying promise.
|
||||
*/
|
||||
export function awaitWithContext<T>(promise: Promise<T>, context: Context): Promise<T> {
|
||||
return waitWithContext(promise, context);
|
||||
}
|
||||
|
||||
/** Create an active host for one complete set of facets. */
|
||||
export async function createFacetHost(options: FacetOptions): Promise<FacetHost> {
|
||||
const kernel = new FacetKernel(options);
|
||||
|
|
@ -151,7 +104,7 @@ export function createLoopbackServiceConnection(provider: RemoteServiceProvider)
|
|||
invoke: (call, context) => provider.invoke(call, context),
|
||||
subscribe: async (serviceId, mode, listener) => {
|
||||
const subscription = provider.subscribe(serviceId, mode, (update) =>
|
||||
listener(update, createDeliveryContext()),
|
||||
listener(update, serviceDeliveryContext()),
|
||||
);
|
||||
return {
|
||||
snapshot: subscription.snapshot,
|
||||
|
|
@ -165,8 +118,3 @@ export function createLoopbackServiceConnection(provider: RemoteServiceProvider)
|
|||
export function replicatedState<T>(initial: T): MutableReplicatedState<T> {
|
||||
return new MutableReplicatedStateImpl(initial);
|
||||
}
|
||||
|
||||
/** @publicApiReview Delivery contexts may only be an internal service-replication concern. */
|
||||
export function freshDeliveryContext(): Context {
|
||||
return createDeliveryContext();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
import type { Context, ContextKey } from "../types.ts";
|
||||
|
||||
export type { Context, ContextKey } from "../types.ts";
|
||||
|
||||
export const ABORT_SIGNAL_CONTEXT_KEY: ContextKey<AbortSignal | undefined> = Object.freeze({
|
||||
const ABORT_SIGNAL_CONTEXT_KEY: ContextKey<AbortSignal | undefined> = Object.freeze({
|
||||
token: Symbol("chord.abortSignal"),
|
||||
});
|
||||
|
||||
|
|
@ -57,36 +55,47 @@ class ContextValue<T> extends BaseContext {
|
|||
export const BACKGROUND_CONTEXT: Context = new EmptyContext("[Context BACKGROUND_CONTEXT]");
|
||||
export const TODO_CONTEXT: Context = new EmptyContext("[Context TODO_CONTEXT]");
|
||||
|
||||
function createContextKey<T>(description: string): ContextKey<T> {
|
||||
export function createContextKey<T>(description: string): ContextKey<T> {
|
||||
return Object.freeze({ token: Symbol(description) });
|
||||
}
|
||||
|
||||
export function deriveContextValue<T>(key: ContextKey<T>, value: T, parent: Context): Context {
|
||||
/** Derive a context containing one additional or replaced value. */
|
||||
export function withContextValue<T>(key: ContextKey<T>, value: T, parent: Context): Context {
|
||||
return new ContextValue(parent, key, value);
|
||||
}
|
||||
|
||||
export function deriveContextWithAbortSignal(signal: AbortSignal, context: Context): Context {
|
||||
/**
|
||||
* Derive a context cancelled by either the parent signal or the supplied signal.
|
||||
* The parent context remains unchanged.
|
||||
*/
|
||||
export function withAbortSignal(signal: AbortSignal, context: Context): Context {
|
||||
const parentSignal = context.abortSignal;
|
||||
const combined = parentSignal === undefined ? signal : AbortSignal.any([parentSignal, signal]);
|
||||
return deriveContextValue(ABORT_SIGNAL_CONTEXT_KEY, combined, context);
|
||||
return withContextValue(ABORT_SIGNAL_CONTEXT_KEY, combined, context);
|
||||
}
|
||||
|
||||
export function deriveContextWithoutAbortSignal(context: Context): Context {
|
||||
return deriveContextValue(ABORT_SIGNAL_CONTEXT_KEY, undefined, context);
|
||||
/** Derive a context retaining all values except caller cancellation. Intended for mandatory cleanup only. */
|
||||
export function withoutAbortSignal(context: Context): Context {
|
||||
return withContextValue(ABORT_SIGNAL_CONTEXT_KEY, undefined, context);
|
||||
}
|
||||
|
||||
export function deriveCancellableContext(context: Context): {
|
||||
/** Derive an independently cancellable child context. */
|
||||
export function withCancel(context: Context): {
|
||||
readonly context: Context;
|
||||
readonly cancel: (reason?: unknown) => void;
|
||||
} {
|
||||
const controller = new AbortController();
|
||||
return {
|
||||
context: deriveContextWithAbortSignal(controller.signal, context),
|
||||
context: withAbortSignal(controller.signal, context),
|
||||
cancel: (reason?: unknown) => controller.abort(reason),
|
||||
};
|
||||
}
|
||||
|
||||
export function waitWithContext<T>(promise: Promise<T>, context: Context): Promise<T> {
|
||||
/**
|
||||
* Observe a promise until it settles or the invocation is cancelled.
|
||||
* Cancellation rejects only this waiter; it does not cancel the underlying promise.
|
||||
*/
|
||||
export function awaitWithContext<T>(promise: Promise<T>, context: Context): Promise<T> {
|
||||
const signal = context.abortSignal;
|
||||
if (signal === undefined) return promise;
|
||||
if (signal.aborted) return Promise.reject(abortError(signal));
|
||||
|
|
@ -110,13 +119,3 @@ function abortError(signal: AbortSignal): Error {
|
|||
const reason: unknown = signal.reason;
|
||||
return reason instanceof Error ? reason : new DOMException("The operation was aborted", "AbortError");
|
||||
}
|
||||
|
||||
/** @internal Narrow compatibility surface for the legacy context entry point. */
|
||||
export const INTERNAL_CONTEXT_OPERATIONS = Object.freeze({
|
||||
awaitWithContext: waitWithContext,
|
||||
createContextKey,
|
||||
withAbortSignal: deriveContextWithAbortSignal,
|
||||
withCancel: deriveCancellableContext,
|
||||
withContextValue: deriveContextValue,
|
||||
withoutAbortSignal: deriveContextWithoutAbortSignal,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,27 +1,17 @@
|
|||
/**
|
||||
* Chord is a standalone application-composition runtime.
|
||||
*
|
||||
* Its public API is under development.
|
||||
* Chord is a standalone application-composition runtime for agentic applications.
|
||||
*/
|
||||
export {
|
||||
awaitWithContext,
|
||||
combineFacetLoaders,
|
||||
createContextKey,
|
||||
createFacetHost,
|
||||
createLoopbackServiceConnection,
|
||||
createRemoteServiceBinding,
|
||||
createStaticFacetLoader,
|
||||
defineFacet,
|
||||
defineService,
|
||||
freshDeliveryContext,
|
||||
getServiceInstanceKey,
|
||||
replicatedState,
|
||||
withAbortSignal,
|
||||
withCancel,
|
||||
withContextValue,
|
||||
withoutAbortSignal,
|
||||
} from "./api.ts";
|
||||
export { BACKGROUND_CONTEXT, TODO_CONTEXT } from "./context/index.ts";
|
||||
export { RemoteServiceError } from "./services/errors.ts";
|
||||
export { RemoteServiceProvider } from "./services/provider.ts";
|
||||
export type {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { BACKGROUND_CONTEXT, waitWithContext } from "../context/index.ts";
|
||||
import { awaitWithContext, BACKGROUND_CONTEXT } from "../context/index.ts";
|
||||
import type {
|
||||
Context,
|
||||
JsonValue,
|
||||
|
|
@ -14,7 +14,7 @@ import type {
|
|||
} from "../types.ts";
|
||||
import { RemoteServiceError } from "./errors.ts";
|
||||
import { InstanceDirectory, type InstanceDirectoryEntry } from "./instances.ts";
|
||||
import { createDeliveryContext, ReplicatedStateReplica } from "./state.ts";
|
||||
import { ReplicatedStateReplica, serviceDeliveryContext } from "./state.ts";
|
||||
|
||||
type ErrorReporter = (error: Error) => void;
|
||||
type ServiceMemberKind = ServiceMemberSnapshot["kind"];
|
||||
|
|
@ -346,7 +346,7 @@ class KeyedBinding<T> {
|
|||
if (subscription.snapshot.mode !== "keyed" || subscription.snapshot.serviceId !== this.#service.id) {
|
||||
throw new Error(`Remote service ${this.#service.id} returned the wrong keyed snapshot`);
|
||||
}
|
||||
for (const snapshot of subscription.snapshot.instances) this.#spawn(snapshot, createDeliveryContext());
|
||||
for (const snapshot of subscription.snapshot.instances) this.#spawn(snapshot, serviceDeliveryContext());
|
||||
this.#instances.ready();
|
||||
subscription.activate();
|
||||
}
|
||||
|
|
@ -500,7 +500,7 @@ export class RemoteServiceBindingImpl implements RemoteServiceBinding {
|
|||
),
|
||||
...[...this.#keyed.values()].map((binding) => binding.ready()),
|
||||
];
|
||||
await waitWithContext(
|
||||
await awaitWithContext(
|
||||
Promise.all(starts).then(() => undefined),
|
||||
context,
|
||||
);
|
||||
|
|
@ -595,7 +595,7 @@ export class RemoteServiceBindingImpl implements RemoteServiceBinding {
|
|||
if (snapshot.mode !== "singleton" || snapshot.serviceId !== serviceId || snapshot.instances.length !== 1) {
|
||||
throw new Error(`Remote service ${serviceId} returned an invalid singleton snapshot`);
|
||||
}
|
||||
binding.facade.install(snapshot.instances[0]!, createDeliveryContext());
|
||||
binding.facade.install(snapshot.instances[0]!, serviceDeliveryContext());
|
||||
subscription.activate();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { BACKGROUND_CONTEXT, deriveCancellableContext } from "../context/index.ts";
|
||||
import { BACKGROUND_CONTEXT, withCancel } from "../context/index.ts";
|
||||
import type { Context } from "../types.ts";
|
||||
|
||||
const instanceKeys = new WeakMap<object, string>();
|
||||
|
|
@ -134,7 +134,7 @@ export class InstanceDirectory<TEntry extends InstanceDirectoryEntry> {
|
|||
|
||||
#start(observer: Observer, entry: TEntry): void {
|
||||
if (observer.closed || observer.tasks.has(entry)) return;
|
||||
const { context, cancel } = deriveCancellableContext(BACKGROUND_CONTEXT);
|
||||
const { context, cancel } = withCancel(BACKGROUND_CONTEXT);
|
||||
observer.tasks.set(entry, { cancel });
|
||||
try {
|
||||
void Promise.resolve(observer.handler(entry.service, context)).catch((error: unknown) => {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import type {
|
|||
ServiceSubscriptionSnapshot,
|
||||
} from "../types.ts";
|
||||
import { RemoteServiceError } from "./errors.ts";
|
||||
import { createDeliveryContext } from "./state.ts";
|
||||
import { serviceDeliveryContext } from "./state.ts";
|
||||
import { getReplicatedStateInternals, type ReplicatedStateInternals } from "./state-internals.ts";
|
||||
|
||||
type RemoteMethod = (...args: unknown[]) => unknown;
|
||||
|
|
@ -364,7 +364,7 @@ export class RemoteServiceProvider {
|
|||
|
||||
#emit(registration: ServiceRegistration, update: ServiceProviderUpdate, context?: Context): void {
|
||||
if (registration.subscribers.size === 0) return;
|
||||
const deliveryContext = context ?? createDeliveryContext();
|
||||
const deliveryContext = context ?? serviceDeliveryContext();
|
||||
for (const subscriber of registration.subscribers) {
|
||||
if (subscriber.closed) continue;
|
||||
const entry = { update, context: deliveryContext };
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { BACKGROUND_CONTEXT, deriveCancellableContext } from "../context/index.ts";
|
||||
import { BACKGROUND_CONTEXT } from "../context/index.ts";
|
||||
import type { Context, JsonValue, MutableReplicatedState, ReplicatedState } from "../types.ts";
|
||||
import { registerReplicatedStateInternals } from "./state-internals.ts";
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ export class MutableReplicatedStateImpl<T> implements MutableReplicatedState<T>
|
|||
|
||||
subscribe(listener: (value: T, context: Context) => void): () => void {
|
||||
this.#listeners.add(listener);
|
||||
listener(this.value, createDeliveryContext());
|
||||
listener(this.value, serviceDeliveryContext());
|
||||
return () => this.#listeners.delete(listener);
|
||||
}
|
||||
}
|
||||
|
|
@ -63,7 +63,7 @@ export class ReplicatedStateReplica<T extends JsonValue = JsonValue> implements
|
|||
|
||||
subscribe(listener: (value: T, context: Context) => void): () => void {
|
||||
this.#listeners.add(listener);
|
||||
if (this.#value !== undefined) this.#deliver(listener, this.#value, createDeliveryContext());
|
||||
if (this.#value !== undefined) this.#deliver(listener, this.#value, serviceDeliveryContext());
|
||||
return () => this.#listeners.delete(listener);
|
||||
}
|
||||
|
||||
|
|
@ -101,8 +101,10 @@ export class ReplicatedStateReplica<T extends JsonValue = JsonValue> implements
|
|||
}
|
||||
}
|
||||
|
||||
export function createDeliveryContext(): Context {
|
||||
return deriveCancellableContext(BACKGROUND_CONTEXT).context;
|
||||
/** @internal Context for synthetic service deliveries without a caller. */
|
||||
export function serviceDeliveryContext(): Context {
|
||||
// TODO: Add delivery-scoped cancellation or metadata if deliveries gain an owned lifecycle.
|
||||
return BACKGROUND_CONTEXT;
|
||||
}
|
||||
|
||||
function toError(error: unknown): Error {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import {
|
|||
withCancel,
|
||||
withContextValue,
|
||||
withoutAbortSignal,
|
||||
} from "../src/index.ts";
|
||||
} from "../src/context/index.ts";
|
||||
|
||||
describe("Context", () => {
|
||||
it("provides distinct empty root contexts", () => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect, test, vi } from "vitest";
|
||||
import { BACKGROUND_CONTEXT } from "../src/context/index.ts";
|
||||
import {
|
||||
BACKGROUND_CONTEXT,
|
||||
type Context,
|
||||
combineFacetLoaders,
|
||||
createFacetHost,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect, test, vi } from "vitest";
|
||||
import { BACKGROUND_CONTEXT } from "../src/context/index.ts";
|
||||
import {
|
||||
BACKGROUND_CONTEXT,
|
||||
type Context,
|
||||
createFacetHost,
|
||||
createLoopbackServiceConnection,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect, test, vi } from "vitest";
|
||||
import { BACKGROUND_CONTEXT } from "../src/context/index.ts";
|
||||
import {
|
||||
BACKGROUND_CONTEXT,
|
||||
type Context,
|
||||
createLoopbackServiceConnection,
|
||||
createRemoteServiceBinding,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { basename } from "node:path";
|
||||
import { BACKGROUND_CONTEXT } from "@earendil-works/chord";
|
||||
import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context";
|
||||
import { Client } from "@earendil-works/pi-client";
|
||||
import { createUnixTransportFactory, discoverUnixServers, type UnixServerRoute } from "@earendil-works/pi-client/unix";
|
||||
import { isServerId, type ServerId } from "@earendil-works/pi-protocol";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import {
|
||||
BACKGROUND_CONTEXT,
|
||||
combineFacetLoaders,
|
||||
createFacetHost,
|
||||
createStaticFacetLoader,
|
||||
|
|
@ -8,6 +7,7 @@ import {
|
|||
type FacetLoader,
|
||||
type LoadedFacets,
|
||||
} from "@earendil-works/chord";
|
||||
import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context";
|
||||
import type { SessionSummary } from "@earendil-works/pi-protocol";
|
||||
import {
|
||||
CombinedAutocompleteProvider,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
import {
|
||||
BACKGROUND_CONTEXT,
|
||||
type Context,
|
||||
createRemoteServiceBinding,
|
||||
type FacetConnection,
|
||||
freshDeliveryContext,
|
||||
type JsonValue,
|
||||
type MutableReplicatedState,
|
||||
type RemoteServiceBinding,
|
||||
|
|
@ -13,6 +11,7 @@ import {
|
|||
replicatedState,
|
||||
type Service,
|
||||
} from "@earendil-works/chord";
|
||||
import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context";
|
||||
import type { Client } from "@earendil-works/pi-client";
|
||||
import type {
|
||||
ProtocolRpcCall,
|
||||
|
|
@ -464,7 +463,7 @@ function createRemoteServiceConnection(
|
|||
target,
|
||||
serviceId,
|
||||
mode,
|
||||
(update: ServiceProviderUpdate) => listener(update, freshDeliveryContext()),
|
||||
(update: ServiceProviderUpdate) => listener(update, BACKGROUND_CONTEXT),
|
||||
context.abortSignal,
|
||||
);
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,5 @@
|
|||
import {
|
||||
BACKGROUND_CONTEXT,
|
||||
type Context,
|
||||
defineFacet,
|
||||
type Facet,
|
||||
type MutableReplicatedState,
|
||||
} from "@earendil-works/chord";
|
||||
import { type Context, defineFacet, type Facet, type MutableReplicatedState } from "@earendil-works/chord";
|
||||
import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context";
|
||||
import type { AgentLane, ThinkingLevel } from "@earendil-works/pi-agent-core";
|
||||
import { getSupportedThinkingLevels } from "@earendil-works/pi-ai";
|
||||
import type { ModelRuntime } from "../../core/model-runtime.ts";
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import {
|
||||
BACKGROUND_CONTEXT,
|
||||
type Context,
|
||||
type ServiceProviderUpdate as CoreServiceProviderUpdate,
|
||||
RemoteServiceProvider,
|
||||
replicatedState,
|
||||
type ServiceSubscription,
|
||||
} from "@earendil-works/chord";
|
||||
import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context";
|
||||
import {
|
||||
decodeServiceControlCall,
|
||||
type JsonValue,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import {
|
||||
BACKGROUND_CONTEXT,
|
||||
createLoopbackServiceConnection,
|
||||
createRemoteServiceBinding,
|
||||
defineFacet,
|
||||
|
|
@ -7,6 +6,7 @@ import {
|
|||
RemoteServiceProvider,
|
||||
replicatedState,
|
||||
} from "@earendil-works/chord";
|
||||
import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context";
|
||||
import type { AgentLane } from "@earendil-works/pi-agent-core";
|
||||
import type { LaneEvent, LaneSnapshot, SessionSummary } from "@earendil-works/pi-protocol";
|
||||
import { ProcessTerminal, TuiMainScreen } from "@earendil-works/pi-tui";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { lstat, mkdtemp, readdir, rm, writeFile } from "node:fs/promises";
|
||||
import { join, resolve } from "node:path";
|
||||
import { BACKGROUND_CONTEXT, type Context, createFacetHost, defineFacet, withCancel } from "@earendil-works/chord";
|
||||
import { type Context, createFacetHost, defineFacet } from "@earendil-works/chord";
|
||||
import { BACKGROUND_CONTEXT, withCancel } from "@earendil-works/chord/context";
|
||||
import { Client } from "@earendil-works/pi-client";
|
||||
import { createUnixTransportFactory } from "@earendil-works/pi-client/unix";
|
||||
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { BACKGROUND_CONTEXT, createFacetHost } from "@earendil-works/chord";
|
||||
import { createFacetHost } from "@earendil-works/chord";
|
||||
import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context";
|
||||
import { describe, expect, test } from "vitest";
|
||||
import {
|
||||
accountsServiceFacet,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { JsonValue } from "@earendil-works/chord/types";
|
||||
import type { JsonValue } from "@earendil-works/chord";
|
||||
import Type from "typebox";
|
||||
|
||||
/** Static JSON contract. Concrete serializers are responsible for rejecting unsupported runtime values. */
|
||||
export const JsonValueSchema = Type.Unsafe<JsonValue>(Type.Unknown());
|
||||
|
||||
export type { JsonValue } from "@earendil-works/chord/types";
|
||||
export type { JsonValue } from "@earendil-works/chord";
|
||||
|
|
|
|||
|
|
@ -7,9 +7,7 @@
|
|||
"paths": {
|
||||
"*": ["./*"],
|
||||
"@earendil-works/chord": ["./packages/chord/src/index.ts"],
|
||||
"@earendil-works/chord/api": ["./packages/chord/src/api.ts"],
|
||||
"@earendil-works/chord/context": ["./packages/chord/src/context/index.ts"],
|
||||
"@earendil-works/chord/types": ["./packages/chord/src/types.ts"],
|
||||
"@earendil-works/pi-telemetry": ["./packages/telemetry/src/index.ts"],
|
||||
"@earendil-works/pi-telemetry/testing": ["./packages/telemetry/src/testing/index.ts"],
|
||||
"@earendil-works/pi-ai": ["./packages/ai/src/index.ts"],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue