@agent-native/core 0.7.22 → 0.7.24
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 +2 -2
- package/dist/a2a/client.d.ts +10 -4
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +16 -1
- package/dist/a2a/client.js.map +1 -1
- package/dist/a2a/handlers.d.ts.map +1 -1
- package/dist/a2a/handlers.js +20 -17
- package/dist/a2a/handlers.js.map +1 -1
- package/dist/cli/create.d.ts +3 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +33 -32
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +23 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/workspace-dev.d.ts +3 -0
- package/dist/cli/workspace-dev.d.ts.map +1 -0
- package/dist/cli/workspace-dev.js +323 -0
- package/dist/cli/workspace-dev.js.map +1 -0
- package/dist/cli/workspacify.d.ts +3 -3
- package/dist/cli/workspacify.js +4 -4
- package/dist/cli/workspacify.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +10 -9
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +2 -1
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +2 -1
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/components/ui/tooltip.d.ts +8 -0
- package/dist/client/components/ui/tooltip.d.ts.map +1 -0
- package/dist/client/components/ui/tooltip.js +11 -0
- package/dist/client/components/ui/tooltip.js.map +1 -0
- package/dist/client/resources/ResourceTree.d.ts.map +1 -1
- package/dist/client/resources/ResourceTree.js +21 -17
- package/dist/client/resources/ResourceTree.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +13 -11
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/deploy/workspace-core.d.ts +1 -1
- package/dist/deploy/workspace-core.d.ts.map +1 -1
- package/dist/deploy/workspace-core.js +14 -11
- package/dist/deploy/workspace-core.js.map +1 -1
- package/dist/integrations/a2a-continuation-processor.d.ts +10 -0
- package/dist/integrations/a2a-continuation-processor.d.ts.map +1 -0
- package/dist/integrations/a2a-continuation-processor.js +150 -0
- package/dist/integrations/a2a-continuation-processor.js.map +1 -0
- package/dist/integrations/a2a-continuations-store.d.ts +41 -0
- package/dist/integrations/a2a-continuations-store.d.ts.map +1 -0
- package/dist/integrations/a2a-continuations-store.js +214 -0
- package/dist/integrations/a2a-continuations-store.js.map +1 -0
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js +4 -1
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +52 -0
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/integrations/types.d.ts +5 -0
- package/dist/integrations/types.d.ts.map +1 -1
- package/dist/integrations/types.js.map +1 -1
- package/dist/integrations/webhook-handler.d.ts +6 -0
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +69 -15
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/org/handlers.d.ts.map +1 -1
- package/dist/org/handlers.js +22 -16
- package/dist/org/handlers.js.map +1 -1
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +91 -30
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/server/agent-discovery.d.ts.map +1 -1
- package/dist/server/agent-discovery.js +17 -105
- package/dist/server/agent-discovery.js.map +1 -1
- package/dist/server/agents-bundle.js +1 -1
- package/dist/server/agents-bundle.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +29 -120
- package/dist/server/auth.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts +1 -0
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +7 -5
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/framework-request-handler.js +1 -1
- package/dist/server/framework-request-handler.js.map +1 -1
- package/dist/server/onboarding-html.d.ts +1 -8
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +321 -152
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/server/request-context.d.ts +14 -3
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js +3 -0
- package/dist/server/request-context.js.map +1 -1
- package/dist/templates/default/_gitignore +2 -0
- package/dist/templates/workspace-core/AGENTS.md +18 -71
- package/dist/templates/workspace-core/package.json +2 -20
- package/dist/templates/workspace-core/src/client/index.ts +2 -26
- package/dist/templates/workspace-core/src/index.ts +1 -21
- package/dist/templates/workspace-core/src/server/index.ts +3 -22
- package/dist/templates/workspace-root/.prettierignore +19 -0
- package/dist/templates/workspace-root/README.md +17 -20
- package/dist/templates/workspace-root/_gitignore +8 -0
- package/dist/templates/workspace-root/package.json +8 -4
- package/dist/templates/workspace-root/pnpm-workspace.yaml +5 -2
- package/dist/vite/agents-bundle-plugin.js +2 -2
- package/dist/vite/agents-bundle-plugin.js.map +1 -1
- package/docs/content/authentication.md +3 -5
- package/docs/content/multi-app-workspace.md +38 -50
- package/package.json +1 -1
- package/src/templates/default/_gitignore +2 -0
- package/src/templates/workspace-core/AGENTS.md +18 -71
- package/src/templates/workspace-core/package.json +2 -20
- package/src/templates/workspace-core/src/client/index.ts +2 -26
- package/src/templates/workspace-core/src/index.ts +1 -21
- package/src/templates/workspace-core/src/server/index.ts +3 -22
- package/src/templates/workspace-root/.prettierignore +19 -0
- package/src/templates/workspace-root/README.md +17 -20
- package/src/templates/workspace-root/_gitignore +8 -0
- package/src/templates/workspace-root/package.json +8 -4
- package/src/templates/workspace-root/pnpm-workspace.yaml +5 -2
- package/dist/templates/default/.claude/settings.json +0 -100
- package/dist/templates/workspace-core/.agents/skills/company-policies/SKILL.md +0 -42
- package/dist/templates/workspace-core/actions/company-directory.ts +0 -38
- package/dist/templates/workspace-core/src/client/AuthenticatedLayout.tsx +0 -37
- package/dist/templates/workspace-core/src/credentials.ts +0 -67
- package/dist/templates/workspace-core/src/server/agent-chat-plugin.ts +0 -30
- package/dist/templates/workspace-core/src/server/auth-plugin.ts +0 -35
- package/dist/templates/workspace-core/styles/tokens.css +0 -22
- package/dist/templates/workspace-root/scripts/workspace-dev.ts +0 -377
- package/src/templates/default/.claude/settings.json +0 -100
- package/src/templates/workspace-core/.agents/skills/company-policies/SKILL.md +0 -42
- package/src/templates/workspace-core/actions/company-directory.ts +0 -38
- package/src/templates/workspace-core/src/client/AuthenticatedLayout.tsx +0 -37
- package/src/templates/workspace-core/src/credentials.ts +0 -67
- package/src/templates/workspace-core/src/server/agent-chat-plugin.ts +0 -30
- package/src/templates/workspace-core/src/server/auth-plugin.ts +0 -35
- package/src/templates/workspace-core/styles/tokens.css +0 -22
- package/src/templates/workspace-root/scripts/workspace-dev.ts +0 -377
package/dist/org/handlers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/org/handlers.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n defineEventHandler,\n getRouterParam,\n getRequestURL,\n createError,\n type H3Event,\n} from \"h3\";\n\n/**\n * Extract the :id from invitation-accept paths. The framework request handler\n * strips the mount prefix before calling the handler, so `event.url.pathname`\n * is the relative tail — e.g. `/some-id/accept`. Falls back to matching the\n * full path for contexts that don't strip, and to the h3 router param.\n */\nfunction extractInvitationId(event: H3Event): string | undefined {\n const fromRouter = getRouterParam(event, \"id\");\n if (fromRouter) return fromRouter;\n const path = getRequestURL(event).pathname;\n const match =\n path.match(/^\\/([^\\/]+)\\/accept\\/?$/) ??\n path.match(/\\/org\\/invitations\\/([^\\/]+)\\/accept\\/?$/);\n return match?.[1] ? decodeURIComponent(match[1]) : undefined;\n}\n\n/** Extract the :email from member-delete paths. Same prefix-stripping caveat. */\nfunction extractMemberEmail(event: H3Event): string | undefined {\n const fromRouter = getRouterParam(event, \"email\");\n if (fromRouter) return fromRouter;\n const path = getRequestURL(event).pathname;\n const match =\n path.match(/^\\/([^\\/]+)\\/?$/) ?? path.match(/\\/org\\/members\\/([^\\/]+)\\/?$/);\n return match?.[1] ? decodeURIComponent(match[1]) : undefined;\n}\nconst nanoid = (): string =>\n globalThis.crypto?.randomUUID?.().replace(/-/g, \"\") ??\n Math.random().toString(36).slice(2) + Date.now().toString(36);\nimport { readBody } from \"../server/h3-helpers.js\";\nimport { getSession } from \"../server/auth.js\";\nimport { putUserSetting } from \"../settings/user-settings.js\";\nimport { getDbExec } from \"../db/client.js\";\nimport { sendEmail, isEmailConfigured } from \"../server/email.js\";\nimport { renderInviteEmail } from \"../server/email-templates.js\";\nimport { getAppProductionUrl } from \"../server/app-url.js\";\nimport { getOrgContext } from \"./context.js\";\nimport type { OrgRole } from \"./types.js\";\n\nfunction getInviteAppUrl(event: H3Event): string {\n return getAppProductionUrl(event);\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\nasync function exec() {\n return getDbExec();\n}\n\nfunction requireAuthEmail(session: { email?: string } | null): string {\n const email = session?.email;\n if (!email) {\n throw createError({ statusCode: 401, message: \"Authentication required\" });\n }\n return email;\n}\n\n/** GET /_agent-native/org/me — current user's active org, all orgs, pending invitations */\nexport const getMyOrgHandler = defineEventHandler(async (event: H3Event) => {\n const ctx = await getOrgContext(event);\n\n const e = await exec();\n const allOrgsRes = await e.execute({\n sql: `SELECT m.org_id AS \"orgId\", m.role AS role, o.name AS \"orgName\"\n FROM org_members m\n INNER JOIN organizations o ON m.org_id = o.id\n WHERE LOWER(m.email) = ?`,\n args: [ctx.email.toLowerCase()],\n });\n const orgs = allOrgsRes.rows.map((r: any) => ({\n orgId: String(r.orgId ?? r.org_id),\n role: String(r.role) as OrgRole,\n orgName: String(r.orgName ?? r.org_name),\n }));\n\n let domainMatches: Array<{ orgId: string; orgName: string }> = [];\n if (!ctx.orgId) {\n const domain = ctx.email.split(\"@\")[1]?.toLowerCase();\n if (domain) {\n try {\n const dmRes = await e.execute({\n sql: `SELECT id, name FROM organizations WHERE LOWER(allowed_domain) = ?`,\n args: [domain],\n });\n domainMatches = dmRes.rows.map((r: any) => ({\n orgId: String(r.id),\n orgName: String(r.name),\n }));\n } catch {\n // allowed_domain column may not exist yet if migration hasn't run\n }\n }\n }\n\n let allowedDomain: string | null = null;\n let a2aSecret: string | null = null;\n if (ctx.orgId) {\n try {\n const adRes = await e.execute({\n sql: `SELECT allowed_domain, a2a_secret FROM organizations WHERE id = ? LIMIT 1`,\n args: [ctx.orgId],\n });\n if (adRes.rows[0]) {\n allowedDomain =\n String((adRes.rows[0] as any).allowed_domain ?? \"\") || null;\n a2aSecret = String((adRes.rows[0] as any).a2a_secret ?? \"\") || null;\n }\n } catch {\n // Column may not exist yet\n }\n }\n\n const isOwnerOrAdmin = ctx.role === \"owner\" || ctx.role === \"admin\";\n\n const invitesRes = await e.execute({\n // Case-insensitive match: invitations are stored with whatever case\n // the inviter typed, but the session email may be normalized\n // differently by the auth provider. LOWER(both sides) keeps these\n // discoverable and matches getOrgContext.hasPendingInvitation.\n sql: `SELECT i.id AS id, i.org_id AS \"orgId\", o.name AS \"orgName\", i.invited_by AS \"invitedBy\"\n FROM org_invitations i\n INNER JOIN organizations o ON i.org_id = o.id\n WHERE LOWER(i.email) = ? AND i.status = 'pending'`,\n args: [ctx.email.toLowerCase()],\n });\n const pendingInvitations = invitesRes.rows.map((r: any) => ({\n id: String(r.id),\n orgId: String(r.orgId ?? r.org_id),\n orgName: String(r.orgName ?? r.org_name),\n invitedBy: String(r.invitedBy ?? r.invited_by),\n }));\n\n return {\n email: ctx.email,\n orgId: ctx.orgId,\n orgName: ctx.orgName,\n role: ctx.role,\n orgs,\n pendingInvitations,\n domainMatches,\n allowedDomain,\n a2aSecret: isOwnerOrAdmin ? a2aSecret : undefined,\n };\n});\n\n/** POST /_agent-native/org — create a new organization */\nexport const createOrgHandler = defineEventHandler(async (event: H3Event) => {\n const session = await getSession(event);\n const email = requireAuthEmail(session);\n\n const body = await readBody(event);\n const name = body?.name?.trim();\n if (!name) {\n throw createError({\n statusCode: 400,\n message: \"Organization name is required\",\n });\n }\n\n const orgId = nanoid();\n const now = Date.now();\n const e = await exec();\n\n // Auto-generate a per-org A2A secret for cross-app delegation\n const { randomBytes } = await import(\"node:crypto\");\n const a2aSecret = randomBytes(32).toString(\"base64url\");\n\n await e.execute({\n sql: `INSERT INTO organizations (id, name, created_by, created_at, a2a_secret) VALUES (?, ?, ?, ?, ?)`,\n args: [orgId, name, email, now, a2aSecret],\n });\n\n await e.execute({\n sql: `INSERT INTO org_members (id, org_id, email, role, joined_at) VALUES (?, ?, ?, ?, ?)`,\n args: [nanoid(), orgId, email, \"owner\", now],\n });\n\n await putUserSetting(email, \"active-org-id\", { orgId });\n\n return { id: orgId, name, role: \"owner\" };\n});\n\n/** GET /_agent-native/org/members — list org members */\nexport const listMembersHandler = defineEventHandler(async (event: H3Event) => {\n const ctx = await getOrgContext(event);\n if (!ctx.orgId) return { members: [] };\n\n const e = await exec();\n const { rows } = await e.execute({\n sql: `SELECT email, role, joined_at AS \"joinedAt\" FROM org_members WHERE org_id = ?`,\n args: [ctx.orgId],\n });\n const members = rows.map((r: any) => ({\n email: String(r.email),\n role: String(r.role) as OrgRole,\n joinedAt: Number(r.joinedAt ?? r.joined_at),\n }));\n return { members };\n});\n\n/** POST /_agent-native/org/invitations — invite a user by email */\nexport const createInvitationHandler = defineEventHandler(\n async (event: H3Event) => {\n const ctx = await getOrgContext(event);\n if (!ctx.orgId) {\n throw createError({\n statusCode: 400,\n message: \"You must belong to an organization to invite members\",\n });\n }\n if (ctx.role !== \"owner\" && ctx.role !== \"admin\") {\n throw createError({\n statusCode: 403,\n message: \"Only owners and admins can invite members\",\n });\n }\n\n const body = await readBody(event);\n const email = body?.email?.trim()?.toLowerCase();\n if (!email) {\n throw createError({ statusCode: 400, message: \"Email is required\" });\n }\n\n const e = await exec();\n\n // Existing rows in org_members / org_invitations may have any case\n // (writes haven't been normalized historically). Compare with LOWER\n // on both sides so an \"alice@...\" invite check correctly recognizes\n // an existing \"Alice@...\" membership. `email` is already lowercased\n // at parse time above, but call .toLowerCase() explicitly here so\n // the contract at the SQL boundary matches every other handler in\n // this file.\n const existingMember = await e.execute({\n sql: `SELECT 1 FROM org_members WHERE org_id = ? AND LOWER(email) = ? LIMIT 1`,\n args: [ctx.orgId, email.toLowerCase()],\n });\n if (existingMember.rows.length > 0) {\n throw createError({\n statusCode: 409,\n message: \"User is already a member of this organization\",\n });\n }\n\n const existingInvite = await e.execute({\n sql: `SELECT 1 FROM org_invitations WHERE org_id = ? AND LOWER(email) = ? AND status = 'pending' LIMIT 1`,\n args: [ctx.orgId, email.toLowerCase()],\n });\n if (existingInvite.rows.length > 0) {\n throw createError({\n statusCode: 409,\n message: \"An invitation is already pending for this email\",\n });\n }\n\n const id = nanoid();\n await e.execute({\n sql: `INSERT INTO org_invitations (id, org_id, email, invited_by, created_at, status) VALUES (?, ?, ?, ?, ?, 'pending')`,\n args: [id, ctx.orgId, email, ctx.email, Date.now()],\n });\n\n let emailSent = false;\n let emailError: string | undefined;\n if (isEmailConfigured()) {\n try {\n const { subject, html, text } = renderInviteEmail({\n invitee: email,\n orgName: ctx.orgName || \"your team\",\n acceptUrl: getInviteAppUrl(event),\n inviter: ctx.email,\n });\n await sendEmail({ to: email, subject, html, text });\n emailSent = true;\n } catch (err) {\n emailError = err instanceof Error ? err.message : String(err);\n console.error(\"[org/invitations] failed to send invite email\", err);\n }\n }\n\n return { id, email, status: \"pending\", emailSent, emailError };\n },\n);\n\n/** GET /_agent-native/org/invitations — list pending invitations for the org */\nexport const listInvitationsHandler = defineEventHandler(\n async (event: H3Event) => {\n const ctx = await getOrgContext(event);\n if (!ctx.orgId) return { invitations: [] };\n\n const e = await exec();\n const { rows } = await e.execute({\n sql: `SELECT id, email, invited_by AS \"invitedBy\", created_at AS \"createdAt\", status\n FROM org_invitations\n WHERE org_id = ? AND status = 'pending'`,\n args: [ctx.orgId],\n });\n const invitations = rows.map((r: any) => ({\n id: String(r.id),\n email: String(r.email),\n invitedBy: String(r.invitedBy ?? r.invited_by),\n createdAt: Number(r.createdAt ?? r.created_at),\n status: String(r.status),\n }));\n return { invitations };\n },\n);\n\n/** POST /_agent-native/org/invitations/:id/accept — accept an invitation */\nexport const acceptInvitationHandler = defineEventHandler(\n async (event: H3Event) => {\n const session = await getSession(event);\n const email = requireAuthEmail(session);\n\n const invitationId = extractInvitationId(event);\n if (!invitationId) {\n throw createError({\n statusCode: 400,\n message: \"Invitation ID required\",\n });\n }\n\n const e = await exec();\n\n const invRes = await e.execute({\n // Case-insensitive on email — see comment on the analogous\n // pending-invitations query in getMyOrgHandler.\n sql: `SELECT id, org_id AS \"orgId\" FROM org_invitations\n WHERE id = ? AND LOWER(email) = ? AND status = 'pending' LIMIT 1`,\n args: [invitationId, email.toLowerCase()],\n });\n if (invRes.rows.length === 0) {\n throw createError({\n statusCode: 404,\n message: \"Invitation not found or already used\",\n });\n }\n const inv = invRes.rows[0] as any;\n const invOrgId = String(inv.orgId ?? inv.org_id);\n\n const existingMembership = await e.execute({\n sql: `SELECT role FROM org_members WHERE org_id = ? AND LOWER(email) = ? LIMIT 1`,\n args: [invOrgId, email.toLowerCase()],\n });\n\n const orgRes = await e.execute({\n sql: `SELECT name FROM organizations WHERE id = ? LIMIT 1`,\n args: [invOrgId],\n });\n const orgName = String((orgRes.rows[0] as any)?.name ?? \"\");\n\n if (existingMembership.rows.length > 0) {\n await e.execute({\n sql: `UPDATE org_invitations SET status = 'accepted' WHERE id = ?`,\n args: [invitationId],\n });\n await putUserSetting(email, \"active-org-id\", { orgId: invOrgId });\n return {\n orgId: invOrgId,\n orgName,\n role: String((existingMembership.rows[0] as any).role) as OrgRole,\n };\n }\n\n await e.execute({\n sql: `INSERT INTO org_members (id, org_id, email, role, joined_at) VALUES (?, ?, ?, 'member', ?)`,\n args: [nanoid(), invOrgId, email, Date.now()],\n });\n\n await e.execute({\n sql: `UPDATE org_invitations SET status = 'accepted' WHERE id = ?`,\n args: [invitationId],\n });\n\n await putUserSetting(email, \"active-org-id\", { orgId: invOrgId });\n\n return { orgId: invOrgId, orgName, role: \"member\" as OrgRole };\n },\n);\n\n/** DELETE /_agent-native/org/members/:email — remove a member (owner/admin only) */\nexport const removeMemberHandler = defineEventHandler(\n async (event: H3Event) => {\n const ctx = await getOrgContext(event);\n if (!ctx.orgId) {\n throw createError({ statusCode: 400, message: \"No organization found\" });\n }\n if (ctx.role !== \"owner\" && ctx.role !== \"admin\") {\n throw createError({\n statusCode: 403,\n message: \"Only owners and admins can remove members\",\n });\n }\n\n const memberEmail = extractMemberEmail(event);\n if (!memberEmail) {\n throw createError({ statusCode: 400, message: \"Email is required\" });\n }\n\n // memberEmail comes from the URL path verbatim; org_members may\n // hold the row with any case. LOWER both sides for the lookup AND\n // the DELETE so removal works regardless of how either side cased\n // it. The self-removal guard ALSO compares case-insensitively —\n // otherwise an owner whose email was stored as Alice@... could\n // remove themselves via the lowercase URL alice@..., bypassing the\n // guard and leaving the org ownerless.\n const memberEmailLower = memberEmail.toLowerCase();\n if (memberEmailLower === ctx.email.toLowerCase() && ctx.role === \"owner\") {\n throw createError({\n statusCode: 400,\n message: \"Organization owner cannot remove themselves\",\n });\n }\n const e = await exec();\n // Look specifically for an OWNER row matching this email rather\n // than just \"any matching row\". Duplicate-case rows are possible\n // (e.g. legacy data with both \"Alice@...\" and \"alice@...\" in\n // org_members), and the prior `SELECT role ... LIMIT 1` could\n // return the non-owner duplicate, pass the role check, and then\n // the case-insensitive DELETE below would remove BOTH rows —\n // including the owner — leaving the org ownerless. Querying for\n // the owner row directly closes that case-mismatch attack.\n const ownerCheck = await e.execute({\n sql: `SELECT 1 FROM org_members WHERE org_id = ? AND LOWER(email) = ? AND role = 'owner' LIMIT 1`,\n args: [ctx.orgId, memberEmailLower],\n });\n if (ownerCheck.rows.length > 0) {\n throw createError({\n statusCode: 403,\n message: \"Cannot remove the organization owner\",\n });\n }\n\n await e.execute({\n sql: `DELETE FROM org_members WHERE org_id = ? AND LOWER(email) = ?`,\n args: [ctx.orgId, memberEmailLower],\n });\n\n return { success: true };\n },\n);\n\n/** PATCH /_agent-native/org — rename the current organization (owner/admin only) */\nexport const updateOrgHandler = defineEventHandler(async (event: H3Event) => {\n const ctx = await getOrgContext(event);\n if (!ctx.orgId) {\n throw createError({ statusCode: 400, message: \"No organization found\" });\n }\n if (ctx.role !== \"owner\" && ctx.role !== \"admin\") {\n throw createError({\n statusCode: 403,\n message: \"Only owners and admins can update the organization\",\n });\n }\n\n const body = await readBody(event);\n const name = body?.name?.trim();\n if (!name) {\n throw createError({\n statusCode: 400,\n message: \"Organization name is required\",\n });\n }\n\n const e = await exec();\n await e.execute({\n sql: `UPDATE organizations SET name = ? WHERE id = ?`,\n args: [name, ctx.orgId],\n });\n\n return { orgId: ctx.orgId, name };\n});\n\n/** PUT /_agent-native/org/switch — switch the user's active organization */\nexport const switchOrgHandler = defineEventHandler(async (event: H3Event) => {\n const session = await getSession(event);\n const email = requireAuthEmail(session);\n\n const body = await readBody(event);\n const orgId = body?.orgId;\n\n if (!orgId) {\n await putUserSetting(email, \"active-org-id\", { orgId: null });\n return { orgId: null, orgName: null, role: null };\n }\n\n const e = await exec();\n const membership = await e.execute({\n sql: `SELECT m.role AS role, o.name AS \"orgName\"\n FROM org_members m\n INNER JOIN organizations o ON m.org_id = o.id\n WHERE m.org_id = ? AND LOWER(m.email) = ? LIMIT 1`,\n args: [orgId, email.toLowerCase()],\n });\n\n if (membership.rows.length === 0) {\n throw createError({\n statusCode: 403,\n message: \"You are not a member of that organization\",\n });\n }\n\n await putUserSetting(email, \"active-org-id\", { orgId });\n\n const row = membership.rows[0] as any;\n return {\n orgId,\n orgName: String(row.orgName ?? row.org_name),\n role: String(row.role) as OrgRole,\n };\n});\n\n/** POST /_agent-native/org/join-by-domain — join an org whose allowed_domain matches your email */\nexport const joinByDomainHandler = defineEventHandler(\n async (event: H3Event) => {\n const session = await getSession(event);\n const email = requireAuthEmail(session);\n\n const body = await readBody(event);\n const orgId = body?.orgId;\n if (!orgId) {\n throw createError({ statusCode: 400, message: \"orgId is required\" });\n }\n\n const e = await exec();\n\n const orgRes = await e.execute({\n sql: `SELECT id, name, allowed_domain FROM organizations WHERE id = ? LIMIT 1`,\n args: [orgId],\n });\n if (orgRes.rows.length === 0) {\n throw createError({ statusCode: 404, message: \"Organization not found\" });\n }\n const org = orgRes.rows[0] as any;\n const allowedDomain = String(org.allowed_domain || \"\").toLowerCase();\n const userDomain = email.split(\"@\")[1]?.toLowerCase();\n\n if (!allowedDomain || allowedDomain !== userDomain) {\n throw createError({\n statusCode: 403,\n message:\n \"Your email domain does not match this organization's allowed domain\",\n });\n }\n\n const existing = await e.execute({\n sql: `SELECT 1 FROM org_members WHERE org_id = ? AND LOWER(email) = ? LIMIT 1`,\n args: [orgId, email.toLowerCase()],\n });\n if (existing.rows.length > 0) {\n throw createError({\n statusCode: 409,\n message: \"Already a member of this organization\",\n });\n }\n\n await e.execute({\n sql: `INSERT INTO org_members (id, org_id, email, role, joined_at) VALUES (?, ?, ?, 'member', ?)`,\n args: [nanoid(), orgId, email, Date.now()],\n });\n\n await putUserSetting(email, \"active-org-id\", { orgId });\n\n return {\n orgId,\n orgName: String(org.name),\n role: \"member\" as OrgRole,\n };\n },\n);\n\n/** PUT /_agent-native/org/domain — set or clear the allowed email domain (owner/admin only) */\nexport const setDomainHandler = defineEventHandler(async (event: H3Event) => {\n const ctx = await getOrgContext(event);\n if (!ctx.orgId) {\n throw createError({ statusCode: 400, message: \"No active organization\" });\n }\n if (ctx.role !== \"owner\" && ctx.role !== \"admin\") {\n throw createError({\n statusCode: 403,\n message: \"Only owners and admins can set the allowed domain\",\n });\n }\n\n const body = await readBody(event);\n const raw = body?.domain?.trim()?.toLowerCase() || null;\n\n if (raw && !/^([a-z0-9]([a-z0-9-]*[a-z0-9])?\\.)+[a-z]{2,}$/.test(raw)) {\n throw createError({\n statusCode: 400,\n message: \"Invalid domain format\",\n });\n }\n\n const e = await exec();\n\n if (raw) {\n const existing = await e.execute({\n sql: `SELECT id FROM organizations WHERE LOWER(allowed_domain) = ? AND id != ? LIMIT 1`,\n args: [raw, ctx.orgId],\n });\n if (existing.rows.length > 0) {\n throw createError({\n statusCode: 409,\n message: \"Another organization already uses this domain\",\n });\n }\n }\n\n await e.execute({\n sql: `UPDATE organizations SET allowed_domain = ? WHERE id = ?`,\n args: [raw, ctx.orgId],\n });\n\n return { domain: raw };\n});\n\n/** PUT /_agent-native/org/a2a-secret — regenerate or set the org's A2A secret (owner/admin only) */\nexport const setA2ASecretHandler = defineEventHandler(\n async (event: H3Event) => {\n const ctx = await getOrgContext(event);\n if (!ctx.orgId) {\n throw createError({\n statusCode: 400,\n message: \"No active organization\",\n });\n }\n if (ctx.role !== \"owner\" && ctx.role !== \"admin\") {\n throw createError({\n statusCode: 403,\n message: \"Only owners and admins can manage the A2A secret\",\n });\n }\n\n const body = await readBody(event);\n let secret = body?.secret?.trim() || null;\n\n // If no secret provided, auto-generate one\n if (!secret) {\n const { randomBytes } = await import(\"node:crypto\");\n secret = randomBytes(32).toString(\"base64url\");\n }\n\n const e = await exec();\n // Read the previous secret BEFORE overwriting so the client can chain a\n // sync call that signs JWTs with the secret peers still hold.\n const prevRes = await e.execute({\n sql: `SELECT a2a_secret FROM organizations WHERE id = ? LIMIT 1`,\n args: [ctx.orgId],\n });\n const previousSecret =\n String((prevRes.rows[0] as any)?.a2a_secret ?? \"\") || null;\n\n await e.execute({\n sql: `UPDATE organizations SET a2a_secret = ? WHERE id = ?`,\n args: [secret, ctx.orgId],\n });\n\n return { a2aSecret: secret, previousSecret };\n },\n);\n\n/**\n * POST /_agent-native/org/a2a-secret/sync — push the org's A2A secret to all\n * connected apps so cross-app delegation works without manual copy/paste.\n *\n * Auth: standard session — owner/admin only.\n *\n * For each discovered agent, signs a JWT with the org's CURRENT a2a_secret\n * and POSTs to `<app>/_agent-native/org/a2a-secret/receive` with the same\n * secret + the org's domain. The receiving app verifies the JWT using its\n * own copy of the secret (peers must already share a secret to be trusted)\n * — for the first-ever sync this means at least one peer must already hold\n * the secret, which is the bootstrap. For ongoing rotation, regenerate\n * locally and call sync immediately; sync signs with the secret that's\n * currently in DB, which the peers still have.\n *\n * Body (optional): { signSecret?: string } — sign the outbound JWTs with\n * this secret instead of the org's current secret. Used by the regenerate-\n * then-sync flow: regenerate stores the NEW secret, but sync needs to\n * authenticate using the OLD one that peers still hold. Owner/admin only,\n * gated by the session.\n */\nexport const syncA2ASecretHandler = defineEventHandler(\n async (event: H3Event) => {\n const ctx = await getOrgContext(event);\n if (!ctx.orgId) {\n throw createError({\n statusCode: 400,\n message: \"No active organization\",\n });\n }\n if (ctx.role !== \"owner\" && ctx.role !== \"admin\") {\n throw createError({\n statusCode: 403,\n message: \"Only owners and admins can sync the A2A secret\",\n });\n }\n\n const body = await readBody(event).catch(() => null);\n const overrideSignSecret =\n typeof body?.signSecret === \"string\" && body.signSecret.trim()\n ? body.signSecret.trim()\n : null;\n\n const e = await exec();\n const orgRes = await e.execute({\n sql: `SELECT a2a_secret, allowed_domain FROM organizations WHERE id = ? LIMIT 1`,\n args: [ctx.orgId],\n });\n if (orgRes.rows.length === 0) {\n throw createError({\n statusCode: 404,\n message: \"Organization not found\",\n });\n }\n const orgRow = orgRes.rows[0] as any;\n const secret = String(orgRow.a2a_secret ?? \"\") || null;\n const orgDomain = String(orgRow.allowed_domain ?? \"\") || null;\n\n if (!secret) {\n throw createError({\n statusCode: 400,\n message: \"Org has no A2A secret. Generate one first before syncing.\",\n });\n }\n if (!orgDomain) {\n throw createError({\n statusCode: 400,\n message:\n \"Org has no allowed domain set. Set the email domain first so connected apps can identify which org to update.\",\n });\n }\n\n const signSecret = overrideSignSecret || secret;\n\n const { discoverAgents } = await import(\"../server/agent-discovery.js\");\n const { signA2AToken } = await import(\"../a2a/client.js\");\n\n const agents = await discoverAgents();\n\n const results: Array<{\n id: string;\n name: string;\n url: string;\n ok: boolean;\n status?: number;\n error?: string;\n }> = [];\n\n await Promise.all(\n agents.map(async (agent) => {\n try {\n const token = await signA2AToken(ctx.email, orgDomain, signSecret);\n\n const target = `${agent.url.replace(/\\/$/, \"\")}/_agent-native/org/a2a-secret/receive`;\n const res = await fetch(target, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify({ secret, orgDomain }),\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n results.push({\n id: agent.id,\n name: agent.name,\n url: agent.url,\n ok: false,\n status: res.status,\n error: text || res.statusText,\n });\n return;\n }\n results.push({\n id: agent.id,\n name: agent.name,\n url: agent.url,\n ok: true,\n status: res.status,\n });\n } catch (err) {\n results.push({\n id: agent.id,\n name: agent.name,\n url: agent.url,\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }),\n );\n\n const succeeded = results.filter((r) => r.ok).length;\n return {\n total: results.length,\n succeeded,\n failed: results.length - succeeded,\n results,\n };\n },\n);\n\n/**\n * POST /_agent-native/org/a2a-secret/receive — accept a secret push from a\n * connected agent-native app. Auth-exempt at the route guard; we verify a\n * JWT signed by the calling app using OUR copy of the org's a2a_secret. If\n * verification succeeds the calling app is a trusted peer and we overwrite\n * our local org's secret with the supplied value.\n *\n * Body: { secret: string, orgDomain: string }\n *\n * Header: Authorization: Bearer <JWT signed with the existing shared\n * a2a_secret, with `org_domain` matching the body's orgDomain>.\n */\nexport const receiveA2ASecretHandler = defineEventHandler(\n async (event: H3Event) => {\n const { getRequestHeader } = await import(\"h3\");\n const jose = await import(\"jose\");\n\n const authHeader = getRequestHeader(event, \"authorization\");\n if (!authHeader || !authHeader.startsWith(\"Bearer \")) {\n throw createError({\n statusCode: 401,\n message: \"Bearer token required\",\n });\n }\n const token = authHeader.slice(\"Bearer \".length);\n\n const body = await readBody(event);\n const newSecret =\n typeof body?.secret === \"string\" ? body.secret.trim() : \"\";\n const orgDomain =\n typeof body?.orgDomain === \"string\"\n ? body.orgDomain.trim().toLowerCase()\n : \"\";\n if (!newSecret || !orgDomain) {\n throw createError({\n statusCode: 400,\n message: \"secret and orgDomain are required\",\n });\n }\n\n // Peek at JWT (unverified) to confirm it claims the same domain we're\n // updating. Verification still happens below with the trusted secret.\n let claimedDomain: string | undefined;\n try {\n const unverified = jose.decodeJwt(token);\n claimedDomain =\n (unverified.org_domain as string | undefined) || undefined;\n } catch {\n throw createError({\n statusCode: 401,\n message: \"Malformed JWT\",\n });\n }\n if (\n !claimedDomain ||\n claimedDomain.toLowerCase() !== orgDomain.toLowerCase()\n ) {\n throw createError({\n statusCode: 401,\n message: \"JWT org_domain does not match request body\",\n });\n }\n\n // Look up our local org by the domain and grab the existing secret.\n const e = await exec();\n const orgRes = await e.execute({\n sql: `SELECT id, a2a_secret FROM organizations WHERE LOWER(allowed_domain) = ? LIMIT 1`,\n args: [orgDomain],\n });\n if (orgRes.rows.length === 0) {\n throw createError({\n statusCode: 404,\n message: \"No local org matches that domain\",\n });\n }\n const row = orgRes.rows[0] as any;\n const localOrgId = String(row.id);\n const existingSecret = String(row.a2a_secret ?? \"\") || null;\n\n if (!existingSecret) {\n // Bootstrap requires an existing shared secret to verify the caller.\n // If we have nothing on file, we can't verify trust — refuse.\n throw createError({\n statusCode: 401,\n message:\n \"Local org has no A2A secret yet — cannot verify caller. Set the secret manually for the first time.\",\n });\n }\n\n // Verify the JWT using OUR existing secret. If the caller is a trusted\n // peer they signed with the same secret and verification succeeds.\n try {\n await jose.jwtVerify(token, new TextEncoder().encode(existingSecret));\n } catch {\n throw createError({\n statusCode: 401,\n message: \"Invalid or expired JWT signature\",\n });\n }\n\n // Trusted — apply the new secret.\n await e.execute({\n sql: `UPDATE organizations SET a2a_secret = ? WHERE id = ?`,\n args: [newSecret, localOrgId],\n });\n\n return { ok: true, orgId: localOrgId };\n },\n);\n"]}
|
|
1
|
+
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/org/handlers.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n defineEventHandler,\n getRouterParam,\n getRequestURL,\n createError,\n type H3Event,\n} from \"h3\";\n\n/**\n * Extract the :id from invitation-accept paths. The framework request handler\n * strips the mount prefix before calling the handler, so `event.url.pathname`\n * is the relative tail — e.g. `/some-id/accept`. Falls back to matching the\n * full path for contexts that don't strip, and to the h3 router param.\n */\nfunction extractInvitationId(event: H3Event): string | undefined {\n const fromRouter = getRouterParam(event, \"id\");\n if (fromRouter) return fromRouter;\n const path = getRequestURL(event).pathname;\n const match =\n path.match(/^\\/([^\\/]+)\\/accept\\/?$/) ??\n path.match(/\\/org\\/invitations\\/([^\\/]+)\\/accept\\/?$/);\n return match?.[1] ? decodeURIComponent(match[1]) : undefined;\n}\n\n/** Extract the :email from member-delete paths. Same prefix-stripping caveat. */\nfunction extractMemberEmail(event: H3Event): string | undefined {\n const fromRouter = getRouterParam(event, \"email\");\n if (fromRouter) return fromRouter;\n const path = getRequestURL(event).pathname;\n const match =\n path.match(/^\\/([^\\/]+)\\/?$/) ?? path.match(/\\/org\\/members\\/([^\\/]+)\\/?$/);\n return match?.[1] ? decodeURIComponent(match[1]) : undefined;\n}\nconst nanoid = (): string =>\n globalThis.crypto?.randomUUID?.().replace(/-/g, \"\") ??\n Math.random().toString(36).slice(2) + Date.now().toString(36);\nimport { readBody } from \"../server/h3-helpers.js\";\nimport { getSession } from \"../server/auth.js\";\nimport { putUserSetting } from \"../settings/user-settings.js\";\nimport { getDbExec } from \"../db/client.js\";\nimport { sendEmail, isEmailConfigured } from \"../server/email.js\";\nimport { renderInviteEmail } from \"../server/email-templates.js\";\nimport { getAppProductionUrl } from \"../server/app-url.js\";\nimport { getOrgContext } from \"./context.js\";\nimport type { OrgRole } from \"./types.js\";\n\nfunction getInviteAppUrl(event: H3Event): string {\n return getAppProductionUrl(event);\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\nasync function exec() {\n return getDbExec();\n}\n\nfunction requireAuthEmail(session: { email?: string } | null): string {\n const email = session?.email;\n if (!email) {\n throw createError({ statusCode: 401, message: \"Authentication required\" });\n }\n return email;\n}\n\n/** GET /_agent-native/org/me — current user's active org, all orgs, pending invitations */\nexport const getMyOrgHandler = defineEventHandler(async (event: H3Event) => {\n const ctx = await getOrgContext(event);\n\n const e = await exec();\n const allOrgsRes = await e.execute({\n sql: `SELECT m.org_id AS \"orgId\", m.role AS role, o.name AS \"orgName\"\n FROM org_members m\n INNER JOIN organizations o ON m.org_id = o.id\n WHERE LOWER(m.email) = ?`,\n args: [ctx.email.toLowerCase()],\n });\n const orgs = allOrgsRes.rows.map((r: any) => ({\n orgId: String(r.orgId ?? r.org_id),\n role: String(r.role) as OrgRole,\n orgName: String(r.orgName ?? r.org_name),\n }));\n\n let domainMatches: Array<{ orgId: string; orgName: string }> = [];\n const domain = ctx.email.split(\"@\")[1]?.toLowerCase();\n if (domain) {\n try {\n const dmRes = await e.execute({\n sql: `SELECT o.id, o.name\n FROM organizations o\n WHERE LOWER(o.allowed_domain) = ?\n AND NOT EXISTS (\n SELECT 1\n FROM org_members m\n WHERE m.org_id = o.id\n AND LOWER(m.email) = ?\n )`,\n args: [domain, ctx.email.toLowerCase()],\n });\n domainMatches = dmRes.rows.map((r: any) => ({\n orgId: String(r.id),\n orgName: String(r.name),\n }));\n } catch {\n // allowed_domain column may not exist yet if migration hasn't run\n }\n }\n\n let allowedDomain: string | null = null;\n let a2aSecret: string | null = null;\n if (ctx.orgId) {\n try {\n const adRes = await e.execute({\n sql: `SELECT allowed_domain, a2a_secret FROM organizations WHERE id = ? LIMIT 1`,\n args: [ctx.orgId],\n });\n if (adRes.rows[0]) {\n allowedDomain =\n String((adRes.rows[0] as any).allowed_domain ?? \"\") || null;\n a2aSecret = String((adRes.rows[0] as any).a2a_secret ?? \"\") || null;\n }\n } catch {\n // Column may not exist yet\n }\n }\n\n const isOwnerOrAdmin = ctx.role === \"owner\" || ctx.role === \"admin\";\n\n const invitesRes = await e.execute({\n // Case-insensitive match: invitations are stored with whatever case\n // the inviter typed, but the session email may be normalized\n // differently by the auth provider. LOWER(both sides) keeps these\n // discoverable and matches getOrgContext.hasPendingInvitation.\n sql: `SELECT i.id AS id, i.org_id AS \"orgId\", o.name AS \"orgName\", i.invited_by AS \"invitedBy\"\n FROM org_invitations i\n INNER JOIN organizations o ON i.org_id = o.id\n WHERE LOWER(i.email) = ? AND i.status = 'pending'`,\n args: [ctx.email.toLowerCase()],\n });\n const pendingInvitations = invitesRes.rows.map((r: any) => ({\n id: String(r.id),\n orgId: String(r.orgId ?? r.org_id),\n orgName: String(r.orgName ?? r.org_name),\n invitedBy: String(r.invitedBy ?? r.invited_by),\n }));\n\n return {\n email: ctx.email,\n orgId: ctx.orgId,\n orgName: ctx.orgName,\n role: ctx.role,\n orgs,\n pendingInvitations,\n domainMatches,\n allowedDomain,\n a2aSecret: isOwnerOrAdmin ? a2aSecret : undefined,\n };\n});\n\n/** POST /_agent-native/org — create a new organization */\nexport const createOrgHandler = defineEventHandler(async (event: H3Event) => {\n const session = await getSession(event);\n const email = requireAuthEmail(session);\n\n const body = await readBody(event);\n const name = body?.name?.trim();\n if (!name) {\n throw createError({\n statusCode: 400,\n message: \"Organization name is required\",\n });\n }\n\n const orgId = nanoid();\n const now = Date.now();\n const e = await exec();\n\n // Auto-generate a per-org A2A secret for cross-app delegation\n const { randomBytes } = await import(\"node:crypto\");\n const a2aSecret = randomBytes(32).toString(\"base64url\");\n\n await e.execute({\n sql: `INSERT INTO organizations (id, name, created_by, created_at, a2a_secret) VALUES (?, ?, ?, ?, ?)`,\n args: [orgId, name, email, now, a2aSecret],\n });\n\n await e.execute({\n sql: `INSERT INTO org_members (id, org_id, email, role, joined_at) VALUES (?, ?, ?, ?, ?)`,\n args: [nanoid(), orgId, email, \"owner\", now],\n });\n\n await putUserSetting(email, \"active-org-id\", { orgId });\n\n return { id: orgId, name, role: \"owner\" };\n});\n\n/** GET /_agent-native/org/members — list org members */\nexport const listMembersHandler = defineEventHandler(async (event: H3Event) => {\n const ctx = await getOrgContext(event);\n if (!ctx.orgId) return { members: [] };\n\n const e = await exec();\n const { rows } = await e.execute({\n sql: `SELECT email, role, joined_at AS \"joinedAt\" FROM org_members WHERE org_id = ?`,\n args: [ctx.orgId],\n });\n const members = rows.map((r: any) => ({\n email: String(r.email),\n role: String(r.role) as OrgRole,\n joinedAt: Number(r.joinedAt ?? r.joined_at),\n }));\n return { members };\n});\n\n/** POST /_agent-native/org/invitations — invite a user by email */\nexport const createInvitationHandler = defineEventHandler(\n async (event: H3Event) => {\n const ctx = await getOrgContext(event);\n if (!ctx.orgId) {\n throw createError({\n statusCode: 400,\n message: \"You must belong to an organization to invite members\",\n });\n }\n if (ctx.role !== \"owner\" && ctx.role !== \"admin\") {\n throw createError({\n statusCode: 403,\n message: \"Only owners and admins can invite members\",\n });\n }\n\n const body = await readBody(event);\n const email = body?.email?.trim()?.toLowerCase();\n if (!email) {\n throw createError({ statusCode: 400, message: \"Email is required\" });\n }\n\n const e = await exec();\n\n // Existing rows in org_members / org_invitations may have any case\n // (writes haven't been normalized historically). Compare with LOWER\n // on both sides so an \"alice@...\" invite check correctly recognizes\n // an existing \"Alice@...\" membership. `email` is already lowercased\n // at parse time above, but call .toLowerCase() explicitly here so\n // the contract at the SQL boundary matches every other handler in\n // this file.\n const existingMember = await e.execute({\n sql: `SELECT 1 FROM org_members WHERE org_id = ? AND LOWER(email) = ? LIMIT 1`,\n args: [ctx.orgId, email.toLowerCase()],\n });\n if (existingMember.rows.length > 0) {\n throw createError({\n statusCode: 409,\n message: \"User is already a member of this organization\",\n });\n }\n\n const existingInvite = await e.execute({\n sql: `SELECT 1 FROM org_invitations WHERE org_id = ? AND LOWER(email) = ? AND status = 'pending' LIMIT 1`,\n args: [ctx.orgId, email.toLowerCase()],\n });\n if (existingInvite.rows.length > 0) {\n throw createError({\n statusCode: 409,\n message: \"An invitation is already pending for this email\",\n });\n }\n\n const id = nanoid();\n await e.execute({\n sql: `INSERT INTO org_invitations (id, org_id, email, invited_by, created_at, status) VALUES (?, ?, ?, ?, ?, 'pending')`,\n args: [id, ctx.orgId, email, ctx.email, Date.now()],\n });\n\n let emailSent = false;\n let emailError: string | undefined;\n if (isEmailConfigured()) {\n try {\n const { subject, html, text } = renderInviteEmail({\n invitee: email,\n orgName: ctx.orgName || \"your team\",\n acceptUrl: getInviteAppUrl(event),\n inviter: ctx.email,\n });\n await sendEmail({ to: email, subject, html, text });\n emailSent = true;\n } catch (err) {\n emailError = err instanceof Error ? err.message : String(err);\n console.error(\"[org/invitations] failed to send invite email\", err);\n }\n }\n\n return { id, email, status: \"pending\", emailSent, emailError };\n },\n);\n\n/** GET /_agent-native/org/invitations — list pending invitations for the org */\nexport const listInvitationsHandler = defineEventHandler(\n async (event: H3Event) => {\n const ctx = await getOrgContext(event);\n if (!ctx.orgId) return { invitations: [] };\n\n const e = await exec();\n const { rows } = await e.execute({\n sql: `SELECT id, email, invited_by AS \"invitedBy\", created_at AS \"createdAt\", status\n FROM org_invitations\n WHERE org_id = ? AND status = 'pending'`,\n args: [ctx.orgId],\n });\n const invitations = rows.map((r: any) => ({\n id: String(r.id),\n email: String(r.email),\n invitedBy: String(r.invitedBy ?? r.invited_by),\n createdAt: Number(r.createdAt ?? r.created_at),\n status: String(r.status),\n }));\n return { invitations };\n },\n);\n\n/** POST /_agent-native/org/invitations/:id/accept — accept an invitation */\nexport const acceptInvitationHandler = defineEventHandler(\n async (event: H3Event) => {\n const session = await getSession(event);\n const email = requireAuthEmail(session);\n\n const invitationId = extractInvitationId(event);\n if (!invitationId) {\n throw createError({\n statusCode: 400,\n message: \"Invitation ID required\",\n });\n }\n\n const e = await exec();\n\n const invRes = await e.execute({\n // Case-insensitive on email — see comment on the analogous\n // pending-invitations query in getMyOrgHandler.\n sql: `SELECT id, org_id AS \"orgId\" FROM org_invitations\n WHERE id = ? AND LOWER(email) = ? AND status = 'pending' LIMIT 1`,\n args: [invitationId, email.toLowerCase()],\n });\n if (invRes.rows.length === 0) {\n throw createError({\n statusCode: 404,\n message: \"Invitation not found or already used\",\n });\n }\n const inv = invRes.rows[0] as any;\n const invOrgId = String(inv.orgId ?? inv.org_id);\n\n const existingMembership = await e.execute({\n sql: `SELECT role FROM org_members WHERE org_id = ? AND LOWER(email) = ? LIMIT 1`,\n args: [invOrgId, email.toLowerCase()],\n });\n\n const orgRes = await e.execute({\n sql: `SELECT name FROM organizations WHERE id = ? LIMIT 1`,\n args: [invOrgId],\n });\n const orgName = String((orgRes.rows[0] as any)?.name ?? \"\");\n\n if (existingMembership.rows.length > 0) {\n await e.execute({\n sql: `UPDATE org_invitations SET status = 'accepted' WHERE id = ?`,\n args: [invitationId],\n });\n await putUserSetting(email, \"active-org-id\", { orgId: invOrgId });\n return {\n orgId: invOrgId,\n orgName,\n role: String((existingMembership.rows[0] as any).role) as OrgRole,\n };\n }\n\n await e.execute({\n sql: `INSERT INTO org_members (id, org_id, email, role, joined_at) VALUES (?, ?, ?, 'member', ?)`,\n args: [nanoid(), invOrgId, email, Date.now()],\n });\n\n await e.execute({\n sql: `UPDATE org_invitations SET status = 'accepted' WHERE id = ?`,\n args: [invitationId],\n });\n\n await putUserSetting(email, \"active-org-id\", { orgId: invOrgId });\n\n return { orgId: invOrgId, orgName, role: \"member\" as OrgRole };\n },\n);\n\n/** DELETE /_agent-native/org/members/:email — remove a member (owner/admin only) */\nexport const removeMemberHandler = defineEventHandler(\n async (event: H3Event) => {\n const ctx = await getOrgContext(event);\n if (!ctx.orgId) {\n throw createError({ statusCode: 400, message: \"No organization found\" });\n }\n if (ctx.role !== \"owner\" && ctx.role !== \"admin\") {\n throw createError({\n statusCode: 403,\n message: \"Only owners and admins can remove members\",\n });\n }\n\n const memberEmail = extractMemberEmail(event);\n if (!memberEmail) {\n throw createError({ statusCode: 400, message: \"Email is required\" });\n }\n\n // memberEmail comes from the URL path verbatim; org_members may\n // hold the row with any case. LOWER both sides for the lookup AND\n // the DELETE so removal works regardless of how either side cased\n // it. The self-removal guard ALSO compares case-insensitively —\n // otherwise an owner whose email was stored as Alice@... could\n // remove themselves via the lowercase URL alice@..., bypassing the\n // guard and leaving the org ownerless.\n const memberEmailLower = memberEmail.toLowerCase();\n if (memberEmailLower === ctx.email.toLowerCase() && ctx.role === \"owner\") {\n throw createError({\n statusCode: 400,\n message: \"Organization owner cannot remove themselves\",\n });\n }\n const e = await exec();\n // Look specifically for an OWNER row matching this email rather\n // than just \"any matching row\". Duplicate-case rows are possible\n // (e.g. legacy data with both \"Alice@...\" and \"alice@...\" in\n // org_members), and the prior `SELECT role ... LIMIT 1` could\n // return the non-owner duplicate, pass the role check, and then\n // the case-insensitive DELETE below would remove BOTH rows —\n // including the owner — leaving the org ownerless. Querying for\n // the owner row directly closes that case-mismatch attack.\n const ownerCheck = await e.execute({\n sql: `SELECT 1 FROM org_members WHERE org_id = ? AND LOWER(email) = ? AND role = 'owner' LIMIT 1`,\n args: [ctx.orgId, memberEmailLower],\n });\n if (ownerCheck.rows.length > 0) {\n throw createError({\n statusCode: 403,\n message: \"Cannot remove the organization owner\",\n });\n }\n\n await e.execute({\n sql: `DELETE FROM org_members WHERE org_id = ? AND LOWER(email) = ?`,\n args: [ctx.orgId, memberEmailLower],\n });\n\n return { success: true };\n },\n);\n\n/** PATCH /_agent-native/org — rename the current organization (owner/admin only) */\nexport const updateOrgHandler = defineEventHandler(async (event: H3Event) => {\n const ctx = await getOrgContext(event);\n if (!ctx.orgId) {\n throw createError({ statusCode: 400, message: \"No organization found\" });\n }\n if (ctx.role !== \"owner\" && ctx.role !== \"admin\") {\n throw createError({\n statusCode: 403,\n message: \"Only owners and admins can update the organization\",\n });\n }\n\n const body = await readBody(event);\n const name = body?.name?.trim();\n if (!name) {\n throw createError({\n statusCode: 400,\n message: \"Organization name is required\",\n });\n }\n\n const e = await exec();\n await e.execute({\n sql: `UPDATE organizations SET name = ? WHERE id = ?`,\n args: [name, ctx.orgId],\n });\n\n return { orgId: ctx.orgId, name };\n});\n\n/** PUT /_agent-native/org/switch — switch the user's active organization */\nexport const switchOrgHandler = defineEventHandler(async (event: H3Event) => {\n const session = await getSession(event);\n const email = requireAuthEmail(session);\n\n const body = await readBody(event);\n const orgId = body?.orgId;\n\n if (!orgId) {\n await putUserSetting(email, \"active-org-id\", { orgId: null });\n return { orgId: null, orgName: null, role: null };\n }\n\n const e = await exec();\n const membership = await e.execute({\n sql: `SELECT m.role AS role, o.name AS \"orgName\"\n FROM org_members m\n INNER JOIN organizations o ON m.org_id = o.id\n WHERE m.org_id = ? AND LOWER(m.email) = ? LIMIT 1`,\n args: [orgId, email.toLowerCase()],\n });\n\n if (membership.rows.length === 0) {\n throw createError({\n statusCode: 403,\n message: \"You are not a member of that organization\",\n });\n }\n\n await putUserSetting(email, \"active-org-id\", { orgId });\n\n const row = membership.rows[0] as any;\n return {\n orgId,\n orgName: String(row.orgName ?? row.org_name),\n role: String(row.role) as OrgRole,\n };\n});\n\n/** POST /_agent-native/org/join-by-domain — join an org whose allowed_domain matches your email */\nexport const joinByDomainHandler = defineEventHandler(\n async (event: H3Event) => {\n const session = await getSession(event);\n const email = requireAuthEmail(session);\n\n const body = await readBody(event);\n const orgId = body?.orgId;\n if (!orgId) {\n throw createError({ statusCode: 400, message: \"orgId is required\" });\n }\n\n const e = await exec();\n\n const orgRes = await e.execute({\n sql: `SELECT id, name, allowed_domain FROM organizations WHERE id = ? LIMIT 1`,\n args: [orgId],\n });\n if (orgRes.rows.length === 0) {\n throw createError({ statusCode: 404, message: \"Organization not found\" });\n }\n const org = orgRes.rows[0] as any;\n const allowedDomain = String(org.allowed_domain || \"\").toLowerCase();\n const userDomain = email.split(\"@\")[1]?.toLowerCase();\n\n if (!allowedDomain || allowedDomain !== userDomain) {\n throw createError({\n statusCode: 403,\n message:\n \"Your email domain does not match this organization's allowed domain\",\n });\n }\n\n const existing = await e.execute({\n sql: `SELECT 1 FROM org_members WHERE org_id = ? AND LOWER(email) = ? LIMIT 1`,\n args: [orgId, email.toLowerCase()],\n });\n if (existing.rows.length > 0) {\n throw createError({\n statusCode: 409,\n message: \"Already a member of this organization\",\n });\n }\n\n await e.execute({\n sql: `INSERT INTO org_members (id, org_id, email, role, joined_at) VALUES (?, ?, ?, 'member', ?)`,\n args: [nanoid(), orgId, email, Date.now()],\n });\n\n await putUserSetting(email, \"active-org-id\", { orgId });\n\n return {\n orgId,\n orgName: String(org.name),\n role: \"member\" as OrgRole,\n };\n },\n);\n\n/** PUT /_agent-native/org/domain — set or clear the allowed email domain (owner/admin only) */\nexport const setDomainHandler = defineEventHandler(async (event: H3Event) => {\n const ctx = await getOrgContext(event);\n if (!ctx.orgId) {\n throw createError({ statusCode: 400, message: \"No active organization\" });\n }\n if (ctx.role !== \"owner\" && ctx.role !== \"admin\") {\n throw createError({\n statusCode: 403,\n message: \"Only owners and admins can set the allowed domain\",\n });\n }\n\n const body = await readBody(event);\n const raw = body?.domain?.trim()?.toLowerCase() || null;\n\n if (raw && !/^([a-z0-9]([a-z0-9-]*[a-z0-9])?\\.)+[a-z]{2,}$/.test(raw)) {\n throw createError({\n statusCode: 400,\n message: \"Invalid domain format\",\n });\n }\n\n const e = await exec();\n\n if (raw) {\n const existing = await e.execute({\n sql: `SELECT id FROM organizations WHERE LOWER(allowed_domain) = ? AND id != ? LIMIT 1`,\n args: [raw, ctx.orgId],\n });\n if (existing.rows.length > 0) {\n throw createError({\n statusCode: 409,\n message: \"Another organization already uses this domain\",\n });\n }\n }\n\n await e.execute({\n sql: `UPDATE organizations SET allowed_domain = ? WHERE id = ?`,\n args: [raw, ctx.orgId],\n });\n\n return { domain: raw };\n});\n\n/** PUT /_agent-native/org/a2a-secret — regenerate or set the org's A2A secret (owner/admin only) */\nexport const setA2ASecretHandler = defineEventHandler(\n async (event: H3Event) => {\n const ctx = await getOrgContext(event);\n if (!ctx.orgId) {\n throw createError({\n statusCode: 400,\n message: \"No active organization\",\n });\n }\n if (ctx.role !== \"owner\" && ctx.role !== \"admin\") {\n throw createError({\n statusCode: 403,\n message: \"Only owners and admins can manage the A2A secret\",\n });\n }\n\n const body = await readBody(event);\n let secret = body?.secret?.trim() || null;\n\n // If no secret provided, auto-generate one\n if (!secret) {\n const { randomBytes } = await import(\"node:crypto\");\n secret = randomBytes(32).toString(\"base64url\");\n }\n\n const e = await exec();\n // Read the previous secret BEFORE overwriting so the client can chain a\n // sync call that signs JWTs with the secret peers still hold.\n const prevRes = await e.execute({\n sql: `SELECT a2a_secret FROM organizations WHERE id = ? LIMIT 1`,\n args: [ctx.orgId],\n });\n const previousSecret =\n String((prevRes.rows[0] as any)?.a2a_secret ?? \"\") || null;\n\n await e.execute({\n sql: `UPDATE organizations SET a2a_secret = ? WHERE id = ?`,\n args: [secret, ctx.orgId],\n });\n\n return { a2aSecret: secret, previousSecret };\n },\n);\n\n/**\n * POST /_agent-native/org/a2a-secret/sync — push the org's A2A secret to all\n * connected apps so cross-app delegation works without manual copy/paste.\n *\n * Auth: standard session — owner/admin only.\n *\n * For each discovered agent, signs a JWT with the org's CURRENT a2a_secret\n * and POSTs to `<app>/_agent-native/org/a2a-secret/receive` with the same\n * secret + the org's domain. The receiving app verifies the JWT using its\n * own copy of the secret (peers must already share a secret to be trusted)\n * — for the first-ever sync this means at least one peer must already hold\n * the secret, which is the bootstrap. For ongoing rotation, regenerate\n * locally and call sync immediately; sync signs with the secret that's\n * currently in DB, which the peers still have.\n *\n * Body (optional): { signSecret?: string } — sign the outbound JWTs with\n * this secret instead of the org's current secret. Used by the regenerate-\n * then-sync flow: regenerate stores the NEW secret, but sync needs to\n * authenticate using the OLD one that peers still hold. Owner/admin only,\n * gated by the session.\n */\nexport const syncA2ASecretHandler = defineEventHandler(\n async (event: H3Event) => {\n const ctx = await getOrgContext(event);\n if (!ctx.orgId) {\n throw createError({\n statusCode: 400,\n message: \"No active organization\",\n });\n }\n if (ctx.role !== \"owner\" && ctx.role !== \"admin\") {\n throw createError({\n statusCode: 403,\n message: \"Only owners and admins can sync the A2A secret\",\n });\n }\n\n const body = await readBody(event).catch(() => null);\n const overrideSignSecret =\n typeof body?.signSecret === \"string\" && body.signSecret.trim()\n ? body.signSecret.trim()\n : null;\n\n const e = await exec();\n const orgRes = await e.execute({\n sql: `SELECT a2a_secret, allowed_domain FROM organizations WHERE id = ? LIMIT 1`,\n args: [ctx.orgId],\n });\n if (orgRes.rows.length === 0) {\n throw createError({\n statusCode: 404,\n message: \"Organization not found\",\n });\n }\n const orgRow = orgRes.rows[0] as any;\n const secret = String(orgRow.a2a_secret ?? \"\") || null;\n const orgDomain = String(orgRow.allowed_domain ?? \"\") || null;\n\n if (!secret) {\n throw createError({\n statusCode: 400,\n message: \"Org has no A2A secret. Generate one first before syncing.\",\n });\n }\n if (!orgDomain) {\n throw createError({\n statusCode: 400,\n message:\n \"Org has no allowed domain set. Set the email domain first so connected apps can identify which org to update.\",\n });\n }\n\n const signSecret = overrideSignSecret || secret;\n\n const { discoverAgents } = await import(\"../server/agent-discovery.js\");\n const { signA2AToken } = await import(\"../a2a/client.js\");\n\n const agents = await discoverAgents();\n\n const results: Array<{\n id: string;\n name: string;\n url: string;\n ok: boolean;\n status?: number;\n error?: string;\n }> = [];\n\n await Promise.all(\n agents.map(async (agent) => {\n try {\n const token = await signA2AToken(ctx.email, orgDomain, signSecret);\n\n const target = `${agent.url.replace(/\\/$/, \"\")}/_agent-native/org/a2a-secret/receive`;\n const res = await fetch(target, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify({ secret, orgDomain }),\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n results.push({\n id: agent.id,\n name: agent.name,\n url: agent.url,\n ok: false,\n status: res.status,\n error: text || res.statusText,\n });\n return;\n }\n results.push({\n id: agent.id,\n name: agent.name,\n url: agent.url,\n ok: true,\n status: res.status,\n });\n } catch (err) {\n results.push({\n id: agent.id,\n name: agent.name,\n url: agent.url,\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }),\n );\n\n const succeeded = results.filter((r) => r.ok).length;\n return {\n total: results.length,\n succeeded,\n failed: results.length - succeeded,\n results,\n };\n },\n);\n\n/**\n * POST /_agent-native/org/a2a-secret/receive — accept a secret push from a\n * connected agent-native app. Auth-exempt at the route guard; we verify a\n * JWT signed by the calling app using OUR copy of the org's a2a_secret. If\n * verification succeeds the calling app is a trusted peer and we overwrite\n * our local org's secret with the supplied value.\n *\n * Body: { secret: string, orgDomain: string }\n *\n * Header: Authorization: Bearer <JWT signed with the existing shared\n * a2a_secret, with `org_domain` matching the body's orgDomain>.\n */\nexport const receiveA2ASecretHandler = defineEventHandler(\n async (event: H3Event) => {\n const { getRequestHeader } = await import(\"h3\");\n const jose = await import(\"jose\");\n\n const authHeader = getRequestHeader(event, \"authorization\");\n if (!authHeader || !authHeader.startsWith(\"Bearer \")) {\n throw createError({\n statusCode: 401,\n message: \"Bearer token required\",\n });\n }\n const token = authHeader.slice(\"Bearer \".length);\n\n const body = await readBody(event);\n const newSecret =\n typeof body?.secret === \"string\" ? body.secret.trim() : \"\";\n const orgDomain =\n typeof body?.orgDomain === \"string\"\n ? body.orgDomain.trim().toLowerCase()\n : \"\";\n if (!newSecret || !orgDomain) {\n throw createError({\n statusCode: 400,\n message: \"secret and orgDomain are required\",\n });\n }\n\n // Peek at JWT (unverified) to confirm it claims the same domain we're\n // updating. Verification still happens below with the trusted secret.\n let claimedDomain: string | undefined;\n try {\n const unverified = jose.decodeJwt(token);\n claimedDomain =\n (unverified.org_domain as string | undefined) || undefined;\n } catch {\n throw createError({\n statusCode: 401,\n message: \"Malformed JWT\",\n });\n }\n if (\n !claimedDomain ||\n claimedDomain.toLowerCase() !== orgDomain.toLowerCase()\n ) {\n throw createError({\n statusCode: 401,\n message: \"JWT org_domain does not match request body\",\n });\n }\n\n // Look up our local org by the domain and grab the existing secret.\n const e = await exec();\n const orgRes = await e.execute({\n sql: `SELECT id, a2a_secret FROM organizations WHERE LOWER(allowed_domain) = ? LIMIT 1`,\n args: [orgDomain],\n });\n if (orgRes.rows.length === 0) {\n throw createError({\n statusCode: 404,\n message: \"No local org matches that domain\",\n });\n }\n const row = orgRes.rows[0] as any;\n const localOrgId = String(row.id);\n const existingSecret = String(row.a2a_secret ?? \"\") || null;\n\n if (!existingSecret) {\n // Bootstrap requires an existing shared secret to verify the caller.\n // If we have nothing on file, we can't verify trust — refuse.\n throw createError({\n statusCode: 401,\n message:\n \"Local org has no A2A secret yet — cannot verify caller. Set the secret manually for the first time.\",\n });\n }\n\n // Verify the JWT using OUR existing secret. If the caller is a trusted\n // peer they signed with the same secret and verification succeeds.\n try {\n await jose.jwtVerify(token, new TextEncoder().encode(existingSecret));\n } catch {\n throw createError({\n statusCode: 401,\n message: \"Invalid or expired JWT signature\",\n });\n }\n\n // Trusted — apply the new secret.\n await e.execute({\n sql: `UPDATE organizations SET a2a_secret = ? WHERE id = ?`,\n args: [newSecret, localOrgId],\n });\n\n return { ok: true, orgId: localOrgId };\n },\n);\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"call-agent.d.ts","sourceRoot":"","sources":["../../src/scripts/call-agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"call-agent.d.ts","sourceRoot":"","sources":["../../src/scripts/call-agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAqDrE,eAAO,MAAM,IAAI,EAAE,UAqBlB,CAAC;AAEF,wBAAsB,GAAG,CACvB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,CAAC,EAAE,gBAAgB,EAC1B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAoMjB;AA+CD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CASzE"}
|
|
@@ -1,7 +1,38 @@
|
|
|
1
1
|
import { findAgent, discoverAgents } from "../server/agent-discovery.js";
|
|
2
|
-
import { A2AClient, callAgent, signA2AToken } from "../a2a/client.js";
|
|
3
|
-
import { getRequestUserEmail, getRequestOrgId, isIntegrationCallerRequest, } from "../server/request-context.js";
|
|
2
|
+
import { A2AClient, A2ATaskTimeoutError, callAgent, signA2AToken, } from "../a2a/client.js";
|
|
3
|
+
import { getRequestUserEmail, getRequestOrgId, isIntegrationCallerRequest, getIntegrationRequestContext, } from "../server/request-context.js";
|
|
4
4
|
import { getOrgDomain, getOrgA2ASecret } from "../org/context.js";
|
|
5
|
+
const DEFAULT_SERVERLESS_INTEGRATION_A2A_TIMEOUT_MS = 18_000;
|
|
6
|
+
const NETLIFY_INTEGRATION_A2A_TIMEOUT_MS = 50_000;
|
|
7
|
+
function parseTimeoutMs(value) {
|
|
8
|
+
if (!value)
|
|
9
|
+
return undefined;
|
|
10
|
+
const parsed = Number(value);
|
|
11
|
+
if (!Number.isFinite(parsed) || parsed <= 0)
|
|
12
|
+
return undefined;
|
|
13
|
+
return Math.floor(parsed);
|
|
14
|
+
}
|
|
15
|
+
function isServerlessHost() {
|
|
16
|
+
// Detection mirrors db/migrations.ts:297-301. On Cloudflare Workers/Pages,
|
|
17
|
+
// `process.env` is shimmed and CF_PAGES isn't reliably populated at runtime —
|
|
18
|
+
// the canonical signal is the `__cf_env` global injected by workerd.
|
|
19
|
+
return (!!process.env.NETLIFY ||
|
|
20
|
+
!!process.env.AWS_LAMBDA_FUNCTION_NAME ||
|
|
21
|
+
!!process.env.VERCEL ||
|
|
22
|
+
"__cf_env" in globalThis);
|
|
23
|
+
}
|
|
24
|
+
function getIntegrationCallTimeoutMs() {
|
|
25
|
+
if (!isServerlessHost() || !isIntegrationCallerRequest())
|
|
26
|
+
return undefined;
|
|
27
|
+
const configured = parseTimeoutMs(process.env.AGENT_NATIVE_INTEGRATION_A2A_TIMEOUT_MS);
|
|
28
|
+
if (configured !== undefined)
|
|
29
|
+
return configured;
|
|
30
|
+
// Netlify's current synchronous function budget is 60s, but leave room for
|
|
31
|
+
// cold start, polling overhead, and the caller's final platform response.
|
|
32
|
+
if (process.env.NETLIFY)
|
|
33
|
+
return NETLIFY_INTEGRATION_A2A_TIMEOUT_MS;
|
|
34
|
+
return DEFAULT_SERVERLESS_INTEGRATION_A2A_TIMEOUT_MS;
|
|
35
|
+
}
|
|
5
36
|
export const tool = {
|
|
6
37
|
description: "Call a DIFFERENT, separately-deployed agent app to ask a question or delegate a task. This is strictly for cross-app A2A communication — for example, asking the mail agent to send an email while you are the calendar agent. NEVER use this to call your own app or perform actions you can do with your own tools. Using call-agent on yourself will fail and waste time. " +
|
|
7
38
|
"IMPORTANT — handling the response: " +
|
|
@@ -119,33 +150,19 @@ export async function run(args, context, selfAppId) {
|
|
|
119
150
|
// response support, so message/stream returns a single JSON-RPC error
|
|
120
151
|
// body in a 200 response that our SSE parser silently consumes — the
|
|
121
152
|
// `for await` loop yields nothing AND keeps the connection open until
|
|
122
|
-
// the function timeout, eating the
|
|
123
|
-
// the sync fallback, Lambda is dead and the second fetch
|
|
124
|
-
// as "fetch failed". Async+poll has its own short fetches
|
|
125
|
-
// own budgets, so it works reliably across hosts. The
|
|
126
|
-
// we lose progressive in-UI text streaming for cross-app
|
|
127
|
-
// but the receiving agent's full response still surfaces via
|
|
128
|
-
// tool_result event below.
|
|
153
|
+
// the function timeout, eating the current serverless budget. By the
|
|
154
|
+
// time we get to the sync fallback, Lambda is dead and the second fetch
|
|
155
|
+
// errors out as "fetch failed". Async+poll has its own short fetches
|
|
156
|
+
// with their own budgets, so it works reliably across hosts. The
|
|
157
|
+
// trade-off is we lose progressive in-UI text streaming for cross-app
|
|
158
|
+
// A2A calls, but the receiving agent's full response still surfaces via
|
|
159
|
+
// the tool_result event below.
|
|
129
160
|
try {
|
|
130
|
-
// Apply
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
//
|
|
134
|
-
|
|
135
|
-
// bail before the lambda dies. On long-running hosts (local Node
|
|
136
|
-
// dev, self-hosted Node, Docker containers) the budget is
|
|
137
|
-
// effectively infinite, so the cap would just truncate
|
|
138
|
-
// slow-but-valid answers.
|
|
139
|
-
//
|
|
140
|
-
// Detection mirrors db/migrations.ts:297-301. On Cloudflare
|
|
141
|
-
// Workers/Pages, `process.env` is shimmed and CF_PAGES isn't
|
|
142
|
-
// reliably populated at runtime — the canonical signal is the
|
|
143
|
-
// `__cf_env` global injected by the workerd runtime.
|
|
144
|
-
const onServerlessHost = !!process.env.NETLIFY ||
|
|
145
|
-
!!process.env.AWS_LAMBDA_FUNCTION_NAME ||
|
|
146
|
-
!!process.env.VERCEL ||
|
|
147
|
-
"__cf_env" in globalThis;
|
|
148
|
-
const callTimeoutMs = onServerlessHost && isIntegrationCallerRequest() ? 18000 : undefined;
|
|
161
|
+
// Apply a polling cap ONLY for integration-platform callers on
|
|
162
|
+
// serverless hosts. Normal chat, local Node, self-hosted Node, and
|
|
163
|
+
// Docker can wait for slow-but-valid answers; integration processors
|
|
164
|
+
// still need to finish before their current function execution dies.
|
|
165
|
+
const callTimeoutMs = getIntegrationCallTimeoutMs();
|
|
149
166
|
responseText = await callAgent(agent.url, messageWithHint, {
|
|
150
167
|
userEmail: callerEmail,
|
|
151
168
|
orgDomain: callerOrgDomain,
|
|
@@ -162,8 +179,21 @@ export async function run(args, context, selfAppId) {
|
|
|
162
179
|
emitNewText(responseText);
|
|
163
180
|
}
|
|
164
181
|
catch (pollErr) {
|
|
165
|
-
|
|
166
|
-
|
|
182
|
+
if (pollErr instanceof A2ATaskTimeoutError) {
|
|
183
|
+
const queued = await enqueueIntegrationContinuationIfPossible(pollErr, agent, callerEmail);
|
|
184
|
+
if (queued) {
|
|
185
|
+
responseText = `The ${agent.name} agent is still working. I will update this thread with the final result when it finishes.`;
|
|
186
|
+
emitNewText(responseText);
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
const reason = pollErr?.message ?? "unknown error";
|
|
190
|
+
responseText = `The ${agent.name} agent is taking longer than expected and didn't reply in time. (${reason})`;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
const reason = pollErr?.message ?? "unknown error";
|
|
195
|
+
responseText = `The ${agent.name} agent is taking longer than expected and didn't reply in time. (${reason})`;
|
|
196
|
+
}
|
|
167
197
|
}
|
|
168
198
|
context.send({
|
|
169
199
|
type: "agent_call",
|
|
@@ -205,6 +235,37 @@ export async function run(args, context, selfAppId) {
|
|
|
205
235
|
return `Error calling ${agent.name}: ${msg}`;
|
|
206
236
|
}
|
|
207
237
|
}
|
|
238
|
+
async function enqueueIntegrationContinuationIfPossible(error, agent, ownerEmail) {
|
|
239
|
+
const integration = getIntegrationRequestContext();
|
|
240
|
+
if (!integration || !ownerEmail)
|
|
241
|
+
return false;
|
|
242
|
+
try {
|
|
243
|
+
const [{ insertA2AContinuation }, { dispatchA2AContinuation }] = await Promise.all([
|
|
244
|
+
import("../integrations/a2a-continuations-store.js"),
|
|
245
|
+
import("../integrations/a2a-continuation-processor.js"),
|
|
246
|
+
]);
|
|
247
|
+
const continuation = await insertA2AContinuation({
|
|
248
|
+
integrationTaskId: integration.taskId,
|
|
249
|
+
platform: integration.incoming.platform,
|
|
250
|
+
externalThreadId: integration.incoming.externalThreadId,
|
|
251
|
+
incoming: integration.incoming,
|
|
252
|
+
placeholderRef: integration.placeholderRef,
|
|
253
|
+
ownerEmail,
|
|
254
|
+
orgId: getRequestOrgId() ?? null,
|
|
255
|
+
agentName: agent.name,
|
|
256
|
+
agentUrl: agent.url,
|
|
257
|
+
a2aTaskId: error.taskId,
|
|
258
|
+
});
|
|
259
|
+
await dispatchA2AContinuation(continuation.id).catch((err) => {
|
|
260
|
+
console.error(`[call-agent] Failed to dispatch A2A continuation ${continuation.id}:`, err);
|
|
261
|
+
});
|
|
262
|
+
return true;
|
|
263
|
+
}
|
|
264
|
+
catch (err) {
|
|
265
|
+
console.error("[call-agent] Failed to enqueue A2A continuation:", err);
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
208
269
|
// Expand bare leading-slash paths (e.g. "/deck/abc") into fully-qualified URLs
|
|
209
270
|
// rooted at the receiving agent's host. The receiver doesn't always know it's
|
|
210
271
|
// being called cross-app, so it may emit relative paths that resolve against
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"call-agent.js","sourceRoot":"","sources":["../../src/scripts/call-agent.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ActionTool } from \"../agent/types.js\";\nimport type { ActionRunContext } from \"../agent/production-agent.js\";\nimport { findAgent, discoverAgents } from \"../server/agent-discovery.js\";\nimport { A2AClient, callAgent, signA2AToken } from \"../a2a/client.js\";\nimport {\n getRequestUserEmail,\n getRequestOrgId,\n isIntegrationCallerRequest,\n} from \"../server/request-context.js\";\nimport { getOrgDomain, getOrgA2ASecret } from \"../org/context.js\";\n\nexport const tool: ActionTool = {\n description:\n \"Call a DIFFERENT, separately-deployed agent app to ask a question or delegate a task. This is strictly for cross-app A2A communication — for example, asking the mail agent to send an email while you are the calendar agent. NEVER use this to call your own app or perform actions you can do with your own tools. Using call-agent on yourself will fail and waste time. \" +\n \"IMPORTANT — handling the response: \" +\n \"(a) If it contains a URL or ID, copy it VERBATIM into your reply. Do not 'correct' or pluralize the path (e.g. /deck/ → /decks/), normalize casing, or change the slug — any edit breaks the link. \" +\n '(b) If it does NOT contain a URL/ID and the user asked for one, say so explicitly (e.g. \"the agent created the deck but didn\\'t return a link — open the app directly to view it\"). NEVER invent a URL, slug, or path — guessing produces broken links that look real.',\n parameters: {\n type: \"object\",\n properties: {\n agent: {\n type: \"string\",\n description:\n \"Name or URL of a DIFFERENT deployed agent app (e.g. 'mail', 'calendar', 'analytics'). Must not be the current app's own name.\",\n },\n message: {\n type: \"string\",\n description: \"The message/question to send to the other agent\",\n },\n },\n required: [\"agent\", \"message\"],\n },\n};\n\nexport async function run(\n args: Record<string, string>,\n context?: ActionRunContext,\n selfAppId?: string,\n): Promise<string> {\n const { agent: agentIdOrName, message } = args;\n\n if (!agentIdOrName) return \"Error: --agent is required\";\n if (!message) return \"Error: --message is required\";\n\n // Prevent self-calls — the agent must use its own registered tools instead\n if (selfAppId && agentIdOrName.toLowerCase() === selfAppId.toLowerCase()) {\n return `Error: You cannot use call-agent to call yourself (${selfAppId}). Use your own registered actions/tools instead. call-agent is only for communicating with OTHER separately-deployed apps.`;\n }\n\n const agent = await findAgent(agentIdOrName, selfAppId);\n if (!agent) {\n const available = (await discoverAgents(selfAppId))\n .map((a) => a.name)\n .join(\", \");\n return `Error: Agent \"${agentIdOrName}\" not found. Available agents: ${available || \"(none)\"}`;\n }\n\n // Append a small cross-app hint to the outgoing message so the receiving\n // agent (which may be on an older deploy without the receiver-side hint\n // in handlers.ts) still emits fully-qualified URLs. This is belt-and-\n // suspenders with the receiver hint — but it works against any current\n // deployment, no redeploy required.\n const messageWithHint =\n `${message}\\n\\n` +\n `[Note: this request comes from another app via A2A. The caller cannot see your local UI, deck list, or navigation — only the literal text you put in your reply. ` +\n `If you create or reference a deck/document/dashboard, include its FULLY-QUALIFIED URL (e.g. ${agent.url}/deck/<id>) in your reply, not a relative path. ` +\n `Use only IDs returned by your own actions — never invent slugs or hosts.]`;\n\n try {\n // If we have a send context, use streaming so the UI shows progressive text\n if (context?.send) {\n const callerEmail = getRequestUserEmail();\n\n // Build metadata with identity\n const a2aMetadata: Record<string, unknown> = {};\n if (callerEmail) a2aMetadata.userEmail = callerEmail;\n\n // Include org domain for cross-app org resolution\n let callerOrgDomain: string | undefined;\n let callerOrgSecret: string | undefined;\n const orgId = getRequestOrgId();\n if (orgId) {\n try {\n const domain = await getOrgDomain(orgId);\n if (domain) {\n callerOrgDomain = domain;\n a2aMetadata.orgDomain = domain;\n }\n } catch {}\n try {\n const secret = await getOrgA2ASecret(orgId);\n if (secret) callerOrgSecret = secret;\n } catch {}\n }\n\n // Sign JWT with identity + org domain for the streaming client\n let apiKey: string | undefined;\n if (callerEmail && (callerOrgSecret || process.env.A2A_SECRET)) {\n try {\n apiKey = await signA2AToken(\n callerEmail,\n callerOrgDomain,\n callerOrgSecret,\n );\n } catch {}\n }\n\n const client = new A2AClient(agent.url, apiKey);\n\n if (process.env.NODE_ENV === \"production\" && callerEmail) {\n try {\n const { listOAuthAccountsByOwner } =\n await import(\"../oauth-tokens/store.js\");\n const accounts = await listOAuthAccountsByOwner(\n \"google\",\n callerEmail,\n );\n const tokens = accounts[0]?.tokens;\n if (tokens?.access_token) {\n a2aMetadata.googleToken = tokens.access_token;\n }\n } catch {}\n }\n\n let responseText = \"\";\n let lastSentLength = 0;\n\n context.send({\n type: \"agent_call\",\n agent: agent.name,\n status: \"start\",\n });\n\n const emitNewText = (newText: string) => {\n if (newText.length > lastSentLength) {\n context.send!({\n type: \"agent_call_text\",\n agent: agent.name,\n text: newText.slice(lastSentLength),\n });\n lastSentLength = newText.length;\n }\n responseText = newText;\n };\n\n // Skip the SSE streaming attempt and go straight to async + poll.\n // Why: on Netlify (Lambda), the receiving server has no streaming\n // response support, so message/stream returns a single JSON-RPC error\n // body in a 200 response that our SSE parser silently consumes — the\n // `for await` loop yields nothing AND keeps the connection open until\n // the function timeout, eating the 26s budget. By the time we get to\n // the sync fallback, Lambda is dead and the second fetch errors out\n // as \"fetch failed\". Async+poll has its own short fetches with their\n // own budgets, so it works reliably across hosts. The trade-off is\n // we lose progressive in-UI text streaming for cross-app A2A calls,\n // but the receiving agent's full response still surfaces via the\n // tool_result event below.\n try {\n // Apply the 18s polling cap ONLY when we're on a serverless host\n // (Netlify / Vercel / AWS Lambda / Cloudflare Workers) AND the\n // call is from an integration-platform path. On those hosts the\n // function timeout (~26s on Netlify Pro) plus the platform's\n // deliver-by deadline are the binding budget, so dispatch must\n // bail before the lambda dies. On long-running hosts (local Node\n // dev, self-hosted Node, Docker containers) the budget is\n // effectively infinite, so the cap would just truncate\n // slow-but-valid answers.\n //\n // Detection mirrors db/migrations.ts:297-301. On Cloudflare\n // Workers/Pages, `process.env` is shimmed and CF_PAGES isn't\n // reliably populated at runtime — the canonical signal is the\n // `__cf_env` global injected by the workerd runtime.\n const onServerlessHost =\n !!process.env.NETLIFY ||\n !!process.env.AWS_LAMBDA_FUNCTION_NAME ||\n !!process.env.VERCEL ||\n \"__cf_env\" in globalThis;\n const callTimeoutMs =\n onServerlessHost && isIntegrationCallerRequest() ? 18000 : undefined;\n responseText = await callAgent(agent.url, messageWithHint, {\n userEmail: callerEmail,\n orgDomain: callerOrgDomain,\n orgSecret: callerOrgSecret,\n ...(callTimeoutMs ? { timeoutMs: callTimeoutMs } : {}),\n });\n // Some agents reply with relative paths (e.g. slides emits\n // \"/deck/abc\"). Those resolve against the caller's host, not the\n // receiver's, so they're broken for the user. Expand any leading-slash\n // URL into a fully-qualified one rooted at the receiving agent's host.\n responseText = expandRelativeUrls(responseText, agent.url);\n // Mirror the response into the streaming UI so the user sees it.\n if (responseText) emitNewText(responseText);\n } catch (pollErr: any) {\n const reason = pollErr?.message ?? \"unknown error\";\n responseText = `The ${agent.name} agent is taking longer than expected and didn't reply in time. (${reason})`;\n }\n\n context.send({\n type: \"agent_call\",\n agent: agent.name,\n status: \"done\",\n });\n\n return responseText || \"(empty response)\";\n }\n\n // No context — use the async + poll call so we don't get cut off at the\n // serverless gateway's ~30s timeout. callAgent defaults to async:true.\n const email = getRequestUserEmail();\n let domain: string | undefined;\n let orgSecret: string | undefined;\n const currentOrgId = getRequestOrgId();\n if (currentOrgId) {\n try {\n domain = (await getOrgDomain(currentOrgId)) ?? undefined;\n } catch {}\n try {\n orgSecret = (await getOrgA2ASecret(currentOrgId)) ?? undefined;\n } catch {}\n }\n const response = await callAgent(agent.url, messageWithHint, {\n userEmail: email,\n orgDomain: domain,\n orgSecret,\n });\n return expandRelativeUrls(response, agent.url) || \"(empty response)\";\n } catch (err: any) {\n const msg = err?.message ?? String(err);\n // Friendlier message for the common timeout case so the calling agent can\n // decide whether to give up or retry.\n if (/timeout|did not complete|Inactivity|504/i.test(msg)) {\n return `The ${agent.name} agent is taking longer than expected. Please try again, ask a simpler question, or open the ${agent.name} app directly.`;\n }\n return `Error calling ${agent.name}: ${msg}`;\n }\n}\n\n// Expand bare leading-slash paths (e.g. \"/deck/abc\") into fully-qualified URLs\n// rooted at the receiving agent's host. The receiver doesn't always know it's\n// being called cross-app, so it may emit relative paths that resolve against\n// the caller's host (broken). Match a path that starts at a word boundary,\n// begins with `/`, and has at least one path segment after that. Skip if it\n// already looks like a fully-qualified URL.\nexport function expandRelativeUrls(text: string, agentUrl: string): string {\n if (!text || !agentUrl) return text;\n const base = agentUrl.replace(/\\/$/, \"\");\n // Path must start at boundary (start, whitespace, or punctuation that isn't\n // ':' — to avoid mangling `https://example.com/foo` or markdown link bodies).\n return text.replace(\n /(^|[\\s(\\[<\"'`])(\\/[a-z0-9_-][a-z0-9_/?&=%#.,:-]*)/gi,\n (_match, lead, path) => `${lead}${base}${path}`,\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"call-agent.js","sourceRoot":"","sources":["../../src/scripts/call-agent.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ActionTool } from \"../agent/types.js\";\nimport type { ActionRunContext } from \"../agent/production-agent.js\";\nimport { findAgent, discoverAgents } from \"../server/agent-discovery.js\";\nimport {\n A2AClient,\n A2ATaskTimeoutError,\n callAgent,\n signA2AToken,\n} from \"../a2a/client.js\";\nimport {\n getRequestUserEmail,\n getRequestOrgId,\n isIntegrationCallerRequest,\n getIntegrationRequestContext,\n} from \"../server/request-context.js\";\nimport { getOrgDomain, getOrgA2ASecret } from \"../org/context.js\";\n\nconst DEFAULT_SERVERLESS_INTEGRATION_A2A_TIMEOUT_MS = 18_000;\nconst NETLIFY_INTEGRATION_A2A_TIMEOUT_MS = 50_000;\n\nfunction parseTimeoutMs(value: string | undefined): number | undefined {\n if (!value) return undefined;\n const parsed = Number(value);\n if (!Number.isFinite(parsed) || parsed <= 0) return undefined;\n return Math.floor(parsed);\n}\n\nfunction isServerlessHost(): boolean {\n // Detection mirrors db/migrations.ts:297-301. On Cloudflare Workers/Pages,\n // `process.env` is shimmed and CF_PAGES isn't reliably populated at runtime —\n // the canonical signal is the `__cf_env` global injected by workerd.\n return (\n !!process.env.NETLIFY ||\n !!process.env.AWS_LAMBDA_FUNCTION_NAME ||\n !!process.env.VERCEL ||\n \"__cf_env\" in globalThis\n );\n}\n\nfunction getIntegrationCallTimeoutMs(): number | undefined {\n if (!isServerlessHost() || !isIntegrationCallerRequest()) return undefined;\n\n const configured = parseTimeoutMs(\n process.env.AGENT_NATIVE_INTEGRATION_A2A_TIMEOUT_MS,\n );\n if (configured !== undefined) return configured;\n\n // Netlify's current synchronous function budget is 60s, but leave room for\n // cold start, polling overhead, and the caller's final platform response.\n if (process.env.NETLIFY) return NETLIFY_INTEGRATION_A2A_TIMEOUT_MS;\n\n return DEFAULT_SERVERLESS_INTEGRATION_A2A_TIMEOUT_MS;\n}\n\nexport const tool: ActionTool = {\n description:\n \"Call a DIFFERENT, separately-deployed agent app to ask a question or delegate a task. This is strictly for cross-app A2A communication — for example, asking the mail agent to send an email while you are the calendar agent. NEVER use this to call your own app or perform actions you can do with your own tools. Using call-agent on yourself will fail and waste time. \" +\n \"IMPORTANT — handling the response: \" +\n \"(a) If it contains a URL or ID, copy it VERBATIM into your reply. Do not 'correct' or pluralize the path (e.g. /deck/ → /decks/), normalize casing, or change the slug — any edit breaks the link. \" +\n '(b) If it does NOT contain a URL/ID and the user asked for one, say so explicitly (e.g. \"the agent created the deck but didn\\'t return a link — open the app directly to view it\"). NEVER invent a URL, slug, or path — guessing produces broken links that look real.',\n parameters: {\n type: \"object\",\n properties: {\n agent: {\n type: \"string\",\n description:\n \"Name or URL of a DIFFERENT deployed agent app (e.g. 'mail', 'calendar', 'analytics'). Must not be the current app's own name.\",\n },\n message: {\n type: \"string\",\n description: \"The message/question to send to the other agent\",\n },\n },\n required: [\"agent\", \"message\"],\n },\n};\n\nexport async function run(\n args: Record<string, string>,\n context?: ActionRunContext,\n selfAppId?: string,\n): Promise<string> {\n const { agent: agentIdOrName, message } = args;\n\n if (!agentIdOrName) return \"Error: --agent is required\";\n if (!message) return \"Error: --message is required\";\n\n // Prevent self-calls — the agent must use its own registered tools instead\n if (selfAppId && agentIdOrName.toLowerCase() === selfAppId.toLowerCase()) {\n return `Error: You cannot use call-agent to call yourself (${selfAppId}). Use your own registered actions/tools instead. call-agent is only for communicating with OTHER separately-deployed apps.`;\n }\n\n const agent = await findAgent(agentIdOrName, selfAppId);\n if (!agent) {\n const available = (await discoverAgents(selfAppId))\n .map((a) => a.name)\n .join(\", \");\n return `Error: Agent \"${agentIdOrName}\" not found. Available agents: ${available || \"(none)\"}`;\n }\n\n // Append a small cross-app hint to the outgoing message so the receiving\n // agent (which may be on an older deploy without the receiver-side hint\n // in handlers.ts) still emits fully-qualified URLs. This is belt-and-\n // suspenders with the receiver hint — but it works against any current\n // deployment, no redeploy required.\n const messageWithHint =\n `${message}\\n\\n` +\n `[Note: this request comes from another app via A2A. The caller cannot see your local UI, deck list, or navigation — only the literal text you put in your reply. ` +\n `If you create or reference a deck/document/dashboard, include its FULLY-QUALIFIED URL (e.g. ${agent.url}/deck/<id>) in your reply, not a relative path. ` +\n `Use only IDs returned by your own actions — never invent slugs or hosts.]`;\n\n try {\n // If we have a send context, use streaming so the UI shows progressive text\n if (context?.send) {\n const callerEmail = getRequestUserEmail();\n\n // Build metadata with identity\n const a2aMetadata: Record<string, unknown> = {};\n if (callerEmail) a2aMetadata.userEmail = callerEmail;\n\n // Include org domain for cross-app org resolution\n let callerOrgDomain: string | undefined;\n let callerOrgSecret: string | undefined;\n const orgId = getRequestOrgId();\n if (orgId) {\n try {\n const domain = await getOrgDomain(orgId);\n if (domain) {\n callerOrgDomain = domain;\n a2aMetadata.orgDomain = domain;\n }\n } catch {}\n try {\n const secret = await getOrgA2ASecret(orgId);\n if (secret) callerOrgSecret = secret;\n } catch {}\n }\n\n // Sign JWT with identity + org domain for the streaming client\n let apiKey: string | undefined;\n if (callerEmail && (callerOrgSecret || process.env.A2A_SECRET)) {\n try {\n apiKey = await signA2AToken(\n callerEmail,\n callerOrgDomain,\n callerOrgSecret,\n );\n } catch {}\n }\n\n const client = new A2AClient(agent.url, apiKey);\n\n if (process.env.NODE_ENV === \"production\" && callerEmail) {\n try {\n const { listOAuthAccountsByOwner } =\n await import(\"../oauth-tokens/store.js\");\n const accounts = await listOAuthAccountsByOwner(\n \"google\",\n callerEmail,\n );\n const tokens = accounts[0]?.tokens;\n if (tokens?.access_token) {\n a2aMetadata.googleToken = tokens.access_token;\n }\n } catch {}\n }\n\n let responseText = \"\";\n let lastSentLength = 0;\n\n context.send({\n type: \"agent_call\",\n agent: agent.name,\n status: \"start\",\n });\n\n const emitNewText = (newText: string) => {\n if (newText.length > lastSentLength) {\n context.send!({\n type: \"agent_call_text\",\n agent: agent.name,\n text: newText.slice(lastSentLength),\n });\n lastSentLength = newText.length;\n }\n responseText = newText;\n };\n\n // Skip the SSE streaming attempt and go straight to async + poll.\n // Why: on Netlify (Lambda), the receiving server has no streaming\n // response support, so message/stream returns a single JSON-RPC error\n // body in a 200 response that our SSE parser silently consumes — the\n // `for await` loop yields nothing AND keeps the connection open until\n // the function timeout, eating the current serverless budget. By the\n // time we get to the sync fallback, Lambda is dead and the second fetch\n // errors out as \"fetch failed\". Async+poll has its own short fetches\n // with their own budgets, so it works reliably across hosts. The\n // trade-off is we lose progressive in-UI text streaming for cross-app\n // A2A calls, but the receiving agent's full response still surfaces via\n // the tool_result event below.\n try {\n // Apply a polling cap ONLY for integration-platform callers on\n // serverless hosts. Normal chat, local Node, self-hosted Node, and\n // Docker can wait for slow-but-valid answers; integration processors\n // still need to finish before their current function execution dies.\n const callTimeoutMs = getIntegrationCallTimeoutMs();\n responseText = await callAgent(agent.url, messageWithHint, {\n userEmail: callerEmail,\n orgDomain: callerOrgDomain,\n orgSecret: callerOrgSecret,\n ...(callTimeoutMs ? { timeoutMs: callTimeoutMs } : {}),\n });\n // Some agents reply with relative paths (e.g. slides emits\n // \"/deck/abc\"). Those resolve against the caller's host, not the\n // receiver's, so they're broken for the user. Expand any leading-slash\n // URL into a fully-qualified one rooted at the receiving agent's host.\n responseText = expandRelativeUrls(responseText, agent.url);\n // Mirror the response into the streaming UI so the user sees it.\n if (responseText) emitNewText(responseText);\n } catch (pollErr: any) {\n if (pollErr instanceof A2ATaskTimeoutError) {\n const queued = await enqueueIntegrationContinuationIfPossible(\n pollErr,\n agent,\n callerEmail,\n );\n if (queued) {\n responseText = `The ${agent.name} agent is still working. I will update this thread with the final result when it finishes.`;\n emitNewText(responseText);\n } else {\n const reason = pollErr?.message ?? \"unknown error\";\n responseText = `The ${agent.name} agent is taking longer than expected and didn't reply in time. (${reason})`;\n }\n } else {\n const reason = pollErr?.message ?? \"unknown error\";\n responseText = `The ${agent.name} agent is taking longer than expected and didn't reply in time. (${reason})`;\n }\n }\n\n context.send({\n type: \"agent_call\",\n agent: agent.name,\n status: \"done\",\n });\n\n return responseText || \"(empty response)\";\n }\n\n // No context — use the async + poll call so we don't get cut off at the\n // serverless gateway's ~30s timeout. callAgent defaults to async:true.\n const email = getRequestUserEmail();\n let domain: string | undefined;\n let orgSecret: string | undefined;\n const currentOrgId = getRequestOrgId();\n if (currentOrgId) {\n try {\n domain = (await getOrgDomain(currentOrgId)) ?? undefined;\n } catch {}\n try {\n orgSecret = (await getOrgA2ASecret(currentOrgId)) ?? undefined;\n } catch {}\n }\n const response = await callAgent(agent.url, messageWithHint, {\n userEmail: email,\n orgDomain: domain,\n orgSecret,\n });\n return expandRelativeUrls(response, agent.url) || \"(empty response)\";\n } catch (err: any) {\n const msg = err?.message ?? String(err);\n // Friendlier message for the common timeout case so the calling agent can\n // decide whether to give up or retry.\n if (/timeout|did not complete|Inactivity|504/i.test(msg)) {\n return `The ${agent.name} agent is taking longer than expected. Please try again, ask a simpler question, or open the ${agent.name} app directly.`;\n }\n return `Error calling ${agent.name}: ${msg}`;\n }\n}\n\nasync function enqueueIntegrationContinuationIfPossible(\n error: A2ATaskTimeoutError,\n agent: { name: string; url: string },\n ownerEmail: string | undefined,\n): Promise<boolean> {\n const integration = getIntegrationRequestContext();\n if (!integration || !ownerEmail) return false;\n\n try {\n const [{ insertA2AContinuation }, { dispatchA2AContinuation }] =\n await Promise.all([\n import(\"../integrations/a2a-continuations-store.js\"),\n import(\"../integrations/a2a-continuation-processor.js\"),\n ]);\n const continuation = await insertA2AContinuation({\n integrationTaskId: integration.taskId,\n platform: integration.incoming.platform,\n externalThreadId: integration.incoming.externalThreadId,\n incoming: integration.incoming,\n placeholderRef: integration.placeholderRef,\n ownerEmail,\n orgId: getRequestOrgId() ?? null,\n agentName: agent.name,\n agentUrl: agent.url,\n a2aTaskId: error.taskId,\n });\n await dispatchA2AContinuation(continuation.id).catch((err) => {\n console.error(\n `[call-agent] Failed to dispatch A2A continuation ${continuation.id}:`,\n err,\n );\n });\n return true;\n } catch (err) {\n console.error(\"[call-agent] Failed to enqueue A2A continuation:\", err);\n return false;\n }\n}\n\n// Expand bare leading-slash paths (e.g. \"/deck/abc\") into fully-qualified URLs\n// rooted at the receiving agent's host. The receiver doesn't always know it's\n// being called cross-app, so it may emit relative paths that resolve against\n// the caller's host (broken). Match a path that starts at a word boundary,\n// begins with `/`, and has at least one path segment after that. Skip if it\n// already looks like a fully-qualified URL.\nexport function expandRelativeUrls(text: string, agentUrl: string): string {\n if (!text || !agentUrl) return text;\n const base = agentUrl.replace(/\\/$/, \"\");\n // Path must start at boundary (start, whitespace, or punctuation that isn't\n // ':' — to avoid mangling `https://example.com/foo` or markdown link bodies).\n return text.replace(\n /(^|[\\s(\\[<\"'`])(\\/[a-z0-9_-][a-z0-9_/?&=%#.,:-]*)/gi,\n (_match, lead, path) => `${lead}${base}${path}`,\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-discovery.d.ts","sourceRoot":"","sources":["../../src/server/agent-discovery.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"agent-discovery.d.ts","sourceRoot":"","sources":["../../src/server/agent-discovery.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AA6BD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,eAAe,EAAE,CAUtE;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,eAAe,EAAE,CAAC,CAiE5B;AAED;;GAEG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAItC;AAeD;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,EAAE,eAAe,EAOnD,CAAC"}
|