@canonmsg/core 0.19.1 → 0.19.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-session.js +3 -1
- package/dist/browser.d.ts +4 -3
- package/dist/browser.js +2 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.js +2 -1
- package/dist/local-runtime-catalog.d.ts +1 -0
- package/dist/runtime-cards.d.ts +65 -0
- package/dist/runtime-cards.js +198 -0
- package/dist/runtime-descriptor.d.ts +2 -0
- package/dist/runtime-descriptor.js +2 -0
- package/dist/runtime-presentation.d.ts +38 -0
- package/dist/runtime-presentation.js +441 -0
- package/dist/runtime-state-publisher.js +71 -15
- package/dist/turn-protocol.js +13 -0
- package/dist/types.d.ts +36 -1
- package/dist/types.js +9 -0
- package/package.json +1 -1
package/dist/agent-session.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { redactAgentSessionSnapshotForConversation } from './runtime-presentation.js';
|
|
1
2
|
function listDescriptorControls(runtime) {
|
|
2
3
|
const descriptor = runtime?.runtimeDescriptor;
|
|
3
4
|
return [
|
|
@@ -104,7 +105,7 @@ export function buildAgentSessionSnapshot(input) {
|
|
|
104
105
|
const executionMode = input.sessionState?.executionMode
|
|
105
106
|
?? input.sessionConfig?.executionMode;
|
|
106
107
|
const controlState = buildControlState(input);
|
|
107
|
-
|
|
108
|
+
const snapshot = {
|
|
108
109
|
conversationId: input.conversationId,
|
|
109
110
|
agentId: input.agentId,
|
|
110
111
|
clientType: input.sessionConfig?.clientType
|
|
@@ -146,4 +147,5 @@ export function buildAgentSessionSnapshot(input) {
|
|
|
146
147
|
?? input.sessionConfig?.updatedAt
|
|
147
148
|
?? input.runtime?.updatedAt,
|
|
148
149
|
};
|
|
150
|
+
return redactAgentSessionSnapshotForConversation(input.runtime?.runtimeDescriptor, snapshot);
|
|
149
151
|
}
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export { AGENT_CAPABILITIES, CLAUDE_PERMISSION_MODE_OPTIONS, } from './types.js';
|
|
2
2
|
export { resolveCanonBaseUrl } from './base-url.js';
|
|
3
3
|
export { DEFAULT_BASE_URL, DEFAULT_STREAM_URL, DEFAULT_RTDB_URL, FIREBASE_WEB_API_KEY } from './constants.js';
|
|
4
|
-
export type { AddMemberResult, AgentCapabilities, AgentClientType, AgentSessionSnapshot, AgentRuntime, CanonControlAvailability, CanonControlDescriptor, CanonControlLiveBehavior, CanonControlSelectionPolicy, CanonControlValue, CanonContact, CanonContactRequest, CanonContactRequestStatus, CanonResolveAdmissionResult, ContactAddedPayload, ContactApprovedPayload, ContactRemovedPayload, ContactRequestPayload, ContactSource, ResolvedAdmissionState, ResolvedAdmissionTargetSummary, ResolvedTargetAdmissionPayload, CanonStreamEvent, CreateContactRequestResult, MediaAttachment, MediaAttachmentKind, ModelOption, PermissionModeOption, CanonRuntimeDescriptor, CanonRuntimeActionAvailability, CanonRuntimeActionCategory, CanonRuntimeActionDescriptor, CanonRuntimeActionDispatch, CanonRuntimeActionPlacement, CanonRuntimeCommandArgumentChoice, CanonRuntimeCommandArgumentDescriptor, CanonRuntimeCommandArgumentKind, CanonRuntimeCommandDescriptor, CanonRuntimeDetailTier, CanonRuntimeExecutionMetadata, CanonRuntimeProvenance, CanonRuntimeActivityItem, CanonRuntimeActivityKind, CanonRuntimeActivityStatus, CanonRuntimeFact, CanonRuntimeFactGroup, CanonRuntimeInventory, CanonRuntimeInventoryEntry, CanonRuntimePrimitiveId, CanonRuntimeStreamingMode, CanonRuntimeStatusItem, CanonRuntimeSurfaceMode, CanonWorkspaceRootMetadata, RuntimeUpdatedPayload, RuntimeInfoPayload, RuntimeControlError, RuntimeControlState, RuntimeControlValueSource, ResolvedAdmission, SessionConfig, TurnUpdatedPayload, WorkspaceOption, WorkspaceOptionSource, } from './types.js';
|
|
4
|
+
export type { AddMemberResult, AgentCapabilities, AgentClientType, AgentSessionSnapshot, AgentRuntime, CanonControlAvailability, CanonControlDescriptor, CanonControlLiveBehavior, CanonControlSelectionPolicy, CanonControlValue, CanonContact, CanonContactRequest, CanonContactRequestStatus, CanonResolveAdmissionResult, ContactAddedPayload, ContactApprovedPayload, ContactRemovedPayload, ContactRequestPayload, ContactSource, ResolvedAdmissionState, ResolvedAdmissionTargetSummary, ResolvedTargetAdmissionPayload, CanonStreamEvent, CreateContactRequestResult, MediaAttachment, MediaAttachmentKind, ModelOption, PermissionModeOption, CanonRuntimeDescriptor, CanonRuntimeActionAvailability, CanonRuntimeActionCategory, CanonRuntimeActionDescriptor, CanonRuntimeActionDispatch, CanonRuntimeActionPlacement, CanonRuntimeCommandArgumentChoice, CanonRuntimeCommandArgumentDescriptor, CanonRuntimeCommandArgumentKind, CanonRuntimeCommandDescriptor, CanonRuntimeDetailTier, CanonRuntimeExecutionMetadata, CanonRuntimePresentationField, CanonRuntimePresentationHint, CanonRuntimePresentationPolicy, CanonRuntimePresentationPreset, CanonRuntimeVisibility, CanonRuntimeProvenance, CanonRuntimeActivityItem, CanonRuntimeActivityKind, CanonRuntimeActivityStatus, CanonRuntimeFact, CanonRuntimeFactGroup, CanonRuntimeInventory, CanonRuntimeInventoryEntry, CanonRuntimePrimitiveId, CanonRuntimeStreamingMode, CanonRuntimeStatusItem, CanonRuntimeSurfaceMode, CanonWorkspaceRootMetadata, RuntimeUpdatedPayload, RuntimeInfoPayload, RuntimeControlError, RuntimeControlState, RuntimeControlValueSource, ResolvedAdmission, SessionConfig, TurnUpdatedPayload, WorkspaceOption, WorkspaceOptionSource, } from './types.js';
|
|
5
|
+
export { DEFAULT_FIRST_PARTY_RUNTIME_PRESENTATION, RUNTIME_PRESENTATION_FIELDS, buildRuntimePresentationPolicy, getRuntimePresentationHint, isRuntimePresentationField, isRuntimePresentationFieldHidden, redactAgentSessionSnapshotForConversation, redactExecutionMetadataForConversation, redactRuntimeDescriptorForConversation, redactRuntimeInfoForConversation, } from './runtime-presentation.js';
|
|
5
6
|
export { buildRuntimeProvenance, resolveRuntimeProvenance, } from './provenance.js';
|
|
6
7
|
export { EXECUTION_ENVIRONMENT_MODES, isExecutionEnvironmentMode, } from './execution-environment-mode.js';
|
|
7
8
|
export type { ExecutionEnvironmentMode } from './execution-environment-mode.js';
|
|
@@ -16,5 +17,5 @@ export type { DeliveryIntent, InboundDisposition, RuntimeCapabilities, TriggerDe
|
|
|
16
17
|
export { buildApprovalReply, buildApprovalRequest, buildApprovalOutcome, generateApprovalId, parseTextApprovalReply, redactSecrets, } from './approval-format.js';
|
|
17
18
|
export type { ApprovalRequestCategory, ApprovalRequestDetail, ApprovalRequestMetadata, ApprovalNativeRequestMetadata, ApprovalRisk, ApprovalReplyMetadata, ApprovalOutcomeMetadata, SessionRule, ApprovalResult, ApprovalConfig, } from './approval-types.js';
|
|
18
19
|
export { DEFAULT_APPROVAL_CONFIG, parseApprovalRequestMetadata, parseApprovalReplyMetadata, parseSessionRule, } from './approval-types.js';
|
|
19
|
-
export { buildPlanApprovalReply, buildPlanApprovalRequest, buildQuestionReply, buildQuestionRequest, } from './runtime-cards.js';
|
|
20
|
-
export type { ClaudeQuestionMetadata, ClaudeQuestionReplyMetadata, PlanApprovalMetadata, PlanApprovalReplyMetadata, RuntimeQuestionDefinition, RuntimeQuestionOption, } from './runtime-cards.js';
|
|
20
|
+
export { buildRuntimeInputOutcome, buildRuntimeInputReply, buildRuntimeInputRequest, buildPlanApprovalReply, buildPlanApprovalRequest, buildQuestionReply, buildQuestionRequest, parseRuntimeInputOutcomeMetadata, parseRuntimeInputReplyMetadata, parseRuntimeInputRequestMetadata, } from './runtime-cards.js';
|
|
21
|
+
export type { ClaudeQuestionMetadata, ClaudeQuestionReplyMetadata, PlanApprovalMetadata, PlanApprovalReplyMetadata, RuntimeInputChoice, RuntimeInputKind, RuntimeInputNativeMetadata, RuntimeInputOutcomeMetadata, RuntimeInputReplyMetadata, RuntimeInputReplyStatus, RuntimeInputRequestMetadata, RuntimeInputResolutionStatus, RuntimeQuestionDefinition, RuntimeQuestionOption, } from './runtime-cards.js';
|
package/dist/browser.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { AGENT_CAPABILITIES, CLAUDE_PERMISSION_MODE_OPTIONS, } from './types.js';
|
|
2
2
|
export { resolveCanonBaseUrl } from './base-url.js';
|
|
3
3
|
export { DEFAULT_BASE_URL, DEFAULT_STREAM_URL, DEFAULT_RTDB_URL, FIREBASE_WEB_API_KEY } from './constants.js';
|
|
4
|
+
export { DEFAULT_FIRST_PARTY_RUNTIME_PRESENTATION, RUNTIME_PRESENTATION_FIELDS, buildRuntimePresentationPolicy, getRuntimePresentationHint, isRuntimePresentationField, isRuntimePresentationFieldHidden, redactAgentSessionSnapshotForConversation, redactExecutionMetadataForConversation, redactRuntimeDescriptorForConversation, redactRuntimeInfoForConversation, } from './runtime-presentation.js';
|
|
4
5
|
export { buildRuntimeProvenance, resolveRuntimeProvenance, } from './provenance.js';
|
|
5
6
|
export { EXECUTION_ENVIRONMENT_MODES, isExecutionEnvironmentMode, } from './execution-environment-mode.js';
|
|
6
7
|
export { buildSelfContextPromptLines, normalizeSelfContexts, } from './self-context.js';
|
|
@@ -10,4 +11,4 @@ export { buildParticipationHistorySnapshot, buildParticipationHistorySnapshots,
|
|
|
10
11
|
export { DEFAULT_RUNTIME_CAPABILITIES, FINAL_MESSAGE_HANDOFF_MS, isTurnOpen, normalizeTurnMetadata, normalizeTurnState, resolveTurnMessageSemantics, shouldPromoteConversationMessage, shouldTriggerAgentTurn, } from './turn-protocol.js';
|
|
11
12
|
export { buildApprovalReply, buildApprovalRequest, buildApprovalOutcome, generateApprovalId, parseTextApprovalReply, redactSecrets, } from './approval-format.js';
|
|
12
13
|
export { DEFAULT_APPROVAL_CONFIG, parseApprovalRequestMetadata, parseApprovalReplyMetadata, parseSessionRule, } from './approval-types.js';
|
|
13
|
-
export { buildPlanApprovalReply, buildPlanApprovalRequest, buildQuestionReply, buildQuestionRequest, } from './runtime-cards.js';
|
|
14
|
+
export { buildRuntimeInputOutcome, buildRuntimeInputReply, buildRuntimeInputRequest, buildPlanApprovalReply, buildPlanApprovalRequest, buildQuestionReply, buildQuestionRequest, parseRuntimeInputOutcomeMetadata, parseRuntimeInputReplyMetadata, parseRuntimeInputRequestMetadata, } from './runtime-cards.js';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { AGENT_CAPABILITIES, CLAUDE_PERMISSION_MODE_OPTIONS, } from './types.js';
|
|
2
|
-
export type { AddMemberResult, AgentCapabilities, AgentClientType, CanonControlAvailability, CanonControlDescriptor, CanonControlLiveBehavior, CanonControlSelectionPolicy, CanonControlValue, CanonContact, CanonContactRequest, CanonContactRequestStatus, CanonGroupContext, CanonGroupContextMode, CanonKnownRecentParticipant, CanonMembershipChange, CanonResolveAdmissionResult, ConversationUpdatedPayload, ContactAddedPayload, ContactApprovedPayload, ContactCardPayload, ContactRemovedPayload, ContactRequestPayload, ContactSource, ResolvedAdmissionState, ResolvedAdmissionTargetSummary, ResolvedTargetAdmissionPayload, CanonMessage, CanonRuntimeProvenance, CanonConversation, CanonMessagesPage, CreateContactRequestResult, AgentContext, CanonStreamEvent, AgentSessionSnapshot, ResolvedAdmission, MediaAttachment, MediaAttachmentKind, MessageCreatedPayload, TypingPayload, PresencePayload, RuntimeUpdatedPayload, TurnUpdatedPayload, SendMessageOptions, CreateConversationOptions, RegistrationInput, RegistrationResult, RegistrationStatus, StreamingStatus, SetStreamingOptions, SessionControl, SessionState, SessionConfig, AgentRuntime, CanonRuntimeDescriptor, CanonRuntimeActionAvailability, CanonRuntimeActionCategory, CanonRuntimeActionDescriptor, CanonRuntimeActionDispatch, CanonRuntimeActionPlacement, CanonRuntimeCommandArgumentChoice, CanonRuntimeCommandArgumentDescriptor, CanonRuntimeCommandArgumentKind, CanonRuntimeCommandDescriptor, CanonRuntimeDetailTier, CanonRuntimeExecutionMetadata, CanonRuntimeActivityItem, CanonRuntimeActivityKind, CanonRuntimeActivityStatus, CanonRuntimeFact, CanonRuntimeFactGroup, CanonRuntimeInventory, CanonRuntimeInventoryEntry, CanonRuntimePrimitiveId, CanonRuntimeStreamingMode, CanonRuntimeStatusItem, CanonRuntimeSurfaceMode, CanonWorkspaceRootMetadata, ModelOption, PermissionModeOption, RuntimeInfoPayload, RuntimeControlError, RuntimeControlState, RuntimeControlValueSource, WorkspaceOption, WorkspaceOptionSource, } from './types.js';
|
|
2
|
+
export type { AddMemberResult, AgentCapabilities, AgentClientType, CanonControlAvailability, CanonControlDescriptor, CanonControlLiveBehavior, CanonControlSelectionPolicy, CanonControlValue, CanonContact, CanonContactRequest, CanonContactRequestStatus, CanonGroupContext, CanonGroupContextMode, CanonKnownRecentParticipant, CanonMembershipChange, CanonResolveAdmissionResult, ConversationUpdatedPayload, ContactAddedPayload, ContactApprovedPayload, ContactCardPayload, ContactRemovedPayload, ContactRequestPayload, ContactSource, ResolvedAdmissionState, ResolvedAdmissionTargetSummary, ResolvedTargetAdmissionPayload, CanonMessage, CanonRuntimeProvenance, CanonConversation, CanonMessagesPage, CreateContactRequestResult, AgentContext, CanonStreamEvent, AgentSessionSnapshot, ResolvedAdmission, MediaAttachment, MediaAttachmentKind, MessageCreatedPayload, TypingPayload, PresencePayload, RuntimeUpdatedPayload, TurnUpdatedPayload, SendMessageOptions, CreateConversationOptions, RegistrationInput, RegistrationResult, RegistrationStatus, StreamingStatus, SetStreamingOptions, SessionControl, SessionState, SessionConfig, AgentRuntime, CanonRuntimeDescriptor, CanonRuntimeActionAvailability, CanonRuntimeActionCategory, CanonRuntimeActionDescriptor, CanonRuntimeActionDispatch, CanonRuntimeActionPlacement, CanonRuntimeCommandArgumentChoice, CanonRuntimeCommandArgumentDescriptor, CanonRuntimeCommandArgumentKind, CanonRuntimeCommandDescriptor, CanonRuntimeDetailTier, CanonRuntimeExecutionMetadata, CanonRuntimePresentationField, CanonRuntimePresentationHint, CanonRuntimePresentationPolicy, CanonRuntimePresentationPreset, CanonRuntimeVisibility, CanonRuntimeActivityItem, CanonRuntimeActivityKind, CanonRuntimeActivityStatus, CanonRuntimeFact, CanonRuntimeFactGroup, CanonRuntimeInventory, CanonRuntimeInventoryEntry, CanonRuntimePrimitiveId, CanonRuntimeStreamingMode, CanonRuntimeStatusItem, CanonRuntimeSurfaceMode, CanonWorkspaceRootMetadata, ModelOption, PermissionModeOption, RuntimeInfoPayload, RuntimeControlError, RuntimeControlState, RuntimeControlValueSource, WorkspaceOption, WorkspaceOptionSource, } from './types.js';
|
|
3
|
+
export { DEFAULT_FIRST_PARTY_RUNTIME_PRESENTATION, RUNTIME_PRESENTATION_FIELDS, buildRuntimePresentationPolicy, getRuntimePresentationHint, isRuntimePresentationField, isRuntimePresentationFieldHidden, redactAgentRuntimeForConversation, redactAgentSessionSnapshotForConversation, redactExecutionMetadataForConversation, redactRuntimeActivityItemForConversation, redactRuntimeDescriptorForConversation, redactRuntimeInfoForConversation, redactSessionStateForConversation, } from './runtime-presentation.js';
|
|
3
4
|
export { buildRuntimeProvenance, resolveRuntimeProvenance, } from './provenance.js';
|
|
4
5
|
export type { CanonSelfContext, CanonSelfContextType, SelfContextPromptRenderOptions, SendContextualMessageOptions, SendContextualMessageResult, SendContextualSelfContextInput, } from './self-context.js';
|
|
5
6
|
export { buildSelfContextPromptLines, normalizeSelfContexts, resolveMessageActiveSelfContextId, selectActiveSelfContexts, } from './self-context.js';
|
|
@@ -19,8 +20,8 @@ export { ApprovalManager } from './approval-manager.js';
|
|
|
19
20
|
export { generateApprovalId, buildApprovalRequest, buildApprovalReply, buildApprovalOutcome, parseTextApprovalReply, redactSecrets, } from './approval-format.js';
|
|
20
21
|
export { DEFAULT_APPROVAL_CONFIG, parseApprovalRequestMetadata, parseApprovalReplyMetadata, parseSessionRule, } from './approval-types.js';
|
|
21
22
|
export type { ApprovalRequestCategory, ApprovalRequestDetail, ApprovalRequestMetadata, ApprovalNativeRequestMetadata, ApprovalRisk, ApprovalReplyMetadata, ApprovalOutcomeMetadata, SessionRule, ApprovalResult, ApprovalConfig, } from './approval-types.js';
|
|
22
|
-
export { buildPlanApprovalReply, buildPlanApprovalRequest, buildQuestionReply, buildQuestionRequest, } from './runtime-cards.js';
|
|
23
|
-
export type { ClaudeQuestionMetadata, ClaudeQuestionReplyMetadata, PlanApprovalMetadata, PlanApprovalReplyMetadata, RuntimeQuestionDefinition, RuntimeQuestionOption, } from './runtime-cards.js';
|
|
23
|
+
export { buildRuntimeInputOutcome, buildRuntimeInputReply, buildRuntimeInputRequest, buildPlanApprovalReply, buildPlanApprovalRequest, buildQuestionReply, buildQuestionRequest, parseRuntimeInputOutcomeMetadata, parseRuntimeInputReplyMetadata, parseRuntimeInputRequestMetadata, } from './runtime-cards.js';
|
|
24
|
+
export type { ClaudeQuestionMetadata, ClaudeQuestionReplyMetadata, PlanApprovalMetadata, PlanApprovalReplyMetadata, RuntimeInputChoice, RuntimeInputKind, RuntimeInputNativeMetadata, RuntimeInputOutcomeMetadata, RuntimeInputReplyMetadata, RuntimeInputReplyStatus, RuntimeInputRequestMetadata, RuntimeInputResolutionStatus, RuntimeQuestionDefinition, RuntimeQuestionOption, } from './runtime-cards.js';
|
|
24
25
|
export { createStreamingHelper } from './streaming.js';
|
|
25
26
|
export type { RTDBHandle, RTDBRef, ServerTimestamp, StreamingHelperOptions, StreamingNode } from './streaming.js';
|
|
26
27
|
export { clearPendingRegistration, getOrCreatePendingRegistration, loadPendingRegistrations, loadProfiles, savePendingRegistrations, saveProfiles, updatePendingRegistration, upsertAgentProfile, isProfileLocked, acquireLock, releaseLock, isProcessAlive, CANON_DIR, AGENTS_PATH, LOCKS_DIR, } from './agent-profiles.js';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Types
|
|
2
2
|
export { AGENT_CAPABILITIES, CLAUDE_PERMISSION_MODE_OPTIONS, } from './types.js';
|
|
3
|
+
export { DEFAULT_FIRST_PARTY_RUNTIME_PRESENTATION, RUNTIME_PRESENTATION_FIELDS, buildRuntimePresentationPolicy, getRuntimePresentationHint, isRuntimePresentationField, isRuntimePresentationFieldHidden, redactAgentRuntimeForConversation, redactAgentSessionSnapshotForConversation, redactExecutionMetadataForConversation, redactRuntimeActivityItemForConversation, redactRuntimeDescriptorForConversation, redactRuntimeInfoForConversation, redactSessionStateForConversation, } from './runtime-presentation.js';
|
|
3
4
|
export { buildRuntimeProvenance, resolveRuntimeProvenance, } from './provenance.js';
|
|
4
5
|
export { buildSelfContextPromptLines, normalizeSelfContexts, resolveMessageActiveSelfContextId, selectActiveSelfContexts, } from './self-context.js';
|
|
5
6
|
export { buildConfiguredWorkspaceOptionsWithRoots, buildPublicWorkspaceRoots, buildWorkspaceRootId, discoverWorkspaceProjects, } from './workspace-discovery.js';
|
|
@@ -18,7 +19,7 @@ export { ackRegistrationApproval, registerAndWaitForApproval, submitRegistration
|
|
|
18
19
|
export { ApprovalManager } from './approval-manager.js';
|
|
19
20
|
export { generateApprovalId, buildApprovalRequest, buildApprovalReply, buildApprovalOutcome, parseTextApprovalReply, redactSecrets, } from './approval-format.js';
|
|
20
21
|
export { DEFAULT_APPROVAL_CONFIG, parseApprovalRequestMetadata, parseApprovalReplyMetadata, parseSessionRule, } from './approval-types.js';
|
|
21
|
-
export { buildPlanApprovalReply, buildPlanApprovalRequest, buildQuestionReply, buildQuestionRequest, } from './runtime-cards.js';
|
|
22
|
+
export { buildRuntimeInputOutcome, buildRuntimeInputReply, buildRuntimeInputRequest, buildPlanApprovalReply, buildPlanApprovalRequest, buildQuestionReply, buildQuestionRequest, parseRuntimeInputOutcomeMetadata, parseRuntimeInputReplyMetadata, parseRuntimeInputRequestMetadata, } from './runtime-cards.js';
|
|
22
23
|
// Streaming (RTDB helpers)
|
|
23
24
|
export { createStreamingHelper } from './streaming.js';
|
|
24
25
|
// Agent profiles (loading, locking, resolution)
|
package/dist/runtime-cards.d.ts
CHANGED
|
@@ -35,6 +35,49 @@ export interface PlanApprovalReplyMetadata {
|
|
|
35
35
|
decision: 'approve' | 'revise';
|
|
36
36
|
feedback?: string;
|
|
37
37
|
}
|
|
38
|
+
export type RuntimeInputKind = 'clarify' | 'sudo' | 'secret';
|
|
39
|
+
export type RuntimeInputReplyStatus = 'submitted' | 'cancelled';
|
|
40
|
+
export type RuntimeInputResolutionStatus = RuntimeInputReplyStatus | 'timeout';
|
|
41
|
+
export interface RuntimeInputChoice {
|
|
42
|
+
label: string;
|
|
43
|
+
value?: string;
|
|
44
|
+
description?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface RuntimeInputNativeMetadata {
|
|
47
|
+
runtime?: string;
|
|
48
|
+
method?: string;
|
|
49
|
+
requestId?: string;
|
|
50
|
+
sessionKey?: string;
|
|
51
|
+
turnId?: string;
|
|
52
|
+
handles?: Record<string, string>;
|
|
53
|
+
}
|
|
54
|
+
export interface RuntimeInputRequestMetadata {
|
|
55
|
+
type: 'runtime_input_request';
|
|
56
|
+
inputId: string;
|
|
57
|
+
kind: RuntimeInputKind;
|
|
58
|
+
prompt: string;
|
|
59
|
+
title?: string;
|
|
60
|
+
choices?: RuntimeInputChoice[];
|
|
61
|
+
secretName?: string;
|
|
62
|
+
native?: RuntimeInputNativeMetadata;
|
|
63
|
+
expiresAt: string;
|
|
64
|
+
sensitive?: boolean;
|
|
65
|
+
}
|
|
66
|
+
export interface RuntimeInputReplyMetadata {
|
|
67
|
+
type: 'runtime_input_reply';
|
|
68
|
+
inputId: string;
|
|
69
|
+
kind?: RuntimeInputKind;
|
|
70
|
+
status: RuntimeInputReplyStatus;
|
|
71
|
+
answerSummary?: string;
|
|
72
|
+
sensitive?: boolean;
|
|
73
|
+
}
|
|
74
|
+
export interface RuntimeInputOutcomeMetadata {
|
|
75
|
+
type: 'runtime_input_outcome';
|
|
76
|
+
inputId: string;
|
|
77
|
+
kind?: RuntimeInputKind;
|
|
78
|
+
status: RuntimeInputResolutionStatus;
|
|
79
|
+
reason?: 'submitted' | 'cancelled' | 'timeout' | 'expired' | 'interrupted';
|
|
80
|
+
}
|
|
38
81
|
export declare function buildQuestionRequest(questionId: string, questions: RuntimeQuestionDefinition[]): {
|
|
39
82
|
text: string;
|
|
40
83
|
metadata: ClaudeQuestionMetadata;
|
|
@@ -51,3 +94,25 @@ export declare function buildPlanApprovalReply(planId: string, decision: 'approv
|
|
|
51
94
|
text: string;
|
|
52
95
|
metadata: PlanApprovalReplyMetadata;
|
|
53
96
|
};
|
|
97
|
+
export declare function buildRuntimeInputRequest(inputId: string, input: Omit<RuntimeInputRequestMetadata, 'type' | 'inputId'>): {
|
|
98
|
+
text: string;
|
|
99
|
+
metadata: RuntimeInputRequestMetadata;
|
|
100
|
+
};
|
|
101
|
+
export declare function buildRuntimeInputReply(inputId: string, status: RuntimeInputReplyStatus, details?: {
|
|
102
|
+
kind?: RuntimeInputKind;
|
|
103
|
+
answerSummary?: string;
|
|
104
|
+
sensitive?: boolean;
|
|
105
|
+
}): {
|
|
106
|
+
text: string;
|
|
107
|
+
metadata: RuntimeInputReplyMetadata;
|
|
108
|
+
};
|
|
109
|
+
export declare function buildRuntimeInputOutcome(inputId: string, status: RuntimeInputResolutionStatus, details?: {
|
|
110
|
+
kind?: RuntimeInputKind;
|
|
111
|
+
reason?: RuntimeInputOutcomeMetadata['reason'];
|
|
112
|
+
}): {
|
|
113
|
+
text: string;
|
|
114
|
+
metadata: RuntimeInputOutcomeMetadata;
|
|
115
|
+
};
|
|
116
|
+
export declare function parseRuntimeInputRequestMetadata(value: unknown): RuntimeInputRequestMetadata | null;
|
|
117
|
+
export declare function parseRuntimeInputReplyMetadata(value: unknown): RuntimeInputReplyMetadata | null;
|
|
118
|
+
export declare function parseRuntimeInputOutcomeMetadata(value: unknown): RuntimeInputOutcomeMetadata | null;
|
package/dist/runtime-cards.js
CHANGED
|
@@ -1,3 +1,73 @@
|
|
|
1
|
+
function isRecord(value) {
|
|
2
|
+
return Boolean(value && typeof value === 'object' && !Array.isArray(value));
|
|
3
|
+
}
|
|
4
|
+
function normalizeString(value, maxLength) {
|
|
5
|
+
if (typeof value !== 'string')
|
|
6
|
+
return null;
|
|
7
|
+
const trimmed = value.trim();
|
|
8
|
+
if (!trimmed || trimmed.length > maxLength)
|
|
9
|
+
return null;
|
|
10
|
+
return trimmed;
|
|
11
|
+
}
|
|
12
|
+
function normalizeRuntimeInputKind(value) {
|
|
13
|
+
return value === 'clarify' || value === 'sudo' || value === 'secret' ? value : null;
|
|
14
|
+
}
|
|
15
|
+
function normalizeRuntimeInputReplyStatus(value) {
|
|
16
|
+
return value === 'submitted' || value === 'cancelled' ? value : null;
|
|
17
|
+
}
|
|
18
|
+
function normalizeRuntimeInputResolutionStatus(value) {
|
|
19
|
+
return value === 'submitted' || value === 'cancelled' || value === 'timeout' ? value : null;
|
|
20
|
+
}
|
|
21
|
+
function normalizeRuntimeInputChoices(value) {
|
|
22
|
+
if (!Array.isArray(value))
|
|
23
|
+
return undefined;
|
|
24
|
+
const choices = value.slice(0, 12).flatMap((entry) => {
|
|
25
|
+
if (!isRecord(entry))
|
|
26
|
+
return [];
|
|
27
|
+
const label = normalizeString(entry.label, 120);
|
|
28
|
+
if (!label)
|
|
29
|
+
return [];
|
|
30
|
+
const choice = { label };
|
|
31
|
+
const choiceValue = normalizeString(entry.value, 200);
|
|
32
|
+
const description = normalizeString(entry.description, 300);
|
|
33
|
+
if (choiceValue)
|
|
34
|
+
choice.value = choiceValue;
|
|
35
|
+
if (description)
|
|
36
|
+
choice.description = description;
|
|
37
|
+
return [choice];
|
|
38
|
+
});
|
|
39
|
+
return choices.length > 0 ? choices : undefined;
|
|
40
|
+
}
|
|
41
|
+
function normalizeRuntimeInputNative(value) {
|
|
42
|
+
if (!isRecord(value))
|
|
43
|
+
return undefined;
|
|
44
|
+
const native = {};
|
|
45
|
+
for (const key of ['runtime', 'method', 'requestId', 'sessionKey', 'turnId']) {
|
|
46
|
+
const normalized = normalizeString(value[key], 256);
|
|
47
|
+
if (normalized)
|
|
48
|
+
native[key] = normalized;
|
|
49
|
+
}
|
|
50
|
+
if (isRecord(value.handles)) {
|
|
51
|
+
const handles = {};
|
|
52
|
+
for (const [key, raw] of Object.entries(value.handles).slice(0, 16)) {
|
|
53
|
+
if (!/^[a-zA-Z0-9_.:-]{1,80}$/.test(key))
|
|
54
|
+
continue;
|
|
55
|
+
const normalized = normalizeString(raw, 256);
|
|
56
|
+
if (normalized)
|
|
57
|
+
handles[key] = normalized;
|
|
58
|
+
}
|
|
59
|
+
if (Object.keys(handles).length > 0)
|
|
60
|
+
native.handles = handles;
|
|
61
|
+
}
|
|
62
|
+
return Object.keys(native).length > 0 ? native : undefined;
|
|
63
|
+
}
|
|
64
|
+
function assertNoSensitiveRuntimeInputPayload(value) {
|
|
65
|
+
return !('value' in value)
|
|
66
|
+
&& !('answer' in value)
|
|
67
|
+
&& !('password' in value)
|
|
68
|
+
&& !('secret' in value)
|
|
69
|
+
&& !('rawValue' in value);
|
|
70
|
+
}
|
|
1
71
|
export function buildQuestionRequest(questionId, questions) {
|
|
2
72
|
const text = questions.length === 1
|
|
3
73
|
? questions[0]?.question || 'Question'
|
|
@@ -43,3 +113,131 @@ export function buildPlanApprovalReply(planId, decision, feedback) {
|
|
|
43
113
|
},
|
|
44
114
|
};
|
|
45
115
|
}
|
|
116
|
+
export function buildRuntimeInputRequest(inputId, input) {
|
|
117
|
+
const title = input.title?.trim() || (input.kind === 'sudo'
|
|
118
|
+
? 'Sudo password required'
|
|
119
|
+
: input.kind === 'secret'
|
|
120
|
+
? 'Secret required'
|
|
121
|
+
: 'Input required');
|
|
122
|
+
return {
|
|
123
|
+
text: title,
|
|
124
|
+
metadata: {
|
|
125
|
+
type: 'runtime_input_request',
|
|
126
|
+
inputId,
|
|
127
|
+
kind: input.kind,
|
|
128
|
+
prompt: input.prompt.slice(0, 1000),
|
|
129
|
+
title: title.slice(0, 120),
|
|
130
|
+
...(input.choices?.length ? { choices: input.choices.slice(0, 12) } : {}),
|
|
131
|
+
...(input.secretName ? { secretName: input.secretName.slice(0, 120) } : {}),
|
|
132
|
+
...(input.native ? { native: input.native } : {}),
|
|
133
|
+
expiresAt: input.expiresAt,
|
|
134
|
+
...(input.sensitive ? { sensitive: true } : {}),
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
export function buildRuntimeInputReply(inputId, status, details) {
|
|
139
|
+
const answerSummary = details?.sensitive ? undefined : details?.answerSummary?.trim().slice(0, 500);
|
|
140
|
+
return {
|
|
141
|
+
text: status === 'submitted' ? 'Submitted' : 'Cancelled',
|
|
142
|
+
metadata: {
|
|
143
|
+
type: 'runtime_input_reply',
|
|
144
|
+
inputId,
|
|
145
|
+
...(details?.kind ? { kind: details.kind } : {}),
|
|
146
|
+
status,
|
|
147
|
+
...(answerSummary ? { answerSummary } : {}),
|
|
148
|
+
...(details?.sensitive ? { sensitive: true } : {}),
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
export function buildRuntimeInputOutcome(inputId, status, details) {
|
|
153
|
+
return {
|
|
154
|
+
text: status === 'timeout'
|
|
155
|
+
? 'Input request expired'
|
|
156
|
+
: status === 'cancelled'
|
|
157
|
+
? 'Input request cancelled'
|
|
158
|
+
: 'Input request resolved',
|
|
159
|
+
metadata: {
|
|
160
|
+
type: 'runtime_input_outcome',
|
|
161
|
+
inputId,
|
|
162
|
+
...(details?.kind ? { kind: details.kind } : {}),
|
|
163
|
+
status,
|
|
164
|
+
...(details?.reason ? { reason: details.reason } : {}),
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
export function parseRuntimeInputRequestMetadata(value) {
|
|
169
|
+
if (!isRecord(value) || value.type !== 'runtime_input_request')
|
|
170
|
+
return null;
|
|
171
|
+
if (!assertNoSensitiveRuntimeInputPayload(value))
|
|
172
|
+
return null;
|
|
173
|
+
const inputId = normalizeString(value.inputId, 128);
|
|
174
|
+
const kind = normalizeRuntimeInputKind(value.kind);
|
|
175
|
+
const prompt = normalizeString(value.prompt, 1000);
|
|
176
|
+
const expiresAt = normalizeString(value.expiresAt, 128);
|
|
177
|
+
if (!inputId || !kind || !prompt || !expiresAt)
|
|
178
|
+
return null;
|
|
179
|
+
const expiresMs = Date.parse(expiresAt);
|
|
180
|
+
if (!Number.isFinite(expiresMs))
|
|
181
|
+
return null;
|
|
182
|
+
const title = normalizeString(value.title, 120) ?? undefined;
|
|
183
|
+
const choices = normalizeRuntimeInputChoices(value.choices);
|
|
184
|
+
const secretName = normalizeString(value.secretName, 120) ?? undefined;
|
|
185
|
+
const native = normalizeRuntimeInputNative(value.native);
|
|
186
|
+
return {
|
|
187
|
+
type: 'runtime_input_request',
|
|
188
|
+
inputId,
|
|
189
|
+
kind,
|
|
190
|
+
prompt,
|
|
191
|
+
...(title ? { title } : {}),
|
|
192
|
+
...(choices ? { choices } : {}),
|
|
193
|
+
...(secretName ? { secretName } : {}),
|
|
194
|
+
...(native ? { native } : {}),
|
|
195
|
+
expiresAt: new Date(expiresMs).toISOString(),
|
|
196
|
+
...(value.sensitive === true ? { sensitive: true } : {}),
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
export function parseRuntimeInputReplyMetadata(value) {
|
|
200
|
+
if (!isRecord(value) || value.type !== 'runtime_input_reply')
|
|
201
|
+
return null;
|
|
202
|
+
if (!assertNoSensitiveRuntimeInputPayload(value))
|
|
203
|
+
return null;
|
|
204
|
+
const inputId = normalizeString(value.inputId, 128);
|
|
205
|
+
const status = normalizeRuntimeInputReplyStatus(value.status);
|
|
206
|
+
if (!inputId || !status)
|
|
207
|
+
return null;
|
|
208
|
+
const kind = normalizeRuntimeInputKind(value.kind) ?? undefined;
|
|
209
|
+
const answerSummary = value.sensitive === true ? undefined : normalizeString(value.answerSummary, 500) ?? undefined;
|
|
210
|
+
return {
|
|
211
|
+
type: 'runtime_input_reply',
|
|
212
|
+
inputId,
|
|
213
|
+
...(kind ? { kind } : {}),
|
|
214
|
+
status,
|
|
215
|
+
...(answerSummary ? { answerSummary } : {}),
|
|
216
|
+
...(value.sensitive === true ? { sensitive: true } : {}),
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
export function parseRuntimeInputOutcomeMetadata(value) {
|
|
220
|
+
if (!isRecord(value) || value.type !== 'runtime_input_outcome')
|
|
221
|
+
return null;
|
|
222
|
+
if (!assertNoSensitiveRuntimeInputPayload(value))
|
|
223
|
+
return null;
|
|
224
|
+
const inputId = normalizeString(value.inputId, 128);
|
|
225
|
+
const status = normalizeRuntimeInputResolutionStatus(value.status);
|
|
226
|
+
if (!inputId || !status)
|
|
227
|
+
return null;
|
|
228
|
+
const kind = normalizeRuntimeInputKind(value.kind) ?? undefined;
|
|
229
|
+
const reason = value.reason === 'submitted'
|
|
230
|
+
|| value.reason === 'cancelled'
|
|
231
|
+
|| value.reason === 'timeout'
|
|
232
|
+
|| value.reason === 'expired'
|
|
233
|
+
|| value.reason === 'interrupted'
|
|
234
|
+
? value.reason
|
|
235
|
+
: undefined;
|
|
236
|
+
return {
|
|
237
|
+
type: 'runtime_input_outcome',
|
|
238
|
+
inputId,
|
|
239
|
+
...(kind ? { kind } : {}),
|
|
240
|
+
status,
|
|
241
|
+
...(reason ? { reason } : {}),
|
|
242
|
+
};
|
|
243
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ExecutionEnvironmentMode } from './execution-environment-mode.js';
|
|
2
2
|
import { type AgentClientType, type CanonControlDescriptor, type CanonRuntimeActionDescriptor, type CanonRuntimeCommandDescriptor, type CanonRuntimeDescriptor, type CanonRuntimeStreamingMode, type CanonWorkspaceRootMetadata, type ModelOption, type PermissionModeOption, type WorkspaceOption } from './types.js';
|
|
3
|
+
import type { CanonRuntimePresentationPolicy } from './types.js';
|
|
3
4
|
import type { HostAdmissionActionCapabilities } from './turn-protocol.js';
|
|
4
5
|
export declare const CLAUDE_EFFORT_OPTIONS: readonly [{
|
|
5
6
|
readonly value: "low";
|
|
@@ -51,4 +52,5 @@ export declare function buildFirstPartyCodingRuntimeDescriptor(input: {
|
|
|
51
52
|
commands?: ReadonlyArray<CanonRuntimeCommandDescriptor>;
|
|
52
53
|
streamingTextMode: CanonRuntimeStreamingMode;
|
|
53
54
|
admissionActions?: HostAdmissionActionCapabilities;
|
|
55
|
+
presentation?: CanonRuntimePresentationPolicy;
|
|
54
56
|
}): CanonRuntimeDescriptor;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CLAUDE_PERMISSION_MODE_OPTIONS, } from './types.js';
|
|
2
|
+
import { DEFAULT_FIRST_PARTY_RUNTIME_PRESENTATION } from './runtime-presentation.js';
|
|
2
3
|
export const CLAUDE_EFFORT_OPTIONS = [
|
|
3
4
|
{ value: 'low', label: 'Low' },
|
|
4
5
|
{ value: 'medium', label: 'Medium' },
|
|
@@ -155,6 +156,7 @@ export function buildFirstPartyCodingRuntimeDescriptor(input) {
|
|
|
155
156
|
supportsInterrupt: true,
|
|
156
157
|
supportsInputInterrupt: true,
|
|
157
158
|
streamingTextMode: input.streamingTextMode,
|
|
159
|
+
presentation: input.presentation ?? DEFAULT_FIRST_PARTY_RUNTIME_PRESENTATION,
|
|
158
160
|
admissionActions: input.admissionActions,
|
|
159
161
|
};
|
|
160
162
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { AgentRuntime, AgentSessionSnapshot, CanonRuntimeActivityItem, CanonRuntimeDescriptor, CanonRuntimeExecutionMetadata, CanonRuntimePresentationField, CanonRuntimePresentationPolicy, RuntimeInfoPayload } from './types.js';
|
|
2
|
+
export declare const RUNTIME_PRESENTATION_FIELDS: readonly ["model", "permissionMode", "effort", "workspace", "executionMode", "contextUsage", "cwd", "branch", "worktreePath", "workspaceRoot", "workspaceRelativePath", "fallbackReason"];
|
|
3
|
+
export declare const DEFAULT_FIRST_PARTY_RUNTIME_PRESENTATION: CanonRuntimePresentationPolicy;
|
|
4
|
+
export declare function isRuntimePresentationField(value: string): value is CanonRuntimePresentationField;
|
|
5
|
+
export declare function buildRuntimePresentationPolicy(input?: {
|
|
6
|
+
preset?: CanonRuntimePresentationPolicy['preset'];
|
|
7
|
+
show?: ReadonlyArray<string>;
|
|
8
|
+
hide?: ReadonlyArray<string>;
|
|
9
|
+
base?: CanonRuntimePresentationPolicy;
|
|
10
|
+
}): CanonRuntimePresentationPolicy;
|
|
11
|
+
export declare function getRuntimePresentationHint(descriptor: CanonRuntimeDescriptor | null | undefined, field: CanonRuntimePresentationField): import("./types.js").CanonRuntimePresentationHint | null;
|
|
12
|
+
export declare function isRuntimePresentationFieldHidden(descriptor: CanonRuntimeDescriptor | null | undefined, field: CanonRuntimePresentationField): boolean;
|
|
13
|
+
export declare function redactRuntimeDescriptorForConversation(descriptor: CanonRuntimeDescriptor): CanonRuntimeDescriptor;
|
|
14
|
+
export declare function redactRuntimeActivityItemForConversation(item: CanonRuntimeActivityItem): CanonRuntimeActivityItem | null;
|
|
15
|
+
export declare function redactExecutionMetadataForConversation(descriptor: CanonRuntimeDescriptor | null | undefined, execution: CanonRuntimeExecutionMetadata | null | undefined): CanonRuntimeExecutionMetadata | null;
|
|
16
|
+
export declare function redactRuntimeInfoForConversation<T extends Partial<Omit<RuntimeInfoPayload, 'updatedAt'>> | RuntimeInfoPayload>(payload: T, options?: {
|
|
17
|
+
descriptor?: CanonRuntimeDescriptor | null;
|
|
18
|
+
}): T;
|
|
19
|
+
export declare function redactAgentRuntimeForConversation(runtime: AgentRuntime): AgentRuntime;
|
|
20
|
+
type SessionStatePresentationLike = {
|
|
21
|
+
model?: unknown;
|
|
22
|
+
permissionMode?: unknown;
|
|
23
|
+
effort?: unknown;
|
|
24
|
+
cwd?: unknown;
|
|
25
|
+
executionMode?: unknown;
|
|
26
|
+
executionBranch?: unknown;
|
|
27
|
+
worktreePath?: unknown;
|
|
28
|
+
executionFallbackReason?: unknown;
|
|
29
|
+
contextUsage?: unknown;
|
|
30
|
+
availableModels?: unknown;
|
|
31
|
+
runtimeControlValues?: Record<string, unknown>;
|
|
32
|
+
controlState?: Record<string, unknown>;
|
|
33
|
+
};
|
|
34
|
+
export declare function redactSessionStateForConversation<T extends SessionStatePresentationLike>(descriptor: CanonRuntimeDescriptor | null | undefined, state: T): T;
|
|
35
|
+
export declare function redactAgentSessionSnapshotForConversation(descriptor: CanonRuntimeDescriptor | null | undefined, snapshot: Partial<AgentSessionSnapshot> & Record<string, unknown>, options?: {
|
|
36
|
+
patch?: boolean;
|
|
37
|
+
}): Partial<AgentSessionSnapshot> & Record<string, unknown>;
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
const MINIMAL_HIDDEN_FIELDS = new Set([
|
|
2
|
+
'model',
|
|
3
|
+
'permissionMode',
|
|
4
|
+
'effort',
|
|
5
|
+
'workspace',
|
|
6
|
+
'contextUsage',
|
|
7
|
+
'cwd',
|
|
8
|
+
'branch',
|
|
9
|
+
'worktreePath',
|
|
10
|
+
'workspaceRoot',
|
|
11
|
+
'workspaceRelativePath',
|
|
12
|
+
'fallbackReason',
|
|
13
|
+
]);
|
|
14
|
+
export const RUNTIME_PRESENTATION_FIELDS = [
|
|
15
|
+
'model',
|
|
16
|
+
'permissionMode',
|
|
17
|
+
'effort',
|
|
18
|
+
'workspace',
|
|
19
|
+
'executionMode',
|
|
20
|
+
'contextUsage',
|
|
21
|
+
'cwd',
|
|
22
|
+
'branch',
|
|
23
|
+
'worktreePath',
|
|
24
|
+
'workspaceRoot',
|
|
25
|
+
'workspaceRelativePath',
|
|
26
|
+
'fallbackReason',
|
|
27
|
+
];
|
|
28
|
+
export const DEFAULT_FIRST_PARTY_RUNTIME_PRESENTATION = {
|
|
29
|
+
preset: 'normal',
|
|
30
|
+
fields: {
|
|
31
|
+
cwd: { visibility: 'hidden' },
|
|
32
|
+
worktreePath: { visibility: 'hidden' },
|
|
33
|
+
workspaceRoot: { visibility: 'hidden' },
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
export function isRuntimePresentationField(value) {
|
|
37
|
+
return RUNTIME_PRESENTATION_FIELDS.includes(value);
|
|
38
|
+
}
|
|
39
|
+
export function buildRuntimePresentationPolicy(input = {}) {
|
|
40
|
+
const preset = input.preset ?? input.base?.preset ?? 'normal';
|
|
41
|
+
const fields = {
|
|
42
|
+
...(preset === 'full' ? {} : input.base?.fields ?? {}),
|
|
43
|
+
};
|
|
44
|
+
for (const field of input.show ?? []) {
|
|
45
|
+
if (!isRuntimePresentationField(field))
|
|
46
|
+
continue;
|
|
47
|
+
fields[field] = {
|
|
48
|
+
...(fields[field] ?? {}),
|
|
49
|
+
visibility: 'conversation',
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
for (const field of input.hide ?? []) {
|
|
53
|
+
if (!isRuntimePresentationField(field))
|
|
54
|
+
continue;
|
|
55
|
+
fields[field] = {
|
|
56
|
+
...(fields[field] ?? {}),
|
|
57
|
+
visibility: 'hidden',
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
preset,
|
|
62
|
+
fields,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function hasOwn(value, key) {
|
|
66
|
+
return Object.prototype.hasOwnProperty.call(value, key);
|
|
67
|
+
}
|
|
68
|
+
function cloneDefined(value) {
|
|
69
|
+
return Object.fromEntries(Object.entries(value).filter(([, entryValue]) => entryValue !== undefined));
|
|
70
|
+
}
|
|
71
|
+
export function getRuntimePresentationHint(descriptor, field) {
|
|
72
|
+
return descriptor?.presentation?.fields?.[field] ?? null;
|
|
73
|
+
}
|
|
74
|
+
export function isRuntimePresentationFieldHidden(descriptor, field) {
|
|
75
|
+
const policy = descriptor?.presentation;
|
|
76
|
+
const hint = policy?.fields?.[field];
|
|
77
|
+
if (hint?.visibility === 'conversation')
|
|
78
|
+
return false;
|
|
79
|
+
if (hint?.visibility === 'hidden')
|
|
80
|
+
return true;
|
|
81
|
+
return policy?.preset === 'minimal' && MINIMAL_HIDDEN_FIELDS.has(field);
|
|
82
|
+
}
|
|
83
|
+
function isRuntimeItemHidden(item) {
|
|
84
|
+
return item?.visibility === 'hidden';
|
|
85
|
+
}
|
|
86
|
+
function isRequiredSetupControl(control) {
|
|
87
|
+
return control.selectionPolicy === 'required_explicit'
|
|
88
|
+
&& (control.availability === 'setup' || control.availability === 'setup_and_live');
|
|
89
|
+
}
|
|
90
|
+
function shouldHideControlValue(descriptor, control) {
|
|
91
|
+
if (isRuntimeItemHidden(control) || control.sensitive)
|
|
92
|
+
return true;
|
|
93
|
+
const field = control.id;
|
|
94
|
+
const hidden = isRuntimePresentationFieldHidden(descriptor, field);
|
|
95
|
+
return hidden && !isRequiredSetupControl(control);
|
|
96
|
+
}
|
|
97
|
+
function hiddenControlValueIds(descriptor) {
|
|
98
|
+
const controls = [
|
|
99
|
+
...(descriptor?.coreControls ?? []),
|
|
100
|
+
...(descriptor?.runtimeControls ?? []),
|
|
101
|
+
];
|
|
102
|
+
return new Set(controls
|
|
103
|
+
.filter((control) => shouldHideControlValue(descriptor, control))
|
|
104
|
+
.map((control) => control.id));
|
|
105
|
+
}
|
|
106
|
+
function redactControlValueMap(descriptor, values, options = {}) {
|
|
107
|
+
if (!values)
|
|
108
|
+
return values;
|
|
109
|
+
const hiddenIds = hiddenControlValueIds(descriptor);
|
|
110
|
+
if (hiddenIds.size === 0)
|
|
111
|
+
return values;
|
|
112
|
+
const redacted = { ...values };
|
|
113
|
+
for (const id of hiddenIds) {
|
|
114
|
+
if (!hasOwn(redacted, id))
|
|
115
|
+
continue;
|
|
116
|
+
if (options.patch) {
|
|
117
|
+
redacted[id] = null;
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
delete redacted[id];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return redacted;
|
|
124
|
+
}
|
|
125
|
+
function redactSensitiveValue(value) {
|
|
126
|
+
void value;
|
|
127
|
+
return 'Hidden';
|
|
128
|
+
}
|
|
129
|
+
function redactControl(descriptor, control) {
|
|
130
|
+
if (isRuntimeItemHidden(control))
|
|
131
|
+
return null;
|
|
132
|
+
const field = control.id;
|
|
133
|
+
const hidden = isRuntimePresentationFieldHidden(descriptor, field);
|
|
134
|
+
if (hidden && !isRequiredSetupControl(control))
|
|
135
|
+
return null;
|
|
136
|
+
if (!control.sensitive)
|
|
137
|
+
return control;
|
|
138
|
+
return cloneDefined({
|
|
139
|
+
...control,
|
|
140
|
+
defaultValue: null,
|
|
141
|
+
options: control.options?.map((option) => ({
|
|
142
|
+
value: option.value,
|
|
143
|
+
label: redactSensitiveValue(option.label),
|
|
144
|
+
})),
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
function redactAction(action) {
|
|
148
|
+
if (isRuntimeItemHidden(action))
|
|
149
|
+
return null;
|
|
150
|
+
if (!action.sensitive)
|
|
151
|
+
return action;
|
|
152
|
+
return cloneDefined({
|
|
153
|
+
...action,
|
|
154
|
+
description: action.description ? redactSensitiveValue(action.description) : undefined,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
function redactWorkspaceOption(descriptor, option) {
|
|
158
|
+
const hideRoot = isRuntimePresentationFieldHidden(descriptor, 'workspaceRoot');
|
|
159
|
+
const hideRelative = isRuntimePresentationFieldHidden(descriptor, 'workspaceRelativePath');
|
|
160
|
+
return cloneDefined({
|
|
161
|
+
...option,
|
|
162
|
+
...(hideRoot ? { workspaceRootId: undefined } : {}),
|
|
163
|
+
...(hideRelative ? { workspaceRelativePath: undefined } : {}),
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
export function redactRuntimeDescriptorForConversation(descriptor) {
|
|
167
|
+
const coreControls = (descriptor.coreControls ?? [])
|
|
168
|
+
.map((control) => redactControl(descriptor, control))
|
|
169
|
+
.filter((control) => Boolean(control))
|
|
170
|
+
.map((control) => control.id === 'workspace'
|
|
171
|
+
? {
|
|
172
|
+
...control,
|
|
173
|
+
options: control.options?.map((option) => redactWorkspaceOption(descriptor, option)),
|
|
174
|
+
}
|
|
175
|
+
: control);
|
|
176
|
+
const runtimeControls = descriptor.runtimeControls?.map((control) => redactControl(descriptor, control))
|
|
177
|
+
.filter((control) => Boolean(control));
|
|
178
|
+
const commands = descriptor.commands?.map((command) => redactAction(command))
|
|
179
|
+
.filter((command) => Boolean(command));
|
|
180
|
+
const actions = descriptor.actions?.map((action) => redactAction(action))
|
|
181
|
+
.filter((action) => Boolean(action));
|
|
182
|
+
return cloneDefined({
|
|
183
|
+
...descriptor,
|
|
184
|
+
coreControls,
|
|
185
|
+
runtimeControls,
|
|
186
|
+
commands,
|
|
187
|
+
actions,
|
|
188
|
+
workspaceRoots: isRuntimePresentationFieldHidden(descriptor, 'workspaceRoot')
|
|
189
|
+
? []
|
|
190
|
+
: descriptor.workspaceRoots,
|
|
191
|
+
writableRoots: isRuntimePresentationFieldHidden(descriptor, 'workspaceRoot')
|
|
192
|
+
? []
|
|
193
|
+
: descriptor.writableRoots,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
function redactStatusItem(item) {
|
|
197
|
+
if (isRuntimeItemHidden(item))
|
|
198
|
+
return null;
|
|
199
|
+
if (!item.sensitive)
|
|
200
|
+
return item;
|
|
201
|
+
return {
|
|
202
|
+
...item,
|
|
203
|
+
value: redactSensitiveValue(item.value),
|
|
204
|
+
tone: item.tone ?? 'warning',
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
function redactFact(item) {
|
|
208
|
+
if (isRuntimeItemHidden(item))
|
|
209
|
+
return null;
|
|
210
|
+
if (!item.sensitive)
|
|
211
|
+
return item;
|
|
212
|
+
return {
|
|
213
|
+
...item,
|
|
214
|
+
value: redactSensitiveValue(item.value),
|
|
215
|
+
tone: item.tone ?? 'warning',
|
|
216
|
+
copyable: false,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
function redactInventoryEntry(entry) {
|
|
220
|
+
if (isRuntimeItemHidden(entry))
|
|
221
|
+
return null;
|
|
222
|
+
if (!entry.sensitive)
|
|
223
|
+
return entry;
|
|
224
|
+
return cloneDefined({
|
|
225
|
+
...entry,
|
|
226
|
+
label: redactSensitiveValue(entry.label),
|
|
227
|
+
description: entry.description ? redactSensitiveValue(entry.description) : undefined,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
function redactInventory(inventory) {
|
|
231
|
+
if (isRuntimeItemHidden(inventory))
|
|
232
|
+
return null;
|
|
233
|
+
const entries = (inventory.entries ?? [])
|
|
234
|
+
.map(redactInventoryEntry)
|
|
235
|
+
.filter((entry) => Boolean(entry));
|
|
236
|
+
if (!inventory.sensitive) {
|
|
237
|
+
return {
|
|
238
|
+
...inventory,
|
|
239
|
+
entries,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
return {
|
|
243
|
+
...inventory,
|
|
244
|
+
entries: [],
|
|
245
|
+
label: redactSensitiveValue(inventory.label),
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
export function redactRuntimeActivityItemForConversation(item) {
|
|
249
|
+
if (isRuntimeItemHidden(item))
|
|
250
|
+
return null;
|
|
251
|
+
const actions = item.actions
|
|
252
|
+
?.map((action) => redactAction(action))
|
|
253
|
+
.filter((action) => Boolean(action));
|
|
254
|
+
if (!item.sensitive) {
|
|
255
|
+
return cloneDefined({
|
|
256
|
+
...item,
|
|
257
|
+
actions,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
return cloneDefined({
|
|
261
|
+
...item,
|
|
262
|
+
title: redactSensitiveValue(item.title),
|
|
263
|
+
summary: item.summary ? redactSensitiveValue(item.summary) : undefined,
|
|
264
|
+
detail: item.detail ? redactSensitiveValue(item.detail) : undefined,
|
|
265
|
+
progressText: item.progressText ? redactSensitiveValue(item.progressText) : undefined,
|
|
266
|
+
actions,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
export function redactExecutionMetadataForConversation(descriptor, execution) {
|
|
270
|
+
if (!execution)
|
|
271
|
+
return null;
|
|
272
|
+
const redacted = cloneDefined({
|
|
273
|
+
...execution,
|
|
274
|
+
resolvedWorkspaceLabel: isRuntimePresentationFieldHidden(descriptor, 'workspace')
|
|
275
|
+
? undefined
|
|
276
|
+
: execution.resolvedWorkspaceLabel,
|
|
277
|
+
resolvedCwd: isRuntimePresentationFieldHidden(descriptor, 'cwd')
|
|
278
|
+
? undefined
|
|
279
|
+
: execution.resolvedCwd,
|
|
280
|
+
workspaceRootId: isRuntimePresentationFieldHidden(descriptor, 'workspaceRoot')
|
|
281
|
+
? undefined
|
|
282
|
+
: execution.workspaceRootId,
|
|
283
|
+
workspaceRelativePath: isRuntimePresentationFieldHidden(descriptor, 'workspaceRelativePath')
|
|
284
|
+
? undefined
|
|
285
|
+
: execution.workspaceRelativePath,
|
|
286
|
+
executionMode: isRuntimePresentationFieldHidden(descriptor, 'executionMode')
|
|
287
|
+
? undefined
|
|
288
|
+
: execution.executionMode,
|
|
289
|
+
executionBranch: isRuntimePresentationFieldHidden(descriptor, 'branch')
|
|
290
|
+
? undefined
|
|
291
|
+
: execution.executionBranch,
|
|
292
|
+
worktreePath: isRuntimePresentationFieldHidden(descriptor, 'worktreePath')
|
|
293
|
+
? undefined
|
|
294
|
+
: execution.worktreePath,
|
|
295
|
+
fallbackReason: isRuntimePresentationFieldHidden(descriptor, 'fallbackReason')
|
|
296
|
+
? undefined
|
|
297
|
+
: execution.fallbackReason,
|
|
298
|
+
});
|
|
299
|
+
return Object.keys(redacted).length > 0 ? redacted : null;
|
|
300
|
+
}
|
|
301
|
+
export function redactRuntimeInfoForConversation(payload, options = {}) {
|
|
302
|
+
const descriptor = payload.descriptor
|
|
303
|
+
? redactRuntimeDescriptorForConversation(payload.descriptor)
|
|
304
|
+
: payload.descriptor;
|
|
305
|
+
const policyDescriptor = options.descriptor ?? payload.descriptor ?? descriptor;
|
|
306
|
+
return cloneDefined({
|
|
307
|
+
...payload,
|
|
308
|
+
descriptor,
|
|
309
|
+
facts: payload.facts
|
|
310
|
+
?.map(redactFact)
|
|
311
|
+
.filter((fact) => Boolean(fact)),
|
|
312
|
+
statusItems: payload.statusItems
|
|
313
|
+
?.map(redactStatusItem)
|
|
314
|
+
.filter((item) => Boolean(item)),
|
|
315
|
+
inventories: payload.inventories
|
|
316
|
+
?.map(redactInventory)
|
|
317
|
+
.filter((inventory) => Boolean(inventory)),
|
|
318
|
+
...(hasOwn(payload, 'execution')
|
|
319
|
+
? { execution: redactExecutionMetadataForConversation(policyDescriptor, payload.execution) }
|
|
320
|
+
: {}),
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
export function redactAgentRuntimeForConversation(runtime) {
|
|
324
|
+
const descriptor = runtime.runtimeDescriptor;
|
|
325
|
+
const redactedDescriptor = descriptor
|
|
326
|
+
? redactRuntimeDescriptorForConversation(descriptor)
|
|
327
|
+
: descriptor;
|
|
328
|
+
return cloneDefined({
|
|
329
|
+
...runtime,
|
|
330
|
+
runtimeDescriptor: redactedDescriptor,
|
|
331
|
+
defaultModel: isRuntimePresentationFieldHidden(descriptor, 'model')
|
|
332
|
+
? undefined
|
|
333
|
+
: runtime.defaultModel,
|
|
334
|
+
availableModels: isRuntimePresentationFieldHidden(descriptor, 'model')
|
|
335
|
+
? undefined
|
|
336
|
+
: runtime.availableModels,
|
|
337
|
+
defaultPermissionMode: isRuntimePresentationFieldHidden(descriptor, 'permissionMode')
|
|
338
|
+
? undefined
|
|
339
|
+
: runtime.defaultPermissionMode,
|
|
340
|
+
availablePermissionModes: isRuntimePresentationFieldHidden(descriptor, 'permissionMode')
|
|
341
|
+
? undefined
|
|
342
|
+
: runtime.availablePermissionModes,
|
|
343
|
+
defaultWorkspaceId: isRuntimePresentationFieldHidden(descriptor, 'workspace')
|
|
344
|
+
? undefined
|
|
345
|
+
: runtime.defaultWorkspaceId,
|
|
346
|
+
availableWorkspaces: isRuntimePresentationFieldHidden(descriptor, 'workspace')
|
|
347
|
+
? undefined
|
|
348
|
+
: runtime.availableWorkspaces,
|
|
349
|
+
defaultExecutionMode: isRuntimePresentationFieldHidden(descriptor, 'executionMode')
|
|
350
|
+
? undefined
|
|
351
|
+
: runtime.defaultExecutionMode,
|
|
352
|
+
availableExecutionModes: isRuntimePresentationFieldHidden(descriptor, 'executionMode')
|
|
353
|
+
? undefined
|
|
354
|
+
: runtime.availableExecutionModes,
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
export function redactSessionStateForConversation(descriptor, state) {
|
|
358
|
+
return cloneDefined({
|
|
359
|
+
...state,
|
|
360
|
+
model: isRuntimePresentationFieldHidden(descriptor, 'model') ? undefined : state.model,
|
|
361
|
+
permissionMode: isRuntimePresentationFieldHidden(descriptor, 'permissionMode')
|
|
362
|
+
? undefined
|
|
363
|
+
: state.permissionMode,
|
|
364
|
+
effort: isRuntimePresentationFieldHidden(descriptor, 'effort') ? undefined : state.effort,
|
|
365
|
+
cwd: isRuntimePresentationFieldHidden(descriptor, 'cwd') ? undefined : state.cwd,
|
|
366
|
+
executionMode: isRuntimePresentationFieldHidden(descriptor, 'executionMode')
|
|
367
|
+
? undefined
|
|
368
|
+
: state.executionMode,
|
|
369
|
+
executionBranch: isRuntimePresentationFieldHidden(descriptor, 'branch')
|
|
370
|
+
? undefined
|
|
371
|
+
: state.executionBranch,
|
|
372
|
+
worktreePath: isRuntimePresentationFieldHidden(descriptor, 'worktreePath')
|
|
373
|
+
? undefined
|
|
374
|
+
: state.worktreePath,
|
|
375
|
+
executionFallbackReason: isRuntimePresentationFieldHidden(descriptor, 'fallbackReason')
|
|
376
|
+
? undefined
|
|
377
|
+
: state.executionFallbackReason,
|
|
378
|
+
contextUsage: isRuntimePresentationFieldHidden(descriptor, 'contextUsage')
|
|
379
|
+
? undefined
|
|
380
|
+
: state.contextUsage,
|
|
381
|
+
availableModels: isRuntimePresentationFieldHidden(descriptor, 'model')
|
|
382
|
+
? undefined
|
|
383
|
+
: state.availableModels,
|
|
384
|
+
runtimeControlValues: redactControlValueMap(descriptor, state.runtimeControlValues),
|
|
385
|
+
controlState: redactControlValueMap(descriptor, state.controlState),
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
export function redactAgentSessionSnapshotForConversation(descriptor, snapshot, options = {}) {
|
|
389
|
+
const hiddenValue = options.patch ? null : undefined;
|
|
390
|
+
const redacted = {
|
|
391
|
+
...snapshot,
|
|
392
|
+
model: isRuntimePresentationFieldHidden(descriptor, 'model') ? hiddenValue : snapshot.model,
|
|
393
|
+
modelOptions: isRuntimePresentationFieldHidden(descriptor, 'model') ? hiddenValue : snapshot.modelOptions,
|
|
394
|
+
permissionMode: isRuntimePresentationFieldHidden(descriptor, 'permissionMode') ? hiddenValue : snapshot.permissionMode,
|
|
395
|
+
permissionModeOptions: isRuntimePresentationFieldHidden(descriptor, 'permissionMode') ? hiddenValue : snapshot.permissionModeOptions,
|
|
396
|
+
effort: isRuntimePresentationFieldHidden(descriptor, 'effort') ? hiddenValue : snapshot.effort,
|
|
397
|
+
workspaceId: isRuntimePresentationFieldHidden(descriptor, 'workspace') ? hiddenValue : snapshot.workspaceId,
|
|
398
|
+
workspaceOptions: isRuntimePresentationFieldHidden(descriptor, 'workspace') ? hiddenValue : snapshot.workspaceOptions,
|
|
399
|
+
executionMode: isRuntimePresentationFieldHidden(descriptor, 'executionMode') ? hiddenValue : snapshot.executionMode,
|
|
400
|
+
availableExecutionModes: isRuntimePresentationFieldHidden(descriptor, 'executionMode') ? hiddenValue : snapshot.availableExecutionModes,
|
|
401
|
+
executionBranch: isRuntimePresentationFieldHidden(descriptor, 'branch') ? hiddenValue : snapshot.executionBranch,
|
|
402
|
+
resolvedWorkspaceLabel: isRuntimePresentationFieldHidden(descriptor, 'workspace') ? hiddenValue : snapshot.resolvedWorkspaceLabel,
|
|
403
|
+
resolvedCwd: isRuntimePresentationFieldHidden(descriptor, 'cwd') ? hiddenValue : snapshot.resolvedCwd,
|
|
404
|
+
worktreePath: isRuntimePresentationFieldHidden(descriptor, 'worktreePath') ? hiddenValue : snapshot.worktreePath,
|
|
405
|
+
executionFallbackReason: isRuntimePresentationFieldHidden(descriptor, 'fallbackReason') ? hiddenValue : snapshot.executionFallbackReason,
|
|
406
|
+
contextUsage: isRuntimePresentationFieldHidden(descriptor, 'contextUsage') ? hiddenValue : snapshot.contextUsage,
|
|
407
|
+
runtimeControlValues: redactControlValueMap(descriptor, snapshot.runtimeControlValues, options),
|
|
408
|
+
};
|
|
409
|
+
if (redacted.runtimeDescriptor) {
|
|
410
|
+
redacted.runtimeDescriptor = redactRuntimeDescriptorForConversation(redacted.runtimeDescriptor);
|
|
411
|
+
}
|
|
412
|
+
if (redacted.runtimeInfo) {
|
|
413
|
+
redacted.runtimeInfo = redactRuntimeInfoForConversation(redacted.runtimeInfo);
|
|
414
|
+
}
|
|
415
|
+
if (!redacted.controlState)
|
|
416
|
+
return cloneDefined(redacted);
|
|
417
|
+
const controlState = { ...redacted.controlState };
|
|
418
|
+
const hiddenIds = hiddenControlValueIds(descriptor);
|
|
419
|
+
for (const field of ['model', 'permissionMode', 'effort', 'workspace', 'executionMode']) {
|
|
420
|
+
if (isRuntimePresentationFieldHidden(descriptor, field) && hasOwn(controlState, field)) {
|
|
421
|
+
if (options.patch) {
|
|
422
|
+
controlState[field] = null;
|
|
423
|
+
}
|
|
424
|
+
else {
|
|
425
|
+
delete controlState[field];
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
for (const id of hiddenIds) {
|
|
430
|
+
if (!hasOwn(controlState, id))
|
|
431
|
+
continue;
|
|
432
|
+
if (options.patch) {
|
|
433
|
+
controlState[id] = null;
|
|
434
|
+
}
|
|
435
|
+
else {
|
|
436
|
+
delete controlState[id];
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
redacted.controlState = controlState;
|
|
440
|
+
return cloneDefined(redacted);
|
|
441
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { redactAgentRuntimeForConversation, redactAgentSessionSnapshotForConversation, isRuntimePresentationFieldHidden, redactRuntimeActivityItemForConversation, redactRuntimeInfoForConversation, redactSessionStateForConversation, } from './runtime-presentation.js';
|
|
1
2
|
import { clearRuntimeInfo, clearRuntimeActivity, clearSessionState, clearTurnState, patchAgentSessionSnapshot, patchRuntimeInfo, readRuntimeActivity, removeRuntimeActivityItem, rtdbRead, rtdbWrite, writeRuntimeActivity, writeRuntimeInfo, writeSessionState, writeTurnState, } from './rtdb-rest.js';
|
|
2
3
|
const SERVER_TIMESTAMP = { '.sv': 'timestamp' };
|
|
3
4
|
const MAX_RUNTIME_ACTIVITY_ITEMS = 50;
|
|
@@ -35,7 +36,31 @@ export function createRuntimeStatePublisher(options) {
|
|
|
35
36
|
const { agentId, clientType, hostMode, rtdb } = options;
|
|
36
37
|
const writePath = (path, data) => (rtdb ? rtdb.write(path, data) : rtdbWrite(path, data));
|
|
37
38
|
const readPath = (path) => (rtdb ? rtdb.read(path) : rtdbRead(path));
|
|
38
|
-
let
|
|
39
|
+
let lastRawRuntime = null;
|
|
40
|
+
let lastPublicRuntime = null;
|
|
41
|
+
function currentDescriptor() {
|
|
42
|
+
return lastRawRuntime?.runtimeDescriptor ?? null;
|
|
43
|
+
}
|
|
44
|
+
function hasHiddenSessionStateField(descriptor) {
|
|
45
|
+
if (!descriptor)
|
|
46
|
+
return false;
|
|
47
|
+
const controls = [
|
|
48
|
+
...(descriptor.coreControls ?? []),
|
|
49
|
+
...(descriptor.runtimeControls ?? []),
|
|
50
|
+
];
|
|
51
|
+
return [
|
|
52
|
+
'model',
|
|
53
|
+
'permissionMode',
|
|
54
|
+
'effort',
|
|
55
|
+
'cwd',
|
|
56
|
+
'executionMode',
|
|
57
|
+
'branch',
|
|
58
|
+
'worktreePath',
|
|
59
|
+
'fallbackReason',
|
|
60
|
+
'contextUsage',
|
|
61
|
+
].some((field) => isRuntimePresentationFieldHidden(descriptor, field))
|
|
62
|
+
|| controls.some((control) => control.visibility === 'hidden' || control.sensitive === true);
|
|
63
|
+
}
|
|
39
64
|
const readRuntimeActivityPath = (conversationId) => (rtdb
|
|
40
65
|
? rtdb.readRuntimeActivity(conversationId, agentId)
|
|
41
66
|
: readRuntimeActivity(conversationId, agentId));
|
|
@@ -63,18 +88,22 @@ export function createRuntimeStatePublisher(options) {
|
|
|
63
88
|
}
|
|
64
89
|
return {
|
|
65
90
|
async publishAgentRuntime(runtime) {
|
|
66
|
-
const
|
|
91
|
+
const rawRuntime = {
|
|
67
92
|
clientType,
|
|
68
93
|
hostMode,
|
|
69
94
|
...runtime,
|
|
95
|
+
};
|
|
96
|
+
const publicPayload = {
|
|
97
|
+
...redactAgentRuntimeForConversation(rawRuntime),
|
|
70
98
|
updatedAt: SERVER_TIMESTAMP,
|
|
71
99
|
};
|
|
72
|
-
|
|
73
|
-
|
|
100
|
+
lastRawRuntime = rawRuntime;
|
|
101
|
+
lastPublicRuntime = publicPayload;
|
|
102
|
+
await writePath(`/agent-runtime/${agentId}`, publicPayload);
|
|
74
103
|
},
|
|
75
104
|
async clearAgentRuntime() {
|
|
76
105
|
const path = `/agent-runtime/${agentId}`;
|
|
77
|
-
const current =
|
|
106
|
+
const current = lastPublicRuntime ?? await readPath(path).catch(() => null);
|
|
78
107
|
if (hasPreservableRuntimeState(current)) {
|
|
79
108
|
await writePath(path, {
|
|
80
109
|
...current,
|
|
@@ -85,9 +114,30 @@ export function createRuntimeStatePublisher(options) {
|
|
|
85
114
|
await writePath(path, null);
|
|
86
115
|
},
|
|
87
116
|
async writeSessionState(conversationId, state) {
|
|
117
|
+
const descriptor = currentDescriptor();
|
|
118
|
+
const publicState = redactSessionStateForConversation(descriptor, state);
|
|
88
119
|
await (rtdb
|
|
89
|
-
? rtdb.writeSessionState(conversationId, agentId,
|
|
90
|
-
: writeSessionState(conversationId, agentId,
|
|
120
|
+
? rtdb.writeSessionState(conversationId, agentId, publicState)
|
|
121
|
+
: writeSessionState(conversationId, agentId, publicState));
|
|
122
|
+
if (hasHiddenSessionStateField(descriptor)) {
|
|
123
|
+
const clearingPatch = redactAgentSessionSnapshotForConversation(descriptor, {
|
|
124
|
+
model: state.model,
|
|
125
|
+
modelOptions: state.availableModels,
|
|
126
|
+
permissionMode: state.permissionMode,
|
|
127
|
+
effort: state.effort,
|
|
128
|
+
resolvedCwd: state.cwd,
|
|
129
|
+
executionMode: state.executionMode,
|
|
130
|
+
executionBranch: state.executionBranch,
|
|
131
|
+
worktreePath: state.worktreePath,
|
|
132
|
+
executionFallbackReason: state.executionFallbackReason,
|
|
133
|
+
contextUsage: state.contextUsage,
|
|
134
|
+
runtimeControlValues: state.runtimeControlValues,
|
|
135
|
+
controlState: state.controlState,
|
|
136
|
+
}, { patch: true });
|
|
137
|
+
await (rtdb
|
|
138
|
+
? rtdb.patchAgentSessionSnapshot(conversationId, agentId, clearingPatch)
|
|
139
|
+
: patchAgentSessionSnapshot(conversationId, agentId, clearingPatch));
|
|
140
|
+
}
|
|
91
141
|
},
|
|
92
142
|
async clearSessionState(conversationId) {
|
|
93
143
|
await (rtdb
|
|
@@ -105,19 +155,22 @@ export function createRuntimeStatePublisher(options) {
|
|
|
105
155
|
: clearTurnState(conversationId, agentId));
|
|
106
156
|
},
|
|
107
157
|
async patchAgentSessionSnapshot(conversationId, snapshot) {
|
|
158
|
+
const publicSnapshot = redactAgentSessionSnapshotForConversation(currentDescriptor(), snapshot, { patch: true });
|
|
108
159
|
await (rtdb
|
|
109
|
-
? rtdb.patchAgentSessionSnapshot(conversationId, agentId,
|
|
110
|
-
: patchAgentSessionSnapshot(conversationId, agentId,
|
|
160
|
+
? rtdb.patchAgentSessionSnapshot(conversationId, agentId, publicSnapshot)
|
|
161
|
+
: patchAgentSessionSnapshot(conversationId, agentId, publicSnapshot));
|
|
111
162
|
},
|
|
112
163
|
async writeRuntimeInfo(conversationId, payload) {
|
|
164
|
+
const publicPayload = redactRuntimeInfoForConversation(payload, { descriptor: currentDescriptor() });
|
|
113
165
|
await (rtdb
|
|
114
|
-
? rtdb.writeRuntimeInfo(conversationId, agentId,
|
|
115
|
-
: writeRuntimeInfo(conversationId, agentId,
|
|
166
|
+
? rtdb.writeRuntimeInfo(conversationId, agentId, publicPayload)
|
|
167
|
+
: writeRuntimeInfo(conversationId, agentId, publicPayload));
|
|
116
168
|
},
|
|
117
169
|
async patchRuntimeInfo(conversationId, payload) {
|
|
170
|
+
const publicPayload = redactRuntimeInfoForConversation(payload, { descriptor: currentDescriptor() });
|
|
118
171
|
await (rtdb
|
|
119
|
-
? rtdb.patchRuntimeInfo(conversationId, agentId,
|
|
120
|
-
: patchRuntimeInfo(conversationId, agentId,
|
|
172
|
+
? rtdb.patchRuntimeInfo(conversationId, agentId, publicPayload)
|
|
173
|
+
: patchRuntimeInfo(conversationId, agentId, publicPayload));
|
|
121
174
|
},
|
|
122
175
|
async clearRuntimeInfo(conversationId) {
|
|
123
176
|
await (rtdb
|
|
@@ -125,9 +178,12 @@ export function createRuntimeStatePublisher(options) {
|
|
|
125
178
|
: clearRuntimeInfo(conversationId, agentId));
|
|
126
179
|
},
|
|
127
180
|
async writeRuntimeActivity(conversationId, item) {
|
|
181
|
+
const publicItem = redactRuntimeActivityItemForConversation(item);
|
|
182
|
+
if (!publicItem)
|
|
183
|
+
return;
|
|
128
184
|
const normalized = {
|
|
129
|
-
...
|
|
130
|
-
updatedAt:
|
|
185
|
+
...publicItem,
|
|
186
|
+
updatedAt: publicItem.updatedAt || Date.now(),
|
|
131
187
|
};
|
|
132
188
|
await (rtdb
|
|
133
189
|
? rtdb.writeRuntimeActivity(conversationId, agentId, normalized)
|
package/dist/turn-protocol.js
CHANGED
|
@@ -43,6 +43,16 @@ export const HOST_ADMISSION_ACTIONS_DISABLED = {
|
|
|
43
43
|
function isRecord(value) {
|
|
44
44
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
45
45
|
}
|
|
46
|
+
function isHiddenRuntimeCardMetadata(metadata) {
|
|
47
|
+
if (!isRecord(metadata) || typeof metadata.type !== 'string')
|
|
48
|
+
return false;
|
|
49
|
+
return metadata.type === 'approval_reply'
|
|
50
|
+
|| metadata.type === 'approval_outcome'
|
|
51
|
+
|| metadata.type === 'question_reply'
|
|
52
|
+
|| metadata.type === 'plan_approval_reply'
|
|
53
|
+
|| metadata.type === 'runtime_input_reply'
|
|
54
|
+
|| metadata.type === 'runtime_input_outcome';
|
|
55
|
+
}
|
|
46
56
|
export function normalizeTurnMetadata(metadata) {
|
|
47
57
|
if (!isRecord(metadata))
|
|
48
58
|
return null;
|
|
@@ -132,6 +142,9 @@ export function resolveTurnMessageSemantics(input) {
|
|
|
132
142
|
return isTurnOpen(input.senderTurnState) ? 'progress' : 'turn_complete';
|
|
133
143
|
}
|
|
134
144
|
export function shouldPromoteConversationMessage(input) {
|
|
145
|
+
if (isHiddenRuntimeCardMetadata(input.metadata)) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
135
148
|
return resolveTurnMessageSemantics(input) !== 'progress';
|
|
136
149
|
}
|
|
137
150
|
export function shouldTriggerAgentTurn(input) {
|
package/dist/types.d.ts
CHANGED
|
@@ -190,7 +190,7 @@ export interface CanonResolveAdmissionResult {
|
|
|
190
190
|
target: ResolvedAdmissionTargetSummary | null;
|
|
191
191
|
admission: ResolvedTargetAdmissionPayload;
|
|
192
192
|
}
|
|
193
|
-
export type AgentClientType = 'claude-code' | 'openclaw' | 'codex' | 'generic';
|
|
193
|
+
export type AgentClientType = 'claude-code' | 'openclaw' | 'codex' | 'hermes' | 'generic';
|
|
194
194
|
export interface ResolvedAdmission {
|
|
195
195
|
discoverable: boolean;
|
|
196
196
|
inboundPolicy: 'open' | 'approval-required' | 'owner-only';
|
|
@@ -250,6 +250,18 @@ export type CanonControlSelectionPolicy = 'inherit' | 'required_explicit';
|
|
|
250
250
|
export type CanonRuntimeStreamingMode = 'none' | 'status' | 'snapshot' | 'block' | 'delta';
|
|
251
251
|
export type CanonRuntimeSurfaceMode = 'host' | 'channel' | 'limited_channel' | 'operator';
|
|
252
252
|
export type CanonRuntimeDetailTier = 'primary' | 'detail' | 'diagnostic';
|
|
253
|
+
export type CanonRuntimeVisibility = 'conversation' | 'hidden';
|
|
254
|
+
export type CanonRuntimePresentationPreset = 'normal' | 'minimal' | 'full';
|
|
255
|
+
export type CanonRuntimePresentationField = 'model' | 'permissionMode' | 'effort' | 'workspace' | 'executionMode' | 'contextUsage' | 'cwd' | 'branch' | 'worktreePath' | 'workspaceRoot' | 'workspaceRelativePath' | 'fallbackReason';
|
|
256
|
+
export interface CanonRuntimePresentationHint {
|
|
257
|
+
visibility?: CanonRuntimeVisibility;
|
|
258
|
+
tier?: CanonRuntimeDetailTier;
|
|
259
|
+
sensitive?: boolean;
|
|
260
|
+
}
|
|
261
|
+
export interface CanonRuntimePresentationPolicy {
|
|
262
|
+
preset?: CanonRuntimePresentationPreset;
|
|
263
|
+
fields?: Partial<Record<CanonRuntimePresentationField, CanonRuntimePresentationHint>>;
|
|
264
|
+
}
|
|
253
265
|
export type CanonRuntimeFactGroup = 'connection' | 'route' | 'runtime' | 'model' | 'session' | 'account' | 'limits';
|
|
254
266
|
export type CanonRuntimeInventoryStatus = 'ready' | 'auth_needed' | 'unknown' | 'configured' | 'running' | 'error';
|
|
255
267
|
export type CanonRuntimeStatusTone = 'default' | 'success' | 'warning' | 'danger';
|
|
@@ -295,6 +307,9 @@ export interface CanonRuntimeActionDescriptor {
|
|
|
295
307
|
id: string;
|
|
296
308
|
label: string;
|
|
297
309
|
description?: string;
|
|
310
|
+
visibility?: CanonRuntimeVisibility;
|
|
311
|
+
tier?: CanonRuntimeDetailTier;
|
|
312
|
+
sensitive?: boolean;
|
|
298
313
|
primitive?: CanonRuntimePrimitiveId;
|
|
299
314
|
aliases?: ReadonlyArray<string>;
|
|
300
315
|
category?: CanonRuntimeActionCategory;
|
|
@@ -319,6 +334,9 @@ export interface CanonControlDescriptor {
|
|
|
319
334
|
liveBehavior: CanonControlLiveBehavior;
|
|
320
335
|
selectionPolicy: CanonControlSelectionPolicy;
|
|
321
336
|
description?: string;
|
|
337
|
+
visibility?: CanonRuntimeVisibility;
|
|
338
|
+
tier?: CanonRuntimeDetailTier;
|
|
339
|
+
sensitive?: boolean;
|
|
322
340
|
}
|
|
323
341
|
export interface CanonRuntimeDescriptor {
|
|
324
342
|
coreControls: ReadonlyArray<CanonControlDescriptor>;
|
|
@@ -341,6 +359,12 @@ export interface CanonRuntimeDescriptor {
|
|
|
341
359
|
* means activity/tool state without live assistant text.
|
|
342
360
|
*/
|
|
343
361
|
streamingTextMode?: CanonRuntimeStreamingMode;
|
|
362
|
+
/**
|
|
363
|
+
* Runtime-owned presentation policy for built-in Canon detail fields.
|
|
364
|
+
* Hidden fields are redacted before public/member-readable runtime payloads
|
|
365
|
+
* are published; clients only render what remains.
|
|
366
|
+
*/
|
|
367
|
+
presentation?: CanonRuntimePresentationPolicy;
|
|
344
368
|
/**
|
|
345
369
|
* Contact-graph and admission actions this runtime exposes through the
|
|
346
370
|
* agent SDK. Plugins set this to advertise which tools they will surface
|
|
@@ -366,6 +390,7 @@ export interface CanonRuntimeStatusItem {
|
|
|
366
390
|
tone?: CanonRuntimeStatusTone;
|
|
367
391
|
tier?: CanonRuntimeDetailTier;
|
|
368
392
|
sensitive?: boolean;
|
|
393
|
+
visibility?: CanonRuntimeVisibility;
|
|
369
394
|
source?: RuntimeControlValueSource;
|
|
370
395
|
}
|
|
371
396
|
export interface CanonRuntimeFact {
|
|
@@ -374,6 +399,8 @@ export interface CanonRuntimeFact {
|
|
|
374
399
|
value: string;
|
|
375
400
|
group: CanonRuntimeFactGroup;
|
|
376
401
|
tier?: CanonRuntimeDetailTier;
|
|
402
|
+
sensitive?: boolean;
|
|
403
|
+
visibility?: CanonRuntimeVisibility;
|
|
377
404
|
tone?: 'neutral' | 'good' | 'warning' | 'danger';
|
|
378
405
|
copyable?: boolean;
|
|
379
406
|
updatedAt?: number;
|
|
@@ -392,6 +419,9 @@ export interface CanonRuntimeActivityItem {
|
|
|
392
419
|
startedAt?: number;
|
|
393
420
|
updatedAt: number;
|
|
394
421
|
endedAt?: number;
|
|
422
|
+
visibility?: CanonRuntimeVisibility;
|
|
423
|
+
tier?: CanonRuntimeDetailTier;
|
|
424
|
+
sensitive?: boolean;
|
|
395
425
|
actions?: ReadonlyArray<CanonRuntimeCommandDescriptor>;
|
|
396
426
|
}
|
|
397
427
|
export interface CanonRuntimeInventoryEntry {
|
|
@@ -399,12 +429,17 @@ export interface CanonRuntimeInventoryEntry {
|
|
|
399
429
|
label: string;
|
|
400
430
|
status?: CanonRuntimeInventoryStatus;
|
|
401
431
|
description?: string;
|
|
432
|
+
tier?: CanonRuntimeDetailTier;
|
|
433
|
+
sensitive?: boolean;
|
|
434
|
+
visibility?: CanonRuntimeVisibility;
|
|
402
435
|
}
|
|
403
436
|
export interface CanonRuntimeInventory {
|
|
404
437
|
id: string;
|
|
405
438
|
label: string;
|
|
406
439
|
entries: ReadonlyArray<CanonRuntimeInventoryEntry>;
|
|
407
440
|
tier?: CanonRuntimeDetailTier;
|
|
441
|
+
sensitive?: boolean;
|
|
442
|
+
visibility?: CanonRuntimeVisibility;
|
|
408
443
|
}
|
|
409
444
|
export interface RuntimeInfoPayload {
|
|
410
445
|
descriptor: CanonRuntimeDescriptor;
|
package/dist/types.js
CHANGED
|
@@ -29,6 +29,15 @@ export const AGENT_CAPABILITIES = {
|
|
|
29
29
|
supportsQueue: true,
|
|
30
30
|
supportsInterleave: false,
|
|
31
31
|
},
|
|
32
|
+
'hermes': {
|
|
33
|
+
supportsModelSwitch: false,
|
|
34
|
+
supportsPermissionMode: false,
|
|
35
|
+
supportsEffort: false,
|
|
36
|
+
supportsSessionState: true,
|
|
37
|
+
supportsInterrupt: true,
|
|
38
|
+
supportsQueue: true,
|
|
39
|
+
supportsInterleave: false,
|
|
40
|
+
},
|
|
32
41
|
'openclaw': { ...DEFAULT_CAPABILITIES },
|
|
33
42
|
'generic': { ...DEFAULT_CAPABILITIES },
|
|
34
43
|
};
|