@indexnetwork/protocol 16.1.1-rc.478.1 → 17.0.1-rc.480.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 +47 -0
- package/dist/chat/chat.agent.js +0 -1
- package/dist/chat/negotiator.persona.d.ts +1 -1
- package/dist/chat/negotiator.persona.js +1 -4
- package/dist/chat/negotiator.prompt.js +1 -2
- package/dist/chat/onboarding.persona.js +0 -1
- package/dist/chat/reporter.persona.js +0 -1
- package/dist/chat/signal.persona.js +0 -1
- package/dist/contacts/application/contact.tools.d.ts +6 -9
- package/dist/contacts/application/contact.tools.js +11 -92
- package/dist/contacts/application/index.d.ts +2 -14
- package/dist/contacts/application/index.js +2 -13
- package/dist/contacts/domain/contact.types.d.ts +0 -23
- package/dist/contacts/domain/index.d.ts +2 -6
- package/dist/contacts/index.d.ts +1 -1
- package/dist/contacts/index.js +1 -1
- package/dist/contacts/ports/contact.repository.port.d.ts +5 -12
- package/dist/contacts/ports/contact.repository.port.js +4 -6
- package/dist/contacts/ports/contact.tools.port.d.ts +1 -3
- package/dist/contacts/ports/contact.tools.port.js +1 -2
- package/dist/contacts/ports/index.d.ts +1 -1
- package/dist/contacts/ports/index.js +1 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -1
- package/dist/mcp/mcp.server.js +2 -4
- package/dist/shared/agent/tool.factory.js +0 -8
- package/dist/shared/agent/tool.helpers.d.ts +0 -45
- package/dist/shared/agent/tool.helpers.js +1 -2
- package/dist/shared/agent/tool.registry.js +1 -3
- package/dist/shared/agent/tool.runtime.js +0 -2
- package/dist/shared/agent/utility.tools.js +9 -13
- package/dist/shared/interfaces/database.member-queries.d.ts +1 -8
- package/package.json +2 -2
- package/dist/contacts/application/contact.inviter.d.ts +0 -49
- package/dist/contacts/application/contact.inviter.js +0 -64
- package/dist/integrations/application/index.d.ts +0 -14
- package/dist/integrations/application/index.js +0 -14
- package/dist/integrations/application/integration.tools.d.ts +0 -27
- package/dist/integrations/application/integration.tools.js +0 -98
- package/dist/integrations/domain/index.d.ts +0 -16
- package/dist/integrations/domain/index.js +0 -1
- package/dist/integrations/domain/integration.types.d.ts +0 -51
- package/dist/integrations/domain/integration.types.js +0 -9
- package/dist/integrations/index.d.ts +0 -10
- package/dist/integrations/index.js +0 -8
- package/dist/integrations/ports/index.d.ts +0 -25
- package/dist/integrations/ports/index.js +0 -23
- package/dist/integrations/ports/integration.adapter.port.d.ts +0 -62
- package/dist/integrations/ports/integration.adapter.port.js +0 -15
- package/dist/integrations/ports/integration.importer.port.d.ts +0 -31
- package/dist/integrations/ports/integration.importer.port.js +0 -15
- package/dist/integrations/ports/integration.tools.port.d.ts +0 -25
- package/dist/integrations/ports/integration.tools.port.js +0 -18
|
@@ -8,7 +8,6 @@ import type { UserIdentity } from "../schemas/identity.schema.js";
|
|
|
8
8
|
import type { ChatGraphCompositeDatabase, CreateOpportunityData, NetworkMembership, UserRecord, UserDatabase, SystemDatabase, NegotiationGraphDatabase } from "../interfaces/database.interface.js";
|
|
9
9
|
import type { Scraper } from "../interfaces/scraper.interface.js";
|
|
10
10
|
import type { Cache, HydeCache } from "../interfaces/cache.interface.js";
|
|
11
|
-
import type { IntegrationAdapter } from "../../integrations/ports/index.js";
|
|
12
11
|
import type { ContactServiceAdapter } from "../../contacts/ports/index.js";
|
|
13
12
|
import type { ProfileEnricher } from "../interfaces/enrichment.interface.js";
|
|
14
13
|
import type { IntentGraphQueue } from "../interfaces/queue.interface.js";
|
|
@@ -99,14 +98,6 @@ export interface ResolvedToolContext {
|
|
|
99
98
|
* which are owner-trusted and receive the full owner view.
|
|
100
99
|
*/
|
|
101
100
|
mcpCaller?: McpActivityCaller;
|
|
102
|
-
/**
|
|
103
|
-
* True when the CONTACTS_ENABLED feature flag is on. Carried from the
|
|
104
|
-
* composition root so prompt modules can gate contact-import guidance —
|
|
105
|
-
* when false/unset, the contacts prompt module is not injected, so the
|
|
106
|
-
* orchestrator never advertises Gmail import / add_contact (whose tools
|
|
107
|
-
* are also de-registered). Fail-closed: treat only `true` as enabled.
|
|
108
|
-
*/
|
|
109
|
-
contactsEnabled?: boolean;
|
|
110
101
|
/** True only when the gated reporter cleanup-action proposal tool is registered. */
|
|
111
102
|
actionToolsEnabled?: boolean;
|
|
112
103
|
}
|
|
@@ -142,19 +133,10 @@ interface ToolContextBindings {
|
|
|
142
133
|
cache: Cache;
|
|
143
134
|
/** Dedicated cache for HyDE graph (may be same instance as cache). */
|
|
144
135
|
hydeCache: HydeCache;
|
|
145
|
-
/** External integration platform adapter (OAuth, tool actions). */
|
|
146
|
-
integration: IntegrationAdapter;
|
|
147
136
|
/** Queue for enqueuing follow-up intent processing (HyDE generation/deletion). */
|
|
148
137
|
intentQueue: IntentGraphQueue;
|
|
149
138
|
/** Contact management operations. */
|
|
150
139
|
contactService: ContactServiceAdapter;
|
|
151
|
-
/**
|
|
152
|
-
* When false (or unset), the contact import / manual-add tools
|
|
153
|
-
* (import_contacts, add_contact, import_gmail_contacts) are not registered.
|
|
154
|
-
* Injected by the composition root from CONTACTS_ENABLED. Read/remove/search
|
|
155
|
-
* contact tools are always registered.
|
|
156
|
-
*/
|
|
157
|
-
contactsEnabled?: boolean;
|
|
158
140
|
/** True only when the gated reporter cleanup-action proposal tool is registered. */
|
|
159
141
|
actionToolsEnabled?: boolean;
|
|
160
142
|
/** Chat session reader for loading conversation history. */
|
|
@@ -224,15 +206,6 @@ interface ToolContextBindings {
|
|
|
224
206
|
enricher: ProfileEnricher;
|
|
225
207
|
/** Database adapter for negotiations/conversation operations. */
|
|
226
208
|
negotiationDatabase: NegotiationGraphDatabase;
|
|
227
|
-
/** Integration importer for bulk contact import from toolkits. */
|
|
228
|
-
integrationImporter: {
|
|
229
|
-
importContacts(userId: string, toolkit: string): Promise<{
|
|
230
|
-
imported: number;
|
|
231
|
-
skipped: number;
|
|
232
|
-
newContacts: number;
|
|
233
|
-
existingContacts: number;
|
|
234
|
-
}>;
|
|
235
|
-
};
|
|
236
209
|
/** Factory for user-scoped database access. */
|
|
237
210
|
createUserDatabase: (db: ChatGraphCompositeDatabase, userId: string) => UserDatabase;
|
|
238
211
|
/** Factory for system-scoped database access. */
|
|
@@ -319,8 +292,6 @@ export declare function resolveChatContext(params: {
|
|
|
319
292
|
networkId?: string;
|
|
320
293
|
/** Chat session ID for draft opportunities (stored as context.conversationId). */
|
|
321
294
|
sessionId?: string;
|
|
322
|
-
/** CONTACTS_ENABLED flag, forwarded onto the resolved context for prompt gating. */
|
|
323
|
-
contactsEnabled?: boolean;
|
|
324
295
|
/** Reporter action gate forwarded into the persona prompt/context. */
|
|
325
296
|
actionToolsEnabled?: boolean;
|
|
326
297
|
}): Promise<ResolvedToolContext>;
|
|
@@ -377,23 +348,7 @@ interface ToolDepsBindings {
|
|
|
377
348
|
scraper: Scraper;
|
|
378
349
|
embedder: import('../interfaces/embedder.interface.js').Embedder;
|
|
379
350
|
cache: Cache;
|
|
380
|
-
integration: IntegrationAdapter;
|
|
381
351
|
contactService: ContactServiceAdapter;
|
|
382
|
-
/**
|
|
383
|
-
* When false (or unset), the contact import / manual-add tools
|
|
384
|
-
* (import_contacts, add_contact, import_gmail_contacts) are not registered.
|
|
385
|
-
* Injected by the composition root from CONTACTS_ENABLED. Read/remove/search
|
|
386
|
-
* contact tools are always registered.
|
|
387
|
-
*/
|
|
388
|
-
contactsEnabled?: boolean;
|
|
389
|
-
integrationImporter: {
|
|
390
|
-
importContacts(userId: string, toolkit: string): Promise<{
|
|
391
|
-
imported: number;
|
|
392
|
-
skipped: number;
|
|
393
|
-
newContacts: number;
|
|
394
|
-
existingContacts: number;
|
|
395
|
-
}>;
|
|
396
|
-
};
|
|
397
352
|
enricher: ProfileEnricher;
|
|
398
353
|
/** Database adapter for negotiations/conversation operations. */
|
|
399
354
|
negotiationDatabase: NegotiationGraphDatabase;
|
|
@@ -16,7 +16,7 @@ export class ChatContextAccessError extends Error {
|
|
|
16
16
|
* This preloads user identity, profile, network memberships, and scoped index role.
|
|
17
17
|
*/
|
|
18
18
|
export async function resolveChatContext(params) {
|
|
19
|
-
const { database, userId, networkId, sessionId,
|
|
19
|
+
const { database, userId, networkId, sessionId, actionToolsEnabled } = params;
|
|
20
20
|
const [user, rawProfile, userNetworks, globalContext] = await Promise.all([
|
|
21
21
|
database.getUser(userId),
|
|
22
22
|
database.getProfile(userId),
|
|
@@ -93,7 +93,6 @@ export async function resolveChatContext(params) {
|
|
|
93
93
|
scopedMembershipRole,
|
|
94
94
|
isOnboarding: !(user.onboarding?.completedAt),
|
|
95
95
|
hasName,
|
|
96
|
-
contactsEnabled,
|
|
97
96
|
actionToolsEnabled,
|
|
98
97
|
...(sessionId !== undefined ? { sessionId } : {}),
|
|
99
98
|
};
|
|
@@ -4,7 +4,6 @@ import { createIntentTools } from '../../intents/application/intent.tools.js';
|
|
|
4
4
|
import { createNetworkTools } from '../../networks/index.js';
|
|
5
5
|
import { createOpportunityTools } from '../../opportunities/index.js';
|
|
6
6
|
import { createUtilityTools } from './utility.tools.js';
|
|
7
|
-
import { createIntegrationTools } from '../../integrations/index.js';
|
|
8
7
|
import { createContactTools } from '../../contacts/index.js';
|
|
9
8
|
import { createAgentTools } from '../../agents/index.js';
|
|
10
9
|
import { createNegotiationTools } from '../../negotiations/index.js';
|
|
@@ -62,10 +61,9 @@ export function createToolRegistry(deps, options = {}) {
|
|
|
62
61
|
// (IND-597). The retired report_agent_activity name retains no alias on
|
|
63
62
|
// either surface (IND-605).
|
|
64
63
|
createUtilityTools(dt, deps, { surface: isMcpSurface ? 'mcp' : 'rest' });
|
|
65
|
-
// Contact
|
|
64
|
+
// Contact tools are omitted from the MCP surface (IND-596). Their
|
|
66
65
|
// implementations remain available to the REST Tool API and chat agent.
|
|
67
66
|
if (!isMcpSurface) {
|
|
68
|
-
createIntegrationTools(dt, deps);
|
|
69
67
|
createContactTools(dt, deps);
|
|
70
68
|
}
|
|
71
69
|
createAgentTools(dt, deps);
|
|
@@ -93,23 +93,19 @@ export function createUtilityTools(defineTool, deps, options = {}) {
|
|
|
93
93
|
|
|
94
94
|
Contacts are people in a user's personal network, stored as members of their personal network with 'contact' permission.
|
|
95
95
|
|
|
96
|
-
- **
|
|
97
|
-
- **Ghost users**: When a contact email doesn't match an existing account, a ghost user is created. Ghost users are enriched with public profile data and participate in opportunity matching — they can be discovered even before joining the platform.
|
|
96
|
+
- **How contacts arise**: Accepting an opportunity puts both people in each other's personal network. There is no import or manual-add path.
|
|
98
97
|
- **Personal network scope**: Approved signals from personal-network contacts are matched in the background. Use list_opportunities only to review persisted results.
|
|
99
|
-
- **Contact data**: Each contact has userId, name, email,
|
|
98
|
+
- **Contact data**: Each contact has userId, name, email, and avatar.
|
|
100
99
|
|
|
101
100
|
### Contact Workflow
|
|
102
|
-
1.
|
|
103
|
-
2.
|
|
104
|
-
3.
|
|
105
|
-
4.
|
|
106
|
-
5. add_contact(email) → add individual contact
|
|
107
|
-
6. remove_contact(contactUserId) → remove from network`;
|
|
101
|
+
1. list_contacts → view all contacts with userId
|
|
102
|
+
2. create_intent or update_intent → create or refine an approved signal for background matching
|
|
103
|
+
3. list_opportunities → review persisted results when background processing finds matches
|
|
104
|
+
4. remove_contact(contactUserId) → remove from network`;
|
|
108
105
|
const managingContactsWorkflow = `### Managing Contacts
|
|
109
|
-
1.
|
|
110
|
-
2.
|
|
111
|
-
3.
|
|
112
|
-
4. list_opportunities → review persisted results
|
|
106
|
+
1. list_contacts() → view network
|
|
107
|
+
2. create_intent or update_intent → create or refine an approved signal for background matching
|
|
108
|
+
3. list_opportunities → review persisted results
|
|
113
109
|
|
|
114
110
|
`;
|
|
115
111
|
const sections = {
|
|
@@ -5,14 +5,7 @@ import type { NetworkAssignmentMetadata } from '../schemas/network-assignment.sc
|
|
|
5
5
|
import type { PremiseAnalysis, PremiseAssertion, PremiseProvenance, PremiseRecord, PremiseValidity } from './database.entities.js';
|
|
6
6
|
/** Contact, premise and user-context operations. */
|
|
7
7
|
export interface DatabaseMemberQueries {
|
|
8
|
-
/**
|
|
9
|
-
createGhostUser(data: {
|
|
10
|
-
name: string;
|
|
11
|
-
email: string;
|
|
12
|
-
}): Promise<{
|
|
13
|
-
id: string;
|
|
14
|
-
}>;
|
|
15
|
-
/** Upsert a contact membership in the owner's personal network (index_members with permissions=['contact']). */
|
|
8
|
+
/** Upsert a contact membership in the owner's personal network (network_members with permissions=['contact']). */
|
|
16
9
|
upsertContactMembership(ownerId: string, contactUserId: string, options?: {
|
|
17
10
|
restore?: boolean;
|
|
18
11
|
}): Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@indexnetwork/protocol",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "17.0.1-rc.480.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"test": "bun test scripts/tests/test-runner.spec.ts && bun scripts/test.ts",
|
|
24
24
|
"test:isolated": "bun test scripts/tests/test-runner.spec.ts && bun scripts/test.ts",
|
|
25
25
|
"test:shared": "bun test",
|
|
26
|
-
"test:architecture": "bun test
|
|
26
|
+
"test:architecture": "bun test scripts/architecture/tests",
|
|
27
27
|
"architecture:host-isolation": "bun scripts/architecture/host-isolation.ts",
|
|
28
28
|
"architecture:capabilities": "bun scripts/architecture/capability-boundaries.ts",
|
|
29
29
|
"architecture:check": "bun run architecture:host-isolation && bun run architecture:capabilities && bun run test:architecture",
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* contacts/application — generateInviteMessage canonical implementation.
|
|
3
|
-
*
|
|
4
|
-
* Invite Generator Agent: generates contextual, editable invite messages for
|
|
5
|
-
* ghost users. Produces warm, concise messages (~2-3 sentences) referencing
|
|
6
|
-
* why two users were matched, with optional referrer mention.
|
|
7
|
-
*
|
|
8
|
-
* IND-549: moved from contact/contact.inviter.ts into the canonical
|
|
9
|
-
* contacts/application layer.
|
|
10
|
-
*/
|
|
11
|
-
import { z } from "zod";
|
|
12
|
-
declare const InviteInputSchema: z.ZodObject<{
|
|
13
|
-
recipientName: z.ZodString;
|
|
14
|
-
senderName: z.ZodString;
|
|
15
|
-
opportunityInterpretation: z.ZodString;
|
|
16
|
-
senderIntents: z.ZodArray<z.ZodString, "many">;
|
|
17
|
-
recipientIntents: z.ZodArray<z.ZodString, "many">;
|
|
18
|
-
referrerName: z.ZodOptional<z.ZodString>;
|
|
19
|
-
}, "strip", z.ZodTypeAny, {
|
|
20
|
-
recipientName: string;
|
|
21
|
-
senderName: string;
|
|
22
|
-
opportunityInterpretation: string;
|
|
23
|
-
senderIntents: string[];
|
|
24
|
-
recipientIntents: string[];
|
|
25
|
-
referrerName?: string | undefined;
|
|
26
|
-
}, {
|
|
27
|
-
recipientName: string;
|
|
28
|
-
senderName: string;
|
|
29
|
-
opportunityInterpretation: string;
|
|
30
|
-
senderIntents: string[];
|
|
31
|
-
recipientIntents: string[];
|
|
32
|
-
referrerName?: string | undefined;
|
|
33
|
-
}>;
|
|
34
|
-
declare const InviteOutputSchema: z.ZodObject<{
|
|
35
|
-
message: z.ZodString;
|
|
36
|
-
}, "strip", z.ZodTypeAny, {
|
|
37
|
-
message: string;
|
|
38
|
-
}, {
|
|
39
|
-
message: string;
|
|
40
|
-
}>;
|
|
41
|
-
export type InviteInput = z.infer<typeof InviteInputSchema>;
|
|
42
|
-
export type InviteOutput = z.infer<typeof InviteOutputSchema>;
|
|
43
|
-
/**
|
|
44
|
-
* Generates a contextual invite message for a ghost user.
|
|
45
|
-
* @param input - Context about sender, recipient, and opportunity
|
|
46
|
-
* @returns Generated invite message text
|
|
47
|
-
*/
|
|
48
|
-
export declare function generateInviteMessage(input: InviteInput): Promise<InviteOutput>;
|
|
49
|
-
export {};
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* contacts/application — generateInviteMessage canonical implementation.
|
|
3
|
-
*
|
|
4
|
-
* Invite Generator Agent: generates contextual, editable invite messages for
|
|
5
|
-
* ghost users. Produces warm, concise messages (~2-3 sentences) referencing
|
|
6
|
-
* why two users were matched, with optional referrer mention.
|
|
7
|
-
*
|
|
8
|
-
* IND-549: moved from contact/contact.inviter.ts into the canonical
|
|
9
|
-
* contacts/application layer.
|
|
10
|
-
*/
|
|
11
|
-
import { HumanMessage, SystemMessage } from "@langchain/core/messages";
|
|
12
|
-
import { z } from "zod";
|
|
13
|
-
import { createStructuredModel } from "../../shared/agent/model.config.js";
|
|
14
|
-
import { stripUnsupportedOpportunityClaims } from "../../shared/utils/claim-safety.js";
|
|
15
|
-
const InviteInputSchema = z.object({
|
|
16
|
-
recipientName: z.string(),
|
|
17
|
-
senderName: z.string(),
|
|
18
|
-
opportunityInterpretation: z.string(),
|
|
19
|
-
senderIntents: z.array(z.string()),
|
|
20
|
-
recipientIntents: z.array(z.string()),
|
|
21
|
-
referrerName: z.string().optional(),
|
|
22
|
-
});
|
|
23
|
-
const InviteOutputSchema = z.object({
|
|
24
|
-
message: z.string().describe("The invite message text, ready to edit and send"),
|
|
25
|
-
});
|
|
26
|
-
const SYSTEM_PROMPT = `You generate brief, casual invite messages for a discovery platform called Index.
|
|
27
|
-
|
|
28
|
-
The sender wants to reach out to someone they were matched with. Write a short, human message (2-3 sentences max) that:
|
|
29
|
-
- Sounds like a real person texting, not a LinkedIn outreach or AI email
|
|
30
|
-
- References one concrete, specific detail from the opportunity context — something actual, like a specific project, technology, or goal they share. Not "we have similar interests" or "I noticed we're both in this space" — name the actual thing.
|
|
31
|
-
- If a referrer is provided, casually drops that they were introduced
|
|
32
|
-
- Ends naturally — no formal CTAs, no "Would you be open to..." closings
|
|
33
|
-
|
|
34
|
-
Tone: casual, direct, human. Think how you'd actually message someone you just got introduced to.
|
|
35
|
-
Do NOT use a generic opener like "Hi [Name], I'm [Sender]." Just get to the point.
|
|
36
|
-
Do NOT summarize the person's background. Pick one real, specific overlap from the context and mention it.
|
|
37
|
-
Do NOT include a subject line. This is a chat message.
|
|
38
|
-
Do NOT use placeholder brackets like [Name]. Use the actual names provided.
|
|
39
|
-
Network assignment, network title/type, and event/network metadata are retrieval context only. They are NEVER proof that either person attended or will attend, belongs to a group, resides in a place, knows anyone from the network, or shared a session, time, place, or location. Do not make co-attendance, membership, residence, shared-session, or same-place/same-time claims from network co-membership.`;
|
|
40
|
-
/**
|
|
41
|
-
* Generates a contextual invite message for a ghost user.
|
|
42
|
-
* @param input - Context about sender, recipient, and opportunity
|
|
43
|
-
* @returns Generated invite message text
|
|
44
|
-
*/
|
|
45
|
-
export async function generateInviteMessage(input) {
|
|
46
|
-
const validated = InviteInputSchema.parse(input);
|
|
47
|
-
const structuredModel = createStructuredModel("inviteGenerator", InviteOutputSchema);
|
|
48
|
-
const safeInterpretation = stripUnsupportedOpportunityClaims(validated.opportunityInterpretation) ||
|
|
49
|
-
"Their current goals may be relevant to each other.";
|
|
50
|
-
const userPrompt = `Generate an invite message with this context:
|
|
51
|
-
- Sender: ${validated.senderName}
|
|
52
|
-
- Recipient: ${validated.recipientName}
|
|
53
|
-
- Why they matched: ${safeInterpretation}
|
|
54
|
-
- Sender's interests: ${validated.senderIntents.join(', ') || 'Not specified'}
|
|
55
|
-
- Recipient's interests: ${validated.recipientIntents.join(', ') || 'Not specified'}${validated.referrerName ? `\n- Referred by: ${validated.referrerName}` : ''}`;
|
|
56
|
-
const result = InviteOutputSchema.parse(await structuredModel.invoke([
|
|
57
|
-
new SystemMessage(SYSTEM_PROMPT),
|
|
58
|
-
new HumanMessage(userPrompt),
|
|
59
|
-
]));
|
|
60
|
-
const safeMessage = stripUnsupportedOpportunityClaims(result.message);
|
|
61
|
-
return {
|
|
62
|
-
message: safeMessage || "Thought it could be useful for us to compare notes on what we're working on.",
|
|
63
|
-
};
|
|
64
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* integrations/application — foreground adapters for the integrations capability.
|
|
3
|
-
*
|
|
4
|
-
* ## Exports
|
|
5
|
-
*
|
|
6
|
-
* ### Tool factory
|
|
7
|
-
* - `createIntegrationTools` — creates integration MCP tools (import_gmail_contacts).
|
|
8
|
-
* The tool is gated behind deps.contactsEnabled; when disabled, returns [].
|
|
9
|
-
*
|
|
10
|
-
* IND-549: canonical application layer for the integrations capability.
|
|
11
|
-
* Legacy path:
|
|
12
|
-
* - integration/integration.tools.ts → thin compatibility shim pointing here
|
|
13
|
-
*/
|
|
14
|
-
export { createIntegrationTools } from "./integration.tools.js";
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* integrations/application — foreground adapters for the integrations capability.
|
|
3
|
-
*
|
|
4
|
-
* ## Exports
|
|
5
|
-
*
|
|
6
|
-
* ### Tool factory
|
|
7
|
-
* - `createIntegrationTools` — creates integration MCP tools (import_gmail_contacts).
|
|
8
|
-
* The tool is gated behind deps.contactsEnabled; when disabled, returns [].
|
|
9
|
-
*
|
|
10
|
-
* IND-549: canonical application layer for the integrations capability.
|
|
11
|
-
* Legacy path:
|
|
12
|
-
* - integration/integration.tools.ts → thin compatibility shim pointing here
|
|
13
|
-
*/
|
|
14
|
-
export { createIntegrationTools } from "./integration.tools.js";
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* integrations/application — createIntegrationTools canonical implementation.
|
|
3
|
-
*
|
|
4
|
-
* Creates integration tools for the chat agent. Exposes `import_gmail_contacts`
|
|
5
|
-
* which authenticates via the integration adapter, fetches all Gmail contacts
|
|
6
|
-
* (paginated), and imports them as ghost users into the network.
|
|
7
|
-
*
|
|
8
|
-
* Feature gating: import_gmail_contacts creates ghost users, so it is gated
|
|
9
|
-
* behind the CONTACTS_ENABLED flag (deps.contactsEnabled). When disabled,
|
|
10
|
-
* the tool is not registered at all (defineTool registers as a side effect).
|
|
11
|
-
*
|
|
12
|
-
* IND-549: moved from integration/integration.tools.ts into the canonical
|
|
13
|
-
* integrations/application layer.
|
|
14
|
-
*/
|
|
15
|
-
import type { DefineTool } from '../../shared/agent/tool.helpers.js';
|
|
16
|
-
import type { IntegrationToolDeps } from '../ports/index.js';
|
|
17
|
-
/**
|
|
18
|
-
* Creates integration tools for the chat agent.
|
|
19
|
-
*
|
|
20
|
-
* Exposes `import_gmail_contacts` which authenticates via the integration adapter,
|
|
21
|
-
* fetches all Gmail contacts (paginated), and imports them as ghost users into the network.
|
|
22
|
-
*
|
|
23
|
-
* @param defineTool - Tool definition helper injected by the tool registry.
|
|
24
|
-
* @param deps - Shared tool dependencies including the integration adapter.
|
|
25
|
-
* @returns An array of tool definitions to register with the chat agent.
|
|
26
|
-
*/
|
|
27
|
-
export declare function createIntegrationTools(defineTool: DefineTool, deps: IntegrationToolDeps): any[];
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* integrations/application — createIntegrationTools canonical implementation.
|
|
3
|
-
*
|
|
4
|
-
* Creates integration tools for the chat agent. Exposes `import_gmail_contacts`
|
|
5
|
-
* which authenticates via the integration adapter, fetches all Gmail contacts
|
|
6
|
-
* (paginated), and imports them as ghost users into the network.
|
|
7
|
-
*
|
|
8
|
-
* Feature gating: import_gmail_contacts creates ghost users, so it is gated
|
|
9
|
-
* behind the CONTACTS_ENABLED flag (deps.contactsEnabled). When disabled,
|
|
10
|
-
* the tool is not registered at all (defineTool registers as a side effect).
|
|
11
|
-
*
|
|
12
|
-
* IND-549: moved from integration/integration.tools.ts into the canonical
|
|
13
|
-
* integrations/application layer.
|
|
14
|
-
*/
|
|
15
|
-
import { z } from 'zod';
|
|
16
|
-
import { success, error } from '../../shared/agent/tool.helpers.js';
|
|
17
|
-
import { requestContext } from "../../shared/observability/request-context.js";
|
|
18
|
-
import { protocolLogger } from '../../shared/observability/protocol.logger.js';
|
|
19
|
-
const logger = protocolLogger('ChatTools:Integration');
|
|
20
|
-
/**
|
|
21
|
-
* Creates integration tools for the chat agent.
|
|
22
|
-
*
|
|
23
|
-
* Exposes `import_gmail_contacts` which authenticates via the integration adapter,
|
|
24
|
-
* fetches all Gmail contacts (paginated), and imports them as ghost users into the network.
|
|
25
|
-
*
|
|
26
|
-
* @param defineTool - Tool definition helper injected by the tool registry.
|
|
27
|
-
* @param deps - Shared tool dependencies including the integration adapter.
|
|
28
|
-
* @returns An array of tool definitions to register with the chat agent.
|
|
29
|
-
*/
|
|
30
|
-
export function createIntegrationTools(defineTool, deps) {
|
|
31
|
-
const { integration, integrationImporter } = deps;
|
|
32
|
-
// import_gmail_contacts creates ghost users, so it is gated behind the
|
|
33
|
-
// CONTACTS_ENABLED flag (injected as deps.contactsEnabled). When disabled the
|
|
34
|
-
// tool is not registered at all (defineTool registers as a side effect).
|
|
35
|
-
if (deps.contactsEnabled !== true) {
|
|
36
|
-
return [];
|
|
37
|
-
}
|
|
38
|
-
const import_gmail_contacts = defineTool({
|
|
39
|
-
name: 'import_gmail_contacts',
|
|
40
|
-
description: "Imports contacts from the user's connected Gmail/Google account into their personal network. " +
|
|
41
|
-
"This is the preferred method for importing Google Contacts — handles OAuth authentication, pagination, and deduplication automatically.\n\n" +
|
|
42
|
-
"**Authentication flow:** If Gmail is not yet connected, returns an `authUrl` the user must visit to grant access. " +
|
|
43
|
-
"After they complete OAuth, call this tool again to perform the actual import.\n\n" +
|
|
44
|
-
"**What happens on import:** All Gmail contacts with valid name+email are imported. " +
|
|
45
|
-
"Contacts without existing platform accounts become ghost users (enriched with public profile data from LinkedIn, GitHub, etc.). " +
|
|
46
|
-
"All imported contacts are added to the user's personal network for opportunity discovery.\n\n" +
|
|
47
|
-
"**When to use:** When the user asks to import or sync their Gmail/Google contacts. No parameters needed.\n\n" +
|
|
48
|
-
"**Returns:** Either `{ requiresAuth: true, authUrl }` (user needs to authenticate) or import statistics: " +
|
|
49
|
-
"imported (total), newContacts (ghost users created), existingContacts (already in network), skipped (invalid entries).",
|
|
50
|
-
querySchema: z.object({}),
|
|
51
|
-
handler: async ({ context }) => {
|
|
52
|
-
try {
|
|
53
|
-
const session = await integration.createSession(context.userId);
|
|
54
|
-
const toolkits = await session.toolkits();
|
|
55
|
-
const gmailToolkit = toolkits.items.find(t => t.slug === 'gmail');
|
|
56
|
-
const isConnected = !!gmailToolkit?.connection?.connectedAccount?.id;
|
|
57
|
-
if (!isConnected) {
|
|
58
|
-
logger.info('Gmail not connected, returning auth URL', { userId: context.userId });
|
|
59
|
-
const originUrl = requestContext.getStore()?.originUrl;
|
|
60
|
-
const callbackUrl = originUrl ? `${originUrl}/oauth/callback` : undefined;
|
|
61
|
-
const authRequest = await session.authorize('gmail', callbackUrl ? { callbackUrl } : undefined);
|
|
62
|
-
return success({
|
|
63
|
-
requiresAuth: true,
|
|
64
|
-
message: 'Please connect your Gmail account to import contacts.',
|
|
65
|
-
authUrl: authRequest.redirectUrl,
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
const importResult = await integrationImporter.importContacts(context.userId, 'gmail');
|
|
69
|
-
logger.info('Gmail contacts imported', {
|
|
70
|
-
userId: context.userId,
|
|
71
|
-
imported: importResult.imported,
|
|
72
|
-
skipped: importResult.skipped,
|
|
73
|
-
newContacts: importResult.newContacts,
|
|
74
|
-
existingContacts: importResult.existingContacts,
|
|
75
|
-
});
|
|
76
|
-
return success({
|
|
77
|
-
message: importResult.newContacts > 0
|
|
78
|
-
? `Imported ${importResult.imported} contacts from Gmail. ${importResult.newContacts} new, ${importResult.existingContacts} already in your network.`
|
|
79
|
-
: importResult.imported > 0
|
|
80
|
-
? `All ${importResult.imported} contacts from Gmail were already in your network. No new contacts added.`
|
|
81
|
-
: 'No contacts with valid name and email found in your Gmail account.',
|
|
82
|
-
imported: importResult.imported,
|
|
83
|
-
newContacts: importResult.newContacts,
|
|
84
|
-
existingContacts: importResult.existingContacts,
|
|
85
|
-
skipped: importResult.skipped,
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
catch (err) {
|
|
89
|
-
logger.error('import_gmail_contacts failed', {
|
|
90
|
-
userId: context.userId,
|
|
91
|
-
err,
|
|
92
|
-
});
|
|
93
|
-
return error('Failed to import Gmail contacts. Please try again.');
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
});
|
|
97
|
-
return [import_gmail_contacts];
|
|
98
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* integrations/domain — pure integration entity value types.
|
|
3
|
-
*
|
|
4
|
-
* Contains IntegrationSession, IntegrationSessionOptions, ToolActionResponse,
|
|
5
|
-
* and IntegrationConnection.
|
|
6
|
-
*
|
|
7
|
-
* ## What does NOT live here
|
|
8
|
-
*
|
|
9
|
-
* - IntegrationAdapter: platform adapter port — lives in integrations/ports.
|
|
10
|
-
* - IntegrationImporter: bulk-import port — lives in integrations/ports.
|
|
11
|
-
* - IntegrationToolDeps: tool host port — lives in integrations/ports.
|
|
12
|
-
* - createIntegrationTools: application layer — lives in integrations/application.
|
|
13
|
-
*
|
|
14
|
-
* IND-549: canonical domain layer for the integrations capability.
|
|
15
|
-
*/
|
|
16
|
-
export type { IntegrationSession, IntegrationSessionOptions, ToolActionResponse, IntegrationConnection, } from "./integration.types.js";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* integrations/domain — pure integration entity value types.
|
|
3
|
-
*
|
|
4
|
-
* Contains session shapes, connection records, and tool action responses.
|
|
5
|
-
* No application logic, no LLM calls, no cross-capability imports.
|
|
6
|
-
*
|
|
7
|
-
* IND-549: canonical domain layer for the integrations capability.
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* Session for interacting with an external integration platform.
|
|
11
|
-
* Provides access to tools, OAuth authorization, and toolkit discovery.
|
|
12
|
-
*/
|
|
13
|
-
export interface IntegrationSession {
|
|
14
|
-
tools(): Promise<unknown[]>;
|
|
15
|
-
authorize(toolkit: string): Promise<{
|
|
16
|
-
redirectUrl: string;
|
|
17
|
-
waitForConnection(timeout?: number): Promise<unknown>;
|
|
18
|
-
}>;
|
|
19
|
-
toolkits(): Promise<{
|
|
20
|
-
items: Array<{
|
|
21
|
-
slug: string;
|
|
22
|
-
name: string;
|
|
23
|
-
connection?: {
|
|
24
|
-
connectedAccount?: {
|
|
25
|
-
id: string;
|
|
26
|
-
};
|
|
27
|
-
};
|
|
28
|
-
}>;
|
|
29
|
-
}>;
|
|
30
|
-
}
|
|
31
|
-
/** Options for creating an integration session. */
|
|
32
|
-
export interface IntegrationSessionOptions {
|
|
33
|
-
manageConnections?: boolean | {
|
|
34
|
-
callbackUrl?: string;
|
|
35
|
-
};
|
|
36
|
-
/** Toolkit slug → auth config ID mapping to pin existing auth configs. */
|
|
37
|
-
authConfigs?: Record<string, string>;
|
|
38
|
-
}
|
|
39
|
-
/** Response from executing a tool action on the integration platform. */
|
|
40
|
-
export interface ToolActionResponse {
|
|
41
|
-
successful: boolean;
|
|
42
|
-
error?: string;
|
|
43
|
-
data?: Record<string, unknown>;
|
|
44
|
-
}
|
|
45
|
-
/** A connected integration account for a user. */
|
|
46
|
-
export interface IntegrationConnection {
|
|
47
|
-
id: string;
|
|
48
|
-
toolkit: string;
|
|
49
|
-
status: string;
|
|
50
|
-
createdAt: string;
|
|
51
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* integrations/domain — pure integration entity value types.
|
|
3
|
-
*
|
|
4
|
-
* Contains session shapes, connection records, and tool action responses.
|
|
5
|
-
* No application logic, no LLM calls, no cross-capability imports.
|
|
6
|
-
*
|
|
7
|
-
* IND-549: canonical domain layer for the integrations capability.
|
|
8
|
-
*/
|
|
9
|
-
export {};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* integrations — the capability's sole cross-capability surface.
|
|
3
|
-
*
|
|
4
|
-
* Anything outside this capability imports from here and nowhere else.
|
|
5
|
-
* Supersedes the capabilities/*.facade.ts + integrations/public/ pair; the export
|
|
6
|
-
* list is the union of the facades it replaces, so the contract is unchanged.
|
|
7
|
-
*/
|
|
8
|
-
export { createIntegrationTools, } from "./application/index.js";
|
|
9
|
-
export type { IntegrationConnection, IntegrationSession, IntegrationSessionOptions, ToolActionResponse, } from "./domain/index.js";
|
|
10
|
-
export type { IntegrationAdapter, IntegrationToolDeps, } from "./ports/index.js";
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* integrations — the capability's sole cross-capability surface.
|
|
3
|
-
*
|
|
4
|
-
* Anything outside this capability imports from here and nowhere else.
|
|
5
|
-
* Supersedes the capabilities/*.facade.ts + integrations/public/ pair; the export
|
|
6
|
-
* list is the union of the facades it replaces, so the contract is unchanged.
|
|
7
|
-
*/
|
|
8
|
-
export { createIntegrationTools, } from "./application/index.js";
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* integrations/ports — injected dependency contracts for the integrations capability.
|
|
3
|
-
*
|
|
4
|
-
* Re-exports the narrow port types that the integrations module declares as
|
|
5
|
-
* explicit injected boundaries. Consumers import these to wire host
|
|
6
|
-
* implementations without depending on the application layer.
|
|
7
|
-
*
|
|
8
|
-
* ## Port groups
|
|
9
|
-
*
|
|
10
|
-
* ### Platform adapter port
|
|
11
|
-
* - IntegrationAdapter — session creation, tool execution, connection management,
|
|
12
|
-
* OAuth auth URLs, and disconnection.
|
|
13
|
-
*
|
|
14
|
-
* ### Bulk import port
|
|
15
|
-
* - IntegrationImporter — toolkit-to-contacts bulk import pipeline.
|
|
16
|
-
* - IntegrationImportResult — aggregate import statistics.
|
|
17
|
-
*
|
|
18
|
-
* ### Tool host port
|
|
19
|
-
* - IntegrationToolDeps — host capabilities for integration-backed tools.
|
|
20
|
-
*
|
|
21
|
-
* IND-549: canonical ports surface for the integrations capability.
|
|
22
|
-
*/
|
|
23
|
-
export type { IntegrationAdapter } from "./integration.adapter.port.js";
|
|
24
|
-
export type { IntegrationImporter, IntegrationImportResult } from "./integration.importer.port.js";
|
|
25
|
-
export type { IntegrationToolDeps } from "./integration.tools.port.js";
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* integrations/ports — injected dependency contracts for the integrations capability.
|
|
3
|
-
*
|
|
4
|
-
* Re-exports the narrow port types that the integrations module declares as
|
|
5
|
-
* explicit injected boundaries. Consumers import these to wire host
|
|
6
|
-
* implementations without depending on the application layer.
|
|
7
|
-
*
|
|
8
|
-
* ## Port groups
|
|
9
|
-
*
|
|
10
|
-
* ### Platform adapter port
|
|
11
|
-
* - IntegrationAdapter — session creation, tool execution, connection management,
|
|
12
|
-
* OAuth auth URLs, and disconnection.
|
|
13
|
-
*
|
|
14
|
-
* ### Bulk import port
|
|
15
|
-
* - IntegrationImporter — toolkit-to-contacts bulk import pipeline.
|
|
16
|
-
* - IntegrationImportResult — aggregate import statistics.
|
|
17
|
-
*
|
|
18
|
-
* ### Tool host port
|
|
19
|
-
* - IntegrationToolDeps — host capabilities for integration-backed tools.
|
|
20
|
-
*
|
|
21
|
-
* IND-549: canonical ports surface for the integrations capability.
|
|
22
|
-
*/
|
|
23
|
-
export {};
|