mirror of
https://github.com/davidkaya/aryx.git
synced 2026-08-07 12:18:44 +02:00
feat: full Copilot SDK feature parity — custom agents, hooks, image input, skills, steering, session persistence
Backend (sidecar): - Extended ProtocolModels with DTOs for custom agents, hooks, skills, infinite sessions, session lifecycle, and 9 new event types - Added CopilotManagedSessionIds for stable SDK session ID mapping - Added CopilotSessionManager/ICopilotSessionManager for session lifecycle - Added CopilotSessionHooks for hook registration - Added CopilotMessageOptionsMetadata for mid-turn steering - Extended CopilotAgentBundle to wire custom agents, hooks, skills, infinite sessions, and stable session IDs - Extended CopilotTurnExecutionState to project 13 new SDK event types - Widened ITurnWorkflowRunner callback to accept SidecarEventDto - Added list/delete/disconnect session commands to SidecarProtocolHost - Added AryxCopilotAgentMessageOptionsTests (14 new tests, 142 total) Frontend (renderer + main + shared): - Added ChatMessageAttachment type and helpers (attachment.ts) - Extended sidecar contracts with MessageMode, 3 new command types, 9 new event types, and agent/session config DTOs - Extended SessionEventRecord with 6 new event kinds and ~20 fields - Added PatternAgentCopilotConfig to pattern domain - Added attachments support to ChatMessageRecord - Updated sidecar client with session lifecycle methods and turn-scoped event routing via onTurnScopedEvent callback - Updated main process: handleTurnScopedEvent(), deleteSession(), steering bypass for mid-turn messages, attachment passthrough - Added deleteSession IPC handler and preload binding - Added TurnEventLog state tracker with format/apply/prune helpers - ChatPane: always-enabled composer, steering indicator, attachment picker with preview, image thumbnails in message history, context-usage bar, amber steer mode for send button - ActivityPanel: turn events section with sub-agent, hook, skill, and compaction event rendering - Sidebar: delete session action in context menu - App.tsx: wired sessionUsage, turnEventLogs, and deleteSession Documentation: - AGENTS.md: added glob safety rule for node_modules - README.md: added steering, image input, and richer observability - ARCHITECTURE.md: added turn-scoped events, steering, and attachments - Website: added steering and image input feature cards, updated live visibility and session cards Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
export type ChatMessageAttachmentType = 'file' | 'blob';
|
||||
|
||||
export interface ChatMessageAttachment {
|
||||
type: ChatMessageAttachmentType;
|
||||
path?: string;
|
||||
data?: string;
|
||||
mimeType?: string;
|
||||
displayName?: string;
|
||||
}
|
||||
|
||||
const supportedImageMimeTypes = new Set([
|
||||
'image/jpeg',
|
||||
'image/png',
|
||||
'image/gif',
|
||||
'image/webp',
|
||||
]);
|
||||
|
||||
export function isImageAttachment(attachment: ChatMessageAttachment): boolean {
|
||||
if (attachment.mimeType) {
|
||||
return supportedImageMimeTypes.has(attachment.mimeType);
|
||||
}
|
||||
|
||||
if (attachment.path) {
|
||||
const ext = attachment.path.split('.').pop()?.toLowerCase();
|
||||
return ext === 'jpg' || ext === 'jpeg' || ext === 'png' || ext === 'gif' || ext === 'webp';
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getAttachmentDisplayName(attachment: ChatMessageAttachment): string {
|
||||
if (attachment.displayName) {
|
||||
return attachment.displayName;
|
||||
}
|
||||
|
||||
if (attachment.path) {
|
||||
const parts = attachment.path.replace(/\\/g, '/').split('/');
|
||||
return parts[parts.length - 1] || attachment.path;
|
||||
}
|
||||
|
||||
return attachment.mimeType ?? 'Attachment';
|
||||
}
|
||||
@@ -8,7 +8,15 @@ export type SessionEventKind =
|
||||
| 'message-complete'
|
||||
| 'agent-activity'
|
||||
| 'run-updated'
|
||||
| 'error';
|
||||
| 'error'
|
||||
| 'subagent'
|
||||
| 'skill-invoked'
|
||||
| 'hook-lifecycle'
|
||||
| 'session-usage'
|
||||
| 'session-compaction'
|
||||
| 'pending-messages-modified';
|
||||
|
||||
export type SubagentEventKind = 'started' | 'completed' | 'failed' | 'selected' | 'deselected';
|
||||
|
||||
export interface SessionEventRecord {
|
||||
sessionId: string;
|
||||
@@ -27,4 +35,32 @@ export interface SessionEventRecord {
|
||||
toolName?: string;
|
||||
run?: SessionRunRecord;
|
||||
error?: string;
|
||||
|
||||
// Subagent event fields
|
||||
subagentEventKind?: SubagentEventKind;
|
||||
customAgentName?: string;
|
||||
customAgentDisplayName?: string;
|
||||
|
||||
// Skill invoked fields
|
||||
skillName?: string;
|
||||
skillPath?: string;
|
||||
pluginName?: string;
|
||||
|
||||
// Hook lifecycle fields
|
||||
hookInvocationId?: string;
|
||||
hookType?: string;
|
||||
hookPhase?: 'start' | 'end';
|
||||
hookSuccess?: boolean;
|
||||
|
||||
// Session usage fields
|
||||
tokenLimit?: number;
|
||||
currentTokens?: number;
|
||||
messagesLength?: number;
|
||||
|
||||
// Session compaction fields
|
||||
compactionPhase?: 'start' | 'complete';
|
||||
compactionSuccess?: boolean;
|
||||
preCompactionTokens?: number;
|
||||
postCompactionTokens?: number;
|
||||
tokensRemoved?: number;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ export const reasoningEffortOptions: ReadonlyArray<{ value: ReasoningEffort; lab
|
||||
{ value: 'xhigh', label: 'Maximum' },
|
||||
];
|
||||
|
||||
import type { PatternAgentCopilotConfig } from '@shared/contracts/sidecar';
|
||||
|
||||
export interface PatternAgentDefinition {
|
||||
id: string;
|
||||
name: string;
|
||||
@@ -39,6 +41,7 @@ export interface PatternAgentDefinition {
|
||||
instructions: string;
|
||||
model: string;
|
||||
reasoningEffort?: ReasoningEffort;
|
||||
copilot?: PatternAgentCopilotConfig;
|
||||
}
|
||||
|
||||
export interface PatternGraphPosition {
|
||||
|
||||
@@ -14,6 +14,7 @@ import type { SessionRunRecord } from '@shared/domain/runTimeline';
|
||||
import type { PendingUserInputRecord } from '@shared/domain/userInput';
|
||||
import type { PendingPlanReviewRecord } from '@shared/domain/planReview';
|
||||
import type { PendingMcpAuthRecord } from '@shared/domain/mcpAuth';
|
||||
import type { ChatMessageAttachment } from '@shared/domain/attachment';
|
||||
import type { InteractionMode } from '@shared/contracts/sidecar';
|
||||
|
||||
export type ChatRole = 'system' | 'user' | 'assistant';
|
||||
@@ -32,6 +33,7 @@ export interface ChatMessageRecord {
|
||||
content: string;
|
||||
createdAt: string;
|
||||
pending?: boolean;
|
||||
attachments?: ChatMessageAttachment[];
|
||||
}
|
||||
|
||||
export interface SessionRecord {
|
||||
|
||||
Reference in New Issue
Block a user