@canonmsg/core 0.19.0 → 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 +108 -14
- package/dist/turn-protocol.js +13 -0
- package/dist/types.d.ts +43 -1
- package/dist/types.js +12 -3
- 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,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { redactAgentRuntimeForConversation, redactAgentSessionSnapshotForConversation, isRuntimePresentationFieldHidden, redactRuntimeActivityItemForConversation, redactRuntimeInfoForConversation, redactSessionStateForConversation, } from './runtime-presentation.js';
|
|
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;
|
|
4
5
|
const TERMINAL_RUNTIME_ACTIVITY_CLEAR_MS = 60_000;
|
|
@@ -6,9 +7,60 @@ const TERMINAL_RUNTIME_ACTIVITY_STATUSES = new Set(['completed', 'failed', 'bloc
|
|
|
6
7
|
function isTerminalRuntimeActivity(item) {
|
|
7
8
|
return TERMINAL_RUNTIME_ACTIVITY_STATUSES.has(item.status);
|
|
8
9
|
}
|
|
10
|
+
function hasNonEmptyArray(value) {
|
|
11
|
+
return Array.isArray(value) && value.length > 0;
|
|
12
|
+
}
|
|
13
|
+
function hasEnabledAdmissionActions(value) {
|
|
14
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
15
|
+
return false;
|
|
16
|
+
return Object.values(value).some((enabled) => enabled === true);
|
|
17
|
+
}
|
|
18
|
+
function hasPreservableRuntimeState(value) {
|
|
19
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
20
|
+
return false;
|
|
21
|
+
const descriptor = value.runtimeDescriptor;
|
|
22
|
+
if (!descriptor || typeof descriptor !== 'object' || Array.isArray(descriptor))
|
|
23
|
+
return false;
|
|
24
|
+
const runtimeDescriptor = descriptor;
|
|
25
|
+
return hasNonEmptyArray(runtimeDescriptor.coreControls)
|
|
26
|
+
|| hasNonEmptyArray(runtimeDescriptor.runtimeControls)
|
|
27
|
+
|| hasNonEmptyArray(runtimeDescriptor.commands)
|
|
28
|
+
|| hasNonEmptyArray(runtimeDescriptor.actions)
|
|
29
|
+
|| hasNonEmptyArray(runtimeDescriptor.workspaceRoots)
|
|
30
|
+
|| hasNonEmptyArray(runtimeDescriptor.writableRoots)
|
|
31
|
+
|| hasEnabledAdmissionActions(runtimeDescriptor.admissionActions)
|
|
32
|
+
|| runtimeDescriptor.streamingTextMode === 'delta'
|
|
33
|
+
|| runtimeDescriptor.streamingTextMode === 'block';
|
|
34
|
+
}
|
|
9
35
|
export function createRuntimeStatePublisher(options) {
|
|
10
36
|
const { agentId, clientType, hostMode, rtdb } = options;
|
|
11
37
|
const writePath = (path, data) => (rtdb ? rtdb.write(path, data) : rtdbWrite(path, data));
|
|
38
|
+
const readPath = (path) => (rtdb ? rtdb.read(path) : rtdbRead(path));
|
|
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
|
+
}
|
|
12
64
|
const readRuntimeActivityPath = (conversationId) => (rtdb
|
|
13
65
|
? rtdb.readRuntimeActivity(conversationId, agentId)
|
|
14
66
|
: readRuntimeActivity(conversationId, agentId));
|
|
@@ -36,20 +88,56 @@ export function createRuntimeStatePublisher(options) {
|
|
|
36
88
|
}
|
|
37
89
|
return {
|
|
38
90
|
async publishAgentRuntime(runtime) {
|
|
39
|
-
|
|
91
|
+
const rawRuntime = {
|
|
40
92
|
clientType,
|
|
41
93
|
hostMode,
|
|
42
94
|
...runtime,
|
|
95
|
+
};
|
|
96
|
+
const publicPayload = {
|
|
97
|
+
...redactAgentRuntimeForConversation(rawRuntime),
|
|
43
98
|
updatedAt: SERVER_TIMESTAMP,
|
|
44
|
-
}
|
|
99
|
+
};
|
|
100
|
+
lastRawRuntime = rawRuntime;
|
|
101
|
+
lastPublicRuntime = publicPayload;
|
|
102
|
+
await writePath(`/agent-runtime/${agentId}`, publicPayload);
|
|
45
103
|
},
|
|
46
104
|
async clearAgentRuntime() {
|
|
47
|
-
|
|
105
|
+
const path = `/agent-runtime/${agentId}`;
|
|
106
|
+
const current = lastPublicRuntime ?? await readPath(path).catch(() => null);
|
|
107
|
+
if (hasPreservableRuntimeState(current)) {
|
|
108
|
+
await writePath(path, {
|
|
109
|
+
...current,
|
|
110
|
+
updatedAt: 0,
|
|
111
|
+
});
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
await writePath(path, null);
|
|
48
115
|
},
|
|
49
116
|
async writeSessionState(conversationId, state) {
|
|
117
|
+
const descriptor = currentDescriptor();
|
|
118
|
+
const publicState = redactSessionStateForConversation(descriptor, state);
|
|
50
119
|
await (rtdb
|
|
51
|
-
? rtdb.writeSessionState(conversationId, agentId,
|
|
52
|
-
: 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
|
+
}
|
|
53
141
|
},
|
|
54
142
|
async clearSessionState(conversationId) {
|
|
55
143
|
await (rtdb
|
|
@@ -67,19 +155,22 @@ export function createRuntimeStatePublisher(options) {
|
|
|
67
155
|
: clearTurnState(conversationId, agentId));
|
|
68
156
|
},
|
|
69
157
|
async patchAgentSessionSnapshot(conversationId, snapshot) {
|
|
158
|
+
const publicSnapshot = redactAgentSessionSnapshotForConversation(currentDescriptor(), snapshot, { patch: true });
|
|
70
159
|
await (rtdb
|
|
71
|
-
? rtdb.patchAgentSessionSnapshot(conversationId, agentId,
|
|
72
|
-
: patchAgentSessionSnapshot(conversationId, agentId,
|
|
160
|
+
? rtdb.patchAgentSessionSnapshot(conversationId, agentId, publicSnapshot)
|
|
161
|
+
: patchAgentSessionSnapshot(conversationId, agentId, publicSnapshot));
|
|
73
162
|
},
|
|
74
163
|
async writeRuntimeInfo(conversationId, payload) {
|
|
164
|
+
const publicPayload = redactRuntimeInfoForConversation(payload, { descriptor: currentDescriptor() });
|
|
75
165
|
await (rtdb
|
|
76
|
-
? rtdb.writeRuntimeInfo(conversationId, agentId,
|
|
77
|
-
: writeRuntimeInfo(conversationId, agentId,
|
|
166
|
+
? rtdb.writeRuntimeInfo(conversationId, agentId, publicPayload)
|
|
167
|
+
: writeRuntimeInfo(conversationId, agentId, publicPayload));
|
|
78
168
|
},
|
|
79
169
|
async patchRuntimeInfo(conversationId, payload) {
|
|
170
|
+
const publicPayload = redactRuntimeInfoForConversation(payload, { descriptor: currentDescriptor() });
|
|
80
171
|
await (rtdb
|
|
81
|
-
? rtdb.patchRuntimeInfo(conversationId, agentId,
|
|
82
|
-
: patchRuntimeInfo(conversationId, agentId,
|
|
172
|
+
? rtdb.patchRuntimeInfo(conversationId, agentId, publicPayload)
|
|
173
|
+
: patchRuntimeInfo(conversationId, agentId, publicPayload));
|
|
83
174
|
},
|
|
84
175
|
async clearRuntimeInfo(conversationId) {
|
|
85
176
|
await (rtdb
|
|
@@ -87,9 +178,12 @@ export function createRuntimeStatePublisher(options) {
|
|
|
87
178
|
: clearRuntimeInfo(conversationId, agentId));
|
|
88
179
|
},
|
|
89
180
|
async writeRuntimeActivity(conversationId, item) {
|
|
181
|
+
const publicItem = redactRuntimeActivityItemForConversation(item);
|
|
182
|
+
if (!publicItem)
|
|
183
|
+
return;
|
|
90
184
|
const normalized = {
|
|
91
|
-
...
|
|
92
|
-
updatedAt:
|
|
185
|
+
...publicItem,
|
|
186
|
+
updatedAt: publicItem.updatedAt || Date.now(),
|
|
93
187
|
};
|
|
94
188
|
await (rtdb
|
|
95
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';
|
|
@@ -216,6 +216,8 @@ export interface ModelOption {
|
|
|
216
216
|
value: string;
|
|
217
217
|
label: string;
|
|
218
218
|
description?: string;
|
|
219
|
+
/** This option may only be selected by the agent owner or the agent itself. */
|
|
220
|
+
ownerOnly?: boolean;
|
|
219
221
|
workspaceRootId?: string;
|
|
220
222
|
workspaceRelativePath?: string;
|
|
221
223
|
source?: WorkspaceOptionSource;
|
|
@@ -248,6 +250,18 @@ export type CanonControlSelectionPolicy = 'inherit' | 'required_explicit';
|
|
|
248
250
|
export type CanonRuntimeStreamingMode = 'none' | 'status' | 'snapshot' | 'block' | 'delta';
|
|
249
251
|
export type CanonRuntimeSurfaceMode = 'host' | 'channel' | 'limited_channel' | 'operator';
|
|
250
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
|
+
}
|
|
251
265
|
export type CanonRuntimeFactGroup = 'connection' | 'route' | 'runtime' | 'model' | 'session' | 'account' | 'limits';
|
|
252
266
|
export type CanonRuntimeInventoryStatus = 'ready' | 'auth_needed' | 'unknown' | 'configured' | 'running' | 'error';
|
|
253
267
|
export type CanonRuntimeStatusTone = 'default' | 'success' | 'warning' | 'danger';
|
|
@@ -293,6 +307,9 @@ export interface CanonRuntimeActionDescriptor {
|
|
|
293
307
|
id: string;
|
|
294
308
|
label: string;
|
|
295
309
|
description?: string;
|
|
310
|
+
visibility?: CanonRuntimeVisibility;
|
|
311
|
+
tier?: CanonRuntimeDetailTier;
|
|
312
|
+
sensitive?: boolean;
|
|
296
313
|
primitive?: CanonRuntimePrimitiveId;
|
|
297
314
|
aliases?: ReadonlyArray<string>;
|
|
298
315
|
category?: CanonRuntimeActionCategory;
|
|
@@ -317,6 +334,9 @@ export interface CanonControlDescriptor {
|
|
|
317
334
|
liveBehavior: CanonControlLiveBehavior;
|
|
318
335
|
selectionPolicy: CanonControlSelectionPolicy;
|
|
319
336
|
description?: string;
|
|
337
|
+
visibility?: CanonRuntimeVisibility;
|
|
338
|
+
tier?: CanonRuntimeDetailTier;
|
|
339
|
+
sensitive?: boolean;
|
|
320
340
|
}
|
|
321
341
|
export interface CanonRuntimeDescriptor {
|
|
322
342
|
coreControls: ReadonlyArray<CanonControlDescriptor>;
|
|
@@ -339,6 +359,12 @@ export interface CanonRuntimeDescriptor {
|
|
|
339
359
|
* means activity/tool state without live assistant text.
|
|
340
360
|
*/
|
|
341
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;
|
|
342
368
|
/**
|
|
343
369
|
* Contact-graph and admission actions this runtime exposes through the
|
|
344
370
|
* agent SDK. Plugins set this to advertise which tools they will surface
|
|
@@ -364,6 +390,7 @@ export interface CanonRuntimeStatusItem {
|
|
|
364
390
|
tone?: CanonRuntimeStatusTone;
|
|
365
391
|
tier?: CanonRuntimeDetailTier;
|
|
366
392
|
sensitive?: boolean;
|
|
393
|
+
visibility?: CanonRuntimeVisibility;
|
|
367
394
|
source?: RuntimeControlValueSource;
|
|
368
395
|
}
|
|
369
396
|
export interface CanonRuntimeFact {
|
|
@@ -372,6 +399,8 @@ export interface CanonRuntimeFact {
|
|
|
372
399
|
value: string;
|
|
373
400
|
group: CanonRuntimeFactGroup;
|
|
374
401
|
tier?: CanonRuntimeDetailTier;
|
|
402
|
+
sensitive?: boolean;
|
|
403
|
+
visibility?: CanonRuntimeVisibility;
|
|
375
404
|
tone?: 'neutral' | 'good' | 'warning' | 'danger';
|
|
376
405
|
copyable?: boolean;
|
|
377
406
|
updatedAt?: number;
|
|
@@ -390,6 +419,9 @@ export interface CanonRuntimeActivityItem {
|
|
|
390
419
|
startedAt?: number;
|
|
391
420
|
updatedAt: number;
|
|
392
421
|
endedAt?: number;
|
|
422
|
+
visibility?: CanonRuntimeVisibility;
|
|
423
|
+
tier?: CanonRuntimeDetailTier;
|
|
424
|
+
sensitive?: boolean;
|
|
393
425
|
actions?: ReadonlyArray<CanonRuntimeCommandDescriptor>;
|
|
394
426
|
}
|
|
395
427
|
export interface CanonRuntimeInventoryEntry {
|
|
@@ -397,12 +429,17 @@ export interface CanonRuntimeInventoryEntry {
|
|
|
397
429
|
label: string;
|
|
398
430
|
status?: CanonRuntimeInventoryStatus;
|
|
399
431
|
description?: string;
|
|
432
|
+
tier?: CanonRuntimeDetailTier;
|
|
433
|
+
sensitive?: boolean;
|
|
434
|
+
visibility?: CanonRuntimeVisibility;
|
|
400
435
|
}
|
|
401
436
|
export interface CanonRuntimeInventory {
|
|
402
437
|
id: string;
|
|
403
438
|
label: string;
|
|
404
439
|
entries: ReadonlyArray<CanonRuntimeInventoryEntry>;
|
|
405
440
|
tier?: CanonRuntimeDetailTier;
|
|
441
|
+
sensitive?: boolean;
|
|
442
|
+
visibility?: CanonRuntimeVisibility;
|
|
406
443
|
}
|
|
407
444
|
export interface RuntimeInfoPayload {
|
|
408
445
|
descriptor: CanonRuntimeDescriptor;
|
|
@@ -640,6 +677,8 @@ export interface PermissionModeOption {
|
|
|
640
677
|
value: string;
|
|
641
678
|
label: string;
|
|
642
679
|
description?: string;
|
|
680
|
+
/** Runtime-owned risk marker; Canon enforces owner-only selection generically. */
|
|
681
|
+
ownerOnly?: boolean;
|
|
643
682
|
}
|
|
644
683
|
export declare const CLAUDE_PERMISSION_MODE_OPTIONS: readonly [{
|
|
645
684
|
readonly value: "default";
|
|
@@ -653,12 +692,15 @@ export declare const CLAUDE_PERMISSION_MODE_OPTIONS: readonly [{
|
|
|
653
692
|
}, {
|
|
654
693
|
readonly value: "dontAsk";
|
|
655
694
|
readonly label: "Don't ask";
|
|
695
|
+
readonly ownerOnly: true;
|
|
656
696
|
}, {
|
|
657
697
|
readonly value: "bypassPermissions";
|
|
658
698
|
readonly label: "Bypass";
|
|
699
|
+
readonly ownerOnly: true;
|
|
659
700
|
}, {
|
|
660
701
|
readonly value: "auto";
|
|
661
702
|
readonly label: "Auto";
|
|
703
|
+
readonly ownerOnly: true;
|
|
662
704
|
}];
|
|
663
705
|
export interface AgentRuntime {
|
|
664
706
|
clientType?: AgentClientType;
|
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
|
};
|
|
@@ -36,7 +45,7 @@ export const CLAUDE_PERMISSION_MODE_OPTIONS = [
|
|
|
36
45
|
{ value: 'default', label: 'Default' },
|
|
37
46
|
{ value: 'acceptEdits', label: 'Auto-edit' },
|
|
38
47
|
{ value: 'plan', label: 'Plan' },
|
|
39
|
-
{ value: 'dontAsk', label: "Don't ask" },
|
|
40
|
-
{ value: 'bypassPermissions', label: 'Bypass' },
|
|
41
|
-
{ value: 'auto', label: 'Auto' },
|
|
48
|
+
{ value: 'dontAsk', label: "Don't ask", ownerOnly: true },
|
|
49
|
+
{ value: 'bypassPermissions', label: 'Bypass', ownerOnly: true },
|
|
50
|
+
{ value: 'auto', label: 'Auto', ownerOnly: true },
|
|
42
51
|
];
|