From cfbe5e1c8e7d977371d20efdf699f19fb5ee48ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Tue, 9 Jun 2026 20:19:34 -0400 Subject: [PATCH] Split oversized modules along domain seams Every source file is now under 500 lines. Task prompt construction moves from task-execution-service into task-prompts; goal assignee resolution moves from organization-service into goal-kickoff; the shared command types become a domain-structured shared/commands directory with unchanged import paths; the provider adapter contract types move to provider-adapter-contract, re-exported through provider-adapters so callers keep a single public surface. --- .../src/main/services/goal-kickoff.ts | 47 ++ .../src/main/services/organization-service.ts | 47 +- .../services/provider-adapter-contract.ts | 75 +++ .../src/main/services/provider-adapters.ts | 92 +-- .../main/services/task-execution-service.ts | 175 +----- .../src/main/services/task-prompts.ts | 162 +++++ AgentCompany-New/src/shared/commands.ts | 588 ------------------ AgentCompany-New/src/shared/commands/chat.ts | 41 ++ .../src/shared/commands/collaboration.ts | 94 +++ AgentCompany-New/src/shared/commands/files.ts | 19 + .../src/shared/commands/governance.ts | 104 ++++ AgentCompany-New/src/shared/commands/index.ts | 9 + .../src/shared/commands/onboarding.ts | 36 ++ .../src/shared/commands/organization.ts | 148 +++++ .../src/shared/commands/provider.ts | 81 +++ .../src/shared/commands/skills.ts | 23 + .../src/shared/commands/social.ts | 31 + 17 files changed, 899 insertions(+), 873 deletions(-) create mode 100644 AgentCompany-New/src/main/services/provider-adapter-contract.ts create mode 100644 AgentCompany-New/src/main/services/task-prompts.ts delete mode 100644 AgentCompany-New/src/shared/commands.ts create mode 100644 AgentCompany-New/src/shared/commands/chat.ts create mode 100644 AgentCompany-New/src/shared/commands/collaboration.ts create mode 100644 AgentCompany-New/src/shared/commands/files.ts create mode 100644 AgentCompany-New/src/shared/commands/governance.ts create mode 100644 AgentCompany-New/src/shared/commands/index.ts create mode 100644 AgentCompany-New/src/shared/commands/onboarding.ts create mode 100644 AgentCompany-New/src/shared/commands/organization.ts create mode 100644 AgentCompany-New/src/shared/commands/provider.ts create mode 100644 AgentCompany-New/src/shared/commands/skills.ts create mode 100644 AgentCompany-New/src/shared/commands/social.ts diff --git a/AgentCompany-New/src/main/services/goal-kickoff.ts b/AgentCompany-New/src/main/services/goal-kickoff.ts index 8667be5a..8712622c 100644 --- a/AgentCompany-New/src/main/services/goal-kickoff.ts +++ b/AgentCompany-New/src/main/services/goal-kickoff.ts @@ -2,6 +2,53 @@ import type { DatabaseSync } from "node:sqlite"; import { RISK_LEVEL, TASK_STATUS } from "../../shared/domain"; import { createId } from "../../shared/ids"; +export interface CreatedGoalKickoffInput { + orgId: string; + goalId: string; + title: string; + description: string; + ownerAgentId: string | null; +} + +/** + * Routes a newly created goal to an accountable agent — the chosen owner, + * or the top-level agent (the CEO) — as a kickoff task bound to the org's + * primary workspace. Returns null when the org has no agent yet; the goal + * then waits until one exists. + */ +export function kickoffCreatedGoal(db: DatabaseSync, input: CreatedGoalKickoffInput): string | null { + const assigneeAgentId = input.ownerAgentId ?? topLevelActiveAgentId(db, input.orgId); + if (!assigneeAgentId) return null; + const organization = db.prepare("select name from organizations where id = ?") + .get(input.orgId) as { name: string }; + return createGoalKickoffTask(db, { + orgId: input.orgId, + goalId: input.goalId, + goalTitle: input.title, + goalDescription: input.description, + companyName: organization.name, + assigneeAgentId, + projectId: null, + workspaceId: primaryWorkspaceId(db, input.orgId), + }); +} + +function topLevelActiveAgentId(db: DatabaseSync, orgId: string): string | null { + const row = db.prepare(` + select id from agents + where org_id = ? and manager_agent_id is null and lifecycle = 'active' + order by created_at asc + limit 1 + `).get(orgId) as { id: string } | undefined; + return row?.id ?? null; +} + +function primaryWorkspaceId(db: DatabaseSync, orgId: string): string | null { + const row = db.prepare("select id from workspaces where org_id = ? and is_primary = 1 order by created_at asc limit 1") + .get(orgId) as { id: string } | undefined; + return row?.id ?? null; +} + export interface GoalKickoffTaskInput { orgId: string; goalId: string; diff --git a/AgentCompany-New/src/main/services/organization-service.ts b/AgentCompany-New/src/main/services/organization-service.ts index ed661746..3ea91082 100644 --- a/AgentCompany-New/src/main/services/organization-service.ts +++ b/AgentCompany-New/src/main/services/organization-service.ts @@ -4,7 +4,7 @@ import { PROVIDER_CATALOG } from "../../shared/provider-catalog"; import { createId } from "../../shared/ids"; import type { CreateAgentInput, CreateGoalInput, CreateOrganizationInput, CreateProjectInput, CreateTaskInput, CreateWorkspaceInput, DeleteTaskInput, UpdateAgentInput, UpdateTaskInput } from "../../shared/commands"; import { AuditService } from "./audit-service"; -import { createGoalKickoffTask } from "./goal-kickoff"; +import { kickoffCreatedGoal } from "./goal-kickoff"; import { PolicyService } from "./policy-service"; import { IdentityAccessService } from "./identity-access-service"; import { OrgGovernanceService } from "./org-governance-service"; @@ -402,47 +402,14 @@ export class OrganizationService { action: "created", payload: { title: input.title.trim() }, }); - this.kickoffGoal(input, id); - return id; - } - - /** - * An active goal must reach an accountable agent — the chosen owner, or - * the top-level agent (the CEO) — as a kickoff task the autonomous - * heartbeat starts. Without this, a goal created outside onboarding would - * sit inert forever. - */ - private kickoffGoal(input: CreateGoalInput, goalId: string): void { - const assigneeAgentId = input.ownerAgentId ?? this.topLevelActiveAgentId(input.orgId); - if (!assigneeAgentId) return; - const organization = this.db.prepare("select name from organizations where id = ?") - .get(input.orgId) as { name: string }; - createGoalKickoffTask(this.db, { + kickoffCreatedGoal(this.db, { orgId: input.orgId, - goalId, - goalTitle: input.title, - goalDescription: input.description, - companyName: organization.name, - assigneeAgentId, - projectId: null, - workspaceId: this.primaryWorkspaceId(input.orgId), + goalId: id, + title: input.title, + description: input.description, + ownerAgentId: input.ownerAgentId, }); - } - - private topLevelActiveAgentId(orgId: string): string | null { - const row = this.db.prepare(` - select id from agents - where org_id = ? and manager_agent_id is null and lifecycle = 'active' - order by created_at asc - limit 1 - `).get(orgId) as { id: string } | undefined; - return row?.id ?? null; - } - - private primaryWorkspaceId(orgId: string): string | null { - const row = this.db.prepare("select id from workspaces where org_id = ? and is_primary = 1 order by created_at asc limit 1") - .get(orgId) as { id: string } | undefined; - return row?.id ?? null; + return id; } createProject(input: CreateProjectInput): string { diff --git a/AgentCompany-New/src/main/services/provider-adapter-contract.ts b/AgentCompany-New/src/main/services/provider-adapter-contract.ts new file mode 100644 index 00000000..b7e6e7a7 --- /dev/null +++ b/AgentCompany-New/src/main/services/provider-adapter-contract.ts @@ -0,0 +1,75 @@ +import type { ProviderAuthType } from "../../shared/domain"; +import type { ProviderModelEntry } from "../../shared/provider-models"; +import type { ProviderObservedRateLimitState } from "../../shared/provider-runtime-domain"; +import type { ProviderAuthProfile } from "./provider-auth-profiles"; +import type { ProviderBackgroundCreateResult, ProviderBackgroundRetrieveResult } from "./provider-background"; +import type { ProviderAuthorizeHandler, ProviderRefreshHandler, ProviderRevokeHandler } from "./provider-auth-lifecycle"; +import type { ProviderCancelResult, ProviderStreamResult } from "./provider-streaming"; + +export interface ProviderExecutionInput { + authProfile: ProviderAuthProfile; + model: string; + prompt: string; + instructions: string | null; +} + +export interface ProviderExecutionResult { + text: string; + rawResponseJson: string; + rateLimitState: ProviderObservedRateLimitState | null; +} + +export type ProviderStreamInput = ProviderExecutionInput; +export type ProviderBackgroundCreateInput = ProviderExecutionInput; + +export interface ProviderCancelInput { + authProfile: ProviderAuthProfile; + responseId: string; +} + +export interface ProviderBackgroundRetrieveInput { + authProfile: ProviderAuthProfile; + responseId: string; +} + +export interface ProviderHealthInput { + authProfile: ProviderAuthProfile; + model: string | null; +} + +export interface ProviderHealthResult { + checkedAt: string; + rateLimitState: ProviderObservedRateLimitState | null; +} + +export interface ProviderContext { + authProfile: ProviderAuthProfile; + model: string | null; +} + +export interface ProviderRateLimitState { + requestLimit: number | null; + remainingRequests: number | null; + resetAt: string | null; + retryAfterMs: number | null; + rawStateJson: string; +} + +export interface ProviderAdapter { + providerKey: string; + authType: ProviderAuthType; + authorize: ProviderAuthorizeHandler; + refresh: ProviderRefreshHandler; + revoke: ProviderRevokeHandler; + parseAuthProfile(secret: string): ProviderAuthProfile; + listModels(ctx: ProviderContext): Promise; + getRateLimitState(ctx: ProviderContext): Promise; + checkHealth(input: ProviderHealthInput): Promise; + streamResponse(input: ProviderStreamInput): Promise; + cancelResponse(input: ProviderCancelInput): Promise; + createBackgroundResponse(input: ProviderBackgroundCreateInput): Promise; + retrieveResponse(input: ProviderBackgroundRetrieveInput): Promise; + createResponse?: (input: ProviderExecutionInput) => Promise; +} + +export type ProviderAdapterRegistry = Record; diff --git a/AgentCompany-New/src/main/services/provider-adapters.ts b/AgentCompany-New/src/main/services/provider-adapters.ts index fa5b3c05..a24608fc 100644 --- a/AgentCompany-New/src/main/services/provider-adapters.ts +++ b/AgentCompany-New/src/main/services/provider-adapters.ts @@ -20,20 +20,8 @@ import { requireVertexProfile, type ProviderAuthProfile, } from "./provider-auth-profiles"; -import { - backgroundUnsupported, - retrieveUnsupported, - type ProviderBackgroundCreateResult, - type ProviderBackgroundRetrieveResult, -} from "./provider-background"; -import { - authorizeWithParser, - refreshUnsupported, - revokeLocalProfile, - type ProviderAuthorizeHandler, - type ProviderRefreshHandler, - type ProviderRevokeHandler, -} from "./provider-auth-lifecycle"; +import { backgroundUnsupported, retrieveUnsupported } from "./provider-background"; +import { authorizeWithParser, refreshUnsupported, revokeLocalProfile } from "./provider-auth-lifecycle"; import { getJson, postEventStream, postJson, type JsonRecord } from "./provider-http"; import { fetchAnthropicModels, fetchOpenAiModels } from "./provider-models-fetch"; @@ -45,80 +33,18 @@ import { mapOpenAiChatCompletionStream, mapOpenAiResponseStream, streamUnsupported, - type ProviderCancelResult, - type ProviderStreamResult, } from "./provider-streaming"; export { ProviderHttpError, providerRateLimitStateFromError } from "./provider-http"; export type { ProviderAuthProfile } from "./provider-auth-profiles"; +export * from "./provider-adapter-contract"; -export interface ProviderExecutionInput { - authProfile: ProviderAuthProfile; - model: string; - prompt: string; - instructions: string | null; -} - -export interface ProviderExecutionResult { - text: string; - rawResponseJson: string; - rateLimitState: ProviderObservedRateLimitState | null; -} - -export type ProviderStreamInput = ProviderExecutionInput; -export type ProviderBackgroundCreateInput = ProviderExecutionInput; - -export interface ProviderCancelInput { - authProfile: ProviderAuthProfile; - responseId: string; -} - -export interface ProviderBackgroundRetrieveInput { - authProfile: ProviderAuthProfile; - responseId: string; -} - -export interface ProviderHealthInput { - authProfile: ProviderAuthProfile; - model: string | null; -} - -export interface ProviderHealthResult { - checkedAt: string; - rateLimitState: ProviderObservedRateLimitState | null; -} - -export interface ProviderContext { - authProfile: ProviderAuthProfile; - model: string | null; -} - -export interface ProviderRateLimitState { - requestLimit: number | null; - remainingRequests: number | null; - resetAt: string | null; - retryAfterMs: number | null; - rawStateJson: string; -} - -export interface ProviderAdapter { - providerKey: string; - authType: ProviderAuthType; - authorize: ProviderAuthorizeHandler; - refresh: ProviderRefreshHandler; - revoke: ProviderRevokeHandler; - parseAuthProfile(secret: string): ProviderAuthProfile; - listModels(ctx: ProviderContext): Promise; - getRateLimitState(ctx: ProviderContext): Promise; - checkHealth(input: ProviderHealthInput): Promise; - streamResponse(input: ProviderStreamInput): Promise; - cancelResponse(input: ProviderCancelInput): Promise; - createBackgroundResponse(input: ProviderBackgroundCreateInput): Promise; - retrieveResponse(input: ProviderBackgroundRetrieveInput): Promise; - createResponse?: (input: ProviderExecutionInput) => Promise; -} - -export type ProviderAdapterRegistry = Record; +import type { + ProviderAdapter, + ProviderAdapterRegistry, + ProviderHealthResult, + ProviderRateLimitState, +} from "./provider-adapter-contract"; export const providerAdapters: ProviderAdapterRegistry = { openai: { diff --git a/AgentCompany-New/src/main/services/task-execution-service.ts b/AgentCompany-New/src/main/services/task-execution-service.ts index ce42f835..02e3d5de 100644 --- a/AgentCompany-New/src/main/services/task-execution-service.ts +++ b/AgentCompany-New/src/main/services/task-execution-service.ts @@ -9,7 +9,19 @@ import { ChatService } from "./chat-service"; import { SkillService } from "./skill-service"; import { runAgentLoop } from "./agent-run-loop"; import type { AgentToolContext } from "./agent-tools"; -import { canonicalMentionHandle } from "./mention-handles"; +import { + buildAgentInstructions, + buildTaskPrompt, + type ChatContextBlock, + type GoalRow, + type ProjectRow, + type SkillRuntimeSnapshotRow, + type TaskExecutionAgentRow, + type TaskExecutionProviderRow, + type TaskExecutionTaskRow, + type TaskRunIsolation, + type WorkspaceRow, +} from "./task-prompts"; const TASK_RUN_STATE = { QUEUED: "queued", @@ -18,82 +30,11 @@ const TASK_RUN_STATE = { FAILED: "failed", } as const; -interface TaskExecutionTaskRow { - id: string; - org_id: string; - title: string; - description: string; - status: string; - assignee_agent_id: string | null; - risk: string; - project_id: string | null; - goal_id: string | null; - workspace_id: string | null; - priority: string; - requires_filesystem: number; -} - -interface TaskExecutionAgentRow { - id: string; - name: string; - role: string; - department: string; - title: string; - role_level: string; - model_provider_id: string | null; - model_id: string | null; - manager_agent_id: string | null; -} - -interface TaskExecutionProviderRow { - id: string; - label: string; - provider_key: string; - model: string | null; -} - -interface ProjectRow { - name: string; - description: string; -} - -interface GoalRow { - title: string; - description: string; -} - -interface WorkspaceRow { - id: string; - name: string; - local_path: string; - repo_url: string; - repo_ref: string; -} - interface TaskApprovalRow { id: string; state: string; } -interface SkillRuntimeSnapshotRow { - id: string; - compiled_prompt: string; - tools_manifest: string; - source_revision_ids: string; -} - -interface TaskRunIsolation { - executionContextId: string; - serviceIdentityId: string; - workspaceMountJson: string; - secretScopeJson: string; -} - -interface ChatContextBlock { - threadId: string; - transcript: string; -} - interface RunRow { task_id: string; agent_id: string; @@ -510,93 +451,3 @@ export class TaskExecutionService { return row.id; } } - -function buildAgentInstructions(agent: TaskExecutionAgentRow): string { - return [ - `You are ${agent.name}, ${agent.title || agent.role} (${agent.department}, ${agent.role_level}) operating an autonomous AI company.`, - "You act by calling tools: hire_agent staffs your team, create_task delegates work and assigns it by agent name, update_task_status tracks progress, write_deliverable produces real files in the company workspace, create_document produces versioned company documents (PRDs, specs, memos, reports), and send_message posts coordination messages to a channel with optional file attachments.", - "Communicate like a real team. Post to the channel that matches the work — 'engineering' for engineering, 'product' for product or design, otherwise 'general'. Use @mentions when addressing a teammate. When you hand work or files to a teammate, use send_message with /handoff @Name and attachment_file_ids containing the file_id returned by write_deliverable. To keep a hand-off as one conversation, reply in the same thread by passing the thread_id a previous send_message returned.", - "Take concrete action with the tools and reserve narrative for brief summaries after coordination is posted.", - ].join("\n"); -} - -function buildTaskPrompt(input: { - task: TaskExecutionTaskRow; - agent: TaskExecutionAgentRow; - provider: TaskExecutionProviderRow; - project: ProjectRow | null; - goal: GoalRow | null; - workspace: WorkspaceRow | null; - isolation: TaskRunIsolation; - skillRuntimeSnapshot: SkillRuntimeSnapshotRow | null; - isManager: boolean; - hasReports: boolean; - managerName: string | null; - chatContext: ChatContextBlock | null; -}): string { - const lines = [ - "Execute this AgentCompany task.", - "", - `Task: ${input.task.title}`, - `Description: ${input.task.description}`, - `Status: ${input.task.status}`, - `Priority: ${input.task.priority}`, - `Risk: ${input.task.risk}`, - `Requires filesystem: ${input.task.requires_filesystem === 1 ? "yes" : "no"}`, - `Assignee: ${input.agent.name} (${input.agent.role})`, - ...(input.managerName ? [`Reports to: ${input.managerName}`] : []), - `Provider: ${input.provider.label} ${input.provider.model ?? input.agent.model_id ?? ""}`.trim(), - `Execution context: ${input.isolation.executionContextId}`, - `Service identity: ${input.isolation.serviceIdentityId}`, - ]; - if (input.goal) lines.push("", `Goal: ${input.goal.title}`, `Goal detail: ${input.goal.description}`); - if (input.project) lines.push("", `Project: ${input.project.name}`, `Project detail: ${input.project.description}`); - if (input.workspace) { - lines.push( - "", - `Workspace: ${input.workspace.name}`, - `Local path: ${input.workspace.local_path}`, - `Repo: ${input.workspace.repo_url}`, - `Ref: ${input.workspace.repo_ref}`, - `Mounts: ${input.isolation.workspaceMountJson}`, - ); - } - lines.push("", `Secret scope: ${input.isolation.secretScopeJson}`); - if (input.skillRuntimeSnapshot) { - lines.push( - "", - "Skill runtime:", - input.skillRuntimeSnapshot.compiled_prompt, - "", - `Tool allowlist: ${input.skillRuntimeSnapshot.tools_manifest}`, - `Skill revisions: ${input.skillRuntimeSnapshot.source_revision_ids}`, - ); - } - if (input.chatContext) { - lines.push( - "", - "Chat thread you are replying to:", - input.chatContext.transcript, - "", - `Reply in this thread by passing thread_id="${input.chatContext.threadId}" to send_message.`, - ); - } - if (input.isManager && !input.hasReports) { - lines.push( - "", - "Your team is currently empty. Hire 3-5 direct reports for the roles this goal needs (hire_agent), create and assign their first tasks (create_task), and write the initial operating plan into the workspace (write_deliverable). Then use send_message with /handoff @Name and attachment_file_ids to pass the operating plan to the relevant report. For EACH report, send_message to that report's department channel (engineering, product, or general) using an @mention and the work you assigned them — start a new thread per report and note the thread_id it returns. Post the company-wide kickoff to #general. Then summarize.", - ); - } else { - const manager = input.managerName ?? "your manager"; - const managerReference = input.managerName ? `${manager} (${agentMention(input.managerName)})` : manager; - lines.push( - "", - `Complete this task: do the work, write your output as real files with write_deliverable, then send_message to your department channel (engineering, product, or general) reporting your progress and completion to ${managerReference}. Use /handoff with attachment_file_ids when passing files. Reply in the assignment thread if you were given a thread_id. Update the task status when done, and summarize.`, - ); - } - return lines.join("\n"); -} - -function agentMention(name: string): string { - return `@${canonicalMentionHandle(name)}`; -} diff --git a/AgentCompany-New/src/main/services/task-prompts.ts b/AgentCompany-New/src/main/services/task-prompts.ts new file mode 100644 index 00000000..85398128 --- /dev/null +++ b/AgentCompany-New/src/main/services/task-prompts.ts @@ -0,0 +1,162 @@ +import { canonicalMentionHandle } from "./mention-handles"; + +export interface TaskExecutionTaskRow { + id: string; + org_id: string; + title: string; + description: string; + status: string; + assignee_agent_id: string | null; + risk: string; + project_id: string | null; + goal_id: string | null; + workspace_id: string | null; + priority: string; + requires_filesystem: number; +} + +export interface TaskExecutionAgentRow { + id: string; + name: string; + role: string; + department: string; + title: string; + role_level: string; + model_provider_id: string | null; + model_id: string | null; + manager_agent_id: string | null; +} + +export interface TaskExecutionProviderRow { + id: string; + label: string; + provider_key: string; + model: string | null; +} + +export interface ProjectRow { + name: string; + description: string; +} + +export interface GoalRow { + title: string; + description: string; +} + +export interface WorkspaceRow { + id: string; + name: string; + local_path: string; + repo_url: string; + repo_ref: string; +} + +export interface TaskRunIsolation { + executionContextId: string; + serviceIdentityId: string; + workspaceMountJson: string; + secretScopeJson: string; +} + +export interface SkillRuntimeSnapshotRow { + id: string; + compiled_prompt: string; + tools_manifest: string; + source_revision_ids: string; +} + +export interface ChatContextBlock { + threadId: string; + transcript: string; +} + +export function buildAgentInstructions(agent: TaskExecutionAgentRow): string { + return [ + `You are ${agent.name}, ${agent.title || agent.role} (${agent.department}, ${agent.role_level}) operating an autonomous AI company.`, + "You act by calling tools: hire_agent staffs your team, create_task delegates work and assigns it by agent name, update_task_status tracks progress, write_deliverable produces real files in the company workspace, create_document produces versioned company documents (PRDs, specs, memos, reports), and send_message posts coordination messages to a channel with optional file attachments.", + "Communicate like a real team. Post to the channel that matches the work — 'engineering' for engineering, 'product' for product or design, otherwise 'general'. Use @mentions when addressing a teammate. When you hand work or files to a teammate, use send_message with /handoff @Name and attachment_file_ids containing the file_id returned by write_deliverable. To keep a hand-off as one conversation, reply in the same thread by passing the thread_id a previous send_message returned.", + "Take concrete action with the tools and reserve narrative for brief summaries after coordination is posted.", + ].join("\n"); +} + +export function buildTaskPrompt(input: { + task: TaskExecutionTaskRow; + agent: TaskExecutionAgentRow; + provider: TaskExecutionProviderRow; + project: ProjectRow | null; + goal: GoalRow | null; + workspace: WorkspaceRow | null; + isolation: TaskRunIsolation; + skillRuntimeSnapshot: SkillRuntimeSnapshotRow | null; + isManager: boolean; + hasReports: boolean; + managerName: string | null; + chatContext: ChatContextBlock | null; +}): string { + const lines = [ + "Execute this AgentCompany task.", + "", + `Task: ${input.task.title}`, + `Description: ${input.task.description}`, + `Status: ${input.task.status}`, + `Priority: ${input.task.priority}`, + `Risk: ${input.task.risk}`, + `Requires filesystem: ${input.task.requires_filesystem === 1 ? "yes" : "no"}`, + `Assignee: ${input.agent.name} (${input.agent.role})`, + ...(input.managerName ? [`Reports to: ${input.managerName}`] : []), + `Provider: ${input.provider.label} ${input.provider.model ?? input.agent.model_id ?? ""}`.trim(), + `Execution context: ${input.isolation.executionContextId}`, + `Service identity: ${input.isolation.serviceIdentityId}`, + ]; + if (input.goal) lines.push("", `Goal: ${input.goal.title}`, `Goal detail: ${input.goal.description}`); + if (input.project) lines.push("", `Project: ${input.project.name}`, `Project detail: ${input.project.description}`); + if (input.workspace) { + lines.push( + "", + `Workspace: ${input.workspace.name}`, + `Local path: ${input.workspace.local_path}`, + `Repo: ${input.workspace.repo_url}`, + `Ref: ${input.workspace.repo_ref}`, + `Mounts: ${input.isolation.workspaceMountJson}`, + ); + } + lines.push("", `Secret scope: ${input.isolation.secretScopeJson}`); + if (input.skillRuntimeSnapshot) { + lines.push( + "", + "Skill runtime:", + input.skillRuntimeSnapshot.compiled_prompt, + "", + `Tool allowlist: ${input.skillRuntimeSnapshot.tools_manifest}`, + `Skill revisions: ${input.skillRuntimeSnapshot.source_revision_ids}`, + ); + } + if (input.chatContext) { + lines.push( + "", + "Chat thread you are replying to:", + input.chatContext.transcript, + "", + `Reply in this thread by passing thread_id="${input.chatContext.threadId}" to send_message.`, + ); + } + if (input.isManager && !input.hasReports) { + lines.push( + "", + "Your team is currently empty. Hire 3-5 direct reports for the roles this goal needs (hire_agent), create and assign their first tasks (create_task), and write the initial operating plan into the workspace (write_deliverable). Then use send_message with /handoff @Name and attachment_file_ids to pass the operating plan to the relevant report. For EACH report, send_message to that report's department channel (engineering, product, or general) using an @mention and the work you assigned them — start a new thread per report and note the thread_id it returns. Post the company-wide kickoff to #general. Then summarize.", + ); + } else { + const manager = input.managerName ?? "your manager"; + const managerReference = input.managerName ? `${manager} (${agentMention(input.managerName)})` : manager; + lines.push( + "", + `Complete this task: do the work, write your output as real files with write_deliverable, then send_message to your department channel (engineering, product, or general) reporting your progress and completion to ${managerReference}. Use /handoff with attachment_file_ids when passing files. Reply in the assignment thread if you were given a thread_id. Update the task status when done, and summarize.`, + ); + } + return lines.join("\n"); +} + +function agentMention(name: string): string { + return `@${canonicalMentionHandle(name)}`; +} diff --git a/AgentCompany-New/src/shared/commands.ts b/AgentCompany-New/src/shared/commands.ts deleted file mode 100644 index 7fb17efa..00000000 --- a/AgentCompany-New/src/shared/commands.ts +++ /dev/null @@ -1,588 +0,0 @@ -import type { - ApprovalState, - ComplianceExportType, - ComplianceSubjectType, - LegalHoldEntityType, - IdentitySource, - PrincipalType, - ProviderDataPolicy, - ProviderExecutionMode, - RetentionFreezeScopeType, - RiskLevel, - RoleKey, - SearchEntityType, - SdlcReviewTargetType, - SocialPlatform, - TaskPriority, - TaskStatus, -} from "./domain"; - -export interface SetActiveOrganizationInput { - orgId: string; -} - -export interface DeleteOrganizationInput { - orgId: string; -} - -export interface CreateOrganizationInput { - organizationName: string; - description?: string; - mission: string; - goal: string; - employeeName: string; - executionMode?: "ai_ceo" | "ai_cofounder"; - autoApproveHires?: boolean; - reviewDeliverables?: boolean; -} - -export interface UpdateAgentInput { - orgId: string; - agentId: string; - role: string; - title: string; - roleLevel: string; - department: string; - budgetCents: number; - modelProviderId: string | null; - modelId: string | null; -} - -export interface CreateAgentInput { - orgId: string; - name: string; - role: string; - department: string; - modelProviderId: string | null; - modelId: string | null; - budgetCents: number; - managerAgentId: string | null; - title?: string; - roleLevel?: string; - modelStrategy?: string; - workspaceId?: string | null; - heartbeatEnabled?: boolean; - heartbeatIntervalSec?: number; -} - -export interface CreateTaskInput { - orgId: string; - title: string; - description: string; - status: TaskStatus; - assigneeAgentId: string | null; - risk: RiskLevel; - projectId: string | null; - goalId: string | null; - workspaceId: string | null; - priority: TaskPriority; - requiresFilesystem: boolean; -} - -export interface UpdateTaskStatusInput { - orgId: string; - taskId: string; - status: TaskStatus; -} - -export interface RunTaskInput { - orgId: string; - taskId: string; -} - -export interface UpdateTaskInput { - orgId: string; - taskId: string; - title: string; - description: string; - assigneeAgentId: string | null; - risk: RiskLevel; - priority: TaskPriority; - parentTaskId: string | null; -} - -export interface DeleteTaskInput { - orgId: string; - taskId: string; -} - -export interface CreateGoalInput { - orgId: string; - title: string; - description: string; - ownerAgentId: string | null; -} - -export interface CreateProjectInput { - orgId: string; - goalId: string | null; - name: string; - description: string; - leadAgentId: string | null; -} - -export interface CreateWorkspaceInput { - orgId: string; - name: string; - localPath: string; - projectId: string | null; -} - -export interface CreateApprovalInput { - orgId: string; - kind: string; - title: string; - details: string; - risk: RiskLevel; - requestedByType: "employee" | "agent" | "system"; - requestedById: string | null; -} - -export interface DecideApprovalInput { - orgId: string; - approvalId: string; - state: Extract; - decidedByEmployeeId: string; - notes?: string; -} - -export interface SyncEmployeeIdentityInput { - orgId: string; - employeeId: string; - source: IdentitySource; - externalSubject: string; - email: string | null; -} - -export interface GrantRoleInput { - orgId: string; - principalType: PrincipalType; - principalId: string; - roleKey: RoleKey; - scopeType: "organization" | "workspace" | "project" | "department"; - scopeId: string; - grantedByEmployeeId: string; -} - -export interface SendMessageInput { - orgId: string; - spaceId: string; - threadId: string | null; - senderType: "employee" | "agent" | "board" | "system"; - senderId: string | null; - bodyMd: string; - attachmentFileIds?: string[]; -} - -export interface EditMessageInput { - orgId: string; - messageId: string; - actorType: SendMessageInput["senderType"]; - actorId: string | null; - bodyMd: string; -} - -export interface DeleteMessageInput { - orgId: string; - messageId: string; - actorType: SendMessageInput["senderType"]; - actorId: string | null; -} - -export interface CreateChatSpaceInput { - orgId: string; - spaceType: "company" | "division" | "department" | "project" | "pod" | "ad_hoc" | "direct"; - name: string; - topic: string; - visibility: "workspace" | "restricted"; - retentionPolicy?: "standard_365d" | "restricted_365d"; - memberEmployeeIds?: string[]; - memberAgentIds?: string[]; -} - -export interface MarkChatSpaceReadInput { - orgId: string; - employeeId: string; - spaceId: string; -} - -export interface SaveProviderCredentialInput { - orgId: string; - providerId: string; - secret: string; - model: string | null; - employeeId?: string | null; -} - -export interface RevokeProviderCredentialInput { - orgId: string; - providerId: string; -} - -export interface LaunchProviderSignInInput { - orgId: string; - providerId: string; - employeeId: string; -} - -export interface StartProviderOAuthInput { - providerKey: string; - enterpriseDomain?: string | null; - /** Present when connecting an existing org's provider (Settings); absent - * during onboarding, where the obtained credential is returned to the caller. */ - orgId?: string; - providerId?: string; - employeeId?: string; - model?: string | null; -} - -export interface StartProviderOAuthResult { - /** The obtained credential JSON when no org context was supplied, else null - * (the credential was already stored). */ - secret: string | null; -} - -export interface CancelProviderOAuthInput { - providerKey: string; -} - -export interface CheckProviderHealthInput { - orgId: string; - providerId: string; -} - -export interface ListProviderModelsInput { - providerKey: string; - /** A just-typed/authorized credential (onboarding or the connect-new dialog). */ - secret?: string; - /** A stored provider whose secret is decrypted server-side (settings refresh). */ - orgId?: string; - providerId?: string; -} - -export interface UpdateProviderPolicyInput { - orgId: string; - providerId: string; - dataPolicy: ProviderDataPolicy; - backgroundEnabled: boolean; - monthlyRequestLimit: number; - workspaceScope: "organization" | "workspace"; -} - -export interface CreateProviderResponseInput { - orgId: string; - providerId: string; - workspaceId?: string | null; - prompt: string; - instructions: string | null; - executionMode?: ProviderExecutionMode; -} - -export type StreamProviderResponseInput = CreateProviderResponseInput; - -export interface CancelProviderResponseInput { - orgId: string; - requestId: string; - providerResponseId?: string; -} - -export interface ImportSkillDirectoryInput { - orgId: string; - directoryPath: string; - versionSemver: string; -} - -export interface BindSkillInput { - orgId: string; - agentId: string; - skillId: string; - revisionId: string; -} - -export interface ResolveAgentSkillsInput { - orgId: string; - agentId: string; - runId: string; -} - -export interface RunSkillTestsInput { - orgId: string; - revisionId: string; -} - -export interface CreateSocialAccountInput { - orgId: string; - platform: SocialPlatform; - handle: string; - displayName: string; - createdByEmployeeId: string; - authorizedEmployeeId: string | null; -} - -export interface LaunchSocialLoginInput { - orgId: string; - socialAccountId: string; - employeeId: string; -} - -export interface ImportFileInput { - orgId: string; -} - -export interface OpenFileInput { - orgId: string; - fileId: string; -} - -export interface CreateMigrationReportInput { - orgId: string; - sourceDatabasePath: string; -} - -export interface CreateRollbackSnapshotInput { - orgId: string; - migrationReportId: string; - createdByEmployeeId: string; -} - -export interface SetRollbackSnapshotActiveInput { - orgId: string; - snapshotId: string; - active: boolean; - employeeId: string; -} - -export interface ResolveMigrationReconciliationInput { - orgId: string; - reconciliationItemId: string; - employeeId: string; -} - -export interface SearchInput { - orgId: string; - employeeId: string; - query: string; - entityTypes?: SearchEntityType[]; - limit?: number; -} - -export interface CreateComplianceExportInput { - orgId: string; - subjectType: ComplianceSubjectType; - subjectId: string; - exportType: ComplianceExportType; - requestedByEmployeeId: string; -} - -export interface CreateAuditReplayInput { - orgId: string; - threadId: string; - createdByEmployeeId: string; -} - -export interface CreateLegalHoldInput { - orgId: string; - entityType: LegalHoldEntityType; - entityId: string; - reason: string; - createdByEmployeeId: string; -} - -export interface SetLegalHoldStateInput { - orgId: string; - legalHoldId: string; - active: boolean; - employeeId: string; -} - -export interface CreateRetentionFreezeInput { - orgId: string; - scopeType: RetentionFreezeScopeType; - scopeId: string; - reason: string; - createdByEmployeeId: string; -} - -export interface SetRetentionFreezeStateInput { - orgId: string; - retentionFreezeId: string; - active: boolean; - employeeId: string; -} - -export interface CreateScheduledPostInput { - orgId: string; - socialAccountId: string; - bodyMd: string; - scheduledFor: string; - createdByEmployeeId: string; -} - -export interface SetScheduledPostStateInput { - orgId: string; - scheduledPostId: string; - state: "draft" | "scheduled" | "published" | "cancelled"; - employeeId: string; -} - -export interface SetFilePinnedInput { - orgId: string; - fileId: string; - pinned: boolean; -} - -export interface SetFeatureFlagInput { - orgId: string; - flagId: string; - enabled: boolean; -} - -export interface RunChaosDrillInput { - orgId: string; - drillId: string; -} - -export interface RunSdlcReviewInput { - orgId: string; - reviewAgentId: string; - targetType: SdlcReviewTargetType; - targetRef: string; -} - -export interface RunEvalSuiteInput { - orgId: string; - suiteId: string; -} - -export interface SetPrBotGateInput { - orgId: string; - gateId: string; - enabled: boolean; -} - -export interface BootstrapOnboardingInput { - companyName: string; - companyDescription: string; - employeeName: string; - workspacePath: string; - executionMode: "ai_ceo" | "ai_cofounder"; - autoApproveHires: boolean; - reviewDeliverables: boolean; - goalTitle: string; - goalDescription: string; - providerKey: string; - providerSecret: string; - providerModel: string; -} - -export interface BootstrapOnboardingSummary { - orgId: string; - employeeId: string; - ceoAgentId: string; - workspaceId: string | null; - goalId: string; - projectId: string; - taskId: string; - runId: string; - providerId: string; -} - -export interface CreateDocumentInput { - orgId: string; - title: string; - docType: string; - content: string; - authorAgentId: string | null; - reviewerAgentId: string | null; - projectId: string | null; - goalId: string | null; - taskId: string | null; -} - -export interface UpdateDocumentInput { - orgId: string; - documentId: string; - title: string; - content: string; - status: string; -} - -export interface DeleteDocumentInput { - orgId: string; - documentId: string; -} - -export interface CreateKnowledgeEntryInput { - orgId: string; - topic: string; - category: string; - content: string; - importance: string; - sourceType: string; - sourceId: string | null; -} - -export interface DeleteKnowledgeEntryInput { - orgId: string; - entryId: string; -} - -export interface CreateAutomationRuleInput { - orgId: string; - name: string; - triggerEvent: string; - conditions: Record; - actionType: string; - actionConfig: Record; - priority: number; - enabled: boolean; -} - -export interface UpdateAutomationRuleInput { - orgId: string; - ruleId: string; - name: string; - triggerEvent: string; - conditions: Record; - actionType: string; - actionConfig: Record; - priority: number; - enabled: boolean; -} - -export interface DeleteAutomationRuleInput { - orgId: string; - ruleId: string; -} - -export interface CreateMeetingInput { - orgId: string; - title: string; - meetingType: string; - scheduledAt: string | null; - durationMinutes: number; - agenda: string; -} - -export interface DeleteMeetingInput { - orgId: string; - meetingId: string; -} - -export interface CreateSprintInput { - orgId: string; - name: string; - goal: string; - startDate: string; - endDate: string; -} - -export interface DeleteSprintInput { - orgId: string; - sprintId: string; -} - -export interface NativeDialogResult { - canceled: boolean; - filePaths: string[]; -} diff --git a/AgentCompany-New/src/shared/commands/chat.ts b/AgentCompany-New/src/shared/commands/chat.ts new file mode 100644 index 00000000..e06136f1 --- /dev/null +++ b/AgentCompany-New/src/shared/commands/chat.ts @@ -0,0 +1,41 @@ +export interface SendMessageInput { + orgId: string; + spaceId: string; + threadId: string | null; + senderType: "employee" | "agent" | "board" | "system"; + senderId: string | null; + bodyMd: string; + attachmentFileIds?: string[]; +} + +export interface EditMessageInput { + orgId: string; + messageId: string; + actorType: SendMessageInput["senderType"]; + actorId: string | null; + bodyMd: string; +} + +export interface DeleteMessageInput { + orgId: string; + messageId: string; + actorType: SendMessageInput["senderType"]; + actorId: string | null; +} + +export interface CreateChatSpaceInput { + orgId: string; + spaceType: "company" | "division" | "department" | "project" | "pod" | "ad_hoc" | "direct"; + name: string; + topic: string; + visibility: "workspace" | "restricted"; + retentionPolicy?: "standard_365d" | "restricted_365d"; + memberEmployeeIds?: string[]; + memberAgentIds?: string[]; +} + +export interface MarkChatSpaceReadInput { + orgId: string; + employeeId: string; + spaceId: string; +} diff --git a/AgentCompany-New/src/shared/commands/collaboration.ts b/AgentCompany-New/src/shared/commands/collaboration.ts new file mode 100644 index 00000000..9051960c --- /dev/null +++ b/AgentCompany-New/src/shared/commands/collaboration.ts @@ -0,0 +1,94 @@ +export interface CreateDocumentInput { + orgId: string; + title: string; + docType: string; + content: string; + authorAgentId: string | null; + reviewerAgentId: string | null; + projectId: string | null; + goalId: string | null; + taskId: string | null; +} + +export interface UpdateDocumentInput { + orgId: string; + documentId: string; + title: string; + content: string; + status: string; +} + +export interface DeleteDocumentInput { + orgId: string; + documentId: string; +} + +export interface CreateKnowledgeEntryInput { + orgId: string; + topic: string; + category: string; + content: string; + importance: string; + sourceType: string; + sourceId: string | null; +} + +export interface DeleteKnowledgeEntryInput { + orgId: string; + entryId: string; +} + +export interface CreateAutomationRuleInput { + orgId: string; + name: string; + triggerEvent: string; + conditions: Record; + actionType: string; + actionConfig: Record; + priority: number; + enabled: boolean; +} + +export interface UpdateAutomationRuleInput { + orgId: string; + ruleId: string; + name: string; + triggerEvent: string; + conditions: Record; + actionType: string; + actionConfig: Record; + priority: number; + enabled: boolean; +} + +export interface DeleteAutomationRuleInput { + orgId: string; + ruleId: string; +} + +export interface CreateMeetingInput { + orgId: string; + title: string; + meetingType: string; + scheduledAt: string | null; + durationMinutes: number; + agenda: string; +} + +export interface DeleteMeetingInput { + orgId: string; + meetingId: string; +} + +export interface CreateSprintInput { + orgId: string; + name: string; + goal: string; + startDate: string; + endDate: string; +} + +export interface DeleteSprintInput { + orgId: string; + sprintId: string; +} diff --git a/AgentCompany-New/src/shared/commands/files.ts b/AgentCompany-New/src/shared/commands/files.ts new file mode 100644 index 00000000..7142c24d --- /dev/null +++ b/AgentCompany-New/src/shared/commands/files.ts @@ -0,0 +1,19 @@ +export interface ImportFileInput { + orgId: string; +} + +export interface OpenFileInput { + orgId: string; + fileId: string; +} + +export interface SetFilePinnedInput { + orgId: string; + fileId: string; + pinned: boolean; +} + +export interface NativeDialogResult { + canceled: boolean; + filePaths: string[]; +} diff --git a/AgentCompany-New/src/shared/commands/governance.ts b/AgentCompany-New/src/shared/commands/governance.ts new file mode 100644 index 00000000..dfcb628f --- /dev/null +++ b/AgentCompany-New/src/shared/commands/governance.ts @@ -0,0 +1,104 @@ +import type { + ComplianceExportType, + ComplianceSubjectType, + LegalHoldEntityType, + RetentionFreezeScopeType, + SdlcReviewTargetType, +} from "../domain"; + +export interface CreateMigrationReportInput { + orgId: string; + sourceDatabasePath: string; +} + +export interface CreateRollbackSnapshotInput { + orgId: string; + migrationReportId: string; + createdByEmployeeId: string; +} + +export interface SetRollbackSnapshotActiveInput { + orgId: string; + snapshotId: string; + active: boolean; + employeeId: string; +} + +export interface ResolveMigrationReconciliationInput { + orgId: string; + reconciliationItemId: string; + employeeId: string; +} + +export interface CreateComplianceExportInput { + orgId: string; + subjectType: ComplianceSubjectType; + subjectId: string; + exportType: ComplianceExportType; + requestedByEmployeeId: string; +} + +export interface CreateAuditReplayInput { + orgId: string; + threadId: string; + createdByEmployeeId: string; +} + +export interface CreateLegalHoldInput { + orgId: string; + entityType: LegalHoldEntityType; + entityId: string; + reason: string; + createdByEmployeeId: string; +} + +export interface SetLegalHoldStateInput { + orgId: string; + legalHoldId: string; + active: boolean; + employeeId: string; +} + +export interface CreateRetentionFreezeInput { + orgId: string; + scopeType: RetentionFreezeScopeType; + scopeId: string; + reason: string; + createdByEmployeeId: string; +} + +export interface SetRetentionFreezeStateInput { + orgId: string; + retentionFreezeId: string; + active: boolean; + employeeId: string; +} + +export interface SetFeatureFlagInput { + orgId: string; + flagId: string; + enabled: boolean; +} + +export interface RunChaosDrillInput { + orgId: string; + drillId: string; +} + +export interface RunSdlcReviewInput { + orgId: string; + reviewAgentId: string; + targetType: SdlcReviewTargetType; + targetRef: string; +} + +export interface RunEvalSuiteInput { + orgId: string; + suiteId: string; +} + +export interface SetPrBotGateInput { + orgId: string; + gateId: string; + enabled: boolean; +} diff --git a/AgentCompany-New/src/shared/commands/index.ts b/AgentCompany-New/src/shared/commands/index.ts new file mode 100644 index 00000000..9e4f029d --- /dev/null +++ b/AgentCompany-New/src/shared/commands/index.ts @@ -0,0 +1,9 @@ +export * from "./organization"; +export * from "./chat"; +export * from "./provider"; +export * from "./skills"; +export * from "./social"; +export * from "./files"; +export * from "./governance"; +export * from "./collaboration"; +export * from "./onboarding"; diff --git a/AgentCompany-New/src/shared/commands/onboarding.ts b/AgentCompany-New/src/shared/commands/onboarding.ts new file mode 100644 index 00000000..31647971 --- /dev/null +++ b/AgentCompany-New/src/shared/commands/onboarding.ts @@ -0,0 +1,36 @@ +import type { SearchEntityType } from "../domain"; + +export interface BootstrapOnboardingInput { + companyName: string; + companyDescription: string; + employeeName: string; + workspacePath: string; + executionMode: "ai_ceo" | "ai_cofounder"; + autoApproveHires: boolean; + reviewDeliverables: boolean; + goalTitle: string; + goalDescription: string; + providerKey: string; + providerSecret: string; + providerModel: string; +} + +export interface BootstrapOnboardingSummary { + orgId: string; + employeeId: string; + ceoAgentId: string; + workspaceId: string | null; + goalId: string; + projectId: string; + taskId: string; + runId: string; + providerId: string; +} + +export interface SearchInput { + orgId: string; + employeeId: string; + query: string; + entityTypes?: SearchEntityType[]; + limit?: number; +} diff --git a/AgentCompany-New/src/shared/commands/organization.ts b/AgentCompany-New/src/shared/commands/organization.ts new file mode 100644 index 00000000..e5200769 --- /dev/null +++ b/AgentCompany-New/src/shared/commands/organization.ts @@ -0,0 +1,148 @@ +import type { ApprovalState, IdentitySource, PrincipalType, RiskLevel, RoleKey, TaskPriority, TaskStatus } from "../domain"; + +export interface SetActiveOrganizationInput { + orgId: string; +} + +export interface DeleteOrganizationInput { + orgId: string; +} + +export interface CreateOrganizationInput { + organizationName: string; + description?: string; + mission: string; + goal: string; + employeeName: string; + executionMode?: "ai_ceo" | "ai_cofounder"; + autoApproveHires?: boolean; + reviewDeliverables?: boolean; +} + +export interface UpdateAgentInput { + orgId: string; + agentId: string; + role: string; + title: string; + roleLevel: string; + department: string; + budgetCents: number; + modelProviderId: string | null; + modelId: string | null; +} + +export interface CreateAgentInput { + orgId: string; + name: string; + role: string; + department: string; + modelProviderId: string | null; + modelId: string | null; + budgetCents: number; + managerAgentId: string | null; + title?: string; + roleLevel?: string; + modelStrategy?: string; + workspaceId?: string | null; + heartbeatEnabled?: boolean; + heartbeatIntervalSec?: number; +} + +export interface CreateTaskInput { + orgId: string; + title: string; + description: string; + status: TaskStatus; + assigneeAgentId: string | null; + risk: RiskLevel; + projectId: string | null; + goalId: string | null; + workspaceId: string | null; + priority: TaskPriority; + requiresFilesystem: boolean; +} + +export interface UpdateTaskStatusInput { + orgId: string; + taskId: string; + status: TaskStatus; +} + +export interface RunTaskInput { + orgId: string; + taskId: string; +} + +export interface UpdateTaskInput { + orgId: string; + taskId: string; + title: string; + description: string; + assigneeAgentId: string | null; + risk: RiskLevel; + priority: TaskPriority; + parentTaskId: string | null; +} + +export interface DeleteTaskInput { + orgId: string; + taskId: string; +} + +export interface CreateGoalInput { + orgId: string; + title: string; + description: string; + ownerAgentId: string | null; +} + +export interface CreateProjectInput { + orgId: string; + goalId: string | null; + name: string; + description: string; + leadAgentId: string | null; +} + +export interface CreateWorkspaceInput { + orgId: string; + name: string; + localPath: string; + projectId: string | null; +} + +export interface CreateApprovalInput { + orgId: string; + kind: string; + title: string; + details: string; + risk: RiskLevel; + requestedByType: "employee" | "agent" | "system"; + requestedById: string | null; +} + +export interface DecideApprovalInput { + orgId: string; + approvalId: string; + state: Extract; + decidedByEmployeeId: string; + notes?: string; +} + +export interface SyncEmployeeIdentityInput { + orgId: string; + employeeId: string; + source: IdentitySource; + externalSubject: string; + email: string | null; +} + +export interface GrantRoleInput { + orgId: string; + principalType: PrincipalType; + principalId: string; + roleKey: RoleKey; + scopeType: "organization" | "workspace" | "project" | "department"; + scopeId: string; + grantedByEmployeeId: string; +} diff --git a/AgentCompany-New/src/shared/commands/provider.ts b/AgentCompany-New/src/shared/commands/provider.ts new file mode 100644 index 00000000..44d934bf --- /dev/null +++ b/AgentCompany-New/src/shared/commands/provider.ts @@ -0,0 +1,81 @@ +import type { ProviderDataPolicy, ProviderExecutionMode } from "../domain"; + +export interface SaveProviderCredentialInput { + orgId: string; + providerId: string; + secret: string; + model: string | null; + employeeId?: string | null; +} + +export interface RevokeProviderCredentialInput { + orgId: string; + providerId: string; +} + +export interface LaunchProviderSignInInput { + orgId: string; + providerId: string; + employeeId: string; +} + +export interface StartProviderOAuthInput { + providerKey: string; + enterpriseDomain?: string | null; + /** Present when connecting an existing org's provider (Settings); absent + * during onboarding, where the obtained credential is returned to the caller. */ + orgId?: string; + providerId?: string; + employeeId?: string; + model?: string | null; +} + +export interface StartProviderOAuthResult { + /** The obtained credential JSON when no org context was supplied, else null + * (the credential was already stored). */ + secret: string | null; +} + +export interface CancelProviderOAuthInput { + providerKey: string; +} + +export interface CheckProviderHealthInput { + orgId: string; + providerId: string; +} + +export interface ListProviderModelsInput { + providerKey: string; + /** A just-typed/authorized credential (onboarding or the connect-new dialog). */ + secret?: string; + /** A stored provider whose secret is decrypted server-side (settings refresh). */ + orgId?: string; + providerId?: string; +} + +export interface UpdateProviderPolicyInput { + orgId: string; + providerId: string; + dataPolicy: ProviderDataPolicy; + backgroundEnabled: boolean; + monthlyRequestLimit: number; + workspaceScope: "organization" | "workspace"; +} + +export interface CreateProviderResponseInput { + orgId: string; + providerId: string; + workspaceId?: string | null; + prompt: string; + instructions: string | null; + executionMode?: ProviderExecutionMode; +} + +export type StreamProviderResponseInput = CreateProviderResponseInput; + +export interface CancelProviderResponseInput { + orgId: string; + requestId: string; + providerResponseId?: string; +} diff --git a/AgentCompany-New/src/shared/commands/skills.ts b/AgentCompany-New/src/shared/commands/skills.ts new file mode 100644 index 00000000..6891d914 --- /dev/null +++ b/AgentCompany-New/src/shared/commands/skills.ts @@ -0,0 +1,23 @@ +export interface ImportSkillDirectoryInput { + orgId: string; + directoryPath: string; + versionSemver: string; +} + +export interface BindSkillInput { + orgId: string; + agentId: string; + skillId: string; + revisionId: string; +} + +export interface ResolveAgentSkillsInput { + orgId: string; + agentId: string; + runId: string; +} + +export interface RunSkillTestsInput { + orgId: string; + revisionId: string; +} diff --git a/AgentCompany-New/src/shared/commands/social.ts b/AgentCompany-New/src/shared/commands/social.ts new file mode 100644 index 00000000..311b069d --- /dev/null +++ b/AgentCompany-New/src/shared/commands/social.ts @@ -0,0 +1,31 @@ +import type { SocialPlatform } from "../domain"; + +export interface CreateSocialAccountInput { + orgId: string; + platform: SocialPlatform; + handle: string; + displayName: string; + createdByEmployeeId: string; + authorizedEmployeeId: string | null; +} + +export interface LaunchSocialLoginInput { + orgId: string; + socialAccountId: string; + employeeId: string; +} + +export interface CreateScheduledPostInput { + orgId: string; + socialAccountId: string; + bodyMd: string; + scheduledFor: string; + createdByEmployeeId: string; +} + +export interface SetScheduledPostStateInput { + orgId: string; + scheduledPostId: string; + state: "draft" | "scheduled" | "published" | "cancelled"; + employeeId: string; +}