@nextclaw/ncp 0.1.1 → 0.3.0
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/README.md +1 -1
- package/dist/index.d.ts +281 -93
- package/dist/index.js +113 -25
- package/package.json +1 -5
package/README.md
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -163,7 +163,7 @@ type NcpEndpointLatency = "realtime" | "seconds" | "minutes" | "hours" | "days";
|
|
|
163
163
|
*
|
|
164
164
|
* Consumers use the manifest for runtime capability discovery —
|
|
165
165
|
* e.g. whether to show a typing indicator, whether to offer file uploads,
|
|
166
|
-
* or whether
|
|
166
|
+
* or whether an existing run can be streamed again.
|
|
167
167
|
*/
|
|
168
168
|
type NcpEndpointManifest = {
|
|
169
169
|
/** Category of this endpoint. */
|
|
@@ -178,8 +178,8 @@ type NcpEndpointManifest = {
|
|
|
178
178
|
supportsAbort: boolean;
|
|
179
179
|
/** Whether this endpoint can push messages without a prior user request. */
|
|
180
180
|
supportsProactiveMessages: boolean;
|
|
181
|
-
/** Whether
|
|
182
|
-
|
|
181
|
+
/** Whether this endpoint can stream the live events of an active session by `sessionId`. */
|
|
182
|
+
supportsLiveSessionStream: boolean;
|
|
183
183
|
/**
|
|
184
184
|
* The subset of `NcpMessagePart` types this endpoint can send or receive.
|
|
185
185
|
* Using the literal union from `NcpMessagePart["type"]` prevents typos
|
|
@@ -215,20 +215,6 @@ type NcpError = {
|
|
|
215
215
|
/** Original cause — preserved for debugging but not guaranteed serializable. */
|
|
216
216
|
cause?: unknown;
|
|
217
217
|
};
|
|
218
|
-
/**
|
|
219
|
-
* Throwable form of `NcpError` for use in exception-based control flows.
|
|
220
|
-
*
|
|
221
|
-
* Bridges typed protocol errors with standard JS `Error` hierarchies so that
|
|
222
|
-
* `instanceof` checks and stack traces work as expected.
|
|
223
|
-
*
|
|
224
|
-
* @example
|
|
225
|
-
* throw new NcpErrorException("auth-error", "Missing API key");
|
|
226
|
-
*/
|
|
227
|
-
declare class NcpErrorException extends Error {
|
|
228
|
-
readonly code: NcpErrorCode;
|
|
229
|
-
readonly details?: Record<string, unknown>;
|
|
230
|
-
constructor(code: NcpErrorCode, message: string, details?: Record<string, unknown>);
|
|
231
|
-
}
|
|
232
218
|
|
|
233
219
|
type NcpSessionStatus = "idle" | "running";
|
|
234
220
|
type NcpSessionSummary = {
|
|
@@ -236,7 +222,7 @@ type NcpSessionSummary = {
|
|
|
236
222
|
messageCount: number;
|
|
237
223
|
updatedAt: string;
|
|
238
224
|
status?: NcpSessionStatus;
|
|
239
|
-
|
|
225
|
+
metadata?: Record<string, unknown>;
|
|
240
226
|
};
|
|
241
227
|
type ListSessionsOptions = {
|
|
242
228
|
limit?: number;
|
|
@@ -295,20 +281,17 @@ type NcpMessageAcceptedPayload = {
|
|
|
295
281
|
correlationId?: string;
|
|
296
282
|
transportId?: string;
|
|
297
283
|
};
|
|
298
|
-
/** Payload for message.abort: identifies which
|
|
284
|
+
/** Payload for message.abort: identifies which session's active execution to cancel. */
|
|
299
285
|
type NcpMessageAbortPayload = {
|
|
286
|
+
sessionId: string;
|
|
300
287
|
messageId?: string;
|
|
301
|
-
correlationId?: string;
|
|
302
|
-
runId?: string;
|
|
303
288
|
};
|
|
304
289
|
/**
|
|
305
|
-
* Payload for message.
|
|
306
|
-
* Used when reconnecting
|
|
290
|
+
* Payload for message.stream-request: attach to the live event stream of a session.
|
|
291
|
+
* Used when reconnecting during an active response or attaching another live reader.
|
|
307
292
|
*/
|
|
308
|
-
type
|
|
293
|
+
type NcpStreamRequestPayload = {
|
|
309
294
|
sessionId: string;
|
|
310
|
-
remoteRunId: string;
|
|
311
|
-
fromEventIndex?: number;
|
|
312
295
|
metadata?: Record<string, unknown>;
|
|
313
296
|
};
|
|
314
297
|
/**
|
|
@@ -435,100 +418,134 @@ type NcpToolCallResultPayload = {
|
|
|
435
418
|
toolCallId: string;
|
|
436
419
|
content: unknown;
|
|
437
420
|
};
|
|
421
|
+
declare enum NcpEventType {
|
|
422
|
+
EndpointReady = "endpoint.ready",
|
|
423
|
+
EndpointError = "endpoint.error",
|
|
424
|
+
MessageRequest = "message.request",
|
|
425
|
+
MessageStreamRequest = "message.stream-request",
|
|
426
|
+
MessageSent = "message.sent",
|
|
427
|
+
MessageAccepted = "message.accepted",
|
|
428
|
+
MessageIncoming = "message.incoming",
|
|
429
|
+
MessageCompleted = "message.completed",
|
|
430
|
+
MessageFailed = "message.failed",
|
|
431
|
+
MessageAbort = "message.abort",
|
|
432
|
+
MessageTextStart = "message.text-start",
|
|
433
|
+
MessageTextDelta = "message.text-delta",
|
|
434
|
+
MessageTextEnd = "message.text-end",
|
|
435
|
+
MessageReasoningStart = "message.reasoning-start",
|
|
436
|
+
MessageReasoningDelta = "message.reasoning-delta",
|
|
437
|
+
MessageReasoningEnd = "message.reasoning-end",
|
|
438
|
+
MessageToolCallStart = "message.tool-call-start",
|
|
439
|
+
MessageToolCallArgs = "message.tool-call-args",
|
|
440
|
+
MessageToolCallArgsDelta = "message.tool-call-args-delta",
|
|
441
|
+
MessageToolCallEnd = "message.tool-call-end",
|
|
442
|
+
MessageToolCallResult = "message.tool-call-result",
|
|
443
|
+
MessageRead = "message.read",
|
|
444
|
+
MessageDelivered = "message.delivered",
|
|
445
|
+
MessageRecalled = "message.recalled",
|
|
446
|
+
MessageReaction = "message.reaction",
|
|
447
|
+
RunStarted = "run.started",
|
|
448
|
+
RunFinished = "run.finished",
|
|
449
|
+
RunError = "run.error",
|
|
450
|
+
RunMetadata = "run.metadata",
|
|
451
|
+
TypingStart = "typing.start",
|
|
452
|
+
TypingEnd = "typing.end",
|
|
453
|
+
PresenceUpdated = "presence.updated"
|
|
454
|
+
}
|
|
438
455
|
type NcpEndpointEvent = {
|
|
439
|
-
type:
|
|
456
|
+
type: NcpEventType.EndpointReady;
|
|
440
457
|
} | {
|
|
441
|
-
type:
|
|
458
|
+
type: NcpEventType.MessageRequest;
|
|
442
459
|
payload: NcpRequestEnvelope;
|
|
443
460
|
} | {
|
|
444
|
-
type:
|
|
445
|
-
payload:
|
|
461
|
+
type: NcpEventType.MessageStreamRequest;
|
|
462
|
+
payload: NcpStreamRequestPayload;
|
|
446
463
|
} | {
|
|
447
|
-
type:
|
|
464
|
+
type: NcpEventType.MessageSent;
|
|
448
465
|
payload: NcpMessageSentPayload;
|
|
449
466
|
} | {
|
|
450
|
-
type:
|
|
467
|
+
type: NcpEventType.MessageAccepted;
|
|
451
468
|
payload: NcpMessageAcceptedPayload;
|
|
452
469
|
} | {
|
|
453
|
-
type:
|
|
470
|
+
type: NcpEventType.MessageIncoming;
|
|
454
471
|
payload: NcpResponseEnvelope;
|
|
455
472
|
} | {
|
|
456
|
-
type:
|
|
473
|
+
type: NcpEventType.MessageCompleted;
|
|
457
474
|
payload: NcpCompletedEnvelope;
|
|
458
475
|
} | {
|
|
459
|
-
type:
|
|
476
|
+
type: NcpEventType.MessageFailed;
|
|
460
477
|
payload: NcpFailedEnvelope;
|
|
461
478
|
} | {
|
|
462
|
-
type:
|
|
479
|
+
type: NcpEventType.MessageAbort;
|
|
463
480
|
payload: NcpMessageAbortPayload;
|
|
464
481
|
} | {
|
|
465
|
-
type:
|
|
482
|
+
type: NcpEventType.EndpointError;
|
|
466
483
|
payload: NcpError;
|
|
467
484
|
} | {
|
|
468
|
-
type:
|
|
485
|
+
type: NcpEventType.RunStarted;
|
|
469
486
|
payload: NcpRunStartedPayload;
|
|
470
487
|
} | {
|
|
471
|
-
type:
|
|
488
|
+
type: NcpEventType.RunFinished;
|
|
472
489
|
payload: NcpRunFinishedPayload;
|
|
473
490
|
} | {
|
|
474
|
-
type:
|
|
491
|
+
type: NcpEventType.RunError;
|
|
475
492
|
payload: NcpRunErrorPayload;
|
|
476
493
|
} | {
|
|
477
|
-
type:
|
|
494
|
+
type: NcpEventType.RunMetadata;
|
|
478
495
|
payload: NcpRunMetadataPayload;
|
|
479
496
|
} | {
|
|
480
|
-
type:
|
|
497
|
+
type: NcpEventType.MessageTextStart;
|
|
481
498
|
payload: NcpTextStartPayload;
|
|
482
499
|
} | {
|
|
483
|
-
type:
|
|
500
|
+
type: NcpEventType.MessageTextDelta;
|
|
484
501
|
payload: NcpTextDeltaPayload;
|
|
485
502
|
} | {
|
|
486
|
-
type:
|
|
503
|
+
type: NcpEventType.MessageTextEnd;
|
|
487
504
|
payload: NcpTextEndPayload;
|
|
488
505
|
} | {
|
|
489
|
-
type:
|
|
506
|
+
type: NcpEventType.MessageReasoningStart;
|
|
490
507
|
payload: NcpReasoningStartPayload;
|
|
491
508
|
} | {
|
|
492
|
-
type:
|
|
509
|
+
type: NcpEventType.MessageReasoningDelta;
|
|
493
510
|
payload: NcpReasoningDeltaPayload;
|
|
494
511
|
} | {
|
|
495
|
-
type:
|
|
512
|
+
type: NcpEventType.MessageReasoningEnd;
|
|
496
513
|
payload: NcpReasoningEndPayload;
|
|
497
514
|
} | {
|
|
498
|
-
type:
|
|
515
|
+
type: NcpEventType.MessageToolCallStart;
|
|
499
516
|
payload: NcpToolCallStartPayload;
|
|
500
517
|
} | {
|
|
501
|
-
type:
|
|
518
|
+
type: NcpEventType.MessageToolCallArgs;
|
|
502
519
|
payload: NcpToolCallArgsPayload;
|
|
503
520
|
} | {
|
|
504
|
-
type:
|
|
521
|
+
type: NcpEventType.MessageToolCallArgsDelta;
|
|
505
522
|
payload: NcpToolCallArgsDeltaPayload;
|
|
506
523
|
} | {
|
|
507
|
-
type:
|
|
524
|
+
type: NcpEventType.MessageToolCallEnd;
|
|
508
525
|
payload: NcpToolCallEndPayload;
|
|
509
526
|
} | {
|
|
510
|
-
type:
|
|
527
|
+
type: NcpEventType.MessageToolCallResult;
|
|
511
528
|
payload: NcpToolCallResultPayload;
|
|
512
529
|
} | {
|
|
513
|
-
type:
|
|
530
|
+
type: NcpEventType.TypingStart;
|
|
514
531
|
payload: NcpTypingStartPayload;
|
|
515
532
|
} | {
|
|
516
|
-
type:
|
|
533
|
+
type: NcpEventType.TypingEnd;
|
|
517
534
|
payload: NcpTypingEndPayload;
|
|
518
535
|
} | {
|
|
519
|
-
type:
|
|
536
|
+
type: NcpEventType.PresenceUpdated;
|
|
520
537
|
payload: NcpPresenceUpdatedPayload;
|
|
521
538
|
} | {
|
|
522
|
-
type:
|
|
539
|
+
type: NcpEventType.MessageRead;
|
|
523
540
|
payload: NcpMessageReadPayload;
|
|
524
541
|
} | {
|
|
525
|
-
type:
|
|
542
|
+
type: NcpEventType.MessageDelivered;
|
|
526
543
|
payload: NcpMessageDeliveredPayload;
|
|
527
544
|
} | {
|
|
528
|
-
type:
|
|
545
|
+
type: NcpEventType.MessageRecalled;
|
|
529
546
|
payload: NcpMessageRecalledPayload;
|
|
530
547
|
} | {
|
|
531
|
-
type:
|
|
548
|
+
type: NcpEventType.MessageReaction;
|
|
532
549
|
payload: NcpMessageReactionPayload;
|
|
533
550
|
};
|
|
534
551
|
type NcpEndpointSubscriber = (event: NcpEndpointEvent) => void;
|
|
@@ -568,7 +585,7 @@ type NcpRunFinalMetadata = {
|
|
|
568
585
|
* const endpoint: NcpEndpoint = new MyAgentEndpoint(options);
|
|
569
586
|
* await endpoint.start();
|
|
570
587
|
* endpoint.subscribe((event) => { ... });
|
|
571
|
-
* await endpoint.emit({ type:
|
|
588
|
+
* await endpoint.emit({ type: NcpEventType.MessageRequest, payload: envelope });
|
|
572
589
|
*/
|
|
573
590
|
interface NcpEndpoint {
|
|
574
591
|
/** Static capability declaration — available before `start()` is called. */
|
|
@@ -598,7 +615,7 @@ interface NcpEndpoint {
|
|
|
598
615
|
*
|
|
599
616
|
* @example
|
|
600
617
|
* const unsubscribe = endpoint.subscribe((event) => {
|
|
601
|
-
* if (event.type ===
|
|
618
|
+
* if (event.type === NcpEventType.MessageCompleted) handleReply(event.payload);
|
|
602
619
|
* });
|
|
603
620
|
* unsubscribe();
|
|
604
621
|
*/
|
|
@@ -614,60 +631,222 @@ interface NcpEndpoint {
|
|
|
614
631
|
interface NcpAgentClientEndpoint extends NcpEndpoint {
|
|
615
632
|
/** Sends a new message request to the agent. Emits `message.request`. */
|
|
616
633
|
send(envelope: NcpRequestEnvelope): Promise<void>;
|
|
617
|
-
/**
|
|
618
|
-
|
|
619
|
-
/** Aborts the
|
|
620
|
-
abort(payload
|
|
634
|
+
/** Attaches to the live event stream of a session. Emits `message.stream-request`. */
|
|
635
|
+
stream(payload: NcpStreamRequestPayload): Promise<void>;
|
|
636
|
+
/** Aborts the active execution of a session. Emits `message.abort`. */
|
|
637
|
+
abort(payload: NcpMessageAbortPayload): Promise<void>;
|
|
621
638
|
}
|
|
622
639
|
|
|
623
640
|
/**
|
|
624
|
-
* Agent server-side endpoint: receives requests and
|
|
641
|
+
* Agent server-side endpoint: receives requests and produces downstream events.
|
|
625
642
|
*
|
|
626
643
|
* Extends `NcpEndpoint` with a manifest constraint (`endpointKind: "agent"`).
|
|
627
|
-
* Use this on the server side that
|
|
628
|
-
*
|
|
644
|
+
* Use this on the server side that handles send/stream/abort requests and emits
|
|
645
|
+
* downstream events (`message.incoming`, streaming deltas, `message.completed`, etc.).
|
|
629
646
|
*/
|
|
630
647
|
interface NcpAgentServerEndpoint extends NcpEndpoint {
|
|
631
648
|
readonly manifest: NcpEndpointManifest & {
|
|
632
649
|
endpointKind: "agent";
|
|
633
650
|
};
|
|
651
|
+
/** Handles a new message request from client side and yields produced events. */
|
|
652
|
+
send(envelope: NcpRequestEnvelope, options?: {
|
|
653
|
+
signal?: AbortSignal;
|
|
654
|
+
}): AsyncIterable<NcpEndpointEvent>;
|
|
655
|
+
/** Streams live events for an active session and yields produced events. */
|
|
656
|
+
stream(payload: NcpStreamRequestPayload, options?: {
|
|
657
|
+
signal?: AbortSignal;
|
|
658
|
+
}): AsyncIterable<NcpEndpointEvent>;
|
|
659
|
+
/** Aborts the active execution of a session on server side. */
|
|
660
|
+
abort(payload: NcpMessageAbortPayload): Promise<void>;
|
|
661
|
+
/**
|
|
662
|
+
* Publishes server-downstream events (typically sent to frontend subscribers/transports).
|
|
663
|
+
* For handling client requests, prefer `send` / `stream` / `abort`.
|
|
664
|
+
*/
|
|
665
|
+
emit(event: NcpEndpointEvent): Promise<void>;
|
|
634
666
|
}
|
|
635
667
|
|
|
636
|
-
/**
|
|
637
|
-
* Creates an NcpAgentClientEndpoint that forwards to an in-process NcpAgentServerEndpoint.
|
|
638
|
-
* Use when the agent runs in-process and you need to pass a client endpoint to the HTTP server.
|
|
639
|
-
*/
|
|
640
|
-
declare function createAgentClientFromServer(server: NcpAgentServerEndpoint): NcpAgentClientEndpoint;
|
|
641
|
-
|
|
642
668
|
type NcpAgentRunInput = {
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
payload: NcpResumeRequestPayload;
|
|
669
|
+
sessionId: string;
|
|
670
|
+
messages: ReadonlyArray<NcpMessage>;
|
|
671
|
+
correlationId?: string;
|
|
672
|
+
metadata?: Record<string, unknown>;
|
|
648
673
|
};
|
|
649
674
|
type NcpAgentRunOptions = {
|
|
650
675
|
signal?: AbortSignal;
|
|
651
|
-
sessionMessages?: ReadonlyArray<NcpMessage>;
|
|
652
676
|
};
|
|
653
677
|
interface NcpAgentRuntime {
|
|
654
678
|
run(input: NcpAgentRunInput, options?: NcpAgentRunOptions): AsyncIterable<NcpEndpointEvent>;
|
|
655
679
|
}
|
|
656
680
|
|
|
657
|
-
type
|
|
681
|
+
type OpenAIContentPart = {
|
|
682
|
+
type: "text";
|
|
683
|
+
text: string;
|
|
684
|
+
} | {
|
|
685
|
+
type: "image_url";
|
|
686
|
+
image_url: {
|
|
687
|
+
url: string;
|
|
688
|
+
detail?: "low" | "high" | "auto";
|
|
689
|
+
};
|
|
690
|
+
};
|
|
691
|
+
type OpenAIToolCall = {
|
|
692
|
+
id: string;
|
|
693
|
+
type: "function";
|
|
694
|
+
function: {
|
|
695
|
+
name: string;
|
|
696
|
+
arguments: string;
|
|
697
|
+
};
|
|
698
|
+
};
|
|
699
|
+
type OpenAIChatMessage = {
|
|
700
|
+
role: "system";
|
|
701
|
+
content: string;
|
|
702
|
+
} | {
|
|
703
|
+
role: "user";
|
|
704
|
+
content: string | OpenAIContentPart[];
|
|
705
|
+
} | {
|
|
706
|
+
role: "assistant";
|
|
707
|
+
content?: string | null;
|
|
708
|
+
reasoning_content?: string;
|
|
709
|
+
tool_calls?: OpenAIToolCall[];
|
|
710
|
+
} | {
|
|
711
|
+
role: "tool";
|
|
712
|
+
content: string;
|
|
713
|
+
tool_call_id: string;
|
|
714
|
+
};
|
|
715
|
+
type OpenAITool = {
|
|
716
|
+
type: "function";
|
|
717
|
+
function: {
|
|
718
|
+
name: string;
|
|
719
|
+
description?: string;
|
|
720
|
+
parameters?: Record<string, unknown>;
|
|
721
|
+
};
|
|
722
|
+
};
|
|
723
|
+
type OpenAIToolCallDelta = {
|
|
724
|
+
index?: number;
|
|
725
|
+
id?: string;
|
|
726
|
+
type?: "function";
|
|
727
|
+
function?: {
|
|
728
|
+
name?: string;
|
|
729
|
+
arguments?: string;
|
|
730
|
+
};
|
|
731
|
+
};
|
|
732
|
+
type OpenAIChatChunk = {
|
|
733
|
+
id?: string;
|
|
734
|
+
choices?: Array<{
|
|
735
|
+
index?: number;
|
|
736
|
+
delta?: {
|
|
737
|
+
content?: string | null;
|
|
738
|
+
tool_calls?: OpenAIToolCallDelta[];
|
|
739
|
+
reasoning_content?: string;
|
|
740
|
+
reasoning?: string;
|
|
741
|
+
};
|
|
742
|
+
finish_reason?: string | null;
|
|
743
|
+
}>;
|
|
744
|
+
usage?: {
|
|
745
|
+
prompt_tokens?: number;
|
|
746
|
+
completion_tokens?: number;
|
|
747
|
+
total_tokens?: number;
|
|
748
|
+
};
|
|
749
|
+
};
|
|
750
|
+
type NcpLLMApiInput = {
|
|
751
|
+
messages: OpenAIChatMessage[];
|
|
752
|
+
tools?: OpenAITool[];
|
|
753
|
+
model?: string;
|
|
754
|
+
thinkingLevel?: string | null;
|
|
755
|
+
max_tokens?: number;
|
|
756
|
+
};
|
|
757
|
+
type NcpLLMApiOptions = {
|
|
658
758
|
signal?: AbortSignal;
|
|
759
|
+
temperature?: number;
|
|
760
|
+
};
|
|
761
|
+
interface NcpLLMApi {
|
|
762
|
+
generate(input: NcpLLMApiInput, options?: NcpLLMApiOptions): AsyncIterable<OpenAIChatChunk>;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
type NcpContextPrepareOptions = {
|
|
766
|
+
sessionMessages?: ReadonlyArray<NcpMessage>;
|
|
767
|
+
systemPrompt?: string;
|
|
768
|
+
maxMessages?: number;
|
|
769
|
+
};
|
|
770
|
+
interface NcpContextBuilder {
|
|
771
|
+
prepare(input: NcpAgentRunInput, options?: NcpContextPrepareOptions): NcpLLMApiInput;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
type NcpToolDefinition = {
|
|
775
|
+
name: string;
|
|
776
|
+
description?: string;
|
|
777
|
+
parameters?: Record<string, unknown>;
|
|
778
|
+
};
|
|
779
|
+
interface NcpTool {
|
|
780
|
+
readonly name: string;
|
|
781
|
+
readonly description?: string;
|
|
782
|
+
readonly parameters?: Record<string, unknown>;
|
|
783
|
+
execute(args: unknown): Promise<unknown>;
|
|
784
|
+
}
|
|
785
|
+
type NcpToolCallResult = {
|
|
786
|
+
toolCallId: string;
|
|
787
|
+
toolName: string;
|
|
788
|
+
args: Record<string, unknown> | null;
|
|
789
|
+
rawArgsText: string;
|
|
790
|
+
result: unknown;
|
|
791
|
+
};
|
|
792
|
+
type NcpInvalidToolArgumentsResult = {
|
|
793
|
+
ok: false;
|
|
794
|
+
error: {
|
|
795
|
+
code: "invalid_tool_arguments";
|
|
796
|
+
message: string;
|
|
797
|
+
toolCallId: string;
|
|
798
|
+
toolName: string;
|
|
799
|
+
rawArgumentsText: string;
|
|
800
|
+
issues: string[];
|
|
801
|
+
};
|
|
659
802
|
};
|
|
660
|
-
|
|
803
|
+
interface NcpToolRegistry {
|
|
804
|
+
listTools(): ReadonlyArray<NcpTool>;
|
|
805
|
+
getTool(name: string): NcpTool | undefined;
|
|
806
|
+
getToolDefinitions(): ReadonlyArray<NcpToolDefinition>;
|
|
807
|
+
execute(toolCallId: string, toolName: string, args: unknown): Promise<unknown>;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
type NcpEncodeContext = {
|
|
811
|
+
sessionId: string;
|
|
812
|
+
messageId: string;
|
|
813
|
+
runId: string;
|
|
814
|
+
correlationId?: string;
|
|
815
|
+
};
|
|
816
|
+
interface NcpStreamEncoder {
|
|
817
|
+
encode(stream: AsyncIterable<OpenAIChatChunk>, context: NcpEncodeContext): AsyncIterable<NcpEndpointEvent>;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
type NcpPendingToolCall = {
|
|
821
|
+
toolCallId: string;
|
|
822
|
+
toolName: string;
|
|
823
|
+
args: unknown;
|
|
824
|
+
};
|
|
825
|
+
interface NcpRoundBuffer {
|
|
826
|
+
appendText(delta: string): void;
|
|
827
|
+
getText(): string;
|
|
828
|
+
appendToolCall(result: NcpToolCallResult): void;
|
|
829
|
+
getToolCalls(): ReadonlyArray<NcpToolCallResult>;
|
|
830
|
+
startToolCall(toolCallId: string, toolName: string): void;
|
|
831
|
+
appendToolCallArgs(args: unknown): void;
|
|
832
|
+
consumePendingToolCall(): NcpPendingToolCall | null;
|
|
833
|
+
clear(): void;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
type NcpAgentRunSendOptions = {
|
|
837
|
+
signal?: AbortSignal;
|
|
838
|
+
};
|
|
839
|
+
type NcpAgentRunStreamOptions = {
|
|
661
840
|
signal?: AbortSignal;
|
|
662
841
|
};
|
|
663
|
-
interface
|
|
664
|
-
send(envelope: NcpRequestEnvelope, options?:
|
|
665
|
-
|
|
842
|
+
interface NcpAgentRunApi {
|
|
843
|
+
send(envelope: NcpRequestEnvelope, options?: NcpAgentRunSendOptions): AsyncIterable<NcpEndpointEvent>;
|
|
844
|
+
stream(payload: NcpStreamRequestPayload, options?: NcpAgentRunStreamOptions): AsyncIterable<NcpEndpointEvent>;
|
|
666
845
|
abort(payload: NcpMessageAbortPayload): Promise<void>;
|
|
667
846
|
}
|
|
668
|
-
type
|
|
847
|
+
type NcpAgentStreamProvider = {
|
|
669
848
|
stream(params: {
|
|
670
|
-
payload:
|
|
849
|
+
payload: NcpStreamRequestPayload;
|
|
671
850
|
signal: AbortSignal;
|
|
672
851
|
}): AsyncIterable<NcpEndpointEvent>;
|
|
673
852
|
};
|
|
@@ -716,6 +895,11 @@ interface NcpConversationStateManager {
|
|
|
716
895
|
subscribe(listener: (snapshot: NcpConversationSnapshot) => void): () => void;
|
|
717
896
|
}
|
|
718
897
|
|
|
898
|
+
type NcpAgentConversationHydrationParams = {
|
|
899
|
+
sessionId: string;
|
|
900
|
+
messages: ReadonlyArray<NcpMessage>;
|
|
901
|
+
activeRun?: NcpRunContext | null;
|
|
902
|
+
};
|
|
719
903
|
/**
|
|
720
904
|
* Agent-scenario state manager: extends the generic conversation state manager
|
|
721
905
|
* with explicit handle methods for each NCP event type that affects agent conversation state.
|
|
@@ -725,13 +909,10 @@ interface NcpConversationStateManager {
|
|
|
725
909
|
*/
|
|
726
910
|
interface NcpAgentConversationStateManager extends NcpConversationStateManager {
|
|
727
911
|
getSnapshot(): NcpAgentConversationSnapshot;
|
|
728
|
-
|
|
912
|
+
reset(): void;
|
|
913
|
+
hydrate(payload: NcpAgentConversationHydrationParams): void;
|
|
729
914
|
/** Local peer sent a message (outbound); typically non-streaming. Add to messages. */
|
|
730
915
|
handleMessageSent(payload: NcpMessageSentPayload): void;
|
|
731
|
-
handleMessageAccepted(payload: NcpMessageAcceptedPayload): void;
|
|
732
|
-
handleMessageIncoming(payload: NcpResponseEnvelope): void;
|
|
733
|
-
handleMessageCompleted(payload: NcpCompletedEnvelope): void;
|
|
734
|
-
handleMessageFailed(payload: NcpFailedEnvelope): void;
|
|
735
916
|
handleMessageAbort(payload: NcpMessageAbortPayload): void;
|
|
736
917
|
handleMessageTextStart(payload: NcpTextStartPayload): void;
|
|
737
918
|
handleMessageTextDelta(payload: NcpTextDeltaPayload): void;
|
|
@@ -751,4 +932,11 @@ interface NcpAgentConversationStateManager extends NcpConversationStateManager {
|
|
|
751
932
|
handleEndpointError(payload: NcpError): void;
|
|
752
933
|
}
|
|
753
934
|
|
|
754
|
-
|
|
935
|
+
type NcpReplyTagParseResult = {
|
|
936
|
+
content: string;
|
|
937
|
+
replyTo?: string;
|
|
938
|
+
};
|
|
939
|
+
declare function stripReplyTagsFromText(content: string, currentMessageId?: string): NcpReplyTagParseResult;
|
|
940
|
+
declare function sanitizeAssistantReplyTags(message: NcpMessage, currentMessageId?: string): NcpMessage;
|
|
941
|
+
|
|
942
|
+
export { type ListMessagesOptions, type ListSessionsOptions, type NcpActionPart, type NcpAgentClientEndpoint, type NcpAgentConversationHydrationParams, type NcpAgentConversationSnapshot, type NcpAgentConversationStateManager, type NcpAgentRunApi, type NcpAgentRunInput, type NcpAgentRunOptions, type NcpAgentRunSendOptions, type NcpAgentRunStreamOptions, type NcpAgentRuntime, type NcpAgentServerEndpoint, type NcpAgentStreamProvider, type NcpCardPart, type NcpCompletedEnvelope, type NcpContextBuilder, type NcpContextPrepareOptions, type NcpConversationSnapshot, type NcpConversationStateManager, type NcpEncodeContext, type NcpEndpoint, type NcpEndpointEvent, type NcpEndpointKind, type NcpEndpointLatency, type NcpEndpointManifest, type NcpEndpointSubscriber, type NcpError, type NcpErrorCode, NcpEventType, type NcpExtensionPart, type NcpFailedEnvelope, type NcpFilePart, type NcpInvalidToolArgumentsResult, type NcpLLMApi, type NcpLLMApiInput, type NcpLLMApiOptions, type NcpMessage, type NcpMessageAbortPayload, type NcpMessageAcceptedPayload, type NcpMessageDeliveredPayload, type NcpMessagePart, type NcpMessageReactionPayload, type NcpMessageReadPayload, type NcpMessageRecalledPayload, type NcpMessageRole, type NcpMessageSentPayload, type NcpMessageStatus, type NcpPendingToolCall, type NcpPresenceUpdatedPayload, type NcpReasoningDeltaPayload, type NcpReasoningEndPayload, type NcpReasoningPart, type NcpReasoningStartPayload, type NcpReplyTagParseResult, type NcpRequestEnvelope, type NcpResponseEnvelope, type NcpRichTextPart, type NcpRoundBuffer, type NcpRunContext, type NcpRunErrorPayload, type NcpRunFinalMetadata, type NcpRunFinishedPayload, type NcpRunMetadataPayload, type NcpRunReadyMetadata, type NcpRunStartedPayload, type NcpSessionApi, type NcpSessionStatus, type NcpSessionSummary, type NcpSourcePart, type NcpStepStartPart, type NcpStreamEncoder, type NcpStreamRequestPayload, type NcpTextDeltaPayload, type NcpTextEndPayload, type NcpTextPart, type NcpTextStartPayload, type NcpTool, type NcpToolCallArgsDeltaPayload, type NcpToolCallArgsPayload, type NcpToolCallEndPayload, type NcpToolCallResult, type NcpToolCallResultPayload, type NcpToolCallStartPayload, type NcpToolDefinition, type NcpToolInvocationPart, type NcpToolRegistry, type NcpTypingEndPayload, type NcpTypingStartPayload, type OpenAIChatChunk, type OpenAIChatMessage, type OpenAIContentPart, type OpenAITool, type OpenAIToolCall, type OpenAIToolCallDelta, sanitizeAssistantReplyTags, stripReplyTagsFromText };
|
package/dist/index.js
CHANGED
|
@@ -1,31 +1,119 @@
|
|
|
1
|
-
// src/types/
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
// src/types/events.ts
|
|
2
|
+
var NcpEventType = /* @__PURE__ */ ((NcpEventType2) => {
|
|
3
|
+
NcpEventType2["EndpointReady"] = "endpoint.ready";
|
|
4
|
+
NcpEventType2["EndpointError"] = "endpoint.error";
|
|
5
|
+
NcpEventType2["MessageRequest"] = "message.request";
|
|
6
|
+
NcpEventType2["MessageStreamRequest"] = "message.stream-request";
|
|
7
|
+
NcpEventType2["MessageSent"] = "message.sent";
|
|
8
|
+
NcpEventType2["MessageAccepted"] = "message.accepted";
|
|
9
|
+
NcpEventType2["MessageIncoming"] = "message.incoming";
|
|
10
|
+
NcpEventType2["MessageCompleted"] = "message.completed";
|
|
11
|
+
NcpEventType2["MessageFailed"] = "message.failed";
|
|
12
|
+
NcpEventType2["MessageAbort"] = "message.abort";
|
|
13
|
+
NcpEventType2["MessageTextStart"] = "message.text-start";
|
|
14
|
+
NcpEventType2["MessageTextDelta"] = "message.text-delta";
|
|
15
|
+
NcpEventType2["MessageTextEnd"] = "message.text-end";
|
|
16
|
+
NcpEventType2["MessageReasoningStart"] = "message.reasoning-start";
|
|
17
|
+
NcpEventType2["MessageReasoningDelta"] = "message.reasoning-delta";
|
|
18
|
+
NcpEventType2["MessageReasoningEnd"] = "message.reasoning-end";
|
|
19
|
+
NcpEventType2["MessageToolCallStart"] = "message.tool-call-start";
|
|
20
|
+
NcpEventType2["MessageToolCallArgs"] = "message.tool-call-args";
|
|
21
|
+
NcpEventType2["MessageToolCallArgsDelta"] = "message.tool-call-args-delta";
|
|
22
|
+
NcpEventType2["MessageToolCallEnd"] = "message.tool-call-end";
|
|
23
|
+
NcpEventType2["MessageToolCallResult"] = "message.tool-call-result";
|
|
24
|
+
NcpEventType2["MessageRead"] = "message.read";
|
|
25
|
+
NcpEventType2["MessageDelivered"] = "message.delivered";
|
|
26
|
+
NcpEventType2["MessageRecalled"] = "message.recalled";
|
|
27
|
+
NcpEventType2["MessageReaction"] = "message.reaction";
|
|
28
|
+
NcpEventType2["RunStarted"] = "run.started";
|
|
29
|
+
NcpEventType2["RunFinished"] = "run.finished";
|
|
30
|
+
NcpEventType2["RunError"] = "run.error";
|
|
31
|
+
NcpEventType2["RunMetadata"] = "run.metadata";
|
|
32
|
+
NcpEventType2["TypingStart"] = "typing.start";
|
|
33
|
+
NcpEventType2["TypingEnd"] = "typing.end";
|
|
34
|
+
NcpEventType2["PresenceUpdated"] = "presence.updated";
|
|
35
|
+
return NcpEventType2;
|
|
36
|
+
})(NcpEventType || {});
|
|
12
37
|
|
|
13
|
-
// src/
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
38
|
+
// src/toolkit/reply-tags.ts
|
|
39
|
+
var REPLY_TO_CURRENT_PATTERN = /\[\[\s*reply_to_current\s*\]\]/gi;
|
|
40
|
+
var REPLY_TO_ID_PATTERN = /\[\[\s*reply_to\s*:\s*([^\]]+?)\s*\]\]/i;
|
|
41
|
+
function normalizeReplyTarget(value) {
|
|
42
|
+
if (typeof value !== "string") {
|
|
43
|
+
return void 0;
|
|
44
|
+
}
|
|
45
|
+
const trimmed = value.trim();
|
|
46
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
47
|
+
}
|
|
48
|
+
function stripReplyTagsFromText(content, currentMessageId) {
|
|
49
|
+
let nextContent = content;
|
|
50
|
+
let replyTo;
|
|
51
|
+
if (REPLY_TO_CURRENT_PATTERN.test(nextContent)) {
|
|
52
|
+
replyTo = normalizeReplyTarget(currentMessageId);
|
|
53
|
+
nextContent = nextContent.replace(REPLY_TO_CURRENT_PATTERN, "").trim();
|
|
54
|
+
}
|
|
55
|
+
const explicitReplyTarget = nextContent.match(REPLY_TO_ID_PATTERN)?.[1];
|
|
56
|
+
if (explicitReplyTarget) {
|
|
57
|
+
replyTo = normalizeReplyTarget(explicitReplyTarget);
|
|
58
|
+
nextContent = nextContent.replace(REPLY_TO_ID_PATTERN, "").trim();
|
|
59
|
+
}
|
|
60
|
+
return replyTo ? { content: nextContent, replyTo } : { content: nextContent };
|
|
61
|
+
}
|
|
62
|
+
function sanitizeAssistantReplyTags(message, currentMessageId = message.id) {
|
|
63
|
+
if (message.role !== "assistant") {
|
|
64
|
+
return {
|
|
65
|
+
...message,
|
|
66
|
+
parts: [...message.parts],
|
|
67
|
+
metadata: message.metadata ? { ...message.metadata } : void 0
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const firstTextIndex = message.parts.findIndex((part) => part.type === "text");
|
|
71
|
+
const nextMetadata = message.metadata ? { ...message.metadata } : void 0;
|
|
72
|
+
const existingReplyTo = normalizeReplyTarget(nextMetadata?.reply_to);
|
|
73
|
+
if (firstTextIndex < 0) {
|
|
74
|
+
return {
|
|
75
|
+
...message,
|
|
76
|
+
parts: [...message.parts],
|
|
77
|
+
metadata: nextMetadata
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const firstTextPart = message.parts[firstTextIndex];
|
|
81
|
+
if (!firstTextPart || firstTextPart.type !== "text") {
|
|
82
|
+
return {
|
|
83
|
+
...message,
|
|
84
|
+
parts: [...message.parts],
|
|
85
|
+
metadata: nextMetadata
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
const { content, replyTo } = stripReplyTagsFromText(firstTextPart.text, currentMessageId);
|
|
89
|
+
const effectiveReplyTo = replyTo ?? existingReplyTo;
|
|
90
|
+
const nextParts = message.parts.flatMap((part, index) => {
|
|
91
|
+
if (index !== firstTextIndex || part.type !== "text") {
|
|
92
|
+
return [part];
|
|
25
93
|
}
|
|
94
|
+
if (content.length === 0) {
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
return [{ ...part, text: content }];
|
|
98
|
+
});
|
|
99
|
+
if (effectiveReplyTo) {
|
|
100
|
+
return {
|
|
101
|
+
...message,
|
|
102
|
+
parts: nextParts,
|
|
103
|
+
metadata: {
|
|
104
|
+
...nextMetadata,
|
|
105
|
+
reply_to: effectiveReplyTo
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
...message,
|
|
111
|
+
parts: nextParts,
|
|
112
|
+
metadata: nextMetadata
|
|
26
113
|
};
|
|
27
114
|
}
|
|
28
115
|
export {
|
|
29
|
-
|
|
30
|
-
|
|
116
|
+
NcpEventType,
|
|
117
|
+
sanitizeAssistantReplyTags,
|
|
118
|
+
stripReplyTagsFromText
|
|
31
119
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextclaw/ncp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "NextClaw Communication Protocol core abstractions and types.",
|
|
6
6
|
"type": "module",
|
|
@@ -16,10 +16,6 @@
|
|
|
16
16
|
],
|
|
17
17
|
"devDependencies": {
|
|
18
18
|
"@types/node": "^20.17.6",
|
|
19
|
-
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
20
|
-
"@typescript-eslint/parser": "^7.18.0",
|
|
21
|
-
"eslint": "^8.57.1",
|
|
22
|
-
"eslint-config-prettier": "^9.1.0",
|
|
23
19
|
"prettier": "^3.3.3",
|
|
24
20
|
"tsup": "^8.3.5",
|
|
25
21
|
"typescript": "^5.6.3"
|