fix(tess): redact sensitive persistence and egress #723
44
packages/types/src/agent/agent-runtime-provider.spec.ts
Normal file
44
packages/types/src/agent/agent-runtime-provider.spec.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import type {
|
||||
AgentRuntimeProvider,
|
||||
RuntimeAttachHandle,
|
||||
RuntimeCapability,
|
||||
RuntimeError,
|
||||
RuntimeSession,
|
||||
RuntimeStreamEvent,
|
||||
} from './agent-runtime-provider.js';
|
||||
|
||||
describe('AgentRuntimeProvider contract', (): void => {
|
||||
it('exposes stable, normalized runtime-only contracts', (): void => {
|
||||
const capability: RuntimeCapability = 'session.attach';
|
||||
const session: RuntimeSession = {
|
||||
id: 'session-1',
|
||||
providerId: 'fleet',
|
||||
runtimeId: 'tmux',
|
||||
state: 'active',
|
||||
createdAt: '2026-07-12T00:00:00.000Z',
|
||||
updatedAt: '2026-07-12T00:00:00.000Z',
|
||||
};
|
||||
const event: RuntimeStreamEvent = {
|
||||
type: 'message.delta',
|
||||
sessionId: session.id,
|
||||
cursor: '2',
|
||||
occurredAt: session.updatedAt,
|
||||
content: 'hello',
|
||||
};
|
||||
const error: RuntimeError = {
|
||||
code: 'capability_unsupported',
|
||||
message: 'Denied',
|
||||
retryable: false,
|
||||
};
|
||||
const attach: RuntimeAttachHandle = {
|
||||
attachmentId: 'attach-1',
|
||||
sessionId: session.id,
|
||||
mode: 'read',
|
||||
expiresAt: session.updatedAt,
|
||||
};
|
||||
const provider: Pick<AgentRuntimeProvider, 'capabilities' | 'getSessionTree' | 'attach'> =
|
||||
{} as Pick<AgentRuntimeProvider, 'capabilities' | 'getSessionTree' | 'attach'>;
|
||||
expect([capability, session.id, event.type, error.code, attach.mode, provider]).toHaveLength(6);
|
||||
});
|
||||
});
|
||||
110
packages/types/src/agent/agent-runtime-provider.ts
Normal file
110
packages/types/src/agent/agent-runtime-provider.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
export type RuntimeCapability =
|
||||
| 'session.list'
|
||||
| 'session.tree'
|
||||
| 'session.stream'
|
||||
| 'session.send'
|
||||
| 'session.attach'
|
||||
| 'session.terminate';
|
||||
export type RuntimeSessionState = 'starting' | 'active' | 'idle' | 'stopped' | 'failed';
|
||||
export type RuntimeAttachMode = 'read' | 'control';
|
||||
|
||||
/** Server-derived immutable authority context. Client identity fields are intentionally absent. */
|
||||
export interface RuntimeScope {
|
||||
readonly actorId: string;
|
||||
readonly tenantId: string;
|
||||
readonly channelId: string;
|
||||
readonly correlationId: string;
|
||||
}
|
||||
export interface RuntimeSession {
|
||||
id: string;
|
||||
providerId: string;
|
||||
runtimeId: string;
|
||||
parentSessionId?: string;
|
||||
state: RuntimeSessionState;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
export interface RuntimeSessionTree {
|
||||
session: RuntimeSession;
|
||||
children: RuntimeSessionTree[];
|
||||
}
|
||||
export interface RuntimeCapabilitySet {
|
||||
supported: RuntimeCapability[];
|
||||
}
|
||||
export interface RuntimeHealth {
|
||||
status: 'healthy' | 'degraded' | 'down';
|
||||
checkedAt: string;
|
||||
detail?: string;
|
||||
}
|
||||
export interface RuntimeMessage {
|
||||
content: string;
|
||||
idempotencyKey: string;
|
||||
}
|
||||
export interface RuntimeAttachHandle {
|
||||
attachmentId: string;
|
||||
sessionId: string;
|
||||
mode: RuntimeAttachMode;
|
||||
expiresAt: string;
|
||||
}
|
||||
export interface RuntimeError {
|
||||
code:
|
||||
| 'capability_unsupported'
|
||||
| 'not_found'
|
||||
| 'forbidden'
|
||||
| 'conflict'
|
||||
| 'unavailable'
|
||||
| 'invalid_request';
|
||||
message: string;
|
||||
retryable: boolean;
|
||||
}
|
||||
export type RuntimeStreamEvent =
|
||||
| {
|
||||
type: 'session.state';
|
||||
sessionId: string;
|
||||
cursor: string;
|
||||
occurredAt: string;
|
||||
state: RuntimeSessionState;
|
||||
}
|
||||
| {
|
||||
type: 'message.delta';
|
||||
sessionId: string;
|
||||
cursor: string;
|
||||
occurredAt: string;
|
||||
content: string;
|
||||
}
|
||||
| {
|
||||
type: 'message.complete';
|
||||
sessionId: string;
|
||||
cursor: string;
|
||||
occurredAt: string;
|
||||
messageId: string;
|
||||
}
|
||||
| {
|
||||
type: 'runtime.error';
|
||||
sessionId: string;
|
||||
cursor: string;
|
||||
occurredAt: string;
|
||||
error: RuntimeError;
|
||||
};
|
||||
|
||||
/** Runtime-neutral boundary; implementations fail closed for unsupported operations. */
|
||||
export interface AgentRuntimeProvider {
|
||||
readonly id: string;
|
||||
capabilities(scope: RuntimeScope): Promise<RuntimeCapabilitySet>;
|
||||
health(scope: RuntimeScope): Promise<RuntimeHealth>;
|
||||
listSessions(scope: RuntimeScope): Promise<RuntimeSession[]>;
|
||||
getSessionTree(scope: RuntimeScope): Promise<RuntimeSessionTree[]>;
|
||||
streamSession(
|
||||
sessionId: string,
|
||||
cursor: string | undefined,
|
||||
scope: RuntimeScope,
|
||||
): AsyncIterable<RuntimeStreamEvent>;
|
||||
sendMessage(sessionId: string, message: RuntimeMessage, scope: RuntimeScope): Promise<void>;
|
||||
attach(
|
||||
sessionId: string,
|
||||
mode: RuntimeAttachMode,
|
||||
scope: RuntimeScope,
|
||||
): Promise<RuntimeAttachHandle>;
|
||||
detach(attachmentId: string, scope: RuntimeScope): Promise<void>;
|
||||
terminate(sessionId: string, approvalRef: string, scope: RuntimeScope): Promise<void>;
|
||||
}
|
||||
@@ -2,3 +2,5 @@
|
||||
export interface AgentSessionHandle {
|
||||
readonly id: string;
|
||||
}
|
||||
|
||||
export * from './agent-runtime-provider.js';
|
||||
|
||||
Reference in New Issue
Block a user