@ziggs-ai/api-client 0.38.2 → 0.39.1
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/CHANGELOG.md +23 -0
- package/README.md +14 -36
- package/dist/capabilities/agreementVerbs.js +13 -21
- package/dist/capabilities/agreements.d.ts +2 -3
- package/dist/capabilities/agreements.js +7 -42
- package/dist/capabilities/artifacts.js +41 -43
- package/dist/capabilities/connections.js +10 -7
- package/dist/capabilities/context.d.ts +1 -1
- package/dist/capabilities/context.js +41 -45
- package/dist/capabilities/discovery.js +5 -5
- package/dist/capabilities/everyday.d.ts +1 -1
- package/dist/capabilities/everyday.js +1 -2
- package/dist/capabilities/index.d.ts +1 -2
- package/dist/capabilities/index.js +1 -2
- package/dist/capabilities/introductions.d.ts +1 -1
- package/dist/capabilities/introductions.js +3 -11
- package/dist/capabilities/links.d.ts +1 -9
- package/dist/capabilities/links.js +7 -28
- package/dist/capabilities/mcpBriefs.js +22 -28
- package/dist/capabilities/messaging.d.ts +9 -0
- package/dist/capabilities/messaging.js +11 -0
- package/dist/capabilities/nextCall.js +8 -17
- package/dist/capabilities/sources.d.ts +2 -3
- package/dist/capabilities/sources.js +1 -2
- package/dist/capabilities/tasks.js +1 -1
- package/dist/capabilities/toolLane.js +2 -2
- package/dist/engagementGuide.d.ts +2 -2
- package/dist/engagementGuide.js +6 -6
- package/dist/handles.d.ts +1 -1
- package/dist/handles.js +2 -2
- package/dist/http/AgreementClient.d.ts +17 -64
- package/dist/http/AgreementClient.js +14 -65
- package/dist/http/ArtifactsClient.d.ts +17 -19
- package/dist/http/ArtifactsClient.js +30 -62
- package/dist/http/ConnectionsClient.d.ts +6 -7
- package/dist/http/ConnectionsClient.js +5 -3
- package/dist/http/ContextDiscoveryClient.d.ts +2 -2
- package/dist/http/ContextGrantsClient.d.ts +8 -15
- package/dist/http/ContextGrantsClient.js +3 -5
- package/dist/http/ContextOpenClient.d.ts +5 -6
- package/dist/http/ContextOpenClient.js +11 -4
- package/dist/http/ContextReadClient.d.ts +23 -27
- package/dist/http/ContextReadClient.js +24 -23
- package/dist/http/ExecutionContextClient.d.ts +5 -1
- package/dist/http/ExecutionContextClient.js +48 -1
- package/dist/http/IntroductionsClient.d.ts +6 -4
- package/dist/http/MessageRecordsClient.d.ts +36 -0
- package/dist/http/MessageRecordsClient.js +30 -0
- package/dist/http/SessionsClient.d.ts +5 -5
- package/dist/http/SessionsClient.js +6 -6
- package/dist/http/TaskClient.d.ts +11 -5
- package/dist/http/TaskClient.js +11 -34
- package/dist/http/agreementFlows.d.ts +2 -3
- package/dist/http/agreementFlows.js +5 -5
- package/dist/http/index.d.ts +3 -5
- package/dist/http/index.js +3 -4
- package/dist/http/operatorHeaders.d.ts +3 -0
- package/dist/http/operatorHeaders.js +14 -5
- package/dist/inboxAck.d.ts +2 -2
- package/dist/inboxAck.js +2 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/types.d.ts +15 -55
- package/package.json +2 -2
- package/dist/capabilities/chat.d.ts +0 -43
- package/dist/capabilities/chat.js +0 -196
- package/dist/capabilities/chatListFields.d.ts +0 -14
- package/dist/capabilities/chatListFields.js +0 -61
- package/dist/http/ChatClient.d.ts +0 -187
- package/dist/http/ChatClient.js +0 -219
- package/dist/http/MessagesClient.d.ts +0 -40
- package/dist/http/MessagesClient.js +0 -81
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ClaimedKind, type ClaimOptions, type
|
|
1
|
+
import { type ClaimedKind, type ClaimOptions, type ProposeTerms } from './AgreementClient.js';
|
|
2
2
|
import { type Agreement, type Creds, type EngagementKind } from '../types.js';
|
|
3
3
|
/**
|
|
4
4
|
* one propose grammar. Direct, broadcast (request and standing
|
|
@@ -13,7 +13,7 @@ import { type Agreement, type Creds, type EngagementKind } from '../types.js';
|
|
|
13
13
|
export interface UnifiedProposeInput extends ProposeTerms {
|
|
14
14
|
proposedTo: string;
|
|
15
15
|
/** Required on direct proposals; optional on broadcasts/links. */
|
|
16
|
-
|
|
16
|
+
addressId?: string;
|
|
17
17
|
engagementKind?: EngagementKind;
|
|
18
18
|
}
|
|
19
19
|
export type ProposeShape = 'direct' | 'request' | 'offer';
|
|
@@ -38,5 +38,4 @@ export declare function proposeUnified(input: UnifiedProposeInput, creds: Creds)
|
|
|
38
38
|
export declare function claimOpenAgreement(agreementId: string, creds: Creds, opts?: ClaimOptions): Promise<{
|
|
39
39
|
agreement: Agreement;
|
|
40
40
|
kind: ClaimedKind;
|
|
41
|
-
room?: ClaimRoom;
|
|
42
41
|
}>;
|
|
@@ -2,7 +2,7 @@ import { claimAgreement, proposeBroadcast, proposeDirectTo, } from './AgreementC
|
|
|
2
2
|
import { publishOffer } from './MarketplaceClient.js';
|
|
3
3
|
import { isBroadcastTarget, } from '../types.js';
|
|
4
4
|
export async function proposeUnified(input, creds) {
|
|
5
|
-
const { proposedTo,
|
|
5
|
+
const { proposedTo, addressId, engagementKind, providerId, ...terms } = input;
|
|
6
6
|
if (!proposedTo)
|
|
7
7
|
throw new Error('proposedTo is required (a user/agent id, or "everyone"/"org"/"company" to broadcast)');
|
|
8
8
|
// The 'link' arm is gone. A link is not a proposal shape: it has no
|
|
@@ -34,7 +34,7 @@ export async function proposeUnified(input, creds) {
|
|
|
34
34
|
// Buyer-broadcast: the claimer works, your side pays — an open request.
|
|
35
35
|
const agreement = await proposeBroadcast({
|
|
36
36
|
...terms,
|
|
37
|
-
|
|
37
|
+
addressId: addressId ?? '',
|
|
38
38
|
engagementKind: engagementKind ?? 'service',
|
|
39
39
|
audience,
|
|
40
40
|
}, creds);
|
|
@@ -51,7 +51,7 @@ export async function proposeUnified(input, creds) {
|
|
|
51
51
|
proposedTo,
|
|
52
52
|
// Omitted rather than sent empty: an absent field says "no room", and an
|
|
53
53
|
// empty string is one more fiction for the server to interpret.
|
|
54
|
-
...(
|
|
54
|
+
...(addressId ? { addressId } : {}),
|
|
55
55
|
providerId: providerId?.trim() || proposedTo,
|
|
56
56
|
engagementKind: engagementKind ?? 'service',
|
|
57
57
|
}, creds);
|
|
@@ -74,8 +74,8 @@ export async function proposeUnified(input, creds) {
|
|
|
74
74
|
export async function claimOpenAgreement(agreementId, creds, opts = {}) {
|
|
75
75
|
if (!agreementId)
|
|
76
76
|
throw new Error('agreementId is required');
|
|
77
|
-
const { agreement, kind
|
|
77
|
+
const { agreement, kind } = await claimAgreement(agreementId, creds, opts);
|
|
78
78
|
// A server that has not shipped the `kind` field yet still claims correctly;
|
|
79
79
|
// 'request' is the shape the route has always handled.
|
|
80
|
-
return { agreement, kind: kind ?? 'request'
|
|
80
|
+
return { agreement, kind: kind ?? 'request' };
|
|
81
81
|
}
|
package/dist/http/index.d.ts
CHANGED
|
@@ -2,13 +2,10 @@ export * from './TaskClient.js';
|
|
|
2
2
|
export * from './AgreementClient.js';
|
|
3
3
|
export * from './MarketplaceClient.js';
|
|
4
4
|
export * from './agreementFlows.js';
|
|
5
|
-
export
|
|
6
|
-
export { MessagesClient, messagesListUrl } from './MessagesClient.js';
|
|
7
|
-
export type { ListMessagesOptions, ListMessagesResult } from './MessagesClient.js';
|
|
8
|
-
export { ArtifactsClient, artifactScopeForSession, AGREEMENT_LANE_PREFIX, ARTIFACT_INLINE_TEXT_MAX_CHARS, ARTIFACT_INLINE_TEXT_OVER_LIMIT_HINT, } from './ArtifactsClient.js';
|
|
5
|
+
export { ArtifactsClient, artifactScope, AGREEMENT_LANE_PREFIX, ARTIFACT_INLINE_TEXT_MAX_CHARS, ARTIFACT_INLINE_TEXT_OVER_LIMIT_HINT, } from './ArtifactsClient.js';
|
|
9
6
|
export type { ArtifactVisibility, ListArtifactsOptions, ListArtifactsQuery, ListArtifactsResult, WriteArtifactInput, } from './ArtifactsClient.js';
|
|
10
7
|
export { ContextReadClient, CONTEXT_READ_TYPES, CONTEXT_READ_VIA, VIA_KINDS, parseVia, viaHint, } from './ContextReadClient.js';
|
|
11
|
-
export type { ContextReadType, ContextReadQuery, ContextReadEnvelope, ContextSnapshotResult, ContextSnapshotParticipant, ViaKind, } from './ContextReadClient.js';
|
|
8
|
+
export type { ContextReadType, ContextReadQuery, ContextReadEnvelope, ContextSnapshotResult, ContextSnapshotQuery, ContextSnapshotParticipant, ViaKind, } from './ContextReadClient.js';
|
|
12
9
|
export { ContextOpenClient, CONTEXT_OPEN_KINDS } from './ContextOpenClient.js';
|
|
13
10
|
export type { ContextOpenKind, ContextOpenOutcome, ContextOpenRef, ContextOpenBody, ResourceAction, ResourceActionCall, ContextOpenAccess, ContextOpenResult, ContextExplainResult, } from './ContextOpenClient.js';
|
|
14
11
|
export { ContextDiscoveryClient } from './ContextDiscoveryClient.js';
|
|
@@ -37,3 +34,4 @@ export { planInboxAck, planPartialInboxAck, inboxAckAllowed, inboxAckHandledIds,
|
|
|
37
34
|
export type { InboxAckDecision, InboxAckStep, InboxAckEnvelope, PlanInboxAckOptions, } from '../inboxAck.js';
|
|
38
35
|
export { laneUnderAgreement, buildOperatorHeaders, buildCredsHeaders, } from './operatorHeaders.js';
|
|
39
36
|
export { backendToolPick, type ToolPickOption, type ToolPickAnswer, type PickTool } from './ToolPickClient.js';
|
|
37
|
+
export * from './MessageRecordsClient.js';
|
package/dist/http/index.js
CHANGED
|
@@ -2,11 +2,9 @@ export * from './TaskClient.js';
|
|
|
2
2
|
export * from './AgreementClient.js';
|
|
3
3
|
export * from './MarketplaceClient.js';
|
|
4
4
|
export * from './agreementFlows.js';
|
|
5
|
-
export * from './ChatClient.js';
|
|
6
|
-
export { MessagesClient, messagesListUrl } from './MessagesClient.js';
|
|
7
5
|
export { ArtifactsClient,
|
|
8
|
-
//
|
|
9
|
-
|
|
6
|
+
// Artifact writes name their conversation or work; a lane is never one.
|
|
7
|
+
artifactScope, AGREEMENT_LANE_PREFIX, ARTIFACT_INLINE_TEXT_MAX_CHARS, ARTIFACT_INLINE_TEXT_OVER_LIMIT_HINT, } from './ArtifactsClient.js';
|
|
10
8
|
export { ContextReadClient, CONTEXT_READ_TYPES, CONTEXT_READ_VIA, VIA_KINDS, parseVia, viaHint, } from './ContextReadClient.js';
|
|
11
9
|
export { ContextOpenClient, CONTEXT_OPEN_KINDS } from './ContextOpenClient.js';
|
|
12
10
|
export { ContextDiscoveryClient } from './ContextDiscoveryClient.js';
|
|
@@ -28,3 +26,4 @@ export { planInboxAck, planPartialInboxAck, inboxAckAllowed, inboxAckHandledIds,
|
|
|
28
26
|
// copy of a header nobody notices missing goes stale unseen.
|
|
29
27
|
export { laneUnderAgreement, buildOperatorHeaders, buildCredsHeaders, } from './operatorHeaders.js';
|
|
30
28
|
export { backendToolPick } from './ToolPickClient.js';
|
|
29
|
+
export * from './MessageRecordsClient.js';
|
|
@@ -12,6 +12,9 @@ type AssistantHints = {
|
|
|
12
12
|
};
|
|
13
13
|
/** Node-only, opt-in request context. Ordinary HTTP clients remain browser-safe. */
|
|
14
14
|
export declare function withAssistantRequest<T>(hints: AssistantHints, run: () => T): Promise<Awaited<T>>;
|
|
15
|
+
/** Start an autonomous callback with no inherited execution, attempt or assistant hints.
|
|
16
|
+
* This is an entry boundary, never a retry of a refused scoped operation. */
|
|
17
|
+
export declare function withAutonomousRequest<T>(run: () => T): Promise<Awaited<T>>;
|
|
15
18
|
export declare function assistantRequestHeaders(): Record<string, string>;
|
|
16
19
|
/** A presentation routing key; it carries no authority. */
|
|
17
20
|
export declare function laneUnderAgreement(laneId: string, agreementId?: string | null): string;
|
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
let assistantRequest;
|
|
2
2
|
let assistantContextLoading;
|
|
3
|
-
|
|
4
|
-
export async function withAssistantRequest(hints, run) {
|
|
3
|
+
async function requestContext() {
|
|
5
4
|
assistantContextLoading ??= import('node:async_hooks').then(({ AsyncLocalStorage }) => {
|
|
6
5
|
assistantRequest = new AsyncLocalStorage();
|
|
7
6
|
return assistantRequest;
|
|
8
7
|
});
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
return assistantContextLoading;
|
|
9
|
+
}
|
|
10
|
+
/** Node-only, opt-in request context. Ordinary HTTP clients remain browser-safe. */
|
|
11
|
+
export async function withAssistantRequest(hints, run) {
|
|
12
|
+
const context = await requestContext();
|
|
12
13
|
return await context.run({ ...context.getStore(), ...hints, orgId: hints.orgId, resource: hints.resource }, run);
|
|
13
14
|
}
|
|
15
|
+
/** Start an autonomous callback with no inherited execution, attempt or assistant hints.
|
|
16
|
+
* This is an entry boundary, never a retry of a refused scoped operation. */
|
|
17
|
+
export async function withAutonomousRequest(run) {
|
|
18
|
+
return await (await requestContext()).run({}, run);
|
|
19
|
+
}
|
|
14
20
|
export function assistantRequestHeaders() {
|
|
15
21
|
const hints = assistantRequest?.getStore();
|
|
16
22
|
return {
|
|
23
|
+
...(hints?.executionContext?.attemptId ? { 'X-Ziggs-Attempt': hints.executionContext.attemptId } : {}),
|
|
17
24
|
...((hints?.executionContextId ?? hints?.executionContext?.contextId) ? { 'X-Ziggs-Execution': (hints?.executionContextId ?? hints?.executionContext?.contextId) } : {}),
|
|
18
25
|
...(hints?.orgId ? { 'X-Workspace-Id': hints.orgId } : {}),
|
|
19
26
|
...(hints?.resource ? { 'X-Ziggs-Resource': hints.resource } : {}),
|
|
@@ -49,6 +56,8 @@ export function withoutExecution(headers) {
|
|
|
49
56
|
const out = { ...headers };
|
|
50
57
|
delete out['X-Ziggs-Execution'];
|
|
51
58
|
delete out['x-ziggs-execution'];
|
|
59
|
+
delete out['X-Ziggs-Attempt'];
|
|
60
|
+
delete out['x-ziggs-attempt'];
|
|
52
61
|
return out;
|
|
53
62
|
}
|
|
54
63
|
/** What a `Creds`-shaped client sends on a JSON call: auth, agent, lane. */
|
package/dist/inboxAck.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export interface InboxAckEnvelope {
|
|
|
3
3
|
ackTo?: string | null;
|
|
4
4
|
deliveries?: ReadonlyArray<{
|
|
5
5
|
resourceId?: string | null;
|
|
6
|
-
|
|
6
|
+
receiptId?: string | null;
|
|
7
7
|
assigneeId?: string | null;
|
|
8
8
|
outOfReach?: unknown;
|
|
9
9
|
executionBlocked?: unknown;
|
|
@@ -12,7 +12,7 @@ export interface InboxAckEnvelope {
|
|
|
12
12
|
}>;
|
|
13
13
|
openRequestsAwaitingMe?: ReadonlyArray<{
|
|
14
14
|
agreementId?: string | null;
|
|
15
|
-
|
|
15
|
+
receiptId?: string | null;
|
|
16
16
|
ts?: string | null;
|
|
17
17
|
}>;
|
|
18
18
|
}
|
package/dist/inboxAck.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export function inboxAckHandledIds(envelope, ownAgentId, ownAgentIds) {
|
|
2
2
|
const mine = (id) => ownAgentIds ? ownAgentIds.includes(id ?? '') : ownAgentId ? id === ownAgentId : !!id;
|
|
3
3
|
return [...new Set([
|
|
4
|
-
...(envelope.deliveries ?? []).filter(d => mine(d.assigneeId) && !d.outOfReach && !d.executionBlocked).map(d => d.
|
|
5
|
-
...(envelope.openRequestsAwaitingMe ?? []).map(r => r.
|
|
4
|
+
...(envelope.deliveries ?? []).filter(d => mine(d.assigneeId) && !d.outOfReach && !d.executionBlocked).map(d => d.receiptId),
|
|
5
|
+
...(envelope.openRequestsAwaitingMe ?? []).map(r => r.receiptId),
|
|
6
6
|
].filter((id) => !!id))];
|
|
7
7
|
}
|
|
8
8
|
export function inboxAckAllowed(envelope, opts = {}) {
|
package/dist/index.d.ts
CHANGED
|
@@ -13,8 +13,8 @@ export type { DelegateEnv, ResolvedDelegateCreds, } from './shared/delegateCreds
|
|
|
13
13
|
export { RateLimitedError, isRateLimited, parseRetryAfterMs, pollSurfaceError, } from './shared/rateLimit.js';
|
|
14
14
|
export { parseErrorMessage, parseErrorCode, throwApiError, } from './shared/apiError.js';
|
|
15
15
|
export { ApiError } from './types.js';
|
|
16
|
-
export type { Creds, Task, TaskState, PlanStep, PlanStepStatus, Agreement, AgreementParties, AgreementPartySide, EngagementKind, BroadcastAudience, EntryType, ContentType,
|
|
17
|
-
export type { ProposeTerms, ProposeDirectInput, ProposeBroadcastInput, ProposeAgreementData, ClaimOptions,
|
|
16
|
+
export type { Creds, Task, TaskState, PlanStep, PlanStepStatus, Agreement, AgreementParties, AgreementPartySide, EngagementKind, BroadcastAudience, EntryType, ContentType, InboxDeliveryKind, InboxDeliveryRef, InboxChatNews, InboxProposalRef, InboxTaskRef, InboxRequestRef, InboxPlanAckRef, InboxConnectionRequestRef, InboxHumanAttention, InboxEnvelope, InboxAckResult, InboxPeek, InboxReadOptions, } from './types.js';
|
|
17
|
+
export type { ProposeTerms, ProposeDirectInput, ProposeBroadcastInput, ProposeAgreementData, ClaimOptions, } from './http/AgreementClient.js';
|
|
18
18
|
export { decisionWords, speakableActor } from './decisionWords.js';
|
|
19
19
|
export type { DecisionOutcome, DecisionWords, DecisionWordsInput, } from './decisionWords.js';
|
|
20
20
|
export { planInboxAck, planPartialInboxAck, inboxAckAllowed, inboxAckHandledIds, } from './inboxAck.js';
|
|
@@ -31,9 +31,9 @@ export { inboxEngagement, isEchoOrDuplicate, isHireWorkOrder, contactPath, forma
|
|
|
31
31
|
export type { EngagementGuide, EngagementGuideKind, EngagementOutcome, EngagementTaskHint, ContactPathInput, FormationInput, GraphHonesty, HireTermsHonesty, WaitingOn, } from './engagementGuide.js';
|
|
32
32
|
export { isContextAccessRequest } from './shared/contextAccessRequest.js';
|
|
33
33
|
export { AssistantConnectionClient, type AssistantWorkspace, type McpEventStatus, } from './http/AssistantConnectionClient.js';
|
|
34
|
-
export { withAssistantRequest, assistantRequestHeaders } from './http/operatorHeaders.js';
|
|
34
|
+
export { withAssistantRequest, withAutonomousRequest, assistantRequestHeaders } from './http/operatorHeaders.js';
|
|
35
35
|
export { HANDLE_ALPHABET, findHandles, looksLikeHandle, parseHandle, parseRef, type HandleKind } from './handles.js';
|
|
36
36
|
export { describeOperationError, type OperationError } from './shared/operationError.js';
|
|
37
37
|
export { withWorkExecution, withWorkExecutionId, currentWorkExecution, withoutExecution } from './http/operatorHeaders.js';
|
|
38
38
|
export { deliveryHandlingId, type WorkExecutionContext, type WorkPositionView } from '@ziggs-ai/contracts';
|
|
39
|
-
export { validateWorkExecution } from './http/ExecutionContextClient.js';
|
|
39
|
+
export { validateWorkExecution, prepareWorkExecution, runWorkExecution } from './http/ExecutionContextClient.js';
|
package/dist/index.js
CHANGED
|
@@ -28,10 +28,10 @@ export { sessionOrientation, } from './sessionOrientation.js';
|
|
|
28
28
|
export { inboxEngagement, isEchoOrDuplicate, isHireWorkOrder, contactPath, formationGuide, marketplaceFormation, liveHireChangedTerms, liveHireConflictFromStatus, withdrawHeldGraph, reminderHonesty, graphReleaseHonesty, hintsFromTasks, } from './engagementGuide.js';
|
|
29
29
|
export { isContextAccessRequest } from './shared/contextAccessRequest.js';
|
|
30
30
|
export { AssistantConnectionClient, } from './http/AssistantConnectionClient.js';
|
|
31
|
-
export { withAssistantRequest, assistantRequestHeaders } from './http/operatorHeaders.js';
|
|
31
|
+
export { withAssistantRequest, withAutonomousRequest, assistantRequestHeaders } from './http/operatorHeaders.js';
|
|
32
32
|
// Short handles: T…, A…, C…, F… (task, agreement, chat, artifact).
|
|
33
33
|
export { HANDLE_ALPHABET, findHandles, looksLikeHandle, parseHandle, parseRef } from './handles.js';
|
|
34
34
|
export { describeOperationError } from './shared/operationError.js';
|
|
35
35
|
export { withWorkExecution, withWorkExecutionId, currentWorkExecution, withoutExecution } from './http/operatorHeaders.js';
|
|
36
36
|
export { deliveryHandlingId } from '@ziggs-ai/contracts';
|
|
37
|
-
export { validateWorkExecution } from './http/ExecutionContextClient.js';
|
|
37
|
+
export { validateWorkExecution, prepareWorkExecution, runWorkExecution } from './http/ExecutionContextClient.js';
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AGREEMENT_ENGAGEMENT_KIND, BROADCAST_TARGETS, COMPANY_AGREEMENT_TARGET, OPEN_AGREEMENT_TARGET, ORG_AGREEMENT_TARGET, isBroadcastTarget, partyActorIds, partySideIds, type AgreementPartySide, type AgreementParties, type AgreementStatusValue, type BroadcastAudience, type InboxDeliveryRef, type InboxPartyKind, type InboxRequestChannel, type PrincipalPresentation, type TaskStateValue } from '@ziggs-ai/contracts';
|
|
1
|
+
import { AGREEMENT_ENGAGEMENT_KIND, BROADCAST_TARGETS, COMPANY_AGREEMENT_TARGET, OPEN_AGREEMENT_TARGET, ORG_AGREEMENT_TARGET, isBroadcastTarget, partyActorIds, partySideIds, type AgreementPartySide, type AgreementParties, type AgreementStatusValue, type BroadcastAudience, type InboxDeliveryRef, type InboxPartyKind, type InboxPlanAckChannel, type InboxRequestChannel, type PrincipalPresentation, type TaskStateValue } from '@ziggs-ai/contracts';
|
|
2
2
|
/**
|
|
3
3
|
* One failure shape for every HTTP client path.
|
|
4
4
|
*
|
|
@@ -299,57 +299,6 @@ export declare function isValidContentType(contentType: string, entryType: strin
|
|
|
299
299
|
export { isPersonaFaceRef as isPersonaRef, isRoomBindingRef as isRoomPresentationRef, isPresentationRef as isOpaquePresentationRef, } from '@ziggs-ai/contracts';
|
|
300
300
|
/** Display + entitlement face for a principal on the message/roster wire. */
|
|
301
301
|
export type { PrincipalPresentation };
|
|
302
|
-
export interface MessageMetadata {
|
|
303
|
-
chatId: string;
|
|
304
|
-
/** Stable id for dedup across push + inbox catch-up. */
|
|
305
|
-
messageId?: string;
|
|
306
|
-
userId: string;
|
|
307
|
-
sender: {
|
|
308
|
-
id: string;
|
|
309
|
-
type?: string;
|
|
310
|
-
presentation?: PrincipalPresentation | null;
|
|
311
|
-
/** Absent when the viewer is masked (persona layer). */
|
|
312
|
-
underAgreementId?: string | null;
|
|
313
|
-
presentedAs?: string | null;
|
|
314
|
-
};
|
|
315
|
-
senderId: string;
|
|
316
|
-
senderType?: string;
|
|
317
|
-
receiver?: {
|
|
318
|
-
id: string;
|
|
319
|
-
presentation?: PrincipalPresentation | null;
|
|
320
|
-
} | null;
|
|
321
|
-
receiverId?: string | null;
|
|
322
|
-
/**
|
|
323
|
-
* Message-level presentation stamp when the backend attaches one
|
|
324
|
-
* (same shape as sender.presentation). Prefer sender.presentation.
|
|
325
|
-
*/
|
|
326
|
-
presentation?: PrincipalPresentation | null;
|
|
327
|
-
entryType?: string;
|
|
328
|
-
contentType?: string;
|
|
329
|
-
taskId?: string | null;
|
|
330
|
-
/**
|
|
331
|
-
* Optional task / agreement snapshot pinned by the backend on
|
|
332
|
-
* `task.notify.chat` / `agreement.notify.direct` traffic. The agent SDK's
|
|
333
|
-
* `normalizeIncomingEvent` reads `metadata.task` to upgrade structured
|
|
334
|
-
* task notifications into `task_result` events (so executors see
|
|
335
|
-
* `task-assigned` outcomes when the orchestrator calls `task_create`),
|
|
336
|
-
* and maps explicit wire `operation` + `agreementId` lifecycle fields
|
|
337
|
-
* into `agreement_lifecycle` events for proposal approve/reject.
|
|
338
|
-
*/
|
|
339
|
-
task?: Record<string, unknown> | null;
|
|
340
|
-
agreement?: Record<string, unknown> | null;
|
|
341
|
-
operation?: string | null;
|
|
342
|
-
agreementId?: string | null;
|
|
343
|
-
/**
|
|
344
|
-
* Message send time from the wire payload. The live-path inbox
|
|
345
|
-
* watermark ack (Agent, P4) needs it — without a timestamp the
|
|
346
|
-
* ack never fires and catch-up re-delivers the chat's whole backlog after a
|
|
347
|
-
* host eviction, re-running already-answered goals.
|
|
348
|
-
*/
|
|
349
|
-
timestamp?: string;
|
|
350
|
-
sentTimestamp?: string;
|
|
351
|
-
}
|
|
352
|
-
export type MessageHandler = (text: string, metadata: MessageMetadata) => Promise<void>;
|
|
353
302
|
/**
|
|
354
303
|
* What a delivery can be about. A closed union, not a comment: a consumer that
|
|
355
304
|
* dispatches on `kind` (the MCP read plan) is only safe if the compiler can tell
|
|
@@ -372,7 +321,7 @@ export interface InboxSourceRef {
|
|
|
372
321
|
export type { InboxDeliveryRef };
|
|
373
322
|
/** Message/artifact deliveries folded by chat, so you can open chats directly. */
|
|
374
323
|
export interface InboxChatNews {
|
|
375
|
-
|
|
324
|
+
addressId: string;
|
|
376
325
|
count: number;
|
|
377
326
|
latestAt: string;
|
|
378
327
|
}
|
|
@@ -453,7 +402,17 @@ export interface InboxTaskRef {
|
|
|
453
402
|
* exact-match triage with zero LLM tokens before any wake.
|
|
454
403
|
*/
|
|
455
404
|
export type { InboxOpenRequestRef as InboxRequestRef } from '@ziggs-ai/contracts';
|
|
456
|
-
|
|
405
|
+
/**
|
|
406
|
+
* A task whose plan waits on this reader's acknowledgement: work the reader's
|
|
407
|
+
* side pays for. A plan on work the reader was hired to do is the hirer's and
|
|
408
|
+
* is not listed.
|
|
409
|
+
*/
|
|
410
|
+
export type { InboxPlanAckRef } from '@ziggs-ai/contracts';
|
|
411
|
+
/**
|
|
412
|
+
* `planAcksAwaitingMe` / `truncatedPlanAcks` are absent on older servers;
|
|
413
|
+
* read them as empty.
|
|
414
|
+
*/
|
|
415
|
+
export interface InboxEnvelope extends InboxRequestChannel, Partial<InboxPlanAckChannel> {
|
|
457
416
|
asOf: string;
|
|
458
417
|
/**
|
|
459
418
|
* The mailboxes this reader's view merges — its owner's, plus whatever
|
|
@@ -498,6 +457,7 @@ export interface InboxEnvelope extends InboxRequestChannel {
|
|
|
498
457
|
*/
|
|
499
458
|
ackTo: string | null;
|
|
500
459
|
/** Open tasks assigned to this agent — the work channel. */
|
|
460
|
+
answersAwaitingMe?: InboxDeliveryRef[];
|
|
501
461
|
tasksAwaitingMe: InboxTaskRef[];
|
|
502
462
|
truncatedTasks: number;
|
|
503
463
|
proposalsAwaitingMe: InboxProposalRef[];
|
|
@@ -545,7 +505,7 @@ export interface InboxChangesResult {
|
|
|
545
505
|
cursor: string;
|
|
546
506
|
expiresAt: string;
|
|
547
507
|
hasMore: boolean;
|
|
548
|
-
deliveries: Array<Pick<InboxDeliveryRef, 'eventId' | 'kind' | 'resourceId' | '
|
|
508
|
+
deliveries: Array<Pick<InboxDeliveryRef, 'eventId' | 'kind' | 'resourceId' | 'addressId' | 'taskId' | 'agreementId' | 'assigneeId' | 'needsHuman' | 'ts'> & {
|
|
549
509
|
orgId?: string | null;
|
|
550
510
|
}>;
|
|
551
511
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ziggs-ai/api-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.39.1",
|
|
4
4
|
"description": "HTTP and WebSocket client for the Ziggs backend API",
|
|
5
5
|
"homepage": "https://ziggsai.com/docs",
|
|
6
6
|
"bugs": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"test:watch": "node --import tsx/esm --test --watch test/*.test.ts"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@ziggs-ai/contracts": "
|
|
34
|
+
"@ziggs-ai/contracts": "0.42.0",
|
|
35
35
|
"socket.io-client": "^4.7.0"
|
|
36
36
|
},
|
|
37
37
|
"keywords": [
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { type SendChatMessageResult } from '../http/ChatClient.js';
|
|
2
|
-
import { type CapabilityDefinition, type CapabilityEnv } from './types.js';
|
|
3
|
-
import { type WorkContext } from './nextCall.js';
|
|
4
|
-
export interface SendPresentation {
|
|
5
|
-
ok: true;
|
|
6
|
-
chatId: string;
|
|
7
|
-
messageId: string;
|
|
8
|
-
/** Keep the server's delivery guidance on every client surface. */
|
|
9
|
-
message?: string;
|
|
10
|
-
/** What the server did with this send, stated so it cannot be over-read. */
|
|
11
|
-
delivered: string;
|
|
12
|
-
/** Who it was addressed to, exactly as the server resolved it. */
|
|
13
|
-
to?: {
|
|
14
|
-
id: string;
|
|
15
|
-
type: string;
|
|
16
|
-
};
|
|
17
|
-
workContext?: WorkContext;
|
|
18
|
-
delivery?: SendChatMessageResult['delivery'];
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Present a send as what it is: a message that now exists, addressed to
|
|
22
|
-
* somebody, which may or may not wake anyone.
|
|
23
|
-
*
|
|
24
|
-
* An agent that sent an answer and read `success: true` had every reason to
|
|
25
|
-
* report the answer delivered. Three different things hide behind that word.
|
|
26
|
-
* The message exists — that much is certain. Who it reached is the server's
|
|
27
|
-
* decision, not the caller's, because an omitted recipient may be inferred.
|
|
28
|
-
* Mailbox routing is a separate asynchronous decision, including coverage by
|
|
29
|
-
* an assistant when the addressee is a person.
|
|
30
|
-
*
|
|
31
|
-
* A server that does not report the destination gets one honest line about the
|
|
32
|
-
* message existing, and nothing invented about where it went.
|
|
33
|
-
*/
|
|
34
|
-
export declare function presentSendResult(result: SendChatMessageResult, env: CapabilityEnv): SendPresentation;
|
|
35
|
-
/**
|
|
36
|
-
* the decided chat surface for agents: chat_open only.
|
|
37
|
-
* There is deliberately NO chat-listing tool on the SDK: taking part in a room
|
|
38
|
-
* IS a grant on it, so "what chats can I see" is already answered by grant_list
|
|
39
|
-
* scopeKind=chat. MCP keeps its rich session-UX lister
|
|
40
|
-
* (ziggs_chat_list) for humans in Cursor/Claude.
|
|
41
|
-
*/
|
|
42
|
-
export declare const openConversationCapability: CapabilityDefinition;
|
|
43
|
-
export declare const CHAT_CAPABILITIES: CapabilityDefinition[];
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
import { openConversation } from '../http/ChatClient.js';
|
|
2
|
-
import { chatAppUrl } from '../utils/appUrls.js';
|
|
3
|
-
import { fullCreds } from './types.js';
|
|
4
|
-
import { webAppOrigin } from './links.js';
|
|
5
|
-
import { workContextFromEnv } from './nextCall.js';
|
|
6
|
-
/**
|
|
7
|
-
* Present a send as what it is: a message that now exists, addressed to
|
|
8
|
-
* somebody, which may or may not wake anyone.
|
|
9
|
-
*
|
|
10
|
-
* An agent that sent an answer and read `success: true` had every reason to
|
|
11
|
-
* report the answer delivered. Three different things hide behind that word.
|
|
12
|
-
* The message exists — that much is certain. Who it reached is the server's
|
|
13
|
-
* decision, not the caller's, because an omitted recipient may be inferred.
|
|
14
|
-
* Mailbox routing is a separate asynchronous decision, including coverage by
|
|
15
|
-
* an assistant when the addressee is a person.
|
|
16
|
-
*
|
|
17
|
-
* A server that does not report the destination gets one honest line about the
|
|
18
|
-
* message existing, and nothing invented about where it went.
|
|
19
|
-
*/
|
|
20
|
-
export function presentSendResult(result, env) {
|
|
21
|
-
const workContext = workContextFromEnv(env);
|
|
22
|
-
const delivery = result.delivery;
|
|
23
|
-
const base = {
|
|
24
|
-
ok: true,
|
|
25
|
-
chatId: result.chatId,
|
|
26
|
-
messageId: result.messageId,
|
|
27
|
-
...(result.message ? { message: result.message } : {}),
|
|
28
|
-
...(workContext ? { workContext } : {}),
|
|
29
|
-
};
|
|
30
|
-
if (!delivery) {
|
|
31
|
-
return {
|
|
32
|
-
...base,
|
|
33
|
-
delivered: `Message ${result.messageId} was accepted into chat ${result.chatId}. Accepted is not read: nothing here says anyone has seen it.`,
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
const destination = delivery.broadcast
|
|
37
|
-
? 'the humans in the room, not one addressee'
|
|
38
|
-
: `${delivery.to.id} (${delivery.to.type})`;
|
|
39
|
-
// What counted it, in the server's words: a stranger's free messages with a
|
|
40
|
-
// listed agent run out, and the person writing needs to know before they do.
|
|
41
|
-
const counted = result.coverage?.message ? ` ${result.coverage.message}` : '';
|
|
42
|
-
const routing = delivery.broadcast
|
|
43
|
-
? "This human-only broadcast does not wake assistants or stand-ins. If you need a reply, send a new message in this same chat to the person's returned participant id (receiverId), with a fresh message id or idempotency key. Existing conversation permissions still apply."
|
|
44
|
-
: delivery.reachable
|
|
45
|
-
? `Assigned to ${delivery.assignee ?? 'nobody'}; reachable: ${delivery.reachable}${delivery.reason ? ` (${delivery.reason})` : ''}.${delivery.lastRead ? ` Last inbox read: ${delivery.lastRead}.` : ''}`
|
|
46
|
-
: 'Mailbox routing is unconfirmed; a person may be covered by an assistant.';
|
|
47
|
-
return {
|
|
48
|
-
...base,
|
|
49
|
-
delivered: `Message ${result.messageId} was accepted into chat ${result.chatId}, addressed to ${destination}. ${routing} Accepted is not read and does not confirm a wake or reply.${counted}`,
|
|
50
|
-
to: delivery.to,
|
|
51
|
-
delivery,
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* the decided chat surface for agents: chat_open only.
|
|
56
|
-
* There is deliberately NO chat-listing tool on the SDK: taking part in a room
|
|
57
|
-
* IS a grant on it, so "what chats can I see" is already answered by grant_list
|
|
58
|
-
* scopeKind=chat. MCP keeps its rich session-UX lister
|
|
59
|
-
* (ziggs_chat_list) for humans in Cursor/Claude.
|
|
60
|
-
*/
|
|
61
|
-
export const openConversationCapability = {
|
|
62
|
-
key: 'chat_open',
|
|
63
|
-
names: { sdk: 'chat_open', mcp: 'ziggs_chat_open' },
|
|
64
|
-
title: 'Open, invite to, or resume a conversation',
|
|
65
|
-
descriptions: {
|
|
66
|
-
sdk: 'Open a conversation or explicitly invite people to a room. To resume admission of an existing hire, pass only chatId and agreementId; this uses the same recovery as the room UI and never hires or charges again. participantId opens/reuses your person’s conversation with one person or agent, the same room each of their agents finds; newChat opens a separate subject, which can take a name. participantIds creates a separate group with the acting caller and those people; include a stable idempotencyKey for retries. chatId plus participantIds invites people into that exact room, requiring room access and admission authority. Every person needs a valid contact basis: shared organization membership, a link, or an applicable agreement. Each participant keeps their own agent and work relationships; opening a group selects no service agreement. Group creation never expands an existing private DM. Invited teammates read from admission onward. participantIds may name agents, when creating a group or inviting into one: each must be reachable (your own, one of your company, published, or already engaged). An agent you add joins at once if your person gave you approval authority; otherwise it is a proposal in the room, and the first person in the room to say yes admits it. The result lists each id as added, already-here or pending. To bring in an agent you would hire, claim its listing with the room\'s chatId instead. Your own missing seat is asked for with access_request. Reach another person through their user id, not an unpublished agent of theirs. If you cannot reach someone your person knows, ask your person to introduce you in a room. Opening does not send a message; chat_send must name its intended receiverId to guarantee a target. To list accessible rooms, use grant_list with scopeKind ["chat"].',
|
|
67
|
-
},
|
|
68
|
-
annotation: 'write',
|
|
69
|
-
params: {
|
|
70
|
-
participantId: {
|
|
71
|
-
type: 'string',
|
|
72
|
-
description: 'Known user or agent id from search, a directory, a chat, or an agreement. For a teammate or a linked person, their user id, not an agent of theirs. No existing chat is required; do not guess ids.',
|
|
73
|
-
},
|
|
74
|
-
participantIds: { type: 'array', items: { type: 'string' }, description: '1–20 known ids. With or without chatId, people and agents; an agent without your approval authority waits for one person in the room to say yes. Use instead of participantId. Each invitation is authorized separately.' },
|
|
75
|
-
chatId: { type: 'string', description: 'Existing room. With participantIds: invite into it. With agreementId only: resume the approved hire admission without another hire or charge.' },
|
|
76
|
-
idempotencyKey: { type: 'string', description: 'Required for group creation: a unique key for this conversation, reused unchanged on retries. A different participant set needs a new key.' },
|
|
77
|
-
name: { type: 'string', description: 'Name for a new group or a newChat room, 1–80 characters. Pair rooms and team channels take no name. A retry of the same idempotencyKey keeps the first name. Rename later is PATCH /chats/:chatId by someone who can admit people.' },
|
|
78
|
-
createIfMissing: { type: 'boolean', description: 'Set false to reuse only an existing room with this participant. A missing room is refused without creating a replacement.' },
|
|
79
|
-
newChat: {
|
|
80
|
-
type: 'boolean',
|
|
81
|
-
description: 'Open a separate chat even though one is already open with the named participants. ' +
|
|
82
|
-
'For when the conversation is genuinely its own subject and would confuse an ' +
|
|
83
|
-
'existing thread. The separate chat does not become the main one, so a later ' +
|
|
84
|
-
'call without this still returns the original. Leave unset to continue where ' +
|
|
85
|
-
'you left off.',
|
|
86
|
-
},
|
|
87
|
-
agreementId: {
|
|
88
|
-
type: 'string',
|
|
89
|
-
description: 'With chatId: resume that existing hire’s room admission. Otherwise, the hire this open is the working room for. On a store-claim kickoff, pass the ' +
|
|
90
|
-
'claimed agreement id so the payer is stamped from-start in that room.',
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
needsAgentId: true,
|
|
94
|
-
handler: async (args, env) => {
|
|
95
|
-
if (args.chatId && args.agreementId) {
|
|
96
|
-
const result = await openConversation(args, fullCreds(env));
|
|
97
|
-
return {
|
|
98
|
-
...result,
|
|
99
|
-
appUrl: chatAppUrl(webAppOrigin(env), result.chatId),
|
|
100
|
-
message: result.status === 'ready'
|
|
101
|
-
? 'The hired agent is admitted under this agreement. No new hire or charge was made.'
|
|
102
|
-
: `Admission is still incomplete${result.reason ? `: ${result.reason}` : ''}. Retry this same call; do not claim again.`,
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
if (!args.participantId && !Array.isArray(args.participantIds)) {
|
|
106
|
-
throw new Error('participantId is required, or use participantIds to invite people');
|
|
107
|
-
}
|
|
108
|
-
if (args.participantIds !== undefined) {
|
|
109
|
-
if (args.participantId !== undefined || !Array.isArray(args.participantIds) ||
|
|
110
|
-
args.participantIds.length < 1 || args.participantIds.length > 20 ||
|
|
111
|
-
args.participantIds.some(id => typeof id !== 'string' || !id.trim())) {
|
|
112
|
-
throw new Error('Use participantIds containing 1–20 ids, without participantId');
|
|
113
|
-
}
|
|
114
|
-
if (!args.chatId && (typeof args.idempotencyKey !== 'string' || !args.idempotencyKey.trim())) {
|
|
115
|
-
throw new Error('Group creation requires an idempotencyKey; reuse it when retrying');
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
else if (args.chatId) {
|
|
119
|
-
throw new Error('chatId requires participantIds');
|
|
120
|
-
}
|
|
121
|
-
if (typeof args.name === 'string' && args.name.trim() && !Array.isArray(args.participantIds) && args.newChat !== true) {
|
|
122
|
-
throw new Error('A name is for a new group or a newChat room. Pair rooms take no name; the person is the name.');
|
|
123
|
-
}
|
|
124
|
-
const { chatId, reused, invited, name } = await openConversation({
|
|
125
|
-
...(typeof args.participantId === 'string' ? { participantId: args.participantId } : {}),
|
|
126
|
-
...(Array.isArray(args.participantIds) ? { participantIds: args.participantIds } : {}),
|
|
127
|
-
...(typeof args.chatId === 'string' ? { chatId: args.chatId } : {}),
|
|
128
|
-
...(typeof args.idempotencyKey === 'string' ? { idempotencyKey: args.idempotencyKey } : {}),
|
|
129
|
-
...(args.newChat === true ? { newChat: true } : {}),
|
|
130
|
-
...(typeof args.createIfMissing === 'boolean' ? { createIfMissing: args.createIfMissing } : {}),
|
|
131
|
-
...(typeof args.agreementId === 'string' && args.agreementId ? { agreementId: args.agreementId } : {}),
|
|
132
|
-
...(typeof args.name === 'string' && args.name.trim() ? { name: args.name.trim() } : {}),
|
|
133
|
-
}, fullCreds(env));
|
|
134
|
-
const agentId = fullCreds(env).agentId;
|
|
135
|
-
const { people, pending } = roomRoster(args, invited, agentId);
|
|
136
|
-
const lister = env.surface === 'mcp' ? 'ziggs_grant_list' : 'grant_list';
|
|
137
|
-
const grantNote = `Use ${lister} with scopeKind ["chat"] to inspect your room grants. Opening a conversation does not send a message or confirm that anyone has read it.`;
|
|
138
|
-
// word the note from the outcome instead of covering both cases.
|
|
139
|
-
// "Open (or reused)" told the agent the distinction existed and then
|
|
140
|
-
// withheld it — worse than silence, because the agent cannot even tell
|
|
141
|
-
// there is something to look up. A backend too old to report it keeps the
|
|
142
|
-
// old both-cases wording, and `reused` is simply absent from the result.
|
|
143
|
-
// A new group that named agents reports each of them too.
|
|
144
|
-
const created = reused === false ? 'Created a new conversation with the named participants, so there is no history to catch up on.' : null;
|
|
145
|
-
const outcomeNote = args.chatId
|
|
146
|
-
? inviteNote(invited)
|
|
147
|
-
: created && invited?.length
|
|
148
|
-
? `${created} ${inviteNote(invited)}`
|
|
149
|
-
: reused === true
|
|
150
|
-
? 'Reused the conversation you already had with the named participants, so it may already hold history — read it before you speak.'
|
|
151
|
-
: reused === false
|
|
152
|
-
? 'Created a new conversation with the named participants, so there is no history to catch up on.'
|
|
153
|
-
: 'Conversation is open (or reused).';
|
|
154
|
-
return {
|
|
155
|
-
chatId,
|
|
156
|
-
appUrl: chatAppUrl(webAppOrigin(env), chatId),
|
|
157
|
-
...(agentId ? { actingAgentId: agentId } : {}),
|
|
158
|
-
people,
|
|
159
|
-
pending,
|
|
160
|
-
...(typeof reused === 'boolean' ? { reused } : {}),
|
|
161
|
-
...(name ? { name } : {}),
|
|
162
|
-
...(invited ? { invited } : {}),
|
|
163
|
-
note: `${outcomeNote} ${grantNote}`,
|
|
164
|
-
};
|
|
165
|
-
},
|
|
166
|
-
};
|
|
167
|
-
/** Ids this open knows are in the room, and ids still waiting for approval. */
|
|
168
|
-
function roomRoster(args, invited, agentId) {
|
|
169
|
-
const named = Array.isArray(args.participantIds)
|
|
170
|
-
? args.participantIds.filter((id) => typeof id === 'string' && id.trim().length > 0).map((id) => id.trim())
|
|
171
|
-
: typeof args.participantId === 'string' && args.participantId.trim()
|
|
172
|
-
? [args.participantId.trim()]
|
|
173
|
-
: [];
|
|
174
|
-
const pending = (invited ?? []).filter((row) => row.status === 'pending').map((row) => row.id);
|
|
175
|
-
const waiting = new Set(pending);
|
|
176
|
-
const here = (invited ?? []).filter((row) => row.status !== 'pending').map((row) => row.id);
|
|
177
|
-
const people = [...new Set([...named.filter((id) => !waiting.has(id)), ...here, ...(agentId ? [agentId] : [])])];
|
|
178
|
-
return { people, pending };
|
|
179
|
-
}
|
|
180
|
-
/** Say what happened to each invited id, so the agent reports it truthfully. */
|
|
181
|
-
function inviteNote(invited) {
|
|
182
|
-
if (!invited?.length) {
|
|
183
|
-
return 'The named people can participate in this room. Their history access remains bounded by their grants.';
|
|
184
|
-
}
|
|
185
|
-
const ids = (status) => invited.filter((row) => row.status === status).map((row) => row.id);
|
|
186
|
-
const parts = [];
|
|
187
|
-
if (ids('added').length)
|
|
188
|
-
parts.push(`Added: ${ids('added').join(', ')}.`);
|
|
189
|
-
if (ids('already-here').length)
|
|
190
|
-
parts.push(`Already in the room: ${ids('already-here').join(', ')}.`);
|
|
191
|
-
if (ids('pending').length) {
|
|
192
|
-
parts.push(`Proposed in the room, waiting for one person there to say yes: ${ids('pending').join(', ')}. The first answer decides; the agent cannot read or write here until then, and asking again does not make a second request.`);
|
|
193
|
-
}
|
|
194
|
-
return `${parts.join(' ')} Invited people read from now on.`;
|
|
195
|
-
}
|
|
196
|
-
export const CHAT_CAPABILITIES = [openConversationCapability];
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Default `ziggs_chat_list` projection.
|
|
3
|
-
*
|
|
4
|
-
* The wire row carries three web-app rosters (`members`, `rosterSummary`,
|
|
5
|
-
* `participantSummary`) and repeats the persona on each. The MCP default
|
|
6
|
-
* keeps the people who actually receive (`participantSummary`) and drops the
|
|
7
|
-
* other two unless `fields` asks for them.
|
|
8
|
-
*/
|
|
9
|
-
export declare const CHAT_LIST_DEFAULT_FIELDS: readonly ["chatId", "name", "updatedAt", "lastMessage", "unreadCount", "participantSummary", "readable", "requestAccess"];
|
|
10
|
-
/** Apply `fields`, or the MCP default when the caller omitted it. */
|
|
11
|
-
export declare function projectChatListRows(chats: unknown[], fieldsRaw?: unknown): unknown[];
|
|
12
|
-
export declare function utf8Bytes(value: unknown): number;
|
|
13
|
-
/** Rough token count: 4 UTF-8 bytes per token, rounded up. */
|
|
14
|
-
export declare function approxTokens(value: unknown): number;
|