@adhdev/daemon-core 0.9.76-rc.60 → 0.9.76-rc.62
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/commands/chat-commands.d.ts +2 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +818 -311
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +811 -316
- package/dist/index.mjs.map +1 -1
- package/dist/providers/chat-message-normalization.d.ts +35 -6
- package/dist/providers/cli-provider-instance.d.ts +4 -1
- package/dist/providers/contracts.d.ts +20 -1
- package/dist/providers/io-contracts.d.ts +17 -1
- package/dist/providers/provider-input-support.d.ts +18 -2
- package/dist/providers/provider-instance.d.ts +2 -0
- package/dist/shared-types.d.ts +4 -0
- package/package.json +1 -1
- package/src/chat/subscription-updates.ts +3 -1
- package/src/commands/chat-commands.ts +40 -5
- package/src/commands/mesh-coordinator.ts +8 -1
- package/src/commands/router.ts +4 -0
- package/src/index.ts +13 -1
- package/src/mesh/coordinator-prompt.ts +7 -0
- package/src/providers/acp-provider-instance.ts +118 -30
- package/src/providers/chat-message-normalization.ts +211 -50
- package/src/providers/cli-provider-instance.ts +96 -5
- package/src/providers/contracts.ts +25 -1
- package/src/providers/io-contracts.ts +63 -5
- package/src/providers/provider-input-support.ts +125 -1
- package/src/providers/provider-instance.ts +2 -0
- package/src/providers/provider-schema.ts +38 -8
- package/src/shared-types.ts +4 -0
- package/src/status/builders.ts +5 -3
|
@@ -2,6 +2,31 @@ import type { ChatMessage } from '../types.js';
|
|
|
2
2
|
export declare const BUILTIN_CHAT_MESSAGE_KINDS: readonly ["standard", "thought", "tool", "terminal", "system"];
|
|
3
3
|
export type BuiltinChatMessageKind = typeof BUILTIN_CHAT_MESSAGE_KINDS[number];
|
|
4
4
|
export type ChatMessageKind = BuiltinChatMessageKind | (string & {});
|
|
5
|
+
export declare const CHAT_MESSAGE_VISIBILITIES: readonly ["user", "debug", "internal", "hidden"];
|
|
6
|
+
export declare const CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES: readonly ["visible", "chat", "user", "debug", "internal", "hidden"];
|
|
7
|
+
export declare const CHAT_MESSAGE_AUDIENCES: readonly ["chat", "debug", "trace", "internal"];
|
|
8
|
+
export declare const CHAT_MESSAGE_SOURCES: readonly ["assistant_text", "tool_call", "terminal_command", "runtime_activity", "runtime_status", "provider_chrome", "control"];
|
|
9
|
+
export declare const CHAT_MESSAGE_ACTIVITY_SOURCES: readonly ["tool_call", "terminal_command", "runtime_activity"];
|
|
10
|
+
export declare const CHAT_MESSAGE_INTERNAL_SOURCES: readonly ["runtime_status", "provider_chrome", "control"];
|
|
11
|
+
export type ChatMessageVisibility = typeof CHAT_MESSAGE_VISIBILITIES[number] | (string & {});
|
|
12
|
+
export type ChatMessageTranscriptVisibility = typeof CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES[number] | (string & {});
|
|
13
|
+
export type ChatMessageAudience = typeof CHAT_MESSAGE_AUDIENCES[number] | (string & {});
|
|
14
|
+
export type ChatMessageSource = typeof CHAT_MESSAGE_SOURCES[number] | (string & {});
|
|
15
|
+
export type ChatMessageTranscriptSurface = 'chat' | 'activity' | 'internal';
|
|
16
|
+
export interface ChatMessageVisibilityClassification {
|
|
17
|
+
surface: ChatMessageTranscriptSurface;
|
|
18
|
+
isUserFacing: boolean;
|
|
19
|
+
isActivityFacing: boolean;
|
|
20
|
+
isInternal: boolean;
|
|
21
|
+
explicitUserFacing: boolean;
|
|
22
|
+
explicitHidden: boolean;
|
|
23
|
+
role: string;
|
|
24
|
+
kind: ChatMessageKind;
|
|
25
|
+
visibility: string;
|
|
26
|
+
transcriptVisibility: string;
|
|
27
|
+
audience: string;
|
|
28
|
+
source: string;
|
|
29
|
+
}
|
|
5
30
|
export declare function isBuiltinChatMessageKind(kind: unknown): kind is BuiltinChatMessageKind;
|
|
6
31
|
export declare function normalizeChatMessageKind(kind: unknown, role: unknown): ChatMessageKind;
|
|
7
32
|
export declare function resolveChatMessageKind<T extends ChatMessage>(message: T): ChatMessageKind;
|
|
@@ -64,13 +89,17 @@ export declare function buildUserChatMessage<T extends Omit<ChatMessage, 'role'
|
|
|
64
89
|
export declare function normalizeChatMessage<T extends ChatMessage>(message: T): T;
|
|
65
90
|
export declare function normalizeChatMessages<T extends ChatMessage>(messages: T[] | null | undefined): T[];
|
|
66
91
|
/**
|
|
67
|
-
*
|
|
92
|
+
* Shared transcript visibility protocol for all ADHDev provider chat messages.
|
|
68
93
|
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* marks a non-standard row as user-facing. This keeps internal tool/status/control
|
|
73
|
-
* plumbing out of the ordinary transcript without matching provider-specific text.
|
|
94
|
+
* Producers can stamp visibility/audience/source/userFacing/internal/debug either
|
|
95
|
+
* at the top level or under `meta`. Consumers should use this classifier instead
|
|
96
|
+
* of matching command text, icons, provider names, or terminal UI fragments.
|
|
74
97
|
*/
|
|
98
|
+
export declare function classifyChatMessageVisibility(message: ChatMessage | null | undefined): ChatMessageVisibilityClassification;
|
|
75
99
|
export declare function isUserFacingChatMessage(message: ChatMessage | null | undefined): boolean;
|
|
100
|
+
export declare function isActivityChatMessage(message: ChatMessage | null | undefined): boolean;
|
|
101
|
+
export declare function isInternalChatMessage(message: ChatMessage | null | undefined): boolean;
|
|
76
102
|
export declare function filterUserFacingChatMessages<T extends ChatMessage>(messages: T[] | null | undefined): T[];
|
|
103
|
+
export declare function filterActivityChatMessages<T extends ChatMessage>(messages: T[] | null | undefined): T[];
|
|
104
|
+
export declare function filterInternalChatMessages<T extends ChatMessage>(messages: T[] | null | undefined): T[];
|
|
105
|
+
export declare function filterChatMessagesByVisibility<T extends ChatMessage>(messages: T[] | null | undefined, surface: ChatMessageTranscriptSurface): T[];
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Lifecycle layer on top of ProviderCliAdapter.
|
|
5
5
|
* collectCliData() + status transition logic from daemon-status.ts moved here.
|
|
6
6
|
*/
|
|
7
|
-
import { type ProviderModule } from './contracts.js';
|
|
7
|
+
import { type ProviderModule, type InputEnvelope } from './contracts.js';
|
|
8
8
|
import type { ProviderInstance, ProviderState, InstanceContext, HotChatSessionState, SessionModalState } from './provider-instance.js';
|
|
9
9
|
import { ProviderCliAdapter } from '../cli-adapters/provider-cli-adapter.js';
|
|
10
10
|
import type { PtyTransportFactory } from '../cli-adapters/pty-transport.js';
|
|
@@ -16,6 +16,9 @@ type PersistableCliHistoryMessage = {
|
|
|
16
16
|
senderName?: string;
|
|
17
17
|
receivedAt?: number;
|
|
18
18
|
};
|
|
19
|
+
export declare function buildCliStructuredInputPrompt(input: InputEnvelope, options?: {
|
|
20
|
+
materializeDir?: string;
|
|
21
|
+
}): string;
|
|
19
22
|
export declare function buildIncrementalHistoryAppendMessages(previousMessages: PersistableCliHistoryMessage[], currentMessages: PersistableCliHistoryMessage[]): PersistableCliHistoryMessage[];
|
|
20
23
|
export declare function getForcedNewSessionScriptName(provider: ProviderModule | undefined, launchMode: 'new' | 'resume' | 'manual'): string | null;
|
|
21
24
|
export declare function waitForCliAdapterReady(adapter: {
|
|
@@ -87,7 +87,7 @@ export interface ProviderEffect {
|
|
|
87
87
|
* ContentBlock — ACP ContentBlock union type
|
|
88
88
|
* Represents displayable content in messages, tool call results, etc.
|
|
89
89
|
*/
|
|
90
|
-
export type ContentBlock = TextBlock | ImageBlock | AudioBlock | ResourceLinkBlock | ResourceBlock;
|
|
90
|
+
export type ContentBlock = TextBlock | ImageBlock | AudioBlock | VideoBlock | ResourceLinkBlock | ResourceBlock;
|
|
91
91
|
/** Text content — ACP TextContent */
|
|
92
92
|
export interface TextBlock {
|
|
93
93
|
type: 'text';
|
|
@@ -100,6 +100,7 @@ export interface ImageBlock {
|
|
|
100
100
|
data: string;
|
|
101
101
|
mimeType: string;
|
|
102
102
|
uri?: string;
|
|
103
|
+
alt?: string;
|
|
103
104
|
annotations?: ContentAnnotations;
|
|
104
105
|
}
|
|
105
106
|
/** Audio content — ACP AudioContent */
|
|
@@ -107,6 +108,18 @@ export interface AudioBlock {
|
|
|
107
108
|
type: 'audio';
|
|
108
109
|
data: string;
|
|
109
110
|
mimeType: string;
|
|
111
|
+
uri?: string;
|
|
112
|
+
transcript?: string;
|
|
113
|
+
annotations?: ContentAnnotations;
|
|
114
|
+
}
|
|
115
|
+
/** Video content — ADHDev canonical display block. ACP prompt input degrades video to resource_link/text. */
|
|
116
|
+
export interface VideoBlock {
|
|
117
|
+
type: 'video';
|
|
118
|
+
data?: string;
|
|
119
|
+
mimeType: string;
|
|
120
|
+
uri?: string;
|
|
121
|
+
transcript?: string;
|
|
122
|
+
posterUri?: string;
|
|
110
123
|
annotations?: ContentAnnotations;
|
|
111
124
|
}
|
|
112
125
|
/** Resource link (file reference) — ACP ResourceLink */
|
|
@@ -487,6 +500,12 @@ export interface ProviderModule {
|
|
|
487
500
|
input?: {
|
|
488
501
|
multipart?: boolean;
|
|
489
502
|
mediaTypes?: Array<'text' | 'image' | 'audio' | 'video' | 'resource'>;
|
|
503
|
+
strategies?: Array<{
|
|
504
|
+
mediaType: 'text' | 'image' | 'audio' | 'video' | 'resource';
|
|
505
|
+
strategies?: Array<'native' | 'native_acp' | 'resource_link' | 'text_fallback' | 'paste' | 'upload'>;
|
|
506
|
+
native?: boolean;
|
|
507
|
+
degradation?: Array<'native' | 'native_acp' | 'resource_link' | 'text_fallback' | 'paste' | 'upload'>;
|
|
508
|
+
}>;
|
|
490
509
|
};
|
|
491
510
|
output?: {
|
|
492
511
|
richContent?: boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ContentAnnotations } from './contracts.js';
|
|
2
|
-
export type InputPart = TextInputPart | ImageInputPart | AudioInputPart | VideoInputPart | ResourceInputPart;
|
|
2
|
+
export type InputPart = TextInputPart | ImageInputPart | AudioInputPart | VideoInputPart | ResourceLinkInputPart | ResourceInputPart;
|
|
3
3
|
export interface TextInputPart {
|
|
4
4
|
type: 'text';
|
|
5
5
|
text: string;
|
|
@@ -23,6 +23,7 @@ export interface VideoInputPart {
|
|
|
23
23
|
mimeType: string;
|
|
24
24
|
uri?: string;
|
|
25
25
|
data?: string;
|
|
26
|
+
transcript?: string;
|
|
26
27
|
posterUri?: string;
|
|
27
28
|
}
|
|
28
29
|
export interface ResourceInputPart {
|
|
@@ -33,6 +34,16 @@ export interface ResourceInputPart {
|
|
|
33
34
|
text?: string;
|
|
34
35
|
data?: string;
|
|
35
36
|
}
|
|
37
|
+
export interface ResourceLinkInputPart {
|
|
38
|
+
type: 'resource_link';
|
|
39
|
+
uri: string;
|
|
40
|
+
name: string;
|
|
41
|
+
title?: string;
|
|
42
|
+
description?: string;
|
|
43
|
+
mimeType?: string;
|
|
44
|
+
size?: number;
|
|
45
|
+
annotations?: ContentAnnotations;
|
|
46
|
+
}
|
|
36
47
|
export interface InputEnvelope {
|
|
37
48
|
parts: InputPart[];
|
|
38
49
|
textFallback: string;
|
|
@@ -52,6 +63,7 @@ export interface ImageMessagePart {
|
|
|
52
63
|
mimeType: string;
|
|
53
64
|
uri?: string;
|
|
54
65
|
data?: string;
|
|
66
|
+
alt?: string;
|
|
55
67
|
annotations?: ContentAnnotations;
|
|
56
68
|
}
|
|
57
69
|
export interface AudioMessagePart {
|
|
@@ -67,6 +79,7 @@ export interface VideoMessagePart {
|
|
|
67
79
|
mimeType: string;
|
|
68
80
|
uri?: string;
|
|
69
81
|
data?: string;
|
|
82
|
+
transcript?: string;
|
|
70
83
|
posterUri?: string;
|
|
71
84
|
annotations?: ContentAnnotations;
|
|
72
85
|
}
|
|
@@ -74,8 +87,11 @@ export interface ResourceLinkMessagePart {
|
|
|
74
87
|
type: 'resource_link';
|
|
75
88
|
uri: string;
|
|
76
89
|
name: string;
|
|
90
|
+
title?: string;
|
|
91
|
+
description?: string;
|
|
77
92
|
mimeType?: string;
|
|
78
93
|
size?: number;
|
|
94
|
+
annotations?: ContentAnnotations;
|
|
79
95
|
}
|
|
80
96
|
export interface ResourceMessagePart {
|
|
81
97
|
type: 'resource';
|
|
@@ -1,9 +1,25 @@
|
|
|
1
1
|
import type { InputEnvelope, ProviderModule } from './contracts.js';
|
|
2
|
-
type InputMediaType = 'text' | 'image' | 'audio' | 'video' | 'resource';
|
|
2
|
+
export type InputMediaType = 'text' | 'image' | 'audio' | 'video' | 'resource';
|
|
3
|
+
export type InputAttachmentStrategy = 'native' | 'native_acp' | 'resource_link' | 'text_fallback' | 'paste' | 'upload';
|
|
4
|
+
export interface InputMediaStrategyDescriptor {
|
|
5
|
+
mediaType: InputMediaType;
|
|
6
|
+
strategies: InputAttachmentStrategy[];
|
|
7
|
+
native?: boolean;
|
|
8
|
+
degradation?: InputAttachmentStrategy[];
|
|
9
|
+
}
|
|
10
|
+
export interface MessageInputSupport {
|
|
11
|
+
text: boolean;
|
|
12
|
+
multipart: boolean;
|
|
13
|
+
mediaTypes: InputMediaType[];
|
|
14
|
+
strategies: InputMediaStrategyDescriptor[];
|
|
15
|
+
}
|
|
16
|
+
export declare const TEXT_ONLY_MESSAGE_INPUT_SUPPORT: MessageInputSupport;
|
|
3
17
|
export declare function assertTextOnlyInput(provider: Pick<ProviderModule, 'name' | 'type'> | null | undefined, input: InputEnvelope): void;
|
|
4
18
|
export declare function getDeclaredProviderInputSupport(provider?: Pick<ProviderModule, 'capabilities'> | null): {
|
|
5
19
|
multipart: boolean;
|
|
6
20
|
mediaTypes: Set<InputMediaType>;
|
|
21
|
+
strategies: InputMediaStrategyDescriptor[];
|
|
7
22
|
};
|
|
23
|
+
export declare function normalizeInputStrategyDescriptors(raw: unknown): InputMediaStrategyDescriptor[];
|
|
24
|
+
export declare function getEffectiveMessageInputSupport(provider?: Pick<ProviderModule, 'category' | 'capabilities'> | null, runtimeCapabilities?: Record<string, any> | null): MessageInputSupport;
|
|
8
25
|
export declare function assertProviderSupportsDeclaredInput(provider: Pick<ProviderModule, 'name' | 'type' | 'capabilities'> | null | undefined, input: InputEnvelope): void;
|
|
9
|
-
export {};
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import type { ProviderModule, ProviderResumeCapability } from './contracts.js';
|
|
11
11
|
import type { AcpConfigOption, AcpMode, ProviderControlSchema, ProviderSummaryMetadata, SessionCapability } from '../shared-types.js';
|
|
12
|
+
import type { MessageInputSupport } from './provider-input-support.js';
|
|
12
13
|
import type { ChatMessage } from '../types.js';
|
|
13
14
|
export type ProviderStatus = 'idle' | 'generating' | 'waiting_approval' | 'error' | 'stopped' | 'starting';
|
|
14
15
|
export interface ProviderRuntimeWriteOwner {
|
|
@@ -71,6 +72,7 @@ interface ProviderStateBase {
|
|
|
71
72
|
runtime?: ProviderRuntimeInfo;
|
|
72
73
|
resume?: ProviderResumeCapability;
|
|
73
74
|
sessionCapabilities?: SessionCapability[];
|
|
75
|
+
messageInput?: MessageInputSupport;
|
|
74
76
|
/** Dynamic control current values */
|
|
75
77
|
controlValues?: Record<string, string | number | boolean>;
|
|
76
78
|
/** Provider-declared controls schema (from provider.controls) */
|
package/dist/shared-types.d.ts
CHANGED
|
@@ -240,7 +240,9 @@ export type SessionTransport = 'cdp-page' | 'cdp-webview' | 'pty' | 'acp';
|
|
|
240
240
|
export type SessionKind = 'workspace' | 'agent';
|
|
241
241
|
export type SessionCapability = 'read_chat' | 'send_message' | 'new_session' | 'list_sessions' | 'switch_session' | 'resolve_action' | 'open_panel' | 'terminal_io' | 'resize_terminal' | 'change_model' | 'set_mode' | 'set_thought_level' | 'delete_notification' | 'mark_notification_unread';
|
|
242
242
|
import type { RuntimeWriteOwner, RuntimeAttachedClient, SessionStatus } from './shared-types-extra.js';
|
|
243
|
+
import type { MessageInputSupport } from './providers/provider-input-support.js';
|
|
243
244
|
export type { RuntimeWriteOwner, RuntimeAttachedClient, SessionStatus } from './shared-types-extra.js';
|
|
245
|
+
export type { MessageInputSupport, InputMediaStrategyDescriptor, InputAttachmentStrategy, InputMediaType } from './providers/provider-input-support.js';
|
|
244
246
|
export interface SessionEntry {
|
|
245
247
|
id: string;
|
|
246
248
|
parentId: string | null;
|
|
@@ -267,6 +269,8 @@ export interface SessionEntry {
|
|
|
267
269
|
resume?: ProviderResumeCapability;
|
|
268
270
|
activeChat: SessionActiveChatData | null;
|
|
269
271
|
capabilities?: SessionCapability[];
|
|
272
|
+
/** Effective message input/media support for this session. Defaults fail-closed to text-only. */
|
|
273
|
+
messageInput?: MessageInputSupport;
|
|
270
274
|
cdpConnected?: boolean;
|
|
271
275
|
/** Dynamic control current values (generic key-value) */
|
|
272
276
|
controlValues?: Record<string, string | number | boolean>;
|
package/package.json
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
buildSessionModalDeliverySignature,
|
|
9
9
|
} from './chat-signatures.js'
|
|
10
10
|
import { normalizeManagedStatus } from '../status/normalize.js'
|
|
11
|
+
import { filterUserFacingChatMessages, normalizeChatMessages } from '../providers/chat-message-normalization.js'
|
|
11
12
|
|
|
12
13
|
export interface ChatTailSubscriptionCursor {
|
|
13
14
|
tailLimit: number
|
|
@@ -101,7 +102,8 @@ export function prepareSessionChatTailUpdate(
|
|
|
101
102
|
}
|
|
102
103
|
}
|
|
103
104
|
|
|
104
|
-
const
|
|
105
|
+
const fullMessages = normalizeChatMessages(Array.isArray(result.messages) ? result.messages as any[] : [])
|
|
106
|
+
const messages = filterUserFacingChatMessages(fullMessages)
|
|
105
107
|
const title = typeof result.title === 'string' ? result.title : undefined
|
|
106
108
|
const activeModal = normalizeChatTailActiveModal(result.activeModal)
|
|
107
109
|
const status = typeof result.status === 'string' ? result.status : 'idle'
|
|
@@ -16,7 +16,7 @@ import type { ProviderInstance } from '../providers/provider-instance.js';
|
|
|
16
16
|
import { readProviderChatHistory } from '../config/chat-history.js';
|
|
17
17
|
import { LOG, getRecentLogs } from '../logging/logger.js';
|
|
18
18
|
import { getRecentDebugTrace, recordDebugTrace } from '../logging/debug-trace.js';
|
|
19
|
-
import { buildChatMessageSignature } from '../chat/chat-signatures.js';
|
|
19
|
+
import { buildChatMessageSignature, hashSignatureParts } from '../chat/chat-signatures.js';
|
|
20
20
|
import type { ChatMessage } from '../types.js';
|
|
21
21
|
import type { SessionTransport } from '../shared-types.js';
|
|
22
22
|
import { filterUserFacingChatMessages, normalizeChatMessages } from '../providers/chat-message-normalization.js';
|
|
@@ -93,10 +93,32 @@ function buildRecentSendKey(h: CommandHelpers, args: any, provider: ProviderModu
|
|
|
93
93
|
return `${transport}:${target}:${signature.trim()}`;
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
function
|
|
96
|
+
function summarizeSendInputPart(part: any): string {
|
|
97
|
+
if (!part || typeof part !== 'object') return String(part ?? '');
|
|
98
|
+
if (part.type === 'text') return `text:${String(part.text || '').trim()}`;
|
|
99
|
+
const fields = [
|
|
100
|
+
`type=${String(part.type || '')}`,
|
|
101
|
+
`mime=${String(part.mimeType || '')}`,
|
|
102
|
+
`uri=${String(part.uri || '')}`,
|
|
103
|
+
`name=${String(part.name || '')}`,
|
|
104
|
+
];
|
|
105
|
+
const data = typeof part.data === 'string'
|
|
106
|
+
? part.data
|
|
107
|
+
: typeof part.resource?.blob === 'string'
|
|
108
|
+
? part.resource.blob
|
|
109
|
+
: '';
|
|
110
|
+
if (data) fields.push(`dataLen=${data.length}`, `dataHash=${hashSignatureParts([data]).slice(0, 12)}`);
|
|
111
|
+
const textish = [part.alt, part.transcript, part.description, part.title, part.resource?.uri]
|
|
112
|
+
.filter((value) => typeof value === 'string' && value.trim())
|
|
113
|
+
.join('\u001f');
|
|
114
|
+
if (textish) fields.push(`meta=${hashSignatureParts([textish]).slice(0, 12)}`);
|
|
115
|
+
return fields.join(';');
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function buildSendInputSignature(input: InputEnvelope): string {
|
|
97
119
|
const text = typeof input.textFallback === 'string' ? input.textFallback.trim() : '';
|
|
98
|
-
|
|
99
|
-
return
|
|
120
|
+
const partSummaries = (input.parts || []).map(summarizeSendInputPart);
|
|
121
|
+
return hashSignatureParts([text, ...partSummaries]);
|
|
100
122
|
}
|
|
101
123
|
|
|
102
124
|
function getSendChatInputEnvelope(args: any): InputEnvelope {
|
|
@@ -1140,12 +1162,25 @@ export async function handleSendChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
1140
1162
|
}
|
|
1141
1163
|
}
|
|
1142
1164
|
|
|
1143
|
-
// PTY transport:
|
|
1165
|
+
// PTY transport: route structured input through the provider instance so
|
|
1166
|
+
// provider-specific CLI attachment strategies (for example Hermes file-path
|
|
1167
|
+
// image prompts) are applied instead of collapsing everything to text.
|
|
1144
1168
|
if (transport === 'pty') {
|
|
1145
1169
|
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
1146
1170
|
if (adapter) {
|
|
1147
1171
|
_log(`${transport} adapter: ${adapter.cliType}`);
|
|
1148
1172
|
try {
|
|
1173
|
+
const hasStructuredParts = input.parts.some((part) => part.type !== 'text');
|
|
1174
|
+
if (hasStructuredParts) {
|
|
1175
|
+
const target = getTargetInstance(h, args);
|
|
1176
|
+
if (!target || target.category !== 'cli') {
|
|
1177
|
+
return { success: false, error: `CLI instance not found for ${provider?.type || args?.agentType || 'unknown'}` };
|
|
1178
|
+
}
|
|
1179
|
+
assertProviderSupportsDeclaredInput(provider, input);
|
|
1180
|
+
await waitOnceForFreshHermesCliStart(adapter, _log);
|
|
1181
|
+
target.onEvent('send_message', { input });
|
|
1182
|
+
return _logSendSuccess(`${transport}-instance`, target.type);
|
|
1183
|
+
}
|
|
1149
1184
|
assertTextOnlyInput(provider, input);
|
|
1150
1185
|
if (!text) return { success: false, error: 'text required for PTY send' };
|
|
1151
1186
|
await waitOnceForFreshHermesCliStart(adapter, _log);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { execFileSync } from 'node:child_process'
|
|
2
|
+
import { createHash } from 'node:crypto'
|
|
2
3
|
import { existsSync, readdirSync, realpathSync } from 'node:fs'
|
|
3
4
|
import { createRequire } from 'node:module'
|
|
4
5
|
import * as os from 'node:os'
|
|
@@ -64,7 +65,7 @@ function resolveHermesMeshCoordinatorSetup(options: ResolveMeshCoordinatorSetupO
|
|
|
64
65
|
reason: 'Could not resolve the ADHDev MCP server entrypoint and a Node runtime with WebSocket support for daemon IPC mode',
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
|
-
const configPath =
|
|
68
|
+
const configPath = join(resolveHermesCoordinatorHome(options.meshId, options.workspace), 'config.yaml')
|
|
68
69
|
if (!configPath.trim()) {
|
|
69
70
|
return createHermesManualMeshCoordinatorSetup(options.meshId, options.workspace)
|
|
70
71
|
}
|
|
@@ -177,6 +178,12 @@ function renderMeshCoordinatorTemplate(template: string, values: Record<string,
|
|
|
177
178
|
return template.replace(/\{\{\s*(meshId|workspace|serverName|adhdevMcpCommand)\s*\}\}/g, (_, key: string) => values[key] || '')
|
|
178
179
|
}
|
|
179
180
|
|
|
181
|
+
function resolveHermesCoordinatorHome(meshId: string, workspace: string): string {
|
|
182
|
+
const key = `${meshId || 'mesh'}\n${resolve(workspace || os.tmpdir())}`
|
|
183
|
+
const hash = createHash('sha256').update(key).digest('hex').slice(0, 16)
|
|
184
|
+
return join(os.tmpdir(), `adhdev-hermes-mesh-coordinator-${hash}`)
|
|
185
|
+
}
|
|
186
|
+
|
|
180
187
|
function resolveMcpConfigPath(configPath: string, workspace: string): string {
|
|
181
188
|
const trimmed = configPath.trim()
|
|
182
189
|
if (trimmed === '~') return os.homedir()
|
package/src/commands/router.ts
CHANGED
|
@@ -1672,6 +1672,10 @@ export class DaemonCommandRouter {
|
|
|
1672
1672
|
|
|
1673
1673
|
const cliArgs: string[] = [];
|
|
1674
1674
|
const launchEnv: Record<string, string> = {};
|
|
1675
|
+
if (configFormat === 'hermes_config_yaml') {
|
|
1676
|
+
launchEnv.HERMES_HOME = dirname(mcpConfigPath);
|
|
1677
|
+
launchEnv.HERMES_IGNORE_USER_CONFIG = '';
|
|
1678
|
+
}
|
|
1675
1679
|
if (systemPrompt) {
|
|
1676
1680
|
if (configFormat === 'hermes_config_yaml') {
|
|
1677
1681
|
launchEnv.HERMES_EPHEMERAL_SYSTEM_PROMPT = systemPrompt;
|
package/src/index.ts
CHANGED
|
@@ -312,10 +312,22 @@ export {
|
|
|
312
312
|
buildUserChatMessage,
|
|
313
313
|
normalizeChatMessage,
|
|
314
314
|
normalizeChatMessages,
|
|
315
|
+
CHAT_MESSAGE_VISIBILITIES,
|
|
316
|
+
CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES,
|
|
317
|
+
CHAT_MESSAGE_AUDIENCES,
|
|
318
|
+
CHAT_MESSAGE_SOURCES,
|
|
319
|
+
CHAT_MESSAGE_ACTIVITY_SOURCES,
|
|
320
|
+
CHAT_MESSAGE_INTERNAL_SOURCES,
|
|
321
|
+
classifyChatMessageVisibility,
|
|
315
322
|
isUserFacingChatMessage,
|
|
323
|
+
isActivityChatMessage,
|
|
324
|
+
isInternalChatMessage,
|
|
316
325
|
filterUserFacingChatMessages,
|
|
326
|
+
filterActivityChatMessages,
|
|
327
|
+
filterInternalChatMessages,
|
|
328
|
+
filterChatMessagesByVisibility,
|
|
317
329
|
} from './providers/chat-message-normalization.js';
|
|
318
|
-
export type { BuiltinChatMessageKind, ChatMessageKind } from './providers/chat-message-normalization.js';
|
|
330
|
+
export type { BuiltinChatMessageKind, ChatMessageKind, ChatMessageVisibility, ChatMessageTranscriptVisibility, ChatMessageAudience, ChatMessageSource, ChatMessageTranscriptSurface, ChatMessageVisibilityClassification } from './providers/chat-message-normalization.js';
|
|
319
331
|
export { VersionArchive, detectAllVersions } from './providers/version-archive.js';
|
|
320
332
|
export type { ProviderVersionInfo, VersionHistory } from './providers/version-archive.js';
|
|
321
333
|
|
|
@@ -52,6 +52,9 @@ Repository: \`${mesh.repoIdentity}\`${mesh.defaultBranch ? `\nDefault branch: \`
|
|
|
52
52
|
// ── Tools ──
|
|
53
53
|
sections.push(TOOLS_SECTION);
|
|
54
54
|
|
|
55
|
+
// ── Tool Exposure Preflight ──
|
|
56
|
+
sections.push(TOOL_EXPOSURE_PREFLIGHT_SECTION);
|
|
57
|
+
|
|
55
58
|
// ── Workflow ──
|
|
56
59
|
sections.push(WORKFLOW_SECTION);
|
|
57
60
|
|
|
@@ -136,6 +139,10 @@ const TOOLS_SECTION = `## Available Tools
|
|
|
136
139
|
| \`mesh_clone_node\` | Create a worktree node for isolated parallel branch work |
|
|
137
140
|
| \`mesh_remove_node\` | Remove a node (cleans up worktree if applicable) |`;
|
|
138
141
|
|
|
142
|
+
const TOOL_EXPOSURE_PREFLIGHT_SECTION = `## Tool Exposure Preflight
|
|
143
|
+
|
|
144
|
+
Before doing any coordinator work, confirm that the actual callable tool list includes \`mesh_status\` and the other \`mesh_*\` tools from the table above. If this Repo Mesh coordinator prompt is present but the callable \`mesh_*\` tools are missing, the MCP server/tool manifest is stale or not injected yet. Do not substitute terminal/file/git tools, do not inspect or edit the repository directly, and do not continue as a non-mesh local coding agent. Stop immediately and tell the user to run \`/reload-mcp\` or start a fresh coordinator session so ADHDev can reconnect \`adhdev-mesh\`.`;
|
|
145
|
+
|
|
139
146
|
const WORKFLOW_SECTION = `## Orchestration Workflow
|
|
140
147
|
|
|
141
148
|
1. **Assess** — Call \`mesh_status\` to see which nodes are healthy and available.
|